MovingPhaseModel.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) 2015-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 "MovingPhaseModel.H"
27 #include "phaseSystem.H"
30 #include "wallFvPatch.H"
32 #include "slipFvPatchFields.H"
34 
35 #include "fvmDdt.H"
36 #include "fvmDiv.H"
37 #include "fvmSup.H"
38 #include "fvcDdt.H"
39 #include "fvcDiv.H"
40 #include "fvcFlux.H"
41 
42 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
43 
44 template<class BasePhaseModel>
47 {
48  word phiName(IOobject::groupName("phi", this->name()));
49 
50  typeIOobject<surfaceScalarField> phiHeader
51  (
52  phiName,
53  U.mesh().time().name(),
54  U.mesh(),
55  IOobject::NO_READ
56  );
57 
58  if (phiHeader.headerOk())
59  {
60  Info<< "Reading face flux field " << phiName << endl;
61 
62  return tmp<surfaceScalarField>
63  (
65  (
66  IOobject
67  (
68  phiName,
69  U.mesh().time().name(),
70  U.mesh(),
71  IOobject::MUST_READ,
72  IOobject::AUTO_WRITE
73  ),
74  U.mesh()
75  )
76  );
77  }
78  else
79  {
80  Info<< indentOrNl << "Calculating face flux field " << phiName << endl;
81 
82  wordList phiTypes
83  (
84  U.boundaryField().size(),
86  );
87 
88  forAll(U.boundaryField(), patchi)
89  {
90  if (!U.boundaryField()[patchi].assignable())
91  {
93  }
94  }
95 
96  return tmp<surfaceScalarField>
97  (
99  (
100  IOobject
101  (
102  phiName,
103  U.mesh().time().name(),
104  U.mesh(),
105  IOobject::NO_READ,
106  IOobject::AUTO_WRITE
107  ),
108  fvc::flux(U),
109  phiTypes
110  )
111  );
112  }
113 }
114 
115 
116 template<class BasePhaseModel>
118 (
119  const volVectorField& U
120 ) const
121 {
122  wordList alphaPhiTypes
123  (
124  U.boundaryField().size(),
126  );
127 
128  forAll(U.boundaryField(), patchi)
129  {
130  const fvPatchVectorField& UPf = U.boundaryField()[patchi];
131 
132  if
133  (
134  // Check for fixedValue with a value of 0 for backward compatibility
135  (
136  isType<fixedValueFvPatchVectorField>(UPf)
137  && gSum(UPf) == vector::zero
138  )
139  // Check for wall patch type
140  || isType<wallFvPatch>(this->mesh().boundary()[patchi])
141  || isA<noSlipFvPatchVectorField>(UPf)
142  || isA<slipFvPatchVectorField>(UPf)
143  || isA<partialSlipFvPatchVectorField>(UPf)
144  )
145  {
147  }
148  }
149 
150  return alphaPhiTypes;
151 }
152 
153 
154 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
155 
156 template<class BasePhaseModel>
158 (
159  const phaseSystem& fluid,
160  const word& phaseName,
161  const bool referencePhase,
162  const label index
163 )
164 :
165  BasePhaseModel(fluid, phaseName, referencePhase, index),
166  U_
167  (
168  IOobject
169  (
170  IOobject::groupName("U", this->name()),
171  fluid.mesh().time().name(),
172  fluid.mesh(),
173  IOobject::MUST_READ,
174  IOobject::AUTO_WRITE
175  ),
176  fluid.mesh()
177  ),
178  phi_(phi(U_)),
179  alphaPhi_
180  (
181  IOobject
182  (
183  IOobject::groupName("alphaPhi", this->name()),
184  fluid.mesh().time().name(),
185  fluid.mesh(),
186  IOobject::READ_IF_PRESENT,
187  IOobject::NO_WRITE
188  ),
189  fluid.mesh(),
190  dimensionedScalar(dimensionSet(0, 3, -1, 0, 0), 0),
191  alphaPhiTypes(U_)
192  ),
193  alphaRhoPhi_
194  (
195  IOobject
196  (
197  IOobject::groupName("alphaRhoPhi", this->name()),
198  fluid.mesh().time().name(),
199  fluid.mesh(),
200  IOobject::READ_IF_PRESENT,
201  IOobject::AUTO_WRITE
202  ),
203  fluid.mesh(),
204  dimensionedScalar(dimensionSet(1, 0, -1, 0, 0), 0),
205  alphaPhiTypes(U_)
206  ),
207  Uf_(nullptr),
208  divU_(nullptr),
209  momentumTransport_
210  (
211  phaseCompressible::momentumTransportModel::New
212  (
213  *this,
214  this->rho(),
215  U_,
216  alphaRhoPhi_,
217  phi_,
218  *this
219  )
220  ),
221  continuityError_
222  (
223  IOobject
224  (
225  IOobject::groupName("continuityError", this->name()),
226  fluid.mesh().time().name(),
227  fluid.mesh()
228  ),
229  fluid.mesh(),
231  ),
232  K_(nullptr)
233 {
235 
236  if (fluid.mesh().dynamic() || this->fluid().MRF().size())
237  {
238  Uf_ = new surfaceVectorField
239  (
240  IOobject
241  (
242  IOobject::groupName("Uf", this->name()),
243  fluid.mesh().time().name(),
244  fluid.mesh(),
247  ),
249  );
250  }
251 
253 }
254 
255 
256 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
257 
258 template<class BasePhaseModel>
260 {}
261 
262 
263 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
264 
265 template<class BasePhaseModel>
267 (
268  const volScalarField& source
269 )
270 {
271  volScalarField& rho = this->rho();
272  continuityError_ = fvc::ddt(*this, rho) + fvc::div(alphaRhoPhi_) - source;
273 }
274 
275 
276 template<class BasePhaseModel>
278 {
280 }
281 
282 
283 template<class BasePhaseModel>
285 {
286  BasePhaseModel::correctKinematics();
287 
288  if (K_.valid())
289  {
290  K_.ref() = 0.5*magSqr(this->U());
291  }
292 }
293 
294 
295 template<class BasePhaseModel>
297 {
298  BasePhaseModel::predictMomentumTransport();
299  momentumTransport_->predict();
300 }
301 
302 
303 template<class BasePhaseModel>
305 {
306  BasePhaseModel::correctMomentumTransport();
307  momentumTransport_->correct();
308 }
309 
310 
311 template<class BasePhaseModel>
313 {
314  const fvMesh& mesh = this->fluid().mesh();
315 
316  if (Uf_.valid())
317  {
318  Uf_() = fvc::interpolate(U_);
320  Uf_() +=
321  n*(
322  this->fluid().MRF().absolute(fvc::absolute(phi_, U_))
323  /mesh.magSf()
324  - (n & Uf_())
325  );
326  }
327 }
328 
329 
330 template<class BasePhaseModel>
332 {
333  return false;
334 }
335 
336 
337 template<class BasePhaseModel>
340 {
341  const volScalarField& alpha = *this;
342  const volScalarField& rho = this->rho();
343 
344  return
345  (
346  fvm::ddt(alpha, rho, U_)
347  + fvm::div(alphaRhoPhi_, U_)
348  + fvm::SuSp(-this->continuityError(), U_)
349  + this->fluid().MRF().DDt(alpha*rho, U_)
350  + momentumTransport_->divDevTau(U_)
351  );
352 }
353 
354 
355 template<class BasePhaseModel>
358 {
359  // As the "normal" U-eqn but without the ddt terms
360 
361  const volScalarField& alpha = *this;
362  const volScalarField& rho = this->rho();
363 
364  return
365  (
366  fvm::div(alphaRhoPhi_, U_)
367  + fvm::SuSp(fvc::ddt(*this, rho) - this->continuityError(), U_)
368  + this->fluid().MRF().DDt(alpha*rho, U_)
369  + momentumTransport_->divDevTau(U_)
370  );
371 }
372 
373 
374 template<class BasePhaseModel>
377 {
378  return U_;
379 }
380 
381 
382 template<class BasePhaseModel>
385 {
386  return U_;
387 }
388 
389 
390 template<class BasePhaseModel>
393 {
394  return U_;
395 }
396 
397 
398 template<class BasePhaseModel>
401 {
402  return phi_;
403 }
404 
405 
406 template<class BasePhaseModel>
409 {
410  return phi_;
411 }
412 
413 
414 template<class BasePhaseModel>
417 {
418  return phi_;
419 }
420 
421 
422 template<class BasePhaseModel>
425 {
426  return Uf_;
427 }
428 
429 
430 template<class BasePhaseModel>
433 {
434  if (Uf_.valid())
435  {
436  return Uf_();
437  }
438  else
439  {
441  << "Uf has not been allocated."
442  << exit(FatalError);
443 
444  return const_cast<surfaceVectorField&>(surfaceVectorField::null());
445  }
446 }
447 
448 
449 template<class BasePhaseModel>
452 {
453  if (Uf_.valid())
454  {
455  return Uf_();
456  }
457  else
458  {
460  << "Uf has not been allocated."
461  << exit(FatalError);
462 
463  return const_cast<surfaceVectorField&>(surfaceVectorField::null());
464  }
465 }
466 
467 
468 template<class BasePhaseModel>
471 {
472  return alphaPhi_;
473 }
474 
475 
476 template<class BasePhaseModel>
479 {
480  return alphaPhi_;
481 }
482 
483 
484 template<class BasePhaseModel>
487 {
488  return alphaPhi_;
489 }
490 
491 
492 template<class BasePhaseModel>
495 {
496  return alphaRhoPhi_;
497 }
498 
499 
500 template<class BasePhaseModel>
503 {
504  return alphaRhoPhi_;
505 }
506 
507 
508 template<class BasePhaseModel>
511 {
512  return alphaRhoPhi_;
513 }
514 
515 
516 template<class BasePhaseModel>
519 {
520  const tmp<surfaceScalarField> taphi(fvc::absolute(phi_, U_));
521  const surfaceScalarField& aphi(taphi());
522 
523  return
524  fvm::div(aphi, U_) - fvm::Sp(fvc::div(aphi), U_)
525  + this->fluid().MRF().DDt(U_);
526 }
527 
528 
529 template<class BasePhaseModel>
532 {
533  return fvm::ddt(U_) + UgradU();
534 }
535 
536 
537 template<class BasePhaseModel>
540 {
541  return continuityError_;
542 }
543 
544 
545 template<class BasePhaseModel>
548 {
549  if (!K_.valid())
550  {
551  K_ =
552  new volScalarField
553  (
554  IOobject::groupName("K", this->name()),
555  0.5*magSqr(this->U())
556  );
557  }
558 
559  return tmp<volScalarField>(K_());
560 }
561 
562 
563 template<class BasePhaseModel>
566 {
567  return divU_;
568 }
569 
570 
571 template<class BasePhaseModel>
573 {
574  if (!divU_.valid())
575  {
576  divU_ = divU.ptr();
577  divU_().rename(IOobject::groupName("divU", this->name()));
578  divU_().checkIn();
579  }
580  else
581  {
582  divU_() = divU;
583  }
584 }
585 
586 
587 template<class BasePhaseModel>
590 {
591  return momentumTransport_->k();
592 }
593 
594 
595 template<class BasePhaseModel>
598 {
599  return momentumTransport_->pPrimef();
600 }
601 
602 
603 // ************************************************************************* //
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
Generic GeometricField class.
static const GeometricField< Type, GeoMesh, PrimitiveField > & null()
Return a null geometric field.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
writeOption & writeOpt() const
Definition: IOobject.H:367
static word groupName(Name name, const word &group)
Class which represents a moving fluid phase. Holds the velocity, fluxes and momentumTransport model a...
virtual void correctUf()
Correct the face velocity for moving meshes.
virtual void correctKinematics()
Correct the kinematics.
virtual tmp< fvVectorMatrix > UEqn()
Return the momentum equation.
volVectorField U_
Velocity field.
virtual void correct()
Correct the phase properties other than the thermo.
virtual tmp< volScalarField > k() const
Return the turbulent kinetic energy.
virtual tmp< fvVectorMatrix > DUDt() const
Return the substantive acceleration matrix.
virtual ~MovingPhaseModel()
Destructor.
virtual tmp< volVectorField > U() const
Return the velocity.
virtual void correctMomentumTransport()
Correct the momentumTransport.
virtual surfaceScalarField & alphaRhoPhiRef()
Access the mass flux of the phase.
virtual const autoPtr< volScalarField > & divU() const
Return the phase dilatation rate (d(alpha)/dt + div(alpha*phi))
virtual surfaceScalarField & phiRef()
Access the volumetric flux.
virtual tmp< surfaceScalarField > alphaPhi() const
Return the volumetric flux of the phase.
virtual tmp< volScalarField > K() const
Return the phase kinetic energy.
surfaceScalarField phi_
Flux.
MovingPhaseModel(const phaseSystem &fluid, const word &phaseName, const bool referencePhase, const label index)
virtual tmp< surfaceScalarField > pPrimef() const
Return the face-phase-pressure'.
virtual const autoPtr< surfaceVectorField > & Uf() const
Return the face velocity.
virtual surfaceVectorField & UfRef()
Access the face velocity.
virtual surfaceScalarField & alphaPhiRef()
Access the volumetric flux of the phase.
virtual tmp< surfaceScalarField > alphaRhoPhi() const
Return the mass flux of the phase.
virtual tmp< surfaceScalarField > phi() const
Return the volumetric flux.
virtual tmp< fvVectorMatrix > UfEqn()
Return the momentum equation for the face-based algorithm.
virtual volVectorField & URef()
Access the velocity.
virtual bool stationary() const
Return whether the phase is stationary.
virtual void predictMomentumTransport()
Predict the momentumTransport.
virtual tmp< fvVectorMatrix > UgradU() const
Return the velocity transport matrix.
virtual tmp< volScalarField > continuityError() const
Return the continuity error.
virtual void correctContinuityError(const volScalarField &source)
Correct the continuity error.
autoPtr< surfaceVectorField > Uf_
Face velocity field.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
Dimension set for the base types.
Definition: dimensionSet.H:125
const word & name() const
Return const reference to name.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:98
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:433
const surfaceVectorField & Sf() const
Return cell face area vectors.
const surfaceScalarField & magSf() const
Return cell face area magnitudes.
bool dynamic() const
Is this mesh dynamic?
Definition: fvMesh.C:695
Abstract base class for momentum transport models (RAS, LES and laminar).
Class to represent a system of phases.
Definition: phaseSystem.H:74
const fvMesh & mesh() const
Return the mesh.
Definition: phaseSystemI.H:91
A class for managing temporary objects.
Definition: tmp.H:55
T * ptr() const
Return tmp pointer for reuse.
Definition: tmpI.H:221
A class for handling words, derived from string.
Definition: word.H:63
const Foam::MRFZones & MRF(Foam::MRFZones::New(mesh))
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
Calculate the first temporal derivative.
Calculate the divergence of the given field.
Calculate the face-flux of the given field.
Calculate the matrix for the first temporal derivative.
Calculate the matrix for the divergence of the given field and flux.
Calculate the matrix for implicit and explicit sources.
label patchi
U
Definition: pEqn.H:72
rho
Definition: pEqn.H:1
volScalarField alpha(IOobject("alpha", runTime.name(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
void correct(const RdeltaTType &rDeltaT, const RhoType &rho, volScalarField &psi, const surfaceScalarField &phiCorr, const SpType &Sp)
const dimensionSet time
tmp< VolField< Type > > DDt(const surfaceScalarField &phi, const VolField< Type > &psi)
Definition: fvcDDt.C:45
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
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< fvMatrix< Type > > div(const surfaceScalarField &flux, const VolField< Type > &vf, const word &name)
Definition: fvmDiv.C:48
tmp< fvMatrix< Type > > Sp(const volScalarField::Internal &, const VolField< Type > &)
tmp< fvMatrix< Type > > SuSp(const volScalarField::Internal &, const VolField< Type > &)
tmp< fvMatrix< Type > > ddt(const VolField< Type > &vf)
Definition: fvmDdt.C:46
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
List< word > wordList
A List of words.
Definition: fileName.H:54
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.
SurfaceField< scalar > surfaceScalarField
messageStream Info
Type gSum(const UList< Type > &f, const label comm)
const dimensionSet & dimTime
Definition: dimensions.C:142
VolField< scalar > volScalarField
Definition: volFieldsFwd.H:62
const dimensionSet & dimDensity
Definition: dimensions.C:158
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
Ostream & indentOrNl(Ostream &os)
Indent stream or add newline if indent level == 0.
Definition: Ostream.H:250
error FatalError
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)
fvPatchField< vector > fvPatchVectorField
faceListList boundary(nPatches)