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