AMG solver robustness improvements

This commit is contained in:
Hrvoje Jasak 2013-06-27 17:50:02 +01:00
parent aef17bc3d0
commit 75be6fb23e
4 changed files with 73 additions and 21 deletions

View file

@ -197,7 +197,13 @@ void Foam::amgCycle::fixedCycle
{
// Calculate scaling factor using a buffer
coarseLevelPtr_->levelPtr_->scaleX(xCoarse, bCoarse, cmpt, xBuffer);
coarseLevelPtr_->levelPtr_->scaleX
(
xCoarse,
bCoarse,
cmpt,
xBuffer
);
}
levelPtr_->prolongateCorrection(x, xCoarse);
@ -208,7 +214,9 @@ void Foam::amgCycle::fixedCycle
else
{
// Call direct solver
levelPtr_->solve(x, b, cmpt, 1e-9, 0);
// Changed tolerance because a better guess will be used on coarsest
// mesh level. HJ, 27/Jun/2013
levelPtr_->solve(x, b, cmpt, 1e-6, 0);
}
}

View file

@ -35,8 +35,7 @@ Author
#include "coarseAmgLevel.H"
#include "SubField.H"
#include "ICCG.H"
#include "BICCG.H"
#include "gmresSolver.H"
#include "vector2D.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -188,33 +187,66 @@ void Foam::coarseAmgLevel::solve
{
lduSolverPerformance coarseSolverPerf;
label maxIter = Foam::min(2*policyPtr_->minCoarseEqns(), 1000);
dictionary topLevelDict;
topLevelDict.add("nDirections", "5");
topLevelDict.add("minIter", 1);
topLevelDict.add("maxIter", maxIter);
topLevelDict.add("tolerance", tolerance);
topLevelDict.add("relTol", relTol);
// Avoid issues with round-off on strict tolerance setup
// HJ, 27/Jun/2013
x = b/matrixPtr_->matrix().diag();
if (matrixPtr_->matrix().symmetric())
{
coarseSolverPerf = ICCG
topLevelDict.add("preconditioner", "Cholesky");
coarseSolverPerf = gmresSolver
(
"topLevelCorr",
matrixPtr_->matrix(),
matrixPtr_->coupleBouCoeffs(),
matrixPtr_->coupleIntCoeffs(),
matrixPtr_->interfaceFields(),
tolerance,
relTol
topLevelDict
).solve(x, b, cmpt);
}
else
{
coarseSolverPerf = BICCG
topLevelDict.add("preconditioner", "ILU0");
coarseSolverPerf = gmresSolver
(
"topLevelCorr",
matrixPtr_->matrix(),
matrixPtr_->coupleBouCoeffs(),
matrixPtr_->coupleIntCoeffs(),
matrixPtr_->interfaceFields(),
tolerance,
relTol
topLevelDict
).solve(x, b, cmpt);
}
// Escape cases of solver divergence
if
(
coarseSolverPerf.nIterations() == maxIter
&& (
coarseSolverPerf.finalResidual()
>= coarseSolverPerf.initialResidual()
)
)
{
// Top-level solution failed. Attempt rescue
// HJ, 27/Jul/2013
x = b/matrixPtr_->matrix().diag();
// Print top level correction failure as info for user
coarseSolverPerf.print();
}
if (lduMatrix::debug >= 2)
{
coarseSolverPerf.print();

View file

@ -35,8 +35,8 @@ Author
#include "fineAmgLevel.H"
#include "coarseAmgLevel.H"
#include "ICCG.H"
#include "BICCG.H"
#include "cgSolver.H"
#include "bicgStabSolver.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -183,30 +183,42 @@ void Foam::fineAmgLevel::solve
lduSolverPerformance coarseSolverPerf;
dictionary fineLevelDict;
fineLevelDict.add("minIter", 1);
fineLevelDict.add("maxIter", 1000);
fineLevelDict.add("tolerance", tolerance);
fineLevelDict.add("relTol", relTol);
// Avoid issues with round-off on strict tolerance setup
// HJ, 27/Jun/2013
x = b/matrix_.diag();
if (matrix_.symmetric())
{
coarseSolverPerf = ICCG
fineLevelDict.add("preconditioner", "Cholesky");
coarseSolverPerf = cgSolver
(
"topLevelCorr",
"fineLevelCorr",
matrix_,
coupleBouCoeffs_,
coupleIntCoeffs_,
interfaceFields_,
tolerance,
relTol
fineLevelDict
).solve(x, b, cmpt);
}
else
{
coarseSolverPerf = BICCG
fineLevelDict.add("preconditioner", "ILU0");
coarseSolverPerf = bicgStabSolver
(
"topLevelCorr",
"fineLevelCorr",
matrix_,
coupleBouCoeffs_,
coupleIntCoeffs_,
interfaceFields_,
tolerance,
relTol
fineLevelDict
).solve(x, b, cmpt);
}

View file

@ -75,7 +75,7 @@ class ILU0
public:
//- Runtime type information
TypeName("Cholesky");
TypeName("ILU0");
// Constructors