Improved normalisation of reported residuals for block-coupled systems
This commit is contained in:
parent
93849cea09
commit
7ef4377a9c
10 changed files with 38 additions and 35 deletions
|
@ -72,10 +72,10 @@ Foam::BlockAMGSolver<Type>::solve
|
||||||
this->fieldName()
|
this->fieldName()
|
||||||
);
|
);
|
||||||
|
|
||||||
scalar norm = this->normFactor(x, b);
|
Type norm = this->normFactor(x, b);
|
||||||
|
|
||||||
// Calculate initial residual
|
// Calculate initial residual
|
||||||
solverPerf.initialResidual() = gSum(cmptMag(amg_.residual(x, b)))/norm;
|
solverPerf.initialResidual() = cmptDivide(gSum(cmptMag(amg_.residual(x, b))),norm);
|
||||||
solverPerf.finalResidual() = solverPerf.initialResidual();
|
solverPerf.finalResidual() = solverPerf.initialResidual();
|
||||||
|
|
||||||
// Stop solver on divergence
|
// Stop solver on divergence
|
||||||
|
@ -88,8 +88,8 @@ Foam::BlockAMGSolver<Type>::solve
|
||||||
{
|
{
|
||||||
amg_.cycle(x, b);
|
amg_.cycle(x, b);
|
||||||
|
|
||||||
solverPerf.finalResidual() =
|
solverPerf.finalResidual() =
|
||||||
gSum(cmptMag(amg_.residual(x, b)))/norm;
|
cmptDivide(gSum(cmptMag(amg_.residual(x, b))), norm);
|
||||||
|
|
||||||
solverPerf.nIterations()++;
|
solverPerf.nIterations()++;
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ Foam::BlockBiCGStabSolver<Type>::solve
|
||||||
this->fieldName()
|
this->fieldName()
|
||||||
);
|
);
|
||||||
|
|
||||||
scalar norm = this->normFactor(x, b);
|
Type norm = this->normFactor(x, b);
|
||||||
|
|
||||||
// Multiplication helper
|
// Multiplication helper
|
||||||
typename BlockCoeff<Type>::multiply mult;
|
typename BlockCoeff<Type>::multiply mult;
|
||||||
|
@ -87,7 +87,8 @@ Foam::BlockBiCGStabSolver<Type>::solve
|
||||||
matrix.Amul(p, x);
|
matrix.Amul(p, x);
|
||||||
Field<Type> r(b - p);
|
Field<Type> r(b - p);
|
||||||
|
|
||||||
solverPerf.initialResidual() = gSum(cmptMag(r))/norm;
|
// NOTE: Normalisation of residual per component! TU, Feb 2019
|
||||||
|
solverPerf.initialResidual() = cmptDivide(gSum(cmptMag(r)),norm);
|
||||||
solverPerf.finalResidual() = solverPerf.initialResidual();
|
solverPerf.finalResidual() = solverPerf.initialResidual();
|
||||||
|
|
||||||
// Check convergence, solve if not converged
|
// Check convergence, solve if not converged
|
||||||
|
@ -160,7 +161,7 @@ Foam::BlockBiCGStabSolver<Type>::solve
|
||||||
r[i] = s[i] - omega*t[i];
|
r[i] = s[i] - omega*t[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
solverPerf.finalResidual() = gSum(cmptMag(r))/norm;
|
solverPerf.finalResidual() = cmptDivide(gSum(cmptMag(r)), norm);
|
||||||
solverPerf.nIterations()++;
|
solverPerf.nIterations()++;
|
||||||
} while (!this->stop(solverPerf));
|
} while (!this->stop(solverPerf));
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ typename Foam::BlockSolverPerformance<Type> Foam::BlockCGSolver<Type>::solve
|
||||||
this->fieldName()
|
this->fieldName()
|
||||||
);
|
);
|
||||||
|
|
||||||
scalar norm = this->normFactor(x, b);
|
Type norm = this->normFactor(x, b);
|
||||||
|
|
||||||
Field<Type> wA(x.size());
|
Field<Type> wA(x.size());
|
||||||
|
|
||||||
|
@ -83,7 +83,8 @@ typename Foam::BlockSolverPerformance<Type> Foam::BlockCGSolver<Type>::solve
|
||||||
matrix.Amul(wA, x);
|
matrix.Amul(wA, x);
|
||||||
Field<Type> rA(b - wA);
|
Field<Type> rA(b - wA);
|
||||||
|
|
||||||
solverPerf.initialResidual() = gSum(cmptMag(rA))/norm;
|
// NOTE: Normalisation of residual per component! TU, Feb 2019
|
||||||
|
solverPerf.initialResidual() = cmptDivide(gSum(cmptMag(rA)),norm);
|
||||||
solverPerf.finalResidual() = solverPerf.initialResidual();
|
solverPerf.finalResidual() = solverPerf.initialResidual();
|
||||||
|
|
||||||
// Check convergence, solve if not converged
|
// Check convergence, solve if not converged
|
||||||
|
@ -120,7 +121,7 @@ typename Foam::BlockSolverPerformance<Type> Foam::BlockCGSolver<Type>::solve
|
||||||
wApA = gSumProd(wA, pA);
|
wApA = gSumProd(wA, pA);
|
||||||
|
|
||||||
// Check for singularity
|
// Check for singularity
|
||||||
if (solverPerf.checkSingularity(mag(wApA)/norm))
|
if (solverPerf.checkSingularity(mag(wApA)/mag(norm)))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -138,7 +139,7 @@ typename Foam::BlockSolverPerformance<Type> Foam::BlockCGSolver<Type>::solve
|
||||||
rA[i] -= alpha*wA[i];
|
rA[i] -= alpha*wA[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
solverPerf.finalResidual() = gSum(cmptMag(rA))/norm;
|
solverPerf.finalResidual() = cmptDivide(gSum(cmptMag(rA)), norm);
|
||||||
solverPerf.nIterations()++;
|
solverPerf.nIterations()++;
|
||||||
} while (!this->stop(solverPerf));
|
} while (!this->stop(solverPerf));
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ Foam::BlockGMRESSolver<Type>::solve
|
||||||
this->fieldName()
|
this->fieldName()
|
||||||
);
|
);
|
||||||
|
|
||||||
scalar norm = this->normFactor(x, b);
|
Type norm = this->normFactor(x, b);
|
||||||
|
|
||||||
Field<Type> wA(x.size());
|
Field<Type> wA(x.size());
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ Foam::BlockGMRESSolver<Type>::solve
|
||||||
matrix.Amul(wA, x);
|
matrix.Amul(wA, x);
|
||||||
Field<Type> rA(b - wA);
|
Field<Type> rA(b - wA);
|
||||||
|
|
||||||
solverPerf.initialResidual() = gSum(cmptMag(rA))/norm;
|
solverPerf.initialResidual() = cmptDivide(gSum(cmptMag(rA)),norm);
|
||||||
solverPerf.finalResidual() = solverPerf.initialResidual();
|
solverPerf.finalResidual() = solverPerf.initialResidual();
|
||||||
|
|
||||||
// Check convergence, solve if not converged
|
// Check convergence, solve if not converged
|
||||||
|
@ -234,7 +234,7 @@ Foam::BlockGMRESSolver<Type>::solve
|
||||||
rA[raI] = b[raI] - wA[raI];
|
rA[raI] = b[raI] - wA[raI];
|
||||||
}
|
}
|
||||||
|
|
||||||
solverPerf.finalResidual() = gSum(cmptMag(rA))/norm;
|
solverPerf.finalResidual() = cmptDivide(gSum(cmptMag(rA)), norm);
|
||||||
solverPerf.nIterations()++;
|
solverPerf.nIterations()++;
|
||||||
} while (!this->stop(solverPerf));
|
} while (!this->stop(solverPerf));
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ Foam::BlockGaussSeidelSolver<Type>::solve
|
||||||
this->fieldName()
|
this->fieldName()
|
||||||
);
|
);
|
||||||
|
|
||||||
scalar norm = this->normFactor(x, b);
|
Type norm = this->normFactor(x, b);
|
||||||
|
|
||||||
Field<Type> wA(x.size());
|
Field<Type> wA(x.size());
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ Foam::BlockGaussSeidelSolver<Type>::solve
|
||||||
matrix.Amul(wA, x);
|
matrix.Amul(wA, x);
|
||||||
wA -= b;
|
wA -= b;
|
||||||
|
|
||||||
solverPerf.initialResidual() = gSum(cmptMag(wA))/norm;
|
solverPerf.initialResidual() = cmptDivide(gSum(cmptMag(wA)),norm);
|
||||||
solverPerf.finalResidual() = solverPerf.initialResidual();
|
solverPerf.finalResidual() = solverPerf.initialResidual();
|
||||||
|
|
||||||
// Check convergence, solve if not converged
|
// Check convergence, solve if not converged
|
||||||
|
@ -103,7 +103,7 @@ Foam::BlockGaussSeidelSolver<Type>::solve
|
||||||
matrix.Amul(wA, x);
|
matrix.Amul(wA, x);
|
||||||
wA -= b;
|
wA -= b;
|
||||||
|
|
||||||
solverPerf.finalResidual() = gSum(cmptMag(wA))/norm;
|
solverPerf.finalResidual() = cmptDivide(gSum(cmptMag(wA)), norm);
|
||||||
} while (!this->stop(solverPerf));
|
} while (!this->stop(solverPerf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ Foam::BlockILUSolver<Type>::solve
|
||||||
this->fieldName()
|
this->fieldName()
|
||||||
);
|
);
|
||||||
|
|
||||||
scalar norm = this->normFactor(x, b);
|
Type norm = this->normFactor(x, b);
|
||||||
|
|
||||||
Field<Type> residual(x.size());
|
Field<Type> residual(x.size());
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ Foam::BlockILUSolver<Type>::solve
|
||||||
residual[i] = b[i] - residual[i];
|
residual[i] = b[i] - residual[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
solverPerf.initialResidual() = gSum(cmptMag(residual))/norm;
|
solverPerf.initialResidual() = cmptDivide(gSum(cmptMag(residual)),norm);
|
||||||
solverPerf.finalResidual() = solverPerf.initialResidual();
|
solverPerf.finalResidual() = solverPerf.initialResidual();
|
||||||
|
|
||||||
// Check convergence, solve if not converged
|
// Check convergence, solve if not converged
|
||||||
|
@ -114,7 +114,7 @@ Foam::BlockILUSolver<Type>::solve
|
||||||
residual[i] = b[i] - residual[i];
|
residual[i] = b[i] - residual[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
solverPerf.finalResidual() = gSum(cmptMag(residual))/norm;
|
solverPerf.finalResidual() = cmptDivide(gSum(cmptMag(residual)), norm);
|
||||||
} while (!this->stop(solverPerf));
|
} while (!this->stop(solverPerf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ Foam::BlockIterativeSolver<Type>::BlockIterativeSolver
|
||||||
// * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * //
|
// * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::scalar Foam::BlockIterativeSolver<Type>::normFactor
|
Type Foam::BlockIterativeSolver<Type>::normFactor
|
||||||
(
|
(
|
||||||
Field<Type>& x,
|
Field<Type>& x,
|
||||||
const Field<Type>& b
|
const Field<Type>& b
|
||||||
|
@ -77,7 +77,13 @@ Foam::scalar Foam::BlockIterativeSolver<Type>::normFactor
|
||||||
Field<Type>(nRows, xRef)
|
Field<Type>(nRows, xRef)
|
||||||
);
|
);
|
||||||
|
|
||||||
scalar normFactor = gSum(mag(wA - pA) + mag(b - pA)) + this->small_;
|
// The components of the normalisation factor cannot be equal to 0 since it
|
||||||
|
// appears in the denominator: replace zero with small_
|
||||||
|
Type small = pTraits<Type>::one*this->small_;
|
||||||
|
|
||||||
|
// Norm factor for the block matrix is not a scalar since each component
|
||||||
|
// should be normalised with a value corresponding to a particular variable
|
||||||
|
Type normFactor = gSum(cmptMag(wA - pA) + cmptMag(b - pA)) + small;
|
||||||
|
|
||||||
if (blockLduMatrix::debug >= 2)
|
if (blockLduMatrix::debug >= 2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -84,7 +84,7 @@ protected:
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
|
|
||||||
//- Return normalisation factor
|
//- Return normalisation factor
|
||||||
scalar normFactor
|
Type normFactor
|
||||||
(
|
(
|
||||||
Field<Type>& x,
|
Field<Type>& x,
|
||||||
const Field<Type>& b
|
const Field<Type>& b
|
||||||
|
@ -107,10 +107,9 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
//- Destructor
|
||||||
|
virtual ~BlockIterativeSolver()
|
||||||
virtual ~BlockIterativeSolver()
|
{}
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
|
@ -39,14 +39,9 @@ bool Foam::BlockSolverPerformance<Type>::checkConvergence
|
||||||
{
|
{
|
||||||
Info<< solverName_
|
Info<< solverName_
|
||||||
<< ": Iteration " << nIterations_
|
<< ": Iteration " << nIterations_
|
||||||
<< " residual = " << finalResidual_;
|
<< " residual = " << finalResidual_
|
||||||
|
<< " mag = " << mag(finalResidual_)
|
||||||
if (pTraits<Type>::rank > 0)
|
<< " tol = "
|
||||||
{
|
|
||||||
Info<< " mag = " << mag(finalResidual_);
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< " tol = "
|
|
||||||
<< Foam::max(Tolerance, RelTolerance*mag(initialResidual_))
|
<< Foam::max(Tolerance, RelTolerance*mag(initialResidual_))
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ defineNamedTemplateTypeNameAndDebug(BlockSolverPerformanceVector, 1);
|
||||||
defineNamedTemplateTypeNameAndDebug(BlockSolverPerformanceSphericalTensor, 1);
|
defineNamedTemplateTypeNameAndDebug(BlockSolverPerformanceSphericalTensor, 1);
|
||||||
defineNamedTemplateTypeNameAndDebug(BlockSolverPerformanceSymmTensor, 1);
|
defineNamedTemplateTypeNameAndDebug(BlockSolverPerformanceSymmTensor, 1);
|
||||||
defineNamedTemplateTypeNameAndDebug(BlockSolverPerformanceTensor, 1);
|
defineNamedTemplateTypeNameAndDebug(BlockSolverPerformanceTensor, 1);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in a new issue