diff --git a/Common/include/config_structure.hpp b/Common/include/config_structure.hpp index bc85e34f16d9..7359c0d5ed99 100644 --- a/Common/include/config_structure.hpp +++ b/Common/include/config_structure.hpp @@ -414,6 +414,7 @@ class CConfig { unsigned short nCFL; /*!< \brief Number of CFL, one for each multigrid level. */ su2double CFLRedCoeff_Turb, /*!< \brief CFL reduction coefficient on the LevelSet problem. */ + CFLRedCoeff_Scalar, /*!< \brief CFL reduction coefficient for the scalar transport equations. */ CFLRedCoeff_AdjFlow, /*!< \brief CFL reduction coefficient for the adjoint problem. */ CFLRedCoeff_AdjTurb, /*!< \brief CFL reduction coefficient for the adjoint problem. */ CFLFineGrid, /*!< \brief CFL of the finest grid. */ @@ -455,6 +456,7 @@ class CConfig { Kind_ViscosityModel, /*!< \brief Kind of the Viscosity Model*/ Kind_ConductivityModel, /*!< \brief Kind of the Thermal Conductivity Model*/ Kind_ConductivityModel_Turb, /*!< \brief Kind of the Turbulent Thermal Conductivity Model*/ + Kind_DiffusivityModel, /*!< \brief Kind of the mass diffusivity model*/ Kind_FreeStreamOption, /*!< \brief Kind of free stream option to choose if initializing with density or temperature */ Kind_InitOption, /*!< \brief Kind of Init option to choose if initializing with Reynolds number or with thermodynamic conditions */ Kind_GasModel, /*!< \brief Kind of the Gas Model. */ @@ -478,6 +480,7 @@ class CConfig { Kind_SlopeLimit, /*!< \brief Global slope limiter. */ Kind_SlopeLimit_Flow, /*!< \brief Slope limiter for flow equations.*/ Kind_SlopeLimit_Turb, /*!< \brief Slope limiter for the turbulence equation.*/ + Kind_SlopeLimit_Scalar, /*!< \brief Slope limiter for the scalar transport equations.*/ Kind_SlopeLimit_AdjTurb, /*!< \brief Slope limiter for the adjoint turbulent equation.*/ Kind_SlopeLimit_AdjFlow, /*!< \brief Slope limiter for the adjoint equation.*/ Kind_TimeNumScheme, /*!< \brief Global explicit or implicit time integration. */ @@ -485,6 +488,7 @@ class CConfig { Kind_TimeIntScheme_FEM_Flow, /*!< \brief Time integration for the flow equations. */ Kind_ADER_Predictor, /*!< \brief Predictor step of the ADER-DG time integration scheme. */ Kind_TimeIntScheme_AdjFlow, /*!< \brief Time integration for the adjoint flow equations. */ + Kind_TimeIntScheme_Scalar, /*!< \brief Time integration for the scalar transport model. */ Kind_TimeIntScheme_Turb, /*!< \brief Time integration for the turbulence model. */ Kind_TimeIntScheme_AdjTurb, /*!< \brief Time integration for the adjoint turbulence model. */ Kind_TimeIntScheme_Heat, /*!< \brief Time integration for the wave equations. */ @@ -497,18 +501,21 @@ class CConfig { Kind_ConvNumScheme_Heat, /*!< \brief Centered or upwind scheme for the flow equations. */ Kind_ConvNumScheme_AdjFlow, /*!< \brief Centered or upwind scheme for the adjoint flow equations. */ Kind_ConvNumScheme_Turb, /*!< \brief Centered or upwind scheme for the turbulence model. */ + Kind_ConvNumScheme_Scalar, /*!< \brief Centered or upwind scheme for the scalar transport equations. */ Kind_ConvNumScheme_AdjTurb, /*!< \brief Centered or upwind scheme for the adjoint turbulence model. */ Kind_ConvNumScheme_Template, /*!< \brief Centered or upwind scheme for the level set equation. */ Kind_Centered, /*!< \brief Centered scheme. */ Kind_Centered_Flow, /*!< \brief Centered scheme for the flow equations. */ Kind_Centered_AdjFlow, /*!< \brief Centered scheme for the adjoint flow equations. */ Kind_Centered_Turb, /*!< \brief Centered scheme for the turbulence model. */ + Kind_Centered_Scalar, /*!< \brief Centered scheme for the scalar transport equations. */ Kind_Centered_AdjTurb, /*!< \brief Centered scheme for the adjoint turbulence model. */ Kind_Centered_Template, /*!< \brief Centered scheme for the template model. */ Kind_Upwind, /*!< \brief Upwind scheme. */ Kind_Upwind_Flow, /*!< \brief Upwind scheme for the flow equations. */ Kind_Upwind_AdjFlow, /*!< \brief Upwind scheme for the adjoint flow equations. */ Kind_Upwind_Turb, /*!< \brief Upwind scheme for the turbulence model. */ + Kind_Upwind_Scalar, /*!< \brief Upwind scheme for the scalar transport equations. */ Kind_Upwind_AdjTurb, /*!< \brief Upwind scheme for the adjoint turbulence model. */ Kind_Upwind_Template, /*!< \brief Upwind scheme for the template model. */ Kind_FEM, /*!< \brief Finite element scheme for the flow equations. */ @@ -522,6 +529,7 @@ class CConfig { bool MUSCL, /*!< \brief MUSCL scheme .*/ MUSCL_Flow, /*!< \brief MUSCL scheme for the flow equations.*/ MUSCL_Turb, /*!< \brief MUSCL scheme for the turbulence equations.*/ + MUSCL_Scalar, /*!< \brief MUSCL scheme for the scalar transport equations.*/ MUSCL_Heat, /*!< \brief MUSCL scheme for the (fvm) heat equation.*/ MUSCL_AdjFlow, /*!< \brief MUSCL scheme for the adj flow equations.*/ MUSCL_AdjTurb, /*!< \brief MUSCL scheme for the adj turbulence equations.*/ @@ -537,6 +545,7 @@ class CConfig { Kind_Struct_Solver, /*!< \brief Determines the geometric condition (small or large deformations) for structural analysis. */ Kind_DV_FEA; /*!< \brief Kind of Design Variable for FEA problems.*/ unsigned short Kind_Turb_Model; /*!< \brief Turbulent model definition. */ + unsigned short Kind_Scalar_Model; /*!< \brief Scalar transport model definition. */ unsigned short Kind_SGS_Model; /*!< \brief LES SGS model definition. */ unsigned short Kind_Trans_Model, /*!< \brief Transition model definition. */ Kind_ActDisk, Kind_Engine_Inflow, Kind_Inlet, *Kind_Inc_Inlet, *Kind_Inc_Outlet, *Kind_Data_Riemann, *Kind_Data_Giles; /*!< \brief Kind of inlet boundary treatment. */ @@ -558,6 +567,7 @@ class CConfig { su2double Roe_Kappa; /*!< \brief Relaxation of the Roe scheme. */ su2double Relaxation_Factor_Flow; /*!< \brief Relaxation coefficient of the linear solver mean flow. */ su2double Relaxation_Factor_Turb; /*!< \brief Relaxation coefficient of the linear solver turbulence. */ + su2double Relaxation_Factor_Scalar; /*!< \brief Relaxation coefficient of the linear solver for scalar transport equations. */ su2double Relaxation_Factor_AdjFlow; /*!< \brief Relaxation coefficient of the linear solver adjoint mean flow. */ su2double Relaxation_Factor_CHT; /*!< \brief Relaxation coefficient for the update of conjugate heat variables. */ su2double AdjTurb_Linear_Error; /*!< \brief Min error of the turbulent adjoint linear solver for the implicit formulation. */ @@ -782,6 +792,7 @@ class CConfig { Inc_Density_Init, /*!< \brief Initial density for incompressible flows. */ *Inc_Velocity_Init, /*!< \brief Initial velocity vector for incompressible flows. */ Inc_Temperature_Init, /*!< \brief Initial temperature for incompressible flows w/ heat transfer. */ + Scalar_Init, /*!< \brief Initial uniform value for scalar transport. */ Heat_Flux_Ref, /*!< \brief Reference heat flux for non-dim. */ Gas_Constant_Ref, /*!< \brief Reference specific gas constant. */ Temperature_Critical, /*!< \brief Critical Temperature for real fluid model. */ @@ -792,6 +803,11 @@ class CConfig { Mu_ConstantND, /*!< \brief Non-dimensional constant viscosity for ConstantViscosity model. */ Kt_Constant, /*!< \brief Constant thermal conductivity for ConstantConductivity model. */ Kt_ConstantND, /*!< \brief Non-dimensional constant thermal conductivity for ConstantConductivity model. */ + Diffusivity_Constant, /*!< \brief Constant mass diffusivity for scalar transport. */ + Diffusivity_ConstantND, /*!< \brief Non-dim. constant mass diffusivity for scalar transport. */ + Schmidt_Lam, /*!< \brief Laminar Schmidt number for mass diffusion. */ + Schmidt_Turb, /*!< \brief Turbulent Schmidt number for mass diffusion. */ + Diffusivity_Ref, /*!< \brief Reference mass diffusion for species equations. */ Mu_Ref, /*!< \brief Reference viscosity for Sutherland model. */ Mu_RefND, /*!< \brief Non-dimensional reference viscosity for Sutherland model. */ Mu_Temperature_Ref, /*!< \brief Reference temperature for Sutherland model. */ @@ -1026,6 +1042,10 @@ class CConfig { su2double *FreeStreamTurboNormal; /*!< \brief Direction to initialize the flow in turbomachinery computation */ su2double Restart_Bandwidth_Agg; /*!< \brief The aggregate of the bandwidth for writing binary restarts (to be averaged later). */ su2double Max_Vel2; /*!< \brief The maximum velocity^2 in the domain for the incompressible preconditioner. */ + bool Scalar_Clipping; /*!< \brief Boolean that activates clipping for scalar transport. */ + su2double Scalar_Clipping_Max, /*!< \brief Maximum value of clipping for scalar transport. */ + Scalar_Clipping_Min; /*!< \brief Minimum value of clipping for scalar transport. */ + bool topology_optimization; /*!< \brief If the structural solver should consider a variable density field to penalize element stiffness. */ string top_optim_output_file; /*!< \brief File to where the derivatives w.r.t. element densities will be written to. */ su2double simp_exponent; /*!< \brief Exponent for the density-based stiffness penalization of the SIMP method. */ @@ -2113,6 +2133,30 @@ class CConfig { */ su2double GetInc_Temperature_Init(void); + /*! + * \brief Get the initial value for a scalar transport. + * \return Initial value for scalar transport. + */ + su2double GetScalar_Init(void); + + /*! + * \brief Get the flag for activating scalar transport clipping + * \return Flag for scalar clipping + */ + bool GetScalar_Clipping(void); + + /*! + * \brief Get the maximum bound for scalar transport clipping + * \return Maximum value for scalar clipping + */ + su2double GetScalar_Clipping_Max(void); + + /*! + * \brief Get the minimum bound for scalar transport clipping + * \return Minimum value for scalar clipping + */ + su2double GetScalar_Clipping_Min(void); + /*! * \brief Get the Young's modulus of elasticity. * \return Value of the Young's modulus of elasticity. @@ -3808,13 +3852,19 @@ class CConfig { * \return Conductivity model. */ unsigned short GetKind_ConductivityModel(void); - + /*! * \brief Get the value of the turbulent thermal conductivity model. * \return Turbulent conductivity model. */ unsigned short GetKind_ConductivityModel_Turb(void); + /*! + * \brief Get the value of the mass diffusivity model. + * \return Mass diffusivity model. + */ + unsigned short GetKind_DiffusivityModel(void); + /*! * \brief Get the value of the constant viscosity. * \return Constant viscosity. @@ -3839,6 +3889,30 @@ class CConfig { */ su2double GetKt_ConstantND(void); + /*! + * \brief Get the value of the constant mass diffusivity for scalar transport. + * \return Constant mass diffusivity. + */ + su2double GetDiffusivity_Constant(void); + + /*! + * \brief Get the value of the non-dimensional constant mass diffusivity. + * \return Non-dimensional constant mass diffusivity. + */ + su2double GetDiffusivity_ConstantND(void); + + /*! + * \brief Get the value of the laminar Schmidt number for scalar transport. + * \return Laminar Schmidt number for scalar transport. + */ + su2double GetSchmidt_Lam(void); + + /*! + * \brief Get the value of the turbulent Schmidt number for scalar transport. + * \return Turbulent Schmidt number for scalar transport. + */ + su2double GetSchmidt_Turb(void); + /*! * \brief Get the value of the reference viscosity for Sutherland model. * \return The reference viscosity. @@ -3945,6 +4019,16 @@ class CConfig { */ void SetKt_ConstantND(su2double kt_const); + /*! + * \brief Set the value of the non-dimensional constant mass diffusivity. + */ + void SetDiffusivity_ConstantND(su2double diffusivity_const); + + /*! + * \brief Set the value of the reference mass diffusivity. + */ + void SetDiffusivity_Ref(su2double diffusivity_ref); + /*! * \brief Set the value of the non-dimensional reference viscosity for Sutherland model. */ @@ -4078,6 +4162,12 @@ class CConfig { */ su2double GetRelaxation_Factor_Turb(void); + /*! + * \brief Get the relaxation coefficient of the linear solver for the implicit formulation. + * \return relaxation coefficient of the linear solver for the implicit formulation. + */ + su2double GetRelaxation_Factor_Scalar(void); + /*! * \brief Get the relaxation coefficient of the CHT coupling. * \return relaxation coefficient of the CHT coupling. @@ -4263,6 +4353,12 @@ class CConfig { */ unsigned short GetKind_SGS_Model(void); + /*! + * \brief Get the kind of the scalar transport model. + * \return Kind of the scalar transport model. + */ + unsigned short GetKind_Scalar_Model(void); + /*! * \brief Get the kind of adaptation technique. * \return Kind of adaptation technique. @@ -4347,6 +4443,15 @@ class CConfig { */ bool GetMUSCL_Turb(void); + /*! + * \brief Get if the upwind scheme used MUSCL or not. + * \note This is the information that the code will use, the method will + * change in runtime depending of the specific equation (direct, adjoint, + * linearized) that is being solved. + * \return MUSCL scheme. + */ + bool GetMUSCL_Scalar(void); + /*! * \brief Get if the upwind scheme used MUSCL or not. * \note This is the information that the code will use, the method will @@ -4525,6 +4630,12 @@ class CConfig { */ unsigned short GetKind_SlopeLimit_Turb(void); + /*! + * \brief Get the method for limiting the spatial gradients. + * \return Method for limiting the spatial gradients solving the scalar transport equations. + */ + unsigned short GetKind_SlopeLimit_Scalar(void); + /*! * \brief Get the method for limiting the spatial gradients. * \return Method for limiting the spatial gradients solving the adjoint turbulent equation. @@ -4626,6 +4737,39 @@ class CConfig { */ su2double GetKappa_1st_AdjFlow(void); + /*! + * \brief Get the kind of integration scheme (implicit) + * for the scalar transport equations. + * \note This value is obtained from the config file, and it is constant + * during the computation. + * \return Kind of integration scheme for the scalar transport equations. + */ + unsigned short GetKind_TimeIntScheme_Scalar(void); + + /*! + * \brief Get the kind of convective numerical scheme for the scalar transport equations (upwind). + * \note This value is obtained from the config file, and it is constant + * during the computation. + * \return Kind of convective numerical scheme for the scalar transport equations. + */ + unsigned short GetKind_ConvNumScheme_Scalar(void); + + /*! + * \brief Get the kind of center convective numerical scheme for the scalar transport equations. + * \note This value is obtained from the config file, and it is constant + * during the computation. + * \return Kind of center convective numerical scheme for the scalar transport equations. + */ + unsigned short GetKind_Centered_Scalar(void); + + /*! + * \brief Get the kind of upwind convective numerical scheme for the scalar transport equations. + * \note This value is obtained from the config file, and it is constant + * during the computation. + * \return Kind of upwind convective numerical scheme for the scalar transport equations. + */ + unsigned short GetKind_Upwind_Scalar(void); + /*! * \brief Get the kind of integration scheme (implicit) * for the turbulence equations. @@ -6543,11 +6687,17 @@ class CConfig { su2double GetExhaust_Pressure_Target(string val_index); /*! - * \brief Value of the CFL reduction in LevelSet problems. - * \return Value of the CFL reduction in LevelSet problems. + * \brief Value of the CFL reduction in turbulence problems. + * \return Value of the CFL reduction in turbulence problems. */ su2double GetCFLRedCoeff_Turb(void); + /*! + * \brief Value of the CFL reduction for scalar transport equations. + * \return Value of the CFL reduction for scalar transport equations. + */ + su2double GetCFLRedCoeff_Scalar(void); + /*! * \brief Get the flow direction unit vector at an inlet boundary. * \param[in] val_index - Index corresponding to the inlet boundary. diff --git a/Common/include/config_structure.inl b/Common/include/config_structure.inl index 8a09a88697ed..16c204e78d0c 100644 --- a/Common/include/config_structure.inl +++ b/Common/include/config_structure.inl @@ -476,6 +476,14 @@ inline su2double* CConfig::GetInc_Velocity_Init(void) { return Inc_Velocity_Init inline su2double CConfig::GetInc_Temperature_Init(void) { return Inc_Temperature_Init; } +inline su2double CConfig::GetScalar_Init(void) { return Scalar_Init; } + +inline bool CConfig::GetScalar_Clipping(void) { return Scalar_Clipping; } + +inline su2double CConfig::GetScalar_Clipping_Max(void) { return Scalar_Clipping_Max; } + +inline su2double CConfig::GetScalar_Clipping_Min(void) { return Scalar_Clipping_Min; } + inline su2double CConfig::GetHeat_Flux_Ref(void) { return Heat_Flux_Ref; } inline su2double CConfig::GetWallTemperature(void) { return Wall_Temperature; } @@ -870,6 +878,8 @@ inline unsigned short CConfig::GetKind_ConductivityModel(void) { return Kind_Con inline unsigned short CConfig::GetKind_ConductivityModel_Turb(void) { return Kind_ConductivityModel_Turb; } +inline unsigned short CConfig::GetKind_DiffusivityModel(void) { return Kind_DiffusivityModel; } + inline su2double CConfig::GetMu_Constant(void) { return Mu_Constant; } inline su2double CConfig::GetMu_ConstantND(void) { return Mu_ConstantND; } @@ -878,6 +888,14 @@ inline su2double CConfig::GetKt_Constant(void) { return Kt_Constant; } inline su2double CConfig::GetKt_ConstantND(void) { return Kt_ConstantND; } +inline su2double CConfig::GetDiffusivity_Constant(void) { return Diffusivity_Constant; } + +inline su2double CConfig::GetDiffusivity_ConstantND(void) { return Diffusivity_ConstantND; } + +inline su2double CConfig::GetSchmidt_Lam(void) { return Schmidt_Lam; } + +inline su2double CConfig::GetSchmidt_Turb(void) { return Schmidt_Turb; } + inline su2double CConfig::GetMu_Ref(void) { return Mu_Ref; } inline su2double CConfig::GetMu_RefND(void) { return Mu_RefND; } @@ -924,6 +942,8 @@ inline void CConfig::SetMu_PolyCoeffND(su2double val_coeff, unsigned short val_i inline void CConfig::SetKt_PolyCoeffND(su2double val_coeff, unsigned short val_index) { KtPolyCoefficientsND[val_index] = val_coeff; } +inline void CConfig::SetDiffusivity_ConstantND(su2double diffusivity_const) { Diffusivity_ConstantND = diffusivity_const; } + inline unsigned short CConfig::GetKind_GridMovement() { return Kind_GridMovement; } inline void CConfig::SetKind_GridMovement(unsigned short motion_Type) { Kind_GridMovement = motion_Type; } @@ -1018,6 +1038,8 @@ inline su2double CConfig::GetRelaxation_Factor_AdjFlow(void) { return Relaxation inline su2double CConfig::GetRelaxation_Factor_Turb(void) { return Relaxation_Factor_Turb; } +inline su2double CConfig::GetRelaxation_Factor_Scalar(void) { return Relaxation_Factor_Scalar; } + inline su2double CConfig::GetRelaxation_Factor_CHT(void) { return Relaxation_Factor_CHT; } inline su2double CConfig::GetRoe_Kappa(void) { return Roe_Kappa; } @@ -1084,6 +1106,8 @@ inline bool CConfig::GetMUSCL_Flow(void) { return MUSCL_Flow; } inline bool CConfig::GetMUSCL_Turb(void) { return MUSCL_Turb; } +inline bool CConfig::GetMUSCL_Scalar(void) { return MUSCL_Scalar; } + inline bool CConfig::GetMUSCL_Heat(void) { return MUSCL_Heat; } inline bool CConfig::GetMUSCL_AdjFlow(void) { return MUSCL_AdjFlow; } @@ -1116,6 +1140,8 @@ inline unsigned short CConfig::GetKind_SlopeLimit_Flow(void) { return Kind_Slope inline unsigned short CConfig::GetKind_SlopeLimit_Turb(void) { return Kind_SlopeLimit_Turb; } +inline unsigned short CConfig::GetKind_SlopeLimit_Scalar(void) { return Kind_SlopeLimit_Scalar; } + inline unsigned short CConfig::GetKind_SlopeLimit_AdjTurb(void) { return Kind_SlopeLimit_AdjTurb; } inline unsigned short CConfig::GetKind_SlopeLimit_AdjFlow(void) { return Kind_SlopeLimit_AdjFlow; } @@ -1152,6 +1178,14 @@ inline su2double CConfig::GetKappa_2nd_AdjFlow(void) { return Kappa_2nd_AdjFlow; inline su2double CConfig::GetKappa_4th_AdjFlow(void) { return Kappa_4th_AdjFlow; } +inline unsigned short CConfig::GetKind_TimeIntScheme_Scalar(void) { return Kind_TimeIntScheme_Scalar; } + +inline unsigned short CConfig::GetKind_ConvNumScheme_Scalar(void) { return Kind_ConvNumScheme_Scalar; } + +inline unsigned short CConfig::GetKind_Centered_Scalar(void) { return Kind_Centered_Scalar; } + +inline unsigned short CConfig::GetKind_Upwind_Scalar(void) { return Kind_Upwind_Scalar; } + inline unsigned short CConfig::GetKind_TimeIntScheme_Turb(void) { return Kind_TimeIntScheme_Turb; } inline unsigned short CConfig::GetKind_ConvNumScheme_Turb(void) { return Kind_ConvNumScheme_Turb; } @@ -1581,6 +1615,8 @@ inline su2double CConfig::GetFixAzimuthalLine(void) { return FixAzimuthalLine; } inline su2double CConfig::GetCFLRedCoeff_Turb(void) { return CFLRedCoeff_Turb; } +inline su2double CConfig::GetCFLRedCoeff_Scalar(void) { return CFLRedCoeff_Scalar; } + inline bool CConfig::GetGrid_Movement(void) { return (Kind_GridMovement != NO_MOVEMENT) || ((nKind_SurfaceMovement > 0) && !GetSurface_Movement(FLUID_STRUCTURE_STATIC)); } inline bool CConfig::GetDynamic_Grid(void) { @@ -1617,6 +1653,8 @@ inline unsigned short CConfig::GetKind_Turb_Model(void) { return Kind_Turb_Model inline unsigned short CConfig::GetKind_Trans_Model(void) { return Kind_Trans_Model; } +inline unsigned short CConfig::GetKind_Scalar_Model(void) { return Kind_Scalar_Model; } + inline unsigned short CConfig::GetKind_SGS_Model(void) { return Kind_SGS_Model; } inline bool CConfig::GetFrozen_Visc_Cont(void) { return Frozen_Visc_Cont; } diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 4edc8f8e88a1..52bcc05925ac 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -444,6 +444,7 @@ enum RUNTIME_TYPE { RUNTIME_HEAT_SYS = 21, /*!< \brief One-physics case, the code is solving the heat equation. */ RUNTIME_ADJHEAT_SYS = 31, /*!< \brief One-physics case, the code is solving the adjoint heat equation. */ RUNTIME_TRANS_SYS = 22, /*!< \brief One-physics case, the code is solving the turbulence model. */ + RUNTIME_SCALAR_SYS = 23, /*!< \brief One-physics case, the code is solving the turbulence model. */ }; const int FLOW_SOL = 0; /*!< \brief Position of the mean flow solution in the solver container array. */ @@ -456,6 +457,8 @@ const int TRANS_SOL = 4; /*!< \brief Position of the transition model solution i const int HEAT_SOL = 5; /*!< \brief Position of the heat equation in the solution solver array. */ const int ADJHEAT_SOL = 6; /*!< \brief Position of the adjoint heat equation in the solution solver array. */ +const int SCALAR_SOL = 5; /*!< \brief Position of the scalar transport solution in the solver container array. */ + const int FEA_SOL = 0; /*!< \brief Position of the FEA equation in the solution solver array. */ const int ADJFEA_SOL = 1; /*!< \brief Position of the FEA adjoint equation in the solution solver array. */ @@ -624,6 +627,18 @@ static const map TurbConductivityModel_Map ("NONE", NO_CONDUCTIVITY_TURB) ("CONSTANT_PRANDTL_TURB", CONSTANT_PRANDTL_TURB); +/*! + * \brief types of mass diffusivity models + */ +enum ENUM_DIFFUSIVITYMODEL { + CONSTANT_DIFFUSIVITY = 0, /*!< \brief Constant mass diffusivity for scalar transport. */ + CONSTANT_SCHMIDT = 1 /*!< \brief Constant Schmidt number for mass diffusion in scalar transport. */ +}; + +static const map DiffusivityModel_Map = CCreateMap +("CONSTANT_DIFFUSIVITY", CONSTANT_DIFFUSIVITY) +("CONSTANT_SCHMIDT", CONSTANT_SCHMIDT); + /*! * \brief types of unsteady mesh motion */ @@ -853,6 +868,21 @@ static const map Trans_Model_Map = CCreateMap Scalar_Model_Map = CCreateMap +("NONE", NO_SCALAR_MODEL) +("PASSIVE_SCALAR", PASSIVE_SCALAR) +("PROGRESS_VARIABLE", PROGRESS_VARIABLE) +("CUSTOM_SCALAR", CUSTOM_SCALAR); + /*! * \brief types of subgrid scale models */ diff --git a/Common/src/config_structure.cpp b/Common/src/config_structure.cpp index e81d2b33b38a..14c141a69a1d 100644 --- a/Common/src/config_structure.cpp +++ b/Common/src/config_structure.cpp @@ -886,6 +886,10 @@ void CConfig::SetConfig_Options() { addEnumOption("KIND_TURB_MODEL", Kind_Turb_Model, Turb_Model_Map, NO_TURB_MODEL); /*!\brief KIND_TRANS_MODEL \n DESCRIPTION: Specify transition model OPTIONS: see \link Trans_Model_Map \endlink \n DEFAULT: NO_TRANS_MODEL \ingroup Config*/ addEnumOption("KIND_TRANS_MODEL", Kind_Trans_Model, Trans_Model_Map, NO_TRANS_MODEL); + /*!\brief KIND_SCALAR_MODEL \n DESCRIPTION: Specify scalar transport model \n Options: see \link Scalar_Model_Map \endlink \n DEFAULT: NO_SCALAR_MODEL \ingroup Config*/ + addEnumOption("KIND_SCALAR_MODEL", Kind_Scalar_Model, Scalar_Model_Map, NO_SCALAR_MODEL); + /*!\brief KIND_TRANS_MODEL \n DESCRIPTION: Specify transition model OPTIONS: see \link Trans_Model_Map \endlink \n DEFAULT: NO_TRANS_MODEL \ingroup Config*/ + /*!\brief HEAT_EQUATION \n DESCRIPTION: Enable heat equation for incompressible flows. \ingroup Config*/ /*!\brief KIND_SGS_MODEL \n DESCRIPTION: Specify subgrid scale model OPTIONS: see \link SGS_Model_Map \endlink \n DEFAULT: NO_SGS_MODEL \ingroup Config*/ addEnumOption("KIND_SGS_MODEL", Kind_SGS_Model, SGS_Model_Map, NO_SGS_MODEL); @@ -995,6 +999,16 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Definition of the temperature polynomial coefficients for specific heat Cp. */ addDoubleArrayOption("KT_POLYCOEFFS", nPolyCoeffs, KtPolyCoefficients, default_kt_polycoeffs); + /*--- Options related to mass diffusivity ---*/ + + addEnumOption("DIFFUSIVITY_MODEL", Kind_DiffusivityModel, DiffusivityModel_Map, CONSTANT_DIFFUSIVITY); + /* DESCRIPTION: default value for AIR */ + addDoubleOption("DIFFUSIVITY_CONSTANT", Diffusivity_Constant , 0.001); + /*!\brief SCHMIDT_LAM \n DESCRIPTION: Laminar Schmidt number of mass diffusion \ingroup Config*/ + addDoubleOption("SCHMIDT_LAM", Schmidt_Lam, 1.0); + /*!\brief SCHMIDT_TURB \n DESCRIPTION: Turbulent Schmidt number of mass diffusion \n DEFAULT 0.90 \ingroup Config*/ + addDoubleOption("SCHMIDT_TURB", Schmidt_Turb, 1.0); + /*!\brief REYNOLDS_NUMBER \n DESCRIPTION: Reynolds number (non-dimensional, based on the free-stream values). Needed for viscous solvers. For incompressible solvers the Reynolds length will always be 1.0 \n DEFAULT: 0.0 \ingroup Config */ addDoubleOption("REYNOLDS_NUMBER", Reynolds, 0.0); /*!\brief REYNOLDS_LENGTH \n DESCRIPTION: Reynolds length (1 m by default). Used for compressible solver: incompressible solver will use 1.0. \ingroup Config */ @@ -1043,6 +1057,16 @@ void CConfig::SetConfig_Options() { addEnumOption("INC_NONDIM", Ref_Inc_NonDim, NonDim_Map, INITIAL_VALUES); /*!\brief INC_INLET_USENORMAL \n DESCRIPTION: Use the local boundary normal for the flow direction with the incompressible pressure inlet. \ingroup Config*/ addBoolOption("INC_INLET_USENORMAL", Inc_Inlet_UseNormal, false); + + /*!\brief SCALAR_INIT \n DESCRIPTION: Initial value for scalar transport \ingroup Config*/ + addDoubleOption("SCALAR_INIT", Scalar_Init, 0.0); + /*!\brief SCALAR_CLIPPING \n DESCRIPTION: Activate clipping for scalar transport equations \ingroup Config*/ + addBoolOption("SCALAR_CLIPPING", Scalar_Clipping, false); + /*!\brief SCALAR_CLIPPING_MAX \n DESCRIPTION: Maximum value for scalar clipping \ingroup Config*/ + addDoubleOption("SCALAR_CLIPPING_MAX", Scalar_Clipping_Max, 1.0e15); + /*!\brief SCALAR_CLIPPING_MIN \n DESCRIPTION: Minimum value for scalar clipping \ingroup Config*/ + addDoubleOption("SCALAR_CLIPPING_MIN", Scalar_Clipping_Min, -1.0e15); + /*!\brief INC_INLET_DAMPING \n DESCRIPTION: Damping factor applied to the iterative updates to the velocity at a pressure inlet in incompressible flow (0.1 by default). \ingroup Config*/ addDoubleOption("INC_INLET_DAMPING", Inc_Inlet_Damping, 0.1); /*!\brief INC_OUTLET_DAMPING \n DESCRIPTION: Damping factor applied to the iterative updates to the pressure at a mass flow outlet in incompressible flow (0.1 by default). \ingroup Config*/ @@ -1393,6 +1417,8 @@ void CConfig::SetConfig_Options() { addDoubleOption("CFL_REDUCTION_TURB", CFLRedCoeff_Turb, 1.0); /* DESCRIPTION: Reduction factor of the CFL coefficient in the turbulent adjoint problem */ addDoubleOption("CFL_REDUCTION_ADJTURB", CFLRedCoeff_AdjTurb, 1.0); + /* DESCRIPTION: Reduction factor of the CFL coefficient in the scalar transport problem */ + addDoubleOption("CFL_REDUCTION_SCALAR", CFLRedCoeff_Scalar, 1.0); /* DESCRIPTION: External iteration offset due to restart */ addUnsignedLongOption("EXT_ITER_OFFSET", ExtIter_OffSet, 0); // these options share nRKStep as their size, which is not a good idea in general @@ -1427,6 +1453,8 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Time discretization */ addEnumOption("TIME_DISCRE_ADJFLOW", Kind_TimeIntScheme_AdjFlow, Time_Int_Map, EULER_IMPLICIT); /* DESCRIPTION: Time discretization */ + addEnumOption("TIME_DISCRE_SCALAR", Kind_TimeIntScheme_Scalar, Time_Int_Map, EULER_IMPLICIT); + /* DESCRIPTION: Time discretization */ addEnumOption("TIME_DISCRE_TURB", Kind_TimeIntScheme_Turb, Time_Int_Map, EULER_IMPLICIT); /* DESCRIPTION: Time discretization */ addEnumOption("TIME_DISCRE_ADJTURB", Kind_TimeIntScheme_AdjTurb, Time_Int_Map, EULER_IMPLICIT); @@ -1460,6 +1488,8 @@ void CConfig::SetConfig_Options() { addDoubleOption("RELAXATION_FACTOR_FLOW", Relaxation_Factor_Flow, 1.0); /* DESCRIPTION: Relaxation of the turb equations solver for the implicit formulation */ addDoubleOption("RELAXATION_FACTOR_TURB", Relaxation_Factor_Turb, 1.0); + /* DESCRIPTION: Relaxation of the scalar transport equations solver for the implicit formulation */ + addDoubleOption("RELAXATION_FACTOR_SCALAR", Relaxation_Factor_Scalar, 1.0); /* DESCRIPTION: Relaxation of the adjoint flow equations solver for the implicit formulation */ addDoubleOption("RELAXATION_FACTOR_ADJFLOW", Relaxation_Factor_AdjFlow, 1.0); /* DESCRIPTION: Relaxation of the CHT coupling */ @@ -1596,6 +1626,15 @@ void CConfig::SetConfig_Options() { * \n DESCRIPTION: Convective numerical method \ingroup Config*/ addConvectOption("CONV_NUM_METHOD_TURB", Kind_ConvNumScheme_Turb, Kind_Centered_Turb, Kind_Upwind_Turb); + /*!\brief MUSCL_FLOW \n DESCRIPTION: Check if the MUSCL scheme should be used \ingroup Config*/ + addBoolOption("MUSCL_SCALAR", MUSCL_Scalar, false); + /*!\brief SLOPE_LIMITER_SCALAR + * \n DESCRIPTION: Slope limiter \n OPTIONS: See \link Limiter_Map \endlink \n DEFAULT VENKATAKRISHNAN \ingroup Config*/ + addEnumOption("SLOPE_LIMITER_SCALAR", Kind_SlopeLimit_Scalar, Limiter_Map, VENKATAKRISHNAN); + /*!\brief CONV_NUM_METHOD_SCALAR + * \n DESCRIPTION: Convective numerical method \ingroup Config*/ + addConvectOption("CONV_NUM_METHOD_SCALAR", Kind_ConvNumScheme_Scalar, Kind_Centered_Scalar, Kind_Upwind_Scalar); + /*!\brief MUSCL_FLOW \n DESCRIPTION: Check if the MUSCL scheme should be used \ingroup Config*/ addBoolOption("MUSCL_ADJTURB", MUSCL_AdjTurb, false); /*!\brief SLOPE_LIMITER_ADJTURB @@ -4363,6 +4402,14 @@ void CConfig::SetPostprocessing(unsigned short val_software, unsigned short val_ } } + /*--- Disable any scalar model other than passive scalar until + they are implemented. ---*/ + + if ((Kind_Scalar_Model != NO_SCALAR_MODEL) && + (Kind_Scalar_Model != PASSIVE_SCALAR)) { + SU2_MPI::Error(string("Selected scalar model not yet implemented.") , CURRENT_FUNCTION); + } + /*--- Handle default options for topology optimization ---*/ if (topology_optimization && top_optim_nKernel==0) { @@ -4553,6 +4600,7 @@ void CConfig::SetPostprocessing(unsigned short val_software, unsigned short val_ RampOutletPressure = false; RampRotatingFrame = false; } + } void CConfig::SetMarkers(unsigned short val_software) { @@ -7672,6 +7720,7 @@ unsigned short CConfig::GetContainerPosition(unsigned short val_eqsystem) { case RUNTIME_FLOW_SYS: return FLOW_SOL; case RUNTIME_TURB_SYS: return TURB_SOL; case RUNTIME_TRANS_SYS: return TRANS_SOL; + case RUNTIME_SCALAR_SYS: return SCALAR_SOL; case RUNTIME_HEAT_SYS: return HEAT_SOL; case RUNTIME_FEA_SYS: return FEA_SOL; case RUNTIME_ADJPOT_SYS: return ADJFLOW_SOL; @@ -7715,6 +7764,12 @@ void CConfig::SetGlobalParam(unsigned short val_solver, MUSCL_Flow, NONE); SetKind_TimeIntScheme(Kind_TimeIntScheme_Flow); } + if (val_system == RUNTIME_SCALAR_SYS) { + SetKind_ConvNumScheme(Kind_ConvNumScheme_Scalar, Kind_Centered_Scalar, + Kind_Upwind_Scalar, Kind_SlopeLimit_Scalar, + MUSCL_Scalar, NONE); + SetKind_TimeIntScheme(Kind_TimeIntScheme_Scalar); + } break; case NAVIER_STOKES: case INC_NAVIER_STOKES: if (val_system == RUNTIME_FLOW_SYS) { @@ -7723,6 +7778,12 @@ void CConfig::SetGlobalParam(unsigned short val_solver, MUSCL_Flow, NONE); SetKind_TimeIntScheme(Kind_TimeIntScheme_Flow); } + if (val_system == RUNTIME_SCALAR_SYS) { + SetKind_ConvNumScheme(Kind_ConvNumScheme_Scalar, Kind_Centered_Scalar, + Kind_Upwind_Scalar, Kind_SlopeLimit_Scalar, + MUSCL_Scalar, NONE); + SetKind_TimeIntScheme(Kind_TimeIntScheme_Scalar); + } if (val_system == RUNTIME_HEAT_SYS) { SetKind_ConvNumScheme(Kind_ConvNumScheme_Heat, NONE, NONE, NONE, NONE, NONE); SetKind_TimeIntScheme(Kind_TimeIntScheme_Heat); @@ -7747,6 +7808,12 @@ void CConfig::SetGlobalParam(unsigned short val_solver, MUSCL_Turb, NONE); SetKind_TimeIntScheme(Kind_TimeIntScheme_Turb); } + if (val_system == RUNTIME_SCALAR_SYS) { + SetKind_ConvNumScheme(Kind_ConvNumScheme_Scalar, Kind_Centered_Scalar, + Kind_Upwind_Scalar, Kind_SlopeLimit_Scalar, + MUSCL_Scalar, NONE); + SetKind_TimeIntScheme(Kind_TimeIntScheme_Scalar); + } if (val_system == RUNTIME_HEAT_SYS) { SetKind_ConvNumScheme(Kind_ConvNumScheme_Heat, NONE, NONE, NONE, NONE, NONE); SetKind_TimeIntScheme(Kind_TimeIntScheme_Heat); diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index 2fd38b1be482..e5a5f28c9849 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -58,6 +58,7 @@ #include "../numerics/CFEAMeshElasticity.hpp" #include "../solvers/CDiscAdjMeshSolver.hpp" #include "../solvers/CMeshSolver.hpp" +#include "../solvers/CPassiveScalarSolver.hpp" #include "../../../Common/include/geometry_structure.hpp" #include "../../../Common/include/grid_movement_structure.hpp" #include "../../../Common/include/config_structure.hpp" diff --git a/SU2_CFD/include/fluid_model.hpp b/SU2_CFD/include/fluid_model.hpp index de5e1d95e1e3..f11297baf273 100644 --- a/SU2_CFD/include/fluid_model.hpp +++ b/SU2_CFD/include/fluid_model.hpp @@ -85,10 +85,14 @@ su2double StaticEnergy, /*!< \brief Internal Energy. */ dmudT_rho, /*!< \brief Specific Heat Capacity at constant pressure. */ Kt, /*!< \brief Specific Heat Capacity at constant pressure. */ dktdrho_T, /*!< \brief Specific Heat Capacity at constant pressure. */ - dktdT_rho; /*!< \brief Specific Heat Capacity at constant pressure. */ + dktdT_rho, /*!< \brief Specific Heat Capacity at constant pressure. */ + Diffusivity; /*!< \brief Mass diffusivity for scalar transport. */ -CViscosityModel *LaminarViscosity; /*!< \brief Laminar Viscosity Model */ + +CViscosityModel *LaminarViscosity; /*!< \brief Laminar Viscosity Model */ CConductivityModel *ThermalConductivity; /*!< \brief Thermal Conductivity Model */ +CDiffusivityModel *MassDiffusivity; /*!< \brief Mass Diffusivity Model */ + public: @@ -159,6 +163,12 @@ CConductivityModel *ThermalConductivity; /*!< \brief Thermal Conductivity Mod su2double GetThermalConductivity (); + /*! + * \brief Get fluid thermal conductivity + */ + + su2double GetMassDiffusivity (); + /*! * \brief Get fluid pressure partial derivative. */ @@ -234,6 +244,17 @@ CConductivityModel *ThermalConductivity; /*!< \brief Thermal Conductivity Mod */ void SetThermalConductivityModel (CConfig *config); + /*! + * \brief Set mass diffusivity model. + */ + void SetMassDiffusivityModel (CConfig *config); + + /*! + * \brief Set the state needed for the mass diffusivity model. + */ + void SetDiffusivityState(su2double val_Temperature, su2double val_Density, + su2double val_Mu, su2double val_Mu_Turb, su2double val_Cp); + /*! * \brief virtual member that would be different for each gas model implemented * \param[in] InputSpec - Input pair for FLP calls ("e, rho"). diff --git a/SU2_CFD/include/fluid_model.inl b/SU2_CFD/include/fluid_model.inl index 947935d4bfc8..a6b1f2b6be15 100644 --- a/SU2_CFD/include/fluid_model.inl +++ b/SU2_CFD/include/fluid_model.inl @@ -101,3 +101,18 @@ inline void CFluidModel::SetTDState_Ps (su2double P, su2double s ) { } inline void CFluidModel::ComputeDerivativeNRBC_Prho (su2double P, su2double rho ){ } inline void CFluidModel::SetTDState_T (su2double val_Temperature) { } inline void CFluidModel::SetEddyViscosity (su2double val_Mu_Turb) { Mu_Turb = val_Mu_Turb; } + +inline void CFluidModel::SetDiffusivityState(su2double val_Temperature, su2double val_Density, + su2double val_Mu, su2double val_Mu_Turb, su2double val_Cp) { + Temperature = val_Temperature; + Density = val_Density; + Mu = val_Mu; + Mu_Turb = val_Mu_Turb; + Cp = val_Cp; +} + +inline su2double CFluidModel::GetMassDiffusivity () { + MassDiffusivity->SetDiffusivity(Temperature, Density, Mu, Mu_Turb, Cp); + Diffusivity = MassDiffusivity->GetDiffusivity(); + return Diffusivity; +} diff --git a/SU2_CFD/include/numerics_structure.hpp b/SU2_CFD/include/numerics_structure.hpp index d4788a3dd3b3..bc145aafea84 100644 --- a/SU2_CFD/include/numerics_structure.hpp +++ b/SU2_CFD/include/numerics_structure.hpp @@ -157,6 +157,8 @@ class CNumerics { *TurbVar_jd; /*!< \brief Vector of derivative of turbulent variables at point j. */ su2double *TransVar_i, /*!< \brief Vector of turbulent variables at point i. */ *TransVar_j; /*!< \brief Vector of turbulent variables at point j. */ + su2double *ScalarVar_i, /*!< \brief Vector of scalar variables at point i. */ + *ScalarVar_j; /*!< \brief Vector of scalar variables at point j. */ su2double *TurbPsi_i, /*!< \brief Vector of adjoint turbulent variables at point i. */ *TurbPsi_j; /*!< \brief Vector of adjoint turbulent variables at point j. */ su2double **ConsVar_Grad_i, /*!< \brief Gradient of conservative variables at point i. */ @@ -172,6 +174,8 @@ class CNumerics { **PsiVar_Grad_j; /*!< \brief Gradient of adjoint variables at point j. */ su2double **TurbVar_Grad_i, /*!< \brief Gradient of turbulent variables at point i. */ **TurbVar_Grad_j; /*!< \brief Gradient of turbulent variables at point j. */ + su2double **ScalarVar_Grad_i, /*!< \brief Gradient of scalar variables at point i. */ + **ScalarVar_Grad_j; /*!< \brief Gradient of scalar variables at point j. */ su2double **TransVar_Grad_i, /*!< \brief Gradient of turbulent variables at point i. */ **TransVar_Grad_j; /*!< \brief Gradient of turbulent variables at point j. */ su2double **TurbPsi_Grad_i, /*!< \brief Gradient of adjoint turbulent variables at point i. */ @@ -400,6 +404,13 @@ class CNumerics { */ void SetTurbVar(su2double *val_turbvar_i, su2double *val_turbvar_j); + /*! + * \brief Set the value of the scalar transport variables. + * \param[in] val_scalarvar_i - Value of the scalar transport variables at point i. + * \param[in] val_scalarvar_j - Value of the scalar transport variables at point j. + */ + void SetScalarVar(su2double *val_scalarvar_i, su2double *val_scalarvar_j); + /*! * \brief Set the value of the turbulent variable. * \param[in] val_transvar_i - Value of the turbulent variable at point i. @@ -414,6 +425,13 @@ class CNumerics { */ void SetTurbVarGradient(su2double **val_turbvar_grad_i, su2double **val_turbvar_grad_j); + /*! + * \brief Set the gradient of the scalar transport variables. + * \param[in] val_scalarvar_grad_i - Gradient of the scalar transport variables at point i. + * \param[in] val_scalarvar_grad_j - Gradient of the scalar transport variables at point j. + */ + void SetScalarVarGradient(su2double **val_scalarvar_grad_i, su2double **val_scalarvar_grad_j); + /*! * \brief Set the gradient of the turbulent variables. * \param[in] val_turbvar_grad_i - Gradient of the turbulent variable at point i. @@ -2359,6 +2377,7 @@ class CUpwLin_AdjTurb : public CNumerics { void ComputeResidual (su2double *val_residual, su2double **val_Jacobian_i, su2double **val_Jacobian_j, CConfig *config); }; + /*! * \class CUpwScalar * \brief Template class for scalar upwind fluxes between nodes i and j. @@ -2371,16 +2390,16 @@ class CUpwLin_AdjTurb : public CNumerics { * calculation for a convection residual, extend this class and implement * the pure virtual functions with model-specific behavior. * \ingroup ConvDiscr - * \author C. Pederson, A. Bueno., and A. Campos. + * \author C. Pederson, A. Bueno, A. Campos, T. Economon */ class CUpwScalar : public CNumerics { private: - + /*! * \brief A pure virtual function; Adds any extra variables to AD */ virtual void ExtraADPreaccIn() = 0; - + /*! * \brief Model-specific steps in the ComputeResidual method * \param[out] val_residual - Pointer to the total residual. @@ -2392,18 +2411,18 @@ class CUpwScalar : public CNumerics { su2double **Jacobian_i, su2double **Jacobian_j, CConfig *config) = 0; - + protected: - su2double *Velocity_i, *Velocity_j; /*!< \brief Velocity, minus any grid movement. */ - su2double Density_i, Density_j; - bool implicit, dynamic_grid, incompressible; - su2double q_ij, /*!< \brief Projected velocity at the face. */ - a0, /*!< \brief The maximum of the face-normal velocity and 0 */ - a1; /*!< \brief The minimum of the face-normal velocity and 0 */ - unsigned short iDim; - + su2double *Velocity_i, *Velocity_j; /*!< \brief Velocity at nodes i and j. */ + su2double Density_i, Density_j; /*!< \brief Density at nodes i and j. */ + bool implicit, grid_movement, incompressible; /*!< \brief Boolean flags. */ + su2double q_ij, /*!< \brief Projected velocity at the face. */ + a0, /*!< \brief The maximum of the face-normal velocity and 0 */ + a1; /*!< \brief The minimum of the face-normal velocity and 0 */ + unsigned short iDim; /*!< \brief Dimension index. */ + public: - + /*! * \brief Constructor of the class. * \param[in] val_nDim - Number of dimensions of the problem. @@ -2411,12 +2430,12 @@ class CUpwScalar : public CNumerics { * \param[in] config - Definition of the particular problem. */ CUpwScalar(unsigned short val_nDim, unsigned short val_nVar, CConfig *config); - + /*! * \brief Destructor of the class. */ ~CUpwScalar(void); - + /*! * \brief Compute the scalar upwind flux between two nodes i and j. * \param[out] val_residual - Pointer to the total residual. @@ -2424,47 +2443,52 @@ class CUpwScalar : public CNumerics { * \param[out] val_Jacobian_j - Jacobian of the numerical method at node j (implicit computation). * \param[in] config - Definition of the particular problem. */ - void ComputeResidual(su2double *val_residual, su2double **val_Jacobian_i, su2double **val_Jacobian_j, CConfig *config); + void ComputeResidual(su2double *val_residual, + su2double **val_Jacobian_i, + su2double **val_Jacobian_j, + CConfig *config); }; /*! - * \class CUpwSca_TurbSA - * \brief Class for doing a scalar upwind solver for the Spalar-Allmaras turbulence model equations. + * \class CUpwScalar_General + * \brief Class for a general scalar upwind solver for an arbitrary number of scalar transport eqns. * \ingroup ConvDiscr - * \author A. Bueno. + * \author T. Economon */ -class CUpwSca_TurbSA : public CUpwScalar { +class CUpwScalar_General : public CUpwScalar { private: - + /*! * \brief Adds any extra variables to AD */ void ExtraADPreaccIn(); - + /*! - * \brief SA specific steps in the ComputeResidual method + * \brief SST specific steps in the ComputeResidual method * \param[out] val_residual - Pointer to the total residual. * \param[out] val_Jacobian_i - Jacobian of the numerical method at node i (implicit computation). * \param[out] val_Jacobian_j - Jacobian of the numerical method at node j (implicit computation). * \param[in] config - Definition of the particular problem. */ void FinishResidualCalc(su2double *val_residual, su2double **Jacobian_i, - su2double **Jacobian_j, CConfig *config); - + su2double **Jacobian_j, CConfig *config); + public: - + /*! * \brief Constructor of the class. * \param[in] val_nDim - Number of dimensions of the problem. * \param[in] val_nVar - Number of variables of the problem. * \param[in] config - Definition of the particular problem. */ - CUpwSca_TurbSA(unsigned short val_nDim, unsigned short val_nVar, CConfig *config); - + CUpwScalar_General(unsigned short val_nDim, + unsigned short val_nVar, + CConfig *config); + /*! * \brief Destructor of the class. */ - ~CUpwSca_TurbSA(void); + ~CUpwScalar_General(void); }; /*! @@ -2474,6 +2498,46 @@ class CUpwSca_TurbSA : public CUpwScalar { * \author A. Campos. */ class CUpwSca_TurbSST : public CUpwScalar { +private: + + /*! + * \brief Adds any extra variables to AD + */ + void ExtraADPreaccIn(); + + /*! + * \brief SST specific steps in the ComputeResidual method + * \param[out] val_residual - Pointer to the total residual. + * \param[out] val_Jacobian_i - Jacobian of the numerical method at node i (implicit computation). + * \param[out] val_Jacobian_j - Jacobian of the numerical method at node j (implicit computation). + * \param[in] config - Definition of the particular problem. + */ + void FinishResidualCalc(su2double *val_residual, su2double **Jacobian_i, + su2double **Jacobian_j, CConfig *config); + +public: + + /*! + * \brief Constructor of the class. + * \param[in] val_nDim - Number of dimensions of the problem. + * \param[in] val_nVar - Number of variables of the problem. + * \param[in] config - Definition of the particular problem. + */ + CUpwSca_TurbSST(unsigned short val_nDim, unsigned short val_nVar, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + ~CUpwSca_TurbSST(void); +}; + +/*! + * \class CUpwSca_TurbSA + * \brief Class for doing a scalar upwind solver for the Spalar-Allmaras turbulence model equations. + * \ingroup ConvDiscr + * \author A. Bueno. + */ +class CUpwSca_TurbSA : public CUpwScalar { private: /*! @@ -2482,7 +2546,7 @@ class CUpwSca_TurbSST : public CUpwScalar { void ExtraADPreaccIn(); /*! - * \brief SST specific steps in the ComputeResidual method + * \brief SA specific steps in the ComputeResidual method * \param[out] val_residual - Pointer to the total residual. * \param[out] val_Jacobian_i - Jacobian of the numerical method at node i (implicit computation). * \param[out] val_Jacobian_j - Jacobian of the numerical method at node j (implicit computation). @@ -2499,12 +2563,12 @@ class CUpwSca_TurbSST : public CUpwScalar { * \param[in] val_nVar - Number of variables of the problem. * \param[in] config - Definition of the particular problem. */ - CUpwSca_TurbSST(unsigned short val_nDim, unsigned short val_nVar, CConfig *config); + CUpwSca_TurbSA(unsigned short val_nDim, unsigned short val_nVar, CConfig *config); /*! * \brief Destructor of the class. */ - ~CUpwSca_TurbSST(void); + ~CUpwSca_TurbSA(void); }; /*! @@ -3503,7 +3567,7 @@ class CAvgGradInc_Flow : public CAvgGrad_Base { }; /*! - * \class CAvgGrad_Scalar + * \class CAvgGradScalar * \brief Template class for computing viscous residual of scalar values * \details This class serves as a template for the scalar viscous residual * classes. The general structure of a viscous residual calculation is the @@ -3514,16 +3578,16 @@ class CAvgGradInc_Flow : public CAvgGrad_Base { * calculation for a viscous residual, extend this class and implement * the pure virtual functions with model-specific behavior. * \ingroup ViscDiscr - * \author C. Pederson, A. Bueno, and F. Palacios + * \author C. Pederson, A. Bueno, F. Palacios, T. Economon */ -class CAvgGrad_Scalar : public CNumerics { - private: - +class CAvgGradScalar : public CNumerics { +private: + /*! * \brief A pure virtual function; Adds any extra variables to AD */ virtual void ExtraADPreaccIn() = 0; - + /*! * \brief Model-specific steps in the ComputeResidual method * \param[out] val_residual - Pointer to the total residual. @@ -3535,34 +3599,34 @@ class CAvgGrad_Scalar : public CNumerics { su2double **Jacobian_i, su2double **Jacobian_j, CConfig *config) = 0; - - protected: + +protected: bool implicit, incompressible; bool correct_gradient; unsigned short iVar, iDim; - su2double **Mean_GradTurbVar; /*!< \brief Average of gradients at cell face */ - su2double *Edge_Vector, /*!< \brief Vector from node i to node j. */ - *Proj_Mean_GradTurbVar_Normal, /*!< \brief Mean_gradTurbVar DOT normal */ - *Proj_Mean_GradTurbVar_Edge, /*!< \brief Mean_gradTurbVar DOT Edge_Vector */ - *Proj_Mean_GradTurbVar; /*!< \brief Mean_gradTurbVar DOT normal, corrected if required*/ - su2double dist_ij_2, /*!< \brief |Edge_Vector|^2 */ - proj_vector_ij; /*!< \brief (Edge_Vector DOT normal)/|Edge_Vector|^2 */ - - public: + su2double **Mean_GradScalarVar; /*!< \brief Average of scalar var gradients at cell face */ + su2double *Edge_Vector, /*!< \brief Vector from node i to node j. */ + *Proj_Mean_GradScalarVar_Normal, /*!< \brief Mean_GradScalarVar DOT normal */ + *Proj_Mean_GradScalarVar_Edge, /*!< \brief Mean_GradScalarVar DOT Edge_Vector */ + *Proj_Mean_GradScalarVar; /*!< \brief Mean_GradScalarVar DOT normal, corrected if required */ + su2double dist_ij_2, /*!< \brief |Edge_Vector|^2 */ + proj_vector_ij; /*!< \brief (Edge_Vector DOT normal)/|Edge_Vector|^2 */ + +public: /*! * \brief Constructor of the class. * \param[in] val_nDim - Number of dimensions of the problem. * \param[in] val_nVar - Number of variables of the problem. * \param[in] config - Definition of the particular problem. */ - CAvgGrad_Scalar(unsigned short val_nDim, unsigned short val_nVar, - bool correct_gradient, CConfig *config); - + CAvgGradScalar(unsigned short val_nDim, unsigned short val_nVar, + bool correct_gradient, CConfig *config); + /*! * \brief Destructor of the class. */ - ~CAvgGrad_Scalar(void); - + ~CAvgGradScalar(void); + /*! * \brief Compute the viscous residual using an average of gradients without correction. * \param[out] val_residual - Pointer to the total residual. @@ -3580,7 +3644,7 @@ class CAvgGrad_Scalar : public CNumerics { * \ingroup ViscDiscr * \author A. Bueno. */ -class CAvgGrad_TurbSA : public CAvgGrad_Scalar { +class CAvgGrad_TurbSA : public CAvgGradScalar { private: const su2double sigma; @@ -3624,7 +3688,7 @@ class CAvgGrad_TurbSA : public CAvgGrad_Scalar { * \ingroup ViscDiscr * \author F. Palacios */ -class CAvgGrad_TurbSA_Neg : public CAvgGrad_Scalar { +class CAvgGrad_TurbSA_Neg : public CAvgGradScalar { private: const su2double sigma; @@ -3706,6 +3770,50 @@ class CAvgGrad_TransLM : public CNumerics { void ComputeResidual(su2double *val_residual, su2double **Jacobian_i, su2double **Jacobian_j, CConfig *config); }; +/*! + * \class CAvgGradScalar_General + * \brief Class for computing viscous term using average of gradients for a passive scalar. + * \ingroup ViscDiscr + * \author T. Economon + */ +class CAvgGradScalar_General : public CAvgGradScalar { +protected: + su2double *Mean_Diffusivity; /*!< \brief Average of mass diffusivities at cell face */ + +private: + + /*! + * \brief Adds any extra variables to AD + */ + void ExtraADPreaccIn(void); + + /*! + * \brief SA specific steps in the ComputeResidual method + * \param[out] val_residual - Pointer to the total residual. + * \param[out] val_Jacobian_i - Jacobian of the numerical method at node i (implicit computation). + * \param[out] val_Jacobian_j - Jacobian of the numerical method at node j (implicit computation). + * \param[in] config - Definition of the particular problem. + */ + void FinishResidualCalc(su2double *val_residual, su2double **Jacobian_i, + su2double **Jacobian_j, CConfig *config); + +public: + + /*! + * \brief Constructor of the class. + * \param[in] val_nDim - Number of dimensions of the problem. + * \param[in] val_nVar - Number of variables of the problem. + * \param[in] config - Definition of the particular problem. + */ + CAvgGradScalar_General(unsigned short val_nDim, unsigned short val_nVar, + bool correct_grad, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + ~CAvgGradScalar_General(void); +}; + /*! * \class CAvgGrad_AdjFlow * \brief Class for computing the adjoint viscous terms. @@ -3792,7 +3900,7 @@ class CAvgGradCorrected_TransLM : public CNumerics { * \ingroup ViscDiscr * \author A. Bueno. */ -class CAvgGrad_TurbSST : public CAvgGrad_Scalar { +class CAvgGrad_TurbSST : public CAvgGradScalar { private: su2double sigma_k1, /*!< \brief Constants for the viscous terms, k-w (1), k-eps (2)*/ sigma_k2, @@ -5157,6 +5265,83 @@ class CSourcePieceWise_TurbSST : public CNumerics { }; +/*! + * \class CSourcePieceWise_Scalar + * \brief Class for integrating the source terms of scalar transport equations. + * \ingroup SourceDiscr + * \author T. Economon + */ +class CSourcePieceWise_Scalar : public CNumerics { +private: + bool incompressible; /*!< \brief Flag defining compressibility. */ + bool implicit; /*!< \brief Flag defining implicit scheme. */ + +public: + + /*! + * \brief Constructor of the class. + * \param[in] val_nDim - Number of dimensions of the problem. + * \param[in] val_nVar - Number of variables of the problem. + * \param[in] config - Definition of the particular problem. + */ + CSourcePieceWise_Scalar(unsigned short val_nDim, + unsigned short val_nVar, + CConfig *config); + + /*! + * \brief Destructor of the class. + */ + ~CSourcePieceWise_Scalar(void); + + /*! + * \brief Residual for source term integration. + * \param[out] val_residual - Pointer to the total residual. + * \param[out] val_Jacobian_i - Jacobian of the numerical method at node i (implicit computation). + * \param[out] val_Jacobian_j - Jacobian of the numerical method at node j (implicit computation). + * \param[in] config - Definition of the particular problem. + */ + void ComputeResidual(su2double *val_residual, + su2double **val_Jacobian_i, + su2double **val_Jacobian_j, + CConfig *config); + +}; + +/*! + * \class CSourceAxisymmetric_Scalar + * \brief Class for source term for solving scalar axisymmetric problems. + * \ingroup SourceDiscr + * \author T. Economon + */ +class CSourceAxisymmetric_Scalar : public CNumerics { + bool implicit, /*!< \brief Implicit calculation. */ + viscous, /*!< \brief Viscous incompressible flows. */ + energy; /*!< \brief computation with the energy equation. */ + +public: + + /*! + * \brief Constructor of the class. + * \param[in] val_nDim - Number of dimensions of the problem. + * \param[in] val_nVar - Number of variables of the problem. + * \param[in] config - Definition of the particular problem. + */ + CSourceAxisymmetric_Scalar(unsigned short val_nDim, unsigned short val_nVar, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + ~CSourceAxisymmetric_Scalar(void); + + /*! + * \brief Residual of the rotational frame source term. + * \param[out] val_residual - Pointer to the total residual. + * \param[in] config - Definition of the particular problem. + */ + void ComputeResidual(su2double *val_residual, su2double **Jacobian_i, CConfig *config); + +}; + /*! * \class CSourceGravity * \brief Class for the source term integration of the gravity force. diff --git a/SU2_CFD/include/numerics_structure.inl b/SU2_CFD/include/numerics_structure.inl index 57c836b396fe..970436127f48 100644 --- a/SU2_CFD/include/numerics_structure.inl +++ b/SU2_CFD/include/numerics_structure.inl @@ -331,6 +331,11 @@ inline void CNumerics::SetTurbVar(su2double *val_turbvar_i, su2double *val_turbv TurbVar_j = val_turbvar_j; } +inline void CNumerics::SetScalarVar(su2double *val_scalarvar_i, su2double *val_scalarvar_j) { + ScalarVar_i = val_scalarvar_i; + ScalarVar_j = val_scalarvar_j; +} + inline void CNumerics::SetTransVar(su2double *val_transvar_i, su2double *val_transvar_j) { TransVar_i = val_transvar_i; TransVar_j = val_transvar_j; @@ -341,6 +346,11 @@ inline void CNumerics::SetTurbVarGradient(su2double **val_turbvar_grad_i, su2dou TurbVar_Grad_j = val_turbvar_grad_j; } +inline void CNumerics::SetScalarVarGradient(su2double **val_scalarvar_grad_i, su2double **val_scalarvar_grad_j) { + ScalarVar_Grad_i = val_scalarvar_grad_i; + ScalarVar_Grad_j = val_scalarvar_grad_j; +} + inline void CNumerics::SetTransVarGradient(su2double **val_transvar_grad_i, su2double **val_transvar_grad_j) { TransVar_Grad_i = val_transvar_grad_i; TransVar_Grad_j = val_transvar_grad_j; diff --git a/SU2_CFD/include/output/CFlowCompOutput.hpp b/SU2_CFD/include/output/CFlowCompOutput.hpp index 44ba12a9f41b..cb0354971081 100644 --- a/SU2_CFD/include/output/CFlowCompOutput.hpp +++ b/SU2_CFD/include/output/CFlowCompOutput.hpp @@ -49,7 +49,8 @@ class CVariable; class CFlowCompOutput final: public CFlowOutput { private: - unsigned short turb_model; //!< Kind of turbulence model + unsigned short turb_model; /*!< \brief Kind of turbulence model */ + unsigned short scalar_model; /*!< \brief The kind of scalar transport model*/ unsigned long lastInnerIter; public: diff --git a/SU2_CFD/include/output/CFlowIncOutput.hpp b/SU2_CFD/include/output/CFlowIncOutput.hpp index 153dd8ce2e33..df97d43aaf49 100644 --- a/SU2_CFD/include/output/CFlowIncOutput.hpp +++ b/SU2_CFD/include/output/CFlowIncOutput.hpp @@ -49,7 +49,8 @@ class CVariable; class CFlowIncOutput final: public CFlowOutput { private: - unsigned short turb_model; /*!< \brief The kind of turbulence model*/ + unsigned short turb_model; /*!< \brief The kind of turbulence model*/ + unsigned short scalar_model; /*!< \brief The kind of scalar transport model*/ bool heat, /*!< \brief Boolean indicating whether have a heat problem*/ weakly_coupled_heat; /*!< \brief Boolean indicating whether have a weakly coupled heat equation*/ diff --git a/SU2_CFD/include/solver_structure.hpp b/SU2_CFD/include/solver_structure.hpp index 770e4249cc39..b70b8b43f1ea 100644 --- a/SU2_CFD/include/solver_structure.hpp +++ b/SU2_CFD/include/solver_structure.hpp @@ -74,6 +74,7 @@ #include "variables/CEulerVariable.hpp" #include "variables/CIncEulerVariable.hpp" #include "variables/CTurbVariable.hpp" +#include "variables/CScalarVariable.hpp" #include "variables/CAdjEulerVariable.hpp" #include "variables/CAdjTurbVariable.hpp" #include "variables/CHeatFVMVariable.hpp" @@ -1525,6 +1526,13 @@ class CSolver { */ virtual void SetPreconditioner(CConfig *config, unsigned long iPoint); + /*! + * \brief A virtual member (overload). + * \param[in] iPoint - Index of the grid point. + * \param[in] config - Definition of the particular problem. + */ + virtual void SetPreconditioner(CGeometry *geometry, CSolver **solver_container, CConfig *config); + /*! * \brief A virtual member. * \param[in] geometry - Geometrical definition of the problem. @@ -3278,6 +3286,12 @@ class CSolver { */ virtual su2double GetOmega_Inf(void); + /*! + * \brief A virtual member. + * \return Value of the transported scalar. + */ + virtual su2double GetScalar_Inf(unsigned short val_ivar); + /*! * \brief A virtual member. * \return Value of the sensitivity coefficient for the Young Modulus E @@ -9466,14 +9480,14 @@ class CTurbSolver : public CSolver { su2double Gamma_Minus_One; /*!< \brief Fluids's Gamma - 1.0 . */ su2double*** Inlet_TurbVars; /*!< \brief Turbulence variables at inlet profiles */ - CTurbVariable* snode; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ + CScalarVariable* snode; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ /* Sliding meshes variables */ su2double ****SlidingState; int **SlidingStateNodes; - CTurbVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ + CScalarVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ /*! * \brief Return nodes to allow CSolver::base_nodes to be set. diff --git a/SU2_CFD/include/solver_structure.inl b/SU2_CFD/include/solver_structure.inl index 8ade67dfd50b..09ea75063987 100644 --- a/SU2_CFD/include/solver_structure.inl +++ b/SU2_CFD/include/solver_structure.inl @@ -114,6 +114,8 @@ inline void CSolver::SetPrimitive_Limiter(CGeometry *geometry, CConfig *config) inline void CSolver::SetPreconditioner(CConfig *config, unsigned long iPoint) { } +inline void CSolver::SetPreconditioner(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } + inline void CSolver::SetDistance(CGeometry *geometry, CConfig *config) { }; inline su2double CSolver::GetCD_Inv(unsigned short val_marker) { return 0; } @@ -608,6 +610,8 @@ inline su2double CSolver::GetTke_Inf(void) { return 0; } inline su2double CSolver::GetOmega_Inf(void) { return 0; } +inline su2double CSolver::GetScalar_Inf(unsigned short val_ivar) { return 0; } + inline su2double CSolver::GetTotal_Sens_E(unsigned short iVal) { return 0.0; } inline su2double CSolver::GetTotal_Sens_Nu(unsigned short iVal) { return 0.0; } @@ -2413,7 +2417,6 @@ inline void CEulerSolver::SetSlidingStateStructure(unsigned short val_marker, un SlidingState[val_marker][val_vertex][iVar] = new su2double[ GetnSlidingStates(val_marker, val_vertex) ]; } - inline void CIncEulerSolver::SetSlidingStateStructure(unsigned short val_marker, unsigned long val_vertex){ int iVar; @@ -2426,9 +2429,7 @@ inline void CIncEulerSolver::SetSlidingStateStructure(unsigned short val_marker, SlidingState[val_marker][val_vertex][iVar] = new su2double[ GetnSlidingStates(val_marker, val_vertex) ]; } - - -inline void CTurbSolver::SetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index, su2double component){ +inline void CTurbSolver::SetSlidingState(unsigned short val_marker, unsigned long val_vertex, unsigned short val_state, unsigned long donor_index, su2double component){ SlidingState[val_marker][val_vertex][val_state][donor_index] = component; } diff --git a/SU2_CFD/include/solvers/CPassiveScalarSolver.hpp b/SU2_CFD/include/solvers/CPassiveScalarSolver.hpp new file mode 100644 index 000000000000..2036fa83c0c8 --- /dev/null +++ b/SU2_CFD/include/solvers/CPassiveScalarSolver.hpp @@ -0,0 +1,137 @@ +/*! + * \file CPassiveScalarSolver.hpp + * \brief Declaration and inlines for the passive scalar transport class. + * \author T. Economon + * \version 6.2.0 "Falcon" + * + * The current SU2 release has been coordinated by the + * SU2 International Developers Society + * with selected contributions from the open-source community. + * + * The main research teams contributing to the current release are: + * - Prof. Juan J. Alonso's group at Stanford University. + * - Prof. Piero Colonna's group at Delft University of Technology. + * - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology. + * - Prof. Alberto Guardone's group at Polytechnic University of Milan. + * - Prof. Rafael Palacios' group at Imperial College London. + * - Prof. Vincent Terrapon's group at the University of Liege. + * - Prof. Edwin van der Weide's group at the University of Twente. + * - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics. + * + * Copyright 2012-2019, Francisco D. Palacios, Thomas D. Economon, + * Tim Albring, and the SU2 contributors. + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CScalarSolver.hpp" + +/*! + * \class CPassiveScalarSolver + * \brief Main class for defining the passive scalar solver. + * \ingroup Scalar_Model + * \author T. Economon + */ +class CPassiveScalarSolver: public CScalarSolver { +private: + CFluidModel *FluidModel; /*!< \brief Fluid model for the scalar transport problem. */ + +public: + /*! + * \brief Constructor of the class. + */ + CPassiveScalarSolver(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] FluidModel + */ + CPassiveScalarSolver(CGeometry *geometry, CConfig *config, + unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + ~CPassiveScalarSolver(void); + + /*! + * \brief Restart residual and compute gradients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, CSolver **solver_container, + CConfig *config, unsigned short iMesh, + unsigned short iRKStep, unsigned short RunTime_EqSystem, + bool Output); + + /*! + * \brief Post-processing routine for the passive scalar model. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void Postprocessing(CGeometry *geometry, CSolver **solver_container, + CConfig *config, unsigned short iMesh); + + /*! + * \brief Compute the primitive variables (diffusivities) + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] Output - boolean to determine whether to print output. + * \return - The number of non-physical points. + */ + unsigned long SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output); + + /*! + * \brief Set the initial condition for the scalar transport problem. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] ExtIter - External iteration. + */ + void SetInitialCondition(CGeometry **geometry, CSolver ***solver_container, + CConfig *config, unsigned long ExtIter); + + /*! + * \brief Compute the preconditioner for low-Mach flows. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void SetPreconditioner(CGeometry *geometry, CSolver **solver_container, CConfig *config); + + /*! + * \brief Source term computation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] second_numerics - Description of the second numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Residual(CGeometry *geometry, CSolver **solver_container, + CNumerics *numerics, CNumerics *second_numerics, + CConfig *config, unsigned short iMesh); + +}; diff --git a/SU2_CFD/include/solvers/CScalarSolver.hpp b/SU2_CFD/include/solvers/CScalarSolver.hpp new file mode 100644 index 000000000000..a07f92c285b4 --- /dev/null +++ b/SU2_CFD/include/solvers/CScalarSolver.hpp @@ -0,0 +1,331 @@ +/*! + * \file CMeshSolver.hpp + * \brief Declaration and inlines of the class to compute the deformation of + * the volumetric numerical grid using the linear elasticity solver. + * \author Ruben Sanchez, based on CVolumetricMovement developments (F. Palacios, A. Bueno, T. Economon, S. Padron) + * \version 6.2.0 "Falcon" + * + * The current SU2 release has been coordinated by the + * SU2 International Developers Society + * with selected contributions from the open-source community. + * + * The main research teams contributing to the current release are: + * - Prof. Juan J. Alonso's group at Stanford University. + * - Prof. Piero Colonna's group at Delft University of Technology. + * - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology. + * - Prof. Alberto Guardone's group at Polytechnic University of Milan. + * - Prof. Rafael Palacios' group at Imperial College London. + * - Prof. Vincent Terrapon's group at the University of Liege. + * - Prof. Edwin van der Weide's group at the University of Twente. + * - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics. + * + * Copyright 2012-2019, Francisco D. Palacios, Thomas D. Economon, + * Tim Albring, and the SU2 contributors. + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "../solver_structure.hpp" + +/*! + * \class CScalarSolver + * \brief Main class for defining the solver for scalar transport eqns. + * \ingroup Scalar_Model + * \author T. Economon + */ +class CScalarSolver : public CSolver { +protected: + su2double *FlowPrimVar_i, /*!< \brief Store the flow solution at point i. */ + *FlowPrimVar_j, /*!< \brief Store the flow solution at point j. */ + *lowerlimit, /*!< \brief contains lower limits for turbulence variables. */ + *upperlimit; /*!< \brief contains upper limits for turbulence variables. */ + su2double*** Inlet_ScalarVars; /*!< \brief Scalar variables at inlet profiles */ + unsigned long nMarker, /*!< \brief Total number of markers using the grid information. */ + *nVertex; /*!< \brief Store nVertex at each marker for deallocation */ + unsigned short Inlet_Position; /*!< \brief Column index for scalar variables in inlet files. */ + su2double *Scalar_Inf; /*!< \brief Array of far-field values for the scalar variables. */ + + /* Sliding mesh variables */ + + su2double ****SlidingState; + int **SlidingStateNodes; + + CScalarVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */ + + /*! + * \brief Return nodes to allow CSolver::base_nodes to be set. + */ + inline CVariable* GetBaseClassPointerToNodes() override { return nodes; } + +public: + + /*! + * \brief Constructor of the class. + */ + CScalarSolver(void); + + /*! + * \brief Destructor of the class. + */ + virtual ~CScalarSolver(void); + + /*! + * \brief Constructor of the class. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + CScalarSolver(CGeometry* geometry, CConfig *config); + + /*! + * \brief Compute the spatial integration using a upwind scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + + void Upwind_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh); + + /*! + * \brief Compute the viscous residuals. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void Viscous_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep); + + + /*! + * \brief Update the solution using an implicit scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void ImplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config); + + /*! + * \brief Impose the Symmetry Plane boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Sym_Plane(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker); + + /*! + * \brief Impose via the residual the Euler wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Euler_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker); + + /*! + * \brief Impose the Navier-Stokes wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, + CNumerics *conv_numerics, CNumerics *visc_numerics, + CConfig *config, unsigned short val_marker); + + /*! + * \brief Impose the Navier-Stokes wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, + CNumerics *conv_numerics, CNumerics *visc_numerics, + CConfig *config, unsigned short val_marker); + + /*! + * \brief Impose the Far Field boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Far_Field(CGeometry *geometry, CSolver **solver_container, + CNumerics *conv_numerics, CNumerics *visc_numerics, + CConfig *config, unsigned short val_marker); + + /*! + * \brief Impose the inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Inlet(CGeometry *geometry, CSolver **solver_container, + CNumerics *conv_numerics, CNumerics *visc_numerics, + CConfig *config, unsigned short val_marker); + + /*! + * \brief Impose the outlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Outlet(CGeometry *geometry, CSolver **solver_container, + CNumerics *conv_numerics, CNumerics *visc_numerics, + CConfig *config, unsigned short val_marker); + /*! + * \brief Impose a periodic boundary condition by summing contributions from the complete control volume. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + */ + void BC_Periodic(CGeometry *geometry, CSolver **solver_container, + CNumerics *numerics, CConfig *config); + + /*! + * \brief Set the total residual adding the term that comes from the Dual Time-Stepping Strategy. + * \param[in] geometry - Geometric definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + */ + void SetResidual_DualTime(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep, + unsigned short iMesh, + unsigned short RunTime_EqSystem); + + /*! + * \brief Load a solution from a restart file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + * \param[in] val_update_geo - Flag for updating coords and grid velocity. + */ + void LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo); + + /*! + * \brief Set custom scalar variables at the vertex of an inlet. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] iDim - Index of the scalar variable + * \param[in] val_turb_var - Value of the turbulence variable to be used. + */ + void SetInlet_ScalarVar(unsigned short val_marker, + unsigned long val_vertex, + unsigned short val_dim, + su2double val_scalar_var); + + /*! + * \brief Set the solution using the Freestream values. + * \param[in] config - Definition of the particular problem. + */ + inline void SetFreeStream_Solution(CConfig *config) { + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint++) + for (unsigned short iVar = 0; iVar < nVar; iVar++) + nodes->SetSolution(iPoint, iVar, Scalar_Inf[iVar]); + } + + /*! + * \brief Store of a set of provided inlet profile values at a vertex. + * \param[in] val_inlet - vector containing the inlet values for the current vertex. + * \param[in] iMarker - Surface marker where the coefficient is computed. + * \param[in] iVertex - Vertex of the marker iMarker where the inlet is being set. + */ + void SetInletAtVertex(su2double *val_inlet, unsigned short iMarker, unsigned long iVertex); + + /*! + * \brief Get the set of values imposed at an inlet. + * \param[in] val_inlet - vector returning the inlet values for the current vertex. + * \param[in] val_inlet_point - Node index where the inlet is being set. + * \param[in] val_kind_marker - Enumerated type for the particular inlet type. + * \param[in] geometry - Geometrical definition of the problem. + * \param config - Definition of the particular problem. + * \return Value of the face area at the vertex. + */ + su2double GetInletAtVertex(su2double *val_inlet, + unsigned long val_inlet_point, + unsigned short val_kind_marker, + string val_marker, + CGeometry *geometry, + CConfig *config); + + /*! + * \brief Set a uniform inlet profile + * + * The values at the inlet are set to match the values specified for + * inlets in the configuration file. + * + * \param[in] config - Definition of the particular problem. + * \param[in] iMarker - Surface marker where the coefficient is computed. + */ + void SetUniformInlet(CConfig* config, unsigned short iMarker); + + /*! + * \brief Get the value of the scalar variables at the far-field. + * \return Value of the scalar variables at the far-field. + */ + inline su2double GetScalar_Inf(unsigned short val_ivar) { return Scalar_Inf[val_ivar]; } + +}; diff --git a/SU2_CFD/include/transport_model.hpp b/SU2_CFD/include/transport_model.hpp index ec0044952211..52f17784392b 100644 --- a/SU2_CFD/include/transport_model.hpp +++ b/SU2_CFD/include/transport_model.hpp @@ -472,4 +472,148 @@ class CPolynomialConductivityRANS : public CConductivityModel { }; +/*! + * \class CDiffusivityModel + * \brief Defines a mass diffusivity model for species equations. + * \author T. Economon + */ +class CDiffusivityModel { + +protected: + su2double Diffusivity; /*!< \brief Mass diffusivity. */ + + +public: + + /*! + * \brief Constructor of the class. + */ + CDiffusivityModel(void); + + /*! + * \brief Destructor of the class. + */ + virtual ~CDiffusivityModel(void); + + /*! + * \brief return diffusivity value. + */ + su2double GetDiffusivity(void); + + /*! + * \brief Set diffusivity. + */ + virtual void SetDiffusivity (su2double T, + su2double rho, + su2double mu_lam, + su2double mu_turb, + su2double cp); + +}; + +/*! + * \class CConstantDiffusivity + * \brief Defines a constant mass diffusivity model for species equations. + * \author T. Economon + */ +class CConstantDiffusivity : public CDiffusivityModel { + +protected: + +public: + + /*! + * \brief Constructor of the class. + */ + CConstantDiffusivity(void); + + /*! + * \brief Constructor of the class. + */ + CConstantDiffusivity(su2double diff_constant); + + /*! + * \brief Destructor of the class. + */ + virtual ~CConstantDiffusivity(void); + +}; + +/*! + * \class CDiffusivityModel + * \brief Defines a mass diffusivity model for species equations based on Schmidt number. + * \author T. Economon + */ +class CConstantSchmidt : public CDiffusivityModel { + +protected: + su2double Schmidt_const; /*!< \brief Constant Schmidt number. */ + +public: + + /*! + * \brief Constructor of the class. + */ + CConstantSchmidt(void); + + /*! + * \brief Constructor of the class. + */ + CConstantSchmidt(su2double sc_const); + + /*! + * \brief Destructor of the class. + */ + virtual ~CConstantSchmidt(void); + + /*! + * \brief Set diffusivity. + */ + void SetDiffusivity(su2double T, + su2double rho, + su2double mu_lam, + su2double mu_turb, + su2double cp); + +}; + +/*! + * \class CDiffusivityModelRANS + * \brief Defines a mass diffusivity model for species equations based on Schmidt numbers for RANS. + * \author T. Economon + */ +class CConstantSchmidtRANS : public CDiffusivityModel { + +protected: + su2double Schmidt_Lam; /*!< \brief Laminar Schmidt number. */ + su2double Schmidt_Turb; /*!< \brief Laminar Schmidt number. */ + +public: + + /*! + * \brief Constructor of the class. + */ + CConstantSchmidtRANS(void); + + /*! + * \brief Constructor of the class. + */ + CConstantSchmidtRANS(su2double sc_lam, su2double sc_turb); + + /*! + * \brief Destructor of the class. + */ + virtual ~CConstantSchmidtRANS(void); + + /*! + * \brief Set diffusivity. + */ + void SetDiffusivity(su2double T, + su2double rho, + su2double mu_lam, + su2double mu_turb, + su2double cp); + +}; + #include "transport_model.inl" diff --git a/SU2_CFD/include/transport_model.inl b/SU2_CFD/include/transport_model.inl index 26055bb1e1d5..725b1f88689e 100644 --- a/SU2_CFD/include/transport_model.inl +++ b/SU2_CFD/include/transport_model.inl @@ -1,7 +1,7 @@ /*! * \file transport_model.inl * \brief In-Line subroutines of the solver_structure.hpp file. - * \author S. Vitale, M. Pini, G. Gori, A. Guardone, P. Colonna + * \author S. Vitale, M. Pini, G. Gori, A. Guardone, P. Colonna, T. Economon * \version 6.2.0 "Falcon" * * The current SU2 release has been coordinated by the @@ -48,3 +48,6 @@ inline su2double CConductivityModel::Getdktdrho_T () { return dktdrho_T; } inline su2double CConductivityModel::GetdktdT_rho () { return dktdT_rho; } inline void CConductivityModel::SetConductivity(su2double T, su2double rho, su2double mu_lam, su2double mu_turb, su2double cp) {} inline void CConductivityModel::SetDerConductivity(su2double T, su2double rho, su2double dmudrho_T, su2double dmudT_rho, su2double cp) {} + +inline su2double CDiffusivityModel::GetDiffusivity() { return Diffusivity; } +inline void CDiffusivityModel::SetDiffusivity(su2double T, su2double rho, su2double mu_lam, su2double mu_turb, su2double cp) {} diff --git a/SU2_CFD/include/variables/CIncNSVariable.hpp b/SU2_CFD/include/variables/CIncNSVariable.hpp index 1992b9f702fd..bf5c5f77bf92 100644 --- a/SU2_CFD/include/variables/CIncNSVariable.hpp +++ b/SU2_CFD/include/variables/CIncNSVariable.hpp @@ -132,7 +132,7 @@ class CIncNSVariable final : public CIncEulerVariable { /*! * \brief Set all the primitive variables for incompressible flows */ - bool SetPrimVar(unsigned long iPoint, su2double eddy_visc, su2double turb_ke, CFluidModel *FluidModel) override; + bool SetPrimVar(unsigned long iPoint, su2double eddy_visc, su2double turb_ke, su2double *scalar, CFluidModel *FluidModel) override; using CVariable::SetPrimVar; /*! diff --git a/SU2_CFD/include/variables/CNSVariable.hpp b/SU2_CFD/include/variables/CNSVariable.hpp index 9efee442d51a..86e922833655 100644 --- a/SU2_CFD/include/variables/CNSVariable.hpp +++ b/SU2_CFD/include/variables/CNSVariable.hpp @@ -181,7 +181,7 @@ class CNSVariable final : public CEulerVariable { /*! * \brief Set all the primitive variables for compressible flows */ - bool SetPrimVar(unsigned long iPoint, su2double eddy_visc, su2double turb_ke, CFluidModel *FluidModel) override; + bool SetPrimVar(unsigned long iPoint, su2double eddy_visc, su2double turb_ke, su2double *scalar, CFluidModel *FluidModel) override; using CVariable::SetPrimVar; /*! diff --git a/SU2_CFD/include/variables/CPassiveScalarVariable.hpp b/SU2_CFD/include/variables/CPassiveScalarVariable.hpp new file mode 100644 index 000000000000..3f760700527b --- /dev/null +++ b/SU2_CFD/include/variables/CPassiveScalarVariable.hpp @@ -0,0 +1,72 @@ +/*! + * \file CPassiveScalarVariable + * \brief Declaration of the variables of the passive scalar model. + * \author T. Economon + * \version 6.2.0 "Falcon" + * + * The current SU2 release has been coordinated by the + * SU2 International Developers Society + * with selected contributions from the open-source community. + * + * The main research teams contributing to the current release are: + * - Prof. Juan J. Alonso's group at Stanford University. + * - Prof. Piero Colonna's group at Delft University of Technology. + * - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology. + * - Prof. Alberto Guardone's group at Polytechnic University of Milan. + * - Prof. Rafael Palacios' group at Imperial College London. + * - Prof. Vincent Terrapon's group at the University of Liege. + * - Prof. Edwin van der Weide's group at the University of Twente. + * - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics. + * + * Copyright 2012-2019, Francisco D. Palacios, Thomas D. Economon, + * Tim Albring, and the SU2 contributors. + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CScalarVariable.hpp" + +/*! + * \class CPassiveScalarVariable + * \brief Main class for defining the variables of the passive scalar model. + * \author T. Economon + */ +class CPassiveScalarVariable final : public CScalarVariable { + +private: + +public: + /*! + * \brief Constructor of the class. + * \param[in] val_scalar_inf - Scalar variable value (initialization value). + * \param[in] npoint - Number of points/nodes/vertices in the domain. + * \param[in] ndim - Number of dimensions of the problem. + * \param[in] nvar - Number of variables of the problem. + * \param[in] constants - + * \param[in] config - Definition of the particular problem. + */ + CPassiveScalarVariable(su2double *val_scalar_inf, + unsigned long npoint, + unsigned long ndim, + unsigned long nvar, + CConfig *config); + + /*! + * \brief Destructor of the class. + */ + ~CPassiveScalarVariable() = default; + +}; diff --git a/SU2_CFD/include/variables/CScalarVariable.hpp b/SU2_CFD/include/variables/CScalarVariable.hpp new file mode 100644 index 000000000000..7ead3e25597d --- /dev/null +++ b/SU2_CFD/include/variables/CScalarVariable.hpp @@ -0,0 +1,99 @@ +/*! + * \file CScalarVariable.hpp + * \brief Class for defining the variables of scalar transport equations. + * \author T. Economon + * \version 6.2.0 "Falcon" + * + * The current SU2 release has been coordinated by the + * SU2 International Developers Society + * with selected contributions from the open-source community. + * + * The main research teams contributing to the current release are: + * - Prof. Juan J. Alonso's group at Stanford University. + * - Prof. Piero Colonna's group at Delft University of Technology. + * - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology. + * - Prof. Alberto Guardone's group at Polytechnic University of Milan. + * - Prof. Rafael Palacios' group at Imperial College London. + * - Prof. Vincent Terrapon's group at the University of Liege. + * - Prof. Edwin van der Weide's group at the University of Twente. + * - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics. + * + * Copyright 2012-2019, Francisco D. Palacios, Thomas D. Economon, + * Tim Albring, and the SU2 contributors. + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CVariable.hpp" + +/*! + * \class CScalarVariable + * \brief Main class for defining the variables of scalar transport eqns. + * \ingroup Scalar_Equations + * \author T. Economon + */ +class CScalarVariable : public CVariable { +protected: + MatrixType Diffusivity; /*!< \brief Vector of mass diffusivities for scalar transport. */ + +public: + /*! + * \brief Constructor of the class. + * \param[in] npoint - Number of points/nodes/vertices in the domain. + * \param[in] ndim - Number of dimensions of the problem. + * \param[in] nvar - Number of variables of the problem. + * \param[in] config - Definition of the particular problem. + */ + CScalarVariable(unsigned long npoint, + unsigned long ndim, + unsigned long nvar, + CConfig *config); + + /*! + * \brief Destructor of the class. + */ + virtual ~CScalarVariable() = default; + + /*! + * \brief Set the value of the mass diffusivity + * \param[in] val_diffusivity - the mass diffusivity. + * \param[in] val_ivar - eqn. index to the mass diffusivity. + */ + inline void SetDiffusivity(unsigned long iPoint, + su2double val_diffusivity, + unsigned short val_ivar) { + Diffusivity(iPoint,val_ivar) = val_diffusivity; + } + + /*! + * \brief Get the value of the mass diffusivity + * \param[in] val_ivar - eqn. index to the mass diffusivity. + * \return Value of the mass diffusivity + */ + inline su2double GetDiffusivity(unsigned long iPoint, + unsigned short val_ivar) { + return Diffusivity(iPoint,val_ivar); + } + + /*! + * \brief Get the value of the mass diffusivities + * \return Pointer to the mass diffusivities + */ + inline su2double* GetDiffusivity(unsigned long iPoint) { + return Diffusivity[iPoint]; + } + +}; diff --git a/SU2_CFD/include/variables/CTransLMVariable.hpp b/SU2_CFD/include/variables/CTransLMVariable.hpp index 43a900f71161..4c52c7da76a2 100644 --- a/SU2_CFD/include/variables/CTransLMVariable.hpp +++ b/SU2_CFD/include/variables/CTransLMVariable.hpp @@ -37,7 +37,7 @@ #pragma once -#include "CTurbVariable.hpp" +#include "CScalarVariable.hpp" /*! * \class CTransLMVariable @@ -45,8 +45,7 @@ * \ingroup Turbulence_Model * \author A. Bueno. */ - -class CTransLMVariable final : public CTurbVariable { +class CTransLMVariable final : public CScalarVariable { protected: VectorType gamma_sep; diff --git a/SU2_CFD/include/variables/CTurbSAVariable.hpp b/SU2_CFD/include/variables/CTurbSAVariable.hpp index 1dc15995f0c9..59a090a3e6e3 100644 --- a/SU2_CFD/include/variables/CTurbSAVariable.hpp +++ b/SU2_CFD/include/variables/CTurbSAVariable.hpp @@ -37,7 +37,7 @@ #pragma once -#include "CTurbVariable.hpp" +#include "CScalarVariable.hpp" /*! * \class CTurbSAVariable @@ -46,9 +46,11 @@ * \author A. Bueno. */ -class CTurbSAVariable final : public CTurbVariable { +class CTurbSAVariable final : public CScalarVariable { private: + VectorType muT; /*!< \brief Eddy viscosity. */ + MatrixType HB_Source; /*!< \brief Harmonic Balance source term. */ VectorType gamma_BC; /*!< \brief Value of the intermittency for the BC trans. model. */ VectorType DES_LengthScale; VectorType Vortex_Tilting; @@ -71,6 +73,20 @@ class CTurbSAVariable final : public CTurbVariable { */ ~CTurbSAVariable() = default; + /*! + * \brief Get the value of the eddy viscosity. + * \param[in] iPoint - Point index. + * \return the value of the eddy viscosity. + */ + inline su2double GetmuT(unsigned long iPoint) const final { return muT(iPoint); } + + /*! + * \brief Set the value of the eddy viscosity. + * \param[in] iPoint - Point index. + * \param[in] val_muT - Value of the eddy viscosity. + */ + inline void SetmuT(unsigned long iPoint, su2double val_muT) final { muT(iPoint) = val_muT; } + /*! * \brief Set the harmonic balance source term. * \param[in] iPoint - Point index. diff --git a/SU2_CFD/include/variables/CTurbSSTVariable.hpp b/SU2_CFD/include/variables/CTurbSSTVariable.hpp index 7b3ae7b7dfd7..bc672b954c23 100644 --- a/SU2_CFD/include/variables/CTurbSSTVariable.hpp +++ b/SU2_CFD/include/variables/CTurbSSTVariable.hpp @@ -37,7 +37,7 @@ #pragma once -#include "CTurbVariable.hpp" +#include "CScalarVariable.hpp" /*! * \class CTurbSSTVariable @@ -46,8 +46,10 @@ * \author A. Bueno. */ -class CTurbSSTVariable final : public CTurbVariable { +class CTurbSSTVariable final : public CScalarVariable { protected: + VectorType muT; /*!< \brief Eddy viscosity. */ + MatrixType HB_Source; /*!< \brief Harmonic Balance source term. */ su2double sigma_om2; su2double beta_star; VectorType F1; @@ -74,6 +76,20 @@ class CTurbSSTVariable final : public CTurbVariable { */ ~CTurbSSTVariable() = default; + /*! + * \brief Get the value of the eddy viscosity. + * \param[in] iPoint - Point index. + * \return the value of the eddy viscosity. + */ + inline su2double GetmuT(unsigned long iPoint) const final { return muT(iPoint); } + + /*! + * \brief Set the value of the eddy viscosity. + * \param[in] iPoint - Point index. + * \param[in] val_muT - Value of the eddy viscosity. + */ + inline void SetmuT(unsigned long iPoint, su2double val_muT) final { muT(iPoint) = val_muT; } + /*! * \brief Set the blending function for the blending of k-w and k-eps. * \param[in] val_viscosity - Value of the vicosity. diff --git a/SU2_CFD/include/variables/CVariable.hpp b/SU2_CFD/include/variables/CVariable.hpp index 3d74df798c4e..ac5b39bae8d2 100644 --- a/SU2_CFD/include/variables/CVariable.hpp +++ b/SU2_CFD/include/variables/CVariable.hpp @@ -1442,6 +1442,11 @@ class CVariable { */ inline virtual bool SetPrimVar(unsigned long iPoint, su2double eddy_visc, su2double turb_ke, CFluidModel *FluidModel) { return true; } + /*! + * \brief A virtual member. + */ + inline virtual bool SetPrimVar(unsigned long iPoint, su2double eddy_visc, su2double turb_ke, su2double *scalar, CFluidModel *FluidModel) { return true; } + /*! * \brief A virtual member. */ @@ -2688,6 +2693,12 @@ class CVariable { inline virtual su2double GetVortex_Tilting(unsigned long iPoint) const { return 0.0; } + inline virtual void SetDiffusivity(unsigned long iPoint, su2double val_diffusivity, unsigned short val_ivar) { } + + inline virtual su2double GetDiffusivity(unsigned long iPoint, unsigned short val_ivar) { return 0.0; } + + inline virtual su2double* GetDiffusivity(unsigned long iPoint) { return NULL; } + inline virtual void SetDynamic_Derivative(unsigned long iPoint, unsigned long iVar, su2double der) {} inline virtual void SetDynamic_Derivative_n(unsigned long iPoint, unsigned long iVar, su2double der) {} diff --git a/SU2_CFD/obj/Makefile.am b/SU2_CFD/obj/Makefile.am index a482e76cce0c..d3d2495e9841 100644 --- a/SU2_CFD/obj/Makefile.am +++ b/SU2_CFD/obj/Makefile.am @@ -80,6 +80,7 @@ libSU2Core_sources = ../src/definition_structure.cpp \ ../src/numerics_direct_mean_inc.cpp \ ../src/numerics_direct_transition.cpp \ ../src/numerics_direct_turbulent.cpp \ + ../src/numerics_direct_scalar.cpp \ ../src/numerics_direct_elasticity_nonlinear.cpp \ ../src/numerics_direct_elasticity_linear.cpp \ ../src/numerics_direct_elasticity.cpp \ @@ -130,6 +131,8 @@ libSU2Core_sources = ../src/definition_structure.cpp \ ../src/solver_direct_turbulent.cpp \ ../src/solver_direct_elasticity.cpp \ ../src/solvers/CMeshSolver.cpp \ + ../src/solvers/CScalarSolver.cpp \ + ../src/solvers/CPassiveScalarSolver.cpp \ ../src/solver_structure.cpp \ ../src/solver_template.cpp \ ../src/interfaces/CInterface.cpp \ @@ -158,6 +161,8 @@ libSU2Core_sources = ../src/definition_structure.cpp \ ../src/variables/CDiscAdjFEAVariable.cpp \ ../src/variables/CIncEulerVariable.cpp \ ../src/variables/CTurbVariable.cpp \ + ../src/variables/CScalarVariable.cpp \ + ../src/variables/CPassiveScalarVariable.cpp \ ../src/variables/CNSVariable.cpp \ ../src/variables/CBaselineVariable.cpp \ ../src/variables/CTurbSAVariable.cpp \ diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index bb4d6b371754..c69b63c0f03e 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -1073,6 +1073,7 @@ void CDriver::Solver_Preprocessing(CConfig* config, CGeometry** geometry, CSolve template_solver, disc_adj, disc_adj_turb, disc_adj_heat, fem_dg_flow, fem_dg_shock_persson, e_spalart_allmaras, comp_spalart_allmaras, e_comp_spalart_allmaras; + bool scalar, passive_scalar, progress_variable; /*--- Count the number of DOFs per solution point. ---*/ @@ -1092,6 +1093,7 @@ void CDriver::Solver_Preprocessing(CConfig* config, CGeometry** geometry, CSolve template_solver = false; fem_dg_flow = false; fem_dg_shock_persson = false; e_spalart_allmaras = false; comp_spalart_allmaras = false; e_comp_spalart_allmaras = false; + scalar = false; passive_scalar = false; progress_variable = false; bool compressible = false; bool incompressible = false; @@ -1101,11 +1103,11 @@ void CDriver::Solver_Preprocessing(CConfig* config, CGeometry** geometry, CSolve switch (config->GetKind_Solver()) { case TEMPLATE_SOLVER: template_solver = true; break; case EULER : euler = true; compressible = true; break; - case NAVIER_STOKES: ns = true; compressible = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case RANS : ns = true; turbulent = true; compressible = true; if (config->GetKind_Trans_Model() == LM) transition = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case NAVIER_STOKES: ns = true; compressible = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case RANS : ns = true; turbulent = true; compressible = true; if (config->GetKind_Trans_Model() == LM) transition = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; case INC_EULER : euler = true; incompressible = true; break; - case INC_NAVIER_STOKES: ns = true; incompressible = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case INC_RANS : ns = true; turbulent = true; incompressible = true; if (config->GetKind_Trans_Model() == LM) transition = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case INC_NAVIER_STOKES: ns = true; incompressible = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case INC_RANS : ns = true; turbulent = true; incompressible = true; if (config->GetKind_Trans_Model() == LM) transition = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; case FEM_EULER : fem_euler = true; compressible = true; break; case FEM_NAVIER_STOKES: fem_ns = true; compressible = true; break; case FEM_RANS : fem_ns = true; fem_turbulent = true; compressible = true; if(config->GetKind_Trans_Model() == LM) fem_transition = true; break; @@ -1116,11 +1118,11 @@ void CDriver::Solver_Preprocessing(CConfig* config, CGeometry** geometry, CSolve case ADJ_NAVIER_STOKES : ns = true; turbulent = (config->GetKind_Turb_Model() != NONE); compressible = true; adj_ns = true; break; case ADJ_RANS : ns = true; turbulent = true; adj_ns = true; compressible = true; adj_turb = (!config->GetFrozen_Visc_Cont()); break; case DISC_ADJ_EULER: euler = true; disc_adj = true; compressible = true; break; - case DISC_ADJ_NAVIER_STOKES: ns = true; disc_adj = true; compressible = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_RANS: ns = true; turbulent = true; disc_adj = true; compressible = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case DISC_ADJ_NAVIER_STOKES: ns = true; disc_adj = true; compressible = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case DISC_ADJ_RANS: ns = true; turbulent = true; disc_adj = true; compressible = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; case DISC_ADJ_INC_EULER: euler = true; disc_adj = true; incompressible = true; break; - case DISC_ADJ_INC_NAVIER_STOKES: ns = true; disc_adj = true; incompressible = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_INC_RANS: ns = true; turbulent = true; disc_adj = true; incompressible = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case DISC_ADJ_INC_NAVIER_STOKES: ns = true; disc_adj = true; incompressible = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case DISC_ADJ_INC_RANS: ns = true; turbulent = true; disc_adj = true; incompressible = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; case DISC_ADJ_FEM_EULER: fem_euler = true; disc_adj = true; compressible = true; break; case DISC_ADJ_FEM_NS: fem_ns = true; disc_adj = true; compressible = true; break; case DISC_ADJ_FEM_RANS: fem_ns = true; fem_turbulent = true; disc_adj = true; compressible = true; if(config->GetKind_Trans_Model() == LM) fem_transition = true; break; @@ -1154,6 +1156,16 @@ void CDriver::Solver_Preprocessing(CConfig* config, CGeometry** geometry, CSolve default: SU2_MPI::Error("Specified turbulence model unavailable or none selected", CURRENT_FUNCTION); break; } + /*--- Assign scalar transport model booleans ---*/ + + if (scalar) { + switch (config->GetKind_Scalar_Model()) { + case PASSIVE_SCALAR: passive_scalar = true; break; + case PROGRESS_VARIABLE: progress_variable = true; break; + default: SU2_MPI::Error("Specified scalar transport model unavailable.", CURRENT_FUNCTION); break; + } + } + /*--- Definition of the Class for the solution: solver[DOMAIN][INSTANCE][MESH_LEVEL][EQUATION]. Note that euler, ns and potential are incompatible, they use the same position in sol container ---*/ @@ -1206,6 +1218,14 @@ void CDriver::Solver_Preprocessing(CConfig* config, CGeometry** geometry, CSolve if (iMGlevel == MESH_0) DOFsPerPoint += solver[iMGlevel][TRANS_SOL]->GetnVar(); } } + + if (scalar) { + if (passive_scalar) { + solver[iMGlevel][SCALAR_SOL] = new CPassiveScalarSolver(geometry[iMGlevel], config, iMGlevel); + } + if (iMGlevel == MESH_0) DOFsPerPoint += solver[iMGlevel][SCALAR_SOL]->GetnVar(); + } + if (fem_euler) { if( fem_dg_flow ) { if( fem_dg_shock_persson ) { @@ -1315,6 +1335,7 @@ void CDriver::Inlet_Preprocessing(CSolver ***solver, CGeometry **geometry, heat, fem, template_solver, disc_adj, disc_adj_fem, disc_adj_turb; + bool scalar; int val_iter = 0; unsigned short iMesh; @@ -1326,6 +1347,7 @@ void CDriver::Inlet_Preprocessing(CSolver ***solver, CGeometry **geometry, fem = false; disc_adj_fem = false; heat = false; disc_adj_turb = false; template_solver = false; + scalar = false; /*--- Adjust iteration number for unsteady restarts. ---*/ @@ -1351,16 +1373,16 @@ void CDriver::Inlet_Preprocessing(CSolver ***solver, CGeometry **geometry, switch (config->GetKind_Solver()) { case TEMPLATE_SOLVER: template_solver = true; break; case EULER : case INC_EULER: euler = true; break; - case NAVIER_STOKES: case INC_NAVIER_STOKES: ns = true; break; - case RANS : case INC_RANS: ns = true; turbulent = true; break; + case NAVIER_STOKES: case INC_NAVIER_STOKES: ns = true; scalar = (config->GetKind_Scalar_Model() != NONE); break; + case RANS : case INC_RANS: ns = true; turbulent = true; scalar = (config->GetKind_Scalar_Model() != NONE); break; case HEAT_EQUATION_FVM: heat = true; break; case FEM_ELASTICITY: fem = true; break; case ADJ_EULER : euler = true; adj_euler = true; break; case ADJ_NAVIER_STOKES : ns = true; turbulent = (config->GetKind_Turb_Model() != NONE); adj_ns = true; break; case ADJ_RANS : ns = true; turbulent = true; adj_ns = true; adj_turb = (!config->GetFrozen_Visc_Cont()); break; case DISC_ADJ_EULER: case DISC_ADJ_INC_EULER: euler = true; disc_adj = true; break; - case DISC_ADJ_NAVIER_STOKES: case DISC_ADJ_INC_NAVIER_STOKES: ns = true; disc_adj = true; break; - case DISC_ADJ_RANS: case DISC_ADJ_INC_RANS: ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); break; + case DISC_ADJ_NAVIER_STOKES: case DISC_ADJ_INC_NAVIER_STOKES: ns = true; disc_adj = true; scalar = (config->GetKind_Scalar_Model() != NONE); break; + case DISC_ADJ_RANS: case DISC_ADJ_INC_RANS: ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); scalar = (config->GetKind_Scalar_Model() != NONE); break; case DISC_ADJ_FEM: fem = true; disc_adj_fem = true; break; } @@ -1387,7 +1409,9 @@ void CDriver::Inlet_Preprocessing(CSolver ***solver, CGeometry **geometry, if (turbulent || adj_turb || disc_adj_turb) { solver[MESH_0][TURB_SOL]->LoadInletProfile(geometry, solver, config, val_iter, TURB_SOL, INLET_FLOW); } - + if (scalar) { + solver[MESH_0][SCALAR_SOL]->LoadInletProfile(geometry, solver, config, val_iter, SCALAR_SOL, INLET_FLOW); + } if (template_solver) { no_profile = true; } @@ -1414,7 +1438,7 @@ void CDriver::Inlet_Preprocessing(CSolver ***solver, CGeometry **geometry, /*--- Uniform inlets or python-customized inlets ---*/ /* --- Initialize quantities for inlet boundary - * This routine does not check if they python wrapper is being used to + * This routine does not check if the python wrapper is being used to * set custom boundary conditions. This is intentional; the * default values for python custom BCs are initialized with the default * values specified in the config (avoiding non physical values) --- */ @@ -1425,6 +1449,8 @@ void CDriver::Inlet_Preprocessing(CSolver ***solver, CGeometry **geometry, solver[iMesh][FLOW_SOL]->SetUniformInlet(config, iMarker); if (turbulent) solver[iMesh][TURB_SOL]->SetUniformInlet(config, iMarker); + if (scalar) + solver[iMesh][SCALAR_SOL]->SetUniformInlet(config, iMarker); } } @@ -1439,6 +1465,7 @@ void CDriver::Solver_Restart(CSolver ***solver, CGeometry **geometry, adj_euler, adj_ns, adj_turb, heat_fvm, fem, fem_euler, fem_ns, fem_dg_flow, template_solver, disc_adj, disc_adj_fem, disc_adj_turb, disc_adj_heat; + bool scalar; int val_iter = 0; /*--- Initialize some useful booleans ---*/ @@ -1451,6 +1478,7 @@ void CDriver::Solver_Restart(CSolver ***solver, CGeometry **geometry, disc_adj_turb = false; heat_fvm = false; disc_adj_heat = false; template_solver = false; + scalar = false; /*--- Check for restarts and use the LoadRestart() routines. ---*/ @@ -1483,8 +1511,8 @@ void CDriver::Solver_Restart(CSolver ***solver, CGeometry **geometry, switch (config->GetKind_Solver()) { case TEMPLATE_SOLVER: template_solver = true; break; case EULER : case INC_EULER: euler = true; break; - case NAVIER_STOKES: case INC_NAVIER_STOKES: ns = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case RANS : case INC_RANS: ns = true; turbulent = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case NAVIER_STOKES: case INC_NAVIER_STOKES: ns = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case RANS : case INC_RANS: ns = true; turbulent = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; case FEM_EULER : fem_euler = true; break; case FEM_NAVIER_STOKES: fem_ns = true; break; case FEM_RANS : fem_ns = true; break; @@ -1495,8 +1523,8 @@ void CDriver::Solver_Restart(CSolver ***solver, CGeometry **geometry, case ADJ_NAVIER_STOKES : ns = true; turbulent = (config->GetKind_Turb_Model() != NONE); adj_ns = true; break; case ADJ_RANS : ns = true; turbulent = true; adj_ns = true; adj_turb = (!config->GetFrozen_Visc_Cont()); break; case DISC_ADJ_EULER: case DISC_ADJ_INC_EULER: euler = true; disc_adj = true; break; - case DISC_ADJ_NAVIER_STOKES: case DISC_ADJ_INC_NAVIER_STOKES: ns = true; disc_adj = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_RANS: case DISC_ADJ_INC_RANS: ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case DISC_ADJ_NAVIER_STOKES: case DISC_ADJ_INC_NAVIER_STOKES: ns = true; disc_adj = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case DISC_ADJ_RANS: case DISC_ADJ_INC_RANS: ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; case DISC_ADJ_FEM_EULER: fem_euler = true; disc_adj = true; break; case DISC_ADJ_FEM_NS: fem_ns = true; disc_adj = true; break; case DISC_ADJ_FEM_RANS: fem_ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); break; @@ -1521,6 +1549,9 @@ void CDriver::Solver_Restart(CSolver ***solver, CGeometry **geometry, if (turbulent) { solver[MESH_0][TURB_SOL]->LoadRestart(geometry, solver, config, val_iter, update_geo); } + if (scalar) { + solver[MESH_0][SCALAR_SOL]->LoadRestart(geometry, solver, config, val_iter, update_geo); + } if (fem) { if (time_domain) val_iter = SU2_TYPE::Int(config->GetRestart_Iter())-1; solver[MESH_0][FEA_SOL]->LoadRestart(geometry, solver, config, val_iter, update_geo); @@ -1590,7 +1621,8 @@ void CDriver::Solver_Postprocessing(CSolver ****solver, CGeometry **geometry, spalart_allmaras, neg_spalart_allmaras, menter_sst, transition, template_solver, disc_adj, disc_adj_turb, disc_adj_fem, disc_adj_heat, e_spalart_allmaras, comp_spalart_allmaras, e_comp_spalart_allmaras; - + bool scalar, passive_scalar, progress_variable; + /*--- Initialize some useful booleans ---*/ euler = false; ns = false; turbulent = false; @@ -1603,14 +1635,15 @@ void CDriver::Solver_Postprocessing(CSolver ****solver, CGeometry **geometry, transition = false; template_solver = false; e_spalart_allmaras = false; comp_spalart_allmaras = false; e_comp_spalart_allmaras = false; - + scalar = false; passive_scalar = false; progress_variable = false; + /*--- Assign booleans ---*/ switch (config->GetKind_Solver()) { case TEMPLATE_SOLVER: template_solver = true; break; case EULER : case INC_EULER: euler = true; break; - case NAVIER_STOKES: case INC_NAVIER_STOKES: ns = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case RANS : case INC_RANS: ns = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case NAVIER_STOKES: case INC_NAVIER_STOKES: ns = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case RANS : case INC_RANS: ns = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; case FEM_EULER : euler = true; break; case FEM_NAVIER_STOKES: case FEM_LES: ns = true; break; @@ -1621,8 +1654,8 @@ void CDriver::Solver_Postprocessing(CSolver ****solver, CGeometry **geometry, case ADJ_NAVIER_STOKES : ns = true; turbulent = (config->GetKind_Turb_Model() != NONE); adj_ns = true; break; case ADJ_RANS : ns = true; turbulent = true; adj_ns = true; adj_turb = (!config->GetFrozen_Visc_Cont()); break; case DISC_ADJ_EULER: case DISC_ADJ_INC_EULER: euler = true; disc_adj = true; break; - case DISC_ADJ_NAVIER_STOKES: case DISC_ADJ_INC_NAVIER_STOKES: ns = true; disc_adj = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_RANS: case DISC_ADJ_INC_RANS: ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case DISC_ADJ_NAVIER_STOKES: case DISC_ADJ_INC_NAVIER_STOKES: ns = true; disc_adj = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case DISC_ADJ_RANS: case DISC_ADJ_INC_RANS: ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; case DISC_ADJ_FEM_EULER: euler = true; disc_adj = true; break; case DISC_ADJ_FEM_NS: ns = true; disc_adj = true; break; case DISC_ADJ_FEM_RANS: ns = true; turbulent = true; disc_adj = true; disc_adj_turb = (!config->GetFrozen_Visc_Disc()); break; @@ -1644,6 +1677,13 @@ void CDriver::Solver_Postprocessing(CSolver ****solver, CGeometry **geometry, default: SU2_MPI::Error("Specified turbulence model unavailable or none selected", CURRENT_FUNCTION); break; } + if (scalar) { + switch (config->GetKind_Scalar_Model()) { + case PASSIVE_SCALAR: passive_scalar = true; break; + case PROGRESS_VARIABLE: progress_variable = true; break; + } + } + /*--- Definition of the Class for the solution: solver_container[DOMAIN][MESH_LEVEL][EQUATION]. Note that euler, ns and potential are incompatible, they use the same position in sol container ---*/ @@ -1685,6 +1725,11 @@ void CDriver::Solver_Postprocessing(CSolver ****solver, CGeometry **geometry, delete solver[val_iInst][iMGlevel][TRANS_SOL]; } } + if (scalar) { + if (passive_scalar || progress_variable) { + delete solver[val_iInst][iMGlevel][SCALAR_SOL]; + } + } if (heat_fvm) { delete solver[val_iInst][iMGlevel][HEAT_SOL]; } @@ -1724,7 +1769,7 @@ void CDriver::Integration_Preprocessing(CConfig *config, CIntegration **&integra bool euler, adj_euler, ns, adj_ns, turbulent, adj_turb, fem, fem_euler, fem_ns, fem_turbulent, - heat_fvm, template_solver, transition, disc_adj, disc_adj_fem, disc_adj_heat; + heat_fvm, template_solver, transition, disc_adj, disc_adj_fem, disc_adj_heat, scalar; /*--- Initialize some useful booleans ---*/ euler = false; adj_euler = false; @@ -1738,13 +1783,14 @@ void CDriver::Integration_Preprocessing(CConfig *config, CIntegration **&integra fem = false; disc_adj_fem = false; transition = false; template_solver = false; + scalar = false; /*--- Assign booleans ---*/ switch (config->GetKind_Solver()) { case TEMPLATE_SOLVER: template_solver = true; break; case EULER : case INC_EULER: euler = true; break; - case NAVIER_STOKES: case INC_NAVIER_STOKES: ns = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case RANS : case INC_RANS: ns = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case NAVIER_STOKES: case INC_NAVIER_STOKES: ns = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case RANS : case INC_RANS: ns = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; case FEM_EULER : fem_euler = true; break; case FEM_NAVIER_STOKES: fem_ns = true; break; case FEM_RANS : fem_ns = true; fem_turbulent = true; break; @@ -1758,8 +1804,8 @@ void CDriver::Integration_Preprocessing(CConfig *config, CIntegration **&integra case DISC_ADJ_FEM_EULER: fem_euler = true; disc_adj = true; break; case DISC_ADJ_FEM_NS: fem_ns = true; disc_adj = true; break; case DISC_ADJ_FEM_RANS: fem_ns = true; fem_turbulent = true; disc_adj = true; break; - case DISC_ADJ_NAVIER_STOKES: case DISC_ADJ_INC_NAVIER_STOKES: ns = true; disc_adj = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_RANS : case DISC_ADJ_INC_RANS: ns = true; turbulent = true; disc_adj = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case DISC_ADJ_NAVIER_STOKES: case DISC_ADJ_INC_NAVIER_STOKES: ns = true; disc_adj = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case DISC_ADJ_RANS : case DISC_ADJ_INC_RANS: ns = true; turbulent = true; disc_adj = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; case DISC_ADJ_FEM: fem = true; disc_adj_fem = true; break; case DISC_ADJ_HEAT: heat_fvm = true; disc_adj_heat = true; break; } @@ -1772,6 +1818,7 @@ void CDriver::Integration_Preprocessing(CConfig *config, CIntegration **&integra if (ns) integration[FLOW_SOL] = new CMultiGridIntegration(config); if (turbulent) integration[TURB_SOL] = new CSingleGridIntegration(config); if (transition) integration[TRANS_SOL] = new CSingleGridIntegration(config); + if (scalar) integration[SCALAR_SOL] = new CMultiGridIntegration(config); if (heat_fvm) integration[HEAT_SOL] = new CSingleGridIntegration(config); if (fem) integration[FEA_SOL] = new CStructuralIntegration(config); @@ -1796,9 +1843,10 @@ void CDriver::Integration_Preprocessing(CConfig *config, CIntegration **&integra } void CDriver::Integration_Postprocessing(CIntegration ***integration, CGeometry **geometry, CConfig *config, unsigned short val_iInst) { + bool euler, adj_euler, ns, adj_ns, turbulent, adj_turb, fem, fem_euler, fem_ns, fem_turbulent, - heat_fvm, template_solver, transition, disc_adj, disc_adj_fem, disc_adj_heat; + heat_fvm, template_solver, transition, disc_adj, disc_adj_fem, disc_adj_heat, scalar; /*--- Initialize some useful booleans ---*/ euler = false; adj_euler = false; @@ -1812,13 +1860,14 @@ void CDriver::Integration_Postprocessing(CIntegration ***integration, CGeometry fem = false; disc_adj_fem = false; transition = false; template_solver = false; - + scalar = false; + /*--- Assign booleans ---*/ switch (config->GetKind_Solver()) { case TEMPLATE_SOLVER: template_solver = true; break; case EULER : case INC_EULER: euler = true; break; - case NAVIER_STOKES: case INC_NAVIER_STOKES: ns = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case RANS : case INC_RANS: ns = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case NAVIER_STOKES: case INC_NAVIER_STOKES: ns = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case RANS : case INC_RANS: ns = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; case FEM_EULER : fem_euler = true; break; case FEM_NAVIER_STOKES: fem_ns = true; break; case FEM_RANS : fem_ns = true; fem_turbulent = true; break; @@ -1829,8 +1878,8 @@ void CDriver::Integration_Postprocessing(CIntegration ***integration, CGeometry case ADJ_NAVIER_STOKES : ns = true; turbulent = (config->GetKind_Turb_Model() != NONE); adj_ns = true; break; case ADJ_RANS : ns = true; turbulent = true; adj_ns = true; adj_turb = (!config->GetFrozen_Visc_Cont()); break; case DISC_ADJ_EULER : case DISC_ADJ_INC_EULER: euler = true; disc_adj = true; break; - case DISC_ADJ_NAVIER_STOKES: case DISC_ADJ_INC_NAVIER_STOKES: ns = true; disc_adj = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case DISC_ADJ_RANS : case DISC_ADJ_INC_RANS: ns = true; turbulent = true; disc_adj = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case DISC_ADJ_NAVIER_STOKES: case DISC_ADJ_INC_NAVIER_STOKES: ns = true; disc_adj = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case DISC_ADJ_RANS : case DISC_ADJ_INC_RANS: ns = true; turbulent = true; disc_adj = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; case DISC_ADJ_FEM_EULER: fem_euler = true; disc_adj = true; break; case DISC_ADJ_FEM_NS: fem_ns = true; disc_adj = true; break; case DISC_ADJ_FEM_RANS: fem_ns = true; fem_turbulent = true; disc_adj = true; break; @@ -1845,6 +1894,7 @@ void CDriver::Integration_Postprocessing(CIntegration ***integration, CGeometry if (euler || ns) delete integration[val_iInst][FLOW_SOL]; if (turbulent) delete integration[val_iInst][TURB_SOL]; if (transition) delete integration[val_iInst][TRANS_SOL]; + if (scalar) delete integration[val_iInst][SCALAR_SOL]; if (heat_fvm) delete integration[val_iInst][HEAT_SOL]; if (fem) delete integration[val_iInst][FEA_SOL]; if (disc_adj_fem) delete integration[val_iInst][ADJFEA_SOL]; @@ -1875,6 +1925,7 @@ void CDriver::Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSol nVar_Flow = 0, nVar_Trans = 0, nVar_Turb = 0, + nVar_Scalar = 0, nVar_Adj_Flow = 0, nVar_Adj_Turb = 0, nVar_FEM = 0, @@ -1896,6 +1947,7 @@ void CDriver::Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSol transition, template_solver; bool e_spalart_allmaras, comp_spalart_allmaras, e_comp_spalart_allmaras; + bool scalar, passive_scalar, progress_variable; bool compressible = false; bool incompressible = false; @@ -1912,16 +1964,17 @@ void CDriver::Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSol transition = false; template_solver = false; e_spalart_allmaras = false; comp_spalart_allmaras = false; e_comp_spalart_allmaras = false; + scalar = false; passive_scalar = false; progress_variable = false; /*--- Assign booleans ---*/ switch (config->GetKind_Solver()) { case TEMPLATE_SOLVER: template_solver = true; break; case EULER : case DISC_ADJ_EULER: compressible = true; euler = true; break; - case NAVIER_STOKES: case DISC_ADJ_NAVIER_STOKES:compressible = true; ns = true; break; - case RANS : case DISC_ADJ_RANS: ns = true; compressible = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; break; + case NAVIER_STOKES: case DISC_ADJ_NAVIER_STOKES:compressible = true; ns = true; scalar = (config->GetKind_Scalar_Model() != NONE); break; + case RANS : case DISC_ADJ_RANS: ns = true; compressible = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; scalar = (config->GetKind_Scalar_Model() != NONE); break; case INC_EULER : case DISC_ADJ_INC_EULER: incompressible =true; euler = true; break; - case INC_NAVIER_STOKES: case DISC_ADJ_INC_NAVIER_STOKES:incompressible =true; ns = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case INC_RANS : case DISC_ADJ_INC_RANS: incompressible =true; ns = true; turbulent = true; heat_fvm = config->GetWeakly_Coupled_Heat(); if (config->GetKind_Trans_Model() == LM) transition = true; break; + case INC_NAVIER_STOKES: case DISC_ADJ_INC_NAVIER_STOKES:incompressible =true; ns = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case INC_RANS : case DISC_ADJ_INC_RANS: incompressible =true; ns = true; turbulent = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); if (config->GetKind_Trans_Model() == LM) transition = true; break; case FEM_EULER : case DISC_ADJ_FEM_EULER : compressible =true; fem_euler = true; break; case FEM_NAVIER_STOKES: case DISC_ADJ_FEM_NS : compressible =true; fem_ns = true; break; case FEM_RANS : case DISC_ADJ_FEM_RANS : compressible =true; fem_ns = true; fem_turbulent = true; break; @@ -1956,6 +2009,16 @@ void CDriver::Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSol omega_Inf = solver[MESH_0][TURB_SOL]->GetOmega_Inf(); } + /*--- Assign scalar transport model booleans. ---*/ + + if (scalar) { + switch (config->GetKind_Scalar_Model()) { + case PASSIVE_SCALAR: passive_scalar = true; break; + case PROGRESS_VARIABLE: progress_variable = true; break; + default: SU2_MPI::Error("Specified scalar transport model unavailable.", CURRENT_FUNCTION); break; + } + } + /*--- Number of variables for the template ---*/ if (template_solver) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); @@ -1966,6 +2029,7 @@ void CDriver::Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSol if (ns) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); if (turbulent) nVar_Turb = solver[MESH_0][TURB_SOL]->GetnVar(); if (transition) nVar_Trans = solver[MESH_0][TRANS_SOL]->GetnVar(); + if (scalar) nVar_Scalar = solver[MESH_0][SCALAR_SOL]->GetnVar(); if (fem_euler) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); if (fem_ns) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); @@ -2408,6 +2472,57 @@ void CDriver::Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSol } } + /*--- Solver definition for the scalar transport model problem ---*/ + + if (scalar) { + + /*--- Definition of the convective scheme for each equation and mesh level ---*/ + + switch (config->GetKind_ConvNumScheme_Scalar()) { + case NONE : + break; + case SPACE_UPWIND : + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + if (passive_scalar || progress_variable) { + numerics[iMGlevel][SCALAR_SOL][CONV_TERM] = new CUpwScalar_General(nDim, nVar_Scalar, config); + } + } + break; + default : + SU2_MPI::Error("Convective scheme not implemented (scalar transport).", CURRENT_FUNCTION); + break; + } + + /*--- Definition of the viscous scheme for each equation and mesh level ---*/ + + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + if (passive_scalar || progress_variable){ + if (iMGlevel == MESH_0) numerics[iMGlevel][SCALAR_SOL][VISC_TERM] = new CAvgGradScalar_General(nDim, nVar_Scalar, true, config); + else numerics[iMGlevel][SCALAR_SOL][VISC_TERM] = new CAvgGradScalar_General(nDim, nVar_Scalar, false, config); + } + } + + /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ + + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + if (passive_scalar || progress_variable) { + numerics[iMGlevel][SCALAR_SOL][SOURCE_FIRST_TERM] = new CSourcePieceWise_Scalar(nDim, nVar_Scalar, config); + if (config->GetAxisymmetric() == YES) + numerics[iMGlevel][SCALAR_SOL][SOURCE_SECOND_TERM] = new CSourceAxisymmetric_Scalar(nDim, nVar_Scalar, config); + else numerics[iMGlevel][SCALAR_SOL][SOURCE_SECOND_TERM] = new CSourceNothing(nDim, nVar_Scalar, config); + } + } + + /*--- Definition of the boundary condition method ---*/ + + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + if (passive_scalar || progress_variable) { + numerics[iMGlevel][SCALAR_SOL][CONV_BOUND_TERM] = new CUpwScalar_General(nDim, nVar_Scalar, config); + numerics[iMGlevel][SCALAR_SOL][VISC_BOUND_TERM] = new CAvgGradScalar_General(nDim, nVar_Scalar, false, config); + } + } + } + /*--- Solver definition of the finite volume heat solver ---*/ if (heat_fvm) { @@ -2729,6 +2844,7 @@ void CDriver::Numerics_Postprocessing(CNumerics *****numerics, template_solver; bool e_spalart_allmaras, comp_spalart_allmaras, e_comp_spalart_allmaras; + bool scalar, passive_scalar, progress_variable; bool compressible = false; bool incompressible = false; @@ -2741,27 +2857,27 @@ void CDriver::Numerics_Postprocessing(CNumerics *****numerics, spalart_allmaras = false; neg_spalart_allmaras = false; menter_sst = false; transition = false; heat_fvm = false; template_solver = false; - e_spalart_allmaras = false; comp_spalart_allmaras = false; e_comp_spalart_allmaras = false; + scalar = false; passive_scalar = false; progress_variable = false; /*--- Assign booleans ---*/ switch (config->GetKind_Solver()) { case TEMPLATE_SOLVER: template_solver = true; break; case EULER : case DISC_ADJ_EULER: compressible = true; euler = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case NAVIER_STOKES: case DISC_ADJ_NAVIER_STOKES:compressible = true; ns = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case RANS : case DISC_ADJ_RANS: ns = true; compressible = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; break; + case NAVIER_STOKES: case DISC_ADJ_NAVIER_STOKES:compressible = true; ns = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case RANS : case DISC_ADJ_RANS: ns = true; compressible = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true;scalar = (config->GetKind_Scalar_Model() != NONE); break; case INC_EULER : case DISC_ADJ_INC_EULER: incompressible =true; euler = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case INC_NAVIER_STOKES: case DISC_ADJ_INC_NAVIER_STOKES:incompressible =true; ns = true; heat_fvm = config->GetWeakly_Coupled_Heat(); break; - case INC_RANS : case DISC_ADJ_INC_RANS: incompressible =true; ns = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; break; + case INC_NAVIER_STOKES: case DISC_ADJ_INC_NAVIER_STOKES:incompressible =true; ns = true; scalar = (config->GetKind_Scalar_Model() != NONE); heat_fvm = config->GetWeakly_Coupled_Heat(); break; + case INC_RANS : case DISC_ADJ_INC_RANS: incompressible =true; ns = true; turbulent = true; if (config->GetKind_Trans_Model() == LM) transition = true; scalar = (config->GetKind_Scalar_Model() != NONE); break; case FEM_EULER : case DISC_ADJ_FEM_EULER : fem_euler = true; break; case FEM_NAVIER_STOKES: case DISC_ADJ_FEM_NS : fem_ns = true; break; case FEM_RANS : case DISC_ADJ_FEM_RANS : fem_ns = true; fem_turbulent = true; break; case FEM_LES : fem_ns = true; break; case HEAT_EQUATION_FVM: heat_fvm = true; break; case FEM_ELASTICITY: case DISC_ADJ_FEM: fem = true; break; - case ADJ_EULER : euler = true; adj_euler = true; break; - case ADJ_NAVIER_STOKES : ns = true; turbulent = (config->GetKind_Turb_Model() != NONE); adj_ns = true; break; - case ADJ_RANS : ns = true; turbulent = true; adj_ns = true; adj_turb = (!config->GetFrozen_Visc_Cont()); break; + case ADJ_EULER : euler = true; scalar = (config->GetKind_Scalar_Model() != NONE); adj_euler = true; break; + case ADJ_NAVIER_STOKES : ns = true; turbulent = (config->GetKind_Turb_Model() != NONE); scalar = (config->GetKind_Scalar_Model() != NONE); adj_ns = true; break; + case ADJ_RANS : ns = true; turbulent = true; scalar = (config->GetKind_Scalar_Model() != NONE); adj_ns = true; adj_turb = (!config->GetFrozen_Visc_Cont()); break; } /*--- Assign turbulence model booleans ---*/ @@ -2778,6 +2894,16 @@ void CDriver::Numerics_Postprocessing(CNumerics *****numerics, default: SU2_MPI::Error("Specified turbulence model unavailable or none selected", CURRENT_FUNCTION); break; } + /*--- Assign scalar transport model booleans. ---*/ + + if (scalar) { + switch (config->GetKind_Scalar_Model()) { + case PASSIVE_SCALAR: passive_scalar = true; break; + case PROGRESS_VARIABLE: progress_variable = true; break; + default: SU2_MPI::Error("Specified scalar transport model unavailable.", CURRENT_FUNCTION); break; + } + } + /*--- Solver definition for the template problem ---*/ if (template_solver) { @@ -2955,6 +3081,37 @@ void CDriver::Numerics_Postprocessing(CNumerics *****numerics, delete numerics[val_iInst][iMGlevel][TRANS_SOL][CONV_BOUND_TERM]; } } + + /*--- Solver definition for the scalar transport model problem ---*/ + + if (scalar) { + + /*--- Definition of the convective scheme for each equation and mesh level ---*/ + + switch (config->GetKind_ConvNumScheme_Scalar()) { + case SPACE_UPWIND : + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + if (passive_scalar || progress_variable) + delete numerics[val_iInst][iMGlevel][SCALAR_SOL][CONV_TERM]; + } + break; + } + + /*--- Definition of the viscous scheme for each equation and mesh level ---*/ + + if (passive_scalar || progress_variable) { + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + delete numerics[val_iInst][iMGlevel][SCALAR_SOL][VISC_TERM]; + delete numerics[val_iInst][iMGlevel][SCALAR_SOL][SOURCE_FIRST_TERM]; + delete numerics[val_iInst][iMGlevel][SCALAR_SOL][SOURCE_SECOND_TERM]; + /*--- Definition of the boundary condition method ---*/ + delete numerics[val_iInst][iMGlevel][SCALAR_SOL][CONV_BOUND_TERM]; + delete numerics[val_iInst][iMGlevel][SCALAR_SOL][VISC_BOUND_TERM]; + + } + } + + } if (heat_fvm) { @@ -4024,8 +4181,11 @@ void CFluidDriver::Preprocess(unsigned long Iter) { (config_container[iZone]->GetKind_Solver() == INC_EULER) || (config_container[iZone]->GetKind_Solver() == INC_NAVIER_STOKES) || (config_container[iZone]->GetKind_Solver() == INC_RANS)) { - for (iInst = 0; iInst < nInst[iZone]; iInst++) + for (iInst = 0; iInst < nInst[iZone]; iInst++) { solver_container[iZone][iInst][MESH_0][FLOW_SOL]->SetInitialCondition(geometry_container[iZone][INST_0], solver_container[iZone][iInst], config_container[iZone], Iter); + if (config_container[iZone]->GetKind_Scalar_Model() != NO_SCALAR_MODEL) + solver_container[iZone][iInst][MESH_0][SCALAR_SOL]->SetInitialCondition(geometry_container[iZone][INST_0], solver_container[iZone][iInst], config_container[iZone], Iter); + } } } } diff --git a/SU2_CFD/src/fluid_model.cpp b/SU2_CFD/src/fluid_model.cpp index 7806672ec325..57ad148dccca 100644 --- a/SU2_CFD/src/fluid_model.cpp +++ b/SU2_CFD/src/fluid_model.cpp @@ -56,14 +56,16 @@ CFluidModel::CFluidModel(void) { Mu = 0.0; Mu_Turb = 0.0; - LaminarViscosity = NULL; + LaminarViscosity = NULL; ThermalConductivity = NULL; + MassDiffusivity = NULL; } CFluidModel::~CFluidModel(void) { - if (LaminarViscosity!= NULL) delete LaminarViscosity; - if (ThermalConductivity!= NULL) delete ThermalConductivity; + if (LaminarViscosity != NULL) delete LaminarViscosity; + if (ThermalConductivity != NULL) delete ThermalConductivity; + if (MassDiffusivity != NULL) delete MassDiffusivity; } void CFluidModel::SetLaminarViscosityModel (CConfig *config) { @@ -116,3 +118,20 @@ void CFluidModel::SetThermalConductivityModel (CConfig *config) { } +void CFluidModel::SetMassDiffusivityModel (CConfig *config) { + + switch (config->GetKind_DiffusivityModel()) { + case CONSTANT_DIFFUSIVITY: + MassDiffusivity = new CConstantDiffusivity(config->GetDiffusivity_ConstantND()); + break; + case CONSTANT_SCHMIDT: + if ((config->GetKind_Solver() == RANS) || (config->GetKind_Solver() == DISC_ADJ_RANS)) { + MassDiffusivity = new CConstantSchmidtRANS(config->GetSchmidt_Lam(),config->GetSchmidt_Turb()); + } else { + MassDiffusivity = new CConstantSchmidt(config->GetSchmidt_Lam()); + } + break; + } + +} + diff --git a/SU2_CFD/src/integration_structure.cpp b/SU2_CFD/src/integration_structure.cpp index 606c6ca7143a..17c6a5d10883 100644 --- a/SU2_CFD/src/integration_structure.cpp +++ b/SU2_CFD/src/integration_structure.cpp @@ -95,7 +95,7 @@ void CIntegration::Space_Integration(CGeometry *geometry, if (dual_time) solver_container[MainSolver]->SetResidual_DualTime(geometry, solver_container, config, iRKStep, iMesh, RunTime_EqSystem); - /*--- Boundary conditions that depend on other boundaries (they require MPI sincronization)---*/ + /*--- Boundary conditions that depend on other boundaries (they require MPI comms)---*/ solver_container[MainSolver]->BC_Fluid_Interface(geometry, solver_container, numerics[CONV_BOUND_TERM], numerics[VISC_BOUND_TERM], config); diff --git a/SU2_CFD/src/integration_time.cpp b/SU2_CFD/src/integration_time.cpp index 46fd945665ac..1fc5f9f851ed 100644 --- a/SU2_CFD/src/integration_time.cpp +++ b/SU2_CFD/src/integration_time.cpp @@ -117,7 +117,7 @@ void CMultiGridIntegration::MultiGrid_Cycle(CGeometry ****geometry, unsigned short iInst) { unsigned short iPreSmooth, iPostSmooth, iRKStep, iRKLimit = 1; - unsigned short SolContainer_Position = config[iZone]->GetContainerPosition(RunTime_EqSystem); + unsigned short SolContainer_Position = config[iZone]->GetContainerPosition(RunTime_EqSystem); /*--- Do a presmoothing on the grid iMesh to be restricted to the grid iMesh+1 ---*/ diff --git a/SU2_CFD/src/iteration_structure.cpp b/SU2_CFD/src/iteration_structure.cpp index 6a104f1c12fb..b2c7b1b5e1d8 100644 --- a/SU2_CFD/src/iteration_structure.cpp +++ b/SU2_CFD/src/iteration_structure.cpp @@ -579,6 +579,12 @@ void CFluidIteration::Iterate(COutput *output, } } + + if (config[val_iZone]->GetKind_Scalar_Model() != NO_SCALAR_MODEL){ + config[val_iZone]->SetGlobalParam(RANS, RUNTIME_SCALAR_SYS); + integration[val_iZone][val_iInst][SCALAR_SOL]->MultiGrid_Iteration(geometry, solver, numerics, + config, RUNTIME_SCALAR_SYS, val_iZone, val_iInst); + } if (config[val_iZone]->GetWeakly_Coupled_Heat()){ config[val_iZone]->SetGlobalParam(RANS, RUNTIME_HEAT_SYS); @@ -650,6 +656,16 @@ void CFluidIteration::Update(COutput *output, integration[val_iZone][val_iInst][TRANS_SOL]->SetDualTime_Solver(geometry[val_iZone][val_iInst][MESH_0], solver[val_iZone][val_iInst][MESH_0][TRANS_SOL], config[val_iZone], MESH_0); integration[val_iZone][val_iInst][TRANS_SOL]->SetConvergence(false); } + + /*--- Update dual time solver for the scalar transport model ---*/ + + if (config[val_iZone]->GetKind_Scalar_Model() != NO_SCALAR_MODEL) { + for (iMesh = 0; iMesh <= config[val_iZone]->GetnMGLevels(); iMesh++) { + integration[val_iZone][val_iInst][SCALAR_SOL]->SetDualTime_Solver(geometry[val_iZone][val_iInst][iMesh], solver[val_iZone][val_iInst][iMesh][SCALAR_SOL], config[val_iZone], iMesh); + integration[val_iZone][val_iInst][SCALAR_SOL]->SetConvergence(false); + } + } + } } diff --git a/SU2_CFD/src/meson.build b/SU2_CFD/src/meson.build index 298d2d1489b2..af7305999d6a 100644 --- a/SU2_CFD/src/meson.build +++ b/SU2_CFD/src/meson.build @@ -34,6 +34,7 @@ su2_cfd_src = files(['solver_direct_transition.cpp', 'numerics_template.cpp', 'solver_adjoint_discrete.cpp', 'numerics_direct_elasticity_nonlinear.cpp', + 'numerics_direct_scalar.cpp', 'SU2_CFD.cpp']) su2_cfd_src += files(['output/CAdjElasticityOutput.cpp', @@ -69,7 +70,7 @@ su2_cfd_src += files(['output/CAdjElasticityOutput.cpp', su2_cfd_src += files(['variables/CIncNSVariable.cpp', 'variables/CTransLMVariable.cpp', - 'variables/CAdjEulerVariable.cpp', + 'variables/CAdjEulerVariable.cpp', 'variables/CHeatFVMVariable.cpp', 'variables/CTurbVariable.cpp', 'variables/CAdjNSVariable.cpp', @@ -89,9 +90,13 @@ su2_cfd_src += files(['variables/CIncNSVariable.cpp', 'variables/CNSVariable.cpp', 'variables/CAdjTurbVariable.cpp', 'variables/CIncEulerVariable.cpp', - 'variables/CEulerVariable.cpp']) + 'variables/CEulerVariable.cpp', + 'variables/CScalarVariable.cpp', + 'variables/CPassiveScalarVariable.cpp']) su2_cfd_src += files(['solvers/CMeshSolver.cpp', + 'solvers/CScalarSolver.cpp', + 'solvers/CPassiveScalarSolver.cpp', 'solvers/CDiscAdjMeshSolver.cpp']) su2_cfd_src += files(['numerics/CFEAMeshElasticity.cpp']) diff --git a/SU2_CFD/src/numerics_direct_scalar.cpp b/SU2_CFD/src/numerics_direct_scalar.cpp new file mode 100644 index 000000000000..15a627de114e --- /dev/null +++ b/SU2_CFD/src/numerics_direct_scalar.cpp @@ -0,0 +1,391 @@ +/*! + * \file numerics_direct_scalar.cpp + * \brief This file contains the numerical methods for scalar transport eqns. + * \author T. Economon + * \version 6.1.0 "Falcon" + * + * The current SU2 release has been coordinated by the + * SU2 International Developers Society + * with selected contributions from the open-source community. + * + * The main research teams contributing to the current release are: + * - Prof. Juan J. Alonso's group at Stanford University. + * - Prof. Piero Colonna's group at Delft University of Technology. + * - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology. + * - Prof. Alberto Guardone's group at Polytechnic University of Milan. + * - Prof. Rafael Palacios' group at Imperial College London. + * - Prof. Vincent Terrapon's group at the University of Liege. + * - Prof. Edwin van der Weide's group at the University of Twente. + * - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics. + * + * Copyright 2012-2018, Francisco D. Palacios, Thomas D. Economon, + * Tim Albring, and the SU2 contributors. + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#include "../include/numerics_structure.hpp" + +CUpwScalar::CUpwScalar(unsigned short val_nDim, + unsigned short val_nVar, + CConfig *config) +: CNumerics(val_nDim, val_nVar, config) { + + implicit = (config->GetKind_TimeIntScheme_Scalar() == EULER_IMPLICIT); + incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); + grid_movement = config->GetGrid_Movement(); + + Velocity_i = new su2double[nDim]; + Velocity_j = new su2double[nDim]; + +} + +CUpwScalar::~CUpwScalar(void) { + + delete [] Velocity_i; + delete [] Velocity_j; + +} + +void CUpwScalar::ComputeResidual(su2double *val_residual, + su2double **val_Jacobian_i, + su2double **val_Jacobian_j, + CConfig *config) { + + AD::StartPreacc(); + AD::SetPreaccIn(Normal, nDim); + if (grid_movement) { + AD::SetPreaccIn(GridVel_i, nDim); AD::SetPreaccIn(GridVel_j, nDim); + } + + ExtraADPreaccIn(); + + Density_i = V_i[nDim+2]; + Density_j = V_j[nDim+2]; + + q_ij = 0.0; + if (grid_movement) { + for (iDim = 0; iDim < nDim; iDim++) { + Velocity_i[iDim] = V_i[iDim+1] - GridVel_i[iDim]; + Velocity_j[iDim] = V_j[iDim+1] - GridVel_j[iDim]; + q_ij += 0.5*(Velocity_i[iDim]+Velocity_j[iDim])*Normal[iDim]; + } + } + else { + for (iDim = 0; iDim < nDim; iDim++) { + Velocity_i[iDim] = V_i[iDim+1]; + Velocity_j[iDim] = V_j[iDim+1]; + q_ij += 0.5*(Velocity_i[iDim]+Velocity_j[iDim])*Normal[iDim]; + } + } + + a0 = 0.5*(q_ij+fabs(q_ij)); + a1 = 0.5*(q_ij-fabs(q_ij)); + + FinishResidualCalc(val_residual, val_Jacobian_i, val_Jacobian_j, config); + + AD::SetPreaccOut(val_residual, nVar); + AD::EndPreacc(); + +} + +CUpwScalar_General::CUpwScalar_General(unsigned short val_nDim, + unsigned short val_nVar, + CConfig *config) +: CUpwScalar(val_nDim, val_nVar, config) { } + +CUpwScalar_General::~CUpwScalar_General(void) { } + +void CUpwScalar_General::ExtraADPreaccIn() { + AD::SetPreaccIn(ScalarVar_i, nVar); AD::SetPreaccIn(ScalarVar_j, nVar); + AD::SetPreaccIn(V_i, nDim+3); AD::SetPreaccIn(V_j, nDim+3); +} + +void CUpwScalar_General::FinishResidualCalc(su2double *val_residual, + su2double **val_Jacobian_i, + su2double **val_Jacobian_j, + CConfig *config) { + + unsigned short iVar, jVar; + + for (iVar = 0; iVar < nVar; iVar++) { + val_residual[iVar] = (a0*Density_i*ScalarVar_i[iVar] + + a1*Density_j*ScalarVar_j[iVar]); + if (implicit) { + for (jVar = 0; jVar < nVar; jVar++) { + if (iVar == jVar) { + val_Jacobian_i[iVar][jVar] = a0*Density_i; + val_Jacobian_j[iVar][jVar] = a1*Density_j; + } else { + val_Jacobian_i[iVar][jVar] = 0.0; + val_Jacobian_j[iVar][jVar] = 0.0; + } + } + } + } + +} + +CAvgGradScalar::CAvgGradScalar(unsigned short val_nDim, + unsigned short val_nVar, + bool correct_grad, + CConfig *config) +: CNumerics(val_nDim, val_nVar, config), correct_gradient(correct_grad) { + + implicit = (config->GetKind_TimeIntScheme_Scalar() == EULER_IMPLICIT); + incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); + + Edge_Vector = new su2double[nDim]; + + Proj_Mean_GradScalarVar_Normal = new su2double[nVar]; + Proj_Mean_GradScalarVar_Edge = new su2double[nVar]; + Proj_Mean_GradScalarVar = new su2double[nVar]; + + Mean_GradScalarVar = new su2double*[nVar]; + for (iVar = 0; iVar < nVar; iVar++) + Mean_GradScalarVar[iVar] = new su2double[nDim]; + +} + +CAvgGradScalar::~CAvgGradScalar(void) { + + delete [] Edge_Vector; + delete [] Proj_Mean_GradScalarVar_Normal; + delete [] Proj_Mean_GradScalarVar_Edge; + delete [] Proj_Mean_GradScalarVar; + for (iVar = 0; iVar < nVar; iVar++) + delete [] Mean_GradScalarVar[iVar]; + delete [] Mean_GradScalarVar; + +} + +void CAvgGradScalar::ComputeResidual(su2double *val_residual, + su2double **Jacobian_i, + su2double **Jacobian_j, + CConfig *config) { + + AD::StartPreacc(); + AD::SetPreaccIn(Coord_i, nDim); AD::SetPreaccIn(Coord_j, nDim); + AD::SetPreaccIn(Normal, nDim); + AD::SetPreaccIn(ScalarVar_Grad_i, nVar, nDim); + AD::SetPreaccIn(ScalarVar_Grad_j, nVar, nDim); + if (correct_gradient) { + AD::SetPreaccIn(ScalarVar_i, nVar); AD::SetPreaccIn(ScalarVar_j, nVar); + } + ExtraADPreaccIn(); + + if (incompressible) { + AD::SetPreaccIn(V_i, nDim+6); AD::SetPreaccIn(V_j, nDim+6); + + Density_i = V_i[nDim+2]; Density_j = V_j[nDim+2]; + Laminar_Viscosity_i = V_i[nDim+4]; Laminar_Viscosity_j = V_j[nDim+4]; + Eddy_Viscosity_i = V_i[nDim+5]; Eddy_Viscosity_j = V_j[nDim+5]; + } + else { + AD::SetPreaccIn(V_i, nDim+7); AD::SetPreaccIn(V_j, nDim+7); + + Density_i = V_i[nDim+2]; Density_j = V_j[nDim+2]; + Laminar_Viscosity_i = V_i[nDim+5]; Laminar_Viscosity_j = V_j[nDim+5]; + Eddy_Viscosity_i = V_i[nDim+6]; Eddy_Viscosity_j = V_j[nDim+6]; + } + + /*--- Compute vector going from iPoint to jPoint ---*/ + + dist_ij_2 = 0; proj_vector_ij = 0; + for (iDim = 0; iDim < nDim; iDim++) { + Edge_Vector[iDim] = Coord_j[iDim]-Coord_i[iDim]; + dist_ij_2 += Edge_Vector[iDim]*Edge_Vector[iDim]; + proj_vector_ij += Edge_Vector[iDim]*Normal[iDim]; + } + if (dist_ij_2 == 0.0) proj_vector_ij = 0.0; + else proj_vector_ij = proj_vector_ij/dist_ij_2; + + /*--- Mean gradient approximation ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + Proj_Mean_GradScalarVar_Normal[iVar] = 0.0; + Proj_Mean_GradScalarVar_Edge[iVar] = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Mean_GradScalarVar[iVar][iDim] = 0.5*(ScalarVar_Grad_i[iVar][iDim] + + ScalarVar_Grad_j[iVar][iDim]); + Proj_Mean_GradScalarVar_Normal[iVar] += Mean_GradScalarVar[iVar][iDim] * + Normal[iDim]; + if (correct_gradient) + Proj_Mean_GradScalarVar_Edge[iVar] += Mean_GradScalarVar[iVar][iDim]*Edge_Vector[iDim]; + } + Proj_Mean_GradScalarVar[iVar] = Proj_Mean_GradScalarVar_Normal[iVar]; + if (correct_gradient) { + Proj_Mean_GradScalarVar[iVar] -= Proj_Mean_GradScalarVar_Edge[iVar]*proj_vector_ij - + (ScalarVar_j[iVar]-ScalarVar_i[iVar])*proj_vector_ij; + } + } + + FinishResidualCalc(val_residual, Jacobian_i, Jacobian_j, config); + + AD::SetPreaccOut(val_residual, nVar); + AD::EndPreacc(); + +} + +CAvgGradScalar_General::CAvgGradScalar_General(unsigned short val_nDim, + unsigned short val_nVar, bool correct_grad, + CConfig *config) +: CAvgGradScalar(val_nDim, val_nVar, correct_grad, config) { + + Mean_Diffusivity = new su2double[nVar]; + +} + +CAvgGradScalar_General::~CAvgGradScalar_General(void) { + + if (Mean_Diffusivity != NULL) delete [] Mean_Diffusivity; + +} + +void CAvgGradScalar_General::ExtraADPreaccIn() { + AD::SetPreaccIn(Diffusion_Coeff_i, nVar); + AD::SetPreaccIn(Diffusion_Coeff_j, nVar); +} + +void CAvgGradScalar_General::FinishResidualCalc(su2double *val_residual, + su2double **Jacobian_i, + su2double **Jacobian_j, + CConfig *config) { + + unsigned short iVar, jVar; + + for (iVar = 0; iVar < nVar; iVar++) { + + /*--- Get the diffusion coefficient(s). ---*/ + + Mean_Diffusivity[iVar] = 0.5*(Diffusion_Coeff_i[iVar] + Diffusion_Coeff_j[iVar]); + + /*--- Compute the viscous residual. ---*/ + + val_residual[iVar] = Mean_Diffusivity[iVar]*Proj_Mean_GradScalarVar[iVar]; + + /*--- Use TSL approx. to compute derivatives of the gradients. ---*/ + + if (implicit) { + for (jVar = 0; jVar < nVar; jVar++) { + if (iVar == jVar) { + Jacobian_i[iVar][jVar] = -Mean_Diffusivity[iVar]*proj_vector_ij; + Jacobian_j[iVar][jVar] = Mean_Diffusivity[iVar]*proj_vector_ij; + } else { + Jacobian_i[iVar][jVar] = 0.0; + Jacobian_j[iVar][jVar] = 0.0; + } + } + } + + } + +} + +CSourcePieceWise_Scalar::CSourcePieceWise_Scalar(unsigned short val_nDim, + unsigned short val_nVar, + CConfig *config) : +CNumerics(val_nDim, val_nVar, config) { + + implicit = (config->GetKind_TimeIntScheme_Scalar() == EULER_IMPLICIT); + incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); + +} + +CSourcePieceWise_Scalar::~CSourcePieceWise_Scalar(void) { } + +void CSourcePieceWise_Scalar::ComputeResidual(su2double *val_residual, + su2double **val_Jacobian_i, + su2double **val_Jacobian_j, + CConfig *config) { + + unsigned short iVar, jVar; + + Density_i = V_i[nDim+2]; + + for (iVar = 0; iVar < nVar; iVar++) { + val_residual[iVar] = 0.0; + if (implicit) { + for (jVar = 0; jVar < nVar; jVar++) { + val_Jacobian_i[iVar][jVar] = 0.0; + } + } + } + +} + +CSourceAxisymmetric_Scalar::CSourceAxisymmetric_Scalar(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) : CNumerics(val_nDim, val_nVar, config) { + + implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + energy = config->GetEnergy_Equation(); + viscous = config->GetViscous(); + +} + +CSourceAxisymmetric_Scalar::~CSourceAxisymmetric_Scalar(void) { } + +void CSourceAxisymmetric_Scalar::ComputeResidual(su2double *val_residual, su2double **Jacobian_i, CConfig *config) { + + su2double yinv, Velocity_i[3]; + unsigned short iDim, iVar, jVar; + + if (Coord_i[1] > EPS) { + yinv = 1.0/Coord_i[1]; + Density_i = V_i[nDim+2]; + + /*--- Set primitive variables at points iPoint. ---*/ + + for (iDim = 0; iDim < nDim; iDim++) + Velocity_i[iDim] = V_i[iDim+1]; + + /*--- Inviscid component of the source term. ---*/ + + for (iVar=0; iVar < nVar; iVar++) + val_residual[iVar] = yinv*Volume*Density_i*ScalarVar_i[iVar]*Velocity_i[1]; + + if (implicit) { + + for (iVar=0; iVar < nVar; iVar++) { + for (jVar=0; jVar < nVar; jVar++) { + if (iVar == jVar) Jacobian_i[iVar][jVar] = Velocity_i[1]; + Jacobian_i[iVar][jVar] *= yinv*Volume*Density_i; + } + } + + } + + /*--- Add the viscous terms if necessary. ---*/ + + if (viscous) { + + for (iVar=0; iVar < nVar; iVar++) + val_residual[iVar] -= Volume*yinv*Diffusion_Coeff_i[iVar]*ScalarVar_Grad_i[iVar][1]; + + } + + } else { + + for (iVar=0; iVar < nVar; iVar++) + val_residual[iVar] = 0.0; + + if (implicit) { + for (iVar=0; iVar < nVar; iVar++) { + for (jVar=0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = 0.0; + } + } + + } + +} + diff --git a/SU2_CFD/src/numerics_direct_turbulent.cpp b/SU2_CFD/src/numerics_direct_turbulent.cpp index a38b4b80d6e9..061811ec7983 100644 --- a/SU2_CFD/src/numerics_direct_turbulent.cpp +++ b/SU2_CFD/src/numerics_direct_turbulent.cpp @@ -38,72 +38,6 @@ #include "../include/numerics_structure.hpp" #include -CUpwScalar::CUpwScalar(unsigned short val_nDim, - unsigned short val_nVar, - CConfig *config) - : CNumerics(val_nDim, val_nVar, config) { - - implicit = (config->GetKind_TimeIntScheme_Turb() == EULER_IMPLICIT); - incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); - /* A grid is defined as dynamic if there's rigid grid movement or grid deformation AND the problem is time domain */ - dynamic_grid = config->GetDynamic_Grid(); - - Velocity_i = new su2double [nDim]; - Velocity_j = new su2double [nDim]; - -} - -CUpwScalar::~CUpwScalar(void) { - - delete [] Velocity_i; - delete [] Velocity_j; - -} - -void CUpwScalar::ComputeResidual(su2double *val_residual, - su2double **val_Jacobian_i, - su2double **val_Jacobian_j, - CConfig *config) { - - AD::StartPreacc(); - AD::SetPreaccIn(Normal, nDim); - AD::SetPreaccIn(TurbVar_i, nVar); AD::SetPreaccIn(TurbVar_j, nVar); - if (dynamic_grid) { - AD::SetPreaccIn(GridVel_i, nDim); AD::SetPreaccIn(GridVel_j, nDim); - } - - ExtraADPreaccIn(); - - Density_i = V_i[nDim+2]; - Density_j = V_j[nDim+2]; - - q_ij = 0.0; - if (dynamic_grid) { - for (iDim = 0; iDim < nDim; iDim++) { - Velocity_i[iDim] = V_i[iDim+1] - GridVel_i[iDim]; - Velocity_j[iDim] = V_j[iDim+1] - GridVel_j[iDim]; - q_ij += 0.5*(Velocity_i[iDim]+Velocity_j[iDim])*Normal[iDim]; - } - } - else { - for (iDim = 0; iDim < nDim; iDim++) { - Velocity_i[iDim] = V_i[iDim+1]; - Velocity_j[iDim] = V_j[iDim+1]; - q_ij += 0.5*(Velocity_i[iDim]+Velocity_j[iDim])*Normal[iDim]; - } - } - - a0 = 0.5*(q_ij+fabs(q_ij)); - a1 = 0.5*(q_ij-fabs(q_ij)); - - FinishResidualCalc(val_residual, val_Jacobian_i, val_Jacobian_j, config); - - - AD::SetPreaccOut(val_residual, nVar); - AD::EndPreacc(); - -} - CUpwSca_TurbSA::CUpwSca_TurbSA(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) @@ -114,6 +48,7 @@ CUpwSca_TurbSA::~CUpwSca_TurbSA(void) { } void CUpwSca_TurbSA::ExtraADPreaccIn() { + AD::SetPreaccIn(TurbVar_i, nVar); AD::SetPreaccIn(TurbVar_j, nVar); AD::SetPreaccIn(V_i, nDim+1); AD::SetPreaccIn(V_j, nDim+1); } @@ -127,108 +62,10 @@ void CUpwSca_TurbSA::FinishResidualCalc(su2double *val_residual, su2double **val } } -CAvgGrad_Scalar::CAvgGrad_Scalar(unsigned short val_nDim, - unsigned short val_nVar, - bool correct_grad, - CConfig *config) - : CNumerics(val_nDim, val_nVar, config), correct_gradient(correct_grad) { - - implicit = (config->GetKind_TimeIntScheme_Turb() == EULER_IMPLICIT); - incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); - - Edge_Vector = new su2double [nDim]; - Proj_Mean_GradTurbVar_Normal = new su2double [nVar]; - Proj_Mean_GradTurbVar_Edge = new su2double [nVar]; - Proj_Mean_GradTurbVar = new su2double [nVar]; - Mean_GradTurbVar = new su2double* [nVar]; - for (iVar = 0; iVar < nVar; iVar++) - Mean_GradTurbVar[iVar] = new su2double [nDim]; - -} - -CAvgGrad_Scalar::~CAvgGrad_Scalar(void) { - - delete [] Edge_Vector; - delete [] Proj_Mean_GradTurbVar_Normal; - delete [] Proj_Mean_GradTurbVar_Edge; - delete [] Proj_Mean_GradTurbVar; - for (iVar = 0; iVar < nVar; iVar++) - delete [] Mean_GradTurbVar[iVar]; - delete [] Mean_GradTurbVar; - -} - -void CAvgGrad_Scalar::ComputeResidual(su2double *val_residual, - su2double **Jacobian_i, - su2double **Jacobian_j, - CConfig *config) { - - AD::StartPreacc(); - AD::SetPreaccIn(Coord_i, nDim); AD::SetPreaccIn(Coord_j, nDim); - AD::SetPreaccIn(Normal, nDim); - AD::SetPreaccIn(TurbVar_Grad_i, nVar, nDim); - AD::SetPreaccIn(TurbVar_Grad_j, nVar, nDim); - if (correct_gradient) { - AD::SetPreaccIn(TurbVar_i, nVar); AD::SetPreaccIn(TurbVar_j ,nVar); - } - ExtraADPreaccIn(); - - if (incompressible) { - AD::SetPreaccIn(V_i, nDim+6); AD::SetPreaccIn(V_j, nDim+6); - - Density_i = V_i[nDim+2]; Density_j = V_j[nDim+2]; - Laminar_Viscosity_i = V_i[nDim+4]; Laminar_Viscosity_j = V_j[nDim+4]; - Eddy_Viscosity_i = V_i[nDim+5]; Eddy_Viscosity_j = V_j[nDim+5]; - } - else { - AD::SetPreaccIn(V_i, nDim+7); AD::SetPreaccIn(V_j, nDim+7); - - Density_i = V_i[nDim+2]; Density_j = V_j[nDim+2]; - Laminar_Viscosity_i = V_i[nDim+5]; Laminar_Viscosity_j = V_j[nDim+5]; - Eddy_Viscosity_i = V_i[nDim+6]; Eddy_Viscosity_j = V_j[nDim+6]; - } - - /*--- Compute vector going from iPoint to jPoint ---*/ - - dist_ij_2 = 0; proj_vector_ij = 0; - for (iDim = 0; iDim < nDim; iDim++) { - Edge_Vector[iDim] = Coord_j[iDim]-Coord_i[iDim]; - dist_ij_2 += Edge_Vector[iDim]*Edge_Vector[iDim]; - proj_vector_ij += Edge_Vector[iDim]*Normal[iDim]; - } - if (dist_ij_2 == 0.0) proj_vector_ij = 0.0; - else proj_vector_ij = proj_vector_ij/dist_ij_2; - - /*--- Mean gradient approximation ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - Proj_Mean_GradTurbVar_Normal[iVar] = 0.0; - Proj_Mean_GradTurbVar_Edge[iVar] = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - Mean_GradTurbVar[iVar][iDim] = 0.5*(TurbVar_Grad_i[iVar][iDim] + - TurbVar_Grad_j[iVar][iDim]); - Proj_Mean_GradTurbVar_Normal[iVar] += Mean_GradTurbVar[iVar][iDim] * - Normal[iDim]; - if (correct_gradient) - Proj_Mean_GradTurbVar_Edge[iVar] += Mean_GradTurbVar[iVar][iDim]*Edge_Vector[iDim]; - } - Proj_Mean_GradTurbVar[iVar] = Proj_Mean_GradTurbVar_Normal[iVar]; - if (correct_gradient) { - Proj_Mean_GradTurbVar[iVar] -= Proj_Mean_GradTurbVar_Edge[iVar]*proj_vector_ij - - (TurbVar_j[iVar]-TurbVar_i[iVar])*proj_vector_ij; - } - } - - FinishResidualCalc(val_residual, Jacobian_i, Jacobian_j, config); - - AD::SetPreaccOut(val_residual, nVar); - AD::EndPreacc(); - -} - CAvgGrad_TurbSA::CAvgGrad_TurbSA(unsigned short val_nDim, unsigned short val_nVar, bool correct_grad, CConfig *config) - : CAvgGrad_Scalar(val_nDim, val_nVar, correct_grad, config), sigma(2./3.) { + : CAvgGradScalar(val_nDim, val_nVar, correct_grad, config), sigma(2./3.) { } CAvgGrad_TurbSA::~CAvgGrad_TurbSA(void) { @@ -243,15 +80,15 @@ void CAvgGrad_TurbSA::FinishResidualCalc(su2double *val_residual, su2double **Ja nu_i = Laminar_Viscosity_i/Density_i; nu_j = Laminar_Viscosity_j/Density_j; - nu_e = 0.5*(nu_i+nu_j+TurbVar_i[0]+TurbVar_j[0]); + nu_e = 0.5*(nu_i+nu_j+ScalarVar_i[0]+ScalarVar_j[0]); - val_residual[0] = nu_e*Proj_Mean_GradTurbVar[0]/sigma; + val_residual[0] = nu_e*Proj_Mean_GradScalarVar[0]/sigma; /*--- For Jacobians -> Use of TSL approx. to compute derivatives of the gradients ---*/ if (implicit) { - Jacobian_i[0][0] = (0.5*Proj_Mean_GradTurbVar[0]-nu_e*proj_vector_ij)/sigma; - Jacobian_j[0][0] = (0.5*Proj_Mean_GradTurbVar[0]+nu_e*proj_vector_ij)/sigma; + Jacobian_i[0][0] = (0.5*Proj_Mean_GradScalarVar[0]-nu_e*proj_vector_ij)/sigma; + Jacobian_j[0][0] = (0.5*Proj_Mean_GradScalarVar[0]+nu_e*proj_vector_ij)/sigma; } } @@ -260,7 +97,7 @@ CAvgGrad_TurbSA_Neg::CAvgGrad_TurbSA_Neg(unsigned short val_nDim, unsigned short val_nVar, bool correct_grad, CConfig *config) - : CAvgGrad_Scalar(val_nDim, val_nVar, correct_grad, config), + : CAvgGradScalar(val_nDim, val_nVar, correct_grad, config), sigma(2./3.), cn1(16.0), fn(0.0) { } @@ -281,7 +118,7 @@ void CAvgGrad_TurbSA_Neg::FinishResidualCalc(su2double *val_residual, nu_j = Laminar_Viscosity_j/Density_j; nu_ij = 0.5*(nu_i+nu_j); - nu_tilde_ij = 0.5*(TurbVar_i[0]+TurbVar_j[0]); + nu_tilde_ij = 0.5*(ScalarVar_i[0]+ScalarVar_j[0]); Xi = nu_tilde_ij/nu_ij; @@ -293,13 +130,13 @@ void CAvgGrad_TurbSA_Neg::FinishResidualCalc(su2double *val_residual, nu_e = nu_ij + fn*nu_tilde_ij; } - val_residual[0] = nu_e*Proj_Mean_GradTurbVar_Normal[0]/sigma; + val_residual[0] = nu_e*Proj_Mean_GradScalarVar_Normal[0]/sigma; /*--- For Jacobians -> Use of TSL approx. to compute derivatives of the gradients ---*/ if (implicit) { - Jacobian_i[0][0] = (0.5*Proj_Mean_GradTurbVar[0]-nu_e*proj_vector_ij)/sigma; - Jacobian_j[0][0] = (0.5*Proj_Mean_GradTurbVar[0]+nu_e*proj_vector_ij)/sigma; + Jacobian_i[0][0] = (0.5*Proj_Mean_GradScalarVar[0]-nu_e*proj_vector_ij)/sigma; + Jacobian_j[0][0] = (0.5*Proj_Mean_GradScalarVar[0]+nu_e*proj_vector_ij)/sigma; } } @@ -1089,7 +926,7 @@ CUpwSca_TurbSST::~CUpwSca_TurbSST(void) { } void CUpwSca_TurbSST::ExtraADPreaccIn() { - + AD::SetPreaccIn(TurbVar_i, nVar); AD::SetPreaccIn(TurbVar_j, nVar); AD::SetPreaccIn(V_i, nDim+3); AD::SetPreaccIn(V_j, nDim+3); @@ -1116,7 +953,7 @@ CAvgGrad_TurbSST::CAvgGrad_TurbSST(unsigned short val_nDim, unsigned short val_nVar, su2double *constants, bool correct_grad, CConfig *config) - : CAvgGrad_Scalar(val_nDim, val_nVar, correct_grad, config) { + : CAvgGradScalar(val_nDim, val_nVar, correct_grad, config) { sigma_k1 = constants[0]; sigma_om1 = constants[2]; @@ -1156,8 +993,8 @@ void CAvgGrad_TurbSST::FinishResidualCalc(su2double *val_residual, su2double **J diff_kine = 0.5*(diff_i_kine + diff_j_kine); // Could instead use weighted average! diff_omega = 0.5*(diff_i_omega + diff_j_omega); - val_residual[0] = diff_kine*Proj_Mean_GradTurbVar[0]; - val_residual[1] = diff_omega*Proj_Mean_GradTurbVar[1]; + val_residual[0] = diff_kine*Proj_Mean_GradScalarVar[0]; + val_residual[1] = diff_omega*Proj_Mean_GradScalarVar[1]; /*--- For Jacobians -> Use of TSL approx. to compute derivatives of the gradients ---*/ if (implicit) { diff --git a/SU2_CFD/src/numerics_structure.cpp b/SU2_CFD/src/numerics_structure.cpp index c1700c085199..3ce59d8843cc 100644 --- a/SU2_CFD/src/numerics_structure.cpp +++ b/SU2_CFD/src/numerics_structure.cpp @@ -248,8 +248,6 @@ CNumerics::~CNumerics(void) { delete [] delta3; } - if (Diffusion_Coeff_i != NULL) delete [] Diffusion_Coeff_i; - if (Diffusion_Coeff_j != NULL) delete [] Diffusion_Coeff_j; if (Vector != NULL) delete [] Vector; if(Enthalpy_formation != NULL) delete [] Enthalpy_formation; diff --git a/SU2_CFD/src/output/CFlowCompOutput.cpp b/SU2_CFD/src/output/CFlowCompOutput.cpp index 1e62fd4926f7..ff9b53e7faf0 100644 --- a/SU2_CFD/src/output/CFlowCompOutput.cpp +++ b/SU2_CFD/src/output/CFlowCompOutput.cpp @@ -43,6 +43,7 @@ CFlowCompOutput::CFlowCompOutput(CConfig *config, unsigned short nDim) : CFlowOutput(config, nDim, false) { turb_model = config->GetKind_Turb_Model(); + scalar_model = config->GetKind_Scalar_Model(); lastInnerIter = curInnerIter; gridMovement = config->GetGrid_Movement(); @@ -138,6 +139,13 @@ void CFlowCompOutput::SetHistoryOutputFields(CConfig *config){ break; default: break; } + + switch(scalar_model){ + case PASSIVE_SCALAR: + AddHistoryOutput("RMS_PASSIVE_SCALAR", "rms[c]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean squared residual of the passive scalar equation.", HistoryFieldType::RESIDUAL); + break; + default: break; + } /// END_GROUP /// BEGIN_GROUP: MAX_RES, DESCRIPTION: The maximum residuals of the SOLUTION variables. @@ -165,6 +173,13 @@ void CFlowCompOutput::SetHistoryOutputFields(CConfig *config){ break; default: break; } + + switch(scalar_model){ + case PASSIVE_SCALAR: + AddHistoryOutput("MAX_PASSIVE_SCALAR", "max[c]", ScreenOutputFormat::FIXED, "MAX_RES", "Maximum residual of the passive scalar equation.", HistoryFieldType::RESIDUAL); + break; + default: break; + } /// END_GROUP /// BEGIN_GROUP: BGS_RES, DESCRIPTION: The block Gauss Seidel residuals of the SOLUTION variables. @@ -192,6 +207,13 @@ void CFlowCompOutput::SetHistoryOutputFields(CConfig *config){ break; default: break; } + + switch(scalar_model){ + case PASSIVE_SCALAR: + AddHistoryOutput("BGS_PASSIVE_SCALAR", "bgs[c]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the passive scalar equation.", HistoryFieldType::RESIDUAL); + break; + default: break; + } /// END_GROUP vector Marker_Monitoring; @@ -314,6 +336,14 @@ void CFlowCompOutput::SetVolumeOutputFields(CConfig *config){ break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + AddVolumeOutput("PASSIVE_SCALAR", "Passive_Scalar", "SOLUTION", "Passive scalar solution"); + break; + case NO_SCALAR_MODEL: + break; + } + // Grid velocity if (config->GetGrid_Movement()){ AddVolumeOutput("GRID_VELOCITY-X", "Grid_Velocity_x", "GRID_VELOCITY", "x-component of the grid velocity vector"); @@ -370,6 +400,14 @@ void CFlowCompOutput::SetVolumeOutputFields(CConfig *config){ break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + AddVolumeOutput("RES_PASSIVE_SCALAR", "Residual_Passive_Scalar", "RESIDUAL", "Residual of passive scalar equation"); + break; + case NO_SCALAR_MODEL: + break; + } + // Limiter values AddVolumeOutput("LIMITER_DENSITY", "Limiter_Density", "LIMITER", "Limiter value of the density"); AddVolumeOutput("LIMITER_MOMENTUM-X", "Limiter_Momentum_x", "LIMITER", "Limiter value of the x-momentum"); @@ -391,6 +429,13 @@ void CFlowCompOutput::SetVolumeOutputFields(CConfig *config){ break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + AddVolumeOutput("LIMITER_PASSIVE_SCALAR", "Limiter_Passive_Scalar", "LIMITER", "Limiter value for the passive scalar"); + break; + case NO_SCALAR_MODEL: + break; + } // Hybrid RANS-LES if (config->GetKind_HybridRANSLES() != NO_HYBRIDRANSLES){ @@ -419,12 +464,16 @@ void CFlowCompOutput::SetVolumeOutputFields(CConfig *config){ void CFlowCompOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolver **solver, unsigned long iPoint){ - CVariable* Node_Flow = solver[FLOW_SOL]->GetNodes(); - CVariable* Node_Turb = NULL; - + CVariable* Node_Flow = solver[FLOW_SOL]->GetNodes(); + CVariable* Node_Turb = NULL; + CVariable* Node_Scalar = NULL; + if (config->GetKind_Turb_Model() != NONE){ Node_Turb = solver[TURB_SOL]->GetNodes(); } + if (config->GetKind_Scalar_Model() != NONE){ + Node_Scalar = solver[SCALAR_SOL]->GetNodes(); + } CPoint* Node_Geo = geometry->node[iPoint]; @@ -457,6 +506,14 @@ void CFlowCompOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolv break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + SetVolumeOutputValue("PASSIVE_SCALAR", iPoint, Node_Scalar->GetSolution(iPoint, 0)); + break; + case NO_SCALAR_MODEL: + break; + } + if (config->GetGrid_Movement()){ SetVolumeOutputValue("GRID_VELOCITY-X", iPoint, Node_Geo->GetGridVel()[0]); SetVolumeOutputValue("GRID_VELOCITY-Y", iPoint, Node_Geo->GetGridVel()[1]); @@ -510,6 +567,14 @@ void CFlowCompOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolv break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + SetVolumeOutputValue("RES_PASSIVE_SCALAR", iPoint, solver[SCALAR_SOL]->LinSysRes.GetBlock(iPoint, 0)); + break; + case NO_SCALAR_MODEL: + break; + } + SetVolumeOutputValue("LIMITER_DENSITY", iPoint, Node_Flow->GetLimiter_Primitive(iPoint, 0)); SetVolumeOutputValue("LIMITER_MOMENTUM-X", iPoint, Node_Flow->GetLimiter_Primitive(iPoint, 1)); SetVolumeOutputValue("LIMITER_MOMENTUM-Y", iPoint, Node_Flow->GetLimiter_Primitive(iPoint, 2)); @@ -533,6 +598,14 @@ void CFlowCompOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolv break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + SetVolumeOutputValue("LIMITER_PASSIVE_SCALAR", iPoint, Node_Scalar->GetLimiter(iPoint, 0)); + break; + case NO_SCALAR_MODEL: + break; + } + if (config->GetKind_HybridRANSLES() != NO_HYBRIDRANSLES){ SetVolumeOutputValue("DES_LENGTHSCALE", iPoint, Node_Flow->GetDES_LengthScale(iPoint)); SetVolumeOutputValue("WALL_DISTANCE", iPoint, Node_Geo->GetWall_Distance()); @@ -571,10 +644,11 @@ void CFlowCompOutput::LoadSurfaceData(CConfig *config, CGeometry *geometry, CSol void CFlowCompOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolver **solver) { - CSolver* flow_solver = solver[FLOW_SOL]; - CSolver* turb_solver = solver[TURB_SOL]; - CSolver* mesh_solver = solver[MESH_SOL]; - + CSolver* flow_solver = solver[FLOW_SOL]; + CSolver* turb_solver = solver[TURB_SOL]; + CSolver* mesh_solver = solver[MESH_SOL]; + CSolver* scalar_solver = solver[SCALAR_SOL]; + SetHistoryOutputValue("RMS_DENSITY", log10(flow_solver->GetRes_RMS(0))); SetHistoryOutputValue("RMS_MOMENTUM-X", log10(flow_solver->GetRes_RMS(1))); SetHistoryOutputValue("RMS_MOMENTUM-Y", log10(flow_solver->GetRes_RMS(2))); @@ -596,6 +670,12 @@ void CFlowCompOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSol default: break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + SetHistoryOutputValue("RMS_PASSIVE_SCALAR", log10(scalar_solver->GetRes_RMS(0))); + break; + } + SetHistoryOutputValue("MAX_DENSITY", log10(flow_solver->GetRes_Max(0))); SetHistoryOutputValue("MAX_MOMENTUM-X", log10(flow_solver->GetRes_Max(1))); SetHistoryOutputValue("MAX_MOMENTUM-Y", log10(flow_solver->GetRes_Max(2))); @@ -617,6 +697,12 @@ void CFlowCompOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSol default: break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + SetHistoryOutputValue("MAX_PASSIVE_SCALAR", log10(scalar_solver->GetRes_Max(0))); + break; + } + if (multiZone){ SetHistoryOutputValue("BGS_DENSITY", log10(flow_solver->GetRes_BGS(0))); SetHistoryOutputValue("BGS_MOMENTUM-X", log10(flow_solver->GetRes_BGS(1))); @@ -628,7 +714,6 @@ void CFlowCompOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSol SetHistoryOutputValue("BGS_ENERGY", log10(flow_solver->GetRes_BGS(4))); } - switch(turb_model){ case SA: case SA_NEG: case SA_E: case SA_COMP: case SA_E_COMP: SetHistoryOutputValue("BGS_NU_TILDE", log10(turb_solver->GetRes_BGS(0))); @@ -639,6 +724,12 @@ void CFlowCompOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSol break; default: break; } + + switch(scalar_model){ + case PASSIVE_SCALAR: + SetHistoryOutputValue("BGS_PASSIVE_SCALAR", log10(scalar_solver->GetRes_BGS(0))); + break; + } } SetHistoryOutputValue("HEATFLUX", flow_solver->GetTotal_HeatFlux()); diff --git a/SU2_CFD/src/output/CFlowIncOutput.cpp b/SU2_CFD/src/output/CFlowIncOutput.cpp index f0372aac2ada..d777a5bba6ec 100644 --- a/SU2_CFD/src/output/CFlowIncOutput.cpp +++ b/SU2_CFD/src/output/CFlowIncOutput.cpp @@ -43,9 +43,8 @@ CFlowIncOutput::CFlowIncOutput(CConfig *config, unsigned short nDim) : CFlowOutput(config, nDim, false) { turb_model = config->GetKind_Turb_Model(); - + scalar_model = config->GetKind_Scalar_Model(); heat = config->GetEnergy_Equation(); - weakly_coupled_heat = config->GetWeakly_Coupled_Heat(); /*--- Set the default history fields if nothing is set in the config file ---*/ @@ -92,7 +91,6 @@ CFlowIncOutput::CFlowIncOutput(CConfig *config, unsigned short nDim) : CFlowOutp if (convFields.empty() ) convFields.emplace_back("RMS_PRESSURE"); - } CFlowIncOutput::~CFlowIncOutput(void) {} @@ -125,6 +123,13 @@ void CFlowIncOutput::SetHistoryOutputFields(CConfig *config){ break; default: break; } + + switch(scalar_model){ + case PASSIVE_SCALAR: + AddHistoryOutput("RMS_PASSIVE_SCALAR", "rms[c]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean squared residual of the passive scalar equation.", HistoryFieldType::RESIDUAL); + break; + default: break; + } /// END_GROUP /// BEGIN_GROUP: MAX_RES, DESCRIPTION: The maximum residuals of the SOLUTION variables. @@ -154,6 +159,13 @@ void CFlowIncOutput::SetHistoryOutputFields(CConfig *config){ break; default: break; } + + switch(scalar_model){ + case PASSIVE_SCALAR: + AddHistoryOutput("MAX_PASSIVE_SCALAR", "max[c]", ScreenOutputFormat::FIXED, "MAX_RES", "Maximum residual of the passive scalar equation.", HistoryFieldType::RESIDUAL); + break; + default: break; + } /// END_GROUP /// BEGIN_GROUP: BGS_RES, DESCRIPTION: The block-gauss seidel residuals of the SOLUTION variables. @@ -183,6 +195,13 @@ void CFlowIncOutput::SetHistoryOutputFields(CConfig *config){ break; default: break; } + + switch(scalar_model){ + case PASSIVE_SCALAR: + AddHistoryOutput("BGS_PASSIVE_SCALAR", "bgs[c]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the passive scalar equation.", HistoryFieldType::RESIDUAL); + break; + default: break; + } /// END_GROUP /// BEGIN_GROUP: HEAT_COEFF, DESCRIPTION: Heat coefficients on all surfaces set with MARKER_MONITORING. @@ -220,11 +239,12 @@ void CFlowIncOutput::SetHistoryOutputFields(CConfig *config){ void CFlowIncOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolver **solver) { - CSolver* flow_solver = solver[FLOW_SOL]; - CSolver* turb_solver = solver[TURB_SOL]; - CSolver* heat_solver = solver[HEAT_SOL]; - CSolver* mesh_solver = solver[MESH_SOL]; - + CSolver* flow_solver = solver[FLOW_SOL]; + CSolver* turb_solver = solver[TURB_SOL]; + CSolver* heat_solver = solver[HEAT_SOL]; + CSolver* mesh_solver = solver[MESH_SOL]; + CSolver* scalar_solver = solver[SCALAR_SOL]; + SetHistoryOutputValue("RMS_PRESSURE", log10(flow_solver->GetRes_RMS(0))); SetHistoryOutputValue("RMS_VELOCITY-X", log10(flow_solver->GetRes_RMS(1))); SetHistoryOutputValue("RMS_VELOCITY-Y", log10(flow_solver->GetRes_RMS(2))); @@ -240,6 +260,12 @@ void CFlowIncOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolv break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + SetHistoryOutputValue("RMS_PASSIVE_SCALAR", log10(scalar_solver->GetRes_RMS(0))); + break; + } + SetHistoryOutputValue("MAX_PRESSURE", log10(flow_solver->GetRes_Max(0))); SetHistoryOutputValue("MAX_VELOCITY-X", log10(flow_solver->GetRes_Max(1))); SetHistoryOutputValue("MAX_VELOCITY-Y", log10(flow_solver->GetRes_Max(2))); @@ -255,6 +281,12 @@ void CFlowIncOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolv break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + SetHistoryOutputValue("MAX_PASSIVE_SCALAR", log10(scalar_solver->GetRes_Max(0))); + break; + } + if (multiZone){ SetHistoryOutputValue("BGS_PRESSURE", log10(flow_solver->GetRes_BGS(0))); SetHistoryOutputValue("BGS_VELOCITY-X", log10(flow_solver->GetRes_BGS(1))); @@ -270,6 +302,12 @@ void CFlowIncOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolv SetHistoryOutputValue("BGS_DISSIPATION", log10(turb_solver->GetRes_BGS(1))); break; } + + switch(scalar_model){ + case PASSIVE_SCALAR: + SetHistoryOutputValue("BGS_PASSIVE_SCALAR", log10(scalar_solver->GetRes_BGS(0))); + break; + } } if (weakly_coupled_heat){ @@ -337,7 +375,7 @@ void CFlowIncOutput::SetVolumeOutputFields(CConfig *config){ if (heat || weakly_coupled_heat) AddVolumeOutput("TEMPERATURE", "Temperature","SOLUTION", "Temperature"); - switch(config->GetKind_Turb_Model()){ + switch(turb_model){ case SST: case SST_SUST: AddVolumeOutput("TKE", "Turb_Kin_Energy", "SOLUTION", "Turbulent kinetic energy"); AddVolumeOutput("DISSIPATION", "Omega", "SOLUTION", "Rate of dissipation"); @@ -350,6 +388,14 @@ void CFlowIncOutput::SetVolumeOutputFields(CConfig *config){ break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + AddVolumeOutput("PASSIVE_SCALAR", "Passive_Scalar", "SOLUTION", "Passive scalar solution"); + break; + case NO_SCALAR_MODEL: + break; + } + // Grid velocity if (config->GetGrid_Movement()){ AddVolumeOutput("GRID_VELOCITY-X", "Grid_Velocity_x", "GRID_VELOCITY", "x-component of the grid velocity vector"); @@ -391,7 +437,7 @@ void CFlowIncOutput::SetVolumeOutputFields(CConfig *config){ AddVolumeOutput("RES_VELOCITY-Z", "Residual_Velocity_z", "RESIDUAL", "Residual of the z-velocity component"); AddVolumeOutput("RES_TEMPERATURE", "Residual_Temperature", "RESIDUAL", "Residual of the temperature"); - switch(config->GetKind_Turb_Model()){ + switch(turb_model){ case SST: case SST_SUST: AddVolumeOutput("RES_TKE", "Residual_TKE", "RESIDUAL", "Residual of turbulent kinetic energy"); AddVolumeOutput("RES_DISSIPATION", "Residual_Omega", "RESIDUAL", "Residual of the rate of dissipation."); @@ -404,6 +450,14 @@ void CFlowIncOutput::SetVolumeOutputFields(CConfig *config){ break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + AddVolumeOutput("RES_PASSIVE_SCALAR", "Residual_Passive_Scalar", "RESIDUAL", "Residual of passive scalar equation"); + break; + case NO_SCALAR_MODEL: + break; + } + // Limiter values AddVolumeOutput("LIMITER_PRESSURE", "Limiter_Pressure", "LIMITER", "Limiter value of the pressure"); AddVolumeOutput("LIMITER_VELOCITY-X", "Limiter_Velocity_x", "LIMITER", "Limiter value of the x-velocity"); @@ -412,7 +466,7 @@ void CFlowIncOutput::SetVolumeOutputFields(CConfig *config){ AddVolumeOutput("LIMITER_VELOCITY-Z", "Limiter_Velocity_z", "LIMITER", "Limiter value of the z-velocity"); AddVolumeOutput("LIMITER_TEMPERATURE", "Limiter_Temperature", "LIMITER", "Limiter value of the temperature"); - switch(config->GetKind_Turb_Model()){ + switch(turb_model){ case SST: case SST_SUST: AddVolumeOutput("LIMITER_TKE", "Limiter_TKE", "LIMITER", "Limiter value of turb. kinetic energy."); AddVolumeOutput("LIMITER_DISSIPATION", "Limiter_Omega", "LIMITER", "Limiter value of dissipation rate."); @@ -425,6 +479,14 @@ void CFlowIncOutput::SetVolumeOutputFields(CConfig *config){ break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + AddVolumeOutput("LIMITER_PASSIVE_SCALAR", "Limiter_Passive_Scalar", "LIMITER", "Limiter value for the passive scalar"); + break; + case NO_SCALAR_MODEL: + break; + } + // Hybrid RANS-LES if (config->GetKind_HybridRANSLES() != NO_HYBRIDRANSLES){ AddVolumeOutput("DES_LENGTHSCALE", "DES_LengthScale", "DDES", "DES length scale value"); @@ -448,9 +510,10 @@ void CFlowIncOutput::SetVolumeOutputFields(CConfig *config){ void CFlowIncOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolver **solver, unsigned long iPoint){ - CVariable* Node_Flow = solver[FLOW_SOL]->GetNodes(); - CVariable* Node_Heat = NULL; - CVariable* Node_Turb = NULL; + CVariable* Node_Flow = solver[FLOW_SOL]->GetNodes(); + CVariable* Node_Heat = NULL; + CVariable* Node_Turb = NULL; + CVariable* Node_Scalar = NULL; if (config->GetKind_Turb_Model() != NONE){ Node_Turb = solver[TURB_SOL]->GetNodes(); @@ -458,6 +521,9 @@ void CFlowIncOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolve if (weakly_coupled_heat){ Node_Heat = solver[HEAT_SOL]->GetNodes(); } + if (config->GetKind_Scalar_Model() != NONE){ + Node_Scalar = solver[SCALAR_SOL]->GetNodes(); + } CPoint* Node_Geo = geometry->node[iPoint]; @@ -490,6 +556,14 @@ void CFlowIncOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolve break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + SetVolumeOutputValue("PASSIVE_SCALAR", iPoint, Node_Scalar->GetSolution(iPoint, 0)); + break; + case NO_SCALAR_MODEL: + break; + } + if (config->GetGrid_Movement()){ SetVolumeOutputValue("GRID_VELOCITY-X", iPoint, Node_Geo->GetGridVel()[0]); SetVolumeOutputValue("GRID_VELOCITY-Y", iPoint, Node_Geo->GetGridVel()[1]); @@ -540,6 +614,14 @@ void CFlowIncOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolve break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + SetVolumeOutputValue("RES_PASSIVE_SCALAR", iPoint, solver[SCALAR_SOL]->LinSysRes.GetBlock(iPoint, 0)); + break; + case NO_SCALAR_MODEL: + break; + } + SetVolumeOutputValue("LIMITER_PRESSURE", iPoint, Node_Flow->GetLimiter_Primitive(iPoint, 0)); SetVolumeOutputValue("LIMITER_VELOCITY-X", iPoint, Node_Flow->GetLimiter_Primitive(iPoint, 1)); SetVolumeOutputValue("LIMITER_VELOCITY-Y", iPoint, Node_Flow->GetLimiter_Primitive(iPoint, 2)); @@ -563,6 +645,14 @@ void CFlowIncOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolve break; } + switch(scalar_model){ + case PASSIVE_SCALAR: + SetVolumeOutputValue("LIMITER_PASSIVE_SCALAR", iPoint, Node_Scalar->GetLimiter(iPoint, 0)); + break; + case NO_SCALAR_MODEL: + break; + } + if (config->GetKind_HybridRANSLES() != NO_HYBRIDRANSLES){ SetVolumeOutputValue("DES_LENGTHSCALE", iPoint, Node_Flow->GetDES_LengthScale(iPoint)); SetVolumeOutputValue("WALL_DISTANCE", iPoint, Node_Geo->GetWall_Distance()); diff --git a/SU2_CFD/src/output/output_structure_legacy.cpp b/SU2_CFD/src/output/output_structure_legacy.cpp index 050bec05079b..2ffe1846ddde 100644 --- a/SU2_CFD/src/output/output_structure_legacy.cpp +++ b/SU2_CFD/src/output/output_structure_legacy.cpp @@ -4343,7 +4343,7 @@ void COutputLegacy::DeallocateSolution(CConfig *config, CGeometry *geometry) { } void COutputLegacy::SetConvHistory_Header(ofstream *ConvHist_file, CConfig *config, unsigned short val_iZone, unsigned short val_iInst) { - char cstr[200], buffer[50], turb_resid[1000], adj_turb_resid[1000]; + char cstr[200], buffer[50], turb_resid[1000], adj_turb_resid[1000], scalar_resid[1000]; unsigned short iMarker_Monitoring; string Monitoring_Tag, monitoring_coeff, aeroelastic_coeff, turbo_coeff; @@ -4356,6 +4356,7 @@ void COutputLegacy::SetConvHistory_Header(ofstream *ConvHist_file, CConfig *conf bool turbulent = ((config->GetKind_Solver() == RANS) || (config->GetKind_Solver() == ADJ_RANS) || (config->GetKind_Solver() == DISC_ADJ_RANS) || (config->GetKind_Solver() == DISC_ADJ_INC_RANS) || (config->GetKind_Solver() == INC_RANS)); + bool scalar = (config->GetKind_Scalar_Model() != NO_SCALAR_MODEL); bool cont_adj = config->GetContinuous_Adjoint(); bool disc_adj = config->GetDiscrete_Adjoint(); bool frozen_visc = (cont_adj && config->GetFrozen_Visc_Cont()) ||( disc_adj && config->GetFrozen_Visc_Disc()); @@ -4495,6 +4496,11 @@ void COutputLegacy::SetConvHistory_Header(ofstream *ConvHist_file, CConfig *conf SPRINTF (turb_resid, ",\"Res_Turb[0]\",\"Res_Turb[1]\""); break; } + switch (config->GetKind_Scalar_Model()) { + case PASSIVE_SCALAR: case PROGRESS_VARIABLE: + SPRINTF (scalar_resid, ",\"Res_Scalar[0]\""); + break; + } switch (config->GetKind_Turb_Model()) { case SA:case SA_NEG:case SA_E: case SA_COMP: case SA_E_COMP: SPRINTF (adj_turb_resid, ",\"Res_AdjTurb[0]\""); @@ -4539,6 +4545,7 @@ void COutputLegacy::SetConvHistory_Header(ofstream *ConvHist_file, CConfig *conf ConvHist_file[0] << flow_resid; if (turbulent) ConvHist_file[0] << turb_resid; + if (scalar) ConvHist_file[0] << scalar_resid; if (weakly_coupled_heat) ConvHist_file[0] << heat_resid; if (aeroelastic) ConvHist_file[0] << aeroelastic_coeff; if (output_per_surface) ConvHist_file[0] << monitoring_coeff; @@ -4734,8 +4741,7 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, adjoint_coeff[1000], flow_resid[1000], adj_flow_resid[1000], turb_resid[1000], trans_resid[1000], adj_turb_resid[1000], begin_fem[1000], fem_coeff[1000], heat_resid[1000], combo_obj[1000], - fem_resid[1000], end[1000], end_fem[1000], surface_outputs[1000], d_surface_outputs[1000], d_direct_coeff[1000], turbo_coeff[10000]; - + fem_resid[1000], end[1000], end_fem[1000], surface_outputs[1000], d_surface_outputs[1000], d_direct_coeff[1000], turbo_coeff[10000], scalar_resid[1000]; su2double dummy = 0.0, *Coord; unsigned short iVar, iMarker_Monitoring; @@ -4758,6 +4764,7 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, bool turbulent = ((config[val_iZone]->GetKind_Solver() == RANS) || (config[val_iZone]->GetKind_Solver() == ADJ_RANS) || (config[val_iZone]->GetKind_Solver() == DISC_ADJ_RANS) || config[val_iZone]->GetKind_Solver() == INC_RANS || config[val_iZone]->GetKind_Solver() == DISC_ADJ_INC_RANS); + bool scalar = (config[val_iZone]->GetKind_Scalar_Model() != NO_SCALAR_MODEL); bool adjoint = cont_adj || disc_adj; bool frozen_visc = (cont_adj && config[val_iZone]->GetFrozen_Visc_Cont()) ||( disc_adj && config[val_iZone]->GetFrozen_Visc_Disc()); bool heat = ((config[val_iZone]->GetKind_Solver() == HEAT_EQUATION_FVM) || (config[val_iZone]->GetWeakly_Coupled_Heat())); @@ -4836,6 +4843,7 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, /*--- Residual arrays ---*/ su2double *residual_flow = NULL, *residual_turbulent = NULL, + *residual_scalar = NULL, *residual_transition = NULL; su2double *residual_adjflow = NULL, *residual_adjturbulent = NULL, @@ -4860,7 +4868,8 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, *Surface_Buffet_Metric = NULL; /*--- Initialize number of variables ---*/ - unsigned short nVar_Flow = 0, nVar_Turb = 0, + + unsigned short nVar_Flow = 0, nVar_Turb = 0, nVar_Scalar = 0, nVar_Trans = 0, nVar_Heat = 0, nVar_AdjFlow = 0, nVar_AdjTurb = 0, nVar_AdjHeat = 0, nVar_FEM = 0; @@ -4873,6 +4882,11 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, case SST: case SST_SUST: nVar_Turb = 2; break; } } + if (scalar) { + switch (config[val_iZone]->GetKind_Scalar_Model()) { + case PASSIVE_SCALAR: case PROGRESS_VARIABLE: nVar_Scalar = 1; break; + } + } if (transition) nVar_Trans = 2; if (heat) nVar_Heat = 1; @@ -4897,6 +4911,7 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, /*--- Allocate memory for the residual ---*/ residual_flow = new su2double[nVar_Flow]; residual_turbulent = new su2double[nVar_Turb]; + residual_scalar = new su2double[nVar_Scalar]; residual_transition = new su2double[nVar_Trans]; residual_heat = new su2double[nVar_Heat]; residual_fem = new su2double[nVar_FEM]; @@ -5100,6 +5115,13 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, residual_turbulent[iVar] = solver_container[val_iZone][val_iInst][FinestMesh][TURB_SOL]->GetRes_RMS(iVar); } + /*--- Scalar residual ---*/ + + if (scalar) { + for (iVar = 0; iVar < nVar_Scalar; iVar++) + residual_scalar[iVar] = solver_container[val_iZone][val_iInst][FinestMesh][SCALAR_SOL]->GetRes_RMS(iVar); + } + if (weakly_coupled_heat) { for (iVar = 0; iVar < nVar_Heat; iVar++) { residual_heat[iVar] = solver_container[val_iZone][val_iInst][FinestMesh][HEAT_SOL]->GetRes_RMS(iVar); @@ -5435,6 +5457,13 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, } } + /*--- Scalar residual ---*/ + if (scalar) { + switch(nVar_Scalar) { + case 1: SPRINTF (scalar_resid, ", %12.10f", log10 (residual_scalar[0])); break; + } + } + /*---- Averaged stagnation pressure at an exit ----*/ if (output_surface) { @@ -5692,8 +5721,10 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, // if (!fluid_structure) { if (incompressible && !weakly_coupled_heat) { - if (energy) {cout << " Res[Press]" << " Res[Temp]" << " CLift(Total)" << " CDrag(Total)" << endl;} - else {cout << " Res[Press]" << " Res[Velx]" << " CLift(Total)" << " CDrag(Total)" << endl;} + if (energy) { cout << " Res[Press]" << " Res[Temp]";} + else {cout << " Res[Press]" << " Res[Velx]";} + if (scalar) cout << " Res[Scalar]" << " CLift(Total)" << " CDrag(Total)" << endl; + else cout << " CLift(Total)" << " CDrag(Total)" << endl; } else if (incompressible && weakly_coupled_heat) cout << " Res[Press]" << " Res[Heat]" << " HFlux(Total)"; else if (rotating_frame && nDim == 3 && !turbo) cout << " Res[Rho]" << " Res[RhoE]" << " CThrust(Total)" << " CTorque(Total)" << endl; @@ -5999,7 +6030,8 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, else { config[val_iZone]->GetHistFile()[0] << begin << turbo_coeff << flow_resid; } - + + if (scalar) ConvHist_file[0] << scalar_resid; if (aeroelastic) config[val_iZone]->GetHistFile()[0] << aeroelastic_coeff; if (output_per_surface) config[val_iZone]->GetHistFile()[0] << monitoring_coeff; if (output_surface) config[val_iZone]->GetHistFile()[0] << surface_outputs; @@ -6026,9 +6058,9 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, if (incompressible && !weakly_coupled_heat) { if (energy) {cout.width(14); cout << log10(residual_flow[nDim+1]);} else {cout.width(14); cout << log10(residual_flow[1]);} + if (scalar) {cout.width(14); cout << log10(residual_scalar[0]);} } if (incompressible && weakly_coupled_heat) { cout.width(14); cout << log10(residual_heat[0]);} - } if (rotating_frame && nDim == 3 && !turbo ) { @@ -6095,6 +6127,7 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, else { config[val_iZone]->GetHistFile()[0] << begin << turbo_coeff << flow_resid << turb_resid; } + if (scalar) ConvHist_file[0] << scalar_resid; if (aeroelastic) config[val_iZone]->GetHistFile()[0] << aeroelastic_coeff; if (output_per_surface) config[val_iZone]->GetHistFile()[0] << monitoring_coeff; @@ -6123,7 +6156,6 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, case 2: cout.width(14); cout << log10(residual_turbulent[0]); cout.width(15); cout << log10(residual_turbulent[1]); break; } - if (weakly_coupled_heat) { cout.width(14); cout << log10(residual_heat[0]); } @@ -6363,6 +6395,7 @@ void COutputLegacy::SetConvHistory_Body(ofstream *ConvHist_file, delete [] residual_flow; delete [] residual_turbulent; + delete [] residual_scalar; delete [] residual_transition; delete [] residual_fea; delete [] residual_fem; @@ -13288,8 +13321,9 @@ void COutputLegacy::LoadLocalData_IncFlow(CConfig *config, CGeometry *geometry, unsigned short nDim = geometry->GetnDim(); unsigned long iVar, jVar; - unsigned long iPoint, jPoint, FirstIndex = NONE, SecondIndex = NONE, iMarker, iVertex; - unsigned long nVar_First = 0, nVar_Second = 0, nVar_Consv_Par = 0; + unsigned long iPoint, jPoint, FirstIndex = NONE, SecondIndex = NONE; + unsigned long ThirdIndex = NONE, iMarker, iVertex; + unsigned long nVar_First = 0, nVar_Second = 0, nVar_Third = 0, nVar_Consv_Par = 0; su2double RefArea = config->GetRefArea(); su2double RefVel2 = 0.0; @@ -13305,6 +13339,8 @@ void COutputLegacy::LoadLocalData_IncFlow(CConfig *config, CGeometry *geometry, bool variable_density = (config->GetKind_DensityModel() == VARIABLE); bool energy = config->GetEnergy_Equation(); bool weakly_coupled_heat = config->GetWeakly_Coupled_Heat(); + bool scalar = (config->GetKind_Scalar_Model() != NO_SCALAR_MODEL); + bool wrt_cp = (variable_density && (config->GetKind_FluidModel() == INC_IDEAL_GAS_POLY)); bool wrt_kt = ((config->GetKind_ConductivityModel() != CONSTANT_CONDUCTIVITY) && @@ -13347,11 +13383,13 @@ void COutputLegacy::LoadLocalData_IncFlow(CConfig *config, CGeometry *geometry, case INC_RANS : FirstIndex = FLOW_SOL; SecondIndex = TURB_SOL; break; default: SecondIndex = NONE; break; } + if (scalar) ThirdIndex = SCALAR_SOL; nVar_First = solver[FirstIndex]->GetnVar(); if ((!energy) && (!weakly_coupled_heat)) nVar_First--; if (SecondIndex != NONE) nVar_Second = solver[SecondIndex]->GetnVar(); - nVar_Consv_Par = nVar_First + nVar_Second; + if (ThirdIndex != NONE) nVar_Third = solver[ThirdIndex]->GetnVar(); + nVar_Consv_Par = nVar_First + nVar_Second + nVar_Third; /*--------------------------------------------------------------------------*/ /*--- Step 1: Register the variables that will be output. To register a ---*/ @@ -13393,11 +13431,19 @@ void COutputLegacy::LoadLocalData_IncFlow(CConfig *config, CGeometry *geometry, Variable_Names.push_back("Nu_Tilde"); } } + + if (ThirdIndex != NONE) { + if (config->GetKind_Scalar_Model() == PASSIVE_SCALAR) { + Variable_Names.push_back("Passive_Scalar"); + } + if (config->GetKind_Scalar_Model() == PROGRESS_VARIABLE) { + Variable_Names.push_back("Progress_Variable"); + } + } /*--- If requested, register the limiter and residuals for all of the equations in the current flow problem. ---*/ - /*--- Add the limiters ---*/ if (config->GetWrt_Limiters()) { @@ -13419,6 +13465,16 @@ void COutputLegacy::LoadLocalData_IncFlow(CConfig *config, CGeometry *geometry, Variable_Names.push_back("Limiter_Nu_Tilde"); } } + + if (ThirdIndex != NONE) { + if (config->GetKind_Scalar_Model() == PASSIVE_SCALAR) { + Variable_Names.push_back("Limiter_Passive_Scalar"); + } + if (config->GetKind_Scalar_Model() == PROGRESS_VARIABLE) { + Variable_Names.push_back("Limiter_Progress_Variable"); + } + } + } /*--- Add the residuals ---*/ @@ -13442,6 +13498,16 @@ void COutputLegacy::LoadLocalData_IncFlow(CConfig *config, CGeometry *geometry, Variable_Names.push_back("Residual_Nu_Tilde"); } } + + if (ThirdIndex != NONE) { + if (config->GetKind_Scalar_Model() == PASSIVE_SCALAR) { + Variable_Names.push_back("Residual_Passive_Scalar"); + } + if (config->GetKind_Scalar_Model() == PROGRESS_VARIABLE) { + Variable_Names.push_back("Residual_Progress_Variable"); + } + } + } /*--- Add the grid velocity. ---*/ @@ -13703,7 +13769,16 @@ void COutputLegacy::LoadLocalData_IncFlow(CConfig *config, CGeometry *geometry, Local_Data[jPoint][iVar] = solver[SecondIndex]->GetNodes()->GetSolution(iPoint, jVar); iVar++; } } - + + /*--- If we have a scalar transport model, get the solution from + those containers. ---*/ + + if (ThirdIndex != NONE) { + for (jVar = 0; jVar < nVar_Third; jVar++) { + Local_Data[jPoint][iVar] = solver[ThirdIndex]->GetNodes()->GetSolution(iPoint, jVar); iVar++; + } + } + /*--- If limiters and/or residuals are requested. ---*/ /*--- Limiters ---*/ @@ -13720,6 +13795,12 @@ void COutputLegacy::LoadLocalData_IncFlow(CConfig *config, CGeometry *geometry, iVar++; } } + /*--- Scalar limiters ---*/ + if (ThirdIndex != NONE) { + for (jVar = 0; jVar < nVar_Third; jVar++) { + Local_Data[jPoint][iVar] = solver[ThirdIndex]->GetNodes()->GetLimiter(iPoint, jVar); iVar++; + } + } } /*--- Residuals ---*/ @@ -13737,9 +13818,14 @@ void COutputLegacy::LoadLocalData_IncFlow(CConfig *config, CGeometry *geometry, iVar++; } } + /*--- Scalar residuals ---*/ + if (ThirdIndex != NONE) { + for (jVar = 0; jVar < nVar_Third; jVar++) { + Local_Data[jPoint][iVar] = solver[ThirdIndex]->LinSysRes.GetBlock(iPoint, jVar); iVar++; + } + } } - /*--- Load buffers with the three grid velocity components. ---*/ if (dynamic_grid) { @@ -18822,7 +18908,8 @@ void COutputLegacy::Write_InletFile_Flow(CConfig *config, CGeometry *geometry, C unsigned short iMarker, iDim, iVar; unsigned long iPoint; su2double turb_val[2] = {0.0,0.0}; - + su2double *scalar_val = NULL; + const unsigned short nDim = geometry->GetnDim(); bool turbulent = (config->GetKind_Solver() == RANS || @@ -18830,6 +18917,7 @@ void COutputLegacy::Write_InletFile_Flow(CConfig *config, CGeometry *geometry, C config->GetKind_Solver() == ADJ_RANS || config->GetKind_Solver() == DISC_ADJ_RANS || config->GetKind_Solver() == DISC_ADJ_INC_RANS); + bool scalar = (config->GetKind_Scalar_Model() != NO_SCALAR_MODEL); unsigned short nVar_Turb = 0; if (turbulent) @@ -18847,13 +18935,27 @@ void COutputLegacy::Write_InletFile_Flow(CConfig *config, CGeometry *geometry, C SU2_MPI::Error("Specified turbulence model unavailable or none selected", CURRENT_FUNCTION); break; } + + unsigned short nVar_Scalar = 0; + if (scalar) + switch (config->GetKind_Scalar_Model()) { + case PASSIVE_SCALAR: case PROGRESS_VARIABLE: + nVar_Scalar = 1; + scalar_val = new su2double[nVar_Scalar]; + for (iVar = 0; iVar < nVar_Scalar; iVar++) + scalar_val[iVar] = solver[SCALAR_SOL]->GetScalar_Inf(iVar); + break; + default: + SU2_MPI::Error("Specified scalar transport model unavailable.", CURRENT_FUNCTION); + break; + } /*--- Count the number of columns that we have for this flow case. Here, we have nDim entries for node coordinates, 2 entries for the total conditions or mass flow, another nDim for the direction vector, and finally entries for the number of turbulence variables. ---*/ - unsigned short nCol_InletFile = nDim + 2 + nDim + nVar_Turb; + unsigned short nCol_InletFile = nDim + 2 + nDim + nVar_Turb + nVar_Scalar; /*--- Write the inlet profile file. Note that we have already merged all of the information for the markers and coordinates previously @@ -18895,12 +18997,17 @@ void COutputLegacy::Write_InletFile_Flow(CConfig *config, CGeometry *geometry, C for (iVar = 0; iVar < nVar_Turb; iVar++) { node_file << "\t" << turb_val[iVar]; } + for (iVar = 0; iVar < nVar_Scalar; iVar++) { + node_file << "\t" << scalar_val[iVar]; + } node_file << endl; } } node_file.close(); + if (scalar_val != NULL) delete [] scalar_val; + /*--- Print a message to inform the user about the template file. ---*/ stringstream err; diff --git a/SU2_CFD/src/solver_direct_mean.cpp b/SU2_CFD/src/solver_direct_mean.cpp index ed28f3a2bf2e..ecae09e89697 100644 --- a/SU2_CFD/src/solver_direct_mean.cpp +++ b/SU2_CFD/src/solver_direct_mean.cpp @@ -12551,7 +12551,7 @@ void CEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig bool steady_restart = config->GetSteadyRestart(); bool turbulent = (config->GetKind_Turb_Model() != NONE); - string restart_filename = config->GetFilename(config->GetSolution_FileName(), "", val_iter); + string restart_filename = config->GetFilename(config->GetSolution_FileName(), "", val_iter); Coord = new su2double [nDim]; for (iDim = 0; iDim < nDim; iDim++) @@ -14927,8 +14927,9 @@ void CNSSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, C unsigned long CNSSolver::SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output) { unsigned long iPoint, ErrorCounter = 0; - su2double eddy_visc = 0.0, turb_ke = 0.0, DES_LengthScale = 0.0; + su2double eddy_visc = 0.0, turb_ke = 0.0, DES_LengthScale = 0.0, *scalar = NULL; unsigned short turb_model = config->GetKind_Turb_Model(); + bool scalar_model = (config->GetKind_Scalar_Model() != NO_SCALAR_MODEL); bool RightSol = true; bool tkeNeeded = ((turb_model == SST) || (turb_model == SST_SUST)) ; @@ -14946,13 +14947,17 @@ unsigned long CNSSolver::SetPrimitive_Variables(CSolver **solver_container, CCon } } + if (scalar_model) { + scalar = solver_container[SCALAR_SOL]->GetNodes()->GetSolution(iPoint); + } + /*--- Initialize the non-physical points vector ---*/ nodes->SetNon_Physical(iPoint,false); /*--- Compressible flow, primitive variables nDim+5, (T, vx, vy, vz, P, rho, h, c, lamMu, eddyMu, ThCond, Cp) ---*/ - RightSol = static_cast(nodes)->SetPrimVar(iPoint,eddy_visc, turb_ke, FluidModel); + RightSol = static_cast(nodes)->SetPrimVar(iPoint,eddy_visc, turb_ke, scalar, FluidModel); nodes->SetSecondaryVar(iPoint,FluidModel); if (!RightSol) { nodes->SetNon_Physical(iPoint,true); ErrorCounter++; } diff --git a/SU2_CFD/src/solver_direct_mean_inc.cpp b/SU2_CFD/src/solver_direct_mean_inc.cpp index c159afa0b1d6..ea4a8fab9a48 100644 --- a/SU2_CFD/src/solver_direct_mean_inc.cpp +++ b/SU2_CFD/src/solver_direct_mean_inc.cpp @@ -7268,8 +7268,9 @@ void CIncNSSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container unsigned long CIncNSSolver::SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output) { unsigned long iPoint, ErrorCounter = 0; - su2double eddy_visc = 0.0, turb_ke = 0.0, DES_LengthScale = 0.0; + su2double eddy_visc = 0.0, turb_ke = 0.0, DES_LengthScale = 0.0, *scalar = NULL; unsigned short turb_model = config->GetKind_Turb_Model(); + bool scalar_model = (config->GetKind_Scalar_Model() != NO_SCALAR_MODEL); bool physical = true; bool tkeNeeded = ((turb_model == SST) || (turb_model == SST_SUST)); @@ -7287,13 +7288,17 @@ unsigned long CIncNSSolver::SetPrimitive_Variables(CSolver **solver_container, C } } + if (scalar_model) { + scalar = solver_container[SCALAR_SOL]->GetNodes()->GetSolution(iPoint); + } + /*--- Initialize the non-physical points vector ---*/ nodes->SetNon_Physical(iPoint,false); /*--- Incompressible flow, primitive variables --- */ - physical = static_cast(nodes)->SetPrimVar(iPoint,eddy_visc, turb_ke, FluidModel); + physical = static_cast(nodes)->SetPrimVar(iPoint,eddy_visc, turb_ke, scalar, FluidModel); /*--- Record any non-physical points. ---*/ diff --git a/SU2_CFD/src/solver_direct_turbulent.cpp b/SU2_CFD/src/solver_direct_turbulent.cpp index 7886ec3f3ec5..46bc59e48583 100644 --- a/SU2_CFD/src/solver_direct_turbulent.cpp +++ b/SU2_CFD/src/solver_direct_turbulent.cpp @@ -231,14 +231,22 @@ void CTurbSolver::Viscous_Residual(CGeometry *geometry, CSolver **solver_contain numerics->SetPrimitive(solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint), solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(jPoint)); - /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ + /*--- Turbulent variables w/o reconstruction. ---*/ - numerics->SetTurbVar(nodes->GetSolution(iPoint), nodes->GetSolution(jPoint)); - numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(jPoint)); + numerics->SetScalarVar(nodes->GetSolution(iPoint), + nodes->GetSolution(jPoint)); + + /*--- Turbulent variable gradients. ---*/ + + numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), + nodes->GetGradient(jPoint)); /*--- Menter's first blending function (only SST)---*/ - if ((config->GetKind_Turb_Model() == SST) || (config->GetKind_Turb_Model() == SST_SUST)) - numerics->SetF1blending(nodes->GetF1blending(iPoint), nodes->GetF1blending(jPoint)); + + if ((config->GetKind_Turb_Model() == SST) || + (config->GetKind_Turb_Model() == SST_SUST)) + numerics->SetF1blending(nodes->GetF1blending(iPoint), + nodes->GetF1blending(jPoint)); /*--- Compute residual, and Jacobians ---*/ @@ -1532,8 +1540,8 @@ void CTurbSASolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, CN // // /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ // -// visc_numerics->SetTurbVar(Solution_i, Solution_j); -// visc_numerics->SetTurbVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); +// visc_numerics->SetScalarVar(Solution_i, Solution_j); +// visc_numerics->SetScalarVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); // // /*--- Compute residual, and Jacobians ---*/ // @@ -1624,8 +1632,8 @@ void CTurbSASolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, C // // /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ // -// visc_numerics->SetTurbVar(Solution_i, Solution_j); -// visc_numerics->SetTurbVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); +// visc_numerics->SetScalarVar(Solution_i, Solution_j); +// visc_numerics->SetScalarVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); // // /*--- Compute residual, and Jacobians ---*/ // @@ -1714,8 +1722,8 @@ void CTurbSASolver::BC_Engine_Inflow(CGeometry *geometry, CSolver **solver_conta // // /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ // -// visc_numerics->SetTurbVar(node[iPoint]->GetSolution(), node[iPoint]->GetSolution()); -// visc_numerics->SetTurbVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); +// visc_numerics->SetScalarVar(node[iPoint]->GetSolution(), node[iPoint]->GetSolution()); +// visc_numerics->SetScalarVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); // // /*--- Compute residual, and Jacobians ---*/ // @@ -1810,8 +1818,8 @@ void CTurbSASolver::BC_Engine_Exhaust(CGeometry *geometry, CSolver **solver_cont // // /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ // -// visc_numerics->SetTurbVar(Solution_i, Solution_j); -// visc_numerics->SetTurbVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); +// visc_numerics->SetScalarVar(Solution_i, Solution_j); +// visc_numerics->SetScalarVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); // // /*--- Compute residual, and Jacobians ---*/ // @@ -1973,9 +1981,8 @@ void CTurbSASolver::BC_ActDisk(CGeometry *geometry, CSolver **solver_container, // // /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ // -// visc_numerics->SetTurbVar(Solution_i, Solution_j); -// -// visc_numerics->SetTurbVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); +// visc_numerics->SetScalarVar(Solution_i, Solution_j); +// visc_numerics->SetScalarVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); // // /*--- Compute residual, and Jacobians ---*/ // @@ -2083,8 +2090,8 @@ void CTurbSASolver::BC_Inlet_MixingPlane(CGeometry *geometry, CSolver **solver_c /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ - visc_numerics->SetTurbVar(Solution_i, Solution_j); - visc_numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); + visc_numerics->SetScalarVar(Solution_i, Solution_j); + visc_numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); /*--- Compute residual, and Jacobians ---*/ @@ -2200,8 +2207,8 @@ void CTurbSASolver::BC_Inlet_Turbo(CGeometry *geometry, CSolver **solver_contain /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ - visc_numerics->SetTurbVar(Solution_i, Solution_j); - visc_numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); + visc_numerics->SetScalarVar(Solution_i, Solution_j); + visc_numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); /*--- Compute residual, and Jacobians ---*/ @@ -2477,8 +2484,8 @@ void CTurbSASolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_con /*--- Turbulent variables and its gradients ---*/ - visc_numerics->SetTurbVar(Solution_i, Solution_j); - visc_numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); + visc_numerics->SetScalarVar(Solution_i, Solution_j); + visc_numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); /*--- Compute and update residual ---*/ @@ -3156,7 +3163,7 @@ su2double CTurbSASolver::GetInletAtVertex(su2double *val_inlet, for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) == INLET_FLOW) && (config->GetMarker_All_TagBound(iMarker) == val_marker)) { - + for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++){ iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); @@ -3834,8 +3841,8 @@ void CTurbSSTSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, C // // /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ // - // visc_numerics->SetTurbVar(Solution_i, Solution_j); - // visc_numerics->SetTurbVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); + // visc_numerics->SetScalarVar(Solution_i, Solution_j); + // visc_numerics->SetScalarVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); // // /*--- Menter's first blending function ---*/ // @@ -3932,8 +3939,8 @@ void CTurbSSTSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, // // /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ // -// visc_numerics->SetTurbVar(Solution_i, Solution_j); -// visc_numerics->SetTurbVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); +// visc_numerics->SetScalarVar(Solution_i, Solution_j); +// visc_numerics->SetScalarVarGradient(node[iPoint]->GetGradient(), node[iPoint]->GetGradient()); // // /*--- Menter's first blending function ---*/ // @@ -4038,8 +4045,8 @@ void CTurbSSTSolver::BC_Inlet_MixingPlane(CGeometry *geometry, CSolver **solver_ visc_numerics->SetPrimitive(V_domain, V_inlet); /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ - visc_numerics->SetTurbVar(Solution_i, Solution_j); - visc_numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); + visc_numerics->SetScalarVar(Solution_i, Solution_j); + visc_numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); /*--- Menter's first blending function ---*/ visc_numerics->SetF1blending(nodes->GetF1blending(iPoint), nodes->GetF1blending(iPoint)); @@ -4164,8 +4171,8 @@ void CTurbSSTSolver::BC_Inlet_Turbo(CGeometry *geometry, CSolver **solver_contai visc_numerics->SetPrimitive(V_domain, V_inlet); /*--- Turbulent variables w/o reconstruction, and its gradients ---*/ - visc_numerics->SetTurbVar(Solution_i, Solution_j); - visc_numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); + visc_numerics->SetScalarVar(Solution_i, Solution_j); + visc_numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); /*--- Menter's first blending function ---*/ visc_numerics->SetF1blending(nodes->GetF1blending(iPoint), nodes->GetF1blending(iPoint)); @@ -4282,8 +4289,8 @@ void CTurbSSTSolver::BC_Fluid_Interface(CGeometry *geometry, CSolver **solver_co /*--- Turbulent variables and its gradients ---*/ - visc_numerics->SetTurbVar(Solution_i, Solution_j); - visc_numerics->SetTurbVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); + visc_numerics->SetScalarVar(Solution_i, Solution_j); + visc_numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), nodes->GetGradient(iPoint)); /*--- Compute and update residual ---*/ @@ -4346,7 +4353,7 @@ su2double CTurbSSTSolver::GetInletAtVertex(su2double *val_inlet, for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if ((config->GetMarker_All_KindBC(iMarker) == INLET_FLOW) && (config->GetMarker_All_TagBound(iMarker) == val_marker)) { - + for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++){ iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); diff --git a/SU2_CFD/src/solver_structure.cpp b/SU2_CFD/src/solver_structure.cpp index 3778a21ff255..44f69adc6148 100644 --- a/SU2_CFD/src/solver_structure.cpp +++ b/SU2_CFD/src/solver_structure.cpp @@ -5667,7 +5667,8 @@ void CBaselineSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf unsigned short iInst = config->GetiInst(); bool steady_restart = config->GetSteadyRestart(); unsigned short turb_model = config->GetKind_Turb_Model(); - + unsigned short scalar_model = config->GetKind_Scalar_Model(); + su2double *Coord = new su2double [nDim]; for (iDim = 0; iDim < nDim; iDim++) Coord[iDim] = 0.0; @@ -5736,6 +5737,11 @@ void CBaselineSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConf index+=2; } + if ((scalar_model == PASSIVE_SCALAR) || + (scalar_model == PROGRESS_VARIABLE)) { + index++; + } + /*--- Read in the next 2 or 3 variables which are the grid velocities ---*/ /*--- If we are restarting the solution from a previously computed static calculation (no grid movement) ---*/ /*--- the grid velocities are set to 0. This is useful for FSI computations ---*/ diff --git a/SU2_CFD/src/solvers/CPassiveScalarSolver.cpp b/SU2_CFD/src/solvers/CPassiveScalarSolver.cpp new file mode 100644 index 000000000000..e06a5479dc1a --- /dev/null +++ b/SU2_CFD/src/solvers/CPassiveScalarSolver.cpp @@ -0,0 +1,552 @@ +/*! + * \file solution_direct_scalar.cpp + * \brief Main subroutines for solving scalar transport equations. + * \author T. Economon + * \version 6.1.0 "Falcon" + * + * The current SU2 release has been coordinated by the + * SU2 International Developers Society + * with selected contributions from the open-source community. + * + * The main research teams contributing to the current release are: + * - Prof. Juan J. Alonso's group at Stanford University. + * - Prof. Piero Colonna's group at Delft University of Technology. + * - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology. + * - Prof. Alberto Guardone's group at Polytechnic University of Milan. + * - Prof. Rafael Palacios' group at Imperial College London. + * - Prof. Vincent Terrapon's group at the University of Liege. + * - Prof. Edwin van der Weide's group at the University of Twente. + * - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics. + * + * Copyright 2012-2018, Francisco D. Palacios, Thomas D. Economon, + * Tim Albring, and the SU2 contributors. + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#include "../../include/solvers/CPassiveScalarSolver.hpp" +#include "../../include/variables/CPassiveScalarVariable.hpp" + +CPassiveScalarSolver::CPassiveScalarSolver(void) : CScalarSolver() { + + Inlet_ScalarVars = NULL; + +} + +CPassiveScalarSolver::CPassiveScalarSolver(CGeometry *geometry, + CConfig *config, + unsigned short iMesh) +: CScalarSolver(geometry, config) { + + unsigned short iVar, iDim, nLineLets; + unsigned long iPoint; + su2double Density_Inf, Viscosity_Inf; + + bool turbulent = ((config->GetKind_Solver() == RANS) || + (config->GetKind_Solver() == DISC_ADJ_RANS)); + bool turb_SST = ((turbulent) && ((config->GetKind_Turb_Model() == SST) || + (config->GetKind_Turb_Model() == SST_SUST))); + + /*--- Dimension of the problem --> passive scalar will only ever + have a single equation. Other child classes of CScalarSolver + can have variable numbers of equations. ---*/ + + nVar = 1; + nPrimVar = 1; + + nPoint = geometry->GetnPoint(); + nPointDomain = geometry->GetnPointDomain(); + + /*--- Initialize nVarGrad for deallocation ---*/ + + nVarGrad = nVar; + + /*--- Define geometry constants in the solver structure ---*/ + + nDim = geometry->GetnDim(); + + /*--- Fluid model pointer initialization ---*/ + + FluidModel = NULL; + + /*--- Define some auxiliar vector related with the residual ---*/ + + Residual = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; + Residual_RMS = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_RMS[iVar] = 0.0; + Residual_i = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_i[iVar] = 0.0; + Residual_j = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_j[iVar] = 0.0; + Residual_Max = new su2double[nVar]; for (iVar = 0; iVar < nVar; iVar++) Residual_Max[iVar] = 0.0; + + /*--- Define some structures for locating max residuals ---*/ + + Point_Max = new unsigned long[nVar]; + for (iVar = 0; iVar < nVar; iVar++) Point_Max[iVar] = 0; + Point_Max_Coord = new su2double*[nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Point_Max_Coord[iVar] = new su2double[nDim]; + for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord[iVar][iDim] = 0.0; + } + + /*--- Define some auxiliar vector related with the solution ---*/ + + Solution = new su2double[nVar]; + Solution_i = new su2double[nVar]; Solution_j = new su2double[nVar]; + + /*--- Define some auxiliar vector related with the geometry ---*/ + + Vector_i = new su2double[nDim]; Vector_j = new su2double[nDim]; + + /*--- Define some auxiliar vector related with the flow solution ---*/ + + FlowPrimVar_i = new su2double [nDim+9]; FlowPrimVar_j = new su2double [nDim+9]; + + /*--- Jacobians and vector structures for implicit computations ---*/ + + Jacobian_i = new su2double* [nVar]; + Jacobian_j = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Jacobian_i[iVar] = new su2double [nVar]; + Jacobian_j[iVar] = new su2double [nVar]; + } + + /*--- Initialization of the structure of the whole Jacobian ---*/ + + if (rank == MASTER_NODE) cout << "Initialize Jacobian structure (Passive Scalar). MG level: " << iMesh <<"." << endl; + Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); + + if (config->GetKind_Linear_Solver_Prec() == LINELET) { + nLineLets = Jacobian.BuildLineletPreconditioner(geometry, config); + if (rank == MASTER_NODE) cout << "Compute linelet structure. " << nLineLets << " elements in each line (average)." << endl; + } + + LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); + LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); + + /*--- Computation of gradients by least squares ---*/ + + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + /*--- S matrix := inv(R)*traspose(inv(R)) ---*/ + Smatrix = new su2double* [nDim]; + for (iDim = 0; iDim < nDim; iDim++) + Smatrix[iDim] = new su2double [nDim]; + + /*--- c vector := transpose(WA)*(Wb) ---*/ + + Cvector = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar++) + Cvector[iVar] = new su2double [nDim]; + } + + /*--- Initialize lower and upper limits---*/ + + lowerlimit = new su2double[nVar]; + upperlimit = new su2double[nVar]; + + lowerlimit[0] = -1.0e15; + upperlimit[0] = 1.0e15; + + /*--- Read farfield conditions from config ---*/ + + Density_Inf = config->GetDensity_FreeStreamND(); + Viscosity_Inf = config->GetViscosity_FreeStreamND(); + + /*--- Set up fluid model for the diffusivity ---*/ + + su2double Diffusivity_Ref = 1.0; + + su2double DiffusivityND = config->GetDiffusivity_Constant()/Diffusivity_Ref; + + config->SetDiffusivity_ConstantND(DiffusivityND); + + FluidModel = new CFluidModel(); + FluidModel->SetMassDiffusivityModel(config); + + /*--- Scalar variable state at the far-field. ---*/ + + Scalar_Inf = new su2double[nVar]; + for (iVar = 0; iVar < nVar; iVar++) + Scalar_Inf[iVar] = config->GetScalar_Init(); + + /*--- Initialize the solution to the far-field state everywhere. ---*/ + + nodes = new CPassiveScalarVariable(Scalar_Inf, nPoint, nDim, nVar, config); + SetBaseClassPointerToNodes(); + + /*--- MPI solution ---*/ + + InitiateComms(geometry, config, SOLUTION); + CompleteComms(geometry, config, SOLUTION); + + /*--- Initializate quantities for SlidingMesh Interface ---*/ + + unsigned long iMarker; + + SlidingState = new su2double*** [nMarker]; + SlidingStateNodes = new int* [nMarker]; + + for (iMarker = 0; iMarker < nMarker; iMarker++){ + + SlidingState[iMarker] = NULL; + SlidingStateNodes[iMarker] = NULL; + + if (config->GetMarker_All_KindBC(iMarker) == FLUID_INTERFACE){ + + SlidingState[iMarker] = new su2double**[geometry->GetnVertex(iMarker)]; + SlidingStateNodes[iMarker] = new int [geometry->GetnVertex(iMarker)]; + + for (iPoint = 0; iPoint < geometry->GetnVertex(iMarker); iPoint++){ + SlidingState[iMarker][iPoint] = new su2double*[nPrimVar+1]; + + SlidingStateNodes[iMarker][iPoint] = 0; + for (iVar = 0; iVar < nPrimVar+1; iVar++) + SlidingState[iMarker][iPoint][iVar] = NULL; + } + + } + } + + /*-- Allocation of inlets has to happen in derived classes + (not CScalarSolver), due to arbitrary number of scalar variables. + First, we also set the column index for any inlet profiles. ---*/ + + Inlet_Position = nDim*2+2; + if (turbulent) { + if (turb_SST) Inlet_Position += 2; + else Inlet_Position += 1; + } + + Inlet_ScalarVars = new su2double**[nMarker]; + for (unsigned long iMarker = 0; iMarker < nMarker; iMarker++) { + Inlet_ScalarVars[iMarker] = new su2double*[nVertex[iMarker]]; + for(unsigned long iVertex=0; iVertex < nVertex[iMarker]; iVertex++){ + Inlet_ScalarVars[iMarker][iVertex] = new su2double[nVar]; + for (unsigned short iVar = 0; iVar < nVar; iVar++) + Inlet_ScalarVars[iMarker][iVertex][0] = Scalar_Inf[iVar]; + } + } + +} + +CPassiveScalarSolver::~CPassiveScalarSolver(void) { + + unsigned long iMarker, iVertex; + unsigned short iVar; + + if ( SlidingState != NULL ) { + for (iMarker = 0; iMarker < nMarker; iMarker++) { + if ( SlidingState[iMarker] != NULL ) { + for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) + if ( SlidingState[iMarker][iVertex] != NULL ){ + for (iVar = 0; iVar < nPrimVar+1; iVar++) + delete [] SlidingState[iMarker][iVertex][iVar]; + delete [] SlidingState[iMarker][iVertex]; + } + delete [] SlidingState[iMarker]; + } + } + delete [] SlidingState; + } + + if ( SlidingStateNodes != NULL ){ + for (iMarker = 0; iMarker < nMarker; iMarker++){ + if (SlidingStateNodes[iMarker] != NULL) + delete [] SlidingStateNodes[iMarker]; + } + delete [] SlidingStateNodes; + } + + if (FluidModel != NULL) delete FluidModel; + +} + +void CPassiveScalarSolver::Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) { + + unsigned long ErrorCounter = 0; + unsigned long InnerIter = config->GetInnerIter(); + bool disc_adjoint = config->GetDiscrete_Adjoint(); + bool limiter_flow = ((config->GetKind_SlopeLimit_Flow() != NO_LIMITER) && + (InnerIter <= config->GetLimiterIter()) && !(disc_adjoint && config->GetFrozen_Limiter_Disc())); + bool limiter_scalar = ((config->GetKind_SlopeLimit_Scalar() != NO_LIMITER) && + (InnerIter <= config->GetLimiterIter()) && !(disc_adjoint && config->GetFrozen_Limiter_Disc())); + + /*--- Set the primitive variables ---*/ + + ErrorCounter = SetPrimitive_Variables(solver_container, config, Output); + + /*--- Initialize the Jacobian matrices ---*/ + + if (!disc_adjoint) Jacobian.SetValZero(); + + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) SetSolution_Gradient_GG(geometry, config); + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) SetSolution_Gradient_LS(geometry, config); + + /*--- Upwind second-order reconstruction ---*/ + + if ((limiter_scalar) && (iMesh == MESH_0)) SetSolution_Limiter(geometry, config); + + if ((limiter_flow) && (iMesh == MESH_0)) solver_container[FLOW_SOL]->SetPrimitive_Limiter(geometry, config); + +} + +void CPassiveScalarSolver::Postprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh) { } + +unsigned long CPassiveScalarSolver::SetPrimitive_Variables(CSolver **solver_container, + CConfig *config, + bool Output) { + + unsigned long iPoint, ErrorCounter = 0; + su2double Density, Temperature, lam_visc = 0.0, eddy_visc = 0.0, Cp; + unsigned short iVar, turb_model = config->GetKind_Turb_Model(); + + for (iPoint = 0; iPoint < nPoint; iPoint++) { + + /*--- Retrieve the density, temperature, Cp, and laminar viscosity. ---*/ + + Density = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + Cp = solver_container[FLOW_SOL]->GetNodes()->GetSpecificHeatCp(iPoint); + Temperature = solver_container[FLOW_SOL]->GetNodes()->GetTemperature(iPoint); + lam_visc = solver_container[FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); + + /*--- Retrieve the value of the kinetic energy (if needed) ---*/ + + if (turb_model != NONE) { + eddy_visc = solver_container[TURB_SOL]->GetNodes()->GetmuT(iPoint); + } + + /*--- Compute and store the mass diffusivity. ---*/ + + FluidModel->SetDiffusivityState(Temperature, Density, lam_visc, eddy_visc, Cp); + + for (iVar = 0; iVar < nVar; iVar++) + nodes->SetDiffusivity(iPoint, FluidModel->GetMassDiffusivity(), iVar); + + /*--- Initialize the convective, source and viscous residual vector ---*/ + + if (!Output) LinSysRes.SetBlock_Zero(iPoint); + + } + + return ErrorCounter; + +} + +void CPassiveScalarSolver::SetInitialCondition(CGeometry **geometry, + CSolver ***solver_container, + CConfig *config, + unsigned long ExtIter) { + + if (ExtIter == 0) { + /* Implement initial condition here. */ + } + +} + + +void CPassiveScalarSolver::SetPreconditioner(CGeometry *geometry, CSolver **solver_container, CConfig *config) { + + unsigned short iVar; + unsigned long iPoint, total_index; + + su2double BetaInc2, Density, dRhodT, dRhodC, Temperature, Cp, Delta; + + bool variable_density = (config->GetKind_DensityModel() == VARIABLE); + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Access the primitive variables at this node. ---*/ + + Density = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + BetaInc2 = solver_container[FLOW_SOL]->GetNodes()->GetBetaInc2(iPoint); + Cp = solver_container[FLOW_SOL]->GetNodes()->GetSpecificHeatCp(iPoint); + Temperature = solver_container[FLOW_SOL]->GetNodes()->GetTemperature(iPoint); + + unsigned short nVar_Flow = solver_container[FLOW_SOL]->GetnVar(); + + su2double SolP = solver_container[FLOW_SOL]->LinSysSol[iPoint*nVar_Flow+0]; + su2double SolT = solver_container[FLOW_SOL]->LinSysSol[iPoint*nVar_Flow+nDim+1]; + + /*--- We need the derivative of the equation of state to build the + preconditioning matrix. For now, the only option is the ideal gas + law, but in the future, dRhodT should be in the fluid model. ---*/ + + if (variable_density) { + dRhodT = -Density/Temperature; + } else { + dRhodT = 0.0; + } + + /*--- Passive scalars have no impact on the density. ---*/ + + dRhodC = 0.0; + + /*--- Modify matrix diagonal with term including volume and time step. ---*/ + + su2double Vol = geometry->node[iPoint]->GetVolume(); + Delta = Vol / (config->GetCFLRedCoeff_Scalar()* + solver_container[FLOW_SOL]->GetNodes()->GetDelta_Time(iPoint)); + + /*--- Calculating the inverse of the preconditioning matrix + that multiplies the time derivative during time integration. ---*/ + + if (implicit) { + + for (iVar = 0; iVar < nVar; iVar++) { + + total_index = iPoint*nVar+iVar; + + su2double c = nodes->GetSolution(iPoint,0); + + /*--- Compute the lag terms for the decoupled linear system from + the mean flow equations and add to the residual for the scalar. + In short, we are effectively making these terms explicit. ---*/ + + su2double artcompc1 = SolP * c/(Density*BetaInc2); + su2double artcompc2 = SolT * dRhodT * c/(Density); + + LinSysRes[total_index] += artcompc1 + artcompc2; + + /*--- Add the extra Jacobian term to the scalar system. ---*/ + + su2double Jaccomp = c * dRhodC + Density; //This is Gamma + su2double JacTerm = Jaccomp*Delta; + + Jacobian.AddVal2Diag(iPoint, JacTerm); + + } + + } + + } + +} + +void CPassiveScalarSolver::Source_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CNumerics *second_numerics, + CConfig *config, + unsigned short iMesh) { + + unsigned short iVar; + unsigned long iPoint; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool axisymmetric = config->GetAxisymmetric(); + bool viscous = config->GetViscous(); + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Conservative variables w/o reconstruction ---*/ + + numerics->SetPrimitive(solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint), NULL); + + /*--- Gradient of the primitive and conservative variables ---*/ + + numerics->SetPrimVarGradient(solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint), NULL); + + /*--- Scalar variables w/o reconstruction, and its gradient ---*/ + + numerics->SetScalarVar(nodes->GetSolution(iPoint), NULL); + numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), NULL); + + /*--- Set volume ---*/ + + numerics->SetVolume(geometry->node[iPoint]->GetVolume()); + + /*--- Compute the source term ---*/ + + numerics->ComputeResidual(Residual, Jacobian_i, NULL, config); + + /*--- Subtract residual and the Jacobian ---*/ + + LinSysRes.SubtractBlock(iPoint, Residual); + + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + + } + + /*--- Axisymmetry source term for the scalar equation. ---*/ + + if (axisymmetric) { + + /*--- Zero out Jacobian structure ---*/ + + if (implicit) { + for (iVar = 0; iVar < nVar; iVar ++) + for (unsigned short jVar = 0; jVar < nVar; jVar ++) + Jacobian_i[iVar][jVar] = 0.0; + } + + /*--- loop over points ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Primitive variables w/o reconstruction ---*/ + + second_numerics->SetPrimitive(solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint), NULL); + + /*--- Scalar variables w/o reconstruction ---*/ + + second_numerics->SetScalarVar(nodes->GetSolution(iPoint), NULL); + + /*--- Mass diffusivity coefficients. ---*/ + + second_numerics->SetDiffusionCoeff(nodes->GetDiffusivity(iPoint), + NULL); + + /*--- Set control volume ---*/ + + second_numerics->SetVolume(geometry->node[iPoint]->GetVolume()); + + /*--- Set y coordinate ---*/ + + second_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), + NULL); + + /*--- If viscous, we need gradients for extra terms. ---*/ + + if (viscous) { + + /*--- Gradient of the scalar variables ---*/ + + second_numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), NULL); + + } + + /*--- Compute Source term Residual ---*/ + + second_numerics->ComputeResidual(Residual, Jacobian_i, config); + + /*--- Add Residual ---*/ + + LinSysRes.AddBlock(iPoint, Residual); + + /*--- Implicit part ---*/ + + if (implicit) Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + + } + } + +} diff --git a/SU2_CFD/src/solvers/CScalarSolver.cpp b/SU2_CFD/src/solvers/CScalarSolver.cpp new file mode 100644 index 000000000000..b645dec3516a --- /dev/null +++ b/SU2_CFD/src/solvers/CScalarSolver.cpp @@ -0,0 +1,1196 @@ +/*! + * \file solution_direct_scalar.cpp + * \brief Main subroutines for solving scalar transport equations. + * \author T. Economon + * \version 6.1.0 "Falcon" + * + * The current SU2 release has been coordinated by the + * SU2 International Developers Society + * with selected contributions from the open-source community. + * + * The main research teams contributing to the current release are: + * - Prof. Juan J. Alonso's group at Stanford University. + * - Prof. Piero Colonna's group at Delft University of Technology. + * - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology. + * - Prof. Alberto Guardone's group at Polytechnic University of Milan. + * - Prof. Rafael Palacios' group at Imperial College London. + * - Prof. Vincent Terrapon's group at the University of Liege. + * - Prof. Edwin van der Weide's group at the University of Twente. + * - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics. + * + * Copyright 2012-2018, Francisco D. Palacios, Thomas D. Economon, + * Tim Albring, and the SU2 contributors. + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#include "../../include/solvers/CScalarSolver.hpp" + +CScalarSolver::CScalarSolver(void) : CSolver() { + + FlowPrimVar_i = NULL; + FlowPrimVar_j = NULL; + lowerlimit = NULL; + upperlimit = NULL; + nVertex = NULL; + nMarker = 0; + Inlet_ScalarVars = NULL; + Scalar_Inf = NULL; + + /*--- The turbulence models are always solved implicitly, so set the + implicit flag in case we have periodic BCs. ---*/ + + SetImplicitPeriodic(true); + +} + +CScalarSolver::CScalarSolver(CGeometry* geometry, CConfig *config) : CSolver() { + + FlowPrimVar_i = NULL; + FlowPrimVar_j = NULL; + lowerlimit = NULL; + upperlimit = NULL; + nMarker = config->GetnMarker_All(); + Inlet_ScalarVars = NULL; + Scalar_Inf = NULL; + + /*--- Store the number of vertices on each marker for deallocation later ---*/ + + nVertex = new unsigned long[nMarker]; + for (unsigned long iMarker = 0; iMarker < nMarker; iMarker++) + nVertex[iMarker] = geometry->nVertex[iMarker]; + + /*--- The turbulence models are always solved implicitly, so set the + implicit flag in case we have periodic BCs. ---*/ + + SetImplicitPeriodic(true); + +} + +CScalarSolver::~CScalarSolver(void) { + + if (Inlet_ScalarVars != NULL) { + for (unsigned long iMarker = 0; iMarker < nMarker; iMarker++) { + if (Inlet_ScalarVars[iMarker] != NULL) { + for (unsigned long iVertex = 0; iVertex < nVertex[iMarker]; iVertex++) { + delete [] Inlet_ScalarVars[iMarker][iVertex]; + } + delete [] Inlet_ScalarVars[iMarker]; + } + } + delete [] Inlet_ScalarVars; + } + + if (FlowPrimVar_i != NULL) delete [] FlowPrimVar_i; + if (FlowPrimVar_j != NULL) delete [] FlowPrimVar_j; + if (lowerlimit != NULL) delete [] lowerlimit; + if (upperlimit != NULL) delete [] upperlimit; + if (nVertex != NULL) delete [] nVertex; + if (Scalar_Inf != NULL) delete [] Scalar_Inf; + +} + +void CScalarSolver::Upwind_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) { + + su2double *Scalar_i, *Scalar_j, *Limiter_i = NULL, *Limiter_j = NULL; + su2double *V_i, *V_j, **Gradient_i, **Gradient_j; + su2double Project_Grad_i, Project_Grad_j; + + unsigned long iEdge, iPoint, jPoint; + unsigned short iDim, iVar; + + bool muscl = (config->GetMUSCL_Scalar() && (iMesh == MESH_0)); + bool limiter = (config->GetKind_SlopeLimit_Scalar() != NO_LIMITER); + bool grid_movement = config->GetGrid_Movement(); + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Points in edge and normal vectors ---*/ + + iPoint = geometry->edge[iEdge]->GetNode(0); + jPoint = geometry->edge[iEdge]->GetNode(1); + numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); + + /*--- Primitive variables w/o reconstruction ---*/ + + V_i = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); + V_j = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(jPoint); + numerics->SetPrimitive(V_i, V_j); + + /*--- Scalar variables w/o reconstruction ---*/ + + Scalar_i = nodes->GetSolution(iPoint); + Scalar_j = nodes->GetSolution(jPoint); + numerics->SetScalarVar(Scalar_i, Scalar_j); + + /*--- Grid Movement ---*/ + + if (grid_movement) + numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), geometry->node[jPoint]->GetGridVel()); + + if (muscl) { + + for (iDim = 0; iDim < nDim; iDim++) { + Vector_i[iDim] = 0.5*(geometry->node[jPoint]->GetCoord(iDim) - geometry->node[iPoint]->GetCoord(iDim)); + Vector_j[iDim] = 0.5*(geometry->node[iPoint]->GetCoord(iDim) - geometry->node[jPoint]->GetCoord(iDim)); + } + + /*--- Mean flow primitive variables using gradient reconstruction and limiters ---*/ + + Gradient_i = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint); + Gradient_j = solver_container[FLOW_SOL]->GetNodes()->GetGradient_Primitive(jPoint); + if (limiter) { + Limiter_i = solver_container[FLOW_SOL]->GetNodes()->GetLimiter_Primitive(iPoint); + Limiter_j = solver_container[FLOW_SOL]->GetNodes()->GetLimiter_Primitive(jPoint); + } + + for (iVar = 0; iVar < solver_container[FLOW_SOL]->GetnPrimVarGrad(); iVar++) { + Project_Grad_i = 0.0; Project_Grad_j = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Project_Grad_i += Vector_i[iDim]*Gradient_i[iVar][iDim]; + Project_Grad_j += Vector_j[iDim]*Gradient_j[iVar][iDim]; + } + if (limiter) { + FlowPrimVar_i[iVar] = V_i[iVar] + Limiter_i[iVar]*Project_Grad_i; + FlowPrimVar_j[iVar] = V_j[iVar] + Limiter_j[iVar]*Project_Grad_j; + } + else { + FlowPrimVar_i[iVar] = V_i[iVar] + Project_Grad_i; + FlowPrimVar_j[iVar] = V_j[iVar] + Project_Grad_j; + } + } + + numerics->SetPrimitive(FlowPrimVar_i, FlowPrimVar_j); + + /*--- Scalar variables using gradient reconstruction and limiters ---*/ + + Gradient_i = nodes->GetGradient(iPoint); + Gradient_j = nodes->GetGradient(jPoint); + if (limiter) { + Limiter_i = nodes->GetLimiter(iPoint); + Limiter_j = nodes->GetLimiter(jPoint); + } + + for (iVar = 0; iVar < nVar; iVar++) { + Project_Grad_i = 0.0; Project_Grad_j = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Project_Grad_i += Vector_i[iDim]*Gradient_i[iVar][iDim]; + Project_Grad_j += Vector_j[iDim]*Gradient_j[iVar][iDim]; + } + if (limiter) { + Solution_i[iVar] = Scalar_i[iVar] + Limiter_i[iVar]*Project_Grad_i; + Solution_j[iVar] = Scalar_j[iVar] + Limiter_j[iVar]*Project_Grad_j; + } + else { + Solution_i[iVar] = Scalar_i[iVar] + Project_Grad_i; + Solution_j[iVar] = Scalar_j[iVar] + Project_Grad_j; + } + } + + numerics->SetScalarVar(Solution_i, Solution_j); + + } + + /*--- Add and subtract residual ---*/ + + numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + + LinSysRes.AddBlock(iPoint, Residual); + LinSysRes.SubtractBlock(jPoint, Residual); + + /*--- Implicit part ---*/ + + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + Jacobian.AddBlock(iPoint, jPoint, Jacobian_j); + Jacobian.SubtractBlock(jPoint, iPoint, Jacobian_i); + Jacobian.SubtractBlock(jPoint, jPoint, Jacobian_j); + + } + +} + +void CScalarSolver::Viscous_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) { + + unsigned long iEdge, iPoint, jPoint; + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Points in edge ---*/ + + iPoint = geometry->edge[iEdge]->GetNode(0); + jPoint = geometry->edge[iEdge]->GetNode(1); + + /*--- Points coordinates, and normal vector ---*/ + + numerics->SetCoord(geometry->node[iPoint]->GetCoord(), + geometry->node[jPoint]->GetCoord()); + numerics->SetNormal(geometry->edge[iEdge]->GetNormal()); + + /*--- Conservative variables w/o reconstruction ---*/ + + numerics->SetPrimitive(solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint), + solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(jPoint)); + + /*--- Scalar variables w/o reconstruction. ---*/ + + numerics->SetScalarVar(nodes->GetSolution(iPoint), + nodes->GetSolution(jPoint)); + + /*--- Scalar variable gradients. ---*/ + + numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), + nodes->GetGradient(jPoint)); + + /*--- Mass diffusivity coefficients. ---*/ + + numerics->SetDiffusionCoeff(nodes->GetDiffusivity(iPoint), + nodes->GetDiffusivity(jPoint)); + + /*--- Compute residuals and Jacobians ---*/ + + numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + + /*--- Add/subtract residual and update Jacobians ---*/ + + LinSysRes.SubtractBlock(iPoint, Residual); + LinSysRes.AddBlock(jPoint, Residual); + + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + Jacobian.SubtractBlock(iPoint, jPoint, Jacobian_j); + + Jacobian.AddBlock(jPoint, iPoint, Jacobian_i); + Jacobian.AddBlock(jPoint, jPoint, Jacobian_j); + + } + +} + +void CScalarSolver::ImplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) { + + unsigned short iVar; + unsigned long iPoint, total_index; + su2double Delta, *local_Res_TruncError, Vol; + + bool scalar_clipping = config->GetScalar_Clipping(); + su2double scalar_clipping_min = config->GetScalar_Clipping_Min(); + su2double scalar_clipping_max = config->GetScalar_Clipping_Max(); + + bool adjoint = ( config->GetContinuous_Adjoint() || + (config->GetDiscrete_Adjoint() && config->GetFrozen_Visc_Disc())); + bool incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); + + if (incompressible) SetPreconditioner(geometry, solver_container, config); + + /*--- Set maximum residual to zero ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + SetRes_RMS(iVar, 0.0); + SetRes_Max(iVar, 0.0, 0); + } + + /*--- Build implicit system ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Read the residual ---*/ + + local_Res_TruncError = nodes->GetResTruncError(iPoint); + + /*--- Read the volume ---*/ + + Vol = (geometry->node[iPoint]->GetVolume() + + geometry->node[iPoint]->GetPeriodicVolume()); + + /*--- Modify matrix diagonal to assure diagonal dominance ---*/ + + Delta = Vol / (config->GetCFLRedCoeff_Scalar()*solver_container[FLOW_SOL]->GetNodes()->GetDelta_Time(iPoint)); + Jacobian.AddVal2Diag(iPoint, Delta); + + /*--- Right hand side of the system (-Residual) and initial guess (x = 0) ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + total_index = iPoint*nVar+iVar; + LinSysRes[total_index] = - (LinSysRes[total_index] + local_Res_TruncError[iVar]); + LinSysSol[total_index] = 0.0; + AddRes_RMS(iVar, LinSysRes[total_index]*LinSysRes[total_index]); + AddRes_Max(iVar, fabs(LinSysRes[total_index]), + geometry->node[iPoint]->GetGlobalIndex(), + geometry->node[iPoint]->GetCoord()); + } + } + + /*--- Initialize residual and solution at the ghost points ---*/ + + for (iPoint = nPointDomain; iPoint < nPoint; iPoint++) { + for (iVar = 0; iVar < nVar; iVar++) { + total_index = iPoint*nVar + iVar; + LinSysRes[total_index] = 0.0; + LinSysSol[total_index] = 0.0; + } + } + + /*--- Solve or smooth the linear system ---*/ + + System.Solve(Jacobian, LinSysRes, LinSysSol, geometry, config); + + /*--- Update solution (system written in terms of increments) ---*/ + + if (!adjoint) { + + /*--- Update the scalar solution. ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + if (scalar_clipping) { + nodes->AddClippedSolution(iPoint, 0, config->GetRelaxation_Factor_Scalar()*LinSysSol[iPoint], + scalar_clipping_min, scalar_clipping_max); + } + else { + nodes->AddSolution(iPoint, 0, config->GetRelaxation_Factor_Scalar()*LinSysSol[iPoint]); + } + } + + } + + /*--- Communicate the solution at the periodic boundaries. ---*/ + + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { + InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); + CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); + } + + /*--- MPI solution ---*/ + + InitiateComms(geometry, config, SOLUTION); + CompleteComms(geometry, config, SOLUTION); + + /*--- Compute the root mean square residual ---*/ + + SetResidual_RMS(geometry, config); + +} + +void CScalarSolver::BC_Sym_Plane(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { + + /*--- Convective fluxes across symmetry plane are equal to zero. ---*/ + +} + +void CScalarSolver::BC_Euler_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short val_marker) { + + /*--- Convective fluxes across euler wall are equal to zero. ---*/ + +} + +void CScalarSolver::BC_HeatFlux_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { + + /*--- Convective fluxes across viscous walls are equal to zero. ---*/ + +} + +void CScalarSolver::BC_Isothermal_Wall(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { + + /*--- Convective fluxes across viscous walls are equal to zero. ---*/ + +} + +void CScalarSolver::BC_Far_Field(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { + + unsigned long iPoint, iVertex; + unsigned short iVar, iDim; + su2double *Normal, *V_infty, *V_domain; + + bool grid_movement = config->GetGrid_Movement(); + + Normal = new su2double[nDim]; + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- Allocate the value at the infinity ---*/ + + V_infty = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); + + /*--- Retrieve solution at the farfield boundary node ---*/ + + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); + + /*--- Grid Movement ---*/ + + if (grid_movement) + conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), + geometry->node[iPoint]->GetGridVel()); + + conv_numerics->SetPrimitive(V_domain, V_infty); + + /*--- Set scalar variable at the wall, and at infinity ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); + Solution_j[iVar] = Scalar_Inf[iVar]; + } + conv_numerics->SetScalarVar(Solution_i, Solution_j); + + /*--- Set Normal (it is necessary to change the sign) ---*/ + + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + for (iDim = 0; iDim < nDim; iDim++) + Normal[iDim] = -Normal[iDim]; + conv_numerics->SetNormal(Normal); + + /*--- Compute residuals and Jacobians ---*/ + + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + + /*--- Add residuals and Jacobians ---*/ + + LinSysRes.AddBlock(iPoint, Residual); + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + + } + } + + delete [] Normal; + +} + +void CScalarSolver::BC_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { + + unsigned short iDim, iVar; + unsigned long iVertex, iPoint; + su2double *V_inlet, *V_domain, *Normal; + + Normal = new su2double[nDim]; + + bool grid_movement = config->GetGrid_Movement(); + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + /*--- Loop over all the vertices on this boundary marker ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- Normal vector for this vertex (negate for outward convention) ---*/ + + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; + + /*--- Allocate the value at the inlet ---*/ + + V_inlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); + + /*--- Retrieve solution at the farfield boundary node ---*/ + + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); + + /*--- Set various quantities in the solver class ---*/ + + conv_numerics->SetPrimitive(V_domain, V_inlet); + + /*--- Set the scalar variable states (prescribed for an inflow) ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); + Solution_j[iVar] = Inlet_ScalarVars[val_marker][iVertex][iVar]; + } + conv_numerics->SetScalarVar(Solution_i, Solution_j); + + /*--- Set various other quantities in the conv_numerics class ---*/ + + conv_numerics->SetNormal(Normal); + + if (grid_movement) + conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), + geometry->node[iPoint]->GetGridVel()); + + /*--- Compute the residual using an upwind scheme ---*/ + + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + LinSysRes.AddBlock(iPoint, Residual); + + /*--- Jacobian contribution for implicit integration ---*/ + + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + + /*--- Viscous contribution, commented out because serious convergence problems ---*/ + + unsigned long Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); + visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); + visc_numerics->SetNormal(Normal); + + /*--- Conservative variables w/o reconstruction ---*/ + + visc_numerics->SetPrimitive(V_domain, V_inlet); + + /*--- Scalar variables w/o reconstruction, and its gradients ---*/ + + visc_numerics->SetScalarVar(Solution_i, Solution_j); + visc_numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), + nodes->GetGradient(iPoint)); + + /*--- Mass diffusivity coefficients. ---*/ + + visc_numerics->SetDiffusionCoeff(nodes->GetDiffusivity(iPoint), + nodes->GetDiffusivity(iPoint)); + + /*--- Compute residual, and Jacobians ---*/ + + visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + + /*--- Subtract residual, and update Jacobians ---*/ + + LinSysRes.SubtractBlock(iPoint, Residual); + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + + } + } + + /*--- Free locally allocated memory ---*/ + delete[] Normal; + +} + +void CScalarSolver::BC_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) { + + unsigned long iPoint, iVertex; + unsigned short iVar, iDim; + su2double *V_outlet, *V_domain, *Normal; + + bool grid_movement = config->GetGrid_Movement(); + + Normal = new su2double[nDim]; + + /*--- Loop over all the vertices on this boundary marker ---*/ + + for (iVertex = 0; iVertex < geometry->nVertex[val_marker]; iVertex++) { + iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ + + if (geometry->node[iPoint]->GetDomain()) { + + /*--- Allocate the value at the outlet ---*/ + + V_outlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); + + /*--- Retrieve solution at the farfield boundary node ---*/ + + V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); + + /*--- Set various quantities in the solver class ---*/ + + conv_numerics->SetPrimitive(V_domain, V_outlet); + + /*--- Set the scalar variables. Here we use a Neumann BC such + that the scalar variable is copied from the interior of the + domain to the outlet before computing the residual. + Solution_i --> ScalarVar_internal, + Solution_j --> ScalarVar_outlet ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Solution_i[iVar] = nodes->GetSolution(iPoint,iVar); + Solution_j[iVar] = nodes->GetSolution(iPoint,iVar); + } + conv_numerics->SetScalarVar(Solution_i, Solution_j); + + /*--- Set Normal (negate for outward convention) ---*/ + + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + for (iDim = 0; iDim < nDim; iDim++) + Normal[iDim] = -Normal[iDim]; + conv_numerics->SetNormal(Normal); + + if (grid_movement) + conv_numerics->SetGridVel(geometry->node[iPoint]->GetGridVel(), + geometry->node[iPoint]->GetGridVel()); + + /*--- Compute the residual using an upwind scheme ---*/ + + conv_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + LinSysRes.AddBlock(iPoint, Residual); + + /*--- Jacobian contribution for implicit integration ---*/ + + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + + /*--- Viscous contribution, commented out because serious convergence problems ---*/ + + unsigned long Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); + visc_numerics->SetCoord(geometry->node[iPoint]->GetCoord(), geometry->node[Point_Normal]->GetCoord()); + visc_numerics->SetNormal(Normal); + + /*--- Conservative variables w/o reconstruction ---*/ + + visc_numerics->SetPrimitive(V_domain, V_outlet); + + /*--- Scalar variables w/o reconstruction, and its gradients ---*/ + + visc_numerics->SetScalarVar(Solution_i, Solution_j); + visc_numerics->SetScalarVarGradient(nodes->GetGradient(iPoint), + nodes->GetGradient(iPoint)); + + /*--- Mass diffusivity coefficients. ---*/ + + visc_numerics->SetDiffusionCoeff(nodes->GetDiffusivity(iPoint), + nodes->GetDiffusivity(iPoint)); + + /*--- Compute residual, and Jacobians ---*/ + + visc_numerics->ComputeResidual(Residual, Jacobian_i, Jacobian_j, config); + + /*--- Subtract residual, and update Jacobians ---*/ + + LinSysRes.SubtractBlock(iPoint, Residual); + Jacobian.SubtractBlock(iPoint, iPoint, Jacobian_i); + + } + } + + /*--- Free locally allocated memory ---*/ + + delete [] Normal; + +} + +void CScalarSolver::BC_Periodic(CGeometry *geometry, CSolver **solver_container, + CNumerics *numerics, CConfig *config) { + + /*--- Complete residuals for periodic boundary conditions. We loop over + the periodic BCs in matching pairs so that, in the event that there are + adjacent periodic markers, the repeated points will have their residuals + accumulated corectly during the communications. For implicit calculations + the Jacobians and linear system are also correctly adjusted here. ---*/ + + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { + InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_RESIDUAL); + CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_RESIDUAL); + } + +} + +void CScalarSolver::SetInletAtVertex(su2double *val_inlet, + unsigned short iMarker, + unsigned long iVertex) { + unsigned short iVar; + + for (iVar = 0; iVar < nVar; iVar++) { + Inlet_ScalarVars[iMarker][iVertex][iVar] = val_inlet[Inlet_Position+iVar]; + } + +} + +su2double CScalarSolver::GetInletAtVertex(su2double *val_inlet, + unsigned long val_inlet_point, + unsigned short val_kind_marker, + string val_marker, + CGeometry *geometry, + CConfig *config) { + + /*--- Local variables ---*/ + + unsigned short iMarker, iDim, iVar; + unsigned long iPoint, iVertex; + su2double Area = 0.0; + su2double Normal[3] = {0.0,0.0,0.0}; + + /*--- Alias positions within inlet file for readability ---*/ + + if (val_kind_marker == INLET_FLOW) { + + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + if ((config->GetMarker_All_KindBC(iMarker) == INLET_FLOW) && + (config->GetMarker_All_TagBound(iMarker) == val_marker)) { + + for (iVertex = 0; iVertex < nVertex[iMarker]; iVertex++){ + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + if (iPoint == val_inlet_point) { + + /*-- Compute boundary face area for this vertex. ---*/ + + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + + /*--- Access and store the inlet variables for this vertex. ---*/ + + for (iVar = 0; iVar < nVar; iVar++) + val_inlet[Inlet_Position+iVar] = Inlet_ScalarVars[iMarker][iVertex][iVar]; + + /*--- Exit once we find the point. ---*/ + + return Area; + + } + } + } + } + + } + + /*--- If we don't find a match, then the child point is not on the + current inlet boundary marker. Return zero area so this point does + not contribute to the restriction operator and continue. ---*/ + + return Area; + +} + +void CScalarSolver::SetUniformInlet(CConfig* config, unsigned short iMarker) { + + for(unsigned long iVertex=0; iVertex < nVertex[iMarker]; iVertex++){ + for (unsigned short iVar = 0; iVar < nVar; iVar++) + Inlet_ScalarVars[iMarker][iVertex][iVar] = Scalar_Inf[iVar]; + } + +} + + + +void CScalarSolver::SetResidual_DualTime(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iRKStep, + unsigned short iMesh, + unsigned short RunTime_EqSystem) { + + /*--- Local variables ---*/ + + unsigned short iVar, jVar, iMarker, iDim; + unsigned long iPoint, jPoint, iEdge, iVertex; + + su2double *U_time_nM1, *U_time_n, *U_time_nP1; + su2double Volume_nM1, Volume_nP1, TimeStep; + su2double Density_nM1, Density_n, Density_nP1; + su2double *Normal = NULL, *GridVel_i = NULL, *GridVel_j = NULL, Residual_GCL; + + bool implicit = (config->GetKind_TimeIntScheme_Scalar() == EULER_IMPLICIT); + bool grid_movement = config->GetGrid_Movement(); + + bool incompressible = (config->GetKind_Regime() == INCOMPRESSIBLE); + + /*--- Store the physical time step ---*/ + + TimeStep = config->GetDelta_UnstTimeND(); + + /*--- Compute the dual time-stepping source term for static meshes ---*/ + + if (!grid_movement) { + + /*--- Loop over all nodes (excluding halos) ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Retrieve the solution at time levels n-1, n, and n+1. Note that + we are currently iterating on U^n+1 and that U^n & U^n-1 are fixed, + previous solutions that are stored in memory. ---*/ + + U_time_nM1 = nodes->GetSolution_time_n1(iPoint); + U_time_n = nodes->GetSolution_time_n(iPoint); + U_time_nP1 = nodes->GetSolution(iPoint); + + /*--- CV volume at time n+1. As we are on a static mesh, the volume + of the CV will remained fixed for all time steps. ---*/ + + Volume_nP1 = geometry->node[iPoint]->GetVolume(); + + /*--- Compute the dual time-stepping source term based on the chosen + time discretization scheme (1st- or 2nd-order).---*/ + + /*--- Get the density to compute the conservative variables. ---*/ + + if (incompressible){ + /*--- This is temporary and only valid for constant-density problems: + density could also be temperature dependent, but as it is not a part + of the solution vector it's neither stored for previous time steps + nor updated with the solution at the end of each iteration. */ + Density_nM1 = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + Density_nP1 = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + } + else{ + Density_nM1 = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n1(iPoint)[0]; + Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(iPoint)[0]; + Density_nP1 = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint)[0]; + } + + for (iVar = 0; iVar < nVar; iVar++) { + if (config->GetTime_Marching() == DT_STEPPING_1ST) + Residual[iVar] = ( Density_nP1*U_time_nP1[iVar] - Density_n*U_time_n[iVar])*Volume_nP1 / TimeStep; + if (config->GetTime_Marching() == DT_STEPPING_2ND) + Residual[iVar] = ( 3.0*Density_nP1*U_time_nP1[iVar] - 4.0*Density_n*U_time_n[iVar] + +1.0*Density_nM1*U_time_nM1[iVar])*Volume_nP1 / (2.0*TimeStep); + } + + + /*--- Store the residual and compute the Jacobian contribution due + to the dual time source term. ---*/ + + LinSysRes.AddBlock(iPoint, Residual); + if (implicit) { + for (iVar = 0; iVar < nVar; iVar++) { + for (jVar = 0; jVar < nVar; jVar++) Jacobian_i[iVar][jVar] = 0.0; + if (config->GetTime_Marching() == DT_STEPPING_1ST) + Jacobian_i[iVar][iVar] = Volume_nP1 / TimeStep; + if (config->GetTime_Marching() == DT_STEPPING_2ND) + Jacobian_i[iVar][iVar] = (Volume_nP1*3.0)/(2.0*TimeStep); + } + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + } + } + + } else { + + /*--- For unsteady flows on dynamic meshes (rigidly transforming or + dynamically deforming), the Geometric Conservation Law (GCL) should be + satisfied in conjunction with the ALE formulation of the governing + equations. The GCL prevents accuracy issues caused by grid motion, i.e. + a uniform free-stream should be preserved through a moving grid. First, + we will loop over the edges and boundaries to compute the GCL component + of the dual time source term that depends on grid velocities. ---*/ + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Get indices for nodes i & j plus the face normal ---*/ + + iPoint = geometry->edge[iEdge]->GetNode(0); + jPoint = geometry->edge[iEdge]->GetNode(1); + Normal = geometry->edge[iEdge]->GetNormal(); + + /*--- Grid velocities stored at nodes i & j ---*/ + + GridVel_i = geometry->node[iPoint]->GetGridVel(); + GridVel_j = geometry->node[jPoint]->GetGridVel(); + + /*--- Compute the GCL term by averaging the grid velocities at the + edge mid-point and dotting with the face normal. ---*/ + + Residual_GCL = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Residual_GCL += 0.5*(GridVel_i[iDim]+GridVel_j[iDim])*Normal[iDim]; + + /*--- Compute the GCL component of the source term for node i ---*/ + + U_time_n = nodes->GetSolution_time_n(iPoint); + + /*--- Multiply by density at node i ---*/ + + if (incompressible) Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); // Temporary fix + else Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(iPoint)[0]; + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = Density_n*U_time_n[iVar]*Residual_GCL; + + LinSysRes.AddBlock(iPoint, Residual); + + /*--- Compute the GCL component of the source term for node j ---*/ + + U_time_n = nodes->GetSolution_time_n(jPoint); + + /*--- Multiply by density at node j ---*/ + + if (incompressible) Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(jPoint); // Temporary fix + else Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(jPoint)[0]; + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = Density_n*U_time_n[iVar]*Residual_GCL; + + LinSysRes.SubtractBlock(jPoint, Residual); + + } + + /*--- Loop over the boundary edges ---*/ + + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { + if (config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + + /*--- Get the index for node i plus the boundary face normal ---*/ + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + + /*--- Grid velocities stored at boundary node i ---*/ + + GridVel_i = geometry->node[iPoint]->GetGridVel(); + + /*--- Compute the GCL term by dotting the grid velocity with the face + normal. The normal is negated to match the boundary convention. ---*/ + + Residual_GCL = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Residual_GCL -= 0.5*(GridVel_i[iDim]+GridVel_i[iDim])*Normal[iDim]; + + /*--- Compute the GCL component of the source term for node i ---*/ + + U_time_n = nodes->GetSolution_time_n(iPoint); + + /*--- Multiply by density at node i ---*/ + + if (incompressible) Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); // Temporary fix + else Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(iPoint)[0]; + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = Density_n*U_time_n[iVar]*Residual_GCL; + + LinSysRes.AddBlock(iPoint, Residual); + } + } + + /*--- Loop over all nodes (excluding halos) to compute the remainder + of the dual time-stepping source term. ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Retrieve the solution at time levels n-1, n, and n+1. Note that + we are currently iterating on U^n+1 and that U^n & U^n-1 are fixed, + previous solutions that are stored in memory. ---*/ + + U_time_nM1 = nodes->GetSolution_time_n1(iPoint); + U_time_n = nodes->GetSolution_time_n(iPoint); + U_time_nP1 = nodes->GetSolution(iPoint); + + /*--- CV volume at time n-1 and n+1. In the case of dynamically deforming + grids, the volumes will change. On rigidly transforming grids, the + volumes will remain constant. ---*/ + + Volume_nM1 = geometry->node[iPoint]->GetVolume_nM1(); + Volume_nP1 = geometry->node[iPoint]->GetVolume(); + + if (incompressible){ + /*--- This is temporary and only valid for constant-density problems: + density could also be temperature dependent, but as it is not a part + of the solution vector it's neither stored for previous time steps + nor updated with the solution at the end of each iteration. */ + Density_nM1 = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + Density_n = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + Density_nP1 = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint); + } + else{ + Density_nM1 = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n1(iPoint)[0]; + Density_n = solver_container[FLOW_SOL]->GetNodes()->GetSolution_time_n(iPoint)[0]; + Density_nP1 = solver_container[FLOW_SOL]->GetNodes()->GetSolution(iPoint)[0]; + } + + for (iVar = 0; iVar < nVar; iVar++) { + if (config->GetTime_Marching() == DT_STEPPING_1ST) + Residual[iVar] = (Density_nP1*U_time_nP1[iVar] - Density_n*U_time_n[iVar])*(Volume_nP1/TimeStep); + if (config->GetTime_Marching() == DT_STEPPING_2ND) + Residual[iVar] = (Density_nP1*U_time_nP1[iVar] - Density_n*U_time_n[iVar])*(3.0*Volume_nP1/(2.0*TimeStep)) + + (Density_nM1*U_time_nM1[iVar] - Density_n*U_time_n[iVar])*(Volume_nM1/(2.0*TimeStep)); + } + + /*--- Store the residual and compute the Jacobian contribution due + to the dual time source term. ---*/ + + LinSysRes.AddBlock(iPoint, Residual); + if (implicit) { // TDE density in Jacobian + for (iVar = 0; iVar < nVar; iVar++) { + for (jVar = 0; jVar < nVar; jVar++) Jacobian_i[iVar][jVar] = 0.0; + if (config->GetTime_Marching() == DT_STEPPING_1ST) + Jacobian_i[iVar][iVar] = Volume_nP1/TimeStep; + if (config->GetTime_Marching() == DT_STEPPING_2ND) + Jacobian_i[iVar][iVar] = (3.0*Volume_nP1)/(2.0*TimeStep); + } + Jacobian.AddBlock(iPoint, iPoint, Jacobian_i); + } + } + } + +} + +void CScalarSolver::LoadRestart(CGeometry **geometry, + CSolver ***solver, + CConfig *config, + int val_iter, + bool val_update_geo) { + + /*--- Restart the solution from file information ---*/ + + unsigned short iVar, iMesh; + unsigned long iPoint, index, iChildren, Point_Fine; + su2double Area_Children, Area_Parent, *Solution_Fine; + bool dual_time = ((config->GetTime_Marching() == DT_STEPPING_1ST) || + (config->GetTime_Marching() == DT_STEPPING_2ND)); + bool time_stepping = (config->GetTime_Marching() == TIME_STEPPING); + unsigned short iZone = config->GetiZone(); + unsigned short nZone = config->GetnZone(); + + string UnstExt, text_line; + ifstream restart_file; + + string restart_filename = config->GetFilename(config->GetSolution_FileName(), "", val_iter); + + bool turbulent = ((config->GetKind_Solver() == RANS) || + (config->GetKind_Solver() == DISC_ADJ_RANS)); + + unsigned short turbSkip = 0; + if (turbulent) turbSkip = solver[MESH_0][TURB_SOL]->GetnVar(); + + /*--- Read the restart data from either an ASCII or binary SU2 file. ---*/ + + if (config->GetRead_Binary_Restart()) { + Read_SU2_Restart_Binary(geometry[MESH_0], config, restart_filename); + } else { + Read_SU2_Restart_ASCII(geometry[MESH_0], config, restart_filename); + } + + int counter = 0; + long iPoint_Local = 0; unsigned long iPoint_Global = 0; + unsigned long iPoint_Global_Local = 0; + unsigned short rbuf_NotMatching = 0, sbuf_NotMatching = 0; + + /*--- Skip flow variables ---*/ + + unsigned short skipVars = 0; + + if (nDim == 2) skipVars += 6; + if (nDim == 3) skipVars += 8; + + /*--- Skip turbulent variables if necessary variables ---*/ + + if (turbulent) skipVars += turbSkip; + + /*--- Load data from the restart into correct containers. ---*/ + + counter = 0; + for (iPoint_Global = 0; iPoint_Global < geometry[MESH_0]->GetGlobal_nPointDomain(); iPoint_Global++ ) { + + /*--- Retrieve local index. If this node from the restart file lives + on the current processor, we will load and instantiate the vars. ---*/ + + iPoint_Local = geometry[MESH_0]->GetGlobal_to_Local_Point(iPoint_Global); + + if (iPoint_Local > -1) { + + /*--- We need to store this point's data, so jump to the correct + offset in the buffer of data from the restart file and load it. ---*/ + + index = counter*Restart_Vars[1] + skipVars; + for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = Restart_Data[index+iVar]; + nodes->SetSolution(iPoint_Local,Solution); + iPoint_Global_Local++; + + /*--- Increment the overall counter for how many points have been loaded. ---*/ + counter++; + } + + } + + /*--- Detect a wrong solution file ---*/ + + if (iPoint_Global_Local < nPointDomain) { sbuf_NotMatching = 1; } + +#ifndef HAVE_MPI + rbuf_NotMatching = sbuf_NotMatching; +#else + SU2_MPI::Allreduce(&sbuf_NotMatching, &rbuf_NotMatching, 1, + MPI_UNSIGNED_SHORT, MPI_SUM, MPI_COMM_WORLD); +#endif + if (rbuf_NotMatching != 0) { + SU2_MPI::Error(string("The solution file ") + restart_filename + string(" doesn't match with the mesh file!\n") + + string("It could be empty lines at the end of the file."), CURRENT_FUNCTION); + } + + /*--- MPI solution ---*/ + + solver[MESH_0][SCALAR_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); + solver[MESH_0][SCALAR_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); + + solver[MESH_0][FLOW_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); + solver[MESH_0][SCALAR_SOL]->Postprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0); + + /*--- Interpolate the solution down to the coarse multigrid levels ---*/ + + for (iMesh = 1; iMesh <= config->GetnMGLevels(); iMesh++) { + for (iPoint = 0; iPoint < geometry[iMesh]->GetnPoint(); iPoint++) { + Area_Parent = geometry[iMesh]->node[iPoint]->GetVolume(); + for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; + for (iChildren = 0; iChildren < geometry[iMesh]->node[iPoint]->GetnChildren_CV(); iChildren++) { + Point_Fine = geometry[iMesh]->node[iPoint]->GetChildren_CV(iChildren); + Area_Children = geometry[iMesh-1]->node[Point_Fine]->GetVolume(); + Solution_Fine = solver[iMesh-1][SCALAR_SOL]->GetNodes()->GetSolution(Point_Fine); + for (iVar = 0; iVar < nVar; iVar++) { + Solution[iVar] += Solution_Fine[iVar]*Area_Children/Area_Parent; + } + } + solver[iMesh][SCALAR_SOL]->GetNodes()->SetSolution(iPoint,Solution); + } + solver[iMesh][SCALAR_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); + solver[iMesh][SCALAR_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); + solver[iMesh][FLOW_SOL]->Preprocessing(geometry[iMesh], solver[iMesh], config, iMesh, NO_RK_ITER, RUNTIME_FLOW_SYS, false); + solver[iMesh][SCALAR_SOL]->Postprocessing(geometry[iMesh], solver[iMesh], config, iMesh); + } + + /*--- Delete the class memory that is used to load the restart. ---*/ + + if (Restart_Vars != NULL) delete [] Restart_Vars; + if (Restart_Data != NULL) delete [] Restart_Data; + Restart_Vars = NULL; Restart_Data = NULL; + +} diff --git a/SU2_CFD/src/transport_model.cpp b/SU2_CFD/src/transport_model.cpp index 117dc101a6dd..03d2bc977012 100644 --- a/SU2_CFD/src/transport_model.cpp +++ b/SU2_CFD/src/transport_model.cpp @@ -294,3 +294,62 @@ void CPolynomialConductivityRANS::SetConductivity(su2double T, su2double rho, su } +/*-----------------------------------------------------*/ +/*---------- Species Mass Diffusivity Models ----------*/ +/*-----------------------------------------------------*/ + +CDiffusivityModel::CDiffusivityModel(void) { + + /*--- Attributes initialization ---*/ + + Diffusivity = 0.0; + +} + +CDiffusivityModel::~CDiffusivityModel(void) { } + + +CConstantDiffusivity::CConstantDiffusivity(void) : CDiffusivityModel() { } + +CConstantDiffusivity::CConstantDiffusivity(su2double Diff_const) : CDiffusivityModel() { + + /*--- Attributes initialization ---*/ + + Diffusivity = Diff_const; + +} + +CConstantDiffusivity::~CConstantDiffusivity(void) { } + +CConstantSchmidt::CConstantSchmidt(void) : CDiffusivityModel() { } + +CConstantSchmidt::CConstantSchmidt(su2double sc_const) : CDiffusivityModel() { + + Schmidt_const = sc_const; + +} + +void CConstantSchmidt::SetDiffusivity(su2double T, su2double rho, su2double mu_lam, su2double mu_turb, su2double cp) { + + Diffusivity = mu_lam/(rho*Schmidt_const); + +} + +CConstantSchmidt::~CConstantSchmidt(void) { } + +CConstantSchmidtRANS::CConstantSchmidtRANS(void) : CDiffusivityModel() { } + +CConstantSchmidtRANS::CConstantSchmidtRANS(su2double sc_lam, su2double sc_turb) : CDiffusivityModel() { + + Schmidt_Lam = sc_lam; + Schmidt_Turb = sc_turb; + +} + +void CConstantSchmidtRANS::SetDiffusivity(su2double T, su2double rho, su2double mu_lam, su2double mu_turb, su2double cp) { + + Diffusivity = mu_lam/(rho*Schmidt_Lam) + mu_turb/(rho*Schmidt_Turb); + +} + +CConstantSchmidtRANS::~CConstantSchmidtRANS(void) { } diff --git a/SU2_CFD/src/variables/CIncEulerVariable.cpp b/SU2_CFD/src/variables/CIncEulerVariable.cpp index 1ef1113d6576..caab0b208b54 100644 --- a/SU2_CFD/src/variables/CIncEulerVariable.cpp +++ b/SU2_CFD/src/variables/CIncEulerVariable.cpp @@ -112,7 +112,10 @@ CIncEulerVariable::CIncEulerVariable(su2double pressure, const su2double *veloci /*--- If axisymmetric and viscous, we need an auxiliary gradient. ---*/ - if (axisymmetric && viscous) Grad_AuxVar.resize(nPoint,nDim); + if (axisymmetric && viscous) { + AuxVar.resize(nPoint); + Grad_AuxVar.resize(nPoint,nDim); + } if (config->GetMultizone_Problem()) Set_BGSSolution_k(); diff --git a/SU2_CFD/src/variables/CIncNSVariable.cpp b/SU2_CFD/src/variables/CIncNSVariable.cpp index 501a67559f92..8f6567c38f9f 100644 --- a/SU2_CFD/src/variables/CIncNSVariable.cpp +++ b/SU2_CFD/src/variables/CIncNSVariable.cpp @@ -99,8 +99,7 @@ bool CIncNSVariable::SetVorticity_StrainMag() { return false; } - -bool CIncNSVariable::SetPrimVar(unsigned long iPoint, su2double eddy_visc, su2double turb_ke, CFluidModel *FluidModel) { +bool CIncNSVariable::SetPrimVar(unsigned long iPoint, su2double eddy_visc, su2double turb_ke, su2double *scalar, CFluidModel *FluidModel) { unsigned short iVar; bool check_dens = false, check_temp = false, physical = true; diff --git a/SU2_CFD/src/variables/CNSVariable.cpp b/SU2_CFD/src/variables/CNSVariable.cpp index 635eff013ae0..14d8e192ab2a 100644 --- a/SU2_CFD/src/variables/CNSVariable.cpp +++ b/SU2_CFD/src/variables/CNSVariable.cpp @@ -193,7 +193,7 @@ void CNSVariable::SetRoe_Dissipation_FD(unsigned long iPoint, su2double val_wall AD::EndPreacc(); } -bool CNSVariable::SetPrimVar(unsigned long iPoint, su2double eddy_visc, su2double turb_ke, CFluidModel *FluidModel) { +bool CNSVariable::SetPrimVar(unsigned long iPoint, su2double eddy_visc, su2double turb_ke, su2double *scalar, CFluidModel *FluidModel) { bool RightVol = true; diff --git a/SU2_CFD/src/variables/CPassiveScalarVariable.cpp b/SU2_CFD/src/variables/CPassiveScalarVariable.cpp new file mode 100644 index 000000000000..eeab6d5db98f --- /dev/null +++ b/SU2_CFD/src/variables/CPassiveScalarVariable.cpp @@ -0,0 +1,75 @@ +/*! + * \file CPassiveScalarVariable.cpp + * \brief Definition of the variable fields for the passive scalar class. + * \author T. Economon + * \version 6.2.0 "Falcon" + * + * The current SU2 release has been coordinated by the + * SU2 International Developers Society + * with selected contributions from the open-source community. + * + * The main research teams contributing to the current release are: + * - Prof. Juan J. Alonso's group at Stanford University. + * - Prof. Piero Colonna's group at Delft University of Technology. + * - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology. + * - Prof. Alberto Guardone's group at Polytechnic University of Milan. + * - Prof. Rafael Palacios' group at Imperial College London. + * - Prof. Vincent Terrapon's group at the University of Liege. + * - Prof. Edwin van der Weide's group at the University of Twente. + * - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics. + * + * Copyright 2012-2019, Francisco D. Palacios, Thomas D. Economon, + * Tim Albring, and the SU2 contributors. + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#include "../../include/variables/CPassiveScalarVariable.hpp" + +CPassiveScalarVariable::CPassiveScalarVariable(su2double *val_scalar_inf, + unsigned long npoint, + unsigned long ndim, + unsigned long nvar, + CConfig *config) +: CScalarVariable(npoint, ndim, nvar, config) { + + for (unsigned long iPoint=0; iPointGetTime_Marching() == DT_STEPPING_1ST) || + (config->GetTime_Marching() == DT_STEPPING_2ND)); + + if (dual_time) { + Solution_time_n = Solution; + Solution_time_n1 = Solution; + } + + /*--- Allocate space for the mass diffusivity. ---*/ + + Diffusivity.resize(nPoint,nVar) = su2double(0.0); + + /*--- If axisymmetric and viscous, we need an auxiliary gradient. ---*/ + + if (config->GetAxisymmetric() && config->GetViscous()) { + AuxVar.resize(nPoint); + Grad_AuxVar.resize(nPoint,nDim); + } + +} diff --git a/SU2_CFD/src/variables/CScalarVariable.cpp b/SU2_CFD/src/variables/CScalarVariable.cpp new file mode 100644 index 000000000000..e0fa6819d6b6 --- /dev/null +++ b/SU2_CFD/src/variables/CScalarVariable.cpp @@ -0,0 +1,67 @@ +/*! + * \file CScalarVariable.cpp + * \brief Definition of the scalar equation variables at each vertex. + * \author T. Economon + * \version 6.1.0 "Falcon" + * + * The current SU2 release has been coordinated by the + * SU2 International Developers Society + * with selected contributions from the open-source community. + * + * The main research teams contributing to the current release are: + * - Prof. Juan J. Alonso's group at Stanford University. + * - Prof. Piero Colonna's group at Delft University of Technology. + * - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology. + * - Prof. Alberto Guardone's group at Polytechnic University of Milan. + * - Prof. Rafael Palacios' group at Imperial College London. + * - Prof. Vincent Terrapon's group at the University of Liege. + * - Prof. Edwin van der Weide's group at the University of Twente. + * - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics. + * + * Copyright 2012-2018, Francisco D. Palacios, Thomas D. Economon, + * Tim Albring, and the SU2 contributors. + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#include "../../include/variables/CScalarVariable.hpp" + +CScalarVariable::CScalarVariable(unsigned long npoint, + unsigned long ndim, + unsigned long nvar, + CConfig *config) +: CVariable(npoint, ndim, nvar, config) { + + /*--- Gradient related fields ---*/ + + Gradient.resize(nPoint,nVar,nDim,0.0); + + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + Rmatrix.resize(nPoint,nDim,nDim,0.0); + } + + /*--- Allocate residual structures ---*/ + + Res_TruncError.resize(nPoint,nVar) = su2double(0.0); + + /*--- Always allocate the slope limiter, and the auxiliar + variables (check the logic - JST with 2nd order Turb model) ---*/ + + Limiter.resize(nPoint,nVar) = su2double(0.0); + Solution_Max.resize(nPoint,nVar) = su2double(0.0); + Solution_Min.resize(nPoint,nVar) = su2double(0.0); + + Delta_Time.resize(nPoint) = su2double(0.0); + +} diff --git a/SU2_CFD/src/variables/CTransLMVariable.cpp b/SU2_CFD/src/variables/CTransLMVariable.cpp index 03a7d19ace45..09257a1f07cb 100644 --- a/SU2_CFD/src/variables/CTransLMVariable.cpp +++ b/SU2_CFD/src/variables/CTransLMVariable.cpp @@ -37,9 +37,13 @@ #include "../../include/variables/CTransLMVariable.hpp" - -CTransLMVariable::CTransLMVariable(su2double intermittency, su2double REth, unsigned long npoint, unsigned long ndim, - unsigned long nvar, CConfig *config) : CTurbVariable(npoint, ndim, nvar, config) { +CTransLMVariable::CTransLMVariable(su2double intermittency, + su2double REth, + unsigned long npoint, + unsigned long ndim, + unsigned long nvar, + CConfig *config) +: CScalarVariable(npoint, ndim, nvar, config) { for(unsigned long iPoint=0; iPointGetTime_Marching() == DT_STEPPING_1ST) || (config->GetTime_Marching() == DT_STEPPING_2ND)); - + if (dual_time) { Solution_time_n = Solution; Solution_time_n1 = Solution; } - + gamma_BC.resize(nPoint); DES_LengthScale.resize(nPoint) = su2double(0.0); Vortex_Tilting.resize(nPoint); + + /*--- Allocate space for the harmonic balance source terms ---*/ + + if (config->GetTime_Marching() == HARMONIC_BALANCE) { + HB_Source.resize(nPoint,nVar) = su2double(0.0); + } + } void CTurbSAVariable::SetVortex_Tilting(unsigned long iPoint, su2double **PrimGrad_Flow, diff --git a/SU2_CFD/src/variables/CTurbSSTVariable.cpp b/SU2_CFD/src/variables/CTurbSSTVariable.cpp index a381c3546085..46773b6c142e 100644 --- a/SU2_CFD/src/variables/CTurbSSTVariable.cpp +++ b/SU2_CFD/src/variables/CTurbSSTVariable.cpp @@ -37,26 +37,38 @@ #include "../../include/variables/CTurbSSTVariable.hpp" - -CTurbSSTVariable::CTurbSSTVariable(su2double kine, su2double omega, su2double mut, unsigned long npoint, unsigned long ndim, unsigned long nvar, const su2double* constants, CConfig *config) - : CTurbVariable(npoint, ndim, nvar, config) { - - for(unsigned long iPoint=0; iPointGetTime_Marching() == HARMONIC_BALANCE) { + HB_Source.resize(nPoint,nVar) = su2double(0.0); + } + } void CTurbSSTVariable::SetBlendingFunc(unsigned long iPoint, su2double val_viscosity, @@ -66,8 +78,8 @@ void CTurbSSTVariable::SetBlendingFunc(unsigned long iPoint, su2double val_visco AD::StartPreacc(); AD::SetPreaccIn(val_viscosity); AD::SetPreaccIn(val_dist); AD::SetPreaccIn(val_density); - AD::SetPreaccIn(Solution[iPoint], nVar); - AD::SetPreaccIn(Gradient[iPoint], nVar, nDim); + AD::SetPreaccIn(Solution[iPoint], (int)nVar); + AD::SetPreaccIn(Gradient[iPoint], (int)nVar, nDim); /*--- Cross diffusion ---*/ diff --git a/SU2_CFD/src/variables/CTurbVariable.cpp b/SU2_CFD/src/variables/CTurbVariable.cpp index adf0c328b6ba..7593a09797f9 100644 --- a/SU2_CFD/src/variables/CTurbVariable.cpp +++ b/SU2_CFD/src/variables/CTurbVariable.cpp @@ -63,4 +63,5 @@ CTurbVariable::CTurbVariable(unsigned long npoint, unsigned long ndim, unsigned Solution_Min.resize(nPoint,nVar) = su2double(0.0); Delta_Time.resize(nPoint) = su2double(0.0); + } diff --git a/SU2_IDE/Xcode/SU2_CFD.xcodeproj/project.pbxproj b/SU2_IDE/Xcode/SU2_CFD.xcodeproj/project.pbxproj index 3e94d826140d..7a9c8f1cfe2f 100644 --- a/SU2_IDE/Xcode/SU2_CFD.xcodeproj/project.pbxproj +++ b/SU2_IDE/Xcode/SU2_CFD.xcodeproj/project.pbxproj @@ -127,13 +127,15 @@ E9225F761FCBC36D002F3682 /* solver_adjoint_elasticity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E9225F741FCBC36D002F3682 /* solver_adjoint_elasticity.cpp */; }; E941BB8E1B71D0D0005C6C06 /* solver_adjoint_discrete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E941BB8D1B71D0D0005C6C06 /* solver_adjoint_discrete.cpp */; }; E941BB941B71D124005C6C06 /* mpi_structure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E941BB911B71D124005C6C06 /* mpi_structure.cpp */; }; + E96766A4237B31E0009FBEE1 /* numerics_direct_scalar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E96766A3237B31E0009FBEE1 /* numerics_direct_scalar.cpp */; }; + E96766A6237B3230009FBEE1 /* CScalarVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E96766A5237B322F009FBEE1 /* CScalarVariable.cpp */; }; + E96766A9237B4EE9009FBEE1 /* CPassiveScalarVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E96766A8237B4EE9009FBEE1 /* CPassiveScalarVariable.cpp */; }; + E96766AD237BB889009FBEE1 /* CScalarSolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E96766AB237BB888009FBEE1 /* CScalarSolver.cpp */; }; + E96766AE237BB889009FBEE1 /* CPassiveScalarSolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E96766AC237BB889009FBEE1 /* CPassiveScalarSolver.cpp */; }; E96FAF102189FE9C0046BF5D /* blas_structure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E96FAF0F2189FE9C0046BF5D /* blas_structure.cpp */; }; E96FAF142189FECA0046BF5D /* graph_coloring_structure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E96FAF112189FECA0046BF5D /* graph_coloring_structure.cpp */; }; E96FAF152189FECA0046BF5D /* fem_gauss_jacobi_quadrature.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E96FAF122189FECA0046BF5D /* fem_gauss_jacobi_quadrature.cpp */; }; E96FAF162189FECA0046BF5D /* fem_cgns_elements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E96FAF132189FECA0046BF5D /* fem_cgns_elements.cpp */; }; - E97429B0231F1577006DA2D3 /* CMeshSolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E97429AE231F1576006DA2D3 /* CMeshSolver.cpp */; }; - E97429B1231F1577006DA2D3 /* CDiscAdjMeshSolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E97429AF231F1577006DA2D3 /* CDiscAdjMeshSolver.cpp */; }; - E97429BF231F1614006DA2D3 /* CMeshElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E97429B8231F1613006DA2D3 /* CMeshElement.cpp */; }; E9C8307F2061E60E004417A9 /* fem_geometry_structure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E9C830752061E60E004417A9 /* fem_geometry_structure.cpp */; }; E9C830802061E60E004417A9 /* fem_integration_rules.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E9C830762061E60E004417A9 /* fem_integration_rules.cpp */; }; E9C830812061E60E004417A9 /* fem_standard_element.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E9C830772061E60E004417A9 /* fem_standard_element.cpp */; }; @@ -416,6 +418,15 @@ E941BBA31B71D1AB005C6C06 /* primitive_structure.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; lineEnding = 0; path = primitive_structure.inl; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E941BBA51B71D1AB005C6C06 /* mpi_structure.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = mpi_structure.hpp; path = ../../Common/include/mpi_structure.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E941BBA61B71D1AB005C6C06 /* mpi_structure.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; lineEnding = 0; name = mpi_structure.inl; path = ../../Common/include/mpi_structure.inl; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; + E96766A3237B31E0009FBEE1 /* numerics_direct_scalar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = numerics_direct_scalar.cpp; path = ../../SU2_CFD/src/numerics_direct_scalar.cpp; sourceTree = ""; }; + E96766A5237B322F009FBEE1 /* CScalarVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CScalarVariable.cpp; path = ../../SU2_CFD/src/variables/CScalarVariable.cpp; sourceTree = ""; }; + E96766A7237B3286009FBEE1 /* CScalarVariable.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CScalarVariable.hpp; path = ../../SU2_CFD/include/variables/CScalarVariable.hpp; sourceTree = ""; }; + E96766A8237B4EE9009FBEE1 /* CPassiveScalarVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CPassiveScalarVariable.cpp; path = ../../SU2_CFD/src/variables/CPassiveScalarVariable.cpp; sourceTree = ""; }; + E96766AA237B4F28009FBEE1 /* CPassiveScalarVariable.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CPassiveScalarVariable.hpp; path = ../../SU2_CFD/include/variables/CPassiveScalarVariable.hpp; sourceTree = ""; }; + E96766AB237BB888009FBEE1 /* CScalarSolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CScalarSolver.cpp; path = ../../SU2_CFD/src/solvers/CScalarSolver.cpp; sourceTree = ""; }; + E96766AC237BB889009FBEE1 /* CPassiveScalarSolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CPassiveScalarSolver.cpp; path = ../../SU2_CFD/src/solvers/CPassiveScalarSolver.cpp; sourceTree = ""; }; + E96766AF237BB917009FBEE1 /* CPassiveScalarSolver.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CPassiveScalarSolver.hpp; path = ../../SU2_CFD/include/solvers/CPassiveScalarSolver.hpp; sourceTree = ""; }; + E96766B0237BB918009FBEE1 /* CScalarSolver.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CScalarSolver.hpp; path = ../../SU2_CFD/include/solvers/CScalarSolver.hpp; sourceTree = ""; }; E96FAF0F2189FE9C0046BF5D /* blas_structure.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = blas_structure.cpp; path = ../../Common/src/blas_structure.cpp; sourceTree = ""; }; E96FAF112189FECA0046BF5D /* graph_coloring_structure.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = graph_coloring_structure.cpp; path = ../../Common/src/graph_coloring_structure.cpp; sourceTree = ""; }; E96FAF122189FECA0046BF5D /* fem_gauss_jacobi_quadrature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fem_gauss_jacobi_quadrature.cpp; path = ../../Common/src/fem_gauss_jacobi_quadrature.cpp; sourceTree = ""; }; @@ -425,9 +436,6 @@ E96FAF1B2189FF620046BF5D /* fem_gauss_jacobi_quadrature.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = fem_gauss_jacobi_quadrature.inl; path = ../../Common/include/fem_gauss_jacobi_quadrature.inl; sourceTree = ""; }; E96FAF1C2189FF620046BF5D /* fem_cgns_elements.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = fem_cgns_elements.hpp; path = ../../Common/include/fem_cgns_elements.hpp; sourceTree = ""; }; E96FAF1D2189FF620046BF5D /* fem_gauss_jacobi_quadrature.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = fem_gauss_jacobi_quadrature.hpp; path = ../../Common/include/fem_gauss_jacobi_quadrature.hpp; sourceTree = ""; }; - E97429AE231F1576006DA2D3 /* CMeshSolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CMeshSolver.cpp; path = ../../SU2_CFD/src/solvers/CMeshSolver.cpp; sourceTree = ""; }; - E97429AF231F1577006DA2D3 /* CDiscAdjMeshSolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CDiscAdjMeshSolver.cpp; path = ../../SU2_CFD/src/solvers/CDiscAdjMeshSolver.cpp; sourceTree = ""; }; - E97429B8231F1613006DA2D3 /* CMeshElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CMeshElement.cpp; path = ../../SU2_CFD/src/variables/CMeshElement.cpp; sourceTree = ""; }; E97B6C8117F941800008255B /* config_template.cfg */ = {isa = PBXFileReference; lastKnownFileType = text; name = config_template.cfg; path = ../../config_template.cfg; sourceTree = ""; }; E9C2835022A701B5007B4E59 /* CMMSNSTwoHalfSpheresSolution.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CMMSNSTwoHalfSpheresSolution.hpp; path = ../../Common/include/toolboxes/MMS/CMMSNSTwoHalfSpheresSolution.hpp; sourceTree = ""; }; E9C2835122A701B5007B4E59 /* CMMSNSTwoHalfCirclesSolution.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CMMSNSTwoHalfCirclesSolution.hpp; path = ../../Common/include/toolboxes/MMS/CMMSNSTwoHalfCirclesSolution.hpp; sourceTree = ""; }; @@ -528,6 +536,8 @@ children = ( E9D6EE662317B80600618E36 /* CDiscAdjMeshSolver.cpp */, E9D6EE652317B80500618E36 /* CMeshSolver.cpp */, + E96766AC237BB889009FBEE1 /* CPassiveScalarSolver.cpp */, + E96766AB237BB888009FBEE1 /* CScalarSolver.cpp */, E941BB8D1B71D0D0005C6C06 /* solver_adjoint_discrete.cpp */, E9225F741FCBC36D002F3682 /* solver_adjoint_elasticity.cpp */, 05E6DBDA17EB62A100FA1F7E /* solver_adjoint_mean.cpp */, @@ -667,8 +677,10 @@ EB14FF9F22F790720045FB27 /* CMultizoneDriver.hpp */, E9C2835622A701B5007B4E59 /* CNSUnitQuadSolution.hpp */, 05E6DAC517EB608000FA1F7E /* config_structure.hpp */, + E96766AF237BB917009FBEE1 /* CPassiveScalarSolver.hpp */, E9E674382302A942009B6A25 /* CRectangularMeshReaderFVM.hpp */, E9C2835822A701B5007B4E59 /* CRinglebSolution.hpp */, + E96766B0237BB918009FBEE1 /* CScalarSolver.hpp */, EB14FF9E22F790720045FB27 /* CSinglezoneDriver.hpp */, E9D6EE5E2316655400618E36 /* CSU2ASCIIMeshReaderFVM.hpp */, E9C2835922A701B5007B4E59 /* CTGVSolution.hpp */, @@ -733,6 +745,7 @@ 05E6DBC917EB62A100FA1F7E /* numerics_direct_heat.cpp */, E9F130C61D513DA300EC8963 /* numerics_direct_mean_inc.cpp */, 05E6DBCB17EB62A100FA1F7E /* numerics_direct_mean.cpp */, + E96766A3237B31E0009FBEE1 /* numerics_direct_scalar.cpp */, 05E6DBCE17EB62A100FA1F7E /* numerics_direct_transition.cpp */, 05E6DBCF17EB62A100FA1F7E /* numerics_direct_turbulent.cpp */, 05E6DBD317EB62A100FA1F7E /* numerics_structure.cpp */, @@ -778,7 +791,6 @@ 0541ABE41370DC56002D668B /* InLine */, 0541ABE51370DC5E002D668B /* Include */, 1AB674ADFE9D54B511CA2CBB /* Products */, - 403426B0235F8376005B5215 /* Recovered References */, ); name = SU2_CFD; sourceTree = ""; @@ -824,16 +836,6 @@ name = Products; sourceTree = ""; }; - 403426B0235F8376005B5215 /* Recovered References */ = { - isa = PBXGroup; - children = ( - E97429AE231F1576006DA2D3 /* CMeshSolver.cpp */, - E97429B8231F1613006DA2D3 /* CMeshElement.cpp */, - E97429AF231F1577006DA2D3 /* CDiscAdjMeshSolver.cpp */, - ); - name = "Recovered References"; - sourceTree = ""; - }; 403426D3235F857D005B5215 /* Output */ = { isa = PBXGroup; children = ( @@ -977,6 +979,8 @@ E9D6EE6F2317B88F00618E36 /* CMeshElement.cpp */, E9D6EE712317B88F00618E36 /* CMeshVariable.cpp */, E90B4FF522DFDFE4000ED392 /* CNSVariable.cpp */, + E96766A8237B4EE9009FBEE1 /* CPassiveScalarVariable.cpp */, + E96766A5237B322F009FBEE1 /* CScalarVariable.cpp */, E90B4FF322DFDFE3000ED392 /* CTransLMVariable.cpp */, E90B4FF722DFDFE4000ED392 /* CTurbSAVariable.cpp */, E90B4FF022DFDFE3000ED392 /* CTurbSSTVariable.cpp */, @@ -1017,6 +1021,8 @@ E9D6EE822317B8CC00618E36 /* CMeshBoundVariable.hpp */, E9D6EE7F2317B8CC00618E36 /* CMeshVariable.hpp */, E90B504122DFE4B7000ED392 /* CNSVariable.hpp */, + E96766AA237B4F28009FBEE1 /* CPassiveScalarVariable.hpp */, + E96766A7237B3286009FBEE1 /* CScalarVariable.hpp */, E90B504D22DFE4B9000ED392 /* CTransLMVariable.hpp */, E90B503F22DFE4B7000ED392 /* CTurbSAVariable.hpp */, E90B503D22DFE4B7000ED392 /* CTurbSSTVariable.hpp */, @@ -1142,6 +1148,7 @@ E90B500722DFDFE4000ED392 /* CNSVariable.cpp in Sources */, 05E6DB9217EB61E600FA1F7E /* config_structure.cpp in Sources */, E96FAF142189FECA0046BF5D /* graph_coloring_structure.cpp in Sources */, + E96766A9237B4EE9009FBEE1 /* CPassiveScalarVariable.cpp in Sources */, 4040B27F235FBFF200843C83 /* CTecplotBinaryFileWriter.cpp in Sources */, 05E6DB9317EB61E600FA1F7E /* dual_grid_structure.cpp in Sources */, E96FAF152189FECA0046BF5D /* fem_gauss_jacobi_quadrature.cpp in Sources */, @@ -1161,6 +1168,7 @@ 4040B27C235FBFF200843C83 /* CParaviewBinaryFileWriter.cpp in Sources */, 05E6DB9617EB61E600FA1F7E /* grid_movement_structure.cpp in Sources */, 403426CF235F83B2005B5215 /* output_physics.cpp in Sources */, + E96766A4237B31E0009FBEE1 /* numerics_direct_scalar.cpp in Sources */, 4040B25E235FBEFD00843C83 /* CDisplacementsInterfaceLegacy.cpp in Sources */, E90B4FDF22DFDF94000ED392 /* CInviscidVortexSolution.cpp in Sources */, 4040B280235FBFF200843C83 /* CSU2FileWriter.cpp in Sources */, @@ -1176,6 +1184,7 @@ 4040B281235FBFF200843C83 /* CFVMDataSorter.cpp in Sources */, 05E6DC0117EB62A100FA1F7E /* definition_structure.cpp in Sources */, 05E6DC0317EB62A100FA1F7E /* integration_structure.cpp in Sources */, + E96766A6237B3230009FBEE1 /* CScalarVariable.cpp in Sources */, E9D6EE782317B88F00618E36 /* CMeshVariable.cpp in Sources */, 403426CA235F83B2005B5215 /* CFlowCompOutput.cpp in Sources */, E9E51ADD22FAB11800773E0C /* CCGNSMeshReaderFVM.cpp in Sources */, @@ -1187,7 +1196,6 @@ 4040B25F235FBEFD00843C83 /* CDisplacementsInterface.cpp in Sources */, E9D6EE572316522800618E36 /* (null) in Sources */, 05F1089B1978D2AE00F2F288 /* fluid_model_ppr.cpp in Sources */, - E97429B0231F1577006DA2D3 /* CMeshSolver.cpp in Sources */, E941BB8E1B71D0D0005C6C06 /* solver_adjoint_discrete.cpp in Sources */, 05E6DC0517EB62A100FA1F7E /* iteration_structure.cpp in Sources */, 403426CC235F83B2005B5215 /* CFlowCompFEMOutput.cpp in Sources */, @@ -1201,6 +1209,8 @@ E9D6EE682317B80600618E36 /* CDiscAdjMeshSolver.cpp in Sources */, 4040B282235FBFF200843C83 /* CParaviewFileWriter.cpp in Sources */, E9FDF6EA1D2DD0560066E49C /* adt_structure.cpp in Sources */, + E96766AE237BB889009FBEE1 /* CPassiveScalarSolver.cpp in Sources */, + E96766AD237BB889009FBEE1 /* CScalarSolver.cpp in Sources */, 05E6DC0E17EB62A100FA1F7E /* numerics_direct_heat.cpp in Sources */, E90B500422DFDFE4000ED392 /* CTurbVariable.cpp in Sources */, E90D35F7203F9C5800A3290D /* fluid_model_inc.cpp in Sources */, @@ -1266,7 +1276,6 @@ E90B4FFD22DFDFE4000ED392 /* CDiscAdjFEAVariable.cpp in Sources */, 05E6DC2A17EB62A100FA1F7E /* solver_direct_transition.cpp in Sources */, E90B4FF822DFDFE4000ED392 /* CVariable.cpp in Sources */, - E97429BF231F1614006DA2D3 /* CMeshElement.cpp in Sources */, 4040B262235FBEFD00843C83 /* CMixingPlaneInterface.cpp in Sources */, E90B4FE122DFDF94000ED392 /* CMMSIncEulerSolution.cpp in Sources */, E9F130CC1D513DA300EC8963 /* numerics_direct_mean_inc.cpp in Sources */, @@ -1294,7 +1303,6 @@ E90B4FFB22DFDFE4000ED392 /* CAdjNSVariable.cpp in Sources */, 403426C7235F83B2005B5215 /* CMeshOutput.cpp in Sources */, E90B500F22DFE043000ED392 /* CSysVector.cpp in Sources */, - E97429B1231F1577006DA2D3 /* CDiscAdjMeshSolver.cpp in Sources */, E90B4FDA22DFDF94000ED392 /* CNSUnitQuadSolution.cpp in Sources */, E9C830802061E60E004417A9 /* fem_integration_rules.cpp in Sources */, E90B501222DFE043000ED392 /* CSysSolve.cpp in Sources */,