mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: multiLevel decomposition method.
This commit is contained in:
@ -3,5 +3,6 @@ geomDecomp/geomDecomp.C
|
||||
simpleGeomDecomp/simpleGeomDecomp.C
|
||||
hierarchGeomDecomp/hierarchGeomDecomp.C
|
||||
manualDecomp/manualDecomp.C
|
||||
multiLevelDecomp/multiLevelDecomp.C
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/libdecompositionMethods
|
||||
|
||||
@ -37,7 +37,6 @@ namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(decompositionMethod, 0);
|
||||
defineRunTimeSelectionTable(decompositionMethod, dictionary);
|
||||
defineRunTimeSelectionTable(decompositionMethod, dictionaryMesh);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
@ -71,57 +70,45 @@ Foam::autoPtr<Foam::decompositionMethod> Foam::decompositionMethod::New
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::decompositionMethod> Foam::decompositionMethod::New
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
)
|
||||
{
|
||||
const word methodType(decompositionDict.lookup("method"));
|
||||
|
||||
Info<< "Selecting decompositionMethod " << methodType << endl;
|
||||
|
||||
dictionaryMeshConstructorTable::iterator cstrIter =
|
||||
dictionaryMeshConstructorTablePtr_->find(methodType);
|
||||
|
||||
if (cstrIter == dictionaryMeshConstructorTablePtr_->end())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"decompositionMethod::New"
|
||||
"(const dictionary& decompositionDict, "
|
||||
"const polyMesh& mesh)"
|
||||
) << "Unknown decompositionMethod "
|
||||
<< methodType << nl << nl
|
||||
<< "Valid decompositionMethods are : " << endl
|
||||
<< dictionaryMeshConstructorTablePtr_->sortedToc()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<decompositionMethod>(cstrIter()(decompositionDict, mesh));
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::decompositionMethod::decompose
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const pointField& points
|
||||
)
|
||||
{
|
||||
scalarField weights(0);
|
||||
scalarField weights(points.size(), 1.0);
|
||||
|
||||
return decompose(points, weights);
|
||||
return decompose(mesh, points, weights);
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::decompositionMethod::decompose
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const labelList& fineToCoarse,
|
||||
const pointField& coarsePoints,
|
||||
const scalarField& coarseWeights
|
||||
)
|
||||
{
|
||||
CompactListList<label> coarseCellCells;
|
||||
calcCellCells
|
||||
(
|
||||
mesh,
|
||||
fineToCoarse,
|
||||
coarsePoints.size(),
|
||||
coarseCellCells
|
||||
);
|
||||
|
||||
// Decompose based on agglomerated points
|
||||
labelList coarseDistribution(decompose(coarsePoints, coarseWeights));
|
||||
labelList coarseDistribution
|
||||
(
|
||||
decompose
|
||||
(
|
||||
coarseCellCells(),
|
||||
coarsePoints,
|
||||
coarseWeights
|
||||
)
|
||||
);
|
||||
|
||||
// Rework back into decomposition for original mesh_
|
||||
labelList fineDistribution(fineToCoarse.size());
|
||||
@ -137,22 +124,20 @@ Foam::labelList Foam::decompositionMethod::decompose
|
||||
|
||||
Foam::labelList Foam::decompositionMethod::decompose
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const labelList& fineToCoarse,
|
||||
const pointField& coarsePoints
|
||||
)
|
||||
{
|
||||
// Decompose based on agglomerated points
|
||||
labelList coarseDistribution(decompose(coarsePoints));
|
||||
scalarField cWeights(coarsePoints.size(), 1.0);
|
||||
|
||||
// Rework back into decomposition for original mesh_
|
||||
labelList fineDistribution(fineToCoarse.size());
|
||||
|
||||
forAll(fineDistribution, i)
|
||||
{
|
||||
fineDistribution[i] = coarseDistribution[fineToCoarse[i]];
|
||||
}
|
||||
|
||||
return fineDistribution;
|
||||
return decompose
|
||||
(
|
||||
mesh,
|
||||
fineToCoarse,
|
||||
coarsePoints,
|
||||
cWeights
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -162,57 +147,12 @@ Foam::labelList Foam::decompositionMethod::decompose
|
||||
const pointField& cc
|
||||
)
|
||||
{
|
||||
scalarField cWeights(0);
|
||||
scalarField cWeights(cc.size(), 1.0);
|
||||
|
||||
return decompose(globalCellCells, cc, cWeights);
|
||||
}
|
||||
|
||||
|
||||
void Foam::decompositionMethod::calcCellCells
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const labelList& fineToCoarse,
|
||||
const label nCoarse,
|
||||
labelListList& cellCells
|
||||
)
|
||||
{
|
||||
if (fineToCoarse.size() != mesh.nCells())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"decompositionMethod::calcCellCells"
|
||||
"(const labelList&, labelListList&) const"
|
||||
) << "Only valid for mesh agglomeration." << exit(FatalError);
|
||||
}
|
||||
|
||||
List<DynamicList<label> > dynCellCells(nCoarse);
|
||||
|
||||
forAll(mesh.faceNeighbour(), faceI)
|
||||
{
|
||||
label own = fineToCoarse[mesh.faceOwner()[faceI]];
|
||||
label nei = fineToCoarse[mesh.faceNeighbour()[faceI]];
|
||||
|
||||
if (own != nei)
|
||||
{
|
||||
if (findIndex(dynCellCells[own], nei) == -1)
|
||||
{
|
||||
dynCellCells[own].append(nei);
|
||||
}
|
||||
if (findIndex(dynCellCells[nei], own) == -1)
|
||||
{
|
||||
dynCellCells[nei].append(own);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cellCells.setSize(dynCellCells.size());
|
||||
forAll(dynCellCells, coarseI)
|
||||
{
|
||||
cellCells[coarseI].transfer(dynCellCells[coarseI]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Return the minimum face between two cells. Only relevant for
|
||||
// cells with multiple faces inbetween.
|
||||
Foam::label Foam::decompositionMethod::masterFace
|
||||
@ -250,208 +190,209 @@ Foam::label Foam::decompositionMethod::masterFace
|
||||
}
|
||||
|
||||
|
||||
void Foam::decompositionMethod::calcCSR
|
||||
//void Foam::decompositionMethod::calcCSR
|
||||
//(
|
||||
// const polyMesh& mesh,
|
||||
// List<int>& adjncy,
|
||||
// List<int>& xadj
|
||||
//)
|
||||
//{
|
||||
// const polyBoundaryMesh& pbm = mesh.boundaryMesh();
|
||||
//
|
||||
// // Make Metis CSR (Compressed Storage Format) storage
|
||||
// // adjncy : contains neighbours (= edges in graph)
|
||||
// // xadj(celli) : start of information in adjncy for celli
|
||||
//
|
||||
//
|
||||
// // Count unique faces between cells
|
||||
// // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// labelList nFacesPerCell(mesh.nCells(), 0);
|
||||
//
|
||||
// // Internal faces
|
||||
// for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
|
||||
// {
|
||||
// label own = mesh.faceOwner()[faceI];
|
||||
// label nei = mesh.faceNeighbour()[faceI];
|
||||
//
|
||||
// if (faceI == masterFace(mesh, own, nei))
|
||||
// {
|
||||
// nFacesPerCell[own]++;
|
||||
// nFacesPerCell[nei]++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Coupled faces. Only cyclics done.
|
||||
// HashSet<edge, Hash<edge> > cellPair(mesh.nFaces()-mesh.nInternalFaces());
|
||||
//
|
||||
// forAll(pbm, patchI)
|
||||
// {
|
||||
// if
|
||||
// (
|
||||
// isA<cyclicPolyPatch>(pbm[patchI])
|
||||
// && refCast<const cyclicPolyPatch>(pbm[patchI]).owner()
|
||||
// )
|
||||
// {
|
||||
// const cyclicPolyPatch& cycPatch = refCast<const cyclicPolyPatch>
|
||||
// (
|
||||
// pbm[patchI]
|
||||
// );
|
||||
//
|
||||
// const unallocLabelList& faceCells = cycPatch.faceCells();
|
||||
// const unallocLabelList& nbrCells =
|
||||
// cycPatch.neighbPatch().faceCells();
|
||||
//
|
||||
// forAll(faceCells, facei)
|
||||
// {
|
||||
// label own = faceCells[facei];
|
||||
// label nei = nbrCells[facei];
|
||||
//
|
||||
// if (cellPair.insert(edge(own, nei)))
|
||||
// {
|
||||
// nFacesPerCell[own]++;
|
||||
// nFacesPerCell[nei]++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// // Size tables
|
||||
// // ~~~~~~~~~~~
|
||||
//
|
||||
// // Sum nFacesPerCell
|
||||
// xadj.setSize(mesh.nCells()+1);
|
||||
//
|
||||
// label nConnections = 0;
|
||||
//
|
||||
// for (label cellI = 0; cellI < mesh.nCells(); cellI++)
|
||||
// {
|
||||
// xadj[cellI] = nConnections;
|
||||
// nConnections += nFacesPerCell[cellI];
|
||||
// }
|
||||
// xadj[mesh.nCells()] = nConnections;
|
||||
// adjncy.setSize(nConnections);
|
||||
//
|
||||
//
|
||||
//
|
||||
// // Fill tables
|
||||
// // ~~~~~~~~~~~
|
||||
//
|
||||
// nFacesPerCell = 0;
|
||||
//
|
||||
// // Internal faces
|
||||
// for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
|
||||
// {
|
||||
// label own = mesh.faceOwner()[faceI];
|
||||
// label nei = mesh.faceNeighbour()[faceI];
|
||||
//
|
||||
// if (faceI == masterFace(mesh, own, nei))
|
||||
// {
|
||||
// adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
||||
// adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Coupled faces. Only cyclics done.
|
||||
// cellPair.clear();
|
||||
// forAll(pbm, patchI)
|
||||
// {
|
||||
// if
|
||||
// (
|
||||
// isA<cyclicPolyPatch>(pbm[patchI])
|
||||
// && refCast<const cyclicPolyPatch>(pbm[patchI]).owner()
|
||||
// )
|
||||
// {
|
||||
// const cyclicPolyPatch& cycPatch = refCast<const cyclicPolyPatch>
|
||||
// (
|
||||
// pbm[patchI]
|
||||
// );
|
||||
//
|
||||
// const unallocLabelList& faceCells = cycPatch.faceCells();
|
||||
// const unallocLabelList& nbrCells =
|
||||
// cycPatch.neighbPatch().faceCells();
|
||||
//
|
||||
// forAll(faceCells, facei)
|
||||
// {
|
||||
// label own = faceCells[facei];
|
||||
// label nei = nbrCells[facei];
|
||||
//
|
||||
// if (cellPair.insert(edge(own, nei)))
|
||||
// {
|
||||
// adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
||||
// adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//
|
||||
//// From cell-cell connections to Metis format (like CompactListList)
|
||||
//void Foam::decompositionMethod::calcCSR
|
||||
//(
|
||||
// const labelListList& cellCells,
|
||||
// List<int>& adjncy,
|
||||
// List<int>& xadj
|
||||
//)
|
||||
//{
|
||||
// labelHashSet nbrCells;
|
||||
//
|
||||
// // Count number of internal faces
|
||||
// label nConnections = 0;
|
||||
//
|
||||
// forAll(cellCells, coarseI)
|
||||
// {
|
||||
// nbrCells.clear();
|
||||
//
|
||||
// const labelList& cCells = cellCells[coarseI];
|
||||
//
|
||||
// forAll(cCells, i)
|
||||
// {
|
||||
// if (nbrCells.insert(cCells[i]))
|
||||
// {
|
||||
// nConnections++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Create the adjncy array as twice the size of the total number of
|
||||
// // internal faces
|
||||
// adjncy.setSize(nConnections);
|
||||
//
|
||||
// xadj.setSize(cellCells.size()+1);
|
||||
//
|
||||
//
|
||||
// // Fill in xadj
|
||||
// // ~~~~~~~~~~~~
|
||||
// label freeAdj = 0;
|
||||
//
|
||||
// forAll(cellCells, coarseI)
|
||||
// {
|
||||
// xadj[coarseI] = freeAdj;
|
||||
//
|
||||
// nbrCells.clear();
|
||||
//
|
||||
// const labelList& cCells = cellCells[coarseI];
|
||||
//
|
||||
// forAll(cCells, i)
|
||||
// {
|
||||
// if (nbrCells.insert(cCells[i]))
|
||||
// {
|
||||
// adjncy[freeAdj++] = cCells[i];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// xadj[cellCells.size()] = freeAdj;
|
||||
//}
|
||||
|
||||
|
||||
void Foam::decompositionMethod::calcCellCells
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
List<int>& adjncy,
|
||||
List<int>& xadj
|
||||
)
|
||||
{
|
||||
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
|
||||
|
||||
// Make Metis CSR (Compressed Storage Format) storage
|
||||
// adjncy : contains neighbours (= edges in graph)
|
||||
// xadj(celli) : start of information in adjncy for celli
|
||||
|
||||
|
||||
// Count unique faces between cells
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
labelList nFacesPerCell(mesh.nCells(), 0);
|
||||
|
||||
// Internal faces
|
||||
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
|
||||
{
|
||||
label own = mesh.faceOwner()[faceI];
|
||||
label nei = mesh.faceNeighbour()[faceI];
|
||||
|
||||
if (faceI == masterFace(mesh, own, nei))
|
||||
{
|
||||
nFacesPerCell[own]++;
|
||||
nFacesPerCell[nei]++;
|
||||
}
|
||||
}
|
||||
|
||||
// Coupled faces. Only cyclics done.
|
||||
HashSet<edge, Hash<edge> > cellPair(mesh.nFaces()-mesh.nInternalFaces());
|
||||
|
||||
forAll(pbm, patchI)
|
||||
{
|
||||
if
|
||||
(
|
||||
isA<cyclicPolyPatch>(pbm[patchI])
|
||||
&& refCast<const cyclicPolyPatch>(pbm[patchI]).owner()
|
||||
)
|
||||
{
|
||||
const cyclicPolyPatch& cycPatch = refCast<const cyclicPolyPatch>
|
||||
(
|
||||
pbm[patchI]
|
||||
);
|
||||
|
||||
const unallocLabelList& faceCells = cycPatch.faceCells();
|
||||
const unallocLabelList& nbrCells =
|
||||
cycPatch.neighbPatch().faceCells();
|
||||
|
||||
forAll(faceCells, facei)
|
||||
{
|
||||
label own = faceCells[facei];
|
||||
label nei = nbrCells[facei];
|
||||
|
||||
if (cellPair.insert(edge(own, nei)))
|
||||
{
|
||||
nFacesPerCell[own]++;
|
||||
nFacesPerCell[nei]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Size tables
|
||||
// ~~~~~~~~~~~
|
||||
|
||||
// Sum nFacesPerCell
|
||||
xadj.setSize(mesh.nCells()+1);
|
||||
|
||||
label nConnections = 0;
|
||||
|
||||
for (label cellI = 0; cellI < mesh.nCells(); cellI++)
|
||||
{
|
||||
xadj[cellI] = nConnections;
|
||||
nConnections += nFacesPerCell[cellI];
|
||||
}
|
||||
xadj[mesh.nCells()] = nConnections;
|
||||
adjncy.setSize(nConnections);
|
||||
|
||||
|
||||
|
||||
// Fill tables
|
||||
// ~~~~~~~~~~~
|
||||
|
||||
nFacesPerCell = 0;
|
||||
|
||||
// Internal faces
|
||||
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
|
||||
{
|
||||
label own = mesh.faceOwner()[faceI];
|
||||
label nei = mesh.faceNeighbour()[faceI];
|
||||
|
||||
if (faceI == masterFace(mesh, own, nei))
|
||||
{
|
||||
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
||||
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
||||
}
|
||||
}
|
||||
|
||||
// Coupled faces. Only cyclics done.
|
||||
cellPair.clear();
|
||||
forAll(pbm, patchI)
|
||||
{
|
||||
if
|
||||
(
|
||||
isA<cyclicPolyPatch>(pbm[patchI])
|
||||
&& refCast<const cyclicPolyPatch>(pbm[patchI]).owner()
|
||||
)
|
||||
{
|
||||
const cyclicPolyPatch& cycPatch = refCast<const cyclicPolyPatch>
|
||||
(
|
||||
pbm[patchI]
|
||||
);
|
||||
|
||||
const unallocLabelList& faceCells = cycPatch.faceCells();
|
||||
const unallocLabelList& nbrCells =
|
||||
cycPatch.neighbPatch().faceCells();
|
||||
|
||||
forAll(faceCells, facei)
|
||||
{
|
||||
label own = faceCells[facei];
|
||||
label nei = nbrCells[facei];
|
||||
|
||||
if (cellPair.insert(edge(own, nei)))
|
||||
{
|
||||
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
||||
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// From cell-cell connections to Metis format (like CompactListList)
|
||||
void Foam::decompositionMethod::calcCSR
|
||||
(
|
||||
const labelListList& cellCells,
|
||||
List<int>& adjncy,
|
||||
List<int>& xadj
|
||||
)
|
||||
{
|
||||
labelHashSet nbrCells;
|
||||
|
||||
// Count number of internal faces
|
||||
label nConnections = 0;
|
||||
|
||||
forAll(cellCells, coarseI)
|
||||
{
|
||||
nbrCells.clear();
|
||||
|
||||
const labelList& cCells = cellCells[coarseI];
|
||||
|
||||
forAll(cCells, i)
|
||||
{
|
||||
if (nbrCells.insert(cCells[i]))
|
||||
{
|
||||
nConnections++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the adjncy array as twice the size of the total number of
|
||||
// internal faces
|
||||
adjncy.setSize(nConnections);
|
||||
|
||||
xadj.setSize(cellCells.size()+1);
|
||||
|
||||
|
||||
// Fill in xadj
|
||||
// ~~~~~~~~~~~~
|
||||
label freeAdj = 0;
|
||||
|
||||
forAll(cellCells, coarseI)
|
||||
{
|
||||
xadj[coarseI] = freeAdj;
|
||||
|
||||
nbrCells.clear();
|
||||
|
||||
const labelList& cCells = cellCells[coarseI];
|
||||
|
||||
forAll(cCells, i)
|
||||
{
|
||||
if (nbrCells.insert(cCells[i]))
|
||||
{
|
||||
adjncy[freeAdj++] = cCells[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
xadj[cellCells.size()] = freeAdj;
|
||||
}
|
||||
|
||||
|
||||
void Foam::decompositionMethod::calcDistributedCSR
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
List<int>& adjncy,
|
||||
List<int>& xadj
|
||||
const labelList& agglom,
|
||||
const label nCoarse,
|
||||
CompactListList<label>& cellCells
|
||||
)
|
||||
{
|
||||
// Create global cell numbers
|
||||
@ -459,14 +400,6 @@ void Foam::decompositionMethod::calcDistributedCSR
|
||||
|
||||
globalIndex globalCells(mesh.nCells());
|
||||
|
||||
|
||||
//
|
||||
// Make Metis Distributed CSR (Compressed Storage Format) storage
|
||||
// adjncy : contains cellCells (= edges in graph)
|
||||
// xadj(celli) : start of information in adjncy for celli
|
||||
//
|
||||
|
||||
|
||||
const labelList& faceOwner = mesh.faceOwner();
|
||||
const labelList& faceNeighbour = mesh.faceNeighbour();
|
||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||
@ -475,7 +408,7 @@ void Foam::decompositionMethod::calcDistributedCSR
|
||||
// Get renumbered owner on other side of coupled faces
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
List<int> globalNeighbour(mesh.nFaces()-mesh.nInternalFaces());
|
||||
labelList globalNeighbour(mesh.nFaces()-mesh.nInternalFaces());
|
||||
|
||||
forAll(patches, patchI)
|
||||
{
|
||||
@ -504,18 +437,15 @@ void Foam::decompositionMethod::calcDistributedCSR
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// Number of faces per cell
|
||||
List<int> nFacesPerCell(mesh.nCells(), 0);
|
||||
labelList nFacesPerCell(mesh.nCells(), 0);
|
||||
|
||||
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
|
||||
{
|
||||
label own = faceOwner[faceI];
|
||||
label nei = faceNeighbour[faceI];
|
||||
label own = agglom[faceOwner[faceI]];
|
||||
label nei = agglom[faceNeighbour[faceI]];
|
||||
|
||||
if (faceI == masterFace(mesh, own, nei))
|
||||
{
|
||||
nFacesPerCell[own]++;
|
||||
nFacesPerCell[nei]++;
|
||||
}
|
||||
nFacesPerCell[own]++;
|
||||
nFacesPerCell[nei]++;
|
||||
}
|
||||
|
||||
// Handle coupled faces
|
||||
@ -532,7 +462,7 @@ void Foam::decompositionMethod::calcDistributedCSR
|
||||
|
||||
forAll(pp, i)
|
||||
{
|
||||
label own = faceOwner[faceI];
|
||||
label own = agglom[faceOwner[faceI]];
|
||||
label globalNei = globalNeighbour[bFaceI];
|
||||
if (cellPair.insert(edge(own, globalNei)))
|
||||
{
|
||||
@ -545,43 +475,24 @@ void Foam::decompositionMethod::calcDistributedCSR
|
||||
}
|
||||
|
||||
|
||||
// Fill in xadj
|
||||
// ~~~~~~~~~~~~
|
||||
// Fill in offset and data
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
xadj.setSize(mesh.nCells()+1);
|
||||
|
||||
int freeAdj = 0;
|
||||
|
||||
for (label cellI = 0; cellI < mesh.nCells(); cellI++)
|
||||
{
|
||||
xadj[cellI] = freeAdj;
|
||||
|
||||
freeAdj += nFacesPerCell[cellI];
|
||||
}
|
||||
xadj[mesh.nCells()] = freeAdj;
|
||||
|
||||
|
||||
|
||||
// Fill in adjncy
|
||||
// ~~~~~~~~~~~~~~
|
||||
|
||||
adjncy.setSize(freeAdj);
|
||||
cellCells.setSize(nFacesPerCell);
|
||||
|
||||
nFacesPerCell = 0;
|
||||
|
||||
labelList& m = cellCells.m();
|
||||
const labelList& offsets = cellCells.offsets();
|
||||
|
||||
// For internal faces is just offsetted owner and neighbour
|
||||
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
|
||||
{
|
||||
label own = faceOwner[faceI];
|
||||
label nei = faceNeighbour[faceI];
|
||||
label own = agglom[faceOwner[faceI]];
|
||||
label nei = agglom[faceNeighbour[faceI]];
|
||||
|
||||
if (faceI == masterFace(mesh, own, nei))
|
||||
{
|
||||
adjncy[xadj[own] + nFacesPerCell[own]++] =
|
||||
globalCells.toGlobal(nei);
|
||||
adjncy[xadj[nei] + nFacesPerCell[nei]++] =
|
||||
globalCells.toGlobal(own);
|
||||
}
|
||||
m[offsets[own] + nFacesPerCell[own]++] = globalCells.toGlobal(nei);
|
||||
m[offsets[nei] + nFacesPerCell[nei]++] = globalCells.toGlobal(own);
|
||||
}
|
||||
|
||||
// For boundary faces is offsetted coupled neighbour
|
||||
@ -597,17 +508,41 @@ void Foam::decompositionMethod::calcDistributedCSR
|
||||
|
||||
forAll(pp, i)
|
||||
{
|
||||
label own = faceOwner[faceI];
|
||||
label own = agglom[faceOwner[faceI]];
|
||||
label globalNei = globalNeighbour[bFaceI];
|
||||
if (cellPair.insert(edge(own, globalNei)))
|
||||
{
|
||||
adjncy[xadj[own] + nFacesPerCell[own]++] = globalNei;
|
||||
m[offsets[own] + nFacesPerCell[own]++] = globalNei;
|
||||
}
|
||||
faceI++;
|
||||
bFaceI++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check for duplicates connections between cells as a postprocessing step
|
||||
// (since quite rare)
|
||||
label startIndex = 0;
|
||||
label newIndex = 0;
|
||||
labelHashSet nbrCells;
|
||||
forAll(cellCells, cellI)
|
||||
{
|
||||
nbrCells.clear();
|
||||
|
||||
label& endIndex = cellCells.offsets()[cellI+1];
|
||||
|
||||
for (label i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
if (nbrCells.insert(cellCells.m()[i]))
|
||||
{
|
||||
cellCells.m()[newIndex++] = cellCells.m()[i];
|
||||
}
|
||||
}
|
||||
|
||||
startIndex = endIndex;
|
||||
endIndex = newIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -37,6 +37,7 @@ SourceFiles
|
||||
|
||||
#include "polyMesh.H"
|
||||
#include "pointField.H"
|
||||
#include "CompactListList.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
@ -56,43 +57,37 @@ protected:
|
||||
label nProcessors_;
|
||||
|
||||
|
||||
//- Helper: determine (non-parallel) cellCells from mesh agglomeration.
|
||||
//- Helper: determine (global) cellCells from mesh agglomeration.
|
||||
static void calcCellCells
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const labelList& agglom,
|
||||
const label nCoarse,
|
||||
labelListList& cellCells
|
||||
CompactListList<label>& cellCells
|
||||
);
|
||||
|
||||
//- Calculate the minimum face between two neighbouring cells
|
||||
// (usually there is only one)
|
||||
static label masterFace(const polyMesh&, const label, const label);
|
||||
|
||||
// From mesh to compact row storage format
|
||||
// (like CompactListList)
|
||||
static void calcCSR
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
List<int>& adjncy,
|
||||
List<int>& xadj
|
||||
);
|
||||
// // From mesh to compact row storage format
|
||||
// // (like CompactListList)
|
||||
// static void calcCSR
|
||||
// (
|
||||
// const polyMesh& mesh,
|
||||
// List<int>& adjncy,
|
||||
// List<int>& xadj
|
||||
// );
|
||||
//
|
||||
// // From cell-cell connections to compact row storage format
|
||||
// // (like CompactListList)
|
||||
// static void calcCSR
|
||||
// (
|
||||
// const labelListList& cellCells,
|
||||
// List<int>& adjncy,
|
||||
// List<int>& xadj
|
||||
// );
|
||||
|
||||
// From cell-cell connections to compact row storage format
|
||||
// (like CompactListList)
|
||||
static void calcCSR
|
||||
(
|
||||
const labelListList& cellCells,
|
||||
List<int>& adjncy,
|
||||
List<int>& xadj
|
||||
);
|
||||
|
||||
static void calcDistributedCSR
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
List<int>& adjncy,
|
||||
List<int>& xadj
|
||||
);
|
||||
|
||||
private:
|
||||
|
||||
@ -122,18 +117,6 @@ public:
|
||||
(decompositionDict)
|
||||
);
|
||||
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
decompositionMethod,
|
||||
dictionaryMesh,
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
),
|
||||
(decompositionDict, mesh)
|
||||
);
|
||||
|
||||
|
||||
// Selectors
|
||||
|
||||
@ -143,13 +126,6 @@ public:
|
||||
const dictionary& decompositionDict
|
||||
);
|
||||
|
||||
//- Return a reference to the selected decomposition method
|
||||
static autoPtr<decompositionMethod> New
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
@ -171,63 +147,105 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
label nDomains() const
|
||||
{
|
||||
return nProcessors_;
|
||||
}
|
||||
|
||||
//- Is method parallel aware (i.e. does it synchronize domains across
|
||||
// proc boundaries)
|
||||
virtual bool parallelAware() const = 0;
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Use the
|
||||
// mesh connectivity (if needed)
|
||||
virtual labelList decompose
|
||||
(
|
||||
const pointField& points,
|
||||
const scalarField& pointWeights
|
||||
) = 0;
|
||||
|
||||
//- Like decompose but with uniform weights on the points
|
||||
virtual labelList decompose(const pointField&);
|
||||
// No topology (implemented by geometric decomposers)
|
||||
|
||||
//- Return for every coordinate the wanted processor number.
|
||||
virtual labelList decompose
|
||||
(
|
||||
const pointField& points,
|
||||
const scalarField& pointWeights
|
||||
)
|
||||
{
|
||||
notImplemented
|
||||
(
|
||||
"decompositionMethod:decompose(const pointField&"
|
||||
", const scalarField&)"
|
||||
);
|
||||
return labelList(0);
|
||||
}
|
||||
|
||||
//- Like decompose but with uniform weights on the points
|
||||
virtual labelList decompose(const pointField&)
|
||||
{
|
||||
notImplemented
|
||||
(
|
||||
"decompositionMethod:decompose(const pointField&)"
|
||||
);
|
||||
return labelList(0);
|
||||
}
|
||||
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Gets
|
||||
// passed agglomeration map (from fine to coarse cells) and coarse cell
|
||||
// location. Can be overridden by decomposers that provide this
|
||||
// functionality natively. Coarse cells are local to the processor
|
||||
// (if in parallel). If you want to have coarse cells spanning
|
||||
// processors use the globalCellCells instead.
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelList& cellToRegion,
|
||||
const pointField& regionPoints,
|
||||
const scalarField& regionWeights
|
||||
);
|
||||
// Topology provided by mesh
|
||||
|
||||
//- Like decompose but with uniform weights on the regions
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelList& cellToRegion,
|
||||
const pointField& regionPoints
|
||||
);
|
||||
//- Return for every coordinate the wanted processor number. Use the
|
||||
// mesh connectivity (if needed)
|
||||
virtual labelList decompose
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const pointField& points,
|
||||
const scalarField& pointWeights
|
||||
) = 0;
|
||||
|
||||
//- Like decompose but with uniform weights on the points
|
||||
virtual labelList decompose(const polyMesh&, const pointField&);
|
||||
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Explicitly
|
||||
// provided connectivity - does not use mesh_.
|
||||
// The connectivity is equal to mesh.cellCells() except for
|
||||
// - in parallel the cell numbers are global cell numbers (starting
|
||||
// from 0 at processor0 and then incrementing all through the
|
||||
// processors)
|
||||
// - the connections are across coupled patches
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelListList& globalCellCells,
|
||||
const pointField& cc,
|
||||
const scalarField& cWeights
|
||||
) = 0;
|
||||
//- Return for every coordinate the wanted processor number. Gets
|
||||
// passed agglomeration map (from fine to coarse cells) and coarse
|
||||
// cell
|
||||
// location. Can be overridden by decomposers that provide this
|
||||
// functionality natively. Coarse cells are local to the processor
|
||||
// (if in parallel). If you want to have coarse cells spanning
|
||||
// processors use the globalCellCells instead.
|
||||
virtual labelList decompose
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const labelList& cellToRegion,
|
||||
const pointField& regionPoints,
|
||||
const scalarField& regionWeights
|
||||
);
|
||||
|
||||
//- Like decompose but with uniform weights on the cells
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelListList& globalCellCells,
|
||||
const pointField& cc
|
||||
);
|
||||
//- Like decompose but with uniform weights on the regions
|
||||
virtual labelList decompose
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const labelList& cellToRegion,
|
||||
const pointField& regionPoints
|
||||
);
|
||||
|
||||
|
||||
// Topology provided explicitly addressing
|
||||
|
||||
//- Return for every coordinate the wanted processor number.
|
||||
// The connectivity is equal to mesh.cellCells() except for
|
||||
// - in parallel the cell numbers are global cell numbers
|
||||
// (starting
|
||||
// from 0 at processor0 and then incrementing all through the
|
||||
// processors)
|
||||
// - the connections are across coupled patches
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelListList& globalCellCells,
|
||||
const pointField& cc,
|
||||
const scalarField& cWeights
|
||||
) = 0;
|
||||
|
||||
//- Like decompose but with uniform weights on the cells
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelListList& globalCellCells,
|
||||
const pointField& cc
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -71,6 +71,17 @@ public:
|
||||
const dictionary& decompositionDict,
|
||||
const word& derivedType
|
||||
);
|
||||
|
||||
//- Return for every coordinate the wanted processor number.
|
||||
virtual labelList decompose
|
||||
(
|
||||
const pointField& points,
|
||||
const scalarField& pointWeights
|
||||
) = 0;
|
||||
|
||||
//- Like decompose but with uniform weights on the points
|
||||
virtual labelList decompose(const pointField&) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -40,13 +40,6 @@ namespace Foam
|
||||
hierarchGeomDecomp,
|
||||
dictionary
|
||||
);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
decompositionMethod,
|
||||
hierarchGeomDecomp,
|
||||
dictionaryMesh
|
||||
);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -685,35 +678,6 @@ void Foam::hierarchGeomDecomp::sortComponent
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::hierarchGeomDecomp::hierarchGeomDecomp
|
||||
(
|
||||
const dictionary& decompositionDict
|
||||
)
|
||||
:
|
||||
geomDecomp(decompositionDict, typeName),
|
||||
decompOrder_()
|
||||
{
|
||||
setDecompOrder();
|
||||
}
|
||||
|
||||
|
||||
Foam::hierarchGeomDecomp::hierarchGeomDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh&
|
||||
)
|
||||
:
|
||||
geomDecomp(decompositionDict, hierarchGeomDecomp::typeName),
|
||||
decompOrder_()
|
||||
{
|
||||
setDecompOrder();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::labelList Foam::hierarchGeomDecomp::decompose
|
||||
(
|
||||
const pointField& points
|
||||
@ -797,4 +761,20 @@ Foam::labelList Foam::hierarchGeomDecomp::decompose
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::hierarchGeomDecomp::hierarchGeomDecomp
|
||||
(
|
||||
const dictionary& decompositionDict
|
||||
)
|
||||
:
|
||||
geomDecomp(decompositionDict, typeName),
|
||||
decompOrder_()
|
||||
{
|
||||
setDecompOrder();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -154,7 +154,6 @@ class hierarchGeomDecomp
|
||||
labelList& finalDecomp // overall decomposition
|
||||
);
|
||||
|
||||
|
||||
//- Disallow default bitwise copy construct and assignment
|
||||
void operator=(const hierarchGeomDecomp&);
|
||||
hierarchGeomDecomp(const hierarchGeomDecomp&);
|
||||
@ -171,13 +170,6 @@ public:
|
||||
//- Construct given the decomposition dictionary
|
||||
hierarchGeomDecomp(const dictionary& decompositionDict);
|
||||
|
||||
//- Construct given the decomposition dictionary and mesh
|
||||
hierarchGeomDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~hierarchGeomDecomp()
|
||||
@ -192,8 +184,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Use the
|
||||
// mesh connectivity (if needed)
|
||||
//- Return for every coordinate the wanted processor number.
|
||||
virtual labelList decompose
|
||||
(
|
||||
const pointField&,
|
||||
@ -204,6 +195,26 @@ public:
|
||||
// so kept separate for now.
|
||||
virtual labelList decompose(const pointField&);
|
||||
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Use the
|
||||
// mesh connectivity (if needed)
|
||||
virtual labelList decompose
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const pointField& cc,
|
||||
const scalarField& cWeights
|
||||
)
|
||||
{
|
||||
return decompose(cc, cWeights);
|
||||
}
|
||||
|
||||
//- Without weights. Code for weighted decomposition is a bit complex
|
||||
// so kept separate for now.
|
||||
virtual labelList decompose(const polyMesh& mesh, const pointField& cc)
|
||||
{
|
||||
return decompose(cc);
|
||||
}
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Explicitly
|
||||
// provided connectivity - does not use mesh_.
|
||||
// The connectivity is equal to mesh.cellCells() except for
|
||||
|
||||
@ -43,34 +43,14 @@ namespace Foam
|
||||
manualDecomp,
|
||||
dictionary
|
||||
);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
decompositionMethod,
|
||||
manualDecomp,
|
||||
dictionaryMesh
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::manualDecomp::manualDecomp(const dictionary& decompositionDict)
|
||||
:
|
||||
decompositionMethod(decompositionDict)
|
||||
{
|
||||
notImplemented("manualDecomp(const dictionary&)");
|
||||
}
|
||||
|
||||
|
||||
Foam::manualDecomp::manualDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
)
|
||||
:
|
||||
decompositionMethod(decompositionDict),
|
||||
meshPtr_(&mesh),
|
||||
decompDataFile_
|
||||
(
|
||||
decompositionDict.subDict(word(decompositionDict.lookup("method"))
|
||||
@ -83,12 +63,11 @@ Foam::manualDecomp::manualDecomp
|
||||
|
||||
Foam::labelList Foam::manualDecomp::decompose
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const pointField& points,
|
||||
const scalarField& pointWeights
|
||||
)
|
||||
{
|
||||
const polyMesh& mesh = *meshPtr_;
|
||||
|
||||
labelIOList finalDecomp
|
||||
(
|
||||
IOobject
|
||||
|
||||
@ -50,8 +50,6 @@ class manualDecomp
|
||||
{
|
||||
// Private data
|
||||
|
||||
const polyMesh* meshPtr_;
|
||||
|
||||
fileName decompDataFile_;
|
||||
|
||||
|
||||
@ -73,14 +71,6 @@ public:
|
||||
//- Construct given the decomposition dictionary
|
||||
manualDecomp(const dictionary& decompositionDict);
|
||||
|
||||
//- Construct given the decomposition dictionary and mesh
|
||||
manualDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~manualDecomp()
|
||||
{}
|
||||
@ -99,8 +89,9 @@ public:
|
||||
// mesh connectivity (if needed)
|
||||
virtual labelList decompose
|
||||
(
|
||||
const pointField& points,
|
||||
const scalarField& pointWeights
|
||||
const polyMesh& mesh,
|
||||
const pointField& cc,
|
||||
const scalarField& cWeights
|
||||
);
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Explicitly
|
||||
@ -117,8 +108,14 @@ public:
|
||||
const scalarField& cWeights
|
||||
)
|
||||
{
|
||||
return decompose(cc, cWeights);
|
||||
notImplemented
|
||||
(
|
||||
"decompose(const labelListList&, const pointField&"
|
||||
", const scalarField)"
|
||||
);
|
||||
return labelList(0);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,293 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
|
||||
\\/ 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 "multiLevelDecomp.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "IFstream.H"
|
||||
#include "globalIndex.H"
|
||||
#include "mapDistribute.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(multiLevelDecomp, 0);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
decompositionMethod,
|
||||
multiLevelDecomp,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
// Given a subset of cells determine the new global indices. The problem
|
||||
// is in the cells from neighbouring processors which need to be renumbered.
|
||||
void Foam::multiLevelDecomp::subsetGlobalCellCells
|
||||
(
|
||||
const labelListList& cellCells,
|
||||
const labelList& set,
|
||||
labelListList& subCellCells,
|
||||
label& cutConnections
|
||||
) const
|
||||
{
|
||||
// Determine new index for cells by inverting subset
|
||||
labelList oldToNew(invert(cellCells.size(), set));
|
||||
|
||||
globalIndex globalCells(cellCells.size());
|
||||
|
||||
// Subset locally the elements for which I have data
|
||||
subCellCells = UIndirectList<labelList>(cellCells, set);
|
||||
|
||||
// Get new indices for neighbouring processors
|
||||
List<Map<label> > compactMap;
|
||||
mapDistribute map(globalCells, subCellCells, compactMap);
|
||||
map.distribute(oldToNew);
|
||||
|
||||
// Now subCellCells contains indices into oldToNew which are the
|
||||
// new locations of the neighbouring cells.
|
||||
|
||||
cutConnections = 0;
|
||||
|
||||
forAll(subCellCells, subCellI)
|
||||
{
|
||||
labelList& cCells = subCellCells[subCellI];
|
||||
|
||||
// Keep the connections to valid mapped cells
|
||||
label newI = 0;
|
||||
forAll(cCells, i)
|
||||
{
|
||||
label subCellI = oldToNew[cCells[i]];
|
||||
if (subCellI == -1)
|
||||
{
|
||||
cutConnections++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cCells[newI++] = subCellI;
|
||||
}
|
||||
}
|
||||
cCells.setSize(newI);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::multiLevelDecomp::decompose
|
||||
(
|
||||
const labelListList& pointPoints,
|
||||
const pointField& points,
|
||||
const scalarField& pointWeights,
|
||||
const labelList& pointMap, // map back to original points
|
||||
const label levelI,
|
||||
|
||||
labelField& finalDecomp
|
||||
)
|
||||
{
|
||||
labelList dist
|
||||
(
|
||||
methods_[levelI].decompose
|
||||
(
|
||||
pointPoints,
|
||||
points,
|
||||
pointWeights
|
||||
)
|
||||
);
|
||||
|
||||
//Pout<< "At level " << levelI << endl;
|
||||
//forAll(dist, i)
|
||||
//{
|
||||
// Pout<< " " << i << " at:" << points[i]
|
||||
// << " original:" << pointMap[i] << " dist:" << dist[i]
|
||||
// << " connected to:" << pointField(points, pointPoints[i])
|
||||
// << endl;
|
||||
//}
|
||||
//Pout<< endl;
|
||||
|
||||
forAll(pointMap, i)
|
||||
{
|
||||
label orig = pointMap[i];
|
||||
finalDecomp[orig] += dist[i];
|
||||
}
|
||||
|
||||
if (levelI != methods_.size()-1)
|
||||
{
|
||||
// Recurse
|
||||
|
||||
// Determine points per domain
|
||||
label n = methods_[levelI].nDomains();
|
||||
labelListList domainToPoints(invertOneToMany(n, dist));
|
||||
|
||||
// 'Make space' for new levels of decomposition
|
||||
finalDecomp *= methods_[levelI+1].nDomains();
|
||||
|
||||
// Extract processor+local index from point-point addressing
|
||||
|
||||
forAll(domainToPoints, domainI)
|
||||
{
|
||||
const labelList& myPoints = domainToPoints[domainI];
|
||||
|
||||
// Subset point-wise data.
|
||||
pointField subPoints(points, myPoints);
|
||||
scalarField subWeights(pointWeights, myPoints);
|
||||
labelList subPointMap(UIndirectList<label>(pointMap, myPoints));
|
||||
// Subset point-point addressing (adapt global numbering)
|
||||
labelListList subPointPoints;
|
||||
label nOutsideConnections;
|
||||
subsetGlobalCellCells
|
||||
(
|
||||
pointPoints,
|
||||
myPoints,
|
||||
subPointPoints,
|
||||
nOutsideConnections
|
||||
);
|
||||
|
||||
//Info<< "At level " << levelI << " domain " << domainI
|
||||
// << " have connections to other domains "
|
||||
// << returnReduce(nOutsideConnections, sumOp<label>())
|
||||
// << endl;
|
||||
|
||||
decompose
|
||||
(
|
||||
subPointPoints,
|
||||
subPoints,
|
||||
subWeights,
|
||||
subPointMap,
|
||||
levelI+1,
|
||||
|
||||
finalDecomp
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::multiLevelDecomp::multiLevelDecomp(const dictionary& decompositionDict)
|
||||
:
|
||||
decompositionMethod(decompositionDict)
|
||||
{
|
||||
const dictionary& myDict = decompositionDict_.subDict(typeName + "Coeffs");
|
||||
|
||||
methods_.setSize(myDict.size());
|
||||
label i = 0;
|
||||
forAllConstIter(dictionary, myDict, iter)
|
||||
{
|
||||
methods_.set(i++, decompositionMethod::New(iter().dict()));
|
||||
}
|
||||
|
||||
label n = 1;
|
||||
Info<< "decompositionMethod " << type() << " :" << endl;
|
||||
forAll(methods_, i)
|
||||
{
|
||||
Info<< " level " << i << " decomposing with " << methods_[i].type()
|
||||
<< " into " << methods_[i].nDomains() << " subdomains." << endl;
|
||||
|
||||
n *= methods_[i].nDomains();
|
||||
}
|
||||
|
||||
if (n != nDomains())
|
||||
{
|
||||
FatalErrorIn("multiLevelDecomp::multiLevelDecomp(const dictionary&)")
|
||||
<< "Top level decomposition specifies " << nDomains()
|
||||
<< " domains which is not equal to the product of"
|
||||
<< " all sub domains " << n
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::multiLevelDecomp::parallelAware() const
|
||||
{
|
||||
forAll(methods_, i)
|
||||
{
|
||||
if (!methods_[i].parallelAware())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::multiLevelDecomp::decompose
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const pointField& cc,
|
||||
const scalarField& cWeights
|
||||
)
|
||||
{
|
||||
CompactListList<label> cellCells;
|
||||
calcCellCells(mesh, identity(cc.size()), cc.size(), cellCells);
|
||||
|
||||
labelField finalDecomp(cc.size(), 0);
|
||||
labelList cellMap(identity(cc.size()));
|
||||
|
||||
decompose
|
||||
(
|
||||
cellCells(),
|
||||
cc,
|
||||
cWeights,
|
||||
cellMap, // map back to original cells
|
||||
0,
|
||||
|
||||
finalDecomp
|
||||
);
|
||||
|
||||
return finalDecomp;
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::multiLevelDecomp::decompose
|
||||
(
|
||||
const labelListList& globalPointPoints,
|
||||
const pointField& points,
|
||||
const scalarField& pointWeights
|
||||
)
|
||||
{
|
||||
labelField finalDecomp(points.size(), 0);
|
||||
labelList pointMap(identity(points.size()));
|
||||
|
||||
decompose
|
||||
(
|
||||
globalPointPoints,
|
||||
points,
|
||||
pointWeights,
|
||||
pointMap, // map back to original points
|
||||
0,
|
||||
|
||||
finalDecomp
|
||||
);
|
||||
|
||||
return finalDecomp;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,136 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
|
||||
\\/ 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/>.
|
||||
|
||||
Class
|
||||
Foam::multiLevelDecomp
|
||||
|
||||
Description
|
||||
Decomposition given using consecutive application of decomposers.
|
||||
|
||||
SourceFiles
|
||||
multiLevelDecomp.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef multiLevelDecomp_H
|
||||
#define multiLevelDecomp_H
|
||||
|
||||
#include "decompositionMethod.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class multiLevelDecomp Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class multiLevelDecomp
|
||||
:
|
||||
public decompositionMethod
|
||||
{
|
||||
// Private data
|
||||
|
||||
PtrList<decompositionMethod> methods_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Given connectivity across processors work out connectivity
|
||||
// for a (consistent) subset
|
||||
void subsetGlobalCellCells
|
||||
(
|
||||
const labelListList& cellCells,
|
||||
const labelList& set,
|
||||
labelListList& subCellCells,
|
||||
label& cutConnections
|
||||
) const;
|
||||
|
||||
//- Decompose level methodI without addressing
|
||||
void decompose
|
||||
(
|
||||
const labelListList& pointPoints,
|
||||
const pointField& points,
|
||||
const scalarField& pointWeights,
|
||||
const labelList& pointMap, // map back to original points
|
||||
const label levelI,
|
||||
|
||||
labelField& finalDecomp
|
||||
);
|
||||
|
||||
//- Disallow default bitwise copy construct and assignment
|
||||
void operator=(const multiLevelDecomp&);
|
||||
multiLevelDecomp(const multiLevelDecomp&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("multiLevel");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct given the decomposition dictionary
|
||||
multiLevelDecomp(const dictionary& decompositionDict);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~multiLevelDecomp()
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Is method parallel aware (i.e. does it synchronize domains across
|
||||
// proc boundaries)
|
||||
virtual bool parallelAware() const;
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Use the
|
||||
// mesh connectivity (if needed)
|
||||
virtual labelList decompose
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const pointField& points,
|
||||
const scalarField& pointWeights
|
||||
);
|
||||
|
||||
//- Return for every coordinate the wanted processor number. Explicitly
|
||||
// provided connectivity - does not use mesh_.
|
||||
virtual labelList decompose
|
||||
(
|
||||
const labelListList& globalCellCells,
|
||||
const pointField& cc,
|
||||
const scalarField& cWeights
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -39,13 +39,6 @@ namespace Foam
|
||||
simpleGeomDecomp,
|
||||
dictionary
|
||||
);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
decompositionMethod,
|
||||
simpleGeomDecomp,
|
||||
dictionaryMesh
|
||||
);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -133,26 +126,6 @@ void Foam::simpleGeomDecomp::assignToProcessorGroup
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::simpleGeomDecomp::simpleGeomDecomp(const dictionary& decompositionDict)
|
||||
:
|
||||
geomDecomp(decompositionDict, typeName)
|
||||
{}
|
||||
|
||||
|
||||
Foam::simpleGeomDecomp::simpleGeomDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh&
|
||||
)
|
||||
:
|
||||
geomDecomp(decompositionDict, typeName)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::labelList Foam::simpleGeomDecomp::decompose(const pointField& points)
|
||||
{
|
||||
// construct a list for the final result
|
||||
@ -315,4 +288,16 @@ Foam::labelList Foam::simpleGeomDecomp::decompose
|
||||
|
||||
return finalDecomp;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::simpleGeomDecomp::simpleGeomDecomp(const dictionary& decompositionDict)
|
||||
:
|
||||
geomDecomp(decompositionDict, typeName)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -76,13 +76,6 @@ public:
|
||||
//- Construct given the decomposition dictionary
|
||||
simpleGeomDecomp(const dictionary& decompositionDict);
|
||||
|
||||
//- Construct given the decomposition dictionary and mesh
|
||||
simpleGeomDecomp
|
||||
(
|
||||
const dictionary& decompositionDict,
|
||||
const polyMesh& mesh
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~simpleGeomDecomp()
|
||||
@ -98,16 +91,24 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual labelList decompose
|
||||
(
|
||||
const pointField& points
|
||||
);
|
||||
virtual labelList decompose(const pointField&);
|
||||
|
||||
virtual labelList decompose(const pointField&, const scalarField&);
|
||||
|
||||
virtual labelList decompose(const polyMesh&, const pointField& points)
|
||||
{
|
||||
return decompose(points);
|
||||
}
|
||||
|
||||
virtual labelList decompose
|
||||
(
|
||||
const polyMesh&,
|
||||
const pointField& points,
|
||||
const scalarField& pointWeights
|
||||
);
|
||||
)
|
||||
{
|
||||
return decompose(points, pointWeights);
|
||||
}
|
||||
|
||||
//- Explicitly provided connectivity
|
||||
virtual labelList decompose
|
||||
|
||||
Reference in New Issue
Block a user