PointEdgeWave.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) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2021-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 
29 #include "PointEdgeWave.H"
30 #include "polyMesh.H"
31 #include "processorPolyPatch.H"
32 #include "cyclicPolyPatch.H"
33 #include "UIPstream.H"
34 #include "UOPstream.H"
35 #include "debug.H"
36 #include "typeInfo.H"
37 #include "globalMeshData.H"
38 #include "pointFields.H"
39 
40 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 
42 namespace Foam
43 {
44  //- Reduction class. If x and y are not equal assign value.
45  template<class Type, class TrackingData>
46  class combineEqOp
47  {
48  TrackingData& td_;
49 
50  public:
51 
52  combineEqOp(TrackingData& td)
53  :
54  td_(td)
55  {}
56 
57  void operator()(Type& x, const Type& y) const
58  {
59  if (!x.valid(td_) && y.valid(td_))
60  {
61  x = y;
62  }
63  }
64  };
65 }
66 
67 
68 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
69 
70 // Handle leaving domain. Implementation referred to Type
71 template<class Type, class TrackingData>
73 (
74  const polyPatch& patch,
75  const labelList& patchPointLabels,
76  List<Type>& pointInfo
77 ) const
78 {
79  const labelList& meshPoints = patch.meshPoints();
80 
81  forAll(patchPointLabels, i)
82  {
83  label patchPointi = patchPointLabels[i];
84 
85  const point& pt = patch.points()[meshPoints[patchPointi]];
86 
87  pointInfo[i].leaveDomain(patch, patchPointi, pt, td_);
88  }
89 }
90 
91 
92 // Handle entering domain. Implementation referred to Type
93 template<class Type, class TrackingData>
95 (
96  const polyPatch& patch,
97  const labelList& patchPointLabels,
98  List<Type>& pointInfo
99 ) const
100 {
101  const labelList& meshPoints = patch.meshPoints();
102 
103  forAll(patchPointLabels, i)
104  {
105  label patchPointi = patchPointLabels[i];
106 
107  const point& pt = patch.points()[meshPoints[patchPointi]];
108 
109  pointInfo[i].enterDomain(patch, patchPointi, pt, td_);
110  }
111 }
112 
113 
114 // Transform. Implementation referred to Type
115 template<class Type, class TrackingData>
117 (
118  const polyPatch& patch,
119  const tensorField& rotTensor,
120  List<Type>& pointInfo
121 ) const
122 {
123  if (rotTensor.size() == 1)
124  {
125  const tensor& T = rotTensor[0];
126 
127  forAll(pointInfo, i)
128  {
129  pointInfo[i].transform(T, td_);
130  }
131  }
132  else
133  {
135  << "Non-uniform transformation on patch " << patch.name()
136  << " of type " << patch.type()
137  << " not supported for point fields"
138  << abort(FatalError);
139 
140  forAll(pointInfo, i)
141  {
142  pointInfo[i].transform(rotTensor[i], td_);
143  }
144  }
145 }
146 
147 
148 // Update info for pointi, at position pt, with information from
149 // neighbouring edge.
150 // Updates:
151 // - changedPoint_, changedPoints_,
152 // - statistics: nEvals_, nUnvisitedPoints_
153 template<class Type, class TrackingData>
155 (
156  const label pointi,
157  const label neighbourEdgeI,
158  const Type& neighbourInfo,
159  Type& pointInfo
160 )
161 {
162  nEvals_++;
163 
164  bool wasValid = pointInfo.valid(td_);
165 
166  bool propagate =
167  pointInfo.updatePoint
168  (
169  mesh_,
170  pointi,
171  neighbourEdgeI,
172  neighbourInfo,
173  propagationTol_,
174  td_
175  );
176 
177  if (propagate)
178  {
179  if (changedPoint_.set(pointi))
180  {
181  changedPoints_.push_back(pointi);
182  }
183  }
184 
185  if (!wasValid && pointInfo.valid(td_))
186  {
187  --nUnvisitedPoints_;
188  }
189 
190  return propagate;
191 }
192 
193 
194 // Update info for pointi, at position pt, with information from
195 // same point.
196 // Updates:
197 // - changedPoint_, changedPoints_,
198 // - statistics: nEvals_, nUnvisitedPoints_
199 template<class Type, class TrackingData>
201 (
202  const label pointi,
203  const Type& neighbourInfo,
204  Type& pointInfo
205 )
206 {
207  nEvals_++;
208 
209  bool wasValid = pointInfo.valid(td_);
210 
211  bool propagate =
212  pointInfo.updatePoint
213  (
214  mesh_,
215  pointi,
216  neighbourInfo,
217  propagationTol_,
218  td_
219  );
220 
221  if (propagate)
222  {
223  if (changedPoint_.set(pointi))
224  {
225  changedPoints_.push_back(pointi);
226  }
227  }
228 
229  if (!wasValid && pointInfo.valid(td_))
230  {
231  --nUnvisitedPoints_;
232  }
233 
234  return propagate;
235 }
236 
237 
238 // Update info for edgei, at position pt, with information from
239 // neighbouring point.
240 // Updates:
241 // - changedEdge_, changedEdges_,
242 // - statistics: nEvals_, nUnvisitedEdge_
243 template<class Type, class TrackingData>
245 (
246  const label edgei,
247  const label neighbourPointi,
248  const Type& neighbourInfo,
249  Type& edgeInfo
250 )
251 {
252  nEvals_++;
253 
254  bool wasValid = edgeInfo.valid(td_);
255 
256  bool propagate =
257  edgeInfo.updateEdge
258  (
259  mesh_,
260  edgei,
261  neighbourPointi,
262  neighbourInfo,
263  propagationTol_,
264  td_
265  );
266 
267  if (propagate)
268  {
269  if (changedEdge_.set(edgei))
270  {
271  changedEdges_.push_back(edgei);
272  }
273  }
274 
275  if (!wasValid && edgeInfo.valid(td_))
276  {
277  --nUnvisitedEdges_;
278  }
279 
280  return propagate;
281 }
283 
284 // Check if patches of given type name are present
285 template<class Type, class TrackingData>
286 template<class PatchType>
288 {
289  label nPatches = 0;
290 
291  for (const polyPatch& p : mesh_.boundaryMesh())
292  {
293  if (isA<PatchType>(p))
294  {
295  ++nPatches;
296  }
297  }
298  return nPatches;
299 }
300 
301 
302 // Transfer all the information to/from neighbouring processors
303 template<class Type, class TrackingData>
305 {
306  // 1. Send all point info on processor patches.
307 
308  PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
309 
310  DynamicList<Type> patchInfo;
311  DynamicList<label> thisPoints;
312  DynamicList<label> nbrPoints;
313 
314  forAll(mesh_.globalData().processorPatches(), i)
315  {
316  label patchi = mesh_.globalData().processorPatches()[i];
317  const processorPolyPatch& procPatch =
318  refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchi]);
319 
320  patchInfo.clear();
321  patchInfo.reserve(procPatch.nPoints());
322  thisPoints.clear();
323  thisPoints.reserve(procPatch.nPoints());
324  nbrPoints.clear();
325  nbrPoints.reserve(procPatch.nPoints());
326 
327  // Get all changed points in reverse order
328  const labelList& neighbPoints = procPatch.neighbPoints();
329  forAll(neighbPoints, thisPointi)
330  {
331  label meshPointi = procPatch.meshPoints()[thisPointi];
332  if (changedPoint_.test(meshPointi))
333  {
334  patchInfo.append(allPointInfo_[meshPointi]);
335  thisPoints.append(thisPointi);
336  nbrPoints.append(neighbPoints[thisPointi]);
337  }
338  }
339 
340  // Adapt for leaving domain
341  leaveDomain(procPatch, thisPoints, patchInfo);
342 
343  //if (debug)
344  //{
345  // Pout<< "Processor patch " << patchi << ' ' << procPatch.name()
346  // << " communicating with " << procPatch.neighbProcNo()
347  // << " Sending:" << patchInfo.size() << endl;
348  //}
349 
350  UOPstream toNeighbour(procPatch.neighbProcNo(), pBufs);
351  toNeighbour << nbrPoints << patchInfo;
352  }
353 
354 
355  pBufs.finishedSends();
356 
357  //
358  // 2. Receive all point info on processor patches.
359  //
360 
361  forAll(mesh_.globalData().processorPatches(), i)
362  {
363  label patchi = mesh_.globalData().processorPatches()[i];
364  const processorPolyPatch& procPatch =
365  refCast<const processorPolyPatch>(mesh_.boundaryMesh()[patchi]);
366 
367  List<Type> patchInfo;
368  labelList patchPoints;
369 
370  {
371  UIPstream fromNeighbour(procPatch.neighbProcNo(), pBufs);
372  fromNeighbour >> patchPoints >> patchInfo;
373  }
374 
375  //if (debug)
376  //{
377  // Pout<< "Processor patch " << patchi << ' ' << procPatch.name()
378  // << " communicating with " << procPatch.neighbProcNo()
379  // << " Received:" << patchInfo.size() << endl;
380  //}
381 
382  // Apply transform to received data for non-parallel planes
383  if (!procPatch.parallel())
384  {
385  transform(procPatch, procPatch.forwardT(), patchInfo);
386  }
387 
388  // Adapt for entering domain
389  enterDomain(procPatch, patchPoints, patchInfo);
390 
391  // Merge received info
392  const labelList& meshPoints = procPatch.meshPoints();
393  forAll(patchInfo, i)
394  {
395  label meshPointi = meshPoints[patchPoints[i]];
396 
397  if (!allPointInfo_[meshPointi].equal(patchInfo[i], td_))
398  {
399  updatePoint
400  (
401  meshPointi,
402  patchInfo[i],
403  allPointInfo_[meshPointi]
404  );
405  }
406  }
407  }
408 
409  // Collocated points should be handled by face based transfer
410  // (since that is how connectivity is worked out)
411  // They are also explicitly equalised in handleCollocatedPoints to
412  // guarantee identical values.
413 }
414 
415 
416 template<class Type, class TrackingData>
418 {
419  // 1. Send all point info on cyclic patches.
420 
421  DynamicList<Type> nbrInfo;
422  DynamicList<label> nbrPoints;
423  DynamicList<label> thisPoints;
424 
425  for (const polyPatch& patch : mesh_.boundaryMesh())
426  {
427  const cyclicPolyPatch* cpp = isA<cyclicPolyPatch>(patch);
428 
429  if (cpp)
430  {
431  const auto& cycPatch = *cpp;
432  const auto& nbrPatch = cycPatch.neighbPatch();
433 
434  nbrInfo.clear();
435  nbrInfo.reserve(cycPatch.nPoints());
436  nbrPoints.clear();
437  nbrPoints.reserve(cycPatch.nPoints());
438  thisPoints.clear();
439  thisPoints.reserve(cycPatch.nPoints());
440 
441  // Collect nbrPatch points that have changed
442  {
443  const edgeList& pairs = cycPatch.coupledPoints();
444  const labelList& meshPoints = nbrPatch.meshPoints();
445 
446  forAll(pairs, pairI)
447  {
448  label thisPointi = pairs[pairI][0];
449  label nbrPointi = pairs[pairI][1];
450  label meshPointi = meshPoints[nbrPointi];
451 
452  if (changedPoint_.test(meshPointi))
453  {
454  nbrInfo.append(allPointInfo_[meshPointi]);
455  nbrPoints.append(nbrPointi);
456  thisPoints.append(thisPointi);
457  }
458  }
459 
460  // nbr : adapt for leaving domain
461  leaveDomain(nbrPatch, nbrPoints, nbrInfo);
462  }
463 
464 
465  // Apply rotation for non-parallel planes
466 
467  if (!cycPatch.parallel())
468  {
469  // received data from half1
470  transform(cycPatch, cycPatch.forwardT(), nbrInfo);
471  }
472 
473  //if (debug)
474  //{
475  // Pout<< "Cyclic patch " << patch.index() << ' ' << patch.name()
476  // << " Changed : " << nbrInfo.size()
477  // << endl;
478  //}
479 
480  // Adapt for entering domain
481  enterDomain(cycPatch, thisPoints, nbrInfo);
482 
483  // Merge received info
484  const labelList& meshPoints = cycPatch.meshPoints();
485  forAll(nbrInfo, i)
486  {
487  label meshPointi = meshPoints[thisPoints[i]];
488 
489  if (!allPointInfo_[meshPointi].equal(nbrInfo[i], td_))
490  {
491  updatePoint
492  (
493  meshPointi,
494  nbrInfo[i],
495  allPointInfo_[meshPointi]
496  );
497  }
498  }
499  }
500  }
501 }
502 
503 
504 // Guarantee collocated points have same information.
505 // Return number of points changed.
506 template<class Type, class TrackingData>
508 {
509  // Transfer onto coupled patch
510  const globalMeshData& gmd = mesh_.globalData();
511  const indirectPrimitivePatch& cpp = gmd.coupledPatch();
512  const labelList& meshPoints = cpp.meshPoints();
513 
514  const mapDistribute& slavesMap = gmd.globalPointSlavesMap();
515  const labelListList& slaves = gmd.globalPointSlaves();
516 
517  List<Type> elems(slavesMap.constructSize());
518  forAll(meshPoints, pointi)
519  {
520  elems[pointi] = allPointInfo_[meshPoints[pointi]];
521  }
522 
523  // Pull slave data onto master (which might or might not have any
524  // initialised points). No need to update transformed slots.
525  slavesMap.distribute(elems, false);
526 
527  // Combine master data with slave data
528  combineEqOp<Type, TrackingData> cop(td_);
529 
530  forAll(slaves, pointi)
531  {
532  Type& elem = elems[pointi];
533 
534  const labelList& slavePoints = slaves[pointi];
535 
536  // Combine master with untransformed slave data
537  forAll(slavePoints, j)
538  {
539  cop(elem, elems[slavePoints[j]]);
540  }
541 
542  // Copy result back to slave slots
543  forAll(slavePoints, j)
544  {
545  elems[slavePoints[j]] = elem;
546  }
547  }
548 
549  // Push slave-slot data back to slaves
550  slavesMap.reverseDistribute(elems.size(), elems, false);
551 
552  // Extract back onto mesh
553  forAll(meshPoints, pointi)
554  {
555  if (elems[pointi].valid(td_))
556  {
557  label meshPointi = meshPoints[pointi];
558 
559  Type& elem = allPointInfo_[meshPointi];
560 
561  bool wasValid = elem.valid(td_);
562 
563  // Like updatePoint but bypass Type::updatePoint with its tolerance
564  // checking
565  //if (!elem.valid(td_) || !elem.equal(elems[pointi], td_))
566  if (!elem.equal(elems[pointi], td_))
567  {
568  nEvals_++;
569  elem = elems[pointi];
570 
571  // See if element now valid
572  if (!wasValid && elem.valid(td_))
573  {
574  --nUnvisitedPoints_;
575  }
576 
577  // Update database of changed points
578  if (changedPoint_.set(meshPointi))
579  {
580  changedPoints_.push_back(meshPointi);
581  }
582  }
583  }
584  }
585 
586  // Sum changedPoints over all procs
587  return returnReduce(nChangedPoints(), sumOp<label>());
588 }
589 
590 
591 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
593 // Iterate, propagating changedPointsInfo across mesh, until no change (or
594 // maxIter reached). Initial point values specified.
595 template<class Type, class TrackingData>
597 (
598  const polyMesh& mesh,
599  const labelList& changedPoints,
600  const List<Type>& changedPointsInfo,
601 
602  UList<Type>& allPointInfo,
603  UList<Type>& allEdgeInfo,
604 
605  const label maxIter,
606  TrackingData& td
607 )
608 :
610 
611  allPointInfo_(allPointInfo),
612  allEdgeInfo_(allEdgeInfo),
613  td_(td),
614  nCyclicPatches_(countPatchType<cyclicPolyPatch>()),
615  nEvals_(0)
616 {
617  if (allPointInfo_.size() != mesh_.nPoints())
618  {
620  << "size of pointInfo work array is not equal to the number"
621  << " of points in the mesh" << endl
622  << " pointInfo :" << allPointInfo_.size() << endl
623  << " mesh.nPoints:" << mesh_.nPoints()
624  << exit(FatalError);
625  }
626  if (allEdgeInfo_.size() != mesh_.nEdges())
627  {
629  << "size of edgeInfo work array is not equal to the number"
630  << " of edges in the mesh" << endl
631  << " edgeInfo :" << allEdgeInfo_.size() << endl
632  << " mesh.nEdges:" << mesh_.nEdges()
633  << exit(FatalError);
634  }
635 
636 
637  // Set from initial changed points data
638  setPointInfo(changedPoints, changedPointsInfo);
639 
640  if (debug)
641  {
642  Info<< typeName << ": Seed points : "
644  }
645 
646  // Iterate until nothing changes
647  label iter = iterate(maxIter);
648 
649  if ((maxIter > 0) && (iter >= maxIter))
650  {
652  << "Maximum number of iterations reached. Increase maxIter." << endl
653  << " maxIter:" << maxIter << nl
654  << " nChangedPoints:" << nChangedPoints() << nl
655  << " nChangedEdges:" << nChangedEdges() << endl
656  << exit(FatalError);
657  }
658 }
659 
660 
661 template<class Type, class TrackingData>
663 (
664  const polyMesh& mesh,
665  UList<Type>& allPointInfo,
666  UList<Type>& allEdgeInfo,
667  TrackingData& td
668 )
669 :
671 
672  allPointInfo_(allPointInfo),
673  allEdgeInfo_(allEdgeInfo),
674  td_(td),
675  nCyclicPatches_(countPatchType<cyclicPolyPatch>()),
676  nEvals_(0)
677 {}
678 
679 
680 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
681 
682 // Copy point information into member data
683 template<class Type, class TrackingData>
685 (
686  const labelList& changedPoints,
687  const List<Type>& changedPointsInfo
688 )
689 {
690  forAll(changedPoints, changedPointi)
691  {
692  const label pointi = changedPoints[changedPointi];
693 
694  const bool wasValid = allPointInfo_[pointi].valid(td_);
695 
696  // Copy info for pointi
697  allPointInfo_[pointi] = changedPointsInfo[changedPointi];
698 
699  // Maintain count of unset points
700  if (!wasValid && allPointInfo_[pointi].valid(td_))
701  {
702  --nUnvisitedPoints_;
703  }
704 
705  // Mark pointi as changed, both on list and on point itself.
706 
707  if (changedPoint_.set(pointi))
708  {
709  changedPoints_.push_back(pointi);
710  }
711  }
712 
713  // Sync
714  handleCollocatedPoints();
715 }
716 
717 
718 // Propagate information from edge to point. Return number of points changed.
719 template<class Type, class TrackingData>
721 {
722  for (const label edgei : changedEdges_)
723  {
724  if (!changedEdge_.test(edgei))
725  {
727  << "edge " << edgei
728  << " not marked as having been changed" << nl
729  << "This might be caused by multiple occurrences of the same"
730  << " seed point." << abort(FatalError);
731  }
732 
733 
734  const Type& neighbourWallInfo = allEdgeInfo_[edgei];
735 
736  // Evaluate all connected points (= edge endpoints)
737  const edge& e = mesh_.edges()[edgei];
738 
739  forAll(e, eI)
740  {
741  Type& currentWallInfo = allPointInfo_[e[eI]];
742 
743  if (!currentWallInfo.equal(neighbourWallInfo, td_))
744  {
745  updatePoint
746  (
747  e[eI],
748  edgei,
749  neighbourWallInfo,
750  currentWallInfo
751  );
752  }
753  }
754 
755  // Reset status of edge
756  changedEdge_.unset(edgei);
757  }
758 
759  // Handled all changed edges by now
760  changedEdges_.clear();
761 
762  if (nCyclicPatches_ > 0)
763  {
764  // Transfer changed points across cyclic halves
765  handleCyclicPatches();
766  }
767  if (Pstream::parRun())
768  {
769  // Transfer changed points from neighbouring processors.
770  handleProcPatches();
771  }
772 
773  //if (debug)
774  //{
775  // Pout<< "Changed points : " << nChangedPoints() << nl;
776  //}
777 
778  // Sum changedPoints over all procs
779  return returnReduce(nChangedPoints(), sumOp<label>());
780 }
781 
782 
783 // Propagate information from point to edge. Return number of edges changed.
784 template<class Type, class TrackingData>
786 {
787  const labelListList& pointEdges = mesh_.pointEdges();
788 
789  for (const label pointi : changedPoints_)
790  {
791  if (!changedPoint_.test(pointi))
792  {
794  << "Point " << pointi
795  << " not marked as having been changed" << nl
796  << "This might be caused by multiple occurrences of the same"
797  << " seed point." << abort(FatalError);
798  }
799 
800  const Type& neighbourWallInfo = allPointInfo_[pointi];
801 
802  // Evaluate all connected edges
803 
804  for (const label edgei : pointEdges[pointi])
805  {
806  Type& currentWallInfo = allEdgeInfo_[edgei];
807 
808  if (!currentWallInfo.equal(neighbourWallInfo, td_))
809  {
810  updateEdge
811  (
812  edgei,
813  pointi,
814  neighbourWallInfo,
815  currentWallInfo
816  );
817  }
818  }
819 
820  // Reset status of point
821  changedPoint_.unset(pointi);
822  }
823 
824  // Handled all changed points by now
825  changedPoints_.clear();
826 
827  //if (debug)
828  //{
829  // Pout<< "Changed edges : " << nChangedEdges() << endl;
830  //}
831 
832  // Sum changedEdges over all procs
833  return returnReduce(nChangedEdges(), sumOp<label>());
834 }
836 
837 // Iterate
838 template<class Type, class TrackingData>
840 (
841  const label maxIter
842 )
843 {
844  if (nCyclicPatches_ > 0)
845  {
846  // Transfer changed points across cyclic halves
847  handleCyclicPatches();
848  }
849  if (Pstream::parRun())
850  {
851  // Transfer changed points from neighbouring processors.
852  handleProcPatches();
853  }
854 
855  nEvals_ = 0;
856 
857  label iter = 0;
858 
859  while (iter < maxIter)
860  {
861  while (iter < maxIter)
862  {
863  if (debug)
864  {
865  Info<< typeName << ": Iteration " << iter << endl;
866  }
867 
868  label nEdges = pointToEdge();
869 
870  if (debug)
871  {
872  Info<< typeName << ": Total changed edges : "
873  << nEdges << endl;
874  }
875 
876  if (nEdges == 0)
877  {
878  break;
879  }
880 
881  label nPoints = edgeToPoint();
882 
883  if (debug)
884  {
885  Info<< typeName << ": Total changed points : "
886  << nPoints << nl
887  << typeName << ": Total evaluations : "
888  << returnReduce(nEvals_, sumOp<label>()) << nl
889  << typeName << ": Remaining unvisited points: "
890  << returnReduce(nUnvisitedPoints_, sumOp<label>()) << nl
891  << typeName << ": Remaining unvisited edges : "
892  << returnReduce(nUnvisitedEdges_, sumOp<label>()) << nl
893  << endl;
894  }
895 
896  if (nPoints == 0)
897  {
898  break;
899  }
900 
901  iter++;
902  }
903 
904 
905  // Enforce collocated points are exactly equal. This might still mean
906  // non-collocated points are not equal though. WIP.
907  label nPoints = handleCollocatedPoints();
908  if (debug)
909  {
910  Info<< typeName << ": Collocated point sync : "
911  << nPoints << nl << endl;
912  }
913 
914  if (nPoints == 0)
915  {
916  break;
917  }
918  }
919 
920  return iter;
921 }
922 
923 
924 // ************************************************************************* //
label nPatches
Definition: readKivaGrid.H:396
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:51
label nPoints() const
Number of points supporting patch faces.
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:118
Reduction class. If x and y are not equal assign value.
Definition: PointEdgeWave.C:41
const labelList & neighbPoints() const
Return neighbour point labels. WIP.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
label nPoints() const noexcept
Number of mesh points.
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
label pointToEdge()
Propagate from point to edge. Returns total number of edges.
const polyMesh & mesh_
Reference to mesh.
Definition: PointEdgeWave.H:96
label iterate(const label maxIter)
Iterate until no changes or maxIter reached. Returns actual.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
Tensor< scalar > tensor
Definition: symmTensor.H:57
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:639
label edgeToPoint()
Propagate from edge to point. Returns total number of points.
void setPointInfo(const labelList &changedPoints, const List< Type > &changedPointsInfo)
Copy initial data into allPointInfo_.
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
A PrimitivePatch with an IndirectList for the faces, const reference for the point field...
combineEqOp(TrackingData &td)
Definition: PointEdgeWave.C:47
void push_back(const T &val)
Append an element at the end of the list.
Definition: ListI.H:168
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.
bool equal(const Matrix< Form1, Type > &A, const Matrix< Form2, Type > &B, const bool verbose=false, const label maxDiffs=10, const scalar relTol=1e-5, const scalar absTol=1e-8)
Compare matrix elements for absolute or relative equality.
Definition: MatrixTools.C:27
const labelList & meshPoints() const
Return labelList of mesh points in patch.
Neighbour processor patch.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:413
scalar y
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
dynamicFvMesh & mesh
List< edge > edgeList
A List of edges.
Definition: edgeList.H:60
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:59
label nPoints
Cyclic plane patch.
label nChangedEdges() const noexcept
Current number of changed edges.
void append(const T &val)
Copy append an element to the end of this list.
Definition: DynamicList.H:558
int neighbProcNo() const
Return neighbour processor number.
errorManip< error > abort(error &err)
Definition: errorManip.H:139
label nEdges() const
Number of mesh edges.
void reserve(const label len)
Reserve allocation space for at least this size, allocating new space if required and retaining old c...
Definition: DynamicListI.H:326
int debug
Static debugging option.
void operator()(Type &x, const Type &y) const
Definition: PointEdgeWave.C:52
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:384
Buffers for inter-processor communications streams (UOPstream, UIPstream).
const volScalarField & T
Field< tensor > tensorField
Specialisation of Field<T> for tensor.
vector point
Point is a vector.
Definition: point.H:37
const std::string patch
OpenFOAM patch number as a std::string.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:73
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:69
Wave propagation of information through grid. Every iteration information goes through one layer of e...
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:529
label nChangedPoints() const noexcept
Current number of changed points.
Namespace for OpenFOAM.