Skip to content

Commit 3e975d3

Browse files
committed
Add a generic Visc_res_impl in ScalarSolver. Template the specific
contribution. Following the idea from SetTime_Step and SetTime_Step_impl from CFVMFlowSolver. The Base class has a Visc_Res_impl function that implements the majority. Each child has a Visc_Res routine that defines a struct with the Solvers-specifc-numerics and then calls the *_impl with this very struct. Like so one can has one base implemenation and each solver only adds its very specific change.
1 parent 11ba64a commit 3e975d3

6 files changed

Lines changed: 123 additions & 51 deletions

File tree

SU2_CFD/include/solvers/CScalarSolver.hpp

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#pragma once
2929

3030
#include <vector>
31+
3132
#include "../../../Common/include/parallelization/omp_structure.hpp"
3233
#include "../variables/CScalarVariable.hpp"
3334
#include "CSolver.hpp"
@@ -49,7 +50,8 @@ class CScalarSolver : public CSolver {
4950

5051
unsigned long omp_chunk_size; /*!< \brief Chunk size used in light point loops. */
5152

52-
su2double lowerlimit[MAXNVAR] = {0.0}; /*!< \brief contains lower limits for turbulence variables. Note that ::min() returns the smallest positive value for floats. */
53+
su2double lowerlimit[MAXNVAR] = {0.0}; /*!< \brief contains lower limits for turbulence variables. Note that ::min()
54+
returns the smallest positive value for floats. */
5355
su2double upperlimit[MAXNVAR] = {0.0}; /*!< \brief contains upper limits for turbulence variables. */
5456

5557
su2double Solution_Inf[MAXNVAR] = {0.0}; /*!< \brief Far-field solution. */
@@ -80,17 +82,72 @@ class CScalarSolver : public CSolver {
8082
*/
8183
inline CVariable* GetBaseClassPointerToNodes() final { return nodes; }
8284

83-
private: // changed from private in CTurbSolver.hpp
85+
/*!
86+
* \brief Compute the viscous flux for the turbulent equation at a particular edge.
87+
* \tparam SolverSpecificNumericsFunc - Struct, that implements solver specific contributions to numerics.
88+
* \note The functor has to implement (*geometry, *numerics, *config, *nodes, iPoint, jPoint)
89+
* \param[in] iEdge - Edge for which we want to compute the flux
90+
* \param[in] geometry - Geometrical definition of the problem.
91+
* \param[in] solver_container - Container vector with all the solutions.
92+
* \param[in] numerics - Description of the numerical method.
93+
* \param[in] config - Definition of the particular problem.
94+
*/
95+
template <class SolverSpecificNumericsFunc>
96+
FORCEINLINE void Viscous_Residual_impl(const SolverSpecificNumericsFunc& SolverSpecificNumerics, unsigned long iEdge,
97+
CGeometry* geometry, CSolver** solver_container, CNumerics* numerics,
98+
CConfig* config) {
99+
const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT);
100+
CVariable* flowNodes = solver_container[FLOW_SOL]->GetNodes();
101+
102+
/*--- Points in edge ---*/
103+
104+
auto iPoint = geometry->edges->GetNode(iEdge, 0);
105+
auto jPoint = geometry->edges->GetNode(iEdge, 1);
106+
107+
/*--- Points coordinates, and normal vector ---*/
108+
109+
numerics->SetCoord(geometry->nodes->GetCoord(iPoint), geometry->nodes->GetCoord(jPoint));
110+
numerics->SetNormal(geometry->edges->GetNormal(iEdge));
111+
112+
/*--- Conservative variables w/o reconstruction ---*/
113+
114+
numerics->SetPrimitive(flowNodes->GetPrimitive(iPoint), flowNodes->GetPrimitive(jPoint));
115+
116+
/*--- Turbulent variables w/o reconstruction, and its gradients ---*/
117+
118+
numerics->SetScalarVar(nodes->GetSolution(iPoint), nodes->GetSolution(jPoint));
119+
numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(jPoint));
120+
121+
/*--- Call Numerics contribution which are Solver-Specifc. Implemented in the caller: Viscous_Residual. ---*/
122+
123+
SolverSpecificNumerics(*geometry, *numerics, *config, *nodes, iPoint, jPoint);
124+
125+
/*--- Compute residual, and Jacobians ---*/
126+
127+
auto residual = numerics->ComputeResidual(config);
128+
129+
if (ReducerStrategy) {
130+
EdgeFluxes.SubtractBlock(iEdge, residual);
131+
if (implicit) Jacobian.UpdateBlocksSub(iEdge, residual.jacobian_i, residual.jacobian_j);
132+
} else {
133+
LinSysRes.SubtractBlock(iPoint, residual);
134+
LinSysRes.AddBlock(jPoint, residual);
135+
if (implicit) Jacobian.UpdateBlocksSub(iEdge, iPoint, jPoint, residual.jacobian_i, residual.jacobian_j);
136+
}
137+
}
138+
139+
private:
84140
/*!
85141
* \brief Compute the viscous flux for the turbulent equation at a particular edge.
86142
* \param[in] iEdge - Edge for which we want to compute the flux
87143
* \param[in] geometry - Geometrical definition of the problem.
88144
* \param[in] solver_container - Container vector with all the solutions.
89145
* \param[in] numerics - Description of the numerical method.
90146
* \param[in] config - Definition of the particular problem.
147+
* \note Calls a generic implementation after defining a SolverSpecificNumerics object.
91148
*/
92-
void Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, CNumerics* numerics,
93-
CConfig* config);
149+
inline virtual void Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container,
150+
CNumerics* numerics, CConfig* config) {}
94151
using CSolver::Viscous_Residual; /*--- Silence warning ---*/
95152

