mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: renumberMesh: use renumberMethods library
This commit is contained in:
@ -2,6 +2,7 @@ EXE_INC = \
|
|||||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
|
-I$(LIB_SRC)/renumberMethods/lnInclude \
|
||||||
-I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude
|
-I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude
|
||||||
|
|
||||||
EXE_LIBS = \
|
EXE_LIBS = \
|
||||||
@ -9,4 +10,5 @@ EXE_LIBS = \
|
|||||||
-ldynamicMesh \
|
-ldynamicMesh \
|
||||||
-lfiniteVolume \
|
-lfiniteVolume \
|
||||||
-lgenericPatchFields \
|
-lgenericPatchFields \
|
||||||
|
-lrenumberMethods \
|
||||||
-ldecompositionMethods
|
-ldecompositionMethods
|
||||||
|
|||||||
@ -37,16 +37,51 @@ Description
|
|||||||
#include "ReadFields.H"
|
#include "ReadFields.H"
|
||||||
#include "volFields.H"
|
#include "volFields.H"
|
||||||
#include "surfaceFields.H"
|
#include "surfaceFields.H"
|
||||||
#include "bandCompression.H"
|
|
||||||
#include "faceSet.H"
|
|
||||||
#include "SortableList.H"
|
#include "SortableList.H"
|
||||||
#include "decompositionMethod.H"
|
#include "decompositionMethod.H"
|
||||||
#include "fvMeshSubset.H"
|
#include "renumberMethod.H"
|
||||||
#include "zeroGradientFvPatchFields.H"
|
#include "zeroGradientFvPatchFields.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
|
|
||||||
|
// Create named field from labelList for postprocessing
|
||||||
|
tmp<volScalarField> createScalarField
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const word& name,
|
||||||
|
const labelList& elems
|
||||||
|
)
|
||||||
|
{
|
||||||
|
tmp<volScalarField> 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
|
// Calculate band of matrix
|
||||||
label getBand(const labelList& owner, const labelList& neighbour)
|
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
|
// Determine upper-triangular face order
|
||||||
labelList regionBandCompression
|
labelList getFaceOrder
|
||||||
(
|
(
|
||||||
const fvMesh& mesh,
|
const primitiveMesh& mesh,
|
||||||
const labelList& cellToRegion
|
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(cellOrder, newCellI)
|
||||||
|
|
||||||
forAll(regionToCells, regionI)
|
|
||||||
{
|
{
|
||||||
Pout<< " region " << regionI << " starts at " << cellI << endl;
|
label oldCellI = cellOrder[newCellI];
|
||||||
|
|
||||||
// Per region do a reordering.
|
const cell& cFaces = mesh.cells()[oldCellI];
|
||||||
fvMeshSubset subsetter(mesh);
|
|
||||||
subsetter.setLargeCellSubset(cellToRegion, regionI);
|
|
||||||
const fvMesh& subMesh = subsetter.subMesh();
|
|
||||||
labelList subCellOrder(bandCompression(subMesh.cellCells()));
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Pout<< endl;
|
|
||||||
|
|
||||||
return cellOrder;
|
order.setSize(nbr.size());
|
||||||
|
sortedOrder(nbr, order);
|
||||||
|
|
||||||
|
forAll(order, i)
|
||||||
|
{
|
||||||
|
label index = order[i];
|
||||||
|
if (nbr[index] != -1)
|
||||||
|
{
|
||||||
|
oldToNewFace[cFaces[index]] = newFaceI++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
// Determine face order such that inside region faces are sorted
|
||||||
// upper-triangular but inbetween region faces are handled like boundary faces.
|
// upper-triangular but inbetween region faces are handled like boundary faces.
|
||||||
labelList regionFaceOrder
|
labelList getRegionFaceOrder
|
||||||
(
|
(
|
||||||
const primitiveMesh& mesh,
|
const primitiveMesh& mesh,
|
||||||
const labelList& cellOrder, // new to old cell
|
const labelList& cellOrder, // new to old cell
|
||||||
const labelList& cellToRegion // old cell to region
|
const labelList& cellToRegion // old cell to region
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Pout<< "Determining face order:" << endl;
|
//Pout<< "Determining face order:" << endl;
|
||||||
|
|
||||||
labelList reverseCellOrder(invert(cellOrder.size(), cellOrder));
|
labelList reverseCellOrder(invert(cellOrder.size(), cellOrder));
|
||||||
|
|
||||||
@ -131,8 +221,8 @@ labelList regionFaceOrder
|
|||||||
if (cellToRegion[oldCellI] != prevRegion)
|
if (cellToRegion[oldCellI] != prevRegion)
|
||||||
{
|
{
|
||||||
prevRegion = cellToRegion[oldCellI];
|
prevRegion = cellToRegion[oldCellI];
|
||||||
Pout<< " region " << prevRegion << " internal faces start at "
|
//Pout<< " region " << prevRegion << " internal faces start at "
|
||||||
<< newFaceI << endl;
|
// << newFaceI << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cell& cFaces = mesh.cells()[oldCellI];
|
const cell& cFaces = mesh.cells()[oldCellI];
|
||||||
@ -219,9 +309,9 @@ labelList regionFaceOrder
|
|||||||
|
|
||||||
if (prevKey != key)
|
if (prevKey != key)
|
||||||
{
|
{
|
||||||
Pout<< " faces inbetween region " << key/nRegions
|
//Pout<< " faces inbetween region " << key/nRegions
|
||||||
<< " and " << key%nRegions
|
// << " and " << key%nRegions
|
||||||
<< " start at " << newFaceI << endl;
|
// << " start at " << newFaceI << endl;
|
||||||
prevKey = key;
|
prevKey = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,14 +333,14 @@ labelList regionFaceOrder
|
|||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"polyDualMesh::getFaceOrder"
|
"getRegionFaceOrder"
|
||||||
"(const labelList&, const labelList&, const label) const"
|
"(const primitveMesh&, const labelList&, const labelList&)"
|
||||||
) << "Did not determine new position"
|
) << "Did not determine new position"
|
||||||
<< " for face " << faceI
|
<< " for face " << faceI
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Pout<< endl;
|
//Pout<< endl;
|
||||||
|
|
||||||
return invert(mesh.nFaces(), oldToNewFace);
|
return invert(mesh.nFaces(), oldToNewFace);
|
||||||
}
|
}
|
||||||
@ -365,10 +455,11 @@ autoPtr<mapPolyMesh> reorderMesh
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
argList::addBoolOption
|
argList::addOption
|
||||||
(
|
(
|
||||||
"blockOrder",
|
"blockSize",
|
||||||
"order cells into regions (using decomposition)"
|
"block size",
|
||||||
|
"order cells into blocks (using decomposition) before ordering"
|
||||||
);
|
);
|
||||||
argList::addBoolOption
|
argList::addBoolOption
|
||||||
(
|
(
|
||||||
@ -400,12 +491,23 @@ int main(int argc, char *argv[])
|
|||||||
# include "createNamedMesh.H"
|
# include "createNamedMesh.H"
|
||||||
const word oldInstance = mesh.pointsInstance();
|
const word oldInstance = mesh.pointsInstance();
|
||||||
|
|
||||||
const bool blockOrder = args.optionFound("blockOrder");
|
label blockSize = 0;
|
||||||
if (blockOrder)
|
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
|
<< " ordering faces into region-internal and region-external." << nl
|
||||||
<< endl;
|
<< 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");
|
const bool orderPoints = args.optionFound("orderPoints");
|
||||||
@ -432,6 +534,24 @@ int main(int argc, char *argv[])
|
|||||||
<< returnReduce(band, maxOp<label>()) << nl << endl;
|
<< returnReduce(band, maxOp<label>()) << nl << endl;
|
||||||
|
|
||||||
|
|
||||||
|
// Construct renumberMethod
|
||||||
|
IOdictionary renumberDict
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"renumberMeshDict",
|
||||||
|
runTime.system(),
|
||||||
|
mesh,
|
||||||
|
IOobject::MUST_READ_IF_MODIFIED,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
)
|
||||||
|
);
|
||||||
|
autoPtr<renumberMethod> renumberPtr = renumberMethod::New(renumberDict);
|
||||||
|
|
||||||
|
Info<< "Selecting renumberMethod " << renumberPtr().type() << endl;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Read parallel reconstruct maps
|
// Read parallel reconstruct maps
|
||||||
labelIOList cellProcAddressing
|
labelIOList cellProcAddressing
|
||||||
(
|
(
|
||||||
@ -522,13 +642,19 @@ int main(int argc, char *argv[])
|
|||||||
ReadFields(mesh, objects, stFlds);
|
ReadFields(mesh, objects, stFlds);
|
||||||
|
|
||||||
|
|
||||||
autoPtr<mapPolyMesh> map;
|
// From renumbering:
|
||||||
|
// - from new cell/face back to original cell/face
|
||||||
|
labelList cellOrder;
|
||||||
|
labelList faceOrder;
|
||||||
|
|
||||||
if (blockOrder)
|
if (blockSize > 0)
|
||||||
{
|
{
|
||||||
// Renumbering in two phases. Should be done in one so mapping of
|
// Renumbering in two phases. Should be done in one so mapping of
|
||||||
// fields is done correctly!
|
// fields is done correctly!
|
||||||
|
|
||||||
|
label nBlocks = mesh.nCells() / blockSize;
|
||||||
|
Info<< "nBlocks = " << nBlocks << endl;
|
||||||
|
|
||||||
// Read decomposePar dictionary
|
// Read decomposePar dictionary
|
||||||
IOdictionary decomposeDict
|
IOdictionary decomposeDict
|
||||||
(
|
(
|
||||||
@ -541,6 +667,8 @@ int main(int argc, char *argv[])
|
|||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
decomposeDict.set("numberOfSubdomains", nBlocks);
|
||||||
|
|
||||||
autoPtr<decompositionMethod> decomposePtr = decompositionMethod::New
|
autoPtr<decompositionMethod> decomposePtr = decompositionMethod::New
|
||||||
(
|
(
|
||||||
decomposeDict
|
decomposeDict
|
||||||
@ -556,80 +684,99 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
|
|
||||||
// For debugging: write out region
|
// For debugging: write out region
|
||||||
{
|
createScalarField
|
||||||
volScalarField cellDist
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
(
|
||||||
|
mesh,
|
||||||
"cellDist",
|
"cellDist",
|
||||||
runTime.timeName(),
|
cellToRegion
|
||||||
mesh,
|
)().write();
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
false
|
|
||||||
),
|
|
||||||
mesh,
|
|
||||||
dimensionedScalar("cellDist", dimless, 0),
|
|
||||||
zeroGradientFvPatchScalarField::typeName
|
|
||||||
);
|
|
||||||
|
|
||||||
forAll(cellToRegion, cellI)
|
|
||||||
{
|
|
||||||
cellDist[cellI] = cellToRegion[cellI];
|
|
||||||
}
|
|
||||||
|
|
||||||
cellDist.write();
|
|
||||||
|
|
||||||
Info<< nl << "Written decomposition as volScalarField to "
|
Info<< nl << "Written decomposition as volScalarField to "
|
||||||
<< cellDist.name() << " for use in postprocessing."
|
<< "cellDist for use in postprocessing."
|
||||||
<< nl << endl;
|
<< nl << endl;
|
||||||
|
|
||||||
|
|
||||||
|
// Find point per region
|
||||||
|
pointField regionPoints(nBlocks, vector::zero);
|
||||||
|
forAll(cellToRegion, cellI)
|
||||||
|
{
|
||||||
|
regionPoints[cellToRegion[cellI]] = mesh.cellCentres()[cellI];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use block based renumbering.
|
// Use block based renumbering.
|
||||||
//labelList cellOrder(bandCompression(mesh.cellCells()));
|
// Detemines old to new cell ordering
|
||||||
labelList cellOrder(regionBandCompression(mesh, cellToRegion));
|
labelList reverseCellOrder = renumberPtr().renumber
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
cellToRegion,
|
||||||
|
regionPoints
|
||||||
|
);
|
||||||
|
|
||||||
|
cellOrder = invert(mesh.nCells(), reverseCellOrder);
|
||||||
|
|
||||||
// Determine new to old face order with new cell numbering
|
// Determine new to old face order with new cell numbering
|
||||||
labelList faceOrder
|
faceOrder = getRegionFaceOrder
|
||||||
(
|
|
||||||
regionFaceOrder
|
|
||||||
(
|
(
|
||||||
mesh,
|
mesh,
|
||||||
cellOrder,
|
cellOrder,
|
||||||
cellToRegion
|
cellToRegion
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!overwrite)
|
|
||||||
{
|
|
||||||
runTime++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change the mesh.
|
|
||||||
map = reorderMesh(mesh, cellOrder, faceOrder);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Use built-in renumbering.
|
// Detemines old to new cell ordering
|
||||||
|
labelList reverseCellOrder = renumberPtr().renumber
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
mesh.cellCentres()
|
||||||
|
);
|
||||||
|
|
||||||
|
cellOrder = invert(mesh.nCells(), reverseCellOrder);
|
||||||
|
|
||||||
|
// Determine new to old face order with new cell numbering
|
||||||
|
faceOrder = getFaceOrder
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
cellOrder // new to old cell
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
polyTopoChange meshMod(mesh);
|
|
||||||
|
|
||||||
if (!overwrite)
|
if (!overwrite)
|
||||||
{
|
{
|
||||||
runTime++;
|
runTime++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Change the mesh.
|
// Change the mesh.
|
||||||
map = meshMod.changeMesh
|
autoPtr<mapPolyMesh> map = reorderMesh(mesh, cellOrder, faceOrder);
|
||||||
|
|
||||||
|
|
||||||
|
if (orderPoints)
|
||||||
|
{
|
||||||
|
polyTopoChange meshMod(mesh);
|
||||||
|
autoPtr<mapPolyMesh> pointOrderMap = meshMod.changeMesh
|
||||||
(
|
(
|
||||||
mesh,
|
mesh,
|
||||||
false, //inflate
|
false, //inflate
|
||||||
true, // parallel sync
|
true, //syncParallel
|
||||||
true, // cell ordering
|
false, //orderCells
|
||||||
orderPoints // point ordering
|
orderPoints //orderPoints
|
||||||
|
);
|
||||||
|
// Combine point reordering into map.
|
||||||
|
const_cast<labelList&>(map().pointMap()) = UIndirectList<label>
|
||||||
|
(
|
||||||
|
map().pointMap(),
|
||||||
|
pointOrderMap().pointMap()
|
||||||
|
)();
|
||||||
|
inplaceRenumber
|
||||||
|
(
|
||||||
|
pointOrderMap().reversePointMap(),
|
||||||
|
const_cast<labelList&>(map().reversePointMap())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Update fields
|
// Update fields
|
||||||
mesh.updateMesh(map);
|
mesh.updateMesh(map);
|
||||||
|
|
||||||
@ -767,6 +914,24 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (writeMaps)
|
if (writeMaps)
|
||||||
{
|
{
|
||||||
|
// For debugging: write out region
|
||||||
|
createScalarField
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
"origCellID",
|
||||||
|
map().cellMap()
|
||||||
|
)().write();
|
||||||
|
createScalarField
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
"cellID",
|
||||||
|
identity(mesh.nCells())
|
||||||
|
)().write();
|
||||||
|
Info<< nl << "Written current cellID and origCellID as volScalarField"
|
||||||
|
<< " for use in postprocessing."
|
||||||
|
<< nl << endl;
|
||||||
|
|
||||||
|
|
||||||
labelIOList
|
labelIOList
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
|
|||||||
@ -0,0 +1,51 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: dev |
|
||||||
|
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
note "mesh renumbering dictionary";
|
||||||
|
object renumberMeshDict;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
method CuthillMcKee;
|
||||||
|
//method manual;
|
||||||
|
//method random;
|
||||||
|
//method spring;
|
||||||
|
|
||||||
|
CuthillMcKeeCoeffs
|
||||||
|
{
|
||||||
|
// Reverse CuthillMcKee (RCM) or plain
|
||||||
|
reverse true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
manualCoeffs
|
||||||
|
{
|
||||||
|
// In system directory: old to new labelIOList
|
||||||
|
dataFile "cellMap";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
springCoeffs
|
||||||
|
{
|
||||||
|
// Maximum jump of cell indices. Is fraction of number of cells
|
||||||
|
maxCo 0.1;
|
||||||
|
|
||||||
|
// Limit the amount of movement; the fraction maxCo gets decreased
|
||||||
|
// with every iteration
|
||||||
|
freezeFraction 0.9;
|
||||||
|
|
||||||
|
// Maximum number of iterations
|
||||||
|
maxIter 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
114
src/renumberMethods/CuthillMcKeeRenumber/CuthillMcKeeRenumber.C
Normal file
114
src/renumberMethods/CuthillMcKeeRenumber/CuthillMcKeeRenumber.C
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "CuthillMcKeeRenumber.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "bandCompression.H"
|
||||||
|
#include "decompositionMethod.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(CuthillMcKeeRenumber, 0);
|
||||||
|
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
renumberMethod,
|
||||||
|
CuthillMcKeeRenumber,
|
||||||
|
dictionary
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::CuthillMcKeeRenumber::CuthillMcKeeRenumber(const dictionary& renumberDict)
|
||||||
|
:
|
||||||
|
renumberMethod(renumberDict),
|
||||||
|
reverse_
|
||||||
|
(
|
||||||
|
renumberDict.found(typeName + "Coeffs")
|
||||||
|
? Switch(renumberDict.subDict(typeName + "Coeffs").lookup("reverse"))
|
||||||
|
: Switch(true)
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::labelList Foam::CuthillMcKeeRenumber::renumber
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const pointField& points
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CompactListList<label> cellCells;
|
||||||
|
decompositionMethod::calcCellCells
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
identity(mesh.nCells()),
|
||||||
|
mesh.nCells(),
|
||||||
|
false, // local only
|
||||||
|
cellCells
|
||||||
|
);
|
||||||
|
|
||||||
|
labelList orderedToOld = bandCompression(cellCells());
|
||||||
|
|
||||||
|
if (reverse_)
|
||||||
|
{
|
||||||
|
Pout<< "** REverseing.." << endl;
|
||||||
|
for (label i = 0; i < orderedToOld.size()/2; i++)
|
||||||
|
{
|
||||||
|
Swap(orderedToOld[i], orderedToOld[orderedToOld.size()-i-1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return invert(orderedToOld.size(), orderedToOld);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::labelList Foam::CuthillMcKeeRenumber::renumber
|
||||||
|
(
|
||||||
|
const labelListList& cellCells,
|
||||||
|
const pointField& points
|
||||||
|
)
|
||||||
|
{
|
||||||
|
labelList orderedToOld = bandCompression(cellCells);
|
||||||
|
|
||||||
|
if (reverse_)
|
||||||
|
{
|
||||||
|
Pout<< "** REverseing.." << endl;
|
||||||
|
for (label i = 0; i < orderedToOld.size()/2; i++)
|
||||||
|
{
|
||||||
|
Swap(orderedToOld[i], orderedToOld[orderedToOld.size()-i-1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return invert(orderedToOld.size(), orderedToOld);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
Reference in New Issue
Block a user