@@ -125,6 +125,8 @@ class CFVMFlowSolverBase : public CSolver {
125125 AeroCoeffsArray SurfaceCoeff; /* !< \brief Totals for each monitoring surface. */
126126 AeroCoeffs TotalCoeff; /* !< \brief Totals for all boundaries. */
127127
128+ su2double AeroCoeffForceRef = 1.0 ; /* !< \brief Reference force for aerodynamic coefficients. */
129+
128130 su2double InverseDesign = 0.0 ; /* !< \brief Inverse design functional for each boundary. */
129131 su2double Total_ComboObj = 0.0 ; /* !< \brief Total 'combo' objective for all monitored boundaries */
130132 su2double Total_Custom_ObjFunc = 0.0 ; /* !< \brief Total custom objective function for all the boundaries. */
@@ -249,6 +251,36 @@ class CFVMFlowSolverBase : public CSolver {
249251 */
250252 inline virtual void InstantiateEdgeNumerics (const CSolver* const * solvers, const CConfig* config) {}
251253
254+ /* !
255+ * \brief Compute the viscous contribution for a particular edge.
256+ * \note The convective residual methods include a call to this for each edge,
257+ * this allows convective and viscous loops to be "fused".
258+ * \param[in] iEdge - Edge for which the flux and Jacobians are to be computed.
259+ * \param[in] geometry - Geometrical definition of the problem.
260+ * \param[in] solver_container - Container vector with all the solutions.
261+ * \param[in] numerics - Description of the numerical method.
262+ * \param[in] config - Definition of the particular problem.
263+ */
264+ inline virtual void Viscous_Residual (unsigned long iEdge, CGeometry *geometry, CSolver **solver_container,
265+ CNumerics *numerics, CConfig *config) { }
266+ void Viscous_Residual_impl (unsigned long iEdge, CGeometry *geometry, CSolver **solver_container,
267+ CNumerics *numerics, CConfig *config);
268+ using CSolver::Viscous_Residual; /* --- Silence warning ---*/
269+
270+ /* !
271+ * \brief General implementation to load a flow solution from a restart file.
272+ * \param[in] geometry - Geometrical definition of the problem.
273+ * \param[in] solver - Container vector with all of the solvers.
274+ * \param[in] config - Definition of the particular problem.
275+ * \param[in] iter - Current external iteration number.
276+ * \param[in] update_geo - Flag for updating coords and grid velocity.
277+ * \param[in] RestartSolution - Optional buffer to load restart vars into,
278+ * this allows default values to be given when nVar > nVar_Restart.
279+ * \param[in] nVar_Restart - Number of restart variables, if 0 defaults to nVar.
280+ */
281+ void LoadRestart_impl (CGeometry **geometry, CSolver ***solver, CConfig *config, int iter, bool update_geo,
282+ su2double* RestartSolution = nullptr , unsigned short nVar_Restart = 0 );
283+
252284 /* !
253285 * \brief Generic implementation to compute the time step based on CFL and conv/visc eigenvalues.
254286 * \param[in] geometry - Geometrical definition of the problem.
@@ -949,36 +981,90 @@ class CFVMFlowSolverBase : public CSolver {
949981
950982 /* !
951983 * \brief Evaluate the vorticity and strain rate magnitude.
984+ * \tparam VelocityOffset: Index in the primitive variables where the velocity starts.
952985 */
953- inline void ComputeVorticityAndStrainMag (const CConfig& config, unsigned short iMesh) {
986+ template <size_t VelocityOffset>
987+ void ComputeVorticityAndStrainMag (const CConfig& config, unsigned short iMesh) {
988+
989+ const auto & Gradient_Primitive = nodes->GetGradient_Primitive ();
990+ auto & StrainMag = nodes->GetStrainMag ();
954991
955992 SU2_OMP_MASTER {
956993 StrainMag_Max = 0.0 ;
957994 Omega_Max = 0.0 ;
958995 }
959996 SU2_OMP_BARRIER
960997
961- nodes-> SetVorticity_StrainMag () ;
998+ su2double strainMax = 0.0 , omegaMax = 0.0 ;
962999
963- /* --- Min and Max are not really differentiable --- */
964- const bool wasActive = AD::BeginPassive ();
1000+ SU2_OMP_FOR_STAT (omp_chunk_size)
1001+ for ( unsigned long iPoint = 0 ; iPoint < nPoint; ++iPoint) {
9651002
966- su2double strainMax = 0.0 , omegaMax = 0.0 ;
1003+ constexpr size_t u = VelocityOffset;
1004+ constexpr size_t v = VelocityOffset+1 ;
1005+ constexpr size_t w = VelocityOffset+2 ;
9671006
968- SU2_OMP (for schedule (static ,omp_chunk_size) nowait)
969- for (unsigned long iPoint = 0 ; iPoint < nPoint; iPoint++) {
970- strainMax = max (strainMax, nodes->GetStrainMag (iPoint));
971- omegaMax = max (omegaMax, GeometryToolbox::Norm (3 , nodes->GetVorticity (iPoint)));
972- }
973- SU2_OMP_CRITICAL {
974- StrainMag_Max = max (StrainMag_Max, strainMax);
975- Omega_Max = max (Omega_Max, omegaMax);
1007+ /* --- Vorticity ---*/
1008+
1009+ su2double* Vorticity = nodes->GetVorticity (iPoint);
1010+
1011+ Vorticity[0 ] = 0.0 ; Vorticity[1 ] = 0.0 ;
1012+
1013+ Vorticity[2 ] = Gradient_Primitive (iPoint,v,0 )-Gradient_Primitive (iPoint,u,1 );
1014+
1015+ if (nDim == 3 ) {
1016+ Vorticity[0 ] = Gradient_Primitive (iPoint,w,1 )-Gradient_Primitive (iPoint,v,2 );
1017+ Vorticity[1 ] = -(Gradient_Primitive (iPoint,w,0 )-Gradient_Primitive (iPoint,u,2 ));
1018+ }
1019+
1020+ /* --- Strain Magnitude ---*/
1021+
1022+ AD::StartPreacc ();
1023+ AD::SetPreaccIn (&Gradient_Primitive[iPoint][VelocityOffset], nDim, nDim);
1024+
1025+ su2double Div = 0.0 ;
1026+ for (unsigned long iDim = 0 ; iDim < nDim; iDim++)
1027+ Div += Gradient_Primitive (iPoint, iDim+VelocityOffset, iDim);
1028+ Div /= 3.0 ;
1029+
1030+ StrainMag (iPoint) = 0.0 ;
1031+
1032+ /* --- Add diagonal part ---*/
1033+
1034+ for (unsigned long iDim = 0 ; iDim < nDim; iDim++) {
1035+ StrainMag (iPoint) += pow (Gradient_Primitive (iPoint, iDim+VelocityOffset, iDim) - Div, 2 );
1036+ }
1037+ if (nDim == 2 ) {
1038+ StrainMag (iPoint) += pow (Div, 2 );
1039+ }
1040+
1041+ /* --- Add off diagonals ---*/
1042+
1043+ StrainMag (iPoint) += 2.0 *pow (0.5 *(Gradient_Primitive (iPoint,u,1 ) + Gradient_Primitive (iPoint,v,0 )), 2 );
1044+
1045+ if (nDim == 3 ) {
1046+ StrainMag (iPoint) += 2.0 *pow (0.5 *(Gradient_Primitive (iPoint,u,2 ) + Gradient_Primitive (iPoint,w,0 )), 2 );
1047+ StrainMag (iPoint) += 2.0 *pow (0.5 *(Gradient_Primitive (iPoint,v,2 ) + Gradient_Primitive (iPoint,w,1 )), 2 );
1048+ }
1049+
1050+ StrainMag (iPoint) = sqrt (2.0 *StrainMag (iPoint));
1051+ AD::SetPreaccOut (StrainMag (iPoint));
1052+
1053+ /* --- Max is not differentiable, so we not register them for preacc. ---*/
1054+ strainMax = max (strainMax, StrainMag (iPoint));
1055+ omegaMax = max (omegaMax, GeometryToolbox::Norm (3 , Vorticity));
1056+
1057+ AD::EndPreacc ();
9761058 }
9771059
9781060 if ((iMesh == MESH_0) && (config.GetComm_Level () == COMM_FULL)) {
1061+ SU2_OMP_CRITICAL {
1062+ StrainMag_Max = max (StrainMag_Max, strainMax);
1063+ Omega_Max = max (Omega_Max, omegaMax);
1064+ }
1065+
9791066 SU2_OMP_BARRIER
980- SU2_OMP_MASTER
981- {
1067+ SU2_OMP_MASTER {
9821068 su2double MyOmega_Max = Omega_Max;
9831069 su2double MyStrainMag_Max = StrainMag_Max;
9841070
@@ -988,7 +1074,6 @@ class CFVMFlowSolverBase : public CSolver {
9881074 SU2_OMP_BARRIER
9891075 }
9901076
991- AD::EndPassive (wasActive);
9921077 }
9931078
9941079 /* !
@@ -997,6 +1082,26 @@ class CFVMFlowSolverBase : public CSolver {
9971082 ~CFVMFlowSolverBase ();
9981083
9991084 public:
1085+
1086+ /* !
1087+ * \brief Load a solution from a restart file.
1088+ * \param[in] geometry - Geometrical definition of the problem.
1089+ * \param[in] solver - Container vector with all of the solvers.
1090+ * \param[in] config - Definition of the particular problem.
1091+ * \param[in] iter - Current external iteration number.
1092+ * \param[in] update_geo - Flag for updating coords and grid velocity.
1093+ */
1094+ void LoadRestart (CGeometry **geometry, CSolver ***solver, CConfig *config, int iter, bool update_geo) override ;
1095+
1096+ /* !
1097+ * \brief Set the initial condition for the Euler Equations.
1098+ * \param[in] geometry - Geometrical definition of the problem.
1099+ * \param[in] solver_container - Container with all the solutions.
1100+ * \param[in] config - Definition of the particular problem.
1101+ * \param[in] ExtIter - External iteration.
1102+ */
1103+ void SetInitialCondition (CGeometry **geometry, CSolver ***solver_container, CConfig *config, unsigned long ExtIter) override ;
1104+
10001105 /* !
10011106 * \brief Compute the gradient of the primitive variables using Green-Gauss method,
10021107 * and stores the result in the <i>Gradient_Primitive</i> variable.
@@ -1490,6 +1595,11 @@ class CFVMFlowSolverBase : public CSolver {
14901595 */
14911596 inline su2double GetTotal_CEff () const final { return TotalCoeff.CEff ; }
14921597
1598+ /* !
1599+ * \brief Get the reference force used to compute CL, CD, etc.
1600+ */
1601+ inline su2double GetAeroCoeffsReferenceForce () const final { return AeroCoeffForceRef; }
1602+
14931603 /* !
14941604 * \brief Provide the total (inviscid + viscous) non dimensional lift coefficient.
14951605 * \return Value of the lift coefficient (inviscid + viscous contribution).
0 commit comments