Go to the documentation of this file.
23#include <opm/common/ErrorMacros.hpp>
24#include <opm/common/TimingMacros.hpp>
42#include <dune/common/unused.hh>
43#include <dune/istl/owneroverlapcopy.hh>
44#include <dune/istl/paamg/amg.hh>
45#include <dune/istl/paamg/fastamg.hh>
46#include <dune/istl/paamg/kamg.hh>
47#include <dune/istl/preconditioners.hh>
55template < class Smoother>
60 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
61 SmootherArgs smootherArgs;
62 smootherArgs.iterations = prm. get< int>( "iterations", 1);
66 smootherArgs.relaxationFactor = prm. get< double>( "relaxation", 1.0);
71template < class M, class V, class C>
77 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
78 SmootherArgs smootherArgs;
79 smootherArgs.iterations = prm. get< int>( "iterations", 1);
80 const int iluwitdh = prm. get< int>( "iluwidth", 0);
81 smootherArgs.setN(iluwitdh);
83 smootherArgs.setMilu(milu);
87 smootherArgs.relaxationFactor = prm. get< double>( "relaxation", 1.0);
94auto setUseFixedOrder(C criterion, bool booleanValue) -> decltype(criterion.setUseFixedOrder(booleanValue))
96 return criterion.setUseFixedOrder(booleanValue);
104template < class Operator, class Comm, class Matrix, class Vector>
108 Criterion criterion(15, prm. get< int>( "coarsenTarget", 1200));
109 criterion.setDefaultValuesIsotropic(2);
110 criterion.setAlpha(prm. get< double>( "alpha", 0.33));
111 criterion.setBeta(prm. get< double>( "beta", 1e-5));
112 criterion.setMaxLevel(prm. get< int>( "maxlevel", 15));
113 criterion.setSkipIsolated(prm. get< bool>( "skip_isolated", false));
114 criterion.setNoPreSmoothSteps(prm. get< int>( "pre_smooth", 1));
115 criterion.setNoPostSmoothSteps(prm. get< int>( "post_smooth", 1));
116 criterion.setDebugLevel(prm. get< int>( "verbosity", 0));
120 criterion.setAccumulate( static_cast<Dune::Amg::AccumulationMode >(prm. get< int>( "accumulate", 1)));
121 criterion.setProlongationDampingFactor(prm. get< double>( "prolongationdamping", 1.6));
122 criterion.setMaxDistance(prm. get< int>( "maxdistance", 2));
123 criterion.setMaxConnectivity(prm. get< int>( "maxconnectivity", 15));
124 criterion.setMaxAggregateSize(prm. get< int>( "maxaggsize", 6));
125 criterion.setMinAggregateSize(prm. get< int>( "minaggsize", 4));
130template < class Operator, class Comm, class Matrix, class Vector>
131template < class Smoother>
137 auto crit = criterion(prm);
141 return std::make_shared<Type>(
142 op, crit, sargs, prm. get<std::size_t>( "max_krylov", 1), prm. get< double>( "min_reduction", 1e-1));
145 return std::make_shared<Type>(op, crit, sargs);
149template < class Operator, class Comm>
153 using namespace Dune;
157 using M = typename F::Matrix;
158 using V = typename F::Vector;
160 F::addCreator( "ILU0", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
163 F::addCreator( "ParOverILU0",
164 []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
165 return createParILU(op, prm, comm, prm.get< int>( "ilulevel", 0));
167 F::addCreator( "ILUn", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
168 return createParILU(op, prm, comm, prm.get< int>( "ilulevel", 0));
170 F::addCreator( "DuneILU", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
171 const int n = prm.get< int>( "ilulevel", 0);
172 const double w = prm.get< double>( "relaxation", 1.0);
173 const bool resort = prm.get< bool>( "resort", false);
174 return wrapBlockPreconditioner<RebuildOnUpdatePreconditioner<Dune::SeqILU<M, V, V>>>(
175 comm, op.getmat(), n, w, resort);
177 F::addCreator( "DILU", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
178 DUNE_UNUSED_PARAMETER(prm);
179 return wrapBlockPreconditioner<MultithreadDILU<M, V, V>>(comm, op.getmat());
181 F::addCreator( "Jac", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
182 const int n = prm.get< int>( "repeats", 1);
183 const double w = prm.get< double>( "relaxation", 1.0);
184 return wrapBlockPreconditioner<DummyUpdatePreconditioner<SeqJac<M, V, V>>>(comm, op.getmat(), n, w);
186 F::addCreator( "GS", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
187 const int n = prm.get< int>( "repeats", 1);
188 const double w = prm.get< double>( "relaxation", 1.0);
189 return wrapBlockPreconditioner<DummyUpdatePreconditioner<SeqGS<M, V, V>>>(comm, op.getmat(), n, w);
191 F::addCreator( "SOR", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
192 const int n = prm.get< int>( "repeats", 1);
193 const double w = prm.get< double>( "relaxation", 1.0);
194 return wrapBlockPreconditioner<DummyUpdatePreconditioner<SeqSOR<M, V, V>>>(comm, op.getmat(), n, w);
196 F::addCreator( "SSOR", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
197 const int n = prm.get< int>( "repeats", 1);
198 const double w = prm.get< double>( "relaxation", 1.0);
199 return wrapBlockPreconditioner<DummyUpdatePreconditioner<SeqSSOR<M, V, V>>>(comm, op.getmat(), n, w);
206 if constexpr (std::is_same_v<O, Dune::OverlappingSchwarzOperator<M, V, V, C>> ||
207 std::is_same_v<O, Opm::GhostLastMatrixAdapter<M, V, V, C>>) {
208 F::addCreator( "amg", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
209 using PrecPtr = std::shared_ptr<Dune::PreconditionerWithUpdate<V, V>>;
210 const std::string smoother = prm.get<std::string>( "smoother", "ParOverILU0");
212 if (smoother == "ILU0" || smoother == "ParOverILU0") {
216 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
218 } else if (smoother == "DILU") {
220 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
221 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
224 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
226 } else if (smoother == "Jac") {
227 using SeqSmoother = SeqJac<M, V, V>;
228 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
229 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
232 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
234 } else if (smoother == "GS") {
235 using SeqSmoother = SeqGS<M, V, V>;
236 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
237 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
240 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
242 } else if (smoother == "SOR") {
243 using SeqSmoother = SeqSOR<M, V, V>;
244 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
245 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
248 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
250 } else if (smoother == "SSOR") {
251 using SeqSmoother = SeqSSOR<M, V, V>;
252 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
253 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
256 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
258 } else if (smoother == "ILUn") {
259 using SeqSmoother = SeqILU<M, V, V>;
260 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
261 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
264 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
267 OPM_THROW(std::invalid_argument, "Properties: No smoother with name " + smoother + ".");
275 const std::function<V()> weightsCalculator,
276 std::size_t pressureIndex,
278 assert(weightsCalculator);
279 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
280 OPM_THROW(std::logic_error,
281 "Pressure index out of bounds. It needs to specified for CPR");
283 using Scalar = typename V::field_type;
285 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy, Comm>>(
286 op, prm, weightsCalculator, pressureIndex, comm);
288 F::addCreator( "cprt",
291 const std::function<V()> weightsCalculator,
292 std::size_t pressureIndex,
294 assert(weightsCalculator);
295 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
296 OPM_THROW(std::logic_error,
297 "Pressure index out of bounds. It needs to specified for CPR");
299 using Scalar = typename V::field_type;
301 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy, Comm>>(
302 op, prm, weightsCalculator, pressureIndex, comm);
305 if constexpr (std::is_same_v<O, WellModelGhostLastMatrixAdapter<M, V, V, true>>) {
306 F::addCreator( "cprw",
309 const std::function<V()> weightsCalculator,
310 std::size_t pressureIndex,
312 assert(weightsCalculator);
313 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
314 OPM_THROW(std::logic_error,
315 "Pressure index out of bounds. It needs to specified for CPR");
317 using Scalar = typename V::field_type;
319 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy, Comm>>(
320 op, prm, weightsCalculator, pressureIndex, comm);
325 F::addCreator( "GPUILU0", []( 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;
328 using GpuILU0 = typename gpuistl::
329 GpuSeqILU0<M, gpuistl::GpuVector<field_type>, gpuistl::GpuVector<field_type>>;
330 auto gpuILU0 = std::make_shared<GpuILU0>(op.getmat(), w);
332 auto adapted = std::make_shared<gpuistl::PreconditionerAdapter<V, V, GpuILU0>>(gpuILU0);
333 auto wrapped = std::make_shared<gpuistl::GpuBlockPreconditioner<V, V, Comm>>(adapted, comm);
337 F::addCreator( "GPUJAC", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
338 const double w = prm.get< double>( "relaxation", 1.0);
339 using field_type = typename V::field_type;
342 auto gpuJac = std::make_shared<GpuJac>(op.getmat(), w);
344 auto adapted = std::make_shared<gpuistl::PreconditionerAdapter<V, V, GpuJac>>(gpuJac);
345 auto wrapped = std::make_shared<gpuistl::GpuBlockPreconditioner<V, V, Comm>>(adapted, comm);
349 F::addCreator( "GPUDILU", []( const O& op, [[maybe_unused]] const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
350 const bool split_matrix = prm.get< bool>( "split_matrix", true);
351 const bool tune_gpu_kernels = prm.get< bool>( "tune_gpu_kernels", true);
352 using field_type = typename V::field_type;
354 auto gpuDILU = std::make_shared<GpuDILU>(op.getmat(), split_matrix, tune_gpu_kernels);
356 auto adapted = std::make_shared<gpuistl::PreconditionerAdapter<V, V, GpuDILU>>(gpuDILU);
357 auto wrapped = std::make_shared<gpuistl::GpuBlockPreconditioner<V, V, Comm>>(adapted, comm);
361 F::addCreator( "OPMGPUILU0", []( const O& op, [[maybe_unused]] const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
362 const bool split_matrix = prm.get< bool>( "split_matrix", true);
363 const bool tune_gpu_kernels = prm.get< bool>( "tune_gpu_kernels", true);
364 using field_type = typename V::field_type;
366 auto gpuilu0 = std::make_shared<OpmGpuILU0>(op.getmat(), split_matrix, tune_gpu_kernels);
368 auto adapted = std::make_shared<gpuistl::PreconditionerAdapter<V, V, OpmGpuILU0>>(gpuilu0);
369 auto wrapped = std::make_shared<gpuistl::GpuBlockPreconditioner<V, V, Comm>>(adapted, comm);
380 using M = typename F::Matrix;
381 using V = typename F::Vector;
383 const double w = prm. get< double>( "relaxation", 1.0);
384 const bool redblack = prm. get< bool>( "redblack", false);
385 const bool reorder_spheres = prm. get< bool>( "reorder_spheres", false);
389 return std::make_shared<ParallelOverlappingILU0<M, V, V, Comm>>(
390 op.getmat(), comm, w, MILU_VARIANT::ILU, num_interior, redblack, reorder_spheres);
392 return std::make_shared<ParallelOverlappingILU0<M, V, V, Comm>>(
403 std::size_t interior_count = 0;
404 std::size_t highest_interior_index = 0;
405 const auto& is = comm.indexSet();
406 for ( const auto& ind : is) {
407 if (Comm::OwnerSet::contains(ind.local().attribute())) {
409 highest_interior_index = std::max(highest_interior_index, ind.local().local());
412 if (highest_interior_index + 1 == interior_count) {
413 return interior_count;
420template < class Operator>
424 using namespace Dune;
426 using C = Dune::Amg::SequentialInformation;
428 using M = typename F::Matrix;
429 using V = typename F::Vector;
431 F::addCreator( "ILU0", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
432 const double w = prm.get< double>( "relaxation", 1.0);
433 return std::make_shared<ParallelOverlappingILU0<M, V, V, C>>(
436 F::addCreator( "DuneILU", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
437 const double w = prm.get< double>( "relaxation", 1.0);
438 const int n = prm.get< int>( "ilulevel", 0);
439 const bool resort = prm.get< bool>( "resort", false);
440 return getRebuildOnUpdateWrapper<Dune::SeqILU<M, V, V>>(op.getmat(), n, w, resort);
442 F::addCreator( "ParOverILU0", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
443 const double w = prm.get< double>( "relaxation", 1.0);
444 const int n = prm.get< int>( "ilulevel", 0);
445 return std::make_shared<ParallelOverlappingILU0<M, V, V, C>>(
448 F::addCreator( "ILUn", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
449 const int n = prm.get< int>( "ilulevel", 0);
450 const double w = prm.get< double>( "relaxation", 1.0);
451 return std::make_shared<ParallelOverlappingILU0<M, V, V, C>>(
454 F::addCreator( "DILU", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
455 DUNE_UNUSED_PARAMETER(prm);
456 return std::make_shared<MultithreadDILU<M, V, V>>(op.getmat());
458 F::addCreator( "Jac", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
459 const int n = prm.get< int>( "repeats", 1);
460 const double w = prm.get< double>( "relaxation", 1.0);
461 return getDummyUpdateWrapper<SeqJac<M, V, V>>(op.getmat(), n, w);
463 F::addCreator( "GS", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
464 const int n = prm.get< int>( "repeats", 1);
465 const double w = prm.get< double>( "relaxation", 1.0);
466 return getDummyUpdateWrapper<SeqGS<M, V, V>>(op.getmat(), n, w);
468 F::addCreator( "SOR", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
469 const int n = prm.get< int>( "repeats", 1);
470 const double w = prm.get< double>( "relaxation", 1.0);
471 return getDummyUpdateWrapper<SeqSOR<M, V, V>>(op.getmat(), n, w);
473 F::addCreator( "SSOR", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
474 const int n = prm.get< int>( "repeats", 1);
475 const double w = prm.get< double>( "relaxation", 1.0);
476 return getDummyUpdateWrapper<SeqSSOR<M, V, V>>(op.getmat(), n, w);
481 if constexpr (std::is_same_v<O, Dune::MatrixAdapter<M, V, V>>) {
482 F::addCreator( "amg", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
483 const std::string smoother = prm.get<std::string>( "smoother", "ParOverILU0");
484 if (smoother == "ILU0" || smoother == "ParOverILU0") {
485 using Smoother = SeqILU<M, V, V>;
487 } else if (smoother == "Jac") {
488 using Smoother = SeqJac<M, V, V>;
490 } else if (smoother == "GS") {
491 using Smoother = SeqGS<M, V, V>;
493 } else if (smoother == "DILU") {
496 } else if (smoother == "SOR") {
497 using Smoother = SeqSOR<M, V, V>;
499 } else if (smoother == "SSOR") {
500 using Smoother = SeqSSOR<M, V, V>;
502 } else if (smoother == "ILUn") {
503 using Smoother = SeqILU<M, V, V>;
506 OPM_THROW(std::invalid_argument, "Properties: No smoother with name " + smoother + ".");
509 F::addCreator( "kamg", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
510 const std::string smoother = prm.get<std::string>( "smoother", "ParOverILU0");
511 if (smoother == "ILU0" || smoother == "ParOverILU0") {
512 using Smoother = SeqILU<M, V, V>;
514 } else if (smoother == "Jac") {
515 using Smoother = SeqJac<M, V, V>;
517 } else if (smoother == "SOR") {
518 using Smoother = SeqSOR<M, V, V>;
520 } else if (smoother == "GS") {
521 using Smoother = SeqGS<M, V, V>;
523 } else if (smoother == "SSOR") {
524 using Smoother = SeqSSOR<M, V, V>;
526 } else if (smoother == "ILUn") {
527 using Smoother = SeqILU<M, V, V>;
530 OPM_THROW(std::invalid_argument, "Properties: No smoother with name " + smoother + ".");
533 F::addCreator( "famg", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
534 if constexpr (std::is_same_v<typename V::field_type, float>) {
535 OPM_THROW(std::logic_error, "famg requires UMFPack which is not available for floats");
539 Dune::Amg::Parameters parms;
540 parms.setNoPreSmoothSteps(1);
541 parms.setNoPostSmoothSteps(1);
542 return getRebuildOnUpdateWrapper<Dune::Amg::FastAMG<O, V>>(op, crit, parms);
546 if constexpr (std::is_same_v<O, WellModelMatrixAdapter<M, V, V, false>>) {
549 []( const O& op, const P& prm, const std::function<V()>& weightsCalculator, std::size_t pressureIndex) {
550 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
551 OPM_THROW(std::logic_error, "Pressure index out of bounds. It needs to specified for CPR");
553 using Scalar = typename V::field_type;
554 using LevelTransferPolicy
556 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy>>(
557 op, prm, weightsCalculator, pressureIndex);
563 []( const O& op, const P& prm, const std::function<V()>& weightsCalculator, std::size_t pressureIndex) {
564 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
565 OPM_THROW(std::logic_error, "Pressure index out of bounds. It needs to specified for CPR");
567 using Scalar = typename V::field_type;
569 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy>>(
570 op, prm, weightsCalculator, pressureIndex);
574 []( const O& op, const P& prm, const std::function<V()>& weightsCalculator, std::size_t pressureIndex) {
575 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
576 OPM_THROW(std::logic_error, "Pressure index out of bounds. It needs to specified for CPR");
578 using Scalar = typename V::field_type;
580 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy>>(
581 op, prm, weightsCalculator, pressureIndex);
585 F::addCreator( "GPUILU0", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
586 const double w = prm.get< double>( "relaxation", 1.0);
587 using field_type = typename V::field_type;
588 using GpuILU0 = typename gpuistl::
589 GpuSeqILU0<M, gpuistl::GpuVector<field_type>, gpuistl::GpuVector<field_type>>;
590 return std::make_shared<gpuistl::PreconditionerAdapter<V, V, GpuILU0>>(
591 std::make_shared<GpuILU0>(op.getmat(), w));
594 F::addCreator( "GPUILU0Float", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
595 const double w = prm.get< double>( "relaxation", 1.0);
596 using block_type = typename V::block_type;
597 using VTo = Dune::BlockVector<Dune::FieldVector<float, block_type::dimension>>;
598 using matrix_type_to =
599 typename Dune::BCRSMatrix<Dune::FieldMatrix<float, block_type::dimension, block_type::dimension>>;
600 using GpuILU0 = typename gpuistl::
601 GpuSeqILU0<matrix_type_to, gpuistl::GpuVector<float>, gpuistl::GpuVector<float>>;
604 auto converted = std::make_shared<Converter>(op.getmat());
605 auto adapted = std::make_shared<Adapter>(std::make_shared<GpuILU0>(converted->getConvertedMatrix(), w));
606 converted->setUnderlyingPreconditioner(adapted);
610 F::addCreator( "GPUJAC", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
611 const double w = prm.get< double>( "relaxation", 1.0);
612 using field_type = typename V::field_type;
615 return std::make_shared<gpuistl::PreconditionerAdapter<V, V, GPUJac>>(
616 std::make_shared<GPUJac>(op.getmat(), w));
619 F::addCreator( "OPMGPUILU0", []( const O& op, [[maybe_unused]] const P& prm, const std::function<V()>&, std::size_t) {
620 const bool split_matrix = prm.get< bool>( "split_matrix", true);
621 const bool tune_gpu_kernels = prm.get< bool>( "tune_gpu_kernels", true);
622 using field_type = typename V::field_type;
625 return std::make_shared<gpuistl::PreconditionerAdapter<V, V, GPUILU0>>(std::make_shared<GPUILU0>(op.getmat(), split_matrix, tune_gpu_kernels));
628 F::addCreator( "GPUDILU", []( const O& op, [[maybe_unused]] const P& prm, const std::function<V()>&, std::size_t) {
629 const bool split_matrix = prm.get< bool>( "split_matrix", true);
630 const bool tune_gpu_kernels = prm.get< bool>( "tune_gpu_kernels", true);
631 using field_type = typename V::field_type;
633 return std::make_shared<gpuistl::PreconditionerAdapter<V, V, GPUDILU>>(std::make_shared<GPUDILU>(op.getmat(), split_matrix, tune_gpu_kernels));
636 F::addCreator( "GPUDILUFloat", []( const O& op, [[maybe_unused]] const P& prm, const std::function<V()>&, std::size_t) {
637 const bool split_matrix = prm.get< bool>( "split_matrix", true);
638 const bool tune_gpu_kernels = prm.get< bool>( "tune_gpu_kernels", true);
639 using block_type = typename V::block_type;
640 using VTo = Dune::BlockVector<Dune::FieldVector<float, block_type::dimension>>;
641 using matrix_type_to = typename Dune::BCRSMatrix<Dune::FieldMatrix<float, block_type::dimension, block_type::dimension>>;
645 auto converted = std::make_shared<Converter>(op.getmat());
646 auto adapted = std::make_shared<Adapter>(std::make_shared<GpuDILU>(converted->getConvertedMatrix(), split_matrix, tune_gpu_kernels));
647 converted->setUnderlyingPreconditioner(adapted);
654template < class Operator, class Comm>
655PreconditionerFactory<Operator, Comm>::PreconditionerFactory()
660template < class Operator, class Comm>
661PreconditionerFactory<Operator, Comm>&
662PreconditionerFactory<Operator, Comm>::instance()
664 static PreconditionerFactory singleton;
668template < class Operator, class Comm>
670PreconditionerFactory<Operator, Comm>::doCreate( const Operator& op,
671 const PropertyTree& prm,
672 const std::function<Vector()> weightsCalculator,
673 std::size_t pressureIndex)
679 const std::string& type = prm.get<std::string>( "type", "ParOverILU0");
680 auto it = creators_.find(type);
681 if (it == creators_.end()) {
682 std::ostringstream msg;
683 msg << "Preconditioner type " << type << " is not registered in the factory. Available types are: ";
684 for ( const auto& prec : creators_) {
685 msg << prec.first << ' ';
688 OPM_THROW(std::invalid_argument, msg.str());
690 return it->second(op, prm, weightsCalculator, pressureIndex);
693template < class Operator, class Comm>
695PreconditionerFactory<Operator, Comm>::doCreate( const Operator& op,
696 const PropertyTree& prm,
697 const std::function<Vector()> weightsCalculator,
698 std::size_t pressureIndex,
705 const std::string& type = prm.get<std::string>( "type", "ParOverILU0");
706 auto it = parallel_creators_.find(type);
707 if (it == parallel_creators_.end()) {
708 std::ostringstream msg;
709 msg << "Parallel preconditioner type " << type << " is not registered in the factory. Available types are: ";
710 for ( const auto& prec : parallel_creators_) {
711 msg << prec.first << ' ';
714 OPM_THROW(std::invalid_argument, msg.str());
716 return it->second(op, prm, weightsCalculator, pressureIndex, comm);
719template < class Operator, class Comm>
721PreconditionerFactory<Operator, Comm>::doAddCreator( const std::string& type, Creator c)
726template < class Operator, class Comm>
728PreconditionerFactory<Operator, Comm>::doAddCreator( const std::string& type, ParCreator c)
730 parallel_creators_[type] = c;
733template < class Operator, class Comm>
737 const std::function< Vector()>& weightsCalculator,
738 std::size_t pressureIndex)
740 return instance().doCreate(op, prm, weightsCalculator, pressureIndex);
743template < class Operator, class Comm>
747 const std::function< Vector()>& weightsCalculator,
749 std::size_t pressureIndex)
751 return instance().doCreate(op, prm, weightsCalculator, pressureIndex, comm);
755template < class Operator, class Comm>
760 std::size_t pressureIndex)
762 return instance().doCreate(op, prm, std::function< Vector()>(), pressureIndex, comm);
765template < class Operator, class Comm>
769 instance().doAddCreator(type, creator);
772template < class Operator, class Comm>
776 instance().doAddCreator(type, creator);
779using CommSeq = Dune::Amg::SequentialInformation;
781template< class Scalar, int Dim>
782using OpFSeq = Dune::MatrixAdapter<Dune::BCRSMatrix<Dune::FieldMatrix<Scalar, Dim, Dim>>,
783 Dune::BlockVector<Dune::FieldVector<Scalar, Dim>>,
784 Dune::BlockVector<Dune::FieldVector<Scalar, Dim>>>;
785template< class Scalar, int Dim>
786using OpBSeq = Dune::MatrixAdapter<Dune::BCRSMatrix<MatrixBlock<Scalar, Dim, Dim>>,
787 Dune::BlockVector<Dune::FieldVector<Scalar, Dim>>,
788 Dune::BlockVector<Dune::FieldVector<Scalar, Dim>>>;
790template< class Scalar, int Dim, bool overlap>
792 Dune::BlockVector<Dune::FieldVector<Scalar, Dim>>,
793 Dune::BlockVector<Dune::FieldVector<Scalar, Dim>>,
796template< class Scalar, int Dim, bool overlap>
798 Dune::BlockVector<Dune::FieldVector<Scalar, Dim>>,
799 Dune::BlockVector<Dune::FieldVector<Scalar, Dim>>,
803using CommPar = Dune::OwnerOverlapCopyCommunication<int, int>;
805template< class Scalar, int Dim>
806using OpFPar = Dune::OverlappingSchwarzOperator<Dune::BCRSMatrix<Dune::FieldMatrix<Scalar, Dim, Dim>>,
807 Dune::BlockVector<Dune::FieldVector<Scalar, Dim>>,
808 Dune::BlockVector<Dune::FieldVector<Scalar, Dim>>,
811template< class Scalar, int Dim>
812using OpBPar = Dune::OverlappingSchwarzOperator<Dune::BCRSMatrix<MatrixBlock<Scalar, Dim, Dim>>,
813 Dune::BlockVector<Dune::FieldVector<Scalar, Dim>>,
814 Dune::BlockVector<Dune::FieldVector<Scalar, Dim>>,
816template< class Scalar, int Dim>
818 Dune::BlockVector<Dune::FieldVector<Scalar,Dim>>,
819 Dune::BlockVector<Dune::FieldVector<Scalar,Dim>>,
822template< class Scalar, int Dim>
824 Dune::BlockVector<Dune::FieldVector<Scalar,Dim>>,
825 Dune::BlockVector<Dune::FieldVector<Scalar,Dim>>,
828#define INSTANTIATE_PF_PAR(T,Dim) \
829 template class PreconditionerFactory<OpBSeq<T,Dim>, CommPar>; \
830 template class PreconditionerFactory<OpFPar<T,Dim>, CommPar>; \
831 template class PreconditionerFactory<OpBPar<T,Dim>, CommPar>; \
832 template class PreconditionerFactory<OpGLFPar<T,Dim>, CommPar>; \
833 template class PreconditionerFactory<OpGLBPar<T,Dim>, CommPar>; \
834 template class PreconditionerFactory<OpW<T,Dim, false>, CommPar>; \
835 template class PreconditionerFactory<OpWG<T,Dim, true>, CommPar>; \
836 template class PreconditionerFactory<OpBPar<T,Dim>, CommSeq>; \
837 template class PreconditionerFactory<OpGLBPar<T,Dim>, CommSeq>;
840#define INSTANTIATE_PF_SEQ(T,Dim) \
841 template class PreconditionerFactory<OpFSeq<T,Dim>, CommSeq>; \
842 template class PreconditionerFactory<OpBSeq<T,Dim>, CommSeq>; \
843 template class PreconditionerFactory<OpW<T,Dim, false>, CommSeq>; \
844 template class PreconditionerFactory<OpWG<T,Dim, true>, CommSeq>;
847#define INSTANTIATE_PF(T,Dim) \
848 INSTANTIATE_PF_PAR(T,Dim) \
849 INSTANTIATE_PF_SEQ(T,Dim)
851#define INSTANTIATE_PF(T,Dim) INSTANTIATE_PF_SEQ(T,Dim)
Dune::OwnerOverlapCopyCommunication< int, int > Comm Definition: FlexibleSolver_impl.hpp:285
Parallel algebraic multigrid based on agglomeration. Definition: amgcpr.hh:88
Definition: PreconditionerWithUpdate.hpp:43
The OpenMP thread parallelized DILU preconditioner. Definition: DILU.hpp:53
Dune linear operator that assumes ghost rows are ordered after interior rows. Avoids some computation... Definition: WellOperators.hpp:340
A two-step version of an overlapping Schwarz preconditioner using one step ILU0 as. Definition: ParallelOverlappingILU0.hpp:131
Definition: PreconditionerFactory.hpp:64
static PrecPtr create(const Operator &op, const PropertyTree &prm, const std::function< Vector()> &weightsCalculator={}, std::size_t pressureIndex=std::numeric_limits< std::size_t >::max()) Definition: PreconditionerFactory_impl.hpp:735
std::function< PrecPtr(const Operator &, const PropertyTree &, const std::function< Vector()> &, std::size_t, const Comm &)> ParCreator Definition: PreconditionerFactory.hpp:77
typename Operator::domain_type Vector Definition: PreconditionerFactory.hpp:68
std::function< PrecPtr(const Operator &, const PropertyTree &, const std::function< Vector()> &, std::size_t)> Creator The type of creator functions passed to addCreator(). Definition: PreconditionerFactory.hpp:75
static void addCreator(const std::string &type, Creator creator) Definition: PreconditionerFactory_impl.hpp:767
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
Definition: PropertyTree.hpp:37
T get(const std::string &key) const
Adapter to combine a matrix and another linear operator into a combined linear operator. Definition: WellOperators.hpp:237
Adapter to combine a matrix and another linear operator into a combined linear operator. Definition: WellOperators.hpp:143
DILU preconditioner on the GPU. Definition: GpuDILU.hpp:44
Jacobi preconditioner on the GPU. Definition: GpuJac.hpp:47
ILU0 preconditioner on the GPU. Definition: OpmGpuILU0.hpp:46
Makes a CUDA preconditioner available to a CPU simulator. Definition: PreconditionerAdapter.hpp:43
Converts the field type (eg. double to float) to benchmark single precision preconditioners. Definition: PreconditionerConvertFieldTypeAdapter.hpp:86
Definition: fvbaseprimaryvariables.hh:141
Definition: blackoilboundaryratevector.hh:37
MILU_VARIANT Definition: MILU.hpp:34
@ ILU Do not perform modified ILU.
Dune::MatrixAdapter< Dune::BCRSMatrix< MatrixBlock< Scalar, Dim, Dim > >, Dune::BlockVector< Dune::FieldVector< Scalar, Dim > >, Dune::BlockVector< Dune::FieldVector< Scalar, Dim > > > OpBSeq Definition: PreconditionerFactory_impl.hpp:788
Dune::OverlappingSchwarzOperator< Dune::BCRSMatrix< MatrixBlock< Scalar, Dim, Dim > >, Dune::BlockVector< Dune::FieldVector< Scalar, Dim > >, Dune::BlockVector< Dune::FieldVector< Scalar, Dim > >, CommPar > OpBPar Definition: PreconditionerFactory_impl.hpp:815
Dune::MatrixAdapter< Dune::BCRSMatrix< Dune::FieldMatrix< Scalar, Dim, Dim > >, Dune::BlockVector< Dune::FieldVector< Scalar, Dim > >, Dune::BlockVector< Dune::FieldVector< Scalar, Dim > > > OpFSeq Definition: PreconditionerFactory_impl.hpp:784
auto setUseFixedOrder(C criterion, bool booleanValue) -> decltype(criterion.setUseFixedOrder(booleanValue)) Definition: PreconditionerFactory_impl.hpp:94
Dune::Amg::SequentialInformation CommSeq Definition: PreconditionerFactory_impl.hpp:779
MILU_VARIANT convertString2Milu(const std::string &milu)
Dune::OverlappingSchwarzOperator< Dune::BCRSMatrix< Dune::FieldMatrix< Scalar, Dim, Dim > >, Dune::BlockVector< Dune::FieldVector< Scalar, Dim > >, Dune::BlockVector< Dune::FieldVector< Scalar, Dim > >, CommPar > OpFPar Definition: PreconditionerFactory_impl.hpp:809
Dune::OwnerOverlapCopyCommunication< int, int > CommPar Definition: PreconditionerFactory_impl.hpp:803
Definition: PreconditionerFactory.hpp:43
Dune::Amg::CoarsenCriterion< CriterionBase > Criterion Definition: PreconditionerFactory.hpp:47
static Criterion criterion(const PropertyTree &prm) Definition: PreconditionerFactory_impl.hpp:106
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: PreconditionerFactory_impl.hpp:133
static auto args(const PropertyTree &prm) Definition: PreconditionerFactory_impl.hpp:74
Definition: PreconditionerFactory_impl.hpp:57
static auto args(const PropertyTree &prm) Definition: PreconditionerFactory_impl.hpp:58
Definition: PreconditionerFactory_impl.hpp:150
static std::size_t interiorIfGhostLast(const Comm &comm) Definition: PreconditionerFactory_impl.hpp:401
static PreconditionerFactory< Operator, Comm >::PrecPtr createParILU(const Operator &op, const PropertyTree &prm, const Comm &comm, const int ilulevel) Definition: PreconditionerFactory_impl.hpp:377
static void add() Definition: PreconditionerFactory_impl.hpp:151
|