Go to the documentation of this file.
21#ifndef OPM_STANDARDPRECONDITIONERS_MPI_HEADER
22#define OPM_STANDARDPRECONDITIONERS_MPI_HEADER
26#include <opm/simulators/linalg/gpuistl_hip/PreconditionerCPUMatrixToGPUMatrix.hpp>
36#if HAVE_AVX2_EXTENSION
43template < class Smoother>
48 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
49 SmootherArgs smootherArgs;
50 smootherArgs.iterations = prm. get< int>( "iterations", 1);
54 smootherArgs.relaxationFactor = prm. get< double>( "relaxation", 1.0);
59template < class M, class V, class C>
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);
71 smootherArgs.setMilu(milu);
75 smootherArgs.relaxationFactor = prm. get< double>( "relaxation", 1.0);
82auto setUseFixedOrder(C& criterion, bool booleanValue) -> decltype(criterion.setUseFixedOrder(booleanValue))
84 return criterion.setUseFixedOrder(booleanValue);
92template < class Operator, class Comm, class Matrix, class Vector>
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));
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));
118template < class Operator, class Comm, class Matrix, class Vector>
119template < class Smoother>
125 auto crit = criterion(prm);
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));
133 return std::make_shared<Type>(op, crit, sargs);
137template < class Operator, class Comm, typename = void>
142 using namespace Dune;
146 using M = typename F::Matrix;
147 using V = typename F::Vector;
149 F::addCreator( "ilu0", []( const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
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));
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));
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);
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());
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");
177 return wrapBlockPreconditioner<MixedPreconditioner<M,V,V>>(comm, op.getmat());
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");
186 return wrapBlockPreconditioner<MixedPreconditioner<M,V,V>>(comm, op.getmat(), true);
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);
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);
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);
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);
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");
221 std::ranges::transform(smoother, smoother.begin(), ::tolower);
223 if (smoother == "ilu0" || smoother == "paroverilu0") {
227 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
229 } else if (smoother == "dilu") {
231 using Smoother = Dune::BlockPreconditioner<V, V, C, SeqSmoother>;
232 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
235 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
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;
243 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
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;
251 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
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;
259 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
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;
267 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
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;
275 PrecPtr prec = std::make_shared<Dune::Amg::AMGCPR<O, V, Smoother, C>>(op, crit, sargs, comm);
278 OPM_THROW(std::invalid_argument, "Properties: No smoother with name " + smoother + ".");
282 if constexpr (M::block_type::rows == 1 && M::block_type::cols == 1
283 && std::is_same_v<HYPRE_Real, typename V::field_type>) {
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);
296 const std::function<V()> weightsCalculator,
297 std::size_t pressureIndex,
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");
304 using Scalar = typename V::field_type;
306 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy, Comm>>(
307 op, prm, weightsCalculator, pressureIndex, comm);
309 F::addCreator( "cprt",
312 const std::function<V()> weightsCalculator,
313 std::size_t pressureIndex,
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");
320 using Scalar = typename V::field_type;
322 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy, Comm>>(
323 op, prm, weightsCalculator, pressureIndex, comm);
331 if constexpr (std::is_same_v<O, WellModelGhostLastMatrixAdapter<M, V, V, true>>) {
332 F::addCreator( "cprw",
335 const std::function<V()> weightsCalculator,
336 std::size_t pressureIndex,
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");
343 using Scalar = typename V::field_type;
345 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy, Comm>>(
346 op, prm, weightsCalculator, pressureIndex, comm);
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::
361 auto gpuILU0 = std::make_shared<GpuILU0>(op.getmat(), w);
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);
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;
377 auto gpuJac = std::make_shared<MatrixOwner>(op.getmat(), w);
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);
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;
396 auto gpuDILU = std::make_shared<MatrixOwner>(op.getmat(), op.getmat(), split_matrix, tune_gpu_kernels, mixed_precision_scheme, reorder);
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);
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;
415 auto gpuilu0 = std::make_shared<MatrixOwner>(op.getmat(), op.getmat(), split_matrix, tune_gpu_kernels, mixed_precision_scheme);
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);
429 using M = typename F::Matrix;
430 using V = typename F::Vector;
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);
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);
442 return std::make_shared<ParallelOverlappingILU0<M, V, V, Comm>>(
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())) {
459 highest_interior_index = std::max(highest_interior_index, ind.local().local());
462 if (highest_interior_index + 1 == interior_count) {
463 return interior_count;
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
|