decompositionMethods::scaleWeights: Filter out zero weights

The nWeights argument is now reduced if any of the weights are zero for all
points on all processors and removed.
This commit is contained in:
Henry Weller
2024-06-01 17:27:27 +01:00
parent 544afc98aa
commit 78dbbdd7d3
7 changed files with 126 additions and 46 deletions

View File

@ -321,7 +321,7 @@ Foam::labelList Foam::decompositionMethod::decompose
Foam::labelList Foam::decompositionMethod::scaleWeights
(
const scalarField& weights,
const label nWeights,
label& nWeights,
const bool distributed
)
{
@ -345,6 +345,41 @@ Foam::labelList Foam::decompositionMethod::scaleWeights
intWeights[i] = ceil(scale*weights[i]);
}
/*
// Alternatively calculate a separate scaling factor
// for each weight, it is not clear from the parMETIS or Scotch manuals
// which method should be used.
//
// Calculate the scalar -> integer scaling factors
scalarList sumWeights(nWeights, 0.0);
forAll(weights, i)
{
sumWeights[i % nWeights] += weights[i];
}
if (distributed)
{
reduce(sumWeights, ListOp<sumOp<scalar>>());
}
scalarList scale(nWeights, 0.0);
forAll(scale, i)
{
if (sumWeights[i] > small)
{
scale[i] = labelMax/(2*sumWeights[i]);
}
}
// Convert weights to integer
intWeights.setSize(weights.size());
forAll(intWeights, i)
{
intWeights[i] = ceil(scale[i % nWeights]*weights[i]);
}
*/
// Calculate the sum over all processors of each weight
labelList sumIntWeights(nWeights, 0);
forAll(weights, i)
@ -383,6 +418,9 @@ Foam::labelList Foam::decompositionMethod::scaleWeights
// Resize the weights list
intWeights.setSize(nNonZeroWeights*(intWeights.size()/nWeights));
// Reset the number of weight to the number of non-zero weights
nWeights = nNonZeroWeights;
}
}

View File

@ -236,10 +236,11 @@ public:
//- Convert the given scalar weights to labels
// in the range 0-labelMax/2
// Removes 0 weights and updates nWeights accordingly
static labelList scaleWeights
(
const scalarField& weights,
const label nWeights,
label& nWeights,
const bool distributed = true
);

View File

@ -79,8 +79,10 @@ Foam::label Foam::decompositionMethods::metis::decompose
<< exit(FatalError);
}
label nWeights = 1;
// Cell weights (so on the vertices of the dual)
labelList intWeights(scaleWeights(cellWeights, 1, false));
labelList intWeights(scaleWeights(cellWeights, nWeights, false));
// Face weights (so on the edges of the dual)
labelList faceWeights;
@ -149,16 +151,16 @@ Foam::label Foam::decompositionMethods::metis::decompose
{
METIS_PartGraphRecursive
(
&numCells, // num vertices in graph
&ncon, // num balancing constraints
&numCells, // num vertices in graph
&ncon, // num balancing constraints
const_cast<labelList&>(xadj).begin(), // indexing into adjncy
const_cast<labelList&>(adjncy).begin(), // neighbour info
intWeights.begin(),// vertexweights
nullptr, // vsize: total communication vol
faceWeights.begin(),// edgeweights
&nProcs, // nParts
intWeights.begin(), // vertexweights
nullptr, // vsize: total communication vol
faceWeights.begin(), // edgeweights
&nProcs, // nParts
processorWeights.begin(), // tpwgts
nullptr, // ubvec: processor imbalance (default)
nullptr, // ubvec: processor imbalance (default)
options.begin(),
&edgeCut,
decomp.begin()
@ -168,16 +170,16 @@ Foam::label Foam::decompositionMethods::metis::decompose
{
METIS_PartGraphKway
(
&numCells, // num vertices in graph
&ncon, // num balancing constraints
&numCells, // num vertices in graph
&ncon, // num balancing constraints
const_cast<labelList&>(xadj).begin(), // indexing into adjncy
const_cast<labelList&>(adjncy).begin(), // neighbour info
intWeights.begin(),// vertexweights
nullptr, // vsize: total communication vol
faceWeights.begin(),// edgeweights
&nProcs, // nParts
intWeights.begin(), // vertexweights
nullptr, // vsize: total communication vol
faceWeights.begin(), // edgeweights
&nProcs, // nParts
processorWeights.begin(), // tpwgts
nullptr, // ubvec: processor imbalance (default)
nullptr, // ubvec: processor imbalance (default)
options.begin(),
&edgeCut,
decomp.begin()

View File

@ -212,6 +212,26 @@ Foam::label Foam::decompositionMethods::parMetis::decompose
);
}
// Sum the number of cells allocated to each processor
labelList nProcCells(Pstream::nProcs(), 0);
forAll(decomp, i)
{
nProcCells[decomp[i]]++;
}
reduce(nProcCells, ListOp<sumOp<label>>());
// If there are no cells allocated to this processor keep the first one
// to ensure that all processors have at least one cell
if (nProcCells[Pstream::myProcNo()] == 0)
{
Pout<< " No cells allocated to this processor"
", keeping first cell"
<< endl;
decomp[0] = Pstream::myProcNo();
}
return edgeCut;
}
@ -327,7 +347,8 @@ Foam::labelList Foam::decompositionMethods::parMetis::decompose
cellCells
);
const label nWeights = this->nWeights(points, pointWeights);
label nWeights = this->nWeights(points, pointWeights);
const labelList intWeights(scaleWeights(pointWeights, nWeights));
labelList decomp;
decompose
@ -336,7 +357,7 @@ Foam::labelList Foam::decompositionMethods::parMetis::decompose
cellCells.m(),
points,
nWeights,
scaleWeights(pointWeights, nWeights),
intWeights,
labelList(),
decomp
);
@ -382,7 +403,8 @@ Foam::labelList Foam::decompositionMethods::parMetis::decompose
cellCells
);
const label nWeights = this->nWeights(regionPoints, pointWeights);
label nWeights = this->nWeights(regionPoints, pointWeights);
const labelList intWeights(scaleWeights(pointWeights, nWeights));
// Decompose using weights
labelList decomp;
@ -392,7 +414,7 @@ Foam::labelList Foam::decompositionMethods::parMetis::decompose
cellCells.offsets(),
regionPoints,
nWeights,
scaleWeights(pointWeights, nWeights),
intWeights,
labelList(),
decomp
);
@ -437,7 +459,8 @@ Foam::labelList Foam::decompositionMethods::parMetis::decompose
// xadj(celli) : start of information in adjncy for celli
CompactListList<label> cellCells(globalCellCells);
const label nWeights = this->nWeights(cellCentres, cellWeights);
label nWeights = this->nWeights(cellCentres, cellWeights);
const labelList intWeights(scaleWeights(cellWeights, nWeights));
labelList decomp;
decompose
@ -446,7 +469,7 @@ Foam::labelList Foam::decompositionMethods::parMetis::decompose
cellCells.m(),
cellCentres,
nWeights,
scaleWeights(cellWeights, nWeights),
intWeights,
labelList(),
decomp
);

