12#ifndef DUMUX_LINEAR_PRECONDITIONERS_HH 
   13#define DUMUX_LINEAR_PRECONDITIONERS_HH 
   15#include <dune/common/exceptions.hh> 
   16#include <dune/common/float_cmp.hh> 
   17#include <dune/common/indices.hh> 
   18#include <dune/istl/preconditioners.hh> 
   19#include <dune/istl/paamg/amg.hh> 
   20#include <dune/istl/gsetc.hh> 
   23#include <dune/istl/umfpack.hh> 
   68template<
class M, 
class X, 
class Y, 
int l = 1>
 
   69class SeqUzawa : 
public Dune::Preconditioner<X,Y>
 
   72    static_assert(l== 1, 
"SeqUzawa expects a block level of 1.");
 
   74    using A = std::decay_t<decltype(std::declval<M>()[Dune::Indices::_0][Dune::Indices::_0])>;
 
   75    using U = std::decay_t<decltype(std::declval<X>()[Dune::Indices::_0])>;
 
   77    using Comm = Dune::Amg::SequentialInformation;
 
   78    using LinearOperator = Dune::MatrixAdapter<A, U, U>;
 
   79    using Smoother = Dune::SeqSSOR<A, U, U>;
 
   80    using AMGSolverForA = Dune::Amg::AMG<LinearOperator, U, Smoother, Comm>;
 
  100    SeqUzawa(
const std::shared_ptr<
const Dune::AssembledLinearOperator<M,X,Y>>& op, 
const Dune::ParameterTree& params)
 
  101    : matrix_(op->getmat())
 
  102    , numIterations_(params.get<std::size_t>(
"iterations"))
 
  104    , verbosity_(params.get<int>(
"verbosity"))
 
  105    , paramGroup_(params.get<std::string>(
"ParameterGroup"))
 
  106    , useDirectVelocitySolverForA_(
getParamFromGroup<bool>(paramGroup_, 
"LinearSolver.Preconditioner.DirectSolverForA", false))
 
  108        const bool determineRelaxationFactor = 
getParamFromGroup<bool>(paramGroup_, 
"LinearSolver.Preconditioner.DetermineRelaxationFactor", 
true);
 
  111        if (determineRelaxationFactor || !useDirectVelocitySolverForA_)
 
  114        if (useDirectVelocitySolverForA_)
 
  117        if (determineRelaxationFactor)
 
  118            relaxationFactor_ = estimateOmega_();
 
 
  124    virtual void pre(X& x, Y& b) {}
 
  132    virtual void apply(X& update, 
const Y& currentDefect)
 
  134        using namespace Dune::Indices;
 
  136        auto& A = matrix_[_0][_0];
 
  137        auto& B = matrix_[_0][_1];
 
  138        auto& C = matrix_[_1][_0];
 
  139        auto& D = matrix_[_1][_1];
 
  141        const auto& f = currentDefect[_0];
 
  142        const auto& g = currentDefect[_1];
 
  143        auto& 
u = update[_0];
 
  144        auto& p = update[_1];
 
  148        for (std::size_t i = 0; i < D.N(); ++i)
 
  150            const auto& block = D[i][i];
 
  151            for (
auto rowIt = block.begin(); rowIt != block.end(); ++rowIt)
 
  152                if (Dune::FloatCmp::eq<scalar_field_type>(rowIt->one_norm(), 1.0))
 
  153                    p[i][rowIt.index()] = g[i][rowIt.index()];
 
  157        for (std::size_t k = 0; k < numIterations_; ++k)
 
  164            applySolverForA_(uIncrement, uRhs);
 
  169            C.mmv(
u, pIncrement);
 
  170            D.mmv(p, pIncrement);
 
  171            pIncrement *= relaxationFactor_;
 
  176                std::cout << 
"Uzawa iteration " << k
 
  177                << 
", residual: " << uRhs.two_norm() + pIncrement.two_norm()/relaxationFactor_ << std::endl;
 
 
  188    virtual Dune::SolverCategory::Category 
