1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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.
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
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/>.
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.
29 MJ 23/03/05 on coupled faces change the patch of the face to the
30 oldInternalFaces patch.
32 \*---------------------------------------------------------------------------*/
34 #include "fvMeshSubset.H"
37 #include "emptyPolyPatch.H"
38 #include "demandDrivenData.H"
39 #include "cyclicPolyPatch.H"
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
46 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
48 bool Foam::fvMeshSubset::checkCellSubset() const
50 if (fvMeshSubsetPtr_.empty())
52 FatalErrorIn("bool fvMeshSubset::checkCellSubset() const")
53 << "Mesh subset not set. Please set the cell map using "
54 << "void setCellSubset(const labelHashSet& cellsToSubset)" << endl
55 << "before attempting to access subset data"
67 void Foam::fvMeshSubset::markPoints
69 const labelList& curPoints,
73 forAll (curPoints, pointI)
75 // Note: insert will only insert if not yet there.
76 pointMap.insert(curPoints[pointI], 0);
81 void Foam::fvMeshSubset::markPoints
83 const labelList& curPoints,
87 forAll (curPoints, pointI)
89 pointMap[curPoints[pointI]] = 0;
94 // Synchronize nCellsUsingFace on both sides of coupled patches. Marks
95 // faces that become 'uncoupled' with 3.
96 void Foam::fvMeshSubset::doCoupledPatches
99 labelList& nCellsUsingFace
102 const polyBoundaryMesh& oldPatches = baseMesh().boundaryMesh();
104 label nUncoupled = 0;
106 if (syncPar && Pstream::parRun())
108 // Send face usage across processor patches
109 forAll (oldPatches, oldPatchI)
111 const polyPatch& pp = oldPatches[oldPatchI];
113 if (isA<processorPolyPatch>(pp))
115 const processorPolyPatch& procPatch =
116 refCast<const processorPolyPatch>(pp);
121 procPatch.neighbProcNo()
125 << SubList<label>(nCellsUsingFace, pp.size(), pp.start());
130 // Receive face usage count and check for faces that become uncoupled.
131 forAll (oldPatches, oldPatchI)
133 const polyPatch& pp = oldPatches[oldPatchI];
135 if (isA<processorPolyPatch>(pp))
137 const processorPolyPatch& procPatch =
138 refCast<const processorPolyPatch>(pp);
140 IPstream fromNeighbour
143 procPatch.neighbProcNo()
146 labelList nbrCellsUsingFace(fromNeighbour);
148 // Combine with this side.
154 nCellsUsingFace[pp.start()+i] == 1
155 && nbrCellsUsingFace[i] == 0
158 // Face's neighbour is no longer there. Mark face off
160 nCellsUsingFace[pp.start()+i] = 3;
168 // Do same for cyclics.
169 forAll (oldPatches, oldPatchI)
171 const polyPatch& pp = oldPatches[oldPatchI];
173 if (isA<cyclicPolyPatch>(pp))
175 const cyclicPolyPatch& cycPatch =
176 refCast<const cyclicPolyPatch>(pp);
180 label thisFaceI = cycPatch.start() + i;
181 label otherFaceI = cycPatch.transformGlobalFace(thisFaceI);
185 nCellsUsingFace[thisFaceI] == 1
186 && nCellsUsingFace[otherFaceI] == 0
189 nCellsUsingFace[thisFaceI] = 3;
198 reduce(nUncoupled, sumOp<label>());
203 Info<< "Uncoupled " << nUncoupled << " faces on coupled patches. "
204 << "(processorPolyPatch, cyclicPolyPatch)" << nl
205 << "You might need to run couplePatches to restore the patch face"
206 << " ordering." << nl << endl;
211 labelList Foam::fvMeshSubset::subset
214 const labelList& selectedElements,
215 const labelList& subsetMap
218 // Mark selected elements.
219 boolList selected(nElems, false);
220 forAll(selectedElements, i)
222 selected[selectedElements[i]] = true;
225 // Count subset of selected elements
229 if (selected[subsetMap[i]])
235 // Collect selected elements
236 labelList subsettedElements(n);
241 if (selected[subsetMap[i]])
243 subsettedElements[n++] = i;
247 return subsettedElements;
251 void Foam::fvMeshSubset::subsetZones()
253 // Keep all zones, even if zero size.
255 const pointZoneMesh& pointZones = baseMesh().pointZones();
258 List<pointZone*> pZonePtrs(pointZones.size());
260 forAll(pointZones, i)
262 const pointZone& pz = pointZones[i];
264 pZonePtrs[i] = new pointZone
267 subset(baseMesh().nPoints(), pz, pointMap()),
269 fvMeshSubsetPtr_().pointZones()
276 const faceZoneMesh& faceZones = baseMesh().faceZones();
279 // Do we need to remove zones where the side we're interested in
280 // no longer exists? Guess not.
281 List<faceZone*> fZonePtrs(faceZones.size());
285 const faceZone& fz = faceZones[i];
287 // Expand faceZone to full mesh
288 // +1 : part of faceZone, flipped
289 // -1 : ,, , unflipped
290 // 0 : not part of faceZone
291 labelList zone(baseMesh().nFaces(), 0);
308 if (zone[faceMap()[j]] != 0)
313 labelList subAddressing(nSub);
314 boolList subFlipStatus(nSub);
316 forAll(faceMap(), subFaceI)
318 label meshFaceI = faceMap()[subFaceI];
319 if (zone[meshFaceI] != 0)
321 subAddressing[nSub] = subFaceI;
322 label subOwner = subMesh().faceOwner()[subFaceI];
323 label baseOwner = baseMesh().faceOwner()[meshFaceI];
324 // If subowner is the same cell as the base keep the flip status
325 bool sameOwner = (cellMap()[subOwner] == baseOwner);
326 bool flip = (zone[meshFaceI] == 1);
327 subFlipStatus[nSub] = (sameOwner == flip);
333 fZonePtrs[i] = new faceZone
339 fvMeshSubsetPtr_().faceZones()
344 const cellZoneMesh& cellZones = baseMesh().cellZones();
346 List<cellZone*> cZonePtrs(cellZones.size());
350 const cellZone& cz = cellZones[i];
352 cZonePtrs[i] = new cellZone
355 subset(baseMesh().nCells(), cz, cellMap()),
357 fvMeshSubsetPtr_().cellZones()
363 fvMeshSubsetPtr_().addZones(pZonePtrs, fZonePtrs, cZonePtrs);
367 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
369 // Construct from components
370 Foam::fvMeshSubset::fvMeshSubset(const fvMesh& baseMesh)
373 fvMeshSubsetPtr_(NULL),
381 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
383 void Foam::fvMeshSubset::setCellSubset
385 const labelHashSet& globalCellMap,
389 // Initial check on patches before doing anything time consuming.
390 const polyBoundaryMesh& oldPatches = baseMesh().boundaryMesh();
391 const cellList& oldCells = baseMesh().cells();
392 const faceList& oldFaces = baseMesh().faces();
393 const pointField& oldPoints = baseMesh().points();
394 const labelList& oldOwner = baseMesh().faceOwner();
395 const labelList& oldNeighbour = baseMesh().faceNeighbour();
397 label wantedPatchID = patchID;
399 if (wantedPatchID == -1)
401 // No explicit patch specified. Put in oldInternalFaces patch.
402 // Check if patch with this name already exists.
403 wantedPatchID = oldPatches.findPatchID("oldInternalFaces");
405 else if (wantedPatchID < 0 || wantedPatchID >= oldPatches.size())
409 "fvMeshSubset::setCellSubset(const labelHashSet&"
410 ", const label patchID)"
411 ) << "Non-existing patch index " << wantedPatchID << endl
412 << "Should be between 0 and " << oldPatches.size()-1
413 << abort(FatalError);
417 cellMap_ = globalCellMap.toc();
419 // Sort the cell map in the ascending order
422 // Approximate sizing parameters for face and point lists
423 const label avgNFacesPerCell = 6;
424 const label avgNPointsPerFace = 4;
427 label nCellsInSet = cellMap_.size();
429 // Mark all used faces
431 Map<label> facesToSubset(avgNFacesPerCell*nCellsInSet);
433 forAll (cellMap_, cellI)
435 // Mark all faces from the cell
436 const labelList& curFaces = oldCells[cellMap_[cellI]];
438 forAll (curFaces, faceI)
440 if (!facesToSubset.found(curFaces[faceI]))
442 facesToSubset.insert(curFaces[faceI], 1);
446 facesToSubset[curFaces[faceI]]++;
451 // Mark all used points and make a global-to-local face map
452 Map<label> globalFaceMap(facesToSubset.size());
454 // Make a global-to-local point map
455 Map<label> globalPointMap(avgNPointsPerFace*facesToSubset.size());
457 // This is done in two goes, so that the boundary faces are last
458 // in the list. Because of this, I need to create the face map
459 // along the way rather than just grab the table of contents.
460 labelList facesToc = facesToSubset.toc();
462 faceMap_.setSize(facesToc.size());
464 // 1. Get all faces that will be internal to the submesh.
465 forAll (facesToc, faceI)
467 if (facesToSubset[facesToc[faceI]] == 2)
469 // Mark face and increment number of points in set
470 faceMap_[globalFaceMap.size()] = facesToc[faceI];
471 globalFaceMap.insert(facesToc[faceI], globalFaceMap.size());
473 // Mark all points from the face
474 markPoints(oldFaces[facesToc[faceI]], globalPointMap);
478 // These are all the internal faces in the mesh.
479 label nInternalFaces = globalFaceMap.size();
482 // Where to insert old internal faces.
483 label oldPatchStart = labelMax;
484 if (wantedPatchID != -1)
486 oldPatchStart = oldPatches[wantedPatchID].start();
492 // 2. Boundary faces up to where we want to insert old internal faces
493 for (; faceI< facesToc.size(); faceI++)
495 if (facesToc[faceI] >= oldPatchStart)
501 !baseMesh().isInternalFace(facesToc[faceI])
502 && facesToSubset[facesToc[faceI]] == 1
505 // Mark face and increment number of points in set
506 faceMap_[globalFaceMap.size()] = facesToc[faceI];
507 globalFaceMap.insert(facesToc[faceI], globalFaceMap.size());
509 // Mark all points from the face
510 markPoints(oldFaces[facesToc[faceI]], globalPointMap);
514 // 3. old internal faces
515 forAll(facesToc, intFaceI)
519 baseMesh().isInternalFace(facesToc[intFaceI])
520 && facesToSubset[facesToc[intFaceI]] == 1
523 // Mark face and increment number of points in set
524 faceMap_[globalFaceMap.size()] = facesToc[intFaceI];
525 globalFaceMap.insert(facesToc[intFaceI], globalFaceMap.size());
527 // Mark all points from the face
528 markPoints(oldFaces[facesToc[intFaceI]], globalPointMap);
532 // 4. Remaining boundary faces
533 for (; faceI< facesToc.size(); faceI++)
537 !baseMesh().isInternalFace(facesToc[faceI])
538 && facesToSubset[facesToc[faceI]] == 1
541 // Mark face and increment number of points in set
542 faceMap_[globalFaceMap.size()] = facesToc[faceI];
543 globalFaceMap.insert(facesToc[faceI], globalFaceMap.size());
545 // Mark all points from the face
546 markPoints(oldFaces[facesToc[faceI]], globalPointMap);
552 // Grab the points map
553 pointMap_ = globalPointMap.toc();
556 forAll (pointMap_, pointI)
558 globalPointMap[pointMap_[pointI]] = pointI;
561 Pout << "Number of cells in new mesh: " << nCellsInSet << endl;
562 Pout << "Number of faces in new mesh: " << globalFaceMap.size() << endl;
563 Pout << "Number of points in new mesh: " << globalPointMap.size() << endl;
566 pointField newPoints(globalPointMap.size());
568 label nNewPoints = 0;
570 forAll (pointMap_, pointI)
572 newPoints[nNewPoints] = oldPoints[pointMap_[pointI]];
576 faceList newFaces(globalFaceMap.size());
580 // Make internal faces
581 for (label faceI = 0; faceI < nInternalFaces; faceI++)
583 const face& oldF = oldFaces[faceMap_[faceI]];
585 face newF(oldF.size());
589 newF[i] = globalPointMap[oldF[i]];
592 newFaces[nNewFaces] = newF;
596 // Make boundary faces
598 label nbSize = oldPatches.size();
599 label oldInternalPatchID = -1;
601 if (wantedPatchID == -1)
603 // Create 'oldInternalFaces' patch at the end
604 // and put all exposed internal faces in there.
605 oldInternalPatchID = nbSize;
611 oldInternalPatchID = wantedPatchID;
615 // Grad size and start of each patch on the fly. Because of the
616 // structure of the underlying mesh, the patches will appear in the
618 labelList boundaryPatchSizes(nbSize, 0);
620 // Assign boundary faces. Visited in order of faceMap_.
621 for (label faceI = nInternalFaces; faceI < faceMap_.size(); faceI++)
623 label oldFaceI = faceMap_[faceI];
625 face oldF = oldFaces[oldFaceI];
627 // Turn the faces as necessary to point outwards
628 if (baseMesh().isInternalFace(oldFaceI))
630 // Internal face. Possibly turned the wrong way round
633 !globalCellMap.found(oldOwner[oldFaceI])
634 && globalCellMap.found(oldNeighbour[oldFaceI])
637 oldF = oldFaces[oldFaceI].reverseFace();
640 // Update count for patch
641 boundaryPatchSizes[oldInternalPatchID]++;
645 // Boundary face. Increment the appropriate patch
646 label patchOfFace = oldPatches.whichPatch(oldFaceI);
648 // Update count for patch
649 boundaryPatchSizes[patchOfFace]++;
652 face newF(oldF.size());
656 newF[i] = globalPointMap[oldF[i]];
659 newFaces[nNewFaces] = newF;
666 cellList newCells(nCellsInSet);
670 forAll (cellMap_, cellI)
672 const labelList& oldC = oldCells[cellMap_[cellI]];
674 labelList newC(oldC.size());
678 newC[i] = globalFaceMap[oldC[i]];
681 newCells[nNewCells] = cell(newC);
686 // Delete any old one
687 fvMeshSubsetPtr_.clear();
689 fvMeshSubsetPtr_.reset
695 baseMesh().name() + "SubSet",
696 baseMesh().time().timeName(),
709 List<polyPatch*> newBoundary(nbSize);
710 patchMap_.setSize(nbSize);
711 label nNewPatches = 0;
712 label patchStart = nInternalFaces;
714 forAll(oldPatches, patchI)
716 if (boundaryPatchSizes[patchI] > 0)
718 // Patch still exists. Add it
719 newBoundary[nNewPatches] = oldPatches[patchI].clone
721 fvMeshSubsetPtr_().boundaryMesh(),
723 boundaryPatchSizes[patchI],
727 patchStart += boundaryPatchSizes[patchI];
728 patchMap_[nNewPatches] = patchI;
733 if (wantedPatchID == -1)
735 // Newly created patch so is at end. Check if any faces in it.
736 if (boundaryPatchSizes[oldInternalPatchID] > 0)
738 newBoundary[nNewPatches] = new emptyPolyPatch
741 boundaryPatchSizes[oldInternalPatchID],
744 fvMeshSubsetPtr_().boundaryMesh()
747 // The index for the first patch is -1 as it originates from
748 // the internal faces
749 patchMap_[nNewPatches] = -1;
754 // Reset the patch lists
755 newBoundary.setSize(nNewPatches);
756 patchMap_.setSize(nNewPatches);
759 fvMeshSubsetPtr_().addFvPatches(newBoundary);
761 // Subset and add any zones
766 void Foam::fvMeshSubset::setLargeCellSubset
768 const labelList& region,
769 const label currentRegion,
774 const cellList& oldCells = baseMesh().cells();
775 const faceList& oldFaces = baseMesh().faces();
776 const pointField& oldPoints = baseMesh().points();
777 const labelList& oldOwner = baseMesh().faceOwner();
778 const labelList& oldNeighbour = baseMesh().faceNeighbour();
779 const polyBoundaryMesh& oldPatches = baseMesh().boundaryMesh();
780 const label oldNInternalFaces = baseMesh().nInternalFaces();
784 if (region.size() != oldCells.size())
788 "fvMeshSubset::setCellSubset(const labelList&"
789 ", const label, const label, const bool)"
790 ) << "Size of region " << region.size()
791 << " is not equal to number of cells in mesh " << oldCells.size()
792 << abort(FatalError);
796 label wantedPatchID = patchID;
798 if (wantedPatchID == -1)
800 // No explicit patch specified. Put in oldInternalFaces patch.
801 // Check if patch with this name already exists.
802 wantedPatchID = oldPatches.findPatchID("oldInternalFaces");
804 else if (wantedPatchID < 0 || wantedPatchID >= oldPatches.size())
808 "fvMeshSubset::setCellSubset(const labelList&"
809 ", const label, const label, const bool)"
810 ) << "Non-existing patch index " << wantedPatchID << endl
811 << "Should be between 0 and " << oldPatches.size()-1
812 << abort(FatalError);
816 // Get the cells for the current region.
817 cellMap_.setSize(oldCells.size());
818 label nCellsInSet = 0;
820 forAll (region, oldCellI)
822 if (region[oldCellI] == currentRegion)
824 cellMap_[nCellsInSet++] = oldCellI;
827 cellMap_.setSize(nCellsInSet);
830 // Mark all used faces. Count number of cells using them
831 // 0: face not used anymore
832 // 1: face used by one cell, face becomes/stays boundary face
833 // 2: face still used and remains internal face
834 // 3: face coupled and used by one cell only (so should become normal,
835 // non-coupled patch face)
837 // Note that this is not really nessecary - but means we can size things
838 // correctly. Also makes handling coupled faces much easier.
840 labelList nCellsUsingFace(oldFaces.size(), 0);
842 label nFacesInSet = 0;
843 forAll (oldFaces, oldFaceI)
845 bool faceUsed = false;
847 if (region[oldOwner[oldFaceI]] == currentRegion)
849 nCellsUsingFace[oldFaceI]++;
855 baseMesh().isInternalFace(oldFaceI)
856 && (region[oldNeighbour[oldFaceI]] == currentRegion)
859 nCellsUsingFace[oldFaceI]++;
868 faceMap_.setSize(nFacesInSet);
870 // Handle coupled faces. Modifies patch faces to be uncoupled to 3.
871 doCoupledPatches(syncPar, nCellsUsingFace);
874 // See which patch to use for exposed internal faces.
875 label oldInternalPatchID = 0;
877 // Insert faces before which patch
878 label nextPatchID = oldPatches.size();
880 // old to new patches
881 labelList globalPatchMap(oldPatches.size());
884 label nbSize = oldPatches.size();
886 if (wantedPatchID == -1)
888 // Create 'oldInternalFaces' patch at the end (or before
890 // and put all exposed internal faces in there.
892 forAll(oldPatches, patchI)
894 if (isA<processorPolyPatch>(oldPatches[patchI]))
896 nextPatchID = patchI;
899 oldInternalPatchID++;
904 // adapt old to new patches for inserted patch
905 for (label oldPatchI = 0; oldPatchI < nextPatchID; oldPatchI++)
907 globalPatchMap[oldPatchI] = oldPatchI;
911 label oldPatchI = nextPatchID;
912 oldPatchI < oldPatches.size();
916 globalPatchMap[oldPatchI] = oldPatchI+1;
921 oldInternalPatchID = wantedPatchID;
922 nextPatchID = wantedPatchID+1;
924 // old to new patches
925 globalPatchMap = identity(oldPatches.size());
928 labelList boundaryPatchSizes(nbSize, 0);
931 // Make a global-to-local point map
932 labelList globalPointMap(oldPoints.size(), -1);
934 labelList globalFaceMap(oldFaces.size(), -1);
937 // 1. Pick up all preserved internal faces.
938 for (label oldFaceI = 0; oldFaceI < oldNInternalFaces; oldFaceI++)
940 if (nCellsUsingFace[oldFaceI] == 2)
942 globalFaceMap[oldFaceI] = faceI;
943 faceMap_[faceI++] = oldFaceI;
945 // Mark all points from the face
946 markPoints(oldFaces[oldFaceI], globalPointMap);
950 // These are all the internal faces in the mesh.
951 label nInternalFaces = faceI;
953 // 2. Boundary faces up to where we want to insert old internal faces
957 oldPatchI < oldPatches.size()
958 && oldPatchI < nextPatchID;
962 const polyPatch& oldPatch = oldPatches[oldPatchI];
964 label oldFaceI = oldPatch.start();
968 if (nCellsUsingFace[oldFaceI] == 1)
970 // Boundary face is kept.
972 // Mark face and increment number of points in set
973 globalFaceMap[oldFaceI] = faceI;
974 faceMap_[faceI++] = oldFaceI;
976 // Mark all points from the face
977 markPoints(oldFaces[oldFaceI], globalPointMap);
979 // Increment number of patch faces
980 boundaryPatchSizes[globalPatchMap[oldPatchI]]++;
986 // 3a. old internal faces that have become exposed.
987 for (label oldFaceI = 0; oldFaceI < oldNInternalFaces; oldFaceI++)
989 if (nCellsUsingFace[oldFaceI] == 1)
991 globalFaceMap[oldFaceI] = faceI;
992 faceMap_[faceI++] = oldFaceI;
994 // Mark all points from the face
995 markPoints(oldFaces[oldFaceI], globalPointMap);
997 // Increment number of patch faces
998 boundaryPatchSizes[oldInternalPatchID]++;
1002 // 3b. coupled patch faces that have become uncoupled.
1005 label oldFaceI = oldNInternalFaces;
1006 oldFaceI < oldFaces.size();
1010 if (nCellsUsingFace[oldFaceI] == 3)
1012 globalFaceMap[oldFaceI] = faceI;
1013 faceMap_[faceI++] = oldFaceI;
1015 // Mark all points from the face
1016 markPoints(oldFaces[oldFaceI], globalPointMap);
1018 // Increment number of patch faces
1019 boundaryPatchSizes[oldInternalPatchID]++;
1023 // 4. Remaining boundary faces
1026 label oldPatchI = nextPatchID;
1027 oldPatchI < oldPatches.size();
1031 const polyPatch& oldPatch = oldPatches[oldPatchI];
1033 label oldFaceI = oldPatch.start();
1035 forAll (oldPatch, i)
1037 if (nCellsUsingFace[oldFaceI] == 1)
1039 // Boundary face is kept.
1041 // Mark face and increment number of points in set
1042 globalFaceMap[oldFaceI] = faceI;
1043 faceMap_[faceI++] = oldFaceI;
1045 // Mark all points from the face
1046 markPoints(oldFaces[oldFaceI], globalPointMap);
1048 // Increment number of patch faces
1049 boundaryPatchSizes[globalPatchMap[oldPatchI]]++;
1055 if (faceI != nFacesInSet)
1059 "fvMeshSubset::setCellSubset(const labelList&"
1060 ", const label, const label, const bool)"
1061 ) << "Problem" << abort(FatalError);
1065 // Grab the points map
1066 label nPointsInSet = 0;
1068 forAll(globalPointMap, pointI)
1070 if (globalPointMap[pointI] != -1)
1075 pointMap_.setSize(nPointsInSet);
1079 forAll(globalPointMap, pointI)
1081 if (globalPointMap[pointI] != -1)
1083 pointMap_[nPointsInSet] = pointI;
1084 globalPointMap[pointI] = nPointsInSet;
1089 //Pout<< "Number of cells in new mesh : " << cellMap_.size() << endl;
1090 //Pout<< "Number of faces in new mesh : " << faceMap_.size() << endl;
1091 //Pout<< "Number of points in new mesh: " << pointMap_.size() << endl;
1094 pointField newPoints(pointMap_.size());
1096 label nNewPoints = 0;
1098 forAll (pointMap_, pointI)
1100 newPoints[nNewPoints] = oldPoints[pointMap_[pointI]];
1104 faceList newFaces(faceMap_.size());
1106 label nNewFaces = 0;
1108 // Make internal faces
1109 for (label faceI = 0; faceI < nInternalFaces; faceI++)
1111 const face& oldF = oldFaces[faceMap_[faceI]];
1113 face newF(oldF.size());
1117 newF[i] = globalPointMap[oldF[i]];
1120 newFaces[nNewFaces] = newF;
1125 // Make boundary faces. (different from internal since might need to be
1127 for (label faceI = nInternalFaces; faceI < faceMap_.size(); faceI++)
1129 label oldFaceI = faceMap_[faceI];
1131 face oldF = oldFaces[oldFaceI];
1133 // Turn the faces as necessary to point outwards
1134 if (baseMesh().isInternalFace(oldFaceI))
1136 // Was internal face. Possibly turned the wrong way round
1139 region[oldOwner[oldFaceI]] != currentRegion
1140 && region[oldNeighbour[oldFaceI]] == currentRegion
1143 oldF = oldFaces[oldFaceI].reverseFace();
1147 // Relabel vertices of the (possibly turned) face.
1148 face newF(oldF.size());
1152 newF[i] = globalPointMap[oldF[i]];
1155 newFaces[nNewFaces] = newF;
1162 cellList newCells(nCellsInSet);
1164 label nNewCells = 0;
1166 forAll (cellMap_, cellI)
1168 const labelList& oldC = oldCells[cellMap_[cellI]];
1170 labelList newC(oldC.size());
1174 newC[i] = globalFaceMap[oldC[i]];
1177 newCells[nNewCells] = cell(newC);
1183 // Note that mesh gets registered with same name as original mesh. This is
1184 // not proper but cannot be avoided since otherwise surfaceInterpolation
1185 // cannot find its fvSchemes (it will try to read e.g.
1186 // system/region0SubSet/fvSchemes)
1187 fvMeshSubsetPtr_.reset
1194 baseMesh().time().timeName(),
1199 xferMove(newPoints),
1202 syncPar // parallel synchronisation
1207 List<polyPatch*> newBoundary(nbSize);
1208 patchMap_.setSize(nbSize);
1209 label nNewPatches = 0;
1210 label patchStart = nInternalFaces;
1213 // For parallel: only remove patch if none of the processors has it.
1214 // This only gets done for patches before the one being inserted
1215 // (so patches < nextPatchID)
1217 // Get sum of patch sizes. Zero if patch can be deleted.
1218 labelList globalPatchSizes(boundaryPatchSizes);
1219 globalPatchSizes.setSize(nextPatchID);
1221 if (syncPar && Pstream::parRun())
1223 // Get patch names (up to nextPatchID)
1224 List<wordList> patchNames(Pstream::nProcs());
1225 patchNames[Pstream::myProcNo()] = oldPatches.names();
1226 patchNames[Pstream::myProcNo()].setSize(nextPatchID);
1227 Pstream::gatherList(patchNames);
1228 Pstream::scatterList(patchNames);
1230 // Get patch sizes (up to nextPatchID).
1231 // Note that up to nextPatchID the globalPatchMap is an identity so
1232 // no need to index through that.
1233 Pstream::listCombineGather(globalPatchSizes, plusEqOp<label>());
1234 Pstream::listCombineScatter(globalPatchSizes);
1236 // Now all processors have all the patchnames.
1237 // Decide: if all processors have the same patch names and size is zero
1238 // everywhere remove the patch.
1239 bool samePatches = true;
1241 for (label procI = 1; procI < patchNames.size(); procI++)
1243 if (patchNames[procI] != patchNames[0])
1245 samePatches = false;
1252 // Patchnames not sync on all processors so disable removal of
1253 // zero sized patches.
1254 globalPatchSizes = labelMax;
1263 label oldPatchI = 0;
1264 oldPatchI < oldPatches.size()
1265 && oldPatchI < nextPatchID;
1269 label newSize = boundaryPatchSizes[globalPatchMap[oldPatchI]];
1271 // Clone (even if 0 size)
1272 newBoundary[nNewPatches] = oldPatches[oldPatchI].clone
1274 fvMeshSubsetPtr_().boundaryMesh(),
1280 patchStart += newSize;
1281 patchMap_[nNewPatches] = oldPatchI; // compact patchMap
1287 if (wantedPatchID == -1)
1289 label oldInternalSize = boundaryPatchSizes[oldInternalPatchID];
1293 reduce(oldInternalSize, sumOp<label>());
1296 // Newly created patch so is at end. Check if any faces in it.
1297 if (oldInternalSize > 0)
1299 newBoundary[nNewPatches] = new emptyPolyPatch
1302 boundaryPatchSizes[oldInternalPatchID],
1305 fvMeshSubsetPtr_().boundaryMesh()
1308 //Pout<< " oldInternalFaces : "
1309 // << boundaryPatchSizes[oldInternalPatchID] << endl;
1311 // The index for the first patch is -1 as it originates from
1312 // the internal faces
1313 patchStart += boundaryPatchSizes[oldInternalPatchID];
1314 patchMap_[nNewPatches] = -1;
1323 label oldPatchI = nextPatchID;
1324 oldPatchI < oldPatches.size();
1328 label newSize = boundaryPatchSizes[globalPatchMap[oldPatchI]];
1330 // Patch still exists. Add it
1331 newBoundary[nNewPatches] = oldPatches[oldPatchI].clone
1333 fvMeshSubsetPtr_().boundaryMesh(),
1339 //Pout<< " " << oldPatches[oldPatchI].name() << " : "
1340 // << newSize << endl;
1342 patchStart += newSize;
1343 patchMap_[nNewPatches] = oldPatchI; // compact patchMap
1348 // Reset the patch lists
1349 newBoundary.setSize(nNewPatches);
1350 patchMap_.setSize(nNewPatches);
1353 // Add the fvPatches
1354 fvMeshSubsetPtr_().addFvPatches(newBoundary, syncPar);
1356 // Subset and add any zones
1361 void Foam::fvMeshSubset::setLargeCellSubset
1363 const labelHashSet& globalCellMap,
1364 const label patchID,
1368 labelList region(baseMesh().nCells(), 0);
1370 forAllConstIter (labelHashSet, globalCellMap, iter)
1372 region[iter.key()] = 1;
1374 setLargeCellSubset(region, 1, patchID, syncPar);
1378 const fvMesh& Foam::fvMeshSubset::subMesh() const
1382 return fvMeshSubsetPtr_();
1386 fvMesh& Foam::fvMeshSubset::subMesh()
1390 return fvMeshSubsetPtr_();
1394 const labelList& Foam::fvMeshSubset::pointMap() const
1402 const labelList& Foam::fvMeshSubset::faceMap() const
1410 const labelList& Foam::fvMeshSubset::cellMap() const
1418 const labelList& Foam::fvMeshSubset::patchMap() const
1426 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1428 } // End namespace Foam
1430 // ************************************************************************* //