59 for (
auto idx : locations)
79 if (selectedElements.
empty() || subsetMap.
empty())
86 const bitSet selected(nElems, selectedElements);
92 if (selected[subsetMap[i]])
104 if (selected[subsetMap[i]])
106 subsettedElements[
n] = i;
111 return subsettedElements;
124 <<
"Mesh is not subsetted!" <<
nl 134 void Foam::fvMeshSubset::calcFaceFlipMap()
const 137 const labelList& subToBaseCell = cellMap();
139 faceFlipMapPtr_.reset(
new labelList(subToBaseFace.size()));
140 auto& faceFlipMap = *faceFlipMapPtr_;
144 const label subInt = subMesh().nInternalFaces();
146 const labelList& subOwn = subMesh().faceOwner();
147 const labelList& own = baseMesh_.faceOwner();
149 for (label subFaceI = 0; subFaceI < subInt; ++subFaceI)
151 faceFlipMap[subFaceI] = subToBaseFace[subFaceI]+1;
153 for (label subFaceI = subInt; subFaceI < subOwn.size(); ++subFaceI)
155 const label faceI = subToBaseFace[subFaceI];
156 if (subToBaseCell[subOwn[subFaceI]] == own[faceI])
158 faceFlipMap[subFaceI] = faceI+1;
162 faceFlipMap[subFaceI] = -faceI-1;
168 void Foam::fvMeshSubset::doCoupledPatches
177 const polyBoundaryMesh& oldPatches = baseMesh().
boundaryMesh();
179 label nUncoupled = 0;
183 PstreamBuffers pBufs;
186 if (!nCellsUsingFace.empty())
188 for (
const polyPatch&
pp : oldPatches)
190 const auto* procPatch = isA<processorPolyPatch>(
pp);
194 const label nbrProci = procPatch->neighbProcNo();
196 UOPstream toNbr(nbrProci, pBufs);
198 SubList<label>(nCellsUsingFace,
pp.size(),
pp.start());
203 pBufs.finishedSends();
206 for (
const polyPatch&
pp : oldPatches)
208 const auto* procPatch = isA<processorPolyPatch>(
pp);
212 const label nbrProci = procPatch->neighbProcNo();
214 if (!pBufs.recvDataCount(nbrProci))
222 UIPstream fromNbr(nbrProci, pBufs);
223 fromNbr >> nbrCellsUsingFace;
226 if (!nCellsUsingFace.empty() && !nbrCellsUsingFace.empty())
234 nCellsUsingFace[
pp.start()+i] == 1
235 && nbrCellsUsingFace[i] == 0
240 nCellsUsingFace[
pp.start()+i] = 3;
250 for (
const polyPatch&
pp : oldPatches)
252 const cyclicPolyPatch* cpp = isA<cyclicPolyPatch>(
pp);
254 if (cpp && !nCellsUsingFace.empty())
256 const auto& cycPatch = *cpp;
260 label thisFacei = cycPatch.start() + i;
261 label otherFacei = cycPatch.transformGlobalFace(thisFacei);
265 nCellsUsingFace[thisFacei] == 1
266 && nCellsUsingFace[otherFacei] == 0
269 nCellsUsingFace[thisFacei] = 3;
278 reduce(nUncoupled, sumOp<label>());
283 Info<<
"Uncoupled " << nUncoupled <<
" faces on coupled patches. " 284 <<
"(processorPolyPatch, cyclicPolyPatch)" <<
endl;
289 void Foam::fvMeshSubset::subsetZones()
297 auto& newSubMesh = subMeshPtr_();
303 List<pointZone*>
pZones(pointZones.size());
307 const pointZone& pz = pointZones[zonei];
309 pZones[zonei] =
new pointZone
314 newSubMesh.pointZones()
325 List<faceZone*> fZones(faceZones.size());
329 const faceZone& fz = faceZones[zonei];
338 zone[fz[j]] = (fz.flipMap()[j] ? 1 : -1);
355 const label meshFacei =
faceMap()[subFacei];
356 if (zone[meshFacei] != 0)
358 subAddressing[nSub] = subFacei;
359 const label subOwner = subMesh().faceOwner()[subFacei];
360 const label baseOwner = baseMesh().
faceOwner()[meshFacei];
362 const bool sameOwner = (cellMap()[subOwner] == baseOwner);
363 const bool flip = (zone[meshFacei] == 1);
364 subFlipStatus[nSub] = (sameOwner == flip);
370 fZones[zonei] =
new faceZone
376 newSubMesh.faceZones()
385 List<cellZone*> cZones(cellZones.size());
389 const cellZone& cz = cellZones[zonei];
391 cZones[zonei] =
new cellZone
396 newSubMesh.cellZones()
401 newSubMesh.addZones(
pZones, fZones, cZones);
410 subMeshPtr_(nullptr),
411 faceFlipMapPtr_(nullptr),
430 const bitSet& selectedCells,
488 subMeshPtr_.reset(
nullptr);
489 faceFlipMapPtr_.reset(
nullptr);
513 subMeshPtr_.reset(std::move(subMeshPtr));
514 faceFlipMapPtr_.reset(
nullptr);
516 pointMap_ = std::move(pointMap);
518 cellMap_ = std::move(cellMap);
519 patchMap_ = std::move(patchMap);
532 const auto* basePointMeshPtr =
533 baseMesh_.thisDb().cfindObject<pointMesh>(pointMesh::typeName);
534 if (basePointMeshPtr)
536 DebugPout<<
"fvMeshSubset::reset(const Foam::zero) :" 537 <<
" Detected pointMesh" <<
endl;
551 baseMesh_.time().timeName(),
561 auto& newSubMesh = subMeshPtr_();
566 const polyBoundaryMesh& oldBoundary = baseMesh_.boundaryMesh();
567 const polyBoundaryMesh& newBoundary = newSubMesh.boundaryMesh();
571 patchMap_ =
identity(newPatches.size());
573 forAll(newPatches, patchi)
578 oldBoundary[patchi].clone
589 newSubMesh.addFvPatches(newPatches,
false);
594 if (basePointMeshPtr)
597 const auto& basePointMesh = *basePointMeshPtr;
598 const auto& oldPointBoundary = basePointMesh.boundary();
605 const_cast<pointBoundaryMesh&
>(newSubPointMesh.boundary());
608 pointPatchMap_ = patchMap_;
611 for (
const auto& oldPointPatch : oldPointBoundary)
613 const auto* mppPtr = isA<meshPointPatch>(oldPointPatch);
614 if (mppPtr && (newBoundary.findPatchID(mppPtr->name()) == -1))
616 newBoundary.push_back
630 pointPatchMap_.setSize(newBoundary.size(), -1);
640 const bitSet& selectedCells,
646 const auto* basePointMeshPtr =
647 baseMesh_.thisDb().cfindObject<
pointMesh>(pointMesh::typeName);
648 if (basePointMeshPtr)
650 DebugPout<<
"fvMeshSubset::reset(const bitSet&) :" 651 <<
" Detected pointMesh" <<
endl;
663 const polyBoundaryMesh& oldPatches = baseMesh().
boundaryMesh();
670 if (wantedPatchID == -1)
674 wantedPatchID = oldPatches.findPatchID(exposedPatchName);
676 else if (wantedPatchID < 0 || wantedPatchID >= oldPatches.size())
679 <<
"Non-existing patch index " << wantedPatchID <<
endl 680 <<
"Should be between 0 and " << oldPatches.size()-1
690 label len = cellMap_.
size();
694 i >= 0 && (cellMap_[i] >= oldCells.size());
700 cellMap_.resize(len);
716 label nFacesInSet = 0;
718 forAll(oldFaces, oldFacei)
720 bool faceUsed =
false;
722 if (selectedCells.
test(oldOwner[oldFacei]))
724 ++nCellsUsingFace[oldFacei];
731 && selectedCells.
test(oldNeighbour[oldFacei])
734 ++nCellsUsingFace[oldFacei];
743 faceMap_.resize(nFacesInSet);
746 doCoupledPatches(syncPar, nCellsUsingFace);
750 label oldInternalPatchID = 0;
753 label nextPatchID = oldPatches.size();
756 labelList globalPatchMap(oldPatches.size());
759 label nbSize = oldPatches.
size();
761 if (wantedPatchID == -1)
767 forAll(oldPatches, patchi)
769 if (isA<processorPolyPatch>(oldPatches[patchi]))
771 nextPatchID = patchi;
774 ++oldInternalPatchID;
780 for (label oldPatchi = 0; oldPatchi < nextPatchID; oldPatchi++)
782 globalPatchMap[oldPatchi] = oldPatchi;
786 label oldPatchi = nextPatchID;
787 oldPatchi < oldPatches.size();
791 globalPatchMap[oldPatchi] = oldPatchi+1;
796 oldInternalPatchID = wantedPatchID;
797 nextPatchID = wantedPatchID+1;
800 globalPatchMap =
identity(oldPatches.size());
807 labelList globalPointMap(oldPoints.size(), -1);
808 labelList globalFaceMap(oldFaces.size(), -1);
813 for (label oldFacei = 0; oldFacei < oldNInternalFaces; ++oldFacei)
815 if (nCellsUsingFace[oldFacei] == 2)
817 globalFaceMap[oldFacei] = facei;
818 faceMap_[facei++] = oldFacei;
821 markUsed(oldFaces[oldFacei], globalPointMap);
826 const label nInternalFaces = facei;
832 oldPatchi < oldPatches.size()
833 && oldPatchi < nextPatchID;
837 const polyPatch& oldPatch = oldPatches[oldPatchi];
839 label oldFacei = oldPatch.start();
843 if (nCellsUsingFace[oldFacei] == 1)
848 globalFaceMap[oldFacei] = facei;
849 faceMap_[facei++] = oldFacei;
852 markUsed(oldFaces[oldFacei], globalPointMap);
855 ++boundaryPatchSizes[globalPatchMap[oldPatchi]];
862 for (label oldFacei = 0; oldFacei < oldNInternalFaces; ++oldFacei)
864 if (nCellsUsingFace[oldFacei] == 1)
866 globalFaceMap[oldFacei] = facei;
867 faceMap_[facei++] = oldFacei;
870 markUsed(oldFaces[oldFacei], globalPointMap);
873 ++boundaryPatchSizes[oldInternalPatchID];
880 label oldFacei = oldNInternalFaces;
881 oldFacei < oldFaces.size();
885 if (nCellsUsingFace[oldFacei] == 3)
887 globalFaceMap[oldFacei] = facei;
888 faceMap_[facei++] = oldFacei;
891 markUsed(oldFaces[oldFacei], globalPointMap);
894 ++boundaryPatchSizes[oldInternalPatchID];
901 label oldPatchi = nextPatchID;
902 oldPatchi < oldPatches.size();
906 const polyPatch& oldPatch = oldPatches[oldPatchi];
908 label oldFacei = oldPatch.start();
912 if (nCellsUsingFace[oldFacei] == 1)
917 globalFaceMap[oldFacei] = facei;
918 faceMap_[facei++] = oldFacei;
921 markUsed(oldFaces[oldFacei], globalPointMap);
924 ++boundaryPatchSizes[globalPatchMap[oldPatchi]];
930 if (facei != nFacesInSet)
938 label nPointsInSet = 0;
940 forAll(globalPointMap, pointi)
942 if (globalPointMap[pointi] != -1)
947 pointMap_.setSize(nPointsInSet);
951 forAll(globalPointMap, pointi)
953 if (globalPointMap[pointi] != -1)
955 pointMap_[nPointsInSet] = pointi;
956 globalPointMap[pointi] = nPointsInSet;
982 auto iter = newFaces.
begin();
983 const auto& renumbering = globalPointMap;
986 for (label facei = 0; facei < nInternalFaces; ++facei)
988 face& newItem = *iter;
991 const face& oldItem = oldFaces[faceMap_[facei]];
994 newItem.
resize(oldItem.size());
998 newItem[i] = renumbering[oldItem[i]];
1003 for (label facei = nInternalFaces; facei < faceMap_.size(); ++facei)
1005 const label oldFacei = faceMap_[facei];
1007 face& newItem = *iter;
1010 const face oldItem =
1014 && selectedCells.
test(oldNeighbour[oldFacei])
1015 && !selectedCells.
test(oldOwner[oldFacei])
1018 ? oldFaces[oldFacei].reverseFace()
1019 : oldFaces[oldFacei]
1023 newItem.resize(oldItem.size());
1027 newItem[i] = renumbering[oldItem[i]];
1037 cellList newCells(cellMap_.size());
1039 auto iter = newCells.
begin();
1040 const auto& renumbering = globalFaceMap;
1042 for (
const label oldCelli : cellMap_)
1044 cell& newItem = *iter;
1047 const labelList& oldItem = oldCells[oldCelli];
1050 newItem.
resize(oldItem.size());
1054 newItem[i] = renumbering[oldItem[i]];
1072 baseMesh_.time().timeName(),
1078 std::move(newPoints),
1079 std::move(newFaces),
1080 std::move(newCells),
1087 patchMap_.resize(nbSize);
1088 label nNewPatches = 0;
1089 label patchStart = nInternalFaces;
1097 labelList globalPatchSizes(boundaryPatchSizes);
1098 globalPatchSizes.setSize(nextPatchID);
1116 bool samePatches =
true;
1122 samePatches =
false;
1140 label oldPatchi = 0;
1141 oldPatchi < oldPatches.size()
1142 && oldPatchi < nextPatchID;
1146 const label newSize = boundaryPatchSizes[globalPatchMap[oldPatchi]];
1148 if (oldInternalPatchID != oldPatchi)
1153 for (label patchFacei = 0; patchFacei < newSize; patchFacei++)
1155 const label facei = patchStart+patchFacei;
1156 const label oldFacei = faceMap_[facei];
1157 map[patchFacei] = oldPatches[oldPatchi].whichFace(oldFacei);
1163 oldPatches[oldPatchi].clone
1165 subMeshPtr_().boundaryMesh(),
1178 oldPatches[oldPatchi].clone
1180 subMeshPtr_().boundaryMesh(),
1188 patchStart += newSize;
1189 patchMap_[nNewPatches] = oldPatchi;
1195 label newInternalPatchID = -1;
1197 if (wantedPatchID == -1)
1199 label oldInternalSize = boundaryPatchSizes[oldInternalPatchID];
1203 reduce(oldInternalSize, sumOp<label>());
1207 if (oldInternalSize > 0)
1215 boundaryPatchSizes[oldInternalPatchID],
1218 subMeshPtr_().boundaryMesh(),
1219 emptyPolyPatch::typeName
1228 patchStart += boundaryPatchSizes[oldInternalPatchID];
1229 patchMap_[nNewPatches] = -1;
1230 newInternalPatchID = nNewPatches;
1239 label oldPatchi = nextPatchID;
1240 oldPatchi < oldPatches.size();
1244 const label newSize = boundaryPatchSizes[globalPatchMap[oldPatchi]];
1246 if (oldInternalPatchID != oldPatchi)
1251 for (label patchFacei = 0; patchFacei < newSize; patchFacei++)
1253 const label facei = patchStart+patchFacei;
1254 const label oldFacei = faceMap_[facei];
1255 map[patchFacei] = oldPatches[oldPatchi].whichFace(oldFacei);
1261 oldPatches[oldPatchi].clone
1263 subMeshPtr_().boundaryMesh(),
1276 oldPatches[oldPatchi].clone
1278 subMeshPtr_().boundaryMesh(),
1289 patchStart += newSize;
1290 patchMap_[nNewPatches] = oldPatchi;
1296 newBoundary.resize(nNewPatches);
1297 patchMap_.resize(nNewPatches);
1301 subMeshPtr_().addFvPatches(newBoundary, syncPar);
1307 if (basePointMeshPtr)
1310 const auto& basePointMesh = *basePointMeshPtr;
1311 const auto& oldPointBoundary = basePointMesh.boundary();
1317 pointPatchMap_ = patchMap_;
1320 const_cast<pointBoundaryMesh&
>(newSubPointMesh.boundary());
1324 labelList oldToNewPoints(baseMesh_.nPoints(), -1);
1327 oldToNewPoints[pointMap_[i]] = i;
1332 pointPatchMap_.setSize(newBoundary.size(), -1);
1334 for (
const auto& oldPointPatch : oldPointBoundary)
1336 const auto* mppPtr = isA<meshPointPatch>(oldPointPatch);
1337 if (mppPtr && (newBoundary.findPatchID(mppPtr->name()) == -1))
1339 const auto&
mp = mppPtr->meshPoints();
1340 DynamicList<label> subPointMap(
mp.size());
1346 subPointMap.append(i);
1350 pointPatchMap_.push_back(mppPtr->index());
1352 newBoundary.push_back
1371 label newPatchi = 0;
1372 forAll(newBoundary, patchi)
1376 patchi != newInternalPatchID
1377 && !isA<processorPointPatch>(newBoundary[patchi])
1380 oldToNew[patchi] = newPatchi++;
1383 if (newInternalPatchID != -1)
1385 oldToNew[newInternalPatchID] = newPatchi++;
1387 forAll(newBoundary, patchi)
1389 if (isA<processorPointPatch>(newBoundary[patchi]))
1391 oldToNew[patchi] = newPatchi++;
1394 newBoundary.reorder(oldToNew,
true);
1434 const label regioni,
void size(const label n)
Older name for setAddressableSize.
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with the type faceZone.
static word exposedPatchName
Name for exposed internal faces (default: oldInternalFaces)
List< cell > cellList
List of cell.
void resize(const label len)
Adjust allocated size of list.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual const labelList & faceNeighbour() const
Return face neighbour.
static FOAM_NO_DANGLING_REFERENCE const pointMesh & New(const polyMesh &mesh, Args &&... args)
Get existing or create MeshObject registered with typeName.
constexpr char nl
The newline '\n' character (0x0a)
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
bool empty() const noexcept
True if List is empty (ie, size() is zero)
labelList sortedToc() const
The indices of the on bits as a sorted labelList.
Ostream & endl(Ostream &os)
Add newline and flush stream.
static bool & parRun() noexcept
Test if this a parallel run.
const cellList & cells() const
Ignore writing from objectRegistry::writeObject()
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
bool isInternalFace(const label faceIndex) const noexcept
Return true if given face label is internal to the mesh.
UList< label > labelUList
A UList of labels.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
void reduce(T &value, [[maybe_unused]] BinaryOp bop, [[maybe_unused]] const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce)
virtual const pointField & points() const
Return raw points.
Mesh representing a set of points created from polyMesh.
#define forAll(list, i)
Loop across all elements in list.
List< face > faceList
List of faces.
PtrList< polyPatch > polyPatchList
Store lists of polyPatch as a PtrList.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
vectorField pointField
pointField is a vectorField.
void setSize(const label n)
Alias for resize()
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
bool checkHasSubMesh() const
FatalError if subset has not been performed.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
wordList patchNames(nPatches)
virtual const labelList & faceOwner() const
Return face owner.
void reset()
Reset subMesh and all maps. Same as clear()
label nInternalFaces() const noexcept
Number of internal faces.
ZoneMesh< pointZone, polyMesh > pointZoneMesh
A ZoneMesh with the type pointZone.
virtual const faceList & faces() const
Return raw faces.
errorManip< error > abort(error &err)
iterator begin() noexcept
Return an iterator to begin traversing the UList.
bool test(const label pos) const
Test for True value at specified position, never auto-vivify entries.
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
defineTypeNameAndDebug(combustionModel, 0)
Holds a reference to the original mesh (the baseMesh) and optionally to a subset of that mesh (the su...
static void allGatherList(UList< T > &values, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Gather data, but keep individual values separate. Uses MPI_Allgather or manual communication.
const pointZoneMesh & pointZones() const noexcept
Return point zone mesh.
fvMeshSubset(const fvMeshSubset &)=delete
No copy construct.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
limits reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL))
Mesh data needed to do the Finite Volume discretisation.
static labelList subsetSubset(const label nElems, const labelUList &selectedElements, const labelUList &subsetMap)
const cellZoneMesh & cellZones() const noexcept
Return cell zone mesh.
#define DebugPout
Report an information message using Foam::Pout.
messageStream Info
Information stream (stdout output on master, null elsewhere)
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
List< label > labelList
A List of labels.
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
bitSet create(const label n, const labelHashSet &locations, const bool on=true)
Create a bitSet with length n with the specified on locations.
static void listReduce(UList< T > &values, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce list elements (list must be equal size on all ranks), applying bop to each list element...
List< bool > boolList
A List of bools.
static const List< label > & null() noexcept
Return a null List (reference to a nullObject). Behaves like an empty List.
ZoneMesh< cellZone, polyMesh > cellZoneMesh
A ZoneMesh with the type cellZone.
const dimensionedScalar mp
Proton mass.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
IOporosityModelList pZones(mesh)
void clear()
Reset subMesh and all maps.
static constexpr const zero Zero
Global zero (0)