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
462 const List<List<remote>>& faceOtherProcFaces,
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,
526 List<List<FixedList<label, 3>>> indicesRef(indices.size());
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]);
554 label nCouplesRemoved = 0, nCouplesAdded = 0;
561 label refi = 0, i = 0;
563 DynamicList<FixedList<label, 3>> removedIndices;
567 refi < indicesRef[proci].size()
568 && i < indices[proci].size()
571 const FixedList<label, 3> index
573 indices[proci][i][0],
574 indices[proci][i][1],
578 FixedList<label, 3>& indexRef = indicesRef[proci][refi];
580 if (index < indexRef)
583 removedIndices.append
585 indices[proci][i][0],
586 indices[proci][i][1],
587 - indices[proci][i][2]
591 else if (index == indexRef)
593 indexRef[2] = indices[proci][i][2];
604 while (i < indices[proci].size())
607 removedIndices.append
609 indices[proci][i][0],
610 indices[proci][i][1],
611 - indices[proci][i][2]
616 nCouplesRemoved +=
min(indices[proci].size() - i, 0);
617 nCouplesAdded +=
min(indicesRef[proci].size() - refi, 0);
619 indicesRef[proci].append(removedIndices);
624 reduce(nCouplesRemoved, sumOp<label>());
625 reduce(nCouplesAdded, sumOp<label>());
626 if ((nCouplesRemoved || nCouplesAdded) && owner)
628 Info<<
indent << nCouplesRemoved <<
'/' << nCouplesAdded
629 <<
" small couplings removed/added to " << ncFvp.
name()
634 Swap(indices, indicesRef);
640 const List<FixedList<label, 3>>& indices
644 while (
n > 0 && indices[
n - 1][2] < 0)
n --;
649 void Foam::fvMeshStitcher::createCouplings
654 const tmp<surfaceVectorField::Boundary>& tOrigSfNbrBf,
655 const tmp<surfaceVectorField::Boundary>& tOrigCfNbrBf,
656 const List<List<FixedList<label, 3>>>& indices,
657 const List<DynamicList<couple>>& couples,
658 const polyPatch& origPp,
668 const label patchOffset = patchOffsets[proci];
672 forAll(indices[proci], indexi)
674 const label origFacei = indices[proci][indexi][!owner];
675 const label i = indices[proci][indexi][2];
677 const label patchFacei = i >= 0 ? indexi + patchOffset : -1;
682 c = couples[origFacei][
mag(i) - 1];
691 small*origPp.faceAreas()[origFacei],
692 origPp.faceCentres()[origFacei]
696 small*tOrigSfNbrBf()[
patchi][patchFacei],
697 tOrigCfNbrBf()[
patchi][patchFacei]
705 const part& pThis =
c, & pOther = owner ?
c.nbr :
c;
712 SfBf[origPp.index()][origFacei],
713 CfBf[origPp.index()][origFacei]
716 if (i < 0 && owner) origP += pOther;
718 SfBf[origPp.index()][origFacei] = origP.area;
719 CfBf[origPp.index()][origFacei] = origP.centre;
725 polyFacesBf[
patchi][patchFacei] =
726 origFacei + origPp.start();
727 SfBf[
patchi][patchFacei] = pOther.area;
728 CfBf[
patchi][patchFacei] = pOther.centre;
736 void Foam::fvMeshStitcher::createErrorAndEdgeParts
740 List<part>& origEdgeParts,
741 const patchToPatches::intersection& intersection,
742 const polyPatch& origPp
746 forAll(intersection.srcErrorParts(), origFacei)
750 SfBf[origPp.index()][origFacei],
751 CfBf[origPp.index()][origFacei]
753 origP += intersection.srcErrorParts()[origFacei];
755 SfBf[origPp.index()][origFacei] = origP.area;
756 CfBf[origPp.index()][origFacei] = origP.centre;
760 forAll(intersection.srcEdgeParts(), origEdgei)
762 origEdgeParts[origEdgei] += intersection.srcEdgeParts()[origEdgei];
767 void Foam::fvMeshStitcher::intersectNonConformalCyclic
769 const nonConformalCyclicFvPatch& nccFvp,
773 const tmp<surfaceLabelField::Boundary>& tOrigFacesNbrBf,
774 const tmp<surfaceVectorField::Boundary>& tOrigSfNbrBf,
775 const tmp<surfaceVectorField::Boundary>& tOrigCfNbrBf,
776 List<part>& origEdgeParts
780 const polyPatch& origPp = nccFvp.origPatch().patch();
786 forAll(mesh_.boundary(), patchj)
788 const fvPatch& fvp = mesh_.boundary()[patchj];
790 if (isA<nonConformalProcessorCyclicFvPatch>(fvp))
792 const nonConformalProcessorCyclicFvPatch& ncpcFvp =
793 refCast<const nonConformalProcessorCyclicFvPatch>(fvp);
795 if (ncpcFvp.referPatchIndex() == nccFvp.index())
797 patchis[ncpcFvp.neighbProcNo()] = patchj;
803 const patchToPatches::intersection& intersection =
805 ? nccFvp.nonConformalCyclicPatch().intersection()
806 : nccFvp.nbrPatch().nonConformalCyclicPatch().intersection();
809 List<List<FixedList<label, 3>>> indices =
813 ? intersection.srcTgtProcFaces()
814 : intersection.tgtSrcProcFaces(),
819 if (tOrigFacesNbrBf.valid())
824 if (patchis[proci] != -1)
826 patchSizes[proci] = polyFacesBf[patchis[proci]].size();
849 const label patchSize = nValidIndices(indices[proci]);
851 if (
patchi == -1 && patchSize)
854 <<
"Intersection generated coupling through "
855 << nccFvp.name() <<
" between processes "
857 <<
" but a corresponding processor interface was not found"
863 polyFacesBf[
patchi].resize(patchSize);
864 SfBf[
patchi].resize(patchSize);
865 CfBf[
patchi].resize(patchSize);
879 nccFvp.owner() ? intersection.srcCouples() : intersection.tgtCouples(),
889 createErrorAndEdgeParts
901 void Foam::fvMeshStitcher::intersectNonConformalMappedWall
903 const nonConformalMappedWallFvPatch& ncmwFvp,
907 const tmp<surfaceLabelField::Boundary>& tOrigFacesNbrBf,
908 const tmp<surfaceVectorField::Boundary>& tOrigSfNbrBf,
909 const tmp<surfaceVectorField::Boundary>& tOrigCfNbrBf,
910 List<part>& origEdgeParts
914 const polyPatch& origPp = ncmwFvp.origPatch().patch();
917 const patchToPatches::intersection& intersection =
919 ? ncmwFvp.nonConformalMappedWallPatch().intersection()
920 : ncmwFvp.nbrPatch().nonConformalMappedWallPatch().intersection();
923 List<List<FixedList<label, 3>>> indices =
927 ? intersection.srcTgtProcFaces()
928 : intersection.tgtSrcProcFaces(),
933 nonConformalMappedPolyFacesFvsPatchLabelField& polyFacesPf =
934 refCast<nonConformalMappedPolyFacesFvsPatchLabelField>
936 polyFacesBf[ncmwFvp.index()]
940 if (tOrigFacesNbrBf.valid())
950 polyFacesPf.procOffsets(),
951 polyFacesPf.procSizes(),
962 polyFacesPf.procOffsets()[proci] =
count;
964 count += nValidIndices(indices[proci]);
967 polyFacesPf.resize(
count);
968 SfBf[polyFacesPf.patch().index()].resize(
count);
969 CfBf[polyFacesPf.patch().index()].resize(
count);
982 ncmwFvp.owner() ? intersection.srcCouples() : intersection.tgtCouples(),
985 polyFacesPf.procOffsets(),
992 createErrorAndEdgeParts
1005 Foam::fvMeshStitcher::calculateOwnerOrigBoundaryEdgeParts
1007 const List<List<part>>& patchEdgeParts
1010 const polyBoundaryMesh& pbMesh = mesh_.boundaryMesh();
1013 const labelList& ownerOrigBoundaryPointMeshPoint =
1014 ncb.ownerOrigBoundaryPointMeshPoint();
1015 const labelList& ownerOrigBoundaryEdgeMeshEdge =
1016 ncb.ownerOrigBoundaryEdgeMeshEdge();
1017 const edgeList& ownerOrigBoundaryEdges = ncb.ownerOrigBoundaryEdges();
1018 const edgeList& ownerOrigBoundaryMeshEdges =
1019 ncb.ownerOrigBoundaryMeshEdges();
1022 labelList ownerOrigBoundaryEdgeNParts(ownerOrigBoundaryEdges.size(), 0);
1023 List<part> ownerOrigBoundaryEdgeParts(ownerOrigBoundaryEdges.size());
1026 if (patchEdgeParts[
patchi].empty())
continue;
1028 const polyPatch& patch = pbMesh[
patchi];
1030 const labelList& patchEdgeOwnerOrigBoundaryEdges =
1031 ncb.patchEdgeOwnerOrigBoundaryEdges(
patchi);
1035 const label ownerOrigBoundaryEdgei =
1036 patchEdgeOwnerOrigBoundaryEdges[patchEdgei];
1042 ownerOrigBoundaryMeshEdges[ownerOrigBoundaryEdgei]
1045 const part& pU = patchEdgeParts[
patchi][patchEdgei];
1046 const part
p =
sign > 0 ? pU : -pU;
1048 ownerOrigBoundaryEdgeNParts[ownerOrigBoundaryEdgei] ++;
1049 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei] +=
p;
1054 const globalIndex globalOwnerOrigBoundaryPoints
1056 ownerOrigBoundaryPointMeshPoint.size()
1060 ownerOrigBoundaryPointMeshPoint.size()
1062 forAll(ownerOrigBoundaryPointIndices, ownerOrigBoundaryPointi)
1064 ownerOrigBoundaryPointIndices[ownerOrigBoundaryPointi] =
1065 globalOwnerOrigBoundaryPoints.toGlobal(ownerOrigBoundaryPointi);
1070 ownerOrigBoundaryPointMeshPoint,
1071 ownerOrigBoundaryPointIndices,
1079 forAll(ownerOrigBoundaryEdgeParts, ownerOrigBoundaryEdgei)
1081 const edge&
e = ownerOrigBoundaryEdges[ownerOrigBoundaryEdgei];
1085 ownerOrigBoundaryPointIndices[
e.start()]
1086 > ownerOrigBoundaryPointIndices[
e.end()])
1088 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei] =
1089 - ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei];
1097 ownerOrigBoundaryEdgeMeshEdge,
1098 ownerOrigBoundaryEdgeNParts,
1105 ownerOrigBoundaryEdgeMeshEdge,
1106 ownerOrigBoundaryEdgeParts,
1111 const transformer& vt,
1122 fld[i].area = vt.transform(
fld[i].area);
1123 fld[i].centre = vt.transformPosition(
fld[i].centre);
1133 fld[i].area = vt.invTransform(
fld[i].area);
1134 fld[i].centre = vt.invTransformPosition(
fld[i].centre);
1140 forAll(ownerOrigBoundaryEdgeParts, ownerOrigBoundaryEdgei)
1142 if (ownerOrigBoundaryEdgeNParts[ownerOrigBoundaryEdgei] != 0)
1144 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei].area /=
1145 ownerOrigBoundaryEdgeNParts[ownerOrigBoundaryEdgei];
1150 forAll(ownerOrigBoundaryEdgeParts, ownerOrigBoundaryEdgei)
1152 const edge&
e = ownerOrigBoundaryEdges[ownerOrigBoundaryEdgei];
1156 ownerOrigBoundaryPointIndices[
e.start()]
1157 > ownerOrigBoundaryPointIndices[
e.end()]
1160 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei] =
1161 - ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei];
1165 return ownerOrigBoundaryEdgeParts;
1169 void Foam::fvMeshStitcher::applyOwnerOrigBoundaryEdgeParts
1173 const List<part>& ownerOrigBoundaryEdgeParts
1176 const polyBoundaryMesh& pbMesh = mesh_.boundaryMesh();
1179 const labelList ownerOrigPatchIndices = ncb.ownerOrigPatchIndices();
1180 const labelList& ownerOrigBoundaryEdgeMeshEdge =
1181 ncb.ownerOrigBoundaryEdgeMeshEdge();
1182 const edgeList& ownerOrigBoundaryMeshEdges =
1183 ncb.ownerOrigBoundaryMeshEdges();
1185 boolList patchIsOwnerOrig(pbMesh.size(),
false);
1186 UIndirectList<bool>(patchIsOwnerOrig, ownerOrigPatchIndices) =
true;
1189 labelList ownerOrigBoundaryEdgeNOrigFaces
1191 ownerOrigBoundaryEdgeMeshEdge.size(),
1194 forAll(ownerOrigBoundaryEdgeMeshEdge, ownerOrigBoundaryEdgei)
1196 const label meshEdgei =
1197 ownerOrigBoundaryEdgeMeshEdge[ownerOrigBoundaryEdgei];
1199 forAll(mesh_.edgeFaces()[meshEdgei], edgeFacei)
1201 const label facei = mesh_.edgeFaces()[meshEdgei][edgeFacei];
1204 mesh_.isInternalFace(facei)
1206 : pbMesh.patchIndices()[facei - mesh_.nInternalFaces()];
1210 ownerOrigBoundaryEdgeNOrigFaces[ownerOrigBoundaryEdgei] ++;
1219 ownerOrigBoundaryEdgeMeshEdge,
1220 ownerOrigBoundaryEdgeNOrigFaces,
1226 tmp<surfaceLabelField> tChanged =
1232 forAll(ownerOrigBoundaryEdgeMeshEdge, ownerOrigBoundaryEdgei)
1234 const label meshEdgei =
1235 ownerOrigBoundaryEdgeMeshEdge[ownerOrigBoundaryEdgei];
1237 const part& ownerOrigBoundaryEdgeP =
1238 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei];
1240 switch (ownerOrigBoundaryEdgeNOrigFaces[ownerOrigBoundaryEdgei])
1251 label origFacei = -1, origPatchi = -1, origPatchFacei = -1;
1252 forAll(mesh_.edgeFaces()[meshEdgei], edgeFacei)
1254 const label facei = mesh_.edgeFaces()[meshEdgei][edgeFacei];
1257 mesh_.isInternalFace(facei)
1259 : pbMesh.patchIndices()[facei - mesh_.nInternalFaces()];
1265 origPatchFacei = facei - pbMesh[
patchi].start();
1270 if (origFacei != -1)
1273 SfSf.boundaryFieldRef()[origPatchi][origPatchFacei];
1275 CfSf.boundaryFieldRef()[origPatchi][origPatchFacei];
1278 mesh_.faces()[origFacei].edgeDirection
1280 ownerOrigBoundaryMeshEdges[ownerOrigBoundaryEdgei]
1283 part
p(area, centre);
1286 ? ownerOrigBoundaryEdgeP
1287 : -ownerOrigBoundaryEdgeP;
1295 [origPatchi][origPatchFacei] =
label(1);
1306 forAll(mesh_.edgeFaces()[meshEdgei], edgeFacei)
1308 const label facei = mesh_.edgeFaces()[meshEdgei][edgeFacei];
1311 mesh_.isInternalFace(facei)
1313 : pbMesh.patchIndices()[facei - mesh_.nInternalFaces()];
1320 const label patchFacei =
1326 : SfSf.boundaryFieldRef()[
patchi][patchFacei];
1330 : CfSf.boundaryFieldRef()[
patchi][patchFacei];
1333 mesh_.faces()[facei].edgeDirection
1335 ownerOrigBoundaryMeshEdges[ownerOrigBoundaryEdgei]
1338 part
p(area, centre);
1341 ? ownerOrigBoundaryEdgeP
1342 : -ownerOrigBoundaryEdgeP;
1347 if (debug &&
patchi != -1)
1360 <<
"Boundary is not manifold"
1370 tChanged->boundaryField();
1375 changedBf.boundaryNeighbourField()
1378 bool synchronised =
true;
1385 if (!isA<processorFvPatch>(changedPf.patch()))
continue;
1387 forAll(changedPf, patchFacei)
1389 if (changedPf[patchFacei] != changedNbrPf[patchFacei])
1392 changedPf.patch().start() + patchFacei;
1395 <<
"Face not synchronised with centre at "
1396 << mesh_.faceCentres()[facei] <<
endl;
1398 synchronised =
false;
1412 void Foam::fvMeshStitcher::stabiliseOrigPatchFaces
1419 const labelList allOrigPatchIndices = ncb.allOrigPatchIndices();
1421 forAll(allOrigPatchIndices, i)
1423 const label origPatchi = allOrigPatchIndices[i];
1424 const polyPatch& origPp = mesh_.boundaryMesh()[origPatchi];
1426 forAll(origPp, origPatchFacei)
1428 const vector& a = origPp.faceAreas()[origPatchFacei];
1429 const point&
c = origPp.faceCentres()[origPatchFacei];
1431 vector& Sf = SfBf[origPatchi][origPatchFacei];
1432 point& Cf = CfBf[origPatchi][origPatchFacei];
1446 dSfHat = (Sf & Sf)*a - (Sf & a)*Sf;
1451 part SAndCf(Sf, Cf);
1453 SAndCf += part(small*
mag(a)*dSfHat,
c);
1462 void Foam::fvMeshStitcher::intersect
1468 const bool matchTopology
1471 const polyBoundaryMesh& pbMesh = mesh_.boundaryMesh();
1474 const labelList ownerOrigPatchIndices = ncb.ownerOrigPatchIndices();
1475 const edgeList& ownerOrigBoundaryMeshEdges =
1476 ncb.ownerOrigBoundaryMeshEdges();
1483 List<List<part>> patchEdgeParts(mesh_.boundary().size());
1484 forAll(ownerOrigPatchIndices, i)
1486 const label origPatchi = ownerOrigPatchIndices[i];
1488 patchEdgeParts[origPatchi].resize
1490 mesh_.boundaryMesh()[origPatchi].nEdges(),
1498 tmp<surfaceLabelField::Boundary> tOrigFacesNbrBf;
1499 tmp<surfaceVectorField::Boundary> tOrigSfNbrBf;
1500 tmp<surfaceVectorField::Boundary> tOrigCfNbrBf;
1517 if (!patchCoupleds[
patchi])
continue;
1519 const fvPatch& fvp = mesh_.boundary()[
patchi];
1521 if (isA<nonConformalCyclicFvPatch>(fvp))
1523 const nonConformalCyclicFvPatch& nccFvp =
1524 refCast<const nonConformalCyclicFvPatch>(fvp);
1526 intersectNonConformalCyclic
1535 patchEdgeParts[nccFvp.origPatchIndex()]
1538 else if (isA<nonConformalProcessorCyclicFvPatch>(fvp))
1540 else if (isA<nonConformalMappedWallFvPatch>(fvp))
1542 const nonConformalMappedWallFvPatch& ncmwFvp =
1543 refCast<const nonConformalMappedWallFvPatch>(fvp);
1545 intersectNonConformalMappedWall
1554 patchEdgeParts[ncmwFvp.origPatchIndex()]
1560 <<
"Coupled patch type not recognised"
1569 if (patchCoupleds[
patchi])
continue;
1571 const fvPatch& fvp = mesh_.boundary()[
patchi];
1573 if (!isA<nonConformalFvPatch>(fvp))
continue;
1575 const polyPatch& origPp =
1576 refCast<const nonConformalFvPatch>(fvp).origPatch().patch();
1581 small*origPp.faceAreas(),
1582 polyFacesBf[
patchi] - origPp.start()
1587 origPp.faceCentres(),
1588 polyFacesBf[
patchi] - origPp.start()
1593 List<part> ownerOrigBoundaryEdgeParts =
1594 calculateOwnerOrigBoundaryEdgeParts(patchEdgeParts);
1598 forAll(ownerOrigPatchIndices, i)
1600 const label origPatchi = ownerOrigPatchIndices[i];
1601 const polyPatch& origPatch = pbMesh[origPatchi];
1603 const labelList& origPatchEdgeOwnerOrigBoundaryEdges =
1604 ncb.patchEdgeOwnerOrigBoundaryEdges(origPatchi);
1606 forAll(patchEdgeParts[origPatchi], origPatchEdgei)
1608 const label ownerOrigBoundaryEdgei =
1609 origPatchEdgeOwnerOrigBoundaryEdges[origPatchEdgei];
1614 meshEdge(origPatch, origPatchEdgei),
1615 ownerOrigBoundaryMeshEdges[ownerOrigBoundaryEdgei]
1619 patchEdgeParts[origPatchi][origPatchEdgei];
1622 ? ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei]
1623 : -ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei];
1625 forAll(origPatch.edgeFaces()[origPatchEdgei], patchEdgeFacei)
1627 const label patchFacei =
1628 origPatch.edgeFaces()[origPatchEdgei][patchEdgeFacei];
1631 origPatch.localFaces()[patchFacei].edgeDirection
1633 origPatch.edges()[origPatchEdgei]
1638 SfBf[origPatchi][patchFacei],
1639 CfBf[origPatchi][patchFacei]
1641 p +=
sign > 0 ? errorP : -errorP;
1643 SfBf[origPatchi][patchFacei] =
p.area;
1644 CfBf[origPatchi][patchFacei] =
p.centre;
1650 applyOwnerOrigBoundaryEdgeParts(SfSf, CfSf, ownerOrigBoundaryEdgeParts);
1653 stabiliseOrigPatchFaces(SfBf, CfBf);
1657 bool Foam::fvMeshStitcher::disconnectThis
1659 const bool changing,
1660 const bool geometric
1663 if (!stitches() || mesh_.conformal())
return false;
1668 ? this->patchCoupleds()
1675 preConformSurfaceFields();
1676 preConformVolFields();
1683 for (
label i = 1; i < mesh_.phi().nOldTimes(
false); ++ i)
1685 phi.oldTimeRef(i) == mesh_.phi().oldTime(i);
1687 conformCorrectMeshPhi(phi);
1696 resizePatchFields<SurfaceField>();
1697 resizePatchFields<VolField>();
1700 const polyTopoChangeMap map(mesh_);
1702 meshObjects::topoChange<fvMesh>(mesh_, map);
1703 meshObjects::topoChange<lduMesh>(mesh_, map);
1705 const_cast<Time&
>(mesh_.time()).functionObjects().topoChange(map);
1711 bool Foam::fvMeshStitcher::connectThis
1713 const bool changing,
1714 const bool geometric,
1718 if (!stitches() || !mesh_.conformal())
return false;
1721 IOobject polyFacesBfIO(
word::null, mesh_.pointsInstance(), mesh_);
1729 const bool matchTopology =
1730 load && loadPolyFacesBf(polyFacesBfIO, polyFacesBf);
1734 (geometric || !matchTopology)
1735 ? this->patchCoupleds()
1736 :
boolList(mesh_.boundary().size(),
false);
1741 if (!patchCoupleds[
patchi])
continue;
1743 const fvPatch& fvp = mesh_.boundary()[
patchi];
1745 if (isA<nonConformalCyclicFvPatch>(fvp))
1747 const nonConformalCyclicFvPatch& nccFvp =
1748 refCast<const nonConformalCyclicFvPatch>(fvp);
1752 nccFvp.nonConformalCyclicPatch().intersection();
1755 else if (isA<nonConformalProcessorCyclicFvPatch>(fvp))
1757 else if (isA<nonConformalMappedWallFvPatch>(fvp))
1759 const nonConformalMappedWallFvPatch& ncmwFvp =
1760 refCast<const nonConformalMappedWallFvPatch>(fvp);
1762 const nonConformalMappedWallFvPatch& ownerNcmwFvp =
1763 ncmwFvp.owner() ? ncmwFvp : ncmwFvp.nbrPatch();
1765 ownerNcmwFvp.nonConformalMappedWallPatch().intersection();
1770 <<
"Coupled patch type not recognised"
1775 if (
any(patchCoupleds))
1785 intersect(polyFacesBf, Sf, Cf, patchCoupleds, matchTopology);
1791 createNonConformalCorrectMeshPhiGeometry(polyFacesBf, Sf, Cf);
1798 for (
label i = 1; i <= mesh_.phi().nOldTimes(
false); ++ i)
1800 phi.oldTimeRef(i) == mesh_.phi().oldTime(i);
1802 unconformCorrectMeshPhi(polyFacesBf, Sf, Cf, phi);
1803 mesh_.unconform(polyFacesBf, Sf, Cf, phi);
1807 mesh_.unconform(polyFacesBf, Sf, Cf);
1813 mesh_.setPolyFacesBfInstance(polyFacesBfIO.instance());
1817 resizePatchFields<SurfaceField>();
1818 resizePatchFields<VolField>();
1824 postUnconformSurfaceFields();
1825 postUnconformVolFields();
1829 mesh_.deltaCoeffs();
1831 if (
any(patchCoupleds))
1834 const scalar gMaxO =
gMax(o);
1835 Info<<
indent <<
"Cell min/average/max openness = "
1837 if (gMaxO > rootSmall)
1840 <<
"Maximum openness of " << gMaxO
1846 for (
label i = 0; i <= mesh_.phi().nOldTimes(
false); ++ i)
1849 const scalar gMaxVce =
gMax(vce);
1851 for (
label j = 0; j < i; ++ j)
Info<<
"old-";
1852 Info<< (i ?
"time " :
"") <<
"volume conservation error = "
1855 if (gMaxVce > rootSmall)
1858 <<
"Maximum volume conservation error of " << gMaxVce
1871 mesh_.phi().boundaryField()
1873 mfe += mesh_.phi().boundaryField().boundaryNeighbourField();
1876 label nNonProcPatches = 0;
1879 const fvPatch& fvp = mesh_.boundary()[
patchi];
1881 if (!isA<processorFvPatch>(fvp))
1883 if (nNonProcPatches !=
patchi)
1886 <<
"Processor patches do not follow non-processor "
1897 scalarField sumMfe(nNonProcPatches, 0), nSumMfe(nNonProcPatches, 0);
1901 const fvPatch& fvp = mesh_.boundary()[
patchi];
1903 const label nccPatchi =
1904 isA<nonConformalCyclicFvPatch>(fvp)
1905 ? refCast<const nonConformalCyclicFvPatch>(fvp)
1907 : isA<nonConformalProcessorCyclicFvPatch>(fvp)
1908 ? refCast<const nonConformalProcessorCyclicFvPatch>(fvp)
1912 if (nccPatchi != -1)
1917 nSumMfe[nccPatchi] += mfe[
patchi].size();
1922 reduce(minMfe, ListOp<minOp<scalar>>());
1923 reduce(sumMfe, ListOp<sumOp<scalar>>());
1924 reduce(nSumMfe, ListOp<sumOp<scalar>>());
1925 reduce(maxMfe, ListOp<maxOp<scalar>>());
1930 const fvPatch& fvp = mesh_.boundary()[
patchi];
1934 isA<nonConformalCyclicFvPatch>(fvp)
1935 && refCast<const nonConformalCyclicFvPatch>(fvp).owner()
1940 <<
" min/average/max mesh flux error = "
1949 const scalar gMaxPvf =
gMax(pvf);
1950 Info<<
indent <<
"Cell min/average/max projected volume fraction = "
1952 if (gMaxPvf > minWarnProjectedVolumeFraction_)
1955 <<
"Maximum projected volume fraction " << gMaxPvf <<
" may "
1956 <<
"cause instability." <<
nl <<
indent <<
"Volumetric "
1957 <<
"distortion can be minimised by making the side of the "
1958 <<
"interface" <<
nl <<
indent <<
"with smaller or more "
1959 <<
"finely layered cells the neighbour." <<
nl <<
indent
1960 <<
"This is done by specifying this side second to "
1961 <<
"createNonConformalCouples;" <<
nl <<
indent <<
"either on "
1962 <<
"the command line, or in the patches (and regions) entries "
1963 <<
"within" <<
nl <<
indent <<
"the "
1964 <<
"createNonConformalCouplesDict." <<
endl;
1968 if (
any(patchCoupleds))
1974 const polyTopoChangeMap map(mesh_);
1976 meshObjects::topoChange<fvMesh>(mesh_, map);
1977 meshObjects::topoChange<lduMesh>(mesh_, map);
1979 const_cast<Time&
>(mesh_.time()).functionObjects().topoChange(map);
1985 void Foam::fvMeshStitcher::preConformSurfaceFields()
1987 #define PreConformSurfaceFields(Type, nullArg) \
1988 preConformSurfaceFields<Type>();
1990 #undef PreConformSurfaceFields
1994 void Foam::fvMeshStitcher::preConformVolFields()
1996 #define PreConformVolFields(Type, nullArg) \
1997 preConformVolFields<Type>();
1999 #undef PreConformVolFields
2004 void Foam::fvMeshStitcher::postUnconformSurfaceFields<Foam::vector>()
2006 if (mesh_.topoChanged())
2016 if (
isNull(
U)) Uf.clearOldTimes();
2026 fields[i].boundaryFieldRefNoStoreOldTimes()
2032 void Foam::fvMeshStitcher::postUnconformSurfaceFields()
2034 #define PostUnconformSurfaceFields(Type, nullArg) \
2035 postUnconformSurfaceFields<Type>();
2037 #undef PostUnconformSurfaceFields
2041 void Foam::fvMeshStitcher::postUnconformVolFields()
2043 #define PostUnconformVolFields(Type, nullArg) \
2044 postUnconformVolFields<Type>();
2046 #undef PostUnconformVolFields
2049 const labelList origPatchIndices = ncb.allOrigPatchIndices();
2050 const labelList errorPatchIndices = ncb.allErrorPatchIndices();
2055 UPtrList<volVectorField> Us(
mesh().fields<volVectorField>());
2060 forAll(errorPatchIndices, i)
2062 const label errorPatchi = errorPatchIndices[i];
2063 const label origPatchi = origPatchIndices[i];
2066 U.boundaryFieldRefNoStoreOldTimes()[origPatchi];
2070 isA<movingWallVelocityFvPatchVectorField>(origUp)
2071 || isA<movingWallSlipVelocityFvPatchVectorField>(origUp)
2074 U.boundaryFieldRefNoStoreOldTimes().set
2077 new movingWallSlipVelocityFvPatchVectorField
2087 #define PostUnconformEvaluateVolFields(Type, nullArg) \
2088 postUnconformEvaluateVolFields<Type>();
2090 #undef PostUnconformEvaluateVolFields
2107 if (isA<nonConformalFvPatch>(mesh_.boundary()[
patchi]))
2109 Uf.boundaryFieldRefNoStoreOldTimes()[
patchi] ==
2110 UfInterpolated.boundaryField()[
patchi];
2121 boolList result(mesh_.boundary().size(),
false);
2128 if (isA<nonConformalCyclicFvPatch>(fvp))
2137 if (isA<nonConformalProcessorCyclicFvPatch>(fvp))
2140 refCast<const nonConformalProcessorCyclicFvPatch>(fvp);
2149 if (isA<nonConformalMappedWallFvPatch>(fvp))
2152 refCast<const nonConformalMappedWallFvPatch>(fvp);
2173 bool result =
false;
2179 if (!isA<nonConformalFvPatch>(fvp))
continue;
2182 mesh_.magSf().boundaryField()[
patchi];
2185 refCast<const nonConformalFvPatch>(fvp).origPatch().patch();
2193 if (
max(magSfp/origMagSfp) > rootSmall)
2213 (small*
sqr(
cbrt(mesh_.V())))()
2224 <<
"Can only compute volume conservation error for this time, or "
2231 n == 0 ? mesh_.time().deltaT() : mesh_.time().deltaT0();
2258 regionPolyFacesBfIOs_(),
2259 regionPolyFacesBfs_()
2274 if (!mesh_.local().empty())
2282 if (isA<nonConformalFvPatch>(mesh_.boundary()[
patchi]))
2294 const bool changing,
2295 const bool geometric
2300 return disconnectThis(changing, geometric);
2307 bool result =
false;
2310 if (regionMeshes[i]().stitcher().disconnectThis(changing, geometric))
2322 const bool changing,
2323 const bool geometric,
2329 return connectThis(changing, geometric, load);
2345 if (!regionMeshes[i]().stitcher().ready_)
2352 bool result =
false;
2355 if (regionMeshes[i]().stitcher().connectThis(changing, geometric, load))
2364 regionMeshes[i]().stitcher().ready_ =
false;
2373 if (mesh_.conformal() || geometric == this->geometric())
return;
2388 ? this->patchCoupleds()
2389 :
boolList(mesh_.boundary().size(),
false);
2396 intersect(polyFacesBf, Sf, Cf, patchCoupleds,
true);
2399 mesh_.unconform(polyFacesBf, Sf, Cf);
2402 mesh_.deltaCoeffs();
2407 meshObjects::topoChange<fvMesh>(mesh_, map);
2408 meshObjects::topoChange<lduMesh>(mesh_, map);
2410 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 const DimensionedField< Type, GeoMesh, PrimitiveField > & null()
Return a null DimensionedField.
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".
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.
fvMeshStitcher(fvMesh &)
Construct from fvMesh.
tmp< DimensionedField< scalar, volMesh > > projectedVolumeFraction() const
Return the projected volume fraction for debugging/checking.
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?
fvMesh & mesh()
Return the fvMesh.
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
tmp< DimensionedField< scalar, volMesh > > openness() const
Return the non-dimensional cell openness for debugging/checking.
tmp< DimensionedField< scalar, volMesh > > volumeConservationError(const label n) const
Return the non-dimensional old-time volume conservation error.
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.
virtual label size() const
Return size.
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.
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Class containing mesh-to-mesh mapping information.
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.
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)
errorManipArg< error, int > exit(error &err, const int errNo=1)
List< word > wordList
A List of words.
VolField< vector > volVectorField
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
List< label > labelList
A List of labels.
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
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 dimless
const word & regionName(const solver ®ion)
SurfaceField< scalar > surfaceScalarField
SurfaceField< label > surfaceLabelField
const dimensionSet dimLength
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.
void mag(LagrangianPatchField< scalar > &f, const LagrangianPatchField< Type > &f1)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
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)
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 &)
defineTypeNameAndDebug(combustionModel, 0)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
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)
void sqr(LagrangianPatchField< typename outerProduct< Type, Type >::type > &f, const LagrangianPatchField< Type > &f1)
bool any(const boolList &l)
Type gAverage(const FieldField< Field, Type > &f)
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.
FOR_ALL_FIELD_TYPES(makeFieldSourceTypedef)
const dimensionSet dimArea
label count(const ListType &l, typename ListType::const_reference x)
Count the number of occurrences of a value in a list.
void magSqr(LagrangianPatchField< scalar > &f, const LagrangianPatchField< Type > &f1)
Type gMin(const FieldField< Field, Type > &f)
static const label labelMax
SurfaceField< vector > surfaceVectorField
dimensionSet perpendicular(const dimensionSet &)
Ostream & indent(Ostream &os)
Indent stream.
fvsPatchField< vector > fvsPatchVectorField
Type gMax(const FieldField< Field, Type > &f)
void cmptMag(LagrangianPatchField< Type > &f, const LagrangianPatchField< Type > &f1)
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 .controlDict().subDict("regionSolvers").toc() :wordList(1, args.optionFound("region") ? args.optionRead< word >("region") :polyMesh::defaultRegion))
Return the vol-field velocity corresponding to a given surface-field velocity.