Skip to content

Commit b3bb7b5

Browse files
authored
Merge branch 'develop' into feature_SST_RoughBCs
2 parents 76aeae0 + db6e087 commit b3bb7b5

28 files changed

Lines changed: 343 additions & 189 deletions

AUTHORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ Aniket C. Aranake
5656
Antonio Rubino
5757
Arne Bachmann
5858
Arne Voß
59+
Ayush Kumar
5960
Beckett Y. Zhou
6061
Benjamin S. Kirk
6162
Brendan Tracey

Common/include/linear_algebra/CSysSolve.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,12 @@ class CSysSolve {
295295
ScalarType& residual, bool monitoring, const CConfig* config,
296296
FgcrodrMode mode) const;
297297

298+
/*!
299+
* \brief Creates the inner solver for nested preconditioning if the settings allow it.
300+
* \returns True if the inner solver can be used.
301+
*/
302+
bool SetupInnerSolver(unsigned short kind_solver, const CConfig* config);
303+
298304
public:
299305
/*!
300306
* \brief default constructor of the class.

Common/include/option_structure.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2441,10 +2441,12 @@ static const MapType<std::string, ENUM_LINEAR_SOLVER> Linear_Solver_Map = {
24412441
enum class LINEAR_SOLVER_INNER {
24422442
NONE, /*!< \brief Do not use a nested linear solver. */
24432443
BCGSTAB, /*!< \brief Use BCGSTAB as the preconditioning linear solver. */
2444+
SMOOTHER, /*!< \brief Iterative smoother. */
24442445
};
24452446
static const MapType<std::string, LINEAR_SOLVER_INNER> Inner_Linear_Solver_Map = {
24462447
MakePair("NONE", LINEAR_SOLVER_INNER::NONE)
24472448
MakePair("BCGSTAB", LINEAR_SOLVER_INNER::BCGSTAB)
2449+
MakePair("SMOOTHER", LINEAR_SOLVER_INNER::SMOOTHER)
24482450
};
24492451

24502452

Common/src/linear_algebra/CSysSolve.cpp