category()
 const 
  190        return Dune::SolverCategory::sequential;
 
 
  195    void initAMG_(
const Dune::ParameterTree& params)
 
  197        using namespace Dune::Indices;
 
  198        auto linearOperator = std::make_shared<LinearOperator>(matrix_[_0][_0]);
 
  199        amgSolverForA_ = std::make_unique<AMGSolverForA>(linearOperator, params);
 
  205            using namespace Dune::Indices;
 
  206            umfPackSolverForA_ = std::make_unique<Dune::UMFPack<A>>(matrix_[_0][_0]);
 
  208            DUNE_THROW(Dune::InvalidStateException, 
"UMFPack not available. Use LinearSolver.Preconditioner.DirectVelocitySolver = false.");
 
  233        using namespace Dune::Indices;
 
  234        auto& A = matrix_[_0][_0];
 
  235        auto& B = matrix_[_0][_1];
 
  236        auto& C = matrix_[_1][_0];
 
  247        for (std::size_t i = 0; i < iterations; ++i)
 
  255            applySolverForA_(ainvbx, bx);
 
  263            lambdaMax = x.dot(v)/(x.dot(x));
 
  266            omega = 1.0/lambdaMax;
 
  275            std::cout << 
"\n*** Uzawa Preconditioner ***" << std::endl;
 
  276            std::cout << 
"Estimating relaxation factor based on Schur complement" << std::endl;
 
  277            std::cout << 
"Largest estimated eigenvalue lambdaMax = " << lambdaMax << std::endl;
 
  278            std::cout << 
"Relaxation factor omega = 1/lambdaMax = " << omega << std::endl;
 
  284    template<
class Sol, 
class Rhs>
 
  285    void applySolverForA_(Sol& sol, Rhs& rhs)
 const 
  287        if (useDirectVelocitySolverForA_)
 
  290            Dune::InverseOperatorResult res;
 
  291            umfPackSolverForA_->apply(sol, rhs, res);
 
  296            amgSolverForA_->pre(sol, rhs);
 
  297            amgSolverForA_->apply(sol, rhs);
 
  298            amgSolverForA_->post(sol);
 
  305    const std::size_t numIterations_;
 
  309    const int verbosity_;
 
  311    std::unique_ptr<AMGSolverForA> amgSolverForA_;
 
  313    std::unique_ptr<Dune::UMFPack<A>> umfPackSolverForA_;
 
  315    const std::string paramGroup_;
 
  316    const bool useDirectVelocitySolverForA_;
 
 
  329template<
class M, 
class X, 
class Y, 
int l=1>
 
  348    : _A_(A), numSteps_(n), relaxationFactor_(
w)
 
  349    { Dune::CheckIfDiagonalPresent<M,l>::check(_A_); }
 
 
  351    ParMTJac (
const std::shared_ptr<
const Dune::AssembledLinearOperator<M,X,Y>>& A, 
const Dune::ParameterTree& configuration)
 
  352    : 
