Go to the documentation of this file.
29 #include "alphaContactAngleFvPatchScalarField.H"
38 #include "surfaceInterpolate.H"
48 const Foam::scalar Foam::multiphaseMixtureThermo::convertToRad =
54 void Foam::multiphaseMixtureThermo::calcAlphas()
59 for (
const phaseModel& phase : phases_)
61 alphas_ += level * phase;
75 psiThermo(
U.
mesh(), word::null),
76 phases_(
lookup(
"phases"), phaseModel::iNew(p_, T_)),
110 sigmas_(
lookup(
"sigmas")),
111 dimSigma_(1, 0, -2, 0, 0),
118 rhoPhi_.setOriented();
129 for (phaseModel& phase : phases_)
134 auto phasei = phases_.cbegin();
151 for (phaseModel& phase : phases_)
153 phase.thermo().rho() += phase.thermo().psi()*dp;
160 auto phasei = phases_.cbegin();
175 for (
const phaseModel& phase : phases_)
177 if (!phase.thermo().incompressible())
189 for (
const phaseModel& phase : phases_)
191 if (!phase.thermo().isochoric())
207 auto phasei = phases_.cbegin();
227 auto phasei = phases_.cbegin();
251 auto phasei = phases_.cbegin();
261 phasei().boundaryField()[patchi]*
phasei().thermo().he(
p,
T, patchi);
270 auto phasei = phases_.cbegin();
311 auto phasei = phases_.cbegin();
329 auto phasei = phases_.cbegin();
331 tmp<scalarField>
trho
339 phasei().boundaryField()[patchi]*
phasei().thermo().rho(patchi);
348 auto phasei = phases_.cbegin();
368 auto phasei = phases_.cbegin();
378 phasei().boundaryField()[patchi]*
phasei().thermo().Cp(
p,
T, patchi);
387 auto phasei = phases_.cbegin();
407 auto phasei = phases_.cbegin();
417 phasei().boundaryField()[patchi]*
phasei().thermo().Cv(
p,
T, patchi);
426 auto phasei = phases_.cbegin();
446 auto phasei = phases_.cbegin();
448 tmp<scalarField> tgamma
456 phasei().boundaryField()[patchi]
457 *
phasei().thermo().gamma(
p,
T, patchi);
466 auto phasei = phases_.cbegin();
486 auto phasei = phases_.cbegin();
488 tmp<scalarField> tCpv
496 phasei().boundaryField()[patchi]
497 *
phasei().thermo().Cpv(
p,
T, patchi);
506 auto phasei = phases_.cbegin();
526 auto phasei = phases_.cbegin();
528 tmp<scalarField> tCpByCpv
536 phasei().boundaryField()[patchi]
537 *
phasei().thermo().CpByCpv(
p,
T, patchi);
546 auto phasei = phases_.cbegin();
570 return mu(patchi)/
rho(patchi);
576 auto phasei = phases_.cbegin();
594 auto phasei = phases_.cbegin();
596 tmp<scalarField> tkappa
604 phasei().boundaryField()[patchi]*
phasei().thermo().kappa(patchi);
613 PtrDictionary<phaseModel>::const_iterator
phasei = phases_.begin();
619 talphaEff.ref() +=
phasei()*
phasei().thermo().alphahe();
631 PtrDictionary<phaseModel>::const_iterator
phasei = phases_.begin();
633 tmp<scalarField> talphaEff
635 phasei().boundaryField()[patchi]
642 phasei().boundaryField()[patchi]
643 *
phasei().thermo().alphahe(patchi);
655 auto phasei = phases_.cbegin();
661 tkappaEff.ref() +=
phasei()*
phasei().thermo().kappaEff(alphat);
674 auto phasei = phases_.cbegin();
676 tmp<scalarField> tkappaEff
678 phasei().boundaryField()[patchi]
685 phasei().boundaryField()[patchi]
686 *
phasei().thermo().kappaEff(alphat, patchi);
698 auto phasei = phases_.cbegin();
704 talphaEff.ref() +=
phasei()*
phasei().thermo().alphaEff(alphat);
717 auto phasei = phases_.cbegin();
719 tmp<scalarField> talphaEff
721 phasei().boundaryField()[patchi]
728 phasei().boundaryField()[patchi]
729 *
phasei().thermo().alphaEff(alphat, patchi);
738 auto phasei = phases_.cbegin();
754 tmp<surfaceScalarField> tstf
760 "surfaceTensionForce",
761 mesh_.time().timeName(),
787 <<
"Cannot find interface " << interfacePair(
alpha1,
alpha2)
788 <<
" in list of sigma values"
823 !(++alphaSubCycle).
end();
861 return gradAlphaf/(
mag(gradAlphaf) + deltaN_);
882 void Foam::multiphaseMixtureThermo::correctContactAngle
886 surfaceVectorField::Boundary& nHatb
889 const volScalarField::Boundary& gbf
892 const fvBoundaryMesh&
boundary = mesh_.boundary();
896 if (isA<alphaContactAngleFvPatchScalarField>(gbf[patchi]))
898 const alphaContactAngleFvPatchScalarField& acap =
899 refCast<const alphaContactAngleFvPatchScalarField>(gbf[patchi]);
905 mesh_.Sf().boundaryField()[patchi]
906 /mesh_.magSf().boundaryField()[patchi]
915 <<
"Cannot find interface " << interfacePair(
alpha1,
alpha2)
916 <<
"\n in table of theta properties for patch "
917 << acap.patch().name()
921 const bool matched = (tp.key().first() ==
alpha1.name());
923 const scalar theta0 =
degToRad(tp().theta0(matched));
926 const scalar uTheta = tp().uTheta();
931 const scalar thetaA =
degToRad(tp().thetaA(matched));
932 const scalar thetaR =
degToRad(tp().thetaR(matched));
937 U_.boundaryField()[patchi].patchInternalField()
938 - U_.boundaryField()[patchi]
940 Uwall -= (AfHatPatch & Uwall)*AfHatPatch;
945 nHatPatch - (AfHatPatch & nHatPatch)*AfHatPatch
949 nWall /= (
mag(nWall) + SMALL);
955 theta += (thetaA - thetaR)*
tanh(uwall/uTheta);
969 b2[facei] =
cos(
acos(a12[facei]) - theta[facei]);
977 nHatPatch = a*AfHatPatch +
b*nHatPatch;
979 nHatPatch /= (
mag(nHatPatch) + deltaN_.value());
991 tmp<surfaceVectorField> tnHatfv = nHatfv(
alpha1,
alpha2);
996 return -
fvc::div(tnHatfv & mesh_.Sf());
1003 tmp<volScalarField> tnearInt
1010 mesh_.time().timeName(),
1018 for (
const phaseModel& phase : phases_)
1021 max(tnearInt(),
pos0(phase - 0.01)*
pos0(0.99 - phase));
1028 void Foam::multiphaseMixtureThermo::solveAlphas
1033 static label nSolves(-1);
1036 const word alphaScheme(
"div(phi,alpha)");
1042 PtrList<surfaceScalarField> alphaPhiCorrs(phases_.size());
1045 for (phaseModel&
alpha : phases_)
1064 for (phaseModel&
alpha2 : phases_)
1080 1.0/mesh_.time().deltaT().value(),
1081 geometricOneField(),
1104 mesh_.time().timeName(),
1117 for (phaseModel&
alpha : phases_)
1127 mesh_.time().timeName(),
1139 mesh_.time().timeName(),
1152 if (dgdt[celli] < 0.0 &&
alpha[celli] > 0.0)
1154 Sp[celli] += dgdt[celli]*
alpha[celli];
1155 Su[celli] -= dgdt[celli]*
alpha[celli];
1157 else if (dgdt[celli] > 0.0 &&
alpha[celli] < 1.0)
1159 Sp[celli] -= dgdt[celli]*(1.0 -
alpha[celli]);
1164 for (
const phaseModel&
alpha2 : phases_)
1172 if (dgdt2[celli] > 0.0 &&
alpha2[celli] < 1.0)
1174 Sp[celli] -= dgdt2[celli]*(1.0 -
alpha2[celli]);
1175 Su[celli] += dgdt2[celli]*
alpha[celli];
1177 else if (dgdt2[celli] < 0.0 &&
alpha2[celli] > 0.0)
1179 Sp[celli] += dgdt2[celli]*
alpha2[celli];
1186 geometricOneField(),
1196 <<
alpha.weightedAverage(mesh_.V()).value()
1206 Info<<
"Phase-sum volume fraction, min, max = "
1207 << sumAlpha.weightedAverage(mesh_.V()).value()
1208 <<
' ' <<
min(sumAlpha).value()
1209 <<
' ' <<
max(sumAlpha).value()
virtual tmp< volScalarField > nu() const
Kinematic viscosity of mixture [m^2/s].
List< label > labelList
A List of labels.
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > snGrad(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
volScalarField psi_
Compressibility [s^2/m^2].
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
tmp< surfaceScalarField > flux(const volVectorField &vvf)
Return the face-flux field obtained from the given volVectorField.
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Dimensionless.
void explicitSolve(const RdeltaTType &rDeltaT, const RhoType &rho, volScalarField &psi, const surfaceScalarField &phiPsi, const SpType &Sp, const SuType &Su)
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> grad(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
A class for handling words, derived from Foam::string.
virtual tmp< volScalarField > alphahe() const
Thermal diffusivity for energy of mixture [kg/m/s].
virtual tmp< volScalarField > CpByCpv() const
Heat capacity ratio [].
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 deltaT() const
Return time step.
const dimensionedScalar mu
Atomic mass unit.
A class for managing temporary objects.
static constexpr const zero Zero
Global zero (0)
Calculate the mesh motion flux and convert fluxes from absolute to relative and back.
const volScalarField & alpha2
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
psiReactionThermo & thermo
const Time & time() const
Return time.
Calculate the snGrad of the given volField.
volScalarField alpha_
Laminar thermal diffusivity [kg/m/s].
const volScalarField & Cv
const tmp< volScalarField > & tCp
Calculate the divergence of the given field.
const word & name() const
Return const reference to name.
Unit conversion functions.
tmp< GeometricField< Type, fvPatchField, volMesh > > div(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Ostream & endl(Ostream &os)
Add newline and flush stream.
virtual tmp< volScalarField > Cpv() const
Heat capacity at constant pressure/volume [J/kg/K].
dimensionedScalar pos0(const dimensionedScalar &ds)
const volScalarField & alpha1
virtual bool isochoric() const
Return true if the equation of state is isochoric.
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
const dimensionedScalar kappa
Coulomb constant: default SI units: [N.m2/C2].
tmp< volScalarField > nearInterface() const
Indicator of the proximity of the interface.
word alpharScheme("div(phirb,alpha)")
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
volScalarField & h
Planck constant.
tmp< surfaceScalarField > surfaceTensionForce() const
#define forAll(list, i)
Loop across all elements in list.
Field< vector > vectorField
Specialisation of Field<T> for vector.
surfaceScalarField phic(mixture.cAlpha() *mag(alphaPhic/mesh.magSf()))
CGAL::Exact_predicates_exact_constructions_kernel K
virtual tmp< volScalarField > kappaEff(const volScalarField &alphat) const
Effective thermal diffusivity of mixture [J/m/s/K].
tmp< volScalarField > trho
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
surfaceScalarField phir(fvc::flux(UdmModel.Udm()))
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
dimensionedScalar tanh(const dimensionedScalar &ds)
surfaceScalarField alphaPhi(phi.name()+alpha1.name(), fvc::flux(phi, alpha1, alphaScheme))
messageStream Info
Information stream (uses stdout - output is on the master only)
word name(const complex &c)
Return string representation of complex.
DimensionedField< scalar, volMesh > Internal
Type of the internal field from which this GeometricField is derived.
const cellModel * lookup(const word &modelName)
Deprecated(2017-11) equivalent to cellModel::ptr static method.
void limitSum(UPtrList< scalarField > &phiPsiCorrs)
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
virtual tmp< volScalarField > Cv() const
Heat capacity at constant volume [J/kg/K].
GeometricField< scalar, fvPatchField, volMesh > volScalarField
virtual tmp< volScalarField > rho() const
Density [kg/m^3].
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
virtual volScalarField & he()
Enthalpy/Internal energy [J/kg].
virtual word thermoName() const
Return the name of the thermo physics.
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
virtual tmp< volScalarField > W() const
Molecular weight [kg/kmol].
volScalarField mu_
Dynamic viscosity [kg/m/s].
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0)
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.
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
errorManipArg< error, int > exit(error &err, const int errNo=1)
virtual tmp< volScalarField > hc() const
Chemical enthalpy [J/kg].
GeometricField< vector, fvPatchField, volMesh > volVectorField
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
tmp< volScalarField > rCv() const
Return the phase-averaged reciprocal Cv.
constexpr scalar pi(M_PI)
forAllConstIters(mixture.phases(), phase)
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.
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
Internal & ref(const bool updateAccessTime=true)
Return a reference to the dimensioned internal field.
dimensionedScalar acos(const dimensionedScalar &ds)
Calculate the gradient of the given field.
virtual tmp< volScalarField > Cp() const
Heat capacity at constant pressure [J/kg/K].
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Calculate the face-flux of the given field.
virtual tmp< volScalarField > alphaEff(const volScalarField &alphat) const
Effective thermal diffusivity of mixture [J/m/s/K].
const dimensionedScalar e
Elementary charge.
volScalarField alphaEff("alphaEff", turbulence->nu()/Pr+alphat)
const volScalarField & Cp
multiphaseMixtureThermo(const volVectorField &U, const surfaceScalarField &phi)
Construct from components.
void setOriented(const bool oriented=true)
Set the oriented flag.
virtual tmp< volScalarField > kappa() const
Thermal diffusivity for temperature of mixture [J/m/s/K].
virtual tmp< volScalarField > gamma() const
Gamma = Cp/Cv [].
dimensionedScalar det(const dimensionedSphericalTensor &dt)
void solve()
Solve for the mixture phase-fractions.
virtual bool incompressible() const
Return true if the equation of state is incompressible.
virtual void correct()
Update properties.
dimensionedScalar sigma("sigma", dimMass/sqr(dimTime), transportProperties)
GeometricField< vector, fvsPatchField, surfaceMesh > surfaceVectorField
const dimensionSet & dimensions() const
Return const reference to dimensions.
dimensionedScalar cbrt(const dimensionedScalar &ds)
MULES: Multidimensional universal limiter for explicit solution.
defineTypeNameAndDebug(combustionModel, 0)
tmp< surfaceScalarField > absolute(const tmp< surfaceScalarField > &tphi, const volVectorField &U)
Return the given relative flux in absolute form.
void correctRho(const volScalarField &dp)
Update densities for given pressure change.
const tmp< volScalarField > & tCv
const Boundary & boundaryField() const
Return const-reference to the boundary field.
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
dimensionedScalar cos(const dimensionedScalar &ds)