Pressure Based Solver - #2812
Conversation
There was a problem hiding this comment.
CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
Implements the full class structure required for the pressure-based solver in a minimal form. The code compiles and runs but does not yet contain any numerical/physical implementation. Future work will focus on implementing solver logic. Note: In the previous attempts (see related work) there is noticeable code duplication between CIncEuler and CPBIncEuler. The final architecture may be revised depending on how the implementation of CPBIncEuler evolves.
Centered residual is not yet implemented as the old code did not have a working version. Upwind residual is functional but requires cleanup and move to more appropiate file.
Variables are a work in progress and still include some commented out code related to energy and pressure
The current viscous residual of the poisson equation uses an isotropic diffusion coefficient, this should not be the case and should thus be replaced
|
I will have to review the code myself first, it is not ready for review as of yet. |
| /*--- Rhie Chow interpolation ---*/ | ||
| Coord_i = geometry->nodes->GetCoord(iPoint); | ||
| Coord_j = geometry->nodes->GetCoord(jPoint); | ||
| dist_ij_2 = 0.0; | ||
| for (iDim = 0; iDim < nDim; iDim++) { | ||
| Edge_Vector[iDim] = Coord_j[iDim]-Coord_i[iDim]; | ||
| dist_ij_2 += Edge_Vector[iDim]*Edge_Vector[iDim]; | ||
| } | ||
| /*--- 1. Interpolate the pressure gradient based on node values ---*/ | ||
| for (iDim = 0; iDim < nDim; iDim++) { | ||
| Grad_Avg = 0.5*(nodes->GetGradient_Primitive(iPoint,0,iDim) + nodes->GetGradient_Primitive(jPoint,0,iDim)); | ||
| GradP_in[iDim] = Grad_Avg; | ||
| } | ||
|
|
||
| /*--- 2. Compute pressure gradient at the face ---*/ | ||
| /*--- Eq 15.62 F Moukalled, L Mangani M. Darwish OpenFOAM and uFVM book. ---*/ | ||
| GradP_proj = 0.0; | ||
| for (iDim = 0; iDim < nDim; iDim++) { | ||
| GradP_proj += GradP_in[iDim]*Edge_Vector[iDim]; | ||
| } | ||
| if (dist_ij_2 != 0.0) { | ||
| for (iDim = 0; iDim < nDim; iDim++) { | ||
| GradP_f[iDim] = GradP_in[iDim] - (GradP_proj - (nodes->GetPressure(jPoint) - nodes->GetPressure(iPoint)))*Edge_Vector[iDim]/ dist_ij_2; | ||
| } | ||
| } |
There was a problem hiding this comment.
Can you extract a common helper from the numerics classes? this is similar to the corrected gradient calculation.
There was a problem hiding this comment.
I could not directly use a common helper as some intermediate variables are used in the Rhie-Chow interpolation, I would thus not know how to unify this with the other existing corrected gradient functions. For now I've added a single helper function specific to the pressure gradient. This could be improved in the future but I think this suffices for now.
6c6d3e7 to
ce55da3
Compare
|
|
||
| su2double Density = nodes->GetDensity(iPoint); | ||
|
|
||
| su2double *pressureGradientSource = new su2double[nVar]; |
There was a problem hiding this comment.
this is leaking memory, use a C array of size MAXNVAR or similar
| /*--- Compute the residual (V / rho * gradp) based on the pressure gradient. ---*/ | ||
|
|
||
| for (unsigned short iDim = 0; iDim < nDim; iDim++) | ||
| pressureGradientSource[iDim+1] = geometry->nodes->GetVolume(iPoint) / Density * nodes->GetGradient_Primitive(iPoint,prim_idx.Pressure(),iDim); |
There was a problem hiding this comment.
Why is the momentum equation divided by density?
There was a problem hiding this comment.
The density based solver uses the solution variables (u,v,w) and the preconditioning matrix basically makes it an equation for (rho u, rho v, rhow). Because we now use the same solution variables for the pressure-based solver, which does not use this preconditioning matrix, the equations are/should be divided by the density. Other implementations sometimes neglect this division by density in the pressure which then represents kinematic pressure but I think that creates confusion with the other solvers in SU2.
There was a problem hiding this comment.
I don't see changes to the regression scripts, can you make sure the new configs have regression tests.
And at least a couple should be V&V quality.
Proposed Changes
The current work (part of GSoC) provides a working version of a pressure-based algorithm for the incompressible flow solver as an alternative to the existing Density-based solver. Below, the reader may find the algorithm which has been implemented, as well as the current progress of the code and challenges. All the way at the bottom one can find performance comparisons between the DB and PB solvers for some test cases.
Algorithm
A lot of versions of pressure-based algorithms exist, and many different versions can be implemented. Here, we opt for versions of the original SIMPLE/PISO algorithm, it is briefly defined here for clarity.
First, the momentum equations are solved, starting from the previous time step's velocity$\vec{u}^{(0)}$, pressure$p^{(0)}$ , and face velocity $\vec{u}_f^{(0)}$ . The resulting momentum is the predicted momentum, here its discretized form is shown, as its coefficients are used in the subsequent equations
The subsequent momentum is not necessarily incompressible, the pressure correction equation can be derived by rewriting it as follows, using a term often called H by A
Note how a simplification is used here where the HbyA term is neglected. Subtracting these two equations yields the first pressure correction equation for$p'$ as
Make note that for the divergence here, we require the face mass fluxes, which are computed using Rhie-Chow interpolation to avoid odd-even decoupling. After the equation is solved, using the pressure correction$p'$ , the pressure and momentum are corrected according to
So far, this is equal to a pseudo-transient version of the SIMPLE algorithm. This algorithm however suffers from a very tight stability condition on the time-step size. Therefore, multiple pressure corrections can be applied, which for two corrections is originally called the PISO algorithm.
The second pressure correction does not neglect the HbyA term, which then results in the equation
And the new correction equations are defined as
Note that HbyA here uses the previous velocity correction and is thus the same quantity as the one used in the second pressure correction equation. Later pressure correction equations follow analogously.
Progress:
Issues
Performance:
The Poisson solver can sometimes struggle a lot due to high Reynolds numbers and fine meshes, and thus require a ridiculous number of iterations to converge reasonably. Possible fixes include adding multigrid support or a DIC preconditioner (far less efficient). Multigrid support is tricky as SU2 currently only considers multigrid for the main (flow) solver and not for auxiliary solvers.
Convergence issues with RANS (SA and SST) on fine meshes with high Reynolds numbers. Tests have shown that cases such as flow over a flat plate converges fine. However, external aerodynamic cases such as the naca0012 RANS test case do not converge well at all. The convergence does slightly improve when we switch out the mesh for a more uniform unstructured mesh without large aspect ratio cells in the wake of the airfoil, although this only slightly helps. The flat plate turbulence test case also uses large aspect ratio cells so this is not the sole issue. The RANS solver also often requires many iterations of the Poisson solver to converge reasonably, this is however not the reason for the lack of convergence.
Periodic boundary conditions have not been implemented/tested at all as of yet.
Any code related to adjoints has not been considered at all either.
Code:
TODO list
Related Work
This work is based on earlier attempts by Nitish Anand (2024) and Akshay Koodly (2021), see feature branches feature_PBFlow_V8 and feature_Pressure_based respectively. Also see PR #2210
PR Checklist
pre-commit run --allto format old commits.Result showcase
Inviscid Hydrofoil
Convergence history of the inviscid flow around a hydrofoil at a 5 degree aoa.
The pressure coefficient along the surface of the hydrofoil at a 5 degree aoa and the corresponding lift coefficients, X-FOIL predicts C_L=0.6.
Lid Driven Cavity
Convergence history of the lid driven cavity problem, note that CFL=60 is the highest stable CFL for the PB solver, whereas the DB solver does not have this CFL related stability issue.
Flatplate RANS
The skin friction coefficient for turbulent flow over a (rough) flat plate with SA.