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