curvatureSeparation.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) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "curvatureSeparation.H"
31 #include "Time.H"
32 #include "stringListOps.H"
33 #include "cyclicPolyPatch.H"
34 
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 namespace regionModels
40 {
41 namespace areaSurfaceFilmModels
42 {
43 
44 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
45 
46 defineTypeNameAndDebug(curvatureSeparation, 0);
48 (
49  injectionModel,
50  curvatureSeparation,
52 );
53 
54 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
55 
57 (
58  const areaVectorField& U,
59  const scalarField& calcCosAngle
60 ) const
61 {
62  const dimensionedScalar smallU(dimVelocity, ROOTVSMALL);
63  const areaVectorField UHat(U/(mag(U) + smallU));
65  (
66  new areaScalarField("invR1", UHat & (UHat & -gradNHat_))
67  );
68 
69  scalarField& invR1 = tinvR1.ref().primitiveFieldRef();
70 
71  // apply defined patch radii
72  const scalar rMin = 1e-6;
73  const scalar definedInvR1 = 1.0/max(rMin, definedPatchRadii_);
74 
75  if (definedPatchRadii_ > 0)
76  {
77  invR1 = definedInvR1;
78  }
79 
80  // filter out large radii
81  const scalar rMax = 1e6;
82  forAll(invR1, i)
83  {
84  if ((mag(invR1[i]) < 1/rMax))
85  {
86  invR1[i] = -1.0;
87  }
88  }
89 
90  return tinvR1;
91 }
92 
93 
95 (
96  const edgeScalarField& phi
97 ) const
98 {
99  const areaVectorField& U = film().Uf();
100  const dimensionedScalar smallU(dimVelocity, ROOTVSMALL);
101  const areaVectorField UHat(U/(mag(U) + smallU));
102 
103  const faMesh& mesh = film().regionMesh();
104  const labelUList& own = mesh.edgeOwner();
105  const labelUList& nbr = mesh.edgeNeighbour();
106 
107  scalarField phiMax(mesh.nFaces(), -GREAT);
108  scalarField cosAngle(UHat.size(), Zero);
109 
110  const scalarField invR1(calcInvR1(U, cosAngle));
111 
112  forAll(nbr, edgei)
113  {
114  const label cellO = own[edgei];
115  const label cellN = nbr[edgei];
116 
117  if (phi[edgei] > phiMax[cellO])
118  {
119  phiMax[cellO] = phi[edgei];
120  cosAngle[cellO] = -gHat_ & UHat[cellN];
121  }
122  if (-phi[edgei] > phiMax[cellN])
123  {
124  phiMax[cellN] = -phi[edgei];
125  cosAngle[cellN] = -gHat_ & UHat[cellO];
126  }
127  }
128 
129  cosAngle *= pos(invR1);
130 
131  // checks
132  if (debug && mesh.time().writeTime())
133  {
134  areaScalarField volCosAngle
135  (
136  IOobject
137  (
138  "cosAngle",
139  film().primaryMesh().time().timeName(),
140  film().primaryMesh(),
142  ),
143  film().regionMesh(),
145  );
146  volCosAngle.primitiveFieldRef() = cosAngle;
147  volCosAngle.correctBoundaryConditions();
148  volCosAngle.write();
149  }
150 
151  return max(min(cosAngle, scalar(1)), scalar(-1));
152 }
153 
154 
155 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
156 
157 curvatureSeparation::curvatureSeparation
158 (
159  liquidFilmBase& film,
160  const dictionary& dict
161 )
162 :
163  injectionModel(type(), film, dict),
164  gradNHat_(fac::grad(film.regionMesh().faceAreaNormals())),
165  deltaByR1Min_(coeffDict_.getOrDefault<scalar>("deltaByR1Min", 0)),
166  definedPatchRadii_
167  (
168  coeffDict_.getOrDefault<scalar>("definedPatchRadii", 0)
169  ),
170  magG_(mag(film.g().value())),
171  gHat_(Zero),
172  fThreshold_
173  (
174  coeffDict_.getOrDefault<scalar>("fThreshold", 1e-8)
175  ),
176  minInvR1_
177  (
178  coeffDict_.getOrDefault<scalar>("minInvR1", 5)
179  )
180 {
181  if (magG_ < ROOTVSMALL)
182  {
184  << "Acceleration due to gravity must be non-zero"
185  << exit(FatalError);
186  }
187 
188  gHat_ = film.g().value()/magG_;
189 }
190 
191 
192 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
193 
195 (
196  scalarField& availableMass,
197  scalarField& massToInject,
198  scalarField& diameterToInject
199 )
200 {
201  const faMesh& mesh = film().regionMesh();
202 
203  const areaScalarField& delta = film().h();
204  const areaVectorField& U = film().Uf();
205  const edgeScalarField& phi = film().phi2s();
206  const areaScalarField& rho = film().rho();
207  const scalarField magSqrU(magSqr(film().Uf()));
208  const areaScalarField& sigma = film().sigma();
209 
210  const scalarField cosAngle(calcCosAngle(phi));
211  const scalarField invR1(calcInvR1(U, cosAngle));
212 
213 
214  // calculate force balance
215  scalarField Fnet(mesh.nFaces(), Zero);
216  scalarField separated(mesh.nFaces(), Zero);
217 
218  forAll(invR1, i)
219  {
220  if ((invR1[i] > minInvR1_) && (delta[i]*invR1[i] > deltaByR1Min_))
221  {
222  const scalar R1 = 1.0/(invR1[i] + ROOTVSMALL);
223  const scalar R2 = R1 + delta[i];
224 
225  // inertial force
226  const scalar Fi = -delta[i]*rho[i]*magSqrU[i]*72.0/60.0*invR1[i];
227 
228  // body force
229  const scalar Fb =
230  - 0.5*rho[i]*magG_*invR1[i]*(sqr(R1) - sqr(R2))*cosAngle[i];
231 
232  // surface force
233  const scalar Fs = sigma[i]/R2;
234 
235  Fnet[i] = Fi + Fb + Fs;
236 
237  if (Fnet[i] + fThreshold_ < 0)
238  {
239  separated[i] = 1.0;
240  }
241  }
242  }
243 
244  // inject all available mass
245  massToInject = separated*availableMass;
246  diameterToInject = separated*delta;
247  availableMass -= separated*availableMass;
248 
249  addToInjectedMass(sum(massToInject));
250 
251  if (debug && mesh.time().writeTime())
252  {
253  areaScalarField volFnet
254  (
255  IOobject
256  (
257  "Fnet",
258  film().primaryMesh().time().timeName(),
259  film().primaryMesh(),
261  ),
262  mesh,
264  );
265  volFnet.primitiveFieldRef() = Fnet;
266  volFnet.write();
267 
268  areaScalarField areaSeparated
269  (
270  IOobject
271  (
272  "separated",
273  film().primaryMesh().time().timeName(),
274  film().primaryMesh(),
276  ),
277  mesh,
279  );
280  areaSeparated.primitiveFieldRef() = separated;
281  areaSeparated.write();
282 
283  areaScalarField areaMassToInject
284  (
285  IOobject
286  (
287  "massToInject",
288  film().primaryMesh().time().timeName(),
289  film().primaryMesh(),
291  ),
292  mesh,
294  );
295  areaMassToInject.primitiveFieldRef() = massToInject;
296  areaMassToInject.write();
297 
298  areaScalarField areaInvR1
299  (
300  IOobject
301  (
302  "InvR1",
303  film().primaryMesh().time().timeName(),
304  film().primaryMesh(),
306  ),
307  mesh,
309  );
310  areaInvR1.primitiveFieldRef() = invR1;
311  areaInvR1.write();
312  }
313 
315 }
316 
317 
318 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
319 
320 } // End namespace areaSurfaceFilmModels
321 } // End namespace regionModels
322 } // End namespace Foam
323 
324 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::regionModels::areaSurfaceFilmModels::liquidFilmBase
Definition: liquidFilmBase.H:60
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::regionModels::areaSurfaceFilmModels::injectionModel::correct
void correct()
Correct.
Definition: injectionModel.C:81
Foam::dimLength
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:52
cyclicPolyPatch.H
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::dimVelocity
const dimensionSet dimVelocity
Uf
autoPtr< surfaceVectorField > Uf
Definition: createUfIfPresent.H:33
Foam::regionModels::areaSurfaceFilmModels::liquidFilmBase::phi2s
const edgeScalarField & phi2s() const
Access continuity flux.
Definition: liquidFilmBase.C:531
Foam::fac::grad
tmp< GeometricField< typename outerProduct< vector, Type >::type, faPatchField, areaMesh >> grad(const GeometricField< Type, faePatchField, edgeMesh > &ssf)
Definition: facGrad.C:56
Foam::dimensioned::value
const Type & value() const
Return const reference to value.
Definition: dimensionedType.C:434
Foam::dimForce
const dimensionSet dimForce
rho
rho
Definition: readInitialConditions.H:88
Foam::regionModels::areaSurfaceFilmModels::addToRunTimeSelectionTable
addToRunTimeSelectionTable(liquidFilmBase, kinematicThinFilm, dictionary)
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::magSqr
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
Foam::regionModels::areaSurfaceFilmModels::liquidFilmBase::Uf
const areaVectorField & Uf() const
Access const reference Uf.
Definition: liquidFilmBase.C:501
Foam::regionModels::areaSurfaceFilmModels::injectionModel
Base class for film injection models, handling mass transfer from the film.
Definition: injectionModel.H:58
CGAL::indexedFace
An indexed form of CGAL::Triangulation_face_base_2<K> used to keep track of the vertices in the trian...
Definition: indexedFace.H:50
Foam::regionModels::areaSurfaceFilmModels::liquidFilmBase::g
const uniformDimensionedVectorField & g() const
Gravity.
Definition: liquidFilmBase.C:513
Foam::tmp::ref
T & ref() const
Definition: tmpI.H:227
Foam::Field< scalar >
Foam::TimeState::writeTime
bool writeTime() const noexcept
True if this is a write time.
Definition: TimeStateI.H:67
Foam::inv
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
Definition: dimensionedSphericalTensor.C:73
Foam::faMesh::faceAreaNormals
const areaVectorField & faceAreaNormals() const
Return face area normals.
Definition: faMesh.C:682
delta
scalar delta
Definition: LISASMDCalcMethod2.H:8
Foam::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:42
phi
surfaceScalarField & phi
Definition: setRegionFluidFields.H:8
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
timeName
word timeName
Definition: getTimeIndex.H:3
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::regionModels::regionFaModel::regionMesh
const faMesh & regionMesh() const
Return the region mesh database.
Definition: regionFaModelI.H:63
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::dimensioned< scalar >
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::dimMass
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:51
Foam::areaScalarField
GeometricField< scalar, faPatchField, areaMesh > areaScalarField
Definition: areaFieldsFwd.H:53
Foam::regionModels::areaSurfaceFilmModels::curvatureSeparation::calcCosAngle
tmp< scalarField > calcCosAngle(const edgeScalarField &phi) const
Definition: curvatureSeparation.C:95
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::GeometricField::primitiveFieldRef
Internal::FieldType & primitiveFieldRef(const bool updateAccessTime=true)
Return a reference to the internal field.
Definition: GeometricField.C:766
curvatureSeparation.H
Foam::GeometricField::correctBoundaryConditions
void correctBoundaryConditions()
Correct boundary field.
Definition: GeometricField.C:940
Foam::regionModels::areaSurfaceFilmModels::liquidFilmBase::rho
virtual const areaScalarField & rho() const =0
Access const reference rho.
Time.H
U
U
Definition: pEqn.H:72
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::sqr
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Definition: dimensionedSymmTensor.C:51
Foam::regionModels::areaSurfaceFilmModels::defineTypeNameAndDebug
defineTypeNameAndDebug(kinematicThinFilm, 0)
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::regionModels::areaSurfaceFilmModels::curvatureSeparation::calcInvR1
tmp< areaScalarField > calcInvR1(const areaVectorField &U, const scalarField &calcCosAngle) const
Calculate local (inverse) radius of curvature.
Definition: curvatureSeparation.C:57
Foam::UList< label >
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:327
Foam::regionModels::areaSurfaceFilmModels::liquidFilmBase::h
const areaScalarField & h() const
Access const reference h.
Definition: liquidFilmBase.C:519
Foam::faMesh
Finite area mesh. Used for 2-D non-Euclidian finite area method.
Definition: faMesh.H:82
Foam::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:280
stringListOps.H
Operations on lists of strings.
Foam::primitiveMesh::nFaces
label nFaces() const noexcept
Number of mesh faces.
Definition: primitiveMeshI.H:90
Foam::regionModels::areaSurfaceFilmModels::liquidFilmBase::sigma
virtual const areaScalarField & sigma() const =0
Access const reference sigma.
sigma
dimensionedScalar sigma("sigma", dimMass/sqr(dimTime), transportProperties)
Foam::GeometricField< vector, faPatchField, areaMesh >
Foam::IOobject::NO_READ
Definition: IOobject.H:188
Foam::dimless
const dimensionSet dimless
Dimensionless.
Definition: dimensionSets.C:189
Foam::pos
dimensionedScalar pos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:177