PointEdgeWave.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "PointEdgeWave.H"
27 #include "polyMesh.H"
28 #include "processorPolyPatch.H"
29 #include "cyclicPolyPatch.H"
30 #include "OPstream.H"
31 #include "IPstream.H"
33 #include "debug.H"
34 #include "typeInfo.H"
35 #include "globalMeshData.H"
36 #include "pointFields.H"
37 
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 
40 template<class Type, class TrackingData>
42 
43 template<class Type, class TrackingData>
45 
46 
47 namespace Foam
48 {
49  //- Reduction class. If x and y are not equal assign value.
50  template<class Type, class TrackingData>
52  {
53  TrackingData& td_;
54 
55  public:
56  combineEqOp(TrackingData& td)
57  :
58  td_(td)
59  {}
60 
61  void operator()(Type& x, const Type& y) const
62  {
63  if (!x.valid(td_) && y.valid(td_))
64  {
65  x = y;
66  }
67  }
68  };
69 }
70 
71 
72 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
73 
74 // Transform across an interface. Implementation referred to Type
75 template<class Type, class TrackingData>
77 (
78  const polyPatch& patch,
79  const labelList& patchPointLabels,
80  const transformer& transform,
81  List<Type>& pointInfo
82 ) const
83 {
84  forAll(pointInfo, i)
85  {
86  pointInfo[i].transform(patch, patchPointLabels[i], transform, td_);
87  }
88 }
89 
90 
91 // Update info for pointi, at position pt, with information from
92 // neighbouring edge.
93 // Updates:
94 // - changedPoint_, changedPoints_, nChangedPoints_,
95 // - statistics: nEvals_, nUnvisitedPoints_
96 template<class Type, class TrackingData>
98 (
99  const label pointi,
100  const label neighbourEdgeI,
101  const Type& neighbourInfo,
102  Type& pointInfo
103 )
104 {
105  nEvals_++;
106 
107  bool wasValid = pointInfo.valid(td_);
108 
109  bool propagate =
110  pointInfo.updatePoint
111  (
112  mesh_,
113  pointi,
114  neighbourEdgeI,
115  neighbourInfo,
116  propagationTol_,
117  td_
118  );
119 
120  if (propagate)
121  {
122  if (!changedPoint_[pointi])
123  {
124  changedPoint_[pointi] = true;
125  changedPoints_[nChangedPoints_++] = pointi;
126  }
127  }
128 
129  if (!wasValid && pointInfo.valid(td_))
130  {
131  --nUnvisitedPoints_;
132  }
133 
134  return propagate;
135 }
136 
137 
138 // Update info for pointi, at position pt, with information from
139 // same point.
140 // Updates:
141 // - changedPoint_, changedPoints_, nChangedPoints_,
142 // - statistics: nEvals_, nUnvisitedPoints_
143 template<class Type, class TrackingData>
145 (
146  const label pointi,
147  const Type& neighbourInfo,
148  Type& pointInfo
149 )
150 {
151  nEvals_++;
152 
153  bool wasValid = pointInfo.valid(td_);
154 
155  bool propagate =
156  pointInfo.updatePoint
157  (
158  mesh_,
159  pointi,
160  neighbourInfo,
161  propagationTol_,
162  td_
163  );
164 
165  if (propagate)
166  {
167  if (!changedPoint_[pointi])
168  {
169  changedPoint_[pointi] = true;
170  changedPoints_[nChangedPoints_++] = pointi;
171  }
172  }
173 
174  if (!wasValid && pointInfo.valid(td_))
175  {
176  --nUnvisitedPoints_;
177  }
178 
179  return propagate;
180 }
181 
182 
183 // Update info for edgeI, at position pt, with information from
184 // neighbouring point.
185 // Updates:
186 // - changedEdge_, changedEdges_, nChangedEdges_,
187 // - statistics: nEvals_, nUnvisitedEdge_
188 template<class Type, class TrackingData>
190 (
191  const label edgeI,
192  const label neighbourPointi,
193  const Type& neighbourInfo,
194  Type& edgeInfo
195 )
196 {
197  nEvals_++;
198 
199  bool wasValid = edgeInfo.valid(td_);
200 
201  bool propagate =
202  edgeInfo.updateEdge
203  (
204  mesh_,
205  edgeI,
206  neighbourPointi,
207  neighbourInfo,
208  propagationTol_,
209  td_
210  );
211 
212  if (propagate)
213  {
214  if (!changedEdge_[edgeI])
215  {
216  changedEdge_[edgeI] = true;
217  changedEdges_[nChangedEdges_++] = edgeI;
218  }
219  }
220 
221  if (!wasValid && edgeInfo.valid(td_))
222  {
223  --nUnvisitedEdges_;
224  }
225 
226  return propagate;
227 }
228 
229 
230 // Check if patches of given type name are present
231 template<class Type, class TrackingData>
232 template<class PatchType>
234 {
235  label nPatches = 0;
236 
237  forAll(mesh_.boundaryMesh(), patchi)
238  {
239  if (isA<PatchType>(mesh_.boundaryMesh()[patchi]))
240  {
241  nPatches++;
242  }
243  }
244  return nPatches;
245 }
246 
247 
248 // Transfer all the information to/from neighbouring processors
249 template<class Type, class TrackingData>
251 {
252  // 1. Send all point info on processor patches.
253 
255 
256  DynamicList<Type> patchInfo;
257  DynamicList<label> thisPoints;
258  DynamicList<label> nbrPoints;
259 
260  forAll(mesh_.globalData().processorPatches(), i)
261  {
262  label patchi = mesh_.globalData().processorPatches()[i];
263  const processorPolyPatch& procPatch =
264  refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchi]);
265 
266  patchInfo.clear();
267  patchInfo.reserve(procPatch.nPoints());
268  thisPoints.clear();
269  thisPoints.reserve(procPatch.nPoints());
270  nbrPoints.clear();
271  nbrPoints.reserve(procPatch.nPoints());
272 
273  // Get all changed points in reverse order
274  const labelList& neighbPoints = procPatch.nbrPoints();
275  forAll(neighbPoints, thisPointi)
276  {
277  label meshPointi = procPatch.meshPoints()[thisPointi];
278  if (changedPoint_[meshPointi])
279  {
280  patchInfo.append(allPointInfo_[meshPointi]);
281  thisPoints.append(thisPointi);
282  nbrPoints.append(neighbPoints[thisPointi]);
283  }
284  }
285 
286  // if (debug)
287  //{
288  // Pout<< "Processor patch " << patchi << ' ' << procPatch.name()
289  // << " communicating with " << procPatch.neighbProcNo()
290  // << " Sending:" << patchInfo.size() << endl;
291  //}
292 
293  UOPstream toNeighbour(procPatch.neighbProcNo(), pBufs);
294  toNeighbour << nbrPoints << patchInfo;
295  }
296 
297 
298  pBufs.finishedSends();
299 
300  //
301  // 2. Receive all point info on processor patches.
302  //
303 
304  forAll(mesh_.globalData().processorPatches(), i)
305  {
306  label patchi = mesh_.globalData().processorPatches()[i];
307  const processorPolyPatch& procPatch =
308  refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchi]);
309 
310  List<Type> patchInfo;
311  labelList patchPoints;
312 
313  {
314  UIPstream fromNeighbour(procPatch.neighbProcNo(), pBufs);
315  fromNeighbour >> patchPoints >> patchInfo;
316  }
317 
318  // if (debug)
319  //{
320  // Pout<< "Processor patch " << patchi << ' ' << procPatch.name()
321  // << " communicating with " << procPatch.neighbProcNo()
322  // << " Received:" << patchInfo.size() << endl;
323  //}
324 
325  // Transform info across the interface
326  transform(procPatch, patchPoints, procPatch.transform(), patchInfo);
327 
328  // Merge received info
329  const labelList& meshPoints = procPatch.meshPoints();
330  forAll(patchInfo, i)
331  {
332  label meshPointi = meshPoints[patchPoints[i]];
333 
334  if (!allPointInfo_[meshPointi].equal(patchInfo[i], td_))
335  {
336  updatePoint
337  (
338  meshPointi,
339  patchInfo[i],
340  allPointInfo_[meshPointi]
341  );
342  }
343  }
344  }
345 
346  // Collocated points should be handled by face based transfer
347  // (since that is how connectivity is worked out)
348  // They are also explicitly equalised in handleCollocatedPoints to
349  // guarantee identical values.
350 }
351 
352 
353 template<class Type, class TrackingData>
355 {
356  // 1. Send all point info on cyclic patches.
357 
358  DynamicList<Type> nbrInfo;
359  DynamicList<label> nbrPoints;
360  DynamicList<label> thisPoints;
361 
362  forAll(mesh_.boundaryMesh(), patchi)
363  {
364  const polyPatch& patch = mesh_.boundaryMesh()[patchi];
365 
366  if (isA<cyclicPolyPatch>(patch))
367  {
368  const cyclicPolyPatch& cycPatch =
369  refCast<const cyclicPolyPatch>(patch);
370 
371  nbrInfo.clear();
372  nbrInfo.reserve(cycPatch.nPoints());
373  nbrPoints.clear();
374  nbrPoints.reserve(cycPatch.nPoints());
375  thisPoints.clear();
376  thisPoints.reserve(cycPatch.nPoints());
377 
378  // Collect nbrPatch points that have changed
379  {
380  const cyclicPolyPatch& nbrPatch = cycPatch.nbrPatch();
381  const edgeList& pairs = cycPatch.coupledPoints();
382  const labelList& meshPoints = nbrPatch.meshPoints();
383 
384  forAll(pairs, pairI)
385  {
386  label thisPointi = pairs[pairI][0];
387  label nbrPointi = pairs[pairI][1];
388  label meshPointi = meshPoints[nbrPointi];
389 
390  if (changedPoint_[meshPointi])
391  {
392  nbrInfo.append(allPointInfo_[meshPointi]);
393  nbrPoints.append(nbrPointi);
394  thisPoints.append(thisPointi);
395  }
396  }
397  }
398 
399  // if (debug)
400  //{
401  // Pout<< "Cyclic patch " << patchi << ' ' << patch.name()
402  // << " Changed : " << nbrInfo.size()
403  // << endl;
404  //}
405 
406  // Transform info across the interface
407  transform(cycPatch, thisPoints, cycPatch.transform(), nbrInfo);
408 
409  // Merge received info
410  const labelList& meshPoints = cycPatch.meshPoints();
411  forAll(nbrInfo, i)
412  {
413  label meshPointi = meshPoints[thisPoints[i]];
414 
415  if (!allPointInfo_[meshPointi].equal(nbrInfo[i], td_))
416  {
417  updatePoint
418  (
419  meshPointi,
420  nbrInfo[i],
421  allPointInfo_[meshPointi]
422  );
423  }
424  }
425  }
426  }
427 }
428 
429 
430 // Guarantee collocated points have same information.
431 // Return number of points changed.
432 template<class Type, class TrackingData>
434 {
435  // Transfer onto coupled patch
436  const globalMeshData& gmd = mesh_.globalData();
437  const indirectPrimitivePatch& cpp = gmd.coupledPatch();
438  const labelList& meshPoints = cpp.meshPoints();
439 
440  const distributionMap& slavesMap = gmd.globalPointSlavesMap();
441  const labelListList& slaves = gmd.globalPointSlaves();
442 
443  List<Type> elems(slavesMap.constructSize());
444  forAll(meshPoints, pointi)
445  {
446  elems[pointi] = allPointInfo_[meshPoints[pointi]];
447  }
448 
449  // Pull slave data onto master (which might or might not have any
450  // initialised points). No need to update transformed slots.
451  slavesMap.distribute(elems, false);
452 
453  // Combine master data with slave data
455 
456  forAll(slaves, pointi)
457  {
458  Type& elem = elems[pointi];
459 
460  const labelList& slavePoints = slaves[pointi];
461 
462  // Combine master with untransformed slave data
463  forAll(slavePoints, j)
464  {
465  cop(elem, elems[slavePoints[j]]);
466  }
467 
468  // Copy result back to slave slots
469  forAll(slavePoints, j)
470  {
471  elems[slavePoints[j]] = elem;
472  }
473  }
474 
475  // Push slave-slot data back to slaves
476  slavesMap.reverseDistribute(elems.size(), elems, false);
477 
478  // Extract back onto mesh
479  forAll(meshPoints, pointi)
480  {
481  if (elems[pointi].valid(td_))
482  {
483  label meshPointi = meshPoints[pointi];
484 
485  Type& elem = allPointInfo_[meshPointi];
486 
487  bool wasValid = elem.valid(td_);
488 
489  // Like updatePoint but bypass Type::updatePoint with its tolerance
490  // checking
491  // if (!elem.valid(td_) || !elem.equal(elems[pointi], td_))
492  if (!elem.equal(elems[pointi], td_))
493  {
494  nEvals_++;
495  elem = elems[pointi];
496 
497  // See if element now valid
498  if (!wasValid && elem.valid(td_))
499  {
500  --nUnvisitedPoints_;
501  }
502 
503  // Update database of changed points
504  if (!changedPoint_[meshPointi])
505  {
506  changedPoint_[meshPointi] = true;
507  changedPoints_[nChangedPoints_++] = meshPointi;
508  }
509  }
510  }
511  }
512 
513  // Sum nChangedPoints over all procs
514  label totNChanged = nChangedPoints_;
515 
516  reduce(totNChanged, sumOp<label>());
517 
518  return totNChanged;
519 }
520 
521 
522 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
523 
524 // Iterate, propagating changedPointsInfo across mesh, until no change (or
525 // maxIter reached). Initial point values specified.
526 template<class Type, class TrackingData>
528 (
529  const polyMesh& mesh,
530  const labelList& changedPoints,
531  const List<Type>& changedPointsInfo,
532 
533  UList<Type>& allPointInfo,
534  UList<Type>& allEdgeInfo,
535 
536  const label maxIter,
537  TrackingData& td
538 )
539 :
540  mesh_(mesh),
541  allPointInfo_(allPointInfo),
542  allEdgeInfo_(allEdgeInfo),
543  td_(td),
544  changedPoint_(mesh_.nPoints(), false),
545  changedPoints_(mesh_.nPoints()),
546  nChangedPoints_(0),
547  changedEdge_(mesh_.nEdges(), false),
548  changedEdges_(mesh_.nEdges()),
549  nChangedEdges_(0),
550  nCyclicPatches_(countPatchType<cyclicPolyPatch>()),
551  nEvals_(0),
552  nUnvisitedPoints_(mesh_.nPoints()),
553  nUnvisitedEdges_(mesh_.nEdges())
554 {
555  if (allPointInfo_.size() != mesh_.nPoints())
556  {
558  << "size of pointInfo work array is not equal to the number"
559  << " of points in the mesh" << endl
560  << " pointInfo :" << allPointInfo_.size() << endl
561  << " mesh.nPoints:" << mesh_.nPoints()
562  << exit(FatalError);
563  }
564  if (allEdgeInfo_.size() != mesh_.nEdges())
565  {
567  << "size of edgeInfo work array is not equal to the number"
568  << " of edges in the mesh" << endl
569  << " edgeInfo :" << allEdgeInfo_.size() << endl
570  << " mesh.nEdges:" << mesh_.nEdges()
571  << exit(FatalError);
572  }
573 
574 
575  // Set from initial changed points data
576  setPointInfo(changedPoints, changedPointsInfo);
577 
578  if (debug)
579  {
580  Info<< typeName << ": Seed points : "
581  << returnReduce(nChangedPoints_, sumOp<label>()) << endl;
582  }
583 
584  // Iterate until nothing changes
585  label iter = iterate(maxIter);
586 
587  if ((maxIter > 0) && (iter >= maxIter))
588  {
590  << "Maximum number of iterations reached. Increase maxIter." << endl
591  << " maxIter:" << maxIter << endl
592  << " nChangedPoints:" << nChangedPoints_ << endl
593  << " nChangedEdges:" << nChangedEdges_ << endl
594  << exit(FatalError);
595  }
596 }
597 
598 
599 template<class Type, class TrackingData>
601 (
602  const polyMesh& mesh,
603  UList<Type>& allPointInfo,
604  UList<Type>& allEdgeInfo,
605  TrackingData& td
606 )
607 :
608  mesh_(mesh),
609  allPointInfo_(allPointInfo),
610  allEdgeInfo_(allEdgeInfo),
611  td_(td),
612  changedPoint_(mesh_.nPoints(), false),
613  changedPoints_(mesh_.nPoints()),
614  nChangedPoints_(0),
615  changedEdge_(mesh_.nEdges(), false),
616  changedEdges_(mesh_.nEdges()),
617  nChangedEdges_(0),
618  nCyclicPatches_(countPatchType<cyclicPolyPatch>()),
619  nEvals_(0),
620  nUnvisitedPoints_(mesh_.nPoints()),
621  nUnvisitedEdges_(mesh_.nEdges())
622 {}
623 
624 
625 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
626 
627 template<class Type, class TrackingData>
629 {}
630 
631 
632 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
633 
634 
635 template<class Type, class TrackingData>
637 {
638  return nUnvisitedPoints_;
639 }
640 
641 
642 template<class Type, class TrackingData>
644 {
645  return nUnvisitedEdges_;
646 }
647 
648 
649 // Copy point information into member data
650 template<class Type, class TrackingData>
652 (
653  const labelList& changedPoints,
654  const List<Type>& changedPointsInfo
655 )
656 {
657  forAll(changedPoints, changedPointi)
658  {
659  label pointi = changedPoints[changedPointi];
660 
661  bool wasValid = allPointInfo_[pointi].valid(td_);
662 
663  // Copy info for pointi
664  allPointInfo_[pointi] = changedPointsInfo[changedPointi];
665 
666  // Maintain count of unset points
667  if (!wasValid && allPointInfo_[pointi].valid(td_))
668  {
669  --nUnvisitedPoints_;
670  }
671 
672  // Mark pointi as changed, both on list and on point itself.
673 
674  if (!changedPoint_[pointi])
675  {
676  changedPoint_[pointi] = true;
677  changedPoints_[nChangedPoints_++] = pointi;
678  }
679  }
680 
681  // Sync
682  handleCollocatedPoints();
683 }
684 
685 
686 // Propagate information from edge to point. Return number of points changed.
687 template<class Type, class TrackingData>
689 {
690  for
691  (
692  label changedEdgeI = 0;
693  changedEdgeI < nChangedEdges_;
694  changedEdgeI++
695  )
696  {
697  label edgeI = changedEdges_[changedEdgeI];
698 
699  if (!changedEdge_[edgeI])
700  {
702  << "edge " << edgeI
703  << " not marked as having been changed" << nl
704  << "This might be caused by multiple occurrences of the same"
705  << " seed point." << abort(FatalError);
706  }
707 
708 
709  const Type& neighbourWallInfo = allEdgeInfo_[edgeI];
710 
711  // Evaluate all connected points (= edge endpoints)
712  const edge& e = mesh_.edges()[edgeI];
713 
714  forAll(e, eI)
715  {
716  Type& currentWallInfo = allPointInfo_[e[eI]];
717 
718  if (!currentWallInfo.equal(neighbourWallInfo, td_))
719  {
720  updatePoint
721  (
722  e[eI],
723  edgeI,
724  neighbourWallInfo,
725  currentWallInfo
726  );
727  }
728  }
729 
730  // Reset status of edge
731  changedEdge_[edgeI] = false;
732  }
733 
734  // Handled all changed edges by now
735  nChangedEdges_ = 0;
736 
737  if (nCyclicPatches_ > 0)
738  {
739  // Transfer changed points across cyclic halves
740  handleCyclicPatches();
741  }
742  if (Pstream::parRun())
743  {
744  // Transfer changed points from neighbouring processors.
745  handleProcPatches();
746  }
747 
748  // if (debug)
749  //{
750  // Pout<< "Changed points : " << nChangedPoints_ << endl;
751  //}
752 
753  // Sum nChangedPoints over all procs
754  label totNChanged = nChangedPoints_;
755 
756  reduce(totNChanged, sumOp<label>());
757 
758  return totNChanged;
759 }
760 
761 
762 // Propagate information from point to edge. Return number of edges changed.
763 template<class Type, class TrackingData>
765 {
766  const labelListList& pointEdges = mesh_.pointEdges();
767 
768  for
769  (
770  label changedPointi = 0;
771  changedPointi < nChangedPoints_;
772  changedPointi++
773  )
774  {
775  label pointi = changedPoints_[changedPointi];
776 
777  if (!changedPoint_[pointi])
778  {
780  << "Point " << pointi
781  << " not marked as having been changed" << nl
782  << "This might be caused by multiple occurrences of the same"
783  << " seed point." << abort(FatalError);
784  }
785 
786  const Type& neighbourWallInfo = allPointInfo_[pointi];
787 
788  // Evaluate all connected edges
789 
790  const labelList& edgeLabels = pointEdges[pointi];
791  forAll(edgeLabels, edgeLabelI)
792  {
793  label edgeI = edgeLabels[edgeLabelI];
794 
795  Type& currentWallInfo = allEdgeInfo_[edgeI];
796 
797  if (!currentWallInfo.equal(neighbourWallInfo, td_))
798  {
799  updateEdge
800  (
801  edgeI,
802  pointi,
803  neighbourWallInfo,
804  currentWallInfo
805  );
806  }
807  }
808 
809  // Reset status of point
810  changedPoint_[pointi] = false;
811  }
812 
813  // Handled all changed points by now
814  nChangedPoints_ = 0;
815 
816  // if (debug)
817  //{
818  // Pout<< "Changed edges : " << nChangedEdges_ << endl;
819  //}
820 
821  // Sum nChangedPoints over all procs
822  label totNChanged = nChangedEdges_;
823 
824  reduce(totNChanged, sumOp<label>());
825 
826  return totNChanged;
827 }
828 
829 
830 // Iterate
831 template<class Type, class TrackingData>
833 (
834  const label maxIter
835 )
836 {
837  if (nCyclicPatches_ > 0)
838  {
839  // Transfer changed points across cyclic halves
840  handleCyclicPatches();
841  }
842  if (Pstream::parRun())
843  {
844  // Transfer changed points from neighbouring processors.
845  handleProcPatches();
846  }
847 
848  nEvals_ = 0;
849 
850  label iter = 0;
851 
852  while (iter < maxIter)
853  {
854  while (iter < maxIter)
855  {
856  if (debug)
857  {
858  Info<< typeName << ": Iteration " << iter << endl;
859  }
860 
861  label nEdges = pointToEdge();
862 
863  if (debug)
864  {
865  Info<< typeName << ": Total changed edges : "
866  << nEdges << endl;
867  }
868 
869  if (nEdges == 0)
870  {
871  break;
872  }
873 
874  label nPoints = edgeToPoint();
875 
876  if (debug)
877  {
878  Info<< typeName << ": Total changed points : "
879  << nPoints << nl
880  << typeName << ": Total evaluations : "
881  << returnReduce(nEvals_, sumOp<label>()) << nl
882  << typeName << ": Remaining unvisited points: "
883  << returnReduce(nUnvisitedPoints_, sumOp<label>()) << nl
884  << typeName << ": Remaining unvisited edges : "
885  << returnReduce(nUnvisitedEdges_, sumOp<label>()) << nl
886  << endl;
887  }
888 
889  if (nPoints == 0)
890  {
891  break;
892  }
893 
894  iter++;
895  }
896 
897 
898  // Enforce collocated points are exactly equal. This might still mean
899  // non-collocated points are not equal though. WIP.
900  label nPoints = handleCollocatedPoints();
901  if (debug)
902  {
903  Info<< typeName << ": Collocated point sync : "
904  << nPoints << nl << endl;
905  }
906 
907  if (nPoints == 0)
908  {
909  break;
910  }
911  }
912 
913  return iter;
914 }
915 
916 
917 // ************************************************************************* //
label nPatches
Definition: readKivaGrid.H:402
label nPoints() const
Return number of points supporting patch faces.
const labelListList & globalPointSlaves() const
Reduction class. If x and y are not equal assign value.
Definition: PointEdgeWave.C:51
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
const labelList & nbrPoints() const
Return neighbour point labels. WIP.
Vector-tensor class used to perform translations, rotations and scaling operations in 3D space...
Definition: transformer.H:83
void finishedSends(const bool block=true)
Mark all sends as having been done. This will start receives.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
const edgeList & coupledPoints() const
Return connected points (from patch local to neighbour patch local)
void reverseDistribute(const label constructSize, List< T > &, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType.
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
label pointToEdge()
Propagate from point to edge. Returns total number of edges.
Various mesh related information for a parallel run. Upon construction, constructs all info using par...
const polyBoundaryMesh & boundaryMesh() const
Return boundaryMesh reference.
Definition: polyPatch.C:297
label iterate(const label maxIter)
Iterate until no changes or maxIter reached. Returns actual.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
label edgeToPoint()
Propagate from edge to point. Returns total number of points.
virtual const transformer & transform() const
Return transformation between the coupled patches.
~PointEdgeWave()
Destructor.
void setPointInfo(const labelList &changedPoints, const List< Type > &changedPointsInfo)
Copy initial data into allPointInfo_.
const cyclicPolyPatch & nbrPatch() const
combineEqOp(TrackingData &td)
Definition: PointEdgeWave.C:56
void distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute data using default commsType.
Combination-Reduction operation for a parallel run. The information from all nodes is collected on th...
void reserve(const label)
Reserve allocation space for at least this size.
Definition: DynamicListI.H:152
const labelList & meshPoints() const
Return labelList of mesh points in patch. They are constructed.
Neighbour processor patch.
Input inter-processor communications stream operating on external buffer.
Definition: UIPstream.H:53
scalar y
A list of faces which address into the list of points.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
label nPoints
Cyclic plane patch.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
int neighbProcNo() const
Return neighbour processor number.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
label constructSize() const
Constructed data size.
Output inter-processor communications stream operating on external buffer.
Definition: UOPstream.H:54
static const char nl
Definition: Ostream.H:260
PointEdgeWave(const polyMesh &mesh, const labelList &initialPoints, const List< Type > &initialPointsInfo, UList< Type > &allPointInfo, UList< Type > &allEdgeInfo, const label maxIter, TrackingData &td=defaultTrackingData_)
Construct from mesh, list of changed points with the Type.
void operator()(Type &x, const Type &y) const
Definition: PointEdgeWave.C:61
Buffers for inter-processor communications streams (UOPstream, UIPstream).
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
const indirectPrimitivePatch & coupledPatch() const
Return patch of all coupled faces.
Class containing processor-to-processor mapping information.
virtual const transformer & transform() const
Return null transform between processor patches.
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:399
label patchi
bool equal(const T &s1, const T &s2)
Definition: doubleFloat.H:62
const distributionMap & globalPointSlavesMap() const
messageStream Info
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
const doubleScalar e
Elementary charge.
Definition: doubleScalar.H:105
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:76
label getUnsetPoints() const
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
void clear()
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:236
Wave propagation of information through grid. Every iteration information goes through one layer of e...
Definition: PointEdgeWave.H:86
label getUnsetEdges() const
Get number of unvisited edges, i.e. edges that were not (yet)
Namespace for OpenFOAM.
dimensionSet transform(const dimensionSet &)
Definition: dimensionSet.C:483