DistributedDelaunayMesh.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2012-2016 OpenFOAM Foundation
9  Copyright (C) 2020-2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
30 #include "meshSearch.H"
31 #include "mapDistribute.H"
33 #include "pointConversion.H"
34 #include "indexedVertexEnum.H"
35 #include "IOmanip.H"
36 #include <algorithm>
37 #include <random>
38 
39 // * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
40 
41 template<class Triangulation>
44 (
45  const List<label>& toProc
46 )
47 {
48  // Determine send map
49  // ~~~~~~~~~~~~~~~~~~
50 
51  // 1. Count
52  labelList nSend(Pstream::nProcs(), Zero);
53 
54  forAll(toProc, i)
55  {
56  label proci = toProc[i];
57 
58  nSend[proci]++;
59  }
60 
61 
62  // 2. Size sendMap
63  labelListList sendMap(Pstream::nProcs());
64 
65  forAll(nSend, proci)
66  {
67  sendMap[proci].setSize(nSend[proci]);
68 
69  nSend[proci] = 0;
70  }
71 
72  // 3. Fill sendMap
73  forAll(toProc, i)
74  {
75  label proci = toProc[i];
76 
77  sendMap[proci][nSend[proci]++] = i;
78  }
79 
80  // 4. Send over how many I need to receive
81  labelList recvSizes;
82  Pstream::exchangeSizes(sendMap, recvSizes);
83 
84 
85  // Determine receive map
86  // ~~~~~~~~~~~~~~~~~~~~~
87 
88  labelListList constructMap(Pstream::nProcs());
89 
90  // Local transfers first
91  constructMap[Pstream::myProcNo()] = identity
92  (
93  sendMap[Pstream::myProcNo()].size()
94  );
95 
96  label constructSize = constructMap[Pstream::myProcNo()].size();
97 
98  forAll(constructMap, proci)
99  {
100  if (proci != Pstream::myProcNo())
101  {
102  label nRecv = recvSizes[proci];
103 
104  constructMap[proci].setSize(nRecv);
105 
106  for (label i = 0; i < nRecv; i++)
107  {
108  constructMap[proci][i] = constructSize++;
109  }
110  }
111  }
112 
114  (
115  constructSize,
116  std::move(sendMap),
117  std::move(constructMap)
118  );
119 }
120 
121 
122 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
123 
124 template<class Triangulation>
126 (
127  const Time& runTime
128 )
129 :
130  DelaunayMesh<Triangulation>(runTime),
131  allBackgroundMeshBounds_()
132 {}
133 
134 
135 template<class Triangulation>
137 (
138  const Time& runTime,
139  const word& meshName
140 )
141 :
142  DelaunayMesh<Triangulation>(runTime, meshName),
143  allBackgroundMeshBounds_()
144 {}
145 
146 
147 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
148 
149 template<class Triangulation>
151 (
152  const boundBox& bb
153 )
154 {
155  allBackgroundMeshBounds_.reset(new List<boundBox>(Pstream::nProcs()));
156 
157  // Give the bounds of every processor to every other processor
158  allBackgroundMeshBounds_()[Pstream::myProcNo()] = bb;
159 
160  Pstream::allGatherList(allBackgroundMeshBounds_());
161 
162  return true;
163 }
164 
165 
166 template<class Triangulation>
168 (
169  const Vertex_handle& v
170 ) const
171 {
172  return isLocal(v->procIndex());
173 }
174 
175 
176 template<class Triangulation>
178 (
179  const label localProcIndex
180 ) const
181 {
182  return localProcIndex == Pstream::myProcNo();
183 }
184 
185 
186 template<class Triangulation>
188 (
189  const point& centre,
190  const scalar radiusSqr
191 ) const
192 {
193  DynamicList<label> toProc(Pstream::nProcs());
194 
195  forAll(allBackgroundMeshBounds_(), proci)
196  {
197  // Test against the bounding box of the processor
198  if
199  (
200  !isLocal(proci)
201  && allBackgroundMeshBounds_()[proci].overlaps(centre, radiusSqr)
202  )
203  {
204  toProc.append(proci);
205  }
206  }
207 
208  return toProc;
209 }
210 
211 
212 template<class Triangulation>
214 (
215  const Cell_handle& cit,
216  Map<labelList>& circumsphereOverlaps
217 ) const
218 {
219  const Foam::point& cc = cit->dual();
220 
221  const scalar crSqr = magSqr
222  (
223  cc - topoint(cit->vertex(0)->point())
224  );
225 
226  labelList circumsphereOverlap = overlapProcessors
227  (
228  cc,
229  sqr(1.01)*crSqr
230  );
231 
232  cit->cellIndex() = this->getNewCellIndex();
233 
234  if (!circumsphereOverlap.empty())
235  {
236  circumsphereOverlaps.insert(cit->cellIndex(), circumsphereOverlap);
237 
238  return true;
239  }
240 
241  return false;
242 }
243 
244 
245 template<class Triangulation>
247 (
248  Map<labelList>& circumsphereOverlaps
249 ) const
250 {
251  // Start by assuming that all the cells have no index
252  // If they do, they have already been visited so ignore them
253 
254  labelHashSet cellToCheck
255  (
256  Triangulation::number_of_finite_cells()
257  /Pstream::nProcs()
258  );
259 
260 // std::list<Cell_handle> infinite_cells;
261 // Triangulation::incident_cells
262 // (
263 // Triangulation::infinite_vertex(),
264 // std::back_inserter(infinite_cells)
265 // );
266 //
267 // for
268 // (
269 // typename std::list<Cell_handle>::iterator vcit
270 // = infinite_cells.begin();
271 // vcit != infinite_cells.end();
272 // ++vcit
273 // )
274 // {
275 // Cell_handle cit = *vcit;
276 //
277 // // Index of infinite vertex in this cell.
278 // label i = cit->index(Triangulation::infinite_vertex());
279 //
280 // Cell_handle c = cit->neighbor(i);
281 //
282 // if (c->unassigned())
283 // {
284 // c->cellIndex() = this->getNewCellIndex();
285 //
286 // if (checkProcBoundaryCell(c, circumsphereOverlaps))
287 // {
288 // cellToCheck.insert(c->cellIndex());
289 // }
290 // }
291 // }
292 //
293 //
294 // for
295 // (
296 // Finite_cells_iterator cit = Triangulation::finite_cells_begin();
297 // cit != Triangulation::finite_cells_end();
298 // ++cit
299 // )
300 // {
301 // if (cit->parallelDualVertex())
302 // {
303 // if (cit->unassigned())
304 // {
305 // if (checkProcBoundaryCell(cit, circumsphereOverlaps))
306 // {
307 // cellToCheck.insert(cit->cellIndex());
308 // }
309 // }
310 // }
311 // }
312 
313 
314  for
315  (
316  All_cells_iterator cit = Triangulation::all_cells_begin();
317  cit != Triangulation::all_cells_end();
318  ++cit
319  )
320  {
321  if (Triangulation::is_infinite(cit))
322  {
323  // Index of infinite vertex in this cell.
324  label i = cit->index(Triangulation::infinite_vertex());
325 
326  Cell_handle c = cit->neighbor(i);
327 
328  if (c->unassigned())
329  {
330  c->cellIndex() = this->getNewCellIndex();
331 
332  if (checkProcBoundaryCell(c, circumsphereOverlaps))
333  {
334  cellToCheck.insert(c->cellIndex());
335  }
336  }
337  }
338  else if (cit->parallelDualVertex())
339  {
340  if (cit->unassigned())
341  {
342  if (checkProcBoundaryCell(cit, circumsphereOverlaps))
343  {
344  cellToCheck.insert(cit->cellIndex());
345  }
346  }
347  }
348  }
349 
350  for
351  (
352  Finite_cells_iterator cit = Triangulation::finite_cells_begin();
353  cit != Triangulation::finite_cells_end();
354  ++cit
355  )
356  {
357  if (cellToCheck.found(cit->cellIndex()))
358  {
359  // Get the neighbours and check them
360  for (label adjCelli = 0; adjCelli < 4; ++adjCelli)
361  {
362  Cell_handle citNeighbor = cit->neighbor(adjCelli);
363 
364  // Ignore if has far point or previously visited
365  if
366  (
367  !citNeighbor->unassigned()
368  || !citNeighbor->internalOrBoundaryDualVertex()
369  || Triangulation::is_infinite(citNeighbor)
370  )
371  {
372  continue;
373  }
374 
375  if
376  (
377  checkProcBoundaryCell
378  (
379  citNeighbor,
380  circumsphereOverlaps
381  )
382  )
383  {
384  cellToCheck.insert(citNeighbor->cellIndex());
385  }
386  }
387 
388  cellToCheck.unset(cit->cellIndex());
389  }
390  }
391 }
392 
393 
394 template<class Triangulation>
396 (
397  const Map<labelList>& circumsphereOverlaps,
398  PtrList<labelPairHashSet>& referralVertices,
399  DynamicList<label>& targetProcessor,
400  DynamicList<Vb>& parallelInfluenceVertices
401 )
402 {
403  // Relying on the order of iteration of cells being the same as before
404  for
405  (
406  Finite_cells_iterator cit = Triangulation::finite_cells_begin();
407  cit != Triangulation::finite_cells_end();
408  ++cit
409  )
410  {
411  if (Triangulation::is_infinite(cit))
412  {
413  continue;
414  }
415 
416  const auto iter = circumsphereOverlaps.cfind(cit->cellIndex());
417 
418  // Pre-tested circumsphere potential influence
419  if (iter.found())
420  {
421  const labelList& citOverlaps = iter();
422 
423  for (const label proci : citOverlaps)
424  {
425  for (int i = 0; i < 4; i++)
426  {
427  Vertex_handle v = cit->vertex(i);
428 
429  if (v->farPoint())
430  {
431  continue;
432  }
433 
434  label vProcIndex = v->procIndex();
435  label vIndex = v->index();
436 
437  const labelPair procIndexPair(vProcIndex, vIndex);
438 
439  // Using the hashSet to ensure that each vertex is only
440  // referred once to each processor.
441  // Do not refer a vertex to its own processor.
442  if (vProcIndex != proci)
443  {
444  if (referralVertices[proci].insert(procIndexPair))
445  {
446  targetProcessor.append(proci);
447 
448  parallelInfluenceVertices.append
449  (
450  Vb
451  (
452  v->point(),
453  v->index(),
454  v->type(),
455  v->procIndex()
456  )
457  );
458 
459  parallelInfluenceVertices.last().targetCellSize() =
460  v->targetCellSize();
461  parallelInfluenceVertices.last().alignment() =
462  v->alignment();
463  }
464  }
465  }
466  }
467  }
468  }
469 }
470 
471 
472 template<class Triangulation>
474 (
475  const DynamicList<label>& targetProcessor,
476  DynamicList<Vb>& parallelVertices,
477  PtrList<labelPairHashSet>& referralVertices,
478  labelPairHashSet& receivedVertices
479 )
480 {
481  DynamicList<Vb> referredVertices(targetProcessor.size());
482 
483  const label preDistributionSize = parallelVertices.size();
484 
485  autoPtr<mapDistribute> pointMapPtr = buildMap(targetProcessor);
486  mapDistribute& pointMap = *pointMapPtr;
487 
488  // Make a copy of the original list.
489  DynamicList<Vb> originalParallelVertices(parallelVertices);
490 
491  pointMap.distribute(parallelVertices);
492 
493  for (const int proci : Pstream::allProcs())
494  {
495  const labelList& constructMap = pointMap.constructMap()[proci];
496 
497  if (constructMap.size())
498  {
499  forAll(constructMap, i)
500  {
501  const Vb& v = parallelVertices[constructMap[i]];
502 
503  if
504  (
505  v.procIndex() != Pstream::myProcNo()
506  && !receivedVertices.found(labelPair(v.procIndex(), v.index()))
507  )
508  {
509  referredVertices.append(v);
510 
511  receivedVertices.insert
512  (
513  labelPair(v.procIndex(), v.index())
514  );
515  }
516  }
517  }
518  }
519 
520  label preInsertionSize = Triangulation::number_of_vertices();
521 
522  labelPairHashSet pointsNotInserted = rangeInsertReferredWithInfo
523  (
524  referredVertices.begin(),
525  referredVertices.end(),
526  true
527  );
528 
529  if (!pointsNotInserted.empty())
530  {
531  forAllConstIters(pointsNotInserted, iter)
532  {
533  if (receivedVertices.found(iter.key()))
534  {
535  receivedVertices.erase(iter.key());
536  }
537  }
538  }
539 
540  boolList pointInserted(parallelVertices.size(), true);
541 
542  forAll(parallelVertices, vI)
543  {
544  const labelPair procIndexI
545  (
546  parallelVertices[vI].procIndex(),
547  parallelVertices[vI].index()
548  );
549 
550  if (pointsNotInserted.found(procIndexI))
551  {
552  pointInserted[vI] = false;
553  }
554  }
555 
556  pointMap.reverseDistribute(preDistributionSize, pointInserted);
557 
558  forAll(originalParallelVertices, vI)
559  {
560  const label procIndex = targetProcessor[vI];
561 
562  if (!pointInserted[vI])
563  {
564  if (referralVertices[procIndex].size())
565  {
566  if
567  (
568  !referralVertices[procIndex].unset
569  (
570  labelPair
571  (
572  originalParallelVertices[vI].procIndex(),
573  originalParallelVertices[vI].index()
574  )
575  )
576  )
577  {
578  Pout<< "*** not found "
579  << originalParallelVertices[vI].procIndex()
580  << " " << originalParallelVertices[vI].index() << endl;
581  }
582  }
583  }
584  }
585 
586  label postInsertionSize = Triangulation::number_of_vertices();
587 
588  reduce(preInsertionSize, sumOp<label>());
589  reduce(postInsertionSize, sumOp<label>());
590 
591  label nTotalToInsert =
592  returnReduce(referredVertices.size(), sumOp<label>());
593 
594  if (preInsertionSize + nTotalToInsert != postInsertionSize)
595  {
596  label nNotInserted =
597  returnReduce(pointsNotInserted.size(), sumOp<label>());
598 
599  Info<< " Inserted = "
600  << setw(name(label(Triangulation::number_of_finite_cells())).size())
601  << nTotalToInsert - nNotInserted
602  << " / " << nTotalToInsert << endl;
603 
604  nTotalToInsert -= nNotInserted;
605  }
606  else
607  {
608  Info<< " Inserted = " << nTotalToInsert << endl;
609  }
610 
611  return nTotalToInsert;
612 }
613 
614 
615 template<class Triangulation>
617 (
618  const boundBox& bb,
619  PtrList<labelPairHashSet>& referralVertices,
620  labelPairHashSet& receivedVertices,
621  bool iterateReferral
622 )
623 {
624  if (!Pstream::parRun())
625  {
626  return;
627  }
628 
629  if (!allBackgroundMeshBounds_)
630  {
631  distributeBoundBoxes(bb);
632  }
633 
634  label nVerts = Triangulation::number_of_vertices();
635  label nCells = Triangulation::number_of_finite_cells();
636 
637  DynamicList<Vb> parallelInfluenceVertices(0.1*nVerts);
638  DynamicList<label> targetProcessor(0.1*nVerts);
639 
640  // Some of these values will not be used, i.e. for non-real cells
641  DynamicList<Foam::point> circumcentre(0.1*nVerts);
642  DynamicList<scalar> circumradiusSqr(0.1*nVerts);
643 
644  Map<labelList> circumsphereOverlaps(nCells);
645 
646  findProcessorBoundaryCells(circumsphereOverlaps);
647 
648  Info<< " Influences = "
649  << setw(name(nCells).size())
650  << returnReduce(circumsphereOverlaps.size(), sumOp<label>()) << " / "
651  << returnReduce(nCells, sumOp<label>());
652 
653  markVerticesToRefer
654  (
655  circumsphereOverlaps,
656  referralVertices,
657  targetProcessor,
658  parallelInfluenceVertices
659  );
660 
661  referVertices
662  (
663  targetProcessor,
664  parallelInfluenceVertices,
665  referralVertices,
666  receivedVertices
667  );
668 
669  if (iterateReferral)
670  {
671  label oldNReferred = 0;
672  label nIterations = 1;
673 
674  Info<< incrIndent << indent
675  << "Iteratively referring referred vertices..."
676  << endl;
677  do
678  {
679  Info<< indent << "Iteration " << nIterations++ << ":";
680 
681  circumsphereOverlaps.clear();
682  targetProcessor.clear();
683  parallelInfluenceVertices.clear();
684 
685  findProcessorBoundaryCells(circumsphereOverlaps);
686 
687  nCells = Triangulation::number_of_finite_cells();
688 
689  Info<< " Influences = "
690  << setw(name(nCells).size())
691  << returnReduce(circumsphereOverlaps.size(), sumOp<label>())
692  << " / "
693  << returnReduce(nCells, sumOp<label>());
694 
695  markVerticesToRefer
696  (
697  circumsphereOverlaps,
698  referralVertices,
699  targetProcessor,
700  parallelInfluenceVertices
701  );
702 
703  label nReferred = referVertices
704  (
705  targetProcessor,
706  parallelInfluenceVertices,
707  referralVertices,
708  receivedVertices
709  );
710 
711  if (nReferred == 0 || nReferred == oldNReferred)
712  {
713  break;
714  }
715 
716  oldNReferred = nReferred;
717 
718  } while (true);
719 
720  Info<< decrIndent;
721  }
722 }
723 
724 
725 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
726 
727 
728 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
729 
730 template<class Triangulation>
731 Foam::scalar
733 {
734  label nRealVertices = 0;
735 
736  for
737  (
738  Finite_vertices_iterator vit = Triangulation::finite_vertices_begin();
739  vit != Triangulation::finite_vertices_end();
740  ++vit
741  )
742  {
743  // Only store real vertices that are not feature vertices
744  if (vit->real() && !vit->featurePoint())
745  {
746  nRealVertices++;
747  }
748  }
749 
750  scalar globalNRealVertices = returnReduce
751  (
752  nRealVertices,
753  sumOp<label>()
754  );
755 
756  scalar unbalance = returnReduce
757  (
758  mag(1.0 - nRealVertices/(globalNRealVertices/Pstream::nProcs())),
759  maxOp<scalar>()
760  );
761 
762  Info<< " Processor unbalance " << unbalance << endl;
763 
764  return unbalance;
765 }
766 
767 
768 template<class Triangulation>
770 (
771  const boundBox& bb
772 )
773 {
775 
776  if (!Pstream::parRun())
777  {
778  return false;
779  }
780 
781  distributeBoundBoxes(bb);
782 
783  return true;
784 }
785 
786 
787 template<class Triangulation>
790 (
791  const backgroundMeshDecomposition& decomposition,
792  List<Foam::point>& points
793 )
794 {
795  if (!Pstream::parRun())
796  {
797  return nullptr;
798  }
799 
800  distributeBoundBoxes(decomposition.procBounds());
801 
802  return decomposition.distributePoints(points);
803 }
804 
805 
806 template<class Triangulation>
808 {
809  if (!Pstream::parRun())
810  {
811  return;
812  }
813 
814  if (!allBackgroundMeshBounds_)
815  {
816  distributeBoundBoxes(bb);
817  }
818 
819  const label nApproxReferred =
820  Triangulation::number_of_vertices()
821  /Pstream::nProcs();
822 
823  PtrList<labelPairHashSet> referralVertices(Pstream::nProcs());
824  forAll(referralVertices, proci)
825  {
826  if (!isLocal(proci))
827  {
828  referralVertices.set(proci, new labelPairHashSet(nApproxReferred));
829  }
830  }
831 
832  labelPairHashSet receivedVertices(nApproxReferred);
833 
834  sync
835  (
836  bb,
837  referralVertices,
838  receivedVertices,
839  true
840  );
841 }
842 
843 
844 template<class Triangulation>
845 template<class PointIterator>
848 (
849  PointIterator begin,
850  PointIterator end,
851  bool printErrors
852 )
853 {
854  const boundBox& bb = allBackgroundMeshBounds_()[Pstream::myProcNo()];
855 
856  typedef DynamicList
857  <
858  std::pair<scalar, label>
859  > vectorPairPointIndex;
860 
861  vectorPairPointIndex pointsBbDistSqr;
862 
863  label count = 0;
864  for (PointIterator it = begin; it != end; ++it)
865  {
866  const Foam::point samplePoint(topoint(it->point()));
867 
868  scalar distFromBbSqr = 0;
869 
870  if (!bb.contains(samplePoint))
871  {
872  distFromBbSqr = bb.nearest(samplePoint).distSqr(samplePoint);
873  }
874 
875  pointsBbDistSqr.append
876  (
877  std::make_pair(distFromBbSqr, count++)
878  );
879  }
880 
882  (
883  pointsBbDistSqr.begin(),
884  pointsBbDistSqr.end(),
885  std::default_random_engine()
886  );
887 
888  // Sort in ascending order by the distance of the point from the centre
889  // of the processor bounding box
890  sort(pointsBbDistSqr.begin(), pointsBbDistSqr.end());
891 
892  typename Triangulation::Vertex_handle hint;
893 
894  typename Triangulation::Locate_type lt;
895  int li, lj;
896 
897  label nNotInserted = 0;
898 
899  labelPairHashSet uninserted
900  (
901  Triangulation::number_of_vertices()
902  /Pstream::nProcs()
903  );
904 
905  for
906  (
907  typename vectorPairPointIndex::const_iterator p =
908  pointsBbDistSqr.begin();
909  p != pointsBbDistSqr.end();
910  ++p
911  )
912  {
913  const size_t checkInsertion = Triangulation::number_of_vertices();
914 
915  const Vb& vert = *(begin + p->second);
916  const Point& pointToInsert = vert.point();
917 
918  // Locate the point
919  Cell_handle c = Triangulation::locate(pointToInsert, lt, li, lj, hint);
920 
921  bool inserted = false;
922 
923  if (lt == Triangulation::VERTEX)
924  {
925  if (printErrors)
926  {
927  Vertex_handle nearV =
928  Triangulation::nearest_vertex(pointToInsert);
929 
930  Pout<< "Failed insertion, point already exists" << nl
931  << "Failed insertion : " << vert.info()
932  << " nearest : " << nearV->info();
933  }
934  }
935  else if (lt == Triangulation::OUTSIDE_AFFINE_HULL)
936  {
938  << "Point is outside affine hull! pt = " << pointToInsert
939  << endl;
940  }
941  else if (lt == Triangulation::OUTSIDE_CONVEX_HULL)
942  {
943  // TODO: Can this be optimised?
944  //
945  // Only want to insert if a connection is formed between
946  // pointToInsert and an internal or internal boundary point.
947  hint = Triangulation::insert(pointToInsert, c);
948  inserted = true;
949  }
950  else
951  {
952  // Get the cells that conflict with p in a vector V,
953  // and a facet on the boundary of this hole in f.
954  std::vector<Cell_handle> V;
955  typename Triangulation::Facet f;
956 
957  Triangulation::find_conflicts
958  (
959  pointToInsert,
960  c,
961  CGAL::Oneset_iterator<typename Triangulation::Facet>(f),
962  std::back_inserter(V)
963  );
964 
965  for (size_t i = 0; i < V.size(); ++i)
966  {
967  Cell_handle conflictingCell = V[i];
968 
969  if
970  (
971  Triangulation::dimension() < 3 // 2D triangulation
972  ||
973  (
974  !Triangulation::is_infinite(conflictingCell)
975  && (
976  conflictingCell->real()
977  || conflictingCell->hasFarPoint()
978  )
979  )
980  )
981  {
982  hint = Triangulation::insert_in_hole
983  (
984  pointToInsert,
985  V.begin(),
986  V.end(),
987  f.first,
988  f.second
989  );
990 
991  inserted = true;
992 
993  break;
994  }
995  }
996  }
997 
998  if (inserted)
999  {
1000  if (checkInsertion != Triangulation::number_of_vertices() - 1)
1001  {
1002  if (printErrors)
1003  {
1004  Vertex_handle nearV =
1005  Triangulation::nearest_vertex(pointToInsert);
1006 
1007  Pout<< "Failed insertion : " << vert.info()
1008  << " nearest : " << nearV->info();
1009  }
1010  }
1011  else
1012  {
1013  hint->index() = vert.index();
1014  hint->type() = vert.type();
1015  hint->procIndex() = vert.procIndex();
1016  hint->targetCellSize() = vert.targetCellSize();
1017  hint->alignment() = vert.alignment();
1018  }
1019  }
1020  else
1021  {
1022  uninserted.insert(labelPair(vert.procIndex(), vert.index()));
1023  nNotInserted++;
1024  }
1025  }
1026 
1027  return uninserted;
1028 }
1029 
1030 
1031 // ************************************************************************* //
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:51
scalar calculateLoadUnbalance() const
A HashTable with keys but without contents that is similar to std::unordered_set. ...
Definition: HashSet.H:73
static autoPtr< mapDistribute > buildMap(const List< label > &toProc)
Build a mapDistribute for the supplied destination processor data.
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:449
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 &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
labelPairHashSet rangeInsertReferredWithInfo(PointIterator begin, PointIterator end, bool printErrors=true)
Inserts points into the triangulation if the point is within.
vertexType & type()
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
Foam::label & index()
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...
Definition: indexedVertex.H:59
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:413
void unset(List< bool > &bools, const labelUList &locations)
Unset the listed locations (assign &#39;false&#39;).
Definition: BitOps.C:99
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:52
const pointField & points
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Definition: labelList.C:31
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:334
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.
Definition: Pair.H:50
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:193
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:467
labelList f(nPoints)
Foam::tensor & alignment()
CGAL::Point_3< K > Point
vector point
Point is a vector.
Definition: point.H:37
#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)
Definition: IOmanip.H:199
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
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.
Definition: UList.C:362
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:458
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:666
constexpr auto begin(C &c) -> decltype(c.begin())
Return iterator to the beginning of the container c.
Definition: stdFoam.H:160
List< bool > boolList
A List of bools.
Definition: List.H:60
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)
Definition: pEqn.H:28
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:157