45 #include "surfaceInterpolate.H"
53 template<
class FaceList,
class Po
intField>
62 p.meshPoints()[
p.edges()[edgei][0]],
63 p.meshPoints()[
p.edges()[edgei][1]]
87 const Foam::scalar Foam::fvMeshStitcher::minWarnProjectedVolumeFraction_ = 0.3;
101 void Foam::fvMeshStitcher::regionNames(
const fvMesh&
mesh,
wordHashSet& names)
109 if (!isA<nonConformalMappedWallFvPatch>(fvp))
continue;
111 const nonConformalMappedWallFvPatch& ncmwFvp =
112 refCast<const nonConformalMappedWallFvPatch>(fvp);
114 if (!names.found(ncmwFvp.nbrRegionName()))
116 regionNames(ncmwFvp.nbrMesh(), names);
134 UPtrList<fvMesh> result(names.size());
140 &mesh_.time().lookupObjectRef<fvMesh>(names[i])
152 UPtrList<const fvMesh> result(names.size());
158 &mesh_.time().lookupObject<fvMesh>(names[i])
186 bool Foam::fvMeshStitcher::loadPolyFacesBf
188 IOobject& polyFacesBfIO,
189 SurfaceFieldBoundary<label>& polyFacesBf
197 auto polyFacesBfIOIter = regionPolyFacesBfIOs_.find(mesh_.name());
198 auto polyFacesBfIter = regionPolyFacesBfs_.find(mesh_.name());
199 if (polyFacesBfIOIter != regionPolyFacesBfIOs_.end())
204 regionPolyFacesBfIOs_.remove(polyFacesBfIOIter)
209 tmp<SurfaceFieldBoundary<label>>
211 regionPolyFacesBfs_.remove(polyFacesBfIter)
221 typeIOobject<surfaceLabelField> io
223 fvMeshStitcher::polyFacesBfIO(mesh_)
240 if (!loaded)
return false;
246 const fvPatch& fvp = mesh_.boundary()[
patchi];
248 if (!isA<nonConformalMappedWallFvPatch>(fvp))
continue;
250 const nonConformalMappedWallFvPatch& ncmwFvp =
251 refCast<const nonConformalMappedWallFvPatch>(fvp);
253 if (!ncmwFvp.haveNbr())
continue;
255 if (regionPolyFacesBfs_.found(ncmwFvp.nbrMesh().name()))
continue;
257 IOobject io = fvMeshStitcher::polyFacesBfIO(ncmwFvp.nbrMesh());
259 regionPolyFacesBfIOs_.insert
261 ncmwFvp.nbrMesh().name(),
265 regionPolyFacesBfs_.insert
267 ncmwFvp.nbrMesh().name(),
291 return mesh_.time().lookupObject<fvMesh>(
regionName).polyFacesBf();
296 void Foam::fvMeshStitcher::getOrigNbrBfs
298 const SurfaceFieldBoundary<label>& polyFacesBf,
299 const SurfaceFieldBoundary<vector>& SfBf,
300 const SurfaceFieldBoundary<vector>& CfBf,
301 tmp<SurfaceFieldBoundary<label>>& tOrigFacesNbrBf,
302 tmp<SurfaceFieldBoundary<vector>>& tOrigSfNbrBf,
303 tmp<SurfaceFieldBoundary<point>>& tOrigCfNbrBf
313 dimensioned<label>(
dimless, -1)
338 const fvPatch& fvp = mesh_.boundary()[
patchi];
340 if (isA<nonConformalCoupledFvPatch>(fvp))
342 const nonConformalCoupledFvPatch& nccFvp =
343 refCast<const nonConformalCoupledFvPatch>(fvp);
345 origFaces.boundaryFieldRef()[
patchi] =
346 polyFacesBf[
patchi] - nccFvp.origPatch().start();
351 if (isA<coupledFvPatch>(fvp))
353 origSf.boundaryFieldRef()[
patchi] =
355 origCf.boundaryFieldRef()[
patchi] =
359 origFaces.boundaryFieldRef() =
360 origFaces.boundaryField().boundaryNeighbourField();
361 origSf.boundaryFieldRef() =
362 origSf.boundaryField().boundaryNeighbourField();
363 origCf.boundaryFieldRef() =
364 origCf.boundaryField().boundaryNeighbourField();
369 const fvPatch& fvp = mesh_.boundary()[
patchi];
371 if (!isA<nonConformalMappedWallFvPatch>(fvp))
continue;
373 const nonConformalMappedWallFvPatch& ncmwFvp =
374 refCast<const nonConformalMappedWallFvPatch>(fvp);
376 if (!ncmwFvp.haveNbr())
continue;
378 const fvMesh& nbrMesh = ncmwFvp.nbrMesh();
379 const nonConformalMappedWallFvPatch& nbrPatch = ncmwFvp.nbrPatch();
382 getPolyFacesBf(nbrMesh.name())[nbrPatch.index()];
384 origFaces.boundaryFieldRef()[
patchi] =
388 nbrPolyFacesPf - nbrPatch.origPatch().start(),
391 origSf.boundaryFieldRef()[
patchi] =
398 origCf.boundaryFieldRef()[
patchi] =
402 vectorField(nbrMesh.faceCentres(), nbrPolyFacesPf),
411 const fvPatch& fvp = mesh_.boundary()[
patchi];
415 if (isA<nonConformalCoupledFvPatch>(fvp))
417 const nonConformalCoupledFvPatch& nccFvp =
418 refCast<const nonConformalCoupledFvPatch>(fvp);
420 nccFvp.transform().invTransform(Cfp, Cfp);
421 nccFvp.transform().transformPosition(Cfp, Cfp);
424 if (isA<nonConformalMappedWallFvPatch>(fvp))
426 const nonConformalMappedWallFvPatch& ncmwFvp =
427 refCast<const nonConformalMappedWallFvPatch>(fvp);
429 if (ncmwFvp.haveNbr())
431 ncmwFvp.transform().invTransform(Cfp, Cfp);
432 ncmwFvp.transform().transformPosition(Cfp, Cfp);
442 origFaces.boundaryField()
448 origSf.boundaryField()
454 origCf.boundaryField()
460 Foam::fvMeshStitcher::procFacesToIndices
468 forAll(faceOtherProcFaces, facei)
470 forAll(faceOtherProcFaces[facei], i)
472 const remote& otherProcFacei = faceOtherProcFaces[facei][i];
474 is[otherProcFacei.proci] ++;
482 indices[proci].resize(is[proci]);
487 forAll(faceOtherProcFaces, facei)
489 forAll(faceOtherProcFaces[facei], i)
491 const remote& otherProcFacei = faceOtherProcFaces[facei][i];
493 FixedList<label, 3>& index =
494 indices[otherProcFacei.proci][is[otherProcFacei.proci] ++];
496 index = {facei, otherProcFacei.elementi, i + 1};
498 if (!owner)
Swap(index[0], index[1]);
505 sort(indices[proci]);
512 void Foam::fvMeshStitcher::matchIndices
516 List<
List<FixedList<label, 3>>>& indices,
517 const fvPatch& ncFvp,
518 const polyPatch& origPp,
531 if (
patchi == -1)
continue;
533 indicesRef[proci].resize(patchSizes[proci]);
535 for (
label indexi = 0; indexi < patchSizes[proci]; ++ indexi)
537 FixedList<label, 3>& indexRef = indicesRef[proci][indexi];
539 const label patchFacei = indexi + patchOffsets[proci];
543 polyFacesBf[
patchi][patchFacei] - origPp.start(),
544 origFacesNbrBf[
patchi][patchFacei],
548 if (!owner)
Swap(indexRef[0], indexRef[1]);
553 label nCouplesRemoved = 0, nCouplesAdded = 0;
558 if (
patchi == -1)
continue;
560 label refi = 0, i = 0;
561 DynamicList<FixedList<label, 3>> removedIndices;
562 while (refi < indicesRef[proci].size() && i < indices[proci].size())
564 const FixedList<label, 3> index
566 indices[proci][i][0],
567 indices[proci][i][1],
571 FixedList<label, 3>& indexRef = indicesRef[proci][refi];
573 if (index < indexRef)
576 removedIndices.append
578 indices[proci][i][0],
579 indices[proci][i][1],
580 - indices[proci][i][2]
584 else if (index == indexRef)
586 indexRef[2] = indices[proci][i][2];
597 while (i < indices[proci].size())
600 removedIndices.append
602 indices[proci][i][0],
603 indices[proci][i][1],
604 - indices[proci][i][2]
609 nCouplesRemoved +=
min(indices[proci].size() - i, 0);
610 nCouplesAdded +=
min(indicesRef[proci].size() - refi, 0);
612 indicesRef[proci].append(removedIndices);
616 reduce(nCouplesRemoved, sumOp<label>());
617 reduce(nCouplesAdded, sumOp<label>());
618 if ((nCouplesRemoved || nCouplesAdded) && owner)
620 Info<<
indent << nCouplesRemoved <<
'/' << nCouplesAdded
621 <<
" small couplings removed/added to " << ncFvp.
name()
626 Swap(indices, indicesRef);
632 const List<FixedList<label, 3>>& indices
636 while (
n > 0 && indices[
n - 1][2] < 0)
n --;
641 void Foam::fvMeshStitcher::createCouplings
646 const tmp<surfaceVectorField::Boundary>& tOrigSfNbrBf,
647 const tmp<surfaceVectorField::Boundary>& tOrigCfNbrBf,
648 const List<
List<FixedList<label, 3>>>& indices,
649 const List<DynamicList<couple>>& couples,
650 const polyPatch& origPp,
660 const label patchOffset = patchOffsets[proci];
662 if (
patchi == -1)
continue;
664 forAll(indices[proci], indexi)
666 const label origFacei = indices[proci][indexi][!owner];
667 const label i = indices[proci][indexi][2];
669 const label patchFacei = i >= 0 ? indexi + patchOffset : -1;
674 c = couples[origFacei][
mag(i) - 1];
683 small*origPp.faceAreas()[origFacei],
684 origPp.faceCentres()[origFacei]
688 small*tOrigSfNbrBf()[
patchi][patchFacei],
689 tOrigCfNbrBf()[
patchi][patchFacei]
697 const part& pThis =
c, & pOther = owner ?
c.nbr :
c;
704 SfBf[origPp.index()][origFacei],
705 CfBf[origPp.index()][origFacei]
708 if (i < 0 && owner) origP += pOther;
710 SfBf[origPp.index()][origFacei] = origP.area;
711 CfBf[origPp.index()][origFacei] = origP.centre;
717 polyFacesBf[
patchi][patchFacei] =
718 origFacei + origPp.start();
719 SfBf[
patchi][patchFacei] = pOther.area;
720 CfBf[
patchi][patchFacei] = pOther.centre;
727 void Foam::fvMeshStitcher::createErrorAndEdgeParts
732 const patchToPatches::intersection& intersection,
733 const polyPatch& origPp
737 forAll(intersection.srcErrorParts(), origFacei)
741 SfBf[origPp.index()][origFacei],
742 CfBf[origPp.index()][origFacei]
744 origP += intersection.srcErrorParts()[origFacei];
746 SfBf[origPp.index()][origFacei] = origP.area;
747 CfBf[origPp.index()][origFacei] = origP.centre;
751 forAll(intersection.srcEdgeParts(), origEdgei)
753 origEdgeParts[origEdgei] += intersection.srcEdgeParts()[origEdgei];
758 void Foam::fvMeshStitcher::intersectNonConformalCyclic
760 const nonConformalCyclicFvPatch& nccFvp,
764 const tmp<surfaceLabelField::Boundary>& tOrigFacesNbrBf,
765 const tmp<surfaceVectorField::Boundary>& tOrigSfNbrBf,
766 const tmp<surfaceVectorField::Boundary>& tOrigCfNbrBf,
771 const polyPatch& origPp = nccFvp.origPatch().poly();
777 forAll(mesh_.boundary(), patchj)
779 const fvPatch& fvp = mesh_.boundary()[patchj];
781 if (isA<nonConformalProcessorCyclicFvPatch>(fvp))
783 const nonConformalProcessorCyclicFvPatch& ncpcFvp =
784 refCast<const nonConformalProcessorCyclicFvPatch>(fvp);
786 if (ncpcFvp.referPatchIndex() == nccFvp.index())
788 patchis[ncpcFvp.neighbProcNo()] = patchj;
794 const patchToPatches::intersection& intersection =
796 ? nccFvp.nonConformalCyclicPoly().intersection()
797 : nccFvp.nbrPatch().nonConformalCyclicPoly().intersection();
804 ? intersection.srcTgtProcFaces()
805 : intersection.tgtSrcProcFaces(),
810 if (tOrigFacesNbrBf.valid())
815 if (patchis[proci] != -1)
817 patchSizes[proci] = polyFacesBf[patchis[proci]].size();
840 const label patchSize = nValidIndices(indices[proci]);
842 if (
patchi == -1 && patchSize)
845 <<
"Intersection generated coupling through "
846 << nccFvp.name() <<
" between processes "
848 <<
" but a corresponding processor interface was not found"
854 polyFacesBf[
patchi].resize(patchSize);
855 SfBf[
patchi].resize(patchSize);
856 CfBf[
patchi].resize(patchSize);
870 nccFvp.owner() ? intersection.srcCouples() : intersection.tgtCouples(),
880 createErrorAndEdgeParts
892 void Foam::fvMeshStitcher::intersectNonConformalMappedWall
894 const nonConformalMappedWallFvPatch& ncmwFvp,
898 const tmp<surfaceLabelField::Boundary>& tOrigFacesNbrBf,
899 const tmp<surfaceVectorField::Boundary>& tOrigSfNbrBf,
900 const tmp<surfaceVectorField::Boundary>& tOrigCfNbrBf,
905 const polyPatch& origPp = ncmwFvp.origPatch().poly();
908 const patchToPatches::intersection& intersection =
910 ? ncmwFvp.nonConformalMappedWallPoly().intersection()
911 : ncmwFvp.nbrPatch().nonConformalMappedWallPoly().intersection();
918 ? intersection.srcTgtProcFaces()
919 : intersection.tgtSrcProcFaces(),
924 nonConformalMappedPolyFacesFvsPatchLabelField& polyFacesPf =
925 refCast<nonConformalMappedPolyFacesFvsPatchLabelField>
927 polyFacesBf[ncmwFvp.index()]
931 if (tOrigFacesNbrBf.valid())
941 polyFacesPf.procOffsets(),
942 polyFacesPf.procSizes(),
953 polyFacesPf.procOffsets()[proci] =
count;
955 count += nValidIndices(indices[proci]);
958 polyFacesPf.resize(
count);
959 SfBf[polyFacesPf.patch().index()].resize(
count);
960 CfBf[polyFacesPf.patch().index()].resize(
count);
973 ncmwFvp.owner() ? intersection.srcCouples() : intersection.tgtCouples(),
976 polyFacesPf.procOffsets(),
983 createErrorAndEdgeParts
996 Foam::fvMeshStitcher::calculateOwnerOrigBoundaryEdgeParts
1001 const polyBoundaryMesh& pbMesh = mesh_.poly().boundary();
1004 const labelList& ownerOrigBoundaryPointMeshPoint =
1005 ncb.ownerOrigBoundaryPointMeshPoint();
1006 const labelList& ownerOrigBoundaryEdgeMeshEdge =
1007 ncb.ownerOrigBoundaryEdgeMeshEdge();
1008 const edgeList& ownerOrigBoundaryEdges = ncb.ownerOrigBoundaryEdges();
1009 const edgeList& ownerOrigBoundaryMeshEdges =
1010 ncb.ownerOrigBoundaryMeshEdges();
1013 labelList ownerOrigBoundaryEdgeNParts(ownerOrigBoundaryEdges.size(), 0);
1014 List<part> ownerOrigBoundaryEdgeParts(ownerOrigBoundaryEdges.size());
1017 if (patchEdgeParts[
patchi].empty())
continue;
1019 const polyPatch& patch = pbMesh[
patchi];
1021 const labelList& patchEdgeOwnerOrigBoundaryEdges =
1022 ncb.patchEdgeOwnerOrigBoundaryEdges(
patchi);
1026 const label ownerOrigBoundaryEdgei =
1027 patchEdgeOwnerOrigBoundaryEdges[patchEdgei];
1033 ownerOrigBoundaryMeshEdges[ownerOrigBoundaryEdgei]
1036 const part& pU = patchEdgeParts[
patchi][patchEdgei];
1037 const part
p =
sign > 0 ? pU : -pU;
1039 ownerOrigBoundaryEdgeNParts[ownerOrigBoundaryEdgei] ++;
1040 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei] +=
p;
1045 const globalIndex globalOwnerOrigBoundaryPoints
1047 ownerOrigBoundaryPointMeshPoint.size()
1051 ownerOrigBoundaryPointMeshPoint.size()
1053 forAll(ownerOrigBoundaryPointIndices, ownerOrigBoundaryPointi)
1055 ownerOrigBoundaryPointIndices[ownerOrigBoundaryPointi] =
1056 globalOwnerOrigBoundaryPoints.toGlobal(ownerOrigBoundaryPointi);
1061 ownerOrigBoundaryPointMeshPoint,
1062 ownerOrigBoundaryPointIndices,
1070 forAll(ownerOrigBoundaryEdgeParts, ownerOrigBoundaryEdgei)
1072 const edge&
e = ownerOrigBoundaryEdges[ownerOrigBoundaryEdgei];
1076 ownerOrigBoundaryPointIndices[
e.start()]
1077 > ownerOrigBoundaryPointIndices[
e.end()])
1079 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei] =
1080 - ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei];
1088 ownerOrigBoundaryEdgeMeshEdge,
1089 ownerOrigBoundaryEdgeNParts,
1096 ownerOrigBoundaryEdgeMeshEdge,
1097 ownerOrigBoundaryEdgeParts,
1102 const transformer& vt,
1114 fld[i].centre = vt.transformPosition(
fld[i].centre);
1125 fld[i].centre = vt.invTransformPosition(
fld[i].centre);
1131 forAll(ownerOrigBoundaryEdgeParts, ownerOrigBoundaryEdgei)
1133 if (ownerOrigBoundaryEdgeNParts[ownerOrigBoundaryEdgei] != 0)
1135 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei].area /=
1136 ownerOrigBoundaryEdgeNParts[ownerOrigBoundaryEdgei];
1141 forAll(ownerOrigBoundaryEdgeParts, ownerOrigBoundaryEdgei)
1143 const edge&
e = ownerOrigBoundaryEdges[ownerOrigBoundaryEdgei];
1147 ownerOrigBoundaryPointIndices[
e.start()]
1148 > ownerOrigBoundaryPointIndices[
e.end()]
1151 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei] =
1152 - ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei];
1156 return ownerOrigBoundaryEdgeParts;
1160 void Foam::fvMeshStitcher::applyOwnerOrigBoundaryEdgeParts
1167 const polyBoundaryMesh& pbMesh = mesh_.poly().boundary();
1170 const labelList ownerOrigPatchIndices = ncb.ownerOrigPatchIndices();
1171 const labelList& ownerOrigBoundaryEdgeMeshEdge =
1172 ncb.ownerOrigBoundaryEdgeMeshEdge();
1173 const edgeList& ownerOrigBoundaryMeshEdges =
1174 ncb.ownerOrigBoundaryMeshEdges();
1176 boolList patchIsOwnerOrig(pbMesh.size(),
false);
1177 UIndirectList<bool>(patchIsOwnerOrig, ownerOrigPatchIndices) =
true;
1180 labelList ownerOrigBoundaryEdgeNOrigFaces
1182 ownerOrigBoundaryEdgeMeshEdge.size(),
1185 forAll(ownerOrigBoundaryEdgeMeshEdge, ownerOrigBoundaryEdgei)
1187 const label meshEdgei =
1188 ownerOrigBoundaryEdgeMeshEdge[ownerOrigBoundaryEdgei];
1190 forAll(mesh_.edgeFaces()[meshEdgei], edgeFacei)
1192 const label facei = mesh_.edgeFaces()[meshEdgei][edgeFacei];
1195 mesh_.isInternalFace(facei)
1197 : pbMesh.patchIndices()[facei - mesh_.nInternalFaces()];
1201 ownerOrigBoundaryEdgeNOrigFaces[ownerOrigBoundaryEdgei] ++;
1210 ownerOrigBoundaryEdgeMeshEdge,
1211 ownerOrigBoundaryEdgeNOrigFaces,
1217 tmp<surfaceLabelField> tChanged =
1223 forAll(ownerOrigBoundaryEdgeMeshEdge, ownerOrigBoundaryEdgei)
1225 const label meshEdgei =
1226 ownerOrigBoundaryEdgeMeshEdge[ownerOrigBoundaryEdgei];
1228 const part& ownerOrigBoundaryEdgeP =
1229 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei];
1231 switch (ownerOrigBoundaryEdgeNOrigFaces[ownerOrigBoundaryEdgei])
1242 label origFacei = -1, origPatchi = -1, origPatchFacei = -1;
1243 forAll(mesh_.edgeFaces()[meshEdgei], edgeFacei)
1245 const label facei = mesh_.edgeFaces()[meshEdgei][edgeFacei];
1248 mesh_.isInternalFace(facei)
1250 : pbMesh.patchIndices()[facei - mesh_.nInternalFaces()];
1256 origPatchFacei = facei - pbMesh[
patchi].start();
1261 if (origFacei != -1)
1264 SfSf.boundaryFieldRef()[origPatchi][origPatchFacei];
1266 CfSf.boundaryFieldRef()[origPatchi][origPatchFacei];
1269 mesh_.faces()[origFacei].edgeDirection
1271 ownerOrigBoundaryMeshEdges[ownerOrigBoundaryEdgei]
1274 part
p(
area, centre);
1277 ? ownerOrigBoundaryEdgeP
1278 : -ownerOrigBoundaryEdgeP;
1286 [origPatchi][origPatchFacei] =
label(1);
1297 forAll(mesh_.edgeFaces()[meshEdgei], edgeFacei)
1299 const label facei = mesh_.edgeFaces()[meshEdgei][edgeFacei];
1302 mesh_.isInternalFace(facei)
1304 : pbMesh.patchIndices()[facei - mesh_.nInternalFaces()];
1311 const label patchFacei =
1317 : SfSf.boundaryFieldRef()[
patchi][patchFacei];
1321 : CfSf.boundaryFieldRef()[
patchi][patchFacei];
1324 mesh_.faces()[facei].edgeDirection
1326 ownerOrigBoundaryMeshEdges[ownerOrigBoundaryEdgei]
1329 part
p(
area, centre);
1332 ? ownerOrigBoundaryEdgeP
1333 : -ownerOrigBoundaryEdgeP;
1338 if (debug &&
patchi != -1)
1351 <<
"Boundary is not manifold"
1361 tChanged->boundaryField();
1366 changedBf.boundaryNeighbourField()
1369 bool synchronised =
true;
1376 if (!isA<processorFvPatch>(changedPf.patch()))
continue;
1378 forAll(changedPf, patchFacei)
1380 if (changedPf[patchFacei] != changedNbrPf[patchFacei])
1383 changedPf.patch().start() + patchFacei;
1386 <<
"Face not synchronised with centre at "
1387 << mesh_.faceCentres()[facei] <<
endl;
1389 synchronised =
false;
1403 void Foam::fvMeshStitcher::stabiliseOrigPatchFaces
1410 const labelList allOrigPatchIndices = ncb.allOrigPatchIndices();
1412 forAll(allOrigPatchIndices, i)
1414 const label origPatchi = allOrigPatchIndices[i];
1415 const polyPatch& origPp = mesh_.poly().boundary()[origPatchi];
1420 forAll(origPp, origPatchFacei)
1422 const vector& a = origPpFaceAreas[origPatchFacei];
1423 const point&
c = origPpFaceCentres[origPatchFacei];
1425 vector& Sf = SfBf[origPatchi][origPatchFacei];
1426 point& Cf = CfBf[origPatchi][origPatchFacei];
1440 dSfHat = (Sf & Sf)*a - (Sf & a)*Sf;
1445 part SAndCf(Sf, Cf);
1447 SAndCf += part(small*
mag(a)*dSfHat,
c);
1456 void Foam::fvMeshStitcher::intersect
1462 const bool matchTopology
1465 const polyBoundaryMesh& pbMesh = mesh_.poly().boundary();
1468 const labelList ownerOrigPatchIndices = ncb.ownerOrigPatchIndices();
1469 const edgeList& ownerOrigBoundaryMeshEdges =
1470 ncb.ownerOrigBoundaryMeshEdges();
1478 forAll(ownerOrigPatchIndices, i)
1480 const label origPatchi = ownerOrigPatchIndices[i];
1482 patchEdgeParts[origPatchi].resize
1484 mesh_.poly().boundary()[origPatchi].nEdges(),
1492 tmp<surfaceLabelField::Boundary> tOrigFacesNbrBf;
1493 tmp<surfaceVectorField::Boundary> tOrigSfNbrBf;
1494 tmp<surfaceVectorField::Boundary> tOrigCfNbrBf;
1511 if (!patchCoupleds[
patchi])
continue;
1513 const fvPatch& fvp = mesh_.boundary()[
patchi];
1515 if (isA<nonConformalCyclicFvPatch>(fvp))
1517 const nonConformalCyclicFvPatch& nccFvp =
1518 refCast<const nonConformalCyclicFvPatch>(fvp);
1520 intersectNonConformalCyclic
1529 patchEdgeParts[nccFvp.origPatchIndex()]
1532 else if (isA<nonConformalProcessorCyclicFvPatch>(fvp))
1534 else if (isA<nonConformalMappedWallFvPatch>(fvp))
1536 const nonConformalMappedWallFvPatch& ncmwFvp =
1537 refCast<const nonConformalMappedWallFvPatch>(fvp);
1539 intersectNonConformalMappedWall
1548 patchEdgeParts[ncmwFvp.origPatchIndex()]
1554 <<
"Coupled patch type not recognised"
1563 if (patchCoupleds[
patchi])
continue;
1565 const fvPatch& fvp = mesh_.boundary()[
patchi];
1567 if (!isA<nonConformalFvPatch>(fvp))
continue;
1569 const polyPatch& origPp =
1570 refCast<const nonConformalFvPatch>(fvp).origPatch().poly();
1575 small*origPp.faceAreas(),
1576 polyFacesBf[
patchi] - origPp.start()
1581 origPp.faceCentres(),
1582 polyFacesBf[
patchi] - origPp.start()
1588 calculateOwnerOrigBoundaryEdgeParts(patchEdgeParts);
1592 forAll(ownerOrigPatchIndices, i)
1594 const label origPatchi = ownerOrigPatchIndices[i];
1595 const polyPatch& origPatch = pbMesh[origPatchi];
1597 const labelList& origPatchEdgeOwnerOrigBoundaryEdges =
1598 ncb.patchEdgeOwnerOrigBoundaryEdges(origPatchi);
1600 forAll(patchEdgeParts[origPatchi], origPatchEdgei)
1602 const label ownerOrigBoundaryEdgei =
1603 origPatchEdgeOwnerOrigBoundaryEdges[origPatchEdgei];
1608 meshEdge(origPatch, origPatchEdgei),
1609 ownerOrigBoundaryMeshEdges[ownerOrigBoundaryEdgei]
1613 patchEdgeParts[origPatchi][origPatchEdgei];
1616 ? ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei]
1617 : -ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei];
1619 forAll(origPatch.edgeFaces()[origPatchEdgei], patchEdgeFacei)
1621 const label patchFacei =
1622 origPatch.edgeFaces()[origPatchEdgei][patchEdgeFacei];
1625 origPatch.localFaces()[patchFacei].edgeDirection
1627 origPatch.edges()[origPatchEdgei]
1632 SfBf[origPatchi][patchFacei],
1633 CfBf[origPatchi][patchFacei]
1635 p +=
sign > 0 ? errorP : -errorP;
1637 SfBf[origPatchi][patchFacei] =
p.area;
1638 CfBf[origPatchi][patchFacei] =
p.centre;
1644 applyOwnerOrigBoundaryEdgeParts(SfSf, CfSf, ownerOrigBoundaryEdgeParts);
1647 stabiliseOrigPatchFaces(SfBf, CfBf);
1651 bool Foam::fvMeshStitcher::disconnectThis
1653 const bool changing,
1654 const bool geometric
1657 if (!stitches() || mesh_.conformal())
return false;
1662 ? this->patchCoupleds()
1669 preConformSurfaceFields();
1670 preConformVolFields();
1677 for (
label i = 1; i < mesh_.phi().nOldTimes(
false); ++ i)
1679 phi.oldTimeRef(i) == mesh_.phi().oldTime(i);
1681 conformCorrectMeshPhi(phi);
1690 resizePatchFields<SurfaceField>();
1691 resizePatchFields<VolField>();
1694 const polyTopoChangeMap map(mesh_);
1696 meshObjects::topoChange<fvMesh>(mesh_, map);
1697 meshObjects::topoChange<lduMesh>(mesh_, map);
1699 const_cast<Time&
>(mesh_.time()).functionObjects().topoChange(map);
1705 bool Foam::fvMeshStitcher::connectThis
1707 const bool changing,
1708 const bool geometric,
1712 if (!stitches() || !mesh_.conformal())
return false;
1715 IOobject polyFacesBfIO(
word::null, mesh_.pointsInstance(), mesh_);
1723 const bool matchTopology =
1724 load && loadPolyFacesBf(polyFacesBfIO, polyFacesBf);
1728 (geometric || !matchTopology)
1729 ? this->patchCoupleds()
1730 :
boolList(mesh_.boundary().size(),
false);
1735 if (!patchCoupleds[
patchi])
continue;
1737 const fvPatch& fvp = mesh_.boundary()[
patchi];
1739 if (isA<nonConformalCyclicFvPatch>(fvp))
1741 const nonConformalCyclicFvPatch& nccFvp =
1742 refCast<const nonConformalCyclicFvPatch>(fvp);
1746 nccFvp.nonConformalCyclicPoly().intersection();
1749 else if (isA<nonConformalProcessorCyclicFvPatch>(fvp))
1751 else if (isA<nonConformalMappedWallFvPatch>(fvp))
1753 const nonConformalMappedWallFvPatch& ncmwFvp =
1754 refCast<const nonConformalMappedWallFvPatch>(fvp);
1756 const nonConformalMappedWallFvPatch& ownerNcmwFvp =
1757 ncmwFvp.owner() ? ncmwFvp : ncmwFvp.nbrPatch();
1759 ownerNcmwFvp.nonConformalMappedWallPoly().intersection();
1764 <<
"Coupled patch type not recognised"
1769 if (
any(patchCoupleds))
1774 Info<<
" region " << mesh_.name();
1784 intersect(polyFacesBf, Sf, Cf, patchCoupleds, matchTopology);
1790 createNonConformalCorrectMeshPhiGeometry(polyFacesBf, Sf, Cf);
1797 for (
label i = 1; i <= mesh_.phi().nOldTimes(
false); ++ i)
1799 phi.oldTimeRef(i) == mesh_.phi().oldTime(i);
1801 unconformCorrectMeshPhi(polyFacesBf, Sf, Cf, phi);
1802 mesh_.unconform(polyFacesBf, Sf, Cf, phi);
1806 mesh_.unconform(polyFacesBf, Sf, Cf);
1812 mesh_.setPolyFacesBfInstance(polyFacesBfIO.instance());
1816 resizePatchFields<SurfaceField>();
1817 resizePatchFields<VolField>();
1823 postUnconformSurfaceFields();
1824 postUnconformVolFields();
1828 mesh_.deltaCoeffs();
1830 if (
any(patchCoupleds))
1833 const scalar gMaxO =
gMax(o);
1834 Info<<
indent <<
"Cell min/average/max openness = "
1836 if (gMaxO > rootSmall)
1839 <<
"Maximum openness of " << gMaxO
1845 for (
label i = 0; i <= mesh_.phi().nOldTimes(
false); ++ i)
1848 const scalar gMinVce =
gMin(vce);
1849 const scalar gMaxVce =
gMax(vce);
1851 for (
label j = 0; j < i; ++ j)
Info<<
"old-";
1852 Info<< (i ?
"time " :
"") <<
"volume conservation error = "
1853 << gMinVce <<
'/' <<
gAverage(vce) <<
'/' << gMaxVce
1855 if (- gMinVce > rootSmall || gMaxVce > rootSmall)
1858 <<
"Maximum volume conservation error of "
1859 <<
max(-gMinVce, gMaxVce) <<
" is not tolerable"
1872 mesh_.phi().boundaryField()
1874 mfe += mesh_.phi().boundaryField().boundaryNeighbourField();
1877 label nNonProcPatches = 0;
1880 const fvPatch& fvp = mesh_.boundary()[
patchi];
1882 if (!isA<processorFvPatch>(fvp))
1884 if (nNonProcPatches !=
patchi)
1887 <<
"Processor patches do not follow non-processor "
1898 scalarField sumMfe(nNonProcPatches, 0), nSumMfe(nNonProcPatches, 0);
1902 const fvPatch& fvp = mesh_.boundary()[
patchi];
1904 const label nccPatchi =
1905 isA<nonConformalCyclicFvPatch>(fvp)
1906 ? refCast<const nonConformalCyclicFvPatch>(fvp)
1908 : isA<nonConformalProcessorCyclicFvPatch>(fvp)
1909 ? refCast<const nonConformalProcessorCyclicFvPatch>(fvp)
1913 if (nccPatchi != -1)
1918 nSumMfe[nccPatchi] += mfe[
patchi].size();
1923 reduce(minMfe, ListOp<minOp<scalar>>());
1924 reduce(sumMfe, ListOp<sumOp<scalar>>());
1925 reduce(nSumMfe, ListOp<sumOp<scalar>>());
1926 reduce(maxMfe, ListOp<maxOp<scalar>>());
1931 const fvPatch& fvp = mesh_.boundary()[
patchi];
1935 isA<nonConformalCyclicFvPatch>(fvp)
1936 && refCast<const nonConformalCyclicFvPatch>(fvp).owner()
1941 <<
" min/average/max mesh flux error = "
1950 const scalar gMaxPvf =
gMax(pvf);
1951 Info<<
indent <<
"Cell min/average/max projected volume fraction = "
1953 if (gMaxPvf > minWarnProjectedVolumeFraction_)
1956 <<
"Maximum projected volume fraction " << gMaxPvf <<
" may "
1957 <<
"cause instability." <<
nl <<
indent <<
"Volumetric "
1958 <<
"distortion can be minimised by making the side of the "
1959 <<
"interface" <<
nl <<
indent <<
"with smaller or more "
1960 <<
"finely layered cells the neighbour." <<
nl <<
indent
1961 <<
"This is done by specifying this side second to "
1962 <<
"createNonConformalCouples;" <<
nl <<
indent <<
"either on "
1963 <<
"the command line, or in the patches (and regions) entries "
1964 <<
"within" <<
nl <<
indent <<
"the "
1965 <<
"createNonConformalCouplesDict." <<
endl;
1969 if (
any(patchCoupleds))
1975 const polyTopoChangeMap map(mesh_);
1977 meshObjects::topoChange<fvMesh>(mesh_, map);
1978 meshObjects::topoChange<lduMesh>(mesh_, map);
1980 const_cast<Time&
>(mesh_.time()).functionObjects().topoChange(map);
1986 void Foam::fvMeshStitcher::preConformSurfaceFields()
1988 #define PreConformSurfaceFields(Type, nullArg) \
1989 preConformSurfaceFields<Type>();
1991 #undef PreConformSurfaceFields
1995 void Foam::fvMeshStitcher::preConformVolFields()
1997 #define PreConformVolFields(Type, nullArg) \
1998 preConformVolFields<Type>();
2000 #undef PreConformVolFields
2005 void Foam::fvMeshStitcher::postUnconformSurfaceFields<Foam::vector>()
2007 if (mesh_.poly().topoChanged())
2017 if (
isNull(
U)) Uf.clearOldTimes();
2027 fields[i].boundaryFieldRefNoStoreOldTimes()
2033 void Foam::fvMeshStitcher::postUnconformSurfaceFields()
2035 #define PostUnconformSurfaceFields(Type, nullArg) \
2036 postUnconformSurfaceFields<Type>();
2038 #undef PostUnconformSurfaceFields
2042 void Foam::fvMeshStitcher::postUnconformVolFields()
2044 #define PostUnconformVolFields(Type, nullArg) \
2045 postUnconformVolFields<Type>();
2047 #undef PostUnconformVolFields
2050 const labelList origPatchIndices = ncb.allOrigPatchIndices();
2051 const labelList errorPatchIndices = ncb.allErrorPatchIndices();
2056 UPtrList<volVectorField> Us(
mesh().fields<volVectorField>());
2061 forAll(errorPatchIndices, i)
2063 const label errorPatchi = errorPatchIndices[i];
2064 const label origPatchi = origPatchIndices[i];
2067 U.boundaryFieldRefNoStoreOldTimes()[origPatchi];
2071 isA<movingWallVelocityFvPatchVectorField>(origUp)
2072 || isA<movingWallSlipVelocityFvPatchVectorField>(origUp)
2075 U.boundaryFieldRefNoStoreOldTimes().set
2078 new movingWallSlipVelocityFvPatchVectorField
2088 #define PostUnconformEvaluateVolFields(Type, nullArg) \
2089 postUnconformEvaluateVolFields<Type>();
2091 #undef PostUnconformEvaluateVolFields
2108 if (isA<nonConformalFvPatch>(mesh_.boundary()[
patchi]))
2110 Uf.boundaryFieldRefNoStoreOldTimes()[
patchi] ==
2111 UfInterpolated.boundaryField()[
patchi];
2122 boolList result(mesh_.boundary().size(),
false);
2129 if (isA<nonConformalCyclicFvPatch>(fvp))
2138 if (isA<nonConformalProcessorCyclicFvPatch>(fvp))
2141 refCast<const nonConformalProcessorCyclicFvPatch>(fvp);
2150 if (isA<nonConformalMappedWallFvPatch>(fvp))
2153 refCast<const nonConformalMappedWallFvPatch>(fvp);
2174 bool result =
false;
2180 if (!isA<nonConformalFvPatch>(fvp))
continue;
2183 mesh_.magSf().boundaryField()[
patchi];
2186 refCast<const nonConformalFvPatch>(fvp).origPatch().poly();
2194 if (
max(magSfp/origMagSfp) > rootSmall)
2217 (small*
sqr(
cbrt(mesh_.V())))()
2229 <<
"Can only compute volume conservation error for this time, or "
2236 n == 0 ? mesh_.time().deltaT() : mesh_.time().deltaT0();
2244 "volumeConservationError" +
word(
n == 0 ?
"" :
"_0"),
2256 "projectedVolumeFraction",
2273 regionPolyFacesBfIOs_(),
2274 regionPolyFacesBfs_()
2289 if (!mesh_.local().empty())
2297 if (isA<nonConformalFvPatch>(mesh_.boundary()[
patchi]))
2309 const bool changing,
2310 const bool geometric
2315 return disconnectThis(changing, geometric);
2322 bool result =
false;
2325 if (regionMeshes[i]().stitcher().disconnectThis(changing, geometric))
2337 const bool changing,
2338 const bool geometric,
2344 return connectThis(changing, geometric, load);
2360 if (!regionMeshes[i]().stitcher().ready_)
2367 bool result =
false;
2370 if (regionMeshes[i]().stitcher().connectThis(changing, geometric, load))
2379 regionMeshes[i]().stitcher().ready_ =
false;
2388 if (mesh_.conformal() || geometric == this->geometric())
return;
2403 ? this->patchCoupleds()
2404 :
boolList(mesh_.boundary().size(),
false);
2411 intersect(polyFacesBf, Sf, Cf, patchCoupleds,
true);
2414 mesh_.unconform(polyFacesBf, Sf, Cf);
2417 mesh_.deltaCoeffs();
2422 meshObjects::topoChange<fvMesh>(mesh_, map);
2423 meshObjects::topoChange<lduMesh>(mesh_, map);
2425 const_cast<Time&
>(mesh_.time()).functionObjects().topoChange(map);
#define forAll(list, i)
Loop across all elements in list.
static nonConformalBoundary & New(const word &name, const polyMesh &mesh)
Construct and return the named DemandDrivenMeshObject.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
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 const DimensionedField< Type, GeoMesh, PrimitiveField > & null()
Return a null DimensionedField.
SubField< vector > subField
Declare type of subField.
Generic GeometricBoundaryField class.
Generic GeometricField class.
DimensionedField< Type, GeoMesh, PrimitiveField > Internal
Type of the internal field from which this GeometricField is derived.
GeometricBoundaryField< Type, GeoMesh, PrimitiveField > Boundary
Type of the boundary field.
Boundary & boundaryFieldRef()
Return a reference to the boundary field.
GeoMesh::template PatchField< Type > Patch
Type of the patch field of which the Boundary is composed.
static const GeometricField< Type, GeoMesh, PrimitiveField > & null()
Return a null geometric field.
static tmp< GeometricField< Type, GeoMesh, PrimitiveField > > New(const word &name, const Internal &, const PtrList< Patch > &, const HashPtrTable< Source > &=HashPtrTable< Source >())
Return a temporary field constructed from name,.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
virtual const fileName & name() const
Return the name of the stream.
const Field0Type & oldTime() const
Return the old-time field.
A list of faces which address into the list of points.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
word findInstance(const fileName &dir, const word &name=word::null, const IOobject::readOption rOpt=IOobject::MUST_READ, const word &stopInstance=word::null) const
Return the location of "dir" containing the file "name".
label size() const
Return the number of elements in the UList.
static label nProcs(const label communicator=0)
Number of processes in parallel run.
static bool & parRun()
Is this a parallel run?
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
static Form uniform(const Cmpt &s)
Return a VectorSpace with all elements = s.
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
static int compare(const edge &, const edge &)
Compare edges.
Mesh manipulator that uses the intersection provided by the cyclic non-conformal poly patches to crea...
bool disconnect(const bool changing, const bool geometric)
Disconnect the mesh by removing faces from the nonConformalCyclics.
bool connect(const bool changing, const bool geometric, const bool load)
Connect the mesh by adding faces into the nonConformalCyclics.
void reconnect(const bool geometric) const
Re-compute the connection. Topology is preserved. Permits a change.
bool geometric() const
Is the connection "geometric", or has the topology just been.
tmp< DimensionedField< scalar, fvMesh > > volumeConservationError(const label n) const
Return the non-dimensional old-time volume conservation error.
fvMeshStitcher(fvMesh &)
Construct from fvMesh.
virtual void topoChange(const polyTopoChangeMap &)
Update corresponding to the given map.
virtual void distribute(const polyDistributionMap &)
Update corresponding to the given distribution map.
bool stitches() const
Does this stitcher do anything?
tmp< DimensionedField< scalar, fvMesh > > projectedVolumeFraction() const
Return the projected volume fraction for debugging/checking.
fvMesh & mesh()
Return the fvMesh.
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
tmp< DimensionedField< scalar, fvMesh > > openness() const
Return the non-dimensional cell openness for debugging/checking.
boolList patchCoupleds() const
Determine which patches are coupled; i.e., for which.
virtual ~fvMeshStitcher()
Destructor.
Mesh data needed to do the Finite Volume discretisation.
const Time & time() const
Return the top-level database.
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
const word & name() const
Return reference to name.
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
const polyPatch & poly() const
Return the polyPatch.
An abstract base class with a fat-interface to all derived classes covering all possible ways in whic...
bool haveNbr() const
Is the neighbour available?
const fileName & dbDir() const
Local directory path of this objectRegistry relative to the time.
Motion of the mesh specified as a list of pointMeshMovers.
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Class containing mesh-to-mesh mapping information.
static word defaultRegion
Return the default region name.
A patch is a list of labels that address the faces in the global face list.
label start() const
Return start label of this patch in the polyMesh face list.
const scalarField::subField magFaceAreas() const
Return face area magnitudes.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
label referPatchIndex() const
Return the referring patch ID.
A class for managing temporary objects.
Template function which returns the un-mangled name of a given type. Useful for types which do not ha...
A class for handling words, derived from string.
static const word null
An empty word.
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define PreConformVolFields(Type, nullArg)
#define PostUnconformEvaluateVolFields(Type, nullArg)
#define PreConformSurfaceFields(Type, nullArg)
#define PostUnconformVolFields(Type, nullArg)
#define PostUnconformSurfaceFields(Type, nullArg)
Surface integrate surfaceField creating a volField. Surface sum a surfaceField creating a volField.
gmvFile<< "tracers "<< particles.size()<< nl;{ pointField positions(particles.size());label particlei=0;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter) { positions[particlei++]=iter().position(mesh);} for(i=0;i< pTraits< point >::nComponents;i++) { forAll(positions, particlei) { gmvFile<< component(positions[particlei], i)<< ' ';} gmvFile<< nl;}}forAll(lagrangianScalarNames, i){ const word &name=lagrangianScalarNames[i];IOField< scalar > fld(IOobject(name, runTime.name(), lagrangian::cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Info<< "Calculating turbulent flame speed field St\n"<< endl;volScalarField St(IOobject("St", runTime.name(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), flameWrinkling->Xi() *Su);multivariateSurfaceInterpolationScheme< scalar >::fieldTable fields
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionedScalar c
Speed of light in a vacuum.
static tmp< SurfaceField< Type > > interpolate(const VolField< Type > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
void surfaceIntegrate(Field< Type > &ivf, const SurfaceField< Type > &ssf)
tmp< VolInternalField< Type > > surfaceSum(const SurfaceField< Type > &ssf)
Type gMin(const UList< Type > &f, const label comm)
errorManipArg< error, int > exit(error &err, const int errNo=1)
List< word > wordList
A List of words.
const dimensionSet & dimless
VolField< vector > volVectorField
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
List< label > labelList
A List of labels.
Type gAverage(const UList< Type > &f, const label comm)
dimensionedScalar sign(const dimensionedScalar &ds)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Ostream & endl(Ostream &os)
Add newline and flush stream.
const dimensionSet & dimLength
String typeName(const std::type_info &info)
Return the un-mangled name given the standard type info.
const word & regionName(const solver ®ion)
SurfaceField< scalar > surfaceScalarField
FOR_ALL_FIELD_TYPES(makeDimensionedPointFieldFunctions)
SurfaceField< label > surfaceLabelField
vectorField pointField
pointField is a vectorField.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
List< bool > boolList
Bool container classes.
List< scalar > scalarList
A List of scalars.
vector point
Point is a vector.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
Vector< scalar > vector
A scalar version of the templated Vector.
fvsPatchField< label > fvsPatchLabelField
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
defineRunTimeSelectionTable(fvConstraint, dictionary)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
edge meshEdge(const PrimitivePatch< FaceList, PointField > &p, const label edgei)
dimensionSet normalised(const dimensionSet &)
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensioned< vector > dimensionedVector
Dimensioned vector obtained from generic dimensioned type.
Field< vector > vectorField
Specialisation of Field<T> for vector.
void cbrt(LagrangianPatchField< scalar > &f, const LagrangianPatchField< scalar > &f1)
bool any(const boolList &l)
Type gMax(const UList< Type > &f, const label comm)
bool isNull(const T &t)
Return true if t is a reference to the nullObject of type T.
HashSet wordHashSet
A HashSet with word keys.
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
label count(const ListType &l, typename ListType::const_reference x)
Count the number of occurrences of a value in a list.
static const label labelMax
tmp< DimensionedField< Type, GeoMesh, Field > > cmptMag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
SurfaceField< vector > surfaceVectorField
const dimensionSet & dimArea
dimensionSet perpendicular(const dimensionSet &)
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
Ostream & indent(Ostream &os)
Indent stream.
fvsPatchField< vector > fvsPatchVectorField
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
const volVectorField & surfaceToVolVelocity(const surfaceVectorField &Uf)
Get the cell velocity field corresponding to a given face velocity, or a.
faceListList boundary(nPatches)
const Foam::wordList regionNames(args.optionFound("allRegions") ? runTime.regionNames() :wordList(1, args.optionFound("region") ? args.optionRead< word >("region") :polyMesh::defaultRegion))
Return the vol-field velocity corresponding to a given surface-field velocity.