ENH: bandCompression: addressing in losort form

This commit is contained in:
mattijs 2013-07-16 21:27:05 +01:00
parent cf12df4564
commit 3540cda2f9
2 changed files with 130 additions and 2 deletions

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -146,4 +146,129 @@ Foam::labelList Foam::bandCompression(const labelListList& cellCellAddressing)
}
Foam::labelList Foam::bandCompression
(
const labelList& cellCells,
const labelList& offsets
)
{
// Count number of neighbours
labelList numNbrs(offsets.size()-1, 0);
forAll(numNbrs, cellI)
{
label start = offsets[cellI];
label end = offsets[cellI+1];
for (label faceI = start; faceI < end; faceI++)
{
numNbrs[cellI]++;
numNbrs[cellCells[faceI]]++;
}
}
labelList newOrder(offsets.size()-1);
// the business bit of the renumbering
SLList<label> nextCell;
PackedBoolList visited(offsets.size()-1);
label cellInOrder = 0;
// Work arrays. Kept outside of loop to minimise allocations.
// - neighbour cells
DynamicList<label> nbrs;
// - corresponding weights
DynamicList<label> weights;
// - ordering
labelList order;
while (true)
{
// For a disconnected region find the lowest connected cell.
label currentCell = -1;
label minWeight = labelMax;
forAll(visited, cellI)
{
// find the lowest connected cell that has not been visited yet
if (!visited[cellI])
{
if (numNbrs[cellI] < minWeight)
{
minWeight = numNbrs[cellI];
currentCell = cellI;
}
}
}
if (currentCell == -1)
{
break;
}
// Starting from currentCell walk breadth-first
// use this cell as a start
nextCell.append(currentCell);
// loop through the nextCell list. Add the first cell into the
// cell order if it has not already been visited and ask for its
// neighbours. If the neighbour in question has not been visited,
// add it to the end of the nextCell list
while (nextCell.size())
{
currentCell = nextCell.removeHead();
if (!visited[currentCell])
{
visited[currentCell] = 1;
// add into cellOrder
newOrder[cellInOrder] = currentCell;
cellInOrder++;
// Add in increasing order of connectivity
// 1. Count neighbours of unvisited neighbours
nbrs.clear();
weights.clear();
label start = offsets[currentCell];
label end = offsets[currentCell+1];
for (label faceI = start; faceI < end; faceI++)
{
label nbr = cellCells[faceI];
if (!visited[nbr])
{
// not visited, add to the list
nbrs.append(nbr);
weights.append(numNbrs[nbr]);
}
}
// 2. Sort in ascending order
sortedOrder(weights, order);
// 3. Add in sorted order
forAll(order, i)
{
nextCell.append(nbrs[i]);
}
}
}
}
return newOrder;
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -51,6 +51,9 @@ namespace Foam
// original)
labelList bandCompression(const labelListList& addressing);
//- Renumber with addressing in losort form (neighbour + start in neighbour)
labelList bandCompression(const labelList& cellCells, const labelList& offsets);
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //