From 58756258a00f90449ac092dac7c36142f02358b6 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Mon, 25 Nov 2024 22:14:23 +0100 Subject: [PATCH 01/61] initial update --- SU2_CFD/include/drivers/CDriverBase.hpp | 19 ++++ SU2_CFD/include/solvers/CEulerSolver.hpp | 13 +++ SU2_CFD/include/solvers/CIncEulerSolver.hpp | 13 +++ SU2_CFD/include/solvers/CSolver.hpp | 14 +++ SU2_CFD/src/integration/CIntegration.cpp | 3 + SU2_CFD/src/solvers/CIncEulerSolver.cpp | 108 ++++++++++++++++++++ 6 files changed, 170 insertions(+) diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index eaa6857c9119..ec15cf90a834 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -444,6 +444,8 @@ class CDriverBase { return CPyWrapperMatrixView(solver->GetNodes()->GetSolution(), "Solution of " + solver->GetSolverName(), false); } + + /*! * \brief Get a read/write view of the current solution on the mesh nodes of a marker. */ @@ -667,6 +669,23 @@ class CDriverBase { return sens; } + /*! + * \brief Get the gradients of a solver variable in a point. + * \returns Vector of gradients grad(iVar). + */ + inline vector GetGradient(unsigned short iSolver, unsigned long iPoint, unsigned short iVar) { + const auto nDim = GetNumberDimensions(); + auto* solver = GetSolverAndCheckMarker(iSolver); + auto* nodes = solver->GetNodes(); + + vector grad(nDim, 0.0); + for (auto iDim = 0u; iDim < nDim; ++iDim) { + grad[iDim] = nodes->GetGradient(iPoint, iVar, iDim); + } + return grad; + } + + /*! * \brief Set the adjoint of the structural displacements. * \note This can be the input of the FEA solver in an adjoint FSI setting. diff --git a/SU2_CFD/include/solvers/CEulerSolver.hpp b/SU2_CFD/include/solvers/CEulerSolver.hpp index 83c4cbe18e6a..ab5240bb5880 100644 --- a/SU2_CFD/include/solvers/CEulerSolver.hpp +++ b/SU2_CFD/include/solvers/CEulerSolver.hpp @@ -409,6 +409,19 @@ class CEulerSolver : public CFVMFlowSolverBaseSource_Residual(geometry, solver_container, numerics, config, iMesh); + /*--- Compute custom (python wrapper) source term residuals ---*/ + solver_container[MainSolver]->Custom_Source_Residual(geometry, solver_container, numerics, config, iMesh); + /*--- Add viscous and convective residuals, and compute the Dual Time Source term ---*/ if (dual_time) diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index 6aaf09a51835..1cbde7c57042 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -1813,6 +1813,114 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont } +void CIncEulerSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, + CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { + + /*--- Pick one numerics object per thread. ---*/ + //CNumerics* numerics = numerics_container[SOURCE_FIRST_TERM + omp_get_thread_num()*MAX_TERMS]; + + unsigned short iVar; + unsigned long iPoint; + + const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); + const bool rotating_frame = config->GetRotating_Frame(); + const bool axisymmetric = config->GetAxisymmetric(); + const bool body_force = config->GetBody_Force(); + const bool boussinesq = (config->GetKind_DensityModel() == INC_DENSITYMODEL::BOUSSINESQ); + const bool viscous = config->GetViscous(); + const bool radiation = config->AddRadiation(); + const bool vol_heat = config->GetHeatSource(); + const bool turbulent = (config->GetKind_Turb_Model() != TURB_MODEL::NONE); + const bool energy = config->GetEnergy_Equation(); + + // if (radiation) { + + // AD::StartNoSharedReading(); + + // CNumerics* second_numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; + + // SU2_OMP_FOR_STAT(omp_chunk_size) + // for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + // /*--- Store the radiation source term ---*/ + + // second_numerics->SetRadVarSource(solver_container[RAD_SOL]->GetNodes()->GetRadiative_SourceTerm(iPoint)); + + // /*--- Set control volume ---*/ + + // second_numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + + // /*--- Compute the residual ---*/ + + // auto residual = second_numerics->ComputeResidual(config); + + // /*--- Add Residual ---*/ + + // LinSysRes.AddBlock(iPoint, residual); + + // /*--- Implicit part ---*/ + + // if (implicit) Jacobian.AddBlock2Diag(iPoint, residual.jacobian_i); + + // if (vol_heat) { + + // if(solver_container[RAD_SOL]->GetNodes()->GetVol_HeatSource(iPoint)) { + + // auto Volume = geometry->nodes->GetVolume(iPoint); + + // /*--- Subtract integrated source from the residual. ---*/ + // LinSysRes(iPoint, nDim+1) -= config->GetHeatSource_Val()*Volume; + // } + + // } + + // } + // END_SU2_OMP_FOR + + // AD::EndNoSharedReading(); + // } + + + // /*--- Check if a verification solution is to be computed. ---*/ + + // if (VerificationSolution) { + // if ( VerificationSolution->IsManufacturedSolution() ) { + + // /*--- Get the physical time. ---*/ + // su2double time = 0.0; + // if (config->GetTime_Marching() != TIME_MARCHING::STEADY) time = config->GetPhysicalTime(); + + // AD::StartNoSharedReading(); + + // /*--- Loop over points ---*/ + // SU2_OMP_FOR_STAT(omp_chunk_size) + // for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + // /*--- Get control volume size. ---*/ + // su2double Volume = geometry->nodes->GetVolume(iPoint); + + // /*--- Get the current point coordinates. ---*/ + // const su2double *coor = geometry->nodes->GetCoord(iPoint); + + // /*--- Get the MMS source term. ---*/ + // vector sourceMan(nVar,0.0); + // VerificationSolution->GetMMSSourceTerm(coor, time, sourceMan.data()); + + // /*--- Compute the residual for this control volume and subtract. ---*/ + // for (iVar = 0; iVar < nVar; iVar++) { + // LinSysRes[iPoint*nVar+iVar] -= sourceMan[iVar]*Volume; + // } + + // } + // END_SU2_OMP_FOR + + // AD::EndNoSharedReading(); + // } + // } + +} + + void CIncEulerSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh) { From cc3dfab47929bb94bad65072a397514dfa6046bf Mon Sep 17 00:00:00 2001 From: bigfooted Date: Tue, 3 Dec 2024 14:42:12 +0100 Subject: [PATCH 02/61] initial working version for buoyant flow --- Common/include/CConfig.hpp | 13 ++ Common/src/CConfig.cpp | 3 +- SU2_CFD/include/drivers/CDriver.hpp | 44 +++++ SU2_CFD/include/drivers/CDriverBase.hpp | 71 +++++++- SU2_CFD/include/numerics/CNumerics.hpp | 1 + .../include/numerics/flow/flow_sources.hpp | 24 +++ .../include/solvers/CFVMFlowSolverBase.hpp | 36 ++++ .../include/solvers/CFVMFlowSolverBase.inl | 3 + SU2_CFD/include/solvers/CSolver.hpp | 20 ++- SU2_CFD/src/drivers/CDriverBase.cpp | 4 + SU2_CFD/src/drivers/CSinglezoneDriver.cpp | 7 +- SU2_CFD/src/numerics/flow/flow_sources.cpp | 38 ++++ SU2_CFD/src/python_wrapper_structure.cpp | 13 ++ SU2_CFD/src/solvers/CIncEulerSolver.cpp | 109 ++--------- .../custom_source/lam_buoyancy_cavity.cfg | 120 +++++++++++++ TestCases/py_wrapper/custom_source/run.py | 169 ++++++++++++++++++ 16 files changed, 577 insertions(+), 98 deletions(-) create mode 100644 TestCases/py_wrapper/custom_source/lam_buoyancy_cavity.cfg create mode 100644 TestCases/py_wrapper/custom_source/run.py diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 0c32f0442882..553b689023f3 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -286,6 +286,7 @@ class CConfig { su2double **Giles_FlowDir; /*!< \brief Specified flow direction vector (unit vector) for Giles BC. */ su2double *Inlet_Ptotal; /*!< \brief Specified total pressures for inlet boundaries. */ su2double **Inlet_FlowDir; /*!< \brief Specified flow direction vector (unit vector) for inlet boundaries. */ + //su2double *PointSource; /*!< \brief Specified flow direction vector (unit vector) for inlet boundaries. */ su2double *Inlet_Temperature; /*!< \brief Specified temperatures for a supersonic inlet boundaries. */ su2double *Inlet_Pressure; /*!< \brief Specified static pressures for supersonic inlet boundaries. */ su2double **Inlet_Velocity; /*!< \brief Specified flow velocity vectors for supersonic inlet boundaries. */ @@ -9454,6 +9455,18 @@ class CConfig { */ unsigned long GetnOuter_Iter(void) const { return nOuterIter; } + /*! + * \brief Get the number of inner iterations + * \return Number of inner iterations on each multizone block + */ + void SetnInner_Iter(unsigned long val_iter) { nInnerIter = val_iter; } + + /*! + * \brief Get the number of outer iterations + * \return Number of outer iterations for the multizone problem + */ + void SetnOuter_Iter(unsigned long val_iter) { cout << "inner iter=" << val_iter << endl; nOuterIter = val_iter; } + /*! * \brief Get the number of time iterations * \return Number of time steps run diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 64be5736bca2..b80fdedfc412 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -890,6 +890,7 @@ void CConfig::SetPointersNull() { Inlet_FlowDir = nullptr; Inlet_Temperature = nullptr; Inlet_Pressure = nullptr; Inlet_Velocity = nullptr; Outlet_Pressure = nullptr; Inlet_SpeciesVal = nullptr; Inlet_TurbVal = nullptr; + //PointSource = nullptr; /*--- Engine Boundary Condition settings ---*/ @@ -913,7 +914,7 @@ void CConfig::SetPointersNull() { Inlet_FlowDir = nullptr; Inlet_Temperature = nullptr; Inlet_Pressure = nullptr; Inlet_Velocity = nullptr; Inflow_Mach = nullptr; Inflow_Pressure = nullptr; Outlet_Pressure = nullptr; Isothermal_Temperature = nullptr; - + //PointSource = nullptr; ElasticityMod = nullptr; PoissonRatio = nullptr; MaterialDensity = nullptr; Load_Dir = nullptr; Load_Dir_Value = nullptr; Load_Dir_Multiplier = nullptr; diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index 2f79be415b3d..7c74ed40a854 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -475,6 +475,37 @@ class CDriver : public CDriverBase { */ unsigned long GetNumberTimeIter() const; + /*! + * \brief Get the number of inner iterations. + * \return Number of inner iterations. + */ + unsigned long GetNumberInnerIter() const; + + /*! + * \brief Get the number of outer iterations. + * \return Number of outer iterations. + */ + unsigned long GetNumberOuterIter() const; + + + /*! + * \brief Set the number of inner iterations. + * \return Number of inner iterations. + */ + void SetNumberInnerIter(unsigned long); + + /*! + * \brief Set the number of outer iterations. + * \return Number of outer iterations. + */ + void SetNumberOuterIter(unsigned long); + + /*! + * \brief Get the current solution + * \return Current solution + */ + unsigned long GetSolution(unsigned short iSolver, unsigned long iPoint, unsigned short iVar); + /*! * \brief Get the current time iteration. * \return Current time iteration. @@ -555,6 +586,19 @@ class CDriver : public CDriverBase { */ void SetMarkerTranslationRate(unsigned short iMarker, passivedouble vel_x, passivedouble vel_y, passivedouble vel_z); + /*! + * \brief Get the Freestream Density for nondimensionalization + * \return Freestream Density + */ + unsigned long GetDensity_FreeStreamND() const; + + /*! + * \brief Get the reference Body force for nondimensionalization + * \return reference Body Force + */ + unsigned long GetForce_Ref() const; + + /// \} }; diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index ec15cf90a834..699379ab444d 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -179,6 +179,15 @@ class CDriverBase { */ unsigned long GetNumberElements() const; + /*! + * \brief Get the number of solution variables + * \return Number of solution variables. + */ + //unsigned long GetNumberSolverVars() const; + + unsigned short GetNumberSolverVars(const unsigned short iSol) const; + unsigned short GetNumberPrimitiveVars(const unsigned short iSol) const; + /*! * \brief Get the global index of a mesh element. * \param[in] iElem - Mesh element index. @@ -444,8 +453,6 @@ class CDriverBase { return CPyWrapperMatrixView(solver->GetNodes()->GetSolution(), "Solution of " + solver->GetSolverName(), false); } - - /*! * \brief Get a read/write view of the current solution on the mesh nodes of a marker. */ @@ -680,7 +687,7 @@ class CDriverBase { vector grad(nDim, 0.0); for (auto iDim = 0u; iDim < nDim; ++iDim) { - grad[iDim] = nodes->GetGradient(iPoint, iVar, iDim); + grad[iDim] = SU2_TYPE::GetValue(nodes->GetGradient(iPoint, iVar, iDim)); } return grad; } @@ -753,6 +760,49 @@ class CDriverBase { } } + /*! + * \brief Set the array of variables for the source in the point + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \param[in] value - Value of the variable. + */ + void SetPointCustomSource(unsigned short iSOLVER, unsigned long iPoint, std::vector values) { + //for (auto iVar = 0ul; iVar < nVar; ++iDim) { + //GetSolverAndCheckField(FLOW_SOL, iPoint)->SetCustomPointSource (iPoint, value); + auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSOLVER]; + solver->SetCustomPointSource(iPoint, values); + } + +// return solution vector +inline vector GetSolutionVector(unsigned short iSOLVER, unsigned long iPoint) { + auto* solver = solver_container[iSOLVER][INST_0][MESH_0][iSOLVER]; + auto* nodes = solver->GetNodes(); + auto nVar = GetNumberSolverVars(iSOLVER); + //cout << "getting solution: "<GetSolution(iPoint,2); + //cout << "value : " << val << endl; + vector solutionvector(nVar, 0.0); + for (auto iVar = 0u; iVar < nVar; ++iVar) { + solutionvector[iVar] = SU2_TYPE::GetValue(nodes->GetSolution(iPoint,iVar)); + //cout << "vector = " << solutionvector[iVar] << endl; + } + return solutionvector; +} + +inline vector GetPrimitiveVector(unsigned short iSOLVER, unsigned long iPoint) { + auto* solver = solver_container[iSOLVER][INST_0][MESH_0][iSOLVER]; + auto* nodes = solver->GetNodes(); + auto nPrimvar = GetNumberPrimitiveVars(iSOLVER); + //cout << "getting solution: "<GetSolution(iPoint,2); + //cout << "value : " << val << endl; + vector solutionvector(nPrimvar, 0.0); + for (auto iVar = 0u; iVar < nPrimvar; ++iVar) { + solutionvector[iVar] = SU2_TYPE::GetValue(nodes->GetPrimitive(iPoint,iVar)); + //cout << "vector = " << solutionvector[iVar] << endl; + } + return solutionvector; +} /// \} protected: @@ -769,6 +819,21 @@ class CDriverBase { return solver; } + /*! + * \brief Automates some boilerplate of accessing solution fields for the python wrapper. + */ + inline CSolver* GetSolverAndCheckField(unsigned short iSolver, + unsigned long iPoint = std::numeric_limits::max()) const { + // 1. check for the solver the number of variables + // 2. check for the mesh the number of points + //if (iPoint < std::numeric_limits::max() && iPoint > GetNumberMarkers()) { + // SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION); + //} + auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; + if (solver == nullptr) SU2_MPI::Error("The selected solver does not exist.", CURRENT_FUNCTION); + return solver; + } + /*! * \brief Initialize containers. */ diff --git a/SU2_CFD/include/numerics/CNumerics.hpp b/SU2_CFD/include/numerics/CNumerics.hpp index 535335947caf..8d23b402bab8 100644 --- a/SU2_CFD/include/numerics/CNumerics.hpp +++ b/SU2_CFD/include/numerics/CNumerics.hpp @@ -155,6 +155,7 @@ class CNumerics { 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 *UserDefinedSource; /*!< \brief User Defined Source term. */ const su2double *Coord_i, /*!< \brief Cartesians coordinates of point i. */ *Coord_j; /*!< \brief Cartesians coordinates of point j. */ diff --git a/SU2_CFD/include/numerics/flow/flow_sources.hpp b/SU2_CFD/include/numerics/flow/flow_sources.hpp index e4cb64e4b54e..e6a138ec9016 100644 --- a/SU2_CFD/include/numerics/flow/flow_sources.hpp +++ b/SU2_CFD/include/numerics/flow/flow_sources.hpp @@ -467,3 +467,27 @@ class CSourceRadiation : public CSourceBase_Flow { ResidualType<> ComputeResidual(const CConfig* config) override; }; + + +/*! + * \class CSourceUserDefined + * \brief Class for a user defined source term using the python wrapper + * \ingroup SourceDiscr + * \author Nijso Beishuizen + */ +class CSourceUserDefined : public CSourceBase_Flow { +private: + bool implicit; + +public: + + CSourceUserDefined(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config); + + /*! + * \brief Source term integration for a user defined source. + * \param[in] config - Definition of the particular problem. + * \return Lightweight const-view of residual and Jacobian. + */ + ResidualType<> ComputeResidual(const CConfig* config) override; + +}; diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp index 2aa31880baea..9aacffc9c2fb 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp @@ -170,6 +170,7 @@ class CFVMFlowSolverBase : public CSolver { vector > Inlet_Ptotal; /*!< \brief Value of the Total P. */ vector > Inlet_Ttotal; /*!< \brief Value of the Total T. */ vector Inlet_FlowDir; /*!< \brief Value of the Flow Direction. */ + su2activematrix PointSource; /*!< \brief Value of the Flow Direction. */ vector > HeatFlux; /*!< \brief Heat transfer coefficient for each boundary and vertex. */ vector > HeatFluxTarget; /*!< \brief Heat transfer coefficient for each boundary and vertex. */ vector CharacPrimVar; /*!< \brief Value of the characteristic variables at each boundary. */ @@ -2148,6 +2149,18 @@ class CFVMFlowSolverBase : public CSolver { return Inlet_FlowDir[val_marker][val_vertex][val_dim]; } + /*! + * \brief A component of the unit vector representing the flow direction at an inlet boundary. + * \param[in] val_marker - Surface marker where the flow direction is evaluated + * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is evaluated + * \param[in] val_dim - The component of the flow direction unit vector to be evaluated + * \return Component of a unit vector representing the flow direction. + */ + inline su2double GetCustomPointSource(unsigned long val_point, + unsigned short val_var) const final { + return PointSource[val_point][val_var]; + } + /*! * \brief Set the value of the total temperature at an inlet boundary. * \param[in] val_marker - Surface marker where the total temperature is set. @@ -2201,6 +2214,29 @@ class CFVMFlowSolverBase : public CSolver { Inlet_FlowDir[val_marker][val_vertex][val_dim] = val_flowdir; } + /*! + * \brief Set a component of the unit vector representing the flow direction at an inlet boundary. + * \param[in] val_marker - Surface marker where the flow direction is set. + * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is set. + * \param[in] val_dim - The component of the flow direction unit vector to be set + * \param[in] val_flowdir - Component of a unit vector representing the flow direction. + */ + inline void SetCustomPointSource(unsigned long val_point, + vector val_source) final { + /*--- Since this call can be accessed indirectly using python, do some error + * checking to prevent segmentation faults ---*/ + //if (val_marker >= nMarker) + // SU2_MPI::Error("Out-of-bounds marker index used on inlet.", CURRENT_FUNCTION); + //else if (val_vertex >= nVertex[val_marker]) + // SU2_MPI::Error("Out-of-bounds vertex index used on inlet.", CURRENT_FUNCTION); + //else + //cout << "value list size=" << val_source.size() << endl; + //cout << "pointsource.size = " << nVar << endl; + //cout << "point,npoint=" << val_point << " " << nPointDomain << endl; + for (unsigned short iVar=0; iVar < val_source.size(); iVar++) + PointSource[val_point][iVar] = val_source[iVar]; + } + /*! * \brief Update the multi-grid structure for the customized boundary conditions. * \param geometry_container - Geometrical definition. diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 4797293529f6..b9bcdc451f2a 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -123,6 +123,9 @@ void CFVMFlowSolverBase::Allocate(const CConfig& config) { /*--- Store the value of the Flow direction at the inlet BC ---*/ AllocVectorOfMatrices(nVertex, nDim, Inlet_FlowDir); + + //AllocVectorOfVectors(nPointDomain, PointSource); + PointSource.resize(nPointDomain,nVar); /*--- Force definition and coefficient arrays for all of the markers ---*/ diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index bc913ed4348f..10b1b6e38ec0 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -2854,7 +2854,15 @@ class CSolver { inline virtual su2double GetInletFlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim) const { return 0; } - + /*! + * \brief A virtual member + * \param[in] val_marker - Surface marker where the flow direction is evaluated + * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is evaluated + * \param[in] val_dim - The component of the flow direction unit vector to be evaluated + * \return Component of a unit vector representing the flow direction. + */ + inline virtual su2double GetCustomPointSource(unsigned long val_point, + unsigned short val_var) const { return 0; } /*! * \brief A virtual member * \param[in] val_marker - Surface marker where the total temperature is set. @@ -2886,7 +2894,15 @@ class CSolver { unsigned long val_vertex, unsigned short val_dim, su2double val_flowdir) { } - + /*! + * \brief A virtual member + * \param[in] val_marker - Surface marker where the flow direction is set. + * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is set. + * \param[in] val_dim - The component of the flow direction unit vector to be set + * \param[in] val_flowdir - Component of a unit vector representing the flow direction. + */ + inline virtual void SetCustomPointSource(unsigned long val_Point, + vector val_source) { } /*! * \brief Updates the components of the farfield velocity vector. */ diff --git a/SU2_CFD/src/drivers/CDriverBase.cpp b/SU2_CFD/src/drivers/CDriverBase.cpp index 53483856b5da..7ea823800954 100644 --- a/SU2_CFD/src/drivers/CDriverBase.cpp +++ b/SU2_CFD/src/drivers/CDriverBase.cpp @@ -165,6 +165,10 @@ unsigned long CDriverBase::GetNumberDimensions() const { return main_geometry->G unsigned long CDriverBase::GetNumberElements() const { return main_geometry->GetnElem(); } +//unsigned long CDriverBase::GetNumberSolverVars() const { return main_geometry->GetnElem(); } +unsigned short CDriverBase::GetNumberSolverVars(const unsigned short iSol) const { return solver_container[selected_zone][INST_0][MESH_0][iSol]->GetnVar(); } +unsigned short CDriverBase::GetNumberPrimitiveVars(const unsigned short iSol) const { return solver_container[selected_zone][INST_0][MESH_0][iSol]->GetnPrimVar(); } + unsigned long CDriverBase::GetElementGlobalIndex(unsigned long iElem) const { if (iElem >= GetNumberElements()) { SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); diff --git a/SU2_CFD/src/drivers/CSinglezoneDriver.cpp b/SU2_CFD/src/drivers/CSinglezoneDriver.cpp index ed4d46f370e1..8bec4611e58f 100644 --- a/SU2_CFD/src/drivers/CSinglezoneDriver.cpp +++ b/SU2_CFD/src/drivers/CSinglezoneDriver.cpp @@ -106,6 +106,10 @@ void CSinglezoneDriver::Preprocess(unsigned long TimeIter) { /*--- Set the current time iteration in the config and also in the driver * because the python interface doesn't offer an explicit way of doing it. ---*/ + if (config_container[ZONE_0]->GetTime_Marching() == TIME_MARCHING::STEADY) { + cout << "steady simulation, iteration = " << TimeIter << endl; + config_container[ZONE_0]->SetInnerIter(TimeIter); + } this->TimeIter = TimeIter; config_container[ZONE_0]->SetTimeIter(TimeIter); @@ -113,8 +117,7 @@ void CSinglezoneDriver::Preprocess(unsigned long TimeIter) { /*--- Store the current physical time in the config container, as this can be used for verification / MMS. This should also be more general once the drivers are more stable. ---*/ - - if (config_container[ZONE_0]->GetTime_Marching() != TIME_MARCHING::STEADY) + if (config_container[ZONE_0]->GetTime_Marching() != TIME_MARCHING::STEADY) config_container[ZONE_0]->SetPhysicalTime(static_cast(TimeIter)*config_container[ZONE_0]->GetDelta_UnstTimeND()); else config_container[ZONE_0]->SetPhysicalTime(0.0); diff --git a/SU2_CFD/src/numerics/flow/flow_sources.cpp b/SU2_CFD/src/numerics/flow/flow_sources.cpp index 6f8359a5f582..b5c29a6325f0 100644 --- a/SU2_CFD/src/numerics/flow/flow_sources.cpp +++ b/SU2_CFD/src/numerics/flow/flow_sources.cpp @@ -427,6 +427,8 @@ CNumerics::ResidualType<> CSourceIncBodyForce::ComputeResidual(const CConfig* co residual[nDim+1] = 0.0; + //cout << "residual = " << residual[0] << " " << residual[1] << " " << residual[2] << " " <(residual, jacobian, nullptr); } @@ -837,3 +839,39 @@ CNumerics::ResidualType<> CSourceRadiation::ComputeResidual(const CConfig *confi return ResidualType<>(residual, jacobian, nullptr); } + +CSourceUserDefined::CSourceUserDefined(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config) : + CSourceBase_Flow(val_nDim, val_nVar, config) { + + implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); +} + +CNumerics::ResidualType<> CSourceUserDefined::ComputeResidual(const CConfig *config) { + + unsigned short iDim; + + /*--- Zero the continuity contribution. ---*/ + + residual[0] = 0.0; + + /*--- Zero the momentum contribution. ---*/ + + for (iDim = 0; iDim < nDim; iDim++) + residual[iDim+1] = 0.0; + + /*--- Set the energy contribution ---*/ + + residual[nDim+1] = -UserDefinedSource[0]*Volume; + + /*--- Set the energy contribution to the Jacobian. ---*/ + + if (implicit) { + + /*--- Jacobian is set to zero on initialization. ---*/ + + jacobian[nDim+1][nDim+1] = -UserDefinedSource[1]*Volume; + + } + + return ResidualType<>(residual, jacobian, nullptr); +} diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index 2a148a346d94..2677eb21943b 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -58,6 +58,14 @@ void CDriver::PreprocessPythonInterface(CConfig** config, CGeometry**** geometry unsigned long CDriver::GetNumberTimeIter() const { return config_container[selected_zone]->GetnTime_Iter(); } +unsigned long CDriver::GetNumberInnerIter() const { return config_container[selected_zone]->GetnInner_Iter(); } +unsigned long CDriver::GetNumberOuterIter() const { return config_container[selected_zone]->GetnOuter_Iter(); } +void CDriver::SetNumberInnerIter(unsigned long nInner) { config_container[selected_zone]->SetnInner_Iter(nInner); } +void CDriver::SetNumberOuterIter(unsigned long nOuter) { config_container[selected_zone]->SetnOuter_Iter(nOuter); } + +unsigned long CDriver::GetDensity_FreeStreamND() const { return config_container[selected_zone]->GetDensity_FreeStreamND(); } +unsigned long CDriver::GetForce_Ref() const { return config_container[selected_zone]->GetForce_Ref(); } + unsigned long CDriver::GetTimeIter() const { return TimeIter; } passivedouble CDriver::GetUnsteadyTimeStep() const { @@ -66,6 +74,11 @@ passivedouble CDriver::GetUnsteadyTimeStep() const { string CDriver::GetSurfaceFileName() const { return config_container[selected_zone]->GetSurfCoeff_FileName(); } +unsigned long CDriver::GetSolution(unsigned short iSOLVER, unsigned long iPoint, unsigned short iVar) { + auto solver = solver_container[iZone][INST_0][MESH_0][iSOLVER]; + return solver->GetNodes()->GetSolution(iPoint,iVar); +} + //////////////////////////////////////////////////////////////////////////////// /* Functions related to the management of markers */ //////////////////////////////////////////////////////////////////////////////// diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index 1cbde7c57042..18f60dfbffa4 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -1817,106 +1817,35 @@ void CIncEulerSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solv CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { /*--- Pick one numerics object per thread. ---*/ - //CNumerics* numerics = numerics_container[SOURCE_FIRST_TERM + omp_get_thread_num()*MAX_TERMS]; + CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; unsigned short iVar; unsigned long iPoint; + AD::StartNoSharedReading(); - const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); - const bool rotating_frame = config->GetRotating_Frame(); - const bool axisymmetric = config->GetAxisymmetric(); - const bool body_force = config->GetBody_Force(); - const bool boussinesq = (config->GetKind_DensityModel() == INC_DENSITYMODEL::BOUSSINESQ); - const bool viscous = config->GetViscous(); - const bool radiation = config->AddRadiation(); - const bool vol_heat = config->GetHeatSource(); - const bool turbulent = (config->GetKind_Turb_Model() != TURB_MODEL::NONE); - const bool energy = config->GetEnergy_Equation(); - - // if (radiation) { - - // AD::StartNoSharedReading(); - - // CNumerics* second_numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; - - // SU2_OMP_FOR_STAT(omp_chunk_size) - // for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - - // /*--- Store the radiation source term ---*/ - - // second_numerics->SetRadVarSource(solver_container[RAD_SOL]->GetNodes()->GetRadiative_SourceTerm(iPoint)); - - // /*--- Set control volume ---*/ - - // second_numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - - // /*--- Compute the residual ---*/ - - // auto residual = second_numerics->ComputeResidual(config); - - // /*--- Add Residual ---*/ - - // LinSysRes.AddBlock(iPoint, residual); - - // /*--- Implicit part ---*/ - - // if (implicit) Jacobian.AddBlock2Diag(iPoint, residual.jacobian_i); - - // if (vol_heat) { - - // if(solver_container[RAD_SOL]->GetNodes()->GetVol_HeatSource(iPoint)) { - - // auto Volume = geometry->nodes->GetVolume(iPoint); - - // /*--- Subtract integrated source from the residual. ---*/ - // LinSysRes(iPoint, nDim+1) -= config->GetHeatSource_Val()*Volume; - // } - - // } - - // } - // END_SU2_OMP_FOR - - // AD::EndNoSharedReading(); - // } - - - // /*--- Check if a verification solution is to be computed. ---*/ - - // if (VerificationSolution) { - // if ( VerificationSolution->IsManufacturedSolution() ) { - - // /*--- Get the physical time. ---*/ - // su2double time = 0.0; - // if (config->GetTime_Marching() != TIME_MARCHING::STEADY) time = config->GetPhysicalTime(); - - // AD::StartNoSharedReading(); - - // /*--- Loop over points ---*/ - // SU2_OMP_FOR_STAT(omp_chunk_size) - // for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + SU2_OMP_FOR_STAT(omp_chunk_size) + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - // /*--- Get control volume size. ---*/ - // su2double Volume = geometry->nodes->GetVolume(iPoint); + /*--- Load the volume of the dual mesh cell ---*/ - // /*--- Get the current point coordinates. ---*/ - // const su2double *coor = geometry->nodes->GetCoord(iPoint); + numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - // /*--- Get the MMS source term. ---*/ - // vector sourceMan(nVar,0.0); - // VerificationSolution->GetMMSSourceTerm(coor, time, sourceMan.data()); + /*--- Get control volume size. ---*/ + su2double Volume = geometry->nodes->GetVolume(iPoint); - // /*--- Compute the residual for this control volume and subtract. ---*/ - // for (iVar = 0; iVar < nVar; iVar++) { - // LinSysRes[iPoint*nVar+iVar] -= sourceMan[iVar]*Volume; - // } + /*--- Compute the residual for this control volume and subtract. ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + LinSysRes[iPoint*nVar+iVar] += PointSource[iPoint][iVar] * Volume; + } + // cout << "source = " << iPoint << " " << PointSource[iPoint][0]*Volume + // << " " << PointSource[iPoint][1]*Volume + // << " " << PointSource[iPoint][2]*Volume + // << " " << PointSource[iPoint][3]*Volume << endl; - // } - // END_SU2_OMP_FOR + } + END_SU2_OMP_FOR - // AD::EndNoSharedReading(); - // } - // } + AD::EndNoSharedReading(); } diff --git a/TestCases/py_wrapper/custom_source/lam_buoyancy_cavity.cfg b/TestCases/py_wrapper/custom_source/lam_buoyancy_cavity.cfg new file mode 100644 index 000000000000..470a895b372a --- /dev/null +++ b/TestCases/py_wrapper/custom_source/lam_buoyancy_cavity.cfg @@ -0,0 +1,120 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Buoyancy-driven flow inside a cavity % +% Author: Thomas D. Economon % +% Date: 2018.06.10 % +% File Version 8.1.0 "Harrier" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= INC_NAVIER_STOKES +KIND_TURB_MODEL= NONE +MATH_PROBLEM= DIRECT +RESTART_SOL= NO + +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +INC_DENSITY_MODEL= VARIABLE +INC_ENERGY_EQUATION = YES +% +% Uncomment a density below for a desired Rayleigh number +%INC_DENSITY_INIT= 0.00018903539834 % Ra ~ 1e3 +%INC_DENSITY_INIT= 0.00059778241716 % Ra ~ 1e4 +%INC_DENSITY_INIT= 0.00189035398341 % Ra ~ 1e5 +INC_DENSITY_INIT= 0.00597782417156 % Ra ~ 1e6 +% +INC_VELOCITY_INIT= ( 1.0, 0.0, 0.0 ) +INC_TEMPERATURE_INIT= 288.15 + +% ---- IDEAL GAS, POLYTROPIC, VAN DER WAALS AND PENG ROBINSON CONSTANTS -------% +% +FLUID_MODEL= INC_IDEAL_GAS +SPECIFIC_HEAT_CP= 1004.703 +MOLECULAR_WEIGHT= 28.96 + +% --------------------------- VISCOSITY MODEL ---------------------------------% +% +VISCOSITY_MODEL= CONSTANT_VISCOSITY +MU_CONSTANT= 1.716e-5 + +% --------------------------- THERMAL CONDUCTIVITY MODEL ----------------------% +% +CONDUCTIVITY_MODEL= CONSTANT_CONDUCTIVITY +THERMAL_CONDUCTIVITY_CONSTANT= 0.0246295028571 + +% ----------------------- BODY FORCE DEFINITION -------------------------------% +% +BODY_FORCE= NO +BODY_FORCE_VECTOR= ( 0.0, -9.81, 0.0 ) + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +REF_ORIGIN_MOMENT_X = 0.25 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +REF_AREA= 1.0 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( upper, 0.0, lower, 0.0 ) +MARKER_ISOTHERMAL= ( left, 461.04, right, 115.26 ) +MARKER_PLOTTING= ( upper, left, right, lower ) +MARKER_MONITORING= ( NONE ) + +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= GREEN_GAUSS +CFL_NUMBER= 50 +CFL_ADAPT= NO +CFL_ADAPT_PARAM= ( 1.5, 0.5, 15.0, 1e10) +MAX_DELTA_TIME= 1E6 +RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) +ITER=1 + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ILU_FILL_IN= 0 +LINEAR_SOLVER_ERROR= 1E-15 +LINEAR_SOLVER_ITER= 20 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= FDS +MUSCL_FLOW= YES +SLOPE_LIMITER_FLOW= NONE +TIME_DISCRE_FLOW= EULER_IMPLICIT + + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_RESIDUAL_MINVAL= -12 +CONV_STARTITER= 10 +CONV_CAUCHY_ELEMS= 100 +CONV_CAUCHY_EPS= 1E-6 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FILENAME= mesh_cavity_65x65.su2 +MESH_FORMAT= SU2 +MESH_OUT_FILENAME= mesh_out.su2 +SOLUTION_FILENAME= solution_flow.dat +SOLUTION_ADJ_FILENAME= solution_adj.dat +TABULAR_FORMAT= CSV +CONV_FILENAME= history +RESTART_FILENAME= restart_flow.dat +RESTART_ADJ_FILENAME= restart_adj.dat +VOLUME_FILENAME= flow +VOLUME_ADJ_FILENAME= adjoint +GRAD_OBJFUNC_FILENAME= of_grad.dat +SURFACE_FILENAME= surface_flow +SURFACE_ADJ_FILENAME= surface_adjoint +OUTPUT_WRT_FREQ= 100 +SCREEN_OUTPUT= (OUTER_ITER, INNER_ITER, RMS_PRESSURE, RMS_TEMPERATURE, LIFT, DRAG) + +% ----------------------- GEOMETRY EVALUATION PARAMETERS ----------------------% +GEO_BOUNDS= ( 0.499, 0.501) diff --git a/TestCases/py_wrapper/custom_source/run.py b/TestCases/py_wrapper/custom_source/run.py new file mode 100644 index 000000000000..c9fcaf4e0ac5 --- /dev/null +++ b/TestCases/py_wrapper/custom_source/run.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python + +## \file run.py +# \brief Unsteady inlet boundary conditions. +# \version 8.1.0 "Harrier" +# +# SU2 Project Website: https://su2code.github.io +# +# The SU2 Project is maintained by the SU2 Foundation +# (http://su2foundation.org) +# +# Copyright 2012-2024, 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 . + +import sys +import pysu2 +import math +import itertools +# from mpi4py import MPI + +def main(): + """ + Run the flow solver with a custom inlet (function of time and space). + """ + # comm = MPI.COMM_WORLD + comm = 0 + + # Initialize the primal driver of SU2, this includes solver preprocessing. + try: + driver = pysu2.CSinglezoneDriver('lam_buoyancy_cavity.cfg', 1, comm) + except TypeError as exception: + print('A TypeError occured in pysu2.CSinglezoneDriver : ', exception) + raise + + # Get the ID of the inlet marker. + all_marker_ids = driver.GetMarkerIndices() + marker_name = 'x_minus' + marker_id = all_marker_ids[marker_name] if marker_name in all_marker_ids else -1 + + # Run the time loop in python to vary the inlet conditions. + dt = driver.GetUnsteadyTimeStep() + + print("\n------------------------------ Begin Solver -----------------------------") + sys.stdout.flush() + + # we need to add a source term to the energy equation. For this, we need to get the solver, and the variable first. + # we then loop over all points and for these points, we add the source term + nDim = driver.GetNumberDimensions() + nNodes = driver.GetNumberNodes() + #solverindex = driver.GetSolverIndices() + #primindex = driver.GetPrimitiveIndices() + + # index to the flow solver + iSOLVER = driver.GetSolverIndices()['INC.FLOW'] + print("index of flow solver = ",iSOLVER) + coords = driver.Coordinates() + # all the indices and the map to the names of the primitives + primindex = driver.GetPrimitiveIndices() + print("indices of primitives=",primindex) + print("number of primitives:",len(primindex)) + + nElem = driver.GetNumberElements() + print("number of elements:",nElem) + + nVars = driver.GetNumberSolverVars(iSOLVER) + print("number of solver variables:",nVars) + varindex = primindex.copy() + for prim in varindex.copy(): + if varindex[prim] >=nVars: + del varindex[prim] + varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) + + + + print("solver variable names:",varindex) + iDENSITY = primindex.get("DENSITY") + print("index of density = ",iDENSITY) + + index_Vel = varindex.get("VELOCITY_X") + print("index of velocity = ",index_Vel) + custom_source_vector = [0.0 for i in range(nVars)] + print("custom source vector = ", custom_source_vector) + + inner_iter = driver.GetNumberInnerIter(); + print("max. number of inner iterations: ",driver.GetNumberInnerIter()); + print("max nr of outer iterations: ",driver.GetNumberOuterIter()); + + # is in domain: isdomain = driver.GetNodeDomain(iPoint) + #for i_vertex in range(n_vertex) + #AllSolutions = driver.GetAllSolutions(iSOLVER) + Body_Force_Vector = [0.0, -9.81, 0.0] + DensityInc_0 = driver.GetDensity_FreeStreamND() + print("rho freestream = ",DensityInc_0) + Force_Ref = driver.GetForce_Ref() + print("reference force = ",Force_Ref) + # get the density from the solution + #residual[iDim+1] = -(DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref; + + #for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): + #print("(x,y) = ( ",coords.Get(i_node,0)," , ",coords.Get(i_node,1)," )") + #custom_source = -9.81 + # we need to set the custom source to the correct primitive equation, in this case let us add it to the y-momentum equation + #i_momy = 2 + #driver.SetCustomSource(iSOLVER, iVar, i_node,custom_source) + #DensityInc_i = driver.GetSolution(iSOLVER,iPoint,2) + #driver.SetPointCustomSource(iSOLVER, i_node,custom_source_vector) + + + + # we get the numer of iterations: + + DensityInc_i = 1 + # we set the actual inner iterations to 1 + #for time_iter in range(inner_iter): + for inner_iter in range(500): + + # set the source term, per point + print("loop over nodes and set the source term field") + for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): + #print("node = ",i_node) + SolutionVector = driver.GetSolutionVector(iSOLVER,i_node) + #print("solutionvector=",SolutionVector) + PrimitiveVector = driver.GetPrimitiveVector(iSOLVER,i_node) + #print("primitivevector=",PrimitiveVector) + DensityInc_i = PrimitiveVector[iDENSITY] + #residual[iDim+1] = -Volume * (DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref; + for iDim in range(nDim): + custom_source_vector[iDim+1] = -(DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref + #print("density=",DensityInc_i) + driver.SetPointCustomSource(iSOLVER, i_node,custom_source_vector) + print("end setting custom source term") + + # Change the total pressure. + #if marker_id >= 0: + # for i_vertex in range(driver.GetNumberMarkerNodes(marker_id)): + # y = driver.MarkerCoordinates(marker_id)(i_vertex, 1) + # t = time_iter * dt + # pt = 1e5 + 2e4 * y / 0.01 * (1 - math.cos(2 * math.pi * t / 0.1)) + # driver.SetMarkerCustomInletFlowVar1(marker_id, i_vertex, pt) + #driver.BoundaryConditionsUpdate() + print(" *** inner iteration:",inner_iter) + driver.Preprocess(inner_iter) + + # Run one time iteration. + driver.Run() + driver.Postprocess() + driver.Update() + + # Monitor the solver and output solution to file if required. + #driver.Monitor(inner_iter) + driver.Output(inner_iter) + + # Finalize the solver and exit cleanly. + driver.Finalize() + +if __name__ == '__main__': + main() From b407a273df875a0c69686153e296f82f6d7bd457 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Tue, 3 Dec 2024 14:53:03 +0100 Subject: [PATCH 03/61] small cleanup --- Common/include/CConfig.hpp | 13 ------------- Common/src/CConfig.cpp | 3 +-- SU2_CFD/include/drivers/CDriver.hpp | 13 ------------- SU2_CFD/src/drivers/CSinglezoneDriver.cpp | 7 ++----- SU2_CFD/src/python_wrapper_structure.cpp | 2 -- 5 files changed, 3 insertions(+), 35 deletions(-) diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 553b689023f3..0c32f0442882 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -286,7 +286,6 @@ class CConfig { su2double **Giles_FlowDir; /*!< \brief Specified flow direction vector (unit vector) for Giles BC. */ su2double *Inlet_Ptotal; /*!< \brief Specified total pressures for inlet boundaries. */ su2double **Inlet_FlowDir; /*!< \brief Specified flow direction vector (unit vector) for inlet boundaries. */ - //su2double *PointSource; /*!< \brief Specified flow direction vector (unit vector) for inlet boundaries. */ su2double *Inlet_Temperature; /*!< \brief Specified temperatures for a supersonic inlet boundaries. */ su2double *Inlet_Pressure; /*!< \brief Specified static pressures for supersonic inlet boundaries. */ su2double **Inlet_Velocity; /*!< \brief Specified flow velocity vectors for supersonic inlet boundaries. */ @@ -9455,18 +9454,6 @@ class CConfig { */ unsigned long GetnOuter_Iter(void) const { return nOuterIter; } - /*! - * \brief Get the number of inner iterations - * \return Number of inner iterations on each multizone block - */ - void SetnInner_Iter(unsigned long val_iter) { nInnerIter = val_iter; } - - /*! - * \brief Get the number of outer iterations - * \return Number of outer iterations for the multizone problem - */ - void SetnOuter_Iter(unsigned long val_iter) { cout << "inner iter=" << val_iter << endl; nOuterIter = val_iter; } - /*! * \brief Get the number of time iterations * \return Number of time steps run diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index b80fdedfc412..64be5736bca2 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -890,7 +890,6 @@ void CConfig::SetPointersNull() { Inlet_FlowDir = nullptr; Inlet_Temperature = nullptr; Inlet_Pressure = nullptr; Inlet_Velocity = nullptr; Outlet_Pressure = nullptr; Inlet_SpeciesVal = nullptr; Inlet_TurbVal = nullptr; - //PointSource = nullptr; /*--- Engine Boundary Condition settings ---*/ @@ -914,7 +913,7 @@ void CConfig::SetPointersNull() { Inlet_FlowDir = nullptr; Inlet_Temperature = nullptr; Inlet_Pressure = nullptr; Inlet_Velocity = nullptr; Inflow_Mach = nullptr; Inflow_Pressure = nullptr; Outlet_Pressure = nullptr; Isothermal_Temperature = nullptr; - //PointSource = nullptr; + ElasticityMod = nullptr; PoissonRatio = nullptr; MaterialDensity = nullptr; Load_Dir = nullptr; Load_Dir_Value = nullptr; Load_Dir_Multiplier = nullptr; diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index 7c74ed40a854..cbb646e5deff 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -487,19 +487,6 @@ class CDriver : public CDriverBase { */ unsigned long GetNumberOuterIter() const; - - /*! - * \brief Set the number of inner iterations. - * \return Number of inner iterations. - */ - void SetNumberInnerIter(unsigned long); - - /*! - * \brief Set the number of outer iterations. - * \return Number of outer iterations. - */ - void SetNumberOuterIter(unsigned long); - /*! * \brief Get the current solution * \return Current solution diff --git a/SU2_CFD/src/drivers/CSinglezoneDriver.cpp b/SU2_CFD/src/drivers/CSinglezoneDriver.cpp index 8bec4611e58f..ed4d46f370e1 100644 --- a/SU2_CFD/src/drivers/CSinglezoneDriver.cpp +++ b/SU2_CFD/src/drivers/CSinglezoneDriver.cpp @@ -106,10 +106,6 @@ void CSinglezoneDriver::Preprocess(unsigned long TimeIter) { /*--- Set the current time iteration in the config and also in the driver * because the python interface doesn't offer an explicit way of doing it. ---*/ - if (config_container[ZONE_0]->GetTime_Marching() == TIME_MARCHING::STEADY) { - cout << "steady simulation, iteration = " << TimeIter << endl; - config_container[ZONE_0]->SetInnerIter(TimeIter); - } this->TimeIter = TimeIter; config_container[ZONE_0]->SetTimeIter(TimeIter); @@ -117,7 +113,8 @@ void CSinglezoneDriver::Preprocess(unsigned long TimeIter) { /*--- Store the current physical time in the config container, as this can be used for verification / MMS. This should also be more general once the drivers are more stable. ---*/ - if (config_container[ZONE_0]->GetTime_Marching() != TIME_MARCHING::STEADY) + + if (config_container[ZONE_0]->GetTime_Marching() != TIME_MARCHING::STEADY) config_container[ZONE_0]->SetPhysicalTime(static_cast(TimeIter)*config_container[ZONE_0]->GetDelta_UnstTimeND()); else config_container[ZONE_0]->SetPhysicalTime(0.0); diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index 2677eb21943b..1008af2d06a7 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -60,8 +60,6 @@ unsigned long CDriver::GetNumberTimeIter() const { return config_container[selec unsigned long CDriver::GetNumberInnerIter() const { return config_container[selected_zone]->GetnInner_Iter(); } unsigned long CDriver::GetNumberOuterIter() const { return config_container[selected_zone]->GetnOuter_Iter(); } -void CDriver::SetNumberInnerIter(unsigned long nInner) { config_container[selected_zone]->SetnInner_Iter(nInner); } -void CDriver::SetNumberOuterIter(unsigned long nOuter) { config_container[selected_zone]->SetnOuter_Iter(nOuter); } unsigned long CDriver::GetDensity_FreeStreamND() const { return config_container[selected_zone]->GetDensity_FreeStreamND(); } unsigned long CDriver::GetForce_Ref() const { return config_container[selected_zone]->GetForce_Ref(); } From ce0b61e6bcf65912cf1724e72679523ad0dedd11 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Tue, 3 Dec 2024 15:08:08 +0100 Subject: [PATCH 04/61] small cleanup of python file --- TestCases/py_wrapper/custom_source/run.py | 53 +++-------------------- 1 file changed, 6 insertions(+), 47 deletions(-) diff --git a/TestCases/py_wrapper/custom_source/run.py b/TestCases/py_wrapper/custom_source/run.py index c9fcaf4e0ac5..ea08aaf98bc4 100644 --- a/TestCases/py_wrapper/custom_source/run.py +++ b/TestCases/py_wrapper/custom_source/run.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ## \file run.py -# \brief Unsteady inlet boundary conditions. +# \brief Buoyancy force using user defines source term # \version 8.1.0 "Harrier" # # SU2 Project Website: https://su2code.github.io @@ -26,8 +26,6 @@ import sys import pysu2 -import math -import itertools # from mpi4py import MPI def main(): @@ -44,28 +42,17 @@ def main(): print('A TypeError occured in pysu2.CSinglezoneDriver : ', exception) raise - # Get the ID of the inlet marker. - all_marker_ids = driver.GetMarkerIndices() - marker_name = 'x_minus' - marker_id = all_marker_ids[marker_name] if marker_name in all_marker_ids else -1 - - # Run the time loop in python to vary the inlet conditions. - dt = driver.GetUnsteadyTimeStep() - print("\n------------------------------ Begin Solver -----------------------------") sys.stdout.flush() # we need to add a source term to the energy equation. For this, we need to get the solver, and the variable first. # we then loop over all points and for these points, we add the source term nDim = driver.GetNumberDimensions() - nNodes = driver.GetNumberNodes() - #solverindex = driver.GetSolverIndices() - #primindex = driver.GetPrimitiveIndices() # index to the flow solver iSOLVER = driver.GetSolverIndices()['INC.FLOW'] print("index of flow solver = ",iSOLVER) - coords = driver.Coordinates() + # all the indices and the map to the names of the primitives primindex = driver.GetPrimitiveIndices() print("indices of primitives=",primindex) @@ -93,7 +80,6 @@ def main(): custom_source_vector = [0.0 for i in range(nVars)] print("custom source vector = ", custom_source_vector) - inner_iter = driver.GetNumberInnerIter(); print("max. number of inner iterations: ",driver.GetNumberInnerIter()); print("max nr of outer iterations: ",driver.GetNumberOuterIter()); @@ -105,51 +91,24 @@ def main(): print("rho freestream = ",DensityInc_0) Force_Ref = driver.GetForce_Ref() print("reference force = ",Force_Ref) - # get the density from the solution - #residual[iDim+1] = -(DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref; - - #for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): - #print("(x,y) = ( ",coords.Get(i_node,0)," , ",coords.Get(i_node,1)," )") - #custom_source = -9.81 - # we need to set the custom source to the correct primitive equation, in this case let us add it to the y-momentum equation - #i_momy = 2 - #driver.SetCustomSource(iSOLVER, iVar, i_node,custom_source) - #DensityInc_i = driver.GetSolution(iSOLVER,iPoint,2) - #driver.SetPointCustomSource(iSOLVER, i_node,custom_source_vector) - - - # we get the numer of iterations: - - DensityInc_i = 1 - # we set the actual inner iterations to 1 - #for time_iter in range(inner_iter): for inner_iter in range(500): # set the source term, per point - print("loop over nodes and set the source term field") for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): #print("node = ",i_node) - SolutionVector = driver.GetSolutionVector(iSOLVER,i_node) + #SolutionVector = driver.GetSolutionVector(iSOLVER,i_node) #print("solutionvector=",SolutionVector) PrimitiveVector = driver.GetPrimitiveVector(iSOLVER,i_node) #print("primitivevector=",PrimitiveVector) DensityInc_i = PrimitiveVector[iDENSITY] - #residual[iDim+1] = -Volume * (DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref; + for iDim in range(nDim): custom_source_vector[iDim+1] = -(DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref + #print("density=",DensityInc_i) driver.SetPointCustomSource(iSOLVER, i_node,custom_source_vector) - print("end setting custom source term") - - # Change the total pressure. - #if marker_id >= 0: - # for i_vertex in range(driver.GetNumberMarkerNodes(marker_id)): - # y = driver.MarkerCoordinates(marker_id)(i_vertex, 1) - # t = time_iter * dt - # pt = 1e5 + 2e4 * y / 0.01 * (1 - math.cos(2 * math.pi * t / 0.1)) - # driver.SetMarkerCustomInletFlowVar1(marker_id, i_vertex, pt) - #driver.BoundaryConditionsUpdate() + print(" *** inner iteration:",inner_iter) driver.Preprocess(inner_iter) From d8d30a4c871ae219798e8618f65264070d3caeb8 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Tue, 3 Dec 2024 15:25:36 +0100 Subject: [PATCH 05/61] small cleanup --- SU2_CFD/include/drivers/CDriverBase.hpp | 49 +++++++++---------- .../include/solvers/CFVMFlowSolverBase.hpp | 14 +++--- 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index 699379ab444d..7a4988d76eb5 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -762,47 +762,49 @@ class CDriverBase { /*! * \brief Set the array of variables for the source in the point - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \param[in] value - Value of the variable. + * \param[in] iSolver - Solver index. + * \param[in] iPoint - Point index. + * \param[in] values - Vector values of the source term. */ - void SetPointCustomSource(unsigned short iSOLVER, unsigned long iPoint, std::vector values) { - //for (auto iVar = 0ul; iVar < nVar; ++iDim) { - //GetSolverAndCheckField(FLOW_SOL, iPoint)->SetCustomPointSource (iPoint, value); - auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSOLVER]; + void SetPointCustomSource(unsigned short iSolver, unsigned long iPoint, std::vector values) { + auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; solver->SetCustomPointSource(iPoint, values); } -// return solution vector -inline vector GetSolutionVector(unsigned short iSOLVER, unsigned long iPoint) { - auto* solver = solver_container[iSOLVER][INST_0][MESH_0][iSOLVER]; + /*! + * \brief Get the solution vector in a point for a specific solver + * \param[in] iSolver - Solver index. + * \param[in] iPoint - Point index. + * \param[out] solutionvector - Vector values of the solution. + */ +inline vector GetSolutionVector(unsigned short iSolver, unsigned long iPoint) { + auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; auto* nodes = solver->GetNodes(); - auto nVar = GetNumberSolverVars(iSOLVER); - //cout << "getting solution: "<GetSolution(iPoint,2); - //cout << "value : " << val << endl; + auto nVar = GetNumberSolverVars(iSolver); vector solutionvector(nVar, 0.0); for (auto iVar = 0u; iVar < nVar; ++iVar) { solutionvector[iVar] = SU2_TYPE::GetValue(nodes->GetSolution(iPoint,iVar)); - //cout << "vector = " << solutionvector[iVar] << endl; } return solutionvector; } -inline vector GetPrimitiveVector(unsigned short iSOLVER, unsigned long iPoint) { - auto* solver = solver_container[iSOLVER][INST_0][MESH_0][iSOLVER]; + /*! + * \brief Get the primitive variables vector in a point for a specific solver + * \param[in] iSolver - Solver index. + * \param[in] iPoint - Point index. + * \param[out] solutionvector - Vector values of the primitive variables. + */ +inline vector GetPrimitiveVector(unsigned short iSolver, unsigned long iPoint) { + auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; auto* nodes = solver->GetNodes(); - auto nPrimvar = GetNumberPrimitiveVars(iSOLVER); - //cout << "getting solution: "<GetSolution(iPoint,2); - //cout << "value : " << val << endl; + auto nPrimvar = GetNumberPrimitiveVars(iSolver); vector solutionvector(nPrimvar, 0.0); for (auto iVar = 0u; iVar < nPrimvar; ++iVar) { solutionvector[iVar] = SU2_TYPE::GetValue(nodes->GetPrimitive(iPoint,iVar)); - //cout << "vector = " << solutionvector[iVar] << endl; } return solutionvector; } + /// \} protected: @@ -826,9 +828,6 @@ inline vector GetPrimitiveVector(unsigned short iSOLVER, unsigned unsigned long iPoint = std::numeric_limits::max()) const { // 1. check for the solver the number of variables // 2. check for the mesh the number of points - //if (iPoint < std::numeric_limits::max() && iPoint > GetNumberMarkers()) { - // SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION); - //} auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; if (solver == nullptr) SU2_MPI::Error("The selected solver does not exist.", CURRENT_FUNCTION); return solver; diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp index 9aacffc9c2fb..3547d97376ab 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp @@ -2225,16 +2225,14 @@ class CFVMFlowSolverBase : public CSolver { vector val_source) final { /*--- Since this call can be accessed indirectly using python, do some error * checking to prevent segmentation faults ---*/ - //if (val_marker >= nMarker) - // SU2_MPI::Error("Out-of-bounds marker index used on inlet.", CURRENT_FUNCTION); - //else if (val_vertex >= nVertex[val_marker]) - // SU2_MPI::Error("Out-of-bounds vertex index used on inlet.", CURRENT_FUNCTION); - //else - //cout << "value list size=" << val_source.size() << endl; - //cout << "pointsource.size = " << nVar << endl; - //cout << "point,npoint=" << val_point << " " << nPointDomain << endl; + if (val_point > nPointDomain) + SU2_MPI::Error("Out-of-bounds point index used on solver.", CURRENT_FUNCTION); + else if (val_source.size() > nVar) + SU2_MPI::Error("Out-of-bounds source size used on solver.", CURRENT_FUNCTION); + else { for (unsigned short iVar=0; iVar < val_source.size(); iVar++) PointSource[val_point][iVar] = val_source[iVar]; + } } /*! From 488efa066788ee0fbcbd24e73f4d6f5443a5d553 Mon Sep 17 00:00:00 2001 From: Nijso Date: Tue, 3 Dec 2024 16:18:57 +0100 Subject: [PATCH 06/61] Update SU2_CFD/include/drivers/CDriverBase.hpp --- SU2_CFD/include/drivers/CDriverBase.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index 7a4988d76eb5..fb7f73c46a15 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -183,7 +183,6 @@ class CDriverBase { * \brief Get the number of solution variables * \return Number of solution variables. */ - //unsigned long GetNumberSolverVars() const; unsigned short GetNumberSolverVars(const unsigned short iSol) const; unsigned short GetNumberPrimitiveVars(const unsigned short iSol) const; From 40e1d9761e1c514f3a6c84824b215f414408f005 Mon Sep 17 00:00:00 2001 From: Nijso Date: Tue, 3 Dec 2024 16:19:32 +0100 Subject: [PATCH 07/61] Fix code scanning alert no. 5107: Comparison of narrow type with wide type in loop condition Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp index 3547d97376ab..c10ff9ea3460 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp @@ -2230,7 +2230,7 @@ class CFVMFlowSolverBase : public CSolver { else if (val_source.size() > nVar) SU2_MPI::Error("Out-of-bounds source size used on solver.", CURRENT_FUNCTION); else { - for (unsigned short iVar=0; iVar < val_source.size(); iVar++) + for (size_t iVar=0; iVar < val_source.size(); iVar++) PointSource[val_point][iVar] = val_source[iVar]; } } From b77fd09582a2857f1c7010a35b962b76393f0364 Mon Sep 17 00:00:00 2001 From: Nijso Date: Tue, 3 Dec 2024 16:20:05 +0100 Subject: [PATCH 08/61] Update SU2_CFD/include/solvers/CFVMFlowSolverBase.inl --- SU2_CFD/include/solvers/CFVMFlowSolverBase.inl | 2 -- 1 file changed, 2 deletions(-) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index b9bcdc451f2a..3f10ef7885ed 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -123,8 +123,6 @@ void CFVMFlowSolverBase::Allocate(const CConfig& config) { /*--- Store the value of the Flow direction at the inlet BC ---*/ AllocVectorOfMatrices(nVertex, nDim, Inlet_FlowDir); - - //AllocVectorOfVectors(nPointDomain, PointSource); PointSource.resize(nPointDomain,nVar); /*--- Force definition and coefficient arrays for all of the markers ---*/ From 4904b1992772dce28d65cba37cbc570049263f47 Mon Sep 17 00:00:00 2001 From: Nijso Date: Tue, 3 Dec 2024 16:20:27 +0100 Subject: [PATCH 09/61] Update SU2_CFD/src/numerics/flow/flow_sources.cpp --- SU2_CFD/src/numerics/flow/flow_sources.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/SU2_CFD/src/numerics/flow/flow_sources.cpp b/SU2_CFD/src/numerics/flow/flow_sources.cpp index b5c29a6325f0..93aab49d9306 100644 --- a/SU2_CFD/src/numerics/flow/flow_sources.cpp +++ b/SU2_CFD/src/numerics/flow/flow_sources.cpp @@ -427,7 +427,6 @@ CNumerics::ResidualType<> CSourceIncBodyForce::ComputeResidual(const CConfig* co residual[nDim+1] = 0.0; - //cout << "residual = " << residual[0] << " " << residual[1] << " " << residual[2] << " " <(residual, jacobian, nullptr); } From d4ac82b0658a25fd7a075cee8196504f463bb7aa Mon Sep 17 00:00:00 2001 From: Nijso Date: Tue, 3 Dec 2024 16:20:50 +0100 Subject: [PATCH 10/61] Update SU2_CFD/src/drivers/CDriverBase.cpp --- SU2_CFD/src/drivers/CDriverBase.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/SU2_CFD/src/drivers/CDriverBase.cpp b/SU2_CFD/src/drivers/CDriverBase.cpp index 7ea823800954..2a6742fe6006 100644 --- a/SU2_CFD/src/drivers/CDriverBase.cpp +++ b/SU2_CFD/src/drivers/CDriverBase.cpp @@ -165,7 +165,6 @@ unsigned long CDriverBase::GetNumberDimensions() const { return main_geometry->G unsigned long CDriverBase::GetNumberElements() const { return main_geometry->GetnElem(); } -//unsigned long CDriverBase::GetNumberSolverVars() const { return main_geometry->GetnElem(); } unsigned short CDriverBase::GetNumberSolverVars(const unsigned short iSol) const { return solver_container[selected_zone][INST_0][MESH_0][iSol]->GetnVar(); } unsigned short CDriverBase::GetNumberPrimitiveVars(const unsigned short iSol) const { return solver_container[selected_zone][INST_0][MESH_0][iSol]->GetnPrimVar(); } From ce99e017d9a9da551e6321e47ba22095f0d6c45d Mon Sep 17 00:00:00 2001 From: bigfooted Date: Mon, 6 Jan 2025 16:22:32 +0100 Subject: [PATCH 11/61] Turbulent combustion (TFC) --- Common/include/option_structure.hpp | 4 +- SU2_CFD/include/drivers/CDriverBase.hpp | 39 +++ .../include/solvers/CFVMFlowSolverBase.hpp | 1 + .../include/solvers/CFVMFlowSolverBase.inl | 3 +- SU2_CFD/include/solvers/CScalarSolver.hpp | 2 + SU2_CFD/include/solvers/CScalarSolver.inl | 1 + SU2_CFD/include/solvers/CSpeciesSolver.hpp | 49 +++ SU2_CFD/src/numerics/flow/flow_sources.cpp | 1 - SU2_CFD/src/solvers/CIncEulerSolver.cpp | 8 + SU2_CFD/src/solvers/CSpeciesSolver.cpp | 48 ++- SU2_CFD/src/solvers/CTurbSSTSolver.cpp | 1 + .../lam_buoyancy_cavity.cfg | 120 +++++++ .../py_wrapper/custom_initialization/run.py | 146 +++++++++ .../py_wrapper/turbulent_premixed_psi/psi.cfg | 167 ++++++++++ .../py_wrapper/turbulent_premixed_psi/run.py | 304 ++++++++++++++++++ 15 files changed, 890 insertions(+), 4 deletions(-) create mode 100644 TestCases/py_wrapper/custom_initialization/lam_buoyancy_cavity.cfg create mode 100644 TestCases/py_wrapper/custom_initialization/run.py create mode 100644 TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg create mode 100644 TestCases/py_wrapper/turbulent_premixed_psi/run.py diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index ddf570ab6978..59c0e6fa8c93 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -549,7 +549,8 @@ enum ENUM_FLUIDMODEL { FLUID_MIXTURE = 9, /*!< \brief Species mixture model. */ COOLPROP = 10, /*!< \brief Thermodynamics library. */ FLUID_FLAMELET = 11, /*!< \brief lookup table (LUT) method for premixed flamelets. */ - DATADRIVEN_FLUID = 12, /*!< \brief multi-layer perceptron driven fluid model. */ + DATADRIVEN_FLUID = 12, /*!< \brief multi-layer perceptron driven fluid model. */ + USER_DEFINED = 13, /*!< \brief user defined through python wrapper. */ }; static const MapType FluidModel_Map = { MakePair("STANDARD_AIR", STANDARD_AIR) @@ -565,6 +566,7 @@ static const MapType FluidModel_Map = { MakePair("COOLPROP", COOLPROP) MakePair("DATADRIVEN_FLUID", DATADRIVEN_FLUID) MakePair("FLUID_FLAMELET", FLUID_FLAMELET) + MakePair("USER_DEFINED", USER_DEFINED) }; /*! diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index fb7f73c46a15..d20de93bc004 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -767,6 +767,9 @@ class CDriverBase { */ void SetPointCustomSource(unsigned short iSolver, unsigned long iPoint, std::vector values) { auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; + + //if (values[0]>1.0e-6) + // cout << "iPoint="<SetCustomPointSource(iPoint, values); } @@ -787,6 +790,23 @@ inline vector GetSolutionVector(unsigned short iSolver, unsigned return solutionvector; } +/* The vector with actual solution values */ +inline void SetSolutionVector(unsigned short iSolver, unsigned long iPoint, vector solutionVector) { + auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; + auto* nodes = solver->GetNodes(); + + /*--- check the size of the solver variables ---*/ + unsigned short nVar = GetNumberSolverVars(iSolver); + if (nVar != solutionVector.size() ) + SU2_MPI::Error("Solution Vector size is not equal to Solver size.", CURRENT_FUNCTION); + //cout << "setting solution vector " << nodes->GetSolution(iPoint,0) << " " << solutionVector[0] << ", "<< nVar<< endl; + for (unsigned int iVar = 0u; iVar < nVar; ++iVar) { + nodes->SetSolution(iPoint,iVar, solutionVector[iVar]); + nodes->SetSolution_Old(iPoint,iVar, solutionVector[iVar]); + } +} + + /*! * \brief Get the primitive variables vector in a point for a specific solver * \param[in] iSolver - Solver index. @@ -804,6 +824,25 @@ inline vector GetPrimitiveVector(unsigned short iSolver, unsigned return solutionvector; } + + /*! + * \brief Get the primitive variables vector in a point for a specific solver + * \param[in] iSolver - Solver index. + * \param[in] iPoint - Point index. + * \param[out] solutionvector - Vector values of the primitive variables. + */ +inline void SetPrimitiveVector(unsigned short iSolver, unsigned long iPoint, vector primitiveVector) { + auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; + auto* nodes = solver->GetNodes(); + auto nPrimvar = GetNumberPrimitiveVars(iSolver); + vector solutionvector(nPrimvar, 0.0); + //cout << "setting primitive vector " << nodes->GetPrimitive(iPoint,0) << " " << primitiveVector[0] << ", "<< nPrimvar<< endl; + + for (auto iVar = 0u; iVar < nPrimvar; ++iVar) { + nodes->SetPrimitive(iPoint,iVar, primitiveVector[iVar]); + } +} + /// \} protected: diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp index c10ff9ea3460..d0a3148af523 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp @@ -2225,6 +2225,7 @@ class CFVMFlowSolverBase : public CSolver { vector val_source) final { /*--- Since this call can be accessed indirectly using python, do some error * checking to prevent segmentation faults ---*/ + //cout << "flow" << endl; if (val_point > nPointDomain) SU2_MPI::Error("Out-of-bounds point index used on solver.", CURRENT_FUNCTION); else if (val_source.size() > nVar) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 3f10ef7885ed..ece65845ce00 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -124,7 +124,8 @@ void CFVMFlowSolverBase::Allocate(const CConfig& config) { AllocVectorOfMatrices(nVertex, nDim, Inlet_FlowDir); PointSource.resize(nPointDomain,nVar); - + PointSource.setConstant(0.0); + /*--- Force definition and coefficient arrays for all of the markers ---*/ AllocVectorOfVectors(nVertex, CPressure); diff --git a/SU2_CFD/include/solvers/CScalarSolver.hpp b/SU2_CFD/include/solvers/CScalarSolver.hpp index 12bc885887ce..68254e481306 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.hpp +++ b/SU2_CFD/include/solvers/CScalarSolver.hpp @@ -64,6 +64,7 @@ class CScalarSolver : public CSolver { vector > SlidingState; // vector of matrix of pointers... inner dim alloc'd elsewhere (welcome, to the twilight zone) vector > SlidingStateNodes; + /*--- Shallow copy of grid coloring for OpenMP parallelization. ---*/ #ifdef HAVE_OMP @@ -578,4 +579,5 @@ class CScalarSolver : public CSolver { return SlidingStateNodes[val_marker][val_vertex]; } + }; diff --git a/SU2_CFD/include/solvers/CScalarSolver.inl b/SU2_CFD/include/solvers/CScalarSolver.inl index 1411de2ca787..6d54bc225524 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.inl +++ b/SU2_CFD/include/solvers/CScalarSolver.inl @@ -36,6 +36,7 @@ CScalarSolver::CScalarSolver(CGeometry* geometry, CConfig* config, config->GetNEMOProblem(), geometry->GetnDim(), config->GetnSpecies()) { nMarker = config->GetnMarker_All(); + /*--- Store the number of vertices on each marker for deallocation later ---*/ nVertex.resize(nMarker); for (unsigned long iMarker = 0; iMarker < nMarker; iMarker++) nVertex[iMarker] = geometry->nVertex[iMarker]; diff --git a/SU2_CFD/include/solvers/CSpeciesSolver.hpp b/SU2_CFD/include/solvers/CSpeciesSolver.hpp index 7236989afd46..fca2cc75c3a8 100644 --- a/SU2_CFD/include/solvers/CSpeciesSolver.hpp +++ b/SU2_CFD/include/solvers/CSpeciesSolver.hpp @@ -40,6 +40,7 @@ class CSpeciesSolver : public CScalarSolver { protected: unsigned short Inlet_Position; /*!< \brief Column index for scalar variables in inlet files. */ vector Inlet_SpeciesVars; /*!< \brief Species variables at inlet profiles. */ + su2activematrix SpeciesPointSource; /*!< \brief Value of the Flow Direction. */ public: /*! @@ -162,6 +163,16 @@ class CSpeciesSolver : public CScalarSolver { */ void Source_Residual(CGeometry* geometry, CSolver** solver_container, CNumerics** numerics_container, CConfig* config, unsigned short iMesh) override; +/*! + * \brief Source term computation for axisymmetric flow. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics_container - Container for description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Custom_Source_Residual(CGeometry* geometry, CSolver** solver_container, CNumerics** numerics_container, CConfig* config, + unsigned short iMesh) override; /*! @@ -183,4 +194,42 @@ class CSpeciesSolver : public CScalarSolver { }, geometry, solver_container, conv_numerics, visc_numerics, config); } + + + /*! + * \brief Set a component of the unit vector representing the flow direction at an inlet boundary. + * \param[in] val_marker - Surface marker where the flow direction is set. + * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is set. + * \param[in] val_dim - The component of the flow direction unit vector to be set + * \param[in] val_flowdir - Component of a unit vector representing the flow direction. + */ + inline void SetCustomPointSource(unsigned long val_point, + vector val_source) final { + /*--- Since this call can be accessed indirectly using python, do some error + * checking to prevent segmentation faults ---*/ + //cout << "***** set custom point source species *****" << endl; + if (val_point > nPointDomain) + SU2_MPI::Error("Out-of-bounds point index used on solver.", CURRENT_FUNCTION); + else if (val_source.size() > nVar) + SU2_MPI::Error("Out-of-bounds source size used on solver.", CURRENT_FUNCTION); + else { + for (size_t iVar=0; iVar < val_source.size(); iVar++) { + SpeciesPointSource[val_point][iVar] = val_source[iVar]; + //if (SpeciesPointSource[val_point][iVar] > 1.0e-6) + // cout << iVar<<", setcustompointsource: "<< SpeciesPointSource[val_point][iVar] << endl; + } + } + } +/*! + * \brief A component of the unit vector representing the flow direction at an inlet boundary. + * \param[in] val_marker - Surface marker where the flow direction is evaluated + * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is evaluated + * \param[in] val_dim - The component of the flow direction unit vector to be evaluated + * \return Component of a unit vector representing the flow direction. + */ + inline su2double GetCustomPointSource(unsigned long val_point, + unsigned short val_var) const final { + return SpeciesPointSource[val_point][val_var]; + } + }; diff --git a/SU2_CFD/src/numerics/flow/flow_sources.cpp b/SU2_CFD/src/numerics/flow/flow_sources.cpp index 93aab49d9306..ca0f40b104f6 100644 --- a/SU2_CFD/src/numerics/flow/flow_sources.cpp +++ b/SU2_CFD/src/numerics/flow/flow_sources.cpp @@ -427,7 +427,6 @@ CNumerics::ResidualType<> CSourceIncBodyForce::ComputeResidual(const CConfig* co residual[nDim+1] = 0.0; - return ResidualType<>(residual, jacobian, nullptr); } diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index 18f60dfbffa4..9c2bc668ad05 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -303,6 +303,10 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i config->SetGas_Constant(UNIVERSAL_GAS_CONSTANT/(config->GetMolecular_Weight()/1000.0)); Pressure_Thermodynamic = Density_FreeStream*Temperature_FreeStream*config->GetGas_Constant(); + cout << "gas constant = " << config->GetGas_Constant() << endl; + cout << "pressure = " << Pressure_Thermodynamic << endl; + cout << "rho="<< Density_FreeStream<< endl; + cout << "T="<< Temperature_FreeStream<< endl; auxFluidModel = new CIncIdealGas(config->GetSpecific_Heat_Cp(), config->GetGas_Constant(), Pressure_Thermodynamic); auxFluidModel->SetTDState_T(Temperature_FreeStream); Pressure_Thermodynamic = auxFluidModel->GetPressure(); @@ -342,6 +346,9 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i auxFluidModel->SetTDState_T(Temperature_FreeStream, config->GetSpecies_Init()); break; + case USER_DEFINED: + break; + default: SU2_MPI::Error("Fluid model not implemented for incompressible solver.", CURRENT_FUNCTION); @@ -1835,6 +1842,7 @@ void CIncEulerSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solv /*--- Compute the residual for this control volume and subtract. ---*/ for (iVar = 0; iVar < nVar; iVar++) { + //cout << iPoint << " " << iVar << ",S="<< PointSource[iPoint][iVar]<< endl; LinSysRes[iPoint*nVar+iVar] += PointSource[iPoint][iVar] * Volume; } // cout << "source = " << iPoint << " " << PointSource[iPoint][0]*Volume diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index 9d7c4494c516..dddf70d199d6 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -94,6 +94,7 @@ void CSpeciesSolver::Initialize(CGeometry* geometry, CConfig* config, unsigned s /*--- Store if an implicit scheme is used, for use during periodic boundary conditions. ---*/ SetImplicitPeriodic(config->GetKind_TimeIntScheme_Species() == EULER_IMPLICIT); + nPrimVar = nVar; if (nVar > MAXNVAR) @@ -111,6 +112,12 @@ void CSpeciesSolver::Initialize(CGeometry* geometry, CConfig* config, unsigned s nDim = geometry->GetnDim(); + + std::cout << "resize species pointsource, nVar="<GetFilename(config->GetSolution_FileName(), "", val_iter); /*--- To make this routine safe to call in parallel most of it can only be executed by one thread. ---*/ @@ -569,3 +576,42 @@ void CSpeciesSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta END_SU2_OMP_FOR } } + + +void CSpeciesSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, + CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { + + /*--- Pick one numerics object per thread. ---*/ + CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; + + unsigned short iVar; + unsigned long iPoint; + AD::StartNoSharedReading(); + + SU2_OMP_FOR_STAT(omp_chunk_size) + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Load the volume of the dual mesh cell ---*/ + + numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + + /*--- Get control volume size. ---*/ + su2double Volume = geometry->nodes->GetVolume(iPoint); + + /*--- Compute the residual for this control volume and subtract. ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + //if (SpeciesPointSource[iPoint][iVar] > 1.0e-6) + //cout << iPoint << " " << iVar << ",Species ="<< SpeciesPointSource[iPoint][iVar]<< endl; + LinSysRes[iPoint*nVar+iVar] -= SpeciesPointSource[iPoint][iVar] * Volume; + } + // cout << "source = " << iPoint << " " << PointSource[iPoint][0]*Volume + // << " " << PointSource[iPoint][1]*Volume + // << " " << PointSource[iPoint][2]*Volume + // << " " << PointSource[iPoint][3]*Volume << endl; + + } + END_SU2_OMP_FOR + + AD::EndNoSharedReading(); + +} diff --git a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp index 02b91c8ab2cf..3a4d45c5ebb0 100644 --- a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp @@ -191,6 +191,7 @@ CTurbSSTSolver::CTurbSSTSolver(CGeometry *geometry, CConfig *config, unsigned sh /*--- Add the solver name. ---*/ SolverName = "SST"; + cout << "end initialize sst" << endl; } void CTurbSSTSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, diff --git a/TestCases/py_wrapper/custom_initialization/lam_buoyancy_cavity.cfg b/TestCases/py_wrapper/custom_initialization/lam_buoyancy_cavity.cfg new file mode 100644 index 000000000000..470a895b372a --- /dev/null +++ b/TestCases/py_wrapper/custom_initialization/lam_buoyancy_cavity.cfg @@ -0,0 +1,120 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Buoyancy-driven flow inside a cavity % +% Author: Thomas D. Economon % +% Date: 2018.06.10 % +% File Version 8.1.0 "Harrier" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= INC_NAVIER_STOKES +KIND_TURB_MODEL= NONE +MATH_PROBLEM= DIRECT +RESTART_SOL= NO + +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +INC_DENSITY_MODEL= VARIABLE +INC_ENERGY_EQUATION = YES +% +% Uncomment a density below for a desired Rayleigh number +%INC_DENSITY_INIT= 0.00018903539834 % Ra ~ 1e3 +%INC_DENSITY_INIT= 0.00059778241716 % Ra ~ 1e4 +%INC_DENSITY_INIT= 0.00189035398341 % Ra ~ 1e5 +INC_DENSITY_INIT= 0.00597782417156 % Ra ~ 1e6 +% +INC_VELOCITY_INIT= ( 1.0, 0.0, 0.0 ) +INC_TEMPERATURE_INIT= 288.15 + +% ---- IDEAL GAS, POLYTROPIC, VAN DER WAALS AND PENG ROBINSON CONSTANTS -------% +% +FLUID_MODEL= INC_IDEAL_GAS +SPECIFIC_HEAT_CP= 1004.703 +MOLECULAR_WEIGHT= 28.96 + +% --------------------------- VISCOSITY MODEL ---------------------------------% +% +VISCOSITY_MODEL= CONSTANT_VISCOSITY +MU_CONSTANT= 1.716e-5 + +% --------------------------- THERMAL CONDUCTIVITY MODEL ----------------------% +% +CONDUCTIVITY_MODEL= CONSTANT_CONDUCTIVITY +THERMAL_CONDUCTIVITY_CONSTANT= 0.0246295028571 + +% ----------------------- BODY FORCE DEFINITION -------------------------------% +% +BODY_FORCE= NO +BODY_FORCE_VECTOR= ( 0.0, -9.81, 0.0 ) + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +REF_ORIGIN_MOMENT_X = 0.25 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +REF_AREA= 1.0 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( upper, 0.0, lower, 0.0 ) +MARKER_ISOTHERMAL= ( left, 461.04, right, 115.26 ) +MARKER_PLOTTING= ( upper, left, right, lower ) +MARKER_MONITORING= ( NONE ) + +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= GREEN_GAUSS +CFL_NUMBER= 50 +CFL_ADAPT= NO +CFL_ADAPT_PARAM= ( 1.5, 0.5, 15.0, 1e10) +MAX_DELTA_TIME= 1E6 +RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) +ITER=1 + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ILU_FILL_IN= 0 +LINEAR_SOLVER_ERROR= 1E-15 +LINEAR_SOLVER_ITER= 20 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= FDS +MUSCL_FLOW= YES +SLOPE_LIMITER_FLOW= NONE +TIME_DISCRE_FLOW= EULER_IMPLICIT + + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_RESIDUAL_MINVAL= -12 +CONV_STARTITER= 10 +CONV_CAUCHY_ELEMS= 100 +CONV_CAUCHY_EPS= 1E-6 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FILENAME= mesh_cavity_65x65.su2 +MESH_FORMAT= SU2 +MESH_OUT_FILENAME= mesh_out.su2 +SOLUTION_FILENAME= solution_flow.dat +SOLUTION_ADJ_FILENAME= solution_adj.dat +TABULAR_FORMAT= CSV +CONV_FILENAME= history +RESTART_FILENAME= restart_flow.dat +RESTART_ADJ_FILENAME= restart_adj.dat +VOLUME_FILENAME= flow +VOLUME_ADJ_FILENAME= adjoint +GRAD_OBJFUNC_FILENAME= of_grad.dat +SURFACE_FILENAME= surface_flow +SURFACE_ADJ_FILENAME= surface_adjoint +OUTPUT_WRT_FREQ= 100 +SCREEN_OUTPUT= (OUTER_ITER, INNER_ITER, RMS_PRESSURE, RMS_TEMPERATURE, LIFT, DRAG) + +% ----------------------- GEOMETRY EVALUATION PARAMETERS ----------------------% +GEO_BOUNDS= ( 0.499, 0.501) diff --git a/TestCases/py_wrapper/custom_initialization/run.py b/TestCases/py_wrapper/custom_initialization/run.py new file mode 100644 index 000000000000..757b464a9c9e --- /dev/null +++ b/TestCases/py_wrapper/custom_initialization/run.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python + +## \file run.py +# \brief Buoyancy force using user defines source term +# \version 8.1.0 "Harrier" +# +# SU2 Project Website: https://su2code.github.io +# +# The SU2 Project is maintained by the SU2 Foundation +# (http://su2foundation.org) +# +# Copyright 2012-2024, 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 . + +import sys +import pysu2 +# from mpi4py import MPI + +def main(): + """ + Run the flow solver with a custom inlet (function of time and space). + """ + # comm = MPI.COMM_WORLD + comm = 0 + + # Initialize the primal driver of SU2, this includes solver preprocessing. + try: + driver = pysu2.CSinglezoneDriver('lam_buoyancy_cavity.cfg', 1, comm) + except TypeError as exception: + print('A TypeError occured in pysu2.CSinglezoneDriver : ', exception) + raise + + print("\n------------------------------ Begin Solver -----------------------------") + sys.stdout.flush() + + # we need to add a source term to the energy equation. For this, we need to get the solver, and the variable first. + # we then loop over all points and for these points, we add the source term + nDim = driver.GetNumberDimensions() + + # index to the flow solver + # C.FLOW + # INC.FLOW + # HEAT + # FLAMELET + # SPECIES + # SA + # SST + iSOLVER = driver.GetSolverIndices()['INC.FLOW'] + print("index of flow solver = ",iSOLVER) + + # all the indices and the map to the names of the primitives + primindex = driver.GetPrimitiveIndices() + print("indices of primitives=",primindex) + print("number of primitives:",len(primindex)) + + nElem = driver.GetNumberElements() + print("number of elements:",nElem) + + nVars = driver.GetNumberSolverVars(iSOLVER) + print("number of solver variables:",nVars) + varindex = primindex.copy() + for prim in varindex.copy(): + if varindex[prim] >=nVars: + del varindex[prim] + varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) + + +# it is possible to get the solver type by doing +# iSOLVER = driver.GetSolverIndices()['INC.FLOW'] +# with the solver type we then get the solver variables using: + +# nVars = driver.GetNumberSolverVars(iSOLVER) +# and the solver variable names: +# print("solver variable names:",varindex) + +# we can overwrite the solution using: +# driver.SetSolutionVector(iSolver, iPoint, solutionVector) +# + + print("solver variable names:",varindex) + iDENSITY = primindex.get("DENSITY") + print("index of density = ",iDENSITY) + + index_Vel = varindex.get("VELOCITY_X") + print("index of velocity = ",index_Vel) + custom_source_vector = [0.0 for i in range(nVars)] + print("custom source vector = ", custom_source_vector) + + print("max. number of inner iterations: ",driver.GetNumberInnerIter()); + print("max nr of outer iterations: ",driver.GetNumberOuterIter()); + + # is in domain: isdomain = driver.GetNodeDomain(iPoint) + #for i_vertex in range(n_vertex) + #AllSolutions = driver.GetAllSolutions(iSOLVER) + Body_Force_Vector = [0.0, -9.81, 0.0] + DensityInc_0 = driver.GetDensity_FreeStreamND() + print("rho freestream = ",DensityInc_0) + Force_Ref = driver.GetForce_Ref() + print("reference force = ",Force_Ref) + + for inner_iter in range(500): + + # set the source term, per point + for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): + #print("node = ",i_node) + #SolutionVector = driver.GetSolutionVector(iSOLVER,i_node) + #print("solutionvector=",SolutionVector) + PrimitiveVector = driver.GetPrimitiveVector(iSOLVER,i_node) + #print("primitivevector=",PrimitiveVector) + DensityInc_i = PrimitiveVector[iDENSITY] + + for iDim in range(nDim): + custom_source_vector[iDim+1] = -(DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref + + #print("density=",DensityInc_i) + driver.SetPointCustomSource(iSOLVER, i_node,custom_source_vector) + + print(" *** inner iteration:",inner_iter) + driver.Preprocess(inner_iter) + + # Run one time iteration. + driver.Run() + driver.Postprocess() + driver.Update() + + # Monitor the solver and output solution to file if required. + #driver.Monitor(inner_iter) + driver.Output(inner_iter) + + # Finalize the solver and exit cleanly. + driver.Finalize() + +if __name__ == '__main__': + main() diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg b/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg new file mode 100644 index 000000000000..ee0cfb797a75 --- /dev/null +++ b/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg @@ -0,0 +1,167 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Species mixing with 3 species, i.e. 2 transport equations % +% Author: T. Kattmann % +% Institution: Bosch Thermotechniek B.V. % +% Date: 2021/10/14 % +% File Version 7.5.1 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= INC_RANS +KIND_TURB_MODEL= SST +SST_OPTIONS= V1994m + +MGLEVEL= 0 +% + +% temperature and density +FREESTREAM_TEMPERATURE = 673 +FREESTREAM_DENSITY = 2.55 +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +%INC_DENSITY_MODEL= CONSTANT +INC_DENSITY_MODEL= VARIABLE +INC_DENSITY_INIT= 2.55 +% +INC_VELOCITY_INIT= (40.00, 0.0, 0.0 ) +% +INC_ENERGY_EQUATION= YES +INC_TEMPERATURE_INIT= 673.0 +% +INC_NONDIM= DIMENSIONAL +% +% -------------------- FLUID PROPERTIES ------------------------------------- % +% +%FLUID_MODEL= CONSTANT_DENSITY +FLUID_MODEL= INC_IDEAL_GAS +% +CONDUCTIVITY_MODEL= CONSTANT_CONDUCTIVITY +THERMAL_CONDUCTIVITY_CONSTANT= 0.0357 +% +PRANDTL_LAM= 0.72 +TURBULENT_CONDUCTIVITY_MODEL= NONE +PRANDTL_TURB= 0.90 +% +VISCOSITY_MODEL= SUTHERLAND +MU_CONSTANT= 1.716E-5 +MU_REF = 1.716e-5 +MU_T_REF= 273.15 +SUTHERLAND_CONSTANT = 110.4 + +SPECIFIC_HEAT_CP = 1150 +% +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( wall_top, 0.0,wall_side,0.0,wall_pipe,0.0, wall_out, 0.0 ) + +% note, case is axisymmetric +MARKER_SYM= ( symmetry ) +AXISYMMETRIC= YES +% +SPECIFIED_INLET_PROFILE= YES +INLET_FILENAME= inlet.dat +%INLET_INTERPOLATION_FUNCTION= LINEAR_1D +INC_INLET_TYPE= VELOCITY_INLET +INC_INLET_DAMPING= 0.01 +MARKER_INLET= ( inlet, 673, 40.0, 1.0, 0.0, 0.0) +MARKER_INLET_TURBULENT = (inlet, 0.10, 15) +MARKER_INLET_SPECIES= (inlet, 0.0) +% +INC_OUTLET_TYPE= PRESSURE_OUTLET +INC_OUTLET_DAMPING= 0.01 +MARKER_OUTLET= ( outlet, 0.0 ) +% +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES +% +%CFL_NUMBER= 25.0 +CFL_NUMBER= 20.0 +CFL_REDUCTION_SPECIES= 1.0 +CFL_REDUCTION_TURB= 1.0 +% +% Run commented Iter for good results +ITER= 1 +% +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1E-8 +LINEAR_SOLVER_ITER= 5 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= FDS +MUSCL_FLOW= NO +SLOPE_LIMITER_FLOW = NONE +TIME_DISCRE_FLOW= EULER_IMPLICIT +% +% -------------------- SCALAR TRANSPORT ---------------------------------------% +% +KIND_SCALAR_MODEL= SPECIES_TRANSPORT +%DIFFUSIVITY_MODEL= CONSTANT_SCHMIDT +DIFFUSIVITY_MODEL= CONSTANT_DIFFUSIVITY +SCHMIDT_NUMBER_LAMINAR= 1.0 +DIFFUSIVITY_CONSTANT= 7.56e-5 + +% according to the paper +SCHMIDT_NUMBER_TURBULENT= 0.7 + +% +CONV_NUM_METHOD_SPECIES= BOUNDED_SCALAR +MUSCL_SPECIES= NO +SLOPE_LIMITER_SPECIES = NONE +% +TIME_DISCRE_SPECIES= EULER_IMPLICIT +% +SPECIES_INIT= 0.0 +SPECIES_CLIPPING= YES +SPECIES_CLIPPING_MIN= 0.0 +SPECIES_CLIPPING_MAX= 1.0 +% +% -------------------- TURBULENT TRANSPORT ---------------------------------------% +% +CONV_NUM_METHOD_TURB= BOUNDED_SCALAR +MUSCL_TURB= NO + +% +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_FIELD= RMS_PRESSURE, RMS_VELOCITY-X, RMS_VELOCITY-Y, RMS_TKE, RMS_SPECIES +CONV_RESIDUAL_MINVAL= -18 +CONV_STARTITER= 10 +% +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +%MESH_FILENAME= psi_coarse.su2 +MESH_FILENAME= psi_medium.su2 +%MESH_FILENAME= psi_fine.su2 +% +SCREEN_OUTPUT= INNER_ITER WALL_TIME \ + RMS_PRESSURE RMS_VELOCITY-X RMS_VELOCITY-Y RMS_TKE RMS_DISSIPATION RMS_SPECIES_0 RMS_SPECIES_1 \ + LINSOL_ITER LINSOL_RESIDUAL \ + LINSOL_ITER_TURB LINSOL_RESIDUAL_TURB \ + LINSOL_ITER_SPECIES LINSOL_RESIDUAL_SPECIES \ + SURFACE_SPECIES_0 +SCREEN_WRT_FREQ_INNER= 1 +% +HISTORY_OUTPUT= ITER RMS_RES LINSOL SPECIES_COEFF SPECIES_COEFF_SURF +CONV_FILENAME= history +MARKER_ANALYZE= gas_inlet, air_axial_inlet, outlet +MARKER_ANALYZE_AVERAGE= AREA +% +OUTPUT_FILES= RESTART_ASCII, PARAVIEW_MULTIBLOCK +VOLUME_OUTPUT= RESIDUAL, PRIMITIVE +OUTPUT_WRT_FREQ= 100 +% +RESTART_SOL= YES +READ_BINARY_RESTART= NO +RESTART_FILENAME= restart +SOLUTION_FILENAME= solution +% +WRT_PERFORMANCE= YES diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py new file mode 100644 index 000000000000..6e22c4c152c6 --- /dev/null +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -0,0 +1,304 @@ +#!/usr/bin/env python + +## \file run.py +# \brief turbulent premixed dump combustor simulation (PSI flame) +# phi=0.5, methane-air, U=40 m/s +# \version 8.1.0 "Harrier" +# +# SU2 Project Website: https://su2code.github.io +# +# The SU2 Project is maintained by the SU2 Foundation +# (http://su2foundation.org) +# +# Copyright 2012-2024, 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 . + +import sys +import pysu2 +import numpy as np +#from mpi4py import MPI + +# unburnt temperature of the propane-air mixture +# flame temperature of the methane-air mixture (phi=0.5, P=5) +Tf = 1777 + +Tu = 673.0 +Pu = 5.0 +phi = 0.5 +# unburnt density at P=5 +rho_u = 2.52 +# unburnt thermal conductivity of methane-air at phi=0.5 (P=5) +k_u = 0.0523 +# unburnt heat capacity of methane-air at phi=0.5 (P=1) +cp_u = 1311.0 + +# P = rho*R*T +# 5 = 2.55 * R * 673 +# R = 0.0029 + +# ################################################################## # +# create a function for the initial progress variable # +# ################################################################## # +def initC(coord): + x = coord[0] + y = coord[1] + #z = coord[2] + #print("x,y = ",x," ",y) + C = 0.0 + # location where the flame should be + flame_x = 0.012 + if (x < flame_x): + C = 0.0 + else: + C = 1.0 + + return C + +# ################################################################## # +# loop over all vertices and set the species progress variable # +# ################################################################## # +def SetInitialSpecies(SU2Driver): + allCoords = SU2Driver.Coordinates() + iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] + print("index of species solver = ",iSPECIESSOLVER) + nVarsSpecies = SU2Driver.GetNumberSolverVars(iSPECIESSOLVER) + print("number of species solver variables:",nVarsSpecies) + for iPoint in range(SU2Driver.GetNumberNodes() - SU2Driver.GetNumberHaloNodes()): + coord = allCoords.Get(iPoint) + C = initC(coord) + # now update the initial condition + SU2Driver.SetSolutionVector(iSPECIESSOLVER, iPoint, [C]) + +def SetInitialVelocity(SU2Driver): + allCoords = SU2Driver.Coordinates() + iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] + print("index of FLOW solver = ",iFLOWSOLVER) + nVarsFlow = SU2Driver.GetNumberSolverVars(iFLOWSOLVER) + print("number of flow solver variables:",nVarsFlow) + for iPoint in range(SU2Driver.GetNumberNodes() - SU2Driver.GetNumberHaloNodes()): + coord = allCoords.Get(iPoint) + C = initC(coord) + # now update the initial condition + SU2Driver.SetSolutionVector(iFLOWSOLVER, iPoint, [C]) + +def update_temperature(SU2Driver, iPoint): + # first, get the progress variable + iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] + # returns a list + C = SU2Driver.GetSolutionVector(iSPECIESSOLVER, iPoint) + T = Tu*(1-C[0]) + Tf*C[0] + P0 = 101325.0 + # kg/kmol.K + R = 8.314 + # kg/kmol + M = 28.5 + RHO = P0/(R*T/M) + iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] + solvar = list(SU2Driver.GetSolutionVector(iFLOWSOLVER, iPoint)) + primvar = list(SU2Driver.GetPrimitiveVector(iFLOWSOLVER, iPoint)) + # the list with names + solindex = getsolvar(SU2Driver) + primindex = SU2Driver.GetPrimitiveIndices() + #print("primindex = ",primindex) + # the actual values + #print("solindex = ",solindex) + #print("primvar = ",primvar) + #print("solvar=",solvar) + iTEMP = solindex.get("TEMPERATURE") + iDENSITY = primindex.get("DENSITY") + #iDIFFUSIVITY = primindex.get("DENSITY") + #print("itemp=",iTEMP) + #print("irho=",iDENSITY) + #print("T=",T) + solvar[iTEMP] = T + # + # + SU2Driver.SetSolutionVector(iFLOWSOLVER, iPoint, solvar) + + # also set the primitive variable list + #primvar[iDENSITY] = 1.225 #RHO + #primvar[iTEMP] = T + #SU2Driver.SetPrimitiveVector(iFLOWSOLVER, iPoint, primvar) + + # how do we get for the scalar solver the diffusion coefficient? + + +def zimont(SU2Driver, iPoint): + + iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] + iSSTSOLVER = SU2Driver.GetSolverIndices()['SST'] + iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] + primindex = SU2Driver.GetPrimitiveIndices() + primvar = list(SU2Driver.GetPrimitiveVector(iFLOWSOLVER, iPoint)) + + iDENSITY = primindex.get("DENSITY") + iMU = primindex.get("LAMINAR_VISCOSITY") + + # laminar burning velocity of methane-air at phi=0.5, P=5 + Slu = 0.232 + + rho = primvar[iDENSITY] + mu = primvar[iMU] + nu=mu/rho + tke, dissipation = SU2Driver.GetSolutionVector(iSSTSOLVER,iPoint) + gradc = SU2Driver.GetGradient(iSPECIESSOLVER,iPoint,0) + norm_gradc = np.sqrt(gradc[0]*gradc[0] + gradc[1]*gradc[1]) + + up = np.sqrt((2.0/3.0) * tke ) + lt = (0.09**0.75) * (tke**1.5) / dissipation + Re = up*lt/nu + Le = 1.0 + Ut = Slu * (1.0 + (0.46/Le)*np.power(Re,0.25)*np.power(up/Slu,0.3)*np.power(Pu,0.2)) + + norm_gradc = np.sqrt(gradc[0]*gradc[0] + gradc[1]*gradc[1]) + + Sc = rho_u * Ut * norm_gradc + + return Sc + +def getsolvar(SU2Driver): + primindex = SU2Driver.GetPrimitiveIndices() + iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] + nVars = SU2Driver.GetNumberSolverVars(iFLOWSOLVER) + varindex = primindex.copy() + for prim in varindex.copy(): + if varindex[prim] >=nVars: + del varindex[prim] + varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) + return varindex + + +def main(): + """ + Run the flow solver with a custom inlet (function of time and space). + """ + # comm = MPI.COMM_WORLD + comm = 0 + + # Initialize the primal driver of SU2, this includes solver preprocessing. + try: + driver = pysu2.CSinglezoneDriver('psi.cfg', 1, comm) + except TypeError as exception: + print('A TypeError occured in pysu2.CSinglezoneDriver : ', exception) + raise + + print("\n------------------------------ Begin Solver -----------------------------") + sys.stdout.flush() + + nDim = driver.GetNumberDimensions() + + # index to the flow solver + # C.FLOW + # INC.FLOW + # HEAT + # FLAMELET + # SPECIES + # SA + # SST + iFLOWSOLVER = driver.GetSolverIndices()['INC.FLOW'] + print("index of flow solver = ",iFLOWSOLVER) + iSPECIESSOLVER = driver.GetSolverIndices()['SPECIES'] + print("index of species solver = ",iSPECIESSOLVER) + iSSTSOLVER = driver.GetSolverIndices()['SST'] + print("index of turbulence solver = ",iSSTSOLVER) + + + # all the indices and the map to the names of the primitives + primindex = driver.GetPrimitiveIndices() + print("indices of primitives=",primindex) + print("number of primitives:",len(primindex)) + + nElem = driver.GetNumberElements() + print("number of elements:",nElem) + + nVars = driver.GetNumberSolverVars(iFLOWSOLVER) + print("number of flow solver variables:",nVars) + + nVarsSpecies = driver.GetNumberSolverVars(iSPECIESSOLVER) + print("number of species solver variables:",nVarsSpecies) + nVarsTurb = driver.GetNumberSolverVars(iSSTSOLVER) + print("number of turbulence solver variables:",nVarsTurb) + + varindex = primindex.copy() + for prim in varindex.copy(): + if varindex[prim] >=nVars: + del varindex[prim] + varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) + + +# it is possible to get the solver type by doing +# iFLOWSOLVER = driver.GetSolverIndices()['INC.FLOW'] +# with the solver type we then get the solver variables using: + +# nVars = driver.GetNumberSolverVars(iFLOWSOLVER) +# and the solver variable names: +# print("solver variable names:",varindex) + +# we can overwrite the solution using: +# driver.SetSolutionVector(iSolver, iPoint, solutionVector) +# + + print("solver variable names:",varindex) + iDENSITY = primindex.get("DENSITY") + print("index of density = ",iDENSITY) + + index_Vel = varindex.get("VELOCITY_X") + print("index of velocity = ",index_Vel) + custom_source_vector = [0.0 for i in range(nVars)] + print("custom source vector = ", custom_source_vector) + + print("max. number of inner iterations: ",driver.GetNumberInnerIter()); + print("max nr of outer iterations: ",driver.GetNumberOuterIter()); + + # set initial condition + print("Start calling SetInitialSpecies") + #SetInitialSpecies(driver) + print("End calling SetInitialSpecies") + + # super important to actually push the commands. + sys.stdout.flush() + + # run 500 iterations + for inner_iter in range(500): + + driver.Preprocess(inner_iter) + driver.Run() + + # set the source term, per point + for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): + #print("inode=",i_node) + # add source term: + # default TFC of Zimont: rho*Sc = rho_u * U_t * grad(c) + S = [zimont(driver,i_node)] + driver.SetPointCustomSource(iSPECIESSOLVER, i_node,S) + # at this point we also need to update the temperature based on the progress variable: + # sete the temperature to T = c*Tf + (1-c)*Tu + update_temperature(driver, i_node) + + + driver.Postprocess() + driver.Update() + + + + driver.Monitor(inner_iter) + + driver.Output(inner_iter) + + # Finalize the solver and exit cleanly. + driver.Finalize() + +if __name__ == '__main__': + main() From dd8462daf0a6cc7428d7bbb8996722cbc9b0fd0d Mon Sep 17 00:00:00 2001 From: bigfooted Date: Sat, 22 Feb 2025 11:55:20 +0100 Subject: [PATCH 12/61] cleanup, fix AD compile error --- SU2_CFD/include/drivers/CDriverBase.hpp | 9 +--- SU2_CFD/include/solvers/CEulerSolver.hpp | 13 ------ .../include/solvers/CFVMFlowSolverBase.hpp | 1 - SU2_CFD/include/solvers/CScalarSolver.hpp | 2 - SU2_CFD/include/solvers/CScalarSolver.inl | 1 - SU2_CFD/include/solvers/CSpeciesSolver.hpp | 5 +-- SU2_CFD/src/python_wrapper_structure.cpp | 10 +++-- SU2_CFD/src/solvers/CIncEulerSolver.cpp | 10 ----- SU2_CFD/src/solvers/CSpeciesSolver.cpp | 12 ------ SU2_CFD/src/solvers/CTurbSSTSolver.cpp | 1 - .../py_wrapper/turbulent_premixed_psi/run.py | 41 +++++++++---------- 11 files changed, 30 insertions(+), 75 deletions(-) diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index d20de93bc004..52e36b064e9f 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -180,7 +180,7 @@ class CDriverBase { unsigned long GetNumberElements() const; /*! - * \brief Get the number of solution variables + * \brief Get the number of solution variables * \return Number of solution variables. */ @@ -760,16 +760,13 @@ class CDriverBase { } /*! - * \brief Set the array of variables for the source in the point + * \brief Set the array of variables for the source in the point * \param[in] iSolver - Solver index. * \param[in] iPoint - Point index. * \param[in] values - Vector values of the source term. */ void SetPointCustomSource(unsigned short iSolver, unsigned long iPoint, std::vector values) { auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; - - //if (values[0]>1.0e-6) - // cout << "iPoint="<SetCustomPointSource(iPoint, values); } @@ -799,7 +796,6 @@ inline void SetSolutionVector(unsigned short iSolver, unsigned long iPoint, vect unsigned short nVar = GetNumberSolverVars(iSolver); if (nVar != solutionVector.size() ) SU2_MPI::Error("Solution Vector size is not equal to Solver size.", CURRENT_FUNCTION); - //cout << "setting solution vector " << nodes->GetSolution(iPoint,0) << " " << solutionVector[0] << ", "<< nVar<< endl; for (unsigned int iVar = 0u; iVar < nVar; ++iVar) { nodes->SetSolution(iPoint,iVar, solutionVector[iVar]); nodes->SetSolution_Old(iPoint,iVar, solutionVector[iVar]); @@ -836,7 +832,6 @@ inline void SetPrimitiveVector(unsigned short iSolver, unsigned long iPoint, vec auto* nodes = solver->GetNodes(); auto nPrimvar = GetNumberPrimitiveVars(iSolver); vector solutionvector(nPrimvar, 0.0); - //cout << "setting primitive vector " << nodes->GetPrimitive(iPoint,0) << " " << primitiveVector[0] << ", "<< nPrimvar<< endl; for (auto iVar = 0u; iVar < nPrimvar; ++iVar) { nodes->SetPrimitive(iPoint,iVar, primitiveVector[iVar]); diff --git a/SU2_CFD/include/solvers/CEulerSolver.hpp b/SU2_CFD/include/solvers/CEulerSolver.hpp index ab5240bb5880..83c4cbe18e6a 100644 --- a/SU2_CFD/include/solvers/CEulerSolver.hpp +++ b/SU2_CFD/include/solvers/CEulerSolver.hpp @@ -409,19 +409,6 @@ class CEulerSolver : public CFVMFlowSolverBase val_source) final { /*--- Since this call can be accessed indirectly using python, do some error * checking to prevent segmentation faults ---*/ - //cout << "flow" << endl; if (val_point > nPointDomain) SU2_MPI::Error("Out-of-bounds point index used on solver.", CURRENT_FUNCTION); else if (val_source.size() > nVar) diff --git a/SU2_CFD/include/solvers/CScalarSolver.hpp b/SU2_CFD/include/solvers/CScalarSolver.hpp index 68254e481306..12bc885887ce 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.hpp +++ b/SU2_CFD/include/solvers/CScalarSolver.hpp @@ -64,7 +64,6 @@ class CScalarSolver : public CSolver { vector > SlidingState; // vector of matrix of pointers... inner dim alloc'd elsewhere (welcome, to the twilight zone) vector > SlidingStateNodes; - /*--- Shallow copy of grid coloring for OpenMP parallelization. ---*/ #ifdef HAVE_OMP @@ -579,5 +578,4 @@ class CScalarSolver : public CSolver { return SlidingStateNodes[val_marker][val_vertex]; } - }; diff --git a/SU2_CFD/include/solvers/CScalarSolver.inl b/SU2_CFD/include/solvers/CScalarSolver.inl index 6d54bc225524..1411de2ca787 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.inl +++ b/SU2_CFD/include/solvers/CScalarSolver.inl @@ -36,7 +36,6 @@ CScalarSolver::CScalarSolver(CGeometry* geometry, CConfig* config, config->GetNEMOProblem(), geometry->GetnDim(), config->GetnSpecies()) { nMarker = config->GetnMarker_All(); - /*--- Store the number of vertices on each marker for deallocation later ---*/ nVertex.resize(nMarker); for (unsigned long iMarker = 0; iMarker < nMarker; iMarker++) nVertex[iMarker] = geometry->nVertex[iMarker]; diff --git a/SU2_CFD/include/solvers/CSpeciesSolver.hpp b/SU2_CFD/include/solvers/CSpeciesSolver.hpp index fca2cc75c3a8..6d3540ae3482 100644 --- a/SU2_CFD/include/solvers/CSpeciesSolver.hpp +++ b/SU2_CFD/include/solvers/CSpeciesSolver.hpp @@ -195,7 +195,6 @@ class CSpeciesSolver : public CScalarSolver { geometry, solver_container, conv_numerics, visc_numerics, config); } - /*! * \brief Set a component of the unit vector representing the flow direction at an inlet boundary. * \param[in] val_marker - Surface marker where the flow direction is set. @@ -207,7 +206,6 @@ class CSpeciesSolver : public CScalarSolver { vector val_source) final { /*--- Since this call can be accessed indirectly using python, do some error * checking to prevent segmentation faults ---*/ - //cout << "***** set custom point source species *****" << endl; if (val_point > nPointDomain) SU2_MPI::Error("Out-of-bounds point index used on solver.", CURRENT_FUNCTION); else if (val_source.size() > nVar) @@ -215,11 +213,10 @@ class CSpeciesSolver : public CScalarSolver { else { for (size_t iVar=0; iVar < val_source.size(); iVar++) { SpeciesPointSource[val_point][iVar] = val_source[iVar]; - //if (SpeciesPointSource[val_point][iVar] > 1.0e-6) - // cout << iVar<<", setcustompointsource: "<< SpeciesPointSource[val_point][iVar] << endl; } } } + /*! * \brief A component of the unit vector representing the flow direction at an inlet boundary. * \param[in] val_marker - Surface marker where the flow direction is evaluated diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index 1008af2d06a7..883a2a08e281 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -61,8 +61,12 @@ unsigned long CDriver::GetNumberTimeIter() const { return config_container[selec unsigned long CDriver::GetNumberInnerIter() const { return config_container[selected_zone]->GetnInner_Iter(); } unsigned long CDriver::GetNumberOuterIter() const { return config_container[selected_zone]->GetnOuter_Iter(); } -unsigned long CDriver::GetDensity_FreeStreamND() const { return config_container[selected_zone]->GetDensity_FreeStreamND(); } -unsigned long CDriver::GetForce_Ref() const { return config_container[selected_zone]->GetForce_Ref(); } +unsigned long CDriver::GetDensity_FreeStreamND() const { + return SU2_TYPE::GetValue(config_container[selected_zone]->GetDensity_FreeStreamND()); + } +unsigned long CDriver::GetForce_Ref() const { + return SU2_TYPE::GetValue(config_container[selected_zone]->GetForce_Ref()); + } unsigned long CDriver::GetTimeIter() const { return TimeIter; } @@ -74,7 +78,7 @@ string CDriver::GetSurfaceFileName() const { return config_container[selected_zo unsigned long CDriver::GetSolution(unsigned short iSOLVER, unsigned long iPoint, unsigned short iVar) { auto solver = solver_container[iZone][INST_0][MESH_0][iSOLVER]; - return solver->GetNodes()->GetSolution(iPoint,iVar); + return SU2_TYPE::GetValue(solver->GetNodes()->GetSolution(iPoint,iVar)); } //////////////////////////////////////////////////////////////////////////////// diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index 9c2bc668ad05..1c746a48369c 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -303,10 +303,6 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i config->SetGas_Constant(UNIVERSAL_GAS_CONSTANT/(config->GetMolecular_Weight()/1000.0)); Pressure_Thermodynamic = Density_FreeStream*Temperature_FreeStream*config->GetGas_Constant(); - cout << "gas constant = " << config->GetGas_Constant() << endl; - cout << "pressure = " << Pressure_Thermodynamic << endl; - cout << "rho="<< Density_FreeStream<< endl; - cout << "T="<< Temperature_FreeStream<< endl; auxFluidModel = new CIncIdealGas(config->GetSpecific_Heat_Cp(), config->GetGas_Constant(), Pressure_Thermodynamic); auxFluidModel->SetTDState_T(Temperature_FreeStream); Pressure_Thermodynamic = auxFluidModel->GetPressure(); @@ -1842,14 +1838,8 @@ void CIncEulerSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solv /*--- Compute the residual for this control volume and subtract. ---*/ for (iVar = 0; iVar < nVar; iVar++) { - //cout << iPoint << " " << iVar << ",S="<< PointSource[iPoint][iVar]<< endl; LinSysRes[iPoint*nVar+iVar] += PointSource[iPoint][iVar] * Volume; } - // cout << "source = " << iPoint << " " << PointSource[iPoint][0]*Volume - // << " " << PointSource[iPoint][1]*Volume - // << " " << PointSource[iPoint][2]*Volume - // << " " << PointSource[iPoint][3]*Volume << endl; - } END_SU2_OMP_FOR diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index dddf70d199d6..f49d12c1d529 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -94,7 +94,6 @@ void CSpeciesSolver::Initialize(CGeometry* geometry, CConfig* config, unsigned s /*--- Store if an implicit scheme is used, for use during periodic boundary conditions. ---*/ SetImplicitPeriodic(config->GetKind_TimeIntScheme_Species() == EULER_IMPLICIT); - nPrimVar = nVar; if (nVar > MAXNVAR) @@ -111,9 +110,6 @@ void CSpeciesSolver::Initialize(CGeometry* geometry, CConfig* config, unsigned s nDim = geometry->GetnDim(); - - - std::cout << "resize species pointsource, nVar="<GetFilename(config->GetSolution_FileName(), "", val_iter); /*--- To make this routine safe to call in parallel most of it can only be executed by one thread. ---*/ diff --git a/TestCases/py_wrapper/custom_initialization/lam_buoyancy_cavity.cfg b/TestCases/py_wrapper/custom_initialization/lam_buoyancy_cavity.cfg deleted file mode 100644 index 470a895b372a..000000000000 --- a/TestCases/py_wrapper/custom_initialization/lam_buoyancy_cavity.cfg +++ /dev/null @@ -1,120 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% SU2 configuration file % -% Case description: Buoyancy-driven flow inside a cavity % -% Author: Thomas D. Economon % -% Date: 2018.06.10 % -% File Version 8.1.0 "Harrier" % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% -% -SOLVER= INC_NAVIER_STOKES -KIND_TURB_MODEL= NONE -MATH_PROBLEM= DIRECT -RESTART_SOL= NO - -% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% -% -INC_DENSITY_MODEL= VARIABLE -INC_ENERGY_EQUATION = YES -% -% Uncomment a density below for a desired Rayleigh number -%INC_DENSITY_INIT= 0.00018903539834 % Ra ~ 1e3 -%INC_DENSITY_INIT= 0.00059778241716 % Ra ~ 1e4 -%INC_DENSITY_INIT= 0.00189035398341 % Ra ~ 1e5 -INC_DENSITY_INIT= 0.00597782417156 % Ra ~ 1e6 -% -INC_VELOCITY_INIT= ( 1.0, 0.0, 0.0 ) -INC_TEMPERATURE_INIT= 288.15 - -% ---- IDEAL GAS, POLYTROPIC, VAN DER WAALS AND PENG ROBINSON CONSTANTS -------% -% -FLUID_MODEL= INC_IDEAL_GAS -SPECIFIC_HEAT_CP= 1004.703 -MOLECULAR_WEIGHT= 28.96 - -% --------------------------- VISCOSITY MODEL ---------------------------------% -% -VISCOSITY_MODEL= CONSTANT_VISCOSITY -MU_CONSTANT= 1.716e-5 - -% --------------------------- THERMAL CONDUCTIVITY MODEL ----------------------% -% -CONDUCTIVITY_MODEL= CONSTANT_CONDUCTIVITY -THERMAL_CONDUCTIVITY_CONSTANT= 0.0246295028571 - -% ----------------------- BODY FORCE DEFINITION -------------------------------% -% -BODY_FORCE= NO -BODY_FORCE_VECTOR= ( 0.0, -9.81, 0.0 ) - -% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% -% -REF_ORIGIN_MOMENT_X = 0.25 -REF_ORIGIN_MOMENT_Y = 0.00 -REF_ORIGIN_MOMENT_Z = 0.00 -REF_AREA= 1.0 - -% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% -% -MARKER_HEATFLUX= ( upper, 0.0, lower, 0.0 ) -MARKER_ISOTHERMAL= ( left, 461.04, right, 115.26 ) -MARKER_PLOTTING= ( upper, left, right, lower ) -MARKER_MONITORING= ( NONE ) - -% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% -% -NUM_METHOD_GRAD= GREEN_GAUSS -CFL_NUMBER= 50 -CFL_ADAPT= NO -CFL_ADAPT_PARAM= ( 1.5, 0.5, 15.0, 1e10) -MAX_DELTA_TIME= 1E6 -RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) -ITER=1 - -% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% -% -LINEAR_SOLVER= FGMRES -LINEAR_SOLVER_PREC= ILU -LINEAR_SOLVER_ILU_FILL_IN= 0 -LINEAR_SOLVER_ERROR= 1E-15 -LINEAR_SOLVER_ITER= 20 - -% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% -% -CONV_NUM_METHOD_FLOW= FDS -MUSCL_FLOW= YES -SLOPE_LIMITER_FLOW= NONE -TIME_DISCRE_FLOW= EULER_IMPLICIT - - -% --------------------------- CONVERGENCE PARAMETERS --------------------------% -% -CONV_RESIDUAL_MINVAL= -12 -CONV_STARTITER= 10 -CONV_CAUCHY_ELEMS= 100 -CONV_CAUCHY_EPS= 1E-6 - -% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% -% -MESH_FILENAME= mesh_cavity_65x65.su2 -MESH_FORMAT= SU2 -MESH_OUT_FILENAME= mesh_out.su2 -SOLUTION_FILENAME= solution_flow.dat -SOLUTION_ADJ_FILENAME= solution_adj.dat -TABULAR_FORMAT= CSV -CONV_FILENAME= history -RESTART_FILENAME= restart_flow.dat -RESTART_ADJ_FILENAME= restart_adj.dat -VOLUME_FILENAME= flow -VOLUME_ADJ_FILENAME= adjoint -GRAD_OBJFUNC_FILENAME= of_grad.dat -SURFACE_FILENAME= surface_flow -SURFACE_ADJ_FILENAME= surface_adjoint -OUTPUT_WRT_FREQ= 100 -SCREEN_OUTPUT= (OUTER_ITER, INNER_ITER, RMS_PRESSURE, RMS_TEMPERATURE, LIFT, DRAG) - -% ----------------------- GEOMETRY EVALUATION PARAMETERS ----------------------% -GEO_BOUNDS= ( 0.499, 0.501) diff --git a/TestCases/py_wrapper/custom_initialization/run.py b/TestCases/py_wrapper/custom_initialization/run.py deleted file mode 100644 index 757b464a9c9e..000000000000 --- a/TestCases/py_wrapper/custom_initialization/run.py +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env python - -## \file run.py -# \brief Buoyancy force using user defines source term -# \version 8.1.0 "Harrier" -# -# SU2 Project Website: https://su2code.github.io -# -# The SU2 Project is maintained by the SU2 Foundation -# (http://su2foundation.org) -# -# Copyright 2012-2024, 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 . - -import sys -import pysu2 -# from mpi4py import MPI - -def main(): - """ - Run the flow solver with a custom inlet (function of time and space). - """ - # comm = MPI.COMM_WORLD - comm = 0 - - # Initialize the primal driver of SU2, this includes solver preprocessing. - try: - driver = pysu2.CSinglezoneDriver('lam_buoyancy_cavity.cfg', 1, comm) - except TypeError as exception: - print('A TypeError occured in pysu2.CSinglezoneDriver : ', exception) - raise - - print("\n------------------------------ Begin Solver -----------------------------") - sys.stdout.flush() - - # we need to add a source term to the energy equation. For this, we need to get the solver, and the variable first. - # we then loop over all points and for these points, we add the source term - nDim = driver.GetNumberDimensions() - - # index to the flow solver - # C.FLOW - # INC.FLOW - # HEAT - # FLAMELET - # SPECIES - # SA - # SST - iSOLVER = driver.GetSolverIndices()['INC.FLOW'] - print("index of flow solver = ",iSOLVER) - - # all the indices and the map to the names of the primitives - primindex = driver.GetPrimitiveIndices() - print("indices of primitives=",primindex) - print("number of primitives:",len(primindex)) - - nElem = driver.GetNumberElements() - print("number of elements:",nElem) - - nVars = driver.GetNumberSolverVars(iSOLVER) - print("number of solver variables:",nVars) - varindex = primindex.copy() - for prim in varindex.copy(): - if varindex[prim] >=nVars: - del varindex[prim] - varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) - - -# it is possible to get the solver type by doing -# iSOLVER = driver.GetSolverIndices()['INC.FLOW'] -# with the solver type we then get the solver variables using: - -# nVars = driver.GetNumberSolverVars(iSOLVER) -# and the solver variable names: -# print("solver variable names:",varindex) - -# we can overwrite the solution using: -# driver.SetSolutionVector(iSolver, iPoint, solutionVector) -# - - print("solver variable names:",varindex) - iDENSITY = primindex.get("DENSITY") - print("index of density = ",iDENSITY) - - index_Vel = varindex.get("VELOCITY_X") - print("index of velocity = ",index_Vel) - custom_source_vector = [0.0 for i in range(nVars)] - print("custom source vector = ", custom_source_vector) - - print("max. number of inner iterations: ",driver.GetNumberInnerIter()); - print("max nr of outer iterations: ",driver.GetNumberOuterIter()); - - # is in domain: isdomain = driver.GetNodeDomain(iPoint) - #for i_vertex in range(n_vertex) - #AllSolutions = driver.GetAllSolutions(iSOLVER) - Body_Force_Vector = [0.0, -9.81, 0.0] - DensityInc_0 = driver.GetDensity_FreeStreamND() - print("rho freestream = ",DensityInc_0) - Force_Ref = driver.GetForce_Ref() - print("reference force = ",Force_Ref) - - for inner_iter in range(500): - - # set the source term, per point - for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): - #print("node = ",i_node) - #SolutionVector = driver.GetSolutionVector(iSOLVER,i_node) - #print("solutionvector=",SolutionVector) - PrimitiveVector = driver.GetPrimitiveVector(iSOLVER,i_node) - #print("primitivevector=",PrimitiveVector) - DensityInc_i = PrimitiveVector[iDENSITY] - - for iDim in range(nDim): - custom_source_vector[iDim+1] = -(DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref - - #print("density=",DensityInc_i) - driver.SetPointCustomSource(iSOLVER, i_node,custom_source_vector) - - print(" *** inner iteration:",inner_iter) - driver.Preprocess(inner_iter) - - # Run one time iteration. - driver.Run() - driver.Postprocess() - driver.Update() - - # Monitor the solver and output solution to file if required. - #driver.Monitor(inner_iter) - driver.Output(inner_iter) - - # Finalize the solver and exit cleanly. - driver.Finalize() - -if __name__ == '__main__': - main() diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg b/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg index ee0cfb797a75..e7fe423fc044 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg +++ b/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg @@ -1,11 +1,11 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % SU2 configuration file % -% Case description: Species mixing with 3 species, i.e. 2 transport equations % -% Author: T. Kattmann % +% Case description: Turbulent premixed high pressure combustion chamber. % +% Author: N. Beishuizen % % Institution: Bosch Thermotechniek B.V. % -% Date: 2021/10/14 % -% File Version 7.5.1 "Blackbird" % +% Date: 2025/01/01 % +% File Version 8.0 "Harrier" % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -79,12 +79,10 @@ MARKER_OUTLET= ( outlet, 0.0 ) % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES % -%CFL_NUMBER= 25.0 CFL_NUMBER= 20.0 CFL_REDUCTION_SPECIES= 1.0 CFL_REDUCTION_TURB= 1.0 % -% Run commented Iter for good results ITER= 1 % % ------------------------ LINEAR SOLVER DEFINITION ---------------------------% @@ -104,7 +102,6 @@ TIME_DISCRE_FLOW= EULER_IMPLICIT % -------------------- SCALAR TRANSPORT ---------------------------------------% % KIND_SCALAR_MODEL= SPECIES_TRANSPORT -%DIFFUSIVITY_MODEL= CONSTANT_SCHMIDT DIFFUSIVITY_MODEL= CONSTANT_DIFFUSIVITY SCHMIDT_NUMBER_LAMINAR= 1.0 DIFFUSIVITY_CONSTANT= 7.56e-5 From cd581f4eb51996a6818e1f8944d3eeba29d1a5fd Mon Sep 17 00:00:00 2001 From: bigfooted Date: Sun, 23 Feb 2025 11:01:15 +0100 Subject: [PATCH 14/61] more cleanup of examples --- TestCases/py_wrapper/custom_source/run.py | 33 +++++----- .../py_wrapper/turbulent_premixed_psi/run.py | 60 +++++-------------- 2 files changed, 30 insertions(+), 63 deletions(-) diff --git a/TestCases/py_wrapper/custom_source/run.py b/TestCases/py_wrapper/custom_source/run.py index ea08aaf98bc4..3bd330eabb40 100644 --- a/TestCases/py_wrapper/custom_source/run.py +++ b/TestCases/py_wrapper/custom_source/run.py @@ -30,7 +30,7 @@ def main(): """ - Run the flow solver with a custom inlet (function of time and space). + custom source to add buoyancy term. """ # comm = MPI.COMM_WORLD comm = 0 @@ -45,24 +45,24 @@ def main(): print("\n------------------------------ Begin Solver -----------------------------") sys.stdout.flush() - # we need to add a source term to the energy equation. For this, we need to get the solver, and the variable first. + # we need to add a source term to the energy equation. For this, we need to get the solver and the variable first. # we then loop over all points and for these points, we add the source term nDim = driver.GetNumberDimensions() # index to the flow solver iSOLVER = driver.GetSolverIndices()['INC.FLOW'] - print("index of flow solver = ",iSOLVER) + #print("index of flow solver = ",iSOLVER) # all the indices and the map to the names of the primitives primindex = driver.GetPrimitiveIndices() - print("indices of primitives=",primindex) - print("number of primitives:",len(primindex)) + #print("indices of primitives=",primindex) + #print("number of primitives:",len(primindex)) nElem = driver.GetNumberElements() - print("number of elements:",nElem) + #print("number of elements:",nElem) nVars = driver.GetNumberSolverVars(iSOLVER) - print("number of solver variables:",nVars) + #print("number of solver variables:",nVars) varindex = primindex.copy() for prim in varindex.copy(): if varindex[prim] >=nVars: @@ -71,42 +71,41 @@ def main(): - print("solver variable names:",varindex) + #print("solver variable names:",varindex) iDENSITY = primindex.get("DENSITY") - print("index of density = ",iDENSITY) + #print("index of density = ",iDENSITY) index_Vel = varindex.get("VELOCITY_X") - print("index of velocity = ",index_Vel) + #print("index of velocity = ",index_Vel) custom_source_vector = [0.0 for i in range(nVars)] - print("custom source vector = ", custom_source_vector) + #print("custom source vector = ", custom_source_vector) - print("max. number of inner iterations: ",driver.GetNumberInnerIter()); - print("max nr of outer iterations: ",driver.GetNumberOuterIter()); + #print("max. number of inner iterations: ",driver.GetNumberInnerIter()); + #print("max nr of outer iterations: ",driver.GetNumberOuterIter()); # is in domain: isdomain = driver.GetNodeDomain(iPoint) #for i_vertex in range(n_vertex) #AllSolutions = driver.GetAllSolutions(iSOLVER) Body_Force_Vector = [0.0, -9.81, 0.0] DensityInc_0 = driver.GetDensity_FreeStreamND() - print("rho freestream = ",DensityInc_0) + #print("rho freestream = ",DensityInc_0) Force_Ref = driver.GetForce_Ref() - print("reference force = ",Force_Ref) + #print("reference force = ",Force_Ref) for inner_iter in range(500): # set the source term, per point for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): - #print("node = ",i_node) #SolutionVector = driver.GetSolutionVector(iSOLVER,i_node) #print("solutionvector=",SolutionVector) PrimitiveVector = driver.GetPrimitiveVector(iSOLVER,i_node) #print("primitivevector=",PrimitiveVector) DensityInc_i = PrimitiveVector[iDENSITY] + #print("density=",DensityInc_i) for iDim in range(nDim): custom_source_vector[iDim+1] = -(DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref - #print("density=",DensityInc_i) driver.SetPointCustomSource(iSOLVER, i_node,custom_source_vector) print(" *** inner iteration:",inner_iter) diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py index 044a16373046..7e2fa6b6d495 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/run.py +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -98,44 +98,17 @@ def update_temperature(SU2Driver, iPoint): # returns a list C = SU2Driver.GetSolutionVector(iSPECIESSOLVER, iPoint) T = Tu*(1-C[0]) + Tf*C[0] - P0 = 101325.0 - # kg/kmol.K - R = 8.314 - # kg/kmol - M = 28.5 - RHO = P0/(R*T/M) iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] solvar = list(SU2Driver.GetSolutionVector(iFLOWSOLVER, iPoint)) - primvar = list(SU2Driver.GetPrimitiveVector(iFLOWSOLVER, iPoint)) # the list with names solindex = getsolvar(SU2Driver) primindex = SU2Driver.GetPrimitiveIndices() - #print("primindex = ",primindex) - # the actual values - #print("solindex = ",solindex) - #print("primvar = ",primvar) - #print("solvar=",solvar) iTEMP = solindex.get("TEMPERATURE") - iDENSITY = primindex.get("DENSITY") - #iDIFFUSIVITY = primindex.get("DENSITY") - #print("itemp=",iTEMP) - #print("irho=",iDENSITY) - #print("T=",T) solvar[iTEMP] = T - # - # SU2Driver.SetSolutionVector(iFLOWSOLVER, iPoint, solvar) - # also set the primitive variable list - #primvar[iDENSITY] = 1.225 #RHO - #primvar[iTEMP] = T - #SU2Driver.SetPrimitiveVector(iFLOWSOLVER, iPoint, primvar) - - # how do we get for the scalar solver the diffusion coefficient? - def zimont(SU2Driver, iPoint): - iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] iSSTSOLVER = SU2Driver.GetSolverIndices()['SST'] iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] @@ -153,7 +126,7 @@ def zimont(SU2Driver, iPoint): nu=mu/rho tke, dissipation = SU2Driver.GetSolutionVector(iSSTSOLVER,iPoint) gradc = SU2Driver.GetGradient(iSPECIESSOLVER,iPoint,0) - + # Turbulent Flamespeed Closure with Dinkelacker correction up = np.sqrt((2.0/3.0) * tke ) lt = (0.09**0.75) * (tke**1.5) / dissipation Re = up*lt/nu @@ -249,51 +222,46 @@ def main(): # driver.SetSolutionVector(iSolver, iPoint, solutionVector) # - print("solver variable names:",varindex) + #print("solver variable names:",varindex) iDENSITY = primindex.get("DENSITY") - print("index of density = ",iDENSITY) + #print("index of density = ",iDENSITY) index_Vel = varindex.get("VELOCITY_X") - print("index of velocity = ",index_Vel) + #print("index of velocity = ",index_Vel) + custom_source_vector = [0.0 for i in range(nVars)] - print("custom source vector = ", custom_source_vector) + #print("custom source vector = ", custom_source_vector) - print("max. number of inner iterations: ",driver.GetNumberInnerIter()); - print("max nr of outer iterations: ",driver.GetNumberOuterIter()); + #print("max. number of inner iterations: ",driver.GetNumberInnerIter()); + #print("max nr of outer iterations: ",driver.GetNumberOuterIter()); - # set initial condition - print("Start calling SetInitialSpecies") + # We can set an initial condition by calling this function: + #print("Start calling SetInitialSpecies") #SetInitialSpecies(driver) - print("End calling SetInitialSpecies") + #print("End calling SetInitialSpecies") # super important to actually push the commands. sys.stdout.flush() - # run 500 iterations - for inner_iter in range(500): + # run 5 iterations + for inner_iter in range(5): driver.Preprocess(inner_iter) driver.Run() # set the source term, per point for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): - #print("inode=",i_node) # add source term: # default TFC of Zimont: rho*Sc = rho_u * U_t * grad(c) S = [zimont(driver,i_node)] driver.SetPointCustomSource(iSPECIESSOLVER, i_node,S) # at this point we also need to update the temperature based on the progress variable: - # sete the temperature to T = c*Tf + (1-c)*Tu + # set the temperature to T = c*Tf + (1-c)*Tu update_temperature(driver, i_node) - driver.Postprocess() driver.Update() - - - driver.Monitor(inner_iter) - driver.Output(inner_iter) # Finalize the solver and exit cleanly. From dc65d47e5fc66f1a696ec3ab2d8a3d562ba09055 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Sun, 23 Feb 2025 11:01:25 +0100 Subject: [PATCH 15/61] more cleanup of examples --- TestCases/py_wrapper/custom_source/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TestCases/py_wrapper/custom_source/run.py b/TestCases/py_wrapper/custom_source/run.py index 3bd330eabb40..d16bf98bd87c 100644 --- a/TestCases/py_wrapper/custom_source/run.py +++ b/TestCases/py_wrapper/custom_source/run.py @@ -92,7 +92,7 @@ def main(): Force_Ref = driver.GetForce_Ref() #print("reference force = ",Force_Ref) - for inner_iter in range(500): + for inner_iter in range(5): # set the source term, per point for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): From 2003b18c498604d283e649b5976aacba489c747f Mon Sep 17 00:00:00 2001 From: bigfooted Date: Mon, 24 Feb 2025 21:26:22 +0100 Subject: [PATCH 16/61] add testcases --- TestCases/parallel_regression.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index 530328b52a64..3fa47cb56c76 100644 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -1458,6 +1458,24 @@ def main(): pywrapper_deformingBump.unsteady = True test_list.append(pywrapper_deformingBump) + # custom source: buoyancy term + pywrapper_buoyancy = TestCase('pywrapper_buoyancy') + pywrapper_buoyancy.cfg_dir = "py_wrapper/custom_source" + pywrapper_buoyancy.cfg_file = "lam_buoyancy_cavity.cfg" + pywrapper_buoyancy.test_iter = 1 + pywrapper_buoyancy.test_vals = [0.500000, 0.000000, -3.037859, -1.603563, -2.074259, 2.424288, 7.762848, -0.220436] + pywrapper_buoyancy.command = TestCase.Command("mpirun -np 2", "python", "run.py") + test_list.append(pywrapper_buoyancy) + + # custom source: turbulent flamespeed closure (Zimont model) for PSI testcase + pywrapper_zimont = TestCase('pywrapper_zimont') + pywrapper_zimont.cfg_dir = "py_wrapper/psi" + pywrapper_zimont.cfg_file = "psi.cfg" + pywrapper_zimont.test_iter = 1 + pywrapper_zimont.test_vals = [0.500000, 0.000000, -3.037859, -1.603563, -2.074259, 2.424288, 7.762848, -0.220436] + pywrapper_zimont.command = TestCase.Command("mpirun -np 2", "python", "run.py") + test_list.append(pywrapper_zimont) + ############################################## ### Method of Manufactured Solutions (MMS) ### ############################################## From effe99d574320d0ce219103ec7b673a54b11b7c4 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Mon, 24 Feb 2025 22:05:43 +0100 Subject: [PATCH 17/61] change testcases branch --- .github/workflows/regression.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml index 2502204b64c4..18423ac686ec 100644 --- a/.github/workflows/regression.yml +++ b/.github/workflows/regression.yml @@ -209,7 +209,7 @@ jobs: uses: docker://ghcr.io/su2code/su2/test-su2:240320-1536 with: # -t -c - args: -b ${{github.ref}} -t develop -c develop -s ${{matrix.testscript}} + args: -b ${{github.ref}} -t develop -c feature_custom_source -s ${{matrix.testscript}} - name: Cleanup uses: docker://ghcr.io/su2code/su2/test-su2:240320-1536 with: From e623a4b3283479da04d1904ae1afd8ded7ebf15c Mon Sep 17 00:00:00 2001 From: Nijso Date: Sun, 9 Mar 2025 14:59:47 +0100 Subject: [PATCH 18/61] Potential fix for code scanning alert no. 5295: Unused local variable Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- TestCases/py_wrapper/custom_source/run.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/TestCases/py_wrapper/custom_source/run.py b/TestCases/py_wrapper/custom_source/run.py index d16bf98bd87c..ea79d52c446a 100644 --- a/TestCases/py_wrapper/custom_source/run.py +++ b/TestCases/py_wrapper/custom_source/run.py @@ -58,8 +58,7 @@ def main(): #print("indices of primitives=",primindex) #print("number of primitives:",len(primindex)) - nElem = driver.GetNumberElements() - #print("number of elements:",nElem) + #print("number of elements:",driver.GetNumberElements()) nVars = driver.GetNumberSolverVars(iSOLVER) #print("number of solver variables:",nVars) From c86a630fb0e7a6b93171e846177f73da0d6339a5 Mon Sep 17 00:00:00 2001 From: Nijso Date: Sun, 9 Mar 2025 15:01:14 +0100 Subject: [PATCH 19/61] Potential fix for code scanning alert no. 5292: Unused local variable Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- TestCases/py_wrapper/turbulent_premixed_psi/run.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py index 7e2fa6b6d495..8ddb9aefeafc 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/run.py +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -223,8 +223,7 @@ def main(): # #print("solver variable names:",varindex) - iDENSITY = primindex.get("DENSITY") - #print("index of density = ",iDENSITY) + #print("index of density = ",primindex.get("DENSITY")) index_Vel = varindex.get("VELOCITY_X") #print("index of velocity = ",index_Vel) From b8aebc80924544cdcded59cf8bef4fdde4b462be Mon Sep 17 00:00:00 2001 From: bigfooted Date: Mon, 10 Mar 2025 08:08:22 +0100 Subject: [PATCH 20/61] update testcases --- SU2_CFD/src/numerics/flow/flow_sources.cpp | 2 +- SU2_CFD/src/solvers/CIncEulerSolver.cpp | 12 +++--- .../py_wrapper/turbulent_premixed_psi/psi.cfg | 17 ++++---- .../py_wrapper/turbulent_premixed_psi/run.py | 42 ++++++++++--------- 4 files changed, 39 insertions(+), 34 deletions(-) diff --git a/SU2_CFD/src/numerics/flow/flow_sources.cpp b/SU2_CFD/src/numerics/flow/flow_sources.cpp index ca0f40b104f6..96df3d6f339a 100644 --- a/SU2_CFD/src/numerics/flow/flow_sources.cpp +++ b/SU2_CFD/src/numerics/flow/flow_sources.cpp @@ -847,7 +847,7 @@ CSourceUserDefined::CSourceUserDefined(unsigned short val_nDim, unsigned short v CNumerics::ResidualType<> CSourceUserDefined::ComputeResidual(const CConfig *config) { unsigned short iDim; - + cout << "CSourceUserDefined" << endl; /*--- Zero the continuity contribution. ---*/ residual[0] = 0.0; diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index 1c746a48369c..f28734f7bb0a 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -1833,13 +1833,13 @@ void CIncEulerSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solv numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - /*--- Get control volume size. ---*/ - su2double Volume = geometry->nodes->GetVolume(iPoint); + /*--- Get control volume size. ---*/ + su2double Volume = geometry->nodes->GetVolume(iPoint); - /*--- Compute the residual for this control volume and subtract. ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - LinSysRes[iPoint*nVar+iVar] += PointSource[iPoint][iVar] * Volume; - } + /*--- Compute the residual for this control volume and subtract. ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + LinSysRes[iPoint*nVar+iVar] += PointSource[iPoint][iVar] * Volume; + } } END_SU2_OMP_FOR diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg b/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg index e7fe423fc044..284fc1ca3ce8 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg +++ b/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg @@ -15,6 +15,8 @@ SOLVER= INC_RANS KIND_TURB_MODEL= SST SST_OPTIONS= V1994m +RESTART_SOL= YES + MGLEVEL= 0 % @@ -63,11 +65,12 @@ MARKER_SYM= ( symmetry ) AXISYMMETRIC= YES % SPECIFIED_INLET_PROFILE= YES +INLET_MATCHING_TOLERANCE=1e-4 INLET_FILENAME= inlet.dat %INLET_INTERPOLATION_FUNCTION= LINEAR_1D INC_INLET_TYPE= VELOCITY_INLET INC_INLET_DAMPING= 0.01 -MARKER_INLET= ( inlet, 673, 40.0, 1.0, 0.0, 0.0) +MARKER_INLET= ( inlet, 673, 40.0, 1.0, 0.0, 0.0) MARKER_INLET_TURBULENT = (inlet, 0.10, 15) MARKER_INLET_SPECIES= (inlet, 0.0) % @@ -79,7 +82,7 @@ MARKER_OUTLET= ( outlet, 0.0 ) % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES % -CFL_NUMBER= 20.0 +CFL_NUMBER= 1.0 CFL_REDUCTION_SPECIES= 1.0 CFL_REDUCTION_TURB= 1.0 % @@ -90,7 +93,7 @@ ITER= 1 LINEAR_SOLVER= FGMRES LINEAR_SOLVER_PREC= ILU LINEAR_SOLVER_ERROR= 1E-8 -LINEAR_SOLVER_ITER= 5 +LINEAR_SOLVER_ITER= 10 % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % @@ -136,15 +139,14 @@ CONV_STARTITER= 10 % ------------------------- INPUT/OUTPUT INFORMATION --------------------------% % %MESH_FILENAME= psi_coarse.su2 -MESH_FILENAME= psi_medium.su2 +MESH_FILENAME= psi.su2 %MESH_FILENAME= psi_fine.su2 % SCREEN_OUTPUT= INNER_ITER WALL_TIME \ - RMS_PRESSURE RMS_VELOCITY-X RMS_VELOCITY-Y RMS_TKE RMS_DISSIPATION RMS_SPECIES_0 RMS_SPECIES_1 \ + RMS_PRESSURE RMS_VELOCITY-X RMS_VELOCITY-Y RMS_TKE RMS_DISSIPATION RMS_SPECIES_0 \ LINSOL_ITER LINSOL_RESIDUAL \ LINSOL_ITER_TURB LINSOL_RESIDUAL_TURB \ - LINSOL_ITER_SPECIES LINSOL_RESIDUAL_SPECIES \ - SURFACE_SPECIES_0 + LINSOL_ITER_SPECIES LINSOL_RESIDUAL_SPECIES SCREEN_WRT_FREQ_INNER= 1 % HISTORY_OUTPUT= ITER RMS_RES LINSOL SPECIES_COEFF SPECIES_COEFF_SURF @@ -156,7 +158,6 @@ OUTPUT_FILES= RESTART_ASCII, PARAVIEW_MULTIBLOCK VOLUME_OUTPUT= RESIDUAL, PRIMITIVE OUTPUT_WRT_FREQ= 100 % -RESTART_SOL= YES READ_BINARY_RESTART= NO RESTART_FILENAME= restart SOLUTION_FILENAME= solution diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py index 8ddb9aefeafc..89096f5a9dd1 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/run.py +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -27,6 +27,7 @@ import sys import pysu2 +from mpi4py import MPI import numpy as np #from mpi4py import MPI @@ -121,6 +122,7 @@ def zimont(SU2Driver, iPoint): # laminar burning velocity of methane-air at phi=0.5, P=5 Slu = 0.232 + rho = primvar[iDENSITY] mu = primvar[iMU] nu=mu/rho @@ -131,10 +133,10 @@ def zimont(SU2Driver, iPoint): lt = (0.09**0.75) * (tke**1.5) / dissipation Re = up*lt/nu Le = 1.0 - Ut = Slu * (1.0 + (0.46/Le)*np.power(Re,0.25)*np.power(up/Slu,0.3)*np.power(Pu,0.2)) - + Ut = Slu * (1.0 + (0.46/Le) * np.power(Re,0.25) * np.power(up/Slu,0.3) * np.power(Pu,0.2) ) norm_gradc = np.sqrt(gradc[0]*gradc[0] + gradc[1]*gradc[1]) - + #if (norm_gradc > 1.): + # print(tke," ",rho_u," Ut=",Ut," , |grad(c)| = ",norm_gradc, " ",gradc[0]," ",gradc[1]) Sc = rho_u * Ut * norm_gradc return Sc @@ -152,11 +154,8 @@ def getsolvar(SU2Driver): def main(): - """ - Run the flow solver with a custom inlet (function of time and space). - """ - # comm = MPI.COMM_WORLD - comm = 0 + comm = MPI.COMM_WORLD + rank = comm.Get_rank() # Initialize the primal driver of SU2, this includes solver preprocessing. try: @@ -165,8 +164,9 @@ def main(): print('A TypeError occured in pysu2.CSinglezoneDriver : ', exception) raise - print("\n------------------------------ Begin Solver -----------------------------") - sys.stdout.flush() + if rank == 0: + print("\n------------------------------ Begin Solver -----------------------------") + sys.stdout.flush() nDim = driver.GetNumberDimensions() print("Dimensions of the problem = ",nDim) @@ -223,7 +223,8 @@ def main(): # #print("solver variable names:",varindex) - #print("index of density = ",primindex.get("DENSITY")) + iDENSITY = primindex.get("DENSITY") + #print("index of density = ",iDENSITY) index_Vel = varindex.get("VELOCITY_X") #print("index of velocity = ",index_Vel) @@ -233,17 +234,20 @@ def main(): #print("max. number of inner iterations: ",driver.GetNumberInnerIter()); #print("max nr of outer iterations: ",driver.GetNumberOuterIter()); - - # We can set an initial condition by calling this function: - #print("Start calling SetInitialSpecies") - #SetInitialSpecies(driver) - #print("End calling SetInitialSpecies") + with open('psi.cfg') as f: + if 'RESTART_SOL= YES' in f.read(): + print("restarting from file") + else: + # We can set an initial condition by calling this function: + print("Start calling SetInitialSpecies") + SetInitialSpecies(driver) + print("End calling SetInitialSpecies") # super important to actually push the commands. sys.stdout.flush() - # run 5 iterations - for inner_iter in range(5): + # run N iterations + for inner_iter in range(10000): driver.Preprocess(inner_iter) driver.Run() @@ -260,7 +264,7 @@ def main(): driver.Postprocess() driver.Update() - driver.Monitor(inner_iter) + #driver.Monitor(inner_iter) driver.Output(inner_iter) # Finalize the solver and exit cleanly. From 10a653a9e636924ef60bef6cab416c24dd8cc842 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Wed, 9 Apr 2025 20:02:26 +0200 Subject: [PATCH 21/61] update --- Common/include/option_structure.hpp | 2 - SU2_CFD/include/numerics/CNumerics.hpp | 1 - .../include/numerics/flow/flow_sources.hpp | 24 ---------- .../include/solvers/CFVMFlowSolverBase.hpp | 33 ++++++++++++++ .../include/solvers/CFVMFlowSolverBase.inl | 2 + SU2_CFD/include/solvers/CIncEulerSolver.hpp | 10 ++--- SU2_CFD/src/numerics/flow/flow_sources.cpp | 45 ++++--------------- SU2_CFD/src/solvers/CIncEulerSolver.cpp | 45 +++++++++---------- 8 files changed, 69 insertions(+), 93 deletions(-) diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 59c0e6fa8c93..b11f0aaa742a 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -550,7 +550,6 @@ enum ENUM_FLUIDMODEL { COOLPROP = 10, /*!< \brief Thermodynamics library. */ FLUID_FLAMELET = 11, /*!< \brief lookup table (LUT) method for premixed flamelets. */ DATADRIVEN_FLUID = 12, /*!< \brief multi-layer perceptron driven fluid model. */ - USER_DEFINED = 13, /*!< \brief user defined through python wrapper. */ }; static const MapType FluidModel_Map = { MakePair("STANDARD_AIR", STANDARD_AIR) @@ -566,7 +565,6 @@ static const MapType FluidModel_Map = { MakePair("COOLPROP", COOLPROP) MakePair("DATADRIVEN_FLUID", DATADRIVEN_FLUID) MakePair("FLUID_FLAMELET", FLUID_FLAMELET) - MakePair("USER_DEFINED", USER_DEFINED) }; /*! diff --git a/SU2_CFD/include/numerics/CNumerics.hpp b/SU2_CFD/include/numerics/CNumerics.hpp index 309cac88e0c9..2e45916edb19 100644 --- a/SU2_CFD/include/numerics/CNumerics.hpp +++ b/SU2_CFD/include/numerics/CNumerics.hpp @@ -155,7 +155,6 @@ class CNumerics { 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 *UserDefinedSource; /*!< \brief User Defined Source term. */ const su2double *Coord_i, /*!< \brief Cartesians coordinates of point i. */ *Coord_j; /*!< \brief Cartesians coordinates of point j. */ diff --git a/SU2_CFD/include/numerics/flow/flow_sources.hpp b/SU2_CFD/include/numerics/flow/flow_sources.hpp index e6a138ec9016..e4cb64e4b54e 100644 --- a/SU2_CFD/include/numerics/flow/flow_sources.hpp +++ b/SU2_CFD/include/numerics/flow/flow_sources.hpp @@ -467,27 +467,3 @@ class CSourceRadiation : public CSourceBase_Flow { ResidualType<> ComputeResidual(const CConfig* config) override; }; - - -/*! - * \class CSourceUserDefined - * \brief Class for a user defined source term using the python wrapper - * \ingroup SourceDiscr - * \author Nijso Beishuizen - */ -class CSourceUserDefined : public CSourceBase_Flow { -private: - bool implicit; - -public: - - CSourceUserDefined(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config); - - /*! - * \brief Source term integration for a user defined source. - * \param[in] config - Definition of the particular problem. - * \return Lightweight const-view of residual and Jacobian. - */ - ResidualType<> ComputeResidual(const CConfig* config) override; - -}; diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp index c10ff9ea3460..1549f3937ff9 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp @@ -316,6 +316,39 @@ class CFVMFlowSolverBase : public CSolver { } } + +inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, + CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { + + /*--- Pick one numerics object per thread. ---*/ + CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; + + unsigned short iVar; + unsigned long iPoint; + AD::StartNoSharedReading(); + + SU2_OMP_FOR_STAT(omp_chunk_size) + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Load the volume of the dual mesh cell ---*/ + + numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + + /*--- Get control volume size. ---*/ + su2double Volume = geometry->nodes->GetVolume(iPoint); + + /*--- Compute the residual for this control volume and subtract. ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + LinSysRes[iPoint*nVar+iVar] += PointSource[iPoint][iVar] * Volume; + } + } + END_SU2_OMP_FOR + + AD::EndNoSharedReading(); + +} + + /*! * \brief Computes and sets the required auxilliary vars (and gradients) for axisymmetric flow. */ diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index b6de6f47ca65..94fea7b9300e 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -1005,6 +1005,8 @@ void CFVMFlowSolverBase::LoadRestart_impl(CGeometry **geometry, CSolver ** END_SU2_OMP_SAFE_GLOBAL_ACCESS } + + template void CFVMFlowSolverBase::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int iter, bool update_geo) { diff --git a/SU2_CFD/include/solvers/CIncEulerSolver.hpp b/SU2_CFD/include/solvers/CIncEulerSolver.hpp index 77bc75a49e0e..7185ea5fec35 100644 --- a/SU2_CFD/include/solvers/CIncEulerSolver.hpp +++ b/SU2_CFD/include/solvers/CIncEulerSolver.hpp @@ -212,11 +212,11 @@ class CIncEulerSolver : public CFVMFlowSolverBase CSourceAxisymmetric_Flow::ComputeResidual(const CConfi sq_vel += Velocity_i *Velocity_i; } - Pressure_i = (Gamma-1.0)*U_i[0]*(U_i[nDim+1]/U_i[0]-0.5*sq_vel); + // P = (gamma-1)*rho * e + // E = e+0.5*U^2 + // do we have primitive variables available? + Pressure_i = Gamma_Minus_One*U_i[0]*(U_i[nDim+1]/U_i[0]-0.5*sq_vel); + // (rho*e +p)/rho = e+p/rho Enthalpy_i = (U_i[nDim+1] + Pressure_i) / U_i[0]; + //cout <<"P="< CSourceRadiation::ComputeResidual(const CConfig *confi return ResidualType<>(residual, jacobian, nullptr); } - -CSourceUserDefined::CSourceUserDefined(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config) : - CSourceBase_Flow(val_nDim, val_nVar, config) { - - implicit = (config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); -} - -CNumerics::ResidualType<> CSourceUserDefined::ComputeResidual(const CConfig *config) { - - unsigned short iDim; - cout << "CSourceUserDefined" << endl; - /*--- Zero the continuity contribution. ---*/ - - residual[0] = 0.0; - - /*--- Zero the momentum contribution. ---*/ - - for (iDim = 0; iDim < nDim; iDim++) - residual[iDim+1] = 0.0; - - /*--- Set the energy contribution ---*/ - - residual[nDim+1] = -UserDefinedSource[0]*Volume; - - /*--- Set the energy contribution to the Jacobian. ---*/ - - if (implicit) { - - /*--- Jacobian is set to zero on initialization. ---*/ - - jacobian[nDim+1][nDim+1] = -UserDefinedSource[1]*Volume; - - } - - return ResidualType<>(residual, jacobian, nullptr); -} diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index f28734f7bb0a..55191bd0025c 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -342,9 +342,6 @@ void CIncEulerSolver::SetNondimensionalization(CConfig *config, unsigned short i auxFluidModel->SetTDState_T(Temperature_FreeStream, config->GetSpecies_Init()); break; - case USER_DEFINED: - break; - default: SU2_MPI::Error("Fluid model not implemented for incompressible solver.", CURRENT_FUNCTION); @@ -1816,36 +1813,36 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont } -void CIncEulerSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { +// void CIncEulerSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, +// CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { - /*--- Pick one numerics object per thread. ---*/ - CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; +// /*--- Pick one numerics object per thread. ---*/ +// CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; - unsigned short iVar; - unsigned long iPoint; - AD::StartNoSharedReading(); +// unsigned short iVar; +// unsigned long iPoint; +// AD::StartNoSharedReading(); - SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { +// SU2_OMP_FOR_STAT(omp_chunk_size) +// for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - /*--- Load the volume of the dual mesh cell ---*/ +// /*--- Load the volume of the dual mesh cell ---*/ - numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); +// numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - /*--- Get control volume size. ---*/ - su2double Volume = geometry->nodes->GetVolume(iPoint); +// /*--- Get control volume size. ---*/ +// su2double Volume = geometry->nodes->GetVolume(iPoint); - /*--- Compute the residual for this control volume and subtract. ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - LinSysRes[iPoint*nVar+iVar] += PointSource[iPoint][iVar] * Volume; - } - } - END_SU2_OMP_FOR +// /*--- Compute the residual for this control volume and subtract. ---*/ +// for (iVar = 0; iVar < nVar; iVar++) { +// LinSysRes[iPoint*nVar+iVar] += PointSource[iPoint][iVar] * Volume; +// } +// } +// END_SU2_OMP_FOR - AD::EndNoSharedReading(); +// AD::EndNoSharedReading(); -} +// } void CIncEulerSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, From c4a0487c6329e3fde4bff3c61e11dbe715f1adfd Mon Sep 17 00:00:00 2001 From: bigfooted Date: Fri, 11 Apr 2025 00:10:32 +0200 Subject: [PATCH 22/61] cleanup --- Common/include/CConfig.hpp | 13 ++++++ SU2_CFD/include/drivers/CDriver.hpp | 20 +++++++-- SU2_CFD/include/solvers/CIncEulerSolver.hpp | 10 ++--- SU2_CFD/src/python_wrapper_structure.cpp | 2 + SU2_CFD/src/solvers/CIncEulerSolver.cpp | 42 +++++++++---------- TestCases/parallel_regression.py | 4 +- .../custom_source/lam_buoyancy_cavity.cfg | 6 +-- TestCases/py_wrapper/custom_source/run.py | 19 +++++---- .../py_wrapper/turbulent_premixed_psi/run.py | 2 +- 9 files changed, 74 insertions(+), 44 deletions(-) diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index acb669e78193..fc17cd068e4f 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -9315,12 +9315,25 @@ class CConfig { */ unsigned long GetnInner_Iter(void) const { return nInnerIter; } + /*! + * \brief Set the number of inner iterations + * \return + */ + void SetnInner_Iter(unsigned long val_iter) { nInnerIter = val_iter; } + /*! * \brief Get the number of outer iterations * \return Number of outer iterations for the multizone problem */ unsigned long GetnOuter_Iter(void) const { return nOuterIter; } + /*! + * \brief Set the number of outer iterations + * \return + */ + unsigned long SetnOuter_Iter(unsigned long val_iter) { nOuterIter = val_iter; } + + /*! * \brief Get the number of time iterations * \return Number of time steps run diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index cbb646e5deff..efdc7484e598 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -481,6 +481,12 @@ class CDriver : public CDriverBase { */ unsigned long GetNumberInnerIter() const; + /*! + * \brief Set the number of inner iterations. + * \return + */ + void SetNumberInnerIter(unsigned long val_iter); + /*! * \brief Get the number of outer iterations. * \return Number of outer iterations. @@ -488,8 +494,14 @@ class CDriver : public CDriverBase { unsigned long GetNumberOuterIter() const; /*! - * \brief Get the current solution - * \return Current solution + * \brief Set the number of outer iterations. + * \return + */ + void SetNumberOuterIter(unsigned long val_iter); + + /*! + * \brief Get the current solution + * \return Current solution */ unsigned long GetSolution(unsigned short iSolver, unsigned long iPoint, unsigned short iVar); @@ -580,8 +592,8 @@ class CDriver : public CDriverBase { unsigned long GetDensity_FreeStreamND() const; /*! - * \brief Get the reference Body force for nondimensionalization - * \return reference Body Force + * \brief Get the reference Body force for nondimensionalization + * \return reference Body Force */ unsigned long GetForce_Ref() const; diff --git a/SU2_CFD/include/solvers/CIncEulerSolver.hpp b/SU2_CFD/include/solvers/CIncEulerSolver.hpp index 7185ea5fec35..77bc75a49e0e 100644 --- a/SU2_CFD/include/solvers/CIncEulerSolver.hpp +++ b/SU2_CFD/include/solvers/CIncEulerSolver.hpp @@ -212,11 +212,11 @@ class CIncEulerSolver : public CFVMFlowSolverBaseGetnInner_Iter(); } unsigned long CDriver::GetNumberOuterIter() const { return config_container[selected_zone]->GetnOuter_Iter(); } +void CDriver::SetNumberInnerIter(unsigned long val_iter) { config_container[selected_zone]->SetnInner_Iter(val_iter); } +void CDriver::SetNumberOuterIter(unsigned long val_iter) { config_container[selected_zone]->SetnOuter_Iter(val_iter); } unsigned long CDriver::GetDensity_FreeStreamND() const { return SU2_TYPE::GetValue(config_container[selected_zone]->GetDensity_FreeStreamND()); diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index 55191bd0025c..77ada96d0c5e 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -1813,36 +1813,36 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont } -// void CIncEulerSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, -// CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { +void CIncEulerSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, + CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { -// /*--- Pick one numerics object per thread. ---*/ -// CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; + /*--- Pick one numerics object per thread. ---*/ + CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; -// unsigned short iVar; -// unsigned long iPoint; -// AD::StartNoSharedReading(); + unsigned short iVar; + unsigned long iPoint; + AD::StartNoSharedReading(); -// SU2_OMP_FOR_STAT(omp_chunk_size) -// for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + SU2_OMP_FOR_STAT(omp_chunk_size) + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { -// /*--- Load the volume of the dual mesh cell ---*/ + /*--- Load the volume of the dual mesh cell ---*/ -// numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); -// /*--- Get control volume size. ---*/ -// su2double Volume = geometry->nodes->GetVolume(iPoint); + /*--- Get control volume size. ---*/ + su2double Volume = geometry->nodes->GetVolume(iPoint); -// /*--- Compute the residual for this control volume and subtract. ---*/ -// for (iVar = 0; iVar < nVar; iVar++) { -// LinSysRes[iPoint*nVar+iVar] += PointSource[iPoint][iVar] * Volume; -// } -// } -// END_SU2_OMP_FOR + /*--- Compute the residual for this control volume and subtract. ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + LinSysRes[iPoint*nVar+iVar] += PointSource[iPoint][iVar] * Volume; + } + } + END_SU2_OMP_FOR -// AD::EndNoSharedReading(); + AD::EndNoSharedReading(); -// } +} void CIncEulerSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index 8c26e1a7364e..0f05bd4d93cb 100644 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -1470,7 +1470,7 @@ def main(): pywrapper_buoyancy = TestCase('pywrapper_buoyancy') pywrapper_buoyancy.cfg_dir = "py_wrapper/custom_source" pywrapper_buoyancy.cfg_file = "lam_buoyancy_cavity.cfg" - pywrapper_buoyancy.test_iter = 1 + pywrapper_buoyancy.test_iter = 0 pywrapper_buoyancy.test_vals = [0.500000, 0.000000, -3.037859, -1.603563, -2.074259, 2.424288, 7.762848, -0.220436] pywrapper_buoyancy.command = TestCase.Command("mpirun -np 2", "python", "run.py") test_list.append(pywrapper_buoyancy) @@ -1479,7 +1479,7 @@ def main(): pywrapper_zimont = TestCase('pywrapper_zimont') pywrapper_zimont.cfg_dir = "py_wrapper/psi" pywrapper_zimont.cfg_file = "psi.cfg" - pywrapper_zimont.test_iter = 1 + pywrapper_zimont.test_iter = 0 pywrapper_zimont.test_vals = [0.500000, 0.000000, -3.037859, -1.603563, -2.074259, 2.424288, 7.762848, -0.220436] pywrapper_zimont.command = TestCase.Command("mpirun -np 2", "python", "run.py") test_list.append(pywrapper_zimont) diff --git a/TestCases/py_wrapper/custom_source/lam_buoyancy_cavity.cfg b/TestCases/py_wrapper/custom_source/lam_buoyancy_cavity.cfg index 470a895b372a..55d2beae88ce 100644 --- a/TestCases/py_wrapper/custom_source/lam_buoyancy_cavity.cfg +++ b/TestCases/py_wrapper/custom_source/lam_buoyancy_cavity.cfg @@ -72,7 +72,7 @@ CFL_ADAPT= NO CFL_ADAPT_PARAM= ( 1.5, 0.5, 15.0, 1e10) MAX_DELTA_TIME= 1E6 RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) -ITER=1 +ITER=6 % ------------------------ LINEAR SOLVER DEFINITION ---------------------------% % @@ -114,7 +114,5 @@ GRAD_OBJFUNC_FILENAME= of_grad.dat SURFACE_FILENAME= surface_flow SURFACE_ADJ_FILENAME= surface_adjoint OUTPUT_WRT_FREQ= 100 -SCREEN_OUTPUT= (OUTER_ITER, INNER_ITER, RMS_PRESSURE, RMS_TEMPERATURE, LIFT, DRAG) +SCREEN_OUTPUT= (OUTER_ITER,INNER_ITER, RMS_PRESSURE, RMS_VELOCITY-X, RMS_VELOCITY-Y, RMS_TEMPERATURE) -% ----------------------- GEOMETRY EVALUATION PARAMETERS ----------------------% -GEO_BOUNDS= ( 0.499, 0.501) diff --git a/TestCases/py_wrapper/custom_source/run.py b/TestCases/py_wrapper/custom_source/run.py index ea79d52c446a..c19e010a41bf 100644 --- a/TestCases/py_wrapper/custom_source/run.py +++ b/TestCases/py_wrapper/custom_source/run.py @@ -26,14 +26,17 @@ import sys import pysu2 -# from mpi4py import MPI +from mpi4py import MPI + def main(): """ custom source to add buoyancy term. """ - # comm = MPI.COMM_WORLD - comm = 0 + # parallel + comm = MPI.COMM_WORLD + # serial + #comm = 0 # Initialize the primal driver of SU2, this includes solver preprocessing. try: @@ -91,16 +94,18 @@ def main(): Force_Ref = driver.GetForce_Ref() #print("reference force = ",Force_Ref) - for inner_iter in range(5): + Iter = driver.GetNumberInnerIter() + print("1. inner iterations = ",Iter) + # set the inner iterations to 1 + driver.SetNumberInnerIter(1) + for inner_iter in range(Iter): # set the source term, per point + print(driver.GetNumberNodes() - driver.GetNumberHaloNodes()) for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): #SolutionVector = driver.GetSolutionVector(iSOLVER,i_node) - #print("solutionvector=",SolutionVector) PrimitiveVector = driver.GetPrimitiveVector(iSOLVER,i_node) - #print("primitivevector=",PrimitiveVector) DensityInc_i = PrimitiveVector[iDENSITY] - #print("density=",DensityInc_i) for iDim in range(nDim): custom_source_vector[iDim+1] = -(DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py index 89096f5a9dd1..855ea373d5da 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/run.py +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -247,7 +247,7 @@ def main(): sys.stdout.flush() # run N iterations - for inner_iter in range(10000): + for inner_iter in range(5): driver.Preprocess(inner_iter) driver.Run() From e711ed042aa7276356c28435f843247937529f4d Mon Sep 17 00:00:00 2001 From: bigfooted Date: Fri, 11 Apr 2025 10:10:27 +0200 Subject: [PATCH 23/61] fix return value --- Common/include/CConfig.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index fc17cd068e4f..ac03b0d6f3f5 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -9331,8 +9331,7 @@ class CConfig { * \brief Set the number of outer iterations * \return */ - unsigned long SetnOuter_Iter(unsigned long val_iter) { nOuterIter = val_iter; } - + void SetnOuter_Iter(unsigned long val_iter) { nOuterIter = val_iter; } /*! * \brief Get the number of time iterations From 64b376115b0651d5de2186ac4f9cf3ee08bf8516 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Sat, 12 Apr 2025 09:21:48 +0200 Subject: [PATCH 24/61] move python source up --- SU2_CFD/include/solvers/CIncEulerSolver.hpp | 10 ++--- SU2_CFD/src/solvers/CIncEulerSolver.cpp | 42 ++++++++++----------- SU2_CFD/src/solvers/CSolver.cpp | 1 + 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/SU2_CFD/include/solvers/CIncEulerSolver.hpp b/SU2_CFD/include/solvers/CIncEulerSolver.hpp index 77bc75a49e0e..7185ea5fec35 100644 --- a/SU2_CFD/include/solvers/CIncEulerSolver.hpp +++ b/SU2_CFD/include/solvers/CIncEulerSolver.hpp @@ -212,11 +212,11 @@ class CIncEulerSolver : public CFVMFlowSolverBaseSetVolume(geometry->nodes->GetVolume(iPoint)); +// numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - /*--- Get control volume size. ---*/ - su2double Volume = geometry->nodes->GetVolume(iPoint); +// /*--- Get control volume size. ---*/ +// su2double Volume = geometry->nodes->GetVolume(iPoint); - /*--- Compute the residual for this control volume and subtract. ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - LinSysRes[iPoint*nVar+iVar] += PointSource[iPoint][iVar] * Volume; - } - } - END_SU2_OMP_FOR +// /*--- Compute the residual for this control volume and subtract. ---*/ +// for (iVar = 0; iVar < nVar; iVar++) { +// LinSysRes[iPoint*nVar+iVar] += PointSource[iPoint][iVar] * Volume; +// } +// } +// END_SU2_OMP_FOR - AD::EndNoSharedReading(); +// AD::EndNoSharedReading(); -} +// } void CIncEulerSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, diff --git a/SU2_CFD/src/solvers/CSolver.cpp b/SU2_CFD/src/solvers/CSolver.cpp index 009910e91a2a..8af6bf8968a6 100644 --- a/SU2_CFD/src/solvers/CSolver.cpp +++ b/SU2_CFD/src/solvers/CSolver.cpp @@ -4357,3 +4357,4 @@ void CSolver::SavelibROM(CGeometry *geometry, CConfig *config, bool converged) { #endif } + From a5013c6721e9338e800c36c773c731e23e106b2e Mon Sep 17 00:00:00 2001 From: bigfooted Date: Sun, 13 Apr 2025 00:16:00 +0200 Subject: [PATCH 25/61] cleanup --- .../include/solvers/CFVMFlowSolverBase.inl | 4 +-- SU2_CFD/include/solvers/CIncEulerSolver.hpp | 13 -------- SU2_CFD/include/solvers/CSolver.hpp | 2 -- SU2_CFD/include/solvers/CSpeciesSolver.hpp | 2 +- SU2_CFD/src/numerics/flow/flow_sources.cpp | 7 ---- SU2_CFD/src/solvers/CIncEulerSolver.cpp | 32 ------------------- 6 files changed, 2 insertions(+), 58 deletions(-) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 94fea7b9300e..e94c732a6519 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -125,7 +125,7 @@ void CFVMFlowSolverBase::Allocate(const CConfig& config) { AllocVectorOfMatrices(nVertex, nDim, Inlet_FlowDir); PointSource.resize(nPointDomain,nVar); PointSource.setConstant(0.0); - + /*--- Force definition and coefficient arrays for all of the markers ---*/ AllocVectorOfVectors(nVertex, CPressure); @@ -1005,8 +1005,6 @@ void CFVMFlowSolverBase::LoadRestart_impl(CGeometry **geometry, CSolver ** END_SU2_OMP_SAFE_GLOBAL_ACCESS } - - template void CFVMFlowSolverBase::LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int iter, bool update_geo) { diff --git a/SU2_CFD/include/solvers/CIncEulerSolver.hpp b/SU2_CFD/include/solvers/CIncEulerSolver.hpp index 7185ea5fec35..990c9b7095d5 100644 --- a/SU2_CFD/include/solvers/CIncEulerSolver.hpp +++ b/SU2_CFD/include/solvers/CIncEulerSolver.hpp @@ -204,19 +204,6 @@ class CIncEulerSolver : public CFVMFlowSolverBase { protected: unsigned short Inlet_Position; /*!< \brief Column index for scalar variables in inlet files. */ vector Inlet_SpeciesVars; /*!< \brief Species variables at inlet profiles. */ - su2activematrix SpeciesPointSource; /*!< \brief Value of the Flow Direction. */ + su2activematrix SpeciesPointSource; /*!< \brief User defined source term. */ public: /*! diff --git a/SU2_CFD/src/numerics/flow/flow_sources.cpp b/SU2_CFD/src/numerics/flow/flow_sources.cpp index 6d60540a346d..379c6ba2f12e 100644 --- a/SU2_CFD/src/numerics/flow/flow_sources.cpp +++ b/SU2_CFD/src/numerics/flow/flow_sources.cpp @@ -73,20 +73,13 @@ CNumerics::ResidualType<> CSourceAxisymmetric_Flow::ComputeResidual(const CConfi sq_vel += Velocity_i *Velocity_i; } - // P = (gamma-1)*rho * e - // E = e+0.5*U^2 - // do we have primitive variables available? Pressure_i = Gamma_Minus_One*U_i[0]*(U_i[nDim+1]/U_i[0]-0.5*sq_vel); - // (rho*e +p)/rho = e+p/rho Enthalpy_i = (U_i[nDim+1] + Pressure_i) / U_i[0]; - //cout <<"P="<SetVolume(geometry->nodes->GetVolume(iPoint)); - -// /*--- Get control volume size. ---*/ -// su2double Volume = geometry->nodes->GetVolume(iPoint); - -// /*--- Compute the residual for this control volume and subtract. ---*/ -// for (iVar = 0; iVar < nVar; iVar++) { -// LinSysRes[iPoint*nVar+iVar] += PointSource[iPoint][iVar] * Volume; -// } -// } -// END_SU2_OMP_FOR - -// AD::EndNoSharedReading(); - -// } - - void CIncEulerSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, CConfig *config, unsigned short iMesh) { From 6470580b761a859d5231853b5dbd7d1b863ce4d3 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Tue, 20 May 2025 09:30:31 +0200 Subject: [PATCH 26/61] custom energy source --- TestCases/py_wrapper/custom_source/run.py | 2 +- TestCases/py_wrapper/tfc_heatloss/psi.cfg | 165 +++++++++++++ TestCases/py_wrapper/tfc_heatloss/run.py | 274 ++++++++++++++++++++++ 3 files changed, 440 insertions(+), 1 deletion(-) create mode 100644 TestCases/py_wrapper/tfc_heatloss/psi.cfg create mode 100644 TestCases/py_wrapper/tfc_heatloss/run.py diff --git a/TestCases/py_wrapper/custom_source/run.py b/TestCases/py_wrapper/custom_source/run.py index c19e010a41bf..040457c79e22 100644 --- a/TestCases/py_wrapper/custom_source/run.py +++ b/TestCases/py_wrapper/custom_source/run.py @@ -110,7 +110,7 @@ def main(): for iDim in range(nDim): custom_source_vector[iDim+1] = -(DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref - driver.SetPointCustomSource(iSOLVER, i_node,custom_source_vector) + driver.SetPointCustomSource(iSOLVER, i_node, custom_source_vector) print(" *** inner iteration:",inner_iter) driver.Preprocess(inner_iter) diff --git a/TestCases/py_wrapper/tfc_heatloss/psi.cfg b/TestCases/py_wrapper/tfc_heatloss/psi.cfg new file mode 100644 index 000000000000..0498fb6b65bd --- /dev/null +++ b/TestCases/py_wrapper/tfc_heatloss/psi.cfg @@ -0,0 +1,165 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Turbulent premixed high pressure combustion chamber. % +% Author: N. Beishuizen % +% Institution: Bosch Thermotechniek B.V. % +% Date: 2025/01/01 % +% File Version 8.0 "Harrier" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= INC_RANS +KIND_TURB_MODEL= SST +SST_OPTIONS= V1994m + +RESTART_SOL= NO + +MGLEVEL= 0 +% + +% temperature and density +FREESTREAM_TEMPERATURE = 673 +FREESTREAM_DENSITY = 2.55 +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +%INC_DENSITY_MODEL= CONSTANT +INC_DENSITY_MODEL= VARIABLE +INC_DENSITY_INIT= 2.55 +% +INC_VELOCITY_INIT= (40.00, 0.0, 0.0 ) +% +INC_ENERGY_EQUATION= YES +INC_TEMPERATURE_INIT= 673.0 +% +INC_NONDIM= DIMENSIONAL +% +% -------------------- FLUID PROPERTIES ------------------------------------- % +% +%FLUID_MODEL= CONSTANT_DENSITY +FLUID_MODEL= INC_IDEAL_GAS +% +CONDUCTIVITY_MODEL= CONSTANT_CONDUCTIVITY +THERMAL_CONDUCTIVITY_CONSTANT= 0.0357 +% +PRANDTL_LAM= 0.72 +TURBULENT_CONDUCTIVITY_MODEL= NONE +PRANDTL_TURB= 0.90 +% +VISCOSITY_MODEL= SUTHERLAND +MU_CONSTANT= 1.716E-5 +MU_REF = 1.716e-5 +MU_T_REF= 273.15 +SUTHERLAND_CONSTANT = 110.4 + +SPECIFIC_HEAT_CP = 1150 +% +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( wall_top, 0.0,wall_side,0.0,wall_pipe,0.0, wall_out, 0.0 ) + +% note, case is axisymmetric +MARKER_SYM= ( symmetry ) +AXISYMMETRIC= YES +% +SPECIFIED_INLET_PROFILE= NO +INLET_MATCHING_TOLERANCE=1e-4 +INLET_FILENAME= inlet.dat +%INLET_INTERPOLATION_FUNCTION= LINEAR_1D +INC_INLET_TYPE= VELOCITY_INLET +INC_INLET_DAMPING= 0.01 +MARKER_INLET= ( inlet, 673, 40.0, 1.0, 0.0, 0.0) +MARKER_INLET_TURBULENT = (inlet, 0.10, 15) +MARKER_INLET_SPECIES= (inlet, 0.0) +% +INC_OUTLET_TYPE= PRESSURE_OUTLET +INC_OUTLET_DAMPING= 0.01 +MARKER_OUTLET= ( outlet, 0.0 ) +% +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES +% +CFL_NUMBER= 1.0 +CFL_REDUCTION_SPECIES= 1.0 +CFL_REDUCTION_TURB= 1.0 +% +ITER= 1 +% +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1E-8 +LINEAR_SOLVER_ITER= 10 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= FDS +MUSCL_FLOW= NO +SLOPE_LIMITER_FLOW = NONE +TIME_DISCRE_FLOW= EULER_IMPLICIT +% +% -------------------- SCALAR TRANSPORT ---------------------------------------% +% +KIND_SCALAR_MODEL= SPECIES_TRANSPORT +DIFFUSIVITY_MODEL= CONSTANT_DIFFUSIVITY +SCHMIDT_NUMBER_LAMINAR= 1.0 +DIFFUSIVITY_CONSTANT= 7.56e-5 + +% according to the paper +SCHMIDT_NUMBER_TURBULENT= 0.7 + +% +CONV_NUM_METHOD_SPECIES= BOUNDED_SCALAR +MUSCL_SPECIES= NO +SLOPE_LIMITER_SPECIES = NONE +% +TIME_DISCRE_SPECIES= EULER_IMPLICIT +% +SPECIES_INIT= 0.0 +SPECIES_CLIPPING= YES +SPECIES_CLIPPING_MIN= 0.0 +SPECIES_CLIPPING_MAX= 1.0 +% +% -------------------- TURBULENT TRANSPORT ---------------------------------------% +% +CONV_NUM_METHOD_TURB= BOUNDED_SCALAR +MUSCL_TURB= NO + +% +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_FIELD= RMS_PRESSURE, RMS_VELOCITY-X, RMS_VELOCITY-Y, RMS_TKE, RMS_SPECIES +CONV_RESIDUAL_MINVAL= -18 +CONV_STARTITER= 10 +% +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +%MESH_FILENAME= psi_coarse.su2 +MESH_FILENAME= psi.su2 +%MESH_FILENAME= psi_fine.su2 +% +SCREEN_OUTPUT= INNER_ITER WALL_TIME \ + RMS_PRESSURE RMS_VELOCITY-X RMS_VELOCITY-Y RMS_TKE RMS_DISSIPATION RMS_SPECIES_0 \ + LINSOL_ITER LINSOL_RESIDUAL \ + LINSOL_ITER_TURB LINSOL_RESIDUAL_TURB \ + LINSOL_ITER_SPECIES LINSOL_RESIDUAL_SPECIES +SCREEN_WRT_FREQ_INNER= 1 +% +HISTORY_OUTPUT= ITER RMS_RES LINSOL SPECIES_COEFF SPECIES_COEFF_SURF +CONV_FILENAME= history +MARKER_ANALYZE= gas_inlet, air_axial_inlet, outlet +MARKER_ANALYZE_AVERAGE= AREA +% +OUTPUT_FILES= RESTART_ASCII, PARAVIEW_MULTIBLOCK +VOLUME_OUTPUT= RESIDUAL, PRIMITIVE +OUTPUT_WRT_FREQ= 100 +% +READ_BINARY_RESTART= NO +RESTART_FILENAME= restart +SOLUTION_FILENAME= solution +% +WRT_PERFORMANCE= YES diff --git a/TestCases/py_wrapper/tfc_heatloss/run.py b/TestCases/py_wrapper/tfc_heatloss/run.py new file mode 100644 index 000000000000..855ea373d5da --- /dev/null +++ b/TestCases/py_wrapper/tfc_heatloss/run.py @@ -0,0 +1,274 @@ +#!/usr/bin/env python + +## \file run.py +# \brief turbulent premixed dump combustor simulation (PSI flame) +# phi=0.5, methane-air, U=40 m/s +# \version 8.1.0 "Harrier" +# +# SU2 Project Website: https://su2code.github.io +# +# The SU2 Project is maintained by the SU2 Foundation +# (http://su2foundation.org) +# +# Copyright 2012-2024, 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 . + +import sys +import pysu2 +from mpi4py import MPI +import numpy as np +#from mpi4py import MPI + +# unburnt temperature of the propane-air mixture +# flame temperature of the methane-air mixture (phi=0.5, P=5) +Tf = 1777 + +Tu = 673.0 +Pu = 5.0 +phi = 0.5 +# unburnt density at P=5 +rho_u = 2.52 +# unburnt thermal conductivity of methane-air at phi=0.5 (P=5) +k_u = 0.0523 +# unburnt heat capacity of methane-air at phi=0.5 (P=1) +cp_u = 1311.0 + +# P = rho*R*T +# 5 = 2.55 * R * 673 +# R = 0.0029 + +# ################################################################## # +# create a function for the initial progress variable # +# ################################################################## # +def initC(coord): + x = coord[0] + #y = coord[1] + #z = coord[2] + #print("x,y = ",x," ",y) + # location where the flame should be + flame_x = 0.012 + if (x < flame_x): + C = 0.0 + else: + C = 1.0 + + return C + +# ################################################################## # +# loop over all vertices and set the species progress variable # +# ################################################################## # +def SetInitialSpecies(SU2Driver): + allCoords = SU2Driver.Coordinates() + iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] + print("index of species solver = ",iSPECIESSOLVER) + nVarsSpecies = SU2Driver.GetNumberSolverVars(iSPECIESSOLVER) + print("number of species solver variables:",nVarsSpecies) + for iPoint in range(SU2Driver.GetNumberNodes() - SU2Driver.GetNumberHaloNodes()): + coord = allCoords.Get(iPoint) + C = initC(coord) + # now update the initial condition + SU2Driver.SetSolutionVector(iSPECIESSOLVER, iPoint, [C]) + +def SetInitialVelocity(SU2Driver): + allCoords = SU2Driver.Coordinates() + iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] + print("index of FLOW solver = ",iFLOWSOLVER) + nVarsFlow = SU2Driver.GetNumberSolverVars(iFLOWSOLVER) + print("number of flow solver variables:",nVarsFlow) + for iPoint in range(SU2Driver.GetNumberNodes() - SU2Driver.GetNumberHaloNodes()): + coord = allCoords.Get(iPoint) + C = initC(coord) + # now update the initial condition + SU2Driver.SetSolutionVector(iFLOWSOLVER, iPoint, [C]) + +def update_temperature(SU2Driver, iPoint): + # first, get the progress variable + iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] + # returns a list + C = SU2Driver.GetSolutionVector(iSPECIESSOLVER, iPoint) + T = Tu*(1-C[0]) + Tf*C[0] + iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] + solvar = list(SU2Driver.GetSolutionVector(iFLOWSOLVER, iPoint)) + # the list with names + solindex = getsolvar(SU2Driver) + primindex = SU2Driver.GetPrimitiveIndices() + iTEMP = solindex.get("TEMPERATURE") + solvar[iTEMP] = T + SU2Driver.SetSolutionVector(iFLOWSOLVER, iPoint, solvar) + + +def zimont(SU2Driver, iPoint): + iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] + iSSTSOLVER = SU2Driver.GetSolverIndices()['SST'] + iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] + primindex = SU2Driver.GetPrimitiveIndices() + primvar = list(SU2Driver.GetPrimitiveVector(iFLOWSOLVER, iPoint)) + + iDENSITY = primindex.get("DENSITY") + iMU = primindex.get("LAMINAR_VISCOSITY") + + # laminar burning velocity of methane-air at phi=0.5, P=5 + Slu = 0.232 + + + rho = primvar[iDENSITY] + mu = primvar[iMU] + nu=mu/rho + tke, dissipation = SU2Driver.GetSolutionVector(iSSTSOLVER,iPoint) + gradc = SU2Driver.GetGradient(iSPECIESSOLVER,iPoint,0) + # Turbulent Flamespeed Closure with Dinkelacker correction + up = np.sqrt((2.0/3.0) * tke ) + lt = (0.09**0.75) * (tke**1.5) / dissipation + Re = up*lt/nu + Le = 1.0 + Ut = Slu * (1.0 + (0.46/Le) * np.power(Re,0.25) * np.power(up/Slu,0.3) * np.power(Pu,0.2) ) + norm_gradc = np.sqrt(gradc[0]*gradc[0] + gradc[1]*gradc[1]) + #if (norm_gradc > 1.): + # print(tke," ",rho_u," Ut=",Ut," , |grad(c)| = ",norm_gradc, " ",gradc[0]," ",gradc[1]) + Sc = rho_u * Ut * norm_gradc + + return Sc + +def getsolvar(SU2Driver): + primindex = SU2Driver.GetPrimitiveIndices() + iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] + nVars = SU2Driver.GetNumberSolverVars(iFLOWSOLVER) + varindex = primindex.copy() + for prim in varindex.copy(): + if varindex[prim] >=nVars: + del varindex[prim] + varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) + return varindex + + +def main(): + comm = MPI.COMM_WORLD + rank = comm.Get_rank() + + # Initialize the primal driver of SU2, this includes solver preprocessing. + try: + driver = pysu2.CSinglezoneDriver('psi.cfg', 1, comm) + except TypeError as exception: + print('A TypeError occured in pysu2.CSinglezoneDriver : ', exception) + raise + + if rank == 0: + print("\n------------------------------ Begin Solver -----------------------------") + sys.stdout.flush() + + nDim = driver.GetNumberDimensions() + print("Dimensions of the problem = ",nDim) + + # index to the flow solver + # C.FLOW + # INC.FLOW + # HEAT + # FLAMELET + # SPECIES + # SA + # SST + iFLOWSOLVER = driver.GetSolverIndices()['INC.FLOW'] + print("index of flow solver = ",iFLOWSOLVER) + iSPECIESSOLVER = driver.GetSolverIndices()['SPECIES'] + print("index of species solver = ",iSPECIESSOLVER) + iSSTSOLVER = driver.GetSolverIndices()['SST'] + print("index of turbulence solver = ",iSSTSOLVER) + + + # all the indices and the map to the names of the primitives + primindex = driver.GetPrimitiveIndices() + print("indices of primitives=",primindex) + print("number of primitives:",len(primindex)) + + nElem = driver.GetNumberElements() + print("number of elements:",nElem) + + nVars = driver.GetNumberSolverVars(iFLOWSOLVER) + print("number of flow solver variables:",nVars) + + nVarsSpecies = driver.GetNumberSolverVars(iSPECIESSOLVER) + print("number of species solver variables:",nVarsSpecies) + nVarsTurb = driver.GetNumberSolverVars(iSSTSOLVER) + print("number of turbulence solver variables:",nVarsTurb) + + varindex = primindex.copy() + for prim in varindex.copy(): + if varindex[prim] >=nVars: + del varindex[prim] + varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) + + +# it is possible to get the solver type by doing +# iFLOWSOLVER = driver.GetSolverIndices()['INC.FLOW'] +# with the solver type we then get the solver variables using: + +# nVars = driver.GetNumberSolverVars(iFLOWSOLVER) +# and the solver variable names: +# print("solver variable names:",varindex) + +# we can overwrite the solution using: +# driver.SetSolutionVector(iSolver, iPoint, solutionVector) +# + + #print("solver variable names:",varindex) + iDENSITY = primindex.get("DENSITY") + #print("index of density = ",iDENSITY) + + index_Vel = varindex.get("VELOCITY_X") + #print("index of velocity = ",index_Vel) + + custom_source_vector = [0.0 for i in range(nVars)] + #print("custom source vector = ", custom_source_vector) + + #print("max. number of inner iterations: ",driver.GetNumberInnerIter()); + #print("max nr of outer iterations: ",driver.GetNumberOuterIter()); + with open('psi.cfg') as f: + if 'RESTART_SOL= YES' in f.read(): + print("restarting from file") + else: + # We can set an initial condition by calling this function: + print("Start calling SetInitialSpecies") + SetInitialSpecies(driver) + print("End calling SetInitialSpecies") + + # super important to actually push the commands. + sys.stdout.flush() + + # run N iterations + for inner_iter in range(5): + + driver.Preprocess(inner_iter) + driver.Run() + + # set the source term, per point + for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): + # add source term: + # default TFC of Zimont: rho*Sc = rho_u * U_t * grad(c) + S = [zimont(driver,i_node)] + driver.SetPointCustomSource(iSPECIESSOLVER, i_node,S) + # at this point we also need to update the temperature based on the progress variable: + # set the temperature to T = c*Tf + (1-c)*Tu + update_temperature(driver, i_node) + + driver.Postprocess() + driver.Update() + #driver.Monitor(inner_iter) + driver.Output(inner_iter) + + # Finalize the solver and exit cleanly. + driver.Finalize() + +if __name__ == '__main__': + main() From a1a0d7b1d49f670275b3beb1a175d5c712d2d57a Mon Sep 17 00:00:00 2001 From: bigfooted Date: Thu, 26 Jun 2025 11:01:58 +0200 Subject: [PATCH 27/61] add new boundary conditions --- Common/include/CConfig.hpp | 35 +++ Common/include/option_structure.hpp | 14 + Common/src/CConfig.cpp | 115 ++++++-- SU2_CFD/include/solvers/CSpeciesSolver.hpp | 21 ++ SU2_CFD/src/solvers/CSpeciesSolver.cpp | 46 ++- TestCases/py_wrapper/tfc_heatloss/psi.cfg | 165 ----------- TestCases/py_wrapper/tfc_heatloss/run.py | 274 ------------------ .../py_wrapper/turbulent_premixed_psi/run.py | 100 +++---- 8 files changed, 247 insertions(+), 523 deletions(-) delete mode 100644 TestCases/py_wrapper/tfc_heatloss/psi.cfg delete mode 100644 TestCases/py_wrapper/tfc_heatloss/run.py diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 5f2627a50405..70ea43a27094 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -194,8 +194,10 @@ class CConfig { nMarker_CHTInterface, /*!< \brief Number of conjugate heat transfer interface markers. */ nMarker_ContactResistance, /*!< \brief Number of CHT interfaces with contact resistance. */ nMarker_Inlet, /*!< \brief Number of inlet flow markers. */ + nMarker_Wall_Species, /*!< \brief Number of inlet flow markers. */ nMarker_Inlet_Species, /*!< \brief Number of inlet species markers. */ nSpecies_per_Inlet, /*!< \brief Number of species defined per inlet markers. */ + nSpecies_per_Wall, /*!< \brief Number of species defined per inlet markers. */ nMarker_Inlet_Turb, /*!< \brief Number of inlet turbulent markers. */ nTurb_Properties, /*!< \brief Number of turbulent properties per inlet markers. */ nMarker_Riemann, /*!< \brief Number of Riemann flow markers. */ @@ -250,6 +252,7 @@ class CConfig { *Marker_ActDiskBemInlet_Axis, /*!< \brief Actuator disk BEM inlet markers passed to MARKER_ACTDISK_BEM_AXIS. */ *Marker_ActDiskBemOutlet_Axis, /*!< \brief Actuator disk BEM outlet markers passed to MARKER_ACTDISK_BEM_AXIS. */ *Marker_Inlet, /*!< \brief Inlet flow markers. */ + *Marker_Wall_Species, /*!< \brief Inlet flow markers. */ *Marker_Inlet_Species, /*!< \brief Inlet species markers. */ *Marker_Inlet_Turb, /*!< \brief Inlet turbulent markers. */ *Marker_Riemann, /*!< \brief Riemann markers. */ @@ -289,6 +292,7 @@ class CConfig { su2double *Inlet_Pressure; /*!< \brief Specified static pressures for supersonic inlet boundaries. */ su2double **Inlet_Velocity; /*!< \brief Specified flow velocity vectors for supersonic inlet boundaries. */ su2double **Inlet_SpeciesVal; /*!< \brief Specified species vector for inlet boundaries. */ + su2double **Wall_SpeciesVal; /*!< \brief Specified species vector for wall boundaries. */ su2double **Inlet_TurbVal; /*!< \brief Specified turbulent intensity and viscosity ratio for inlet boundaries. */ su2double *EngineInflow_Target; /*!< \brief Specified fan face targets for nacelle boundaries. */ su2double *Inflow_Mach; /*!< \brief Specified fan face mach for nacelle boundaries. */ @@ -615,9 +619,13 @@ class CConfig { *Kind_Data_Giles; /*!< \brief Kind of inlet boundary treatment. */ INLET_TYPE Kind_Inlet; INLET_TYPE *Kind_Inc_Inlet; + + //WALL_SPECIES_TYPE **Wall_SpeciesType; + unsigned short **Wall_SpeciesType; INC_OUTLET_TYPE *Kind_Inc_Outlet; unsigned short nWall_Types; /*!< \brief Number of wall treatment types listed. */ unsigned short nInc_Inlet; /*!< \brief Number of inlet boundary treatment types listed. */ + unsigned short nSpecies_Wall; /*!< \brief Number of inlet boundary treatment types listed. */ unsigned short nInc_Outlet; /*!< \brief Number of inlet boundary treatment types listed. */ su2double Inc_Inlet_Damping; /*!< \brief Damping factor applied to the iterative updates to the velocity at a pressure inlet in incompressible flow. */ su2double Inc_Outlet_Damping; /*!< \brief Damping factor applied to the iterative updates to the pressure at a mass flow outlet in incompressible flow. */ @@ -1339,6 +1347,12 @@ class CConfig { void addInletOption(const string& name, unsigned short & nMarker_Inlet, string * & Marker_Inlet, su2double* & Ttotal, su2double* & Ptotal, su2double** & FlowDir); + void addWallSpeciesOption(const string& name, unsigned short & nMarker_Wall_Species, string * & Marker_Wall_Species, + su2double** & wall_species_val, unsigned short & nSpecies_per_Wall); + void addWallSpeciesType(const string& name, unsigned short & nMarker_Wall_Species, string * & Marker_Wall_Species, +// WALL_SPECIES_TYPE** & wall_species_type, unsigned short & nSpecies_per_Wall); + unsigned short** & wall_species_type, unsigned short & nSpecies_per_Wall); + void addInletSpeciesOption(const string& name, unsigned short & nMarker_Inlet_Species, string * & Marker_Inlet_Species, su2double** & inlet_species_val, unsigned short & nSpecies_per_Inlet); @@ -4957,6 +4971,13 @@ class CConfig { */ INLET_TYPE GetKind_Inc_Inlet(const string& val_marker) const; + /*! + * \brief Get the type of incompressible inlet from the list. + * \return Kind of the incompressible inlet. + */ +// WALL_SPECIES_TYPE* GetKind_Wall_Species(const string& val_marker) const; + //unsigned short* GetKind_Wall_Species(const string& val_marker) const; + /*! * \brief Get the total number of types in Kind_Inc_Inlet list * \return Total number of types in Kind_Inc_Inlet list @@ -6828,6 +6849,20 @@ class CConfig { */ const su2double* GetInlet_SpeciesVal(const string& val_index) const; + /*! + * \brief Get the species values at a wall boundary + * \param[in] val_index - Index corresponding to the wall boundary. + * \return The wall species values. + */ + const su2double* GetWall_SpeciesVal(const string& val_index) const; + /*! + * \brief Get the species values at a wall boundary + * \param[in] val_index - Index corresponding to the wall boundary. + * \return The wall species values. + */ + //const WALL_SPECIES_TYPE* GetWall_SpeciesType(const string& val_index) const; + const unsigned short* GetWall_SpeciesType(const string& val_index) const; + /*! * \brief Get the turbulent properties values at an inlet boundary * \param[in] val_index - Index corresponding to the inlet boundary. diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 12c7e5eba0f2..35abfd74c6de 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -1961,6 +1961,20 @@ static const MapType Inlet_Map = { MakePair("PRESSURE_INLET", INLET_TYPE::PRESSURE_INLET) }; + +/*! + * \brief Types species wall boundary treatments + */ +enum class WALL_SPECIES_TYPE { + FLUX, /*!< \brief User specifies total pressure, total temperature, and flow direction. */ + VALUE, /*!< \brief User specifies density and velocity (mass flow). */ +}; + +static const MapType Wall_Species_Map = { + MakePair("FLUX", WALL_SPECIES_TYPE::FLUX) + MakePair("VALUE", WALL_SPECIES_TYPE::VALUE) +}; + /*! * \brief Types outlet boundary treatments */ diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 5fb7220e94e4..7561d1bcacd7 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -495,6 +495,30 @@ void CConfig::addInletSpeciesOption(const string& name, unsigned short & nMarker option_map.insert(pair(name, val)); } +void CConfig::addWallSpeciesOption(const string& name, unsigned short & nMarker_Wall_Species, + string * & Marker_Wall_Species, su2double** & wall_species_val, + unsigned short & nSpecies_per_Wall) { + assert(option_map.find(name) == option_map.end()); + all_options.insert(pair(name, true)); + + COptionBase* val = new COptionStringValuesList(name, nMarker_Wall_Species, Marker_Wall_Species, + wall_species_val, nSpecies_per_Wall); + option_map.insert(pair(name, val)); +} + +void CConfig::addWallSpeciesType(const string& name, unsigned short & nMarker_Wall_Species, + //string * & Marker_Wall_Species, WALL_SPECIES_TYPE** & wall_species_type, + string * & Marker_Wall_Species, unsigned short** & wall_species_type, + unsigned short & nSpecies_per_Wall) { + assert(option_map.find(name) == option_map.end()); + all_options.insert(pair(name, true)); + + //COptionBase* val = new COptionStringValuesList(name, nMarker_Wall_Species, Marker_Wall_Species, + COptionBase* val = new COptionStringValuesList(name, nMarker_Wall_Species, Marker_Wall_Species, + wall_species_type, nSpecies_per_Wall); + option_map.insert(pair(name, val)); +} + void CConfig::addInletTurbOption(const string& name, unsigned short& nMarker_Inlet_Turb, string*& Marker_Inlet_Turb, su2double**& Turb_Properties_val, unsigned short& nTurb_Properties) { assert(option_map.find(name) == option_map.end()); @@ -891,6 +915,7 @@ void CConfig::SetPointersNull() { Inlet_FlowDir = nullptr; Inlet_Temperature = nullptr; Inlet_Pressure = nullptr; Inlet_Velocity = nullptr; Outlet_Pressure = nullptr; Inlet_SpeciesVal = nullptr; Inlet_TurbVal = nullptr; + Wall_SpeciesVal = nullptr; /*--- Engine Boundary Condition settings ---*/ @@ -982,6 +1007,8 @@ void CConfig::SetPointersNull() { Kind_Inc_Inlet = nullptr; Kind_Inc_Outlet = nullptr; + Wall_SpeciesType = nullptr; + Kind_ObjFunc = nullptr; Weight_ObjFunc = nullptr; @@ -1571,6 +1598,8 @@ void CConfig::SetConfig_Options() { addEnumOption("INLET_TYPE", Kind_Inlet, Inlet_Map, INLET_TYPE::TOTAL_CONDITIONS); /*!\brief INC_INLET_TYPE \n DESCRIPTION: List of inlet types for incompressible flows. List length must match number of inlet markers. Options: VELOCITY_INLET, PRESSURE_INLET, INPUT_FILE. \ingroup Config*/ addEnumListOption("INC_INLET_TYPE", nInc_Inlet, Kind_Inc_Inlet, Inlet_Map); + + addBoolOption("SPECIFIED_INLET_PROFILE", Inlet_From_File, false); /*!\brief INLET_FILENAME \n DESCRIPTION: Input file for a specified inlet profile (w/ extension) \n DEFAULT: inlet.dat \ingroup Config*/ addStringOption("INLET_FILENAME", Inlet_Filename, string("inlet.dat")); @@ -1590,6 +1619,10 @@ void CConfig::SetConfig_Options() { /*!\brief MARKER_INLET_SPECIES \n DESCRIPTION: Inlet Species boundary marker(s) with the following format Inlet Species: (inlet_marker, Species1, Species2, ..., SpeciesN-1, inlet_marker2, Species1, Species2, ...) */ addInletSpeciesOption("MARKER_INLET_SPECIES",nMarker_Inlet_Species, Marker_Inlet_Species, Inlet_SpeciesVal, nSpecies_per_Inlet); + addWallSpeciesOption("MARKER_WALL_SPECIES" ,nMarker_Wall_Species , Marker_Wall_Species , Wall_SpeciesVal , nSpecies_per_Wall); + addWallSpeciesType("WALL_SPECIES_TYPE" ,nMarker_Wall_Species , Marker_Wall_Species , Wall_SpeciesType , nSpecies_per_Wall); + + /*!\brief MARKER_INLET_TURBULENT \n DESCRIPTION: Inlet Turbulence boundary marker(s) with the following format Inlet Turbulent: (inlet_marker, TurbulentIntensity1, ViscosityRatio1, inlet_marker2, TurbulentIntensity2, ViscosityRatio2, ...) */ @@ -5578,10 +5611,12 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i CURRENT_FUNCTION); // Helper function that checks scalar variable bounds, - auto checkScalarBounds = [&](su2double scalar, const string& name, su2double lowerBound, su2double upperBound) { - if (scalar < lowerBound || scalar > upperBound) - SU2_MPI::Error(string("Variable: ") + name + string(", is out of bounds."), CURRENT_FUNCTION); - }; + +cout << "Note: we do not check boudns for scalars anymore." << endl; +// auto checkScalarBounds = [&](su2double scalar, const string& name, su2double lowerBound, su2double upperBound) { +// if (scalar < lowerBound || scalar > upperBound) +// SU2_MPI::Error(string("Variable: ") + name + string(", is out of bounds."), CURRENT_FUNCTION); +// }; /*--- Some options have to provide as many entries as there are additional species equations. ---*/ /*--- Fill a vector with the entires and then check if each element is equal to the first one. ---*/ @@ -5603,23 +5638,24 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i /*--- Check whether some variables (or their sums) are in physical bounds. [0,1] for species related quantities. ---*/ /*--- Note, only for species transport, not for flamelet model ---*/ - if (Kind_Species_Model == SPECIES_MODEL::SPECIES_TRANSPORT) { - su2double Species_Init_Sum = 0.0; - for (unsigned short iSpecies = 0; iSpecies < nSpecies; iSpecies++) { - checkScalarBounds(Species_Init[iSpecies], "SPECIES_INIT individual", 0.0, 1.0); - Species_Init_Sum += Species_Init[iSpecies]; - } - checkScalarBounds(Species_Init_Sum, "SPECIES_INIT sum", 0.0, 1.0); - - for (iMarker = 0; iMarker < nMarker_Inlet_Species; iMarker++) { - su2double Inlet_SpeciesVal_Sum = 0.0; - for (unsigned short iSpecies = 0; iSpecies < nSpecies; iSpecies++) { - checkScalarBounds(Inlet_SpeciesVal[iMarker][iSpecies], "MARKER_INLET_SPECIES individual", 0.0, 1.0); - Inlet_SpeciesVal_Sum += Inlet_SpeciesVal[iMarker][iSpecies]; - } - checkScalarBounds(Inlet_SpeciesVal_Sum, "MARKER_INLET_SPECIES sum", 0.0, 1.0); - } - } +cout << "warning: no bounds checked for species" << endl; + // if (Kind_Species_Model == SPECIES_MODEL::SPECIES_TRANSPORT) { + // su2double Species_Init_Sum = 0.0; + // for (unsigned short iSpecies = 0; iSpecies < nSpecies; iSpecies++) { + // checkScalarBounds(Species_Init[iSpecies], "SPECIES_INIT individual", 0.0, 1.0); + // Species_Init_Sum += Species_Init[iSpecies]; + // } + // checkScalarBounds(Species_Init_Sum, "SPECIES_INIT sum", 0.0, 1.0); + + // for (iMarker = 0; iMarker < nMarker_Inlet_Species; iMarker++) { + // su2double Inlet_SpeciesVal_Sum = 0.0; + // for (unsigned short iSpecies = 0; iSpecies < nSpecies; iSpecies++) { + // checkScalarBounds(Inlet_SpeciesVal[iMarker][iSpecies], "MARKER_INLET_SPECIES individual", 0.0, 1.0); + // Inlet_SpeciesVal_Sum += Inlet_SpeciesVal[iMarker][iSpecies]; + // } + // checkScalarBounds(Inlet_SpeciesVal_Sum, "MARKER_INLET_SPECIES sum", 0.0, 1.0); + // } + // } } // species transport checks @@ -5644,7 +5680,7 @@ void CConfig::SetMarkers(SU2_COMPONENT val_software) { iMarker_FarField, iMarker_SymWall, iMarker_PerBound, iMarker_NearFieldBound, iMarker_Fluid_InterfaceBound, iMarker_Inlet, iMarker_Riemann, iMarker_Giles, iMarker_Outlet, - iMarker_Smoluchowski_Maxwell, + iMarker_Smoluchowski_Maxwell, iMarker_Wall, iMarker_Isothermal,iMarker_HeatFlux,iMarker_HeatTansfer, iMarker_EngineInflow, iMarker_EngineExhaust, iMarker_Damper, iMarker_Displacement, iMarker_Load, iMarker_Internal, @@ -6206,7 +6242,7 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { unsigned short iMarker_Euler, iMarker_Custom, iMarker_FarField, iMarker_SymWall, iMarker_PerBound, iMarker_NearFieldBound, - iMarker_Fluid_InterfaceBound, iMarker_Inlet, iMarker_Riemann, + iMarker_Fluid_InterfaceBound, iMarker_Inlet, iMarker_Riemann, iMarker_Wall, iMarker_Deform_Mesh, iMarker_Deform_Mesh_Sym_Plane, iMarker_Fluid_Load, iMarker_Smoluchowski_Maxwell, iWall_Catalytic, iMarker_Giles, iMarker_Outlet, iMarker_Isothermal, iMarker_HeatFlux, iMarker_HeatTransfer, @@ -7537,7 +7573,14 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { } BoundaryTable.PrintFooter(); } - + if (nMarker_Wall_Species != 0) { + BoundaryTable << "Species Wall boundary"; + for (iMarker_Wall = 0; iMarker_Wall < nMarker_Wall_Species; iMarker_Wall++) { + BoundaryTable << Marker_Wall_Species[iMarker_Wall]; + if (iMarker_Wall < nMarker_Wall_Species-1) BoundaryTable << " "; + } + BoundaryTable.PrintFooter(); + } if (nMarker_Riemann != 0) { BoundaryTable << "Riemann boundary"; for (iMarker_Riemann = 0; iMarker_Riemann < nMarker_Riemann; iMarker_Riemann++) { @@ -9028,6 +9071,7 @@ su2double CConfig::GetExhaust_Pressure_Target(const string& val_marker) const { return Exhaust_Pressure_Target[iMarker_EngineExhaust]; } + INLET_TYPE CConfig::GetKind_Inc_Inlet(const string& val_marker) const { unsigned short iMarker_Inlet; for (iMarker_Inlet = 0; iMarker_Inlet < nMarker_Inlet; iMarker_Inlet++) @@ -9035,6 +9079,15 @@ INLET_TYPE CConfig::GetKind_Inc_Inlet(const string& val_marker) const { return Kind_Inc_Inlet[iMarker_Inlet]; } + +//WALL_SPECIES_TYPE* CConfig::GetKind_Wall_Species(const string& val_marker) const { +// unsigned short * CConfig::GetKind_Wall_Species(const string& val_marker) const { +// unsigned short iMarker_Wall_Species; +// for (iMarker_Wall_Species = 0; iMarker_Wall_Species < nMarker_Wall_Species; iMarker_Wall_Species++) +// if (Marker_Wall_Species[iMarker_Wall_Species] == val_marker) break; +// return Wall_SpeciesType[iMarker_Wall_Species]; +// } + INC_OUTLET_TYPE CConfig::GetKind_Inc_Outlet(const string& val_marker) const { unsigned short iMarker_Outlet; for (iMarker_Outlet = 0; iMarker_Outlet < nMarker_Outlet; iMarker_Outlet++) @@ -9098,6 +9151,20 @@ const su2double* CConfig::GetInlet_SpeciesVal(const string& val_marker) const { return Inlet_SpeciesVal[iMarker_Inlet_Species]; } +const su2double* CConfig::GetWall_SpeciesVal(const string& val_marker) const { + unsigned short iMarker_Wall_Species; + for (iMarker_Wall_Species = 0; iMarker_Wall_Species < nMarker_Wall_Species; iMarker_Wall_Species++) + if (Marker_Wall_Species[iMarker_Wall_Species] == val_marker) break; + return Wall_SpeciesVal[iMarker_Wall_Species]; +} +//const WALL_SPECIES_TYPE* CConfig::GetWall_SpeciesType(const string& val_marker) const { +const unsigned short* CConfig::GetWall_SpeciesType(const string& val_marker) const { + unsigned short iMarker_Wall_Species; + for (iMarker_Wall_Species = 0; iMarker_Wall_Species < nMarker_Wall_Species; iMarker_Wall_Species++) + if (Marker_Wall_Species[iMarker_Wall_Species] == val_marker) break; + return Wall_SpeciesType[iMarker_Wall_Species]; +} + const su2double* CConfig::GetInlet_TurbVal(const string& val_marker) const { /*--- If Turbulent Inlet is not provided for the marker, return free stream values. ---*/ for (auto iMarker = 0u; iMarker < nMarker_Inlet_Turb; iMarker++) { diff --git a/SU2_CFD/include/solvers/CSpeciesSolver.hpp b/SU2_CFD/include/solvers/CSpeciesSolver.hpp index 47829debdae6..b324c6d70bf6 100644 --- a/SU2_CFD/include/solvers/CSpeciesSolver.hpp +++ b/SU2_CFD/include/solvers/CSpeciesSolver.hpp @@ -104,6 +104,27 @@ class CSpeciesSolver : public CScalarSolver { */ void BC_Inlet(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) override; + + + /*! + * \brief Impose the Navier-Stokes wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Isothermal_Wall(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, + CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) override; + + /*! + * \brief Generic implementation of the isothermal wall also covering CHT cases, + * for which the wall temperature is given by GetConjugateHeatVariable. + */ + void BC_Isothermal_Wall_Generic(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, + CNumerics* visc_numerics, CConfig* config, unsigned short val_marker, + bool cht_mode = false); /*! * \brief Store of a set of provided inlet profile values at a vertex. diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index 75c7f51b1eff..f62408bf6e87 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -334,9 +334,12 @@ void CSpeciesSolver::BC_Inlet(CGeometry* geometry, CSolver** solver_container, C CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) { const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); - + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); /*--- Loop over all the vertices on this boundary marker ---*/ + const su2double* InletSpecies = config->GetInlet_SpeciesVal(Marker_Tag) ; + cout << Marker_Tag << ", inlet = " << InletSpecies[0] << " " << InletSpecies[1] << endl; + SU2_OMP_FOR_STAT(OMP_MIN_SIZE) for (auto iVertex = 0u; iVertex < geometry->nVertex[val_marker]; iVertex++) { auto iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); @@ -441,6 +444,47 @@ void CSpeciesSolver::SetUniformInlet(const CConfig* config, unsigned short iMark } } + +void CSpeciesSolver::BC_Isothermal_Wall(CGeometry* geometry, CSolver** solver_container, + CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, + unsigned short val_marker) { + BC_Isothermal_Wall_Generic(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); +} + +void CSpeciesSolver::BC_Isothermal_Wall_Generic(CGeometry* geometry, CSolver** solver_container, + CNumerics* conv_numerics, CNumerics* visc_numerics, + CConfig* config, unsigned short val_marker, bool cht_mode) { + const bool implicit = config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT; + + + string Marker_Tag = config->GetMarker_All_TagBound(val_marker); + /*--- Loop over all the vertices on this boundary marker ---*/ + const su2double* InletSpecies = config->GetInlet_SpeciesVal("inlet") ; + cout << "inlet = " << InletSpecies[0] << " " << InletSpecies[1] << endl; + + const su2double* WallSpecies = config->GetWall_SpeciesVal("wall_side") ; + cout << "wall = " << WallSpecies[0] <<" " << WallSpecies[1] << endl; + + const short unsigned int* wallspeciestype = config->GetWall_SpeciesType(Marker_Tag); + cout << "type = "<<(wallspeciestype[0]) << " " << wallspeciestype[1] << endl; + // switch (config->GetWall_SpeciesType(Marker_Tag)[0]) { + // /*--- incompressible conditions ---*/ + + // //case WALL_SPECIES_TYPE::FLUX: + // case 0: + // cout << "flux" << endl; + // break; + // //case WALL_SPECIES_TYPE::VALUE: + // case 1: + // cout << "value" << endl; + // break; + // default: + // break; + // } +} + + + void CSpeciesSolver::BC_Outlet(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) { diff --git a/TestCases/py_wrapper/tfc_heatloss/psi.cfg b/TestCases/py_wrapper/tfc_heatloss/psi.cfg deleted file mode 100644 index 0498fb6b65bd..000000000000 --- a/TestCases/py_wrapper/tfc_heatloss/psi.cfg +++ /dev/null @@ -1,165 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% SU2 configuration file % -% Case description: Turbulent premixed high pressure combustion chamber. % -% Author: N. Beishuizen % -% Institution: Bosch Thermotechniek B.V. % -% Date: 2025/01/01 % -% File Version 8.0 "Harrier" % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% -% -SOLVER= INC_RANS -KIND_TURB_MODEL= SST -SST_OPTIONS= V1994m - -RESTART_SOL= NO - -MGLEVEL= 0 -% - -% temperature and density -FREESTREAM_TEMPERATURE = 673 -FREESTREAM_DENSITY = 2.55 -% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% -% -%INC_DENSITY_MODEL= CONSTANT -INC_DENSITY_MODEL= VARIABLE -INC_DENSITY_INIT= 2.55 -% -INC_VELOCITY_INIT= (40.00, 0.0, 0.0 ) -% -INC_ENERGY_EQUATION= YES -INC_TEMPERATURE_INIT= 673.0 -% -INC_NONDIM= DIMENSIONAL -% -% -------------------- FLUID PROPERTIES ------------------------------------- % -% -%FLUID_MODEL= CONSTANT_DENSITY -FLUID_MODEL= INC_IDEAL_GAS -% -CONDUCTIVITY_MODEL= CONSTANT_CONDUCTIVITY -THERMAL_CONDUCTIVITY_CONSTANT= 0.0357 -% -PRANDTL_LAM= 0.72 -TURBULENT_CONDUCTIVITY_MODEL= NONE -PRANDTL_TURB= 0.90 -% -VISCOSITY_MODEL= SUTHERLAND -MU_CONSTANT= 1.716E-5 -MU_REF = 1.716e-5 -MU_T_REF= 273.15 -SUTHERLAND_CONSTANT = 110.4 - -SPECIFIC_HEAT_CP = 1150 -% -% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% -% -MARKER_HEATFLUX= ( wall_top, 0.0,wall_side,0.0,wall_pipe,0.0, wall_out, 0.0 ) - -% note, case is axisymmetric -MARKER_SYM= ( symmetry ) -AXISYMMETRIC= YES -% -SPECIFIED_INLET_PROFILE= NO -INLET_MATCHING_TOLERANCE=1e-4 -INLET_FILENAME= inlet.dat -%INLET_INTERPOLATION_FUNCTION= LINEAR_1D -INC_INLET_TYPE= VELOCITY_INLET -INC_INLET_DAMPING= 0.01 -MARKER_INLET= ( inlet, 673, 40.0, 1.0, 0.0, 0.0) -MARKER_INLET_TURBULENT = (inlet, 0.10, 15) -MARKER_INLET_SPECIES= (inlet, 0.0) -% -INC_OUTLET_TYPE= PRESSURE_OUTLET -INC_OUTLET_DAMPING= 0.01 -MARKER_OUTLET= ( outlet, 0.0 ) -% -% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% -% -NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -% -CFL_NUMBER= 1.0 -CFL_REDUCTION_SPECIES= 1.0 -CFL_REDUCTION_TURB= 1.0 -% -ITER= 1 -% -% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% -% -LINEAR_SOLVER= FGMRES -LINEAR_SOLVER_PREC= ILU -LINEAR_SOLVER_ERROR= 1E-8 -LINEAR_SOLVER_ITER= 10 - -% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% -% -CONV_NUM_METHOD_FLOW= FDS -MUSCL_FLOW= NO -SLOPE_LIMITER_FLOW = NONE -TIME_DISCRE_FLOW= EULER_IMPLICIT -% -% -------------------- SCALAR TRANSPORT ---------------------------------------% -% -KIND_SCALAR_MODEL= SPECIES_TRANSPORT -DIFFUSIVITY_MODEL= CONSTANT_DIFFUSIVITY -SCHMIDT_NUMBER_LAMINAR= 1.0 -DIFFUSIVITY_CONSTANT= 7.56e-5 - -% according to the paper -SCHMIDT_NUMBER_TURBULENT= 0.7 - -% -CONV_NUM_METHOD_SPECIES= BOUNDED_SCALAR -MUSCL_SPECIES= NO -SLOPE_LIMITER_SPECIES = NONE -% -TIME_DISCRE_SPECIES= EULER_IMPLICIT -% -SPECIES_INIT= 0.0 -SPECIES_CLIPPING= YES -SPECIES_CLIPPING_MIN= 0.0 -SPECIES_CLIPPING_MAX= 1.0 -% -% -------------------- TURBULENT TRANSPORT ---------------------------------------% -% -CONV_NUM_METHOD_TURB= BOUNDED_SCALAR -MUSCL_TURB= NO - -% -% --------------------------- CONVERGENCE PARAMETERS --------------------------% -% -CONV_FIELD= RMS_PRESSURE, RMS_VELOCITY-X, RMS_VELOCITY-Y, RMS_TKE, RMS_SPECIES -CONV_RESIDUAL_MINVAL= -18 -CONV_STARTITER= 10 -% -% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% -% -%MESH_FILENAME= psi_coarse.su2 -MESH_FILENAME= psi.su2 -%MESH_FILENAME= psi_fine.su2 -% -SCREEN_OUTPUT= INNER_ITER WALL_TIME \ - RMS_PRESSURE RMS_VELOCITY-X RMS_VELOCITY-Y RMS_TKE RMS_DISSIPATION RMS_SPECIES_0 \ - LINSOL_ITER LINSOL_RESIDUAL \ - LINSOL_ITER_TURB LINSOL_RESIDUAL_TURB \ - LINSOL_ITER_SPECIES LINSOL_RESIDUAL_SPECIES -SCREEN_WRT_FREQ_INNER= 1 -% -HISTORY_OUTPUT= ITER RMS_RES LINSOL SPECIES_COEFF SPECIES_COEFF_SURF -CONV_FILENAME= history -MARKER_ANALYZE= gas_inlet, air_axial_inlet, outlet -MARKER_ANALYZE_AVERAGE= AREA -% -OUTPUT_FILES= RESTART_ASCII, PARAVIEW_MULTIBLOCK -VOLUME_OUTPUT= RESIDUAL, PRIMITIVE -OUTPUT_WRT_FREQ= 100 -% -READ_BINARY_RESTART= NO -RESTART_FILENAME= restart -SOLUTION_FILENAME= solution -% -WRT_PERFORMANCE= YES diff --git a/TestCases/py_wrapper/tfc_heatloss/run.py b/TestCases/py_wrapper/tfc_heatloss/run.py deleted file mode 100644 index 855ea373d5da..000000000000 --- a/TestCases/py_wrapper/tfc_heatloss/run.py +++ /dev/null @@ -1,274 +0,0 @@ -#!/usr/bin/env python - -## \file run.py -# \brief turbulent premixed dump combustor simulation (PSI flame) -# phi=0.5, methane-air, U=40 m/s -# \version 8.1.0 "Harrier" -# -# SU2 Project Website: https://su2code.github.io -# -# The SU2 Project is maintained by the SU2 Foundation -# (http://su2foundation.org) -# -# Copyright 2012-2024, 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 . - -import sys -import pysu2 -from mpi4py import MPI -import numpy as np -#from mpi4py import MPI - -# unburnt temperature of the propane-air mixture -# flame temperature of the methane-air mixture (phi=0.5, P=5) -Tf = 1777 - -Tu = 673.0 -Pu = 5.0 -phi = 0.5 -# unburnt density at P=5 -rho_u = 2.52 -# unburnt thermal conductivity of methane-air at phi=0.5 (P=5) -k_u = 0.0523 -# unburnt heat capacity of methane-air at phi=0.5 (P=1) -cp_u = 1311.0 - -# P = rho*R*T -# 5 = 2.55 * R * 673 -# R = 0.0029 - -# ################################################################## # -# create a function for the initial progress variable # -# ################################################################## # -def initC(coord): - x = coord[0] - #y = coord[1] - #z = coord[2] - #print("x,y = ",x," ",y) - # location where the flame should be - flame_x = 0.012 - if (x < flame_x): - C = 0.0 - else: - C = 1.0 - - return C - -# ################################################################## # -# loop over all vertices and set the species progress variable # -# ################################################################## # -def SetInitialSpecies(SU2Driver): - allCoords = SU2Driver.Coordinates() - iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] - print("index of species solver = ",iSPECIESSOLVER) - nVarsSpecies = SU2Driver.GetNumberSolverVars(iSPECIESSOLVER) - print("number of species solver variables:",nVarsSpecies) - for iPoint in range(SU2Driver.GetNumberNodes() - SU2Driver.GetNumberHaloNodes()): - coord = allCoords.Get(iPoint) - C = initC(coord) - # now update the initial condition - SU2Driver.SetSolutionVector(iSPECIESSOLVER, iPoint, [C]) - -def SetInitialVelocity(SU2Driver): - allCoords = SU2Driver.Coordinates() - iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] - print("index of FLOW solver = ",iFLOWSOLVER) - nVarsFlow = SU2Driver.GetNumberSolverVars(iFLOWSOLVER) - print("number of flow solver variables:",nVarsFlow) - for iPoint in range(SU2Driver.GetNumberNodes() - SU2Driver.GetNumberHaloNodes()): - coord = allCoords.Get(iPoint) - C = initC(coord) - # now update the initial condition - SU2Driver.SetSolutionVector(iFLOWSOLVER, iPoint, [C]) - -def update_temperature(SU2Driver, iPoint): - # first, get the progress variable - iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] - # returns a list - C = SU2Driver.GetSolutionVector(iSPECIESSOLVER, iPoint) - T = Tu*(1-C[0]) + Tf*C[0] - iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] - solvar = list(SU2Driver.GetSolutionVector(iFLOWSOLVER, iPoint)) - # the list with names - solindex = getsolvar(SU2Driver) - primindex = SU2Driver.GetPrimitiveIndices() - iTEMP = solindex.get("TEMPERATURE") - solvar[iTEMP] = T - SU2Driver.SetSolutionVector(iFLOWSOLVER, iPoint, solvar) - - -def zimont(SU2Driver, iPoint): - iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] - iSSTSOLVER = SU2Driver.GetSolverIndices()['SST'] - iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] - primindex = SU2Driver.GetPrimitiveIndices() - primvar = list(SU2Driver.GetPrimitiveVector(iFLOWSOLVER, iPoint)) - - iDENSITY = primindex.get("DENSITY") - iMU = primindex.get("LAMINAR_VISCOSITY") - - # laminar burning velocity of methane-air at phi=0.5, P=5 - Slu = 0.232 - - - rho = primvar[iDENSITY] - mu = primvar[iMU] - nu=mu/rho - tke, dissipation = SU2Driver.GetSolutionVector(iSSTSOLVER,iPoint) - gradc = SU2Driver.GetGradient(iSPECIESSOLVER,iPoint,0) - # Turbulent Flamespeed Closure with Dinkelacker correction - up = np.sqrt((2.0/3.0) * tke ) - lt = (0.09**0.75) * (tke**1.5) / dissipation - Re = up*lt/nu - Le = 1.0 - Ut = Slu * (1.0 + (0.46/Le) * np.power(Re,0.25) * np.power(up/Slu,0.3) * np.power(Pu,0.2) ) - norm_gradc = np.sqrt(gradc[0]*gradc[0] + gradc[1]*gradc[1]) - #if (norm_gradc > 1.): - # print(tke," ",rho_u," Ut=",Ut," , |grad(c)| = ",norm_gradc, " ",gradc[0]," ",gradc[1]) - Sc = rho_u * Ut * norm_gradc - - return Sc - -def getsolvar(SU2Driver): - primindex = SU2Driver.GetPrimitiveIndices() - iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] - nVars = SU2Driver.GetNumberSolverVars(iFLOWSOLVER) - varindex = primindex.copy() - for prim in varindex.copy(): - if varindex[prim] >=nVars: - del varindex[prim] - varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) - return varindex - - -def main(): - comm = MPI.COMM_WORLD - rank = comm.Get_rank() - - # Initialize the primal driver of SU2, this includes solver preprocessing. - try: - driver = pysu2.CSinglezoneDriver('psi.cfg', 1, comm) - except TypeError as exception: - print('A TypeError occured in pysu2.CSinglezoneDriver : ', exception) - raise - - if rank == 0: - print("\n------------------------------ Begin Solver -----------------------------") - sys.stdout.flush() - - nDim = driver.GetNumberDimensions() - print("Dimensions of the problem = ",nDim) - - # index to the flow solver - # C.FLOW - # INC.FLOW - # HEAT - # FLAMELET - # SPECIES - # SA - # SST - iFLOWSOLVER = driver.GetSolverIndices()['INC.FLOW'] - print("index of flow solver = ",iFLOWSOLVER) - iSPECIESSOLVER = driver.GetSolverIndices()['SPECIES'] - print("index of species solver = ",iSPECIESSOLVER) - iSSTSOLVER = driver.GetSolverIndices()['SST'] - print("index of turbulence solver = ",iSSTSOLVER) - - - # all the indices and the map to the names of the primitives - primindex = driver.GetPrimitiveIndices() - print("indices of primitives=",primindex) - print("number of primitives:",len(primindex)) - - nElem = driver.GetNumberElements() - print("number of elements:",nElem) - - nVars = driver.GetNumberSolverVars(iFLOWSOLVER) - print("number of flow solver variables:",nVars) - - nVarsSpecies = driver.GetNumberSolverVars(iSPECIESSOLVER) - print("number of species solver variables:",nVarsSpecies) - nVarsTurb = driver.GetNumberSolverVars(iSSTSOLVER) - print("number of turbulence solver variables:",nVarsTurb) - - varindex = primindex.copy() - for prim in varindex.copy(): - if varindex[prim] >=nVars: - del varindex[prim] - varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) - - -# it is possible to get the solver type by doing -# iFLOWSOLVER = driver.GetSolverIndices()['INC.FLOW'] -# with the solver type we then get the solver variables using: - -# nVars = driver.GetNumberSolverVars(iFLOWSOLVER) -# and the solver variable names: -# print("solver variable names:",varindex) - -# we can overwrite the solution using: -# driver.SetSolutionVector(iSolver, iPoint, solutionVector) -# - - #print("solver variable names:",varindex) - iDENSITY = primindex.get("DENSITY") - #print("index of density = ",iDENSITY) - - index_Vel = varindex.get("VELOCITY_X") - #print("index of velocity = ",index_Vel) - - custom_source_vector = [0.0 for i in range(nVars)] - #print("custom source vector = ", custom_source_vector) - - #print("max. number of inner iterations: ",driver.GetNumberInnerIter()); - #print("max nr of outer iterations: ",driver.GetNumberOuterIter()); - with open('psi.cfg') as f: - if 'RESTART_SOL= YES' in f.read(): - print("restarting from file") - else: - # We can set an initial condition by calling this function: - print("Start calling SetInitialSpecies") - SetInitialSpecies(driver) - print("End calling SetInitialSpecies") - - # super important to actually push the commands. - sys.stdout.flush() - - # run N iterations - for inner_iter in range(5): - - driver.Preprocess(inner_iter) - driver.Run() - - # set the source term, per point - for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): - # add source term: - # default TFC of Zimont: rho*Sc = rho_u * U_t * grad(c) - S = [zimont(driver,i_node)] - driver.SetPointCustomSource(iSPECIESSOLVER, i_node,S) - # at this point we also need to update the temperature based on the progress variable: - # set the temperature to T = c*Tf + (1-c)*Tu - update_temperature(driver, i_node) - - driver.Postprocess() - driver.Update() - #driver.Monitor(inner_iter) - driver.Output(inner_iter) - - # Finalize the solver and exit cleanly. - driver.Finalize() - -if __name__ == '__main__': - main() diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py index 855ea373d5da..9d86aa4df021 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/run.py +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -29,20 +29,27 @@ import pysu2 from mpi4py import MPI import numpy as np -#from mpi4py import MPI -# unburnt temperature of the propane-air mixture +# Import mpi4py for parallel run +if options.with_MPI == True: + from mpi4py import MPI + comm = MPI.COMM_WORLD + rank = comm.Get_rank() +else: + comm = 0 + # flame temperature of the methane-air mixture (phi=0.5, P=5) Tf = 1777 +# unburnt temperature of the propane-air mixture (phi=0.5, P=5) Tu = 673.0 Pu = 5.0 phi = 0.5 # unburnt density at P=5 rho_u = 2.52 -# unburnt thermal conductivity of methane-air at phi=0.5 (P=5) +# unburnt thermal conductivity of methane-air at phi=0.5 (phi=0.5, P=5) k_u = 0.0523 -# unburnt heat capacity of methane-air at phi=0.5 (P=1) +# unburnt heat capacity of methane-air at phi=0.5 (P=5) cp_u = 1311.0 # P = rho*R*T @@ -50,13 +57,12 @@ # R = 0.0029 # ################################################################## # -# create a function for the initial progress variable # +# create a function for the initial progress variable c # # ################################################################## # def initC(coord): x = coord[0] #y = coord[1] #z = coord[2] - #print("x,y = ",x," ",y) # location where the flame should be flame_x = 0.012 if (x < flame_x): @@ -67,7 +73,7 @@ def initC(coord): return C # ################################################################## # -# loop over all vertices and set the species progress variable # +# loop over all vertices and set the species progress variable c # # ################################################################## # def SetInitialSpecies(SU2Driver): allCoords = SU2Driver.Coordinates() @@ -78,25 +84,16 @@ def SetInitialSpecies(SU2Driver): for iPoint in range(SU2Driver.GetNumberNodes() - SU2Driver.GetNumberHaloNodes()): coord = allCoords.Get(iPoint) C = initC(coord) - # now update the initial condition + # now update the initial condition for the species SU2Driver.SetSolutionVector(iSPECIESSOLVER, iPoint, [C]) -def SetInitialVelocity(SU2Driver): - allCoords = SU2Driver.Coordinates() - iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] - print("index of FLOW solver = ",iFLOWSOLVER) - nVarsFlow = SU2Driver.GetNumberSolverVars(iFLOWSOLVER) - print("number of flow solver variables:",nVarsFlow) - for iPoint in range(SU2Driver.GetNumberNodes() - SU2Driver.GetNumberHaloNodes()): - coord = allCoords.Get(iPoint) - C = initC(coord) - # now update the initial condition - SU2Driver.SetSolutionVector(iFLOWSOLVER, iPoint, [C]) - +# ################################################################## # +# Temperature is an algebraic function of c +# ################################################################## # def update_temperature(SU2Driver, iPoint): # first, get the progress variable iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] - # returns a list + # Note: returns a list C = SU2Driver.GetSolutionVector(iSPECIESSOLVER, iPoint) T = Tu*(1-C[0]) + Tf*C[0] iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] @@ -109,10 +106,18 @@ def update_temperature(SU2Driver, iPoint): SU2Driver.SetSolutionVector(iFLOWSOLVER, iPoint, solvar) +# ################################################################## # +# Source term according to Zimont +# ################################################################## # def zimont(SU2Driver, iPoint): - iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] + iSSTSOLVER = SU2Driver.GetSolverIndices()['SST'] + tke, dissipation = SU2Driver.GetSolutionVector(iSSTSOLVER,iPoint) + iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] + gradc = SU2Driver.GetGradient(iSPECIESSOLVER,iPoint,0) + + iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] primindex = SU2Driver.GetPrimitiveIndices() primvar = list(SU2Driver.GetPrimitiveVector(iFLOWSOLVER, iPoint)) @@ -122,12 +127,9 @@ def zimont(SU2Driver, iPoint): # laminar burning velocity of methane-air at phi=0.5, P=5 Slu = 0.232 - rho = primvar[iDENSITY] mu = primvar[iMU] nu=mu/rho - tke, dissipation = SU2Driver.GetSolutionVector(iSSTSOLVER,iPoint) - gradc = SU2Driver.GetGradient(iSPECIESSOLVER,iPoint,0) # Turbulent Flamespeed Closure with Dinkelacker correction up = np.sqrt((2.0/3.0) * tke ) lt = (0.09**0.75) * (tke**1.5) / dissipation @@ -135,12 +137,13 @@ def zimont(SU2Driver, iPoint): Le = 1.0 Ut = Slu * (1.0 + (0.46/Le) * np.power(Re,0.25) * np.power(up/Slu,0.3) * np.power(Pu,0.2) ) norm_gradc = np.sqrt(gradc[0]*gradc[0] + gradc[1]*gradc[1]) - #if (norm_gradc > 1.): - # print(tke," ",rho_u," Ut=",Ut," , |grad(c)| = ",norm_gradc, " ",gradc[0]," ",gradc[1]) Sc = rho_u * Ut * norm_gradc return Sc +# ################################################################## # +# Get the list of solver variable names +# ################################################################## # def getsolvar(SU2Driver): primindex = SU2Driver.GetPrimitiveIndices() iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] @@ -152,10 +155,10 @@ def getsolvar(SU2Driver): varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) return varindex - +# ################################################################## # +# Main routine +# ################################################################## # def main(): - comm = MPI.COMM_WORLD - rank = comm.Get_rank() # Initialize the primal driver of SU2, this includes solver preprocessing. try: @@ -186,7 +189,6 @@ def main(): iSSTSOLVER = driver.GetSolverIndices()['SST'] print("index of turbulence solver = ",iSSTSOLVER) - # all the indices and the map to the names of the primitives primindex = driver.GetPrimitiveIndices() print("indices of primitives=",primindex) @@ -209,31 +211,7 @@ def main(): del varindex[prim] varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) - -# it is possible to get the solver type by doing -# iFLOWSOLVER = driver.GetSolverIndices()['INC.FLOW'] -# with the solver type we then get the solver variables using: - -# nVars = driver.GetNumberSolverVars(iFLOWSOLVER) -# and the solver variable names: -# print("solver variable names:",varindex) - -# we can overwrite the solution using: -# driver.SetSolutionVector(iSolver, iPoint, solutionVector) -# - - #print("solver variable names:",varindex) - iDENSITY = primindex.get("DENSITY") - #print("index of density = ",iDENSITY) - - index_Vel = varindex.get("VELOCITY_X") - #print("index of velocity = ",index_Vel) - - custom_source_vector = [0.0 for i in range(nVars)] - #print("custom source vector = ", custom_source_vector) - - #print("max. number of inner iterations: ",driver.GetNumberInnerIter()); - #print("max nr of outer iterations: ",driver.GetNumberOuterIter()); + # ### Check if we do a restart or not. ### with open('psi.cfg') as f: if 'RESTART_SOL= YES' in f.read(): print("restarting from file") @@ -252,19 +230,23 @@ def main(): driver.Preprocess(inner_iter) driver.Run() - # set the source term, per point + # set the source term, per point, for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): # add source term: # default TFC of Zimont: rho*Sc = rho_u * U_t * grad(c) S = [zimont(driver,i_node)] driver.SetPointCustomSource(iSPECIESSOLVER, i_node,S) - # at this point we also need to update the temperature based on the progress variable: + + # for the update of temperature, we need to update also the halo nodes + for i_node in range(driver.GetNumberNodes(): # set the temperature to T = c*Tf + (1-c)*Tu update_temperature(driver, i_node) driver.Postprocess() driver.Update() - #driver.Monitor(inner_iter) + # Monitor the solver and output solution to file if required + driver.Monitor(inner_iter) + # Output the solution to file driver.Output(inner_iter) # Finalize the solver and exit cleanly. From 98c7a4c4b5cc86d07aff73222046ffbfcc385cf6 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Thu, 26 Jun 2025 12:05:00 +0200 Subject: [PATCH 28/61] add testcase --- Common/src/CConfig.cpp | 2 +- SU2_CFD/include/solvers/CSpeciesSolver.hpp | 12 + SU2_CFD/src/solvers/CSpeciesSolver.cpp | 6 + TestCases/py_wrapper/psi.cfg | 172 ++++++++++++++ TestCases/py_wrapper/run.py | 256 +++++++++++++++++++++ 5 files changed, 447 insertions(+), 1 deletion(-) create mode 100644 TestCases/py_wrapper/psi.cfg create mode 100755 TestCases/py_wrapper/run.py diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 7561d1bcacd7..841c83e744da 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -513,7 +513,7 @@ void CConfig::addWallSpeciesType(const string& name, unsigned short & nMarker_Wa assert(option_map.find(name) == option_map.end()); all_options.insert(pair(name, true)); - //COptionBase* val = new COptionStringValuesList(name, nMarker_Wall_Species, Marker_Wall_Species, + //COptionBase* val = new COptionStringValuesList<(unsigned short)WALL_SPECIES_TYPE*>(name, nMarker_Wall_Species, Marker_Wall_Species, COptionBase* val = new COptionStringValuesList(name, nMarker_Wall_Species, Marker_Wall_Species, wall_species_type, nSpecies_per_Wall); option_map.insert(pair(name, val)); diff --git a/SU2_CFD/include/solvers/CSpeciesSolver.hpp b/SU2_CFD/include/solvers/CSpeciesSolver.hpp index b324c6d70bf6..46244713b039 100644 --- a/SU2_CFD/include/solvers/CSpeciesSolver.hpp +++ b/SU2_CFD/include/solvers/CSpeciesSolver.hpp @@ -118,6 +118,18 @@ class CSpeciesSolver : public CScalarSolver { void BC_Isothermal_Wall(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) override; + /*! + * \brief Impose the Navier-Stokes wall boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_HeatFlux_Wall(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, + CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) override; + /*! * \brief Generic implementation of the isothermal wall also covering CHT cases, * for which the wall temperature is given by GetConjugateHeatVariable. diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index f62408bf6e87..bdc7829ff6a6 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -451,6 +451,12 @@ void CSpeciesSolver::BC_Isothermal_Wall(CGeometry* geometry, CSolver** solver_co BC_Isothermal_Wall_Generic(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); } +void CSpeciesSolver::BC_HeatFlux_Wall(CGeometry* geometry, CSolver** solver_container, + CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, + unsigned short val_marker) { + BC_Isothermal_Wall_Generic(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); +} + void CSpeciesSolver::BC_Isothermal_Wall_Generic(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, unsigned short val_marker, bool cht_mode) { diff --git a/TestCases/py_wrapper/psi.cfg b/TestCases/py_wrapper/psi.cfg new file mode 100644 index 000000000000..6c796658efae --- /dev/null +++ b/TestCases/py_wrapper/psi.cfg @@ -0,0 +1,172 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Turbulent premixed high pressure combustion chamber. % +% Author: N. Beishuizen % +% Institution: Bosch Thermotechniek B.V. % +% Date: 2025/01/01 % +% File Version 8.0 "Harrier" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= INC_RANS +KIND_TURB_MODEL= SST +SST_OPTIONS= V1994m + +RESTART_SOL= YES + +MGLEVEL= 0 +% + +% temperature and density +FREESTREAM_TEMPERATURE = 673 +FREESTREAM_DENSITY = 2.55 +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +%INC_DENSITY_MODEL= CONSTANT +INC_DENSITY_MODEL= VARIABLE +INC_DENSITY_INIT= 2.55 +% +INC_VELOCITY_INIT= (40.00, 0.0, 0.0 ) +% +INC_ENERGY_EQUATION= YES +INC_TEMPERATURE_INIT= 673.0 +% +INC_NONDIM= DIMENSIONAL +% +% -------------------- FLUID PROPERTIES ------------------------------------- % +% +FLUID_MODEL= INC_IDEAL_GAS +% +%CONDUCTIVITY_MODEL= CONSTANT_CONDUCTIVITY +CONDUCTIVITY_MODEL= CONSTANT_PRANDTL +THERMAL_CONDUCTIVITY_CONSTANT= 0.0357 +% +PRANDTL_LAM= 0.72 +TURBULENT_CONDUCTIVITY_MODEL= NONE +PRANDTL_TURB= 0.90 +% +VISCOSITY_MODEL= SUTHERLAND +MU_CONSTANT= 1.716E-5 +MU_REF = 1.716e-5 +MU_T_REF= 273.15 +SUTHERLAND_CONSTANT = 110.4 + +SPECIFIC_HEAT_CP = 1150 +% +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( wall_side, 0.0, wall_pipe, 0.0, wall_out, 0.0 ) +MARKER_ISOTHERMAL= ( wall_top, 400.0 ) + +% note, case is axisymmetric +MARKER_SYM= ( symmetry ) +AXISYMMETRIC= YES +% +SPECIFIED_INLET_PROFILE= NO +INLET_MATCHING_TOLERANCE=1e-4 +INLET_FILENAME= inlet.dat +%INLET_INTERPOLATION_FUNCTION= LINEAR_1D +INC_INLET_TYPE= VELOCITY_INLET +INC_INLET_DAMPING= 0.01 +MARKER_INLET= ( inlet, 673, 40.0, 1.0, 0.0, 0.0) +MARKER_INLET_TURBULENT = (inlet, 0.10, 15) + + +MARKER_INLET_SPECIES= (inlet, 0.0, 400.0) +%WALL_SPECIES_TYPE = wall_side, FLUX, VALUE, wall_pipe, FLUX, VALUE,wall_out, FLUX, VALUE,wall_top, FLUX, VALUE +WALL_SPECIES_TYPE = wall_side, 0 , 1 , wall_pipe, 0 , 1 ,wall_out 0 , 1 , wall_top 0 , 1 +MARKER_WALL_SPECIES= wall_side, 0.0, 300.0, wall_pipe, 0.0, 400.0, wall_out, 0.0, 500.0, wall_top, 0.0, 300.0 + +% +INC_OUTLET_TYPE= PRESSURE_OUTLET +INC_OUTLET_DAMPING= 0.01 +MARKER_OUTLET= ( outlet, 0.0 ) +% +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES +% +CFL_NUMBER= 10.0 +CFL_REDUCTION_SPECIES= 1.0 +CFL_REDUCTION_TURB= 1.0 +% +ITER= 100 +% +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1E-12 +LINEAR_SOLVER_ITER= 25 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= FDS +MUSCL_FLOW= NO +SLOPE_LIMITER_FLOW = NONE +TIME_DISCRE_FLOW= EULER_IMPLICIT +% +% -------------------- SCALAR TRANSPORT ---------------------------------------% +% +KIND_SCALAR_MODEL= SPECIES_TRANSPORT +DIFFUSIVITY_MODEL= CONSTANT_DIFFUSIVITY +SCHMIDT_NUMBER_LAMINAR= 1.0 +DIFFUSIVITY_CONSTANT= 7.56e-5 + +% according to the paper +SCHMIDT_NUMBER_TURBULENT= 0.7 + +% +CONV_NUM_METHOD_SPECIES= BOUNDED_SCALAR +MUSCL_SPECIES= NO +SLOPE_LIMITER_SPECIES = NONE +% +TIME_DISCRE_SPECIES= EULER_IMPLICIT +% +SPECIES_INIT= 0.0 0.0 +%SPECIES_CLIPPING= YES +%SPECIES_CLIPPING_MIN= 0.0 +%SPECIES_CLIPPING_MAX= 1.0 +% +% -------------------- TURBULENT TRANSPORT ---------------------------------------% +% +CONV_NUM_METHOD_TURB= BOUNDED_SCALAR +MUSCL_TURB= NO + +% +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_FIELD= RMS_PRESSURE, RMS_VELOCITY-X, RMS_VELOCITY-Y, RMS_TKE, RMS_SPECIES +CONV_RESIDUAL_MINVAL= -18 +CONV_STARTITER= 10 +% +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +%MESH_FILENAME= psi_coarse.su2 +MESH_FILENAME= psi.su2 +%MESH_FILENAME= psi_fine.su2 +% +SCREEN_OUTPUT= INNER_ITER WALL_TIME \ + RMS_TEMPERATURE RMS_PRESSURE RMS_VELOCITY-X RMS_VELOCITY-Y RMS_TKE RMS_DISSIPATION RMS_SPECIES_0 \ + LINSOL_ITER LINSOL_RESIDUAL \ + LINSOL_ITER_TURB LINSOL_RESIDUAL_TURB \ + LINSOL_ITER_SPECIES LINSOL_RESIDUAL_SPECIES +SCREEN_WRT_FREQ_INNER= 1 +% +HISTORY_OUTPUT= ITER RMS_RES LINSOL SPECIES_COEFF SPECIES_COEFF_SURF +CONV_FILENAME= history +MARKER_ANALYZE= gas_inlet, air_axial_inlet, outlet +MARKER_ANALYZE_AVERAGE= AREA +% +OUTPUT_FILES= RESTART_ASCII, PARAVIEW_MULTIBLOCK +VOLUME_OUTPUT= RESIDUAL, PRIMITIVE +OUTPUT_WRT_FREQ= 1000 +% +READ_BINARY_RESTART= NO +RESTART_FILENAME= restart +SOLUTION_FILENAME= solution +% +WRT_PERFORMANCE= YES diff --git a/TestCases/py_wrapper/run.py b/TestCases/py_wrapper/run.py new file mode 100755 index 000000000000..9d86aa4df021 --- /dev/null +++ b/TestCases/py_wrapper/run.py @@ -0,0 +1,256 @@ +#!/usr/bin/env python + +## \file run.py +# \brief turbulent premixed dump combustor simulation (PSI flame) +# phi=0.5, methane-air, U=40 m/s +# \version 8.1.0 "Harrier" +# +# SU2 Project Website: https://su2code.github.io +# +# The SU2 Project is maintained by the SU2 Foundation +# (http://su2foundation.org) +# +# Copyright 2012-2024, 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 . + +import sys +import pysu2 +from mpi4py import MPI +import numpy as np + +# Import mpi4py for parallel run +if options.with_MPI == True: + from mpi4py import MPI + comm = MPI.COMM_WORLD + rank = comm.Get_rank() +else: + comm = 0 + +# flame temperature of the methane-air mixture (phi=0.5, P=5) +Tf = 1777 + +# unburnt temperature of the propane-air mixture (phi=0.5, P=5) +Tu = 673.0 +Pu = 5.0 +phi = 0.5 +# unburnt density at P=5 +rho_u = 2.52 +# unburnt thermal conductivity of methane-air at phi=0.5 (phi=0.5, P=5) +k_u = 0.0523 +# unburnt heat capacity of methane-air at phi=0.5 (P=5) +cp_u = 1311.0 + +# P = rho*R*T +# 5 = 2.55 * R * 673 +# R = 0.0029 + +# ################################################################## # +# create a function for the initial progress variable c # +# ################################################################## # +def initC(coord): + x = coord[0] + #y = coord[1] + #z = coord[2] + # location where the flame should be + flame_x = 0.012 + if (x < flame_x): + C = 0.0 + else: + C = 1.0 + + return C + +# ################################################################## # +# loop over all vertices and set the species progress variable c # +# ################################################################## # +def SetInitialSpecies(SU2Driver): + allCoords = SU2Driver.Coordinates() + iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] + print("index of species solver = ",iSPECIESSOLVER) + nVarsSpecies = SU2Driver.GetNumberSolverVars(iSPECIESSOLVER) + print("number of species solver variables:",nVarsSpecies) + for iPoint in range(SU2Driver.GetNumberNodes() - SU2Driver.GetNumberHaloNodes()): + coord = allCoords.Get(iPoint) + C = initC(coord) + # now update the initial condition for the species + SU2Driver.SetSolutionVector(iSPECIESSOLVER, iPoint, [C]) + +# ################################################################## # +# Temperature is an algebraic function of c +# ################################################################## # +def update_temperature(SU2Driver, iPoint): + # first, get the progress variable + iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] + # Note: returns a list + C = SU2Driver.GetSolutionVector(iSPECIESSOLVER, iPoint) + T = Tu*(1-C[0]) + Tf*C[0] + iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] + solvar = list(SU2Driver.GetSolutionVector(iFLOWSOLVER, iPoint)) + # the list with names + solindex = getsolvar(SU2Driver) + primindex = SU2Driver.GetPrimitiveIndices() + iTEMP = solindex.get("TEMPERATURE") + solvar[iTEMP] = T + SU2Driver.SetSolutionVector(iFLOWSOLVER, iPoint, solvar) + + +# ################################################################## # +# Source term according to Zimont +# ################################################################## # +def zimont(SU2Driver, iPoint): + + iSSTSOLVER = SU2Driver.GetSolverIndices()['SST'] + tke, dissipation = SU2Driver.GetSolutionVector(iSSTSOLVER,iPoint) + + iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] + gradc = SU2Driver.GetGradient(iSPECIESSOLVER,iPoint,0) + + iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] + primindex = SU2Driver.GetPrimitiveIndices() + primvar = list(SU2Driver.GetPrimitiveVector(iFLOWSOLVER, iPoint)) + + iDENSITY = primindex.get("DENSITY") + iMU = primindex.get("LAMINAR_VISCOSITY") + + # laminar burning velocity of methane-air at phi=0.5, P=5 + Slu = 0.232 + + rho = primvar[iDENSITY] + mu = primvar[iMU] + nu=mu/rho + # Turbulent Flamespeed Closure with Dinkelacker correction + up = np.sqrt((2.0/3.0) * tke ) + lt = (0.09**0.75) * (tke**1.5) / dissipation + Re = up*lt/nu + Le = 1.0 + Ut = Slu * (1.0 + (0.46/Le) * np.power(Re,0.25) * np.power(up/Slu,0.3) * np.power(Pu,0.2) ) + norm_gradc = np.sqrt(gradc[0]*gradc[0] + gradc[1]*gradc[1]) + Sc = rho_u * Ut * norm_gradc + + return Sc + +# ################################################################## # +# Get the list of solver variable names +# ################################################################## # +def getsolvar(SU2Driver): + primindex = SU2Driver.GetPrimitiveIndices() + iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] + nVars = SU2Driver.GetNumberSolverVars(iFLOWSOLVER) + varindex = primindex.copy() + for prim in varindex.copy(): + if varindex[prim] >=nVars: + del varindex[prim] + varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) + return varindex + +# ################################################################## # +# Main routine +# ################################################################## # +def main(): + + # Initialize the primal driver of SU2, this includes solver preprocessing. + try: + driver = pysu2.CSinglezoneDriver('psi.cfg', 1, comm) + except TypeError as exception: + print('A TypeError occured in pysu2.CSinglezoneDriver : ', exception) + raise + + if rank == 0: + print("\n------------------------------ Begin Solver -----------------------------") + sys.stdout.flush() + + nDim = driver.GetNumberDimensions() + print("Dimensions of the problem = ",nDim) + + # index to the flow solver + # C.FLOW + # INC.FLOW + # HEAT + # FLAMELET + # SPECIES + # SA + # SST + iFLOWSOLVER = driver.GetSolverIndices()['INC.FLOW'] + print("index of flow solver = ",iFLOWSOLVER) + iSPECIESSOLVER = driver.GetSolverIndices()['SPECIES'] + print("index of species solver = ",iSPECIESSOLVER) + iSSTSOLVER = driver.GetSolverIndices()['SST'] + print("index of turbulence solver = ",iSSTSOLVER) + + # all the indices and the map to the names of the primitives + primindex = driver.GetPrimitiveIndices() + print("indices of primitives=",primindex) + print("number of primitives:",len(primindex)) + + nElem = driver.GetNumberElements() + print("number of elements:",nElem) + + nVars = driver.GetNumberSolverVars(iFLOWSOLVER) + print("number of flow solver variables:",nVars) + + nVarsSpecies = driver.GetNumberSolverVars(iSPECIESSOLVER) + print("number of species solver variables:",nVarsSpecies) + nVarsTurb = driver.GetNumberSolverVars(iSSTSOLVER) + print("number of turbulence solver variables:",nVarsTurb) + + varindex = primindex.copy() + for prim in varindex.copy(): + if varindex[prim] >=nVars: + del varindex[prim] + varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) + + # ### Check if we do a restart or not. ### + with open('psi.cfg') as f: + if 'RESTART_SOL= YES' in f.read(): + print("restarting from file") + else: + # We can set an initial condition by calling this function: + print("Start calling SetInitialSpecies") + SetInitialSpecies(driver) + print("End calling SetInitialSpecies") + + # super important to actually push the commands. + sys.stdout.flush() + + # run N iterations + for inner_iter in range(5): + + driver.Preprocess(inner_iter) + driver.Run() + + # set the source term, per point, + for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): + # add source term: + # default TFC of Zimont: rho*Sc = rho_u * U_t * grad(c) + S = [zimont(driver,i_node)] + driver.SetPointCustomSource(iSPECIESSOLVER, i_node,S) + + # for the update of temperature, we need to update also the halo nodes + for i_node in range(driver.GetNumberNodes(): + # set the temperature to T = c*Tf + (1-c)*Tu + update_temperature(driver, i_node) + + driver.Postprocess() + driver.Update() + # Monitor the solver and output solution to file if required + driver.Monitor(inner_iter) + # Output the solution to file + driver.Output(inner_iter) + + # Finalize the solver and exit cleanly. + driver.Finalize() + +if __name__ == '__main__': + main() From e94bb0c616804fd8c974dfa902d89c81a95f094b Mon Sep 17 00:00:00 2001 From: bigfooted Date: Mon, 7 Jul 2025 08:50:56 +0200 Subject: [PATCH 29/61] remove wall species options again --- Common/include/CConfig.hpp | 29 -------------- Common/include/option_structure.hpp | 14 ------- Common/src/CConfig.cpp | 53 +------------------------- SU2_CFD/src/solvers/CSpeciesSolver.cpp | 22 +---------- TestCases/py_wrapper/psi.cfg | 7 +--- 5 files changed, 3 insertions(+), 122 deletions(-) diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 70ea43a27094..9d283ba7e308 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -620,8 +620,6 @@ class CConfig { INLET_TYPE Kind_Inlet; INLET_TYPE *Kind_Inc_Inlet; - //WALL_SPECIES_TYPE **Wall_SpeciesType; - unsigned short **Wall_SpeciesType; INC_OUTLET_TYPE *Kind_Inc_Outlet; unsigned short nWall_Types; /*!< \brief Number of wall treatment types listed. */ unsigned short nInc_Inlet; /*!< \brief Number of inlet boundary treatment types listed. */ @@ -1347,12 +1345,6 @@ class CConfig { void addInletOption(const string& name, unsigned short & nMarker_Inlet, string * & Marker_Inlet, su2double* & Ttotal, su2double* & Ptotal, su2double** & FlowDir); - void addWallSpeciesOption(const string& name, unsigned short & nMarker_Wall_Species, string * & Marker_Wall_Species, - su2double** & wall_species_val, unsigned short & nSpecies_per_Wall); - void addWallSpeciesType(const string& name, unsigned short & nMarker_Wall_Species, string * & Marker_Wall_Species, -// WALL_SPECIES_TYPE** & wall_species_type, unsigned short & nSpecies_per_Wall); - unsigned short** & wall_species_type, unsigned short & nSpecies_per_Wall); - void addInletSpeciesOption(const string& name, unsigned short & nMarker_Inlet_Species, string * & Marker_Inlet_Species, su2double** & inlet_species_val, unsigned short & nSpecies_per_Inlet); @@ -4971,13 +4963,6 @@ class CConfig { */ INLET_TYPE GetKind_Inc_Inlet(const string& val_marker) const; - /*! - * \brief Get the type of incompressible inlet from the list. - * \return Kind of the incompressible inlet. - */ -// WALL_SPECIES_TYPE* GetKind_Wall_Species(const string& val_marker) const; - //unsigned short* GetKind_Wall_Species(const string& val_marker) const; - /*! * \brief Get the total number of types in Kind_Inc_Inlet list * \return Total number of types in Kind_Inc_Inlet list @@ -6849,20 +6834,6 @@ class CConfig { */ const su2double* GetInlet_SpeciesVal(const string& val_index) const; - /*! - * \brief Get the species values at a wall boundary - * \param[in] val_index - Index corresponding to the wall boundary. - * \return The wall species values. - */ - const su2double* GetWall_SpeciesVal(const string& val_index) const; - /*! - * \brief Get the species values at a wall boundary - * \param[in] val_index - Index corresponding to the wall boundary. - * \return The wall species values. - */ - //const WALL_SPECIES_TYPE* GetWall_SpeciesType(const string& val_index) const; - const unsigned short* GetWall_SpeciesType(const string& val_index) const; - /*! * \brief Get the turbulent properties values at an inlet boundary * \param[in] val_index - Index corresponding to the inlet boundary. diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 35abfd74c6de..12c7e5eba0f2 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -1961,20 +1961,6 @@ static const MapType Inlet_Map = { MakePair("PRESSURE_INLET", INLET_TYPE::PRESSURE_INLET) }; - -/*! - * \brief Types species wall boundary treatments - */ -enum class WALL_SPECIES_TYPE { - FLUX, /*!< \brief User specifies total pressure, total temperature, and flow direction. */ - VALUE, /*!< \brief User specifies density and velocity (mass flow). */ -}; - -static const MapType Wall_Species_Map = { - MakePair("FLUX", WALL_SPECIES_TYPE::FLUX) - MakePair("VALUE", WALL_SPECIES_TYPE::VALUE) -}; - /*! * \brief Types outlet boundary treatments */ diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 841c83e744da..499afe280cd9 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -495,30 +495,6 @@ void CConfig::addInletSpeciesOption(const string& name, unsigned short & nMarker option_map.insert(pair(name, val)); } -void CConfig::addWallSpeciesOption(const string& name, unsigned short & nMarker_Wall_Species, - string * & Marker_Wall_Species, su2double** & wall_species_val, - unsigned short & nSpecies_per_Wall) { - assert(option_map.find(name) == option_map.end()); - all_options.insert(pair(name, true)); - - COptionBase* val = new COptionStringValuesList(name, nMarker_Wall_Species, Marker_Wall_Species, - wall_species_val, nSpecies_per_Wall); - option_map.insert(pair(name, val)); -} - -void CConfig::addWallSpeciesType(const string& name, unsigned short & nMarker_Wall_Species, - //string * & Marker_Wall_Species, WALL_SPECIES_TYPE** & wall_species_type, - string * & Marker_Wall_Species, unsigned short** & wall_species_type, - unsigned short & nSpecies_per_Wall) { - assert(option_map.find(name) == option_map.end()); - all_options.insert(pair(name, true)); - - //COptionBase* val = new COptionStringValuesList<(unsigned short)WALL_SPECIES_TYPE*>(name, nMarker_Wall_Species, Marker_Wall_Species, - COptionBase* val = new COptionStringValuesList(name, nMarker_Wall_Species, Marker_Wall_Species, - wall_species_type, nSpecies_per_Wall); - option_map.insert(pair(name, val)); -} - void CConfig::addInletTurbOption(const string& name, unsigned short& nMarker_Inlet_Turb, string*& Marker_Inlet_Turb, su2double**& Turb_Properties_val, unsigned short& nTurb_Properties) { assert(option_map.find(name) == option_map.end()); @@ -1598,7 +1574,7 @@ void CConfig::SetConfig_Options() { addEnumOption("INLET_TYPE", Kind_Inlet, Inlet_Map, INLET_TYPE::TOTAL_CONDITIONS); /*!\brief INC_INLET_TYPE \n DESCRIPTION: List of inlet types for incompressible flows. List length must match number of inlet markers. Options: VELOCITY_INLET, PRESSURE_INLET, INPUT_FILE. \ingroup Config*/ addEnumListOption("INC_INLET_TYPE", nInc_Inlet, Kind_Inc_Inlet, Inlet_Map); - + addBoolOption("SPECIFIED_INLET_PROFILE", Inlet_From_File, false); /*!\brief INLET_FILENAME \n DESCRIPTION: Input file for a specified inlet profile (w/ extension) \n DEFAULT: inlet.dat \ingroup Config*/ @@ -1619,10 +1595,6 @@ void CConfig::SetConfig_Options() { /*!\brief MARKER_INLET_SPECIES \n DESCRIPTION: Inlet Species boundary marker(s) with the following format Inlet Species: (inlet_marker, Species1, Species2, ..., SpeciesN-1, inlet_marker2, Species1, Species2, ...) */ addInletSpeciesOption("MARKER_INLET_SPECIES",nMarker_Inlet_Species, Marker_Inlet_Species, Inlet_SpeciesVal, nSpecies_per_Inlet); - addWallSpeciesOption("MARKER_WALL_SPECIES" ,nMarker_Wall_Species , Marker_Wall_Species , Wall_SpeciesVal , nSpecies_per_Wall); - addWallSpeciesType("WALL_SPECIES_TYPE" ,nMarker_Wall_Species , Marker_Wall_Species , Wall_SpeciesType , nSpecies_per_Wall); - - /*!\brief MARKER_INLET_TURBULENT \n DESCRIPTION: Inlet Turbulence boundary marker(s) with the following format Inlet Turbulent: (inlet_marker, TurbulentIntensity1, ViscosityRatio1, inlet_marker2, TurbulentIntensity2, ViscosityRatio2, ...) */ @@ -9079,15 +9051,6 @@ INLET_TYPE CConfig::GetKind_Inc_Inlet(const string& val_marker) const { return Kind_Inc_Inlet[iMarker_Inlet]; } - -//WALL_SPECIES_TYPE* CConfig::GetKind_Wall_Species(const string& val_marker) const { -// unsigned short * CConfig::GetKind_Wall_Species(const string& val_marker) const { -// unsigned short iMarker_Wall_Species; -// for (iMarker_Wall_Species = 0; iMarker_Wall_Species < nMarker_Wall_Species; iMarker_Wall_Species++) -// if (Marker_Wall_Species[iMarker_Wall_Species] == val_marker) break; -// return Wall_SpeciesType[iMarker_Wall_Species]; -// } - INC_OUTLET_TYPE CConfig::GetKind_Inc_Outlet(const string& val_marker) const { unsigned short iMarker_Outlet; for (iMarker_Outlet = 0; iMarker_Outlet < nMarker_Outlet; iMarker_Outlet++) @@ -9151,20 +9114,6 @@ const su2double* CConfig::GetInlet_SpeciesVal(const string& val_marker) const { return Inlet_SpeciesVal[iMarker_Inlet_Species]; } -const su2double* CConfig::GetWall_SpeciesVal(const string& val_marker) const { - unsigned short iMarker_Wall_Species; - for (iMarker_Wall_Species = 0; iMarker_Wall_Species < nMarker_Wall_Species; iMarker_Wall_Species++) - if (Marker_Wall_Species[iMarker_Wall_Species] == val_marker) break; - return Wall_SpeciesVal[iMarker_Wall_Species]; -} -//const WALL_SPECIES_TYPE* CConfig::GetWall_SpeciesType(const string& val_marker) const { -const unsigned short* CConfig::GetWall_SpeciesType(const string& val_marker) const { - unsigned short iMarker_Wall_Species; - for (iMarker_Wall_Species = 0; iMarker_Wall_Species < nMarker_Wall_Species; iMarker_Wall_Species++) - if (Marker_Wall_Species[iMarker_Wall_Species] == val_marker) break; - return Wall_SpeciesType[iMarker_Wall_Species]; -} - const su2double* CConfig::GetInlet_TurbVal(const string& val_marker) const { /*--- If Turbulent Inlet is not provided for the marker, return free stream values. ---*/ for (auto iMarker = 0u; iMarker < nMarker_Inlet_Turb; iMarker++) { diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index bdc7829ff6a6..2254612cf03d 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -466,27 +466,7 @@ void CSpeciesSolver::BC_Isothermal_Wall_Generic(CGeometry* geometry, CSolver** s string Marker_Tag = config->GetMarker_All_TagBound(val_marker); /*--- Loop over all the vertices on this boundary marker ---*/ const su2double* InletSpecies = config->GetInlet_SpeciesVal("inlet") ; - cout << "inlet = " << InletSpecies[0] << " " << InletSpecies[1] << endl; - - const su2double* WallSpecies = config->GetWall_SpeciesVal("wall_side") ; - cout << "wall = " << WallSpecies[0] <<" " << WallSpecies[1] << endl; - - const short unsigned int* wallspeciestype = config->GetWall_SpeciesType(Marker_Tag); - cout << "type = "<<(wallspeciestype[0]) << " " << wallspeciestype[1] << endl; - // switch (config->GetWall_SpeciesType(Marker_Tag)[0]) { - // /*--- incompressible conditions ---*/ - - // //case WALL_SPECIES_TYPE::FLUX: - // case 0: - // cout << "flux" << endl; - // break; - // //case WALL_SPECIES_TYPE::VALUE: - // case 1: - // cout << "value" << endl; - // break; - // default: - // break; - // } + } diff --git a/TestCases/py_wrapper/psi.cfg b/TestCases/py_wrapper/psi.cfg index 6c796658efae..2d1e10b2acbf 100644 --- a/TestCases/py_wrapper/psi.cfg +++ b/TestCases/py_wrapper/psi.cfg @@ -20,7 +20,7 @@ RESTART_SOL= YES MGLEVEL= 0 % -% temperature and density +% temperature and density FREESTREAM_TEMPERATURE = 673 FREESTREAM_DENSITY = 2.55 % ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% @@ -74,12 +74,7 @@ INC_INLET_DAMPING= 0.01 MARKER_INLET= ( inlet, 673, 40.0, 1.0, 0.0, 0.0) MARKER_INLET_TURBULENT = (inlet, 0.10, 15) - MARKER_INLET_SPECIES= (inlet, 0.0, 400.0) -%WALL_SPECIES_TYPE = wall_side, FLUX, VALUE, wall_pipe, FLUX, VALUE,wall_out, FLUX, VALUE,wall_top, FLUX, VALUE -WALL_SPECIES_TYPE = wall_side, 0 , 1 , wall_pipe, 0 , 1 ,wall_out 0 , 1 , wall_top 0 , 1 -MARKER_WALL_SPECIES= wall_side, 0.0, 300.0, wall_pipe, 0.0, 400.0, wall_out, 0.0, 500.0, wall_top, 0.0, 300.0 - % INC_OUTLET_TYPE= PRESSURE_OUTLET INC_OUTLET_DAMPING= 0.01 From 6f7556416fd5683811fb84ca99e48ce232e73f0c Mon Sep 17 00:00:00 2001 From: bigfooted Date: Mon, 7 Jul 2025 10:44:51 +0200 Subject: [PATCH 30/61] cleanup --- Common/include/CConfig.hpp | 1 - Common/src/CConfig.cpp | 50 ++-- SU2_CFD/src/solvers/CSpeciesSolver.cpp | 15 +- .../lam_buoyancy_cavity.cfg | 0 .../run.py | 8 +- TestCases/py_wrapper/psi.cfg | 167 ------------ TestCases/py_wrapper/run.py | 256 ------------------ .../py_wrapper/turbulent_premixed_psi/run.py | 7 - 8 files changed, 28 insertions(+), 476 deletions(-) rename TestCases/py_wrapper/{custom_source => custom_source_buoyancy}/lam_buoyancy_cavity.cfg (100%) rename TestCases/py_wrapper/{custom_source => custom_source_buoyancy}/run.py (95%) delete mode 100644 TestCases/py_wrapper/psi.cfg delete mode 100755 TestCases/py_wrapper/run.py diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 3dc7ee28ff4f..c45b6e22fc0d 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -293,7 +293,6 @@ class CConfig { su2double *Inlet_Pressure; /*!< \brief Specified static pressures for supersonic inlet boundaries. */ su2double **Inlet_Velocity; /*!< \brief Specified flow velocity vectors for supersonic inlet boundaries. */ su2double **Inlet_SpeciesVal; /*!< \brief Specified species vector for inlet boundaries. */ - su2double **Wall_SpeciesVal; /*!< \brief Specified species vector for wall boundaries. */ su2double **Inlet_TurbVal; /*!< \brief Specified turbulent intensity and viscosity ratio for inlet boundaries. */ su2double *EngineInflow_Target; /*!< \brief Specified fan face targets for nacelle boundaries. */ su2double *Inflow_Mach; /*!< \brief Specified fan face mach for nacelle boundaries. */ diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index f2e36360a6e3..f8093e81a31c 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -891,7 +891,6 @@ void CConfig::SetPointersNull() { Inlet_FlowDir = nullptr; Inlet_Temperature = nullptr; Inlet_Pressure = nullptr; Inlet_Velocity = nullptr; Outlet_Pressure = nullptr; Inlet_SpeciesVal = nullptr; Inlet_TurbVal = nullptr; - Wall_SpeciesVal = nullptr; /*--- Engine Boundary Condition settings ---*/ @@ -983,8 +982,6 @@ void CConfig::SetPointersNull() { Kind_Inc_Inlet = nullptr; Kind_Inc_Outlet = nullptr; - Wall_SpeciesType = nullptr; - Kind_ObjFunc = nullptr; Weight_ObjFunc = nullptr; @@ -5605,13 +5602,11 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i "to be equal to the number of entries of SPECIES_INIT +1", CURRENT_FUNCTION); - // Helper function that checks scalar variable bounds, - -cout << "Note: we do not check boudns for scalars anymore." << endl; -// auto checkScalarBounds = [&](su2double scalar, const string& name, su2double lowerBound, su2double upperBound) { -// if (scalar < lowerBound || scalar > upperBound) -// SU2_MPI::Error(string("Variable: ") + name + string(", is out of bounds."), CURRENT_FUNCTION); -// }; + /*--- Helper function that checks scalar variable bounds. ---*/ + auto checkScalarBounds = [&](su2double scalar, const string& name, su2double lowerBound, su2double upperBound) { + if (scalar < lowerBound || scalar > upperBound) + SU2_MPI::Error(string("Variable: ") + name + string(", is out of bounds."), CURRENT_FUNCTION); + }; /*--- Some options have to provide as many entries as there are additional species equations. ---*/ /*--- Fill a vector with the entires and then check if each element is equal to the first one. ---*/ @@ -5633,24 +5628,23 @@ cout << "Note: we do not check boudns for scalars anymore." << endl; /*--- Check whether some variables (or their sums) are in physical bounds. [0,1] for species related quantities. ---*/ /*--- Note, only for species transport, not for flamelet model ---*/ -cout << "warning: no bounds checked for species" << endl; - // if (Kind_Species_Model == SPECIES_MODEL::SPECIES_TRANSPORT) { - // su2double Species_Init_Sum = 0.0; - // for (unsigned short iSpecies = 0; iSpecies < nSpecies; iSpecies++) { - // checkScalarBounds(Species_Init[iSpecies], "SPECIES_INIT individual", 0.0, 1.0); - // Species_Init_Sum += Species_Init[iSpecies]; - // } - // checkScalarBounds(Species_Init_Sum, "SPECIES_INIT sum", 0.0, 1.0); - - // for (iMarker = 0; iMarker < nMarker_Inlet_Species; iMarker++) { - // su2double Inlet_SpeciesVal_Sum = 0.0; - // for (unsigned short iSpecies = 0; iSpecies < nSpecies; iSpecies++) { - // checkScalarBounds(Inlet_SpeciesVal[iMarker][iSpecies], "MARKER_INLET_SPECIES individual", 0.0, 1.0); - // Inlet_SpeciesVal_Sum += Inlet_SpeciesVal[iMarker][iSpecies]; - // } - // checkScalarBounds(Inlet_SpeciesVal_Sum, "MARKER_INLET_SPECIES sum", 0.0, 1.0); - // } - // } + if (Kind_Species_Model == SPECIES_MODEL::SPECIES_TRANSPORT) { + su2double Species_Init_Sum = 0.0; + for (unsigned short iSpecies = 0; iSpecies < nSpecies; iSpecies++) { + checkScalarBounds(Species_Init[iSpecies], "SPECIES_INIT individual", 0.0, 1.0); + Species_Init_Sum += Species_Init[iSpecies]; + } + checkScalarBounds(Species_Init_Sum, "SPECIES_INIT sum", 0.0, 1.0); + + for (iMarker = 0; iMarker < nMarker_Inlet_Species; iMarker++) { + su2double Inlet_SpeciesVal_Sum = 0.0; + for (unsigned short iSpecies = 0; iSpecies < nSpecies; iSpecies++) { + checkScalarBounds(Inlet_SpeciesVal[iMarker][iSpecies], "MARKER_INLET_SPECIES individual", 0.0, 1.0); + Inlet_SpeciesVal_Sum += Inlet_SpeciesVal[iMarker][iSpecies]; + } + checkScalarBounds(Inlet_SpeciesVal_Sum, "MARKER_INLET_SPECIES sum", 0.0, 1.0); + } + } } // species transport checks diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index 2254612cf03d..13937b8f9a28 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -335,11 +335,8 @@ void CSpeciesSolver::BC_Inlet(CGeometry* geometry, CSolver** solver_container, C const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - /*--- Loop over all the vertices on this boundary marker ---*/ - - const su2double* InletSpecies = config->GetInlet_SpeciesVal(Marker_Tag) ; - cout << Marker_Tag << ", inlet = " << InletSpecies[0] << " " << InletSpecies[1] << endl; + /*--- Loop over all the vertices on this boundary marker ---*/ SU2_OMP_FOR_STAT(OMP_MIN_SIZE) for (auto iVertex = 0u; iVertex < geometry->nVertex[val_marker]; iVertex++) { auto iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); @@ -444,7 +441,7 @@ void CSpeciesSolver::SetUniformInlet(const CConfig* config, unsigned short iMark } } - +/*--- Currently all walls are zero-flux for the species ---*/ void CSpeciesSolver::BC_Isothermal_Wall(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) { @@ -460,17 +457,9 @@ void CSpeciesSolver::BC_HeatFlux_Wall(CGeometry* geometry, CSolver** solver_cont void CSpeciesSolver::BC_Isothermal_Wall_Generic(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, unsigned short val_marker, bool cht_mode) { - const bool implicit = config->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT; - - - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - /*--- Loop over all the vertices on this boundary marker ---*/ - const su2double* InletSpecies = config->GetInlet_SpeciesVal("inlet") ; - } - void CSpeciesSolver::BC_Outlet(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) { diff --git a/TestCases/py_wrapper/custom_source/lam_buoyancy_cavity.cfg b/TestCases/py_wrapper/custom_source_buoyancy/lam_buoyancy_cavity.cfg similarity index 100% rename from TestCases/py_wrapper/custom_source/lam_buoyancy_cavity.cfg rename to TestCases/py_wrapper/custom_source_buoyancy/lam_buoyancy_cavity.cfg diff --git a/TestCases/py_wrapper/custom_source/run.py b/TestCases/py_wrapper/custom_source_buoyancy/run.py similarity index 95% rename from TestCases/py_wrapper/custom_source/run.py rename to TestCases/py_wrapper/custom_source_buoyancy/run.py index 040457c79e22..bba69035b9a6 100644 --- a/TestCases/py_wrapper/custom_source/run.py +++ b/TestCases/py_wrapper/custom_source_buoyancy/run.py @@ -73,14 +73,14 @@ def main(): - #print("solver variable names:",varindex) + print("solver variable names:",varindex) iDENSITY = primindex.get("DENSITY") - #print("index of density = ",iDENSITY) + print("index of density = ",iDENSITY) index_Vel = varindex.get("VELOCITY_X") - #print("index of velocity = ",index_Vel) + print("index of velocity = ",index_Vel) custom_source_vector = [0.0 for i in range(nVars)] - #print("custom source vector = ", custom_source_vector) + print("custom source vector = ", custom_source_vector) #print("max. number of inner iterations: ",driver.GetNumberInnerIter()); #print("max nr of outer iterations: ",driver.GetNumberOuterIter()); diff --git a/TestCases/py_wrapper/psi.cfg b/TestCases/py_wrapper/psi.cfg deleted file mode 100644 index 2d1e10b2acbf..000000000000 --- a/TestCases/py_wrapper/psi.cfg +++ /dev/null @@ -1,167 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% SU2 configuration file % -% Case description: Turbulent premixed high pressure combustion chamber. % -% Author: N. Beishuizen % -% Institution: Bosch Thermotechniek B.V. % -% Date: 2025/01/01 % -% File Version 8.0 "Harrier" % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% -% -SOLVER= INC_RANS -KIND_TURB_MODEL= SST -SST_OPTIONS= V1994m - -RESTART_SOL= YES - -MGLEVEL= 0 -% - -% temperature and density -FREESTREAM_TEMPERATURE = 673 -FREESTREAM_DENSITY = 2.55 -% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% -% -%INC_DENSITY_MODEL= CONSTANT -INC_DENSITY_MODEL= VARIABLE -INC_DENSITY_INIT= 2.55 -% -INC_VELOCITY_INIT= (40.00, 0.0, 0.0 ) -% -INC_ENERGY_EQUATION= YES -INC_TEMPERATURE_INIT= 673.0 -% -INC_NONDIM= DIMENSIONAL -% -% -------------------- FLUID PROPERTIES ------------------------------------- % -% -FLUID_MODEL= INC_IDEAL_GAS -% -%CONDUCTIVITY_MODEL= CONSTANT_CONDUCTIVITY -CONDUCTIVITY_MODEL= CONSTANT_PRANDTL -THERMAL_CONDUCTIVITY_CONSTANT= 0.0357 -% -PRANDTL_LAM= 0.72 -TURBULENT_CONDUCTIVITY_MODEL= NONE -PRANDTL_TURB= 0.90 -% -VISCOSITY_MODEL= SUTHERLAND -MU_CONSTANT= 1.716E-5 -MU_REF = 1.716e-5 -MU_T_REF= 273.15 -SUTHERLAND_CONSTANT = 110.4 - -SPECIFIC_HEAT_CP = 1150 -% -% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% -% -MARKER_HEATFLUX= ( wall_side, 0.0, wall_pipe, 0.0, wall_out, 0.0 ) -MARKER_ISOTHERMAL= ( wall_top, 400.0 ) - -% note, case is axisymmetric -MARKER_SYM= ( symmetry ) -AXISYMMETRIC= YES -% -SPECIFIED_INLET_PROFILE= NO -INLET_MATCHING_TOLERANCE=1e-4 -INLET_FILENAME= inlet.dat -%INLET_INTERPOLATION_FUNCTION= LINEAR_1D -INC_INLET_TYPE= VELOCITY_INLET -INC_INLET_DAMPING= 0.01 -MARKER_INLET= ( inlet, 673, 40.0, 1.0, 0.0, 0.0) -MARKER_INLET_TURBULENT = (inlet, 0.10, 15) - -MARKER_INLET_SPECIES= (inlet, 0.0, 400.0) -% -INC_OUTLET_TYPE= PRESSURE_OUTLET -INC_OUTLET_DAMPING= 0.01 -MARKER_OUTLET= ( outlet, 0.0 ) -% -% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% -% -NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES -% -CFL_NUMBER= 10.0 -CFL_REDUCTION_SPECIES= 1.0 -CFL_REDUCTION_TURB= 1.0 -% -ITER= 100 -% -% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% -% -LINEAR_SOLVER= FGMRES -LINEAR_SOLVER_PREC= ILU -LINEAR_SOLVER_ERROR= 1E-12 -LINEAR_SOLVER_ITER= 25 - -% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% -% -CONV_NUM_METHOD_FLOW= FDS -MUSCL_FLOW= NO -SLOPE_LIMITER_FLOW = NONE -TIME_DISCRE_FLOW= EULER_IMPLICIT -% -% -------------------- SCALAR TRANSPORT ---------------------------------------% -% -KIND_SCALAR_MODEL= SPECIES_TRANSPORT -DIFFUSIVITY_MODEL= CONSTANT_DIFFUSIVITY -SCHMIDT_NUMBER_LAMINAR= 1.0 -DIFFUSIVITY_CONSTANT= 7.56e-5 - -% according to the paper -SCHMIDT_NUMBER_TURBULENT= 0.7 - -% -CONV_NUM_METHOD_SPECIES= BOUNDED_SCALAR -MUSCL_SPECIES= NO -SLOPE_LIMITER_SPECIES = NONE -% -TIME_DISCRE_SPECIES= EULER_IMPLICIT -% -SPECIES_INIT= 0.0 0.0 -%SPECIES_CLIPPING= YES -%SPECIES_CLIPPING_MIN= 0.0 -%SPECIES_CLIPPING_MAX= 1.0 -% -% -------------------- TURBULENT TRANSPORT ---------------------------------------% -% -CONV_NUM_METHOD_TURB= BOUNDED_SCALAR -MUSCL_TURB= NO - -% -% --------------------------- CONVERGENCE PARAMETERS --------------------------% -% -CONV_FIELD= RMS_PRESSURE, RMS_VELOCITY-X, RMS_VELOCITY-Y, RMS_TKE, RMS_SPECIES -CONV_RESIDUAL_MINVAL= -18 -CONV_STARTITER= 10 -% -% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% -% -%MESH_FILENAME= psi_coarse.su2 -MESH_FILENAME= psi.su2 -%MESH_FILENAME= psi_fine.su2 -% -SCREEN_OUTPUT= INNER_ITER WALL_TIME \ - RMS_TEMPERATURE RMS_PRESSURE RMS_VELOCITY-X RMS_VELOCITY-Y RMS_TKE RMS_DISSIPATION RMS_SPECIES_0 \ - LINSOL_ITER LINSOL_RESIDUAL \ - LINSOL_ITER_TURB LINSOL_RESIDUAL_TURB \ - LINSOL_ITER_SPECIES LINSOL_RESIDUAL_SPECIES -SCREEN_WRT_FREQ_INNER= 1 -% -HISTORY_OUTPUT= ITER RMS_RES LINSOL SPECIES_COEFF SPECIES_COEFF_SURF -CONV_FILENAME= history -MARKER_ANALYZE= gas_inlet, air_axial_inlet, outlet -MARKER_ANALYZE_AVERAGE= AREA -% -OUTPUT_FILES= RESTART_ASCII, PARAVIEW_MULTIBLOCK -VOLUME_OUTPUT= RESIDUAL, PRIMITIVE -OUTPUT_WRT_FREQ= 1000 -% -READ_BINARY_RESTART= NO -RESTART_FILENAME= restart -SOLUTION_FILENAME= solution -% -WRT_PERFORMANCE= YES diff --git a/TestCases/py_wrapper/run.py b/TestCases/py_wrapper/run.py deleted file mode 100755 index 9d86aa4df021..000000000000 --- a/TestCases/py_wrapper/run.py +++ /dev/null @@ -1,256 +0,0 @@ -#!/usr/bin/env python - -## \file run.py -# \brief turbulent premixed dump combustor simulation (PSI flame) -# phi=0.5, methane-air, U=40 m/s -# \version 8.1.0 "Harrier" -# -# SU2 Project Website: https://su2code.github.io -# -# The SU2 Project is maintained by the SU2 Foundation -# (http://su2foundation.org) -# -# Copyright 2012-2024, 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 . - -import sys -import pysu2 -from mpi4py import MPI -import numpy as np - -# Import mpi4py for parallel run -if options.with_MPI == True: - from mpi4py import MPI - comm = MPI.COMM_WORLD - rank = comm.Get_rank() -else: - comm = 0 - -# flame temperature of the methane-air mixture (phi=0.5, P=5) -Tf = 1777 - -# unburnt temperature of the propane-air mixture (phi=0.5, P=5) -Tu = 673.0 -Pu = 5.0 -phi = 0.5 -# unburnt density at P=5 -rho_u = 2.52 -# unburnt thermal conductivity of methane-air at phi=0.5 (phi=0.5, P=5) -k_u = 0.0523 -# unburnt heat capacity of methane-air at phi=0.5 (P=5) -cp_u = 1311.0 - -# P = rho*R*T -# 5 = 2.55 * R * 673 -# R = 0.0029 - -# ################################################################## # -# create a function for the initial progress variable c # -# ################################################################## # -def initC(coord): - x = coord[0] - #y = coord[1] - #z = coord[2] - # location where the flame should be - flame_x = 0.012 - if (x < flame_x): - C = 0.0 - else: - C = 1.0 - - return C - -# ################################################################## # -# loop over all vertices and set the species progress variable c # -# ################################################################## # -def SetInitialSpecies(SU2Driver): - allCoords = SU2Driver.Coordinates() - iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] - print("index of species solver = ",iSPECIESSOLVER) - nVarsSpecies = SU2Driver.GetNumberSolverVars(iSPECIESSOLVER) - print("number of species solver variables:",nVarsSpecies) - for iPoint in range(SU2Driver.GetNumberNodes() - SU2Driver.GetNumberHaloNodes()): - coord = allCoords.Get(iPoint) - C = initC(coord) - # now update the initial condition for the species - SU2Driver.SetSolutionVector(iSPECIESSOLVER, iPoint, [C]) - -# ################################################################## # -# Temperature is an algebraic function of c -# ################################################################## # -def update_temperature(SU2Driver, iPoint): - # first, get the progress variable - iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] - # Note: returns a list - C = SU2Driver.GetSolutionVector(iSPECIESSOLVER, iPoint) - T = Tu*(1-C[0]) + Tf*C[0] - iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] - solvar = list(SU2Driver.GetSolutionVector(iFLOWSOLVER, iPoint)) - # the list with names - solindex = getsolvar(SU2Driver) - primindex = SU2Driver.GetPrimitiveIndices() - iTEMP = solindex.get("TEMPERATURE") - solvar[iTEMP] = T - SU2Driver.SetSolutionVector(iFLOWSOLVER, iPoint, solvar) - - -# ################################################################## # -# Source term according to Zimont -# ################################################################## # -def zimont(SU2Driver, iPoint): - - iSSTSOLVER = SU2Driver.GetSolverIndices()['SST'] - tke, dissipation = SU2Driver.GetSolutionVector(iSSTSOLVER,iPoint) - - iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] - gradc = SU2Driver.GetGradient(iSPECIESSOLVER,iPoint,0) - - iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] - primindex = SU2Driver.GetPrimitiveIndices() - primvar = list(SU2Driver.GetPrimitiveVector(iFLOWSOLVER, iPoint)) - - iDENSITY = primindex.get("DENSITY") - iMU = primindex.get("LAMINAR_VISCOSITY") - - # laminar burning velocity of methane-air at phi=0.5, P=5 - Slu = 0.232 - - rho = primvar[iDENSITY] - mu = primvar[iMU] - nu=mu/rho - # Turbulent Flamespeed Closure with Dinkelacker correction - up = np.sqrt((2.0/3.0) * tke ) - lt = (0.09**0.75) * (tke**1.5) / dissipation - Re = up*lt/nu - Le = 1.0 - Ut = Slu * (1.0 + (0.46/Le) * np.power(Re,0.25) * np.power(up/Slu,0.3) * np.power(Pu,0.2) ) - norm_gradc = np.sqrt(gradc[0]*gradc[0] + gradc[1]*gradc[1]) - Sc = rho_u * Ut * norm_gradc - - return Sc - -# ################################################################## # -# Get the list of solver variable names -# ################################################################## # -def getsolvar(SU2Driver): - primindex = SU2Driver.GetPrimitiveIndices() - iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] - nVars = SU2Driver.GetNumberSolverVars(iFLOWSOLVER) - varindex = primindex.copy() - for prim in varindex.copy(): - if varindex[prim] >=nVars: - del varindex[prim] - varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) - return varindex - -# ################################################################## # -# Main routine -# ################################################################## # -def main(): - - # Initialize the primal driver of SU2, this includes solver preprocessing. - try: - driver = pysu2.CSinglezoneDriver('psi.cfg', 1, comm) - except TypeError as exception: - print('A TypeError occured in pysu2.CSinglezoneDriver : ', exception) - raise - - if rank == 0: - print("\n------------------------------ Begin Solver -----------------------------") - sys.stdout.flush() - - nDim = driver.GetNumberDimensions() - print("Dimensions of the problem = ",nDim) - - # index to the flow solver - # C.FLOW - # INC.FLOW - # HEAT - # FLAMELET - # SPECIES - # SA - # SST - iFLOWSOLVER = driver.GetSolverIndices()['INC.FLOW'] - print("index of flow solver = ",iFLOWSOLVER) - iSPECIESSOLVER = driver.GetSolverIndices()['SPECIES'] - print("index of species solver = ",iSPECIESSOLVER) - iSSTSOLVER = driver.GetSolverIndices()['SST'] - print("index of turbulence solver = ",iSSTSOLVER) - - # all the indices and the map to the names of the primitives - primindex = driver.GetPrimitiveIndices() - print("indices of primitives=",primindex) - print("number of primitives:",len(primindex)) - - nElem = driver.GetNumberElements() - print("number of elements:",nElem) - - nVars = driver.GetNumberSolverVars(iFLOWSOLVER) - print("number of flow solver variables:",nVars) - - nVarsSpecies = driver.GetNumberSolverVars(iSPECIESSOLVER) - print("number of species solver variables:",nVarsSpecies) - nVarsTurb = driver.GetNumberSolverVars(iSSTSOLVER) - print("number of turbulence solver variables:",nVarsTurb) - - varindex = primindex.copy() - for prim in varindex.copy(): - if varindex[prim] >=nVars: - del varindex[prim] - varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) - - # ### Check if we do a restart or not. ### - with open('psi.cfg') as f: - if 'RESTART_SOL= YES' in f.read(): - print("restarting from file") - else: - # We can set an initial condition by calling this function: - print("Start calling SetInitialSpecies") - SetInitialSpecies(driver) - print("End calling SetInitialSpecies") - - # super important to actually push the commands. - sys.stdout.flush() - - # run N iterations - for inner_iter in range(5): - - driver.Preprocess(inner_iter) - driver.Run() - - # set the source term, per point, - for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): - # add source term: - # default TFC of Zimont: rho*Sc = rho_u * U_t * grad(c) - S = [zimont(driver,i_node)] - driver.SetPointCustomSource(iSPECIESSOLVER, i_node,S) - - # for the update of temperature, we need to update also the halo nodes - for i_node in range(driver.GetNumberNodes(): - # set the temperature to T = c*Tf + (1-c)*Tu - update_temperature(driver, i_node) - - driver.Postprocess() - driver.Update() - # Monitor the solver and output solution to file if required - driver.Monitor(inner_iter) - # Output the solution to file - driver.Output(inner_iter) - - # Finalize the solver and exit cleanly. - driver.Finalize() - -if __name__ == '__main__': - main() diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py index 9d86aa4df021..15f8c8f305aa 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/run.py +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -100,7 +100,6 @@ def update_temperature(SU2Driver, iPoint): solvar = list(SU2Driver.GetSolutionVector(iFLOWSOLVER, iPoint)) # the list with names solindex = getsolvar(SU2Driver) - primindex = SU2Driver.GetPrimitiveIndices() iTEMP = solindex.get("TEMPERATURE") solvar[iTEMP] = T SU2Driver.SetSolutionVector(iFLOWSOLVER, iPoint, solvar) @@ -205,12 +204,6 @@ def main(): nVarsTurb = driver.GetNumberSolverVars(iSSTSOLVER) print("number of turbulence solver variables:",nVarsTurb) - varindex = primindex.copy() - for prim in varindex.copy(): - if varindex[prim] >=nVars: - del varindex[prim] - varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) - # ### Check if we do a restart or not. ### with open('psi.cfg') as f: if 'RESTART_SOL= YES' in f.read(): From 61d6cffb8f91351feb0045e6e72ddf1b38181238 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Mon, 7 Jul 2025 13:05:51 +0200 Subject: [PATCH 31/61] more cleanup --- Common/src/CConfig.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index f8093e81a31c..3b2a0717be05 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -5669,7 +5669,7 @@ void CConfig::SetMarkers(SU2_COMPONENT val_software) { iMarker_FarField, iMarker_SymWall, iMarker_PerBound, iMarker_NearFieldBound, iMarker_Fluid_InterfaceBound, iMarker_Inlet, iMarker_Riemann, iMarker_Giles, iMarker_Outlet, - iMarker_Smoluchowski_Maxwell, iMarker_Wall, + iMarker_Smoluchowski_Maxwell, iMarker_Isothermal,iMarker_HeatFlux,iMarker_HeatTansfer, iMarker_EngineInflow, iMarker_EngineExhaust, iMarker_Damper, iMarker_Displacement, iMarker_Load, iMarker_Internal, @@ -6231,7 +6231,7 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { unsigned short iMarker_Euler, iMarker_Custom, iMarker_FarField, iMarker_SymWall, iMarker_PerBound, iMarker_NearFieldBound, - iMarker_Fluid_InterfaceBound, iMarker_Inlet, iMarker_Riemann, iMarker_Wall, + iMarker_Fluid_InterfaceBound, iMarker_Inlet, iMarker_Riemann, iMarker_Deform_Mesh, iMarker_Deform_Mesh_Sym_Plane, iMarker_Fluid_Load, iMarker_Smoluchowski_Maxwell, iWall_Catalytic, iMarker_Giles, iMarker_Outlet, iMarker_Isothermal, iMarker_HeatFlux, iMarker_HeatTransfer, @@ -7562,14 +7562,7 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { } BoundaryTable.PrintFooter(); } - if (nMarker_Wall_Species != 0) { - BoundaryTable << "Species Wall boundary"; - for (iMarker_Wall = 0; iMarker_Wall < nMarker_Wall_Species; iMarker_Wall++) { - BoundaryTable << Marker_Wall_Species[iMarker_Wall]; - if (iMarker_Wall < nMarker_Wall_Species-1) BoundaryTable << " "; - } - BoundaryTable.PrintFooter(); - } + if (nMarker_Riemann != 0) { BoundaryTable << "Riemann boundary"; for (iMarker_Riemann = 0; iMarker_Riemann < nMarker_Riemann; iMarker_Riemann++) { @@ -9060,7 +9053,6 @@ su2double CConfig::GetExhaust_Pressure_Target(const string& val_marker) const { return Exhaust_Pressure_Target[iMarker_EngineExhaust]; } - INLET_TYPE CConfig::GetKind_Inc_Inlet(const string& val_marker) const { unsigned short iMarker_Inlet; for (iMarker_Inlet = 0; iMarker_Inlet < nMarker_Inlet; iMarker_Inlet++) From 4f87859a0fbc10ef752540006028e09f38e076c8 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Mon, 7 Jul 2025 16:36:10 +0200 Subject: [PATCH 32/61] fix link to testcase --- TestCases/parallel_regression.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index 5a04ca10dedd..d184de4377c2 100644 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -1477,7 +1477,7 @@ def main(): # custom source: buoyancy term pywrapper_buoyancy = TestCase('pywrapper_buoyancy') - pywrapper_buoyancy.cfg_dir = "py_wrapper/custom_source" + pywrapper_buoyancy.cfg_dir = "py_wrapper/custom_source_buoyancy" pywrapper_buoyancy.cfg_file = "lam_buoyancy_cavity.cfg" pywrapper_buoyancy.test_iter = 0 pywrapper_buoyancy.test_vals = [0.500000, 0.000000, -3.037859, -1.603563, -2.074259, 2.424288, 7.762848, -0.220436] @@ -1486,7 +1486,7 @@ def main(): # custom source: turbulent flamespeed closure (Zimont model) for PSI testcase pywrapper_zimont = TestCase('pywrapper_zimont') - pywrapper_zimont.cfg_dir = "py_wrapper/psi" + pywrapper_zimont.cfg_dir = "py_wrapper/turbulent_premixed_psi" pywrapper_zimont.cfg_file = "psi.cfg" pywrapper_zimont.test_iter = 0 pywrapper_zimont.test_vals = [0.500000, 0.000000, -3.037859, -1.603563, -2.074259, 2.424288, 7.762848, -0.220436] From 76c6d6ac5772704da9bc994109d9a851d91f51b4 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Wed, 9 Jul 2025 20:22:45 +0200 Subject: [PATCH 33/61] cleanup --- Common/include/CConfig.hpp | 5 ----- Common/include/geometry/dual_grid/CPoint.hpp | 1 - Common/src/CConfig.cpp | 2 -- SU2_CFD/include/solvers/CFVMFlowSolverBase.inl | 3 +-- SU2_CFD/src/solvers/CSpeciesSolver.cpp | 3 +-- 5 files changed, 2 insertions(+), 12 deletions(-) diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index c45b6e22fc0d..eb6beab278d1 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -195,10 +195,8 @@ class CConfig { nMarker_CHTInterface, /*!< \brief Number of conjugate heat transfer interface markers. */ nMarker_ContactResistance, /*!< \brief Number of CHT interfaces with contact resistance. */ nMarker_Inlet, /*!< \brief Number of inlet flow markers. */ - nMarker_Wall_Species, /*!< \brief Number of inlet flow markers. */ nMarker_Inlet_Species, /*!< \brief Number of inlet species markers. */ nSpecies_per_Inlet, /*!< \brief Number of species defined per inlet markers. */ - nSpecies_per_Wall, /*!< \brief Number of species defined per inlet markers. */ nMarker_Inlet_Turb, /*!< \brief Number of inlet turbulent markers. */ nTurb_Properties, /*!< \brief Number of turbulent properties per inlet markers. */ nMarker_Riemann, /*!< \brief Number of Riemann flow markers. */ @@ -253,7 +251,6 @@ class CConfig { *Marker_ActDiskBemInlet_Axis, /*!< \brief Actuator disk BEM inlet markers passed to MARKER_ACTDISK_BEM_AXIS. */ *Marker_ActDiskBemOutlet_Axis, /*!< \brief Actuator disk BEM outlet markers passed to MARKER_ACTDISK_BEM_AXIS. */ *Marker_Inlet, /*!< \brief Inlet flow markers. */ - *Marker_Wall_Species, /*!< \brief Inlet flow markers. */ *Marker_Inlet_Species, /*!< \brief Inlet species markers. */ *Marker_Inlet_Turb, /*!< \brief Inlet turbulent markers. */ *Marker_Riemann, /*!< \brief Riemann markers. */ @@ -622,11 +619,9 @@ class CConfig { *Kind_Data_Giles; /*!< \brief Kind of inlet boundary treatment. */ INLET_TYPE Kind_Inlet; INLET_TYPE *Kind_Inc_Inlet; - INC_OUTLET_TYPE *Kind_Inc_Outlet; unsigned short nWall_Types; /*!< \brief Number of wall treatment types listed. */ unsigned short nInc_Inlet; /*!< \brief Number of inlet boundary treatment types listed. */ - unsigned short nSpecies_Wall; /*!< \brief Number of inlet boundary treatment types listed. */ unsigned short nInc_Outlet; /*!< \brief Number of inlet boundary treatment types listed. */ su2double Inc_Inlet_Damping; /*!< \brief Damping factor applied to the iterative updates to the velocity at a pressure inlet in incompressible flow. */ su2double Inc_Outlet_Damping; /*!< \brief Damping factor applied to the iterative updates to the pressure at a mass flow outlet in incompressible flow. */ diff --git a/Common/include/geometry/dual_grid/CPoint.hpp b/Common/include/geometry/dual_grid/CPoint.hpp index 05d64e25482a..c3a962e3af24 100644 --- a/Common/include/geometry/dual_grid/CPoint.hpp +++ b/Common/include/geometry/dual_grid/CPoint.hpp @@ -82,7 +82,6 @@ class CPoint { su2activematrix Coord; /*!< \brief vector with the coordinates of the node. */ su2activematrix Coord_Old; /*!< \brief Old coordinates vector for primal solution reloading for Disc.Adj. with dynamic grid. */ - su2activematrix Coord_Sum; /*!< \brief Sum of coordinates vector for geometry smoothing. */ su2activematrix Coord_n; /*!< \brief Coordinates at time n for use with dynamic meshes. */ su2activematrix Coord_n1; /*!< \brief Coordinates at time n-1 for use with dynamic meshes. */ su2activematrix Coord_p1; /*!< \brief Coordinates at time n+1 for use with dynamic meshes. */ diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 3b2a0717be05..d35da105ffbd 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -1581,8 +1581,6 @@ void CConfig::SetConfig_Options() { addEnumOption("INLET_TYPE", Kind_Inlet, Inlet_Map, INLET_TYPE::TOTAL_CONDITIONS); /*!\brief INC_INLET_TYPE \n DESCRIPTION: List of inlet types for incompressible flows. List length must match number of inlet markers. Options: VELOCITY_INLET, PRESSURE_INLET, INPUT_FILE. \ingroup Config*/ addEnumListOption("INC_INLET_TYPE", nInc_Inlet, Kind_Inc_Inlet, Inlet_Map); - - addBoolOption("SPECIFIED_INLET_PROFILE", Inlet_From_File, false); /*!\brief INLET_FILENAME \n DESCRIPTION: Input file for a specified inlet profile (w/ extension) \n DEFAULT: inlet.dat \ingroup Config*/ addStringOption("INLET_FILENAME", Inlet_Filename, string("inlet.dat")); diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 6932f9a43ffd..612bf0784146 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -123,8 +123,7 @@ void CFVMFlowSolverBase::Allocate(const CConfig& config) { /*--- Store the value of the Flow direction at the inlet BC ---*/ AllocVectorOfMatrices(nVertex, nDim, Inlet_FlowDir); - PointSource.resize(nPointDomain,nVar); - PointSource.setConstant(0.0); + PointSource.resize(nPointDomain,nVar)= su2double(0.0); /*--- Force definition and coefficient arrays for all of the markers ---*/ diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index 13937b8f9a28..82fe30b82c73 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -110,8 +110,7 @@ void CSpeciesSolver::Initialize(CGeometry* geometry, CConfig* config, unsigned s nDim = geometry->GetnDim(); - SpeciesPointSource.resize(nPointDomain,nVar); - SpeciesPointSource.setConstant(0.0); + SpeciesPointSource.resize(nPointDomain,nVar) = su2double(0.0); if (iMesh == MESH_0 || config->GetMGCycle() == FULLMG_CYCLE) { From ea5e99c93bac552fb3481ee182d528c5c3ee3106 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Wed, 9 Jul 2025 21:12:16 +0200 Subject: [PATCH 34/61] precommit --- Common/include/geometry/dual_grid/CPoint.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Common/include/geometry/dual_grid/CPoint.hpp b/Common/include/geometry/dual_grid/CPoint.hpp index c3a962e3af24..a13d4cb3663a 100644 --- a/Common/include/geometry/dual_grid/CPoint.hpp +++ b/Common/include/geometry/dual_grid/CPoint.hpp @@ -82,9 +82,9 @@ class CPoint { su2activematrix Coord; /*!< \brief vector with the coordinates of the node. */ su2activematrix Coord_Old; /*!< \brief Old coordinates vector for primal solution reloading for Disc.Adj. with dynamic grid. */ - su2activematrix Coord_n; /*!< \brief Coordinates at time n for use with dynamic meshes. */ - su2activematrix Coord_n1; /*!< \brief Coordinates at time n-1 for use with dynamic meshes. */ - su2activematrix Coord_p1; /*!< \brief Coordinates at time n+1 for use with dynamic meshes. */ + su2activematrix Coord_n; /*!< \brief Coordinates at time n for use with dynamic meshes. */ + su2activematrix Coord_n1; /*!< \brief Coordinates at time n-1 for use with dynamic meshes. */ + su2activematrix Coord_p1; /*!< \brief Coordinates at time n+1 for use with dynamic meshes. */ su2activematrix GridVel; /*!< \brief Velocity of the grid for dynamic mesh cases. */ CVectorOfMatrix GridVel_Grad; /*!< \brief Gradient of the grid velocity for dynamic meshes. */ From f61c5de112ab6b729e4133149bf3db8685091190 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Thu, 10 Jul 2025 00:13:13 +0200 Subject: [PATCH 35/61] fix typo --- TestCases/parallel_regression.py | 8 ++++---- TestCases/py_wrapper/turbulent_premixed_psi/run.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index d184de4377c2..e031134b3261 100644 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -1479,8 +1479,8 @@ def main(): pywrapper_buoyancy = TestCase('pywrapper_buoyancy') pywrapper_buoyancy.cfg_dir = "py_wrapper/custom_source_buoyancy" pywrapper_buoyancy.cfg_file = "lam_buoyancy_cavity.cfg" - pywrapper_buoyancy.test_iter = 0 - pywrapper_buoyancy.test_vals = [0.500000, 0.000000, -3.037859, -1.603563, -2.074259, 2.424288, 7.762848, -0.220436] + pywrapper_buoyancy.test_iter = 1 + pywrapper_buoyancy.test_vals = [0.500000] pywrapper_buoyancy.command = TestCase.Command("mpirun -np 2", "python", "run.py") test_list.append(pywrapper_buoyancy) @@ -1488,8 +1488,8 @@ def main(): pywrapper_zimont = TestCase('pywrapper_zimont') pywrapper_zimont.cfg_dir = "py_wrapper/turbulent_premixed_psi" pywrapper_zimont.cfg_file = "psi.cfg" - pywrapper_zimont.test_iter = 0 - pywrapper_zimont.test_vals = [0.500000, 0.000000, -3.037859, -1.603563, -2.074259, 2.424288, 7.762848, -0.220436] + pywrapper_zimont.test_iter = 1 + pywrapper_zimont.test_vals = [0.500000] pywrapper_zimont.command = TestCase.Command("mpirun -np 2", "python", "run.py") test_list.append(pywrapper_zimont) diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py index 15f8c8f305aa..d78ce1c1679c 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/run.py +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -231,7 +231,7 @@ def main(): driver.SetPointCustomSource(iSPECIESSOLVER, i_node,S) # for the update of temperature, we need to update also the halo nodes - for i_node in range(driver.GetNumberNodes(): + for i_node in range(driver.GetNumberNodes()): # set the temperature to T = c*Tf + (1-c)*Tu update_temperature(driver, i_node) From 64a891f9aa3ba7e0222acd8cda31f3e65e97643e Mon Sep 17 00:00:00 2001 From: Nijso Date: Thu, 10 Jul 2025 20:19:27 +0200 Subject: [PATCH 36/61] Update SU2_CFD/src/solvers/CSpeciesSolver.cpp Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> --- SU2_CFD/src/solvers/CSpeciesSolver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index 82fe30b82c73..7e2e825a5d5b 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -591,7 +591,7 @@ void CSpeciesSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta } -void CSpeciesSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, +void CSpeciesSolver::CustomSourceResidual(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { /*--- Pick one numerics object per thread. ---*/ From 948d1b3630d4451feed47a7b03c7a2da51a7444d Mon Sep 17 00:00:00 2001 From: Nijso Date: Thu, 10 Jul 2025 20:19:53 +0200 Subject: [PATCH 37/61] Update SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> --- SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp index a45229e81a9b..fb1c2920766b 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp @@ -339,7 +339,7 @@ inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- Compute the residual for this control volume and subtract. ---*/ for (iVar = 0; iVar < nVar; iVar++) { - LinSysRes[iPoint*nVar+iVar] += PointSource[iPoint][iVar] * Volume; + LinSysRes(iPoint, iVar) += PointSource(iPoint, iVar) * Volume; } } END_SU2_OMP_FOR From aa12ebc14600ffb11b567e31b501a634e3448636 Mon Sep 17 00:00:00 2001 From: Nijso Date: Thu, 10 Jul 2025 20:20:05 +0200 Subject: [PATCH 38/61] Update SU2_CFD/include/solvers/CFVMFlowSolverBase.inl Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> --- SU2_CFD/include/solvers/CFVMFlowSolverBase.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 612bf0784146..426bbb87f386 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -123,7 +123,7 @@ void CFVMFlowSolverBase::Allocate(const CConfig& config) { /*--- Store the value of the Flow direction at the inlet BC ---*/ AllocVectorOfMatrices(nVertex, nDim, Inlet_FlowDir); - PointSource.resize(nPointDomain,nVar)= su2double(0.0); + PointSource.resize(nPointDomain, nVar) = su2double(0.0); /*--- Force definition and coefficient arrays for all of the markers ---*/ From 82360ca09d12f82b4b255387ff3a241820106d99 Mon Sep 17 00:00:00 2001 From: Nijso Date: Thu, 10 Jul 2025 20:23:51 +0200 Subject: [PATCH 39/61] Update SU2_CFD/include/drivers/CDriverBase.hpp Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> --- SU2_CFD/include/drivers/CDriverBase.hpp | 61 ------------------------- 1 file changed, 61 deletions(-) diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index 2a37af22efe8..49fbf56c5510 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -776,67 +776,6 @@ class CDriverBase { * \param[in] iPoint - Point index. * \param[out] solutionvector - Vector values of the solution. */ -inline vector GetSolutionVector(unsigned short iSolver, unsigned long iPoint) { - auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; - auto* nodes = solver->GetNodes(); - auto nVar = GetNumberSolverVars(iSolver); - vector solutionvector(nVar, 0.0); - for (auto iVar = 0u; iVar < nVar; ++iVar) { - solutionvector[iVar] = SU2_TYPE::GetValue(nodes->GetSolution(iPoint,iVar)); - } - return solutionvector; -} - -/* The vector with actual solution values */ -inline void SetSolutionVector(unsigned short iSolver, unsigned long iPoint, vector solutionVector) { - auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; - auto* nodes = solver->GetNodes(); - - /*--- check the size of the solver variables ---*/ - unsigned short nVar = GetNumberSolverVars(iSolver); - if (nVar != solutionVector.size() ) - SU2_MPI::Error("Solution Vector size is not equal to Solver size.", CURRENT_FUNCTION); - for (unsigned int iVar = 0u; iVar < nVar; ++iVar) { - nodes->SetSolution(iPoint,iVar, solutionVector[iVar]); - nodes->SetSolution_Old(iPoint,iVar, solutionVector[iVar]); - } -} - - - /*! - * \brief Get the primitive variables vector in a point for a specific solver - * \param[in] iSolver - Solver index. - * \param[in] iPoint - Point index. - * \param[out] solutionvector - Vector values of the primitive variables. - */ -inline vector GetPrimitiveVector(unsigned short iSolver, unsigned long iPoint) { - auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; - auto* nodes = solver->GetNodes(); - auto nPrimvar = GetNumberPrimitiveVars(iSolver); - vector solutionvector(nPrimvar, 0.0); - for (auto iVar = 0u; iVar < nPrimvar; ++iVar) { - solutionvector[iVar] = SU2_TYPE::GetValue(nodes->GetPrimitive(iPoint,iVar)); - } - return solutionvector; -} - - - /*! - * \brief Get the primitive variables vector in a point for a specific solver - * \param[in] iSolver - Solver index. - * \param[in] iPoint - Point index. - * \param[out] solutionvector - Vector values of the primitive variables. - */ -inline void SetPrimitiveVector(unsigned short iSolver, unsigned long iPoint, vector primitiveVector) { - auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; - auto* nodes = solver->GetNodes(); - auto nPrimvar = GetNumberPrimitiveVars(iSolver); - vector solutionvector(nPrimvar, 0.0); - - for (auto iVar = 0u; iVar < nPrimvar; ++iVar) { - nodes->SetPrimitive(iPoint,iVar, primitiveVector[iVar]); - } -} /// \} From 161be5d62cbbd5f1cca9691fb0b7c0760ba7e9f6 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Thu, 10 Jul 2025 23:06:53 +0200 Subject: [PATCH 40/61] cleanup and reviewer suggestions --- .../containers/CPyWrapperMatrixView.hpp | 1 + SU2_CFD/include/drivers/CDriver.hpp | 22 ++----------- SU2_CFD/include/solvers/CSpeciesSolver.hpp | 33 ------------------- SU2_CFD/src/python_wrapper_structure.cpp | 12 ++----- SU2_CFD/src/solvers/CIncEulerSolver.cpp | 2 ++ SU2_CFD/src/solvers/CSpeciesSolver.cpp | 24 +------------- .../py_wrapper/custom_source_buoyancy/run.py | 8 ++--- .../py_wrapper/turbulent_premixed_psi/run.py | 25 +++++++------- 8 files changed, 24 insertions(+), 103 deletions(-) diff --git a/Common/include/containers/CPyWrapperMatrixView.hpp b/Common/include/containers/CPyWrapperMatrixView.hpp index 9a39ef3badf9..6925c48e44ad 100644 --- a/Common/include/containers/CPyWrapperMatrixView.hpp +++ b/Common/include/containers/CPyWrapperMatrixView.hpp @@ -54,6 +54,7 @@ \ /*! \brief Gets the value for a (row, column) pair. */ \ passivedouble operator()(unsigned long row, unsigned long col) const { return Get(row, col); } \ + std::vector operator()(unsigned long row) const { return Get(row); } \ \ /*! \brief Gets the value for a (row, column) pair. */ \ passivedouble Get(unsigned long row, unsigned long col) const { return SU2_TYPE::GetValue(Access(row, col)); } \ diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index 48b5e7dbf625..eb06d7097b9f 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -481,30 +481,12 @@ class CDriver : public CDriverBase { */ unsigned long GetNumberInnerIter() const; - /*! - * \brief Set the number of inner iterations. - * \return - */ - void SetNumberInnerIter(unsigned long val_iter); - /*! * \brief Get the number of outer iterations. * \return Number of outer iterations. */ unsigned long GetNumberOuterIter() const; - /*! - * \brief Set the number of outer iterations. - * \return - */ - void SetNumberOuterIter(unsigned long val_iter); - - /*! - * \brief Get the current solution - * \return Current solution - */ - unsigned long GetSolution(unsigned short iSolver, unsigned long iPoint, unsigned short iVar); - /*! * \brief Get the current time iteration. * \return Current time iteration. @@ -589,13 +571,13 @@ class CDriver : public CDriverBase { * \brief Get the Freestream Density for nondimensionalization * \return Freestream Density */ - unsigned long GetDensity_FreeStreamND() const; + passivedouble GetDensity_FreeStreamND() const; /*! * \brief Get the reference Body force for nondimensionalization * \return reference Body Force */ - unsigned long GetForce_Ref() const; + passivedouble GetForce_Ref() const; /// \} diff --git a/SU2_CFD/include/solvers/CSpeciesSolver.hpp b/SU2_CFD/include/solvers/CSpeciesSolver.hpp index 46244713b039..47829debdae6 100644 --- a/SU2_CFD/include/solvers/CSpeciesSolver.hpp +++ b/SU2_CFD/include/solvers/CSpeciesSolver.hpp @@ -104,39 +104,6 @@ class CSpeciesSolver : public CScalarSolver { */ void BC_Inlet(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) override; - - - /*! - * \brief Impose the Navier-Stokes wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Isothermal_Wall(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, - CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) override; - - /*! - * \brief Impose the Navier-Stokes wall boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_HeatFlux_Wall(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, - CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) override; - - /*! - * \brief Generic implementation of the isothermal wall also covering CHT cases, - * for which the wall temperature is given by GetConjugateHeatVariable. - */ - void BC_Isothermal_Wall_Generic(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, - CNumerics* visc_numerics, CConfig* config, unsigned short val_marker, - bool cht_mode = false); /*! * \brief Store of a set of provided inlet profile values at a vertex. diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index 4b5d2a15f4ce..e9d1e0d99bb2 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -60,13 +60,12 @@ unsigned long CDriver::GetNumberTimeIter() const { return config_container[selec unsigned long CDriver::GetNumberInnerIter() const { return config_container[selected_zone]->GetnInner_Iter(); } unsigned long CDriver::GetNumberOuterIter() const { return config_container[selected_zone]->GetnOuter_Iter(); } -void CDriver::SetNumberInnerIter(unsigned long val_iter) { config_container[selected_zone]->SetnInner_Iter(val_iter); } -void CDriver::SetNumberOuterIter(unsigned long val_iter) { config_container[selected_zone]->SetnOuter_Iter(val_iter); } -unsigned long CDriver::GetDensity_FreeStreamND() const { +passivedouble CDriver::GetDensity_FreeStreamND() const { return SU2_TYPE::GetValue(config_container[selected_zone]->GetDensity_FreeStreamND()); } -unsigned long CDriver::GetForce_Ref() const { + +passivedouble CDriver::GetForce_Ref() const { return SU2_TYPE::GetValue(config_container[selected_zone]->GetForce_Ref()); } @@ -78,11 +77,6 @@ passivedouble CDriver::GetUnsteadyTimeStep() const { string CDriver::GetSurfaceFileName() const { return config_container[selected_zone]->GetSurfCoeff_FileName(); } -unsigned long CDriver::GetSolution(unsigned short iSOLVER, unsigned long iPoint, unsigned short iVar) { - auto solver = solver_container[iZone][INST_0][MESH_0][iSOLVER]; - return SU2_TYPE::GetValue(solver->GetNodes()->GetSolution(iPoint,iVar)); -} - //////////////////////////////////////////////////////////////////////////////// /* Functions related to the management of markers */ //////////////////////////////////////////////////////////////////////////////// diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index 2d81eea38730..ed94061412bd 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -1811,6 +1811,8 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont } } + //Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + } void CIncEulerSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index 7e2e825a5d5b..fc6dfd9acc76 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -344,9 +344,6 @@ void CSpeciesSolver::BC_Inlet(CGeometry* geometry, CSolver** solver_container, C if (!geometry->nodes->GetDomain(iPoint)) continue; - /*--- Identify the boundary by string name ---*/ - string Marker_Tag = config->GetMarker_All_TagBound(val_marker); - if (config->GetMarker_StrongBC(Marker_Tag)==true) { nodes->SetSolution_Old(iPoint, Inlet_SpeciesVars[val_marker][iVertex]); @@ -440,25 +437,6 @@ void CSpeciesSolver::SetUniformInlet(const CConfig* config, unsigned short iMark } } -/*--- Currently all walls are zero-flux for the species ---*/ -void CSpeciesSolver::BC_Isothermal_Wall(CGeometry* geometry, CSolver** solver_container, - CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, - unsigned short val_marker) { - BC_Isothermal_Wall_Generic(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); -} - -void CSpeciesSolver::BC_HeatFlux_Wall(CGeometry* geometry, CSolver** solver_container, - CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, - unsigned short val_marker) { - BC_Isothermal_Wall_Generic(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); -} - -void CSpeciesSolver::BC_Isothermal_Wall_Generic(CGeometry* geometry, CSolver** solver_container, - CNumerics* conv_numerics, CNumerics* visc_numerics, - CConfig* config, unsigned short val_marker, bool cht_mode) { -} - - void CSpeciesSolver::BC_Outlet(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, CNumerics* visc_numerics, CConfig* config, unsigned short val_marker) { @@ -591,7 +569,7 @@ void CSpeciesSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta } -void CSpeciesSolver::CustomSourceResidual(CGeometry *geometry, CSolver **solver_container, +void CSpeciesSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { /*--- Pick one numerics object per thread. ---*/ diff --git a/TestCases/py_wrapper/custom_source_buoyancy/run.py b/TestCases/py_wrapper/custom_source_buoyancy/run.py index bba69035b9a6..1653f84ba95e 100644 --- a/TestCases/py_wrapper/custom_source_buoyancy/run.py +++ b/TestCases/py_wrapper/custom_source_buoyancy/run.py @@ -33,7 +33,7 @@ def main(): """ custom source to add buoyancy term. """ - # parallel + # parallel comm = MPI.COMM_WORLD # serial #comm = 0 @@ -85,7 +85,7 @@ def main(): #print("max. number of inner iterations: ",driver.GetNumberInnerIter()); #print("max nr of outer iterations: ",driver.GetNumberOuterIter()); - # is in domain: isdomain = driver.GetNodeDomain(iPoint) + # is in domain: isdomain = driver.GetNodeDomain(iPoint) #for i_vertex in range(n_vertex) #AllSolutions = driver.GetAllSolutions(iSOLVER) Body_Force_Vector = [0.0, -9.81, 0.0] @@ -96,8 +96,6 @@ def main(): Iter = driver.GetNumberInnerIter() print("1. inner iterations = ",Iter) - # set the inner iterations to 1 - driver.SetNumberInnerIter(1) for inner_iter in range(Iter): # set the source term, per point @@ -105,7 +103,7 @@ def main(): for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): #SolutionVector = driver.GetSolutionVector(iSOLVER,i_node) PrimitiveVector = driver.GetPrimitiveVector(iSOLVER,i_node) - DensityInc_i = PrimitiveVector[iDENSITY] + DensityInc_i = PrimitiveVector[iDENSITY] for iDim in range(nDim): custom_source_vector[iDim+1] = -(DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py index d78ce1c1679c..bb744142ad5f 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/run.py +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -30,13 +30,12 @@ from mpi4py import MPI import numpy as np -# Import mpi4py for parallel run -if options.with_MPI == True: - from mpi4py import MPI - comm = MPI.COMM_WORLD - rank = comm.Get_rank() -else: - comm = 0 +# with mpi: +from mpi4py import MPI +comm = MPI.COMM_WORLD +rank = comm.Get_rank() +# without mpi: +# comm = 0 # flame temperature of the methane-air mixture (phi=0.5, P=5) Tf = 1777 @@ -84,11 +83,11 @@ def SetInitialSpecies(SU2Driver): for iPoint in range(SU2Driver.GetNumberNodes() - SU2Driver.GetNumberHaloNodes()): coord = allCoords.Get(iPoint) C = initC(coord) - # now update the initial condition for the species + # now update the initial condition for the species SU2Driver.SetSolutionVector(iSPECIESSOLVER, iPoint, [C]) # ################################################################## # -# Temperature is an algebraic function of c +# Temperature is an algebraic function of c # ################################################################## # def update_temperature(SU2Driver, iPoint): # first, get the progress variable @@ -106,7 +105,7 @@ def update_temperature(SU2Driver, iPoint): # ################################################################## # -# Source term according to Zimont +# Source term according to Zimont # ################################################################## # def zimont(SU2Driver, iPoint): @@ -141,7 +140,7 @@ def zimont(SU2Driver, iPoint): return Sc # ################################################################## # -# Get the list of solver variable names +# Get the list of solver variable names # ################################################################## # def getsolvar(SU2Driver): primindex = SU2Driver.GetPrimitiveIndices() @@ -155,7 +154,7 @@ def getsolvar(SU2Driver): return varindex # ################################################################## # -# Main routine +# Main routine # ################################################################## # def main(): @@ -223,7 +222,7 @@ def main(): driver.Preprocess(inner_iter) driver.Run() - # set the source term, per point, + # set the source term, per point, for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): # add source term: # default TFC of Zimont: rho*Sc = rho_u * U_t * grad(c) From da794f40a72bbae340f4370151f487ffeca35d99 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Fri, 11 Jul 2025 00:47:37 +0200 Subject: [PATCH 41/61] create matrixview --- SU2_CFD/include/drivers/CDriverBase.hpp | 27 ++++-------- .../include/solvers/CFVMFlowSolverBase.hpp | 36 ++-------------- .../include/solvers/CFVMFlowSolverBase.inl | 1 - SU2_CFD/include/solvers/CSolver.hpp | 20 +-------- SU2_CFD/include/solvers/CSpeciesSolver.hpp | 35 --------------- SU2_CFD/include/variables/CVariable.hpp | 43 +++++++++++++++++++ SU2_CFD/src/solvers/CIncEulerSolver.cpp | 2 +- SU2_CFD/src/solvers/CSpeciesSolver.cpp | 6 +-- SU2_CFD/src/variables/CVariable.cpp | 12 ++++++ .../py_wrapper/custom_source_buoyancy/run.py | 2 +- .../py_wrapper/turbulent_premixed_psi/psi.cfg | 15 ++++--- .../py_wrapper/turbulent_premixed_psi/run.py | 37 +++++++++------- 12 files changed, 102 insertions(+), 134 deletions(-) diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index 49fbf56c5510..4c101598d876 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -452,6 +452,15 @@ class CDriverBase { return CPyWrapperMatrixView(solver->GetNodes()->GetSolution(), "Solution of " + solver->GetSolverName(), false); } + /*! + * \brief Get a read/write view of the usrr defined source on all mesh nodes of a solver. + */ + inline CPyWrapperMatrixView UserDefinedSource(unsigned short iSolver) { + auto* solver = GetSolverAndCheckMarker(iSolver); + return CPyWrapperMatrixView( + solver->GetNodes()->GetUserDefinedSource(), "User Defined Source of " + solver->GetSolverName(), false); + } + /*! * \brief Get a read/write view of the current solution on the mesh nodes of a marker. */ @@ -759,24 +768,6 @@ class CDriverBase { } } - /*! - * \brief Set the array of variables for the source in the point - * \param[in] iSolver - Solver index. - * \param[in] iPoint - Point index. - * \param[in] values - Vector values of the source term. - */ - void SetPointCustomSource(unsigned short iSolver, unsigned long iPoint, std::vector values) { - auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; - solver->SetCustomPointSource(iPoint, values); - } - - /*! - * \brief Get the solution vector in a point for a specific solver - * \param[in] iSolver - Solver index. - * \param[in] iPoint - Point index. - * \param[out] solutionvector - Vector values of the solution. - */ - /// \} protected: diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp index fb1c2920766b..52ab8c852883 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp @@ -170,7 +170,6 @@ class CFVMFlowSolverBase : public CSolver { vector > Inlet_Ptotal; /*!< \brief Value of the Total P. */ vector > Inlet_Ttotal; /*!< \brief Value of the Total T. */ vector Inlet_FlowDir; /*!< \brief Value of the Flow Direction. */ - su2activematrix PointSource; /*!< \brief Value of the Flow Direction. */ vector > HeatFlux; /*!< \brief Heat transfer coefficient for each boundary and vertex. */ vector > HeatFluxTarget; /*!< \brief Heat transfer coefficient for each boundary and vertex. */ vector CharacPrimVar; /*!< \brief Value of the characteristic variables at each boundary. */ @@ -339,7 +338,7 @@ inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- Compute the residual for this control volume and subtract. ---*/ for (iVar = 0; iVar < nVar; iVar++) { - LinSysRes(iPoint, iVar) += PointSource(iPoint, iVar) * Volume; + LinSysRes(iPoint, iVar) += nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; } } END_SU2_OMP_FOR @@ -2182,17 +2181,7 @@ inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_contain return Inlet_FlowDir[val_marker][val_vertex][val_dim]; } - /*! - * \brief A component of the unit vector representing the flow direction at an inlet boundary. - * \param[in] val_marker - Surface marker where the flow direction is evaluated - * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is evaluated - * \param[in] val_dim - The component of the flow direction unit vector to be evaluated - * \return Component of a unit vector representing the flow direction. - */ - inline su2double GetCustomPointSource(unsigned long val_point, - unsigned short val_var) const final { - return PointSource[val_point][val_var]; - } + /*! * \brief Set the value of the total temperature at an inlet boundary. @@ -2247,26 +2236,7 @@ inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_contain Inlet_FlowDir[val_marker][val_vertex][val_dim] = val_flowdir; } - /*! - * \brief Set a component of the unit vector representing the flow direction at an inlet boundary. - * \param[in] val_marker - Surface marker where the flow direction is set. - * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is set. - * \param[in] val_dim - The component of the flow direction unit vector to be set - * \param[in] val_flowdir - Component of a unit vector representing the flow direction. - */ - inline void SetCustomPointSource(unsigned long val_point, - vector val_source) final { - /*--- Since this call can be accessed indirectly using python, do some error - * checking to prevent segmentation faults ---*/ - if (val_point > nPointDomain) - SU2_MPI::Error("Out-of-bounds point index used on solver.", CURRENT_FUNCTION); - else if (val_source.size() > nVar) - SU2_MPI::Error("Out-of-bounds source size used on solver.", CURRENT_FUNCTION); - else { - for (size_t iVar=0; iVar < val_source.size(); iVar++) - PointSource[val_point][iVar] = val_source[iVar]; - } - } + /*! * \brief Update the multi-grid structure for the customized boundary conditions. diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl index 426bbb87f386..49ca3fdc8f91 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.inl @@ -123,7 +123,6 @@ void CFVMFlowSolverBase::Allocate(const CConfig& config) { /*--- Store the value of the Flow direction at the inlet BC ---*/ AllocVectorOfMatrices(nVertex, nDim, Inlet_FlowDir); - PointSource.resize(nPointDomain, nVar) = su2double(0.0); /*--- Force definition and coefficient arrays for all of the markers ---*/ diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index 5a2f8a67bc62..5f15968e3c13 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -2852,15 +2852,7 @@ class CSolver { inline virtual su2double GetInletFlowDir(unsigned short val_marker, unsigned long val_vertex, unsigned short val_dim) const { return 0; } - /*! - * \brief A virtual member - * \param[in] val_marker - Surface marker where the flow direction is evaluated - * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is evaluated - * \param[in] val_dim - The component of the flow direction unit vector to be evaluated - * \return Component of a unit vector representing the flow direction. - */ - inline virtual su2double GetCustomPointSource(unsigned long val_point, - unsigned short val_var) const { return 0; } + /*! * \brief A virtual member * \param[in] val_marker - Surface marker where the total temperature is set. @@ -2892,15 +2884,7 @@ class CSolver { unsigned long val_vertex, unsigned short val_dim, su2double val_flowdir) { } - /*! - * \brief A virtual member - * \param[in] val_marker - Surface marker where the flow direction is set. - * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is set. - * \param[in] val_dim - The component of the flow direction unit vector to be set - * \param[in] val_flowdir - Component of a unit vector representing the flow direction. - */ - inline virtual void SetCustomPointSource(unsigned long val_Point, - vector val_source) { } + /*! * \brief Updates the components of the farfield velocity vector. */ diff --git a/SU2_CFD/include/solvers/CSpeciesSolver.hpp b/SU2_CFD/include/solvers/CSpeciesSolver.hpp index 47829debdae6..6cb40e8fba81 100644 --- a/SU2_CFD/include/solvers/CSpeciesSolver.hpp +++ b/SU2_CFD/include/solvers/CSpeciesSolver.hpp @@ -40,7 +40,6 @@ class CSpeciesSolver : public CScalarSolver { protected: unsigned short Inlet_Position; /*!< \brief Column index for scalar variables in inlet files. */ vector Inlet_SpeciesVars; /*!< \brief Species variables at inlet profiles. */ - su2activematrix SpeciesPointSource; /*!< \brief User defined source term. */ public: /*! @@ -195,38 +194,4 @@ class CSpeciesSolver : public CScalarSolver { geometry, solver_container, conv_numerics, visc_numerics, config); } - /*! - * \brief Set a component of the unit vector representing the flow direction at an inlet boundary. - * \param[in] val_marker - Surface marker where the flow direction is set. - * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is set. - * \param[in] val_dim - The component of the flow direction unit vector to be set - * \param[in] val_flowdir - Component of a unit vector representing the flow direction. - */ - inline void SetCustomPointSource(unsigned long val_point, - vector val_source) final { - /*--- Since this call can be accessed indirectly using python, do some error - * checking to prevent segmentation faults ---*/ - if (val_point > nPointDomain) - SU2_MPI::Error("Out-of-bounds point index used on solver.", CURRENT_FUNCTION); - else if (val_source.size() > nVar) - SU2_MPI::Error("Out-of-bounds source size used on solver.", CURRENT_FUNCTION); - else { - for (size_t iVar=0; iVar < val_source.size(); iVar++) { - SpeciesPointSource[val_point][iVar] = val_source[iVar]; - } - } - } - -/*! - * \brief A component of the unit vector representing the flow direction at an inlet boundary. - * \param[in] val_marker - Surface marker where the flow direction is evaluated - * \param[in] val_vertex - Vertex of the marker val_marker where the flow direction is evaluated - * \param[in] val_dim - The component of the flow direction unit vector to be evaluated - * \return Component of a unit vector representing the flow direction. - */ - inline su2double GetCustomPointSource(unsigned long val_point, - unsigned short val_var) const final { - return SpeciesPointSource[val_point][val_var]; - } - }; diff --git a/SU2_CFD/include/variables/CVariable.hpp b/SU2_CFD/include/variables/CVariable.hpp index 3ff773038e11..9df0c069812c 100644 --- a/SU2_CFD/include/variables/CVariable.hpp +++ b/SU2_CFD/include/variables/CVariable.hpp @@ -55,6 +55,8 @@ class CVariable { MatrixType Solution; /*!< \brief Solution of the problem. */ MatrixType Solution_Old; /*!< \brief Old solution of the problem R-K. */ + MatrixType UserDefinedSource; /*!< \brief User Defined Source of the problem. */ + MatrixType External; /*!< \brief External (outer) contribution in discrete adjoint multizone problems. */ su2vector Non_Physical; /*!< \brief Non-physical points in the solution (force first order). */ @@ -289,6 +291,11 @@ class CVariable { */ void Set_Solution_time_n1(); + /*! + * \brief Set the variable solution at time n-1. + */ + void Set_UserDefinedSource(); + /*! * \brief Set the variable solution at time n. * \param[in] iPoint - Point index. @@ -306,6 +313,15 @@ class CVariable { Solution_time_n1(iPoint,iVar) = val_sol[iVar]; } + /*! + * \brief Set the variable solution at time n-1. + * \param[in] iPoint - Point index. + */ + inline void Set_UserDefinedSource(unsigned long iPoint, const su2double* val_sol) { + for (unsigned long iVar = 0; iVar < nVar; iVar++) + UserDefinedSource(iPoint,iVar) = val_sol[iVar]; + } + /*! * \brief Set the variable solution at time n. * \param[in] iPoint - Point index. @@ -322,6 +338,14 @@ class CVariable { Solution_time_n1(iPoint,iVar) = val_sol; } + /*! + * \brief Set the variable solution at time n-1. + * \param[in] iPoint - Point index. + */ + inline void Set_UserDefinedSource(unsigned long iPoint, unsigned long iVar, su2double val_sol) { + UserDefinedSource(iPoint,iVar) = val_sol; + } + /*! * \brief Virtual Member. Specify a vector to set the velocity components of the solution. * Multiplied by density for compressible cases. @@ -485,6 +509,20 @@ class CVariable { */ inline su2double *GetSolution(unsigned long iPoint) { return Solution[iPoint]; } + /*! + * \brief Get the entire solution of the problem. + * \return Reference to the solution matrix. + */ + inline const MatrixType& GetUserDefinedSource() const { return UserDefinedSource; } + inline MatrixType& GetUserDefinedSource() { return UserDefinedSource; } + + /*! + * \brief Get the solution of the problem. + * \param[in] iPoint - Point index. + * \return Pointer to the solution vector. + */ + inline su2double *GetUserDefinedSource(unsigned long iPoint) { return UserDefinedSource[iPoint]; } + /*! * \brief Get the old solution of the problem (Runge-Kutta method) * \param[in] iPoint - Point index. @@ -2168,6 +2206,11 @@ class CVariable { */ void RegisterSolution_time_n1(); + /*! + * \brief Register the variables in the user defined source array as input/output variable. + */ + void RegisterUserDefinedSource(); + /*! * \brief Set the adjoint values of the solution. * \param[in] adj_sol - The adjoint values of the solution. diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index ed94061412bd..0950f3f62897 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -1811,7 +1811,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont } } - //Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); } diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index fc6dfd9acc76..552ff46fbb6c 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -110,9 +110,6 @@ void CSpeciesSolver::Initialize(CGeometry* geometry, CConfig* config, unsigned s nDim = geometry->GetnDim(); - SpeciesPointSource.resize(nPointDomain,nVar) = su2double(0.0); - - if (iMesh == MESH_0 || config->GetMGCycle() == FULLMG_CYCLE) { /*--- Define some auxiliary vector related with the residual ---*/ @@ -587,10 +584,9 @@ void CSpeciesSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solve /*--- Get control volume size. ---*/ su2double Volume = geometry->nodes->GetVolume(iPoint); - /*--- Compute the residual for this control volume and subtract. ---*/ for (iVar = 0; iVar < nVar; iVar++) { - LinSysRes[iPoint*nVar+iVar] -= SpeciesPointSource[iPoint][iVar] * Volume; + LinSysRes(iPoint,iVar) -= nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; } } END_SU2_OMP_FOR diff --git a/SU2_CFD/src/variables/CVariable.cpp b/SU2_CFD/src/variables/CVariable.cpp index 3370fbb7a104..af8145e8a608 100644 --- a/SU2_CFD/src/variables/CVariable.cpp +++ b/SU2_CFD/src/variables/CVariable.cpp @@ -64,6 +64,10 @@ CVariable::CVariable(unsigned long npoint, unsigned long ndim, unsigned long nva if (config->GetTime_Marching() != TIME_MARCHING::STEADY) Solution_time_n1.resize(nPoint,nVar) = su2double(0.0); + /*--- User defined source terms ---*/ + UserDefinedSource.resize(nPoint,nVar) = su2double(0.0); + + if (config->GetDiscrete_Adjoint()) { if (adjoint && config->GetMultizone_Problem()) External.resize(nPoint,nVar) = su2double(0.0); @@ -98,6 +102,11 @@ void CVariable::Set_Solution_time_n1() { parallelCopy(Solution_time_n.size(), Solution_time_n.data(), Solution_time_n1.data()); } +void CVariable::Set_UserDefinedSource() { + assert(UserDefinedSource.size() == UserDefinedSource.size()); + parallelCopy(UserDefinedSource.size(), UserDefinedSource.data(), UserDefinedSource.data()); +} + void CVariable::Set_BGSSolution_k() { assert(Solution_BGS_k.size() == Solution.size()); parallelCopy(Solution.size(), Solution.data(), Solution_BGS_k.data()); @@ -127,3 +136,6 @@ void CVariable::RegisterSolution_time_n() { void CVariable::RegisterSolution_time_n1() { RegisterContainer(true, Solution_time_n1); } +void CVariable::RegisterUserDefinedSource() { + RegisterContainer(true, UserDefinedSource); +} diff --git a/TestCases/py_wrapper/custom_source_buoyancy/run.py b/TestCases/py_wrapper/custom_source_buoyancy/run.py index 1653f84ba95e..d696f0a13bb5 100644 --- a/TestCases/py_wrapper/custom_source_buoyancy/run.py +++ b/TestCases/py_wrapper/custom_source_buoyancy/run.py @@ -108,7 +108,7 @@ def main(): for iDim in range(nDim): custom_source_vector[iDim+1] = -(DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref - driver.SetPointCustomSource(iSOLVER, i_node, custom_source_vector) + #driver.SetPointCustomSource(iSOLVER, i_node, custom_source_vector) print(" *** inner iteration:",inner_iter) driver.Preprocess(inner_iter) diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg b/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg index 284fc1ca3ce8..1a4195cd22d2 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg +++ b/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg @@ -69,22 +69,25 @@ INLET_MATCHING_TOLERANCE=1e-4 INLET_FILENAME= inlet.dat %INLET_INTERPOLATION_FUNCTION= LINEAR_1D INC_INLET_TYPE= VELOCITY_INLET -INC_INLET_DAMPING= 0.01 +INC_INLET_DAMPING= 0.1 MARKER_INLET= ( inlet, 673, 40.0, 1.0, 0.0, 0.0) MARKER_INLET_TURBULENT = (inlet, 0.10, 15) MARKER_INLET_SPECIES= (inlet, 0.0) % INC_OUTLET_TYPE= PRESSURE_OUTLET -INC_OUTLET_DAMPING= 0.01 +INC_OUTLET_DAMPING= 0.1 MARKER_OUTLET= ( outlet, 0.0 ) % % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES % -CFL_NUMBER= 1.0 +CFL_NUMBER= 10.0 CFL_REDUCTION_SPECIES= 1.0 CFL_REDUCTION_TURB= 1.0 +CFL_ADAPT= YES +CFL_ADAPT_PARAM= ( 0.95, 1.01, 1.0, 250, 1.0e-4, 0) + % ITER= 1 % @@ -146,7 +149,7 @@ SCREEN_OUTPUT= INNER_ITER WALL_TIME \ RMS_PRESSURE RMS_VELOCITY-X RMS_VELOCITY-Y RMS_TKE RMS_DISSIPATION RMS_SPECIES_0 \ LINSOL_ITER LINSOL_RESIDUAL \ LINSOL_ITER_TURB LINSOL_RESIDUAL_TURB \ - LINSOL_ITER_SPECIES LINSOL_RESIDUAL_SPECIES + LINSOL_ITER_SPECIES LINSOL_RESIDUAL_SPECIES AVG_CFL SCREEN_WRT_FREQ_INNER= 1 % HISTORY_OUTPUT= ITER RMS_RES LINSOL SPECIES_COEFF SPECIES_COEFF_SURF @@ -154,11 +157,11 @@ CONV_FILENAME= history MARKER_ANALYZE= gas_inlet, air_axial_inlet, outlet MARKER_ANALYZE_AVERAGE= AREA % -OUTPUT_FILES= RESTART_ASCII, PARAVIEW_MULTIBLOCK +OUTPUT_FILES= RESTART, PARAVIEW_MULTIBLOCK VOLUME_OUTPUT= RESIDUAL, PRIMITIVE OUTPUT_WRT_FREQ= 100 % -READ_BINARY_RESTART= NO +READ_BINARY_RESTART= YES RESTART_FILENAME= restart SOLUTION_FILENAME= solution % diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py index bb744142ad5f..b20c96735365 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/run.py +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -84,7 +84,8 @@ def SetInitialSpecies(SU2Driver): coord = allCoords.Get(iPoint) C = initC(coord) # now update the initial condition for the species - SU2Driver.SetSolutionVector(iSPECIESSOLVER, iPoint, [C]) + #SU2Driver.SetSolutionVector(iSPECIESSOLVER, iPoint, [C]) + SU2Driver.Solution(iSPECIESSOLVER).Set(iPoint,0,C) # ################################################################## # # Temperature is an algebraic function of c @@ -93,15 +94,13 @@ def update_temperature(SU2Driver, iPoint): # first, get the progress variable iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] # Note: returns a list - C = SU2Driver.GetSolutionVector(iSPECIESSOLVER, iPoint) - T = Tu*(1-C[0]) + Tf*C[0] + C = SU2Driver.Solution(iSPECIESSOLVER)(iPoint,0) + T = Tu*(1-C) + Tf*C iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] - solvar = list(SU2Driver.GetSolutionVector(iFLOWSOLVER, iPoint)) # the list with names solindex = getsolvar(SU2Driver) iTEMP = solindex.get("TEMPERATURE") - solvar[iTEMP] = T - SU2Driver.SetSolutionVector(iFLOWSOLVER, iPoint, solvar) + SU2Driver.Solution(iFLOWSOLVER).Set(iPoint,iTEMP,T) # ################################################################## # @@ -110,23 +109,22 @@ def update_temperature(SU2Driver, iPoint): def zimont(SU2Driver, iPoint): iSSTSOLVER = SU2Driver.GetSolverIndices()['SST'] - tke, dissipation = SU2Driver.GetSolutionVector(iSSTSOLVER,iPoint) + #tke, dissipation = SU2Driver.GetSolutionVector(iSSTSOLVER,iPoint) + tke, dissipation = SU2Driver.Solution(iSSTSOLVER)(iPoint) iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] gradc = SU2Driver.GetGradient(iSPECIESSOLVER,iPoint,0) iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] primindex = SU2Driver.GetPrimitiveIndices() - primvar = list(SU2Driver.GetPrimitiveVector(iFLOWSOLVER, iPoint)) - iDENSITY = primindex.get("DENSITY") iMU = primindex.get("LAMINAR_VISCOSITY") # laminar burning velocity of methane-air at phi=0.5, P=5 Slu = 0.232 - rho = primvar[iDENSITY] - mu = primvar[iMU] + rho = SU2Driver.Primitives()(iPoint,iDENSITY) + mu = SU2Driver.Primitives()(iPoint,iMU) nu=mu/rho # Turbulent Flamespeed Closure with Dinkelacker correction up = np.sqrt((2.0/3.0) * tke ) @@ -217,8 +215,9 @@ def main(): sys.stdout.flush() # run N iterations - for inner_iter in range(5): - + for inner_iter in range(1000): + if (rank==0): + print("python iteration ", inner_iter) driver.Preprocess(inner_iter) driver.Run() @@ -226,8 +225,14 @@ def main(): for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): # add source term: # default TFC of Zimont: rho*Sc = rho_u * U_t * grad(c) - S = [zimont(driver,i_node)] - driver.SetPointCustomSource(iSPECIESSOLVER, i_node,S) + S = zimont(driver,i_node) + driver.UserDefinedSource(iSPECIESSOLVER).Set(i_node,0,S) + + + #S = [zimont(driver,i_node)] + #driver.SetPointCustomSource(iSPECIESSOLVER, i_node,S) + + # for the update of temperature, we need to update also the halo nodes for i_node in range(driver.GetNumberNodes()): @@ -237,7 +242,7 @@ def main(): driver.Postprocess() driver.Update() # Monitor the solver and output solution to file if required - driver.Monitor(inner_iter) + #driver.Monitor(inner_iter) # Output the solution to file driver.Output(inner_iter) From 2756cfb41f142298dd2a1827abd4222637599a15 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Fri, 11 Jul 2025 13:35:51 +0200 Subject: [PATCH 42/61] test, place custom_residual in CSolver --- Common/include/CConfig.hpp | 7 ++ Common/src/CConfig.cpp | 3 + .../include/solvers/CFVMFlowSolverBase.hpp | 42 +++++------ SU2_CFD/include/solvers/CSolver.hpp | 39 ++++++++-- SU2_CFD/include/solvers/CSpeciesSolver.hpp | 4 +- SU2_CFD/src/integration/CIntegration.cpp | 2 +- SU2_CFD/src/solvers/CEulerSolver.cpp | 43 +++++++---- SU2_CFD/src/solvers/CIncEulerSolver.cpp | 52 ++++++++++---- SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 1 + SU2_CFD/src/solvers/CRadP1Solver.cpp | 5 ++ SU2_CFD/src/solvers/CSolver.cpp | 29 ++++++++ .../src/solvers/CSpeciesFlameletSolver.cpp | 35 +++++++-- SU2_CFD/src/solvers/CSpeciesSolver.cpp | 72 +++++++++++++------ SU2_CFD/src/solvers/CTransLMSolver.cpp | 6 ++ SU2_CFD/src/solvers/CTurbSASolver.cpp | 6 ++ SU2_CFD/src/solvers/CTurbSSTSolver.cpp | 5 ++ 16 files changed, 269 insertions(+), 82 deletions(-) diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index eb6beab278d1..875dfb34fe82 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -707,6 +707,7 @@ class CConfig { Wrt_Restart_Overwrite, /*!< \brief Overwrite restart files or append iteration number.*/ Wrt_Surface_Overwrite, /*!< \brief Overwrite surface output files or append iteration number.*/ Wrt_Volume_Overwrite, /*!< \brief Overwrite volume output files or append iteration number.*/ + PyCustom_Source, /*!< \brief Use a user defined custom source term .*/ Restart_Flow; /*!< \brief Restart flow solution for adjoint and linearized problems. */ unsigned short nMarker_Monitoring, /*!< \brief Number of markers to monitor. */ nMarker_Designing, /*!< \brief Number of markers for the objective function. */ @@ -3087,6 +3088,12 @@ class CConfig { */ unsigned short GetnMarker_PyCustom(void) const { return nMarker_PyCustom; } + /*! + * \brief Get the Python custom source term activation. + * \return Custom source term is active or not. + */ + bool GetPyCustom_Source(void) const { return PyCustom_Source; } + /*! * \brief Get the total number of moving markers. * \return Total number of moving markers. diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index d35da105ffbd..6eee6ee0281a 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -1548,6 +1548,9 @@ void CConfig::SetConfig_Options() { /*!\brief MARKER_PYTHON_CUSTOM\n DESCRIPTION: Python customizable marker(s) \ingroup Config*/ addStringListOption("MARKER_PYTHON_CUSTOM", nMarker_PyCustom, Marker_PyCustom); + /*!\brief PYTHON_CUSTOM_SOURCE\n DESCRIPTION: Python custom source \ingroup Config*/ + addBoolOption("PYTHON_CUSTOM_SOURCE", PyCustom_Source, false); + /*!\brief MARKER_WALL_FUNCTIONS\n DESCRIPTION: Viscous wall markers for which wall functions must be applied. Format: (Wall function marker, wall function type, ...) \ingroup Config*/ addWallFunctionOption("MARKER_WALL_FUNCTIONS", nMarker_WallFunctions, Marker_WallFunctions, diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp index 52ab8c852883..4dabb50875c1 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp @@ -316,36 +316,36 @@ class CFVMFlowSolverBase : public CSolver { } -inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { +// inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, +// CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { - /*--- Pick one numerics object per thread. ---*/ - CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; +// /*--- Pick one numerics object per thread. ---*/ +// CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; - unsigned short iVar; - unsigned long iPoint; - AD::StartNoSharedReading(); +// unsigned short iVar; +// unsigned long iPoint; +// AD::StartNoSharedReading(); - SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { +// SU2_OMP_FOR_STAT(omp_chunk_size) +// for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - /*--- Load the volume of the dual mesh cell ---*/ +// /*--- Load the volume of the dual mesh cell ---*/ - numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); +// numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - /*--- Get control volume size. ---*/ - su2double Volume = geometry->nodes->GetVolume(iPoint); +// /*--- Get control volume size. ---*/ +// su2double Volume = geometry->nodes->GetVolume(iPoint); - /*--- Compute the residual for this control volume and subtract. ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - LinSysRes(iPoint, iVar) += nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; - } - } - END_SU2_OMP_FOR +// /*--- Compute the residual for this control volume and subtract. ---*/ +// for (iVar = 0; iVar < nVar; iVar++) { +// LinSysRes(iPoint, iVar) += nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; +// } +// } +// END_SU2_OMP_FOR - AD::EndNoSharedReading(); +// AD::EndNoSharedReading(); -} +// } /*! diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index 5f15968e3c13..03982f328773 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -1573,11 +1573,11 @@ class CSolver { * \param[in] config - Definition of the particular problem. * \param[in] iMesh - Index of the mesh in multigrid computations. */ - inline virtual void Custom_Source_Residual(CGeometry *geometry, - CSolver **solver_container, - CNumerics **numerics_container, - CConfig *config, - unsigned short iMesh) { } + // inline virtual void Custom_Source_Residual(CGeometry *geometry, + // CSolver **solver_container, + // CNumerics **numerics_container, + // CConfig *config, + // unsigned short iMesh) { } /*! * \brief A virtual member. @@ -4346,6 +4346,35 @@ class CSolver { END_SU2_OMP_FOR } +/*--- Why not do this? ---*/ +inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, + CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { + + /*--- Pick one numerics object per thread. ---*/ + CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; + + unsigned short iVar; + unsigned long iPoint; + AD::StartNoSharedReading(); + + SU2_OMP_FOR_STAT(omp_chunk_size) + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Load the volume of the dual mesh cell ---*/ + numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + + /*--- Get control volume size. ---*/ + su2double Volume = geometry->nodes->GetVolume(iPoint); + /*--- Compute the residual for this control volume and subtract. ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + LinSysRes(iPoint,iVar) -= base_nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; + } + } + END_SU2_OMP_FOR + + AD::EndNoSharedReading(); +} + protected: /*! * \brief Allocate the memory for the verification solution, if necessary. diff --git a/SU2_CFD/include/solvers/CSpeciesSolver.hpp b/SU2_CFD/include/solvers/CSpeciesSolver.hpp index 6cb40e8fba81..c53357d7bb17 100644 --- a/SU2_CFD/include/solvers/CSpeciesSolver.hpp +++ b/SU2_CFD/include/solvers/CSpeciesSolver.hpp @@ -170,8 +170,8 @@ class CSpeciesSolver : public CScalarSolver { * \param[in] config - Definition of the particular problem. * \param[in] iMesh - Index of the mesh in multigrid computations. */ - void Custom_Source_Residual(CGeometry* geometry, CSolver** solver_container, CNumerics** numerics_container, CConfig* config, - unsigned short iMesh) override; + // void Custom_Source_Residual(CGeometry* geometry, CSolver** solver_container, CNumerics** numerics_container, CConfig* config, + // unsigned short iMesh) override; /*! diff --git a/SU2_CFD/src/integration/CIntegration.cpp b/SU2_CFD/src/integration/CIntegration.cpp index 706f63860b14..040ec72e9887 100644 --- a/SU2_CFD/src/integration/CIntegration.cpp +++ b/SU2_CFD/src/integration/CIntegration.cpp @@ -64,7 +64,7 @@ void CIntegration::Space_Integration(CGeometry *geometry, solver_container[MainSolver]->Source_Residual(geometry, solver_container, numerics, config, iMesh); /*--- Compute custom (python wrapper) source term residuals ---*/ - solver_container[MainSolver]->Custom_Source_Residual(geometry, solver_container, numerics, config, iMesh); + //solver_container[MainSolver]->Custom_Source_Residual(geometry, solver_container, numerics, config, iMesh); /*--- Add viscous and convective residuals, and compute the Dual Time Source term ---*/ diff --git a/SU2_CFD/src/solvers/CEulerSolver.cpp b/SU2_CFD/src/solvers/CEulerSolver.cpp index 15f5a227c94a..8d6fee155517 100644 --- a/SU2_CFD/src/solvers/CEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CEulerSolver.cpp @@ -2053,15 +2053,12 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- Pick one numerics object per thread. ---*/ CNumerics* numerics = numerics_container[SOURCE_FIRST_TERM + omp_get_thread_num()*MAX_TERMS]; - unsigned short iVar; - unsigned long iPoint; - if (body_force) { /*--- Loop over all points ---*/ AD::StartNoSharedReading(); SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { /*--- Load the conservative variables ---*/ numerics->SetConservative(nodes->GetSolution(iPoint), @@ -2091,7 +2088,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- Loop over all points ---*/ AD::StartNoSharedReading(); SU2_OMP_FOR_DYN(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { /*--- Load the conservative variables ---*/ numerics->SetConservative(nodes->GetSolution(iPoint), @@ -2124,7 +2121,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- loop over points ---*/ AD::StartNoSharedReading(); SU2_OMP_FOR_DYN(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { /*--- Set solution ---*/ numerics->SetConservative(nodes->GetSolution(iPoint), nodes->GetSolution(iPoint)); @@ -2177,7 +2174,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- loop over points ---*/ SU2_OMP_FOR_DYN(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { /*--- Set solution ---*/ numerics->SetConservative(nodes->GetSolution(iPoint), nodes->GetSolution(iPoint)); @@ -2200,13 +2197,13 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- loop over points ---*/ SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { /*--- Get control volume ---*/ su2double Volume = geometry->nodes->GetVolume(iPoint); /*--- Get stored time spectral source term and add to residual ---*/ - for (iVar = 0; iVar < nVar; iVar++) { + for (auto iVar = 0; iVar < nVar; iVar++) { LinSysRes(iPoint,iVar) += Volume * nodes->GetHarmonicBalance_Source(iPoint,iVar); } } @@ -2223,7 +2220,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- set vorticity magnitude as auxilliary variable ---*/ SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPoint; iPoint++) { + for (auto iPoint = 0; iPoint < nPoint; iPoint++) { const su2double VorticityMag = max(GeometryToolbox::Norm(3, nodes->GetVorticity(iPoint)), 1e-12); nodes->SetAuxVar(iPoint, 0, VorticityMag); } @@ -2233,7 +2230,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain SetAuxVar_Gradient_GG(geometry, config); SU2_OMP_FOR_DYN(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { second_numerics->SetPrimitive(nodes->GetPrimitive(iPoint), nullptr); second_numerics->SetVorticity(nodes->GetVorticity(iPoint), nullptr); second_numerics->SetAuxVarGrad(nodes->GetAuxVarGradient(iPoint), nullptr); @@ -2260,7 +2257,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- Loop over points ---*/ SU2_OMP_FOR_DYN(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { /*--- Get control volume size. ---*/ su2double Volume = geometry->nodes->GetVolume(iPoint); @@ -2273,7 +2270,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain VerificationSolution->GetMMSSourceTerm(coor, time, sourceMan.data()); /*--- Compute the residual for this control volume and subtract. ---*/ - for (iVar = 0; iVar < nVar; iVar++) { + for (auto iVar = 0; iVar < nVar; iVar++) { LinSysRes(iPoint,iVar) -= sourceMan[iVar]*Volume; } } @@ -2281,6 +2278,26 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain } } + /*--- Custom user defined source term (from the python wrapper) ---*/ + if (config->GetPyCustom_Source() ) { + SU2_OMP_FOR_STAT(omp_chunk_size) + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Load the volume of the dual mesh cell ---*/ + + numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + + /*--- Get control volume size. ---*/ + su2double Volume = geometry->nodes->GetVolume(iPoint); + + /*--- Compute the residual for this control volume and subtract. ---*/ + for (auto iVar = 0; iVar < nVar; iVar++) { + LinSysRes(iPoint, iVar) += nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; + } + } + END_SU2_OMP_FOR + } + AD::EndNoSharedReading(); } diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index 0950f3f62897..ff5a1f3907ab 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -1381,9 +1381,6 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont /*--- Pick one numerics object per thread. ---*/ CNumerics* numerics = numerics_container[SOURCE_FIRST_TERM + omp_get_thread_num()*MAX_TERMS]; - unsigned short iVar; - unsigned long iPoint; - const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); const bool rotating_frame = config->GetRotating_Frame(); const bool axisymmetric = config->GetAxisymmetric(); @@ -1404,7 +1401,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont /*--- Loop over all points ---*/ SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { /*--- Load the conservative variables ---*/ @@ -1437,7 +1434,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont /*--- Loop over all points ---*/ SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { /*--- Load the conservative variables ---*/ @@ -1470,7 +1467,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont /*--- Loop over all points ---*/ SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { /*--- Load the primitive variables ---*/ @@ -1511,7 +1508,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont AD::StartNoSharedReading(); SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPoint; iPoint++) { + for (auto iPoint = 0; iPoint < nPoint; iPoint++) { su2double yCoord = geometry->nodes->GetCoord(iPoint, 1); su2double yVelocity = nodes->GetVelocity(iPoint,1); @@ -1546,7 +1543,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont AD::StartNoSharedReading(); SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { /*--- Conservative variables w/o reconstruction ---*/ @@ -1606,7 +1603,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont CNumerics* second_numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { /*--- Store the radiation source term ---*/ @@ -1654,7 +1651,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont AD::StartNoSharedReading(); SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPoint; iPoint++) { + for (auto iPoint = 0; iPoint < nPoint; iPoint++) { /*--- Set the auxiliary variable, Eddy viscosity mu_t, for this node. ---*/ nodes->SetAuxVar(iPoint, 0, nodes->GetEddyViscosity(iPoint)); } @@ -1703,7 +1700,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont /*--- Loop over all points ---*/ SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { /*--- Load the primitive variables ---*/ numerics->SetPrimitive(nodes->GetPrimitive(iPoint), nullptr); @@ -1747,7 +1744,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont SU2_OMP_FOR_STAT(OMP_MIN_SIZE) for (auto iVertex = 0ul; iVertex < nVertex[iMarker]; iVertex++) { - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); if (!geometry->nodes->GetDomain(iPoint)) continue; @@ -1787,7 +1784,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont /*--- Loop over points ---*/ SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { /*--- Get control volume size. ---*/ su2double Volume = geometry->nodes->GetVolume(iPoint); @@ -1800,7 +1797,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont VerificationSolution->GetMMSSourceTerm(coor, time, sourceMan.data()); /*--- Compute the residual for this control volume and subtract. ---*/ - for (iVar = 0; iVar < nVar; iVar++) { + for (auto iVar = 0; iVar < nVar; iVar++) { LinSysRes[iPoint*nVar+iVar] -= sourceMan[iVar]*Volume; } @@ -1811,7 +1808,32 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont } } - Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + /*--- Custom user defined source term (from the python wrapper) ---*/ + if (config->GetPyCustom_Source() ) { + Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + } + + // /*--- Custom user defined source term (from the python wrapper) ---*/ + // if (config->GetPyCustom_Source() ) { + // AD::StartNoSharedReading(); + // SU2_OMP_FOR_STAT(omp_chunk_size) + // for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + + // /*--- Load the volume of the dual mesh cell ---*/ + + // numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + + // /*--- Get control volume size. ---*/ + // su2double Volume = geometry->nodes->GetVolume(iPoint); + + // /*--- Compute the residual for this control volume and subtract. ---*/ + // for (auto iVar = 0; iVar < nVar; iVar++) { + // LinSysRes(iPoint, iVar) += nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; + // } + // } + // END_SU2_OMP_FOR + // AD::EndNoSharedReading(); + // } } diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index af2c19fc7518..b7dede100351 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -894,6 +894,7 @@ void CNEMOEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_con cout << "Chemical: " << eChm_global << endl; cout << "Vib. Relax: " << eVib_global << endl; } + } void CNEMOEulerSolver::ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_container, diff --git a/SU2_CFD/src/solvers/CRadP1Solver.cpp b/SU2_CFD/src/solvers/CRadP1Solver.cpp index 87a1317c7803..15e5364a4876 100644 --- a/SU2_CFD/src/solvers/CRadP1Solver.cpp +++ b/SU2_CFD/src/solvers/CRadP1Solver.cpp @@ -256,6 +256,11 @@ void CRadP1Solver::Source_Residual(CGeometry *geometry, CSolver **solver_contain } + /*--- Custom user defined source term (from the python wrapper) ---*/ + if (config->GetPyCustom_Source() ) { + Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + } + } void CRadP1Solver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, diff --git a/SU2_CFD/src/solvers/CSolver.cpp b/SU2_CFD/src/solvers/CSolver.cpp index f24222ffb2e3..73a848ba5ae8 100644 --- a/SU2_CFD/src/solvers/CSolver.cpp +++ b/SU2_CFD/src/solvers/CSolver.cpp @@ -4368,3 +4368,32 @@ void CSolver::SavelibROM(CGeometry *geometry, CConfig *config, bool converged) { } + +// void CSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, +// CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { + +// /*--- Pick one numerics object per thread. ---*/ +// CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; + +// unsigned short iVar; +// unsigned long iPoint; +// AD::StartNoSharedReading(); + +// SU2_OMP_FOR_STAT(omp_chunk_size) +// for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + +// /*--- Load the volume of the dual mesh cell ---*/ +// numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + +// /*--- Get control volume size. ---*/ +// su2double Volume = geometry->nodes->GetVolume(iPoint); +// /*--- Compute the residual for this control volume and subtract. ---*/ +// for (iVar = 0; iVar < nVar; iVar++) { +// LinSysRes(iPoint,iVar) -= nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; +// } +// } +// END_SU2_OMP_FOR + +// AD::EndNoSharedReading(); + +// } diff --git a/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp b/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp index 4355e3ecb22d..f50743ea56c1 100644 --- a/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp @@ -39,7 +39,7 @@ CSpeciesFlameletSolver::CSpeciesFlameletSolver(CGeometry* geometry, CConfig* con /*--- Retrieve options from config. ---*/ flamelet_config_options = config->GetFlameletParsedOptions(); - + /*--- Dimension of the problem. ---*/ nVar = flamelet_config_options.n_scalars; include_mixture_fraction = (flamelet_config_options.n_control_vars == 3); @@ -225,7 +225,7 @@ void CSpeciesFlameletSolver::SetInitialCondition(CGeometry** geometry, CSolver** if (flame_front_ignition) { prog_burnt = GetBurntProgressVariable(fluid_model_local, scalar_init); - + /*--- Determine if point is above or below the plane, assuming the normal is pointing towards the burned region. ---*/ point_loc = 0.0; @@ -377,6 +377,9 @@ void CSpeciesFlameletSolver::SetPreconditioner(CGeometry* geometry, CSolver** so void CSpeciesFlameletSolver::Source_Residual(CGeometry* geometry, CSolver** solver_container, CNumerics** numerics_container, CConfig* config, unsigned short iMesh) { + + CNumerics* numerics = numerics_container[SOURCE_FIRST_TERM + omp_get_thread_num()*MAX_TERMS]; + SU2_OMP_FOR_STAT(omp_chunk_size) for (auto i_point = 0u; i_point < nPointDomain; i_point++) { /*--- Add source terms from the lookup table directly to the residual. ---*/ @@ -386,8 +389,32 @@ void CSpeciesFlameletSolver::Source_Residual(CGeometry* geometry, CSolver** solv } END_SU2_OMP_FOR - /*--- call the species solver for the shared sources (axisymmetric) ---*/ - CSpeciesSolver::Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + + /*--- Custom user defined source term (from the python wrapper) ---*/ + if (config->GetPyCustom_Source() ) { + Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + + // AD::StartNoSharedReading(); + // SU2_OMP_FOR_STAT(omp_chunk_size) + // for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + + // /*--- Load the volume of the dual mesh cell ---*/ + + // numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + + // /*--- Get control volume size. ---*/ + // su2double Volume = geometry->nodes->GetVolume(iPoint); + + // /*--- Compute the residual for this control volume and subtract. ---*/ + // for (auto iVar = 0; iVar < nVar; iVar++) { + // LinSysRes(iPoint, iVar) += nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; + // } + // } + // END_SU2_OMP_FOR + // AD::EndNoSharedReading(); + } + + } void CSpeciesFlameletSolver::BC_Inlet(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index 552ff46fbb6c..1b7efcb37832 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -563,34 +563,64 @@ void CSpeciesSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta } END_SU2_OMP_FOR } + + /*--- Custom user defined source term (from the python wrapper) ---*/ + if (config->GetPyCustom_Source() ) { + Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + } + +// /*--- Custom user defined source term (from the python wrapper) ---*/ +// if (config->GetPyCustom_Source() ) { +// CNumerics *numerics = numerics_container[SOURCE_FIRST_TERM + omp_get_thread_num()*MAX_TERMS]; + +// AD::StartNoSharedReading(); +// SU2_OMP_FOR_STAT(omp_chunk_size) +// for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + +// /*--- Load the volume of the dual mesh cell ---*/ + +// numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + +// /*--- Get control volume size. ---*/ +// su2double Volume = geometry->nodes->GetVolume(iPoint); + +// /*--- Compute the residual for this control volume and subtract. ---*/ +// for (auto iVar = 0; iVar < nVar; iVar++) { +// LinSysRes(iPoint, iVar) += nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; +// } +// } +// END_SU2_OMP_FOR +// AD::EndNoSharedReading(); +// } + } -void CSpeciesSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { +// void CSpeciesSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, +// CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { - /*--- Pick one numerics object per thread. ---*/ - CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; +// /*--- Pick one numerics object per thread. ---*/ +// CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; - unsigned short iVar; - unsigned long iPoint; - AD::StartNoSharedReading(); +// unsigned short iVar; +// unsigned long iPoint; +// AD::StartNoSharedReading(); - SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { +// SU2_OMP_FOR_STAT(omp_chunk_size) +// for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - /*--- Load the volume of the dual mesh cell ---*/ - numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); +// /*--- Load the volume of the dual mesh cell ---*/ +// numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - /*--- Get control volume size. ---*/ - su2double Volume = geometry->nodes->GetVolume(iPoint); - /*--- Compute the residual for this control volume and subtract. ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - LinSysRes(iPoint,iVar) -= nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; - } - } - END_SU2_OMP_FOR +// /*--- Get control volume size. ---*/ +// su2double Volume = geometry->nodes->GetVolume(iPoint); +// /*--- Compute the residual for this control volume and subtract. ---*/ +// for (iVar = 0; iVar < nVar; iVar++) { +// LinSysRes(iPoint,iVar) -= nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; +// } +// } +// END_SU2_OMP_FOR - AD::EndNoSharedReading(); +// AD::EndNoSharedReading(); -} +// } diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index 8a872799a4d5..4554395b668b 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -352,6 +352,12 @@ void CTransLMSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta AD::EndNoSharedReading(); + /*--- Custom user defined source term (from the python wrapper) ---*/ + if (config->GetPyCustom_Source() ) { + Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + } + + } void CTransLMSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, diff --git a/SU2_CFD/src/solvers/CTurbSASolver.cpp b/SU2_CFD/src/solvers/CTurbSASolver.cpp index 18eff14832e2..4c7fed9bb6b4 100644 --- a/SU2_CFD/src/solvers/CTurbSASolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSASolver.cpp @@ -492,6 +492,12 @@ void CTurbSASolver::Source_Residual(CGeometry *geometry, CSolver **solver_contai AD::EndNoSharedReading(); + /*--- Custom user defined source term (from the python wrapper) ---*/ + if (config->GetPyCustom_Source() ) { + Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + } + + } void CTurbSASolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, diff --git a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp index 9fee88d18760..bdf2a57e1156 100644 --- a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp @@ -387,6 +387,11 @@ void CTurbSSTSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta AD::EndNoSharedReading(); + /*--- Custom user defined source term (from the python wrapper) ---*/ + if (config->GetPyCustom_Source() ) { + Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + } + } void CTurbSSTSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, From f7f2f75388d7db2f26158c40f22f88ee0487ac98 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Fri, 11 Jul 2025 18:34:03 +0200 Subject: [PATCH 43/61] move uds to CSolver --- .../include/solvers/CFVMFlowSolverBase.hpp | 33 ----------- SU2_CFD/include/solvers/CSolver.hpp | 20 +------ SU2_CFD/include/solvers/CSpeciesSolver.hpp | 11 ---- SU2_CFD/src/integration/CIntegration.cpp | 3 - SU2_CFD/src/solvers/CEulerSolver.cpp | 20 +------ SU2_CFD/src/solvers/CIncEulerSolver.cpp | 22 -------- SU2_CFD/src/solvers/CSolver.cpp | 30 ---------- .../src/solvers/CSpeciesFlameletSolver.cpp | 23 +------- SU2_CFD/src/solvers/CSpeciesSolver.cpp | 56 +------------------ SU2_CFD/src/solvers/CTransLMSolver.cpp | 3 +- SU2_CFD/src/solvers/CTurbSASolver.cpp | 3 +- 11 files changed, 9 insertions(+), 215 deletions(-) diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp index 4dabb50875c1..e689c24014b8 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp @@ -315,39 +315,6 @@ class CFVMFlowSolverBase : public CSolver { } } - -// inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, -// CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { - -// /*--- Pick one numerics object per thread. ---*/ -// CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; - -// unsigned short iVar; -// unsigned long iPoint; -// AD::StartNoSharedReading(); - -// SU2_OMP_FOR_STAT(omp_chunk_size) -// for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - -// /*--- Load the volume of the dual mesh cell ---*/ - -// numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - -// /*--- Get control volume size. ---*/ -// su2double Volume = geometry->nodes->GetVolume(iPoint); - -// /*--- Compute the residual for this control volume and subtract. ---*/ -// for (iVar = 0; iVar < nVar; iVar++) { -// LinSysRes(iPoint, iVar) += nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; -// } -// } -// END_SU2_OMP_FOR - -// AD::EndNoSharedReading(); - -// } - - /*! * \brief Computes and sets the required auxilliary vars (and gradients) for axisymmetric flow. */ diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index 03982f328773..4485635dc5d2 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -1565,19 +1565,6 @@ class CSolver { CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { } - /*! - * \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_container - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - // inline virtual void Custom_Source_Residual(CGeometry *geometry, - // CSolver **solver_container, - // CNumerics **numerics_container, - // CConfig *config, - // unsigned short iMesh) { } /*! * \brief A virtual member. @@ -4346,19 +4333,16 @@ class CSolver { END_SU2_OMP_FOR } -/*--- Why not do this? ---*/ inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { /*--- Pick one numerics object per thread. ---*/ CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; - unsigned short iVar; - unsigned long iPoint; AD::StartNoSharedReading(); SU2_OMP_FOR_STAT(omp_chunk_size) - for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { /*--- Load the volume of the dual mesh cell ---*/ numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); @@ -4366,7 +4350,7 @@ inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- Get control volume size. ---*/ su2double Volume = geometry->nodes->GetVolume(iPoint); /*--- Compute the residual for this control volume and subtract. ---*/ - for (iVar = 0; iVar < nVar; iVar++) { + for (auto iVar = 0; iVar < nVar; iVar++) { LinSysRes(iPoint,iVar) -= base_nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; } } diff --git a/SU2_CFD/include/solvers/CSpeciesSolver.hpp b/SU2_CFD/include/solvers/CSpeciesSolver.hpp index c53357d7bb17..4d962d4088c3 100644 --- a/SU2_CFD/include/solvers/CSpeciesSolver.hpp +++ b/SU2_CFD/include/solvers/CSpeciesSolver.hpp @@ -162,17 +162,6 @@ class CSpeciesSolver : public CScalarSolver { */ void Source_Residual(CGeometry* geometry, CSolver** solver_container, CNumerics** numerics_container, CConfig* config, unsigned short iMesh) override; -/*! - * \brief Source term computation for axisymmetric flow. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics_container - Container for description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - // void Custom_Source_Residual(CGeometry* geometry, CSolver** solver_container, CNumerics** numerics_container, CConfig* config, - // unsigned short iMesh) override; - /*! * \brief Impose the fluid interface boundary condition using tranfer data. diff --git a/SU2_CFD/src/integration/CIntegration.cpp b/SU2_CFD/src/integration/CIntegration.cpp index 040ec72e9887..a751ff01cdb7 100644 --- a/SU2_CFD/src/integration/CIntegration.cpp +++ b/SU2_CFD/src/integration/CIntegration.cpp @@ -63,9 +63,6 @@ void CIntegration::Space_Integration(CGeometry *geometry, /*--- Compute source term residuals ---*/ solver_container[MainSolver]->Source_Residual(geometry, solver_container, numerics, config, iMesh); - /*--- Compute custom (python wrapper) source term residuals ---*/ - //solver_container[MainSolver]->Custom_Source_Residual(geometry, solver_container, numerics, config, iMesh); - /*--- Add viscous and convective residuals, and compute the Dual Time Source term ---*/ if (dual_time) diff --git a/SU2_CFD/src/solvers/CEulerSolver.cpp b/SU2_CFD/src/solvers/CEulerSolver.cpp index 8d6fee155517..70f0aca4b76c 100644 --- a/SU2_CFD/src/solvers/CEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CEulerSolver.cpp @@ -2278,27 +2278,13 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain } } + AD::EndNoSharedReading(); + /*--- Custom user defined source term (from the python wrapper) ---*/ if (config->GetPyCustom_Source() ) { - SU2_OMP_FOR_STAT(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { - - /*--- Load the volume of the dual mesh cell ---*/ - - numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - - /*--- Get control volume size. ---*/ - su2double Volume = geometry->nodes->GetVolume(iPoint); - - /*--- Compute the residual for this control volume and subtract. ---*/ - for (auto iVar = 0; iVar < nVar; iVar++) { - LinSysRes(iPoint, iVar) += nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; - } - } - END_SU2_OMP_FOR + Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); } - AD::EndNoSharedReading(); } void CEulerSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index ff5a1f3907ab..f2cb3833e6de 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -1813,28 +1813,6 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); } - // /*--- Custom user defined source term (from the python wrapper) ---*/ - // if (config->GetPyCustom_Source() ) { - // AD::StartNoSharedReading(); - // SU2_OMP_FOR_STAT(omp_chunk_size) - // for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { - - // /*--- Load the volume of the dual mesh cell ---*/ - - // numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - - // /*--- Get control volume size. ---*/ - // su2double Volume = geometry->nodes->GetVolume(iPoint); - - // /*--- Compute the residual for this control volume and subtract. ---*/ - // for (auto iVar = 0; iVar < nVar; iVar++) { - // LinSysRes(iPoint, iVar) += nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; - // } - // } - // END_SU2_OMP_FOR - // AD::EndNoSharedReading(); - // } - } void CIncEulerSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, diff --git a/SU2_CFD/src/solvers/CSolver.cpp b/SU2_CFD/src/solvers/CSolver.cpp index 73a848ba5ae8..796e009f181b 100644 --- a/SU2_CFD/src/solvers/CSolver.cpp +++ b/SU2_CFD/src/solvers/CSolver.cpp @@ -4367,33 +4367,3 @@ void CSolver::SavelibROM(CGeometry *geometry, CConfig *config, bool converged) { #endif } - - -// void CSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, -// CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { - -// /*--- Pick one numerics object per thread. ---*/ -// CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; - -// unsigned short iVar; -// unsigned long iPoint; -// AD::StartNoSharedReading(); - -// SU2_OMP_FOR_STAT(omp_chunk_size) -// for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - -// /*--- Load the volume of the dual mesh cell ---*/ -// numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - -// /*--- Get control volume size. ---*/ -// su2double Volume = geometry->nodes->GetVolume(iPoint); -// /*--- Compute the residual for this control volume and subtract. ---*/ -// for (iVar = 0; iVar < nVar; iVar++) { -// LinSysRes(iPoint,iVar) -= nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; -// } -// } -// END_SU2_OMP_FOR - -// AD::EndNoSharedReading(); - -// } diff --git a/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp b/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp index f50743ea56c1..63da73862768 100644 --- a/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp @@ -389,32 +389,11 @@ void CSpeciesFlameletSolver::Source_Residual(CGeometry* geometry, CSolver** solv } END_SU2_OMP_FOR - - /*--- Custom user defined source term (from the python wrapper) ---*/ + /*--- Custom user defined source term (from the python wrapper) ---*/ if (config->GetPyCustom_Source() ) { Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); - - // AD::StartNoSharedReading(); - // SU2_OMP_FOR_STAT(omp_chunk_size) - // for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { - - // /*--- Load the volume of the dual mesh cell ---*/ - - // numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - - // /*--- Get control volume size. ---*/ - // su2double Volume = geometry->nodes->GetVolume(iPoint); - - // /*--- Compute the residual for this control volume and subtract. ---*/ - // for (auto iVar = 0; iVar < nVar; iVar++) { - // LinSysRes(iPoint, iVar) += nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; - // } - // } - // END_SU2_OMP_FOR - // AD::EndNoSharedReading(); } - } void CSpeciesFlameletSolver::BC_Inlet(CGeometry* geometry, CSolver** solver_container, CNumerics* conv_numerics, diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index 1b7efcb37832..8900ddb49fad 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -564,63 +564,9 @@ void CSpeciesSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta END_SU2_OMP_FOR } - /*--- Custom user defined source term (from the python wrapper) ---*/ + /*--- Custom user defined source term (from the python wrapper) ---*/ if (config->GetPyCustom_Source() ) { Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); } -// /*--- Custom user defined source term (from the python wrapper) ---*/ -// if (config->GetPyCustom_Source() ) { -// CNumerics *numerics = numerics_container[SOURCE_FIRST_TERM + omp_get_thread_num()*MAX_TERMS]; - -// AD::StartNoSharedReading(); -// SU2_OMP_FOR_STAT(omp_chunk_size) -// for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { - -// /*--- Load the volume of the dual mesh cell ---*/ - -// numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - -// /*--- Get control volume size. ---*/ -// su2double Volume = geometry->nodes->GetVolume(iPoint); - -// /*--- Compute the residual for this control volume and subtract. ---*/ -// for (auto iVar = 0; iVar < nVar; iVar++) { -// LinSysRes(iPoint, iVar) += nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; -// } -// } -// END_SU2_OMP_FOR -// AD::EndNoSharedReading(); -// } - } - - -// void CSpeciesSolver::Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, -// CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { - -// /*--- Pick one numerics object per thread. ---*/ -// CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; - -// unsigned short iVar; -// unsigned long iPoint; -// AD::StartNoSharedReading(); - -// SU2_OMP_FOR_STAT(omp_chunk_size) -// for (iPoint = 0; iPoint < nPointDomain; iPoint++) { - -// /*--- Load the volume of the dual mesh cell ---*/ -// numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - -// /*--- Get control volume size. ---*/ -// su2double Volume = geometry->nodes->GetVolume(iPoint); -// /*--- Compute the residual for this control volume and subtract. ---*/ -// for (iVar = 0; iVar < nVar; iVar++) { -// LinSysRes(iPoint,iVar) -= nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; -// } -// } -// END_SU2_OMP_FOR - -// AD::EndNoSharedReading(); - -// } diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index 4554395b668b..e0f1b9bcb3a1 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -352,12 +352,11 @@ void CTransLMSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta AD::EndNoSharedReading(); - /*--- Custom user defined source term (from the python wrapper) ---*/ + /*--- Custom user defined source term (from the python wrapper) ---*/ if (config->GetPyCustom_Source() ) { Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); } - } void CTransLMSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, diff --git a/SU2_CFD/src/solvers/CTurbSASolver.cpp b/SU2_CFD/src/solvers/CTurbSASolver.cpp index 4c7fed9bb6b4..e4d645d608d0 100644 --- a/SU2_CFD/src/solvers/CTurbSASolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSASolver.cpp @@ -492,12 +492,11 @@ void CTurbSASolver::Source_Residual(CGeometry *geometry, CSolver **solver_contai AD::EndNoSharedReading(); - /*--- Custom user defined source term (from the python wrapper) ---*/ + /*--- Custom user defined source term (from the python wrapper) ---*/ if (config->GetPyCustom_Source() ) { Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); } - } void CTurbSASolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, From 03409223e76cfc0416afa3756a8ffad66befbc43 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Fri, 11 Jul 2025 20:18:52 +0200 Subject: [PATCH 44/61] add species user source to output --- SU2_CFD/include/solvers/CSolver.hpp | 4 ++-- SU2_CFD/include/variables/CVariable.hpp | 12 ++++++++++-- SU2_CFD/src/output/CFlowOutput.cpp | 17 ++++++++++++++--- SU2_CFD/src/solvers/CEulerSolver.cpp | 20 ++++++++++---------- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index 4485635dc5d2..1866fee1a92f 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -4342,7 +4342,7 @@ inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_contain AD::StartNoSharedReading(); SU2_OMP_FOR_STAT(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Load the volume of the dual mesh cell ---*/ numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); @@ -4350,7 +4350,7 @@ inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- Get control volume size. ---*/ su2double Volume = geometry->nodes->GetVolume(iPoint); /*--- Compute the residual for this control volume and subtract. ---*/ - for (auto iVar = 0; iVar < nVar; iVar++) { + for (auto iVar = 0ul; iVar < nVar; iVar++) { LinSysRes(iPoint,iVar) -= base_nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; } } diff --git a/SU2_CFD/include/variables/CVariable.hpp b/SU2_CFD/include/variables/CVariable.hpp index 9df0c069812c..7842cb947957 100644 --- a/SU2_CFD/include/variables/CVariable.hpp +++ b/SU2_CFD/include/variables/CVariable.hpp @@ -510,19 +510,27 @@ class CVariable { inline su2double *GetSolution(unsigned long iPoint) { return Solution[iPoint]; } /*! - * \brief Get the entire solution of the problem. + * \brief Get the entire User Define Source of the problem. * \return Reference to the solution matrix. */ inline const MatrixType& GetUserDefinedSource() const { return UserDefinedSource; } inline MatrixType& GetUserDefinedSource() { return UserDefinedSource; } /*! - * \brief Get the solution of the problem. + * \brief Get the User Defined Source of the problem. * \param[in] iPoint - Point index. * \return Pointer to the solution vector. */ inline su2double *GetUserDefinedSource(unsigned long iPoint) { return UserDefinedSource[iPoint]; } + /*! + * \brief Get the User Defined Source of the problem. + * \param[in] iPoint - Point index. + * \param[in] iVar - Scalar index. + * \return Pointer to the solution vector. + */ + inline su2double GetUserDefinedSource(unsigned long iPoint, unsigned long iVar) const { return UserDefinedSource(iPoint,iVar); } + /*! * \brief Get the old solution of the problem (Runge-Kutta method) * \param[in] iPoint - Point index. diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index e9f70fee2768..38c11f48a943 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -1430,6 +1430,13 @@ void CFlowOutput::SetVolumeOutputFieldsScalarSource(const CConfig* config) { /*--- Only place outputs of the "SOURCE" group for scalar transport here. ---*/ switch (config->GetKind_Species_Model()) { + case SPECIES_MODEL::SPECIES_TRANSPORT: + if (config->GetPyCustom_Source()){ + for (unsigned short iVar = 0; iVar < config->GetnSpecies(); iVar++){ + AddVolumeOutput("SPECIES_UDS_" + std::to_string(iVar), "Species_UDS_" + std::to_string(iVar), "SOURCE", "Species User Defined Source " + std::to_string(iVar)); + } + } + break; case SPECIES_MODEL::FLAMELET: { const auto& flamelet_config_options = config->GetFlameletParsedOptions(); for (auto iCV=0u; iCV < flamelet_config_options.n_control_vars; iCV++) { @@ -1444,8 +1451,8 @@ void CFlowOutput::SetVolumeOutputFieldsScalarSource(const CConfig* config) { const auto& species_name = flamelet_config_options.user_scalar_names[iReactant]; AddVolumeOutput("SOURCE_" + species_name, "Source_" + species_name, "SOURCE", "Source " + species_name); } - } - break; + } + break; default: break; } @@ -1581,12 +1588,16 @@ void CFlowOutput::LoadVolumeDataScalar(const CConfig* config, const CSolver* con case SPECIES_MODEL::SPECIES_TRANSPORT: { const auto Node_Species = solver[SPECIES_SOL]->GetNodes(); - for (unsigned short iVar = 0; iVar < config->GetnSpecies(); iVar++) { + + for (unsigned long iVar = 0; iVar < config->GetnSpecies(); iVar++) { SetVolumeOutputValue("SPECIES_" + std::to_string(iVar), iPoint, Node_Species->GetSolution(iPoint, iVar)); SetVolumeOutputValue("RES_SPECIES_" + std::to_string(iVar), iPoint, solver[SPECIES_SOL]->LinSysRes(iPoint, iVar)); SetVolumeOutputValue("DIFFUSIVITY_"+ std::to_string(iVar), iPoint, Node_Species->GetDiffusivity(iPoint,iVar)); if (config->GetKind_SlopeLimit_Species() != LIMITER::NONE) SetVolumeOutputValue("LIMITER_SPECIES_" + std::to_string(iVar), iPoint, Node_Species->GetLimiter(iPoint, iVar)); + if (config->GetPyCustom_Source()){ + SetVolumeOutputValue("SPECIES_UDS_" + std::to_string(iVar), iPoint, Node_Species->GetUserDefinedSource(iPoint, iVar)); + } } break; } diff --git a/SU2_CFD/src/solvers/CEulerSolver.cpp b/SU2_CFD/src/solvers/CEulerSolver.cpp index 70f0aca4b76c..e7ee82d6c0ef 100644 --- a/SU2_CFD/src/solvers/CEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CEulerSolver.cpp @@ -2058,7 +2058,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- Loop over all points ---*/ AD::StartNoSharedReading(); SU2_OMP_FOR_STAT(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Load the conservative variables ---*/ numerics->SetConservative(nodes->GetSolution(iPoint), @@ -2088,7 +2088,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- Loop over all points ---*/ AD::StartNoSharedReading(); SU2_OMP_FOR_DYN(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Load the conservative variables ---*/ numerics->SetConservative(nodes->GetSolution(iPoint), @@ -2121,7 +2121,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- loop over points ---*/ AD::StartNoSharedReading(); SU2_OMP_FOR_DYN(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Set solution ---*/ numerics->SetConservative(nodes->GetSolution(iPoint), nodes->GetSolution(iPoint)); @@ -2174,7 +2174,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- loop over points ---*/ SU2_OMP_FOR_DYN(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Set solution ---*/ numerics->SetConservative(nodes->GetSolution(iPoint), nodes->GetSolution(iPoint)); @@ -2197,13 +2197,13 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- loop over points ---*/ SU2_OMP_FOR_STAT(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Get control volume ---*/ su2double Volume = geometry->nodes->GetVolume(iPoint); /*--- Get stored time spectral source term and add to residual ---*/ - for (auto iVar = 0; iVar < nVar; iVar++) { + for (auto iVar = 0ul; iVar < nVar; iVar++) { LinSysRes(iPoint,iVar) += Volume * nodes->GetHarmonicBalance_Source(iPoint,iVar); } } @@ -2220,7 +2220,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- set vorticity magnitude as auxilliary variable ---*/ SU2_OMP_FOR_STAT(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPoint; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { const su2double VorticityMag = max(GeometryToolbox::Norm(3, nodes->GetVorticity(iPoint)), 1e-12); nodes->SetAuxVar(iPoint, 0, VorticityMag); } @@ -2230,7 +2230,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain SetAuxVar_Gradient_GG(geometry, config); SU2_OMP_FOR_DYN(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { second_numerics->SetPrimitive(nodes->GetPrimitive(iPoint), nullptr); second_numerics->SetVorticity(nodes->GetVorticity(iPoint), nullptr); second_numerics->SetAuxVarGrad(nodes->GetAuxVarGradient(iPoint), nullptr); @@ -2257,7 +2257,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- Loop over points ---*/ SU2_OMP_FOR_DYN(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Get control volume size. ---*/ su2double Volume = geometry->nodes->GetVolume(iPoint); @@ -2270,7 +2270,7 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain VerificationSolution->GetMMSSourceTerm(coor, time, sourceMan.data()); /*--- Compute the residual for this control volume and subtract. ---*/ - for (auto iVar = 0; iVar < nVar; iVar++) { + for (auto iVar = 0ul; iVar < nVar; iVar++) { LinSysRes(iPoint,iVar) -= sourceMan[iVar]*Volume; } } From 1af69b893e69bbd155345fba25ca08e75756466b Mon Sep 17 00:00:00 2001 From: bigfooted Date: Fri, 11 Jul 2025 20:31:26 +0200 Subject: [PATCH 45/61] fix auto warnings --- SU2_CFD/src/solvers/CIncEulerSolver.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index f2cb3833e6de..94197e4d2a5b 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -1401,7 +1401,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont /*--- Loop over all points ---*/ SU2_OMP_FOR_STAT(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Load the conservative variables ---*/ @@ -1434,7 +1434,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont /*--- Loop over all points ---*/ SU2_OMP_FOR_STAT(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Load the conservative variables ---*/ @@ -1467,7 +1467,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont /*--- Loop over all points ---*/ SU2_OMP_FOR_STAT(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Load the primitive variables ---*/ @@ -1508,7 +1508,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont AD::StartNoSharedReading(); SU2_OMP_FOR_STAT(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPoint; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { su2double yCoord = geometry->nodes->GetCoord(iPoint, 1); su2double yVelocity = nodes->GetVelocity(iPoint,1); @@ -1543,7 +1543,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont AD::StartNoSharedReading(); SU2_OMP_FOR_STAT(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Conservative variables w/o reconstruction ---*/ @@ -1603,7 +1603,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont CNumerics* second_numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; SU2_OMP_FOR_STAT(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Store the radiation source term ---*/ @@ -1651,7 +1651,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont AD::StartNoSharedReading(); SU2_OMP_FOR_STAT(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPoint; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { /*--- Set the auxiliary variable, Eddy viscosity mu_t, for this node. ---*/ nodes->SetAuxVar(iPoint, 0, nodes->GetEddyViscosity(iPoint)); } @@ -1700,7 +1700,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont /*--- Loop over all points ---*/ SU2_OMP_FOR_STAT(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Load the primitive variables ---*/ numerics->SetPrimitive(nodes->GetPrimitive(iPoint), nullptr); @@ -1784,7 +1784,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont /*--- Loop over points ---*/ SU2_OMP_FOR_STAT(omp_chunk_size) - for (auto iPoint = 0; iPoint < nPointDomain; iPoint++) { + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Get control volume size. ---*/ su2double Volume = geometry->nodes->GetVolume(iPoint); From d91bb626a52ce552adcb5b1193e88be9b0b4f092 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Fri, 11 Jul 2025 22:00:16 +0200 Subject: [PATCH 46/61] remove unused variable --- SU2_CFD/include/solvers/CSolver.hpp | 5 +++-- SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index 1866fee1a92f..86dfd6a20932 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -4338,10 +4338,11 @@ inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_contain /*--- Pick one numerics object per thread. ---*/ CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; - AD::StartNoSharedReading(); - SU2_OMP_FOR_STAT(omp_chunk_size) + //SU2_OMP_FOR_STAT(omp_chunk_size) + SU2_OMP_FOR_STAT(roundUpDiv(nPointDomain,2*omp_get_max_threads())) + for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Load the volume of the dual mesh cell ---*/ diff --git a/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp b/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp index 63da73862768..f6313062c908 100644 --- a/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp @@ -378,8 +378,6 @@ void CSpeciesFlameletSolver::SetPreconditioner(CGeometry* geometry, CSolver** so void CSpeciesFlameletSolver::Source_Residual(CGeometry* geometry, CSolver** solver_container, CNumerics** numerics_container, CConfig* config, unsigned short iMesh) { - CNumerics* numerics = numerics_container[SOURCE_FIRST_TERM + omp_get_thread_num()*MAX_TERMS]; - SU2_OMP_FOR_STAT(omp_chunk_size) for (auto i_point = 0u; i_point < nPointDomain; i_point++) { /*--- Add source terms from the lookup table directly to the residual. ---*/ From a1131499ea132041b9c727617d743f37d222cb95 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Sat, 12 Jul 2025 12:59:46 +0200 Subject: [PATCH 47/61] update buoyancy --- SU2_CFD/src/iteration/CFluidIteration.cpp | 7 +- .../lam_buoyancy_cavity.cfg | 19 +++-- .../py_wrapper/custom_source_buoyancy/run.py | 84 ++++++++----------- .../py_wrapper/turbulent_premixed_psi/psi.cfg | 12 ++- 4 files changed, 52 insertions(+), 70 deletions(-) diff --git a/SU2_CFD/src/iteration/CFluidIteration.cpp b/SU2_CFD/src/iteration/CFluidIteration.cpp index 6bd9c714f01d..e8d898f1580f 100644 --- a/SU2_CFD/src/iteration/CFluidIteration.cpp +++ b/SU2_CFD/src/iteration/CFluidIteration.cpp @@ -238,7 +238,7 @@ bool CFluidIteration::Monitor(COutput* output, CIntegration**** integration, CGe output->SetHistoryOutput(geometry[val_iZone][val_iInst][MESH_0], solver[val_iZone][val_iInst][MESH_0], config[val_iZone], config[val_iZone]->GetTimeIter(), config[val_iZone]->GetOuterIter(), config[val_iZone]->GetInnerIter()); - + StopCalc = output->GetConvergence(); /* --- Checking convergence of Fixed CL mode to target CL, and perform finite differencing if needed --*/ @@ -345,12 +345,12 @@ void CFluidIteration::ComputeTurboPerformance(CSolver***** solver, CGeometry**** bladesPrimitives.push_back(bladePrimitives); } TurbomachineryPerformance->ComputeTurbomachineryPerformance(bladesPrimitives); - + auto nSpan = config_container[ZONE_0]->GetnSpanWiseSections(); auto InState = TurbomachineryPerformance->GetBladesPerformances().at(ZONE_0).at(nSpan)->GetInletState(); nSpan = config_container[nZone-1]->GetnSpanWiseSections(); auto OutState = TurbomachineryPerformance->GetBladesPerformances().at(nZone-1).at(nSpan)->GetOutletState(); - + TurbomachineryStagePerformance->ComputePerformanceStage(InState, OutState, config_container[nZone-1]); } } @@ -658,7 +658,6 @@ void CFluidIteration::SetDualTime_Aeroelastic(CConfig* config) const { Marker_Tag = config->GetMarker_All_TagBound(iMarker); if (Marker_Tag == Monitoring_Tag) { owner = 1; break; } owner = 0; - } plunge = config->GetAeroelastic_plunge(iMarker_Monitoring); diff --git a/TestCases/py_wrapper/custom_source_buoyancy/lam_buoyancy_cavity.cfg b/TestCases/py_wrapper/custom_source_buoyancy/lam_buoyancy_cavity.cfg index 55d2beae88ce..718f9207332d 100644 --- a/TestCases/py_wrapper/custom_source_buoyancy/lam_buoyancy_cavity.cfg +++ b/TestCases/py_wrapper/custom_source_buoyancy/lam_buoyancy_cavity.cfg @@ -12,8 +12,7 @@ % SOLVER= INC_NAVIER_STOKES KIND_TURB_MODEL= NONE -MATH_PROBLEM= DIRECT -RESTART_SOL= NO +RESTART_SOL= YES % ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% % @@ -47,6 +46,7 @@ THERMAL_CONDUCTIVITY_CONSTANT= 0.0246295028571 % ----------------------- BODY FORCE DEFINITION -------------------------------% % +% switch off body force, we now do this with the python wrapper BODY_FORCE= NO BODY_FORCE_VECTOR= ( 0.0, -9.81, 0.0 ) @@ -67,12 +67,12 @@ MARKER_MONITORING= ( NONE ) % ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% % NUM_METHOD_GRAD= GREEN_GAUSS -CFL_NUMBER= 50 +CFL_NUMBER= 100 CFL_ADAPT= NO -CFL_ADAPT_PARAM= ( 1.5, 0.5, 15.0, 1e10) +CFL_ADAPT_PARAM= ( 0.9, 1.1, 10.0,10000, 1.0e-3) MAX_DELTA_TIME= 1E6 RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) -ITER=6 +ITER=1 % ------------------------ LINEAR SOLVER DEFINITION ---------------------------% % @@ -93,7 +93,7 @@ TIME_DISCRE_FLOW= EULER_IMPLICIT % --------------------------- CONVERGENCE PARAMETERS --------------------------% % CONV_RESIDUAL_MINVAL= -12 -CONV_STARTITER= 10 +CONV_STARTITER= 1 CONV_CAUCHY_ELEMS= 100 CONV_CAUCHY_EPS= 1E-6 @@ -113,6 +113,9 @@ VOLUME_ADJ_FILENAME= adjoint GRAD_OBJFUNC_FILENAME= of_grad.dat SURFACE_FILENAME= surface_flow SURFACE_ADJ_FILENAME= surface_adjoint -OUTPUT_WRT_FREQ= 100 -SCREEN_OUTPUT= (OUTER_ITER,INNER_ITER, RMS_PRESSURE, RMS_VELOCITY-X, RMS_VELOCITY-Y, RMS_TEMPERATURE) +OUTPUT_WRT_FREQ= 10 +SCREEN_OUTPUT= (INNER_ITER, RMS_PRESSURE, RMS_VELOCITY-X, RMS_VELOCITY-Y, RMS_TEMPERATURE) + +WRT_PERFORMANCE= YES +PYTHON_CUSTOM_SOURCE= YES diff --git a/TestCases/py_wrapper/custom_source_buoyancy/run.py b/TestCases/py_wrapper/custom_source_buoyancy/run.py index d696f0a13bb5..03aefbb7b6d2 100644 --- a/TestCases/py_wrapper/custom_source_buoyancy/run.py +++ b/TestCases/py_wrapper/custom_source_buoyancy/run.py @@ -26,17 +26,17 @@ import sys import pysu2 -from mpi4py import MPI +import numpy as np +# with mpi: +from mpi4py import MPI +comm = MPI.COMM_WORLD +rank = comm.Get_rank() +# without mpi: +# comm = 0 def main(): - """ - custom source to add buoyancy term. - """ - # parallel - comm = MPI.COMM_WORLD - # serial - #comm = 0 + # Initialize the primal driver of SU2, this includes solver preprocessing. try: @@ -45,8 +45,9 @@ def main(): print('A TypeError occured in pysu2.CSinglezoneDriver : ', exception) raise - print("\n------------------------------ Begin Solver -----------------------------") - sys.stdout.flush() + if rank == 0: + print("\n------------------------------ Begin Solver -----------------------------") + sys.stdout.flush() # we need to add a source term to the energy equation. For this, we need to get the solver and the variable first. # we then loop over all points and for these points, we add the source term @@ -54,74 +55,55 @@ def main(): # index to the flow solver iSOLVER = driver.GetSolverIndices()['INC.FLOW'] - #print("index of flow solver = ",iSOLVER) # all the indices and the map to the names of the primitives primindex = driver.GetPrimitiveIndices() - #print("indices of primitives=",primindex) - #print("number of primitives:",len(primindex)) - - #print("number of elements:",driver.GetNumberElements()) nVars = driver.GetNumberSolverVars(iSOLVER) - #print("number of solver variables:",nVars) varindex = primindex.copy() - for prim in varindex.copy(): - if varindex[prim] >=nVars: - del varindex[prim] - varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) - + #for prim in varindex.copy(): + # if varindex[prim] >=nVars: + # del varindex[prim] + #varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) - - print("solver variable names:",varindex) iDENSITY = primindex.get("DENSITY") - print("index of density = ",iDENSITY) - - index_Vel = varindex.get("VELOCITY_X") - print("index of velocity = ",index_Vel) - custom_source_vector = [0.0 for i in range(nVars)] - print("custom source vector = ", custom_source_vector) + #index_Vel = varindex.get("VELOCITY_X") - #print("max. number of inner iterations: ",driver.GetNumberInnerIter()); - #print("max nr of outer iterations: ",driver.GetNumberOuterIter()); - - # is in domain: isdomain = driver.GetNodeDomain(iPoint) - #for i_vertex in range(n_vertex) - #AllSolutions = driver.GetAllSolutions(iSOLVER) Body_Force_Vector = [0.0, -9.81, 0.0] DensityInc_0 = driver.GetDensity_FreeStreamND() - #print("rho freestream = ",DensityInc_0) Force_Ref = driver.GetForce_Ref() - #print("reference force = ",Force_Ref) - Iter = driver.GetNumberInnerIter() - print("1. inner iterations = ",Iter) + # super important to actually push the commands. + sys.stdout.flush() + + # run N iterations + for inner_iter in range(11): + if (rank==0): + print("python iteration ", inner_iter) - for inner_iter in range(Iter): # set the source term, per point - print(driver.GetNumberNodes() - driver.GetNumberHaloNodes()) for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): - #SolutionVector = driver.GetSolutionVector(iSOLVER,i_node) - PrimitiveVector = driver.GetPrimitiveVector(iSOLVER,i_node) - DensityInc_i = PrimitiveVector[iDENSITY] + DensityInc_i = driver.Primitives()(i_node,iDENSITY) for iDim in range(nDim): - custom_source_vector[iDim+1] = -(DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref - - #driver.SetPointCustomSource(iSOLVER, i_node, custom_source_vector) + custom_source_vector = (DensityInc_i - DensityInc_0) * Body_Force_Vector[iDim] / Force_Ref + driver.UserDefinedSource(iSOLVER).Set(i_node,iDim+1,custom_source_vector) - print(" *** inner iteration:",inner_iter) driver.Preprocess(inner_iter) - - # Run one time iteration. driver.Run() + driver.Postprocess() driver.Update() # Monitor the solver and output solution to file if required. - #driver.Monitor(inner_iter) + #stopcalc = driver.Monitor(inner_iter) driver.Output(inner_iter) + #if (stopcalc): + # if (rank==0): + # "Max iterations or convergence criteria reached, stopping." + # break; + # Finalize the solver and exit cleanly. driver.Finalize() diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg b/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg index 1a4195cd22d2..5c2b266fe9d4 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg +++ b/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg @@ -67,7 +67,6 @@ AXISYMMETRIC= YES SPECIFIED_INLET_PROFILE= YES INLET_MATCHING_TOLERANCE=1e-4 INLET_FILENAME= inlet.dat -%INLET_INTERPOLATION_FUNCTION= LINEAR_1D INC_INLET_TYPE= VELOCITY_INLET INC_INLET_DAMPING= 0.1 MARKER_INLET= ( inlet, 673, 40.0, 1.0, 0.0, 0.0) @@ -82,9 +81,10 @@ MARKER_OUTLET= ( outlet, 0.0 ) % NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES % -CFL_NUMBER= 10.0 +CFL_NUMBER= 2.00 CFL_REDUCTION_SPECIES= 1.0 CFL_REDUCTION_TURB= 1.0 +%CFL_ADAPT= YES CFL_ADAPT= YES CFL_ADAPT_PARAM= ( 0.95, 1.01, 1.0, 250, 1.0e-4, 0) @@ -95,7 +95,7 @@ ITER= 1 % LINEAR_SOLVER= FGMRES LINEAR_SOLVER_PREC= ILU -LINEAR_SOLVER_ERROR= 1E-8 +LINEAR_SOLVER_ERROR= 1E-12 LINEAR_SOLVER_ITER= 10 % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% @@ -131,7 +131,6 @@ SPECIES_CLIPPING_MAX= 1.0 % CONV_NUM_METHOD_TURB= BOUNDED_SCALAR MUSCL_TURB= NO - % % --------------------------- CONVERGENCE PARAMETERS --------------------------% % @@ -141,9 +140,7 @@ CONV_STARTITER= 10 % % ------------------------- INPUT/OUTPUT INFORMATION --------------------------% % -%MESH_FILENAME= psi_coarse.su2 MESH_FILENAME= psi.su2 -%MESH_FILENAME= psi_fine.su2 % SCREEN_OUTPUT= INNER_ITER WALL_TIME \ RMS_PRESSURE RMS_VELOCITY-X RMS_VELOCITY-Y RMS_TKE RMS_DISSIPATION RMS_SPECIES_0 \ @@ -158,7 +155,7 @@ MARKER_ANALYZE= gas_inlet, air_axial_inlet, outlet MARKER_ANALYZE_AVERAGE= AREA % OUTPUT_FILES= RESTART, PARAVIEW_MULTIBLOCK -VOLUME_OUTPUT= RESIDUAL, PRIMITIVE +VOLUME_OUTPUT= RESIDUAL, PRIMITIVE, SPECIES_UDS_0 OUTPUT_WRT_FREQ= 100 % READ_BINARY_RESTART= YES @@ -166,3 +163,4 @@ RESTART_FILENAME= restart SOLUTION_FILENAME= solution % WRT_PERFORMANCE= YES +PYTHON_CUSTOM_SOURCE= YES From 7ddf9d73d64729bd8e41dac18cd7994beac99cac Mon Sep 17 00:00:00 2001 From: bigfooted Date: Sat, 12 Jul 2025 17:29:09 +0200 Subject: [PATCH 48/61] fix regression test residuals --- TestCases/parallel_regression.py | 8 ++-- .../py_wrapper/custom_source_buoyancy/run.py | 2 +- .../py_wrapper/turbulent_premixed_psi/psi.cfg | 6 +-- .../py_wrapper/turbulent_premixed_psi/run.py | 48 ++++++++----------- 4 files changed, 27 insertions(+), 37 deletions(-) diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index e031134b3261..496fee1a6ae1 100644 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -1479,8 +1479,8 @@ def main(): pywrapper_buoyancy = TestCase('pywrapper_buoyancy') pywrapper_buoyancy.cfg_dir = "py_wrapper/custom_source_buoyancy" pywrapper_buoyancy.cfg_file = "lam_buoyancy_cavity.cfg" - pywrapper_buoyancy.test_iter = 1 - pywrapper_buoyancy.test_vals = [0.500000] + pywrapper_buoyancy.test_iter = 0 + pywrapper_buoyancy.test_vals = [-17.746018, -17.462127, -17.428851, -12.260605] pywrapper_buoyancy.command = TestCase.Command("mpirun -np 2", "python", "run.py") test_list.append(pywrapper_buoyancy) @@ -1488,8 +1488,8 @@ def main(): pywrapper_zimont = TestCase('pywrapper_zimont') pywrapper_zimont.cfg_dir = "py_wrapper/turbulent_premixed_psi" pywrapper_zimont.cfg_file = "psi.cfg" - pywrapper_zimont.test_iter = 1 - pywrapper_zimont.test_vals = [0.500000] + pywrapper_zimont.test_iter = 0 + pywrapper_zimont.test_vals = [-3.229704, -1.602176, -3.904854, -2.631849, -0.325639, -3.498356] pywrapper_zimont.command = TestCase.Command("mpirun -np 2", "python", "run.py") test_list.append(pywrapper_zimont) diff --git a/TestCases/py_wrapper/custom_source_buoyancy/run.py b/TestCases/py_wrapper/custom_source_buoyancy/run.py index 03aefbb7b6d2..e6bb9c2480bf 100644 --- a/TestCases/py_wrapper/custom_source_buoyancy/run.py +++ b/TestCases/py_wrapper/custom_source_buoyancy/run.py @@ -77,7 +77,7 @@ def main(): sys.stdout.flush() # run N iterations - for inner_iter in range(11): + for inner_iter in range(2): if (rank==0): print("python iteration ", inner_iter) diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg b/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg index 5c2b266fe9d4..537eee85ce8b 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg +++ b/TestCases/py_wrapper/turbulent_premixed_psi/psi.cfg @@ -143,10 +143,8 @@ CONV_STARTITER= 10 MESH_FILENAME= psi.su2 % SCREEN_OUTPUT= INNER_ITER WALL_TIME \ - RMS_PRESSURE RMS_VELOCITY-X RMS_VELOCITY-Y RMS_TKE RMS_DISSIPATION RMS_SPECIES_0 \ - LINSOL_ITER LINSOL_RESIDUAL \ - LINSOL_ITER_TURB LINSOL_RESIDUAL_TURB \ - LINSOL_ITER_SPECIES LINSOL_RESIDUAL_SPECIES AVG_CFL + RMS_PRESSURE RMS_VELOCITY-X RMS_VELOCITY-Y RMS_TKE RMS_DISSIPATION RMS_SPECIES_0 + SCREEN_WRT_FREQ_INNER= 1 % HISTORY_OUTPUT= ITER RMS_RES LINSOL SPECIES_COEFF SPECIES_COEFF_SURF diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py index b20c96735365..f74c548cc778 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/run.py +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -27,7 +27,6 @@ import sys import pysu2 -from mpi4py import MPI import numpy as np # with mpi: @@ -77,9 +76,7 @@ def initC(coord): def SetInitialSpecies(SU2Driver): allCoords = SU2Driver.Coordinates() iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] - print("index of species solver = ",iSPECIESSOLVER) nVarsSpecies = SU2Driver.GetNumberSolverVars(iSPECIESSOLVER) - print("number of species solver variables:",nVarsSpecies) for iPoint in range(SU2Driver.GetNumberNodes() - SU2Driver.GetNumberHaloNodes()): coord = allCoords.Get(iPoint) C = initC(coord) @@ -168,7 +165,6 @@ def main(): sys.stdout.flush() nDim = driver.GetNumberDimensions() - print("Dimensions of the problem = ",nDim) # index to the flow solver # C.FLOW @@ -179,61 +175,57 @@ def main(): # SA # SST iFLOWSOLVER = driver.GetSolverIndices()['INC.FLOW'] - print("index of flow solver = ",iFLOWSOLVER) iSPECIESSOLVER = driver.GetSolverIndices()['SPECIES'] - print("index of species solver = ",iSPECIESSOLVER) iSSTSOLVER = driver.GetSolverIndices()['SST'] - print("index of turbulence solver = ",iSSTSOLVER) - # all the indices and the map to the names of the primitives primindex = driver.GetPrimitiveIndices() - print("indices of primitives=",primindex) - print("number of primitives:",len(primindex)) - nElem = driver.GetNumberElements() - print("number of elements:",nElem) - nVars = driver.GetNumberSolverVars(iFLOWSOLVER) - print("number of flow solver variables:",nVars) - nVarsSpecies = driver.GetNumberSolverVars(iSPECIESSOLVER) - print("number of species solver variables:",nVarsSpecies) nVarsTurb = driver.GetNumberSolverVars(iSSTSOLVER) - print("number of turbulence solver variables:",nVarsTurb) + + if rank == 0: + print("Dimensions of the problem = ",nDim) + print("index of flow solver = ",iFLOWSOLVER) + print("index of turbulence solver = ",iSSTSOLVER) + print("indices of primitives=",primindex) + print("number of primitives:",len(primindex)) + print("number of elements:",nElem) + print("number of flow solver variables:",nVars) + print("number of species solver variables:",nVarsSpecies) + print("number of turbulence solver variables:",nVarsTurb) + sys.stdout.flush() + + # ### Check if we do a restart or not. ### with open('psi.cfg') as f: if 'RESTART_SOL= YES' in f.read(): + if rank == 0: print("restarting from file") else: # We can set an initial condition by calling this function: - print("Start calling SetInitialSpecies") + if rank == 0: + print("Using user defined initial condition.") SetInitialSpecies(driver) - print("End calling SetInitialSpecies") # super important to actually push the commands. sys.stdout.flush() # run N iterations - for inner_iter in range(1000): + for inner_iter in range(2): if (rank==0): print("python iteration ", inner_iter) driver.Preprocess(inner_iter) driver.Run() - # set the source term, per point, + # set the source term, per point for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): # add source term: # default TFC of Zimont: rho*Sc = rho_u * U_t * grad(c) S = zimont(driver,i_node) driver.UserDefinedSource(iSPECIESSOLVER).Set(i_node,0,S) - - #S = [zimont(driver,i_node)] - #driver.SetPointCustomSource(iSPECIESSOLVER, i_node,S) - - - # for the update of temperature, we need to update also the halo nodes for i_node in range(driver.GetNumberNodes()): # set the temperature to T = c*Tf + (1-c)*Tu @@ -241,7 +233,7 @@ def main(): driver.Postprocess() driver.Update() - # Monitor the solver and output solution to file if required + # Monitor the solver and output solution to file if required. #driver.Monitor(inner_iter) # Output the solution to file driver.Output(inner_iter) From c81183dc9977aec15d5d6958e78dcd12715ca72f Mon Sep 17 00:00:00 2001 From: bigfooted Date: Sat, 12 Jul 2025 17:38:04 +0200 Subject: [PATCH 49/61] clean up --- Common/include/CConfig.hpp | 12 ------------ SU2_CFD/include/drivers/CDriver.hpp | 12 ------------ SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp | 4 ---- SU2_CFD/include/solvers/CSpeciesSolver.hpp | 2 +- SU2_CFD/src/output/CFlowOutput.cpp | 1 - SU2_CFD/src/solvers/CNEMOEulerSolver.cpp | 1 - 6 files changed, 1 insertion(+), 31 deletions(-) diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 875dfb34fe82..7a029f65a78d 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -9374,24 +9374,12 @@ class CConfig { */ unsigned long GetnInner_Iter(void) const { return nInnerIter; } - /*! - * \brief Set the number of inner iterations - * \return - */ - void SetnInner_Iter(unsigned long val_iter) { nInnerIter = val_iter; } - /*! * \brief Get the number of outer iterations * \return Number of outer iterations for the multizone problem */ unsigned long GetnOuter_Iter(void) const { return nOuterIter; } - /*! - * \brief Set the number of outer iterations - * \return - */ - void SetnOuter_Iter(unsigned long val_iter) { nOuterIter = val_iter; } - /*! * \brief Get the number of time iterations * \return Number of time steps run diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index eb06d7097b9f..9df6532106b5 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -475,18 +475,6 @@ class CDriver : public CDriverBase { */ unsigned long GetNumberTimeIter() const; - /*! - * \brief Get the number of inner iterations. - * \return Number of inner iterations. - */ - unsigned long GetNumberInnerIter() const; - - /*! - * \brief Get the number of outer iterations. - * \return Number of outer iterations. - */ - unsigned long GetNumberOuterIter() const; - /*! * \brief Get the current time iteration. * \return Current time iteration. diff --git a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp index e689c24014b8..95e5306f6aa4 100644 --- a/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp +++ b/SU2_CFD/include/solvers/CFVMFlowSolverBase.hpp @@ -2148,8 +2148,6 @@ class CFVMFlowSolverBase : public CSolver { return Inlet_FlowDir[val_marker][val_vertex][val_dim]; } - - /*! * \brief Set the value of the total temperature at an inlet boundary. * \param[in] val_marker - Surface marker where the total temperature is set. @@ -2203,8 +2201,6 @@ class CFVMFlowSolverBase : public CSolver { Inlet_FlowDir[val_marker][val_vertex][val_dim] = val_flowdir; } - - /*! * \brief Update the multi-grid structure for the customized boundary conditions. * \param geometry_container - Geometrical definition. diff --git a/SU2_CFD/include/solvers/CSpeciesSolver.hpp b/SU2_CFD/include/solvers/CSpeciesSolver.hpp index 4d962d4088c3..26f45800bf4e 100644 --- a/SU2_CFD/include/solvers/CSpeciesSolver.hpp +++ b/SU2_CFD/include/solvers/CSpeciesSolver.hpp @@ -163,7 +163,7 @@ class CSpeciesSolver : public CScalarSolver { void Source_Residual(CGeometry* geometry, CSolver** solver_container, CNumerics** numerics_container, CConfig* config, unsigned short iMesh) override; -/*! + /*! * \brief Impose the fluid interface boundary condition using tranfer data. * \param[in] geometry - Geometrical definition of the problem. * \param[in] solver_container - Container vector with all the solutions. diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index 38c11f48a943..084e61cbbbd6 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -1588,7 +1588,6 @@ void CFlowOutput::LoadVolumeDataScalar(const CConfig* config, const CSolver* con case SPECIES_MODEL::SPECIES_TRANSPORT: { const auto Node_Species = solver[SPECIES_SOL]->GetNodes(); - for (unsigned long iVar = 0; iVar < config->GetnSpecies(); iVar++) { SetVolumeOutputValue("SPECIES_" + std::to_string(iVar), iPoint, Node_Species->GetSolution(iPoint, iVar)); SetVolumeOutputValue("RES_SPECIES_" + std::to_string(iVar), iPoint, solver[SPECIES_SOL]->LinSysRes(iPoint, iVar)); diff --git a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp index b7dede100351..af2c19fc7518 100644 --- a/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CNEMOEulerSolver.cpp @@ -894,7 +894,6 @@ void CNEMOEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_con cout << "Chemical: " << eChm_global << endl; cout << "Vib. Relax: " << eVib_global << endl; } - } void CNEMOEulerSolver::ExplicitRK_Iteration(CGeometry *geometry, CSolver **solver_container, From 4f3a9687641285900739541b341d67449c189f80 Mon Sep 17 00:00:00 2001 From: Nijso Date: Sat, 12 Jul 2025 18:00:03 +0200 Subject: [PATCH 50/61] Potential fix for code scanning alert no. 5680: Unused local variable Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- TestCases/py_wrapper/custom_source_buoyancy/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TestCases/py_wrapper/custom_source_buoyancy/run.py b/TestCases/py_wrapper/custom_source_buoyancy/run.py index e6bb9c2480bf..1f4dfbf49a4a 100644 --- a/TestCases/py_wrapper/custom_source_buoyancy/run.py +++ b/TestCases/py_wrapper/custom_source_buoyancy/run.py @@ -59,7 +59,7 @@ def main(): # all the indices and the map to the names of the primitives primindex = driver.GetPrimitiveIndices() - nVars = driver.GetNumberSolverVars(iSOLVER) + varindex = primindex.copy() #for prim in varindex.copy(): # if varindex[prim] >=nVars: From 6a5f28b5c7a8a62fee010f969a2cc02eb419d0f4 Mon Sep 17 00:00:00 2001 From: Nijso Date: Sat, 12 Jul 2025 18:00:21 +0200 Subject: [PATCH 51/61] Potential fix for code scanning alert no. 5546: Unused local variable Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- TestCases/py_wrapper/turbulent_premixed_psi/run.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py index f74c548cc778..2f77e65caf2f 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/run.py +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -111,8 +111,6 @@ def zimont(SU2Driver, iPoint): iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] gradc = SU2Driver.GetGradient(iSPECIESSOLVER,iPoint,0) - - iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] primindex = SU2Driver.GetPrimitiveIndices() iDENSITY = primindex.get("DENSITY") iMU = primindex.get("LAMINAR_VISCOSITY") From 3ca4f2771cb321526224da0d778560e529813575 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Sat, 12 Jul 2025 18:22:12 +0200 Subject: [PATCH 52/61] flamelet now shares python source with species. --- SU2_CFD/src/python_wrapper_structure.cpp | 3 --- SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp | 6 ++---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index e9d1e0d99bb2..db74b5526253 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -58,9 +58,6 @@ void CDriver::PreprocessPythonInterface(CConfig** config, CGeometry**** geometry unsigned long CDriver::GetNumberTimeIter() const { return config_container[selected_zone]->GetnTime_Iter(); } -unsigned long CDriver::GetNumberInnerIter() const { return config_container[selected_zone]->GetnInner_Iter(); } -unsigned long CDriver::GetNumberOuterIter() const { return config_container[selected_zone]->GetnOuter_Iter(); } - passivedouble CDriver::GetDensity_FreeStreamND() const { return SU2_TYPE::GetValue(config_container[selected_zone]->GetDensity_FreeStreamND()); } diff --git a/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp b/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp index f6313062c908..61330ff6d45a 100644 --- a/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesFlameletSolver.cpp @@ -387,10 +387,8 @@ void CSpeciesFlameletSolver::Source_Residual(CGeometry* geometry, CSolver** solv } END_SU2_OMP_FOR - /*--- Custom user defined source term (from the python wrapper) ---*/ - if (config->GetPyCustom_Source() ) { - Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); - } + /*--- call the species solver for the shared sources (axisymmetric and custom python source term) ---*/ + CSpeciesSolver::Source_Residual(geometry, solver_container, numerics_container, config, iMesh); } From be73f1f805708b2e4630cdcc37894c38720f2dfb Mon Sep 17 00:00:00 2001 From: bigfooted Date: Sat, 12 Jul 2025 20:00:19 +0200 Subject: [PATCH 53/61] remove unused setvolume --- SU2_CFD/include/solvers/CSolver.hpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index 86dfd6a20932..b99ffa9d62bb 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -4340,20 +4340,15 @@ inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_contain CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; AD::StartNoSharedReading(); - //SU2_OMP_FOR_STAT(omp_chunk_size) SU2_OMP_FOR_STAT(roundUpDiv(nPointDomain,2*omp_get_max_threads())) for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { - - /*--- Load the volume of the dual mesh cell ---*/ - numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - - /*--- Get control volume size. ---*/ - su2double Volume = geometry->nodes->GetVolume(iPoint); - /*--- Compute the residual for this control volume and subtract. ---*/ - for (auto iVar = 0ul; iVar < nVar; iVar++) { - LinSysRes(iPoint,iVar) -= base_nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; - } + /*--- Get control volume size. ---*/ + su2double Volume = geometry->nodes->GetVolume(iPoint); + /*--- Compute the residual for this control volume and subtract. ---*/ + for (auto iVar = 0ul; iVar < nVar; iVar++) { + LinSysRes(iPoint,iVar) -= base_nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; + } } END_SU2_OMP_FOR From 303424d7540a59d37a36128799b338fd4efb841e Mon Sep 17 00:00:00 2001 From: bigfooted Date: Sat, 12 Jul 2025 20:25:56 +0200 Subject: [PATCH 54/61] remove unused variables --- SU2_CFD/include/solvers/CSolver.hpp | 1 - .../py_wrapper/custom_source_buoyancy/run.py | 15 --------------- .../py_wrapper/turbulent_premixed_psi/run.py | 3 +-- 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index b99ffa9d62bb..f49face812f6 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -4337,7 +4337,6 @@ inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_contain CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { /*--- Pick one numerics object per thread. ---*/ - CNumerics* numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; AD::StartNoSharedReading(); SU2_OMP_FOR_STAT(roundUpDiv(nPointDomain,2*omp_get_max_threads())) diff --git a/TestCases/py_wrapper/custom_source_buoyancy/run.py b/TestCases/py_wrapper/custom_source_buoyancy/run.py index 1f4dfbf49a4a..e09d2faf1c81 100644 --- a/TestCases/py_wrapper/custom_source_buoyancy/run.py +++ b/TestCases/py_wrapper/custom_source_buoyancy/run.py @@ -26,7 +26,6 @@ import sys import pysu2 -import numpy as np # with mpi: from mpi4py import MPI @@ -59,15 +58,7 @@ def main(): # all the indices and the map to the names of the primitives primindex = driver.GetPrimitiveIndices() - - varindex = primindex.copy() - #for prim in varindex.copy(): - # if varindex[prim] >=nVars: - # del varindex[prim] - #varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) - iDENSITY = primindex.get("DENSITY") - #index_Vel = varindex.get("VELOCITY_X") Body_Force_Vector = [0.0, -9.81, 0.0] DensityInc_0 = driver.GetDensity_FreeStreamND() @@ -96,14 +87,8 @@ def main(): driver.Update() # Monitor the solver and output solution to file if required. - #stopcalc = driver.Monitor(inner_iter) driver.Output(inner_iter) - #if (stopcalc): - # if (rank==0): - # "Max iterations or convergence criteria reached, stopping." - # break; - # Finalize the solver and exit cleanly. driver.Finalize() diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py index 2f77e65caf2f..ad0185be0ae7 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/run.py +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -76,7 +76,6 @@ def initC(coord): def SetInitialSpecies(SU2Driver): allCoords = SU2Driver.Coordinates() iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] - nVarsSpecies = SU2Driver.GetNumberSolverVars(iSPECIESSOLVER) for iPoint in range(SU2Driver.GetNumberNodes() - SU2Driver.GetNumberHaloNodes()): coord = allCoords.Get(iPoint) C = initC(coord) @@ -118,7 +117,7 @@ def zimont(SU2Driver, iPoint): # laminar burning velocity of methane-air at phi=0.5, P=5 Slu = 0.232 - rho = SU2Driver.Primitives()(iPoint,iDENSITY) + rho = SU2Driver.Primitives()(iPoint,iDENSITY) mu = SU2Driver.Primitives()(iPoint,iMU) nu=mu/rho # Turbulent Flamespeed Closure with Dinkelacker correction From e14aa3e6053587423058bb507228a3c5ec0582c1 Mon Sep 17 00:00:00 2001 From: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> Date: Mon, 14 Jul 2025 19:41:18 -0700 Subject: [PATCH 55/61] Apply suggestions from code review --- Common/include/CConfig.hpp | 4 +- Common/src/CConfig.cpp | 2 +- SU2_CFD/include/drivers/CDriver.hpp | 4 +- SU2_CFD/include/drivers/CDriverBase.hpp | 20 ---------- SU2_CFD/include/solvers/CSolver.hpp | 8 ++-- SU2_CFD/include/variables/CVariable.hpp | 37 ------------------- SU2_CFD/src/drivers/CDriverBase.cpp | 3 -- SU2_CFD/src/output/CFlowOutput.cpp | 4 +- SU2_CFD/src/python_wrapper_structure.cpp | 4 +- SU2_CFD/src/solvers/CEulerSolver.cpp | 4 +- SU2_CFD/src/solvers/CIncEulerSolver.cpp | 4 +- SU2_CFD/src/solvers/CRadP1Solver.cpp | 4 +- SU2_CFD/src/solvers/CTurbSSTSolver.cpp | 4 +- SU2_CFD/src/variables/CVariable.cpp | 8 +--- .../py_wrapper/custom_source_buoyancy/run.py | 4 +- 15 files changed, 23 insertions(+), 91 deletions(-) diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 7a029f65a78d..cb5a607c9df0 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -707,7 +707,7 @@ class CConfig { Wrt_Restart_Overwrite, /*!< \brief Overwrite restart files or append iteration number.*/ Wrt_Surface_Overwrite, /*!< \brief Overwrite surface output files or append iteration number.*/ Wrt_Volume_Overwrite, /*!< \brief Overwrite volume output files or append iteration number.*/ - PyCustom_Source, /*!< \brief Use a user defined custom source term .*/ + PyCustomSource, /*!< \brief Use a user-defined custom source term .*/ Restart_Flow; /*!< \brief Restart flow solution for adjoint and linearized problems. */ unsigned short nMarker_Monitoring, /*!< \brief Number of markers to monitor. */ nMarker_Designing, /*!< \brief Number of markers for the objective function. */ @@ -3092,7 +3092,7 @@ class CConfig { * \brief Get the Python custom source term activation. * \return Custom source term is active or not. */ - bool GetPyCustom_Source(void) const { return PyCustom_Source; } + bool GetPyCustomSource(void) const { return PyCustomSource; } /*! * \brief Get the total number of moving markers. diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 6eee6ee0281a..af17bd4e6f5c 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -1549,7 +1549,7 @@ void CConfig::SetConfig_Options() { addStringListOption("MARKER_PYTHON_CUSTOM", nMarker_PyCustom, Marker_PyCustom); /*!\brief PYTHON_CUSTOM_SOURCE\n DESCRIPTION: Python custom source \ingroup Config*/ - addBoolOption("PYTHON_CUSTOM_SOURCE", PyCustom_Source, false); + addBoolOption("PYTHON_CUSTOM_SOURCE", PyCustomSource, false); /*!\brief MARKER_WALL_FUNCTIONS\n DESCRIPTION: Viscous wall markers for which wall functions must be applied. Format: (Wall function marker, wall function type, ...) \ingroup Config*/ diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index 9df6532106b5..96b29e75b2dd 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -559,13 +559,13 @@ class CDriver : public CDriverBase { * \brief Get the Freestream Density for nondimensionalization * \return Freestream Density */ - passivedouble GetDensity_FreeStreamND() const; + passivedouble GetDensityFreeStreamND() const; /*! * \brief Get the reference Body force for nondimensionalization * \return reference Body Force */ - passivedouble GetForce_Ref() const; + passivedouble GetForceRef() const; /// \} diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index 4c101598d876..78d6c04bb1ca 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -179,14 +179,6 @@ class CDriverBase { */ unsigned long GetNumberElements() const; - /*! - * \brief Get the number of solution variables - * \return Number of solution variables. - */ - - unsigned short GetNumberSolverVars(const unsigned short iSol) const; - unsigned short GetNumberPrimitiveVars(const unsigned short iSol) const; - /*! * \brief Get the global index of a mesh element. * \param[in] iElem - Mesh element index. @@ -784,18 +776,6 @@ class CDriverBase { return solver; } - /*! - * \brief Automates some boilerplate of accessing solution fields for the python wrapper. - */ - inline CSolver* GetSolverAndCheckField(unsigned short iSolver, - unsigned long iPoint = std::numeric_limits::max()) const { - // 1. check for the solver the number of variables - // 2. check for the mesh the number of points - auto* solver = solver_container[selected_zone][INST_0][MESH_0][iSolver]; - if (solver == nullptr) SU2_MPI::Error("The selected solver does not exist.", CURRENT_FUNCTION); - return solver; - } - /*! * \brief Initialize containers. */ diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index f49face812f6..a90596c11eff 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -4333,20 +4333,18 @@ class CSolver { END_SU2_OMP_FOR } -inline void Custom_Source_Residual(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { +inline void CustomSourceResidual(CGeometry *geometry, CSolver **solver_container, + CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { - /*--- Pick one numerics object per thread. ---*/ AD::StartNoSharedReading(); SU2_OMP_FOR_STAT(roundUpDiv(nPointDomain,2*omp_get_max_threads())) - for (auto iPoint = 0ul; iPoint < nPointDomain; iPoint++) { /*--- Get control volume size. ---*/ su2double Volume = geometry->nodes->GetVolume(iPoint); /*--- Compute the residual for this control volume and subtract. ---*/ for (auto iVar = 0ul; iVar < nVar; iVar++) { - LinSysRes(iPoint,iVar) -= base_nodes->GetUserDefinedSource(iPoint)[iVar] * Volume; + LinSysRes(iPoint,iVar) -= base_nodes->GetUserDefinedSource()(iPoint, iVar) * Volume; } } END_SU2_OMP_FOR diff --git a/SU2_CFD/include/variables/CVariable.hpp b/SU2_CFD/include/variables/CVariable.hpp index 7842cb947957..71052c876137 100644 --- a/SU2_CFD/include/variables/CVariable.hpp +++ b/SU2_CFD/include/variables/CVariable.hpp @@ -291,11 +291,6 @@ class CVariable { */ void Set_Solution_time_n1(); - /*! - * \brief Set the variable solution at time n-1. - */ - void Set_UserDefinedSource(); - /*! * \brief Set the variable solution at time n. * \param[in] iPoint - Point index. @@ -313,15 +308,6 @@ class CVariable { Solution_time_n1(iPoint,iVar) = val_sol[iVar]; } - /*! - * \brief Set the variable solution at time n-1. - * \param[in] iPoint - Point index. - */ - inline void Set_UserDefinedSource(unsigned long iPoint, const su2double* val_sol) { - for (unsigned long iVar = 0; iVar < nVar; iVar++) - UserDefinedSource(iPoint,iVar) = val_sol[iVar]; - } - /*! * \brief Set the variable solution at time n. * \param[in] iPoint - Point index. @@ -338,14 +324,6 @@ class CVariable { Solution_time_n1(iPoint,iVar) = val_sol; } - /*! - * \brief Set the variable solution at time n-1. - * \param[in] iPoint - Point index. - */ - inline void Set_UserDefinedSource(unsigned long iPoint, unsigned long iVar, su2double val_sol) { - UserDefinedSource(iPoint,iVar) = val_sol; - } - /*! * \brief Virtual Member. Specify a vector to set the velocity components of the solution. * Multiplied by density for compressible cases. @@ -516,21 +494,6 @@ class CVariable { inline const MatrixType& GetUserDefinedSource() const { return UserDefinedSource; } inline MatrixType& GetUserDefinedSource() { return UserDefinedSource; } - /*! - * \brief Get the User Defined Source of the problem. - * \param[in] iPoint - Point index. - * \return Pointer to the solution vector. - */ - inline su2double *GetUserDefinedSource(unsigned long iPoint) { return UserDefinedSource[iPoint]; } - - /*! - * \brief Get the User Defined Source of the problem. - * \param[in] iPoint - Point index. - * \param[in] iVar - Scalar index. - * \return Pointer to the solution vector. - */ - inline su2double GetUserDefinedSource(unsigned long iPoint, unsigned long iVar) const { return UserDefinedSource(iPoint,iVar); } - /*! * \brief Get the old solution of the problem (Runge-Kutta method) * \param[in] iPoint - Point index. diff --git a/SU2_CFD/src/drivers/CDriverBase.cpp b/SU2_CFD/src/drivers/CDriverBase.cpp index 36dbdabc088c..fcf9162e0729 100644 --- a/SU2_CFD/src/drivers/CDriverBase.cpp +++ b/SU2_CFD/src/drivers/CDriverBase.cpp @@ -165,9 +165,6 @@ unsigned long CDriverBase::GetNumberDimensions() const { return main_geometry->G unsigned long CDriverBase::GetNumberElements() const { return main_geometry->GetnElem(); } -unsigned short CDriverBase::GetNumberSolverVars(const unsigned short iSol) const { return solver_container[selected_zone][INST_0][MESH_0][iSol]->GetnVar(); } -unsigned short CDriverBase::GetNumberPrimitiveVars(const unsigned short iSol) const { return solver_container[selected_zone][INST_0][MESH_0][iSol]->GetnPrimVar(); } - unsigned long CDriverBase::GetElementGlobalIndex(unsigned long iElem) const { if (iElem >= GetNumberElements()) { SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index 084e61cbbbd6..11befafb4ca9 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -1431,7 +1431,7 @@ void CFlowOutput::SetVolumeOutputFieldsScalarSource(const CConfig* config) { switch (config->GetKind_Species_Model()) { case SPECIES_MODEL::SPECIES_TRANSPORT: - if (config->GetPyCustom_Source()){ + if (config->GetPyCustomSource()) { for (unsigned short iVar = 0; iVar < config->GetnSpecies(); iVar++){ AddVolumeOutput("SPECIES_UDS_" + std::to_string(iVar), "Species_UDS_" + std::to_string(iVar), "SOURCE", "Species User Defined Source " + std::to_string(iVar)); } @@ -1595,7 +1595,7 @@ void CFlowOutput::LoadVolumeDataScalar(const CConfig* config, const CSolver* con if (config->GetKind_SlopeLimit_Species() != LIMITER::NONE) SetVolumeOutputValue("LIMITER_SPECIES_" + std::to_string(iVar), iPoint, Node_Species->GetLimiter(iPoint, iVar)); if (config->GetPyCustom_Source()){ - SetVolumeOutputValue("SPECIES_UDS_" + std::to_string(iVar), iPoint, Node_Species->GetUserDefinedSource(iPoint, iVar)); + SetVolumeOutputValue("SPECIES_UDS_" + std::to_string(iVar), iPoint, Node_Species->GetUserDefinedSource()(iPoint, iVar)); } } break; diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index db74b5526253..1d6ac6ec3e57 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -58,11 +58,11 @@ void CDriver::PreprocessPythonInterface(CConfig** config, CGeometry**** geometry unsigned long CDriver::GetNumberTimeIter() const { return config_container[selected_zone]->GetnTime_Iter(); } -passivedouble CDriver::GetDensity_FreeStreamND() const { +passivedouble CDriver::GetDensityFreeStreamND() const { return SU2_TYPE::GetValue(config_container[selected_zone]->GetDensity_FreeStreamND()); } -passivedouble CDriver::GetForce_Ref() const { +passivedouble CDriver::GetForceRef() const { return SU2_TYPE::GetValue(config_container[selected_zone]->GetForce_Ref()); } diff --git a/SU2_CFD/src/solvers/CEulerSolver.cpp b/SU2_CFD/src/solvers/CEulerSolver.cpp index e7ee82d6c0ef..6ed259a03523 100644 --- a/SU2_CFD/src/solvers/CEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CEulerSolver.cpp @@ -2281,8 +2281,8 @@ void CEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_contain AD::EndNoSharedReading(); /*--- Custom user defined source term (from the python wrapper) ---*/ - if (config->GetPyCustom_Source() ) { - Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + if (config->GetPyCustomSource() ) { + CustomSourceResidual(geometry, solver_container, numerics_container, config, iMesh); } } diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index 94197e4d2a5b..ba17808f80c8 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -1809,8 +1809,8 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont } /*--- Custom user defined source term (from the python wrapper) ---*/ - if (config->GetPyCustom_Source() ) { - Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + if (config->GetPyCustomSource() ) { + CustomSourceResidual(geometry, solver_container, numerics_container, config, iMesh); } } diff --git a/SU2_CFD/src/solvers/CRadP1Solver.cpp b/SU2_CFD/src/solvers/CRadP1Solver.cpp index 15e5364a4876..2cddba7a7c19 100644 --- a/SU2_CFD/src/solvers/CRadP1Solver.cpp +++ b/SU2_CFD/src/solvers/CRadP1Solver.cpp @@ -257,8 +257,8 @@ void CRadP1Solver::Source_Residual(CGeometry *geometry, CSolver **solver_contain } /*--- Custom user defined source term (from the python wrapper) ---*/ - if (config->GetPyCustom_Source() ) { - Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + if (config->GetPyCustomSource()) { + CustomSourceResidual(geometry, solver_container, numerics_container, config, iMesh); } } diff --git a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp index bdf2a57e1156..e041e1308bef 100644 --- a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp @@ -388,8 +388,8 @@ void CTurbSSTSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta AD::EndNoSharedReading(); /*--- Custom user defined source term (from the python wrapper) ---*/ - if (config->GetPyCustom_Source() ) { - Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + if (config->GetPyCustomSource()) { + CustomSourceResidual(geometry, solver_container, numerics_container, config, iMesh); } } diff --git a/SU2_CFD/src/variables/CVariable.cpp b/SU2_CFD/src/variables/CVariable.cpp index af8145e8a608..b68ded9e6687 100644 --- a/SU2_CFD/src/variables/CVariable.cpp +++ b/SU2_CFD/src/variables/CVariable.cpp @@ -65,8 +65,7 @@ CVariable::CVariable(unsigned long npoint, unsigned long ndim, unsigned long nva Solution_time_n1.resize(nPoint,nVar) = su2double(0.0); /*--- User defined source terms ---*/ - UserDefinedSource.resize(nPoint,nVar) = su2double(0.0); - + if (config->GetPyCustomSource()) UserDefinedSource.resize(nPoint,nVar) = su2double(0.0); if (config->GetDiscrete_Adjoint()) { if (adjoint && config->GetMultizone_Problem()) @@ -102,11 +101,6 @@ void CVariable::Set_Solution_time_n1() { parallelCopy(Solution_time_n.size(), Solution_time_n.data(), Solution_time_n1.data()); } -void CVariable::Set_UserDefinedSource() { - assert(UserDefinedSource.size() == UserDefinedSource.size()); - parallelCopy(UserDefinedSource.size(), UserDefinedSource.data(), UserDefinedSource.data()); -} - void CVariable::Set_BGSSolution_k() { assert(Solution_BGS_k.size() == Solution.size()); parallelCopy(Solution.size(), Solution.data(), Solution_BGS_k.data()); diff --git a/TestCases/py_wrapper/custom_source_buoyancy/run.py b/TestCases/py_wrapper/custom_source_buoyancy/run.py index e09d2faf1c81..f07dfdc3570c 100644 --- a/TestCases/py_wrapper/custom_source_buoyancy/run.py +++ b/TestCases/py_wrapper/custom_source_buoyancy/run.py @@ -61,8 +61,8 @@ def main(): iDENSITY = primindex.get("DENSITY") Body_Force_Vector = [0.0, -9.81, 0.0] - DensityInc_0 = driver.GetDensity_FreeStreamND() - Force_Ref = driver.GetForce_Ref() + DensityInc_0 = driver.GetDensityFreeStreamND() + Force_Ref = driver.GetForceRef() # super important to actually push the commands. sys.stdout.flush() From b209f4c203f38788416395ff8d04bc210b9cbb59 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Mon, 14 Jul 2025 20:38:39 -0700 Subject: [PATCH 56/61] 3D matrix view --- .../containers/CPyWrapperMatrixView.hpp | 76 +++++++++++++++++++ .../containers/container_decorators.hpp | 5 ++ 2 files changed, 81 insertions(+) diff --git a/Common/include/containers/CPyWrapperMatrixView.hpp b/Common/include/containers/CPyWrapperMatrixView.hpp index 6925c48e44ad..367c889bc556 100644 --- a/Common/include/containers/CPyWrapperMatrixView.hpp +++ b/Common/include/containers/CPyWrapperMatrixView.hpp @@ -54,6 +54,8 @@ \ /*! \brief Gets the value for a (row, column) pair. */ \ passivedouble operator()(unsigned long row, unsigned long col) const { return Get(row, col); } \ + \ + /*! \brief Gets the values for a row of the matrix. */ \ std::vector operator()(unsigned long row) const { return Get(row); } \ \ /*! \brief Gets the value for a (row, column) pair. */ \ @@ -164,3 +166,77 @@ class CPyWrapperMarkerMatrixView { /*--- Use the macro to generate the interface. ---*/ PY_WRAPPER_MATRIX_INTERFACE }; + +/*! + * \class CPyWrapper3DMatrixView + * \ingroup PySU2 + * \brief This class wraps C3DDoubleMatrix for the python wrapper matrix interface. + * It is generaly used to wrap access to solver gradients defined for the entire volume. + */ +class CPyWrapper3DMatrixView { + protected: + static_assert(su2activematrix::IsRowMajor, ""); + su2double* data_ = nullptr; + unsigned long rows_ = 0, cols_ = 0, dims_ = 0; + std::string name_; + bool read_only_ = false; + + /*--- Define the functions required by the interface macro. ---*/ + inline const su2double& Access(unsigned long row, unsigned long col, unsigned long dim) const { + if (row > rows_ || col > cols_ || dim > dims_) SU2_MPI::Error(name_ + " out of bounds", "CPyWrapper3DMatrixView"); + return data_[row * (cols_ * dims_) + col * dims_ + dim]; + } + inline su2double& Access(unsigned long row, unsigned long col, unsigned long dim) { + if (read_only_) SU2_MPI::Error(name_ + " is read-only", "CPyWrapper3DMatrixView"); + const auto& const_me = *this; + return const_cast(const_me.Access(row, col, dim)); + } + + public: + CPyWrapper3DMatrixView() = default; + + /*! + * \brief Construct the view of the matrix. + * \note "name" should be set to the variable name being returned to give better information to users. + * \note "read_only" can be set to true to prevent the data from being modified. + */ + CPyWrapper3DMatrixView(C3DDoubleMatrix& mat, const std::string& name, bool read_only) + : data_(mat.data()), + rows_(mat.length()), + cols_(mat.rows()), + dims_(mat.cols()), + name_(name), + read_only_(read_only) {} + + /*! \brief Returns the shape of the matrix. */ + std::vector Shape() const { return {rows_, cols_, dims_}; } + + /*! \brief Returns whether the data is read-only [true] or if it can be modified [false]. */ + bool IsReadOnly() const { return read_only_; } + + /*! \brief Gets the value for a (row, column, dimension) triplet. */ + passivedouble operator()(unsigned long row, unsigned long col, unsigned long dim) const { return Get(row, col, dim); } + + /*! \brief Gets the values for a row and column of the matrix. */ + std::vector operator()(unsigned long row, unsigned long col) const { return Get(row, col); } + + /*! \brief Gets the value for a (row, column, dimension) triplet. */ + passivedouble Get(unsigned long row, unsigned long col, unsigned long dim) const { + return SU2_TYPE::GetValue(Access(row, col, dim)); + } + + /*! \brief Gets the values for a row and column of the matrix. */ + std::vector Get(unsigned long row, unsigned long col) const { + std::vector vals(dims_); + for (unsigned long j = 0; j < dims_; ++j) vals[j] = Get(row, col, j); + return vals; + } + /*! \brief Sets the value for a (row, column, dimension) triplet. This clears derivative information. */ + void Set(unsigned long row, unsigned long col, unsigned long dim, passivedouble val) { Access(row, col, dim) = val; } + + /*! \brief Sets the values for a row and column of the matrix. */ + void Set(unsigned long row, unsigned long col, std::vector vals) { + unsigned long j = 0; + for (const auto& val : vals) Set(row, col, j++, val); + } +}; diff --git a/Common/include/containers/container_decorators.hpp b/Common/include/containers/container_decorators.hpp index 0c2eae1c296d..435f6acdb69c 100644 --- a/Common/include/containers/container_decorators.hpp +++ b/Common/include/containers/container_decorators.hpp @@ -165,6 +165,11 @@ class C3DContainerDecorator { FORCEINLINE StaticContainer get(Int i, Index j = 0) const noexcept { return m_storage.template get(i, j * m_innerSz); } + + /*! + * \brief Raw data access, for Python wrapper. + */ + FORCEINLINE Scalar* data() { return m_storage.data(); } }; /*! From b78afd9ad774c64809a0eef7d05a844607fe20d4 Mon Sep 17 00:00:00 2001 From: Nijso Date: Tue, 15 Jul 2025 22:09:19 +0200 Subject: [PATCH 57/61] Update SU2_CFD/src/solvers/CTurbSASolver.cpp Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> --- SU2_CFD/src/solvers/CTurbSASolver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SU2_CFD/src/solvers/CTurbSASolver.cpp b/SU2_CFD/src/solvers/CTurbSASolver.cpp index e4d645d608d0..0fb9c5656548 100644 --- a/SU2_CFD/src/solvers/CTurbSASolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSASolver.cpp @@ -493,8 +493,8 @@ void CTurbSASolver::Source_Residual(CGeometry *geometry, CSolver **solver_contai AD::EndNoSharedReading(); /*--- Custom user defined source term (from the python wrapper) ---*/ - if (config->GetPyCustom_Source() ) { - Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + if (config->GetPyCustomSource()) { + CustomSourceResidual(geometry, solver_container, numerics_container, config, iMesh); } } From fc01bbfa0f47e70fb7f363e99a8f53d20230bc07 Mon Sep 17 00:00:00 2001 From: Nijso Date: Tue, 15 Jul 2025 22:10:21 +0200 Subject: [PATCH 58/61] Update SU2_CFD/src/solvers/CSpeciesSolver.cpp Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> --- SU2_CFD/src/solvers/CSpeciesSolver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SU2_CFD/src/solvers/CSpeciesSolver.cpp b/SU2_CFD/src/solvers/CSpeciesSolver.cpp index 8900ddb49fad..e1b4b9dc1c47 100644 --- a/SU2_CFD/src/solvers/CSpeciesSolver.cpp +++ b/SU2_CFD/src/solvers/CSpeciesSolver.cpp @@ -565,8 +565,8 @@ void CSpeciesSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta } /*--- Custom user defined source term (from the python wrapper) ---*/ - if (config->GetPyCustom_Source() ) { - Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + if (config->GetPyCustomSource()) { + CustomSourceResidual(geometry, solver_container, numerics_container, config, iMesh); } } From 1fa0053f951842b6b05c682a6b937280845aac05 Mon Sep 17 00:00:00 2001 From: Nijso Date: Tue, 15 Jul 2025 22:10:43 +0200 Subject: [PATCH 59/61] Update SU2_CFD/src/solvers/CTransLMSolver.cpp Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> --- SU2_CFD/src/solvers/CTransLMSolver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index e0f1b9bcb3a1..0228a28cb669 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -353,8 +353,8 @@ void CTransLMSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta AD::EndNoSharedReading(); /*--- Custom user defined source term (from the python wrapper) ---*/ - if (config->GetPyCustom_Source() ) { - Custom_Source_Residual(geometry, solver_container, numerics_container, config, iMesh); + if (config->GetPyCustomSource()) { + CustomSourceResidual(geometry, solver_container, numerics_container, config, iMesh); } } From ceb3b399bb8d5a3695b393ae20444c3d268e636e Mon Sep 17 00:00:00 2001 From: bigfooted Date: Tue, 15 Jul 2025 23:53:12 +0200 Subject: [PATCH 60/61] changes from code review --- SU2_CFD/include/drivers/CDriverBase.hpp | 27 +++++++------------ SU2_CFD/src/output/CFlowOutput.cpp | 2 +- .../py_wrapper/turbulent_premixed_psi/run.py | 20 +++++++------- 3 files changed, 20 insertions(+), 29 deletions(-) diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index 78d6c04bb1ca..b5dc5b6d30e1 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -445,7 +445,15 @@ class CDriverBase { } /*! - * \brief Get a read/write view of the usrr defined source on all mesh nodes of a solver. + * \brief Get read/write view of the gradients of a solver variable in a point. + */ + inline CPyWrapper3DMatrixView Gradient(unsigned short iSolver) { + auto* solver = GetSolverAndCheckMarker(iSolver); + return CPyWrapper3DMatrixView(solver->GetNodes()->GetGradient(), "Gradient of " + solver->GetSolverName(), false); + } + + /*! + * \brief Get a read/write view of the user defined source on all mesh nodes of a solver. */ inline CPyWrapperMatrixView UserDefinedSource(unsigned short iSolver) { auto* solver = GetSolverAndCheckMarker(iSolver); @@ -676,23 +684,6 @@ class CDriverBase { return sens; } - /*! - * \brief Get the gradients of a solver variable in a point. - * \returns Vector of gradients grad(iVar). - */ - inline vector GetGradient(unsigned short iSolver, unsigned long iPoint, unsigned short iVar) { - const auto nDim = GetNumberDimensions(); - auto* solver = GetSolverAndCheckMarker(iSolver); - auto* nodes = solver->GetNodes(); - - vector grad(nDim, 0.0); - for (auto iDim = 0u; iDim < nDim; ++iDim) { - grad[iDim] = SU2_TYPE::GetValue(nodes->GetGradient(iPoint, iVar, iDim)); - } - return grad; - } - - /*! * \brief Set the adjoint of the structural displacements. * \note This can be the input of the FEA solver in an adjoint FSI setting. diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index 11befafb4ca9..aae57d7fb0d0 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -1594,7 +1594,7 @@ void CFlowOutput::LoadVolumeDataScalar(const CConfig* config, const CSolver* con SetVolumeOutputValue("DIFFUSIVITY_"+ std::to_string(iVar), iPoint, Node_Species->GetDiffusivity(iPoint,iVar)); if (config->GetKind_SlopeLimit_Species() != LIMITER::NONE) SetVolumeOutputValue("LIMITER_SPECIES_" + std::to_string(iVar), iPoint, Node_Species->GetLimiter(iPoint, iVar)); - if (config->GetPyCustom_Source()){ + if (config->GetPyCustomSource()){ SetVolumeOutputValue("SPECIES_UDS_" + std::to_string(iVar), iPoint, Node_Species->GetUserDefinedSource()(iPoint, iVar)); } } diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py index ad0185be0ae7..c53821a51043 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/run.py +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -39,21 +39,22 @@ # flame temperature of the methane-air mixture (phi=0.5, P=5) Tf = 1777 -# unburnt temperature of the propane-air mixture (phi=0.5, P=5) +# unburnt temperature of the methane-air mixture (phi=0.5, P=5) Tu = 673.0 Pu = 5.0 phi = 0.5 # unburnt density at P=5 rho_u = 2.52 -# unburnt thermal conductivity of methane-air at phi=0.5 (phi=0.5, P=5) +# unburnt thermal conductivity of methane-air (phi=0.5, P=5) k_u = 0.0523 -# unburnt heat capacity of methane-air at phi=0.5 (P=5) +# unburnt heat capacity of methane-air (phi=0.5, P=5) cp_u = 1311.0 # P = rho*R*T # 5 = 2.55 * R * 673 # R = 0.0029 + # ################################################################## # # create a function for the initial progress variable c # # ################################################################## # @@ -80,7 +81,6 @@ def SetInitialSpecies(SU2Driver): coord = allCoords.Get(iPoint) C = initC(coord) # now update the initial condition for the species - #SU2Driver.SetSolutionVector(iSPECIESSOLVER, iPoint, [C]) SU2Driver.Solution(iSPECIESSOLVER).Set(iPoint,0,C) # ################################################################## # @@ -105,11 +105,11 @@ def update_temperature(SU2Driver, iPoint): def zimont(SU2Driver, iPoint): iSSTSOLVER = SU2Driver.GetSolverIndices()['SST'] - #tke, dissipation = SU2Driver.GetSolutionVector(iSSTSOLVER,iPoint) tke, dissipation = SU2Driver.Solution(iSSTSOLVER)(iPoint) iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] - gradc = SU2Driver.GetGradient(iSPECIESSOLVER,iPoint,0) + # get the gradient of species_0 + gradc = SU2Driver.Gradient(iSPECIESSOLVER)(iPoint,0) primindex = SU2Driver.GetPrimitiveIndices() iDENSITY = primindex.get("DENSITY") iMU = primindex.get("LAMINAR_VISCOSITY") @@ -137,7 +137,7 @@ def zimont(SU2Driver, iPoint): def getsolvar(SU2Driver): primindex = SU2Driver.GetPrimitiveIndices() iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] - nVars = SU2Driver.GetNumberSolverVars(iFLOWSOLVER) + nVars = SU2Driver.Solution(iFLOWSOLVER).Shape()[1] varindex = primindex.copy() for prim in varindex.copy(): if varindex[prim] >=nVars: @@ -177,9 +177,9 @@ def main(): # all the indices and the map to the names of the primitives primindex = driver.GetPrimitiveIndices() nElem = driver.GetNumberElements() - nVars = driver.GetNumberSolverVars(iFLOWSOLVER) - nVarsSpecies = driver.GetNumberSolverVars(iSPECIESSOLVER) - nVarsTurb = driver.GetNumberSolverVars(iSSTSOLVER) + nVars = driver.Solution(iFLOWSOLVER).Shape()[1] + nVarsSpecies = driver.Solution(iSPECIESSOLVER).Shape()[1] + nVarsTurb = driver.Solution(iSSTSOLVER).Shape()[1] if rank == 0: print("Dimensions of the problem = ",nDim) From 33dc79b6d0b39a2b1739901ad99a1101aa2e6da6 Mon Sep 17 00:00:00 2001 From: bigfooted Date: Wed, 16 Jul 2025 06:40:08 +0200 Subject: [PATCH 61/61] move pywrapper matrix out of loop --- TestCases/py_wrapper/turbulent_premixed_psi/run.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/TestCases/py_wrapper/turbulent_premixed_psi/run.py b/TestCases/py_wrapper/turbulent_premixed_psi/run.py index c53821a51043..8b418785bbc3 100644 --- a/TestCases/py_wrapper/turbulent_premixed_psi/run.py +++ b/TestCases/py_wrapper/turbulent_premixed_psi/run.py @@ -216,12 +216,14 @@ def main(): driver.Preprocess(inner_iter) driver.Run() + Source = driver.UserDefinedSource(iSPECIESSOLVER) + # set the source term, per point for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): # add source term: # default TFC of Zimont: rho*Sc = rho_u * U_t * grad(c) S = zimont(driver,i_node) - driver.UserDefinedSource(iSPECIESSOLVER).Set(i_node,0,S) + Source.Set(i_node,0,S) # for the update of temperature, we need to update also the halo nodes for i_node in range(driver.GetNumberNodes()):