96153
/*!

SU2_CFD/include/solvers/CTurbSASolver.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,19 @@ class CTurbSASolver final : public CTurbSolver {
120120
CSolver **solver_container,
121121
CConfig *config,
122122
unsigned short iMesh) override;
123+
124+
/*!
125+
* \brief Compute the viscous flux for the turbulent equation at a particular edge.
126+
* \param[in] iEdge - Edge for which we want to compute the flux
127+
* \param[in] geometry - Geometrical definition of the problem.
128+
* \param[in] solver_container - Container vector with all the solutions.
129+
* \param[in] numerics - Description of the numerical method.
130+
* \param[in] config - Definition of the particular problem.
131+
* \note Calls a generic implementation after defining a SolverSpecificNumerics object.
132+
*/
133+
void Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container,
134+
CNumerics* numerics, CConfig* config) override;
135+
123136
/*!
124137
* \brief Source term computation.
125138
* \param[in] geometry - Geometrical definition of the problem.

SU2_CFD/include/solvers/CTurbSSTSolver.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,18 @@ class CTurbSSTSolver final : public CTurbSolver {
106106
CConfig *config,
107107
unsigned short iMesh) override;
108108

109+
/*!
110+
* \brief Compute the viscous flux for the turbulent equation at a particular edge.
111+
* \param[in] iEdge - Edge for which we want to compute the flux
112+
* \param[in] geometry - Geometrical definition of the problem.
113+
* \param[in] solver_container - Container vector with all the solutions.
114+
* \param[in] numerics - Description of the numerical method.
115+
* \param[in] config - Definition of the particular problem.
116+
* \note Calls a generic implementation after defining a SolverSpecificNumerics object.
117+
*/
118+
void Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container,
119+
CNumerics* numerics, CConfig* config) override;
120+
109121
/*!
110122
* \brief Source term computation.
111123
* \param[in] geometry - Geometrical definition of the problem.

SU2_CFD/src/solvers/CScalarSolver.cpp

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -236,52 +236,6 @@ void CScalarSolver::Upwind_Residual(CGeometry* geometry, CSolver** solver_contai
236236
}
237237
}
238238

239-
void CScalarSolver::Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container,
240-
CNumerics* numerics, CConfig* config) {
241-
const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT);
242-
CVariable* flowNodes = solver_container[FLOW_SOL]->GetNodes();
243-
244-
/*--- Points in edge ---*/
245-
246-
auto iPoint = geometry->edges->GetNode(iEdge, 0);
247-
auto jPoint = geometry->edges->GetNode(iEdge, 1);
248-
249-
/*--- Points coordinates, and normal vector ---*/
250-
251-
numerics->SetCoord(geometry->nodes->GetCoord(iPoint), geometry->nodes->GetCoord(jPoint));
252-
numerics->SetNormal(geometry->edges->GetNormal(iEdge));
253-
254-
/*--- Conservative variables w/o reconstruction ---*/
255-
256-
numerics->SetPrimitive(flowNodes->GetPrimitive(iPoint), flowNodes->GetPrimitive(jPoint));
257-
258-
/*--- Turbulent variables w/o reconstruction, and its gradients ---*/
259-
260-
numerics->SetScalarVar(nodes->GetSolution(iPoint), nodes->GetSolution(jPoint));
261-
numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(jPoint));
262-
263-
/*--- Menter's first blending function (only SST)---*/
264-
if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST))
265-
numerics->SetF1blending(nodes->GetF1blending(iPoint), nodes->GetF1blending(jPoint));
266-
267-
/*--- Roughness heights. ---*/
268-
if (config->GetKind_Turb_Model() == SA)
269-
numerics->SetRoughness(geometry->nodes->GetRoughnessHeight(iPoint), geometry->nodes->GetRoughnessHeight(jPoint));
270-
271-
/*--- Compute residual, and Jacobians ---*/
272-
273-
auto residual = numerics->ComputeResidual(config);
274-
275-
if (ReducerStrategy) {
276-
EdgeFluxes.SubtractBlock(iEdge, residual);
277-
if (implicit) Jacobian.UpdateBlocksSub(iEdge, residual.jacobian_i, residual.jacobian_j);
278-
} else {
279-
LinSysRes.SubtractBlock(iPoint, residual);
280-
LinSysRes.AddBlock(jPoint, residual);
281-
if (implicit) Jacobian.UpdateBlocksSub(iEdge, iPoint, jPoint, residual.jacobian_i, residual.jacobian_j);
282-
}
283-
}
284-
285239
void CScalarSolver::SumEdgeFluxes(CGeometry* geometry) {
286240
SU2_OMP_FOR_STAT(omp_chunk_size)
287241
for (unsigned long iPoint = 0; iPoint < nPoint; ++iPoint) {
@@ -606,7 +560,6 @@ void CScalarSolver::SetResidual_DualTime(CGeometry* geometry, CSolver** solver_c
606560
}
607561

608562
for (iVar = 0; iVar < nVar; iVar++) LinSysRes(iPoint, iVar) += Density_n * U_time_n[iVar] * Residual_GCL;
609-
610563
}
611564
END_SU2_OMP_FOR
612565
}

