27 #include "alphaContactAngleFvPatchScalarField.H" 36 #include "surfaceInterpolate.H" 46 const Foam::scalar Foam::multiphaseMixtureThermo::convertToRad =
52 void Foam::multiphaseMixtureThermo::calcAlphas()
57 forAllIter(PtrDictionary<phaseModel>, phases_, phase)
59 alphas_ += level*phase();
73 psiThermo(U.
mesh(), word::null),
74 phases_(
lookup(
"phases"), phaseModel::iNew(p_, T_)),
108 sigmas_(
lookup(
"sigmas")),
109 dimSigma_(1, 0, -2, 0, 0),
126 forAllIter(PtrDictionary<phaseModel>, phases_, phasei)
137 for (++phasei; phasei != phases_.end(); ++
phasei)
148 forAllIter(PtrDictionary<phaseModel>, phases_, phasei)
161 ico &= phase().thermo().incompressible();
174 iso &= phase().thermo().incompressible();
191 for (++phasei; phasei != phases_.end(); ++
phasei)
214 for (++phasei; phasei != phases_.end(); ++
phasei)
238 for (++phasei; phasei != phases_.end(); ++
phasei)
254 for (++phasei; phasei != phases_.end(); ++
phasei)
295 for (++phasei; phasei != phases_.end(); ++
phasei)
311 tmp<scalarField>
trho 316 for (++phasei; phasei != phases_.end(); ++
phasei)
332 for (++phasei; phasei != phases_.end(); ++
phasei)
355 for (++phasei; phasei != phases_.end(); ++
phasei)
371 for (++phasei; phasei != phases_.end(); ++
phasei)
394 for (++phasei; phasei != phases_.end(); ++
phasei)
410 for (++phasei; phasei != phases_.end(); ++
phasei)
428 tmp<scalarField> tgamma
433 for (++phasei; phasei != phases_.end(); ++
phasei)
437 *
phasei().thermo().gamma(p, T, patchi);
450 for (++phasei; phasei != phases_.end(); ++
phasei)
468 tmp<scalarField> tCpv
473 for (++phasei; phasei != phases_.end(); ++
phasei)
477 *
phasei().thermo().Cpv(p, T, patchi);
490 for (++phasei; phasei != phases_.end(); ++
phasei)
508 tmp<scalarField> tCpByCpv
513 for (++phasei; phasei != phases_.end(); ++
phasei)
517 *
phasei().thermo().CpByCpv(p, T, patchi);
535 return mu(patchi)/
rho(patchi);
545 for (++phasei; phasei != phases_.end(); ++
phasei)
561 tmp<scalarField> tkappa
566 for (++phasei; phasei != phases_.end(); ++
phasei)
585 for (++phasei; phasei != phases_.end(); ++
phasei)
587 tkappaEff.ref() +=
phasei()*
phasei().thermo().kappaEff(alphat);
602 tmp<scalarField> tkappaEff
604 phasei().boundaryField()[patchi]
608 for (++phasei; phasei != phases_.end(); ++
phasei)
612 *
phasei().thermo().kappaEff(alphat, patchi);
628 for (++phasei; phasei != phases_.end(); ++
phasei)
647 phasei().boundaryField()[patchi]
651 for (++phasei; phasei != phases_.end(); ++
phasei)
655 *
phasei().thermo().alphaEff(alphat, patchi);
668 for (++phasei; phasei != phases_.end(); ++
phasei)
680 tmp<surfaceScalarField> tstf
686 "surfaceTensionForce",
687 mesh_.time().timeName(),
693 "surfaceTensionForce",
694 dimensionSet(1, -2, -2, 0, 0),
704 const phaseModel& alpha1 =
phase1();
709 for (; phase2 != phases_.end(); ++
phase2)
711 const phaseModel& alpha2 =
phase2();
713 sigmaTable::const_iterator sigma =
714 sigmas_.find(interfacePair(alpha1, alpha2));
716 if (sigma == sigmas_.end())
719 <<
"Cannot find interface " << interfacePair(alpha1, alpha2)
720 <<
" in list of sigma values" 739 const Time& runTime = mesh_.time();
741 const dictionary& alphaControls = mesh_.solverDict(
"alpha");
743 scalar cAlpha(
readScalar(alphaControls.lookup(
"cAlpha")));
755 !(++alphaSubCycle).
end();
759 rhoPhiSum += (runTime.deltaT()/totalDeltaT)*rhoPhi_;
793 return gradAlphaf/(
mag(gradAlphaf) + deltaN_);
804 return nHatfv(alpha1, alpha2) & mesh_.Sf();
814 void Foam::multiphaseMixtureThermo::correctContactAngle
816 const phaseModel& alpha1,
817 const phaseModel& alpha2,
818 surfaceVectorField::Boundary& nHatb
821 const volScalarField::Boundary& gbf
822 = alpha1.boundaryField();
824 const fvBoundaryMesh&
boundary = mesh_.boundary();
828 if (isA<alphaContactAngleFvPatchScalarField>(gbf[patchi]))
830 const alphaContactAngleFvPatchScalarField& acap =
831 refCast<const alphaContactAngleFvPatchScalarField>(gbf[
patchi]);
837 mesh_.Sf().boundaryField()[
patchi]
838 /mesh_.magSf().boundaryField()[
patchi]
843 acap.thetaProps().find(interfacePair(alpha1, alpha2));
845 if (tp == acap.thetaProps().end())
848 <<
"Cannot find interface " << interfacePair(alpha1, alpha2)
849 <<
"\n in table of theta properties for patch " 850 << acap.patch().name()
854 bool matched = (tp.key().first() == alpha1.name());
856 scalar theta0 = convertToRad*tp().theta0(matched);
859 scalar uTheta = tp().uTheta();
864 scalar thetaA = convertToRad*tp().thetaA(matched);
865 scalar thetaR = convertToRad*tp().thetaR(matched);
870 U_.boundaryField()[
patchi].patchInternalField()
871 - U_.boundaryField()[
patchi]
873 Uwall -= (AfHatPatch & Uwall)*AfHatPatch;
878 nHatPatch - (AfHatPatch & nHatPatch)*AfHatPatch
882 nWall /= (
mag(nWall) + SMALL);
888 theta += (thetaA - thetaR)*
tanh(uwall/uTheta);
902 b2[facei] =
cos(
acos(a12[facei]) - theta[facei]);
910 nHatPatch = a*AfHatPatch +
b*nHatPatch;
912 nHatPatch /= (
mag(nHatPatch) + deltaN_.
value());
920 const phaseModel& alpha1,
921 const phaseModel& alpha2
924 tmp<surfaceVectorField> tnHatfv = nHatfv(alpha1, alpha2);
926 correctContactAngle(alpha1, alpha2, tnHatfv.ref().boundaryFieldRef());
929 return -
fvc::div(tnHatfv & mesh_.Sf());
936 tmp<volScalarField> tnearInt
943 mesh_.time().timeName(),
954 max(tnearInt(),
pos(phase() - 0.01)*
pos(0.99 - phase()));
961 void Foam::multiphaseMixtureThermo::solveAlphas
966 static label nSolves=-1;
969 word alphaScheme(
"div(phi,alpha)");
975 PtrList<surfaceScalarField> alphaPhiCorrs(phases_.size());
978 forAllIter(PtrDictionary<phaseModel>, phases_, phase)
980 phaseModel& alpha = phase();
987 phi_.name() + alpha.name(),
999 forAllIter(PtrDictionary<phaseModel>, phases_, phase2)
1001 phaseModel& alpha2 =
phase2();
1003 if (&alpha2 == &alpha)
continue;
1017 1.0/mesh_.time().deltaT().value(),
1018 geometricOneField(),
1041 mesh_.time().timeName(),
1054 forAllIter(PtrDictionary<phaseModel>, phases_, phase)
1056 phaseModel& alpha = phase();
1059 alphaPhi += upwind<scalar>(mesh_, phi_).
flux(alpha);
1066 mesh_.time().timeName(),
1078 mesh_.time().timeName(),
1091 if (dgdt[celli] < 0.0 && alpha[celli] > 0.0)
1093 Sp[celli] += dgdt[celli]*alpha[celli];
1094 Su[celli] -= dgdt[celli]*alpha[celli];
1096 else if (dgdt[celli] > 0.0 && alpha[celli] < 1.0)
1098 Sp[celli] -= dgdt[celli]*(1.0 - alpha[celli]);
1105 const phaseModel& alpha2 =
phase2();
1107 if (&alpha2 == &alpha)
continue;
1113 if (dgdt2[celli] > 0.0 && alpha2[celli] < 1.0)
1115 Sp[celli] -= dgdt2[celli]*(1.0 - alpha2[celli]);
1116 Su[celli] += dgdt2[celli]*alpha[celli];
1118 else if (dgdt2[celli] < 0.0 && alpha2[celli] > 0.0)
1120 Sp[celli] += dgdt2[celli]*alpha2[celli];
1127 geometricOneField(),
1136 Info<< alpha.name() <<
" volume fraction, min, max = " 1137 << alpha.weightedAverage(mesh_.V()).value()
1138 <<
' ' <<
min(alpha).value()
1139 <<
' ' <<
max(alpha).value()
1147 Info<<
"Phase-sum volume fraction, min, max = " 1148 << sumAlpha.weightedAverage(mesh_.V()).value()
1149 <<
' ' <<
min(sumAlpha).value()
1150 <<
' ' <<
max(sumAlpha).value()
tmp< surfaceScalarField > surfaceTensionForce() const
dimensionedScalar tanh(const dimensionedScalar &ds)
virtual tmp< volScalarField > rho() const
Density [kg/m^3] - uses current value of pressure.
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.
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)
const double e
Elementary charge.
virtual tmp< volScalarField > Cpv() const
Heat capacity at constant pressure/volume [J/kg/K].
virtual tmp< volScalarField > Cp() const
Heat capacity at constant pressure [J/kg/K].
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Info<< "Creating turbulence model\n"<< endl;tmp< volScalarField > talphaEff
tmp< GeometricField< Type, fvPatchField, volMesh > > div(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
virtual tmp< volScalarField > Cpv() const
Heat capacity at constant pressure/volume [J/kg/K].
virtual tmp< volScalarField > Cv() const
Heat capacity at constant volume [J/kg/K].
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
virtual tmp< volScalarField > kappa() const
Thermal diffusivity for temperature of mixture [J/m/s/K].
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.
virtual tmp< volScalarField > Cp() const
Heat capacity at constant pressure [J/kg/K].
word alpharScheme("div(phirb,alpha)")
GeometricField< vector, fvsPatchField, surfaceMesh > surfaceVectorField
Ostream & endl(Ostream &os)
Add newline and flush stream.
virtual tmp< volScalarField > rho() const
Density [kg/m^3].
tmp< volScalarField > trho
const dimensionedScalar sigma
Stefan-Boltzmann constant: default SI units: [W/m2/K4].
virtual tmp< volScalarField > CpByCpv() const
Heat capacity ratio [].
tmp< GeometricField< Type, fvPatchField, volMesh > > Sp(const volScalarField &sp, const GeometricField< Type, fvPatchField, volMesh > &vf)
const Type & value() const
Return const reference to value.
Calculate the snGrad of the given volField.
dimensionedScalar det(const dimensionedSphericalTensor &dt)
virtual tmp< volScalarField > kappaEff(const volScalarField &alphat) const
Effective thermal diffusivity of mixture [J/m/s/K].
label size() const
Return number of elements in list.
GeometricField< vector, fvPatchField, volMesh > volVectorField
T & first()
Return the first element of the list.
DimensionedField< scalar, volMesh > Internal
Type of the internal field from which this GeometricField is derived.
CGAL::Exact_predicates_exact_constructions_kernel K
virtual tmp< volScalarField > kappaEff(const volScalarField &alphat) const
Effective thermal diffusivity of mixture [J/m/s/K].
virtual tmp< volScalarField > CpByCpv() const
Heat capacity ratio [].
surfaceScalarField phir(phic *interface.nHatf())
virtual tmp< volScalarField > mu() const
Dynamic viscosity of mixture [kg/m/s].
dictionary()
Construct top-level dictionary null.
tmp< volScalarField > rCv() const
Return the phase-averaged reciprocal Cv.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
void correctRho(const volScalarField &dp)
Update densities for given pressure change.
psiReactionThermo & thermo
dimensionedScalar pos(const dimensionedScalar &ds)
virtual tmp< volScalarField > hc() const
Chemical enthalpy [J/kg].
void solve()
Solve for the mixture phase-fractions.
surfaceScalarField alphaPhi(IOobject("alphaPhi", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), phi *fvc::interpolate(alpha1))
stressControl lookup("compactNormalStress") >> compactNormalStress
virtual tmp< volScalarField > kappa() const
Thermal diffusivity for temperature of mixture [J/m/s/K].
dimensionedScalar cos(const dimensionedScalar &ds)
void limitSum(UPtrList< scalarField > &phiPsiCorrs)
virtual tmp< volScalarField > gamma() const
Gamma = Cp/Cv [].
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Calculate the gradient of the given field.
void explicitSolve(const RdeltaTType &rDeltaT, const RhoType &rho, volScalarField &psi, const surfaceScalarField &phiPsi, const SpType &Sp, const SuType &Su)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Calculate the face-flux of the given field.
friend class const_iterator
Declare friendship with the const_iterator.
virtual tmp< volScalarField > Cv() const
Heat capacity at constant volume [J/kg/K].
List< label > labelList
A List of labels.
virtual tmp< volScalarField > gamma() const
Gamma = Cp/Cv [].
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
faceListList boundary(nPatches)
bool readScalar(const char *buf, doubleScalar &s)
Read whole of buf as a scalar. Return true if succesful.
virtual tmp< volScalarField > hc() const
Chemical enthalpy [J/kg].
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
label readLabel(Istream &is)
Calculate the divergence of the given field.
virtual bool incompressible() const
Return true if the equation of state is incompressible.
virtual tmp< scalarField > THE(const scalarField &h, const scalarField &p, const scalarField &T0, const labelList &cells) const
Temperature from enthalpy/internal energy for cell-set.
defineTypeNameAndDebug(combustionModel, 0)
virtual tmp< volScalarField > nu() const
Kinematic viscosity of mixture [m^2/s].
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
virtual volScalarField & he()
Enthalpy/Internal energy [J/kg].
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.
Calculate the mesh motion flux and convert fluxes from absolute to relative and back.
const dimensionedScalar h
Planck constant.
Internal & ref()
Return a reference to the dimensioned internal field.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
multiphaseMixtureThermo(const volVectorField &U, const surfaceScalarField &phi)
Construct from components.
volScalarField alpha_
Laminar thermal diffusuvity [kg/m/s].
virtual tmp< volScalarField > alphaEff(const volScalarField &alphat) const
Effective thermal diffusivity of mixture [J/m/s/K].
tmp< surfaceScalarField > absolute(const tmp< surfaceScalarField > &tphi, const volVectorField &U)
Return the given relative flux in absolute form.
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
virtual void correct()
Update properties.
virtual const volScalarField & alpha() const
Thermal diffusivity for enthalpy of mixture [kg/m/s].
tmp< volScalarField > nearInterface() const
Indicator of the proximity of the interface.
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
dimensioned< scalar > mag(const dimensioned< Type > &)
volScalarField divU(fvc::div(fvc::absolute(phi, U)))
Field< vector > vectorField
Specialisation of Field<T> for vector.
MULES: Multidimensional universal limiter for explicit solution.
void limit(const RdeltaTType &rDeltaT, const RhoType &rho, const volScalarField &psi, const surfaceScalarField &phi, surfaceScalarField &phiPsi, const SpType &Sp, const SuType &Su, const scalar psiMax, const scalar psiMin, const bool returnCorr)
volScalarField mu_
Dynamic viscosity [kg/m/s].
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0)
virtual tmp< volScalarField > alphaEff(const volScalarField &alphat) const
Effective thermal diffusivity of mixture [J/m/s/K].
volScalarField psi_
Compressibility [s^2/m^2].
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
virtual bool isochoric() const
Return true if the equation of state is isochoric.
tmp< GeometricField< Type, fvPatchField, volMesh > > Su(const GeometricField< Type, fvPatchField, volMesh > &su, const GeometricField< Type, fvPatchField, volMesh > &vf)
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
virtual volScalarField & he()
Enthalpy/Internal energy [J/kg].
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > snGrad(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
friend class const_iterator
virtual void correct()
Update properties.