syncToolsTemplates.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) 2015-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 "syncTools.H"
30 #include "polyMesh.H"
31 #include "processorPolyPatch.H"
32 #include "cyclicPolyPatch.H"
33 #include "globalMeshData.H"
34 #include "transformList.H"
35 
36 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
37 
38 template<class T, class CombineOp>
39 void Foam::syncTools::combine
40 (
41  Map<T>& pointValues,
42  const CombineOp& cop,
43  const label index,
44  const T& val
45 )
46 {
47  auto iter = pointValues.find(index);
48 
49  if (iter.found())
50  {
51  cop(*iter, val);
52  }
53  else
54  {
55  pointValues.insert(index, val);
56  }
57 }
58 
59 
60 template<class T, class CombineOp>
61 void Foam::syncTools::combine
62 (
63  EdgeMap<T>& edgeValues,
64  const CombineOp& cop,
65  const edge& index,
66  const T& val
67 )
68 {
69  auto iter = edgeValues.find(index);
70 
71  if (iter.found())
72  {
73  cop(*iter, val);
74  }
75  else
76  {
77  edgeValues.insert(index, val);
78  }
79 }
80 
81 
82 template<class T, class CombineOp, class TransformOp>
84 (
85  const polyMesh& mesh,
86  Map<T>& pointValues, // from mesh point label to value
87  const CombineOp& cop,
88  const TransformOp& top
89 )
90 {
92 
93  // Synchronize multiple shared points.
94  const globalMeshData& pd = mesh.globalData();
95 
96  // Values on shared points. Keyed on global shared index.
97  Map<T> sharedPointValues(0);
98 
99  if (pd.nGlobalPoints() > 0)
100  {
101  // meshPoint per local index
102  const labelList& sharedPtLabels = pd.sharedPointLabels();
103 
104  // global shared index per local index
105  const labelList& sharedPtAddr = pd.sharedPointAddr();
106 
107  sharedPointValues.resize(sharedPtAddr.size());
108 
109  // Fill my entries in the shared points
110  forAll(sharedPtLabels, i)
111  {
112  const auto fnd = pointValues.cfind(sharedPtLabels[i]);
113 
114  if (fnd.found())
115  {
116  combine
117  (
118  sharedPointValues,
119  cop,
120  sharedPtAddr[i], // index
121  *fnd // value
122  );
123  }
124  }
125  }
126 
127 
128  if (Pstream::parRun())
129  {
131 
132  // Send
133  for (const polyPatch& pp : patches)
134  {
135  const auto* ppp = isA<processorPolyPatch>(pp);
136 
137  if (ppp && pp.nPoints())
138  {
139  const auto& procPatch = *ppp;
140 
141  // Get data per patchPoint in neighbouring point numbers.
142 
143  const labelList& meshPts = procPatch.meshPoints();
144  const labelList& nbrPts = procPatch.neighbPoints();
145 
146  // Extract local values. Create map from nbrPoint to value.
147  // Note: how small initial size?
148  Map<T> patchInfo(meshPts.size() / 20);
149 
150  forAll(meshPts, i)
151  {
152  const auto iter = pointValues.cfind(meshPts[i]);
153 
154  if (iter.found())
155  {
156  patchInfo.insert(nbrPts[i], *iter);
157  }
158  }
159 
160  UOPstream toNeighb(procPatch.neighbProcNo(), pBufs);
161  toNeighb << patchInfo;
162  }
163  }
164 
165  pBufs.finishedSends();
166 
167  // Receive and combine.
168  for (const polyPatch& pp : patches)
169  {
170  const auto* ppp = isA<processorPolyPatch>(pp);
171 
172  if (ppp && pp.nPoints())
173  {
174  const auto& procPatch = *ppp;
175 
176  UIPstream fromNbr(procPatch.neighbProcNo(), pBufs);
177  Map<T> nbrPatchInfo(fromNbr);
178 
179  // Transform
180  top(procPatch, nbrPatchInfo);
181 
182  const labelList& meshPts = procPatch.meshPoints();
183 
184  // Only update those values which come from neighbour
185  forAllConstIters(nbrPatchInfo, nbrIter)
186  {
187  combine
188  (
189  pointValues,
190  cop,
191  meshPts[nbrIter.key()],
192  nbrIter.val()
193  );
194  }
195  }
196  }
197  }
198 
199  // Do the cyclics.
200  for (const polyPatch& pp : patches)
201  {
202  const cyclicPolyPatch* cpp = isA<cyclicPolyPatch>(pp);
203 
204  if (cpp && cpp->owner())
205  {
206  // Owner does all.
207 
208  const cyclicPolyPatch& cycPatch = *cpp;
209  const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
210 
211  const edgeList& coupledPoints = cycPatch.coupledPoints();
212  const labelList& meshPtsA = cycPatch.meshPoints();
213  const labelList& meshPtsB = nbrPatch.meshPoints();
214 
215  // Extract local values. Create map from coupled-edge to value.
216  Map<T> half0Values(meshPtsA.size() / 20);
217  Map<T> half1Values(half0Values.size());
218 
219  forAll(coupledPoints, i)
220  {
221  const edge& e = coupledPoints[i];
222 
223  const auto point0Fnd = pointValues.cfind(meshPtsA[e[0]]);
224 
225  if (point0Fnd.found())
226  {
227  half0Values.insert(i, *point0Fnd);
228  }
229 
230  const auto point1Fnd = pointValues.cfind(meshPtsB[e[1]]);
231 
232  if (point1Fnd.found())
233  {
234  half1Values.insert(i, *point1Fnd);
235  }
236  }
237 
238  // Transform to receiving side
239  top(cycPatch, half1Values);
240  top(nbrPatch, half0Values);
241 
242  forAll(coupledPoints, i)
243  {
244  const edge& e = coupledPoints[i];
245 
246  const auto half0Fnd = half0Values.cfind(i);
247 
248  if (half0Fnd.found())
249  {
250  combine
251  (
252  pointValues,
253  cop,
254  meshPtsB[e[1]],
255  *half0Fnd
256  );
257  }
258 
259  const auto half1Fnd = half1Values.cfind(i);
260 
261  if (half1Fnd.found())
262  {
263  combine
264  (
265  pointValues,
266  cop,
267  meshPtsA[e[0]],
268  *half1Fnd
269  );
270  }
271  }
272  }
273  }
274 
275  // Synchronize multiple shared points.
276  if (pd.nGlobalPoints() > 0)
277  {
278  // meshPoint per local index
279  const labelList& sharedPtLabels = pd.sharedPointLabels();
280  // global shared index per local index
281  const labelList& sharedPtAddr = pd.sharedPointAddr();
282 
283  // Reduce on master.
284 
285  if (Pstream::parRun())
286  {
287  if (Pstream::master())
288  {
289  // Receive the edges using shared points from the slave.
290  for (const int slave : Pstream::subProcs())
291  {
292  IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
293  Map<T> nbrValues(fromSlave);
294 
295  // Merge neighbouring values with my values
296  forAllConstIters(nbrValues, iter)
297  {
298  combine
299  (
300  sharedPointValues,
301  cop,
302  iter.key(), // edge
303  iter.val() // value
304  );
305  }
306  }
307 
308  // Send back
309  for (const int slave : Pstream::subProcs())
310  {
312  toSlave << sharedPointValues;
313  }
314  }
315  else
316  {
317  // Slave: send to master
318  {
319  OPstream toMaster
320  (
323  );
324  toMaster << sharedPointValues;
325  }
326  // Receive merged values
327  {
328  IPstream fromMaster
329  (
332  );
333  fromMaster >> sharedPointValues;
334  }
335  }
336  }
337 
338 
339  // Merge sharedPointValues (keyed on sharedPointAddr) into
340  // pointValues (keyed on mesh points).
341 
342  // Map from global shared index to meshpoint
343  Map<label> sharedToMeshPoint(2*sharedPtAddr.size());
344  forAll(sharedPtAddr, i)
345  {
346  sharedToMeshPoint.insert(sharedPtAddr[i], sharedPtLabels[i]);
347  }
348 
349  forAllConstIters(sharedToMeshPoint, iter)
350  {
351  // Do I have a value for my shared point
352  const auto sharedFnd = sharedPointValues.cfind(iter.key());
353 
354  if (sharedFnd.found())
355  {
356  pointValues.set(*iter, *sharedFnd);
357  }
358  }
359  }
360 }
361 
362 
363 template<class T, class CombineOp, class TransformOp>
365 (
366  const polyMesh& mesh,
367  EdgeMap<T>& edgeValues,
368  const CombineOp& cop,
369  const TransformOp& top
370 )
371 {
373 
374 
375  // Do synchronisation without constructing globalEdge addressing
376  // (since this constructs mesh edge addressing)
377 
378 
379  // Swap proc patch info
380  // ~~~~~~~~~~~~~~~~~~~~
381 
382  if (Pstream::parRun())
383  {
385 
386  // Send
387  for (const polyPatch& pp : patches)
388  {
389  const auto* ppp = isA<processorPolyPatch>(pp);
390 
391  if (ppp && pp.nEdges())
392  {
393  const auto& procPatch = *ppp;
394 
395  // Get data per patch edge in neighbouring edge.
396 
397  const edgeList& edges = procPatch.edges();
398  const labelList& meshPts = procPatch.meshPoints();
399  const labelList& nbrPts = procPatch.neighbPoints();
400 
401  EdgeMap<T> patchInfo(edges.size() / 20);
402 
403  for (const edge& e : edges)
404  {
405  const edge meshEdge(meshPts[e[0]], meshPts[e[1]]);
406 
407  const auto iter = edgeValues.cfind(meshEdge);
408 
409  if (iter.found())
410  {
411  const edge nbrEdge(nbrPts[e[0]], nbrPts[e[1]]);
412  patchInfo.insert(nbrEdge, *iter);
413  }
414  }
415 
416  UOPstream toNeighb(procPatch.neighbProcNo(), pBufs);
417  toNeighb << patchInfo;
418  }
419  }
420 
421  pBufs.finishedSends();
422 
423  // Receive and combine.
424  for (const polyPatch& pp : patches)
425  {
426  const auto* ppp = isA<processorPolyPatch>(pp);
427 
428  if (ppp && pp.nEdges())
429  {
430  const auto& procPatch = *ppp;
431 
432  EdgeMap<T> nbrPatchInfo;
433  {
434  UIPstream fromNbr(procPatch.neighbProcNo(), pBufs);
435  fromNbr >> nbrPatchInfo;
436  }
437 
438  // Apply transform to convert to this side properties.
439  top(procPatch, nbrPatchInfo);
440 
441 
442  // Only update those values which come from neighbour
443  const labelList& meshPts = procPatch.meshPoints();
444 
445  forAllConstIters(nbrPatchInfo, nbrIter)
446  {
447  const edge& e = nbrIter.key();
448  const edge meshEdge(meshPts[e[0]], meshPts[e[1]]);
449 
450  combine
451  (
452  edgeValues,
453  cop,
454  meshEdge, // edge
455  nbrIter.val() // value
456  );
457  }
458  }
459  }
460  }
461 
462 
463  // Swap cyclic info
464  // ~~~~~~~~~~~~~~~~
465 
466  for (const polyPatch& pp : patches)
467  {
468  const cyclicPolyPatch* cpp = isA<cyclicPolyPatch>(pp);
469 
470  if (cpp && cpp->owner())
471  {
472  // Owner does all.
473 
474  const cyclicPolyPatch& cycPatch = *cpp;
475  const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
476 
477  const edgeList& coupledEdges = cycPatch.coupledEdges();
478 
479  const labelList& meshPtsA = cycPatch.meshPoints();
480  const edgeList& edgesA = cycPatch.edges();
481 
482  const labelList& meshPtsB = nbrPatch.meshPoints();
483  const edgeList& edgesB = nbrPatch.edges();
484 
485  // Extract local values. Create map from edge to value.
486  Map<T> half0Values(edgesA.size() / 20);
487  Map<T> half1Values(half0Values.size());
488 
489  forAll(coupledEdges, edgei)
490  {
491  const edge& twoEdges = coupledEdges[edgei];
492 
493  {
494  const edge& e0 = edgesA[twoEdges[0]];
495  const edge meshEdge0(meshPtsA[e0[0]], meshPtsA[e0[1]]);
496 
497  const auto iter = edgeValues.cfind(meshEdge0);
498 
499  if (iter.found())
500  {
501  half0Values.insert(edgei, *iter);
502  }
503  }
504  {
505  const edge& e1 = edgesB[twoEdges[1]];
506  const edge meshEdge1(meshPtsB[e1[0]], meshPtsB[e1[1]]);
507 
508  const auto iter = edgeValues.cfind(meshEdge1);
509 
510  if (iter.found())
511  {
512  half1Values.insert(edgei, *iter);
513  }
514  }
515  }
516 
517  // Transform to this side
518  top(cycPatch, half1Values);
519  top(nbrPatch, half0Values);
520 
521 
522  // Extract and combine information
523 
524  forAll(coupledEdges, edgei)
525  {
526  const edge& twoEdges = coupledEdges[edgei];
527 
528  const auto half1Fnd = half1Values.cfind(edgei);
529 
530  if (half1Fnd.found())
531  {
532  const edge& e0 = edgesA[twoEdges[0]];
533  const edge meshEdge0(meshPtsA[e0[0]], meshPtsA[e0[1]]);
534 
535  combine
536  (
537  edgeValues,
538  cop,
539  meshEdge0, // edge
540  *half1Fnd // value
541  );
542  }
543 
544  const auto half0Fnd = half0Values.cfind(edgei);
545 
546  if (half0Fnd.found())
547  {
548  const edge& e1 = edgesB[twoEdges[1]];
549  const edge meshEdge1(meshPtsB[e1[0]], meshPtsB[e1[1]]);
550 
551  combine
552  (
553  edgeValues,
554  cop,
555  meshEdge1, // edge
556  *half0Fnd // value
557  );
558  }
559  }
560  }
561  }
562 
563  // Synchronize multiple shared points.
564  // Problem is that we don't want to construct shared edges so basically
565  // we do here like globalMeshData but then using sparse edge representation
566  // (EdgeMap instead of mesh.edges())
567 
568  const globalMeshData& pd = mesh.globalData();
569  const labelList& sharedPtAddr = pd.sharedPointAddr();
570  const labelList& sharedPtLabels = pd.sharedPointLabels();
571 
572  // 1. Create map from meshPoint to globalShared index.
573  Map<label> meshToShared(2*sharedPtLabels.size());
574  forAll(sharedPtLabels, i)
575  {
576  meshToShared.insert(sharedPtLabels[i], sharedPtAddr[i]);
577  }
578 
579  // Values on shared points. From two sharedPtAddr indices to a value.
580  EdgeMap<T> sharedEdgeValues(meshToShared.size());
581 
582  // From shared edge to mesh edge. Used for merging later on.
583  EdgeMap<edge> potentialSharedEdge(meshToShared.size());
584 
585  // 2. Find any edges using two global shared points. These will always be
586  // on the outside of the mesh. (though might not be on coupled patch
587  // if is single edge and not on coupled face)
588  // Store value (if any) on sharedEdgeValues
589  for (label facei = mesh.nInternalFaces(); facei < mesh.nFaces(); ++facei)
590  {
591  const face& f = mesh.faces()[facei];
592 
593  forAll(f, fp)
594  {
595  const label v0 = f[fp];
596  const label v1 = f[f.fcIndex(fp)];
597 
598  const auto v0Fnd = meshToShared.cfind(v0);
599 
600  if (v0Fnd.found())
601  {
602  const auto v1Fnd = meshToShared.cfind(v1);
603 
604  if (v1Fnd.found())
605  {
606  const edge meshEdge(v0, v1);
607 
608  // edge in shared point labels
609  const edge sharedEdge(*v0Fnd, *v1Fnd);
610 
611  // Store mesh edge as a potential shared edge.
612  potentialSharedEdge.insert(sharedEdge, meshEdge);
613 
614  const auto edgeFnd = edgeValues.cfind(meshEdge);
615 
616  if (edgeFnd.found())
617  {
618  // edge exists in edgeValues. See if already in map
619  // (since on same processor, e.g. cyclic)
620  combine
621  (
622  sharedEdgeValues,
623  cop,
624  sharedEdge, // edge
625  *edgeFnd // value
626  );
627  }
628  }
629  }
630  }
631  }
632 
633 
634  // Now sharedEdgeValues will contain per potential sharedEdge the value.
635  // (potential since an edge having two shared points is not necessary a
636  // shared edge).
637  // Reduce this on the master.
638 
639  if (Pstream::parRun())
640  {
641  if (Pstream::master())
642  {
643  // Receive the edges using shared points from the slave.
644  for (const int slave : Pstream::subProcs())
645  {
646  IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
647  EdgeMap<T> nbrValues(fromSlave);
648 
649  // Merge neighbouring values with my values
650  forAllConstIters(nbrValues, iter)
651  {
652  combine
653  (
654  sharedEdgeValues,
655  cop,
656  iter.key(), // edge
657  iter.val() // value
658  );
659  }
660  }
661 
662  // Send back
663  for (const int slave : Pstream::subProcs())
664  {
666  toSlave << sharedEdgeValues;
667  }
668  }
669  else
670  {
671  // Send to master
672  {
673  OPstream toMaster
674  (
677  );
678  toMaster << sharedEdgeValues;
679  }
680  // Receive merged values
681  {
682  IPstream fromMaster
683  (
686  );
687  fromMaster >> sharedEdgeValues;
688  }
689  }
690  }
691 
692 
693  // Merge sharedEdgeValues (keyed on sharedPointAddr) into edgeValues
694  // (keyed on mesh points).
695 
696  // Loop over all my shared edges.
697  forAllConstIters(potentialSharedEdge, iter)
698  {
699  const edge& sharedEdge = iter.key();
700  const edge& meshEdge = iter.val();
701 
702  // Do I have a value for the shared edge?
703  const auto sharedFnd = sharedEdgeValues.cfind(sharedEdge);
704 
705  if (sharedFnd.found())
706  {
707  combine
708  (
709  edgeValues,
710  cop,
711  meshEdge, // edge
712  *sharedFnd // value
713  );
714  }
715  }
716 }
717 
718 
719 template<class T, class CombineOp, class TransformOp>
721 (
722  const polyMesh& mesh,
723  List<T>& pointValues,
724  const CombineOp& cop,
725  const T& nullValue,
726  const TransformOp& top
727 )
728 {
729  if (pointValues.size() != mesh.nPoints())
730  {
732  << "Number of values " << pointValues.size()
733  << " is not equal to the number of points in the mesh "
734  << mesh.nPoints() << abort(FatalError);
735  }
736 
737  mesh.globalData().syncPointData(pointValues, cop, top);
738 }
739 
740 
741 template<class T, class CombineOp, class TransformOp>
743 (
744  const polyMesh& mesh,
745  const labelUList& meshPoints,
746  List<T>& pointValues,
747  const CombineOp& cop,
748  const T& nullValue,
749  const TransformOp& top
750 )
751 {
752  if (pointValues.size() != meshPoints.size())
753  {
755  << "Number of values " << pointValues.size()
756  << " is not equal to the number of meshPoints "
757  << meshPoints.size() << abort(FatalError);
758  }
759  const globalMeshData& gd = mesh.globalData();
760  const indirectPrimitivePatch& cpp = gd.coupledPatch();
761  const Map<label>& mpm = cpp.meshPointMap();
762 
763  List<T> cppFld(cpp.nPoints(), nullValue);
764 
765  forAll(meshPoints, i)
766  {
767  const auto iter = mpm.cfind(meshPoints[i]);
768 
769  if (iter.found())
770  {
771  cppFld[*iter] = pointValues[i];
772  }
773  }
774 
776  (
777  cppFld,
778  gd.globalPointSlaves(),
781  gd.globalTransforms(),
782  cop,
783  top
784  );
785 
786  forAll(meshPoints, i)
787  {
788  const auto iter = mpm.cfind(meshPoints[i]);
789 
790  if (iter.found())
791  {
792  pointValues[i] = cppFld[*iter];
793  }
794  }
795 }
796 
797 
798 template<class T, class CombineOp, class TransformOp, class FlipOp>
800 (
801  const polyMesh& mesh,
802  List<T>& edgeValues,
803  const CombineOp& cop,
804  const T& nullValue,
805  const TransformOp& top,
806  const FlipOp& fop
807 )
808 {
809  if (edgeValues.size() != mesh.nEdges())
810  {
812  << "Number of values " << edgeValues.size()
813  << " is not equal to the number of edges in the mesh "
814  << mesh.nEdges() << abort(FatalError);
815  }
816 
817  const edgeList& edges = mesh.edges();
818  const globalMeshData& gd = mesh.globalData();
819  const labelList& meshEdges = gd.coupledPatchMeshEdges();
820  const indirectPrimitivePatch& cpp = gd.coupledPatch();
821  const edgeList& cppEdges = cpp.edges();
822  const labelList& mp = cpp.meshPoints();
823  const globalIndexAndTransform& git = gd.globalTransforms();
824  const mapDistribute& edgeMap = gd.globalEdgeSlavesMap();
825  const bitSet& orientation = gd.globalEdgeOrientation();
826 
827  List<T> cppFld(meshEdges.size());
828  forAll(meshEdges, i)
829  {
830  const edge& cppE = cppEdges[i];
831  const label meshEdgei = meshEdges[i];
832  const edge& meshE = edges[meshEdgei];
833 
834  // 1. is cpp edge oriented as mesh edge
835  // 2. is cpp edge oriented same as master edge
836 
837  const int dir = edge::compare(meshE, edge(mp, cppE));
838  if (dir == 0)
839  {
840  FatalErrorInFunction<< "Problem:"
841  << " mesh edge:" << meshE.line(mesh.points())
842  << " coupled edge:" << cppE.line(cpp.localPoints())
843  << exit(FatalError);
844  }
845 
846  const bool sameOrientation = ((dir == 1) == orientation[i]);
847 
848  if (sameOrientation)
849  {
850  cppFld[i] = edgeValues[meshEdgei];
851  }
852  else
853  {
854  cppFld[i] = fop(edgeValues[meshEdgei]);
855  }
856  }
857 
858 
860  (
861  cppFld,
862  gd.globalEdgeSlaves(),
864  edgeMap,
865  git,
866  cop,
867  top
868  );
869 
870  // Extract back onto mesh
871  forAll(meshEdges, i)
872  {
873  const edge& cppE = cppEdges[i];
874  const label meshEdgei = meshEdges[i];
875  const edge& meshE = edges[meshEdgei];
876 
877  // 1. is cpp edge oriented as mesh edge
878  // 2. is cpp edge oriented same as master edge
879 
880  const int dir = edge::compare(meshE, edge(mp, cppE));
881  const bool sameOrientation = ((dir == 1) == orientation[i]);
882 
883  if (sameOrientation)
884  {
885  edgeValues[meshEdges[i]] = cppFld[i];
886  }
887  else
888  {
889  edgeValues[meshEdges[i]] = fop(cppFld[i]);
890  }
891  }
892 }
893 
894 
895 template<class T, class CombineOp, class TransformOp, class FlipOp>
897 (
898  const polyMesh& mesh,
899  const labelList& meshEdges,
900  List<T>& edgeValues,
901  const CombineOp& cop,
902  const T& nullValue,
903  const TransformOp& top,
904  const FlipOp& fop
905 )
906 {
907  if (edgeValues.size() != meshEdges.size())
908  {
910  << "Number of values " << edgeValues.size()
911  << " is not equal to the number of meshEdges "
912  << meshEdges.size() << abort(FatalError);
913  }
914  const edgeList& edges = mesh.edges();
915  const globalMeshData& gd = mesh.globalData();
916  const indirectPrimitivePatch& cpp = gd.coupledPatch();
917  const edgeList& cppEdges = cpp.edges();
918  const labelList& mp = cpp.meshPoints();
919  const Map<label>& mpm = gd.coupledPatchMeshEdgeMap();
920  const bitSet& orientation = gd.globalEdgeOrientation();
921 
922  List<T> cppFld(cpp.nEdges(), nullValue);
923 
924  forAll(meshEdges, i)
925  {
926  const label meshEdgei = meshEdges[i];
927  const auto iter = mpm.cfind(meshEdgei);
928  if (iter.found())
929  {
930  const label cppEdgei = iter();
931  const edge& cppE = cppEdges[cppEdgei];
932  const edge& meshE = edges[meshEdgei];
933 
934  // 1. is cpp edge oriented as mesh edge
935  // 2. is cpp edge oriented same as master edge
936 
937  const int dir = edge::compare(meshE, edge(mp, cppE));
938  if (dir == 0)
939  {
940  FatalErrorInFunction<< "Problem:"
941  << " mesh edge:" << meshE.line(mesh.points())
942  << " coupled edge:" << cppE.line(cpp.localPoints())
943  << exit(FatalError);
944  }
945 
946  const bool sameOrientation = ((dir == 1) == orientation[i]);
947 
948  if (sameOrientation)
949  {
950  cppFld[cppEdgei] = edgeValues[i];
951  }
952  else
953  {
954  cppFld[cppEdgei] = fop(edgeValues[i]);
955  }
956  }
957  }
958 
960  (
961  cppFld,
962  gd.globalEdgeSlaves(),
964  gd.globalEdgeSlavesMap(),
965  gd.globalTransforms(),
966  cop,
967  top
968  );
969 
970  forAll(meshEdges, i)
971  {
972  label meshEdgei = meshEdges[i];
973  Map<label>::const_iterator iter = mpm.find(meshEdgei);
974  if (iter != mpm.end())
975  {
976  label cppEdgei = iter();
977  const edge& cppE = cppEdges[cppEdgei];
978  const edge& meshE = edges[meshEdgei];
979 
980  const int dir = edge::compare(meshE, edge(mp, cppE));
981  const bool sameOrientation = ((dir == 1) == orientation[i]);
982 
983  if (sameOrientation)
984  {
985  edgeValues[i] = cppFld[cppEdgei];
986  }
987  else
988  {
989  edgeValues[i] = fop(cppFld[cppEdgei]);
990  }
991  }
992  }
993 }
994 
995 
996 template<class T, class CombineOp, class TransformOp>
998 (
999  const polyMesh& mesh,
1000  UList<T>& faceValues,
1001  const CombineOp& cop,
1002  const TransformOp& top,
1003  const bool parRun
1004 )
1005 {
1006  // Offset (global to local) for start of boundaries
1007  const label boundaryOffset = mesh.nInternalFaces();
1008 
1009  if (faceValues.size() != mesh.nBoundaryFaces())
1010  {
1012  << "Number of values " << faceValues.size()
1013  << " is not equal to the number of boundary faces in the mesh "
1014  << mesh.nBoundaryFaces() << nl
1015  << abort(FatalError);
1016  }
1017 
1019 
1020  if (parRun)
1021  {
1022  // Avoid mesh.globalData() - possible race condition
1023 
1024  if
1025  (
1028  )
1029  {
1030  const label startRequest = UPstream::nRequests();
1031 
1032  // Receive buffer
1033  List<T> receivedValues(mesh.nBoundaryFaces());
1034 
1035  // Set up reads
1036  for (const polyPatch& pp : patches)
1037  {
1038  const auto* ppp = isA<processorPolyPatch>(pp);
1039 
1040  if (ppp && pp.size())
1041  {
1042  const auto& procPatch = *ppp;
1043 
1044  SubList<T> fld
1045  (
1046  receivedValues,
1047  pp.size(),
1048  pp.start()-boundaryOffset
1049  );
1050 
1052  (
1054  procPatch.neighbProcNo(),
1055  fld.data_bytes(),
1056  fld.size_bytes()
1057  );
1058  }
1059  }
1060 
1061  // Set up writes
1062  for (const polyPatch& pp : patches)
1063  {
1064  const auto* ppp = isA<processorPolyPatch>(pp);
1065 
1066  if (ppp && pp.size())
1067  {
1068  const auto& procPatch = *ppp;
1069 
1070  const SubList<T> fld
1071  (
1072  faceValues,
1073  pp.size(),
1074  pp.start()-boundaryOffset
1075  );
1076 
1078  (
1080  procPatch.neighbProcNo(),
1081  fld.cdata_bytes(),
1082  fld.size_bytes()
1083  );
1084  }
1085  }
1086 
1087  // Wait for all comms to finish
1088  Pstream::waitRequests(startRequest);
1089 
1090  // Combine with existing data
1091  for (const polyPatch& pp : patches)
1092  {
1093  const auto* ppp = isA<processorPolyPatch>(pp);
1094 
1095  if (ppp && pp.size())
1096  {
1097  const auto& procPatch = *ppp;
1098 
1099  SubList<T> recvFld
1100  (
1101  receivedValues,
1102  pp.size(),
1103  pp.start()-boundaryOffset
1104  );
1105  const List<T>& fakeList = recvFld;
1106  top(procPatch, const_cast<List<T>&>(fakeList));
1107 
1108  SubList<T> patchValues
1109  (
1110  faceValues,
1111  pp.size(),
1112  pp.start()-boundaryOffset
1113  );
1114 
1115  forAll(patchValues, i)
1116  {
1117  cop(patchValues[i], recvFld[i]);
1118  }
1119  }
1120  }
1121  }
1122  else
1123  {
1125 
1126  // Send
1127  for (const polyPatch& pp : patches)
1128  {
1129  const auto* ppp = isA<processorPolyPatch>(pp);
1130 
1131  if (ppp && pp.size())
1132  {
1133  const auto& procPatch = *ppp;
1134 
1135  const SubList<T> fld
1136  (
1137  faceValues,
1138  pp.size(),
1139  pp.start()-boundaryOffset
1140  );
1141 
1142  UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
1143  toNbr << fld;;
1144  }
1145  }
1146 
1147  pBufs.finishedSends();
1148 
1149  // Receive and combine.
1150  for (const polyPatch& pp : patches)
1151  {
1152  const auto* ppp = isA<processorPolyPatch>(pp);
1153 
1154  if (ppp && pp.size())
1155  {
1156  const auto& procPatch = *ppp;
1157 
1158  List<T> recvFld(pp.size());
1159 
1160  UIPstream fromNbr(procPatch.neighbProcNo(), pBufs);
1161  fromNbr >> recvFld;
1162 
1163  top(procPatch, recvFld);
1164 
1165  SubList<T> patchValues
1166  (
1167  faceValues,
1168  pp.size(),
1169  pp.start()-boundaryOffset
1170  );
1171 
1172  forAll(patchValues, i)
1173  {
1174  cop(patchValues[i], recvFld[i]);
1175  }
1176  }
1177  }
1178  }
1179  }
1180 
1181  // Do the cyclics.
1182  for (const polyPatch& pp : patches)
1183  {
1184  const cyclicPolyPatch* cpp = isA<cyclicPolyPatch>(pp);
1185 
1186  if (cpp && cpp->owner())
1187  {
1188  // Owner does all.
1189 
1190  const cyclicPolyPatch& cycPatch = *cpp;
1191  const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
1192  const label patchSize = cycPatch.size();
1193 
1194  SubList<T> ownPatchValues
1195  (
1196  faceValues,
1197  patchSize,
1198  cycPatch.start()-boundaryOffset
1199  );
1200 
1201  SubList<T> nbrPatchValues
1202  (
1203  faceValues,
1204  patchSize,
1205  nbrPatch.start()-boundaryOffset
1206  );
1207 
1208  // Transform (copy of) data on both sides
1209  List<T> ownVals(ownPatchValues);
1210  top(nbrPatch, ownVals);
1211 
1212  List<T> nbrVals(nbrPatchValues);
1213  top(cycPatch, nbrVals);
1214 
1215  forAll(ownPatchValues, i)
1216  {
1217  cop(ownPatchValues[i], nbrVals[i]);
1218  }
1219 
1220  forAll(nbrPatchValues, i)
1221  {
1222  cop(nbrPatchValues[i], ownVals[i]);
1223  }
1224  }
1225  }
1226 }
1227 
1228 
1229 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
1230 
1231 template<unsigned Width, class CombineOp>
1234  const polyMesh& mesh,
1235  const bool isBoundaryOnly,
1236  PackedList<Width>& faceValues,
1237  const CombineOp& cop,
1238  const bool parRun
1239 )
1240 {
1241  // Offset (global to local) for start of boundaries
1242  const label boundaryOffset = (isBoundaryOnly ? mesh.nInternalFaces() : 0);
1243 
1244  // Check size
1245  if (faceValues.size() != (mesh.nFaces() - boundaryOffset))
1246  {
1248  << "Number of values " << faceValues.size()
1249  << " is not equal to the number of "
1250  << (isBoundaryOnly ? "boundary" : "mesh") << " faces "
1251  << ((mesh.nFaces() - boundaryOffset)) << nl
1252  << abort(FatalError);
1253  }
1254 
1256 
1257  if (parRun)
1258  {
1259  const label startRequest = UPstream::nRequests();
1260 
1261  // Receive buffers
1262  PtrList<PackedList<Width>> recvInfos(patches.size());
1263 
1264  // Set up reads
1265  for (const polyPatch& pp : patches)
1266  {
1267  const auto* ppp = isA<processorPolyPatch>(pp);
1268 
1269  if (ppp && pp.size())
1270  {
1271  const auto& procPatch = *ppp;
1272  const label patchi = pp.index();
1273  const label patchSize = pp.size();
1274 
1275  recvInfos.set(patchi, new PackedList<Width>(patchSize));
1276  PackedList<Width>& recvInfo = recvInfos[patchi];
1277 
1279  (
1281  procPatch.neighbProcNo(),
1282  recvInfo.data_bytes(),
1283  recvInfo.size_bytes()
1284  );
1285  }
1286  }
1287 
1288  // Send buffers
1289  PtrList<PackedList<Width>> sendInfos(patches.size());
1290 
1291  // Set up writes
1292  for (const polyPatch& pp : patches)
1293  {
1294  const auto* ppp = isA<processorPolyPatch>(pp);
1295 
1296  if (ppp && pp.size())
1297  {
1298  const auto& procPatch = *ppp;
1299  const label patchi = pp.index();
1300 
1301  const labelRange range
1302  (
1303  pp.start()-boundaryOffset,
1304  pp.size()
1305  );
1306  sendInfos.set
1307  (
1308  patchi,
1309  new PackedList<Width>(faceValues, range)
1310  );
1311  PackedList<Width>& sendInfo = sendInfos[patchi];
1312 
1314  (
1316  procPatch.neighbProcNo(),
1317  sendInfo.cdata_bytes(),
1318  sendInfo.size_bytes()
1319  );
1320  }
1321  }
1322 
1323  // Wait for all comms to finish
1324  Pstream::waitRequests(startRequest);
1325 
1326  // Combine with existing data
1327  for (const polyPatch& pp : patches)
1328  {
1329  const auto* ppp = isA<processorPolyPatch>(pp);
1330 
1331  if (ppp && pp.size())
1332  {
1333  const label patchi = pp.index();
1334  const label patchSize = pp.size();
1335 
1336  const PackedList<Width>& recvInfo = recvInfos[patchi];
1337 
1338  // Combine (bitwise)
1339  label bFacei = pp.start()-boundaryOffset;
1340  for (label i = 0; i < patchSize; ++i)
1341  {
1342  unsigned int recvVal = recvInfo[i];
1343  unsigned int faceVal = faceValues[bFacei];
1344 
1345  cop(faceVal, recvVal);
1346  faceValues.set(bFacei, faceVal);
1347 
1348  ++bFacei;
1349  }
1350  }
1351  }
1352  }
1353 
1354 
1355  // Do the cyclics.
1356  for (const polyPatch& pp : patches)
1357  {
1358  const cyclicPolyPatch* cpp = isA<cyclicPolyPatch>(pp);
1359 
1360  if (cpp && cpp->owner())
1361  {
1362  // Owner does all.
1363 
1364  const cyclicPolyPatch& cycPatch = *cpp;
1365  const cyclicPolyPatch& nbrPatch = cycPatch.neighbPatch();
1366  const label patchSize = cycPatch.size();
1367 
1368  label face0 = cycPatch.start()-boundaryOffset;
1369  label face1 = nbrPatch.start()-boundaryOffset;
1370  for (label i = 0; i < patchSize; ++i)
1371  {
1372  unsigned int val0 = faceValues[face0];
1373  unsigned int val1 = faceValues[face1];
1374 
1375  unsigned int t = val0;
1376  cop(t, val1);
1377  faceValues[face0] = t;
1378 
1379  cop(val1, val0);
1380  faceValues[face1] = val1;
1381 
1382  ++face0;
1383  ++face1;
1384  }
1385  }
1386  }
1387 }
1388 
1389 
1390 template<class T>
1393  const polyMesh& mesh,
1394  const UList<T>& cellData,
1395  List<T>& neighbourCellData
1396 )
1397 {
1398  if (cellData.size() != mesh.nCells())
1399  {
1401  << "Number of cell values " << cellData.size()
1402  << " is not equal to the number of cells in the mesh "
1403  << mesh.nCells() << abort(FatalError);
1404  }
1405 
1407 
1408  neighbourCellData.resize(mesh.nBoundaryFaces());
1409 
1410  for (const polyPatch& pp : patches)
1411  {
1412  label bFacei = pp.offset();
1413 
1414  for (const label celli : pp.faceCells())
1415  {
1416  neighbourCellData[bFacei] = cellData[celli];
1417  ++bFacei;
1418  }
1419  }
1420  syncTools::swapBoundaryFaceList(mesh, neighbourCellData);
1421 }
1422 
1423 
1424 template<unsigned Width, class CombineOp>
1427  const polyMesh& mesh,
1428  PackedList<Width>& faceValues,
1429  const CombineOp& cop,
1430  const bool parRun
1431 )
1432 {
1433  syncFaceList(mesh, false, faceValues, cop, parRun);
1434 }
1435 
1436 
1437 template<unsigned Width, class CombineOp>
1440  const polyMesh& mesh,
1441  PackedList<Width>& faceValues,
1442  const CombineOp& cop,
1443  const bool parRun
1444 )
1445 {
1446  syncFaceList(mesh, true, faceValues, cop, parRun);
1447 }
1448 
1449 
1450 template<unsigned Width>
1453  const polyMesh& mesh,
1454  PackedList<Width>& faceValues
1455 )
1456 {
1457  syncFaceList(mesh, faceValues, eqOp<unsigned int>());
1458 }
1459 
1460 
1461 template<unsigned Width>
1464  const polyMesh& mesh,
1465  PackedList<Width>& faceValues
1466 )
1467 {
1468  syncBoundaryFaceList(mesh, faceValues, eqOp<unsigned int>());
1469 }
1470 
1471 
1472 template<unsigned Width, class CombineOp>
1475  const polyMesh& mesh,
1476  PackedList<Width>& pointValues,
1477  const CombineOp& cop,
1478  const unsigned int nullValue
1479 )
1480 {
1481  if (pointValues.size() != mesh.nPoints())
1482  {
1484  << "Number of values " << pointValues.size()
1485  << " is not equal to the number of points in the mesh "
1486  << mesh.nPoints() << abort(FatalError);
1487  }
1488 
1489  const globalMeshData& gd = mesh.globalData();
1490  const labelList& meshPoints = gd.coupledPatch().meshPoints();
1491 
1493  forAll(meshPoints, i)
1494  {
1495  cppFld[i] = pointValues[meshPoints[i]];
1496  }
1497 
1499  (
1500  cppFld,
1501  gd.globalPointSlaves(),
1503  gd.globalPointSlavesMap(),
1504  cop
1505  );
1506 
1507  // Extract back to mesh
1508  forAll(meshPoints, i)
1509  {
1510  pointValues[meshPoints[i]] = cppFld[i];
1511  }
1512 }
1513 
1514 
1515 template<unsigned Width, class CombineOp>
1518  const polyMesh& mesh,
1519  PackedList<Width>& edgeValues,
1520  const CombineOp& cop,
1521  const unsigned int nullValue
1522 )
1523 {
1524  if (edgeValues.size() != mesh.nEdges())
1525  {
1527  << "Number of values " << edgeValues.size()
1528  << " is not equal to the number of edges in the mesh "
1529  << mesh.nEdges() << abort(FatalError);
1530  }
1531 
1532  const globalMeshData& gd = mesh.globalData();
1533  const labelList& meshEdges = gd.coupledPatchMeshEdges();
1534 
1536  forAll(meshEdges, i)
1537  {
1538  cppFld[i] = edgeValues[meshEdges[i]];
1539  }
1540 
1542  (
1543  cppFld,
1544  gd.globalEdgeSlaves(),
1546  gd.globalEdgeSlavesMap(),
1547  cop
1548  );
1549 
1550  // Extract back to mesh
1551  forAll(meshEdges, i)
1552  {
1553  edgeValues[meshEdges[i]] = cppFld[i];
1554  }
1555 }
1556 
1557 
1558 // ************************************************************************* //
Foam::syncTools::syncEdgeList
static void syncEdgeList(const polyMesh &mesh, List< T > &edgeValues, const CombineOp &cop, const T &nullValue, const TransformOp &top, const FlipOp &fop)
Synchronize values on all mesh edges.
Definition: syncToolsTemplates.C:800
Foam::polyMesh::points
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1069
Foam::constant::atomic::mp
const dimensionedScalar mp
Proton mass.
Foam::globalMeshData::globalPointTransformedSlaves
const labelListList & globalPointTransformedSlaves() const
Definition: globalMeshData.C:2180
Foam::globalMeshData::globalPointSlaves
const labelListList & globalPointSlaves() const
Definition: globalMeshData.C:2170
Foam::UPstream::masterNo
static constexpr int masterNo() noexcept
Process index of the master (always 0)
Definition: UPstream.H:451
Foam::UOPstream::write
static bool write(const commsTypes commsType, const int toProcNo, const char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label communicator=UPstream::worldComm)
Write given buffer to given processor.
Definition: UOPwrite.C:36
Foam::UOPstream
Output inter-processor communications stream operating on external buffer.
Definition: UOPstream.H:57
Foam::globalMeshData::coupledPatchMeshEdgeMap
const Map< label > & coupledPatchMeshEdgeMap() const
Return map from mesh edges to coupledPatch edges.
Definition: globalMeshData.C:2127
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:63
Foam::syncTools::syncPointMap
static void syncPointMap(const polyMesh &mesh, Map< T > &pointValues, const CombineOp &cop, const TransformOp &top)
Synchronize values on selected points.
Definition: syncToolsTemplates.C:84
Foam::List::resize
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:63
Foam::PrimitivePatch::edges
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
Definition: PrimitivePatch.C:183
Foam::globalMeshData::globalEdgeSlavesMap
const mapDistribute & globalEdgeSlavesMap() const
Definition: globalMeshData.C:2245
cyclicPolyPatch.H
Foam::cyclicPolyPatch
Cyclic plane patch.
Definition: cyclicPolyPatch.H:66
Foam::edge::line
linePointRef line(const UList< point > &pts) const
Return edge line.
Definition: edgeI.H:456
Foam::OPstream
Output inter-processor communications stream.
Definition: OPstream.H:53
Foam::cyclicPolyPatch::neighbPatch
const cyclicPolyPatch & neighbPatch() const
Definition: cyclicPolyPatch.H:382
globalMeshData.H
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:54
Foam::PrimitivePatch::nEdges
label nEdges() const
Number of edges in patch.
Definition: PrimitivePatch.H:322
Foam::syncTools::syncBoundaryFaceList
static void syncBoundaryFaceList(const polyMesh &mesh, UList< T > &faceValues, const CombineOp &cop, const TransformOp &top, const bool parRun=Pstream::parRun())
Synchronize values on boundary faces only.
Definition: syncToolsTemplates.C:998
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::PackedList::size_bytes
std::streamsize size_bytes() const noexcept
Definition: PackedListI.H:589
Foam::primitiveMesh::nEdges
label nEdges() const
Number of mesh edges.
Definition: primitiveMeshI.H:67
Foam::Map
A HashTable to objects of type <T> with a label key.
Definition: lumpedPointController.H:69
Foam::UPstream::waitRequests
static void waitRequests(const label start=0)
Wait until all requests (from start onwards) have finished.
Definition: UPstream.C:262
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:457
Foam::syncTools::swapBoundaryFaceList
static void swapBoundaryFaceList(const polyMesh &mesh, UList< T > &faceValues)
Swap coupled boundary face values. Uses eqOp.
Definition: syncTools.H:445
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:444
Foam::UPstream::defaultCommsType
static commsTypes defaultCommsType
Default commsType.
Definition: UPstream.H:281
Foam::primitiveMesh::edges
const edgeList & edges() const
Return mesh edges. Uses calcEdges.
Definition: primitiveMeshEdges.C:505
Foam::globalMeshData::globalPointSlavesMap
const mapDistribute & globalPointSlavesMap() const
Definition: globalMeshData.C:2191
polyMesh.H
syncTools.H
Foam::UIPstream::read
static label read(const commsTypes commsType, const int fromProcNo, char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label communicator=UPstream::worldComm)
Read into given buffer from given processor.
Definition: UIPread.C:81
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::syncTools::syncPointList
static void syncPointList(const polyMesh &mesh, List< T > &pointValues, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh points.
Definition: syncToolsTemplates.C:721
Foam::primitiveMesh::nPoints
label nPoints() const noexcept
Number of mesh points.
Definition: primitiveMeshI.H:37
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::cyclicPolyPatch::coupledPoints
const edgeList & coupledPoints() const
Return connected points (from patch local to neighbour patch local)
Definition: cyclicPolyPatch.C:1030
Foam::PackedList::cdata_bytes
const char * cdata_bytes() const noexcept
A const pointer to the raw storage, reinterpreted as byte data.
Definition: PackedListI.H:575
Foam::globalMeshData::globalEdgeOrientation
const bitSet & globalEdgeOrientation() const
Is my edge same orientation as master edge.
Definition: globalMeshData.C:2235
Foam::syncTools::syncFaceList
static void syncFaceList(const polyMesh &mesh, UList< T > &faceValues, const CombineOp &cop)
Synchronize values on all mesh faces.
Definition: syncTools.H:396
Foam::primitiveMesh::nCells
label nCells() const noexcept
Number of mesh cells.
Definition: primitiveMeshI.H:96
Foam::UPstream::subProcs
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
Definition: UPstream.H:515
Foam::globalMeshData::nGlobalPoints
label nGlobalPoints() const
Return number of globally shared points.
Definition: globalMeshData.C:1986
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:68
Foam::ListListOps::combine
AccessType combine(const UList< T > &lists, AccessOp aop=accessOp< T >())
Combines sub-lists into a single list.
Definition: ListListOps.C:69
Foam::globalMeshData::globalTransforms
const globalIndexAndTransform & globalTransforms() const
Global transforms numbering.
Definition: globalMeshData.C:2160
Foam::globalMeshData::coupledPatchMeshEdges
const labelList & coupledPatchMeshEdges() const
Return map from coupledPatch edges to mesh edges.
Definition: globalMeshData.C:2107
Foam::mapDistribute
Class containing processor-to-processor mapping information.
Definition: mapDistribute.H:163
Foam::T
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Definition: FieldFieldFunctions.C:58
Foam::primitiveMesh::nBoundaryFaces
label nBoundaryFaces() const noexcept
Number of boundary faces (== nFaces - nInternalFaces)
Definition: primitiveMeshI.H:84
Foam::labelRange
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:55
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:59
Foam::globalMeshData::globalEdgeSlaves
const labelListList & globalEdgeSlaves() const
Definition: globalMeshData.C:2214
fld
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputLagrangian.H:23
Foam::globalMeshData::syncData
static void syncData(List< Type > &elems, const labelListList &slaves, const labelListList &transformedSlaves, const mapDistribute &slavesMap, const globalIndexAndTransform &, const CombineOp &cop, const TransformOp &top)
Helper: synchronise data with transforms.
Definition: globalMeshDataTemplates.C:37
Foam::syncTools::swapBoundaryCellList
static void swapBoundaryCellList(const polyMesh &mesh, const UList< T > &cellData, List< T > &neighbourCellData)
Swap to obtain neighbour cell values for all boundary faces.
Definition: syncToolsTemplates.C:1392
Foam::PstreamBuffers::finishedSends
void finishedSends(const bool block=true)
Mark all sends as having been done.
Definition: PstreamBuffers.C:73
Foam::cyclicPolyPatch::coupledEdges
const edgeList & coupledEdges() const
Return connected edges (from patch local to neighbour patch local).
Definition: cyclicPolyPatch.C:1111
Foam::PrimitivePatch::nPoints
label nPoints() const
Number of points supporting patch faces.
Definition: PrimitivePatch.H:316
Foam::cyclicPolyPatch::owner
virtual bool owner() const
Does this side own the patch ?
Definition: cyclicPolyPatch.H:372
Foam::FatalError
error FatalError
processorPolyPatch.H
Foam::eqOp
Definition: ops.H:71
Foam::globalMeshData
Various mesh related information for a parallel run. Upon construction, constructs all info using par...
Definition: globalMeshData.H:107
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
T
const volScalarField & T
Definition: createFieldRefs.H:2
Foam::polyPatch::start
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:361
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::PrimitivePatch::localPoints
const Field< point_type > & localPoints() const
Return pointField of points in patch.
Definition: PrimitivePatch.C:359
Foam::mapDistributeBase::constructSize
label constructSize() const
Constructed data size.
Definition: mapDistributeBase.H:277
Foam::EdgeMap
Map from edge (expressed as its endpoints) to value. For easier forward declaration it is currently i...
Definition: EdgeMap.H:51
Foam::polyMesh::faces
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1094
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::edge::compare
static int compare(const edge &a, const edge &b)
Compare edges.
Definition: edgeI.H:33
Foam::UPstream::commsTypes::nonBlocking
Foam::UPstream::nRequests
static label nRequests()
Get number of outstanding requests.
Definition: UPstream.C:252
Foam::HashTable< T, edge, Hash< edge > >::cfind
const_iterator cfind(const edge &key) const
Find and return an const_iterator set at the hashed entry.
Definition: HashTableI.H:141
range
scalar range
Definition: LISASMDCalcMethod1.H:12
Foam::nl
constexpr char nl
Definition: Ostream.H:404
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::globalMeshData::globalEdgeTransformedSlaves
const labelListList & globalEdgeTransformedSlaves() const
Definition: globalMeshData.C:2224
Foam::UPstream::commsTypes::scheduled
f
labelList f(nPoints)
Foam::syncTools::swapFaceList
static void swapFaceList(const polyMesh &mesh, UList< T > &faceValues)
Swap coupled face values. Uses eqOp.
Definition: syncTools.H:478
Foam::primitiveMesh::nInternalFaces
label nInternalFaces() const noexcept
Number of internal faces.
Definition: primitiveMeshI.H:78
Foam::UPstream::parRun
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
Foam::List< label >
Foam::globalMeshData::coupledPatch
const indirectPrimitivePatch & coupledPatch() const
Return patch of all coupled faces.
Definition: globalMeshData.C:2046
Foam::PackedList
A dynamic list of packed unsigned integers, with the number of bits per item specified by the <Width>...
Definition: PackedList.H:108
Foam::syncTools::syncEdgeMap
static void syncEdgeMap(const polyMesh &mesh, EdgeMap< T > &edgeValues, const CombineOp &cop, const TransformOp &top)
Synchronize values on selected edges.
Definition: syncToolsTemplates.C:365
Foam::PackedList::size
label size() const noexcept
Number of entries.
Definition: PackedListI.H:377
Foam::UList< label >
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
Foam::PackedList::data_bytes
char * data_bytes() noexcept
A pointer to the raw storage, reinterpreted as byte data.
Definition: PackedListI.H:582
Foam::globalMeshData::sharedPointLabels
const labelList & sharedPointLabels() const
Return indices of local points that are globally shared.
Definition: globalMeshData.C:1996
Foam::PackedList::set
bool set(const label i, unsigned int val=~0u)
Set value at index i, default value set is the max_value.
Definition: PackedListI.H:653
Foam::globalMeshData::sharedPointAddr
const labelList & sharedPointAddr() const
Return addressing into the complete globally shared points.
Definition: globalMeshData.C:2006
Foam::IPstream
Input inter-processor communications stream.
Definition: IPstream.H:53
Foam::primitiveMesh::nFaces
label nFaces() const noexcept
Number of mesh faces.
Definition: primitiveMeshI.H:90
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Foam::UIPstream
Input inter-processor communications stream operating on external buffer.
Definition: UIPstream.H:56
Foam::polyMesh::globalData
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1295
Foam::PrimitivePatch::meshPointMap
const Map< label > & meshPointMap() const
Mesh point map.
Definition: PrimitivePatch.C:343
transformList.H
Spatial transformation functions for list of values and primitive fields.
Foam::PrimitivePatch::meshPoints
const labelList & meshPoints() const
Return labelList of mesh points in patch.
Definition: PrimitivePatch.C:330
Foam::globalIndexAndTransform
Determination and storage of the possible independent transforms introduced by coupledPolyPatches,...
Definition: globalIndexAndTransform.H:64
Foam::is_contiguous
A template class to specify that a data type can be considered as being contiguous in memory.
Definition: contiguous.H:75
Foam::globalMeshData::syncPointData
void syncPointData(List< Type > &pointData, const CombineOp &cop, const TransformOp &top) const
Helper to synchronise coupled patch point data.
Definition: globalMeshDataTemplates.C:159
Foam::PrimitivePatch
A list of faces which address into the list of points.
Definition: PrimitivePatch.H:79