45 FriedrichModel::separationType
47FriedrichModel::separationTypeNames
49 { separationType::FULL,
"full" },
50 { separationType::PARTIAL ,
"partial" },
56bitSet FriedrichModel::calcCornerEdges()
const
70 const label faceO = own[edgei];
71 const label faceN = nbr[edgei];
73 cornerEdges[edgei] = isCornerEdgeSharp
94 const label patchi = fap.index();
95 const auto& edgeFaces = fap.edgeFaces();
96 const label internalEdgei = fap.start();
98 const auto& faceCentresp = faceCentres.
boundaryField()[patchi];
99 const auto& faceNormalsp = faceNormals.
boundaryField()[patchi];
101 forAll(faceNormalsp, bndEdgei)
103 const label faceO = edgeFaces[bndEdgei];
104 const label meshEdgei = internalEdgei + bndEdgei;
106 cornerEdges[meshEdgei] = isCornerEdgeSharp
109 faceCentresp[bndEdgei],
111 faceNormalsp[bndEdgei]
121bool FriedrichModel::isCornerEdgeSharp
123 const vector& faceCentreO,
124 const vector& faceCentreN,
125 const vector& faceNormalO,
130 const vector relativePosition(faceCentreN - faceCentreO);
133 const vector relativeNormal(faceNormalN - faceNormalO);
136 return ((relativeNormal & relativePosition) < -1
e-8);
140scalarList FriedrichModel::calcCornerAngles()
const
152 if (!cornerEdges_[edgei])
continue;
154 const label faceO = own[edgei];
155 const label faceN = nbr[edgei];
157 cornerAngles[edgei] = calcCornerAngle
175 const label patchi = fap.index();
176 const auto& edgeFaces = fap.edgeFaces();
177 const label internalEdgei = fap.start();
179 const auto& faceNormalsp = faceNormals.
boundaryField()[patchi];
181 forAll(faceNormalsp, bndEdgei)
183 const label faceO = edgeFaces[bndEdgei];
184 const label meshEdgei = internalEdgei + bndEdgei;
186 if (!cornerEdges_[meshEdgei])
continue;
188 cornerAngles[meshEdgei] = calcCornerAngle
191 faceNormalsp[bndEdgei]
201scalar FriedrichModel::calcCornerAngle
203 const vector& faceNormalO,
207 const scalar magFaceNormal =
mag(faceNormalO)*
mag(faceNormalN);
210 if (magFaceNormal < SMALL)
return 0;
212 scalar cosAngle = (faceNormalO & faceNormalN)/magFaceNormal;
213 cosAngle =
clamp(cosAngle, -1, 1);
215 return std::acos(cosAngle);
219bitSet FriedrichModel::calcSeparationFaces()
const
221 bitSet separationFaces(
mesh().faces().size(),
false);
231 if (!cornerEdges_[edgei])
continue;
233 const label faceO = own[edgei];
234 const label faceN = nbr[edgei];
256 const label patchi = fap.index();
257 const auto& edgeFaces = fap.edgeFaces();
258 const label internalEdgei = fap.start();
260 const auto& phisp =
phis.boundaryField()[patchi];
264 const label faceO = edgeFaces[bndEdgei];
265 const label meshEdgei(internalEdgei + bndEdgei);
267 if (!cornerEdges_[meshEdgei])
continue;
279 return separationFaces;
283void FriedrichModel::isSeparationFace
286 const scalar phiEdge,
291 const scalar tol = 1
e-8;
296 separationFaces[faceO] =
true;
298 else if ((phiEdge < -tol) && (faceN != -1))
300 separationFaces[faceN] =
true;
305scalarList FriedrichModel::calcSeparationAngles
307 const bitSet& separationFaces
318 if (!cornerEdges_[edgei])
continue;
320 const label faceO = own[edgei];
321 const label faceN = nbr[edgei];
323 if (separationFaces[faceO])
325 separationAngles[faceO] = cornerAngles_[edgei];
328 if (separationFaces[faceN])
330 separationAngles[faceN] = cornerAngles_[edgei];
346 const label patchi = fap.index();
347 const auto& edgeFaces = fap.edgeFaces();
348 const label internalEdgei = fap.start();
350 const auto& phisp =
phis.boundaryField()[patchi];
354 const label faceO = edgeFaces[bndEdgei];
355 const label meshEdgei(internalEdgei + bndEdgei);
357 if (!cornerEdges_[meshEdgei])
continue;
359 if (separationFaces[faceO])
361 separationAngles[faceO] = cornerAngles_[meshEdgei];
367 return separationAngles;
381 const bitSet separationFaces(calcSeparationFaces());
384 const scalarList separationAngles(calcSeparationAngles(separationFaces));
388 auto& Fratio = tFratio.ref();
391 forAll(separationFaces, i)
394 if (!separationFaces[i])
continue;
397 const scalar sinAngle = std::sin(separationAngles[i]);
398 const scalar cosAngle = std::cos(separationAngles[i]);
413 sigma[i]*(sinAngle + 1.0) +
rho[i]*magG_*
h[i]*Lb*cosAngle;
433 const label patchi = fap.index();
434 const label internalEdgei = fap.start();
436 const auto& hp =
h.boundaryField()[patchi];
437 const auto& Ufp =
Uf.boundaryField()[patchi];
439 const auto& rhop =
rho.boundaryField()[patchi];
440 const auto& sigmap =
sigma.boundaryField()[patchi];
441 const auto& mup =
mu.boundaryField()[patchi];
446 if (!separationFaces[i])
continue;
448 const label meshEdgei = internalEdgei + i;
451 const scalar sinAngle = std::sin(cornerAngles_[meshEdgei]);
452 const scalar cosAngle = std::cos(cornerAngles_[meshEdgei]);
455 const scalar
Re = hp[i]*
mag(Ufp[i])*rhop[i]/mup[i];
458 const vector Urelp(Upp[i] - Ufp[i]);
459 const scalar We = hp[i]*rhop_*
sqr(
mag(Urelp))/(2.0*sigmap[i]);
468 sigmap[i]*(sinAngle + 1.0)
469 + rhop[i]*magG_*hp[i]*Lb*cosAngle;
474 Fratio[i] = rhop[i]*
sqr(
mag(Ufp[i]))*hp[i]*sinAngle/den;
495 separationTypeNames.getOrDefault
502 rhop_(
dict.getScalar(
"rhop")),
503 magG_(
mag(film.
g().value())),
504 C0_(
dict.getOrDefault<scalar>(
"C0", 0.882)),
505 C1_(
dict.getOrDefault<scalar>(
"C1", -1.908)),
506 C2_(
dict.getOrDefault<scalar>(
"C2", 1.264)),
507 cornerEdges_(calcCornerEdges()),
508 cornerAngles_(calcCornerAngles())
513 <<
"Primary-phase density, rhop: " << rhop_ <<
" must be non-zero."
517 if (
mag(C2_) < VSMALL)
520 <<
"Empirical constant, C2 = " << C2_ <<
"cannot be zero."
531 const auto& Fratio = tFratio.
cref();
535 auto& separated = tseparated.ref();
540 case separationType::FULL:
551 case separationType::PARTIAL:
558 separated[i] = C0_ + C1_*
Foam::exp(-Fratio[i]/C2_);
567 if (debug &&
mesh().time().writeTime())
572 mesh().newIOobject(
"Fratio"),
576 areaFratio.primitiveFieldRef() = Fratio;
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
const uniformDimensionedVectorField & g
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Internal::FieldType & primitiveFieldRef(const bool updateAccessTime=true)
Return a reference to the internal field values.
const Boundary & boundaryField() const noexcept
Return const-reference to the boundary field.
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
static bool & parRun() noexcept
Test if this a parallel run.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Finite area boundary mesh, which is a faPatch list with registered IO, a reference to the associated ...
const labelList & edgeNeighbour() const noexcept
Edge neighbour addressing.
const faBoundaryMesh & boundary() const noexcept
Return constant reference to boundary mesh.
const labelList & edgeOwner() const noexcept
Edge owner addressing.
const areaVectorField & faceAreaNormals() const
Return face area normals.
const areaVectorField & areaCentres() const
Return face centres as areaVectorField.
Finite area patch class. Used for 2-D non-Euclidian finite area method.
A base class for filmSeparation models.
const regionModels::areaSurfaceFilmModels::liquidFilmBase & film() const
Return const access to the film properties.
const faMesh & mesh() const noexcept
Return const access to the finite-area mesh.
filmSeparationModel(const filmSeparationModel &)=delete
No copy construct.
Computes film-separation properties from sharp edges for full separation (Friedrich et al....
virtual tmp< scalarField > separatedMassRatio() const
Calculate the mass ratio of film separation.
FriedrichModel(const regionModels::areaSurfaceFilmModels::liquidFilmBase &film, const dictionary &dict)
Construct from the base film model and dictionary.
virtual bool write(const bool writeOnProc=true) const
Write using setting from DB.
virtual const areaScalarField & sigma() const =0
Access const reference sigma.
virtual const areaScalarField & mu() const =0
Access const reference mu.
virtual const areaScalarField & rho() const =0
Access const reference rho.
const areaVectorField & Uf() const noexcept
Access const reference Uf.
const areaScalarField & h() const noexcept
Access const reference h.
const edgeScalarField & phi2s() const noexcept
Access continuity flux.
A class for managing temporary objects.
const T & cref() const
Return const reference to the object or to the contents of a (non-null) managed pointer.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
const polyBoundaryMesh & patches
autoPtr< surfaceVectorField > Uf
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Namespace for handling debugging switches.
A namespace for various filmSeparation model implementations.
dimensionedScalar exp(const dimensionedScalar &ds)
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensionSet clamp(const dimensionSet &a, const dimensionSet &range)
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
GeometricField< vector, faPatchField, areaMesh > areaVectorField
GeometricField< scalar, faePatchField, edgeMesh > edgeScalarField
dimensionedScalar sqrt(const dimensionedScalar &ds)
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
GeometricField< scalar, faPatchField, areaMesh > areaScalarField
errorManip< error > abort(error &err)
const dimensionSet dimForce
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
static constexpr const zero Zero
Global zero (0).
scalarField Re(const UList< complex > &cmplx)
Extract real component.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
UList< label > labelUList
A UList of labels.
List< scalar > scalarList
List of scalar.
dimensionedScalar sigma("sigma", dimMass/sqr(dimTime), transportProperties)
edgeScalarField phis(IOobject("phis", runTime.timeName(), aMesh.thisDb(), IOobject::NO_READ, IOobject::NO_WRITE), linearEdgeInterpolate(Us) &aMesh.Le())
#define forAll(list, i)
Loop across all elements in list.
Unit conversion functions.