From d5268bf30cd5150a3a9aaf4f41c64926a96d364e Mon Sep 17 00:00:00 2001 From: mattijs Date: Thu, 8 Dec 2011 16:28:32 +0000 Subject: [PATCH] ENH: renumberMesh: use renumberMethods library --- .../manipulation/renumberMesh/Make/options | 2 + .../manipulation/renumberMesh/renumberMesh.C | 367 +++++++++++++----- .../renumberMesh/renumberMeshDict | 51 +++ .../CuthillMcKeeRenumber.C | 114 ++++++ 4 files changed, 433 insertions(+), 101 deletions(-) create mode 100644 applications/utilities/mesh/manipulation/renumberMesh/renumberMeshDict create mode 100644 src/renumberMethods/CuthillMcKeeRenumber/CuthillMcKeeRenumber.C diff --git a/applications/utilities/mesh/manipulation/renumberMesh/Make/options b/applications/utilities/mesh/manipulation/renumberMesh/Make/options index b5e293282a..2981cf30be 100644 --- a/applications/utilities/mesh/manipulation/renumberMesh/Make/options +++ b/applications/utilities/mesh/manipulation/renumberMesh/Make/options @@ -2,6 +2,7 @@ EXE_INC = \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/renumberMethods/lnInclude \ -I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude EXE_LIBS = \ @@ -9,4 +10,5 @@ EXE_LIBS = \ -ldynamicMesh \ -lfiniteVolume \ -lgenericPatchFields \ + -lrenumberMethods \ -ldecompositionMethods diff --git a/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C b/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C index 8d9b0c91eb..4bb6512a35 100644 --- a/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C +++ b/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C @@ -37,16 +37,51 @@ Description #include "ReadFields.H" #include "volFields.H" #include "surfaceFields.H" -#include "bandCompression.H" -#include "faceSet.H" #include "SortableList.H" #include "decompositionMethod.H" -#include "fvMeshSubset.H" +#include "renumberMethod.H" #include "zeroGradientFvPatchFields.H" using namespace Foam; +// Create named field from labelList for postprocessing +tmp createScalarField +( + const fvMesh& mesh, + const word& name, + const labelList& elems +) +{ + tmp tfld + ( + new volScalarField + ( + IOobject + ( + name, + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::AUTO_WRITE, + false + ), + mesh, + dimensionedScalar("zero", dimless, 0), + zeroGradientFvPatchScalarField::typeName + ) + ); + volScalarField& fld = tfld(); + + forAll(fld, cellI) + { + fld[cellI] = elems[cellI]; + } + + return tfld; +} + + // Calculate band of matrix label getBand(const labelList& owner, const labelList& neighbour) { @@ -65,56 +100,111 @@ label getBand(const labelList& owner, const labelList& neighbour) } -// Return new to old cell numbering -labelList regionBandCompression +// Determine upper-triangular face order +labelList getFaceOrder ( - const fvMesh& mesh, - const labelList& cellToRegion + const primitiveMesh& mesh, + const labelList& cellOrder // new to old cell ) { - Pout<< "Determining cell order:" << endl; + labelList reverseCellOrder(invert(cellOrder.size(), cellOrder)); - labelList cellOrder(cellToRegion.size()); + labelList oldToNewFace(mesh.nFaces(), -1); - label nRegions = max(cellToRegion)+1; + label newFaceI = 0; - labelListList regionToCells(invertOneToMany(nRegions, cellToRegion)); + labelList nbr; + labelList order; - label cellI = 0; - - forAll(regionToCells, regionI) + forAll(cellOrder, newCellI) { - Pout<< " region " << regionI << " starts at " << cellI << endl; + label oldCellI = cellOrder[newCellI]; - // Per region do a reordering. - fvMeshSubset subsetter(mesh); - subsetter.setLargeCellSubset(cellToRegion, regionI); - const fvMesh& subMesh = subsetter.subMesh(); - labelList subCellOrder(bandCompression(subMesh.cellCells())); + const cell& cFaces = mesh.cells()[oldCellI]; - const labelList& cellMap = subsetter.cellMap(); + // Neighbouring cells + nbr.setSize(cFaces.size()); - forAll(subCellOrder, i) + forAll(cFaces, i) { - cellOrder[cellI++] = cellMap[subCellOrder[i]]; + label faceI = cFaces[i]; + + if (mesh.isInternalFace(faceI)) + { + // Internal face. Get cell on other side. + label nbrCellI = reverseCellOrder[mesh.faceNeighbour()[faceI]]; + if (nbrCellI == newCellI) + { + nbrCellI = reverseCellOrder[mesh.faceOwner()[faceI]]; + } + + if (newCellI < nbrCellI) + { + // CellI is master + nbr[i] = nbrCellI; + } + else + { + // nbrCell is master. Let it handle this face. + nbr[i] = -1; + } + } + else + { + // External face. Do later. + nbr[i] = -1; + } + } + + order.setSize(nbr.size()); + sortedOrder(nbr, order); + + forAll(order, i) + { + label index = order[i]; + if (nbr[index] != -1) + { + oldToNewFace[cFaces[index]] = newFaceI++; + } } } - Pout<< endl; - return cellOrder; + // Leave patch faces intact. + for (label faceI = newFaceI; faceI < mesh.nFaces(); faceI++) + { + oldToNewFace[faceI] = faceI; + } + + + // Check done all faces. + forAll(oldToNewFace, faceI) + { + if (oldToNewFace[faceI] == -1) + { + FatalErrorIn + ( + "getFaceOrder" + "(const primitiveMesh&, const labelList&, const labelList&)" + ) << "Did not determine new position" + << " for face " << faceI + << abort(FatalError); + } + } + + return invert(mesh.nFaces(), oldToNewFace); } // Determine face order such that inside region faces are sorted // upper-triangular but inbetween region faces are handled like boundary faces. -labelList regionFaceOrder +labelList getRegionFaceOrder ( const primitiveMesh& mesh, const labelList& cellOrder, // new to old cell const labelList& cellToRegion // old cell to region ) { - Pout<< "Determining face order:" << endl; + //Pout<< "Determining face order:" << endl; labelList reverseCellOrder(invert(cellOrder.size(), cellOrder)); @@ -131,8 +221,8 @@ labelList regionFaceOrder if (cellToRegion[oldCellI] != prevRegion) { prevRegion = cellToRegion[oldCellI]; - Pout<< " region " << prevRegion << " internal faces start at " - << newFaceI << endl; + //Pout<< " region " << prevRegion << " internal faces start at " + // << newFaceI << endl; } const cell& cFaces = mesh.cells()[oldCellI]; @@ -219,9 +309,9 @@ labelList regionFaceOrder if (prevKey != key) { - Pout<< " faces inbetween region " << key/nRegions - << " and " << key%nRegions - << " start at " << newFaceI << endl; + //Pout<< " faces inbetween region " << key/nRegions + // << " and " << key%nRegions + // << " start at " << newFaceI << endl; prevKey = key; } @@ -243,14 +333,14 @@ labelList regionFaceOrder { FatalErrorIn ( - "polyDualMesh::getFaceOrder" - "(const labelList&, const labelList&, const label) const" + "getRegionFaceOrder" + "(const primitveMesh&, const labelList&, const labelList&)" ) << "Did not determine new position" << " for face " << faceI << abort(FatalError); } } - Pout<< endl; + //Pout<< endl; return invert(mesh.nFaces(), oldToNewFace); } @@ -365,10 +455,11 @@ autoPtr reorderMesh int main(int argc, char *argv[]) { - argList::addBoolOption + argList::addOption ( - "blockOrder", - "order cells into regions (using decomposition)" + "blockSize", + "block size", + "order cells into blocks (using decomposition) before ordering" ); argList::addBoolOption ( @@ -400,12 +491,23 @@ int main(int argc, char *argv[]) # include "createNamedMesh.H" const word oldInstance = mesh.pointsInstance(); - const bool blockOrder = args.optionFound("blockOrder"); - if (blockOrder) + label blockSize = 0; + args.optionReadIfPresent("blockSize", blockSize, 0); + + if (blockSize > 0) { - Info<< "Ordering cells into regions (using decomposition);" + Info<< "Ordering cells into regions of size " << blockSize + << " (using decomposition);" << " ordering faces into region-internal and region-external." << nl << endl; + + if (blockSize < 0 || blockSize >= mesh.nCells()) + { + FatalErrorIn(args.executable()) + << "Block size " << blockSize << " should be positive integer" + << " and less than the number of cells in the mesh." + << exit(FatalError); + } } const bool orderPoints = args.optionFound("orderPoints"); @@ -432,6 +534,24 @@ int main(int argc, char *argv[]) << returnReduce(band, maxOp