92 const word standardRegionName(
"region");
108 forAll(patchesToRename, i)
115 patches.renamePatches(newNames,
true);
119 template<
class GeoField>
133 mesh.objectRegistry::lookupClass<GeoField>()
138 const GeoField&
fld = *iter();
160 tSubFld.ref().boundaryFieldRef()[
patchi] ==
161 tSubFld.ref().boundaryField()[
patchi].patchInternalField();
166 GeoField* subFld = tSubFld.ptr();
167 subFld->rename(
fld.name());
174 template<
class GeoField>
175 void subsetSurfaceFields
188 mesh.objectRegistry::lookupClass<GeoField>()
193 const GeoField&
fld = *iter();
211 GeoField* subFld = tSubFld.ptr();
212 subFld->rename(
fld.name());
225 if (cellRegion[celli] != regioni)
227 nonRegionCells.append(celli);
230 return nonRegionCells.shrink();
238 const label ownRegion,
239 const label neiRegion,
245 min(ownRegion, neiRegion),
246 max(ownRegion, neiRegion)
254 if (iter != regionsToSize.
end())
258 if (zoneFnd != iter().end())
273 zoneToSize.
insert(zoneID, 1);
274 regionsToSize.
insert(interface, zoneToSize);
282 const bool faceZonePatches,
290 if (zones.size() == 0)
294 else if (zones.size() == 1)
301 <<
"Face " << facei <<
" is in more than one zone " << zones
316 void getInterfaceSizes
319 const bool faceZonePatches,
342 if (ownRegion != neiRegion)
347 whichZone(
mesh, faceZonePatches, facei),
364 coupledRegion[i] = cellRegion[celli];
372 label neiRegion = coupledRegion[i];
374 if (ownRegion != neiRegion)
379 whichZone(
mesh, faceZonePatches, facei),
407 regionsToSize.
find(slaveIter.key());
409 if (masterIter != regionsToSize.
end())
417 label zoneID = iter.key();
418 label slaveSize = iter();
424 if (zoneFnd != masterInfo.
end())
426 zoneFnd() += slaveSize;
430 masterInfo.
insert(zoneID, slaveSize);
436 regionsToSize.
insert(slaveIter.key(), slaveIter());
450 toMaster << regionsToSize;
463 label nInterfaces = 0;
467 nInterfaces += info.
size();
470 interfaces.
setSize(nInterfaces);
471 interfaceNames.
setSize(nInterfaces);
472 interfaceNFaces.
setSize(nInterfaces);
478 const edge&
e = iter.key();
485 interfaces[nInterfaces] = iter.key();
486 label zoneID = infoIter.key();
491 name0 +
"_to_" + name1,
492 name1 +
"_to_" + name0
500 zoneName +
"_" + name0 +
"_to_" + name1,
501 zoneName +
"_" + name1 +
"_to_" + name0
504 interfaceNFaces[nInterfaces] = infoIter();
506 if (regionsToInterface.found(
e))
508 regionsToInterface[
e].insert(zoneID, nInterfaces);
513 zoneAndInterface.
insert(zoneID, nInterfaces);
514 regionsToInterface.insert(
e, zoneAndInterface);
536 if (ownRegion != neiRegion)
538 const label zoneID = whichZone(
mesh, faceZonePatches, facei);
542 min(ownRegion, neiRegion),
543 max(ownRegion, neiRegion)
546 faceInterfaces[facei] = regionsToInterface[interface][zoneID];
553 label neiRegion = coupledRegion[i];
555 if (ownRegion != neiRegion)
557 const label zoneID = whichZone(
mesh, faceZonePatches, facei);
561 min(ownRegion, neiRegion),
562 max(ownRegion, neiRegion)
565 faceInterfaces[facei] = regionsToInterface[interface][zoneID];
592 coupledRegion[i] = cellRegion[celli];
604 labelList cellsToRemove(getNonRegionCells(cellRegion, regioni));
609 labelList exposedFaces = cellRemover.getExposedFaces(cellsToRemove);
614 label facei = exposedFaces[i];
615 label interfacei = faceInterfaces[facei];
618 label neiRegion = -1;
633 label otherRegion = -1;
635 if (ownRegion == regioni && neiRegion != regioni)
637 otherRegion = neiRegion;
639 else if (ownRegion != regioni && neiRegion == regioni)
641 otherRegion = ownRegion;
646 <<
"Exposed face:" << facei
648 <<
" has owner region " << ownRegion
649 <<
" and neighbour region " << neiRegion
650 <<
" when handling region:" << regioni
655 if (regioni < otherRegion)
657 exposedPatchIDs[i] = interfacePatches[interfacei];
661 exposedPatchIDs[i] = interfacePatches[interfacei]+1;
666 cellRemover.setRefinement
692 void createAndWriteRegion
700 const word& newMeshInstance
703 Info<<
"Creating mesh for region \'"
720 forAll(interfacePatches, interfacei)
722 addedPatches.
insert(interfacePatches[interfacei]);
723 addedPatches.
insert(interfacePatches[interfacei]+1);
729 newMesh().topoChange(map());
732 #define SUBSET_VOL_FIELDS(Type, nullArg) \
733 subsetVolFields<VolField<Type>> \
742 #undef SUBSET_VOL_FIELDS
744 #define SUBSET_SURFACE_FIELDS(Type, nullArg) \
745 subsetSurfaceFields<SurfaceField<Type>> \
754 #undef SUBSET_SURFACE_FIELDS
775 if (!isA<processorPolyPatch>(pp))
782 sharedPatches.
append(newI);
794 if (isA<processorPolyPatch>(pp) && pp.
size())
796 oldToNew[
patchi] = newI++;
800 const label nNewPatches = newI;
805 if (oldToNew[
patchi] == -1)
807 oldToNew[
patchi] = newI++;
815 newMesh().setInstance(newMeshInstance);
836 forAll(interfaces, interI)
838 const edge&
e = interfaces[interI];
839 const Pair<word>& names = interfaceNames[interI];
870 return interfacePatches;
874 void getCellCellZoneis
885 label failCelli = -1;
890 const label cellZonei = cellZoneis[i];
896 const label celli = cz[czCelli];
898 if (cellCellZones[celli] == -1)
900 cellCellZones[celli] = cellZonei;
907 failCellZones.
append(cellCellZones[celli]);
909 if (failCelli == celli)
911 failCellZones.
append(cellZonei);
920 <<
"Cell " << failCelli <<
" with centre "
922 <<
" is multiple selected zones; ";
930 <<
". This is not allowed."
935 bFaceNbrCellZones = -1;
937 forAll(bFaceNbrCellZones, bFacei)
939 bFaceNbrCellZones[bFacei] =
950 const label nRegions,
952 const word& defaultRegion,
956 const scalar minOverlapFraction
961 regionCellZones.
setSize(nRegions, -1);
972 forAll(cellZoneNames, proci)
974 if (cellZoneNames[proci] != cellZoneNames[0])
977 <<
"cellZones not synchronised across processors." <<
endl
978 <<
"Master has cellZones " << cellZoneNames[0] <<
endl
979 <<
"Processor " << proci <<
" has cellZones "
1000 Info<<
"Trying to match regions to existing cell zones:" <<
endl;
1010 cellZoneCellInZone =
true;
1012 const label minOverlapNCells =
1013 max(1,
label(minOverlapFraction*cellZoneNCells[cellZonei]));
1017 forAll(cellRegion, celli)
1019 if (cellInZone[celli])
1021 nCellsInZone[cellRegion[celli]]++;
1030 if (nCellsInZone[regioni] < minOverlapNCells)
1038 forAll(cellRegion, celli)
1040 if (cellRegion[celli] == regioni && !cellInZone[celli])
1052 Info<<
" Matched region " << regioni
1054 <<
" with " << cellZoneNCells[cellZonei] <<
" cells "
1057 if (cellZoneRegions[cellZonei] == -1)
1059 cellZoneRegions[cellZonei] = regioni;
1061 regionCellZones[regioni] = cellZonei;
1065 cellZoneRegions[cellZonei] = -2;
1067 regionCellZones[regioni] = -1;
1071 cellZoneCellInZone =
false;
1075 forAll(cellZoneRegions, cellZonei)
1077 cellZoneRegions[cellZonei] =
max(cellZoneRegions[cellZonei], -1);
1081 label nUnmatchedRegions = 0;
1082 forAll(regionCellZones, regioni)
1084 if (regionCellZones[regioni] == -1)
1086 nUnmatchedRegions ++;
1090 if (nUnmatchedRegions)
1092 label nUnmatchedi = 1;
1095 forAll(regionCellZones, regioni)
1097 if (regionCellZones[regioni] == -1)
1101 nUnmatchedRegions == 1
1102 && defaultRegion != standardRegionName
1137 cellToRegion.write();
1139 Info<<
"Writing region index per cell as a "
1141 << cellToRegion.relativeObjectPath() <<
nl <<
endl;
1160 forAll(cellRegion, celli)
1162 cellToRegion[celli] = cellRegion[celli];
1164 cellToRegion.write();
1166 Info<<
"Writing region index per cell as a "
1168 << cellToRegion.relativeObjectPath() <<
nl <<
endl;
1173 template<
unsigned int NColumns>
1181 tableWs[j] =
max(tableWs[j],
table[i][j].size());
1207 int main(
int argc,
char *argv[])
1211 "splits mesh into multiple regions (detected by walking across faces)"
1219 "put disconnected parts of the mesh into separate regions"
1223 "disconnectedFaceSet",
1225 "specify a set of faces that are considered disconnected"
1231 "put cells in the specified zones into separate regions"
1237 "name given to regions which do not correspond to a named cell zone; "
1238 "default \"region\""
1243 "only write the largest region"
1249 "only write the region containing the given point"
1254 "do not write region meshes"
1259 "do not write region fields"
1263 "minOverlapFraction",
1265 "the minimum fraction a zone must overlap a cell-zone in order to "
1266 "be named after it and associated with it; default 0"
1271 "Use face zones to define the inter-region patches instead of creating "
1272 "a single inter-region patch per pair of regions"
1280 <<
"Neither -disconnected nor -cellZones specified, so no "
1281 <<
"criteria is available to identify regions" <<
exit(
FatalError);
1291 if (largest && insidePoint)
1294 <<
"-largest (i.e., write the region with most cells)"
1295 <<
" and -insidePoint (write the region containing the given "
1302 if (faceZonePatches)
1304 Info<<
"Using face zones to divide inter-region interfaces"
1305 <<
" into multiple patches" <<
nl <<
endl;
1309 Info<<
"Creating single patch per inter-region interface"
1313 const word defaultRegion
1329 if (cellZoneNames[i] ==
"all")
1335 const label cellZonei =
1338 if (cellZonei == -1)
1341 <<
"Cell zone \'" << cellZoneNames[i] <<
"\' not found. "
1346 if (cellZoneUsed[cellZonei])
continue;
1348 cellZoneisDyn.append(cellZonei);
1349 cellZoneUsed[cellZonei] =
true;
1351 cellZoneis.
transfer(cellZoneisDyn);
1365 const word disconnectedFaceSetName =
1370 faceSet blockedFaceSet(
mesh, disconnectedFaceSetName);
1374 <<
" blocked faces from set \'" << disconnectedFaceSetName
1379 faceBlockeds[iter.key()] =
true;
1388 cellZoneRegions[cellZoneis[i]] = i;
1391 labelList cellCellZones, bFaceNbrCellZones;
1402 const label ownerZone =
1404 const label neighbourZone =
1409 const label ownerRegion =
1410 ownerZone != -1 ? cellZoneRegions[ownerZone] : -1;
1411 const label neighbourRegion =
1412 neighbourZone != -1 ? cellZoneRegions[neighbourZone] : -1;
1414 faceBlockeds[facei] =
1415 faceBlockeds[facei] || ownerRegion != neighbourRegion;
1421 cellRegions.transfer(regions);
1442 cellZoneRegions[cellZoneis[i]] = i;
1445 regionCellZones[i] = cellZoneis[i];
1448 labelList cellCellZones, bFaceNbrCellZones;
1457 renumber(cellZoneRegions, cellCellZones, cellRegions);
1459 bool haveDefaultRegion =
false;
1460 forAll(cellRegions, celli)
1462 if (cellRegions[celli] == -1)
1464 cellRegions[celli] = cellZoneis.size();
1465 haveDefaultRegion =
true;
1470 if (haveDefaultRegion)
1473 regionCellZones.
append(-1);
1480 Info<<
"Only one region identified. Doing nothing." <<
nl <<
endl;
1488 forAll(cellRegions, celli)
1490 regionNCells[cellRegions[celli]] ++;
1493 forAll(regionNCells, regioni)
1502 table[0] = {
"Region",
"nCells",
"cellZone"};
1503 forAll(regionNCells, regioni)
1507 table[regioni + 1][2] =
1508 regionCellZones[regioni] == -1
1517 writeCellToRegion(
mesh, cellRegions);
1553 if (interfaces.
size())
1563 forAll(interfaces, interfacei)
1565 const edge&
e = interfaces[interfacei];
1567 table[interfacei + 1][0] = interfaceNames[interfacei][0];
1593 if (interfaces.
size())
1595 Info<<
"Adding interface patches" <<
nl <<
endl;
1622 Info<<
"Subsetting largest region " << regioni <<
" containing "
1623 << regionNCells[regioni] <<
" cells" <<
nl <<
endl;
1629 else if (regionCellZones[regioni] == -1)
1634 createAndWriteRegion
1642 (
overwrite ? oldInstance : runTime.name())
1645 else if (insidePoint)
1656 procCellRegion.
data = cellRegions[celli];
1661 if (procCellRegion.
proci != -1)
1663 Info<<
"Found point " << insidePoint
1664 <<
" in cell " << procCellRegion.
elementi;
1667 Info<<
" of processor " << procCellRegion.
proci;
1674 <<
"Did not find a cell containing the point " << insidePoint
1675 <<
". The bounding box of the mesh is " <<
mesh.
bounds()
1679 const label regioni = procCellRegion.
data;
1682 <<
" containing point " << insidePoint <<
nl <<
endl;
1688 else if (regionCellZones[regioni] == -1)
1693 createAndWriteRegion
1701 (
overwrite ? oldInstance : runTime.name())
1708 createAndWriteRegion
1716 (
overwrite ? oldInstance : runTime.name())
Istream and Ostream manipulators taking arguments.
Field reading functions for post-processing utilities.
graph_traits< Graph >::vertices_size_type size_type
#define forAll(list, i)
Loop across all elements in list.
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
wordList toc() const
Return the table of contents.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Map from edge (expressed as its endpoints) to value.
A 1D vector of objects of type <T> with a fixed size <Size>.
bool insert(const Key &key)
Insert a new entry.
An STL-conforming hash table.
label size() const
Return number of elements in table.
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
bool found(const Key &) const
Return true if hashedEntry is found in table.
List of IOobjects with searching and retrieving facilities.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
const word & name() const
Return name.
Input inter-processor communications stream.
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
void append(const T &)
Append an element at the end of the list.
void resize(const label)
Alias for setSize(const label)
void size(const label)
Override size to be inconsistent with allocated storage.
void setSize(const label)
Reset size of List.
Output inter-processor communications stream.
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
static void scatterList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Scatter data. Reverse of gatherList.
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
label findIndex(const word &key) const
Return the index of the given the key or -1 if not found.
void append(T *)
Append an element at the end of the list.
Struct for keeping processor, element (cell, face, point) and a piece of data. Used for finding minim...
A List with indirect addressing.
label size() const
Return the number of elements in the UList.
static int masterNo()
Process index of the master.
static bool master(const label communicator=0)
Am I the master process.
static int lastSlave(const label communicator=0)
Process index of last slave.
static label nProcs(const label communicator=0)
Number of processes in parallel run.
static int firstSlave()
Process index of first slave.
static bool & parRun()
Is this a parallel run?
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
label size() const
Return the number of elements in the UPtrList.
labelList whichZones(const label objectIndex) const
Given a global object index, return the list of zones it is in.
bool checkParallelSync(const bool report=false) const
Check whether all procs have all zones and in same order. Return.
static void addOption(const word &opt, const string ¶m="", const string &usage="")
Add to an option to validOptions with usage information.
static void addNote(const string &)
Add extra notes for the usage information.
T optionRead(const word &opt) const
Read a value from the named option.
static void addBoolOption(const word &opt, const string &usage="")
Add to a bool option to validOptions with usage information.
bool optionFound(const word &opt) const
Return true if the named option is found.
List< T > optionReadList(const word &opt) const
Read a List of values from the named option.
T optionLookupOrDefault(const word &opt, const T &deflt) const
Read a value from the named option if present.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Named list of cell indices representing a sub-set of the mesh.
const word & name() const
Return const reference to name.
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
static tmp< VolField< Type > > interpolate(const VolField< Type > &, const fvMesh &sMesh, const labelList &patchMap, const labelList &cellMap, const labelList &faceMap)
Map volume field.
Mesh data needed to do the Finite Volume discretisation.
const Time & time() const
Return the top-level database.
const word & name() const
Return reference to name.
void clearOut()
Clear all geometry and addressing.
const polyMesh & poly() const
Return reference to polyMesh.
Wall poly patch which can do interpolative mapping of values from another globally conforming poly pa...
label findCell(const point &p, const pointInCellShapes=pointInCellShapes::tets) const
Find the cell containing the given point.
static const meshSearch & New(const polyMesh &mesh, const pointInCellShapes=pointInCellShapes::tets)
Lookup or construct from mesh and cell decomposition option.
bool checkParallelSync(const bool report=false) const
Check whether all procs have all patches and in same order. Return.
Mesh consisting of general polyhedral cells.
const fileName & facesInstance() const
Return the current instance directory for faces.
const cellZoneList & cellZones() const
Return cell zones.
static word defaultRegion
Return the default region name.
const polyBoundaryMesh & boundary() const
Return boundary mesh.
virtual const faceList & faces() const
Return raw faces.
virtual const labelList & faceOwner() const
Return face owner.
const fileName & pointsInstance() const
Return the current instance directory for points.
const faceZoneList & faceZones() const
Return face zones.
virtual const labelList & faceNeighbour() const
Return face neighbour.
const boundBox & bounds() const
Return mesh bounding box.
A patch is a list of labels that address the faces in the global face list.
Direct mesh changes based on v1.3 polyTopoChange syntax.
const vectorField & faceCentres() const
label nInternalFaces() const
const vectorField & cellCentres() const
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
This class separates the mesh into distinct unconnected regions, each of which is then given a label ...
label elementi
Element index.
label proci
Processor index.
Given list of cells to remove insert all the topology changes.
A class for handling character strings derived from std::string.
A class for managing temporary objects.
A class for handling words, derived from string.
static const word null
An empty word.
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
int main(int argc, char *argv[])
gmvFile<< "tracers "<< particles.size()<< nl;{ pointField positions(particles.size());label particlei=0;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter) { positions[particlei++]=iter().position(mesh);} for(i=0;i< pTraits< point >::nComponents;i++) { forAll(positions, particlei) { gmvFile<< component(positions[particlei], i)<< ' ';} gmvFile<< nl;}}forAll(lagrangianScalarNames, i){ const word &name=lagrangianScalarNames[i];IOField< scalar > fld(IOobject(name, runTime.name(), lagrangian::cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
const fvPatchList & patches
Info<< "Calculating turbulent flame speed field St\n"<< endl;volScalarField St(IOobject("St", runTime.name(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), flameWrinkling->Xi() *Su);multivariateSurfaceInterpolationScheme< scalar >::fieldTable fields
const HashTable< dimensionSet > table
Table of dimensions.
errorManipArg< error, int > exit(error &err, const int errNo=1)
const dimensionSet & dimless
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
label findMax(const ListType &, const label start=0)
Find index of max element (and larger than given element).
Ostream & endl(Ostream &os)
Add newline and flush stream.
Omanip< int > setw(const int i)
String typeName(const std::type_info &info)
Return the un-mangled name given the standard type info.
const word & regionName(const solver ®ion)
ListType renumber(const labelUList &oldToNew, const ListType &)
Renumber the values (not the indices) of a list.
FOR_ALL_FIELD_TYPES(makeDimensionedPointFieldFunctions)
Ostream & incrIndent(Ostream &os)
Increment the indent level.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
void printTable(const List< wordList > &, List< string::size_type > &, Ostream &)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
Ostream & indent(Ostream &os)
Indent stream.
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
const Foam::wordList regionNames(args.optionFound("allRegions") ? runTime.regionNames() :wordList(1, args.optionFound("region") ? args.optionRead< word >("region") :polyMesh::defaultRegion))
Foam::argList args(argc, argv)
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Operator to take the first valid process.