correctPressure.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2022-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "isothermalFluid.H"
27 #include "constrainHbyA.H"
28 #include "constrainPressure.H"
29 #include "adjustPhi.H"
30 #include "fvcMeshPhi.H"
31 #include "fvcFlux.H"
32 #include "fvcDdt.H"
33 #include "fvcGrad.H"
34 #include "fvcSnGrad.H"
35 #include "fvcReconstruct.H"
36 #include "fvcVolumeIntegrate.H"
37 #include "fvmDiv.H"
38 #include "fvmLaplacian.H"
39 
40 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
41 
42 void Foam::solvers::isothermalFluid::correctPressure()
43 {
48 
49  const volScalarField& psi = thermo.psi();
50  rho = thermo.rho();
51  rho.relax();
52 
53  fvVectorMatrix& UEqn = tUEqn.ref();
54 
55  // Thermodynamic density needs to be updated by psi*d(p) after the
56  // pressure solution
57  const volScalarField p0("p0", p);
58 
60 
61  const volScalarField rAU("rAU", 1.0/UEqn.A());
62  surfaceScalarField rhorAUf("rhorAUf", fvc::interpolate(rho*rAU));
63 
64  tmp<volScalarField> rAtU
65  (
67  ? volScalarField::New("rAtU", 1.0/(1.0/rAU - UEqn.H1()))
68  : tmp<volScalarField>(nullptr)
69  );
70 
71  tmp<surfaceScalarField> rhorAtUf
72  (
74  ? surfaceScalarField::New("rhoRAtUf", fvc::interpolate(rho*rAtU()))
75  : tmp<surfaceScalarField>(nullptr)
76  );
77 
78  const volScalarField& rAAtU = pimple.consistent() ? rAtU() : rAU;
79  surfaceScalarField& rhorAAtUf =
80  pimple.consistent() ? rhorAtUf.ref() : rhorAUf;
81 
83 
84  if (pimple.nCorrPiso() <= 1)
85  {
86  tUEqn.clear();
87  }
88 
90  (
91  "phiHbyA",
92  rhof*fvc::flux(HbyA)
93  + rhorAUf*fvc::ddtCorr(rho, U, phi, rhoUf)
94  );
95 
96  MRF.makeRelative(rhof, phiHbyA);
97 
98  bool adjustMass = false;
99 
100  if (pimple.transonic())
101  {
102  const surfaceScalarField phidByPsi
103  (
105  (
106  fvc::relative(phiHbyA, rho, U)/rhof,
107  U,
108  p,
109  rhorAUf,
110  rhorAAtUf
111  )
112  );
113 
114  const surfaceScalarField phid("phid", fvc::interpolate(psi)*phidByPsi);
115 
116  // Subtract the compressible part
117  // The resulting flux will be zero for a perfect gas
118  phiHbyA -= fvc::interpolate(psi*p)*phidByPsi;
119 
120  if (pimple.consistent())
121  {
122  phiHbyA += (rhorAAtUf - rhorAUf)*fvc::snGrad(p)*mesh.magSf();
123  HbyA += (rAAtU - rAU)*fvc::grad(p);
124  }
125 
126  // Update the pressure BCs to ensure flux consistency
127  constrainPressure(p, rho, U, phiHbyA, rhorAAtUf, MRF);
128 
130 
131  fvScalarMatrix pDDtEqn
132  (
134  + fvc::div(phiHbyA) + fvm::div(phid, p)
135  ==
136  fvModels().sourceProxy(rho, p)
137  );
138 
139  while (pimple.correctNonOrthogonal())
140  {
141  fvScalarMatrix pEqn(pDDtEqn - fvm::laplacian(rhorAAtUf, p));
142 
143  // Relax the pressure equation to ensure diagonal-dominance
144  pEqn.relax();
145 
146  pEqn.setReference
147  (
150  );
151 
152  fvConstraints().constrain(pEqn);
153 
154  pEqn.solve();
155 
157  {
158  phi = phiHbyA + pEqn.flux();
159  }
160  }
161  }
162  else
163  {
164  if (pimple.consistent())
165  {
166  phiHbyA += (rhorAAtUf - rhorAUf)*fvc::snGrad(p)*mesh.magSf();
167  HbyA += (rAAtU - rAU)*fvc::grad(p);
168  }
169 
170  // Update the pressure BCs to ensure flux consistency
171  constrainPressure(p, rho, U, phiHbyA, rhorAAtUf, MRF);
172 
174 
175  if (mesh.schemes().steady())
176  {
177  adjustMass = adjustPhi(phiHbyA, U, p);
178  }
179 
180  fvScalarMatrix pDDtEqn
181  (
183  + fvc::div(phiHbyA)
184  ==
185  fvModels().sourceProxy(rho, p)
186  );
187 
188  while (pimple.correctNonOrthogonal())
189  {
190  fvScalarMatrix pEqn(pDDtEqn - fvm::laplacian(rhorAAtUf, p));
191 
192  pEqn.setReference
193  (
196  );
197 
198  fvConstraints().constrain(pEqn);
199 
200  pEqn.solve();
201 
203  {
204  phi = phiHbyA + pEqn.flux();
205  }
206  }
207  }
208 
209  if (!mesh.schemes().steady())
210  {
211  const bool constrained = fvConstraints().constrain(p);
212 
213  // Thermodynamic density update
214  thermo_.correctRho(p - p0);
215 
216  if (constrained)
217  {
218  rho = thermo.rho();
219  }
220 
221  correctDensity();
222  }
223 
224  continuityErrors();
225 
226  // Explicitly relax pressure for momentum corrector
227  p.relax();
228 
229  U = HbyA - rAAtU*fvc::grad(p);
232  K = 0.5*magSqr(U);
233 
234  if (mesh.schemes().steady())
235  {
237  }
238 
239  // For steady compressible closed-volume cases adjust the pressure level
240  // to obey overall mass continuity
241  if (adjustMass && !thermo.incompressible())
242  {
246  }
247 
248  if (mesh.schemes().steady() || pimple.simpleRho() || adjustMass)
249  {
250  rho = thermo.rho();
251  }
252 
253  if (mesh.schemes().steady() || pimple.simpleRho())
254  {
255  rho.relax();
256  }
257 
258  // Correct rhoUf if the mesh is moving
260 
261  if (thermo.dpdt())
262  {
263  dpdt = fvc::ddt(p);
264  }
265 }
266 
267 
268 // ************************************************************************* //
For cases which do no have a pressure boundary adjust the balance of fluxes to obey continuity....
void relax(const scalar alpha)
Relax field (for steady-state solution).
void correctBoundaryConditions()
Correct boundary field.
static tmp< GeometricField< Type, GeoMesh, PrimitiveField > > New(const word &name, const Internal &, const PtrList< Patch > &, const HashPtrTable< Source > &=HashPtrTable< Source >())
Return a temporary field constructed from name,.
void makeRelative(volVectorField &U) const
Make the given absolute velocity relative within the MRF region.
Definition: MRFZoneList.C:173
virtual Switch dpdt() const =0
Should the dpdt term be included in the enthalpy equation.
virtual bool incompressible() const =0
Return true if the equation of state is incompressible.
virtual tmp< volScalarField > rho() const =0
Density [kg/m^3].
bool transonic() const
Flag to indicate to solve using transonic algorithm.
bool consistent() const
Flag to indicate to relax pressure using the "consistent".
virtual void correctRho(const volScalarField &dp)=0
Update the density corresponding to the given pressure change.
virtual const volScalarField & psi() const =0
Compressibility [s^2/m^2].
bool constrain(fvMatrix< Type > &eqn) const
Apply constraints to an equation.
const fvSchemes & schemes() const
Return the fvSchemes.
Definition: fvMesh.C:1792
const surfaceScalarField & magSf() const
Return cell face area magnitudes.
bool steady() const
Return true if the default ddtScheme is steadyState.
Definition: fvSchemes.H:145
bool finalNonOrthogonalIter() const
Flag to indicate the last non-orthogonal iteration.
bool simpleRho() const
Switch to indicate whether to update the density in simple mode.
bool correctNonOrthogonal()
Non-orthogonal corrector loop.
label nCorrPiso() const
Maximum number of piso correctors.
Definition: pisoControlI.H:28
scalar refValue() const
Return the pressure reference level.
label refCell() const
Return the cell in which the reference pressure is set.
Foam::fvModels & fvModels() const
Return the fvModels that are created on demand.
Definition: solver.C:103
pimpleNoLoopControl pimple
PIMPLE inner-loop controls.
Definition: solver.H:107
Foam::fvConstraints & fvConstraints() const
Return the fvConstraints that are created on demand.
Definition: solver.C:114
const fvMesh & mesh
Region mesh.
Definition: solver.H:101
volScalarField rho_
The continuity density field.
const surfaceScalarField & phi
Mass-flux field.
volVectorField U_
Velocity field.
tmp< fvVectorMatrix > tUEqn
Cached momentum matrix.
autoPtr< surfaceVectorField > rhoUf
Pointer to the surface momentum field.
fluidThermo & thermo_
Reference to the fluid thermophysical properties.
volScalarField K
Kinetic energy field.
const volVectorField & U
Velocity field.
volScalarField & p_
Reference to the pressure field.
surfaceScalarField phi_
Mass-flux field.
const MRFZones & MRF
Reference to the MRFZones MeshObject.
const volScalarField & rho
Reference to the continuity density field.
volScalarField::Internal dpdt
Rate of change of the pressure.
Foam::pressureReference pressureReference
Pressure reference.
const fluidThermo & thermo
Reference to the fluid thermophysical properties.
const volScalarField & p
Reference to the pressure field.
dimensionedScalar initialMass
Initial mass in the region.
fvVectorMatrix & UEqn
Definition: UEqn.H:11
Calculate the first temporal derivative.
Calculate the face-flux of the given field.
Calculate the gradient of the given field.
Calculate the mesh motion flux and convert fluxes from absolute to relative and back.
Reconstruct volField from a face flux field.
Calculate the snGrad of the given volField.
Volume integrate volField creating a volField.
Calculate the matrix for the divergence of the given field and flux.
Calculate the matrix for the laplacian of the field.
const volScalarField & psi
volScalarField rAU(1.0/UEqn.A())
volVectorField & HbyA
Definition: pEqn.H:13
surfaceScalarField phiHbyA("phiHbyA", fvc::interpolate(rho) *fvc::flux(HbyA))
tmp< SurfaceField< typename innerProduct< vector, Type >::type > > flux(const VolField< Type > &vf)
Return the face-flux field obtained from the given volVectorField.
static tmp< SurfaceField< Type > > interpolate(const VolField< Type > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
tmp< VolField< Type > > ddt(const dimensioned< Type > dt, const fvMesh &mesh)
Definition: fvcDdt.C:45
void correctRhoUf(autoPtr< surfaceVectorField > &rhoUf, const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const MRFType &MRF)
tmp< surfaceScalarField > relative(const tmp< surfaceScalarField > &tphi, const volVectorField &U)
Return the given absolute flux in relative form.
Definition: fvcMeshPhi.C:167
dimensioned< Type > domainIntegrate(const VolField< Type > &vf)
tmp< VolField< typename outerProduct< vector, Type >::type > > grad(const SurfaceField< Type > &ssf)
Definition: fvcGrad.C:46
tmp< VolField< Type > > div(const SurfaceField< Type > &ssf)
Definition: fvcDiv.C:47
void makeRelative(surfaceScalarField &phi, const volVectorField &U)
Make the given flux relative.
Definition: fvcMeshPhi.C:89
tmp< SurfaceField< Type > > snGrad(const VolField< Type > &vf, const word &name)
Definition: fvcSnGrad.C:45
tmp< SurfaceField< typename Foam::flux< Type >::type > > ddtCorr(const VolField< Type > &U, const SurfaceField< Type > &Uf)
Definition: fvcDdt.C:196
tmp< fvMatrix< Type > > laplacian(const VolField< Type > &vf, const word &name)
Definition: fvmLaplacian.C:47
tmp< fvMatrix< Type > > div(const surfaceScalarField &flux, const VolField< Type > &vf, const word &name)
Definition: fvmDiv.C:48
tmp< fvMatrix< Type > > ddt(const VolField< Type > &vf)
Definition: fvmDdt.C:46
void constrainPressure(volScalarField &p, const RhoType &rho, const volVectorField &U, const surfaceScalarField &phiHbyA, const RAUType &rhorAU, const MRFType &MRF)
bool adjustPhi(surfaceScalarField &phi, const volVectorField &U, volScalarField &p)
Adjust the balance of fluxes to obey continuity.
Definition: adjustPhi.C:35
VolField< vector > volVectorField
Definition: volFieldsFwd.H:63
fvMatrix< scalar > fvScalarMatrix
Definition: fvMatricesFwd.H:42
SurfaceField< scalar > surfaceScalarField
void constrainHbyA(volVectorField &HbyA, const volVectorField &U, const volScalarField &p)
Definition: constrainHbyA.C:34
VolField< scalar > volScalarField
Definition: volFieldsFwd.H:62
fvMatrix< vector > fvVectorMatrix
Definition: fvMatricesFwd.H:45
tmp< fvMatrix< Type > > correction(const fvMatrix< Type > &)
Return the correction form of the given matrix.
tmp< surfaceScalarField > constrainPhid(const tmp< surfaceScalarField > &tphid, const volVectorField &U, const volScalarField &p, surfaceScalarField &rhorAUf, surfaceScalarField &rhorAAtUf)
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)