SU2_CFD/src/solvers/CTurbSASolver.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,24 @@ void CTurbSASolver::Postprocessing(CGeometry *geometry, CSolver **solver_contain
286286
AD::EndNoSharedReading();
287287
}
288288

289+
void CTurbSASolver::Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container,
290+
CNumerics* numerics, CConfig* config) {
291+
292+
/*--- Define an object to set solver specific numerics contribution. ---*/
293+
struct SolverSpecificNumerics {
294+
295+
FORCEINLINE void operator() (const CGeometry& geometry, CNumerics& numerics, CConfig& config, const CScalarVariable& nodes, unsigned long iPoint, unsigned long jPoint) const {
296+
/*--- Roughness heights. ---*/
297+
if (config.GetKind_Turb_Model() == SA)
298+
numerics.SetRoughness(geometry.nodes->GetRoughnessHeight(iPoint), geometry.nodes->GetRoughnessHeight(jPoint));
299+
}
300+
301+
} SolverSpecificNumerics;
302+
303+
/*--- Now instantiate the generic implementation with the functor above. ---*/
304+
305+
Viscous_Residual_impl(SolverSpecificNumerics, iEdge, geometry, solver_container, numerics, config);
306+
}
289307

290308
void CTurbSASolver::Source_Residual(CGeometry *geometry, CSolver **solver_container,
291309
CNumerics **numerics_container, CConfig *config, unsigned short iMesh) {

SU2_CFD/src/solvers/CTurbSSTSolver.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,25 @@ void CTurbSSTSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai
275275
AD::EndNoSharedReading();
276276
}
277277

278+
void CTurbSSTSolver::Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container,
279+
CNumerics* numerics, CConfig* config) {
280+
281+
/*--- Define an object to set solver specific numerics contribution. ---*/
282+
struct SolverSpecificNumerics {
283+
284+
FORCEINLINE void operator() (const CGeometry& geometry, CNumerics& numerics, CConfig& config, const CScalarVariable& nodes, unsigned long iPoint, unsigned long jPoint) const {
285+
/*--- Menter's first blending function (only SST)---*/
286+
if ((config.GetKind_Turb_Model() == SST) || (config.GetKind_Turb_Model() == SST_SUST))
287+
numerics.SetF1blending(nodes.GetF1blending(iPoint), nodes.GetF1blending(jPoint));
288+
}
289+
290+
} SolverSpecificNumerics;
291+
292+
/*--- Now instantiate the generic implementation with the functor above. ---*/
293+
294+
Viscous_Residual_impl(SolverSpecificNumerics, iEdge, geometry, solver_container, numerics, config);
295+
}
296+
278297
void CTurbSSTSolver::Source_Residual(CGeometry *geometry, CSolver **solver_container,
279298
CNumerics **numerics_container, CConfig *config, unsigned short iMesh) {
280299

0 commit comments

Comments
 (0)