pEqn.H
Go to the documentation of this file.
1 PtrList<surfaceScalarField> alphafs(phases.size());
2 PtrList<volScalarField> rAUs(phases.size());
3 PtrList<surfaceScalarField> alpharAUfs(phases.size());
4 
6 {
7  phaseModel& phase = phases[phasei];
8  const volScalarField& alpha = phase;
9 
10  alphafs.set(phasei, fvc::interpolate(alpha).ptr());
11  alphafs[phasei].rename("pEqn" + alphafs[phasei].name());
12 
13  rAUs.set
14  (
15  phasei,
16  new volScalarField
17  (
18  IOobject::groupName("rAU", phase.name()),
19  1.0
20  /(
21  UEqns[phasei].A()
22  + max(phase.residualAlpha() - alpha, scalar(0))
23  *phase.rho()/runTime.deltaT()
24  )
25  )
26  );
27 
28  alpharAUfs.set
29  (
30  phasei,
31  (
32  fvc::interpolate(max(alpha, phase.residualAlpha())*rAUs[phasei])
33  ).ptr()
34  );
35 }
36 
37 // Lift, wall-lubrication and turbulent diffusion fluxes
38 PtrList<surfaceScalarField> phiFs(phases.size());
39 {
40  autoPtr<PtrList<volVectorField>> Fs = fluid.Fs();
41 
43  {
44  phaseModel& phase = phases[phasei];
45 
46  if (Fs().set(phasei))
47  {
48  phiFs.set
49  (
50  phasei,
52  (
53  IOobject::groupName("phiF", phase.name()),
54  fvc::flux(rAUs[phasei]*Fs()[phasei])
55  )
56  );
57  }
58  }
59 }
60 {
61  autoPtr<PtrList<surfaceScalarField>> phiDs = fluid.phiDs(rAUs);
62 
64  {
65  phaseModel& phase = phases[phasei];
66 
67  if (phiDs().set(phasei))
68  {
69  if (phiFs.set(phasei))
70  {
71  phiFs[phasei] += phiDs()[phasei];
72  }
73  else
74  {
75  phiFs.set
76  (
77  phasei,
79  (
80  IOobject::groupName("phiF", phase.name()),
81  phiDs()[phasei]
82  )
83  );
84  }
85  }
86  }
87 }
88 
89 // --- Pressure corrector loop
90 while (pimple.correct())
91 {
92  volScalarField rho("rho", fluid.rho());
93 
94  // Correct p_rgh for consistency with p and the updated densities
95  p_rgh = p - rho*gh;
96 
97  PtrList<volVectorField> HbyAs(phases.size());
98 
100  {
101  phaseModel& phase = phases[phasei];
102  const volScalarField& alpha = phase;
103 
104  // Correct fixed-flux BCs to be consistent with the velocity BCs
105  MRF.correctBoundaryFlux(phase.U(), phase.phi());
106 
107  HbyAs.set
108  (
109  phasei,
110  new volVectorField
111  (
112  IOobject::groupName("HbyA", phase.name()),
113  phase.U()
114  )
115  );
116 
117  HbyAs[phasei] =
118  rAUs[phasei]
119  *(
120  UEqns[phasei].H()
121  + max(phase.residualAlpha() - alpha, scalar(0))
122  *phase.rho()*phase.U().oldTime()/runTime.deltaT()
123  );
124  }
125 
127  (
128  "ghSnGradRho",
129  ghf*fvc::snGrad(rho)*mesh.magSf()
130  );
131 
132  PtrList<surfaceScalarField> phigFs(phases.size());
134  {
135  phaseModel& phase = phases[phasei];
136 
137  phigFs.set
138  (
139  phasei,
140  (
142  *(
144  - (fvc::interpolate(phase.rho() - rho))*(g & mesh.Sf())
145  - fluid.surfaceTension(phase)*mesh.magSf()
146  )
147  ).ptr()
148  );
149 
150  if (phiFs.set(phasei))
151  {
152  phigFs[phasei] += phiFs[phasei];
153  }
154  }
155 
156  PtrList<surfaceScalarField> phiHbyAs(phases.size());
157 
159  (
160  IOobject
161  (
162  "phiHbyA",
163  runTime.timeName(),
164  mesh,
165  IOobject::NO_READ,
166  IOobject::AUTO_WRITE
167  ),
168  mesh,
169  dimensionedScalar("phiHbyA", dimArea*dimVelocity, 0)
170  );
171 
173  {
174  phaseModel& phase = phases[phasei];
175  const volScalarField& alpha = phase;
176 
177  // ddtPhiCorr filter -- only apply in pure(ish) phases
178  surfaceScalarField alphafBar
179  (
181  );
182  surfaceScalarField phiCorrCoeff(pos0(alphafBar - 0.99));
183 
184  surfaceScalarField::Boundary& phiCorrCoeffBf =
185  phiCorrCoeff.boundaryFieldRef();
186 
187  forAll(mesh.boundary(), patchi)
188  {
189  // Set ddtPhiCorr to 0 on non-coupled boundaries
190  if
191  (
192  !mesh.boundary()[patchi].coupled()
193  || isA<cyclicAMIFvPatch>(mesh.boundary()[patchi])
194  )
195  {
196  phiCorrCoeffBf[patchi] = 0;
197  }
198  }
199 
200  phiHbyAs.set
201  (
202  phasei,
204  (
205  IOobject::groupName("phiHbyA", phase.name()),
206  fvc::flux(HbyAs[phasei])
207  + phiCorrCoeff
209  (
210  alpha.oldTime()*phase.rho()().oldTime()*rAUs[phasei]
211  )
212  *(
213  MRF.absolute(phase.phi().oldTime())
214  - fvc::flux(phase.U().oldTime())
215  )/runTime.deltaT()
216  - phigFs[phasei]
217  )
218  );
219 
221  (
222  phaseSystem::KdTable,
223  fluid.Kds(),
224  KdIter
225  )
226  {
227  const volScalarField& K(*KdIter());
228 
229  const phasePair& pair(fluid.phasePairs()[KdIter.key()]);
230 
231  const phaseModel* phase1 = &pair.phase1();
232  const phaseModel* phase2 = &pair.phase2();
233 
234  forAllConstIter(phasePair, pair, iter)
235  {
236  if (phase1 == &phase)
237  {
238  phiHbyAs[phasei] +=
239  fvc::interpolate(rAUs[phasei]*K)
240  *MRF.absolute(phase2->phi());
241 
242  HbyAs[phasei] += rAUs[phasei]*K*phase2->U();
243  }
244 
245  Swap(phase1, phase2);
246  }
247  }
248 
250  }
251 
252  MRF.makeRelative(phiHbyA);
253 
254  // Construct pressure "diffusivity"
256  (
257  IOobject
258  (
259  "rAUf",
260  runTime.timeName(),
261  mesh
262  ),
263  mesh,
264  dimensionedScalar("rAUf", dimensionSet(-1, 3, 1, 0, 0), 0)
265  );
266 
268  {
269  rAUf += alphafs[phasei]*alpharAUfs[phasei];
270  }
271  rAUf = mag(rAUf);
272 
273 
274  // Update the fixedFluxPressure BCs to ensure flux consistency
275  {
276  surfaceScalarField::Boundary phib(phi.boundaryField());
277  phib = 0;
279  {
280  phaseModel& phase = phases[phasei];
281  phib += alphafs[phasei].boundaryField()*phase.phi().boundaryField();
282  }
283 
285  (
286  p_rgh.boundaryFieldRef(),
287  (
288  phiHbyA.boundaryField() - phib
289  )/(mesh.magSf().boundaryField()*rAUf.boundaryField())
290  );
291  }
292 
293  PtrList<fvScalarMatrix> pEqnComps(phases.size());
295  {
296  phaseModel& phase = phases[phasei];
297  const volScalarField& alpha = phase;
298  volScalarField& rho = phase.thermo().rho();
299 
300  if (phase.compressible())
301  {
302  if (pimple.transonic())
303  {
305  (
306  IOobject::groupName("phid", phase.name()),
307  fvc::interpolate(phase.thermo().psi())*phase.phi()
308  );
309 
310  pEqnComps.set
311  (
312  phasei,
313  (
314  (
315  phase.continuityError()
316  - fvc::Sp
317  (
318  fvc::ddt(alpha) + fvc::div(phase.alphaPhi()),
319  rho
320  )
321  )/rho
322  + correction
323  (
324  (alpha/rho)*
325  (
326  phase.thermo().psi()*fvm::ddt(p_rgh)
327  + fvm::div(phid, p_rgh)
328  - fvm::Sp(fvc::div(phid), p_rgh)
329  )
330  )
331  ).ptr()
332  );
333 
335  (
336  pEqnComps[phasei].faceFluxCorrectionPtr()
337  );
338  pEqnComps[phasei].relax();
339  }
340  else
341  {
342  pEqnComps.set
343  (
344  phasei,
345  (
346  (
347  phase.continuityError()
348  - fvc::Sp
349  (
350  (fvc::ddt(alpha) + fvc::div(phase.alphaPhi())),
351  rho
352  )
353  )/rho
354  + (alpha*phase.thermo().psi()/rho)
355  *correction(fvm::ddt(p_rgh))
356  ).ptr()
357  );
358  }
359  }
360  else
361  {
362  pEqnComps.set
363  (
364  phasei,
365  fvm::Su(-(fvOptions(alpha, rho)&rho)/rho, p_rgh).ptr()
366  );
367  }
368 
369  if (fluid.transfersMass(phase))
370  {
371  if (pEqnComps.set(phasei))
372  {
373  pEqnComps[phasei] -= fluid.dmdt(phase)/rho;
374  }
375  else
376  {
377  pEqnComps.set
378  (
379  phasei,
380  fvm::Su(-fluid.dmdt(phase)/rho, p_rgh)
381  );
382  }
383  }
384  }
385 
386  // Cache p prior to solve for density update
387  volScalarField p_rgh_0(p_rgh);
388 
389  // Iterate over the pressure equation to correct for non-orthogonality
390  while (pimple.correctNonOrthogonal())
391  {
392  // Construct the transport part of the pressure equation
393  fvScalarMatrix pEqnIncomp
394  (
396  - fvm::laplacian(rAUf, p_rgh)
397  );
398 
399  {
400  fvScalarMatrix pEqn(pEqnIncomp);
401 
403  {
404  if (pEqnComps.set(phasei))
405  {
406  pEqn += pEqnComps[phasei];
407  }
408  }
409 
410  solve
411  (
412  pEqn,
413  mesh.solver(p_rgh.select(pimple.finalInnerIter()))
414  );
415  }
416 
417  // Correct fluxes and velocities on last non-orthogonal iteration
418  if (pimple.finalNonOrthogonalIter())
419  {
420  phi = phiHbyA + pEqnIncomp.flux();
421 
422  surfaceScalarField mSfGradp("mSfGradp", pEqnIncomp.flux()/rAUf);
423 
425  {
426  phaseModel& phase = phases[phasei];
427 
428  phase.phi() = phiHbyAs[phasei] + alpharAUfs[phasei]*mSfGradp;
429 
430  // Set the phase dilatation rates
431  if (pEqnComps.set(phasei))
432  {
433  phase.divU(-pEqnComps[phasei] & p_rgh);
434  }
435  }
436 
437  // Optionally relax pressure for velocity correction
438  p_rgh.relax();
439 
440  mSfGradp = pEqnIncomp.flux()/rAUf;
441 
443  {
444  phaseModel& phase = phases[phasei];
445 
446  phase.U() =
447  HbyAs[phasei]
449  (
450  alpharAUfs[phasei]*mSfGradp
451  - phigFs[phasei]
452  );
453  phase.U().correctBoundaryConditions();
454  fvOptions.correct(phase.U());
455  }
456  }
457  }
458 
459  // Update and limit the static pressure
460  p = max(p_rgh + rho*gh, pMin);
461 
462  // Limit p_rgh
463  p_rgh = p - rho*gh;
464 
465  // Update densities from change in p_rgh
467  {
468  phaseModel& phase = phases[phasei];
469  phase.thermo().rho() += phase.thermo().psi()*(p_rgh - p_rgh_0);
470  }
471 
472  // Correct p_rgh for consistency with p and the updated densities
473  rho = fluid.rho();
474  p_rgh = p - rho*gh;
475  p_rgh.correctBoundaryConditions();
476 }
tmp< fvMatrix< Type > > correction(const fvMatrix< Type > &)
Return the correction form of the given matrix.
K
Definition: pEqn.H:86
fvMatrix< scalar > fvScalarMatrix
Definition: fvMatricesFwd.H:42
rho oldTime()
zeroField Su
Definition: alphaSuSp.H:1
multiphaseSystem & fluid
Definition: createFields.H:11
p
Definition: pEqn.H:50
label phasei
Definition: pEqn.H:27
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
phiHbyA
Definition: pEqn.H:20
multiphaseSystem::phaseModelList & phases
Definition: createFields.H:12
tmp< GeometricField< Type, fvPatchField, volMesh > > div(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcDiv.C:47
const dictionary & pimple
GeometricField< vector, fvPatchField, volMesh > volVectorField
Definition: volFieldsFwd.H:55
tmp< GeometricField< Type, fvPatchField, volMesh > > laplacian(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvcLaplacian.C:45
forAll(phases, phasei)
Definition: pEqn.H:5
fv::options & fvOptions
const surfaceScalarField & ghf
tmp< GeometricField< Type, fvPatchField, volMesh > > ddt(const dimensioned< Type > dt, const fvMesh &mesh)
Definition: fvcDdt.C:45
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:52
dynamicFvMesh & mesh
void Swap(T &a, T &b)
Definition: Swap.H:43
IOMRFZoneList & MRF
PtrList< volScalarField > rAUs(fluid.phases().size())
PtrList< surfaceScalarField > alpharAUfs(phases.size())
rhoEqn solve()
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:29
phaseModel & phase1
p_rgh
Definition: pEqn.H:134
dimensionedScalar pos0(const dimensionedScalar &ds)
const dimensionedVector & g
dimensionedScalar pMin("pMin", dimPressure, fluid)
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
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.
PtrList< volVectorField > HbyAs(fluid.phases().size())
surfaceScalarField phid("phid", fvc::interpolate(psi) *(fvc::flux(HbyA)+rhorAUf *fvc::ddtCorr(rho, U, phi)/fvc::interpolate(rho)))
PtrList< surfaceScalarField > alphafs(phases.size())
surfaceScalarField rAUf("rAUf", fvc::interpolate(rAU))
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> reconstruct(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
label patchi
surfaceScalarField ghSnGradRho(ghf *fvc::snGrad(rho) *mesh.magSf())
PtrList< fvVectorMatrix > UEqns(fluid.phases().size())
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
setSnGrad< fixedFluxPressureFvPatchScalarField >(p_rgh.boundaryFieldRef(),(phiHbyA.boundaryField() - MRF.relative(phib))/(mesh.magSf().boundaryField() *rAUf.boundaryField()))
const volScalarField & gh
volScalarField p_rgh_0(p_rgh)
PtrList< surfaceScalarField > phiHbyAs(fluid.phases().size())
tmp< GeometricField< Type, fvPatchField, volMesh > > average(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Area-weighted average a surfaceField creating a volField.
Definition: fvcAverage.C:46
dimensioned< scalar > mag(const dimensioned< Type > &)
phi
Definition: pEqn.H:18
phib
Definition: pEqn.H:191
phaseModel & phase2
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
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
rho
Definition: pEqn.H:1
void deleteDemandDrivenData(DataPtr &dataPtr)
PtrList< surfaceScalarField > phiFs(phases.size())
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > snGrad(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvcSnGrad.C:45
const dimensionSet dimArea(sqr(dimLength))
Definition: dimensionSets.H:57
zeroField Sp
Definition: alphaSuSp.H:2
const dimensionSet dimVelocity