Skip to content

Commit 264d2e0

Browse files
committed
allow UQ + vectorization
1 parent 20cebb7 commit 264d2e0

11 files changed

Lines changed: 125 additions & 49 deletions

File tree

SU2_CFD/include/numerics_simd/CNumericsSIMD.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@
3636
* \brief Generic factory implementation.
3737
*/
3838
template<class ViscousDecorator>
39-
CNumericsSIMD* createNumerics(const CConfig& config, int iMesh) {
39+
CNumericsSIMD* createNumerics(const CConfig& config, int iMesh, const CVariable* turbVars) {
4040
CNumericsSIMD* obj = nullptr;
4141
switch (config.GetKind_ConvNumScheme_Flow()) {
4242
case SPACE_UPWIND:
4343
switch (config.GetKind_Upwind_Flow()) {
4444
case ROE:
45-
obj = new CRoeScheme<ViscousDecorator>(config, iMesh);
45+
obj = new CRoeScheme<ViscousDecorator>(config, iMesh, turbVars);
4646
break;
4747
}
4848
break;
@@ -52,16 +52,16 @@ CNumericsSIMD* createNumerics(const CConfig& config, int iMesh) {
5252
case NO_CENTERED:
5353
break;
5454
case LAX:
55-
obj = new CLaxScheme<ViscousDecorator>(config, iMesh);
55+
obj = new CLaxScheme<ViscousDecorator>(config, iMesh, turbVars);
5656
break;
5757
case JST:
58-
obj = new CJSTScheme<ViscousDecorator>(config, iMesh);
58+
obj = new CJSTScheme<ViscousDecorator>(config, iMesh, turbVars);
5959
break;
6060
case JST_KE:
61-
obj = new CJSTkeScheme<ViscousDecorator>(config, iMesh);
61+
obj = new CJSTkeScheme<ViscousDecorator>(config, iMesh, turbVars);
6262
break;
6363
case JST_MAT:
64-
obj = new CJSTmatScheme<ViscousDecorator>(config, iMesh);
64+
obj = new CJSTmatScheme<ViscousDecorator>(config, iMesh, turbVars);
6565
break;
6666
}
6767
break;
@@ -74,17 +74,17 @@ CNumericsSIMD* createNumerics(const CConfig& config, int iMesh) {
7474
* createNumerics, which in turn instantiates the class templates of the different
7575
* numerical methods.
7676
*/
77-
CNumericsSIMD* CNumericsSIMD::CreateNumerics(const CConfig& config, int nDim, int iMesh) {
77+
CNumericsSIMD* CNumericsSIMD::CreateNumerics(const CConfig& config, int nDim, int iMesh, const CVariable* turbVars) {
7878
if ((Double::Size < 4) && (SU2_MPI::GetRank() == MASTER_NODE)) {
7979
cout << "WARNING: SU2 was not compiled for an AVX-capable architecture." << endl;
8080
}
8181
CNumericsSIMD* obj = nullptr;
8282
if (config.GetViscous()) {
83-
if (nDim == 2) obj = createNumerics<CCompressibleViscousFlux<2> >(config, iMesh);
84-
if (nDim == 3) obj = createNumerics<CCompressibleViscousFlux<3> >(config, iMesh);
83+
if (nDim == 2) obj = createNumerics<CCompressibleViscousFlux<2> >(config, iMesh, turbVars);
84+
if (nDim == 3) obj = createNumerics<CCompressibleViscousFlux<3> >(config, iMesh, turbVars);
8585
} else {
86-
if (nDim == 2) obj = createNumerics<CNoViscousFlux<2> >(config, iMesh);
87-
if (nDim == 3) obj = createNumerics<CNoViscousFlux<3> >(config, iMesh);
86+
if (nDim == 2) obj = createNumerics<CNoViscousFlux<2> >(config, iMesh, turbVars);
87+
if (nDim == 3) obj = createNumerics<CNoViscousFlux<3> >(config, iMesh, turbVars);
8888
}
8989
return obj;
9090
}

SU2_CFD/include/numerics_simd/CNumericsSIMD.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ class CNumericsSIMD {
9393
* \param[in] config - Problem definitions.
9494
* \param[in] nDim - 2D or 3D.
9595
* \param[in] iMesh - Grid index.
96+
* \param[in] turbVars - Turbulence variables.
9697
*/
97-
static CNumericsSIMD* CreateNumerics(const CConfig& config, int nDim, int iMesh);
98+
static CNumericsSIMD* CreateNumerics(const CConfig& config, int nDim, int iMesh, const CVariable* turbVars = nullptr);
9899

99100
};

SU2_CFD/include/numerics_simd/flow/diffusion/common.hpp

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "../../CNumericsSIMD.hpp"
3131
#include "../../util.hpp"
3232
#include "../variables.hpp"
33+
#include "../../../numerics/CNumerics.hpp"
3334

3435
/*!
3536
* \brief Average gradients at i/j points.
@@ -65,14 +66,12 @@ FORCEINLINE void correctGradient(const PrimitiveType& V,
6566
}
6667

6768
/*!
68-
* \brief Compute the stress tensor (using the total viscosity).
69+
* \brief Compute the stress tensor.
6970
* \note Second viscosity term ignored.
7071
*/
71-
template<size_t nVar, size_t nDim, class PrimitiveType>
72-
FORCEINLINE MatrixDbl<nDim> stressTensor(const PrimitiveType& V,
72+
template<size_t nVar, size_t nDim>
73+
FORCEINLINE MatrixDbl<nDim> stressTensor(Double viscosity,
7374
const MatrixDbl<nVar,nDim> grad) {
74-
Double viscosity = V.laminarVisc() + V.eddyVisc();
75-
7675
/*--- Hydrostatic term. ---*/
7776
Double velDiv = 0.0;
7877
for (size_t iDim = 0; iDim < nDim; ++iDim) {
@@ -91,6 +90,33 @@ FORCEINLINE MatrixDbl<nDim> stressTensor(const PrimitiveType& V,
9190
return tau;
9291
}
9392

93+
/*!
94+
* \brief Add perturbed stress tensor.
95+
* \note Not inlined because it is not easy to vectorize properly, due to tred2 and tql2.
96+
*/
97+
template<class PrimitiveType, class MatrixType, size_t nDim, class... Ts>
98+
NEVERINLINE void addPerturbedRSM(const PrimitiveType& V,
99+
const MatrixType& grad,
100+
const Double& turb_ke,
101+
MatrixDbl<nDim,nDim>& tau,
102+
Ts... uq_args) {
103+
/*--- Handle SIMD dimensions 1 by 1. ---*/
104+
for (size_t k = 0; k < Double::Size; ++k) {
105+
su2double velgrad[nDim][nDim];
106+
for (size_t iVar = 0; iVar < nDim; ++iVar)
107+
for (size_t iDim = 0; iDim < nDim; ++iDim)
108+
velgrad[iVar][iDim] = grad(iVar+1,iDim)[k];
109+
110+
su2double rsm[3][3];
111+
CNumerics::ComputePerturbedRSM(nDim, uq_args..., velgrad, V.density()[k],
112+
V.eddyVisc()[k], turb_ke[k], rsm);
113+
114+
for (size_t iDim = 0; iDim < nDim; ++iDim)
115+
for (size_t jDim = 0; jDim < nDim; ++jDim)
116+
tau(iDim,jDim)[k] -= V.density()[k] * rsm[iDim][jDim];
117+
}
118+
}
119+
94120
/*!
95121
* \brief SA-QCR2000 modification of the stress tensor.
96122
*/

SU2_CFD/include/numerics_simd/flow/diffusion/viscous_fluxes.hpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,33 @@ class CCompressibleViscousFlux : public CNumericsSIMD {
7979
const su2double cp;
8080
const bool correct;
8181
const bool useSA_QCR;
82+
const bool uq;
83+
const bool uq_permute;
84+
const size_t uq_eigval_comp;
85+
const su2double uq_delta_b;
86+
const su2double uq_urlx;
87+
88+
const CVariable* turbVars;
8289

8390
/*!
8491
* \brief Constructor, initialize constants and booleans.
8592
*/
8693
template<class... Ts>
87-
CCompressibleViscousFlux(const CConfig& config, int iMesh, Ts&...) :
94+
CCompressibleViscousFlux(const CConfig& config, int iMesh,
95+
const CVariable* turbVars_ = nullptr, Ts&...) :
8896
gamma(config.GetGamma()),
8997
gasConst(config.GetGas_ConstantND()),
9098
prandtlLam(config.GetPrandtl_Lam()),
9199
prandtlTurb(config.GetPrandtl_Turb()),
92100
cp(gamma * gasConst / (gamma - 1)),
93101
correct(iMesh == MESH_0),
94-
useSA_QCR(config.GetQCR()) {
102+
useSA_QCR(config.GetQCR()),
103+
uq(config.GetUsing_UQ()),
104+
uq_permute(config.GetUQ_Permute()),
105+
uq_eigval_comp(config.GetEig_Val_Comp()),
106+
uq_delta_b(config.GetUQ_Delta_B()),
107+
uq_urlx(config.GetUQ_URLX()),
108+
turbVars(turbVars_) {
95109
}
96110

97111
/*!
@@ -130,12 +144,16 @@ class CCompressibleViscousFlux : public CNumericsSIMD {
130144
auto avgGrad = averageGradient<nPrimVarGrad,nDim>(iPoint, jPoint, gradient);
131145
if(correct) correctGradient(V, vector_ij, dist2_ij, avgGrad);
132146

133-
/// TODO: Uncertainty quantification (needs a way to access tke, maybe in ctor).
134-
135147
/*--- Stress and heat flux tensors. ---*/
136148

137-
auto tau = stressTensor(avgV, avgGrad);
149+
auto tau = stressTensor(avgV.laminarVisc() + (uq? Double(0.0) : avgV.eddyVisc()), avgGrad);
138150
if(useSA_QCR) addQCR(avgGrad, tau);
151+
if(uq) {
152+
Double turb_ke = 0.5*(gatherVariables(iPoint, turbVars->GetSolution()) +
153+
gatherVariables(jPoint, turbVars->GetSolution()));
154+
addPerturbedRSM(avgV, avgGrad, turb_ke, tau,
155+
uq_eigval_comp, uq_permute, uq_delta_b, uq_urlx);
156+
}
139157

140158
Double cond = cp * (avgV.laminarVisc()/prandtlLam + avgV.eddyVisc()/prandtlTurb);
141159
VectorDbl<nDim> heatFlux;

SU2_CFD/include/solvers/CEulerSolver.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,13 @@ class CEulerSolver : public CFVMFlowSolverBase<CEulerVariable, COMPRESSIBLE> {
278278
*/
279279
void SetCoefficient_Gradients(CConfig *config) const;
280280

281+
/*!
282+
* \brief Instantiate a SIMD numerics object.
283+
* \param[in] solvers - Container vector with all the solutions.
284+
* \param[in] config - Definition of the particular problem.
285+
*/
286+
void InstantiateEdgeNumerics(const CSolver* const* solvers, const CConfig* config) final;
287+
281288
public:
282289
/*!
283290
* \brief Constructor of the class.

SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,18 @@ class CFVMFlowSolverBase : public CSolver {
232232
/*!
233233
* \brief Method to compute convective and viscous residual contribution using vectorized numerics.
234234
*/
235-
void EdgeFluxResidual(const CGeometry *geometry, const CConfig *config);
235+
void EdgeFluxResidual(const CGeometry *geometry, const CSolver* const* solvers, const CConfig *config);
236236

237237
/*!
238238
* \brief Sum the edge fluxes for each cell to populate the residual vector, only used on coarse grids.
239239
*/
240240
void SumEdgeFluxes(const CGeometry* geometry);
241241

242+
/*!
243+
* \brief Instantiate a SIMD numerics object.
244+
*/
245+
inline virtual void InstantiateEdgeNumerics(const CSolver* const* solvers, const CConfig* config) {}
246+
242247
/*!
243248
* \brief Destructor.
244249
*/

SU2_CFD/include/solvers/CFVMFlowSolverBase.inl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1287,7 +1287,12 @@ void CFVMFlowSolverBase<V, R>::BC_Custom(CGeometry* geometry, CSolver** solver_c
12871287
}
12881288

12891289
template <class V, ENUM_REGIME R>
1290-
void CFVMFlowSolverBase<V, R>::EdgeFluxResidual(const CGeometry *geometry, const CConfig *config) {
1290+
void CFVMFlowSolverBase<V, R>::EdgeFluxResidual(const CGeometry *geometry,
1291+
const CSolver* const* solvers,
1292+
const CConfig *config) {
1293+
if (!edgeNumerics) {
1294+
InstantiateEdgeNumerics(solvers, config);
1295+
}
12911296

12921297
/*--- Loop over edge colors. ---*/
12931298
for (auto color : EdgeColoring) {

SU2_CFD/include/solvers/CSolver.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,10 @@ class CSolver {
197197
assert(base_nodes!=nullptr && "CSolver::base_nodes was not set properly, see brief for CSolver::SetBaseClassPointerToNodes()");
198198
return base_nodes;
199199
}
200+
inline const CVariable* GetNodes() const {
201+
assert(base_nodes!=nullptr && "CSolver::base_nodes was not set properly, see brief for CSolver::SetBaseClassPointerToNodes()");
202+
return base_nodes;
203+
}
200204

201205
/*!
202206
* \brief Helper function to define the type and number of variables per point for each communication type.

SU2_CFD/include/variables/CVariable.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ class CVariable {
447447
* \brief Get the entire solution of the problem.
448448
* \return Reference to the solution matrix.
449449
*/
450-
inline const MatrixType& GetSolution(void) { return Solution; }
450+
inline const MatrixType& GetSolution(void) const { return Solution; }
451451

452452
/*!
453453
* \brief Get the solution of the problem.

SU2_CFD/src/solvers/CEulerSolver.cpp

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -349,26 +349,6 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config,
349349
/*--- Add the solver name (max 8 characters). ---*/
350350
SolverName = "C.FLOW";
351351

352-
/*--- Vectorized numerics. ---*/
353-
if (config->GetUseVectorization()) {
354-
const bool uncertain = config->GetUsing_UQ();
355-
const bool ideal_gas = (config->GetKind_FluidModel() == STANDARD_AIR) ||
356-
(config->GetKind_FluidModel() == IDEAL_GAS);
357-
const bool low_mach_corr = config->Low_Mach_Correction();
358-
359-
if (uncertain || !ideal_gas || low_mach_corr) {
360-
SU2_MPI::Error("Some of the requested features are not yet "
361-
"supported with vectorization.", CURRENT_FUNCTION);
362-
}
363-
364-
edgeNumerics = CNumericsSIMD::CreateNumerics(*config, nDim, iMesh);
365-
366-
if (!edgeNumerics) {
367-
SU2_MPI::Error("The numerical scheme in use does not "
368-
"support vectorization.", CURRENT_FUNCTION);
369-
}
370-
}
371-
372352
/*--- Finally, check that the static arrays will be large enough (keep this
373353
* check at the bottom to make sure we consider the "final" values). ---*/
374354
if((nDim > MAXNDIM) || (nPrimVar > MAXNVAR) || (nSecondaryVar > MAXNVAR))
@@ -688,6 +668,31 @@ CEulerSolver::~CEulerSolver(void) {
688668

689669
}
690670

671+
void CEulerSolver::InstantiateEdgeNumerics(const CSolver* const* solver_container, const CConfig* config) {
672+
673+
SU2_OMP_MASTER {
674+
675+
const bool ideal_gas = (config->GetKind_FluidModel() == STANDARD_AIR) ||
676+
(config->GetKind_FluidModel() == IDEAL_GAS);
677+
const bool low_mach_corr = config->Low_Mach_Correction();
678+
679+
if (!ideal_gas || low_mach_corr)
680+
SU2_MPI::Error("Some of the requested features are not yet "
681+
"supported with vectorization.", CURRENT_FUNCTION);
682+
683+
if (solver_container[TURB_SOL])
684+
edgeNumerics = CNumericsSIMD::CreateNumerics(*config, nDim, MGLevel, solver_container[TURB_SOL]->GetNodes());
685+
else
686+
edgeNumerics = CNumericsSIMD::CreateNumerics(*config, nDim, MGLevel);
687+
688+
if (!edgeNumerics)
689+
SU2_MPI::Error("The numerical scheme in use does not "
690+
"support vectorization.", CURRENT_FUNCTION);
691+
692+
}
693+
SU2_OMP_BARRIER
694+
}
695+
691696
void CEulerSolver::InitTurboContainers(CGeometry *geometry, CConfig *config){
692697
unsigned short iMarker, iSpan, iVar;
693698
nSpanMax = config->GetnSpanMaxAllZones();
@@ -2645,8 +2650,10 @@ void CEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container,
26452650
void CEulerSolver::Centered_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container,
26462651
CConfig *config, unsigned short iMesh, unsigned short iRKStep) {
26472652

2648-
/*--- If possible use the vectorized numerics instead. ---*/
2649-
if (edgeNumerics) { EdgeFluxResidual(geometry, config); return; }
2653+
if (config->GetUseVectorization()) {
2654+
EdgeFluxResidual(geometry, solver_container, config);
2655+
return;
2656+
}
26502657

26512658
const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT);
26522659
const bool jst_scheme = (config->GetKind_Centered_Flow() == JST) && (iMesh == MESH_0);
@@ -2732,8 +2739,10 @@ void CEulerSolver::Centered_Residual(CGeometry *geometry, CSolver **solver_conta
27322739
void CEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_container,
27332740
CNumerics **numerics_container, CConfig *config, unsigned short iMesh) {
27342741

2735-
/*--- If possible use the vectorized numerics instead. ---*/
2736-
if (edgeNumerics) { EdgeFluxResidual(geometry, config); return; }
2742+
if (config->GetUseVectorization()) {
2743+
EdgeFluxResidual(geometry, solver_container, config);
2744+
return;
2745+
}
27372746

27382747
const auto InnerIter = config->GetInnerIter();
27392748
const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT);

0 commit comments

Comments
 (0)