StandardPreconditioners_mpi.hpp
Go to the documentation of this file.
1/*
2 Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
3 Copyright 2019 SINTEF Digital, Mathematics and Cybernetics.
4
5 This file is part of the Open Porous Media project (OPM).
6
7 OPM is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 OPM is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with OPM. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#ifndef OPM_STANDARDPRECONDITIONERS_MPI_HEADER
22#define OPM_STANDARDPRECONDITIONERS_MPI_HEADER
23
24#if HAVE_CUDA
25#if USE_HIP
26#include <opm/simulators/linalg/gpuistl_hip/PreconditionerCPUMatrixToGPUMatrix.hpp>
27#else
29#endif
30#endif
31
32#include <functional>
33#include <memory>
34#include <type_traits>
35
36#if HAVE_AVX2_EXTENSION
38#endif
39
40namespace Opm {
41
42
43template <class Smoother>
45{
46 static auto args(const PropertyTree& prm)
47 {
48 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
49 SmootherArgs smootherArgs;
50 smootherArgs.iterations = prm.get<int>("iterations", 1);
51 // smootherArgs.overlap=SmootherArgs::vertex;
52 // smootherArgs.overlap=SmootherArgs::none;
53 // smootherArgs.overlap=SmootherArgs::aggregate;
54 smootherArgs.relaxationFactor = prm.get<double>("relaxation", 1.0);
55 return smootherArgs;
56 }
57};
58
59template <class M, class V, class C>
61{
62 static auto args(const PropertyTree& prm)
63 {
65 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
66 SmootherArgs smootherArgs;
67 smootherArgs.iterations = prm.get<int>("iterations", 1);
68 const int iluwitdh = prm.get<int>("iluwidth", 0);
69 smootherArgs.setN(iluwitdh);
70 const MILU_VARIANT milu = convertString2Milu(prm.get<std::string>("milutype", std::string("ilu")));
71 smootherArgs.setMilu(milu);
72 // smootherArgs.overlap=SmootherArgs::vertex;
73 // smootherArgs.overlap=SmootherArgs::none;
74 // smootherArgs.overlap=SmootherArgs::aggregate;
75 smootherArgs.relaxationFactor = prm.get<double>("relaxation", 1.0);
76 return smootherArgs;
77 }
78};
79
80// trailing return type with decltype used for detecting existence of setUseFixedOrder member function by overloading the setUseFixedOrder function
81template <typename C>
82auto setUseFixedOrder(C& criterion, bool booleanValue) -> decltype(criterion.setUseFixedOrder(booleanValue))
83{
84 return criterion.setUseFixedOrder(booleanValue); // Set flag to ensure that the matrices in the AMG hierarchy are constructed with deterministic indices.
85}
86template <typename C>
87void setUseFixedOrder(C&, ...)
88{
89 // do nothing, since the function setUseFixedOrder does not exist yet
90}
91
92template <class Operator, class Comm, class Matrix, class Vector>
95{
96 Criterion criterion(15, prm.get<int>("coarsenTarget", 1200));
97 criterion.setDefaultValuesIsotropic(2);
98 criterion.setAlpha(prm.get<double>("alpha", 0.33));
99 criterion.setBeta(prm.get<double>("beta", 1e-5));
100 criterion.setMaxLevel(prm.get<int>("maxlevel", 15));
101 criterion.setSkipIsolated(prm.get<bool>("skip_isolated", false));
102 criterion.setNoPreSmoothSteps(prm.get<int>("pre_smooth", 1));
103 criterion.setNoPostSmoothSteps(prm.get<int>("post_smooth", 1));
104 criterion.setDebugLevel(prm.get<int>("verbosity", 0));
105 // As the default we request to accumulate data to 1 process always as our matrix
106 // graph might be unsymmetric and hence not supported by the PTScotch/ParMetis
107 // calls in DUNE. Accumulating to 1 skips PTScotch/ParMetis
108 criterion.setAccumulate(static_cast<Dune::Amg::AccumulationMode>(prm.get<int>("accumulate", 1)));
109 criterion.setProlongationDampingFactor(prm.get<double>("prolongationdamping", 1.6));
110 criterion.setMaxDistance(prm.get<int>("maxdistance", 2));
111 criterion.setMaxConnectivity(prm.get<int>("maxconnectivity", 15));
112 criterion.setMaxAggregateSize(prm.get<int>("maxaggsize", 6));
113 criterion.setMinAggregateSize(prm.get<int>("minaggsize", 4));
114 setUseFixedOrder(criterion, true); // If possible, set flag to ensure that the matrices in the AMG hierarchy are constructed with deterministic indices.
115 return criterion;
116}
117
118template <class Operator, class Comm, class Matrix, class Vector>
119template <class Smoother>
122 const PropertyTree& prm,
123 bool useKamg)
124{
125 auto crit = criterion(prm);
127 if (useKamg) {
129 return std::make_shared<Type>(
130 op, crit, sargs, prm.get<std::size_t>("max_krylov", 1), prm.get<double>("min_reduction", 1e-1));
131 } else {
133 return std::make_shared<Type>(op, crit, sargs);
134 }
135}
136
137template <class Operator, class Comm, typename = void> // Note: Last argument is to allow partial specialization for GPU
139{
140 static void add()
141 {
142 using namespace Dune;
143 using O = Operator;
144 using C = Comm;
146 using M = typename F::Matrix;
147 using V = typename F::Vector;
148 using P = PropertyTree;
149 F::addCreator("ilu0", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
150 return createParILU(op, prm, comm, 0);
151 });
152 F::addCreator("paroverilu0",
153 [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
154 return createParILU(op, prm, comm, prm.get<int>("ilulevel", 0));
155 });
156 F::addCreator("ilun", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
157 return createParILU(op, prm, comm, prm.get<int>("ilulevel", 0));
158 });
159 F::addCreator("duneilu", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
160 const int n = prm.get<int>("ilulevel", 0);
161 const double w = prm.get<double>("relaxation", 1.0);
162 const bool resort = prm.get<bool>("resort", false);
163 return wrapBlockPreconditioner<RebuildOnUpdatePreconditioner<Dune::SeqILU<M, V, V>>>(
164 comm, std::cref(op.getmat()), n, w, resort);
165 });
166 F::addCreator("dilu", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
167 DUNE_UNUSED_PARAMETER(prm);
168 return wrapBlockPreconditioner<MultithreadDILU<M, V, V>>(comm, op.getmat());
169 });
170#if HAVE_AVX2_EXTENSION
171 F::addCreator("mixed-ilu0", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
172 DUNE_UNUSED_PARAMETER(prm);
173 if constexpr (std::is_same_v<typename V::field_type, float>) {
174 OPM_THROW(std::logic_error, "mixed-ilu0 is not available for floats");
175 return nullptr;
176 } else {
177 return wrapBlockPreconditioner<MixedPreconditioner<M,V,V>>(comm, op.getmat());
178 }
179 });
180 F::addCreator("mixed-dilu", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
181 DUNE_UNUSED_PARAMETER(prm);
182 if constexpr (std::is_same_v<typename V::field_type, float>) {
183 OPM_THROW(std::logic_error, "mixed-dilu is not available for floats");
184 return nullptr;
185 } else {
186 return wrapBlockPreconditioner<MixedPreconditioner<M,V,V>>(comm, op.getmat(), true);
187 }
188 });
189#endif
190 F::addCreator("jac", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
191 const int n = prm.get<int>("repeats", 1);
192 const double w = prm.get<double>("relaxation", 1.0);
193 return wrapBlockPreconditioner<DummyUpdatePreconditioner<SeqJac<M, V, V>>>(comm, op.getmat(), n, w);
194 });
195 F::addCreator("gs", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
196 const int n = prm.get<int>("repeats", 1);
197 const double w = prm.get<double>("relaxation", 1.0);
198 return wrapBlockPreconditioner<DummyUpdatePreconditioner<SeqGS<M, V, V>>>(comm, op.getmat(), n, w);
199 });
200 F::addCreator("sor", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
201 const int n = prm.get<int>("repeats", 1);
202 const double w = prm.get<double>("relaxation", 1.0);
203 return wrapBlockPreconditioner<DummyUpdatePreconditioner<SeqSOR<M, V, V>>>(comm, op.getmat(), n, w);
204 });
205 F::addCreator("ssor", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
206 const int n = prm.get<int>("repeats", 1);
207 const double w = prm.get<double>("relaxation", 1.0);
208 return wrapBlockPreconditioner<DummyUpdatePreconditioner<SeqSSOR<M, V, V>>>(comm, op.getmat(), n, w);
209 });
210
211 // Only add AMG preconditioners to the factory if the operator
212 // is the overlapping schwarz operator or GhostLastMatrixAdapter. This could be extended
213 // later, but at this point no other operators are compatible
214 // with the AMG hierarchy construction.
215 if constexpr (std::is_same_v<O, Dune::OverlappingSchwarzOperator<M, V, V, C>> ||
216 std::is_same_v<O, Opm::GhostLastMatrixAdapter<M, V, V, C>>) {
217 F::addCreator("amg", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
218 using PrecPtr = std::shared_ptr<Dune::PreconditionerWithUpdate<V, V>>;
219 std::string smoother = prm.get<std::string>("smoother", "paroverilu0");
220 // Make the smoother type lowercase for internal canonical representation
221 std::ranges::transform(smoother, smoother.begin(), ::tolower);
222 // TODO: merge this with ILUn, and possibly simplify the factory to only work with ILU?
223 if (smoother == "ilu0" || smoother == "paroverilu0") {
225 auto crit = AMGHelper<O, C, M, V>::criterion(prm);
227 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
228 return prec;
229 } else if (smoother == "dilu") {
230 using SeqSmoother = Dune::MultithreadDILU<M, V, V>;
231 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
232 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
233 SmootherArgs sargs;
234 auto crit = AMGHelper<O, C, M, V>::criterion(prm);
235 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
236 return prec;
237 } else if (smoother == "jac") {
238 using SeqSmoother = SeqJac<M, V, V>;
239 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
240 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
241 SmootherArgs sargs;
242 auto crit = AMGHelper<O, C, M, V>::criterion(prm);
243 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
244 return prec;
245 } else if (smoother == "gs") {
246 using SeqSmoother = SeqGS<M, V, V>;
247 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
248 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
249 SmootherArgs sargs;
250 auto crit = AMGHelper<O, C, M, V>::criterion(prm);
251 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
252 return prec;
253 } else if (smoother == "sor") {
254 using SeqSmoother = SeqSOR<M, V, V>;
255 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
256 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
257 SmootherArgs sargs;
258 auto crit = AMGHelper<O, C, M, V>::criterion(prm);
259 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
260 return prec;
261 } else if (smoother == "ssor") {
262 using SeqSmoother = SeqSSOR<M, V, V>;
263 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
264 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
265 SmootherArgs sargs;
266 auto crit = AMGHelper<O, C, M, V>::criterion(prm);
267 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
268 return prec;
269 } else if (smoother == "ilun") {
270 using SeqSmoother = SeqILU<M, V, V>;
271 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
272 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
273 SmootherArgs sargs;
274 auto crit = AMGHelper<O, C, M, V>::criterion(prm);
275 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
276 return prec;
277 } else {
278 OPM_THROW(std::invalid_argument, "Properties: No smoother with name " + smoother + ".");
279 }
280 });
281#if HAVE_HYPRE
282 if constexpr (M::block_type::rows == 1 && M::block_type::cols == 1
283 && std::is_same_v<HYPRE_Real, typename V::field_type>) {
284 F::addCreator(
285 "hypre", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
286 return std::make_shared<linalg::HyprePreconditioner<M, V, V, C>>(op.getmat(), prm, comm);
287 });
288 }
289#endif
290 }
291
292
293 F::addCreator("cpr",
294 [](const O& op,
295 const P& prm,
296 const std::function<V()> weightsCalculator,
297 std::size_t pressureIndex,
298 const C& comm) {
299 assert(weightsCalculator);
300 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
301 OPM_THROW(std::logic_error,
302 "Pressure index out of bounds. It needs to specified for CPR");
303 }
304 using Scalar = typename V::field_type;
305 using LevelTransferPolicy = PressureTransferPolicy<O, Comm, Scalar, false>;
306 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy, Comm>>(
307 op, prm, weightsCalculator, pressureIndex, comm);
308 });
309 F::addCreator("cprt",
310 [](const O& op,
311 const P& prm,
312 const std::function<V()> weightsCalculator,
313 std::size_t pressureIndex,
314 const C& comm) {
315 assert(weightsCalculator);
316 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
317 OPM_THROW(std::logic_error,
318 "Pressure index out of bounds. It needs to specified for CPR");
319 }
320 using Scalar = typename V::field_type;
321 using LevelTransferPolicy = PressureTransferPolicy<O, Comm, Scalar, true>;
322 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy, Comm>>(
323 op, prm, weightsCalculator, pressureIndex, comm);
324 });
325
326 // Add CPRW only for the WellModelGhostLastMatrixAdapter, as the method requires that the
327 // operator has the addWellPressureEquations() method (and a few more) it can not be combined
328 // with a well-less operator such as GhostLastMatrixAdapter or OverlappingSchwarzOperator.
329 // For OPM Flow this corresponds to requiring --matrix-add-well-contributions=false
330 // (which is the default).
331 if constexpr (std::is_same_v<O, WellModelGhostLastMatrixAdapter<M, V, V, true>>) {
332 F::addCreator("cprw",
333 [](const O& op,
334 const P& prm,
335 const std::function<V()> weightsCalculator,
336 std::size_t pressureIndex,
337 const C& comm) {
338 assert(weightsCalculator);
339 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
340 OPM_THROW(std::logic_error,
341 "Pressure index out of bounds. It needs to specified for CPR");
342 }
343 using Scalar = typename V::field_type;
344 using LevelTransferPolicy = PressureBhpTransferPolicy<O, Comm, Scalar, false>;
345 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy, Comm>>(
346 op, prm, weightsCalculator, pressureIndex, comm);
347 });
348 }
349
350#if HAVE_CUDA
351 // Here we create the *wrapped* GPU preconditioners
352 // meaning they will act as CPU preconditioners on the outside,
353 // but copy data back and forth to the GPU as needed.
354
355 // TODO: Make this use the GPU preconditioner factory once that is up and running.
356 F::addCreator("gpuilu0", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
357 const double w = prm.get<double>("relaxation", 1.0);
358 using field_type = typename V::field_type;
359 using GpuILU0 = typename gpuistl::
360 GpuSeqILU0<M, gpuistl::GpuVector<field_type>, gpuistl::GpuVector<field_type>>;
361 auto gpuILU0 = std::make_shared<GpuILU0>(op.getmat(), w);
362
363 auto adapted = std::make_shared<gpuistl::PreconditionerAdapter<V, V, GpuILU0>>(gpuILU0);
364 auto wrapped = std::make_shared<gpuistl::GpuBlockPreconditioner<V, V, Comm>>(adapted, comm);
365 return wrapped;
366 });
367
368 F::addCreator("gpujac", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
369 const double w = prm.get<double>("relaxation", 1.0);
370 using field_type = typename V::field_type;
371 using GpuJac =
373
376
377 auto gpuJac = std::make_shared<MatrixOwner>(op.getmat(), w);
378
379 auto adapted = std::make_shared<gpuistl::PreconditionerAdapter<V, V, MatrixOwner>>(gpuJac);
380 auto wrapped = std::make_shared<gpuistl::GpuBlockPreconditioner<V, V, Comm>>(adapted, comm);
381 return wrapped;
382 });
383
384 F::addCreator("gpudilu", [](const O& op, [[maybe_unused]] const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
385 const bool split_matrix = prm.get<bool>("split_matrix", true);
386 const bool tune_gpu_kernels = prm.get<bool>("tune_gpu_kernels", true);
387 const int mixed_precision_scheme = prm.get<int>("mixed_precision_scheme", 0);
388 const bool reorder = prm.get<bool>("reorder", true);
389 using field_type = typename V::field_type;
393
394 // Note: op.getmat() is passed twice, because the GpuDILU needs both the CPU and GPU matrix.
395 // The first argument will be converted to a GPU matrix, and the second one is used as a CPU matrix.
396 auto gpuDILU = std::make_shared<MatrixOwner>(op.getmat(), op.getmat(), split_matrix, tune_gpu_kernels, mixed_precision_scheme, reorder);
397
398 auto adapted = std::make_shared<gpuistl::PreconditionerAdapter<V, V, MatrixOwner>>(gpuDILU);
399 auto wrapped = std::make_shared<gpuistl::GpuBlockPreconditioner<V, V, Comm>>(adapted, comm);
400 return wrapped;
401 });
402
403 F::addCreator("opmgpuilu0", [](const O& op, [[maybe_unused]] const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
404 const bool split_matrix = prm.get<bool>("split_matrix", true);
405 const bool tune_gpu_kernels = prm.get<bool>("tune_gpu_kernels", true);
406 const int mixed_precision_scheme = prm.get<int>("mixed_precision_scheme", 0);
407 using field_type = typename V::field_type;
409
411 gpuistl::GpuVector<field_type>, OpmGpuILU0, M>;
412
413 // Note: op.getmat() is passed twice, because the OPMGPUILU0 needs both the CPU and GPU matrix.
414 // The first argument will be converted to a GPU matrix, and the second one is used as a CPU matrix.
415 auto gpuilu0 = std::make_shared<MatrixOwner>(op.getmat(), op.getmat(), split_matrix, tune_gpu_kernels, mixed_precision_scheme);
416
417 auto adapted = std::make_shared<gpuistl::PreconditionerAdapter<V, V, MatrixOwner>>(gpuilu0);
418 auto wrapped = std::make_shared<gpuistl::GpuBlockPreconditioner<V, V, Comm>>(adapted, comm);
419 return wrapped;
420 });
421#endif // HAVE_CUDA
422 }
423
424
426 createParILU(const Operator& op, const PropertyTree& prm, const Comm& comm, const int ilulevel)
427 {
429 using M = typename F::Matrix;
430 using V = typename F::Vector;
431
432 const double w = prm.get<double>("relaxation", 1.0);
433 const bool redblack = prm.get<bool>("redblack", false);
434 const bool reorder_spheres = prm.get<bool>("reorder_spheres", false);
435 // Already a parallel preconditioner. Need to pass comm, but no need to wrap it in a BlockPreconditioner.
436 if (ilulevel == 0) {
437 const std::size_t num_interior = interiorIfGhostLast(comm);
438 assert(num_interior <= op.getmat().N());
439 return std::make_shared<ParallelOverlappingILU0<M, V, V, Comm>>(
440 op.getmat(), comm, w, MILU_VARIANT::ILU, num_interior, redblack, reorder_spheres);
441 } else {
442 return std::make_shared<ParallelOverlappingILU0<M, V, V, Comm>>(
443 op.getmat(), comm, ilulevel, w, MILU_VARIANT::ILU, redblack, reorder_spheres);
444 }
445 }
446
451 static std::size_t interiorIfGhostLast(const Comm& comm)
452 {
453 std::size_t interior_count = 0;
454 std::size_t highest_interior_index = 0;
455 const auto& is = comm.indexSet();
456 for (const auto& ind : is) {
457 if (Comm::OwnerSet::contains(ind.local().attribute())) {
458 ++interior_count;
459 highest_interior_index = std::max(highest_interior_index, ind.local().local());
460 }
461 }
462 if (highest_interior_index + 1 == interior_count) {
463 return interior_count;
464 } else {
465 return is.size();
466 }
467 }
468};
469
470
471} // namespace Opm
472
473#endif // OPM_STANDARDPRECONDITIONERS_MPI_HEADER
Dune::OwnerOverlapCopyCommunication< int, int > Comm
Definition: FlexibleSolver_impl.hpp:394
Parallel algebraic multigrid based on agglomeration.
Definition: amgcpr.hh:88
Definition: PreconditionerWithUpdate.hpp:45
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:53
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:161
Definition: blackoilbioeffectsmodules.hh:45
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:82
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:94
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:121
static auto args(const PropertyTree &prm)
Definition: StandardPreconditioners_mpi.hpp:62
Definition: StandardPreconditioners_mpi.hpp:45
static auto args(const PropertyTree &prm)
Definition: StandardPreconditioners_mpi.hpp:46
Definition: StandardPreconditioners_mpi.hpp:139
static PreconditionerFactory< Operator, Comm >::PrecPtr createParILU(const Operator &op, const PropertyTree &prm, const Comm &comm, const int ilulevel)
Definition: StandardPreconditioners_mpi.hpp:426
static std::size_t interiorIfGhostLast(const Comm &comm)
Definition: StandardPreconditioners_mpi.hpp:451
static void add()
Definition: StandardPreconditioners_mpi.hpp:140