27 #include "alphaContactAngleFvPatchScalarField.H" 32 #include "surfaceInterpolate.H" 41 void Foam::multiphaseMixture::calcAlphas()
46 forAllIter(PtrDictionary<phase>, phases_, iter)
48 alphas_ += level*iter();
66 "transportProperties",
74 phases_(
lookup(
"phases"), phase::iNew(U, phi)),
119 sigmas_(
lookup(
"sigmas")),
120 dimSigma_(1, 0, -2, 0, 0),
139 tmp<volScalarField> trho = iter()*iter().rho();
142 for (++iter; iter != phases_.end(); ++iter)
144 rho += iter()*iter().rho();
156 tmp<scalarField> trho = iter().boundaryField()[
patchi]*iter().rho().value();
159 for (++iter; iter != phases_.end(); ++iter)
161 rho += iter().boundaryField()[
patchi]*iter().rho().value();
173 tmp<volScalarField> tmu = iter()*iter().rho()*iter().nu();
176 for (++iter; iter != phases_.end(); ++iter)
178 mu += iter()*iter().rho()*iter().nu();
190 tmp<scalarField> tmu =
191 iter().boundaryField()[
patchi]
192 *iter().rho().value()
196 for (++iter; iter != phases_.end(); ++iter)
199 iter().boundaryField()[
patchi]
200 *iter().rho().value()
213 tmp<surfaceScalarField> tmuf =
217 for (++iter; iter != phases_.end(); ++iter)
237 return nu_.boundaryField()[
patchi];
251 tmp<surfaceScalarField> tstf
255 "surfaceTensionForce",
265 const phase& alpha1 = iter1();
270 for (; iter2 != phases_.end(); ++iter2)
272 const phase& alpha2 = iter2();
274 sigmaTable::const_iterator sigma =
275 sigmas_.find(interfacePair(alpha1, alpha2));
277 if (sigma == sigmas_.end())
280 <<
"Cannot find interface " << interfacePair(alpha1, alpha2)
281 <<
" in list of sigma values" 302 const Time& runTime = mesh_.
time();
306 const dictionary& alphaControls = mesh_.
solverDict(
"alpha");
308 scalar cAlpha(alphaControls.lookup<scalar>(
"cAlpha"));
329 !(++alphaSubCycle).end();
333 rhoPhiSum += (runTime.deltaT()/totalDeltaT)*rhoPhi_;
350 forAllIter(PtrDictionary<phase>, phases_, iter)
379 return gradAlphaf/(
mag(gradAlphaf) + deltaN_);
390 return nHatfv(alpha1, alpha2) & mesh_.
Sf();
394 void Foam::multiphaseMixture::correctContactAngle
398 surfaceVectorField::Boundary& nHatb
401 const volScalarField::Boundary& a1bf = alpha1.boundaryField();
402 const volScalarField::Boundary& a2bf = alpha2.boundaryField();
410 isA<alphaContactAngleFvPatchScalarField>(a1bf[patchi])
411 || isA<alphaContactAngleFvPatchScalarField>(a2bf[patchi])
416 isA<alphaContactAngleFvPatchScalarField>(a1bf[patchi])
417 && isA<alphaContactAngleFvPatchScalarField>(a2bf[patchi])
421 <<
"alphaContactAngle boundary condition " 422 "specified on patch " << boundary[
patchi].name()
423 <<
" for both " << alpha1.name() <<
" and " << alpha2.name()
424 <<
nl <<
"which may be inconsistent." 428 const alphaContactAngleFvPatchScalarField& acap =
429 isA<alphaContactAngleFvPatchScalarField>(a1bf[
patchi])
430 ? refCast<const alphaContactAngleFvPatchScalarField>(a1bf[patchi])
431 :
refCast<const alphaContactAngleFvPatchScalarField>(a2bf[patchi])
442 alphaContactAngleFvPatchScalarField::thetaPropsTable::
444 acap.thetaProps().find(interfacePair(alpha1, alpha2));
446 if (tp == acap.thetaProps().end())
449 <<
"Cannot find interface " << interfacePair(alpha1, alpha2)
450 <<
"\n in table of theta properties for patch " 451 << acap.patch().name()
455 const bool matched = (tp.key().first() == alpha1.name());
457 const scalar theta0 =
degToRad(tp().theta0(matched));
459 scalarField theta(boundary[patchi].size(), theta0);
461 const scalar uTheta = tp().uTheta();
466 const scalar thetaA =
degToRad(tp().thetaA(matched));
467 const scalar thetaR =
degToRad(tp().thetaR(matched));
472 U_.boundaryField()[
patchi].patchInternalField()
473 - U_.boundaryField()[
patchi]
475 Uwall -= (AfHatPatch & Uwall)*AfHatPatch;
480 nHatPatch - (AfHatPatch & nHatPatch)*AfHatPatch
484 nWall /= (
mag(nWall) + small);
490 theta += (thetaA - thetaR)*
tanh(uwall/uTheta);
504 b2[facei] =
cos(
acos(a12[facei]) - theta[facei]);
512 nHatPatch = a*AfHatPatch +
b*nHatPatch;
514 nHatPatch /= (
mag(nHatPatch) + deltaN_.
value());
526 tmp<surfaceVectorField> tnHatfv = nHatfv(alpha1, alpha2);
528 correctContactAngle(alpha1, alpha2, tnHatfv.ref().boundaryFieldRef());
538 tmp<volScalarField> tnearInt
551 max(tnearInt(),
pos0(iter() - 0.01)*
pos0(0.99 - iter()));
558 void Foam::multiphaseMixture::solveAlphas
563 static label nSolves=-1;
572 UPtrList<const volScalarField>
alphas(phases_.size());
573 PtrList<surfaceScalarField> alphaPhis(phases_.size());
576 forAllIter(PtrDictionary<phase>, phases_, iter)
578 const phase& alpha = iter();
580 alphas.set(phasei, &alpha);
587 "phi" + alpha.name() +
"Corr",
599 forAllIter(PtrDictionary<phase>, phases_, iter2)
601 phase& alpha2 = iter2();
603 if (&alpha2 == &alpha)
continue;
651 forAllIter(PtrDictionary<phase>, phases_, iter)
653 phase& alpha = iter();
663 rhoPhi_ += alphaPhi*alpha.rho();
665 Info<< alpha.name() <<
" volume fraction, min, max = " 666 << alpha.weightedAverage(mesh_.
V()).value()
667 <<
' ' <<
min(alpha).value()
668 <<
' ' <<
max(alpha).value()
676 Info<<
"Phase-sum volume fraction, min, max = " 677 << sumAlpha.weightedAverage(mesh_.
V()).value()
678 <<
' ' <<
min(sumAlpha).value()
679 <<
' ' <<
max(sumAlpha).value()
684 forAllIter(PtrDictionary<phase>, phases_, iter)
686 phase& alpha = iter();
687 alpha += alpha*sumCorr;
700 PtrList<entry> phaseData(
lookup(
"phases"));
703 forAllIter(PtrDictionary<phase>, phases_, iter)
705 readOK &= iter().read(phaseData[phasei++].
dict());
708 lookup(
"sigmas") >> sigmas_;
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)
dimensionedScalar tanh(const dimensionedScalar &ds)
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> grad(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
dimensionedScalar acos(const dimensionedScalar &ds)
#define forAll(list, i)
Loop across all elements in list.
const surfaceVectorField & Sf() const
Return cell face area vectors.
tmp< surfaceScalarField > muf() const
Return the face-interpolated dynamic laminar viscosity.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
errorManipArg< error, int > exit(error &err, const int errNo=1)
virtual bool read()
Read object.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const Boundary & boundaryField() const
Return const-reference to the boundary field.
tmp< GeometricField< Type, fvPatchField, volMesh > > div(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Unit conversion functions.
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
To & refCast(From &r)
Reference type cast template function.
IOobject(const word &name, const fileName &instance, const objectRegistry ®istry, readOption r=NO_READ, writeOption w=NO_WRITE, bool registerObject=true)
Construct from name, instance, registry, io options.
volScalarField alpha(IOobject("alpha", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
static tmp< GeometricField< scalar, fvsPatchField, surfaceMesh > > New(const word &name, const Internal &, const PtrList< fvsPatchField< scalar >> &)
Return a temporary field constructed from name,.
GeometricField< vector, fvsPatchField, surfaceMesh > surfaceVectorField
const dimensionedScalar b
Wien displacement law constant: default SI units: [m K].
Ostream & endl(Ostream &os)
Add newline and flush stream.
tmp< volScalarField > trho
tmp< volScalarField > nearInterface() const
Indicator of the proximity of the interface.
const dictionary & dict() const
Return populationBalanceCoeffs dictionary.
Calculate the snGrad of the given volField.
surfaceScalarField phir(fvc::flux(UdmModel.Udm()))
static word timeName(const scalar, const int precision=precision_)
Return time name of given scalar time.
const dimensionSet dimless
dimensionedScalar det(const dimensionedSphericalTensor &dt)
const Time & time() const
Return the top-level database.
const dictionary & solverDict(const word &name) const
Return the solver controls dictionary for the given field.
const DimensionedField< scalar, volMesh > & V() const
Return cell volumes.
GeometricField< vector, fvPatchField, volMesh > volVectorField
T & first()
Return the first element of the list.
CGAL::Exact_predicates_exact_constructions_kernel K
multiphaseMixture(const volVectorField &U, const surfaceScalarField &phi)
Construct from components.
scalar degToRad(const scalar deg)
Conversion from degrees to radians.
tmp< volScalarField > rho() const
Return the mixture density.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
const dimensionedScalar sigma
Stefan-Boltzmann constant: default SI units: [W/m^2/K^4].
const dimensionSet dimTime
stressControl lookup("compactNormalStress") >> compactNormalStress
dimensionedScalar cos(const dimensionedScalar &ds)
bool read()
Read base transportProperties dictionary.
void limitSum(UPtrList< scalarField > &phiPsiCorrs)
Calculate the gradient of the given field.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
void correct()
Correct the mixture properties.
Calculate the face-flux of the given field.
const Type & value() const
Return const reference to value.
surfaceScalarField alphaPhi(phi.name()+alpha1.name(), fvc::flux(phi, alpha1, alphaScheme))
void correct()
Correct derived quantities.
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
faceListList boundary(nPatches)
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
tmp< volScalarField > nu() const
Return the kinematic laminar viscosity.
IOdictionary(const IOobject &io, const word &wantedType)
Construct given an IOobject, supply wanted typeName.
Calculate the divergence of the given field.
const surfaceScalarField & magSf() const
Return cell face area magnitudes.
dimensionedScalar pos0(const dimensionedScalar &ds)
const dimensionedScalar mu
Atomic mass unit.
tmp< volScalarField > mu() const
Return the dynamic laminar viscosity.
const label nAlphaSubCycles(alphaControls.lookup< label >("nAlphaSubCycles"))
void solve()
Solve for the mixture phase-fractions.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
const dimensionSet dimMass
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.
const word alphaScheme(mesh.divScheme(divAlphaName)[1].wordToken())
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
tmp< surfaceScalarField > nuf() const
Return the face-interpolated dynamic laminar viscosity.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
const Time & time() const
Return time.
const volScalarField & alphas() const
Return total void of phases belonging to this populationBalance.
word alpharScheme("div(phirb,alpha)")
dimensioned< scalar > mag(const dimensioned< Type > &)
Field< vector > vectorField
Specialisation of Field<T> for vector.
MULES: Multidimensional universal limiter for explicit solution.
const doubleScalar e
Elementary charge.
A class for managing temporary objects.
tmp< surfaceScalarField > flux(const volVectorField &vvf)
Return the face-flux field obtained from the given volVectorField.
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
const objectRegistry & db() const
Return the local objectRegistry.
void explicitSolve(const RdeltaTType &rDeltaT, const RhoType &rho, volScalarField &psi, const surfaceScalarField &phiPsi, const SpType &Sp, const SuType &Su)
dimensionedScalar deltaT() const
Return time step.
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > snGrad(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
friend class const_iterator
tmp< surfaceScalarField > surfaceTensionForce() const
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.