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