diff --git a/src/foam/matrices/lduMatrix/lduMatrix/SolverPerformance.C b/src/foam/matrices/lduMatrix/lduMatrix/SolverPerformance.C new file mode 100644 index 000000000..e898751fd --- /dev/null +++ b/src/foam/matrices/lduMatrix/lduMatrix/SolverPerformance.C @@ -0,0 +1,240 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +#include "SolverPerformance.H" +#include "IOstreams.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template +bool Foam::SolverPerformance::checkSingularity +( + const Type& wApA +) +{ + for(direction cmpt=0; cmpt::nComponents; cmpt++) + { + singular_[cmpt] = + component(wApA, cmpt) < vsmall_; + } + + return singular(); +} + + +template +bool Foam::SolverPerformance::singular() const +{ + for(direction cmpt=0; cmpt::nComponents; cmpt++) + { + if (!singular_[cmpt]) return false; + } + + return true; +} + + +template +bool Foam::SolverPerformance::checkConvergence +( + const Type& Tolerance, + const Type& RelTolerance +) +{ + if (debug >= 2) + { + Info<< solverName_ + << ": Iteration " << noIterations_ + << " residual = " << finalResidual_ + << endl; + } + + if + ( + finalResidual_ < Tolerance + || ( + RelTolerance + > small_*pTraits::one + && finalResidual_ < cmptMultiply(RelTolerance, initialResidual_) + ) + ) + { + converged_ = true; + } + else + { + converged_ = false; + } + + return converged_; +} + + +template +void Foam::SolverPerformance::print +( + Ostream& os +) const +{ + for(direction cmpt=0; cmpt::nComponents; cmpt++) + { + if (pTraits::nComponents == 1) + { + os << solverName_ << ": Solving for " << fieldName_; + + } + else + { + os << solverName_ << ": Solving for " + << word(fieldName_ + pTraits::componentNames[cmpt]); + } + + if (singular_[cmpt]) + { + os << ": solution singularity" << endl; + } + else + { + os << ", Initial residual = " << component(initialResidual_, cmpt) + << ", Final residual = " << component(finalResidual_, cmpt) + << ", No Iterations " << noIterations_ + << endl; + } + } +} + + +template +void Foam::SolverPerformance::replace +( + const Foam::label cmpt, + const Foam::SolverPerformance::cmptType>& sp +) +{ + initialResidual_.replace(cmpt, sp.initialResidual()); + finalResidual_.replace(cmpt, sp.finalResidual()); + singular_[cmpt] = sp.singular(); +} + + +template +Foam::SolverPerformance::cmptType> +Foam::SolverPerformance::max() +{ + return SolverPerformance::cmptType> + ( + solverName_, + fieldName_, + cmptMax(initialResidual_), + cmptMax(finalResidual_), + noIterations_, + converged_, + singular() + ); +} + + +template +bool Foam::SolverPerformance::operator!= +( + const SolverPerformance& sp +) const +{ + return + ( + solverName() != sp.solverName() + || fieldName() != sp.fieldName() + || initialResidual() != sp.initialResidual() + || finalResidual() != sp.finalResidual() + || nIterations() != sp.nIterations() + || converged() != sp.converged() + || singular() != sp.singular() + ); +} + + +template +typename Foam::SolverPerformance Foam::max +( + const typename Foam::SolverPerformance& sp1, + const typename Foam::SolverPerformance& sp2 +) +{ + return SolverPerformance + ( + 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() + ); +} + + +template +Foam::Istream& Foam::operator>> +( + Istream& is, + typename Foam::SolverPerformance& sp +) +{ + is.readBeginList("SolverPerformance"); + is >> sp.solverName_ + >> sp.fieldName_ + >> sp.initialResidual_ + >> sp.finalResidual_ + >> sp.noIterations_ + >> sp.converged_ + >> sp.singular_; + is.readEndList("SolverPerformance"); + + return is; +} + + +template +Foam::Ostream& Foam::operator<< +( + Ostream& os, + const typename Foam::SolverPerformance& sp +) +{ + os << token::BEGIN_LIST + << sp.solverName_ << token::SPACE + << sp.fieldName_ << token::SPACE + << sp.initialResidual_ << token::SPACE + << sp.finalResidual_ << token::SPACE + << sp.noIterations_ << token::SPACE + << sp.converged_ << token::SPACE + << sp.singular_ << token::SPACE + << token::END_LIST; + + return os; +} + + +// ************************************************************************* // diff --git a/src/foam/matrices/lduMatrix/lduMatrix/SolverPerformance.H b/src/foam/matrices/lduMatrix/lduMatrix/SolverPerformance.H new file mode 100644 index 000000000..c24fc9c79 --- /dev/null +++ b/src/foam/matrices/lduMatrix/lduMatrix/SolverPerformance.H @@ -0,0 +1,301 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2012-2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Class + Foam::SolverPerformance + +Description + SolverPerformance is the class returned by the LduMatrix solver + containing performance statistics. + +SourceFiles + SolverPerformance.C + +\*---------------------------------------------------------------------------*/ + +#ifndef SolverPerformance_H +#define SolverPerformance_H + +#include "word.H" +#include "FixedList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of friend functions and operators + +template +class SolverPerformance; + +template +SolverPerformance max +( + const SolverPerformance&, + const SolverPerformance& +); + +template +Istream& operator>> +( + Istream&, + SolverPerformance& +); + +template +Ostream& operator<< +( + Ostream&, + const SolverPerformance& +); + + +/*---------------------------------------------------------------------------*\ + Class SolverPerformance Declaration +\*---------------------------------------------------------------------------*/ + +template +class SolverPerformance +{ + // Private data + + word solverName_; + word fieldName_; + Type initialResidual_; + Type finalResidual_; + label noIterations_; + bool converged_; + FixedList::nComponents> singular_; + + +public: + + // Static data + + // Declare name of the class and its debug switch + ClassName("SolverPerformance"); + + //- Large Type for the use in solvers + static const scalar great_; + + //- Small Type for the use in solvers + static const scalar small_; + + //- Very small Type for the use in solvers + static const scalar vsmall_; + + + // Constructors + + SolverPerformance() + : + initialResidual_(pTraits::zero), + finalResidual_(pTraits::zero), + noIterations_(0), + converged_(false), + singular_(false) + {} + + + SolverPerformance + ( + const word& solverName, + const word& fieldName, + const Type& iRes = pTraits::zero, + const Type& fRes = pTraits::zero, + const label nIter = 0, + const bool converged = false, + const bool singular = false + ) + : + solverName_(solverName), + fieldName_(fieldName), + initialResidual_(iRes), + finalResidual_(fRes), + noIterations_(nIter), + converged_(converged), + singular_(singular) + {} + + + // Member functions + + //- Return solver name + const word& solverName() const + { + return solverName_; + } + + //- Return solver name + word& solverName() + { + return solverName_; + } + + + //- Return field name + const word& fieldName() const + { + return fieldName_; + } + + + //- Return initial residual + const Type& initialResidual() const + { + return initialResidual_; + } + + //- Return initial residual + Type& initialResidual() + { + return initialResidual_; + } + + + //- Return final residual + const Type& finalResidual() const + { + return finalResidual_; + } + + //- Return final residual + Type& finalResidual() + { + return finalResidual_; + } + + + //- Return number of iterations + label nIterations() const + { + return noIterations_; + } + + //- Return number of iterations + label& nIterations() + { + return noIterations_; + } + + + //- Has the solver converged? + bool converged() const + { + return converged_; + } + + //- Is the matrix singular? + bool singular() const; + + //- Check, store and return convergence + bool checkConvergence + ( + const Type& tolerance, + const Type& relTolerance + ); + + //- Singularity test + bool checkSingularity(const Type& residual); + + //- Print summary of solver performance to the given stream + void print(Ostream& os) const; + + //- Replace component based on the minimal SolverPerformance + void replace + ( + const label cmpt, + const SolverPerformance::cmptType>& sp + ); + + //- Return the summary maximum of SolverPerformance + // Effectively it will mostly return solverPerformanceScalar + SolverPerformance::cmptType> max(); + + + // Member Operators + + bool operator!=(const SolverPerformance&) const; + + + // Friend functions + + //- Return the element-wise maximum of two SolverPerformances + friend SolverPerformance Foam::max + ( + const SolverPerformance&, + const SolverPerformance& + ); + + + // Ostream Operator + + friend Istream& operator>> + ( + Istream&, + SolverPerformance& + ); + + friend Ostream& operator<< + ( + Ostream&, + const SolverPerformance& + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#define makeSolverPerformance(Type) \ + \ +typedef Foam::SolverPerformance \ + 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); \ + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "SolverPerformance.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/foam/meshes/data/data.C b/src/foam/meshes/data/data.C new file mode 100644 index 000000000..6ad811658 --- /dev/null +++ b/src/foam/meshes/data/data.C @@ -0,0 +1,62 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +#include "data.H" +#include "Time.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +int Foam::data::debug(Foam::debug::debugSwitch("data", false)); + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::data::data(const objectRegistry& obr) +: + IOdictionary + ( + IOobject + ( + "data", + obr.time().system(), + obr, + IOobject::NO_READ, + IOobject::NO_WRITE + ) + ), + prevTimeIndex_(0) +{ + set("solverPerformance", dictionary()); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +const Foam::dictionary& Foam::data::solverPerformanceDict() const +{ + return subDict("solverPerformance"); +} + + +// ************************************************************************* // diff --git a/src/foam/meshes/data/data.H b/src/foam/meshes/data/data.H new file mode 100644 index 000000000..c5b7758e9 --- /dev/null +++ b/src/foam/meshes/data/data.H @@ -0,0 +1,124 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Class + Foam::data + +Description + Database for solution data, solver performance and other reduced data. + + fvMesh is derived from data so that all fields have access to the data from + the mesh reference they hold. + +SourceFiles + data.C + +\*---------------------------------------------------------------------------*/ + +#ifndef data_H +#define data_H + +#include "IOdictionary.H" +#include "solverPerformance.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class data Declaration +\*---------------------------------------------------------------------------*/ + +class data +: + public IOdictionary +{ + // Private data + + //- Previously used time-index, used for reset between iterations + mutable label prevTimeIndex_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + data(const data&); + + //- Disallow default bitwise assignment + void operator=(const data&); + + +public: + + //- Debug switch + static int debug; + + + // Constructors + + //- Construct for objectRegistry + data(const objectRegistry& obr); + + + // Member Functions + + // Access + + //- Return the dictionary of solver performance data + // which includes initial and final residuals for convergence + // checking + const dictionary& solverPerformanceDict() const; + + //- Add/set the solverPerformance entry for the named field + template + void setSolverPerformance + ( + const word& name, + const SolverPerformance& + ) const; + + //- Add/set the solverPerformance entry, using its fieldName + template + void setSolverPerformance + ( + const SolverPerformance& + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "dataTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/foam/meshes/data/dataTemplates.C b/src/foam/meshes/data/dataTemplates.C new file mode 100644 index 000000000..8929ee123 --- /dev/null +++ b/src/foam/meshes/data/dataTemplates.C @@ -0,0 +1,71 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2015 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +#include "data.H" +#include "Time.H" +#include "solverPerformance.H" + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +void Foam::data::setSolverPerformance +( + const word& name, + const SolverPerformance& sp +) const +{ + dictionary& dict = const_cast(solverPerformanceDict()); + + List > perfs; + + if (prevTimeIndex_ != this->time().timeIndex()) + { + // Reset solver performance between iterations + prevTimeIndex_ = this->time().timeIndex(); + dict.clear(); + } + else + { + dict.readIfPresent(name, perfs); + } + + // Append to list + perfs.setSize(perfs.size()+1, sp); + + dict.set(name, perfs); +} + + +template +void Foam::data::setSolverPerformance +( + const SolverPerformance& sp +) const +{ + setSolverPerformance(sp.fieldName(), sp); +} + + +// ************************************************************************* //