From 647ef5d8b79aa123a4722daf68340e71844df25f Mon Sep 17 00:00:00 2001 From: Nitish Anand Date: Tue, 13 Feb 2024 16:37:17 +0100 Subject: [PATCH 1/6] changes to make PBFlow solver upgraded to V8 --- Common/include/CConfig.hpp | 97 ++++++++- Common/include/geometry/CGeometry.hpp | 5 + Common/include/geometry/CPhysicalGeometry.hpp | 5 + Common/include/option_structure.hpp | 47 ++++- Common/src/CConfig.cpp | 22 ++ Common/src/geometry/CPhysicalGeometry.cpp | 58 ++++++ SU2_CFD/include/integration/CIntegration.hpp | 7 + .../integration/CMultiGridIntegration.hpp | 8 + SU2_CFD/include/numerics/CNumerics.hpp | 125 +++++++++++- .../numerics/scalar/scalar_convection.hpp | 3 +- SU2_CFD/include/output/CFlowIncOutput.hpp | 1 + .../include/solvers/CFVMFlowSolverBase.hpp | 8 +- .../include/solvers/CFVMFlowSolverBase.inl | 3 +- SU2_CFD/include/solvers/CScalarSolver.hpp | 4 +- SU2_CFD/include/solvers/CScalarSolver.inl | 4 +- SU2_CFD/include/solvers/CSolver.hpp | 59 ++++++ SU2_CFD/include/solvers/CSolverFactory.hpp | 1 + SU2_CFD/include/variables/CIncNSVariable.hpp | 5 + SU2_CFD/include/variables/CNSVariable.hpp | 5 + .../include/variables/CPrimitiveIndices.hpp | 4 +- SU2_CFD/include/variables/CVariable.hpp | 126 ++++++++++++ SU2_CFD/src/drivers/CDriver.cpp | 85 +++++++- SU2_CFD/src/integration/CIntegration.cpp | 3 + .../src/integration/CMultiGridIntegration.cpp | 188 +++++++++++++++++ SU2_CFD/src/iteration/CIterationFactory.cpp | 6 + SU2_CFD/src/meson.build | 16 +- SU2_CFD/src/numerics/CNumerics.cpp | 189 +++++++++++++++++- SU2_CFD/src/numerics/flow/flow_sources.cpp | 7 +- SU2_CFD/src/output/CFlowIncOutput.cpp | 136 +++++++++---- SU2_CFD/src/output/CFlowOutput.cpp | 7 +- SU2_CFD/src/solvers/CIncEulerSolver.cpp | 4 + SU2_CFD/src/solvers/CSolver.cpp | 39 +++- SU2_CFD/src/solvers/CSolverFactory.cpp | 39 +++- SU2_CFD/src/solvers/CTurbSASolver.cpp | 3 +- SU2_CFD/src/variables/CIncNSVariable.cpp | 52 +++++ SU2_CFD/src/variables/CNSVariable.cpp | 53 +++++ 36 files changed, 1349 insertions(+), 75 deletions(-) diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 910be2231acc..5ce787b64b22 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -133,7 +133,8 @@ class CConfig { Sens_Remove_Sharp, /*!< \brief Flag for removing or not the sharp edges from the sensitivity computation. */ Hold_GridFixed, /*!< \brief Flag hold fixed some part of the mesh during the deformation. */ Axisymmetric, /*!< \brief Flag for axisymmetric calculations */ - Integrated_HeatFlux; /*!< \brief Flag for heat flux BC whether it deals with integrated values.*/ + Integrated_HeatFlux, /*!< \brief Flag for heat flux BC whether it deals with integrated values.*/ + Pressure_based; /*!< \brief Flag to check if we are using a pressure-based system.*/ su2double Buffet_k; /*!< \brief Sharpness coefficient for buffet sensor.*/ su2double Buffet_lambda; /*!< \brief Offset parameter for buffet sensor.*/ su2double Damp_Engine_Inflow; /*!< \brief Damping factor for the engine inlet. */ @@ -524,6 +525,7 @@ class CConfig { Kind_TimeIntScheme_AdjTurb, /*!< \brief Time integration for the adjoint turbulence model. */ Kind_TimeIntScheme_Species, /*!< \brief Time integration for the species model. */ Kind_TimeIntScheme_Heat, /*!< \brief Time integration for the wave equations. */ + Kind_TimeIntScheme_Poisson, /*!< \brief Time integration for the poisson(pressure correction) equation. */ Kind_TimeStep_Heat, /*!< \brief Time stepping method for the (fvm) heat equation. */ n_Datadriven_files; ENUM_DATADRIVEN_METHOD Kind_DataDriven_Method; /*!< \brief Method used for datset regression in data-driven fluid models. */ @@ -574,6 +576,12 @@ class CConfig { Kind_Upwind_Heat, /*!< \brief Upwind scheme for the heat transfer model. */ Kind_Upwind_Template; /*!< \brief Upwind scheme for the template model. */ + ENUM_PBITER /*!< \brief Pressure-based solver for incompressible flows. */ + Kind_PBIter; + ENUM_INCOMP_SYSTEM + Kind_Incomp_System; + + bool MUSCL, /*!< \brief MUSCL scheme .*/ MUSCL_Flow, /*!< \brief MUSCL scheme for the flow equations.*/ MUSCL_Turb, /*!< \brief MUSCL scheme for the turbulence equations.*/ @@ -617,12 +625,15 @@ class CConfig { su2double Deform_Linear_Solver_Error; /*!< \brief Min error of the linear solver for the implicit formulation. */ su2double Linear_Solver_Smoother_Relaxation; /*!< \brief Relaxation factor for iterative linear smoothers. */ unsigned long Linear_Solver_Iter; /*!< \brief Max iterations of the linear solver for the implicit formulation. */ + unsigned long Poisson_Linear_Solver_Iter; /*!< \brief Max iterations of the linear solver for the implicit formulation. */ unsigned long Deform_Linear_Solver_Iter; /*!< \brief Max iterations of the linear solver for the implicit formulation. */ unsigned long Linear_Solver_Restart_Frequency; /*!< \brief Restart frequency of the linear solver for the implicit formulation. */ unsigned long Linear_Solver_Prec_Threads; /*!< \brief Number of threads per rank for ILU and LU_SGS preconditioners. */ unsigned short Linear_Solver_ILU_n; /*!< \brief ILU fill=in level. */ su2double SemiSpan; /*!< \brief Wing Semi span. */ su2double Roe_Kappa; /*!< \brief Relaxation of the Roe scheme. */ + su2double RCFactor; /*!< \brief Relaxation for Rhie Chow interpolation contribution. */ + su2double Relaxation_Factor_PBFlow; /*!< \brief Relaxation coefficient of the flow corrections in PB solver. */ su2double Relaxation_Factor_Adjoint; /*!< \brief Relaxation coefficient for variable updates of adjoint solvers. */ su2double Relaxation_Factor_CHT; /*!< \brief Relaxation coefficient for the update of conjugate heat variables. */ su2double EntropyFix_Coeff; /*!< \brief Entropy fix coefficient. */ @@ -860,6 +871,11 @@ class CConfig { su2double Schmidt_Number_Laminar; /*!< \brief Laminar Schmidt number for mass diffusion. */ su2double Schmidt_Number_Turbulent; /*!< \brief Turbulent Schmidt number for mass diffusion. */ su2double *Constant_Lewis_Number; /*!< \brief Different Lewis number for mass diffusion. */ + + su2double Mu_ConstantND, /*!< \brief Non-dimensional constant viscosity for ConstantViscosity model. */ + Kt_ConstantND, /*!< \brief Non-dimensional constant thermal conductivity for ConstantConductivity model. */ + Mu_SND, /*!< \brief Non-dimensional reference S for Sutherland model. */ + Mu_Temperature_RefND; /*!< \brief Non-dimensional reference temperature for Sutherland model. */ array CpPolyCoefficientsND{{0.0}}; /*!< \brief Definition of the non-dimensional temperature polynomial coefficients for specific heat Cp. */ array MuPolyCoefficientsND{{0.0}}; /*!< \brief Definition of the non-dimensional temperature polynomial coefficients for viscosity. */ array KtPolyCoefficientsND{{0.0}}; /*!< \brief Definition of the non-dimensional temperature polynomial coefficients for thermal conductivity. */ @@ -3818,6 +3834,33 @@ class CConfig { */ ENUM_REGIME GetKind_Regime(void) const { return Kind_Regime; } + /*! + * \brief Governing equations of the flow (it can be different from the run time equation). + * \param[in] val_zone - Zone where the soler is applied. + * \return Governing equation that we are solving. + */ + ENUM_INCOMP_SYSTEM GetKind_Incomp_System(void) const { return Kind_Incomp_System; } + + /*! + * \brief Governing equations of the flow (it can be different from the run time equation). + * \param[in] val_zone - Zone where the soler is applied. + * \return Governing equation that we are solving. + */ + ENUM_PBITER GetKind_PBIter(void) const { return Kind_PBIter; } + + /*! + * \brief Governing equations of the flow (it can be different from the run time equation). + * \param[in] val_zone - Zone where the soler is applied. + * \return Governing equation that we are solving. + */ + void SetIncomp_System(unsigned short val_system); + + /*! + * \brief Governing equations of the flow (it can be different from the run time equation). + * \param[in] val_zone - Zone where the soler is applied. + * \return Governing equation that we are solving. + */ + void SetPBIter(unsigned short val_PBIter); /*! * \brief Governing equations of the flow (it can be different from the run time equation). * \param[in] val_zone - Zone where the soler is applied. @@ -4124,6 +4167,31 @@ class CConfig { */ const su2double* GetKt_PolyCoeffND(void) const { return KtPolyCoefficientsND.data(); } + /*! + * \brief Set the value of the non-dimensional constant viscosity. + */ + void SetMu_ConstantND(su2double mu_const) { Mu_ConstantND = mu_const; } + + /*! + * \brief Set the value of the non-dimensional thermal conductivity. + */ + void SetKt_ConstantND(su2double kt_const) { Kt_ConstantND = kt_const; } + + /*! + * \brief Set the value of the non-dimensional reference viscosity for Sutherland model. + */ + // void SetMu_RefND(su2double mu_ref) { Mu_RefND = mu_ref; } + + /*! + * \brief Set the value of the non-dimensional reference temperature for Sutherland model. + */ + void SetMu_Temperature_RefND(su2double mu_Tref) { Mu_Temperature_RefND = mu_Tref; } + + /*! + * \brief Set the value of the non-dimensional S for Sutherland model. + */ + void SetMu_SND(su2double mu_s) { Mu_SND = mu_s; } + /*! * \brief Set the temperature polynomial coefficient for specific heat Cp. * \param[in] val_coeff - Temperature polynomial coefficient for specific heat Cp. @@ -4211,6 +4279,12 @@ class CConfig { */ unsigned long GetLinear_Solver_Iter(void) const { return Linear_Solver_Iter; } + /*! + * \brief Get max number of iterations of the linear solver for the implicit formulation. + * \return Max number of iterations of the linear solver for the implicit formulation. + */ + unsigned long GetPoisson_Linear_Solver_Iter(void) const { return Poisson_Linear_Solver_Iter; } + /*! * \brief Get max number of iterations of the linear solver for the implicit formulation. * \return Max number of iterations of the linear solver for the implicit formulation. @@ -4234,6 +4308,18 @@ class CConfig { * \return Relaxation factor. */ su2double GetLinear_Solver_Smoother_Relaxation(void) const { return Linear_Solver_Smoother_Relaxation; } + + /*! + * \brief Get the relaxation coefficient of the flow correction for PB solver. + * \return relaxation coefficient of the flow correction for PB solver + */ + su2double GetRelaxation_Factor_PBFlow(void) const { return Relaxation_Factor_PBFlow; } + + /*! + * \brief Get the relaxation coefficient of the flow correction for PB solver. + * \return relaxation coefficient of the flow correction for PB solver + */ + su2double GetRCFactor(void) const { return RCFactor; } /*! * \brief Get the relaxation factor for solution updates of adjoint solvers. @@ -4591,6 +4677,15 @@ class CConfig { */ unsigned short GetKind_TimeIntScheme_Radiation(void) const { return Kind_TimeIntScheme_Radiation; } + /*! + * \brief Get the kind of integration scheme (explicit or implicit) + * for the poisson/pressure correction equations. + * \note This value is obtained from the config file, and it is constant + * during the computation. + * \return Kind of integration scheme for the poisson/pressure correction equations. + */ + unsigned short GetKind_TimeIntScheme_Poisson(void) const { return Kind_TimeIntScheme_Poisson; } + /*! * \brief Get the kind of integration scheme (explicit or implicit) * for the template equations. diff --git a/Common/include/geometry/CGeometry.hpp b/Common/include/geometry/CGeometry.hpp index adc7b800a810..782a9a1f764e 100644 --- a/Common/include/geometry/CGeometry.hpp +++ b/Common/include/geometry/CGeometry.hpp @@ -765,6 +765,11 @@ class CGeometry { inline virtual void SetAvgTurboValue(CConfig* config, unsigned short val_iZone, unsigned short marker_flag, bool allocate) {} + /*! + * \brief Sets CG coordinates. + */ + inline virtual void SetCoord_CG(void) {} + /*! * \brief A virtual member. * \param[in] config - Definition of the particular problem. diff --git a/Common/include/geometry/CPhysicalGeometry.hpp b/Common/include/geometry/CPhysicalGeometry.hpp index 740b0429bbde..b723f3dd3d47 100644 --- a/Common/include/geometry/CPhysicalGeometry.hpp +++ b/Common/include/geometry/CPhysicalGeometry.hpp @@ -416,6 +416,11 @@ class CPhysicalGeometry final : public CGeometry { */ void SetAvgTurboGeoValues(const CConfig* donor_config, CGeometry* donor_geometry, unsigned short donorZone) override; + /*! + * \brief Set the center of gravity of the face, elements and edges. + */ + void SetCoord_CG(void) override; + /*! * \brief Set the edge structure of the control volume. * \param[in] config - Definition of the particular problem. diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index a2b5f551525e..7071632cc308 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -256,6 +256,7 @@ enum class MAIN_SOLVER { FEM_RANS, /*!< \brief Definition of the finite element Reynolds-averaged Navier-Stokes' (RANS) solver. */ FEM_LES, /*!< \brief Definition of the finite element Large Eddy Simulation Navier-Stokes' (LES) solver. */ MULTIPHYSICS, + POISSON_EQUATION, NEMO_EULER, /*!< \brief Definition of the NEMO Euler solver. */ NEMO_NAVIER_STOKES, /*!< \brief Definition of the NEMO NS solver. */ }; @@ -331,6 +332,36 @@ static const MapType MatComp_Map = { MakePair("NEARLY_INCOMPRESSIBLE", STRUCT_COMPRESS::NEARLY_INCOMP) }; +/*------New option for pressure-based system-------*/ +/*! + * \brief Type of incompressible solver + */ +enum class ENUM_INCOMP_SYSTEM { + DENSITY_BASED, /*!< \brief Density-based. */ + PRESSURE_BASED, /*!< \brief Pressure-based. */ +}; +static const MapType Incomp_Map = { + MakePair("DENSITY_BASED", ENUM_INCOMP_SYSTEM::DENSITY_BASED) + MakePair("PRESSURE_BASED", ENUM_INCOMP_SYSTEM::PRESSURE_BASED) +}; + +/*! + * \brief Type of iteration + */ +enum class ENUM_PBITER { + SIMPLE, /*!< \brief SIMPLE algorithm. */ + SIMPLEC, /*!< \brief SIMPLE algorithm. */ + PISO, /*!< \brief PISO algorithm. */ +}; + +static const MapType PBIter_Map = { + MakePair("SIMPLE", ENUM_PBITER::SIMPLE) + MakePair("SIMPLEC", ENUM_PBITER::SIMPLEC) + MakePair("PISO", ENUM_PBITER::PISO) +}; + +/*------ End new option for pressure-based system-------*/ + /*! * \brief Types of interpolators */ @@ -470,6 +501,7 @@ enum RUNTIME_TYPE { RUNTIME_ADJRAD_SYS = 24, /*!< \brief One-physics case, the code is solving the adjoint radiation model. */ RUNTIME_SPECIES_SYS = 25, /*!< \brief One-physics case, the code is solving the species model. */ RUNTIME_ADJSPECIES_SYS = 26,/*!< \brief One-physics case, the code is solving the adjoint species model. */ + RUNTIME_POISSON_SYS = 27, /*!< \brief One-physics case, the code is solving the adjoint species model. */ }; enum SOLVER_TYPE : const int { @@ -488,6 +520,7 @@ enum RUNTIME_TYPE { ADJSPECIES_SOL=12, /*!< \brief Position of the adjoint of the species solver. */ FEA_SOL=0, /*!< \brief Position of the Finite Element flow solution in the solver container array. */ ADJFEA_SOL=1, /*!< \brief Position of the continuous adjoint Finite Element flow solution in the solver container array. */ + POISSON_SOL=12, /*!< \brief Position of the template solution. */ TEMPLATE_SOL=0, /*!< \brief Position of the template solution. */ }; @@ -818,7 +851,8 @@ enum class CENTERED { JST, /*!< \brief Jameson-Smith-Turkel centered numerical method. */ LAX, /*!< \brief Lax-Friedrich centered numerical method. */ JST_MAT, /*!< \brief JST with matrix dissipation. */ - JST_KE /*!< \brief Kinetic Energy preserving Jameson-Smith-Turkel centered numerical method. */ + JST_KE, /*!< \brief Kinetic Energy preserving Jameson-Smith-Turkel centered numerical method. */ + CDS /*!< \brief Used for pressure based solver. */ }; static const MapType Centered_Map = { MakePair("NONE", CENTERED::NONE) @@ -826,6 +860,7 @@ static const MapType Centered_Map = { MakePair("JST_KE", CENTERED::JST_KE) MakePair("JST_MAT", CENTERED::JST_MAT) MakePair("LAX-FRIEDRICH", CENTERED::LAX) + MakePair("CDS", CENTERED::CDS) }; @@ -852,7 +887,8 @@ enum class UPWIND { AUSMPLUSUP, /*!< \brief AUSM+ -up numerical method (All Speed) */ AUSMPLUSUP2, /*!< \brief AUSM+ -up2 numerical method (All Speed) */ AUSMPLUSM, /*!< \breif AUSM+M numerical method. (NEMO Only)*/ - BOUNDED_SCALAR /*!< \brief Scalar advection numerical method. */ + BOUNDED_SCALAR, /*!< \brief Scalar advection numerical method. */ + UDS }; static const MapType Upwind_Map = { MakePair("NONE", UPWIND::NONE) @@ -873,6 +909,7 @@ static const MapType Upwind_Map = { MakePair("LMROE", UPWIND::LMROE) MakePair("SLAU2", UPWIND::SLAU2) MakePair("FDS", UPWIND::FDS) + MakePair("UDS", UPWIND::UDS) MakePair("LAX-FRIEDRICH", UPWIND::LAX_FRIEDRICH) }; @@ -1841,10 +1878,12 @@ static const MapType Inlet_Map = { enum class INC_OUTLET_TYPE { PRESSURE_OUTLET, /*!< \brief Gauge pressure outlet for incompressible flow */ MASS_FLOW_OUTLET, /*!< \brief Mass flow outlet for incompressible flow. */ + OPEN, /*!< \brief Inlet-Outlet type. */ }; static const MapType Inc_Outlet_Map = { MakePair("PRESSURE_OUTLET", INC_OUTLET_TYPE::PRESSURE_OUTLET) MakePair("MASS_FLOW_OUTLET", INC_OUTLET_TYPE::MASS_FLOW_OUTLET) + MakePair("OPEN", INC_OUTLET_TYPE::OPEN) }; /*! @@ -2466,6 +2505,7 @@ enum PERIODIC_QUANTITIES { PERIODIC_LIM_PRIM_1 , /*!< \brief Primitive limiter communication phase 1 of 2 (periodic only). */ PERIODIC_LIM_PRIM_2 , /*!< \brief Primitive limiter communication phase 2 of 2 (periodic only). */ PERIODIC_IMPLICIT , /*!< \brief Implicit update communication to ensure consistency across periodic boundaries. */ + PERIODIC_PRESSURE , /*!< \brief Corrected pressure communication . */ }; /*! @@ -2497,6 +2537,9 @@ enum MPI_QUANTITIES { MESH_DISPLACEMENTS , /*!< \brief Mesh displacements at the interface. */ SOLUTION_TIME_N , /*!< \brief Solution at time n. */ SOLUTION_TIME_N1 , /*!< \brief Solution at time n-1. */ + PRESSURE_VAR , /*!< \brief Primitive variable communication. */ + MASS_FLUX , /*!< \brief Primitive variable communication. */ + MOM_COEFF, }; /*! diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 86a0d31e4565..e769c646b016 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -1117,6 +1117,11 @@ void CConfig::SetConfig_Options() { /*!\brief SST_OPTIONS \n DESCRIPTION: Specify SA turbulence model options/corrections. \n Options: see \link SA_Options_Map \endlink \n DEFAULT: NONE \ingroup Config*/ addEnumListOption("SA_OPTIONS", nSA_Options, SA_Options, SA_Options_Map); + /*!\brief KIND_INCOMP_SYSTEM \n DESCRIPTION: Incomp Type \n OPTIONS: see \link Incomp_Map \endlink \ingroup Config*/ + addEnumOption("KIND_INCOMP_SYSTEM", Kind_Incomp_System, Incomp_Map, ENUM_INCOMP_SYSTEM::DENSITY_BASED); + /*!\brief KIND_PB_ITER \n DESCRIPTION: Kind_PBIter \n OPTIONS: see \link PBIter_Map \endlink \ingroup Config*/ + addEnumOption("KIND_PB_ITER", Kind_PBIter, PBIter_Map, ENUM_PBITER::SIMPLE); + /*!\brief KIND_TRANS_MODEL \n DESCRIPTION: Specify transition model OPTIONS: see \link Trans_Model_Map \endlink \n DEFAULT: NONE \ingroup Config*/ addEnumOption("KIND_TRANS_MODEL", Kind_Trans_Model, Trans_Model_Map, TURB_TRANS_MODEL::NONE); /*!\brief SST_OPTIONS \n DESCRIPTION: Specify LM transition model options/correlations. \n Options: see \link LM_Options_Map \endlink \n DEFAULT: NONE \ingroup Config*/ @@ -1815,6 +1820,8 @@ void CConfig::SetConfig_Options() { addEnumOption("TIME_DISCRE_HEAT", Kind_TimeIntScheme_Heat, Time_Int_Map, EULER_IMPLICIT); /* DESCRIPTION: Time discretization */ addEnumOption("TIMESTEP_HEAT", Kind_TimeStep_Heat, Heat_TimeStep_Map, MINIMUM); + /* DESCRIPTION: Time discretization */ + addEnumOption("TIME_DISCRE_POISSON", Kind_TimeIntScheme_Poisson, Time_Int_Map, EULER_IMPLICIT); /*!\par CONFIG_CATEGORY: Linear solver definition \ingroup Config*/ /*--- Options related to the linear solvers ---*/ @@ -1829,6 +1836,8 @@ void CConfig::SetConfig_Options() { addDoubleOption("LINEAR_SOLVER_ERROR", Linear_Solver_Error, 1E-6); /* DESCRIPTION: Maximum number of iterations of the linear solver for the implicit formulation */ addUnsignedLongOption("LINEAR_SOLVER_ITER", Linear_Solver_Iter, 10); + /* DESCRIPTION: Maximum number of iterations of the linear solver for the implicit formulation */ + addUnsignedLongOption("POISSON_LINEAR_SOLVER_ITER", Poisson_Linear_Solver_Iter, 10); /* DESCRIPTION: Fill in level for the ILU preconditioner */ addUnsignedShortOption("LINEAR_SOLVER_ILU_FILL_IN", Linear_Solver_ILU_n, 0); /* DESCRIPTION: Maximum number of iterations of the linear solver for the implicit formulation */ @@ -1837,6 +1846,10 @@ void CConfig::SetConfig_Options() { addDoubleOption("LINEAR_SOLVER_SMOOTHER_RELAXATION", Linear_Solver_Smoother_Relaxation, 1.0); /* DESCRIPTION: Custom number of threads used for additive domain decomposition for ILU and LU_SGS (0 is "auto"). */ addUnsignedLongOption("LINEAR_SOLVER_PREC_THREADS", Linear_Solver_Prec_Threads, 0); + /* DESCRIPTION: Relaxation of the pressure based flow corrections */ + addDoubleOption("RELAXATION_FACTOR_PBFLOW", Relaxation_Factor_PBFlow, 0.5); + /* DESCRIPTION: Relaxation of the Rhie Chow interpolation contribution in pressure based flow. */ + addDoubleOption("RELAXATION_FACTOR_RHIECHOW", RCFactor, 0.0); /* DESCRIPTION: Relaxation factor for updates of adjoint variables. */ addDoubleOption("RELAXATION_FACTOR_ADJOINT", Relaxation_Factor_Adjoint, 1.0); /* DESCRIPTION: Relaxation of the CHT coupling */ @@ -2089,6 +2102,7 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Maximum number of iterations of the linear solver for the implicit formulation */ addUnsignedLongOption("GRAD_LINEAR_SOLVER_ITER", Grad_Linear_Solver_Iter, 1000); + /*!\par CONFIG_CATEGORY: Input/output files and formats \ingroup Config */ /*--- Options related to input/output files and formats ---*/ @@ -8391,6 +8405,7 @@ unsigned short CConfig::GetContainerPosition(unsigned short val_eqsystem) { case RUNTIME_ADJSPECIES_SYS:return ADJSPECIES_SOL; case RUNTIME_ADJFEA_SYS: return ADJFEA_SOL; case RUNTIME_RADIATION_SYS: return RAD_SOL; + case RUNTIME_POISSON_SYS: return POISSON_SOL; case RUNTIME_MULTIGRID_SYS: return 0; } return 0; @@ -8526,6 +8541,13 @@ void CConfig::SetGlobalParam(MAIN_SOLVER val_solver, SetKind_TimeIntScheme(Kind_TimeIntScheme_Heat); } break; + + case MAIN_SOLVER::POISSON_EQUATION: + if (val_system == RUNTIME_POISSON_SYS) { + SetKind_ConvNumScheme(NONE, CENTERED::NONE, UPWIND::NONE, LIMITER::NONE, NONE, NONE); + SetKind_TimeIntScheme(Kind_TimeIntScheme_Poisson); // TODO: PBFlow Kind_TimeIntScheme -> Kind_TimeIntScheme_Poission + } + break; case MAIN_SOLVER::FEM_ELASTICITY: case MAIN_SOLVER::DISC_ADJ_FEM: diff --git a/Common/src/geometry/CPhysicalGeometry.cpp b/Common/src/geometry/CPhysicalGeometry.cpp index 8be327af7a7b..2585e0029718 100644 --- a/Common/src/geometry/CPhysicalGeometry.cpp +++ b/Common/src/geometry/CPhysicalGeometry.cpp @@ -6326,6 +6326,64 @@ void CPhysicalGeometry::SetAvgTurboGeoValues(const CConfig* donor_config, CGeome } } +void CPhysicalGeometry::SetCoord_CG(void) { + + unsigned short iMarker, iNode; + unsigned long elem_poin, edge_poin, iElem, iEdge; + + /*--- Buffer of pointers to node coordinates ---*/ + array Coord; + + /*--- Compute the center of gravity for elements ---*/ + + SU2_OMP_FOR_STAT(roundUpDiv(nElem,2*omp_get_max_threads())) + for (iElem = 0; iElemGetnNodes() <= N_POINTS_MAXIMUM && "Insufficient N_POINTS_MAXIMUM"); + + /*--- Store the coordinates for all the element nodes ---*/ + for (iNode = 0; iNode < elem[iElem]->GetnNodes(); iNode++) { + elem_poin = elem[iElem]->GetNode(iNode); + Coord[iNode] = nodes->GetCoord(elem_poin); + } + + /*--- Compute the element CG coordinates ---*/ + elem[iElem]->SetCoord_CG(nDim, Coord.data()); + } + + /*--- Center of gravity for face elements ---*/ + + SU2_OMP_FOR_DYN(1) + for (iMarker = 0; iMarker < nMarker; iMarker++) { + for (iElem = 0; iElem < nElem_Bound[iMarker]; iElem++) { + + /*--- Store the coordinates for all the element nodes ---*/ + for (iNode = 0; iNode < bound[iMarker][iElem]->GetnNodes(); iNode++) { + elem_poin = bound[iMarker][iElem]->GetNode(iNode); + Coord[iNode] = nodes->GetCoord(elem_poin); + } + + /*--- Compute the element CG coordinates ---*/ + bound[iMarker][iElem]->SetCoord_CG(nDim, Coord.data()); + } + } + + /*--- Center of gravity for edges ---*/ + + SU2_OMP_FOR_STAT(roundUpDiv(nEdge,2*omp_get_max_threads())) + for (iEdge = 0; iEdge < nEdge; iEdge++) { + + /*--- Store the coordinates for all the element nodes ---*/ + for (iNode = 0; iNode < edges->GetnNodes(); iNode++) { + edge_poin=edges->GetNode(iEdge,iNode); + Coord[iNode] = nodes->GetCoord(edge_poin); + } + + /*--- Compute the edge CG coordinates ---*/ + // edges->SetCoord_CG(nDim, Coord.data()); //TODO PBFlow + } + +} + void CPhysicalGeometry::SetMaxLength(CConfig* config) { SU2_OMP_FOR_STAT(roundUpDiv(nPointDomain, omp_get_max_threads())) for (unsigned long iPoint = 0; iPoint < nPointDomain; iPoint++) { diff --git a/SU2_CFD/include/integration/CIntegration.hpp b/SU2_CFD/include/integration/CIntegration.hpp index 29538908d4f4..dd615048ee6e 100644 --- a/SU2_CFD/include/integration/CIntegration.hpp +++ b/SU2_CFD/include/integration/CIntegration.hpp @@ -137,4 +137,11 @@ class CIntegration { CNumerics ******numerics_container, CConfig **config, unsigned short RunTime_EqSystem, unsigned short iZone, unsigned short iInst) { }; + virtual void MultiGrid_CyclePB(CGeometry ****geometry, CSolver *****solver_container, CNumerics ******numerics_container, + CConfig **config, unsigned short iMesh, unsigned short mu, unsigned short RunTime_EqSystem, + unsigned short iZone, unsigned short iInst) { }; + + virtual void CurrentGridIteration(CGeometry ****geometry, CSolver *****solver_container, CNumerics ******numerics_container, + CConfig **config, unsigned short iMesh, unsigned short RunTime_EqSystem, + unsigned short iZone, unsigned short iInst) {}; }; diff --git a/SU2_CFD/include/integration/CMultiGridIntegration.hpp b/SU2_CFD/include/integration/CMultiGridIntegration.hpp index 164999039611..eb9c31e22802 100644 --- a/SU2_CFD/include/integration/CMultiGridIntegration.hpp +++ b/SU2_CFD/include/integration/CMultiGridIntegration.hpp @@ -70,6 +70,14 @@ class CMultiGridIntegration final : public CIntegration { unsigned short iMesh, unsigned short mu, unsigned short RunTime_EqSystem, unsigned short iZone, unsigned short iInst); + void CurrentGridIteration(CGeometry ****geometry, CSolver *****solver_container, CNumerics ******numerics_container, + CConfig **config, unsigned short iMesh, unsigned short RunTime_EqSystem, + unsigned short iZone, unsigned short iInst); + + void MultiGrid_CyclePB(CGeometry ****geometry, CSolver *****solver_container, CNumerics ******numerics_container, + CConfig **config, unsigned short iMesh, unsigned short mu, unsigned short RunTime_EqSystem, + unsigned short iZone, unsigned short iInst) override; + /*! * \brief Compute the forcing term. * \param[in] sol_fine - Pointer to the solution on the fine grid. diff --git a/SU2_CFD/include/numerics/CNumerics.hpp b/SU2_CFD/include/numerics/CNumerics.hpp index 14088f021cd6..11298b667661 100644 --- a/SU2_CFD/include/numerics/CNumerics.hpp +++ b/SU2_CFD/include/numerics/CNumerics.hpp @@ -57,6 +57,7 @@ class CNumerics { su2double Prandtl_Turb; /*!< \brief Turbulent Prandtl's number. */ su2double MassFlux; /*!< \brief Mass flux across edge. */ su2double + **Flux_Tensor, /*!< \brief Flux tensor (used for viscous and inviscid purposes. */ *Proj_Flux_Tensor; /*!< \brief Flux tensor projected in a direction. */ su2double **tau; /*!< \brief Viscous stress tensor. */ const su2double delta [3][3] = {{1.0, 0.0, 0.0},{0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}}; /*!< \brief Identity matrix. */ @@ -152,12 +153,15 @@ class CNumerics { TurbPsi_Grad_j, /*!< \brief Gradient of adjoint turbulent variables at point j. */ AuxVar_Grad_i, /*!< \brief Gradient of an auxiliary variable at point i. */ AuxVar_Grad_j; /*!< \brief Gradient of an auxiliary variable at point i. */ + su2double Poisson_Coeff_i, /*!< \brief Poisson coefficient at point i. */ + Poisson_Coeff_j; /*!< \brief Poisson coefficient at point j. */ + su2double Poissonval_i, /*!< \brief Temperature at point i. */ + Poissonval_j; /*!< \brief Temperature at point j. */ su2double LocalGridLength_i; /*!< \brief Local grid length at point i. */ const su2double *RadVar_Source; /*!< \brief Source term from the radiative heat transfer equation. */ - const su2double - *Coord_i, /*!< \brief Cartesians coordinates of point i. */ - *Coord_j; /*!< \brief Cartesians coordinates of point j. */ + const su2double *Coord_i = nullptr, /*!< \brief Cartesians coordinates of point i. */ + *Coord_j = nullptr; /*!< \brief Cartesians coordinates of point j. */ unsigned short Neighbor_i, /*!< \brief Number of neighbors of the point i. */ Neighbor_j; /*!< \brief Number of neighbors of the point j. */ @@ -176,6 +180,7 @@ class CNumerics { su2double StrainMag_i, StrainMag_j; /*!< \brief Strain rate magnitude. */ su2double Dissipation_i, Dissipation_j; /*!< \brief Dissipation. */ su2double Dissipation_ij; + su2double Source_Term; su2double roughness_i = 0.0, /*!< \brief Roughness of the wall nearest to point i. */ roughness_j = 0.0; /*!< \brief Roughness of the wall nearest to point j. */ @@ -185,6 +190,7 @@ class CNumerics { su2double uq_delta_b; /*!< \brief Magnitude of perturbation */ su2double uq_urlx; /*!< \brief Under-relaxation factor for numerical stability */ bool uq_permute; /*!< \brief Flag for eigenvector permutation */ + su2double Face_Flux; bool nemo; /*!< \brief Flag for NEMO problems */ @@ -980,6 +986,39 @@ class CNumerics { * \brief Get the final Roe dissipation factor. */ inline su2double GetDissipation() const { return Dissipation_ij; } + /*! + * \brief Set the Poisson coefficient + * \param[in] val_Poisson_i - Value of the Poisson coefficient at point i. + * \param[in] val_Poisson_j - Value of the Poisson coefficient at point j. + */ + inline void SetPoisson_Coeff(su2double val_Poisson_Coeff_i,su2double val_Poisson_Coeff_j){ + Poisson_Coeff_i = val_Poisson_Coeff_i; + Poisson_Coeff_j = val_Poisson_Coeff_j; + } + + /*! + * \brief Set the Poisson value + * \param[in] val_Poisson_i - Value of the Poisson variable at point i. + * \param[in] val_Poisson_j - Value of the Poisson variable at point j. + */ + inline void SetPoissonval(su2double val_Poisson_i,su2double val_Poisson_j){ + Poissonval_i = val_Poisson_i; + Poissonval_j = val_Poisson_j; + } + + /*! + * \brief Set the Poisson value + * \param[in] val_Poisson_i - Value of the Poisson variable at point i. + * \param[in] val_Poisson_j - Value of the Poisson variable at point j. + */ + inline void SetSourcePoisson(su2double val_Source_Term) { Source_Term = val_Source_Term; } + + /*! + * \brief Set the value of the momentum equation coefficients for Poisson eq. + * \param[in] val_Mom_Coeff_i - Value of the cross coefficient at point i. + * \param[in] val_Mom_Coeff_j - Value of the cross coefficient at point j. + */ + inline virtual void SetInvMomCoeff(su2double *val_Mom_Coeff_i, su2double *val_Mom_Coeff_j) { } ; /*! * \brief Compute the projected inviscid flux vector. @@ -1056,6 +1095,21 @@ class CNumerics { su2double val_scale, su2double **val_Proj_Jac_Tensor) const; + /*! + * \brief Compute the projected inviscid flux vector for incompresible simulations + * \param[in] val_density - Pointer to the density. + * \param[in] val_velocity - Pointer to the velocity. + * \param[in] val_pressure - Pointer to the pressure. + * \param[in] val_betainc2 - Value of the artificial compresibility factor. + * \param[in] val_normal - Normal vector, the norm of the vector is the area of the face. + * \param[out] val_Proj_Flux - Pointer to the projected flux. + */ + void GetInviscidPBProjFlux(const su2double *val_density, + const su2double *val_velocity, + const su2double *val_pressure, + const su2double *val_normal, + su2double *val_Proj_Flux); + /*! * \brief Compute the low speed preconditioning matrix. * \param[in] val_density - Value of the density. @@ -1101,6 +1155,37 @@ class CNumerics { const su2double *val_normal, su2double val_scale, su2double **val_Proj_Jac_tensor) const; + /*! + * \brief Compute the projection of the inviscid Jacobian matrices (Pressure based method). + * \param[in] val_density - Value of the density. + * \param[in] val_velocity - Pointer to the velocity. + * \param[in] val_cp - Value of the specific heat at constant pressure. + * \param[in] val_normal - Normal vector, the norm of the vector is the area of the face. + * \param[in] val_scale - Scale of the projection. + * \param[out] val_Proj_Jac_tensor - Pointer to the projected inviscid Jacobian. + */ + + + void GetInviscidPBProjJac(const su2double val_density, const su2double *val_velocity, + const su2double *val_normal, const su2double val_scale, + su2double **val_Proj_Jac_tensor); + // /*! + // * \brief Set the gradient of the conservative variables. + // * \param[in] val_consvar_grad_i - Gradient of the conservative variable at point i. + // * \param[in] val_consvar_grad_j - Gradient of the conservative variable at point j. + // */ + // inline void SetConsVarGradient(CMatrixView val_consvar_grad_i, + // CMatrixView val_consvar_grad_j) { + // ConsVar_Grad_i = val_consvar_grad_i; + // ConsVar_Grad_j = val_consvar_grad_j; + // } + + // /*! + // * \brief Set the gradient of the conservative variables. + // * \param[in] val_consvar_grad - Gradient of the conservative variable which is a scalar. + // */ + // inline void SetConsVarGradient(CMatrixView val_consvar_grad) { ConsVar_Grad = val_consvar_grad; } + /*! * \brief Mapping between primitives variables P and conservatives variables C. * \param[in] val_Mean_PrimVar - Mean value of the primitive variables. @@ -1605,6 +1690,40 @@ class CNumerics { * \return is_bounded_scalar : scalar solver uses bounded scalar convective transport */ inline bool GetBoundedScalar() const { return bounded_scalar;} + + /*! + * \brief Compute the projection of the viscous Jacobian matrices. + * \param[in] val_laminar_viscosity - Value of the laminar viscosity. + * \param[in] val_eddy_viscosity - Value of the eddy viscosity. + * \param[in] val_dist_ij - Distance between the points. + * \param[in] val_normal - Normal vector, the norm of the vector is the area of the face. + * \param[in] val_dS - Area of the face between two nodes. + * \param[out] val_Proj_Jac_Tensor_i - Pointer to the projected viscous Jacobian at point i. + * \param[out] val_Proj_Jac_Tensor_j - Pointer to the projected viscous Jacobian at point j. + */ + + void GetViscousPBIncProjJacs(const su2double val_laminar_viscosity, + const su2double val_eddy_viscosity, + const su2double val_dist_ij, + const su2double *val_normal, + const su2double val_dS, + su2double **val_Proj_Jac_Tensor_i, + su2double **val_Proj_Jac_Tensor_j); + /*! + * \brief Compute the projection of the viscous fluxes into a direction (pressure based method). + * \param[in] val_primvar - Primitive variables. + * \param[in] val_gradprimvar - Gradient of the primitive variables. + * \param[in] val_normal - Normal vector, the norm of the vector is the area of the face. + * \param[in] val_laminar_viscosity - Laminar viscosity. + * \param[in] val_eddy_viscosity - Eddy viscosity. + */ + + void GetViscousPBIncProjFlux(const su2double *val_primvar, + su2double **val_gradprimvar, + const su2double *val_normal, + const su2double val_laminar_viscosity, + const su2double val_eddy_viscosity, + const su2double val_turb_ke); }; /*! diff --git a/SU2_CFD/include/numerics/scalar/scalar_convection.hpp b/SU2_CFD/include/numerics/scalar/scalar_convection.hpp index 5c4d7fadf5bd..7b10e8010fac 100644 --- a/SU2_CFD/include/numerics/scalar/scalar_convection.hpp +++ b/SU2_CFD/include/numerics/scalar/scalar_convection.hpp @@ -129,7 +129,8 @@ class CUpwScalar : public CNumerics { for (unsigned short iDim = 0; iDim < nDim; iDim++) { su2double Velocity_i = V_i[iDim + idx.Velocity()] - GridVel_i[iDim]; su2double Velocity_j = V_j[iDim + idx.Velocity()] - GridVel_j[iDim]; - q_ij += 0.5 * (Velocity_i + Velocity_j) * Normal[iDim]; + q_ij += 0.5 * (Velocity_i + Velocity_j) + * Normal[iDim]; } } else { for (unsigned short iDim = 0; iDim < nDim; iDim++) { diff --git a/SU2_CFD/include/output/CFlowIncOutput.hpp b/SU2_CFD/include/output/CFlowIncOutput.hpp index caa3197c8bb1..2672a47a5185 100644 --- a/SU2_CFD/include/output/CFlowIncOutput.hpp +++ b/SU2_CFD/include/output/CFlowIncOutput.hpp @@ -42,6 +42,7 @@ class CFlowIncOutput final: public CFlowOutput { bool heat; /*!< \brief Boolean indicating whether have a heat problem*/ bool weakly_coupled_heat; /*!< \brief Boolean indicating whether have a weakly coupled heat equation*/ bool flamelet; /*!< \brief Boolean indicating whether we solve the flamelet equations */ + bool pressure_based; /*!< \brief Boolean indicating whether running the pressure based version*/ unsigned short streamwisePeriodic; /*!< \brief Boolean indicating whether it is a streamwise periodic simulation. */ bool streamwisePeriodic_temperature; /*!< \brief Boolean indicating streamwise periodic temperature is used. */ diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp index 6953dd1bc59c..544d3ba7945b 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp @@ -235,7 +235,7 @@ class CFVMFlowSolverBase : public CSolver { * \note Implement this method in the derived class and call it in its constructor. * Duplicating this type of information has caused bugs (I know because I fixed them). */ - virtual void SetReferenceValues(const CConfig& config) = 0; + virtual void SetReferenceValues(const CConfig& config) {} /*! * \brief Allocate member variables. @@ -1067,7 +1067,7 @@ class CFVMFlowSolverBase : public CSolver { /*! * \brief Implementation of implicit Euler iteration. */ - void ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) final; + void ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) override; /*! * \brief Set the total residual adding the term that comes from the Dual Time Strategy. @@ -1148,7 +1148,7 @@ class CFVMFlowSolverBase : public CSolver { * \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) final; + void BC_Periodic(CGeometry* geometry, CSolver** solver_container, CNumerics* numerics, CConfig* config) override; /*! * \brief Impose the interface state across sliding meshes. @@ -2432,4 +2432,6 @@ class CFVMFlowSolverBase : public CSolver { */ inline const su2activevector* GetEdgeMassFluxes() const final { return &EdgeMassFluxes; } + inline virtual void Flow_Correction(CGeometry *geometry, CSolver **solver_container, CConfig *config) { }; + }; diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index c2af5a18d825..4f62a5bb78b5 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -2472,6 +2472,7 @@ void CFVMFlowSolverBase::Friction_Forces(const CGeometry* geometr const bool axisymmetric = config->GetAxisymmetric(); const bool roughwall = (config->GetnRoughWall() > 0); const bool nemo = config->GetNEMOProblem(); + const bool heat = config->GetEnergy_Equation(); const su2double factor = 1.0 / AeroCoeffForceRef; const su2double factorFric = config->GetRefArea() * factor; @@ -2533,7 +2534,7 @@ void CFVMFlowSolverBase::Friction_Forces(const CGeometry* geometr for (jDim = 0; jDim < nDim; jDim++) { Grad_Vel[iDim][jDim] = nodes->GetGradient_Primitive(iPoint, prim_idx.Velocity() + iDim, jDim); } - Grad_Temp[iDim] = nodes->GetGradient_Primitive(iPoint, prim_idx.Temperature(), iDim); + if (heat) Grad_Temp[iDim] = nodes->GetGradient_Primitive(iPoint, prim_idx.Temperature(), iDim); // TODO: PBFlow if added if (nemo) Grad_Temp_ve[iDim] = nodes->GetGradient_Primitive(iPoint, prim_idx.Temperature_ve(), iDim); } diff --git a/SU2_CFD/include/solvers/CScalarSolver.hpp b/SU2_CFD/include/solvers/CScalarSolver.hpp index bd854d4e51c9..51ea37ef82c6 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.hpp +++ b/SU2_CFD/include/solvers/CScalarSolver.hpp @@ -104,8 +104,8 @@ class CScalarSolver : public CSolver { CConfig* config) { const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); CFlowVariable* flowNodes = solver_container[FLOW_SOL] ? - su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()) : nullptr; - + su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()) : nullptr; + /*--- Points in edge ---*/ auto iPoint = geometry->edges->GetNode(iEdge, 0); diff --git a/SU2_CFD/include/solvers/CScalarSolver.inl b/SU2_CFD/include/solvers/CScalarSolver.inl index 343944ebd6c6..57ea4b2dcfc6 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.inl +++ b/SU2_CFD/include/solvers/CScalarSolver.inl @@ -141,8 +141,8 @@ void CScalarSolver::Upwind_Residual(CGeometry* geometry, CSolver** /*--- Only consider flow limiters for cell-based limiters, edge-based would need to be recomputed. ---*/ const bool limiterFlow = (config->GetKind_SlopeLimit_Flow() != LIMITER::NONE) && (config->GetKind_SlopeLimit_Flow() != LIMITER::VAN_ALBADA_EDGE); - - auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); + + auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); const auto& edgeMassFluxes = *(solver_container[FLOW_SOL]->GetEdgeMassFluxes()); /*--- Pick one numerics object per thread. ---*/ diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index 9134c901174c..144c34bbc573 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -474,6 +474,33 @@ class CSolver { */ inline virtual su2double GetRes_FEM(unsigned short val_var) const { return 0.0; } +/*! + * \brief Set the RMS of mass flux to zero. + */ + inline virtual void SetResMassFluxZero() { } + + /*! + * \brief Set the RMS of mass flux to given value. + * \param[in] val_ResMassFlux - Value of ResMassFlux + */ + inline virtual void SetResMassFlux(su2double val_ResMassFlux) { } + + /*! + * \brief Set the RMS of mass flux. + */ + inline virtual void SetResMassFluxRMS(CGeometry *geometry, CConfig *config) { } + + /*! + * \brief Set the convergence of mass flux for current internal iteration. + */ + inline virtual void AddResMassFlux(su2double val_ResMassFlux) { } + + /*! + * \brief Get the convergence of mass flux for current internal iteration. + * \return Value of the residual for the variable in the position val_var. + */ + inline virtual su2double GetResMassFlux() const {return 0.0; } + /*! * \brief Get the maximal residual, this is useful for the convergence history. * \param[in] val_var - Index of the variable. @@ -1244,6 +1271,8 @@ class CSolver { CConfig *config, unsigned short val_marker) { } + inline virtual void SetReferenceValues(const CConfig& config) {}; + /*! * \brief A virtual member. * \param[in] geometry - Geometrical definition of the problem. @@ -4284,6 +4313,31 @@ class CSolver { */ inline virtual bool GetHasHybridParallel() const { return false; } + + /*! + * \brief A virtual member + * Correct velocity and pressure. + */ + inline virtual void Flow_Correction(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } + + /*! + * \brief A virtual member + * Set source term for pressure correction. + */ + inline virtual void SetPoissonSourceTerm(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh) { } + + /*! + * \brief A virtual member + * Set coefficients for pressure correction equation. + */ + inline virtual void SetMomCoeff(CGeometry *geometry, CSolver **solver_container, CConfig *config, bool periodic, unsigned short iMesh) { } + + /*! + * \brief A virtual member + * Set coefficients for pressure correction equation in periodic problems. + */ + inline virtual void SetMomCoeffPer(CGeometry *geometry, CSolver **solver_container, CConfig *config) { } + /*! * \brief Get values for streamwise periodic flow: delta P, m_dot, inlet T, integrated heat, etc. * \return Struct holding streamwise periodic values. @@ -4326,6 +4380,11 @@ class CSolver { } END_SU2_OMP_FOR } + /*! + * \brief A virtual member + * Update corrections for the Rhie-Chow interpolation for unsteady problems. + */ + inline virtual void SetMomentumCorrection_DualTime() { } protected: /*! diff --git a/SU2_CFD/include/solvers/CSolverFactory.hpp b/SU2_CFD/include/solvers/CSolverFactory.hpp index ab8d757c2809..7f3c5313c079 100644 --- a/SU2_CFD/include/solvers/CSolverFactory.hpp +++ b/SU2_CFD/include/solvers/CSolverFactory.hpp @@ -63,6 +63,7 @@ enum class SUB_SOLVER_TYPE { MESH, /*!< \brief Mesh solver */ RADIATION, /*!< \brief Radiation solver */ DISC_ADJ_RADIATION, /*!< \brief Discrete adjoint radiation solver */ + POISSON_EQUATION, /*!< \brief Discrete adjoint radiation solver */ NONE }; diff --git a/SU2_CFD/include/variables/CIncNSVariable.hpp b/SU2_CFD/include/variables/CIncNSVariable.hpp index a5b42a512cce..48aa8ea0d3ea 100644 --- a/SU2_CFD/include/variables/CIncNSVariable.hpp +++ b/SU2_CFD/include/variables/CIncNSVariable.hpp @@ -62,6 +62,11 @@ class CIncNSVariable final : public CIncEulerVariable { Primitive(iPoint, indices.LaminarViscosity()) = laminarViscosity; } + /*! + * \brief Set the vorticity value. + */ + bool SetVorticity_StrainMag() override; + /*! * \overload * \param[in] eddy_visc - Value of the eddy viscosity. diff --git a/SU2_CFD/include/variables/CNSVariable.hpp b/SU2_CFD/include/variables/CNSVariable.hpp index d23b7a16eb41..f55b728c3224 100644 --- a/SU2_CFD/include/variables/CNSVariable.hpp +++ b/SU2_CFD/include/variables/CNSVariable.hpp @@ -79,6 +79,11 @@ class CNSVariable final : public CEulerVariable { Primitive(iPoint, indices.CpTotal()) = val_Cp; } + /*! + * \brief Set the vorticity value. + */ + bool SetVorticity_StrainMag() override; + /*! * \overload * \param[in] eddy_visc - Value of the eddy viscosity. diff --git a/SU2_CFD/include/variables/CPrimitiveIndices.hpp b/SU2_CFD/include/variables/CPrimitiveIndices.hpp index 1ffbaa341f68..afb473611838 100644 --- a/SU2_CFD/include/variables/CPrimitiveIndices.hpp +++ b/SU2_CFD/include/variables/CPrimitiveIndices.hpp @@ -32,6 +32,7 @@ #include #include "CEulerVariable.hpp" +#include "CPBIncEulerVariable.hpp" #include "CIncEulerVariable.hpp" #include "CNEMOEulerVariable.hpp" @@ -51,7 +52,8 @@ struct CPrimitiveIndices { } else if (nemo) { type_ = 1; Construct>(nDim, nSpecies); - } else { + } + else { type_ = 2; Construct>(nDim, nSpecies); } diff --git a/SU2_CFD/include/variables/CVariable.hpp b/SU2_CFD/include/variables/CVariable.hpp index 453dca7226b2..5bc19e6d8717 100644 --- a/SU2_CFD/include/variables/CVariable.hpp +++ b/SU2_CFD/include/variables/CVariable.hpp @@ -726,6 +726,8 @@ class CVariable { */ inline CMatrixView GetGradient(unsigned long iPoint) { return Gradient[iPoint]; } + // inline su2double **GetGradient(unsigned long iPoint) { return Gradient[iPoint]; } + /*! * \brief Get the value of the solution gradient. * \param[in] iPoint - Point index. @@ -759,6 +761,47 @@ class CVariable { */ inline C3DDoubleMatrix& GetRmatrix(void) { return Rmatrix; } + /*! + * \brief Set the value of the limiter. + * \param[in] iPoint - Point index. + * \param[in] iVar - Index of the variable. + * \param[in] val_limiter - Value of the limiter for the index iVar. + */ + inline void SetLimiter(unsigned long iPoint, unsigned long iVar, su2double val_limiter) { Limiter(iPoint,iVar) = val_limiter; } + + /*! + * \brief Set the value of the limiter. + * \param[in] iPoint - Point index. + * \param[in] val_species - Index of the species . + * \param[in] iVar - Index of the variable. + * \param[in] val_limiter - Value of the limiter for the index iVar. + */ + inline virtual void SetLimiterPrimitive(unsigned long iPoint, unsigned long val_species, unsigned long iVar, su2double val_limiter) {} + + /*! + * \brief Set the value of the limiter. + * \param[in] iPoint - Point index. + * \param[in] val_species - Index of the species . + * \param[in] iVar - Index of the variable. + */ + inline virtual su2double GetLimiterPrimitive(unsigned long iPoint, unsigned long val_species, unsigned long iVar) const { return 0.0; } + + /*! + * \brief Set the value of the max solution. + * \param[in] iPoint - Point index. + * \param[in] iVar - Index of the variable. + * \param[in] solution - Value of the max solution for the index iVar. + */ + inline void SetSolution_Max(unsigned long iPoint, unsigned long iVar, su2double solution) { Solution_Max(iPoint,iVar) = solution; } + + /*! + * \brief Set the value of the min solution. + * \param[in] iPoint - Point index. + * \param[in] iVar - Index of the variable. + * \param[in] solution - Value of the min solution for the index iVar. + */ + inline void SetSolution_Min(unsigned long iPoint, unsigned long iVar, su2double solution) { Solution_Min(iPoint,iVar) = solution; } + /*! * \brief Get the slope limiter. * \return Reference to the limiters vector. @@ -930,6 +973,13 @@ class CVariable { */ inline virtual su2double GetDensity(unsigned long iPoint) const { return 0.0; } + /*! + * \brief A virtual member. + * \param[in] iPoint - Point index. + * \return Old value of the flow density. + */ + inline virtual su2double GetDensity_Old(unsigned long iPoint) const { return 0.0; } + /*! * \brief A virtual member. * \param[in] iPoint - Point index. @@ -1565,11 +1615,24 @@ class CVariable { */ inline virtual void SetSpecificHeatCv(unsigned long iPoint, su2double Cv) {} + /*! + * \brief A virtual member. + */ + inline virtual bool SetVorticity_StrainMag() { return false; } + /*! * \brief A virtual member. */ inline virtual void SetVelSolutionDVector(unsigned long iPoint) {} + /*! + * \brief A virtual member. + * \param[in] iVar - Index of the variable. + * \param[in] iDim - Index of the dimension. + * \param[in] val_value - Value to add to the gradient of the primitive variables. + */ + inline virtual void AddGradient_Primitive(unsigned long iPoint, unsigned long iVar, unsigned long iDim, su2double val_value) {} + /*! * \brief A virtual member. * \param[in] iVar - Index of the variable. @@ -1592,6 +1655,14 @@ class CVariable { inline virtual MatrixType& GetLimiter_Primitive() { AssertOverride(); return Limiter; } inline virtual const MatrixType& GetLimiter_Primitive() const { AssertOverride(); return Limiter; } + /*! + * \brief A virtual member. + * \param[in] iVar - Index of the variable. + * \param[in] iDim - Index of the dimension. + * \param[in] val_value - Value of the gradient. + */ + inline virtual void SetGradient_Primitive(unsigned long iPoint, unsigned long iVar, unsigned long iDim, su2double val_value) {} + /*! * \brief A virtual member. * \param[in] iVar - Index of the variable. @@ -1611,6 +1682,22 @@ class CVariable { */ inline virtual su2double *GetLimiter_Primitive(unsigned long iPoint) { return nullptr; } + /*! + * \brief Get the value of the primitive gradient for MUSCL reconstruction. + * \param[in] val_var - Index of the variable. + * \param[in] val_dim - Index of the dimension. + * \return Value of the primitive variables gradient. + */ + inline virtual su2double GetGradient_Reconstruction(unsigned long iPoint, unsigned long val_var, unsigned long val_dim) const { return 0.0; } + + /*! + * \brief Set the value of the primitive gradient for MUSCL reconstruction. + * \param[in] val_var - Index of the variable. + * \param[in] val_dim - Index of the dimension. + * \param[in] val_value - Value of the gradient. + */ + inline virtual void SetGradient_Reconstruction(unsigned long iPoint, unsigned long val_var, unsigned long val_dim, su2double val_value) { } + /*! * \brief Get the value of the primitive gradient for MUSCL reconstruction. * \return Value of the primitive gradient for MUSCL reconstruction. @@ -2340,4 +2427,43 @@ class CVariable { inline virtual const su2double *GetScalarSources(unsigned long iPoint) const { return nullptr; } inline virtual const su2double *GetScalarLookups(unsigned long iPoint) const { return nullptr; } +// inline virtual void AddGradient_Primitive(unsigned long iPoint, unsigned long iVar, unsigned long iDim, su2double value) {} +// inline virtual void SetGradient_Primitive(unsigned long iPoint, unsigned long iVar, unsigned long iDim, su2double value) {} +// inline virtual void SetGradient_Primitive(unsigned long iPoint, unsigned long iVar, unsigned long iDim, su2double value) {} + inline virtual void SetLimiter_Primitive(unsigned long iPoint, unsigned long iVar, su2double value) {} +// inline virtual su2double **GetGradient_Primitive(unsigned long iPoint) {} +// inline virtual su2double** GetGradient_Primitive(unsigned long iPoint) {} +// inline virtual su2double GetGradient_Reconstruction(unsigned long iPoint, unsigned long iVar, unsigned long iDim) {} +// inline virtual void SetGradient_Reconstruction(unsigned long iPoint, unsigned long iVar, unsigned long iDim, su2double value) {} +inline virtual su2double GetMassFlux(unsigned long iPoint) const { return 0.0; } + + inline virtual void SetMassFlux(unsigned long iPoint, su2double val_MassFlux) {} + + inline virtual void AddMassFlux(unsigned long iPoint, su2double val_MassFlux) {} + + inline virtual void SubtractMassFlux(unsigned long iPoint, su2double val_MassFlux) {} + + inline virtual void Set_Mom_Coeff(unsigned long iPoint, su2double *val_Mom_Coeff) {} + + inline virtual su2double Get_Mom_Coeff(unsigned long iPoint, unsigned short val_Var) { return 0.0; } + + inline virtual su2double Get_Mom_Coeff_nb(unsigned long iPoint, unsigned short val_Var) { return 0.0; } + + inline virtual void Set_Mom_Coeff_nb(unsigned long iPoint, su2double *val_Mom_Coeff) {} + + inline virtual void Add_Mom_Coeff_nb(unsigned long iPoint, su2double val_coeff_nb, unsigned short val_Var) {} + + inline virtual void Add_Mom_Coeff(unsigned long iPoint, su2double val_coeff, unsigned short val_Var) {} + + inline virtual void Set_Mom_Coeff_nbZero(unsigned long iPoint) {} + + inline virtual void Set_Mom_CoeffZero(unsigned long iPoint) {} + + inline virtual void Set_Mom_Coeff(unsigned long iPoint, unsigned short val_Var, su2double val_Mom_Coeff) {} + + inline virtual void Set_Mom_Coeff_nb(unsigned long iPoint, unsigned short val_Var, su2double val_Mom_Coeff) {} + +inline virtual su2double GetPoisson_Coeff(unsigned long iPoint) { return 0.0; } + + inline virtual void SetPoisson_Coeff(unsigned long iPoint, su2double val_Poisson_Coeff) {} }; diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index 0fdfb2c2a2e6..36442b1410ba 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -51,11 +51,14 @@ #include "../../include/variables/CEulerVariable.hpp" #include "../../include/variables/CIncEulerVariable.hpp" +#include "../../include/variables/CPBIncEulerVariable.hpp" #include "../../include/variables/CNEMOEulerVariable.hpp" #include "../../include/numerics/template.hpp" #include "../../include/numerics/radiation.hpp" #include "../../include/numerics/heat.hpp" +#include "../../include/numerics/pbflow.hpp" +#include "../../include/numerics/poisson.hpp" #include "../../include/numerics/flow/convection/roe.hpp" #include "../../include/numerics/flow/convection/fds.hpp" #include "../../include/numerics/flow/convection/fvs.hpp" @@ -1460,13 +1463,16 @@ void CDriver::InitializeNumerics(CConfig *config, CGeometry **geometry, CSolver nVar_Adj_Flow = 0, nVar_Adj_Turb = 0, nVar_FEM = 0, - nVar_Rad = 0; + nVar_Rad = 0, + nVar_Poisson = 0; numerics = new CNumerics***[config->GetnMGLevels()+1] (); bool compressible = false; bool incompressible = false; bool ideal_gas = (config->GetKind_FluidModel() == STANDARD_AIR) || (config->GetKind_FluidModel() == IDEAL_GAS); + bool pressure_based = (config->GetKind_Incomp_System() == ENUM_INCOMP_SYSTEM::PRESSURE_BASED); + bool poisson = (config->GetKind_Incomp_System() == ENUM_INCOMP_SYSTEM::PRESSURE_BASED); bool roe_low_dissipation = (config->GetKind_RoeLowDiss() != NO_ROELOWDISS); /*--- Initialize some useful booleans ---*/ @@ -1577,6 +1583,7 @@ void CDriver::InitializeNumerics(CConfig *config, CGeometry **geometry, CSolver if (fem_ns) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); if (fem) nVar_FEM = solver[MESH_0][FEA_SOL]->GetnVar(); + if (poisson) nVar_Poisson = solver[MESH_0][POISSON_SOL]->GetnVar(); if (config->AddRadiation()) nVar_Rad = solver[MESH_0][RAD_SOL]->GetnVar(); @@ -1665,6 +1672,7 @@ void CDriver::InitializeNumerics(CConfig *config, CGeometry **geometry, CSolver } if (incompressible) { + if (!pressure_based) { /*--- Incompressible flow, use preconditioning method ---*/ switch (config->GetKind_Centered_Flow()) { case CENTERED::LAX : numerics[MESH_0][FLOW_SOL][conv_term] = new CCentLaxInc_Flow(nDim, nVar_Flow, config); break; @@ -1672,14 +1680,29 @@ void CDriver::InitializeNumerics(CConfig *config, CGeometry **geometry, CSolver default: SU2_MPI::Error("Invalid centered scheme or not implemented.\n Currently, only JST and LAX-FRIEDRICH are available for incompressible flows.", CURRENT_FUNCTION); break; - } + } for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) numerics[iMGlevel][FLOW_SOL][conv_term] = new CCentLaxInc_Flow(nDim, nVar_Flow, config); /*--- Definition of the boundary condition method ---*/ for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwFDSInc_Flow(nDim, nVar_Flow, config); + } else { + /*--- Incompressible flow, use pressure based method ---*/ + switch (config->GetKind_Centered_Flow()) { + case CENTERED::CDS : numerics[MESH_0][FLOW_SOL][conv_term] = new CCentPB_Flow(nDim, nVar_Flow, config); break; + default: + SU2_OMP_MASTER + SU2_MPI::Error("Invalid centered scheme or not implemented.\n Currently, only CDS are available for incompressible flows.", CURRENT_FUNCTION); + break; + } + for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][conv_term] = new CCentPB_Flow(nDim, nVar_Flow, config); + /*--- Definition of the boundary condition method ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwPB_Flow(nDim, nVar_Flow, config); + } } break; case SPACE_UPWIND : @@ -1786,6 +1809,7 @@ void CDriver::InitializeNumerics(CConfig *config, CGeometry **geometry, CSolver } if (incompressible) { + if (!pressure_based) { /*--- Incompressible flow, use artificial compressibility method ---*/ switch (config->GetKind_Upwind_Flow()) { case UPWIND::FDS: @@ -1797,14 +1821,29 @@ void CDriver::InitializeNumerics(CConfig *config, CGeometry **geometry, CSolver default: SU2_MPI::Error("Invalid upwind scheme or not implemented.\n Currently, only FDS is available for incompressible flows.", CURRENT_FUNCTION); break; + } + } else { + /*--- Incompressible flow, use pressure based method ---*/ + switch (config->GetKind_Upwind_Flow()) { + case UPWIND::UDS: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwPB_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwPB_Flow(nDim, nVar_Flow, config); + } + break; + default: + SU2_OMP_MASTER + SU2_MPI::Error("Invalid upwind scheme or not implemented.\n Currently, only UDS is available for pressure based incompressible flows.", CURRENT_FUNCTION); + break; + } } } break; - default: - SU2_MPI::Error("Invalid convective scheme for the Euler / Navier-Stokes equations.", CURRENT_FUNCTION); - break; - } + default: + SU2_MPI::Error("Invalid convective scheme for the Euler / Navier-Stokes equations.", CURRENT_FUNCTION); + break; + } /*--- Definition of the viscous scheme for each equation and mesh level ---*/ if (compressible) { @@ -1833,6 +1872,7 @@ void CDriver::InitializeNumerics(CConfig *config, CGeometry **geometry, CSolver } } if (incompressible) { + if (!pressure_based) { /*--- Incompressible flow, use preconditioning method ---*/ numerics[MESH_0][FLOW_SOL][visc_term] = new CAvgGradInc_Flow(nDim, nVar_Flow, true, config); for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) @@ -1841,6 +1881,17 @@ void CDriver::InitializeNumerics(CConfig *config, CGeometry **geometry, CSolver /*--- Definition of the boundary condition method ---*/ for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) numerics[iMGlevel][FLOW_SOL][visc_bound_term] = new CAvgGradInc_Flow(nDim, nVar_Flow, false, config); + } else { + /*--- Incompressible flow, use pressure based method ---*/ + numerics[MESH_0][FLOW_SOL][visc_term] = new CAvgGradCorrectedPBInc_Flow(nDim, nVar_Flow, config); + for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][visc_term] = new CAvgGradPBInc_Flow(nDim, nVar_Flow, config); + } + + /*--- Definition of the boundary condition method ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][visc_bound_term] = new CAvgGradPBInc_Flow(nDim, nVar_Flow, config); + } } /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ @@ -2045,8 +2096,12 @@ void CDriver::InitializeNumerics(CConfig *config, CGeometry **geometry, CSolver if (turbulent) { if (incompressible) + if (!pressure_based) InstantiateTurbulentNumerics >(nVar_Turb, offset, config, solver[MESH_0][TURB_SOL], numerics); + else + InstantiateTurbulentNumerics >(nVar_Turb, offset, config, + solver[MESH_0][TURB_SOL], numerics); else if (NEMO_ns) InstantiateTurbulentNumerics >(nVar_Turb, offset, config, solver[MESH_0][TURB_SOL], numerics); @@ -2103,6 +2158,24 @@ void CDriver::InitializeNumerics(CConfig *config, CGeometry **geometry, CSolver } } } + + /*--- Solver definition for the poisson/pressure correction problem ---*/ + if (poisson) { + /*--- Pressure correction (Poisson) equation ---*/ + numerics[MESH_0][POISSON_SOL][visc_term] = new CAvgGradCorrected_Poisson(nDim, nVar_Poisson, config); + + for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][POISSON_SOL][visc_term] = new CAvgGrad_Poisson(nDim, nVar_Poisson, config); + + /*--- Assign the convective boundary term as well to account for flow BCs as well --*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][POISSON_SOL][visc_bound_term] = new CAvgGrad_Poisson(nDim, nVar_Poisson, config); + + /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ + numerics[iMGlevel][POISSON_SOL][source_first_term] = new CSource_PoissonFVM(nDim, nVar_Poisson, config); + numerics[iMGlevel][POISSON_SOL][source_second_term] = new CSourceNothing(nDim, nVar_Poisson, config); + } + } /*--- Solver definition for the radiation model problem ---*/ diff --git a/SU2_CFD/src/integration/CIntegration.cpp b/SU2_CFD/src/integration/CIntegration.cpp index ca612e7d2369..5ff1aa0715c9 100644 --- a/SU2_CFD/src/integration/CIntegration.cpp +++ b/SU2_CFD/src/integration/CIntegration.cpp @@ -257,6 +257,9 @@ void CIntegration::SetDualTime_Solver(const CGeometry *geometry, CSolver *solver /*--- Initialize the underrelaxation ---*/ solver->GetNodes()->SetUnderRelaxation(iPoint, 1.0); + if (config->GetKind_Incomp_System() == ENUM_INCOMP_SYSTEM::PRESSURE_BASED) + solver->SetMomentumCorrection_DualTime(); + /*--- Initialize the local CFL number ---*/ solver->GetNodes()->SetLocalCFL(iPoint, config->GetCFL(iMesh)); } diff --git a/SU2_CFD/src/integration/CMultiGridIntegration.cpp b/SU2_CFD/src/integration/CMultiGridIntegration.cpp index d335d4d14c48..ee1700a93b37 100644 --- a/SU2_CFD/src/integration/CMultiGridIntegration.cpp +++ b/SU2_CFD/src/integration/CMultiGridIntegration.cpp @@ -748,3 +748,191 @@ void CMultiGridIntegration::Adjoint_Setup(CGeometry ****geometry, CSolver *****s } } + + +void CMultiGridIntegration::MultiGrid_CyclePB(CGeometry ****geometry, + CSolver *****solver, + CNumerics ******numerics, + CConfig **config, + unsigned short iMesh, + unsigned short RecursiveParam, + unsigned short RunTime_EqSystem, + unsigned short iZone, + unsigned short iInst) { + /*--- Not using this routine for now. ---*/ + + unsigned short iPreSmooth, iPostSmooth, iRKStep, iRKLimit = 1, iCorr, nCorr = 1; + + //bool startup_multigrid = (config[iZone]->GetRestart_Flow() && (RunTime_EqSystem == RUNTIME_FLOW_SYS) && (Iteration == 0)); + //bool piso = true; + bool piso = (config[iZone]->GetKind_PBIter() == ENUM_PBITER::PISO); + unsigned short SolContainer_Position = config[iZone]->GetContainerPosition(RunTime_EqSystem); + bool periodic = (config[iZone]->GetnMarker_Periodic() > 0); + + /*--- Do a presmoothing on the grid iMesh to be restricted to the grid iMesh+1 ---*/ + + + for (iPreSmooth = 0; iPreSmooth < config[iZone]->GetMG_PreSmooth(iMesh); iPreSmooth++) { + + /*--- Momentum solve (Predict velocities using existing pressure field)---*/ + switch( config[iZone]->GetKind_Solver() ) { + case MAIN_SOLVER::INC_EULER: + config[iZone]->SetGlobalParam(MAIN_SOLVER::INC_EULER, RUNTIME_FLOW_SYS); break; + + case MAIN_SOLVER::INC_NAVIER_STOKES: + config[iZone]->SetGlobalParam(MAIN_SOLVER::INC_NAVIER_STOKES, RUNTIME_FLOW_SYS); break; + + case MAIN_SOLVER::INC_RANS: + config[iZone]->SetGlobalParam(MAIN_SOLVER::INC_RANS, RUNTIME_FLOW_SYS); break; + } + + config[iZone]->SetKind_TimeIntScheme(config[iZone]->GetKind_TimeIntScheme_Flow()); + + CurrentGridIteration(geometry, solver, numerics, config, iMesh, RUNTIME_FLOW_SYS, iZone, iInst); + + /*--- Set source term for pressure correction equation based on current flow solution ---*/ + solver[iZone][iInst][iMesh][FLOW_SOL]->SetMomCoeff(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], config[iZone], periodic, iMesh); + + solver[iZone][iInst][iMesh][FLOW_SOL]->SetPoissonSourceTerm(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], config[iZone], iMesh); + + /*--- Solve the poisson equation (pressure correction) ---*/ + config[iZone]->SetGlobalParam(MAIN_SOLVER::POISSON_EQUATION, RUNTIME_POISSON_SYS); + config[iZone]->SetKind_TimeIntScheme(config[iZone]->GetKind_TimeIntScheme()); // TODO PBFlow + + for (iCorr = 0; iCorr < nCorr; iCorr++) { + CurrentGridIteration(geometry, solver, numerics, config, iMesh, RUNTIME_POISSON_SYS, iZone, iInst); + } + + /*--- Correct pressure and velocities ---*/ + solver[iZone][iInst][iMesh][FLOW_SOL]->Flow_Correction(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], config[iZone]); + + solver[iZone][iInst][iMesh][FLOW_SOL]->Postprocessing(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], config[iZone], iMesh); + + if (piso) { + config[iZone]->SetKind_TimeIntScheme(EULER_EXPLICIT); + + /*--- Momentum solve (Predict velocities using existing pressure field)---*/ + switch( config[iZone]->GetKind_Solver() ) { + case MAIN_SOLVER::INC_EULER: + config[iZone]->SetGlobalParam(MAIN_SOLVER::INC_EULER, RUNTIME_FLOW_SYS); break; + + case MAIN_SOLVER::INC_NAVIER_STOKES: + config[iZone]->SetGlobalParam(MAIN_SOLVER::INC_NAVIER_STOKES, RUNTIME_FLOW_SYS); break; + + case MAIN_SOLVER::INC_RANS: + config[iZone]->SetGlobalParam(MAIN_SOLVER::INC_RANS, RUNTIME_FLOW_SYS); break; + } + + CurrentGridIteration(geometry, solver, numerics, config, iMesh, RUNTIME_FLOW_SYS, iZone, iInst); + + config[iZone]->SetKind_TimeIntScheme(config[iZone]->GetKind_TimeIntScheme_Flow()); + + /*--- Set source term for pressure correction equation based on current flow solution ---*/ + solver[iZone][iInst][iMesh][FLOW_SOL]->SetMomCoeff(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], config[iZone], periodic, iMesh); + + solver[iZone][iInst][iMesh][FLOW_SOL]->SetPoissonSourceTerm(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], config[iZone], iMesh); + + /*--- Solve the poisson equation (pressure correction) ---*/ + config[iZone]->SetGlobalParam(MAIN_SOLVER::POISSON_EQUATION, RUNTIME_POISSON_SYS); + + config[iZone]->SetKind_TimeIntScheme(config[iZone]->GetKind_TimeIntScheme()); // TODO PBFlow + + CurrentGridIteration(geometry, solver, numerics, config, iMesh, RUNTIME_POISSON_SYS, iZone, iInst); + + /*--- Correct pressure and velocities ---*/ + solver[iZone][iInst][iMesh][FLOW_SOL]->Flow_Correction(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], config[iZone]); + } + + } + /*--- Compute Forcing Term $P_(k+1) = I^(k+1)_k(P_k+F_k(u_k))-F_(k+1)(I^(k+1)_k u_k)$ and update solution for multigrid ---*/ + + if ( iMesh < config[iZone]->GetnMGLevels() ) { + + + /*--- Solution postsmoothing in the prolongated grid ---*/ + + for (iPostSmooth = 0; iPostSmooth < config[iZone]->GetMG_PostSmooth(iMesh); iPostSmooth++) { + + /*--- Momentum solve (Predict velocities using existing pressure field)---*/ + switch( config[iZone]->GetKind_Solver() ) { + case MAIN_SOLVER::EULER: + config[iZone]->SetGlobalParam(MAIN_SOLVER::INC_EULER, RUNTIME_FLOW_SYS); break; + + case MAIN_SOLVER::NAVIER_STOKES: + config[iZone]->SetGlobalParam(MAIN_SOLVER::INC_NAVIER_STOKES, RUNTIME_FLOW_SYS); break; + + case MAIN_SOLVER::RANS: + config[iZone]->SetGlobalParam(MAIN_SOLVER::INC_RANS, RUNTIME_FLOW_SYS); break; + + } + + CurrentGridIteration(geometry, solver, numerics, config, + iMesh, RUNTIME_FLOW_SYS, + iZone, iInst); + + /*--- Set source term for pressure correction equation based on current flow solution ---*/ + solver[iZone][iInst][iMesh][FLOW_SOL]->SetMomCoeff(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], config[iZone], periodic, iMesh); + + solver[iZone][iInst][iMesh][FLOW_SOL]->SetPoissonSourceTerm(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], config[iZone], iMesh); + + + /*--- Solve the poisson equation (pressure correction) ---*/ + config[iZone]->SetGlobalParam(MAIN_SOLVER::POISSON_EQUATION, RUNTIME_POISSON_SYS); + + CurrentGridIteration(geometry, solver, numerics, config, + iMesh, RUNTIME_POISSON_SYS, + iZone, iInst); + + + /*--- Correct pressure and velocities ---*/ + solver[iZone][iInst][iMesh][FLOW_SOL]->Flow_Correction(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], config[iZone]); + } + } +} + +void CMultiGridIntegration::CurrentGridIteration(CGeometry ****geometry, + CSolver *****solver, + CNumerics ******numerics, + CConfig **config, + unsigned short iMesh, + unsigned short RunTime_EqSystem, + unsigned short iZone, + unsigned short iInst) { + + unsigned short SolContainer_Position = config[iZone]->GetContainerPosition(RunTime_EqSystem); + su2double monitor = 0.0; + unsigned short FinestMesh = config[iZone]->GetFinestMesh(); + + + /*--- Send-Receive boundary conditions, and preprocessing ---*/ + + solver[iZone][iInst][iMesh][SolContainer_Position]->Preprocessing(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], config[iZone], iMesh, 0, RunTime_EqSystem, false); + + /*--- Set the old solution ---*/ + + solver[iZone][iInst][iMesh][SolContainer_Position]->Set_OldSolution(); + + /*--- Compute time step, max eigenvalue, and integration scheme (steady and unsteady problems) ---*/ + solver[iZone][iInst][iMesh][SolContainer_Position]->SetTime_Step(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], config[iZone], iMesh, config[iZone]->GetTimeIter()); + + /*--- Space integration ---*/ + Space_Integration(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], numerics[iZone][iInst][iMesh][SolContainer_Position], config[iZone], iMesh, NO_RK_ITER, RunTime_EqSystem); + + /*--- Time integration, update solution using the old solution plus the solution increment ---*/ + Time_Integration(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], config[iZone], NO_RK_ITER, RunTime_EqSystem); + + /*--- Send-Receive boundary conditions, and postprocessing ---*/ + solver[iZone][iInst][iMesh][SolContainer_Position]->Postprocessing(geometry[iZone][iInst][iMesh], solver[iZone][iInst][iMesh], config[iZone], iMesh); + + /*--- Compute adimensional parameters and the convergence monitor ---*/ + + switch (RunTime_EqSystem) { + case RUNTIME_POISSON_SYS: monitor = log10(solver[iZone][iInst][iMesh][POISSON_SOL]->GetRes_RMS(0)); break; + case RUNTIME_FLOW_SYS: monitor = log10(solver[iZone][iInst][iMesh][FLOW_SOL]->GetRes_RMS(0)); break; + } + + /*--- Convergence strategy ---*/ + + //Convergence_Monitoring(geometry[iZone][iInst][FinestMesh], config[iZone], Iteration, monitor, FinestMesh); + +} diff --git a/SU2_CFD/src/iteration/CIterationFactory.cpp b/SU2_CFD/src/iteration/CIterationFactory.cpp index 159d8133c513..ea788498936b 100644 --- a/SU2_CFD/src/iteration/CIterationFactory.cpp +++ b/SU2_CFD/src/iteration/CIterationFactory.cpp @@ -32,6 +32,7 @@ #include "../../include/iteration/CDiscAdjFluidIteration.hpp" #include "../../include/iteration/CDiscAdjHeatIteration.hpp" #include "../../include/iteration/CFluidIteration.hpp" +#include "../../include/iteration/CPBFluidIteration.hpp" #include "../../include/iteration/CFEMFluidIteration.hpp" #include "../../include/iteration/CTurboIteration.hpp" #include "../../include/iteration/CHeatIteration.hpp" @@ -56,6 +57,11 @@ CIteration* CIterationFactory::CreateIteration(MAIN_SOLVER kindSolver, const CCo iteration = new CTurboIteration(config); } + else if (config->GetKind_Incomp_System() == ENUM_INCOMP_SYSTEM::PRESSURE_BASED) { + if (rank == MASTER_NODE) + cout<<"Pressure based fluid iteration."<GetPrandtl_Turb(); Gas_Constant = config->GetGas_ConstantND(); + Flux_Tensor = new su2double* [nVar]; + for (iVar = 0; iVar < (nVar); iVar++) + Flux_Tensor[iVar] = new su2double [nDim] (); + tau = new su2double* [nDim]; for (iDim = 0; iDim < nDim; iDim++) tau[iDim] = new su2double [nDim] (); @@ -1727,3 +1731,186 @@ su2double CNumerics::GetRoe_Dissipation(const su2double Dissipation_i, } return Dissipation_ij; } + +void CNumerics::GetInviscidPBProjFlux(const su2double *val_density, + const su2double *val_velocity, + const su2double *val_pressure, + const su2double *val_normal, + su2double *val_Proj_Flux) { + su2double rhou, rhov, rhow; + + if (nDim == 2) { + rhou = (*val_density)*val_velocity[0]; + rhov = (*val_density)*val_velocity[1]; + + val_Proj_Flux[0] = (rhou*val_velocity[0])*val_normal[0] + rhou*val_velocity[1]*val_normal[1]; + val_Proj_Flux[1] = rhov*val_velocity[0]*val_normal[0] + (rhov*val_velocity[1])*val_normal[1]; + } + else { + rhou = (*val_density)*val_velocity[0]; + rhov = (*val_density)*val_velocity[1]; + rhow = (*val_density)*val_velocity[2]; + + val_Proj_Flux[0] = (rhou*val_velocity[0])*val_normal[0] + rhou*val_velocity[1]*val_normal[1] + rhou*val_velocity[2]*val_normal[2]; + val_Proj_Flux[1] = rhov*val_velocity[0]*val_normal[0] + (rhov*val_velocity[1])*val_normal[1] + rhov*val_velocity[2]*val_normal[2]; + val_Proj_Flux[2] = rhow*val_velocity[0]*val_normal[0] + rhow*val_velocity[1]*val_normal[1] + (rhow*val_velocity[2])*val_normal[2]; + } +} + +void CNumerics::GetInviscidPBProjJac(const su2double val_density, const su2double *val_velocity, const su2double *val_normal, + const su2double val_scale, su2double **val_Proj_Jac_Tensor) { + + unsigned short iDim; + su2double proj_vel; + + proj_vel = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + proj_vel += val_velocity[iDim]*val_normal[iDim]; + + if (nDim == 2) { + val_Proj_Jac_Tensor[0][0] = val_scale*val_density*(val_velocity[0]*val_normal[0] + proj_vel); + val_Proj_Jac_Tensor[0][1] = val_scale*val_density*val_velocity[0]*val_normal[1]; + + val_Proj_Jac_Tensor[1][0] = val_scale*val_density*val_velocity[1]*val_normal[0]; + val_Proj_Jac_Tensor[1][1] = val_scale*val_density*(val_velocity[1]*val_normal[1] + proj_vel); + } + else { + val_Proj_Jac_Tensor[0][0] = val_scale*val_density*(proj_vel+val_velocity[0]*val_normal[0]); + val_Proj_Jac_Tensor[0][1] = val_scale*val_density*(val_velocity[0]*val_normal[1]); + val_Proj_Jac_Tensor[0][2] = val_scale*val_density*(val_velocity[0]*val_normal[2]); + + val_Proj_Jac_Tensor[1][0] = val_scale*val_density*(val_velocity[1]*val_normal[0]); + val_Proj_Jac_Tensor[1][1] = val_scale*val_density*(proj_vel+val_velocity[1]*val_normal[1]); + val_Proj_Jac_Tensor[1][2] = val_scale*val_density*(val_velocity[1]*val_normal[2]); + + val_Proj_Jac_Tensor[2][0] = val_scale*val_density*(val_velocity[2]*val_normal[0]); + val_Proj_Jac_Tensor[2][1] = val_scale*val_density*(val_velocity[2]*val_normal[1]); + val_Proj_Jac_Tensor[2][2] = val_scale*val_density*(proj_vel+val_velocity[2]*val_normal[2]); + + } +} + +void CNumerics::GetViscousPBIncProjFlux(const su2double *val_primvar, + su2double **val_gradprimvar, + const su2double *val_normal, + const su2double val_laminar_viscosity, + const su2double val_eddy_viscosity, + const su2double val_turb_ke) { + + unsigned short iVar, iDim, jDim; + su2double total_viscosity, div_vel, Density; + + Density = val_primvar[nDim+1]; + + total_viscosity = (val_laminar_viscosity + val_eddy_viscosity); + + /*--- The full stress tensor is needed for variable density, as nabla.u != 0 ---*/ + /*--- Note: Gradients are computed as [iDim][jDim] and not [iDim+1][jDim] because + *--- the mean gradient passed here contains only velocities and no pressure. The + *--- mean gradient is computed as PrimVar_Grad[iVar+1][iDim], so no need to repeat.---*/ + + div_vel = 0.0; + for (iDim = 0 ; iDim < nDim; iDim++) + div_vel += val_gradprimvar[iDim][iDim]; + + for (iDim = 0 ; iDim < nDim; iDim++) + for (jDim = 0 ; jDim < nDim; jDim++) + tau[iDim][jDim] = (total_viscosity*(val_gradprimvar[jDim][iDim] + + val_gradprimvar[iDim][jDim] ) + -TWO3*total_viscosity*div_vel*delta[iDim][jDim] + -TWO3*Density*val_turb_ke*delta[iDim][jDim]); + + /*--- Gradient of primitive variables -> [Pressure vel_x vel_y vel_z Density] ---*/ + + if (nDim == 2) { + Flux_Tensor[0][0] = tau[0][0]; + Flux_Tensor[1][0] = tau[0][1]; + + Flux_Tensor[0][1] = tau[1][0]; + Flux_Tensor[1][1] = tau[1][1]; + + } else { + + Flux_Tensor[0][0] = tau[0][0]; + Flux_Tensor[1][0] = tau[0][1]; + Flux_Tensor[2][0] = tau[0][2]; + + Flux_Tensor[0][1] = tau[1][0]; + Flux_Tensor[1][1] = tau[1][1]; + Flux_Tensor[2][1] = tau[1][2]; + + Flux_Tensor[0][2] = tau[2][0]; + Flux_Tensor[1][2] = tau[2][1]; + Flux_Tensor[2][2] = tau[2][2]; + + } + + for (iVar = 0; iVar < nVar; iVar++) { + Proj_Flux_Tensor[iVar] = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Proj_Flux_Tensor[iVar] += Flux_Tensor[iVar][iDim] * val_normal[iDim]; + } + +} + +void CNumerics::GetViscousPBIncProjJacs(const su2double val_laminar_viscosity, + const su2double val_eddy_viscosity, + const su2double val_dist_ij, + const su2double *val_normal, + const su2double val_dS, + su2double **val_Proj_Jac_Tensor_i, su2double **val_Proj_Jac_Tensor_j) { + unsigned short iDim, iVar, jVar; + + su2double theta = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + theta += val_normal[iDim]*val_normal[iDim]; + + su2double total_viscosity = val_laminar_viscosity + val_eddy_viscosity; + su2double factor = total_viscosity/(val_dist_ij)*val_dS; + + if (nDim == 3) { + su2double thetax = theta + val_normal[0]*val_normal[0]/3.0; + su2double thetay = theta + val_normal[1]*val_normal[1]/3.0; + su2double thetaz = theta + val_normal[2]*val_normal[2]/3.0; + + su2double etax = val_normal[1]*val_normal[2]/3.0; + su2double etay = val_normal[0]*val_normal[2]/3.0; + su2double etaz = val_normal[0]*val_normal[1]/3.0; + + val_Proj_Jac_Tensor_i[0][0] = -factor*thetax; + val_Proj_Jac_Tensor_i[0][1] = -factor*etaz; + val_Proj_Jac_Tensor_i[0][2] = -factor*etay; + + val_Proj_Jac_Tensor_i[1][0] = -factor*etaz; + val_Proj_Jac_Tensor_i[1][1] = -factor*thetay; + val_Proj_Jac_Tensor_i[1][2] = -factor*etax; + + val_Proj_Jac_Tensor_i[2][0] = -factor*etay; + val_Proj_Jac_Tensor_i[2][1] = -factor*etax; + val_Proj_Jac_Tensor_i[2][2] = -factor*thetaz; + + + for (iVar = 0; iVar < nVar; iVar++) + for (jVar = 0; jVar < nVar; jVar++) + val_Proj_Jac_Tensor_j[iVar][jVar] = -val_Proj_Jac_Tensor_i[iVar][jVar]; + + } + + if (nDim == 2) { + su2double thetax = theta + val_normal[0]*val_normal[0]/3.0; + su2double thetay = theta + val_normal[1]*val_normal[1]/3.0; + su2double etaz = val_normal[0]*val_normal[1]/3.0; + + + val_Proj_Jac_Tensor_i[0][0] = -factor*thetax; + val_Proj_Jac_Tensor_i[0][1] = -factor*etaz; + + val_Proj_Jac_Tensor_i[1][0] = -factor*etaz; + val_Proj_Jac_Tensor_i[1][1] = -factor*thetay; + + for (iVar = 0; iVar < nVar; iVar++) + for (jVar = 0; jVar < nVar; jVar++) + val_Proj_Jac_Tensor_j[iVar][jVar] = -val_Proj_Jac_Tensor_i[iVar][jVar]; + } + +} \ No newline at end of file diff --git a/SU2_CFD/src/numerics/flow/flow_sources.cpp b/SU2_CFD/src/numerics/flow/flow_sources.cpp index 5ebcbf3096ea..85f59f6cad96 100644 --- a/SU2_CFD/src/numerics/flow/flow_sources.cpp +++ b/SU2_CFD/src/numerics/flow/flow_sources.cpp @@ -569,10 +569,15 @@ CNumerics::ResidualType<> CSourceIncRotatingFrame_Flow::ComputeResidual(const CC unsigned short iDim, iVar, jVar; su2double Momentum[MAXNDIM] = {0}, Velocity_i[MAXNDIM] = {0}; + unsigned short iVel = 1; + if (config->GetKind_Incomp_System()==ENUM_INCOMP_SYSTEM::PRESSURE_BASED) iVel = 0; /*--- Primitive variables plus momentum at the node (point i) ---*/ - DensityInc_i = V_i[nDim+2]; + if (config->GetKind_Incomp_System()==ENUM_INCOMP_SYSTEM::PRESSURE_BASED) + DensityInc_i = V_i[nDim+1]; + else + DensityInc_i = V_i[nDim+2]; for (iDim = 0; iDim < nDim; iDim++) { Velocity_i[iDim] = V_i[iDim+1]; diff --git a/SU2_CFD/src/output/CFlowIncOutput.cpp b/SU2_CFD/src/output/CFlowIncOutput.cpp index 8159c16b3454..ebe1b410300a 100644 --- a/SU2_CFD/src/output/CFlowIncOutput.cpp +++ b/SU2_CFD/src/output/CFlowIncOutput.cpp @@ -39,7 +39,7 @@ CFlowIncOutput::CFlowIncOutput(CConfig *config, unsigned short nDim) : CFlowOutp weakly_coupled_heat = config->GetWeakly_Coupled_Heat(); flamelet = (config->GetKind_Species_Model() == SPECIES_MODEL::FLAMELET); - + pressure_based = (config->GetKind_Incomp_System() == ENUM_INCOMP_SYSTEM::PRESSURE_BASED); streamwisePeriodic = (config->GetKind_Streamwise_Periodic() != ENUM_STREAMWISE_PERIODIC::NONE); streamwisePeriodic_temperature = config->GetStreamwise_Periodic_Temperature(); @@ -92,7 +92,9 @@ CFlowIncOutput::CFlowIncOutput(CConfig *config, unsigned short nDim) : CFlowOutp /*--- Set the default convergence field --- */ - if (convFields.empty()) convFields.emplace_back("RMS_PRESSURE"); + if (convFields.empty() && !pressure_based) convFields.emplace_back("RMS_PRESSURE"); + if (convFields.empty() && pressure_based) convFields.emplace_back("RMS_VELOCITY-X"); + } @@ -100,7 +102,7 @@ void CFlowIncOutput::SetHistoryOutputFields(CConfig *config){ /// BEGIN_GROUP: RMS_RES, DESCRIPTION: The root-mean-square residuals of the SOLUTION variables. /// DESCRIPTION: Root-mean square residual of the pressure. - AddHistoryOutput("RMS_PRESSURE", "rms[P]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of the pressure.", HistoryFieldType::RESIDUAL); + if (!pressure_based) AddHistoryOutput("RMS_PRESSURE", "rms[P]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of the pressure.", HistoryFieldType::RESIDUAL); /// DESCRIPTION: Root-mean square residual of the velocity x-component. AddHistoryOutput("RMS_VELOCITY-X", "rms[U]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of the velocity x-component.", HistoryFieldType::RESIDUAL); /// DESCRIPTION: Root-mean square residual of the velocity y-component. @@ -109,7 +111,8 @@ void CFlowIncOutput::SetHistoryOutputFields(CConfig *config){ if (nDim == 3) AddHistoryOutput("RMS_VELOCITY-Z", "rms[W]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of the velocity z-component.", HistoryFieldType::RESIDUAL); /// DESCRIPTION: Maximum residual of the temperature. if (heat || weakly_coupled_heat) AddHistoryOutput("RMS_TEMPERATURE", "rms[T]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of the temperature.", HistoryFieldType::RESIDUAL); - + /// DESCRIPTION: Maximum residual of the mass flux (only for pressure based). + if (pressure_based) AddHistoryOutput("RMS_MASSFLUX", "rms[Mf]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of the mass flux.", HistoryFieldType::RESIDUAL); AddHistoryOutputFields_ScalarRMS_RES(config); /// DESCRIPTION: Root-mean square residual of the radiative energy (P1 model). @@ -158,6 +161,7 @@ void CFlowIncOutput::SetHistoryOutputFields(CConfig *config){ /// DESCRIPTION: Linear solver iterations AddHistoryOutput("LINSOL_ITER", "LinSolIter", ScreenOutputFormat::INTEGER, "LINSOL", "Number of iterations of the linear solver."); AddHistoryOutput("LINSOL_RESIDUAL", "LinSolRes", ScreenOutputFormat::FIXED, "LINSOL", "Residual of the linear solver."); + AddHistoryOutput("POISSON_RESIDUAL", "PoissonSolRes", ScreenOutputFormat::FIXED, "LINSOL", "Residual of the poisson solver."); AddHistoryOutputFieldsScalarLinsol(config); AddHistoryOutput("MIN_DELTA_TIME", "Min DT", ScreenOutputFormat::SCIENTIFIC, "CFL_NUMBER", "Current minimum local time step"); @@ -199,19 +203,34 @@ void CFlowIncOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolv CSolver* heat_solver = solver[HEAT_SOL]; CSolver* rad_solver = solver[RAD_SOL]; CSolver* mesh_solver = solver[MESH_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))); - if (nDim == 3) SetHistoryOutputValue("RMS_VELOCITY-Z", log10(flow_solver->GetRes_RMS(3))); - + CSolver* poisson_solver = solver[POISSON_SOL]; + + if (pressure_based) { + SetHistoryOutputValue("RMS_MASSFLUX", log10(flow_solver->GetResMassFlux())); // TODO: FIXED + SetHistoryOutputValue("RMS_VELOCITY-X", log10(flow_solver->GetRes_RMS(0))); + SetHistoryOutputValue("RMS_VELOCITY-Y", log10(flow_solver->GetRes_RMS(1))); + if (nDim == 3) SetHistoryOutputValue("RMS_VELOCITY-Z", log10(flow_solver->GetRes_RMS(2))); + } + else { + 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))); + if (nDim == 3) SetHistoryOutputValue("RMS_VELOCITY-Z", log10(flow_solver->GetRes_RMS(3))); + } if (config->AddRadiation()) SetHistoryOutputValue("RMS_RAD_ENERGY", log10(rad_solver->GetRes_RMS(0))); - 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))); - if (nDim == 3) SetHistoryOutputValue("RMS_VELOCITY-Z", log10(flow_solver->GetRes_Max(3))); + if (pressure_based) { + SetHistoryOutputValue("MAX_VELOCITY-X", log10(flow_solver->GetRes_Max(0))); + SetHistoryOutputValue("MAX_VELOCITY-Y", log10(flow_solver->GetRes_Max(1))); + if (nDim == 3) SetHistoryOutputValue("RMS_VELOCITY-Z", log10(flow_solver->GetRes_Max(2))); + } + else { + 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))); + if (nDim == 3) SetHistoryOutputValue("RMS_VELOCITY-Z", log10(flow_solver->GetRes_Max(3))); + } if (multiZone){ SetHistoryOutputValue("BGS_PRESSURE", log10(flow_solver->GetRes_BGS(0))); @@ -241,6 +260,7 @@ void CFlowIncOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolv SetHistoryOutputValue("LINSOL_ITER", flow_solver->GetIterLinSolver()); SetHistoryOutputValue("LINSOL_RESIDUAL", log10(flow_solver->GetResLinSolver())); + if (pressure_based) SetHistoryOutputValue("POISSON_RESIDUAL",log10(poisson_solver->GetResLinSolver())); if (config->GetDeform_Mesh()){ SetHistoryOutputValue("DEFORM_MIN_VOLUME", mesh_solver->GetMinimum_Volume()); @@ -297,7 +317,8 @@ void CFlowIncOutput::SetVolumeOutputFields(CConfig *config){ AddVolumeOutput("VELOCITY-Z", "Velocity_z", "SOLUTION", "z-component of the velocity vector"); if (heat || weakly_coupled_heat || flamelet) AddVolumeOutput("TEMPERATURE", "Temperature","SOLUTION", "Temperature"); - + if (pressure_based) + AddVolumeOutput("MASS_FLUX", "Mass_flux","SOLUTION", "Mass flux at a point"); SetVolumeOutputFieldsScalarSolution(config); // Radiation variables @@ -338,11 +359,21 @@ void CFlowIncOutput::SetVolumeOutputFields(CConfig *config){ } //Residuals - AddVolumeOutput("RES_PRESSURE", "Residual_Pressure", "RESIDUAL", "Residual of the pressure"); - AddVolumeOutput("RES_VELOCITY-X", "Residual_Velocity_x", "RESIDUAL", "Residual of the x-velocity component"); - AddVolumeOutput("RES_VELOCITY-Y", "Residual_Velocity_y", "RESIDUAL", "Residual of the y-velocity component"); - if (nDim == 3) - AddVolumeOutput("RES_VELOCITY-Z", "Residual_Velocity_z", "RESIDUAL", "Residual of the z-velocity component"); + if (pressure_based) { + AddVolumeOutput("RES_VELOCITY-X", "Residual_Velocity_x", "RESIDUAL", "Residual of the x-velocity component"); + AddVolumeOutput("RES_VELOCITY-Y", "Residual_Velocity_y", "RESIDUAL", "Residual of the y-velocity component"); + if (nDim == 3) + AddVolumeOutput("RES_VELOCITY-Z", "Residual_Velocity_z", "RESIDUAL", "Residual of the z-velocity component"); + AddVolumeOutput("RES_MASSFLUX", "Residual_Mass_Flux", "RESIDUAL", "Residual of the mass flux"); + } + else { + AddVolumeOutput("RES_PRESSURE", "Residual_Pressure", "RESIDUAL", "Residual of the pressure"); + AddVolumeOutput("RES_VELOCITY-X", "Residual_Velocity_x", "RESIDUAL", "Residual of the x-velocity component"); + AddVolumeOutput("RES_VELOCITY-Y", "Residual_Velocity_y", "RESIDUAL", "Residual of the y-velocity component"); + if (nDim == 3) + AddVolumeOutput("RES_VELOCITY-Z", "Residual_Velocity_z", "RESIDUAL", "Residual of the z-velocity component"); + AddVolumeOutput("RES_TEMPERATURE", "Residual_Temperature", "RESIDUAL", "Residual of the temperature"); + } if (config->GetEnergy_Equation()) AddVolumeOutput("RES_TEMPERATURE", "Residual_Temperature", "RESIDUAL", "Residual of the temperature"); @@ -393,14 +424,32 @@ void CFlowIncOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolve LoadCoordinates(Node_Geo->GetCoord(iPoint), iPoint); - SetVolumeOutputValue("PRESSURE", iPoint, Node_Flow->GetSolution(iPoint, 0)); - SetVolumeOutputValue("VELOCITY-X", iPoint, Node_Flow->GetSolution(iPoint, 1)); - SetVolumeOutputValue("VELOCITY-Y", iPoint, Node_Flow->GetSolution(iPoint, 2)); - if (nDim == 3) - SetVolumeOutputValue("VELOCITY-Z", iPoint, Node_Flow->GetSolution(iPoint, 3)); - - if (heat || flamelet) SetVolumeOutputValue("TEMPERATURE", iPoint, Node_Flow->GetSolution(iPoint, nDim+1)); - if (weakly_coupled_heat) SetVolumeOutputValue("TEMPERATURE", iPoint, Node_Heat->GetSolution(iPoint, 0)); +//TODO:PBFlow +/* TO BE REOMOVED */ +// SetVolumeOutputValue("PRESSURE", iPoint, Node_Flow->GetSolution(iPoint, 0)); +// SetVolumeOutputValue("VELOCITY-X", iPoint, Node_Flow->GetSolution(iPoint, 1)); +// SetVolumeOutputValue("VELOCITY-Y", iPoint, Node_Flow->GetSolution(iPoint, 2)); // TODO: To be fixed +// if (nDim == 3) +// SetVolumeOutputValue("VELOCITY-Z", iPoint, Node_Flow->GetSolution(iPoint, 3)); + +// if (heat || flamelet) SetVolumeOutputValue("TEMPERATURE", iPoint, Node_Flow->GetSolution(iPoint, nDim+1)); +// if (weakly_coupled_heat) SetVolumeOutputValue("TEMPERATURE", iPoint, Node_Heat->GetSolution(iPoint, 0)); + + if (pressure_based) { + SetVolumeOutputValue("PRESSURE", iPoint, Node_Flow->GetPressure(iPoint)); + SetVolumeOutputValue("VELOCITY-X", iPoint, Node_Flow->GetSolution(iPoint, 0)); + SetVolumeOutputValue("VELOCITY-Y", iPoint, Node_Flow->GetSolution(iPoint, 1)); + if (nDim == 3) SetVolumeOutputValue("VELOCITY-Z", iPoint, Node_Flow->GetSolution(iPoint, 2)); + SetVolumeOutputValue("MASS_FLUX", iPoint, Node_Flow->GetMassFlux(iPoint)); + } else { + SetVolumeOutputValue("PRESSURE", iPoint, Node_Flow->GetSolution(iPoint, 0)); + SetVolumeOutputValue("VELOCITY-X", iPoint, Node_Flow->GetSolution(iPoint, 1)); + SetVolumeOutputValue("VELOCITY-Y", iPoint, Node_Flow->GetSolution(iPoint, 2)); + if (nDim == 3) + SetVolumeOutputValue("VELOCITY-Z", iPoint, Node_Flow->GetSolution(iPoint, 3)); + } + if (heat || flamelet) SetVolumeOutputValue("TEMPERATURE", iPoint, Node_Flow->GetSolution(iPoint, nDim+1)); + if (weakly_coupled_heat) SetVolumeOutputValue("TEMPERATURE", iPoint, Node_Heat->GetSolution(iPoint, 0)); // Radiation solver if (config->AddRadiation()){ @@ -425,13 +474,30 @@ void CFlowIncOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolve SetVolumeOutputValue("THERMAL_CONDUCTIVITY", iPoint, Node_Flow->GetThermalConductivity(iPoint)); } - SetVolumeOutputValue("RES_PRESSURE", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 0)); - SetVolumeOutputValue("RES_VELOCITY-X", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 1)); - SetVolumeOutputValue("RES_VELOCITY-Y", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 2)); - if (nDim == 3) - SetVolumeOutputValue("RES_VELOCITY-Z", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 3)); - if (config->GetEnergy_Equation()) - SetVolumeOutputValue("RES_TEMPERATURE", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, nDim+1)); + if (pressure_based) { + SetVolumeOutputValue("RES_VELOCITY-X", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 0)); + SetVolumeOutputValue("RES_VELOCITY-Y", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 1)); + if (nDim == 3) + SetVolumeOutputValue("RES_VELOCITY-Z", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 2)); + SetVolumeOutputValue("RES_MASSFLUX", iPoint, solver[POISSON_SOL]->LinSysRes(iPoint, 0)); + } else { + SetVolumeOutputValue("RES_PRESSURE", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 0)); + SetVolumeOutputValue("RES_VELOCITY-X", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 1)); + SetVolumeOutputValue("RES_VELOCITY-Y", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 2)); + if (nDim == 3) + SetVolumeOutputValue("RES_VELOCITY-Z", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 3)); + SetVolumeOutputValue("RES_TEMPERATURE", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, nDim+1)); + } + +// TODO: PBFlow +/* TO BE REMOVED */ +// SetVolumeOutputValue("RES_PRESSURE", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 0)); +// SetVolumeOutputValue("RES_VELOCITY-X", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 1)); +// SetVolumeOutputValue("RES_VELOCITY-Y", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 2)); +// if (nDim == 3) +// SetVolumeOutputValue("RES_VELOCITY-Z", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, 3)); +// if (config->GetEnergy_Equation()) +// SetVolumeOutputValue("RES_TEMPERATURE", iPoint, solver[FLOW_SOL]->LinSysRes(iPoint, nDim+1)); if (config->GetKind_SlopeLimit_Flow() != LIMITER::NONE && config->GetKind_SlopeLimit_Flow() != LIMITER::VAN_ALBADA_EDGE) { SetVolumeOutputValue("LIMITER_PRESSURE", iPoint, Node_Flow->GetLimiter_Primitive(iPoint, 0)); diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index 5ed2862922a7..ce2f26f22366 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -1501,14 +1501,15 @@ void CFlowOutput::LoadVolumeDataScalar(const CConfig* config, const CSolver* con SetVolumeOutputValue("CFL", iPoint, Node_Flow->GetLocalCFL(iPoint)); if (config->GetViscous()) { - if (nDim == 3){ + // TODO: PBFlow to be fixed + if (nDim == 3) { SetVolumeOutputValue("VORTICITY_X", iPoint, Node_Flow->GetVorticity(iPoint)[0]); SetVolumeOutputValue("VORTICITY_Y", iPoint, Node_Flow->GetVorticity(iPoint)[1]); SetVolumeOutputValue("VORTICITY_Z", iPoint, Node_Flow->GetVorticity(iPoint)[2]); } else { - SetVolumeOutputValue("VORTICITY", iPoint, Node_Flow->GetVorticity(iPoint)[2]); + SetVolumeOutputValue("VORTICITY", iPoint, 0.0); //Node_Flow->GetVorticity(iPoint)[2]); // TODO: PBFlow } - SetVolumeOutputValue("Q_CRITERION", iPoint, GetQCriterion(Node_Flow->GetVelocityGradient(iPoint))); + SetVolumeOutputValue("Q_CRITERION", iPoint, 0.0); //GetQCriterion(Node_Flow->GetVelocityGradient(iPoint))); // TODO: PBFlow } const bool limiter = (config->GetKind_SlopeLimit_Turb() != LIMITER::NONE); diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index d8f538456224..475e4d7f9497 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -2566,6 +2566,10 @@ void CIncEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, } break; + case INC_OUTLET_TYPE::OPEN: + SU2_MPI::Error("Boundary condition not implemented for density-based incompressible solver.", CURRENT_FUNCTION); + break; + } diff --git a/SU2_CFD/src/solvers/CSolver.cpp b/SU2_CFD/src/solvers/CSolver.cpp index 5cd2fd93425b..e237350ecad9 100644 --- a/SU2_CFD/src/solvers/CSolver.cpp +++ b/SU2_CFD/src/solvers/CSolver.cpp @@ -276,6 +276,10 @@ void CSolver::GetPeriodicCommCountAndType(const CConfig* config, MPI_TYPE = COMM_TYPE_DOUBLE; ICOUNT = nVar; break; + case PERIODIC_PRESSURE: + COUNT_PER_POINT = 1; + MPI_TYPE = COMM_TYPE_DOUBLE; + break; default: SU2_MPI::Error("Unrecognized quantity for periodic communication.", CURRENT_FUNCTION); @@ -350,8 +354,9 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, bool boundary_i, boundary_j; bool weighted = true; + bool pressure_based = (config->GetKind_Incomp_System() == ENUM_INCOMP_SYSTEM::PRESSURE_BASED); - unsigned short iVar, jVar, iDim; + unsigned short iVar, jVar, iDim, iVel; unsigned short nNeighbor = 0; unsigned short COUNT_PER_POINT = 0; unsigned short MPI_TYPE = 0; @@ -386,6 +391,8 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, }; string Marker_Tag; + + if (pressure_based) iVel = 0; /*--- Set the size of the data packet and type depending on quantity. ---*/ @@ -970,7 +977,7 @@ void CSolver::InitiatePeriodicComms(CGeometry *geometry, break; - default: + default: SU2_MPI::Error("Unrecognized quantity for periodic communication.", CURRENT_FUNCTION); break; @@ -1291,8 +1298,8 @@ void CSolver::CompletePeriodicComms(CGeometry *geometry, limiter(iPoint, iVar) = min(limiter(iPoint, iVar), bufDRecv[buf_offset+iVar]); break; - - default: + + default: SU2_MPI::Error("Unrecognized quantity for periodic communication.", CURRENT_FUNCTION); @@ -1368,7 +1375,15 @@ void CSolver::GetCommCountAndType(const CConfig* config, COUNT_PER_POINT = nDim*base_nodes->GetnAuxVar(); MPI_TYPE = COMM_TYPE_DOUBLE; break; - case MESH_DISPLACEMENTS: + case MASS_FLUX: + COUNT_PER_POINT = 1; + MPI_TYPE = COMM_TYPE_DOUBLE; + break; + case PRESSURE_VAR: + COUNT_PER_POINT = 1; + MPI_TYPE = COMM_TYPE_DOUBLE; + break; + case MESH_DISPLACEMENTS: COUNT_PER_POINT = nDim; MPI_TYPE = COMM_TYPE_DOUBLE; break; @@ -1380,6 +1395,10 @@ void CSolver::GetCommCountAndType(const CConfig* config, COUNT_PER_POINT = nVar; MPI_TYPE = COMM_TYPE_DOUBLE; break; + case MOM_COEFF: + COUNT_PER_POINT = nVar; + MPI_TYPE = COMM_TYPE_DOUBLE; + break; default: SU2_MPI::Error("Unrecognized quantity for point-to-point MPI comms.", CURRENT_FUNCTION); @@ -1516,6 +1535,16 @@ void CSolver::InitiateComms(CGeometry *geometry, bufDSend[buf_offset+nVar*2+iVar] = base_nodes->GetSolution_Accel(iPoint, iVar); } } + break; + case MOM_COEFF: + for (iVar = 0; iVar < nVar; iVar++) + bufDSend[buf_offset+iVar] = base_nodes->Get_Mom_Coeff(iPoint, iVar); + break; + case MASS_FLUX: + bufDSend[buf_offset] = base_nodes->GetMassFlux(iPoint); + break; + case PRESSURE_VAR: + bufDSend[buf_offset] = base_nodes->GetPrimitive(iPoint, 0); break; case MESH_DISPLACEMENTS: for (iDim = 0; iDim < nDim; iDim++) diff --git a/SU2_CFD/src/solvers/CSolverFactory.cpp b/SU2_CFD/src/solvers/CSolverFactory.cpp index cf252ba018da..35204c257012 100644 --- a/SU2_CFD/src/solvers/CSolverFactory.cpp +++ b/SU2_CFD/src/solvers/CSolverFactory.cpp @@ -29,8 +29,11 @@ #include "../../include/solvers/CSolverFactory.hpp" #include "../../include/solvers/CEulerSolver.hpp" #include "../../include/solvers/CIncEulerSolver.hpp" +#include "../../include/solvers/CPBIncEulerSolver.hpp" #include "../../include/solvers/CNSSolver.hpp" #include "../../include/solvers/CIncNSSolver.hpp" +#include "../../include/solvers/CPBIncNSSolver.hpp" +#include "../../include/solvers/CPoissonSolverFVM.hpp" #include "../../include/solvers/CNEMOEulerSolver.hpp" #include "../../include/solvers/CNEMONSSolver.hpp" #include "../../include/solvers/CTurbSASolver.hpp" @@ -69,6 +72,7 @@ CSolver** CSolverFactory::CreateSolverContainer(MAIN_SOLVER kindMainSolver, CCon case MAIN_SOLVER::INC_EULER: solver[FLOW_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::INC_EULER, solver, geometry, config, iMGLevel); solver[RAD_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::RADIATION, solver, geometry, config, iMGLevel); + solver[POISSON_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::POISSON_EQUATION, solver, geometry, config, iMGLevel); break; case MAIN_SOLVER::EULER: solver[FLOW_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::EULER, solver, geometry, config, iMGLevel); @@ -81,6 +85,7 @@ CSolver** CSolverFactory::CreateSolverContainer(MAIN_SOLVER kindMainSolver, CCon solver[HEAT_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::HEAT, solver, geometry, config, iMGLevel); solver[RAD_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::RADIATION, solver, geometry, config, iMGLevel); solver[SPECIES_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::SPECIES, solver, geometry, config, iMGLevel); + solver[POISSON_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::POISSON_EQUATION, solver, geometry, config, iMGLevel); break; case MAIN_SOLVER::NAVIER_STOKES: solver[FLOW_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::NAVIER_STOKES, solver, geometry, config, iMGLevel); @@ -103,6 +108,7 @@ CSolver** CSolverFactory::CreateSolverContainer(MAIN_SOLVER kindMainSolver, CCon solver[TURB_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::TURB, solver, geometry, config, iMGLevel); solver[TRANS_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::TRANSITION, solver, geometry, config, iMGLevel); solver[RAD_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::RADIATION, solver, geometry, config, iMGLevel); + solver[POISSON_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::POISSON_EQUATION, solver, geometry, config, iMGLevel); break; case MAIN_SOLVER::HEAT_EQUATION: solver[HEAT_SOL] = CreateSubSolver(SUB_SOLVER_TYPE::HEAT, solver, geometry, config, iMGLevel); @@ -324,6 +330,12 @@ CSolver* CSolverFactory::CreateSubSolver(SUB_SOLVER_TYPE kindSolver, CSolver **s } metaData.integrationType = INTEGRATION_TYPE::DEFAULT; break; + case SUB_SOLVER_TYPE::POISSON_EQUATION: + if (config->GetKind_Incomp_System() == ENUM_INCOMP_SYSTEM::PRESSURE_BASED) { + genericSolver = new CPoissonSolverFVM(geometry, config); + } + metaData.integrationType = INTEGRATION_TYPE::MULTIGRID; + break; default: SU2_MPI::Error("No proper allocation found for requested sub solver", CURRENT_FUNCTION); break; @@ -484,11 +496,32 @@ CSolver* CSolverFactory::CreateFlowSolver(SUB_SOLVER_TYPE kindFlowSolver, CSolve flowSolver = new CNSSolver(geometry, config, iMGLevel); break; case SUB_SOLVER_TYPE::INC_EULER: - flowSolver = new CIncEulerSolver(geometry, config, iMGLevel); - flowSolver->Preprocessing(geometry, solver, config, iMGLevel, NO_RK_ITER, RUNTIME_FLOW_SYS, false); + switch (config->GetKind_Incomp_System()) { + case ENUM_INCOMP_SYSTEM::DENSITY_BASED: + flowSolver = new CIncEulerSolver(geometry, config, iMGLevel); + flowSolver->Preprocessing(geometry, solver, config, iMGLevel, NO_RK_ITER, RUNTIME_FLOW_SYS, false); + break; + case ENUM_INCOMP_SYSTEM::PRESSURE_BASED: + flowSolver = new CPBIncEulerSolver(geometry, config, iMGLevel); + flowSolver->Preprocessing(geometry, solver, config, iMGLevel, NO_RK_ITER, RUNTIME_FLOW_SYS, false); + break; + default: + SU2_MPI::Error("Flow solver not found", CURRENT_FUNCTION); + break; + } break; case SUB_SOLVER_TYPE::INC_NAVIER_STOKES: - flowSolver = new CIncNSSolver(geometry, config, iMGLevel); + switch (config->GetKind_Incomp_System()) { + case ENUM_INCOMP_SYSTEM::DENSITY_BASED: + flowSolver = new CIncNSSolver(geometry, config, iMGLevel); + break; + case ENUM_INCOMP_SYSTEM::PRESSURE_BASED: + flowSolver = new CPBIncNSSolver(geometry, config, iMGLevel); + break; + default: + SU2_MPI::Error("Flow solver not found", CURRENT_FUNCTION); + break; + } break; case SUB_SOLVER_TYPE::NEMO_EULER: flowSolver = new CNEMOEulerSolver(geometry, config, iMGLevel); diff --git a/SU2_CFD/src/solvers/CTurbSASolver.cpp b/SU2_CFD/src/solvers/CTurbSASolver.cpp index 2d301dc77220..f91a0dd5a736 100644 --- a/SU2_CFD/src/solvers/CTurbSASolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSASolver.cpp @@ -312,7 +312,8 @@ void CTurbSASolver::Source_Residual(CGeometry *geometry, CSolver **solver_contai const bool harmonic_balance = (config->GetTime_Marching() == TIME_MARCHING::HARMONIC_BALANCE); const bool transition_BC = config->GetSAParsedOptions().bc; - auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); + // auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); + auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); // TODO:PBFlow: Bad fix /*--- Pick one numerics object per thread. ---*/ auto* numerics = numerics_container[SOURCE_FIRST_TERM + omp_get_thread_num()*MAX_TERMS]; diff --git a/SU2_CFD/src/variables/CIncNSVariable.cpp b/SU2_CFD/src/variables/CIncNSVariable.cpp index e32b8d6dd73d..7c8f820ef297 100644 --- a/SU2_CFD/src/variables/CIncNSVariable.cpp +++ b/SU2_CFD/src/variables/CIncNSVariable.cpp @@ -126,3 +126,55 @@ bool CIncNSVariable::SetPrimVar(unsigned long iPoint, su2double eddy_visc, su2do return physical; } + +bool CIncNSVariable::SetVorticity_StrainMag() { + + for (unsigned long iPoint = 0; iPoint < nPoint; ++iPoint) { + + /*--- Vorticity ---*/ + + Vorticity(iPoint,0) = 0.0; Vorticity(iPoint,1) = 0.0; + + Vorticity(iPoint,2) = Gradient_Primitive(iPoint,2,0)-Gradient_Primitive(iPoint,1,1); + + if (nDim == 3) { + Vorticity(iPoint,0) = Gradient_Primitive(iPoint,3,1)-Gradient_Primitive(iPoint,2,2); + Vorticity(iPoint,1) = -(Gradient_Primitive(iPoint,3,0)-Gradient_Primitive(iPoint,1,2)); + } + + /*--- Strain Magnitude ---*/ + + AD::StartPreacc(); + AD::SetPreaccIn(Gradient_Primitive[iPoint], nDim+1, nDim); + + su2double Div = 0.0; + for (unsigned long iDim = 0; iDim < nDim; iDim++) + Div += Gradient_Primitive(iPoint,iDim+1,iDim); + + StrainMag(iPoint) = 0.0; + + /*--- Add diagonal part ---*/ + + for (unsigned long iDim = 0; iDim < nDim; iDim++) { + StrainMag(iPoint) += pow(Gradient_Primitive(iPoint,iDim+1,iDim) - 1.0/3.0*Div, 2.0); + } + if (nDim == 2) { + StrainMag(iPoint) += pow(1.0/3.0*Div, 2.0); + } + + /*--- Add off diagonals ---*/ + + StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,1,1) + Gradient_Primitive(iPoint,2,0)), 2); + + if (nDim == 3) { + StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,1,2) + Gradient_Primitive(iPoint,3,0)), 2); + StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,2,2) + Gradient_Primitive(iPoint,3,1)), 2); + } + + StrainMag(iPoint) = sqrt(2.0*StrainMag(iPoint)); + + AD::SetPreaccOut(StrainMag(iPoint)); + AD::EndPreacc(); + } + return false; +} \ No newline at end of file diff --git a/SU2_CFD/src/variables/CNSVariable.cpp b/SU2_CFD/src/variables/CNSVariable.cpp index b2fe70b35cc9..dfce3ac29fb9 100644 --- a/SU2_CFD/src/variables/CNSVariable.cpp +++ b/SU2_CFD/src/variables/CNSVariable.cpp @@ -45,6 +45,59 @@ CNSVariable::CNSVariable(su2double density, const su2double *velocity, su2double } +bool CNSVariable::SetVorticity_StrainMag() { + + SU2_OMP_FOR_STAT(256) + for (unsigned long iPoint = 0; iPoint < nPoint; ++iPoint) { + + /*--- Vorticity ---*/ + + Vorticity(iPoint,0) = 0.0; Vorticity(iPoint,1) = 0.0; + + Vorticity(iPoint,2) = Gradient_Primitive(iPoint,2,0)-Gradient_Primitive(iPoint,1,1); + + if (nDim == 3) { + Vorticity(iPoint,0) = Gradient_Primitive(iPoint,3,1)-Gradient_Primitive(iPoint,2,2); + Vorticity(iPoint,1) = -(Gradient_Primitive(iPoint,3,0)-Gradient_Primitive(iPoint,1,2)); + } + + /*--- Strain Magnitude ---*/ + + AD::StartPreacc(); + AD::SetPreaccIn(Gradient_Primitive[iPoint], nDim+1, nDim); + + su2double Div = 0.0; + for (unsigned long iDim = 0; iDim < nDim; iDim++) + Div += Gradient_Primitive(iPoint,iDim+1,iDim); + + StrainMag(iPoint) = 0.0; + + /*--- Add diagonal part ---*/ + + for (unsigned long iDim = 0; iDim < nDim; iDim++) { + StrainMag(iPoint) += pow(Gradient_Primitive(iPoint,iDim+1,iDim) - 1.0/3.0*Div, 2.0); + } + if (nDim == 2) { + StrainMag(iPoint) += pow(1.0/3.0*Div, 2.0); + } + + /*--- Add off diagonals ---*/ + + StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,1,1) + Gradient_Primitive(iPoint,2,0)), 2); + + if (nDim == 3) { + StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,1,2) + Gradient_Primitive(iPoint,3,0)), 2); + StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,2,2) + Gradient_Primitive(iPoint,3,1)), 2); + } + + StrainMag(iPoint) = sqrt(2.0*StrainMag(iPoint)); + + AD::SetPreaccOut(StrainMag(iPoint)); + AD::EndPreacc(); + } + return false; +} + void CNSVariable::SetRoe_Dissipation_NTS(unsigned long iPoint, su2double val_delta, su2double val_const_DES){ From 06935e19a69e73ad0bde5ea0454c2025cbbd0479 Mon Sep 17 00:00:00 2001 From: Nitish Anand Date: Tue, 13 Feb 2024 16:37:53 +0100 Subject: [PATCH 2/6] Some new files needed for the new solver --- .../include/iteration/CPBFluidIteration.hpp | 74 + SU2_CFD/include/numerics/pbflow.hpp | 232 ++ SU2_CFD/include/numerics/poisson.hpp | 219 ++ SU2_CFD/include/solvers/CPBIncEulerSolver.hpp | 386 +++ SU2_CFD/include/solvers/CPBIncNSSolver.hpp | 99 + SU2_CFD/include/solvers/CPoissonSolverFVM.hpp | 247 ++ .../include/variables/CPBIncEulerVariable.hpp | 450 +++ .../include/variables/CPBIncNSVariable.hpp | 144 + SU2_CFD/src/iteration/CPBFluidIteration.cpp | 139 + SU2_CFD/src/numerics/heat.cpp | 322 ++ SU2_CFD/src/numerics/pbflow.cpp | 573 ++++ SU2_CFD/src/numerics/poisson.cpp | 421 +++ SU2_CFD/src/solvers/CPBIncEulerSolver.cpp | 2779 +++++++++++++++++ SU2_CFD/src/solvers/CPBIncNSSolver.cpp | 562 ++++ SU2_CFD/src/solvers/CPoissonSolverFVM.cpp | 586 ++++ SU2_CFD/src/variables/CPBIncEulerVariable.cpp | 199 ++ SU2_CFD/src/variables/CPBIncNSVariable.cpp | 118 + 17 files changed, 7550 insertions(+) create mode 100644 SU2_CFD/include/iteration/CPBFluidIteration.hpp create mode 100644 SU2_CFD/include/numerics/pbflow.hpp create mode 100644 SU2_CFD/include/numerics/poisson.hpp create mode 100644 SU2_CFD/include/solvers/CPBIncEulerSolver.hpp create mode 100644 SU2_CFD/include/solvers/CPBIncNSSolver.hpp create mode 100644 SU2_CFD/include/solvers/CPoissonSolverFVM.hpp create mode 100644 SU2_CFD/include/variables/CPBIncEulerVariable.hpp create mode 100644 SU2_CFD/include/variables/CPBIncNSVariable.hpp create mode 100644 SU2_CFD/src/iteration/CPBFluidIteration.cpp create mode 100644 SU2_CFD/src/numerics/heat.cpp create mode 100644 SU2_CFD/src/numerics/pbflow.cpp create mode 100644 SU2_CFD/src/numerics/poisson.cpp create mode 100644 SU2_CFD/src/solvers/CPBIncEulerSolver.cpp create mode 100644 SU2_CFD/src/solvers/CPBIncNSSolver.cpp create mode 100644 SU2_CFD/src/solvers/CPoissonSolverFVM.cpp create mode 100644 SU2_CFD/src/variables/CPBIncEulerVariable.cpp create mode 100644 SU2_CFD/src/variables/CPBIncNSVariable.cpp diff --git a/SU2_CFD/include/iteration/CPBFluidIteration.hpp b/SU2_CFD/include/iteration/CPBFluidIteration.hpp new file mode 100644 index 000000000000..2169a099fcab --- /dev/null +++ b/SU2_CFD/include/iteration/CPBFluidIteration.hpp @@ -0,0 +1,74 @@ +/*! + * \file CIteration.hpp + * \brief Headers of the iteration classes used by SU2_CFD. + * Each CIteration class represents an available physics package. + * \author F. Palacios, T. Economon + * \version 8.0.0 "Harrier" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2020, SU2 Contributors (cf. AUTHORS.md) + * + * 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 "CFluidIteration.hpp" + +/*! + * \class CFluidIteration + * \brief Class for driving an iteration of the fluid system. + * \author T. Economon + */ +class CPBFluidIteration : public CFluidIteration { +public: + + /*! + * \brief Constructor of the class. + * \param[in] config - Definition of the particular problem. + */ + CPBFluidIteration(const CConfig *config) ; + + /*! + * \brief Preprocessing to prepare for an iteration of the physics. + * \param[in] ??? - Description here. + */ + void Preprocess(COutput* output, CIntegration**** integration, CGeometry**** geometry, CSolver***** solver, + CNumerics****** numerics, CConfig** config, CSurfaceMovement** surface_movement, + CVolumetricMovement*** grid_movement, CFreeFormDefBox*** FFDBox, unsigned short val_iZone, + unsigned short val_iInst) final; + + /*! + * \brief Perform a single iteration of the fluid system. + * \param[in] output - Pointer to the COutput class. + * \param[in] integration_container - Container vector with all the integration methods. + * \param[in] geometry_container - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). + * \param[in] config_container - Definition of the particular problem. + * \param[in] surface_movement - Surface movement classes of the problem. + * \param[in] grid_movement - Volume grid movement classes of the problem. + * \param[in] FFDBox - FFD FFDBoxes of the problem. + */ + void Iterate(COutput* output, CIntegration**** integration, CGeometry**** geometry, CSolver***** solver, + CNumerics****** numerics, CConfig** config, CSurfaceMovement** surface_movement, + CVolumetricMovement*** grid_movement, CFreeFormDefBox*** FFDBox, unsigned short val_iZone, + unsigned short val_iInst) final; + +}; + diff --git a/SU2_CFD/include/numerics/pbflow.hpp b/SU2_CFD/include/numerics/pbflow.hpp new file mode 100644 index 000000000000..637db426d1fa --- /dev/null +++ b/SU2_CFD/include/numerics/pbflow.hpp @@ -0,0 +1,232 @@ +/*! + * \file pbflow.hpp + * \brief Delarations of numerics classes for heat transfer problems. + * \author F. Palacios, T. Economon + * \version 8.0.0 "Harrier" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2020, SU2 Contributors (cf. AUTHORS.md) + * + * 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 "CNumerics.hpp" + +/*! + * \class CUpwPB_Flow + * \brief Class for solving an approximate Riemann solver of Roe for the pressure based incompressible flow equations. + * \ingroup ConvDiscr + * \author F. Palacios + */ +class CUpwPB_Flow : public CNumerics { +private: + bool implicit, dynamic_grid; + bool gravity; + su2double Froude, Upw_i, Upw_j; + su2double *Diff_U; + su2double *Velocity_i, *Velocity_j, *MeanVelocity, *Velocity_upw; + su2double *ProjFlux_i, *ProjFlux_j; + su2double Proj_ModJac_Tensor_ij, Pressure_i, + Pressure_j, MeanDensity, MeanSoundSpeed, MeanPressure, MeanBetaInc2, + ProjVelocity, FaceVel, Face_Flux; + unsigned short iDim, iVar, jVar, kVar; + + su2double *Flux = nullptr; + su2double **Jacobian_i = nullptr; + su2double **Jacobian_j = nullptr; + su2double **Jacobian_upw = nullptr; + +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. + */ + CUpwPB_Flow(unsigned short val_nDim, unsigned short val_nVar, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + ~CUpwPB_Flow(void); + + /*! + * \brief Compute the Roe's flux between two nodes i and j. + * \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. + */ + ResidualType<> ComputeResidual(const CConfig* config) override; + + /*! + * \brief Set the value of face velocity. This is used as a proxy for massflux at a face. + * \param[in] val_FaceVel. + */ + inline void SetFaceVel(su2double val_FaceVel){ FaceVel = val_FaceVel; } +}; + + +/*! + * \class CCentLaxArtComp_Flow + * \brief Class for computing the Lax-Friedrich centered scheme (artificial compressibility). + * \ingroup ConvDiscr + * \author F. Palacios + */ +class CCentPB_Flow : public CNumerics { +private: + bool implicit, dynamic_grid; + bool gravity; + su2double Froude, Upw_i, Upw_j; + su2double *Diff_U; + su2double *Velocity_i, *Velocity_j, *MeanVelocity, *Velocity_upw; + su2double *ProjFlux_i, *ProjFlux_j; + su2double *Lambda, *Epsilon; + su2double **P_Tensor, **invP_Tensor,**val_Jacobian_upw; + su2double Proj_ModJac_Tensor_ij, Pressure_i, + Pressure_j, MeanDensity, MeanSoundSpeed, MeanPressure, MeanBetaInc2, + ProjVelocity, FaceVel; + unsigned short iDim, iVar, jVar, kVar; + + su2double *Flux = nullptr; + su2double **Jacobian_i = nullptr; + su2double **Jacobian_j = nullptr; + su2double **Jacobian_upw = nullptr; + +public: + + /*! + * \brief Constructor of the class. + * \param[in] val_nDim - Number of dimension of the problem. + * \param[in] val_nVar - Number of variables of the problem. + * \param[in] config - Definition of the particular problem. + */ + CCentPB_Flow(unsigned short val_nDim, unsigned short val_nVar, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + ~CCentPB_Flow(void); + + /*! + * \brief Compute the flow residual using a Lax method. + * \param[out] val_resconv - Pointer to the convective residual. + * \param[out] val_resvisc - Pointer to the artificial viscosity 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. + */ + ResidualType<> ComputeResidual(const CConfig* config) override; +}; + +/*! + * \class CAvgGradInc_Flow + * \brief Class for computing viscous term using an average of gradients. + * \ingroup ViscDiscr + * \author A. Bueno, F. Palacios, T. Economon + */ +class CAvgGradPBInc_Flow : public CNumerics { +private: + unsigned short iDim, iVar, jVar; /*!< \brief Iterators in dimension an variable. */ + su2double *Mean_PrimVar, /*!< \brief Mean primitive variables. */ + *PrimVar_i, *PrimVar_j; /*!< \brief Primitives variables at point i and j. */ + su2double **Mean_GradPrimVar, /*!< \brief Mean value of the gradient. */ + Mean_Laminar_Viscosity, Mean_Eddy_Viscosity, /*!< \brief Mean value of the viscosity. */ + Mean_turb_ke, /*!< \brief Mean value of the turbulent kinetic energy. */ + dist_ij, /*!< \brief Length of the edge and face. */ + proj_vector_ij; /*!< \brief (Edge_Vector DOT normal)/|Edge_Vector|^2 */ + bool implicit; /*!< \brief Implicit calculus. */ + + su2double *Flux = nullptr; + su2double **Jacobian_i = nullptr; + su2double **Jacobian_j = nullptr; + +public: + + /*! + * \brief Constructor of the class. + * \param[in] val_nDim - Number of dimension of the problem. + * \param[in] val_nVar - Number of variables of the problem. + * \param[in] config - Definition of the particular problem. + */ + CAvgGradPBInc_Flow(unsigned short val_nDim, unsigned short val_nVar, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + ~CAvgGradPBInc_Flow(void); + /*! + * \brief Compute the viscous flow residual using an average of gradients. + * \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. + */ + ResidualType<> ComputeResidual(const CConfig* config) override; +}; + + +/*! + * \class CAvgGradCorrectedPBInc_Flow + * \brief Class for computing viscous term using an average of gradients with correction (incompressible). + * \ingroup ViscDiscr + */ +class CAvgGradCorrectedPBInc_Flow : public CNumerics { +private: + unsigned short iDim, iVar, jVar; /*!< \brief Iterators in dimension an variable. */ + su2double *Mean_PrimVar; /*!< \brief Mean primitive variables. */ + su2double *PrimVar_i, *PrimVar_j, /*!< \brief Primitives variables at point i and 1. */ + *Edge_Vector, /*!< \brief Vector form point i to point j. */ + **Mean_GradPrimVar, *Proj_Mean_GradPrimVar_Edge, /*!< \brief Mean value of the gradient. */ + Mean_Laminar_Viscosity, Mean_Eddy_Viscosity, /*!< \brief Mean value of the viscosity. */ + Mean_turb_ke, /*!< \brief Mean value of the turbulent kinetic energy. */ + dist_ij_2, /*!< \brief Length of the edge and face. */ + proj_vector_ij; /*!< \brief (Edge_Vector DOT normal)/|Edge_Vector|^2 */ + bool implicit; /*!< \brief Implicit calculus. */ + + su2double *Flux = nullptr; + su2double **Jacobian_i = nullptr; + su2double **Jacobian_j = nullptr; + +public: + + /*! + * \brief Constructor of the class. + * \param[in] val_nDim - Number of dimension of the problem. + * \param[in] val_nVar - Number of variables of the problem. + * \param[in] config - Definition of the particular problem. + */ + CAvgGradCorrectedPBInc_Flow(unsigned short val_nDim, unsigned short val_nVar, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + ~CAvgGradCorrectedPBInc_Flow(void); + + /*! + * \brief Compute the viscous flow residual using an average of gradients with correction. + * \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. + */ + ResidualType<> ComputeResidual(const CConfig* config) override; +}; diff --git a/SU2_CFD/include/numerics/poisson.hpp b/SU2_CFD/include/numerics/poisson.hpp new file mode 100644 index 000000000000..21fe28d60b03 --- /dev/null +++ b/SU2_CFD/include/numerics/poisson.hpp @@ -0,0 +1,219 @@ +/*! + * \file heat.hpp + * \brief Delarations of numerics classes for heat transfer problems. + * \author F. Palacios, T. Economon + * \version 8.0.0 "Harrier" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2020, SU2 Contributors (cf. AUTHORS.md) + * + * 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 "CNumerics.hpp" + +/*! + * \class CAvgGrad_Poisson + * \brief Class for computing viscous term using average of gradients without correction (Poisson equation). + * \ingroup ViscDiscr + */ +class CAvgGrad_Poisson : public CNumerics { +private: + + su2double *Edge_Vector; + bool implicit,direct; + su2double **Mean_GradPoissonVar; + su2double *Mom_Coeff_i,*Mom_Coeff_j; + su2double *Proj_Mean_GradPoissonVar_Normal, *Proj_Mean_GradPoissonVar_Corrected; + su2double dist_ij_2, proj_vector_ij, Poisson_Coeff_Mean ; + unsigned short iVar, iDim; + + su2double *Flux = nullptr; + su2double **Jacobian_i = nullptr; + su2double **Jacobian_j = nullptr; + +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_Poisson(unsigned short val_nDim, unsigned short val_nVar, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + ~CAvgGrad_Poisson(void); + + /*! + * \brief Compute the viscous heat residual using an average of gradients with correction. + * \param[out] val_residual - Pointer to the total residual. + * \param[out] Jacobian_i - Jacobian of the numerical method at node i (implicit computation). + * \param[out] Jacobian_j - Jacobian of the numerical method at node j (implicit computation). + * \param[in] config - Definition of the particular problem. + */ + ResidualType<> ComputeResidual(const CConfig* config) override; + + + inline void SetInvMomCoeff(su2double *val_Mom_Coeff_i, su2double *val_Mom_Coeff_j) { + for (unsigned short iDim = 0; iDim < nDim; iDim++) { + Mom_Coeff_i[iDim] = val_Mom_Coeff_i[iDim]; + Mom_Coeff_j[iDim] = val_Mom_Coeff_j[iDim]; + } + } +}; + +/*! + * \class CAvgGradCorrected_Poisson + * \brief Class for computing viscous term using average of gradients with correction (Poisson equation). + * \ingroup ViscDiscr + */ + +class CAvgGradCorrected_Poisson : public CNumerics { +private: + + su2double *Edge_Vector; + bool implicit,direct; + su2double **Mean_GradPoissonVar; + su2double *Mom_Coeff_i,*Mom_Coeff_j; + su2double *Proj_Mean_GradPoissonVar_Kappa, *Proj_Mean_GradPoissonVar_Edge, *Proj_Mean_GradPoissonVar_Corrected; + su2double dist_ij_2, proj_vector_ij, Poisson_Coeff_Mean; + unsigned short iVar, iDim; + + su2double *Flux = nullptr; + su2double **Jacobian_i = nullptr; + su2double **Jacobian_j = nullptr; + +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. + */ + CAvgGradCorrected_Poisson(unsigned short val_nDim, unsigned short val_nVar, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + ~CAvgGradCorrected_Poisson(void); + + /*! + * \brief Compute the viscous residual using an average of gradients with correction. + * \param[out] val_residual - Pointer to the total residual. + * \param[out] Jacobian_i - Jacobian of the numerical method at node i (implicit computation). + * \param[out] Jacobian_j - Jacobian of the numerical method at node j (implicit computation). + * \param[in] config - Definition of the particular problem. + */ + ResidualType<> ComputeResidual(const CConfig* config) override; + + + inline void SetInvMomCoeff(su2double *val_Mom_Coeff_i, su2double *val_Mom_Coeff_j) { + for (unsigned short iDim = 0; iDim < nDim; iDim++) { + Mom_Coeff_i[iDim] = val_Mom_Coeff_i[iDim]; + Mom_Coeff_j[iDim] = val_Mom_Coeff_j[iDim]; + } + } +}; + +/*! + * \class CAvgGrad_Poisson + * \brief Class for computing viscous term using average of gradients without correction (Poisson equation). + * \ingroup ViscDiscr + */ +class CPressure_Poisson : public CNumerics { +private: + + su2double *Edge_Vector; + bool implicit,direct; + su2double **Mean_GradPoissonVar; + su2double *Proj_Mean_GradPoissonVar_Kappa, *Proj_Mean_GradPoissonVar_Edge, *Proj_Mean_GradPoissonVar_Corrected; + su2double dist_ij_2, proj_vector_ij, Poisson_Coeff_Mean; + su2double *Mom_Coeff_i,*Mom_Coeff_j; + unsigned short iVar, iDim; + +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. + */ + CPressure_Poisson(unsigned short val_nDim, unsigned short val_nVar, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + ~CPressure_Poisson(void); + + /*! + * \brief Compute the viscous heat residual using an average of gradients with correction. + * \param[out] val_residual - Pointer to the total residual. + * \param[out] Jacobian_i - Jacobian of the numerical method at node i (implicit computation). + * \param[out] 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 **Jacobian_i, su2double **Jacobian_j, CConfig *config); + + + inline void SetInvMomCoeff(su2double *val_Mom_Coeff_i, su2double *val_Mom_Coeff_j) { + for (unsigned short iDim = 0; iDim < nDim; iDim++) { + Mom_Coeff_i[iDim] = val_Mom_Coeff_i[iDim]; + Mom_Coeff_j[iDim] = val_Mom_Coeff_j[iDim]; + } + } +}; + +/*! + * \class CSource_Poisson + * \brief Class for source term of the Poisson equation. + * \ingroup SourceDiscr + */ +class CSource_PoissonFVM : public CNumerics { +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 - Name of the input config file + * + */ + CSource_PoissonFVM(unsigned short val_nDim, unsigned short val_nVar, CConfig *config); + + + /*! + * \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[in] config - Definition of the particular problem. + */ + void ComputeResidual(su2double *val_residual, su2double **Jacobian_i, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + ~CSource_PoissonFVM(void); +}; + diff --git a/SU2_CFD/include/solvers/CPBIncEulerSolver.hpp b/SU2_CFD/include/solvers/CPBIncEulerSolver.hpp new file mode 100644 index 000000000000..81a0e0b2b165 --- /dev/null +++ b/SU2_CFD/include/solvers/CPBIncEulerSolver.hpp @@ -0,0 +1,386 @@ +/*! + * \file CIncEulerSolver.hpp + * \brief Headers of the CIncEulerSolver class + * \author F. Palacios, T. Economon, T. Albring + * \version 8.0.0 "Harrier" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2020, SU2 Contributors (cf. AUTHORS.md) + * + * 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 "CFVMFlowSolverBase.hpp" +#include "../variables/CPBIncEulerVariable.hpp" + +class CPBIncEulerSolver : public CFVMFlowSolverBase { +protected: + +su2double + *Primitive = nullptr, /*!< \brief Auxiliary nPrimVar vector. */ + *Primitive_i = nullptr, /*!< \brief Auxiliary nPrimVar vector for storing the primitive at point i. */ + *Primitive_j = nullptr; /*!< \brief Auxiliary nPrimVar vector for storing the primitive at point j. */ + + CFluidModel *FluidModel; /*!< \brief fluid model used in the solver */ + + su2double ResMassFlux; + su2activematrix PseudoTimeCorr, TimeMarchingCorr_n, TimeMarchingCorr_n1; + + su2activematrix FaceVelocity, FaceVelocityCorrec; + + unsigned long PRef_Point = 1; /*!< \brief Store the index of reference cell for pressure */ + bool PRef_Check; /*!< \brief To check if a reference pressure cell is necessary */ + unsigned long nEdge; + +public: + +// CPBIncEulerSolver() = delete; + + /*! + * \brief Constructor of the class. + */ +// CPBIncEulerSolver(void): CFVMFlowSolverBase() {*geometry, *config} + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + CPBIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh, const bool navier_stokes = false); + + /*! + * \brief Destructor of the class. + */ + ~CPBIncEulerSolver(void) override; + + /*! + * \brief Set the solver nondimensionalization. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void SetNondimensionalization(CConfig *config, unsigned short iMesh); + + /*! + * \brief Compute the time step for solving the Euler equations. + * \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] Iteration - Value of the current iteration. + */ + void SetTime_Step(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned long Iteration) override; + + /*! + * \brief Compute the spatial integration using a centered scheme. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics_container - 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 Centered_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics **numerics_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep) final; + + /*! + * \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_container - 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_container, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \brief Source term integration. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics_container - Description of the 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_container, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \brief Source term integration. + * \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 Source_Template(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \brief Compute primitive variables and their 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] 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) override; + + /*! + * \brief A virtual member. + * \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. + */ + void Postprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Compute the velocity^2, SoundSpeed, Pressure, Enthalpy, Viscosity. + * \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 Impose the far-field boundary condition using characteristics. + * \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) final; + + /*! + * \brief Impose a subsonic 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) final; + + /*! + * \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) final; + + /*! + * \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) override; + + /*! + * \brief compare to values. + * \param[in] a - value 1. + * \param[in] b - value 2. + */ + static bool Compareval(std::vector a,std::vector b); + + /*! + * \brief Update the solution using the explicit Euler 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 ExplicitEuler_Iteration(CGeometry *geometry, + CSolver **solver_container, + CConfig *config) final; + + /*! + * \brief Update the solution using an implicit Euler 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) final; + + /*! + * \brief Set the total residual adding the term that comes from the Dual Time Strategy. + * \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] 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) final; + + /*! + * \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) final; + + /*! + * \brief Set the initial condition for the Euler Equations. + * \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 TimeIter) final; + + /*! + * \brief Print verification error to screen. + * \param[in] config - Definition of the particular problem. + */ + void PrintVerificationError(const CConfig* config) const final; + + + /*! + * \brief Correct the velocity using the velocity corrections. + * + * + */ + void Flow_Correction(CGeometry *geometry, CSolver **solver_container, CConfig *config) override; + + /*! + * \brief Compute the source term for the pressure correction equation based + * on the residuals from the solution of momentum equation. + * + */ + void SetPoissonSourceTerm(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh); + + /*! + * \brief Compute the coefficients for the pressure correction equation based + * on the residuals from the solution of momentum equation. + */ + void SetMomCoeff(CGeometry *geometry, CSolver **solver_container, CConfig *config, bool periodic, unsigned short iMesh); + + /*! + * \brief Compute the coefficients for the pressure correction equation based + * on the residuals from the solution of momentum equation in a periodic problem. + */ + void SetMomCoeffPer(CGeometry *geometry, CSolver **solver_container, CConfig *config); + + /*! + * \brief Update corrections for the Rhie-Chow interpolation for unsteady problems. + */ + void SetMomentumCorrection_DualTime(); + + /*! + * \brief Set the convergence of mass flux for current internal iteration. + */ + void SetResMassFluxZero() { ResMassFlux = 0.0; } + + /*! + * \brief Set the convergence of mass flux for current internal iteration. + */ + void SetResMassFlux(su2double val_ResMassFlux) { ResMassFlux = val_ResMassFlux; } + + /*! + * \brief Set the convergence of mass flux for current internal iteration. + */ + void SetResMassFluxRMS(CGeometry *geometry, CConfig *config); + + /*! + * \brief Set the convergence of mass flux for current internal iteration. + */ + void AddResMassFlux(su2double val_ResMassFlux) { ResMassFlux += val_ResMassFlux; } + + /*! + * \brief Get the convergence of mass flux for current internal iteration. + * \return Value of the residual for the variable in the position val_var. + */ + su2double GetResMassFlux(void) const { return ResMassFlux; } + +}; diff --git a/SU2_CFD/include/solvers/CPBIncNSSolver.hpp b/SU2_CFD/include/solvers/CPBIncNSSolver.hpp new file mode 100644 index 000000000000..bdea1664df99 --- /dev/null +++ b/SU2_CFD/include/solvers/CPBIncNSSolver.hpp @@ -0,0 +1,99 @@ +#pragma once + +#include "CPBIncEulerSolver.hpp" + +/*! + * \class CPBIncNSSolver + * \brief Main class for defining the pressure based incompressible Navier-Stokes flow solver. + * \ingroup Navier_Stokes_Equations + */ +class CPBIncNSSolver final : public CPBIncEulerSolver { + +public: + + /*! + * \brief Constructor of the class. + */ +// CPBIncNSSolver(void): CPBIncEulerSolver() {} + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + CPBIncNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); + + /*! + * \brief Compute the time step for solving the Navier-Stokes equations with turbulence 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. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] Iteration - Index of the current iteration. + */ + void SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, + unsigned short iMesh, unsigned long Iteration); + + /*! + * \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] 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 A virtual member. + * \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. + */ + void Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh); + + /*! + * \brief Compute the velocity^2, SoundSpeed, Pressure, Enthalpy, Viscosity. + * \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 Impose a no-slip 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 an isothermal temperature condition at the wall. + * \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 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_container, + CConfig *config, unsigned short iMesh, unsigned short iRKStep); +}; diff --git a/SU2_CFD/include/solvers/CPoissonSolverFVM.hpp b/SU2_CFD/include/solvers/CPoissonSolverFVM.hpp new file mode 100644 index 000000000000..190af8d6191d --- /dev/null +++ b/SU2_CFD/include/solvers/CPoissonSolverFVM.hpp @@ -0,0 +1,247 @@ +/*! + * \file CHeatSolver.hpp + * \brief Headers of the CHeatSolver class + * \author F. Palacios, T. Economon + * \version 7.0.2 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2020, SU2 Contributors (cf. AUTHORS.md) + * + * 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 "CSolver.hpp" +#include "../variables/CPBIncEulerVariable.hpp" + +/*! \class CPoissonSolverFVM + * \brief Main class for defining the poisson finite volume solver. + * \version 6.0.0 "Falcon" + */ +class CPoissonSolverFVM : public CSolver { +protected: + static constexpr size_t MAXNDIM = 3; /*!< \brief Max number of space dimensions, used in some static arrays. */ + su2double **CoeffMatrix_Node; /*!< \brief Auxiliary matrices for storing point to point coefficient matrices. */ + + CPoissonVariable* 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. + */ + CPoissonSolverFVM(void); + + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + CPoissonSolverFVM(CGeometry *geometry, CConfig *config); + + + /*! + * \brief Destructor of the class. + */ + ~CPoissonSolverFVM(void); + + + /*! + * \brief Return the value at the dirichlet boundary + * + */ +// su2double GetDirichlet_BC(CGeometry *geometry, CConfig *config, unsigned long Point); + + /*! + * \brief Compute the spatial integration using a centered 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. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + */ + void Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, CConfig *config, + unsigned short iMesh, unsigned short iRKStep); + /*! + * \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 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 Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, + unsigned short iMesh); + + + void SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, + unsigned short iMesh, unsigned long Iteration); + /*! + * \brief A virtual member. + * \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 *conv_numerics, CNumerics *visc_numerics,CConfig *config, + unsigned short val_marker) final; + /*! + * \brief A virtual member. + * \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_Sym_Plane(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, + unsigned short val_marker); + + + /*! + * \brief A virtual member. + * \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_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker); + + + /*! + * \brief A virtual member. + * \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 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_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) final; + + /*! + * \brief Set residuals to zero. + * \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] 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 Source term integration. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics_container - Description of the 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_container, + CConfig *config, + unsigned short iMesh) final; + + /*! + * \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] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, + CConfig *config, unsigned short iMesh); + + /*! + * \brief Update the solution using an implicit solver. + * \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 Update the solution using an explicit solver. + * \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 ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config); + +}; diff --git a/SU2_CFD/include/variables/CPBIncEulerVariable.hpp b/SU2_CFD/include/variables/CPBIncEulerVariable.hpp new file mode 100644 index 000000000000..42fb606091d3 --- /dev/null +++ b/SU2_CFD/include/variables/CPBIncEulerVariable.hpp @@ -0,0 +1,450 @@ +/*! + * \file CPBIncEulerVariable.hpp + * \brief Class for defining the variables of the pressure based incompressible Euler solver. + * \author F. Palacios, 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" +#include "CIncEulerVariable.hpp" + +/*! + * \class CPBIncEulerVariable + * \brief Class for defining the variables of the pressure based incompressible Euler solver. + * \ingroup Euler_Equations + * \author A. Koodly + */ +class CPBIncEulerVariable : public CVariable { +protected: + VectorType Velocity2; /*!< \brief Square of the velocity vector. */ + MatrixType Primitive; /*!< \brief Primitive variables (P, vx, vy, vz, T, rho, beta, lamMu, EddyMu, Kt_eff, Cp, Cv) in incompressible flows. */ + CVectorOfMatrix Gradient_Primitive; /*!< \brief Gradient of the primitive variables (P, vx, vy, vz, T, rho, beta). */ + CVectorOfMatrix& Gradient_Reconstruction; /*!< \brief Reference to the gradient of the primitive variables for MUSCL reconstruction for the convective term */ + CVectorOfMatrix Gradient_Aux; /*!< \brief Auxiliary structure to store a second gradient for reconstruction, if required. */ + MatrixType Limiter_Primitive; /*!< \brief Limiter of the primitive variables (P, vx, vy, vz, T, rho, beta). */ + VectorType Density_Old; /*!< \brief Old density for variable density turbulent flows (SST). */ + + VectorType MassFlux; /*!< \brief Massflux associated with each CV */ + MatrixType Mom_Coeff; + MatrixType Mom_Coeff_nb; + using BoolVectorType = C2DContainer; + BoolVectorType strong_bc; + VectorType StrainMag; /*!< \brief Magnitude of rate of strain tensor. */ + + +public: +mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reconstruction counter for each edge. */ + static constexpr size_t MAXNVAR = 7; + template + struct CIndices { + const IndexType nDim; + CIndices(IndexType ndim, IndexType) : nDim(ndim) {} + inline IndexType NDim() const { return nDim; } + // inline IndexType NSpecies() const { return 0; } + inline IndexType Pressure() const { return 0; } + inline IndexType Velocity() const { return 1; } + // inline IndexType Temperature() const { return nDim+1; } + inline IndexType Density() const { return nDim+1; } + // inline IndexType Beta() const { return nDim+3; } + // inline IndexType SoundSpeed() const { return Beta(); } + inline IndexType LaminarViscosity() const { return nDim+2; } + inline IndexType EddyViscosity() const { return nDim+3; } + inline IndexType Temperature() const { return nDim+4; } + // inline IndexType ThermalConductivity() const { return nDim+4; } + // inline IndexType CpTotal() const { return nDim+7; } + // inline IndexType CvTotal() const { return nDim+8; } + + /*--- For compatible interface with NEMO. ---*/ + // inline IndexType SpeciesDensities() const { return std::numeric_limits::max(); } + inline IndexType Temperature_ve() const { return std::numeric_limits::max(); } + // inline IndexType Enthalpy() const { return std::numeric_limits::max(); } + + }; + /*! + * \brief Constructor of the class. + * \param[in] val_pressure - value of the pressure. + * \param[in] velocity - Value of the flow velocity (initialization value). + * \param[in] temperature - Value of the temperature (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] config - Definition of the particular problem. + */ + CPBIncEulerVariable(su2double density, su2double pressure, const su2double *velocity, + unsigned long npoint, unsigned long ndim, unsigned long nvar, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + virtual ~CPBIncEulerVariable() = default; + + /*! + * \brief Get the primitive variable gradients for all points. + * \return Reference to primitive variable gradient. + */ + inline CVectorOfMatrix& GetGradient_Primitive(void) { return Gradient_Primitive; } + + /*! + * \brief Get the reconstruction gradient for primitive variable at all points. + * \return Reference to variable reconstruction gradient. + */ + inline CVectorOfMatrix& GetGradient_Reconstruction(void) final { return Gradient_Reconstruction; } + + /*! + * \brief Add value to the gradient of the primitive variables. + * \param[in] iPoint - Point index. + * \param[in] iVar - Index of the variable. + * \param[in] iDim - Index of the dimension. + * \param[in] value - Value to add to the gradient of the primitive variables. + */ + inline void AddGradient_Primitive(unsigned long iPoint, unsigned long iVar, unsigned long iDim, su2double value) final { + Gradient_Primitive(iPoint,iVar,iDim) += value; + } + + /*! + * \brief Get the value of the primitive variables gradient. + * \param[in] iPoint - Point index. + * \param[in] iVar - Index of the variable. + * \param[in] iDim - Index of the dimension. + * \return Value of the primitive variables gradient. + */ + inline su2double GetGradient_Primitive(unsigned long iPoint, unsigned long iVar, unsigned long iDim) const final { + return Gradient_Primitive(iPoint,iVar,iDim); + } + + /*! + * \brief Get the primitive variables limiter. + * \return Primitive variables limiter for the entire domain. + */ + inline MatrixType& GetLimiter_Primitive(void) {return Limiter_Primitive; } + + /*! + * \brief Get the value of the primitive variables gradient. + * \param[in] iPoint - Point index. + * \param[in] iVar - Index of the variable. + * \return Value of the primitive variables gradient. + */ + inline su2double GetLimiter_Primitive(unsigned long iPoint, unsigned long iVar) const final { + return Limiter_Primitive(iPoint,iVar); + } + + /*! + * \brief Set the gradient of the primitive variables. + * \param[in] iPoint - Point index. + * \param[in] iVar - Index of the variable. + * \param[in] iDim - Index of the dimension. + * \param[in] value - Value of the gradient. + */ + inline void SetGradient_Primitive(unsigned long iPoint, unsigned long iVar, unsigned long iDim, su2double value) final { + Gradient_Primitive(iPoint,iVar,iDim) = value; + } + + /*! + * \brief Set the gradient of the primitive variables. + * \param[in] iPoint - Point index. + * \param[in] iVar - Index of the variable. + * \param[in] value - Value of the gradient. + */ + inline void SetLimiter_Primitive(unsigned long iPoint, unsigned long iVar, su2double value) final { + Limiter_Primitive(iPoint,iVar) = value; + } + + /*! + * \brief Get the value of the primitive variables gradient. + * \param[in] iPoint - Point index. + * \return Value of the primitive variables gradient. + */ + inline CMatrixView GetGradient_Primitive(unsigned long iPoint, unsigned long iVar=0) final { return Gradient_Primitive[iPoint]; } + + /*! + * \brief Get the value of the primitive variables gradient. + * \param[in] iPoint - Point index. + * \return Value of the primitive variables gradient. + */ + inline su2double *GetLimiter_Primitive(unsigned long iPoint) final { return Limiter_Primitive[iPoint]; } + + /*! + * \brief Get the value of the reconstruction variables gradient at a node. + * \param[in] iPoint - Index of the current node. + * \param[in] iVar - Index of the variable. + * \param[in] iDim - Index of the dimension. + * \return Value of the reconstruction variables gradient at a node. + */ + inline su2double GetGradient_Reconstruction(unsigned long iPoint, unsigned long iVar, unsigned long iDim) const final { + return Gradient_Reconstruction(iPoint,iVar,iDim); + } + + /*! + * \brief Get the value of the reconstruction variables gradient at a node. + * \param[in] iPoint - Index of the current node. + * \param[in] iVar - Index of the variable. + * \param[in] iDim - Index of the dimension. + * \param[in] value - Value of the reconstruction gradient component. + */ + inline void SetGradient_Reconstruction(unsigned long iPoint, unsigned long iVar, unsigned long iDim, su2double value) final { + Gradient_Reconstruction(iPoint,iVar,iDim) = value; + } + + /*! + * \brief Get the array of the reconstruction variables gradient at a node. + * \param[in] iPoint - Index of the current node. + * \return Array of the reconstruction variables gradient at a node. + */ + inline CMatrixView GetGradient_Reconstruction(unsigned long iPoint) final { return Gradient_Reconstruction[iPoint]; } + + /*! + * \brief Get the primitive variables for all points. + * \return Reference to primitives. + */ + inline const MatrixType& GetPrimitive(void) const { return Primitive; } + + /*! + * \brief Get the primitive variables. + * \param[in] iPoint - Point index. + * \param[in] iVar - Index of the variable. + * \return Value of the primitive variable for the index iVar. + */ + inline su2double GetPrimitive(unsigned long iPoint, unsigned long iVar) const final { return Primitive(iPoint,iVar); } + + /*! + * \brief Set the value of the primitive variables. + * \param[in] iPoint - Point index. + * \param[in] iVar - Index of the variable. + * \param[in] iVar - Index of the variable. + * \return Set the value of the primitive variable for the index iVar. + */ + inline void SetPrimitive(unsigned long iPoint, unsigned long iVar, su2double val_prim) final { Primitive(iPoint,iVar) = val_prim; } + + /*! + * \brief Set the value of the primitive variables. + * \param[in] iPoint - Point index. + * \param[in] val_prim - Primitive variables. + * \return Set the value of the primitive variable for the index iVar. + */ + inline void SetPrimitive(unsigned long iPoint, const su2double *val_prim) final { + for (unsigned long iVar = 0; iVar < nPrimVar; iVar++) Primitive(iPoint,iVar) = val_prim[iVar]; + } + + /*! + * \brief Get the primitive variables of the problem. + * \param[in] iPoint - Point index. + * \return Pointer to the primitive variable vector. + */ + inline su2double *GetPrimitive(unsigned long iPoint) final { return Primitive[iPoint]; } + + /*! + * \brief Set the value of the pressure. + */ + inline void SetPressure_val(unsigned long iPoint, su2double val_pressure) { Primitive(iPoint,0) = val_pressure; } + + /*! + * \brief Set the value of the density for the incompressible flows. + * \param[in] iPoint - Point index. + */ + inline bool SetDensity(unsigned long iPoint, su2double val_density) final { + Primitive(iPoint,nDim+1) = val_density; + if (Primitive(iPoint,nDim+1) > 0.0) return false; + else return true; + } + + /*! + * \brief Set the value of the density for the incompressible flows. + * \param[in] iPoint - Point index. + */ + inline void SetVelocity(unsigned long iPoint) final { + Velocity2(iPoint) = 0.0; + for (unsigned long iDim = 0; iDim < nDim; iDim++) { + Primitive(iPoint,iDim+1) = Solution(iPoint,iDim)/Primitive(iPoint, nDim+1); + Velocity2(iPoint) += pow(Primitive(iPoint,iDim+1),2); + } + } + + /*! + * \brief Get the norm 2 of the velocity. + * \return Norm 2 of the velocity vector. + */ + inline su2double GetVelocity2(unsigned long iPoint) const final { return Velocity2(iPoint); } + + /*! + * \brief Get the flow pressure. + * \return Value of the flow pressure. + */ + inline su2double GetPressure(unsigned long iPoint) const final { return Primitive(iPoint,0); } + + /*! + * \brief Get the density of the flow. + * \return Value of the density of the flow. + */ + inline su2double GetDensity(unsigned long iPoint) const final { return Primitive(iPoint,nDim+1); } + + /*! + * \brief Get the density of the flow from the previous iteration. + * \return Old value of the density of the flow. + */ + inline su2double GetDensity_Old(unsigned long iPoint) const final { return Density_Old(iPoint); } + + /*! + * \brief Get the velocity of the flow. + * \param[in] iDim - Index of the dimension. + * \return Value of the velocity for the dimension iDim. + */ + inline su2double GetVelocity(unsigned long iPoint, unsigned long iDim) const final { return Primitive(iPoint,iDim+1); } + + /*! + * \brief Get the projected velocity in a unitary vector direction (compressible solver). + * \param[in] val_vector - Direction of projection. + * \return Value of the projected velocity. + */ + inline su2double GetProjVel(unsigned long iPoint, const su2double *val_vector) const final { + su2double ProjVel = 0.0; + for (unsigned long iDim = 0; iDim < nDim; iDim++) + ProjVel += Primitive(iPoint,iDim+1)*val_vector[iDim]; + return ProjVel; + } + + /*! + * \brief Set the velocity vector from the old solution. + * \param[in] val_velocity - Pointer to the velocity. + */ + inline void SetVelocity_Old(unsigned long iPoint, const su2double *val_velocity) final { + for (unsigned long iDim = 0; iDim < nDim; iDim++) + Solution_Old(iPoint,iDim) = Primitive(iPoint,nDim+1)*val_velocity[iDim]; + } + + /*! + * \brief Set all the primitive variables for incompressible flows. + */ + bool SetPrimVar(unsigned long iPoint, su2double Density_Inf, CConfig *config); + + inline void Set_Mom_CoeffZero(unsigned long iPoint) { + for (unsigned short iDim = 0; iDim < nDim; iDim++) + Mom_Coeff(iPoint,iDim) = 0.0; + } + + inline su2double Get_Mom_Coeff(unsigned long iPoint, unsigned short val_Var) { return Mom_Coeff(iPoint,val_Var);} + + inline void Set_Mom_Coeff(unsigned long iPoint, const su2double *val_Mom_Coeff) { + for (unsigned short iDim = 0; iDim < nDim; iDim++) + Mom_Coeff(iPoint,iDim) = val_Mom_Coeff[iDim]; + } + + inline void Set_Mom_Coeff(unsigned long iPoint, unsigned short val_Var, su2double val_Mom_Coeff) { Mom_Coeff(iPoint,val_Var) = val_Mom_Coeff; } + + inline su2double Get_Mom_Coeff_nb(unsigned long iPoint, unsigned short val_Var) { return Mom_Coeff_nb(iPoint,val_Var);} + + inline void Set_Mom_Coeff_nb(unsigned long iPoint, su2double *val_Mom_Coeff) { + for (unsigned short iDim = 0; iDim < nDim; iDim++) + Mom_Coeff_nb(iPoint,iDim) = val_Mom_Coeff[iDim]; + } + + inline void Set_Mom_Coeff_nb(unsigned long iPoint, unsigned short val_Var, su2double val_Mom_Coeff) { Mom_Coeff_nb(iPoint,val_Var) = val_Mom_Coeff; } + + inline void Set_Mom_Coeff_nbZero(unsigned long iPoint) { + for (unsigned short iDim = 0; iDim < nDim; iDim++) + Mom_Coeff_nb(iPoint,iDim) = 0.0; + } + + inline void Add_Mom_Coeff_nb(unsigned long iPoint, su2double val_coeff_nb, unsigned short val_Var) { Mom_Coeff_nb(iPoint,val_Var) += val_coeff_nb;} + + inline void Add_Mom_Coeff(unsigned long iPoint, su2double val_coeff, unsigned short val_Var) { Mom_Coeff(iPoint,val_Var) += val_coeff;} + + inline void SetStrongBC(unsigned long iPoint) { strong_bc(iPoint) = true; } + + inline void ResetStrongBC(unsigned long iPoint) { strong_bc(iPoint) = false; } + + inline bool GetStrongBC(unsigned long iPoint) { return strong_bc(iPoint); } + + inline void SetMassFluxZero(unsigned iPoint) {MassFlux(iPoint) = 0.0; } + + inline void SetMassFlux(unsigned long iPoint, su2double val_MassFlux) { MassFlux(iPoint) = val_MassFlux; } + + inline void AddMassFlux(unsigned long iPoint, su2double val_MassFlux) {MassFlux(iPoint) += val_MassFlux; } + + inline void SubtractMassFlux(unsigned long iPoint, su2double val_MassFlux) {MassFlux(iPoint) -= val_MassFlux; } + + inline su2double GetMassFlux(unsigned long iPoint) const { return MassFlux(iPoint); } + + /*! + * \brief Get the entire vector of the rate of strain magnitude. + * \return Vector of magnitudes. + */ + inline su2activevector& GetStrainMag() { return StrainMag; } + +}; + + + + +/*! + * \class CPoissonVariable + * \brief Main class for defining the variables of the potential solver. + * \ingroup Potential_Flow_Equation + * \author F. Palacios + */ +class CPoissonVariable : public CVariable { + VectorType SourceTerm; + VectorType Poisson_Coeff; + using BoolVectorType = C2DContainer; + BoolVectorType strong_bc; +public: + /*! + * \overload + * \param[in] val_potential - Value of the potential solution (initialization value). + * \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. + */ + CPoissonVariable(su2double val_SourceTerm, unsigned long npoint, unsigned short val_nDim, unsigned short val_nvar, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + virtual ~CPoissonVariable() = default; + + inline su2double GetPoisson_Coeff(unsigned long iPoint) { return Poisson_Coeff(iPoint);} + + inline void SetPoisson_Coeff(unsigned long iPoint, su2double val_Poisson_Coeff) { Poisson_Coeff(iPoint) = val_Poisson_Coeff ; } + + inline void SetSourceTerm(unsigned long iPoint, su2double val_SourceTerm) { SourceTerm(iPoint) = val_SourceTerm ; } + + inline su2double GetSourceTerm(unsigned long iPoint) { return SourceTerm(iPoint);} + + inline void SetStrongBC(unsigned long iPoint) { strong_bc(iPoint) = true; } + + inline bool GetStrongBC(unsigned long iPoint) { return strong_bc(iPoint); } + + inline void ResetStrongBC(unsigned long iPoint) { strong_bc(iPoint) = false; } + +}; diff --git a/SU2_CFD/include/variables/CPBIncNSVariable.hpp b/SU2_CFD/include/variables/CPBIncNSVariable.hpp new file mode 100644 index 000000000000..4c42bc732cfd --- /dev/null +++ b/SU2_CFD/include/variables/CPBIncNSVariable.hpp @@ -0,0 +1,144 @@ +/*! + * \file CPBIncNSVariable.hpp + * \brief Class for defining the variables of the pressure based incompressible NS solver. + * \author F. Palacios, 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 "CPBIncEulerVariable.hpp" +/*! + * \class CPBIncNSVariable + * \brief Main class for defining the variables of the incompressible Navier-Stokes solver. + * \ingroup Navier_Stokes_Equations + */ +class CPBIncNSVariable final : public CPBIncEulerVariable { +private: + MatrixType Vorticity; /*!< \brief Vorticity of the fluid. */ + VectorType StrainMag; /*!< \brief Magnitude of rate of strain tensor. */ + + VectorType DES_LengthScale; +public: + + /*! + * \brief Constructor of the class. + */ + CPBIncNSVariable(void); + + /*! + * \param[in] val_pressure - value of the pressure. + * \param[in] val_velocity - Value of the flow velocity (initialization value). + * \param[in] val_temperature - Value of the temperature (initialization value). + * \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. + */ + CPBIncNSVariable(su2double val_density, su2double val_pressure, su2double *val_velocity, + unsigned long npoint, unsigned short val_nDim, unsigned short val_nvar, CConfig *config); + + /*! + * \brief Destructor of the class. + */ + virtual ~CPBIncNSVariable() = default; + + /*! + * \brief Set all the primitive variables for incompressible flows + */ + bool SetPrimVar(unsigned long iPoint, su2double Density_Inf, su2double Viscosity_Inf, su2double eddy_visc, su2double turb_ke, CConfig *config); + using CVariable::SetPrimVar; + + /*! + * \brief Set the laminar viscosity. + */ + inline void SetLaminarViscosity(unsigned long iPoint, su2double laminarViscosity) override { + Primitive(iPoint,nDim+2) = laminarViscosity; + } + + /*! + * \brief Set the vorticity value. + */ + bool SetVorticity_StrainMag() override; + + /*! + * \overload + * \param[in] eddy_visc - Value of the eddy viscosity. + */ + inline void SetEddyViscosity(unsigned long iPoint, su2double eddy_visc) override { + Primitive(iPoint,nDim+3) = eddy_visc; + } + + /*! + * \brief Get the laminar viscosity of the flow. + * \return Value of the laminar viscosity of the flow. + */ + inline su2double GetLaminarViscosity(unsigned long iPoint) const override { return Primitive(iPoint,nDim+2); } + + /*! + * \brief Get the eddy viscosity of the flow. + * \return The eddy viscosity of the flow. + */ + inline su2double GetEddyViscosity(unsigned long iPoint) const override { return Primitive(iPoint,nDim+3); } + + /*! + * \brief Get the value of the vorticity. + * \return Value of the vorticity. + */ + inline su2double *GetVorticity(unsigned long iPoint) override { return Vorticity[iPoint]; } + + /*! + * \brief Get the value of the magnitude of rate of strain. + * \return Value of the rate of strain magnitude. + */ + inline su2double GetStrainMag(unsigned long iPoint) const override { return StrainMag(iPoint); } + + /*! + * \brief Set the DES Length Scale. + */ + inline void SetDES_LengthScale(unsigned long iPoint, su2double val_des_lengthscale) override { + DES_LengthScale(iPoint) = val_des_lengthscale; + } + + /*! + * \brief Get the DES length scale + * \return Value of the DES length Scale. + */ + inline su2double GetDES_LengthScale(unsigned long iPoint) const override { return DES_LengthScale(iPoint); } + + /*! + * \brief Get the thermal conductivity of the flow. + * \return Value of the laminar viscosity of the flow. + */ + inline su2double GetThermalConductivity(unsigned long iPoint) const override { return 0.0; } + +}; diff --git a/SU2_CFD/src/iteration/CPBFluidIteration.cpp b/SU2_CFD/src/iteration/CPBFluidIteration.cpp new file mode 100644 index 000000000000..2eeb784d2e39 --- /dev/null +++ b/SU2_CFD/src/iteration/CPBFluidIteration.cpp @@ -0,0 +1,139 @@ +/*! + * \file CPBFluidIteration.cpp + * \brief Main subroutines used by SU2_CFD + * \author F. Palacios, T. Economon + * \version 7.0.6 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2020, SU2 Contributors (cf. AUTHORS.md) + * + * 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/iteration/CPBFluidIteration.hpp" +#include "../../include/solvers/CPBIncEulerSolver.hpp" +#include "../../include/solvers/CPBIncNSSolver.hpp" +#include "../../include/output/COutput.hpp" + +CPBFluidIteration::CPBFluidIteration(const CConfig *config) : CFluidIteration(config) { } + +void CPBFluidIteration::Preprocess(COutput *output, + CIntegration ****integration_container, + CGeometry ****geometry_container, + CSolver *****solver_container, + CNumerics ******numerics_container, + CConfig **config_container, + CSurfaceMovement **surface_movement, + CVolumetricMovement ***grid_movement, + CFreeFormDefBox*** FFDBox, + unsigned short val_iZone, + unsigned short val_iInst) { } + +void CPBFluidIteration::Iterate(COutput *output, + CIntegration ****integration, + CGeometry ****geometry, + CSolver *****solver, + CNumerics ******numerics, + CConfig **config, + CSurfaceMovement **surface_movement, + CVolumetricMovement ***grid_movement, + CFreeFormDefBox*** FFDBox, + unsigned short val_iZone, + unsigned short val_iInst) { + unsigned long InnerIter, TimeIter; + unsigned short FinestMesh = config[val_iZone]->GetFinestMesh(); + bool unsteady = (config[val_iZone]->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) || (config[val_iZone]->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND); + bool frozen_visc = (config[val_iZone]->GetContinuous_Adjoint() && config[val_iZone]->GetFrozen_Visc_Cont()) || + (config[val_iZone]->GetDiscrete_Adjoint() && config[val_iZone]->GetFrozen_Visc_Disc()); + bool periodic = (config[val_iZone]->GetnMarker_Periodic() > 0); + TimeIter = config[val_iZone]->GetTimeIter(); + + /* --- Setting up iteration values depending on if this is a + steady or an unsteady simulaiton */ + + InnerIter = config[val_iZone]->GetInnerIter(); + + /*--- Solve the Euler, Navier-Stokes or Reynolds-averaged Navier-Stokes (RANS) equations ---*/ + + switch( config[val_iZone]->GetKind_Solver() ) { + case MAIN_SOLVER::INC_EULER: + config[val_iZone]->SetGlobalParam(MAIN_SOLVER::INC_EULER, RUNTIME_FLOW_SYS); break; + + case MAIN_SOLVER::INC_NAVIER_STOKES: + config[val_iZone]->SetGlobalParam(MAIN_SOLVER::INC_NAVIER_STOKES, RUNTIME_FLOW_SYS); break; + + case MAIN_SOLVER::INC_RANS: + config[val_iZone]->SetGlobalParam(MAIN_SOLVER::INC_RANS, RUNTIME_FLOW_SYS); break; + } + + /*--- Solve the momentum equations. ---*/ + + integration[val_iZone][val_iInst][FLOW_SOL]->CurrentGridIteration(geometry, solver, numerics, config, FinestMesh, RUNTIME_FLOW_SYS, val_iZone,val_iInst); + + + /*--- Set source term for pressure correction equation based on current flow solution ---*/ + solver[val_iZone][val_iInst][MESH_0][FLOW_SOL]->SetMomCoeff(geometry[val_iZone][val_iInst][MESH_0], solver[val_iZone][val_iInst][MESH_0], config[val_iZone], periodic, MESH_0); + + solver[val_iZone][val_iInst][MESH_0][FLOW_SOL]->SetPoissonSourceTerm(geometry[val_iZone][val_iInst][MESH_0], solver[val_iZone][val_iInst][MESH_0], config[val_iZone], MESH_0); + + + /*--- Solve the poisson equation ---*/ + config[val_iZone]->SetGlobalParam(MAIN_SOLVER::POISSON_EQUATION, RUNTIME_POISSON_SYS); + + integration[val_iZone][val_iInst][POISSON_SOL]->CurrentGridIteration(geometry, solver, numerics, config, FinestMesh, RUNTIME_POISSON_SYS, val_iZone,val_iInst); +// integration[val_iZone][val_iInst][POISSON_SOL]->MultiGrid_Iteration(geometry, solver, numerics, config, RUNTIME_POISSON_SYS, ExtIter, val_iZone,val_iInst); + + /*--- Correct pressure and velocities ---*/ + solver[val_iZone][val_iInst][MESH_0][FLOW_SOL]->Flow_Correction(geometry[val_iZone][val_iInst][MESH_0], solver[val_iZone][val_iInst][MESH_0], config[val_iZone]); + + /*--- Set the prmitive value based on updated solution ---*/ + solver[val_iZone][val_iInst][MESH_0][FLOW_SOL]->Postprocessing(geometry[val_iZone][val_iInst][MESH_0], solver[val_iZone][val_iInst][MESH_0], config[val_iZone], MESH_0); + + /*integration[val_iZone][val_iInst][FLOW_SOL]->MultiGrid_CyclePB(geometry, solver, numerics, + config, FinestMesh, 0, RUNTIME_FLOW_SYS, val_iZone,val_iInst);*/ + + if (config[val_iZone]->GetKind_Solver() == MAIN_SOLVER::INC_RANS) { + + /*--- Solve the turbulence model ---*/ + + config[val_iZone]->SetGlobalParam(MAIN_SOLVER::INC_RANS, RUNTIME_TURB_SYS); + integration[val_iZone][val_iInst][TURB_SOL]->SingleGrid_Iteration(geometry, solver, numerics, config, RUNTIME_TURB_SYS, val_iZone, val_iInst); + + /*--- Solve transition model ---*/ + + if (config[val_iZone]->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM) { + config[val_iZone]->SetGlobalParam(MAIN_SOLVER::INC_RANS, RUNTIME_TRANS_SYS); + integration[val_iZone][val_iInst][TRANS_SOL]->SingleGrid_Iteration(geometry, solver, numerics, + config, RUNTIME_TRANS_SYS, val_iZone, val_iInst); + } + } + + + /*--- Calculate the inviscid and viscous forces ---*/ + + solver[val_iZone][val_iInst][MESH_0][FLOW_SOL]->Pressure_Forces(geometry[val_iZone][val_iInst][MESH_0], config[val_iZone]); + solver[val_iZone][val_iInst][MESH_0][FLOW_SOL]->Momentum_Forces(geometry[val_iZone][val_iInst][MESH_0], config[val_iZone]); + solver[val_iZone][val_iInst][MESH_0][FLOW_SOL]->Friction_Forces(geometry[val_iZone][val_iInst][MESH_0], config[val_iZone]); + + + /*--- Write the convergence history ---*/ + + /*if ( unsteady && !config[val_iZone]->GetDiscrete_Adjoint() ) + output->SetConvHistory_Body(NULL, geometry, solver, config, integration, true, 0.0, val_iZone,val_iInst);*/ + +} diff --git a/SU2_CFD/src/numerics/heat.cpp b/SU2_CFD/src/numerics/heat.cpp new file mode 100644 index 000000000000..d9e44f54ee56 --- /dev/null +++ b/SU2_CFD/src/numerics/heat.cpp @@ -0,0 +1,322 @@ +/*! + * \file heat.cpp + * \brief Implementation of numerics classes for heat transfer. + * \author F. Palacios, T. Economon + * \version 7.0.7 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2020, SU2 Contributors (cf. AUTHORS.md) + * + * 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/heat.hpp" + +CCentSca_Heat::CCentSca_Heat(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) : + CNumerics(val_nDim, val_nVar, config) { + + implicit = (config->GetKind_TimeIntScheme_Turb() == EULER_IMPLICIT); + /* 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(); + + MeanVelocity = new su2double [nDim]; + + Laminar_Viscosity_i = config->GetViscosity_FreeStreamND(); + Laminar_Viscosity_j = config->GetViscosity_FreeStreamND(); + + Param_Kappa_4 = config->GetKappa_4th_Heat(); + Diff_Lapl = new su2double [nVar]; +} + +CCentSca_Heat::~CCentSca_Heat(void) { + + delete [] MeanVelocity; + delete [] Diff_Lapl; + +} + +void CCentSca_Heat::ComputeResidual(su2double *val_residual, su2double **val_Jacobian_i, + su2double **val_Jacobian_j, CConfig *config) { + + AD::StartPreacc(); + AD::SetPreaccIn(V_i, nDim+3); AD::SetPreaccIn(V_j, nDim+3); + AD::SetPreaccIn(Temp_i); AD::SetPreaccIn(Temp_j); + AD::SetPreaccIn(Und_Lapl_i, nVar); AD::SetPreaccIn(Und_Lapl_j, nVar); + AD::SetPreaccIn(Normal, nDim); + if (dynamic_grid) { + AD::SetPreaccIn(GridVel_i, nDim); AD::SetPreaccIn(GridVel_j, nDim); + } + + /*--- Primitive variables at point i and j ---*/ + + Pressure_i = V_i[0]; Pressure_j = V_j[0]; + DensityInc_i = V_i[nDim+2]; DensityInc_j = V_j[nDim+2]; + BetaInc2_i = V_i[nDim+3]; BetaInc2_j = V_j[nDim+3]; + + /*--- Projected velocities at the current edge ---*/ + + ProjVelocity = 0.0; ProjVelocity_i = 0.0; ProjVelocity_j = 0.0; Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + ProjVelocity_i += V_i[iDim+1]*Normal[iDim]; + ProjVelocity_j += V_j[iDim+1]*Normal[iDim]; + Area += Normal[iDim]*Normal[iDim]; + } + Area = sqrt(Area); + + /*--- Computing the second order centered scheme part ---*/ + + ProjVelocity = 0.5*(ProjVelocity_i+ProjVelocity_j); + + val_residual[0] = 0.5*(Temp_i + Temp_j)*ProjVelocity; + + if (implicit) { + val_Jacobian_i[0][0] = 0.5*ProjVelocity; + val_Jacobian_j[0][0] = 0.5*ProjVelocity; + } + + /*--- Adding artificial dissipation to stabilize the centered scheme ---*/ + + Diff_Lapl[0] = Und_Lapl_i[0]-Und_Lapl_j[0]; + + SoundSpeed_i = sqrt(ProjVelocity_i*ProjVelocity_i + (BetaInc2_i/DensityInc_i)*Area*Area); + SoundSpeed_j = sqrt(ProjVelocity_j*ProjVelocity_j + (BetaInc2_j/DensityInc_j)*Area*Area); + + Local_Lambda_i = fabs(ProjVelocity_i)+SoundSpeed_i; + Local_Lambda_j = fabs(ProjVelocity_j)+SoundSpeed_j; + MeanLambda = 0.5*(Local_Lambda_i+Local_Lambda_j); + + val_residual[0] += -Param_Kappa_4*Diff_Lapl[0]*MeanLambda; + + if (implicit) { + cte_0 = Param_Kappa_4*su2double(Neighbor_i+1)*MeanLambda; + cte_1 = Param_Kappa_4*su2double(Neighbor_j+1)*MeanLambda; + + val_Jacobian_i[0][0] += cte_0; + val_Jacobian_j[0][0] -= cte_1; + } + + AD::SetPreaccOut(val_residual[0]); + AD::EndPreacc(); + +} + +CUpwSca_Heat::CUpwSca_Heat(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) : + CNumerics(val_nDim, val_nVar, config) { + + implicit = (config->GetKind_TimeIntScheme_Turb() == EULER_IMPLICIT); + /* 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]; + + Laminar_Viscosity_i = config->GetViscosity_FreeStreamND(); + Laminar_Viscosity_j = config->GetViscosity_FreeStreamND(); +} + +CUpwSca_Heat::~CUpwSca_Heat(void) { + + delete [] Velocity_i; + delete [] Velocity_j; + +} + +void CUpwSca_Heat::ComputeResidual(su2double *val_residual, su2double **val_Jacobian_i, + su2double **val_Jacobian_j, CConfig *config) { + + q_ij = 0.0; + + AD::StartPreacc(); + AD::SetPreaccIn(V_i, nDim+1); AD::SetPreaccIn(V_j, nDim+1); + AD::SetPreaccIn(Temp_i); AD::SetPreaccIn(Temp_j); + AD::SetPreaccIn(Normal, nDim); + if (dynamic_grid) { + AD::SetPreaccIn(GridVel_i, nDim); AD::SetPreaccIn(GridVel_j, nDim); + } + + 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)); + val_residual[0] = a0*Temp_i+a1*Temp_j; + + if (implicit) { + val_Jacobian_i[0][0] = a0; + val_Jacobian_j[0][0] = a1; + } + + AD::SetPreaccOut(val_residual[0]); + AD::EndPreacc(); + +} + +CAvgGrad_Heat::CAvgGrad_Heat(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) : + CNumerics(val_nDim, val_nVar, config) { + + implicit = (config->GetKind_TimeIntScheme_Heat() == EULER_IMPLICIT); + + Edge_Vector = new su2double [nDim]; + Proj_Mean_GradHeatVar_Normal = new su2double [nVar]; + Proj_Mean_GradHeatVar_Corrected = new su2double [nVar]; + Mean_GradHeatVar = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar++) + Mean_GradHeatVar[iVar] = new su2double [nDim]; + +} + +CAvgGrad_Heat::~CAvgGrad_Heat(void) { + + delete [] Edge_Vector; + delete [] Proj_Mean_GradHeatVar_Normal; + delete [] Proj_Mean_GradHeatVar_Corrected; + for (iVar = 0; iVar < nVar; iVar++) + delete [] Mean_GradHeatVar[iVar]; + delete [] Mean_GradHeatVar; + +} + +void CAvgGrad_Heat::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(Temp_i); AD::SetPreaccIn(Temp_j); + AD::SetPreaccIn(ConsVar_Grad_i[0],nDim); AD::SetPreaccIn(ConsVar_Grad_j[0],nDim); + AD::SetPreaccIn(Thermal_Diffusivity_i); AD::SetPreaccIn(Thermal_Conductivity_j); + + Thermal_Diffusivity_Mean = 0.5*(Thermal_Diffusivity_i + Thermal_Diffusivity_j); + + /*--- 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. Projection of the mean gradient in the direction of the edge ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + Proj_Mean_GradHeatVar_Normal[iVar] = 0.0; + Proj_Mean_GradHeatVar_Corrected[iVar] = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Mean_GradHeatVar[iVar][iDim] = 0.5*(ConsVar_Grad_i[iVar][iDim] + ConsVar_Grad_j[iVar][iDim]); + Proj_Mean_GradHeatVar_Normal[iVar] += Mean_GradHeatVar[iVar][iDim]*Normal[iDim]; + } + Proj_Mean_GradHeatVar_Corrected[iVar] = Proj_Mean_GradHeatVar_Normal[iVar]; + } + + val_residual[0] = Thermal_Diffusivity_Mean*Proj_Mean_GradHeatVar_Corrected[0]; + + /*--- For Jacobians -> Use of TSL approx. to compute derivatives of the gradients ---*/ + if (implicit) { + Jacobian_i[0][0] = -Thermal_Diffusivity_Mean*proj_vector_ij; + Jacobian_j[0][0] = Thermal_Diffusivity_Mean*proj_vector_ij; + } + + AD::SetPreaccOut(val_residual, nVar); + AD::EndPreacc(); + +} + +CAvgGradCorrected_Heat::CAvgGradCorrected_Heat(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) : + CNumerics(val_nDim, val_nVar, config) { + + implicit = (config->GetKind_TimeIntScheme_Heat() == EULER_IMPLICIT); + + Edge_Vector = new su2double [nDim]; + Proj_Mean_GradHeatVar_Edge = new su2double [nVar]; + Proj_Mean_GradHeatVar_Kappa = new su2double [nVar]; + Proj_Mean_GradHeatVar_Corrected = new su2double [nVar]; + Mean_GradHeatVar = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar++) + Mean_GradHeatVar[iVar] = new su2double [nDim]; + +} + +CAvgGradCorrected_Heat::~CAvgGradCorrected_Heat(void) { + + delete [] Edge_Vector; + delete [] Proj_Mean_GradHeatVar_Edge; + delete [] Proj_Mean_GradHeatVar_Kappa; + delete [] Proj_Mean_GradHeatVar_Corrected; + for (iVar = 0; iVar < nVar; iVar++) + delete [] Mean_GradHeatVar[iVar]; + delete [] Mean_GradHeatVar; + +} + +void CAvgGradCorrected_Heat::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(Temp_i); AD::SetPreaccIn(Temp_j); + AD::SetPreaccIn(ConsVar_Grad_i[0],nDim); AD::SetPreaccIn(ConsVar_Grad_j[0],nDim); + AD::SetPreaccIn(Thermal_Diffusivity_i); AD::SetPreaccIn(Thermal_Diffusivity_j); + + Thermal_Diffusivity_Mean = 0.5*(Thermal_Diffusivity_i + Thermal_Diffusivity_j); + + /*--- 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. Projection of the mean gradient + in the direction of the edge ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Proj_Mean_GradHeatVar_Edge[iVar] = 0.0; + Proj_Mean_GradHeatVar_Kappa[iVar] = 0.0; + + for (iDim = 0; iDim < nDim; iDim++) { + Mean_GradHeatVar[iVar][iDim] = 0.5*(ConsVar_Grad_i[iVar][iDim] + ConsVar_Grad_j[iVar][iDim]); + Proj_Mean_GradHeatVar_Kappa[iVar] += Mean_GradHeatVar[iVar][iDim]*Normal[iDim]; + Proj_Mean_GradHeatVar_Edge[iVar] += Mean_GradHeatVar[iVar][iDim]*Edge_Vector[iDim]; + } + Proj_Mean_GradHeatVar_Corrected[iVar] = Proj_Mean_GradHeatVar_Kappa[iVar]; + Proj_Mean_GradHeatVar_Corrected[iVar] -= Proj_Mean_GradHeatVar_Edge[iVar]*proj_vector_ij - + (Temp_j-Temp_i)*proj_vector_ij; + } + + val_residual[0] = Thermal_Diffusivity_Mean*Proj_Mean_GradHeatVar_Corrected[0]; + + /*--- For Jacobians -> Use of TSL approx. to compute derivatives of the gradients ---*/ + + if (implicit) { + Jacobian_i[0][0] = -Thermal_Diffusivity_Mean*proj_vector_ij; + Jacobian_j[0][0] = Thermal_Diffusivity_Mean*proj_vector_ij; + } + + AD::SetPreaccOut(val_residual, nVar); + AD::EndPreacc(); +} diff --git a/SU2_CFD/src/numerics/pbflow.cpp b/SU2_CFD/src/numerics/pbflow.cpp new file mode 100644 index 000000000000..7a940bea0269 --- /dev/null +++ b/SU2_CFD/src/numerics/pbflow.cpp @@ -0,0 +1,573 @@ +/*! + * \file pbflow.cpp + * \brief This file contains the numerical methods for incompressible flow. + * \author F. Palacios, T. Economon + * \version 6.0.1 "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/pbflow.hpp" + +CUpwPB_Flow::CUpwPB_Flow(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) : CNumerics(val_nDim, val_nVar, config) { + + implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + gravity = config->GetGravityForce(); + Froude = config->GetFroude(); + dynamic_grid = config->GetDynamic_Grid(); + + Diff_U = new su2double [nVar]; + Velocity_i = new su2double [nDim]; + Velocity_j = new su2double [nDim]; + Velocity_upw = new su2double [nDim]; + MeanVelocity = new su2double [nDim]; + Flux = new su2double [nDim]; + ProjFlux_i = new su2double [nVar]; + ProjFlux_j = new su2double [nVar]; + Jacobian_i = new su2double* [nVar]; + Jacobian_j = new su2double* [nVar]; + Jacobian_upw = new su2double* [nVar]; + + + for (iVar = 0; iVar < nVar; iVar++) { + Jacobian_i[iVar] = new su2double [nVar]; + Jacobian_j[iVar] = new su2double [nVar]; + Jacobian_upw[iVar] = new su2double [nVar]; + } + +} + +CUpwPB_Flow::~CUpwPB_Flow(void) { + + delete [] Diff_U; + delete [] Velocity_i; + delete [] Velocity_j; + delete [] Velocity_upw; + delete [] MeanVelocity; + delete [] Flux; + delete [] ProjFlux_i; + delete [] ProjFlux_j; + + for (iVar = 0; iVar < nVar; iVar++) { + delete [] Jacobian_i[iVar]; + delete [] Jacobian_j[iVar]; + delete [] Jacobian_upw[iVar]; + } + delete [] Jacobian_i; + delete [] Jacobian_j; + delete [] Jacobian_upw; + +} + +CNumerics::ResidualType<> CUpwPB_Flow::ComputeResidual(const CConfig *config) { + + + su2double MeanDensity, Flux0, Flux1, MeanPressure, Area, FF, Vel0, Vel1, ProjGridVelFlux = 0.0; + + + /*--- Primitive variables at point i and j ---*/ + Pressure_i = V_i[0]; Pressure_j = V_j[0]; + DensityInc_i = V_i[nDim+1]; DensityInc_j = V_j[nDim+1]; + MeanDensity = 0.5*(DensityInc_i + DensityInc_j); + MeanPressure = 0.5*(Pressure_i + Pressure_j); + + Area = 0.0; + for(iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + + /*--- (rho*u_i) ---*/ + Face_Flux = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Velocity_i[iDim] = V_i[iDim+1]; + Velocity_j[iDim] = V_j[iDim+1]; + MeanVelocity[iDim] = 0.5*(Velocity_i[iDim] + Velocity_j[iDim]); + Face_Flux += MeanDensity*MeanVelocity[iDim]*Normal[iDim]; + } + + if (dynamic_grid) { + ProjGridVelFlux = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + ProjGridVelFlux += 0.5*MeanDensity*(GridVel_i[iDim]+GridVel_j[iDim])*Normal[iDim]; + } + Face_Flux -= ProjGridVelFlux; + } + + /*--- Find upwind direction. ---*/ + Flux0 = 0.5*(Face_Flux + fabs(Face_Flux)) ; + Flux1 = 0.5*(Face_Flux - fabs(Face_Flux)) ; + + Upw_i = round(fabs(Flux0/(fabs(Face_Flux)+EPS))); + Upw_j = round(fabs(Flux1/(fabs(Face_Flux)+EPS))); + + /*--- Find flux. ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + Flux[iVar] = Flux0*V_i[iVar+1] + Flux1*V_j[iVar+1]; + Velocity_upw[iVar] = Upw_i*V_i[iVar+1] + Upw_j*V_j[iVar+1]; + if (dynamic_grid) Velocity_upw[iVar] -= (Upw_i*GridVel_i[iVar] + Upw_j*GridVel_j[iVar]); + } + + if (implicit) { + for (iVar = 0; iVar < nVar; iVar++) + for (jVar = 0; jVar < nVar; jVar++) { + Jacobian_j[iVar][jVar] = 0.0; + Jacobian_i[iVar][jVar] = 0.0; + Jacobian_upw[iVar][jVar] = 0.0; + } + + GetInviscidPBProjJac(MeanDensity, Velocity_upw, Normal, 0.5, Jacobian_upw); + + for (iVar = 0; iVar < nVar; iVar++) + for (jVar = 0; jVar < nVar; jVar++) { + Jacobian_i[iVar][jVar] = Upw_i*Jacobian_upw[iVar][jVar]; + Jacobian_j[iVar][jVar] = Upw_j*Jacobian_upw[iVar][jVar]; + } + } + + return ResidualType<>(Flux, Jacobian_i, Jacobian_j); +} + +CCentPB_Flow::CCentPB_Flow(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) : CNumerics(val_nDim, val_nVar, config) { + + implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + gravity = config->GetGravityForce(); + Froude = config->GetFroude(); + dynamic_grid = config->GetDynamic_Grid(); + + Diff_U = new su2double [nVar]; + Velocity_i = new su2double [nDim]; + Velocity_j = new su2double [nDim]; + Velocity_upw = new su2double [nDim]; + MeanVelocity = new su2double [nDim]; + Flux = new su2double [nDim]; + ProjFlux_i = new su2double [nVar]; + ProjFlux_j = new su2double [nVar]; + Jacobian_i = new su2double* [nVar]; + Jacobian_j = new su2double* [nVar]; + Jacobian_upw = new su2double* [nVar]; + + for (iVar = 0; iVar < nVar; iVar++) { + Jacobian_i[iVar] = new su2double [nVar]; + Jacobian_j[iVar] = new su2double [nVar]; + Jacobian_upw[iVar] = new su2double [nVar]; + } +} + +CCentPB_Flow::~CCentPB_Flow(void) { + + delete [] Diff_U; + delete [] Velocity_i; + delete [] Velocity_j; + delete [] Velocity_upw; + delete [] MeanVelocity; + delete [] Flux; + delete [] ProjFlux_i; + delete [] ProjFlux_j; + + for (iVar = 0; iVar < nVar; iVar++) { + delete [] Jacobian_i[iVar]; + delete [] Jacobian_j[iVar]; + delete [] Jacobian_upw[iVar]; + } + delete [] Jacobian_i; + delete [] Jacobian_j; + delete [] Jacobian_upw; + +} + +CNumerics::ResidualType<> CCentPB_Flow::ComputeResidual(const CConfig *config) { + /*--- To do list + * 1. Find upwind direction, upwind node and downwind node + * 2. Compute normalised variable for the upwind node using the gradient of the upwind node + * 3. Find face velocity using central difference scheme + * 4. Use the ULTIMATE limiter to find the adjusted face velocity + * 5. Find residual as FaceFlux * AdjustedFaceVelocity + * */ + + + su2double MeanDensity, Flux0, Flux1, MeanPressure, Area, FF, Vel0, Vel1, ProjGridVelFlux = 0.0; + su2double dissipation, kappa=0.15, ProjVel_i = 0.0, ProjVel_j = 0.0; + + /*--- Conservative variables at point i and j ---*/ + + Pressure_i = V_i[0]; Pressure_j = V_j[0]; + DensityInc_i = V_i[nDim+1]; DensityInc_j = V_j[nDim+1]; + + for (iDim = 0; iDim < nDim; iDim++) { + Velocity_i[iDim] = V_i[iDim+1]; + Velocity_j[iDim] = V_j[iDim+1]; + } + + Area = 0.0; + for(iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + + Face_Flux = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Velocity_i[iDim] = V_i[iDim+1]; + Velocity_j[iDim] = V_j[iDim+1]; + MeanVelocity[iDim] = 0.5*(Velocity_i[iDim] + Velocity_j[iDim]); + Face_Flux += MeanDensity*MeanVelocity[iDim]*Normal[iDim]; + ProjVel_i += Velocity_i[iDim]*Normal[iDim]; + ProjVel_j += Velocity_j[iDim]*Normal[iDim]; + } + + if (dynamic_grid) { + ProjGridVelFlux = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + ProjGridVelFlux += 0.5*MeanDensity*(GridVel_i[iDim]+GridVel_j[iDim])*Normal[iDim]; + } + Face_Flux -= ProjGridVelFlux; + } + + Flux0 = 0.5*(Face_Flux + fabs(Face_Flux)) ; + Flux1 = 0.5*(Face_Flux - fabs(Face_Flux)) ; + + Upw_i = round(fabs(Flux0/(fabs(Face_Flux)+EPS))); + Upw_j = round(fabs(Flux1/(fabs(Face_Flux)+EPS))); + + for (iVar = 0; iVar < nVar; iVar++) { + Velocity_upw[iVar] = Upw_i*V_i[iVar+1] + Upw_j*V_j[iVar+1]; + if (dynamic_grid) Velocity_upw[iVar] -= (Upw_i*GridVel_i[iVar] + Upw_j*GridVel_j[iVar]); + Flux[iVar] = Face_Flux*MeanVelocity[iVar]; + } + + //Dissipation + su2double lambda_i = 0.0, lambda_j = 0.0; + lambda_i = 2.0*abs(ProjVel_i); + lambda_j = 2.0*abs(ProjVel_j); + + su2double lambda_mean = 0.5*(lambda_i + lambda_j); + if (lambda_mean < EPS) { + lambda_i = 2.0*abs(config->GetVelocity_Ref()*Area); + lambda_j = 2.0*abs(config->GetVelocity_Ref()*Area); + lambda_mean = abs(config->GetVelocity_Ref()*Area); + } + + su2double Param_p = 0.3, SF=0.0; + su2double Phi_i = pow((lambda_i/(4.0*lambda_mean)),Param_p); + su2double Phi_j = pow((lambda_j/(4.0*lambda_mean)),Param_p); + + if ((Phi_i + Phi_j) != 0.0) + SF = 4.0*Phi_i*Phi_j/(Phi_i + Phi_j); + + su2double sc0 = 3.0*(Neighbor_i + Neighbor_j)/(Neighbor_i*Neighbor_j); + su2double E_0 = kappa*sc0*2.0/3.0; + + su2double diss[MAXNDIM]; + for (iDim = 0; iDim < nDim; iDim++) + diss[iDim] = E_0*(DensityInc_i*Velocity_i[iDim] - DensityInc_j*Velocity_j[iDim])*SF*lambda_mean; + + for (iVar = 0; iVar < nVar; iVar++) + Flux[iVar] += diss[iVar]; + + /*--- For implicit schemes, compute jacobians based on the upwind scheme for stability issues. (See ANSYS user guide) ---*/ + if (implicit) { + for (iVar = 0; iVar < nVar; iVar++) + for (jVar = 0; jVar < nVar; jVar++) { + Jacobian_j[iVar][jVar] = 0.0; + Jacobian_i[iVar][jVar] = 0.0; + Jacobian_upw[iVar][jVar] = 0.0; + } + + GetInviscidPBProjJac(MeanDensity, MeanVelocity, Normal, 0.5, Jacobian_upw); + //GetInviscidPBProjJac(&DensityInc_i, Velocity_upw, Normal, 0.5, val_Jacobian_upw); + /*GetInviscidPBProjJac(&DensityInc_i, Velocity_i, Normal, 0.5, Jacobian_i); + GetInviscidPBProjJac(&DensityInc_i, Velocity_j, Normal, 0.5, Jacobian_j);*/ + + for (iVar = 0; iVar < nVar; iVar++) + for (jVar = 0; jVar < nVar; jVar++) { + Jacobian_i[iVar][jVar] = Upw_i*Jacobian_upw[iVar][jVar]; + Jacobian_j[iVar][jVar] = Upw_j*Jacobian_upw[iVar][jVar]; + } + for (iVar = 0; iVar < nVar; iVar++) { + Jacobian_i[iVar][iVar] += E_0*DensityInc_i*SF*lambda_mean; + Jacobian_i[iVar][iVar] -= E_0*DensityInc_j*SF*lambda_mean; + } + + } + + return ResidualType<>(Flux, Jacobian_i, Jacobian_j); + +} + +CAvgGradPBInc_Flow::CAvgGradPBInc_Flow(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) : CNumerics(val_nDim, val_nVar, config) { + + implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + + 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]; + } + + /*--- Primitive flow variables. ---*/ + + PrimVar_i = new su2double [nDim+4]; + PrimVar_j = new su2double [nDim+4]; + Mean_PrimVar = new su2double [nDim+4]; + + /*--- Incompressible flow, primitive variables nDim+2, (P, vx, vy, vz, rho) ---*/ + + Mean_GradPrimVar = new su2double*[nVar]; + + /*--- Incompressible flow, gradient primitive variables nDim+2, (P, vx, vy, vz, rho) ---*/ + + for (iVar = 0; iVar < nVar; iVar++) + Mean_GradPrimVar[iVar] = new su2double[nDim]; + +} + +CAvgGradPBInc_Flow::~CAvgGradPBInc_Flow(void) { + + delete [] PrimVar_i; + delete [] PrimVar_j; + delete [] Mean_PrimVar; + + for (iVar = 0; iVar < nVar; iVar++) + delete [] Mean_GradPrimVar[iVar]; + delete [] Mean_GradPrimVar; + + for (iVar = 0; iVar < nVar; iVar++) { + delete [] Jacobian_i[iVar]; + delete [] Jacobian_j[iVar]; + } + delete [] Jacobian_i; + delete [] Jacobian_j; + +} + +CNumerics::ResidualType<> CAvgGradPBInc_Flow::ComputeResidual(const CConfig *config) { + + /*--- Normalized normal vector ---*/ + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + + for (iDim = 0; iDim < nDim; iDim++) + UnitNormal[iDim] = Normal[iDim]/Area; + + for (iVar = 0; iVar < nDim+4; iVar++) { + PrimVar_i[iVar] = V_i[iVar]; + PrimVar_j[iVar] = V_j[iVar]; + Mean_PrimVar[iVar] = 0.5*(PrimVar_i[iVar]+PrimVar_j[iVar]); + } + + /*--- Density and transport properties ---*/ + + Laminar_Viscosity_i = V_i[nDim+2]; Laminar_Viscosity_j = V_j[nDim+2]; + Eddy_Viscosity_i = V_i[nDim+3]; Eddy_Viscosity_j = V_j[nDim+3]; + + /*--- Mean transport properties ---*/ + + Mean_Laminar_Viscosity = 0.5*(Laminar_Viscosity_i + Laminar_Viscosity_j); + Mean_Eddy_Viscosity = 0.5*(Eddy_Viscosity_i + Eddy_Viscosity_j); + Mean_turb_ke = 0.0;//0.5*(turb_ke_i + turb_ke_j); + + /*--- Mean gradient approximation ---*/ + + for (iVar = 0; iVar < nVar; iVar++) + for (iDim = 0; iDim < nDim; iDim++) + Mean_GradPrimVar[iVar][iDim] = 0.5*(PrimVar_Grad_i[iVar+1][iDim] + PrimVar_Grad_j[iVar+1][iDim]); + + /*--- Get projected flux tensor ---*/ + + GetViscousPBIncProjFlux(Mean_PrimVar, Mean_GradPrimVar, Normal, Mean_Laminar_Viscosity, Mean_Eddy_Viscosity, Mean_turb_ke); + + + /*--- Implicit part ---*/ + + if (implicit) { + + dist_ij = 0.0; proj_vector_ij = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + dist_ij += (Coord_j[iDim]-Coord_i[iDim])*(Coord_j[iDim]-Coord_i[iDim]); + proj_vector_ij += (Coord_j[iDim]-Coord_i[iDim])*Normal[iDim]; + } + proj_vector_ij = proj_vector_ij/dist_ij; + dist_ij = sqrt(dist_ij); + + if (dist_ij == 0.0) { + for (iVar = 0; iVar < nVar; iVar++) { + for (jVar = 0; jVar < nVar; jVar++) { + Jacobian_i[iVar][jVar] = 0.0; + Jacobian_j[iVar][jVar] = 0.0; + } + } + } + else { + GetViscousPBIncProjJacs(Mean_Laminar_Viscosity, Mean_Eddy_Viscosity, dist_ij, UnitNormal, + Area, Jacobian_i, Jacobian_j); + } + + } + + return ResidualType<>(Proj_Flux_Tensor, Jacobian_i, Jacobian_j); +} + +CAvgGradCorrectedPBInc_Flow::CAvgGradCorrectedPBInc_Flow(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) : CNumerics(val_nDim, val_nVar, config) { + + implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + + 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]; + } + + /*--- Primitive flow variables. ---*/ + + Mean_PrimVar = new su2double [nDim+4]; + PrimVar_i = new su2double [nDim+4]; + PrimVar_j = new su2double [nDim+4]; + Proj_Mean_GradPrimVar_Edge = new su2double [nVar]; + Edge_Vector = new su2double [nDim]; + + Mean_GradPrimVar = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar++) + Mean_GradPrimVar[iVar] = new su2double [nDim]; + +} + +CAvgGradCorrectedPBInc_Flow::~CAvgGradCorrectedPBInc_Flow(void) { + + delete [] Mean_PrimVar; + delete [] PrimVar_i; + delete [] PrimVar_j; + delete [] Proj_Mean_GradPrimVar_Edge; + delete [] Edge_Vector; + + for (iVar = 0; iVar < nVar; iVar++) + delete [] Mean_GradPrimVar[iVar]; + delete [] Mean_GradPrimVar; + + for (iVar = 0; iVar < nVar; iVar++) { + delete [] Jacobian_i[iVar]; + delete [] Jacobian_j[iVar]; + } + delete [] Jacobian_i; + delete [] Jacobian_j; + +} + +CNumerics::ResidualType<> CAvgGradCorrectedPBInc_Flow::ComputeResidual(const CConfig *config) { + + unsigned short nPrimVarGrad = nDim+2, nPrimVar = nDim+4; + + /*--- Normalized normal vector ---*/ + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + + for (iDim = 0; iDim < nDim; iDim++) + UnitNormal[iDim] = Normal[iDim]/Area; + + /*--- Conversion to Primitive Variables (P, u, v, w, rho, mu, muT) ---*/ + + for (iVar = 0; iVar < nPrimVar; iVar++) { + PrimVar_i[iVar] = V_i[iVar]; + PrimVar_j[iVar] = V_j[iVar]; + Mean_PrimVar[iVar] = 0.5*(PrimVar_i[iVar]+PrimVar_j[iVar]); + } + + /*--- Density and transport properties ---*/ + + DensityInc_i = V_i[nDim+1]; DensityInc_j = V_j[nDim+1]; + Laminar_Viscosity_i = V_i[nDim+2]; Laminar_Viscosity_j = V_j[nDim+2]; + Eddy_Viscosity_i = V_i[nDim+3]; Eddy_Viscosity_j = V_j[nDim+3]; + + /*--- Mean transport properties ---*/ + + Mean_Laminar_Viscosity = 0.5*(Laminar_Viscosity_i + Laminar_Viscosity_j); + Mean_Eddy_Viscosity = 0.5*(Eddy_Viscosity_i + Eddy_Viscosity_j); + Mean_turb_ke = 0.0;//0.5*(turb_ke_i + turb_ke_j); + + /*--- Compute vector going from iPoint to jPoint ---*/ + + dist_ij_2 = 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]; + } + + /*--- Projection of the mean gradient in the direction of the edge ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Proj_Mean_GradPrimVar_Edge[iVar] = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Mean_GradPrimVar[iVar][iDim] = 0.5*(PrimVar_Grad_i[iVar+1][iDim] + PrimVar_Grad_j[iVar+1][iDim]); + Proj_Mean_GradPrimVar_Edge[iVar] += Mean_GradPrimVar[iVar][iDim]*Edge_Vector[iDim]; + } + if (dist_ij_2 != 0.0) { + for (iDim = 0; iDim < nDim; iDim++) { + Mean_GradPrimVar[iVar][iDim] -= (Proj_Mean_GradPrimVar_Edge[iVar] - + (PrimVar_j[iVar+1]-PrimVar_i[iVar+1]))*Edge_Vector[iDim] / dist_ij_2; + } + } + } + + /*--- Get projected flux tensor ---*/ + + GetViscousPBIncProjFlux(Mean_PrimVar, Mean_GradPrimVar, Normal, Mean_Laminar_Viscosity, Mean_Eddy_Viscosity, Mean_turb_ke); + + /*--- Implicit part ---*/ + + if (implicit) { + + proj_vector_ij = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + proj_vector_ij += (Coord_j[iDim]-Coord_i[iDim])*Normal[iDim]; + } + proj_vector_ij = proj_vector_ij/dist_ij_2; + + if (dist_ij_2 == 0.0) { + for (iVar = 0; iVar < nVar; iVar++) { + for (jVar = 0; jVar < nVar; jVar++) { + Jacobian_i[iVar][jVar] = 0.0; + Jacobian_j[iVar][jVar] = 0.0; + } + } + } + else { + GetViscousPBIncProjJacs(Mean_Laminar_Viscosity, Mean_Eddy_Viscosity, sqrt(dist_ij_2), UnitNormal, + Area, Jacobian_i, Jacobian_j); + } + + } + + return ResidualType<>(Proj_Flux_Tensor, Jacobian_i, Jacobian_j); +} diff --git a/SU2_CFD/src/numerics/poisson.cpp b/SU2_CFD/src/numerics/poisson.cpp new file mode 100644 index 000000000000..9daceada2725 --- /dev/null +++ b/SU2_CFD/src/numerics/poisson.cpp @@ -0,0 +1,421 @@ +/*! + * \file numerics_direct_poisson.cpp + * \brief This file contains all the convective term discretization. + * \author F. Palacios + * \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/poisson.hpp" + + +CAvgGradCorrected_Poisson::CAvgGradCorrected_Poisson(unsigned short val_nDim, unsigned short val_nVar, + CConfig *config) : CNumerics(val_nDim, val_nVar, config) { + + implicit = false; + implicit = (config->GetKind_TimeIntScheme_Poisson() == EULER_IMPLICIT); + direct = false; + + + Edge_Vector = new su2double [nDim]; + Proj_Mean_GradPoissonVar_Edge = new su2double [nVar]; + Proj_Mean_GradPoissonVar_Kappa = new su2double [nVar]; + Proj_Mean_GradPoissonVar_Corrected = new su2double [nVar]; + Jacobian_i = new su2double* [nVar]; + Jacobian_j = new su2double* [nVar]; + Mean_GradPoissonVar = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Jacobian_i[iVar] = new su2double [nDim]; + Jacobian_j[iVar] = new su2double [nDim]; + Mean_GradPoissonVar[iVar] = new su2double [nDim]; + } + + Poisson_Coeff_i = 1.0; + Poisson_Coeff_j = 1.0; + + Mom_Coeff_i = new su2double [nDim]; + Mom_Coeff_j = new su2double [nDim]; + +} + + +CAvgGradCorrected_Poisson::~CAvgGradCorrected_Poisson(void) { + + delete [] Edge_Vector; + delete [] Proj_Mean_GradPoissonVar_Edge; + delete [] Proj_Mean_GradPoissonVar_Kappa; + delete [] Proj_Mean_GradPoissonVar_Corrected; + delete [] Mom_Coeff_i; + delete [] Mom_Coeff_j; + + for (iVar = 0; iVar < nVar; iVar++) { + delete [] Mean_GradPoissonVar[iVar]; + delete [] Jacobian_i[iVar]; + delete [] Jacobian_j[iVar]; + } + delete [] Mean_GradPoissonVar; + delete [] Jacobian_i; + delete [] Jacobian_j; +} + +CNumerics::ResidualType<> CAvgGradCorrected_Poisson::ComputeResidual(const CConfig *config) { + + su2double Coeff_Mean; + su2double *MomCoeffxNormal = new su2double[nDim]; + su2double *MomCoeffxNormalCorrected = new su2double[nDim]; + su2double Mean_GradPoissonVar_Edge[MAXNDIM], GradPoisson[MAXNDIM]; + su2double Mean_GradPoissonVar_Face[MAXNDIM][MAXNDIM], Num, Den; + + Poisson_Coeff_Mean = 1.0;//0.5*(Poisson_Coeff_i + Poisson_Coeff_j); + + /*--- Multiply the normal with the coefficients of the momentum equation + * and use it instead of the normal during the projection operation ---*/ + for (iDim = 0; iDim < nDim; iDim++) { + Coeff_Mean = 0.5*(Mom_Coeff_i[iDim] + Mom_Coeff_j[iDim]) ; + MomCoeffxNormal[iDim] = Coeff_Mean*Normal[iDim]; + } + + /*--- Compute vector going from iPoint to jPoint ---*/ + /*--- Minimum correction approach. ---*/ + /*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]*MomCoeffxNormal[iDim]; + } + if (dist_ij_2 == 0.0) proj_vector_ij = 0.0; + else proj_vector_ij = proj_vector_ij/dist_ij_2;*/ + + /*--- Over relaxed approach. ---*/ + dist_ij_2 = 0; proj_vector_ij = 0; + Num = 0.0; Den = 0.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]; + Num += MomCoeffxNormal[iDim]*MomCoeffxNormal[iDim]; + Den += Edge_Vector[iDim]*MomCoeffxNormal[iDim]; + } + if (Den == 0.0) proj_vector_ij = 0.0; + else proj_vector_ij = Num/Den; + + /*--- Orthogonal correction approach. ---*/ + /*dist_ij_2 = 0; proj_vector_ij = 0; + Num = 0.0; Den = 0.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]; + Num += MomCoeffxNormal[iDim]*MomCoeffxNormal[iDim]; + } + Den = dist_ij_2; + if (Den == 0.0) proj_vector_ij = 0.0; + else proj_vector_ij = sqrt(Num/Den);*/ + + /*--- Correct the face gradient for odd-even decoupling ---*/ + /*--- Steps are + * 1. Interpolate the gradient at the face -> du/ds|_in + * 2. Find the projection of the interpolated gradient on the edge vector -> (du/ds|_in) . e + * 3. Find the gradient as the difference between the neighboring nodes -> (u_j - u_i)/ds + * 4. Correct the gradient at the face using du/ds = du/ds|_in + ( (u_j - u_i)/ds - (du/ds|_in . e) ) . e ---*/ + + /*for (iVar = 0; iVar < nVar; iVar++) { + Mean_GradPoissonVar_Edge[iVar] = 0.0; + + GradPoisson[iVar] = (Poissonval_j - Poissonval_i)/sqrt(dist_ij_2); + + for (iDim = 0; iDim < nDim; iDim++) { + Mean_GradPoissonVar[iVar][iDim] = 0.5*(ConsVar_Grad_i[iVar][iDim] + ConsVar_Grad_j[iVar][iDim]); + + Mean_GradPoissonVar_Edge[iVar] += Mean_GradPoissonVar[iVar][iDim]*Edge_Vector[iDim]/dist_ij_2; + } + } + + for (iVar = 0; iVar < nVar; iVar++) { + for (iDim = 0; iDim < nDim; iDim++) { + Mean_GradPoissonVar_Face[iVar][iDim] = Mean_GradPoissonVar[iVar][iDim] + + (GradPoisson[iVar] - Mean_GradPoissonVar_Edge[iVar])*Edge_Vector[iDim]/dist_ij_2; + } + }*/ + + + /*--- Mean gradient approximation. Projection of the mean gradient + in the direction of the edge ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Proj_Mean_GradPoissonVar_Edge[iVar] = 0.0; + Proj_Mean_GradPoissonVar_Kappa[iVar] = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Mean_GradPoissonVar[iVar][iDim] = 0.5*(ConsVar_Grad_i[iVar][iDim] + ConsVar_Grad_j[iVar][iDim]); + Proj_Mean_GradPoissonVar_Kappa[iVar] += Mean_GradPoissonVar[iVar][iDim]*MomCoeffxNormal[iDim]; + Proj_Mean_GradPoissonVar_Edge[iVar] += Mean_GradPoissonVar[iVar][iDim]*Edge_Vector[iDim]; + } + Proj_Mean_GradPoissonVar_Corrected[iVar] = Proj_Mean_GradPoissonVar_Kappa[iVar]; + Proj_Mean_GradPoissonVar_Corrected[iVar] -= Proj_Mean_GradPoissonVar_Edge[iVar]*proj_vector_ij - + (Poissonval_j-Poissonval_i)*proj_vector_ij; + } + + /*--- Jacobians for implicit scheme ---*/ + + if (implicit) { + Jacobian_i[0][0] = -Poisson_Coeff_Mean*proj_vector_ij; + Jacobian_j[0][0] = Poisson_Coeff_Mean*proj_vector_ij; + } + + /*AD::SetPreaccOut(val_residual, nVar); + AD::EndPreacc();*/ + + delete [] MomCoeffxNormal; + delete [] MomCoeffxNormalCorrected; + + return ResidualType<>(Proj_Mean_GradPoissonVar_Corrected, Jacobian_i, Jacobian_j); +} + +CAvgGrad_Poisson::CAvgGrad_Poisson(unsigned short val_nDim, unsigned short val_nVar, + CConfig *config) : CNumerics(val_nDim, val_nVar, config) { + + implicit = false; + implicit = (config->GetKind_TimeIntScheme_Poisson() == EULER_IMPLICIT); // TODO: PBFlow: FIXED + direct = false; + + + Edge_Vector = new su2double [nDim]; + Proj_Mean_GradPoissonVar_Normal = new su2double [nVar]; + Proj_Mean_GradPoissonVar_Corrected = new su2double [nVar]; + Mom_Coeff_i = new su2double [nDim]; + Mom_Coeff_j = new su2double [nDim]; + + Jacobian_i = new su2double* [nVar]; + Jacobian_j = new su2double* [nVar]; + Mean_GradPoissonVar = new su2double* [nVar]; + for (iVar = 0; iVar < nVar; iVar++) { + Jacobian_i[iVar] = new su2double [nDim]; + Jacobian_j[iVar] = new su2double [nDim]; + Mean_GradPoissonVar[iVar] = new su2double [nDim]; + } + + Poisson_Coeff_i = 1.0; + Poisson_Coeff_j = 1.0; +} + + +CAvgGrad_Poisson::~CAvgGrad_Poisson(void) { + + unsigned int iDim; + delete [] Edge_Vector; + delete [] Proj_Mean_GradPoissonVar_Normal; + delete [] Proj_Mean_GradPoissonVar_Corrected; + delete [] Mom_Coeff_i; + delete [] Mom_Coeff_j; + + for (iVar = 0; iVar < nVar; iVar++) { + delete [] Mean_GradPoissonVar[iVar]; + delete [] Jacobian_i[iVar]; + delete [] Jacobian_j[iVar]; + } + delete [] Mean_GradPoissonVar; + delete [] Jacobian_i; + delete [] Jacobian_j; + +} + +CNumerics::ResidualType<> CAvgGrad_Poisson::ComputeResidual(const CConfig *config) { + + + su2double Coeff_Mean, Num, Den; + su2double *MomCoeffxNormal = new su2double[nDim]; + su2double Mean_GradPoissonVar_Edge[MAXNDIM], GradPoisson[MAXNDIM]; + su2double Mean_GradPoissonVar_Face[MAXNDIM][MAXNDIM]; + + + + Poisson_Coeff_Mean = 1.0;//0.5*(Poisson_Coeff_i + Poisson_Coeff_j); + + /*--- Multiply the normal with the coefficients of the momentum equation + * and use it instead of the normal during the projection operation ---*/ + for (iDim = 0; iDim < nDim; iDim++) { + Coeff_Mean = 0.5*(Mom_Coeff_i[iDim] + Mom_Coeff_j[iDim]) ; + MomCoeffxNormal[iDim] = Coeff_Mean*Normal[iDim]; + } + + /*--- Compute vector going from iPoint to jPoint ---*/ + /*--- Minimum correction approach. ---*/ + /*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]*MomCoeffxNormal[iDim]; + } + if (dist_ij_2 == 0.0) proj_vector_ij = 0.0; + else proj_vector_ij = proj_vector_ij/dist_ij_2;*/ + + /*--- Over relaxed approach. ---*/ + dist_ij_2 = 0; proj_vector_ij = 0; + Num = 0.0; Den = 0.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]; + Num += MomCoeffxNormal[iDim]*MomCoeffxNormal[iDim]; + Den += Edge_Vector[iDim]*MomCoeffxNormal[iDim]; + } + if (Den == 0.0) proj_vector_ij = 0.0; + else proj_vector_ij = Num/Den; + + /*--- Orthogonal correction approach. ---*/ + /*dist_ij_2 = 0; proj_vector_ij = 0; + Num = 0.0; Den = 0.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]; + Num += MomCoeffxNormal[iDim]*MomCoeffxNormal[iDim]; + } + Den = dist_ij_2; + if (Den == 0.0) proj_vector_ij = 0.0; + else proj_vector_ij = sqrt(Num/Den);*/ + + /*--- Correct the face gradient for odd-even decoupling ---*/ + /*--- Steps are + * 1. Interpolate the gradient at the face -> du/ds|_in + * 2. Find the projection of the interpolated gradient on the edge vector -> (du/ds|_in) . e + * 3. Find the gradient as the difference between the neighboring nodes -> (u_j - u_i)/ds + * 4. Correct the gradient at the face using du/ds = du/ds|_in + ( (u_j - u_i)/ds - (du/ds|_in . e) ) . e ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Mean_GradPoissonVar_Edge[iVar] = 0.0; + + GradPoisson[iVar] = (Poissonval_j - Poissonval_i)/sqrt(dist_ij_2); + + for (iDim = 0; iDim < nDim; iDim++) { + Mean_GradPoissonVar[iVar][iDim] = 0.5*(ConsVar_Grad_i[iVar][iDim] + ConsVar_Grad_j[iVar][iDim]); + + Mean_GradPoissonVar_Edge[iVar] += Mean_GradPoissonVar[iVar][iDim]*Edge_Vector[iDim]/sqrt(dist_ij_2); + } + } + + for (iVar = 0; iVar < nVar; iVar++) { + for (iDim = 0; iDim < nDim; iDim++) { + Mean_GradPoissonVar_Face[iVar][iDim] = Mean_GradPoissonVar[iVar][iDim] + + (GradPoisson[iVar] - Mean_GradPoissonVar_Edge[iVar])*Edge_Vector[iDim]/sqrt(dist_ij_2); + } + } + + /*--- Mean gradient approximation. Projection of the mean gradient in the direction of the edge ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + Proj_Mean_GradPoissonVar_Normal[iVar] = 0.0; + Proj_Mean_GradPoissonVar_Corrected[iVar] = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Proj_Mean_GradPoissonVar_Normal[iVar] += Mean_GradPoissonVar_Face[iVar][iDim]*MomCoeffxNormal[iDim]; + } + } + + /*--- Jacobians for implicit scheme ---*/ + if (implicit) { + Jacobian_i[0][0] = -Poisson_Coeff_Mean*proj_vector_ij; + Jacobian_j[0][0] = Poisson_Coeff_Mean*proj_vector_ij; + } + + delete [] MomCoeffxNormal; + + return ResidualType<>(Proj_Mean_GradPoissonVar_Normal, Jacobian_i, Jacobian_j); +} + + + +CPressure_Poisson::CPressure_Poisson(unsigned short val_nDim, unsigned short val_nVar, + CConfig *config) : CNumerics(val_nDim, val_nVar, config) { + + implicit = true; + + Edge_Vector = new su2double [nDim]; + + Poisson_Coeff_i = 1.0; + Poisson_Coeff_j = 1.0; + + Mom_Coeff_i = new su2double [nDim]; + Mom_Coeff_j = new su2double [nDim]; + +} + + +CPressure_Poisson::~CPressure_Poisson(void) { + + unsigned int iDim; + delete [] Edge_Vector; + + delete Mom_Coeff_i; + delete Mom_Coeff_j; +} + +void CPressure_Poisson::ComputeResidual(su2double *val_residual, su2double **Jacobian_i, su2double **Jacobian_j, CConfig *config) { + + + su2double Area; + su2double UnitNormal[MAXNDIM]; + + /*--- Compute vector going from iPoint to jPoint ---*/ + + dist_ij_2 = 0; proj_vector_ij = 0; + Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + 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]; + UnitNormal[iDim] = Normal[iDim]/Area; + } + if (dist_ij_2 == 0.0) proj_vector_ij = 0.0; + else proj_vector_ij = proj_vector_ij/dist_ij_2; + + + Poisson_Coeff_Mean = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Poisson_Coeff_Mean += 0.5*(Mom_Coeff_i[iDim] + Mom_Coeff_j[iDim]); + + + val_residual[0] = 0.5*Poisson_Coeff_Mean*(Poissonval_i + Poissonval_j); + + if (implicit){ + Jacobian_i[0][0] = Poisson_Coeff_Mean; + Jacobian_j[0][0] = -Poisson_Coeff_Mean; + } +} + + +CSource_PoissonFVM::CSource_PoissonFVM(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) : CNumerics(val_nDim, val_nVar, config) { } + +CSource_PoissonFVM::~CSource_PoissonFVM(void) { } + +void CSource_PoissonFVM::ComputeResidual(su2double *val_residual, su2double **val_Jacobian_i, CConfig *config) { + + if (config->GetKind_Incomp_System()==ENUM_INCOMP_SYSTEM::PRESSURE_BASED) + val_residual[0] = Source_Term; + else + val_residual[0] = Source_Term*Volume; +} \ No newline at end of file diff --git a/SU2_CFD/src/solvers/CPBIncEulerSolver.cpp b/SU2_CFD/src/solvers/CPBIncEulerSolver.cpp new file mode 100644 index 000000000000..a66a976ffb41 --- /dev/null +++ b/SU2_CFD/src/solvers/CPBIncEulerSolver.cpp @@ -0,0 +1,2779 @@ +/*! + * \file CPBIncEulerSolver.cpp + * \brief Main subroutines for solving pressure based incompressible flow (Euler, Navier-Stokes, etc.). + * \author F. Palacios, T. Economon, A. Koodly + * \version 8.0.0 "Harrier" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2020, SU2 Contributors (cf. AUTHORS.md) + * + * 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/CPBIncEulerSolver.hpp" +#include "../../../Common/include/toolboxes/printing_toolbox.hpp" +#include "../../include/fluid/CConstantDensity.hpp" +#include "../../include/fluid/CIncIdealGas.hpp" +#include "../../include/fluid/CIncIdealGasPolynomial.hpp" +#include "../../include/variables/CPBIncNSVariable.hpp" +#include "../../include/solvers/CFVMFlowSolverBase.inl" + +template class CFVMFlowSolverBase; + +CPBIncEulerSolver::CPBIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh, + const bool navier_stokes) : + CFVMFlowSolverBase(*geometry, *config) { + + /*--- Based on the navier_stokes boolean, determine if this constructor is + * being called by itself, or by the Navier Stokes solver. ---*/ + const string description = navier_stokes? "Navier-Stokes" : "Euler"; + + unsigned long iPoint, iVertex, iEdge, jPoint; + unsigned short iVar, iDim, iMarker; + ifstream restart_file; + unsigned short nZone = geometry->GetnZone(); + bool restart = (config->GetRestart() || config->GetRestart_Flow()); + int Unst_RestartIter; + unsigned short iZone = config->GetiZone(); + bool dual_time = ((config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) || + (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND)); + bool time_stepping = config->GetTime_Marching() == TIME_MARCHING::TIME_STEPPING; + string filename_ = config->GetSolution_FileName(); + + /* 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(); + + /*--- Check for a restart file to evaluate if there is a change in the angle of attack + before computing all the non-dimesional quantities. ---*/ + if (!(!restart || (iMesh != MESH_0) || nZone > 1)) { + + /*--- Multizone problems require the number of the zone to be appended. ---*/ + + if (nZone > 1) filename_ = config->GetMultizone_FileName(filename_, iZone, ".dat"); + + /*--- Modify file name for a dual-time unsteady restart ---*/ + + if (dual_time) { + if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) + Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-1; + else Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-2; + filename_ = config->GetUnsteady_FileName(filename_, Unst_RestartIter, ".dat"); + } + + /*--- Modify file name for a time stepping unsteady restart ---*/ + + if (time_stepping) { + Unst_RestartIter = SU2_TYPE::Int(config->GetRestart_Iter())-1; + filename_ = config->GetUnsteady_FileName(filename_, Unst_RestartIter, ".dat"); + } + } + + /*--- Define geometry constants in the solver structure. + * Incompressible flow, primitive variables (P, vx, vy, vz, rho, mu_lam, mu_t) ---*/ + + nDim = geometry->GetnDim(); + + nVar = nDim; nPrimVar = nDim+4; nPrimVarGrad = nDim+2; + + Residual_RMS.resize(nVar,0.0); // TODO: Added PBFlow + Residual_Max.resize(nVar,0.0); + /*--- Initialize nVarGrad for deallocation ---*/ + + nVarGrad = nPrimVarGrad; + + nMarker = config->GetnMarker_All(); + nPoint = geometry->GetnPoint(); + nPointDomain = geometry->GetnPointDomain(); + nEdge = geometry->GetnEdge(); + + /*--- Store the number of vertices on each marker for deallocation later ---*/ + + nVertex.resize(nMarker); + for (iMarker = 0; iMarker < nMarker; iMarker++) + nVertex[iMarker] = geometry->nVertex[iMarker]; + + /*--- Perform the non-dimensionalization for the flow equations using the + specified reference values. ---*/ + + SetNondimensionalization(config, iMesh); + + AllocateTerribleLegacyTemporaryVariables(); + + /*--- Define some auxiliary vectors related to the primitive solution ---*/ + + Primitive = new su2double[nPrimVar] (); + Primitive_i = new su2double[nPrimVar] (); + Primitive_j = new su2double[nPrimVar] (); + + /*--- Allocate base class members. ---*/ + + Allocate(*config); + + /*--- Jacobians and vector structures for implicit computations ---*/ + + if (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT) { + if (rank == MASTER_NODE) cout << "Initialize Jacobian structure ("<GetDensity_FreeStreamND(); + Pressure_Inf = config->GetPressure_FreeStreamND(); + Velocity_Inf = config->GetVelocity_FreeStreamND(); + + + /*--- Initialize the solution to the far-field state everywhere. ---*/ + if (navier_stokes) { + nodes = new CPBIncNSVariable(Density_Inf, Pressure_Inf, Velocity_Inf, nPoint, nDim, nVar, config); + } else { + nodes = new CPBIncEulerVariable(Density_Inf, Pressure_Inf, Velocity_Inf, nPoint, nDim, nVar, config); + } + SetBaseClassPointerToNodes(); + + /*--- Allocate velocities at every face. This is for momentum interpolation. ---*/ + + FaceVelocity.resize(nEdge,nDim); + FaceVelocityCorrec.resize(nEdge,nDim); + su2double Normal[MAXNDIM]; + for (iEdge = 0; iEdge < nEdge; iEdge++) { + geometry->edges->GetNormal(iEdge, Normal); + iPoint = geometry->edges->GetNode(iEdge,0); + jPoint = geometry->edges->GetNode(iEdge,1); + for (iDim = 0; iDim < nDim; iDim++) { + FaceVelocity[iEdge][iDim]= 0.5*(nodes->GetSolution(iPoint,iDim)+nodes->GetSolution(jPoint,iDim)); + FaceVelocityCorrec[iEdge][iDim] = 0.0; + } + } + PseudoTimeCorr.resize(nEdge,nDim) = su2double(0.0); + TimeMarchingCorr_n.resize(nEdge,nDim) = su2double(0.0); + TimeMarchingCorr_n1.resize(nEdge,nDim) = su2double(0.0); + + /*--- Initial comms. ---*/ + + CommunicateInitialState(geometry, config); + InitiateComms(geometry, config, PRESSURE_VAR); + CompleteComms(geometry, config, PRESSURE_VAR); + + /*--- Add the solver name (max 8 characters) ---*/ + SolverName = "INC.FLOW"; + +} + +CPBIncEulerSolver::~CPBIncEulerSolver() { + + unsigned short iMarker; + unsigned long iVertex; + unsigned long iEdge; + + delete [] Primitive; + delete [] Primitive_i; + delete [] Primitive_j; + + delete FluidModel; + +} + +void CPBIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMesh) { + + su2double Temperature_FreeStream = 0.0, ModVel_FreeStream = 0.0,Energy_FreeStream = 0.0, + ModVel_FreeStreamND = 0.0, Omega_FreeStream = 0.0, Omega_FreeStreamND = 0.0, Viscosity_FreeStream = 0.0, + Density_FreeStream = 0.0, Pressure_FreeStream = 0.0, Pressure_Thermodynamic = 0.0, Tke_FreeStream = 0.0, + Length_Ref = 0.0, Density_Ref = 0.0, Pressure_Ref = 0.0, Temperature_Ref = 0.0, Velocity_Ref = 0.0, Time_Ref = 0.0, + Gas_Constant_Ref = 0.0, Omega_Ref = 0.0, Force_Ref = 0.0, Viscosity_Ref = 0.0, Conductivity_Ref = 0.0, Heat_Flux_Ref = 0.0, Energy_Ref= 0.0, Pressure_FreeStreamND = 0.0, Pressure_ThermodynamicND = 0.0, Density_FreeStreamND = 0.0, + Temperature_FreeStreamND = 0.0, Gas_ConstantND = 0.0, Specific_Heat_CpND = 0.0, Specific_Heat_CvND = 0.0, Thermal_Expansion_CoeffND = 0.0, + Velocity_FreeStreamND[3] = {0.0, 0.0, 0.0}, Viscosity_FreeStreamND = 0.0, + Tke_FreeStreamND = 0.0, Energy_FreeStreamND = 0.0, + Total_UnstTimeND = 0.0, Delta_UnstTimeND = 0.0; + + unsigned short iDim, iVar; + + /*--- Local variables ---*/ + + su2double Mach = config->GetMach(); + su2double Reynolds = config->GetReynolds(); + auto turb_model = config->GetKind_Turb_Model(); + + bool unsteady = (config->GetTime_Marching() != TIME_MARCHING::STEADY); + bool viscous = config->GetViscous(); + bool turbulent = (config->GetKind_Solver() == MAIN_SOLVER::RANS); + bool tkeNeeded = ((turbulent) && (turb_model == TURB_MODEL::SST)); + + /*--- Compute dimensional free-stream values. ---*/ + + Density_FreeStream = config->GetInc_Density_Init(); config->SetDensity_FreeStream(Density_FreeStream); + Temperature_FreeStream = config->GetInc_Temperature_Init(); config->SetTemperature_FreeStream(Temperature_FreeStream); + Pressure_FreeStream = 0.0; config->SetPressure_FreeStream(Pressure_FreeStream); + + ModVel_FreeStream = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + ModVel_FreeStream += config->GetInc_Velocity_Init()[iDim]*config->GetInc_Velocity_Init()[iDim]; + config->SetVelocity_FreeStream(config->GetInc_Velocity_Init()[iDim],iDim); + } + ModVel_FreeStream = sqrt(ModVel_FreeStream); config->SetModVel_FreeStream(ModVel_FreeStream); + + /*--- Only constant density model is available. ---*/ + + switch (config->GetKind_FluidModel()) { + + case CONSTANT_DENSITY: + + FluidModel = new CConstantDensity(Density_FreeStream, config->GetSpecific_Heat_Cp()); + FluidModel->SetTDState_T(Temperature_FreeStream); + break; + default: + SU2_MPI::Error("Fluid model not implemented for pressure based incompressible solver.", CURRENT_FUNCTION); + break; + } + + if (viscous) { + + /*--- The dimensional viscosity is needed to determine the free-stream conditions. + To accomplish this, simply set the non-dimensional coefficients to the + dimensional ones. This will be overruled later.---*/ + + // config->SetMu_RefND(config->GetMu_Ref()); + config->SetMu_Temperature_RefND(config->GetMu_Temperature_Ref()); + config->SetMu_SND(config->GetMu_S()); + config->SetMu_ConstantND(config->GetMu_Constant()); + + /*--- Use the fluid model to compute the dimensional viscosity/conductivity. ---*/ + + FluidModel->SetLaminarViscosityModel(config); + Viscosity_FreeStream = FluidModel->GetLaminarViscosity(); + config->SetViscosity_FreeStream(Viscosity_FreeStream); + + Reynolds = Density_FreeStream*ModVel_FreeStream/Viscosity_FreeStream; config->SetReynolds(Reynolds); + + /*--- Turbulence kinetic energy ---*/ + + Tke_FreeStream = 3.0/2.0*(ModVel_FreeStream*ModVel_FreeStream*config->GetTurbulenceIntensity_FreeStream()*config->GetTurbulenceIntensity_FreeStream()); + + } + + /*--- The non-dim. scheme for incompressible flows uses the following ref. values: + Reference length = 1 m (fixed by default, grid in meters) + Reference density = liquid density or freestream (input) + Reference velocity = liquid velocity or freestream (input) + Reference temperature = liquid temperature or freestream (input) + Reference pressure = Reference density * Reference velocity * Reference velocity + Reference viscosity = Reference Density * Reference velocity * Reference length + This is the same non-dim. scheme as in the compressible solver. + Note that the Re and Re Length are not used as part of initialization. ---*/ + + if (config->GetRef_Inc_NonDim() == DIMENSIONAL) { + Density_Ref = 1.0; + Velocity_Ref = 1.0; + Temperature_Ref = 1.0; + Pressure_Ref = 1.0; + } + else if (config->GetRef_Inc_NonDim() == INITIAL_VALUES) { + Density_Ref = Density_FreeStream; + Velocity_Ref = ModVel_FreeStream; + Temperature_Ref = Temperature_FreeStream; + Pressure_Ref = Density_Ref*Velocity_Ref*Velocity_Ref; + } + else if (config->GetRef_Inc_NonDim() == REFERENCE_VALUES) { + Density_Ref = config->GetInc_Density_Ref(); + Velocity_Ref = config->GetInc_Velocity_Ref(); + Temperature_Ref = config->GetInc_Temperature_Ref(); + Pressure_Ref = Density_Ref*Velocity_Ref*Velocity_Ref; + } + config->SetDensity_Ref(Density_Ref); + config->SetVelocity_Ref(Velocity_Ref); + config->SetTemperature_Ref(Temperature_Ref); + config->SetPressure_Ref(Pressure_Ref); + + /*--- More derived reference values ---*/ + + Length_Ref = 1.0; config->SetLength_Ref(Length_Ref); + Time_Ref = Length_Ref/Velocity_Ref; config->SetTime_Ref(Time_Ref); + Omega_Ref = Velocity_Ref/Length_Ref; config->SetOmega_Ref(Omega_Ref); + Force_Ref = Velocity_Ref*Velocity_Ref/Length_Ref; config->SetForce_Ref(Force_Ref); + Gas_Constant_Ref = Velocity_Ref*Velocity_Ref/Temperature_Ref; config->SetGas_Constant_Ref(Gas_Constant_Ref); + Viscosity_Ref = Density_Ref*Velocity_Ref*Length_Ref; config->SetViscosity_Ref(Viscosity_Ref); + Heat_Flux_Ref = Density_Ref*Velocity_Ref*Velocity_Ref*Velocity_Ref; config->SetHeat_Flux_Ref(Heat_Flux_Ref); //To avoid error in Friction Force routine only + + /*--- Get the freestream energy. Only useful if energy equation is active. ---*/ + + Energy_FreeStream = FluidModel->GetStaticEnergy() + 0.5*ModVel_FreeStream*ModVel_FreeStream; + config->SetEnergy_FreeStream(Energy_FreeStream); + if (tkeNeeded) { Energy_FreeStream += Tke_FreeStream; }; config->SetEnergy_FreeStream(Energy_FreeStream); + + /*--- Compute Mach number ---*/ + + if (config->GetKind_FluidModel() == CONSTANT_DENSITY) { + Mach = ModVel_FreeStream / sqrt(config->GetBulk_Modulus()/Density_FreeStream); + } else { + Mach = 0.0; + } + config->SetMach(Mach); + + /*--- Divide by reference values, to compute the non-dimensional free-stream values ---*/ + + Pressure_FreeStreamND = Pressure_FreeStream/config->GetPressure_Ref(); config->SetPressure_FreeStreamND(Pressure_FreeStreamND); + Pressure_ThermodynamicND = Pressure_Thermodynamic/config->GetPressure_Ref(); config->SetPressure_ThermodynamicND(Pressure_ThermodynamicND); + Density_FreeStreamND = Density_FreeStream/config->GetDensity_Ref(); config->SetDensity_FreeStreamND(Density_FreeStreamND); + + for (iDim = 0; iDim < nDim; iDim++) { + Velocity_FreeStreamND[iDim] = config->GetVelocity_FreeStream()[iDim]/Velocity_Ref; config->SetVelocity_FreeStreamND(Velocity_FreeStreamND[iDim], iDim); + } + + ModVel_FreeStreamND = 0.0; + for (iDim = 0; iDim < nDim; iDim++) ModVel_FreeStreamND += Velocity_FreeStreamND[iDim]*Velocity_FreeStreamND[iDim]; + ModVel_FreeStreamND = sqrt(ModVel_FreeStreamND); config->SetModVel_FreeStreamND(ModVel_FreeStreamND); + + Viscosity_FreeStreamND = Viscosity_FreeStream / Viscosity_Ref; config->SetViscosity_FreeStreamND(Viscosity_FreeStreamND); + + Tke_FreeStream = 3.0/2.0*(ModVel_FreeStream*ModVel_FreeStream*config->GetTurbulenceIntensity_FreeStream()*config->GetTurbulenceIntensity_FreeStream()); + config->SetTke_FreeStream(Tke_FreeStream); + + Tke_FreeStreamND = 3.0/2.0*(ModVel_FreeStreamND*ModVel_FreeStreamND*config->GetTurbulenceIntensity_FreeStream()*config->GetTurbulenceIntensity_FreeStream()); + config->SetTke_FreeStreamND(Tke_FreeStreamND); + + Omega_FreeStream = Density_FreeStream*Tke_FreeStream/(Viscosity_FreeStream*config->GetTurb2LamViscRatio_FreeStream()); + config->SetOmega_FreeStream(Omega_FreeStream); + + Omega_FreeStreamND = Density_FreeStreamND*Tke_FreeStreamND/(Viscosity_FreeStreamND*config->GetTurb2LamViscRatio_FreeStream()); + config->SetOmega_FreeStreamND(Omega_FreeStreamND); + + /*--- Delete the original (dimensional) FluidModel object. No fluid is used for inscompressible cases. ---*/ + + delete FluidModel; + + switch (config->GetKind_FluidModel()) { + + case CONSTANT_DENSITY: + FluidModel = new CConstantDensity(Density_FreeStreamND, Specific_Heat_CpND); + FluidModel->SetTDState_T(Temperature_FreeStreamND); + break; + + } + + if (viscous) { + + /*--- Constant viscosity model ---*/ + + config->SetMu_ConstantND(config->GetMu_Constant()/Viscosity_Ref); + + /*--- Set up the transport property models. ---*/ + + FluidModel->SetLaminarViscosityModel(config); + + } + + if (tkeNeeded) { Energy_FreeStreamND += Tke_FreeStreamND; }; config->SetEnergy_FreeStreamND(Energy_FreeStreamND); + + Total_UnstTimeND = config->GetTotal_UnstTime() / Time_Ref; config->SetTotal_UnstTimeND(Total_UnstTimeND); + Delta_UnstTimeND = config->GetDelta_UnstTime() / Time_Ref; config->SetDelta_UnstTimeND(Delta_UnstTimeND); + + /*--- Write output to the console if this is the master node and first domain ---*/ + + if ((rank == MASTER_NODE) && (iMesh == MESH_0)) { + + cout.precision(6); + + if (config->GetRef_Inc_NonDim() == DIMENSIONAL) { + cout << "Pressure based incompressible flow: rho_ref, vel_ref, temp_ref, p_ref" << endl; + cout << "are set to 1.0 in order to perform a dimensional calculation." << endl; + if (dynamic_grid) cout << "Force coefficients computed using MACH_MOTION." << endl; + else cout << "Force coefficients computed using initial values." << endl; + } + else if (config->GetRef_Inc_NonDim() == INITIAL_VALUES) { + cout << "Pressure based incompressible flow: rho_ref, vel_ref, and temp_ref" << endl; + cout << "are based on the initial values, p_ref = rho_ref*vel_ref^2." << endl; + if (dynamic_grid) cout << "Force coefficients computed using MACH_MOTION." << endl; + else cout << "Force coefficients computed using initial values." << endl; + } + else if (config->GetRef_Inc_NonDim() == REFERENCE_VALUES) { + cout << "Pressure based incompressible flow: rho_ref, vel_ref, and temp_ref" << endl; + cout << "are user-provided reference values, p_ref = rho_ref*vel_ref^2." << endl; + if (dynamic_grid) cout << "Force coefficients computed using MACH_MOTION." << endl; + else cout << "Force coefficients computed using reference values." << endl; + } + cout << "The reference area for force coeffs. is " << config->GetRefArea() << " m^2." << endl; + cout << "The reference length for force coeffs. is " << config->GetRefLength() << " m." << endl; + + cout << "The pressure is decomposed into thermodynamic and dynamic components." << endl; + cout << "The initial value of the dynamic pressure is 0." << endl; + + cout << "Mach number: "<< config->GetMach(); + if (config->GetKind_FluidModel() == CONSTANT_DENSITY) { + cout << ", computed using the Bulk modulus." << endl; + } else { + cout << ", computed using fluid speed of sound." << endl; + } + + cout << "For external flows, the initial state is imposed at the far-field." << endl; + cout << "Angle of attack (deg): "<< config->GetAoA() << ", computed using the initial velocity." << endl; + cout << "Side slip angle (deg): "<< config->GetAoS() << ", computed using the initial velocity." << endl; + + if (viscous) { + cout << "Reynolds number per meter: " << config->GetReynolds() << ", computed using initial values."<< endl; + cout << "Reynolds number is a byproduct of inputs only (not used internally)." << endl; + } + cout << "SI units only. The grid should be dimensional (meters)." << endl; + + switch (config->GetKind_DensityModel()) { + + case INC_DENSITYMODEL::CONSTANT: + cout << "No energy equation." << endl; + break; + } + + stringstream NonDimTableOut, ModelTableOut; + stringstream Unit; + + cout << endl; + PrintingToolbox::CTablePrinter ModelTable(&ModelTableOut); + ModelTableOut <<"-- Models:"<< endl; + + ModelTable.AddColumn("Viscosity Model", 25); + ModelTable.AddColumn("Conductivity Model", 26); + ModelTable.AddColumn("Fluid Model", 25); + ModelTable.SetAlign(PrintingToolbox::CTablePrinter::RIGHT); + ModelTable.PrintHeader(); + + PrintingToolbox::CTablePrinter NonDimTable(&NonDimTableOut); + NonDimTable.AddColumn("Name", 22); + NonDimTable.AddColumn("Dim. value", 14); + NonDimTable.AddColumn("Ref. value", 14); + NonDimTable.AddColumn("Unit", 10); + NonDimTable.AddColumn("Non-dim. value", 14); + NonDimTable.SetAlign(PrintingToolbox::CTablePrinter::RIGHT); + + NonDimTableOut <<"-- Fluid properties:"<< endl; + + NonDimTable.PrintHeader(); + + if (viscous){ + + switch(config->GetKind_ViscosityModel()){ + case VISCOSITYMODEL::CONSTANT: + ModelTable << "CONSTANT_VISCOSITY"; + if (config->GetSystemMeasurements() == SI) Unit << "N.s/m^2"; + else if (config->GetSystemMeasurements() == US) Unit << "lbf.s/ft^2"; + NonDimTable << "Viscosity" << config->GetMu_Constant() << config->GetMu_Constant()/config->GetMu_ConstantND() << Unit.str() << config->GetMu_ConstantND(); + Unit.str(""); + NonDimTable.PrintFooter(); + break; + } + } else { + ModelTable << "-" << "-"; + } + + NonDimTableOut <<"-- Initial and free-stream conditions:"<< endl; + NonDimTable.PrintHeader(); + + if (config->GetSystemMeasurements() == SI) Unit << "Pa"; + else if (config->GetSystemMeasurements() == US) Unit << "psf"; + NonDimTable << "Dynamic Pressure" << config->GetPressure_FreeStream() << config->GetPressure_Ref() << Unit.str() << config->GetPressure_FreeStreamND(); + Unit.str(""); + if (config->GetSystemMeasurements() == SI) Unit << "Pa"; + else if (config->GetSystemMeasurements() == US) Unit << "psf"; + NonDimTable << "Total Pressure" << config->GetPressure_FreeStream() + 0.5*config->GetDensity_FreeStream()*config->GetModVel_FreeStream()*config->GetModVel_FreeStream() + << config->GetPressure_Ref() << Unit.str() << config->GetPressure_FreeStreamND() + 0.5*config->GetDensity_FreeStreamND()*config->GetModVel_FreeStreamND()*config->GetModVel_FreeStreamND(); + Unit.str(""); + if (config->GetSystemMeasurements() == SI) Unit << "kg/m^3"; + else if (config->GetSystemMeasurements() == US) Unit << "slug/ft^3"; + NonDimTable << "Density" << config->GetDensity_FreeStream() << config->GetDensity_Ref() << Unit.str() << config->GetDensity_FreeStreamND(); + Unit.str(""); + if (config->GetSystemMeasurements() == SI) Unit << "m/s"; + else if (config->GetSystemMeasurements() == US) Unit << "ft/s"; + NonDimTable << "Velocity-X" << config->GetVelocity_FreeStream()[0] << config->GetVelocity_Ref() << Unit.str() << config->GetVelocity_FreeStreamND()[0]; + NonDimTable << "Velocity-Y" << config->GetVelocity_FreeStream()[1] << config->GetVelocity_Ref() << Unit.str() << config->GetVelocity_FreeStreamND()[1]; + if (nDim == 3){ + NonDimTable << "Velocity-Z" << config->GetVelocity_FreeStream()[2] << config->GetVelocity_Ref() << Unit.str() << config->GetVelocity_FreeStreamND()[2]; + } + NonDimTable << "Velocity Magnitude" << config->GetModVel_FreeStream() << config->GetVelocity_Ref() << Unit.str() << config->GetModVel_FreeStreamND(); + Unit.str(""); + + if (viscous){ + NonDimTable.PrintFooter(); + if (config->GetSystemMeasurements() == SI) Unit << "N.s/m^2"; + else if (config->GetSystemMeasurements() == US) Unit << "lbf.s/ft^2"; + NonDimTable << "Viscosity" << config->GetViscosity_FreeStream() << config->GetViscosity_Ref() << Unit.str() << config->GetViscosity_FreeStreamND(); + Unit.str(""); + if (turbulent){ + if (config->GetSystemMeasurements() == SI) Unit << "m^2/s^2"; + else if (config->GetSystemMeasurements() == US) Unit << "ft^2/s^2"; + NonDimTable << "Turb. Kin. Energy" << config->GetTke_FreeStream() << config->GetTke_FreeStream()/config->GetTke_FreeStreamND() << Unit.str() << config->GetTke_FreeStreamND(); + Unit.str(""); + if (config->GetSystemMeasurements() == SI) Unit << "1/s"; + else if (config->GetSystemMeasurements() == US) Unit << "1/s"; + NonDimTable << "Spec. Dissipation" << config->GetOmega_FreeStream() << config->GetOmega_FreeStream()/config->GetOmega_FreeStreamND() << Unit.str() << config->GetOmega_FreeStreamND(); + Unit.str(""); + } + } + + NonDimTable.PrintFooter(); + NonDimTable << "Mach Number" << "-" << "-" << "-" << config->GetMach(); + if (viscous){ + NonDimTable << "Reynolds Number" << "-" << "-" << "-" << config->GetReynolds(); + } + + NonDimTable.PrintFooter(); + ModelTable.PrintFooter(); + + if (unsteady){ + NonDimTable.PrintHeader(); + NonDimTableOut << "-- Unsteady conditions" << endl; + NonDimTable << "Total Time" << config->GetTotal_UnstTime() << config->GetTime_Ref() << "s" << config->GetTotal_UnstTimeND(); + Unit.str(""); + NonDimTable << "Time Step" << config->GetDelta_UnstTime() << config->GetTime_Ref() << "s" << config->GetDelta_UnstTimeND(); + Unit.str(""); + NonDimTable.PrintFooter(); + } + + + cout << ModelTableOut.str(); + cout << NonDimTableOut.str(); + } +} + +void CPBIncEulerSolver::SetInitialCondition(CGeometry **geometry, CSolver ***solver_container, CConfig *config, unsigned long TimeIter) { + +} + +void CPBIncEulerSolver::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 implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool muscl = config->GetMUSCL_Flow(); + bool limiter = (config->GetKind_SlopeLimit_Flow() != LIMITER::NONE) && (InnerIter <= config->GetLimiterIter()); + unsigned long iVertex; + unsigned short iVar, iMarker; + + /*--- Set the primitive variables ---*/ + + ErrorCounter = SetPrimitive_Variables(solver_container, config, Output); + + /*--- Compute Primitive gradients to be used in Mass flux computation and pressure residual ---*/ + + if ((iMesh == MESH_0) && !Output) { + + /*--- Gradient computation for MUSCL reconstruction. ---*/ + + if (config->GetKind_Gradient_Method_Recon() == GREEN_GAUSS) + SetPrimitive_Gradient_GG(geometry, config, true); + if (config->GetKind_Gradient_Method_Recon() == LEAST_SQUARES) + SetPrimitive_Gradient_LS(geometry, config, true); + if (config->GetKind_Gradient_Method_Recon() == WEIGHTED_LEAST_SQUARES) + SetPrimitive_Gradient_LS(geometry, config, true); + + /*--- Limiter computation ---*/ + + if ((limiter) && (iMesh == MESH_0) && !Output) { + SetPrimitive_Limiter(geometry, config); + } + + /*--- Compute gradient of the primitive variables for pressure source term ---*/ + + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { + SetPrimitive_Gradient_GG(geometry, config, false); + } + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + SetPrimitive_Gradient_LS(geometry, config, false); + } + } + + /*--- Reset mass flux residual. ---*/ + SetResMassFluxZero(); + + /*--- Reset flag for strong BCs. ---*/ + for (unsigned long iPoint = 0; iPoint < nPointDomain; iPoint++) + nodes->ResetStrongBC(iPoint); + + + /*--- Initialize the Jacobian matrices ---*/ + + if (implicit) Jacobian.SetValZero(); + + /*--- Error message ---*/ + + if (config->GetComm_Level() == COMM_FULL) { +#ifdef HAVE_MPI + unsigned long MyErrorCounter = ErrorCounter; ErrorCounter = 0; + SU2_MPI::Allreduce(&MyErrorCounter, &ErrorCounter, 1, MPI_UNSIGNED_LONG, MPI_SUM, MPI_COMM_WORLD); +#endif + if (iMesh == MESH_0) config->SetNonphysical_Points(ErrorCounter); + } +} + +void CPBIncEulerSolver::Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, + unsigned short iMesh) { +bool RightSol = true; +unsigned long iPoint, ErrorCounter = 0; + + /*--- Set the current estimate of velocity as a primitive variable, needed for momentum interpolation. + * -- This does not change the pressure, it remains the same as the old value .i.e. previous (pseudo)time step. ---*/ + if (iMesh == MESH_0) ErrorCounter = SetPrimitive_Variables(solver_container, config, true); + + /*--- Compute gradients to be used in Rhie Chow interpolation ---*/ + + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { + SetPrimitive_Gradient_GG(geometry, config); + } + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + SetPrimitive_Gradient_LS(geometry, config); + } +} + +unsigned long CPBIncEulerSolver::SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output) { + + unsigned long iPoint, nonPhysicalPoints = 0; + unsigned short iVar; + su2double pressure_val; + + bool physical = true; + + for (iPoint = 0; iPoint < nPoint; iPoint ++) { + + /*--- PB Incompressible flow, primitive variables nDim+4, (P, vx, vy, vz, rho, lam_mu, eddy_visc) ---*/ + + physical = nodes->SetPrimVar(iPoint, Density_Inf, config); + + /* Check for non-realizable states for reporting. */ + + if (!physical) nonPhysicalPoints++; + + /*--- Initialize the convective, source and viscous residual vector ---*/ + + if (!Output) LinSysRes.SetBlock_Zero(iPoint); + + } + + return nonPhysicalPoints; +} + + +void CPBIncEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo) { + + /*--- Restart the solution from file information ---*/ + unsigned short iDim, iVar, iMesh, iMeshFine; + unsigned long iPoint, index, iChildren, Point_Fine; + auto turb_model = config->GetKind_Turb_Model(); + su2double Area_Children, Area_Parent, Coord[3] = {0.0}, *Solution_Fine; + + bool dual_time = ((config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) || + (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND)); + bool steady_restart = config->GetSteadyRestart(); + bool time_stepping = config->GetTime_Marching() == TIME_MARCHING::TIME_STEPPING; + bool turbulent = (config->GetKind_Solver() == MAIN_SOLVER::INC_RANS) || (config->GetKind_Solver() == MAIN_SOLVER::DISC_ADJ_INC_RANS); + + string restart_filename = config->GetFilename(config->GetSolution_FileName(), "", val_iter); + + 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; + + /*--- This variable is only used to skip upto grid velocities. + Pressure + ndim velocities need to be read from the restart file. + Mass flux is also stored in restart file, need to skip it when + reading grid velocities.---*/ + unsigned short nVar_Restart = nVar+2; + + /*--- Skip coordinates ---*/ + + unsigned short skipVars = geometry[MESH_0]->GetnDim(); + + /*--- Store the number of variables for the turbulence model + (that could appear in the restart file before the grid velocities). ---*/ + unsigned short turbVars = 0; + if (turbulent){ + if (turb_model == TURB_MODEL::SST) turbVars = 2; + else turbVars = 1; + } + + /*--- 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); + } + + /*--- 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. + Pressure is not part of the solution vector, so store it in the + primitive variable vector---*/ + + index = counter*Restart_Vars[1] + skipVars; + nodes->SetPressure_val(iPoint_Local, Restart_Data[index]); + for (iVar = 1; iVar <= nVar; iVar++) Solution[iVar-1] = Restart_Data[index+iVar]; + nodes->SetSolution(iPoint_Local, Solution); + iPoint_Global_Local++; + + /*--- Remove mass flux. ---*/ + index++; + + /*--- For dynamic meshes, read in and store the + grid coordinates and grid velocities for each node. ---*/ + + if (dynamic_grid) { + + /*--- First, remove any variables for the turbulence model that + appear in the restart file before the grid velocities. ---*/ + + if (turb_model == TURB_MODEL::SA) { + index++; + } else if (turb_model == TURB_MODEL::SST) { + index+=2; + } + + /*--- 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 ---*/ + + su2double GridVel[3] = {0.0,0.0,0.0}; + if (!steady_restart) { + + /*--- Rewind the index to retrieve the Coords. ---*/ + index = counter*Restart_Vars[1]; + for (iDim = 0; iDim < nDim; iDim++) { Coord[iDim] = Restart_Data[index+iDim]; } + + /*--- Move the index forward to get the grid velocities. ---*/ + index = counter*Restart_Vars[1] + skipVars + nVar_Restart + turbVars; + for (iDim = 0; iDim < nDim; iDim++) { GridVel[iDim] = Restart_Data[index+iDim]; } + } + + for (iDim = 0; iDim < nDim; iDim++) { + geometry[MESH_0]->nodes->SetCoord(iPoint_Local, iDim, Coord[iDim]); + geometry[MESH_0]->nodes->SetGridVel(iPoint_Local, iDim, GridVel[iDim]); + } + } + /*--- Increment the overall counter for how many points have been loaded. ---*/ + counter++; + + } + } + + /*--- Detect a wrong solution file ---*/ + + if (iPoint_Global_Local < nPointDomain) { + 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); + } + + /*--- Update the geometry for flows on deforming meshes ---*/ + + if (dynamic_grid) { + + /*--- Communicate the new coordinates and grid velocities at the halos ---*/ + + geometry[MESH_0]->InitiateComms(geometry[MESH_0], config, COORDINATES); + geometry[MESH_0]->CompleteComms(geometry[MESH_0], config, COORDINATES); + + if (dynamic_grid) { + geometry[MESH_0]->InitiateComms(geometry[MESH_0], config, GRID_VELOCITY); + geometry[MESH_0]->CompleteComms(geometry[MESH_0], config, GRID_VELOCITY); + } + + /*--- Recompute the edges and dual mesh control volumes in the + domain and on the boundaries. ---*/ + + geometry[MESH_0]->SetCoord_CG(); + geometry[MESH_0]->SetControlVolume(config, UPDATE); + geometry[MESH_0]->SetBoundControlVolume(config, UPDATE); + geometry[MESH_0]->SetMaxLength(config); + + /*--- Update the multigrid structure after setting up the finest grid, + including computing the grid velocities on the coarser levels. ---*/ + + for (iMesh = 1; iMesh <= config->GetnMGLevels(); iMesh++) { + iMeshFine = iMesh-1; + geometry[iMesh]->SetControlVolume(config, UPDATE); + geometry[iMesh]->SetBoundControlVolume(config, UPDATE); + geometry[iMesh]->SetCoord(geometry[iMeshFine]); + if (dynamic_grid) { + geometry[iMesh]->SetRestricted_GridVelocity(geometry[iMeshFine]); + } + geometry[iMesh]->SetMaxLength(config); + } + } + + /*--- Communicate the loaded solution on the fine grid before we transfer + it down to the coarse levels. We alo call the preprocessing routine + on the fine level in order to have all necessary quantities updated, + especially if this is a turbulent simulation (eddy viscosity). ---*/ + + solver[MESH_0][FLOW_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); + solver[MESH_0][FLOW_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); + solver[MESH_0][FLOW_SOL]->InitiateComms(geometry[MESH_0], config, PRESSURE_VAR); + solver[MESH_0][FLOW_SOL]->CompleteComms(geometry[MESH_0], config, PRESSURE_VAR); + + /*--- For turbulent simulations the flow preprocessing is done by the turbulence solver + * after it loads its variables (they are needed to compute flow primitives). ---*/ + if (!turbulent) { + solver[MESH_0][FLOW_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, RUNTIME_FLOW_SYS, false); + } + + /*--- 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]->nodes->GetVolume(iPoint); + for (iVar = 0; iVar < nVar; iVar++) Solution[iVar] = 0.0; + for (iChildren = 0; iChildren < geometry[iMesh]->nodes->GetnChildren_CV(iPoint); iChildren++) { + Point_Fine = geometry[iMesh]->nodes->GetChildren_CV(iPoint, iChildren); + Area_Children = geometry[iMesh-1]->nodes->GetVolume(Point_Fine); + Solution_Fine = solver[iMesh-1][FLOW_SOL]->GetNodes()->GetSolution(Point_Fine); + for (iVar = 0; iVar < nVar; iVar++) { + Solution[iVar] += Solution_Fine[iVar]*Area_Children/Area_Parent; + } + } + solver[iMesh][FLOW_SOL]->GetNodes()->SetSolution(iPoint, Solution); + } + + solver[iMesh][FLOW_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); + solver[iMesh][FLOW_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); + solver[MESH_0][FLOW_SOL]->InitiateComms(geometry[iMesh], config, PRESSURE_VAR); + solver[MESH_0][FLOW_SOL]->CompleteComms(geometry[iMesh], config, PRESSURE_VAR); + if (!turbulent) { + solver[iMesh][FLOW_SOL]->Preprocessing(geometry[iMesh], solver[iMesh], config, iMesh, NO_RK_ITER, RUNTIME_FLOW_SYS, false); + } + } + + /*--- Update the old geometry (coordinates n and n-1) in dual time-stepping strategy ---*/ + if (dual_time && config->GetGrid_Movement() && !config->GetDeform_Mesh() && + (config->GetKind_GridMovement() != RIGID_MOTION)) { + Restart_OldGeometry(geometry[MESH_0], config); + } + + /*--- Delete the class memory that is used to load the restart. ---*/ + + delete [] Restart_Vars; Restart_Vars = nullptr; + delete [] Restart_Data; Restart_Data = nullptr; + +} + + + + +void CPBIncEulerSolver::Centered_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, + CConfig *config, unsigned short iMesh, unsigned short iRKStep) { + + CNumerics* numerics = numerics_container[CONV_TERM]; + su2double *V_i, *V_j; + unsigned long iEdge, iPoint, jPoint, counter_local = 0, counter_global = 0; + unsigned short iDim, iVar; + unsigned long InnerIter = config->GetInnerIter(); + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + + /*--- Loop over all the edges ---*/ + + for (iEdge = 0; iEdge < nEdge; iEdge++) { + + /*--- Points in edge and normal vectors ---*/ + iPoint = geometry->edges->GetNode(iEdge,0); jPoint = geometry->edges->GetNode(iEdge,1); + numerics->SetNormal(geometry->edges->GetNormal(iEdge)); + numerics->SetNeighbor(geometry->nodes->GetnNeighbor(iPoint), geometry->nodes->GetnNeighbor(jPoint)); + + /*--- Grid movement ---*/ + if (dynamic_grid) + numerics->SetGridVel(geometry->nodes->GetGridVel(iPoint), geometry->nodes->GetGridVel(jPoint)); + + /*--- Get primitive variables ---*/ + V_i = nodes->GetPrimitive(iPoint); V_j = nodes->GetPrimitive(jPoint); + numerics->SetPrimitive(V_i, V_j); + + /*--- Compute residuals, and Jacobians ---*/ + auto residual = numerics->ComputeResidual(config); + + /*--- Update residual value ---*/ + LinSysRes.AddBlock(iPoint, residual); + LinSysRes.SubtractBlock(jPoint, residual); + + + /*--- Set implicit Jacobians ---*/ + if (implicit) + Jacobian.UpdateBlocks(iEdge,iPoint,jPoint,residual.jacobian_i, residual.jacobian_j); + } +} + +void CPBIncEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, + CConfig *config, unsigned short iMesh) { + + CNumerics* numerics = numerics_container[CONV_TERM]; + CMatrixView Gradient_i, Gradient_j; + su2double Project_Grad_i, Project_Grad_j, Normal[3], *GV, + *V_i, *V_j, *S_i, *S_j, *Limiter_i = NULL, *Limiter_j = NULL, Non_Physical = 1.0; + unsigned long iEdge, iPoint, jPoint, counter_local = 0, counter_global = 0; + unsigned short iDim, iVar; + unsigned long InnerIter = config->GetInnerIter(); + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool muscl = (config->GetMUSCL_Flow() && (iMesh == MESH_0)); + bool limiter = ((config->GetKind_SlopeLimit_Flow() != LIMITER::NONE) && (InnerIter <= config->GetLimiterIter())); + bool van_albada = config->GetKind_SlopeLimit_Flow() == LIMITER::VAN_ALBADA_EDGE; + + /*--- Loop over all the edges ---*/ + + for (iEdge = 0; iEdge < nEdge; iEdge++) { + + /*--- Points in edge and normal vectors ---*/ + + iPoint = geometry->edges->GetNode(iEdge,0); jPoint = geometry->edges->GetNode(iEdge,1); + numerics->SetNormal(geometry->edges->GetNormal(iEdge)); + + /*--- Grid movement ---*/ + + if (dynamic_grid) + numerics->SetGridVel(geometry->nodes->GetGridVel(iPoint), geometry->nodes->GetGridVel(jPoint)); + + /*--- Get primitive variables ---*/ + + V_i = nodes->GetPrimitive(iPoint); V_j = nodes->GetPrimitive(jPoint); + S_i = nodes->GetSecondary(iPoint); S_j = nodes->GetSecondary(jPoint); + + /*--- High order reconstruction using MUSCL strategy ---*/ + + if (muscl) { + + for (iDim = 0; iDim < nDim; iDim++) { + Vector_i[iDim] = 0.5*(geometry->nodes->GetCoord(jPoint, iDim) - geometry->nodes->GetCoord(iPoint, iDim)); + Vector_j[iDim] = 0.5*(geometry->nodes->GetCoord(iPoint, iDim) - geometry->nodes->GetCoord(jPoint, iDim)); + } + + Gradient_i = nodes->GetGradient_Reconstruction(iPoint); + Gradient_j = nodes->GetGradient_Reconstruction(jPoint); + + if (limiter) { + Limiter_i = nodes->GetLimiter_Primitive(iPoint); + Limiter_j = nodes->GetLimiter_Primitive(jPoint); + } + + for (iVar = 0; iVar < nPrimVarGrad; 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) { + if (van_albada){ + Limiter_i[iVar] = (V_j[iVar]-V_i[iVar])*(2.0*Project_Grad_i + V_j[iVar]-V_i[iVar])/(4*Project_Grad_i*Project_Grad_i+(V_j[iVar]-V_i[iVar])*(V_j[iVar]-V_i[iVar])+EPS); + Limiter_j[iVar] = (V_j[iVar]-V_i[iVar])*(-2.0*Project_Grad_j + V_j[iVar]-V_i[iVar])/(4*Project_Grad_j*Project_Grad_j+(V_j[iVar]-V_i[iVar])*(V_j[iVar]-V_i[iVar])+EPS); + } + Primitive_i[iVar] = V_i[iVar] + Limiter_i[iVar]*Project_Grad_i; + Primitive_j[iVar] = V_j[iVar] + Limiter_j[iVar]*Project_Grad_j; + } + else { + Primitive_i[iVar] = V_i[iVar] + Project_Grad_i; + Primitive_j[iVar] = V_j[iVar] + Project_Grad_j; + } + } + + for (iVar = nPrimVarGrad; iVar < nPrimVar; iVar++) { + Primitive_i[iVar] = V_i[iVar]; + Primitive_j[iVar] = V_j[iVar]; + } + numerics->SetPrimitive(Primitive_i, Primitive_j); + } else { + /*--- Set conservative variables without reconstruction ---*/ + numerics->SetPrimitive(V_i, V_j); + numerics->SetSecondary(S_i, S_j); + + } + //numerics->SetFaceVel(FaceVelocity[iEdge]); + + auto residual = numerics->ComputeResidual(config); + + /*--- Update residual value ---*/ + LinSysRes.AddBlock(iPoint, residual); + LinSysRes.SubtractBlock(jPoint, residual); + + + /*--- Set implicit Jacobians ---*/ + if (implicit) + Jacobian.UpdateBlocks(iEdge, iPoint, jPoint, residual.jacobian_i, residual.jacobian_j); + + } + + /*--- Warning message about non-physical reconstructions. ---*/ + + if (config->GetComm_Level() == COMM_FULL) { +#ifdef HAVE_MPI + SU2_MPI::Reduce(&counter_local, &counter_global, 1, MPI_UNSIGNED_LONG, MPI_SUM, MASTER_NODE, MPI_COMM_WORLD); +#else + counter_global = counter_local; +#endif + if (iMesh == MESH_0) config->SetNonphysical_Reconstr(counter_global); + } + +} + + + +void CPBIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, + CConfig *config, unsigned short iMesh) { + + CNumerics* numerics = numerics_container[SOURCE_FIRST_TERM]; + + unsigned short iVar,iDim,jVar,jDim; + unsigned long iEdge, iPoint, jPoint; + + const bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + const bool rotating_frame = config->GetRotating_Frame(); + const bool axisymmetric = config->GetAxisymmetric(); + const bool gravity = (config->GetGravityForce() == YES); + const bool body_force = config->GetBody_Force(); + + su2double **Jacobian_Temp, *Residual_Temp; + + /*--- Add pressure contribution. ---*/ + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Initialize residual to zero. ---*/ + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = 0.0; + + /*--- Assign the pressure gradient to the residual. ---*/ + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = geometry->nodes->GetVolume(iPoint)*nodes->GetGradient_Primitive(iPoint,0,iVar); + + /*--- Add Residual ---*/ + LinSysRes.AddBlock(iPoint, Residual); + } + + /*--- Other source terms for body force, rotation etc ---*/ + if (body_force) { + /*--- Loop over all points ---*/ + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + /*--- Load the conservative variables ---*/ + numerics->SetConservative(nodes->GetSolution(iPoint), + nodes->GetSolution(iPoint)); + /*--- Set incompressible density ---*/ + numerics->SetDensity(nodes->GetDensity(iPoint), + nodes->GetDensity(iPoint)); + /*--- Load the volume of the dual mesh cell ---*/ + numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + /*--- Compute the rotating frame source residual ---*/ + auto residual = numerics->ComputeResidual(config); + /*--- Add the source residual to the total ---*/ + LinSysRes.AddBlock(iPoint, residual); + } + } + + if (rotating_frame) { + + /*--- Loop over all points ---*/ + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Load the primitive variables ---*/ + numerics->SetPrimitive(nodes->GetPrimitive(iPoint), NULL); + + /*--- Set incompressible density ---*/ + numerics->SetDensity(nodes->GetDensity(iPoint), 0.0); + + /*--- Load the volume of the dual mesh cell ---*/ + numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + + /*--- Compute the rotating frame source residual (CSourceIncRotatingFrame_Flow class) ---*/ + auto residual = numerics->ComputeResidual(config); + + /*--- Add the source residual to the total ---*/ + LinSysRes.AddBlock(iPoint, residual); + + /*--- Add the implicit Jacobian contribution ---*/ + if (implicit) Jacobian.AddBlock2Diag(iPoint, residual.jacobian_i); + + } + } + + if (axisymmetric) { + + } +} + +void CPBIncEulerSolver::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { + + su2double *local_Residual, *local_Res_TruncError, Vol, Delta, Res,alfa,Mom_Coeff[3]; + unsigned short iVar, jVar; + unsigned long iPoint; + + for (iVar = 0; iVar < nVar; iVar++) { //TODO: TO be fixed for PBFlow was replaced in preprocess + // SetResidual_RMS(iVar, 0.0); // TODO: PBFlow + Residual_RMS[iVar] = 0.0; // TODO: PBFlow: Updated with current std in the code. + Residual_Max[iVar] = 0.0; + } + alfa = 1.0; + /*--- Update the solution ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + Vol = (geometry->nodes->GetVolume(iPoint) + + geometry->nodes->GetPeriodicVolume(iPoint)); + Delta = nodes->GetDelta_Time(iPoint) / Vol; + + local_Res_TruncError = nodes->GetResTruncError(iPoint); + local_Residual = LinSysRes.GetBlock(iPoint); + + /*--- Workaround to deal with nodes that are part of multiple boundaries and where + * one face might be strong BC and another weak BC (mostly for farfield boundary + * where the boundary face is strong or weak depending on local flux. ---*/ + if (nodes->GetStrongBC(iPoint)) { + LinSysRes.SetBlock_Zero(iPoint); + } + + for (iVar = 0; iVar < nVar; iVar ++ ) { // TODO: PBFlow + Res = local_Residual[iVar] + local_Res_TruncError[iVar]; + nodes->AddSolution(iPoint, iVar, -alfa*Res*Delta); + // AddRes_RMS(iVar, Res*Res); // Old COde + Residual_RMS[iVar] += Res*Res; // TODO: PBFlow: Updated with current std in the code. + AddRes_Max(iVar, fabs(Res), geometry->nodes->GetGlobalIndex(iPoint), geometry->nodes->GetCoord(iPoint)); + + // AddRes_Max(iVar, fabs(Res), geometry->nodes->GetGlobalIndex(iPoint), geometry->nodes->GetCoord(iPoint)); + } + } + SetIterLinSolver(1); + + /*-- Note here that there is an assumption that solution[0] is pressure/density and velocities start from 1 ---*/ + 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 CPBIncEulerSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { + + unsigned short iVar, iDim; + unsigned long iPoint, total_index, IterLinSol = 0; + su2double Delta, *local_Res_TruncError, Vol,Mom_Coeff[3]; + + /*--- Set maximum residual to zero ---*/ + +// for (iVar = 0; iVar < nVar; iVar++) { // TODO: PBFlow + // SetRes_RMS(iVar, 0.0); + SetResToZero(); // TODO: PBFlow: Updated with current std in the code. +// Residual_Max[iVar] = 0.0; +// } + +// config->SetLinear_Solver_Iter(config->GetPoisson_Linear_Solver_Iter()); // TODO:PBFlow + + /*--- Build implicit system ---*/ + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Workaround to deal with nodes that are part of multiple boundaries and where + * one face might be strong BC and another weak BC (mostly for farfield boundary + * where the boundary face is strong or weak depending on local flux. ---*/ + if (nodes->GetStrongBC(iPoint)) { + for (iVar = 0; iVar < nVar; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + LinSysRes.SetBlock_Zero(iPoint); + } + + /*--- Read the volume ---*/ + Vol = (geometry->nodes->GetVolume(iPoint) + + geometry->nodes->GetPeriodicVolume(iPoint)); + + if (nodes->GetDelta_Time(iPoint) != 0.0) { + Delta = Vol / nodes->GetDelta_Time(iPoint); + Jacobian.AddVal2Diag(iPoint, Delta); + } else { + Jacobian.SetVal2Diag(iPoint, 1.0); + for (iVar = 0; iVar < nVar; iVar++) { + total_index = iPoint*nVar + iVar; + LinSysRes[total_index] = 0.0; + local_Res_TruncError[iVar] = 0.0; + } + } + + /*--- Read the residual ---*/ + + local_Res_TruncError = nodes->GetResTruncError(iPoint); + /*--- 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; + Residual_RMS[iVar] += LinSysRes[total_index]*LinSysRes[total_index]; // TODO:PBFlow + AddRes_Max(iVar, fabs(LinSysRes[total_index]), geometry->nodes->GetGlobalIndex(iPoint), geometry->nodes->GetCoord(iPoint)); + } + } + + /*--- 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 ---*/ + IterLinSol = System.Solve(Jacobian, LinSysRes, LinSysSol, geometry, config); + + /*--- Store the value of the residual. ---*/ + SetResLinSolver(System.GetResidual()); + + /*--- The the number of iterations of the linear solver ---*/ + SetIterLinSolver(IterLinSol); + + /*--- Update solution (system written in terms of increments) ---*/ + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (iVar = 0; iVar < nVar; iVar++) { + nodes->AddSolution(iPoint, iVar, config->GetRelaxation_Factor_PBFlow()*LinSysSol[iPoint*nVar+iVar]); + } + } + + /*-- Note here that there is an assumption that solution[0] is pressure/density and velocities start from 1 ---*/ + 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 CPBIncEulerSolver::SetMomCoeff(CGeometry *geometry, CSolver **solver_container, CConfig *config, bool periodic, unsigned short iMesh) { + + unsigned short iVar, jVar, iDim, jDim; + unsigned long iPoint, jPoint, iNeigh; + su2double Mom_Coeff[MAXNDIM], Mom_Coeff_nb[MAXNDIM], Vol, delT; + bool simplec = (config->GetKind_PBIter() == ENUM_PBITER::SIMPLEC); + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + + if (!periodic) { + + if (implicit) { + /* First sum up the momentum coefficient using the jacobian from given point and it's neighbors. ---*/ + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Self contribution. ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + Mom_Coeff[iVar] = Jacobian.GetBlock(iPoint,iPoint,iVar,iVar); + } + + /*--- Contribution from neighbors. ---*/ + nodes->Set_Mom_Coeff_nbZero(iPoint); + + if (simplec) { + for (iNeigh = 0; iNeigh < geometry->nodes->GetnPoint(iPoint); iNeigh++) { + jPoint = geometry->nodes->GetPoint(iPoint,iNeigh); + for (iVar = 0; iVar < nVar; iVar++) { + nodes->Add_Mom_Coeff_nb(iPoint, Jacobian.GetBlock(iPoint,jPoint,iVar,iVar),iVar); + } + } + } + + Vol = geometry->nodes->GetVolume(iPoint); delT = nodes->GetDelta_Time(iPoint); + + for (iVar = 0; iVar < nVar; iVar++) { + Mom_Coeff[iVar] = Mom_Coeff[iVar] - nodes->Get_Mom_Coeff_nb(iPoint, iVar) - config->GetRCFactor()*(Vol/delT); + //Mom_Coeff[iVar] = nodes->GetDensity(iPoint)*Vol/Mom_Coeff[iVar]; + Mom_Coeff[iVar] = Vol/Mom_Coeff[iVar]; + } + + nodes->Set_Mom_Coeff(iPoint, Mom_Coeff); + } + } + else { + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + Vol = geometry->nodes->GetVolume(iPoint); delT = nodes->GetDelta_Time(iPoint); + + for(iVar = 0; iVar < nVar; iVar++) + Mom_Coeff[iVar] = delT/Vol; + + nodes->Set_Mom_Coeff(iPoint, Mom_Coeff); + } + } + /*--- Insert MPI call here. ---*/ + InitiateComms(geometry, config, MOM_COEFF); + CompleteComms(geometry, config, MOM_COEFF); + } + +} + + +void CPBIncEulerSolver::SetMomCoeffPer(CGeometry *geometry, CSolver **solver_container, CConfig *config) { + + unsigned short iVar, jVar, iDim, jDim; + unsigned long iPoint, jPoint, iNeigh; + su2double Mom_Coeff[MAXNDIM], Mom_Coeff_nb[MAXNDIM], Vol, delT; + bool simplec = (config->GetKind_PBIter() == ENUM_PBITER::SIMPLEC); + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Self contribution. ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + Mom_Coeff[iVar] = Jacobian.GetBlock(iPoint,iPoint,iVar,iVar); + } + + /*--- Contribution from neighbors. ---*/ + nodes->Set_Mom_Coeff_nbZero(iPoint); + if (simplec) { + for (iNeigh = 0; iNeigh < geometry->nodes->GetnPoint(iPoint); iNeigh++) { + jPoint = geometry->nodes->GetPoint(iPoint,iNeigh); + for (iVar = 0; iVar < nVar; iVar++) { + nodes->Add_Mom_Coeff_nb(iPoint, Jacobian.GetBlock(iPoint,jPoint,iVar,iVar),iVar); + } + } + } + + Vol = geometry->nodes->GetVolume(iPoint); delT = nodes->GetDelta_Time(iPoint); + + for (iVar = 0; iVar < nVar; iVar++) { + Mom_Coeff[iVar] = Mom_Coeff[iVar] + (1.0 - config->GetRCFactor())*(Vol/delT) - nodes->Get_Mom_Coeff_nb(iPoint, iVar); + //Mom_Coeff[iVar] = nodes->GetDensity(iPoint)*Vol/Mom_Coeff[iVar]; + Mom_Coeff[iVar] = Vol/Mom_Coeff[iVar]; + } + nodes->Set_Mom_Coeff(iPoint, Mom_Coeff); + } + + /*--- Insert MPI call here. ---*/ + InitiateComms(geometry, config, MOM_COEFF); // TODO: PBFlow: FIXED + CompleteComms(geometry, config, MOM_COEFF); // TODO: PBFlow: FIXED + +} + +void CPBIncEulerSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, + unsigned short iMesh, unsigned long Iteration) { + + su2double *Normal, Area, Vol, Length, Mean_ProjVel = 0.0, Mean_Vel, Mean_Density, + Mean_BetaInc2 = 4.1, Lambda, Local_Delta_Time, Mean_DensityInc, GradVel, Lambda1, + Global_Delta_Time = 1E6, Global_Delta_UnstTimeND, ProjVel, RefProjFlux, MinRefProjFlux, ProjVel_i, ProjVel_j; + + unsigned long iEdge, iVertex, iPoint, jPoint; + unsigned short iDim, iMarker, iVar; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool time_steping = config->GetTime_Marching() == TIME_MARCHING::TIME_STEPPING; + bool dual_time = ((config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) || + (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND)); + + Min_Delta_Time = 1.E6; Max_Delta_Time = 0.0; MinRefProjFlux = 0.0; + Normal = new su2double[nDim]; + + /*--- Set maximum inviscid eigenvalue to zero, and compute sound speed ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) + nodes->SetMax_Lambda_Inv(iPoint, 0.0); + + /*--- Loop interior edges ---*/ + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Point identification, Normal vector and area ---*/ + + iPoint = geometry->edges->GetNode(iEdge,0); + jPoint = geometry->edges->GetNode(iEdge,1); + + geometry->edges->GetNormal(iEdge, Normal); + + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + + /*--- Compute flux across the cell ---*/ + + Mean_Density = 0.5*(nodes->GetDensity(iPoint) + nodes->GetDensity(jPoint)); + Mean_ProjVel = 0.0; + for (iVar = 0; iVar < nVar; iVar++) { + Mean_Vel = 0.5*(nodes->GetVelocity(iPoint, iVar) + nodes->GetVelocity(jPoint, iVar)); + Mean_ProjVel += (Mean_Vel*Normal[iVar]); + } + + /*--- Adjustment for grid movement ---*/ + + if (dynamic_grid) { + su2double *GridVel_i = geometry->nodes->GetGridVel(iPoint); + su2double *GridVel_j = geometry->nodes->GetGridVel(jPoint); + ProjVel_i = 0.0; ProjVel_j = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + ProjVel_i += GridVel_i[iDim]*Normal[iDim]; + ProjVel_j += GridVel_j[iDim]*Normal[iDim]; + } + Mean_ProjVel -= 0.5 * (ProjVel_i + ProjVel_j); + } + + RefProjFlux = fabs(config->GetInc_Velocity_Ref()*Area); + MinRefProjFlux = max(RefProjFlux, MinRefProjFlux); + + Lambda = fabs(Mean_ProjVel) + RefProjFlux; + + /*--- Inviscid contribution ---*/ + + if (geometry->nodes->GetDomain(iPoint)) nodes->AddMax_Lambda_Inv(iPoint, Lambda+EPS); + if (geometry->nodes->GetDomain(jPoint)) nodes->AddMax_Lambda_Inv(jPoint, Lambda+EPS); + + } + + /*--- Loop boundary edges ---*/ + + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { + if ((config->GetMarker_All_KindBC(iMarker) != INTERNAL_BOUNDARY) && + (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + + /*--- Point identification, Normal vector and area ---*/ + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + + /*--- Compute flux across the cell ---*/ + Mean_Density = nodes->GetDensity(iPoint); + Mean_ProjVel = 0.0; + for (iVar = 0; iVar < nVar; iVar++) { + Mean_Vel = nodes->GetVelocity(iPoint, iVar); + Mean_ProjVel += Mean_Vel*Normal[iVar]; + } + + /*--- Adjustment for grid movement ---*/ + + if (dynamic_grid) { + su2double *GridVel = geometry->nodes->GetGridVel(iPoint); + ProjVel = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + ProjVel += GridVel[iDim]*Normal[iDim]; + Mean_ProjVel -= ProjVel; + } + + RefProjFlux = fabs(config->GetInc_Velocity_Ref()*Area); + MinRefProjFlux = max(RefProjFlux, MinRefProjFlux); + + Lambda = fabs(Mean_ProjVel) + RefProjFlux; + + if (geometry->nodes->GetDomain(iPoint)) { + nodes->AddMax_Lambda_Inv(iPoint, Lambda+EPS); + } + } + } + } + + /*--- Local time-stepping: each element uses their own speed for steady state + simulations or for pseudo time steps in a dual time simulation. ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + Vol = geometry->nodes->GetVolume(iPoint); + + if (Vol != 0.0) { + Local_Delta_Time = config->GetCFL(iMesh)*Vol/nodes->GetMax_Lambda_Inv(iPoint); + if (!implicit) Local_Delta_Time = 0.5*config->GetCFL(iMesh)*Vol/nodes->GetMax_Lambda_Inv(iPoint); + Global_Delta_Time = min(Global_Delta_Time, Local_Delta_Time); + Min_Delta_Time = min(Min_Delta_Time, Local_Delta_Time); + Max_Delta_Time = max(Max_Delta_Time, Local_Delta_Time); + if (Local_Delta_Time > config->GetMax_DeltaTime()) + Local_Delta_Time = config->GetMax_DeltaTime(); + nodes->SetDelta_Time(iPoint, Local_Delta_Time); + } + else { + nodes->SetDelta_Time(iPoint, 0.0); + } + } + + /*--- Compute the max and the min dt (in parallel) ---*/ + + if (config->GetComm_Level() == COMM_FULL) { +#ifdef HAVE_MPI + su2double rbuf_time, sbuf_time; + sbuf_time = Min_Delta_Time; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Min_Delta_Time = rbuf_time; + + sbuf_time = Max_Delta_Time; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MAX, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Max_Delta_Time = rbuf_time; +#endif + } + + /*--- For time-accurate simulations use the minimum delta time of the whole mesh (global) ---*/ + + if (time_steping) { +#ifdef HAVE_MPI + su2double rbuf_time, sbuf_time; + sbuf_time = Global_Delta_Time; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Global_Delta_Time = rbuf_time; +#endif + for (iPoint = 0; iPoint < nPointDomain; iPoint++){ + + /*--- Sets the regular CFL equal to the unsteady CFL ---*/ + + config->SetCFL(iMesh,config->GetUnst_CFL()); + + /*--- If the unsteady CFL is set to zero, it uses the defined unsteady time step, otherwise + it computes the time step based on the unsteady CFL ---*/ + + if (config->GetCFL(iMesh) == 0.0){ + nodes->SetDelta_Time(iPoint, config->GetDelta_UnstTime()); + } else { + nodes->SetDelta_Time(iPoint, Global_Delta_Time); + } + } + } + + /*--- Recompute the unsteady time step for the dual time strategy + if the unsteady CFL is diferent from 0 ---*/ + + if ((dual_time) && (Iteration == 0) && (config->GetUnst_CFL() != 0.0) && (iMesh == MESH_0)) { + Global_Delta_UnstTimeND = config->GetUnst_CFL()*Global_Delta_Time/config->GetCFL(iMesh); + +#ifdef HAVE_MPI + su2double rbuf_time, sbuf_time; + sbuf_time = Global_Delta_UnstTimeND; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Global_Delta_UnstTimeND = rbuf_time; +#endif + config->SetDelta_UnstTimeND(Global_Delta_UnstTimeND); + } + + /*--- The pseudo local time (explicit integration) cannot be greater than the physical time ---*/ + + if (dual_time) + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + if (!implicit) { + Local_Delta_Time = min((2.0/3.0)*config->GetDelta_UnstTimeND(), nodes->GetDelta_Time(iPoint)); + nodes->SetDelta_Time(iPoint, Local_Delta_Time); + } + } + +} + +void CPBIncEulerSolver::SetPoissonSourceTerm(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh) { + + + unsigned short iVar, jVar, iDim, jDim, KindBC; + unsigned long iPoint, jPoint, iEdge, iMarker, iVertex, iNeigh, n_inlet; + su2double Edge_Vector[MAXNDIM], dist_ij_2; + su2double *Coord_i, *Coord_j; + su2double MassFlux_Part, MassFlux_Avg, Mom_Coeff[MAXNDIM], *Normal,Vel_Avg, Grad_Avg; + su2double Area, MeanDensity, Vol , TimeStep; + su2double GradP_f[MAXNDIM], GradP_in[MAXNDIM], GradP_proj, RhieChowInterp, Coeff_Mom, PsCorr[MAXNDIM], PsCorrFace; + su2double *Flow_Dir, Flow_Dir_Mag, Vel_Mag, Adj_Mass,*GridVel_i,*GridVel_j; + su2double Net_Mass, alfa, Mass_In, Mass_Out, Mass_Free_In, Mass_Free_Out, Mass_Corr, Area_out; + string Marker_Tag; + su2double ProjGridVelFlux, *MeshVel_i, *MeshVel_j; + Normal = new su2double [nDim]; + bool unsteady = (config->GetTime_Marching() != TIME_MARCHING::STEADY); + + /*--- Initialize mass flux to zero ---*/ + for (iPoint = 0; iPoint < nPointDomain; iPoint++) + nodes->SetMassFluxZero(iPoint); + + Net_Mass = 0.0; + + for (iEdge = 0; iEdge < nEdge; iEdge++) { + + iPoint = geometry->edges->GetNode(iEdge,0); jPoint = geometry->edges->GetNode(iEdge,1); + geometry->edges->GetNormal(iEdge, Normal); + + Area = GeometryToolbox::Norm(nDim, Normal); + + MeanDensity = 0.5*(nodes->GetDensity(iPoint) + nodes->GetDensity(jPoint)); + + if (dynamic_grid) { + GridVel_i = geometry->nodes->GetGridVel(iPoint); + GridVel_j = geometry->nodes->GetGridVel(jPoint); + } + + /*--- Face average mass flux. ---*/ + MassFlux_Avg = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Vel_Avg = 0.5*(nodes->GetVelocity(iPoint,iDim) + nodes->GetVelocity(jPoint,iDim)); + MassFlux_Avg += MeanDensity*Vel_Avg*Normal[iDim]; + } + + if (dynamic_grid) + for (iDim = 0; iDim < nDim; iDim++) { + Vel_Avg = 0.5*(GridVel_i[iDim]+GridVel_j[iDim]); + MassFlux_Avg -= MeanDensity*Vel_Avg*Normal[iDim]; + } + + /*--- Rhie Chow interpolation ---*/ + Coord_i = geometry->nodes->GetCoord(iPoint); + Coord_j = geometry->nodes->GetCoord(jPoint); + dist_ij_2 = 0.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]; + } + /*--- 1. Interpolate the pressure gradient based on node values ---*/ + for (iDim = 0; iDim < nDim; iDim++) { + Grad_Avg = 0.5*(nodes->GetGradient_Primitive(iPoint,0,iDim) + nodes->GetGradient_Primitive(jPoint,0,iDim)); + GradP_in[iDim] = Grad_Avg; + } + + /*--- 2. Compute pressure gradient at the face ---* + Eq 15.62 F Moukalled, L Mangani M. Darwish OpenFOAM and uFVM book. ---*/ + GradP_proj = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + GradP_proj += GradP_in[iDim]*Edge_Vector[iDim]; + } + if (dist_ij_2 != 0.0) { + for (iDim = 0; iDim < nDim; iDim++) { + GradP_f[iDim] = GradP_in[iDim] - (GradP_proj - (nodes->GetPressure(jPoint) - nodes->GetPressure(iPoint)))*Edge_Vector[iDim]/ dist_ij_2; + } + } + + /*--- Correct the massflux by adding the pressure terms. + * --- GradP_f is the gradient computed directly at the face and GradP_in is the + * --- gradient linearly interpolated based on node values. This effectively adds a third + * --- order derivative of pressure to remove odd-even decoupling of pressure and velocities. + * --- GradP_f = (p_F^n - p_P^n)/ds , GradP_in = 0.5*(GradP_P^n + GradP_F^n)---*/ + RhieChowInterp = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + /*--- Linearly interpolated coefficient. ---*/ + Coeff_Mom = 0.5*(nodes->Get_Mom_Coeff(iPoint,iDim) + nodes->Get_Mom_Coeff(jPoint,iDim)); + /*--- Difference of pressure gradients. ---*/ + RhieChowInterp += Coeff_Mom*(GradP_f[iDim] - GradP_in[iDim])*Normal[iDim]*MeanDensity; + /*--- Save the pressure gradient contribution for the correction term used in the next iteration. ---*/ + PsCorr[iDim] = -Coeff_Mom*(GradP_f[iDim] - GradP_in[iDim]); + } + + /*--- Rhie Chow correction for time step must go here ---*/ + su2double beta = 0.0, beta_n = 0.0, beta_n1 = 0.0; + su2double den_i,den_j,num_i,num_n_i,num_n1_i,num_j,num_n1_j,num_n_j; + if (unsteady) { + TimeStep = config->GetDelta_UnstTimeND(); + + Vol = 0.5*(geometry->nodes->GetVolume(iPoint) + geometry->nodes->GetVolume(jPoint)); + + for (iDim = 0; iDim < nDim; iDim++) { + den_i = geometry->nodes->GetVolume(iPoint)/nodes->Get_Mom_Coeff(iPoint,iDim); + den_j = geometry->nodes->GetVolume(jPoint)/nodes->Get_Mom_Coeff(jPoint,iDim); + Coeff_Mom = 0.5*(nodes->Get_Mom_Coeff(iPoint,iDim) + nodes->Get_Mom_Coeff(jPoint,iDim)); + } + PsCorrFace = 0.0; + if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) { + for (iDim = 0; iDim < nDim; iDim++) { + // Coefficient of correction for pseudo time iteration + num_i = den_i - geometry->nodes->GetVolume(iPoint)/TimeStep; + num_j = den_j - geometry->nodes->GetVolume(jPoint)/TimeStep; + beta = 0.5*(num_i/den_i + num_j/den_j); + // Coefficient of correction for unsteady time level n + num_n_i = -geometry->nodes->GetVolume(iPoint)/TimeStep; + num_n_j = -geometry->nodes->GetVolume(jPoint)/TimeStep; + beta_n = -0.5*(num_n_i/den_i + num_n_j/den_j); + + PsCorrFace += (beta*PseudoTimeCorr[iEdge][iDim] + beta_n*TimeMarchingCorr_n[iEdge][iDim])*Normal[iDim]*MeanDensity; + } + } + if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) { + for (iDim = 0; iDim < nDim; iDim++) { + // Coefficient of correction for pseudo time iteration + num_i = den_i - 3.0*geometry->nodes->GetVolume(iPoint)/(2.0*TimeStep); + num_j = den_j - 3.0*geometry->nodes->GetVolume(jPoint)/(2.0*TimeStep); + beta = 0.5*(num_i/den_i + num_j/den_j); + // Coefficient of correction for unsteady time level n + num_n_i = -4.0*geometry->nodes->GetVolume(iPoint)/(2.0*TimeStep); + num_n_j = -4.0*geometry->nodes->GetVolume(jPoint)/(2.0*TimeStep); + beta_n = -0.5*(num_n_i/den_i + num_n_j/den_j); + // Coefficient of correction for unsteady time level n-1 + num_n1_i = geometry->nodes->GetVolume(iPoint)/(2.0*TimeStep); + num_n1_j = geometry->nodes->GetVolume(jPoint)/(2.0*TimeStep); + beta_n1 = 0.5*(num_n1_i/den_i + num_n1_j/den_j); + + PsCorrFace += (beta*PseudoTimeCorr[iEdge][iDim] + beta_n*TimeMarchingCorr_n[iEdge][iDim] + beta_n1*TimeMarchingCorr_n1[iEdge][iDim])*Normal[iDim]*MeanDensity; + } + } + } + else { + beta = 1.0; PsCorrFace = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + PsCorrFace += PseudoTimeCorr[iEdge][iDim]*Normal[iDim]*MeanDensity; + PsCorrFace = beta*PsCorrFace; + } + + /*--- Calculate the mass flux at the face including the linearly interpolated velocities, pressure + * gradient difference contribution and correction for time stepping (both pseudo and dual time). ---*/ + MassFlux_Part = MassFlux_Avg - RhieChowInterp + PsCorrFace; + + + /*--- Update correction of face velocity for the next iteration. ---*/ + for (iDim = 0; iDim < nDim; iDim++) + PseudoTimeCorr[iEdge][iDim] = PsCorr[iDim] ;//+ PseudoTimeCorr[iEdge][iDim]; + + if (geometry->nodes->GetDomain(iPoint)) nodes->AddMassFlux(iPoint,MassFlux_Part); + if (geometry->nodes->GetDomain(jPoint)) nodes->SubtractMassFlux(jPoint,MassFlux_Part); + } + + /*--- Mass flux correction for outflow ---*/ + Mass_In = 0.0; Mass_Out = 0.0; Mass_Free_In = 0.0; Mass_Free_Out = 0.0; + Area_out = 0.0; Adj_Mass = 0.0; n_inlet = 0; + /*--- Loop boundary edges ---*/ + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { + KindBC = config->GetMarker_All_KindBC(iMarker); + Marker_Tag = config->GetMarker_All_TagBound(iMarker); + + switch (KindBC) { + /*--- Wall boundaries have zero mass flux (irrespective of grid movement) ---*/ + case EULER_WALL: case ISOTHERMAL: case HEAT_FLUX: case SYMMETRY_PLANE: + break; + + case INLET_FLOW: + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + if (geometry->nodes->GetDomain(iPoint)) { + + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); + + if (dynamic_grid) + GridVel_i = geometry->nodes->GetGridVel(iPoint); + + MassFlux_Part = 0.0; + if (dynamic_grid) + for (iDim = 0; iDim < nDim; iDim++) + MassFlux_Part -= nodes->GetDensity(iPoint)*(nodes->GetVelocity(iPoint, iDim)-GridVel_i[iDim])*Normal[iDim]; + else + for (iDim = 0; iDim < nDim; iDim++) + MassFlux_Part -= nodes->GetDensity(iPoint)*(nodes->GetVelocity(iPoint, iDim))*Normal[iDim]; + + if (geometry->nodes->GetDomain(iPoint)) + nodes->AddMassFlux(iPoint, MassFlux_Part); + + /*--- Sum up the mass flux entering to be used for mass flow correction at outflow ---*/ + Mass_In += fabs(MassFlux_Part); + } + } + break; + + case FAR_FIELD: + /*--- Treat the farfield as a fully developed outlet for pressure. I still compute the mass fluxes + * to use when dealing with truncated open boundaries (not implemented yet). ---*/ + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + if (geometry->nodes->GetDomain(iPoint)) { + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); + + if (dynamic_grid) + GridVel_i = geometry->nodes->GetGridVel(iPoint); + + MassFlux_Part = 0.0; + if (dynamic_grid) + for (iDim = 0; iDim < nDim; iDim++) + MassFlux_Part -= nodes->GetDensity(iPoint)*(nodes->GetVelocity(iPoint, iDim)-GridVel_i[iDim])*Normal[iDim]; + else + for (iDim = 0; iDim < nDim; iDim++) + MassFlux_Part -= nodes->GetDensity(iPoint)*(nodes->GetVelocity(iPoint, iDim))*Normal[iDim]; + + if ((MassFlux_Part < 0.0) && (fabs(MassFlux_Part) > EPS)) { + Mass_Free_In += fabs(MassFlux_Part); + nodes->AddMassFlux(iPoint, MassFlux_Part); + } + else { + Mass_Free_Out += fabs(MassFlux_Part); + nodes->AddMassFlux(iPoint, MassFlux_Part); + } + + nodes->SetMassFluxZero(iPoint); + } + } + break; + + case OUTLET_FLOW:{ + /*--- Note I am assuming a fully developed outlet, thus the pressure value is prescribed + * -- and a dirichlet bc has to be applied along outlet faces. The Massflux, which forms the RHS + * -- of the equation, is set to zero to enforce the dirichlet bc. ---*/ + + auto Kind_Outlet = config->GetKind_Inc_Outlet(Marker_Tag); + + switch (Kind_Outlet) { + case INC_OUTLET_TYPE::PRESSURE_OUTLET: + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + if (geometry->nodes->GetDomain(iPoint)) { + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); + + if (dynamic_grid) + GridVel_i = geometry->nodes->GetGridVel(iPoint); + + MassFlux_Part = 0.0; + if (dynamic_grid) + for (iDim = 0; iDim < nDim; iDim++) + MassFlux_Part -= nodes->GetDensity(iPoint)*(nodes->GetVelocity(iPoint, iDim)-GridVel_i[iDim])*Normal[iDim]; + else + for (iDim = 0; iDim < nDim; iDim++) + MassFlux_Part -= nodes->GetDensity(iPoint)*(nodes->GetVelocity(iPoint, iDim))*Normal[iDim]; + + /*--- Sum up the mass flux leaving to be used for mass flow correction at outflow ---*/ + Mass_Out += fabs(MassFlux_Part); + + nodes->AddMassFlux(iPoint, MassFlux_Part); + } + } + break; + // Not working properly - Also removed the mass flux correction outside the loop which was summing up mass in and out + case INC_OUTLET_TYPE::OPEN: { + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + if (geometry->nodes->GetDomain(iPoint)) { + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); + + MassFlux_Part = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + MassFlux_Part -= nodes->GetDensity(iPoint)*nodes->GetVelocity(iPoint,iDim)*Normal[iDim]; + + /*--- Sum up the mass flux leaving to be used for mass flow correction at outflow ---*/ + if (MassFlux_Part > 0.0) + Mass_Free_Out += fabs(MassFlux_Part); + else + Mass_Free_In += fabs(MassFlux_Part); + } + } + } + break; + } + } + break; + + default:{ + cout<<"Invalid option!"<GetMassFlux(iPoint)*nodes->GetMassFlux(iPoint)); + //cout<GetMassFlux(iPoint)<GetnPoint()); + +#else + + int nProcessor = size, iProcessor; + + su2double sbuf_residual, rbuf_residual; + unsigned long Global_nPointDomain; + unsigned short iDim; + + /*--- Set the L2 Norm residual in all the processors ---*/ + + sbuf_residual = 0.0; + rbuf_residual = 0.0; + + sbuf_residual = GetResMassFlux(); + + if (config->GetComm_Level() == COMM_FULL) { + + unsigned long Local_nPointDomain = geometry->GetnPointDomain(); + SU2_MPI::Allreduce(&sbuf_residual, &rbuf_residual, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&Local_nPointDomain, &Global_nPointDomain, 1, MPI_UNSIGNED_LONG, MPI_SUM, MPI_COMM_WORLD); + + } else { + + /*--- Reduced MPI comms have been requested. Use a local residual only. ---*/ + + rbuf_residual = sbuf_residual; + Global_nPointDomain = geometry->GetnPointDomain(); + + } + + + if (rbuf_residual != rbuf_residual) { + SU2_MPI::Error("SU2 has diverged. (NaN detected)", CURRENT_FUNCTION); + } + + SetResMassFlux(max(EPS*EPS, sqrt(rbuf_residual/Global_nPointDomain))); +#endif + +} + + +void CPBIncEulerSolver:: Flow_Correction(CGeometry *geometry, CSolver **solver_container, CConfig *config) { + + unsigned long iEdge, iPoint, jPoint, iMarker, iVertex; + unsigned short iDim, iVar, KindBC; + su2double Vel, Current_Pressure, factor, PCorr_Ref, Vol, delT, Density; + string Marker_Tag; + su2activevector Pressure_Correc, alpha_p; + su2activematrix vel_corr; + long Pref_local; + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + + /*--- Allocate corrections and relaxation ---*/ + Pressure_Correc.resize(nPointDomain); + vel_corr.resize(nPointDomain,nVar); + alpha_p.resize(nPointDomain); + + /*--- Pressure Corrections ---*/ + for (iPoint = 0; iPoint < nPointDomain; iPoint++) + Pressure_Correc[iPoint] = solver_container[POISSON_SOL]->GetNodes()->GetSolution(iPoint,0); + + Pref_local = geometry->GetGlobal_to_Local_Point(PRef_Point); + PCorr_Ref = 0.0; + if (Pref_local >= 0) + if(geometry->nodes->GetDomain(Pref_local)) + PCorr_Ref = 0.0;//Pressure_Correc[Pref_local]; + + /*--- Velocity Corrections. ---*/ + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + factor = 0.0; + Vol = geometry->nodes->GetVolume(iPoint); + delT = nodes->GetDelta_Time(iPoint); + for (iVar = 0; iVar < nVar; iVar++) { + vel_corr[iPoint][iVar] = nodes->Get_Mom_Coeff(iPoint,iVar)*(solver_container[POISSON_SOL]->GetNodes()->GetGradient(iPoint,0,iVar)); + if (implicit) factor += Jacobian.GetBlock(iPoint, iPoint, iVar, iVar); + } + if (implicit) + alpha_p[iPoint] = config->GetRelaxation_Factor_PBFlow()*(Vol/delT) / (factor+(Vol/delT)); + else + alpha_p[iPoint] = config->GetRelaxation_Factor_PBFlow(); + } + + /*--- Reassign strong boundary conditions ---*/ + /*--- For now I only have velocity inlet and fully developed outlet. Will need to add other types of inlet/outlet conditions + * where different treatment of pressure might be needed. Symmetry and Euler wall are weak BCs. ---*/ + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { + KindBC = config->GetMarker_All_KindBC(iMarker); + Marker_Tag = config->GetMarker_All_TagBound(iMarker); + switch (KindBC) { + /*--- Only a fully developed outlet is implemented. For pressure, a dirichlet + BC has to be applied and no correction is necessary. Velocity has a neumann BC. ---*/ + case OUTLET_FLOW:{ + auto Kind_Outlet = config->GetKind_Inc_Outlet(Marker_Tag); + switch (Kind_Outlet) { + case INC_OUTLET_TYPE::PRESSURE_OUTLET:{ + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + if (geometry->nodes->GetDomain(iPoint)) + Pressure_Correc[iPoint] = PCorr_Ref; + } + break; + } + // Not working yet + case INC_OUTLET_TYPE::OPEN:{ + break; + } + } + break; + } + + /*--- Only a fixed velocity inlet is implemented now. Along with the wall boundaries, + * the velocity is known and thus no correction is necessary.---*/ + case ISOTHERMAL: case HEAT_FLUX: case INLET_FLOW: { + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + if (geometry->nodes->GetDomain(iPoint)) { + for (iDim = 0; iDim < nDim; iDim++) + vel_corr[iPoint][iDim] = 0.0; + alpha_p[iPoint] = 1.0; + } + } + break; + } + + /*--- Farfield is treated as a fully developed flow for pressure and a fixed pressure is + * used, thus no correction is necessary. The treatment for velocity depends on whether the + * flow is into the domain or out. If flow is in, a dirichlet bc is applied and no correction + * is made, otherwise a Neumann BC is used and velocity is adjusted. The fixed value of velocity + * is the one from the previous iteration. ---*/ + + case FAR_FIELD:{ + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + if (geometry->nodes->GetDomain(iPoint)) { + // Check if inlet or not + if (nodes->GetStrongBC(iPoint)) { + for (iDim = 0; iDim < nDim; iDim++) + vel_corr[iPoint][iDim] = 0.0; + } + Pressure_Correc[iPoint] = PCorr_Ref; + } + } + break; + } + default:{ + break; + } + } + } + + /*--- Velocity corrections ---*/ + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (iVar = 0; iVar < nVar; iVar++) { + Vel = nodes->GetVelocity(iPoint,iVar); + Vel = Vel - vel_corr[iPoint][iVar]; + Density = nodes->GetDensity(iPoint); + nodes->SetSolution(iPoint,iVar,Density*Vel); + } + nodes->SetVelocity(iPoint); + /*--- Pressure corrections ---*/ + Current_Pressure = nodes->GetPressure(iPoint); + Current_Pressure += alpha_p[iPoint]*(Pressure_Correc[iPoint] - PCorr_Ref); + nodes->SetPressure_val(iPoint,Current_Pressure); + } + + /*--- Correct face velocity. ---*/ + /*su2double Area, Vel_Mag,rho, GradP_in[MAXNDIM],GradP_f[MAXNDIM], GradP_proj; + su2double *Coord_i, *Coord_j, dist_ij, delP, Pressure_j, Pressure_i; + su2double Edge_Vector[MAXNDIM], dist_ij_2, proj_vector_ij; + for (iEdge = 0; iEdge < nEdge; iEdge++) { + + iPoint = geometry->edges->GetNode(iEdge,0); jPoint = geometry->edges->GetNode(iEdge,1); + geometry->edges->GetNormal(iEdge, Normal); + dist_ij_2 = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Edge_Vector[iDim] = (geometry->nodes->GetCoord(jPoint, iDim) - + geometry->nodes->GetCoord(iPoint, iDim)); + dist_ij_2 += Edge_Vector[iDim]*Edge_Vector[iDim]; + } + + for (iDim = 0; iDim < nDim; iDim++) + GradP_in[iDim] = ( solver_container[POISSON_SOL]->GetNodes()->GetGradient(iPoint,0,iDim) + + solver_container[POISSON_SOL]->GetNodes()->GetGradient(jPoint,0,iDim) ); + + GradP_proj = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + GradP_proj += GradP_in[iDim]*Edge_Vector[iDim]; + } + if (dist_ij_2 != 0.0) { + for (iDim = 0; iDim < nDim; iDim++) { + GradP_f[iDim] = GradP_in[iDim] - (GradP_proj - (Pressure_Correc[jPoint] - Pressure_Correc[iPoint]))*Edge_Vector[iDim]/ dist_ij_2; + } + } + + for (iDim =0; iDim < nDim; iDim++) { + Coeff_Mom = 0.5*(nodes->Get_Mom_Coeff(iPoint,iDim) + nodes->Get_Mom_Coeff(jPoint,iDim)); + FaceVelocity[iEdge][iDim] = FaceVelocity[iEdge][iDim] - Coeff_Mom*(GradP_f[iDim]); + } + }*/ + + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { + InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); + CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); + + InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_PRESSURE); + CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_PRESSURE); + } + + /*--- Communicate updated velocities and pressure ---*/ + InitiateComms(geometry, config, SOLUTION); + CompleteComms(geometry, config, SOLUTION); + + InitiateComms(geometry, config, PRESSURE_VAR); + CompleteComms(geometry, config, PRESSURE_VAR); + + /*--- Reset pressure corrections to zero for next iteration. ---*/ + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + solver_container[POISSON_SOL]->GetNodes()->SetSolution(iPoint,0,0.0); + } + + /*--- Communicate updated Poisson solution ---*/ + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { + solver_container[POISSON_SOL]->InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); + solver_container[POISSON_SOL]->CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_IMPLICIT); + } + + solver_container[POISSON_SOL]->InitiateComms(geometry, config, SOLUTION); + solver_container[POISSON_SOL]->CompleteComms(geometry, config, SOLUTION); + +} + + +void CPBIncEulerSolver::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 *GridVel_i = nullptr, *GridVel_j = nullptr, Residual_GCL; + const su2double* Normal; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + + /*--- Store the physical time step ---*/ + + TimeStep = config->GetDelta_UnstTimeND(); + + /*--- Compute the dual time-stepping source term for static meshes ---*/ + + if (!dynamic_grid) { + + /*--- Loop over all nodes (excluding halos) ---*/ + + for (iPoint = 0; iPoint < nPoint; iPoint++) { + + /*--- Initialize the Residual / Jacobian container to zero. ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Residual[iVar] = 0.0; + if (implicit) { + for (jVar = 0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = 0.0; + } + } + + /*--- 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->nodes->GetVolume(iPoint); + + /*--- Compute the dual time-stepping source term based on the chosen + time discretization scheme (1st- or 2nd-order). ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) + Residual[iVar] = (U_time_nP1[iVar] - U_time_n[iVar])*Volume_nP1 / TimeStep; + if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) + Residual[iVar] = ( 3.0*U_time_nP1[iVar] - 4.0*U_time_n[iVar] + +1.0*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++) { + if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) + Jacobian_i[iVar][iVar] = Volume_nP1 / TimeStep; + if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) + Jacobian_i[iVar][iVar] = (Volume_nP1*3.0)/(2.0*TimeStep); + } + Jacobian.AddBlock2Diag(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++) { + + /*--- Initialize the Residual / Jacobian container to zero. ---*/ + + for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; + + /*--- Get indices for nodes i & j plus the face normal ---*/ + + iPoint = geometry->edges->GetNode(iEdge,0); + jPoint = geometry->edges->GetNode(iEdge,1); + Normal = geometry->edges->GetNormal(iEdge); + + /*--- Grid velocities stored at nodes i & j ---*/ + + GridVel_i = geometry->nodes->GetGridVel(iPoint); + GridVel_j = geometry->nodes->GetGridVel(jPoint); + + /*--- 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); + + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = 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); + + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = 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) && + (config->GetMarker_All_KindBC(iMarker) != PERIODIC_BOUNDARY)) { + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + + /*--- Initialize the Residual / Jacobian container to zero. ---*/ + + for (iVar = 0; iVar < nVar; iVar++) Residual[iVar] = 0.0; + + /*--- 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->nodes->GetGridVel(iPoint); + + /*--- 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); + + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = 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++) { + + /*--- Initialize the Residual / Jacobian container to zero. ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Residual[iVar] = 0.0; + if (implicit) { + for (jVar = 0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = 0.0; + } + } + + /*--- 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->nodes->GetVolume_nM1(iPoint); + Volume_nP1 = geometry->nodes->GetVolume(iPoint); + + /*--- Compute the dual time-stepping source residual. Due to the + introduction of the GCL term above, the remainder of the source residual + due to the time discretization has a new form.---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) + Residual[iVar] = (U_time_nP1[iVar] - U_time_n[iVar])*(Volume_nP1/TimeStep); + if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) + Residual[iVar] = (U_time_nP1[iVar] - U_time_n[iVar])*(3.0*Volume_nP1/(2.0*TimeStep)) + + (U_time_nM1[iVar] - 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) { + for (iVar = 0; iVar < nVar; iVar++) { + if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) + Jacobian_i[iVar][iVar] = Volume_nP1 / TimeStep; + if (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) + Jacobian_i[iVar][iVar] = (Volume_nP1*3.0)/(2.0*TimeStep); + } + Jacobian.AddBlock2Diag(iPoint, Jacobian_i); + } + } + } +} + +void CPBIncEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, + CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + unsigned short iDim, jDim, iVar; + unsigned long iVertex, iPoint, Point_Normal, total_index; + + su2double *V_infty, *V_domain; + su2double Face_Flux, Flux0, Flux1, MeanDensity, proj_vel; + su2double *Coord_i, *Coord_j, dist_ij, delP, Pressure_j, Pressure_i; + bool implicit = config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT; + bool viscous = config->GetViscous(); + bool inflow = false; + + su2double *Normal = new su2double[nDim]; + auto turb_model = config->GetKind_Turb_Model(); + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + su2double *GridVel_i; + + /*--- 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->nodes->GetDomain(iPoint)) { + + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + for (iDim = 0; iDim < nDim; iDim++) + Normal[iDim] = -Normal[iDim]; + conv_numerics->SetNormal(Normal); + + /*--- Retrieve solution at the farfield boundary node ---*/ + V_domain = nodes->GetPrimitive(iPoint); + + /*--- Set farfield soultion. ---*/ + V_infty = GetCharacPrimVar(val_marker, iVertex); + V_infty[0] = GetPressure_Inf(); + for (iDim = 0; iDim < nDim; iDim++) + V_infty[iDim+1] = GetVelocity_Inf(iDim); + V_infty[nDim+1] = nodes->GetDensity(iPoint); + + if (dynamic_grid) { + GridVel_i = geometry->nodes->GetGridVel(iPoint); + conv_numerics->SetGridVel(GridVel_i,GridVel_i); + } + + Face_Flux = 0.0; + if (dynamic_grid) + for (iDim = 0; iDim < nDim; iDim++) + Face_Flux += nodes->GetDensity(iPoint)*(V_domain[iDim+1]-GridVel_i[iDim])*Normal[iDim]; + else + for (iDim = 0; iDim < nDim; iDim++) + Face_Flux += nodes->GetDensity(iPoint)*V_domain[iDim+1]*Normal[iDim]; + + inflow = false; + if ((Face_Flux < 0.0) && (fabs(Face_Flux) > EPS)) inflow = true; + + if (inflow) { + + /*--- Set this face as an inlet. ---*/ + LinSysRes.SetBlock_Zero(iPoint); + + nodes->SetStrongBC(iPoint); + + if (implicit) { + for (iDim = 0; iDim < nDim; iDim++) { + total_index = iPoint*nVar+iDim; + Jacobian.DeleteValsRowi(total_index); + } + } + } + else { + + if (dynamic_grid) + conv_numerics->SetGridVel(geometry->nodes->GetGridVel(iPoint), geometry->nodes->GetGridVel(iPoint)); + /*--- Compute the residual using an upwind scheme ---*/ + + conv_numerics->SetPrimitive(V_domain, V_domain); + auto residual = conv_numerics->ComputeResidual(config); + + LinSysRes.AddBlock(iPoint, residual); + nodes->SetPressure_val(iPoint,GetPressure_Inf()); + + if (implicit) + Jacobian.AddBlock2Diag(iPoint, residual.jacobian_i); + } + + /*--- Set transport properties at the outlet (used by turb solver also). ---*/ + if (viscous) { + V_domain[nDim+2] = nodes->GetLaminarViscosity(iPoint); + V_domain[nDim+3] = nodes->GetEddyViscosity(iPoint); + V_infty[nDim+2] = nodes->GetLaminarViscosity(iPoint); + V_infty[nDim+3] = nodes->GetEddyViscosity(iPoint); + } + if (viscous && !inflow) { + + /*--- Set the normal vector and the coordinates ---*/ + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); + + visc_numerics->SetNormal(Normal); + visc_numerics->SetCoord(geometry->nodes->GetCoord(iPoint), + geometry->nodes->GetCoord(Point_Normal)); + + /*--- Primitive variables, and gradient ---*/ + visc_numerics->SetPrimitive(V_domain, V_domain); + visc_numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), + nodes->GetGradient_Primitive(iPoint)); + + /*--- Turbulent kinetic energy ---*/ + if (turb_model == TURB_MODEL::SST) + visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), + solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0)); + + /*--- Compute and update residual ---*/ + auto residual = visc_numerics->ComputeResidual(config); + + LinSysRes.SubtractBlock(iPoint, residual); + + /*--- Jacobian contribution for implicit integration ---*/ + if (implicit) + Jacobian.SubtractBlock2Diag(iPoint, residual.jacobian_i); + } + } + } + + /*--- Free locally allocated memory ---*/ + delete [] Normal; +} + + +void CPBIncEulerSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, + CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + unsigned short iDim, iVar, jDim; + unsigned long iVertex, iPoint,total_index, Point_Normal; + su2double *Flow_Dir, Vel_Mag, Area, Flow_Dir_Mag; + su2double UnitFlowDir[3] = {0.0,0.0,0.0}; + su2double Face_Flux, proj_vel; + su2double *V_inlet = new su2double[nDim]; + su2double *V_Charac; + su2double *V_domain; + su2double *Coord_i, *Coord_j, dist_ij, delP, Pressure_j, Pressure_i; + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool viscous = config->GetViscous(); + + su2double *Normal = new su2double[nDim]; + su2double *val_normal = new su2double[nDim]; + su2double *GridVel_i; + + /*--- 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->nodes->GetDomain(iPoint)) { + + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + + /*--- Retrieve solution at the farfield boundary node ---*/ + + V_domain = nodes->GetPrimitive(iPoint); + + /*--- Retrieve the specified velocity for the inlet. ---*/ + + Vel_Mag = Inlet_Ptotal[val_marker][iVertex]/config->GetVelocity_Ref(); + + Flow_Dir = Inlet_FlowDir[val_marker][iVertex]; + Flow_Dir_Mag = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Flow_Dir_Mag += Flow_Dir[iDim]*Flow_Dir[iDim]; + Flow_Dir_Mag = sqrt(Flow_Dir_Mag); + + /*--- Store the unit flow direction vector. ---*/ + + for (iDim = 0; iDim < nDim; iDim++) + UnitFlowDir[iDim] = Flow_Dir[iDim]/Flow_Dir_Mag; + + /*--- Store the velocity in the primitive variable vector. ---*/ + + for (iDim = 0; iDim < nDim; iDim++) + V_inlet[iDim] = Vel_Mag*UnitFlowDir[iDim]; + + /*--- Adding the grid velocity because SetVelocityOld sets the solution which is U = U_rel + U_grid. ---*/ + /*if (dynamic_grid) { + GridVel_i = geometry->nodes->GetGridVel(iPoint); + for (iDim = 0; iDim < nDim; iDim++) + V_inlet[iDim] += GridVel_i[iDim]; + }*/ + + /*--- Update the CharacPrimVar for this vertex on inlet marker. ---*/ + /*--- This is necessary for the turbulent solver. ---*/ + V_Charac = GetCharacPrimVar(val_marker, iVertex); + + V_Charac[0] = nodes->GetPressure(iPoint); + for (iDim = 0; iDim < nDim; iDim++) + V_Charac[iDim+1] = V_domain[iDim]; + V_Charac[nDim+1] = nodes->GetDensity(iPoint); + + if (viscous) { + V_Charac[nDim+2] = nodes->GetLaminarViscosity(iPoint); + V_Charac[nDim+3] = nodes->GetEddyViscosity(iPoint); + } + + /*--- Impose the value of the velocity as a strong boundary condition (Dirichlet). + * Fix the velocity and remove any contribution to the residual at this node. + * Note that SetVelocityOld sets the solution which needs to be multiplied by rho. ---*/ + + nodes->SetVelocity_Old(iPoint,V_inlet); + + nodes->SetStrongBC(iPoint); + + LinSysRes.SetBlock_Zero(iPoint); + /*--- Jacobian contribution for implicit integration ---*/ + if (implicit) { + for (iDim = 0; iDim < nDim; iDim++) { + total_index = iPoint*nVar+iDim; + Jacobian.DeleteValsRowi(total_index); + } + } + } + } + + /*--- Free locally allocated memory ---*/ + + delete [] Normal; + delete [] V_inlet; + delete [] val_normal; + +} + +void CPBIncEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, + CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + unsigned short iDim,iVar,jDim; + unsigned long iVertex, iPoint, Point_Normal, total_index; + su2double Area, yCoordRef, yCoord,proj_vel; + su2double *V_outlet, *V_domain, P_Outlet, Face_Flux, Flux0; + su2double *Coord_i, *Coord_j, dist_ij, delP, Pressure_j, Pressure_i; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool viscous = config->GetViscous(); + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + su2double *Normal = new su2double[nDim]; + auto Kind_Outlet = config->GetKind_Inc_Outlet(Marker_Tag); + auto turb_model = config->GetKind_Turb_Model(); + su2double *GridVel_j = 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->nodes->GetDomain(iPoint)) { + + /*--- Normal vector for this vertex (negate for outward convention) ---*/ + + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + + Area = GeometryToolbox::Norm(nDim, Normal); + for (iDim = 0; iDim < nDim; iDim++) Normal[iDim] = -Normal[iDim]; + conv_numerics->SetNormal(Normal); + + /*--- Current solution at this boundary node ---*/ + + V_domain = nodes->GetPrimitive(iPoint); + + V_outlet = GetCharacPrimVar(val_marker, iVertex); + + for (iDim = 0; iDim < nDim; iDim++) GridVel_j[iDim] = 0.0; + if (dynamic_grid) + conv_numerics->SetGridVel(geometry->nodes->GetGridVel(iPoint), GridVel_j); + + switch (Kind_Outlet) { + case INC_OUTLET_TYPE::PRESSURE_OUTLET: { + + /*--- Retrieve the specified back pressure for this outlet. ---*/ + P_Outlet = config->GetOutlet_Pressure(Marker_Tag)/config->GetPressure_Ref(); + + nodes->SetPressure_val(iPoint, P_Outlet); + V_outlet[0] = P_Outlet; + for (iDim = 0; iDim < nDim; iDim++) + V_outlet[iDim+1] = 0.0; + V_outlet[nDim+1] = nodes->GetDensity(iPoint); + + conv_numerics->SetPrimitive(V_domain, V_outlet); + + /*--- Compute the residual using an upwind scheme ---*/ + + auto residual = conv_numerics->ComputeResidual(config); + + for (iVar = 0; iVar < nVar; iVar++) { + Residual[iVar] = 2.0*residual.residual[iVar]; + } + + for (iDim = 0; iDim < nDim; iDim++) + for (jDim = 0; jDim < nDim; jDim++) + Jacobian_i[iDim][jDim] = 2.0*residual.jacobian_i[iDim][jDim]; + + /*--- Update residual value ---*/ + LinSysRes.AddBlock(iPoint, Residual); + + if (implicit) + Jacobian.AddBlock2Diag(iPoint, Jacobian_i); + + for (iDim = 0; iDim < nDim; iDim++) + V_outlet[iDim+1] = V_domain[iDim+1]; + + break; + } + + case INC_OUTLET_TYPE::OPEN: + /* Not working yet */ + + break; + } + + if (viscous) { + /*--- Set transport properties at the outlet. ---*/ + V_domain[nDim+2] = nodes->GetLaminarViscosity(iPoint); + V_domain[nDim+3] = nodes->GetEddyViscosity(iPoint); + V_outlet[nDim+2] = nodes->GetLaminarViscosity(iPoint); + V_outlet[nDim+3] = nodes->GetEddyViscosity(iPoint); + + /*--- Set the normal vector and the coordinates ---*/ + Point_Normal = geometry->vertex[val_marker][iVertex]->GetNormal_Neighbor(); + visc_numerics->SetNormal(Normal); + visc_numerics->SetCoord(geometry->nodes->GetCoord(iPoint), + geometry->nodes->GetCoord(Point_Normal)); + + /*--- Primitive variables, and gradient ---*/ + visc_numerics->SetPrimitive(V_domain, V_outlet); + visc_numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), + nodes->GetGradient_Primitive(iPoint)); + + /*--- Turbulent kinetic energy ---*/ + if (turb_model == TURB_MODEL::SST) + visc_numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), + solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0)); + + /*--- Compute and update residual ---*/ + auto residual = visc_numerics->ComputeResidual(config); + + LinSysRes.SubtractBlock(iPoint, residual); + + /*--- Jacobian contribution for implicit integration ---*/ + if (implicit) + Jacobian.SubtractBlock2Diag(iPoint, residual.jacobian_i); + } + } + } + + /*--- Free locally allocated memory ---*/ + delete [] Normal; + delete [] GridVel_j; + +} + +/*--- Note that velocity indices in residual are hard coded in solver_structure. Need to be careful. ---*/ +// TODO: PBFlow: Already initialized in FVMFlowSolverBase +void CPBIncEulerSolver::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 correctly during the communications. For implicit calculations, + the Jacobians and linear system are also correctly adjusted here. ---*/ + + SetMomCoeffPer(geometry, solver_container, config); + + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { + InitiatePeriodicComms(geometry, config, iPeriodic, PERIODIC_RESIDUAL); + CompletePeriodicComms(geometry, config, iPeriodic, PERIODIC_RESIDUAL); + } +} + +void CPBIncEulerSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, + CConfig *config, unsigned short iMesh) { } + + +void CPBIncEulerSolver::PrintVerificationError(const CConfig *config) const { } diff --git a/SU2_CFD/src/solvers/CPBIncNSSolver.cpp b/SU2_CFD/src/solvers/CPBIncNSSolver.cpp new file mode 100644 index 000000000000..01d7a2162614 --- /dev/null +++ b/SU2_CFD/src/solvers/CPBIncNSSolver.cpp @@ -0,0 +1,562 @@ +/*! + * \file CPBIncNSSolver.cpp + * \brief Main subroutines for solving Navier-Stokes incompressible flow. + * \author F. Palacios, T. Economon + * \version 8.0.0 "Harrier" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2020, SU2 Contributors (cf. AUTHORS.md) + * + * 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/CPBIncNSSolver.hpp" +#include "../../include/variables/CPBIncNSVariable.hpp" +#include "../../../Common/include/toolboxes/printing_toolbox.hpp" +#include "../../include/solvers/CFVMFlowSolverBase.inl" + + +CPBIncNSSolver::CPBIncNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) : CPBIncEulerSolver(geometry, config, iMesh, true) { + + + Viscosity_Inf = config->GetViscosity_FreeStreamND(); + Tke_Inf = config->GetTke_FreeStreamND(); + +} + +void CPBIncNSSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { + +unsigned long iPoint, ErrorCounter = 0; + su2double StrainMag = 0.0, Omega = 0.0, *Vorticity; + + unsigned long InnerIter = config->GetInnerIter(); + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool limiter_flow = (config->GetKind_SlopeLimit_Flow() != LIMITER::NONE) && (InnerIter <= config->GetLimiterIter()); + bool limiter_turb = (config->GetKind_SlopeLimit_Turb() != LIMITER::NONE) && (InnerIter <= config->GetLimiterIter()); + bool van_albada = config->GetKind_SlopeLimit_Flow() == LIMITER::VAN_ALBADA_EDGE; + bool outlet = ((config->GetnMarker_Outlet() != 0)); + + /*--- Set the primitive variables ---*/ + + ErrorCounter = SetPrimitive_Variables(solver_container, config, Output); + + /*--- Compute gradient for MUSCL reconstruction. ---*/ + + if (config->GetReconstructionGradientRequired() && (iMesh == MESH_0)) { + if (config->GetKind_Gradient_Method_Recon() == GREEN_GAUSS) + SetPrimitive_Gradient_GG(geometry, config, true); + if (config->GetKind_Gradient_Method_Recon() == LEAST_SQUARES) + SetPrimitive_Gradient_LS(geometry, config, true); + if (config->GetKind_Gradient_Method_Recon() == WEIGHTED_LEAST_SQUARES) + SetPrimitive_Gradient_LS(geometry, config, true); + } + + /*--- Compute gradient of the primitive variables ---*/ + + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { + SetPrimitive_Gradient_GG(geometry, config, false); + } + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + SetPrimitive_Gradient_LS(geometry, config, false); + } + + /*--- Compute the limiter in case we need it in the turbulence model + or to limit the viscous terms (check this logic with JST and 2nd order turbulence model) ---*/ + + if ((iMesh == MESH_0) && (limiter_flow || limiter_turb ) + && !Output && !van_albada) { SetPrimitive_Limiter(geometry, config); } + + /*--- Evaluate the vorticity and strain rate magnitude ---*/ + + solver_container[FLOW_SOL]->GetNodes()->SetVorticity_StrainMag(); // TODO:PBFlow + + StrainMag_Max = 0.0; Omega_Max = 0.0; + for (iPoint = 0; iPoint < nPoint; iPoint++) { + + StrainMag = solver_container[FLOW_SOL]->GetNodes()->GetStrainMag(iPoint); + Vorticity = solver_container[FLOW_SOL]->GetNodes()->GetVorticity(iPoint); + Omega = sqrt(Vorticity[0]*Vorticity[0]+ Vorticity[1]*Vorticity[1]+ Vorticity[2]*Vorticity[2]); + + StrainMag_Max = max(StrainMag_Max, StrainMag); + Omega_Max = max(Omega_Max, Omega); + + nodes->ResetStrongBC(iPoint); + + } + + /*--- Initialize the Jacobian matrices ---*/ + + if (implicit ) Jacobian.SetValZero(); + + /*--- Error message ---*/ + if (config->GetComm_Level() == COMM_FULL) { + +#ifdef HAVE_MPI + unsigned long MyErrorCounter = ErrorCounter; ErrorCounter = 0; + su2double MyOmega_Max = Omega_Max; Omega_Max = 0.0; + su2double MyStrainMag_Max = StrainMag_Max; StrainMag_Max = 0.0; + + SU2_MPI::Allreduce(&MyErrorCounter, &ErrorCounter, 1, MPI_UNSIGNED_LONG, MPI_SUM, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyStrainMag_Max, &StrainMag_Max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); + SU2_MPI::Allreduce(&MyOmega_Max, &Omega_Max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); +#endif + + if (iMesh == MESH_0) + config->SetNonphysical_Points(ErrorCounter); + + } + + SetResMassFluxZero(); + +} + + +unsigned long CPBIncNSSolver::SetPrimitive_Variables(CSolver **solver_container, CConfig *config, bool Output) { + + unsigned long iPoint, nonPhysicalPoints = 0; + su2double eddy_visc = 0.0, turb_ke = 0.0, DES_LengthScale = 0.0; + auto turb_model = config->GetKind_Turb_Model(); + bool physical = true; + + bool tkeNeeded = (turb_model == TURB_MODEL::SST); + + for (iPoint = 0; iPoint < nPoint; iPoint++) { + + /*--- Retrieve the value of the kinetic energy (if needed) ---*/ + + if (turb_model != TURB_MODEL::NONE && solver_container[TURB_SOL] != nullptr) { + eddy_visc = solver_container[TURB_SOL]->GetNodes()->GetmuT(iPoint); + if (tkeNeeded) turb_ke = solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0); + + if (config->GetKind_HybridRANSLES() != NO_HYBRIDRANSLES){ + DES_LengthScale = solver_container[TURB_SOL]->GetNodes()->GetDES_LengthScale(iPoint); + } + } + + /*--- Incompressible flow, primitive variables --- */ + + physical = static_cast(nodes)->SetPrimVar(iPoint,Density_Inf, Viscosity_Inf, eddy_visc, turb_ke, config); + + /* Check for non-realizable states for reporting. */ + + if (!physical) nonPhysicalPoints++; + + /*--- Initialize the convective, source and viscous residual vector ---*/ + + if (!Output) LinSysRes.SetBlock_Zero(iPoint); + + } + + return nonPhysicalPoints; + + +} + +void CPBIncNSSolver::Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, + unsigned short iMesh) { + +bool RightSol = true; +unsigned long iPoint, ErrorCounter = 0; + + /*--- Set the current estimate of velocity as a primitive variable, needed for momentum interpolation. + * -- This does not change the pressure, it remains the same as the old value .i.e. previous (pseudo)time step. ---*/ + if (iMesh == MESH_0) ErrorCounter = SetPrimitive_Variables(solver_container, config, true); + + /*--- Compute gradients to be used in Rhie Chow interpolation ---*/ + + /*--- Gradient computation ---*/ + + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { + SetPrimitive_Gradient_GG(geometry, config); + } + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + SetPrimitive_Gradient_LS(geometry, config); + } + + /*--- Evaluate the vorticity and strain rate magnitude ---*/ + + solver_container[FLOW_SOL]->GetNodes()->SetVorticity_StrainMag(); +} + + +void CPBIncNSSolver::Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, + CConfig *config, unsigned short iMesh, unsigned short iRKStep) { + + CNumerics* numerics = numerics_container[VISC_TERM]; + + unsigned long iPoint, jPoint, iEdge; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + auto turb_model = config->GetKind_Turb_Model(); + bool print = false; + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Points, coordinates and normal vector in edge ---*/ + + iPoint = geometry->edges->GetNode(iEdge,0); + jPoint = geometry->edges->GetNode(iEdge,1); + numerics->SetCoord(geometry->nodes->GetCoord(iPoint), + geometry->nodes->GetCoord(jPoint)); + numerics->SetNormal(geometry->edges->GetNormal(iEdge)); + + /*--- Primitive and secondary variables ---*/ + + numerics->SetPrimitive(nodes->GetPrimitive(iPoint), + nodes->GetPrimitive(jPoint)); + + /*--- Gradient and limiters ---*/ + + numerics->SetPrimVarGradient(nodes->GetGradient_Primitive(iPoint), + nodes->GetGradient_Primitive(jPoint)); + + /*--- Turbulent kinetic energy ---*/ + + if (config->GetKind_Turb_Model() == TURB_MODEL::SST) + numerics->SetTurbKineticEnergy(solver_container[TURB_SOL]->GetNodes()->GetSolution(iPoint,0), + solver_container[TURB_SOL]->GetNodes()->GetSolution(jPoint,0)); + + /*--- Compute and update residual ---*/ + + auto residual = numerics->ComputeResidual(config); + + LinSysRes.SubtractBlock(iPoint, residual); + LinSysRes.AddBlock(jPoint, residual); + + /*--- Implicit part ---*/ + + if (implicit) { + Jacobian.UpdateBlocksSub(iEdge, iPoint, jPoint, residual.jacobian_i, residual.jacobian_j); + } + + } +} + + + +void CPBIncNSSolver::SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, + unsigned short iMesh, unsigned long Iteration) { + + su2double *Normal, Area, Vol, Length, Mean_ProjVel = 0.0, Mean_Vel, Mean_Density, + Mean_BetaInc2 = 4.1, Lambda, Local_Delta_Time, Mean_DensityInc, GradVel, Lambda1, + Mean_LaminarVisc, Mean_EddyVisc, Local_Delta_Time_Visc, K_v = 0.25, ProjVel_i, ProjVel_j, + Global_Delta_Time = 1E6, Global_Delta_UnstTimeND, ProjVel, RefProjFlux, MinRefProjFlux; + + unsigned long iEdge, iVertex, iPoint, jPoint; + unsigned short iDim, iMarker, iVar; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool grid_movement = config->GetGrid_Movement(); + bool time_steping = config->GetTime_Marching() == TIME_MARCHING::TIME_STEPPING; + bool dual_time = ((config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) || + (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND)); + + Min_Delta_Time = 1.E6; Max_Delta_Time = 0.0; MinRefProjFlux = 0.0; + + Normal = new su2double [nDim]; + + /*--- Set maximum inviscid eigenvalue to zero, and compute sound speed ---*/ + + for (iPoint = 0; iPoint < nPointDomain; iPoint++){ + nodes->SetMax_Lambda_Inv(iPoint,0.0); + nodes->SetMax_Lambda_Visc(iPoint, 0.0); + } + + /*--- Loop interior edges ---*/ + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + + /*--- Point identification, Normal vector and area ---*/ + + iPoint = geometry->edges->GetNode(iEdge,0); + jPoint = geometry->edges->GetNode(iEdge,1); + + geometry->edges->GetNormal(iEdge,Normal); + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + + /*--- Compute flux across the cell ---*/ + + Mean_Density = 0.5*(nodes->GetDensity(iPoint) + nodes->GetDensity(jPoint)); + Mean_ProjVel = 0.0; + for (iVar = 0; iVar < nVar; iVar++) { + Mean_Vel = 0.5*(nodes->GetVelocity(iPoint, iVar) + nodes->GetVelocity(jPoint,iVar)); + Mean_ProjVel += Mean_Vel*Normal[iVar]; + } + RefProjFlux = fabs(config->GetInc_Velocity_Ref()*Area); + MinRefProjFlux = max(RefProjFlux, MinRefProjFlux); + + /*--- Adjustment for grid movement ---*/ + + if (dynamic_grid) { + su2double *GridVel_i = geometry->nodes->GetGridVel(iPoint); + su2double *GridVel_j = geometry->nodes->GetGridVel(jPoint); + ProjVel_i = 0.0; ProjVel_j =0.0; + for (iDim = 0; iDim < nDim; iDim++) { + ProjVel_i += GridVel_i[iDim]*Normal[iDim]; + ProjVel_j += GridVel_j[iDim]*Normal[iDim]; + } + Mean_ProjVel -= 0.5 * (ProjVel_i + ProjVel_j); + } + + Lambda = fabs(Mean_ProjVel) + fabs(RefProjFlux); + + /*--- Inviscid contribution ---*/ + + if (geometry->nodes->GetDomain(iPoint)) nodes->AddMax_Lambda_Inv(iPoint,Lambda+EPS); + if (geometry->nodes->GetDomain(jPoint)) nodes->AddMax_Lambda_Inv(jPoint,Lambda+EPS); + + + /*--- Viscous contribution ---*/ + + Mean_LaminarVisc = 0.5*(nodes->GetLaminarViscosity(iPoint) + nodes->GetLaminarViscosity(jPoint)); + Mean_EddyVisc = 0.5*(nodes->GetEddyViscosity(iPoint) + nodes->GetEddyViscosity(jPoint)); + Mean_Density = 0.5*(nodes->GetDensity(iPoint) + nodes->GetDensity(jPoint)); + + Lambda = (4.0/3.0)*(Mean_LaminarVisc + Mean_EddyVisc)*Area*Area/Mean_Density; + + if (geometry->nodes->GetDomain(iPoint)) nodes->AddMax_Lambda_Visc(iPoint,Lambda); + if (geometry->nodes->GetDomain(jPoint)) nodes->AddMax_Lambda_Visc(jPoint,Lambda); + + } + + /*--- Loop boundary edges ---*/ + + for (iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++) { + for (iVertex = 0; iVertex < geometry->GetnVertex(iMarker); iVertex++) { + + /*--- Point identification, Normal vector and area ---*/ + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) Area += Normal[iDim]*Normal[iDim]; + Area = sqrt(Area); + + /*--- Compute flux across the cell ---*/ + Mean_Density = nodes->GetDensity(iPoint); + Mean_ProjVel = 0.0; + for (iVar = 0; iVar < nVar; iVar++) { + Mean_Vel = nodes->GetVelocity(iPoint,iVar); + Mean_ProjVel += Mean_Vel*Normal[iVar]; + } + RefProjFlux = fabs(config->GetInc_Velocity_Ref()*Area); + + MinRefProjFlux = max(RefProjFlux, MinRefProjFlux); + + /*--- Adjustment for grid movement ---*/ + + if (dynamic_grid) { + su2double *GridVel = geometry->nodes->GetGridVel(iPoint); + ProjVel = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + ProjVel += GridVel[iDim]*Normal[iDim]; + Mean_ProjVel -= ProjVel; + } + + Lambda = fabs(Mean_ProjVel) + fabs(RefProjFlux); + + if (geometry->nodes->GetDomain(iPoint)) { + nodes->AddMax_Lambda_Inv(iPoint,Lambda+EPS); + } + + /*--- Viscous contribution ---*/ + + Mean_LaminarVisc = nodes->GetLaminarViscosity(iPoint); + Mean_EddyVisc = nodes->GetEddyViscosity(iPoint); + Mean_Density = nodes->GetDensity(iPoint); + + Lambda = (4.0/3.0)*(Mean_LaminarVisc + Mean_EddyVisc)*Area*Area/Mean_Density; + + if (geometry->nodes->GetDomain(iPoint)) nodes->AddMax_Lambda_Visc(iPoint,Lambda); + } + } + + /*--- Each element uses their own speed, steady state simulation ---*/ + + + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + Vol = geometry->nodes->GetVolume(iPoint); + + if (Vol != 0.0) { + Local_Delta_Time = config->GetCFL(iMesh)*Vol / nodes->GetMax_Lambda_Inv(iPoint); + Local_Delta_Time_Visc = config->GetCFL(iMesh)*K_v*Vol*Vol/ nodes->GetMax_Lambda_Visc(iPoint); + Local_Delta_Time = min(Local_Delta_Time, Local_Delta_Time_Visc); + Global_Delta_Time = min(Global_Delta_Time, Local_Delta_Time); + Min_Delta_Time = min(Min_Delta_Time, Local_Delta_Time); + Max_Delta_Time = max(Max_Delta_Time, Local_Delta_Time); + if (Local_Delta_Time > config->GetMax_DeltaTime()) + Local_Delta_Time = config->GetMax_DeltaTime(); + nodes->SetDelta_Time(iPoint, Local_Delta_Time); + } + else { + nodes->SetDelta_Time(iPoint, 0.0); + } + } + + /*--- Compute the max and the min dt (in parallel) ---*/ + if (config->GetComm_Level() == COMM_FULL) { +#ifdef HAVE_MPI + su2double rbuf_time, sbuf_time; + sbuf_time = Min_Delta_Time; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Min_Delta_Time = rbuf_time; + + sbuf_time = Max_Delta_Time; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MAX, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Max_Delta_Time = rbuf_time; +#endif + } + + /*--- For exact time solution use the minimum delta time of the whole mesh ---*/ + if (config->GetTime_Marching() == TIME_MARCHING::TIME_STEPPING) { +#ifdef HAVE_MPI + su2double rbuf_time, sbuf_time; + sbuf_time = Global_Delta_Time; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Global_Delta_Time = rbuf_time; +#endif + for (iPoint = 0; iPoint < nPointDomain; iPoint++) + nodes->SetDelta_Time(iPoint, Global_Delta_Time); + } + + /*--- Recompute the unsteady time step for the dual time strategy + if the unsteady CFL is diferent from 0 ---*/ + if ((dual_time) && (Iteration == 0) && (config->GetUnst_CFL() != 0.0) && (iMesh == MESH_0)) { + Global_Delta_UnstTimeND = config->GetUnst_CFL()*Global_Delta_Time/config->GetCFL(iMesh); + +#ifdef HAVE_MPI + su2double rbuf_time, sbuf_time; + sbuf_time = Global_Delta_UnstTimeND; + SU2_MPI::Reduce(&sbuf_time, &rbuf_time, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, MPI_COMM_WORLD); + SU2_MPI::Bcast(&rbuf_time, 1, MPI_DOUBLE, MASTER_NODE, MPI_COMM_WORLD); + Global_Delta_UnstTimeND = rbuf_time; +#endif + config->SetDelta_UnstTimeND(Global_Delta_UnstTimeND); + } + + /*--- The pseudo local time (explicit integration) cannot be greater than the physical time ---*/ + if (dual_time) + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + if (!implicit) { + Local_Delta_Time = min((2.0/3.0)*config->GetDelta_UnstTimeND(), nodes->GetDelta_Time(iPoint)); + nodes->SetDelta_Time(iPoint, Local_Delta_Time); + } + } + + delete [] Normal; +} + +void CPBIncNSSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker){ + + + unsigned short iDim, iVar, jVar;// Wall_Function; + unsigned long iVertex, iPoint, total_index, Point_Normal; + + su2double *GridVel, *Normal, Area, Wall_HeatFlux; + su2double *Coord_i, *Coord_j, dist_ij, delP, Pressure_j, Pressure_i; + + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + Normal = new su2double [nDim]; + /*--- Identify the boundary by string name ---*/ + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + + /*--- Loop over all of 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->nodes->GetDomain(iPoint)) { + + /*--- Compute dual-grid area and boundary normal ---*/ + + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + Area += Normal[iDim]*Normal[iDim]; + Area = sqrt (Area); + + /*--- Initialize the convective & viscous residuals to zero ---*/ + + for (iVar = 0; iVar < nVar; iVar++) { + Res_Conv[iVar] = 0.0; + Res_Visc[iVar] = 0.0; + if (implicit) { + for (jVar = 0; jVar < nVar; jVar++) + Jacobian_i[iVar][jVar] = 0.0; + } + } + + /*--- Store the corrected velocity at the wall which will + be zero (v = 0), unless there are moving walls (v = u_wall)---*/ + + if (dynamic_grid) { + GridVel = geometry->nodes->GetGridVel(iPoint); + for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = GridVel[iDim]; + } else { + for (iDim = 0; iDim < nDim; iDim++) Vector[iDim] = 0.0; + } + + /*--- Impose the value of the velocity as a strong boundary + condition (Dirichlet). Fix the velocity and remove any + contribution to the residual at this node. ---*/ + + nodes->SetVelocity_Old(iPoint, Vector); + + /*for (iDim = 0; iDim < nDim; iDim++) + LinSysRes.SetBlock_Zero(iPoint, iDim);*/ + LinSysRes.SetBlock_Zero(iPoint); + + nodes->SetStrongBC(iPoint); + + /*--- Enforce the no-slip boundary condition in a strong way by + modifying the velocity-rows of the Jacobian (1 on the diagonal). ---*/ + + if (implicit) { + for (iVar = 0; iVar < nDim; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + } + } + } + + delete [] Normal; +} + + + +void CPBIncNSSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker){ + + + /*--- No energy equation => Both adiabatic and isothermal walls become the usual no-slip boundary. ---*/ + BC_HeatFlux_Wall(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); + +} diff --git a/SU2_CFD/src/solvers/CPoissonSolverFVM.cpp b/SU2_CFD/src/solvers/CPoissonSolverFVM.cpp new file mode 100644 index 000000000000..32228fe540ac --- /dev/null +++ b/SU2_CFD/src/solvers/CPoissonSolverFVM.cpp @@ -0,0 +1,586 @@ +/*! + * \file solution_direct_poisson.cpp + * \brief Main subrotuines for solving direct problems + * \author F. Palacios + * \version 8.0.0 "Harrier" + * + * 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/CPoissonSolverFVM.hpp" +#include "../../../Common/include/toolboxes/printing_toolbox.hpp" +#include "../../include/gradients/computeGradientsGreenGauss.hpp" +#include "../../include/gradients/computeGradientsLeastSquares.hpp" +#include "../../include/limiters/computeLimiters.hpp" + +CPoissonSolverFVM::CPoissonSolverFVM(void) : CSolver() { } + +CPoissonSolverFVM::CPoissonSolverFVM(CGeometry *geometry, CConfig *config) : CSolver() { + + unsigned long iPoint; + unsigned short iVar, iDim; + + int rank = MASTER_NODE; +#ifdef HAVE_MPI + MPI_Comm_rank(MPI_COMM_WORLD, &rank); +#endif + + nDim = geometry->GetnDim(); + nPoint = geometry->GetnPoint(); + nPointDomain = geometry->GetnPointDomain(); + nVar = 1; + nPrimVar = 1; + + /*--- Initialize nVarGrad for deallocation ---*/ + + nVarGrad = nVar; + +Residual_RMS.resize(nVar,0.0); // TODO: Added PBFlow + Residual_Max.resize(nVar,0.0); + + Residual = new su2double[nVar]; +// Residual_RMS = new su2double[nVar]; + Solution = new su2double[nVar]; +// Residual_Max = new su2double[nVar]; + + + /*--- Define some structures for locating max residuals ---*/ +// nVertex.resize(nMarker); +// for (iMarker = 0; iMarker < nMarker; iMarker++) +// nVertex[iMarker] = geometry->nVertex[iMarker]; + Point_Max.resize(nVar,0.0); +// for (iVar = 0; iVar < nVar; iVar++) Point_Max[iVar] = 0; + Point_Max_Coord.resize(nVar, nDim) = su2double(0.0); +// for (iVar = 0; iVar < nVar; iVar++) { +// Point_Max_Coord[iVar].resize(nDim,0.0); +// // for (iDim = 0; iDim < nDim; iDim++) Point_Max_Coord[iVar][iDim] = 0.0; +// } + + /*--- Define some auxiliar vector related with the solution ---*/ + + Solution_i = new su2double[nVar]; Solution_j = new su2double[nVar]; + + if (config->GetKind_TimeIntScheme() == EULER_IMPLICIT) { // TODO:PBFlow + 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 (Poisson equation)." << endl; + Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config); + } + /*--- Solution and residual vectors ---*/ + + LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); + LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); + + /*--- Computation of gradients by least squares ---*/ + + + /*--- Always instantiate and initialize the variable to a zero value. ---*/ + + nodes = new CPoissonVariable(0.0, nPoint, nDim, nVar, config); + SetBaseClassPointerToNodes(); + + /*--- The poisson equation always solved implicitly, so set the + implicit flag in case we have periodic BCs. Geometry info is + communicated in the flow solver. ---*/ + + SetImplicitPeriodic(true); + + /*--- Perform the MPI communication of the solution ---*/ + + InitiateComms(geometry, config, SOLUTION); + CompleteComms(geometry, config, SOLUTION); + +} + +CPoissonSolverFVM::~CPoissonSolverFVM(void) { + + if (nodes != nullptr) delete nodes; +} + + +void CPoissonSolverFVM::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, + CConfig *config, unsigned short iMesh) { +} + + +void CPoissonSolverFVM::Preprocessing(CGeometry *geometry, CSolver **solver_container, + CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { + unsigned long iPoint; + /*--- Initialize the residual vector ---*/ + for (iPoint = 0; iPoint < nPoint; iPoint ++) + LinSysRes.SetBlock_Zero(iPoint); + + /*--- Initialize the Jacobian matrices ---*/ + Jacobian.SetValZero(); + + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) + SetSolution_Gradient_GG(geometry, config,false); + + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) + SetSolution_Gradient_LS(geometry, config,false); +} + +void CPoissonSolverFVM::Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, + unsigned short iMesh){ + + /*--- Compute gradients so we can use it to find the velocity corrections ---*/ + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) + SetSolution_Gradient_GG(geometry, config,false); + + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) + SetSolution_Gradient_LS(geometry, config,false); +} + +void CPoissonSolverFVM:: LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo){ + +} + +void CPoissonSolverFVM::Viscous_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, + CConfig *config, unsigned short iMesh, unsigned short iRKStep) { + + CNumerics* numerics = numerics_container[VISC_TERM]; + + CMatrixView Sol_i_Grad,Sol_j_Grad; + su2double Poisson_Coeff_i,Poisson_Coeff_j,Poissonval_i,Poissonval_j,Normal[MAXNDIM]; + su2double Mom_Coeff_i[MAXNDIM],Mom_Coeff_j[MAXNDIM]; + unsigned long iEdge, iPoint, jPoint; + unsigned short iDim; + bool implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + + for (iEdge = 0; iEdge < geometry->GetnEdge(); iEdge++) { + iPoint = geometry->edges->GetNode(iEdge,0); + jPoint = geometry->edges->GetNode(iEdge,1); + + /*--- Points coordinates, and normal vector ---*/ + numerics->SetCoord(geometry->nodes->GetCoord(iPoint),geometry->nodes->GetCoord(jPoint)); //TODO:PB_Flow + numerics->SetNormal(geometry->edges->GetNormal(iEdge)); + + numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + numerics->SetVolume(geometry->nodes->GetVolume(jPoint)); + + /*--- Primitive variables w/o reconstruction ---*/ + Poissonval_i = nodes->GetSolution(iPoint, 0); + Poissonval_j = nodes->GetSolution(jPoint, 0); + + numerics->SetPoissonval(Poissonval_i,Poissonval_j); + + Sol_i_Grad = nodes->GetGradient(iPoint); + Sol_j_Grad = nodes->GetGradient(jPoint); + + numerics->SetConsVarGradient(Sol_i_Grad, Sol_j_Grad); + + if (config->GetKind_Incomp_System()!=ENUM_INCOMP_SYSTEM::PRESSURE_BASED) { + for (iDim = 0; iDim < nDim; iDim++) { + Mom_Coeff_i[iDim] = 1.0; + Mom_Coeff_j[iDim] = 1.0; + } + } else { + for (iDim = 0; iDim < nDim; iDim++) { + Mom_Coeff_i[iDim] = solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint)*solver_container[FLOW_SOL]->GetNodes()->Get_Mom_Coeff(iPoint, iDim) ; + Mom_Coeff_j[iDim] = solver_container[FLOW_SOL]->GetNodes()->GetDensity(jPoint)*solver_container[FLOW_SOL]->GetNodes()->Get_Mom_Coeff(jPoint, iDim) ; + } + } + numerics->SetInvMomCoeff(Mom_Coeff_i,Mom_Coeff_j); + + /*--- Compute and update residual ---*/ + auto residual = numerics->ComputeResidual(config); + + LinSysRes.SubtractBlock(iPoint, residual); + LinSysRes.AddBlock(jPoint, residual); + + /*--- Implicit part ---*/ + if (implicit) + Jacobian.UpdateBlocksSub(iEdge, iPoint, jPoint, residual.jacobian_i, residual.jacobian_j); + } +} + +void CPoissonSolverFVM::Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, + CConfig *config, unsigned short iMesh) { + CNumerics* numerics = numerics_container[SOURCE_FIRST_TERM]; + + unsigned short iVar; + unsigned long iPoint; + su2double Src_Term; + + /*--- Initialize the source residual to zero ---*/ + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = 0.0; + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Load the volume of the dual mesh cell ---*/ + numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + + /*--- Compute the source term ---*/ + if ((config->GetKind_Incomp_System() == ENUM_INCOMP_SYSTEM::PRESSURE_BASED)) { + Src_Term = solver_container[FLOW_SOL]->GetNodes()->GetMassFlux(iPoint) ; + if (Src_Term != Src_Term)Src_Term = 0.0; + nodes->SetSourceTerm(iPoint, Src_Term); + } + numerics->SetSourcePoisson(nodes->GetSourceTerm(iPoint)); + + /*--- Compute the source residual ---*/ + numerics->ComputeResidual(Residual, Jacobian_i, config); + + /*--- Add the source residual to the total ---*/ + LinSysRes.AddBlock(iPoint, Residual); + + /*--- No jacobian contribution from mass flux/constant source term. ---*/ + } +} + +void CPoissonSolverFVM::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { + + /*--- No time integration is done here. The routine is used as a means to solve the jacobian matrix in a way + * consistent with the rest of the code. Time step is set to zero and no under-relaxation is applied to the + * jacobian matrix.*/ + + unsigned long iPoint, total_index, IterLinSol = 0;; + unsigned short iVar; + su2double *local_Residual, *local_Res_TruncError, Vol, Delta, Res; + + /*--- Set max linear solver iter which can be different from flow iterations ---*/ +// config->SetLinear_Solver_Iter(config->GetLinear_Solver_Iter_Poisson()); //TODO:PBFlow +// SetLinear_Solver_Iter(config->GetLinear_Solver_Iter()); + + /*--- Set maximum residual to zero ---*/ //TODO:Already done before PBFlow +// for (iVar = 0; iVar < nVar; iVar++) { + // Residual_RMS[iVar] = 0.0; +// SetResidual_RMS(geometry, config); +// } + + SetResToZero(); + + /*--- Initialize residual and solution at the ghost points ---*/ + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { +/*--- Workaround to deal with nodes that are part of multiple boundaries and where + * one face might be strong BC and another weak BC (mostly for farfield boundary + * where the boundary face is strong or weak depending on local flux. ---*/ + if (nodes->GetStrongBC(iPoint)) { + for (iVar = 0; iVar < nVar; iVar++) { + total_index = iPoint*nVar+iVar; + Jacobian.DeleteValsRowi(total_index); + } + LinSysRes.SetBlock_Zero(iPoint); + } + + /*--- Read the residual ---*/ + local_Res_TruncError = nodes->GetResTruncError(iPoint); + + /*--- Read the volume ---*/ + Vol = geometry->nodes->GetVolume(iPoint); + + /*--- Possible under-relaxation if needed goes here. ---*/ + /*--- Currently, nothing changes. ---*/ + /*su2double *diag = Jacobian.GetBlock(iPoint, iPoint); + for (iVar = 0; iVar < nVar; iVar++) + diag[(nVar+1)*iVar] = diag[(nVar+1)*iVar]/1.0; + + Jacobian.SetBlock(iPoint, iPoint, diag);*/ + + /*--- 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; + Residual_RMS[iVar] += LinSysRes[total_index]*LinSysRes[total_index]; + AddRes_Max(iVar, fabs(LinSysRes[total_index]), geometry->nodes->GetGlobalIndex(iPoint), geometry->nodes->GetCoord(iPoint)); + } + } + + /*--- 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 ---*/ + IterLinSol = System.Solve(Jacobian, LinSysRes, LinSysSol, geometry, config); + + /*--- Store the value of the residual. ---*/ + SetResLinSolver(System.GetResidual()); + + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (iVar = 0; iVar < nVar; iVar++) { + nodes->AddSolution(iPoint, iVar, LinSysSol[iPoint*nVar+iVar]); + } + } + + 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 CPoissonSolverFVM::ExplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_container, CConfig *config) { + + + +} + +void CPoissonSolverFVM::SetTime_Step(CGeometry *geometry, CSolver **solver_container, CConfig *config, + unsigned short iMesh, unsigned long Iteration){ + + /*--- Set a value for periodic communication routines. Is not used during any computations. + * Done in the constructor---*/ +} + +void CPoissonSolverFVM::BC_Far_Field(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, + CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + unsigned long iVertex, iPoint; + unsigned short iDim, iVar; + + 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->nodes->GetDomain(iPoint)) { + /*--- The farfield boundary is considered as an inlet-outlet boundary, where flow + * can either enter or leave. For pressure, it is treated as a fully developed flow + * and a dirichlet BC is applied. For velocity, based on the sign of massflux, either + * a dirichlet or a neumann BC is applied (in Flow_Correction routine). ---*/ + + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = 0.0; + + LinSysRes.SetBlock_Zero(iPoint); + + nodes->SetSolution(iPoint, Residual); + nodes->SetSolution_Old(iPoint,Residual); + nodes->SetStrongBC(iPoint); + if (config->GetKind_TimeIntScheme() == EULER_IMPLICIT) { // TODO: PBFlow + Jacobian.DeleteValsRowi(iPoint); + } + } + } +} + + + +void CPoissonSolverFVM::BC_Euler_Wall(CGeometry *geometry, CSolver **solver_container, + CNumerics *numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { +unsigned long iVertex, iPoint, Point_Normal; +unsigned short iVar; + + 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->nodes->GetDomain(iPoint)) { + /*--- Zero flux (Neumann) BC on pressure ---*/ + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = 0.0; + + /*--- Add and subtract residual, and update Jacobians ---*/ + LinSysRes.SubtractBlock(iPoint, Residual); + if (config->GetKind_TimeIntScheme() == EULER_IMPLICIT) { // TODO: PBFlow + Jacobian_i[0][0] = 0.0; + Jacobian.SubtractBlock2Diag(iPoint, Jacobian_i); + } + } + } +} + + +void CPoissonSolverFVM::BC_Inlet(CGeometry *geometry, CSolver **solver_container, + CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + +unsigned long iVertex, iPoint; +unsigned short iVar; + + /*--- Only fixed velocity inlet is considered ---*/ + 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->nodes->GetDomain(iPoint)) { + /*--- Zero flux (Neumann) BC on pressure ---*/ + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = 0.0; + + /*--- Add and subtract residual, and update Jacobians ---*/ + LinSysRes.SubtractBlock(iPoint, Residual); + + if (config->GetKind_TimeIntScheme() == EULER_IMPLICIT) { // TODO: PBFlow + Jacobian_i[0][0] = 0.0; + Jacobian.SubtractBlock2Diag(iPoint, Jacobian_i); + } + } + } +} + + +void CPoissonSolverFVM::BC_Outlet(CGeometry *geometry, CSolver **solver_container, + CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + unsigned long iVertex, iPoint; + unsigned short iDim, iVar; + su2double MassFlux_Part, Normal[MAXNDIM]; + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + auto Kind_Outlet = config->GetKind_Inc_Outlet(Marker_Tag); + + /*--- Only fully developed case is considered ---*/ + 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->nodes->GetDomain(iPoint)) { + + /*--- A Dirichlet BC is applied at the fully developed outlet, pressure is + * assumed to be uniform and assigned the value of P_ref. ---*/ + for (iVar = 0; iVar < nVar; iVar++) + Residual[iVar] = 0.0; + + switch (Kind_Outlet) { + case INC_OUTLET_TYPE::PRESSURE_OUTLET: + LinSysRes.SetBlock_Zero(iPoint); + nodes->SetSolution(iPoint, Residual); + nodes->SetSolution_Old(iPoint, Residual); + nodes->SetStrongBC(iPoint); + if (config->GetKind_TimeIntScheme() == EULER_IMPLICIT) // TODO: PBFlow + Jacobian.DeleteValsRowi(iPoint); + break; + + case INC_OUTLET_TYPE::OPEN: + /*--- Normal vector for this vertex (negative for outward convention) ---*/ + geometry->vertex[val_marker][iVertex]->GetNormal(Normal); + MassFlux_Part = 0.0; + for (iDim = 0; iDim < nDim; iDim++) + MassFlux_Part -= solver_container[FLOW_SOL]->GetNodes()->GetDensity(iPoint)*(solver_container[FLOW_SOL]->GetNodes()->GetVelocity(iPoint, iDim))*Normal[iDim]; + + LinSysRes.SubtractBlock(iPoint, Residual); + if (config->GetKind_TimeIntScheme() == EULER_IMPLICIT) { // TODO:PBFlow + Jacobian_i[0][0] = 0.0; + Jacobian.SubtractBlock2Diag(iPoint, Jacobian_i); + } + break; + } + } + } + +} + + +void CPoissonSolverFVM::BC_Sym_Plane(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, + CConfig *config, unsigned short val_marker) { + + unsigned long iVertex, iPoint; + unsigned short iVar; + + 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->nodes->GetDomain(iPoint)) { + + /*--- Zero flux (Neumann) BC on pressure ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + Residual[iVar] = 0.0; + } + + /*--- Add and subtract residual, and update Jacobians ---*/ + LinSysRes.SubtractBlock(iPoint, Residual); + + if (config->GetKind_TimeIntScheme() == EULER_IMPLICIT) { // TODO: PBFlow + Jacobian_i[0][0] = 0.0; + Jacobian.SubtractBlock2Diag(iPoint, Jacobian_i); + } + } + } +} + + +void CPoissonSolverFVM::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + +unsigned long iVertex, iPoint, jPoint, total_index; +unsigned short iVar; + + 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->nodes->GetDomain(iPoint)) { + + /*--- Zero flux (Neumann) BC on pressure ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + Residual[iVar] = 0.0; + } + + /*--- Add and subtract residual, and update Jacobians ---*/ + LinSysRes.SubtractBlock(iPoint, Residual); + + if (config->GetKind_TimeIntScheme() == EULER_IMPLICIT) { // TODO: PBFlow + Jacobian_i[0][0] = 0.0; + Jacobian.SubtractBlock2Diag(iPoint, Jacobian_i); + } + } + } +} + + +/*--- Note that velocity indices in residual are hard coded in solver_structure. Need to be careful. ---*/ + +void CPoissonSolverFVM::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 correctly 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); + } + +} diff --git a/SU2_CFD/src/variables/CPBIncEulerVariable.cpp b/SU2_CFD/src/variables/CPBIncEulerVariable.cpp new file mode 100644 index 000000000000..93960fe48fce --- /dev/null +++ b/SU2_CFD/src/variables/CPBIncEulerVariable.cpp @@ -0,0 +1,199 @@ +/*! + * \file variable_direct_mean_inc.cpp + * \brief Definition of the variable classes for incompressible flow. + * \author F. Palacios, T. Economon + * \version 8.0.0 "Harrier" + * + * 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/CPBIncEulerVariable.hpp" +#include + +CPBIncEulerVariable::CPBIncEulerVariable(su2double density, su2double pressure, const su2double *velocity, unsigned long nPoint, + unsigned long ndim, unsigned long nvar, CConfig *config) : CVariable(nPoint, ndim, nvar, config), + Gradient_Reconstruction(config->GetReconstructionGradientRequired() ? Gradient_Aux : Gradient_Primitive) { + + bool dual_time = (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) || + (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND); + bool viscous = config->GetViscous(); + bool axisymmetric = config->GetAxisymmetric(); + + /*--- Allocate and initialize the primitive variables and gradients ---*/ + + nPrimVar = nDim+4; nPrimVarGrad = nDim+2; + + /*--- Allocate residual structures ---*/ + + Res_TruncError.resize(nPoint,nVar) = su2double(0.0); + + /*--- Only for residual smoothing (multigrid) ---*/ + + for (unsigned long iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { + if (config->GetMG_CorrecSmooth(iMesh) > 0) { + Residual_Sum.resize(nPoint,nVar); + Residual_Old.resize(nPoint,nVar); + break; + } + } + + /*--- Allocate undivided laplacian (centered) and limiter (upwind)---*/ + + if (config->GetKind_ConvNumScheme_Flow() == SPACE_CENTERED) + Undivided_Laplacian.resize(nPoint,nVar); + + /*--- Always allocate the slope limiter, + and the auxiliar variables (check the logic - JST with 2nd order Turb model - ) ---*/ + + Limiter_Primitive.resize(nPoint,nPrimVarGrad) = su2double(0.0); + + Limiter.resize(nPoint,nVar) = su2double(0.0); + + Solution_Max.resize(nPoint,nPrimVarGrad) = su2double(0.0); + Solution_Min.resize(nPoint,nPrimVarGrad) = su2double(0.0); + + /*--- Solution initialization ---*/ + for(unsigned long iPoint=0; iPointGetReconstructionGradientRequired()) { + Gradient_Aux.resize(nPoint,nPrimVarGrad,nDim,0.0); + } + + if (config->GetLeastSquaresRequired()) { + Rmatrix.resize(nPoint,nDim,nDim,0.0); + } + + /*--- If axisymmetric and viscous, we need an auxiliary gradient. ---*/ + + if (axisymmetric && viscous) Grad_AuxVar.resize(nPoint,nAuxVar,nDim, 0.0); + + Velocity2.resize(nPoint) = su2double(0.0); + Max_Lambda_Inv.resize(nPoint) = su2double(0.0); + Delta_Time.resize(nPoint) = su2double(0.0); + + /* Under-relaxation parameter. */ + UnderRelaxation.resize(nPoint) = su2double(1.0); + LocalCFL.resize(nPoint) = su2double(0.0); + + /* Non-physical point (first-order) initialization. */ + Non_Physical.resize(nPoint) = false; + Non_Physical_Counter.resize(nPoint) = 0; + + /*--- Store coefficients of momentum equation ---*/ + Mom_Coeff.resize(nPoint, nDim) = su2double(0.0); + Mom_Coeff_nb.resize(nPoint, nDim) = su2double(0.0); + + /*--- Strong BC flag ---*/ + strong_bc.resize(nPoint) = false; + + MassFlux.resize(nPoint) = su2double(0.0); +} + +bool CPBIncEulerVariable::SetPrimVar(unsigned long iPoint, su2double Density_Inf, CConfig *config) { + + unsigned long iVar; + bool check_dens = false, physical = true; + + /*--- Set the value of the density ---*/ + + check_dens = SetDensity(iPoint, Density_Inf); + + /*--- Set the value of the velocity and velocity^2 (requires density) ---*/ + + SetVelocity(iPoint); + + return physical; + +} + +CPoissonVariable::CPoissonVariable(su2double val_SourceTerm, unsigned long nPoint, + unsigned short val_nDim, unsigned short val_nVar, + CConfig *config) : CVariable(nPoint, val_nDim, + val_nVar, + config) { + unsigned short iVar,iMesh ,nMGSmooth = 0; + + /*--- Allocate residual structures ---*/ + + Res_TruncError.resize(nPoint,nVar) = su2double(0.0); + + /*--- Only for residual smoothing (multigrid) ---*/ + + for (unsigned long iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { + if (config->GetMG_CorrecSmooth(iMesh) > 0) { + Residual_Sum.resize(nPoint,nVar); + Residual_Old.resize(nPoint,nVar); + break; + } + } + + /*--- Gradient related fields ---*/ + + Gradient.resize(nPoint,val_nVar,val_nDim,0.0); + + if (config->GetLeastSquaresRequired()) { + Rmatrix.resize(nPoint,nDim,nDim,0.0); + } + + /*--- Intitialize the source term of Poisson equation. ---*/ + + SourceTerm.resize(nPoint) = su2double(0.0); + Delta_Time.resize(nPoint) = su2double(0.0); + + for(unsigned long iPoint=0; iPoint + * 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/CPBIncNSVariable.hpp" + +CPBIncNSVariable::CPBIncNSVariable(su2double val_density, su2double val_pressure, su2double *val_velocity, unsigned long nPoint, + unsigned short nDim, unsigned short nvar, CConfig *config) : + CPBIncEulerVariable(val_density, val_pressure, val_velocity, nPoint, nDim, nvar, config) { + + Vorticity.resize(nPoint,3); + StrainMag.resize(nPoint); + DES_LengthScale.resize(nPoint) = su2double(0.0); + Max_Lambda_Visc.resize(nPoint); +} + +bool CPBIncNSVariable::SetPrimVar(unsigned long iPoint, su2double Density_Inf, su2double Viscosity_Inf, su2double eddy_visc, su2double turb_ke, CConfig *config) { + + unsigned short iVar; + bool check_dens = false, physical = true; + + /*--- Set eddy viscosity locally and in the fluid model. ---*/ + SetEddyViscosity(iPoint, eddy_visc); + + /*--- Set the value of the density ---*/ + + check_dens = SetDensity(iPoint, Density_Inf); + + /*--- Set the value of the velocity and velocity^2 (requires density) ---*/ + + SetVelocity(iPoint); + + /*--- Set laminar viscosity ---*/ + + SetLaminarViscosity(iPoint, Viscosity_Inf); + + return physical; +} + + +bool CPBIncNSVariable::SetVorticity_StrainMag(void) { + + for (unsigned long iPoint = 0; iPoint < nPoint; ++iPoint) { + + /*--- Vorticity ---*/ + + Vorticity(iPoint,0) = 0.0; Vorticity(iPoint,1) = 0.0; + + Vorticity(iPoint,2) = Gradient_Primitive(iPoint,2,0)-Gradient_Primitive(iPoint,1,1); + + if (nDim == 3) { + Vorticity(iPoint,0) = Gradient_Primitive(iPoint,3,1)-Gradient_Primitive(iPoint,2,2); + Vorticity(iPoint,1) = -(Gradient_Primitive(iPoint,3,0)-Gradient_Primitive(iPoint,1,2)); + } + + /*--- Strain Magnitude ---*/ + su2double Div = 0.0; + for (unsigned long iDim = 0; iDim < nDim; iDim++) + Div += Gradient_Primitive(iPoint,iDim+1,iDim); + + StrainMag(iPoint) = 0.0; + + /*--- Add diagonal part ---*/ + + for (unsigned long iDim = 0; iDim < nDim; iDim++) { + StrainMag(iPoint) += pow(Gradient_Primitive(iPoint,iDim+1,iDim) - 1.0/3.0*Div, 2.0); + } + if (nDim == 2) { + StrainMag(iPoint) += pow(1.0/3.0*Div, 2.0); + } + + /*--- Add off diagonals ---*/ + + StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,1,1) + Gradient_Primitive(iPoint,2,0)), 2); + + if (nDim == 3) { + StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,1,2) + Gradient_Primitive(iPoint,3,0)), 2); + StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,2,2) + Gradient_Primitive(iPoint,3,1)), 2); + } + + StrainMag(iPoint) = sqrt(2.0*StrainMag(iPoint)); + + } + return false; +} From f4427f5bdb40cd1416f65c6417570e301e8cce8a Mon Sep 17 00:00:00 2001 From: bigfooted Date: Thu, 15 Feb 2024 12:27:57 +0100 Subject: [PATCH 3/6] remove duplicated setvorticity_strainmag --- SU2_CFD/include/variables/CIncNSVariable.hpp | 5 - SU2_CFD/include/variables/CNSVariable.hpp | 5 - .../include/variables/CPBIncNSVariable.hpp | 21 +- SU2_CFD/include/variables/CVariable.hpp | 29 +- SU2_CFD/src/numerics/heat.cpp | 322 ------------------ SU2_CFD/src/solvers/CPBIncNSSolver.cpp | 15 +- SU2_CFD/src/variables/CIncNSVariable.cpp | 52 --- SU2_CFD/src/variables/CNSVariable.cpp | 53 --- SU2_CFD/src/variables/CPBIncNSVariable.cpp | 61 +--- 9 files changed, 35 insertions(+), 528 deletions(-) delete mode 100644 SU2_CFD/src/numerics/heat.cpp diff --git a/SU2_CFD/include/variables/CIncNSVariable.hpp b/SU2_CFD/include/variables/CIncNSVariable.hpp index 48aa8ea0d3ea..a5b42a512cce 100644 --- a/SU2_CFD/include/variables/CIncNSVariable.hpp +++ b/SU2_CFD/include/variables/CIncNSVariable.hpp @@ -62,11 +62,6 @@ class CIncNSVariable final : public CIncEulerVariable { Primitive(iPoint, indices.LaminarViscosity()) = laminarViscosity; } - /*! - * \brief Set the vorticity value. - */ - bool SetVorticity_StrainMag() override; - /*! * \overload * \param[in] eddy_visc - Value of the eddy viscosity. diff --git a/SU2_CFD/include/variables/CNSVariable.hpp b/SU2_CFD/include/variables/CNSVariable.hpp index f55b728c3224..d23b7a16eb41 100644 --- a/SU2_CFD/include/variables/CNSVariable.hpp +++ b/SU2_CFD/include/variables/CNSVariable.hpp @@ -79,11 +79,6 @@ class CNSVariable final : public CEulerVariable { Primitive(iPoint, indices.CpTotal()) = val_Cp; } - /*! - * \brief Set the vorticity value. - */ - bool SetVorticity_StrainMag() override; - /*! * \overload * \param[in] eddy_visc - Value of the eddy viscosity. diff --git a/SU2_CFD/include/variables/CPBIncNSVariable.hpp b/SU2_CFD/include/variables/CPBIncNSVariable.hpp index 4c42bc732cfd..26c5d8495138 100644 --- a/SU2_CFD/include/variables/CPBIncNSVariable.hpp +++ b/SU2_CFD/include/variables/CPBIncNSVariable.hpp @@ -50,12 +50,12 @@ class CPBIncNSVariable final : public CPBIncEulerVariable { VectorType DES_LengthScale; public: - + /*! * \brief Constructor of the class. */ CPBIncNSVariable(void); - + /*! * \param[in] val_pressure - value of the pressure. * \param[in] val_velocity - Value of the flow velocity (initialization value). @@ -64,20 +64,20 @@ class CPBIncNSVariable final : public CPBIncEulerVariable { * \param[in] val_nvar - Number of variables of the problem. * \param[in] config - Definition of the particular problem. */ - CPBIncNSVariable(su2double val_density, su2double val_pressure, su2double *val_velocity, + CPBIncNSVariable(su2double val_density, su2double val_pressure, su2double *val_velocity, unsigned long npoint, unsigned short val_nDim, unsigned short val_nvar, CConfig *config); - + /*! * \brief Destructor of the class. */ virtual ~CPBIncNSVariable() = default; - + /*! * \brief Set all the primitive variables for incompressible flows */ bool SetPrimVar(unsigned long iPoint, su2double Density_Inf, su2double Viscosity_Inf, su2double eddy_visc, su2double turb_ke, CConfig *config); using CVariable::SetPrimVar; - + /*! * \brief Set the laminar viscosity. */ @@ -85,11 +85,6 @@ class CPBIncNSVariable final : public CPBIncEulerVariable { Primitive(iPoint,nDim+2) = laminarViscosity; } - /*! - * \brief Set the vorticity value. - */ - bool SetVorticity_StrainMag() override; - /*! * \overload * \param[in] eddy_visc - Value of the eddy viscosity. @@ -134,11 +129,11 @@ class CPBIncNSVariable final : public CPBIncEulerVariable { * \return Value of the DES length Scale. */ inline su2double GetDES_LengthScale(unsigned long iPoint) const override { return DES_LengthScale(iPoint); } - + /*! * \brief Get the thermal conductivity of the flow. * \return Value of the laminar viscosity of the flow. */ inline su2double GetThermalConductivity(unsigned long iPoint) const override { return 0.0; } - + }; diff --git a/SU2_CFD/include/variables/CVariable.hpp b/SU2_CFD/include/variables/CVariable.hpp index 5bc19e6d8717..ceaca8d1cf8e 100644 --- a/SU2_CFD/include/variables/CVariable.hpp +++ b/SU2_CFD/include/variables/CVariable.hpp @@ -1615,11 +1615,6 @@ class CVariable { */ inline virtual void SetSpecificHeatCv(unsigned long iPoint, su2double Cv) {} - /*! - * \brief A virtual member. - */ - inline virtual bool SetVorticity_StrainMag() { return false; } - /*! * \brief A virtual member. */ @@ -2438,32 +2433,32 @@ class CVariable { inline virtual su2double GetMassFlux(unsigned long iPoint) const { return 0.0; } inline virtual void SetMassFlux(unsigned long iPoint, su2double val_MassFlux) {} - + inline virtual void AddMassFlux(unsigned long iPoint, su2double val_MassFlux) {} - + inline virtual void SubtractMassFlux(unsigned long iPoint, su2double val_MassFlux) {} - + inline virtual void Set_Mom_Coeff(unsigned long iPoint, su2double *val_Mom_Coeff) {} - + inline virtual su2double Get_Mom_Coeff(unsigned long iPoint, unsigned short val_Var) { return 0.0; } - + inline virtual su2double Get_Mom_Coeff_nb(unsigned long iPoint, unsigned short val_Var) { return 0.0; } - + inline virtual void Set_Mom_Coeff_nb(unsigned long iPoint, su2double *val_Mom_Coeff) {} - + inline virtual void Add_Mom_Coeff_nb(unsigned long iPoint, su2double val_coeff_nb, unsigned short val_Var) {} inline virtual void Add_Mom_Coeff(unsigned long iPoint, su2double val_coeff, unsigned short val_Var) {} - + inline virtual void Set_Mom_Coeff_nbZero(unsigned long iPoint) {} - + inline virtual void Set_Mom_CoeffZero(unsigned long iPoint) {} - + inline virtual void Set_Mom_Coeff(unsigned long iPoint, unsigned short val_Var, su2double val_Mom_Coeff) {} - + inline virtual void Set_Mom_Coeff_nb(unsigned long iPoint, unsigned short val_Var, su2double val_Mom_Coeff) {} inline virtual su2double GetPoisson_Coeff(unsigned long iPoint) { return 0.0; } - + inline virtual void SetPoisson_Coeff(unsigned long iPoint, su2double val_Poisson_Coeff) {} }; diff --git a/SU2_CFD/src/numerics/heat.cpp b/SU2_CFD/src/numerics/heat.cpp deleted file mode 100644 index d9e44f54ee56..000000000000 --- a/SU2_CFD/src/numerics/heat.cpp +++ /dev/null @@ -1,322 +0,0 @@ -/*! - * \file heat.cpp - * \brief Implementation of numerics classes for heat transfer. - * \author F. Palacios, T. Economon - * \version 7.0.7 "Blackbird" - * - * SU2 Project Website: https://su2code.github.io - * - * The SU2 Project is maintained by the SU2 Foundation - * (http://su2foundation.org) - * - * Copyright 2012-2020, SU2 Contributors (cf. AUTHORS.md) - * - * 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/heat.hpp" - -CCentSca_Heat::CCentSca_Heat(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) : - CNumerics(val_nDim, val_nVar, config) { - - implicit = (config->GetKind_TimeIntScheme_Turb() == EULER_IMPLICIT); - /* 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(); - - MeanVelocity = new su2double [nDim]; - - Laminar_Viscosity_i = config->GetViscosity_FreeStreamND(); - Laminar_Viscosity_j = config->GetViscosity_FreeStreamND(); - - Param_Kappa_4 = config->GetKappa_4th_Heat(); - Diff_Lapl = new su2double [nVar]; -} - -CCentSca_Heat::~CCentSca_Heat(void) { - - delete [] MeanVelocity; - delete [] Diff_Lapl; - -} - -void CCentSca_Heat::ComputeResidual(su2double *val_residual, su2double **val_Jacobian_i, - su2double **val_Jacobian_j, CConfig *config) { - - AD::StartPreacc(); - AD::SetPreaccIn(V_i, nDim+3); AD::SetPreaccIn(V_j, nDim+3); - AD::SetPreaccIn(Temp_i); AD::SetPreaccIn(Temp_j); - AD::SetPreaccIn(Und_Lapl_i, nVar); AD::SetPreaccIn(Und_Lapl_j, nVar); - AD::SetPreaccIn(Normal, nDim); - if (dynamic_grid) { - AD::SetPreaccIn(GridVel_i, nDim); AD::SetPreaccIn(GridVel_j, nDim); - } - - /*--- Primitive variables at point i and j ---*/ - - Pressure_i = V_i[0]; Pressure_j = V_j[0]; - DensityInc_i = V_i[nDim+2]; DensityInc_j = V_j[nDim+2]; - BetaInc2_i = V_i[nDim+3]; BetaInc2_j = V_j[nDim+3]; - - /*--- Projected velocities at the current edge ---*/ - - ProjVelocity = 0.0; ProjVelocity_i = 0.0; ProjVelocity_j = 0.0; Area = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - ProjVelocity_i += V_i[iDim+1]*Normal[iDim]; - ProjVelocity_j += V_j[iDim+1]*Normal[iDim]; - Area += Normal[iDim]*Normal[iDim]; - } - Area = sqrt(Area); - - /*--- Computing the second order centered scheme part ---*/ - - ProjVelocity = 0.5*(ProjVelocity_i+ProjVelocity_j); - - val_residual[0] = 0.5*(Temp_i + Temp_j)*ProjVelocity; - - if (implicit) { - val_Jacobian_i[0][0] = 0.5*ProjVelocity; - val_Jacobian_j[0][0] = 0.5*ProjVelocity; - } - - /*--- Adding artificial dissipation to stabilize the centered scheme ---*/ - - Diff_Lapl[0] = Und_Lapl_i[0]-Und_Lapl_j[0]; - - SoundSpeed_i = sqrt(ProjVelocity_i*ProjVelocity_i + (BetaInc2_i/DensityInc_i)*Area*Area); - SoundSpeed_j = sqrt(ProjVelocity_j*ProjVelocity_j + (BetaInc2_j/DensityInc_j)*Area*Area); - - Local_Lambda_i = fabs(ProjVelocity_i)+SoundSpeed_i; - Local_Lambda_j = fabs(ProjVelocity_j)+SoundSpeed_j; - MeanLambda = 0.5*(Local_Lambda_i+Local_Lambda_j); - - val_residual[0] += -Param_Kappa_4*Diff_Lapl[0]*MeanLambda; - - if (implicit) { - cte_0 = Param_Kappa_4*su2double(Neighbor_i+1)*MeanLambda; - cte_1 = Param_Kappa_4*su2double(Neighbor_j+1)*MeanLambda; - - val_Jacobian_i[0][0] += cte_0; - val_Jacobian_j[0][0] -= cte_1; - } - - AD::SetPreaccOut(val_residual[0]); - AD::EndPreacc(); - -} - -CUpwSca_Heat::CUpwSca_Heat(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) : - CNumerics(val_nDim, val_nVar, config) { - - implicit = (config->GetKind_TimeIntScheme_Turb() == EULER_IMPLICIT); - /* 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]; - - Laminar_Viscosity_i = config->GetViscosity_FreeStreamND(); - Laminar_Viscosity_j = config->GetViscosity_FreeStreamND(); -} - -CUpwSca_Heat::~CUpwSca_Heat(void) { - - delete [] Velocity_i; - delete [] Velocity_j; - -} - -void CUpwSca_Heat::ComputeResidual(su2double *val_residual, su2double **val_Jacobian_i, - su2double **val_Jacobian_j, CConfig *config) { - - q_ij = 0.0; - - AD::StartPreacc(); - AD::SetPreaccIn(V_i, nDim+1); AD::SetPreaccIn(V_j, nDim+1); - AD::SetPreaccIn(Temp_i); AD::SetPreaccIn(Temp_j); - AD::SetPreaccIn(Normal, nDim); - if (dynamic_grid) { - AD::SetPreaccIn(GridVel_i, nDim); AD::SetPreaccIn(GridVel_j, nDim); - } - - 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)); - val_residual[0] = a0*Temp_i+a1*Temp_j; - - if (implicit) { - val_Jacobian_i[0][0] = a0; - val_Jacobian_j[0][0] = a1; - } - - AD::SetPreaccOut(val_residual[0]); - AD::EndPreacc(); - -} - -CAvgGrad_Heat::CAvgGrad_Heat(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) : - CNumerics(val_nDim, val_nVar, config) { - - implicit = (config->GetKind_TimeIntScheme_Heat() == EULER_IMPLICIT); - - Edge_Vector = new su2double [nDim]; - Proj_Mean_GradHeatVar_Normal = new su2double [nVar]; - Proj_Mean_GradHeatVar_Corrected = new su2double [nVar]; - Mean_GradHeatVar = new su2double* [nVar]; - for (iVar = 0; iVar < nVar; iVar++) - Mean_GradHeatVar[iVar] = new su2double [nDim]; - -} - -CAvgGrad_Heat::~CAvgGrad_Heat(void) { - - delete [] Edge_Vector; - delete [] Proj_Mean_GradHeatVar_Normal; - delete [] Proj_Mean_GradHeatVar_Corrected; - for (iVar = 0; iVar < nVar; iVar++) - delete [] Mean_GradHeatVar[iVar]; - delete [] Mean_GradHeatVar; - -} - -void CAvgGrad_Heat::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(Temp_i); AD::SetPreaccIn(Temp_j); - AD::SetPreaccIn(ConsVar_Grad_i[0],nDim); AD::SetPreaccIn(ConsVar_Grad_j[0],nDim); - AD::SetPreaccIn(Thermal_Diffusivity_i); AD::SetPreaccIn(Thermal_Conductivity_j); - - Thermal_Diffusivity_Mean = 0.5*(Thermal_Diffusivity_i + Thermal_Diffusivity_j); - - /*--- 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. Projection of the mean gradient in the direction of the edge ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - Proj_Mean_GradHeatVar_Normal[iVar] = 0.0; - Proj_Mean_GradHeatVar_Corrected[iVar] = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - Mean_GradHeatVar[iVar][iDim] = 0.5*(ConsVar_Grad_i[iVar][iDim] + ConsVar_Grad_j[iVar][iDim]); - Proj_Mean_GradHeatVar_Normal[iVar] += Mean_GradHeatVar[iVar][iDim]*Normal[iDim]; - } - Proj_Mean_GradHeatVar_Corrected[iVar] = Proj_Mean_GradHeatVar_Normal[iVar]; - } - - val_residual[0] = Thermal_Diffusivity_Mean*Proj_Mean_GradHeatVar_Corrected[0]; - - /*--- For Jacobians -> Use of TSL approx. to compute derivatives of the gradients ---*/ - if (implicit) { - Jacobian_i[0][0] = -Thermal_Diffusivity_Mean*proj_vector_ij; - Jacobian_j[0][0] = Thermal_Diffusivity_Mean*proj_vector_ij; - } - - AD::SetPreaccOut(val_residual, nVar); - AD::EndPreacc(); - -} - -CAvgGradCorrected_Heat::CAvgGradCorrected_Heat(unsigned short val_nDim, unsigned short val_nVar, CConfig *config) : - CNumerics(val_nDim, val_nVar, config) { - - implicit = (config->GetKind_TimeIntScheme_Heat() == EULER_IMPLICIT); - - Edge_Vector = new su2double [nDim]; - Proj_Mean_GradHeatVar_Edge = new su2double [nVar]; - Proj_Mean_GradHeatVar_Kappa = new su2double [nVar]; - Proj_Mean_GradHeatVar_Corrected = new su2double [nVar]; - Mean_GradHeatVar = new su2double* [nVar]; - for (iVar = 0; iVar < nVar; iVar++) - Mean_GradHeatVar[iVar] = new su2double [nDim]; - -} - -CAvgGradCorrected_Heat::~CAvgGradCorrected_Heat(void) { - - delete [] Edge_Vector; - delete [] Proj_Mean_GradHeatVar_Edge; - delete [] Proj_Mean_GradHeatVar_Kappa; - delete [] Proj_Mean_GradHeatVar_Corrected; - for (iVar = 0; iVar < nVar; iVar++) - delete [] Mean_GradHeatVar[iVar]; - delete [] Mean_GradHeatVar; - -} - -void CAvgGradCorrected_Heat::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(Temp_i); AD::SetPreaccIn(Temp_j); - AD::SetPreaccIn(ConsVar_Grad_i[0],nDim); AD::SetPreaccIn(ConsVar_Grad_j[0],nDim); - AD::SetPreaccIn(Thermal_Diffusivity_i); AD::SetPreaccIn(Thermal_Diffusivity_j); - - Thermal_Diffusivity_Mean = 0.5*(Thermal_Diffusivity_i + Thermal_Diffusivity_j); - - /*--- 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. Projection of the mean gradient - in the direction of the edge ---*/ - - for (iVar = 0; iVar < nVar; iVar++) { - Proj_Mean_GradHeatVar_Edge[iVar] = 0.0; - Proj_Mean_GradHeatVar_Kappa[iVar] = 0.0; - - for (iDim = 0; iDim < nDim; iDim++) { - Mean_GradHeatVar[iVar][iDim] = 0.5*(ConsVar_Grad_i[iVar][iDim] + ConsVar_Grad_j[iVar][iDim]); - Proj_Mean_GradHeatVar_Kappa[iVar] += Mean_GradHeatVar[iVar][iDim]*Normal[iDim]; - Proj_Mean_GradHeatVar_Edge[iVar] += Mean_GradHeatVar[iVar][iDim]*Edge_Vector[iDim]; - } - Proj_Mean_GradHeatVar_Corrected[iVar] = Proj_Mean_GradHeatVar_Kappa[iVar]; - Proj_Mean_GradHeatVar_Corrected[iVar] -= Proj_Mean_GradHeatVar_Edge[iVar]*proj_vector_ij - - (Temp_j-Temp_i)*proj_vector_ij; - } - - val_residual[0] = Thermal_Diffusivity_Mean*Proj_Mean_GradHeatVar_Corrected[0]; - - /*--- For Jacobians -> Use of TSL approx. to compute derivatives of the gradients ---*/ - - if (implicit) { - Jacobian_i[0][0] = -Thermal_Diffusivity_Mean*proj_vector_ij; - Jacobian_j[0][0] = Thermal_Diffusivity_Mean*proj_vector_ij; - } - - AD::SetPreaccOut(val_residual, nVar); - AD::EndPreacc(); -} diff --git a/SU2_CFD/src/solvers/CPBIncNSSolver.cpp b/SU2_CFD/src/solvers/CPBIncNSSolver.cpp index 01d7a2162614..e1d193cb7029 100644 --- a/SU2_CFD/src/solvers/CPBIncNSSolver.cpp +++ b/SU2_CFD/src/solvers/CPBIncNSSolver.cpp @@ -33,7 +33,7 @@ CPBIncNSSolver::CPBIncNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) : CPBIncEulerSolver(geometry, config, iMesh, true) { - + Viscosity_Inf = config->GetViscosity_FreeStreamND(); Tke_Inf = config->GetTke_FreeStreamND(); @@ -41,7 +41,10 @@ CPBIncNSSolver::CPBIncNSSolver(CGeometry *geometry, CConfig *config, unsigned sh void CPBIncNSSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { -unsigned long iPoint, ErrorCounter = 0; + auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); + + + unsigned long iPoint, ErrorCounter = 0; su2double StrainMag = 0.0, Omega = 0.0, *Vorticity; unsigned long InnerIter = config->GetInnerIter(); @@ -82,13 +85,12 @@ unsigned long iPoint, ErrorCounter = 0; && !Output && !van_albada) { SetPrimitive_Limiter(geometry, config); } /*--- Evaluate the vorticity and strain rate magnitude ---*/ - - solver_container[FLOW_SOL]->GetNodes()->SetVorticity_StrainMag(); // TODO:PBFlow + ComputeVorticityAndStrainMag(*config, geometry, iMesh); StrainMag_Max = 0.0; Omega_Max = 0.0; for (iPoint = 0; iPoint < nPoint; iPoint++) { - StrainMag = solver_container[FLOW_SOL]->GetNodes()->GetStrainMag(iPoint); + StrainMag = flowNodes->GetStrainMag(iPoint); Vorticity = solver_container[FLOW_SOL]->GetNodes()->GetVorticity(iPoint); Omega = sqrt(Vorticity[0]*Vorticity[0]+ Vorticity[1]*Vorticity[1]+ Vorticity[2]*Vorticity[2]); @@ -189,8 +191,7 @@ unsigned long iPoint, ErrorCounter = 0; } /*--- Evaluate the vorticity and strain rate magnitude ---*/ - - solver_container[FLOW_SOL]->GetNodes()->SetVorticity_StrainMag(); + ComputeVorticityAndStrainMag(*config, geometry, iMesh); } diff --git a/SU2_CFD/src/variables/CIncNSVariable.cpp b/SU2_CFD/src/variables/CIncNSVariable.cpp index 7c8f820ef297..e32b8d6dd73d 100644 --- a/SU2_CFD/src/variables/CIncNSVariable.cpp +++ b/SU2_CFD/src/variables/CIncNSVariable.cpp @@ -126,55 +126,3 @@ bool CIncNSVariable::SetPrimVar(unsigned long iPoint, su2double eddy_visc, su2do return physical; } - -bool CIncNSVariable::SetVorticity_StrainMag() { - - for (unsigned long iPoint = 0; iPoint < nPoint; ++iPoint) { - - /*--- Vorticity ---*/ - - Vorticity(iPoint,0) = 0.0; Vorticity(iPoint,1) = 0.0; - - Vorticity(iPoint,2) = Gradient_Primitive(iPoint,2,0)-Gradient_Primitive(iPoint,1,1); - - if (nDim == 3) { - Vorticity(iPoint,0) = Gradient_Primitive(iPoint,3,1)-Gradient_Primitive(iPoint,2,2); - Vorticity(iPoint,1) = -(Gradient_Primitive(iPoint,3,0)-Gradient_Primitive(iPoint,1,2)); - } - - /*--- Strain Magnitude ---*/ - - AD::StartPreacc(); - AD::SetPreaccIn(Gradient_Primitive[iPoint], nDim+1, nDim); - - su2double Div = 0.0; - for (unsigned long iDim = 0; iDim < nDim; iDim++) - Div += Gradient_Primitive(iPoint,iDim+1,iDim); - - StrainMag(iPoint) = 0.0; - - /*--- Add diagonal part ---*/ - - for (unsigned long iDim = 0; iDim < nDim; iDim++) { - StrainMag(iPoint) += pow(Gradient_Primitive(iPoint,iDim+1,iDim) - 1.0/3.0*Div, 2.0); - } - if (nDim == 2) { - StrainMag(iPoint) += pow(1.0/3.0*Div, 2.0); - } - - /*--- Add off diagonals ---*/ - - StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,1,1) + Gradient_Primitive(iPoint,2,0)), 2); - - if (nDim == 3) { - StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,1,2) + Gradient_Primitive(iPoint,3,0)), 2); - StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,2,2) + Gradient_Primitive(iPoint,3,1)), 2); - } - - StrainMag(iPoint) = sqrt(2.0*StrainMag(iPoint)); - - AD::SetPreaccOut(StrainMag(iPoint)); - AD::EndPreacc(); - } - return false; -} \ No newline at end of file diff --git a/SU2_CFD/src/variables/CNSVariable.cpp b/SU2_CFD/src/variables/CNSVariable.cpp index dfce3ac29fb9..b2fe70b35cc9 100644 --- a/SU2_CFD/src/variables/CNSVariable.cpp +++ b/SU2_CFD/src/variables/CNSVariable.cpp @@ -45,59 +45,6 @@ CNSVariable::CNSVariable(su2double density, const su2double *velocity, su2double } -bool CNSVariable::SetVorticity_StrainMag() { - - SU2_OMP_FOR_STAT(256) - for (unsigned long iPoint = 0; iPoint < nPoint; ++iPoint) { - - /*--- Vorticity ---*/ - - Vorticity(iPoint,0) = 0.0; Vorticity(iPoint,1) = 0.0; - - Vorticity(iPoint,2) = Gradient_Primitive(iPoint,2,0)-Gradient_Primitive(iPoint,1,1); - - if (nDim == 3) { - Vorticity(iPoint,0) = Gradient_Primitive(iPoint,3,1)-Gradient_Primitive(iPoint,2,2); - Vorticity(iPoint,1) = -(Gradient_Primitive(iPoint,3,0)-Gradient_Primitive(iPoint,1,2)); - } - - /*--- Strain Magnitude ---*/ - - AD::StartPreacc(); - AD::SetPreaccIn(Gradient_Primitive[iPoint], nDim+1, nDim); - - su2double Div = 0.0; - for (unsigned long iDim = 0; iDim < nDim; iDim++) - Div += Gradient_Primitive(iPoint,iDim+1,iDim); - - StrainMag(iPoint) = 0.0; - - /*--- Add diagonal part ---*/ - - for (unsigned long iDim = 0; iDim < nDim; iDim++) { - StrainMag(iPoint) += pow(Gradient_Primitive(iPoint,iDim+1,iDim) - 1.0/3.0*Div, 2.0); - } - if (nDim == 2) { - StrainMag(iPoint) += pow(1.0/3.0*Div, 2.0); - } - - /*--- Add off diagonals ---*/ - - StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,1,1) + Gradient_Primitive(iPoint,2,0)), 2); - - if (nDim == 3) { - StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,1,2) + Gradient_Primitive(iPoint,3,0)), 2); - StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,2,2) + Gradient_Primitive(iPoint,3,1)), 2); - } - - StrainMag(iPoint) = sqrt(2.0*StrainMag(iPoint)); - - AD::SetPreaccOut(StrainMag(iPoint)); - AD::EndPreacc(); - } - return false; -} - void CNSVariable::SetRoe_Dissipation_NTS(unsigned long iPoint, su2double val_delta, su2double val_const_DES){ diff --git a/SU2_CFD/src/variables/CPBIncNSVariable.cpp b/SU2_CFD/src/variables/CPBIncNSVariable.cpp index bd5587416d10..1480cae012b1 100644 --- a/SU2_CFD/src/variables/CPBIncNSVariable.cpp +++ b/SU2_CFD/src/variables/CPBIncNSVariable.cpp @@ -40,7 +40,7 @@ CPBIncNSVariable::CPBIncNSVariable(su2double val_density, su2double val_pressure, su2double *val_velocity, unsigned long nPoint, unsigned short nDim, unsigned short nvar, CConfig *config) : CPBIncEulerVariable(val_density, val_pressure, val_velocity, nPoint, nDim, nvar, config) { - + Vorticity.resize(nPoint,3); StrainMag.resize(nPoint); DES_LengthScale.resize(nPoint) = su2double(0.0); @@ -48,71 +48,24 @@ CPBIncNSVariable::CPBIncNSVariable(su2double val_density, su2double val_pressure } bool CPBIncNSVariable::SetPrimVar(unsigned long iPoint, su2double Density_Inf, su2double Viscosity_Inf, su2double eddy_visc, su2double turb_ke, CConfig *config) { - + unsigned short iVar; bool check_dens = false, physical = true; - + /*--- Set eddy viscosity locally and in the fluid model. ---*/ SetEddyViscosity(iPoint, eddy_visc); - + /*--- Set the value of the density ---*/ - + check_dens = SetDensity(iPoint, Density_Inf); /*--- Set the value of the velocity and velocity^2 (requires density) ---*/ SetVelocity(iPoint); - + /*--- Set laminar viscosity ---*/ - + SetLaminarViscosity(iPoint, Viscosity_Inf); return physical; } - - -bool CPBIncNSVariable::SetVorticity_StrainMag(void) { - - for (unsigned long iPoint = 0; iPoint < nPoint; ++iPoint) { - - /*--- Vorticity ---*/ - - Vorticity(iPoint,0) = 0.0; Vorticity(iPoint,1) = 0.0; - - Vorticity(iPoint,2) = Gradient_Primitive(iPoint,2,0)-Gradient_Primitive(iPoint,1,1); - - if (nDim == 3) { - Vorticity(iPoint,0) = Gradient_Primitive(iPoint,3,1)-Gradient_Primitive(iPoint,2,2); - Vorticity(iPoint,1) = -(Gradient_Primitive(iPoint,3,0)-Gradient_Primitive(iPoint,1,2)); - } - - /*--- Strain Magnitude ---*/ - su2double Div = 0.0; - for (unsigned long iDim = 0; iDim < nDim; iDim++) - Div += Gradient_Primitive(iPoint,iDim+1,iDim); - - StrainMag(iPoint) = 0.0; - - /*--- Add diagonal part ---*/ - - for (unsigned long iDim = 0; iDim < nDim; iDim++) { - StrainMag(iPoint) += pow(Gradient_Primitive(iPoint,iDim+1,iDim) - 1.0/3.0*Div, 2.0); - } - if (nDim == 2) { - StrainMag(iPoint) += pow(1.0/3.0*Div, 2.0); - } - - /*--- Add off diagonals ---*/ - - StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,1,1) + Gradient_Primitive(iPoint,2,0)), 2); - - if (nDim == 3) { - StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,1,2) + Gradient_Primitive(iPoint,3,0)), 2); - StrainMag(iPoint) += 2.0*pow(0.5*(Gradient_Primitive(iPoint,2,2) + Gradient_Primitive(iPoint,3,1)), 2); - } - - StrainMag(iPoint) = sqrt(2.0*StrainMag(iPoint)); - - } - return false; -} From 11cbfab54adc421bac0df4956cfee7a0502c07da Mon Sep 17 00:00:00 2001 From: Nitish Anand Date: Thu, 15 Feb 2024 16:44:56 +0100 Subject: [PATCH 4/6] Configuration files for PB Flow solver. Configs with V8 are the updated configs. --- .../centrifugal_blade_inc.cfg | 286 +++++++++++++++++ .../channel/channel_visc.cfg | 225 +++++++++++++ .../couette_flow/couette_flow.cfg | 223 +++++++++++++ .../cylinder/incomp_cylinder_V8.cfg | 98 ++++++ .../cylinder/lam_cylinder.cfg | 243 ++++++++++++++ .../flatplate_turb/turb_flatplate.cfg | 298 ++++++++++++++++++ .../incomp_NACA0012_PB_V8.cfg | 102 ++++++ .../lid_driven_cavity/liddrivencavity.cfg | 297 +++++++++++++++++ .../turb_naca0012/turb_naca0012_v7.cfg | 247 +++++++++++++++ 9 files changed, 2019 insertions(+) create mode 100644 TestCases/incomp_pressure_based_solver/centrifugal_blade/centrifugal_blade_inc.cfg create mode 100644 TestCases/incomp_pressure_based_solver/channel/channel_visc.cfg create mode 100644 TestCases/incomp_pressure_based_solver/couette_flow/couette_flow.cfg create mode 100644 TestCases/incomp_pressure_based_solver/cylinder/incomp_cylinder_V8.cfg create mode 100755 TestCases/incomp_pressure_based_solver/cylinder/lam_cylinder.cfg create mode 100755 TestCases/incomp_pressure_based_solver/flatplate_turb/turb_flatplate.cfg create mode 100644 TestCases/incomp_pressure_based_solver/hydrofoil_naca0012/incomp_NACA0012_PB_V8.cfg create mode 100644 TestCases/incomp_pressure_based_solver/lid_driven_cavity/liddrivencavity.cfg create mode 100644 TestCases/incomp_pressure_based_solver/turb_naca0012/turb_naca0012_v7.cfg diff --git a/TestCases/incomp_pressure_based_solver/centrifugal_blade/centrifugal_blade_inc.cfg b/TestCases/incomp_pressure_based_solver/centrifugal_blade/centrifugal_blade_inc.cfg new file mode 100644 index 000000000000..c180de4a4533 --- /dev/null +++ b/TestCases/incomp_pressure_based_solver/centrifugal_blade/centrifugal_blade_inc.cfg @@ -0,0 +1,286 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Centrifugal turbine rotor % +% based on turbomachinery/centrifugal blade % +% Author: Akshay Koodly % +% Institution: University of Twente % +% File Version 7.0.7 "Blackbird % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% +% +% +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +% Physical governing equations (EULER, NAVIER_STOKES) +SOLVER= INC_RANS +% +% Specify turbulent model (NONE, SA, SST) +KIND_TURB_MODEL= SST +% +% Mathematical problem (DIRECT, ADJOINT, LINEARIZED) +MATH_PROBLEM= DIRECT +% +% Restart solution (NO, YES) +RESTART_SOL= NO +% +% Incompressible solver (DENSITY_BASED, PRESSURE_BASED) +% DENSITY_BASED is chosen by default +KIND_INCOMP_SYSTEM= PRESSURE_BASED +% +% +% -------------------- INCOMPRESSIBLE FREE-STREAM DEFINITION ------------------% +% +% Free-stream density (1.2886 Kg/m^3 (air), 998.2 Kg/m^3 (water)) +INC_DENSITY_INIT= 1.36524 +% +% Initial velocity for incompressible flows (1.0,0,0 m/s by default) +% +% AoA 0.0 deg +INC_VELOCITY_INIT= ( 22.6435, 0, 0.0 ) +% +% Non-dimensionalization scheme for incompressible flows. Options are +% INITIAL_VALUES (default), REFERENCE_VALUES, or DIMENSIONAL. +% INC_*_REF values are ignored unless REFERENCE_VALUES is chosen. +INC_NONDIM= INITIAL_VALUES +% +% Reference density for incompressible flows (1.0 kg/m^3 by default) +INC_DENSITY_REF= 1.0 +% +% Reference velocity for incompressible flows (1.0 m/s by default) +INC_VELOCITY_REF= 1.0 +% +% Reference temperature for incompressible flows that include the +% energy equation (1.0 K by default) +INC_TEMPERATURE_REF = 1.0 +% +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +% Reference length for moment non-dimensional coefficients (m or in) +REF_LENGTH= 1.0 +% +% Reference area for force coefficients (0 implies automatic calculation) +REF_AREA= 0.0 +% +% --------------------------------- FLUID MODEL -----------------------------------% +% +% Different gas model (STANDARD_AIR, IDEAL_GAS, VW_GAS, PR_GAS) +FLUID_MODEL= IDEAL_GAS +% +% --------------------------- VISCOSITY MODEL ---------------------------------% +% +% Viscosity model (SUTHERLAND, CONSTANT_VISCOSITY). +VISCOSITY_MODEL= CONSTANT_VISCOSITY +% +% Molecular Viscosity that would be constant (1.716E-5 by default) +MU_CONSTANT= 1.0563E-5 +% +% Sutherland Viscosity Ref (1.716E-5 default value for AIR SI) +MU_REF= 1.716E-5 +% +% Sutherland Temperature Ref (273.15 K default value for AIR SI) +MU_T_REF= 273.15 +% +% Sutherland constant (110.4 default value for AIR SI) +SUTHERLAND_CONSTANT= 110.4 +% +% +% +% +% --------------------------- THERMAL CONDUCTIVITY MODEL ----------------------% +% +% Conductivity model (CONSTANT_CONDUCTIVITY, CONSTANT_PRANDTL). +CONDUCTIVITY_MODEL= CONSTANT_PRANDTL +% +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +% Navier-Stokes wall boundary marker(s) (NONE = no marker) +MARKER_HEATFLUX= ( wall1, 0.0, wall2, 0.0 ) +%MARKER_EULER= ( wall1, wall2 ) +% +% Periodic boundary marker(s) (NONE = no marker) +% Format: ( periodic marker, donor marker, rot_cen_x, rot_cen_y, rot_cen_z, rot_angle_x-axis, rot_angle_y-axis, rot_angle_z-axis, translation_x, translation_y, translation_z) +MARKER_PERIODIC= ( periodic1, periodic2, 0.0, 0.0, 0.0, 0.0, 0.0, 9.47, 0.0, 0.0, 0.0) +% +% Inlet boundary marker(s) (NONE = no marker) +% Format: ( inlet marker, total temperature, total pressure, flow_direction_x, +% flow_direction_y, flow_direction_z, ... ) +MARKER_INLET= ( inflow, 302.4, 22.6435, 1.0, 0.0, 0.0 ) +INC_INLET_TYPE= VELOCITY_INLET +% +% Outlet boundary marker(s) (NONE = no marker) +% Format: ( outlet marker, back pressure, ... ) +MARKER_OUTLET= ( outflow, 0, farfield, 0 ) +INC_OUTLET_TYPE= PRESSURE_OUTLET,PRESSURE_OUTLET +% +% +% ------------------------ SURFACES IDENTIFICATION ----------------------------% +% +% Marker(s) of the surface in the surface flow solution file +MARKER_PLOTTING= (wall1, wall2 ) +% +% ------------------------- GRID ADAPTATION STRATEGY --------------------------% +% +% Kind of grid adaptation (NONE, PERIODIC) +KIND_ADAPT= PERIODIC +% +% +% ----------------------- DYNAMIC MESH DEFINITION -----------------------------% +% +% Dynamic mesh simulation (NO, YES) +GRID_MOVEMENT= ROTATING_FRAME +% +% Motion mach number (non-dimensional). Used for intitializing a viscous flow +% with the Reynolds number and for computing force coeffs. with dynamic meshes. +MACH_MOTION= 0.35 +% +% Angular velocity vector (rad/s) about the motion origi. Example 1250 RPM -> 130.89969389957471 rad/s +ROTATION_RATE = 0.0 0.0 1990.00 +% +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +% Numerical method for spatial gradients (GREEN_GAUSS, WEIGHTED_LEAST_SQUARES) +%NUM_METHOD_GRAD= GREEN_GAUSS +% +% Courant-Friedrichs-Lewy condition of the finest grid +CFL_NUMBER= 1 +% +% Adaptive CFL number (NO, YES) +CFL_ADAPT= NO +% +% Parameters of the adaptive CFL number (factor down, factor up, CFL min value, CFL max value ) +CFL_ADAPT_PARAM= ( 0.3, 0.4, 10.0, 1000.0) +% +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +% Linear solver or smoother for implicit formulations (BCGSTAB, FGMRES, SMOOTHER) +LINEAR_SOLVER= FGMRES +% +% Preconditioner of the Krylov linear solver (ILU, LU_SGS, LINELET, JACOBI) +LINEAR_SOLVER_PREC= LU_SGS +% +% Min error of the linear solver for the implicit formulation +LINEAR_SOLVER_ERROR= 1E-4 +% +% Max number of iterations of the linear solver for the implicit formulation +LINEAR_SOLVER_ITER= 5 +% +% ----------------------- SLOPE LIMITER DEFINITION ----------------------------% +% +% Coefficient for the limiter +VENKAT_LIMITER_COEFF= 0.1 +% +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +% Convective numerical method (JST, JST_KE, JST_MAT, LAX-FRIEDRICH, CUSP, ROE, AUSM, +% AUSMPLUSUP, AUSMPLUSUP2, AUSMPWPLUS, HLLC, TURKEL_PREC, +% SW, MSW, FDS, SLAU, SLAU2, L2ROE, LMROE, UDS) +CONV_NUM_METHOD_FLOW= UDS +% +% Spatial numerical order integration (1ST_ORDER, 2ND_ORDER, 2ND_ORDER_LIMITER) +MUSCL_FLOW= YES +% +% Slope limiter (VENKATAKRISHNAN, BARTH_JESPERSEN, VAN_ALBADA_EDGE) +SLOPE_LIMITER_FLOW= VENKATAKRISHNAN +% +% Time discretization (RUNGE-KUTTA_EXPLICIT, EULER_IMPLICIT, EULER_EXPLICIT) +TIME_DISCRE_FLOW= EULER_IMPLICIT +% +% -------------------- TURBULENT NUMERICAL METHOD DEFINITION ------------------% +% +% Convective numerical method (SCALAR_UPWIND) +CONV_NUM_METHOD_TURB= SCALAR_UPWIND +% +% Monotonic Upwind Scheme for Conservation Laws (TVD) in the turbulence equations. +% Required for 2nd order upwind schemes (NO, YES) +MUSCL_TURB= NO +% +% Slope limiter (VENKATAKRISHNAN) +SLOPE_LIMITER_TURB= NONE +% +% Time discretization (EULER_IMPLICIT) +TIME_DISCRE_TURB= EULER_IMPLICIT +% +% Reduction factor of the CFL coefficient in the turbulence problem +CFL_REDUCTION_TURB= 0.01 +% +% Number of iterations for the poisson solver +LINEAR_SOLVER_ITER_POISSON = 20 +% +% Number of iterations for the flow solver +LINEAR_SOLVER_ITER_FLOW = 20 +% +% Relaxation factor for pressure solution +RELAXATION_FACTOR_PBFLOW= 1.0 +% +% +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +% Number of total iterations +ITER=1500 +% +% Convergence criteria (CAUCHY, RESIDUAL) +CONV_CRITERIA= RESIDUAL +% +% Flow functional for the Residual criteria (RHO, RHO_ENERGY) +% +% +% Min value of the residual (log10 of the residual) +CONV_RESIDUAL_MINVAL= -16 +% +% Start convergence criteria at iteration number +CONV_STARTITER= 10 +% +% Number of elements to apply the criteria +CONV_CAUCHY_ELEMS= 100 +% +% Epsilon to control the series convergence +CONV_CAUCHY_EPS= 1E-6 +% +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +% Mesh input file +MESH_FILENAME= su2mesh.su2 +%MESH_FILENAME= centrifugal_blade_tet.su2 +% +% Mesh input file format (SU2, CGNS) +MESH_FORMAT= SU2 +% +% Mesh output file +MESH_OUT_FILENAME= su2mesh_per.su2 +% +% Restart flow input file +SOLUTION_FILENAME= restart_flow.dat +% +% Output file format (PARAVIEW, TECPLOT, STL) +TABULAR_FORMAT= CSV +% +% Output file convergence history (w/o extension) +CONV_FILENAME= history +% +% Output file restart flow +RESTART_FILENAME= restart_flow.dat +% +% Output file flow (w/o extension) variables +VOLUME_FILENAME= flow +% +% Output file surface flow coefficient (w/o extension) +SURFACE_FILENAME= surface_flow +% +% Writing solution file frequency +WRT_SOL_FREQ= 500 +% +% Writing convergence history frequency +WRT_CON_FREQ= 1 +% +WRT_FORCES_BREAKDOWN= YES +% +SCREEN_OUTPUT= INNER_ITER, RMS_VELOCITY-X, RMS_MASSFLUX +% +VOLUME_OUTPUT= COORDINATES, SOLUTION, PRIMITIVE +% +BREAKDOWN_FILENAME= forces_breakdown.dat + + diff --git a/TestCases/incomp_pressure_based_solver/channel/channel_visc.cfg b/TestCases/incomp_pressure_based_solver/channel/channel_visc.cfg new file mode 100644 index 000000000000..77e0c1e60571 --- /dev/null +++ b/TestCases/incomp_pressure_based_solver/channel/channel_visc.cfg @@ -0,0 +1,225 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Incompressible and laminar channel flow % +% Author: Akshay Koodly % +% Institution: University of Twente % +% File Version 7.0.7 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +% Physical governing equations (EULER, NAVIER_STOKES, +% WAVE_EQUATION, HEAT_EQUATION, FEM_ELASTICITY, +% POISSON_EQUATION) +SOLVER= INC_EULER +% +% Incompressible solver (DENSITY_BASED, PRESSURE_BASED) +% DENSITY_BASED is chosen by default +KIND_INCOMP_SYSTEM= PRESSURE_BASED +% +% Mathematical problem (DIRECT, CONTINUOUS_ADJOINT) +MATH_PROBLEM= DIRECT +% +% Restart solution (NO, YES) +RESTART_SOL= NO +% +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +% Density model within the incompressible flow solver. +% Options are CONSTANT (default), BOUSSINESQ, or VARIABLE. If VARIABLE, +% an appropriate fluid model must be selected. +INC_DENSITY_MODEL= CONSTANT +% +% Solve the energy equation in the incompressible flow solver +INC_ENERGY_EQUATION = NO +% +% Initial density for incompressible flows (1.2886 kg/m^3 by default) +INC_DENSITY_INIT= 1.0 +% +% Reference density for incompressible flows (1.0 kg/m^3 by default) +INC_DENSITY_REF= 1.0 +% +% Reference velocity for incompressible flows (1.0 m/s by default) +INC_VELOCITY_REF= 1.0 +% +% Reference temperature for incompressible flows that include the +% energy equation (1.0 K by default) +INC_TEMPERATURE_REF = 1.0 +% Initial velocity for incompressible flows (1.0,0,0 m/s by default) +INC_VELOCITY_INIT= ( 1.0, 0.0, 0.0 ) + +% Non-dimensionalization scheme for incompressible flows. Options are +% INITIAL_VALUES (default), REFERENCE_VALUES, or DIMENSIONAL. +% INC_*_REF values are ignored unless REFERENCE_VALUES is chosen. +%INC_NONDIM= INITIAL_VALUES +% +% --------------------------- VISCOSITY MODEL ---------------------------------% +% +% Viscosity model (SUTHERLAND, CONSTANT_VISCOSITY). +VISCOSITY_MODEL= CONSTANT_VISCOSITY +% +% Molecular Viscosity thsat would be constant (1.716E-5 by default) +MU_CONSTANT= 2.5E-3 +% +% +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +% Reference origin for moment computation +REF_ORIGIN_MOMENT_X = 0.25 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +% +% Reference length for pitching, rolling, and yawing non-dimensional moment +REF_LENGTH= 1.0 +% +% Reference area for force coefficients (0 implies automatic calculation) +REF_AREA= 1.0 + +% ----------------------- BOUNDARY CONDITION DEFINITION -----------------------% +% +% Euler wall boundary marker(s) (NONE = no marker) +MARKER_HEATFLUX= ( lower_wall,0.0 ) +% +% Incompressible: (inlet marker, NULL, velocity magnitude, flow_direction_x, +% flow_direction_y, flow_direction_z, ... ) where flow_direction is +% a unit vector. +MARKER_INLET= (inlet, 0.0, 1.0, 1.0, 0.0, 0.0 ) +% +INC_INLET_TYPE= VELOCITY_INLET +% +% Outlet boundary marker(s) (NONE = no marker) +MARKER_OUTLET= ( outlet, 0.0 ) +% +INC_OUTLET_TYPE= PRESSURE_OUTLET +% +% upper_wall boundary marker(s) (NONE = no marker) +MARKER_SYM= ( upper_wall) +% +% Marker(s) of the surface that is going to be analyzed in detail (massflow, average pressure, distortion, etc) +MARKER_ANALYZE = ( inlet, outlet ) +% +MARKER_PLOTTING= ( lower_wall ) +% +% Marker(s) of the surface where the functional (Cd, Cl, etc.) will be evaluated +MARKER_MONITORING= ( lower_wall) + +% ------------- COMMON PARAMETERS TO DEFINE THE NUMERICAL METHOD --------------% +% +% Numerical method for spatial gradients (GREEN_GAUSS, WEIGHTED_LEAST_SQUARES) +NUM_METHOD_GRAD= GREEN_GAUSS +% +% Courant-Friedrichs-Lewy condition of the finest grid +CFL_NUMBER= 4.0 +% +% Adaptive CFL number (NO, YES) +CFL_ADAPT= NO +% +% Parameters of the adaptive CFL number (factor down, factor up, CFL min value, +% CFL max value ) +CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) +% +% Runge-Kutta alpha coefficients +RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) +% +% Number of total iterations +ITER= 15000 + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +% Linear solver or smoother for implicit formulations (BCGSTAB, FGMRES, SMOOTHER_JACOBI, +% SMOOTHER_ILU, SMOOTHER_LUSGS, +% SMOOTHER_LINELET) +LINEAR_SOLVER= FGMRES +% +% Preconditioner of the Krylov linear solver (ILU, LU_SGS, LINELET, JACOBI) +LINEAR_SOLVER_PREC= LU_SGS +% +% Linael solver ILU preconditioner fill-in level (0 by default) +LINEAR_SOLVER_ILU_FILL_IN= 0 +% +% Minimum error of the linear solver for implicit formulations +LINEAR_SOLVER_ERROR= 1E-12 +% +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +% Convective numerical method (JST, JST_KE, JST_MAT, LAX-FRIEDRICH, CUSP, ROE, AUSM, +% AUSMPLUSUP, AUSMPLUSUP2, AUSMPWPLUS, HLLC, TURKEL_PREC, +% SW, MSW, FDS, SLAU, SLAU2, L2ROE, LMROE, UDS) +CONV_NUM_METHOD_FLOW= CDS +% +% Monotonic Upwind Scheme for Conservation Laws (TVD) in the flow equations. +% Required for 2nd order upwind schemes (NO, YES) +MUSCL_FLOW= NO +% +% Slope limiter (VENKATAKRISHNAN, MINMOD) +SLOPE_LIMITER_FLOW= NONE +% +% Coefficient for the limiter (smooth regions) +VENKAT_LIMITER_COEFF= 0.05 +% +% 2nd and 4th order artificial dissipation coefficients +JST_SENSOR_COEFF= ( 0.5, 0.02 ) +% +% Time discretization (RUNGE-KUTTA_EXPLICIT, EULER_IMPLICIT, EULER_EXPLICIT) +TIME_DISCRE_FLOW= EULER_IMPLICIT +% +% Number of iterations for the poisson solver +POISSON_LINEAR_SOLVER_ITER = 30 +% +% Number of iterations for the flow solver +LINEAR_SOLVER_ITER = 30 +RELAXATION_FACTOR_PBFLOW= 1.0 +RELAXATION_FACTOR_RHIECHOW= 1.0 +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +%1 +% Convergence criteria (CAUCHY, RESIDUAL) +% +CONV_FIELD= RMS_VELOCITY-X +% +% Min value of the residual (log10 of the residual) +CONV_RESIDUAL_MINVAL= -14 +% +% Start convergence criteria at iteration number +CONV_STARTITER= 10 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +% Mesh input file +MESH_FILENAME= mesh_channel_256x128.su2 +% +% Mesh input file format (SU2, CGNS, NETCDF_ASCII) +MESH_FORMAT= SU2 +% +% Mesh output file +MESH_OUT_FILENAME= mesh_out.su2 +% +% Restart flow input file +SOLUTION_FILENAME= restart_flow +% +% Output file format (PARAVIEW, TECPLOT, SLT) +TABULAR_FORMAT= CSV + +OUTPUT_FILES= PARAVIEW, RESTART, SURFACE_PARAVIEW +% +% Output file convergence history (w/o extension) +CONV_FILENAME= history +% +% Output file restart flow +RESTART_FILENAME= restart_flow +% +% Output file flow (w/o extension) variables +VOLUME_FILENAME= flow +% +% Output file surface flow coefficient (w/o extension) +SURFACE_FILENAME= surface_flow +% +% Writing solution file frequency +%WRT_SOL_FREQ= 250 +% +% Writing convergence history frequency +%WRT_CON_FREQ= 1 + +SCREEN_OUTPUT= (INNER_ITER, RMS_VELOCITY-X, RMS_MASSFLUX, LIFT,DRAG) +%SCREEN_OUTPUT= (INNER_ITER, RMS_VELOCITY-X, RMS_MASSFLUX, RMS_NU_TILDE, LIFT,DRAG) diff --git a/TestCases/incomp_pressure_based_solver/couette_flow/couette_flow.cfg b/TestCases/incomp_pressure_based_solver/couette_flow/couette_flow.cfg new file mode 100644 index 000000000000..1bf8a56cbeb7 --- /dev/null +++ b/TestCases/incomp_pressure_based_solver/couette_flow/couette_flow.cfg @@ -0,0 +1,223 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Couette flow (co-rotating discs % +% Author: Akshay Koodly % +% Institution: University of Twente % +% File Version 7.0.7 "Blackbird % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +% Physical governing equations (EULER, NAVIER_STOKES, +% WAVE_EQUATION, HEAT_EQUATION, FEM_ELASTICITY, +% POISSON_EQUATION) +SOLVER= INC_NAVIER_STOKES +% +% Mathematical problem (DIRECT, CONTINUOUS_ADJOINT) +MATH_PROBLEM= DIRECT +% +% Restart solution (NO, YES) +RESTART_SOL= NO +% +% If Navier-Stokes, kind of turbulent model (NONE, SA) +KIND_TURB_MODEL= NONE + +KIND_INCOMP_SYSTEM= PRESSURE_BASED + +% -------------------- INCOMPRESSIBLE FREE-STREAM DEFINITION ------------------% +% +% Initial density for incompressible flows +% (1.2886 kg/m^3 by default (air), 998.2 Kg/m^3 (water)) +INC_DENSITY_INIT= 1.0 +% +% Initial velocity for incompressible flows (1.0,0,0 m/s by default) +INC_VELOCITY_INIT= ( 0.0, 0.0, 0.0 ) +% +% Non-dimensionalization scheme for incompressible flows. Options are +% INITIAL_VALUES (default), REFERENCE_VALUES, or DIMENSIONAL. +% INC_*_REF values are ignored unless REFERENCE_VALUES is chosen. +INC_NONDIM= REFERENCE_VALUES +% --------------------------- VISCOSITY MODEL ---------------------------------% +% +% Viscosity model (SUTHERLAND, CONSTANT_VISCOSITY). +VISCOSITY_MODEL= CONSTANT_VISCOSITY +% +% Molecular Viscosity that would be constant (1.716E-5 by default) +% Re : 1 +MU_CONSTANT= 1 +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +% Reference origin for moment computation +REF_ORIGIN_MOMENT_X = 0.25 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +% +% +% Reference area for force coefficients (0 implies automatic calculation) +REF_AREA= 1.0 + +% ----------------------- DYNAMIC MESH DEFINITION -----------------------------% + +% Type of dynamic mesh (NONE, RIGID_MOTION, DEFORMING, ROTATING_FRAME, +% MOVING_WALL, FLUID_STRUCTURE, AEROELASTIC, EXTERNAL) +SURFACE_MOVEMENT= MOVING_WALL + +MARKER_MOVING= Inner_cylinder +% +% +% Coordinates of the motion origin +SURFACE_MOTION_ORIGIN = 0.0 0.0 0.0 +% +% Angular velocity vector (rad/s) about the motion origin +SURFACE_ROTATION_RATE = 0.0 1.0 0.0 +%SURFACE_ROTATION_RATE = 0.0 0.0 1.0 + +% ----------------------- BOUNDARY CONDITION DEFINITION -----------------------% +% +% Marker of the Euler boundary (0 = no marker) +%Non-periodic case +%MARKER_HEATFLUX= ( inner_cylinder, 0.0, outer_cylinder, 0.0 ) +%Periodic case +MARKER_HEATFLUX= ( Inner_cylinder, 0.0, Outer_cylinder, 0.0 ) + +MARKER_SYM= ( Symmetry) + +MARKER_PERIODIC= (Periodic1,Periodic2, 0.0,0.0,0.0, 0.0,-120,0.0, 0.0,0.0,0.0) +%MARKER_PERIODIC= (Periodic1,Periodic2, 0.0,0.0,0.0, 0.0,0,120.0, 0.0,0.0,0.0) +% +% ------------------------ SURFACES IDENTIFICATION ----------------------------% +% +% Marker(s) of the surface in the surface flow solution file +MARKER_PLOTTING = ( Periodic1,Periodic2) +% +% Marker(s) of the surface where the non-dimensional coefficients are evaluated. +MARKER_MONITORING = ( Inner_cylinder, Outer_cylinder ) +% + +% ------------- COMMON PARAMETERS TO DEFINE THE NUMERICAL METHOD --------------% +% +% Numerical method for spatial gradients (GREEN_GAUSS, WEIGHTED_LEAST_SQUARES) +%NUM_METHOD_GRAD_RECON= WEIGHTED_LEAST_SQUARES +NUM_METHOD_GRAD= GREEN_GAUSS +% +% Courant-Friedrichs-Lewy condition of the finest grid +CFL_NUMBER=5.0 +% +% Adaptive CFL number (NO, YES) +CFL_ADAPT= NO +% +% Parameters of the adaptive CFL number (factor down, factor up, CFL min value, +% CFL max value ) +CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) +% +% Runge-Kutta alpha coefficients +RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) +% + +RELAXATION_FACTOR_PBFLOW= 1.0 +RELAXATION_FACTOR_RHIECHOW= 0.0 +LINEAR_SOLVER_ITER_POISSON = 20 +LINEAR_SOLVER_ITER_FLOW = 20 +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +% Linear solver for implicit formulations (BCGSTAB, FGMRES) +LINEAR_SOLVER= FGMRES +% +% Preconditioner of the Krylov linear solver (JACOBI, LINELET, LU_SGS) +LINEAR_SOLVER_PREC= LU_SGS +% +% Minimum error of the linear solver for implicit formulations +LINEAR_SOLVER_ERROR= 1E-6 +% +% Max number of iterations of the linear solver for the implicit formulation +LINEAR_SOLVER_ITER= 25 + +% -------------------------- MULTIGRID PARAMETERS -----------------------------% +% +% Multi-Grid Levels (0 = no multi-grid) +MGLEVEL= 0 +% +% Multi-grid cycle (V_CYCLE, W_CYCLE, FULLMG_CYCLE) +MGCYCLE= W_CYCLE +% +% Multi-Grid PreSmoothing Level +MG_PRE_SMOOTH= ( 1, 2, 3, 3 ) +% +% Multi-Grid PostSmoothing Level +MG_POST_SMOOTH= ( 0, 0, 0, 0 ) +% +% Jacobi implicit smoothing of the correction +MG_CORRECTION_SMOOTH= ( 0, 0, 0, 0 ) +% +% Damping factor for the residual restriction +MG_DAMP_RESTRICTION= 0.95 +% +% Damping factor for the correction prolongation +MG_DAMP_PROLONGATION= 0.95 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +% Convective numerical method (JST, LAX-FRIEDRICH, CUSP, ROE, AUSM, HLLC, +% TURKEL_PREC, MSW) +%CONV_NUM_METHOD_FLOW= FDS +CONV_NUM_METHOD_FLOW= UDS +% +% Spatial numerical order integration (1ST_ORDER, 2ND_ORDER, 2ND_ORDER_LIMITER) +% +MUSCL_FLOW= YES +% +% Time discretization (RUNGE-KUTTA_EXPLICIT, EULER_IMPLICIT, EULER_EXPLICIT) +TIME_DISCRE_FLOW= EULER_IMPLICIT +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +% Number of total iterations +ITER= 10000 +% +% Convergence criteria (CAUCHY, RESIDUAL) +CONV_FIELD= RESIDUAL +% +% Min value of the residual (log10 of the residual) +CONV_RESIDUAL_MINVAL= -10 +% +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +% Mesh input file +MESH_FILENAME= couette_per.su2 +%MESH_FILENAME= couette_per2d.su2 +% +% Mesh input file format (SU2, CGNS, NETCDF_ASCII) +MESH_FORMAT= SU2 +% +% Mesh output file +MESH_OUT_FILENAME= mesh_out.su2 +% +% Restart flow input file +SOLUTION_FILENAME= restart_flow.dat +% +%Output file format(CSV, TECPLOT) +TABULAR_FORMAT= CSV +% +% Output file format (PARAVIEW, TECPLOT, STL) +OUTPUT_FILES= PARAVIEW, SURFACE_PARAVIEW, RESTART +% +% Output file convergence history (w/o extension) +CONV_FILENAME= history +% +% Output file restart flow +RESTART_FILENAME= restart_flow.dat +% +% Output file flow (w/o extension) variables +VOLUME_FILENAME= flowpbhex_per +% +% Output file surface flow coefficient (w/o extension) +SURFACE_FILENAME= surface_flow +% +% Writing solution file frequency +WRT_SOL_FREQ= 25 +% +% Writing convergence history frequency +WRT_CON_FREQ= 1 + +SCREEN_OUTPUT= (INNER_ITER, RMS_VELOCITY-X, LIFT,DRAG) diff --git a/TestCases/incomp_pressure_based_solver/cylinder/incomp_cylinder_V8.cfg b/TestCases/incomp_pressure_based_solver/cylinder/incomp_cylinder_V8.cfg new file mode 100644 index 000000000000..c4a1a40354ea --- /dev/null +++ b/TestCases/incomp_pressure_based_solver/cylinder/incomp_cylinder_V8.cfg @@ -0,0 +1,98 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Steady PB incompressible laminar flow around a cylinder % +% Author: Nitish Anand % +% Institution: VITO NV, Belgium. % +% Date: 2024.02.14 % +% File Version 8.0.0 "Harrier" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= INC_NAVIER_STOKES +KIND_TURB_MODEL= NONE +MATH_PROBLEM= DIRECT +RESTART_SOL= NO +KIND_INCOMP_SYSTEM= PRESSURE_BASED +KIND_PB_ITER= PISO + +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +INC_DENSITY_INIT= 998.2 +INC_VELOCITY_INIT= ( 0.000008, 0.0, 0.0 ) + +% --------------------------- VISCOSITY MODEL ---------------------------------% +% +VISCOSITY_MODEL= CONSTANT_VISCOSITY +MU_CONSTANT= 0.798E-3 + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +REF_ORIGIN_MOMENT_X = 0.25 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +REF_LENGTH= 1.0 +REF_AREA= 1.0 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( cylinder, 0.0 ) +MARKER_FAR= ( farfield ) +MARKER_PLOTTING= ( cylinder ) +MARKER_MONITORING= ( cylinder ) + +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= GREEN_GAUSS +CFL_NUMBER= 10.0 +CFL_ADAPT= NO +CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) +RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) +ITER= 5000 +VENKAT_LIMITER_COEFF= 0.01 + +% -------------------------- MULTIGRID PARAMETERS -----------------------------% +% +MGLEVEL= 0 +MGCYCLE= V_CYCLE +MG_PRE_SMOOTH= ( 1, 2, 3, 3 ) +MG_POST_SMOOTH= ( 1, 1, 1, 1 ) +MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) +MG_DAMP_RESTRICTION= 0.75 +MG_DAMP_PROLONGATION= 0.75 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= UDS +MUSCL_FLOW= YES +SLOPE_LIMITER_FLOW= NONE +JST_SENSOR_COEFF= ( 0.5, 0.04 ) +TIME_DISCRE_FLOW= EULER_IMPLICIT +POISSON_LINEAR_SOLVER_ITER = 20 +LINEAR_SOLVER_ITER = 20 +RELAXATION_FACTOR_PBFLOW= 1.0 +RELAXATION_FACTOR_RHIECHOW= 0.5 + + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_RESIDUAL_MINVAL= -10 +CONV_STARTITER= 10 +CONV_CAUCHY_ELEMS= 100 +CONV_CAUCHY_EPS= 1E-6 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FILENAME= mesh_cylinder_lam.su2 +MESH_FORMAT= SU2 +SOLUTION_FILENAME= solution_flow.dat +TABULAR_FORMAT= CSV +CONV_FILENAME= history +RESTART_FILENAME= restart_flow.dat +VOLUME_FILENAME= flow +SURFACE_FILENAME= surface_flow +OUTPUT_WRT_FREQ= 100 +OUTPUT_FILES= (SURFACE_CSV, RESTART, PARAVIEW) +SCREEN_OUTPUT= (INNER_ITER, RMS_PRESSURE, RMS_VELOCITY-X, LIFT, DRAG) diff --git a/TestCases/incomp_pressure_based_solver/cylinder/lam_cylinder.cfg b/TestCases/incomp_pressure_based_solver/cylinder/lam_cylinder.cfg new file mode 100755 index 000000000000..8fef1010daa2 --- /dev/null +++ b/TestCases/incomp_pressure_based_solver/cylinder/lam_cylinder.cfg @@ -0,0 +1,243 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Steady incompressible laminar flow around a cylinder % +% Author: Akshay Koodly % +% Institution: University of Twente % +% File Version 7.0.7 "Blackbird % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +% Physical governing equations (EULER, NAVIER_STOKES, +% WAVE_EQUATION, HEAT_EQUATION, FEM_ELASTICITY, +% POISSON_EQUATION) +SOLVER= INC_NAVIER_STOKES + +% +% +KIND_INCOMP_SYSTEM= PRESSURE_BASED + + +% Mathematical problem (DIRECT, CONTINUOUS_ADJOINT) +MATH_PROBLEM= DIRECT +% +% Restart solution (NO, YES) +RESTART_SOL= NO + +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +% Initial density for incompressible flows (1.2886 kg/m^3 by default) +INC_DENSITY_INIT= 1.0 +% +% Initial velocity for incompressible flows (1.0,0,0 m/s by default) +%INC_VELOCITY_INIT= ( 0.76604444311, 0.64278760968, 0.0 ) +INC_VELOCITY_INIT= ( 1.0, 0.0, 0.0 ) + +% --------------------------- VISCOSITY MODEL ---------------------------------% +% +% Viscosity model (SUTHERLAND, CONSTANT_VISCOSITY). +VISCOSITY_MODEL= CONSTANT_VISCOSITY +% +% Molecular Viscosity that would be constant (1.716E-5 by default) +MU_CONSTANT= 0.025 +% +% Sutherland Viscosity Ref (1.716E-5 default value for AIR SI) +MU_REF= 1.716E-5 +% +% Sutherland Temperature Ref (273.15 K default value for AIR SI) +MU_T_REF= 273.15 +% +% Sutherland constant (110.4 default value for AIR SI) +SUTHERLAND_CONSTANT= 110.4 +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +% Reference origin for moment computation +REF_ORIGIN_MOMENT_X = 0.25 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +% +% Reference length for pitching, rolling, and yawing non-dimensional moment +REF_LENGTH= 1.0 +% +% Reference area for force coefficients (0 implies automatic calculation) +REF_AREA= 1.0 + +%PRESSURE_REF_COORD= (10.0, 10.0, 0.0) + +%PRESSURE_REF= 0.0 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +% Navier-Stokes wall boundary marker(s) (NONE = no marker) +MARKER_HEATFLUX= ( cylinder, 0.0 ) +% +% Farfield boundary marker(s) (NONE = no marker) +MARKER_FAR= ( farfield ) +% +% Marker(s) of the surface to be plotted or designed +MARKER_PLOTTING= ( cylinder ) +% +% Marker(s) of the surface where the functional (Cd, Cl, etc.) will be evaluated +MARKER_MONITORING= ( cylinder ) + +MARKER_ANALYZE = ( farfield) + +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +% Numerical method for spatial gradients (GREEN_GAUSS, WEIGHTED_LEAST_SQUARES) +NUM_METHOD_GRAD= GREEN_GAUSS +% +% Courant-Friedrichs-Lewy condition of the finest grid +CFL_NUMBER=1.0 +% +% Adaptive CFL number (NO, YES) +CFL_ADAPT= NO +% +% Parameters of the adaptive CFL number (factor down, factor up, CFL min value, +% CFL max value ) +CFL_ADAPT_PARAM= ( 1.5, 0.5, 10.0, 100.0 ) +% +% Runge-Kutta alpha coefficients +RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) +% +% Number of total iterations +ITER= 25000 +% +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +% Linear solver or smoother for implicit formulations (BCGSTAB, FGMRES, SMOOTHER_JACOBI, +% SMOOTHER_ILU, SMOOTHER_LUSGS, +% SMOOTHER_LINELET) +LINEAR_SOLVER= FGMRES +% +% Preconditioner of the Krylov linear solver (ILU, LU_SGS, LINELET, JACOBI) +LINEAR_SOLVER_PREC= ILU +% +% Linael solver ILU preconditioner fill-in level (0 by default) +LINEAR_SOLVER_ILU_FILL_IN= 0 +% +% Minimum error of the linear solver for implicit formulations +LINEAR_SOLVER_ERROR= 1E-12 +% +% Max number of iterations of the linear solver for the implicit formulation +LINEAR_SOLVER_ITER= 20 + +% -------------------------- MULTIGRID PARAMETERS -----------------------------% +% +% Multi-Grid Levels (0 = no multi-grid) +MGLEVEL= 0 +% +% Multi-grid cycle (V_CYCLE, W_CYCLE, FULLMG_CYCLE) +MGCYCLE= V_CYCLE +% +% Multi-grid pre-smoothing level +MG_PRE_SMOOTH= ( 1, 2, 3, 3 ) +% +% Multi-grid post-smoothing level +MG_POST_SMOOTH= ( 1, 1, 1, 1 ) +% +% Jacobi implicit smoothing of the correction +MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) +% +% Damping factor for the residual restriction +MG_DAMP_RESTRICTION= 0.75 +% +% Damping factor for the correction prolongation +MG_DAMP_PROLONGATION= 0.75 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +% Convective numerical method (JST, LAX-FRIEDRICH, CUSP, ROE, AUSM, HLLC, +% TURKEL_PREC, MSW) +CONV_NUM_METHOD_FLOW= UDS +% +% Monotonic Upwind Scheme for Conservation Laws (TVD) in the flow equations. +% Required for 2nd order upwind schemes (NO, YES) +MUSCL_FLOW= YES +% +% Slope limiter (NONE, VENKATAKRISHNAN, VENKATAKRISHNAN_WANG, +% BARTH_JESPERSEN, VAN_ALBADA_EDGE) +SLOPE_LIMITER_FLOW= NONE +% +% 2nd and 4th order artificial dissipation coefficients +JST_SENSOR_COEFF= ( 0.5, 0.02 ) +% +% Time discretization (RUNGE-KUTTA_EXPLICIT, EULER_IMPLICIT, EULER_EXPLICIT) +TIME_DISCRE_FLOW= EULER_IMPLICIT +LINEAR_SOLVER_ITER_POISSON = 25 +LINEAR_SOLVER_ITER_FLOW = 25 +RELAXATION_FACTOR_PBFLOW= 0.5 +RELAXATION_FACTOR_RHIECHOW= 1.0 + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +% Convergence criteria (CAUCHY, RESIDUAL) +% +CONV_FIELD= RMS_VELOCITY-X +% +% Min value of the residual (log10 of the residual) +CONV_RESIDUAL_MINVAL= -12 +% +% Start convergence criteria at iteration number +CONV_STARTITER= 10 +% +% -------------------- TURBULENT NUMERICAL METHOD DEFINITION ------------------% +% +% Convective numerical method (SCALAR_UPWIND) +CONV_NUM_METHOD_TURB= SCALAR_UPWIND +% +% Monotonic Upwind Scheme for Conservation Laws (TVD) in the turbulence equations. +% Required for 2nd order upwind schemes (NO, YES) +MUSCL_TURB= NO +% +% Slope limiter (VENKATAKRISHNAN, MINMOD) +SLOPE_LIMITER_TURB= VENKATAKRISHNAN +% +% Time discretization (EULER_IMPLICIT) +TIME_DISCRE_TURB= EULER_IMPLICIT + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +% Mesh input file +%MESH_FILENAME= ../mesh/mesh_cylinder_lam_65.su2 +%MESH_FILENAME= ../mesh/mesh_cylinder_lam_129.su2 +MESH_FILENAME= ../mesh/mesh_cylinder_lam_257.su2 +%MESH_FILENAME= ../mesh/mesh_cylinder_lam_513.su2 +% +% Mesh input file format (SU2, CGNS, NETCDF_ASCII) +MESH_FORMAT= SU2 +% +% Restart flow input file +SOLUTION_FILENAME= restart_flow +% +% Output file format (PARAVIEW, TECPLOT) +TABULAR_FORMAT= CSV +% +OUTPUT_FILES= RESTART PARAVIEW SURFACE_PARAVIEW +% +% Output file convergence history (w/o extension) +CONV_FILENAME= history +% +% Output file restart flow +RESTART_FILENAME= restart_flow +% +% Output file flow (w/o extension) variables +VOLUME_FILENAME= flow +% +% Output file surface flow coefficient (w/o extension) +SURFACE_FILENAME= surface_flow +% +% Writing solution file frequency +WRT_SOL_FREQ= 200 +% +% Writing convergence history frequency +WRT_CON_FREQ= 1 + +SCREEN_OUTPUT= (INNER_ITER, RMS_VELOCITY-X, RMS_MASSFLUX, LIFT,DRAG) +% +%1.547135 +%1.517068 +%1.505034 +%1.501479 diff --git a/TestCases/incomp_pressure_based_solver/flatplate_turb/turb_flatplate.cfg b/TestCases/incomp_pressure_based_solver/flatplate_turb/turb_flatplate.cfg new file mode 100755 index 000000000000..872f63084e0b --- /dev/null +++ b/TestCases/incomp_pressure_based_solver/flatplate_turb/turb_flatplate.cfg @@ -0,0 +1,298 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Turbulent flow over flat plate with zero pressure gradient % +% Author: Akshay Koodly % +% Institution: University of Twente % +% File Version 7.0.7 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +% Physical governing equations (EULER, NAVIER_STOKES, +% WAVE_EQUATION, HEAT_EQUATION, FEM_ELASTICITY, +% POISSON_EQUATION) +SOLVER= INC_RANS +% +% If Navier-Stokes, kind of turbulent model (NONE, SA) +KIND_TURB_MODEL= SA + +% Mathematical problem (DIRECT, CONTINUOUS_ADJOINT) +MATH_PROBLEM= DIRECT +% +% Restart solution (NO, YES) +RESTART_SOL=NO +% +% Incompressible solver (DENSITY_BASED, PRESSURE_BASED) +% DENSITY_BASED is chosen by default +KIND_INCOMP_SYSTEM= PRESSURE_BASED + +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +% Density model within the incompressible flow solver. +% Options are CONSTANT (default), BOUSSINESQ, or VARIABLE. If VARIABLE, +% an appropriate fluid model must be selected. +INC_DENSITY_MODEL= CONSTANT +% +% Solve the energy equation in the incompressible flow solver +INC_ENERGY_EQUATION = NO +% +% Initial density for incompressible flows (1.2886 kg/m^3 by default) +INC_DENSITY_INIT= 1.32905 +% +% Initial velocity for incompressible flows (1.0,0,0 m/s by default) +INC_VELOCITY_INIT= ( 69.4448, 0.0, 0.0 ) +% +% Initial temperature for incompressible flows that include the +% energy equation (288.15 K by default). Value is ignored if +% INC_ENERGY_EQUATION is false. +INC_TEMPERATURE_INIT= 300.0 +% +% Non-dimensionalization scheme for incompressible flows. Options are +% INITIAL_VALUES (default), REFERENCE_VALUES, or DIMENSIONAL. +% INC_*_REF values are ignored unless REFERENCE_VALUES is chosen. +INC_NONDIM= INITIAL_VALUES +% +% Reference density for incompressible flows (1.0 kg/m^3 by default) +INC_DENSITY_REF= 1.0 +% +% Reference velocity for incompressible flows (1.0 m/s by default) +INC_VELOCITY_REF= 1.0KIND_PB_ITER=PISO +% +% Reference temperature for incompressible flows that include the +% energy equation (1.0 K by default) +INC_TEMPERATURE_REF = 1.0 +% +% List of inlet types for incompressible flows. List length must +% match number of inlet markers. Options: VELOCITY_INLET, PRESSURE_INLET. +INC_INLET_TYPE= VELOCITY_INLET + +% --------------------------- VISCOSITY MODEL ---------------------------------% +% +% Viscosity model (SUTHERLAND, CONSTANT_VISCOSITY). +VISCOSITY_MODEL= CONSTANT_VISCOSITY +% +% Molecular Viscosity that would be constant (1.716E-5 by default) +MU_CONSTANT= 1.84592e-05 +% +% Sutherland Viscosity Ref (1.716E-5 default value for AIR SI) +MU_REF= 1.716E-5 +% +% Sutherland Temperature Ref (273.15 K default value for AIR SI) +MU_T_REF= 273.15 +% +% Sutherland constant (110.4 default value for AIR SI) +SUTHERLAND_CONSTANT= 110.4 + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +% Reference origin for moment computation +REF_ORIGIN_MOMENT_X = 0.25 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +% +% Reference length for pitching, rolling, and yawing non-dimensional moment +REF_LENGTH= 1.0 +% +% Reference area for force coefficients (0 implies automatic calculation) +REF_AREA= 2.0 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +% Navier-Stokes wall boundary marker(s) (NONE = no marker) +MARKER_HEATFLUX= ( wall, 0.0 ) +% +% Inlet boundary marker(s) (NONE = no marker) +% Format: ( inlet marker, total temperature, total pressure, flow_direction_x, +% flow_direction_y, flow_direction_z, ... ) +MARKER_INLET= ( inlet, 300.0, 69.4448, 1.0, 0.0, 0.0 ) +% +% Outlet boundary marker(s) (NONE = no marker) +% Format: ( outlet marker, back pressure, ... ) +MARKER_OUTLET= ( outlet, 0.0, farfield, 0.0 ) +% +INC_OUTLET_TYPE= PRESSURE_OUTLET,PRESSURE_OUTLET +% +% Symmetry boundary marker(s) (NONE = no marker) +MARKER_SYM= ( symmetry ) +% +% Marker(s) of the surface to be plotted or designed +MARKER_PLOTTING= ( wall ) +% +% Marker(s) of the surface where the functional (Cd, Cl, etc.) will be evaluated +MARKER_MONITORING= ( wall ) + +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +% Numerical method for spatial gradients (GREEN_GAUSS, LEAST_SQUARES, +% WEIGHTED_LEAST_SQUARES) +NUM_METHOD_GRAD= GREEN_GAUSS +% +% Courant-Friedrichs-Lewy condition of the finest grid +CFL_NUMBER= 1 +% +% Adaptive CFL number (NO, YES) +CFL_ADAPT= NO +% +% Parameters of the adaptive CFL number (factor down, factor up, CFL min value, +% CFL max value ) +CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) +% +% Runge-Kutta alpha coefficients +RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) +% +% Number of total iterations +ITER= 15000 + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +% Linear solver for implicit formulations (BCGSTAB, FGMRES) +LINEAR_SOLVER= FGMRES +% +% Preconditioner of the Krylov linear solver (JACOBI, LINELET, LU_SGS) +LINEAR_SOLVER_PREC= ILU +% +% Linael solver ILU preconditioner fill-in level (0 by default) +LINEAR_SOLVER_ILU_FILL_IN= 0 +% +% Minimum error of the linear solver for implicit formulations +LINEAR_SOLVER_ERROR= 1E-12 +% +% Max number of iterations of the linear solver for the implicit formulation +LINEAR_SOLVER_ITER= 20 + +% ----------------------- SLOPE LIMITER DEFINITION ----------------------------% +% +% Coefficient for the limiter +VENKAT_LIMITER_COEFF= 0.1 +% +% Coefficient for the sharp edges limiter +ADJ_SHARP_LIMITER_COEFF= 3.0 +% +% Reference coefficient (sensitivity) for detecting sharp edges. +REF_SHARP_EDGES= 3.0 +% +% Remove sharp edges from the sensitivity evaluation (NO, YES) +SENS_REMOVE_SHARP= NO + +% -------------------------- MULTIGRID PARAMETERS -----------------------------% +% +% Multi-Grid Levels (0 = no multi-grid) +MGLEVEL= 0 +% +% Multi-grid cycle (V_CYCLE, W_CYCLE, FULLMG_CYCLE) +MGCYCLE= V_CYCLE +% +% Multi-grid pre-smoothing level +MG_PRE_SMOOTH= ( 1, 1, 1, 1 ) +% +% Multi-grid post-smoothing level +MG_POST_SMOOTH= ( 0, 0, 0, 0 ) +% +% Jacobi implicit smoothing of the correction +MG_CORRECTION_SMOOTH= ( 0, 0, 0, 0 ) +% +% Damping factor for the residual restriction +MG_DAMP_RESTRICTION= 0.8 +% +% Damping factor for the correction prolongation +MG_DAMP_PROLONGATION= 0.8 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +% Convective numerical method (JST, JST_KE, JST_MAT, LAX-FRIEDRICH, CUSP, ROE, AUSM, +% AUSMPLUSUP, AUSMPLUSUP2, AUSMPWPLUS, HLLC, TURKEL_PREC, +% SW, MSW, FDS, SLAU, SLAU2, L2ROE, LMROE, UDS) +CONV_NUM_METHOD_FLOW= UDS +% +% Monotonic Upwind Scheme for Conservation Laws (TVD) in the flow equations. +% Required for 2nd order upwind schemes (NO, YES) +MUSCL_FLOW= YES +% +% Slope limiter (NONE, VENKATAKRISHNAN, VENKATAKRISHNAN_WANG, +% BARTH_JESPERSEN, VAN_ALBADA_EDGE) +SLOPE_LIMITER_FLOW= NONE +% +% 2nd and 4th order artificial dissipation coefficients +JST_SENSOR_COEFF= ( 0.5, 0.02 ) +% +% Time discretization (RUNGE-KUTTA_EXPLICIT, EULER_IMPLICIT, EULER_EXPLICIT) +TIME_DISCRE_FLOW= EULER_IMPLICIT + +% -------------------- TURBULENT NUMERICAL METHOD DEFINITION ------------------% +% +% Convective numerical method (SCALAR_UPWIND) +CONV_NUM_METHOD_TURB= SCALAR_UPWIND +% +% Monotonic Upwind Scheme for Conservation Laws (TVD) in the turbulence equations. +% Required for 2nd order upwind schemes (NO, YES) +MUSCL_TURB= NO +% +% Slope limiter (VENKATAKRISHNAN, MINMOD) +SLOPE_LIMITER_TURB= VENKATAKRISHNAN +% +% Time discretization (EULER_IMPLICIT) +TIME_DISCRE_TURB= EULER_IMPLICIT +% +% Number of iterations for the poisson solver +LINEAR_SOLVER_ITER_POISSON = 25 +% +% Number of iterations for the flow solver +LINEAR_SOLVER_ITER_FLOW = 25 + +RELAXATION_FACTOR_PBFLOW= 1.0 +RELAXATION_FACTOR_RHIECHOW= 1.0 + + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +% Convergence criteria (CAUCHY, RESIDUAL) +% +CONV_FIELD= RMS_VELOCITY-X +% +% Min value of the residual (log10 of the residual) +CONV_RESIDUAL_MINVAL= -14 +% +% Start convergence criteria at iteration number +CONV_STARTITER= 10 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +% Mesh input file +MESH_FILENAME= mesh/mesh_flatplate_turb_69x49.su2 +% +% Mesh input file format (SU2, CGNS, NETCDF_ASCII) +MESH_FORMAT= SU2 +% +% Mesh output file +MESH_OUT_FILENAME= mesh_out.su2 +% +% Restart flow input file +SOLUTION_FILENAME= restart_flowo2 +% +% Output file format (PARAVIEW, TECPLOT, SLT) +TABULAR_FORMAT= CSV + +OUTPUT_FILES= PARAVIEW, RESTART, SURFACE_PARAVIEW +% +% Output file convergence history (w/o extension) +CONV_FILENAME= historyc1l4 +% +% Output file restart flow +RESTART_FILENAME= restart_flowo2 +% +% Output file flow (w/o extension) variables +VOLUME_FILENAME= flow_l4o2 +% +% Output file surface flow coefficient (w/o extension) +SURFACE_FILENAME= surface_flow_l4o2 +% +% Writing solution file frequency +WRT_SOL_FREQ= 250 +% +% Writing convergence history frequency +WRT_CON_FREQ= 1 + +%SCREEN_OUTPUT= (INNER_ITER, RMS_VELOCITY-X, RMS_MASSFLUX, RMS_TKE, LIFT,DRAG) +SCREEN_OUTPUT= (INNER_ITER, RMS_VELOCITY-X, RMS_MASSFLUX, RMS_NU_TILDE, LIFT,DRAG) diff --git a/TestCases/incomp_pressure_based_solver/hydrofoil_naca0012/incomp_NACA0012_PB_V8.cfg b/TestCases/incomp_pressure_based_solver/hydrofoil_naca0012/incomp_NACA0012_PB_V8.cfg new file mode 100644 index 000000000000..e60704b08d43 --- /dev/null +++ b/TestCases/incomp_pressure_based_solver/hydrofoil_naca0012/incomp_NACA0012_PB_V8.cfg @@ -0,0 +1,102 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Incompressible flow hydrofoil 5 degrees % +% Author: Nitish Anand % +% Institution: VITO NV Belgium % +% Date: 2024/02/14 % +% File Version 8.0.0 "Harrier" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= INC_EULER +MATH_PROBLEM= DIRECT +KIND_INCOMP_SYSTEM= PRESSURE_BASED +KIND_PB_ITER= SIMPLE +RESTART_SOL= NO + +VISCOSITY_MODEL=CONSTANT_VISCOSITY +MU_CONSTANT= 0.01 +FLUID_MODEL= INC_IDEAL_GAS + +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +INC_DENSITY_INIT= 998.2 +INC_VELOCITY_INIT= ( 1.0, 0.0, 0.0 ) +INC_INLET_TYPE= VELOCITY_INLET +INC_INLET_DAMPING= 0.1 +INC_OUTLET_TYPE= PRESSURE_OUTLET +INC_OUTLET_DAMPING= 0.1 + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +REF_ORIGIN_MOMENT_X = 0.25 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +REF_LENGTH= 1.0 +REF_AREA= 1.0 + +% ----------------------- BOUNDARY CONDITION DEFINITION -----------------------% +% +%MARKER_HEATFLUX= (airfoil, 0.0) +MARKER_EULER= ( airfoil, lower_wall, upper_wall ) +MARKER_INLET= ( inlet, 0.0, 1.0, 1.0, 0.0, 0.0 ) +MARKER_OUTLET= ( outlet, 0.0 ) +MARKER_PLOTTING= ( airfoil ) +MARKER_MONITORING= ( airfoil ) + +% ------------- COMMON PARAMETERS TO DEFINE THE NUMERICAL METHOD --------------% +% +NUM_METHOD_GRAD= GREEN_GAUSS +CFL_NUMBER= 1.0 +CFL_ADAPT= NO +CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) +RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) +ITER= 9999 + + +% -------------------------- MULTIGRID PARAMETERS -----------------------------% +% +MGLEVEL= 0 +MGCYCLE= W_CYCLE +MG_PRE_SMOOTH= ( 1, 2, 3, 3 ) +MG_POST_SMOOTH= ( 1, 1, 1, 1 ) +MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) +MG_DAMP_RESTRICTION= 0.85 +MG_DAMP_PROLONGATION= 0.85 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= UDS +MUSCL_FLOW= YES +SLOPE_LIMITER_FLOW= NONE +VENKAT_LIMITER_COEFF= 0.0002 +JST_SENSOR_COEFF= ( 0.5, 0.04 ) +TIME_DISCRE_FLOW= EULER_IMPLICIT +POISSON_LINEAR_SOLVER_ITER = 20 +LINEAR_SOLVER_ITER = 20 +RELAXATION_FACTOR_PBFLOW= 1.0 +RELAXATION_FACTOR_RHIECHOW= 0.5 + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_RESIDUAL_MINVAL= -99 +CONV_STARTITER= 10 +CONV_CAUCHY_ELEMS= 50 +CONV_CAUCHY_EPS= 1E-6 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FILENAME= mesh_NACA0012_5deg_6814.su2 +MESH_FORMAT= SU2 +SOLUTION_FILENAME= solution_flow.dat +TABULAR_FORMAT= CSV +CONV_FILENAME= history +RESTART_FILENAME= restart_flow.dat +VOLUME_FILENAME= flow +SURFACE_FILENAME= surface_flow +OUTPUT_WRT_FREQ= 200 +SCREEN_OUTPUT= (INNER_ITER, RMS_VELOCITY-X, RMS_VELOCITY-Y, RMS_MASSFLUX, FORCE-X_ON_SURFACE, FORCE-Y_ON_SURFACE, REFERENCE_FORCE) +OUTPUT_FILES= (SURFACE_CSV, RESTART, PARAVIEW) diff --git a/TestCases/incomp_pressure_based_solver/lid_driven_cavity/liddrivencavity.cfg b/TestCases/incomp_pressure_based_solver/lid_driven_cavity/liddrivencavity.cfg new file mode 100644 index 000000000000..9c82dd8a9023 --- /dev/null +++ b/TestCases/incomp_pressure_based_solver/lid_driven_cavity/liddrivencavity.cfg @@ -0,0 +1,297 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Incompressible and laminar lid driven cavity % +% Author: Akshay Koodly % +% Institution: University of Twente % +% File Version 7.0.7 "Blackbird % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +% Physical governing equations (EULER, NAVIER_STOKES, +% WAVE_EQUATION, HEAT_EQUATION, FEM_ELASTICITY, +% POISSON_EQUATION) + +SOLVER= INC_NAVIER_STOKES +% +% Incompressible solver (DENSITY_BASED, PRESSURE_BASED) +% DENSITY_BASED is chosen by default +KIND_INCOMP_SYSTEM= PRESSURE_BASED +% +% Gravity force (NO, YES) +GRAVITY_FORCE= NO +% +% Mathematical problem (DIRECT, CONTINUOUS_ADJOINT) +MATH_PROBLEM= DIRECT +% +% Restart solution (NO, YES) +RESTART_SOL= NO + +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +% Density model within the incompressible flow solver. +% Options are CONSTANT (default), BOUSSINESQ, or VARIABLE. If VARIABLE, +% an appropriate fluid model must be selected. +INC_DENSITY_MODEL= CONSTANT +% +% Solve the energy equation in the incompressible flow solver +INC_ENERGY_EQUATION = NO +% +% Initial density for incompressible flows (1.2886 kg/m^3 by default) +INC_DENSITY_INIT= 1.0 +% +% Reference density for incompressible flows (1.0 kg/m^3 by default) +INC_DENSITY_REF= 1.0 +% +% Reference velocity for incompressible flows (1.0 m/s by default) +INC_VELOCITY_REF= 1.0 +% +% Reference temperature for incompressible flows that include the +% energy equation (1.0 K by default) +INC_TEMPERATURE_REF = 1.0 +% Initial velocity for incompressible flows (1.0,0,0 m/s by default) +INC_VELOCITY_INIT= ( 1.0, 0.0, 0.0 ) + +% Non-dimensionalization scheme for incompressible flows. Options are +% INITIAL_VALUES (default), REFERENCE_VALUES, or DIMENSIONAL. +% INC_*_REF values are ignored unless REFERENCE_VALUES is chosen. +%INC_NONDIM= REFERENCE_VALUES +% +% --------------------------- VISCOSITY MODEL ---------------------------------% +% +% Viscosity model (SUTHERLAND, CONSTANT_VISCOSITY). +VISCOSITY_MODEL= CONSTANT_VISCOSITY +% +% Molecular Viscosity thsat would be constant (1.716E-5 by default) +MU_CONSTANT= 2.5E-3 +% +% +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +% Reference origin for moment computation +REF_ORIGIN_MOMENT_X = 0.25 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +% +% Reference length for pitching, rolling, and yawing non-dimensional moment +REF_LENGTH= 1.0 +% +% Reference area for force coefficients (0 implies automatic calculation) +REF_AREA= 1.0 + +% ----------------------- BOUNDARY CONDITION DEFINITION -----------------------% +% +% Euler wall boundary marker(s) (NONE = no marker) +MARKER_HEATFLUX= ( Bottom,0.0 , Left, 0.0, Right, 0.0, Top, 0.0) +% +% Incompressible: (inlet marker, NULL, velocity magnitude, flow_direction_x, +% flow_direction_y, flow_direction_z, ... ) where flow_direction is +% a unit vector. +%MARKER_INLET= (Left, 0.0, 1.0, 1.0, 0.0, 0.0 ) +% +%INC_INLET_TYPE= VELOCITY_INLET +% +% Outlet boundary marker(s) (NONE = no marker) +%MARKER_OUTLET= ( Right, 0.0,Top, 0.0, Bottom, 0.0 ) +% +%INC_OUTLET_TYPE= PRESSURE_OUTLET, OPEN, OPEN +% Outlet boundary marker(s) (NONE = no marker) +%MARKER_OUTLET= ( Right, 0.0, Top, 0.0 ) +% +%INC_OUTLET_TYPE= PRESSURE_OUTLET,PRESSURE_OUTLET +% +% Symmetry boundary marker(s) (NONE = no marker) +%MARKER_EULER= ( Bottom) +% +%MARKER_SYM= (Bottom) +% Marker(s) of the surface that is going to be analyzed in detail (massflow, average pressure, distortion, etc) +%MARKER_ANALYZE = ( Left, Right, Top, Bottom ) + +% Method to compute the average value in MARKER_ANALYZE (AREA, MASSFLUX). +%MARKER_ANALYZE_AVERAGE = AREA + +%MARKER_PLOTTING= ( Bottom, Top ) +% +% Marker(s) of the surface where the functional (Cd, Cl, etc.) will be evaluated +MARKER_MONITORING= ( Bottom, Top) + +% ----------------------- DYNAMIC MESH DEFINITION -----------------------------% + +% Type of dynamic mesh (NONE, RIGID_MOTION, DEFORMING, ROTATING_FRAME, +% MOVING_WALL, FLUID_STRUCTURE, AEROELASTIC, EXTERNAL) +SURFACE_MOVEMENT= MOVING_WALL + +MARKER_MOVING= Top +% +% +% Coordinates of the motion origin +SURFACE_MOTION_ORIGIN = 0.0 0.0 0.0 +% +% Angular velocity vector (rad/s) about the motion origin +SURFACE_ROTATION_RATE = 0.0 0.0 0.0 +SURFACE_TRANSLATION_RATE = 1.0 0.0 0.0 + +% ------------- COMMON PARAMETERS TO DEFINE THE NUMERICAL METHOD --------------% +% +% Numerical method for spatial gradients (GREEN_GAUSS, WEIGHTED_LEAST_SQUARES) +%NUM_METHOD_GRAD= GREEN_GAUSS +NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES +% +% Courant-Friedrichs-Lewy condition of the finest grid +CFL_NUMBER= 1.0 +% +% Adaptive CFL number (NO, YES) +CFL_ADAPT= NO +% +% Parameters of the adaptive CFL number (factor down, factor up, CFL min value, +% CFL max value ) +CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) +% +% Runge-Kutta alpha coefficients +RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) +% +% Number of total iterations +EXT_ITER= 10000 + +% -------------------------- MULTIGRID PARAMETERS -----------------------------% +% +% Multi-Grid Levels (0 = no multi-grid) +MGLEVEL= 0 +% +% Multi-grid cycle (V_CYCLE, W_CYCLE, FULLMG_CYCLE) +MGCYCLE= V_CYCLE +% +% Multi-grid pre-smoothing level +MG_PRE_SMOOTH= ( 1, 2, 3, 3 ) +% +% Multi-grid post-smoothing level +MG_POST_SMOOTH= ( 1, 1, 1, 1 ) +% +% Jacobi implicit smoothing of the correction +MG_CORRECTION_SMOOTH= ( 1, 1, 1, 1 ) +% +% Damping factor for the residual restriction +MG_DAMP_RESTRICTION= 0.85 +% +% Damping factor for the correction prolongation +MG_DAMP_PROLONGATION= 0.85 + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +% Linear solver for implicit formulations (BCGSTAB, FGMRES) +LINEAR_SOLVER= FGMRES +% +% Preconditioner of the Krylov linear solver (JACOBI, LINELET, LU_SGS) +LINEAR_SOLVER_PREC= LU_SGS +% +% Minimum error of the linear solver for implicit formulations +LINEAR_SOLVER_ERROR= 1E-6 +% +% Max number of iterations of the linear solver for the implicit formulation +LINEAR_SOLVER_ITER= 20 +% +% Number of iterations for the poisson solver +LINEAR_SOLVER_ITER_POISSON= 50 +% +% Number of iterations for the flow solver +LINEAR_SOLVER_ITER_FLOW= 25 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +% Convective numerical method (JST, JST_KE, JST_MAT, LAX-FRIEDRICH, CUSP, ROE, AUSM, +% AUSMPLUSUP, AUSMPLUSUP2, AUSMPWPLUS, HLLC, TURKEL_PREC, +% SW, MSW, FDS, SLAU, SLAU2, L2ROE, LMROE, UDS) +CONV_NUM_METHOD_FLOW= UDS +% +% Monotonic Upwind Scheme for Conservation Laws (TVD) in the flow equations. +% Required for 2nd order upwind schemes (NO, YES) +MUSCL_FLOW= YES +% +% Slope limiter (VENKATAKRISHNAN, MINMOD) +SLOPE_LIMITER_FLOW= NONE +% +% Coefficient for the limiter (smooth regions) +VENKAT_LIMITER_COEFF= 0.03 +% +% 2nd and 4th order artificial dissipation coefficients +JST_SENSOR_COEFF= ( 0.5, 0.02 ) +% +% Time discretization (RUNGE-KUTTA_EXPLICIT, EULER_IMPLICIT, EULER_EXPLICIT) +TIME_DISCRE_FLOW= EULER_IMPLICIT + +% -------------------- TURBULENT NUMERICAL METHOD DEFINITION ------------------% +% +% Convective numerical method (SCALAR_UPWIND) +CONV_NUM_METHOD_TURB= SCALAR_UPWIND +% +% Monotonic Upwind Scheme for Conservation Laws (TVD) in the turbulence equations. +% Required for 2nd order upwind schemes (NO, YES) +MUSCL_TURB= NO +% +% Slope limiter (VENKATAKRISHNAN, MINMOD) +SLOPE_LIMITER_TURB= VENKATAKRISHNAN +% +% Time discretization (EULER_IMPLICIT) +TIME_DISCRE_TURB= EULER_IMPLICIT +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% Convergence criteria (CAUCHY, RESIDUAL) +% +CONV_CRITERIA= RESIDUAL +% +% Residual reduction (order of magnitude with respect to the initial value) +RESIDUAL_REDUCTION= 7 +% +% Min value of the residual (log10 of the residual) +RESIDUAL_MINVAL= -10 +% +% Start Cauchy criteria at iteration number +STARTCONV_ITER= 10 +% +% Number of elements to apply the criteria +CAUCHY_ELEMS= 50 +% +% Epsilon to control the series convergence +CAUCHY_EPS= 1E-6 +% +% Function to apply the criteria (LIFT, DRAG, SENS_GEOMETRY, SENS_MACH, +% DELTA_LIFT, DELTA_DRAG) +CAUCHY_FUNC_FLOW= DRAG + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +% Mesh input file +%MESH_FILENAME= Square_8x8.su2 +MESH_FILENAME= ../Square_65x65.su2 +% +% Mesh input file format (SU2, CGNS, NETCDF_ASCII) +MESH_FORMAT= SU2 +% +% Restart flow input file +SOLUTION_FLOW_FILENAME= restart_flow.dat +% +% Output file format (PARAVIEW, TECPLOT) +OUTPUT_FORMAT= PARAVIEW +% +% Output file convergence history (w/o extension) +CONV_FILENAME= history15_25 +% +% Output file restart flow +RESTART_FLOW_FILENAME= restart_flow.dat +% +% Output file flow (w/o extension) variables +VOLUME_FLOW_FILENAME= squaredb128 +% +% Output file surface flow coefficient (w/o extension) +SURFACE_FLOW_FILENAME= surface_flow +% +% Writing solution file frequency +WRT_SOL_FREQ= 50 +% +% Writing convergence history frequency +WRT_CON_FREQ= 1 +% Write binary restart files (YES, NO) +WRT_BINARY_RESTART= NO +READ_BINARY_RESTART= NO +WRT_PERFORMANCE= YES diff --git a/TestCases/incomp_pressure_based_solver/turb_naca0012/turb_naca0012_v7.cfg b/TestCases/incomp_pressure_based_solver/turb_naca0012/turb_naca0012_v7.cfg new file mode 100644 index 000000000000..16e984666ad7 --- /dev/null +++ b/TestCases/incomp_pressure_based_solver/turb_naca0012/turb_naca0012_v7.cfg @@ -0,0 +1,247 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: 2D NACA 0012 Airfoil Validation Case (incompressible) % +% http://turbmodels.larc.nasa.gov/naca0012_val_sa.html % +% Author: Akshay Koodly % +% Institution: University of Twente % +% File Version 7.0.7 "Blackbird % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +% Physical governing equations (EULER, NAVIER_STOKES, +% WAVE_EQUATION, HEAT_EQUATION, FEM_ELASTICITY, +% POISSON_EQUATION) +SOLVER= INC_RANS +% +% Specify turbulent model (NONE, SA, SA_NEG, SST) +KIND_TURB_MODEL= SST +% +% Mathematical problem (DIRECT, CONTINUOUS_ADJOINT) +MATH_PROBLEM= DIRECT +% +% Restart solution (NO, YES) +RESTART_SOL= NO +% +% Incompressible solver (DENSITY_BASED, PRESSURE_BASED) +% DENSITY_BASED is chosen by default +%KIND_INCOMP_SYSTEM= PRESSURE_BASED +% -------------------- INCOMPRESSIBLE FREE-STREAM DEFINITION ------------------% +% +% Free-stream density (1.2886 Kg/m^3 (air), 998.2 Kg/m^3 (water)) +INC_DENSITY_INIT= 2.13163 +% +% Initial velocity for incompressible flows (1.0,0,0 m/s by default) +% +% AoA 0.0 deg +INC_VELOCITY_INIT= ( 52.1572, 0.0, 0.0 ) + +% AoA 4.0 deg +INC_VELOCITY_INIT= ( 52.0301476822, 3.63830235237, 0.0 ) +% +% AoA 10 deg +%INC_VELOCITY_INIT= ( 51.36481493540834, 9.0570027322096198, 0.0 ) +% +% AoA 15 deg +%INC_VELOCITY_INIT= (50.3799865069, 13.4992766992, 0.0 ) +% Non-dimensionalization scheme for incompressible flows. Options are +% INITIAL_VALUES (default), REFERENCE_VALUES, or DIMENSIONAL. +% INC_*_REF values are ignored unless REFERENCE_VALUES is chosen. +INC_NONDIM= INITIAL_VALUES +% +% Reference density for incompressible flows (1.0 kg/m^3 by default) +INC_DENSITY_REF= 1.0 +% +% Reference velocity for incompressible flows (1.0 m/s by default) +INC_VELOCITY_REF= 1.0 +% +% Reference temperature for incompressible flows that include the +% energy equation (1.0 K by default) +INC_TEMPERATURE_REF = 1.0 +% --------------------------- VISCOSITY MODEL ---------------------------------% +% +% Viscosity model (SUTHERLAND, CONSTANT_VISCOSITY). +VISCOSITY_MODEL= CONSTANT_VISCOSITY +% +% Molecular Viscosity that would be constant (1.716E-5 by default) +MU_CONSTANT= 1.853e-05 + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +% Reference origin for moment computation +REF_ORIGIN_MOMENT_X = 0.25 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +% +% Reference length for pitching, rolling, and yawing non-dimensional moment +REF_LENGTH= 1.0 +% +% Reference area for force coefficients (0 implies automatic calculation) +REF_AREA= 1.0 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +% Navier-Stokes wall boundary marker(s) (NONE = no marker) +MARKER_HEATFLUX= ( airfoil, 0.0 ) +% +% Farfield boundary marker(s) (NONE = no marker) +MARKER_FAR= ( farfield-1, farfield-2 ) +% +% Marker(s) of the surface to be plotted or designed +MARKER_PLOTTING= ( airfoil ) +% +% Marker(s) of the surface where the functional (Cd, Cl, etc.) will be evaluated +MARKER_MONITORING= ( airfoil ) + +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +% Numerical method for spatial gradients (GREEN_GAUSS, WEIGHTED_LEAST_SQUARES) +NUM_METHOD_GRAD= GREEN_GAUSS +% +% Courant-Friedrichs-Lewy condition of the finest grid +CFL_NUMBER= 1 +% +% Adaptive CFL number (NO, YES) +CFL_ADAPT= NO +% +% Parameters of the adaptive CFL number (factor down, factor up, CFL min value, +% CFL max value ) +CFL_ADAPT_PARAM= ( 1.5, 0.5, 10.0, 100.0 ) +% +% Maximum Delta Time in local time stepping simulations +MAX_DELTA_TIME= 1E6 +% +% Runge-Kutta alpha coefficients +RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) +% +% Number of total iterations +ITER= 45000 + +% ----------------------- SLOPE LIMITER DEFINITION ----------------------------% +% +% Coefficient for the limiter +VENKAT_LIMITER_COEFF= 0.05 +% +% Coefficient for the sharp edges limiter +ADJ_SHARP_LIMITER_COEFF= 3.0 +% +% Reference coefficient (sensitivity) for detecting sharp edges. +REF_SHARP_EDGES= 3.0 +% +% Remove sharp edges from the sensitivity evaluation (NO, YES) +SENS_REMOVE_SHARP= NO + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +% Linear solver for implicit formulations (BCGSTAB, FGMRES) +LINEAR_SOLVER= FGMRES +% +% Preconditioner of the Krylov linear solver (JACOBI, LINELET, LU_SGS) +LINEAR_SOLVER_PREC= ILU +% +% Linael solver ILU preconditioner fill-in level (0 by default) +LINEAR_SOLVER_ILU_FILL_IN= 0 +% +% Minimum error of the linear solver for implicit formulations +LINEAR_SOLVER_ERROR= 1E-10 +% +% Max number of iterations of the linear solver for the implicit formulation +LINEAR_SOLVER_ITER= 10 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +% Convective numerical method (JST, JST_KE, JST_MAT, LAX-FRIEDRICH, CUSP, ROE, AUSM, +% AUSMPLUSUP, AUSMPLUSUP2, AUSMPWPLUS, HLLC, TURKEL_PREC, +% SW, MSW, FDS, SLAU, SLAU2, L2ROE, LMROE, UDS) +CONV_NUM_METHOD_FLOW= UDS +% +% Monotonic Upwind Scheme for Conservation Laws (TVD) in the flow equations. +% Required for 2nd order upwind schemes (NO, YES) +MUSCL_FLOW= YES +% +% Slope limiter (VENKATAKRISHNAN, MINMOD) +SLOPE_LIMITER_FLOW= NONE +% +% 2nd and 4th order artificial dissipation coefficients +JST_SENSOR_COEFF= ( 0.0, 0.02 ) +% +% Time discretization (RUNGE-KUTTA_EXPLICIT, EULER_IMPLICIT, EULER_EXPLICIT) +TIME_DISCRE_FLOW= EULER_IMPLICIT +% +% Number of iterations for the poisson solver +LINEAR_SOLVER_ITER_POISSON = 20 +% +% Number of iterations for the flow solver +LINEAR_SOLVER_ITER_FLOW = 20 + +RELAXATION_FACTOR_PBFLOW= 1.0 +RELAXATION_FACTOR_RHIECHOW= 0.5 + +% -------------------- TURBULENT NUMERICAL METHOD DEFINITION ------------------% +% +% Convective numerical method (SCALAR_UPWIND) +CONV_NUM_METHOD_TURB= SCALAR_UPWIND +% +% Monotonic Upwind Scheme for Conservation Laws (TVD) in the turbulence equations. +% Required for 2nd order upwind schemes (NO, YES) +MUSCL_TURB= NO +% +% Slope limiter (VENKATAKRISHNAN, MINMOD) +SLOPE_LIMITER_TURB= VENKATAKRISHNAN +% +% Time discretization (EULER_IMPLICIT) +TIME_DISCRE_TURB= EULER_IMPLICIT + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +% Convergence criteria (CAUCHY, RESIDUAL) +% +CONV_FIELD= RMS_VELOCITY-X +% +% +% Min value of the residual (log10 of the residual) +CONV_RESIDUAL_MINVAL= -14 +% +% Start convergence criteria at iteration number +CONV_STARTITER= 10 +% +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +% Mesh input file +MESH_FILENAME= NACA0012refgrid_lvl2.su2 +% +% Mesh input file format (SU2, CGNS, NETCDF_ASCII) +MESH_FORMAT= SU2 +% +% Restart flow input file +SOLUTION_FILENAME= restart_flow +% +% Output file format (CSV, TECPLOT) +TABULAR_FORMAT= CSV + +OUTPUT_FILES= PARAVIEW RESTART SURFACE_PARAVIEW +% +% Output file convergence history (w/o extension) +CONV_FILENAME= history +% +% Output file restart flow +RESTART_FILENAME= restart_flow +% +% Output file flow (w/o extension) variables +VOLUME_FILENAME= flow_rough_sa2 +% +% Output file surface flow coefficient (w/o extension) +SURFACE_FILENAME= surface_flow_rough_sa2 +% +% Writing solution file frequency +WRT_SOL_FREQ= 200 +% +% Writing convergence history frequency +WRT_CON_FREQ= 1 + +%SCREEN_OUTPUT= (INNER_ITER, RMS_VELOCITY-X, RMS_MASSFLUX, RMS_NU_TILDE, LIFT,DRAG) +SCREEN_OUTPUT= (INNER_ITER, RMS_VELOCITY-X, RMS_MASSFLUX, RMS_TKE, RMS_DISSIPATION, LIFT,DRAG) + +WRT_FORCES_BREAKDOWN= YES From 135d58a35469de346113660bb5d82d2a393509d0 Mon Sep 17 00:00:00 2001 From: Nitish Anand Date: Thu, 15 Feb 2024 22:49:07 +0100 Subject: [PATCH 5/6] CVariable -> CFlowVariable is done. --- .../include/variables/CPBIncEulerVariable.hpp | 62 +++++++++---------- .../include/variables/CPBIncNSVariable.hpp | 4 +- SU2_CFD/src/variables/CPBIncEulerVariable.cpp | 4 +- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/SU2_CFD/include/variables/CPBIncEulerVariable.hpp b/SU2_CFD/include/variables/CPBIncEulerVariable.hpp index 42fb606091d3..2f5b252355bc 100644 --- a/SU2_CFD/include/variables/CPBIncEulerVariable.hpp +++ b/SU2_CFD/include/variables/CPBIncEulerVariable.hpp @@ -46,12 +46,12 @@ * \ingroup Euler_Equations * \author A. Koodly */ -class CPBIncEulerVariable : public CVariable { +class CPBIncEulerVariable : public CFlowVariable { protected: - VectorType Velocity2; /*!< \brief Square of the velocity vector. */ - MatrixType Primitive; /*!< \brief Primitive variables (P, vx, vy, vz, T, rho, beta, lamMu, EddyMu, Kt_eff, Cp, Cv) in incompressible flows. */ - CVectorOfMatrix Gradient_Primitive; /*!< \brief Gradient of the primitive variables (P, vx, vy, vz, T, rho, beta). */ - CVectorOfMatrix& Gradient_Reconstruction; /*!< \brief Reference to the gradient of the primitive variables for MUSCL reconstruction for the convective term */ +// VectorType Velocity2; /*!< \brief Square of the velocity vector. */ +// MatrixType Primitive; /*!< \brief Primitive variables (P, vx, vy, vz, T, rho, beta, lamMu, EddyMu, Kt_eff, Cp, Cv) in incompressible flows. */ +// CVectorOfMatrix Gradient_Primitive; /*!< \brief Gradient of the primitive variables (P, vx, vy, vz, T, rho, beta). */ +// CVectorOfMatrix& Gradient_Reconstruction; /*!< \brief Reference to the gradient of the primitive variables for MUSCL reconstruction for the convective term */ CVectorOfMatrix Gradient_Aux; /*!< \brief Auxiliary structure to store a second gradient for reconstruction, if required. */ MatrixType Limiter_Primitive; /*!< \brief Limiter of the primitive variables (P, vx, vy, vz, T, rho, beta). */ VectorType Density_Old; /*!< \brief Old density for variable density turbulent flows (SST). */ @@ -114,13 +114,13 @@ mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reco * \brief Get the primitive variable gradients for all points. * \return Reference to primitive variable gradient. */ - inline CVectorOfMatrix& GetGradient_Primitive(void) { return Gradient_Primitive; } +// inline CVectorOfMatrix& GetGradient_Primitive(void) { return Gradient_Primitive; } /*! * \brief Get the reconstruction gradient for primitive variable at all points. * \return Reference to variable reconstruction gradient. */ - inline CVectorOfMatrix& GetGradient_Reconstruction(void) final { return Gradient_Reconstruction; } +// inline CVectorOfMatrix& GetGradient_Reconstruction(void) final { return Gradient_Reconstruction; } /*! * \brief Add value to the gradient of the primitive variables. @@ -140,15 +140,15 @@ mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reco * \param[in] iDim - Index of the dimension. * \return Value of the primitive variables gradient. */ - inline su2double GetGradient_Primitive(unsigned long iPoint, unsigned long iVar, unsigned long iDim) const final { - return Gradient_Primitive(iPoint,iVar,iDim); - } +// inline su2double GetGradient_Primitive(unsigned long iPoint, unsigned long iVar, unsigned long iDim) const final { +// return Gradient_Primitive(iPoint,iVar,iDim); +// } /*! * \brief Get the primitive variables limiter. * \return Primitive variables limiter for the entire domain. */ - inline MatrixType& GetLimiter_Primitive(void) {return Limiter_Primitive; } +// inline MatrixType& GetLimiter_Primitive(void) {return Limiter_Primitive; } /*! * \brief Get the value of the primitive variables gradient. @@ -156,9 +156,9 @@ mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reco * \param[in] iVar - Index of the variable. * \return Value of the primitive variables gradient. */ - inline su2double GetLimiter_Primitive(unsigned long iPoint, unsigned long iVar) const final { - return Limiter_Primitive(iPoint,iVar); - } +// inline su2double GetLimiter_Primitive(unsigned long iPoint, unsigned long iVar) const final { +// return Limiter_Primitive(iPoint,iVar); +// } /*! * \brief Set the gradient of the primitive variables. @@ -186,14 +186,14 @@ mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reco * \param[in] iPoint - Point index. * \return Value of the primitive variables gradient. */ - inline CMatrixView GetGradient_Primitive(unsigned long iPoint, unsigned long iVar=0) final { return Gradient_Primitive[iPoint]; } +// inline CMatrixView GetGradient_Primitive(unsigned long iPoint, unsigned long iVar=0) final { return Gradient_Primitive[iPoint]; } /*! * \brief Get the value of the primitive variables gradient. * \param[in] iPoint - Point index. * \return Value of the primitive variables gradient. */ - inline su2double *GetLimiter_Primitive(unsigned long iPoint) final { return Limiter_Primitive[iPoint]; } +// inline su2double *GetLimiter_Primitive(unsigned long iPoint) final { return Limiter_Primitive[iPoint]; } /*! * \brief Get the value of the reconstruction variables gradient at a node. @@ -202,9 +202,9 @@ mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reco * \param[in] iDim - Index of the dimension. * \return Value of the reconstruction variables gradient at a node. */ - inline su2double GetGradient_Reconstruction(unsigned long iPoint, unsigned long iVar, unsigned long iDim) const final { - return Gradient_Reconstruction(iPoint,iVar,iDim); - } +// inline su2double GetGradient_Reconstruction(unsigned long iPoint, unsigned long iVar, unsigned long iDim) const final { +// return Gradient_Reconstruction(iPoint,iVar,iDim); +// } /*! * \brief Get the value of the reconstruction variables gradient at a node. @@ -213,22 +213,22 @@ mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reco * \param[in] iDim - Index of the dimension. * \param[in] value - Value of the reconstruction gradient component. */ - inline void SetGradient_Reconstruction(unsigned long iPoint, unsigned long iVar, unsigned long iDim, su2double value) final { - Gradient_Reconstruction(iPoint,iVar,iDim) = value; - } +// inline void SetGradient_Reconstruction(unsigned long iPoint, unsigned long iVar, unsigned long iDim, su2double value) final { +// Gradient_Reconstruction(iPoint,iVar,iDim) = value; +// } /*! * \brief Get the array of the reconstruction variables gradient at a node. * \param[in] iPoint - Index of the current node. * \return Array of the reconstruction variables gradient at a node. */ - inline CMatrixView GetGradient_Reconstruction(unsigned long iPoint) final { return Gradient_Reconstruction[iPoint]; } +// inline CMatrixView GetGradient_Reconstruction(unsigned long iPoint) final { return Gradient_Reconstruction[iPoint]; } /*! * \brief Get the primitive variables for all points. * \return Reference to primitives. */ - inline const MatrixType& GetPrimitive(void) const { return Primitive; } +// inline const MatrixType& GetPrimitive(void) const { return Primitive; } /*! * \brief Get the primitive variables. @@ -236,7 +236,7 @@ mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reco * \param[in] iVar - Index of the variable. * \return Value of the primitive variable for the index iVar. */ - inline su2double GetPrimitive(unsigned long iPoint, unsigned long iVar) const final { return Primitive(iPoint,iVar); } +// inline su2double GetPrimitive(unsigned long iPoint, unsigned long iVar) const final { return Primitive(iPoint,iVar); } /*! * \brief Set the value of the primitive variables. @@ -245,7 +245,7 @@ mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reco * \param[in] iVar - Index of the variable. * \return Set the value of the primitive variable for the index iVar. */ - inline void SetPrimitive(unsigned long iPoint, unsigned long iVar, su2double val_prim) final { Primitive(iPoint,iVar) = val_prim; } +// inline void SetPrimitive(unsigned long iPoint, unsigned long iVar, su2double val_prim) final { Primitive(iPoint,iVar) = val_prim; } /*! * \brief Set the value of the primitive variables. @@ -253,16 +253,16 @@ mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reco * \param[in] val_prim - Primitive variables. * \return Set the value of the primitive variable for the index iVar. */ - inline void SetPrimitive(unsigned long iPoint, const su2double *val_prim) final { - for (unsigned long iVar = 0; iVar < nPrimVar; iVar++) Primitive(iPoint,iVar) = val_prim[iVar]; - } +// inline void SetPrimitive(unsigned long iPoint, const su2double *val_prim) final { +// for (unsigned long iVar = 0; iVar < nPrimVar; iVar++) Primitive(iPoint,iVar) = val_prim[iVar]; +// } /*! * \brief Get the primitive variables of the problem. * \param[in] iPoint - Point index. * \return Pointer to the primitive variable vector. */ - inline su2double *GetPrimitive(unsigned long iPoint) final { return Primitive[iPoint]; } +// inline su2double *GetPrimitive(unsigned long iPoint) final { return Primitive[iPoint]; } /*! * \brief Set the value of the pressure. @@ -295,7 +295,7 @@ mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reco * \brief Get the norm 2 of the velocity. * \return Norm 2 of the velocity vector. */ - inline su2double GetVelocity2(unsigned long iPoint) const final { return Velocity2(iPoint); } +// inline su2double GetVelocity2(unsigned long iPoint) const final { return Velocity2(iPoint); } /*! * \brief Get the flow pressure. diff --git a/SU2_CFD/include/variables/CPBIncNSVariable.hpp b/SU2_CFD/include/variables/CPBIncNSVariable.hpp index 26c5d8495138..1b470f071f9c 100644 --- a/SU2_CFD/include/variables/CPBIncNSVariable.hpp +++ b/SU2_CFD/include/variables/CPBIncNSVariable.hpp @@ -109,13 +109,13 @@ class CPBIncNSVariable final : public CPBIncEulerVariable { * \brief Get the value of the vorticity. * \return Value of the vorticity. */ - inline su2double *GetVorticity(unsigned long iPoint) override { return Vorticity[iPoint]; } +// inline su2double *GetVorticity(unsigned long iPoint) override { return Vorticity[iPoint]; } /*! * \brief Get the value of the magnitude of rate of strain. * \return Value of the rate of strain magnitude. */ - inline su2double GetStrainMag(unsigned long iPoint) const override { return StrainMag(iPoint); } +// inline su2double GetStrainMag(unsigned long iPoint) const override { return StrainMag(iPoint); } /*! * \brief Set the DES Length Scale. diff --git a/SU2_CFD/src/variables/CPBIncEulerVariable.cpp b/SU2_CFD/src/variables/CPBIncEulerVariable.cpp index 93960fe48fce..b09b6489d3c0 100644 --- a/SU2_CFD/src/variables/CPBIncEulerVariable.cpp +++ b/SU2_CFD/src/variables/CPBIncEulerVariable.cpp @@ -39,8 +39,8 @@ #include CPBIncEulerVariable::CPBIncEulerVariable(su2double density, su2double pressure, const su2double *velocity, unsigned long nPoint, - unsigned long ndim, unsigned long nvar, CConfig *config) : CVariable(nPoint, ndim, nvar, config), - Gradient_Reconstruction(config->GetReconstructionGradientRequired() ? Gradient_Aux : Gradient_Primitive) { + unsigned long ndim, unsigned long nvar, CConfig *config) : CFlowVariable(nPoint, ndim, nvar, nDim+4, nDim+2, config) { + // Gradient_Reconstruction(config->GetReconstructionGradientRequired() ? Gradient_Aux : Gradient_Primitive) { bool dual_time = (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) || (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND); From 98dd29944b65e8e67f9bfe9b357aa99ccc3c06f8 Mon Sep 17 00:00:00 2001 From: Nitish Anand Date: Tue, 20 Feb 2024 16:40:06 +0100 Subject: [PATCH 6/6] Ole behaviour recovered. Bug fixes and vorticity fixes. --- .../include/variables/CPBIncEulerVariable.hpp | 47 +++++++++++-------- .../include/variables/CPBIncNSVariable.hpp | 6 +-- SU2_CFD/src/solvers/CPBIncEulerSolver.cpp | 8 ++-- SU2_CFD/src/solvers/CPBIncNSSolver.cpp | 1 + SU2_CFD/src/variables/CPBIncEulerVariable.cpp | 5 +- SU2_CFD/src/variables/CPBIncNSVariable.cpp | 8 ++-- 6 files changed, 43 insertions(+), 32 deletions(-) diff --git a/SU2_CFD/include/variables/CPBIncEulerVariable.hpp b/SU2_CFD/include/variables/CPBIncEulerVariable.hpp index 2f5b252355bc..bdebc4504402 100644 --- a/SU2_CFD/include/variables/CPBIncEulerVariable.hpp +++ b/SU2_CFD/include/variables/CPBIncEulerVariable.hpp @@ -47,22 +47,6 @@ * \author A. Koodly */ class CPBIncEulerVariable : public CFlowVariable { -protected: -// VectorType Velocity2; /*!< \brief Square of the velocity vector. */ -// MatrixType Primitive; /*!< \brief Primitive variables (P, vx, vy, vz, T, rho, beta, lamMu, EddyMu, Kt_eff, Cp, Cv) in incompressible flows. */ -// CVectorOfMatrix Gradient_Primitive; /*!< \brief Gradient of the primitive variables (P, vx, vy, vz, T, rho, beta). */ -// CVectorOfMatrix& Gradient_Reconstruction; /*!< \brief Reference to the gradient of the primitive variables for MUSCL reconstruction for the convective term */ - CVectorOfMatrix Gradient_Aux; /*!< \brief Auxiliary structure to store a second gradient for reconstruction, if required. */ - MatrixType Limiter_Primitive; /*!< \brief Limiter of the primitive variables (P, vx, vy, vz, T, rho, beta). */ - VectorType Density_Old; /*!< \brief Old density for variable density turbulent flows (SST). */ - - VectorType MassFlux; /*!< \brief Massflux associated with each CV */ - MatrixType Mom_Coeff; - MatrixType Mom_Coeff_nb; - using BoolVectorType = C2DContainer; - BoolVectorType strong_bc; - VectorType StrainMag; /*!< \brief Magnitude of rate of strain tensor. */ - public: mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reconstruction counter for each edge. */ @@ -92,6 +76,25 @@ mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reco // inline IndexType Enthalpy() const { return std::numeric_limits::max(); } }; + protected: + const CIndices indices; +// VectorType Velocity2; /*!< \brief Square of the velocity vector. */ +// MatrixType Primitive; /*!< \brief Primitive variables (P, vx, vy, vz, T, rho, beta, lamMu, EddyMu, Kt_eff, Cp, Cv) in incompressible flows. */ +// CVectorOfMatrix Gradient_Primitive; /*!< \brief Gradient of the primitive variables (P, vx, vy, vz, T, rho, beta). */ +// CVectorOfMatrix& Gradient_Reconstruction; /*!< \brief Reference to the gradient of the primitive variables for MUSCL reconstruction for the convective term */ + CVectorOfMatrix Gradient_Aux; /*!< \brief Auxiliary structure to store a second gradient for reconstruction, if required. */ + MatrixType Limiter_Primitive; /*!< \brief Limiter of the primitive variables (P, vx, vy, vz, T, rho, beta). */ + VectorType Density_Old; /*!< \brief Old density for variable density turbulent flows (SST). */ + + VectorType MassFlux; /*!< \brief Massflux associated with each CV */ + MatrixType Mom_Coeff; + MatrixType Mom_Coeff_nb; + using BoolVectorType = C2DContainer; + BoolVectorType strong_bc; + // VectorType StrainMag; /*!< \brief Magnitude of rate of strain tensor. */ + + + public: /*! * \brief Constructor of the class. * \param[in] val_pressure - value of the pressure. @@ -267,7 +270,10 @@ mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reco /*! * \brief Set the value of the pressure. */ - inline void SetPressure_val(unsigned long iPoint, su2double val_pressure) { Primitive(iPoint,0) = val_pressure; } +// inline bool SetPressure(unsigned long iPoint, su2double val_pressure) override { +// Primitive(iPoint,0) = val_pressure; +// return true; +// } /*! * \brief Set the value of the density for the incompressible flows. @@ -400,8 +406,11 @@ mutable su2vector NonPhysicalEdgeCounter; /*!< \brief Non-physical reco * \brief Get the entire vector of the rate of strain magnitude. * \return Vector of magnitudes. */ - inline su2activevector& GetStrainMag() { return StrainMag; } - +// inline su2activevector& GetStrainMag() { return StrainMag; } + + inline CMatrixView GetVelocityGradient(unsigned long iPoint) const final { + return Gradient_Primitive(iPoint, indices.Velocity()); + } }; diff --git a/SU2_CFD/include/variables/CPBIncNSVariable.hpp b/SU2_CFD/include/variables/CPBIncNSVariable.hpp index 1b470f071f9c..700bb3096bf4 100644 --- a/SU2_CFD/include/variables/CPBIncNSVariable.hpp +++ b/SU2_CFD/include/variables/CPBIncNSVariable.hpp @@ -45,8 +45,8 @@ */ class CPBIncNSVariable final : public CPBIncEulerVariable { private: - MatrixType Vorticity; /*!< \brief Vorticity of the fluid. */ - VectorType StrainMag; /*!< \brief Magnitude of rate of strain tensor. */ +// MatrixType Vorticity; /*!< \brief Vorticity of the fluid. */ +// VectorType StrainMag; /*!< \brief Magnitude of rate of strain tensor. */ VectorType DES_LengthScale; public: @@ -115,7 +115,7 @@ class CPBIncNSVariable final : public CPBIncEulerVariable { * \brief Get the value of the magnitude of rate of strain. * \return Value of the rate of strain magnitude. */ -// inline su2double GetStrainMag(unsigned long iPoint) const override { return StrainMag(iPoint); } + // inline su2double GetStrainMag(unsigned long iPoint) const override { return StrainMag(iPoint); } /*! * \brief Set the DES Length Scale. diff --git a/SU2_CFD/src/solvers/CPBIncEulerSolver.cpp b/SU2_CFD/src/solvers/CPBIncEulerSolver.cpp index a66a976ffb41..02ea749c8674 100644 --- a/SU2_CFD/src/solvers/CPBIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CPBIncEulerSolver.cpp @@ -734,7 +734,7 @@ void CPBIncEulerSolver::LoadRestart(CGeometry **geometry, CSolver ***solver, CCo primitive variable vector---*/ index = counter*Restart_Vars[1] + skipVars; - nodes->SetPressure_val(iPoint_Local, Restart_Data[index]); + nodes->SetPressure(iPoint_Local, Restart_Data[index]); for (iVar = 1; iVar <= nVar; iVar++) Solution[iVar-1] = Restart_Data[index+iVar]; nodes->SetSolution(iPoint_Local, Solution); iPoint_Global_Local++; @@ -2090,7 +2090,7 @@ void CPBIncEulerSolver:: Flow_Correction(CGeometry *geometry, CSolver **solver_c /*--- Pressure corrections ---*/ Current_Pressure = nodes->GetPressure(iPoint); Current_Pressure += alpha_p[iPoint]*(Pressure_Correc[iPoint] - PCorr_Ref); - nodes->SetPressure_val(iPoint,Current_Pressure); + nodes->SetPressure(iPoint,Current_Pressure); } /*--- Correct face velocity. ---*/ @@ -2471,7 +2471,7 @@ void CPBIncEulerSolver::BC_Far_Field(CGeometry *geometry, CSolver **solver_conta auto residual = conv_numerics->ComputeResidual(config); LinSysRes.AddBlock(iPoint, residual); - nodes->SetPressure_val(iPoint,GetPressure_Inf()); + nodes->SetPressure(iPoint,GetPressure_Inf()); if (implicit) Jacobian.AddBlock2Diag(iPoint, residual.jacobian_i); @@ -2674,7 +2674,7 @@ void CPBIncEulerSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_containe /*--- Retrieve the specified back pressure for this outlet. ---*/ P_Outlet = config->GetOutlet_Pressure(Marker_Tag)/config->GetPressure_Ref(); - nodes->SetPressure_val(iPoint, P_Outlet); + nodes->SetPressure(iPoint, P_Outlet); V_outlet[0] = P_Outlet; for (iDim = 0; iDim < nDim; iDim++) V_outlet[iDim+1] = 0.0; diff --git a/SU2_CFD/src/solvers/CPBIncNSSolver.cpp b/SU2_CFD/src/solvers/CPBIncNSSolver.cpp index e1d193cb7029..391cbfd7955b 100644 --- a/SU2_CFD/src/solvers/CPBIncNSSolver.cpp +++ b/SU2_CFD/src/solvers/CPBIncNSSolver.cpp @@ -30,6 +30,7 @@ #include "../../../Common/include/toolboxes/printing_toolbox.hpp" #include "../../include/solvers/CFVMFlowSolverBase.inl" +template class CFVMFlowSolverBase; CPBIncNSSolver::CPBIncNSSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) : CPBIncEulerSolver(geometry, config, iMesh, true) { diff --git a/SU2_CFD/src/variables/CPBIncEulerVariable.cpp b/SU2_CFD/src/variables/CPBIncEulerVariable.cpp index b09b6489d3c0..330c419913cf 100644 --- a/SU2_CFD/src/variables/CPBIncEulerVariable.cpp +++ b/SU2_CFD/src/variables/CPBIncEulerVariable.cpp @@ -38,8 +38,9 @@ #include "../../include/variables/CPBIncEulerVariable.hpp" #include -CPBIncEulerVariable::CPBIncEulerVariable(su2double density, su2double pressure, const su2double *velocity, unsigned long nPoint, - unsigned long ndim, unsigned long nvar, CConfig *config) : CFlowVariable(nPoint, ndim, nvar, nDim+4, nDim+2, config) { +CPBIncEulerVariable::CPBIncEulerVariable(su2double density, su2double pressure, const su2double *velocity, unsigned long npoint, + unsigned long ndim, unsigned long nvar, CConfig *config) : CFlowVariable(npoint, ndim, nvar, ndim+4, ndim+2, config), + indices(ndim, 0) { // Gradient_Reconstruction(config->GetReconstructionGradientRequired() ? Gradient_Aux : Gradient_Primitive) { bool dual_time = (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) || diff --git a/SU2_CFD/src/variables/CPBIncNSVariable.cpp b/SU2_CFD/src/variables/CPBIncNSVariable.cpp index 1480cae012b1..2eec1c52ab32 100644 --- a/SU2_CFD/src/variables/CPBIncNSVariable.cpp +++ b/SU2_CFD/src/variables/CPBIncNSVariable.cpp @@ -37,13 +37,13 @@ #include "../../include/variables/CPBIncNSVariable.hpp" -CPBIncNSVariable::CPBIncNSVariable(su2double val_density, su2double val_pressure, su2double *val_velocity, unsigned long nPoint, - unsigned short nDim, unsigned short nvar, CConfig *config) : - CPBIncEulerVariable(val_density, val_pressure, val_velocity, nPoint, nDim, nvar, config) { +CPBIncNSVariable::CPBIncNSVariable(su2double val_density, su2double val_pressure, su2double *val_velocity, unsigned long npoint, + unsigned short ndim, unsigned short nvar, CConfig *config) : + CPBIncEulerVariable(val_density, val_pressure, val_velocity, npoint, ndim, nvar, config) { Vorticity.resize(nPoint,3); StrainMag.resize(nPoint); - DES_LengthScale.resize(nPoint) = su2double(0.0); + DES_LengthScale.resize(nPoint); Max_Lambda_Visc.resize(nPoint); }