34 template<
class BasePhaseSystem>
38 const phasePairKey& key
41 tmp<volScalarField> tTotalDmdtf = phaseSystem::dmdtf(key);
44 const scalar tTotalDmdtfSign =
47 if (dmdtfs_.found(key))
49 totalDmdtf += *dmdtfs_[key];
52 if (nDmdtfs_.found(key))
54 totalDmdtf += *nDmdtfs_[key];
57 return tTotalDmdtfSign*tTotalDmdtf;
63 template<
class BasePhaseSystem>
70 BasePhaseSystem(mesh),
71 volatile_(this->template lookupOrDefault<word>(
"volatile",
"none")),
72 dmdt0s_(this->
phases().size())
74 this->generatePairsAndSubModels
87 const phasePair& pair(phasePairIter());
104 "thermalPhaseChange:dmdtf",
107 this->
mesh().time().timeName(),
127 "thermalPhaseChange:nucleation:dmdtf",
130 this->
mesh().time().timeName(),
150 "thermalPhaseChange:nucleation:dmdtLf",
153 this->
mesh().time().timeName(),
168 template<
class BasePhaseSystem>
176 template<
class BasePhaseSystem>
180 const phasePairKey& key
183 return saturationModels_[key];
187 template<
class BasePhaseSystem>
191 const phasePairKey& key
194 return BasePhaseSystem::dmdtf(key) + this->totalDmdtf(key);
198 template<
class BasePhaseSystem>
202 PtrList<volScalarField>
dmdts(BasePhaseSystem::dmdts());
206 const phasePair& pair = this->phasePairs_[dmdtfIter.key()];
209 addField(pair.phase1(),
"dmdt",
dmdtf,
dmdts);
210 addField(pair.phase2(),
"dmdt", -
dmdtf,
dmdts);
215 const phasePair& pair = this->phasePairs_[nDmdtfIter.key()];
218 addField(pair.phase1(),
"dmdt", nDmdtf,
dmdts);
219 addField(pair.phase2(),
"dmdt", - nDmdtf,
dmdts);
226 template<
class BasePhaseSystem>
231 autoPtr<phaseSystem::momentumTransferTable> eqnsPtr =
236 this->addDmdtUfs(dmdtfs_, eqns);
237 this->addDmdtUfs(nDmdtfs_, eqns);
243 template<
class BasePhaseSystem>
248 autoPtr<phaseSystem::momentumTransferTable> eqnsPtr =
249 BasePhaseSystem::momentumTransferf();
253 this->addDmdtUfs(dmdtfs_, eqns);
254 this->addDmdtUfs(nDmdtfs_, eqns);
260 template<
class BasePhaseSystem>
264 autoPtr<phaseSystem::heatTransferTable> eqnsPtr =
265 BasePhaseSystem::heatTransfer();
271 typename BasePhaseSystem::heatTransferModelTable,
272 this->heatTransferModels_,
273 heatTransferModelIter
276 const phasePair& pair
278 this->phasePairs_[heatTransferModelIter.key()]
281 const phaseModel& phase1 = pair.phase1();
282 const phaseModel& phase2 = pair.phase2();
290 *eqns[phase1.name()] +=
291 H1*(Tf - phase1.thermo().T())
292 - HEff*(phase2.thermo().T() - phase1.thermo().T());
294 *eqns[phase2.name()] +=
295 H2*(Tf - phase2.thermo().T())
296 - HEff*(phase1.thermo().T() - phase2.thermo().T());
306 const phaseModel& phase(phaseIter());
308 if (dmdt0s_.set(phase.index()))
310 *eqns[phase.name()] +=
311 fvm::Sp(dmdt0s_[phase.index()],phase.thermo().he());
322 const phasePair& pair(phasePairIter());
329 const phaseModel& phase1 = pair.phase1();
330 const phaseModel& phase2 = pair.phase2();
332 const rhoThermo& thermo1 = phase1.thermo();
333 const rhoThermo& thermo2 = phase2.thermo();
345 *eqns[phase1.name()] +=
347 + dmdtf21*K2 + dmdtf12*
K1;
349 *eqns[phase2.name()] -=
351 + dmdtf12*K1 + dmdtf21*
K2;
353 if (this->saturationModels_.found(phasePairIter.key()))
357 if (volatile_ !=
"none" && isA<rhoReactionThermo>(thermo1))
359 const basicSpecieMixture& composition1 =
362 *eqns[phase1.name()] +=
366 composition1.species()[volatile_],
373 *eqns[phase1.name()] +=
374 dmdtf21*thermo1.he(thermo1.p(), Tf);
377 if (volatile_ !=
"none" && isA<rhoReactionThermo>(thermo2))
379 const basicSpecieMixture& composition2 =
382 *eqns[phase2.name()] -=
386 composition2.species()[volatile_],
393 *eqns[phase2.name()] -=
394 dmdtf12*thermo2.he(thermo2.p(), Tf);
399 *eqns[phase1.name()] += dmdtf21*he2;
400 *eqns[phase2.name()] -= dmdtf12*he1;
403 if (this->nDmdtLfs_.found(phasePairIter.key()))
405 *eqns[phase1.name()] +=
negPart(*this->nDmdtLfs_[pair]);
406 *eqns[phase2.name()] -=
posPart(*this->nDmdtLfs_[pair]);
409 if (phase1.thermo().he().member() ==
"e")
411 *eqns[phase1.name()] +=
412 phase1.thermo().p()*dmdtf/phase1.thermo().rho();
415 if (phase2.thermo().he().member() ==
"e")
417 *eqns[phase2.name()] -=
418 phase2.thermo().p()*dmdtf/phase2.thermo().rho();
426 template<
class BasePhaseSystem>
430 autoPtr<phaseSystem::specieTransferTable> eqnsPtr =
433 if (volatile_ ==
"none")
447 const phasePair& pair(phasePairIter());
454 const phaseModel& phase1 = pair.phase1();
455 const phaseModel& phase2 = pair.phase2();
457 if (phase1.pure() || phase2.pure())
460 <<
"Volatile specie was given, but at least one phase in pair " 461 << pair <<
" is pure." 470 *eqns[Y1.name()] +=
dmdtf;
471 *eqns[Y2.name()] -=
dmdtf;
478 template<
class BasePhaseSystem>
482 dmdt0s_ = PtrList<volScalarField>(this->
phases().size());
486 const phasePair& pair = this->phasePairs_[dmdtfIter.key()];
489 addField(pair.phase1(),
"dmdt",
dmdtf, dmdt0s_);
490 addField(pair.phase2(),
"dmdt", -
dmdtf, dmdt0s_);
495 const phasePair& pair = this->phasePairs_[nDmdtfIter.key()];
498 addField(pair.phase1(),
"dmdt", nDmdtf, dmdt0s_);
499 addField(pair.phase2(),
"dmdt", - nDmdtf, dmdt0s_);
502 BasePhaseSystem::correctContinuityError();
506 template<
class BasePhaseSystem>
510 typedef compressible::alphatPhaseChangeWallFunctionFvPatchScalarField
511 alphatPhaseChangeWallFunction;
515 typename BasePhaseSystem::heatTransferModelTable,
516 this->heatTransferModels_,
517 heatTransferModelIter
520 const phasePair& pair
522 this->phasePairs_[heatTransferModelIter.key()]
525 const phaseModel& phase1 = pair.phase1();
526 const phaseModel& phase2 = pair.phase2();
528 const rhoThermo& thermo1 = phase1.thermo();
529 const rhoThermo& thermo2 = phase2.thermo();
541 if (saturationModels_.found(heatTransferModelIter.key()))
543 const phasePairKey& key = heatTransferModelIter.key();
549 if (volatile_ !=
"none" && isA<rhoReactionThermo>(thermo1))
551 const basicSpecieMixture& composition1 =
557 composition1.species()[volatile_],
565 composition1.species()[volatile_],
574 if (volatile_ !=
"none" && isA<rhoReactionThermo>(thermo2))
576 const basicSpecieMixture& composition2 =
582 composition2.species()[volatile_],
590 composition2.species()[volatile_],
598 (
neg0(dmdtf)*haf2 +
pos(dmdtf)*ha2)
599 - (
pos0(dmdtf)*haf1 +
neg(dmdtf)*ha1)
605 dmdtfNew = (H1*(Tsat - T1) + H2*(Tsat - T2))/L;
607 if (volatile_ !=
"none")
610 neg0(dmdtfNew)*phase1.Y(volatile_)
611 +
pos(dmdtfNew)*phase2.Y(volatile_);
614 H1 = heatTransferModelIter().first()->K();
615 H2 = heatTransferModelIter().second()->K();
621 Tf = (H1*T1 + H2*T2 + dmdtfNew*L)/(H1 + H2);
629 Tf = (H1*T1 + H2*T2)/(H1 + H2);
632 Info<<
"Tf." << pair.name()
633 <<
": min = " <<
min(Tf.primitiveField())
634 <<
", mean = " <<
average(Tf.primitiveField())
635 <<
", max = " <<
max(Tf.primitiveField())
639 this->
mesh().fieldRelaxationFactor(dmdtf.member());
640 dmdtf = (1 - dmdtfRelax)*dmdtf + dmdtfRelax*dmdtfNew;
642 if (saturationModels_.found(heatTransferModelIter.key()))
645 <<
": min = " <<
min(dmdtf.primitiveField())
646 <<
", mean = " <<
average(dmdtf.primitiveField())
647 <<
", max = " <<
max(dmdtf.primitiveField())
657 bool wallBoilingActive =
false;
661 const phaseModel& phase = iter();
662 const phaseModel& otherPhase = iter.otherPhase();
670 saturationModels_.found(heatTransferModelIter.key())
682 const fvPatch& currPatch = patches[
patchi];
686 isA<alphatPhaseChangeWallFunction>
688 alphat.boundaryField()[
patchi]
692 const alphatPhaseChangeWallFunction& PCpatch =
693 refCast<const alphatPhaseChangeWallFunction>
695 alphat.boundaryField()[
patchi]
698 phasePairKey key(phase.name(), otherPhase.name());
700 if (PCpatch.activePhasePair(key))
702 wallBoilingActive =
true;
704 const scalarField& patchDmdtf = PCpatch.dmdtf(key);
715 const label faceCelli =
716 currPatch.faceCells()[facei];
717 nDmdtf[faceCelli] -=
sign*patchDmdtf[facei];
718 nDmdtLf[faceCelli] -=
sign*patchDmdtLf[facei];
726 if (wallBoilingActive)
729 <<
": min = " <<
min(nDmdtf.primitiveField())
730 <<
", mean = " <<
average(nDmdtf.primitiveField())
731 <<
", max = " <<
max(nDmdtf.primitiveField())
739 template<
class BasePhaseSystem>
dimensionedScalar sign(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)
HashTable< autoPtr< phasePair >, phasePairKey, phasePairKey::hash > phasePairTable
virtual PtrList< volScalarField > dmdts() const
Return the mass transfer rates for each phase.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
ThermalPhaseChangePhaseSystem(const fvMesh &)
Construct from fvMesh.
basicSpecieMixture & composition
HashPtrTable< fvVectorMatrix > momentumTransferTable
static int compare(const Pair< word > &a, const Pair< word > &b)
Compare Pairs.
virtual autoPtr< phaseSystem::specieTransferTable > specieTransfer() const
Return the specie transfer matrices.
Ostream & endl(Ostream &os)
Add newline and flush stream.
virtual PtrList< volScalarField > dmdts() const
Return the mass transfer rates for each phase.
HashPtrTable< fvScalarMatrix > heatTransferTable
dimensioned< Type > domainIntegrate(const GeometricField< Type, fvPatchField, volMesh > &vf)
HashPtrTable< fvScalarMatrix > specieTransferTable
const saturationModel & saturation(const phasePairKey &key) const
Return the saturationModel.
tmp< fvMatrix< Type > > Sp(const volScalarField::Internal &, const GeometricField< Type, fvPatchField, volMesh > &)
CGAL::Exact_predicates_exact_constructions_kernel K
dimensionedScalar posPart(const dimensionedScalar &ds)
Class to provide interfacial heat and mass transfer between a number of phases according the interfac...
dimensionedScalar neg(const dimensionedScalar &ds)
virtual tmp< volScalarField > dmdtf(const phasePairKey &key) const
Return the mass transfer rate for an interface.
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
dimensionedScalar pos(const dimensionedScalar &ds)
const dimensionSet dimVolume(pow3(dimLength))
virtual void correctInterfaceThermo()
Correct the interface thermodynamics.
mixture thermo2().correctRho(psi2 *(p_rgh - p_rgh_0))
virtual tmp< volScalarField > dmdtf(const phasePairKey &key) const
Return the mass transfer rate for an interface.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
static word groupName(Name name, const word &group)
HashPtrTable< volScalarField, phasePairKey, phasePairKey::hash > dmdtfTable
dimensionedScalar neg0(const dimensionedScalar &ds)
PtrListDictionary< phaseModel > phaseModelList
virtual autoPtr< phaseSystem::heatTransferTable > heatTransfer() const
Return the heat transfer matrices.
virtual autoPtr< phaseSystem::momentumTransferTable > momentumTransferf()
Return the momentum transfer matrices for the face-based algorithm.
Volume integrate volField creating a volField.
mixture thermo1().correctRho(psi1 *(p_rgh - p_rgh_0))
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
dimensionedScalar pos0(const dimensionedScalar &ds)
phaseSystem::specieTransferTable & specieTransfer(specieTransferPtr())
const Mesh & mesh() const
Return mesh.
virtual bool read()
Read base phaseProperties dictionary.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
const dimensionSet dimEnergy
phaseSystem::momentumTransferTable & momentumTransfer(momentumTransferPtr())
const dimensionSet dimDensity
Internal & ref()
Return a reference to the dimensioned internal field.
PtrList< fvPatch > fvPatchList
container classes for fvPatch
virtual ~ThermalPhaseChangePhaseSystem()
Destructor.
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...
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
virtual void correctContinuityError()
Store phase dmdts at the during the continuity error update.
phaseSystem::phaseModelList & phases
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
A class for managing temporary objects.
virtual autoPtr< phaseSystem::momentumTransferTable > momentumTransfer()
Return the momentum transfer matrices for the cell-based algorithm.
Calculate the matrix for implicit and explicit sources.
dimensionedScalar negPart(const dimensionedScalar &ds)