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