isothermalFluid.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 "localEulerDdtScheme.H"
29 #include "fvcMeshPhi.H"
30 #include "fvcVolumeIntegrate.H"
31 #include "fvcReconstruct.H"
32 #include "fvcDiv.H"
33 #include "fvcSnGrad.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40 namespace solvers
41 {
44 }
45 }
46 
47 
48 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
49 
50 void Foam::solvers::isothermalFluid::correctCoNum()
51 {
52  basicFluidSolver::correctCoNum(rho, phi);
53 }
54 
55 
56 void Foam::solvers::isothermalFluid::continuityErrors()
57 {
59 }
60 
61 
62 // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
63 
66 (
68 ) const
69 {
70  if (mesh.moving())
71  {
72  return
73  work
74  + fvc::div
75  (
77  p/rho,
78  "div(phi,(p|rho))"
79  )();
80  }
81  else
82  {
83  return move(work);
84  }
85 }
86 
87 
88 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
89 
91 (
92  fvMesh& mesh,
93  autoPtr<fluidThermo> thermoPtr
94 )
95 :
97 
98  thermoPtr_(thermoPtr),
99  thermo_(thermoPtr_()),
100 
101  p_(thermo_.p()),
102 
103  rho_
104  (
105  IOobject
106  (
107  "rho",
108  runTime.name(),
109  mesh,
110  IOobject::READ_IF_PRESENT,
111  IOobject::AUTO_WRITE
112  ),
113  thermo_.renameRho()
114  ),
115 
116  dpdt
117  (
118  IOobject
119  (
120  "dpdt",
121  runTime.name(),
122  mesh
123  ),
124  mesh,
125  dimensionedScalar(p_.dimensions()/dimTime, 0)
126  ),
127 
129 
130  p_rgh_(buoyancy.valid() ? buoyancy->p_rgh : p_),
131 
133  (
134  p_,
135  p_rgh_,
136  pimple.dict(),
137  thermo_.incompressible()
138  ),
139 
140  U_
141  (
142  IOobject
143  (
144  "U",
145  runTime.name(),
146  mesh,
147  IOobject::MUST_READ,
148  IOobject::AUTO_WRITE
149  ),
150  mesh,
151  dimensions::velocity
152  ),
153 
154  phi_
155  (
156  IOobject
157  (
158  "phi",
159  runTime.name(),
160  mesh,
161  IOobject::READ_IF_PRESENT,
162  IOobject::AUTO_WRITE
163  ),
164  linearInterpolate(rho_*U_) & mesh.Sf()
165  ),
166 
167  K("K", 0.5*magSqr(U_)),
168 
169  momentumTransport
170  (
171  compressible::momentumTransportModel::New
172  (
173  rho_,
174  U_,
175  phi_,
176  thermo_
177  )
178  ),
179 
180  initialMass(fvc::domainIntegrate(rho_)),
181 
182  MRF(MRFZones::New(mesh)),
183 
184  thermo(thermo_),
185  p(p_),
186  p_rgh(p_rgh_),
187  rho(rho_),
188  U(U_),
189  phi(phi_)
190 {
192  momentumTransport->validate();
193 
194  if (buoyancy.valid())
195  {
197  (
198  p_rgh_,
199  p_,
200  rho_,
201  U,
202  buoyancy->gh,
203  buoyancy->ghf,
204  buoyancy->pRef,
205  thermo_,
206  pimple.dict()
207  );
208 
210  (
211  IOobject
212  (
213  "netForce",
214  runTime.name(),
215  mesh
216  ),
218  (
220  *mesh.magSf()
221  )
222  );
223  }
224 
225  if (transient())
226  {
227  correctCoNum();
228  }
229  else if (LTS)
230  {
231  Info<< "Using LTS" << endl;
232 
234  (
235  new volScalarField
236  (
237  IOobject
238  (
240  runTime.name(),
241  mesh,
244  ),
245  mesh,
248  )
249  );
250  }
251 }
252 
253 
255 :
257 {}
258 
259 
260 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
261 
263 {}
264 
265 
266 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
267 
269 {
270  if ((mesh.dynamic() || MRF.size()) && !rhoUf.valid())
271  {
272  Info<< "Constructing face momentum rhoUf" << endl;
273 
274  // Ensure the U BCs are up-to-date before constructing Uf
275  U_.correctBoundaryConditions();
276 
277  rhoUf = new surfaceVectorField
278  (
279  IOobject
280  (
281  "rhoUf",
282  runTime.name(),
283  mesh,
286  ),
288  );
289  }
290 
291  if (transient())
292  {
293  correctCoNum();
294  }
295  else if (LTS)
296  {
297  setRDeltaT();
298  }
299 
300  // Store divrhoU from the previous mesh so that it can be mapped
301  // and used in correctPhi to ensure the corrected phi has the
302  // same divergence
303  if (correctPhi || mesh.topoChanging())
304  {
305  divrhoU = new volScalarField
306  (
307  "divrhoU",
308  fvc::div(fvc::absolute(phi, rho, U))
309  );
310  }
311 
313 
314  // Store momentum to set rhoUf for introduced faces
315  if (mesh.topoChanging())
316  {
317  rhoU = new volVectorField("rhoU", rho*U);
318 
319  for (label i = 1; i <= rhoUf().nOldTimes(false); ++ i)
320  {
321  rhoU().oldTimeRef(i) == rho.oldTime(i)*U.oldTime(i);
322  }
323  }
324 
325  // Update the mesh for topology change, mesh to mesh mapping
326  mesh_.update();
327 }
328 
329 
331 {
332  if
333  (
334  !mesh.schemes().steady()
335  && !pimple.simpleRho()
336  && pimple.firstIter()
337  )
338  {
339  correctDensity();
340  }
341 }
342 
343 
345 {
346  momentumTransport->predict();
347 }
348 
349 
351 {}
352 
353 
355 {
356  thermo_.correct();
357 }
358 
359 
361 {
362  while (pimple.correct())
363  {
364  if (buoyancy.valid())
365  {
366  correctBuoyantPressure();
367  }
368  else
369  {
370  correctPressure();
371  }
372  }
373 
374  tUEqn.clear();
375 }
376 
377 
379 {
380  momentumTransport->correct();
381 }
382 
383 
385 {}
386 
387 
389 {
390  divrhoU.clear();
391 
392  if (!mesh.schemes().steady())
393  {
394  rho_ = thermo.rho();
395 
396  // Correct rhoUf with the updated density if the mesh is moving
397  fvc::correctRhoUf(rhoUf, rho, U, phi, MRF);
398  }
399 }
400 
401 
402 // ************************************************************************* //
Macros for easy insertion into run-time selection tables.
Generic GeometricField class.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
const word & name() const
Return name.
Definition: IOobject.H:307
MRF zones DemandDrivenMeshObject read from MRFProperties dictionary.
Definition: MRFZones.H:76
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
const word & name() const
Return const reference to name.
Base-class for fluid thermodynamic properties.
Definition: fluidThermo.H:56
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:98
const fvSchemes & schemes() const
Return the fvSchemes.
Definition: fvMesh.C:1795
const surfaceScalarField & magSf() const
Return cell face area magnitudes.
bool dynamic() const
Is this mesh dynamic?
Definition: fvMesh.C:697
bool topoChanging() const
Does the mesh topology change?
Definition: fvMesh.C:685
virtual void preUpdateMesh()
Prepare for mesh update.
Definition: fvModels.C:258
void setFluxRequired(const word &name) const
Definition: fvSchemes.C:434
bool steady() const
Return true if the default ddtScheme is steadyState.
Definition: fvSchemes.H:145
static word rDeltaTName
Name of the reciprocal local time-step field.
Abstract base class for momentum transport models (RAS, LES and laminar).
static const dictionary & dict(const fvMesh &mesh, const word &algorithmName="PIMPLE")
Return the solution dictionary.
bool moving() const
Is the mesh moving?
Definition: polyMesh.H:462
Provides controls for the pressure reference in closed-volume simulations.
Abstract base class for run-time selectable region solvers.
Definition: solver.H:56
bool LTS
Switch for local time step transient operation.
Definition: solver.H:70
pimpleNoLoopControl pimple
PIMPLE inner-loop controls.
Definition: solver.H:107
const Time & runTime
Time.
Definition: solver.H:104
const fvMesh & mesh
Region mesh.
Definition: solver.H:101
Base solver module for fluid solvers.
void continuityErrors(const surfaceScalarField &phi)
Calculate and print the continuity errors.
Buoyancy related data for the Foam::solvers::isothermalFluid solver module when solving buoyant cases...
Definition: buoyancy.H:70
volScalarField gh
(g & h) - ghRef
Definition: buoyancy.H:95
uniformDimensionedScalarField pRef
Reference pressure.
Definition: buoyancy.H:89
surfaceScalarField ghf
(g & hf) - ghRef
Definition: buoyancy.H:98
Solver module for steady or transient turbulent flow of compressible isothermal fluids with optional ...
virtual void thermophysicalPredictor()
Construct and solve the energy equation,.
volScalarField rho_
The continuity density field.
const surfaceScalarField & phi
Mass-flux field.
virtual void momentumTransportCorrector()
Correct the momentum transport.
virtual void prePredictor()
Called at the start of the PIMPLE loop.
const volScalarField & p_rgh
Reference to the buoyant pressure for buoyant cases.
virtual void postSolve()
Called after the PIMPLE loop at the end of the time-step.
virtual void momentumTransportPredictor()
Predict the momentum transport.
tmp< volVectorField > netForce
Momentum equation net force source term.
tmp< volScalarField > trDeltaT
Optional LTS reciprocal time-step field.
fluidThermo & thermo_
Reference to the fluid thermophysical properties.
virtual ~isothermalFluid()
Destructor.
const volVectorField & U
Velocity field.
virtual void pressureCorrector()
Construct and solve the pressure equation in the PISO loop.
tmp< volScalarField::Internal > pressureWork(const tmp< volScalarField::Internal > &) const
Adds the mesh-motion work to the pressure work term provided.
volScalarField & p_
Reference to the pressure field.
virtual void thermophysicalTransportCorrector()
Correct the thermophysical transport.
isothermalFluid(fvMesh &mesh, autoPtr< fluidThermo >)
Construct from region mesh and thermophysical properties.
const volScalarField & rho
Reference to the continuity density field.
volScalarField & p_rgh_
Reference to the buoyant pressure for buoyant cases.
virtual void preSolve()
Called at the start of the time-step, before the PIMPLE loop.
const volScalarField & p
Reference to the pressure field.
virtual void thermophysicalTransportPredictor()
Predict thermophysical transport.
autoPtr< compressible::momentumTransportModel > momentumTransport
Pointer to the momentum transport model.
A class for managing temporary objects.
Definition: tmp.H:55
tmp< fvVectorMatrix > tUEqn(fvm::div(phi, U)+MRF.DDt(rho, U)+turbulence->divDevTau(U)==fvModels.source(rho, U))
Foam::fvModels & fvModels(Foam::fvModels::New(mesh))
const Foam::MRFZones & MRF(Foam::MRFZones::New(mesh))
pimpleControl pimple(mesh)
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
Calculate the divergence 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.
K
Definition: pEqn.H:75
U
Definition: pEqn.H:72
rho
Definition: pEqn.H:1
dimensionedScalar initialMass
Definition: createFields.H:68
bool valid(const PtrList< ModelType > &l)
const dimensionSet velocity
const dimensionSet dimless
static tmp< SurfaceField< Type > > interpolate(const VolField< Type > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
void correctRhoUf(autoPtr< surfaceVectorField > &rhoUf, const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const MRFType &MRF)
tmp< surfaceScalarField > meshPhi(const volVectorField &U)
Definition: fvcMeshPhi.C:34
tmp< VolField< typename outerProduct< vector, Type >::type > > reconstruct(const SurfaceField< Type > &ssf)
dimensioned< Type > domainIntegrate(const VolField< Type > &vf)
tmp< VolField< Type > > div(const SurfaceField< Type > &ssf)
Definition: fvcDiv.C:47
tmp< surfaceScalarField > absolute(const tmp< surfaceScalarField > &tphi, const volVectorField &U)
Return the given relative flux in absolute form.
Definition: fvcMeshPhi.C:202
tmp< SurfaceField< Type > > snGrad(const VolField< Type > &vf, const word &name)
Definition: fvcSnGrad.C:45
addToRunTimeSelectionTable(solver, compressibleMultiphaseVoF, fvMesh)
defineTypeNameAndDebug(basicFluidSolver, 0)
Namespace for OpenFOAM.
VolField< vector > volVectorField
Definition: volFieldsFwd.H:63
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
String typeName(const std::type_info &info)
Return the un-mangled name given the standard type info.
messageStream Info
void hydrostaticInitialisation(volScalarField &p_rgh, volScalarField &p, volScalarField &rho, const volVectorField &U, const volScalarField &gh, const surfaceScalarField &ghf, const uniformDimensionedScalarField &pRef, fluidThermo &thermo, const dictionary &dict)
tmp< SurfaceField< Type > > linearInterpolate(const VolField< Type > &vf)
Definition: linear.H:108
const dimensionSet & dimTime
Definition: dimensions.C:277
VolField< scalar > volScalarField
Definition: volFieldsFwd.H:62
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
SurfaceField< vector > surfaceVectorField
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
tmp< DimensionedField< TypeR, GeoMesh, Field > > New(const tmp< DimensionedField< TypeR, GeoMesh, Field >> &tdf1, const word &name, const dimensionSet &dimensions)
correctPhi
dictionary dict
volScalarField & p
fluidMulticomponentThermo & thermo
Definition: createFields.H:15