ENH: PCG: cache preconditioner

This commit is contained in:
Mattijs Janssens
2023-06-15 12:33:25 +00:00
committed by Andrew Heather
parent f1f797a815
commit 40d6ba19b1
13 changed files with 160 additions and 39 deletions

View File

@ -575,6 +575,10 @@ public:
{ {
NotImplemented; NotImplemented;
} }
//- Signal end of solver
virtual void setFinished(const solverPerformance& perf) const
{}
}; };

View File

@ -159,12 +159,14 @@ Foam::solverPerformance Foam::FPCG::scalarSolve
) )
{ {
// --- Select and construct the preconditioner // --- Select and construct the preconditioner
autoPtr<lduMatrix::preconditioner> preconPtr = if (!preconPtr_)
lduMatrix::preconditioner::New {
preconPtr_ = lduMatrix::preconditioner::New
( (
*this, *this,
controlDict_ controlDict_
); );
}
FixedList<solveScalar, 2> globalSum; FixedList<solveScalar, 2> globalSum;
@ -175,7 +177,7 @@ Foam::solverPerformance Foam::FPCG::scalarSolve
wArAold = wArA; wArAold = wArA;
// --- Precondition residual // --- Precondition residual
preconPtr->precondition(wA, rA, cmpt); preconPtr_->precondition(wA, rA, cmpt);
// --- Update search directions and calculate residual: // --- Update search directions and calculate residual:
gSumMagProd(globalSum, wA, rA, matrix().mesh().comm()); gSumMagProd(globalSum, wA, rA, matrix().mesh().comm());
@ -237,6 +239,11 @@ Foam::solverPerformance Foam::FPCG::scalarSolve
); );
} }
if (preconPtr_)
{
preconPtr_->setFinished(solverPerf);
}
matrix().setResidualField matrix().setResidualField
( (
ConstPrecisionAdaptor<scalar, solveScalar>(rA)(), ConstPrecisionAdaptor<scalar, solveScalar>(rA)(),

View File

@ -61,6 +61,12 @@ class FPCG
: :
public lduMatrix::solver public lduMatrix::solver
{ {
// Private Member Data
//- Cached preconditioner
mutable autoPtr<lduMatrix::preconditioner> preconPtr_;
// Private Member Functions // Private Member Functions
//- Blocking version of sum(a*b), sum(mag(b)) //- Blocking version of sum(a*b), sum(mag(b))

View File

@ -146,12 +146,14 @@ Foam::solverPerformance Foam::PBiCG::solve
solveScalar wArT = 0; solveScalar wArT = 0;
// --- Select and construct the preconditioner // --- Select and construct the preconditioner
autoPtr<lduMatrix::preconditioner> preconPtr = if (!preconPtr_)
lduMatrix::preconditioner::New {
preconPtr_ = lduMatrix::preconditioner::New
( (
*this, *this,
controlDict_ controlDict_
); );
}
// --- Solver iteration // --- Solver iteration
do do
@ -160,8 +162,8 @@ Foam::solverPerformance Foam::PBiCG::solve
const solveScalar wArTold = wArT; const solveScalar wArTold = wArT;
// --- Precondition residuals // --- Precondition residuals
preconPtr->precondition(wA, rA, cmpt); preconPtr_->precondition(wA, rA, cmpt);
preconPtr->preconditionT(wT, rT, cmpt); preconPtr_->preconditionT(wT, rT, cmpt);
// --- Update search directions: // --- Update search directions:
wArT = gSumProd(wA, rT, matrix().mesh().comm()); wArT = gSumProd(wA, rT, matrix().mesh().comm());
@ -235,6 +237,11 @@ Foam::solverPerformance Foam::PBiCG::solve
<< exit(FatalError); << exit(FatalError);
} }
if (preconPtr_)
{
preconPtr_->setFinished(solverPerf);
}
matrix().setResidualField matrix().setResidualField
( (
ConstPrecisionAdaptor<scalar, solveScalar>(rA)(), ConstPrecisionAdaptor<scalar, solveScalar>(rA)(),

View File

@ -54,6 +54,12 @@ class PBiCG
: :
public lduMatrix::solver public lduMatrix::solver
{ {
// Private Member Data
//- Cached preconditioner
mutable autoPtr<lduMatrix::preconditioner> preconPtr_;
// Private Member Functions // Private Member Functions
//- No copy construct //- No copy construct

View File

@ -149,12 +149,14 @@ Foam::solverPerformance Foam::PBiCGStab::scalarSolve
solveScalar omega = 0; solveScalar omega = 0;
// --- Select and construct the preconditioner // --- Select and construct the preconditioner
autoPtr<lduMatrix::preconditioner> preconPtr = if (!preconPtr_)
lduMatrix::preconditioner::New {
preconPtr_ = lduMatrix::preconditioner::New
( (
*this, *this,
controlDict_ controlDict_
); );
}
// --- Solver iteration // --- Solver iteration
do do
@ -196,7 +198,7 @@ Foam::solverPerformance Foam::PBiCGStab::scalarSolve
} }
// --- Precondition pA // --- Precondition pA
preconPtr->precondition(yA, pA, cmpt); preconPtr_->precondition(yA, pA, cmpt);
// --- Calculate AyA // --- Calculate AyA
matrix_.Amul(AyA, yA, interfaceBouCoeffs_, interfaces_, cmpt); matrix_.Amul(AyA, yA, interfaceBouCoeffs_, interfaces_, cmpt);
@ -233,7 +235,7 @@ Foam::solverPerformance Foam::PBiCGStab::scalarSolve
} }
// --- Precondition sA // --- Precondition sA
preconPtr->precondition(zA, sA, cmpt); preconPtr_->precondition(zA, sA, cmpt);
// --- Calculate tA // --- Calculate tA
matrix_.Amul(tA, zA, interfaceBouCoeffs_, interfaces_, cmpt); matrix_.Amul(tA, zA, interfaceBouCoeffs_, interfaces_, cmpt);
@ -264,6 +266,11 @@ Foam::solverPerformance Foam::PBiCGStab::scalarSolve
); );
} }
if (preconPtr_)
{
preconPtr_->setFinished(solverPerf);
}
matrix().setResidualField matrix().setResidualField
( (
ConstPrecisionAdaptor<scalar, solveScalar>(rA)(), ConstPrecisionAdaptor<scalar, solveScalar>(rA)(),

View File

@ -69,6 +69,12 @@ class PBiCGStab
: :
public lduMatrix::solver public lduMatrix::solver
{ {
// Private Member Data
//- Cached preconditioner
mutable autoPtr<lduMatrix::preconditioner> preconPtr_;
// Private Member Functions // Private Member Functions
//- No copy construct //- No copy construct

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019-2021 OpenCFD Ltd. Copyright (C) 2019-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -129,12 +129,14 @@ Foam::solverPerformance Foam::PCG::scalarSolve
) )
{ {
// --- Select and construct the preconditioner // --- Select and construct the preconditioner
autoPtr<lduMatrix::preconditioner> preconPtr = if (!preconPtr_)
lduMatrix::preconditioner::New {
preconPtr_ = lduMatrix::preconditioner::New
( (
*this, *this,
controlDict_ controlDict_
); );
}
// --- Solver iteration // --- Solver iteration
do do
@ -143,7 +145,7 @@ Foam::solverPerformance Foam::PCG::scalarSolve
wArAold = wArA; wArAold = wArA;
// --- Precondition residual // --- Precondition residual
preconPtr->precondition(wA, rA, cmpt); preconPtr_->precondition(wA, rA, cmpt);
// --- Update search directions: // --- Update search directions:
wArA = gSumProd(wA, rA, matrix().mesh().comm()); wArA = gSumProd(wA, rA, matrix().mesh().comm());
@ -199,6 +201,11 @@ Foam::solverPerformance Foam::PCG::scalarSolve
); );
} }
if (preconPtr_)
{
preconPtr_->setFinished(solverPerf);
}
matrix().setResidualField matrix().setResidualField
( (
ConstPrecisionAdaptor<scalar, solveScalar>(rA)(), ConstPrecisionAdaptor<scalar, solveScalar>(rA)(),

View File

@ -57,6 +57,12 @@ class PCG
: :
public lduMatrix::solver public lduMatrix::solver
{ {
// Private Member Data
//- Cached preconditioner
mutable autoPtr<lduMatrix::preconditioner> preconPtr_;
// Private Member Functions // Private Member Functions
//- No copy construct //- No copy construct

View File

@ -113,16 +113,18 @@ Foam::solverPerformance Foam::PPCG::scalarSolveCG
} }
// --- Select and construct the preconditioner // --- Select and construct the preconditioner
autoPtr<lduMatrix::preconditioner> preconPtr = if (!preconPtr_)
lduMatrix::preconditioner::New {
preconPtr_ = lduMatrix::preconditioner::New
( (
*this, *this,
controlDict_ controlDict_
); );
}
// --- Precondition residual (= u0) // --- Precondition residual (= u0)
solveScalarField u(nCells); solveScalarField u(nCells);
preconPtr->precondition(u, r, cmpt); preconPtr_->precondition(u, r, cmpt);
// --- Calculate A*u - reuse w // --- Calculate A*u - reuse w
matrix_.Amul(w, u, interfaceBouCoeffs_, interfaces_, cmpt); matrix_.Amul(w, u, interfaceBouCoeffs_, interfaces_, cmpt);
@ -143,12 +145,12 @@ Foam::solverPerformance Foam::PPCG::scalarSolveCG
gSumMagProd(globalSum, u, r, w, r, outstandingRequest, comm); gSumMagProd(globalSum, u, r, w, r, outstandingRequest, comm);
// --- Precondition residual // --- Precondition residual
preconPtr->precondition(m, w, cmpt); preconPtr_->precondition(m, w, cmpt);
} }
else else
{ {
// --- Precondition residual // --- Precondition residual
preconPtr->precondition(m, w, cmpt); preconPtr_->precondition(m, w, cmpt);
// --- Start global reductions for inner products // --- Start global reductions for inner products
gSumMagProd(globalSum, w, u, m, r, outstandingRequest, comm); gSumMagProd(globalSum, w, u, m, r, outstandingRequest, comm);
@ -229,12 +231,12 @@ Foam::solverPerformance Foam::PPCG::scalarSolveCG
gSumMagProd(globalSum, u, r, w, r, outstandingRequest, comm); gSumMagProd(globalSum, u, r, w, r, outstandingRequest, comm);
// --- Precondition residual // --- Precondition residual
preconPtr->precondition(m, w, cmpt); preconPtr_->precondition(m, w, cmpt);
} }
else else
{ {
// --- Precondition residual // --- Precondition residual
preconPtr->precondition(m, w, cmpt); preconPtr_->precondition(m, w, cmpt);
// --- Start global reductions for inner products // --- Start global reductions for inner products
gSumMagProd(globalSum, w, u, m, r, outstandingRequest, comm); gSumMagProd(globalSum, w, u, m, r, outstandingRequest, comm);
@ -247,11 +249,23 @@ Foam::solverPerformance Foam::PPCG::scalarSolveCG
// Cleanup any outstanding requests // Cleanup any outstanding requests
outstandingRequest.wait(); outstandingRequest.wait();
if (preconPtr_)
{
preconPtr_->setFinished(solverPerf);
}
//TBD
//matrix().setResidualField
//(
// ConstPrecisionAdaptor<scalar, solveScalar>(rA)(),
// fieldName_,
// false
//);
return solverPerf; return solverPerf;
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::PPCG::PPCG Foam::PPCG::PPCG

View File

@ -66,6 +66,12 @@ class PPCG
: :
public lduMatrix::solver public lduMatrix::solver
{ {
// Private Member Data
//- Cached preconditioner
mutable autoPtr<lduMatrix::preconditioner> preconPtr_;
// Private Member Functions // Private Member Functions
//- Non-blocking version of sum(a*b), sum(a*c), sum(mag(sumMag)) //- Non-blocking version of sum(a*b), sum(a*c), sum(mag(sumMag))

View File

@ -248,10 +248,18 @@ void Foam::distributedDILUPreconditioner::send
void Foam::distributedDILUPreconditioner::wait void Foam::distributedDILUPreconditioner::wait
( (
DynamicList<UPstream::Request>& requests DynamicList<UPstream::Request>& requests,
const bool cancel
) const ) const
{ {
if (cancel)
{
UPstream::cancelRequests(requests);
}
else
{
UPstream::waitRequests(requests); UPstream::waitRequests(requests);
}
requests.clear(); requests.clear();
} }
@ -757,12 +765,20 @@ Foam::distributedDILUPreconditioner::distributedDILUPreconditioner
Foam::distributedDILUPreconditioner::~distributedDILUPreconditioner() Foam::distributedDILUPreconditioner::~distributedDILUPreconditioner()
{ {
DebugPout<< "~distributedDILUPreconditioner()" << endl;
// Wait on all requests before storage is being taken down // Wait on all requests before storage is being taken down
// (could rely on construction order?)
wait(lowerSendRequests_); wait(lowerSendRequests_);
wait(lowerRecvRequests_); wait(lowerRecvRequests_);
wait(higherSendRequests_); wait(higherSendRequests_);
wait(higherRecvRequests_); wait(higherRecvRequests_);
// TBD: cancel/ignore outstanding messages
//wait(lowerSendRequests_, true);
//wait(lowerRecvRequests_, true);
//wait(higherSendRequests_, true);
//wait(higherRecvRequests_, true);
} }
@ -894,4 +910,26 @@ void Foam::distributedDILUPreconditioner::precondition
} }
void Foam::distributedDILUPreconditioner::setFinished
(
const solverPerformance& s
) const
{
DebugPout<< "setFinished fieldName:" << s.fieldName() << endl;
// Wait on all requests before storage is being taken down
// (could rely on construction order?)
wait(lowerSendRequests_);
wait(lowerRecvRequests_);
wait(higherSendRequests_);
wait(higherRecvRequests_);
// TBD: cancel/ignore outstanding messages
//wait(lowerSendRequests_, true);
//wait(lowerRecvRequests_, true);
//wait(higherSendRequests_, true);
//wait(higherRecvRequests_, true);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -62,8 +62,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef distributedDILUPreconditioner_H #ifndef Foam_distributedDILUPreconditioner_H
#define distributedDILUPreconditioner_H #define Foam_distributedDILUPreconditioner_H
#include "lduMatrix.H" #include "lduMatrix.H"
@ -82,7 +82,7 @@ class distributedDILUPreconditioner
{ {
protected: protected:
// Protected data // Protected Data
//- Precondition across global coupled bc //- Precondition across global coupled bc
const bool coupled_; const bool coupled_;
@ -187,8 +187,12 @@ protected:
DynamicList<UPstream::Request>& requests DynamicList<UPstream::Request>& requests
) const; ) const;
//- Wait for explicit requests //- Wait for requests or cancel/free requests
void wait(DynamicList<UPstream::Request>& requests) const; void wait
(
DynamicList<UPstream::Request>& requests,
const bool cancel = false
) const;
//- Update diagonal for interface //- Update diagonal for interface
virtual void addInterfaceDiag virtual void addInterfaceDiag
@ -260,6 +264,9 @@ public:
const solveScalarField& rA, const solveScalarField& rA,
const direction cmpt=0 const direction cmpt=0
) const; ) const;
//- Signal end of solver
virtual void setFinished(const solverPerformance& perf) const;
}; };