Go to the documentation of this file.
21#ifndef OPM_STANDARDPRECONDITIONERS_MPI_HEADER
22#define OPM_STANDARDPRECONDITIONERS_MPI_HEADER
32template < class Smoother>
37 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
38 SmootherArgs smootherArgs;
39 smootherArgs.iterations = prm. get< int>( "iterations", 1);
43 smootherArgs.relaxationFactor = prm. get< double>( "relaxation", 1.0);
48template < class M, class V, class C>
54 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
55 SmootherArgs smootherArgs;
56 smootherArgs.iterations = prm. get< int>( "iterations", 1);
57 const int iluwitdh = prm. get< int>( "iluwidth", 0);
58 smootherArgs.setN(iluwitdh);
60 smootherArgs.setMilu(milu);
64 smootherArgs.relaxationFactor = prm. get< double>( "relaxation", 1.0);
71auto setUseFixedOrder(C& criterion, bool booleanValue) -> decltype(criterion.setUseFixedOrder(booleanValue))
73 return criterion.setUseFixedOrder(booleanValue);
81template < class Operator, class Comm, class Matrix, class Vector>
85 Criterion criterion(15, prm. get< int>( "coarsenTarget", 1200));
86 criterion.setDefaultValuesIsotropic(2);
87 criterion.setAlpha(prm. get< double>( "alpha", 0.33));
88 criterion.setBeta(prm. get< double>( "beta", 1e-5));
89 criterion.setMaxLevel(prm. get< int>( "maxlevel", 15));
90 criterion.setSkipIsolated(prm. get< bool>( "skip_isolated", false));
91 criterion.setNoPreSmoothSteps(prm. get< int>( "pre_smooth", 1));
92 criterion.setNoPostSmoothSteps(prm. get< int>( "post_smooth", 1));
93 criterion.setDebugLevel(prm. get< int>( "verbosity", 0));
97 criterion.setAccumulate( static_cast<Dune::Amg::AccumulationMode >(prm. get< int>( "accumulate", 1)));
98 criterion.setProlongationDampingFactor(prm. get< double>( "prolongationdamping", 1.6));
99 criterion.setMaxDistance(prm. get< int>( "maxdistance", 2));
100 criterion.setMaxConnectivity(prm. get< int>( "maxconnectivity", 15));
101 criterion.setMaxAggregateSize(prm. get< int>( "maxaggsize", 6));
102 criterion.setMinAggregateSize(prm. get< int>( "minaggsize", 4));
107template < class Operator, class Comm, class Matrix, class Vector>
108template < class Smoother>
114 auto crit = criterion(prm);
118 return std::make_shared<Type>(
119 op, crit, sargs, prm. get<std::size_t>( "max_krylov", 1), prm. get< double>( "min_reduction", 1e-1));
122 return std::make_shared<Type>(op, crit, sargs);
126template < class Operator, class Comm, typename = void>
131 using namespace Dune;
135 using M = typename F::Matrix;
136 using V = typename F::Vector;
138 F::addCreator( "ILU0", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
141 F::addCreator( "ParOverILU0",
142 []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
143 return createParILU(op, prm, comm, prm.get< int>( "ilulevel", 0));
145 F::addCreator( "ILUn", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
146 return createParILU(op, prm, comm, prm.get< int>( "ilulevel", 0));
148 F::addCreator( "DuneILU", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
149 const int n = prm.get< int>( "ilulevel", 0);
150 const double w = prm.get< double>( "relaxation", 1.0);
151 const bool resort = prm.get< bool>( "resort", false);
152 return wrapBlockPreconditioner<RebuildOnUpdatePreconditioner<Dune::SeqILU<M, V, V>>>(
153 comm, op.getmat(), n, w, resort);
155 F::addCreator( "DILU", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
156 DUNE_UNUSED_PARAMETER(prm);
157 return wrapBlockPreconditioner<MultithreadDILU<M, V, V>>(comm, op.getmat());
159 F::addCreator( "Jac", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
160 const int n = prm.get< int>( "repeats", 1);
161 const double w = prm.get< double>( "relaxation", 1.0);
162 return wrapBlockPreconditioner<DummyUpdatePreconditioner<SeqJac<M, V, V>>>(comm, op.getmat(), n, w);
164 F::addCreator( "GS", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
165 const int n = prm.get< int>( "repeats", 1);
166 const double w = prm.get< double>( "relaxation", 1.0);
167 return wrapBlockPreconditioner<DummyUpdatePreconditioner<SeqGS<M, V, V>>>(comm, op.getmat(), n, w);
169 F::addCreator( "SOR", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
170 const int n = prm.get< int>( "repeats", 1);
171 const double w = prm.get< double>( "relaxation", 1.0);
172 return wrapBlockPreconditioner<DummyUpdatePreconditioner<SeqSOR<M, V, V>>>(comm, op.getmat(), n, w);
174 F::addCreator( "SSOR", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
175 const int n = prm.get< int>( "repeats", 1);
176 const double w = prm.get< double>( "relaxation", 1.0);
177 return wrapBlockPreconditioner<DummyUpdatePreconditioner<SeqSSOR<M, V, V>>>(comm, op.getmat(), n, w);
184 if constexpr (std::is_same_v<O, Dune::OverlappingSchwarzOperator<M, V, V, C>> ||
185 std::is_same_v<O, Opm::GhostLastMatrixAdapter<M, V, V, C>>) {
186 F::addCreator( "amg", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
187 using PrecPtr = std::shared_ptr<Dune::PreconditionerWithUpdate<V, V>>;
188 const std::string smoother = prm.get<std::string>( "smoother", "ParOverILU0");
190 if (smoother == "ILU0" || smoother == "ParOverILU0") {
194 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
196 } else if (smoother == "DILU") {
198 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
199 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
202 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
204 } else if (smoother == "Jac") {
205 using SeqSmoother = SeqJac<M, V, V>;
206 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
207 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
210 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
212 } else if (smoother == "GS") {
213 using SeqSmoother = SeqGS<M, V, V>;
214 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
215 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
218 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
220 } else if (smoother == "SOR") {
221 using SeqSmoother = SeqSOR<M, V, V>;
222 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
223 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
226 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
228 } else if (smoother == "SSOR") {
229 using SeqSmoother = SeqSSOR<M, V, V>;
230 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
231 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
234 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
236 } else if (smoother == "ILUn") {
237 using SeqSmoother = SeqILU<M, V, V>;
238 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
239 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
242 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
245 OPM_THROW(std::invalid_argument, "Properties: No smoother with name " + smoother + ".");
253 const std::function<V()> weightsCalculator,
254 std::size_t pressureIndex,
256 assert(weightsCalculator);
257 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
258 OPM_THROW(std::logic_error,
259 "Pressure index out of bounds. It needs to specified for CPR");
261 using Scalar = typename V::field_type;
263 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy, Comm>>(
264 op, prm, weightsCalculator, pressureIndex, comm);
266 F::addCreator( "cprt",
269 const std::function<V()> weightsCalculator,
270 std::size_t pressureIndex,
272 assert(weightsCalculator);
273 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
274 OPM_THROW(std::logic_error,
275 "Pressure index out of bounds. It needs to specified for CPR");
277 using Scalar = typename V::field_type;
279 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy, Comm>>(
280 op, prm, weightsCalculator, pressureIndex, comm);
288 if constexpr (std::is_same_v<O, WellModelGhostLastMatrixAdapter<M, V, V, true>>) {
289 F::addCreator( "cprw",
292 const std::function<V()> weightsCalculator,
293 std::size_t pressureIndex,
295 assert(weightsCalculator);
296 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
297 OPM_THROW(std::logic_error,
298 "Pressure index out of bounds. It needs to specified for CPR");
300 using Scalar = typename V::field_type;
302 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy, Comm>>(
303 op, prm, weightsCalculator, pressureIndex, comm);
313 F::addCreator( "GPUILU0", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
314 const double w = prm.get< double>( "relaxation", 1.0);
315 using field_type = typename V::field_type;
316 using GpuILU0 = typename gpuistl::
317 GpuSeqILU0<M, gpuistl::GpuVector<field_type>, gpuistl::GpuVector<field_type>>;
318 auto gpuILU0 = std::make_shared<GpuILU0>(op.getmat(), w);
320 auto adapted = std::make_shared<gpuistl::PreconditionerAdapter<V, V, GpuILU0>>(gpuILU0);
321 auto wrapped = std::make_shared<gpuistl::GpuBlockPreconditioner<V, V, Comm>>(adapted, comm);
325 F::addCreator( "GPUJAC", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
326 const double w = prm.get< double>( "relaxation", 1.0);
327 using field_type = typename V::field_type;
332 gpuistl::GpuVector<field_type>, GpuJac, M>;
334 auto gpuJac = std::make_shared<MatrixOwner>(op.getmat(), w);
336 auto adapted = std::make_shared<gpuistl::PreconditionerAdapter<V, V, MatrixOwner>>(gpuJac);
337 auto wrapped = std::make_shared<gpuistl::GpuBlockPreconditioner<V, V, Comm>>(adapted, comm);
341 F::addCreator( "GPUDILU", []( const O& op, [[maybe_unused]] const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
342 const bool split_matrix = prm.get< bool>( "split_matrix", true);
343 const bool tune_gpu_kernels = prm.get< bool>( "tune_gpu_kernels", true);
344 const int mixed_precision_scheme = prm.get< int>( "mixed_precision_scheme", 0);
345 using field_type = typename V::field_type;
348 gpuistl::GpuVector<field_type>, GpuDILU, M>;
352 auto gpuDILU = std::make_shared<MatrixOwner>(op.getmat(), op.getmat(), split_matrix, tune_gpu_kernels, mixed_precision_scheme);
354 auto adapted = std::make_shared<gpuistl::PreconditionerAdapter<V, V, MatrixOwner>>(gpuDILU);
355 auto wrapped = std::make_shared<gpuistl::GpuBlockPreconditioner<V, V, Comm>>(adapted, comm);
359 F::addCreator( "OPMGPUILU0", []( const O& op, [[maybe_unused]] const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
360 const bool split_matrix = prm.get< bool>( "split_matrix", true);
361 const bool tune_gpu_kernels = prm.get< bool>( "tune_gpu_kernels", true);
362 const int mixed_precision_scheme = prm.get< int>( "mixed_precision_scheme", 0);
363 using field_type = typename V::field_type;
367 gpuistl::GpuVector<field_type>, OpmGpuILU0, M>;
371 auto gpuilu0 = std::make_shared<MatrixOwner>(op.getmat(), op.getmat(), split_matrix, tune_gpu_kernels, mixed_precision_scheme);
373 auto adapted = std::make_shared<gpuistl::PreconditionerAdapter<V, V, MatrixOwner>>(gpuilu0);
374 auto wrapped = std::make_shared<gpuistl::GpuBlockPreconditioner<V, V, Comm>>(adapted, comm);
385 using M = typename F::Matrix;
386 using V = typename F::Vector;
388 const double w = prm. get< double>( "relaxation", 1.0);
389 const bool redblack = prm. get< bool>( "redblack", false);
390 const bool reorder_spheres = prm. get< bool>( "reorder_spheres", false);
394 assert(num_interior <= op.getmat().N());
395 return std::make_shared<ParallelOverlappingILU0<M, V, V, Comm>>(
396 op.getmat(), comm, w, MILU_VARIANT::ILU, num_interior, redblack, reorder_spheres);
398 return std::make_shared<ParallelOverlappingILU0<M, V, V, Comm>>(
409 std::size_t interior_count = 0;
410 std::size_t highest_interior_index = 0;
411 const auto& is = comm.indexSet();
412 for ( const auto& ind : is) {
413 if (Comm::OwnerSet::contains(ind.local().attribute())) {
415 highest_interior_index = std::max(highest_interior_index, ind.local().local());
418 if (highest_interior_index + 1 == interior_count) {
419 return interior_count;
Dune::OwnerOverlapCopyCommunication< int, int > Comm Definition: FlexibleSolver_impl.hpp:304
Parallel algebraic multigrid based on agglomeration. Definition: amgcpr.hh:88
Definition: PreconditionerWithUpdate.hpp:43
The OpenMP thread parallelized DILU preconditioner. Definition: DILU.hpp:53
A two-step version of an overlapping Schwarz preconditioner using one step ILU0 as. Definition: ParallelOverlappingILU0.hpp:131
Definition: PreconditionerFactory.hpp:64
std::shared_ptr< Dune::PreconditionerWithUpdate< Vector, Vector > > PrecPtr The type of pointer returned by create(). Definition: PreconditionerFactory.hpp:71
Definition: PressureBhpTransferPolicy.hpp:99
Definition: PressureTransferPolicy.hpp:55
Hierarchical collection of key/value pairs. Definition: PropertyTree.hpp:39
T get(const std::string &key) const
DILU preconditioner on the GPU. Definition: GpuDILU.hpp:50
Jacobi preconditioner on the GPU. Definition: GpuJac.hpp:47
ILU0 preconditioner on the GPU. Definition: OpmGpuILU0.hpp:51
Convert a CPU matrix to a GPU matrix and use a CUDA preconditioner on the GPU. Definition: PreconditionerCPUMatrixToGPUMatrix.hpp:42
Definition: fvbaseprimaryvariables.hh:141
Definition: blackoilboundaryratevector.hh:39
MILU_VARIANT Definition: MILU.hpp:34
@ ILU Do not perform modified ILU.
auto setUseFixedOrder(C &criterion, bool booleanValue) -> decltype(criterion.setUseFixedOrder(booleanValue)) Definition: StandardPreconditioners_mpi.hpp:71
MILU_VARIANT convertString2Milu(const std::string &milu)
Dune::Amg::CoarsenCriterion< CriterionBase > Criterion Definition: PreconditionerFactory.hpp:47
static Criterion criterion(const PropertyTree &prm) Definition: StandardPreconditioners_mpi.hpp:83
std::shared_ptr< Dune::PreconditionerWithUpdate< Vector, Vector > > PrecPtr Definition: PreconditionerFactory.hpp:44
static PrecPtr makeAmgPreconditioner(const Operator &op, const PropertyTree &prm, bool useKamg=false) Definition: StandardPreconditioners_mpi.hpp:110
static auto args(const PropertyTree &prm) Definition: StandardPreconditioners_mpi.hpp:51
Definition: StandardPreconditioners_mpi.hpp:34
static auto args(const PropertyTree &prm) Definition: StandardPreconditioners_mpi.hpp:35
Definition: StandardPreconditioners_mpi.hpp:128
static PreconditionerFactory< Operator, Comm >::PrecPtr createParILU(const Operator &op, const PropertyTree &prm, const Comm &comm, const int ilulevel) Definition: StandardPreconditioners_mpi.hpp:382
static std::size_t interiorIfGhostLast(const Comm &comm) Definition: StandardPreconditioners_mpi.hpp:407
static void add() Definition: StandardPreconditioners_mpi.hpp:129
|