41 template<
class Triangulation>
45 const List<label>& toProc
56 label proci = toProc[i];
67 sendMap[proci].setSize(nSend[proci]);
75 label proci = toProc[i];
77 sendMap[proci][nSend[proci]++] = i;
82 Pstream::exchangeSizes(sendMap, recvSizes);
91 constructMap[Pstream::myProcNo()] =
identity 93 sendMap[Pstream::myProcNo()].size()
96 label constructSize = constructMap[Pstream::myProcNo()].size();
98 forAll(constructMap, proci)
100 if (proci != Pstream::myProcNo())
102 label nRecv = recvSizes[proci];
104 constructMap[proci].setSize(nRecv);
106 for (label i = 0; i < nRecv; i++)
108 constructMap[proci][i] = constructSize++;
117 std::move(constructMap)
124 template<
class Triangulation>
130 DelaunayMesh<Triangulation>(
runTime),
131 allBackgroundMeshBounds_()
135 template<
class Triangulation>
142 DelaunayMesh<Triangulation>(
runTime, meshName),
143 allBackgroundMeshBounds_()
149 template<
class Triangulation>
155 allBackgroundMeshBounds_.
reset(
new List<boundBox>(Pstream::nProcs()));
158 allBackgroundMeshBounds_()[Pstream::myProcNo()] = bb;
160 Pstream::allGatherList(allBackgroundMeshBounds_());
166 template<
class Triangulation>
169 const Vertex_handle& v
172 return isLocal(v->procIndex());
176 template<
class Triangulation>
179 const label localProcIndex
182 return localProcIndex == Pstream::myProcNo();
186 template<
class Triangulation>
190 const scalar radiusSqr
193 DynamicList<label> toProc(Pstream::nProcs());
195 forAll(allBackgroundMeshBounds_(), proci)
201 && allBackgroundMeshBounds_()[proci].overlaps(centre, radiusSqr)
204 toProc.append(proci);
212 template<
class Triangulation>
215 const Cell_handle& cit,
216 Map<labelList>& circumsphereOverlaps
221 const scalar crSqr =
magSqr 223 cc -
topoint(cit->vertex(0)->point())
226 labelList circumsphereOverlap = overlapProcessors
232 cit->cellIndex() = this->getNewCellIndex();
234 if (!circumsphereOverlap.empty())
236 circumsphereOverlaps.insert(cit->cellIndex(), circumsphereOverlap);
245 template<
class Triangulation>
248 Map<labelList>& circumsphereOverlaps
256 Triangulation::number_of_finite_cells()
316 All_cells_iterator cit = Triangulation::all_cells_begin();
317 cit != Triangulation::all_cells_end();
321 if (Triangulation::is_infinite(cit))
324 label i = cit->index(Triangulation::infinite_vertex());
326 Cell_handle
c = cit->neighbor(i);
330 c->cellIndex() = this->getNewCellIndex();
332 if (checkProcBoundaryCell(
c, circumsphereOverlaps))
334 cellToCheck.insert(
c->cellIndex());
338 else if (cit->parallelDualVertex())
340 if (cit->unassigned())
342 if (checkProcBoundaryCell(cit, circumsphereOverlaps))
344 cellToCheck.insert(cit->cellIndex());
352 Finite_cells_iterator cit = Triangulation::finite_cells_begin();
353 cit != Triangulation::finite_cells_end();
357 if (cellToCheck.found(cit->cellIndex()))
360 for (label adjCelli = 0; adjCelli < 4; ++adjCelli)
362 Cell_handle citNeighbor = cit->neighbor(adjCelli);
367 !citNeighbor->unassigned()
368 || !citNeighbor->internalOrBoundaryDualVertex()
369 || Triangulation::is_infinite(citNeighbor)
377 checkProcBoundaryCell
384 cellToCheck.insert(citNeighbor->cellIndex());
388 cellToCheck.unset(cit->cellIndex());
394 template<
class Triangulation>
397 const Map<labelList>& circumsphereOverlaps,
398 PtrList<labelPairHashSet>& referralVertices,
399 DynamicList<label>& targetProcessor,
400 DynamicList<Vb>& parallelInfluenceVertices
406 Finite_cells_iterator cit = Triangulation::finite_cells_begin();
407 cit != Triangulation::finite_cells_end();
411 if (Triangulation::is_infinite(cit))
416 const auto iter = circumsphereOverlaps.cfind(cit->cellIndex());
423 for (
const label proci : citOverlaps)
425 for (
int i = 0; i < 4; i++)
427 Vertex_handle v = cit->vertex(i);
434 label vProcIndex = v->procIndex();
435 label vIndex = v->index();
437 const labelPair procIndexPair(vProcIndex, vIndex);
442 if (vProcIndex != proci)
444 if (referralVertices[proci].
insert(procIndexPair))
446 targetProcessor.append(proci);
448 parallelInfluenceVertices.append
459 parallelInfluenceVertices.last().targetCellSize() =
461 parallelInfluenceVertices.last().alignment() =
472 template<
class Triangulation>
475 const DynamicList<label>& targetProcessor,
476 DynamicList<Vb>& parallelVertices,
477 PtrList<labelPairHashSet>& referralVertices,
481 DynamicList<Vb> referredVertices(targetProcessor.size());
483 const label preDistributionSize = parallelVertices.size();
485 autoPtr<mapDistribute> pointMapPtr = buildMap(targetProcessor);
486 mapDistribute& pointMap = *pointMapPtr;
489 DynamicList<Vb> originalParallelVertices(parallelVertices);
491 pointMap.distribute(parallelVertices);
493 for (
const int proci : Pstream::allProcs())
495 const labelList& constructMap = pointMap.constructMap()[proci];
497 if (constructMap.size())
501 const Vb& v = parallelVertices[constructMap[i]];
509 referredVertices.append(v);
511 receivedVertices.insert
520 label preInsertionSize = Triangulation::number_of_vertices();
524 referredVertices.begin(),
525 referredVertices.end(),
529 if (!pointsNotInserted.empty())
533 if (receivedVertices.found(iter.key()))
535 receivedVertices.erase(iter.key());
540 boolList pointInserted(parallelVertices.size(),
true);
542 forAll(parallelVertices, vI)
546 parallelVertices[vI].procIndex(),
547 parallelVertices[vI].index()
550 if (pointsNotInserted.found(procIndexI))
552 pointInserted[vI] =
false;
556 pointMap.reverseDistribute(preDistributionSize, pointInserted);
558 forAll(originalParallelVertices, vI)
560 const label procIndex = targetProcessor[vI];
562 if (!pointInserted[vI])
564 if (referralVertices[procIndex].size())
568 !referralVertices[procIndex].
unset 572 originalParallelVertices[vI].procIndex(),
573 originalParallelVertices[vI].index()
578 Pout<<
"*** not found " 579 << originalParallelVertices[vI].procIndex()
580 <<
" " << originalParallelVertices[vI].index() <<
endl;
586 label postInsertionSize = Triangulation::number_of_vertices();
588 reduce(preInsertionSize, sumOp<label>());
589 reduce(postInsertionSize, sumOp<label>());
591 label nTotalToInsert =
594 if (preInsertionSize + nTotalToInsert != postInsertionSize)
599 Info<<
" Inserted = " 600 <<
setw(
name(label(Triangulation::number_of_finite_cells())).size())
601 << nTotalToInsert - nNotInserted
602 <<
" / " << nTotalToInsert <<
endl;
604 nTotalToInsert -= nNotInserted;
608 Info<<
" Inserted = " << nTotalToInsert <<
endl;
611 return nTotalToInsert;
615 template<
class Triangulation>
619 PtrList<labelPairHashSet>& referralVertices,
624 if (!Pstream::parRun())
629 if (!allBackgroundMeshBounds_)
631 distributeBoundBoxes(bb);
634 label nVerts = Triangulation::number_of_vertices();
635 label nCells = Triangulation::number_of_finite_cells();
637 DynamicList<Vb> parallelInfluenceVertices(0.1*nVerts);
638 DynamicList<label> targetProcessor(0.1*nVerts);
641 DynamicList<Foam::point> circumcentre(0.1*nVerts);
642 DynamicList<scalar> circumradiusSqr(0.1*nVerts);
644 Map<labelList> circumsphereOverlaps(nCells);
646 findProcessorBoundaryCells(circumsphereOverlaps);
648 Info<<
" Influences = " 650 <<
returnReduce(circumsphereOverlaps.size(), sumOp<label>()) <<
" / " 655 circumsphereOverlaps,
658 parallelInfluenceVertices
664 parallelInfluenceVertices,
671 label oldNReferred = 0;
672 label nIterations = 1;
675 <<
"Iteratively referring referred vertices..." 679 Info<<
indent <<
"Iteration " << nIterations++ <<
":";
681 circumsphereOverlaps.clear();
682 targetProcessor.clear();
683 parallelInfluenceVertices.clear();
685 findProcessorBoundaryCells(circumsphereOverlaps);
687 nCells = Triangulation::number_of_finite_cells();
689 Info<<
" Influences = " 691 <<
returnReduce(circumsphereOverlaps.size(), sumOp<label>())
697 circumsphereOverlaps,
700 parallelInfluenceVertices
703 label nReferred = referVertices
706 parallelInfluenceVertices,
711 if (nReferred == 0 || nReferred == oldNReferred)
716 oldNReferred = nReferred;
730 template<
class Triangulation>
734 label nRealVertices = 0;
738 Finite_vertices_iterator vit = Triangulation::finite_vertices_begin();
739 vit != Triangulation::finite_vertices_end();
744 if (vit->real() && !vit->featurePoint())
758 mag(1.0 - nRealVertices/(globalNRealVertices/Pstream::nProcs())),
762 Info<<
" Processor unbalance " << unbalance <<
endl;
768 template<
class Triangulation>
776 if (!Pstream::parRun())
781 distributeBoundBoxes(bb);
787 template<
class Triangulation>
791 const backgroundMeshDecomposition& decomposition,
795 if (!Pstream::parRun())
800 distributeBoundBoxes(decomposition.procBounds());
802 return decomposition.distributePoints(
points);
806 template<
class Triangulation>
809 if (!Pstream::parRun())
814 if (!allBackgroundMeshBounds_)
816 distributeBoundBoxes(bb);
819 const label nApproxReferred =
820 Triangulation::number_of_vertices()
823 PtrList<labelPairHashSet> referralVertices(Pstream::nProcs());
824 forAll(referralVertices, proci)
844 template<
class Triangulation>
845 template<
class Po
intIterator>
854 const boundBox& bb = allBackgroundMeshBounds_()[Pstream::myProcNo()];
858 std::pair<scalar, label>
859 > vectorPairPointIndex;
861 vectorPairPointIndex pointsBbDistSqr;
864 for (PointIterator it =
begin; it !=
end; ++it)
868 scalar distFromBbSqr = 0;
870 if (!bb.contains(samplePoint))
872 distFromBbSqr = bb.nearest(samplePoint).distSqr(samplePoint);
875 pointsBbDistSqr.append
877 std::make_pair(distFromBbSqr,
count++)
883 pointsBbDistSqr.begin(),
884 pointsBbDistSqr.end(),
885 std::default_random_engine()
890 sort(pointsBbDistSqr.begin(), pointsBbDistSqr.end());
892 typename Triangulation::Vertex_handle hint;
894 typename Triangulation::Locate_type lt;
897 label nNotInserted = 0;
901 Triangulation::number_of_vertices()
907 typename vectorPairPointIndex::const_iterator
p =
908 pointsBbDistSqr.begin();
909 p != pointsBbDistSqr.end();
913 const size_t checkInsertion = Triangulation::number_of_vertices();
915 const Vb& vert = *(
begin +
p->second);
916 const Point& pointToInsert = vert.point();
919 Cell_handle
c = Triangulation::locate(pointToInsert, lt, li, lj, hint);
921 bool inserted =
false;
923 if (lt == Triangulation::VERTEX)
927 Vertex_handle nearV =
928 Triangulation::nearest_vertex(pointToInsert);
930 Pout<<
"Failed insertion, point already exists" <<
nl 931 <<
"Failed insertion : " << vert.
info()
932 <<
" nearest : " << nearV->info();
935 else if (lt == Triangulation::OUTSIDE_AFFINE_HULL)
938 <<
"Point is outside affine hull! pt = " << pointToInsert
941 else if (lt == Triangulation::OUTSIDE_CONVEX_HULL)
954 std::vector<Cell_handle> V;
955 typename Triangulation::Facet
f;
957 Triangulation::find_conflicts
961 CGAL::Oneset_iterator<typename Triangulation::Facet>(
f),
962 std::back_inserter(V)
965 for (
size_t i = 0; i < V.size(); ++i)
967 Cell_handle conflictingCell = V[i];
971 Triangulation::dimension() < 3
974 !Triangulation::is_infinite(conflictingCell)
976 conflictingCell->real()
977 || conflictingCell->hasFarPoint()
982 hint = Triangulation::insert_in_hole
1000 if (checkInsertion != Triangulation::number_of_vertices() - 1)
1004 Vertex_handle nearV =
1005 Triangulation::nearest_vertex(pointToInsert);
1007 Pout<<
"Failed insertion : " << vert.
info()
1008 <<
" nearest : " << nearV->info();
1013 hint->index() = vert.
index();
1014 hint->type() = vert.
type();
List< labelList > labelListList
A List of labelList.
scalar calculateLoadUnbalance() const
A HashTable with keys but without contents that is similar to std::unordered_set. ...
static autoPtr< mapDistribute > buildMap(const List< label > &toProc)
Build a mapDistribute for the supplied destination processor data.
Ostream & indent(Ostream &os)
Indent stream.
pointFromPoint topoint(const Point &P)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
dimensionedSymmTensor sqr(const dimensionedVector &dv)
srcOptions insert("case", fileName(rootDirSource/caseDirSource))
constexpr char nl
The newline '\n' character (0x0a)
labelPairHashSet rangeInsertReferredWithInfo(PointIterator begin, PointIterator end, bool printErrors=true)
Inserts points into the triangulation if the point is within.
Ostream & endl(Ostream &os)
Add newline and flush stream.
bool distribute(const boundBox &bb)
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
Foam::scalar & targetCellSize()
An indexed form of CGAL::Triangulation_vertex_base_3<K> used to keep track of the Delaunay vertices i...
#define forAll(list, i)
Loop across all elements in list.
void unset(List< bool > &bools, const labelUList &locations)
Unset the listed locations (assign 'false').
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
void sort(UList< T > &list)
Sort the list.
void reset()
Clear the entire triangulation.
Foam::InfoProxy< indexedVertex< Gt, Vb > > info() const
Info proxy, to print information to a stream.
Istream and Ostream manipulators taking arguments.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
Pair< label > labelPair
A pair of labels.
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Foam::tensor & alignment()
vector point
Point is a vector.
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionedScalar c
Speed of light in a vacuum.
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Omanip< int > setw(const int i)
List< label > labelList
A List of labels.
HashSet< labelPair, Foam::Hash< labelPair > > labelPairHashSet
A HashSet for a labelPair. The hashing is based on labelPair (FixedList) and is thus non-commutative...
void shuffle(UList< T > &list)
Randomise the list order.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
constexpr auto begin(C &c) -> decltype(c.begin())
Return iterator to the beginning of the container c.
List< bool > boolList
A List of bools.
void sync(const boundBox &bb)
Refer vertices so that the processor interfaces are consistent.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
forAllConstIters(mixture.phases(), phase)
static constexpr const zero Zero
Global zero (0)