mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Add DILU preconditioner
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user