54 #ifdef FOAM_USE_ZOLTAN 77 zeroGradientFvPatchScalarField::typeName
84 fld[celli] = elems[celli];
98 label diff = neighbour[facei] - owner[facei];
112 const bool calculateIntersect,
118 scalar& sumSqrIntersect
126 label own = owner[facei];
127 label nei = neighbour[facei];
131 cellBandwidth[nei] =
max(cellBandwidth[nei], diff);
134 bandwidth =
max(cellBandwidth);
138 forAll(cellBandwidth, celli)
140 profile += 1.0*cellBandwidth[celli];
143 sumSqrIntersect = 0.0;
144 if (calculateIntersect)
148 for (
label colI = celli-cellBandwidth[celli]; colI <= celli; colI++)
150 nIntersect[colI] += 1.0;
175 forAll(cellOrder, newCelli)
177 label oldCelli = cellOrder[newCelli];
179 const cell& cFaces = mesh.
cells()[oldCelli];
186 label facei = cFaces[i];
192 if (nbrCelli == newCelli)
194 nbrCelli = reverseCellOrder[mesh.
faceOwner()[facei]];
197 if (newCelli < nbrCelli)
220 label index = order[i];
221 if (nbr[index] != -1)
223 oldToNewFace[cFaces[index]] = newFacei++;
229 for (
label facei = newFacei; facei < mesh.
nFaces(); facei++)
231 oldToNewFace[facei] = facei;
236 forAll(oldToNewFace, facei)
238 if (oldToNewFace[facei] == -1)
241 <<
"Did not determine new position" <<
" for face " << facei
265 label prevRegion = -1;
267 forAll(cellOrder, newCelli)
269 label oldCelli = cellOrder[newCelli];
271 if (cellToRegion[oldCelli] != prevRegion)
273 prevRegion = cellToRegion[oldCelli];
276 const cell& cFaces = mesh.
cells()[oldCelli];
282 label facei = cFaces[i];
288 if (nbrCelli == newCelli)
290 nbrCelli = reverseCellOrder[mesh.
faceOwner()[facei]];
293 if (cellToRegion[oldCelli] != cellToRegion[cellOrder[nbrCelli]])
298 else if (newCelli < nbrCelli)
322 oldToNewFace[cFaces[nbr.indices()[i]]] = newFacei++;
328 label nRegions =
max(cellToRegion)+1;
338 if (ownRegion != neiRegion)
341 min(ownRegion, neiRegion)*nRegions
342 +
max(ownRegion, neiRegion);
351 label key = sortKey[i];
363 oldToNewFace[sortKey.indices()[i]] = newFacei++;
368 for (
label facei = newFacei; facei < mesh.
nFaces(); facei++)
370 oldToNewFace[facei] = facei;
375 forAll(oldToNewFace, facei)
377 if (oldToNewFace[facei] == -1)
380 <<
"Did not determine new position" 381 <<
" for face " << facei
423 forAll(newNeighbour, facei)
425 label own = newOwner[facei];
426 label nei = newNeighbour[facei];
430 newFaces[facei].flip();
431 Swap(newOwner[facei], newNeighbour[facei]);
432 flipFaceFlux.insert(facei);
446 oldPatchNMeshPoints[
patchi] = patches[
patchi].nPoints();
452 NullObjectMove<pointField>(),
473 label oldFacei = fZone[i];
474 newAddressing[i] = reverseFaceOrder[oldFacei];
475 if (flipFaceFlux.found(newAddressing[i]))
477 newFlipMap[i] = !fZone.
flipMap()[i];
481 newFlipMap[i] = fZone.
flipMap()[i];
554 Info<<
"Determining cell order:" <<
endl;
558 label nRegions =
max(cellToRegion)+1;
564 forAll(regionToCells, regionI)
566 Info<<
" region " << regionI <<
" starts at " << celli <<
endl;
574 subsetter.setLargeCellSubset(cellToRegion, regionI);
576 const fvMesh& subMesh = subsetter.subMesh();
587 const labelList& cellMap = subsetter.cellMap();
591 cellOrder[celli++] = cellMap[subCellOrder[i]];
602 int main(
int argc,
char *argv[])
606 "Renumber mesh to minimise bandwidth" 616 "calculate the rms of the frontwidth" 621 "do not update fields" 626 runTime.functionObjects().off();
630 #ifdef FOAM_USE_ZOLTAN 631 Info<<
"renumberMesh built with zoltan support." << nl <<
endl;
632 (void)zoltanRenumber::typeName;
641 runTime.setTime(Times[startTime], startTime);
653 scalar sumSqrIntersect;
677 <<
"Before renumbering :" << nl
678 <<
" band : " << band << nl
679 <<
" profile : " << profile <<
nl;
683 Info<<
" rms frontwidth : " << rmsFrontwidth <<
nl;
688 bool sortCoupledFaceCells =
false;
689 bool writeMaps =
false;
690 bool orderPoints =
false;
692 bool renumberSets =
true;
700 renumberDictPtr.
reset 704 const dictionary& renumberDict = renumberDictPtr();
710 "sortCoupledFaceCells",
713 if (sortCoupledFaceCells)
715 Info<<
"Sorting cells on coupled boundaries to be last." << nl
722 Info<<
"Ordering cells into regions of size " << blockSize
723 <<
" (using decomposition);" 724 <<
" ordering faces into region-internal and region-external." 727 if (blockSize < 0 || blockSize >= mesh.
nCells())
730 <<
"Block size " << blockSize
731 <<
" should be positive integer" 732 <<
" and less than the number of cells in the mesh." 740 Info<<
"Ordering points into internal and boundary points." << nl
744 renumberDict.
lookup(
"writeMaps") >> writeMaps;
747 Info<<
"Writing renumber maps (new to old) to polyMesh." << nl
755 Info<<
"Using default renumberMethod." << nl <<
endl;
760 Info<<
"Selecting renumberMethod " << renumberPtr().type() << nl <<
endl;
769 "cellProcAddressing",
782 "faceProcAddressing",
783 mesh.facesInstance(),
794 "pointProcAddressing",
795 mesh.pointsInstance(),
807 if (fields)
Info<<
"Reading geometric fields" << nl <<
endl;
825 label nBlocks = mesh.nCells()/blockSize;
826 Info<<
"nBlocks = " << nBlocks <<
endl;
829 dictionary decomposeDict(renumberDictPtr().subDict(
"blockCoeffs"));
830 decomposeDict.set(
"numberOfSubdomains", nBlocks);
842 decomposePtr().decompose
860 Info<< nl <<
"Written decomposition as volScalarField to " 861 <<
"cellDist for use in postprocessing." 865 cellOrder = regionRenumber(renumberPtr(), mesh, cellToRegion);
868 faceOrder = getRegionFaceOrder
878 cellOrder = renumberPtr().renumber
884 if (sortCoupledFaceCells)
893 if (pbm[
patchi].coupled())
906 if (pbm[
patchi].coupled())
911 label celli = faceCells[i];
913 if (reverseCellOrder[celli] != -1)
915 bndCells[nBndCells] = celli;
916 bndCellMap[nBndCells++] = reverseCellOrder[celli];
917 reverseCellOrder[celli] = -1;
923 bndCellMap.setSize(nBndCells);
930 labelList newReverseCellOrder(mesh.nCells(), -1);
932 label sortedI = mesh.nCells();
935 label origCelli = bndCells[order[i]];
936 newReverseCellOrder[origCelli] = --sortedI;
939 Info<<
"Ordered all " << nBndCells <<
" cells with a coupled face" 940 <<
" to the end of the cell list, starting at " << sortedI
945 forAll(cellOrder, newCelli)
947 label origCelli = cellOrder[newCelli];
948 if (newReverseCellOrder[origCelli] == -1)
950 newReverseCellOrder[origCelli] = sortedI++;
955 cellOrder =
invert(mesh.nCells(), newReverseCellOrder);
960 faceOrder = getFaceOrder
994 pointOrderMap().pointMap()
999 pointOrderMap().reversePointMap(),
1000 const_cast<labelList&>(map().reversePointMap())
1006 mesh.topoChange(map);
1011 cellProcAddressing.headerOk()
1012 && cellProcAddressing.size() == mesh.nCells()
1015 Info<<
"Renumbering processor cell decomposition map " 1016 << cellProcAddressing.name() <<
endl;
1025 faceProcAddressing.headerOk()
1026 && faceProcAddressing.size() == mesh.nFaces()
1029 Info<<
"Renumbering processor face decomposition map " 1030 << faceProcAddressing.name() <<
endl;
1041 label facei = iter.key();
1042 label masterFacei = faceProcAddressing[facei];
1044 faceProcAddressing[facei] = -masterFacei;
1046 if (masterFacei == 0)
1055 pointProcAddressing.headerOk()
1056 && pointProcAddressing.size() == mesh.nPoints()
1059 Info<<
"Renumbering processor point decomposition map " 1060 << pointProcAddressing.name() <<
endl;
1070 if (map().hasMotionPoints())
1072 mesh.setPoints(map().preMotionPoints());
1079 scalar sumSqrIntersect;
1085 mesh.faceNeighbour(),
1098 )/mesh.globalData().nTotalCells()
1101 Info<<
"After renumbering :" << nl
1102 <<
" band : " << band << nl
1103 <<
" profile : " << profile <<
nl;
1108 Info<<
" rms frontwidth : " << rmsFrontwidth <<
nl;
1127 mesh.nInternalPoints(),
1138 mesh.nInternalEdges(),
1143 mesh.nInternal0Edges(),
1148 mesh.nInternal1Edges(),
1152 Info<<
"Points:" << nl
1153 <<
" total : " << nTotPoints << nl
1154 <<
" internal: " << nTotIntPoints << nl
1155 <<
" boundary: " << nTotPoints-nTotIntPoints << nl
1157 <<
" total : " << nTotEdges << nl
1158 <<
" internal: " << nTotIntEdges << nl
1159 <<
" internal using 0 boundary points: " 1160 << nTotInt0Edges << nl
1161 <<
" internal using 1 boundary points: " 1162 << nTotInt1Edges-nTotInt0Edges << nl
1163 <<
" internal using 2 boundary points: " 1164 << nTotIntEdges-nTotInt1Edges << nl
1165 <<
" boundary: " << nTotEdges-nTotIntEdges << nl
1172 mesh.setInstance(oldInstance);
1175 Info<<
"Writing mesh to " << mesh.facesInstance() <<
endl;
1179 if (cellProcAddressing.headerOk())
1181 cellProcAddressing.instance() = mesh.facesInstance();
1182 if (cellProcAddressing.size() == mesh.nCells())
1184 cellProcAddressing.
write();
1189 const fileName fName(cellProcAddressing.filePath());
1192 Info<<
"Deleting inconsistent processor cell decomposition" 1193 <<
" map " << fName <<
endl;
1199 if (faceProcAddressing.headerOk())
1201 faceProcAddressing.instance() = mesh.facesInstance();
1202 if (faceProcAddressing.size() == mesh.nFaces())
1204 faceProcAddressing.write();
1208 const fileName fName(faceProcAddressing.filePath());
1211 Info<<
"Deleting inconsistent processor face decomposition" 1212 <<
" map " << fName <<
endl;
1218 if (pointProcAddressing.headerOk())
1220 pointProcAddressing.instance() = mesh.facesInstance();
1221 if (pointProcAddressing.size() == mesh.nPoints())
1223 pointProcAddressing.write();
1227 const fileName fName(pointProcAddressing.filePath());
1230 Info<<
"Deleting inconsistent processor point decomposition" 1231 <<
" map " << fName <<
endl;
1254 Info<< nl <<
"Written current cellID and origCellID as volScalarField" 1255 <<
" for use in postprocessing." 1263 mesh.facesInstance(),
1278 mesh.facesInstance(),
1293 mesh.facesInstance(),
1317 Info<<
"Renumbering cellSets:" <<
endl;
1322 cs.topoChange(map());
1323 cs.instance() = mesh.facesInstance();
1333 Info<<
"Renumbering faceSets:" <<
endl;
1338 fs.topoChange(map());
1339 fs.instance() = mesh.facesInstance();
1349 Info<<
"Renumbering pointSets:" <<
endl;
1354 ps.topoChange(map());
1355 ps.instance() = mesh.facesInstance();
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
ListType renumber(const labelUList &oldToNew, const ListType &)
Renumber the values (not the indices) of a list.
List< labelList > labelListList
A List of labelList.
virtual labelList renumber(const pointField &) const
Return the order in which cells need to be visited, i.e.
scalar diff(const triad &A, const triad &B)
Return a quantity of the difference between two triads.
#define forAll(list, i)
Loop across all elements in list.
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
virtual Ostream & write(const char)=0
Write character.
virtual void resetAddressing(const labelUList &, const boolList &)
Reset addressing and flip map (clearing demand-driven data)
void sortedOrder(const UList< T > &, labelList &order)
Generate the (stable) sort order for the list.
A class for handling file names.
void inplaceRenumber(const labelUList &oldToNew, ListType &)
Inplace renumber the values of a list.
List of IOobjects with searching and retrieving facilities.
errorManipArg< error, int > exit(error &err, const int errNo=1)
const fileName & facesInstance() const
Return the current instance directory for faces.
void reset(T *=nullptr)
If object pointer already set, delete object and set to given.
const meshCellZones & cellZones() const
Return cell zones.
A list of keyword definitions, which are a keyword followed by any number of values (e...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
label nInternalFaces() const
virtual const labelList & faceNeighbour() const
Return face neighbour.
A list that is sorted upon construction or when explicitly requested with the sort() method...
Cell-face mesh analysis engine.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
labelListList invertOneToMany(const label len, const labelUList &)
Invert one-to-many map. Unmapped elements will be size 0.
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
void size(const label)
Override size to be inconsistent with allocated storage.
const boolList & flipMap() const
Return face flip map.
static tmp< GeometricField< scalar, fvPatchField, volMesh > > New(const word &name, const Internal &, const PtrList< fvPatchField< scalar >> &)
Return a temporary field constructed from name,.
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
bool optionFound(const word &opt) const
Return true if the named option is found.
static autoPtr< renumberMethod > New(const dictionary &renumberDict)
Return a reference to the selected renumbering method.
label nTotalCells() const
Return total number of cells in decomposed mesh.
#define forAllReverse(list, i)
Reverse loop across all elements in list.
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
const cellList & cells() const
Field reading functions for post-processing utilities.
const dimensionSet dimless
IOdictionary systemDict(const word &dictName, const argList &args, const objectRegistry &ob, const word ®ionName=polyMesh::defaultRegion)
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
virtual const labelList & faceNeighbour() const =0
Face face-neighbour addressing.
Abstract base class for renumbering.
vectorField pointField
pointField is a vectorField.
const fileName & pointsInstance() const
Return the current instance directory for points.
labelList invert(const label len, const labelUList &)
Invert one-to-one map. Unmapped elements will be -1.
A class for handling words, derived from string.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Cuthill-McKee renumbering.
virtual const labelList & faceOwner() const
Return face owner.
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
static autoPtr< decompositionMethod > NewDecomposer(const dictionary &decompositionDict)
Return a reference to the selected decomposition method.
const globalMeshData & globalData() const
Return parallel info.
static const label labelMax
List< label > labelList
A List of labels.
virtual const faceList & faces() const
Return raw faces.
const vectorField & cellCentres() const
errorManip< error > abort(error &err)
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
ListType reorder(const labelUList &oldToNew, const ListType &)
Reorder the elements (indices, not values) of a list.
void resetPrimitives(pointField &&points, faceList &&faces, labelList &&owner, labelList &&neighbour, const labelList &patchSizes, const labelList &patchStarts, const bool validBoundary=true)
Reset mesh primitive data. Assumes all patch info correct.
Post-processing mesh subset tool. Given the original mesh and the list of selected cells...
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Internal & ref()
Return a reference to the dimensioned internal field.
label size() const
Return the number of elements in the UPtrList.
void setSize(const label)
Reset size of List.
static bool & parRun()
Is this a parallel run?
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
A cell is defined as a list of faces with extra functionality.
A collection of cell labels.
const meshFaceZones & faceZones() const
Return face zones.
Mesh data needed to do the Finite Volume discretisation.
A List with indirect addressing.
Direct mesh changes based on v1.3 polyTopoChange syntax.
virtual const labelList & faceOwner() const =0
Face face-owner addressing.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Mesh consisting of general polyhedral cells.
static void addBoolOption(const word &opt, const string &usage="")
Add to a bool option to validOptions with usage information.
A subset of mesh faces organised as a primitive patch.
static void addNote(const string &)
Add extra notes for the usage information.
A class for managing temporary objects.
bool rm(const fileName &)
Remove a file, returning true if successful otherwise false.
Foam::argList args(argc, argv)
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
void clearAddressing()
Clear addressing.
IOList< label > labelIOList
Label container classes.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.