Use only one norm in block selective AMG
This commit is contained in:
parent
c5fd9c9326
commit
e48f1057fd
2 changed files with 37 additions and 65 deletions
|
@ -147,41 +147,25 @@ void Foam::BlockMatrixSelection<Type>::calcCoarsening()
|
||||||
// Note: not taking norm magnitudes. HJ, 28/Feb/2017
|
// Note: not taking norm magnitudes. HJ, 28/Feb/2017
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// CALCULATE COARSENING NORM
|
// CALCULATE NORM
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Calculate norm for diagonal coefficients
|
// Calculate norm for diagonal coefficients
|
||||||
scalarField normDiag(nRows);
|
scalarField normDiag(nRows);
|
||||||
coarseningNormPtr_->normalize(normDiag, matrix_.diag());
|
normPtr_->normalize(normDiag, matrix_.diag());
|
||||||
|
|
||||||
// Calculate norm for upper triangle coeffs (magUpper)
|
// Calculate norm for upper triangle coeffs (magUpper)
|
||||||
scalarField normUpper(col.size());
|
scalarField normUpper(col.size());
|
||||||
coarseningNormPtr_->normalize(normUpper, matrix_.upper());
|
normPtr_->normalize(normUpper, matrix_.upper());
|
||||||
|
|
||||||
// Calculate norm for lower triangle coeffs (magLower)
|
// Calculate norm for lower triangle coeffs (magLower)
|
||||||
scalarField normLower(col.size());
|
scalarField normLower(col.size());
|
||||||
coarseningNormPtr_->normalize(normLower, matrix_.lower());
|
normPtr_->normalize(normLower, matrix_.lower());
|
||||||
|
|
||||||
// Calculate norm magnitudes
|
// Calculate norm magnitudes
|
||||||
scalarField magNormUpper = mag(normUpper);
|
scalarField magNormUpper = mag(normUpper);
|
||||||
scalarField magNormLower = mag(normLower);
|
scalarField magNormLower = mag(normLower);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// CALCULATE INTERPOLATION NORM
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Calculate norm for diagonal coefficients (store into magDiag)
|
|
||||||
scalarField interpolationNormDiag(nRows);
|
|
||||||
interpolationNormPtr_->normalize(interpolationNormDiag, matrix_.diag());
|
|
||||||
|
|
||||||
// Calculate norm for upper triangle coeffs (magUpper)
|
|
||||||
scalarField interpolationNormUpper(col.size());
|
|
||||||
interpolationNormPtr_->normalize(interpolationNormUpper, matrix_.upper());
|
|
||||||
|
|
||||||
// Calculate norm for lower triangle coeffs (magLower)
|
|
||||||
scalarField interpolationNormLower(col.size());
|
|
||||||
interpolationNormPtr_->normalize(interpolationNormLower, matrix_.lower());
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// CRITERIA FOR COARSENING: FIND STRONG CONNECTIONS FOR EACH ROW
|
// CRITERIA FOR COARSENING: FIND STRONG CONNECTIONS FOR EACH ROW
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -197,6 +181,8 @@ void Foam::BlockMatrixSelection<Type>::calcCoarsening()
|
||||||
// Create largest norm. It will be multiplied by epsilon later
|
// Create largest norm. It will be multiplied by epsilon later
|
||||||
scalarField epsilonStrongCoeff(nRows, 0);
|
scalarField epsilonStrongCoeff(nRows, 0);
|
||||||
|
|
||||||
|
// Select strongest coefficient in each row
|
||||||
|
|
||||||
for (register label i = 0; i < nRows; i++)
|
for (register label i = 0; i < nRows; i++)
|
||||||
{
|
{
|
||||||
scalar signDiag = sign(normDiag[i]);
|
scalar signDiag = sign(normDiag[i]);
|
||||||
|
@ -298,7 +284,7 @@ void Foam::BlockMatrixSelection<Type>::calcCoarsening()
|
||||||
// each row i
|
// each row i
|
||||||
strongCol[strongRow[i] + strongCoeffCounter[i]] = j;
|
strongCol[strongRow[i] + strongCoeffCounter[i]] = j;
|
||||||
strongCoeff[strongRow[i] + strongCoeffCounter[i]] =
|
strongCoeff[strongRow[i] + strongCoeffCounter[i]] =
|
||||||
interpolationNormUpper[k];
|
normUpper[k];
|
||||||
|
|
||||||
strongCoeffCounter[i]++;
|
strongCoeffCounter[i]++;
|
||||||
}
|
}
|
||||||
|
@ -310,7 +296,7 @@ void Foam::BlockMatrixSelection<Type>::calcCoarsening()
|
||||||
{
|
{
|
||||||
strongCol[strongRow[j] + strongCoeffCounter[j]] = i;
|
strongCol[strongRow[j] + strongCoeffCounter[j]] = i;
|
||||||
strongCoeff[strongRow[j] + strongCoeffCounter[j]] =
|
strongCoeff[strongRow[j] + strongCoeffCounter[j]] =
|
||||||
interpolationNormLower[k];
|
normLower[k];
|
||||||
|
|
||||||
strongCoeffCounter[j]++;
|
strongCoeffCounter[j]++;
|
||||||
}
|
}
|
||||||
|
@ -429,7 +415,7 @@ void Foam::BlockMatrixSelection<Type>::calcCoarsening()
|
||||||
scalarField num(nRows, 0);
|
scalarField num(nRows, 0);
|
||||||
|
|
||||||
// Sum of positive elements in row (sign equal to diagonal)
|
// Sum of positive elements in row (sign equal to diagonal)
|
||||||
scalarField Dii(sign(interpolationNormDiag)*interpolationNormDiag);
|
scalarField Dii(sign(normDiag)*normDiag);
|
||||||
|
|
||||||
scalar Dij, Dji, den, signDii;
|
scalar Dij, Dji, den, signDii;
|
||||||
|
|
||||||
|
@ -462,7 +448,7 @@ void Foam::BlockMatrixSelection<Type>::calcCoarsening()
|
||||||
{
|
{
|
||||||
// Get norm of boundary coefficients
|
// Get norm of boundary coefficients
|
||||||
scalarField normCplUpper(matrix_.coupleUpper()[intI].size());
|
scalarField normCplUpper(matrix_.coupleUpper()[intI].size());
|
||||||
interpolationNormPtr_->normalize
|
normPtr_->normalize
|
||||||
(
|
(
|
||||||
normCplUpper,
|
normCplUpper,
|
||||||
matrix_.coupleUpper()[intI]
|
matrix_.coupleUpper()[intI]
|
||||||
|
@ -478,7 +464,7 @@ void Foam::BlockMatrixSelection<Type>::calcCoarsening()
|
||||||
const label i = faceCells[coeffI];
|
const label i = faceCells[coeffI];
|
||||||
|
|
||||||
// Get sign of diagonal coeff
|
// Get sign of diagonal coeff
|
||||||
scalar signDiag = sign(interpolationNormDiag[i]);
|
scalar signDiag = sign(normDiag[i]);
|
||||||
|
|
||||||
// Adjust sign of off-diag coeff
|
// Adjust sign of off-diag coeff
|
||||||
// Note: additional minus because the sign of interface
|
// Note: additional minus because the sign of interface
|
||||||
|
@ -528,12 +514,12 @@ void Foam::BlockMatrixSelection<Type>::calcCoarsening()
|
||||||
|
|
||||||
// Handle the unknown sign of diagonal: multiplying
|
// Handle the unknown sign of diagonal: multiplying
|
||||||
// row coeffs by the sign
|
// row coeffs by the sign
|
||||||
signDii = sign(interpolationNormDiag[i]);
|
signDii = sign(normDiag[i]);
|
||||||
|
|
||||||
for (label k = row[i]; k < row[i + 1]; k++)
|
for (label k = row[i]; k < row[i + 1]; k++)
|
||||||
{
|
{
|
||||||
// Adjust sign of off-diag coeff
|
// Adjust sign of off-diag coeff
|
||||||
Dij = signDii*interpolationNormUpper[k];
|
Dij = signDii*normUpper[k];
|
||||||
|
|
||||||
// Add negative coeff to num
|
// Add negative coeff to num
|
||||||
// Add positive coeff to diag to eliminate it
|
// Add positive coeff to diag to eliminate it
|
||||||
|
@ -543,7 +529,7 @@ void Foam::BlockMatrixSelection<Type>::calcCoarsening()
|
||||||
// Scatter lower triangular contribution
|
// Scatter lower triangular contribution
|
||||||
label j = col[k];
|
label j = col[k];
|
||||||
|
|
||||||
Dji = sign(interpolationNormDiag[j])*interpolationNormLower[k];
|
Dji = sign(normDiag[j])*normLower[k];
|
||||||
num[j] += Foam::min(Dji, 0);
|
num[j] += Foam::min(Dji, 0);
|
||||||
Dii[j] += Foam::max(Dji, 0);
|
Dii[j] += Foam::max(Dji, 0);
|
||||||
}
|
}
|
||||||
|
@ -598,27 +584,27 @@ void Foam::BlockMatrixSelection<Type>::calcCoarsening()
|
||||||
|
|
||||||
prolongation.coeffs().transfer(pCoeff);
|
prolongation.coeffs().transfer(pCoeff);
|
||||||
|
|
||||||
// Check prolongation matrix
|
// // Check prolongation matrix
|
||||||
{
|
// {
|
||||||
scalarField sumRow(nRows, 0);
|
// scalarField sumRow(nRows, 0);
|
||||||
const labelList& prolongationRow = Pptr_->crAddr().rowStart();
|
// const labelList& prolongationRow = Pptr_->crAddr().rowStart();
|
||||||
const scalarField& prolongationCoeff = Pptr_->coeffs();
|
// const scalarField& prolongationCoeff = Pptr_->coeffs();
|
||||||
|
|
||||||
for (label rowI = 0; rowI < nRows; rowI++)
|
// for (label rowI = 0; rowI < nRows; rowI++)
|
||||||
{
|
// {
|
||||||
for
|
// for
|
||||||
(
|
// (
|
||||||
label colI = prolongationRow[rowI];
|
// label colI = prolongationRow[rowI];
|
||||||
colI < prolongationRow[rowI + 1];
|
// colI < prolongationRow[rowI + 1];
|
||||||
colI++
|
// colI++
|
||||||
)
|
// )
|
||||||
{
|
// {
|
||||||
sumRow[rowI] += prolongationCoeff[colI];
|
// sumRow[rowI] += prolongationCoeff[colI];
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
Pout<< "sumRow (min, max) = (" << min(sumRow) << " "
|
// Pout<< "sumRow (min, max) = (" << min(sumRow) << " "
|
||||||
<< max(sumRow) << ")" << endl;
|
// << max(sumRow) << ")" << endl;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// The decision on parallel agglomeration needs to be made for the
|
// The decision on parallel agglomeration needs to be made for the
|
||||||
// whole gang of processes; otherwise I may end up with a different
|
// whole gang of processes; otherwise I may end up with a different
|
||||||
|
@ -676,14 +662,7 @@ Foam::BlockMatrixSelection<Type>::BlockMatrixSelection
|
||||||
:
|
:
|
||||||
BlockMatrixCoarsening<Type>(matrix, dict, groupSize, minCoarseEqns),
|
BlockMatrixCoarsening<Type>(matrix, dict, groupSize, minCoarseEqns),
|
||||||
matrix_(matrix),
|
matrix_(matrix),
|
||||||
coarseningNormPtr_
|
normPtr_(BlockCoeffNorm<Type>::New(dict)),
|
||||||
(
|
|
||||||
BlockCoeffNorm<Type>::New(dict.subDict("coarseningNorm"))
|
|
||||||
),
|
|
||||||
interpolationNormPtr_
|
|
||||||
(
|
|
||||||
BlockCoeffNorm<Type>::New(dict.subDict("interpolationNorm"))
|
|
||||||
),
|
|
||||||
nCoarseEqns_(0),
|
nCoarseEqns_(0),
|
||||||
coarsen_(false),
|
coarsen_(false),
|
||||||
Pptr_(NULL),
|
Pptr_(NULL),
|
||||||
|
|
|
@ -78,15 +78,8 @@ class BlockMatrixSelection
|
||||||
//- Reference to matrix
|
//- Reference to matrix
|
||||||
const BlockLduMatrix<Type>& matrix_;
|
const BlockLduMatrix<Type>& matrix_;
|
||||||
|
|
||||||
//- Reference to a templated norm calculator
|
//- Norm calculator
|
||||||
//- INFO: This norm will be calculated for coarsening process (it can be
|
autoPtr<BlockCoeffNorm<Type> > normPtr_;
|
||||||
//- arbitrary: component norm, max norm, two norm)
|
|
||||||
autoPtr<BlockCoeffNorm<Type> > coarseningNormPtr_;
|
|
||||||
|
|
||||||
//- Reference to a templated norm calculator
|
|
||||||
//- INFO: This norm will be used for interpolation. Component norm based
|
|
||||||
//- on a representative equation is recommended.
|
|
||||||
autoPtr<BlockCoeffNorm<Type> > interpolationNormPtr_;
|
|
||||||
|
|
||||||
//- Number of coarse equations
|
//- Number of coarse equations
|
||||||
label nCoarseEqns_;
|
label nCoarseEqns_;
|
||||||
|
|
Reference in a new issue