pEqn.H
Go to the documentation of this file.
1 // Face volume fractions
2 PtrList<surfaceScalarField> alphafs(phases.size());
4 {
5  phaseModel& phase = phases[phasei];
6  const volScalarField& alpha = phase;
7 
8  alphafs.set(phasei, fvc::interpolate(alpha).ptr());
9  alphafs[phasei].rename("pEqn" + alphafs[phasei].name());
10 }
11 
12 // Diagonal coefficients
13 rAUs.clear();
14 rAUs.setSize(phases.size());
15 
16 forAll(fluid.movingPhases(), movingPhasei)
17 {
18  phaseModel& phase = fluid.movingPhases()[movingPhasei];
19  const volScalarField& alpha = phase;
20 
21  rAUs.set
22  (
23  phase.index(),
24  new volScalarField
25  (
26  IOobject::groupName("rAU", phase.name()),
27  1.0
28  /(
29  UEqns[phase.index()].A()
30  + byDt(max(phase.residualAlpha() - alpha, scalar(0))*phase.rho())
31  )
32  )
33  );
34 }
35 fluid.fillFields("rAU", dimTime/dimDensity, rAUs);
36 
37 // Phase diagonal coefficients
38 PtrList<surfaceScalarField> alpharAUfs(phases.size());
40 {
41  phaseModel& phase = phases[phasei];
42  const volScalarField& alpha = phase;
43 
44  alpharAUfs.set
45  (
46  phasei,
47  (
48  fvc::interpolate(max(alpha, phase.residualAlpha())*rAUs[phasei])
49  ).ptr()
50  );
51 }
52 
53 // Explicit force fluxes
54 PtrList<surfaceScalarField> phiFs(fluid.phiFs(rAUs));
55 
56 // --- Pressure corrector loop
57 while (pimple.correct())
58 {
59  volScalarField rho("rho", fluid.rho());
60 
61  // Correct p_rgh for consistency with p and the updated densities
62  p_rgh = p - rho*gh;
63 
64  // Correct fixed-flux BCs to be consistent with the velocity BCs
65  forAll(fluid.movingPhases(), movingPhasei)
66  {
67  phaseModel& phase = fluid.movingPhases()[movingPhasei];
68  MRF.correctBoundaryFlux(phase.U(), phase.phiRef());
69  }
70 
71  // Combined buoyancy and force fluxes
72  PtrList<surfaceScalarField> phigFs(phases.size());
73  {
74  const surfaceScalarField ghSnGradRho
75  (
76  "ghSnGradRho",
77  ghf*fvc::snGrad(rho)*mesh.magSf()
78  );
79 
81  {
82  phaseModel& phase = phases[phasei];
83 
84  phigFs.set
85  (
86  phasei,
87  (
89  *(
90  ghSnGradRho
91  - (fvc::interpolate(phase.rho() - rho))*(g & mesh.Sf())
92  - fluid.surfaceTension(phase)*mesh.magSf()
93  )
94  ).ptr()
95  );
96 
97  if (phiFs.set(phasei))
98  {
99  phigFs[phasei] += phiFs[phasei];
100  }
101  }
102  }
103 
104  // Predicted velocities and fluxes for each phase
105  PtrList<volVectorField> HbyAs(phases.size());
106  PtrList<surfaceScalarField> phiHbyAs(phases.size());
107  {
108  // Correction force fluxes
109  PtrList<surfaceScalarField> ddtCorrByAs(fluid.ddtCorrByAs(rAUs));
110 
111  forAll(fluid.movingPhases(), movingPhasei)
112  {
113  phaseModel& phase = fluid.movingPhases()[movingPhasei];
114  const volScalarField& alpha = phase;
115 
116  HbyAs.set
117  (
118  phase.index(),
119  new volVectorField
120  (
121  IOobject::groupName("HbyA", phase.name()),
122  phase.U()
123  )
124  );
125 
126  HbyAs[phase.index()] =
127  rAUs[phase.index()]
128  *(
129  UEqns[phase.index()].H()
130  + byDt
131  (
132  max(phase.residualAlpha() - alpha, scalar(0))
133  *phase.rho()
134  )
135  *phase.U()().oldTime()
136  );
137 
138  phiHbyAs.set
139  (
140  phase.index(),
142  (
143  IOobject::groupName("phiHbyA", phase.name()),
144  fvc::flux(HbyAs[phase.index()])
145  - phigFs[phase.index()]
146  - ddtCorrByAs[phase.index()]
147  )
148  );
149  }
150  }
151  fluid.fillFields("HbyA", dimVelocity, HbyAs);
152  fluid.fillFields("phiHbyA", dimForce/dimDensity/dimVelocity, phiHbyAs);
153 
154  // Add explicit drag forces and fluxes
155  PtrList<volVectorField> KdUByAs(fluid.KdUByAs(rAUs));
156  PtrList<surfaceScalarField> phiKdPhis(fluid.phiKdPhis(rAUs));
157 
159  {
160  if (KdUByAs.set(phasei))
161  {
162  HbyAs[phasei] -= KdUByAs[phasei];
163  }
164 
165  if (phiKdPhis.set(phasei))
166  {
167  phiHbyAs[phasei] -= phiKdPhis[phasei];
168  }
169  }
170 
171  // Total predicted flux
173  (
174  IOobject
175  (
176  "phiHbyA",
177  runTime.timeName(),
178  mesh,
179  IOobject::NO_READ,
180  IOobject::AUTO_WRITE
181  ),
182  mesh,
184  );
185 
187  {
188  phiHbyA += alphafs[phasei]*phiHbyAs[phasei];
189  }
190 
191  MRF.makeRelative(phiHbyA);
192 
193  // Construct pressure "diffusivity"
195  (
196  IOobject
197  (
198  "rAUf",
199  runTime.timeName(),
200  mesh
201  ),
202  mesh,
203  dimensionedScalar(dimensionSet(-1, 3, 1, 0, 0), 0)
204  );
205 
207  {
208  rAUf += alphafs[phasei]*alpharAUfs[phasei];
209  }
210 
211  rAUf = mag(rAUf);
212 
213  // Update the fixedFluxPressure BCs to ensure flux consistency
214  {
215  surfaceScalarField::Boundary phib(phi.boundaryField());
216  phib = 0;
218  {
219  phaseModel& phase = phases[phasei];
220  phib +=
221  alphafs[phasei].boundaryField()*phase.phi()().boundaryField();
222  }
223 
224  setSnGrad<fixedFluxPressureFvPatchScalarField>
225  (
226  p_rgh.boundaryFieldRef(),
227  (
228  phiHbyA.boundaryField() - phib
229  )/(mesh.magSf().boundaryField()*rAUf.boundaryField())
230  );
231  }
232 
233  // Compressible pressure equations
234  PtrList<fvScalarMatrix> pEqnComps(phases.size());
235  PtrList<volScalarField> dmdts(fluid.dmdts());
237  {
238  phaseModel& phase = phases[phasei];
239  const volScalarField& alpha = phase;
240  volScalarField& rho = phase.thermoRef().rho();
241 
242  pEqnComps.set(phasei, new fvScalarMatrix(p_rgh, dimVolume/dimTime));
243  fvScalarMatrix& pEqnComp = pEqnComps[phasei];
244 
245  // Density variation
246  if (!phase.isochoric() || !phase.pure())
247  {
248  pEqnComp +=
249  (
250  fvc::ddt(alpha, rho) + fvc::div(phase.alphaRhoPhi())
251  - fvc::Sp(fvc::ddt(alpha) + fvc::div(phase.alphaPhi()), rho)
252  )/rho;
253  }
254 
255  // Compressibility
256  if (!phase.incompressible())
257  {
258  if (pimple.transonic())
259  {
260  const surfaceScalarField phid
261  (
262  IOobject::groupName("phid", phase.name()),
263  fvc::interpolate(phase.thermo().psi())*phase.phi()
264  );
265 
266  pEqnComp +=
267  correction
268  (
269  (alpha/rho)*
270  (
271  phase.thermo().psi()*fvm::ddt(p_rgh)
272  + fvm::div(phid, p_rgh)
273  - fvm::Sp(fvc::div(phid), p_rgh)
274  )
275  );
276 
277  pEqnComps[phasei].relax();
278  }
279  else
280  {
281  pEqnComp +=
282  (alpha*phase.thermo().psi()/rho)
283  *correction(fvm::ddt(p_rgh));
284  }
285  }
286 
287  // Option sources
288  if (fvOptions.appliesToField(rho.name()))
289  {
290  pEqnComp -= (fvOptions(alpha, rho) & rho)/rho;
291  }
292 
293  // Mass transfer
294  if (dmdts.set(phasei))
295  {
296  pEqnComp -= dmdts[phasei]/rho;
297  }
298  }
299 
300  // Cache p prior to solve for density update
301  volScalarField p_rgh_0(p_rgh);
302 
303  // Iterate over the pressure equation to correct for non-orthogonality
304  while (pimple.correctNonOrthogonal())
305  {
306  // Construct the transport part of the pressure equation
307  fvScalarMatrix pEqnIncomp
308  (
310  - fvm::laplacian(rAUf, p_rgh)
311  );
312 
313  // Solve
314  {
315  fvScalarMatrix pEqn(pEqnIncomp);
316 
318  {
319  pEqn += pEqnComps[phasei];
320  }
321 
322  if (fluid.incompressible())
323  {
324  pEqn.setReference(pRefCell, getRefCellValue(p_rgh, pRefCell));
325  }
326 
327  pEqn.solve();
328  }
329 
330  // Correct fluxes and velocities on last non-orthogonal iteration
331  if (pimple.finalNonOrthogonalIter())
332  {
333  phi = phiHbyA + pEqnIncomp.flux();
334 
335  surfaceScalarField mSfGradp("mSfGradp", pEqnIncomp.flux()/rAUf);
336 
337  forAll(fluid.movingPhases(), movingPhasei)
338  {
339  phaseModel& phase = fluid.movingPhases()[movingPhasei];
340 
341  phase.phiRef() =
342  phiHbyAs[phase.index()]
343  + alpharAUfs[phase.index()]*mSfGradp;
344 
345  // Set the phase dilatation rate
346  phase.divU(-pEqnComps[phase.index()] & p_rgh);
347  }
348 
349  // Optionally relax pressure for velocity correction
350  p_rgh.relax();
351 
352  mSfGradp = pEqnIncomp.flux()/rAUf;
353 
354  forAll(fluid.movingPhases(), movingPhasei)
355  {
356  phaseModel& phase = fluid.movingPhases()[movingPhasei];
357 
358  phase.URef() =
359  HbyAs[phase.index()]
361  (
362  alpharAUfs[phase.index()]*mSfGradp
363  - phigFs[phase.index()]
364  );
365  }
366 
367  if (partialElimination)
368  {
369  fluid.partialElimination(rAUs, KdUByAs, alphafs, phiKdPhis);
370  }
371  else
372  {
373  forAll(fluid.movingPhases(), movingPhasei)
374  {
375  phaseModel& phase = fluid.movingPhases()[movingPhasei];
376  MRF.makeRelative(phase.phiRef());
377  }
378  }
379 
380  forAll(fluid.movingPhases(), movingPhasei)
381  {
382  phaseModel& phase = fluid.movingPhases()[movingPhasei];
383 
384  phase.URef().correctBoundaryConditions();
385  fvOptions.correct(phase.URef());
386  }
387  }
388  }
389 
390  // Update and limit the static pressure
391  p = max(p_rgh + rho*gh, pMin);
392 
393  // Account for static pressure reference
394  if (p_rgh.needReference() && fluid.incompressible())
395  {
397  (
398  "p",
399  p.dimensions(),
401  );
402  }
403 
404  // Limit p_rgh
405  p_rgh = p - rho*gh;
406 
407  // Update densities from change in p_rgh
409  {
410  phaseModel& phase = phases[phasei];
411  phase.thermoRef().rho() += phase.thermo().psi()*(p_rgh - p_rgh_0);
412  }
413 
414  // Correct p_rgh for consistency with p and the updated densities
415  rho = fluid.rho();
416  p_rgh = p - rho*gh;
417  p_rgh.correctBoundaryConditions();
418 }
419 
420 if (!fluid.implicitPhasePressure())
421 {
422  rAUs.clear();
423 }
forAll(phases, phasei)
Definition: pEqn.H:3
tmp< fvMatrix< Type > > correction(const fvMatrix< Type > &)
Return the correction form of the given matrix.
fvMatrix< scalar > fvScalarMatrix
Definition: fvMatricesFwd.H:42
rho oldTime()
fv::options & fvOptions
rho
Definition: pEqn.H:1
Info<< "Constructing momentum equations"<< endl;PtrList< fvVectorMatrix > UEqns(phases.size())
pimpleNoLoopControl & pimple
p
Definition: pEqn.H:50
label phasei
Definition: pEqn.H:27
IOMRFZoneList & MRF
surfaceScalarField rAUf("rAUf", fvc::interpolate(rAU))
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
PtrList< surfaceScalarField > alphafs(phases.size())
volScalarField p_rgh_0(p_rgh)
tmp< GeometricField< Type, fvPatchField, volMesh > > div(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcDiv.C:47
p_rgh
Definition: pEqn.H:140
engineTime & runTime
GeometricField< vector, fvPatchField, volMesh > volVectorField
Definition: volFieldsFwd.H:58
tmp< GeometricField< Type, fvPatchField, volMesh > > laplacian(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvcLaplacian.C:45
scalar getRefCellValue(const volScalarField &field, const label refCelli)
Return the current value of field in the reference cell.
Definition: findRefCell.C:136
phi
Definition: pEqn.H:104
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:57
const dimensionSet dimVolume(pow3(dimLength))
Definition: dimensionSets.H:58
PtrList< surfaceScalarField > phiFs(fluid.phiFs(rAUs))
dynamicFvMesh & mesh
Info<< "Reading field p_rgh\"<< endl;volScalarField p_rgh(IOobject("p_rgh", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE), mesh);label pRefCell=0;scalar pRefValue=0.0;if(fluid.incompressible()){ p=max(p_rgh+fluid.rho() *gh, pMin);if(p_rgh.needReference()) { setRefCell(p, p_rgh, pimple.dict(), pRefCell, pRefValue);p+=dimensionedScalar("p", p.dimensions(), pRefValue - getRefCellValue(p, pRefCell));p_rgh=p - fluid.rho() *gh;}}mesh.setFluxRequired(p_rgh.name());PtrList< volScalarField > rAUs
Definition: createFields.H:67
phaseSystem & fluid
Definition: createFields.H:11
PtrList< surfaceScalarField > alpharAUfs(phases.size())
dimensionedScalar pMin("pMin", dimPressure, fluid)
const dimensionSet dimForce
const surfaceScalarField & ghf
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
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.
const dimensionSet dimDensity
phiHbyA
Definition: pEqn.H:32
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> reconstruct(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
label pRefCell
Definition: createFields.H:106
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
Definition: dimensionSets.H:51
phaseSystem::phaseModelList & phases
Definition: createFields.H:12
const volScalarField & gh
dimensioned< scalar > mag(const dimensioned< Type > &)
volScalarField alpha(IOobject("alpha", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
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 dimensionedVector & g
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
scalar pRefValue
Definition: createFields.H:107
zeroField Sp
Definition: alphaSuSp.H:2
const dimensionSet dimVelocity