View File

@ -219,9 +219,10 @@ Foam::label Foam::decompositionMethods::ptscotch::decompose
<< exit(FatalError);
}
velotab = scaleWeights(cellWeights, 1);
label nWeights = 1;
velotab = scaleWeights(cellWeights, nWeights);
if (!cellWeights.size())
if (nWeights == 1 && !cellWeights.size())
{
// Locally zero cells but not globally. Make sure we have
// some size so .begin() does not return null pointer. Data

View File

@ -313,7 +313,8 @@ Foam::label Foam::decompositionMethods::scotch::decomposeOneProc
<< exit(FatalError);
}
velotab = scaleWeights(cellWeights, 1, false);
label nWeights = 1;
velotab = scaleWeights(cellWeights, nWeights, false);
}
@ -329,10 +330,10 @@ Foam::label Foam::decompositionMethods::scotch::decomposeOneProc
xadj.begin(), // verttab, start index per cell into adjncy
&xadj[1], // vendtab, end index ,,
velotab.begin(), // velotab, vertex weights
nullptr, // vlbltab
nullptr, // vlbltab
adjncy.size(), // edgenbr, number of arcs
adjncy.begin(), // edgetab
nullptr // edlotab, edge weights
nullptr // edlotab, edge weights
),
"SCOTCH_graphBuild"
);

View File

@ -248,7 +248,7 @@ Foam::label Foam::decompositionMethods::zoltan::decompose
const CompactListList<label>& adjacency,
const pointField& points,
const scalarField& pWeights,
List<label>& finalDecomp
List<label>& decomp
) const
{
if (Pstream::parRun() && !points.size())
@ -391,14 +391,34 @@ Foam::label Foam::decompositionMethods::zoltan::decompose
Pout << "Zoltan number to move " << changed << " " << num_exp << endl;
}
finalDecomp.setSize(points.size());
finalDecomp = Pstream::myProcNo();
decomp.setSize(points.size());
decomp = Pstream::myProcNo();
if (changed)
{
for(int i=0; i<num_exp; i++)
{
finalDecomp[exp_local_ids[i]] = exp_procs[i];
decomp[exp_local_ids[i]] = exp_procs[i];
}
// Sum the number of cells allocated to each processor
labelList nProcCells(Pstream::nProcs(), 0);
forAll(decomp, i)
{
nProcCells[decomp[i]]++;
}
reduce(nProcCells, ListOp<sumOp<label>>());
// If there are no cells allocated to this processor keep the first one
// to ensure that all processors have at least one cell
if (nProcCells[Pstream::myProcNo()] == 0)
{
Pout<< " No cells allocated to this processor"
", keeping first cell"
<< endl;
decomp[0] = Pstream::myProcNo();
}
}
@ -467,21 +487,15 @@ Foam::labelList Foam::decompositionMethods::zoltan::decompose
);
// Decompose using default weights
List<label> finalDecomp;
List<label> decomp;
decompose
(
cellCells,
cellCentres,
cellWeights,
finalDecomp
decomp
);
// Copy back to labelList
labelList decomp(cellCentres.size());
forAll(decomp, i)
{
decomp[i] = finalDecomp[i];
}
return decomp;
}
@ -514,13 +528,13 @@ Foam::labelList Foam::decompositionMethods::zoltan::decompose
);
// Decompose using weights
List<label> finalDecomp;
List<label> decomp;
decompose
(
cellCells,
agglomPoints,
pointWeights,
finalDecomp
decomp
);
// Rework back into decomposition for original mesh
@ -528,7 +542,7 @@ Foam::labelList Foam::decompositionMethods::zoltan::decompose
forAll(fineDistribution, i)
{
fineDistribution[i] = finalDecomp[agglom[i]];
fineDistribution[i] = decomp[agglom[i]];
}
return fineDistribution;
@ -555,16 +569,16 @@ Foam::labelList Foam::decompositionMethods::zoltan::decompose
CompactListList<label> pointPoints(globalPointPoints);
// Decompose using weights
List<label> finalDecomp;
List<label> decomp;
decompose
(
pointPoints,
points,
pWeights,
finalDecomp
decomp
);
return finalDecomp;
return decomp;
}