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-2022 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"
29 #include "slipFvPatchFields.H"
31 
32 #include "fvmDdt.H"
33 #include "fvmDiv.H"
34 #include "fvmSup.H"
35 #include "fvcDdt.H"
36 #include "fvcDiv.H"
37 #include "fvcFlux.H"
38 
39 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
40 
41 template<class BasePhaseModel>
44 {
45  word phiName(IOobject::groupName("phi", this->name()));
46 
47  typeIOobject<surfaceScalarField> phiHeader
48  (
49  phiName,
50  U.mesh().time().timeName(),
51  U.mesh(),
52  IOobject::NO_READ
53  );
54 
55  if (phiHeader.headerOk())
56  {
57  Info<< "Reading face flux field " << phiName << endl;
58 
59  return tmp<surfaceScalarField>
60  (
62  (
63  IOobject
64  (
65  phiName,
66  U.mesh().time().timeName(),
67  U.mesh(),
68  IOobject::MUST_READ,
69  IOobject::AUTO_WRITE
70  ),
71  U.mesh()
72  )
73  );
74  }
75  else
76  {
77  Info<< "Calculating face flux field " << phiName << endl;
78 
79  wordList phiTypes
80  (
81  U.boundaryField().size(),
82  calculatedFvPatchScalarField::typeName
83  );
84 
85  forAll(U.boundaryField(), patchi)
86  {
87  if (!U.boundaryField()[patchi].assignable())
88  {
89  phiTypes[patchi] = fixedValueFvPatchScalarField::typeName;
90  }
91  }
92 
93  return tmp<surfaceScalarField>
94  (
96  (
97  IOobject
98  (
99  phiName,
100  U.mesh().time().timeName(),
101  U.mesh(),
102  IOobject::NO_READ,
103  IOobject::AUTO_WRITE
104  ),
105  fvc::flux(U),
106  phiTypes
107  )
108  );
109  }
110 }
111 
112 
113 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
114 
115 template<class BasePhaseModel>
117 (
118  const phaseSystem& fluid,
119  const word& phaseName,
120  const bool referencePhase,
121  const label index
122 )
123 :
124  BasePhaseModel(fluid, phaseName, referencePhase, index),
125  U_
126  (
127  IOobject
128  (
129  IOobject::groupName("U", this->name()),
130  fluid.mesh().time().timeName(),
131  fluid.mesh(),
132  IOobject::MUST_READ,
133  IOobject::AUTO_WRITE
134  ),
135  fluid.mesh()
136  ),
137  phi_(phi(U_)),
138  alphaPhi_
139  (
140  IOobject
141  (
142  IOobject::groupName("alphaPhi", this->name()),
143  fluid.mesh().time().timeName(),
144  fluid.mesh()
145  ),
146  fluid.mesh(),
147  dimensionedScalar(dimensionSet(0, 3, -1, 0, 0), 0)
148  ),
149  alphaRhoPhi_
150  (
151  IOobject
152  (
153  IOobject::groupName("alphaRhoPhi", this->name()),
154  fluid.mesh().time().timeName(),
155  fluid.mesh()
156  ),
157  fluid.mesh(),
158  dimensionedScalar(dimensionSet(1, 0, -1, 0, 0), 0)
159  ),
160  Uf_(nullptr),
161  DUDt_(nullptr),
162  DUDtf_(nullptr),
163  divU_(nullptr),
164  turbulence_
165  (
166  phaseCompressible::momentumTransportModel::New
167  (
168  *this,
169  this->thermo().rho(),
170  U_,
171  alphaRhoPhi_,
172  phi_,
173  *this
174  )
175  ),
176  thermophysicalTransport_
177  (
178  PhaseThermophysicalTransportModel
179  <
180  phaseCompressible::momentumTransportModel,
181  transportThermoModel
182  >::New(turbulence_, this->thermo_)
183  ),
184  continuityError_
185  (
186  IOobject
187  (
188  IOobject::groupName("continuityError", this->name()),
189  fluid.mesh().time().timeName(),
190  fluid.mesh()
191  ),
192  fluid.mesh(),
194  ),
195  K_(nullptr)
196 {
197  phi_.writeOpt() = IOobject::AUTO_WRITE;
198 
199  if (fluid.mesh().dynamic())
200  {
201  Uf_ = new surfaceVectorField
202  (
203  IOobject
204  (
205  IOobject::groupName("Uf", this->name()),
206  fluid.mesh().time().timeName(),
207  fluid.mesh(),
210  ),
211  fvc::interpolate(U_)
212  );
213  }
214 
215  correctKinematics();
216 }
217 
218 
219 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
220 
221 template<class BasePhaseModel>
223 {}
224 
225 
226 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
227 
228 template<class BasePhaseModel>
230 (
231  const volScalarField& source
232 )
233 {
234  volScalarField& rho = this->thermoRef().rho();
235 
236  continuityError_ = fvc::ddt(*this, rho) + fvc::div(alphaRhoPhi_) - source;
237 }
238 
239 
240 template<class BasePhaseModel>
242 {
244  this->fluid().MRF().correctBoundaryVelocity(U_);
245 }
246 
247 
248 template<class BasePhaseModel>
250 {
251  BasePhaseModel::correctKinematics();
252 
253  if (DUDt_.valid())
254  {
255  DUDt_.clear();
256  DUDt();
257  }
258 
259  if (DUDtf_.valid())
260  {
261  DUDtf_.clear();
262  DUDtf();
263  }
264 
265  if (K_.valid())
266  {
267  K_.ref() = 0.5*magSqr(this->U());
268  }
269 }
270 
271 
272 template<class BasePhaseModel>
274 {
275  BasePhaseModel::correctTurbulence();
276 
277  turbulence_->correct();
278 }
279 
280 
281 template<class BasePhaseModel>
283 {
284  BasePhaseModel::correctEnergyTransport();
285  thermophysicalTransport_->correct();
286 }
287 
288 
289 template<class BasePhaseModel>
291 {
292  const fvMesh& mesh = this->fluid().mesh();
293 
294  if (mesh.dynamic())
295  {
296  Uf_.ref() = fvc::interpolate(U_);
297  surfaceVectorField n(mesh.Sf()/mesh.magSf());
298  Uf_.ref() +=
299  n*(
300  this->fluid().MRF().absolute(fvc::absolute(phi_, U_))
301  /mesh.magSf()
302  - (n & Uf_())
303  );
304 
305  surfaceVectorField::Boundary& UfBf = Uf_.ref().boundaryFieldRef();
306  const volVectorField::Boundary& UBf = U_.boundaryField();
307 
308  forAll(mesh.boundary(), patchi)
309  {
310  // Remove the flux correction on AMI patches to compensate for
311  // AMI non-conservation error
312  if (isA<cyclicAMIFvPatch>(mesh.boundary()[patchi]))
313  {
314  UfBf[patchi] = UBf[patchi];
315  }
316  }
317  }
318 }
319 
320 
321 template<class BasePhaseModel>
323 {
324  return false;
325 }
326 
327 
328 template<class BasePhaseModel>
331 {
332  const volScalarField& alpha = *this;
333  const volScalarField& rho = this->thermo().rho();
334 
335  return
336  (
337  fvm::ddt(alpha, rho, U_)
338  + fvm::div(alphaRhoPhi_, U_)
339  + fvm::SuSp(-this->continuityError(), U_)
340  + this->fluid().MRF().DDt(alpha*rho, U_)
341  + turbulence_->divDevTau(U_)
342  );
343 }
344 
345 
346 template<class BasePhaseModel>
349 {
350  // As the "normal" U-eqn but without the ddt terms
351 
352  const volScalarField& alpha = *this;
353  const volScalarField& rho = this->thermo().rho();
354 
355  return
356  (
357  fvm::div(alphaRhoPhi_, U_)
358  + fvm::SuSp(fvc::ddt(*this, rho) - this->continuityError(), U_)
359  + this->fluid().MRF().DDt(alpha*rho, U_)
360  + turbulence_->divDevTau(U_)
361  );
362 }
363 
364 
365 template<class BasePhaseModel>
368 {
369  return U_;
370 }
371 
372 
373 template<class BasePhaseModel>
376 {
377  return U_;
378 }
379 
380 
381 template<class BasePhaseModel>
384 {
385  return phi_;
386 }
387 
388 
389 template<class BasePhaseModel>
392 {
393  return phi_;
394 }
395 
396 
397 template<class BasePhaseModel>
400 {
401  return
402  Uf_.valid()
403  ? tmp<surfaceVectorField>(Uf_())
404  : tmp<surfaceVectorField>();
405 }
406 
407 
408 template<class BasePhaseModel>
411 {
412  if (Uf_.valid())
413  {
414  return Uf_.ref();
415  }
416  else
417  {
419  << "Uf has not been allocated."
420  << exit(FatalError);
421 
422  return const_cast<surfaceVectorField&>(surfaceVectorField::null());
423  }
424 }
425 
426 
427 template<class BasePhaseModel>
430 {
431  return alphaPhi_;
432 }
433 
434 
435 template<class BasePhaseModel>
438 {
439  return alphaPhi_;
440 }
441 
442 
443 template<class BasePhaseModel>
446 {
447  return alphaRhoPhi_;
448 }
449 
450 
451 template<class BasePhaseModel>
454 {
455  return alphaRhoPhi_;
456 }
457 
458 
459 template<class BasePhaseModel>
462 {
463  if (!DUDt_.valid())
464  {
465  const tmp<surfaceScalarField> taphi(fvc::absolute(phi_, U_));
466  const surfaceScalarField& aphi(taphi());
467  DUDt_ =
468  new volVectorField
469  (
470  IOobject::groupName("DUDt", this->name()),
471  fvc::ddt(U_) + fvc::div(aphi, U_) - fvc::div(aphi)*U_
472  );
473  }
474 
475  return tmp<volVectorField>(DUDt_());
476 }
477 
478 
479 template<class BasePhaseModel>
482 {
483  if (!DUDtf_.valid())
484  {
485  DUDtf_ =
487  (
488  IOobject::groupName("DUDtf", this->name()),
489  byDt(phi_ - phi_.oldTime())
490  );
491  }
492 
493  return tmp<surfaceScalarField>(DUDtf_());
494 }
495 
496 
497 template<class BasePhaseModel>
500 {
501  return continuityError_;
502 }
503 
504 
505 template<class BasePhaseModel>
508 {
509  if (!K_.valid())
510  {
511  K_ =
512  new volScalarField
513  (
514  IOobject::groupName("K", this->name()),
515  0.5*magSqr(this->U())
516  );
517  }
518 
519  return tmp<volScalarField>(K_());
520 }
521 
522 
523 template<class BasePhaseModel>
526 {
527  return divU_.valid() ? tmp<volScalarField>(divU_()) : tmp<volScalarField>();
528 }
529 
530 
531 template<class BasePhaseModel>
532 void Foam::MovingPhaseModel<BasePhaseModel>::divU(tmp<volScalarField> divU)
533 {
534  if (!divU_.valid())
535  {
536  divU_ = divU;
537  divU_.ref().rename(IOobject::groupName("divU", this->name()));
538  divU_.ref().checkIn();
539  }
540  else
541  {
542  divU_.ref() = divU;
543  }
544 }
545 
546 
547 template<class BasePhaseModel>
550 {
551  return turbulence_->k();
552 }
553 
554 
555 template<class BasePhaseModel>
558 {
559  return turbulence_->pPrime();
560 }
561 
562 
563 template<class BasePhaseModel>
566 {
567  return thermophysicalTransport_->kappaEff(patchi);
568 }
569 
570 
571 template<class BasePhaseModel>
574 {
575  return thermophysicalTransport_->divq(he);
576 }
577 
578 
579 template<class BasePhaseModel>
582 {
583  return thermophysicalTransport_->divj(Yi);
584 }
585 
586 
587 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
virtual tmp< volScalarField > divU() const
Return the phase dilatation rate (d(alpha)/dt + div(alpha*phi))
tmp< GeometricField< Type, fvPatchField, volMesh > > DDt(const surfaceScalarField &phi, const GeometricField< Type, fvPatchField, volMesh > &psi)
Definition: fvcDDt.C:45
tmp< fvMatrix< Type > > SuSp(const volScalarField::Internal &, const GeometricField< Type, fvPatchField, volMesh > &)
FvWallInfoData< WallInfo, label > label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
fluidReactionThermo & thermo
Definition: createFields.H:28
autoPtr< CompressibleMomentumTransportModel > New(const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const viscosity &viscosity)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
virtual surfaceScalarField & alphaRhoPhiRef()
Access the mass flux of the phase.
U
Definition: pEqn.H:72
IOMRFZoneList & MRF
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
Info<< "Predicted p max-min : "<< max(p).value()<< " "<< min(p).value()<< endl;rho==max(rho0+psi *p, rhoMin);# 1 "/home/ubuntu/OpenFOAM-10/applications/solvers/multiphase/cavitatingFoam/alphavPsi.H" 1{ alphav=max(min((rho - rholSat)/(rhovSat - rholSat), scalar(1)), scalar(0));alphal=1.0 - alphav;Info<< "max-min alphav: "<< max(alphav).value()<< " "<< min(alphav).value()<< endl;psiModel-> correct()
Definition: pEqn.H:68
virtual tmp< surfaceVectorField > Uf() const
Return the face velocity.
tmp< GeometricField< Type, fvPatchField, volMesh > > div(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcDiv.C:47
virtual bool stationary() const
Return whether the phase is stationary.
GeometricField< vector, fvsPatchField, surfaceMesh > surfaceVectorField
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
virtual tmp< volVectorField > DUDt() const
Return the substantive acceleration.
virtual tmp< surfaceScalarField > alphaPhi() const
Return the volumetric flux of the phase.
GeometricBoundaryField< vector, fvsPatchField, surfaceMesh > Boundary
Type of the boundary field.
virtual tmp< fvScalarMatrix > divj(volScalarField &Yi) const
Return the source term for the given specie mass-fraction.
virtual void correctTurbulence()
Correct the turbulence.
GeometricField< vector, fvPatchField, volMesh > volVectorField
Definition: volFieldsFwd.H:59
tmp< GeometricField< Type, fvPatchField, volMesh > > ddt(const dimensioned< Type > dt, const fvMesh &mesh)
Definition: fvcDdt.C:45
virtual tmp< volScalarField > k() const
Return the turbulent kinetic energy.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:58
Calculate the first temporal derivative.
compressibleMomentumTransportModel momentumTransportModel
const dimensionSet dimTime
MovingPhaseModel(const phaseSystem &fluid, const word &phaseName, const bool referencePhase, const label index)
virtual tmp< surfaceScalarField > alphaRhoPhi() const
Return the mass flux of the phase.
virtual tmp< fvVectorMatrix > UfEqn()
Return the momentum equation for the face-based algorithm.
virtual ~MovingPhaseModel()
Destructor.
Calculate the face-flux of the given field.
static word groupName(Name name, const word &group)
const dimensionSet dimDensity
virtual surfaceScalarField & phiRef()
Access the volumetric flux.
tmp< fvMatrix< Type > > ddt(const GeometricField< Type, fvPatchField, volMesh > &vf)
Definition: fvmDdt.C:46
Calculate the matrix for the first temporal derivative.
phaseSystem & fluid
Definition: createFields.H:11
phi
Definition: correctPhi.H:3
word timeName
Definition: getTimeIndex.H:3
virtual surfaceVectorField & UfRef()
Access the face velocity.
virtual volVectorField & URef()
Access the velocity.
virtual tmp< volScalarField > pPrime() const
Return the phase-pressure&#39;.
Calculate the divergence of the given field.
dimensioned< scalar > magSqr(const dimensioned< Type > &)
tmp< fvMatrix< Type > > div(const surfaceScalarField &flux, const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvmDiv.C:46
virtual void correctUf()
Correct the face velocity for moving meshes.
tmp< volScalarField > divU
Definition: alphaSuSp.H:9
virtual void correct()
Correct the phase properties other than the thermo and turbulence.
virtual tmp< volVectorField > U() const
Return the velocity.
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
virtual void correctEnergyTransport()
Correct the energy transport e.g. alphat.
tmp< volScalarField > byDt(const volScalarField &vf)
static tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > interpolate(const GeometricField< Type, fvPatchField, volMesh > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
Internal & ref()
Return a reference to the dimensioned internal field.
static const GeometricField< vector, fvsPatchField, surfaceMesh > & null()
Return a null geometric field.
virtual tmp< volScalarField > continuityError() const
Return the continuity error.
virtual tmp< fvScalarMatrix > divq(volScalarField &he) const
Return the source term for the energy equation.
Calculate the matrix for the divergence of the given field and flux.
List< word > wordList
A List of words.
Definition: fileName.H:54
virtual tmp< volScalarField > K() const
Return the phase kinetic energy.
label patchi
virtual void correctContinuityError(const volScalarField &source)
Correct the continuity error.
tmp< surfaceScalarField > absolute(const tmp< surfaceScalarField > &tphi, const volVectorField &U)
Return the given relative flux in absolute form.
Definition: fvcMeshPhi.C:202
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
virtual surfaceScalarField & alphaPhiRef()
Access the volumetric flux of the phase.
virtual tmp< fvVectorMatrix > UEqn()
Return the momentum equation.
virtual tmp< scalarField > kappaEff(const label patchi) const
Return the effective thermal conductivity on a patch.
messageStream Info
label n
virtual void correctKinematics()
Correct the kinematics.
virtual tmp< surfaceScalarField > phi() const
Return the volumetric flux.
A class for managing temporary objects.
Definition: PtrList.H:53
tmp< surfaceScalarField > flux(const volVectorField &vvf)
Return the face-flux field obtained from the given volVectorField.
Definition: fvcFlux.C:32
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
virtual tmp< surfaceScalarField > DUDtf() const
Return the substantive acceleration on the faces.
Calculate the matrix for implicit and explicit sources.