ENH: multiple faces between two cells gives problems for scotch

We filter them out now when constructing the adjacency structure.
This commit is contained in:
mattijs
2010-04-15 15:12:48 +01:00
parent d4ca02cf7e
commit 01aa79be54
2 changed files with 178 additions and 75 deletions

View File

@ -215,6 +215,43 @@ void Foam::decompositionMethod::calcCellCells
}
// Return the minimum face between two cells. Only relevant for
// cells with multiple faces inbetween.
Foam::label Foam::decompositionMethod::masterFace
(
const polyMesh& mesh,
const label own,
const label nei
)
{
label minFaceI = labelMax;
// Count multiple faces between own and nei only once
const cell& ownFaces = mesh.cells()[own];
forAll(ownFaces, i)
{
label otherFaceI = ownFaces[i];
if (mesh.isInternalFace(otherFaceI))
{
label nbrCellI =
(
mesh.faceNeighbour()[otherFaceI] != own
? mesh.faceNeighbour()[otherFaceI]
: mesh.faceOwner()[otherFaceI]
);
if (nbrCellI == nei)
{
minFaceI = min(minFaceI, otherFaceI);
}
}
}
return minFaceI;
}
void Foam::decompositionMethod::calcCSR
(
const polyMesh& mesh,
@ -222,61 +259,15 @@ void Foam::decompositionMethod::calcCSR
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
xadj.setSize(mesh.nCells()+1);
// Initialise the number of internal faces of the cells to twice the
// number of internal faces
label nInternalFaces = 2*mesh.nInternalFaces();
// Check the boundary for coupled patches and add to the number of
// internal faces
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
forAll(pbm, patchi)
{
if (isA<cyclicPolyPatch>(pbm[patchi]))
{
nInternalFaces += pbm[patchi].size();
}
}
// Create the adjncy array the size of the total number of internal and
// coupled faces
adjncy.setSize(nInternalFaces);
// Fill in xadj
// ~~~~~~~~~~~~
label freeAdj = 0;
for (label cellI = 0; cellI < mesh.nCells(); cellI++)
{
xadj[cellI] = freeAdj;
const labelList& cFaces = mesh.cells()[cellI];
forAll(cFaces, i)
{
label faceI = cFaces[i];
if
(
mesh.isInternalFace(faceI)
|| isA<cyclicPolyPatch>(pbm[pbm.whichPatch(faceI)])
)
{
freeAdj++;
}
}
}
xadj[mesh.nCells()] = freeAdj;
// Fill in adjncy
// ~~~~~~~~~~~~~~
// Count unique faces between cells
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
labelList nFacesPerCell(mesh.nCells(), 0);
@ -286,26 +277,95 @@ void Foam::decompositionMethod::calcCSR
label own = mesh.faceOwner()[faceI];
label nei = mesh.faceNeighbour()[faceI];
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
if (faceI == masterFace(mesh, own, nei))
{
nFacesPerCell[own]++;
nFacesPerCell[nei]++;
}
}
// Coupled faces. Only cyclics done.
forAll(pbm, patchi)
HashSet<edge, Hash<edge> > cellPair(mesh.nFaces()-mesh.nInternalFaces());
forAll(pbm, patchI)
{
if (isA<cyclicPolyPatch>(pbm[patchi]))
if (isA<cyclicPolyPatch>(pbm[patchI]))
{
const unallocLabelList& faceCells = pbm[patchi].faceCells();
const unallocLabelList& faceCells = pbm[patchI].faceCells();
label sizeby2 = faceCells.size()/2;
for (label facei=0; facei<sizeby2; facei++)
for (label faceI=0; faceI<sizeby2; faceI++)
{
label own = faceCells[facei];
label nei = faceCells[facei + sizeby2];
label own = faceCells[faceI];
label nei = faceCells[faceI + sizeby2];
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
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]))
{
const unallocLabelList& faceCells = pbm[patchI].faceCells();
label sizeby2 = faceCells.size()/2;
for (label faceI=0; faceI<sizeby2; faceI++)
{
label own = faceCells[faceI];
label nei = faceCells[faceI + sizeby2];
if (cellPair.insert(edge(own, nei)))
{
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
}
}
}
}
@ -320,12 +380,24 @@ void Foam::decompositionMethod::calcCSR
List<int>& xadj
)
{
labelHashSet nbrCells;
// Count number of internal faces
label nConnections = 0;
forAll(cellCells, coarseI)
{
nConnections += cellCells[coarseI].size();
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
@ -343,11 +415,16 @@ void Foam::decompositionMethod::calcCSR
{
xadj[coarseI] = freeAdj;
nbrCells.clear();
const labelList& cCells = cellCells[coarseI];
forAll(cCells, i)
{
adjncy[freeAdj++] = cCells[i];
if (nbrCells.insert(cCells[i]))
{
adjncy[freeAdj++] = cCells[i];
}
}
}
xadj[cellCells.size()] = freeAdj;
@ -413,15 +490,21 @@ void Foam::decompositionMethod::calcDistributedCSR
// Number of faces per cell
List<int> nFacesPerCell(mesh.nCells(), 0);
// Number of coupled faces
label nCoupledFaces = 0;
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
{
nFacesPerCell[faceOwner[faceI]]++;
nFacesPerCell[faceNeighbour[faceI]]++;
label own = faceOwner[faceI];
label nei = faceNeighbour[faceI];
if (faceI == masterFace(mesh, own, nei))
{
nFacesPerCell[own]++;
nFacesPerCell[nei]++;
}
}
// Handle coupled faces
HashSet<edge, Hash<edge> > cellPair(mesh.nFaces()-mesh.nInternalFaces());
forAll(patches, patchI)
{
const polyPatch& pp = patches[patchI];
@ -429,11 +512,18 @@ void Foam::decompositionMethod::calcDistributedCSR
if (pp.coupled())
{
label faceI = pp.start();
label bFaceI = pp.start()-mesh.nInternalFaces();
forAll(pp, i)
{
nCoupledFaces++;
nFacesPerCell[faceOwner[faceI++]]++;
label own = faceOwner[faceI];
label globalNei = globalNeighbour[bFaceI];
if (cellPair.insert(edge(own, globalNei)))
{
nFacesPerCell[own]++;
}
faceI++;
bFaceI++;
}
}
}
@ -459,7 +549,7 @@ void Foam::decompositionMethod::calcDistributedCSR
// Fill in adjncy
// ~~~~~~~~~~~~~~
adjncy.setSize(2*mesh.nInternalFaces() + nCoupledFaces);
adjncy.setSize(freeAdj);
nFacesPerCell = 0;
@ -469,10 +559,17 @@ void Foam::decompositionMethod::calcDistributedCSR
label own = faceOwner[faceI];
label nei = faceNeighbour[faceI];
adjncy[xadj[own] + nFacesPerCell[own]++] = globalCells.toGlobal(nei);
adjncy[xadj[nei] + nFacesPerCell[nei]++] = globalCells.toGlobal(own);
if (faceI == masterFace(mesh, own, nei))
{
adjncy[xadj[own] + nFacesPerCell[own]++] =
globalCells.toGlobal(nei);
adjncy[xadj[nei] + nFacesPerCell[nei]++] =
globalCells.toGlobal(own);
}
}
// For boundary faces is offsetted coupled neighbour
cellPair.clear();
forAll(patches, patchI)
{
const polyPatch& pp = patches[patchI];
@ -485,9 +582,11 @@ void Foam::decompositionMethod::calcDistributedCSR
forAll(pp, i)
{
label own = faceOwner[faceI];
adjncy[xadj[own] + nFacesPerCell[own]++] =
globalNeighbour[bFaceI];
label globalNei = globalNeighbour[bFaceI];
if (cellPair.insert(edge(own, globalNei)))
{
adjncy[xadj[own] + nFacesPerCell[own]++] = globalNei;
}
faceI++;
bFaceI++;
}