homogeneousLiquidPhaseSeparation.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) 2024-2026 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 
27 #include "fundamentalConstants.H"
31 
32 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36 namespace fv
37 {
40  (
41  fvModel,
44  );
45 }
46 }
47 
48 
49 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
50 
51 void Foam::fv::homogeneousLiquidPhaseSeparation::readCoeffs
52 (
53  const dictionary& dict
54 )
55 {
56  solubilityCurve_.reset
57  (
59  (
60  "solubility",
63  dict
64  ).ptr()
65  );
66 }
67 
68 
70 Foam::fv::homogeneousLiquidPhaseSeparation::dAndMDotByAlphaSolution() const
71 {
72  #define infoFieldVariable(field, print) infoField(#field, field, print)
73 
77 
78  const ThermoRefPair<multicomponentThermo> multicomponentThermos =
79  this->multicomponentThermos(true, false);
80 
81  const fluidMulticomponentThermo& thermoSolution =
82  this->fluidMulticomponentThermos(true, false).first();
83 
84  const volScalarField& p = this->p();
85  const volScalarField& T = thermoSolution.T();
86  infoFieldVariable(p, debug);
87  infoFieldVariable(T, debug);
88 
89  // Phase molecular masses and densities
90  const volScalarField::Internal rhoSolution(vfToVif(thermoSolution.rho()));
91  const volScalarField::Internal WPrecipitate
92  (
93  multicomponentThermos.valid().second()
95  (
96  "W",
97  mesh(),
98  multicomponentThermos.second().Wi(specieis().second())
99  )
100  : vfToVif(thermos().second().W())
101  );
102  const volScalarField::Internal rhoPrecipitate
103  (
104  multicomponentThermos.valid().second()
105  ? vfToVif(multicomponentThermos.second().rhoi(specieis().second(), p, T))
106  : vfToVif(thermos().second().rho())
107  );
108  infoFieldVariable(rhoSolution, debug);
109  infoFieldVariable(WPrecipitate, debug);
110  infoFieldVariable(rhoPrecipitate, debug);
111 
112  // Viscosity
113  const volScalarField::Internal muSolution(vfToVif(thermoSolution.mu()));
114 
115  // Surface tension
116  const volScalarField::Internal sigma(this->sigma());
117  infoFieldVariable(sigma, debug);
118 
119  // Mass fraction of nucleating specie
120  const volScalarField::Internal Yi = thermoSolution.Y()[specieis().first()];
121 
122  // Saturation mass fraction and concentration
123  const volScalarField::Internal solubility
124  (
126  (
127  "YSat",
128  mesh(),
129  dimless,
130  solubilityCurve_->value(T)
131  )
132  );
133  const volScalarField::Internal YSat(solubility/(solubility + 1));
134  const volScalarField::Internal cSat(YSat*rhoSolution/WPrecipitate);
135  infoFieldVariable(YSat, debug);
136  infoFieldVariable(cSat, debug);
137 
138  // Supersaturation of the nucleating specie
139  const volScalarField::Internal S(Yi/YSat);
140  infoFieldVariable(S, true);
141 
142  // Mass and diameter of one molecule in the precipitate
143  const volScalarField::Internal mMolc(WPrecipitate/NNA);
144  const volScalarField::Internal dMolc(cbrt(6/pi*(mMolc/rhoPrecipitate)));
145  infoFieldVariable(mMolc, debug);
146  infoFieldVariable(dMolc, debug);
147 
148  // Diameter and mass of a nucleus
149  tmp<volScalarField::Internal> td =
150  4*sigma*mMolc/rhoPrecipitate/(k*T()*log(max(S, 1 + small)));
151  const volScalarField::Internal& d = td();
152  const volScalarField::Internal m(pi/6*pow3(d)*rhoPrecipitate);
153  infoFieldVariable(d, true);
154  infoField("m/mMolc", m/mMolc, debug);
155 
156  // Free energy cost of a nucleus
157  const volScalarField::Internal deltaPhiStar(pi/3*sigma*sqr(d));
158  infoFieldVariable(deltaPhiStar, debug);
159 
160  // Number-based nucleation rate; i.e., number of nuclei created per second
161  // per unit volume
163  (
164  cSat*NNA*k*T()/(3*pi*pow3(dMolc)*muSolution)*exp(-deltaPhiStar/(k*T()))
165  );
166  infoFieldVariable(J, debug);
167 
168  return Pair<tmp<volScalarField::Internal>>(td, J*m);
169 
170  #undef infoFieldVariable
171 }
172 
173 
174 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
175 
177 (
178  const word& name,
179  const word& modelType,
180  const fvMesh& mesh,
181  const dictionary& dict
182 )
183 :
184  homogeneousNucleation(name, modelType, mesh, dict),
185  solubilityCurve_(nullptr)
186 {
187  readCoeffs(coeffs(dict));
188 }
189 
190 
191 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
192 
194 {
196  {
197  readCoeffs(coeffs(dict));
198  return true;
199  }
200  else
201  {
202  return false;
203  }
204 }
205 
206 
207 // ************************************************************************* //
label k
Macros for easy insertion into run-time selection tables.
static tmp< DimensionedField< Type, GeoMesh, PrimitiveField > > New(const word &name, const GeoMesh &mesh, const dimensionSet &, const PrimitiveField< Type > &)
Return a temporary field constructed from name, mesh,.
static autoPtr< Function1< scalar > > New(const word &name, const Function1s::unitSets &units, const dictionary &dict)
Select from dictionary.
Definition: Function1New.C:32
DimensionedField< Type, GeoMesh, PrimitiveField > Internal
Type of the internal field from which this GeometricField is derived.
An ordered pair of two objects of type <Type> with first() and second() elements.
Definition: Pair.H:67
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:98
Finite volume model abstract base class.
Definition: fvModel.H:60
static const dictionary & coeffs(const word &modelType, const dictionary &)
Return the coefficients sub-dictionary for a given model type.
Definition: fvModelI.H:31
Model for the homogeneous nucleation of a solid or liquid phase separating out of a liquid solution.
homogeneousLiquidPhaseSeparation(const word &name, const word &modelType, const fvMesh &mesh, const dictionary &dict)
Construct from explicit source name and mesh.
virtual bool read(const dictionary &dict)
Read source dictionary.
Base class for homogeneous nucleation models based on classical nucleation theory.
virtual bool read(const dictionary &dict)
Read source dictionary.
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)
Fundamental dimensioned constants.
#define infoFieldVariable(field, print)
rho
Definition: pEqn.H:1
const dimensionedScalar k
Boltzmann constant.
const dimensionedScalar sigma
Stefan-Boltzmann constant: default SI units: [W/m^2/K^4].
const dimensionedScalar NNA
Avagadro number: default SI units: [1/kmol].
addToRunTimeSelectionTable(fvConstraint, bound, dictionary)
defineTypeNameAndDebug(bound, 0)
tmp< fvMatrix< Type > > S(const Pair< tmp< volScalarField::Internal >> &, const VolField< Type > &)
const unitSet fraction
Namespace for OpenFOAM.
dimensionedScalar exp(const dimensionedScalar &ds)
const dimensionSet & dimless
Definition: dimensions.C:138
labelList second(const UList< labelPair > &p)
Definition: patchToPatch.C:49
dimensionedScalar log(const dimensionedScalar &ds)
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
scalarList W(const fluidMulticomponentThermo &thermo)
VolField< scalar > volScalarField
Definition: volFieldsFwd.H:62
void pow3(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
void cbrt(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)
const dimensionSet & dimTemperature
Definition: dimensions.C:143
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
labelList fv(nPoints)
dictionary dict
volScalarField & p