ENH: Prevent overflow in weight field.

This commit is contained in:
graham
2011-06-22 17:33:04 +01:00
parent 05fd8276e9
commit a0a6dfb19d
2 changed files with 36 additions and 11 deletions

View File

@ -483,8 +483,10 @@ if (debug)
// Check for externally provided cellweights and if so initialise weights // Check for externally provided cellweights and if so initialise weights
scalar minWeights = gMin(cWeights); scalar minWeights = gMin(cWeights);
if (cWeights.size() > 0)
if (!cWeights.empty())
{ {
if (minWeights <= 0) if (minWeights <= 0)
{ {
@ -504,12 +506,39 @@ if (debug)
<< " does not equal number of cells " << xadj.size()-1 << " does not equal number of cells " << xadj.size()-1
<< exit(FatalError); << exit(FatalError);
} }
}
scalar velotabSum = gSum(cWeights)/minWeights;
scalar rangeScale(1.0);
if (Pstream::master())
{
if (velotabSum > scalar(INT_MAX - 1))
{
// 0.9 factor of safety to avoid floating point round-off in
// rangeScale tipping the subsequent sum over the integer limit.
rangeScale = 0.9*scalar(INT_MAX - 1)/velotabSum;
WarningIn
(
"ptscotchDecomp::decompose(...)"
) << "Sum of weights has overflowed integer: " << velotabSum
<< ", compressing weight scale by a factor of " << rangeScale
<< endl;
}
}
Pstream::scatter(rangeScale);
if (!cWeights.empty())
{
// Convert to integers. // Convert to integers.
velotab.setSize(cWeights.size()); velotab.setSize(cWeights.size());
forAll(velotab, i) forAll(velotab, i)
{ {
velotab[i] = int(cWeights[i]/minWeights); velotab[i] = int((cWeights[i]/minWeights - 1)*rangeScale) + 1;
} }
} }

View File

@ -386,14 +386,13 @@ Foam::label Foam::scotchDecomp::decomposeOneProc
// Check for externally provided cellweights and if so initialise weights // Check for externally provided cellweights and if so initialise weights
// Note: min, not gMin since routine runs on master only. // Note: min, not gMin since routine runs on master only.
scalar minWeights = min(cWeights); scalar minWeights = min(cWeights);
if (cWeights.size() > 0) if (!cWeights.empty())
{ {
if (minWeights <= 0) if (minWeights <= 0)
{ {
WarningIn WarningIn
( (
"scotchDecomp::decompose" "scotchDecomp::decompose(...)"
"(const pointField&, const scalarField&)"
) << "Illegal minimum weight " << minWeights ) << "Illegal minimum weight " << minWeights
<< endl; << endl;
} }
@ -402,8 +401,7 @@ Foam::label Foam::scotchDecomp::decomposeOneProc
{ {
FatalErrorIn FatalErrorIn
( (
"scotchDecomp::decompose" "scotchDecomp::decompose(...)"
"(const pointField&, const scalarField&)"
) << "Number of cell weights " << cWeights.size() ) << "Number of cell weights " << cWeights.size()
<< " does not equal number of cells " << xadj.size()-1 << " does not equal number of cells " << xadj.size()-1
<< exit(FatalError); << exit(FatalError);
@ -421,8 +419,7 @@ Foam::label Foam::scotchDecomp::decomposeOneProc
WarningIn WarningIn
( (
"scotchDecomp::decompose" "scotchDecomp::decompose(...)"
"(const pointField&, const scalarField&)"
) << "Sum of weights has overflowed integer: " << velotabSum ) << "Sum of weights has overflowed integer: " << velotabSum
<< ", compressing weight scale by a factor of " << rangeScale << ", compressing weight scale by a factor of " << rangeScale
<< endl; << endl;
@ -433,8 +430,7 @@ Foam::label Foam::scotchDecomp::decomposeOneProc
forAll(velotab, i) forAll(velotab, i)
{ {
velotab[i] = velotab[i] = int((cWeights[i]/minWeights - 1)*rangeScale) + 1;
int((cWeights[i]/minWeights - 1)*rangeScale) + 1;
} }
} }