liquidFilmModel.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2020-2023 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "liquidFilmModel.H"
31 #include "gravityMeshObject.H"
32 #include "volFields.H"
33 
34 
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 namespace regionModels
40 {
41 namespace areaSurfaceFilmModels
42 {
43 
44 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
45 
47 
48 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
49 
51 {
52  scalarField X(thermo_.size(), 1);
53 
54  forAll(rho_, faceI)
55  {
56  rho_[faceI] = thermo_.rho(pRef_, Tf_[faceI], X);
57  mu_[faceI] = thermo_.mu(pRef_, Tf_[faceI], X);
58  sigma_[faceI] = thermo_.sigma(pRef_, Tf_[faceI], X);
59  Cp_[faceI] = thermo_.Cp(pRef_, Tf_[faceI], X);
60  }
61 
62  forAll(regionMesh().boundary(), patchI)
63  {
64  const scalarField& patchTf = Tf_.boundaryFieldRef()[patchI];
65 
66  scalarField& patchRho = rho_.boundaryFieldRef()[patchI];
67  scalarField& patchmu = mu_.boundaryFieldRef()[patchI];
68  scalarField& patchsigma = sigma_.boundaryFieldRef()[patchI];
69  scalarField& patchCp = Cp_.boundaryFieldRef()[patchI];
70 
71  forAll(patchRho, edgeI)
72  {
73  patchRho[edgeI] = thermo_.rho(pRef_, patchTf[edgeI], X);
74  patchmu[edgeI] = thermo_.mu(pRef_, patchTf[edgeI], X);
75  patchsigma[edgeI] = thermo_.sigma(pRef_, patchTf[edgeI], X);
76  patchCp[edgeI] = thermo_.Cp(pRef_, patchTf[edgeI], X);
77  }
78  }
79 
80  //Initialize pf_
82 }
83 
84 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
85 
87 (
88  const word& modelType,
89  const fvMesh& mesh,
90  const dictionary& dict
91 )
92 :
93  liquidFilmBase(modelType, mesh, dict),
94 
95  thermo_(dict.subDict("thermo")),
96 
97  rho_
98  (
99  IOobject
100  (
101  "rhof",
102  regionMesh().time().timeName(),
103  regionMesh().thisDb(),
104  IOobject::NO_READ,
105  IOobject::AUTO_WRITE
106  ),
107  regionMesh(),
109  ),
110  mu_
111  (
112  IOobject
113  (
114  "muf",
115  regionMesh().time().timeName(),
116  regionMesh().thisDb(),
117  IOobject::NO_READ,
118  IOobject::NO_WRITE
119  ),
120  regionMesh(),
122  ),
123  Tf_
124  (
125  IOobject
126  (
127  "Tf_" + regionName_,
128  regionMesh().time().timeName(),
129  regionMesh().thisDb(),
130  IOobject::READ_IF_PRESENT,
131  IOobject::AUTO_WRITE
132  ),
133  regionMesh(),
135  ),
136  Cp_
137  (
138  IOobject
139  (
140  "Cp_" + regionName_,
141  regionMesh().time().timeName(),
142  regionMesh().thisDb(),
143  IOobject::NO_READ,
144  IOobject::NO_WRITE
145  ),
146  regionMesh(),
148  ),
149  sigma_
150  (
151  IOobject
152  (
153  "sigmaf",
154  regionMesh().time().timeName(),
155  regionMesh().thisDb(),
156  IOobject::NO_READ,
157  IOobject::NO_WRITE
158  ),
159  regionMesh(),
161  ),
162  hRho_
163  (
164  IOobject
165  (
166  h_.name() + "*" + rho_.name(),
167  regionMesh().time().timeName(),
168  regionMesh().thisDb(),
169  IOobject::NO_READ,
170  IOobject::NO_WRITE
171  ),
172  regionMesh(),
173  dimensionedScalar(h_.dimensions()*rho_.dimensions(), Zero)
174  ),
175  rhoSp_
176  (
177  IOobject
178  (
179  "rhoSp",
180  regionMesh().time().timeName(),
181  regionMesh().thisDb(),
182  IOobject::NO_READ,
183  IOobject::NO_WRITE
184  ),
185  regionMesh(),
187  ),
188  USp_
189  (
190  IOobject
191  (
192  "USp",
193  regionMesh().time().timeName(),
194  regionMesh().thisDb(),
195  IOobject::NO_READ,
196  IOobject::NO_WRITE
197  ),
198  regionMesh(),
200  ),
201  pnSp_
202  (
203  IOobject
204  (
205  "pnSp",
206  regionMesh().time().timeName(),
207  regionMesh().thisDb(),
208  IOobject::NO_READ,
209  IOobject::NO_WRITE
210  ),
211  regionMesh(),
213  ),
214  cloudMassTrans_
215  (
216  IOobject
217  (
218  "cloudMassTrans",
219  primaryMesh().time().timeName(),
220  primaryMesh().thisDb(),
221  IOobject::NO_READ,
222  IOobject::NO_WRITE
223  ),
224  primaryMesh(),
226  ),
227 
228  cloudDiameterTrans_
229  (
230  IOobject
231  (
232  "cloudDiameterTrans",
233  primaryMesh().time().timeName(),
234  primaryMesh().thisDb(),
235  IOobject::NO_READ,
236  IOobject::NO_WRITE
237  ),
238  primaryMesh(),
240  ),
241 
242  turbulence_(filmTurbulenceModel::New(*this, dict)),
243 
244  availableMass_(regionMesh().faces().size(), Zero),
245 
246  injection_(*this, dict),
247 
248  forces_(*this, dict)
249 {
250  if (dict.readIfPresent("T0", Tref_))
251  {
253  }
255 }
256 
257 
258 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
261 {
262  return mu_;
263 }
264 
267 {
268  return rho_;
269 }
270 
273 {
274  return sigma_;
275 }
276 
279 {
280  return Tf_;
281 }
282 
285 {
286  return Cp_;
287 }
288 
291 {
292  return thermo_;
293 }
294 
296 scalar liquidFilmModel::Tref() const
297 {
298  return Tref_;
299 }
300 
303 {
304  return cloudMassTrans_;
305 }
306 
309 {
310  return cloudDiameterTrans_;
311 }
312 
313 
315 {
317 
318 
321 
322  const scalar deltaT = primaryMesh().time().deltaTValue();
323  const scalarField rAreaDeltaT(scalar(1)/deltaT/regionMesh().S().field());
324 
325  // Map the total mass, mom [kg.m/s] and pnSource from particles
326 
328 
330 
332 
333 
334  // Calculate rate per area
335  rhoSp_.primitiveFieldRef() *= rAreaDeltaT/rho_;
336  USp_.primitiveFieldRef() *= rAreaDeltaT/rho_;
337  pnSp_.primitiveFieldRef() *= rAreaDeltaT/rho_;
339  rhoSp_.relax();
340  pnSp_.relax();
341  USp_.relax();
342 }
343 
344 
346 {
347  availableMass_ = (h() - h0_)*rho()*regionMesh().S();
350 }
351 
352 
354 {
355  Info<< "\nSurface film: " << type() << " on patch: ";
356 
357  for (const label patchi : this->primaryPatchIDs())
358  {
359  Info<< ' ' << patchi;
360  }
361  Info<< endl;
362 
364 
365  Info<< indent << "min/max(mag(Uf)) = "
366  << gMinMaxMag(Uf_.field()) << nl
367  << indent << "min/max(delta) = "
368  << gMinMax(h_.field()) << nl
369  << indent << "coverage = "
370  << gSum(alpha()().field()*mag(sf.field()))/gSumMag(sf.field()) << nl
371  << indent << "total mass = "
372  << gSum(availableMass_) << nl;
373 
375 }
376 
377 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
378 
379 } // End namespace areaSurfaceFilmModels
380 } // End namespace regionModels
381 } // End namespace Foam
382 
383 // ************************************************************************* //
scalar Cp(const scalar p, const scalar T, const scalarField &X) const
Calculate the mixture heat capacity [J/(kg K)].
faceListList boundary
void mapToSurface(const GeometricBoundaryField< Type, fvPatchField, volMesh > &, Field< Type > &result) const
Map volume boundary fields as area field.
const areaScalarField & rho() const
Access const reference rho.
dictionary dict
rDeltaTY field()
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:493
scalar deltaTValue() const noexcept
Return time step value.
Definition: TimeStateI.H:49
volScalarField cloudDiameterTrans_
Parcel diameters originating from film to cloud.
virtual void correct(scalarField &availableMass, volScalarField &massToInject, volScalarField &diameterToInject)
Correct.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
const areaScalarField & h() const
Access const reference h.
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
areaScalarField mu_
Dynamic viscosity [Pa.s].
const volSurfaceMapping & vsm() const
Return mapping between surface and volume fields.
liquidMixtureProperties thermo_
Liquid thermo.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
dimensionedScalar h0_
Smallest numerical thickness.
label size() const
Return the number of liquids in the mixture.
Various UniformDimensionedField types.
const dimensionSet dimViscosity
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
const DimensionedField< scalar, areaMesh > & S() const
Return face areas.
Definition: faMesh.C:914
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:360
virtual const volScalarField & cloudDiameterTrans() const
Return the parcel diameters originating from film to cloud.
virtual void info(Ostream &os)
Provide some info.
defineTypeNameAndDebug(kinematicThinFilm, 0)
const areaScalarField & mu() const
Access const reference mu.
Macros for easy insertion into run-time selection tables.
volScalarField pnSource_
Normal pressure by particles.
scalar mu(const scalar p, const scalar T, const scalarField &X) const
Calculate the mixture viscosity [Pa s].
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
const areaScalarField & Tf() const
Access const reference Tf.
scalar rho(const scalar p, const scalar T, const scalarField &X) const
Calculate the mixture density [kg/m^3].
word timeName
Definition: getTimeIndex.H:3
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
areaScalarField sigma_
Surface tension [m/s2].
dynamicFvMesh & mesh
Type gSum(const FieldField< Field, Type > &f)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
A class for handling words, derived from Foam::string.
Definition: word.H:63
const dimensionSet dimTemperature(0, 0, 0, 1, 0, 0, 0)
Definition: dimensionSets.H:52
scalar sigma(const scalar p, const scalar T, const scalarField &X) const
Estimate mixture surface tension [N/m].
tmp< GeometricField< Type, faPatchField, areaMesh > > laplacian(const GeometricField< Type, faPatchField, areaMesh > &vf, const word &name)
Definition: facLaplacian.C:40
const fvMesh & primaryMesh() const noexcept
Return the reference to the primary mesh database.
const areaScalarField & sigma() const
Access const reference sigma.
const faMesh & regionMesh() const
Return the region mesh database.
volScalarField cloudMassTrans_
Film mass for transfer to cloud.
MinMax< Type > gMinMax(const FieldField< Field, Type > &f)
const liquidMixtureProperties & thermo() const
Access to thermo.
const dimensionSet dimPressure
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
virtual const volScalarField & cloudMassTrans() const
Return the film mass available for transfer to cloud.
const areaScalarField & Cp() const
Access const reference Cp.
liquidFilmModel(const word &modelType, const fvMesh &mesh, const dictionary &dict)
Construct from components and dict.
scalar Tref() const
Access to reference temperature.
scalarMinMax gMinMaxMag(const FieldField< Field, Type > &f)
const dimensionSet dimEnergy
typeOfMag< Type >::type gSumMag(const FieldField< Field, Type > &f)
const dimensionSet dimDensity
const labelList & primaryPatchIDs() const
List of patch IDs on the primary region coupled to this region.
const Field< Type > & field() const noexcept
Return const-reference to the field values.
Internal::FieldType & primitiveFieldRef(const bool updateAccessTime=true)
Return a reference to the internal field values.
areaScalarField pnSp_
Normal pressure by particles.
void relax(const scalar alpha)
Relax field (for steady-state solution).
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:50
scalarField availableMass_
Available mass for transfer via sub-models.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Definition: areaFieldsFwd.H:42
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
Definition: dimensionSets.H:51
Boundary & boundaryFieldRef(const bool updateAccessTime=true)
Return a reference to the boundary field.
messageStream Info
Information stream (stdout output on master, null elsewhere)
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:49
tmp< areaScalarField > alpha() const
Wet indicator using h0.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:172
Namespace for OpenFOAM.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127
const dimensionSet dimVelocity