49 template<
class BasePhaseSystem>
52 const phaseSystem::dmdtfTable& dmdtfs,
53 phaseSystem::momentumTransferTable& eqns
58 const phaseInterface interface(*
this, dmdtfIter.key());
64 phaseModel& phase1 = this->
phases()[interface.phase1().name()];
65 phaseModel& phase2 = this->
phases()[interface.phase2().name()];
67 if (!phase1.stationary())
69 *eqns[phase1.name()] +=
70 dmdtf21*phase2.U() +
fvm::Sp(dmdtf12, phase1.URef());
73 if (!phase2.stationary())
75 *eqns[phase2.name()] -=
76 dmdtf12*phase1.U() +
fvm::Sp(dmdtf21, phase2.URef());
84 template<
class BasePhaseSystem>
93 this->generateInterfacialModels(dragModels_);
94 this->generateInterfacialModels(virtualMassModels_);
95 this->generateInterfacialModels(liftModels_);
96 this->generateInterfacialModels(wallLubricationModels_);
97 this->generateInterfacialModels(turbulentDispersionModels_);
106 const phaseInterface&
interface = dragModelIter()->interface();
116 this->
mesh().time().timeName(),
132 this->
mesh().time().timeName(),
143 virtualMassModelTable,
148 const phaseInterface&
interface = virtualMassModelIter()->interface();
158 this->
mesh().time().timeName(),
174 this->
mesh().time().timeName(),
187 template<
class BasePhaseSystem>
195 template<
class BasePhaseSystem>
200 autoPtr<phaseSystem::momentumTransferTable> eqnsPtr
207 forAll(this->movingPhases(), movingPhasei)
209 const phaseModel& phase = this->movingPhases()[movingPhasei];
226 *Kds_[dragModelIter.key()] = dragModelIter()->K();
227 *Kdfs_[dragModelIter.key()] = dragModelIter()->Kf();
234 const phaseInterface interface(*
this, KdIter.key());
238 if (!iter().stationary())
250 virtualMassModelTable,
255 *Vms_[virtualMassModelIter.key()] = virtualMassModelIter()->K();
256 *Vmfs_[virtualMassModelIter.key()] = virtualMassModelIter()->Kf();
263 const phaseInterface interface(*
this, VmIter.key());
267 const phaseModel& phase = iter();
268 const phaseModel& otherPhase = iter.otherPhase();
270 if (!phase.stationary())
286 + this->MRF_.DDt(Vm, U - otherPhase.U());
295 template<
class BasePhaseSystem>
300 autoPtr<phaseSystem::momentumTransferTable> eqnsPtr
307 forAll(this->movingPhases(), movingPhasei)
309 const phaseModel& phase = this->movingPhases()[movingPhasei];
319 PtrList<fvVectorMatrix> UgradUs(this->phaseModels_.size());
320 forAll(this->phaseModels_, phasei)
322 const phaseModel& phase = this->phaseModels_[
phasei];
324 if (!phase.stationary())
347 const phaseInterface interface(*
this, VmIter.key());
351 const phaseModel& phase = iter();
352 const phaseModel& otherPhase = iter.otherPhase();
354 if (!phase.stationary())
356 *eqns[phase.name()] -=
359 UgradUs[phase.index()]
360 - (UgradUs[otherPhase.index()] & otherPhase.U())
370 template<
class BasePhaseSystem>
374 PtrList<surfaceScalarField> AFfs(this->phaseModels_.size());
380 const phaseInterface interface(*
this, KdfIter.key());
384 addField(iter(),
"AFf", Kf, AFfs);
392 const phaseInterface interface(*
this, VmfIter.key());
396 addField(iter(),
"AFf",
byDt(Vmf), AFfs);
406 template<
class BasePhaseSystem>
410 const PtrList<volScalarField>& rAUs
413 PtrList<surfaceScalarField>
phiFs(this->phaseModels_.size());
423 const phaseInterface&
interface = liftModelIter()->interface();
431 fvc::flux(rAUs[interface.phase1().index()]*
F),
438 -
fvc::flux(rAUs[interface.phase2().index()]*
F),
446 wallLubricationModelTable,
447 wallLubricationModels_,
448 wallLubricationModelIter
451 const phaseInterface&
interface =
452 wallLubricationModelIter()->interface();
460 fvc::flux(rAUs[interface.phase1().index()]*
F),
467 -
fvc::flux(rAUs[interface.phase2().index()]*
F),
473 forAll(this->phaseModels_, phasei)
475 const phaseModel& phase = this->phaseModels_[
phasei];
487 addField(phase,
"phiF", pPrimeByAf*snGradAlpha1,
phiFs);
493 turbulentDispersionModelTable,
494 turbulentDispersionModels_,
495 turbulentDispersionModelIter
498 const phaseInterface&
interface =
499 turbulentDispersionModelIter()->interface();
512 const volScalarField alpha12(interface.phase1() + interface.phase2());
518 /
max(alpha12, interface.phase1().residualAlpha())
519 )*this->mesh_.magSf()
526 /
max(alpha12, interface.phase2().residualAlpha())
527 )*this->mesh_.magSf()
530 addField(interface.phase1(),
"phiF", DByA1f*snGradAlpha1By12,
phiFs);
531 addField(interface.phase2(),
"phiF", DByA2f*snGradAlpha2By12,
phiFs);
534 if (this->fillFields_)
543 template<
class BasePhaseSystem>
547 const PtrList<surfaceScalarField>& rAUfs
550 PtrList<surfaceScalarField>
phiFfs(this->phaseModels_.size());
556 const phaseInterface interface(*
this, VmfIter.key());
564 -rAUfs[iter().index()]*Vmf
574 + iter.otherPhase().DUDtf()
589 const phaseInterface&
interface = liftModelIter()->interface();
597 rAUfs[interface.phase1().index()]*Ff,
604 -rAUfs[interface.phase2().index()]*Ff,
612 wallLubricationModelTable,
613 wallLubricationModels_,
614 wallLubricationModelIter
617 const phaseInterface&
interface =
618 wallLubricationModelIter()->interface();
626 rAUfs[interface.phase1().index()]*Ff,
633 -rAUfs[interface.phase2().index()]*Ff,
639 forAll(this->phaseModels_, phasei)
641 const phaseModel& phase = this->phaseModels_[
phasei];
653 addField(phase,
"phiFf", pPrimeByAf*snGradAlpha1,
phiFfs);
659 turbulentDispersionModelTable,
660 turbulentDispersionModels_,
661 turbulentDispersionModelIter
664 const phaseInterface&
interface =
665 turbulentDispersionModelIter()->interface();
675 const volScalarField alpha12(interface.phase1() + interface.phase2());
681 /
max(alpha12, interface.phase1().residualAlpha())
682 )*this->mesh_.magSf()
689 /
max(alpha12, interface.phase2().residualAlpha())
690 )*this->mesh_.magSf()
693 addField(interface.phase1(),
"phiF", DByA1f*snGradAlpha1By12,
phiFfs);
694 addField(interface.phase2(),
"phiF", DByA2f*snGradAlpha2By12,
phiFfs);
697 if (this->fillFields_)
706 template<
class BasePhaseSystem>
710 const PtrList<volScalarField>& rAUs
713 PtrList<surfaceScalarField> phiKdPhis(this->phaseModels_.size());
719 const phaseInterface interface(*
this, KdIter.key());
731 iter.otherPhase().U()
738 if (this->fillFields_)
752 template<
class BasePhaseSystem>
756 const PtrList<surfaceScalarField>& rAUfs
759 PtrList<surfaceScalarField> phiKdPhifs(this->phaseModels_.size());
765 const phaseInterface interface(*
this, KdfIter.key());
773 -rAUfs[iter().index()]*Kf
777 iter.otherPhase().U()
784 if (this->fillFields_)
798 template<
class BasePhaseSystem>
802 const PtrList<volScalarField>& rAUs
805 PtrList<volVectorField> KdUByAs(this->phaseModels_.size());
811 const phaseInterface interface(*
this, KdIter.key());
819 -rAUs[iter().index()]*K*iter.otherPhase().U(),
825 if (this->fillFields_)
834 template<
class BasePhaseSystem>
839 this->mesh_.solution().solverDict(phase.volScalarField::name()).
840 template lookupOrDefault<Switch>
842 "implicitPhasePressure",
848 template<
class BasePhaseSystem>
852 bool implicitPressure =
false;
854 forAll(this->phaseModels_, phasei)
856 const phaseModel& phase = this->phaseModels_[
phasei];
858 implicitPressure = implicitPressure || implicitPhasePressure(phase);
861 return implicitPressure;
865 template<
class BasePhaseSystem>
869 const PtrList<volScalarField>& rAUs,
870 const PtrList<surfaceScalarField>& rAUfs
873 PtrList<surfaceScalarField> DByAfs(this->phaseModels_.size());
878 forAll(this->phaseModels_, phasei)
880 const phaseModel& phase = this->phaseModels_[
phasei];
887 addField(phase,
"DByAf", pPrimeByAf, DByAfs);
889 forAll(this->phaseModels_, phasej)
891 if (phasej != phasei)
893 const phaseModel& phase2 = this->phaseModels_[phasej];
902 /
max(1 - phase, phase2.residualAlpha())
913 turbulentDispersionModelTable,
914 turbulentDispersionModels_,
915 turbulentDispersionModelIter
918 const phaseInterface&
interface =
919 turbulentDispersionModelIter()->interface();
935 rAUfs[interface.phase1().index()]*Df
936 /
max(alpha12f, interface.phase1().residualAlpha()),
943 rAUfs[interface.phase2().index()]*Df
944 /
max(alpha12f, interface.phase2().residualAlpha()),
952 forAll(this->phaseModels_, phasei)
954 const phaseModel& phase = this->phaseModels_[
phasei];
961 addField(phase,
"DByAf", pPrimeByAf, DByAfs);
963 forAll(this->phaseModels_, phasej)
965 if (phasej != phasei)
967 const phaseModel& phase2 = this->phaseModels_[phasej];
976 /
max(1 - phase, phase2.residualAlpha())
987 turbulentDispersionModelTable,
988 turbulentDispersionModels_,
989 turbulentDispersionModelIter
992 const phaseInterface&
interface =
993 turbulentDispersionModelIter()->interface();
999 interface.phase1() + interface.phase2()
1008 rAUs[interface.phase1().index()]*D
1009 /
max(alpha12, interface.phase1().residualAlpha())
1019 rAUs[interface.phase2().index()]*D
1020 /
max(alpha12, interface.phase2().residualAlpha())
1031 template<
class BasePhaseSystem>
1035 const PtrList<volScalarField>& rAUs,
1036 const bool includeVirtualMass
1039 PtrList<surfaceScalarField> ddtCorrByAs(this->phaseModels_.size());
1042 PtrList<surfaceScalarField> phiCorrs(this->phaseModels_.size());
1044 forAll(this->movingPhases(), movingPhasei)
1046 const phaseModel& phase = this->movingPhases()[movingPhasei];
1047 const label phasei = phase.index();
1052 this->
MRF().zeroFilter
1056 ? (this->mesh_.Sf() & phase.Uf()().
oldTime())()
1065 forAll(this->movingPhases(), movingPhasei)
1067 const phaseModel& phase = this->movingPhases()[movingPhasei];
1068 const label phasei = phase.index();
1077 tmp<surfaceScalarField> phiCorrCoeff =
pos0(alphafBar - 0.99);
1080 phiCorrCoeff.ref().boundaryFieldRef();
1087 !this->mesh_.boundary()[
patchi].coupled()
1088 || isA<cyclicAMIFvPatch>(this->mesh_.boundary()[
patchi])
1091 phiCorrCoeffBf[
patchi] = 0;
1108 if (includeVirtualMass)
1113 const phaseInterface interface(*
this, VmIter.key());
1117 const phaseModel& phase = iter();
1118 const phaseModel& otherPhase = iter.otherPhase();
1126 phiCorrs[phase.index()]
1133 - phiCorrs[otherPhase.index()]
1145 template<
class BasePhaseSystem>
1148 const PtrList<volScalarField>& rAUs,
1149 const PtrList<volVectorField>& KdUByAs,
1150 const PtrList<surfaceScalarField>& alphafs,
1151 const PtrList<surfaceScalarField>& phiKdPhis
1154 Info<<
"Inverting drag systems: ";
1160 volVectorField Um(this->movingPhases()[0]*this->movingPhases()[0].
U());
1164 label movingPhasei=1;
1165 movingPhasei<this->movingPhases().size();
1170 this->movingPhases()[movingPhasei]
1171 *this->movingPhases()[movingPhasei].U();
1178 if (!phases[i].stationary())
1180 phases[i].URef() += KdUByAs[i];
1181 phases[i].phiRef() += phiKdPhis[i];
1187 PtrList<PtrList<volScalarField>> KdByAs(phases.size());
1188 PtrList<PtrList<surfaceScalarField>> phiKds(phases.size());
1195 new PtrList<volScalarField>(phases.size())
1201 new PtrList<surfaceScalarField>(phases.size())
1208 const phaseInterface interface(*
this, KdIter.key());
1210 const label phase1i = interface.phase1().index();
1211 const label phase2i = interface.phase2().index();
1254 for (
label i = 0; i < phases.size(); i++)
1256 for (
label j = i + 1; j < phases.size(); j++)
1258 KdByAs[i][j] /= KdByAs[i][i];
1259 phiKds[i][j] /= phiKds[i][i];
1260 for (
label k = i + 1;
k < phases.size(); ++
k)
1262 KdByAs[j][
k] -= KdByAs[j][i]*KdByAs[i][
k];
1263 phiKds[j][
k] -= phiKds[j][i]*phiKds[i][
k];
1272 for (
label i = 1; i < phases.size(); i++)
1274 detKdByAs *= KdByAs[i][i];
1275 detPhiKdfs *= phiKds[i][i];
1278 Info<<
"Min cell/face det = " <<
gMin(detKdByAs.primitiveField())
1279 <<
"/" <<
gMin(detPhiKdfs.primitiveField()) <<
endl;
1283 for (
label i = 1; i < phases.size(); i++)
1285 if (!phases[i].stationary())
1287 for (
label j = 0; j < i; j ++)
1289 phases[i].URef() -= KdByAs[i][j]*phases[j].U();
1290 phases[i].phiRef() -= phiKds[i][j]*phases[j].phi();
1294 for (
label i = phases.size() - 1; i >= 0; i--)
1296 if (!phases[i].stationary())
1298 for (
label j = phases.size() - 1; j > i; j--)
1300 phases[i].URef() -= KdByAs[i][j]*phases[j].U();
1301 phases[i].phiRef() -= phiKds[i][j]*phases[j].phi();
1303 phases[i].URef() /= KdByAs[i][i];
1304 phases[i].phiRef() /= phiKds[i][i];
1309 this->setMixtureU(Um);
1310 this->setMixturePhi(alphafs, this->
phi());
1314 template<
class BasePhaseSystem>
1317 const PtrList<surfaceScalarField>& rAUfs,
1318 const PtrList<surfaceScalarField>& alphafs,
1319 const PtrList<surfaceScalarField>& phiKdPhifs
1322 Info<<
"Inverting drag system: ";
1330 if (!phases[i].stationary())
1332 phases[i].phiRef() += phiKdPhifs[i];
1338 PtrList<PtrList<surfaceScalarField>> phiKdfs(phases.size());
1345 new PtrList<surfaceScalarField>(phases.size())
1352 const phaseInterface interface(*
this, KdfIter.key());
1354 const label phase1i = interface.phase1().index();
1355 const label phase2i = interface.phase2().index();
1381 for (
label i = 0; i < phases.size(); i++)
1383 for (
label j = i + 1; j < phases.size(); j++)
1385 phiKdfs[i][j] /= phiKdfs[i][i];
1386 for (
label k = i + 1;
k < phases.size(); ++
k)
1388 phiKdfs[j][
k] -= phiKdfs[j][i]*phiKdfs[i][
k];
1396 for (
label i = 1; i < phases.size(); i++)
1398 detPhiKdfs *= phiKdfs[i][i];
1401 Info<<
"Min face det = " 1402 <<
gMin(detPhiKdfs.primitiveField()) <<
endl;
1406 for (
label i = 1; i < phases.size(); i++)
1408 if (!phases[i].stationary())
1410 for (
label j = 0; j < i; j ++)
1412 phases[i].phiRef() -= phiKdfs[i][j]*phases[j].phi();
1416 for (
label i = phases.size() - 1; i >= 0; i--)
1418 if (!phases[i].stationary())
1420 for (
label j = phases.size() - 1; j > i; j--)
1422 phases[i].phiRef() -= phiKdfs[i][j]*phases[j].phi();
1424 phases[i].phiRef() /= phiKdfs[i][i];
1429 this->setMixturePhi(alphafs, this->
phi());
1433 template<
class BasePhaseSystem>
#define forAll(list, i)
Loop across all elements in list.
tmp< GeometricField< Type, fvPatchField, volMesh > > DDt(const surfaceScalarField &phi, const GeometricField< Type, fvPatchField, volMesh > &psi)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
FvWallInfoData< WallInfo, label > label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
virtual PtrList< surfaceScalarField > phiFs(const PtrList< volScalarField > &rAUs)
Return the explicit force fluxes for the cell-based algorithm, that.
const dimensionedScalar F
Faraday constant: default SI units: [C/mol].
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Type gMin(const FieldField< Field, Type > &f)
HashPtrTable< fvVectorMatrix > momentumTransferTable
virtual autoPtr< phaseSystem::momentumTransferTable > momentumTransferf()
As momentumTransfer, but for the face-based algorithm.
tmp< GeometricField< Type, fvPatchField, volMesh > > div(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
virtual bool read()
Read base phaseProperties dictionary.
Ostream & endl(Ostream &os)
Add newline and flush stream.
fluid fillFields("rAU", dimTime/dimDensity, rAUs)
MomentumTransferPhaseSystem(const fvMesh &)
Construct from fvMesh.
Calculate the snGrad of the given volField.
GeometricBoundaryField< scalar, fvsPatchField, surfaceMesh > Boundary
Type of the boundary field.
const dimensionSet dimless
label k
Boltzmann constant.
tmp< fvMatrix< Type > > Sp(const volScalarField::Internal &, const GeometricField< Type, fvPatchField, volMesh > &)
GeometricField< vector, fvPatchField, volMesh > volVectorField
CGAL::Exact_predicates_exact_constructions_kernel K
static const dimensionSet dimK
Coefficient dimensions.
dimensionedScalar posPart(const dimensionedScalar &ds)
Area-weighted average a surfaceField creating a volField.
virtual bool implicitPhasePressure() const
Returns true if the phase pressure is treated implicitly.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Calculate the first temporal derivative.
const dimensionSet dimTime
PtrList< surfaceScalarField > phiFs(fluid.phiFs(rAUs))
Calculate the face-flux of the given field.
static word groupName(Name name, const word &group)
virtual void partialEliminationf(const PtrList< surfaceScalarField > &rAUfs, const PtrList< surfaceScalarField > &alphafs, const PtrList< surfaceScalarField > &phiKdPhifs)
As partialElimination, but for the face-based algorithm. Only solves.
const dimensionSet dimDensity
tmp< fvMatrix< Type > > ddt(const GeometricField< Type, fvPatchField, volMesh > &vf)
Calculate the matrix for the first temporal derivative.
PtrListDictionary< phaseModel > phaseModelList
virtual PtrList< volVectorField > KdUByAs(const PtrList< volScalarField > &rAUs) const
Return the explicit part of the drag force for the cell-based.
const dimensionSet dimForce
virtual PtrList< surfaceScalarField > phiKdPhis(const PtrList< volScalarField > &rAUs) const
Return the explicit drag force fluxes for the cell-based algorithm.
Calculate the divergence of the given field.
dimensionedScalar pos0(const dimensionedScalar &ds)
PtrList< surfaceScalarField > phiFfs(fluid.phiFfs(rAUfs))
tmp< fvMatrix< Type > > div(const surfaceScalarField &flux, const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
const dimensionSet dimVelocity
const dimensionSet dimMass
virtual PtrList< surfaceScalarField > ddtCorrByAs(const PtrList< volScalarField > &rAUs, const bool includeVirtualMass=false) const
Return the flux corrections for the cell-based algorithm. These.
tmp< volScalarField > byDt(const volScalarField &vf)
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.
const tmp< volScalarField::Internal > & Sp
Calculate the mesh motion flux and convert fluxes from absolute to relative and back.
Calculate the matrix for the divergence of the given field and flux.
virtual ~MomentumTransferPhaseSystem()
Destructor.
virtual PtrList< surfaceScalarField > phiFfs(const PtrList< surfaceScalarField > &rAUfs)
As phiFs, but for the face-based algorithm.
tmp< surfaceScalarField > absolute(const tmp< surfaceScalarField > &tphi, const volVectorField &U)
Return the given relative flux in absolute form.
static const dimensionSet dimK
Coefficient dimensions.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
virtual void partialElimination(const PtrList< volScalarField > &rAUs, const PtrList< volVectorField > &KdUByAs, const PtrList< surfaceScalarField > &alphafs, const PtrList< surfaceScalarField > &phiKdPhis)
Solve the drag system for the velocities and fluxes.
fvMatrix< vector > fvVectorMatrix
phaseSystem::phaseModelList & phases
tmp< GeometricField< Type, fvPatchField, volMesh > > average(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Area-weighted average a surfaceField creating a volField.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
tmp< surfaceScalarField > flux(const volVectorField &vvf)
Return the face-flux field obtained from the given volVectorField.
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
virtual PtrList< surfaceScalarField > AFfs() const
Return implicit force coefficients on the faces, for the face-based.
virtual PtrList< surfaceScalarField > DByAfs(const PtrList< volScalarField > &rAUs, const PtrList< surfaceScalarField > &rAUfs) const
Return the phase diffusivity.
void addDmdtUfs(const phaseSystem::dmdtfTable &dmdtfs, phaseSystem::momentumTransferTable &eqns)
Add momentum transfer terms which result from bulk mass transfers.
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > snGrad(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Calculate the matrix for implicit and explicit sources.
dimensionedScalar negPart(const dimensionedScalar &ds)
virtual autoPtr< phaseSystem::momentumTransferTable > momentumTransfer()
Return the momentum transfer matrices for the cell-based algorithm.
virtual PtrList< surfaceScalarField > phiKdPhifs(const PtrList< surfaceScalarField > &rAUfs) const
As phiKdPhis, but for the face-based algorithm.