77 void Foam::interfaceTrackingFvMesh::initializeData()
81 const word fsPatchName(
motion().get<word>(
"fsPatchName"));
88 <<
"Patch name " << fsPatchName <<
" not found." 92 fsPatchIndex_ =
patch.index();
96 if (!pointNormalsCorrectionPatches_.empty())
100 for (
const word& patchName : pointNormalsCorrectionPatches_)
107 <<
"Patch name '" << patchName
108 <<
"' for point normals correction does not exist" 117 if (!normalMotionDir_)
127 "nonReflectingFreeSurfacePatches",
128 nonReflectingFreeSurfacePatches_
133 void Foam::interfaceTrackingFvMesh::makeUs()
const 136 <<
"making free-surface velocity field" <<
nl;
141 <<
"free-surface velocity field already exists" 156 == wedgeFaPatch::typeName
159 patchFieldTypes[patchI] =
160 wedgeFaPatchVectorField::typeName;
164 label ngbPolyPatchID =
165 aMesh().boundary()[patchI].ngbPolyPatchIndex();
167 if (ngbPolyPatchID != -1)
172 == wallFvPatch::typeName
175 patchFieldTypes[patchI] =
176 slipFaPatchVectorField::typeName;
182 for (
const word& patchName : fixedFreeSurfacePatches_)
184 const label fixedPatchID =
185 aMesh().boundary().findPatchID(patchName);
187 if (fixedPatchID == -1)
190 <<
"Wrong faPatch name '" << patchName
191 <<
"' in the fixedFreeSurfacePatches list" 192 <<
" defined in the dynamicMeshDict dictionary" 196 label ngbPolyPatchID =
197 aMesh().boundary()[fixedPatchID].ngbPolyPatchIndex();
199 if (ngbPolyPatchID != -1)
204 == wallFvPatch::typeName
207 patchFieldTypes[fixedPatchID] =
208 fixedValueFaPatchVectorField::typeName;
228 for (
const word& patchName : fixedFreeSurfacePatches_)
230 const label fixedPatchID = aMesh().boundary().findPatchID(patchName);
232 if (fixedPatchID == -1)
235 <<
"Wrong faPatch name '" << patchName
236 <<
"' in the fixedFreeSurfacePatches list" 237 <<
" defined in the dynamicMeshDict dictionary" 241 label ngbPolyPatchID =
242 aMesh().boundary()[fixedPatchID].ngbPolyPatchIndex();
244 if (ngbPolyPatchID != -1)
249 == wallFvPatch::typeName
252 UsPtr_->boundaryFieldRef()[fixedPatchID] ==
Zero;
259 void Foam::interfaceTrackingFvMesh::makeFsNetPhi()
const 262 <<
"making free-surface net flux" <<
nl;
267 <<
"free-surface net flux already exists" 287 void Foam::interfaceTrackingFvMesh::makeControlPoints()
290 <<
"making control points" <<
nl;
292 if (controlPointsPtr_)
295 <<
"control points already exists" 311 Info<<
"Reading control points" <<
endl;
318 Info<<
"Creating new control points" <<
endl;
322 aMesh().areaCentres().internalField()
325 initializeControlPointsPosition();
330 void Foam::interfaceTrackingFvMesh::makeMotionPointsMask()
333 <<
"making motion points mask" <<
nl;
335 if (motionPointsMaskPtr_)
338 <<
"motion points mask already exists" 355 == processorFaPatch::typeName
359 aMesh().boundary()[patchI].pointLabels();
361 forAll(patchPoints, pointI)
363 motionPointsMask()[patchPoints[pointI]] = -1;
369 for (
const word& patchName : fixedFreeSurfacePatches_)
371 const label fixedPatchID = aMesh().boundary().findPatchID(patchName);
373 if (fixedPatchID == -1)
376 <<
"Wrong faPatch name in the fixedFreeSurfacePatches list" 377 <<
" defined in the dynamicMeshDict dictionary" 382 aMesh().boundary()[fixedPatchID].pointLabels();
384 forAll(patchPoints, pointI)
386 motionPointsMask()[patchPoints[pointI]] = 0;
392 void Foam::interfaceTrackingFvMesh::makeDirections()
395 <<
"make displacement directions for points and control points" <<
nl;
397 if (pointsDisplacementDirPtr_ || facesDisplacementDirPtr_)
400 <<
"points, control points displacement directions already exist" 404 pointsDisplacementDirPtr_ =
411 facesDisplacementDirPtr_ =
418 if (!normalMotionDir())
420 if (
mag(motionDir_) < SMALL)
423 <<
"Zero motion direction" 427 facesDisplacementDir() = motionDir_;
428 pointsDisplacementDir() = motionDir_;
431 updateDisplacementDirections();
435 void Foam::interfaceTrackingFvMesh::makePhis()
438 <<
"making free-surface flux" <<
nl;
443 <<
"free-surface flux already exists" 462 void Foam::interfaceTrackingFvMesh::makeSurfactConc()
const 465 <<
"making free-surface surfactant concentration field" <<
nl;
470 <<
"free-surface surfactant concentration field already exists" 493 void Foam::interfaceTrackingFvMesh::makeBulkSurfactConc()
const 496 <<
"making volume surfactant concentration field" <<
nl;
498 if (bulkSurfactConcPtr_)
501 <<
"volume surfactant concentration field already exists" 526 bulkSurfactConc = surfactant().bulkConc();
532 void Foam::interfaceTrackingFvMesh::makeSurfaceTension()
const 535 <<
"making surface tension field" <<
nl;
537 if (surfaceTensionPtr_)
540 <<
"surface tension field already exists" 554 sigma() + surfactant().dSigma(surfactantConcentration())/rho_
559 void Foam::interfaceTrackingFvMesh::makeSurfactant()
const 562 <<
"making surfactant properties" <<
nl;
567 <<
"surfactant properties already exists" 572 motion().
subDict(
"surfactantProperties");
578 void Foam::interfaceTrackingFvMesh::makeContactAngle()
581 <<
"making contact angle field" <<
nl;
583 if (contactAnglePtr_)
586 <<
"contact angle already exists" 602 Info<<
"Reading contact angle field" <<
endl;
609 void Foam::interfaceTrackingFvMesh::updateDisplacementDirections()
611 if (normalMotionDir())
614 pointsDisplacementDir() = aMesh().pointAreaNormals();
619 if (contactAnglePtr_)
621 label ngbPolyPatchID =
622 aMesh().boundary()[patchI].ngbPolyPatchIndex();
624 if (ngbPolyPatchID != -1)
629 == wallFvPatch::typeName
633 aMesh().boundary()[patchI].pointLabels();
638 .ngbPolyPatchPointNormals()
641 forAll(patchPoints, pointI)
643 pointsDisplacementDir()[patchPoints[pointI]] -=
647 & pointsDisplacementDir()[patchPoints[pointI]]
650 pointsDisplacementDir()[patchPoints[pointI]] /=
653 pointsDisplacementDir()
665 facesDisplacementDir() =
666 aMesh().faceAreaNormals().internalField();
669 const vectorField& Cf = aMesh().areaCentres().internalField();
672 facesDisplacementDir()
673 *(facesDisplacementDir()&(controlPoints() - Cf))
679 void Foam::interfaceTrackingFvMesh::initializeControlPointsPosition()
682 const faceList& faces = aMesh().faces();
687 correctPointDisplacement(sweptVolCorr, displacement);
695 sweptVol[faceI] = -faces[faceI].sweptVol(
points, newPoints);
702 faceArea[faceI] = faces[faceI].unitNormal(newPoints);
709 deltaH[faceI] = sweptVol[faceI]/
710 ((faceArea[faceI] & facesDisplacementDir()[faceI]) + SMALL);
712 if (
mag(faceArea[faceI] & facesDisplacementDir()[faceI]) < SMALL)
719 <<
"Something is wrong with specified motion direction" 724 for (
const word& patchName : fixedFreeSurfacePatches_)
726 label fixedPatchID = aMesh().boundary().findPatchID(patchName);
728 if (fixedPatchID == -1)
731 <<
"Wrong faPatch name in the fixedFreeSurfacePatches list" 732 <<
" defined in the freeSurfaceProperties dictionary" 737 aMesh().boundary()[fixedPatchID].edgeFaces();
741 deltaH[eFaces[edgeI]] *= 2.0;
745 controlPoints() += facesDisplacementDir()*deltaH;
750 void Foam::interfaceTrackingFvMesh::smoothFreeSurfaceMesh()
752 Info<<
"Smoothing free surface mesh" <<
endl;
754 controlPoints() = aMesh().areaCentres().internalField();
758 const faceList& faces = aMesh().faces();
766 sweptVol[faceI] = -faces[faceI].sweptVol(
points, newPoints);
772 faceArea[faceI] = faces[faceI].unitNormal(newPoints);
777 sweptVol/(faceArea & facesDisplacementDir())
780 for (
const word& patchName : fixedFreeSurfacePatches_)
782 label fixedPatchID = aMesh().boundary().findPatchID(patchName);
784 if (fixedPatchID == -1)
787 <<
"Wrong faPatch name fixedFreeSurfacePatches list" 788 <<
" defined in the dynamicMeshDict dictionary" 793 aMesh().boundary()[fixedPatchID].edgeFaces();
797 deltaHf[eFaces[edgeI]] *= 2.0;
801 controlPoints() += facesDisplacementDir()*deltaHf;
803 displacement = pointDisplacement();
806 refCast<velocityMotionSolver>
814 fixedValuePointPatchVectorField& fsPatchPointMeshU =
815 refCast<fixedValuePointPatchVectorField>
829 void Foam::interfaceTrackingFvMesh::updateSurfaceFlux()
835 void Foam::interfaceTrackingFvMesh::updateSurfactantConcentration()
837 if (!pureFreeSurface())
847 +
fam::div(Phis(), surfactantConcentration())
850 surfactant().diffusion(),
851 surfactantConcentration()
855 if (surfactant().soluble())
875 bulkSurfactantConcentration().boundaryField()[fsPatchIndex()];
876 Cb.correctBoundaryConditions();
881 surfactant().adsorptionCoeff()*
Cb 882 + surfactant().adsorptionCoeff()
883 *surfactant().desorptionCoeff(),
884 surfactantConcentration()
886 - surfactant().adsorptionCoeff()
887 *
Cb*surfactant().saturatedConc();
895 sigma() + surfactant().dSigma(surfactantConcentration())/rho_;
897 if (
neg(
min(surfaceTension().internalField().
field())))
900 <<
"Surface tension is negative" 907 Foam::vector Foam::interfaceTrackingFvMesh::totalPressureForce()
const 911 const vectorField&
n = aMesh().faceAreaNormals().internalField();
917 return gSum(pressureForces);
921 Foam::vector Foam::interfaceTrackingFvMesh::totalViscousForce()
const 937 const vectorField&
n = aMesh().faceAreaNormals().internalField();
941 U().boundaryField()[fsPatchIndex()].
snGrad()
954 return gSum(viscousForces);
958 Foam::vector Foam::interfaceTrackingFvMesh::totalSurfaceTensionForce()
const 962 const vectorField&
n = aMesh().faceAreaNormals().internalField();
964 const scalarField&
K = aMesh().faceCurvatures().internalField();
968 if (pureFreeSurface())
974 aMesh().Le()*aMesh().edgeLengthCorrection()
979 surfTensionForces = surfaceTension().internalField().field()*
K*S*
n;
982 return gSum(surfTensionForces);
986 Foam::scalar Foam::interfaceTrackingFvMesh::maxCourantNumber()
990 if (pureFreeSurface())
996 mesh().time().deltaTValue()/
1015 mesh().time().deltaTValue()/
1027 void Foam::interfaceTrackingFvMesh::updateProperties()
1032 "transportProperties" 1041 void Foam::interfaceTrackingFvMesh::correctPointDisplacement
1048 aMesh().patch().pointFaces();
1051 aMesh().patch().localFaces();
1054 aMesh().patch().localPoints();
1056 for (
const word& patchName : fixedFreeSurfacePatches_)
1058 label fixedPatchID = aMesh().boundary().findPatchID(patchName);
1061 aMesh().boundary()[fixedPatchID].pointLabels();
1064 aMesh().boundary()[fixedPatchID].edgeFaces();
1070 label curFace = eFaces[edgeI];
1072 const labelList& curPoints = faces[curFace];
1074 forAll(curPoints, pointI)
1076 label curPoint = curPoints[pointI];
1077 label index = pLabels.
find(curPoint);
1090 forAll(corrPoints, pointI)
1092 label curPoint = corrPoints[pointI];
1098 label curFace =
pFaces[curPoint][faceI];
1100 label index = eFaces.
find(curFace);
1111 forAll(corrPoints, pointI)
1113 label curPoint = corrPoints[pointI];
1117 const labelList& curPointFaces = corrPointFaces[pointI];
1119 forAll(curPointFaces, faceI)
1121 const face& curFace = faces[curPointFaces[faceI]];
1123 label ptInFace = curFace.
which(curPoint);
1124 label next = curFace.
nextLabel(ptInFace);
1125 label prev = curFace.
prevLabel(ptInFace);
1129 const vector&
c = pointsDisplacementDir()[curPoint];
1131 curDisp += 2*sweptVolCorr[curPointFaces[faceI]]/((a^
b)&
c);
1134 curDisp /= curPointFaces.
size();
1136 displacement[curPoint] =
1137 curDisp*pointsDisplacementDir()[curPoint];
1142 for (
const word& patchName : nonReflectingFreeSurfacePatches_)
1144 label nonReflectingPatchID =
1145 aMesh().boundary().findPatchID(patchName);
1148 aMesh().boundary()[nonReflectingPatchID].pointLabels();
1151 aMesh().boundary()[nonReflectingPatchID].edgeFaces();
1157 forAll(corrPoints, pointI)
1159 label curPoint = corrPoints[pointI];
1165 label curFace =
pFaces[curPoint][faceI];
1167 label index = eFaces.
find(curFace);
1179 forAll(corrPoints, pointI)
1181 label curPoint = corrPoints[pointI];
1185 const labelList& curPointFaces = corrPointFaces[pointI];
1187 forAll(curPointFaces, faceI)
1189 const face& curFace = faces[curPointFaces[faceI]];
1191 label ptInFace = curFace.
which(curPoint);
1192 label next = curFace.
nextLabel(ptInFace);
1193 label prev = curFace.
prevLabel(ptInFace);
1199 if (corrPoints.
find(next) == -1)
1214 vector c0 = displacement[p1];
1216 scalar V0 =
mag((
a0^b0)&c0)/2;
1218 scalar DV = sweptVolCorr[curPointFaces[faceI]] - V0;
1220 if (corrPoints.
find(prev) != -1)
1224 (
points[next] + displacement[next])
1226 const vector&
c = pointsDisplacementDir()[curPoint];
1228 curDisp += 2*DV/((a^
b)&
c);
1233 - (
points[prev] + displacement[prev]);
1235 const vector&
c = pointsDisplacementDir()[curPoint];
1237 curDisp += 2*DV/((a^
b)&
c);
1241 curDisp /= curPointFaces.size();
1243 displacement[curPoint] =
1244 curDisp*pointsDisplacementDir()[curPoint];
1250 void Foam::interfaceTrackingFvMesh::correctContactLinePointNormals()
1258 aMesh().pointAreaNormals()
1261 if (contactAnglePtr_ && correctContactLineNormals())
1263 Info<<
"Correcting contact line normals" <<
endl;
1267 const labelList& meshPoints = aMesh().patch().meshPoints();
1292 const labelListList& edgeFaces = aMesh().patch().edgeFaces();
1293 const labelListList& pointEdges = aMesh().patch().pointEdges();
1294 const labelListList& pointFaces = aMesh().patch().pointFaces();
1295 const edgeList& edges = aMesh().edges();
1302 == processorFaPatch::typeName
1306 refCast<const processorFaPatch>
1308 aMesh().boundary()[patchI]
1314 forAll(patchPointLabels, pointI)
1316 label curPoint = patchPointLabels[pointI];
1323 const labelList& curPointEdges = pointEdges[curPoint];
1325 forAll(curPointEdges, edgeI)
1327 label curEdge = curPointEdges[edgeI];
1329 if (edgeFaces[curEdge].size() == 1)
1334 aMesh().boundary()[pI];
1336 label index = curEdges.
find(curEdge);
1343 != processorFaPatch::typeName
1360 vector t = edges[curEdge].vec(oldPoints);
1361 t /=
mag(t) + SMALL;
1364 pointFaces[curPoint];
1366 forAll(curPointFaces, fI)
1368 tangent.ref().field()[curPointFaces[fI]] = t;
1375 tangent.correctBoundaryConditions();
1380 label ngbPolyPatchID =
1381 aMesh().boundary()[patchI].ngbPolyPatchIndex();
1383 if (ngbPolyPatchID != -1)
1388 == wallFvPatch::typeName
1396 - contactAnglePtr_->boundaryField()[patchI]
1402 aMesh().
boundary()[patchI].ngbPolyPatchPointNormals()
1406 aMesh().boundary()[patchI].pointLabels();
1411 rotationAxis /=
mag(rotationAxis) + SMALL;
1416 const edgeList& edges = aMesh().edges();
1419 aMesh().boundary()[patchI].pointEdges();
1421 forAll(pointEdges, pointI)
1425 forAll(pointEdges[pointI], eI)
1428 aMesh().boundary()[patchI].start()
1429 + pointEdges[pointI][eI];
1431 vector e = edges[curEdge].vec(oldPoints);
1433 e *= (
e&rotationAxis[pointI])
1434 /
mag(
e&rotationAxis[pointI]);
1436 e /=
mag(
e) + SMALL;
1441 if (pointEdges[pointI].size() == 1)
1443 label curPoint = patchPoints[pointI];
1446 aMesh().patch().pointEdges();
1450 label procPatchID = -1;
1454 aMesh().patch().edgeFaces();
1456 forAll(curPointEdges, edgeI)
1458 label curEdge = curPointEdges[edgeI];
1460 if (edgeFaces[curEdge].size() == 1)
1465 aMesh().boundary()[pI];
1468 curEdges.
find(curEdge);
1475 == processorFaPatch::typeName
1487 if (procPatchID != -1)
1490 tangent.boundaryField()[procPatchID]
1491 .patchNeighbourField()()[
edgeID];
1493 t *= (t&rotationAxis[pointI])
1494 /(
mag(t&rotationAxis[pointI]) + SMALL);
1496 t /=
mag(t) + SMALL;
1502 rotationAxis[pointI] = rotAx/(
mag(rotAx) + SMALL);
1506 ngbN = ngbN*
cos(rotAngle)
1507 + rotationAxis*(rotationAxis & ngbN)*(1 -
cos(rotAngle))
1508 + (rotationAxis^ngbN)*
sin(rotAngle);
1511 forAll(patchPoints, pointI)
1513 N[patchPoints[pointI]] -=
1514 ngbN[pointI]*(ngbN[pointI]&
N[patchPoints[pointI]]);
1516 N[patchPoints[pointI]] /=
1517 mag(
N[patchPoints[pointI]]) + SMALL;
1530 Foam::interfaceTrackingFvMesh::interfaceTrackingFvMesh
1539 fixedFreeSurfacePatches_(),
1540 nonReflectingFreeSurfacePatches_(),
1541 pointNormalsCorrectionPatches_(),
1542 normalMotionDir_(false),
1545 pureFreeSurface_(true),
1546 rigidFreeSurface_(false),
1547 correctContactLineNormals_(false),
1552 controlPointsPtr_(nullptr),
1553 motionPointsMaskPtr_(nullptr),
1554 pointsDisplacementDirPtr_(nullptr),
1555 facesDisplacementDirPtr_(nullptr),
1556 fsNetPhiPtr_(nullptr),
1558 surfactConcPtr_(nullptr),
1559 bulkSurfactConcPtr_(nullptr),
1560 surfaceTensionPtr_(nullptr),
1561 surfactantPtr_(nullptr),
1562 contactAnglePtr_(nullptr)
1645 aMeshPtr_.reset(
new faMesh(*
this));
1648 fixedFreeSurfacePatches_ =
1649 motion().get<
wordList>(
"fixedFreeSurfacePatches");
1651 pointNormalsCorrectionPatches_ =
1652 motion().
get<
wordList>(
"pointNormalsCorrectionPatches");
1654 normalMotionDir_ = motion().
get<
bool>(
"normalMotionDir");
1655 smoothing_ = motion().getOrDefault(
"smoothing",
false);
1656 pureFreeSurface_ = motion().getOrDefault(
"pureFreeSurface",
true);
1693 return *fsNetPhiPtr_;
1704 return *fsNetPhiPtr_;
1710 forAll(
Us().boundaryField(), patchI)
1714 Us().boundaryField()[patchI].
type()
1715 == calculatedFaPatchVectorField::typeName
1720 pUs =
Us().boundaryField()[patchI].patchInternalField();
1722 label ngbPolyPatchID =
1723 aMesh().boundary()[patchI].ngbPolyPatchIndex();
1725 if (ngbPolyPatchID != -1)
1730 U().boundaryField()[ngbPolyPatchID].
type()
1731 == slipFvPatchVectorField::typeName
1735 U().boundaryField()[ngbPolyPatchID].
type()
1736 == symmetryFvPatchVectorField::typeName
1742 aMesh().
boundary()[patchI].ngbPolyPatchFaceNormals()
1751 Us().correctBoundaryConditions();
1759 Us().ref().field() =
U().boundaryField()[fsPatchIndex()];
1767 correctUsBoundaryConditions();
1773 return *getObjectPtr<const volVectorField>(
"U");
1779 return *getObjectPtr<const volScalarField>(
"p");
1785 return *getObjectPtr<const surfaceScalarField>(
"phi");
1793 auto& SnGradU = tSnGradU.ref();
1795 const vectorField& nA = aMesh().faceAreaNormals().internalField();
1800 - aMesh().faceCurvatures()*(aMesh().faceAreaNormals()&
Us())
1807 gradUs -=
n*(
n & gradUs);
1808 gradUs.correctBoundaryConditions();
1817 if (!pureFreeSurface() &&
max(
nu) > SMALL)
1819 tangentialSurfaceTensionForce =
1820 surfaceTensionGrad()().internalField();
1824 tangentialSurfaceTensionForce/(
nu + SMALL)
1825 - nA*divUs.internalField()
1826 - (gradUs.internalField()&nA);
1836 auto& SnGradUn = tSnGradUn.ref();
1841 - aMesh().faceCurvatures()*(aMesh().faceAreaNormals()&
Us())
1854 auto& pressureJump = tPressureJump.ref();
1856 const scalarField&
K = aMesh().faceCurvatures().internalField();
1868 + 2.0*
nu*freeSurfaceSnGradUn();
1870 if (pureFreeSurface())
1876 pressureJump -= surfaceTension().internalField()*
K;
1879 return tPressureJump;
1885 if (!controlPointsPtr_)
1887 makeControlPoints();
1890 return *controlPointsPtr_;
1896 if (!motionPointsMaskPtr_)
1898 makeMotionPointsMask();
1901 return *motionPointsMaskPtr_;
1907 if (!pointsDisplacementDirPtr_)
1912 return *pointsDisplacementDirPtr_;
1918 if (!facesDisplacementDirPtr_)
1923 return *facesDisplacementDirPtr_;
1940 if (!surfactConcPtr_)
1945 return *surfactConcPtr_;
1952 if (!surfactConcPtr_)
1957 return *surfactConcPtr_;
1964 if (!bulkSurfactConcPtr_)
1966 makeBulkSurfactConc();
1969 return *bulkSurfactConcPtr_;
1976 if (!bulkSurfactConcPtr_)
1978 makeBulkSurfactConc();
1981 return *bulkSurfactConcPtr_;
1988 if (!surfaceTensionPtr_)
1990 makeSurfaceTension();
1993 return *surfaceTensionPtr_;
2000 if (!surfaceTensionPtr_)
2002 makeSurfaceTension();
2005 return *surfaceTensionPtr_;
2012 if (!surfactantPtr_)
2017 return *surfactantPtr_;
2028 "surfaceTensionGrad",
2040 auto&
grad = tgrad.ref();
2045 grad.correctBoundaryConditions();
2055 if (smoothing_ && !rigidFreeSurface_)
2057 smoothFreeSurfaceMesh();
2058 clearControlPoints();
2061 updateDisplacementDirections();
2065 Info<<
"Maximal capillary Courant number: " 2066 << maxCourantNumber() <<
endl;
2068 const scalarField&
K = aMesh().faceCurvatures().internalField();
2070 Info<<
"Free surface curvature: min = " <<
gMin(
K)
2076 if (!rigidFreeSurface_)
2080 phi().boundaryField()[fsPatchIndex()];
2092 Info<<
"Free surface continuity error : sum local = " 2093 <<
gSum(
mag(sweptVolCorr)) <<
", global = " <<
gSum(sweptVolCorr)
2097 fsNetPhi().ref().field() = sweptVolCorr;
2103 "ddt(" +
U().
name() +
')' 2141 <<
"Unsupported temporal differencing scheme : " 2147 const vectorField& Nf = aMesh().faceAreaNormals().internalField();
2151 sweptVolCorr/(Sf*(Nf & facesDisplacementDir()))
2154 for (
const word& patchName : fixedFreeSurfacePatches_)
2156 label fixedPatchID =
2157 aMesh().boundary().findPatchID(patchName);
2159 if (fixedPatchID == -1)
2162 <<
"Wrong faPatch name '" << patchName
2163 <<
"'in the fixedFreeSurfacePatches list" 2164 <<
" defined in dynamicMeshDict dictionary" 2169 aMesh().boundary()[fixedPatchID].edgeFaces();
2173 deltaHf[eFaces[edgeI]] *= 2.0;
2177 controlPoints() += facesDisplacementDir()*deltaHf;
2179 pointField displacement(pointDisplacement());
2180 correctPointDisplacement(sweptVolCorr, displacement);
2183 refCast<velocityMotionSolver>
2191 fixedValuePointPatchVectorField& fsPatchPointMeshU =
2192 refCast<fixedValuePointPatchVectorField>
2204 correctContactLinePointNormals();
2215 refCast<velocityMotionSolver>
2223 fixedValuePointPatchVectorField& fsPatchPointMeshU =
2224 refCast<fixedValuePointPatchVectorField>
2239 updateSurfactantConcentration();
2251 mesh().time().timePath()/
"freeSurface",
2263 mesh().time().timePath()/
"freeSurfaceControlPoints.vtk" 2266 Info<<
"Writing free surface control points to " <<
os.
name() <<
nl;
2268 os <<
"# vtk DataFile Version 2.0" <<
nl 2269 <<
"freeSurfaceControlPoints" <<
nl 2271 <<
"DATASET POLYDATA" <<
nl;
2273 const label
nPoints = controlPoints().size();
2276 for (
const point&
p : controlPoints())
2278 os << float(
p.x()) <<
' ' 2279 <<
float(
p.y()) <<
' ' 2280 <<
float(
p.z()) <<
nl;
2284 for (label
id = 0;
id <
nPoints; ++id)
2286 os << 1 <<
' ' <<
id <<
nl;
edgeScalarField & Phis()
Return free-surface fluid flux field.
virtual bool init(const bool doInit)
Initialise all non-demand-driven data.
Finite area mesh (used for 2-D non-Euclidian finite area method) defined using a patch of faces on a ...
Write concrete PrimitivePatch faces/points (optionally with fields) as a vtp file or a legacy vtk fil...
tmp< fvMatrix< Type > > correction(const fvMatrix< Type > &)
Return the correction form of the given matrix by subtracting the matrix multiplied by the current fi...
const Type & value() const noexcept
Return const reference to value.
Second-oder Crank-Nicolson implicit ddt using the current and previous time-step fields as well as th...
void size(const label n)
Older name for setAddressableSize.
const Type & lookupObject(const word &name, const bool recursive=false) const
Lookup and return const reference to the object of the given Type. Fatal if not found or the wrong ty...
vectorField & facesDisplacementDir()
Return reference to control points displacement direction field.
scalar deltaTValue() const noexcept
Return time step value.
A face is a list of labels corresponding to mesh vertices.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
CGAL::indexedCell< K > Cb
vtk::lineWriter writer(edgeCentres, edgeList::null(), fileName(aMesh.time().globalPath()/"finiteArea-edgesCentres"))
const areaScalarField & fsNetPhi() const
Return free-surface net flux.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const surfaceVectorField & Cf() const
Return face centres as surfaceVectorField.
Type gMin(const FieldField< Field, Type > &f)
virtual const fileName & name() const override
Read/write access to the name of the stream.
Virtual base class for velocity motion solver.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
static tmp< GeometricField< Type, faePatchField, edgeMesh > > interpolate(const GeometricField< Type, faPatchField, areaMesh > &tvf, const edgeScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
Unit conversion functions.
const Internal & internalField() const noexcept
Return a const-reference to the dimensioned internal field.
Output to file stream as an OSstream, normally using std::ofstream for the actual output...
tmp< scalarField > freeSurfacePressureJump()
Return free surface pressure jump.
constexpr char nl
The newline '\n' character (0x0a)
vectorField & pointsDisplacementDir()
Return reference to point displacement direction field.
tmp< GeometricField< Type, faPatchField, areaMesh > > div(const GeometricField< Type, faePatchField, edgeMesh > &ssf)
virtual bool update()
Update the mesh for both mesh motion and topology change.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface...
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
void updateUs()
Update free-surface velocity field.
const labelList & pointLabels() const
Return patch point labels.
static bool & parRun() noexcept
Test if this a parallel run.
An indexed form of CGAL::Triangulation_cell_base_3<K> used to keep track of the Delaunay cells (tets)...
label nextLabel(const label i) const
Next vertex on face.
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type get(const label i) const
Return bool value at specified position, always false for out-of-range access.
const volVectorField & U() const
Return constant reference to velocity field.
Virtual base class for mesh motion solver.
void correctUsBoundaryConditions()
Correct surface velocity boundary conditions.
Ignore writing from objectRegistry::writeObject()
quaternion normalised(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
const dimensionSet dimless
Dimensionless.
const Time & time() const
Return the top-level database.
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
CGAL::Exact_predicates_exact_constructions_kernel K
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Abstract base class for turbulence models (RAS, LES and laminar).
dimensionedScalar sigma("sigma", dimMass/sqr(dimTime), transportProperties)
faMesh & aMesh()
Return reference to finite area mesh.
dimensionedScalar neg(const dimensionedScalar &ds)
static const word & zeroGradientType() noexcept
The type name for zeroGradient patch fields.
Macros for easy insertion into run-time selection tables.
#define forAll(list, i)
Loop across all elements in list.
tmp< faMatrix< Type > > laplacian(const GeometricField< Type, faPatchField, areaMesh > &vf)
label prevLabel(const label i) const
Previous vertex on face.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
volScalarField & bulkSurfactantConcentration()
Return volume surfactant concentration field.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
const dimensionSet dimVolume(pow3(dimLength))
zeroField Sp(const Foam::zero, const GeometricField< Type, faPatchField, areaMesh > &)
A no-op source.
virtual bool init(const bool doInit)
Initialise all non-demand-driven data.
label findPatchID(const word &patchName, const bool allowNotFound=true) const
Find patch index given a name, return -1 if not found.
tmp< GeometricField< Type, faePatchField, edgeMesh > > linearEdgeInterpolate(const GeometricField< Type, faPatchField, areaMesh > &vf)
const dimensionedScalar e
Elementary charge.
Type gSum(const FieldField< Field, Type > &f)
dimensionedScalar cos(const dimensionedScalar &ds)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
* ~interfaceTrackingFvMesh()
Destructor.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
#define DebugInFunction
Report an information message using Foam::Info.
areaVectorField & Us()
Return free-surface velocity field.
virtual const pointField & oldPoints() const
Return old points (mesh motion)
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
label which(const label vertex) const
Find local vertex on face for the vertex label, same as find()
label timeIndex() const noexcept
Return the current time index.
GeometricField< scalar, faePatchField, edgeMesh > edgeScalarField
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Second-order backward-differencing ddt using the current and two previous time-step values...
errorManip< error > abort(error &err)
vectorField & controlPoints()
Return control points.
label find(const T &val) const
Find index of the first occurrence of the value.
virtual bool update()
Update the mesh for both mesh motion and topology change.
areaScalarField & surfactantConcentration()
Return free-surface surfactant concentration field.
tmp< faMatrix< Type > > ddt(const GeometricField< Type, faPatchField, areaMesh > &vf)
const uniformDimensionedVectorField & g
dimensionedScalar sin(const dimensionedScalar &ds)
const dimensionSet dimForce
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
tmp< faMatrix< Type > > div(const edgeScalarField &flux, const GeometricField< Type, faPatchField, areaMesh > &vf, const word &name)
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...
Type gMax(const FieldField< Field, Type > &f)
OBJstream os(runTime.globalPath()/outputName)
const dimensionSet dimMoles(0, 0, 0, 0, 1, 0, 0)
Info<< "Reading field U\"<< endl;volVectorField U(IOobject("U", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE), mesh);volScalarField rho(IOobject("rho", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), thermo.rho());volVectorField rhoU(IOobject("rhoU", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE), rho *U);volScalarField rhoE(IOobject("rhoE", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE), rho *(e+0.5 *magSqr(U)));surfaceScalarField pos(IOobject("pos", runTime.timeName(), mesh), mesh, dimensionedScalar("pos", dimless, 1.0));surfaceScalarField neg(IOobject("neg", runTime.timeName(), mesh), mesh, dimensionedScalar("neg", dimless, -1.0));surfaceScalarField phi("phi", fvc::flux(rhoU));Info<< "Creating turbulence model\"<< endl;autoPtr< compressible::turbulenceModel > turbulence(compressible::turbulenceModel::New(rho, U, phi, thermo))
defineTypeNameAndDebug(combustionModel, 0)
const volScalarField & p() const
Return constant reference to pressure field.
static const gravity & New(const word &name, const Time &runTime)
Return named gravity field cached or construct on Time.
tmp< GeometricField< Type, faPatchField, areaMesh > > edgeIntegrate(const GeometricField< Type, faePatchField, edgeMesh > &ssf)
const faBoundaryMesh & boundary() const noexcept
Return constant reference to boundary mesh.
const surfaceScalarField & phi() const
Return constant reference to velocity field.
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=cellModel::ref(cellModel::HEX);labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells].reset(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< SMALL) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} label minLabel=min(start, end);pointMap[start]=pointMap[end]=minLabel;} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};const label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &oldCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< SLList< face > > pFaces[nBCs]
labelList & motionPointsMask()
Return reference to motion points mask field.
const dimensionSet dimDensity
const Vector< label > N(dict.get< Vector< label >>("N"))
Calculate the mesh motion flux and convert fluxes from absolute to relative and back.
const surfactantProperties & surfactant() const
Return surfactant properties.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Template functions to aid in the implementation of demand driven data.
Internal::FieldType & primitiveFieldRef(const bool updateAccessTime=true)
Return a reference to the internal field values.
Ostream & flush(Ostream &os)
Flush stream.
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Type gAverage(const FieldField< Field, Type > &f)
Abstract base class for geometry and/or topology changing fvMesh.
const dimensionedScalar c
Speed of light in a vacuum.
Automatically write from objectRegistry::writeObject()
void writeVTKControlPoints()
Write VTK freeSurface control points.
const dimensionedScalar a0
Bohr radius: default SI units: [m].
Template specialisation for scalar faMatrix.
const std::string patch
OpenFOAM patch number as a std::string.
const motionSolver & motion() const
Return the motionSolver.
tmp< scalarField > freeSurfaceSnGradUn()
Return free surface normal derivative of normal velocity comp.
void correctBoundaryConditions()
Correct boundary field.
Legacy ASCII, legacyAsciiFormatter.
bool correctPatchPointNormals(const label patchID) const
Whether point normals should be corrected for a patch.
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual bool writeGeometry()
Write patch topology.
Field< vector > vectorField
Specialisation of Field<T> for vector.
tmp< areaVectorField > surfaceTensionGrad()
Return surface tension gradient.
The dynamicMotionSolverFvMesh.
List< Key > toc() const
The table of contents (the keys) in unsorted order.
void writeVTK() const
Write VTK freeSurface mesh.
List< label > labelList
A List of labels.
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
A class for managing temporary objects.
tmp< vectorField > freeSurfaceSnGradU()
Return free surface normal derivative of velocity.
Basic first-order Euler implicit/explicit ddt using only the current and previous time-step values...
A simple single-phase transport model based on viscosityModel.
void deleteDemandDrivenData(DataPtr &dataPtr)
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Request registration (bool: true)
GeometricField< vector, faPatchField, areaMesh > areaVectorField
A primitive field of type <T> with automated input and output.
IOField< vector > vectorIOField
IO for a Field of vector.
const Boundary & boundaryField() const noexcept
Return const-reference to the boundary field.
const volScalarField & p0
tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > snGrad(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
const dimensionSet dimArea(sqr(dimLength))
tmp< GeometricField< typename outerProduct< vector, Type >::type, faPatchField, areaMesh >> grad(const GeometricField< Type, faePatchField, edgeMesh > &ssf)
areaScalarField & surfaceTension()
Return surface tension field.
addToRunTimeSelectionTable(functionObject, pointHistory, dictionary)
The interfaceTrackingFvMesh.
GeometricField< scalar, faPatchField, areaMesh > areaScalarField
static constexpr const zero Zero
Global zero (0)
const dimensionSet dimVelocity