Compare commits

...

2 Commits

Author SHA1 Message Date
29e4d6b961 wip 2020-06-04 22:31:53 +02:00
2970275410 ENH: constexpr for scalar constants in SolverPerformance
STYLE: simplify coding in SolverPerformance
2020-06-04 11:34:55 +02:00
6 changed files with 192 additions and 125 deletions

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -36,10 +37,9 @@ bool Foam::SolverPerformance<Type>::checkSingularity
const Type& wApA
)
{
for(direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; ++cmpt)
{
singular_[cmpt] =
component(wApA, cmpt) < vsmall_;
singular_[cmpt] = (component(wApA, cmpt) < vsmall_);
}
return singular();
@ -49,15 +49,43 @@ bool Foam::SolverPerformance<Type>::checkSingularity
template<class Type>
bool Foam::SolverPerformance<Type>::singular() const
{
for(direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
for (const bool val : singular_)
{
if (!singular_[cmpt]) return false;
if (!val) return false;
}
return true;
}
template<class Type>
double Foam::SolverPerformance<Type>::timing() const
{
double ret{0};
for (const double val : timing_)
{
ret += val;
}
return ret;
}
template<class Type>
double Foam::SolverPerformance<Type>::maxTiming() const
{
double ret{0};
for (const double val : timing_)
{
ret = Foam::max(ret, val);
}
return ret;
}
template<class Type>
bool Foam::SolverPerformance<Type>::checkConvergence
(
@ -73,7 +101,7 @@ bool Foam::SolverPerformance<Type>::checkConvergence
<< endl;
}
if
converged_ =
(
finalResidual_ < Tolerance
|| (
@ -81,14 +109,7 @@ bool Foam::SolverPerformance<Type>::checkConvergence
> small_*pTraits<Type>::one
&& finalResidual_ < cmptMultiply(RelTolerance, initialResidual_)
)
)
{
converged_ = true;
}
else
{
converged_ = false;
}
);
return converged_;
}
@ -100,30 +121,26 @@ void Foam::SolverPerformance<Type>::print
Ostream& os
) const
{
for(direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; ++cmpt)
{
if (pTraits<Type>::nComponents == 1)
os << solverName_ << ": Solving for " << fieldName_;
if (pTraits<Type>::nComponents > 1)
{
os << solverName_ << ": Solving for " << fieldName_;
}
else
{
os << solverName_ << ": Solving for "
<< word(fieldName_ + pTraits<Type>::componentNames[cmpt]);
os << pTraits<Type>::componentNames[cmpt];
}
if (singular_[cmpt])
{
os << ": solution singularity" << endl;
os << ": solution singularity";
}
else
{
os << ", Initial residual = " << component(initialResidual_, cmpt)
<< ", Final residual = " << component(finalResidual_, cmpt)
<< ", No Iterations " << nIterations_
<< endl;
<< ", Timing = " << timing_[cmpt];
}
os << endl;
}
}
@ -139,12 +156,13 @@ void Foam::SolverPerformance<Type>::replace
finalResidual_.replace(cmpt, sp.finalResidual());
nIterations_.replace(cmpt, sp.nIterations());
singular_[cmpt] = sp.singular();
timing_[cmpt] = sp.timing();
}
template<class Type>
Foam::SolverPerformance<typename Foam::pTraits<Type>::cmptType>
Foam::SolverPerformance<Type>::max()
Foam::SolverPerformance<Type>::max() const
{
return SolverPerformance<typename pTraits<Type>::cmptType>
(
@ -154,46 +172,49 @@ Foam::SolverPerformance<Type>::max()
cmptMax(finalResidual_),
cmptMax(nIterations_),
converged_,
singular()
singular(),
maxTiming()
);
}
template<class Type>
bool Foam::SolverPerformance<Type>::operator!=
bool Foam::operator!=
(
const SolverPerformance<Type>& sp
) const
const SolverPerformance<Type>& a,
const SolverPerformance<Type>& b
)
{
return
(
solverName() != sp.solverName()
|| fieldName() != sp.fieldName()
|| initialResidual() != sp.initialResidual()
|| finalResidual() != sp.finalResidual()
|| nIterations() != sp.nIterations()
|| converged() != sp.converged()
|| singular() != sp.singular()
a.solverName() != b.solverName()
|| a.fieldName() != b.fieldName()
|| a.initialResidual() != b.initialResidual()
|| a.finalResidual() != b.finalResidual()
|| a.nIterations() != b.nIterations()
|| a.converged() != b.converged()
|| a.singular() != b.singular()
);
}
template<class Type>
typename Foam::SolverPerformance<Type> Foam::max
Foam::SolverPerformance<Type> Foam::max
(
const typename Foam::SolverPerformance<Type>& sp1,
const typename Foam::SolverPerformance<Type>& sp2
const SolverPerformance<Type>& a,
const SolverPerformance<Type>& b
)
{
return SolverPerformance<Type>
(
sp1.solverName(),
sp1.fieldName_,
max(sp1.initialResidual(), sp2.initialResidual()),
max(sp1.finalResidual(), sp2.finalResidual()),
max(sp1.nIterations(), sp2.nIterations()),
sp1.converged() && sp2.converged(),
sp1.singular() || sp2.singular()
a.solverName(),
a.fieldName(),
max(a.initialResidual(), b.initialResidual()),
max(a.finalResidual(), b.finalResidual()),
max(a.nIterations(), b.nIterations()),
a.converged() && b.converged(),
a.singular() || b.singular(),
max(a.maxTiming(), b.maxTiming())
);
}
@ -212,7 +233,8 @@ Foam::Istream& Foam::operator>>
>> sp.finalResidual_
>> sp.nIterations_
>> sp.converged_
>> sp.singular_;
>> sp.singular_
>> sp.timing_;
is.readEnd("SolverPerformance");
return is;
@ -234,6 +256,7 @@ Foam::Ostream& Foam::operator<<
<< sp.nIterations_ << token::SPACE
<< sp.converged_ << token::SPACE
<< sp.singular_ << token::SPACE
<< sp.timing_ << token::SPACE
<< token::END_LIST;
return os;

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -40,37 +41,28 @@ SourceFiles
#include "word.H"
#include "FixedList.H"
#include "clockValue.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of friend functions and operators
template<class Type>
class SolverPerformance;
// Forward Declarations
template<class Type> class SolverPerformance;
template<class Type>
SolverPerformance<Type> max
(
const SolverPerformance<Type>&,
const SolverPerformance<Type>&
const SolverPerformance<Type>& sp1,
const SolverPerformance<Type>& sp2
);
template<class Type>
Istream& operator>>
(
Istream&,
SolverPerformance<Type>&
);
Istream& operator>>(Istream& is, SolverPerformance<Type>& sp);
template<class Type>
Ostream& operator<<
(
Ostream&,
const SolverPerformance<Type>&
);
Ostream& operator<<(Ostream& os, const SolverPerformance<Type>& sp);
/*---------------------------------------------------------------------------*\
@ -83,7 +75,7 @@ class SolverPerformance
// Label type corresponding to Type
typedef typename pTraits<Type>::labelType labelType;
// Private data
// Private Data
word solverName_;
word fieldName_;
@ -92,37 +84,44 @@ class SolverPerformance
labelType nIterations_;
bool converged_;
FixedList<bool, pTraits<Type>::nComponents> singular_;
FixedList<double, pTraits<Type>::nComponents> timing_;
public:
// Static data
// Static Data
// Declare name of the class and its debug switch
//- Declare name of the class and its debug switch
ClassName("SolverPerformance");
//- Large Type for the use in solvers
static const scalar great_;
//- Large value for the use in solvers
static constexpr scalar great_ = 1e20;
//- Small Type for the use in solvers
static const scalar small_;
//- Small value for the use in solvers
static constexpr scalar small_ = 1e-20;
//- Very small value for the use in solvers
static constexpr scalar vsmall_ = VSMALL;
//- Very small Type for the use in solvers
static const scalar vsmall_;
// Constructors
//- Default construct, zero-initialized
SolverPerformance()
:
solverName_(),
fieldName_(),
initialResidual_(Zero),
finalResidual_(Zero),
nIterations_(Zero),
converged_(false),
singular_(false)
singular_(false),
timing_(Zero)
{}
//- Construct for given solver and field, zero-initialized
SolverPerformance
(
const word& solverName,
@ -131,7 +130,8 @@ public:
const Type& fRes = pTraits<Type>::zero,
const labelType& nIter = pTraits<labelType>::zero,
const bool converged = false,
const bool singular = false
const bool singular = false,
const scalar timingValue = 0
)
:
solverName_(solverName),
@ -140,11 +140,15 @@ public:
finalResidual_(fRes),
nIterations_(nIter),
converged_(converged),
singular_(singular)
{}
singular_(singular),
timing_(Zero)
{
// Single-value assignment affects single component only
timing_.first() = timingValue;
}
// Member functions
// Member Functions
//- Return solver name
const word& solverName() const
@ -158,7 +162,6 @@ public:
return solverName_;
}
//- Return field name
const word& fieldName() const
{
@ -204,7 +207,6 @@ public:
return nIterations_;
}
//- Has the solver converged?
bool converged() const
{
@ -214,6 +216,24 @@ public:
//- Is the matrix singular?
bool singular() const;
//- Return total timing, the sum of all components
double timing() const;
//- Add to single-component timing
void addTiming(double timingValue)
{
timing_.first() += timingValue;
}
//- Set single-component timing
void setTiming(double timingValue)
{
timing_.first() = timingValue;
}
//- Return the max timing
double maxTiming() const;
//- Check, store and return convergence
bool checkConvergence
(
@ -221,7 +241,7 @@ public:
const Type& relTolerance
);
//- Singularity test
//- Test singularity
bool checkSingularity(const Type& residual);
//- Print summary of solver performance to the given stream
@ -236,61 +256,56 @@ public:
//- Return the summary maximum of SolverPerformance<Type>
// Effectively it will mostly return solverPerformanceScalar
SolverPerformance<typename pTraits<Type>::cmptType> max();
// Member Operators
bool operator!=(const SolverPerformance<Type>&) const;
// Friend functions
//- Return the element-wise maximum of two SolverPerformance<Type>s
friend SolverPerformance<Type> Foam::max <Type>
(
const SolverPerformance<Type>&,
const SolverPerformance<Type>&
);
SolverPerformance<typename pTraits<Type>::cmptType> max() const;
// Ostream Operator
friend Istream& operator>> <Type>
(
Istream&,
SolverPerformance<Type>&
Istream& is,
SolverPerformance<Type>& sp
);
friend Ostream& operator<< <Type>
(
Ostream&,
const SolverPerformance<Type>&
Ostream& os,
const SolverPerformance<Type>& sp
);
};
// Global Operators
//- Test for inequality
template<class Type>
bool operator!=
(
const SolverPerformance<Type>& a,
const SolverPerformance<Type>& b
);
// Global Functions
//- Return element-wise maximum of SolverPerformance
template<class Type>
SolverPerformance<Type> max
(
const SolverPerformance<Type>& a,
const SolverPerformance<Type>& b
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#define makeSolverPerformance(Type) \
\
typedef Foam::SolverPerformance<Type> \
solverPerformance##Type; \
\
defineNamedTemplateTypeNameAndDebug(solverPerformance##Type, 0); \
\
template<> \
const scalar solverPerformance##Type::great_(1e20); \
\
template<> \
const scalar solverPerformance##Type::small_(1e-20); \
\
template<> \
const scalar solverPerformance##Type::vsmall_(VSMALL); \
#define makeSolverPerformance(Type) \
typedef Foam::SolverPerformance<Type> solverPerformance##Type; \
defineNamedTemplateTypeNameAndDebug(solverPerformance##Type, 0);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2015 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -40,10 +41,24 @@ namespace Foam
template<>
Foam::SolverPerformance<Foam::scalar>
Foam::SolverPerformance<Foam::scalar>::max()
Foam::SolverPerformance<Foam::scalar>::max() const
{
return *this;
}
template<>
double Foam::SolverPerformance<Foam::scalar>::timing() const
{
return timing_.first();
}
template<>
double Foam::SolverPerformance<Foam::scalar>::maxTiming() const
{
return timing_.first();
}
// ************************************************************************* //

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2015 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -45,9 +46,17 @@ namespace Foam
{
typedef SolverPerformance<scalar> solverPerformance;
// Specialization of the max function for scalar object
// Specialize max() member function for scalar
template<>
SolverPerformance<scalar> SolverPerformance<scalar>::max();
SolverPerformance<scalar> SolverPerformance<scalar>::max() const;
// Specialize timing() member function for scalar
template<>
double SolverPerformance<scalar>::timing() const;
// Specialize maxTiming() member function for scalar
template<>
double SolverPerformance<scalar>::maxTiming() const;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -129,10 +129,10 @@ Foam::SolverPerformance<Type> Foam::faMatrix<Type>::solve
);
}
solverPerformance solverPerf;
// Solver call
solverPerf = lduMatrix::solver::New
const auto timing = clockValue::now();
solverPerformance solverPerf = lduMatrix::solver::New
(
psi_.name() + pTraits<Type>::componentNames[cmpt],
*this,
@ -142,6 +142,8 @@ Foam::SolverPerformance<Type> Foam::faMatrix<Type>::solve
solverControls
)->solve(psiCmpt, sourceCmpt, cmpt);
solverPerf.setTiming(timing.elapsedTime());
if (SolverPerformance<Type>::debug)
{
solverPerf.print(Info);

View File

@ -203,10 +203,11 @@ Foam::SolverPerformance<Type> Foam::fvMatrix<Type>::solveSegregated
);
}
solverPerformance solverPerf;
// Solver call
solverPerf = lduMatrix::solver::New
const auto timing = clockValue::now();
solverPerformance solverPerf = lduMatrix::solver::New
(
psi.name() + pTraits<Type>::componentNames[cmpt],
*this,
@ -216,6 +217,8 @@ Foam::SolverPerformance<Type> Foam::fvMatrix<Type>::solveSegregated
solverControls
)->solve(psiCmpt, sourceCmpt, cmpt);
solverPerf.setTiming(timing.elapsedTime());
if (SolverPerformance<Type>::debug)
{
solverPerf.print(Info.masterStream(this->mesh().comm()));