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 nCouplesRemoved +=
min(indices[proci].size() - i, 0);
605 nCouplesAdded +=
min(indicesRef[proci].size() - refi, 0);
607 indicesRef[proci].append(removedIndices);
612 reduce(nCouplesRemoved, sumOp<label>());
613 reduce(nCouplesAdded, sumOp<label>());
614 if ((nCouplesRemoved || nCouplesAdded) && owner)
616 Info<<
indent << nCouplesRemoved <<
'/' << nCouplesAdded
617 <<
" small couplings removed/added to " << ncFvp.
name()
622 Swap(indices, indicesRef);
628 const List<FixedList<label, 3>>& indices
632 while (
n > 0 && indices[
n - 1][2] < 0)
n --;
637 void Foam::fvMeshStitcher::createCouplings
642 const tmp<surfaceVectorField::Boundary>& tOrigSfNbrBf,
643 const tmp<surfaceVectorField::Boundary>& tOrigCfNbrBf,
644 const List<List<FixedList<label, 3>>>& indices,
645 const List<DynamicList<couple>>& couples,
646 const polyPatch& origPp,
656 const label patchOffset = patchOffsets[proci];
660 forAll(indices[proci], indexi)
662 const label origFacei = indices[proci][indexi][!owner];
663 const label i = indices[proci][indexi][2];
665 const label patchFacei = i >= 0 ? indexi + patchOffset : -1;
670 c = couples[origFacei][
mag(i) - 1];
679 small*origPp.faceAreas()[origFacei],
680 origPp.faceCentres()[origFacei]
684 small*tOrigSfNbrBf()[
patchi][patchFacei],
685 tOrigCfNbrBf()[
patchi][patchFacei]
693 const part& pThis =
c, & pOther = owner ?
c.nbr :
c;
700 SfBf[origPp.index()][origFacei],
701 CfBf[origPp.index()][origFacei]
704 if (i < 0 && owner) origP += pOther;
706 SfBf[origPp.index()][origFacei] = origP.area;
707 CfBf[origPp.index()][origFacei] = origP.centre;
713 polyFacesBf[
patchi][patchFacei] =
714 origFacei + origPp.start();
715 SfBf[
patchi][patchFacei] = pOther.area;
716 CfBf[
patchi][patchFacei] = pOther.centre;
724 void Foam::fvMeshStitcher::createErrorAndEdgeParts
728 List<part>& origEdgeParts,
729 const patchToPatches::intersection& intersection,
730 const polyPatch& origPp
734 forAll(intersection.srcErrorParts(), origFacei)
738 SfBf[origPp.index()][origFacei],
739 CfBf[origPp.index()][origFacei]
741 origP += intersection.srcErrorParts()[origFacei];
743 SfBf[origPp.index()][origFacei] = origP.area;
744 CfBf[origPp.index()][origFacei] = origP.centre;
748 forAll(intersection.srcEdgeParts(), origEdgei)
750 origEdgeParts[origEdgei] += intersection.srcEdgeParts()[origEdgei];
755 void Foam::fvMeshStitcher::intersectNonConformalCyclic
757 const nonConformalCyclicFvPatch& nccFvp,
761 const tmp<surfaceLabelField::Boundary>& tOrigFacesNbrBf,
762 const tmp<surfaceVectorField::Boundary>& tOrigSfNbrBf,
763 const tmp<surfaceVectorField::Boundary>& tOrigCfNbrBf,
764 List<part>& origEdgeParts
768 const polyPatch& origPp = nccFvp.origPatch().patch();
774 forAll(mesh_.boundary(), patchj)
776 const fvPatch& fvp = mesh_.boundary()[patchj];
778 if (isA<nonConformalProcessorCyclicFvPatch>(fvp))
780 const nonConformalProcessorCyclicFvPatch& ncpcFvp =
781 refCast<const nonConformalProcessorCyclicFvPatch>(fvp);
783 if (ncpcFvp.referPatchIndex() == nccFvp.index())
785 patchis[ncpcFvp.neighbProcNo()] = patchj;
791 const patchToPatches::intersection& intersection =
793 ? nccFvp.nonConformalCyclicPatch().intersection()
794 : nccFvp.nbrPatch().nonConformalCyclicPatch().intersection();
797 List<List<FixedList<label, 3>>> indices =
801 ? intersection.srcTgtProcFaces()
802 : intersection.tgtSrcProcFaces(),
807 if (tOrigFacesNbrBf.valid())
812 if (patchis[proci] != -1)
814 patchSizes[proci] = polyFacesBf[patchis[proci]].size();
837 const label patchSize = nValidIndices(indices[proci]);
839 if (
patchi == -1 && patchSize)
842 <<
"Intersection generated coupling through "
843 << nccFvp.name() <<
" between processes "
845 <<
" but a corresponding processor interface was not found"
851 polyFacesBf[
patchi].resize(patchSize);
852 SfBf[
patchi].resize(patchSize);
853 CfBf[
patchi].resize(patchSize);
867 nccFvp.owner() ? intersection.srcCouples() : intersection.tgtCouples(),
877 createErrorAndEdgeParts
889 void Foam::fvMeshStitcher::intersectNonConformalMappedWall
891 const nonConformalMappedWallFvPatch& ncmwFvp,
895 const tmp<surfaceLabelField::Boundary>& tOrigFacesNbrBf,
896 const tmp<surfaceVectorField::Boundary>& tOrigSfNbrBf,
897 const tmp<surfaceVectorField::Boundary>& tOrigCfNbrBf,
898 List<part>& origEdgeParts
902 const polyPatch& origPp = ncmwFvp.origPatch().patch();
905 const patchToPatches::intersection& intersection =
907 ? ncmwFvp.nonConformalMappedWallPatch().intersection()
908 : ncmwFvp.nbrPatch().nonConformalMappedWallPatch().intersection();
911 List<List<FixedList<label, 3>>> indices =
915 ? intersection.srcTgtProcFaces()
916 : intersection.tgtSrcProcFaces(),
921 nonConformalMappedPolyFacesFvsPatchLabelField& polyFacesPf =
922 refCast<nonConformalMappedPolyFacesFvsPatchLabelField>
924 polyFacesBf[ncmwFvp.index()]
928 if (tOrigFacesNbrBf.valid())
938 polyFacesPf.procOffsets(),
939 polyFacesPf.procSizes(),
950 polyFacesPf.procOffsets()[proci] =
count;
952 count += nValidIndices(indices[proci]);
955 polyFacesPf.resize(
count);
956 SfBf[polyFacesPf.patch().index()].resize(
count);
957 CfBf[polyFacesPf.patch().index()].resize(
count);
970 ncmwFvp.owner() ? intersection.srcCouples() : intersection.tgtCouples(),
973 polyFacesPf.procOffsets(),
980 createErrorAndEdgeParts
993 Foam::fvMeshStitcher::calculateOwnerOrigBoundaryEdgeParts
995 const List<List<part>>& patchEdgeParts
998 const polyBoundaryMesh& pbMesh = mesh_.boundaryMesh();
1001 const labelList& ownerOrigBoundaryPointMeshPoint =
1002 ncb.ownerOrigBoundaryPointMeshPoint();
1003 const labelList& ownerOrigBoundaryEdgeMeshEdge =
1004 ncb.ownerOrigBoundaryEdgeMeshEdge();
1005 const edgeList& ownerOrigBoundaryEdges = ncb.ownerOrigBoundaryEdges();
1006 const edgeList& ownerOrigBoundaryMeshEdges =
1007 ncb.ownerOrigBoundaryMeshEdges();
1010 labelList ownerOrigBoundaryEdgeNParts(ownerOrigBoundaryEdges.size(), 0);
1011 List<part> ownerOrigBoundaryEdgeParts(ownerOrigBoundaryEdges.size());
1014 if (patchEdgeParts[
patchi].empty())
continue;
1016 const polyPatch& patch = pbMesh[
patchi];
1018 const labelList& patchEdgeOwnerOrigBoundaryEdges =
1019 ncb.patchEdgeOwnerOrigBoundaryEdges(
patchi);
1023 const label ownerOrigBoundaryEdgei =
1024 patchEdgeOwnerOrigBoundaryEdges[patchEdgei];
1030 ownerOrigBoundaryMeshEdges[ownerOrigBoundaryEdgei]
1033 const part& pU = patchEdgeParts[
patchi][patchEdgei];
1034 const part
p =
sign > 0 ? pU : -pU;
1036 ownerOrigBoundaryEdgeNParts[ownerOrigBoundaryEdgei] ++;
1037 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei] +=
p;
1042 const globalIndex globalOwnerOrigBoundaryPoints
1044 ownerOrigBoundaryPointMeshPoint.size()
1048 ownerOrigBoundaryPointMeshPoint.size()
1050 forAll(ownerOrigBoundaryPointIndices, ownerOrigBoundaryPointi)
1052 ownerOrigBoundaryPointIndices[ownerOrigBoundaryPointi] =
1053 globalOwnerOrigBoundaryPoints.toGlobal(ownerOrigBoundaryPointi);
1058 ownerOrigBoundaryPointMeshPoint,
1059 ownerOrigBoundaryPointIndices,
1067 forAll(ownerOrigBoundaryEdgeParts, ownerOrigBoundaryEdgei)
1069 const edge&
e = ownerOrigBoundaryEdges[ownerOrigBoundaryEdgei];
1073 ownerOrigBoundaryPointIndices[
e.start()]
1074 > ownerOrigBoundaryPointIndices[
e.end()])
1076 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei] =
1077 - ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei];
1085 ownerOrigBoundaryEdgeMeshEdge,
1086 ownerOrigBoundaryEdgeNParts,
1093 ownerOrigBoundaryEdgeMeshEdge,
1094 ownerOrigBoundaryEdgeParts,
1099 const transformer& vt,
1110 fld[i].area = vt.transform(
fld[i].area);
1111 fld[i].centre = vt.transformPosition(
fld[i].centre);
1121 fld[i].area = vt.invTransform(
fld[i].area);
1122 fld[i].centre = vt.invTransformPosition(
fld[i].centre);
1128 forAll(ownerOrigBoundaryEdgeParts, ownerOrigBoundaryEdgei)
1130 if (ownerOrigBoundaryEdgeNParts[ownerOrigBoundaryEdgei] != 0)
1132 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei].area /=
1133 ownerOrigBoundaryEdgeNParts[ownerOrigBoundaryEdgei];
1138 forAll(ownerOrigBoundaryEdgeParts, ownerOrigBoundaryEdgei)
1140 const edge&
e = ownerOrigBoundaryEdges[ownerOrigBoundaryEdgei];
1144 ownerOrigBoundaryPointIndices[
e.start()]
1145 > ownerOrigBoundaryPointIndices[
e.end()]
1148 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei] =
1149 - ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei];
1153 return ownerOrigBoundaryEdgeParts;
1157 void Foam::fvMeshStitcher::applyOwnerOrigBoundaryEdgeParts
1161 const List<part>& ownerOrigBoundaryEdgeParts
1164 const polyBoundaryMesh& pbMesh = mesh_.boundaryMesh();
1167 const labelList ownerOrigPatchIndices = ncb.ownerOrigPatchIndices();
1168 const labelList& ownerOrigBoundaryEdgeMeshEdge =
1169 ncb.ownerOrigBoundaryEdgeMeshEdge();
1170 const edgeList& ownerOrigBoundaryMeshEdges =
1171 ncb.ownerOrigBoundaryMeshEdges();
1173 boolList patchIsOwnerOrig(pbMesh.size(),
false);
1174 UIndirectList<bool>(patchIsOwnerOrig, ownerOrigPatchIndices) =
true;
1177 labelList ownerOrigBoundaryEdgeNOrigFaces
1179 ownerOrigBoundaryEdgeMeshEdge.size(),
1182 forAll(ownerOrigBoundaryEdgeMeshEdge, ownerOrigBoundaryEdgei)
1184 const label meshEdgei =
1185 ownerOrigBoundaryEdgeMeshEdge[ownerOrigBoundaryEdgei];
1187 forAll(mesh_.edgeFaces()[meshEdgei], edgeFacei)
1189 const label facei = mesh_.edgeFaces()[meshEdgei][edgeFacei];
1192 mesh_.isInternalFace(facei)
1194 : pbMesh.patchIndices()[facei - mesh_.nInternalFaces()];
1198 ownerOrigBoundaryEdgeNOrigFaces[ownerOrigBoundaryEdgei] ++;
1207 ownerOrigBoundaryEdgeMeshEdge,
1208 ownerOrigBoundaryEdgeNOrigFaces,
1214 tmp<surfaceLabelField> tChanged =
1220 forAll(ownerOrigBoundaryEdgeMeshEdge, ownerOrigBoundaryEdgei)
1222 const label meshEdgei =
1223 ownerOrigBoundaryEdgeMeshEdge[ownerOrigBoundaryEdgei];
1225 const part& ownerOrigBoundaryEdgeP =
1226 ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei];
1228 switch (ownerOrigBoundaryEdgeNOrigFaces[ownerOrigBoundaryEdgei])
1239 label origFacei = -1, origPatchi = -1, origPatchFacei = -1;
1240 forAll(mesh_.edgeFaces()[meshEdgei], edgeFacei)
1242 const label facei = mesh_.edgeFaces()[meshEdgei][edgeFacei];
1245 mesh_.isInternalFace(facei)
1247 : pbMesh.patchIndices()[facei - mesh_.nInternalFaces()];
1253 origPatchFacei = facei - pbMesh[
patchi].start();
1258 if (origFacei != -1)
1261 SfSf.boundaryFieldRef()[origPatchi][origPatchFacei];
1263 CfSf.boundaryFieldRef()[origPatchi][origPatchFacei];
1266 mesh_.faces()[origFacei].edgeDirection
1268 ownerOrigBoundaryMeshEdges[ownerOrigBoundaryEdgei]
1271 part
p(area, centre);
1274 ? ownerOrigBoundaryEdgeP
1275 : -ownerOrigBoundaryEdgeP;
1283 [origPatchi][origPatchFacei] =
label(1);
1294 forAll(mesh_.edgeFaces()[meshEdgei], edgeFacei)
1296 const label facei = mesh_.edgeFaces()[meshEdgei][edgeFacei];
1299 mesh_.isInternalFace(facei)
1301 : pbMesh.patchIndices()[facei - mesh_.nInternalFaces()];
1308 const label patchFacei =
1314 : SfSf.boundaryFieldRef()[
patchi][patchFacei];
1318 : CfSf.boundaryFieldRef()[
patchi][patchFacei];
1321 mesh_.faces()[facei].edgeDirection
1323 ownerOrigBoundaryMeshEdges[ownerOrigBoundaryEdgei]
1326 part
p(area, centre);
1329 ? ownerOrigBoundaryEdgeP
1330 : -ownerOrigBoundaryEdgeP;
1335 if (debug &&
patchi != -1)
1348 <<
"Boundary is not manifold"
1358 tChanged->boundaryField();
1363 changedBf.boundaryNeighbourField()
1366 bool synchronised =
true;
1373 if (!isA<processorFvPatch>(changedPf.patch()))
continue;
1375 forAll(changedPf, patchFacei)
1377 if (changedPf[patchFacei] != changedNbrPf[patchFacei])
1380 changedPf.patch().start() + patchFacei;
1383 <<
"Face not synchronised with centre at "
1384 << mesh_.faceCentres()[facei] <<
endl;
1386 synchronised =
false;
1400 void Foam::fvMeshStitcher::stabiliseOrigPatchFaces
1407 const labelList allOrigPatchIndices = ncb.allOrigPatchIndices();
1409 forAll(allOrigPatchIndices, i)
1411 const label origPatchi = allOrigPatchIndices[i];
1412 const polyPatch& origPp = mesh_.boundaryMesh()[origPatchi];
1414 forAll(origPp, origPatchFacei)
1416 const vector& a = origPp.faceAreas()[origPatchFacei];
1417 const point&
c = origPp.faceCentres()[origPatchFacei];
1419 vector& Sf = SfBf[origPatchi][origPatchFacei];
1420 point& Cf = CfBf[origPatchi][origPatchFacei];
1434 dSfHat = (Sf & Sf)*a - (Sf & a)*Sf;
1439 part SAndCf(Sf, Cf);
1441 SAndCf += part(small*
mag(a)*dSfHat,
c);
1450 void Foam::fvMeshStitcher::intersect
1456 const bool matchTopology
1459 const polyBoundaryMesh& pbMesh = mesh_.boundaryMesh();
1462 const labelList ownerOrigPatchIndices = ncb.ownerOrigPatchIndices();
1463 const edgeList& ownerOrigBoundaryMeshEdges =
1464 ncb.ownerOrigBoundaryMeshEdges();
1471 List<List<part>> patchEdgeParts(mesh_.boundary().size());
1472 forAll(ownerOrigPatchIndices, i)
1474 const label origPatchi = ownerOrigPatchIndices[i];
1476 patchEdgeParts[origPatchi].resize
1478 mesh_.boundaryMesh()[origPatchi].nEdges(),
1486 tmp<surfaceLabelField::Boundary> tOrigFacesNbrBf;
1487 tmp<surfaceVectorField::Boundary> tOrigSfNbrBf;
1488 tmp<surfaceVectorField::Boundary> tOrigCfNbrBf;
1505 if (!patchCoupleds[
patchi])
continue;
1507 const fvPatch& fvp = mesh_.boundary()[
patchi];
1509 if (isA<nonConformalCyclicFvPatch>(fvp))
1511 const nonConformalCyclicFvPatch& nccFvp =
1512 refCast<const nonConformalCyclicFvPatch>(fvp);
1514 intersectNonConformalCyclic
1523 patchEdgeParts[nccFvp.origPatchIndex()]
1526 else if (isA<nonConformalProcessorCyclicFvPatch>(fvp))
1528 else if (isA<nonConformalMappedWallFvPatch>(fvp))
1530 const nonConformalMappedWallFvPatch& ncmwFvp =
1531 refCast<const nonConformalMappedWallFvPatch>(fvp);
1533 intersectNonConformalMappedWall
1542 patchEdgeParts[ncmwFvp.origPatchIndex()]
1548 <<
"Coupled patch type not recognised"
1557 if (patchCoupleds[
patchi])
continue;
1559 const fvPatch& fvp = mesh_.boundary()[
patchi];
1561 if (!isA<nonConformalFvPatch>(fvp))
continue;
1563 const polyPatch& origPp =
1564 refCast<const nonConformalFvPatch>(fvp).origPatch().patch();
1569 small*origPp.faceAreas(),
1570 polyFacesBf[
patchi] - origPp.start()
1575 origPp.faceCentres(),
1576 polyFacesBf[
patchi] - origPp.start()
1581 List<part> ownerOrigBoundaryEdgeParts =
1582 calculateOwnerOrigBoundaryEdgeParts(patchEdgeParts);
1586 forAll(ownerOrigPatchIndices, i)
1588 const label origPatchi = ownerOrigPatchIndices[i];
1589 const polyPatch& origPatch = pbMesh[origPatchi];
1591 const labelList& origPatchEdgeOwnerOrigBoundaryEdges =
1592 ncb.patchEdgeOwnerOrigBoundaryEdges(origPatchi);
1594 forAll(patchEdgeParts[origPatchi], origPatchEdgei)
1596 const label ownerOrigBoundaryEdgei =
1597 origPatchEdgeOwnerOrigBoundaryEdges[origPatchEdgei];
1602 meshEdge(origPatch, origPatchEdgei),
1603 ownerOrigBoundaryMeshEdges[ownerOrigBoundaryEdgei]
1607 patchEdgeParts[origPatchi][origPatchEdgei];
1610 ? ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei]
1611 : -ownerOrigBoundaryEdgeParts[ownerOrigBoundaryEdgei];
1613 forAll(origPatch.edgeFaces()[origPatchEdgei], patchEdgeFacei)
1615 const label patchFacei =
1616 origPatch.edgeFaces()[origPatchEdgei][patchEdgeFacei];
1619 origPatch.localFaces()[patchFacei].edgeDirection
1621 origPatch.edges()[origPatchEdgei]
1626 SfBf[origPatchi][patchFacei],
1627 CfBf[origPatchi][patchFacei]
1629 p +=
sign > 0 ? errorP : -errorP;
1631 SfBf[origPatchi][patchFacei] =
p.area;
1632 CfBf[origPatchi][patchFacei] =
p.centre;
1638 applyOwnerOrigBoundaryEdgeParts(SfSf, CfSf, ownerOrigBoundaryEdgeParts);
1641 stabiliseOrigPatchFaces(SfBf, CfBf);
1645 bool Foam::fvMeshStitcher::disconnectThis
1647 const bool changing,
1648 const bool geometric
1651 if (!stitches())
return false;
1656 ? this->patchCoupleds()
1663 preConformSurfaceFields();
1664 preConformVolFields();
1671 for (
label i = 1; i < mesh_.phi().nOldTimes(
false); ++ i)
1673 phi.oldTimeRef(i) == mesh_.phi().oldTime(i);
1675 conformCorrectMeshPhi(phi);
1684 resizePatchFields<SurfaceField>();
1685 resizePatchFields<VolField>();
1688 const polyTopoChangeMap map(mesh_);
1690 meshObjects::topoChange<fvMesh>(mesh_, map);
1691 meshObjects::topoChange<lduMesh>(mesh_, map);
1693 const_cast<Time&
>(mesh_.time()).functionObjects().topoChange(map);
1699 bool Foam::fvMeshStitcher::connectThis
1701 const bool changing,
1702 const bool geometric,
1706 if (!stitches())
return false;
1709 IOobject polyFacesBfIO(
word::null, mesh_.pointsInstance(), mesh_);
1717 const bool matchTopology =
1718 load && loadPolyFacesBf(polyFacesBfIO, polyFacesBf);
1722 (geometric || !matchTopology)
1723 ? this->patchCoupleds()
1724 :
boolList(mesh_.boundary().size(),
false);
1729 if (!patchCoupleds[
patchi])
continue;
1731 const fvPatch& fvp = mesh_.boundary()[
patchi];
1733 if (isA<nonConformalCyclicFvPatch>(fvp))
1735 const nonConformalCyclicFvPatch& nccFvp =
1736 refCast<const nonConformalCyclicFvPatch>(fvp);
1740 nccFvp.nonConformalCyclicPatch().intersection();
1743 else if (isA<nonConformalProcessorCyclicFvPatch>(fvp))
1745 else if (isA<nonConformalMappedWallFvPatch>(fvp))
1747 const nonConformalMappedWallFvPatch& ncmwFvp =
1748 refCast<const nonConformalMappedWallFvPatch>(fvp);
1750 const nonConformalMappedWallFvPatch& ownerNcmwFvp =
1751 ncmwFvp.owner() ? ncmwFvp : ncmwFvp.nbrPatch();
1753 ownerNcmwFvp.nonConformalMappedWallPatch().intersection();
1758 <<
"Coupled patch type not recognised"
1763 if (
any(patchCoupleds))
1773 intersect(polyFacesBf, Sf, Cf, patchCoupleds, matchTopology);
1779 createNonConformalCorrectMeshPhiGeometry(polyFacesBf, Sf, Cf);
1786 for (
label i = 1; i <= mesh_.phi().nOldTimes(
false); ++ i)
1788 phi.oldTimeRef(i) == mesh_.phi().oldTime(i);
1790 unconformCorrectMeshPhi(polyFacesBf, Sf, Cf, phi);
1791 mesh_.unconform(polyFacesBf, Sf, Cf, phi);
1795 mesh_.unconform(polyFacesBf, Sf, Cf);
1801 mesh_.setPolyFacesBfInstance(polyFacesBfIO.instance());
1805 resizePatchFields<SurfaceField>();
1806 resizePatchFields<VolField>();
1812 postUnconformSurfaceFields();
1813 postUnconformVolFields();
1817 mesh_.deltaCoeffs();
1819 if (
any(patchCoupleds))
1822 const scalar gMaxO =
gMax(o);
1823 Info<<
indent <<
"Cell min/average/max openness = "
1825 if (gMaxO > rootSmall)
1828 <<
"Maximum openness of " << gMaxO
1834 for (
label i = 0; i <= mesh_.phi().nOldTimes(
false); ++ i)
1837 const scalar gMaxVce =
gMax(vce);
1839 for (
label j = 0; j < i; ++ j)
Info<<
"old-";
1840 Info<< (i ?
"time " :
"") <<
"volume conservation error = "
1843 if (gMaxVce > rootSmall)
1846 <<
"Maximum volume conservation error of " << gMaxVce
1859 mesh_.phi().boundaryField()
1861 mfe += mesh_.phi().boundaryField().boundaryNeighbourField();
1864 label nNonProcPatches = 0;
1867 const fvPatch& fvp = mesh_.boundary()[
patchi];
1869 if (!isA<processorFvPatch>(fvp))
1871 if (nNonProcPatches !=
patchi)
1874 <<
"Processor patches do not follow non-processor "
1885 scalarField sumMfe(nNonProcPatches, 0), nSumMfe(nNonProcPatches, 0);
1889 const fvPatch& fvp = mesh_.boundary()[
patchi];
1891 const label nccPatchi =
1892 isA<nonConformalCyclicFvPatch>(fvp)
1893 ? refCast<const nonConformalCyclicFvPatch>(fvp)
1895 : isA<nonConformalProcessorCyclicFvPatch>(fvp)
1896 ? refCast<const nonConformalProcessorCyclicFvPatch>(fvp)
1900 if (nccPatchi != -1)
1905 nSumMfe[nccPatchi] += mfe[
patchi].size();
1910 reduce(minMfe, ListOp<minOp<scalar>>());
1911 reduce(sumMfe, ListOp<sumOp<scalar>>());
1912 reduce(nSumMfe, ListOp<sumOp<scalar>>());
1913 reduce(maxMfe, ListOp<maxOp<scalar>>());
1918 const fvPatch& fvp = mesh_.boundary()[
patchi];
1922 isA<nonConformalCyclicFvPatch>(fvp)
1923 && refCast<const nonConformalCyclicFvPatch>(fvp).owner()
1928 <<
" min/average/max mesh flux error = "
1937 const scalar gMaxPvf =
gMax(pvf);
1938 Info<<
indent <<
"Cell min/average/max projected volume fraction = "
1940 if (gMaxPvf > minWarnProjectedVolumeFraction_)
1943 <<
"Maximum projected volume fraction " << gMaxPvf <<
" may "
1944 <<
"cause instability." <<
nl <<
indent <<
"Volumetric "
1945 <<
"distortion can be minimised by making the side of the "
1946 <<
"interface" <<
nl <<
indent <<
"with smaller or more "
1947 <<
"finely layered cells the neighbour." <<
nl <<
indent
1948 <<
"This is done by specifying this side second to "
1949 <<
"createNonConformalCouples;" <<
nl <<
indent <<
"either on "
1950 <<
"the command line, or in the patches (and regions) entries "
1951 <<
"within" <<
nl <<
indent <<
"the "
1952 <<
"createNonConformalCouplesDict." <<
endl;
1956 if (
any(patchCoupleds))
1962 const polyTopoChangeMap map(mesh_);
1964 meshObjects::topoChange<fvMesh>(mesh_, map);
1965 meshObjects::topoChange<lduMesh>(mesh_, map);
1967 const_cast<Time&
>(mesh_.time()).functionObjects().topoChange(map);
1973 void Foam::fvMeshStitcher::preConformSurfaceFields()
1975 #define PreConformSurfaceFields(Type, nullArg) \
1976 preConformSurfaceFields<Type>();
1978 #undef PreConformSurfaceFields
1982 void Foam::fvMeshStitcher::preConformVolFields()
1984 #define PreConformVolFields(Type, nullArg) \
1985 preConformVolFields<Type>();
1987 #undef PreConformVolFields
1992 void Foam::fvMeshStitcher::postUnconformSurfaceFields<Foam::vector>()
1994 if (mesh_.topoChanged())
2004 if (
isNull(
U)) Uf.clearOldTimes();
2014 fields[i].boundaryFieldRefNoStoreOldTimes()
2020 void Foam::fvMeshStitcher::postUnconformSurfaceFields()
2022 #define PostUnconformSurfaceFields(Type, nullArg) \
2023 postUnconformSurfaceFields<Type>();
2025 #undef PostUnconformSurfaceFields
2029 void Foam::fvMeshStitcher::postUnconformVolFields()
2031 #define PostUnconformVolFields(Type, nullArg) \
2032 postUnconformVolFields<Type>();
2034 #undef PostUnconformVolFields
2037 const labelList origPatchIndices = ncb.allOrigPatchIndices();
2038 const labelList errorPatchIndices = ncb.allErrorPatchIndices();
2043 UPtrList<volVectorField> Us(
mesh().fields<volVectorField>());
2048 forAll(errorPatchIndices, i)
2050 const label errorPatchi = errorPatchIndices[i];
2051 const label origPatchi = origPatchIndices[i];
2054 U.boundaryFieldRefNoStoreOldTimes()[origPatchi];
2058 isA<movingWallVelocityFvPatchVectorField>(origUp)
2059 || isA<movingWallSlipVelocityFvPatchVectorField>(origUp)
2062 U.boundaryFieldRefNoStoreOldTimes().set
2065 new movingWallSlipVelocityFvPatchVectorField
2075 #define PostUnconformEvaluateVolFields(Type, nullArg) \
2076 postUnconformEvaluateVolFields<Type>();
2078 #undef PostUnconformEvaluateVolFields
2095 if (isA<nonConformalFvPatch>(mesh_.boundary()[
patchi]))
2097 Uf.boundaryFieldRefNoStoreOldTimes()[
patchi] ==
2098 UfInterpolated.boundaryField()[
patchi];
2109 boolList result(mesh_.boundary().size(),
false);
2116 if (isA<nonConformalCyclicFvPatch>(fvp))
2125 if (isA<nonConformalProcessorCyclicFvPatch>(fvp))
2128 refCast<const nonConformalProcessorCyclicFvPatch>(fvp);
2137 if (isA<nonConformalMappedWallFvPatch>(fvp))
2140 refCast<const nonConformalMappedWallFvPatch>(fvp);
2161 bool result =
false;
2167 if (!isA<nonConformalFvPatch>(fvp))
continue;
2170 mesh_.magSf().boundaryField()[
patchi];
2173 refCast<const nonConformalFvPatch>(fvp).origPatch().patch();
2181 if (
max(magSfp/origMagSfp) > rootSmall)
2201 (small*
sqr(
cbrt(mesh_.V())))()
2212 <<
"Can only compute volume conservation error for this time, or "
2219 n == 0 ? mesh_.time().deltaT() : mesh_.time().deltaT0();
2246 regionPolyFacesBfIOs_(),
2247 regionPolyFacesBfs_()
2262 if (!mesh_.local().empty())
2270 if (isA<nonConformalFvPatch>(mesh_.boundary()[
patchi]))
2282 const bool changing,
2283 const bool geometric
2287 if (mesh_.conformal())
return false;
2291 return disconnectThis(changing, geometric);
2298 bool result =
false;
2301 if (regionMeshes[i]().stitcher().disconnectThis(changing, geometric))
2313 const bool changing,
2314 const bool geometric,
2320 return connectThis(changing, geometric, load);
2336 if (!regionMeshes[i]().stitcher().ready_)
2343 bool result =
false;
2346 if (regionMeshes[i]().stitcher().connectThis(changing, geometric, load))
2355 regionMeshes[i]().stitcher().ready_ =
false;
2364 if (mesh_.conformal() || geometric == this->geometric())
2382 ? this->patchCoupleds()
2383 :
boolList(mesh_.boundary().size(),
false);
2390 intersect(polyFacesBf, Sf, Cf, patchCoupleds,
true);
2393 mesh_.unconform(polyFacesBf, Sf, Cf);
2396 mesh_.deltaCoeffs();
2401 meshObjects::topoChange<fvMesh>(mesh_, map);
2402 meshObjects::topoChange<lduMesh>(mesh_, map);
2404 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.