globalMeshData.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 | Copyright (C) 2011-2015 OpenFOAM Foundation
6  \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "globalMeshData.H"
27 #include "Time.H"
28 #include "Pstream.H"
30 #include "processorPolyPatch.H"
31 #include "demandDrivenData.H"
32 #include "globalPoints.H"
33 #include "polyMesh.H"
34 #include "mapDistribute.H"
35 #include "labelIOList.H"
36 #include "PackedList.H"
37 #include "mergePoints.H"
38 #include "matchPoints.H"
39 #include "OFstream.H"
41 
42 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
43 
44 namespace Foam
45 {
46 defineTypeNameAndDebug(globalMeshData, 0);
47 
48 // Geometric matching tolerance. Factor of mesh bounding box.
49 const scalar globalMeshData::matchTol_ = 1e-8;
50 
51 template<>
52 class minEqOp<labelPair>
53 {
54 public:
55  void operator()(labelPair& x, const labelPair& y) const
56  {
57  x[0] = min(x[0], y[0]);
58  x[1] = min(x[1], y[1]);
59  }
60 };
61 }
62 
63 
64 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
65 
66 // Collect processor patch addressing.
68 {
71 
74 
75  // Construct processor patch indexing. processorPatchNeighbours_ only
76  // set if running in parallel!
78 
79  label nNeighbours = 0;
80 
82  {
83  if (isA<processorPolyPatch>(mesh_.boundaryMesh()[patchi]))
84  {
85  processorPatches_[nNeighbours] = patchi;
86  processorPatchIndices_[patchi] = nNeighbours++;
87  }
88  }
89  processorPatches_.setSize(nNeighbours);
90 
91 
92  if (Pstream::parRun())
93  {
95 
96  // Send indices of my processor patches to my neighbours
98  {
100 
101  UOPstream toNeighbour
102  (
103  refCast<const processorPolyPatch>
104  (
106  ).neighbProcNo(),
107  pBufs
108  );
109 
110  toNeighbour << processorPatchIndices_[patchi];
111  }
112 
113  pBufs.finishedSends();
114 
116  {
118 
119  UIPstream fromNeighbour
120  (
121  refCast<const processorPolyPatch>
122  (
124  ).neighbProcNo(),
125  pBufs
126  );
127 
128  fromNeighbour >> processorPatchNeighbours_[patchi];
129  }
130  }
131 }
132 
133 
135 {
136  if
137  (
138  nGlobalPoints_ != -1
139  || sharedPointLabelsPtr_.valid()
140  || sharedPointAddrPtr_.valid()
141  )
142  {
144  << "Shared point addressing already done" << abort(FatalError);
145  }
146 
147  // Calculate all shared points (exclude points that are only
148  // on two coupled patches). This does all the hard work.
149  globalPoints parallelPoints(mesh_, false, true);
150 
151  // Count the number of master points
152  label nMaster = 0;
153  forAll(parallelPoints.pointPoints(), i)
154  {
155  const labelList& pPoints = parallelPoints.pointPoints()[i];
156  const labelList& transPPoints =
157  parallelPoints.transformedPointPoints()[i];
158 
159  if (pPoints.size()+transPPoints.size() > 0)
160  {
161  nMaster++;
162  }
163  }
164 
165  // Allocate global numbers
166  globalIndex masterNumbering(nMaster);
167 
168  nGlobalPoints_ = masterNumbering.size();
169 
170 
171  // Push master number to slaves
172  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
173  // 1. Fill master and slave slots
174  nMaster = 0;
175  labelList master(parallelPoints.map().constructSize(), -1);
176  forAll(parallelPoints.pointPoints(), i)
177  {
178  const labelList& pPoints = parallelPoints.pointPoints()[i];
179  const labelList& transPPoints =
180  parallelPoints.transformedPointPoints()[i];
181 
182  if (pPoints.size()+transPPoints.size() > 0)
183  {
184  master[i] = masterNumbering.toGlobal(nMaster);
185  forAll(pPoints, j)
186  {
187  master[pPoints[j]] = master[i];
188  }
189  forAll(transPPoints, j)
190  {
191  master[transPPoints[j]] = master[i];
192  }
193  nMaster++;
194  }
195  }
196 
197 
198  // 2. Push slave slots back to local storage on originating processor
199  // For all the four types of points:
200  // - local master : already set
201  // - local transformed slave point : the reverse transform at
202  // reverseDistribute will have copied it back to its originating local
203  // point
204  // - remote untransformed slave point : sent back to originating processor
205  // - remote transformed slave point : the reverse transform will
206  // copy it back into the remote slot which then gets sent back to
207  // originating processor
208 
209  parallelPoints.map().reverseDistribute
210  (
211  parallelPoints.map().constructSize(),
212  master
213  );
214 
215 
216  // Collect all points that are a master or refer to a master.
217  nMaster = 0;
218  forAll(parallelPoints.pointPoints(), i)
219  {
220  if (master[i] != -1)
221  {
222  nMaster++;
223  }
224  }
225 
226  sharedPointLabelsPtr_.reset(new labelList(nMaster));
227  labelList& sharedPointLabels = sharedPointLabelsPtr_();
228  sharedPointAddrPtr_.reset(new labelList(nMaster));
229  labelList& sharedPointAddr = sharedPointAddrPtr_();
230  nMaster = 0;
231 
232  forAll(parallelPoints.pointPoints(), i)
233  {
234  if (master[i] != -1)
235  {
236  // I am master or slave
237  sharedPointLabels[nMaster] = i;
238  sharedPointAddr[nMaster] = master[i];
239  nMaster++;
240  }
241  }
242 
243  if (debug)
244  {
245  Pout<< "globalMeshData : nGlobalPoints_:" << nGlobalPoints_ << nl
246  << "globalMeshData : sharedPointLabels_:"
247  << sharedPointLabelsPtr_().size() << nl
248  << "globalMeshData : sharedPointAddr_:"
249  << sharedPointAddrPtr_().size() << endl;
250  }
251 }
252 
253 
254 // Given information about locally used edges allocate global shared edges.
256 (
257  const EdgeMap<labelList>& procSharedEdges,
258  EdgeMap<label>& globalShared,
259  label& sharedEdgeI
260 )
261 {
262  // Count occurrences of procSharedEdges in global shared edges table.
263  forAllConstIter(EdgeMap<labelList>, procSharedEdges, iter)
264  {
265  const edge& e = iter.key();
266 
267  EdgeMap<label>::iterator globalFnd = globalShared.find(e);
268 
269  if (globalFnd == globalShared.end())
270  {
271  // First time occurrence of this edge. Check how many we are adding.
272  if (iter().size() == 1)
273  {
274  // Only one edge. Mark with special value.
275  globalShared.insert(e, -1);
276  }
277  else
278  {
279  // Edge used more than once (even by local shared edges alone)
280  // so allocate proper shared edge label.
281  globalShared.insert(e, sharedEdgeI++);
282  }
283  }
284  else
285  {
286  if (globalFnd() == -1)
287  {
288  // Second time occurence of this edge. Assign proper
289  // edge label.
290  globalFnd() = sharedEdgeI++;
291  }
292  }
293  }
294 }
295 
296 
297 // Shared edges are shared between multiple processors. By their nature both
298 // of their endpoints are shared points. (but not all edges using two shared
299 // points are shared edges! There might e.g. be an edge between two unrelated
300 // clusters of shared points)
302 {
303  if
304  (
305  nGlobalEdges_ != -1
306  || sharedEdgeLabelsPtr_.valid()
307  || sharedEdgeAddrPtr_.valid()
308  )
309  {
311  << "Shared edge addressing already done" << abort(FatalError);
312  }
313 
314 
315  const labelList& sharedPtAddr = sharedPointAddr();
316  const labelList& sharedPtLabels = sharedPointLabels();
317 
318  // Since don't want to construct pointEdges for whole mesh create
319  // Map for all shared points.
320  Map<label> meshToShared(2*sharedPtLabels.size());
321  forAll(sharedPtLabels, i)
322  {
323  meshToShared.insert(sharedPtLabels[i], i);
324  }
325 
326  // Find edges using shared points. Store correspondence to local edge
327  // numbering. Note that multiple local edges can have the same shared
328  // points! (for cyclics or separated processor patches)
329  EdgeMap<labelList> localShared(2*sharedPtAddr.size());
330 
331  const edgeList& edges = mesh_.edges();
332 
333  forAll(edges, edgeI)
334  {
335  const edge& e = edges[edgeI];
336 
337  Map<label>::const_iterator e0Fnd = meshToShared.find(e[0]);
338 
339  if (e0Fnd != meshToShared.end())
340  {
341  Map<label>::const_iterator e1Fnd = meshToShared.find(e[1]);
342 
343  if (e1Fnd != meshToShared.end())
344  {
345  // Found edge which uses shared points. Probably shared.
346 
347  // Construct the edge in shared points (or rather global indices
348  // of the shared points)
350  (
351  sharedPtAddr[e0Fnd()],
352  sharedPtAddr[e1Fnd()]
353  );
354 
356  localShared.find(sharedEdge);
357 
358  if (iter == localShared.end())
359  {
360  // First occurrence of this point combination. Store.
361  localShared.insert(sharedEdge, labelList(1, edgeI));
362  }
363  else
364  {
365  // Add this edge to list of edge labels.
366  labelList& edgeLabels = iter();
367 
368  label sz = edgeLabels.size();
369  edgeLabels.setSize(sz+1);
370  edgeLabels[sz] = edgeI;
371  }
372  }
373  }
374  }
375 
376 
377  // Now we have a table on every processors which gives its edges which use
378  // shared points. Send this all to the master and have it allocate
379  // global edge numbers for it. But only allocate a global edge number for
380  // edge if it is used more than once!
381  // Note that we are now sending the whole localShared to the master whereas
382  // we only need the local count (i.e. the number of times a global edge is
383  // used). But then this only gets done once so not too bothered about the
384  // extra global communication.
385 
386  EdgeMap<label> globalShared(nGlobalPoints());
387 
388  if (Pstream::master())
389  {
390  label sharedEdgeI = 0;
391 
392  // Merge my shared edges into the global list
393  if (debug)
394  {
395  Pout<< "globalMeshData::calcSharedEdges : Merging in from proc0 : "
396  << localShared.size() << endl;
397  }
398  countSharedEdges(localShared, globalShared, sharedEdgeI);
399 
400  // Receive data from slaves and insert
401  if (Pstream::parRun())
402  {
403  for
404  (
405  int slave=Pstream::firstSlave();
406  slave<=Pstream::lastSlave();
407  slave++
408  )
409  {
410  // Receive the edges using shared points from the slave.
411  IPstream fromSlave(Pstream::blocking, slave);
412  EdgeMap<labelList> procSharedEdges(fromSlave);
413 
414  if (debug)
415  {
416  Pout<< "globalMeshData::calcSharedEdges : "
417  << "Merging in from proc"
418  << Foam::name(slave) << " : " << procSharedEdges.size()
419  << endl;
420  }
421  countSharedEdges(procSharedEdges, globalShared, sharedEdgeI);
422  }
423  }
424 
425  // Now our globalShared should have some edges with -1 as edge label
426  // These were only used once so are not proper shared edges.
427  // Remove them.
428  {
429  EdgeMap<label> oldSharedEdges(globalShared);
430 
431  globalShared.clear();
432 
433  forAllConstIter(EdgeMap<label>, oldSharedEdges, iter)
434  {
435  if (iter() != -1)
436  {
437  globalShared.insert(iter.key(), iter());
438  }
439  }
440  if (debug)
441  {
442  Pout<< "globalMeshData::calcSharedEdges : Filtered "
443  << oldSharedEdges.size()
444  << " down to " << globalShared.size() << endl;
445  }
446  }
447 
448 
449  // Send back to slaves.
450  if (Pstream::parRun())
451  {
452  for
453  (
454  int slave=Pstream::firstSlave();
455  slave<=Pstream::lastSlave();
456  slave++
457  )
458  {
459  // Receive the edges using shared points from the slave.
460  OPstream toSlave(Pstream::blocking, slave);
461  toSlave << globalShared;
462  }
463  }
464  }
465  else
466  {
467  // Send local edges to master
468  {
470 
471  toMaster << localShared;
472  }
473  // Receive merged edges from master.
474  {
476 
477  fromMaster >> globalShared;
478  }
479  }
480 
481  // Now use the global shared edges list (globalShared) to classify my local
482  // ones (localShared)
483 
484  nGlobalEdges_ = globalShared.size();
485 
486  DynamicList<label> dynSharedEdgeLabels(globalShared.size());
487  DynamicList<label> dynSharedEdgeAddr(globalShared.size());
488 
489  forAllConstIter(EdgeMap<labelList>, localShared, iter)
490  {
491  const edge& e = iter.key();
492 
493  EdgeMap<label>::const_iterator edgeFnd = globalShared.find(e);
494 
495  if (edgeFnd != globalShared.end())
496  {
497  // My local edge is indeed a shared one. Go through all local edge
498  // labels with this point combination.
499  const labelList& edgeLabels = iter();
500 
501  forAll(edgeLabels, i)
502  {
503  // Store label of local mesh edge
504  dynSharedEdgeLabels.append(edgeLabels[i]);
505 
506  // Store label of shared edge
507  dynSharedEdgeAddr.append(edgeFnd());
508  }
509  }
510  }
511 
512  sharedEdgeLabelsPtr_.reset(new labelList());
513  labelList& sharedEdgeLabels = sharedEdgeLabelsPtr_();
514  sharedEdgeLabels.transfer(dynSharedEdgeLabels);
515 
516  sharedEdgeAddrPtr_.reset(new labelList());
517  labelList& sharedEdgeAddr = sharedEdgeAddrPtr_();
518  sharedEdgeAddr.transfer(dynSharedEdgeAddr);
519 
520  if (debug)
521  {
522  Pout<< "globalMeshData : nGlobalEdges_:" << nGlobalEdges_ << nl
523  << "globalMeshData : sharedEdgeLabels:" << sharedEdgeLabels.size()
524  << nl
525  << "globalMeshData : sharedEdgeAddr:" << sharedEdgeAddr.size()
526  << endl;
527  }
528 }
529 
530 
532 {
533  if (debug)
534  {
535  Pout<< "globalMeshData::calcGlobalPointSlaves() :"
536  << " calculating coupled master to slave point addressing."
537  << endl;
538  }
539 
540  // Calculate connected points for master points.
541  globalPoints globalData(mesh_, coupledPatch(), true, true);
542 
543  globalPointSlavesPtr_.reset
544  (
545  new labelListList
546  (
547  globalData.pointPoints().xfer()
548  )
549  );
550  globalPointTransformedSlavesPtr_.reset
551  (
552  new labelListList
553  (
554  globalData.transformedPointPoints().xfer()
555  )
556  );
557 
558  globalPointSlavesMapPtr_.reset
559  (
560  new mapDistribute
561  (
562  globalData.map().xfer()
563  )
564  );
565 }
566 
567 
569 (
570  List<labelPairList>& allPointConnectivity
571 ) const
572 {
573  const globalIndexAndTransform& transforms = globalTransforms();
574  const labelListList& slaves = globalPointSlaves();
575  const labelListList& transformedSlaves = globalPointTransformedSlaves();
576 
577 
578  // Create field with my local data
579  labelPairList myData(globalPointSlavesMap().constructSize());
580  forAll(slaves, pointI)
581  {
582  myData[pointI] = globalIndexAndTransform::encode
583  (
585  pointI,
586  transforms.nullTransformIndex()
587  );
588  }
589  // Send over.
590  globalPointSlavesMap().distribute(myData);
591 
592 
593  // String of connected points with their transform
594  allPointConnectivity.setSize(globalPointSlavesMap().constructSize());
595  forAll(slaves, pointI)
596  {
597  // Reconstruct string of connected points
598  const labelList& pSlaves = slaves[pointI];
599  const labelList& pTransformSlaves = transformedSlaves[pointI];
600  labelPairList& pConnectivity = allPointConnectivity[pointI];
601  pConnectivity.setSize(1+pSlaves.size()+pTransformSlaves.size());
602  label connI = 0;
603 
604  // Add myself
605  pConnectivity[connI++] = myData[pointI];
606  // Add untransformed points
607  forAll(pSlaves, i)
608  {
609  pConnectivity[connI++] = myData[pSlaves[i]];
610  }
611  // Add transformed points.
612  forAll(pTransformSlaves, i)
613  {
614  // Get transform from index
615  label transformI = globalPointSlavesMap().whichTransform
616  (
617  pTransformSlaves[i]
618  );
619  // Add transform to connectivity
620  const labelPair& n = myData[pTransformSlaves[i]];
623  pConnectivity[connI++] = globalIndexAndTransform::encode
624  (
625  procI,
626  index,
627  transformI
628  );
629  }
630 
631  // Put back in slots
632  forAll(pSlaves, i)
633  {
634  allPointConnectivity[pSlaves[i]] = pConnectivity;
635  }
636  forAll(pTransformSlaves, i)
637  {
638  allPointConnectivity[pTransformSlaves[i]] = pConnectivity;
639  }
640  }
641  globalPointSlavesMap().reverseDistribute
642  (
643  allPointConnectivity.size(),
644  allPointConnectivity
645  );
646 }
647 
648 
650 (
651  labelListList& globalPointEdges,
652  List<labelPairList>& globalPointPoints
653 ) const
654 {
655  const edgeList& edges = coupledPatch().edges();
656  const labelListList& pointEdges = coupledPatch().pointEdges();
657  const globalIndex& globalEdgeNumbers = globalEdgeNumbering();
658  const labelListList& slaves = globalPointSlaves();
659  const labelListList& transformedSlaves = globalPointTransformedSlaves();
660 
661  // Create local version
662  globalPointEdges.setSize(globalPointSlavesMap().constructSize());
663  globalPointPoints.setSize(globalPointSlavesMap().constructSize());
664  forAll(pointEdges, pointI)
665  {
666  const labelList& pEdges = pointEdges[pointI];
667  labelList& globalPEdges = globalPointEdges[pointI];
668  globalPEdges.setSize(pEdges.size());
669  forAll(pEdges, i)
670  {
671  globalPEdges[i] = globalEdgeNumbers.toGlobal(pEdges[i]);
672  }
673 
674  labelPairList& globalPPoints = globalPointPoints[pointI];
675  globalPPoints.setSize(pEdges.size());
676  forAll(pEdges, i)
677  {
678  label otherPointI = edges[pEdges[i]].otherVertex(pointI);
679  globalPPoints[i] = globalIndexAndTransform::encode
680  (
682  otherPointI,
683  globalTransforms().nullTransformIndex()
684  );
685  }
686  }
687 
688  // Pull slave data to master. Dummy transform.
689  globalPointSlavesMap().distribute(globalPointEdges);
690  globalPointSlavesMap().distribute(globalPointPoints);
691  // Add all pointEdges
692  forAll(slaves, pointI)
693  {
694  const labelList& pSlaves = slaves[pointI];
695  const labelList& pTransformSlaves = transformedSlaves[pointI];
696 
697  label n = 0;
698  forAll(pSlaves, i)
699  {
700  n += globalPointEdges[pSlaves[i]].size();
701  }
702  forAll(pTransformSlaves, i)
703  {
704  n += globalPointEdges[pTransformSlaves[i]].size();
705  }
706 
707  // Add all the point edges of the slaves to those of the (master) point
708  {
709  labelList& globalPEdges = globalPointEdges[pointI];
710  label sz = globalPEdges.size();
711  globalPEdges.setSize(sz+n);
712  forAll(pSlaves, i)
713  {
714  const labelList& otherData = globalPointEdges[pSlaves[i]];
715  forAll(otherData, j)
716  {
717  globalPEdges[sz++] = otherData[j];
718  }
719  }
720  forAll(pTransformSlaves, i)
721  {
722  const labelList& otherData =
723  globalPointEdges[pTransformSlaves[i]];
724  forAll(otherData, j)
725  {
726  globalPEdges[sz++] = otherData[j];
727  }
728  }
729 
730  // Put back in slots
731  forAll(pSlaves, i)
732  {
733  globalPointEdges[pSlaves[i]] = globalPEdges;
734  }
735  forAll(pTransformSlaves, i)
736  {
737  globalPointEdges[pTransformSlaves[i]] = globalPEdges;
738  }
739  }
740 
741 
742  // Same for corresponding pointPoints
743  {
744  labelPairList& globalPPoints = globalPointPoints[pointI];
745  label sz = globalPPoints.size();
746  globalPPoints.setSize(sz + n);
747 
748  // Add untransformed points
749  forAll(pSlaves, i)
750  {
751  const labelPairList& otherData = globalPointPoints[pSlaves[i]];
752  forAll(otherData, j)
753  {
754  globalPPoints[sz++] = otherData[j];
755  }
756  }
757  // Add transformed points.
758  forAll(pTransformSlaves, i)
759  {
760  // Get transform from index
761  label transformI = globalPointSlavesMap().whichTransform
762  (
763  pTransformSlaves[i]
764  );
765 
766  const labelPairList& otherData =
767  globalPointPoints[pTransformSlaves[i]];
768  forAll(otherData, j)
769  {
770  // Add transform to connectivity
771  const labelPair& n = otherData[j];
774  globalPPoints[sz++] = globalIndexAndTransform::encode
775  (
776  procI,
777  index,
778  transformI
779  );
780  }
781  }
782 
783  // Put back in slots
784  forAll(pSlaves, i)
785  {
786  globalPointPoints[pSlaves[i]] = globalPPoints;
787  }
788  forAll(pTransformSlaves, i)
789  {
790  globalPointPoints[pTransformSlaves[i]] = globalPPoints;
791  }
792  }
793  }
794  // Push back
795  globalPointSlavesMap().reverseDistribute
796  (
797  globalPointEdges.size(),
798  globalPointEdges
799  );
800  // Push back
801  globalPointSlavesMap().reverseDistribute
802  (
803  globalPointPoints.size(),
804  globalPointPoints
805  );
806 }
807 
808 
809 // Find transformation to take remotePoint to localPoint. Use info to find
810 // the transforms.
812 (
813  const labelPairList& info,
814  const labelPair& remotePoint,
815  const label localPoint
816 ) const
817 {
818  const label remoteProcI = globalIndexAndTransform::processor(remotePoint);
819  const label remoteIndex = globalIndexAndTransform::index(remotePoint);
820 
821  label remoteTransformI = -1;
822  label localTransformI = -1;
823  forAll(info, i)
824  {
825  label procI = globalIndexAndTransform::processor(info[i]);
826  label pointI = globalIndexAndTransform::index(info[i]);
827  label transformI = globalIndexAndTransform::transformIndex(info[i]);
828 
829  if (procI == Pstream::myProcNo() && pointI == localPoint)
830  {
831  localTransformI = transformI;
832  //Pout<< "For local :" << localPoint
833  // << " found transform:" << localTransformI
834  // << endl;
835  }
836  if (procI == remoteProcI && pointI == remoteIndex)
837  {
838  remoteTransformI = transformI;
839  //Pout<< "For remote:" << remotePoint
840  // << " found transform:" << remoteTransformI
841  // << " at index:" << i
842  // << endl;
843  }
844  }
845 
846  if (remoteTransformI == -1 || localTransformI == -1)
847  {
849  << "Problem. Cannot find " << remotePoint
850  << " or " << localPoint << " "
851  << coupledPatch().localPoints()[localPoint]
852  << " in " << info
853  << endl
854  << "remoteTransformI:" << remoteTransformI << endl
855  << "localTransformI:" << localTransformI
856  << abort(FatalError);
857  }
858 
859  return globalTransforms().subtractTransformIndex
860  (
861  remoteTransformI,
862  localTransformI
863  );
864 }
865 
866 
868 {
869  if (debug)
870  {
871  Pout<< "globalMeshData::calcGlobalEdgeSlaves() :"
872  << " calculating coupled master to slave edge addressing." << endl;
873  }
874 
875  const edgeList& edges = coupledPatch().edges();
876  const globalIndex& globalEdgeNumbers = globalEdgeNumbering();
877 
878 
879  // The whole problem with deducting edge-connectivity from
880  // point-connectivity is that one of the the endpoints might be
881  // a local master but the other endpoint might not. So we first
882  // need to make sure that all points know about connectivity and
883  // the transformations.
884 
885 
886  // 1. collect point connectivity - basically recreating globalPoints output.
887  // All points will now have a string of points. The transforms are
888  // in respect to the master.
889  List<labelPairList> allPointConnectivity;
890  calcPointConnectivity(allPointConnectivity);
891 
892 
893  // 2. Get all pointEdges and pointPoints
894  // Coupled point to global coupled edges and corresponding endpoint.
895  labelListList globalPointEdges;
896  List<labelPairList> globalPointPoints;
897  calcGlobalPointEdges(globalPointEdges, globalPointPoints);
898 
899 
900  // 3. Now all points have
901  // - all the connected points with original transform
902  // - all the connected global edges
903 
904  // Now all we need to do is go through all the edges and check
905  // both endpoints. If there is a edge between the two which is
906  // produced by transforming both points in the same way it is a shared
907  // edge.
908 
909  // Collect strings of connected edges.
910  List<labelPairList> allEdgeConnectivity(edges.size());
911 
912  forAll(edges, edgeI)
913  {
914  const edge& e = edges[edgeI];
915  const labelList& pEdges0 = globalPointEdges[e[0]];
916  const labelPairList& pPoints0 = globalPointPoints[e[0]];
917  const labelList& pEdges1 = globalPointEdges[e[1]];
918  const labelPairList& pPoints1 = globalPointPoints[e[1]];
919 
920  // Most edges will be size 2
921  DynamicList<labelPair> eEdges(2);
922  // Append myself.
923  eEdges.append
924  (
926  (
928  edgeI,
929  globalTransforms().nullTransformIndex()
930  )
931  );
932 
933  forAll(pEdges0, i)
934  {
935  forAll(pEdges1, j)
936  {
937  if
938  (
939  pEdges0[i] == pEdges1[j]
940  && pEdges0[i] != globalEdgeNumbers.toGlobal(edgeI)
941  )
942  {
943  // Found a shared edge. Now check if the endpoints
944  // go through the same transformation.
945  // Local: e[0] remote:pPoints1[j]
946  // Local: e[1] remote:pPoints0[i]
947 
948 
949  // Find difference in transforms to go from point on remote
950  // edge (pPoints1[j]) to this point.
951 
952  label transform0 = findTransform
953  (
954  allPointConnectivity[e[0]],
955  pPoints1[j],
956  e[0]
957  );
958  label transform1 = findTransform
959  (
960  allPointConnectivity[e[1]],
961  pPoints0[i],
962  e[1]
963  );
964 
965  if (transform0 == transform1)
966  {
967  label procI = globalEdgeNumbers.whichProcID(pEdges0[i]);
968  eEdges.append
969  (
971  (
972  procI,
973  globalEdgeNumbers.toLocal(procI, pEdges0[i]),
974  transform0
975  )
976  );
977  }
978  }
979  }
980  }
981 
982  allEdgeConnectivity[edgeI].transfer(eEdges);
983  sort(allEdgeConnectivity[edgeI], globalIndexAndTransform::less());
984  }
985 
986  // We now have - in allEdgeConnectivity - a list of edges which are shared
987  // between multiple processors. Filter into non-transformed and transformed
988  // connections.
989 
990  globalEdgeSlavesPtr_.reset(new labelListList(edges.size()));
991  labelListList& globalEdgeSlaves = globalEdgeSlavesPtr_();
992  List<labelPairList> transformedEdges(edges.size());
993  forAll(allEdgeConnectivity, edgeI)
994  {
995  const labelPairList& edgeInfo = allEdgeConnectivity[edgeI];
996  if (edgeInfo.size() >= 2)
997  {
998  const labelPair& masterInfo = edgeInfo[0];
999 
1000  // Check if master edge (= first element (since sorted)) is me.
1001  if
1002  (
1003  (
1005  == Pstream::myProcNo()
1006  )
1007  && (globalIndexAndTransform::index(masterInfo) == edgeI)
1008  )
1009  {
1010  // Sort into transformed and untransformed
1011  labelList& eEdges = globalEdgeSlaves[edgeI];
1012  eEdges.setSize(edgeInfo.size()-1);
1013 
1014  labelPairList& trafoEEdges = transformedEdges[edgeI];
1015  trafoEEdges.setSize(edgeInfo.size()-1);
1016 
1017  label nonTransformI = 0;
1018  label transformI = 0;
1019 
1020  for (label i = 1; i < edgeInfo.size(); i++)
1021  {
1022  const labelPair& info = edgeInfo[i];
1024  label index = globalIndexAndTransform::index(info);
1026  (
1027  info
1028  );
1029 
1030  if (transform == globalTransforms().nullTransformIndex())
1031  {
1032  eEdges[nonTransformI++] = globalEdgeNumbers.toGlobal
1033  (
1034  procI,
1035  index
1036  );
1037  }
1038  else
1039  {
1040  trafoEEdges[transformI++] = info;
1041  }
1042  }
1043 
1044  eEdges.setSize(nonTransformI);
1045  trafoEEdges.setSize(transformI);
1046  }
1047  }
1048  }
1049 
1050 
1051  // Construct map
1052  globalEdgeTransformedSlavesPtr_.reset(new labelListList());
1053 
1054  List<Map<label> > compactMap(Pstream::nProcs());
1055  globalEdgeSlavesMapPtr_.reset
1056  (
1057  new mapDistribute
1058  (
1059  globalEdgeNumbers,
1060  globalEdgeSlaves,
1061 
1062  globalTransforms(),
1063  transformedEdges,
1064  globalEdgeTransformedSlavesPtr_(),
1065 
1066  compactMap
1067  )
1068  );
1069 
1070 
1071  if (debug)
1072  {
1073  Pout<< "globalMeshData::calcGlobalEdgeSlaves() :"
1074  << " coupled edges:" << edges.size()
1075  << " additional coupled edges:"
1076  << globalEdgeSlavesMapPtr_().constructSize() - edges.size()
1077  << endl;
1078  }
1079 }
1080 
1081 
1083 {
1084  if (debug)
1085  {
1086  Pout<< "globalMeshData::calcGlobalEdgeOrientation() :"
1087  << " calculating edge orientation w.r.t. master edge." << endl;
1088  }
1089 
1090  const globalIndex& globalPoints = globalPointNumbering();
1091 
1092  // 1. Determine master point
1093  labelList masterPoint;
1094  {
1095  const mapDistribute& map = globalPointSlavesMap();
1096 
1097  masterPoint.setSize(map.constructSize());
1098  masterPoint = labelMax;
1099 
1100  for (label pointI = 0; pointI < coupledPatch().nPoints(); pointI++)
1101  {
1102  masterPoint[pointI] = globalPoints.toGlobal(pointI);
1103  }
1104  syncData
1105  (
1106  masterPoint,
1107  globalPointSlaves(),
1108  globalPointTransformedSlaves(),
1109  map,
1110  minEqOp<label>()
1111  );
1112  }
1113 
1114  // Now all points should know who is master by comparing their global
1115  // pointID with the masterPointID. We now can use this information
1116  // to find the orientation of the master edge.
1117 
1118  {
1119  const mapDistribute& map = globalEdgeSlavesMap();
1120  const labelListList& slaves = globalEdgeSlaves();
1121  const labelListList& transformedSlaves = globalEdgeTransformedSlaves();
1122 
1123  // Distribute orientation of master edge (in masterPoint numbering)
1124  labelPairList masterEdgeVerts(map.constructSize());
1125  masterEdgeVerts = labelPair(labelMax, labelMax);
1126 
1127  for (label edgeI = 0; edgeI < coupledPatch().nEdges(); edgeI++)
1128  {
1129  if
1130  (
1131  (
1132  slaves[edgeI].size()
1133  + transformedSlaves[edgeI].size()
1134  )
1135  > 0
1136  )
1137  {
1138  // I am master. Fill in my masterPoint equivalent.
1139 
1140  const edge& e = coupledPatch().edges()[edgeI];
1141  masterEdgeVerts[edgeI] = labelPair
1142  (
1143  masterPoint[e[0]],
1144  masterPoint[e[1]]
1145  );
1146  }
1147  }
1148  syncData
1149  (
1150  masterEdgeVerts,
1151  slaves,
1152  transformedSlaves,
1153  map,
1155  );
1156 
1157  // Now check my edges on how they relate to the master's edgeVerts
1158  globalEdgeOrientationPtr_.reset
1159  (
1160  new PackedBoolList(coupledPatch().nEdges())
1161  );
1162  PackedBoolList& globalEdgeOrientation = globalEdgeOrientationPtr_();
1163 
1164  forAll(coupledPatch().edges(), edgeI)
1165  {
1166  const edge& e = coupledPatch().edges()[edgeI];
1167  const labelPair masterE
1168  (
1169  masterPoint[e[0]],
1170  masterPoint[e[1]]
1171  );
1172 
1173  label stat = labelPair::compare
1174  (
1175  masterE,
1176  masterEdgeVerts[edgeI]
1177  );
1178  if (stat == 0)
1179  {
1181  << "problem : my edge:" << e
1182  << " in master points:" << masterE
1183  << " v.s. masterEdgeVerts:" << masterEdgeVerts[edgeI]
1184  << exit(FatalError);
1185  }
1186  else
1187  {
1188  globalEdgeOrientation[edgeI] = (stat == 1);
1189  }
1190  }
1191  }
1192 
1193  if (debug)
1194  {
1195  Pout<< "globalMeshData::calcGlobalEdgeOrientation() :"
1196  << " finished calculating edge orientation."
1197  << endl;
1198  }
1199 }
1200 
1201 
1202 // Calculate uncoupled boundary faces (without calculating
1203 // primitiveMesh::pointFaces())
1206  labelListList& pointBoundaryFaces
1207 ) const
1208 {
1209  const polyBoundaryMesh& bMesh = mesh_.boundaryMesh();
1210  const Map<label>& meshPointMap = coupledPatch().meshPointMap();
1211 
1212  // 1. Count
1213 
1214  labelList nPointFaces(coupledPatch().nPoints(), 0);
1215 
1216  forAll(bMesh, patchI)
1217  {
1218  const polyPatch& pp = bMesh[patchI];
1219 
1220  if (!pp.coupled())
1221  {
1222  forAll(pp, i)
1223  {
1224  const face& f = pp[i];
1225 
1226  forAll(f, fp)
1227  {
1228  Map<label>::const_iterator iter = meshPointMap.find
1229  (
1230  f[fp]
1231  );
1232  if (iter != meshPointMap.end())
1233  {
1234  nPointFaces[iter()]++;
1235  }
1236  }
1237  }
1238  }
1239  }
1240 
1241 
1242  // 2. Size
1243 
1244  pointBoundaryFaces.setSize(coupledPatch().nPoints());
1245  forAll(nPointFaces, pointI)
1246  {
1247  pointBoundaryFaces[pointI].setSize(nPointFaces[pointI]);
1248  }
1249  nPointFaces = 0;
1250 
1251 
1252  // 3. Fill
1253 
1254  forAll(bMesh, patchI)
1255  {
1256  const polyPatch& pp = bMesh[patchI];
1257 
1258  if (!pp.coupled())
1259  {
1260  forAll(pp, i)
1261  {
1262  const face& f = pp[i];
1263  forAll(f, fp)
1264  {
1265  Map<label>::const_iterator iter = meshPointMap.find
1266  (
1267  f[fp]
1268  );
1269  if (iter != meshPointMap.end())
1270  {
1271  label bFaceI =
1272  pp.start() + i - mesh_.nInternalFaces();
1273  pointBoundaryFaces[iter()][nPointFaces[iter()]++] =
1274  bFaceI;
1275  }
1276  }
1277  }
1278  }
1279  }
1280 }
1281 
1282 
1284 {
1285  if (debug)
1286  {
1287  Pout<< "globalMeshData::calcGlobalPointBoundaryFaces() :"
1288  << " calculating coupled point to boundary face addressing."
1289  << endl;
1290  }
1291 
1292  // Construct local point to (uncoupled)boundaryfaces.
1293  labelListList pointBoundaryFaces;
1294  calcPointBoundaryFaces(pointBoundaryFaces);
1295 
1296 
1297  // Global indices for boundary faces
1298  globalBoundaryFaceNumberingPtr_.reset
1299  (
1300  new globalIndex(mesh_.nFaces()-mesh_.nInternalFaces())
1301  );
1302  globalIndex& globalIndices = globalBoundaryFaceNumberingPtr_();
1303 
1304 
1305  // Convert local boundary faces to global numbering
1306  globalPointBoundaryFacesPtr_.reset
1307  (
1308  new labelListList(globalPointSlavesMap().constructSize())
1309  );
1310  labelListList& globalPointBoundaryFaces = globalPointBoundaryFacesPtr_();
1311 
1312  forAll(pointBoundaryFaces, pointI)
1313  {
1314  const labelList& bFaces = pointBoundaryFaces[pointI];
1315  labelList& globalFaces = globalPointBoundaryFaces[pointI];
1316  globalFaces.setSize(bFaces.size());
1317  forAll(bFaces, i)
1318  {
1319  globalFaces[i] = globalIndices.toGlobal(bFaces[i]);
1320  }
1321  }
1322 
1323 
1324  // Pull slave pointBoundaryFaces to master
1325  globalPointSlavesMap().distribute
1326  (
1327  globalPointBoundaryFaces,
1328  true // put data on transformed points into correct slots
1329  );
1330 
1331 
1332  // Merge slave labels into master globalPointBoundaryFaces.
1333  // Split into untransformed and transformed values.
1334  const labelListList& pointSlaves = globalPointSlaves();
1335  const labelListList& pointTransformSlaves =
1336  globalPointTransformedSlaves();
1337 
1338 
1339  // Any faces coming in through transformation
1340  List<labelPairList> transformedFaces(pointSlaves.size());
1341 
1342 
1343  forAll(pointSlaves, pointI)
1344  {
1345  const labelList& slaves = pointSlaves[pointI];
1346  const labelList& transformedSlaves = pointTransformSlaves[pointI];
1347 
1348  if (slaves.size() > 0)
1349  {
1350  labelList& myBFaces = globalPointBoundaryFaces[pointI];
1351  label sz = myBFaces.size();
1352 
1353  // Count
1354  label n = 0;
1355  forAll(slaves, i)
1356  {
1357  n += globalPointBoundaryFaces[slaves[i]].size();
1358  }
1359  // Fill
1360  myBFaces.setSize(sz+n);
1361  n = sz;
1362  forAll(slaves, i)
1363  {
1364  const labelList& slaveBFaces =
1365  globalPointBoundaryFaces[slaves[i]];
1366 
1367  // Add all slaveBFaces. Note that need to check for
1368  // uniqueness only in case of cyclics.
1369 
1370  forAll(slaveBFaces, j)
1371  {
1372  label slave = slaveBFaces[j];
1373  if (findIndex(SubList<label>(myBFaces, sz), slave) == -1)
1374  {
1375  myBFaces[n++] = slave;
1376  }
1377  }
1378  }
1379  myBFaces.setSize(n);
1380  }
1381 
1382 
1383  if (transformedSlaves.size() > 0)
1384  {
1385  const labelList& untrafoFaces = globalPointBoundaryFaces[pointI];
1386 
1387  labelPairList& myBFaces = transformedFaces[pointI];
1388  label sz = myBFaces.size();
1389 
1390  // Count
1391  label n = 0;
1392  forAll(transformedSlaves, i)
1393  {
1394  n += globalPointBoundaryFaces[transformedSlaves[i]].size();
1395  }
1396  // Fill
1397  myBFaces.setSize(sz+n);
1398  n = sz;
1399  forAll(transformedSlaves, i)
1400  {
1401  label transformI = globalPointSlavesMap().whichTransform
1402  (
1403  transformedSlaves[i]
1404  );
1405 
1406  const labelList& slaveBFaces =
1407  globalPointBoundaryFaces[transformedSlaves[i]];
1408 
1409  forAll(slaveBFaces, j)
1410  {
1411  label slave = slaveBFaces[j];
1412  // Check that same face not already present untransformed
1413  if (findIndex(untrafoFaces, slave)== -1)
1414  {
1415  label procI = globalIndices.whichProcID(slave);
1416  label faceI = globalIndices.toLocal(procI, slave);
1417 
1418  myBFaces[n++] = globalIndexAndTransform::encode
1419  (
1420  procI,
1421  faceI,
1422  transformI
1423  );
1424  }
1425  }
1426  }
1427  myBFaces.setSize(n);
1428  }
1429 
1430 
1431  if (slaves.size() + transformedSlaves.size() == 0)
1432  {
1433  globalPointBoundaryFaces[pointI].clear();
1434  }
1435  }
1436 
1437  // Construct a map to get the face data directly
1438  List<Map<label> > compactMap(Pstream::nProcs());
1439 
1440  globalPointTransformedBoundaryFacesPtr_.reset
1441  (
1442  new labelListList(transformedFaces.size())
1443  );
1444 
1445  globalPointBoundaryFacesMapPtr_.reset
1446  (
1447  new mapDistribute
1448  (
1449  globalIndices,
1450  globalPointBoundaryFaces,
1451 
1452  globalTransforms(),
1453  transformedFaces,
1454  globalPointTransformedBoundaryFacesPtr_(),
1455 
1456  compactMap
1457  )
1458  );
1459  globalPointBoundaryFaces.setSize(coupledPatch().nPoints());
1460  globalPointTransformedBoundaryFacesPtr_().setSize(coupledPatch().nPoints());
1461 
1462  if (debug)
1463  {
1464  Pout<< "globalMeshData::calcGlobalPointBoundaryFaces() :"
1465  << " coupled points:" << coupledPatch().nPoints()
1466  << " local boundary faces:" << globalIndices.localSize()
1467  << " additional coupled faces:"
1468  << globalPointBoundaryFacesMapPtr_().constructSize()
1469  - globalIndices.localSize()
1470  << endl;
1471  }
1472 }
1473 
1474 
1476 {
1477  if (debug)
1478  {
1479  Pout<< "globalMeshData::calcGlobalPointBoundaryCells() :"
1480  << " calculating coupled point to boundary cell addressing."
1481  << endl;
1482  }
1483 
1484  // Create map of boundary cells and point-cell addressing
1485  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1486 
1487  label bCellI = 0;
1488  Map<label> meshCellMap(4*coupledPatch().nPoints());
1489  DynamicList<label> cellMap(meshCellMap.size());
1490 
1491  // Create addressing for point to boundary cells (local)
1492  labelListList pointBoundaryCells(coupledPatch().nPoints());
1493 
1494  forAll(coupledPatch().meshPoints(), pointI)
1495  {
1496  label meshPointI = coupledPatch().meshPoints()[pointI];
1497  const labelList& pCells = mesh_.pointCells(meshPointI);
1498 
1499  labelList& bCells = pointBoundaryCells[pointI];
1500  bCells.setSize(pCells.size());
1501 
1502  forAll(pCells, i)
1503  {
1504  label cellI = pCells[i];
1505  Map<label>::iterator fnd = meshCellMap.find(cellI);
1506 
1507  if (fnd != meshCellMap.end())
1508  {
1509  bCells[i] = fnd();
1510  }
1511  else
1512  {
1513  meshCellMap.insert(cellI, bCellI);
1514  cellMap.append(cellI);
1515  bCells[i] = bCellI;
1516  bCellI++;
1517  }
1518  }
1519  }
1520 
1521 
1522  boundaryCellsPtr_.reset(new labelList());
1523  labelList& boundaryCells = boundaryCellsPtr_();
1524  boundaryCells.transfer(cellMap.shrink());
1525 
1526 
1527  // Convert point-cells to global (boundary)cell numbers
1528  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1529 
1530  globalBoundaryCellNumberingPtr_.reset
1531  (
1532  new globalIndex(boundaryCells.size())
1533  );
1534  globalIndex& globalIndices = globalBoundaryCellNumberingPtr_();
1535 
1536 
1537  globalPointBoundaryCellsPtr_.reset
1538  (
1539  new labelListList(globalPointSlavesMap().constructSize())
1540  );
1541  labelListList& globalPointBoundaryCells = globalPointBoundaryCellsPtr_();
1542 
1543  forAll(pointBoundaryCells, pointI)
1544  {
1545  const labelList& pCells = pointBoundaryCells[pointI];
1546  labelList& globalCells = globalPointBoundaryCells[pointI];
1547  globalCells.setSize(pCells.size());
1548  forAll(pCells, i)
1549  {
1550  globalCells[i] = globalIndices.toGlobal(pCells[i]);
1551  }
1552  }
1553 
1554 
1555  // Pull slave pointBoundaryCells to master
1556  globalPointSlavesMap().distribute
1557  (
1558  globalPointBoundaryCells,
1559  true // put data on transformed points into correct slots
1560  );
1561 
1562 
1563  // Merge slave labels into master globalPointBoundaryCells
1564  const labelListList& pointSlaves = globalPointSlaves();
1565  const labelListList& pointTransformSlaves =
1566  globalPointTransformedSlaves();
1567 
1568  List<labelPairList> transformedCells(pointSlaves.size());
1569 
1570 
1571  forAll(pointSlaves, pointI)
1572  {
1573  const labelList& slaves = pointSlaves[pointI];
1574  const labelList& transformedSlaves = pointTransformSlaves[pointI];
1575 
1576  if (slaves.size() > 0)
1577  {
1578  labelList& myBCells = globalPointBoundaryCells[pointI];
1579  label sz = myBCells.size();
1580 
1581  // Count
1582  label n = 0;
1583  forAll(slaves, i)
1584  {
1585  n += globalPointBoundaryCells[slaves[i]].size();
1586  }
1587  // Fill
1588  myBCells.setSize(sz+n);
1589  n = sz;
1590  forAll(slaves, i)
1591  {
1592  const labelList& slaveBCells =
1593  globalPointBoundaryCells[slaves[i]];
1594 
1595  // Add all slaveBCells. Note that need to check for
1596  // uniqueness only in case of cyclics.
1597 
1598  forAll(slaveBCells, j)
1599  {
1600  label slave = slaveBCells[j];
1601  if (findIndex(SubList<label>(myBCells, sz), slave) == -1)
1602  {
1603  myBCells[n++] = slave;
1604  }
1605  }
1606  }
1607  myBCells.setSize(n);
1608  }
1609 
1610 
1611  if (transformedSlaves.size() > 0)
1612  {
1613  const labelList& untrafoCells = globalPointBoundaryCells[pointI];
1614 
1615  labelPairList& myBCells = transformedCells[pointI];
1616  label sz = myBCells.size();
1617 
1618  // Count
1619  label n = 0;
1620  forAll(transformedSlaves, i)
1621  {
1622  n += globalPointBoundaryCells[transformedSlaves[i]].size();
1623  }
1624  // Fill
1625  myBCells.setSize(sz+n);
1626  n = sz;
1627  forAll(transformedSlaves, i)
1628  {
1629  label transformI = globalPointSlavesMap().whichTransform
1630  (
1631  transformedSlaves[i]
1632  );
1633 
1634  const labelList& slaveBCells =
1635  globalPointBoundaryCells[transformedSlaves[i]];
1636 
1637  forAll(slaveBCells, j)
1638  {
1639  label slave = slaveBCells[j];
1640 
1641  // Check that same cell not already present untransformed
1642  if (findIndex(untrafoCells, slave)== -1)
1643  {
1644  label procI = globalIndices.whichProcID(slave);
1645  label cellI = globalIndices.toLocal(procI, slave);
1646  myBCells[n++] = globalIndexAndTransform::encode
1647  (
1648  procI,
1649  cellI,
1650  transformI
1651  );
1652  }
1653  }
1654  }
1655  myBCells.setSize(n);
1656  }
1657 
1658  if (slaves.size() + transformedSlaves.size() == 0)
1659  {
1660  globalPointBoundaryCells[pointI].clear();
1661  }
1662  }
1663 
1664  // Construct a map to get the cell data directly
1665  List<Map<label> > compactMap(Pstream::nProcs());
1666 
1667  globalPointTransformedBoundaryCellsPtr_.reset
1668  (
1669  new labelListList(transformedCells.size())
1670  );
1671 
1672  globalPointBoundaryCellsMapPtr_.reset
1673  (
1674  new mapDistribute
1675  (
1676  globalIndices,
1677  globalPointBoundaryCells,
1678 
1679  globalTransforms(),
1680  transformedCells,
1681  globalPointTransformedBoundaryCellsPtr_(),
1682 
1683  compactMap
1684  )
1685  );
1686  globalPointBoundaryCells.setSize(coupledPatch().nPoints());
1687  globalPointTransformedBoundaryCellsPtr_().setSize(coupledPatch().nPoints());
1688 
1689  if (debug)
1690  {
1691  Pout<< "globalMeshData::calcGlobalPointBoundaryCells() :"
1692  << " coupled points:" << coupledPatch().nPoints()
1693  << " local boundary cells:" << globalIndices.localSize()
1694  << " additional coupled cells:"
1695  << globalPointBoundaryCellsMapPtr_().constructSize()
1696  - globalIndices.localSize()
1697  << endl;
1698  }
1699 }
1700 
1701 
1703 {
1704  if (debug)
1705  {
1706  Pout<< "globalMeshData::calcGlobalCoPointSlaves() :"
1707  << " calculating coupled master to collocated"
1708  << " slave point addressing." << endl;
1709  }
1710 
1711  // Calculate connected points for master points.
1712  globalPoints globalData(mesh_, coupledPatch(), true, false);
1713 
1714  globalCoPointSlavesPtr_.reset
1715  (
1716  new labelListList
1717  (
1718  globalData.pointPoints().xfer()
1719  )
1720  );
1721  globalCoPointSlavesMapPtr_.reset
1722  (
1723  new mapDistribute
1724  (
1725  globalData.map().xfer()
1726  )
1727  );
1728 
1729  if (debug)
1730  {
1731  Pout<< "globalMeshData::calcGlobalCoPointSlaves() :"
1732  << " finished calculating coupled master to collocated"
1733  << " slave point addressing." << endl;
1734  }
1735 }
1736 
1737 
1738 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
1739 
1740 // Construct from polyMesh
1742 :
1744  mesh_(mesh),
1745  nTotalPoints_(-1),
1746  nTotalFaces_(-1),
1747  nTotalCells_(-1),
1748  processorPatches_(0),
1749  processorPatchIndices_(0),
1750  processorPatchNeighbours_(0),
1751  nGlobalPoints_(-1),
1752  sharedPointLabelsPtr_(NULL),
1753  sharedPointAddrPtr_(NULL),
1754  sharedPointGlobalLabelsPtr_(NULL),
1755  nGlobalEdges_(-1),
1756  sharedEdgeLabelsPtr_(NULL),
1757  sharedEdgeAddrPtr_(NULL)
1758 {
1759  updateMesh();
1760 }
1761 
1762 
1763 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
1764 
1766 {
1767  clearOut();
1768 }
1769 
1770 
1772 {
1773  // Point
1774  nGlobalPoints_ = -1;
1775  sharedPointLabelsPtr_.clear();
1776  sharedPointAddrPtr_.clear();
1777  sharedPointGlobalLabelsPtr_.clear();
1778 
1779  // Edge
1780  nGlobalEdges_ = -1;
1781  sharedEdgeLabelsPtr_.clear();
1782  sharedEdgeAddrPtr_.clear();
1783 
1784  // Coupled patch
1785  coupledPatchPtr_.clear();
1786  coupledPatchMeshEdgesPtr_.clear();
1787  coupledPatchMeshEdgeMapPtr_.clear();
1788  globalTransformsPtr_.clear();
1789 
1790  // Point
1791  globalPointNumberingPtr_.clear();
1792  globalPointSlavesPtr_.clear();
1793  globalPointTransformedSlavesPtr_.clear();
1794  globalPointSlavesMapPtr_.clear();
1795  // Edge
1796  globalEdgeNumberingPtr_.clear();
1797  globalEdgeSlavesPtr_.clear();
1798  globalEdgeTransformedSlavesPtr_.clear();
1799  globalEdgeOrientationPtr_.clear();
1800  globalEdgeSlavesMapPtr_.clear();
1801 
1802  // Face
1803  globalBoundaryFaceNumberingPtr_.clear();
1804  globalPointBoundaryFacesPtr_.clear();
1805  globalPointTransformedBoundaryFacesPtr_.clear();
1806  globalPointBoundaryFacesMapPtr_.clear();
1807 
1808  // Cell
1809  boundaryCellsPtr_.clear();
1810  globalBoundaryCellNumberingPtr_.clear();
1811  globalPointBoundaryCellsPtr_.clear();
1812  globalPointTransformedBoundaryCellsPtr_.clear();
1813  globalPointBoundaryCellsMapPtr_.clear();
1814 
1815  // Other: collocated points
1816  globalCoPointSlavesPtr_.clear();
1817  globalCoPointSlavesMapPtr_.clear();
1818 }
1819 
1820 
1821 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
1822 
1823 // Return shared point global labels.
1825 {
1826  if (!sharedPointGlobalLabelsPtr_.valid())
1827  {
1828  sharedPointGlobalLabelsPtr_.reset
1829  (
1830  new labelList(sharedPointLabels().size())
1831  );
1832  labelList& sharedPointGlobalLabels = sharedPointGlobalLabelsPtr_();
1833 
1834  IOobject addrHeader
1835  (
1836  "pointProcAddressing",
1837  mesh_.facesInstance()/mesh_.meshSubDir,
1838  mesh_,
1840  );
1841 
1842  if (addrHeader.headerOk())
1843  {
1844  // There is a pointProcAddressing file so use it to get labels
1845  // on the original mesh
1846  Pout<< "globalMeshData::sharedPointGlobalLabels : "
1847  << "Reading pointProcAddressing" << endl;
1848 
1849  labelIOList pointProcAddressing(addrHeader);
1850 
1851  const labelList& pointLabels = sharedPointLabels();
1852 
1853  forAll(pointLabels, i)
1854  {
1855  // Get my mesh point
1856  label pointI = pointLabels[i];
1857 
1858  // Map to mesh point of original mesh
1859  sharedPointGlobalLabels[i] = pointProcAddressing[pointI];
1860  }
1861  }
1862  else
1863  {
1864  Pout<< "globalMeshData::sharedPointGlobalLabels :"
1865  << " Setting pointProcAddressing to -1" << endl;
1866 
1867  sharedPointGlobalLabels = -1;
1868  }
1869  }
1870  return sharedPointGlobalLabelsPtr_();
1871 }
1872 
1873 
1874 // Collect coordinates of shared points. (does parallel communication!)
1876 {
1877  // Get all processors to send their shared points to master.
1878  // (not very efficient)
1879 
1880  pointField sharedPoints(nGlobalPoints());
1881  const labelList& pointAddr = sharedPointAddr();
1882  const labelList& pointLabels = sharedPointLabels();
1883 
1884  if (Pstream::master())
1885  {
1886  // Master:
1887  // insert my own data first
1888  forAll(pointLabels, i)
1889  {
1890  label sharedPointI = pointAddr[i];
1891 
1892  sharedPoints[sharedPointI] = mesh_.points()[pointLabels[i]];
1893  }
1894 
1895  // Receive data from slaves and insert
1896  for
1897  (
1898  int slave=Pstream::firstSlave();
1899  slave<=Pstream::lastSlave();
1900  slave++
1901  )
1902  {
1903  IPstream fromSlave(Pstream::blocking, slave);
1904 
1905  labelList nbrSharedPointAddr;
1906  pointField nbrSharedPoints;
1907  fromSlave >> nbrSharedPointAddr >> nbrSharedPoints;
1908 
1909  forAll(nbrSharedPointAddr, i)
1910  {
1911  label sharedPointI = nbrSharedPointAddr[i];
1912 
1913  sharedPoints[sharedPointI] = nbrSharedPoints[i];
1914  }
1915  }
1916 
1917  // Send back
1918  for
1919  (
1920  int slave=Pstream::firstSlave();
1921  slave<=Pstream::lastSlave();
1922  slave++
1923  )
1924  {
1925  OPstream toSlave
1926  (
1928  slave,
1929  sharedPoints.size()*sizeof(vector::zero)
1930  );
1931  toSlave << sharedPoints;
1932  }
1933  }
1934  else
1935  {
1936  // Slave:
1937  // send points
1938  {
1940 
1941  toMaster
1942  << pointAddr
1943  << UIndirectList<point>(mesh_.points(), pointLabels)();
1944  }
1945 
1946  // Receive sharedPoints
1947  {
1949  fromMaster >> sharedPoints;
1950  }
1951  }
1952 
1953  return sharedPoints;
1954 }
1955 
1956 
1957 // Collect coordinates of shared points. (does parallel communication!)
1959 {
1960  // Get coords of my shared points
1961  pointField sharedPoints(mesh_.points(), sharedPointLabels());
1962 
1963  // Append from all processors
1964  combineReduce(sharedPoints, ListPlusEqOp<pointField>());
1965 
1966  // Merge tolerance
1967  scalar tolDim = matchTol_ * mesh_.bounds().mag();
1968 
1969  // And see how many are unique
1970  labelList pMap;
1971  pointField mergedPoints;
1972 
1974  (
1975  sharedPoints, // coordinates to merge
1976  tolDim, // tolerance
1977  false, // verbosity
1978  pMap,
1979  mergedPoints
1980  );
1981 
1982  return mergedPoints;
1983 }
1984 
1985 
1987 {
1988  if (nGlobalPoints_ == -1)
1989  {
1990  calcSharedPoints();
1991  }
1992  return nGlobalPoints_;
1993 }
1994 
1995 
1997 {
1998  if (!sharedPointLabelsPtr_.valid())
1999  {
2000  calcSharedPoints();
2001  }
2002  return sharedPointLabelsPtr_();
2003 }
2004 
2005 
2007 {
2008  if (!sharedPointAddrPtr_.valid())
2009  {
2010  calcSharedPoints();
2011  }
2012  return sharedPointAddrPtr_();
2013 }
2014 
2015 
2017 {
2018  if (nGlobalEdges_ == -1)
2019  {
2020  calcSharedEdges();
2021  }
2022  return nGlobalEdges_;
2023 }
2024 
2025 
2027 {
2028  if (!sharedEdgeLabelsPtr_.valid())
2029  {
2030  calcSharedEdges();
2031  }
2032  return sharedEdgeLabelsPtr_();
2033 }
2034 
2035 
2037 {
2038  if (!sharedEdgeAddrPtr_.valid())
2039  {
2040  calcSharedEdges();
2041  }
2042  return sharedEdgeAddrPtr_();
2043 }
2044 
2045 
2047 {
2048  if (!coupledPatchPtr_.valid())
2049  {
2050  const polyBoundaryMesh& bMesh = mesh_.boundaryMesh();
2051 
2052  label nCoupled = 0;
2053 
2054  forAll(bMesh, patchI)
2055  {
2056  const polyPatch& pp = bMesh[patchI];
2057 
2058  if (pp.coupled())
2059  {
2060  nCoupled += pp.size();
2061  }
2062  }
2063  labelList coupledFaces(nCoupled);
2064  nCoupled = 0;
2065 
2066  forAll(bMesh, patchI)
2067  {
2068  const polyPatch& pp = bMesh[patchI];
2069 
2070  if (pp.coupled())
2071  {
2072  label faceI = pp.start();
2073 
2074  forAll(pp, i)
2075  {
2076  coupledFaces[nCoupled++] = faceI++;
2077  }
2078  }
2079  }
2080 
2081  coupledPatchPtr_.reset
2082  (
2084  (
2086  (
2087  mesh_.faces(),
2088  coupledFaces
2089  ),
2090  mesh_.points()
2091  )
2092  );
2093 
2094  if (debug)
2095  {
2096  Pout<< "globalMeshData::coupledPatch() :"
2097  << " constructed coupled faces patch:"
2098  << " faces:" << coupledPatchPtr_().size()
2099  << " points:" << coupledPatchPtr_().nPoints()
2100  << endl;
2101  }
2102  }
2103  return coupledPatchPtr_();
2104 }
2105 
2106 
2108 {
2109  if (!coupledPatchMeshEdgesPtr_.valid())
2110  {
2111  coupledPatchMeshEdgesPtr_.reset
2112  (
2113  new labelList
2114  (
2115  coupledPatch().meshEdges
2116  (
2117  mesh_.edges(),
2118  mesh_.pointEdges()
2119  )
2120  )
2121  );
2122  }
2123  return coupledPatchMeshEdgesPtr_();
2124 }
2125 
2126 
2128 const
2129 {
2130  if (!coupledPatchMeshEdgeMapPtr_.valid())
2131  {
2132  const labelList& me = coupledPatchMeshEdges();
2133 
2134  coupledPatchMeshEdgeMapPtr_.reset(new Map<label>(2*me.size()));
2135  Map<label>& em = coupledPatchMeshEdgeMapPtr_();
2136 
2137  forAll(me, i)
2138  {
2139  em.insert(me[i], i);
2140  }
2141  }
2142  return coupledPatchMeshEdgeMapPtr_();
2143 }
2144 
2145 
2147 {
2148  if (!globalPointNumberingPtr_.valid())
2149  {
2150  globalPointNumberingPtr_.reset
2151  (
2152  new globalIndex(coupledPatch().nPoints())
2153  );
2154  }
2155  return globalPointNumberingPtr_();
2156 }
2157 
2158 
2161 {
2162  if (!globalTransformsPtr_.valid())
2163  {
2164  globalTransformsPtr_.reset(new globalIndexAndTransform(mesh_));
2165  }
2166  return globalTransformsPtr_();
2167 }
2168 
2169 
2171 {
2172  if (!globalPointSlavesPtr_.valid())
2173  {
2174  calcGlobalPointSlaves();
2175  }
2176  return globalPointSlavesPtr_();
2177 }
2178 
2179 
2181 const
2182 {
2183  if (!globalPointTransformedSlavesPtr_.valid())
2184  {
2185  calcGlobalPointSlaves();
2186  }
2187  return globalPointTransformedSlavesPtr_();
2188 }
2189 
2190 
2192 {
2193  if (!globalPointSlavesMapPtr_.valid())
2194  {
2195  calcGlobalPointSlaves();
2196  }
2197  return globalPointSlavesMapPtr_();
2198 }
2199 
2200 
2202 {
2203  if (!globalEdgeNumberingPtr_.valid())
2204  {
2205  globalEdgeNumberingPtr_.reset
2206  (
2207  new globalIndex(coupledPatch().nEdges())
2208  );
2209  }
2210  return globalEdgeNumberingPtr_();
2211 }
2212 
2213 
2215 {
2216  if (!globalEdgeSlavesPtr_.valid())
2217  {
2218  calcGlobalEdgeSlaves();
2219  }
2220  return globalEdgeSlavesPtr_();
2221 }
2222 
2223 
2225 const
2226 {
2227  if (!globalEdgeTransformedSlavesPtr_.valid())
2228  {
2229  calcGlobalEdgeSlaves();
2230  }
2231  return globalEdgeTransformedSlavesPtr_();
2232 }
2233 
2234 
2236 {
2237  if (!globalEdgeOrientationPtr_.valid())
2238  {
2239  calcGlobalEdgeOrientation();
2240  }
2241  return globalEdgeOrientationPtr_();
2242 }
2243 
2244 
2246 {
2247  if (!globalEdgeSlavesMapPtr_.valid())
2248  {
2249  calcGlobalEdgeSlaves();
2250  }
2251  return globalEdgeSlavesMapPtr_();
2252 }
2253 
2254 
2256 const
2257 {
2258  if (!globalBoundaryFaceNumberingPtr_.valid())
2259  {
2260  calcGlobalPointBoundaryFaces();
2261  }
2262  return globalBoundaryFaceNumberingPtr_();
2263 }
2264 
2265 
2267 const
2268 {
2269  if (!globalPointBoundaryFacesPtr_.valid())
2270  {
2271  calcGlobalPointBoundaryFaces();
2272  }
2273  return globalPointBoundaryFacesPtr_();
2274 }
2275 
2276 
2277 const Foam::labelListList&
2279 {
2280  if (!globalPointTransformedBoundaryFacesPtr_.valid())
2281  {
2282  calcGlobalPointBoundaryFaces();
2283  }
2284  return globalPointTransformedBoundaryFacesPtr_();
2285 }
2286 
2287 
2289 const
2290 {
2291  if (!globalPointBoundaryFacesMapPtr_.valid())
2292  {
2293  calcGlobalPointBoundaryFaces();
2294  }
2295  return globalPointBoundaryFacesMapPtr_();
2296 }
2297 
2298 
2300 {
2301  if (!boundaryCellsPtr_.valid())
2302  {
2303  calcGlobalPointBoundaryCells();
2304  }
2305  return boundaryCellsPtr_();
2306 }
2307 
2308 
2310 const
2311 {
2312  if (!globalBoundaryCellNumberingPtr_.valid())
2313  {
2314  calcGlobalPointBoundaryCells();
2315  }
2316  return globalBoundaryCellNumberingPtr_();
2317 }
2318 
2319 
2321 const
2322 {
2323  if (!globalPointBoundaryCellsPtr_.valid())
2324  {
2325  calcGlobalPointBoundaryCells();
2326  }
2327  return globalPointBoundaryCellsPtr_();
2328 }
2329 
2330 
2331 const Foam::labelListList&
2333 {
2334  if (!globalPointTransformedBoundaryCellsPtr_.valid())
2335  {
2336  calcGlobalPointBoundaryCells();
2337  }
2338  return globalPointTransformedBoundaryCellsPtr_();
2339 }
2340 
2341 
2343 const
2344 {
2345  if (!globalPointBoundaryCellsMapPtr_.valid())
2346  {
2347  calcGlobalPointBoundaryCells();
2348  }
2349  return globalPointBoundaryCellsMapPtr_();
2350 }
2351 
2352 
2354 {
2355  if (!globalCoPointSlavesPtr_.valid())
2356  {
2357  calcGlobalCoPointSlaves();
2358  }
2359  return globalCoPointSlavesPtr_();
2360 }
2361 
2362 
2364 {
2365  if (!globalCoPointSlavesMapPtr_.valid())
2366  {
2367  calcGlobalCoPointSlaves();
2368  }
2369  return globalCoPointSlavesMapPtr_();
2370 }
2371 
2372 
2375  labelList& pointToGlobal,
2376  labelList& uniquePoints
2377 ) const
2378 {
2379  const indirectPrimitivePatch& cpp = coupledPatch();
2380  const globalIndex& globalCoupledPoints = globalPointNumbering();
2381  // Use collocated only
2382  const labelListList& pointSlaves = globalCoPointSlaves();
2383  const mapDistribute& pointSlavesMap = globalCoPointSlavesMap();
2384 
2385 
2386  // Points are either
2387  // - master with slaves
2388  // - slave with a master
2389  // - other (since e.g. non-collocated cyclics not connected)
2390 
2391  labelList masterGlobalPoint(cpp.nPoints(), -1);
2392  forAll(masterGlobalPoint, pointI)
2393  {
2394  const labelList& slavePoints = pointSlaves[pointI];
2395  if (slavePoints.size() > 0)
2396  {
2397  masterGlobalPoint[pointI] = globalCoupledPoints.toGlobal(pointI);
2398  }
2399  }
2400 
2401  // Sync by taking max
2402  syncData
2403  (
2404  masterGlobalPoint,
2405  pointSlaves,
2406  labelListList(0), // no transforms
2407  pointSlavesMap,
2408  maxEqOp<label>()
2409  );
2410 
2411 
2412  // 1. Count number of masters on my processor.
2413  label nMaster = 0;
2414  PackedBoolList isMaster(mesh_.nPoints(), 1);
2415  forAll(pointSlaves, pointI)
2416  {
2417  if (masterGlobalPoint[pointI] == -1)
2418  {
2419  // unconnected point (e.g. from separated cyclic)
2420  nMaster++;
2421  }
2422  else if
2423  (
2424  masterGlobalPoint[pointI]
2425  == globalCoupledPoints.toGlobal(pointI)
2426  )
2427  {
2428  // connected master
2429  nMaster++;
2430  }
2431  else
2432  {
2433  // connected slave point
2434  isMaster[cpp.meshPoints()[pointI]] = 0;
2435  }
2436  }
2437 
2438  label myUniquePoints = mesh_.nPoints() - cpp.nPoints() + nMaster;
2439 
2440  //Pout<< "Points :" << nl
2441  // << " mesh : " << mesh_.nPoints() << nl
2442  // << " of which coupled : " << cpp.nPoints() << nl
2443  // << " of which master : " << nMaster << nl
2444  // << endl;
2445 
2446 
2447  // 2. Create global indexing for unique points.
2448  autoPtr<globalIndex> globalPointsPtr(new globalIndex(myUniquePoints));
2449 
2450 
2451  // 3. Assign global point numbers. Keep slaves unset.
2452  pointToGlobal.setSize(mesh_.nPoints());
2453  pointToGlobal = -1;
2454  uniquePoints.setSize(myUniquePoints);
2455  nMaster = 0;
2456 
2457  forAll(isMaster, meshPointI)
2458  {
2459  if (isMaster[meshPointI])
2460  {
2461  pointToGlobal[meshPointI] = globalPointsPtr().toGlobal(nMaster);
2462  uniquePoints[nMaster] = meshPointI;
2463  nMaster++;
2464  }
2465  }
2466 
2467 
2468  // 4. Push global index for coupled points to slaves.
2469  {
2470  labelList masterToGlobal(pointSlavesMap.constructSize(), -1);
2471 
2472  forAll(pointSlaves, pointI)
2473  {
2474  const labelList& slaves = pointSlaves[pointI];
2475 
2476  if (slaves.size() > 0)
2477  {
2478  // Duplicate master globalpoint into slave slots
2479  label meshPointI = cpp.meshPoints()[pointI];
2480  masterToGlobal[pointI] = pointToGlobal[meshPointI];
2481  forAll(slaves, i)
2482  {
2483  masterToGlobal[slaves[i]] = masterToGlobal[pointI];
2484  }
2485  }
2486  }
2487 
2488  // Send back
2489  pointSlavesMap.reverseDistribute(cpp.nPoints(), masterToGlobal);
2490 
2491  // On slave copy master index into overal map.
2492  forAll(pointSlaves, pointI)
2493  {
2494  label meshPointI = cpp.meshPoints()[pointI];
2495 
2496  if (!isMaster[meshPointI])
2497  {
2498  pointToGlobal[meshPointI] = masterToGlobal[pointI];
2499  }
2500  }
2501  }
2502 
2503  return globalPointsPtr;
2504 }
2505 
2506 
2509  const labelList& meshPoints,
2510  const Map<label>& meshPointMap,
2511  labelList& pointToGlobal,
2512  labelList& uniqueMeshPoints
2513 ) const
2514 {
2515  const indirectPrimitivePatch& cpp = coupledPatch();
2516  const labelListList& pointSlaves = globalCoPointSlaves();
2517  const mapDistribute& pointSlavesMap = globalCoPointSlavesMap();
2518 
2519 
2520  // The patch points come in two variants:
2521  // - not on a coupled patch so guaranteed unique
2522  // - on a coupled patch
2523  // If the point is on a coupled patch the problem is that the
2524  // master-slave structure (globalPointSlaves etc.) assigns one of the
2525  // coupled points to be the master but this master point is not
2526  // necessarily on the patch itself! (it might just be connected to the
2527  // patch point via coupled patches).
2528 
2529 
2530  // Determine mapping:
2531  // - from patch point to coupled point (or -1)
2532  // - from coupled point to global patch point
2533  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2534 
2535  globalIndex globalPPoints(meshPoints.size());
2536 
2537  labelList patchToCoupled(meshPoints.size(), -1);
2538  label nCoupled = 0;
2539  labelList coupledToGlobalPatch(pointSlavesMap.constructSize(), -1);
2540 
2541  // Note: loop over patch since usually smaller
2542  forAll(meshPoints, patchPointI)
2543  {
2544  label meshPointI = meshPoints[patchPointI];
2545 
2546  Map<label>::const_iterator iter = cpp.meshPointMap().find(meshPointI);
2547 
2548  if (iter != cpp.meshPointMap().end())
2549  {
2550  patchToCoupled[patchPointI] = iter();
2551  coupledToGlobalPatch[iter()] = globalPPoints.toGlobal(patchPointI);
2552  nCoupled++;
2553  }
2554  }
2555 
2556  //Pout<< "Patch:" << nl
2557  // << " points:" << meshPoints.size() << nl
2558  // << " of which on coupled patch:" << nCoupled << endl;
2559 
2560 
2561  // Determine master of connected points
2562  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2563  // Problem is that the coupled master might not be on the patch. So
2564  // work out the best patch-point master from all connected points.
2565  // - if the coupled master is on the patch it becomes the patch-point master
2566  // - else the slave with the lowest numbered patch point label
2567 
2568  // Get all data on master
2569  pointSlavesMap.distribute(coupledToGlobalPatch);
2570  forAll(pointSlaves, coupledPointI)
2571  {
2572  const labelList& slaves = pointSlaves[coupledPointI];
2573 
2574  if (slaves.size() > 0)
2575  {
2576  // I am master. What is the best candidate for patch-point master
2577  label masterI = labelMax;
2578  if (coupledToGlobalPatch[coupledPointI] != -1)
2579  {
2580  // I am master and on the coupled patch. Use me.
2581  masterI = coupledToGlobalPatch[coupledPointI];
2582  }
2583  else
2584  {
2585  // Get min of slaves as master.
2586  forAll(slaves, i)
2587  {
2588  label slavePp = coupledToGlobalPatch[slaves[i]];
2589  if (slavePp != -1 && slavePp < masterI)
2590  {
2591  masterI = slavePp;
2592  }
2593  }
2594  }
2595 
2596  if (masterI != labelMax)
2597  {
2598  // Push back
2599  coupledToGlobalPatch[coupledPointI] = masterI;
2600  forAll(slaves, i)
2601  {
2602  coupledToGlobalPatch[slaves[i]] = masterI;
2603  }
2604  }
2605  }
2606  }
2607  pointSlavesMap.reverseDistribute(cpp.nPoints(), coupledToGlobalPatch);
2608 
2609 
2610  // Generate compact numbering for master points
2611  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2612  // Now coupledToGlobalPatch is the globalIndex of the master point.
2613  // Now every processor can check whether they hold it and generate a
2614  // compact numbering.
2615 
2616  label nMasters = 0;
2617  forAll(meshPoints, patchPointI)
2618  {
2619  if (patchToCoupled[patchPointI] == -1)
2620  {
2621  nMasters++;
2622  }
2623  else
2624  {
2625  label coupledPointI = patchToCoupled[patchPointI];
2626  if
2627  (
2628  globalPPoints.toGlobal(patchPointI)
2629  == coupledToGlobalPatch[coupledPointI]
2630  )
2631  {
2632  // I am the master
2633  nMasters++;
2634  }
2635  }
2636  }
2637 
2638  autoPtr<globalIndex> globalPointsPtr(new globalIndex(nMasters));
2639 
2640  //Pout<< "Patch:" << nl
2641  // << " points:" << meshPoints.size() << nl
2642  // << " of which on coupled patch:" << nCoupled << nl
2643  // << " of which master:" << nMasters << endl;
2644 
2645 
2646 
2647  // Push back compact numbering for master point onto slaves
2648  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2649 
2650  pointToGlobal.setSize(meshPoints.size());
2651  pointToGlobal = -1;
2652  uniqueMeshPoints.setSize(nMasters);
2653 
2654  // Sync master in global point numbering so all know the master point.
2655  // Initialise globalMaster to be -1 except at a globalMaster.
2656  labelList globalMaster(cpp.nPoints(), -1);
2657 
2658  nMasters = 0;
2659  forAll(meshPoints, patchPointI)
2660  {
2661  if (patchToCoupled[patchPointI] == -1)
2662  {
2663  uniqueMeshPoints[nMasters++] = meshPoints[patchPointI];
2664  }
2665  else
2666  {
2667  label coupledPointI = patchToCoupled[patchPointI];
2668  if
2669  (
2670  globalPPoints.toGlobal(patchPointI)
2671  == coupledToGlobalPatch[coupledPointI]
2672  )
2673  {
2674  globalMaster[coupledPointI] =
2675  globalPointsPtr().toGlobal(nMasters);
2676  uniqueMeshPoints[nMasters++] = meshPoints[patchPointI];
2677  }
2678  }
2679  }
2680 
2681 
2682  // Sync by taking max
2683  syncData
2684  (
2685  globalMaster,
2686  pointSlaves,
2687  labelListList(0), // no transforms
2688  pointSlavesMap,
2689  maxEqOp<label>()
2690  );
2691 
2692 
2693  // Now everyone has the master point in globalPointsPtr numbering. Fill
2694  // in the pointToGlobal map.
2695  nMasters = 0;
2696  forAll(meshPoints, patchPointI)
2697  {
2698  if (patchToCoupled[patchPointI] == -1)
2699  {
2700  pointToGlobal[patchPointI] = globalPointsPtr().toGlobal(nMasters++);
2701  }
2702  else
2703  {
2704  label coupledPointI = patchToCoupled[patchPointI];
2705  pointToGlobal[patchPointI] = globalMaster[coupledPointI];
2706 
2707  if
2708  (
2709  globalPPoints.toGlobal(patchPointI)
2710  == coupledToGlobalPatch[coupledPointI]
2711  )
2712  {
2713  nMasters++;
2714  }
2715  }
2716  }
2717 
2718  return globalPointsPtr;
2719 }
2720 
2721 
2723 {
2724  // Topology does not change and we don't store any geometry so nothing
2725  // needs to be done.
2726  // Only global transformations might change but this is not really
2727  // supported.
2728 }
2729 
2730 
2731 // Update all data after morph
2733 {
2734  // Clear out old data
2735  clearOut();
2736 
2737  // Do processor patch addressing
2738  initProcAddr();
2739 
2740  scalar tolDim = matchTol_ * mesh_.bounds().mag();
2741 
2742  if (debug)
2743  {
2744  Pout<< "globalMeshData : merge dist:" << tolDim << endl;
2745  }
2746 
2747  // *** Temporary hack to avoid problems with overlapping communication
2748  // *** between these reductions and the calculation of deltaCoeffs
2749  //label comm = UPstream::worldComm + 1;
2751  (
2754  true
2755  );
2756 
2757  // Total number of faces.
2758  nTotalFaces_ = returnReduce
2759  (
2760  mesh_.nFaces(),
2761  sumOp<label>(),
2762  Pstream::msgType(),
2763  comm
2764  );
2765 
2766  if (debug)
2767  {
2768  Pout<< "globalMeshData : nTotalFaces_:" << nTotalFaces_ << endl;
2769  }
2770 
2771  nTotalCells_ = returnReduce
2772  (
2773  mesh_.nCells(),
2774  sumOp<label>(),
2775  Pstream::msgType(),
2776  comm
2777  );
2778 
2779  if (debug)
2780  {
2781  Pout<< "globalMeshData : nTotalCells_:" << nTotalCells_ << endl;
2782  }
2783 
2784  nTotalPoints_ = returnReduce
2785  (
2786  mesh_.nPoints(),
2787  sumOp<label>(),
2788  Pstream::msgType(),
2789  comm
2790  );
2791 
2793 
2794  if (debug)
2795  {
2796  Pout<< "globalMeshData : nTotalPoints_:" << nTotalPoints_ << endl;
2797  }
2798 }
2799 
2800 
2801 // ************************************************************************* //
Foam::globalMeshData::processorPatches_
labelList processorPatches_
List of processor patch labels.
Definition: globalMeshData.H:133
Foam::IOobject
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
Foam::help::sharedEdge
edge sharedEdge(const faceType1 &f1, const faceType2 &f2)
return the edge shared by the faces
Definition: helperFunctionsTopologyManipulationI.H:343
Foam::globalMeshData::globalPointTransformedSlaves
const labelListList & globalPointTransformedSlaves() const
Definition: globalMeshData.C:2180
Foam::globalMeshData::globalCoPointSlavesMap
const mapDistribute & globalCoPointSlavesMap() const
Definition: globalMeshData.C:2363
Foam::PackedBoolList
A bit-packed bool list.
Definition: PackedBoolList.H:63
Foam::globalMeshData::globalPointSlaves
const labelListList & globalPointSlaves() const
Definition: globalMeshData.C:2170
PackedList.H
Foam::globalPoints
Calculates points shared by more than two processor patches or cyclic patches.
Definition: globalPoints.H:100
Foam::Vector< scalar >::zero
static const Vector zero
Definition: Vector.H:80
Foam::globalMeshData::globalBoundaryFaceNumbering
const globalIndex & globalBoundaryFaceNumbering() const
Numbering of boundary faces is face-mesh.nInternalFaces()
Definition: globalMeshData.C:2255
Foam::globalMeshData::countSharedEdges
static void countSharedEdges(const EdgeMap< labelList > &, EdgeMap< label > &, label &)
Helper function for shared edge addressing.
Definition: globalMeshData.C:256
Foam::UOPstream
Output inter-processor communications stream operating on external buffer.
Definition: UOPstream.H:54
Foam::labelList
List< label > labelList
A List of labels.
Definition: labelList.H:56
Foam::globalMeshData::globalPointBoundaryCellsMap
const mapDistribute & globalPointBoundaryCellsMap() const
Definition: globalMeshData.C:2342
Foam::globalMeshData::coupledPatchMeshEdgeMap
const Map< label > & coupledPatchMeshEdgeMap() const
Return map from mesh edges to coupledPatch edges.
Definition: globalMeshData.C:2127
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:86
Foam::globalMeshData::calcGlobalEdgeSlaves
void calcGlobalEdgeSlaves() const
Calculate global edge addressing.
Definition: globalMeshData.C:867
Foam::polyBoundaryMesh
Foam::polyBoundaryMesh.
Definition: polyBoundaryMesh.H:60
Foam::globalMeshData::matchTol_
static const Foam::scalar matchTol_
Geometric tolerance (fraction of bounding box)
Definition: globalMeshData.H:346
Foam::globalMeshData::globalEdgeSlavesMap
const mapDistribute & globalEdgeSlavesMap() const
Definition: globalMeshData.C:2245
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::findIndex
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
Foam::DynamicList< label >
Foam::List::xfer
Xfer< List< T > > xfer()
Transfer contents to the Xfer container.
Definition: ListI.H:90
Foam::OPstream
Output inter-processor communications stream.
Definition: OPstream.H:50
globalMeshData.H
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
Foam::globalMeshData::sharedPointGlobalLabels
const labelList & sharedPointGlobalLabels() const
Return shared point global labels. Tries to read.
Definition: globalMeshData.C:1824
Foam::globalMeshData::globalBoundaryCellNumbering
const globalIndex & globalBoundaryCellNumbering() const
Numbering of boundary cells is according to boundaryCells()
Definition: globalMeshData.C:2309
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:53
Foam::labelMax
static const label labelMax
Definition: label.H:62
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:387
Foam::globalMeshData::sharedEdgeAddr
const labelList & sharedEdgeAddr() const
Return addressing into the complete globally shared edge.
Definition: globalMeshData.C:2036
Foam::PstreamBuffers
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Definition: PstreamBuffers.H:85
Foam::polyPatch::coupled
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
Definition: polyPatch.H:322
Foam::globalMeshData::globalPointBoundaryCells
const labelListList & globalPointBoundaryCells() const
Definition: globalMeshData.C:2320
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:377
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
Foam::maxEqOp
Definition: ops.H:77
Foam::globalMeshData::sharedEdgeLabels
const labelList & sharedEdgeLabels() const
Return indices of local edges that are globally shared.
Definition: globalMeshData.C:2026
Foam::List::transfer
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Foam::HashTable::insert
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
Foam::Map< label >
Foam::globalMeshData::calcGlobalPointBoundaryCells
void calcGlobalPointBoundaryCells() const
Calculate global point to global boundary cell addressing.
Definition: globalMeshData.C:1475
Foam::combineReduce
void combineReduce(const List< UPstream::commsStruct > &comms, T &Value, const CombineOp &cop, const int tag, const label comm)
Definition: PstreamCombineReduceOps.H:52
Foam::globalIndex::localSize
label localSize() const
My local size.
Definition: globalIndexI.H:60
Foam::globalIndexAndTransform::encode
static labelPair encode(const label index, const label transformIndex)
Encode index and bare index as components on own processor.
Definition: globalIndexAndTransformI.H:340
Foam::IOobject::MUST_READ
@ MUST_READ
Definition: IOobject.H:108
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:421
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::globalMeshData::clearOut
void clearOut()
Remove all demand driven data.
Definition: globalMeshData.C:1771
Foam::globalMeshData::globalPointSlavesMap
const mapDistribute & globalPointSlavesMap() const
Definition: globalMeshData.C:2191
polyMesh.H
Foam::globalMeshData::calcSharedEdges
void calcSharedEdges() const
Calculate shared edge addressing.
Definition: globalMeshData.C:301
Foam::constant::atomic::me
const dimensionedScalar me
Electron mass.
Foam::globalMeshData::ListPlusEqOp
Definition: globalMeshData.H:320
Foam::globalMeshData::nGlobalEdges
label nGlobalEdges() const
Return number of globally shared edges. Demand-driven.
Definition: globalMeshData.C:2016
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
Foam::transform
dimensionSet transform(const dimensionSet &)
Definition: dimensionSet.C:465
Foam::globalMeshData::globalMeshData
globalMeshData(const globalMeshData &)
Disallow default bitwise copy construct.
Foam::globalMeshData::boundaryCells
const labelList & boundaryCells() const
From boundary cell to mesh cell.
Definition: globalMeshData.C:2299
forAllConstIter
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
OFstream.H
Foam::globalMeshData::mergePoints
autoPtr< globalIndex > mergePoints(labelList &pointToGlobal, labelList &uniquePoints) const
Helper for merging (collocated!) mesh point data.
Definition: globalMeshData.C:2374
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::globalPoints::map
const mapDistribute & map() const
Corresponding map.
Definition: globalPoints.H:347
Foam::IOobject::headerOk
bool headerOk()
Read and check header info.
Definition: IOobject.C:439
PstreamCombineReduceOps.H
Combination-Reduction operation for a parallel run. The information from all nodes is collected on th...
Foam::UPstream::blocking
@ blocking
Definition: UPstream.H:66
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::globalMeshData::initProcAddr
void initProcAddr()
Set up processor patch addressing.
Definition: globalMeshData.C:67
matchPoints.H
Determine correspondence between points. See below.
Foam::globalMeshData::globalPointTransformedBoundaryFaces
const labelListList & globalPointTransformedBoundaryFaces() const
Definition: globalMeshData.C:2278
Foam::globalMeshData::nGlobalPoints
label nGlobalPoints() const
Return number of globally shared points.
Definition: globalMeshData.C:1986
Foam::UPstream::allocateCommunicator
static label allocateCommunicator(const label parent, const labelList &subRanks, const bool doPstream=true)
Allocate a new communicator.
Definition: UPstream.C:248
Foam::UPstream::nonBlocking
@ nonBlocking
Definition: UPstream.H:68
Foam::globalIndexAndTransform::nullTransformIndex
label nullTransformIndex() const
Return the transformIndex (index in transformPermutations)
Definition: globalIndexAndTransformI.H:429
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::globalIndexAndTransform::transformIndex
static label transformIndex(const labelPair &globalIAndTransform)
Transform carried by the object.
Definition: globalIndexAndTransformI.H:401
Foam::UPstream
Inter-processor communications stream.
Definition: UPstream.H:58
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::globalPoints::pointPoints
const labelListList & pointPoints() const
Non-transformed connected points per point (in mapDistribute.
Definition: globalPoints.H:322
Foam::UPstream::lastSlave
static int lastSlave(const label communicator=0)
Process index of last slave.
Definition: UPstream.H:428
Foam::nl
static const char nl
Definition: Ostream.H:260
globalIndexAndTransform.H
Foam::globalMeshData::globalEdgeOrientation
const PackedBoolList & globalEdgeOrientation() const
Is my edge same orientation as master edge.
Definition: globalMeshData.C:2235
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
Foam::minEqOp
Definition: ops.H:78
Foam::globalMeshData::globalTransforms
const globalIndexAndTransform & globalTransforms() const
Global transforms numbering.
Definition: globalMeshData.C:2160
Foam::globalMeshData::calcGlobalEdgeOrientation
void calcGlobalEdgeOrientation() const
Calculate orientation w.r.t. edge master.
Definition: globalMeshData.C:1082
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:152
Foam::IndirectList
A List with indirect addressing.
Definition: IndirectList.H:102
Foam::globalIndexAndTransform::index
static label index(const labelPair &globalIAndTransform)
Index carried by the object.
Definition: globalIndexAndTransformI.H:383
Foam::ProcessorTopology
Determines processor-processor connection. After instantiation contains on all processors the process...
Definition: ProcessorTopology.H:56
Foam::minEqOp< labelPair >
Definition: createShellMesh.C:48
Foam::UPstream::freeCommunicator
static void freeCommunicator(const label communicator, const bool doPstream=true)
Free a previously allocated communicator.
Definition: UPstream.C:314
Foam::DynamicList::shrink
DynamicList< T, SizeInc, SizeMult, SizeDiv > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:258
Foam::globalMeshData::globalEdgeSlaves
const labelListList & globalEdgeSlaves() const
Definition: globalMeshData.C:2214
Foam::UPstream::masterNo
static int masterNo()
Process index of the master.
Definition: UPstream.H:393
Foam::mapDistribute::distribute
void distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute data using default commsType.
Definition: mapDistributeTemplates.C:155
Foam::globalMeshData::globalPointNumbering
const globalIndex & globalPointNumbering() const
Numbering of coupled points is according to coupledPatch.
Definition: globalMeshData.C:2146
Foam::globalMeshData::globalPointBoundaryFaces
const labelListList & globalPointBoundaryFaces() const
Definition: globalMeshData.C:2266
Foam::PstreamBuffers::finishedSends
void finishedSends(const bool block=true)
Mark all sends as having been done. This will start receives.
Definition: PstreamBuffers.C:82
Foam::identity
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
Foam::PrimitivePatch::nPoints
label nPoints() const
Return number of points supporting patch faces.
Definition: PrimitivePatchTemplate.H:293
Foam::FatalError
error FatalError
processorPolyPatch.H
Foam::HashTable< T, edge, Hash< edge > >::size
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
Foam::globalMeshData::calcGlobalPointBoundaryFaces
void calcGlobalPointBoundaryFaces() const
Calculate global point to global boundary face addressing.
Definition: globalMeshData.C:1283
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
Foam::UPstream::firstSlave
static int firstSlave()
Process index of first slave.
Definition: UPstream.H:422
Foam::globalMeshData::calcSharedPoints
void calcSharedPoints() const
Calculate shared point addressing.
Definition: globalMeshData.C:134
Pstream.H
Foam::globalMeshData::movePoints
void movePoints(const pointField &newPoints)
Update for moving points.
Definition: globalMeshData.C:2722
Foam::globalMeshData::calcGlobalPointSlaves
void calcGlobalPointSlaves() const
Calculate global point addressing.
Definition: globalMeshData.C:531
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::globalMeshData::calcPointConnectivity
void calcPointConnectivity(List< labelPairList > &) const
Calculate connected points.
Definition: globalMeshData.C:569
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:63
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
Foam::polyPatch::start
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:312
Foam::HashTable::find
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
Foam::DynamicList::append
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:405
Foam::UPstream::master
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:399
Foam::globalMeshData::calcPointBoundaryFaces
void calcPointBoundaryFaces(labelListList &) const
Calculate coupled point to uncoupled boundary faces. Local only.
Definition: globalMeshData.C:1205
Foam::mapDistributeBase::constructSize
label constructSize() const
Constructed data size.
Definition: mapDistributeBase.H:244
Foam::List::setSize
void setSize(const label)
Reset size of List.
Foam::globalIndex::toLocal
label toLocal(const label i) const
From global to local on current processor.
Definition: globalIndexI.H:117
Foam::autoPtr< Foam::globalIndex >
Foam::globalMeshData::globalEdgeNumbering
const globalIndex & globalEdgeNumbering() const
Definition: globalMeshData.C:2201
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
Foam::EdgeMap
Map from edge (expressed as its endpoints) to value.
Definition: EdgeMap.H:47
Foam::UPstream::msgType
static int & msgType()
Message tag of standard messages.
Definition: UPstream.H:452
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::globalIndexAndTransform::processor
static label processor(const labelPair &globalIAndTransform)
Which processor does this come from?
Definition: globalIndexAndTransformI.H:392
Foam::globalMeshData::~globalMeshData
~globalMeshData()
Destructor.
Definition: globalMeshData.C:1765
Foam::sumOp
Definition: ops.H:162
Foam::Pair
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: contiguous.H:49
Foam::Pout
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
Foam::HashTable::clear
void clear()
Clear all entries from table.
Definition: HashTable.C:473
Foam::globalMeshData::globalEdgeTransformedSlaves
const labelListList & globalEdgeTransformedSlaves() const
Definition: globalMeshData.C:2224
mapDistribute.H
f
labelList f(nPoints)
Foam::globalIndex::size
label size() const
Global sum of localSizes.
Definition: globalIndexI.H:66
Foam::UPstream::worldComm
static label worldComm
Default communicator (all processors)
Definition: UPstream.H:258
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::globalMeshData::coupledPatch
const indirectPrimitivePatch & coupledPatch() const
Return patch of all coupled faces.
Definition: globalMeshData.C:2046
Foam::minEqOp< labelPair >::operator()
void operator()(labelPair &x, const labelPair &y) const
Definition: globalMeshData.C:55
Foam::globalIndexAndTransform::less
Less function class used in sorting encoded transforms and indices.
Definition: globalIndexAndTransform.H:71
Foam::globalIndex::whichProcID
label whichProcID(const label i) const
Which processor does global come from? Binary search.
Definition: globalIndexI.H:123
Foam::globalMeshData::globalPointTransformedBoundaryCells
const labelListList & globalPointTransformedBoundaryCells() const
Definition: globalMeshData.C:2332
labelIOList.H
patchi
label patchi
Definition: getPatchFieldScalar.H:1
Foam::globalMeshData::calcGlobalCoPointSlaves
void calcGlobalCoPointSlaves() const
Definition: globalMeshData.C:1702
Foam::IOList< label >
Foam::List::clear
void clear()
Clear the list, i.e. set size to zero.
Definition: List.C:379
Foam::globalMeshData::processorPatchIndices_
labelList processorPatchIndices_
List of indices into processorPatches_ for each patch.
Definition: globalMeshData.H:138
Foam::PtrList::size
label size() const
Return the number of elements in the PtrList.
Definition: PtrListI.H:32
Foam::globalMeshData::mesh_
const polyMesh & mesh_
Reference to mesh.
Definition: globalMeshData.H:114
x
x
Definition: LISASMDCalcMethod2.H:52
mergePoints.H
Merge points. See below.
Foam::mapDistribute::reverseDistribute
void reverseDistribute(const label constructSize, List< T > &, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType.
Definition: mapDistributeTemplates.C:187
Foam::globalPoints::transformedPointPoints
const labelListList & transformedPointPoints() const
Transformed points per point (in mapDistribute indices)
Definition: globalPoints.H:335
Foam::globalMeshData::sharedPointLabels
const labelList & sharedPointLabels() const
Return indices of local points that are globally shared.
Definition: globalMeshData.C:1996
Foam::UIndirectList
A List with indirect addressing.
Definition: fvMatrix.H:106
Foam::boundaryMesh
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:59
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:50
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Foam::sort
void sort(UList< T > &)
Definition: UList.C:107
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::UIPstream
Input inter-processor communications stream operating on external buffer.
Definition: UIPstream.H:53
Foam::PrimitivePatch::meshPointMap
const Map< label > & meshPointMap() const
Mesh point map. Given the global point index find its.
Definition: PrimitivePatchTemplate.C:412
Foam::PrimitivePatch::meshPoints
const labelList & meshPoints() const
Return labelList of mesh points in patch.
Definition: PrimitivePatchTemplate.C:392
Foam::globalMeshData::sharedPoints
pointField sharedPoints() const
Collect coordinates of shared points on all processors.
Definition: globalMeshData.C:1875
Foam::mapDistribute::xfer
Xfer< mapDistribute > xfer()
Transfer contents to the Xfer container.
Definition: mapDistribute.C:531
Foam::globalIndexAndTransform
Determination and storage of the possible independent transforms introduced by coupledPolyPatches,...
Definition: globalIndexAndTransform.H:60
Foam::globalMeshData::calcGlobalPointEdges
void calcGlobalPointEdges(labelListList &globalPointEdges, List< labelPairList > &globalPointPoints) const
Calculate pointEdges and pointPoints addressing.
Definition: globalMeshData.C:650
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::globalMeshData::geometricSharedPoints
pointField geometricSharedPoints() const
Like sharedPoints but keeps cyclic points separate.
Definition: globalMeshData.C:1958
Foam::min
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::globalMeshData::findTransform
label findTransform(const labelPairList &info, const labelPair &remotePoint, const label localPoint) const
Look up remote and local point and find using info the.
Definition: globalMeshData.C:812
Foam::mergePoints
label mergePoints(const UList< Type > &points, const scalar mergeTol, const bool verbose, labelList &pointMap, const Type &origin=Type::zero)
Sorts and merges points. All points closer than/equal mergeTol get merged.
Foam::globalMeshData::globalPointBoundaryFacesMap
const mapDistribute & globalPointBoundaryFacesMap() const
Definition: globalMeshData.C:2288
Foam::labelPair
Pair< label > labelPair
Label pair.
Definition: labelPair.H:48
pointLabels
labelList pointLabels(nPoints, -1)
Foam::name
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
Foam::Pair::compare
static int compare(const Pair< Type > &a, const Pair< Type > &b)
Compare Pairs.
Definition: Pair.H:141
Foam::globalMeshData::globalCoPointSlaves
const labelListList & globalCoPointSlaves() const
Definition: globalMeshData.C:2353
Foam::globalIndex::toGlobal
label toGlobal(const label i) const
From local to global.
Definition: globalIndexI.H:82
y
scalar y
Definition: LISASMDCalcMethod1.H:14
Foam::PrimitivePatch
A list of faces which address into the list of points.
Definition: PrimitivePatchTemplate.H:88
Foam::globalMeshData::processorPatchNeighbours_
labelList processorPatchNeighbours_
processorPatchIndices_ of the neighbours processor patches
Definition: globalMeshData.H:141
globalPoints.H
Foam::globalMeshData::updateMesh
void updateMesh()
Change global mesh data given a topological change. Does a.
Definition: globalMeshData.C:2732