57 distributedTriSurfaceMesh,
200 if (
y.first().hit() &&
y.second() <
x.second())
205 else if (
y.first().hit())
220 { distributionType::FOLLOW,
"follow" },
221 { distributionType::INDEPENDENT,
"independent" },
222 { distributionType::DISTRIBUTED,
"distributed" },
223 { distributionType::FROZEN,
"frozen" }
229 Foam::word Foam::distributedTriSurfaceMesh::findLocalInstance
238 io.time().findInstance
261 io.rootPath()/
io.globalCaseName()
262 /
io.instance()/
io.db().dbDir()/
io.local()/
io.name()
267 return io.instance();
271 const scalar startValue =
io.time().timeOutputValue();
275 label instIndex = ts.size()-1;
278 for (; instIndex >= 0; --instIndex)
280 if (ts[instIndex].value() <= startValue)
287 for (; instIndex >= 0; --instIndex)
290 if (ts[instIndex].
name() ==
io.instance())
297 io.rootPath()/
io.globalCaseName()
298 /ts[instIndex].name()/
io.db().dbDir()/
io.local()/
io.name()
303 return ts[instIndex].name();
312 if (!ts.size() || ts[0].name() !=
io.time().constant())
320 io.rootPath()/
io.globalCaseName()
321 /
io.time().constant()/
io.db().dbDir()/
io.local()/
io.name()
326 return io.time().constant();
338 return io.time().constant();
342 bool Foam::distributedTriSurfaceMesh::readSettings(
const bool undecomposed)
359 decomposeUsingBbs_ = dict_.getOrDefault<
bool>(
"decomposeUsingBbs",
true);
364 !distributionTypeNames_.readIfPresent
373 distType_ = DISTRIBUTED;
374 dict_.add(
"distributionType", distributionTypeNames_[distType_]);
378 if (!dict_.readIfPresent(
"mergeDistance", mergeDist_))
381 dict_.add(
"mergeDistance", mergeDist_);
385 if (!dict_.readIfPresent<label>(
"closed", surfaceClosed_))
394 surfaceClosed_ =
false;
396 dict_.add(
"closed", surfaceClosed_);
411 outsideVolType_ = vt;
415 if (undecomposed && surfaceClosed_)
423 const triSurface& surf = *
this;
426 const point outsidePt(localBb.max()+localBb.centre());
434 if (info.distance() < nearInfo.distance())
470 label volType = outsideVolType_;
472 outsideVolType_ = volumeType(volType);
489 void Foam::distributedTriSurfaceMesh::calcVertexNormals
491 const triSurface& surf,
492 List<FixedList<vector, 3>>& vn
496 vectorField pointNormals(surf.points().size(), vector::zero);
500 const vector n =
f.unitNormal(surf.points());
503 const label pointi =
f[fp];
504 pointNormals[pointi] +=
n;
507 pointNormals.normalise();
510 vn.resize_nocopy(surf.size());
518 vn[facei][fp] = pointNormals[
f[fp]];
525 bool Foam::distributedTriSurfaceMesh::isLocal
527 const List<treeBoundBox>& myBbs,
534 if (myBbs[bbi].contains(start) && myBbs[bbi].contains(
end))
605 void Foam::distributedTriSurfaceMesh::distributeSegment
607 const label segmenti,
611 DynamicList<segment>& allSegments,
612 DynamicList<label>& allSegmentMap,
613 List<DynamicList<label>>& sendMap
616 if (decomposeUsingBbs_)
632 const List<treeBoundBox>& bbs = procBb_[proci];
634 if (isLocal(bbs, start,
end))
636 sendMap[proci].
append(allSegments.size());
637 allSegmentMap.append(segmenti);
650 const List<treeBoundBox>& bbs = procBb_[proci];
654 const treeBoundBox& bb = bbs[bbi];
662 if (bb.intersects(start,
end, clipPt))
664 sendMap[proci].append(allSegments.size());
665 allSegmentMap.append(segmenti);
689 Foam::distributedTriSurfaceMesh::distributeSegments
694 List<segment>& allSegments,
709 DynamicList<segment> dynAllSegments(start.size());
711 DynamicList<label> dynAllSegmentMap(start.size());
718 dynSendMap[proci].reserve
744 sendMap[proci].transfer(dynSendMap[proci]);
747 allSegments.transfer(dynAllSegments);
748 allSegmentMap.transfer(dynAllSegmentMap);
755 void Foam::distributedTriSurfaceMesh::findLine
757 const bool nearestIntersection,
760 List<pointIndexHit>& info
765 Pout<<
"distributedTriSurfaceMesh::findLine :" 768 << start.size() <<
" rays" <<
endl;
770 addProfiling(findLine,
"distributedTriSurfaceMesh::findLine");
772 const indexedOctree<treeDataTriSurface>& octree =
tree();
778 info.setSize(start.size());
785 const globalIndex& triIndexer = globalTris();
797 if (nearestIntersection)
799 info[i] = octree.findLine(start[i],
end[i]);
803 info[i] = octree.findLineAny(start[i],
end[i]);
808 info[i].setIndex(triIndexer.toGlobal(info[i].index()));
810 end[i] = info[i].hitPoint();
840 List<segment> allSegments(start.size());
844 const autoPtr<mapDistribute> mapPtr
854 const mapDistribute& map = mapPtr();
856 label nOldAllSegments = allSegments.size();
862 map.distribute(allSegments);
869 List<pointIndexHit> intersections(allSegments.size());
873 if (nearestIntersection)
875 intersections[i] = octree.findLine
877 allSegments[i].first(),
878 allSegments[i].second()
883 intersections[i] = octree.findLineAny
885 allSegments[i].first(),
886 allSegments[i].second()
891 if (intersections[i].hit())
893 intersections[i].setIndex
895 triIndexer.toGlobal(intersections[i].index())
904 map.reverseDistribute(nOldAllSegments, intersections);
913 label segmenti = allSegmentMap[i];
923 else if (nearestIntersection)
928 start[segmenti].distSqr(allInfo.point())
929 < start[segmenti].distSqr(hitInfo.point())
940 void Foam::distributedTriSurfaceMesh::convertTriIndices
942 List<pointIndexHit>& info
946 const globalIndex& triIndexer = globalTris();
952 pi.setIndex(triIndexer.toGlobal(
pi.index()));
962 Foam::distributedTriSurfaceMesh::calcLocalQueries
964 const List<pointIndexHit>& info,
972 triangleIndex.setSize(info.size());
974 const globalIndex& triIndexer = globalTris();
990 label proci = triIndexer.whichProcID(info[i].index());
999 sendMap[proci].setSize(nSend[proci]);
1008 label proci = triIndexer.whichProcID(info[i].index());
1009 triangleIndex[i] = triIndexer.toLocal(proci, info[i].index());
1010 sendMap[proci][nSend[proci]++] = i;
1014 triangleIndex[i] = -1;
1023 mapPtr().distribute(triangleIndex);
1029 bool Foam::distributedTriSurfaceMesh::contains
1031 const List<treeBoundBox>& bbs,
1037 if (bbs[bbi].contains(sample))
1047 Foam::distributedTriSurfaceMesh::findBestProcs
1049 const point& centre,
1050 const scalar radiusSqr,
1061 procContains =
false;
1064 procOverlaps =
false;
1068 scalar minDistSqr = radiusSqr;
1073 const List<treeBoundBox>& bbs = procBb_[proci];
1077 if (bbs[bbi].contains(centre))
1082 if (!procContains[proci])
1084 procContains[proci] =
true;
1089 bbs[bbi].calcExtremities(centre, near, far);
1090 minDistSqr =
min(minDistSqr, centre.distSqr(far));
1097 return Tuple2<label, scalar>(nContain, minDistSqr);
1101 scalar maxDistSqr = radiusSqr;
1108 const List<treeBoundBox>& bbs = procBb_[proci];
1112 if (bbs[bbi].overlaps(centre, radiusSqr))
1115 bbs[bbi].calcExtremities(centre, near, far);
1117 scalar d2 = centre.distSqr(near);
1118 if (d2 < minDistSqr)
1121 maxDistSqr =
min(radiusSqr, centre.distSqr(far));
1133 procOverlaps[minProci] =
true;
1138 if (proci != minProci)
1140 const List<treeBoundBox>& bbs = procBb_[proci];
1143 if (bbs[bbi].overlaps(centre, maxDistSqr))
1145 procOverlaps[proci] =
true;
1153 return Tuple2<label, scalar>(nOverlap, maxDistSqr);
1158 Foam::label Foam::distributedTriSurfaceMesh::calcOverlappingProcs
1160 const point& centre,
1161 const scalar radiusSqr,
1166 label nOverlaps = 0;
1170 const List<treeBoundBox>& bbs = procBb_[proci];
1174 if (bbs[bbi].overlaps(centre, radiusSqr))
1176 overlaps[proci] =
true;
1190 Foam::distributedTriSurfaceMesh::calcLocalQueries
1192 const bool includeLocalProcessor,
1208 DynamicList<point> dynAllCentres(centres.size());
1209 DynamicList<scalar> dynAllRadiusSqr(centres.size());
1211 DynamicList<label> dynAllSegmentMap(centres.size());
1216 forAll(dynSendMap, proci)
1218 dynSendMap[proci].reserve
1232 calcOverlappingProcs
1239 forAll(procBbOverlaps, proci)
1243 procBbOverlaps[proci]
1245 includeLocalProcessor
1250 dynSendMap[proci].append(dynAllCentres.size());
1251 dynAllSegmentMap.append(centrei);
1252 dynAllCentres.append(centres[centrei]);
1253 dynAllRadiusSqr.append(radiusSqr[centrei]);
1262 sendMap[proci].transfer(dynSendMap[proci]);
1265 allCentres.transfer(dynAllCentres);
1266 allRadiusSqr.transfer(dynAllRadiusSqr);
1267 allSegmentMap.transfer(dynAllSegmentMap);
1276 const point& sample,
1277 const point& nearestPoint,
1282 const triSurface& surf = *
this;
1292 if (((sample - nearestPoint) &
n) > 0)
1303 Foam::label Foam::distributedTriSurfaceMesh::findOtherFace
1306 const label nearFacei,
1307 const label nearLabel
1310 const triSurface& surf = *
this;
1313 const edge
e(nearF[nearLabel], nearF[nearF.fcIndex(nearLabel)]);
1316 for (
const label facei :
pFaces)
1318 if (facei != nearFacei)
1320 if (surf[facei].contains(
e))
1330 void Foam::distributedTriSurfaceMesh::calcFaceFaces
1332 const triSurface&
s,
1337 faceFaces.setSize(
s.size());
1339 DynamicList<label> nbrs;
1343 const labelledTri&
f =
s[facei];
1345 nbrs.reserve(
f.
size());
1352 for (
const label otherFacei :
pFaces)
1354 if (otherFacei != facei)
1356 if (
s[otherFacei].contains(
e))
1358 if (!nbrs.find(otherFacei))
1360 nbrs.append(otherFacei);
1366 faceFaces[facei] = std::move(nbrs);
1371 void Foam::distributedTriSurfaceMesh::surfaceSide
1374 const List<pointIndexHit>& nearestInfo,
1375 List<volumeType>& volType
1380 Pout<<
"distributedTriSurfaceMesh::surfaceSide :" 1382 <<
" finding surface side given points on surface for " 1384 <<
" cached vertexnormals " << vertexNormals_.valid() <<
endl;
1390 labelList triangleIndex(nearestInfo.size());
1391 autoPtr<mapDistribute> mapPtr
1399 const mapDistribute& map = mapPtr();
1403 map.distribute(localSamples);
1406 List<pointIndexHit> localNearestInfo(nearestInfo);
1407 map.distribute(localNearestInfo);
1413 volType.setSize(triangleIndex.size());
1416 const triSurface& surf = *
this;
1426 const label facei = triangleIndex[i];
1428 const auto& vn = vertexNormals_()[facei];
1430 const point& sample = localSamples[i];
1432 const point& nearest = localNearestInfo[i].point();
1434 const vector sampleNearestVec(sample - nearest);
1438 const vector n = w[0]*vn[0]+w[1]*vn[1]+w[2]*vn[2];
1440 const scalar
c = (sampleNearestVec &
n);
1460 EdgeMap<labelPair> edgeToFaces;
1464 const label facei = triangleIndex[i];
1466 const point& sample = localSamples[i];
1469 label nearType, nearLabel;
1471 f.nearestPointClassify(sample,
points, nearType, nearLabel);
1473 const point& nearestPoint(pHit.point());
1477 const vector sampleNearestVec = (sample - nearestPoint);
1481 const scalar
c = (sampleNearestVec &
f.areaNormal(
points));
1499 label otherFacei = findOtherFace(pointFaces, facei, nearLabel);
1500 if (otherFacei != -1)
1503 edgeSide(sample, nearestPoint, facei, otherFacei);
1517 const label pointi =
f[nearLabel];
1519 const vector sampleNearestVec = (sample - nearestPoint);
1523 edgeToFaces.clear();
1525 scalar maxCosAngle = -GREAT;
1528 for (
const label facei :
pFaces)
1532 label fp =
f.
find(pointi);
1544 for (
const edge&
e : edges)
1546 auto iter = edgeToFaces.find(
e);
1549 if (iter().second() == -1)
1552 iter().second() = facei;
1555 scalar magEVec =
mag(eVec);
1557 if (magEVec > VSMALL)
1563 scalar cosAngle(sampleNearestVec&eVec);
1564 if (cosAngle > maxCosAngle)
1566 maxCosAngle = cosAngle;
1567 maxEdgeFaces = iter();
1587 for (
auto iter : edgeToFaces)
1589 if (iter[0] == -1 || iter[1] == -1)
1597 volType[i] = edgeSide
1665 map.constructHasFlip(),
1678 Pout<<
"distributedTriSurfaceMesh::surfaceSide :" 1680 <<
" given points on surface " 1689 const indexedOctree<treeDataTriSurface>&
tree,
1692 PackedList<2>& nodeTypes
1695 const auto& nod =
tree.nodes()[nodei];
1705 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
1707 const labelBits index = nod.subNodes_[octant];
1708 const treeBoundBox subBb(nod.bb_.subBbox(octant));
1710 if (subBb.intersects(tri))
1767 else if (subType != myType)
1787 void Foam::distributedTriSurfaceMesh::markMixedOverlap
1789 const indexedOctree<treeDataTriSurface>&
tree,
1790 PackedList<2>& nodeTypes
1800 PstreamBuffers pBufs;
1818 const triSurface subSurface
1827 UOPstream
os(proci, pBufs);
1833 pBufs.finishedSends();
1836 for (
const int proci : pBufs.allProcs())
1840 UIPstream is(proci, pBufs);
1843 const triSurface subSurface(is);
1862 for (
const auto& tri : subSurface)
1868 tri.tri(subSurface.points()),
1877 void Foam::distributedTriSurfaceMesh::collectLeafMids
1880 DynamicField<point>& midPoints
1883 const auto& nod =
tree().nodes()[nodeI];
1885 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
1887 const labelBits index = nod.subNodes_[octant];
1904 const treeBoundBox subBb = nod.bb_.subBbox(octant);
1905 midPoints.append(subBb.centre());
1913 const List<volumeType>& midPointTypes,
1915 PackedList<2>& nodeTypes,
1923 const auto& nod =
tree().nodes()[nodeI];
1927 for (
direction octant = 0; octant < nod.subNodes_.size(); octant++)
1931 const labelBits index = nod.subNodes_[octant];
1936 subType = calcVolumeType
1958 subType = midPointTypes[midPointi++];
1970 else if (subType != myType)
1979 void Foam::distributedTriSurfaceMesh::cacheVolumeType(PackedList<2>& nt)
const 1982 const indexedOctree<treeDataTriSurface>& t =
tree();
1983 const auto& nodes = t.nodes();
1986 DynamicField<point> midPoints(label(0.5*nodes.size()));
1989 collectLeafMids(0, midPoints);
1994 Pout<<
"distributedTriSurfaceMesh::cacheVolumeType :" 1996 <<
" triggering orientation caching for " 1997 << midPoints.size() <<
" leaf mids" <<
endl;
2001 List<volumeType> midVolTypes;
2007 List<pointIndexHit> nearestInfo;
2014 surfaceSide(midPoints, nearestInfo, midVolTypes);
2023 OBJstream outsideStr
2033 insideStr.write(
ln);
2037 outsideStr.write(
ln);
2041 <<
" have inside:" << insideStr.nVertices()
2042 <<
" have outside:" << outsideStr.nVertices()
2061 Pout<<
"distributedTriSurfaceMesh::cacheVolumeType :" 2063 <<
" done orientation caching for " 2064 << midPoints.size() <<
" leaf mids" <<
endl;
2075 const auto& nod =
tree().nodes()[nodeI];
2077 direction octant = nod.bb_.subOctant(sample);
2099 labelBits index = nod.subNodes_[octant];
2104 volumeType subType = cachedVolumeType
2122 <<
"Sample:" << sample <<
" node:" << nodeI
2123 <<
" with bb:" << nod.bb_ <<
nl 2124 <<
"Empty subnode has invalid volume type MIXED." 2133 <<
"Sample:" << sample <<
" at node:" << nodeI
2134 <<
" octant:" << octant
2135 <<
" with bb:" << nod.bb_.subBbox(octant) <<
nl 2136 <<
"Node has invalid volume type " << octantType
2145 Foam::distributedTriSurfaceMesh::decomposer()
const 2150 if (dict_.found(
"method"))
2154 Pout<<
"distributedTriSurfaceMesh::decomposer() :" 2155 <<
" constructing decomposer from provided dictionary " 2166 const auto* dictPtr =
2177 Pout<<
"distributedTriSurfaceMesh::decomposer() :" 2178 <<
" constructing decomposer from registered" 2179 <<
" dictionary " << *dictPtr <<
endl;
2186 if (!decomposeParDict_)
2188 decomposeParDict_.reset
2206 Pout<<
"distributedTriSurfaceMesh::decomposer() :" 2208 << decomposeParDict_().objectRelPath()
2217 return decomposer_();
2227 void Foam::distributedTriSurfaceMesh::independentlyDistributedBbs
2229 const triSurface&
s,
2231 List<List<treeBoundBox>>& bbs
2237 "distributedTriSurfaceMesh::independentlyDistributedBbs" 2244 const globalIndex& triIndexer = globalTris();
2251 if (triIndexer.localSize(proci) != 0)
2263 Pout<<
"distributedTriSurfaceMesh::independentlyDistributedBbs :" 2264 <<
" determining master-only decomposition for " <<
s.size()
2272 triCentres[trii] =
s[trii].centre(
s.points());
2275 if (!isA<geomDecomp>(decomposer()))
2281 calcFaceFaces(
s, pointFaces, faceFaces);
2285 distribution = decomposer().decompose(faceFaces, triCentres);
2291 distribution = decomposer().decompose(triCentres);
2296 Pout<<
"distributedTriSurfaceMesh::independentlyDistributedBbs :" 2297 <<
" determining processor bounding boxes for surface " 2304 treeBoundBox& bb = bbs[distribution[trii]][0];
2305 bb.add(
s.points(),
s[trii]);
2312 for (
auto& bb : bbs[proci])
2314 bb.grow(mergeDist_);
2320 else if (distType_ == DISTRIBUTED)
2324 if (!decomposer().parallelAware())
2327 <<
"The decomposition method " << decomposer().typeName
2328 <<
" does not decompose in parallel." 2334 Pout<<
"distributedTriSurfaceMesh::independentlyDistributedBbs :" 2335 <<
" determining decomposition for " <<
s.size()
2344 triCentres[trii] =
s[trii].centre(
s.points());
2347 distribution = decomposer().decompose(triCentres);
2351 Pout<<
"distributedTriSurfaceMesh::independentlyDistributedBbs :" 2352 <<
" determining processor bounding boxes for " 2359 treeBoundBox& bb = bbs[distribution[trii]][0];
2360 bb.add(
s.points(),
s[trii]);
2367 for (
auto& bb : bbs[proci])
2369 bb.grow(mergeDist_);
2573 Pout<<
"distributedTriSurfaceMesh::independentlyDistributedBbs :" 2574 <<
" collecting all centroids for surface " 2583 allCentres[trii] =
s[trii].centre(
s.points());
2585 globalTris().gatherInplace(allCentres);
2604 Pout<<
"distributedTriSurfaceMesh::" 2605 <<
"independentlyDistributedBbs :" 2607 <<
" merged " << allCentres.size()
2608 <<
" centroids down to " << nMerged <<
endl;
2613 UIndirectList<point>(mergedPoints, allToMerged) = allCentres;
2617 labelList mergedDist(decomposer().decompose(mergedPoints));
2621 allDistribution = UIndirectList<label>
2629 globalTris().scatter(allDistribution, distribution);
2633 Pout<<
"distributedTriSurfaceMesh::" 2634 <<
"independentlyDistributedBbs :" 2635 <<
" determined decomposition" <<
endl;
2642 Pout<<
"distributedTriSurfaceMesh::independentlyDistributedBbs :" 2643 <<
" determining processor bounding boxes for " 2649 treeBoundBox& bb = bbs[distribution[trii]][0];
2650 bb.add(
s.points(),
s[trii]);
2657 for (
auto& bb : bbs[proci])
2659 bb.grow(mergeDist_);
2669 bool Foam::distributedTriSurfaceMesh::overlaps
2671 const List<treeBoundBox>& bbs,
2675 treeBoundBox triBb(tri.a());
2679 for (
const treeBoundBox& bb : bbs)
2686 if (bb.overlaps(triBb) && bb.intersects(tri))
2695 void Foam::distributedTriSurfaceMesh::subsetMeshMap
2697 const triSurface&
s,
2699 const label nIncluded,
2705 newToOldFaces.setSize(nIncluded);
2706 newToOldPoints.setSize(
s.points().size());
2707 oldToNewPoints.setSize(
s.points().size());
2708 oldToNewPoints = -1;
2713 forAll(include, oldFacei)
2715 if (include[oldFacei])
2718 newToOldFaces[facei++] = oldFacei;
2721 for (
const label oldPointi :
s[oldFacei])
2723 if (oldToNewPoints[oldPointi] == -1)
2725 oldToNewPoints[oldPointi] = pointi;
2726 newToOldPoints[pointi++] = oldPointi;
2731 newToOldPoints.setSize(pointi);
2738 const triSurface&
s,
2746 forAll(newToOldPoints, i)
2748 newPoints[i] =
s.points()[newToOldPoints[i]];
2751 List<labelledTri> newTriangles(newToOldFaces.size());
2756 const labelledTri& tri =
s[newToOldFaces[i]];
2758 newTriangles[i][0] = oldToNewPoints[tri[0]];
2759 newTriangles[i][1] = oldToNewPoints[tri[1]];
2760 newTriangles[i][2] = oldToNewPoints[tri[2]];
2761 newTriangles[i].region() = tri.region();
2765 return triSurface(newTriangles,
s.patches(), newPoints,
true);
2771 const triSurface&
s,
2810 const triSurface&
s,
2817 ListOps::createWithValue<bool>(
s.size(), newToOldFaces,
true,
false)
2820 newToOldPoints.setSize(
s.points().size());
2821 labelList oldToNewPoints(
s.points().size(), -1);
2825 forAll(include, oldFacei)
2827 if (include[oldFacei])
2830 for (
const label oldPointi :
s[oldFacei])
2832 if (oldToNewPoints[oldPointi] == -1)
2834 oldToNewPoints[oldPointi] = pointi;
2835 newToOldPoints[pointi++] = oldPointi;
2840 newToOldPoints.setSize(pointi);
2853 Foam::label Foam::distributedTriSurfaceMesh::findTriangle
2855 const List<labelledTri>& allFaces,
2857 const labelledTri& otherF
2865 const labelledTri&
f = allFaces[
pFaces[i]];
2867 if (
f.region() == otherF.region())
2870 label fp0 =
f.
find(otherF[0]);
2875 if (
f[fp1] == otherF[1] &&
f[fp2] == otherF[2])
2886 void Foam::distributedTriSurfaceMesh::merge
2888 const scalar mergeDist,
2889 const List<labelledTri>& subTris,
2892 List<labelledTri>& allTris,
2915 label allPointi = nOldAllPoints;
2916 forAll(pointConstructMap, pointi)
2918 if (pointConstructMap[pointi] == -1)
2920 pointConstructMap[pointi] = allPointi++;
2924 if (allPointi > nOldAllPoints)
2928 forAll(pointConstructMap, pointi)
2930 if (pointConstructMap[pointi] >= nOldAllPoints)
2932 allPoints[pointConstructMap[pointi]] = subPoints[pointi];
2946 label allTrii = allTris.size();
2947 allTris.setSize(allTrii + subTris.size());
2949 faceConstructMap.setSize(subTris.size());
2953 const labelledTri& subTri = subTris[trii];
2956 labelledTri mappedTri
2958 pointConstructMap[subTri[0]],
2959 pointConstructMap[subTri[1]],
2960 pointConstructMap[subTri[2]],
2966 bool fullMatch =
true;
2970 if (mappedTri[fp] >= nOldAllPoints)
2981 label i = findTriangle
2991 faceConstructMap[trii] = allTrii;
2992 allTris[allTrii] = mappedTri;
2997 faceConstructMap[trii] = i;
3003 faceConstructMap[trii] = allTrii;
3004 allTris[allTrii] = mappedTri;
3008 allTris.setSize(allTrii);
3014 Foam::distributedTriSurfaceMesh::distributedTriSurfaceMesh
3036 currentDistType_(FROZEN)
3041 readSettings(dict_.empty());
3062 Info<<
'\t' << proci <<
'\t' << nTris[proci]
3063 <<
'\t' << procBb_[proci] <<
endl;
3071 Foam::distributedTriSurfaceMesh::distributedTriSurfaceMesh(
const IOobject&
io)
3078 findLocalInstance(
io),
3101 currentDistType_(FROZEN)
3108 const bool readFromMaster =
3111 || actualFile !=
io.localFilePath(triSurfaceMesh::typeName)
3114 readSettings(readFromMaster);
3123 <<
"Forcing consistent normals since undecomposed" <<
endl;
3128 if (readFromMaster && !decomposeUsingBbs_)
3132 <<
"Determining vertex based normals since undecomposed" <<
endl;
3135 calcVertexNormals(surf, vertexNormals_());
3145 <<
"Read distributedTriSurface " <<
io.name()
3146 <<
" from parent path " << actualFile <<
endl;
3169 <<
"Read distributedTriSurface " <<
io.name()
3170 <<
" from actual path " << actualFile <<
':' <<
endl;
3182 Info<<
'\t' << proci <<
'\t' << nTris[proci]
3183 <<
'\t' << procBb_[proci] <<
endl;
3192 <<
"Read distributedTriSurface " <<
io.name() <<
':' <<
endl;
3198 Foam::distributedTriSurfaceMesh::distributedTriSurfaceMesh
3209 findLocalInstance(
io),
3233 currentDistType_(FROZEN)
3240 const bool readFromMaster =
3249 readSettings(readFromMaster);
3253 if (readFromMaster && !decomposeUsingBbs_)
3257 <<
"Determining vertex based normals since undecomposed" <<
endl;
3260 calcVertexNormals(surf, vertexNormals_());
3266 && (distType_ == INDEPENDENT || distType_ == DISTRIBUTED)
3270 <<
"Read distributedTriSurface " <<
io.
name()
3271 <<
" from parent path " << actualFile
3272 <<
" and dictionary" <<
endl;
3295 <<
"Read distributedTriSurface " <<
io.
name()
3296 <<
" from actual path " << actualFile
3297 <<
" and dictionary:" <<
endl;
3309 Info<<
'\t' << proci <<
'\t' << nTris[proci]
3310 <<
'\t' << procBb_[proci] <<
endl;
3319 <<
"Read distributedTriSurface " <<
io.
name() <<
':' <<
endl;
3335 globalTris_.clear();
3348 return *globalTris_;
3356 Pout<<
"distributedTriSurfaceMesh::flip :" 3358 <<
" with current orientation " 3360 <<
" vertexNormals_ " << vertexNormals_.good()
3370 for (
auto& normals : vn)
3372 for (
auto&
n : normals)
3621 "distributedTriSurfaceMesh::findNearest" 3626 Pout<<
"distributedTriSurfaceMesh::findNearest :" 3628 <<
" trying to find nearest for " <<
samples.
size()
3629 <<
" samples with max sphere " 3659 forAll(dynSendMap, proci)
3666 label minProci = -1;
3676 label nContains = 0;
3679 if (procContains[proci])
3682 dynSendMap[proci].
append(samplei);
3683 distSqr[samplei] = best.
second();
3703 dynSendMap[minProci].
append(samplei);
3704 distSqr[samplei] = best.
second();
3712 sendMap[proci].
transfer(dynSendMap[proci]);
3731 <<
" outside\t" << nOutside <<
endl;
3744 convertTriIndices(localInfo);
3752 label nIgnoredHit = 0;
3778 ni.
second() = info.
point().distSqr(localPoints[i]);
3785 Pout<<
"distributedTriSurfaceMesh::findNearest :" 3787 <<
" searched locally for " << localPoints.
size()
3788 <<
" samples with max sphere " 3790 <<
" found hits:" << nHit
3791 <<
" of which outside local bb:" << nIgnoredHit
3834 forAll(nearestInfo, samplei)
3860 calcOverlappingProcs(sample, d2, procBbOverlaps);
3862 forAll(procBbOverlaps, proci)
3864 if (procBbOverlaps[proci])
3870 if (proci != hitProci)
3872 dynSendMap[proci].
append(samplei);
3881 sendMap[proci].
transfer(dynSendMap[proci]);
3906 forAll(nearestInfo, samplei)
3909 if (ni.
first().hit())
3911 localDistSqr[samplei] = ni.
second();
3919 convertTriIndices(localInfo);
3924 label nIgnoredHit = 0;
3944 ni.
second() = info.
point().distSqr(localSamples[i]);
3951 Pout<<
"distributedTriSurfaceMesh::findNearest :" 3953 <<
" searched locally for " << localSamples.
size()
3954 <<
" samples with max sphere " 3956 <<
" found hits:" << nHit
3957 <<
" of which outside local bb:" << nIgnoredHit
3985 info[samplei] = ni.
first();
4013 "distributedTriSurfaceMesh::findNearestRegion" 4018 Pout<<
"distributedTriSurfaceMesh::findNearest :" 4020 <<
" trying to find nearest and region for " <<
samples.
size()
4021 <<
" samples with max sphere " 4026 if (regionIndices.
empty())
4028 findNearest(
samples, nearestDistSqr, info);
4072 convertTriIndices(allInfo);
4076 if (allInfo[i].hit())
4089 allInfo[i].setMiss();
4090 allInfo[i].setIndex(-1);
4107 if (allInfo[i].hit())
4109 label pointi = allSegmentMap[i];
4111 if (!info[pointi].hit())
4114 info[pointi] = allInfo[i];
4125 info[pointi] = allInfo[i];
4134 void Foam::distributedTriSurfaceMesh::findLine
4197 Pout<<
"distributedTriSurfaceMesh::findLineAll :" 4199 <<
" intersecting with " 4200 << start.
size() <<
" rays" <<
endl;
4206 "distributedTriSurfaceMesh::findLineAll" 4236 + vector::uniform(ROOTVSMALL)
4248 if (hitInfo[pointi].hit())
4251 info[pointi][0] = hitInfo[pointi];
4253 point pt = hitInfo[pointi].point() + smallVec[pointi];
4255 if (((pt-start[pointi])&dirVec[pointi]) <= magSqrDirVec[pointi])
4258 e1[compacti] =
end[pointi];
4259 pointMap[compacti] = pointi;
4265 info[pointi].
clear();
4269 e0.setSize(compacti);
4270 e1.setSize(compacti);
4271 pointMap.setSize(compacti);
4290 if (hitInfo[i].hit())
4292 label pointi = pointMap[i];
4294 label sz = info[pointi].
size();
4296 info[pointi][sz] = hitInfo[i];
4298 point pt = hitInfo[i].point() + smallVec[pointi];
4301 scalar d = ((pt-start[pointi])&dirVec[pointi]);
4305 if (d > 0 && d <= magSqrDirVec[pointi])
4308 e1[compacti] =
end[pointi];
4309 pointMap[compacti] = pointi;
4316 e0.setSize(compacti);
4317 e1.setSize(compacti);
4318 pointMap.setSize(compacti);
4324 Pout<<
"distributedTriSurfaceMesh::findLineAll :" 4325 <<
" Exiting loop due to excessive number of" 4326 <<
" intersections along ray" 4337 Pout<<
"distributedTriSurfaceMesh::findLineAll :" 4339 <<
" finished intersecting with " 4340 << start.
size() <<
" rays" <<
endl;
4353 Pout<<
"distributedTriSurfaceMesh::getRegion :" 4355 <<
" getting region for " 4356 << info.
size() <<
" triangles" <<
endl;
4359 addProfiling(getRegion,
"distributedTriSurfaceMesh::getRegion");
4378 Pout<<
"distributedTriSurfaceMesh::getRegion :" 4380 <<
" finished getting region for " 4381 << info.
size() <<
" triangles" <<
endl;
4407 region.
setSize(triangleIndex.size());
4411 label trii = triangleIndex[i];
4412 region[i] =
s[trii].region();
4423 Pout<<
"distributedTriSurfaceMesh::getRegion :" 4425 <<
" finished getting region for " 4426 << info.
size() <<
" triangles" <<
endl;
4445 Pout<<
"distributedTriSurfaceMesh::getNormal :" 4447 <<
" getting normal for " 4448 << info.
size() <<
" triangles" <<
endl;
4451 addProfiling(getNormal,
"distributedTriSurfaceMesh::getNormal");
4474 normal.
setSize(triangleIndex.size());
4486 const point& nearest = localNearestInfo[i].point();
4488 const label trii = triangleIndex[i];
4490 const auto& vn = vertexNormals_()[trii];
4492 normal[i] = w[0]*vn[0]+w[1]*vn[1]+w[2]*vn[2];
4499 const label trii = triangleIndex[i];
4500 normal[i] =
s[trii].unitNormal(
s.points());
4512 Pout<<
"distributedTriSurfaceMesh::getNormal :" 4514 <<
" finished getting normal for " 4515 << info.
size() <<
" triangles" <<
endl;
4602 if (!hasVolumeType())
4605 <<
"Volume type only supported for closed distributed surfaces." 4617 "distributedTriSurfaceMesh::getCachedVolumeType" 4621 const point outsidePt(bounds().
max() + 0.5*bounds().span());
4624 Pout<<
"distributedTriSurfaceMesh::getVolumeType :" 4626 <<
" triggering outsidePoint" << outsidePt
4627 <<
" orientation" <<
endl;
4640 surfaceSide(outsidePts, nearestInfo, outsideVolTypes);
4651 Pout<<
"distributedTriSurfaceMesh::getVolumeType :" 4653 <<
" determined outsidePoint" << outsidePt
4664 const auto& nodes = t.
nodes();
4669 if (!decomposeUsingBbs_)
4671 markMixedOverlap(t, nt);
4674 cacheVolumeType(nt);
4681 Pout<<
"distributedTriSurfaceMesh::getVolumeType :" 4684 <<
" samples" <<
endl;
4690 "distributedTriSurfaceMesh::getVolumeType" 4709 if (contains(procBb_[proci],
samples[samplei]))
4722 outsideSamples.
append(samplei);
4738 if (contains(procBb_[proci],
samples[samplei]))
4740 sendMap[proci][nSend[proci]++] = samplei;
4772 if (decomposeUsingBbs_ &&
tree().nodes().size())
4774 volType[i] = cachedVolumeType(0, localPoints[i]);
4778 fullSearchMap.append(i);
4779 fullSearchPoints.append(localPoints[i]);
4785 Pout<<
"distributedTriSurfaceMesh::getVolumeType :" 4788 <<
" resulting in local queries:" 4789 << localPoints.
size()
4790 <<
" of which cached:" << localPoints.
size()-fullSearchPoints.size()
4805 surfaceSide(fullSearchPoints, nearestInfo, fullSearchType);
4813 vt = fullSearchType[i];
4815 else if (vt != fullSearchType[i])
4817 Pout<<
"At point:" << fullSearchPoints[i]
4818 <<
" or point:" << localPoints[fullSearchMap[i]]
4819 <<
" have cached status:" << vt
4820 <<
" have full-search status:" << fullSearchType[i]
4893 for (label samplei : outsideSamples)
4895 volType[samplei] = outsideVolType_;
4900 Pout<<
"distributedTriSurfaceMesh::getVolumeType :" 4902 <<
" finished finding orientation for " <<
samples.
size()
4903 <<
" samples" <<
endl;
4922 Pout<<
"distributedTriSurfaceMesh::getField :" 4924 <<
" retrieving field for " 4925 << info.
size() <<
" triangles" <<
endl;
4930 const auto* fldPtr = findObject<triSurfaceLabelField>(
"values");
4954 values.setSize(triangleIndex.size());
4958 label trii = triangleIndex[i];
4971 Pout<<
"distributedTriSurfaceMesh::getField :" 4973 <<
" finished retrieving field for " 4974 << info.
size() <<
" triangles" <<
endl;
4988 includedFace =
false;
4992 const scalar eps = 1.0e-4;
4995 const point mid = bbs[i].centre();
4996 const vector halfSpan = (1.0+eps)*(bbs[i].
max() - mid);
4998 bbsX[i].min() = mid - halfSpan;
4999 bbsX[i].max() = mid + halfSpan;
5008 if (overlaps(bbsX, tri))
5010 includedFace[trii] =
true;
5028 overlappingSurface(
s, bbs, includedFace);
5029 return subsetMesh(
s, includedFace, subPointMap, subFaceMap);
5061 label proci = triIndexer.
whichProcID(info[i].index());
5079 label proci = triIndexer.
whichProcID(info[i].index());
5080 triangleIndex[i] = triIndexer.
toLocal(proci, info[i].index());
5081 sendMap[proci][nSend[proci]++] = i;
5085 triangleIndex[i] = -1;
5094 mapPtr().distribute(triangleIndex);
5103 const bool keepNonLocal,
5115 Pout<<
"distributedTriSurfaceMesh::distribute :" 5117 <<
" distributing surface according to method:" 5118 << distributionTypeNames_[distType_]
5119 <<
" fill-in:" << decomposeUsingBbs_
5123 addProfiling(distribute,
"distributedTriSurfaceMesh::distribute");
5144 if (currentDistType_ == distType_)
5148 independentlyDistributedBbs(*
this,
distribution, newProcBb);
5161 if (newProcBb == procBb_)
5167 procBb_.transfer(newProcBb);
5184 <<
"before distribution:" <<
endl <<
"\tproc\ttris" <<
endl;
5188 Info<<
'\t' << proci <<
'\t' << nTris[proci] <<
endl;
5201 if (decomposeUsingBbs_)
5209 pointSendMap[proci],
5228 pointSendMap[proci],
5243 forAll(faceSendMap, proci)
5247 forAll(faceSendMap[proci], i)
5249 includedFace[faceSendMap[proci][i]] =
false;
5298 allTris = subSurface;
5318 forAll(faceSendMap, proci)
5344 for (
const int proci : pBufs.
allProcs())
5362 faceConstructMap[proci],
5363 pointConstructMap[proci]
5374 std::move(faceSendMap),
5375 std::move(faceConstructMap)
5383 std::move(pointSendMap),
5384 std::move(pointConstructMap)
5397 currentDistType_ = distType_;
5402 distributeFields<label>(
faceMap());
5403 distributeFields<scalar>(
faceMap());
5404 distributeFields<vector>(
faceMap());
5405 distributeFields<sphericalTensor>(
faceMap());
5406 distributeFields<symmTensor>(
faceMap());
5407 distributeFields<tensor>(
faceMap());
5423 const auto&
f =
s[trii];
5427 const point& pt =
s.points()[
f[fp]];
5428 const vector&
n = vn[trii][fp];
5432 Pout<<
"Dumped local vertex normals to " << str.
name() <<
endl;
5446 const auto& nodes = t.
nodes();
5452 if (!decomposeUsingBbs_)
5458 markMixedOverlap(t, nt);
5461 cacheVolumeType(nt);
5476 <<
"after distribution:" <<
endl <<
"\tproc\ttris" <<
endl;
5480 Info<<
'\t' << proci <<
'\t' << nTris[proci] <<
endl;
5492 Info<<
"Writing local bounding box to " << str.
name() <<
endl;
5496 str.
write(bb,
true);
5507 Info<<
"Writing all bounding boxes to " << str.
name() <<
endl;
5508 for (
const auto& myBbs : procBb_)
5512 str.
write(bb,
true);
5520 Pout<<
"distributedTriSurfaceMesh::distribute :" 5522 <<
" done distributing surface according to method:" 5523 << distributionTypeNames_[distType_]
5532 const bool writeOnProc
5537 Pout<<
"distributedTriSurfaceMesh::writeObject :" 5539 <<
" writing surface:" << writeOnProc <<
endl;
5567 bool ok = dict_.writeObject(streamOpt,
true);
5571 Pout<<
"distributedTriSurfaceMesh::writeObject :" 5573 <<
" done writing surface" <<
endl;
5587 os <<
"Triangles : " 5590 <<
"Vertex normals : " << vertexNormals_.valid() <<
endl 5591 <<
"Bounding Box : " << bb <<
endl 5592 <<
"Closed : " << surfaceClosed_ <<
endl 5594 <<
"Distribution : " << distributionTypeNames_[distType_] <<
endl;
label toLocal(const label proci, const label i) const
From global to local on proci.
virtual void getField(const List< pointIndexHit > &, labelList &) const
WIP. From a set of hits (points and.
static const Enum< distributionType > distributionTypeNames_
static label getNode(const labelBits i)
Return real (dereferenced) index for a parent node.
virtual void findLine(const pointField &start, const pointField &end, List< pointIndexHit > &) const
Find first intersection on segment from start to end.
void reset(const label localSize, const label comm=UPstream::worldComm, const bool parallel=UPstream::parRun())
Reset from local size, using gather/broadcast with default/specified communicator if parallel...
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc) const
Write using stream options.
void size(const label n)
Older name for setAddressableSize.
A triangle primitive used to calculate face normals and swept volumes. Uses referred points...
static const treeBoundBox & null() noexcept
The null treeBoundBox is the same as an inverted box.
A class for handling file names.
readOption readOpt() const noexcept
Get the read option.
virtual void findLineAny(const pointField &start, const pointField &end, List< pointIndexHit > &) const
Return any intersection on segment from start to end.
static void overlappingSurface(const triSurface &, const List< treeBoundBox > &, boolList &includedFace)
Calculate the triangles that are overlapping bounds.
type
Volume classification types.
Barycentric2D< scalar > barycentric2D
A scalar version of the templated Barycentric2D.
errorManipArg< error, int > exit(error &err, const int errNo=1)
void clearOut()
Clear storage.
const List< node > & nodes() const noexcept
List of all nodes.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
barycentric2D pointToBarycentric(const point &pt) const
Calculate the barycentric coordinates from the given point.
virtual Ostream & write(const char c) override
Write character.
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
void append(const T &val)
Append an element at the end of the list.
void distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute List data using default commsType, default flip/negate operator.
virtual const fileName & name() const override
Read/write access to the name of the stream.
const word & name() const noexcept
Return the object name.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
const globalIndex & globalTris() const
Triangle indexing (demand driven)
constexpr char nl
The newline '\n' character (0x0a)
label whichProcID(const label proci, const label i) const
Which processor does global id come from? Checks proci first (assumed to occur reasonably frequently)...
static constexpr label pack(const label val, const direction bits) noexcept
Pack integer value and bits (octant) into a label.
bool empty() const noexcept
True if List is empty (ie, size() is zero)
virtual void distribute(const List< treeBoundBox > &, const bool keepNonLocal, autoPtr< mapDistribute > &faceMap, autoPtr< mapDistribute > &pointMap)
Set bounds of surface. Bounds currently set as list of.
virtual void findNearest(const pointField &sample, const scalarField &nearestDistSqr, List< pointIndexHit > &) const
scalarField samples(nIntervals, Zero)
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
static bool & parRun() noexcept
Test if this a parallel run.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
#define addProfiling(Name,...)
Define profiling trigger with specified name and description string. The description is generated by ...
label comm() const noexcept
The communicator used.
refPtr< fileOperation > fileHandler(std::nullptr_t)
Delete current file handler - forwards to fileOperation::handler()
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
A bounding box defined in terms of min/max extrema points.
static int & msgType() noexcept
Message tag of standard messages.
const Type * findObject(const word &name, const bool recursive=false) const
Return const pointer to the object of the given Type.
This class describes the interaction of an object (often a face) and a point. It carries the info of ...
List< treeBoundBox > treeBoundBoxList
A List of treeBoundBox.
A simple container for options an IOstream can normally have.
static std::string path(const std::string &str)
Return directory path name (part before last /)
Base class of (analytical or triangulated) surface. Encapsulates all the search routines. WIP.
static void broadcast(Type &value, const int communicator=UPstream::worldComm)
Broadcast content (contiguous or non-contiguous) to all communicator ranks. Does nothing in non-paral...
Ignore writing from objectRegistry::writeObject()
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
An enumeration wrapper for classification of a location as being inside/outside of a volume...
virtual const boundBox & bounds() const
Return const reference to boundBox.
List< labelList > labelListList
List of labelList.
void write(Ostream &os) const
Write to Ostream in simple OpenFOAM format.
Determine correspondence between points. See below.
fileName objectPath() const
The complete path + object name.
Macros for easy insertion into run-time selection tables.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
virtual void getVolumeType(const pointField &, List< volumeType > &) const
Determine type (inside/outside/mixed) for point. unknown if.
void resize(const label numElem, const unsigned int val=0u)
Reset addressable list size, does not shrink the allocated size.
#define forAll(list, i)
Loop across all elements in list.
IOoject and searching on triSurface.
T & operator[](const label i)
Return element of UList.
Templated 2D Barycentric derived from VectorSpace. Has 3 components, one of which is redundant...
label fcIndex(const label i) const noexcept
The forward circular index. The next index in the list which returns to the first at the end of the l...
virtual bool hasVolumeType() const
Whether supports volume type (below) - i.e. whether is closed.
label mergePoints(const PointList &points, labelList &pointToUnique, labelList &uniquePoints, const scalar mergeTol=SMALL, const bool verbose=false)
Calculate merge mapping, preserving the original point order. All points closer/equal mergeTol are to...
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
bool subHasFlip() const noexcept
Does subMap include a sign.
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Input inter-processor communications stream using MPI send/recv etc. - operating on external buffer...
virtual void flip()
Flip triangles, outsideVolumeType and all cached inside/outside.
const point_type & point() const noexcept
Return point, no checks.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
bool matchPoints(const UList< point > &pts0, const UList< point > &pts1, const UList< scalar > &matchDistance, const bool verbose, labelList &from0To1, const point &origin=point::zero)
Determine correspondence between pointFields. Gets passed.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
writeOption writeOpt() const noexcept
Get the write option.
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
void setSize(const label n)
Alias for resize()
virtual void getVolumeType(const pointField &points, List< volumeType > &volType) const
Determine type (inside/outside/mixed) for point.
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
line< point, const point & > linePointRef
A line using referred points.
static bool isContent(labelBits i) noexcept
Node with content (leaf)
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
virtual ~distributedTriSurfaceMesh()
Destructor.
void clear()
Clear the list, i.e. set size to zero.
virtual void getRegion(const List< pointIndexHit > &, labelList ®ion) const
From a set of points and indices get the region.
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
#define DebugInFunction
Report an information message using Foam::Info.
labelledTri face_type
The face type (same as the underlying PrimitivePatch)
void finishedSends(const bool wait=true)
Mark the send phase as being finished.
void clearOut()
Clear storage.
PackedList< 2 > & nodeTypes() const noexcept
Per node, per octant whether is fully inside/outside/mixed.
Tree tree(triangles.begin(), triangles.end())
virtual void findLineAll(const pointField &start, const pointField &end, List< List< pointIndexHit >> &) const
Get all intersections in order from start to end.
Tuple2< pointIndexHit, scalar > nearestAndDist
Combine operator for nearest.
Reading is optional [identical to LAZY_READ].
const objectRegistry & db() const noexcept
Return the local objectRegistry.
static const word null
An empty word.
void operator()(volumeType &x, const volumeType &y) const
virtual void getNormal(const List< pointIndexHit > &, vectorField &normal) const
From a set of points and indices get the normal.
constexpr scalar pi(M_PI)
fileName localFilePath(const word &typeName, const bool search=true) const
Redirect to fileHandler filePath, searching locally.
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=cellModel::ref(cellModel::HEX);labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells].reset(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< SMALL) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} pointMap[start]=pointMap[end]=Foam::min(start, end);} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};constexpr label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &oldCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< DynamicList< face > > pFaces[nBCs]
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
Dynamically sized Field. Similar to DynamicList, but inheriting from a Field instead of a List...
Abstract base class for domain decomposition.
A triFace with additional (region) index.
const Field< point_type > & points() const noexcept
Return reference to global points.
A location inside the volume.
void append(const T &val)
Copy append an element to the end of this list.
Accumulating histogram of values. Specified bin resolution automatic generation of bins...
A location outside the volume.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
bool returnReduceOr(const bool value, const int communicator=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
label index() const noexcept
Return the hit index.
errorManip< error > abort(error &err)
void reverseDistribute(const label constructSize, List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType.
label find(const T &val) const
Find index of the first occurrence of the value.
virtual void findLineAll(const pointField &start, const pointField &end, List< List< pointIndexHit >> &) const
Get all intersections in order from start to end.
bool ln(const fileName &src, const fileName &dst)
Create a softlink. dst should not exist. Returns true if successful.
const Time & time() const noexcept
Return Time associated with the objectRegistry.
void reduce()
Inplace parallel reduction of min/max values.
A location that is partly inside and outside.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Output inter-processor communications stream using MPI send/recv etc. - operating on external buffer...
A functor that returns its argument unchanged (cf. C++20 std::identity) Should never be specialized...
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
An OFstream that keeps track of vertices and provides convenience output methods for OBJ files...
label size() const noexcept
The number of elements in the container.
label recvDataCount(const label proci) const
Number of unconsumed receive bytes for the specified processor. Must call finishedSends() or other fi...
bool constructHasFlip() const noexcept
Does constructMap include a sign.
int debug
Static debugging option.
Pair< label > labelPair
A pair of labels.
virtual void findNearest(const pointField &sample, const scalarField &nearestDistSqr, List< pointIndexHit > &) const
tmp< GeoField > getField(const IOobject &io, const typename GeoField::Mesh &mesh)
Get the field or FatalError.
OBJstream os(runTime.globalPath()/outputName)
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
defineTypeNameAndDebug(combustionModel, 0)
static bool orientConsistent(triSurface &s)
Make sure surface has consistent orientation across connected.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Combine operator for volume types.
const fileName & instance() const noexcept
Read access to instance path component.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
static readOption lazierRead(readOption opt) noexcept
Downgrade readOption optional (LAZY_READ), leaves NO_READ intact.
static void allGatherList(UList< T > &values, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Gather data, but keep individual values separate. Uses MPI_Allgather or manual communication.
virtual void getNormal(const List< pointIndexHit > &, vectorField &normal) const
From a set of points and indices get the normal.
const labelListList & constructMap() const noexcept
From subsetted data to new reconstructed data.
bool isFile(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist as a FILE in the file system?
static bool isNode(labelBits i) noexcept
A parent node.
static autoPtr< decompositionMethod > New(const dictionary &decompDict, const word ®ionName="")
Return a reference to the selected decomposition method, optionally region-specific.
void operator()(nearestAndDist &x, const nearestAndDist &y) const
bool hit() const noexcept
Is there a hit?
Class containing processor-to-processor mapping information.
vector point
Point is a vector.
static fileName findFile(const IOobject &io, const bool isGlobal=true)
Use IOobject information to resolve file to load from, or empty if the file does not exist...
Non-pointer based hierarchical recursive searching.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
virtual void findLineAny(const pointField &start, const pointField &end, List< pointIndexHit > &) const
Return any intersection on segment from start to end.
A List with indirect addressing. Like IndirectList but does not store addressing. ...
const T2 & second() const noexcept
Access the second element.
const dimensionedScalar c
Speed of light in a vacuum.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
A simple container of IOobject preferences. Can also be used for general handling of read/no-read/rea...
const polyBoundaryMesh & patches
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
meshDefDict readIfPresent("polyMeshPatches", polyPatchNames)
static autoPtr< searchableSurface > New(const word &surfaceType, const IOobject &io, const dictionary &dict)
Return a reference to the selected searchableSurface.
triangle< point, const point & > triPointRef
A triangle using referred points.
Standard boundBox with extra functionality for use in octree.
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
messageStream Info
Information stream (stdout output on master, null elsewhere)
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Field< vector > vectorField
Specialisation of Field<T> for vector.
bool registerObject() const noexcept
Should objects created with this IOobject be registered?
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
List< label > labelList
A List of labels.
int system(const std::string &command, const bool bg=false)
Execute the specified command via the shell.
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
List< instant > instantList
List of instants.
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
virtual autoPtr< mapDistribute > localQueries(const List< pointIndexHit > &, labelList &triangleIndex) const
Obtains global indices from pointIndexHit and swaps them back.
const labelListList & subMap() const noexcept
From subsetted data back to original data.
const T1 & first() const noexcept
Access the first element.
Triangulated surface description with patch information.
label rcIndex(const label i) const noexcept
The reverse circular index. The previous index in the list which returns to the last at the beginning...
const fileName & local() const noexcept
Read access to local path component.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
void invertManyToMany(const label len, const UList< InputIntListType > &input, List< OutputIntListType > &output)
Invert many-to-many.
const nearestAndDist nearestZero(nearestAndDist(pointIndexHit(), -GREAT))
void operator=(const triSurface &surf)
Copy assignment.
virtual void flip()
Flip triangles, outsideVolumeType and all cached inside/outside.
Defines the attributes of an object for which implicit objectRegistry management is supported...
List< bool > boolList
A List of bools.
streamFormat format() const noexcept
Get the current stream format.
static void distribute(const UPstream::commsTypes commsType, const UList< labelPair > &schedule, const label constructSize, const labelListList &subMap, const bool subHasFlip, const labelListList &constructMap, const bool constructHasFlip, List< T > &field, const T &nullValue, const CombineOp &cop, const NegateOp &negOp, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Distribute combine data with specified combine operation and negate operator (for flips)...
static const List< T > & null() noexcept
Return a null List (reference to a nullObject). Behaves like an empty List.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
static void listCombineGather(UList< T > &values, CombineOp cop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Forwards to Pstream::listGather with an in-place cop.
UPstream::rangeType allProcs() const noexcept
Range of ranks indices associated with PstreamBuffers.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
PointHit< point > pointHit
A PointHit with a 3D point.
virtual void getField(const List< pointIndexHit > &, labelList &) const
WIP. From a set of hits (points and.
addToRunTimeSelectionTable(functionObject, pointHistory, dictionary)
void writeStats(Ostream &os) const
Print some stats. Parallel aware version of.
static const Enum< volumeType::type > names
Names for the classification enumeration.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
#define InfoInFunction
Report an information message using Foam::Info.
static constexpr const zero Zero
Global zero (0)