multiphaseMixture.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2017 OpenFOAM Foundation
9 Copyright (C) 2021 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "multiphaseMixture.H"
30#include "Time.H"
31#include "subCycle.H"
32#include "MULES.H"
33#include "surfaceInterpolate.H"
34#include "fvcGrad.H"
35#include "fvcSnGrad.H"
36#include "fvcDiv.H"
37#include "fvcFlux.H"
38#include "unitConversion.H"
39#include "alphaContactAngleFvPatchScalarField.H"
40
41// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
42
43void Foam::multiphaseMixture::calcAlphas()
44{
45 scalar level = 0.0;
46 alphas_ == 0.0;
47
48 for (const phase& ph : phases_)
49 {
50 alphas_ += level * ph;
51 level += 1.0;
52 }
53}
54
55
56// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
57
59(
60 const volVectorField& U,
62)
63:
64 IOdictionary
65 (
66 IOobject
67 (
68 "transportProperties",
69 U.time().constant(),
70 U.db(),
71 IOobject::MUST_READ_IF_MODIFIED,
72 IOobject::NO_WRITE
73 )
74 ),
75
76 phases_(lookup("phases"), phase::iNew(U, phi)),
77
78 mesh_(U.mesh()),
79 U_(U),
80 phi_(phi),
81
82 rhoPhi_
83 (
84 IOobject
85 (
86 "rhoPhi",
87 mesh_.time().timeName(),
88 mesh_,
89 IOobject::NO_READ,
90 IOobject::NO_WRITE
91 ),
92 mesh_,
94 ),
95
96 alphas_
97 (
98 IOobject
99 (
100 "alphas",
101 mesh_.time().timeName(),
102 mesh_,
103 IOobject::NO_READ,
104 IOobject::AUTO_WRITE
105 ),
106 mesh_,
108 ),
109
110 nu_
111 (
112 IOobject
113 (
114 "nu",
115 mesh_.time().timeName(),
116 mesh_
117 ),
118 mu()/rho()
119 ),
120
121 sigmas_(lookup("sigmas")),
122 dimSigma_(1, 0, -2, 0, 0),
123 deltaN_
124 (
125 "deltaN",
126 1e-8/cbrt(average(mesh_.V()))
127 )
128{
129 rhoPhi_.setOriented();
130
131 calcAlphas();
132 alphas_.write();
133}
134
135
136// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
137
140{
141 auto iter = phases_.cbegin();
142
143 tmp<volScalarField> trho = iter()*iter().rho();
144 volScalarField& rho = trho.ref();
145
146 for (++iter; iter != phases_.cend(); ++iter)
147 {
148 rho += iter()*iter().rho();
149 }
150
151 return trho;
152}
153
154
156Foam::multiphaseMixture::rho(const label patchi) const
157{
158 auto iter = phases_.cbegin();
159
160 tmp<scalarField> trho = iter().boundaryField()[patchi]*iter().rho().value();
161 scalarField& rho = trho.ref();
162
163 for (++iter; iter != phases_.cend(); ++iter)
164 {
165 rho += iter().boundaryField()[patchi]*iter().rho().value();
166 }
167
168 return trho;
169}
170
171
174{
175 auto iter = phases_.cbegin();
176
177 tmp<volScalarField> tmu = iter()*iter().rho()*iter().nu();
178 volScalarField& mu = tmu.ref();
179
180 for (++iter; iter != phases_.cend(); ++iter)
181 {
182 mu += iter()*iter().rho()*iter().nu();
183 }
184
185 return tmu;
186}
187
188
190Foam::multiphaseMixture::mu(const label patchi) const
191{
192 auto iter = phases_.cbegin();
193
194 tmp<scalarField> tmu =
195 (
196 iter().boundaryField()[patchi]
197 *iter().rho().value()
198 *iter().nu(patchi)
199 );
200
201 scalarField& mu = tmu.ref();
202
203 for (++iter; iter != phases_.cend(); ++iter)
204 {
205 mu +=
206 (
207 iter().boundaryField()[patchi]
208 *iter().rho().value()
209 *iter().nu(patchi)
210 );
211 }
212
213 return tmu;
214}
215
216
219{
220 auto iter = phases_.cbegin();
221
222 tmp<surfaceScalarField> tmuf =
223 fvc::interpolate(iter())*iter().rho()*fvc::interpolate(iter().nu());
224 surfaceScalarField& muf = tmuf.ref();
225
226 for (++iter; iter != phases_.cend(); ++iter)
227 {
228 muf +=
229 fvc::interpolate(iter())*iter().rho()*fvc::interpolate(iter().nu());
230 }
231
232 return tmuf;
233}
234
235
238{
239 return nu_;
240}
241
242
244Foam::multiphaseMixture::nu(const label patchi) const
245{
246 return nu_.boundaryField()[patchi];
247}
248
249
252{
253 return muf()/fvc::interpolate(rho());
254}
255
256
259{
260 tmp<surfaceScalarField> tstf
261 (
263 (
264 IOobject
265 (
266 "surfaceTensionForce",
267 mesh_.time().timeName(),
268 mesh_
269 ),
270 mesh_,
271 dimensionedScalar(dimensionSet(1, -2, -2, 0, 0), Zero)
272 )
273 );
274
275 surfaceScalarField& stf = tstf.ref();
276 stf.setOriented();
277
278 forAllConstIters(phases_, iter1)
279 {
280 const phase& alpha1 = iter1();
281
282 auto iter2 = iter1;
283
284 for (++iter2; iter2 != phases_.cend(); ++iter2)
285 {
286 const phase& alpha2 = iter2();
287
288 auto sigma = sigmas_.cfind(interfacePair(alpha1, alpha2));
289
290 if (!sigma.found())
291 {
293 << "Cannot find interface " << interfacePair(alpha1, alpha2)
294 << " in list of sigma values"
295 << exit(FatalError);
296 }
297
298 stf += dimensionedScalar("sigma", dimSigma_, *sigma)
300 (
303 );
304 }
305 }
306
307 return tstf;
308}
309
310
312{
313 correct();
314
315 const Time& runTime = mesh_.time();
316
317 volScalarField& alpha = phases_.first();
318
319 const dictionary& alphaControls = mesh_.solverDict("alpha");
320 label nAlphaSubCycles(alphaControls.get<label>("nAlphaSubCycles"));
321 scalar cAlpha(alphaControls.get<scalar>("cAlpha"));
322
323 if (nAlphaSubCycles > 1)
324 {
325 surfaceScalarField rhoPhiSum
326 (
327 IOobject
328 (
329 "rhoPhiSum",
331 mesh_
332 ),
333 mesh_,
334 dimensionedScalar(rhoPhi_.dimensions(), Zero)
335 );
336
337 dimensionedScalar totalDeltaT = runTime.deltaT();
338
339 for
340 (
341 subCycle<volScalarField> alphaSubCycle(alpha, nAlphaSubCycles);
342 !(++alphaSubCycle).end();
343 )
344 {
345 solveAlphas(cAlpha);
346 rhoPhiSum += (runTime.deltaT()/totalDeltaT)*rhoPhi_;
347 }
348
349 rhoPhi_ = rhoPhiSum;
350 }
351 else
352 {
353 solveAlphas(cAlpha);
354 }
355
356 // Update the mixture kinematic viscosity
357 nu_ = mu()/rho();
358}
359
360
362{
363 for (phase& ph : phases_)
364 {
365 ph.correct();
366 }
367}
368
369
370Foam::tmp<Foam::surfaceVectorField> Foam::multiphaseMixture::nHatfv
371(
372 const volScalarField& alpha1,
374) const
375{
376 /*
377 // Cell gradient of alpha
378 volVectorField gradAlpha =
379 alpha2*fvc::grad(alpha1) - alpha1*fvc::grad(alpha2);
380
381 // Interpolated face-gradient of alpha
382 surfaceVectorField gradAlphaf = fvc::interpolate(gradAlpha);
383 */
384
385 surfaceVectorField gradAlphaf
386 (
389 );
390
391 // Face unit interface normal
392 return gradAlphaf/(mag(gradAlphaf) + deltaN_);
393}
394
395
397(
398 const volScalarField& alpha1,
400) const
401{
402 // Face unit interface normal flux
403 return nHatfv(alpha1, alpha2) & mesh_.Sf();
404}
405
406
407// Correction for the boundary condition on the unit normal nHat on
408// walls to produce the correct contact angle.
409
410// The dynamic contact angle is calculated from the component of the
411// velocity on the direction of the interface, parallel to the wall.
412
413void Foam::multiphaseMixture::correctContactAngle
414(
415 const phase& alpha1,
416 const phase& alpha2,
418) const
419{
422
423 const fvBoundaryMesh& boundary = mesh_.boundary();
424
425 forAll(boundary, patchi)
426 {
427 if (isA<alphaContactAngleFvPatchScalarField>(gb1f[patchi]))
428 {
429 const alphaContactAngleFvPatchScalarField& acap =
430 refCast<const alphaContactAngleFvPatchScalarField>(gb1f[patchi]);
431
432 correctBoundaryContactAngle(acap, patchi, alpha1, alpha2, nHatb);
433 }
434 else if (isA<alphaContactAngleFvPatchScalarField>(gb2f[patchi]))
435 {
436 const alphaContactAngleFvPatchScalarField& acap =
437 refCast<const alphaContactAngleFvPatchScalarField>(gb2f[patchi]);
438
439 correctBoundaryContactAngle(acap, patchi, alpha2, alpha1, nHatb);
440 }
441 }
442}
443
444
445void Foam::multiphaseMixture::correctBoundaryContactAngle
446(
447 const alphaContactAngleFvPatchScalarField& acap,
448 label patchi,
449 const phase& alpha1,
450 const phase& alpha2,
452) const
453{
454 const fvBoundaryMesh& boundary = mesh_.boundary();
455
456 vectorField& nHatPatch = nHatb[patchi];
457
458 vectorField AfHatPatch
459 (
460 mesh_.Sf().boundaryField()[patchi]
461 /mesh_.magSf().boundaryField()[patchi]
462 );
463
464 const auto tp = acap.thetaProps().cfind(interfacePair(alpha1, alpha2));
465
466 if (!tp.found())
467 {
469 << "Cannot find interface " << interfacePair(alpha1, alpha2)
470 << "\n in table of theta properties for patch "
471 << acap.patch().name()
472 << exit(FatalError);
473 }
474
475 const bool matched = (tp.key().first() == alpha1.name());
476
477 const scalar theta0 = degToRad(tp().theta0(matched));
478 scalarField theta(boundary[patchi].size(), theta0);
479
480 const scalar uTheta = tp().uTheta();
481
482 // Calculate the dynamic contact angle if required
483 if (uTheta > SMALL)
484 {
485 const scalar thetaA = degToRad(tp().thetaA(matched));
486 const scalar thetaR = degToRad(tp().thetaR(matched));
487
488 // Calculated the component of the velocity parallel to the wall
489 vectorField Uwall
490 (
491 U_.boundaryField()[patchi].patchInternalField()
492 - U_.boundaryField()[patchi]
493 );
494 Uwall -= (AfHatPatch & Uwall)*AfHatPatch;
495
496 // Find the direction of the interface parallel to the wall
497 vectorField nWall
498 (
499 nHatPatch - (AfHatPatch & nHatPatch)*AfHatPatch
500 );
501
502 // Normalise nWall
503 nWall /= (mag(nWall) + SMALL);
504
505 // Calculate Uwall resolved normal to the interface parallel to
506 // the interface
507 scalarField uwall(nWall & Uwall);
508
509 theta += (thetaA - thetaR)*tanh(uwall/uTheta);
510 }
511
512
513 // Reset nHatPatch to correspond to the contact angle
514
515 scalarField a12(nHatPatch & AfHatPatch);
516
517 scalarField b1(cos(theta));
518
519 scalarField b2(nHatPatch.size());
520
521 forAll(b2, facei)
522 {
523 b2[facei] = cos(acos(a12[facei]) - theta[facei]);
524 }
525
526 scalarField det(1.0 - a12*a12);
527
528 scalarField a((b1 - a12*b2)/det);
529 scalarField b((b2 - a12*b1)/det);
530
531 nHatPatch = a*AfHatPatch + b*nHatPatch;
532
533 nHatPatch /= (mag(nHatPatch) + deltaN_.value());
534}
535
536
538(
539 const phase& alpha1,
540 const phase& alpha2
541) const
542{
543 tmp<surfaceVectorField> tnHatfv = nHatfv(alpha1, alpha2);
544
545 correctContactAngle(alpha1, alpha2, tnHatfv.ref().boundaryFieldRef());
546
547 // Simple expression for curvature
548 return -fvc::div(tnHatfv & mesh_.Sf());
549}
550
551
554{
555 tmp<volScalarField> tnearInt
556 (
558 (
559 IOobject
560 (
561 "nearInterface",
562 mesh_.time().timeName(),
563 mesh_
564 ),
565 mesh_,
567 )
568 );
569
570 for (const phase& ph : phases_)
571 {
572 tnearInt.ref() = max(tnearInt(), pos0(ph - 0.01)*pos0(0.99 - ph));
573 }
574
575 return tnearInt;
576}
577
578
579void Foam::multiphaseMixture::solveAlphas
580(
581 const scalar cAlpha
582)
583{
584 static label nSolves(-1);
585 ++nSolves;
586
587 const word alphaScheme("div(phi,alpha)");
588 const word alpharScheme("div(phirb,alpha)");
589
590 surfaceScalarField phic(mag(phi_/mesh_.magSf()));
591 phic = min(cAlpha*phic, max(phic));
592
593 PtrList<surfaceScalarField> alphaPhiCorrs(phases_.size());
594 int phasei = 0;
595
596 for (phase& alpha : phases_)
597 {
598 alphaPhiCorrs.set
599 (
600 phasei,
602 (
603 "phi" + alpha.name() + "Corr",
605 (
606 phi_,
607 alpha,
608 alphaScheme
609 )
610 )
611 );
612
613 surfaceScalarField& alphaPhiCorr = alphaPhiCorrs[phasei];
614
615 for (phase& alpha2 : phases_)
616 {
617 if (&alpha2 == &alpha) continue;
618
620
621 alphaPhiCorr += fvc::flux
622 (
624 alpha,
626 );
627 }
628
630 (
631 1.0/mesh_.time().deltaT().value(),
632 geometricOneField(),
633 alpha,
634 phi_,
635 alphaPhiCorr,
636 zeroField(),
637 zeroField(),
638 oneField(),
639 zeroField(),
640 true
641 );
642
643 ++phasei;
644 }
645
646 MULES::limitSum(alphaPhiCorrs);
647
649
650 volScalarField sumAlpha
651 (
652 IOobject
653 (
654 "sumAlpha",
655 mesh_.time().timeName(),
656 mesh_
657 ),
658 mesh_,
660 );
661
662 phasei = 0;
663
664 for (phase& alpha : phases_)
665 {
666 surfaceScalarField& alphaPhi = alphaPhiCorrs[phasei];
667 alphaPhi += upwind<scalar>(mesh_, phi_).flux(alpha);
668
670 (
671 geometricOneField(),
672 alpha,
674 );
675
676 rhoPhi_ += alphaPhi*alpha.rho();
677
678 Info<< alpha.name() << " volume fraction, min, max = "
679 << alpha.weightedAverage(mesh_.V()).value()
680 << ' ' << min(alpha).value()
681 << ' ' << max(alpha).value()
682 << endl;
683
684 sumAlpha += alpha;
685
686 ++phasei;
687 }
688
689 Info<< "Phase-sum volume fraction, min, max = "
690 << sumAlpha.weightedAverage(mesh_.V()).value()
691 << ' ' << min(sumAlpha).value()
692 << ' ' << max(sumAlpha).value()
693 << endl;
694
695 // Correct the sum of the phase-fractions to avoid 'drift'
696 volScalarField sumCorr(1.0 - sumAlpha);
697 for (phase& alpha : phases_)
698 {
699 alpha += alpha*sumCorr;
700 }
701
702 calcAlphas();
703}
704
705
707{
709 {
710 bool readOK = true;
711
712 PtrList<entry> phaseData(lookup("phases"));
713 label phasei = 0;
714
715 for (phase& ph : phases_)
716 {
717 readOK &= ph.read(phaseData[phasei++].dict());
718 }
719
720 readEntry("sigmas", sigmas_);
721
722 return readOK;
723 }
724
725 return false;
726}
727
728
729// ************************************************************************* //
CGAL::Exact_predicates_exact_constructions_kernel K
surfaceScalarField phic(mixture.cAlpha() *mag(alphaPhic/mesh.magSf()))
MULES: Multidimensional universal limiter for explicit solution.
surfaceScalarField & phi
const volScalarField & alpha1
const volScalarField & alpha2
dimensioned< Type > weightedAverage(const DimensionedField< scalar, GeoMesh > &weightField) const
Calculate and return weighted average.
void setOriented(const bool oriented=true) noexcept
Set the oriented flag.
Internal & ref(const bool updateAccessTime=true)
Return a reference to the dimensioned internal field.
GeometricBoundaryField< vector, fvsPatchField, surfaceMesh > Boundary
Type of boundary fields.
const Boundary & boundaryField() const
Return const-reference to the boundary field.
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:65
dimensionedScalar deltaT() const
Return time step.
Definition: TimeStateI.H:55
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
T & first()
Return the first element of the list.
Definition: UListI.H:202
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
const surfaceScalarField & nHatf() const
Incompressible multi-phase mixture with built in solution for the phase fractions with interface comp...
tmp< volScalarField > nearInterface() const
Indicator of the proximity of the interface.
tmp< surfaceScalarField > surfaceTensionForce() const
void correct()
Correct the mixture properties.
tmp< surfaceScalarField > muf() const
Return the face-interpolated dynamic laminar viscosity.
tmp< volScalarField > nu() const
Return the kinematic laminar viscosity.
tmp< volScalarField > mu() const
Return the dynamic laminar viscosity.
tmp< volScalarField > rho() const
Return the mixture density.
void solve()
Solve for the mixture phase-fractions.
bool read()
Read base transportProperties dictionary.
tmp< surfaceScalarField > nuf() const
Return the face-interpolated dynamic laminar viscosity.
const Time & time() const noexcept
Return time registry.
constant condensation/saturation model.
A class for managing temporary objects.
Definition: tmp.H:65
virtual bool read()=0
Read transportProperties dictionary.
U
Definition: pEqn.H:72
thermo correct()
const volScalarField & mu
faceListList boundary
dynamicFvMesh & mesh
engineTime & runTime
surfaceScalarField phir(fvc::flux(UdmModel.Udm()))
word alpharScheme("div(phirb,alpha)")
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Calculate the divergence of the given field.
Calculate the face-flux of the given field.
Calculate the gradient of the given field.
Calculate the snGrad of the given volField.
word timeName
Definition: getTimeIndex.H:3
label phasei
Definition: pEqn.H:27
void explicitSolve(const RdeltaTType &rDeltaT, const RhoType &rho, volScalarField &psi, const surfaceScalarField &phiPsi, const SpType &Sp, const SuType &Su)
void limit(const RdeltaTType &rDeltaT, const RhoType &rho, const volScalarField &psi, const surfaceScalarField &phi, surfaceScalarField &phiPsi, const SpType &Sp, const SuType &Su, const PsiMaxType &psiMax, const PsiMinType &psiMin, const bool returnCorr)
void limitSum(UPtrList< scalarField > &phiPsiCorrs)
Definition: MULES.C:34
const dimensionedScalar sigma
Stefan-Boltzmann constant: default SI units: [W/m2/K4].
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.
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh > > grad(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcGrad.C:54
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > snGrad(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvcSnGrad.C:47
tmp< GeometricField< Type, fvPatchField, volMesh > > div(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcDiv.C:49
tmp< surfaceScalarField > flux(const volVectorField &vvf)
Return the face-flux field obtained from the given volVectorField.
Definition: fvcFlux.C:34
vtkSmartPointer< vtkFloatArray > zeroField(const word &name, const label size)
Create named field initialized to zero.
GeometricField< vector, fvsPatchField, surfaceMesh > surfaceVectorField
dimensionedScalar det(const dimensionedSphericalTensor &dt)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
GeometricField< vector, fvPatchField, volMesh > volVectorField
Definition: volFieldsFwd.H:83
const dimensionSet dimless
Dimensionless.
dimensionedScalar pos0(const dimensionedScalar &ds)
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
Definition: dimensionSets.H:53
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:82
dimensionedScalar tanh(const dimensionedScalar &ds)
messageStream Info
Information stream (stdout output on master, null elsewhere)
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
constexpr scalar degToRad() noexcept
Multiplication factor for degrees to radians conversion.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
Field< vector > vectorField
Specialisation of Field<T> for vector.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
error FatalError
dimensionedScalar cbrt(const dimensionedScalar &ds)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
dimensionedScalar cos(const dimensionedScalar &ds)
dimensionedScalar acos(const dimensionedScalar &ds)
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:51
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:158
volScalarField & nu
volScalarField & alpha
dictionary dict
tmp< volScalarField > trho
volScalarField & b
Definition: createFields.H:27
volScalarField & e
Definition: createFields.H:11
const dictionary & alphaControls
Definition: alphaControls.H:1
label nAlphaSubCycles(alphaControls.get< label >("nAlphaSubCycles"))
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
#define forAllConstIters(container, iter)
Iterate across all elements of the container object with const access.
Definition: stdFoam.H:278
surfaceScalarField alphaPhi(phi.name()+alpha1.name(), fvc::flux(phi, alpha1, alphaScheme))
Unit conversion functions.