2022-08-17 01:23:01 -05:00
/*
Copyright 2009 , 2010 SINTEF ICT , Applied Mathematics .
Copyright 2019 SINTEF Digital , Mathematics and Cybernetics .
This file is part of the Open Porous Media project ( OPM ) .
OPM is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
OPM is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with OPM . If not , see < http : //www.gnu.org/licenses/>.
*/
2023-07-24 05:28:08 -05:00
# include <opm/common/ErrorMacros.hpp>
# include <opm/common/TimingMacros.hpp>
2022-08-17 01:23:01 -05:00
# include <opm/simulators/linalg/PreconditionerFactory.hpp>
2023-12-20 03:00:06 -06:00
# include <opm/simulators/linalg/DILU.hpp>
# include <opm/simulators/linalg/ExtraSmoothers.hpp>
2022-08-17 01:23:01 -05:00
# include <opm/simulators/linalg/FlexibleSolver.hpp>
# include <opm/simulators/linalg/OwningBlockPreconditioner.hpp>
# include <opm/simulators/linalg/OwningTwoLevelPreconditioner.hpp>
# include <opm/simulators/linalg/ParallelOverlappingILU0.hpp>
# include <opm/simulators/linalg/PressureBhpTransferPolicy.hpp>
# include <opm/simulators/linalg/PressureTransferPolicy.hpp>
# include <opm/simulators/linalg/PropertyTree.hpp>
# include <opm/simulators/linalg/WellOperators.hpp>
2023-12-20 03:00:06 -06:00
# include <opm/simulators/linalg/amgcpr.hh>
# include <opm/simulators/linalg/ilufirstelement.hh>
# include <opm/simulators/linalg/matrixblock.hh>
2022-08-17 01:23:01 -05:00
2023-09-27 08:47:05 -05:00
# include <dune/common/unused.hh>
2022-08-17 01:23:01 -05:00
# include <dune/istl/owneroverlapcopy.hh>
# include <dune/istl/paamg/amg.hh>
# include <dune/istl/paamg/fastamg.hh>
2023-12-20 03:00:06 -06:00
# include <dune/istl/paamg/kamg.hh>
# include <dune/istl/preconditioners.hh>
2022-08-17 01:23:01 -05:00
2023-03-31 07:48:57 -05:00
# include <config.h>
2023-05-31 09:28:51 -05:00
2024-03-11 09:30:51 -05:00
// Include all cuistl/GPU preconditioners inside of this headerfile
# include <opm/simulators/linalg/PreconditionerFactoryGPUIncludeWrapper.hpp>
2023-03-31 07:48:57 -05:00
2024-04-13 08:18:32 -05:00
namespace Opm {
2023-12-20 03:00:06 -06:00
template < class Smoother >
2024-04-13 08:18:32 -05:00
struct AMGSmootherArgsHelper
{
2022-08-17 01:23:01 -05:00
static auto args ( const PropertyTree & prm )
{
using SmootherArgs = typename Dune : : Amg : : SmootherTraits < Smoother > : : Arguments ;
SmootherArgs smootherArgs ;
smootherArgs . iterations = prm . get < int > ( " iterations " , 1 ) ;
// smootherArgs.overlap=SmootherArgs::vertex;
// smootherArgs.overlap=SmootherArgs::none;
// smootherArgs.overlap=SmootherArgs::aggregate;
smootherArgs . relaxationFactor = prm . get < double > ( " relaxation " , 1.0 ) ;
return smootherArgs ;
}
} ;
2023-12-20 03:00:06 -06:00
template < class M , class V , class C >
2024-04-13 08:18:32 -05:00
struct AMGSmootherArgsHelper < ParallelOverlappingILU0 < M , V , V , C > >
{
2022-08-17 01:23:01 -05:00
static auto args ( const PropertyTree & prm )
{
2024-04-13 08:18:32 -05:00
using Smoother = ParallelOverlappingILU0 < M , V , V , C > ;
2022-08-17 01:23:01 -05:00
using SmootherArgs = typename Dune : : Amg : : SmootherTraits < Smoother > : : Arguments ;
SmootherArgs smootherArgs ;
smootherArgs . iterations = prm . get < int > ( " iterations " , 1 ) ;
const int iluwitdh = prm . get < int > ( " iluwidth " , 0 ) ;
smootherArgs . setN ( iluwitdh ) ;
const MILU_VARIANT milu = convertString2Milu ( prm . get < std : : string > ( " milutype " , std : : string ( " ilu " ) ) ) ;
smootherArgs . setMilu ( milu ) ;
// smootherArgs.overlap=SmootherArgs::vertex;
// smootherArgs.overlap=SmootherArgs::none;
// smootherArgs.overlap=SmootherArgs::aggregate;
smootherArgs . relaxationFactor = prm . get < double > ( " relaxation " , 1.0 ) ;
return smootherArgs ;
}
} ;
2024-01-26 07:27:12 -06:00
// trailing return type with decltype used for detecting existence of setUseFixedOrder member function by overloading the setUseFixedOrder function
2024-01-24 01:27:56 -06:00
template < typename C >
auto setUseFixedOrder ( C criterion , bool booleanValue ) - > decltype ( criterion . setUseFixedOrder ( booleanValue ) )
{
return criterion . setUseFixedOrder ( booleanValue ) ; // Set flag to ensure that the matrices in the AMG hierarchy are constructed with deterministic indices.
}
template < typename C >
void setUseFixedOrder ( C , . . . )
{
// do nothing, since the function setUseFixedOrder does not exist yet
}
2022-08-17 01:23:01 -05:00
template < class Operator , class Comm , class Matrix , class Vector >
typename AMGHelper < Operator , Comm , Matrix , Vector > : : Criterion
2023-12-20 03:00:06 -06:00
AMGHelper < Operator , Comm , Matrix , Vector > : : criterion ( const PropertyTree & prm )
2022-08-17 01:23:01 -05:00
{
Criterion criterion ( 15 , prm . get < int > ( " coarsenTarget " , 1200 ) ) ;
criterion . setDefaultValuesIsotropic ( 2 ) ;
criterion . setAlpha ( prm . get < double > ( " alpha " , 0.33 ) ) ;
criterion . setBeta ( prm . get < double > ( " beta " , 1e-5 ) ) ;
criterion . setMaxLevel ( prm . get < int > ( " maxlevel " , 15 ) ) ;
criterion . setSkipIsolated ( prm . get < bool > ( " skip_isolated " , false ) ) ;
criterion . setNoPreSmoothSteps ( prm . get < int > ( " pre_smooth " , 1 ) ) ;
criterion . setNoPostSmoothSteps ( prm . get < int > ( " post_smooth " , 1 ) ) ;
criterion . setDebugLevel ( prm . get < int > ( " verbosity " , 0 ) ) ;
// As the default we request to accumulate data to 1 process always as our matrix
// graph might be unsymmetric and hence not supported by the PTScotch/ParMetis
// calls in DUNE. Accumulating to 1 skips PTScotch/ParMetis
criterion . setAccumulate ( static_cast < Dune : : Amg : : AccumulationMode > ( prm . get < int > ( " accumulate " , 1 ) ) ) ;
criterion . setProlongationDampingFactor ( prm . get < double > ( " prolongationdamping " , 1.6 ) ) ;
criterion . setMaxDistance ( prm . get < int > ( " maxdistance " , 2 ) ) ;
criterion . setMaxConnectivity ( prm . get < int > ( " maxconnectivity " , 15 ) ) ;
criterion . setMaxAggregateSize ( prm . get < int > ( " maxaggsize " , 6 ) ) ;
criterion . setMinAggregateSize ( prm . get < int > ( " minaggsize " , 4 ) ) ;
2024-01-24 01:27:56 -06:00
setUseFixedOrder ( criterion , true ) ; // If possible, set flag to ensure that the matrices in the AMG hierarchy are constructed with deterministic indices.
2022-08-17 01:23:01 -05:00
return criterion ;
}
template < class Operator , class Comm , class Matrix , class Vector >
template < class Smoother >
typename AMGHelper < Operator , Comm , Matrix , Vector > : : PrecPtr
2023-12-20 03:00:06 -06:00
AMGHelper < Operator , Comm , Matrix , Vector > : : makeAmgPreconditioner ( const Operator & op ,
const PropertyTree & prm ,
bool useKamg )
2022-08-17 01:23:01 -05:00
{
auto crit = criterion ( prm ) ;
auto sargs = AMGSmootherArgsHelper < Smoother > : : args ( prm ) ;
if ( useKamg ) {
using Type = Dune : : DummyUpdatePreconditioner < Dune : : Amg : : KAMG < Operator , Vector , Smoother > > ;
2023-12-20 03:00:06 -06:00
return std : : make_shared < Type > (
op , crit , sargs , prm . get < std : : size_t > ( " max_krylov " , 1 ) , prm . get < double > ( " min_reduction " , 1e-1 ) ) ;
2022-08-17 01:23:01 -05:00
} else {
using Type = Dune : : Amg : : AMGCPR < Operator , Vector , Smoother > ;
return std : : make_shared < Type > ( op , crit , sargs ) ;
}
}
2023-12-20 03:00:06 -06:00
template < class Operator , class Comm >
struct StandardPreconditioners {
2022-08-17 01:23:01 -05:00
static void add ( )
{
using namespace Dune ;
using O = Operator ;
using C = Comm ;
2023-12-20 03:00:06 -06:00
using F = PreconditionerFactory < O , C > ;
2022-08-17 01:23:01 -05:00
using M = typename F : : Matrix ;
using V = typename F : : Vector ;
using P = PropertyTree ;
F : : addCreator ( " ILU0 " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t , const C & comm ) {
2023-12-20 03:00:06 -06:00
return createParILU ( op , prm , comm , 0 ) ;
2022-08-17 01:23:01 -05:00
} ) ;
2023-12-20 03:00:06 -06:00
F : : addCreator ( " ParOverILU0 " ,
[ ] ( 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 ) ) ;
} ) ;
2022-08-17 01:23:01 -05:00
F : : addCreator ( " ILUn " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t , const C & comm ) {
2023-12-20 03:00:06 -06:00
return createParILU ( op , prm , comm , prm . get < int > ( " ilulevel " , 0 ) ) ;
2022-08-17 01:23:01 -05:00
} ) ;
2024-04-15 09:06:37 -05:00
F : : addCreator ( " DuneILU " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t , const C & comm ) {
const int n = prm . get < int > ( " ilulevel " , 0 ) ;
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
const bool resort = prm . get < bool > ( " resort " , false ) ;
2024-04-16 08:39:17 -05:00
return wrapBlockPreconditioner < RebuildOnUpdatePreconditioner < Dune : : SeqILU < M , V , V > > > (
2024-04-15 09:06:37 -05:00
comm , op . getmat ( ) , n , w , resort ) ;
} ) ;
2023-09-27 08:47:05 -05:00
F : : addCreator ( " DILU " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t , const C & comm ) {
2023-12-20 03:00:06 -06:00
DUNE_UNUSED_PARAMETER ( prm ) ;
return wrapBlockPreconditioner < MultithreadDILU < M , V , V > > ( comm , op . getmat ( ) ) ;
2023-09-27 08:47:05 -05:00
} ) ;
2023-12-20 03:00:06 -06:00
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 ) ;
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
return wrapBlockPreconditioner < DummyUpdatePreconditioner < SeqJac < M , V , V > > > ( comm , op . getmat ( ) , n , w ) ;
2022-08-17 01:23:01 -05:00
} ) ;
F : : addCreator ( " GS " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t , const C & comm ) {
2023-12-20 03:00:06 -06:00
const int n = prm . get < int > ( " repeats " , 1 ) ;
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
return wrapBlockPreconditioner < DummyUpdatePreconditioner < SeqGS < M , V , V > > > ( comm , op . getmat ( ) , n , w ) ;
2022-08-17 01:23:01 -05:00
} ) ;
F : : addCreator ( " SOR " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t , const C & comm ) {
2023-12-20 03:00:06 -06:00
const int n = prm . get < int > ( " repeats " , 1 ) ;
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
return wrapBlockPreconditioner < DummyUpdatePreconditioner < SeqSOR < M , V , V > > > ( comm , op . getmat ( ) , n , w ) ;
2022-08-17 01:23:01 -05:00
} ) ;
F : : addCreator ( " SSOR " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t , const C & comm ) {
2023-12-20 03:00:06 -06:00
const int n = prm . get < int > ( " repeats " , 1 ) ;
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
return wrapBlockPreconditioner < DummyUpdatePreconditioner < SeqSSOR < M , V , V > > > ( comm , op . getmat ( ) , n , w ) ;
2022-08-17 01:23:01 -05:00
} ) ;
// Only add AMG preconditioners to the factory if the operator
// is the overlapping schwarz operator. This could be extended
// later, but at this point no other operators are compatible
// with the AMG hierarchy construction.
2022-11-03 06:04:54 -05:00
if constexpr ( std : : is_same_v < O , Dune : : OverlappingSchwarzOperator < M , V , V , C > > | |
std : : is_same_v < O , Opm : : GhostLastMatrixAdapter < M , V , V , C > > ) {
2023-12-20 03:00:06 -06:00
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 " ) ;
// TODO: merge this with ILUn, and possibly simplify the factory to only work with ILU?
if ( smoother = = " ILU0 " | | smoother = = " ParOverILU0 " ) {
2024-04-13 08:18:32 -05:00
using Smoother = ParallelOverlappingILU0 < M , V , V , C > ;
2023-12-20 03:00:06 -06:00
auto crit = AMGHelper < O , C , M , V > : : criterion ( prm ) ;
auto sargs = AMGSmootherArgsHelper < Smoother > : : args ( prm ) ;
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 : : MultithreadDILU < 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 if ( smoother = = " Jac " ) {
using SeqSmoother = SeqJac < 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 if ( smoother = = " GS " ) {
using SeqSmoother = SeqGS < 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 if ( smoother = = " SOR " ) {
using SeqSmoother = SeqSOR < 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 if ( smoother = = " SSOR " ) {
using SeqSmoother = SeqSSOR < 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 if ( smoother = = " ILUn " ) {
using SeqSmoother = SeqILU < 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 + " . " ) ;
}
} ) ;
2022-08-17 01:23:01 -05:00
}
2023-12-20 03:00:06 -06:00
F : : addCreator ( " cpr " ,
[ ] ( const O & op ,
const P & prm ,
const std : : function < V ( ) > weightsCalculator ,
std : : size_t pressureIndex ,
const C & comm ) {
assert ( weightsCalculator ) ;
if ( pressureIndex = = std : : numeric_limits < std : : size_t > : : max ( ) ) {
OPM_THROW ( std : : logic_error ,
" Pressure index out of bounds. It needs to specified for CPR " ) ;
}
2024-04-13 08:18:32 -05:00
using Scalar = typename V : : field_type ;
using LevelTransferPolicy = PressureTransferPolicy < O , Comm , Scalar , false > ;
2023-12-20 03:00:06 -06:00
return std : : make_shared < OwningTwoLevelPreconditioner < O , V , LevelTransferPolicy , Comm > > (
op , prm , weightsCalculator , pressureIndex , comm ) ;
} ) ;
F : : addCreator ( " cprt " ,
[ ] ( const O & op ,
const P & prm ,
const std : : function < V ( ) > weightsCalculator ,
std : : size_t pressureIndex ,
const C & comm ) {
assert ( weightsCalculator ) ;
if ( pressureIndex = = std : : numeric_limits < std : : size_t > : : max ( ) ) {
OPM_THROW ( std : : logic_error ,
" Pressure index out of bounds. It needs to specified for CPR " ) ;
}
2024-04-13 08:18:32 -05:00
using Scalar = typename V : : field_type ;
using LevelTransferPolicy = PressureTransferPolicy < O , Comm , Scalar , true > ;
2023-12-20 03:00:06 -06:00
return std : : make_shared < OwningTwoLevelPreconditioner < O , V , LevelTransferPolicy , Comm > > (
op , prm , weightsCalculator , pressureIndex , comm ) ;
} ) ;
2022-08-17 01:23:01 -05:00
if constexpr ( std : : is_same_v < O , WellModelGhostLastMatrixAdapter < M , V , V , true > > ) {
2023-12-20 03:00:06 -06:00
F : : addCreator ( " cprw " ,
[ ] ( const O & op ,
const P & prm ,
const std : : function < V ( ) > weightsCalculator ,
std : : size_t pressureIndex ,
const C & comm ) {
assert ( weightsCalculator ) ;
if ( pressureIndex = = std : : numeric_limits < std : : size_t > : : max ( ) ) {
OPM_THROW ( std : : logic_error ,
" Pressure index out of bounds. It needs to specified for CPR " ) ;
}
2024-04-13 08:18:32 -05:00
using Scalar = typename V : : field_type ;
using LevelTransferPolicy = PressureBhpTransferPolicy < O , Comm , Scalar , false > ;
2023-12-20 03:00:06 -06:00
return std : : make_shared < OwningTwoLevelPreconditioner < O , V , LevelTransferPolicy , Comm > > (
op , prm , weightsCalculator , pressureIndex , comm ) ;
} ) ;
2022-08-17 01:23:01 -05:00
}
2023-05-31 09:28:51 -05:00
# if HAVE_CUDA
2024-08-22 08:07:53 -05:00
F : : addCreator ( " GPUILU0 " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t , const C & comm ) {
2023-05-31 09:28:51 -05:00
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
using field_type = typename V : : field_type ;
2024-08-22 08:07:53 -05:00
using GpuILU0 = typename gpuistl : :
2024-08-22 08:20:20 -05:00
GpuSeqILU0 < M , gpuistl : : GpuVector < field_type > , gpuistl : : GpuVector < field_type > > ;
2024-08-22 08:07:53 -05:00
auto gpuILU0 = std : : make_shared < GpuILU0 > ( op . getmat ( ) , w ) ;
2023-05-31 09:28:51 -05:00
2024-08-22 08:07:53 -05:00
auto adapted = std : : make_shared < gpuistl : : PreconditionerAdapter < V , V , GpuILU0 > > ( gpuILU0 ) ;
2024-08-22 06:58:35 -05:00
auto wrapped = std : : make_shared < gpuistl : : GpuBlockPreconditioner < V , V , Comm > > ( adapted , comm ) ;
2023-05-31 09:28:51 -05:00
return wrapped ;
} ) ;
2023-08-29 04:34:57 -05:00
2024-08-22 07:40:23 -05:00
F : : addCreator ( " GPUJAC " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t , const C & comm ) {
2023-08-29 04:34:57 -05:00
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
using field_type = typename V : : field_type ;
2024-08-22 07:40:23 -05:00
using GpuJac =
2024-08-22 08:20:20 -05:00
typename gpuistl : : GpuJac < M , gpuistl : : GpuVector < field_type > , gpuistl : : GpuVector < field_type > > ;
2024-08-22 07:40:23 -05:00
auto gpuJac = std : : make_shared < GpuJac > ( op . getmat ( ) , w ) ;
2023-08-29 04:34:57 -05:00
2024-08-22 07:40:23 -05:00
auto adapted = std : : make_shared < gpuistl : : PreconditionerAdapter < V , V , GpuJac > > ( gpuJac ) ;
2024-08-22 06:58:35 -05:00
auto wrapped = std : : make_shared < gpuistl : : GpuBlockPreconditioner < V , V , Comm > > ( adapted , comm ) ;
2023-08-29 04:34:57 -05:00
return wrapped ;
} ) ;
2023-11-22 07:29:43 -06:00
2024-08-22 07:40:23 -05:00
F : : addCreator ( " GPUDILU " , [ ] ( const O & op , [[maybe_unused]] const P & prm , const std : : function < V ( ) > & , std : : size_t , const C & comm ) {
2024-06-18 08:44:19 -05:00
const bool split_matrix = prm . get < bool > ( " split_matrix " , true ) ;
const bool tune_gpu_kernels = prm . get < bool > ( " tune_gpu_kernels " , true ) ;
2023-11-22 07:29:43 -06:00
using field_type = typename V : : field_type ;
2024-08-22 08:20:20 -05:00
using GpuDILU = typename gpuistl : : GpuDILU < M , gpuistl : : GpuVector < field_type > , gpuistl : : GpuVector < field_type > > ;
2024-08-22 07:40:23 -05:00
auto gpuDILU = std : : make_shared < GpuDILU > ( op . getmat ( ) , split_matrix , tune_gpu_kernels ) ;
2023-11-22 07:29:43 -06:00
2024-08-22 07:40:23 -05:00
auto adapted = std : : make_shared < gpuistl : : PreconditionerAdapter < V , V , GpuDILU > > ( gpuDILU ) ;
2024-08-22 06:58:35 -05:00
auto wrapped = std : : make_shared < gpuistl : : GpuBlockPreconditioner < V , V , Comm > > ( adapted , comm ) ;
2023-11-22 07:29:43 -06:00
return wrapped ;
} ) ;
2024-06-19 06:14:59 -05:00
F : : addCreator ( " OPMCUILU0 " , [ ] ( const O & op , [[maybe_unused]] const P & prm , const std : : function < V ( ) > & , std : : size_t , const C & comm ) {
const bool split_matrix = prm . get < bool > ( " split_matrix " , true ) ;
const bool tune_gpu_kernels = prm . get < bool > ( " tune_gpu_kernels " , true ) ;
using field_type = typename V : : field_type ;
2024-08-22 08:20:20 -05:00
using OpmCuILU0 = typename gpuistl : : OpmCuILU0 < M , gpuistl : : GpuVector < field_type > , gpuistl : : GpuVector < field_type > > ;
2024-06-19 06:14:59 -05:00
auto cuilu0 = std : : make_shared < OpmCuILU0 > ( op . getmat ( ) , split_matrix , tune_gpu_kernels ) ;
2024-08-22 06:52:50 -05:00
auto adapted = std : : make_shared < gpuistl : : PreconditionerAdapter < V , V , OpmCuILU0 > > ( cuilu0 ) ;
2024-08-22 06:58:35 -05:00
auto wrapped = std : : make_shared < gpuistl : : GpuBlockPreconditioner < V , V , Comm > > ( adapted , comm ) ;
2024-06-19 06:14:59 -05:00
return wrapped ;
} ) ;
2023-05-31 09:28:51 -05:00
# endif
2022-08-17 01:23:01 -05:00
}
2023-12-20 03:00:06 -06:00
static typename PreconditionerFactory < Operator , Comm > : : PrecPtr
2022-08-17 01:23:01 -05:00
createParILU ( const Operator & op , const PropertyTree & prm , const Comm & comm , const int ilulevel )
{
2023-12-20 03:00:06 -06:00
using F = PreconditionerFactory < Operator , Comm > ;
2022-08-17 01:23:01 -05:00
using M = typename F : : Matrix ;
using V = typename F : : Vector ;
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
const bool redblack = prm . get < bool > ( " redblack " , false ) ;
const bool reorder_spheres = prm . get < bool > ( " reorder_spheres " , false ) ;
// Already a parallel preconditioner. Need to pass comm, but no need to wrap it in a BlockPreconditioner.
if ( ilulevel = = 0 ) {
2023-08-15 02:32:10 -05:00
const std : : size_t num_interior = interiorIfGhostLast ( comm ) ;
2024-04-13 08:18:32 -05:00
return std : : make_shared < ParallelOverlappingILU0 < M , V , V , Comm > > (
op . getmat ( ) , comm , w , MILU_VARIANT : : ILU , num_interior , redblack , reorder_spheres ) ;
2022-08-17 01:23:01 -05:00
} else {
2024-04-13 08:18:32 -05:00
return std : : make_shared < ParallelOverlappingILU0 < M , V , V , Comm > > (
op . getmat ( ) , comm , ilulevel , w , MILU_VARIANT : : ILU , redblack , reorder_spheres ) ;
2022-08-17 01:23:01 -05:00
}
}
/// Helper method to determine if the local partitioning has the
/// K interior cells from [0, K-1] and ghost cells from [K, N-1].
/// Returns K if true, otherwise returns N. This is motivated by
2022-08-17 03:37:00 -05:00
/// usage in the ParallelOverlappingILU0 preconditioner.
2023-08-15 02:32:10 -05:00
static std : : size_t interiorIfGhostLast ( const Comm & comm )
2022-08-17 01:23:01 -05:00
{
2023-08-15 02:32:10 -05:00
std : : size_t interior_count = 0 ;
std : : size_t highest_interior_index = 0 ;
2022-08-17 01:23:01 -05:00
const auto & is = comm . indexSet ( ) ;
for ( const auto & ind : is ) {
if ( Comm : : OwnerSet : : contains ( ind . local ( ) . attribute ( ) ) ) {
+ + interior_count ;
highest_interior_index = std : : max ( highest_interior_index , ind . local ( ) . local ( ) ) ;
}
}
if ( highest_interior_index + 1 = = interior_count ) {
return interior_count ;
} else {
return is . size ( ) ;
}
}
} ;
2023-12-20 03:00:06 -06:00
template < class Operator >
struct StandardPreconditioners < Operator , Dune : : Amg : : SequentialInformation > {
2022-08-17 01:23:01 -05:00
static void add ( )
{
using namespace Dune ;
using O = Operator ;
using C = Dune : : Amg : : SequentialInformation ;
2023-12-20 03:00:06 -06:00
using F = PreconditionerFactory < O , C > ;
2022-08-17 01:23:01 -05:00
using M = typename F : : Matrix ;
using V = typename F : : Vector ;
using P = PropertyTree ;
F : : addCreator ( " ILU0 " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t ) {
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
2024-04-13 08:18:32 -05:00
return std : : make_shared < ParallelOverlappingILU0 < M , V , V , C > > (
op . getmat ( ) , 0 , w , MILU_VARIANT : : ILU ) ;
2022-08-17 01:23:01 -05:00
} ) ;
2023-11-27 09:49:07 -06:00
F : : addCreator ( " DuneILU " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t ) {
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
const int n = prm . get < int > ( " ilulevel " , 0 ) ;
const bool resort = prm . get < bool > ( " resort " , false ) ;
2024-04-16 08:39:17 -05:00
return getRebuildOnUpdateWrapper < Dune : : SeqILU < M , V , V > > ( op . getmat ( ) , n , w , resort ) ;
2023-11-27 09:49:07 -06:00
} ) ;
2022-08-17 01:23:01 -05:00
F : : addCreator ( " ParOverILU0 " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t ) {
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
const int n = prm . get < int > ( " ilulevel " , 0 ) ;
2024-04-13 08:18:32 -05:00
return std : : make_shared < ParallelOverlappingILU0 < M , V , V , C > > (
op . getmat ( ) , n , w , MILU_VARIANT : : ILU ) ;
2022-08-17 01:23:01 -05:00
} ) ;
F : : addCreator ( " ILUn " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t ) {
const int n = prm . get < int > ( " ilulevel " , 0 ) ;
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
2024-04-13 08:18:32 -05:00
return std : : make_shared < ParallelOverlappingILU0 < M , V , V , C > > (
op . getmat ( ) , n , w , MILU_VARIANT : : ILU ) ;
2022-08-17 01:23:01 -05:00
} ) ;
2023-09-27 08:47:05 -05:00
F : : addCreator ( " DILU " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t ) {
DUNE_UNUSED_PARAMETER ( prm ) ;
2023-10-18 08:44:58 -05:00
return std : : make_shared < MultithreadDILU < M , V , V > > ( op . getmat ( ) ) ;
2023-09-27 08:47:05 -05:00
} ) ;
2022-08-17 01:23:01 -05:00
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 ) ;
2023-12-20 02:55:27 -06:00
return getDummyUpdateWrapper < SeqJac < M , V , V > > ( op . getmat ( ) , n , w ) ;
2022-08-17 01:23:01 -05:00
} ) ;
F : : addCreator ( " GS " , [ ] ( 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 ) ;
2023-12-20 02:55:27 -06:00
return getDummyUpdateWrapper < SeqGS < M , V , V > > ( op . getmat ( ) , n , w ) ;
2022-08-17 01:23:01 -05:00
} ) ;
F : : addCreator ( " SOR " , [ ] ( 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 ) ;
2023-12-20 02:55:27 -06:00
return getDummyUpdateWrapper < SeqSOR < M , V , V > > ( op . getmat ( ) , n , w ) ;
2022-08-17 01:23:01 -05:00
} ) ;
F : : addCreator ( " SSOR " , [ ] ( 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 ) ;
2023-12-20 02:55:27 -06:00
return getDummyUpdateWrapper < SeqSSOR < M , V , V > > ( op . getmat ( ) , n , w ) ;
2022-08-17 01:23:01 -05:00
} ) ;
// Only add AMG preconditioners to the factory if the operator
// is an actual matrix operator.
if constexpr ( std : : is_same_v < O , Dune : : MatrixAdapter < M , V , V > > ) {
F : : addCreator ( " amg " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t ) {
const std : : string smoother = prm . get < std : : string > ( " smoother " , " ParOverILU0 " ) ;
if ( smoother = = " ILU0 " | | smoother = = " ParOverILU0 " ) {
using Smoother = SeqILU < M , V , V > ;
2023-12-20 03:00:06 -06:00
return AMGHelper < O , C , M , V > : : template makeAmgPreconditioner < Smoother > ( op , prm ) ;
2022-08-17 01:23:01 -05:00
} else if ( smoother = = " Jac " ) {
using Smoother = SeqJac < M , V , V > ;
2023-12-20 03:00:06 -06:00
return AMGHelper < O , C , M , V > : : template makeAmgPreconditioner < Smoother > ( op , prm ) ;
2023-11-28 03:49:11 -06:00
} else if ( smoother = = " GS " ) {
using Smoother = SeqGS < M , V , V > ;
2023-12-20 03:00:06 -06:00
return AMGHelper < O , C , M , V > : : template makeAmgPreconditioner < Smoother > ( op , prm ) ;
2023-09-27 08:47:05 -05:00
} else if ( smoother = = " DILU " ) {
2023-10-18 08:44:58 -05:00
using Smoother = MultithreadDILU < M , V , V > ;
2023-12-20 03:00:06 -06:00
return AMGHelper < O , C , M , V > : : template makeAmgPreconditioner < Smoother > ( op , prm ) ;
2022-08-17 01:23:01 -05:00
} else if ( smoother = = " SOR " ) {
using Smoother = SeqSOR < M , V , V > ;
2023-12-20 03:00:06 -06:00
return AMGHelper < O , C , M , V > : : template makeAmgPreconditioner < Smoother > ( op , prm ) ;
2022-08-17 01:23:01 -05:00
} else if ( smoother = = " SSOR " ) {
using Smoother = SeqSSOR < M , V , V > ;
2023-12-20 03:00:06 -06:00
return AMGHelper < O , C , M , V > : : template makeAmgPreconditioner < Smoother > ( op , prm ) ;
2022-08-17 01:23:01 -05:00
} else if ( smoother = = " ILUn " ) {
using Smoother = SeqILU < M , V , V > ;
2023-12-20 03:00:06 -06:00
return AMGHelper < O , C , M , V > : : template makeAmgPreconditioner < Smoother > ( op , prm ) ;
2022-08-17 01:23:01 -05:00
} else {
2023-12-20 03:00:06 -06:00
OPM_THROW ( std : : invalid_argument , " Properties: No smoother with name " + smoother + " . " ) ;
2022-08-17 01:23:01 -05:00
}
} ) ;
F : : addCreator ( " kamg " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t ) {
const std : : string smoother = prm . get < std : : string > ( " smoother " , " ParOverILU0 " ) ;
if ( smoother = = " ILU0 " | | smoother = = " ParOverILU0 " ) {
using Smoother = SeqILU < M , V , V > ;
2023-12-20 03:00:06 -06:00
return AMGHelper < O , C , M , V > : : template makeAmgPreconditioner < Smoother > ( op , prm , true ) ;
2022-08-17 01:23:01 -05:00
} else if ( smoother = = " Jac " ) {
using Smoother = SeqJac < M , V , V > ;
2023-12-20 03:00:06 -06:00
return AMGHelper < O , C , M , V > : : template makeAmgPreconditioner < Smoother > ( op , prm , true ) ;
2022-08-17 01:23:01 -05:00
} else if ( smoother = = " SOR " ) {
using Smoother = SeqSOR < M , V , V > ;
2023-12-20 03:00:06 -06:00
return AMGHelper < O , C , M , V > : : template makeAmgPreconditioner < Smoother > ( op , prm , true ) ;
2023-11-28 03:49:11 -06:00
} else if ( smoother = = " GS " ) {
using Smoother = SeqGS < M , V , V > ;
2023-12-20 03:00:06 -06:00
return AMGHelper < O , C , M , V > : : template makeAmgPreconditioner < Smoother > ( op , prm , true ) ;
2022-08-17 01:23:01 -05:00
} else if ( smoother = = " SSOR " ) {
using Smoother = SeqSSOR < M , V , V > ;
2023-12-20 03:00:06 -06:00
return AMGHelper < O , C , M , V > : : template makeAmgPreconditioner < Smoother > ( op , prm , true ) ;
2022-08-17 01:23:01 -05:00
} else if ( smoother = = " ILUn " ) {
using Smoother = SeqILU < M , V , V > ;
2023-12-20 03:00:06 -06:00
return AMGHelper < O , C , M , V > : : template makeAmgPreconditioner < Smoother > ( op , prm , true ) ;
2022-08-17 01:23:01 -05:00
} else {
2023-12-20 03:00:06 -06:00
OPM_THROW ( std : : invalid_argument , " Properties: No smoother with name " + smoother + " . " ) ;
2022-08-17 01:23:01 -05:00
}
} ) ;
F : : addCreator ( " famg " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t ) {
2024-04-13 08:18:32 -05:00
if constexpr ( std : : is_same_v < typename V : : field_type , float > ) {
OPM_THROW ( std : : logic_error , " famg requires UMFPack which is not available for floats " ) ;
return nullptr ;
} else {
auto crit = AMGHelper < O , C , M , V > : : criterion ( prm ) ;
Dune : : Amg : : Parameters parms ;
parms . setNoPreSmoothSteps ( 1 ) ;
parms . setNoPostSmoothSteps ( 1 ) ;
return getRebuildOnUpdateWrapper < Dune : : Amg : : FastAMG < O , V > > ( op , crit , parms ) ;
}
2022-08-17 01:23:01 -05:00
} ) ;
}
if constexpr ( std : : is_same_v < O , WellModelMatrixAdapter < M , V , V , false > > ) {
2023-12-20 03:00:06 -06:00
F : : addCreator (
" cprw " ,
[ ] ( const O & op , const P & prm , const std : : function < V ( ) > & weightsCalculator , std : : size_t pressureIndex ) {
if ( pressureIndex = = std : : numeric_limits < std : : size_t > : : max ( ) ) {
OPM_THROW ( std : : logic_error , " Pressure index out of bounds. It needs to specified for CPR " ) ;
}
2024-04-13 08:18:32 -05:00
using Scalar = typename V : : field_type ;
2023-12-20 03:00:06 -06:00
using LevelTransferPolicy
2024-04-13 08:18:32 -05:00
= PressureBhpTransferPolicy < O , Dune : : Amg : : SequentialInformation , Scalar , false > ;
2023-12-20 03:00:06 -06:00
return std : : make_shared < OwningTwoLevelPreconditioner < O , V , LevelTransferPolicy > > (
op , prm , weightsCalculator , pressureIndex ) ;
} ) ;
}
F : : addCreator (
" cpr " ,
[ ] ( const O & op , const P & prm , const std : : function < V ( ) > & weightsCalculator , std : : size_t pressureIndex ) {
2022-08-17 01:23:01 -05:00
if ( pressureIndex = = std : : numeric_limits < std : : size_t > : : max ( ) ) {
OPM_THROW ( std : : logic_error , " Pressure index out of bounds. It needs to specified for CPR " ) ;
}
2024-04-13 08:18:32 -05:00
using Scalar = typename V : : field_type ;
using LevelTransferPolicy = PressureTransferPolicy < O , Dune : : Amg : : SequentialInformation , Scalar , false > ;
2023-12-20 03:00:06 -06:00
return std : : make_shared < OwningTwoLevelPreconditioner < O , V , LevelTransferPolicy > > (
op , prm , weightsCalculator , pressureIndex ) ;
} ) ;
F : : addCreator (
" cprt " ,
[ ] ( const O & op , const P & prm , const std : : function < V ( ) > & weightsCalculator , std : : size_t pressureIndex ) {
if ( pressureIndex = = std : : numeric_limits < std : : size_t > : : max ( ) ) {
OPM_THROW ( std : : logic_error , " Pressure index out of bounds. It needs to specified for CPR " ) ;
}
2024-04-13 08:18:32 -05:00
using Scalar = typename V : : field_type ;
using LevelTransferPolicy = PressureTransferPolicy < O , Dune : : Amg : : SequentialInformation , Scalar , true > ;
2023-12-20 03:00:06 -06:00
return std : : make_shared < OwningTwoLevelPreconditioner < O , V , LevelTransferPolicy > > (
op , prm , weightsCalculator , pressureIndex ) ;
2022-08-17 01:23:01 -05:00
} ) ;
2023-03-31 07:48:57 -05:00
# if HAVE_CUDA
2024-08-22 08:07:53 -05:00
F : : addCreator ( " GPUILU0 " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t ) {
2023-03-31 07:48:57 -05:00
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
using field_type = typename V : : field_type ;
2024-08-23 07:42:37 -05:00
using GpuILU0 = typename gpuistl : :
2024-08-22 08:20:20 -05:00
GpuSeqILU0 < M , gpuistl : : GpuVector < field_type > , gpuistl : : GpuVector < field_type > > ;
2024-08-23 07:42:37 -05:00
return std : : make_shared < gpuistl : : PreconditionerAdapter < V , V , GpuILU0 > > (
std : : make_shared < GpuILU0 > ( op . getmat ( ) , w ) ) ;
2023-03-31 07:48:57 -05:00
} ) ;
2024-08-22 08:07:53 -05:00
F : : addCreator ( " GPUILU0Float " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t ) {
2023-03-31 07:48:57 -05:00
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
using block_type = typename V : : block_type ;
using VTo = Dune : : BlockVector < Dune : : FieldVector < float , block_type : : dimension > > ;
2023-12-20 03:00:06 -06:00
using matrix_type_to =
typename Dune : : BCRSMatrix < Dune : : FieldMatrix < float , block_type : : dimension , block_type : : dimension > > ;
2024-08-23 07:42:37 -05:00
using GpuILU0 = typename gpuistl : :
2024-08-22 08:20:20 -05:00
GpuSeqILU0 < matrix_type_to , gpuistl : : GpuVector < float > , gpuistl : : GpuVector < float > > ;
2024-08-23 07:42:37 -05:00
using Adapter = typename gpuistl : : PreconditionerAdapter < VTo , VTo , GpuILU0 > ;
2024-08-22 06:52:50 -05:00
using Converter = typename gpuistl : : PreconditionerConvertFieldTypeAdapter < Adapter , M , V , V > ;
2023-03-31 07:48:57 -05:00
auto converted = std : : make_shared < Converter > ( op . getmat ( ) ) ;
2024-08-23 07:42:37 -05:00
auto adapted = std : : make_shared < Adapter > ( std : : make_shared < GpuILU0 > ( converted - > getConvertedMatrix ( ) , w ) ) ;
2023-03-31 07:48:57 -05:00
converted - > setUnderlyingPreconditioner ( adapted ) ;
return converted ;
} ) ;
2023-08-29 04:34:57 -05:00
2024-08-22 07:40:23 -05:00
F : : addCreator ( " GPUJAC " , [ ] ( const O & op , const P & prm , const std : : function < V ( ) > & , std : : size_t ) {
2023-08-29 04:34:57 -05:00
const double w = prm . get < double > ( " relaxation " , 1.0 ) ;
using field_type = typename V : : field_type ;
2024-08-22 07:40:23 -05:00
using GPUJac =
2024-08-22 08:20:20 -05:00
typename gpuistl : : GpuJac < M , gpuistl : : GpuVector < field_type > , gpuistl : : GpuVector < field_type > > ;
2024-08-22 07:40:23 -05:00
return std : : make_shared < gpuistl : : PreconditionerAdapter < V , V , GPUJac > > (
std : : make_shared < GPUJac > ( op . getmat ( ) , w ) ) ;
2023-08-29 04:34:57 -05:00
} ) ;
2023-11-22 07:29:43 -06:00
2024-06-19 06:14:59 -05:00
F : : addCreator ( " OPMCUILU0 " , [ ] ( const O & op , [[maybe_unused]] const P & prm , const std : : function < V ( ) > & , std : : size_t ) {
const bool split_matrix = prm . get < bool > ( " split_matrix " , true ) ;
const bool tune_gpu_kernels = prm . get < bool > ( " tune_gpu_kernels " , true ) ;
using field_type = typename V : : field_type ;
2024-08-22 08:20:20 -05:00
using CUILU0 = typename gpuistl : : OpmCuILU0 < M , gpuistl : : GpuVector < field_type > , gpuistl : : GpuVector < field_type > > ;
2024-06-19 06:14:59 -05:00
2024-08-22 06:52:50 -05:00
return std : : make_shared < gpuistl : : PreconditionerAdapter < V , V , CUILU0 > > ( std : : make_shared < CUILU0 > ( op . getmat ( ) , split_matrix , tune_gpu_kernels ) ) ;
2024-06-19 06:14:59 -05:00
} ) ;
2024-08-22 07:40:23 -05:00
F : : addCreator ( " GPUDILU " , [ ] ( const O & op , [[maybe_unused]] const P & prm , const std : : function < V ( ) > & , std : : size_t ) {
2024-05-31 03:36:46 -05:00
const bool split_matrix = prm . get < bool > ( " split_matrix " , true ) ;
2024-06-18 08:44:19 -05:00
const bool tune_gpu_kernels = prm . get < bool > ( " tune_gpu_kernels " , true ) ;
2023-11-22 07:29:43 -06:00
using field_type = typename V : : field_type ;
2024-08-22 08:20:20 -05:00
using GPUDILU = typename gpuistl : : GpuDILU < M , gpuistl : : GpuVector < field_type > , gpuistl : : GpuVector < field_type > > ;
2024-08-22 07:40:23 -05:00
return std : : make_shared < gpuistl : : PreconditionerAdapter < V , V , GPUDILU > > ( std : : make_shared < GPUDILU > ( op . getmat ( ) , split_matrix , tune_gpu_kernels ) ) ;
2023-11-22 07:29:43 -06:00
} ) ;
2024-08-22 07:40:23 -05:00
F : : addCreator ( " GPUDILUFloat " , [ ] ( const O & op , [[maybe_unused]] const P & prm , const std : : function < V ( ) > & , std : : size_t ) {
2024-06-18 08:44:19 -05:00
const bool split_matrix = prm . get < bool > ( " split_matrix " , true ) ;
const bool tune_gpu_kernels = prm . get < bool > ( " tune_gpu_kernels " , true ) ;
2023-11-22 07:29:43 -06:00
using block_type = typename V : : block_type ;
using VTo = Dune : : BlockVector < Dune : : FieldVector < float , block_type : : dimension > > ;
using matrix_type_to = typename Dune : : BCRSMatrix < Dune : : FieldMatrix < float , block_type : : dimension , block_type : : dimension > > ;
2024-08-22 08:20:20 -05:00
using GpuDILU = typename gpuistl : : GpuDILU < matrix_type_to , gpuistl : : GpuVector < float > , gpuistl : : GpuVector < float > > ;
2024-08-22 07:28:33 -05:00
using Adapter = typename gpuistl : : PreconditionerAdapter < VTo , VTo , GpuDILU > ;
2024-08-22 06:52:50 -05:00
using Converter = typename gpuistl : : PreconditionerConvertFieldTypeAdapter < Adapter , M , V , V > ;
2023-11-22 07:29:43 -06:00
auto converted = std : : make_shared < Converter > ( op . getmat ( ) ) ;
2024-08-22 07:28:33 -05:00
auto adapted = std : : make_shared < Adapter > ( std : : make_shared < GpuDILU > ( converted - > getConvertedMatrix ( ) , split_matrix , tune_gpu_kernels ) ) ;
2023-11-22 07:29:43 -06:00
converted - > setUnderlyingPreconditioner ( adapted ) ;
return converted ;
} ) ;
2023-03-31 07:48:57 -05:00
# endif
2022-08-17 01:23:01 -05:00
}
} ;
template < class Operator , class Comm >
2023-12-20 03:00:06 -06:00
PreconditionerFactory < Operator , Comm > : : PreconditionerFactory ( )
2022-08-17 01:23:01 -05:00
{
}
template < class Operator , class Comm >
2023-12-20 03:00:06 -06:00
PreconditionerFactory < Operator , Comm > &
PreconditionerFactory < Operator , Comm > : : instance ( )
2022-08-17 01:23:01 -05:00
{
static PreconditionerFactory singleton ;
return singleton ;
}
template < class Operator , class Comm >
2023-12-20 03:00:06 -06:00
typename PreconditionerFactory < Operator , Comm > : : PrecPtr
PreconditionerFactory < Operator , Comm > : : doCreate ( const Operator & op ,
const PropertyTree & prm ,
const std : : function < Vector ( ) > weightsCalculator ,
std : : size_t pressureIndex )
2022-08-17 01:23:01 -05:00
{
if ( ! defAdded_ ) {
2023-12-20 03:00:06 -06:00
StandardPreconditioners < Operator , Comm > : : add ( ) ;
defAdded_ = true ;
2022-08-17 01:23:01 -05:00
}
const std : : string & type = prm . get < std : : string > ( " type " , " ParOverILU0 " ) ;
auto it = creators_ . find ( type ) ;
if ( it = = creators_ . end ( ) ) {
std : : ostringstream msg ;
msg < < " Preconditioner type " < < type < < " is not registered in the factory. Available types are: " ;
for ( const auto & prec : creators_ ) {
msg < < prec . first < < ' ' ;
}
msg < < std : : endl ;
OPM_THROW ( std : : invalid_argument , msg . str ( ) ) ;
}
return it - > second ( op , prm , weightsCalculator , pressureIndex ) ;
}
template < class Operator , class Comm >
2023-12-20 03:00:06 -06:00
typename PreconditionerFactory < Operator , Comm > : : PrecPtr
PreconditionerFactory < Operator , Comm > : : doCreate ( const Operator & op ,
const PropertyTree & prm ,
const std : : function < Vector ( ) > weightsCalculator ,
std : : size_t pressureIndex ,
const Comm & comm )
2022-08-17 01:23:01 -05:00
{
if ( ! defAdded_ ) {
2023-12-20 03:00:06 -06:00
StandardPreconditioners < Operator , Comm > : : add ( ) ;
2022-08-17 01:23:01 -05:00
defAdded_ = true ;
}
const std : : string & type = prm . get < std : : string > ( " type " , " ParOverILU0 " ) ;
auto it = parallel_creators_ . find ( type ) ;
if ( it = = parallel_creators_ . end ( ) ) {
std : : ostringstream msg ;
2023-12-20 03:00:06 -06:00
msg < < " Parallel preconditioner type " < < type < < " is not registered in the factory. Available types are: " ;
2022-08-17 01:23:01 -05:00
for ( const auto & prec : parallel_creators_ ) {
msg < < prec . first < < ' ' ;
}
msg < < std : : endl ;
OPM_THROW ( std : : invalid_argument , msg . str ( ) ) ;
}
return it - > second ( op , prm , weightsCalculator , pressureIndex , comm ) ;
}
template < class Operator , class Comm >
2023-12-20 03:00:06 -06:00
void
PreconditionerFactory < Operator , Comm > : : doAddCreator ( const std : : string & type , Creator c )
2022-08-17 01:23:01 -05:00
{
creators_ [ type ] = c ;
}
template < class Operator , class Comm >
2023-12-20 03:00:06 -06:00
void
PreconditionerFactory < Operator , Comm > : : doAddCreator ( const std : : string & type , ParCreator c )
2022-08-17 01:23:01 -05:00
{
parallel_creators_ [ type ] = c ;
}
template < class Operator , class Comm >
2023-12-20 03:00:06 -06:00
typename PreconditionerFactory < Operator , Comm > : : PrecPtr
PreconditionerFactory < Operator , Comm > : : create ( const Operator & op ,
const PropertyTree & prm ,
const std : : function < Vector ( ) > & weightsCalculator ,
std : : size_t pressureIndex )
2022-08-17 01:23:01 -05:00
{
return instance ( ) . doCreate ( op , prm , weightsCalculator , pressureIndex ) ;
}
template < class Operator , class Comm >
2023-12-20 03:00:06 -06:00
typename PreconditionerFactory < Operator , Comm > : : PrecPtr
PreconditionerFactory < Operator , Comm > : : create ( const Operator & op ,
const PropertyTree & prm ,
const std : : function < Vector ( ) > & weightsCalculator ,
const Comm & comm ,
std : : size_t pressureIndex )
2022-08-17 01:23:01 -05:00
{
return instance ( ) . doCreate ( op , prm , weightsCalculator , pressureIndex , comm ) ;
}
template < class Operator , class Comm >
2023-12-20 03:00:06 -06:00
typename PreconditionerFactory < Operator , Comm > : : PrecPtr
PreconditionerFactory < Operator , Comm > : : create ( const Operator & op ,
const PropertyTree & prm ,
const Comm & comm ,
std : : size_t pressureIndex )
2022-08-17 01:23:01 -05:00
{
return instance ( ) . doCreate ( op , prm , std : : function < Vector ( ) > ( ) , pressureIndex , comm ) ;
}
template < class Operator , class Comm >
2023-12-20 03:00:06 -06:00
void
PreconditionerFactory < Operator , Comm > : : addCreator ( const std : : string & type , Creator creator )
2022-08-17 01:23:01 -05:00
{
instance ( ) . doAddCreator ( type , creator ) ;
}
template < class Operator , class Comm >
2023-12-20 03:00:06 -06:00
void
PreconditionerFactory < Operator , Comm > : : addCreator ( const std : : string & type , ParCreator creator )
2022-08-17 01:23:01 -05:00
{
instance ( ) . doAddCreator ( type , creator ) ;
}
using CommSeq = Dune : : Amg : : SequentialInformation ;
2023-12-20 03:00:06 -06:00
template < int Dim >
using OpFSeq = Dune : : MatrixAdapter < Dune : : BCRSMatrix < Dune : : FieldMatrix < double , Dim , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > > ;
template < int Dim >
2024-04-13 08:18:32 -05:00
using OpBSeq = Dune : : MatrixAdapter < Dune : : BCRSMatrix < MatrixBlock < double , Dim , Dim > > ,
2023-12-20 03:00:06 -06:00
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > > ;
template < int Dim , bool overlap >
using OpW = WellModelMatrixAdapter < Dune : : BCRSMatrix < MatrixBlock < double , Dim , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > ,
overlap > ;
template < int Dim , bool overlap >
using OpWG = WellModelGhostLastMatrixAdapter < Dune : : BCRSMatrix < MatrixBlock < double , Dim , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > ,
2022-08-17 01:23:01 -05:00
overlap > ;
# if HAVE_MPI
2023-12-20 03:00:06 -06:00
using CommPar = Dune : : OwnerOverlapCopyCommunication < int , int > ;
2022-08-17 01:23:01 -05:00
2023-12-20 03:00:06 -06:00
template < int Dim >
using OpFPar = Dune : : OverlappingSchwarzOperator < Dune : : BCRSMatrix < Dune : : FieldMatrix < double , Dim , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > ,
2022-08-17 01:23:01 -05:00
CommPar > ;
2023-12-20 03:00:06 -06:00
template < int Dim >
using OpBPar = Dune : : OverlappingSchwarzOperator < Dune : : BCRSMatrix < MatrixBlock < double , Dim , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > ,
2022-08-17 01:23:01 -05:00
CommPar > ;
2022-11-03 06:04:54 -05:00
template < int Dim >
using OpGLFPar = Opm : : GhostLastMatrixAdapter < Dune : : BCRSMatrix < Dune : : FieldMatrix < double , Dim , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > ,
CommPar > ;
template < int Dim >
using OpGLBPar = Opm : : GhostLastMatrixAdapter < Dune : : BCRSMatrix < MatrixBlock < double , Dim , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > ,
Dune : : BlockVector < Dune : : FieldVector < double , Dim > > ,
CommPar > ;
2022-08-17 01:23:01 -05:00
2023-12-20 03:00:06 -06:00
# define INSTANCE_PF_PAR(Dim) \
template class PreconditionerFactory < OpBSeq < Dim > , CommPar > ; \
template class PreconditionerFactory < OpFPar < Dim > , CommPar > ; \
template class PreconditionerFactory < OpBPar < Dim > , CommPar > ; \
2022-11-03 06:04:54 -05:00
template class PreconditionerFactory < OpGLFPar < Dim > , CommPar > ; \
template class PreconditionerFactory < OpGLBPar < Dim > , CommPar > ; \
2023-12-20 03:00:06 -06:00
template class PreconditionerFactory < OpW < Dim , false > , CommPar > ; \
template class PreconditionerFactory < OpWG < Dim , true > , CommPar > ; \
2022-11-03 06:04:54 -05:00
template class PreconditionerFactory < OpBPar < Dim > , CommSeq > ; \
template class PreconditionerFactory < OpGLBPar < Dim > , CommSeq > ;
2022-08-17 01:23:01 -05:00
# endif
2023-12-20 03:00:06 -06:00
# define INSTANCE_PF_SEQ(Dim) \
template class PreconditionerFactory < OpFSeq < Dim > , CommSeq > ; \
template class PreconditionerFactory < OpBSeq < Dim > , CommSeq > ; \
template class PreconditionerFactory < OpW < Dim , false > , CommSeq > ; \
template class PreconditionerFactory < OpWG < Dim , true > , CommSeq > ;
2022-08-17 01:23:01 -05:00
# if HAVE_MPI
2023-12-20 03:00:06 -06:00
# define INSTANCE_PF(Dim) \
INSTANCE_PF_PAR ( Dim ) \
2022-08-17 01:23:01 -05:00
INSTANCE_PF_SEQ ( Dim )
# else
2023-12-20 03:00:06 -06:00
# define INSTANCE_PF(Dim) INSTANCE_PF_SEQ(Dim)
2022-08-17 01:23:01 -05:00
# endif
2023-12-20 03:00:06 -06:00
} // namespace Opm