ParMTJac(A->getmat(), configuration)
 
 
  355    ParMTJac (
const M& A, 
const Dune::ParameterTree& configuration)
 
 
  359    void pre (X&, Y&)
 override {}
 
  361    void apply (X& update, 
const Y& defect)
 override 
  366        for (
int k=0; k<numSteps_; k++)
 
  375                auto rhs = defect[i];
 
  376                const auto endColIt = row.end();
 
  377                auto colIt = row.begin();
 
  379                for (; colIt.index()<i; ++colIt)
 
  380                    colIt->mmv(xOld[colIt.index()], rhs);
 
  381                const auto diag = colIt;
 
  382                for (; colIt != endColIt; ++colIt)
 
  383                    colIt->mmv(xOld[colIt.index()], rhs);
 
  385                Dune::algmeta_itsteps<l-1, typename M::block_type>::dbjac(
 
  386                    *diag, v, rhs, relaxationFactor_
 
  389                update[i].axpy(relaxationFactor_, v);
 
 
  397    Dune::SolverCategory::Category 
category()
 const override 
  398    { 
return Dune::SolverCategory::sequential; }
 
 
 
  416    std::vector<int> colors(matrix.N(), -1);
 
  417    std::vector<int> neighborColors; neighborColors.reserve(30);
 
  418    std::vector<bool> colorUsed; colorUsed.reserve(30);
 
  422    for (std::size_t i = 0; i < colors.size(); ++i)
 
  424        neighborColors.clear();
 
  425        auto& row = matrix[i];
 
  426        const auto endColIt = row.end();
 
  427        for (
auto colIt = row.begin(); colIt != endColIt; ++colIt)
 
  428            neighborColors.push_back(colors[colIt.index()]);
 
  430        const auto c = Detail::smallestAvailableColor(neighborColors, colorUsed);
 
  434        if (c < coloredIndices.size())
 
  435            coloredIndices[c].push_back(i);
 
  437            coloredIndices.emplace_back(1, i);
 
 
  442template<
bool forward, 
int l, 
class M, 
class X, 
class Y, 
class K>
 
  444                       const std::deque<std::vector<std::size_t>>& coloredIndices)
 
  446    for (
int color = 0; color < coloredIndices.size(); ++color)
 
  448        const auto c = forward ? color : coloredIndices.size()-1-color;
 
  449        const auto& rowIndices = coloredIndices[c];
 
  452            const auto i = rowIndices[k];
 
  456            const auto endColIt = row.end();
 
  457            auto colIt = row.begin();
 
  459            for (; colIt.index()<i; ++colIt)
 
  460                colIt->mmv(update[colIt.index()], rhs);
 
  461            const auto diag = colIt;
 
  462            for (; colIt != endColIt; ++colIt)
 
  463                colIt->mmv(update[colIt.index()], rhs);
 
  465            if constexpr (forward)
 
  466                Dune::algmeta_itsteps<l-1,typename M::block_type>::bsorf(
 
  467                    *diag, v, rhs, relaxationFactor
 
  470                Dune::algmeta_itsteps<l-1,typename M::block_type>::bsorb(
 
  471                    *diag, v, rhs, relaxationFactor
 
  474            update[i].axpy(relaxationFactor, v);
 
 
 
  488template<
class M, 
class X, 
class Y, 
int l=1>
 
  507    : _A_(A), numSteps_(n), relaxationFactor_(
w)
 
  509        Dune::CheckIfDiagonalPresent<M,l>::check(_A_);
 
 
  513    ParMTSOR (
const std::shared_ptr<
const Dune::AssembledLinearOperator<M,X,Y>>& A, 
const Dune::ParameterTree& configuration)
 
  514    : 
ParMTSOR(A->getmat(), configuration)
 
 
  517    ParMTSOR (
const M& A, 
const Dune::ParameterTree& configuration)
 
 
  521    void pre (X&, Y&)
 override {}
 
  523    void apply (X& v, 
const Y& d)
 override 
 
  528    template<
bool forward>
 
  531        for (
int i=0; i<numSteps_; i++)
 
 
  538    Dune::SolverCategory::Category 
category()
 const override 
  539    { 
return Dune::SolverCategory::sequential; }
 
 
  547    std::deque<std::vector<std::size_t>> colors_;
 
 
  560template<
class M, 
class X, 
class Y, 
int l=1>
 
  579    : _A_(A), numSteps_(n), relaxationFactor_(
w)
 
  581        Dune::CheckIfDiagonalPresent<M,l>::check(_A_);
 
 
  585    ParMTSSOR (
const std::shared_ptr<
const Dune::AssembledLinearOperator<M,X,Y>>& A, 
const Dune::ParameterTree& configuration)
 
 
  589    ParMTSSOR (
const M& A, 
const Dune::ParameterTree& configuration)
 
 
  593    void pre (X&, Y&)
 override {}
 
  595    void apply (X& v, 
const Y& d)
 override 
  597        for (
int i=0; i<numSteps_; i++)
 
 
  607    Dune::SolverCategory::Category 
category()
 const override 
  608    { 
return Dune::SolverCategory::sequential; }
 
 
  616    std::deque<std::vector<std::size_t>> colors_;
 
 
  626template<
class M, 
class X, 
class Y, 
int l>
 
  627struct ConstructionTraits<
Dumux::ParMTJac<M,X,Y,l> >
 
  629    using Arguments = DefaultConstructionArgs<SeqJac<M,X,Y,l> >;
 
  632        return std::make_shared<Dumux::ParMTJac<M,X,Y,l>>(
 
  633            args.getMatrix(), args.getArgs().iterations, args.getArgs().relaxationFactor
 
 
 
  639template<
class M, 
class X, 
class Y, 
int l>
 
  640struct ConstructionTraits<
Dumux::ParMTSOR<M,X,Y,l> >
 
  642    using Arguments = DefaultConstructionArgs<SeqSOR<M,X,Y,l> >;
 
  645        return std::make_shared<Dumux::ParMTSOR<M,X,Y,l>>(
 
  646            args.getMatrix(), args.getArgs().iterations, args.getArgs().relaxationFactor
 
 
 
  651template<
class M, 
class X, 
class Y, 
int l>
 
  652struct SmootherApplier<
Dumux::ParMTSOR<M,X,Y,l> >
 
  659    { smoother.template apply<true>(v,d); }
 
 
  662    { smoother.template apply<false>(v,d); }
 
 
 
  666template<
class M, 
class X, 
class Y, 
int l>
 
  667struct ConstructionTraits<
Dumux::ParMTSSOR<M,X,Y,l> >
 
  669    using Arguments = DefaultConstructionArgs<SeqSSOR<M,X,Y,l> >;
 
  672        return std::make_shared<Dumux::ParMTSSOR<M,X,Y,l>>(
 
  673            args.getMatrix(), args.getArgs().iterations, args.getArgs().relaxationFactor
 
 
 
 
ParMTJac(const M &A, const Dune::ParameterTree &configuration)
Definition preconditioners.hh:355
ParMTJac(const std::shared_ptr< const Dune::AssembledLinearOperator< M, X, Y > > &A, const Dune::ParameterTree &configuration)
Definition preconditioners.hh:351
ParMTJac(const M &A, int n, real_field_type w)
Constructor.
Definition preconditioners.hh:347
X::field_type field_type
The field type of the preconditioner.
Definition preconditioners.hh:340
void pre(X &, Y &) override
Definition preconditioners.hh:359
Dune::FieldTraits< scalar_field_type >::real_type real_field_type
real scalar type underlying the field_type
Definition preconditioners.hh:344
void post(X &) override
Definition preconditioners.hh:394
M matrix_type
The matrix type the preconditioner is for.
Definition preconditioners.hh:334
Dune::Simd::Scalar< field_type > scalar_field_type
scalar type underlying the field_type
Definition preconditioners.hh:342
Y range_type
The range type of the preconditioner.
Definition preconditioners.hh:338
X domain_type
The domain type of the preconditioner.
Definition preconditioners.hh:336
Dune::SolverCategory::Category category() const override
Category of the preconditioner (see SolverCategory::Category)
Definition preconditioners.hh:397
void apply(X &update, const Y &defect) override
Definition preconditioners.hh:361
Multi-threaded SOR preconditioner using coloring.
Definition preconditioners.hh:490
ParMTSOR(const M &A, const Dune::ParameterTree &configuration)
Definition preconditioners.hh:517
X domain_type
The domain type of the preconditioner.
Definition preconditioners.hh:495
M matrix_type
The matrix type the preconditioner is for.
Definition preconditioners.hh:493
void apply(X &v, const Y &d)
Definition preconditioners.hh:529
ParMTSOR(const M &A, int n, real_field_type w)
Constructor.
Definition preconditioners.hh:506
void apply(X &v, const Y &d) override
Definition preconditioners.hh:523
Dune::Simd::Scalar< field_type > scalar_field_type
scalar type underlying the field_type
Definition preconditioners.hh:501
void post(X &) override
Definition preconditioners.hh:535
Dune::SolverCategory::Category category() const override
Category of the preconditioner (see SolverCategory::Category)
Definition preconditioners.hh:538
Y range_type
The range type of the preconditioner.
Definition preconditioners.hh:497
void pre(X &, Y &) override
Definition preconditioners.hh:521
X::field_type field_type
The field type of the preconditioner.
Definition preconditioners.hh:499
ParMTSOR(const std::shared_ptr< const Dune::AssembledLinearOperator< M, X, Y > > &A, const Dune::ParameterTree &configuration)
Definition preconditioners.hh:513
Dune::FieldTraits< scalar_field_type >::real_type real_field_type
real scalar type underlying the field_type
Definition preconditioners.hh:503
ParMTSSOR(const M &A, int n, real_field_type w)
Constructor.
Definition preconditioners.hh:578
Dune::Simd::Scalar< field_type > scalar_field_type
scalar type underlying the field_type
Definition preconditioners.hh:573
ParMTSSOR(const std::shared_ptr< const Dune::AssembledLinearOperator< M, X, Y > > &A, const Dune::ParameterTree &configuration)
Definition preconditioners.hh:585
void pre(X &, Y &) override
Definition preconditioners.hh:593
Dune::SolverCategory::Category category() const override
Category of the preconditioner (see SolverCategory::Category)
Definition preconditioners.hh:607
void apply(X &v, const Y &d) override
Definition preconditioners.hh:595
X domain_type
The domain type of the preconditioner.
Definition preconditioners.hh:567
Dune::FieldTraits< scalar_field_type >::real_type real_field_type
real scalar type underlying the field_type
Definition preconditioners.hh:575
ParMTSSOR(const M &A, const Dune::ParameterTree &configuration)
Definition preconditioners.hh:589
M matrix_type
The matrix type the preconditioner is for.
Definition preconditioners.hh:565
Y range_type
The range type of the preconditioner.
Definition preconditioners.hh:569
void post(X &) override
Definition preconditioners.hh:604
X::field_type field_type
The field type of the preconditioner.
Definition preconditioners.hh:571
virtual Dune::SolverCategory::Category category() const
Category of the preconditioner (see SolverCategory::Category)
Definition preconditioners.hh:188
M matrix_type
The matrix type the preconditioner is for.
Definition preconditioners.hh:84
virtual void pre(X &x, Y &b)
Prepare the preconditioner.
Definition preconditioners.hh:124
SeqUzawa(const std::shared_ptr< const Dune::AssembledLinearOperator< M, X, Y > > &op, const Dune::ParameterTree ¶ms)
Constructor.
Definition preconditioners.hh:100
virtual void post(X &x)
Clean up.
Definition preconditioners.hh:185
Dune::Simd::Scalar< field_type > scalar_field_type
Scalar type underlying the field_type.
Definition preconditioners.hh:92
typename X::field_type field_type
The field type of the preconditioner.
Definition preconditioners.hh:90
X domain_type
The domain type of the preconditioner.
Definition preconditioners.hh:86
Y range_type
The range type of the preconditioner.
Definition preconditioners.hh:88
virtual void apply(X &update, const Y ¤tDefect)
Apply the preconditioner.
Definition preconditioners.hh:132
Coloring schemes for shared-memory-parallel assembly.
void parallelFor(const std::size_t count, const FunctorType &functor)
A parallel for loop (multithreading)
Definition parallel_for.hh:160
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:149
The specialized Dumux macro and tag for the ISTL registry to choose the solver and preconditioner at ...
#define DUMUX_REGISTER_PRECONDITIONER(name, tag,...)
Register a Dumux preconditioner.
Definition istlsolverregistry.hh:31
Type traits to be used with matrix types.
Definition preconditioners.hh:409
void parallelBlockSOR_(const M &A, X &update, const Y &b, const K &relaxationFactor, const std::deque< std::vector< std::size_t > > &coloredIndices)
Definition preconditioners.hh:443
void computeColorsForMatrixSweep_(const M &matrix, std::deque< std::vector< std::size_t > > &coloredIndices)
Definition preconditioners.hh:413
const Scalar PengRobinsonMixture< Scalar, StaticParameters >::w
Definition pengrobinsonmixture.hh:140
const Scalar PengRobinsonMixture< Scalar, StaticParameters >::u
Definition pengrobinsonmixture.hh:138
Definition preconditioners.hh:623
Parallel for loop (multithreading)
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Helper type to determine whether a given type is a Dune::MultiTypeBlockMatrix.
Definition matrix.hh:37
DefaultConstructionArgs< SeqJac< M, X, Y, l > > Arguments
Definition preconditioners.hh:629
static std::shared_ptr< Dumux::ParMTJac< M, X, Y, l > > construct(Arguments &args)
Definition preconditioners.hh:630
static std::shared_ptr< Dumux::ParMTSOR< M, X, Y, l > > construct(Arguments &args)
Definition preconditioners.hh:643
DefaultConstructionArgs< SeqSOR< M, X, Y, l > > Arguments
Definition preconditioners.hh:642
DefaultConstructionArgs< SeqSSOR< M, X, Y, l > > Arguments
Definition preconditioners.hh:669
static std::shared_ptr< Dumux::ParMTSSOR< M, X, Y, l > > construct(Arguments &args)
Definition preconditioners.hh:670
static void preSmooth(Smoother &smoother, Domain &v, Range &d)
Definition preconditioners.hh:658
Smoother::range_type Range
Definition preconditioners.hh:655
Dumux::ParMTSOR< M, X, Y, l > Smoother
Definition preconditioners.hh:654
Smoother::domain_type Domain
Definition preconditioners.hh:656
static void postSmooth(Smoother &smoother, Domain &v, Range &d)
Definition preconditioners.hh:661