homogeneousNucleation.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2025 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "homogeneousNucleation.H"
27 #include "multicomponentThermo.H"
28 #include "multiphaseEuler.H"
29 #include "phaseSystem.H"
30 
31 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35 namespace fv
36 {
38 }
39 }
40 
41 
42 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 
44 void Foam::fv::homogeneousNucleation::readCoeffs(const dictionary& dict)
45 {
47 }
48 
49 
50 void Foam::fv::homogeneousNucleation::correctDAndMDot() const
51 {
52  Info<< type() << ": " << name() << endl << incrIndent;
53 
54  Pair<tmp<volScalarField::Internal>> dAndMDotByAlphaSolution =
55  this->dAndMDotByAlphaSolution();
56 
57  d_ = dAndMDotByAlphaSolution.first();
58 
59  mDotByAlphaSolution_ = dAndMDotByAlphaSolution.second();
60  infoField("mDotByAlphaSolution", mDotByAlphaSolution_, debug);
61 
62  const volScalarField::Internal alphaSolution =
63  mesh().lookupObject<volScalarField::Internal>(alphaNames().first());
64 
65  mDot_ = alphaSolution*mDotByAlphaSolution_;
66  infoField("mDot", mDot_);
67 
68  Info<< decrIndent;
69 }
70 
71 
72 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
73 
76 {
77  return vfToVif(fluid_.sigma(phaseInterface(solution_, nucleate_)));
78 }
79 
80 
81 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
82 
84 (
85  const word& name,
86  const word& modelType,
87  const fvMesh& mesh,
88  const dictionary& dict
89 )
90 :
91  phaseChange(name, modelType, mesh, dict, readSpecie(dict, true)),
92  fluid_
93  (
94  mesh().lookupObject<phaseSystem>(phaseSystem::propertiesName)
95  ),
96  solution_(fluid_.phases()[phaseNames().first()]),
97  nucleate_(fluid_.phases()[phaseNames().second()]),
98  p_rgh_
99  (
100  mesh().lookupObject<solvers::multiphaseEuler>(solver::typeName).p_rgh
101  ),
102  d_
103  (
104  IOobject
105  (
106  name + ":d",
107  mesh.time().name(),
108  mesh,
109  IOobject::READ_IF_PRESENT,
110  IOobject::AUTO_WRITE
111  ),
112  mesh,
114  ),
115  mDotByAlphaSolution_
116  (
117  IOobject
118  (
119  IOobject::groupName(name + ":mDotByAlpha", solution_.name()),
120  mesh.time().name(),
121  mesh,
122  IOobject::READ_IF_PRESENT,
123  IOobject::AUTO_WRITE
124  ),
125  mesh,
127  ),
128  mDot_
129  (
130  IOobject
131  (
132  name + ":mDot",
133  mesh.time().name(),
134  mesh,
135  IOobject::READ_IF_PRESENT,
136  IOobject::AUTO_WRITE
137  ),
138  mesh,
140  )
141 {
142  readCoeffs(coeffs(dict));
143 }
144 
145 
146 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
147 
150 {
151  return d_;
152 }
153 
154 
157 {
158  const ThermoRefPair<multicomponentThermo> multicomponentThermos =
159  this->multicomponentThermos(true, false);
160 
161  const multicomponentThermo& thermoSolution = multicomponentThermos.first();
162 
163  const volScalarField& p = this->p();
164  const volScalarField& T = thermoSolution.T();
165 
166  const volScalarField::Internal rhoNucleate
167  (
168  multicomponentThermos.valid().second()
169  ? vfToVif(multicomponentThermos.second().rhoi(specieis().second(), p, T))
170  : vfToVif(thermos().second().rho())
171  );
172 
174 
175  return mDot_/(rhoNucleate*v);
176 }
177 
178 
181 {
182  return mDot_;
183 }
184 
185 
188 {
189  static const dimensionedScalar mDotRootVSmall
190  (
192  rootVSmall
193  );
194 
195  const ThermoRefPair<multicomponentThermo> multicomponentThermos =
196  this->multicomponentThermos(true, false);
197 
198  const multicomponentThermo& thermoSolution = multicomponentThermos.first();
199 
200  // Solution molecular mass and density
201  const volScalarField::Internal WSolution(vfToVif(thermoSolution.W()));
202  const volScalarField::Internal rhoSolution(vfToVif(thermoSolution.rho()));
203 
204  // Mass and mole fractions of the nucleating specie in the fluid
205  const volScalarField::Internal& Yi = thermoSolution.Y()[specieis().first()];
206  const volScalarField::Internal Xi
207  (
208  Yi*WSolution/thermoSolution.Wi(specieis().first())
209  );
210 
211  return Xi*rhoSolution/max(mDotByAlphaSolution_, mDotRootVSmall);
212 }
213 
214 
216 {
217  // Reset the p_rgh equation solution counter
218  pressureEquationIndex_ = 0;
219 
220  // Correct the total phase change rate
221  correctDAndMDot();
222 }
223 
224 
226 (
227  const volScalarField& alpha,
228  const volScalarField& rho,
229  fvMatrix<scalar>& eqn
230 ) const
231 {
232  // Pressure equation (i.e., continuity, linearised in the pressure)
233  if
234  (
235  (&alpha == &solution_ || &alpha == &nucleate_)
236  && (&rho == &solution_.rho() || &rho == &nucleate_.rho())
237  && &eqn.psi() == &p_rgh_
238  )
239  {
240  // Ensure that the source is up-to date if this is the first call in
241  // the current phase loop
242  if (pressureEquationIndex_ % 2 == 0) correctDAndMDot();
243  pressureEquationIndex_ ++;
244  }
245 
246  // Let the base class add the actual source
248 }
249 
250 
252 {
253  if (phaseChange::read(dict))
254  {
255  readCoeffs(coeffs(dict));
256  return true;
257  }
258  else
259  {
260  return false;
261  }
262 }
263 
264 
265 // ************************************************************************* //
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Generic GeometricField class.
DimensionedField< Type, GeoMesh, PrimitiveField > Internal
Type of the internal field from which this GeometricField is derived.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
const Type & second() const
Return second.
Definition: PairI.H:121
Class containing a pair of thermo references. Handles down-casting to more specific thermo types by c...
Definition: ThermoRefPair.H:51
const Pair< bool > & valid() const
Access the validity flags.
const ThermoType & first() const
Access the first thermo.
const ThermoType & second() const
Access the second thermo.
virtual tmp< volScalarField > W() const =0
Molecular weight [kg/kmol].
virtual const volScalarField & T() const =0
Temperature [K].
virtual tmp< volScalarField > rho() const =0
Density [kg/m^3].
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
A special matrix type and solver, designed for finite volume solutions of scalar equations....
Definition: fvMatrix.H:118
VolField< Type > & psi()
Definition: fvMatrix.H:289
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:98
static const dictionary & coeffs(const word &modelType, const dictionary &)
Return the coefficients sub-dictionary for a given model type.
Definition: fvModelI.H:31
Base class for homogeneous nucleation models based on classical nucleation theory.
virtual void correct()
Correct the fvModel.
homogeneousNucleation(const word &name, const word &modelType, const fvMesh &mesh, const dictionary &dict)
Construct from explicit source name and mesh.
virtual tmp< DimensionedField< scalar, fvMesh > > mDot() const
Return the mass transfer rate.
virtual bool read(const dictionary &dict)
Read source dictionary.
tmp< volScalarField::Internal > sigma() const
Return the surface tension coefficient between the phases.
void addSup(const volScalarField &alpha, const volScalarField &rho, const volScalarField &heOrYi, fvMatrix< scalar > &eqn) const
Use phaseChange's source functions.
Definition: phaseChange.C:529
virtual tmp< DimensionedField< scalar, fvMesh > > d() const
Return the diameter of nuclei.
virtual tmp< DimensionedField< scalar, fvMesh > > tau() const
Return the nucleation time scale.
virtual tmp< DimensionedField< scalar, fvMesh > > nDot() const
Return the number rate at which nuclei are generated.
virtual void addSup(fvMatrix< scalar > &eqn) const
Add a source term to a field-less proxy equation.
Definition: massTransfer.C:223
Base class for phase change models.
Definition: phaseChange.H:61
void reReadSpecie(const dictionary &dict) const
Re-read the names of the transferring specie.
Definition: phaseChange.C:107
virtual bool read(const dictionary &dict)
Read source dictionary.
Definition: phaseChange.C:602
Base-class for multi-component thermodynamic properties.
virtual PtrList< volScalarField > & Y()=0
Access the mass-fraction fields.
virtual dimensionedScalar Wi(const label speciei) const =0
Molecular weight [kg/kmol].
const Type & lookupObject(const word &name) const
Lookup and return the object of the given Type and name.
Class to represent an interface between phases. Derivations can further specify the configuration of ...
Class to represent a system of phases.
Definition: phaseSystem.H:74
Abstract base class for run-time selectable region solvers.
Definition: solver.H:56
A class for managing temporary objects.
Definition: tmp.H:55
Template function which returns the un-mangled name of a given type. Useful for types which do not ha...
A class for handling words, derived from string.
Definition: word.H:63
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
rho
Definition: pEqn.H:1
volScalarField alpha(IOobject("alpha", runTime.name(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
const dimensionSet time
defineTypeNameAndDebug(bound, 0)
Namespace for OpenFOAM.
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:272
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
const dimensionSet & dimLength
Definition: dimensions.C:141
messageStream Info
labelList second(const UList< labelPair > &p)
Definition: patchToPatch.C:49
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:265
labelList first(const UList< labelPair > &p)
Definition: patchToPatch.C:39
const dimensionSet & dimTime
Definition: dimensions.C:142
const dimensionSet & dimDensity
Definition: dimensions.C:158
void pow3(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
void T(GeometricField< Type, GeoMesh, PrimitiveField1 > &gf, const GeometricField< Type, GeoMesh, PrimitiveField2 > &gf1)
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
labelList fv(nPoints)
dictionary dict
volScalarField & p