fvMeshSubset.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
6  \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25  Post-processing mesh subset tool. Given the original mesh and the
26  list of selected cells, it creates the mesh consisting only of the
27  desired cells, with the mapping list for points, faces, and cells.
28 
29 \*---------------------------------------------------------------------------*/
30 
31 #include "fvMeshSubset.H"
32 #include "boolList.H"
33 #include "Pstream.H"
34 #include "emptyPolyPatch.H"
35 #include "demandDrivenData.H"
36 #include "cyclicPolyPatch.H"
37 #include "removeCells.H"
38 #include "polyTopoChange.H"
39 #include "mapPolyMesh.H"
40 
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45 
46 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
47 
49 {
50  if (fvMeshSubsetPtr_.empty())
51  {
53  << "void setCellSubset(const labelHashSet& cellsToSubset)" << endl
54  << "before attempting to access subset data"
55  << abort(FatalError);
56 
57  return false;
58  }
59  else
60  {
61  return true;
62  }
63 }
64 
65 
67 (
68  const labelList& curPoints,
69  Map<label>& pointMap
70 )
71 {
72  forAll(curPoints, pointI)
73  {
74  // Note: insert will only insert if not yet there.
75  pointMap.insert(curPoints[pointI], 0);
76  }
77 }
78 
79 
81 (
82  const labelList& curPoints,
83  labelList& pointMap
84 )
85 {
86  forAll(curPoints, pointI)
87  {
88  pointMap[curPoints[pointI]] = 0;
89  }
90 }
91 
92 
93 // Synchronize nCellsUsingFace on both sides of coupled patches. Marks
94 // faces that become 'uncoupled' with 3.
96 (
97  const bool syncPar,
98  labelList& nCellsUsingFace
99 ) const
100 {
101  const polyBoundaryMesh& oldPatches = baseMesh().boundaryMesh();
102 
103  label nUncoupled = 0;
104 
105  if (syncPar && Pstream::parRun())
106  {
108 
109  // Send face usage across processor patches
110  forAll(oldPatches, oldPatchI)
111  {
112  const polyPatch& pp = oldPatches[oldPatchI];
113 
114  if (isA<processorPolyPatch>(pp))
115  {
116  const processorPolyPatch& procPatch =
117  refCast<const processorPolyPatch>(pp);
118 
119  UOPstream toNeighbour(procPatch.neighbProcNo(), pBufs);
120 
121  toNeighbour
122  << SubList<label>(nCellsUsingFace, pp.size(), pp.start());
123  }
124  }
125 
126  pBufs.finishedSends();
127 
128  // Receive face usage count and check for faces that become uncoupled.
129  forAll(oldPatches, oldPatchI)
130  {
131  const polyPatch& pp = oldPatches[oldPatchI];
132 
133  if (isA<processorPolyPatch>(pp))
134  {
135  const processorPolyPatch& procPatch =
136  refCast<const processorPolyPatch>(pp);
137 
138  UIPstream fromNeighbour(procPatch.neighbProcNo(), pBufs);
139 
140  labelList nbrCellsUsingFace(fromNeighbour);
141 
142  // Combine with this side.
143 
144  forAll(pp, i)
145  {
146  if
147  (
148  nCellsUsingFace[pp.start()+i] == 1
149  && nbrCellsUsingFace[i] == 0
150  )
151  {
152  // Face's neighbour is no longer there. Mark face off
153  // as coupled
154  nCellsUsingFace[pp.start()+i] = 3;
155  nUncoupled++;
156  }
157  }
158  }
159  }
160  }
161 
162  // Do same for cyclics.
163  forAll(oldPatches, oldPatchI)
164  {
165  const polyPatch& pp = oldPatches[oldPatchI];
166 
167  if (isA<cyclicPolyPatch>(pp))
168  {
169  const cyclicPolyPatch& cycPatch =
170  refCast<const cyclicPolyPatch>(pp);
171 
172  forAll(cycPatch, i)
173  {
174  label thisFaceI = cycPatch.start() + i;
175  label otherFaceI = cycPatch.transformGlobalFace(thisFaceI);
176 
177  if
178  (
179  nCellsUsingFace[thisFaceI] == 1
180  && nCellsUsingFace[otherFaceI] == 0
181  )
182  {
183  nCellsUsingFace[thisFaceI] = 3;
184  nUncoupled++;
185  }
186  }
187  }
188  }
189 
190  if (syncPar)
191  {
192  reduce(nUncoupled, sumOp<label>());
193  }
194 
195  if (nUncoupled > 0)
196  {
197  Info<< "Uncoupled " << nUncoupled << " faces on coupled patches. "
198  << "(processorPolyPatch, cyclicPolyPatch)" << endl;
199  }
200 }
201 
202 
204 (
205  const label nElems,
206  const labelList& selectedElements,
207  const labelList& subsetMap
208 )
209 {
210  // Mark selected elements.
211  boolList selected(nElems, false);
212  forAll(selectedElements, i)
213  {
214  selected[selectedElements[i]] = true;
215  }
216 
217  // Count subset of selected elements
218  label n = 0;
219  forAll(subsetMap, i)
220  {
221  if (selected[subsetMap[i]])
222  {
223  n++;
224  }
225  }
226 
227  // Collect selected elements
228  labelList subsettedElements(n);
229  n = 0;
230 
231  forAll(subsetMap, i)
232  {
233  if (selected[subsetMap[i]])
234  {
235  subsettedElements[n++] = i;
236  }
237  }
238 
239  return subsettedElements;
240 }
241 
242 
244 {
245  // Keep all zones, even if zero size.
246 
247  const pointZoneMesh& pointZones = baseMesh().pointZones();
248 
249  // PointZones
250  List<pointZone*> pZonePtrs(pointZones.size());
251 
252  forAll(pointZones, i)
253  {
254  const pointZone& pz = pointZones[i];
255 
256  pZonePtrs[i] = new pointZone
257  (
258  pz.name(),
259  subset(baseMesh().nPoints(), pz, pointMap()),
260  i,
261  fvMeshSubsetPtr_().pointZones()
262  );
263  }
264 
265 
266  // FaceZones
267 
268  const faceZoneMesh& faceZones = baseMesh().faceZones();
269 
270 
271  // Do we need to remove zones where the side we're interested in
272  // no longer exists? Guess not.
273  List<faceZone*> fZonePtrs(faceZones.size());
274 
275  forAll(faceZones, i)
276  {
277  const faceZone& fz = faceZones[i];
278 
279  // Expand faceZone to full mesh
280  // +1 : part of faceZone, flipped
281  // -1 : ,, , unflipped
282  // 0 : not part of faceZone
283  labelList zone(baseMesh().nFaces(), 0);
284  forAll(fz, j)
285  {
286  if (fz.flipMap()[j])
287  {
288  zone[fz[j]] = 1;
289  }
290  else
291  {
292  zone[fz[j]] = -1;
293  }
294  }
295 
296  // Select faces
297  label nSub = 0;
298  forAll(faceMap(), j)
299  {
300  if (zone[faceMap()[j]] != 0)
301  {
302  nSub++;
303  }
304  }
305  labelList subAddressing(nSub);
306  boolList subFlipStatus(nSub);
307  nSub = 0;
308  forAll(faceMap(), subFaceI)
309  {
310  label meshFaceI = faceMap()[subFaceI];
311  if (zone[meshFaceI] != 0)
312  {
313  subAddressing[nSub] = subFaceI;
314  label subOwner = subMesh().faceOwner()[subFaceI];
315  label baseOwner = baseMesh().faceOwner()[meshFaceI];
316  // If subowner is the same cell as the base keep the flip status
317  bool sameOwner = (cellMap()[subOwner] == baseOwner);
318  bool flip = (zone[meshFaceI] == 1);
319  subFlipStatus[nSub] = (sameOwner == flip);
320 
321  nSub++;
322  }
323  }
324 
325  fZonePtrs[i] = new faceZone
326  (
327  fz.name(),
328  subAddressing,
329  subFlipStatus,
330  i,
331  fvMeshSubsetPtr_().faceZones()
332  );
333  }
334 
335 
336  const cellZoneMesh& cellZones = baseMesh().cellZones();
337 
338  List<cellZone*> cZonePtrs(cellZones.size());
339 
340  forAll(cellZones, i)
341  {
342  const cellZone& cz = cellZones[i];
343 
344  cZonePtrs[i] = new cellZone
345  (
346  cz.name(),
347  subset(baseMesh().nCells(), cz, cellMap()),
348  i,
349  fvMeshSubsetPtr_().cellZones()
350  );
351  }
352 
353 
354  // Add the zones
355  fvMeshSubsetPtr_().addZones(pZonePtrs, fZonePtrs, cZonePtrs);
356 }
357 
358 
360 (
361  const labelList& region,
362  const label currentRegion
363 ) const
364 {
365  // Count
366  label nKeep = 0;
367  forAll(region, cellI)
368  {
369  if (region[cellI] == currentRegion)
370  {
371  nKeep++;
372  }
373  }
374 
375  // Collect cells to remove
376  label nRemove = baseMesh().nCells() - nKeep;
377  labelList cellsToRemove(nRemove);
378 
379  nRemove = 0;
380  forAll(region, cellI)
381  {
382  if (region[cellI] != currentRegion)
383  {
384  cellsToRemove[nRemove++] = cellI;
385  }
386  }
387 
388  return cellsToRemove;
389 }
390 
391 
392 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
393 
394 // Construct from components
396 :
397  baseMesh_(baseMesh),
398  fvMeshSubsetPtr_(NULL),
399  pointMap_(0),
400  faceMap_(0),
401  cellMap_(0),
402  patchMap_(0),
403  faceFlipMapPtr_()
404 {}
405 
406 
407 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
408 
410 (
411  const labelHashSet& globalCellMap,
412  const label patchID
413 )
414 {
415  // Initial check on patches before doing anything time consuming.
416  const polyBoundaryMesh& oldPatches = baseMesh().boundaryMesh();
417  const cellList& oldCells = baseMesh().cells();
418  const faceList& oldFaces = baseMesh().faces();
419  const pointField& oldPoints = baseMesh().points();
420  const labelList& oldOwner = baseMesh().faceOwner();
421  const labelList& oldNeighbour = baseMesh().faceNeighbour();
422 
423  label wantedPatchID = patchID;
424 
425  if (wantedPatchID == -1)
426  {
427  // No explicit patch specified. Put in oldInternalFaces patch.
428  // Check if patch with this name already exists.
429  wantedPatchID = oldPatches.findPatchID("oldInternalFaces");
430  }
431  else if (wantedPatchID < 0 || wantedPatchID >= oldPatches.size())
432  {
434  << "Non-existing patch index " << wantedPatchID << endl
435  << "Should be between 0 and " << oldPatches.size()-1
436  << abort(FatalError);
437  }
438 
439 
440  // Clear demand driven data
441  faceFlipMapPtr_.clear();
442 
443 
444  cellMap_ = globalCellMap.toc();
445 
446  // Sort the cell map in the ascending order
447  sort(cellMap_);
448 
449  // Approximate sizing parameters for face and point lists
450  const label avgNFacesPerCell = 6;
451  const label avgNPointsPerFace = 4;
452 
453 
454  label nCellsInSet = cellMap_.size();
455 
456  // Mark all used faces
457 
458  Map<label> facesToSubset(avgNFacesPerCell*nCellsInSet);
459 
460  forAll(cellMap_, cellI)
461  {
462  // Mark all faces from the cell
463  const labelList& curFaces = oldCells[cellMap_[cellI]];
464 
465  forAll(curFaces, faceI)
466  {
467  if (!facesToSubset.found(curFaces[faceI]))
468  {
469  facesToSubset.insert(curFaces[faceI], 1);
470  }
471  else
472  {
473  facesToSubset[curFaces[faceI]]++;
474  }
475  }
476  }
477 
478  // Mark all used points and make a global-to-local face map
479  Map<label> globalFaceMap(facesToSubset.size());
480 
481  // Make a global-to-local point map
482  Map<label> globalPointMap(avgNPointsPerFace*facesToSubset.size());
483 
484  // This is done in two goes, so that the boundary faces are last
485  // in the list. Because of this, I need to create the face map
486  // along the way rather than just grab the table of contents.
487  labelList facesToc = facesToSubset.toc();
488  sort(facesToc);
489  faceMap_.setSize(facesToc.size());
490 
491  // 1. Get all faces that will be internal to the submesh.
492  forAll(facesToc, faceI)
493  {
494  if (facesToSubset[facesToc[faceI]] == 2)
495  {
496  // Mark face and increment number of points in set
497  faceMap_[globalFaceMap.size()] = facesToc[faceI];
498  globalFaceMap.insert(facesToc[faceI], globalFaceMap.size());
499 
500  // Mark all points from the face
501  markPoints(oldFaces[facesToc[faceI]], globalPointMap);
502  }
503  }
504 
505  // These are all the internal faces in the mesh.
506  label nInternalFaces = globalFaceMap.size();
507 
508 
509  // Where to insert old internal faces.
510  label oldPatchStart = labelMax;
511  if (wantedPatchID != -1)
512  {
513  oldPatchStart = oldPatches[wantedPatchID].start();
514  }
515 
516 
517  label faceI = 0;
518 
519  // 2. Boundary faces up to where we want to insert old internal faces
520  for (; faceI< facesToc.size(); faceI++)
521  {
522  if (facesToc[faceI] >= oldPatchStart)
523  {
524  break;
525  }
526  if
527  (
528  !baseMesh().isInternalFace(facesToc[faceI])
529  && facesToSubset[facesToc[faceI]] == 1
530  )
531  {
532  // Mark face and increment number of points in set
533  faceMap_[globalFaceMap.size()] = facesToc[faceI];
534  globalFaceMap.insert(facesToc[faceI], globalFaceMap.size());
535 
536  // Mark all points from the face
537  markPoints(oldFaces[facesToc[faceI]], globalPointMap);
538  }
539  }
540 
541  // 3. old internal faces
542  forAll(facesToc, intFaceI)
543  {
544  if
545  (
546  baseMesh().isInternalFace(facesToc[intFaceI])
547  && facesToSubset[facesToc[intFaceI]] == 1
548  )
549  {
550  // Mark face and increment number of points in set
551  faceMap_[globalFaceMap.size()] = facesToc[intFaceI];
552  globalFaceMap.insert(facesToc[intFaceI], globalFaceMap.size());
553 
554  // Mark all points from the face
555  markPoints(oldFaces[facesToc[intFaceI]], globalPointMap);
556  }
557  }
558 
559  // 4. Remaining boundary faces
560  for (; faceI< facesToc.size(); faceI++)
561  {
562  if
563  (
564  !baseMesh().isInternalFace(facesToc[faceI])
565  && facesToSubset[facesToc[faceI]] == 1
566  )
567  {
568  // Mark face and increment number of points in set
569  faceMap_[globalFaceMap.size()] = facesToc[faceI];
570  globalFaceMap.insert(facesToc[faceI], globalFaceMap.size());
571 
572  // Mark all points from the face
573  markPoints(oldFaces[facesToc[faceI]], globalPointMap);
574  }
575  }
576 
577 
578 
579  // Grab the points map
580  pointMap_ = globalPointMap.toc();
581  sort(pointMap_);
582 
583  forAll(pointMap_, pointI)
584  {
585  globalPointMap[pointMap_[pointI]] = pointI;
586  }
587 
588  Pout<< "Number of cells in new mesh: " << nCellsInSet << endl;
589  Pout<< "Number of faces in new mesh: " << globalFaceMap.size() << endl;
590  Pout<< "Number of points in new mesh: " << globalPointMap.size() << endl;
591 
592  // Make a new mesh
593  pointField newPoints(globalPointMap.size());
594 
595  label nNewPoints = 0;
596 
597  forAll(pointMap_, pointI)
598  {
599  newPoints[nNewPoints] = oldPoints[pointMap_[pointI]];
600  nNewPoints++;
601  }
602 
603  faceList newFaces(globalFaceMap.size());
604 
605  label nNewFaces = 0;
606 
607  // Make internal faces
608  for (label faceI = 0; faceI < nInternalFaces; faceI++)
609  {
610  const face& oldF = oldFaces[faceMap_[faceI]];
611 
612  face newF(oldF.size());
613 
614  forAll(newF, i)
615  {
616  newF[i] = globalPointMap[oldF[i]];
617  }
618 
619  newFaces[nNewFaces] = newF;
620  nNewFaces++;
621  }
622 
623  // Make boundary faces
624 
625  label nbSize = oldPatches.size();
626  label oldInternalPatchID = -1;
627 
628  if (wantedPatchID == -1)
629  {
630  // Create 'oldInternalFaces' patch at the end
631  // and put all exposed internal faces in there.
632  oldInternalPatchID = nbSize;
633  nbSize++;
634 
635  }
636  else
637  {
638  oldInternalPatchID = wantedPatchID;
639  }
640 
641 
642  // Grad size and start of each patch on the fly. Because of the
643  // structure of the underlying mesh, the patches will appear in the
644  // ascending order
645  labelList boundaryPatchSizes(nbSize, 0);
646 
647  // Assign boundary faces. Visited in order of faceMap_.
648  for (label faceI = nInternalFaces; faceI < faceMap_.size(); faceI++)
649  {
650  label oldFaceI = faceMap_[faceI];
651 
652  face oldF = oldFaces[oldFaceI];
653 
654  // Turn the faces as necessary to point outwards
655  if (baseMesh().isInternalFace(oldFaceI))
656  {
657  // Internal face. Possibly turned the wrong way round
658  if
659  (
660  !globalCellMap.found(oldOwner[oldFaceI])
661  && globalCellMap.found(oldNeighbour[oldFaceI])
662  )
663  {
664  oldF = oldFaces[oldFaceI].reverseFace();
665  }
666 
667  // Update count for patch
668  boundaryPatchSizes[oldInternalPatchID]++;
669  }
670  else
671  {
672  // Boundary face. Increment the appropriate patch
673  label patchOfFace = oldPatches.whichPatch(oldFaceI);
674 
675  // Update count for patch
676  boundaryPatchSizes[patchOfFace]++;
677  }
678 
679  face newF(oldF.size());
680 
681  forAll(newF, i)
682  {
683  newF[i] = globalPointMap[oldF[i]];
684  }
685 
686  newFaces[nNewFaces] = newF;
687  nNewFaces++;
688  }
689 
690 
691 
692  // Create cells
693  cellList newCells(nCellsInSet);
694 
695  label nNewCells = 0;
696 
697  forAll(cellMap_, cellI)
698  {
699  const labelList& oldC = oldCells[cellMap_[cellI]];
700 
701  labelList newC(oldC.size());
702 
703  forAll(newC, i)
704  {
705  newC[i] = globalFaceMap[oldC[i]];
706  }
707 
708  newCells[nNewCells] = cell(newC);
709  nNewCells++;
710  }
711 
712 
713  // Delete any old mesh
714  fvMeshSubsetPtr_.clear();
715  // Make a new mesh
716  fvMeshSubsetPtr_.reset
717  (
718  new fvMesh
719  (
720  IOobject
721  (
722  baseMesh().name() + "SubSet",
723  baseMesh().time().timeName(),
724  baseMesh().time(),
727  ),
728  xferMove(newPoints),
729  xferMove(newFaces),
730  xferMove(newCells)
731  )
732  );
733 
734 
735  // Add old patches
736  List<polyPatch*> newBoundary(nbSize);
737  patchMap_.setSize(nbSize);
738  label nNewPatches = 0;
739  label patchStart = nInternalFaces;
740 
741  forAll(oldPatches, patchI)
742  {
743  if (boundaryPatchSizes[patchI] > 0)
744  {
745  // Patch still exists. Add it
746  newBoundary[nNewPatches] = oldPatches[patchI].clone
747  (
748  fvMeshSubsetPtr_().boundaryMesh(),
749  nNewPatches,
750  boundaryPatchSizes[patchI],
751  patchStart
752  ).ptr();
753 
754  patchStart += boundaryPatchSizes[patchI];
755  patchMap_[nNewPatches] = patchI;
756  nNewPatches++;
757  }
758  }
759 
760  if (wantedPatchID == -1)
761  {
762  // Newly created patch so is at end. Check if any faces in it.
763  if (boundaryPatchSizes[oldInternalPatchID] > 0)
764  {
765  newBoundary[nNewPatches] = new emptyPolyPatch
766  (
767  "oldInternalFaces",
768  boundaryPatchSizes[oldInternalPatchID],
769  patchStart,
770  nNewPatches,
771  fvMeshSubsetPtr_().boundaryMesh(),
772  emptyPolyPatch::typeName
773  );
774 
775  // The index for the first patch is -1 as it originates from
776  // the internal faces
777  patchMap_[nNewPatches] = -1;
778  nNewPatches++;
779  }
780  }
781 
782  // Reset the patch lists
783  newBoundary.setSize(nNewPatches);
784  patchMap_.setSize(nNewPatches);
785 
786  // Add the fvPatches
787  fvMeshSubsetPtr_().addFvPatches(newBoundary);
788 
789  // Subset and add any zones
790  subsetZones();
791 }
792 
793 
795 (
796  const labelList& region,
797  const label currentRegion,
798  const label patchID,
799  const bool syncPar
800 )
801 {
802  const cellList& oldCells = baseMesh().cells();
803  const faceList& oldFaces = baseMesh().faces();
804  const pointField& oldPoints = baseMesh().points();
805  const labelList& oldOwner = baseMesh().faceOwner();
806  const labelList& oldNeighbour = baseMesh().faceNeighbour();
807  const polyBoundaryMesh& oldPatches = baseMesh().boundaryMesh();
808  const label oldNInternalFaces = baseMesh().nInternalFaces();
809 
810  // Initial checks
811 
812  if (region.size() != oldCells.size())
813  {
815  << "Size of region " << region.size()
816  << " is not equal to number of cells in mesh " << oldCells.size()
817  << abort(FatalError);
818  }
819 
820 
821  label wantedPatchID = patchID;
822 
823  if (wantedPatchID == -1)
824  {
825  // No explicit patch specified. Put in oldInternalFaces patch.
826  // Check if patch with this name already exists.
827  wantedPatchID = oldPatches.findPatchID("oldInternalFaces");
828  }
829  else if (wantedPatchID < 0 || wantedPatchID >= oldPatches.size())
830  {
832  << "Non-existing patch index " << wantedPatchID << endl
833  << "Should be between 0 and " << oldPatches.size()-1
834  << abort(FatalError);
835  }
836 
837  // Clear demand driven data
838  faceFlipMapPtr_.clear();
839 
840  // Get the cells for the current region.
841  cellMap_.setSize(oldCells.size());
842  label nCellsInSet = 0;
843 
844  forAll(region, oldCellI)
845  {
846  if (region[oldCellI] == currentRegion)
847  {
848  cellMap_[nCellsInSet++] = oldCellI;
849  }
850  }
851  cellMap_.setSize(nCellsInSet);
852 
853 
854  // Mark all used faces. Count number of cells using them
855  // 0: face not used anymore
856  // 1: face used by one cell, face becomes/stays boundary face
857  // 2: face still used and remains internal face
858  // 3: face coupled and used by one cell only (so should become normal,
859  // non-coupled patch face)
860  //
861  // Note that this is not really necessary - but means we can size things
862  // correctly. Also makes handling coupled faces much easier.
863 
864  labelList nCellsUsingFace(oldFaces.size(), 0);
865 
866  label nFacesInSet = 0;
867  forAll(oldFaces, oldFaceI)
868  {
869  bool faceUsed = false;
870 
871  if (region[oldOwner[oldFaceI]] == currentRegion)
872  {
873  nCellsUsingFace[oldFaceI]++;
874  faceUsed = true;
875  }
876 
877  if
878  (
879  baseMesh().isInternalFace(oldFaceI)
880  && (region[oldNeighbour[oldFaceI]] == currentRegion)
881  )
882  {
883  nCellsUsingFace[oldFaceI]++;
884  faceUsed = true;
885  }
886 
887  if (faceUsed)
888  {
889  nFacesInSet++;
890  }
891  }
892  faceMap_.setSize(nFacesInSet);
893 
894  // Handle coupled faces. Modifies patch faces to be uncoupled to 3.
895  doCoupledPatches(syncPar, nCellsUsingFace);
896 
897 
898  // See which patch to use for exposed internal faces.
899  label oldInternalPatchID = 0;
900 
901  // Insert faces before which patch
902  label nextPatchID = oldPatches.size();
903 
904  // old to new patches
905  labelList globalPatchMap(oldPatches.size());
906 
907  // New patch size
908  label nbSize = oldPatches.size();
909 
910  if (wantedPatchID == -1)
911  {
912  // Create 'oldInternalFaces' patch at the end (or before
913  // processorPatches)
914  // and put all exposed internal faces in there.
915 
916  forAll(oldPatches, patchI)
917  {
918  if (isA<processorPolyPatch>(oldPatches[patchI]))
919  {
920  nextPatchID = patchI;
921  break;
922  }
923  oldInternalPatchID++;
924  }
925 
926  nbSize++;
927 
928  // adapt old to new patches for inserted patch
929  for (label oldPatchI = 0; oldPatchI < nextPatchID; oldPatchI++)
930  {
931  globalPatchMap[oldPatchI] = oldPatchI;
932  }
933  for
934  (
935  label oldPatchI = nextPatchID;
936  oldPatchI < oldPatches.size();
937  oldPatchI++
938  )
939  {
940  globalPatchMap[oldPatchI] = oldPatchI+1;
941  }
942  }
943  else
944  {
945  oldInternalPatchID = wantedPatchID;
946  nextPatchID = wantedPatchID+1;
947 
948  // old to new patches
949  globalPatchMap = identity(oldPatches.size());
950  }
951 
952  labelList boundaryPatchSizes(nbSize, 0);
953 
954 
955  // Make a global-to-local point map
956  labelList globalPointMap(oldPoints.size(), -1);
957 
958  labelList globalFaceMap(oldFaces.size(), -1);
959  label faceI = 0;
960 
961  // 1. Pick up all preserved internal faces.
962  for (label oldFaceI = 0; oldFaceI < oldNInternalFaces; oldFaceI++)
963  {
964  if (nCellsUsingFace[oldFaceI] == 2)
965  {
966  globalFaceMap[oldFaceI] = faceI;
967  faceMap_[faceI++] = oldFaceI;
968 
969  // Mark all points from the face
970  markPoints(oldFaces[oldFaceI], globalPointMap);
971  }
972  }
973 
974  // These are all the internal faces in the mesh.
975  label nInternalFaces = faceI;
976 
977  // 2. Boundary faces up to where we want to insert old internal faces
978  for
979  (
980  label oldPatchI = 0;
981  oldPatchI < oldPatches.size()
982  && oldPatchI < nextPatchID;
983  oldPatchI++
984  )
985  {
986  const polyPatch& oldPatch = oldPatches[oldPatchI];
987 
988  label oldFaceI = oldPatch.start();
989 
990  forAll(oldPatch, i)
991  {
992  if (nCellsUsingFace[oldFaceI] == 1)
993  {
994  // Boundary face is kept.
995 
996  // Mark face and increment number of points in set
997  globalFaceMap[oldFaceI] = faceI;
998  faceMap_[faceI++] = oldFaceI;
999 
1000  // Mark all points from the face
1001  markPoints(oldFaces[oldFaceI], globalPointMap);
1002 
1003  // Increment number of patch faces
1004  boundaryPatchSizes[globalPatchMap[oldPatchI]]++;
1005  }
1006  oldFaceI++;
1007  }
1008  }
1009 
1010  // 3a. old internal faces that have become exposed.
1011  for (label oldFaceI = 0; oldFaceI < oldNInternalFaces; oldFaceI++)
1012  {
1013  if (nCellsUsingFace[oldFaceI] == 1)
1014  {
1015  globalFaceMap[oldFaceI] = faceI;
1016  faceMap_[faceI++] = oldFaceI;
1017 
1018  // Mark all points from the face
1019  markPoints(oldFaces[oldFaceI], globalPointMap);
1020 
1021  // Increment number of patch faces
1022  boundaryPatchSizes[oldInternalPatchID]++;
1023  }
1024  }
1025 
1026  // 3b. coupled patch faces that have become uncoupled.
1027  for
1028  (
1029  label oldFaceI = oldNInternalFaces;
1030  oldFaceI < oldFaces.size();
1031  oldFaceI++
1032  )
1033  {
1034  if (nCellsUsingFace[oldFaceI] == 3)
1035  {
1036  globalFaceMap[oldFaceI] = faceI;
1037  faceMap_[faceI++] = oldFaceI;
1038 
1039  // Mark all points from the face
1040  markPoints(oldFaces[oldFaceI], globalPointMap);
1041 
1042  // Increment number of patch faces
1043  boundaryPatchSizes[oldInternalPatchID]++;
1044  }
1045  }
1046 
1047  // 4. Remaining boundary faces
1048  for
1049  (
1050  label oldPatchI = nextPatchID;
1051  oldPatchI < oldPatches.size();
1052  oldPatchI++
1053  )
1054  {
1055  const polyPatch& oldPatch = oldPatches[oldPatchI];
1056 
1057  label oldFaceI = oldPatch.start();
1058 
1059  forAll(oldPatch, i)
1060  {
1061  if (nCellsUsingFace[oldFaceI] == 1)
1062  {
1063  // Boundary face is kept.
1064 
1065  // Mark face and increment number of points in set
1066  globalFaceMap[oldFaceI] = faceI;
1067  faceMap_[faceI++] = oldFaceI;
1068 
1069  // Mark all points from the face
1070  markPoints(oldFaces[oldFaceI], globalPointMap);
1071 
1072  // Increment number of patch faces
1073  boundaryPatchSizes[globalPatchMap[oldPatchI]]++;
1074  }
1075  oldFaceI++;
1076  }
1077  }
1078 
1079  if (faceI != nFacesInSet)
1080  {
1082  << "Problem" << abort(FatalError);
1083  }
1084 
1085 
1086  // Grab the points map
1087  label nPointsInSet = 0;
1088 
1089  forAll(globalPointMap, pointI)
1090  {
1091  if (globalPointMap[pointI] != -1)
1092  {
1093  nPointsInSet++;
1094  }
1095  }
1096  pointMap_.setSize(nPointsInSet);
1097 
1098  nPointsInSet = 0;
1099 
1100  forAll(globalPointMap, pointI)
1101  {
1102  if (globalPointMap[pointI] != -1)
1103  {
1104  pointMap_[nPointsInSet] = pointI;
1105  globalPointMap[pointI] = nPointsInSet;
1106  nPointsInSet++;
1107  }
1108  }
1109 
1110  //Pout<< "Number of cells in new mesh : " << cellMap_.size() << endl;
1111  //Pout<< "Number of faces in new mesh : " << faceMap_.size() << endl;
1112  //Pout<< "Number of points in new mesh: " << pointMap_.size() << endl;
1113 
1114  // Make a new mesh
1115  pointField newPoints(pointMap_.size());
1116 
1117  label nNewPoints = 0;
1118 
1119  forAll(pointMap_, pointI)
1120  {
1121  newPoints[nNewPoints] = oldPoints[pointMap_[pointI]];
1122  nNewPoints++;
1123  }
1124 
1125  faceList newFaces(faceMap_.size());
1126 
1127  label nNewFaces = 0;
1128 
1129  // Make internal faces
1130  for (label faceI = 0; faceI < nInternalFaces; faceI++)
1131  {
1132  const face& oldF = oldFaces[faceMap_[faceI]];
1133 
1134  face newF(oldF.size());
1135 
1136  forAll(newF, i)
1137  {
1138  newF[i] = globalPointMap[oldF[i]];
1139  }
1140 
1141  newFaces[nNewFaces] = newF;
1142  nNewFaces++;
1143  }
1144 
1145 
1146  // Make boundary faces. (different from internal since might need to be
1147  // flipped)
1148  for (label faceI = nInternalFaces; faceI < faceMap_.size(); faceI++)
1149  {
1150  label oldFaceI = faceMap_[faceI];
1151 
1152  face oldF = oldFaces[oldFaceI];
1153 
1154  // Turn the faces as necessary to point outwards
1155  if (baseMesh().isInternalFace(oldFaceI))
1156  {
1157  // Was internal face. Possibly turned the wrong way round
1158  if
1159  (
1160  region[oldOwner[oldFaceI]] != currentRegion
1161  && region[oldNeighbour[oldFaceI]] == currentRegion
1162  )
1163  {
1164  oldF = oldFaces[oldFaceI].reverseFace();
1165  }
1166  }
1167 
1168  // Relabel vertices of the (possibly turned) face.
1169  face newF(oldF.size());
1170 
1171  forAll(newF, i)
1172  {
1173  newF[i] = globalPointMap[oldF[i]];
1174  }
1175 
1176  newFaces[nNewFaces] = newF;
1177  nNewFaces++;
1178  }
1179 
1180 
1181 
1182  // Create cells
1183  cellList newCells(nCellsInSet);
1184 
1185  label nNewCells = 0;
1186 
1187  forAll(cellMap_, cellI)
1188  {
1189  const labelList& oldC = oldCells[cellMap_[cellI]];
1190 
1191  labelList newC(oldC.size());
1192 
1193  forAll(newC, i)
1194  {
1195  newC[i] = globalFaceMap[oldC[i]];
1196  }
1197 
1198  newCells[nNewCells] = cell(newC);
1199  nNewCells++;
1200  }
1201 
1202 
1203  // Delete any old one
1204  fvMeshSubsetPtr_.clear();
1205 
1206  // Make a new mesh
1207  // Note that mesh gets registered with same name as original mesh. This is
1208  // not proper but cannot be avoided since otherwise surfaceInterpolation
1209  // cannot find its fvSchemes (it will try to read e.g.
1210  // system/region0SubSet/fvSchemes)
1211  // Make a new mesh
1212  fvMeshSubsetPtr_.reset
1213  (
1214  new fvMesh
1215  (
1216  IOobject
1217  (
1218  baseMesh().name(),
1219  baseMesh().time().timeName(),
1220  baseMesh().time(),
1223  ),
1224  xferMove(newPoints),
1225  xferMove(newFaces),
1226  xferMove(newCells),
1227  syncPar // parallel synchronisation
1228  )
1229  );
1230 
1231  // Add old patches
1232  List<polyPatch*> newBoundary(nbSize);
1233  patchMap_.setSize(nbSize);
1234  label nNewPatches = 0;
1235  label patchStart = nInternalFaces;
1236 
1237 
1238  // For parallel: only remove patch if none of the processors has it.
1239  // This only gets done for patches before the one being inserted
1240  // (so patches < nextPatchID)
1241 
1242  // Get sum of patch sizes. Zero if patch can be deleted.
1243  labelList globalPatchSizes(boundaryPatchSizes);
1244  globalPatchSizes.setSize(nextPatchID);
1245 
1246  if (syncPar && Pstream::parRun())
1247  {
1248  // Get patch names (up to nextPatchID)
1250  patchNames[Pstream::myProcNo()] = oldPatches.names();
1251  patchNames[Pstream::myProcNo()].setSize(nextPatchID);
1254 
1255  // Get patch sizes (up to nextPatchID).
1256  // Note that up to nextPatchID the globalPatchMap is an identity so
1257  // no need to index through that.
1258  Pstream::listCombineGather(globalPatchSizes, plusEqOp<label>());
1259  Pstream::listCombineScatter(globalPatchSizes);
1260 
1261  // Now all processors have all the patchnames.
1262  // Decide: if all processors have the same patch names and size is zero
1263  // everywhere remove the patch.
1264  bool samePatches = true;
1265 
1266  for (label procI = 1; procI < patchNames.size(); procI++)
1267  {
1268  if (patchNames[procI] != patchNames[0])
1269  {
1270  samePatches = false;
1271  break;
1272  }
1273  }
1274 
1275  if (!samePatches)
1276  {
1277  // Patchnames not sync on all processors so disable removal of
1278  // zero sized patches.
1279  globalPatchSizes = labelMax;
1280  }
1281  }
1282 
1283 
1284  // Old patches
1285 
1286  for
1287  (
1288  label oldPatchI = 0;
1289  oldPatchI < oldPatches.size()
1290  && oldPatchI < nextPatchID;
1291  oldPatchI++
1292  )
1293  {
1294  label newSize = boundaryPatchSizes[globalPatchMap[oldPatchI]];
1295 
1296  // Clone (even if 0 size)
1297  newBoundary[nNewPatches] = oldPatches[oldPatchI].clone
1298  (
1299  fvMeshSubsetPtr_().boundaryMesh(),
1300  nNewPatches,
1301  newSize,
1302  patchStart
1303  ).ptr();
1304 
1305  patchStart += newSize;
1306  patchMap_[nNewPatches] = oldPatchI; // compact patchMap
1307  nNewPatches++;
1308  }
1309 
1310  // Inserted patch
1311 
1312  if (wantedPatchID == -1)
1313  {
1314  label oldInternalSize = boundaryPatchSizes[oldInternalPatchID];
1315 
1316  if (syncPar)
1317  {
1318  reduce(oldInternalSize, sumOp<label>());
1319  }
1320 
1321  // Newly created patch so is at end. Check if any faces in it.
1322  if (oldInternalSize > 0)
1323  {
1324  newBoundary[nNewPatches] = new emptyPolyPatch
1325  (
1326  "oldInternalFaces",
1327  boundaryPatchSizes[oldInternalPatchID],
1328  patchStart,
1329  nNewPatches,
1330  fvMeshSubsetPtr_().boundaryMesh(),
1331  emptyPolyPatch::typeName
1332  );
1333 
1334  //Pout<< " oldInternalFaces : "
1335  // << boundaryPatchSizes[oldInternalPatchID] << endl;
1336 
1337  // The index for the first patch is -1 as it originates from
1338  // the internal faces
1339  patchStart += boundaryPatchSizes[oldInternalPatchID];
1340  patchMap_[nNewPatches] = -1;
1341  nNewPatches++;
1342  }
1343  }
1344 
1345  // Old patches
1346 
1347  for
1348  (
1349  label oldPatchI = nextPatchID;
1350  oldPatchI < oldPatches.size();
1351  oldPatchI++
1352  )
1353  {
1354  label newSize = boundaryPatchSizes[globalPatchMap[oldPatchI]];
1355 
1356  // Patch still exists. Add it
1357  newBoundary[nNewPatches] = oldPatches[oldPatchI].clone
1358  (
1359  fvMeshSubsetPtr_().boundaryMesh(),
1360  nNewPatches,
1361  newSize,
1362  patchStart
1363  ).ptr();
1364 
1365  //Pout<< " " << oldPatches[oldPatchI].name() << " : "
1366  // << newSize << endl;
1367 
1368  patchStart += newSize;
1369  patchMap_[nNewPatches] = oldPatchI; // compact patchMap
1370  nNewPatches++;
1371  }
1372 
1373 
1374  // Reset the patch lists
1375  newBoundary.setSize(nNewPatches);
1376  patchMap_.setSize(nNewPatches);
1377 
1378 
1379  // Add the fvPatches
1380  fvMeshSubsetPtr_().addFvPatches(newBoundary, syncPar);
1381 
1382  // Subset and add any zones
1383  subsetZones();
1384 }
1385 
1386 
1389  const labelHashSet& globalCellMap,
1390  const label patchID,
1391  const bool syncPar
1392 )
1393 {
1394  labelList region(baseMesh().nCells(), 0);
1395 
1396  forAllConstIter(labelHashSet, globalCellMap, iter)
1397  {
1398  region[iter.key()] = 1;
1399  }
1400  setLargeCellSubset(region, 1, patchID, syncPar);
1401 }
1402 
1403 
1406  const labelList& region,
1407  const label currentRegion,
1408  const bool syncCouples
1409 ) const
1410 {
1411  // Collect cells to remove
1412  labelList cellsToRemove(getCellsToRemove(region, currentRegion));
1413 
1414  return removeCells(baseMesh(), syncCouples).getExposedFaces(cellsToRemove);
1415 }
1416 
1417 
1420  const labelList& region,
1421  const label currentRegion,
1422  const labelList& exposedFaces,
1423  const labelList& patchIDs,
1424  const bool syncCouples
1425 )
1426 {
1427  // Collect cells to remove
1428  labelList cellsToRemove(getCellsToRemove(region, currentRegion));
1429 
1430  // Mesh changing engine.
1431  polyTopoChange meshMod(baseMesh());
1432 
1433  removeCells cellRemover(baseMesh(), syncCouples);
1434 
1435  cellRemover.setRefinement
1436  (
1437  cellsToRemove,
1438  exposedFaces,
1439  patchIDs,
1440  meshMod
1441  );
1442 
1443  // Create mesh, return map from old to new mesh.
1444  autoPtr<mapPolyMesh> map = meshMod.makeMesh
1445  (
1446  fvMeshSubsetPtr_,
1447  IOobject
1448  (
1449  baseMesh().name(),
1450  baseMesh().time().timeName(),
1451  baseMesh().time(),
1454  ),
1455  baseMesh(),
1456  syncCouples
1457  );
1458 
1459  pointMap_ = map().pointMap();
1460  faceMap_ = map().faceMap();
1461  cellMap_ = map().cellMap();
1462  patchMap_ = identity(baseMesh().boundaryMesh().size());
1463 }
1464 
1465 
1467 {
1468  return fvMeshSubsetPtr_.valid();
1469 }
1470 
1471 
1473 {
1474  checkCellSubset();
1475 
1476  return fvMeshSubsetPtr_();
1477 }
1478 
1479 
1481 {
1482  checkCellSubset();
1483 
1484  return fvMeshSubsetPtr_();
1485 }
1486 
1487 
1489 {
1490  checkCellSubset();
1491 
1492  return pointMap_;
1493 }
1494 
1495 
1497 {
1498  checkCellSubset();
1499 
1500  return faceMap_;
1501 }
1502 
1503 
1505 {
1506  if (!faceFlipMapPtr_.valid())
1507  {
1508  const labelList& subToBaseFace = faceMap();
1509  const labelList& subToBaseCell = cellMap();
1510 
1511  faceFlipMapPtr_.reset(new labelList(subToBaseFace.size()));
1512  labelList& faceFlipMap = faceFlipMapPtr_();
1513 
1514  // Only exposed internal faces might be flipped (since we don't do
1515  // any cell renumbering, just compacting)
1516  label subInt = subMesh().nInternalFaces();
1517  const labelList& subOwn = subMesh().faceOwner();
1518  const labelList& own = baseMesh_.faceOwner();
1519 
1520  for (label subFaceI = 0; subFaceI < subInt; subFaceI++)
1521  {
1522  faceFlipMap[subFaceI] = subToBaseFace[subFaceI]+1;
1523  }
1524  for (label subFaceI = subInt; subFaceI < subOwn.size(); subFaceI++)
1525  {
1526  label faceI = subToBaseFace[subFaceI];
1527  if (subToBaseCell[subOwn[subFaceI]] == own[faceI])
1528  {
1529  faceFlipMap[subFaceI] = faceI+1;
1530  }
1531  else
1532  {
1533  faceFlipMap[subFaceI] = -faceI-1;
1534  }
1535  }
1536  }
1537 
1538  return faceFlipMapPtr_();
1539 }
1540 
1541 
1543 {
1544  checkCellSubset();
1545 
1546  return cellMap_;
1547 }
1548 
1549 
1551 {
1552  checkCellSubset();
1553 
1554  return patchMap_;
1555 }
1556 
1557 
1558 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1559 
1560 } // End namespace Foam
1561 
1562 // ************************************************************************* //
Foam::fvMeshSubset::setLargeCellSubset
void setLargeCellSubset(const labelList &region, const label currentRegion, const label patchID=-1, const bool syncCouples=true)
Set the subset from all cells with region == currentRegion.
Definition: fvMeshSubset.C:795
Foam::IOobject
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
Foam::fvMeshSubset::doCoupledPatches
void doCoupledPatches(const bool syncPar, labelList &nCellsUsingFace) const
Adapt nCellsUsingFace for coupled faces becoming 'uncoupled'.
Definition: fvMeshSubset.C:96
Foam::faceMap
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Definition: blockMeshMergeFast.C:90
Foam::polyBoundaryMesh::findPatchID
label findPatchID(const word &patchName) const
Find patch index given a name.
Definition: polyBoundaryMesh.C:678
boolList.H
Foam::UOPstream
Output inter-processor communications stream operating on external buffer.
Definition: UOPstream.H:54
Foam::labelList
List< label > labelList
A List of labels.
Definition: labelList.H:56
Foam::polyBoundaryMesh
Foam::polyBoundaryMesh.
Definition: polyBoundaryMesh.H:60
Foam::HashTable::toc
List< Key > toc() const
Return the table of contents.
Definition: HashTable.C:201
cyclicPolyPatch.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::cyclicPolyPatch::transformGlobalFace
label transformGlobalFace(const label facei) const
Definition: cyclicPolyPatch.H:353
Foam::cyclicPolyPatch
Cyclic plane patch.
Definition: cyclicPolyPatch.H:63
Foam::removeCells
Given list of cells to remove insert all the topology changes.
Definition: removeCells.H:59
Foam::fvMeshSubset::subsetZones
void subsetZones()
Create zones for submesh.
Definition: fvMeshSubset.C:243
fvMeshSubset.H
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
Foam::Pstream::scatterList
static void scatterList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Scatter data. Reverse of gatherList.
Definition: gatherScatterList.C:205
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:53
mapPolyMesh.H
Foam::labelMax
static const label labelMax
Definition: label.H:62
Foam::pointZone
A subset of mesh points. The labels of points in the zone can be obtained from the addressing() list.
Definition: pointZone.H:62
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:387
Foam::PstreamBuffers
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Definition: PstreamBuffers.H:85
polyTopoChange.H
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:377
Foam::polyTopoChange
Direct mesh changes based on v1.3 polyTopoChange syntax.
Definition: polyTopoChange.H:97
Foam::zone
Base class for zones.
Definition: zone.H:57
Foam::Map< label >
Foam::processorPolyPatch::neighbProcNo
int neighbProcNo() const
Return neigbour processor number.
Definition: processorPolyPatch.H:255
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
removeCells.H
Foam::fvMeshSubset::getCellsToRemove
labelList getCellsToRemove(const labelList &region, const label currentRegion) const
Helper: extract cells-to-remove from cells-to-keep.
Definition: fvMeshSubset.C:360
Foam::HashSet< label, Hash< label > >
Foam::IOobject::NO_WRITE
@ NO_WRITE
Definition: IOobject.H:118
Foam::polyBoundaryMesh::names
wordList names() const
Return a list of patch names.
Definition: polyBoundaryMesh.C:527
Foam::cellZone
A subset of mesh cells.
Definition: cellZone.H:61
forAllConstIter
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::fvMeshSubset::cellMap
const labelList & cellMap() const
Return cell map.
Definition: fvMeshSubset.C:1542
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:43
Foam::UPstream::nonBlocking
@ nonBlocking
Definition: UPstream.H:68
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::fvMeshSubset::fvMeshSubset
fvMeshSubset(const fvMeshSubset &)
Disallow default bitwise copy construct.
Foam::faceZone
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:64
Foam::IOobject::NO_READ
@ NO_READ
Definition: IOobject.H:111
Foam::Info
messageStream Info
Foam::fvMeshSubset::setCellSubset
void setCellSubset(const labelHashSet &globalCellMap, const label patchID=-1)
Set the subset. Create "oldInternalFaces" patch for exposed.
Definition: fvMeshSubset.C:410
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
Foam::polyTopoChange::makeMesh
autoPtr< mapPolyMesh > makeMesh(autoPtr< fvMesh > &newMesh, const IOobject &io, const polyMesh &mesh, const bool syncParallel=true, const bool orderCells=false, const bool orderPoints=false)
Create new mesh with old mesh patches.
Definition: polyTopoChange.C:3305
Foam::ZoneMesh
A list of mesh zones.
Definition: cellZoneMeshFwd.H:39
Foam::polyBoundaryMesh::whichPatch
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
Definition: polyBoundaryMesh.C:703
Foam::fvMeshSubset::pointMap
const labelList & pointMap() const
Return point map.
Definition: fvMeshSubset.C:1488
Foam::processorPolyPatch
Neighbour processor patch.
Definition: processorPolyPatch.H:55
Foam::fvMeshSubset::faceFlipMap
const labelList & faceFlipMap() const
Return face map with sign to encode flipped faces.
Definition: fvMeshSubset.C:1504
patchNames
wordList patchNames(nPatches)
Foam::fvMeshSubset::getExposedFaces
labelList getExposedFaces(const labelList &region, const label currentRegion, const bool syncCouples=true) const
Two step subsetting.
Definition: fvMeshSubset.C:1405
Foam::PstreamBuffers::finishedSends
void finishedSends(const bool block=true)
Mark all sends as having been done. This will start receives.
Definition: PstreamBuffers.C:82
Foam::removeCells::setRefinement
void setRefinement(const labelList &cellsToRemove, const labelList &facesToExpose, const labelList &patchIDs, polyTopoChange &) const
Play commands into polyTopoChange to remove cells.
Definition: removeCells.C:189
Foam::identity
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
Foam::fvMeshSubset::subset
static labelList subset(const label nElems, const labelList &selectedElements, const labelList &subsetMap)
Subset of subset.
Definition: fvMeshSubset.C:204
Foam::FatalError
error FatalError
Foam::plusEqOp
Definition: ops.H:71
Foam::fvMeshSubset::checkCellSubset
bool checkCellSubset() const
Check if subset has been performed.
Definition: fvMeshSubset.C:48
Pstream.H
Foam::HashTable::found
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:109
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::zone::name
const word & name() const
Return name.
Definition: zone.H:150
Foam::fvMeshSubset::patchMap
const labelList & patchMap() const
Return patch map.
Definition: fvMeshSubset.C:1550
Foam::polyPatch::start
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:312
emptyPolyPatch.H
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:405
Foam::subset
ListType subset(const UList< T > &select, const T &value, const ListType &)
Extract elements of List when select is a certain value.
Definition: ListOpsTemplates.C:290
Foam::Pstream::listCombineGather
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
Definition: combineGatherScatter.C:282
Foam::fvMeshSubset::markPoints
static void markPoints(const labelList &, Map< label > &)
Mark points in Map.
Definition: fvMeshSubset.C:67
Foam::emptyPolyPatch
Empty front and back plane patch. Used for 2-D geometries.
Definition: emptyPolyPatch.H:48
Foam::List::setSize
void setSize(const label)
Reset size of List.
Foam::autoPtr
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::Pstream::gatherList
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
Definition: gatherScatterList.C:49
Foam::xferMove
Xfer< T > xferMove(T &)
Construct by transferring the contents of the arg.
Foam::sumOp
Definition: ops.H:162
Foam::Pout
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::IOobject::clone
Foam::autoPtr< IOobject > clone() const
Clone.
Definition: IOobject.H:252
Foam::PtrList::size
label size() const
Return the number of elements in the PtrList.
Definition: PtrListI.H:32
timeName
word timeName
Definition: getTimeIndex.H:3
Foam::fvMeshSubset::subMesh
const fvMesh & subMesh() const
Return reference to subset mesh.
Definition: fvMeshSubset.C:1472
Foam::boundaryMesh
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:59
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Foam::sort
void sort(UList< T > &)
Definition: UList.C:107
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::UIPstream
Input inter-processor communications stream operating on external buffer.
Definition: UIPstream.H:53
Foam::Pstream::listCombineScatter
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
Definition: combineGatherScatter.C:417
Foam::faceZone::flipMap
const boolList & flipMap() const
Return face flip map.
Definition: faceZone.H:249
Foam::removeCells::getExposedFaces
labelList getExposedFaces(const labelList &cellsToRemove) const
Get labels of exposed faces.
Definition: removeCells.C:73
Foam::cell
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:56
Foam::fvMeshSubset::hasSubMesh
bool hasSubMesh() const
Have subMesh?
Definition: fvMeshSubset.C:1466
Foam::name
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
Foam::fvMeshSubset::faceMap
const labelList & faceMap() const
Return face map.
Definition: fvMeshSubset.C:1496