Add DILU preconditioner

This commit is contained in:
jakobtorben
2023-09-27 15:47:05 +02:00
parent d98de155de
commit ab0ca76194
8 changed files with 1068 additions and 3 deletions

View File

@@ -34,7 +34,10 @@
#include <opm/simulators/linalg/PressureTransferPolicy.hpp>
#include <opm/simulators/linalg/PropertyTree.hpp>
#include <opm/simulators/linalg/WellOperators.hpp>
#include <opm/simulators/linalg/DILU.hpp>
#include <opm/simulators/linalg/ExtraSmoothers.hpp>
#include <dune/common/unused.hh>
#include <dune/istl/owneroverlapcopy.hh>
#include <dune/istl/preconditioners.hh>
#include <dune/istl/paamg/amg.hh>
@@ -91,6 +94,7 @@ struct AMGSmootherArgsHelper<Opm::ParallelOverlappingILU0<M,V,V,C>>
}
};
template <class Operator, class Comm, class Matrix, class Vector>
typename AMGHelper<Operator, Comm, Matrix, Vector>::Criterion
AMGHelper<Operator,Comm,Matrix,Vector>::criterion(const PropertyTree& prm)
@@ -158,6 +162,10 @@ struct StandardPreconditioners
F::addCreator("ILUn", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
return createParILU(op, prm, comm, prm.get<int>("ilulevel", 0));
});
F::addCreator("DILU", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
DUNE_UNUSED_PARAMETER(prm);
return wrapBlockPreconditioner<SeqDilu<M, V, V>>(comm, op.getmat());
});
F::addCreator("Jac", [](const O& op, const P& prm, const std::function<V()>&,
std::size_t, const C& comm) {
const int n = prm.get<int>("repeats", 1);
@@ -186,12 +194,23 @@ struct StandardPreconditioners
// with the AMG hierarchy construction.
if constexpr (std::is_same_v<O, Dune::OverlappingSchwarzOperator<M, V, V, C>>) {
F::addCreator("amg", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
using PrecPtr = std::shared_ptr<Dune::PreconditionerWithUpdate<V, V>>;
const std::string smoother = prm.get<std::string>("smoother", "ParOverILU0");
if (smoother == "ILU0" || smoother == "ParOverILU0") {
using Smoother = Opm::ParallelOverlappingILU0<M, V, V, C>;
auto crit = AMGHelper<O,C,M,V>::criterion(prm);
auto sargs = AMGSmootherArgsHelper<Smoother>::args(prm);
return std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
return prec;
}
else if (smoother == "DILU") {
using SeqSmoother = Dune::SeqDilu<M, V, V>;
using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
SmootherArgs sargs;
auto crit = AMGHelper<O,C,M,V>::criterion(prm);
PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
return prec;
} else {
OPM_THROW(std::invalid_argument, "Properties: No smoother with name " + smoother + ".");
}
@@ -329,6 +348,10 @@ struct StandardPreconditioners<Operator,Dune::Amg::SequentialInformation>
return std::make_shared<Opm::ParallelOverlappingILU0<M, V, V, C>>(
op.getmat(), n, w, Opm::MILU_VARIANT::ILU);
});
F::addCreator("DILU", [](const O& op, const P& prm, const std::function<V()>&, std::size_t) {
DUNE_UNUSED_PARAMETER(prm);
return std::make_shared<SeqDilu<M, V, V>>(op.getmat());
});
F::addCreator("Jac", [](const O& op, const P& prm, const std::function<V()>&, std::size_t) {
const int n = prm.get<int>("repeats", 1);
const double w = prm.get<double>("relaxation", 1.0);
@@ -361,6 +384,9 @@ struct StandardPreconditioners<Operator,Dune::Amg::SequentialInformation>
} else if (smoother == "Jac") {
using Smoother = SeqJac<M, V, V>;
return AMGHelper<O,C,M,V>::template makeAmgPreconditioner<Smoother>(op, prm);
} else if (smoother == "DILU") {
using Smoother = SeqDilu<M, V, V>;
return AMGHelper<O,C,M,V>::template makeAmgPreconditioner<Smoother>(op, prm);
} else if (smoother == "SOR") {
using Smoother = SeqSOR<M, V, V>;
return AMGHelper<O,C,M,V>::template makeAmgPreconditioner<Smoother>(op, prm);