From a7136d32c0f1c9b50c77a5779d9778b35359fcee Mon Sep 17 00:00:00 2001 From: rois1995 Date: Fri, 27 Jan 2023 18:21:13 +0100 Subject: [PATCH 01/20] - Just copied the CTransLMSolver header and source to commit --- SU2_CFD/include/solvers/CTransSLMSolver.hpp | 218 +++++++ SU2_CFD/src/solvers/CTransSLMSolver.cpp | 602 ++++++++++++++++++++ 2 files changed, 820 insertions(+) create mode 100644 SU2_CFD/include/solvers/CTransSLMSolver.hpp create mode 100644 SU2_CFD/src/solvers/CTransSLMSolver.cpp diff --git a/SU2_CFD/include/solvers/CTransSLMSolver.hpp b/SU2_CFD/include/solvers/CTransSLMSolver.hpp new file mode 100644 index 00000000000..acdf90fb9a4 --- /dev/null +++ b/SU2_CFD/include/solvers/CTransSLMSolver.hpp @@ -0,0 +1,218 @@ +/*! + * \file CTransLMSolver.hpp + * \brief Headers of the CTransLMSolver class + * \author A. Aranake + * \version 7.5.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "CTurbSolver.hpp" +#include "../numerics/turbulent/transition/trans_correlations.hpp" + +/*! + * \class CTransLMSolver + * \brief Main class for defining the transition model solver. + * \ingroup Turbulence_Model + * \author A. Aranake, S. Kang. + */ + +class CTransLMSolver final : public CTurbSolver { +private: + + LM_ParsedOptions options; + TURB_FAMILY TurbFamily; + + TransLMCorrelations TransCorrelations; + +public: + /*! + * \overload + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); + + /*! + * \brief Destructor of the class. + */ + ~CTransLMSolver() = default; + + /*! + * \brief Restart residual and compute gradients. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + * \param[in] iRKStep - Current step of the Runge-Kutta iteration. + * \param[in] RunTime_EqSystem - System of equations which is going to be solved. + * \param[in] Output - boolean to determine whether to print output. + */ + void Preprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh, + unsigned short iRKStep, + unsigned short RunTime_EqSystem, + bool Output) override; + + /*! + * \brief Computes the effective intermtittency. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Postprocessing(CGeometry *geometry, + CSolver **solver_container, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Compute the viscous flux for the LM equation at a particular edge. + * \param[in] iEdge - Edge for which we want to compute the flux + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \note Calls a generic implementation after defining a SolverSpecificNumerics object. + */ + void Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, + CNumerics* numerics, CConfig* config) override; + + /*! + * \brief Source term computation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics_container - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Residual(CGeometry *geometry, + CSolver **solver_container, + CNumerics **numerics_container, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Source term computation. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] iMesh - Index of the mesh in multigrid computations. + */ + void Source_Template(CGeometry *geometry, + CSolver **solver_container, + CNumerics *numerics, + CConfig *config, + unsigned short iMesh) override; + + /*! + * \brief Impose the Langtry Menter transition 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 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 inlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Inlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Impose the outlet boundary condition. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] conv_numerics - Description of the numerical method. + * \param[in] visc_numerics - Description of the numerical method. + * \param[in] config - Definition of the particular problem. + * \param[in] val_marker - Surface marker where the boundary condition is applied. + */ + void BC_Outlet(CGeometry *geometry, + CSolver **solver_container, + CNumerics *conv_numerics, + CNumerics *visc_numerics, + CConfig *config, + unsigned short val_marker) override; + + /*! + * \brief Get the value of the intermittency. + * \return Value of the turbulent kinetic energy. + */ + inline su2double GetIntermittency_Inf(void) const override { return Solution_Inf[0]; } + + /*! + * \brief Get the value of the intermittency. + * \return Value of the turbulent kinetic energy. + */ + inline su2double GetReThetaT_Inf(void) const override { return Solution_Inf[1]; } + + /*! + * \brief Load a solution from a restart file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all of the solvers. + * \param[in] config - Definition of the particular problem. + * \param[in] val_iter - Current external iteration number. + * \param[in] val_update_geo - Flag for updating coords and grid velocity. + */ + void LoadRestart(CGeometry** geometry, CSolver*** solver, CConfig* config, int val_iter, bool val_update_geo) final; + +}; diff --git a/SU2_CFD/src/solvers/CTransSLMSolver.cpp b/SU2_CFD/src/solvers/CTransSLMSolver.cpp new file mode 100644 index 00000000000..01a254e98b7 --- /dev/null +++ b/SU2_CFD/src/solvers/CTransSLMSolver.cpp @@ -0,0 +1,602 @@ +/*! + * \file CTransLMSolver.cpp + * \brief Main subroutines for Langtry-Menter Transition model solver. + * \author A. Aranake, S. Kang. + * \version 7.5.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#include "../../include/solvers/CTransLMSolver.hpp" +#include "../../include/variables/CTransLMVariable.hpp" +#include "../../include/variables/CFlowVariable.hpp" +#include "../../include/variables/CTurbSAVariable.hpp" +#include "../../../Common/include/parallelization/omp_structure.hpp" +#include "../../../Common/include/toolboxes/geometry_toolbox.hpp" + +/*--- This is the implementation of the Langtry-Menter transition model. + The main reference for this model is:Langtry, Menter, AIAA J. 47(12) 2009 + DOI: https://doi.org/10.2514/1.42362 ---*/ + +// Note: TransLM seems to use rho*gamma, rho*Re_sigma as Solution variables, thus Conservative=true + +CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) + : CTurbSolver(geometry, config, true) { + unsigned long iPoint; + ifstream restart_file; + string text_line; + + bool multizone = config->GetMultizone_Problem(); + + /*--- Dimension of the problem --> 2 Transport equations (intermittency, Reth) ---*/ + nVar = 2; + nPrimVar = 2; + nPoint = geometry->GetnPoint(); + nPointDomain = geometry->GetnPointDomain(); + + /*--- Initialize nVarGrad for deallocation ---*/ + + nVarGrad = nVar; + + /*--- Define geometry constants in the solver structure ---*/ + + nDim = geometry->GetnDim(); + + /*--- Define variables needed for transition from config file */ + options = config->GetLMParsedOptions(); + TransCorrelations.SetOptions(options); + TurbFamily = TurbModelFamily(config->GetKind_Turb_Model()); + + /*--- Single grid simulation ---*/ + + if (iMesh == MESH_0) { + + /*--- Define some auxiliary vector related with the residual ---*/ + + Residual_RMS.resize(nVar,0.0); + Residual_Max.resize(nVar,0.0); + Point_Max.resize(nVar,0); + Point_Max_Coord.resize(nVar,nDim) = su2double(0.0); + + /*--- Initialization of the structure of the whole Jacobian ---*/ + + if (rank == MASTER_NODE) cout << "Initialize Jacobian structure (LM transition model)." << endl; + Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config, ReducerStrategy); + LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); + LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); + System.SetxIsZero(true); + + if (ReducerStrategy) + EdgeFluxes.Initialize(geometry->GetnEdge(), geometry->GetnEdge(), nVar, nullptr); + + /*--- Initialize the BGS residuals in multizone problems. ---*/ + if (multizone){ + Residual_BGS.resize(nVar,0.0); + Residual_Max_BGS.resize(nVar,0.0); + Point_Max_BGS.resize(nVar,0); + Point_Max_Coord_BGS.resize(nVar,nDim) = su2double(0.0); + } + + } + + /*--- Initialize lower and upper limits---*/ + lowerlimit[0] = 1.0e-4; + upperlimit[0] = 5.0; + + lowerlimit[1] = 1.0e-4; + upperlimit[1] = 1.0e15; + + /*--- Far-field flow state quantities and initialization. ---*/ + const su2double Intensity = config->GetTurbulenceIntensity_FreeStream()*100.0; + + const su2double Intermittency_Inf = 1.0; + su2double ReThetaT_Inf = 100.0; + + /*--- Momentum thickness Reynolds number, initialized from freestream turbulent intensity*/ + if (Intensity <= 1.3) { + if(Intensity >=0.027) { + ReThetaT_Inf = (1173.51-589.428*Intensity+0.2196/(Intensity*Intensity)); + } + else { + ReThetaT_Inf = (1173.51-589.428*Intensity+0.2196/(0.27*0.27)); + } + } + else if(Intensity>1.3) { + ReThetaT_Inf = 331.5*pow(Intensity-0.5658,-0.671); + } + + Solution_Inf[0] = Intermittency_Inf; + Solution_Inf[1] = ReThetaT_Inf; + + /*--- Initialize the solution to the far-field state everywhere. ---*/ + nodes = new CTransLMVariable(Intermittency_Inf, ReThetaT_Inf, 1.0, 1.0, nPoint, nDim, nVar, config); + SetBaseClassPointerToNodes(); + + /*--- MPI solution ---*/ + + InitiateComms(geometry, config, SOLUTION); + CompleteComms(geometry, config, SOLUTION); + + /*--- Initializate quantities for SlidingMesh Interface ---*/ + + SlidingState.resize(nMarker); + SlidingStateNodes.resize(nMarker); + + for (unsigned long iMarker = 0; iMarker < nMarker; iMarker++) { + if (config->GetMarker_All_KindBC(iMarker) == FLUID_INTERFACE) { + SlidingState[iMarker].resize(nVertex[iMarker], nPrimVar+1) = nullptr; + SlidingStateNodes[iMarker].resize(nVertex[iMarker],0); + } + } + + /*-- Allocation of inlets has to happen in derived classes (not CTurbSolver), + due to arbitrary number of turbulence variables ---*/ + + Inlet_TurbVars.resize(nMarker); + for (unsigned long iMarker = 0; iMarker < nMarker; iMarker++) { + Inlet_TurbVars[iMarker].resize(nVertex[iMarker],nVar); + for (unsigned long iVertex = 0; iVertex < nVertex[iMarker]; ++iVertex) { + Inlet_TurbVars[iMarker](iVertex,0) = Intermittency_Inf; + Inlet_TurbVars[iMarker](iVertex,1) = ReThetaT_Inf; + } + } + + const su2double CFL = config->GetCFL(MGLevel)*config->GetCFLRedCoeff_Turb(); + for (iPoint = 0; iPoint < nPoint; iPoint++) { + nodes->SetLocalCFL(iPoint, CFL); + } + Min_CFL_Local = CFL; + Max_CFL_Local = CFL; + Avg_CFL_Local = CFL; + + /*--- Add the solver name (max 8 characters) ---*/ + SolverName = "LM model"; + +} + +void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, + unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { + SU2_OMP_SAFE_GLOBAL_ACCESS(config->SetGlobalParam(config->GetKind_Solver(), RunTime_EqSystem);) + + /*--- Upwind second order reconstruction and gradients ---*/ + CommonPreprocessing(geometry, config, Output); +} + +void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh) { + + /*--- Compute LM model gradients. ---*/ + + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { + SetSolution_Gradient_GG(geometry, config); + } + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + SetSolution_Gradient_LS(geometry, config); + } + + AD::StartNoSharedReading(); + auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); + auto* turbNodes = su2staticcast_p(solver_container[TURB_SOL]->GetNodes()); + + SU2_OMP_FOR_STAT(omp_chunk_size) + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { + + // Here the nodes already have the new solution, thus I have to compute everything from scratch + + const su2double rho = flowNodes->GetDensity(iPoint); + const su2double mu = flowNodes->GetLaminarViscosity(iPoint); + const su2double muT = turbNodes->GetmuT(iPoint); + const su2double dist = geometry->nodes->GetWall_Distance(iPoint); + su2double VorticityMag = GeometryToolbox::Norm(3, flowNodes->GetVorticity(iPoint)); + su2double StrainMag =flowNodes->GetStrainMag(iPoint); + VorticityMag = max(VorticityMag, 1e-12); + StrainMag = max(StrainMag, 1e-12); // safety against division by zero + const su2double Intermittency = nodes->GetSolution(iPoint,0); + const su2double Re_t = nodes->GetSolution(iPoint,1); + const su2double Re_v = rho*dist*dist*StrainMag/mu; + const su2double vel_u = flowNodes->GetVelocity(iPoint, 0); + const su2double vel_v = flowNodes->GetVelocity(iPoint, 1); + const su2double vel_w = (nDim ==3) ? flowNodes->GetVelocity(iPoint, 2) : 0.0; + const su2double VelocityMag = sqrt(vel_u*vel_u + vel_v*vel_v + vel_w*vel_w); + su2double omega = 0.0; + su2double k = 0.0; + if(TurbFamily == TURB_FAMILY::KW){ + omega = turbNodes->GetSolution(iPoint,1); + k = turbNodes->GetSolution(iPoint,0); + } + su2double Tu = 1.0; + if(TurbFamily == TURB_FAMILY::KW) + Tu = max(100.0*sqrt( 2.0 * k / 3.0 ) / VelocityMag,0.027); + if(TurbFamily == TURB_FAMILY::SA) + Tu = config->GetTurbulenceIntensity_FreeStream()*100; + + const su2double Corr_Rec = TransCorrelations.ReThetaC_Correlations(Tu, Re_t); + + su2double R_t = 1.0; + if(TurbFamily == TURB_FAMILY::KW) + R_t = rho*k/ mu/ omega; + if(TurbFamily == TURB_FAMILY::SA) + R_t = muT/ mu; + + const su2double f_reattach = exp(-pow(R_t/20,4)); + su2double f_wake = 0.0; + if(TurbFamily == TURB_FAMILY::KW){ + const su2double re_omega = rho*omega*dist*dist/mu; + f_wake = exp(-pow(re_omega/(1.0e+05),2)); + } + if(TurbFamily == TURB_FAMILY::SA) + f_wake = 1.0; + + const su2double theta_bl = Re_t*mu / rho /VelocityMag; + const su2double delta_bl = 7.5*theta_bl; + const su2double delta = 50.0*VorticityMag*dist/VelocityMag*delta_bl + 1e-20; + const su2double var1 = (Intermittency-1.0/50.0)/(1.0-1.0/50.0); + const su2double var2 = 1.0 - pow(var1,2.0); + const su2double f_theta = min(max(f_wake*exp(-pow(dist/delta, 4)), var2), 1.0); + su2double Intermittency_Sep = 2.0*max(0.0, Re_v/(3.235*Corr_Rec)-1.0)*f_reattach; + Intermittency_Sep = min(Intermittency_Sep,2.0)*f_theta; + Intermittency_Sep = min(max(0.0, Intermittency_Sep), 2.0); + nodes -> SetIntermittencySep(iPoint, Intermittency_Sep); + nodes -> SetIntermittencyEff(iPoint, Intermittency_Sep); + + } + END_SU2_OMP_FOR + + AD::EndNoSharedReading(); +} + + +void CTransLMSolver::Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, + CNumerics* numerics, CConfig* config) { + + /*--- Define an object to set solver specific numerics contribution. ---*/ + + auto SolverSpecificNumerics = [&](unsigned long iPoint, unsigned long jPoint) {}; + + /*--- Now instantiate the generic implementation with the functor above. ---*/ + + Viscous_Residual_impl(SolverSpecificNumerics, iEdge, geometry, solver_container, numerics, config); +} + + +void CTransLMSolver::Source_Residual(CGeometry *geometry, CSolver **solver_container, + CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { + + const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); + + auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); + //auto* turbNodes = su2staticcast_p(solver_container[TURB_SOL]->GetNodes()); + CVariable* turbNodes = solver_container[TURB_SOL]->GetNodes(); + + /*--- Pick one numerics object per thread. ---*/ + auto* numerics = numerics_container[SOURCE_FIRST_TERM + omp_get_thread_num()*MAX_TERMS]; + + /*--- Loop over all points. ---*/ + + AD::StartNoSharedReading(); + + SU2_OMP_FOR_DYN(omp_chunk_size) + for (unsigned long iPoint = 0; iPoint < nPointDomain; iPoint++) { + + + + /*--- Conservative variables w/o reconstruction ---*/ + + numerics->SetPrimitive(flowNodes->GetPrimitive(iPoint), nullptr); + + /*--- Gradient of the primitive and conservative variables ---*/ + + numerics->SetPrimVarGradient(flowNodes->GetGradient_Primitive(iPoint), nullptr); + + /*--- Turbulent variables w/o reconstruction, and its gradient ---*/ + /*--- ScalarVar & ScalarVarGradient : Turbulence model solution(k&w) ---*/ + + numerics->SetScalarVar(turbNodes->GetSolution(iPoint), nullptr); + numerics->SetScalarVarGradient(turbNodes->GetGradient(iPoint), nullptr); + + /*--- Transition variables w/o reconstruction, and its gradient ---*/ + + numerics->SetTransVar(nodes->GetSolution(iPoint), nullptr); + numerics->SetTransVarGradient(nodes->GetGradient(iPoint), nullptr); + + /*--- Set volume ---*/ + + numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + + /*--- Set distance to the surface ---*/ + + numerics->SetDistance(geometry->nodes->GetWall_Distance(iPoint), 0.0); + + /*--- Set vorticity and strain rate magnitude ---*/ + + numerics->SetVorticity(flowNodes->GetVorticity(iPoint), nullptr); + + numerics->SetStrainMag(flowNodes->GetStrainMag(iPoint), 0.0); + + /*--- Set coordinate (for debugging) ---*/ + numerics->SetCoord(geometry->nodes->GetCoord(iPoint), nullptr); + + if (options.LM2015) { + /*--- Set local grid length (for LM2015)*/ + numerics->SetLocalGridLength(geometry->nodes->GetMaxLength(iPoint)); + } + + /*--- Compute the source term ---*/ + + auto residual = numerics->ComputeResidual(config); + + /*--- Subtract residual and the Jacobian ---*/ + + LinSysRes.SubtractBlock(iPoint, residual); + if (implicit) Jacobian.SubtractBlock2Diag(iPoint, residual.jacobian_i); + + } + END_SU2_OMP_FOR + + AD::EndNoSharedReading(); + +} + +void CTransLMSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, + CConfig *config, unsigned short iMesh) { +} + +void CTransLMSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, + CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); + + SU2_OMP_FOR_STAT(OMP_MIN_SIZE) + for (auto iVertex = 0u; iVertex < geometry->nVertex[val_marker]; iVertex++) { + + const auto iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ + + if (geometry->nodes->GetDomain(iPoint)) { + + /*--- Allocate the value at the infinity ---*/ + + auto V_infty = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); + + /*--- Retrieve solution at the farfield boundary node ---*/ + + auto V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); + + conv_numerics->SetPrimitive(V_domain, V_infty); + + /*--- Set turbulent variable at the wall, and at infinity ---*/ + + conv_numerics->SetScalarVar(nodes->GetSolution(iPoint), Solution_Inf); + + /*--- Set Normal (it is necessary to change the sign) ---*/ + /*--- It's mean wall normal zero flux. */ + + su2double Normal[MAXNDIM] = {0.0}; + for (auto iDim = 0u; iDim < nDim; iDim++) + Normal[iDim] = -geometry->vertex[val_marker][iVertex]->GetNormal(iDim); + conv_numerics->SetNormal(Normal); + + /*--- Grid Movement ---*/ + + if (dynamic_grid) + conv_numerics->SetGridVel(geometry->nodes->GetGridVel(iPoint), + geometry->nodes->GetGridVel(iPoint)); + + /*--- Compute residuals and Jacobians ---*/ + + auto residual = conv_numerics->ComputeResidual(config); + + /*--- Add residuals and Jacobians ---*/ + + LinSysRes.AddBlock(iPoint, residual); + if (implicit) Jacobian.AddBlock2Diag(iPoint, residual.jacobian_i); + } + } + END_SU2_OMP_FOR + +} + +void CTransLMSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, + CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + + BC_HeatFlux_Wall(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); + +} + +void CTransLMSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, + unsigned short val_marker) { + const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); + + /*--- 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++) { + + const auto iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); + + /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ + + if (geometry->nodes->GetDomain(iPoint)) { + + /*--- Normal vector for this vertex (negate for outward convention) ---*/ + + su2double Normal[MAXNDIM] = {0.0}; + for (auto iDim = 0u; iDim < nDim; iDim++) + Normal[iDim] = -geometry->vertex[val_marker][iVertex]->GetNormal(iDim); + conv_numerics->SetNormal(Normal); + + /*--- Allocate the value at the inlet ---*/ + + auto V_inlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); + + /*--- Retrieve solution at the farfield boundary node ---*/ + + auto V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); + + /*--- Set various quantities in the solver class ---*/ + + conv_numerics->SetPrimitive(V_domain, V_inlet); + + /*--- Non-dimensionalize Inlet_TurbVars if Inlet-Files are used. ---*/ + su2double Inlet_Vars[MAXNVAR]; + Inlet_Vars[0] = Inlet_TurbVars[val_marker][iVertex][0]; + Inlet_Vars[1] = Inlet_TurbVars[val_marker][iVertex][1]; + if (config->GetInlet_Profile_From_File()) { + Inlet_Vars[0] /= pow(config->GetVelocity_Ref(), 2); + Inlet_Vars[1] *= config->GetViscosity_Ref() / (config->GetDensity_Ref() * pow(config->GetVelocity_Ref(), 2)); + } + + /*--- Set the LM variable states. ---*/ + /*--- Load the inlet transition LM model variables (uniform by default). ---*/ + + conv_numerics->SetScalarVar(nodes->GetSolution(iPoint), Inlet_Vars); + + /*--- Set various other quantities in the solver class ---*/ + + if (dynamic_grid) + conv_numerics->SetGridVel(geometry->nodes->GetGridVel(iPoint), + geometry->nodes->GetGridVel(iPoint)); + + /*--- Compute the residual using an upwind scheme ---*/ + + auto residual = conv_numerics->ComputeResidual(config); + LinSysRes.AddBlock(iPoint, residual); + + /*--- Jacobian contribution for implicit integration ---*/ + + if (implicit) Jacobian.AddBlock2Diag(iPoint, residual.jacobian_i); + } + } + END_SU2_OMP_FOR + +} + +void CTransLMSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, + CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { + BC_Far_Field(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); +} + +void CTransLMSolver::LoadRestart(CGeometry** geometry, CSolver*** solver, CConfig* config, int val_iter, + bool val_update_geo) { + + const string restart_filename = config->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. ---*/ + BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { + /*--- Read the restart data from either an ASCII or binary SU2 file. ---*/ + + if (config->GetRead_Binary_Restart()) { + Read_SU2_Restart_Binary(geometry[MESH_0], config, restart_filename); + } else { + Read_SU2_Restart_ASCII(geometry[MESH_0], config, restart_filename); + } + + /*--- Skip flow variables ---*/ + + unsigned short skipVars = nDim + solver[MESH_0][FLOW_SOL]->GetnVar() + solver[MESH_0][TURB_SOL] ->GetnVar(); + + /*--- Adjust the number of solution variables in the incompressible + restart. We always carry a space in nVar for the energy equation in the + mean flow solver, but we only write it to the restart if it is active. + Therefore, we must reduce skipVars here if energy is inactive so that + the turbulent variables are read correctly. ---*/ + + const bool incompressible = (config->GetKind_Regime() == ENUM_REGIME::INCOMPRESSIBLE); + const bool energy = config->GetEnergy_Equation(); + const bool weakly_coupled_heat = config->GetWeakly_Coupled_Heat(); + + if (incompressible && ((!energy) && (!weakly_coupled_heat))) skipVars--; + + /*--- Load data from the restart into correct containers. ---*/ + + unsigned long counter = 0; + for (auto iPoint_Global = 0ul; iPoint_Global < geometry[MESH_0]->GetGlobal_nPointDomain(); iPoint_Global++) { + /*--- Retrieve local index. If this node from the restart file lives + on the current processor, we will load and instantiate the vars. ---*/ + + const auto iPoint_Local = geometry[MESH_0]->GetGlobal_to_Local_Point(iPoint_Global); + + if (iPoint_Local > -1) { + /*--- We need to store this point's data, so jump to the correct + offset in the buffer of data from the restart file and load it. ---*/ + + const auto index = counter * Restart_Vars[1] + skipVars; + for (auto iVar = 0u; iVar < nVar; iVar++) nodes->SetSolution(iPoint_Local, iVar, Restart_Data[index + iVar]); + nodes ->SetIntermittencySep(iPoint_Local, Restart_Data[index + 2]); + nodes ->SetIntermittencyEff(iPoint_Local, Restart_Data[index + 3]); + + /*--- Increment the overall counter for how many points have been loaded. ---*/ + counter++; + } + } + + /*--- Detect a wrong solution file ---*/ + + if (counter != nPointDomain) { + SU2_MPI::Error(string("The solution file ") + restart_filename + string(" does not match with the mesh file!\n") + + string("This can be caused by empty lines at the end of the file."), + CURRENT_FUNCTION); + } + + } // end SU2_OMP_MASTER, pre and postprocessing are thread-safe. + END_SU2_OMP_SAFE_GLOBAL_ACCESS + + /*--- MPI solution and compute the eddy viscosity ---*/ + + solver[MESH_0][TRANS_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); + solver[MESH_0][TRANS_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); + + /*--- For turbulent+species simulations the solver Pre-/Postprocessing is done by the species solver. ---*/ + if (config->GetKind_Species_Model() == SPECIES_MODEL::NONE) { + solver[MESH_0][FLOW_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, + RUNTIME_FLOW_SYS, false); + solver[MESH_0][TURB_SOL]->Postprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0); + solver[MESH_0][TRANS_SOL]->Postprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0); + } + + /*--- Interpolate the solution down to the coarse multigrid levels ---*/ + + for (auto iMesh = 1u; iMesh <= config->GetnMGLevels(); iMesh++) { + + MultigridRestriction(*geometry[iMesh - 1], solver[iMesh - 1][TRANS_SOL]->GetNodes()->GetSolution(), + *geometry[iMesh], solver[iMesh][TRANS_SOL]->GetNodes()->GetSolution()); + solver[iMesh][TRANS_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); + solver[iMesh][TRANS_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); + + if (config->GetKind_Species_Model() == SPECIES_MODEL::NONE) { + solver[iMesh][FLOW_SOL]->Preprocessing(geometry[iMesh], solver[iMesh], config, iMesh, NO_RK_ITER, RUNTIME_FLOW_SYS, + false); + solver[iMesh][TRANS_SOL]->Postprocessing(geometry[iMesh], solver[iMesh], config, iMesh); + } + } + + /*--- Go back to single threaded execution. ---*/ + BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { + /*--- Delete the class memory that is used to load the restart. ---*/ + + delete[] Restart_Vars; + Restart_Vars = nullptr; + delete[] Restart_Data; + Restart_Data = nullptr; + } + END_SU2_OMP_SAFE_GLOBAL_ACCESS + +} \ No newline at end of file From e9226db18fdf915d49e780ca1e82741fac63bb85 Mon Sep 17 00:00:00 2001 From: rois1995 Date: Fri, 27 Jan 2023 18:57:31 +0100 Subject: [PATCH 02/20] - Start of implementation of Simplified LM transition model --- Common/include/option_structure.hpp | 4 + SU2_CFD/include/solvers/CTransSLMSolver.hpp | 218 ------- SU2_CFD/src/solvers/CSolverFactory.cpp | 2 +- SU2_CFD/src/solvers/CTransSLMSolver.cpp | 602 -------------------- 4 files changed, 5 insertions(+), 821 deletions(-) delete mode 100644 SU2_CFD/include/solvers/CTransSLMSolver.hpp delete mode 100644 SU2_CFD/src/solvers/CTransSLMSolver.cpp diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index d39d6abde86..6fe93797363 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -1174,6 +1174,7 @@ static const MapType Trans_Model_Map = { enum class LM_OPTIONS { NONE, /*!< \brief No option / default. */ LM2015, /*!< \brief Cross-flow corrections. */ + SLM, /*!< \brief Simplified version. */ MALAN, /*!< \brief Kind of transition correlation model (Malan). */ SULUKSNA, /*!< \brief Kind of transition correlation model (Suluksna). */ KRAUSE, /*!< \brief Kind of transition correlation model (Krause). */ @@ -1187,6 +1188,7 @@ enum class LM_OPTIONS { static const MapType LM_Options_Map = { MakePair("NONE", LM_OPTIONS::NONE) MakePair("LM2015", LM_OPTIONS::LM2015) + MakePair("SLM", LM_OPTIONS::SLM) MakePair("MALAN", LM_OPTIONS::MALAN) MakePair("SULUKSNA", LM_OPTIONS::SULUKSNA) MakePair("KRAUSE", LM_OPTIONS::KRAUSE) @@ -1216,6 +1218,7 @@ enum class TURB_TRANS_CORRELATION { struct LM_ParsedOptions { LM_OPTIONS version = LM_OPTIONS::NONE; /*!< \brief LM base model. */ bool LM2015 = false; /*!< \brief Use cross-flow corrections. */ + bool SLM = false; /*!< \brief Use simplified version. */ TURB_TRANS_CORRELATION Correlation = TURB_TRANS_CORRELATION::DEFAULT; }; @@ -1235,6 +1238,7 @@ inline LM_ParsedOptions ParseLMOptions(const LM_OPTIONS *LM_Options, unsigned sh }; LMParsedOptions.LM2015 = IsPresent(LM_OPTIONS::LM2015); + LMParsedOptions.SLM = IsPresent(LM_OPTIONS::SLM); int NFoundCorrelations = 0; if (IsPresent(LM_OPTIONS::MALAN)) { diff --git a/SU2_CFD/include/solvers/CTransSLMSolver.hpp b/SU2_CFD/include/solvers/CTransSLMSolver.hpp deleted file mode 100644 index acdf90fb9a4..00000000000 --- a/SU2_CFD/include/solvers/CTransSLMSolver.hpp +++ /dev/null @@ -1,218 +0,0 @@ -/*! - * \file CTransLMSolver.hpp - * \brief Headers of the CTransLMSolver class - * \author A. Aranake - * \version 7.5.0 "Blackbird" - * - * SU2 Project Website: https://su2code.github.io - * - * The SU2 Project is maintained by the SU2 Foundation - * (http://su2foundation.org) - * - * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) - * - * SU2 is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * SU2 is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with SU2. If not, see . - */ - -#pragma once - -#include "CTurbSolver.hpp" -#include "../numerics/turbulent/transition/trans_correlations.hpp" - -/*! - * \class CTransLMSolver - * \brief Main class for defining the transition model solver. - * \ingroup Turbulence_Model - * \author A. Aranake, S. Kang. - */ - -class CTransLMSolver final : public CTurbSolver { -private: - - LM_ParsedOptions options; - TURB_FAMILY TurbFamily; - - TransLMCorrelations TransCorrelations; - -public: - /*! - * \overload - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh); - - /*! - * \brief Destructor of the class. - */ - ~CTransLMSolver() = default; - - /*! - * \brief Restart residual and compute gradients. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - * \param[in] iRKStep - Current step of the Runge-Kutta iteration. - * \param[in] RunTime_EqSystem - System of equations which is going to be solved. - * \param[in] Output - boolean to determine whether to print output. - */ - void Preprocessing(CGeometry *geometry, - CSolver **solver_container, - CConfig *config, - unsigned short iMesh, - unsigned short iRKStep, - unsigned short RunTime_EqSystem, - bool Output) override; - - /*! - * \brief Computes the effective intermtittency. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Postprocessing(CGeometry *geometry, - CSolver **solver_container, - CConfig *config, - unsigned short iMesh) override; - - /*! - * \brief Compute the viscous flux for the LM equation at a particular edge. - * \param[in] iEdge - Edge for which we want to compute the flux - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \note Calls a generic implementation after defining a SolverSpecificNumerics object. - */ - void Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, - CNumerics* numerics, CConfig* config) override; - - /*! - * \brief Source term computation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics_container - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Residual(CGeometry *geometry, - CSolver **solver_container, - CNumerics **numerics_container, - CConfig *config, - unsigned short iMesh) override; - - /*! - * \brief Source term computation. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] iMesh - Index of the mesh in multigrid computations. - */ - void Source_Template(CGeometry *geometry, - CSolver **solver_container, - CNumerics *numerics, - CConfig *config, - unsigned short iMesh) override; - - /*! - * \brief Impose the Langtry Menter transition 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 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 inlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Inlet(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) override; - - /*! - * \brief Impose the outlet boundary condition. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] conv_numerics - Description of the numerical method. - * \param[in] visc_numerics - Description of the numerical method. - * \param[in] config - Definition of the particular problem. - * \param[in] val_marker - Surface marker where the boundary condition is applied. - */ - void BC_Outlet(CGeometry *geometry, - CSolver **solver_container, - CNumerics *conv_numerics, - CNumerics *visc_numerics, - CConfig *config, - unsigned short val_marker) override; - - /*! - * \brief Get the value of the intermittency. - * \return Value of the turbulent kinetic energy. - */ - inline su2double GetIntermittency_Inf(void) const override { return Solution_Inf[0]; } - - /*! - * \brief Get the value of the intermittency. - * \return Value of the turbulent kinetic energy. - */ - inline su2double GetReThetaT_Inf(void) const override { return Solution_Inf[1]; } - - /*! - * \brief Load a solution from a restart file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver - Container vector with all of the solvers. - * \param[in] config - Definition of the particular problem. - * \param[in] val_iter - Current external iteration number. - * \param[in] val_update_geo - Flag for updating coords and grid velocity. - */ - void LoadRestart(CGeometry** geometry, CSolver*** solver, CConfig* config, int val_iter, bool val_update_geo) final; - -}; diff --git a/SU2_CFD/src/solvers/CSolverFactory.cpp b/SU2_CFD/src/solvers/CSolverFactory.cpp index bf2a09ddfe5..9ee374d254b 100644 --- a/SU2_CFD/src/solvers/CSolverFactory.cpp +++ b/SU2_CFD/src/solvers/CSolverFactory.cpp @@ -381,7 +381,7 @@ CSolver* CSolverFactory::CreateTransSolver(TURB_TRANS_MODEL kindTransModel, CSol solver[FLOW_SOL]->Preprocessing(geometry, solver, config, iMGLevel, NO_RK_ITER, RUNTIME_FLOW_SYS, false); transSolver->Postprocessing(geometry, solver, config, iMGLevel); solver[FLOW_SOL]->Preprocessing(geometry, solver, config, iMGLevel, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - break; + break; case TURB_TRANS_MODEL::NONE: break; } diff --git a/SU2_CFD/src/solvers/CTransSLMSolver.cpp b/SU2_CFD/src/solvers/CTransSLMSolver.cpp deleted file mode 100644 index 01a254e98b7..00000000000 --- a/SU2_CFD/src/solvers/CTransSLMSolver.cpp +++ /dev/null @@ -1,602 +0,0 @@ -/*! - * \file CTransLMSolver.cpp - * \brief Main subroutines for Langtry-Menter Transition model solver. - * \author A. Aranake, S. Kang. - * \version 7.5.0 "Blackbird" - * - * SU2 Project Website: https://su2code.github.io - * - * The SU2 Project is maintained by the SU2 Foundation - * (http://su2foundation.org) - * - * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) - * - * SU2 is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * SU2 is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with SU2. If not, see . - */ - -#include "../../include/solvers/CTransLMSolver.hpp" -#include "../../include/variables/CTransLMVariable.hpp" -#include "../../include/variables/CFlowVariable.hpp" -#include "../../include/variables/CTurbSAVariable.hpp" -#include "../../../Common/include/parallelization/omp_structure.hpp" -#include "../../../Common/include/toolboxes/geometry_toolbox.hpp" - -/*--- This is the implementation of the Langtry-Menter transition model. - The main reference for this model is:Langtry, Menter, AIAA J. 47(12) 2009 - DOI: https://doi.org/10.2514/1.42362 ---*/ - -// Note: TransLM seems to use rho*gamma, rho*Re_sigma as Solution variables, thus Conservative=true - -CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh) - : CTurbSolver(geometry, config, true) { - unsigned long iPoint; - ifstream restart_file; - string text_line; - - bool multizone = config->GetMultizone_Problem(); - - /*--- Dimension of the problem --> 2 Transport equations (intermittency, Reth) ---*/ - nVar = 2; - nPrimVar = 2; - nPoint = geometry->GetnPoint(); - nPointDomain = geometry->GetnPointDomain(); - - /*--- Initialize nVarGrad for deallocation ---*/ - - nVarGrad = nVar; - - /*--- Define geometry constants in the solver structure ---*/ - - nDim = geometry->GetnDim(); - - /*--- Define variables needed for transition from config file */ - options = config->GetLMParsedOptions(); - TransCorrelations.SetOptions(options); - TurbFamily = TurbModelFamily(config->GetKind_Turb_Model()); - - /*--- Single grid simulation ---*/ - - if (iMesh == MESH_0) { - - /*--- Define some auxiliary vector related with the residual ---*/ - - Residual_RMS.resize(nVar,0.0); - Residual_Max.resize(nVar,0.0); - Point_Max.resize(nVar,0); - Point_Max_Coord.resize(nVar,nDim) = su2double(0.0); - - /*--- Initialization of the structure of the whole Jacobian ---*/ - - if (rank == MASTER_NODE) cout << "Initialize Jacobian structure (LM transition model)." << endl; - Jacobian.Initialize(nPoint, nPointDomain, nVar, nVar, true, geometry, config, ReducerStrategy); - LinSysSol.Initialize(nPoint, nPointDomain, nVar, 0.0); - LinSysRes.Initialize(nPoint, nPointDomain, nVar, 0.0); - System.SetxIsZero(true); - - if (ReducerStrategy) - EdgeFluxes.Initialize(geometry->GetnEdge(), geometry->GetnEdge(), nVar, nullptr); - - /*--- Initialize the BGS residuals in multizone problems. ---*/ - if (multizone){ - Residual_BGS.resize(nVar,0.0); - Residual_Max_BGS.resize(nVar,0.0); - Point_Max_BGS.resize(nVar,0); - Point_Max_Coord_BGS.resize(nVar,nDim) = su2double(0.0); - } - - } - - /*--- Initialize lower and upper limits---*/ - lowerlimit[0] = 1.0e-4; - upperlimit[0] = 5.0; - - lowerlimit[1] = 1.0e-4; - upperlimit[1] = 1.0e15; - - /*--- Far-field flow state quantities and initialization. ---*/ - const su2double Intensity = config->GetTurbulenceIntensity_FreeStream()*100.0; - - const su2double Intermittency_Inf = 1.0; - su2double ReThetaT_Inf = 100.0; - - /*--- Momentum thickness Reynolds number, initialized from freestream turbulent intensity*/ - if (Intensity <= 1.3) { - if(Intensity >=0.027) { - ReThetaT_Inf = (1173.51-589.428*Intensity+0.2196/(Intensity*Intensity)); - } - else { - ReThetaT_Inf = (1173.51-589.428*Intensity+0.2196/(0.27*0.27)); - } - } - else if(Intensity>1.3) { - ReThetaT_Inf = 331.5*pow(Intensity-0.5658,-0.671); - } - - Solution_Inf[0] = Intermittency_Inf; - Solution_Inf[1] = ReThetaT_Inf; - - /*--- Initialize the solution to the far-field state everywhere. ---*/ - nodes = new CTransLMVariable(Intermittency_Inf, ReThetaT_Inf, 1.0, 1.0, nPoint, nDim, nVar, config); - SetBaseClassPointerToNodes(); - - /*--- MPI solution ---*/ - - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); - - /*--- Initializate quantities for SlidingMesh Interface ---*/ - - SlidingState.resize(nMarker); - SlidingStateNodes.resize(nMarker); - - for (unsigned long iMarker = 0; iMarker < nMarker; iMarker++) { - if (config->GetMarker_All_KindBC(iMarker) == FLUID_INTERFACE) { - SlidingState[iMarker].resize(nVertex[iMarker], nPrimVar+1) = nullptr; - SlidingStateNodes[iMarker].resize(nVertex[iMarker],0); - } - } - - /*-- Allocation of inlets has to happen in derived classes (not CTurbSolver), - due to arbitrary number of turbulence variables ---*/ - - Inlet_TurbVars.resize(nMarker); - for (unsigned long iMarker = 0; iMarker < nMarker; iMarker++) { - Inlet_TurbVars[iMarker].resize(nVertex[iMarker],nVar); - for (unsigned long iVertex = 0; iVertex < nVertex[iMarker]; ++iVertex) { - Inlet_TurbVars[iMarker](iVertex,0) = Intermittency_Inf; - Inlet_TurbVars[iMarker](iVertex,1) = ReThetaT_Inf; - } - } - - const su2double CFL = config->GetCFL(MGLevel)*config->GetCFLRedCoeff_Turb(); - for (iPoint = 0; iPoint < nPoint; iPoint++) { - nodes->SetLocalCFL(iPoint, CFL); - } - Min_CFL_Local = CFL; - Max_CFL_Local = CFL; - Avg_CFL_Local = CFL; - - /*--- Add the solver name (max 8 characters) ---*/ - SolverName = "LM model"; - -} - -void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, - unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) { - SU2_OMP_SAFE_GLOBAL_ACCESS(config->SetGlobalParam(config->GetKind_Solver(), RunTime_EqSystem);) - - /*--- Upwind second order reconstruction and gradients ---*/ - CommonPreprocessing(geometry, config, Output); -} - -void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh) { - - /*--- Compute LM model gradients. ---*/ - - if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { - SetSolution_Gradient_GG(geometry, config); - } - if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { - SetSolution_Gradient_LS(geometry, config); - } - - AD::StartNoSharedReading(); - auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); - auto* turbNodes = su2staticcast_p(solver_container[TURB_SOL]->GetNodes()); - - SU2_OMP_FOR_STAT(omp_chunk_size) - for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { - - // Here the nodes already have the new solution, thus I have to compute everything from scratch - - const su2double rho = flowNodes->GetDensity(iPoint); - const su2double mu = flowNodes->GetLaminarViscosity(iPoint); - const su2double muT = turbNodes->GetmuT(iPoint); - const su2double dist = geometry->nodes->GetWall_Distance(iPoint); - su2double VorticityMag = GeometryToolbox::Norm(3, flowNodes->GetVorticity(iPoint)); - su2double StrainMag =flowNodes->GetStrainMag(iPoint); - VorticityMag = max(VorticityMag, 1e-12); - StrainMag = max(StrainMag, 1e-12); // safety against division by zero - const su2double Intermittency = nodes->GetSolution(iPoint,0); - const su2double Re_t = nodes->GetSolution(iPoint,1); - const su2double Re_v = rho*dist*dist*StrainMag/mu; - const su2double vel_u = flowNodes->GetVelocity(iPoint, 0); - const su2double vel_v = flowNodes->GetVelocity(iPoint, 1); - const su2double vel_w = (nDim ==3) ? flowNodes->GetVelocity(iPoint, 2) : 0.0; - const su2double VelocityMag = sqrt(vel_u*vel_u + vel_v*vel_v + vel_w*vel_w); - su2double omega = 0.0; - su2double k = 0.0; - if(TurbFamily == TURB_FAMILY::KW){ - omega = turbNodes->GetSolution(iPoint,1); - k = turbNodes->GetSolution(iPoint,0); - } - su2double Tu = 1.0; - if(TurbFamily == TURB_FAMILY::KW) - Tu = max(100.0*sqrt( 2.0 * k / 3.0 ) / VelocityMag,0.027); - if(TurbFamily == TURB_FAMILY::SA) - Tu = config->GetTurbulenceIntensity_FreeStream()*100; - - const su2double Corr_Rec = TransCorrelations.ReThetaC_Correlations(Tu, Re_t); - - su2double R_t = 1.0; - if(TurbFamily == TURB_FAMILY::KW) - R_t = rho*k/ mu/ omega; - if(TurbFamily == TURB_FAMILY::SA) - R_t = muT/ mu; - - const su2double f_reattach = exp(-pow(R_t/20,4)); - su2double f_wake = 0.0; - if(TurbFamily == TURB_FAMILY::KW){ - const su2double re_omega = rho*omega*dist*dist/mu; - f_wake = exp(-pow(re_omega/(1.0e+05),2)); - } - if(TurbFamily == TURB_FAMILY::SA) - f_wake = 1.0; - - const su2double theta_bl = Re_t*mu / rho /VelocityMag; - const su2double delta_bl = 7.5*theta_bl; - const su2double delta = 50.0*VorticityMag*dist/VelocityMag*delta_bl + 1e-20; - const su2double var1 = (Intermittency-1.0/50.0)/(1.0-1.0/50.0); - const su2double var2 = 1.0 - pow(var1,2.0); - const su2double f_theta = min(max(f_wake*exp(-pow(dist/delta, 4)), var2), 1.0); - su2double Intermittency_Sep = 2.0*max(0.0, Re_v/(3.235*Corr_Rec)-1.0)*f_reattach; - Intermittency_Sep = min(Intermittency_Sep,2.0)*f_theta; - Intermittency_Sep = min(max(0.0, Intermittency_Sep), 2.0); - nodes -> SetIntermittencySep(iPoint, Intermittency_Sep); - nodes -> SetIntermittencyEff(iPoint, Intermittency_Sep); - - } - END_SU2_OMP_FOR - - AD::EndNoSharedReading(); -} - - -void CTransLMSolver::Viscous_Residual(unsigned long iEdge, CGeometry* geometry, CSolver** solver_container, - CNumerics* numerics, CConfig* config) { - - /*--- Define an object to set solver specific numerics contribution. ---*/ - - auto SolverSpecificNumerics = [&](unsigned long iPoint, unsigned long jPoint) {}; - - /*--- Now instantiate the generic implementation with the functor above. ---*/ - - Viscous_Residual_impl(SolverSpecificNumerics, iEdge, geometry, solver_container, numerics, config); -} - - -void CTransLMSolver::Source_Residual(CGeometry *geometry, CSolver **solver_container, - CNumerics **numerics_container, CConfig *config, unsigned short iMesh) { - - const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); - - auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); - //auto* turbNodes = su2staticcast_p(solver_container[TURB_SOL]->GetNodes()); - CVariable* turbNodes = solver_container[TURB_SOL]->GetNodes(); - - /*--- Pick one numerics object per thread. ---*/ - auto* numerics = numerics_container[SOURCE_FIRST_TERM + omp_get_thread_num()*MAX_TERMS]; - - /*--- Loop over all points. ---*/ - - AD::StartNoSharedReading(); - - SU2_OMP_FOR_DYN(omp_chunk_size) - for (unsigned long iPoint = 0; iPoint < nPointDomain; iPoint++) { - - - - /*--- Conservative variables w/o reconstruction ---*/ - - numerics->SetPrimitive(flowNodes->GetPrimitive(iPoint), nullptr); - - /*--- Gradient of the primitive and conservative variables ---*/ - - numerics->SetPrimVarGradient(flowNodes->GetGradient_Primitive(iPoint), nullptr); - - /*--- Turbulent variables w/o reconstruction, and its gradient ---*/ - /*--- ScalarVar & ScalarVarGradient : Turbulence model solution(k&w) ---*/ - - numerics->SetScalarVar(turbNodes->GetSolution(iPoint), nullptr); - numerics->SetScalarVarGradient(turbNodes->GetGradient(iPoint), nullptr); - - /*--- Transition variables w/o reconstruction, and its gradient ---*/ - - numerics->SetTransVar(nodes->GetSolution(iPoint), nullptr); - numerics->SetTransVarGradient(nodes->GetGradient(iPoint), nullptr); - - /*--- Set volume ---*/ - - numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); - - /*--- Set distance to the surface ---*/ - - numerics->SetDistance(geometry->nodes->GetWall_Distance(iPoint), 0.0); - - /*--- Set vorticity and strain rate magnitude ---*/ - - numerics->SetVorticity(flowNodes->GetVorticity(iPoint), nullptr); - - numerics->SetStrainMag(flowNodes->GetStrainMag(iPoint), 0.0); - - /*--- Set coordinate (for debugging) ---*/ - numerics->SetCoord(geometry->nodes->GetCoord(iPoint), nullptr); - - if (options.LM2015) { - /*--- Set local grid length (for LM2015)*/ - numerics->SetLocalGridLength(geometry->nodes->GetMaxLength(iPoint)); - } - - /*--- Compute the source term ---*/ - - auto residual = numerics->ComputeResidual(config); - - /*--- Subtract residual and the Jacobian ---*/ - - LinSysRes.SubtractBlock(iPoint, residual); - if (implicit) Jacobian.SubtractBlock2Diag(iPoint, residual.jacobian_i); - - } - END_SU2_OMP_FOR - - AD::EndNoSharedReading(); - -} - -void CTransLMSolver::Source_Template(CGeometry *geometry, CSolver **solver_container, CNumerics *numerics, - CConfig *config, unsigned short iMesh) { -} - -void CTransLMSolver::BC_HeatFlux_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, - CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - - const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); - - SU2_OMP_FOR_STAT(OMP_MIN_SIZE) - for (auto iVertex = 0u; iVertex < geometry->nVertex[val_marker]; iVertex++) { - - const auto iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - /*--- Check if the node belongs to the domain (i.e, not a halo node) ---*/ - - if (geometry->nodes->GetDomain(iPoint)) { - - /*--- Allocate the value at the infinity ---*/ - - auto V_infty = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - - /*--- Retrieve solution at the farfield boundary node ---*/ - - auto V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - - conv_numerics->SetPrimitive(V_domain, V_infty); - - /*--- Set turbulent variable at the wall, and at infinity ---*/ - - conv_numerics->SetScalarVar(nodes->GetSolution(iPoint), Solution_Inf); - - /*--- Set Normal (it is necessary to change the sign) ---*/ - /*--- It's mean wall normal zero flux. */ - - su2double Normal[MAXNDIM] = {0.0}; - for (auto iDim = 0u; iDim < nDim; iDim++) - Normal[iDim] = -geometry->vertex[val_marker][iVertex]->GetNormal(iDim); - conv_numerics->SetNormal(Normal); - - /*--- Grid Movement ---*/ - - if (dynamic_grid) - conv_numerics->SetGridVel(geometry->nodes->GetGridVel(iPoint), - geometry->nodes->GetGridVel(iPoint)); - - /*--- Compute residuals and Jacobians ---*/ - - auto residual = conv_numerics->ComputeResidual(config); - - /*--- Add residuals and Jacobians ---*/ - - LinSysRes.AddBlock(iPoint, residual); - if (implicit) Jacobian.AddBlock2Diag(iPoint, residual.jacobian_i); - } - } - END_SU2_OMP_FOR - -} - -void CTransLMSolver::BC_Isothermal_Wall(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, - CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - - BC_HeatFlux_Wall(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); - -} - -void CTransLMSolver::BC_Inlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, CNumerics *visc_numerics, CConfig *config, - unsigned short val_marker) { - const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); - - /*--- 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++) { - - const auto iPoint = geometry->vertex[val_marker][iVertex]->GetNode(); - - /*--- Check if the node belongs to the domain (i.e., not a halo node) ---*/ - - if (geometry->nodes->GetDomain(iPoint)) { - - /*--- Normal vector for this vertex (negate for outward convention) ---*/ - - su2double Normal[MAXNDIM] = {0.0}; - for (auto iDim = 0u; iDim < nDim; iDim++) - Normal[iDim] = -geometry->vertex[val_marker][iVertex]->GetNormal(iDim); - conv_numerics->SetNormal(Normal); - - /*--- Allocate the value at the inlet ---*/ - - auto V_inlet = solver_container[FLOW_SOL]->GetCharacPrimVar(val_marker, iVertex); - - /*--- Retrieve solution at the farfield boundary node ---*/ - - auto V_domain = solver_container[FLOW_SOL]->GetNodes()->GetPrimitive(iPoint); - - /*--- Set various quantities in the solver class ---*/ - - conv_numerics->SetPrimitive(V_domain, V_inlet); - - /*--- Non-dimensionalize Inlet_TurbVars if Inlet-Files are used. ---*/ - su2double Inlet_Vars[MAXNVAR]; - Inlet_Vars[0] = Inlet_TurbVars[val_marker][iVertex][0]; - Inlet_Vars[1] = Inlet_TurbVars[val_marker][iVertex][1]; - if (config->GetInlet_Profile_From_File()) { - Inlet_Vars[0] /= pow(config->GetVelocity_Ref(), 2); - Inlet_Vars[1] *= config->GetViscosity_Ref() / (config->GetDensity_Ref() * pow(config->GetVelocity_Ref(), 2)); - } - - /*--- Set the LM variable states. ---*/ - /*--- Load the inlet transition LM model variables (uniform by default). ---*/ - - conv_numerics->SetScalarVar(nodes->GetSolution(iPoint), Inlet_Vars); - - /*--- Set various other quantities in the solver class ---*/ - - if (dynamic_grid) - conv_numerics->SetGridVel(geometry->nodes->GetGridVel(iPoint), - geometry->nodes->GetGridVel(iPoint)); - - /*--- Compute the residual using an upwind scheme ---*/ - - auto residual = conv_numerics->ComputeResidual(config); - LinSysRes.AddBlock(iPoint, residual); - - /*--- Jacobian contribution for implicit integration ---*/ - - if (implicit) Jacobian.AddBlock2Diag(iPoint, residual.jacobian_i); - } - } - END_SU2_OMP_FOR - -} - -void CTransLMSolver::BC_Outlet(CGeometry *geometry, CSolver **solver_container, CNumerics *conv_numerics, - CNumerics *visc_numerics, CConfig *config, unsigned short val_marker) { - BC_Far_Field(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker); -} - -void CTransLMSolver::LoadRestart(CGeometry** geometry, CSolver*** solver, CConfig* config, int val_iter, - bool val_update_geo) { - - const string restart_filename = config->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. ---*/ - BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { - /*--- Read the restart data from either an ASCII or binary SU2 file. ---*/ - - if (config->GetRead_Binary_Restart()) { - Read_SU2_Restart_Binary(geometry[MESH_0], config, restart_filename); - } else { - Read_SU2_Restart_ASCII(geometry[MESH_0], config, restart_filename); - } - - /*--- Skip flow variables ---*/ - - unsigned short skipVars = nDim + solver[MESH_0][FLOW_SOL]->GetnVar() + solver[MESH_0][TURB_SOL] ->GetnVar(); - - /*--- Adjust the number of solution variables in the incompressible - restart. We always carry a space in nVar for the energy equation in the - mean flow solver, but we only write it to the restart if it is active. - Therefore, we must reduce skipVars here if energy is inactive so that - the turbulent variables are read correctly. ---*/ - - const bool incompressible = (config->GetKind_Regime() == ENUM_REGIME::INCOMPRESSIBLE); - const bool energy = config->GetEnergy_Equation(); - const bool weakly_coupled_heat = config->GetWeakly_Coupled_Heat(); - - if (incompressible && ((!energy) && (!weakly_coupled_heat))) skipVars--; - - /*--- Load data from the restart into correct containers. ---*/ - - unsigned long counter = 0; - for (auto iPoint_Global = 0ul; iPoint_Global < geometry[MESH_0]->GetGlobal_nPointDomain(); iPoint_Global++) { - /*--- Retrieve local index. If this node from the restart file lives - on the current processor, we will load and instantiate the vars. ---*/ - - const auto iPoint_Local = geometry[MESH_0]->GetGlobal_to_Local_Point(iPoint_Global); - - if (iPoint_Local > -1) { - /*--- We need to store this point's data, so jump to the correct - offset in the buffer of data from the restart file and load it. ---*/ - - const auto index = counter * Restart_Vars[1] + skipVars; - for (auto iVar = 0u; iVar < nVar; iVar++) nodes->SetSolution(iPoint_Local, iVar, Restart_Data[index + iVar]); - nodes ->SetIntermittencySep(iPoint_Local, Restart_Data[index + 2]); - nodes ->SetIntermittencyEff(iPoint_Local, Restart_Data[index + 3]); - - /*--- Increment the overall counter for how many points have been loaded. ---*/ - counter++; - } - } - - /*--- Detect a wrong solution file ---*/ - - if (counter != nPointDomain) { - SU2_MPI::Error(string("The solution file ") + restart_filename + string(" does not match with the mesh file!\n") + - string("This can be caused by empty lines at the end of the file."), - CURRENT_FUNCTION); - } - - } // end SU2_OMP_MASTER, pre and postprocessing are thread-safe. - END_SU2_OMP_SAFE_GLOBAL_ACCESS - - /*--- MPI solution and compute the eddy viscosity ---*/ - - solver[MESH_0][TRANS_SOL]->InitiateComms(geometry[MESH_0], config, SOLUTION); - solver[MESH_0][TRANS_SOL]->CompleteComms(geometry[MESH_0], config, SOLUTION); - - /*--- For turbulent+species simulations the solver Pre-/Postprocessing is done by the species solver. ---*/ - if (config->GetKind_Species_Model() == SPECIES_MODEL::NONE) { - solver[MESH_0][FLOW_SOL]->Preprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0, NO_RK_ITER, - RUNTIME_FLOW_SYS, false); - solver[MESH_0][TURB_SOL]->Postprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0); - solver[MESH_0][TRANS_SOL]->Postprocessing(geometry[MESH_0], solver[MESH_0], config, MESH_0); - } - - /*--- Interpolate the solution down to the coarse multigrid levels ---*/ - - for (auto iMesh = 1u; iMesh <= config->GetnMGLevels(); iMesh++) { - - MultigridRestriction(*geometry[iMesh - 1], solver[iMesh - 1][TRANS_SOL]->GetNodes()->GetSolution(), - *geometry[iMesh], solver[iMesh][TRANS_SOL]->GetNodes()->GetSolution()); - solver[iMesh][TRANS_SOL]->InitiateComms(geometry[iMesh], config, SOLUTION); - solver[iMesh][TRANS_SOL]->CompleteComms(geometry[iMesh], config, SOLUTION); - - if (config->GetKind_Species_Model() == SPECIES_MODEL::NONE) { - solver[iMesh][FLOW_SOL]->Preprocessing(geometry[iMesh], solver[iMesh], config, iMesh, NO_RK_ITER, RUNTIME_FLOW_SYS, - false); - solver[iMesh][TRANS_SOL]->Postprocessing(geometry[iMesh], solver[iMesh], config, iMesh); - } - } - - /*--- Go back to single threaded execution. ---*/ - BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS { - /*--- Delete the class memory that is used to load the restart. ---*/ - - delete[] Restart_Vars; - Restart_Vars = nullptr; - delete[] Restart_Data; - Restart_Data = nullptr; - } - END_SU2_OMP_SAFE_GLOBAL_ACCESS - -} \ No newline at end of file From d03742af36f37757e1a2eff2182cf02f11af2c7c Mon Sep 17 00:00:00 2001 From: rois1995 Date: Fri, 27 Jan 2023 19:17:58 +0100 Subject: [PATCH 03/20] - Modify number of variables if SLM option is used --- SU2_CFD/src/solvers/CSolverFactory.cpp | 2 +- SU2_CFD/src/solvers/CTransLMSolver.cpp | 46 ++++++++++++++-------- SU2_CFD/src/variables/CTransLMVariable.cpp | 5 ++- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/SU2_CFD/src/solvers/CSolverFactory.cpp b/SU2_CFD/src/solvers/CSolverFactory.cpp index 9ee374d254b..11726796d69 100644 --- a/SU2_CFD/src/solvers/CSolverFactory.cpp +++ b/SU2_CFD/src/solvers/CSolverFactory.cpp @@ -381,7 +381,7 @@ CSolver* CSolverFactory::CreateTransSolver(TURB_TRANS_MODEL kindTransModel, CSol solver[FLOW_SOL]->Preprocessing(geometry, solver, config, iMGLevel, NO_RK_ITER, RUNTIME_FLOW_SYS, false); transSolver->Postprocessing(geometry, solver, config, iMGLevel); solver[FLOW_SOL]->Preprocessing(geometry, solver, config, iMGLevel, NO_RK_ITER, RUNTIME_FLOW_SYS, false); - break; + break; case TURB_TRANS_MODEL::NONE: break; } diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index 01a254e98b7..0ceb3d86992 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -60,11 +60,17 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh nDim = geometry->GetnDim(); - /*--- Define variables needed for transition from config file */ + /*--- Define variables needed for transition from config file ---*/ options = config->GetLMParsedOptions(); TransCorrelations.SetOptions(options); TurbFamily = TurbModelFamily(config->GetKind_Turb_Model()); + /*--- Check if Simplified version is used ---*/ + if (options.SLM) { + nVar = 1; + nPrimVar = 1; + } + /*--- Single grid simulation ---*/ if (iMesh == MESH_0) { @@ -101,33 +107,41 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh lowerlimit[0] = 1.0e-4; upperlimit[0] = 5.0; - lowerlimit[1] = 1.0e-4; - upperlimit[1] = 1.0e15; + if (!options.SLM) { + lowerlimit[1] = 1.0e-4; + upperlimit[1] = 1.0e15; + } /*--- Far-field flow state quantities and initialization. ---*/ const su2double Intensity = config->GetTurbulenceIntensity_FreeStream()*100.0; const su2double Intermittency_Inf = 1.0; - su2double ReThetaT_Inf = 100.0; + Solution_Inf[0] = Intermittency_Inf; - /*--- Momentum thickness Reynolds number, initialized from freestream turbulent intensity*/ - if (Intensity <= 1.3) { - if(Intensity >=0.027) { - ReThetaT_Inf = (1173.51-589.428*Intensity+0.2196/(Intensity*Intensity)); + su2double ReThetaT_Inf = 0.0; + + if (!options.SLM) { + su2double ReThetaT_Inf = 100.0; + + /*--- Momentum thickness Reynolds number, initialized from freestream turbulent intensity*/ + if (Intensity <= 1.3) { + if(Intensity >=0.027) { + ReThetaT_Inf = (1173.51-589.428*Intensity+0.2196/(Intensity*Intensity)); + } + else { + ReThetaT_Inf = (1173.51-589.428*Intensity+0.2196/(0.27*0.27)); + } } - else { - ReThetaT_Inf = (1173.51-589.428*Intensity+0.2196/(0.27*0.27)); + else if(Intensity>1.3) { + ReThetaT_Inf = 331.5*pow(Intensity-0.5658,-0.671); } - } - else if(Intensity>1.3) { - ReThetaT_Inf = 331.5*pow(Intensity-0.5658,-0.671); - } - Solution_Inf[0] = Intermittency_Inf; - Solution_Inf[1] = ReThetaT_Inf; + Solution_Inf[1] = ReThetaT_Inf; + } /*--- Initialize the solution to the far-field state everywhere. ---*/ nodes = new CTransLMVariable(Intermittency_Inf, ReThetaT_Inf, 1.0, 1.0, nPoint, nDim, nVar, config); + SetBaseClassPointerToNodes(); /*--- MPI solution ---*/ diff --git a/SU2_CFD/src/variables/CTransLMVariable.cpp b/SU2_CFD/src/variables/CTransLMVariable.cpp index df345c23aef..ce73c451942 100644 --- a/SU2_CFD/src/variables/CTransLMVariable.cpp +++ b/SU2_CFD/src/variables/CTransLMVariable.cpp @@ -31,10 +31,13 @@ CTransLMVariable::CTransLMVariable(su2double Intermittency, su2double ReThetaT, su2double gammaSep, su2double gammaEff, unsigned long npoint, unsigned long ndim, unsigned long nvar, CConfig *config) : CTurbVariable(npoint, ndim, nvar, config) { + LM_ParsedOptions options = config->GetLMParsedOptions(); + for(unsigned long iPoint=0; iPoint Date: Tue, 31 Jan 2023 18:26:43 +0100 Subject: [PATCH 04/20] - Updates on the transition model. - Added correlations for Simplified LM. - There is a bug on the computation of grad(n*U)*n --- Common/include/geometry/dual_grid/CPoint.hpp | 12 ++ Common/include/option_structure.hpp | 43 +++- Common/src/CConfig.cpp | 26 ++- SU2_CFD/include/numerics/CNumerics.hpp | 19 ++ .../turbulent/transition/trans_convection.hpp | 7 + .../transition/trans_correlations.hpp | 103 ++++++++++ .../turbulent/transition/trans_diffusion.hpp | 69 +++++++ .../turbulent/transition/trans_sources.hpp | 189 +++++++++++++++++- .../numerics/turbulent/turb_sources.hpp | 10 + .../include/variables/CTransLMVariable.hpp | 33 +++ SU2_CFD/include/variables/CVariable.hpp | 20 ++ SU2_CFD/src/drivers/CDriver.cpp | 30 ++- SU2_CFD/src/output/CFlowOutput.cpp | 46 +++-- SU2_CFD/src/solvers/CTransLMSolver.cpp | 129 ++++++++++-- SU2_CFD/src/variables/CTransLMVariable.cpp | 35 +++- 15 files changed, 726 insertions(+), 45 deletions(-) diff --git a/Common/include/geometry/dual_grid/CPoint.hpp b/Common/include/geometry/dual_grid/CPoint.hpp index b5750ddb4d2..82489486acd 100644 --- a/Common/include/geometry/dual_grid/CPoint.hpp +++ b/Common/include/geometry/dual_grid/CPoint.hpp @@ -456,6 +456,18 @@ class CPoint { } inline void SetWall_Distance(unsigned long iPoint, su2double distance) { Wall_Distance(iPoint) = distance; } + /*! + * \brief Get the index of the closest wall element. + * \param[in] iPoint - Index of the point. + */ + inline unsigned long GetClosestWall_Elem(unsigned long iPoint) {return ClosestWall_Elem(iPoint);} + + /*! + * \brief Get the marker of the closest wall marker. + * \param[in] iPoint - Index of the point. + */ + inline unsigned long GetClosestWall_Marker(unsigned long iPoint) {return ClosestWall_Marker(iPoint);} + /*! * \brief Get the value of the distance to the nearest wall. * \param[in] iPoint - Index of the point. diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 6fe93797363..63f2676ffde 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -1175,6 +1175,7 @@ enum class LM_OPTIONS { NONE, /*!< \brief No option / default. */ LM2015, /*!< \brief Cross-flow corrections. */ SLM, /*!< \brief Simplified version. */ + PRODLIM, /*!< \brief Add production term to Pk. */ MALAN, /*!< \brief Kind of transition correlation model (Malan). */ SULUKSNA, /*!< \brief Kind of transition correlation model (Suluksna). */ KRAUSE, /*!< \brief Kind of transition correlation model (Krause). */ @@ -1182,6 +1183,9 @@ enum class LM_OPTIONS { MEDIDA_BAEDER,/*!< \brief Kind of transition correlation model (Medida-Baeder). */ MEDIDA, /*!< \brief Kind of transition correlation model (Medida). */ MENTER_LANGTRY, /*!< \brief Kind of transition correlation model (Menter-Langtry). */ + MENTER_SLM, /*!< \brief Kind of transition correlation model (Menter Simplified LM model). */ + CODER_SLM, /*!< \brief Kind of transition correlation model (Coder Simplified LM model). */ + MOD_EPPLER_SLM, /*!< \brief Kind of transition correlation model (Modified Eppler Simplified LM model). */ DEFAULT /*!< \brief Kind of transition correlation model (Menter-Langtry if SST, MALAN if SA). */ }; @@ -1189,12 +1193,16 @@ static const MapType LM_Options_Map = { MakePair("NONE", LM_OPTIONS::NONE) MakePair("LM2015", LM_OPTIONS::LM2015) MakePair("SLM", LM_OPTIONS::SLM) + MakePair("PRODLIM", LM_OPTIONS::PRODLIM) MakePair("MALAN", LM_OPTIONS::MALAN) MakePair("SULUKSNA", LM_OPTIONS::SULUKSNA) MakePair("KRAUSE", LM_OPTIONS::KRAUSE) MakePair("KRAUSE_HYPER", LM_OPTIONS::KRAUSE_HYPER) MakePair("MEDIDA_BAEDER", LM_OPTIONS::MEDIDA_BAEDER) MakePair("MENTER_LANGTRY", LM_OPTIONS::MENTER_LANGTRY) + MakePair("MENTER_SLM", LM_OPTIONS::MENTER_SLM) + MakePair("CODER_SLM", LM_OPTIONS::CODER_SLM) + MakePair("MOD_EPPLER_SLM", LM_OPTIONS::MOD_EPPLER_SLM) MakePair("DEFAULT", LM_OPTIONS::DEFAULT) }; @@ -1212,14 +1220,26 @@ enum class TURB_TRANS_CORRELATION { DEFAULT /*!< \brief Kind of transition correlation model (Menter-Langtry if SST, MALAN if SA). */ }; +/*! + * \brief Types of transition correlations for Simplified LM model + */ +enum class TURB_TRANS_CORRELATION_SLM { + MENTER_SLM, /*!< \brief Kind of transition correlation model (Menter Simplified LM model). */ + CODER_SLM, /*!< \brief Kind of transition correlation model (Coder Simplified LM model). */ + MOD_EPPLER_SLM, /*!< \brief Kind of transition correlation model (Modified Eppler Simplified LM model). */ + DEFAULT /*!< \brief Kind of transition correlation model. */ +}; + /*! * \brief Structure containing parsed LM options. */ struct LM_ParsedOptions { LM_OPTIONS version = LM_OPTIONS::NONE; /*!< \brief LM base model. */ bool LM2015 = false; /*!< \brief Use cross-flow corrections. */ - bool SLM = false; /*!< \brief Use simplified version. */ + bool SLM = false; /*!< \brief Use simplified version. */ + bool ProdLim = false; /*!< \brief Add production term to Pk. */ TURB_TRANS_CORRELATION Correlation = TURB_TRANS_CORRELATION::DEFAULT; + TURB_TRANS_CORRELATION_SLM Correlation_SLM = TURB_TRANS_CORRELATION_SLM::DEFAULT; }; /*! @@ -1239,8 +1259,10 @@ inline LM_ParsedOptions ParseLMOptions(const LM_OPTIONS *LM_Options, unsigned sh LMParsedOptions.LM2015 = IsPresent(LM_OPTIONS::LM2015); LMParsedOptions.SLM = IsPresent(LM_OPTIONS::SLM); + LMParsedOptions.ProdLim = IsPresent(LM_OPTIONS::PRODLIM); int NFoundCorrelations = 0; + int NFoundCorrelations_SLM = 0; if (IsPresent(LM_OPTIONS::MALAN)) { LMParsedOptions.Correlation = TURB_TRANS_CORRELATION::MALAN; NFoundCorrelations++; @@ -1269,10 +1291,25 @@ inline LM_ParsedOptions ParseLMOptions(const LM_OPTIONS *LM_Options, unsigned sh LMParsedOptions.Correlation = TURB_TRANS_CORRELATION::MENTER_LANGTRY; NFoundCorrelations++; } + if (IsPresent(LM_OPTIONS::MENTER_SLM)) { + LMParsedOptions.Correlation_SLM = TURB_TRANS_CORRELATION_SLM::MENTER_SLM; + NFoundCorrelations_SLM++; + } + if (IsPresent(LM_OPTIONS::CODER_SLM)) { + LMParsedOptions.Correlation_SLM = TURB_TRANS_CORRELATION_SLM::CODER_SLM; + NFoundCorrelations_SLM++; + } + if (IsPresent(LM_OPTIONS::MOD_EPPLER_SLM)) { + LMParsedOptions.Correlation_SLM = TURB_TRANS_CORRELATION_SLM::MOD_EPPLER_SLM; + NFoundCorrelations_SLM++; + } if (NFoundCorrelations > 1) { SU2_MPI::Error("Two correlations selected for LM_OPTIONS. Please choose only one.", CURRENT_FUNCTION); } + if (NFoundCorrelations_SLM > 1) { + SU2_MPI::Error("Two correlations selected for Simplified model into LM_OPTIONS. Please choose only one.", CURRENT_FUNCTION); + } if (LMParsedOptions.Correlation == TURB_TRANS_CORRELATION::DEFAULT){ if (Kind_Turb_Model == TURB_MODEL::SST) { @@ -1282,6 +1319,10 @@ inline LM_ParsedOptions ParseLMOptions(const LM_OPTIONS *LM_Options, unsigned sh } } + if (LMParsedOptions.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::DEFAULT){ + LMParsedOptions.Correlation_SLM = TURB_TRANS_CORRELATION_SLM::MENTER_SLM; + } + return LMParsedOptions; } diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 0357290120f..04ce1bc6734 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -6113,11 +6113,26 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { switch (Kind_Trans_Model) { case TURB_TRANS_MODEL::NONE: break; case TURB_TRANS_MODEL::LM: { - cout << "Transition model: Langtry and Menter's 4 equation model"; + int NTurbEqs = 0; + switch (Kind_Turb_Model) { + case TURB_MODEL::SA: NTurbEqs = 1; break; + case TURB_MODEL::SST: NTurbEqs = 2; break; + } + if (!lmParsedOptions.SLM) { + int NEquations = 2; + cout << "Transition model: Langtry and Menter's "<< NEquations+NTurbEqs <<" equation model"; + } else { + int NEquations = 1; + cout << "Transition model: Simplified Langtry and Menter's "<< NEquations+NTurbEqs <<" equation model"; + } if (lmParsedOptions.LM2015) { cout << " w/ cross-flow corrections (2015)" << endl; } else { - cout << " (2009)" << endl; + if (!lmParsedOptions.SLM) { + cout << " (2009)" << endl; + } else { + cout << " (2015)" << endl; + } } break; } @@ -6141,6 +6156,13 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { } break; } + cout << "Correlation Functions for Simplified LM model: "; + switch (lmParsedOptions.Correlation_SLM) { + case TURB_TRANS_CORRELATION_SLM::CODER_SLM: cout << "Coder et al. (2012)" << endl; break; + case TURB_TRANS_CORRELATION_SLM::MOD_EPPLER_SLM: cout << "Modified Eppler (from Coder et al. 2012)" << endl; break; + case TURB_TRANS_CORRELATION_SLM::MENTER_SLM: + case TURB_TRANS_CORRELATION_SLM::DEFAULT: cout << "Menter et al. (2015)" << endl; break; + } } cout << "Hybrid RANS/LES: "; switch (Kind_HybridRANSLES) { diff --git a/SU2_CFD/include/numerics/CNumerics.hpp b/SU2_CFD/include/numerics/CNumerics.hpp index 4eea7d9debd..4b4c9c6224f 100644 --- a/SU2_CFD/include/numerics/CNumerics.hpp +++ b/SU2_CFD/include/numerics/CNumerics.hpp @@ -734,6 +734,25 @@ class CNumerics { */ su2double GetIntermittencyEff() const { return intermittency_eff_i; } + /*! + * \brief Get the value of the Transition Momentum Thickness Reynolds number from correlations. + * \param[in] Corr_Rec_i - Value of the Transition Momentum Thickness Reynolds number at point i. + */ + inline virtual su2double GetCorr_Rec() {return 0.0;} + + /*! + * \brief Get the value of the Momentum Thickness Reynolds number. + * \param[in] Corr_Rec_i - Value of the Momentum Thickness Reynolds number at point i. + */ + inline virtual su2double GetRe_t() {return 0.0;} + + /*! + * \brief Set the gradient of the auxiliary variables. + * \param[in] val_auxvar_grad_i - Gradient of the auxiliary variable at point i. + * \param[in] val_auxvar_grad_j - Gradient of the auxiliary variable at point j. + */ + inline virtual void SetAuxVar(su2double val_AuxVar) {} + /*! * \brief Set the gradient of the auxiliary variables. * \param[in] val_auxvar_grad_i - Gradient of the auxiliary variable at point i. diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_convection.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_convection.hpp index 88de5a666e2..ebcb0257af9 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_convection.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_convection.hpp @@ -38,3 +38,10 @@ template using CUpwSca_TransLM = CUpwSca_TurbSST; +/*! + * \class CUpwSca_TransSLM + * \brief Re-use the SA convective fluxes for the scalar upwind discretization of Simplified LM transition model equations. + * \ingroup ConvDiscr + */ +template +using CUpwSca_TransSLM = CUpwSca_TurbSA; diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp index bb80218ac6d..a4f9f663fbd 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp @@ -25,6 +25,7 @@ */ #pragma once +//#include /*! * \class TransLMCorrelations @@ -189,4 +190,106 @@ class TransLMCorrelations { return F_length1; } + + /*! + * \brief Compute Re_theta_c from correlations for the Simplified LM model. + * \param[in] Tu - Turbulence intensity. + * \param[in] du_ds - Streamwise velocity gradient. + * \param[out] rethetac - Corrected value for Re_theta. + */ + su2double ReThetaC_Correlations_SLM(const su2double Tu_L, const su2double du_ds, const su2double wall_dist, const su2double Laminar_Viscosity, const su2double Density, const su2double VorticityMag, const su2double VelocityMag) const { + + su2double rethetac = 0.0; + + switch (options.Correlation_SLM) { + case TURB_TRANS_CORRELATION_SLM::MENTER_SLM: { + + /*-- Thwaites parameter ---*/ + su2double lambda_theta_local = 7.57e-3 * du_ds * wall_dist * wall_dist * Density / Laminar_Viscosity + 0.0128; + lambda_theta_local = min(max(lambda_theta_local, -1.0), 1.0); + + /*-- Function to sensitize the transition onset to the streamwise pressure gradient ---*/ + su2double FPG = 0.0; + const su2double C_PG1 = 14.68; + const su2double C_PG1_lim = 1.5; + const su2double C_PG2 = -7.34; + const su2double C_PG2_lim = 3.0; + const su2double C_PG3 = 0.0; + if (lambda_theta_local >= 0.0) { + FPG = min(1+ C_PG1 * lambda_theta_local, C_PG1_lim); + } else { + const su2double FirstTerm = C_PG2 * lambda_theta_local; + const su2double SecondTerm = C_PG3 * min(lambda_theta_local + 0.0681, 0.0); + FPG = min(1 + FirstTerm + SecondTerm, C_PG2_lim); + } + + FPG = max(FPG, 0.0); + + const su2double C_TU1 = 100.0; + const su2double C_TU2 = 1000.0; + const su2double C_TU3 = 1.0; + rethetac = C_TU1 + C_TU2 * exp(-C_TU3 * Tu_L * FPG); + + break; + } case TURB_TRANS_CORRELATION_SLM::CODER_SLM: { + + /*-- Local pressure gradient parameter ---*/ + const su2double H_c = max(min(wall_dist * VorticityMag / VelocityMag, 1.1542), 0.3823); + + /*-- Thwaites parameter ---*/ + su2double lambda_theta_local = 0.0; + const su2double H_c_delta = 0.587743 - H_c; + if ( H_c >= 0.587743 ) { + const su2double FirstTerm = 0.1919 * pow(H_c_delta, 3.0); + const su2double SecondTerm = 0.4182 * pow(H_c_delta, 2.0); + const su2double ThirdTerm = 0.2959 * H_c_delta; + lambda_theta_local = FirstTerm + SecondTerm + ThirdTerm; + } else { + const su2double FirstTerm = 4.7596 * pow(H_c_delta, 3.0); + const su2double SecondTerm = -0.3837 * pow(H_c_delta, 2.0); + const su2double ThirdTerm = 0.3575 * H_c_delta; + lambda_theta_local = FirstTerm + SecondTerm + ThirdTerm; + } + + /*-- Function to sensitize the transition onset to the streamwise pressure gradient ---*/ + su2double FPG = 0.0; + if (lambda_theta_local <= 0.0) { + const su2double FirstTerm = -12.986 * lambda_theta_local; + const su2double SecondTerm = -123.66 * pow(lambda_theta_local, 2.0); + const su2double ThirdTerm = -405.689 * pow(lambda_theta_local, 3.0); + FPG = 1 - (FirstTerm + SecondTerm + ThirdTerm) * exp(-pow(Tu_L/1.5,1.5)); + } else { + FPG = 1 + 0.275 * (1 - exp(-35.0 * lambda_theta_local)) * exp(-Tu_L/0.5); + } + + // This is not reported in the paper + //FPG = max(FPG, 0.0); + + const su2double C_TU1 = 100.0; + const su2double C_TU2 = 1000.0; + const su2double C_TU3 = 1.0; + rethetac = C_TU1 + C_TU2 * exp(-C_TU3 * Tu_L * FPG); + + break; + } case TURB_TRANS_CORRELATION_SLM::MOD_EPPLER_SLM: { + + /*-- Local pressure gradient parameter ---*/ + const su2double H_c = max(min(wall_dist * VorticityMag / VelocityMag, 1.1542), 0.3823); + + /*-- H_32 Shape factor --*/ + const su2double H_32 = 1.515095 + 0.2041 * pow((1.1542 - H_c), 2.0956); + + rethetac = exp(127.94 * pow((H_32-1.515095), 2.0) + 6.774224); + + break; + } + case TURB_TRANS_CORRELATION_SLM::DEFAULT: + SU2_MPI::Error("Transition correlation for Simplified LM model is set to DEFAULT but no default value has ben set in the code.", + CURRENT_FUNCTION); + break; + } + + return rethetac; + } + }; diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_diffusion.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_diffusion.hpp index 0ad86cf349d..6deafc31f7c 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_diffusion.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_diffusion.hpp @@ -103,3 +103,72 @@ class CAvgGrad_TransLM final : public CAvgGrad_Scalar { } }; + + +/*! + * \class CAvgGrad_TransSLM + * \brief Class for computing viscous term using average of gradient with correction (Simplified LM transition model). + * \ingroup ViscDiscr + * \author S. Kang. + */ +template +class CAvgGrad_TransSLM final : public CAvgGrad_Scalar { +private: + using Base = CAvgGrad_Scalar; + using Base::Laminar_Viscosity_i; + using Base::Laminar_Viscosity_j; + using Base::Eddy_Viscosity_i; + using Base::Eddy_Viscosity_j; + using Base::Density_i; + using Base::Density_j; + using Base::ScalarVar_i; + using Base::ScalarVar_j; + using Base::Proj_Mean_GradScalarVar; + using Base::proj_vector_ij; + using Base::Flux; + using Base::Jacobian_i; + using Base::Jacobian_j; + + /*! + * \brief Adds any extra variables to AD + */ + void ExtraADPreaccIn() override {} + + /*! + * \brief LM transition model specific steps in the ComputeResidual method + * \param[in] config - Definition of the particular problem. + */ + void FinishResidualCalc(const CConfig* config) override { + const bool implicit = config->GetKind_TimeIntScheme() == EULER_IMPLICIT; + + /*--- Compute mean effective dynamic viscosity ---*/ + const su2double diff_i_gamma = Laminar_Viscosity_i + Eddy_Viscosity_i; + const su2double diff_j_gamma = Laminar_Viscosity_j + Eddy_Viscosity_j; + + const su2double diff_gamma = 0.5*(diff_i_gamma + diff_j_gamma); + + Flux[0] = diff_gamma*Proj_Mean_GradScalarVar[0]; + + /*--- For Jacobians -> Use of TSL (Thin Shear Layer) approx. to compute derivatives of the gradients ---*/ + if (implicit) { + const su2double proj_on_rho_i = proj_vector_ij/Density_i; + Jacobian_i[0][0] = -diff_gamma*proj_on_rho_i; + + const su2double proj_on_rho_j = proj_vector_ij/Density_j; + Jacobian_j[0][0] = diff_gamma*proj_on_rho_j; + } + } + +public: + /*! + * \brief Constructor of the class. + * \param[in] val_nDim - Number of dimensions of the problem. + * \param[in] val_nVar - Number of variables of the problem. + * \param[in] correct_grad - Whether to correct gradient for skewness. + * \param[in] config - Definition of the particular problem. + */ + CAvgGrad_TransSLM(unsigned short val_nDim, unsigned short val_nVar, bool correct_grad, const CConfig* config) + : CAvgGrad_Scalar(val_nDim, val_nVar, correct_grad, config){ + } + +}; diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp index de013fb1a67..bcce973c240 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp @@ -92,7 +92,7 @@ class CSourcePieceWise_TransLM final : public CNumerics { * \return A lightweight const-view (read-only) of the residual/flux and Jacobians. */ ResidualType<> ComputeResidual(const CConfig* config) override { - /*--- ScalarVar[0] = k, ScalarVar[0] = w, TransVar[0] = gamma, and TransVar[0] = ReThetaT ---*/ + /*--- ScalarVar[0] = k, ScalarVar[0] = w, TransVar[0] = gamma, and TransVar[1] = ReThetaT ---*/ /*--- dU/dx = PrimVar_Grad[1][0] ---*/ AD::StartPreacc(); AD::SetPreaccIn(StrainMag_i); @@ -323,3 +323,190 @@ class CSourcePieceWise_TransLM final : public CNumerics { return ResidualType<>(Residual, Jacobian_i, nullptr); } }; + + +/*! + * \class CSourcePieceWise_TranSLM + * \brief Class for integrating the source terms of the Simplified LM transition model equations. + * \ingroup SourceDiscr + * \author S. Kang. + */ +template +class CSourcePieceWise_TransSLM final : public CNumerics { + private: + const FlowIndices idx; /*!< \brief Object to manage the access to the flow primitives. */ + + const LM_ParsedOptions options; + + /*--- LM Closure constants ---*/ + const su2double c_e1 = 1.0; + const su2double c_a1 = 2.0; + const su2double c_e2 = 50.0; + const su2double c_a2 = 0.06; + const su2double sigmaf = 1.0; + const su2double s1 = 2.0; + const su2double c_theta = 0.03; + const su2double c_CF = 0.6; + const su2double sigmat = 2.0; + + TURB_FAMILY TurbFamily; + su2double hRoughness; + + su2double IntermittencySep = 1.0; + su2double IntermittencyEff = 1.0; + + su2double Re_t; + su2double Corr_Rec; + su2double AuxVar; + + su2double Residual; + su2double* Jacobian_i; + su2double Jacobian_Buffer; // Static storage for the Jacobian (which needs to be pointer for return type). + + TransLMCorrelations TransCorrelations; + + public: + /*! + * \brief Constructor of the class. + * \param[in] val_nDim - Number of dimensions of the problem. + * \param[in] val_nVar - Number of variables of the problem. + * \param[in] config - Definition of the particular problem. + */ + CSourcePieceWise_TransSLM(unsigned short val_nDim, unsigned short val_nVar, const CConfig* config) + : CNumerics(val_nDim, 1, config), idx(val_nDim, config->GetnSpecies()), options(config->GetLMParsedOptions()){ + /*--- "Allocate" the Jacobian using the static buffer. ---*/ + Jacobian_i = &Jacobian_Buffer; + + TurbFamily = TurbModelFamily(config->GetKind_Turb_Model()); + + hRoughness = config->GethRoughness(); + + TransCorrelations.SetOptions(options); + + } + + /*! + * \brief Residual for source term integration. + * \param[in] config - Definition of the particular problem. + * \return A lightweight const-view (read-only) of the residual/flux and Jacobians. + */ + ResidualType<> ComputeResidual(const CConfig* config) override { + /*--- ScalarVar[0] = k, ScalarVar[0] = w, TransVar[0] = gamma ---*/ + /*--- dU/dx = PrimVar_Grad[1][0] ---*/ + AD::StartPreacc(); + AD::SetPreaccIn(StrainMag_i); + AD::SetPreaccIn(ScalarVar_i, nVar); + AD::SetPreaccIn(ScalarVar_Grad_i, nVar, nDim); + AD::SetPreaccIn(TransVar_i, nVar); + AD::SetPreaccIn(TransVar_Grad_i, nVar, nDim); + AD::SetPreaccIn(Volume); + AD::SetPreaccIn(dist_i); + AD::SetPreaccIn(&V_i[idx.Velocity()], nDim); + AD::SetPreaccIn(PrimVar_Grad_i, nDim + idx.Velocity(), nDim); + AD::SetPreaccIn(Vorticity_i, 3); + + su2double VorticityMag = + sqrt(Vorticity_i[0] * Vorticity_i[0] + Vorticity_i[1] * Vorticity_i[1] + Vorticity_i[2] * Vorticity_i[2]); + + const su2double vel_u = V_i[idx.Velocity()]; + const su2double vel_v = V_i[1 + idx.Velocity()]; + const su2double vel_w = (nDim == 3) ? V_i[2 + idx.Velocity()] : 0.0; + + const su2double Velocity_Mag = sqrt(vel_u * vel_u + vel_v * vel_v + vel_w * vel_w); + + AD::SetPreaccIn(V_i[idx.Density()], V_i[idx.LaminarViscosity()], V_i[idx.EddyViscosity()]); + + Density_i = V_i[idx.Density()]; + Laminar_Viscosity_i = V_i[idx.LaminarViscosity()]; + Eddy_Viscosity_i = V_i[idx.EddyViscosity()]; + + Residual = 0.0; + Jacobian_i[0] = 0.0; + + if (dist_i > 1e-10) { + su2double Tu_L = 1.0; + if (TurbFamily == TURB_FAMILY::KW) Tu_L = max(min(100.0 * sqrt(2.0 * ScalarVar_i[0] / 3.0) / (ScalarVar_i[1]*dist_i), 100.0), 0.027); + if (TurbFamily == TURB_FAMILY::SA) Tu_L = config->GetTurbulenceIntensity_FreeStream() * 100; + + /*--- F_length ---*/ + su2double F_length = 100.0; + + /*--- F_onset ---*/ + su2double R_t = 1.0; + if (TurbFamily == TURB_FAMILY::KW) R_t = Density_i * ScalarVar_i[0] / Laminar_Viscosity_i / ScalarVar_i[1]; + if (TurbFamily == TURB_FAMILY::SA) R_t = Eddy_Viscosity_i / Laminar_Viscosity_i; + + /*-- Gradient of velocity magnitude ---*/ + + su2double dU_dx = 0.5 / Velocity_Mag * (2. * vel_u * PrimVar_Grad_i[1][0] + 2. * vel_v * PrimVar_Grad_i[2][0]); + if (nDim == 3) dU_dx += 0.5 / Velocity_Mag * (2. * vel_w * PrimVar_Grad_i[3][0]); + + su2double dU_dy = 0.5 / Velocity_Mag * (2. * vel_u * PrimVar_Grad_i[1][1] + 2. * vel_v * PrimVar_Grad_i[2][1]); + if (nDim == 3) dU_dy += 0.5 / Velocity_Mag * (2. * vel_w * PrimVar_Grad_i[3][1]); + + su2double dU_dz = 0.0; + if (nDim == 3) + dU_dz = + 0.5 / Velocity_Mag * + (2. * vel_u * PrimVar_Grad_i[1][2] + 2. * vel_v * PrimVar_Grad_i[2][2] + 2. * vel_w * PrimVar_Grad_i[3][2]); + + su2double du_ds = vel_u / Velocity_Mag * dU_dx + vel_v / Velocity_Mag * dU_dy; + if (nDim == 3) du_ds += vel_w / Velocity_Mag * dU_dz; + + /*--- Corr_RetC correlation*/ + //Re_t = TransCorrelations.ReThetaC_Correlations_SLM(Tu_L, du_ds, dist_i, Laminar_Viscosity_i, Density_i, VorticityMag, Velocity_Mag); + Re_t = TransCorrelations.ReThetaC_Correlations_SLM(Tu_L, AuxVar, dist_i, Laminar_Viscosity_i, Density_i, VorticityMag, Velocity_Mag); + + if (options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::CODER_SLM || options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MOD_EPPLER_SLM) { + // If these correlations are used, then the value of Corr_Rec has to be used instead of the TransVar[1] of the original LM model + F_length = TransCorrelations.FLength_Correlations(Tu_L, Re_t); + Corr_Rec = TransCorrelations.ReThetaC_Correlations(Tu_L, Re_t); + } + if (options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM) Corr_Rec = Re_t; + + + const su2double Re_v = Density_i * dist_i * dist_i * StrainMag_i / Laminar_Viscosity_i; + const su2double F_onset1 = Re_v / (2.2 * Corr_Rec); + su2double F_onset2 = 1.0; + su2double F_onset3 = 1.0; + if (TurbFamily == TURB_FAMILY::KW) { + F_onset2 = min(F_onset1, 2.0); + F_onset3 = max(1.0 - pow(R_t / 3.5, 3.0), 0.0); + } + if (TurbFamily == TURB_FAMILY::SA) { + F_onset2 = min(max(F_onset1, pow(F_onset1, 4.0)), 4.0); + F_onset3 = max(2.0 - pow(R_t / 2.5, 3.0), 0.0); + } + const su2double F_onset = max(F_onset2 - F_onset3, 0.0); + + const su2double f_turb = exp(-pow(R_t / 4, 4)); + + /*-- production term of Intermeittency(Gamma) --*/ + const su2double Pg = + F_length * Density_i * StrainMag_i * F_onset * TransVar_i[0] * (1.0 - TransVar_i[0]); + + /*-- destruction term of Intermeittency(Gamma) --*/ + const su2double Dg = c_a2 * Density_i * VorticityMag * TransVar_i[0] * f_turb * (c_e2 * TransVar_i[0] - 1.0); + + /*--- Source ---*/ + Residual += (Pg - Dg) * Volume; + + /*--- Implicit part ---*/ + Jacobian_i[0] = (F_length * StrainMag_i * F_onset * (1 - 2*TransVar_i[0]) - + c_a2 * VorticityMag * f_turb * (2.0 * c_e2 * TransVar_i[0] - 1.0)) * + Volume; + + } + + AD::SetPreaccOut(Residual, nVar); + AD::EndPreacc(); + + return ResidualType<>(&Residual, &Jacobian_i, nullptr); + + } + + inline su2double GetRe_t() override {return Re_t;} + inline su2double GetCorr_Rec() override {return Corr_Rec;} + inline void SetAuxVar(su2double val_AuxVar) override { AuxVar = val_AuxVar;} + +}; diff --git a/SU2_CFD/include/numerics/turbulent/turb_sources.hpp b/SU2_CFD/include/numerics/turbulent/turb_sources.hpp index e11880bb41e..810245a2b43 100644 --- a/SU2_CFD/include/numerics/turbulent/turb_sources.hpp +++ b/SU2_CFD/include/numerics/turbulent/turb_sources.hpp @@ -831,6 +831,16 @@ class CSourcePieceWise_TurbSST final : public CNumerics { /*--- LM model coupling with production and dissipation term for k transport equation---*/ if (config->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM) { pk = pk * eff_intermittency; + // Check if the Prod_lim_k has to be introduced based on input options + if ((config->GetLMParsedOptions()).ProdLim) { + const su2double Re_theta_c_lim = 1100.0; + const su2double C_k = 1.0; + const su2double C_SEP = 1.0; + const su2double Re_v = Density_i * dist_i * dist_i * StrainMag_i / Laminar_Viscosity_i; + const su2double F_on_lim = min(max(Re_v/(2.2*Re_theta_c_lim)-1.0, 0.0), 3.0); + const su2double IntermittencyRelated = max(eff_intermittency-0.2, 0.0) * (1.0 - eff_intermittency); + pk = pk + 5*C_k * IntermittencyRelated * F_on_lim * max(3.0*C_SEP*Laminar_Viscosity_i - Eddy_Viscosity_i, 0.0) * StrainMag_i * VorticityMag; + } dk = min(max(eff_intermittency, 0.1), 1.0) * dk; } diff --git a/SU2_CFD/include/variables/CTransLMVariable.hpp b/SU2_CFD/include/variables/CTransLMVariable.hpp index c3893023d55..6c18eb03b59 100644 --- a/SU2_CFD/include/variables/CTransLMVariable.hpp +++ b/SU2_CFD/include/variables/CTransLMVariable.hpp @@ -40,6 +40,8 @@ class CTransLMVariable final : public CTurbVariable { protected: VectorType Intermittency_Eff; VectorType Intermittency_Sep; + VectorType Corr_Rec; + VectorType Re_t; public: /*! @@ -55,6 +57,18 @@ class CTransLMVariable final : public CTurbVariable { */ CTransLMVariable(su2double Intermittency, su2double ReThetaT, su2double gammaSep, su2double gammaEff, unsigned long npoint, unsigned long ndim, unsigned long nvar, CConfig *config); + /*! + * \brief Constructor of the class. + * \param[in] Intermittency - intermittency(gamma) (initialization value). + * \param[in] gammaSep - separation intermittency(gamma) (initialization value). + * \param[in] gammaEff - effective intermittency(gamma) (initialization value). + * \param[in] npoint - Number of points/nodes/vertices in the domain. + * \param[in] ndim - Number of dimensions of the problem. + * \param[in] nvar - Number of variables of the problem. + * \param[in] config - Definition of the particular problem. + */ + CTransLMVariable(su2double Intermittency, su2double gammaSep, su2double gammaEff, unsigned long npoint, unsigned long ndim, unsigned long nvar, CConfig *config); + /*! * \brief Destructor of the class. */ @@ -70,6 +84,16 @@ class CTransLMVariable final : public CTurbVariable { */ void SetIntermittencyEff(unsigned long iPoint, su2double val_Intermittency_sep) override; + /*! + * \brief Set Value of Transition Momentum Thickness Reynolds number from correlations. + */ + void SetCorr_Rec(unsigned long iPoint, su2double val_Corr_Rec) override; + + /*! + * \brief Set Value of Momentum Thickness Reynolds number from correlations (substitute to the second equation of original LM model). + */ + void SetRe_t(unsigned long iPoint, su2double val_Re_t) override; + /*! * \brief Calculate effective intermittency. */ @@ -80,4 +104,13 @@ class CTransLMVariable final : public CTurbVariable { */ inline su2double GetIntermittencySep(unsigned long iPoint) const override { return Intermittency_Sep(iPoint); } + /*! + * \brief Get Value of Transition Momentum Thickness Reynolds number from correlations. + */ + inline su2double GetCorr_Rec(unsigned long iPoint) const override { return Corr_Rec(iPoint); } + + /*! + * \brief Get Value of Momentum Thickness Reynolds number from correlations (substitute to the second equation of original LM model). + */ + inline su2double GetRe_t(unsigned long iPoint) const override { return Re_t(iPoint); } }; diff --git a/SU2_CFD/include/variables/CVariable.hpp b/SU2_CFD/include/variables/CVariable.hpp index 73ac61075d6..099988e1a2b 100644 --- a/SU2_CFD/include/variables/CVariable.hpp +++ b/SU2_CFD/include/variables/CVariable.hpp @@ -1713,6 +1713,26 @@ class CVariable { */ inline virtual void SetIntermittencyEff(unsigned long iPoint, su2double val_Intermittency_eff) {} + /*! + * \brief Set Value of Transition Momentum Thickness Reynolds number from correlations. + */ + inline virtual void SetCorr_Rec(unsigned long iPoint, su2double val_Corr_Rec) {}; + + /*! + * \brief Get Value of Transition Momentum Thickness Reynolds number from correlations. + */ + inline virtual su2double GetCorr_Rec(unsigned long iPoint) const { return 0.0; } + + /*! + * \brief Set Value of Momentum Thickness Reynolds number from correlations (substitute to the second equation of original LM model). + */ + inline virtual void SetRe_t(unsigned long iPoint, su2double val_Re_t) {}; + + /*! + * \brief Get Value of Momentum Thickness Reynolds number from correlations (substitute to the second equation of original LM model). + */ + inline virtual su2double GetRe_t(unsigned long iPoint) const { return 0.0; } + /*! * \brief Set the value of the eddy viscosity. * \param[in] val_muT diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index 0b2c5d94aab..5c39743c64b 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -1346,6 +1346,8 @@ void CDriver::InstantiateTransitionNumerics(unsigned short nVar_Trans, int offse const int visc_bound_term = VISC_BOUND_TERM + offset; const bool LM = config->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM; + LM_ParsedOptions options; + if(LM) options = config->GetLMParsedOptions(); /*--- Definition of the convective scheme for each equation and mesh level ---*/ @@ -1355,7 +1357,10 @@ void CDriver::InstantiateTransitionNumerics(unsigned short nVar_Trans, int offse break; case SPACE_UPWIND : for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - if (LM) numerics[iMGlevel][TRANS_SOL][conv_term] = new CUpwSca_TransLM(nDim, nVar_Trans, config); + if (LM){ + if (!options.SLM) numerics[iMGlevel][TRANS_SOL][conv_term] = new CUpwSca_TransLM(nDim, nVar_Trans, config); + if (options.SLM) numerics[iMGlevel][TRANS_SOL][conv_term] = new CUpwSca_TransSLM(nDim, nVar_Trans, config); + } } break; default: @@ -1366,7 +1371,10 @@ void CDriver::InstantiateTransitionNumerics(unsigned short nVar_Trans, int offse /*--- Definition of the viscous scheme for each equation and mesh level ---*/ for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - if (LM) numerics[iMGlevel][TRANS_SOL][visc_term] = new CAvgGrad_TransLM(nDim, nVar_Trans, true, config); + if (LM){ + if (!options.SLM) numerics[iMGlevel][TRANS_SOL][visc_term] = new CAvgGrad_TransLM(nDim, nVar_Trans, true, config); + if (options.SLM) numerics[iMGlevel][TRANS_SOL][visc_term] = new CAvgGrad_TransSLM(nDim, nVar_Trans, true, config); + } } /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ @@ -1374,17 +1382,25 @@ void CDriver::InstantiateTransitionNumerics(unsigned short nVar_Trans, int offse for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { auto& trans_source_first_term = numerics[iMGlevel][TRANS_SOL][source_first_term]; - if (LM) trans_source_first_term = new CSourcePieceWise_TransLM(nDim, nVar_Trans, config); - + if (LM){ + if (!options.SLM) trans_source_first_term = new CSourcePieceWise_TransLM(nDim, nVar_Trans, config); + if (options.SLM) trans_source_first_term = new CSourcePieceWise_TransSLM(nDim, nVar_Trans, config); + } numerics[iMGlevel][TRANS_SOL][source_second_term] = new CSourceNothing(nDim, nVar_Trans, config); } /*--- Definition of the boundary condition method ---*/ for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - if (LM) { - numerics[iMGlevel][TRANS_SOL][conv_bound_term] = new CUpwSca_TransLM(nDim, nVar_Trans, config); - numerics[iMGlevel][TRANS_SOL][visc_bound_term] = new CAvgGrad_TransLM(nDim, nVar_Trans, false, config); + if (LM) { + if (!options.SLM) { + numerics[iMGlevel][TRANS_SOL][conv_bound_term] = new CUpwSca_TransLM(nDim, nVar_Trans, config); + numerics[iMGlevel][TRANS_SOL][visc_bound_term] = new CAvgGrad_TransLM(nDim, nVar_Trans, false, config); + } else { + numerics[iMGlevel][TRANS_SOL][conv_bound_term] = new CUpwSca_TransSLM(nDim, nVar_Trans, config); + numerics[iMGlevel][TRANS_SOL][visc_bound_term] = new CAvgGrad_TransSLM(nDim, nVar_Trans, false, config); + } + } } } diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index cb88b9f9f26..00236d8e588 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -873,8 +873,10 @@ void CFlowOutput::AddHistoryOutputFields_ScalarRMS_RES(const CConfig* config) { case TURB_TRANS_MODEL::LM: /// DESCRIPTION: Root-mean square residual of the intermittency (LM model). AddHistoryOutput("RMS_INTERMITTENCY", "rms[LM_1]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of intermittency (LM model).", HistoryFieldType::RESIDUAL); - /// DESCRIPTION: Root-mean square residual of the momentum thickness Reynolds number (LM model). - AddHistoryOutput("RMS_RE_THETA_T", "rms[LM_2]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of momentum thickness Reynolds number (LM model).", HistoryFieldType::RESIDUAL); + if (!(config->GetLMParsedOptions()).SLM) { + /// DESCRIPTION: Root-mean square residual of the momentum thickness Reynolds number (LM model). + AddHistoryOutput("RMS_RE_THETA_T", "rms[LM_2]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of momentum thickness Reynolds number (LM model).", HistoryFieldType::RESIDUAL); + } break; case TURB_TRANS_MODEL::NONE: break; @@ -910,8 +912,10 @@ void CFlowOutput::AddHistoryOutputFields_ScalarMAX_RES(const CConfig* config) { case TURB_TRANS_MODEL::LM: /// DESCRIPTION: Maximum residual of the intermittency (LM model). AddHistoryOutput("MAX_INTERMITTENCY", "max[LM_1]", ScreenOutputFormat::FIXED, "MAX_RES", "Maximum residual of the intermittency (LM model).", HistoryFieldType::RESIDUAL); - /// DESCRIPTION: Maximum residual of the momentum thickness Reynolds number (LM model). - AddHistoryOutput("MAX_RE_THETA_T", "max[LM_2]", ScreenOutputFormat::FIXED, "MAX_RES", "Maximum residual of the momentum thickness Reynolds number (LM model).", HistoryFieldType::RESIDUAL); + if (!(config->GetLMParsedOptions()).SLM) { + /// DESCRIPTION: Maximum residual of the momentum thickness Reynolds number (LM model). + AddHistoryOutput("MAX_RE_THETA_T", "max[LM_2]", ScreenOutputFormat::FIXED, "MAX_RES", "Maximum residual of the momentum thickness Reynolds number (LM model).", HistoryFieldType::RESIDUAL); + } break; case TURB_TRANS_MODEL::NONE: @@ -948,8 +952,10 @@ void CFlowOutput::AddHistoryOutputFields_ScalarBGS_RES(const CConfig* config) { case TURB_TRANS_MODEL::LM: /// DESCRIPTION: Maximum residual of the intermittency (LM model). AddHistoryOutput("BGS_INTERMITTENCY", "bgs[LM_1]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the intermittency (LM model).", HistoryFieldType::RESIDUAL); - /// DESCRIPTION: Maximum residual of the momentum thickness Reynolds number (LM model). - AddHistoryOutput("BGS_RE_THETA_T", "bgs[LM_2]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the momentum thickness Reynolds number (LM model).", HistoryFieldType::RESIDUAL); + if (!(config->GetLMParsedOptions()).SLM) { + /// DESCRIPTION: Maximum residual of the momentum thickness Reynolds number (LM model). + AddHistoryOutput("BGS_RE_THETA_T", "bgs[LM_2]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the momentum thickness Reynolds number (LM model).", HistoryFieldType::RESIDUAL); + } break; case TURB_TRANS_MODEL::NONE: break; @@ -1012,12 +1018,16 @@ void CFlowOutput::LoadHistoryData_Scalar(const CConfig* config, const CSolver* c switch (config->GetKind_Trans_Model()) { case TURB_TRANS_MODEL::LM: SetHistoryOutputValue("RMS_INTERMITTENCY", log10(solver[TRANS_SOL]->GetRes_RMS(0))); - SetHistoryOutputValue("RMS_RE_THETA_T",log10(solver[TRANS_SOL]->GetRes_RMS(1))); SetHistoryOutputValue("MAX_INTERMITTENCY", log10(solver[TRANS_SOL]->GetRes_Max(0))); - SetHistoryOutputValue("MAX_RE_THETA_T", log10(solver[TRANS_SOL]->GetRes_Max(1))); + if (!(config->GetLMParsedOptions()).SLM) { + SetHistoryOutputValue("RMS_RE_THETA_T",log10(solver[TRANS_SOL]->GetRes_RMS(1))); + SetHistoryOutputValue("MAX_RE_THETA_T", log10(solver[TRANS_SOL]->GetRes_Max(1))); + } if (multiZone) { SetHistoryOutputValue("BGS_INTERMITTENCY", log10(solver[TRANS_SOL]->GetRes_BGS(0))); - SetHistoryOutputValue("BGS_RE_THETA_T", log10(solver[TRANS_SOL]->GetRes_BGS(1))); + if (!(config->GetLMParsedOptions()).SLM) { + SetHistoryOutputValue("BGS_RE_THETA_T", log10(solver[TRANS_SOL]->GetRes_BGS(1))); + } } SetHistoryOutputValue("LINSOL_ITER_TRANS", solver[TRANS_SOL]->GetIterLinSolver()); SetHistoryOutputValue("LINSOL_RESIDUAL_TRANS", log10(solver[TRANS_SOL]->GetResLinSolver())); @@ -1059,6 +1069,9 @@ void CFlowOutput::SetVolumeOutputFields_ScalarSolution(const CConfig* config){ case TURB_TRANS_MODEL::LM: AddVolumeOutput("INTERMITTENCY", "LM_gamma", "SOLUTION", "LM intermittency"); AddVolumeOutput("RE_THETA_T", "LM_Re_t", "SOLUTION", "LM RE_THETA_T"); + if ((config->GetLMParsedOptions()).SLM) { + AddVolumeOutput("RE_THETA_CORR", "LM_Corr_Rec", "SOLUTION", "LM RE_THETA_CORR"); + } AddVolumeOutput("INTERMITTENCY_SEP", "LM_gamma_sep", "PRIMITIVE", "LM intermittency"); AddVolumeOutput("INTERMITTENCY_EFF", "LM_gamma_eff", "PRIMITIVE", "LM RE_THETA_T"); AddVolumeOutput("TURB_INDEX", "Turb_index", "PRIMITIVE", "Turbulence index"); @@ -1092,7 +1105,9 @@ void CFlowOutput::SetVolumeOutputFields_ScalarResidual(const CConfig* config) { switch (config->GetKind_Trans_Model()) { case TURB_TRANS_MODEL::LM: AddVolumeOutput("RES_INTERMITTENCY", "Residual_LM_intermittency", "RESIDUAL", "Residual of LM intermittency"); - AddVolumeOutput("RES_RE_THETA_T", "Residual_LM_RE_THETA_T", "RESIDUAL", "Residual of LM RE_THETA_T"); + if (!(config->GetLMParsedOptions()).SLM) { + AddVolumeOutput("RES_RE_THETA_T", "Residual_LM_RE_THETA_T", "RESIDUAL", "Residual of LM RE_THETA_T"); + } break; case TURB_TRANS_MODEL::NONE: @@ -1212,12 +1227,19 @@ void CFlowOutput::LoadVolumeData_Scalar(const CConfig* config, const CSolver* co switch (config->GetKind_Trans_Model()) { case TURB_TRANS_MODEL::LM: SetVolumeOutputValue("INTERMITTENCY", iPoint, Node_Trans->GetSolution(iPoint, 0)); - SetVolumeOutputValue("RE_THETA_T", iPoint, Node_Trans->GetSolution(iPoint, 1)); + if (!(config->GetLMParsedOptions()).SLM) { + SetVolumeOutputValue("RE_THETA_T", iPoint, Node_Trans->GetSolution(iPoint, 1)); + } else { + SetVolumeOutputValue("RE_THETA_T", iPoint, Node_Trans->GetRe_t(iPoint)); + SetVolumeOutputValue("RE_THETA_CORR", iPoint, Node_Trans->GetCorr_Rec(iPoint)); + } SetVolumeOutputValue("INTERMITTENCY_SEP", iPoint, Node_Trans->GetIntermittencySep(iPoint)); SetVolumeOutputValue("INTERMITTENCY_EFF", iPoint, Node_Trans->GetIntermittencyEff(iPoint)); SetVolumeOutputValue("TURB_INDEX", iPoint, Node_Turb->GetTurbIndex(iPoint)); SetVolumeOutputValue("RES_INTERMITTENCY", iPoint, trans_solver->LinSysRes(iPoint, 0)); - SetVolumeOutputValue("RES_RE_THETA_T", iPoint, trans_solver->LinSysRes(iPoint, 1)); + if (!(config->GetLMParsedOptions()).SLM) { + SetVolumeOutputValue("RES_RE_THETA_T", iPoint, trans_solver->LinSysRes(iPoint, 1)); + } break; case TURB_TRANS_MODEL::NONE: break; diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index 0ceb3d86992..8e06e296154 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -49,6 +49,14 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh /*--- Dimension of the problem --> 2 Transport equations (intermittency, Reth) ---*/ nVar = 2; nPrimVar = 2; + + /*--- Check if Simplified version is used ---*/ + options = config->GetLMParsedOptions(); + if (options.SLM) { + nVar = 1; + nPrimVar = 1; + } + nPoint = geometry->GetnPoint(); nPointDomain = geometry->GetnPointDomain(); @@ -61,16 +69,9 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh nDim = geometry->GetnDim(); /*--- Define variables needed for transition from config file ---*/ - options = config->GetLMParsedOptions(); TransCorrelations.SetOptions(options); TurbFamily = TurbModelFamily(config->GetKind_Turb_Model()); - /*--- Check if Simplified version is used ---*/ - if (options.SLM) { - nVar = 1; - nPrimVar = 1; - } - /*--- Single grid simulation ---*/ if (iMesh == MESH_0) { @@ -121,7 +122,8 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh su2double ReThetaT_Inf = 0.0; if (!options.SLM) { - su2double ReThetaT_Inf = 100.0; + + ReThetaT_Inf = 100.0; /*--- Momentum thickness Reynolds number, initialized from freestream turbulent intensity*/ if (Intensity <= 1.3) { @@ -140,7 +142,10 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh } /*--- Initialize the solution to the far-field state everywhere. ---*/ - nodes = new CTransLMVariable(Intermittency_Inf, ReThetaT_Inf, 1.0, 1.0, nPoint, nDim, nVar, config); + nodes = new CTransLMVariable(Intermittency_Inf, 1.0, 1.0, nPoint, nDim, nVar, config); + if (!options.SLM) { + nodes = new CTransLMVariable(Intermittency_Inf, ReThetaT_Inf, 1.0, 1.0, nPoint, nDim, nVar, config); + } SetBaseClassPointerToNodes(); @@ -169,7 +174,7 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh Inlet_TurbVars[iMarker].resize(nVertex[iMarker],nVar); for (unsigned long iVertex = 0; iVertex < nVertex[iMarker]; ++iVertex) { Inlet_TurbVars[iMarker](iVertex,0) = Intermittency_Inf; - Inlet_TurbVars[iMarker](iVertex,1) = ReThetaT_Inf; + if (!options.SLM) Inlet_TurbVars[iMarker](iVertex,1) = ReThetaT_Inf; } } @@ -192,6 +197,70 @@ void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contain /*--- Upwind second order reconstruction and gradients ---*/ CommonPreprocessing(geometry, config, Output); + + + ///////////////////// + // ATTENZIONE! Forse devo farlo solamente per i punti che sono nello strato limite! Quindi magari nelle sources devo usare la function che mi definisce lo strato limite! + // Al di fuori di essa devo usare la solita du/ds? PerchĆØ altrimenti il contorno piĆ¹ vicino ad un certo punto diventa il farfield, e non ha senso! + // UPDATE: Mi sa che la wall distance ĆØ rispetto alla parete, quindi effettivamente l'elemento piĆ¹ vicino ĆØ sempre a parete. + ///////////////////// + + cout << "Sono qui" << endl; + //if (rank == MASTER_NODE) { + if (options.SLM) { + /*--- Reconstructon of auxiliary variables gradient ---*/ + su2double Normal[nPoint][nDim]; + SU2_OMP_FOR_STAT(omp_chunk_size) + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { + for (auto iDim = 0u; iDim < nDim; iDim++) + Normal[iPoint][iDim] = 0.0; + + // Extract nearest wall element and wall marker + unsigned long NearestWallElement = geometry->nodes->GetClosestWall_Elem(iPoint); + unsigned short NearestWallMarker = geometry->nodes->GetClosestWall_Marker(iPoint); + + // Cycle on all of the points of the wall element + for (unsigned short iNode = 0; iNode < geometry->bound[NearestWallMarker][NearestWallElement]->GetnNodes(); iNode++) { + // Extract global coordinate of the node + unsigned long iPointHere = geometry->bound[NearestWallMarker][NearestWallElement]->GetNode(iNode); + long iVertexHere = geometry->nodes->GetVertex(iPointHere, NearestWallMarker); + for (auto iDim = 0u; iDim < nDim; iDim++) + Normal[iPoint][iDim] += geometry->vertex[NearestWallMarker][iVertexHere]->GetNormal(iDim); + } + for (auto iDim = 0u; iDim < nDim; iDim++) + Normal[iPoint][iDim] /= geometry->bound[NearestWallMarker][NearestWallElement]->GetnNodes(); + + nodes->SetAuxVar(iPoint, 0, nodes->GetProjVel(iPoint, Normal[iPoint])); + } + END_SU2_OMP_FOR + + //SU2_OMP_BARRIER + + cout << "primo for" << endl; + + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { + SetAuxVar_Gradient_GG(geometry, config); + } + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + SetAuxVar_Gradient_LS(geometry, config); + } + + //SU2_OMP_BARRIER + + cout << "Dopo Gradienti" << endl; + + SU2_OMP_FOR_STAT(omp_chunk_size) + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { + su2double AuxVarHere = 0.0; + for (auto iDim = 0u; iDim < nDim; iDim++) + AuxVarHere += Normal[iPoint][iDim] * nodes->GetAuxVarGradient(iPoint, 0, iDim); + nodes->SetAuxVar(iPoint, 0, AuxVarHere); + } + END_SU2_OMP_FOR + + cout << "Ho finito" << endl; + } + } void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh) { @@ -223,7 +292,6 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai VorticityMag = max(VorticityMag, 1e-12); StrainMag = max(StrainMag, 1e-12); // safety against division by zero const su2double Intermittency = nodes->GetSolution(iPoint,0); - const su2double Re_t = nodes->GetSolution(iPoint,1); const su2double Re_v = rho*dist*dist*StrainMag/mu; const su2double vel_u = flowNodes->GetVelocity(iPoint, 0); const su2double vel_v = flowNodes->GetVelocity(iPoint, 1); @@ -231,17 +299,28 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai const su2double VelocityMag = sqrt(vel_u*vel_u + vel_v*vel_v + vel_w*vel_w); su2double omega = 0.0; su2double k = 0.0; - if(TurbFamily == TURB_FAMILY::KW){ - omega = turbNodes->GetSolution(iPoint,1); - k = turbNodes->GetSolution(iPoint,0); + + su2double Corr_Rec = 0.0; + su2double Re_t = 0.0; + if (!options.SLM) { + Re_t = nodes->GetSolution(iPoint,1); + if(TurbFamily == TURB_FAMILY::KW){ + omega = turbNodes->GetSolution(iPoint,1); + k = turbNodes->GetSolution(iPoint,0); + } + su2double Tu = 1.0; + if(TurbFamily == TURB_FAMILY::KW) + Tu = max(100.0*sqrt( 2.0 * k / 3.0 ) / VelocityMag,0.027); + if(TurbFamily == TURB_FAMILY::SA) + Tu = config->GetTurbulenceIntensity_FreeStream()*100; + + Corr_Rec = TransCorrelations.ReThetaC_Correlations(Tu, Re_t); } - su2double Tu = 1.0; - if(TurbFamily == TURB_FAMILY::KW) - Tu = max(100.0*sqrt( 2.0 * k / 3.0 ) / VelocityMag,0.027); - if(TurbFamily == TURB_FAMILY::SA) - Tu = config->GetTurbulenceIntensity_FreeStream()*100; - const su2double Corr_Rec = TransCorrelations.ReThetaC_Correlations(Tu, Re_t); + if (options.SLM) { + Re_t = nodes->GetRe_t(iPoint); + Corr_Rec = nodes->GetCorr_Rec(iPoint); + } su2double R_t = 1.0; if(TurbFamily == TURB_FAMILY::KW) @@ -352,10 +431,19 @@ void CTransLMSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta numerics->SetLocalGridLength(geometry->nodes->GetMaxLength(iPoint)); } + if(options.SLM) { + numerics->SetAuxVar(nodes->GetAuxVar(iPoint, 0)); + } + /*--- Compute the source term ---*/ auto residual = numerics->ComputeResidual(config); + if(options.SLM) { + nodes->SetRe_t(iPoint, numerics->GetRe_t()); + nodes->SetCorr_Rec(iPoint, numerics->GetCorr_Rec()); + } + /*--- Subtract residual and the Jacobian ---*/ LinSysRes.SubtractBlock(iPoint, residual); @@ -554,6 +642,7 @@ void CTransLMSolver::LoadRestart(CGeometry** geometry, CSolver*** solver, CConfi const auto index = counter * Restart_Vars[1] + skipVars; for (auto iVar = 0u; iVar < nVar; iVar++) nodes->SetSolution(iPoint_Local, iVar, Restart_Data[index + iVar]); + // I am really not sure about these, I have to check if they are actually saved nodes ->SetIntermittencySep(iPoint_Local, Restart_Data[index + 2]); nodes ->SetIntermittencyEff(iPoint_Local, Restart_Data[index + 3]); diff --git a/SU2_CFD/src/variables/CTransLMVariable.cpp b/SU2_CFD/src/variables/CTransLMVariable.cpp index ce73c451942..1e7d09f75da 100644 --- a/SU2_CFD/src/variables/CTransLMVariable.cpp +++ b/SU2_CFD/src/variables/CTransLMVariable.cpp @@ -36,8 +36,7 @@ CTransLMVariable::CTransLMVariable(su2double Intermittency, su2double ReThetaT, for(unsigned long iPoint=0; iPointGetLMParsedOptions(); + + for(unsigned long iPoint=0; iPoint Date: Tue, 31 Jan 2023 19:57:24 +0100 Subject: [PATCH 05/20] - Added Cross flow effects for SLM - Modified LM_OPTIONS to include cross-flow effects: from LM2015 to CROSSFLOW --- Common/include/option_structure.hpp | 8 +- Common/src/CConfig.cpp | 11 +- .../transition/trans_correlations.hpp | 5 +- .../turbulent/transition/trans_sources.hpp | 69 +++++++++-- SU2_CFD/src/output/CFlowOutput.cpp | 2 +- SU2_CFD/src/solvers/CTransLMSolver.cpp | 112 +++++++++--------- config_template.cfg | 2 +- 7 files changed, 132 insertions(+), 77 deletions(-) diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 63f2676ffde..f927d5b30d0 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -1173,7 +1173,7 @@ static const MapType Trans_Model_Map = { */ enum class LM_OPTIONS { NONE, /*!< \brief No option / default. */ - LM2015, /*!< \brief Cross-flow corrections. */ + CROSSFLOW, /*!< \brief Cross-flow corrections. */ SLM, /*!< \brief Simplified version. */ PRODLIM, /*!< \brief Add production term to Pk. */ MALAN, /*!< \brief Kind of transition correlation model (Malan). */ @@ -1191,7 +1191,7 @@ enum class LM_OPTIONS { static const MapType LM_Options_Map = { MakePair("NONE", LM_OPTIONS::NONE) - MakePair("LM2015", LM_OPTIONS::LM2015) + MakePair("CROSSFLOW", LM_OPTIONS::CROSSFLOW) MakePair("SLM", LM_OPTIONS::SLM) MakePair("PRODLIM", LM_OPTIONS::PRODLIM) MakePair("MALAN", LM_OPTIONS::MALAN) @@ -1235,7 +1235,7 @@ enum class TURB_TRANS_CORRELATION_SLM { */ struct LM_ParsedOptions { LM_OPTIONS version = LM_OPTIONS::NONE; /*!< \brief LM base model. */ - bool LM2015 = false; /*!< \brief Use cross-flow corrections. */ + bool CrossFlow = false; /*!< \brief Use cross-flow corrections. */ bool SLM = false; /*!< \brief Use simplified version. */ bool ProdLim = false; /*!< \brief Add production term to Pk. */ TURB_TRANS_CORRELATION Correlation = TURB_TRANS_CORRELATION::DEFAULT; @@ -1257,7 +1257,7 @@ inline LM_ParsedOptions ParseLMOptions(const LM_OPTIONS *LM_Options, unsigned sh return std::find(LM_Options, lm_options_end, option) != lm_options_end; }; - LMParsedOptions.LM2015 = IsPresent(LM_OPTIONS::LM2015); + LMParsedOptions.CrossFlow = IsPresent(LM_OPTIONS::CROSSFLOW); LMParsedOptions.SLM = IsPresent(LM_OPTIONS::SLM); LMParsedOptions.ProdLim = IsPresent(LM_OPTIONS::PRODLIM); diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 04ce1bc6734..ca78af64e6e 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -3471,9 +3471,9 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i if (Kind_Trans_Model == TURB_TRANS_MODEL::LM) { lmParsedOptions = ParseLMOptions(LM_Options, nLM_Options, rank, Kind_Turb_Model); - /*--- Check if problem is 2D and LM2015 has been selected ---*/ - if (lmParsedOptions.LM2015 && val_nDim == 2) { - SU2_MPI::Error("LM2015 is available only for 3D problems", CURRENT_FUNCTION); + /*--- Check if problem is 2D and CrossFlow has been selected ---*/ + if (lmParsedOptions.CrossFlow && val_nDim == 2) { + SU2_MPI::Error("Cross-flow corrections are available only for 3D problems", CURRENT_FUNCTION); } } @@ -6117,6 +6117,7 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { switch (Kind_Turb_Model) { case TURB_MODEL::SA: NTurbEqs = 1; break; case TURB_MODEL::SST: NTurbEqs = 2; break; + case TURB_MODEL::NONE: SU2_MPI::Error("No turbulence model has been selected but LM transition model is active.", CURRENT_FUNCTION); break; } if (!lmParsedOptions.SLM) { int NEquations = 2; @@ -6125,8 +6126,8 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { int NEquations = 1; cout << "Transition model: Simplified Langtry and Menter's "<< NEquations+NTurbEqs <<" equation model"; } - if (lmParsedOptions.LM2015) { - cout << " w/ cross-flow corrections (2015)" << endl; + if (lmParsedOptions.CrossFlow) { + cout << " w/ cross-flow corrections" << endl; } else { if (!lmParsedOptions.SLM) { cout << " (2009)" << endl; diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp index a4f9f663fbd..ecd569984ed 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp @@ -197,7 +197,7 @@ class TransLMCorrelations { * \param[in] du_ds - Streamwise velocity gradient. * \param[out] rethetac - Corrected value for Re_theta. */ - su2double ReThetaC_Correlations_SLM(const su2double Tu_L, const su2double du_ds, const su2double wall_dist, const su2double Laminar_Viscosity, const su2double Density, const su2double VorticityMag, const su2double VelocityMag) const { + su2double ReThetaC_Correlations_SLM(const su2double Tu_L, const su2double lambda_theta, const su2double wall_dist, const su2double VorticityMag, const su2double VelocityMag) const { su2double rethetac = 0.0; @@ -205,7 +205,8 @@ class TransLMCorrelations { case TURB_TRANS_CORRELATION_SLM::MENTER_SLM: { /*-- Thwaites parameter ---*/ - su2double lambda_theta_local = 7.57e-3 * du_ds * wall_dist * wall_dist * Density / Laminar_Viscosity + 0.0128; + // su2double lambda_theta_local = 7.57e-3 * du_ds * wall_dist * wall_dist * Density / Laminar_Viscosity + 0.0128; + su2double lambda_theta_local = lambda_theta; lambda_theta_local = min(max(lambda_theta_local, -1.0), 1.0); /*-- Function to sensitize the transition onset to the streamwise pressure gradient ---*/ diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp index bcce973c240..1bdc5c959cc 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp @@ -186,7 +186,7 @@ class CSourcePieceWise_TransLM final : public CNumerics { /*-- Calculate blending function f_theta --*/ su2double time_scale = 500.0 * Laminar_Viscosity_i / Density_i / Velocity_Mag / Velocity_Mag; - if (options.LM2015) + if (options.CrossFlow) time_scale = min(time_scale, Density_i * LocalGridLength_i * LocalGridLength_i / (Laminar_Viscosity_i + Eddy_Viscosity_i)); const su2double theta_bl = TransVar_i[1] * Laminar_Viscosity_i / Density_i / Velocity_Mag; @@ -206,7 +206,7 @@ class CSourcePieceWise_TransLM final : public CNumerics { const su2double f_turb = exp(-pow(R_t / 4, 4)); su2double f_theta_2 = 0.0; - if (options.LM2015) + if (options.CrossFlow) f_theta_2 = min(f_wake * exp(-pow(dist_i / delta, 4.0)), 1.0); /*--- Corr_Ret correlation*/ @@ -247,7 +247,7 @@ class CSourcePieceWise_TransLM final : public CNumerics { /*-- Corr_RetT_SCF Correlations--*/ su2double ReThetat_SCF = 0.0; - if (options.LM2015) { + if (options.CrossFlow) { su2double VelocityNormalized[3]; VelocityNormalized[0] = vel_u / Velocity_Mag; VelocityNormalized[1] = vel_v / Velocity_Mag; @@ -298,7 +298,7 @@ class CSourcePieceWise_TransLM final : public CNumerics { /*-- destruction term of ReThetaT --*/ // It should not be with the minus sign but I put for consistency su2double DRethetat = 0.0; - if (options.LM2015) + if (options.CrossFlow) DRethetat = -c_theta * (Density_i / time_scale) * c_CF * min(ReThetat_SCF - TransVar_i[1], 0.0) * f_theta_2; /*--- Source ---*/ @@ -313,7 +313,7 @@ class CSourcePieceWise_TransLM final : public CNumerics { Jacobian_i[0][1] = 0.0; Jacobian_i[1][0] = 0.0; Jacobian_i[1][1] = -c_theta / time_scale * (1.0 - f_theta) * Volume; - if (options.LM2015 && ReThetat_SCF - TransVar_i[1] < 0) + if (options.CrossFlow && ReThetat_SCF - TransVar_i[1] < 0) Jacobian_i[1][1] += (c_theta / time_scale) * c_CF * f_theta_2 * Volume; } @@ -453,9 +453,12 @@ class CSourcePieceWise_TransSLM final : public CNumerics { su2double du_ds = vel_u / Velocity_Mag * dU_dx + vel_v / Velocity_Mag * dU_dy; if (nDim == 3) du_ds += vel_w / Velocity_Mag * dU_dz; + const su2double lambda_theta = 7.57e-3 * du_ds * dist_i * dist_i * Density_i / Laminar_Viscosity_i + 0.0128; + // const su2double lambda_theta = 7.57e-3 * AuxVar * dist_i * dist_i * Density_i / Laminar_Viscosity_i + 0.0128; + /*--- Corr_RetC correlation*/ - //Re_t = TransCorrelations.ReThetaC_Correlations_SLM(Tu_L, du_ds, dist_i, Laminar_Viscosity_i, Density_i, VorticityMag, Velocity_Mag); - Re_t = TransCorrelations.ReThetaC_Correlations_SLM(Tu_L, AuxVar, dist_i, Laminar_Viscosity_i, Density_i, VorticityMag, Velocity_Mag); + Re_t = TransCorrelations.ReThetaC_Correlations_SLM(Tu_L, lambda_theta, dist_i, VorticityMag, Velocity_Mag); + // Re_t = TransCorrelations.ReThetaC_Correlations_SLM(Tu_L, lambda_theta, dist_i, VorticityMag, Velocity_Mag); if (options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::CODER_SLM || options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MOD_EPPLER_SLM) { // If these correlations are used, then the value of Corr_Rec has to be used instead of the TransVar[1] of the original LM model @@ -477,7 +480,57 @@ class CSourcePieceWise_TransSLM final : public CNumerics { F_onset2 = min(max(F_onset1, pow(F_onset1, 4.0)), 4.0); F_onset3 = max(2.0 - pow(R_t / 2.5, 3.0), 0.0); } - const su2double F_onset = max(F_onset2 - F_onset3, 0.0); + su2double F_onset = max(F_onset2 - F_onset3, 0.0); + + if (options.CrossFlow) { + + // Computation of shape factor + const su2double k = 0.25 - lambda_theta; + const su2double FirstTerm = 4.14 * k; + const su2double SecondTerm = 83.5 * pow(k, 2.0); + const su2double ThirdTerm = 854 * pow(k, 3.0); + const su2double ForthTerm = 3337 * pow(k, 4.0); + const su2double FifthTerm = 4576 * pow(k, 5.0); + const su2double H = min(2.0 + FirstTerm - SecondTerm + ThirdTerm - ForthTerm + FifthTerm, 2.7); + + // Computation of critical cross flow Reynolds number + su2double Re_Crit_CF = 0.0; + if(H < 2.3) { + Re_Crit_CF = 150.0; + } else { + Re_Crit_CF = -(300.0/PI_NUMBER) * atan(0.106/(pow(H-2.3, 2.05))); + } + + // Helicity computation + su2double VelocityNormalized[3]; + VelocityNormalized[0] = vel_u / Velocity_Mag; + VelocityNormalized[1] = vel_v / Velocity_Mag; + if (nDim == 3) VelocityNormalized[2] = vel_w / Velocity_Mag; + + su2double StreamwiseVort = 0.0; + for (auto iDim = 0u; iDim < nDim; iDim++) { + StreamwiseVort += VelocityNormalized[iDim] * Vorticity_i[iDim]; + } + StreamwiseVort = abs(StreamwiseVort); + + const su2double H_CF = StreamwiseVort * dist_i / Velocity_Mag; + + // Computation of Delta_H_CF. Here I have included directly R_t as the ration between turb and lam viscosity + const su2double Delta_H_CF = H_CF * (1.0 + min(R_t, 0.4)); + + // Take into account for roughness + const su2double h_0 = 0.25e-6; + const su2double C_r = 2.0 - pow(0.5, config->GethRoughness()/h_0); + + // Construct Cross flow activation function + const su2double C_CF = 1.0; + const su2double f_CF = (C_CF * C_r * Delta_H_CF * Corr_Rec) / Re_Crit_CF; + const su2double F_onset_CF = min(max(0.0, f_CF - 1.0), 1.0); + + // Adjust onset function for intermittency + F_onset = max(F_onset, F_onset_CF); + + } const su2double f_turb = exp(-pow(R_t / 4, 4)); diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index 00236d8e588..1c0d1e8f39a 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -2295,7 +2295,7 @@ void CFlowOutput::WriteForcesBreakdown(const CConfig* config, const CSolver* flo case TURB_TRANS_MODEL::NONE: break; case TURB_TRANS_MODEL::LM: file << "Langtry and Menter's transition"; - if (config->GetLMParsedOptions().LM2015) { + if (config->GetLMParsedOptions().CrossFlow) { file << " w/ cross-flow corrections (2015)\n"; } else { file << " (2009)\n"; diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index 8e06e296154..505cac4f713 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -205,61 +205,61 @@ void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contain // UPDATE: Mi sa che la wall distance ĆØ rispetto alla parete, quindi effettivamente l'elemento piĆ¹ vicino ĆØ sempre a parete. ///////////////////// - cout << "Sono qui" << endl; + // cout << "Sono qui" << endl; //if (rank == MASTER_NODE) { - if (options.SLM) { - /*--- Reconstructon of auxiliary variables gradient ---*/ - su2double Normal[nPoint][nDim]; - SU2_OMP_FOR_STAT(omp_chunk_size) - for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { - for (auto iDim = 0u; iDim < nDim; iDim++) - Normal[iPoint][iDim] = 0.0; - - // Extract nearest wall element and wall marker - unsigned long NearestWallElement = geometry->nodes->GetClosestWall_Elem(iPoint); - unsigned short NearestWallMarker = geometry->nodes->GetClosestWall_Marker(iPoint); - - // Cycle on all of the points of the wall element - for (unsigned short iNode = 0; iNode < geometry->bound[NearestWallMarker][NearestWallElement]->GetnNodes(); iNode++) { - // Extract global coordinate of the node - unsigned long iPointHere = geometry->bound[NearestWallMarker][NearestWallElement]->GetNode(iNode); - long iVertexHere = geometry->nodes->GetVertex(iPointHere, NearestWallMarker); - for (auto iDim = 0u; iDim < nDim; iDim++) - Normal[iPoint][iDim] += geometry->vertex[NearestWallMarker][iVertexHere]->GetNormal(iDim); - } - for (auto iDim = 0u; iDim < nDim; iDim++) - Normal[iPoint][iDim] /= geometry->bound[NearestWallMarker][NearestWallElement]->GetnNodes(); - - nodes->SetAuxVar(iPoint, 0, nodes->GetProjVel(iPoint, Normal[iPoint])); - } - END_SU2_OMP_FOR - - //SU2_OMP_BARRIER - - cout << "primo for" << endl; - - if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { - SetAuxVar_Gradient_GG(geometry, config); - } - if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { - SetAuxVar_Gradient_LS(geometry, config); - } - - //SU2_OMP_BARRIER - - cout << "Dopo Gradienti" << endl; - - SU2_OMP_FOR_STAT(omp_chunk_size) - for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { - su2double AuxVarHere = 0.0; - for (auto iDim = 0u; iDim < nDim; iDim++) - AuxVarHere += Normal[iPoint][iDim] * nodes->GetAuxVarGradient(iPoint, 0, iDim); - nodes->SetAuxVar(iPoint, 0, AuxVarHere); - } - END_SU2_OMP_FOR - - cout << "Ho finito" << endl; - } + // if (options.SLM) { + // /*--- Reconstructon of auxiliary variables gradient ---*/ + // su2double Normal[nPoint][nDim]; + // SU2_OMP_FOR_STAT(omp_chunk_size) + // for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { + // for (auto iDim = 0u; iDim < nDim; iDim++) + // Normal[iPoint][iDim] = 0.0; + + // // Extract nearest wall element and wall marker + // unsigned long NearestWallElement = geometry->nodes->GetClosestWall_Elem(iPoint); + // unsigned short NearestWallMarker = geometry->nodes->GetClosestWall_Marker(iPoint); + + // // Cycle on all of the points of the wall element + // for (unsigned short iNode = 0; iNode < geometry->bound[NearestWallMarker][NearestWallElement]->GetnNodes(); iNode++) { + // // Extract global coordinate of the node + // unsigned long iPointHere = geometry->bound[NearestWallMarker][NearestWallElement]->GetNode(iNode); + // long iVertexHere = geometry->nodes->GetVertex(iPointHere, NearestWallMarker); + // for (auto iDim = 0u; iDim < nDim; iDim++) + // Normal[iPoint][iDim] += geometry->vertex[NearestWallMarker][iVertexHere]->GetNormal(iDim); + // } + // for (auto iDim = 0u; iDim < nDim; iDim++) + // Normal[iPoint][iDim] /= geometry->bound[NearestWallMarker][NearestWallElement]->GetnNodes(); + + // nodes->SetAuxVar(iPoint, 0, nodes->GetProjVel(iPoint, Normal[iPoint])); + // } + // END_SU2_OMP_FOR + + // //SU2_OMP_BARRIER + + // cout << "primo for" << endl; + + // if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { + // SetAuxVar_Gradient_GG(geometry, config); + // } + // if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + // SetAuxVar_Gradient_LS(geometry, config); + // } + + // //SU2_OMP_BARRIER + + // cout << "Dopo Gradienti" << endl; + + // SU2_OMP_FOR_STAT(omp_chunk_size) + // for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { + // su2double AuxVarHere = 0.0; + // for (auto iDim = 0u; iDim < nDim; iDim++) + // AuxVarHere += Normal[iPoint][iDim] * nodes->GetAuxVarGradient(iPoint, 0, iDim); + // nodes->SetAuxVar(iPoint, 0, AuxVarHere); + // } + // END_SU2_OMP_FOR + + // cout << "Ho finito" << endl; + // } } @@ -426,8 +426,8 @@ void CTransLMSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta /*--- Set coordinate (for debugging) ---*/ numerics->SetCoord(geometry->nodes->GetCoord(iPoint), nullptr); - if (options.LM2015) { - /*--- Set local grid length (for LM2015)*/ + if (options.CrossFlow && !options.SLM) { + /*--- Set local grid length (for LM2015 cross-flow corrections)*/ numerics->SetLocalGridLength(geometry->nodes->GetMaxLength(iPoint)); } diff --git a/config_template.cfg b/config_template.cfg index a7d0c468d8e..8c468371198 100644 --- a/config_template.cfg +++ b/config_template.cfg @@ -29,7 +29,7 @@ SA_OPTIONS= NONE % % Transition model (NONE, LM) KIND_TRANS_MODEL= NONE -% Specify versions/correlations of the LM model (LM2015, MALAN, SULUKSNA, KRAUSE, KRAUSE_HYPER, MEDIDA, MEDIDA_BAEDER, MENTER_LANGTRY) +% Specify versions/correlations of the LM model (CROSSFLOW, MALAN, SULUKSNA, KRAUSE, KRAUSE_HYPER, MEDIDA, MEDIDA_BAEDER, MENTER_LANGTRY) LM_OPTIONS= NONE % % Specify subgrid scale model(NONE, IMPLICIT_LES, SMAGORINSKY, WALE, VREMAN) From 04cd56dc1fb6f3d7958b505948c000a31e1b977e Mon Sep 17 00:00:00 2001 From: rois1995 Date: Thu, 2 Feb 2023 15:28:05 +0100 Subject: [PATCH 06/20] - Fixed Intermittency_Sep computation for SLM. --- Common/include/geometry/dual_grid/CPoint.hpp | 4 +- .../include/variables/CTransLMVariable.hpp | 12 ----- SU2_CFD/src/solvers/CTransLMSolver.cpp | 47 ++++++++++--------- SU2_CFD/src/variables/CTransLMVariable.cpp | 43 +++++++---------- 4 files changed, 45 insertions(+), 61 deletions(-) diff --git a/Common/include/geometry/dual_grid/CPoint.hpp b/Common/include/geometry/dual_grid/CPoint.hpp index 82489486acd..6fee192b852 100644 --- a/Common/include/geometry/dual_grid/CPoint.hpp +++ b/Common/include/geometry/dual_grid/CPoint.hpp @@ -459,12 +459,14 @@ class CPoint { /*! * \brief Get the index of the closest wall element. * \param[in] iPoint - Index of the point. - */ + * \param[out] ClosestWall_Elem - ID of the closest element on a wall boundary. + */ inline unsigned long GetClosestWall_Elem(unsigned long iPoint) {return ClosestWall_Elem(iPoint);} /*! * \brief Get the marker of the closest wall marker. * \param[in] iPoint - Index of the point. + * \param[out] ClosestWall_Marker - MarkerID of the closest wall boundary. */ inline unsigned long GetClosestWall_Marker(unsigned long iPoint) {return ClosestWall_Marker(iPoint);} diff --git a/SU2_CFD/include/variables/CTransLMVariable.hpp b/SU2_CFD/include/variables/CTransLMVariable.hpp index 6c18eb03b59..fc6a2f65448 100644 --- a/SU2_CFD/include/variables/CTransLMVariable.hpp +++ b/SU2_CFD/include/variables/CTransLMVariable.hpp @@ -57,18 +57,6 @@ class CTransLMVariable final : public CTurbVariable { */ CTransLMVariable(su2double Intermittency, su2double ReThetaT, su2double gammaSep, su2double gammaEff, unsigned long npoint, unsigned long ndim, unsigned long nvar, CConfig *config); - /*! - * \brief Constructor of the class. - * \param[in] Intermittency - intermittency(gamma) (initialization value). - * \param[in] gammaSep - separation intermittency(gamma) (initialization value). - * \param[in] gammaEff - effective intermittency(gamma) (initialization value). - * \param[in] npoint - Number of points/nodes/vertices in the domain. - * \param[in] ndim - Number of dimensions of the problem. - * \param[in] nvar - Number of variables of the problem. - * \param[in] config - Definition of the particular problem. - */ - CTransLMVariable(su2double Intermittency, su2double gammaSep, su2double gammaEff, unsigned long npoint, unsigned long ndim, unsigned long nvar, CConfig *config); - /*! * \brief Destructor of the class. */ diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index 505cac4f713..14fa20c37b3 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -119,33 +119,27 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh const su2double Intermittency_Inf = 1.0; Solution_Inf[0] = Intermittency_Inf; - su2double ReThetaT_Inf = 0.0; + su2double ReThetaT_Inf = 100.0; - if (!options.SLM) { - - ReThetaT_Inf = 100.0; - - /*--- Momentum thickness Reynolds number, initialized from freestream turbulent intensity*/ - if (Intensity <= 1.3) { - if(Intensity >=0.027) { - ReThetaT_Inf = (1173.51-589.428*Intensity+0.2196/(Intensity*Intensity)); - } - else { - ReThetaT_Inf = (1173.51-589.428*Intensity+0.2196/(0.27*0.27)); - } + /*--- Momentum thickness Reynolds number, initialized from freestream turbulent intensity*/ + if (Intensity <= 1.3) { + if(Intensity >=0.027) { + ReThetaT_Inf = (1173.51-589.428*Intensity+0.2196/(Intensity*Intensity)); } - else if(Intensity>1.3) { - ReThetaT_Inf = 331.5*pow(Intensity-0.5658,-0.671); + else { + ReThetaT_Inf = (1173.51-589.428*Intensity+0.2196/(0.27*0.27)); } + } + else if(Intensity>1.3) { + ReThetaT_Inf = 331.5*pow(Intensity-0.5658,-0.671); + } + if (!options.SLM) { Solution_Inf[1] = ReThetaT_Inf; } /*--- Initialize the solution to the far-field state everywhere. ---*/ - nodes = new CTransLMVariable(Intermittency_Inf, 1.0, 1.0, nPoint, nDim, nVar, config); - if (!options.SLM) { - nodes = new CTransLMVariable(Intermittency_Inf, ReThetaT_Inf, 1.0, 1.0, nPoint, nDim, nVar, config); - } + nodes = new CTransLMVariable(Intermittency_Inf, ReThetaT_Inf, 1.0, 1.0, nPoint, nDim, nVar, config); SetBaseClassPointerToNodes(); @@ -299,15 +293,15 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai const su2double VelocityMag = sqrt(vel_u*vel_u + vel_v*vel_v + vel_w*vel_w); su2double omega = 0.0; su2double k = 0.0; + if(TurbFamily == TURB_FAMILY::KW){ + omega = turbNodes->GetSolution(iPoint,1); + k = turbNodes->GetSolution(iPoint,0); + } su2double Corr_Rec = 0.0; su2double Re_t = 0.0; if (!options.SLM) { Re_t = nodes->GetSolution(iPoint,1); - if(TurbFamily == TURB_FAMILY::KW){ - omega = turbNodes->GetSolution(iPoint,1); - k = turbNodes->GetSolution(iPoint,0); - } su2double Tu = 1.0; if(TurbFamily == TURB_FAMILY::KW) Tu = max(100.0*sqrt( 2.0 * k / 3.0 ) / VelocityMag,0.027); @@ -322,6 +316,9 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai Corr_Rec = nodes->GetCorr_Rec(iPoint); } + // cout << Re_t << " " << Corr_Rec << endl; + // if (geometry->nodes->GetDomain(iPoint)) cout << "Point is on boundary" << endl; + su2double R_t = 1.0; if(TurbFamily == TURB_FAMILY::KW) R_t = rho*k/ mu/ omega; @@ -329,6 +326,7 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai R_t = muT/ mu; const su2double f_reattach = exp(-pow(R_t/20,4)); + su2double f_wake = 0.0; if(TurbFamily == TURB_FAMILY::KW){ const su2double re_omega = rho*omega*dist*dist/mu; @@ -337,6 +335,8 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai if(TurbFamily == TURB_FAMILY::SA) f_wake = 1.0; + //cout << "StrainMag = " << StrainMag << " rho = " << rho << " dist = " << dist << " Re_v = " << Re_v << " Corr_Rec = " << Corr_Rec << endl; + const su2double theta_bl = Re_t*mu / rho /VelocityMag; const su2double delta_bl = 7.5*theta_bl; const su2double delta = 50.0*VorticityMag*dist/VelocityMag*delta_bl + 1e-20; @@ -344,6 +344,7 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai const su2double var2 = 1.0 - pow(var1,2.0); const su2double f_theta = min(max(f_wake*exp(-pow(dist/delta, 4)), var2), 1.0); su2double Intermittency_Sep = 2.0*max(0.0, Re_v/(3.235*Corr_Rec)-1.0)*f_reattach; + //if (Intermittency_Sep>1.0) cout << "StrainMag = " << StrainMag << " rho = " << rho << " dist = " << dist << " Re_v = " << Re_v << " Corr_Rec = " << Corr_Rec << " Intermittency: " << Intermittency_Sep << " f_reattach = " << f_reattach << endl; Intermittency_Sep = min(Intermittency_Sep,2.0)*f_theta; Intermittency_Sep = min(max(0.0, Intermittency_Sep), 2.0); nodes -> SetIntermittencySep(iPoint, Intermittency_Sep); diff --git a/SU2_CFD/src/variables/CTransLMVariable.cpp b/SU2_CFD/src/variables/CTransLMVariable.cpp index 1e7d09f75da..29fdd45d2ad 100644 --- a/SU2_CFD/src/variables/CTransLMVariable.cpp +++ b/SU2_CFD/src/variables/CTransLMVariable.cpp @@ -33,10 +33,17 @@ CTransLMVariable::CTransLMVariable(su2double Intermittency, su2double ReThetaT, LM_ParsedOptions options = config->GetLMParsedOptions(); - for(unsigned long iPoint=0; iPointGetLMParsedOptions(); - - for(unsigned long iPoint=0; iPoint Date: Fri, 24 Feb 2023 14:10:07 +0100 Subject: [PATCH 07/20] - Added computation for normals of grid points - Added variables only for debug --- Common/include/geometry/dual_grid/CPoint.hpp | 7 + Common/include/option_structure.hpp | 3 +- SU2_CFD/include/numerics/CNumerics.hpp | 20 +- .../transition/trans_correlations.hpp | 14 +- .../turbulent/transition/trans_sources.hpp | 119 +++++- .../numerics/turbulent/turb_sources.hpp | 2 +- SU2_CFD/include/solvers/CTransLMSolver.hpp | 1 + .../include/variables/CTransLMVariable.hpp | 35 ++ .../include/variables/CTurbSSTVariable.hpp | 1 + SU2_CFD/include/variables/CVariable.hpp | 22 ++ SU2_CFD/src/output/CFlowOutput.cpp | 52 ++- SU2_CFD/src/solvers/CTransLMSolver.cpp | 345 +++++++++++------- SU2_CFD/src/variables/CIncNSVariable.cpp | 1 - SU2_CFD/src/variables/CTransLMVariable.cpp | 51 ++- SU2_CFD/src/variables/CTurbSSTVariable.cpp | 1 + 15 files changed, 507 insertions(+), 167 deletions(-) diff --git a/Common/include/geometry/dual_grid/CPoint.hpp b/Common/include/geometry/dual_grid/CPoint.hpp index 6fee192b852..795ee519a2e 100644 --- a/Common/include/geometry/dual_grid/CPoint.hpp +++ b/Common/include/geometry/dual_grid/CPoint.hpp @@ -470,6 +470,13 @@ class CPoint { */ inline unsigned long GetClosestWall_Marker(unsigned long iPoint) {return ClosestWall_Marker(iPoint);} + /*! + * \brief Get the rank of the closest wall marker. + * \param[in] iPoint - Index of the point. + * \param[out] ClosestWall_Rank - RankID of the closest wall boundary. + */ + inline unsigned long GetClosestWall_Rank(unsigned long iPoint) {return ClosestWall_Rank(iPoint);} + /*! * \brief Get the value of the distance to the nearest wall. * \param[in] iPoint - Index of the point. diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index f927d5b30d0..29940f0e21b 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -1262,7 +1262,6 @@ inline LM_ParsedOptions ParseLMOptions(const LM_OPTIONS *LM_Options, unsigned sh LMParsedOptions.ProdLim = IsPresent(LM_OPTIONS::PRODLIM); int NFoundCorrelations = 0; - int NFoundCorrelations_SLM = 0; if (IsPresent(LM_OPTIONS::MALAN)) { LMParsedOptions.Correlation = TURB_TRANS_CORRELATION::MALAN; NFoundCorrelations++; @@ -1291,6 +1290,8 @@ inline LM_ParsedOptions ParseLMOptions(const LM_OPTIONS *LM_Options, unsigned sh LMParsedOptions.Correlation = TURB_TRANS_CORRELATION::MENTER_LANGTRY; NFoundCorrelations++; } + + int NFoundCorrelations_SLM = 0; if (IsPresent(LM_OPTIONS::MENTER_SLM)) { LMParsedOptions.Correlation_SLM = TURB_TRANS_CORRELATION_SLM::MENTER_SLM; NFoundCorrelations_SLM++; diff --git a/SU2_CFD/include/numerics/CNumerics.hpp b/SU2_CFD/include/numerics/CNumerics.hpp index 4b4c9c6224f..837223daa59 100644 --- a/SU2_CFD/include/numerics/CNumerics.hpp +++ b/SU2_CFD/include/numerics/CNumerics.hpp @@ -736,15 +736,31 @@ class CNumerics { /*! * \brief Get the value of the Transition Momentum Thickness Reynolds number from correlations. - * \param[in] Corr_Rec_i - Value of the Transition Momentum Thickness Reynolds number at point i. + * \param[out] Corr_Rec_i - Value of the Transition Momentum Thickness Reynolds number at point i. */ inline virtual su2double GetCorr_Rec() {return 0.0;} /*! * \brief Get the value of the Momentum Thickness Reynolds number. - * \param[in] Corr_Rec_i - Value of the Momentum Thickness Reynolds number at point i. + * \param[out] re_t - Value of the Momentum Thickness Reynolds number at point i. */ inline virtual su2double GetRe_t() {return 0.0;} + inline virtual su2double GetTu() {return 0.0;} + inline virtual su2double GetLambda_theta() {return 0.0;} + inline virtual su2double Getduds() {return 0.0;} + inline virtual su2double GetRe_v() {return 0.0;} + inline virtual su2double GetProd() {return 0.0;} + inline virtual su2double GetDestr() {return 0.0;} + inline virtual su2double GetF_onset1() {return 0.0;} + inline virtual su2double GetF_onset2() {return 0.0;} + inline virtual su2double GetF_onset3() {return 0.0;} + inline virtual su2double GetF_onset() {return 0.0;} + + /*! + * \brief Set the value of the F2 blending function into SLM transition model. + * \param[in] val_F2 - F2 blending function. + */ + inline virtual void SetF2(su2double val_F2) {} /*! * \brief Set the gradient of the auxiliary variables. diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp index ecd569984ed..acfe282beec 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp @@ -205,9 +205,7 @@ class TransLMCorrelations { case TURB_TRANS_CORRELATION_SLM::MENTER_SLM: { /*-- Thwaites parameter ---*/ - // su2double lambda_theta_local = 7.57e-3 * du_ds * wall_dist * wall_dist * Density / Laminar_Viscosity + 0.0128; su2double lambda_theta_local = lambda_theta; - lambda_theta_local = min(max(lambda_theta_local, -1.0), 1.0); /*-- Function to sensitize the transition onset to the streamwise pressure gradient ---*/ su2double FPG = 0.0; @@ -266,10 +264,14 @@ class TransLMCorrelations { // This is not reported in the paper //FPG = max(FPG, 0.0); - const su2double C_TU1 = 100.0; - const su2double C_TU2 = 1000.0; - const su2double C_TU3 = 1.0; - rethetac = C_TU1 + C_TU2 * exp(-C_TU3 * Tu_L * FPG); + if (Tu_L <= 1.3) { + const su2double FirstTerm = -589.428 * Tu_L; + const su2double SecondTerm = 0.2196 / max(pow(Tu_L, 2.0), 1e-12); + rethetac = 1173.51 + FirstTerm + SecondTerm; + } else { + rethetac = 331.50 * pow(Tu_L-0.5658, -0.671); + } + rethetac = rethetac * FPG; break; } case TURB_TRANS_CORRELATION_SLM::MOD_EPPLER_SLM: { diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp index 1bdc5c959cc..14daac3d81a 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp @@ -56,6 +56,17 @@ class CSourcePieceWise_TransLM final : public CNumerics { TURB_FAMILY TurbFamily; su2double hRoughness; + su2double Re_v_Here; + su2double Corr_Rec_Here; + su2double Prod_Here = 0.0; + su2double Destr_Here = 0.0; + su2double F_onset1_Here = 0.0; + su2double F_onset2_Here = 0.0; + su2double F_onset3_Here = 0.0; + su2double F_onset_Here = 0.0; + su2double lambda_theta_Here = 0.0; + su2double duds_Here = 0.0; + su2double IntermittencySep = 1.0; su2double IntermittencyEff = 1.0; @@ -135,6 +146,8 @@ class CSourcePieceWise_TransLM final : public CNumerics { /*--- Corr_RetC correlation*/ const su2double Corr_Rec = TransCorrelations.ReThetaC_Correlations(Tu, TransVar_i[1]); + // AGGIUNTO PER DEBUG + Corr_Rec_Here = Corr_Rec; /*--- F_length correlation*/ const su2double Corr_F_length = TransCorrelations.FLength_Correlations(Tu, TransVar_i[1]); @@ -154,6 +167,11 @@ class CSourcePieceWise_TransLM final : public CNumerics { if (TurbFamily == TURB_FAMILY::SA) R_t = Eddy_Viscosity_i / Laminar_Viscosity_i; const su2double Re_v = Density_i * dist_i * dist_i * StrainMag_i / Laminar_Viscosity_i; + + // AGGIUNTO PER DEBUG + Re_v_Here = Re_v; + + const su2double F_onset1 = Re_v / (2.193 * Corr_Rec); su2double F_onset2 = 1.0; su2double F_onset3 = 1.0; @@ -166,6 +184,10 @@ class CSourcePieceWise_TransLM final : public CNumerics { F_onset3 = max(2.0 - pow(R_t / 2.5, 3.0), 0.0); } const su2double F_onset = max(F_onset2 - F_onset3, 0.0); + F_onset1_Here = F_onset1; + F_onset2_Here = F_onset2; + F_onset3_Here = F_onset3; + F_onset_Here = F_onset; /*-- Gradient of velocity magnitude ---*/ @@ -245,6 +267,9 @@ class CSourcePieceWise_TransLM final : public CNumerics { Retheta_old = Corr_Ret; } + lambda_theta_Here = lambda; + duds_Here = du_ds; + /*-- Corr_RetT_SCF Correlations--*/ su2double ReThetat_SCF = 0.0; if (options.CrossFlow) { @@ -292,6 +317,9 @@ class CSourcePieceWise_TransLM final : public CNumerics { /*-- destruction term of Intermeittency(Gamma) --*/ const su2double Dg = c_a2 * Density_i * VorticityMag * TransVar_i[0] * f_turb * (c_e2 * TransVar_i[0] - 1.0); + Prod_Here = Pg; + Destr_Here = Dg; + /*-- production term of ReThetaT --*/ const su2double PRethetat = c_theta * Density_i / time_scale * (Corr_Ret - TransVar_i[1]) * (1.0 - f_theta); @@ -322,6 +350,19 @@ class CSourcePieceWise_TransLM final : public CNumerics { return ResidualType<>(Residual, Jacobian_i, nullptr); } + + + inline su2double GetRe_v() override {return Re_v_Here;} + inline su2double GetCorr_Rec() override {return Corr_Rec_Here;} + inline su2double GetProd() override {return Prod_Here;} + inline su2double GetDestr() override {return Destr_Here;} + inline su2double GetF_onset1() override {return F_onset1_Here;} + inline su2double GetF_onset2() override {return F_onset2_Here;} + inline su2double GetF_onset3() override {return F_onset3_Here;} + inline su2double GetF_onset() override {return F_onset_Here;} + inline su2double GetLambda_theta() override {return lambda_theta_Here;} + inline su2double Getduds() override {return duds_Here;} + }; @@ -358,6 +399,17 @@ class CSourcePieceWise_TransSLM final : public CNumerics { su2double Re_t; su2double Corr_Rec; su2double AuxVar; + su2double F2; + su2double Tu_Here = 0.0; + su2double duds_Here = 0.0; + su2double lambda_theta_Here = 0.0; + su2double Re_v_Here = 0.0; + su2double Prod_Here = 0.0; + su2double Destr_Here = 0.0; + su2double F_onset1_Here = 0.0; + su2double F_onset2_Here = 0.0; + su2double F_onset3_Here = 0.0; + su2double F_onset_Here = 0.0; su2double Residual; su2double* Jacobian_i; @@ -412,7 +464,13 @@ class CSourcePieceWise_TransSLM final : public CNumerics { const su2double vel_v = V_i[1 + idx.Velocity()]; const su2double vel_w = (nDim == 3) ? V_i[2 + idx.Velocity()] : 0.0; - const su2double Velocity_Mag = sqrt(vel_u * vel_u + vel_v * vel_v + vel_w * vel_w); + su2double Velocity[nDim]; + Velocity[0] = vel_u; + Velocity[1] = vel_v; + if(nDim == 3) Velocity[2] = vel_w; + + + const su2double Velocity_Mag = max(sqrt(vel_u * vel_u + vel_v * vel_v + vel_w * vel_w), 1e-20); AD::SetPreaccIn(V_i[idx.Density()], V_i[idx.LaminarViscosity()], V_i[idx.EddyViscosity()]); @@ -425,50 +483,51 @@ class CSourcePieceWise_TransSLM final : public CNumerics { if (dist_i > 1e-10) { su2double Tu_L = 1.0; - if (TurbFamily == TURB_FAMILY::KW) Tu_L = max(min(100.0 * sqrt(2.0 * ScalarVar_i[0] / 3.0) / (ScalarVar_i[1]*dist_i), 100.0), 0.027); + if (TurbFamily == TURB_FAMILY::KW) Tu_L = min(100.0 * sqrt(2.0 * ScalarVar_i[0] / 3.0) / (ScalarVar_i[1]*dist_i), 100.0); + // if (TurbFamily == TURB_FAMILY::KW) Tu_L = min(100.0 * sqrt(2.0 * ScalarVar_i[0] / 3.0) / (Velocity_Mag), 100.0); if (TurbFamily == TURB_FAMILY::SA) Tu_L = config->GetTurbulenceIntensity_FreeStream() * 100; + Tu_Here = Tu_L; + /*--- F_length ---*/ su2double F_length = 100.0; /*--- F_onset ---*/ su2double R_t = 1.0; - if (TurbFamily == TURB_FAMILY::KW) R_t = Density_i * ScalarVar_i[0] / Laminar_Viscosity_i / ScalarVar_i[1]; + if (TurbFamily == TURB_FAMILY::KW) R_t = Density_i * ScalarVar_i[0] / (Laminar_Viscosity_i * ScalarVar_i[1]); if (TurbFamily == TURB_FAMILY::SA) R_t = Eddy_Viscosity_i / Laminar_Viscosity_i; /*-- Gradient of velocity magnitude ---*/ - su2double dU_dx = 0.5 / Velocity_Mag * (2. * vel_u * PrimVar_Grad_i[1][0] + 2. * vel_v * PrimVar_Grad_i[2][0]); - if (nDim == 3) dU_dx += 0.5 / Velocity_Mag * (2. * vel_w * PrimVar_Grad_i[3][0]); - - su2double dU_dy = 0.5 / Velocity_Mag * (2. * vel_u * PrimVar_Grad_i[1][1] + 2. * vel_v * PrimVar_Grad_i[2][1]); - if (nDim == 3) dU_dy += 0.5 / Velocity_Mag * (2. * vel_w * PrimVar_Grad_i[3][1]); - - su2double dU_dz = 0.0; - if (nDim == 3) - dU_dz = - 0.5 / Velocity_Mag * - (2. * vel_u * PrimVar_Grad_i[1][2] + 2. * vel_v * PrimVar_Grad_i[2][2] + 2. * vel_w * PrimVar_Grad_i[3][2]); + // su2double du_ds = 0.0; + // for (int i = 0; i < nDim; i++) + // for (int j = 0; j < nDim; j++) + // du_ds = du_ds + Velocity[i]*Velocity[j]*PrimVar_Grad_i[i][j]; - su2double du_ds = vel_u / Velocity_Mag * dU_dx + vel_v / Velocity_Mag * dU_dy; - if (nDim == 3) du_ds += vel_w / Velocity_Mag * dU_dz; + // du_ds = du_ds/(Velocity_Mag*Velocity_Mag); - const su2double lambda_theta = 7.57e-3 * du_ds * dist_i * dist_i * Density_i / Laminar_Viscosity_i + 0.0128; + // const su2double lambda_theta = -7.57e-3 * du_ds * dist_i * dist_i * Density_i / Laminar_Viscosity_i + 0.0128; + const su2double lambda_theta = max(min(-7.57e-3 * AuxVar * dist_i * dist_i * Density_i / Laminar_Viscosity_i + 0.0128, 1.0), -1.0); + // const su2double lambda_theta = du_ds * dist_i * dist_i * Density_i / Laminar_Viscosity_i; + // duds_Here = du_ds; + duds_Here = AuxVar; + lambda_theta_Here = lambda_theta; + // const su2double lambda_theta = 7.57e-3 * AuxVar * dist_i * dist_i * Density_i / Laminar_Viscosity_i + 0.0128; /*--- Corr_RetC correlation*/ Re_t = TransCorrelations.ReThetaC_Correlations_SLM(Tu_L, lambda_theta, dist_i, VorticityMag, Velocity_Mag); - // Re_t = TransCorrelations.ReThetaC_Correlations_SLM(Tu_L, lambda_theta, dist_i, VorticityMag, Velocity_Mag); + Corr_Rec = Re_t; // If the MENTER_SLM correlation is used then they are the same thing if (options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::CODER_SLM || options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MOD_EPPLER_SLM) { // If these correlations are used, then the value of Corr_Rec has to be used instead of the TransVar[1] of the original LM model F_length = TransCorrelations.FLength_Correlations(Tu_L, Re_t); Corr_Rec = TransCorrelations.ReThetaC_Correlations(Tu_L, Re_t); } - if (options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM) Corr_Rec = Re_t; const su2double Re_v = Density_i * dist_i * dist_i * StrainMag_i / Laminar_Viscosity_i; + Re_v_Here = Re_v; const su2double F_onset1 = Re_v / (2.2 * Corr_Rec); su2double F_onset2 = 1.0; su2double F_onset3 = 1.0; @@ -482,6 +541,11 @@ class CSourcePieceWise_TransSLM final : public CNumerics { } su2double F_onset = max(F_onset2 - F_onset3, 0.0); + F_onset1_Here = F_onset1; + F_onset2_Here = F_onset2; + F_onset3_Here = F_onset3; + F_onset_Here = F_onset; + if (options.CrossFlow) { // Computation of shape factor @@ -532,7 +596,7 @@ class CSourcePieceWise_TransSLM final : public CNumerics { } - const su2double f_turb = exp(-pow(R_t / 4, 4)); + const su2double f_turb = exp(-pow(R_t / 2, 4)); /*-- production term of Intermeittency(Gamma) --*/ const su2double Pg = @@ -540,6 +604,9 @@ class CSourcePieceWise_TransSLM final : public CNumerics { /*-- destruction term of Intermeittency(Gamma) --*/ const su2double Dg = c_a2 * Density_i * VorticityMag * TransVar_i[0] * f_turb * (c_e2 * TransVar_i[0] - 1.0); + + Prod_Here = Pg; + Destr_Here = Dg; /*--- Source ---*/ Residual += (Pg - Dg) * Volume; @@ -560,6 +627,18 @@ class CSourcePieceWise_TransSLM final : public CNumerics { inline su2double GetRe_t() override {return Re_t;} inline su2double GetCorr_Rec() override {return Corr_Rec;} + inline su2double GetTu() override {return Tu_Here;} + inline su2double GetLambda_theta() override {return lambda_theta_Here;} + inline su2double Getduds() override {return duds_Here;} + inline su2double GetRe_v() override {return Re_v_Here;} + inline su2double GetProd() override {return Prod_Here;} + inline su2double GetDestr() override {return Destr_Here;} + inline su2double GetF_onset1() override {return F_onset1_Here;} + inline su2double GetF_onset2() override {return F_onset2_Here;} + inline su2double GetF_onset3() override {return F_onset3_Here;} + inline su2double GetF_onset() override {return F_onset_Here;} inline void SetAuxVar(su2double val_AuxVar) override { AuxVar = val_AuxVar;} + // non serve piĆ¹ + inline void SetF2(su2double val_F2) override { F2 = val_F2;} }; diff --git a/SU2_CFD/include/numerics/turbulent/turb_sources.hpp b/SU2_CFD/include/numerics/turbulent/turb_sources.hpp index 810245a2b43..8283018dd6a 100644 --- a/SU2_CFD/include/numerics/turbulent/turb_sources.hpp +++ b/SU2_CFD/include/numerics/turbulent/turb_sources.hpp @@ -832,7 +832,7 @@ class CSourcePieceWise_TurbSST final : public CNumerics { if (config->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM) { pk = pk * eff_intermittency; // Check if the Prod_lim_k has to be introduced based on input options - if ((config->GetLMParsedOptions()).ProdLim) { + if ((config->GetLMParsedOptions()).SLM) { const su2double Re_theta_c_lim = 1100.0; const su2double C_k = 1.0; const su2double C_SEP = 1.0; diff --git a/SU2_CFD/include/solvers/CTransLMSolver.hpp b/SU2_CFD/include/solvers/CTransLMSolver.hpp index acdf90fb9a4..176e7b602e4 100644 --- a/SU2_CFD/include/solvers/CTransLMSolver.hpp +++ b/SU2_CFD/include/solvers/CTransLMSolver.hpp @@ -42,6 +42,7 @@ class CTransLMSolver final : public CTurbSolver { LM_ParsedOptions options; TURB_FAMILY TurbFamily; + bool isSepNeeded; TransLMCorrelations TransCorrelations; diff --git a/SU2_CFD/include/variables/CTransLMVariable.hpp b/SU2_CFD/include/variables/CTransLMVariable.hpp index fc6a2f65448..8478b84d550 100644 --- a/SU2_CFD/include/variables/CTransLMVariable.hpp +++ b/SU2_CFD/include/variables/CTransLMVariable.hpp @@ -42,6 +42,19 @@ class CTransLMVariable final : public CTurbVariable { VectorType Intermittency_Sep; VectorType Corr_Rec; VectorType Re_t; + VectorType Tu; + VectorType Lambda_theta; + VectorType duds; + VectorType Re_v; + VectorType Prod; + VectorType Destr; + VectorType F_onset1; + VectorType F_onset2; + VectorType F_onset3; + VectorType F_onset; + + VectorType normal_x; + VectorType normal_y; public: /*! @@ -81,6 +94,17 @@ class CTransLMVariable final : public CTurbVariable { * \brief Set Value of Momentum Thickness Reynolds number from correlations (substitute to the second equation of original LM model). */ void SetRe_t(unsigned long iPoint, su2double val_Re_t) override; + void SetTu(unsigned long iPoint, su2double val_Tu) override; + void SetLambda_theta(unsigned long iPoint, su2double val_Lambda_theta) override; + void Setduds(unsigned long iPoint, su2double val_duds) override; + void SetRe_v(unsigned long iPoint, su2double val_Re_v) override; + void SetProd(unsigned long iPoint, su2double val_Prod) override; + void SetDestr(unsigned long iPoint, su2double val_Destr) override; + void SetF_onset1(unsigned long iPoint, su2double val_F_onset1) override; + void SetF_onset2(unsigned long iPoint, su2double val_F_onset2) override; + void SetF_onset3(unsigned long iPoint, su2double val_F_onset3) override; + void SetF_onset(unsigned long iPoint, su2double val_F_onset) override; + void SetNormal(unsigned long iPoint, su2double val_normal_x, su2double val_normal_y) override; /*! * \brief Calculate effective intermittency. @@ -101,4 +125,15 @@ class CTransLMVariable final : public CTurbVariable { * \brief Get Value of Momentum Thickness Reynolds number from correlations (substitute to the second equation of original LM model). */ inline su2double GetRe_t(unsigned long iPoint) const override { return Re_t(iPoint); } + inline su2double GetTu(unsigned long iPoint) const override { return Tu(iPoint); } + inline su2double GetLambda_theta(unsigned long iPoint) const override { return Lambda_theta(iPoint); } + inline su2double Getduds(unsigned long iPoint) const override { return duds(iPoint); } + inline su2double GetRe_v(unsigned long iPoint) const override { return Re_v(iPoint); } + inline su2double GetProd(unsigned long iPoint) const override { return Prod(iPoint); } + inline su2double GetDestr(unsigned long iPoint) const override { return Destr(iPoint); } + inline su2double GetF_onset1(unsigned long iPoint) const override { return F_onset1(iPoint); } + inline su2double GetF_onset2(unsigned long iPoint) const override { return F_onset2(iPoint); } + inline su2double GetF_onset3(unsigned long iPoint) const override { return F_onset3(iPoint); } + inline su2double GetF_onset(unsigned long iPoint) const override { return F_onset(iPoint); } + inline pair GetNormal(unsigned long iPoint) const override {return make_pair(normal_x(iPoint), normal_y(iPoint));}; }; diff --git a/SU2_CFD/include/variables/CTurbSSTVariable.hpp b/SU2_CFD/include/variables/CTurbSSTVariable.hpp index e8a5d4559aa..159a110eb9b 100644 --- a/SU2_CFD/include/variables/CTurbSSTVariable.hpp +++ b/SU2_CFD/include/variables/CTurbSSTVariable.hpp @@ -45,6 +45,7 @@ class CTurbSSTVariable final : public CTurbVariable { VectorType F2; /*!< \brief Menter blending function for blending of k-w and k-eps. */ VectorType CDkw; /*!< \brief Cross-diffusion. */ SST_ParsedOptions sstParsedOptions; + LM_ParsedOptions lmParsedOptions; public: /*! * \brief Constructor of the class. diff --git a/SU2_CFD/include/variables/CVariable.hpp b/SU2_CFD/include/variables/CVariable.hpp index 099988e1a2b..9fb1cac0556 100644 --- a/SU2_CFD/include/variables/CVariable.hpp +++ b/SU2_CFD/include/variables/CVariable.hpp @@ -1717,11 +1717,33 @@ class CVariable { * \brief Set Value of Transition Momentum Thickness Reynolds number from correlations. */ inline virtual void SetCorr_Rec(unsigned long iPoint, su2double val_Corr_Rec) {}; + inline virtual void SetTu(unsigned long iPoint, su2double val_Tu) {}; + inline virtual void SetLambda_theta(unsigned long iPoint, su2double val_Lambda_theta) {}; + inline virtual void Setduds(unsigned long iPoint, su2double val_duds) {}; + inline virtual void SetRe_v(unsigned long iPoint, su2double val_Re_v) {}; + inline virtual void SetProd(unsigned long iPoint, su2double val_Prod) {}; + inline virtual void SetDestr(unsigned long iPoint, su2double val_Destr) {}; + inline virtual void SetF_onset1(unsigned long iPoint, su2double val_F_onset1) {}; + inline virtual void SetF_onset2(unsigned long iPoint, su2double val_F_onset2) {}; + inline virtual void SetF_onset3(unsigned long iPoint, su2double val_F_onset3) {}; + inline virtual void SetF_onset(unsigned long iPoint, su2double val_F_onset1) {}; + inline virtual void SetNormal(unsigned long iPoint, su2double val_normal_x, su2double val_normal_y) {}; /*! * \brief Get Value of Transition Momentum Thickness Reynolds number from correlations. */ inline virtual su2double GetCorr_Rec(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetTu(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetLambda_theta(unsigned long iPoint) const { return 0.0; } + inline virtual su2double Getduds(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetRe_v(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetProd(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetDestr(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetF_onset1(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetF_onset2(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetF_onset3(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetF_onset(unsigned long iPoint) const { return 0.0; } + inline virtual pair GetNormal(unsigned long iPoint) const { return make_pair(0.0, 0.0); } /*! * \brief Set Value of Momentum Thickness Reynolds number from correlations (substitute to the second equation of original LM model). diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index 1c0d1e8f39a..0ba43a94a98 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -1069,11 +1069,31 @@ void CFlowOutput::SetVolumeOutputFields_ScalarSolution(const CConfig* config){ case TURB_TRANS_MODEL::LM: AddVolumeOutput("INTERMITTENCY", "LM_gamma", "SOLUTION", "LM intermittency"); AddVolumeOutput("RE_THETA_T", "LM_Re_t", "SOLUTION", "LM RE_THETA_T"); + AddVolumeOutput("RE_V", "Re_v", "DEBUG", "LM Re_v"); + AddVolumeOutput("RE_THETA_CORR", "LM_Corr_Rec", "DEBUG", "LM RE_THETA_CORR"); + AddVolumeOutput("PROD", "LM_Prod", "DEBUG", "LM PROD"); + AddVolumeOutput("DESTR", "LM_Destr", "DEBUG", "LM DESTR"); + AddVolumeOutput("F_ONSET1", "LM_F_onset1", "DEBUG", "LM F_ONSET1"); + AddVolumeOutput("F_ONSET2", "LM_F_onset2", "DEBUG", "LM F_ONSET2"); + AddVolumeOutput("F_ONSET3", "LM_F_onset3", "DEBUG", "LM F_ONSET3"); + AddVolumeOutput("F_ONSET", "LM_F_onset", "DEBUG", "LM F_ONSET"); + AddVolumeOutput("STRAINMAG", "StrainMag", "DEBUG", "LM STRAINMAG"); + AddVolumeOutput("LAMBDA_THETA", "Lambda_theta", "DEBUG", "LM Lambda_theta"); + AddVolumeOutput("DU_DS", "du_ds", "DEBUG", "LM du_ds"); if ((config->GetLMParsedOptions()).SLM) { - AddVolumeOutput("RE_THETA_CORR", "LM_Corr_Rec", "SOLUTION", "LM RE_THETA_CORR"); + AddVolumeOutput("TU", "Tu", "SOLUTION", "LM Tu"); + AddVolumeOutput("NORMAL_X", "Normal_x", "DEBUG", "LM Normal_x"); + AddVolumeOutput("NORMAL_Y", "Normal_y", "DEBUG", "LM Normal_y"); + AddVolumeOutput("NORMAL_Z", "Normal_z", "DEBUG", "LM Normal_z"); + if (TurbModelFamily(config->GetKind_Turb_Model()) == TURB_FAMILY::SA) { + AddVolumeOutput("INTERMITTENCY_SEP", "LM_gamma_sep", "PRIMITIVE", "LM intermittency"); + AddVolumeOutput("INTERMITTENCY_EFF", "LM_gamma_eff", "PRIMITIVE", "LM RE_THETA_T"); + } + } + if (!(config->GetLMParsedOptions()).SLM) { + AddVolumeOutput("INTERMITTENCY_SEP", "LM_gamma_sep", "PRIMITIVE", "LM intermittency"); + AddVolumeOutput("INTERMITTENCY_EFF", "LM_gamma_eff", "PRIMITIVE", "LM RE_THETA_T"); } - AddVolumeOutput("INTERMITTENCY_SEP", "LM_gamma_sep", "PRIMITIVE", "LM intermittency"); - AddVolumeOutput("INTERMITTENCY_EFF", "LM_gamma_eff", "PRIMITIVE", "LM RE_THETA_T"); AddVolumeOutput("TURB_INDEX", "Turb_index", "PRIMITIVE", "Turbulence index"); break; @@ -1227,14 +1247,34 @@ void CFlowOutput::LoadVolumeData_Scalar(const CConfig* config, const CSolver* co switch (config->GetKind_Trans_Model()) { case TURB_TRANS_MODEL::LM: SetVolumeOutputValue("INTERMITTENCY", iPoint, Node_Trans->GetSolution(iPoint, 0)); + SetVolumeOutputValue("RE_V", iPoint, Node_Trans->GetRe_v(iPoint)); + SetVolumeOutputValue("RE_THETA_CORR", iPoint, Node_Trans->GetCorr_Rec(iPoint)); + SetVolumeOutputValue("PROD", iPoint, Node_Trans->GetProd(iPoint)); + SetVolumeOutputValue("DESTR", iPoint, Node_Trans->GetDestr(iPoint)); + SetVolumeOutputValue("F_ONSET1", iPoint, Node_Trans->GetF_onset1(iPoint)); + SetVolumeOutputValue("F_ONSET2", iPoint, Node_Trans->GetF_onset2(iPoint)); + SetVolumeOutputValue("F_ONSET3", iPoint, Node_Trans->GetF_onset3(iPoint)); + SetVolumeOutputValue("F_ONSET", iPoint, Node_Trans->GetF_onset(iPoint)); + SetVolumeOutputValue("STRAINMAG", iPoint, Node_Flow->GetStrainMag(iPoint)); + SetVolumeOutputValue("LAMBDA_THETA", iPoint, Node_Trans->GetLambda_theta(iPoint)); + SetVolumeOutputValue("DU_DS", iPoint, Node_Trans->Getduds(iPoint)); if (!(config->GetLMParsedOptions()).SLM) { SetVolumeOutputValue("RE_THETA_T", iPoint, Node_Trans->GetSolution(iPoint, 1)); } else { SetVolumeOutputValue("RE_THETA_T", iPoint, Node_Trans->GetRe_t(iPoint)); - SetVolumeOutputValue("RE_THETA_CORR", iPoint, Node_Trans->GetCorr_Rec(iPoint)); + SetVolumeOutputValue("TU", iPoint, Node_Trans->GetTu(iPoint)); + SetVolumeOutputValue("NORMAL_X", iPoint, (Node_Trans->GetNormal(iPoint)).first); + SetVolumeOutputValue("NORMAL_Y", iPoint, (Node_Trans->GetNormal(iPoint)).second); + SetVolumeOutputValue("NORMAL_Z", iPoint, 0.0); + if (TurbModelFamily(config->GetKind_Turb_Model()) == TURB_FAMILY::SA) { + SetVolumeOutputValue("INTERMITTENCY_SEP", iPoint, Node_Trans->GetIntermittencySep(iPoint)); + SetVolumeOutputValue("INTERMITTENCY_EFF", iPoint, Node_Trans->GetIntermittencyEff(iPoint)); + } + } + if (!(config->GetLMParsedOptions()).SLM) { + SetVolumeOutputValue("INTERMITTENCY_SEP", iPoint, Node_Trans->GetIntermittencySep(iPoint)); + SetVolumeOutputValue("INTERMITTENCY_EFF", iPoint, Node_Trans->GetIntermittencyEff(iPoint)); } - SetVolumeOutputValue("INTERMITTENCY_SEP", iPoint, Node_Trans->GetIntermittencySep(iPoint)); - SetVolumeOutputValue("INTERMITTENCY_EFF", iPoint, Node_Trans->GetIntermittencyEff(iPoint)); SetVolumeOutputValue("TURB_INDEX", iPoint, Node_Turb->GetTurbIndex(iPoint)); SetVolumeOutputValue("RES_INTERMITTENCY", iPoint, trans_solver->LinSysRes(iPoint, 0)); if (!(config->GetLMParsedOptions()).SLM) { diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index 14fa20c37b3..bc44dca07f9 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -71,6 +71,11 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh /*--- Define variables needed for transition from config file ---*/ TransCorrelations.SetOptions(options); TurbFamily = TurbModelFamily(config->GetKind_Turb_Model()); + isSepNeeded = true; + // If the Simplified model is used coupled with SST then we do not need the separation induced intermittency + // due to the added production term to k equation + if (options.SLM && TurbFamily == TURB_FAMILY::KW) isSepNeeded = false; + /*--- Single grid simulation ---*/ @@ -200,60 +205,115 @@ void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contain ///////////////////// // cout << "Sono qui" << endl; - //if (rank == MASTER_NODE) { - // if (options.SLM) { - // /*--- Reconstructon of auxiliary variables gradient ---*/ - // su2double Normal[nPoint][nDim]; - // SU2_OMP_FOR_STAT(omp_chunk_size) - // for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { - // for (auto iDim = 0u; iDim < nDim; iDim++) - // Normal[iPoint][iDim] = 0.0; - - // // Extract nearest wall element and wall marker - // unsigned long NearestWallElement = geometry->nodes->GetClosestWall_Elem(iPoint); - // unsigned short NearestWallMarker = geometry->nodes->GetClosestWall_Marker(iPoint); - - // // Cycle on all of the points of the wall element - // for (unsigned short iNode = 0; iNode < geometry->bound[NearestWallMarker][NearestWallElement]->GetnNodes(); iNode++) { - // // Extract global coordinate of the node - // unsigned long iPointHere = geometry->bound[NearestWallMarker][NearestWallElement]->GetNode(iNode); - // long iVertexHere = geometry->nodes->GetVertex(iPointHere, NearestWallMarker); - // for (auto iDim = 0u; iDim < nDim; iDim++) - // Normal[iPoint][iDim] += geometry->vertex[NearestWallMarker][iVertexHere]->GetNormal(iDim); - // } - // for (auto iDim = 0u; iDim < nDim; iDim++) - // Normal[iPoint][iDim] /= geometry->bound[NearestWallMarker][NearestWallElement]->GetnNodes(); - - // nodes->SetAuxVar(iPoint, 0, nodes->GetProjVel(iPoint, Normal[iPoint])); - // } - // END_SU2_OMP_FOR - - // //SU2_OMP_BARRIER - - // cout << "primo for" << endl; - - // if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { - // SetAuxVar_Gradient_GG(geometry, config); - // } - // if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { - // SetAuxVar_Gradient_LS(geometry, config); - // } - - // //SU2_OMP_BARRIER - - // cout << "Dopo Gradienti" << endl; - - // SU2_OMP_FOR_STAT(omp_chunk_size) - // for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { - // su2double AuxVarHere = 0.0; - // for (auto iDim = 0u; iDim < nDim; iDim++) - // AuxVarHere += Normal[iPoint][iDim] * nodes->GetAuxVarGradient(iPoint, 0, iDim); - // nodes->SetAuxVar(iPoint, 0, AuxVarHere); - // } - // END_SU2_OMP_FOR - - // cout << "Ho finito" << endl; - // } + if (options.SLM && options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM) { + /*--- Reconstructon of auxiliary variables gradient ---*/ + + // Each rank collects all normals + + vector>> WallNormal; + WallNormal.resize(config->GetnMarker_All()); + for (auto iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++){ + if (config->GetViscous_Wall(iMarker)) { + WallNormal[iMarker].resize(geometry->GetnElem_Bound(iMarker)); + + // cout << "geometry->nVertex[iMarker] = " << geometry->nVertex[iMarker] << endl; + for (auto iElem = 0u; iElem < geometry->GetnElem_Bound(iMarker); iElem++) { + vector NormalHere(nDim, 0.0); + + for (unsigned short iNode = 0; iNode < geometry->bound[iMarker][iElem]->GetnNodes(); iNode++) { + // Extract global coordinate of the node + unsigned long iPointHere = geometry->bound[iMarker][iElem]->GetNode(iNode); + long iVertexHere = geometry->nodes->GetVertex(iPointHere, iMarker); + for (auto iDim = 0u; iDim < nDim; iDim++) + NormalHere[iDim] += geometry->vertex[iMarker][iElem]->GetNormal(iDim); + //cout << "NormalHere(x, y, z) = " << NormalHere[0] << ", " << NormalHere[1] << ", " << NormalHere[2] << endl; + } + + for (auto iDim = 0u; iDim < nDim; iDim++) + NormalHere[iDim] /= geometry->bound[iMarker][iElem]->GetnNodes(); + su2double NormalMag = 0.0; + for (auto iDim = 0u; iDim < nDim; iDim++) + NormalMag += NormalHere[iDim]*NormalHere[iDim]; + NormalMag = sqrt(NormalMag); + + for (auto iDim = 0u; iDim < nDim; iDim++) + NormalHere[iDim] /= NormalMag; + + // cout << "FianlNormalHere(x, y, z) = " << NormalHere[0] << ", " << NormalHere[1] << ", " << NormalHere[2] << endl << endl; + + WallNormal[iMarker][iElem] = NormalHere; + } + } else { + WallNormal[iMarker].resize(1); + WallNormal[iMarker][0].resize(3); + WallNormal[iMarker][0][0] = 0.0; + WallNormal[iMarker][0][1] = 0.0; + WallNormal[iMarker][0][2] = 0.0; + } + } + + auto normal_i = + make_pair( config->GetnMarker_All(), [config,geometry,WallNormal](unsigned long iMarker){ + auto nElem_Bou = geometry->GetnElem_Bound(iMarker); + if (!config->GetViscous_Wall(iMarker)) nElem_Bou = 1; + + return make_pair(nElem_Bou, [WallNormal,iMarker](unsigned long iElem){ + const auto dimensions = 3; + + return make_pair(dimensions, [WallNormal,iMarker,iElem](unsigned short iDim){ + // cout << "iMarker = " << iMarker << " iElem = " << iElem << " iDim = " << iDim << endl; + return WallNormal[iMarker][iElem][iDim]; + }); + }); + }); + + NdFlattener<3>Normals_Local(normal_i); + NdFlattener<4> Normals_global(Nd_MPI_Environment(), Normals_Local); + su2double** NormalPerPoint = new su2double* [nPoint]; + + auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); + SU2_OMP_FOR_STAT(omp_chunk_size) + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { + + // Extract nearest wall element and wall marker + int NearestWallRank = geometry->nodes->GetClosestWall_Rank(iPoint); + unsigned long NearestWallElement = geometry->nodes->GetClosestWall_Elem(iPoint); + unsigned short NearestWallMarker = geometry->nodes->GetClosestWall_Marker(iPoint); + + NormalPerPoint[iPoint] = new su2double [MAXNDIM]; + for(auto iDim = 0; iDim < nDim; iDim++) + NormalPerPoint[iPoint][iDim] = Normals_global[NearestWallRank][NearestWallMarker][NearestWallMarker][iDim]; + + nodes->SetAuxVar(iPoint, 0, flowNodes->GetProjVel(iPoint, NormalPerPoint[iPoint])); + nodes->SetNormal(iPoint, NormalPerPoint[iPoint][0], NormalPerPoint[iPoint][1]); + } + END_SU2_OMP_FOR + + + // cout << "primo for" << endl; + + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { + SetAuxVar_Gradient_GG(geometry, config); + } + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + SetAuxVar_Gradient_LS(geometry, config); + } + + //SU2_OMP_BARRIER + + // cout << "Dopo Gradienti" << endl; + + SU2_OMP_FOR_STAT(omp_chunk_size) + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { + su2double AuxVarHere = 0.0; + for (auto iDim = 0u; iDim < nDim; iDim++) + AuxVarHere += NormalPerPoint[iPoint][iDim] * nodes->GetAuxVarGradient(iPoint, 0, iDim); + nodes->SetAuxVar(iPoint, 0, AuxVarHere); + } + END_SU2_OMP_FOR + + // cout << "Ho finito" << endl; + } } @@ -269,89 +329,104 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai } AD::StartNoSharedReading(); - auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); - auto* turbNodes = su2staticcast_p(solver_container[TURB_SOL]->GetNodes()); - - SU2_OMP_FOR_STAT(omp_chunk_size) - for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { - - // Here the nodes already have the new solution, thus I have to compute everything from scratch - - const su2double rho = flowNodes->GetDensity(iPoint); - const su2double mu = flowNodes->GetLaminarViscosity(iPoint); - const su2double muT = turbNodes->GetmuT(iPoint); - const su2double dist = geometry->nodes->GetWall_Distance(iPoint); - su2double VorticityMag = GeometryToolbox::Norm(3, flowNodes->GetVorticity(iPoint)); - su2double StrainMag =flowNodes->GetStrainMag(iPoint); - VorticityMag = max(VorticityMag, 1e-12); - StrainMag = max(StrainMag, 1e-12); // safety against division by zero - const su2double Intermittency = nodes->GetSolution(iPoint,0); - const su2double Re_v = rho*dist*dist*StrainMag/mu; - const su2double vel_u = flowNodes->GetVelocity(iPoint, 0); - const su2double vel_v = flowNodes->GetVelocity(iPoint, 1); - const su2double vel_w = (nDim ==3) ? flowNodes->GetVelocity(iPoint, 2) : 0.0; - const su2double VelocityMag = sqrt(vel_u*vel_u + vel_v*vel_v + vel_w*vel_w); - su2double omega = 0.0; - su2double k = 0.0; - if(TurbFamily == TURB_FAMILY::KW){ - omega = turbNodes->GetSolution(iPoint,1); - k = turbNodes->GetSolution(iPoint,0); - } - su2double Corr_Rec = 0.0; - su2double Re_t = 0.0; - if (!options.SLM) { - Re_t = nodes->GetSolution(iPoint,1); - su2double Tu = 1.0; - if(TurbFamily == TURB_FAMILY::KW) - Tu = max(100.0*sqrt( 2.0 * k / 3.0 ) / VelocityMag,0.027); - if(TurbFamily == TURB_FAMILY::SA) - Tu = config->GetTurbulenceIntensity_FreeStream()*100; + if(isSepNeeded){ + + AD::StartNoSharedReading(); + auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); + auto* turbNodes = su2staticcast_p(solver_container[TURB_SOL]->GetNodes()); + + SU2_OMP_FOR_STAT(omp_chunk_size) + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { + + // Here the nodes already have the new solution, thus I have to compute everything from scratch + + const su2double rho = flowNodes->GetDensity(iPoint); + const su2double mu = flowNodes->GetLaminarViscosity(iPoint); + const su2double muT = turbNodes->GetmuT(iPoint); + const su2double dist = geometry->nodes->GetWall_Distance(iPoint); + su2double VorticityMag = GeometryToolbox::Norm(3, flowNodes->GetVorticity(iPoint)); + su2double StrainMag =flowNodes->GetStrainMag(iPoint); + VorticityMag = max(VorticityMag, 1e-12); + StrainMag = max(StrainMag, 1e-12); // safety against division by zero + const su2double Intermittency = nodes->GetSolution(iPoint,0); + const su2double Re_v = rho*dist*dist*StrainMag/mu; + const su2double vel_u = flowNodes->GetVelocity(iPoint, 0); + const su2double vel_v = flowNodes->GetVelocity(iPoint, 1); + const su2double vel_w = (nDim ==3) ? flowNodes->GetVelocity(iPoint, 2) : 0.0; + const su2double VelocityMag = sqrt(vel_u*vel_u + vel_v*vel_v + vel_w*vel_w); + su2double omega = 0.0; + su2double k = 0.0; + if(TurbFamily == TURB_FAMILY::KW){ + omega = turbNodes->GetSolution(iPoint,1); + k = turbNodes->GetSolution(iPoint,0); + } - Corr_Rec = TransCorrelations.ReThetaC_Correlations(Tu, Re_t); - } + su2double Re_t = 0.0; + su2double Corr_Rec = 0.0; + + if (options.SLM && TurbFamily == TURB_FAMILY::SA) { + Re_t = nodes->GetRe_t(iPoint); + Corr_Rec = nodes->GetCorr_Rec(iPoint); + } else { + Re_t = nodes->GetSolution(iPoint,1); + su2double Tu = 1.0; + if(TurbFamily == TURB_FAMILY::KW) + Tu = max(100.0*sqrt( 2.0 * k / 3.0 ) / VelocityMag,0.027); + if(TurbFamily == TURB_FAMILY::SA) + Tu = config->GetTurbulenceIntensity_FreeStream()*100; + + Corr_Rec = TransCorrelations.ReThetaC_Correlations(Tu, Re_t); + } - if (options.SLM) { - Re_t = nodes->GetRe_t(iPoint); - Corr_Rec = nodes->GetCorr_Rec(iPoint); - } - // cout << Re_t << " " << Corr_Rec << endl; - // if (geometry->nodes->GetDomain(iPoint)) cout << "Point is on boundary" << endl; + // cout << Re_t << " " << Corr_Rec << endl; + // if (geometry->nodes->GetDomain(iPoint)) cout << "Point is on boundary" << endl; - su2double R_t = 1.0; - if(TurbFamily == TURB_FAMILY::KW) - R_t = rho*k/ mu/ omega; - if(TurbFamily == TURB_FAMILY::SA) - R_t = muT/ mu; + su2double R_t = 1.0; + if(TurbFamily == TURB_FAMILY::KW) + R_t = rho*k/ mu/ omega; + if(TurbFamily == TURB_FAMILY::SA) + R_t = muT/ mu; + + const su2double f_reattach = exp(-pow(R_t/20,4)); - const su2double f_reattach = exp(-pow(R_t/20,4)); + su2double f_wake = 0.0; + if(TurbFamily == TURB_FAMILY::KW){ + const su2double re_omega = rho*omega*dist*dist/mu; + f_wake = exp(-pow(re_omega/(1.0e+05),2)); + } + if(TurbFamily == TURB_FAMILY::SA) + f_wake = 1.0; + + //cout << "StrainMag = " << StrainMag << " rho = " << rho << " dist = " << dist << " Re_v = " << Re_v << " Corr_Rec = " << Corr_Rec << endl; + + const su2double theta_bl = Re_t*mu / rho /VelocityMag; + const su2double delta_bl = 7.5*theta_bl; + const su2double delta = 50.0*VorticityMag*dist/VelocityMag*delta_bl + 1e-20; + const su2double var1 = (Intermittency-1.0/50.0)/(1.0-1.0/50.0); + const su2double var2 = 1.0 - pow(var1,2.0); + const su2double f_theta = min(max(f_wake*exp(-pow(dist/delta, 4)), var2), 1.0); + su2double Intermittency_Sep = 2.0*max(0.0, Re_v/(3.235*Corr_Rec)-1.0)*f_reattach; + //if (Intermittency_Sep>1.0) cout << "StrainMag = " << StrainMag << " rho = " << rho << " dist = " << dist << " Re_v = " << Re_v << " Corr_Rec = " << Corr_Rec << " Intermittency: " << Intermittency_Sep << " f_reattach = " << f_reattach << endl; + Intermittency_Sep = min(Intermittency_Sep,2.0)*f_theta; + Intermittency_Sep = min(max(0.0, Intermittency_Sep), 2.0); + nodes -> SetIntermittencySep(iPoint, Intermittency_Sep); + nodes -> SetIntermittencyEff(iPoint, Intermittency_Sep); - su2double f_wake = 0.0; - if(TurbFamily == TURB_FAMILY::KW){ - const su2double re_omega = rho*omega*dist*dist/mu; - f_wake = exp(-pow(re_omega/(1.0e+05),2)); } - if(TurbFamily == TURB_FAMILY::SA) - f_wake = 1.0; - - //cout << "StrainMag = " << StrainMag << " rho = " << rho << " dist = " << dist << " Re_v = " << Re_v << " Corr_Rec = " << Corr_Rec << endl; - - const su2double theta_bl = Re_t*mu / rho /VelocityMag; - const su2double delta_bl = 7.5*theta_bl; - const su2double delta = 50.0*VorticityMag*dist/VelocityMag*delta_bl + 1e-20; - const su2double var1 = (Intermittency-1.0/50.0)/(1.0-1.0/50.0); - const su2double var2 = 1.0 - pow(var1,2.0); - const su2double f_theta = min(max(f_wake*exp(-pow(dist/delta, 4)), var2), 1.0); - su2double Intermittency_Sep = 2.0*max(0.0, Re_v/(3.235*Corr_Rec)-1.0)*f_reattach; - //if (Intermittency_Sep>1.0) cout << "StrainMag = " << StrainMag << " rho = " << rho << " dist = " << dist << " Re_v = " << Re_v << " Corr_Rec = " << Corr_Rec << " Intermittency: " << Intermittency_Sep << " f_reattach = " << f_reattach << endl; - Intermittency_Sep = min(Intermittency_Sep,2.0)*f_theta; - Intermittency_Sep = min(max(0.0, Intermittency_Sep), 2.0); - nodes -> SetIntermittencySep(iPoint, Intermittency_Sep); - nodes -> SetIntermittencyEff(iPoint, Intermittency_Sep); + END_SU2_OMP_FOR } - END_SU2_OMP_FOR + else { + + // Effective intermittency and separation intermittency are not taken into account here! There is the added production term in the k-equation + SU2_OMP_FOR_STAT(omp_chunk_size) + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { + nodes -> SetIntermittencyEff(iPoint, nodes->GetSolution(iPoint,0)); + } + END_SU2_OMP_FOR + } AD::EndNoSharedReading(); } @@ -433,7 +508,8 @@ void CTransLMSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta } if(options.SLM) { - numerics->SetAuxVar(nodes->GetAuxVar(iPoint, 0)); + if (options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM) numerics->SetAuxVar(nodes->GetAuxVar(iPoint, 0)); + numerics->SetF2(turbNodes->GetF2blending(iPoint)); } /*--- Compute the source term ---*/ @@ -442,9 +518,20 @@ void CTransLMSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta if(options.SLM) { nodes->SetRe_t(iPoint, numerics->GetRe_t()); - nodes->SetCorr_Rec(iPoint, numerics->GetCorr_Rec()); + nodes->SetTu(iPoint, numerics->GetTu()); } + nodes->SetRe_v(iPoint, numerics->GetRe_v()); + nodes->SetCorr_Rec(iPoint, numerics->GetCorr_Rec()); + nodes->SetProd(iPoint, numerics->GetProd()); + nodes->SetDestr(iPoint, numerics->GetDestr()); + nodes->SetF_onset1(iPoint, numerics->GetF_onset1()); + nodes->SetF_onset2(iPoint, numerics->GetF_onset2()); + nodes->SetF_onset3(iPoint, numerics->GetF_onset3()); + nodes->SetF_onset(iPoint, numerics->GetF_onset()); + nodes->SetLambda_theta(iPoint, numerics->GetLambda_theta()); + nodes->Setduds(iPoint, numerics->Getduds()); + /*--- Subtract residual and the Jacobian ---*/ LinSysRes.SubtractBlock(iPoint, residual); diff --git a/SU2_CFD/src/variables/CIncNSVariable.cpp b/SU2_CFD/src/variables/CIncNSVariable.cpp index a3458a9eb46..907ecba7293 100644 --- a/SU2_CFD/src/variables/CIncNSVariable.cpp +++ b/SU2_CFD/src/variables/CIncNSVariable.cpp @@ -100,7 +100,6 @@ bool CIncNSVariable::SetPrimVar(unsigned long iPoint, su2double eddy_visc, su2do SetVelocity(iPoint); /*--- Set laminar viscosity ---*/ - SetLaminarViscosity(iPoint, FluidModel->GetLaminarViscosity()); /*--- Set eddy viscosity locally and in the fluid model. ---*/ diff --git a/SU2_CFD/src/variables/CTransLMVariable.cpp b/SU2_CFD/src/variables/CTransLMVariable.cpp index 29fdd45d2ad..bcc72b3af70 100644 --- a/SU2_CFD/src/variables/CTransLMVariable.cpp +++ b/SU2_CFD/src/variables/CTransLMVariable.cpp @@ -53,13 +53,28 @@ CTransLMVariable::CTransLMVariable(su2double Intermittency, su2double ReThetaT, Intermittency_Sep.resize(nPoint) = gammaSep; if (options.SLM) { - Corr_Rec.resize(nPoint) = ReThetaT; Re_t.resize(nPoint) = ReThetaT; nAuxVar = 1; Grad_AuxVar.resize(nPoint, nAuxVar, nDim, 0.0); AuxVar.resize(nPoint, nAuxVar) = su2double(0.0); + Tu.resize(nPoint) = 0.0; + + normal_x.resize(nPoint) = 0.0; + normal_y.resize(nPoint) = 0.0; } + + + Re_v.resize(nPoint) = 0.0; + Corr_Rec.resize(nPoint) = 0.0; + Prod.resize(nPoint) = 0.0; + Destr.resize(nPoint) = 0.0; + F_onset1.resize(nPoint) = 0.0; + F_onset2.resize(nPoint) = 0.0; + F_onset3.resize(nPoint) = 0.0; + F_onset.resize(nPoint) = 0.0; + Lambda_theta.resize(nPoint) = 0.0; + duds.resize(nPoint) = 0.0; } @@ -81,4 +96,38 @@ void CTransLMVariable::SetCorr_Rec(unsigned long iPoint, su2double val_Corr_Rec) void CTransLMVariable::SetRe_t(unsigned long iPoint, su2double val_Re_t) { Re_t(iPoint) = val_Re_t; +} +void CTransLMVariable::SetTu(unsigned long iPoint, su2double val_Tu) { + Tu(iPoint) = val_Tu; +} +void CTransLMVariable::SetLambda_theta(unsigned long iPoint, su2double val_Lambda_theta) { + Lambda_theta(iPoint) = val_Lambda_theta; +} +void CTransLMVariable::Setduds(unsigned long iPoint, su2double val_duds) { + duds(iPoint) = val_duds; +} +void CTransLMVariable::SetRe_v(unsigned long iPoint, su2double val_Re_v) { + Re_v(iPoint) = val_Re_v; +} +void CTransLMVariable::SetProd(unsigned long iPoint, su2double val_Prod) { + Prod(iPoint) = val_Prod; +} +void CTransLMVariable::SetDestr(unsigned long iPoint, su2double val_Destr) { + Destr(iPoint) = val_Destr; +} +void CTransLMVariable::SetF_onset1(unsigned long iPoint, su2double val_F_onset1) { + F_onset1(iPoint) = val_F_onset1; +} +void CTransLMVariable::SetF_onset2(unsigned long iPoint, su2double val_F_onset2) { + F_onset2(iPoint) = val_F_onset2; +} +void CTransLMVariable::SetF_onset3(unsigned long iPoint, su2double val_F_onset3) { + F_onset3(iPoint) = val_F_onset3; +} +void CTransLMVariable::SetF_onset(unsigned long iPoint, su2double val_F_onset) { + F_onset(iPoint) = val_F_onset; +} +void CTransLMVariable::SetNormal(unsigned long iPoint, su2double val_normal_x, su2double val_normal_y) { + normal_x(iPoint) = val_normal_x; + normal_y(iPoint) = val_normal_y; } \ No newline at end of file diff --git a/SU2_CFD/src/variables/CTurbSSTVariable.cpp b/SU2_CFD/src/variables/CTurbSSTVariable.cpp index c4506529d10..c134d7ca2e2 100644 --- a/SU2_CFD/src/variables/CTurbSSTVariable.cpp +++ b/SU2_CFD/src/variables/CTurbSSTVariable.cpp @@ -33,6 +33,7 @@ CTurbSSTVariable::CTurbSSTVariable(su2double kine, su2double omega, su2double mu : CTurbVariable(npoint, ndim, nvar, config) { sstParsedOptions = config->GetSSTParsedOptions(); + lmParsedOptions = config->GetLMParsedOptions(); for(unsigned long iPoint=0; iPoint Date: Fri, 24 Feb 2023 14:52:37 +0100 Subject: [PATCH 08/20] Fixed normal extraction from structure --- SU2_CFD/src/solvers/CTransLMSolver.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index bc44dca07f9..add591209ff 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -226,11 +226,11 @@ void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contain long iVertexHere = geometry->nodes->GetVertex(iPointHere, iMarker); for (auto iDim = 0u; iDim < nDim; iDim++) NormalHere[iDim] += geometry->vertex[iMarker][iElem]->GetNormal(iDim); - //cout << "NormalHere(x, y, z) = " << NormalHere[0] << ", " << NormalHere[1] << ", " << NormalHere[2] << endl; } for (auto iDim = 0u; iDim < nDim; iDim++) NormalHere[iDim] /= geometry->bound[iMarker][iElem]->GetnNodes(); + su2double NormalMag = 0.0; for (auto iDim = 0u; iDim < nDim; iDim++) NormalMag += NormalHere[iDim]*NormalHere[iDim]; @@ -239,6 +239,7 @@ void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contain for (auto iDim = 0u; iDim < nDim; iDim++) NormalHere[iDim] /= NormalMag; + // cout << "NormalHere(x, y, z) = " << NormalHere[0] << ", " << NormalHere[1] << ", " << NormalHere[2] << endl; // cout << "FianlNormalHere(x, y, z) = " << NormalHere[0] << ", " << NormalHere[1] << ", " << NormalHere[2] << endl << endl; WallNormal[iMarker][iElem] = NormalHere; @@ -262,6 +263,8 @@ void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contain return make_pair(dimensions, [WallNormal,iMarker,iElem](unsigned short iDim){ // cout << "iMarker = " << iMarker << " iElem = " << iElem << " iDim = " << iDim << endl; + // cout << "WallNormal(x, y, z) = " << WallNormal[iMarker][iElem][0] << ", " << WallNormal[iMarker][iElem][1] << ", " << WallNormal[iMarker][iElem][2] << endl; + return WallNormal[iMarker][iElem][iDim]; }); }); @@ -279,11 +282,13 @@ void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contain int NearestWallRank = geometry->nodes->GetClosestWall_Rank(iPoint); unsigned long NearestWallElement = geometry->nodes->GetClosestWall_Elem(iPoint); unsigned short NearestWallMarker = geometry->nodes->GetClosestWall_Marker(iPoint); + // cout << "NearestWallRank = " << NearestWallRank << " NearestWallElement = " << NearestWallElement << " NearestWallMarker = " << NearestWallMarker << endl; NormalPerPoint[iPoint] = new su2double [MAXNDIM]; for(auto iDim = 0; iDim < nDim; iDim++) - NormalPerPoint[iPoint][iDim] = Normals_global[NearestWallRank][NearestWallMarker][NearestWallMarker][iDim]; + NormalPerPoint[iPoint][iDim] = Normals_global[NearestWallRank][NearestWallMarker][NearestWallElement][iDim]; + // cout << "NormalHere(x, y, z) = " << NormalPerPoint[iPoint][0] << ", " << NormalPerPoint[iPoint][1] << ", " << NormalPerPoint[iPoint][2] << endl; nodes->SetAuxVar(iPoint, 0, flowNodes->GetProjVel(iPoint, NormalPerPoint[iPoint])); nodes->SetNormal(iPoint, NormalPerPoint[iPoint][0], NormalPerPoint[iPoint][1]); } From b1edf61fca342c17a93f4daca8701474f15de5e5 Mon Sep 17 00:00:00 2001 From: rois1995 Date: Fri, 24 Feb 2023 19:20:46 +0100 Subject: [PATCH 09/20] Added computation of wall normals to the CPoint structure --- Common/include/geometry/dual_grid/CPoint.hpp | 36 ++++ Common/src/geometry/CGeometry.cpp | 76 +++++++++ Common/src/geometry/dual_grid/CPoint.cpp | 2 + SU2_CFD/src/solvers/CTransLMSolver.cpp | 169 +++++++++---------- 4 files changed, 193 insertions(+), 90 deletions(-) diff --git a/Common/include/geometry/dual_grid/CPoint.hpp b/Common/include/geometry/dual_grid/CPoint.hpp index 795ee519a2e..efe3a81406c 100644 --- a/Common/include/geometry/dual_grid/CPoint.hpp +++ b/Common/include/geometry/dual_grid/CPoint.hpp @@ -102,6 +102,7 @@ class CPoint { su2activevector Curvature; /*!< \brief Value of the surface curvature (SU2_GEO). */ su2activevector MaxLength; /*!< \brief The maximum cell-center to cell-center length. */ su2activevector RoughnessHeight; /*!< \brief Roughness of the nearest wall. */ + su2activematrix Normals; /*!< \brief Normal of the nearest wall element. */ su2matrix AD_InputIndex; /*!< \brief Indices of Coord variables in the adjoint vector. */ su2matrix AD_OutputIndex; /*!< \brief Indices of Coord variables in the adjoint vector after having been updated. */ @@ -499,6 +500,24 @@ class CPoint { */ inline su2double GetRoughnessHeight(unsigned long iPoint) const { return RoughnessHeight(iPoint); } + /*! + * \brief Set the value of the normal of the nearest wall element. + * \param[in] iPoint - Index of the point. + * \param[in] normal - Value of the normal. + */ + template + inline void SetNormal(unsigned long iPoint, Normals_type const&normal) { + for (unsigned long iDim = 0; iDim < nDim; iDim++) + Normals(iPoint,iDim) = normal[iDim]; + } + + /*! + * \brief Set the value of the normal of the nearest wall element. + * \param[in] iPoint - Index of the point. + * \return normal to the normal of the nearest wall element. + */ + inline su2double *GetNormal(unsigned long iPoint) { return Normals[iPoint]; } + /*! * \brief Set the value of the distance to a sharp edge. * \param[in] iPoint - Index of the point. @@ -900,4 +919,21 @@ class CPoint { } } + + /*! + * \brief Set wall normal according to stored closest wall information. + * \param[in] normals - Mapping [rank][zone][marker][element] -> normal + */ + template + void SetWallNormals(Normals_type const&normals){ + for (unsigned long iPoint=0; iPoint= 0) + SetNormal(iPoint, normals[rankID][zoneID][markerID][elementID]); + } + } + }; diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index 87ed7214f60..c5436b8930d 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -4106,5 +4106,81 @@ void CGeometry::ComputeWallDistance(const CConfig* const* config_container, CGeo } } } + + + su2vector>> WallNormal_container; + WallNormal_container.resize(nZone) = su2vector>(); + for (int iZone = 0; iZone < nZone; iZone++){ + const CConfig* config = config_container[iZone]; + const CGeometry* geometry = geometry_container[iZone][iInst][MESH_0]; + WallNormal_container[iZone].resize(geometry->GetnMarker()); + for (auto iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++){ + if (config->GetViscous_Wall(iMarker)) { + WallNormal_container[iZone][iMarker].resize(geometry->GetnElem_Bound(iMarker), 3); + + // cout << "geometry->nVertex[iMarker] = " << geometry->nVertex[iMarker] << endl; + for (auto iElem = 0u; iElem < geometry->GetnElem_Bound(iMarker); iElem++) { + su2vector NormalHere; + NormalHere.resize(3) = su2double(0.0); + + for (unsigned short iNode = 0; iNode < geometry->bound[iMarker][iElem]->GetnNodes(); iNode++) { + // Extract global coordinate of the node + unsigned long iPointHere = geometry->bound[iMarker][iElem]->GetNode(iNode); + long iVertexHere = geometry->nodes->GetVertex(iPointHere, iMarker); + for (auto iDim = 0u; iDim < 3; iDim++) + NormalHere[iDim] += geometry->vertex[iMarker][iElem]->GetNormal(iDim); + } + + for (auto iDim = 0u; iDim < 3; iDim++) + NormalHere[iDim] /= geometry->bound[iMarker][iElem]->GetnNodes(); + + su2double NormalMag = 0.0; + for (auto iDim = 0u; iDim < 3; iDim++) + NormalMag += NormalHere[iDim]*NormalHere[iDim]; + NormalMag = sqrt(NormalMag); + + for (auto iDim = 0u; iDim < 3; iDim++) + NormalHere[iDim] /= NormalMag; + + for (auto iDim = 0u; iDim < 3; iDim++) + WallNormal_container[iZone][iMarker](iElem, iDim) = NormalHere[iDim]; + + } + } else { + WallNormal_container[iZone][iMarker].resize(1, 3) = su2double(0.0); + } + } + } + + auto normal_i = + make_pair(nZone, [config_container,geometry_container,iInst,WallNormal_container](unsigned long iZone){ + const CConfig* config = config_container[iZone]; + const CGeometry* geometry = geometry_container[iZone][iInst][MESH_0]; + const auto nMarker = geometry->GetnMarker(); + const auto WallNormal = WallNormal_container[iZone]; + + return make_pair( nMarker, [config,geometry,WallNormal](unsigned long iMarker){ + auto nElem_Bou = geometry->GetnElem_Bound(iMarker); + if (!config->GetViscous_Wall(iMarker)) nElem_Bou = 1; + + return make_pair(nElem_Bou, [WallNormal,iMarker](unsigned long iElem){ + const auto dimensions = 3; + + return make_pair(dimensions, [WallNormal,iMarker,iElem](unsigned short iDim){ + + return WallNormal[iMarker](iElem, iDim); + }); + }); + }); + }); + + NdFlattener<4>Normals_Local(normal_i); + NdFlattener<5> Normals_global(Nd_MPI_Environment(), Normals_Local); + + + // use it to update roughnesses + for(int jZone=0; jZonenodes->SetWallNormals(Normals_global); + } } } diff --git a/Common/src/geometry/dual_grid/CPoint.cpp b/Common/src/geometry/dual_grid/CPoint.cpp index 3d392128b31..752d4df0cd6 100644 --- a/Common/src/geometry/dual_grid/CPoint.cpp +++ b/Common/src/geometry/dual_grid/CPoint.cpp @@ -141,6 +141,8 @@ void CPoint::FullAllocation(unsigned short imesh, const CConfig *config) { RoughnessHeight.resize(npoint) = su2double(0.0); SharpEdge_Distance.resize(npoint) = su2double(0.0); + Normals.resize(npoint, 3) = su2double(0.0); + } void CPoint::SetElems(const vector >& elemsMatrix) { diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index add591209ff..a7eda1086c2 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -198,105 +198,97 @@ void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contain CommonPreprocessing(geometry, config, Output); - ///////////////////// - // ATTENZIONE! Forse devo farlo solamente per i punti che sono nello strato limite! Quindi magari nelle sources devo usare la function che mi definisce lo strato limite! - // Al di fuori di essa devo usare la solita du/ds? PerchĆØ altrimenti il contorno piĆ¹ vicino ad un certo punto diventa il farfield, e non ha senso! - // UPDATE: Mi sa che la wall distance ĆØ rispetto alla parete, quindi effettivamente l'elemento piĆ¹ vicino ĆØ sempre a parete. - ///////////////////// - - // cout << "Sono qui" << endl; if (options.SLM && options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM) { /*--- Reconstructon of auxiliary variables gradient ---*/ // Each rank collects all normals - vector>> WallNormal; - WallNormal.resize(config->GetnMarker_All()); - for (auto iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++){ - if (config->GetViscous_Wall(iMarker)) { - WallNormal[iMarker].resize(geometry->GetnElem_Bound(iMarker)); - - // cout << "geometry->nVertex[iMarker] = " << geometry->nVertex[iMarker] << endl; - for (auto iElem = 0u; iElem < geometry->GetnElem_Bound(iMarker); iElem++) { - vector NormalHere(nDim, 0.0); - - for (unsigned short iNode = 0; iNode < geometry->bound[iMarker][iElem]->GetnNodes(); iNode++) { - // Extract global coordinate of the node - unsigned long iPointHere = geometry->bound[iMarker][iElem]->GetNode(iNode); - long iVertexHere = geometry->nodes->GetVertex(iPointHere, iMarker); - for (auto iDim = 0u; iDim < nDim; iDim++) - NormalHere[iDim] += geometry->vertex[iMarker][iElem]->GetNormal(iDim); - } - - for (auto iDim = 0u; iDim < nDim; iDim++) - NormalHere[iDim] /= geometry->bound[iMarker][iElem]->GetnNodes(); - - su2double NormalMag = 0.0; - for (auto iDim = 0u; iDim < nDim; iDim++) - NormalMag += NormalHere[iDim]*NormalHere[iDim]; - NormalMag = sqrt(NormalMag); - - for (auto iDim = 0u; iDim < nDim; iDim++) - NormalHere[iDim] /= NormalMag; - - // cout << "NormalHere(x, y, z) = " << NormalHere[0] << ", " << NormalHere[1] << ", " << NormalHere[2] << endl; - // cout << "FianlNormalHere(x, y, z) = " << NormalHere[0] << ", " << NormalHere[1] << ", " << NormalHere[2] << endl << endl; - - WallNormal[iMarker][iElem] = NormalHere; - } - } else { - WallNormal[iMarker].resize(1); - WallNormal[iMarker][0].resize(3); - WallNormal[iMarker][0][0] = 0.0; - WallNormal[iMarker][0][1] = 0.0; - WallNormal[iMarker][0][2] = 0.0; - } - } - - auto normal_i = - make_pair( config->GetnMarker_All(), [config,geometry,WallNormal](unsigned long iMarker){ - auto nElem_Bou = geometry->GetnElem_Bound(iMarker); - if (!config->GetViscous_Wall(iMarker)) nElem_Bou = 1; - - return make_pair(nElem_Bou, [WallNormal,iMarker](unsigned long iElem){ - const auto dimensions = 3; - - return make_pair(dimensions, [WallNormal,iMarker,iElem](unsigned short iDim){ - // cout << "iMarker = " << iMarker << " iElem = " << iElem << " iDim = " << iDim << endl; - // cout << "WallNormal(x, y, z) = " << WallNormal[iMarker][iElem][0] << ", " << WallNormal[iMarker][iElem][1] << ", " << WallNormal[iMarker][iElem][2] << endl; + // vector>> WallNormal; + // WallNormal.resize(config->GetnMarker_All()); + // for (auto iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++){ + // if (config->GetViscous_Wall(iMarker)) { + // WallNormal[iMarker].resize(geometry->GetnElem_Bound(iMarker)); + + // // cout << "geometry->nVertex[iMarker] = " << geometry->nVertex[iMarker] << endl; + // for (auto iElem = 0u; iElem < geometry->GetnElem_Bound(iMarker); iElem++) { + // vector NormalHere(nDim, 0.0); + + // for (unsigned short iNode = 0; iNode < geometry->bound[iMarker][iElem]->GetnNodes(); iNode++) { + // // Extract global coordinate of the node + // unsigned long iPointHere = geometry->bound[iMarker][iElem]->GetNode(iNode); + // long iVertexHere = geometry->nodes->GetVertex(iPointHere, iMarker); + // for (auto iDim = 0u; iDim < nDim; iDim++) + // NormalHere[iDim] += geometry->vertex[iMarker][iElem]->GetNormal(iDim); + // } + + // for (auto iDim = 0u; iDim < nDim; iDim++) + // NormalHere[iDim] /= geometry->bound[iMarker][iElem]->GetnNodes(); + + // su2double NormalMag = 0.0; + // for (auto iDim = 0u; iDim < nDim; iDim++) + // NormalMag += NormalHere[iDim]*NormalHere[iDim]; + // NormalMag = sqrt(NormalMag); + + // for (auto iDim = 0u; iDim < nDim; iDim++) + // NormalHere[iDim] /= NormalMag; + + // WallNormal[iMarker][iElem] = NormalHere; + // } + // } else { + // WallNormal[iMarker].resize(1); + // WallNormal[iMarker][0].resize(3); + // WallNormal[iMarker][0][0] = 0.0; + // WallNormal[iMarker][0][1] = 0.0; + // WallNormal[iMarker][0][2] = 0.0; + // } + // } + + // auto normal_i = + // make_pair( config->GetnMarker_All(), [config,geometry,WallNormal](unsigned long iMarker){ + // auto nElem_Bou = geometry->GetnElem_Bound(iMarker); + // if (!config->GetViscous_Wall(iMarker)) nElem_Bou = 1; + + // return make_pair(nElem_Bou, [WallNormal,iMarker](unsigned long iElem){ + // const auto dimensions = 3; + + // return make_pair(dimensions, [WallNormal,iMarker,iElem](unsigned short iDim){ + + // return WallNormal[iMarker][iElem][iDim]; + // }); + // }); + // }); + + // NdFlattener<3>Normals_Local(normal_i); + // NdFlattener<4> Normals_global(Nd_MPI_Environment(), Normals_Local); + // su2double** NormalPerPoint = new su2double* [nPoint]; + + // auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); + // SU2_OMP_FOR_STAT(omp_chunk_size) + // for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { + + // // Extract nearest wall element and wall marker + // int NearestWallRank = geometry->nodes->GetClosestWall_Rank(iPoint); + // unsigned long NearestWallElement = geometry->nodes->GetClosestWall_Elem(iPoint); + // unsigned short NearestWallMarker = geometry->nodes->GetClosestWall_Marker(iPoint); - return WallNormal[iMarker][iElem][iDim]; - }); - }); - }); + // NormalPerPoint[iPoint] = new su2double [MAXNDIM]; + // for(auto iDim = 0; iDim < nDim; iDim++) + // NormalPerPoint[iPoint][iDim] = Normals_global[NearestWallRank][NearestWallMarker][NearestWallElement][iDim]; - NdFlattener<3>Normals_Local(normal_i); - NdFlattener<4> Normals_global(Nd_MPI_Environment(), Normals_Local); - su2double** NormalPerPoint = new su2double* [nPoint]; + // nodes->SetAuxVar(iPoint, 0, flowNodes->GetProjVel(iPoint, NormalPerPoint[iPoint])); + // nodes->SetNormal(iPoint, NormalPerPoint[iPoint][0], NormalPerPoint[iPoint][1]); + // } + // END_SU2_OMP_FOR auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); SU2_OMP_FOR_STAT(omp_chunk_size) for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { - - // Extract nearest wall element and wall marker - int NearestWallRank = geometry->nodes->GetClosestWall_Rank(iPoint); - unsigned long NearestWallElement = geometry->nodes->GetClosestWall_Elem(iPoint); - unsigned short NearestWallMarker = geometry->nodes->GetClosestWall_Marker(iPoint); - // cout << "NearestWallRank = " << NearestWallRank << " NearestWallElement = " << NearestWallElement << " NearestWallMarker = " << NearestWallMarker << endl; - - NormalPerPoint[iPoint] = new su2double [MAXNDIM]; - for(auto iDim = 0; iDim < nDim; iDim++) - NormalPerPoint[iPoint][iDim] = Normals_global[NearestWallRank][NearestWallMarker][NearestWallElement][iDim]; - - // cout << "NormalHere(x, y, z) = " << NormalPerPoint[iPoint][0] << ", " << NormalPerPoint[iPoint][1] << ", " << NormalPerPoint[iPoint][2] << endl; - nodes->SetAuxVar(iPoint, 0, flowNodes->GetProjVel(iPoint, NormalPerPoint[iPoint])); - nodes->SetNormal(iPoint, NormalPerPoint[iPoint][0], NormalPerPoint[iPoint][1]); + auto Normal = geometry->nodes->GetNormal(iPoint); + nodes->SetAuxVar(iPoint, 0, flowNodes->GetProjVel(iPoint, Normal)); + nodes->SetNormal(iPoint, Normal[0], Normal[1]); } END_SU2_OMP_FOR - - // cout << "primo for" << endl; - if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { SetAuxVar_Gradient_GG(geometry, config); } @@ -304,20 +296,17 @@ void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contain SetAuxVar_Gradient_LS(geometry, config); } - //SU2_OMP_BARRIER - - // cout << "Dopo Gradienti" << endl; SU2_OMP_FOR_STAT(omp_chunk_size) for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { su2double AuxVarHere = 0.0; + auto Normal = geometry->nodes->GetNormal(iPoint); for (auto iDim = 0u; iDim < nDim; iDim++) - AuxVarHere += NormalPerPoint[iPoint][iDim] * nodes->GetAuxVarGradient(iPoint, 0, iDim); + AuxVarHere += Normal[iDim] * nodes->GetAuxVarGradient(iPoint, 0, iDim); nodes->SetAuxVar(iPoint, 0, AuxVarHere); } END_SU2_OMP_FOR - // cout << "Ho finito" << endl; } } From 7eee4ab87bd40ab5b5bc02a7bc04b0e6925c99f0 Mon Sep 17 00:00:00 2001 From: rois1995 Date: Thu, 27 Apr 2023 10:06:15 +0200 Subject: [PATCH 10/20] Check For changes --- .../turbulent/transition/trans_sources.hpp | 4 +- .../numerics/turbulent/turb_sources.hpp | 7 +- SU2_CFD/src/SU2_CFD.cpp | 3 +- SU2_CFD/src/output/CFlowIncOutput.cpp | 1 + SU2_CFD/src/output/CFlowOutput.cpp | 7 +- SU2_CFD/src/solvers/CTransLMSolver.cpp | 89 +------------------ SU2_CFD/src/solvers/CTurbSASolver.cpp | 4 +- SU2_CFD/src/solvers/CTurbSSTSolver.cpp | 4 +- 8 files changed, 21 insertions(+), 98 deletions(-) diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp index 14daac3d81a..0dae2e76c0e 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp @@ -124,7 +124,7 @@ class CSourcePieceWise_TransLM final : public CNumerics { const su2double vel_v = V_i[1 + idx.Velocity()]; const su2double vel_w = (nDim == 3) ? V_i[2 + idx.Velocity()] : 0.0; - const su2double Velocity_Mag = sqrt(vel_u * vel_u + vel_v * vel_v + vel_w * vel_w); + const su2double Velocity_Mag = max(sqrt(vel_u * vel_u + vel_v * vel_v + vel_w * vel_w), 1e-20); AD::SetPreaccIn(V_i[idx.Density()], V_i[idx.LaminarViscosity()], V_i[idx.EddyViscosity()]); @@ -235,7 +235,7 @@ class CSourcePieceWise_TransLM final : public CNumerics { const su2double Corr_Ret_lim = 20.0; su2double f_lambda = 1.0; - su2double Retheta_Error = 200.0, Retheta_old = 0.0; + su2double Retheta_Error = 200.0, Retheta_old = 1.0; su2double lambda = 0.0; su2double Corr_Ret = 20.0; diff --git a/SU2_CFD/include/numerics/turbulent/turb_sources.hpp b/SU2_CFD/include/numerics/turbulent/turb_sources.hpp index 8283018dd6a..eff9a773051 100644 --- a/SU2_CFD/include/numerics/turbulent/turb_sources.hpp +++ b/SU2_CFD/include/numerics/turbulent/turb_sources.hpp @@ -122,7 +122,10 @@ class CSourceBase_TurbSA : public CNumerics { /*--- Dacles-Mariani et. al. rotation correction ("-R"). ---*/ if (options.rot) { - var.Omega += 2.0 * min(0.0, StrainMag_i - var.Omega); + // const su2double Crot = 2.0; // Orig + const su2double Crot = 1.0; // HLPW-5 + var.Omega += Crot * min(0.0, StrainMag_i - var.Omega); + if(ScalarVar_i[0] < 0 ) var.Omega = abs(var.Omega); } if (dist_i > 1e-10) { @@ -832,7 +835,7 @@ class CSourcePieceWise_TurbSST final : public CNumerics { if (config->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM) { pk = pk * eff_intermittency; // Check if the Prod_lim_k has to be introduced based on input options - if ((config->GetLMParsedOptions()).SLM) { + if ((config->GetLMParsedOptions()).SLM && (config->GetLMParsedOptions()).Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM) { const su2double Re_theta_c_lim = 1100.0; const su2double C_k = 1.0; const su2double C_SEP = 1.0; diff --git a/SU2_CFD/src/SU2_CFD.cpp b/SU2_CFD/src/SU2_CFD.cpp index a6a6a92f69c..6e4fb584cea 100644 --- a/SU2_CFD/src/SU2_CFD.cpp +++ b/SU2_CFD/src/SU2_CFD.cpp @@ -33,7 +33,7 @@ #endif /* Include file, needed for the runtime NaN catching. You also have to include feenableexcept(...) below. */ -//#include +#include using namespace std; @@ -75,6 +75,7 @@ int main(int argc, char *argv[]) { /*--- Uncomment the following line if runtime NaN catching is desired. ---*/ // feenableexcept(FE_INVALID | FE_OVERFLOW | FE_DIVBYZERO ); + feenableexcept(FE_OVERFLOW | FE_DIVBYZERO ); /*--- Initialize libxsmm, if supported. ---*/ #ifdef HAVE_LIBXSMM diff --git a/SU2_CFD/src/output/CFlowIncOutput.cpp b/SU2_CFD/src/output/CFlowIncOutput.cpp index c98685c5058..794bca81cb6 100644 --- a/SU2_CFD/src/output/CFlowIncOutput.cpp +++ b/SU2_CFD/src/output/CFlowIncOutput.cpp @@ -210,6 +210,7 @@ void CFlowIncOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolv SetHistoryOutputValue("MAX_PRESSURE", log10(flow_solver->GetRes_Max(0))); SetHistoryOutputValue("MAX_VELOCITY-X", log10(flow_solver->GetRes_Max(1))); + cout << flow_solver->GetRes_Max(2) << endl; SetHistoryOutputValue("MAX_VELOCITY-Y", log10(flow_solver->GetRes_Max(2))); if (nDim == 3) SetHistoryOutputValue("RMS_VELOCITY-Z", log10(flow_solver->GetRes_Max(3))); diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index 0ba43a94a98..5808e8d500a 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -1079,17 +1079,18 @@ void CFlowOutput::SetVolumeOutputFields_ScalarSolution(const CConfig* config){ AddVolumeOutput("F_ONSET", "LM_F_onset", "DEBUG", "LM F_ONSET"); AddVolumeOutput("STRAINMAG", "StrainMag", "DEBUG", "LM STRAINMAG"); AddVolumeOutput("LAMBDA_THETA", "Lambda_theta", "DEBUG", "LM Lambda_theta"); - AddVolumeOutput("DU_DS", "du_ds", "DEBUG", "LM du_ds"); + AddVolumeOutput("DU_DS", "du_ds", "DEBUG", "LM du_ds"); if ((config->GetLMParsedOptions()).SLM) { AddVolumeOutput("TU", "Tu", "SOLUTION", "LM Tu"); AddVolumeOutput("NORMAL_X", "Normal_x", "DEBUG", "LM Normal_x"); AddVolumeOutput("NORMAL_Y", "Normal_y", "DEBUG", "LM Normal_y"); AddVolumeOutput("NORMAL_Z", "Normal_z", "DEBUG", "LM Normal_z"); - if (TurbModelFamily(config->GetKind_Turb_Model()) == TURB_FAMILY::SA) { + if (!((config->GetLMParsedOptions()).Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM)) { AddVolumeOutput("INTERMITTENCY_SEP", "LM_gamma_sep", "PRIMITIVE", "LM intermittency"); AddVolumeOutput("INTERMITTENCY_EFF", "LM_gamma_eff", "PRIMITIVE", "LM RE_THETA_T"); } } + if (!(config->GetLMParsedOptions()).SLM) { AddVolumeOutput("INTERMITTENCY_SEP", "LM_gamma_sep", "PRIMITIVE", "LM intermittency"); AddVolumeOutput("INTERMITTENCY_EFF", "LM_gamma_eff", "PRIMITIVE", "LM RE_THETA_T"); @@ -1266,7 +1267,7 @@ void CFlowOutput::LoadVolumeData_Scalar(const CConfig* config, const CSolver* co SetVolumeOutputValue("NORMAL_X", iPoint, (Node_Trans->GetNormal(iPoint)).first); SetVolumeOutputValue("NORMAL_Y", iPoint, (Node_Trans->GetNormal(iPoint)).second); SetVolumeOutputValue("NORMAL_Z", iPoint, 0.0); - if (TurbModelFamily(config->GetKind_Turb_Model()) == TURB_FAMILY::SA) { + if (!((config->GetLMParsedOptions()).Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM)) { SetVolumeOutputValue("INTERMITTENCY_SEP", iPoint, Node_Trans->GetIntermittencySep(iPoint)); SetVolumeOutputValue("INTERMITTENCY_EFF", iPoint, Node_Trans->GetIntermittencyEff(iPoint)); } diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index a7eda1086c2..b831af93e47 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -74,7 +74,7 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh isSepNeeded = true; // If the Simplified model is used coupled with SST then we do not need the separation induced intermittency // due to the added production term to k equation - if (options.SLM && TurbFamily == TURB_FAMILY::KW) isSepNeeded = false; + if (options.SLM && options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM) isSepNeeded = false; /*--- Single grid simulation ---*/ @@ -199,86 +199,6 @@ void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contain if (options.SLM && options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM) { - /*--- Reconstructon of auxiliary variables gradient ---*/ - - // Each rank collects all normals - - // vector>> WallNormal; - // WallNormal.resize(config->GetnMarker_All()); - // for (auto iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++){ - // if (config->GetViscous_Wall(iMarker)) { - // WallNormal[iMarker].resize(geometry->GetnElem_Bound(iMarker)); - - // // cout << "geometry->nVertex[iMarker] = " << geometry->nVertex[iMarker] << endl; - // for (auto iElem = 0u; iElem < geometry->GetnElem_Bound(iMarker); iElem++) { - // vector NormalHere(nDim, 0.0); - - // for (unsigned short iNode = 0; iNode < geometry->bound[iMarker][iElem]->GetnNodes(); iNode++) { - // // Extract global coordinate of the node - // unsigned long iPointHere = geometry->bound[iMarker][iElem]->GetNode(iNode); - // long iVertexHere = geometry->nodes->GetVertex(iPointHere, iMarker); - // for (auto iDim = 0u; iDim < nDim; iDim++) - // NormalHere[iDim] += geometry->vertex[iMarker][iElem]->GetNormal(iDim); - // } - - // for (auto iDim = 0u; iDim < nDim; iDim++) - // NormalHere[iDim] /= geometry->bound[iMarker][iElem]->GetnNodes(); - - // su2double NormalMag = 0.0; - // for (auto iDim = 0u; iDim < nDim; iDim++) - // NormalMag += NormalHere[iDim]*NormalHere[iDim]; - // NormalMag = sqrt(NormalMag); - - // for (auto iDim = 0u; iDim < nDim; iDim++) - // NormalHere[iDim] /= NormalMag; - - // WallNormal[iMarker][iElem] = NormalHere; - // } - // } else { - // WallNormal[iMarker].resize(1); - // WallNormal[iMarker][0].resize(3); - // WallNormal[iMarker][0][0] = 0.0; - // WallNormal[iMarker][0][1] = 0.0; - // WallNormal[iMarker][0][2] = 0.0; - // } - // } - - // auto normal_i = - // make_pair( config->GetnMarker_All(), [config,geometry,WallNormal](unsigned long iMarker){ - // auto nElem_Bou = geometry->GetnElem_Bound(iMarker); - // if (!config->GetViscous_Wall(iMarker)) nElem_Bou = 1; - - // return make_pair(nElem_Bou, [WallNormal,iMarker](unsigned long iElem){ - // const auto dimensions = 3; - - // return make_pair(dimensions, [WallNormal,iMarker,iElem](unsigned short iDim){ - - // return WallNormal[iMarker][iElem][iDim]; - // }); - // }); - // }); - - // NdFlattener<3>Normals_Local(normal_i); - // NdFlattener<4> Normals_global(Nd_MPI_Environment(), Normals_Local); - // su2double** NormalPerPoint = new su2double* [nPoint]; - - // auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); - // SU2_OMP_FOR_STAT(omp_chunk_size) - // for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { - - // // Extract nearest wall element and wall marker - // int NearestWallRank = geometry->nodes->GetClosestWall_Rank(iPoint); - // unsigned long NearestWallElement = geometry->nodes->GetClosestWall_Elem(iPoint); - // unsigned short NearestWallMarker = geometry->nodes->GetClosestWall_Marker(iPoint); - - // NormalPerPoint[iPoint] = new su2double [MAXNDIM]; - // for(auto iDim = 0; iDim < nDim; iDim++) - // NormalPerPoint[iPoint][iDim] = Normals_global[NearestWallRank][NearestWallMarker][NearestWallElement][iDim]; - - // nodes->SetAuxVar(iPoint, 0, flowNodes->GetProjVel(iPoint, NormalPerPoint[iPoint])); - // nodes->SetNormal(iPoint, NormalPerPoint[iPoint][0], NormalPerPoint[iPoint][1]); - // } - // END_SU2_OMP_FOR auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); SU2_OMP_FOR_STAT(omp_chunk_size) @@ -345,10 +265,7 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai StrainMag = max(StrainMag, 1e-12); // safety against division by zero const su2double Intermittency = nodes->GetSolution(iPoint,0); const su2double Re_v = rho*dist*dist*StrainMag/mu; - const su2double vel_u = flowNodes->GetVelocity(iPoint, 0); - const su2double vel_v = flowNodes->GetVelocity(iPoint, 1); - const su2double vel_w = (nDim ==3) ? flowNodes->GetVelocity(iPoint, 2) : 0.0; - const su2double VelocityMag = sqrt(vel_u*vel_u + vel_v*vel_v + vel_w*vel_w); + const su2double VelocityMag = max(sqrt(flowNodes->GetVelocity2(iPoint)), 1e-20); su2double omega = 0.0; su2double k = 0.0; if(TurbFamily == TURB_FAMILY::KW){ @@ -359,7 +276,7 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai su2double Re_t = 0.0; su2double Corr_Rec = 0.0; - if (options.SLM && TurbFamily == TURB_FAMILY::SA) { + if (options.SLM) { Re_t = nodes->GetRe_t(iPoint); Corr_Rec = nodes->GetCorr_Rec(iPoint); } else { diff --git a/SU2_CFD/src/solvers/CTurbSASolver.cpp b/SU2_CFD/src/solvers/CTurbSASolver.cpp index 30d7308cd2e..8d0855dbe4f 100644 --- a/SU2_CFD/src/solvers/CTurbSASolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSASolver.cpp @@ -269,7 +269,7 @@ void CTurbSASolver::Postprocessing(CGeometry *geometry, CSolver **solver_contain } shearStress = sqrt(shearStress); - FrictionVelocity = sqrt(shearStress/flowNodes->GetDensity(iPoint)); + FrictionVelocity = sqrt(shearStress/max(flowNodes->GetDensity(iPoint), 1e-20)); } else { su2double VorticityMag = max(GeometryToolbox::Norm(3, flowNodes->GetVorticity(iPoint)), 1e-12); FrictionVelocity = sqrt(flowNodes->GetLaminarViscosity(iPoint)*VorticityMag); @@ -277,7 +277,7 @@ void CTurbSASolver::Postprocessing(CGeometry *geometry, CSolver **solver_contain const su2double wall_dist = geometry->nodes->GetWall_Distance(jPoint); const su2double Derivative = nodes->GetSolution(jPoint, 0) / wall_dist; - const su2double turbulence_index = Derivative / (FrictionVelocity * 0.41); + const su2double turbulence_index = Derivative / max((FrictionVelocity * 0.41), 1e-20); nodes->SetTurbIndex(iPoint, turbulence_index); diff --git a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp index c2f1983cd73..d0e26a43153 100644 --- a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp @@ -259,10 +259,10 @@ void CTurbSSTSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai } shearStress = sqrt(shearStress); - const su2double FrictionVelocity = sqrt(shearStress/flowNodes->GetDensity(iPoint)); + const su2double FrictionVelocity = sqrt(shearStress/max(flowNodes->GetDensity(iPoint),1e-20)); const su2double wall_dist = geometry->nodes->GetWall_Distance(jPoint); const su2double Derivative = flowNodes->GetLaminarViscosity(jPoint) * pow(nodes->GetSolution(jPoint, 0), 0.673) / wall_dist; - const su2double turbulence_index = 6.1 * Derivative / pow(FrictionVelocity, 2.346); + const su2double turbulence_index = 6.1 * Derivative / max(pow(FrictionVelocity, 2.346),1e-20); nodes->SetTurbIndex(iPoint, turbulence_index); From c4615188e5718f3f44b0e5cf7a72032bd51f3fdf Mon Sep 17 00:00:00 2001 From: rois1995 Date: Thu, 27 Apr 2023 10:08:30 +0200 Subject: [PATCH 11/20] Removing changes for SA-R --- SU2_CFD/include/numerics/turbulent/turb_sources.hpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/SU2_CFD/include/numerics/turbulent/turb_sources.hpp b/SU2_CFD/include/numerics/turbulent/turb_sources.hpp index eff9a773051..999e1dad3ef 100644 --- a/SU2_CFD/include/numerics/turbulent/turb_sources.hpp +++ b/SU2_CFD/include/numerics/turbulent/turb_sources.hpp @@ -122,10 +122,7 @@ class CSourceBase_TurbSA : public CNumerics { /*--- Dacles-Mariani et. al. rotation correction ("-R"). ---*/ if (options.rot) { - // const su2double Crot = 2.0; // Orig - const su2double Crot = 1.0; // HLPW-5 - var.Omega += Crot * min(0.0, StrainMag_i - var.Omega); - if(ScalarVar_i[0] < 0 ) var.Omega = abs(var.Omega); + var.Omega += 2.0 * min(0.0, StrainMag_i - var.Omega); } if (dist_i > 1e-10) { From e68a9e47c4d6d8a026156500478e33908e2cda6a Mon Sep 17 00:00:00 2001 From: rois1995 Date: Thu, 27 Apr 2023 12:12:09 +0200 Subject: [PATCH 12/20] Fixed vertex indexing for wall normal computation --- Common/src/geometry/CGeometry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index c5436b8930d..db8772f464b 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -4128,7 +4128,7 @@ void CGeometry::ComputeWallDistance(const CConfig* const* config_container, CGeo unsigned long iPointHere = geometry->bound[iMarker][iElem]->GetNode(iNode); long iVertexHere = geometry->nodes->GetVertex(iPointHere, iMarker); for (auto iDim = 0u; iDim < 3; iDim++) - NormalHere[iDim] += geometry->vertex[iMarker][iElem]->GetNormal(iDim); + NormalHere[iDim] += geometry->vertex[iMarker][iVertexHere]->GetNormal(iDim); } for (auto iDim = 0u; iDim < 3; iDim++) From bcdd671de3903c7ba1bfad0aed72a2ae620c78ff Mon Sep 17 00:00:00 2001 From: rois1995 Date: Thu, 27 Apr 2023 12:19:37 +0200 Subject: [PATCH 13/20] Removed a cout --- SU2_CFD/src/output/CFlowIncOutput.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/SU2_CFD/src/output/CFlowIncOutput.cpp b/SU2_CFD/src/output/CFlowIncOutput.cpp index 794bca81cb6..c98685c5058 100644 --- a/SU2_CFD/src/output/CFlowIncOutput.cpp +++ b/SU2_CFD/src/output/CFlowIncOutput.cpp @@ -210,7 +210,6 @@ void CFlowIncOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolv SetHistoryOutputValue("MAX_PRESSURE", log10(flow_solver->GetRes_Max(0))); SetHistoryOutputValue("MAX_VELOCITY-X", log10(flow_solver->GetRes_Max(1))); - cout << flow_solver->GetRes_Max(2) << endl; SetHistoryOutputValue("MAX_VELOCITY-Y", log10(flow_solver->GetRes_Max(2))); if (nDim == 3) SetHistoryOutputValue("RMS_VELOCITY-Z", log10(flow_solver->GetRes_Max(3))); From 9bb243599b99b9c12b8698b7c53861921d400525 Mon Sep 17 00:00:00 2001 From: rois1995 Date: Thu, 27 Apr 2023 12:41:08 +0200 Subject: [PATCH 14/20] Fixed division by zero with Corr_Rec --- SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp | 2 +- SU2_CFD/src/solvers/CTransLMSolver.cpp | 1 + SU2_CFD/src/variables/CTransLMVariable.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp index 0dae2e76c0e..97b00174fda 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp @@ -397,7 +397,7 @@ class CSourcePieceWise_TransSLM final : public CNumerics { su2double IntermittencyEff = 1.0; su2double Re_t; - su2double Corr_Rec; + su2double Corr_Rec = 1.0; su2double AuxVar; su2double F2; su2double Tu_Here = 0.0; diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index b831af93e47..3bd90c72b87 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -291,6 +291,7 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai } + // cout << Re_t << " " << Corr_Rec << endl; // if (geometry->nodes->GetDomain(iPoint)) cout << "Point is on boundary" << endl; diff --git a/SU2_CFD/src/variables/CTransLMVariable.cpp b/SU2_CFD/src/variables/CTransLMVariable.cpp index bcc72b3af70..d5de642adc3 100644 --- a/SU2_CFD/src/variables/CTransLMVariable.cpp +++ b/SU2_CFD/src/variables/CTransLMVariable.cpp @@ -66,7 +66,7 @@ CTransLMVariable::CTransLMVariable(su2double Intermittency, su2double ReThetaT, Re_v.resize(nPoint) = 0.0; - Corr_Rec.resize(nPoint) = 0.0; + Corr_Rec.resize(nPoint) = 1.0; Prod.resize(nPoint) = 0.0; Destr.resize(nPoint) = 0.0; F_onset1.resize(nPoint) = 0.0; From a9a6ce48e8619402b1763d811425846a17d2f432 Mon Sep 17 00:00:00 2001 From: rois1995 Date: Thu, 27 Apr 2023 14:07:03 +0200 Subject: [PATCH 15/20] Removed cout --- .../include/numerics/turbulent/transition/trans_sources.hpp | 6 +++--- SU2_CFD/src/solvers/CTransLMSolver.cpp | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp index 97b00174fda..2a134d3f99e 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp @@ -552,9 +552,9 @@ class CSourcePieceWise_TransSLM final : public CNumerics { const su2double k = 0.25 - lambda_theta; const su2double FirstTerm = 4.14 * k; const su2double SecondTerm = 83.5 * pow(k, 2.0); - const su2double ThirdTerm = 854 * pow(k, 3.0); - const su2double ForthTerm = 3337 * pow(k, 4.0); - const su2double FifthTerm = 4576 * pow(k, 5.0); + const su2double ThirdTerm = 854.0 * pow(k, 3.0); + const su2double ForthTerm = 3337.0 * pow(k, 4.0); + const su2double FifthTerm = 4576.0 * pow(k, 5.0); const su2double H = min(2.0 + FirstTerm - SecondTerm + ThirdTerm - ForthTerm + FifthTerm, 2.7); // Computation of critical cross flow Reynolds number diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index 3bd90c72b87..b831af93e47 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -291,7 +291,6 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai } - // cout << Re_t << " " << Corr_Rec << endl; // if (geometry->nodes->GetDomain(iPoint)) cout << "Point is on boundary" << endl; From 86b068c00f85be0943d6d5700ff7972bb20d3122 Mon Sep 17 00:00:00 2001 From: rois1995 Date: Thu, 27 Apr 2023 14:22:19 +0200 Subject: [PATCH 16/20] Fixed Max Velocity-Z output for Incompressible flow --- SU2_CFD/src/output/CFlowIncOutput.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SU2_CFD/src/output/CFlowIncOutput.cpp b/SU2_CFD/src/output/CFlowIncOutput.cpp index c98685c5058..87783ca9bc7 100644 --- a/SU2_CFD/src/output/CFlowIncOutput.cpp +++ b/SU2_CFD/src/output/CFlowIncOutput.cpp @@ -211,7 +211,7 @@ void CFlowIncOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolv SetHistoryOutputValue("MAX_PRESSURE", log10(flow_solver->GetRes_Max(0))); SetHistoryOutputValue("MAX_VELOCITY-X", log10(flow_solver->GetRes_Max(1))); SetHistoryOutputValue("MAX_VELOCITY-Y", log10(flow_solver->GetRes_Max(2))); - if (nDim == 3) SetHistoryOutputValue("RMS_VELOCITY-Z", log10(flow_solver->GetRes_Max(3))); + if (nDim == 3) SetHistoryOutputValue("MAX_VELOCITY-Z", log10(flow_solver->GetRes_Max(3))); if (multiZone){ SetHistoryOutputValue("BGS_PRESSURE", log10(flow_solver->GetRes_BGS(0))); From 73c0a4b40ca64266dd9bb914e745524afbc2538b Mon Sep 17 00:00:00 2001 From: rois1995 Date: Thu, 27 Apr 2023 15:14:21 +0200 Subject: [PATCH 17/20] Fixed output of Normals in volume --- SU2_CFD/include/variables/CTransLMVariable.hpp | 7 +++++-- SU2_CFD/include/variables/CVariable.hpp | 6 ++++-- SU2_CFD/src/output/CFlowOutput.cpp | 6 +++--- SU2_CFD/src/solvers/CTransLMSolver.cpp | 2 +- SU2_CFD/src/variables/CTransLMVariable.cpp | 4 +++- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/SU2_CFD/include/variables/CTransLMVariable.hpp b/SU2_CFD/include/variables/CTransLMVariable.hpp index 8478b84d550..84e15f2dccb 100644 --- a/SU2_CFD/include/variables/CTransLMVariable.hpp +++ b/SU2_CFD/include/variables/CTransLMVariable.hpp @@ -55,6 +55,7 @@ class CTransLMVariable final : public CTurbVariable { VectorType normal_x; VectorType normal_y; + VectorType normal_z; public: /*! @@ -104,7 +105,7 @@ class CTransLMVariable final : public CTurbVariable { void SetF_onset2(unsigned long iPoint, su2double val_F_onset2) override; void SetF_onset3(unsigned long iPoint, su2double val_F_onset3) override; void SetF_onset(unsigned long iPoint, su2double val_F_onset) override; - void SetNormal(unsigned long iPoint, su2double val_normal_x, su2double val_normal_y) override; + void SetNormal(unsigned long iPoint, su2double val_normal_x, su2double val_normal_y, su2double val_normal_z) override; /*! * \brief Calculate effective intermittency. @@ -135,5 +136,7 @@ class CTransLMVariable final : public CTurbVariable { inline su2double GetF_onset2(unsigned long iPoint) const override { return F_onset2(iPoint); } inline su2double GetF_onset3(unsigned long iPoint) const override { return F_onset3(iPoint); } inline su2double GetF_onset(unsigned long iPoint) const override { return F_onset(iPoint); } - inline pair GetNormal(unsigned long iPoint) const override {return make_pair(normal_x(iPoint), normal_y(iPoint));}; + inline su2double GetNormal_x(unsigned long iPoint) const override {return normal_x(iPoint);}; + inline su2double GetNormal_y(unsigned long iPoint) const override {return normal_y(iPoint);}; + inline su2double GetNormal_z(unsigned long iPoint) const override {return normal_z(iPoint);}; }; diff --git a/SU2_CFD/include/variables/CVariable.hpp b/SU2_CFD/include/variables/CVariable.hpp index 9fb1cac0556..726e81112be 100644 --- a/SU2_CFD/include/variables/CVariable.hpp +++ b/SU2_CFD/include/variables/CVariable.hpp @@ -1727,7 +1727,7 @@ class CVariable { inline virtual void SetF_onset2(unsigned long iPoint, su2double val_F_onset2) {}; inline virtual void SetF_onset3(unsigned long iPoint, su2double val_F_onset3) {}; inline virtual void SetF_onset(unsigned long iPoint, su2double val_F_onset1) {}; - inline virtual void SetNormal(unsigned long iPoint, su2double val_normal_x, su2double val_normal_y) {}; + inline virtual void SetNormal(unsigned long iPoint, su2double val_normal_x, su2double val_normal_y, su2double val_normal_z) {}; /*! * \brief Get Value of Transition Momentum Thickness Reynolds number from correlations. @@ -1743,7 +1743,9 @@ class CVariable { inline virtual su2double GetF_onset2(unsigned long iPoint) const { return 0.0; } inline virtual su2double GetF_onset3(unsigned long iPoint) const { return 0.0; } inline virtual su2double GetF_onset(unsigned long iPoint) const { return 0.0; } - inline virtual pair GetNormal(unsigned long iPoint) const { return make_pair(0.0, 0.0); } + inline virtual su2double GetNormal_x(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetNormal_y(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetNormal_z(unsigned long iPoint) const { return 0.0; } /*! * \brief Set Value of Momentum Thickness Reynolds number from correlations (substitute to the second equation of original LM model). diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index 5808e8d500a..2851d9636f5 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -1264,9 +1264,9 @@ void CFlowOutput::LoadVolumeData_Scalar(const CConfig* config, const CSolver* co } else { SetVolumeOutputValue("RE_THETA_T", iPoint, Node_Trans->GetRe_t(iPoint)); SetVolumeOutputValue("TU", iPoint, Node_Trans->GetTu(iPoint)); - SetVolumeOutputValue("NORMAL_X", iPoint, (Node_Trans->GetNormal(iPoint)).first); - SetVolumeOutputValue("NORMAL_Y", iPoint, (Node_Trans->GetNormal(iPoint)).second); - SetVolumeOutputValue("NORMAL_Z", iPoint, 0.0); + SetVolumeOutputValue("NORMAL_X", iPoint, Node_Trans->GetNormal_x(iPoint)); + SetVolumeOutputValue("NORMAL_Y", iPoint, Node_Trans->GetNormal_y(iPoint)); + SetVolumeOutputValue("NORMAL_Z", iPoint, Node_Trans->GetNormal_z(iPoint)); if (!((config->GetLMParsedOptions()).Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM)) { SetVolumeOutputValue("INTERMITTENCY_SEP", iPoint, Node_Trans->GetIntermittencySep(iPoint)); SetVolumeOutputValue("INTERMITTENCY_EFF", iPoint, Node_Trans->GetIntermittencyEff(iPoint)); diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index b831af93e47..d0f8eeaf11d 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -205,7 +205,7 @@ void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contain for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { auto Normal = geometry->nodes->GetNormal(iPoint); nodes->SetAuxVar(iPoint, 0, flowNodes->GetProjVel(iPoint, Normal)); - nodes->SetNormal(iPoint, Normal[0], Normal[1]); + nodes->SetNormal(iPoint, Normal[0], Normal[1], Normal[2]); } END_SU2_OMP_FOR diff --git a/SU2_CFD/src/variables/CTransLMVariable.cpp b/SU2_CFD/src/variables/CTransLMVariable.cpp index d5de642adc3..405e2fea9a0 100644 --- a/SU2_CFD/src/variables/CTransLMVariable.cpp +++ b/SU2_CFD/src/variables/CTransLMVariable.cpp @@ -62,6 +62,7 @@ CTransLMVariable::CTransLMVariable(su2double Intermittency, su2double ReThetaT, normal_x.resize(nPoint) = 0.0; normal_y.resize(nPoint) = 0.0; + normal_z.resize(nPoint) = 0.0; } @@ -127,7 +128,8 @@ void CTransLMVariable::SetF_onset3(unsigned long iPoint, su2double val_F_onset3) void CTransLMVariable::SetF_onset(unsigned long iPoint, su2double val_F_onset) { F_onset(iPoint) = val_F_onset; } -void CTransLMVariable::SetNormal(unsigned long iPoint, su2double val_normal_x, su2double val_normal_y) { +void CTransLMVariable::SetNormal(unsigned long iPoint, su2double val_normal_x, su2double val_normal_y, su2double val_normal_z) { normal_x(iPoint) = val_normal_x; normal_y(iPoint) = val_normal_y; + normal_z(iPoint) = val_normal_z; } \ No newline at end of file From 8d5148e1ef5d18483fa28aa42ec82a21116fecae Mon Sep 17 00:00:00 2001 From: rois1995 Date: Mon, 1 Jul 2024 10:55:41 +0200 Subject: [PATCH 18/20] - Added Simplified Langtry Menter model --- Common/include/geometry/dual_grid/CPoint.hpp | 57 +++ Common/include/option_structure.hpp | 74 +++- Common/src/CConfig.cpp | 33 +- Common/src/geometry/CGeometry.cpp | 75 ++++ Common/src/geometry/dual_grid/CPoint.cpp | 2 + SU2_CFD/include/numerics/CNumerics.hpp | 35 ++ .../turbulent/transition/trans_convection.hpp | 7 + .../transition/trans_correlations.hpp | 105 ++++++ .../turbulent/transition/trans_diffusion.hpp | 68 ++++ .../turbulent/transition/trans_sources.hpp | 332 +++++++++++++++++- .../numerics/turbulent/turb_sources.hpp | 12 + SU2_CFD/include/solvers/CTransLMSolver.hpp | 1 + .../include/variables/CTransLMVariable.hpp | 61 ++++ .../include/variables/CTurbSSTVariable.hpp | 1 + SU2_CFD/include/variables/CVariable.hpp | 45 +++ SU2_CFD/src/drivers/CDriver.cpp | 22 +- SU2_CFD/src/output/CFlowIncOutput.cpp | 2 +- SU2_CFD/src/output/CFlowOutput.cpp | 92 ++++- SU2_CFD/src/solvers/CTransLMSolver.cpp | 236 +++++++++---- SU2_CFD/src/solvers/CTurbSASolver.cpp | 2 +- SU2_CFD/src/solvers/CTurbSSTSolver.cpp | 4 +- SU2_CFD/src/variables/CTransLMVariable.cpp | 85 ++++- SU2_CFD/src/variables/CTurbSSTVariable.cpp | 1 + 23 files changed, 1236 insertions(+), 116 deletions(-) diff --git a/Common/include/geometry/dual_grid/CPoint.hpp b/Common/include/geometry/dual_grid/CPoint.hpp index 9c73fdeaa9a..a2cc83c04cd 100644 --- a/Common/include/geometry/dual_grid/CPoint.hpp +++ b/Common/include/geometry/dual_grid/CPoint.hpp @@ -112,6 +112,7 @@ class CPoint { su2activevector Curvature; /*!< \brief Value of the surface curvature (SU2_GEO). */ su2activevector MaxLength; /*!< \brief The maximum cell-center to cell-center length. */ su2activevector RoughnessHeight; /*!< \brief Roughness of the nearest wall. */ + su2activematrix Normals; /*!< \brief Normal of the nearest wall element. */ su2matrix AD_InputIndex; /*!< \brief Indices of Coord variables in the adjoint vector. */ su2matrix @@ -494,6 +495,27 @@ class CPoint { inline su2double& GetWall_Distance(unsigned long iPoint) { return Wall_Distance(iPoint); } inline const su2double& GetWall_Distance(unsigned long iPoint) const { return Wall_Distance(iPoint); } + /*! + * \brief Get the index of the closest wall element. + * \param[in] iPoint - Index of the point. + * \param[out] ClosestWall_Elem - ID of the closest element on a wall boundary. + */ + inline unsigned long GetClosestWall_Elem(unsigned long iPoint) {return ClosestWall_Elem(iPoint);} + + /*! + * \brief Get the marker of the closest wall marker. + * \param[in] iPoint - Index of the point. + * \param[out] ClosestWall_Marker - MarkerID of the closest wall boundary. + */ + inline unsigned long GetClosestWall_Marker(unsigned long iPoint) {return ClosestWall_Marker(iPoint);} + + /*! + * \brief Get the rank of the closest wall marker. + * \param[in] iPoint - Index of the point. + * \param[out] ClosestWall_Rank - RankID of the closest wall boundary. + */ + inline unsigned long GetClosestWall_Rank(unsigned long iPoint) {return ClosestWall_Rank(iPoint);} + /*! * \brief Set the value of the distance to the nearest wall. * \param[in] iPoint - Index of the point. @@ -508,6 +530,24 @@ class CPoint { */ inline su2double GetRoughnessHeight(unsigned long iPoint) const { return RoughnessHeight(iPoint); } + /*! + * \brief Set the value of the normal of the nearest wall element. + * \param[in] iPoint - Index of the point. + * \param[in] normal - Value of the normal. + */ + template + inline void SetNormal(unsigned long iPoint, Normals_type const&normal) { + for (unsigned long iDim = 0; iDim < nDim; iDim++) + Normals(iPoint,iDim) = normal[iDim]; + } + + /*! + * \brief Set the value of the normal of the nearest wall element. + * \param[in] iPoint - Index of the point. + * \return normal to the normal of the nearest wall element. + */ + inline su2double *GetNormal(unsigned long iPoint) { return Normals[iPoint]; } + /*! * \brief Set the value of the distance to a sharp edge. * \param[in] iPoint - Index of the point. @@ -908,4 +948,21 @@ class CPoint { } } } + + /*! + * \brief Set wall normal according to stored closest wall information. + * \param[in] normals - Mapping [rank][zone][marker][element] -> normal + */ + template + void SetWallNormals(Normals_type const&normals){ + for (unsigned long iPoint=0; iPoint= 0) + SetNormal(iPoint, normals[rankID][zoneID][markerID][elementID]); + } + } + }; diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 9bbe613c4bc..605cb49ca17 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -1189,27 +1189,37 @@ static const MapType Trans_Model_Map = { * \brief LM Options */ enum class LM_OPTIONS { - NONE, /*!< \brief No option / default. */ - LM2015, /*!< \brief Cross-flow corrections. */ - MALAN, /*!< \brief Kind of transition correlation model (Malan). */ - SULUKSNA, /*!< \brief Kind of transition correlation model (Suluksna). */ - KRAUSE, /*!< \brief Kind of transition correlation model (Krause). */ - KRAUSE_HYPER, /*!< \brief Kind of transition correlation model (Krause hypersonic). */ - MEDIDA_BAEDER,/*!< \brief Kind of transition correlation model (Medida-Baeder). */ - MEDIDA, /*!< \brief Kind of transition correlation model (Medida). */ - MENTER_LANGTRY, /*!< \brief Kind of transition correlation model (Menter-Langtry). */ - DEFAULT /*!< \brief Kind of transition correlation model (Menter-Langtry if SST, MALAN if SA). */ + NONE, /*!< \brief No option / default. */ + CROSSFLOW, /*!< \brief Cross-flow corrections. */ + SLM, /*!< \brief Simplified version. */ + PRODLIM, /*!< \brief Add production term to Pk. */ + MALAN, /*!< \brief Kind of transition correlation model (Malan). */ + SULUKSNA, /*!< \brief Kind of transition correlation model (Suluksna). */ + KRAUSE, /*!< \brief Kind of transition correlation model (Krause). */ + KRAUSE_HYPER, /*!< \brief Kind of transition correlation model (Krause hypersonic). */ + MEDIDA_BAEDER, /*!< \brief Kind of transition correlation model (Medida-Baeder). */ + MEDIDA, /*!< \brief Kind of transition correlation model (Medida). */ + MENTER_LANGTRY, /*!< \brief Kind of transition correlation model (Menter-Langtry). */ + MENTER_SLM, /*!< \brief Kind of transition correlation model (Menter Simplified LM model). */ + CODER_SLM, /*!< \brief Kind of transition correlation model (Coder Simplified LM model). */ + MOD_EPPLER_SLM, /*!< \brief Kind of transition correlation model (Modified Eppler Simplified LM model). */ + DEFAULT /*!< \brief Kind of transition correlation model (Menter-Langtry if SST, MALAN if SA). */ }; static const MapType LM_Options_Map = { MakePair("NONE", LM_OPTIONS::NONE) - MakePair("LM2015", LM_OPTIONS::LM2015) + MakePair("CROSSFLOW", LM_OPTIONS::CROSSFLOW) + MakePair("SLM", LM_OPTIONS::SLM) + MakePair("PRODLIM", LM_OPTIONS::PRODLIM) MakePair("MALAN", LM_OPTIONS::MALAN) MakePair("SULUKSNA", LM_OPTIONS::SULUKSNA) MakePair("KRAUSE", LM_OPTIONS::KRAUSE) MakePair("KRAUSE_HYPER", LM_OPTIONS::KRAUSE_HYPER) MakePair("MEDIDA_BAEDER", LM_OPTIONS::MEDIDA_BAEDER) MakePair("MENTER_LANGTRY", LM_OPTIONS::MENTER_LANGTRY) + MakePair("MENTER_SLM", LM_OPTIONS::MENTER_SLM) + MakePair("CODER_SLM", LM_OPTIONS::CODER_SLM) + MakePair("MOD_EPPLER_SLM", LM_OPTIONS::MOD_EPPLER_SLM) MakePair("DEFAULT", LM_OPTIONS::DEFAULT) }; @@ -1227,13 +1237,26 @@ enum class TURB_TRANS_CORRELATION { DEFAULT /*!< \brief Kind of transition correlation model (Menter-Langtry if SST, MALAN if SA). */ }; +/*! + * \brief Types of transition correlations for Simplified LM model + */ +enum class TURB_TRANS_CORRELATION_SLM { + MENTER_SLM, /*!< \brief Kind of transition correlation model (Menter Simplified LM model). */ + CODER_SLM, /*!< \brief Kind of transition correlation model (Coder Simplified LM model). */ + MOD_EPPLER_SLM, /*!< \brief Kind of transition correlation model (Modified Eppler Simplified LM model). */ + DEFAULT /*!< \brief Kind of transition correlation model. */ +}; + /*! * \brief Structure containing parsed LM options. */ struct LM_ParsedOptions { LM_OPTIONS version = LM_OPTIONS::NONE; /*!< \brief LM base model. */ - bool LM2015 = false; /*!< \brief Use cross-flow corrections. */ + bool SLM = false; /*!< \brief Use simplified version. */ + bool ProdLim = false; /*!< \brief Add production term to Pk. */ + bool CrossFlow = false; /*!< \brief Use cross-flow corrections. */ TURB_TRANS_CORRELATION Correlation = TURB_TRANS_CORRELATION::DEFAULT; + TURB_TRANS_CORRELATION_SLM Correlation_SLM = TURB_TRANS_CORRELATION_SLM::DEFAULT; }; /*! @@ -1251,7 +1274,10 @@ inline LM_ParsedOptions ParseLMOptions(const LM_OPTIONS *LM_Options, unsigned sh return std::find(LM_Options, lm_options_end, option) != lm_options_end; }; - LMParsedOptions.LM2015 = IsPresent(LM_OPTIONS::LM2015); + LMParsedOptions.SLM = IsPresent(LM_OPTIONS::SLM); + LMParsedOptions.ProdLim = IsPresent(LM_OPTIONS::PRODLIM); + + LMParsedOptions.CrossFlow = IsPresent(LM_OPTIONS::CROSSFLOW); int NFoundCorrelations = 0; if (IsPresent(LM_OPTIONS::MALAN)) { @@ -1287,6 +1313,24 @@ inline LM_ParsedOptions ParseLMOptions(const LM_OPTIONS *LM_Options, unsigned sh SU2_MPI::Error("Two correlations selected for LM_OPTIONS. Please choose only one.", CURRENT_FUNCTION); } + int NFoundCorrelations_SLM = 0; + if (IsPresent(LM_OPTIONS::MENTER_SLM)) { + LMParsedOptions.Correlation_SLM = TURB_TRANS_CORRELATION_SLM::MENTER_SLM; + NFoundCorrelations_SLM++; + } + if (IsPresent(LM_OPTIONS::CODER_SLM)) { + LMParsedOptions.Correlation_SLM = TURB_TRANS_CORRELATION_SLM::CODER_SLM; + NFoundCorrelations_SLM++; + } + if (IsPresent(LM_OPTIONS::MOD_EPPLER_SLM)) { + LMParsedOptions.Correlation_SLM = TURB_TRANS_CORRELATION_SLM::MOD_EPPLER_SLM; + NFoundCorrelations_SLM++; + } + + if (NFoundCorrelations_SLM > 1) { + SU2_MPI::Error("Two correlations selected for Simplified model into LM_OPTIONS. Please choose only one.", CURRENT_FUNCTION); + } + if (LMParsedOptions.Correlation == TURB_TRANS_CORRELATION::DEFAULT){ if (Kind_Turb_Model == TURB_MODEL::SST) { LMParsedOptions.Correlation = TURB_TRANS_CORRELATION::MENTER_LANGTRY; @@ -1295,6 +1339,10 @@ inline LM_ParsedOptions ParseLMOptions(const LM_OPTIONS *LM_Options, unsigned sh } } + if (LMParsedOptions.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::DEFAULT){ + LMParsedOptions.Correlation_SLM = TURB_TRANS_CORRELATION_SLM::MENTER_SLM; + } + return LMParsedOptions; } diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 5ff351cfee5..9517aacacdb 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -3485,7 +3485,7 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i lmParsedOptions = ParseLMOptions(LM_Options, nLM_Options, rank, Kind_Turb_Model); /*--- Check if problem is 2D and LM2015 has been selected ---*/ - if (lmParsedOptions.LM2015 && val_nDim == 2) { + if (lmParsedOptions.CrossFlow && val_nDim == 2) { SU2_MPI::Error("LM2015 is available only for 3D problems", CURRENT_FUNCTION); } } @@ -6180,11 +6180,27 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { switch (Kind_Trans_Model) { case TURB_TRANS_MODEL::NONE: break; case TURB_TRANS_MODEL::LM: { - cout << "Transition model: Langtry and Menter's 4 equation model"; - if (lmParsedOptions.LM2015) { - cout << " w/ cross-flow corrections (2015)" << endl; + int NTurbEqs = 0; + switch (Kind_Turb_Model) { + case TURB_MODEL::SA: NTurbEqs = 1; break; + case TURB_MODEL::SST: NTurbEqs = 2; break; + case TURB_MODEL::NONE: SU2_MPI::Error("No turbulence model has been selected but LM transition model is active.", CURRENT_FUNCTION); break; + } + if (!lmParsedOptions.SLM) { + int NEquations = 2; + cout << "Transition model: Langtry and Menter's "<< NEquations+NTurbEqs <<" equation model"; } else { - cout << " (2009)" << endl; + int NEquations = 1; + cout << "Transition model: Simplified Langtry and Menter's "<< NEquations+NTurbEqs <<" equation model"; + } + if (lmParsedOptions.CrossFlow) { + cout << " w/ cross-flow corrections" << endl; + } else { + if (!lmParsedOptions.SLM) { + cout << " (2009)" << endl; + } else { + cout << " (2015)" << endl; + } } break; } @@ -6208,6 +6224,13 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { } break; } + cout << "Correlation Functions for Simplified LM model: "; + switch (lmParsedOptions.Correlation_SLM) { + case TURB_TRANS_CORRELATION_SLM::CODER_SLM: cout << "Coder et al. (2012)" << endl; break; + case TURB_TRANS_CORRELATION_SLM::MOD_EPPLER_SLM: cout << "Modified Eppler (from Coder et al. 2012)" << endl; break; + case TURB_TRANS_CORRELATION_SLM::MENTER_SLM: + case TURB_TRANS_CORRELATION_SLM::DEFAULT: cout << "Menter et al. (2015)" << endl; break; + } } cout << "Hybrid RANS/LES: "; switch (Kind_HybridRANSLES) { diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index bbdbb0316d0..94238a4259b 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -4021,5 +4021,80 @@ void CGeometry::ComputeWallDistance(const CConfig* const* config_container, CGeo } } } + + su2vector>> WallNormal_container; + WallNormal_container.resize(nZone) = su2vector>(); + for (int iZone = 0; iZone < nZone; iZone++){ + const CConfig* config = config_container[iZone]; + const CGeometry* geometry = geometry_container[iZone][iInst][MESH_0]; + WallNormal_container[iZone].resize(geometry->GetnMarker()); + for (auto iMarker = 0; iMarker < geometry->GetnMarker(); iMarker++){ + if (config->GetViscous_Wall(iMarker)) { + WallNormal_container[iZone][iMarker].resize(geometry->GetnElem_Bound(iMarker), 3); + + // cout << "geometry->nVertex[iMarker] = " << geometry->nVertex[iMarker] << endl; + for (auto iElem = 0u; iElem < geometry->GetnElem_Bound(iMarker); iElem++) { + su2vector NormalHere; + NormalHere.resize(3) = su2double(0.0); + + for (unsigned short iNode = 0; iNode < geometry->bound[iMarker][iElem]->GetnNodes(); iNode++) { + // Extract global coordinate of the node + unsigned long iPointHere = geometry->bound[iMarker][iElem]->GetNode(iNode); + long iVertexHere = geometry->nodes->GetVertex(iPointHere, iMarker); + for (auto iDim = 0u; iDim < 3; iDim++) + NormalHere[iDim] += geometry->vertex[iMarker][iVertexHere]->GetNormal(iDim); + } + + for (auto iDim = 0u; iDim < 3; iDim++) + NormalHere[iDim] /= geometry->bound[iMarker][iElem]->GetnNodes(); + + su2double NormalMag = 0.0; + for (auto iDim = 0u; iDim < 3; iDim++) + NormalMag += NormalHere[iDim]*NormalHere[iDim]; + NormalMag = sqrt(NormalMag); + + for (auto iDim = 0u; iDim < 3; iDim++) + NormalHere[iDim] /= NormalMag; + + for (auto iDim = 0u; iDim < 3; iDim++) + WallNormal_container[iZone][iMarker](iElem, iDim) = NormalHere[iDim]; + + } + } else { + WallNormal_container[iZone][iMarker].resize(1, 3) = su2double(0.0); + } + } + } + + auto normal_i = + make_pair(nZone, [config_container,geometry_container,iInst,WallNormal_container](unsigned long iZone){ + const CConfig* config = config_container[iZone]; + const CGeometry* geometry = geometry_container[iZone][iInst][MESH_0]; + const auto nMarker = geometry->GetnMarker(); + const auto WallNormal = WallNormal_container[iZone]; + + return make_pair( nMarker, [config,geometry,WallNormal](unsigned long iMarker){ + auto nElem_Bou = geometry->GetnElem_Bound(iMarker); + if (!config->GetViscous_Wall(iMarker)) nElem_Bou = 1; + + return make_pair(nElem_Bou, [WallNormal,iMarker](unsigned long iElem){ + const auto dimensions = 3; + + return make_pair(dimensions, [WallNormal,iMarker,iElem](unsigned short iDim){ + + return WallNormal[iMarker](iElem, iDim); + }); + }); + }); + }); + + NdFlattener<4>Normals_Local(normal_i); + NdFlattener<5> Normals_global(Nd_MPI_Environment(), Normals_Local); + + + // use it to update roughnesses + for(int jZone=0; jZonenodes->SetWallNormals(Normals_global); + } } } diff --git a/Common/src/geometry/dual_grid/CPoint.cpp b/Common/src/geometry/dual_grid/CPoint.cpp index f11b7dd8945..34999b1fbd1 100644 --- a/Common/src/geometry/dual_grid/CPoint.cpp +++ b/Common/src/geometry/dual_grid/CPoint.cpp @@ -132,6 +132,8 @@ void CPoint::FullAllocation(unsigned short imesh, const CConfig* config) { RoughnessHeight.resize(npoint) = su2double(0.0); SharpEdge_Distance.resize(npoint) = su2double(0.0); + + Normals.resize(npoint, 3) = su2double(0.0); } void CPoint::SetElems(const vector >& elemsMatrix) { Elem = CCompressedSparsePatternL(elemsMatrix); } diff --git a/SU2_CFD/include/numerics/CNumerics.hpp b/SU2_CFD/include/numerics/CNumerics.hpp index 450112df8f7..9c80ec71ff3 100644 --- a/SU2_CFD/include/numerics/CNumerics.hpp +++ b/SU2_CFD/include/numerics/CNumerics.hpp @@ -729,6 +729,41 @@ class CNumerics { */ su2double GetIntermittencyEff() const { return intermittency_eff_i; } + /*! + * \brief Get the value of the Transition Momentum Thickness Reynolds number from correlations. + * \param[out] Corr_Rec_i - Value of the Transition Momentum Thickness Reynolds number at point i. + */ + inline virtual su2double GetCorr_Rec() {return 0.0;} + + /*! + * \brief Get the value of the Momentum Thickness Reynolds number. + * \param[out] re_t - Value of the Momentum Thickness Reynolds number at point i. + */ + inline virtual su2double GetRe_t() {return 0.0;} + inline virtual su2double GetTu() {return 0.0;} + inline virtual su2double GetLambda_theta() {return 0.0;} + inline virtual su2double Getduds() {return 0.0;} + inline virtual su2double GetRe_v() {return 0.0;} + inline virtual su2double GetProd() {return 0.0;} + inline virtual su2double GetDestr() {return 0.0;} + inline virtual su2double GetF_onset1() {return 0.0;} + inline virtual su2double GetF_onset2() {return 0.0;} + inline virtual su2double GetF_onset3() {return 0.0;} + inline virtual su2double GetF_onset() {return 0.0;} + + /*! + * \brief Set the value of the F2 blending function into SLM transition model. + * \param[in] val_F2 - F2 blending function. + */ + inline virtual void SetF2(su2double val_F2) {} + + /*! + * \brief Set the gradient of the auxiliary variables. + * \param[in] val_auxvar_grad_i - Gradient of the auxiliary variable at point i. + * \param[in] val_auxvar_grad_j - Gradient of the auxiliary variable at point j. + */ + inline virtual void SetAuxVar(su2double val_AuxVar) {} + /*! * \brief Set the gradient of the auxiliary variables. * \param[in] val_auxvar_grad_i - Gradient of the auxiliary variable at point i. diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_convection.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_convection.hpp index 669c3a3dfa4..29ff718cd30 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_convection.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_convection.hpp @@ -38,3 +38,10 @@ template using CUpwSca_TransLM = CUpwSca_TurbSST; +/*! + * \class CUpwSca_TransSLM + * \brief Re-use the SA convective fluxes for the scalar upwind discretization of Simplified LM transition model equations. + * \ingroup ConvDiscr + */ +template +using CUpwSca_TransSLM = CUpwSca_TurbSA; \ No newline at end of file diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp index b8102120701..b16daf7c071 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_correlations.hpp @@ -189,4 +189,109 @@ class TransLMCorrelations { return F_length1; } + + /*! + * \brief Compute Re_theta_c from correlations for the Simplified LM model. + * \param[in] Tu - Turbulence intensity. + * \param[in] du_ds - Streamwise velocity gradient. + * \param[out] rethetac - Corrected value for Re_theta. + */ + su2double ReThetaC_Correlations_SLM(const su2double Tu_L, const su2double lambda_theta, const su2double wall_dist, const su2double VorticityMag, const su2double VelocityMag) const { + + su2double rethetac = 0.0; + + switch (options.Correlation_SLM) { + case TURB_TRANS_CORRELATION_SLM::MENTER_SLM: { + + /*-- Thwaites parameter ---*/ + su2double lambda_theta_local = lambda_theta; + + /*-- Function to sensitize the transition onset to the streamwise pressure gradient ---*/ + su2double FPG = 0.0; + const su2double C_PG1 = 14.68; + const su2double C_PG1_lim = 1.5; + const su2double C_PG2 = -7.34; + const su2double C_PG2_lim = 3.0; + const su2double C_PG3 = 0.0; + if (lambda_theta_local >= 0.0) { + FPG = min(1+ C_PG1 * lambda_theta_local, C_PG1_lim); + } else { + const su2double FirstTerm = C_PG2 * lambda_theta_local; + const su2double SecondTerm = C_PG3 * min(lambda_theta_local + 0.0681, 0.0); + FPG = min(1 + FirstTerm + SecondTerm, C_PG2_lim); + } + + FPG = max(FPG, 0.0); + + const su2double C_TU1 = 100.0; + const su2double C_TU2 = 1000.0; + const su2double C_TU3 = 1.0; + rethetac = C_TU1 + C_TU2 * exp(-C_TU3 * Tu_L * FPG); + + break; + } case TURB_TRANS_CORRELATION_SLM::CODER_SLM: { + + /*-- Local pressure gradient parameter ---*/ + const su2double H_c = max(min(wall_dist * VorticityMag / VelocityMag, 1.1542), 0.3823); + + /*-- Thwaites parameter ---*/ + su2double lambda_theta_local = 0.0; + const su2double H_c_delta = 0.587743 - H_c; + if ( H_c >= 0.587743 ) { + const su2double FirstTerm = 0.1919 * pow(H_c_delta, 3.0); + const su2double SecondTerm = 0.4182 * pow(H_c_delta, 2.0); + const su2double ThirdTerm = 0.2959 * H_c_delta; + lambda_theta_local = FirstTerm + SecondTerm + ThirdTerm; + } else { + const su2double FirstTerm = 4.7596 * pow(H_c_delta, 3.0); + const su2double SecondTerm = -0.3837 * pow(H_c_delta, 2.0); + const su2double ThirdTerm = 0.3575 * H_c_delta; + lambda_theta_local = FirstTerm + SecondTerm + ThirdTerm; + } + + /*-- Function to sensitize the transition onset to the streamwise pressure gradient ---*/ + su2double FPG = 0.0; + if (lambda_theta_local <= 0.0) { + const su2double FirstTerm = -12.986 * lambda_theta_local; + const su2double SecondTerm = -123.66 * pow(lambda_theta_local, 2.0); + const su2double ThirdTerm = -405.689 * pow(lambda_theta_local, 3.0); + FPG = 1 - (FirstTerm + SecondTerm + ThirdTerm) * exp(-pow(Tu_L/1.5,1.5)); + } else { + FPG = 1 + 0.275 * (1 - exp(-35.0 * lambda_theta_local)) * exp(-Tu_L/0.5); + } + + // This is not reported in the paper + //FPG = max(FPG, 0.0); + + if (Tu_L <= 1.3) { + const su2double FirstTerm = -589.428 * Tu_L; + const su2double SecondTerm = 0.2196 / max(pow(Tu_L, 2.0), 1e-12); + rethetac = 1173.51 + FirstTerm + SecondTerm; + } else { + rethetac = 331.50 * pow(Tu_L-0.5658, -0.671); + } + rethetac = rethetac * FPG; + + break; + } case TURB_TRANS_CORRELATION_SLM::MOD_EPPLER_SLM: { + + /*-- Local pressure gradient parameter ---*/ + const su2double H_c = max(min(wall_dist * VorticityMag / VelocityMag, 1.1542), 0.3823); + + /*-- H_32 Shape factor --*/ + const su2double H_32 = 1.515095 + 0.2041 * pow((1.1542 - H_c), 2.0956); + + rethetac = exp(127.94 * pow((H_32-1.515095), 2.0) + 6.774224); + + break; + } + case TURB_TRANS_CORRELATION_SLM::DEFAULT: + SU2_MPI::Error("Transition correlation for Simplified LM model is set to DEFAULT but no default value has ben set in the code.", + CURRENT_FUNCTION); + break; + } + + return rethetac; + } + }; diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_diffusion.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_diffusion.hpp index 50153606860..e5d581b537e 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_diffusion.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_diffusion.hpp @@ -103,3 +103,71 @@ class CAvgGrad_TransLM final : public CAvgGrad_Scalar { } }; + +/*! + * \class CAvgGrad_TransSLM + * \brief Class for computing viscous term using average of gradient with correction (Simplified LM transition model). + * \ingroup ViscDiscr + * \author S. Kang. + */ +template +class CAvgGrad_TransSLM final : public CAvgGrad_Scalar { +private: + using Base = CAvgGrad_Scalar; + using Base::Laminar_Viscosity_i; + using Base::Laminar_Viscosity_j; + using Base::Eddy_Viscosity_i; + using Base::Eddy_Viscosity_j; + using Base::Density_i; + using Base::Density_j; + using Base::ScalarVar_i; + using Base::ScalarVar_j; + using Base::Proj_Mean_GradScalarVar; + using Base::proj_vector_ij; + using Base::Flux; + using Base::Jacobian_i; + using Base::Jacobian_j; + + /*! + * \brief Adds any extra variables to AD + */ + void ExtraADPreaccIn() override {} + + /*! + * \brief LM transition model specific steps in the ComputeResidual method + * \param[in] config - Definition of the particular problem. + */ + void FinishResidualCalc(const CConfig* config) override { + const bool implicit = config->GetKind_TimeIntScheme() == EULER_IMPLICIT; + + /*--- Compute mean effective dynamic viscosity ---*/ + const su2double diff_i_gamma = Laminar_Viscosity_i + Eddy_Viscosity_i; + const su2double diff_j_gamma = Laminar_Viscosity_j + Eddy_Viscosity_j; + + const su2double diff_gamma = 0.5*(diff_i_gamma + diff_j_gamma); + + Flux[0] = diff_gamma*Proj_Mean_GradScalarVar[0]; + + /*--- For Jacobians -> Use of TSL (Thin Shear Layer) approx. to compute derivatives of the gradients ---*/ + if (implicit) { + const su2double proj_on_rho_i = proj_vector_ij/Density_i; + Jacobian_i[0][0] = -diff_gamma*proj_on_rho_i; + + const su2double proj_on_rho_j = proj_vector_ij/Density_j; + Jacobian_j[0][0] = diff_gamma*proj_on_rho_j; + } + } + +public: + /*! + * \brief Constructor of the class. + * \param[in] val_nDim - Number of dimensions of the problem. + * \param[in] val_nVar - Number of variables of the problem. + * \param[in] correct_grad - Whether to correct gradient for skewness. + * \param[in] config - Definition of the particular problem. + */ + CAvgGrad_TransSLM(unsigned short val_nDim, unsigned short val_nVar, bool correct_grad, const CConfig* config) + : CAvgGrad_Scalar(val_nDim, val_nVar, correct_grad, config){ + } + +}; \ No newline at end of file diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp index c1388c2df9c..dd6bae78a81 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_sources.hpp @@ -56,6 +56,17 @@ class CSourcePieceWise_TransLM final : public CNumerics { TURB_FAMILY TurbFamily; su2double hRoughness; + su2double Re_v_Here; + su2double Corr_Rec_Here; + su2double Prod_Here = 0.0; + su2double Destr_Here = 0.0; + su2double F_onset1_Here = 0.0; + su2double F_onset2_Here = 0.0; + su2double F_onset3_Here = 0.0; + su2double F_onset_Here = 0.0; + su2double lambda_theta_Here = 0.0; + su2double duds_Here = 0.0; + su2double IntermittencySep = 1.0; su2double IntermittencyEff = 1.0; @@ -92,7 +103,7 @@ class CSourcePieceWise_TransLM final : public CNumerics { * \return A lightweight const-view (read-only) of the residual/flux and Jacobians. */ ResidualType<> ComputeResidual(const CConfig* config) override { - /*--- ScalarVar[0] = k, ScalarVar[0] = w, TransVar[0] = gamma, and TransVar[0] = ReThetaT ---*/ + /*--- ScalarVar[0] = k, ScalarVar[0] = w, TransVar[0] = gamma, and TransVar[1] = ReThetaT ---*/ /*--- dU/dx = PrimVar_Grad[1][0] ---*/ AD::StartPreacc(); AD::SetPreaccIn(StrainMag_i); @@ -113,7 +124,7 @@ class CSourcePieceWise_TransLM final : public CNumerics { const su2double vel_v = V_i[1 + idx.Velocity()]; const su2double vel_w = (nDim == 3) ? V_i[2 + idx.Velocity()] : 0.0; - const su2double Velocity_Mag = sqrt(vel_u * vel_u + vel_v * vel_v + vel_w * vel_w); + const su2double Velocity_Mag = max(sqrt(vel_u * vel_u + vel_v * vel_v + vel_w * vel_w), 1e-20); AD::SetPreaccIn(V_i[idx.Density()], V_i[idx.LaminarViscosity()], V_i[idx.EddyViscosity()]); @@ -135,6 +146,8 @@ class CSourcePieceWise_TransLM final : public CNumerics { /*--- Corr_RetC correlation*/ const su2double Corr_Rec = TransCorrelations.ReThetaC_Correlations(Tu, TransVar_i[1]); + // AGGIUNTO PER DEBUG + Corr_Rec_Here = Corr_Rec; /*--- F_length correlation*/ const su2double Corr_F_length = TransCorrelations.FLength_Correlations(Tu, TransVar_i[1]); @@ -154,6 +167,9 @@ class CSourcePieceWise_TransLM final : public CNumerics { if (TurbFamily == TURB_FAMILY::SA) R_t = Eddy_Viscosity_i / Laminar_Viscosity_i; const su2double Re_v = Density_i * dist_i * dist_i * StrainMag_i / Laminar_Viscosity_i; + // AGGIUNTO PER DEBUG + Re_v_Here = Re_v; + const su2double F_onset1 = Re_v / (2.193 * Corr_Rec); su2double F_onset2 = 1.0; su2double F_onset3 = 1.0; @@ -166,6 +182,11 @@ class CSourcePieceWise_TransLM final : public CNumerics { F_onset3 = max(2.0 - pow(R_t / 2.5, 3.0), 0.0); } const su2double F_onset = max(F_onset2 - F_onset3, 0.0); + // AGGIUNTO PER DEBUG + F_onset1_Here = F_onset1; + F_onset2_Here = F_onset2; + F_onset3_Here = F_onset3; + F_onset_Here = F_onset; /*-- Gradient of velocity magnitude ---*/ @@ -186,7 +207,7 @@ class CSourcePieceWise_TransLM final : public CNumerics { /*-- Calculate blending function f_theta --*/ su2double time_scale = 500.0 * Laminar_Viscosity_i / Density_i / Velocity_Mag / Velocity_Mag; - if (options.LM2015) + if (options.CrossFlow) time_scale = min(time_scale, Density_i * LocalGridLength_i * LocalGridLength_i / (Laminar_Viscosity_i + Eddy_Viscosity_i)); const su2double theta_bl = TransVar_i[1] * Laminar_Viscosity_i / Density_i / Velocity_Mag; @@ -206,7 +227,7 @@ class CSourcePieceWise_TransLM final : public CNumerics { const su2double f_turb = exp(-pow(R_t / 4, 4)); su2double f_theta_2 = 0.0; - if (options.LM2015) + if (options.CrossFlow) f_theta_2 = min(f_wake * exp(-pow(dist_i / delta, 4.0)), 1.0); /*--- Corr_Ret correlation*/ @@ -245,9 +266,13 @@ class CSourcePieceWise_TransLM final : public CNumerics { Retheta_old = Corr_Ret; } + // DEBUG + lambda_theta_Here = lambda; + duds_Here = du_ds; + /*-- Corr_RetT_SCF Correlations--*/ su2double ReThetat_SCF = 0.0; - if (options.LM2015) { + if (options.CrossFlow) { su2double VelocityNormalized[3]; VelocityNormalized[0] = vel_u / Velocity_Mag; VelocityNormalized[1] = vel_v / Velocity_Mag; @@ -292,13 +317,17 @@ class CSourcePieceWise_TransLM final : public CNumerics { /*-- destruction term of Intermeittency(Gamma) --*/ const su2double Dg = c_a2 * Density_i * VorticityMag * TransVar_i[0] * f_turb * (c_e2 * TransVar_i[0] - 1.0); + // DEBUG + Prod_Here = Pg; + Destr_Here = Dg; + /*-- production term of ReThetaT --*/ const su2double PRethetat = c_theta * Density_i / time_scale * (Corr_Ret - TransVar_i[1]) * (1.0 - f_theta); /*-- destruction term of ReThetaT --*/ // It should not be with the minus sign but I put for consistency su2double DRethetat = 0.0; - if (options.LM2015) + if (options.CrossFlow) DRethetat = -c_theta * (Density_i / time_scale) * c_CF * min(ReThetat_SCF - TransVar_i[1], 0.0) * f_theta_2; /*--- Source ---*/ @@ -313,7 +342,7 @@ class CSourcePieceWise_TransLM final : public CNumerics { Jacobian_i[0][1] = 0.0; Jacobian_i[1][0] = 0.0; Jacobian_i[1][1] = -c_theta / time_scale * (1.0 - f_theta) * Volume; - if (options.LM2015 && ReThetat_SCF - TransVar_i[1] < 0) + if (options.CrossFlow && ReThetat_SCF - TransVar_i[1] < 0) Jacobian_i[1][1] += (c_theta / time_scale) * c_CF * f_theta_2 * Volume; } @@ -322,4 +351,293 @@ class CSourcePieceWise_TransLM final : public CNumerics { return ResidualType<>(Residual, Jacobian_i, nullptr); } + + inline su2double GetRe_v() override {return Re_v_Here;} + inline su2double GetCorr_Rec() override {return Corr_Rec_Here;} + inline su2double GetProd() override {return Prod_Here;} + inline su2double GetDestr() override {return Destr_Here;} + inline su2double GetF_onset1() override {return F_onset1_Here;} + inline su2double GetF_onset2() override {return F_onset2_Here;} + inline su2double GetF_onset3() override {return F_onset3_Here;} + inline su2double GetF_onset() override {return F_onset_Here;} + inline su2double GetLambda_theta() override {return lambda_theta_Here;} + inline su2double Getduds() override {return duds_Here;} + }; + +/*! + * \class CSourcePieceWise_TranSLM + * \brief Class for integrating the source terms of the Simplified LM transition model equations. + * \ingroup SourceDiscr + * \author S. Kang. + */ +template +class CSourcePieceWise_TransSLM final : public CNumerics { + private: + const FlowIndices idx; /*!< \brief Object to manage the access to the flow primitives. */ + + const LM_ParsedOptions options; + + /*--- LM Closure constants ---*/ + const su2double c_e1 = 1.0; + const su2double c_a1 = 2.0; + const su2double c_e2 = 50.0; + const su2double c_a2 = 0.06; + const su2double sigmaf = 1.0; + const su2double s1 = 2.0; + const su2double c_theta = 0.03; + const su2double c_CF = 0.6; + const su2double sigmat = 2.0; + + TURB_FAMILY TurbFamily; + su2double hRoughness; + + su2double IntermittencySep = 1.0; + su2double IntermittencyEff = 1.0; + + su2double Re_t; + su2double Corr_Rec = 1.0; + su2double AuxVar; + su2double F2; + su2double Tu_Here = 0.0; + su2double duds_Here = 0.0; + su2double lambda_theta_Here = 0.0; + su2double Re_v_Here = 0.0; + su2double Prod_Here = 0.0; + su2double Destr_Here = 0.0; + su2double F_onset1_Here = 0.0; + su2double F_onset2_Here = 0.0; + su2double F_onset3_Here = 0.0; + su2double F_onset_Here = 0.0; + + su2double Residual; + su2double* Jacobian_i; + su2double Jacobian_Buffer; // Static storage for the Jacobian (which needs to be pointer for return type). + + TransLMCorrelations TransCorrelations; + + public: + /*! + * \brief Constructor of the class. + * \param[in] val_nDim - Number of dimensions of the problem. + * \param[in] val_nVar - Number of variables of the problem. + * \param[in] config - Definition of the particular problem. + */ + CSourcePieceWise_TransSLM(unsigned short val_nDim, unsigned short val_nVar, const CConfig* config) + : CNumerics(val_nDim, 1, config), idx(val_nDim, config->GetnSpecies()), options(config->GetLMParsedOptions()){ + /*--- "Allocate" the Jacobian using the static buffer. ---*/ + Jacobian_i = &Jacobian_Buffer; + + TurbFamily = TurbModelFamily(config->GetKind_Turb_Model()); + + hRoughness = config->GethRoughness(); + + TransCorrelations.SetOptions(options); + + } + + /*! + * \brief Residual for source term integration. + * \param[in] config - Definition of the particular problem. + * \return A lightweight const-view (read-only) of the residual/flux and Jacobians. + */ + ResidualType<> ComputeResidual(const CConfig* config) override { + /*--- ScalarVar[0] = k, ScalarVar[0] = w, TransVar[0] = gamma ---*/ + /*--- dU/dx = PrimVar_Grad[1][0] ---*/ + AD::StartPreacc(); + AD::SetPreaccIn(StrainMag_i); + AD::SetPreaccIn(ScalarVar_i, nVar); + AD::SetPreaccIn(ScalarVar_Grad_i, nVar, nDim); + AD::SetPreaccIn(TransVar_i, nVar); + AD::SetPreaccIn(TransVar_Grad_i, nVar, nDim); + AD::SetPreaccIn(Volume); + AD::SetPreaccIn(dist_i); + AD::SetPreaccIn(&V_i[idx.Velocity()], nDim); + AD::SetPreaccIn(PrimVar_Grad_i, nDim + idx.Velocity(), nDim); + AD::SetPreaccIn(Vorticity_i, 3); + + su2double VorticityMag = + sqrt(Vorticity_i[0] * Vorticity_i[0] + Vorticity_i[1] * Vorticity_i[1] + Vorticity_i[2] * Vorticity_i[2]); + + const su2double vel_u = V_i[idx.Velocity()]; + const su2double vel_v = V_i[1 + idx.Velocity()]; + const su2double vel_w = (nDim == 3) ? V_i[2 + idx.Velocity()] : 0.0; + + su2double Velocity[nDim]; + Velocity[0] = vel_u; + Velocity[1] = vel_v; + if(nDim == 3) Velocity[2] = vel_w; + + + const su2double Velocity_Mag = max(sqrt(vel_u * vel_u + vel_v * vel_v + vel_w * vel_w), 1e-20); + + AD::SetPreaccIn(V_i[idx.Density()], V_i[idx.LaminarViscosity()], V_i[idx.EddyViscosity()]); + + Density_i = V_i[idx.Density()]; + Laminar_Viscosity_i = V_i[idx.LaminarViscosity()]; + Eddy_Viscosity_i = V_i[idx.EddyViscosity()]; + + Residual = 0.0; + Jacobian_i[0] = 0.0; + + if (dist_i > 1e-10) { + su2double Tu_L = 1.0; + if (TurbFamily == TURB_FAMILY::KW) Tu_L = min(100.0 * sqrt(2.0 * ScalarVar_i[0] / 3.0) / (ScalarVar_i[1]*dist_i), 100.0); + // if (TurbFamily == TURB_FAMILY::KW) Tu_L = min(100.0 * sqrt(2.0 * ScalarVar_i[0] / 3.0) / (Velocity_Mag), 100.0); + if (TurbFamily == TURB_FAMILY::SA) Tu_L = config->GetTurbulenceIntensity_FreeStream() * 100; + + Tu_Here = Tu_L; + + /*--- F_length ---*/ + su2double F_length = 100.0; + + /*--- F_onset ---*/ + su2double R_t = 1.0; + if (TurbFamily == TURB_FAMILY::KW) R_t = Density_i * ScalarVar_i[0] / (Laminar_Viscosity_i * ScalarVar_i[1]); + if (TurbFamily == TURB_FAMILY::SA) R_t = Eddy_Viscosity_i / Laminar_Viscosity_i; + + /*-- Gradient of velocity magnitude ---*/ + + // su2double du_ds = 0.0; + // for (int i = 0; i < nDim; i++) + // for (int j = 0; j < nDim; j++) + // du_ds = du_ds + Velocity[i]*Velocity[j]*PrimVar_Grad_i[i][j]; + + // du_ds = du_ds/(Velocity_Mag*Velocity_Mag); + + // const su2double lambda_theta = -7.57e-3 * du_ds * dist_i * dist_i * Density_i / Laminar_Viscosity_i + 0.0128; + const su2double lambda_theta = max(min(-7.57e-3 * AuxVar * dist_i * dist_i * Density_i / Laminar_Viscosity_i + 0.0128, 1.0), -1.0); + // const su2double lambda_theta = du_ds * dist_i * dist_i * Density_i / Laminar_Viscosity_i; + // duds_Here = du_ds; + duds_Here = AuxVar; + lambda_theta_Here = lambda_theta; + + // const su2double lambda_theta = 7.57e-3 * AuxVar * dist_i * dist_i * Density_i / Laminar_Viscosity_i + 0.0128; + + /*--- Corr_RetC correlation*/ + Re_t = TransCorrelations.ReThetaC_Correlations_SLM(Tu_L, lambda_theta, dist_i, VorticityMag, Velocity_Mag); + Corr_Rec = Re_t; // If the MENTER_SLM correlation is used then they are the same thing + + if (options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::CODER_SLM || options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MOD_EPPLER_SLM) { + // If these correlations are used, then the value of Corr_Rec has to be used instead of the TransVar[1] of the original LM model + F_length = TransCorrelations.FLength_Correlations(Tu_L, Re_t); + Corr_Rec = TransCorrelations.ReThetaC_Correlations(Tu_L, Re_t); + } + + + const su2double Re_v = Density_i * dist_i * dist_i * StrainMag_i / Laminar_Viscosity_i; + Re_v_Here = Re_v; + const su2double F_onset1 = Re_v / (2.2 * Corr_Rec); + su2double F_onset2 = 1.0; + su2double F_onset3 = 1.0; + if (TurbFamily == TURB_FAMILY::KW) { + F_onset2 = min(F_onset1, 2.0); + F_onset3 = max(1.0 - pow(R_t / 3.5, 3.0), 0.0); + } + if (TurbFamily == TURB_FAMILY::SA) { + F_onset2 = min(max(F_onset1, pow(F_onset1, 4.0)), 4.0); + F_onset3 = max(2.0 - pow(R_t / 2.5, 3.0), 0.0); + } + su2double F_onset = max(F_onset2 - F_onset3, 0.0); + + F_onset1_Here = F_onset1; + F_onset2_Here = F_onset2; + F_onset3_Here = F_onset3; + F_onset_Here = F_onset; + + if (options.CrossFlow) { + + // Computation of shape factor + const su2double k = 0.25 - lambda_theta; + const su2double FirstTerm = 4.14 * k; + const su2double SecondTerm = 83.5 * pow(k, 2.0); + const su2double ThirdTerm = 854.0 * pow(k, 3.0); + const su2double ForthTerm = 3337.0 * pow(k, 4.0); + const su2double FifthTerm = 4576.0 * pow(k, 5.0); + const su2double H = min(2.0 + FirstTerm - SecondTerm + ThirdTerm - ForthTerm + FifthTerm, 2.7); + + // Computation of critical cross flow Reynolds number + su2double Re_Crit_CF = 0.0; + if(H < 2.3) { + Re_Crit_CF = 150.0; + } else { + Re_Crit_CF = -(300.0/PI_NUMBER) * atan(0.106/(pow(H-2.3, 2.05))); + } + + // Helicity computation + su2double VelocityNormalized[3]; + VelocityNormalized[0] = vel_u / Velocity_Mag; + VelocityNormalized[1] = vel_v / Velocity_Mag; + if (nDim == 3) VelocityNormalized[2] = vel_w / Velocity_Mag; + + su2double StreamwiseVort = 0.0; + for (auto iDim = 0u; iDim < nDim; iDim++) { + StreamwiseVort += VelocityNormalized[iDim] * Vorticity_i[iDim]; + } + StreamwiseVort = abs(StreamwiseVort); + + const su2double H_CF = StreamwiseVort * dist_i / Velocity_Mag; + + // Computation of Delta_H_CF. Here I have included directly R_t as the ration between turb and lam viscosity + const su2double Delta_H_CF = H_CF * (1.0 + min(R_t, 0.4)); + + // Take into account for roughness + const su2double h_0 = 0.25e-6; + const su2double C_r = 2.0 - pow(0.5, config->GethRoughness()/h_0); + + // Construct Cross flow activation function + const su2double C_CF = 1.0; + const su2double f_CF = (C_CF * C_r * Delta_H_CF * Corr_Rec) / Re_Crit_CF; + const su2double F_onset_CF = min(max(0.0, f_CF - 1.0), 1.0); + + // Adjust onset function for intermittency + F_onset = max(F_onset, F_onset_CF); + + } + + const su2double f_turb = exp(-pow(R_t / 2, 4)); + + /*-- production term of Intermeittency(Gamma) --*/ + const su2double Pg = + F_length * Density_i * StrainMag_i * F_onset * TransVar_i[0] * (1.0 - TransVar_i[0]); + + /*-- destruction term of Intermeittency(Gamma) --*/ + const su2double Dg = c_a2 * Density_i * VorticityMag * TransVar_i[0] * f_turb * (c_e2 * TransVar_i[0] - 1.0); + + Prod_Here = Pg; + Destr_Here = Dg; + + /*--- Source ---*/ + Residual += (Pg - Dg) * Volume; + + /*--- Implicit part ---*/ + Jacobian_i[0] = (F_length * StrainMag_i * F_onset * (1 - 2*TransVar_i[0]) - + c_a2 * VorticityMag * f_turb * (2.0 * c_e2 * TransVar_i[0] - 1.0)) * + Volume; + + } + + AD::SetPreaccOut(Residual, nVar); + AD::EndPreacc(); + + return ResidualType<>(&Residual, &Jacobian_i, nullptr); + + } + + inline su2double GetRe_t() override {return Re_t;} + inline su2double GetCorr_Rec() override {return Corr_Rec;} + inline su2double GetTu() override {return Tu_Here;} + inline su2double GetLambda_theta() override {return lambda_theta_Here;} + inline su2double Getduds() override {return duds_Here;} + inline su2double GetRe_v() override {return Re_v_Here;} + inline su2double GetProd() override {return Prod_Here;} + inline su2double GetDestr() override {return Destr_Here;} + inline su2double GetF_onset1() override {return F_onset1_Here;} + inline su2double GetF_onset2() override {return F_onset2_Here;} + inline su2double GetF_onset3() override {return F_onset3_Here;} + inline su2double GetF_onset() override {return F_onset_Here;} + inline void SetAuxVar(su2double val_AuxVar) override { AuxVar = val_AuxVar;} + // non serve piĆ¹ + inline void SetF2(su2double val_F2) override { F2 = val_F2;} + +}; \ No newline at end of file diff --git a/SU2_CFD/include/numerics/turbulent/turb_sources.hpp b/SU2_CFD/include/numerics/turbulent/turb_sources.hpp index bdf9d0c6fc4..28eab561957 100644 --- a/SU2_CFD/include/numerics/turbulent/turb_sources.hpp +++ b/SU2_CFD/include/numerics/turbulent/turb_sources.hpp @@ -839,6 +839,18 @@ class CSourcePieceWise_TurbSST final : public CNumerics { /*--- LM model coupling with production and dissipation term for k transport equation---*/ if (config->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM) { pk = pk * eff_intermittency; + + // Check if the Prod_lim_k has to be introduced based on input options + if ((config->GetLMParsedOptions()).SLM && (config->GetLMParsedOptions()).Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM) { + const su2double Re_theta_c_lim = 1100.0; + const su2double C_k = 1.0; + const su2double C_SEP = 1.0; + const su2double Re_v = Density_i * dist_i * dist_i * StrainMag_i / Laminar_Viscosity_i; + const su2double F_on_lim = min(max(Re_v/(2.2*Re_theta_c_lim)-1.0, 0.0), 3.0); + const su2double IntermittencyRelated = max(eff_intermittency-0.2, 0.0) * (1.0 - eff_intermittency); + pk = pk + 5*C_k * IntermittencyRelated * F_on_lim * max(3.0*C_SEP*Laminar_Viscosity_i - Eddy_Viscosity_i, 0.0) * StrainMag_i * VorticityMag; + } + dk = min(max(eff_intermittency, 0.1), 1.0) * dk; } diff --git a/SU2_CFD/include/solvers/CTransLMSolver.hpp b/SU2_CFD/include/solvers/CTransLMSolver.hpp index 98595abb266..40515ed5054 100644 --- a/SU2_CFD/include/solvers/CTransLMSolver.hpp +++ b/SU2_CFD/include/solvers/CTransLMSolver.hpp @@ -42,6 +42,7 @@ class CTransLMSolver final : public CTurbSolver { LM_ParsedOptions options; TURB_FAMILY TurbFamily; + bool isSepNeeded; TransLMCorrelations TransCorrelations; diff --git a/SU2_CFD/include/variables/CTransLMVariable.hpp b/SU2_CFD/include/variables/CTransLMVariable.hpp index 96b556f5450..f1c3f280264 100644 --- a/SU2_CFD/include/variables/CTransLMVariable.hpp +++ b/SU2_CFD/include/variables/CTransLMVariable.hpp @@ -40,6 +40,23 @@ class CTransLMVariable final : public CTurbVariable { protected: VectorType Intermittency_Eff; VectorType Intermittency_Sep; + + VectorType Corr_Rec; + VectorType Re_t; + VectorType Tu; + VectorType Lambda_theta; + VectorType duds; + VectorType Re_v; + VectorType Prod; + VectorType Destr; + VectorType F_onset1; + VectorType F_onset2; + VectorType F_onset3; + VectorType F_onset; + + VectorType normal_x; + VectorType normal_y; + VectorType normal_z; public: /*! @@ -70,6 +87,28 @@ class CTransLMVariable final : public CTurbVariable { */ void SetIntermittencyEff(unsigned long iPoint, su2double val_Intermittency_sep) override; + /*! + * \brief Set Value of Transition Momentum Thickness Reynolds number from correlations. + */ + void SetCorr_Rec(unsigned long iPoint, su2double val_Corr_Rec) override; + + /*! + * \brief Set Value of Momentum Thickness Reynolds number from correlations (substitute to the second equation of original LM model). + */ + void SetRe_t(unsigned long iPoint, su2double val_Re_t) override; + void SetTu(unsigned long iPoint, su2double val_Tu) override; + void SetLambda_theta(unsigned long iPoint, su2double val_Lambda_theta) override; + void Setduds(unsigned long iPoint, su2double val_duds) override; + void SetRe_v(unsigned long iPoint, su2double val_Re_v) override; + void SetProd(unsigned long iPoint, su2double val_Prod) override; + void SetDestr(unsigned long iPoint, su2double val_Destr) override; + void SetF_onset1(unsigned long iPoint, su2double val_F_onset1) override; + void SetF_onset2(unsigned long iPoint, su2double val_F_onset2) override; + void SetF_onset3(unsigned long iPoint, su2double val_F_onset3) override; + void SetF_onset(unsigned long iPoint, su2double val_F_onset) override; + void SetNormal(unsigned long iPoint, su2double val_normal_x, su2double val_normal_y, su2double val_normal_z) override; + + /*! * \brief Calculate effective intermittency. */ @@ -80,4 +119,26 @@ class CTransLMVariable final : public CTurbVariable { */ inline su2double GetIntermittencySep(unsigned long iPoint) const override { return Intermittency_Sep(iPoint); } + /*! + * \brief Get Value of Transition Momentum Thickness Reynolds number from correlations. + */ + inline su2double GetCorr_Rec(unsigned long iPoint) const override { return Corr_Rec(iPoint); } + + /*! + * \brief Get Value of Momentum Thickness Reynolds number from correlations (substitute to the second equation of original LM model). + */ + inline su2double GetRe_t(unsigned long iPoint) const override { return Re_t(iPoint); } + inline su2double GetTu(unsigned long iPoint) const override { return Tu(iPoint); } + inline su2double GetLambda_theta(unsigned long iPoint) const override { return Lambda_theta(iPoint); } + inline su2double Getduds(unsigned long iPoint) const override { return duds(iPoint); } + inline su2double GetRe_v(unsigned long iPoint) const override { return Re_v(iPoint); } + inline su2double GetProd(unsigned long iPoint) const override { return Prod(iPoint); } + inline su2double GetDestr(unsigned long iPoint) const override { return Destr(iPoint); } + inline su2double GetF_onset1(unsigned long iPoint) const override { return F_onset1(iPoint); } + inline su2double GetF_onset2(unsigned long iPoint) const override { return F_onset2(iPoint); } + inline su2double GetF_onset3(unsigned long iPoint) const override { return F_onset3(iPoint); } + inline su2double GetF_onset(unsigned long iPoint) const override { return F_onset(iPoint); } + inline su2double GetNormal_x(unsigned long iPoint) const override {return normal_x(iPoint);}; + inline su2double GetNormal_y(unsigned long iPoint) const override {return normal_y(iPoint);}; + inline su2double GetNormal_z(unsigned long iPoint) const override {return normal_z(iPoint);}; }; diff --git a/SU2_CFD/include/variables/CTurbSSTVariable.hpp b/SU2_CFD/include/variables/CTurbSSTVariable.hpp index 8735ddc6de6..d745ca82d71 100644 --- a/SU2_CFD/include/variables/CTurbSSTVariable.hpp +++ b/SU2_CFD/include/variables/CTurbSSTVariable.hpp @@ -45,6 +45,7 @@ class CTurbSSTVariable final : public CTurbVariable { VectorType F2; /*!< \brief Menter blending function for blending of k-w and k-eps. */ VectorType CDkw; /*!< \brief Cross-diffusion. */ SST_ParsedOptions sstParsedOptions; + LM_ParsedOptions lmParsedOptions; public: /*! * \brief Constructor of the class. diff --git a/SU2_CFD/include/variables/CVariable.hpp b/SU2_CFD/include/variables/CVariable.hpp index 358824ae8d7..d48f8839d57 100644 --- a/SU2_CFD/include/variables/CVariable.hpp +++ b/SU2_CFD/include/variables/CVariable.hpp @@ -1689,6 +1689,51 @@ class CVariable { */ inline virtual void SetIntermittencyEff(unsigned long iPoint, su2double val_Intermittency_eff) {} + + /*! + * \brief Set Value of Transition Momentum Thickness Reynolds number from correlations. + */ + inline virtual void SetCorr_Rec(unsigned long iPoint, su2double val_Corr_Rec) {}; + inline virtual void SetTu(unsigned long iPoint, su2double val_Tu) {}; + inline virtual void SetLambda_theta(unsigned long iPoint, su2double val_Lambda_theta) {}; + inline virtual void Setduds(unsigned long iPoint, su2double val_duds) {}; + inline virtual void SetRe_v(unsigned long iPoint, su2double val_Re_v) {}; + inline virtual void SetProd(unsigned long iPoint, su2double val_Prod) {}; + inline virtual void SetDestr(unsigned long iPoint, su2double val_Destr) {}; + inline virtual void SetF_onset1(unsigned long iPoint, su2double val_F_onset1) {}; + inline virtual void SetF_onset2(unsigned long iPoint, su2double val_F_onset2) {}; + inline virtual void SetF_onset3(unsigned long iPoint, su2double val_F_onset3) {}; + inline virtual void SetF_onset(unsigned long iPoint, su2double val_F_onset1) {}; + inline virtual void SetNormal(unsigned long iPoint, su2double val_normal_x, su2double val_normal_y, su2double val_normal_z) {}; + + /*! + * \brief Get Value of Transition Momentum Thickness Reynolds number from correlations. + */ + inline virtual su2double GetCorr_Rec(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetTu(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetLambda_theta(unsigned long iPoint) const { return 0.0; } + inline virtual su2double Getduds(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetRe_v(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetProd(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetDestr(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetF_onset1(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetF_onset2(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetF_onset3(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetF_onset(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetNormal_x(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetNormal_y(unsigned long iPoint) const { return 0.0; } + inline virtual su2double GetNormal_z(unsigned long iPoint) const { return 0.0; } + + /*! + * \brief Set Value of Momentum Thickness Reynolds number from correlations (substitute to the second equation of original LM model). + */ + inline virtual void SetRe_t(unsigned long iPoint, su2double val_Re_t) {}; + + /*! + * \brief Get Value of Momentum Thickness Reynolds number from correlations (substitute to the second equation of original LM model). + */ + inline virtual su2double GetRe_t(unsigned long iPoint) const { return 0.0; } + /*! * \brief Set the value of the eddy viscosity. * \param[in] val_muT diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index 14c478c0f47..0b799282544 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -1333,6 +1333,8 @@ void CDriver::InstantiateTransitionNumerics(unsigned short nVar_Trans, int offse const int visc_bound_term = VISC_BOUND_TERM + offset; const bool LM = config->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM; + LM_ParsedOptions options; + if(LM) options = config->GetLMParsedOptions(); /*--- Definition of the convective scheme for each equation and mesh level ---*/ @@ -1342,7 +1344,10 @@ void CDriver::InstantiateTransitionNumerics(unsigned short nVar_Trans, int offse break; case SPACE_UPWIND : for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - if (LM) numerics[iMGlevel][TRANS_SOL][conv_term] = new CUpwSca_TransLM(nDim, nVar_Trans, config); + if (LM){ + if (!options.SLM) numerics[iMGlevel][TRANS_SOL][conv_term] = new CUpwSca_TransLM(nDim, nVar_Trans, config); + if (options.SLM) numerics[iMGlevel][TRANS_SOL][conv_term] = new CUpwSca_TransSLM(nDim, nVar_Trans, config); + } } break; default: @@ -1353,7 +1358,10 @@ void CDriver::InstantiateTransitionNumerics(unsigned short nVar_Trans, int offse /*--- Definition of the viscous scheme for each equation and mesh level ---*/ for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - if (LM) numerics[iMGlevel][TRANS_SOL][visc_term] = new CAvgGrad_TransLM(nDim, nVar_Trans, true, config); + if (LM){ + if (!options.SLM) numerics[iMGlevel][TRANS_SOL][visc_term] = new CAvgGrad_TransLM(nDim, nVar_Trans, true, config); + if (options.SLM) numerics[iMGlevel][TRANS_SOL][visc_term] = new CAvgGrad_TransSLM(nDim, nVar_Trans, true, config); + } } /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ @@ -1361,7 +1369,10 @@ void CDriver::InstantiateTransitionNumerics(unsigned short nVar_Trans, int offse for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { auto& trans_source_first_term = numerics[iMGlevel][TRANS_SOL][source_first_term]; - if (LM) trans_source_first_term = new CSourcePieceWise_TransLM(nDim, nVar_Trans, config); + if (LM){ + if (!options.SLM) trans_source_first_term = new CSourcePieceWise_TransLM(nDim, nVar_Trans, config); + if (options.SLM) trans_source_first_term = new CSourcePieceWise_TransSLM(nDim, nVar_Trans, config); + } numerics[iMGlevel][TRANS_SOL][source_second_term] = new CSourceNothing(nDim, nVar_Trans, config); } @@ -1369,9 +1380,12 @@ void CDriver::InstantiateTransitionNumerics(unsigned short nVar_Trans, int offse /*--- Definition of the boundary condition method ---*/ for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - if (LM) { + if (!options.SLM) { numerics[iMGlevel][TRANS_SOL][conv_bound_term] = new CUpwSca_TransLM(nDim, nVar_Trans, config); numerics[iMGlevel][TRANS_SOL][visc_bound_term] = new CAvgGrad_TransLM(nDim, nVar_Trans, false, config); + } else { + numerics[iMGlevel][TRANS_SOL][conv_bound_term] = new CUpwSca_TransSLM(nDim, nVar_Trans, config); + numerics[iMGlevel][TRANS_SOL][visc_bound_term] = new CAvgGrad_TransSLM(nDim, nVar_Trans, false, config); } } } diff --git a/SU2_CFD/src/output/CFlowIncOutput.cpp b/SU2_CFD/src/output/CFlowIncOutput.cpp index cd275b8f51e..c70551c14d4 100644 --- a/SU2_CFD/src/output/CFlowIncOutput.cpp +++ b/SU2_CFD/src/output/CFlowIncOutput.cpp @@ -211,7 +211,7 @@ void CFlowIncOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolv SetHistoryOutputValue("MAX_PRESSURE", log10(flow_solver->GetRes_Max(0))); SetHistoryOutputValue("MAX_VELOCITY-X", log10(flow_solver->GetRes_Max(1))); SetHistoryOutputValue("MAX_VELOCITY-Y", log10(flow_solver->GetRes_Max(2))); - if (nDim == 3) SetHistoryOutputValue("RMS_VELOCITY-Z", log10(flow_solver->GetRes_Max(3))); + if (nDim == 3) SetHistoryOutputValue("MAX_VELOCITY-Z", log10(flow_solver->GetRes_Max(3))); if (multiZone){ SetHistoryOutputValue("BGS_PRESSURE", log10(flow_solver->GetRes_BGS(0))); diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index 5ffee0d23f5..bf45c281b0f 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -981,7 +981,10 @@ void CFlowOutput::AddHistoryOutputFields_ScalarRMS_RES(const CConfig* config) { /// DESCRIPTION: Root-mean square residual of the intermittency (LM model). AddHistoryOutput("RMS_INTERMITTENCY", "rms[LM_1]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of intermittency (LM model).", HistoryFieldType::RESIDUAL); /// DESCRIPTION: Root-mean square residual of the momentum thickness Reynolds number (LM model). - AddHistoryOutput("RMS_RE_THETA_T", "rms[LM_2]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of momentum thickness Reynolds number (LM model).", HistoryFieldType::RESIDUAL); + if (!(config->GetLMParsedOptions()).SLM) { + /// DESCRIPTION: Root-mean square residual of the momentum thickness Reynolds number (LM model). + AddHistoryOutput("RMS_RE_THETA_T", "rms[LM_2]", ScreenOutputFormat::FIXED, "RMS_RES", "Root-mean square residual of momentum thickness Reynolds number (LM model).", HistoryFieldType::RESIDUAL); + } break; case TURB_TRANS_MODEL::NONE: break; @@ -1037,7 +1040,10 @@ void CFlowOutput::AddHistoryOutputFields_ScalarMAX_RES(const CConfig* config) { /// DESCRIPTION: Maximum residual of the intermittency (LM model). AddHistoryOutput("MAX_INTERMITTENCY", "max[LM_1]", ScreenOutputFormat::FIXED, "MAX_RES", "Maximum residual of the intermittency (LM model).", HistoryFieldType::RESIDUAL); /// DESCRIPTION: Maximum residual of the momentum thickness Reynolds number (LM model). - AddHistoryOutput("MAX_RE_THETA_T", "max[LM_2]", ScreenOutputFormat::FIXED, "MAX_RES", "Maximum residual of the momentum thickness Reynolds number (LM model).", HistoryFieldType::RESIDUAL); + if (!(config->GetLMParsedOptions()).SLM) { + /// DESCRIPTION: Maximum residual of the momentum thickness Reynolds number (LM model). + AddHistoryOutput("MAX_RE_THETA_T", "max[LM_2]", ScreenOutputFormat::FIXED, "MAX_RES", "Maximum residual of the momentum thickness Reynolds number (LM model).", HistoryFieldType::RESIDUAL); + } break; case TURB_TRANS_MODEL::NONE: @@ -1093,7 +1099,10 @@ void CFlowOutput::AddHistoryOutputFields_ScalarBGS_RES(const CConfig* config) { /// DESCRIPTION: Maximum residual of the intermittency (LM model). AddHistoryOutput("BGS_INTERMITTENCY", "bgs[LM_1]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the intermittency (LM model).", HistoryFieldType::RESIDUAL); /// DESCRIPTION: Maximum residual of the momentum thickness Reynolds number (LM model). - AddHistoryOutput("BGS_RE_THETA_T", "bgs[LM_2]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the momentum thickness Reynolds number (LM model).", HistoryFieldType::RESIDUAL); + if (!(config->GetLMParsedOptions()).SLM) { + /// DESCRIPTION: Maximum residual of the momentum thickness Reynolds number (LM model). + AddHistoryOutput("BGS_RE_THETA_T", "bgs[LM_2]", ScreenOutputFormat::FIXED, "BGS_RES", "BGS residual of the momentum thickness Reynolds number (LM model).", HistoryFieldType::RESIDUAL); + } break; case TURB_TRANS_MODEL::NONE: break; @@ -1186,10 +1195,15 @@ void CFlowOutput::LoadHistoryDataScalar(const CConfig* config, const CSolver* co SetHistoryOutputValue("RMS_INTERMITTENCY", log10(solver[TRANS_SOL]->GetRes_RMS(0))); SetHistoryOutputValue("RMS_RE_THETA_T",log10(solver[TRANS_SOL]->GetRes_RMS(1))); SetHistoryOutputValue("MAX_INTERMITTENCY", log10(solver[TRANS_SOL]->GetRes_Max(0))); - SetHistoryOutputValue("MAX_RE_THETA_T", log10(solver[TRANS_SOL]->GetRes_Max(1))); + if (!(config->GetLMParsedOptions()).SLM) { + SetHistoryOutputValue("RMS_RE_THETA_T",log10(solver[TRANS_SOL]->GetRes_RMS(1))); + SetHistoryOutputValue("MAX_RE_THETA_T", log10(solver[TRANS_SOL]->GetRes_Max(1))); + } if (multiZone) { SetHistoryOutputValue("BGS_INTERMITTENCY", log10(solver[TRANS_SOL]->GetRes_BGS(0))); - SetHistoryOutputValue("BGS_RE_THETA_T", log10(solver[TRANS_SOL]->GetRes_BGS(1))); + if (!(config->GetLMParsedOptions()).SLM) { + SetHistoryOutputValue("BGS_RE_THETA_T", log10(solver[TRANS_SOL]->GetRes_BGS(1))); + } } SetHistoryOutputValue("LINSOL_ITER_TRANS", solver[TRANS_SOL]->GetIterLinSolver()); SetHistoryOutputValue("LINSOL_RESIDUAL_TRANS", log10(solver[TRANS_SOL]->GetResLinSolver())); @@ -1262,6 +1276,33 @@ void CFlowOutput::SetVolumeOutputFieldsScalarSolution(const CConfig* config){ case TURB_TRANS_MODEL::LM: AddVolumeOutput("INTERMITTENCY", "LM_gamma", "SOLUTION", "LM intermittency"); AddVolumeOutput("RE_THETA_T", "LM_Re_t", "SOLUTION", "LM RE_THETA_T"); + AddVolumeOutput("RE_V", "Re_v", "DEBUG", "LM Re_v"); + AddVolumeOutput("RE_THETA_CORR", "LM_Corr_Rec", "DEBUG", "LM RE_THETA_CORR"); + AddVolumeOutput("PROD", "LM_Prod", "DEBUG", "LM PROD"); + AddVolumeOutput("DESTR", "LM_Destr", "DEBUG", "LM DESTR"); + AddVolumeOutput("F_ONSET1", "LM_F_onset1", "DEBUG", "LM F_ONSET1"); + AddVolumeOutput("F_ONSET2", "LM_F_onset2", "DEBUG", "LM F_ONSET2"); + AddVolumeOutput("F_ONSET3", "LM_F_onset3", "DEBUG", "LM F_ONSET3"); + AddVolumeOutput("F_ONSET", "LM_F_onset", "DEBUG", "LM F_ONSET"); + AddVolumeOutput("STRAINMAG", "StrainMag", "DEBUG", "LM STRAINMAG"); + AddVolumeOutput("LAMBDA_THETA", "Lambda_theta", "DEBUG", "LM Lambda_theta"); + AddVolumeOutput("DU_DS", "du_ds", "DEBUG", "LM du_ds"); + if ((config->GetLMParsedOptions()).SLM) { + AddVolumeOutput("TU", "Tu", "SOLUTION", "LM Tu"); + AddVolumeOutput("NORMAL_X", "Normal_x", "DEBUG", "LM Normal_x"); + AddVolumeOutput("NORMAL_Y", "Normal_y", "DEBUG", "LM Normal_y"); + AddVolumeOutput("NORMAL_Z", "Normal_z", "DEBUG", "LM Normal_z"); + if (!((config->GetLMParsedOptions()).Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM)) { + AddVolumeOutput("INTERMITTENCY_SEP", "LM_gamma_sep", "PRIMITIVE", "LM intermittency"); + AddVolumeOutput("INTERMITTENCY_EFF", "LM_gamma_eff", "PRIMITIVE", "LM RE_THETA_T"); + } + } + + if (!(config->GetLMParsedOptions()).SLM) { + AddVolumeOutput("INTERMITTENCY_SEP", "LM_gamma_sep", "PRIMITIVE", "LM intermittency"); + AddVolumeOutput("INTERMITTENCY_EFF", "LM_gamma_eff", "PRIMITIVE", "LM RE_THETA_T"); + } + AddVolumeOutput("TURB_INDEX", "Turb_index", "PRIMITIVE", "Turbulence index"); break; case TURB_TRANS_MODEL::NONE: @@ -1334,7 +1375,9 @@ void CFlowOutput::SetVolumeOutputFieldsScalarResidual(const CConfig* config) { switch (config->GetKind_Trans_Model()) { case TURB_TRANS_MODEL::LM: AddVolumeOutput("RES_INTERMITTENCY", "Residual_LM_intermittency", "RESIDUAL", "Residual of LM intermittency"); - AddVolumeOutput("RES_RE_THETA_T", "Residual_LM_RE_THETA_T", "RESIDUAL", "Residual of LM RE_THETA_T"); + if (!(config->GetLMParsedOptions()).SLM) { + AddVolumeOutput("RES_RE_THETA_T", "Residual_LM_RE_THETA_T", "RESIDUAL", "Residual of LM RE_THETA_T"); + } break; case TURB_TRANS_MODEL::NONE: @@ -1553,12 +1596,39 @@ void CFlowOutput::LoadVolumeDataScalar(const CConfig* config, const CSolver* con switch (config->GetKind_Trans_Model()) { case TURB_TRANS_MODEL::LM: SetVolumeOutputValue("INTERMITTENCY", iPoint, Node_Trans->GetSolution(iPoint, 0)); - SetVolumeOutputValue("RE_THETA_T", iPoint, Node_Trans->GetSolution(iPoint, 1)); - SetVolumeOutputValue("INTERMITTENCY_SEP", iPoint, Node_Trans->GetIntermittencySep(iPoint)); - SetVolumeOutputValue("INTERMITTENCY_EFF", iPoint, Node_Trans->GetIntermittencyEff(iPoint)); + SetVolumeOutputValue("RE_V", iPoint, Node_Trans->GetRe_v(iPoint)); + SetVolumeOutputValue("RE_THETA_CORR", iPoint, Node_Trans->GetCorr_Rec(iPoint)); + SetVolumeOutputValue("PROD", iPoint, Node_Trans->GetProd(iPoint)); + SetVolumeOutputValue("DESTR", iPoint, Node_Trans->GetDestr(iPoint)); + SetVolumeOutputValue("F_ONSET1", iPoint, Node_Trans->GetF_onset1(iPoint)); + SetVolumeOutputValue("F_ONSET2", iPoint, Node_Trans->GetF_onset2(iPoint)); + SetVolumeOutputValue("F_ONSET3", iPoint, Node_Trans->GetF_onset3(iPoint)); + SetVolumeOutputValue("F_ONSET", iPoint, Node_Trans->GetF_onset(iPoint)); + SetVolumeOutputValue("STRAINMAG", iPoint, Node_Flow->GetStrainMag(iPoint)); + SetVolumeOutputValue("LAMBDA_THETA", iPoint, Node_Trans->GetLambda_theta(iPoint)); + SetVolumeOutputValue("DU_DS", iPoint, Node_Trans->Getduds(iPoint)); + if (!(config->GetLMParsedOptions()).SLM) { + SetVolumeOutputValue("RE_THETA_T", iPoint, Node_Trans->GetSolution(iPoint, 1)); + } else { + SetVolumeOutputValue("RE_THETA_T", iPoint, Node_Trans->GetRe_t(iPoint)); + SetVolumeOutputValue("TU", iPoint, Node_Trans->GetTu(iPoint)); + SetVolumeOutputValue("NORMAL_X", iPoint, Node_Trans->GetNormal_x(iPoint)); + SetVolumeOutputValue("NORMAL_Y", iPoint, Node_Trans->GetNormal_y(iPoint)); + SetVolumeOutputValue("NORMAL_Z", iPoint, Node_Trans->GetNormal_z(iPoint)); + if (!((config->GetLMParsedOptions()).Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM)) { + SetVolumeOutputValue("INTERMITTENCY_SEP", iPoint, Node_Trans->GetIntermittencySep(iPoint)); + SetVolumeOutputValue("INTERMITTENCY_EFF", iPoint, Node_Trans->GetIntermittencyEff(iPoint)); + } + } + if (!(config->GetLMParsedOptions()).SLM) { + SetVolumeOutputValue("INTERMITTENCY_SEP", iPoint, Node_Trans->GetIntermittencySep(iPoint)); + SetVolumeOutputValue("INTERMITTENCY_EFF", iPoint, Node_Trans->GetIntermittencyEff(iPoint)); + } SetVolumeOutputValue("TURB_INDEX", iPoint, Node_Turb->GetTurbIndex(iPoint)); SetVolumeOutputValue("RES_INTERMITTENCY", iPoint, trans_solver->LinSysRes(iPoint, 0)); - SetVolumeOutputValue("RES_RE_THETA_T", iPoint, trans_solver->LinSysRes(iPoint, 1)); + if (!(config->GetLMParsedOptions()).SLM) { + SetVolumeOutputValue("RES_RE_THETA_T", iPoint, trans_solver->LinSysRes(iPoint, 1)); + } break; case TURB_TRANS_MODEL::NONE: break; @@ -2667,7 +2737,7 @@ void CFlowOutput::WriteForcesBreakdown(const CConfig* config, const CSolver* flo case TURB_TRANS_MODEL::NONE: break; case TURB_TRANS_MODEL::LM: file << "Langtry and Menter's transition"; - if (config->GetLMParsedOptions().LM2015) { + if (config->GetLMParsedOptions().CrossFlow) { file << " w/ cross-flow corrections (2015)\n"; } else { file << " (2009)\n"; diff --git a/SU2_CFD/src/solvers/CTransLMSolver.cpp b/SU2_CFD/src/solvers/CTransLMSolver.cpp index 1fdf2a47de1..a6d99018115 100644 --- a/SU2_CFD/src/solvers/CTransLMSolver.cpp +++ b/SU2_CFD/src/solvers/CTransLMSolver.cpp @@ -49,6 +49,14 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh /*--- Dimension of the problem --> 2 Transport equations (intermittency, Reth) ---*/ nVar = 2; nPrimVar = 2; + + /*--- Check if Simplified version is used ---*/ + options = config->GetLMParsedOptions(); + if (options.SLM) { + nVar = 1; + nPrimVar = 1; + } + nPoint = geometry->GetnPoint(); nPointDomain = geometry->GetnPointDomain(); @@ -65,6 +73,11 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh TransCorrelations.SetOptions(options); TurbFamily = TurbModelFamily(config->GetKind_Turb_Model()); + isSepNeeded = true; + // If the Simplified model is used coupled with SST then we do not need the separation induced intermittency + // due to the added production term to k equation + if (options.SLM && options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM) isSepNeeded = false; + /*--- Single grid simulation ---*/ if (iMesh == MESH_0) { @@ -101,8 +114,10 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh lowerlimit[0] = 1.0e-4; upperlimit[0] = 5.0; - lowerlimit[1] = 1.0e-4; - upperlimit[1] = 1.0e15; + if (!options.SLM) { + lowerlimit[1] = 1.0e-4; + upperlimit[1] = 1.0e15; + } /*--- Far-field flow state quantities and initialization. ---*/ const su2double Intensity = config->GetTurbulenceIntensity_FreeStream()*100.0; @@ -124,7 +139,9 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh } Solution_Inf[0] = Intermittency_Inf; - Solution_Inf[1] = ReThetaT_Inf; + if (!options.SLM) { + Solution_Inf[1] = ReThetaT_Inf; + } /*--- Initialize the solution to the far-field state everywhere. ---*/ nodes = new CTransLMVariable(Intermittency_Inf, ReThetaT_Inf, 1.0, 1.0, nPoint, nDim, nVar, config); @@ -155,7 +172,7 @@ CTransLMSolver::CTransLMSolver(CGeometry *geometry, CConfig *config, unsigned sh Inlet_TurbVars[iMarker].resize(nVertex[iMarker],nVar); for (unsigned long iVertex = 0; iVertex < nVertex[iMarker]; ++iVertex) { Inlet_TurbVars[iMarker](iVertex,0) = Intermittency_Inf; - Inlet_TurbVars[iMarker](iVertex,1) = ReThetaT_Inf; + if (!options.SLM) Inlet_TurbVars[iMarker](iVertex,1) = ReThetaT_Inf; } } @@ -178,6 +195,38 @@ void CTransLMSolver::Preprocessing(CGeometry *geometry, CSolver **solver_contain /*--- Upwind second order reconstruction and gradients ---*/ CommonPreprocessing(geometry, config, Output); + + if (options.SLM && options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM) { + + auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); + SU2_OMP_FOR_STAT(omp_chunk_size) + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { + auto Normal = geometry->nodes->GetNormal(iPoint); + nodes->SetAuxVar(iPoint, 0, flowNodes->GetProjVel(iPoint, Normal)); + nodes->SetNormal(iPoint, Normal[0], Normal[1], Normal[2]); + } + END_SU2_OMP_FOR + + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { + SetAuxVar_Gradient_GG(geometry, config); + } + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + SetAuxVar_Gradient_LS(geometry, config); + } + + + SU2_OMP_FOR_STAT(omp_chunk_size) + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { + su2double AuxVarHere = 0.0; + auto Normal = geometry->nodes->GetNormal(iPoint); + for (auto iDim = 0u; iDim < nDim; iDim++) + AuxVarHere += Normal[iDim] * nodes->GetAuxVarGradient(iPoint, 0, iDim); + nodes->SetAuxVar(iPoint, 0, AuxVarHere); + } + END_SU2_OMP_FOR + + } + } void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh) { @@ -191,73 +240,103 @@ void CTransLMSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai SetSolution_Gradient_LS(geometry, config); } + AD::StartNoSharedReading(); - auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); - auto* turbNodes = su2staticcast_p(solver_container[TURB_SOL]->GetNodes()); - - SU2_OMP_FOR_STAT(omp_chunk_size) - for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { - - // Here the nodes already have the new solution, thus I have to compute everything from scratch - - const su2double rho = flowNodes->GetDensity(iPoint); - const su2double mu = flowNodes->GetLaminarViscosity(iPoint); - const su2double muT = turbNodes->GetmuT(iPoint); - const su2double dist = geometry->nodes->GetWall_Distance(iPoint); - su2double VorticityMag = GeometryToolbox::Norm(3, flowNodes->GetVorticity(iPoint)); - su2double StrainMag =flowNodes->GetStrainMag(iPoint); - VorticityMag = max(VorticityMag, 1e-12); - StrainMag = max(StrainMag, 1e-12); // safety against division by zero - const su2double Intermittency = nodes->GetSolution(iPoint,0); - const su2double Re_t = nodes->GetSolution(iPoint,1); - const su2double Re_v = rho*dist*dist*StrainMag/mu; - const su2double vel_u = flowNodes->GetVelocity(iPoint, 0); - const su2double vel_v = flowNodes->GetVelocity(iPoint, 1); - const su2double vel_w = (nDim ==3) ? flowNodes->GetVelocity(iPoint, 2) : 0.0; - const su2double VelocityMag = sqrt(vel_u*vel_u + vel_v*vel_v + vel_w*vel_w); - su2double omega = 0.0; - su2double k = 0.0; - if(TurbFamily == TURB_FAMILY::KW){ - omega = turbNodes->GetSolution(iPoint,1); - k = turbNodes->GetSolution(iPoint,0); - } - su2double Tu = 1.0; - if(TurbFamily == TURB_FAMILY::KW) - Tu = max(100.0*sqrt( 2.0 * k / 3.0 ) / VelocityMag,0.027); - if(TurbFamily == TURB_FAMILY::SA) - Tu = config->GetTurbulenceIntensity_FreeStream()*100; - - const su2double Corr_Rec = TransCorrelations.ReThetaC_Correlations(Tu, Re_t); - - su2double R_t = 1.0; - if(TurbFamily == TURB_FAMILY::KW) - R_t = rho*k/ mu/ omega; - if(TurbFamily == TURB_FAMILY::SA) - R_t = muT/ mu; - - const su2double f_reattach = exp(-pow(R_t/20,4)); - su2double f_wake = 0.0; - if(TurbFamily == TURB_FAMILY::KW){ - const su2double re_omega = rho*omega*dist*dist/mu; - f_wake = exp(-pow(re_omega/(1.0e+05),2)); + + if(isSepNeeded){ + + AD::StartNoSharedReading(); + auto* flowNodes = su2staticcast_p(solver_container[FLOW_SOL]->GetNodes()); + auto* turbNodes = su2staticcast_p(solver_container[TURB_SOL]->GetNodes()); + + SU2_OMP_FOR_STAT(omp_chunk_size) + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { + + // Here the nodes already have the new solution, thus I have to compute everything from scratch + + const su2double rho = flowNodes->GetDensity(iPoint); + const su2double mu = flowNodes->GetLaminarViscosity(iPoint); + const su2double muT = turbNodes->GetmuT(iPoint); + const su2double dist = geometry->nodes->GetWall_Distance(iPoint); + su2double VorticityMag = GeometryToolbox::Norm(3, flowNodes->GetVorticity(iPoint)); + su2double StrainMag =flowNodes->GetStrainMag(iPoint); + VorticityMag = max(VorticityMag, 1e-12); + StrainMag = max(StrainMag, 1e-12); // safety against division by zero + const su2double Intermittency = nodes->GetSolution(iPoint,0); + const su2double Re_v = rho*dist*dist*StrainMag/mu; + const su2double VelocityMag = max(sqrt(flowNodes->GetVelocity2(iPoint)), 1e-20); + su2double omega = 0.0; + su2double k = 0.0; + if(TurbFamily == TURB_FAMILY::KW){ + omega = turbNodes->GetSolution(iPoint,1); + k = turbNodes->GetSolution(iPoint,0); + } + + su2double Re_t = 0.0; + su2double Corr_Rec = 0.0; + + if (options.SLM) { + Re_t = nodes->GetRe_t(iPoint); + Corr_Rec = nodes->GetCorr_Rec(iPoint); + } else { + Re_t = nodes->GetSolution(iPoint,1); + su2double Tu = 1.0; + if(TurbFamily == TURB_FAMILY::KW) + Tu = max(100.0*sqrt( 2.0 * k / 3.0 ) / VelocityMag,0.027); + if(TurbFamily == TURB_FAMILY::SA) + Tu = config->GetTurbulenceIntensity_FreeStream()*100; + + Corr_Rec = TransCorrelations.ReThetaC_Correlations(Tu, Re_t); + } + + + // cout << Re_t << " " << Corr_Rec << endl; + // if (geometry->nodes->GetDomain(iPoint)) cout << "Point is on boundary" << endl; + + su2double R_t = 1.0; + if(TurbFamily == TURB_FAMILY::KW) + R_t = rho*k/ mu/ omega; + if(TurbFamily == TURB_FAMILY::SA) + R_t = muT/ mu; + + const su2double f_reattach = exp(-pow(R_t/20,4)); + + su2double f_wake = 0.0; + if(TurbFamily == TURB_FAMILY::KW){ + const su2double re_omega = rho*omega*dist*dist/mu; + f_wake = exp(-pow(re_omega/(1.0e+05),2)); + } + if(TurbFamily == TURB_FAMILY::SA) + f_wake = 1.0; + + //cout << "StrainMag = " << StrainMag << " rho = " << rho << " dist = " << dist << " Re_v = " << Re_v << " Corr_Rec = " << Corr_Rec << endl; + + const su2double theta_bl = Re_t*mu / rho /VelocityMag; + const su2double delta_bl = 7.5*theta_bl; + const su2double delta = 50.0*VorticityMag*dist/VelocityMag*delta_bl + 1e-20; + const su2double var1 = (Intermittency-1.0/50.0)/(1.0-1.0/50.0); + const su2double var2 = 1.0 - pow(var1,2.0); + const su2double f_theta = min(max(f_wake*exp(-pow(dist/delta, 4)), var2), 1.0); + su2double Intermittency_Sep = 2.0*max(0.0, Re_v/(3.235*Corr_Rec)-1.0)*f_reattach; + //if (Intermittency_Sep>1.0) cout << "StrainMag = " << StrainMag << " rho = " << rho << " dist = " << dist << " Re_v = " << Re_v << " Corr_Rec = " << Corr_Rec << " Intermittency: " << Intermittency_Sep << " f_reattach = " << f_reattach << endl; + Intermittency_Sep = min(Intermittency_Sep,2.0)*f_theta; + Intermittency_Sep = min(max(0.0, Intermittency_Sep), 2.0); + nodes -> SetIntermittencySep(iPoint, Intermittency_Sep); + nodes -> SetIntermittencyEff(iPoint, Intermittency_Sep); + } - if(TurbFamily == TURB_FAMILY::SA) - f_wake = 1.0; - - const su2double theta_bl = Re_t*mu / rho /VelocityMag; - const su2double delta_bl = 7.5*theta_bl; - const su2double delta = 50.0*VorticityMag*dist/VelocityMag*delta_bl + 1e-20; - const su2double var1 = (Intermittency-1.0/50.0)/(1.0-1.0/50.0); - const su2double var2 = 1.0 - pow(var1,2.0); - const su2double f_theta = min(max(f_wake*exp(-pow(dist/delta, 4)), var2), 1.0); - su2double Intermittency_Sep = 2.0*max(0.0, Re_v/(3.235*Corr_Rec)-1.0)*f_reattach; - Intermittency_Sep = min(Intermittency_Sep,2.0)*f_theta; - Intermittency_Sep = min(max(0.0, Intermittency_Sep), 2.0); - nodes -> SetIntermittencySep(iPoint, Intermittency_Sep); - nodes -> SetIntermittencyEff(iPoint, Intermittency_Sep); + END_SU2_OMP_FOR } - END_SU2_OMP_FOR + else { + + // Effective intermittency and separation intermittency are not taken into account here! There is the added production term in the k-equation + SU2_OMP_FOR_STAT(omp_chunk_size) + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint ++) { + nodes -> SetIntermittencyEff(iPoint, nodes->GetSolution(iPoint,0)); + } + END_SU2_OMP_FOR + } AD::EndNoSharedReading(); } @@ -333,15 +412,36 @@ void CTransLMSolver::Source_Residual(CGeometry *geometry, CSolver **solver_conta /*--- Set coordinate (for debugging) ---*/ numerics->SetCoord(geometry->nodes->GetCoord(iPoint), nullptr); - if (options.LM2015) { + if (options.CrossFlow && !options.SLM) { /*--- Set local grid length (for LM2015)*/ numerics->SetLocalGridLength(geometry->nodes->GetMaxLength(iPoint)); } + if(options.SLM) { + if (options.Correlation_SLM == TURB_TRANS_CORRELATION_SLM::MENTER_SLM) numerics->SetAuxVar(nodes->GetAuxVar(iPoint, 0)); + numerics->SetF2(turbNodes->GetF2blending(iPoint)); + } + /*--- Compute the source term ---*/ auto residual = numerics->ComputeResidual(config); + if(options.SLM) { + nodes->SetRe_t(iPoint, numerics->GetRe_t()); + nodes->SetTu(iPoint, numerics->GetTu()); + } + + nodes->SetRe_v(iPoint, numerics->GetRe_v()); + nodes->SetCorr_Rec(iPoint, numerics->GetCorr_Rec()); + nodes->SetProd(iPoint, numerics->GetProd()); + nodes->SetDestr(iPoint, numerics->GetDestr()); + nodes->SetF_onset1(iPoint, numerics->GetF_onset1()); + nodes->SetF_onset2(iPoint, numerics->GetF_onset2()); + nodes->SetF_onset3(iPoint, numerics->GetF_onset3()); + nodes->SetF_onset(iPoint, numerics->GetF_onset()); + nodes->SetLambda_theta(iPoint, numerics->GetLambda_theta()); + nodes->Setduds(iPoint, numerics->Getduds()); + /*--- Subtract residual and the Jacobian ---*/ LinSysRes.SubtractBlock(iPoint, residual); diff --git a/SU2_CFD/src/solvers/CTurbSASolver.cpp b/SU2_CFD/src/solvers/CTurbSASolver.cpp index f53596e9901..6de6dd03ac3 100644 --- a/SU2_CFD/src/solvers/CTurbSASolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSASolver.cpp @@ -269,7 +269,7 @@ void CTurbSASolver::Postprocessing(CGeometry *geometry, CSolver **solver_contain } shearStress = sqrt(shearStress); - FrictionVelocity = sqrt(shearStress/flowNodes->GetDensity(iPoint)); + FrictionVelocity = sqrt(shearStress/max(flowNodes->GetDensity(iPoint), 1e-20)); } else { su2double VorticityMag = max(GeometryToolbox::Norm(3, flowNodes->GetVorticity(iPoint)), 1e-12); FrictionVelocity = sqrt(flowNodes->GetLaminarViscosity(iPoint)*VorticityMag); diff --git a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp index 555f8e77155..d99b294f138 100644 --- a/SU2_CFD/src/solvers/CTurbSSTSolver.cpp +++ b/SU2_CFD/src/solvers/CTurbSSTSolver.cpp @@ -259,10 +259,10 @@ void CTurbSSTSolver::Postprocessing(CGeometry *geometry, CSolver **solver_contai } shearStress = sqrt(shearStress); - const su2double FrictionVelocity = sqrt(shearStress/flowNodes->GetDensity(iPoint)); + const su2double FrictionVelocity = sqrt(shearStress/max(flowNodes->GetDensity(iPoint),1e-20)); const su2double wall_dist = geometry->nodes->GetWall_Distance(jPoint); const su2double Derivative = flowNodes->GetLaminarViscosity(jPoint) * pow(nodes->GetSolution(jPoint, 0), 0.673) / wall_dist; - const su2double turbulence_index = 6.1 * Derivative / pow(FrictionVelocity, 2.346); + const su2double turbulence_index = 6.1 * Derivative / max(pow(FrictionVelocity, 2.346),1e-20); nodes->SetTurbIndex(iPoint, turbulence_index); diff --git a/SU2_CFD/src/variables/CTransLMVariable.cpp b/SU2_CFD/src/variables/CTransLMVariable.cpp index 551968b1c35..dca6f89113b 100644 --- a/SU2_CFD/src/variables/CTransLMVariable.cpp +++ b/SU2_CFD/src/variables/CTransLMVariable.cpp @@ -31,10 +31,19 @@ CTransLMVariable::CTransLMVariable(su2double Intermittency, su2double ReThetaT, su2double gammaSep, su2double gammaEff, unsigned long npoint, unsigned long ndim, unsigned long nvar, CConfig *config) : CTurbVariable(npoint, ndim, nvar, config) { - for(unsigned long iPoint=0; iPointGetLMParsedOptions(); + + if (!options.SLM) { + for(unsigned long iPoint=0; iPointGetSSTParsedOptions(); + lmParsedOptions = config->GetLMParsedOptions(); for(unsigned long iPoint=0; iPoint Date: Mon, 1 Jul 2024 10:57:57 +0200 Subject: [PATCH 19/20] - corrected bu in output --- SU2_CFD/src/output/CFlowOutput.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index bf45c281b0f..baafc717594 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -1193,7 +1193,6 @@ void CFlowOutput::LoadHistoryDataScalar(const CConfig* config, const CSolver* co switch (config->GetKind_Trans_Model()) { case TURB_TRANS_MODEL::LM: SetHistoryOutputValue("RMS_INTERMITTENCY", log10(solver[TRANS_SOL]->GetRes_RMS(0))); - SetHistoryOutputValue("RMS_RE_THETA_T",log10(solver[TRANS_SOL]->GetRes_RMS(1))); SetHistoryOutputValue("MAX_INTERMITTENCY", log10(solver[TRANS_SOL]->GetRes_Max(0))); if (!(config->GetLMParsedOptions()).SLM) { SetHistoryOutputValue("RMS_RE_THETA_T",log10(solver[TRANS_SOL]->GetRes_RMS(1))); From a6fe9bca59ce02409b3b80c2d80f57fb1a7bbcb5 Mon Sep 17 00:00:00 2001 From: rois1995 Date: Fri, 13 Sep 2024 14:54:12 +0200 Subject: [PATCH 20/20] - finish update --- Common/include/geometry/dual_grid/CPoint.hpp | 39 ----------- .../turbulent/transition/trans_diffusion.hpp | 68 ------------------- SU2_CFD/include/variables/CVariable.hpp | 45 ------------ externals/codi | 2 +- externals/medi | 2 +- externals/mel | 2 +- externals/opdi | 2 +- subprojects/CoolProp | 2 +- 8 files changed, 5 insertions(+), 157 deletions(-) diff --git a/Common/include/geometry/dual_grid/CPoint.hpp b/Common/include/geometry/dual_grid/CPoint.hpp index 79d5c2076c1..ae725fea258 100644 --- a/Common/include/geometry/dual_grid/CPoint.hpp +++ b/Common/include/geometry/dual_grid/CPoint.hpp @@ -514,27 +514,6 @@ class CPoint { inline su2double& GetWall_Distance(unsigned long iPoint) { return Wall_Distance(iPoint); } inline const su2double& GetWall_Distance(unsigned long iPoint) const { return Wall_Distance(iPoint); } - /*! - * \brief Get the index of the closest wall element. - * \param[in] iPoint - Index of the point. - * \param[out] ClosestWall_Elem - ID of the closest element on a wall boundary. - */ - inline unsigned long GetClosestWall_Elem(unsigned long iPoint) {return ClosestWall_Elem(iPoint);} - - /*! - * \brief Get the marker of the closest wall marker. - * \param[in] iPoint - Index of the point. - * \param[out] ClosestWall_Marker - MarkerID of the closest wall boundary. - */ - inline unsigned long GetClosestWall_Marker(unsigned long iPoint) {return ClosestWall_Marker(iPoint);} - - /*! - * \brief Get the rank of the closest wall marker. - * \param[in] iPoint - Index of the point. - * \param[out] ClosestWall_Rank - RankID of the closest wall boundary. - */ - inline unsigned long GetClosestWall_Rank(unsigned long iPoint) {return ClosestWall_Rank(iPoint);} - /*! * \brief Set the value of the distance to the nearest wall. * \param[in] iPoint - Index of the point. @@ -567,24 +546,6 @@ class CPoint { */ inline su2double *GetNormal(unsigned long iPoint) { return Normals[iPoint]; } - /*! - * \brief Set the value of the normal of the nearest wall element. - * \param[in] iPoint - Index of the point. - * \param[in] normal - Value of the normal. - */ - template - inline void SetNormal(unsigned long iPoint, Normals_type const&normal) { - for (unsigned long iDim = 0; iDim < nDim; iDim++) - Normals(iPoint,iDim) = normal[iDim]; - } - - /*! - * \brief Set the value of the normal of the nearest wall element. - * \param[in] iPoint - Index of the point. - * \return normal to the normal of the nearest wall element. - */ - inline su2double *GetNormal(unsigned long iPoint) { return Normals[iPoint]; } - /*! * \brief Set the value of the distance to a sharp edge. * \param[in] iPoint - Index of the point. diff --git a/SU2_CFD/include/numerics/turbulent/transition/trans_diffusion.hpp b/SU2_CFD/include/numerics/turbulent/transition/trans_diffusion.hpp index 0961c8b8b82..4beb7d374eb 100644 --- a/SU2_CFD/include/numerics/turbulent/transition/trans_diffusion.hpp +++ b/SU2_CFD/include/numerics/turbulent/transition/trans_diffusion.hpp @@ -105,74 +105,6 @@ class CAvgGrad_TransLM final : public CAvgGrad_Scalar { }; -/*! - * \class CAvgGrad_TransSLM - * \brief Class for computing viscous term using average of gradient with correction (Simplified LM transition model). - * \ingroup ViscDiscr - * \author S. Kang. - */ -template -class CAvgGrad_TransSLM final : public CAvgGrad_Scalar { -private: - using Base = CAvgGrad_Scalar; - using Base::Laminar_Viscosity_i; - using Base::Laminar_Viscosity_j; - using Base::Eddy_Viscosity_i; - using Base::Eddy_Viscosity_j; - using Base::Density_i; - using Base::Density_j; - using Base::ScalarVar_i; - using Base::ScalarVar_j; - using Base::Proj_Mean_GradScalarVar; - using Base::proj_vector_ij; - using Base::Flux; - using Base::Jacobian_i; - using Base::Jacobian_j; - - /*! - * \brief Adds any extra variables to AD - */ - void ExtraADPreaccIn() override {} - - /*! - * \brief LM transition model specific steps in the ComputeResidual method - * \param[in] config - Definition of the particular problem. - */ - void FinishResidualCalc(const CConfig* config) override { - const bool implicit = config->GetKind_TimeIntScheme() == EULER_IMPLICIT; - - /*--- Compute mean effective dynamic viscosity ---*/ - const su2double diff_i_gamma = Laminar_Viscosity_i + Eddy_Viscosity_i; - const su2double diff_j_gamma = Laminar_Viscosity_j + Eddy_Viscosity_j; - - const su2double diff_gamma = 0.5*(diff_i_gamma + diff_j_gamma); - - Flux[0] = diff_gamma*Proj_Mean_GradScalarVar[0]; - - /*--- For Jacobians -> Use of TSL (Thin Shear Layer) approx. to compute derivatives of the gradients ---*/ - if (implicit) { - const su2double proj_on_rho_i = proj_vector_ij/Density_i; - Jacobian_i[0][0] = -diff_gamma*proj_on_rho_i; - - const su2double proj_on_rho_j = proj_vector_ij/Density_j; - Jacobian_j[0][0] = diff_gamma*proj_on_rho_j; - } - } - -public: - /*! - * \brief Constructor of the class. - * \param[in] val_nDim - Number of dimensions of the problem. - * \param[in] val_nVar - Number of variables of the problem. - * \param[in] correct_grad - Whether to correct gradient for skewness. - * \param[in] config - Definition of the particular problem. - */ - CAvgGrad_TransSLM(unsigned short val_nDim, unsigned short val_nVar, bool correct_grad, const CConfig* config) - : CAvgGrad_Scalar(val_nDim, val_nVar, correct_grad, config){ - } - -}; - /*! * \class CAvgGrad_TransSLM * \brief Class for computing viscous term using average of gradient with correction (Simplified LM transition model). diff --git a/SU2_CFD/include/variables/CVariable.hpp b/SU2_CFD/include/variables/CVariable.hpp index aa4810328c9..9c51ffafb39 100644 --- a/SU2_CFD/include/variables/CVariable.hpp +++ b/SU2_CFD/include/variables/CVariable.hpp @@ -1699,51 +1699,6 @@ class CVariable { */ inline virtual void SetIntermittencyEff(unsigned long iPoint, su2double val_Intermittency_eff) {} - - /*! - * \brief Set Value of Transition Momentum Thickness Reynolds number from correlations. - */ - inline virtual void SetCorr_Rec(unsigned long iPoint, su2double val_Corr_Rec) {}; - inline virtual void SetTu(unsigned long iPoint, su2double val_Tu) {}; - inline virtual void SetLambda_theta(unsigned long iPoint, su2double val_Lambda_theta) {}; - inline virtual void Setduds(unsigned long iPoint, su2double val_duds) {}; - inline virtual void SetRe_v(unsigned long iPoint, su2double val_Re_v) {}; - inline virtual void SetProd(unsigned long iPoint, su2double val_Prod) {}; - inline virtual void SetDestr(unsigned long iPoint, su2double val_Destr) {}; - inline virtual void SetF_onset1(unsigned long iPoint, su2double val_F_onset1) {}; - inline virtual void SetF_onset2(unsigned long iPoint, su2double val_F_onset2) {}; - inline virtual void SetF_onset3(unsigned long iPoint, su2double val_F_onset3) {}; - inline virtual void SetF_onset(unsigned long iPoint, su2double val_F_onset1) {}; - inline virtual void SetNormal(unsigned long iPoint, su2double val_normal_x, su2double val_normal_y, su2double val_normal_z) {}; - - /*! - * \brief Get Value of Transition Momentum Thickness Reynolds number from correlations. - */ - inline virtual su2double GetCorr_Rec(unsigned long iPoint) const { return 0.0; } - inline virtual su2double GetTu(unsigned long iPoint) const { return 0.0; } - inline virtual su2double GetLambda_theta(unsigned long iPoint) const { return 0.0; } - inline virtual su2double Getduds(unsigned long iPoint) const { return 0.0; } - inline virtual su2double GetRe_v(unsigned long iPoint) const { return 0.0; } - inline virtual su2double GetProd(unsigned long iPoint) const { return 0.0; } - inline virtual su2double GetDestr(unsigned long iPoint) const { return 0.0; } - inline virtual su2double GetF_onset1(unsigned long iPoint) const { return 0.0; } - inline virtual su2double GetF_onset2(unsigned long iPoint) const { return 0.0; } - inline virtual su2double GetF_onset3(unsigned long iPoint) const { return 0.0; } - inline virtual su2double GetF_onset(unsigned long iPoint) const { return 0.0; } - inline virtual su2double GetNormal_x(unsigned long iPoint) const { return 0.0; } - inline virtual su2double GetNormal_y(unsigned long iPoint) const { return 0.0; } - inline virtual su2double GetNormal_z(unsigned long iPoint) const { return 0.0; } - - /*! - * \brief Set Value of Momentum Thickness Reynolds number from correlations (substitute to the second equation of original LM model). - */ - inline virtual void SetRe_t(unsigned long iPoint, su2double val_Re_t) {}; - - /*! - * \brief Get Value of Momentum Thickness Reynolds number from correlations (substitute to the second equation of original LM model). - */ - inline virtual su2double GetRe_t(unsigned long iPoint) const { return 0.0; } - /*! * \brief Set Value of Transition Momentum Thickness Reynolds number from correlations. */ diff --git a/externals/codi b/externals/codi index c6b039e5c9e..96ac78ec5bc 160000 --- a/externals/codi +++ b/externals/codi @@ -1 +1 @@ -Subproject commit c6b039e5c9edb7675f90ffc725f9dd8e66571264 +Subproject commit 96ac78ec5bcc5ac25b785e79b16ed76fca22d736 diff --git a/externals/medi b/externals/medi index ab3a7688f6d..6aef76912e7 160000 --- a/externals/medi +++ b/externals/medi @@ -1 +1 @@ -Subproject commit ab3a7688f6d518f8d940eb61a341d89f51922ba4 +Subproject commit 6aef76912e7099c4f08c9705848797ca9e8070da diff --git a/externals/mel b/externals/mel index 46205ab019e..2484cd3258e 160000 --- a/externals/mel +++ b/externals/mel @@ -1 +1 @@ -Subproject commit 46205ab019e5224559091375a6d71aabae6bc5b9 +Subproject commit 2484cd3258ef800a10e361016cb341834ee7930b diff --git a/externals/opdi b/externals/opdi index 8c897988172..1aabf5bd1ed 160000 --- a/externals/opdi +++ b/externals/opdi @@ -1 +1 @@ -Subproject commit 8c89798817253abb017d857a0ae7f0520187645c +Subproject commit 1aabf5bd1ed77611742eb655002f2ac7a3dddef9 diff --git a/subprojects/CoolProp b/subprojects/CoolProp index bafdea1f39e..0ce42fcf3bb 160000 --- a/subprojects/CoolProp +++ b/subprojects/CoolProp @@ -1 +1 @@ -Subproject commit bafdea1f39ee873a6bb9833e3a21fe41f90b85e8 +Subproject commit 0ce42fcf3bb2c373512bc825a4f0c1973a78f307