polyMeshAdder.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-2013 OpenFOAM Foundation
6  \\/ M anipulation |
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 "polyMeshAdder.H"
27 #include "mapAddedPolyMesh.H"
28 #include "IOobject.H"
29 #include "faceCoupleInfo.H"
30 #include "processorPolyPatch.H"
31 #include "SortableList.H"
32 #include "Time.H"
33 #include "globalMeshData.H"
34 #include "mergePoints.H"
35 #include "polyModifyFace.H"
36 #include "polyRemovePoint.H"
37 #include "polyTopoChange.H"
38 
39 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
40 
41 // Get index of patch in new set of patchnames/types
42 Foam::label Foam::polyMeshAdder::patchIndex
43 (
44  const polyPatch& p,
45  DynamicList<word>& allPatchNames,
46  DynamicList<word>& allPatchTypes
47 )
48 {
49  // Find the patch name on the list. If the patch is already there
50  // and patch types match, return index
51  const word& pType = p.type();
52  const word& pName = p.name();
53 
54  label patchI = findIndex(allPatchNames, pName);
55 
56  if (patchI == -1)
57  {
58  // Patch not found. Append to the list
59  allPatchNames.append(pName);
60  allPatchTypes.append(pType);
61 
62  return allPatchNames.size() - 1;
63  }
64  else if (allPatchTypes[patchI] == pType)
65  {
66  // Found name and types match
67  return patchI;
68  }
69  else
70  {
71  // Found the name, but type is different
72 
73  // Duplicate name is not allowed. Create a composite name from the
74  // patch name and case name
75  const word& caseName = p.boundaryMesh().mesh().time().caseName();
76 
77  allPatchNames.append(pName + "_" + caseName);
78  allPatchTypes.append(pType);
79 
80  Pout<< "label patchIndex(const polyPatch& p) : "
81  << "Patch " << p.index() << " named "
82  << pName << " in mesh " << caseName
83  << " already exists, but patch types"
84  << " do not match.\nCreating a composite name as "
85  << allPatchNames.last() << endl;
86 
87  return allPatchNames.size() - 1;
88  }
89 }
90 
91 
92 // Get index of zone in new set of zone names
93 Foam::label Foam::polyMeshAdder::zoneIndex
94 (
95  const word& curName,
96  DynamicList<word>& names
97 )
98 {
99  label zoneI = findIndex(names, curName);
100 
101  if (zoneI != -1)
102  {
103  return zoneI;
104  }
105  else
106  {
107  // Not found. Add new name to the list
108  names.append(curName);
109 
110  return names.size() - 1;
111  }
112 }
113 
114 
115 void Foam::polyMeshAdder::mergePatchNames
116 (
117  const polyBoundaryMesh& patches0,
118  const polyBoundaryMesh& patches1,
119 
120  DynamicList<word>& allPatchNames,
121  DynamicList<word>& allPatchTypes,
122 
123  labelList& from1ToAllPatches,
124  labelList& fromAllTo1Patches
125 )
126 {
127  // Insert the mesh0 patches and zones
128  allPatchNames.append(patches0.names());
129  allPatchTypes.append(patches0.types());
130 
131 
132  // Patches
133  // ~~~~~~~
134  // Patches from 0 are taken over as is; those from 1 get either merged
135  // (if they share name and type) or appended.
136  // Empty patches are filtered out much much later on.
137 
138  // Add mesh1 patches and build map both ways.
139  from1ToAllPatches.setSize(patches1.size());
140 
141  forAll(patches1, patchI)
142  {
143  from1ToAllPatches[patchI] = patchIndex
144  (
145  patches1[patchI],
146  allPatchNames,
147  allPatchTypes
148  );
149  }
150  allPatchTypes.shrink();
151  allPatchNames.shrink();
152 
153  // Invert 1 to all patch map
154  fromAllTo1Patches.setSize(allPatchNames.size());
155  fromAllTo1Patches = -1;
156 
157  forAll(from1ToAllPatches, i)
158  {
159  fromAllTo1Patches[from1ToAllPatches[i]] = i;
160  }
161 }
162 
163 
164 Foam::labelList Foam::polyMeshAdder::getPatchStarts
165 (
166  const polyBoundaryMesh& patches
167 )
168 {
169  labelList patchStarts(patches.size());
170  forAll(patches, patchI)
171  {
172  patchStarts[patchI] = patches[patchI].start();
173  }
174  return patchStarts;
175 }
176 
177 
178 Foam::labelList Foam::polyMeshAdder::getPatchSizes
179 (
180  const polyBoundaryMesh& patches
181 )
182 {
183  labelList patchSizes(patches.size());
184  forAll(patches, patchI)
185  {
186  patchSizes[patchI] = patches[patchI].size();
187  }
188  return patchSizes;
189 }
190 
191 
192 Foam::List<Foam::polyPatch*> Foam::polyMeshAdder::combinePatches
193 (
194  const polyMesh& mesh0,
195  const polyMesh& mesh1,
196  const polyBoundaryMesh& allBoundaryMesh,
197  const label nAllPatches,
198  const labelList& fromAllTo1Patches,
199 
200  const label nInternalFaces,
201  const labelList& nFaces,
202 
203  labelList& from0ToAllPatches,
204  labelList& from1ToAllPatches
205 )
206 {
207  const polyBoundaryMesh& patches0 = mesh0.boundaryMesh();
208  const polyBoundaryMesh& patches1 = mesh1.boundaryMesh();
209 
210 
211  // Compacted new patch list.
212  DynamicList<polyPatch*> allPatches(nAllPatches);
213 
214 
215  // Map from 0 to all patches (since gets compacted)
216  from0ToAllPatches.setSize(patches0.size());
217  from0ToAllPatches = -1;
218 
219  label startFaceI = nInternalFaces;
220 
221  // Copy patches0 with new sizes. First patches always come from
222  // mesh0 and will always be present.
223  forAll(patches0, patchI)
224  {
225  // Originates from mesh0. Clone with new size & filter out empty
226  // patch.
227  label filteredPatchI;
228 
229  if (nFaces[patchI] == 0 && isA<processorPolyPatch>(patches0[patchI]))
230  {
231  //Pout<< "Removing zero sized mesh0 patch "
232  // << patches0[patchI].name() << endl;
233  filteredPatchI = -1;
234  }
235  else
236  {
237  filteredPatchI = allPatches.size();
238 
239  allPatches.append
240  (
241  patches0[patchI].clone
242  (
243  allBoundaryMesh,
244  filteredPatchI,
245  nFaces[patchI],
246  startFaceI
247  ).ptr()
248  );
249  startFaceI += nFaces[patchI];
250  }
251 
252  // Record new index in allPatches
253  from0ToAllPatches[patchI] = filteredPatchI;
254 
255  // Check if patch was also in mesh1 and update its addressing if so.
256  if (fromAllTo1Patches[patchI] != -1)
257  {
258  from1ToAllPatches[fromAllTo1Patches[patchI]] = filteredPatchI;
259  }
260  }
261 
262  // Copy unique patches of mesh1.
263  forAll(from1ToAllPatches, patchI)
264  {
265  label allPatchI = from1ToAllPatches[patchI];
266 
267  if (allPatchI >= patches0.size())
268  {
269  // Patch has not been merged with any mesh0 patch.
270 
271  label filteredPatchI;
272 
273  if
274  (
275  nFaces[allPatchI] == 0
276  && isA<processorPolyPatch>(patches1[patchI])
277  )
278  {
279  //Pout<< "Removing zero sized mesh1 patch "
280  // << patches1[patchI].name() << endl;
281  filteredPatchI = -1;
282  }
283  else
284  {
285  filteredPatchI = allPatches.size();
286 
287  allPatches.append
288  (
289  patches1[patchI].clone
290  (
291  allBoundaryMesh,
292  filteredPatchI,
293  nFaces[allPatchI],
294  startFaceI
295  ).ptr()
296  );
297  startFaceI += nFaces[allPatchI];
298  }
299 
300  from1ToAllPatches[patchI] = filteredPatchI;
301  }
302  }
303 
304  allPatches.shrink();
305 
306  return allPatches;
307 }
308 
309 
310 Foam::labelList Foam::polyMeshAdder::getFaceOrder
311 (
312  const cellList& cells,
313  const label nInternalFaces,
314  const labelList& owner,
315  const labelList& neighbour
316 )
317 {
318  labelList oldToNew(owner.size(), -1);
319 
320  // Leave boundary faces in order
321  for (label faceI = nInternalFaces; faceI < owner.size(); ++faceI)
322  {
323  oldToNew[faceI] = faceI;
324  }
325 
326  // First unassigned face
327  label newFaceI = 0;
328 
329  forAll(cells, cellI)
330  {
331  const labelList& cFaces = cells[cellI];
332 
333  SortableList<label> nbr(cFaces.size());
334 
335  forAll(cFaces, i)
336  {
337  label faceI = cFaces[i];
338 
339  label nbrCellI = neighbour[faceI];
340 
341  if (nbrCellI != -1)
342  {
343  // Internal face. Get cell on other side.
344  if (nbrCellI == cellI)
345  {
346  nbrCellI = owner[faceI];
347  }
348 
349  if (cellI < nbrCellI)
350  {
351  // CellI is master
352  nbr[i] = nbrCellI;
353  }
354  else
355  {
356  // nbrCell is master. Let it handle this face.
357  nbr[i] = -1;
358  }
359  }
360  else
361  {
362  // External face. Do later.
363  nbr[i] = -1;
364  }
365  }
366 
367  nbr.sort();
368 
369  forAll(nbr, i)
370  {
371  if (nbr[i] != -1)
372  {
373  oldToNew[cFaces[nbr.indices()[i]]] = newFaceI++;
374  }
375  }
376  }
377 
378 
379  // Check done all faces.
380  forAll(oldToNew, faceI)
381  {
382  if (oldToNew[faceI] == -1)
383  {
385  (
386  "polyMeshAdder::getFaceOrder"
387  "(const cellList&, const label, const labelList&"
388  ", const labelList&) const"
389  ) << "Did not determine new position"
390  << " for face " << faceI
391  << abort(FatalError);
392  }
393  }
394 
395  return oldToNew;
396 }
397 
398 
399 // Extends face f with split points. cutEdgeToPoints gives for every
400 // edge the points introduced inbetween the endpoints.
401 void Foam::polyMeshAdder::insertVertices
402 (
403  const edgeLookup& cutEdgeToPoints,
404  const Map<label>& meshToMaster,
405  const labelList& masterToCutPoints,
406  const face& masterF,
407 
408  DynamicList<label>& workFace,
409  face& allF
410 )
411 {
412  workFace.clear();
413 
414  // Check any edge for being cut (check on the cut so takes account
415  // for any point merging on the cut)
416 
417  forAll(masterF, fp)
418  {
419  label v0 = masterF[fp];
420  label v1 = masterF.nextLabel(fp);
421 
422  // Copy existing face point
423  workFace.append(allF[fp]);
424 
425  // See if any edge between v0,v1
426 
427  Map<label>::const_iterator v0Fnd = meshToMaster.find(v0);
428  if (v0Fnd != meshToMaster.end())
429  {
430  Map<label>::const_iterator v1Fnd = meshToMaster.find(v1);
431  if (v1Fnd != meshToMaster.end())
432  {
433  // Get edge in cutPoint numbering
434  edge cutEdge
435  (
436  masterToCutPoints[v0Fnd()],
437  masterToCutPoints[v1Fnd()]
438  );
439 
440  edgeLookup::const_iterator iter = cutEdgeToPoints.find(cutEdge);
441 
442  if (iter != cutEdgeToPoints.end())
443  {
444  const edge& e = iter.key();
445  const labelList& addedPoints = iter();
446 
447  // cutPoints first in allPoints so no need for renumbering
448  if (e[0] == cutEdge[0])
449  {
450  forAll(addedPoints, i)
451  {
452  workFace.append(addedPoints[i]);
453  }
454  }
455  else
456  {
457  forAllReverse(addedPoints, i)
458  {
459  workFace.append(addedPoints[i]);
460  }
461  }
462  }
463  }
464  }
465  }
466 
467  if (workFace.size() != allF.size())
468  {
469  allF.transfer(workFace);
470  }
471 }
472 
473 
474 // Adds primitives (cells, faces, points)
475 // Cells:
476 // - all of mesh0
477 // - all of mesh1
478 // Faces:
479 // - all uncoupled of mesh0
480 // - all coupled faces
481 // - all uncoupled of mesh1
482 // Points:
483 // - all coupled
484 // - all uncoupled of mesh0
485 // - all uncoupled of mesh1
486 void Foam::polyMeshAdder::mergePrimitives
487 (
488  const polyMesh& mesh0,
489  const polyMesh& mesh1,
490  const faceCoupleInfo& coupleInfo,
491 
492  const label nAllPatches, // number of patches in the new mesh
493  const labelList& fromAllTo1Patches,
494  const labelList& from1ToAllPatches,
495 
496  pointField& allPoints,
497  labelList& from0ToAllPoints,
498  labelList& from1ToAllPoints,
499 
500  faceList& allFaces,
501  labelList& allOwner,
502  labelList& allNeighbour,
503  label& nInternalFaces,
504  labelList& nFacesPerPatch,
505  label& nCells,
506 
507  labelList& from0ToAllFaces,
508  labelList& from1ToAllFaces,
509  labelList& from1ToAllCells
510 )
511 {
512  const polyBoundaryMesh& patches0 = mesh0.boundaryMesh();
513  const polyBoundaryMesh& patches1 = mesh1.boundaryMesh();
514 
515  const primitiveFacePatch& cutFaces = coupleInfo.cutFaces();
516  const indirectPrimitivePatch& masterPatch = coupleInfo.masterPatch();
517  const indirectPrimitivePatch& slavePatch = coupleInfo.slavePatch();
518 
519 
520  // Points
521  // ~~~~~~
522 
523  // Storage for new points
524  allPoints.setSize(mesh0.nPoints() + mesh1.nPoints());
525  label allPointI = 0;
526 
527  from0ToAllPoints.setSize(mesh0.nPoints());
528  from0ToAllPoints = -1;
529  from1ToAllPoints.setSize(mesh1.nPoints());
530  from1ToAllPoints = -1;
531 
532  // Copy coupled points (on cut)
533  {
534  const pointField& cutPoints = coupleInfo.cutPoints();
535 
536  //const labelListList& cutToMasterPoints =
537  // coupleInfo.cutToMasterPoints();
538  labelListList cutToMasterPoints
539  (
541  (
542  cutPoints.size(),
543  coupleInfo.masterToCutPoints()
544  )
545  );
546 
547  //const labelListList& cutToSlavePoints =
548  // coupleInfo.cutToSlavePoints();
549  labelListList cutToSlavePoints
550  (
552  (
553  cutPoints.size(),
554  coupleInfo.slaveToCutPoints()
555  )
556  );
557 
558  forAll(cutPoints, i)
559  {
560  allPoints[allPointI] = cutPoints[i];
561 
562  // Mark all master and slave points referring to this point.
563 
564  const labelList& masterPoints = cutToMasterPoints[i];
565 
566  forAll(masterPoints, j)
567  {
568  label mesh0PointI = masterPatch.meshPoints()[masterPoints[j]];
569  from0ToAllPoints[mesh0PointI] = allPointI;
570  }
571 
572  const labelList& slavePoints = cutToSlavePoints[i];
573 
574  forAll(slavePoints, j)
575  {
576  label mesh1PointI = slavePatch.meshPoints()[slavePoints[j]];
577  from1ToAllPoints[mesh1PointI] = allPointI;
578  }
579  allPointI++;
580  }
581  }
582 
583  // Add uncoupled mesh0 points
584  forAll(mesh0.points(), pointI)
585  {
586  if (from0ToAllPoints[pointI] == -1)
587  {
588  allPoints[allPointI] = mesh0.points()[pointI];
589  from0ToAllPoints[pointI] = allPointI;
590  allPointI++;
591  }
592  }
593 
594  // Add uncoupled mesh1 points
595  forAll(mesh1.points(), pointI)
596  {
597  if (from1ToAllPoints[pointI] == -1)
598  {
599  allPoints[allPointI] = mesh1.points()[pointI];
600  from1ToAllPoints[pointI] = allPointI;
601  allPointI++;
602  }
603  }
604 
605  allPoints.setSize(allPointI);
606 
607 
608  // Faces
609  // ~~~~~
610 
611  // Sizes per patch
612  nFacesPerPatch.setSize(nAllPatches);
613  nFacesPerPatch = 0;
614 
615  // Storage for faces and owner/neighbour
616  allFaces.setSize(mesh0.nFaces() + mesh1.nFaces());
617  allOwner.setSize(allFaces.size());
618  allOwner = -1;
619  allNeighbour.setSize(allFaces.size());
620  allNeighbour = -1;
621  label allFaceI = 0;
622 
623  from0ToAllFaces.setSize(mesh0.nFaces());
624  from0ToAllFaces = -1;
625  from1ToAllFaces.setSize(mesh1.nFaces());
626  from1ToAllFaces = -1;
627 
628  // Copy mesh0 internal faces (always uncoupled)
629  for (label faceI = 0; faceI < mesh0.nInternalFaces(); faceI++)
630  {
631  allFaces[allFaceI] = renumber(from0ToAllPoints, mesh0.faces()[faceI]);
632  allOwner[allFaceI] = mesh0.faceOwner()[faceI];
633  allNeighbour[allFaceI] = mesh0.faceNeighbour()[faceI];
634  from0ToAllFaces[faceI] = allFaceI++;
635  }
636 
637  // Copy coupled faces. Every coupled face has an equivalent master and
638  // slave. Also uncount as boundary faces all the newly coupled faces.
639  const labelList& cutToMasterFaces = coupleInfo.cutToMasterFaces();
640  const labelList& cutToSlaveFaces = coupleInfo.cutToSlaveFaces();
641 
642  forAll(cutFaces, i)
643  {
644  label masterFaceI = cutToMasterFaces[i];
645 
646  label mesh0FaceI = masterPatch.addressing()[masterFaceI];
647 
648  if (from0ToAllFaces[mesh0FaceI] == -1)
649  {
650  // First occurrence of face
651  from0ToAllFaces[mesh0FaceI] = allFaceI;
652 
653  // External face becomes internal so uncount
654  label patch0 = patches0.whichPatch(mesh0FaceI);
655  nFacesPerPatch[patch0]--;
656  }
657 
658  label slaveFaceI = cutToSlaveFaces[i];
659 
660  label mesh1FaceI = slavePatch.addressing()[slaveFaceI];
661 
662  if (from1ToAllFaces[mesh1FaceI] == -1)
663  {
664  from1ToAllFaces[mesh1FaceI] = allFaceI;
665 
666  label patch1 = patches1.whichPatch(mesh1FaceI);
667  nFacesPerPatch[from1ToAllPatches[patch1]]--;
668  }
669 
670  // Copy cut face (since cutPoints are copied first no renumbering
671  // necessary)
672  allFaces[allFaceI] = cutFaces[i];
673  allOwner[allFaceI] = mesh0.faceOwner()[mesh0FaceI];
674  allNeighbour[allFaceI] = mesh1.faceOwner()[mesh1FaceI] + mesh0.nCells();
675 
676  allFaceI++;
677  }
678 
679  // Copy mesh1 internal faces (always uncoupled)
680  for (label faceI = 0; faceI < mesh1.nInternalFaces(); faceI++)
681  {
682  allFaces[allFaceI] = renumber(from1ToAllPoints, mesh1.faces()[faceI]);
683  allOwner[allFaceI] = mesh1.faceOwner()[faceI] + mesh0.nCells();
684  allNeighbour[allFaceI] = mesh1.faceNeighbour()[faceI] + mesh0.nCells();
685  from1ToAllFaces[faceI] = allFaceI++;
686  }
687 
688  nInternalFaces = allFaceI;
689 
690  // Copy (unmarked/uncoupled) external faces in new order.
691  for (label allPatchI = 0; allPatchI < nAllPatches; allPatchI++)
692  {
693  if (allPatchI < patches0.size())
694  {
695  // Patch is present in mesh0
696  const polyPatch& pp = patches0[allPatchI];
697 
698  nFacesPerPatch[allPatchI] += pp.size();
699 
700  label faceI = pp.start();
701 
702  forAll(pp, i)
703  {
704  if (from0ToAllFaces[faceI] == -1)
705  {
706  // Is uncoupled face since has not yet been dealt with
707  allFaces[allFaceI] = renumber
708  (
709  from0ToAllPoints,
710  mesh0.faces()[faceI]
711  );
712  allOwner[allFaceI] = mesh0.faceOwner()[faceI];
713  allNeighbour[allFaceI] = -1;
714 
715  from0ToAllFaces[faceI] = allFaceI++;
716  }
717  faceI++;
718  }
719  }
720  if (fromAllTo1Patches[allPatchI] != -1)
721  {
722  // Patch is present in mesh1
723  const polyPatch& pp = patches1[fromAllTo1Patches[allPatchI]];
724 
725  nFacesPerPatch[allPatchI] += pp.size();
726 
727  label faceI = pp.start();
728 
729  forAll(pp, i)
730  {
731  if (from1ToAllFaces[faceI] == -1)
732  {
733  // Is uncoupled face
734  allFaces[allFaceI] = renumber
735  (
736  from1ToAllPoints,
737  mesh1.faces()[faceI]
738  );
739  allOwner[allFaceI] =
740  mesh1.faceOwner()[faceI]
741  + mesh0.nCells();
742  allNeighbour[allFaceI] = -1;
743 
744  from1ToAllFaces[faceI] = allFaceI++;
745  }
746  faceI++;
747  }
748  }
749  }
750  allFaces.setSize(allFaceI);
751  allOwner.setSize(allFaceI);
752  allNeighbour.setSize(allFaceI);
753 
754 
755  // So now we have all ok for one-to-one mapping.
756  // For split slace faces:
757  // - mesh consistent with slave side
758  // - mesh not consistent with owner side. It is not zipped up, the
759  // original faces need edges split.
760 
761  // Use brute force to prevent having to calculate addressing:
762  // - get map from master edge to split edges.
763  // - check all faces to find any edge that is split.
764  {
765  // From two cut-points to labels of cut-points inbetween.
766  // (in order: from e[0] to e[1]
767  const edgeLookup& cutEdgeToPoints = coupleInfo.cutEdgeToPoints();
768 
769  // Get map of master face (in mesh labels) that are in cut. These faces
770  // do not need to be renumbered.
771  labelHashSet masterCutFaces(cutToMasterFaces.size());
772  forAll(cutToMasterFaces, i)
773  {
774  label meshFaceI = masterPatch.addressing()[cutToMasterFaces[i]];
775 
776  masterCutFaces.insert(meshFaceI);
777  }
778 
779  DynamicList<label> workFace(100);
780 
781  forAll(from0ToAllFaces, face0)
782  {
783  if (!masterCutFaces.found(face0))
784  {
785  label allFaceI = from0ToAllFaces[face0];
786 
787  insertVertices
788  (
789  cutEdgeToPoints,
790  masterPatch.meshPointMap(),
791  coupleInfo.masterToCutPoints(),
792  mesh0.faces()[face0],
793 
794  workFace,
795  allFaces[allFaceI]
796  );
797  }
798  }
799 
800  // Same for slave face
801 
802  labelHashSet slaveCutFaces(cutToSlaveFaces.size());
803  forAll(cutToSlaveFaces, i)
804  {
805  label meshFaceI = slavePatch.addressing()[cutToSlaveFaces[i]];
806 
807  slaveCutFaces.insert(meshFaceI);
808  }
809 
810  forAll(from1ToAllFaces, face1)
811  {
812  if (!slaveCutFaces.found(face1))
813  {
814  label allFaceI = from1ToAllFaces[face1];
815 
816  insertVertices
817  (
818  cutEdgeToPoints,
819  slavePatch.meshPointMap(),
820  coupleInfo.slaveToCutPoints(),
821  mesh1.faces()[face1],
822 
823  workFace,
824  allFaces[allFaceI]
825  );
826  }
827  }
828  }
829 
830  // Now we have a full facelist and owner/neighbour addressing.
831 
832 
833  // Cells
834  // ~~~~~
835 
836  from1ToAllCells.setSize(mesh1.nCells());
837  from1ToAllCells = -1;
838 
839  forAll(mesh1.cells(), i)
840  {
841  from1ToAllCells[i] = i + mesh0.nCells();
842  }
843 
844  // Make cells (= cell-face addressing)
845  nCells = mesh0.nCells() + mesh1.nCells();
846  cellList allCells(nCells);
847  primitiveMesh::calcCells(allCells, allOwner, allNeighbour, nCells);
848 
849  // Reorder faces for upper-triangular order.
850  labelList oldToNew
851  (
852  getFaceOrder
853  (
854  allCells,
855  nInternalFaces,
856  allOwner,
857  allNeighbour
858  )
859  );
860 
861  inplaceReorder(oldToNew, allFaces);
862  inplaceReorder(oldToNew, allOwner);
863  inplaceReorder(oldToNew, allNeighbour);
864  inplaceRenumber(oldToNew, from0ToAllFaces);
865  inplaceRenumber(oldToNew, from1ToAllFaces);
866 }
867 
868 
869 void Foam::polyMeshAdder::mergePointZones
870 (
871  const label nAllPoints,
872  const pointZoneMesh& pz0,
873  const pointZoneMesh& pz1,
874  const labelList& from0ToAllPoints,
875  const labelList& from1ToAllPoints,
876 
877  DynamicList<word>& zoneNames,
878  labelList& from1ToAll,
879  List<DynamicList<label> >& pzPoints
880 )
881 {
882  zoneNames.setCapacity(pz0.size() + pz1.size());
883  zoneNames.append(pz0.names());
884 
885  from1ToAll.setSize(pz1.size());
886 
887  forAll(pz1, zoneI)
888  {
889  from1ToAll[zoneI] = zoneIndex(pz1[zoneI].name(), zoneNames);
890  }
891  zoneNames.shrink();
892 
893 
894 
895  // Zone(s) per point. Two levels: if only one zone
896  // stored in pointToZone. Any extra stored in additionalPointToZones.
897  // This is so we only allocate labelLists per point if absolutely
898  // necesary.
899  labelList pointToZone(nAllPoints, -1);
900  labelListList addPointToZones(nAllPoints);
901 
902  // mesh0 zones kept
903  forAll(pz0, zoneI)
904  {
905  const pointZone& pz = pz0[zoneI];
906 
907  forAll(pz, i)
908  {
909  label point0 = pz[i];
910  label allPointI = from0ToAllPoints[point0];
911 
912  if (pointToZone[allPointI] == -1)
913  {
914  pointToZone[allPointI] = zoneI;
915  }
916  else if (pointToZone[allPointI] != zoneI)
917  {
918  labelList& pZones = addPointToZones[allPointI];
919  if (findIndex(pZones, zoneI) == -1)
920  {
921  pZones.append(zoneI);
922  }
923  }
924  }
925  }
926 
927  // mesh1 zones renumbered
928  forAll(pz1, zoneI)
929  {
930  const pointZone& pz = pz1[zoneI];
931  const label allZoneI = from1ToAll[zoneI];
932 
933  forAll(pz, i)
934  {
935  label point1 = pz[i];
936  label allPointI = from1ToAllPoints[point1];
937 
938  if (pointToZone[allPointI] == -1)
939  {
940  pointToZone[allPointI] = allZoneI;
941  }
942  else if (pointToZone[allPointI] != allZoneI)
943  {
944  labelList& pZones = addPointToZones[allPointI];
945  if (findIndex(pZones, allZoneI) == -1)
946  {
947  pZones.append(allZoneI);
948  }
949  }
950  }
951  }
952 
953  // Extract back into zones
954 
955  // 1. Count
956  labelList nPoints(zoneNames.size(), 0);
957  forAll(pointToZone, allPointI)
958  {
959  label zoneI = pointToZone[allPointI];
960  if (zoneI != -1)
961  {
962  nPoints[zoneI]++;
963  }
964  }
965  forAll(addPointToZones, allPointI)
966  {
967  const labelList& pZones = addPointToZones[allPointI];
968  forAll(pZones, i)
969  {
970  nPoints[pZones[i]]++;
971  }
972  }
973 
974  // 2. Fill
975  pzPoints.setSize(zoneNames.size());
976  forAll(pzPoints, zoneI)
977  {
978  pzPoints[zoneI].setCapacity(nPoints[zoneI]);
979  }
980  forAll(pointToZone, allPointI)
981  {
982  label zoneI = pointToZone[allPointI];
983  if (zoneI != -1)
984  {
985  pzPoints[zoneI].append(allPointI);
986  }
987  }
988  forAll(addPointToZones, allPointI)
989  {
990  const labelList& pZones = addPointToZones[allPointI];
991  forAll(pZones, i)
992  {
993  pzPoints[pZones[i]].append(allPointI);
994  }
995  }
996  forAll(pzPoints, i)
997  {
998  pzPoints[i].shrink();
999  stableSort(pzPoints[i]);
1000  }
1001 }
1002 
1003 
1004 void Foam::polyMeshAdder::mergeFaceZones
1005 (
1006  const labelList& allOwner,
1007 
1008  const polyMesh& mesh0,
1009  const polyMesh& mesh1,
1010 
1011  const labelList& from0ToAllFaces,
1012  const labelList& from1ToAllFaces,
1013 
1014  const labelList& from1ToAllCells,
1015 
1016  DynamicList<word>& zoneNames,
1017  labelList& from1ToAll,
1018  List<DynamicList<label> >& fzFaces,
1019  List<DynamicList<bool> >& fzFlips
1020 )
1021 {
1022  const faceZoneMesh& fz0 = mesh0.faceZones();
1023  const labelList& owner0 = mesh0.faceOwner();
1024  const faceZoneMesh& fz1 = mesh1.faceZones();
1025  const labelList& owner1 = mesh1.faceOwner();
1026 
1027 
1028  zoneNames.setCapacity(fz0.size() + fz1.size());
1029  zoneNames.append(fz0.names());
1030 
1031  from1ToAll.setSize(fz1.size());
1032 
1033  forAll(fz1, zoneI)
1034  {
1035  from1ToAll[zoneI] = zoneIndex(fz1[zoneI].name(), zoneNames);
1036  }
1037  zoneNames.shrink();
1038 
1039 
1040  // Zone(s) per face
1041  labelList faceToZone(allOwner.size(), -1);
1042  labelListList addFaceToZones(allOwner.size());
1043  boolList faceToFlip(allOwner.size(), false);
1044  boolListList addFaceToFlips(allOwner.size());
1045 
1046  // mesh0 zones kept
1047  forAll(fz0, zoneI)
1048  {
1049  const labelList& addressing = fz0[zoneI];
1050  const boolList& flipMap = fz0[zoneI].flipMap();
1051 
1052  forAll(addressing, i)
1053  {
1054  label face0 = addressing[i];
1055  bool flip0 = flipMap[i];
1056 
1057  label allFaceI = from0ToAllFaces[face0];
1058  if (allFaceI != -1)
1059  {
1060  // Check if orientation same
1061  label allCell0 = owner0[face0];
1062  if (allOwner[allFaceI] != allCell0)
1063  {
1064  flip0 = !flip0;
1065  }
1066 
1067  if (faceToZone[allFaceI] == -1)
1068  {
1069  faceToZone[allFaceI] = zoneI;
1070  faceToFlip[allFaceI] = flip0;
1071  }
1072  else if (faceToZone[allFaceI] != zoneI)
1073  {
1074  labelList& fZones = addFaceToZones[allFaceI];
1075  boolList& flipZones = addFaceToFlips[allFaceI];
1076 
1077  if (findIndex(fZones, zoneI) == -1)
1078  {
1079  fZones.append(zoneI);
1080  flipZones.append(flip0);
1081  }
1082  }
1083  }
1084  }
1085  }
1086 
1087  // mesh1 zones renumbered
1088  forAll(fz1, zoneI)
1089  {
1090  const labelList& addressing = fz1[zoneI];
1091  const boolList& flipMap = fz1[zoneI].flipMap();
1092 
1093  const label allZoneI = from1ToAll[zoneI];
1094 
1095  forAll(addressing, i)
1096  {
1097  label face1 = addressing[i];
1098  bool flip1 = flipMap[i];
1099 
1100  label allFaceI = from1ToAllFaces[face1];
1101  if (allFaceI != -1)
1102  {
1103  // Check if orientation same
1104  label allCell1 = from1ToAllCells[owner1[face1]];
1105  if (allOwner[allFaceI] != allCell1)
1106  {
1107  flip1 = !flip1;
1108  }
1109 
1110  if (faceToZone[allFaceI] == -1)
1111  {
1112  faceToZone[allFaceI] = allZoneI;
1113  faceToFlip[allFaceI] = flip1;
1114  }
1115  else if (faceToZone[allFaceI] != allZoneI)
1116  {
1117  labelList& fZones = addFaceToZones[allFaceI];
1118  boolList& flipZones = addFaceToFlips[allFaceI];
1119 
1120  if (findIndex(fZones, allZoneI) == -1)
1121  {
1122  fZones.append(allZoneI);
1123  flipZones.append(flip1);
1124  }
1125  }
1126  }
1127  }
1128  }
1129 
1130 
1131  // Extract back into zones
1132 
1133  // 1. Count
1134  labelList nFaces(zoneNames.size(), 0);
1135  forAll(faceToZone, allFaceI)
1136  {
1137  label zoneI = faceToZone[allFaceI];
1138  if (zoneI != -1)
1139  {
1140  nFaces[zoneI]++;
1141  }
1142  }
1143  forAll(addFaceToZones, allFaceI)
1144  {
1145  const labelList& fZones = addFaceToZones[allFaceI];
1146  forAll(fZones, i)
1147  {
1148  nFaces[fZones[i]]++;
1149  }
1150  }
1151 
1152  // 2. Fill
1153  fzFaces.setSize(zoneNames.size());
1154  fzFlips.setSize(zoneNames.size());
1155  forAll(fzFaces, zoneI)
1156  {
1157  fzFaces[zoneI].setCapacity(nFaces[zoneI]);
1158  fzFlips[zoneI].setCapacity(nFaces[zoneI]);
1159  }
1160  forAll(faceToZone, allFaceI)
1161  {
1162  label zoneI = faceToZone[allFaceI];
1163  bool flip = faceToFlip[allFaceI];
1164  if (zoneI != -1)
1165  {
1166  fzFaces[zoneI].append(allFaceI);
1167  fzFlips[zoneI].append(flip);
1168  }
1169  }
1170  forAll(addFaceToZones, allFaceI)
1171  {
1172  const labelList& fZones = addFaceToZones[allFaceI];
1173  const boolList& flipZones = addFaceToFlips[allFaceI];
1174 
1175  forAll(fZones, i)
1176  {
1177  label zoneI = fZones[i];
1178  fzFaces[zoneI].append(allFaceI);
1179  fzFlips[zoneI].append(flipZones[i]);
1180  }
1181  }
1182 
1183  forAll(fzFaces, i)
1184  {
1185  fzFaces[i].shrink();
1186  fzFlips[i].shrink();
1187 
1188  labelList order;
1189  sortedOrder(fzFaces[i], order);
1190  fzFaces[i] = UIndirectList<label>(fzFaces[i], order)();
1191  fzFlips[i] = UIndirectList<bool>(fzFlips[i], order)();
1192  }
1193 }
1194 
1195 
1196 void Foam::polyMeshAdder::mergeCellZones
1197 (
1198  const label nAllCells,
1199 
1200  const cellZoneMesh& cz0,
1201  const cellZoneMesh& cz1,
1202  const labelList& from1ToAllCells,
1203 
1204  DynamicList<word>& zoneNames,
1205  labelList& from1ToAll,
1206  List<DynamicList<label> >& czCells
1207 )
1208 {
1209  zoneNames.setCapacity(cz0.size() + cz1.size());
1210  zoneNames.append(cz0.names());
1211 
1212  from1ToAll.setSize(cz1.size());
1213  forAll(cz1, zoneI)
1214  {
1215  from1ToAll[zoneI] = zoneIndex(cz1[zoneI].name(), zoneNames);
1216  }
1217  zoneNames.shrink();
1218 
1219 
1220  // Zone(s) per cell. Two levels: if only one zone
1221  // stored in cellToZone. Any extra stored in additionalCellToZones.
1222  // This is so we only allocate labelLists per cell if absolutely
1223  // necesary.
1224  labelList cellToZone(nAllCells, -1);
1225  labelListList addCellToZones(nAllCells);
1226 
1227  // mesh0 zones kept
1228  forAll(cz0, zoneI)
1229  {
1230  const cellZone& cz = cz0[zoneI];
1231  forAll(cz, i)
1232  {
1233  label cell0 = cz[i];
1234 
1235  if (cellToZone[cell0] == -1)
1236  {
1237  cellToZone[cell0] = zoneI;
1238  }
1239  else if (cellToZone[cell0] != zoneI)
1240  {
1241  labelList& cZones = addCellToZones[cell0];
1242  if (findIndex(cZones, zoneI) == -1)
1243  {
1244  cZones.append(zoneI);
1245  }
1246  }
1247  }
1248  }
1249 
1250  // mesh1 zones renumbered
1251  forAll(cz1, zoneI)
1252  {
1253  const cellZone& cz = cz1[zoneI];
1254  const label allZoneI = from1ToAll[zoneI];
1255  forAll(cz, i)
1256  {
1257  label cell1 = cz[i];
1258  label allCellI = from1ToAllCells[cell1];
1259 
1260  if (cellToZone[allCellI] == -1)
1261  {
1262  cellToZone[allCellI] = allZoneI;
1263  }
1264  else if (cellToZone[allCellI] != allZoneI)
1265  {
1266  labelList& cZones = addCellToZones[allCellI];
1267  if (findIndex(cZones, allZoneI) == -1)
1268  {
1269  cZones.append(allZoneI);
1270  }
1271  }
1272  }
1273  }
1274 
1275  // Extract back into zones
1276 
1277  // 1. Count
1278  labelList nCells(zoneNames.size(), 0);
1279  forAll(cellToZone, allCellI)
1280  {
1281  label zoneI = cellToZone[allCellI];
1282  if (zoneI != -1)
1283  {
1284  nCells[zoneI]++;
1285  }
1286  }
1287  forAll(addCellToZones, allCellI)
1288  {
1289  const labelList& cZones = addCellToZones[allCellI];
1290  forAll(cZones, i)
1291  {
1292  nCells[cZones[i]]++;
1293  }
1294  }
1295 
1296  // 2. Fill
1297  czCells.setSize(zoneNames.size());
1298  forAll(czCells, zoneI)
1299  {
1300  czCells[zoneI].setCapacity(nCells[zoneI]);
1301  }
1302  forAll(cellToZone, allCellI)
1303  {
1304  label zoneI = cellToZone[allCellI];
1305  if (zoneI != -1)
1306  {
1307  czCells[zoneI].append(allCellI);
1308  }
1309  }
1310  forAll(addCellToZones, allCellI)
1311  {
1312  const labelList& cZones = addCellToZones[allCellI];
1313  forAll(cZones, i)
1314  {
1315  czCells[cZones[i]].append(allCellI);
1316  }
1317  }
1318  forAll(czCells, i)
1319  {
1320  czCells[i].shrink();
1321  stableSort(czCells[i]);
1322  }
1323 }
1324 
1325 
1326 void Foam::polyMeshAdder::mergeZones
1327 (
1328  const label nAllPoints,
1329  const labelList& allOwner,
1330  const label nAllCells,
1331 
1332  const polyMesh& mesh0,
1333  const polyMesh& mesh1,
1334  const labelList& from0ToAllPoints,
1335  const labelList& from0ToAllFaces,
1336 
1337  const labelList& from1ToAllPoints,
1338  const labelList& from1ToAllFaces,
1339  const labelList& from1ToAllCells,
1340 
1341  DynamicList<word>& pointZoneNames,
1342  List<DynamicList<label> >& pzPoints,
1343 
1344  DynamicList<word>& faceZoneNames,
1345  List<DynamicList<label> >& fzFaces,
1346  List<DynamicList<bool> >& fzFlips,
1347 
1348  DynamicList<word>& cellZoneNames,
1349  List<DynamicList<label> >& czCells
1350 )
1351 {
1352  labelList from1ToAllPZones;
1353  mergePointZones
1354  (
1355  nAllPoints,
1356  mesh0.pointZones(),
1357  mesh1.pointZones(),
1358  from0ToAllPoints,
1359  from1ToAllPoints,
1360 
1361  pointZoneNames,
1362  from1ToAllPZones,
1363  pzPoints
1364  );
1365 
1366  labelList from1ToAllFZones;
1367  mergeFaceZones
1368  (
1369  allOwner,
1370  mesh0,
1371  mesh1,
1372  from0ToAllFaces,
1373  from1ToAllFaces,
1374  from1ToAllCells,
1375 
1376  faceZoneNames,
1377  from1ToAllFZones,
1378  fzFaces,
1379  fzFlips
1380  );
1381 
1382  labelList from1ToAllCZones;
1383  mergeCellZones
1384  (
1385  nAllCells,
1386  mesh0.cellZones(),
1387  mesh1.cellZones(),
1388  from1ToAllCells,
1389 
1390  cellZoneNames,
1391  from1ToAllCZones,
1392  czCells
1393  );
1394 }
1395 
1396 
1397 void Foam::polyMeshAdder::addZones
1398 (
1399  const DynamicList<word>& pointZoneNames,
1400  const List<DynamicList<label> >& pzPoints,
1401 
1402  const DynamicList<word>& faceZoneNames,
1403  const List<DynamicList<label> >& fzFaces,
1404  const List<DynamicList<bool> >& fzFlips,
1405 
1406  const DynamicList<word>& cellZoneNames,
1407  const List<DynamicList<label> >& czCells,
1408 
1409  polyMesh& mesh
1410 )
1411 {
1412  List<pointZone*> pZones(pzPoints.size());
1413  forAll(pZones, i)
1414  {
1415  pZones[i] = new pointZone
1416  (
1417  pointZoneNames[i],
1418  pzPoints[i],
1419  i,
1420  mesh.pointZones()
1421  );
1422  }
1423 
1424  List<faceZone*> fZones(fzFaces.size());
1425  forAll(fZones, i)
1426  {
1427  fZones[i] = new faceZone
1428  (
1429  faceZoneNames[i],
1430  fzFaces[i],
1431  fzFlips[i],
1432  i,
1433  mesh.faceZones()
1434  );
1435  }
1436 
1437  List<cellZone*> cZones(czCells.size());
1438  forAll(cZones, i)
1439  {
1440  cZones[i] = new cellZone
1441  (
1442  cellZoneNames[i],
1443  czCells[i],
1444  i,
1445  mesh.cellZones()
1446  );
1447  }
1448 
1449  mesh.addZones
1450  (
1451  pZones,
1452  fZones,
1453  cZones
1454  );
1455 }
1456 
1457 
1458 
1459 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
1460 
1461 // Returns new mesh and sets
1462 // - map from new cell/face/point/patch to either mesh0 or mesh1
1463 //
1464 // mesh0Faces/mesh1Faces: corresponding faces on both meshes.
1467  const IOobject& io,
1468  const polyMesh& mesh0,
1469  const polyMesh& mesh1,
1470  const faceCoupleInfo& coupleInfo,
1472 )
1473 {
1474  const polyBoundaryMesh& patches0 = mesh0.boundaryMesh();
1475  const polyBoundaryMesh& patches1 = mesh1.boundaryMesh();
1476 
1477 
1478  DynamicList<word> allPatchNames(patches0.size() + patches1.size());
1479  DynamicList<word> allPatchTypes(allPatchNames.size());
1480 
1481  // Patch maps
1482  labelList from1ToAllPatches(patches1.size());
1483  labelList fromAllTo1Patches(allPatchNames.size(), -1);
1484 
1485  mergePatchNames
1486  (
1487  patches0,
1488  patches1,
1489  allPatchNames,
1490  allPatchTypes,
1491  from1ToAllPatches,
1492  fromAllTo1Patches
1493  );
1494 
1495 
1496  // New points
1498 
1499  // Map from mesh0/1 points to allPoints.
1500  labelList from0ToAllPoints(mesh0.nPoints(), -1);
1501  labelList from1ToAllPoints(mesh1.nPoints(), -1);
1502 
1503  // New faces
1504  faceList allFaces;
1505  label nInternalFaces;
1506 
1507  // New cells
1508  labelList allOwner;
1509  labelList allNeighbour;
1510  label nCells;
1511 
1512  // Sizes per patch
1513  labelList nFaces(allPatchNames.size(), 0);
1514 
1515  // Maps
1516  labelList from0ToAllFaces(mesh0.nFaces(), -1);
1517  labelList from1ToAllFaces(mesh1.nFaces(), -1);
1518 
1519  // Map
1520  labelList from1ToAllCells(mesh1.nCells(), -1);
1521 
1522  mergePrimitives
1523  (
1524  mesh0,
1525  mesh1,
1526  coupleInfo,
1527 
1528  allPatchNames.size(),
1529  fromAllTo1Patches,
1530  from1ToAllPatches,
1531 
1532  allPoints,
1533  from0ToAllPoints,
1534  from1ToAllPoints,
1535 
1536  allFaces,
1537  allOwner,
1538  allNeighbour,
1539  nInternalFaces,
1540  nFaces,
1541  nCells,
1542 
1543  from0ToAllFaces,
1544  from1ToAllFaces,
1545  from1ToAllCells
1546  );
1547 
1548 
1549  // Zones
1550  // ~~~~~
1551 
1552  DynamicList<word> pointZoneNames;
1553  List<DynamicList<label> > pzPoints;
1554 
1555  DynamicList<word> faceZoneNames;
1556  List<DynamicList<label> > fzFaces;
1557  List<DynamicList<bool> > fzFlips;
1558 
1559  DynamicList<word> cellZoneNames;
1560  List<DynamicList<label> > czCells;
1561 
1562  mergeZones
1563  (
1564  allPoints.size(),
1565  allOwner,
1566  nCells,
1567 
1568  mesh0,
1569  mesh1,
1570 
1571  from0ToAllPoints,
1572  from0ToAllFaces,
1573 
1574  from1ToAllPoints,
1575  from1ToAllFaces,
1576  from1ToAllCells,
1577 
1578  pointZoneNames,
1579  pzPoints,
1580 
1581  faceZoneNames,
1582  fzFaces,
1583  fzFlips,
1584 
1585  cellZoneNames,
1586  czCells
1587  );
1588 
1589 
1590  // Patches
1591  // ~~~~~~~
1592 
1593  // Map from 0 to all patches (since gets compacted)
1594  labelList from0ToAllPatches(patches0.size(), -1);
1595 
1596  List<polyPatch*> allPatches
1597  (
1598  combinePatches
1599  (
1600  mesh0,
1601  mesh1,
1602  patches0, // Should be boundaryMesh() on new mesh.
1603  allPatchNames.size(),
1604  fromAllTo1Patches,
1605  mesh0.nInternalFaces()
1606  + mesh1.nInternalFaces()
1607  + coupleInfo.cutFaces().size(),
1608  nFaces,
1609 
1610  from0ToAllPatches,
1611  from1ToAllPatches
1612  )
1613  );
1614 
1615 
1616  // Map information
1617  // ~~~~~~~~~~~~~~~
1618 
1619  mapPtr.reset
1620  (
1621  new mapAddedPolyMesh
1622  (
1623  mesh0.nPoints(),
1624  mesh0.nFaces(),
1625  mesh0.nCells(),
1626 
1627  mesh1.nPoints(),
1628  mesh1.nFaces(),
1629  mesh1.nCells(),
1630 
1631  from0ToAllPoints,
1632  from0ToAllFaces,
1633  identity(mesh0.nCells()),
1634 
1635  from1ToAllPoints,
1636  from1ToAllFaces,
1637  from1ToAllCells,
1638 
1639  from0ToAllPatches,
1640  from1ToAllPatches,
1641  getPatchSizes(patches0),
1642  getPatchStarts(patches0)
1643  )
1644  );
1645 
1646 
1647 
1648  // Now we have extracted all information from all meshes.
1649  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1650 
1651  // Construct mesh
1652  autoPtr<polyMesh> tmesh
1653  (
1654  new polyMesh
1655  (
1656  io,
1657  xferMove(allPoints),
1658  xferMove(allFaces),
1659  xferMove(allOwner),
1660  xferMove(allNeighbour)
1661  )
1662  );
1663  polyMesh& mesh = tmesh();
1664 
1665  // Add zones to new mesh.
1666  addZones
1667  (
1668  pointZoneNames,
1669  pzPoints,
1670 
1671  faceZoneNames,
1672  fzFaces,
1673  fzFlips,
1674 
1675  cellZoneNames,
1676  czCells,
1677  mesh
1678  );
1679 
1680  // Add patches to new mesh
1681  mesh.addPatches(allPatches);
1682 
1683  return tmesh;
1684 }
1685 
1686 
1687 // Inplace add mesh1 to mesh0
1690  polyMesh& mesh0,
1691  const polyMesh& mesh1,
1692  const faceCoupleInfo& coupleInfo,
1693  const bool validBoundary
1694 )
1695 {
1696  const polyBoundaryMesh& patches0 = mesh0.boundaryMesh();
1697  const polyBoundaryMesh& patches1 = mesh1.boundaryMesh();
1698 
1699  DynamicList<word> allPatchNames(patches0.size() + patches1.size());
1700  DynamicList<word> allPatchTypes(allPatchNames.size());
1701 
1702  // Patch maps
1703  labelList from1ToAllPatches(patches1.size());
1704  labelList fromAllTo1Patches(allPatchNames.size(), -1);
1705 
1706  mergePatchNames
1707  (
1708  patches0,
1709  patches1,
1710  allPatchNames,
1711  allPatchTypes,
1712  from1ToAllPatches,
1713  fromAllTo1Patches
1714  );
1715 
1716 
1717  // New points
1719 
1720  // Map from mesh0/1 points to allPoints.
1721  labelList from0ToAllPoints(mesh0.nPoints(), -1);
1722  labelList from1ToAllPoints(mesh1.nPoints(), -1);
1723 
1724  // New faces
1725  faceList allFaces;
1726  labelList allOwner;
1727  labelList allNeighbour;
1728  label nInternalFaces;
1729  // Sizes per patch
1730  labelList nFaces(allPatchNames.size(), 0);
1731  label nCells;
1732 
1733  // Maps
1734  labelList from0ToAllFaces(mesh0.nFaces(), -1);
1735  labelList from1ToAllFaces(mesh1.nFaces(), -1);
1736  // Map
1737  labelList from1ToAllCells(mesh1.nCells(), -1);
1738 
1739  mergePrimitives
1740  (
1741  mesh0,
1742  mesh1,
1743  coupleInfo,
1744 
1745  allPatchNames.size(),
1746  fromAllTo1Patches,
1747  from1ToAllPatches,
1748 
1749  allPoints,
1750  from0ToAllPoints,
1751  from1ToAllPoints,
1752 
1753  allFaces,
1754  allOwner,
1755  allNeighbour,
1756  nInternalFaces,
1757  nFaces,
1758  nCells,
1759 
1760  from0ToAllFaces,
1761  from1ToAllFaces,
1762  from1ToAllCells
1763  );
1764 
1765 
1766  // Zones
1767  // ~~~~~
1768 
1769  DynamicList<word> pointZoneNames;
1770  List<DynamicList<label> > pzPoints;
1771 
1772  DynamicList<word> faceZoneNames;
1773  List<DynamicList<label> > fzFaces;
1774  List<DynamicList<bool> > fzFlips;
1775 
1776  DynamicList<word> cellZoneNames;
1777  List<DynamicList<label> > czCells;
1778 
1779  mergeZones
1780  (
1781  allPoints.size(),
1782  allOwner,
1783  nCells,
1784 
1785  mesh0,
1786  mesh1,
1787 
1788  from0ToAllPoints,
1789  from0ToAllFaces,
1790 
1791  from1ToAllPoints,
1792  from1ToAllFaces,
1793  from1ToAllCells,
1794 
1795  pointZoneNames,
1796  pzPoints,
1797 
1798  faceZoneNames,
1799  fzFaces,
1800  fzFlips,
1801 
1802  cellZoneNames,
1803  czCells
1804  );
1805 
1806 
1807  // Patches
1808  // ~~~~~~~
1809 
1810 
1811  // Store mesh0 patch info before modifying patches0.
1812  labelList mesh0PatchSizes(getPatchSizes(patches0));
1813  labelList mesh0PatchStarts(getPatchStarts(patches0));
1814 
1815  // Map from 0 to all patches (since gets compacted)
1816  labelList from0ToAllPatches(patches0.size(), -1);
1817 
1818  // Inplace extend mesh0 patches (note that patches0.size() now also
1819  // has changed)
1820  polyBoundaryMesh& allPatches =
1821  const_cast<polyBoundaryMesh&>(mesh0.boundaryMesh());
1822  allPatches.setSize(allPatchNames.size());
1823  labelList patchSizes(allPatches.size());
1824  labelList patchStarts(allPatches.size());
1825 
1826  label startFaceI = nInternalFaces;
1827 
1828  // Copy patches0 with new sizes. First patches always come from
1829  // mesh0 and will always be present.
1830  label allPatchI = 0;
1831 
1832  forAll(from0ToAllPatches, patch0)
1833  {
1834  // Originates from mesh0. Clone with new size & filter out empty
1835  // patch.
1836 
1837  if (nFaces[patch0] == 0 && isA<processorPolyPatch>(allPatches[patch0]))
1838  {
1839  //Pout<< "Removing zero sized mesh0 patch " << allPatchNames[patch0]
1840  // << endl;
1841  from0ToAllPatches[patch0] = -1;
1842  // Check if patch was also in mesh1 and update its addressing if so.
1843  if (fromAllTo1Patches[patch0] != -1)
1844  {
1845  from1ToAllPatches[fromAllTo1Patches[patch0]] = -1;
1846  }
1847  }
1848  else
1849  {
1850  // Clone. Note dummy size and start. Gets overwritten later in
1851  // resetPrimitives. This avoids getting temporarily illegal
1852  // SubList construction in polyPatch.
1853  allPatches.set
1854  (
1855  allPatchI,
1856  allPatches[patch0].clone
1857  (
1858  allPatches,
1859  allPatchI,
1860  0, // dummy size
1861  0 // dummy start
1862  )
1863  );
1864  patchSizes[allPatchI] = nFaces[patch0];
1865  patchStarts[allPatchI] = startFaceI;
1866 
1867  // Record new index in allPatches
1868  from0ToAllPatches[patch0] = allPatchI;
1869 
1870  // Check if patch was also in mesh1 and update its addressing if so.
1871  if (fromAllTo1Patches[patch0] != -1)
1872  {
1873  from1ToAllPatches[fromAllTo1Patches[patch0]] = allPatchI;
1874  }
1875 
1876  startFaceI += nFaces[patch0];
1877 
1878  allPatchI++;
1879  }
1880  }
1881 
1882  // Copy unique patches of mesh1.
1883  forAll(from1ToAllPatches, patch1)
1884  {
1885  label uncompactAllPatchI = from1ToAllPatches[patch1];
1886 
1887  if (uncompactAllPatchI >= from0ToAllPatches.size())
1888  {
1889  // Patch has not been merged with any mesh0 patch.
1890 
1891  if
1892  (
1893  nFaces[uncompactAllPatchI] == 0
1894  && isA<processorPolyPatch>(patches1[patch1])
1895  )
1896  {
1897  //Pout<< "Removing zero sized mesh1 patch "
1898  // << allPatchNames[uncompactAllPatchI] << endl;
1899  from1ToAllPatches[patch1] = -1;
1900  }
1901  else
1902  {
1903  // Clone.
1904  allPatches.set
1905  (
1906  allPatchI,
1907  patches1[patch1].clone
1908  (
1909  allPatches,
1910  allPatchI,
1911  0, // dummy size
1912  0 // dummy start
1913  )
1914  );
1915  patchSizes[allPatchI] = nFaces[uncompactAllPatchI];
1916  patchStarts[allPatchI] = startFaceI;
1917 
1918  // Record new index in allPatches
1919  from1ToAllPatches[patch1] = allPatchI;
1920 
1921  startFaceI += nFaces[uncompactAllPatchI];
1922 
1923  allPatchI++;
1924  }
1925  }
1926  }
1927 
1928  allPatches.setSize(allPatchI);
1929  patchSizes.setSize(allPatchI);
1930  patchStarts.setSize(allPatchI);
1931 
1932 
1933  // Construct map information before changing mesh0 primitives
1934  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1935 
1937  (
1938  new mapAddedPolyMesh
1939  (
1940  mesh0.nPoints(),
1941  mesh0.nFaces(),
1942  mesh0.nCells(),
1943 
1944  mesh1.nPoints(),
1945  mesh1.nFaces(),
1946  mesh1.nCells(),
1947 
1948  from0ToAllPoints,
1949  from0ToAllFaces,
1950  identity(mesh0.nCells()),
1951 
1952  from1ToAllPoints,
1953  from1ToAllFaces,
1954  from1ToAllCells,
1955 
1956  from0ToAllPatches,
1957  from1ToAllPatches,
1958 
1959  mesh0PatchSizes,
1960  mesh0PatchStarts
1961  )
1962  );
1963 
1964 
1965 
1966  // Now we have extracted all information from all meshes.
1967  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1968 
1969  mesh0.resetMotion(); // delete any oldPoints.
1970  mesh0.resetPrimitives
1971  (
1972  xferMove(allPoints),
1973  xferMove(allFaces),
1974  xferMove(allOwner),
1975  xferMove(allNeighbour),
1976  patchSizes, // size
1977  patchStarts, // patchstarts
1978  validBoundary // boundary valid?
1979  );
1980 
1981  // Add zones to new mesh.
1982  mesh0.pointZones().clear();
1983  mesh0.faceZones().clear();
1984  mesh0.cellZones().clear();
1985  addZones
1986  (
1987  pointZoneNames,
1988  pzPoints,
1989 
1990  faceZoneNames,
1991  fzFaces,
1992  fzFlips,
1993 
1994  cellZoneNames,
1995  czCells,
1996  mesh0
1997  );
1998 
1999  return mapPtr;
2000 }
2001 
2002 
2005  const polyMesh& mesh,
2006  const scalar mergeDist
2007 )
2008 {
2009  const labelList& sharedPointLabels = mesh.globalData().sharedPointLabels();
2010  const labelList& sharedPointAddr = mesh.globalData().sharedPointAddr();
2011 
2012  // Because of adding the missing pieces e.g. when redistributing a mesh
2013  // it can be that there are multiple points on the same processor that
2014  // refer to the same shared point.
2015 
2016  // Invert point-to-shared addressing
2017  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2018 
2019  Map<labelList> sharedToMesh(sharedPointLabels.size());
2020 
2021  label nMultiple = 0;
2022 
2023  forAll(sharedPointLabels, i)
2024  {
2025  label pointI = sharedPointLabels[i];
2026 
2027  label sharedI = sharedPointAddr[i];
2028 
2029  Map<labelList>::iterator iter = sharedToMesh.find(sharedI);
2030 
2031  if (iter != sharedToMesh.end())
2032  {
2033  // sharedI already used by other point. Add this one.
2034 
2035  nMultiple++;
2036 
2037  labelList& connectedPointLabels = iter();
2038 
2039  label sz = connectedPointLabels.size();
2040 
2041  // Check just to make sure.
2042  if (findIndex(connectedPointLabels, pointI) != -1)
2043  {
2044  FatalErrorIn("polyMeshAdder::findSharedPoints(..)")
2045  << "Duplicate point in sharedPoint addressing." << endl
2046  << "When trying to add point " << pointI << " on shared "
2047  << sharedI << " with connected points "
2048  << connectedPointLabels
2049  << abort(FatalError);
2050  }
2051 
2052  connectedPointLabels.setSize(sz+1);
2053  connectedPointLabels[sz] = pointI;
2054  }
2055  else
2056  {
2057  sharedToMesh.insert(sharedI, labelList(1, pointI));
2058  }
2059  }
2060 
2061 
2062  // Assign single master for every shared with multiple geometric points
2063  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2064 
2065  Map<label> pointToMaster(nMultiple);
2066 
2067  forAllConstIter(Map<labelList>, sharedToMesh, iter)
2068  {
2069  const labelList& connectedPointLabels = iter();
2070 
2071  //Pout<< "For shared:" << iter.key()
2072  // << " found points:" << connectedPointLabels
2073  // << " at coords:"
2074  // << pointField(mesh.points(), connectedPointLabels) << endl;
2075 
2076  if (connectedPointLabels.size() > 1)
2077  {
2078  const pointField connectedPoints
2079  (
2080  mesh.points(),
2081  connectedPointLabels
2082  );
2083 
2084  labelList toMergedPoints;
2085  label nUnique = Foam::mergePoints
2086  (
2087  connectedPoints,
2088  mergeDist,
2089  false,
2090  toMergedPoints
2091  );
2092 
2093  if (nUnique < connectedPoints.size())
2094  {
2095  // Invert toMergedPoints
2096  const labelListList mergeSets
2097  (
2099  (
2100  nUnique,
2101  toMergedPoints
2102  )
2103  );
2104 
2105  // Find master for valid merges
2106  forAll(mergeSets, setI)
2107  {
2108  const labelList& mergeSet = mergeSets[setI];
2109 
2110  if (mergeSet.size() > 1)
2111  {
2112  // Pick lowest numbered point
2113  label masterPointI = labelMax;
2114 
2115  forAll(mergeSet, i)
2116  {
2117  label pointI = connectedPointLabels[mergeSet[i]];
2118 
2119  masterPointI = min(masterPointI, pointI);
2120  }
2121 
2122  forAll(mergeSet, i)
2123  {
2124  label pointI = connectedPointLabels[mergeSet[i]];
2125 
2126  //Pout<< "Merging point " << pointI
2127  // << " at " << mesh.points()[pointI]
2128  // << " into master point "
2129  // << masterPointI
2130  // << " at " << mesh.points()[masterPointI]
2131  // << endl;
2132 
2133  pointToMaster.insert(pointI, masterPointI);
2134  }
2135  }
2136  }
2137  }
2138  }
2139  }
2140 
2141  //- Old: geometric merging. Causes problems for two close shared points.
2142  //labelList sharedToMerged;
2143  //label nUnique = Foam::mergePoints
2144  //(
2145  // pointField
2146  // (
2147  // mesh.points(),
2148  // sharedPointLabels
2149  // ),
2150  // mergeDist,
2151  // false,
2152  // sharedToMerged
2153  //);
2154  //
2157  //
2158  //Map<label> pointToMaster(10*sharedToMerged.size());
2159  //
2160  //if (nUnique < sharedPointLabels.size())
2161  //{
2162  // labelListList mergeSets
2163  // (
2164  // invertOneToMany
2165  // (
2166  // sharedToMerged.size(),
2167  // sharedToMerged
2168  // )
2169  // );
2170  //
2171  // label nMergeSets = 0;
2172  //
2173  // forAll(mergeSets, setI)
2174  // {
2175  // const labelList& mergeSet = mergeSets[setI];
2176  //
2177  // if (mergeSet.size() > 1)
2178  // {
2179  // // Take as master the shared point with the lowest mesh
2180  // // point label. (rather arbitrarily - could use max or
2181  // // any other one of the points)
2182  //
2183  // nMergeSets++;
2184  //
2185  // label masterI = labelMax;
2186  //
2187  // forAll(mergeSet, i)
2188  // {
2189  // label sharedI = mergeSet[i];
2190  //
2191  // masterI = min(masterI, sharedPointLabels[sharedI]);
2192  // }
2193  //
2194  // forAll(mergeSet, i)
2195  // {
2196  // label sharedI = mergeSet[i];
2197  //
2198  // pointToMaster.insert(sharedPointLabels[sharedI], masterI);
2199  // }
2200  // }
2201  // }
2202  //
2203  // //if (debug)
2204  // //{
2205  // // Pout<< "polyMeshAdder : merging:"
2206  // // << pointToMaster.size() << " into " << nMergeSets
2207  // // << " sets." << endl;
2208  // //}
2209  //}
2210 
2211  return pointToMaster;
2212 }
2213 
2214 
2217  const polyMesh& mesh,
2218  const Map<label>& pointToMaster,
2219  polyTopoChange& meshMod
2220 )
2221 {
2222  // Remove all non-master points.
2223  forAll(mesh.points(), pointI)
2224  {
2225  Map<label>::const_iterator iter = pointToMaster.find(pointI);
2226 
2227  if (iter != pointToMaster.end())
2228  {
2229  if (iter() != pointI)
2230  {
2231  meshMod.removePoint(pointI, iter());
2232  }
2233  }
2234  }
2235 
2236  // Modify faces for points. Note: could use pointFaces here but want to
2237  // avoid addressing calculation.
2238  const faceList& faces = mesh.faces();
2239 
2240  forAll(faces, faceI)
2241  {
2242  const face& f = faces[faceI];
2243 
2244  bool hasMerged = false;
2245 
2246  forAll(f, fp)
2247  {
2248  label pointI = f[fp];
2249 
2250  Map<label>::const_iterator iter = pointToMaster.find(pointI);
2251 
2252  if (iter != pointToMaster.end())
2253  {
2254  if (iter() != pointI)
2255  {
2256  hasMerged = true;
2257  break;
2258  }
2259  }
2260  }
2261 
2262  if (hasMerged)
2263  {
2264  face newF(f);
2265 
2266  forAll(f, fp)
2267  {
2268  label pointI = f[fp];
2269 
2270  Map<label>::const_iterator iter = pointToMaster.find(pointI);
2271 
2272  if (iter != pointToMaster.end())
2273  {
2274  newF[fp] = iter();
2275  }
2276  }
2277 
2278  label patchID = mesh.boundaryMesh().whichPatch(faceI);
2279  label nei = (patchID == -1 ? mesh.faceNeighbour()[faceI] : -1);
2280  label zoneID = mesh.faceZones().whichZone(faceI);
2281  bool zoneFlip = false;
2282 
2283  if (zoneID >= 0)
2284  {
2285  const faceZone& fZone = mesh.faceZones()[zoneID];
2286  zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
2287  }
2288 
2289  meshMod.setAction
2290  (
2292  (
2293  newF, // modified face
2294  faceI, // label of face
2295  mesh.faceOwner()[faceI], // owner
2296  nei, // neighbour
2297  false, // face flip
2298  patchID, // patch for face
2299  false, // remove from zone
2300  zoneID, // zone for face
2301  zoneFlip // face flip in zone
2302  )
2303  );
2304  }
2305  }
2306 }
2307 
2308 
2309 // ************************************************************************* //
const boolList & flipMap() const
Return face flip map.
Definition: faceZone.H:249
label setAction(const topoAction &action)
For compatibility with polyTopoChange: set topological action.
const faceZoneMesh & faceZones() const
Return face zone mesh.
Definition: polyMesh.H:463
void setSize(const label)
Reset size of PtrList. If extending the PtrList, new entries are.
Definition: PtrList.C:142
ZoneMesh< cellZone, polyMesh > cellZoneMesh
A ZoneMesh with the type cellZone.
label size() const
Return the number of elements in the PtrList.
Definition: PtrListI.H:32
label nFaces() const
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
label whichZone(const label objectIndex) const
Given a global object index, return the zone it is in.
Definition: ZoneMesh.C:232
void clear()
Delete object (if the pointer is valid) and set pointer to NULL.
Definition: autoPtrI.H:126
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
labelList f(nPoints)
Merge points. See below.
labelListList invertOneToMany(const label len, const labelUList &)
Invert one-to-many map. Unmapped elements will be size 0.
Definition: ListOps.C:67
void reset(T *=0)
If object pointer already set, delete object and set to given.
Definition: autoPtrI.H:114
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
An STL-conforming iterator.
Definition: HashTable.H:415
void inplaceReorder(const labelUList &oldToNew, ListType &)
Inplace reorder the elements of a list.
const labelList & sharedPointLabels() const
Return indices of local points that are globally shared.
List< List< bool > > boolListList
Definition: boolList.H:51
void sortedOrder(const UList< T > &, labelList &order)
Generate the (stable) sort order for the list.
A HashTable to objects of type <T> with a label key.
Definition: Map.H:49
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:64
static void mergePoints(const polyMesh &, const Map< label > &pointToMaster, polyTopoChange &meshMod)
Helper: Merge points.
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
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
label nCells() const
friend class const_iterator
Declare friendship with the const_iterator.
Definition: HashTable.H:192
PrimitivePatch< face, IndirectList, const pointField & > indirectPrimitivePatch
Foam::indirectPrimitivePatch.
List< face > faceList
Definition: faceListFwd.H:43
PrimitivePatch< face, List, const pointField & > primitiveFacePatch
Foam::primitiveFacePatch.
IOporosityModelList pZones(mesh)
Container for information needed to couple to meshes. When constructed from two meshes and a geometri...
Xfer< T > xferMove(T &)
void addPatches(const List< polyPatch * > &, const bool validBoundary=true)
Add boundary patches.
Definition: polyMesh.C:925
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
label whichFace(const label globalCellID) const
Helper function to re-direct to zone::localID(...)
Definition: faceZone.C:317
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
void setSize(const label)
Reset size of List.
Definition: List.C:318
List< cell > cellList
list of cells
Definition: cellList.H:42
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
static autoPtr< polyMesh > add(const IOobject &io, const polyMesh &mesh0, const polyMesh &mesh1, const faceCoupleInfo &coupleInfo, autoPtr< mapAddedPolyMesh > &mapPtr)
Add two polyMeshes. Returns new polyMesh and map construct.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1035
Foam::polyBoundaryMesh.
static Map< label > findSharedPoints(const polyMesh &, const scalar mergeTol)
Find topologically and geometrically shared points.
#define forAll(list, i)
Definition: UList.H:421
ListType renumber(const labelUList &oldToNew, const ListType &)
Renumber the values (not the indices) of a list.
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
Class describing modification of a face.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1073
ZoneMesh< pointZone, polyMesh > pointZoneMesh
A ZoneMesh with the type pointZone.
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:421
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
Definition: HashSet.H:210
tmp< pointField > allPoints(const Triangulation &t)
Extract all points in vertex-index order.
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.
HashTable< labelList, edge, Hash< edge > > edgeLookup
#define forAllReverse(list, i)
Definition: UList.H:424
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
error FatalError
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with the type faceZone.
List< label > labelList
A List of labels.
Definition: labelList.H:56
void stableSort(UList< T > &)
Definition: UList.C:121
Direct mesh changes based on v1.3 polyTopoChange syntax.
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:106
void removePoint(const label, const label)
Remove/merge point.
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:97
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1060
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
Definition: HashTable.C:139
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
label nPoints
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1079
HashTable< label, label, Hash< label > >::const_iterator const_iterator
Definition: Map.H:59
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117
void inplaceRenumber(const labelUList &oldToNew, ListType &)
Inplace renumber the values of a list.
label nPoints() const
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1200
const labelList & sharedPointAddr() const
Return addressing into the complete globally shared points.
prefixOSstream Pout(cout,"Pout")
Definition: IOstreams.H:53
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
static const label labelMax
Definition: label.H:62
Class containing mesh-to-mesh mapping information after a mesh addition where we add a mesh (&#39;added m...
const primitiveFacePatch & cutFaces() const
Addressing engine for combined set of faces.