pEqn.H
Go to the documentation of this file.
1const surfaceScalarField alphaf1("alphaf1", fvc::interpolate(alpha1));
2const surfaceScalarField alphaf2("alphaf2", scalar(1) - alphaf1);
3
4PtrList<volScalarField> rAUs;
5rAUs.append
6(
7 new volScalarField
8 (
9 IOobject::groupName("rAU", phase1.name()),
10 1.0
11 /(
12 U1Eqn.A()
13 + byDt(max(phase1.residualAlpha() - alpha1, scalar(0))*rho1)
14 )
15 )
16);
17rAUs.append
18(
19 new volScalarField
20 (
21 IOobject::groupName("rAU", phase2.name()),
22 1.0
23 /(
24 U2Eqn.A()
25 + byDt(max(phase2.residualAlpha() - alpha2, scalar(0))*rho2)
26 )
27 )
28);
29const volScalarField& rAU1 = rAUs[0];
30const volScalarField& rAU2 = rAUs[1];
31
32const surfaceScalarField alpharAUf1
33(
34 fvc::interpolate(max(alpha1, phase1.residualAlpha())*rAU1)
35);
36const surfaceScalarField alpharAUf2
37(
38 fvc::interpolate(max(alpha2, phase2.residualAlpha())*rAU2)
39);
40
41// Drag coefficients
42const volScalarField Kd(fluid.Kd());
43const volScalarField rAUKd1(rAU1*Kd);
44const volScalarField rAUKd2(rAU2*Kd);
45const surfaceScalarField phiKd1(fvc::interpolate(rAUKd1));
46const surfaceScalarField phiKd2(fvc::interpolate(rAUKd2));
47
48// Explicit force fluxes
49PtrList<surfaceScalarField> phiFs(fluid.phiFs(rAUs));
50const surfaceScalarField& phiF1 = phiFs[0];
51const surfaceScalarField& phiF2 = phiFs[1];
52
53// --- Pressure corrector loop
54while (pimple.correct())
55{
56 volScalarField rho("rho", fluid.rho());
57
58 // Correct p_rgh for consistency with p and the updated densities
59 p_rgh = p - rho*gh;
60
61 // Correct fixed-flux BCs to be consistent with the velocity BCs
62 MRF.correctBoundaryFlux(U1, phi1);
63 MRF.correctBoundaryFlux(U2, phi2);
64
65 // Combined buoyancy and force fluxes
66 const surfaceScalarField ghSnGradRho
67 (
68 "ghSnGradRho",
69 ghf*fvc::snGrad(rho)*mesh.magSf()
70 );
71
72 const surfaceScalarField phigF1
73 (
75 *(
77 - alphaf2*fvc::interpolate(rho1 - rho2)*(g & mesh.Sf())
78 )
79 + phiF1
80 );
81
82 const surfaceScalarField phigF2
83 (
85 *(
87 - alphaf1*fvc::interpolate(rho2 - rho1)*(g & mesh.Sf())
88 )
89 + phiF2
90 );
91
92 // Predicted velocities
93 volVectorField HbyA1
94 (
95 IOobject::groupName("HbyA", phase1.name()),
96 U1
97 );
98 HbyA1 =
99 rAU1
100 *(
101 U1Eqn.H()
102 + byDt(max(phase1.residualAlpha() - alpha1, scalar(0))*rho1)
103 *U1.oldTime()
104 );
105
106 volVectorField HbyA2
107 (
108 IOobject::groupName("HbyA", phase2.name()),
109 U2
110 );
111 HbyA2 =
112 rAU2
113 *(
114 U2Eqn.H()
115 + byDt(max(phase2.residualAlpha() - alpha2, scalar(0))*rho2)
116 *U2.oldTime()
117 );
118
119 // Correction force fluxes
120 PtrList<surfaceScalarField> ddtCorrByAs(fluid.ddtCorrByAs(rAUs));
121
122 // Predicted fluxes
123 const surfaceScalarField phiHbyA1
124 (
125 IOobject::groupName("phiHbyA", phase1.name()),
126 fvc::flux(HbyA1) - phigF1 - ddtCorrByAs[0]
127 );
128
129 const surfaceScalarField phiHbyA2
130 (
131 IOobject::groupName("phiHbyA", phase2.name()),
132 fvc::flux(HbyA2) - phigF2 - ddtCorrByAs[1]
133 );
134
135 ddtCorrByAs.clear();
136
137 // Drag fluxes
138 PtrList<surfaceScalarField> phiKdPhis(fluid.phiKdPhis(rAUs));
139 const surfaceScalarField& phiKdPhi1 = phiKdPhis[0];
140 const surfaceScalarField& phiKdPhi2 = phiKdPhis[1];
141
142 // Total predicted flux
143 surfaceScalarField phiHbyA
144 (
145 "phiHbyA",
146 alphaf1*(phiHbyA1 - phiKdPhi1) + alphaf2*(phiHbyA2 - phiKdPhi2)
147 );
148
149 MRF.makeRelative(phiHbyA);
150
151 phiKdPhis.clear();
152
153 // Construct pressure "diffusivity"
154 const surfaceScalarField rAUf
155 (
156 "rAUf",
158 );
159
160 // Update the fixedFluxPressure BCs to ensure flux consistency
162 (
163 p_rgh.boundaryFieldRef(),
164 (
165 phiHbyA.boundaryField()
166 - (
167 alphaf1.boundaryField()*phi1.boundaryField()
168 + alphaf2.boundaryField()*phi2.boundaryField()
169 )
170 )/(mesh.magSf().boundaryField()*rAUf.boundaryField())
171 );
172
173 // Construct the compressibility parts of the pressure equation
174 tmp<fvScalarMatrix> pEqnComp1, pEqnComp2;
175 if (phase1.compressible())
176 {
177 if (pimple.transonic())
178 {
179 const surfaceScalarField phid1
180 (
181 IOobject::groupName("phid", phase1.name()),
182 fvc::interpolate(psi1)*phi1
183 );
184
185 pEqnComp1 =
186 (
187 fvc::ddt(alpha1, rho1) + fvc::div(phase1.alphaRhoPhi())
188 - fvc::Sp(fvc::ddt(alpha1) + fvc::div(alphaPhi1), rho1)
189 )/rho1
190 + correction
191 (
192 (alpha1/rho1)*
193 (
194 psi1*fvm::ddt(p_rgh)
195 + fvm::div(phid1, p_rgh) - fvm::Sp(fvc::div(phid1), p_rgh)
196 )
197 );
198
199 pEqnComp1.ref().relax();
200 }
201 else
202 {
203 pEqnComp1 =
204 (
205 fvc::ddt(alpha1, rho1) + fvc::div(phase1.alphaRhoPhi())
206 - fvc::Sp(fvc::ddt(alpha1) + fvc::div(alphaPhi1), rho1)
207 )/rho1
208 + (alpha1*psi1/rho1)*correction(fvm::ddt(p_rgh));
209 }
210 }
211 if (phase2.compressible())
212 {
213 if (pimple.transonic())
214 {
215 const surfaceScalarField phid2
216 (
217 IOobject::groupName("phid", phase2.name()),
218 fvc::interpolate(psi2)*phi2
219 );
220
221 pEqnComp2 =
222 (
223 fvc::ddt(alpha2, rho2) + fvc::div(phase2.alphaRhoPhi())
224 - fvc::Sp(fvc::ddt(alpha2) + fvc::div(alphaPhi2), rho2)
225 )/rho2
226 + correction
227 (
228 (alpha2/rho2)*
229 (
230 psi2*fvm::ddt(p_rgh)
231 + fvm::div(phid2, p_rgh) - fvm::Sp(fvc::div(phid2), p_rgh)
232 )
233 );
234
235 pEqnComp2.ref().relax();
236 }
237 else
238 {
239 pEqnComp2 =
240 (
241 fvc::ddt(alpha2, rho2) + fvc::div(phase2.alphaRhoPhi())
242 - fvc::Sp(fvc::ddt(alpha2) + fvc::div(alphaPhi2), rho2)
243 )/rho2
244 + (alpha2*psi2/rho2)*correction(fvm::ddt(p_rgh));
245 }
246 }
247
248 // Add option sources
249 {
250 if (fvOptions.appliesToField(rho1.name()))
251 {
252 tmp<fvScalarMatrix> optEqn1 = fvOptions(alpha1, rho1);
253 if (pEqnComp1.valid())
254 {
255 pEqnComp1.ref() -= (optEqn1 & rho1)/rho1;
256 }
257 else
258 {
259 pEqnComp1 = fvm::Su(- (optEqn1 & rho1)/rho1, p_rgh);
260 }
261 }
262 if (fvOptions.appliesToField(rho2.name()))
263 {
264 tmp<fvScalarMatrix> optEqn2 = fvOptions(alpha2, rho2);
265 if (pEqnComp2.valid())
266 {
267 pEqnComp2.ref() -= (optEqn2 & rho2)/rho2;
268 }
269 else
270 {
271 pEqnComp2 = fvm::Su(- (optEqn2 & rho2)/rho2, p_rgh);
272 }
273 }
274 }
275
276 // Add mass transfer
277 {
278 PtrList<volScalarField> dmdts(fluid.dmdts());
279 if (dmdts.set(0))
280 {
281 if (pEqnComp1.valid())
282 {
283 pEqnComp1.ref() -= dmdts[0]/rho1;
284 }
285 else
286 {
287 pEqnComp1 = fvm::Su(- dmdts[0]/rho1, p_rgh);
288 }
289 }
290 if (dmdts.set(1))
291 {
292 if (pEqnComp2.valid())
293 {
294 pEqnComp2.ref() -= dmdts[1]/rho2;
295 }
296 else
297 {
298 pEqnComp2 = fvm::Su(- dmdts[1]/rho2, p_rgh);
299 }
300 }
301 }
302
303 // Cache p prior to solve for density update
304 const volScalarField p_rgh_0(p_rgh);
305
306 // Iterate over the pressure equation to correct for non-orthogonality
307 while (pimple.correctNonOrthogonal())
308 {
309 // Construct the transport part of the pressure equation
310 fvScalarMatrix pEqnIncomp
311 (
312 fvc::div(phiHbyA)
313 - fvm::laplacian(rAUf, p_rgh)
314 );
315
316 {
317 fvScalarMatrix pEqn(pEqnIncomp);
318
319 if (pEqnComp1.valid())
320 {
321 pEqn += pEqnComp1();
322 }
323
324 if (pEqnComp2.valid())
325 {
326 pEqn += pEqnComp2();
327 }
328
329 pEqn.solve();
330 }
331
332 // Correct fluxes and velocities on last non-orthogonal iteration
333 if (pimple.finalNonOrthogonalIter())
334 {
335 phi = phiHbyA + pEqnIncomp.flux();
336
337 surfaceScalarField mSfGradp
338 (
339 "mSfGradp",
340 pEqnIncomp.flux()/rAUf
341 );
342
343 // Partial-elimination phase-flux corrector
344 {
345 const surfaceScalarField phi1s
346 (
347 phiHbyA1 + alpharAUf1*mSfGradp
348 );
349
350 const surfaceScalarField phi2s
351 (
352 phiHbyA2 + alpharAUf2*mSfGradp
353 );
354
355 surfaceScalarField phir
356 (
357 ((phi1s + phiKd1*phi2s) - (phi2s + phiKd2*phi1s))
358 /(1 - phiKd1*phiKd2)
359 );
360
361 phi1 = phi + alphaf2*phir;
362 phi2 = phi - alphaf1*phir;
363 }
364
365 // Set the phase dilatation rates
366 if (pEqnComp1.valid())
367 {
368 phase1.divU(-pEqnComp1 & p_rgh);
369 }
370 if (pEqnComp2.valid())
371 {
372 phase2.divU(-pEqnComp2 & p_rgh);
373 }
374
375 // Optionally relax pressure for velocity correction
376 p_rgh.relax();
377
378 mSfGradp = pEqnIncomp.flux()/rAUf;
379
380 // Partial-elimination phase-velocity corrector
381 {
382 const volVectorField Us1
383 (
384 HbyA1
385 + fvc::reconstruct(alpharAUf1*mSfGradp - phigF1)
386 );
387
388 const volVectorField Us2
389 (
390 HbyA2
391 + fvc::reconstruct(alpharAUf2*mSfGradp - phigF2)
392 );
393
394 const volVectorField U
395 (
396 alpha1*(Us1 + rAUKd1*U2) + alpha2*(Us2 + rAUKd2*U1)
397 );
398
399 const volVectorField Ur
400 (
401 ((1 - rAUKd2)*Us1 - (1 - rAUKd1)*Us2)/(1 - rAUKd1*rAUKd2)
402 );
403
404 U1 = U + alpha2*Ur;
405 U1.correctBoundaryConditions();
406 fvOptions.correct(U1);
407
408 U2 = U - alpha1*Ur;
409 U2.correctBoundaryConditions();
410 fvOptions.correct(U2);
411 }
412 }
413 }
414
415 // Update and limit the static pressure
416 p = max(p_rgh + rho*gh, pMin);
417
418 // Limit p_rgh
419 p_rgh = p - rho*gh;
420
421 // Update densities from change in p_rgh
422 rho1 += psi1*(p_rgh - p_rgh_0);
423 rho2 += psi2*(p_rgh - p_rgh_0);
424
425 // Correct p_rgh for consistency with p and the updated densities
426 rho = fluid.rho();
427 p_rgh = p - rho*gh;
428 p_rgh.correctBoundaryConditions();
429}
Y[inertIndex] max(0.0)
const uniformDimensionedVectorField & g
volScalarField & p_rgh
fv::options & fvOptions
surfaceScalarField & phi
const surfaceScalarField & ghf
IOMRFZoneList & MRF
const volScalarField & gh
pimpleControl & pimple
const volScalarField & alpha1
const volScalarField & psi2
surfaceScalarField & phi2
twoPhaseSystem & fluid
phaseModel & phase1
volScalarField & rho2
const volScalarField & alpha2
const surfaceScalarField & alphaPhi1
surfaceScalarField & phi1
phaseModel & phase2
const volScalarField & psi1
volVectorField & U1
const dimensionedScalar & pMin
volScalarField & rho1
volVectorField & U2
const surfaceScalarField & alphaPhi2
U
Definition: pEqn.H:72
volScalarField & p
phiHbyA
Definition: pcEqn.H:73
dynamicFvMesh & mesh
surfaceScalarField phir(fvc::flux(UdmModel.Udm()))
surfaceScalarField rAUf("rAUf", fvc::interpolate(rAU))
volScalarField p_rgh_0(p_rgh)
surfaceScalarField ghSnGradRho(ghf *fvc::snGrad(rho) *mesh.magSf())
setSnGrad< fixedFluxPressureFvPatchScalarField >(p_rgh.boundaryFieldRef(),(phiHbyA.boundaryField() - MRF.relative(phib))/(mesh.magSf().boundaryField() *rAUf.boundaryField()))
PtrList< surfaceScalarField > phiFs(fluid.phiFs(rAUs))
const surfaceScalarField & phiF1
Definition: pEqn.H:50
const surfaceScalarField alphaf2("alphaf2", scalar(1) - alphaf1)
const surfaceScalarField alpharAUf1(fvc::interpolate(max(alpha1, phase1.residualAlpha()) *rAU1))
const volScalarField Kd(fluid.Kd())
const surfaceScalarField & phiF2
Definition: pEqn.H:51
const surfaceScalarField phiKd2(fvc::interpolate(rAUKd2))
const volScalarField & rAU2
Definition: pEqn.H:30
const volScalarField rAUKd2(rAU2 *Kd)
PtrList< volScalarField > rAUs
Definition: pEqn.H:4
const surfaceScalarField phiKd1(fvc::interpolate(rAUKd1))
const surfaceScalarField alpharAUf2(fvc::interpolate(max(alpha2, phase2.residualAlpha()) *rAU2))
const volScalarField rAUKd1(rAU1 *Kd)
const surfaceScalarField alphaf1("alphaf1", fvc::interpolate(alpha1))
const volScalarField & rAU1
Definition: pEqn.H:29