-
Notifications
You must be signed in to change notification settings - Fork 915
[WIP] Stochastic Backscatter Model for Grey Area Mitigation in Hybrid RANS-LES Simulations #2572
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
The Reynolds stress tensor definition is modified to include a random contribution, which is expressed as the curl of a normally-distributed stochastic vector potential.
Add Langevin equations to Spalart-Allmaras solver (uncorrelated random source term) + add stochastic contribution to Reynolds stress tensor (using conservative variables from Langevin equations).
Fix sanitizer warnings and regression test failures - Address issues reported by clang sanitizers. - Adjust implementation to ensure regression tests pass.
- Enhance readability. - Ensure consistent declaration types.
- Extend implementation to 2D configurations. - Improve robustness.
Enforce boundary conditions in Langevin equations.
- Implement a skew-symmetric scheme for the discretization of the convective terms in the Langevin equations. - Fix the seed for the generation of the random source terms at the beginning of the simulation.
- Add the flag for the simulation of the Decaying Isotropic Homogeneous Turbulence. - Generate the initial velocity field matching the experimental data by Comte-Bellot & Corrsin. - Include a preliminary test case.
- Implement flag to enforce LES in the whole domain. - Add option to set the LES filter width to a user-specified value. - Add velocity divergence to volume outputs. - Remove internal generation of initial velocity field for simulating the Decaying Isotropic Homogeneous Turbulence (DIHT).
- Add consistent evaluation of the turbulent kinetic energy in the random source term appearing in the momentum equations. - Add backscatter intensity coefficient in the configuration file. - Add random initialization of the Langevin variables.
- Add Laplacian smoothing of source terms in Langevin equations. Remark: pseudo-time integration is employed (residuals are printed on screen with fixed frequency, the maximum number of time iterations can be defined by the user).
- Fix redundancy in virtual member definition.
- Add stochastic source term to Spalart-Allmaras turbulence model equation (to ensure exchange of modeled and resolved kinetic energy).
- Replace dual-time integration with Successive Over-Relaxation for Laplacian smoothing. - Initialize stochastic vector potential as equal to the stochastic source terms in Langevin equations. - Add random source term to main balance equations in LES zones exclusively. - Blend RANS and LES turbulence timescales using the LES sensor.
- Scale source terms in Langevin equations using Bessel functions to preserve the variance. - Compute Bessel integral at the beginning of the simulation for optimization. - Add variance monitoring to screen output.
- Add LD2 discretization for the inviscid terms in the main balance equations. Remarks: -- Valid only for the incompressible flow solver, with constant density fluid model. -- JST scheme must be selected in the config file. The novel option LD2_SCHEME must be set to YES.
- Retrieve classic second-order central scheme at periodic boundaries.
Add option to include stochastic contribution to turbulence model equation.
- Use logarithmic approximation for Bessel function. - Compute relative variance of the stochastic field for verification.
- Add option to print time-averaged skin friction coefficient in volume output.
- Include time-averaged skin friction coefficient and instantaneous energy backscatter ratio into volume output fields. - Fix boundary conditions for the implicit smoothing of the stochastic source term in Langevin equations. - Fix computation of the source term in turbulence model equation. - Fix computation of the subgrid kinetic energy (divide eddy viscosity by flow density). - Diagonalize Jacobian in turbulence equations for numerical robustness.
- Allow LD2 option only for JST scheme.
- Add option to include diagnostics of the stochastic source term smoothing. - Add relaxation factor for the random forcing term in the main balanca equations. - Add modeled and stochastic Reynolds stresses to volume output files.
- Random generators removed from static variables. - Random generators re-initialized at every time step using deterministic seeds.
- Account for zero DES length scale in ghost cells. - Fix threshold (=0.9) for the activation of the backscatter model.
| } else { | ||
| for (unsigned long iPoint = 0; iPoint < nPoint; iPoint++) { | ||
| Solution_Old(iPoint, 0) = Solution(iPoint, 0) = val_nu_tilde; | ||
| for (unsigned short iVar = 1; iVar < nVar; iVar++) { |
Check failure
Code scanning / CodeQL
Comparison of narrow type with wide type in loop condition High
iVar
nVar
|
|
||
| if (backscatter && innerIter==0) { | ||
| SetLangevinSourceTerms(config, geometry); | ||
| const unsigned short maxIter = config->GetSBS_maxIterSmooth(); |
Check warning
Code scanning / CodeQL
Lossy function result cast Warning
| const su2double LES_FilterWidth = config->GetLES_FilterWidth(); | ||
| const su2double constDES = config->GetConst_DES(); | ||
| const su2double cDelta = config->GetSBS_Cdelta(); | ||
| const unsigned short maxIter = config->GetSBS_maxIterSmooth(); |
Check warning
Code scanning / CodeQL
Lossy function result cast Warning
pcarruscag
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments to start, I'll look more into the TurbSolver changes later
| /* DESCRIPTION: Specify if the LD2 scheme must be employed (incompressible flows, combined with JST discretization). */ | ||
| addBoolOption("LD2_OPTION", LD2_Scheme, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make this part of CONV_NUM_METHOD enum, ok to still re-use JST in the code, but the option to use the scheme should be consistent with all other schemes.
| * \param[in] velGrad - Velocity gradient matrix. | ||
| * \param[out] stochReynStress - Stochastic tensor (to be added to the Reynolds stress tensor). | ||
| */ | ||
| template<class Mat, class Scalar, class Vector> | ||
| NEVERINLINE static void ComputeStochReynStress(size_t nDim, Scalar density, Scalar tke, | ||
| Vector rndVec, Mat& stochReynStress, Scalar Cmag) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cmag before the output and add to the function doc
| inline void SetStochVar(su2double val_stochvar_i, su2double val_stochvar_j, unsigned short iDim) { | ||
| stochVar_i[iDim] = val_stochvar_i; | ||
| stochVar_j[iDim] = val_stochvar_j; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iDim first in these functions to be more consistent with others
| const FlowIndices idx; /*!< \brief Object to manage the access to the flow primitives. */ | ||
| su2double a0 = 0.0; /*!< \brief The maximum of the face-normal velocity and 0. */ | ||
| su2double a1 = 0.0; /*!< \brief The minimum of the face-normal velocity and 0. */ | ||
| su2double qij = 0.0; /*!< \brief The face-normal velocity (Langevin equations). */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not a qdot it's an mdot
| if (config->GetStochastic_Backscatter()) { | ||
| qij = 0.0; | ||
| for (unsigned short iDim = 0; iDim < nDim; iDim++) { | ||
| qij += 0.5 * (V_i[idx.Density()]*V_i[iDim + idx.Velocity()] + V_j[idx.Density()]*V_j[iDim + idx.Velocity()]) * Normal[iDim]; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't you use a0 and a1 for this?
| /*! | ||
| * \brief A virtual member. | ||
| * \param[in] iPoint - Point index. | ||
| */ | ||
| inline virtual su2double GetLES_Mode(unsigned long iPoint) const { return 0.0; } | ||
|
|
||
| /*! | ||
| * \brief A virtual member. | ||
| * \param[in] iPoint - Point index. | ||
| * \param[in] val_les_mode - Value of the LES sensor. | ||
| */ | ||
| inline virtual void SetLES_Mode(unsigned long iPoint, su2double val_les_mode) {} | ||
|
|
||
| /*! | ||
| * \brief A virtual member. | ||
| * \param[in] iPoint - Point index. | ||
| * \param[in] iDim - Dimension index. | ||
| */ | ||
| inline virtual su2double GetLangevinSourceTerms(unsigned long iPoint, unsigned short iDim) const { return 0.0; } | ||
|
|
||
| /*! | ||
| * \brief A virtual member. | ||
| * \param[in] iPoint - Point index. | ||
| * \param[in] iDim - Dimension index. | ||
| * \param[in] val_stochSource - Source term in Langevin equations. | ||
| */ | ||
| inline virtual void SetLangevinSourceTerms(unsigned long iPoint, unsigned short iDim, su2double val_stochSource) {} | ||
|
|
||
| /*! | ||
| * \brief A virtual member. | ||
| * \param[in] iPoint - Point index. | ||
| * \param[in] iDim - Dimension index. | ||
| */ | ||
| inline virtual su2double GetLangevinSourceTermsOld(unsigned long iPoint, unsigned short iDim) const { return 0.0; } | ||
|
|
||
| /*! | ||
| * \brief A virtual member. | ||
| * \param[in] iPoint - Point index. | ||
| * \param[in] iDim - Dimension index. | ||
| * \param[in] val_stochSource_old - Old value of source term in Langevin equations. | ||
| */ | ||
| inline virtual void SetLangevinSourceTermsOld(unsigned long iPoint, unsigned short iDim, su2double val_stochSource_old) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need all of these to be virtual, try to remove what you can from CVariable because the turbulence solvers cast to CTurbVariable
| su2double velGrad_i[3][3] = {{0.0}}; | ||
| su2double velGrad_j[3][3] = {{0.0}}; | ||
| for (unsigned short jDim = 0; jDim < nDim; jDim++) { | ||
| for (iDim = 0; iDim < nDim; iDim++) { | ||
| velGrad_i[iDim][jDim] = PrimVar_Grad_i[iDim+1][jDim]; | ||
| velGrad_j[iDim][jDim] = PrimVar_Grad_j[iDim+1][jDim]; | ||
| } | ||
| } | ||
| for (iDim = 0; iDim < nDim; iDim++) { | ||
| Velocity_i[iDim] += alpha_LD2 * (velGrad_i[iDim][0] * d_ij[0] + | ||
| velGrad_i[iDim][1] * d_ij[1] + | ||
| velGrad_i[iDim][2] * d_ij[2]); | ||
| Velocity_j[iDim] -= alpha_LD2 * (velGrad_j[iDim][0] * d_ij[0] + | ||
| velGrad_j[iDim][1] * d_ij[1] + | ||
| velGrad_j[iDim][2] * d_ij[2]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this enough to make it LD2? what about pressure and the dissipation terms?
| if (config->GetStochastic_Backscatter()) { | ||
| for (iVar = 0; iVar < nDim; iVar++) | ||
| Mean_StochVar[iVar] = 0.5*(stochVar_i[iVar] + stochVar_j[iVar]); | ||
| su2double SBS_Cmag = config->GetSBS_Cmag(); | ||
| su2double SBS_RelaxFactor = config->GetStochSourceRelax(); | ||
| su2double intensityCoeff = SBS_Cmag; | ||
| if (SBS_RelaxFactor > 0.0) { | ||
| su2double FS_Vel = config->GetModVel_FreeStream(); | ||
| su2double ReynoldsLength = config->GetLength_Reynolds(); | ||
| su2double timeScale = ReynoldsLength / FS_Vel; | ||
| unsigned long timeIter = config->GetTimeIter(); | ||
| unsigned long restartIter = config->GetRestart_Iter(); | ||
| su2double timeStep = config->GetTime_Step(); | ||
| su2double currentTime = (timeIter - restartIter) * timeStep; | ||
| intensityCoeff = SBS_Cmag * (1.0 - exp(- currentTime / (timeScale*SBS_RelaxFactor))); | ||
| } | ||
| ComputeStochReynStress(nDim, Mean_PrimVar[nDim+2], Mean_turb_ke, | ||
| Mean_StochVar, stochReynStress, intensityCoeff); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make a helper function that you can share across numerics
| AddVolumeOutput("VELOCITY_DIVERGENCE", "Velocity_Divergence", "DERIVED", "Divergence of the velocity field"); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
after primitives please
| const auto VelocityGradient = Node_Flow->GetVelocityGradient(iPoint); | ||
| su2double divVel = 0.0; | ||
| for (unsigned short iDim = 0; iDim < nDim; iDim++) { | ||
| divVel += VelocityGradient[iDim][iDim]; | ||
| } | ||
| SetVolumeOutputValue("VELOCITY_DIVERGENCE", iPoint, divVel); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move to common flow outputs
Proposed Changes
Hybrid RANS-LES methods aim to leverage the strengths of both Reynolds-Averaged Navier-Stokes (RANS) approaches and Large Eddy Simulation (LES), applying RANS near solid walls for computational efficiency and LES in outer flow regions for improved fidelity. A persistent challenge in these techniques is the appearance of the so-called grey area—the transitional region between RANS and LES zones—which is characterized by the absence of resolved turbulence. This leads to degraded accuracy in capturing free shear layers. The Stochastic Backscatter Model (Kok, 2017) aims to mitigate this issue. The model introduces stochastic forcing terms into the momentum and total energy equations that emulate the backscatter of energy from unresolved (subgrid) scales to resolved scales. The random forcing is formulated as the curl of a stochastic vector potential, say$\underline\xi$ . The latter must be constructed using a three-step procedure:
References:
Roadmap
Related Work
None.
PR Checklist
pre-commit run --allto format old commits.