From 1faa10bed07cc14eb448b3ac0354e259a518e40c Mon Sep 17 00:00:00 2001 From: Hrvoje Jasak Date: Thu, 1 Jun 2017 10:21:19 +0100 Subject: [PATCH] Parallel block selective AMG. Tessa Uroic --- .../BlockMatrixSelection.C | 684 ++++++++---------- 1 file changed, 321 insertions(+), 363 deletions(-) diff --git a/src/foam/matrices/blockLduMatrix/BlockAMG/BlockMatrixCoarsening/BlockMatrixSelection/BlockMatrixSelection.C b/src/foam/matrices/blockLduMatrix/BlockAMG/BlockMatrixCoarsening/BlockMatrixSelection/BlockMatrixSelection.C index 7207aba0d..9e5460555 100644 --- a/src/foam/matrices/blockLduMatrix/BlockAMG/BlockMatrixCoarsening/BlockMatrixSelection/BlockMatrixSelection.C +++ b/src/foam/matrices/blockLduMatrix/BlockAMG/BlockMatrixCoarsening/BlockMatrixSelection/BlockMatrixSelection.C @@ -132,7 +132,6 @@ Foam::BlockMatrixSelection::filterProlongation } - template void Foam::BlockMatrixSelection::calcCoarsening() { @@ -141,12 +140,9 @@ void Foam::BlockMatrixSelection::calcCoarsening() //------------------------------------------------------------------------------ // Get addressing - const unallocLabelList& rowStart = matrix_.lduAddr().ownerStartAddr(); - const unallocLabelList& losortAddr = matrix_.lduAddr().losortAddr(); - const unallocLabelList& losortStart = matrix_.lduAddr().losortStartAddr(); - const unallocLabelList& column = matrix_.lduAddr().upperAddr(); - const unallocLabelList& row = matrix_.lduAddr().lowerAddr(); - const label matrixSize = matrix_.lduAddr().size(); + const label nRows = matrix_.lduAddr().size(); + const unallocLabelList& row = matrix_.lduAddr().ownerStartAddr(); + const unallocLabelList& col = matrix_.lduAddr().upperAddr(); // Note: not taking norm magnitudes. HJ, 28/Feb/2017 @@ -155,15 +151,15 @@ void Foam::BlockMatrixSelection::calcCoarsening() //------------------------------------------------------------------------------ // Calculate norm for diagonal coefficients - scalarField normDiag(matrixSize); + scalarField normDiag(nRows); coarseningNormPtr_->normalize(normDiag, matrix_.diag()); // Calculate norm for upper triangle coeffs (magUpper) - scalarField normUpper(row.size()); + scalarField normUpper(col.size()); coarseningNormPtr_->normalize(normUpper, matrix_.upper()); // Calculate norm for lower triangle coeffs (magLower) - scalarField normLower(column.size()); + scalarField normLower(col.size()); coarseningNormPtr_->normalize(normLower, matrix_.lower()); // Calculate norm magnitudes @@ -175,15 +171,15 @@ void Foam::BlockMatrixSelection::calcCoarsening() //------------------------------------------------------------------------------ // Calculate norm for diagonal coefficients (store into magDiag) - scalarField interpolationNormDiag(matrixSize); + scalarField interpolationNormDiag(nRows); interpolationNormPtr_->normalize(interpolationNormDiag, matrix_.diag()); // Calculate norm for upper triangle coeffs (magUpper) - scalarField interpolationNormUpper(column.size()); + scalarField interpolationNormUpper(col.size()); interpolationNormPtr_->normalize(interpolationNormUpper, matrix_.upper()); // Calculate norm for lower triangle coeffs (magLower) - scalarField interpolationNormLower(column.size()); + scalarField interpolationNormLower(col.size()); interpolationNormPtr_->normalize(interpolationNormLower, matrix_.lower()); //------------------------------------------------------------------------------ @@ -199,68 +195,66 @@ void Foam::BlockMatrixSelection::calcCoarsening() // because it has coeffs on the off-diagonal with sign opposite to diagonal // Create largest norm. It will be multiplied by epsilon later - scalarField epsLargestNorm(matrixSize, 0); + scalarField epsilonStrongCoeff(nRows, 0); - register label j = -1; - - for (register label i = 0; i < matrixSize; i++) + for (register label i = 0; i < nRows; i++) { scalar signDiag = sign(normDiag[i]); - for (register label k = rowStart[i]; k < rowStart[i + 1]; k++) + for (register label k = row[i]; k < row[i + 1]; k++) { + // Lower triangle + label j = col[k]; + // Do row coefficient scalar magAij = mag(min(signDiag*normUpper[k], 0)); // Upper triangle - if (magAij > epsLargestNorm[i]) + if (magAij > epsilonStrongCoeff[i]) { - epsLargestNorm[i] = magAij; + epsilonStrongCoeff[i] = magAij; } // Do col coefficient scalar magAji = mag(min(signDiag*normLower[k], 0)); - // Lower triangle - j = column[k]; - - if (magAji > epsLargestNorm[j]) + if (magAji > epsilonStrongCoeff[j]) { - epsLargestNorm[j] = magAji; + epsilonStrongCoeff[j] = magAji; } } } // Multiply largest norm by epsilon. This is now used below - epsLargestNorm *= epsilon_(); + epsilonStrongCoeff *= epsilon_(); - // Count strong elements in each row - for rowStart addressing + // Count strong elements in each row - for row addressing // Note: checking magnitude of coeff, which accounts for both strong // positive and negative coefficients. HJ, 28/Feb/2017 - labelList strongCoeffCounter(matrixSize, 0); + labelList strongCoeffCounter(nRows, 0); - for (register label i = 0; i < matrixSize; i++) + for (register label i = 0; i < nRows; i++) { scalar signDiag = sign(normDiag[i]); - for (register label k = rowStart[i]; k < rowStart [i + 1]; k++) + for (register label k = row[i]; k < row[i + 1]; k++) { + // Col of coefficient k in row i + label j = col[k]; + // Do row coefficient scalar magAij = mag(min(signDiag*normUpper[k], 0)); // Upper triangle - if (magAij > epsLargestNorm[i]) + if (magAij > epsilonStrongCoeff[i]) { - strongCoeffCounter[i]++; + strongCoeffCounter[i]++; } // Do col coefficient scalar magAji = mag(min(signDiag*normLower[k], 0)); - // Column of coefficient k in row i - j = column[k]; - - if (magAji > epsLargestNorm[j]) + if (magAji > epsilonStrongCoeff[j]) { strongCoeffCounter[j]++; } @@ -272,52 +266,53 @@ void Foam::BlockMatrixSelection::calcCoarsening() // (some will become FINE and some COARSE - and this will determine the // direct and standard interpolation procedures) - crMatrix strong(matrixSize, matrixSize, strongCoeffCounter); + crMatrix strong(nRows, nRows, strongCoeffCounter); // Set addressing for the matrix: // stongCol and strongElement are arrays needed to create a compressed row // matrix - const labelList& strongRowStart = strong.crAddr().rowStart(); + const label sNRows = strong.crAddr().nRows(); + const labelList& strongRow = strong.crAddr().rowStart(); labelList& strongCol = strong.column(); scalarField& strongCoeff = strong.coeffs(); - // Counter for counting the strong elements in a row - labelList counter(matrixSize, 0); + // Reset strongCoeffCounter for re-use + strongCoeffCounter = 0; - for (register label i = 0; i < matrixSize; i++) + for (register label i = 0; i < nRows; i++) { scalar signDiag = sign(normDiag[i]); - for (register label k = rowStart[i]; k < rowStart [i+1]; k++) + for (register label k = row[i]; k < row[i + 1]; k++) { + // Col of coefficient k in row i + label j = col[k]; + // Check elements in upper triangle scalar magAij = mag(min(signDiag*normUpper[k], 0)); - if (magAij > epsLargestNorm[i]) + if (magAij > epsilonStrongCoeff[i]) { // Store the strong elements into crMatrix, use counter // to count the number of negative strong elements for // each row i - strongCol[strongRowStart[i] + counter[i]] = j; - strongCoeff[strongRowStart[i] + counter[i]] = + strongCol[strongRow[i] + strongCoeffCounter[i]] = j; + strongCoeff[strongRow[i] + strongCoeffCounter[i]] = interpolationNormUpper[k]; - counter[i]++; + strongCoeffCounter[i]++; } // Check elements in lower triangle scalar magAji = mag(min(signDiag*normLower[k], 0)); - // Column of coefficient k in row i - j = column[k]; - - if (magAji > epsLargestNorm[j]) + if (magAji > epsilonStrongCoeff[j]) { - strongCol[strongRowStart[j] + counter[j]] = i; - strongCoeff[strongRowStart[j] + counter[j]] = + strongCol[strongRow[j] + strongCoeffCounter[j]] = i; + strongCoeff[strongRow[j] + strongCoeffCounter[j]] = interpolationNormLower[k]; - counter[j]++; + strongCoeffCounter[j]++; } } } @@ -338,17 +333,21 @@ void Foam::BlockMatrixSelection::calcCoarsening() // (weight of the element) // Mark equations - rowLabel_.setSize(matrixSize, UNDECIDED); + rowLabel_.setSize(nRows, UNDECIDED); - PriorityList