@@ -62,14 +62,13 @@ class CNoViscousFlux : public CNumericsSIMD {
6262};
6363
6464/* !
65- * \class CCompressibleViscousFlux
66- * \brief Decorator class to add viscous fluxes (compressible flow, ideal gas ).
65+ * \class CCompressibleViscousFluxBase
66+ * \brief Decorator class to add viscous fluxes (compressible flow).
6767 */
68- template <size_t NDIM>
69- class CCompressibleViscousFlux : public CNumericsSIMD {
68+ template <size_t NDIM, class Derived >
69+ class CCompressibleViscousFluxBase : public CNumericsSIMD {
7070protected:
7171 static constexpr size_t nDim = NDIM;
72- static constexpr size_t nPrimVar = nDim+7 ;
7372 static constexpr size_t nPrimVarGrad = nDim+1 ;
7473
7574 const su2double gamma;
@@ -91,8 +90,8 @@ class CCompressibleViscousFlux : public CNumericsSIMD {
9190 * \brief Constructor, initialize constants and booleans.
9291 */
9392 template <class ... Ts>
94- CCompressibleViscousFlux (const CConfig& config, int iMesh,
95- const CVariable* turbVars_ = nullptr , Ts&...) :
93+ CCompressibleViscousFluxBase (const CConfig& config, int iMesh,
94+ const CVariable* turbVars_ = nullptr , Ts&...) :
9695 gamma (config.GetGamma()),
9796 gasConst (config.GetGas_ConstantND()),
9897 prandtlLam (config.GetPrandtl_Lam()),
@@ -128,7 +127,11 @@ class CCompressibleViscousFlux : public CNumericsSIMD {
128127 MatrixDbl<nVar>& jac_i,
129128 MatrixDbl<nVar>& jac_j) const {
130129
131- static_assert (PrimVarType::nVar <= nPrimVar," " );
130+ static_assert (PrimVarType::nVar <= Derived::nPrimVar," " );
131+
132+ /* --- Pointer on which to call the "compile-time virtual" methods. ---*/
133+
134+ const auto derived = static_cast <const Derived*>(this );
132135
133136 const auto & solution = static_cast <const CNSVariable&>(solution_);
134137 const auto & gradient = solution.GetGradient_Primitive ();
@@ -155,7 +158,7 @@ class CCompressibleViscousFlux : public CNumericsSIMD {
155158 uq_eigval_comp, uq_permute, uq_delta_b, uq_urlx);
156159 }
157160
158- Double cond = cp * (avgV. laminarVisc ()/prandtlLam + avgV. eddyVisc ()/prandtlTurb );
161+ Double cond = derived-> thermalConductivity (avgV);
159162 VectorDbl<nDim> heatFlux;
160163 for (size_t iDim = 0 ; iDim < nDim; ++iDim) {
161164 heatFlux (iDim) = cond * avgGrad (0 ,iDim);
@@ -175,23 +178,9 @@ class CCompressibleViscousFlux : public CNumericsSIMD {
175178
176179 Double dist_ij = sqrt (dist2_ij);
177180 auto dtau = stressTensorJacobian<nVar>(avgV, unitNormal, dist_ij);
178- Double contraction = 0.0 ;
179- for (size_t iDim = 0 ; iDim < nDim; ++iDim) {
180- contraction += dtau (iDim,0 ) * avgV.velocity (iDim);
181- }
182181
183182 /* --- Energy flux Jacobian. ---*/
184- VectorDbl<nVar> dEdU;
185- Double vel2 = 0.5 * squaredNorm<nDim>(avgV.velocity ());
186- Double phi = (gamma-1 ) / avgV.density ();
187- Double RdTdrho = phi*vel2 - avgV.pressure () / pow (avgV.density (),2 );
188- Double condOnRd = cond / (gasConst * dist_ij);
189-
190- dEdU (0 ) = area * (condOnRd * RdTdrho - contraction);
191- for (size_t iDim = 0 ; iDim < nDim; ++iDim) {
192- dEdU (iDim+1 ) = area * (condOnRd*phi*avgV.velocity (iDim) + dtau (iDim,0 ));
193- }
194- dEdU (nDim+1 ) = area * condOnRd * phi;
183+ auto dEdU = derived->energyJacobian (avgV, dtau, cond, area, dist_ij, iPoint, jPoint, solution);
195184
196185 /* --- Update momentum and energy terms ("symmetric" part). ---*/
197186 for (size_t iDim = 0 ; iDim < nDim; ++iDim) {
@@ -252,3 +241,125 @@ class CCompressibleViscousFlux : public CNumericsSIMD {
252241 viscousTerms (iEdge, iPoint, jPoint, avgV, V, solution_, vector_ij, geometry, args...);
253242 }
254243};
244+
245+ /* !
246+ * \class CCompressibleViscousFlux
247+ * \brief Decorator class to add viscous fluxes (compressible flow, ideal gas).
248+ */
249+ template <size_t NDIM>
250+ class CCompressibleViscousFlux : public CCompressibleViscousFluxBase <NDIM, CCompressibleViscousFlux<NDIM> > {
251+ public:
252+ static constexpr size_t nPrimVar = NDIM+7 ;
253+ using Base = CCompressibleViscousFluxBase<NDIM, CCompressibleViscousFlux<NDIM> >;
254+ using Base::gamma;
255+ using Base::gasConst;
256+ using Base::prandtlLam;
257+ using Base::prandtlTurb;
258+ using Base::cp;
259+
260+ /* !
261+ * \brief Constructor, initialize constants and booleans.
262+ */
263+ template <class ... Ts>
264+ CCompressibleViscousFlux (Ts&... args) : Base(args...) {}
265+
266+ /* !
267+ * \brief Compute the thermal conductivity.
268+ */
269+ template <class PrimitiveType >
270+ FORCEINLINE Double thermalConductivity (const PrimitiveType& V) const {
271+ return cp * (V.laminarVisc ()/prandtlLam + V.eddyVisc ()/prandtlTurb);
272+ }
273+
274+ /* !
275+ * \brief Compute Jacobian of the energy flux, except the part due to the work of viscous forces.
276+ */
277+ template <size_t nVar, size_t nDim, class PrimitiveType , class ... Ts>
278+ FORCEINLINE VectorDbl<nVar> energyJacobian (const PrimitiveType& V,
279+ const MatrixDbl<nDim,nVar>& dtau,
280+ Double thermalCond,
281+ Double area,
282+ Double dist_ij,
283+ Ts&... args) const {
284+ Double vel2 = 0.5 * squaredNorm<nDim>(V.velocity ());
285+ Double phi = (gamma-1 ) / V.density ();
286+ Double RdTdrho = phi*vel2 - V.pressure () / pow (V.density (),2 );
287+ Double condOnRd = thermalCond / (gasConst * dist_ij);
288+ Double contraction = 0.0 ;
289+ for (size_t iDim = 0 ; iDim < nDim; ++iDim) {
290+ contraction += dtau (iDim,0 ) * V.velocity (iDim);
291+ }
292+ VectorDbl<nVar> dEdU;
293+ dEdU (0 ) = area * (condOnRd * RdTdrho - contraction);
294+ for (size_t iDim = 0 ; iDim < nDim; ++iDim) {
295+ dEdU (iDim+1 ) = area * (dtau (iDim,0 ) - condOnRd*phi*V.velocity (iDim));
296+ }
297+ dEdU (nDim+1 ) = area * condOnRd * phi;
298+
299+ return dEdU;
300+ }
301+ };
302+
303+ /* !
304+ * \class CGeneralCompressibleViscousFlux
305+ * \brief Decorator class to add viscous fluxes (compressible flow, real gas).
306+ */
307+ template <size_t NDIM>
308+ class CGeneralCompressibleViscousFlux : public CCompressibleViscousFluxBase <NDIM, CGeneralCompressibleViscousFlux<NDIM> > {
309+ public:
310+ static constexpr size_t nPrimVar = NDIM+9 ;
311+ static constexpr size_t nSecVar = 4 ;
312+ using Base = CCompressibleViscousFluxBase<NDIM, CGeneralCompressibleViscousFlux<NDIM> >;
313+ using Base::prandtlTurb;
314+
315+ /* !
316+ * \brief Constructor, initialize constants and booleans.
317+ */
318+ template <class ... Ts>
319+ CGeneralCompressibleViscousFlux (Ts&... args) : Base(args...) {}
320+
321+ /* !
322+ * \brief Compute the thermal conductivity.
323+ */
324+ template <class PrimitiveType >
325+ FORCEINLINE Double thermalConductivity (const PrimitiveType& V) const {
326+ return V.thermalCond () + V.cp ()*V.eddyVisc ()/prandtlTurb;
327+ }
328+
329+ /* !
330+ * \brief Compute Jacobian of the energy flux, except the part due to the work of viscous forces.
331+ */
332+ template <size_t nVar, size_t nDim, class PrimitiveType , class VariableType >
333+ FORCEINLINE VectorDbl<nVar> energyJacobian (const PrimitiveType& V,
334+ const MatrixDbl<nDim,nVar>& dtau,
335+ Double thermalCond,
336+ Double area,
337+ Double dist_ij,
338+ Int iPoint,
339+ Int jPoint,
340+ const VariableType& solution) const {
341+ Double vel2 = squaredNorm<nDim>(V.velocity ());
342+ Double contraction = 0.0 ;
343+ for (size_t iDim = 0 ; iDim < nDim; ++iDim) {
344+ contraction += dtau (iDim,0 ) * V.velocity (iDim);
345+ }
346+
347+ auto secVar_i = gatherVariables<nSecVar>(iPoint, solution.GetSecondary ());
348+ auto secVar_j = gatherVariables<nSecVar>(jPoint, solution.GetSecondary ());
349+
350+ Double dTdrho_e = 0.5 * (secVar_i (2 ) + secVar_j (2 ));
351+ Double dTde_rho = 0.5 * (secVar_i (3 ) + secVar_j (3 )) / V.density ();
352+
353+ Double condOnDist = thermalCond / dist_ij;
354+ Double dTdrho = dTdrho_e + dTde_rho*(vel2-V.enthalpy ()+V.pressure ()/V.density ());
355+
356+ VectorDbl<nVar> dEdU;
357+ dEdU (0 ) = area * (condOnDist * dTdrho - contraction);
358+ for (size_t iDim = 0 ; iDim < nDim; ++iDim) {
359+ dEdU (iDim+1 ) = area * (dtau (iDim,0 ) - condOnDist*dTde_rho*V.velocity (iDim));
360+ }
361+ dEdU (nDim+1 ) = area * condOnDist * dTde_rho;
362+
363+ return dEdU;
364+ }
365+ };
0 commit comments