Lines changed: 57 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,8 @@ unsigned long CSysSolve<ScalarType>::CG_LinSolver(const CSysVector<ScalarType>&
312312
/*--- Only compute the residuals in full communication mode. ---*/
313313

314314
if (config->GetComm_Level() == COMM_FULL) {
315-
norm_r = r.norm();
316315
norm0 = b.norm();
316+
norm_r = xIsZero ? norm0 : r.norm();
317317

318318
/*--- Set the norm to the initial initial residual value ---*/
319319

@@ -626,14 +626,15 @@ unsigned long CSysSolve<ScalarType>::RFGMRES_LinSolver(const CSysVector<ScalarTy
626626
}
627627
END_SU2_OMP_SAFE_GLOBAL_ACCESS
628628

629-
for (auto totalIter = 0ul; totalIter < MaxIter;) {
629+
auto totalIter = 0ul;
630+
while (totalIter < MaxIter) {
630631
/*--- Enforce a hard limit on total number of iterations ---*/
631632
auto iterLimit = min(restartIter, MaxIter - totalIter);
632633
auto iter = FGMRES_LinSolver(b, x, mat_vec, precond, tol, iterLimit, residual, monitoring, config);
633634
totalIter += iter;
634-
if (residual <= tol || iter < iterLimit) return totalIter;
635+
if (residual <= tol || iter < iterLimit) break;
635636
}
636-
return 0;
637+
return totalIter;
637638
}
638639

639640
template <class ScalarType>
@@ -1032,8 +1033,8 @@ unsigned long CSysSolve<ScalarType>::BCGSTAB_LinSolver(const CSysVector<ScalarTy
10321033
/*--- Only compute the residuals in full communication mode. ---*/
10331034

10341035
if (config->GetComm_Level() == COMM_FULL) {
1035-
norm_r = r.norm();
10361036
norm0 = b.norm();
1037+
norm_r = xIsZero ? norm0 : r.norm();
10371038

10381039
/*--- Set the norm to the initial initial residual value ---*/
10391040

@@ -1205,8 +1206,8 @@ unsigned long CSysSolve<ScalarType>::Smoother_LinSolver(const CSysVector<ScalarT
12051206
/*--- Only compute the residuals in full communication mode. ---*/
12061207

12071208
if (config->GetComm_Level() == COMM_FULL) {
1208-
norm_r = r.norm();
12091209
norm0 = b.norm();
1210+
norm_r = xIsZero ? norm0 : r.norm();
12101211

12111212
/*--- Set the norm to the initial initial residual value ---*/
12121213

@@ -1246,15 +1247,19 @@ unsigned long CSysSolve<ScalarType>::Smoother_LinSolver(const CSysVector<ScalarT
12461247
current residual, the system is linear so this saves some computation
12471248
compared to re-evaluating r = b-A*x. ---*/
12481249

1249-
mat_vec(z, A_x);
1250+
if (!fix_iter_mode || i != m - 1) {
1251+
mat_vec(z, A_x);
1252+
}
12501253

12511254
/*--- Update solution and residual with relaxation omega. Mathematically this
12521255
is a modified Richardson iteration for the left-preconditioned system
12531256
M^{-1}(b-A*x) which converges if ||I-w*M^{-1}*A|| < 1. Combining this method
12541257
with a Gauss-Seidel preconditioner and w>1 is NOT equivalent to SOR. ---*/
12551258

12561259
x += omega * z;
1257-
r -= omega * A_x;
1260+
if (!fix_iter_mode || i != m - 1) {
1261+
r -= omega * A_x;
1262+
}
12581263

12591264
/*--- Only compute the residuals in full communication mode. ---*/
12601265
/*--- Check if solution has converged, else output the relative residual if necessary. ---*/
@@ -1282,6 +1287,33 @@ unsigned long CSysSolve<ScalarType>::Smoother_LinSolver(const CSysVector<ScalarT
12821287
return i;
12831288
}
12841289

1290+
template <class ScalarType>
1291+
bool CSysSolve<ScalarType>::SetupInnerSolver(unsigned short kind_solver, const CConfig* config) {
1292+
bool flexible = false;
1293+
switch (kind_solver) {
1294+
case FGMRES:
1295+
case FGCRODR:
1296+
case RESTARTED_FGMRES:
1297+
case SMOOTHER:
1298+
flexible = true;
1299+
break;
1300+
default:
1301+
flexible = false;
1302+
}
1303+
const bool is_linear = config->GetKind_Linear_Solver_Inner() == LINEAR_SOLVER_INNER::SMOOTHER;
1304+
1305+
if (config->GetKind_Linear_Solver_Inner() != LINEAR_SOLVER_INNER::NONE && (flexible || is_linear)) {
1306+
BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS
1307+
if (!inner_solver) {
1308+
inner_solver = std::make_unique<CSysSolve<ScalarType>>(LINEAR_SOLVER_MODE::STANDARD);
1309+
inner_solver->SetxIsZero(true);
1310+
}
1311+
END_SU2_OMP_SAFE_GLOBAL_ACCESS
1312+
return true;
1313+
}
1314+
return false;
1315+
}
1316+
12851317
template <class ScalarType>
12861318
unsigned long CSysSolve<ScalarType>::Solve(CSysMatrix<ScalarType>& Jacobian, const CSysVector<su2double>& LinSysRes,
12871319
CSysVector<su2double>& LinSysSol, CGeometry* geometry,
@@ -1334,16 +1366,7 @@ unsigned long CSysSolve<ScalarType>::Solve(CSysMatrix<ScalarType>& Jacobian, con
13341366
}
13351367
}
13361368

1337-
const bool nested = (KindSolver == FGMRES || KindSolver == RESTARTED_FGMRES || KindSolver == SMOOTHER) &&
1338-
config->GetKind_Linear_Solver_Inner() != LINEAR_SOLVER_INNER::NONE;
1339-
1340-
if (nested && !inner_solver) {
1341-
BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS {
1342-
inner_solver = std::make_unique<CSysSolve<ScalarType>>(LINEAR_SOLVER_MODE::STANDARD);
1343-
inner_solver->SetxIsZero(true);
1344-
}
1345-
END_SU2_OMP_SAFE_GLOBAL_ACCESS
1346-
}
1369+
const bool nested = SetupInnerSolver(KindSolver, config);
13471370

13481371
/*--- Stop the recording for the linear solver ---*/
13491372
bool TapeActive = NO;
@@ -1389,11 +1412,15 @@ unsigned long CSysSolve<ScalarType>::Solve(CSysMatrix<ScalarType>& Jacobian, con
13891412
auto f = [&](const CSysVector<ScalarType>& u, CSysVector<ScalarType>& v) {
13901413
/*--- Initialize to 0 to be safe. ---*/
13911414
v = ScalarType{};
1392-
ScalarType unused{};
1415+
ScalarType res{};
13931416
/*--- Handle other types here if desired but do not call Solve because
13941417
* that will create issues with the AD external function. ---*/
1395-
(void)inner_solver->BCGSTAB_LinSolver(u, v, mat_vec, *normal_prec, sqrt(SolverTol), MaxIter, unused, false,
1396-
config);
1418+
if (config->GetKind_Linear_Solver_Inner() == LINEAR_SOLVER_INNER::BCGSTAB) {
1419+
inner_solver->BCGSTAB_LinSolver(u, v, mat_vec, *normal_prec, sqrt(SolverTol), MaxIter, res, false, config);
1420+
} else {
1421+
const auto smooth_iter = static_cast<unsigned long>(std::round(fmax(2, sqrt(MaxIter))));
1422+
inner_solver->Smoother_LinSolver(u, v, mat_vec, *normal_prec, 0, smooth_iter, res, false, config);
1423+
}
13971424
};
13981425
nested_prec = new CAbstractPreconditioner<ScalarType>(f);
13991426
}
@@ -1545,16 +1572,7 @@ unsigned long CSysSolve<ScalarType>::Solve_b(CSysMatrix<ScalarType>& Jacobian, c
15451572
}
15461573
}
15471574

1548-
const bool nested = (KindSolver == FGMRES || KindSolver == RESTARTED_FGMRES || KindSolver == SMOOTHER) &&
1549-
config->GetKind_Linear_Solver_Inner() != LINEAR_SOLVER_INNER::NONE;
1550-
1551-
if (nested && !inner_solver) {
1552-
BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS {
1553-
inner_solver = std::make_unique<CSysSolve<ScalarType>>(LINEAR_SOLVER_MODE::STANDARD);
1554-
inner_solver->SetxIsZero(true);
1555-
}
1556-
END_SU2_OMP_SAFE_GLOBAL_ACCESS
1557-
}
1575+
const bool nested = SetupInnerSolver(KindSolver, config);
15581576

15591577
/*--- Set up preconditioner and matrix-vector product ---*/
15601578

@@ -1572,13 +1590,15 @@ unsigned long CSysSolve<ScalarType>::Solve_b(CSysMatrix<ScalarType>& Jacobian, c
15721590
CPreconditioner<ScalarType>* nested_prec = nullptr;
15731591
if (nested) {
15741592
auto f = [&](const CSysVector<ScalarType>& u, CSysVector<ScalarType>& v) {
1575-
/*--- Initialize to 0 to be safe. ---*/
1593+
/*--- See "Solve". ---*/
15761594
v = ScalarType{};
1577-
ScalarType unused{};
1578-
/*--- Handle other types here if desired but do not call Solve because
1579-
* that will create issues with the AD external function. ---*/
1580-
(void)inner_solver->BCGSTAB_LinSolver(u, v, mat_vec, *normal_prec, sqrt(SolverTol), MaxIter, unused, false,
1581-
config);
1595+
ScalarType res{};
1596+
if (config->GetKind_Linear_Solver_Inner() == LINEAR_SOLVER_INNER::BCGSTAB) {
1597+
inner_solver->BCGSTAB_LinSolver(u, v, mat_vec, *normal_prec, sqrt(SolverTol), MaxIter, res, false, config);
1598+
} else {
1599+
const auto smooth_iter = static_cast<unsigned long>(std::round(fmax(2, sqrt(MaxIter))));
1600+
inner_solver->Smoother_LinSolver(u, v, mat_vec, *normal_prec, 0, smooth_iter, res, false, config);
1601+
}
15821602
};
15831603
nested_prec = new CAbstractPreconditioner<ScalarType>(f);
15841604
}

SU2_CFD/include/integration/CNewtonIntegration.hpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,17 +152,25 @@ class CNewtonIntegration final : public CIntegration {
152152
template<class T, su2enable_if<std::is_same<T,MixedScalar>::value> = 0>
153153
inline unsigned long Preconditioner_impl(const CSysVector<T>& u, CSysVector<T>& v,
154154
unsigned long iters, Scalar& eps) const {
155-
if (iters == 0) {
155+
const auto inner_solver = config->GetKind_Linear_Solver_Inner();
156+
157+
if (iters == 0 || (iters == 1 && inner_solver == LINEAR_SOLVER_INNER::SMOOTHER)) {
156158
(*preconditioner)(u, v);
157159
return 0;
158160
}
159161
auto product = CSysMatrixVectorProduct<MixedScalar>(solvers[FLOW_SOL]->Jacobian, geometry, config);
160162
v = MixedScalar(0.0);
161163
MixedScalar eps_t = eps;
162-
if (config->GetKind_Linear_Solver_Inner() == LINEAR_SOLVER_INNER::NONE) {
163-
iters = solvers[FLOW_SOL]->System.FGMRES_LinSolver(u, v, product, *preconditioner, eps, iters, eps_t, false, config);
164-
} else {
165-
iters = solvers[FLOW_SOL]->System.BCGSTAB_LinSolver(u, v, product, *preconditioner, eps, iters, eps_t, false, config);
164+
switch (inner_solver) {
165+
case LINEAR_SOLVER_INNER::NONE:
166+
iters = solvers[FLOW_SOL]->System.FGMRES_LinSolver(u, v, product, *preconditioner, eps, iters, eps_t, false, config);
167+
break;
168+
case LINEAR_SOLVER_INNER::BCGSTAB:
169+
iters = solvers[FLOW_SOL]->System.BCGSTAB_LinSolver(u, v, product, *preconditioner, eps, iters, eps_t, false, config);
170+
break;
171+
case LINEAR_SOLVER_INNER::SMOOTHER:
172+
iters = solvers[FLOW_SOL]->System.Smoother_LinSolver(u, v, product, *preconditioner, 0, iters, eps_t, false, config);
173+
break;
166174
}
167175
eps = eps_t;
168176
return iters;

SU2_CFD/include/numerics/elasticity/CFEAElasticity.hpp

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ class CFEAElasticity : public CNumerics {
8080
su2double *DV_Val = nullptr; /*!< \brief For optimization cases, value of the design variables. */
8181
unsigned short n_DV = 0; /*!< \brief For optimization cases, number of design variables. */
8282

83-
bool plane_stress = false; /*!< \brief Checks if we are solving a plane stress case */
83+
bool plane_stress = false; /*!< \brief Checks if we are solving a plane stress case. */
84+
bool linear = false; /*!< \brief Checks if we are solving a linear elasticity case. */
8485

8586
public:
8687
/*!
@@ -181,28 +182,21 @@ class CFEAElasticity : public CNumerics {
181182

182183
/*!
183184
* \brief Compute VonMises stress from components Sxx Syy Sxy Szz Sxz Syz.
185+
* \note Szz is required in 2D whereas Sxz and Syz are assumed to be 0.
184186
*/
185-
template<class T>
187+
template <class T>
186188
static su2double VonMisesStress(unsigned short nDim, const T& stress) {
187-
if (nDim == 2) {
188-
su2double Sxx = stress[0], Syy = stress[1], Sxy = stress[2];
189-
190-
su2double S1, S2; S1 = S2 = (Sxx+Syy)/2;
191-
su2double tauMax = sqrt(pow((Sxx-Syy)/2, 2) + pow(Sxy,2));
192-
S1 += tauMax;
193-
S2 -= tauMax;
194-
195-
return sqrt(S1*S1+S2*S2-2*S1*S2);
196-
}
197-
else {
198-
su2double Sxx = stress[0], Syy = stress[1], Szz = stress[3];
199-
su2double Sxy = stress[2], Sxz = stress[4], Syz = stress[5];
200-
201-
return sqrt(0.5*(pow(Sxx - Syy, 2) +
202-
pow(Syy - Szz, 2) +
203-
pow(Szz - Sxx, 2) +
204-
6.0*(Sxy*Sxy+Sxz*Sxz+Syz*Syz)));
189+
/*--- In 2D, we only have 4 components: Sxx, Syy, Sxy, Szz. ---*/
190+
const auto& Sxx = stress[0];
191+
const auto& Syy = stress[1];
192+
const auto& Sxy = stress[2];
193+
const auto& Szz = stress[3];
194+
su2double Sxz = 0, Syz = 0;
195+
if (nDim == 3) {
196+
Sxz = stress[4];
197+
Syz = stress[5];
205198
}
199+
return sqrt(0.5 * (pow(Sxx - Syy, 2) + pow(Syy - Szz, 2) + pow(Szz - Sxx, 2) + 6 * (Sxy * Sxy + Sxz * Sxz + Syz * Syz)));
206200
}
207201

208202
protected:
@@ -233,8 +227,12 @@ class CFEAElasticity : public CNumerics {
233227
Mu = E / (2.0*(1.0 + Nu));
234228
Lambda = Nu*E/((1.0+Nu)*(1.0-2.0*Nu));
235229
Kappa = Lambda + (2/3)*Mu;
236-
/*--- https://solidmechanics.org/Text/Chapter3_2/Chapter3_2.php ---*/
237-
ThermalStressTerm = -Alpha * E / (1 - (plane_stress ? 1 : 2) * Nu);
230+
/*--- https://solidmechanics.org/Text/Chapter3_2/Chapter3_2.php
231+
* The stress tensor for nonlinear problems is still 3x3 and plane stress is imposed
232+
* by determining the deformation that makes sigma_33 = 0, hence this denominator is
233+
* only changed for linear elasticity. ---*/
234+
const auto nu_mult = (linear && plane_stress) ? 1 : 2;
235+
ThermalStressTerm = -Alpha * E / (1 - nu_mult * Nu);
238236
}
239237

240238
/*!

SU2_CFD/include/numerics/elasticity/CFEANonlinearElasticity.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,9 @@ class CFEANonlinearElasticity : public CFEAElasticity {
134134
* \brief Compute the plane stress term.
135135
* \param[in,out] element_container - The finite element.
136136
* \param[in] config - Definition of the problem.
137+
* \param[in] iGauss - Index of Gaussian integration point.
137138
*/
138-
virtual void Compute_Plane_Stress_Term(CElement *element_container, const CConfig *config) = 0;
139+
virtual void Compute_Plane_Stress_Term(CElement *element_container, const CConfig *config, unsigned short iGauss) = 0;
139140

140141
/*!
141142
* \brief Compute the stress tensor.

0 commit comments

Comments
 (0)