Go to the documentation of this file.
21#ifndef OPM_FLEXIBLE_SOLVER_IMPL_HEADER_INCLUDED
22#define OPM_FLEXIBLE_SOLVER_IMPL_HEADER_INCLUDED
24#include <opm/common/ErrorMacros.hpp>
25#include <opm/common/TimingMacros.hpp>
36#if HAVE_AVX2_EXTENSION
40#include <dune/common/fmatrix.hh>
41#include <dune/istl/bcrsmatrix.hh>
42#include <dune/istl/multitypeblockvector.hh>
43#include <dune/istl/solvers.hh>
44#include <dune/istl/umfpack.hh>
45#include <dune/istl/owneroverlapcopy.hh>
46#include <dune/istl/paamg/pinfo.hh>
52template < typename... Args>
60#include <opm/simulators/linalg/gpuistl_hip/SolverAdapter.hpp>
69 template < class Operator>
74 std::size_t pressureIndex)
76 init(op, Dune::Amg::SequentialInformation(), prm, weightsCalculator,
81 template < class Operator>
87 const std::function< VectorType()>& weightsCalculator,
88 std::size_t pressureIndex)
90 init(op, comm, prm, weightsCalculator, pressureIndex);
93 template < class Operator>
100 if (direct_precond && direct_precond->needsRebuild()) {
101 recreateDirectSolver();
102 direct_precond->resetNeedsRebuild();
105 linsolver_->apply(x, rhs, res);
108 template < class Operator>
113 if (direct_solver_) {
115 if (direct_precond && direct_precond->needsRebuild()) {
116 recreateDirectSolver();
117 direct_precond->resetNeedsRebuild();
120 linsolver_->apply(x, rhs, reduction, res);
124 template < class Operator>
129 return *preconditioner_;
132 template < class Operator>
133 Dune::SolverCategory::Category
137 return linearoperator_for_solver_->category();
141 template < class Operator>
142 template < class Comm>
147 const std::function<VectorType()> weightsCalculator,
149 std::size_t pressureIndex)
152 linearoperator_for_solver_ = &op;
153 const std::string solver_type = prm. get<std::string>( "solver", "bicgstab");
155 if (solver_type == "umfpack") {
156 preconditioner_ = std::make_shared<Dune::DirectSolverUpdatePreconditioner<VectorType, VectorType>>(
157 linearoperator_for_solver_->category());
165 scalarproduct_ = Dune::createScalarProduct<VectorType, Comm>(comm, op.category());
168 template < class Operator>
170 FlexibleSolver<Operator>::
171 initOpPrecSp(Operator& op,
173 const std::function<VectorType()> weightsCalculator,
174 const Dune::Amg::SequentialInformation&,
175 std::size_t pressureIndex)
178 linearoperator_for_solver_ = &op;
179 const std::string solver_type = prm. get<std::string>( "solver", "bicgstab");
181 if (solver_type == "umfpack") {
182 preconditioner_ = std::make_shared<Dune::DirectSolverUpdatePreconditioner<VectorType, VectorType>>(
183 linearoperator_for_solver_->category());
190 scalarproduct_ = std::make_shared<Dune::SeqScalarProduct<VectorType>>();
194 template < class Operator>
195 template < class Comm>
197 FlexibleSolver<Operator>::
200 const bool is_iorank = comm.communicator().rank() == 0;
201 const double tol = prm. get< double>( "tol", 1e-2);
202 const int maxiter = prm. get< int>( "maxiter", 200);
203 const int verbosity = is_iorank ? prm. get< int>( "verbosity", 0) : 0;
204 const std::string solver_type = prm. get<std::string>( "solver", "bicgstab");
212 direct_solver_ = false;
213 if (solver_type == "bicgstab") {
214 linsolver_ = std::make_shared<Dune::BiCGSTABSolver<VectorType>>(*linearoperator_for_solver_,
220#if HAVE_AVX2_EXTENSION
221 } else if (solver_type == "mixed-bicgstab") {
222 if constexpr (Opm::is_gpu_operator_v<Operator>) {
223 OPM_THROW(std::invalid_argument, "mixed-bicgstab solver not supported for GPU operatorsg");
224 } else if constexpr (Opm::detail::is_multi_type_block_vector_v<VectorType>) {
225 OPM_THROW(std::invalid_argument, "mixed-bicgstab solver not supported for multi-type block vectors.");
226 } else if constexpr (std::is_same_v<typename VectorType::field_type, float>){
227 OPM_THROW(std::invalid_argument, "mixed-bicgstab solver not supported for single precision.");
229 const std::string prec_type = prm. get<std::string>( "preconditioner.type", "error");
230 bool use_mixed_dilu= (prec_type== "mixed-dilu");
231 using MatrixType = decltype(linearoperator_for_solver_->getmat());
232 linsolver_ = std::make_shared<Dune::MixedSolver<VectorType,MatrixType>>(
233 linearoperator_for_solver_->getmat(),
240 } else if (solver_type == "loopsolver") {
241 linsolver_ = std::make_shared<Dune::LoopSolver<VectorType>>(*linearoperator_for_solver_,
247 } else if (solver_type == "gmres") {
248 int restart = prm. get< int>( "restart", 15);
249 linsolver_ = std::make_shared<Dune::RestartedGMResSolver<VectorType>>(*linearoperator_for_solver_,
256 } else if (solver_type == "flexgmres") {
257 if constexpr (Opm::is_gpu_operator_v<Operator>) {
258 OPM_THROW(std::invalid_argument, "flexgmres solver not supported for GPU operators.");
260 int restart = prm. get< int>( "restart", 15);
261 linsolver_ = std::make_shared<Dune::RestartedFlexibleGMResSolver<VectorType>>(*linearoperator_for_solver_,
269 } else if (solver_type == "preconditioner2inverseoperator") {
270 if (!preconditioner_) {
271 OPM_THROW(std::invalid_argument,
272 "Properties: Solver preconditioner2inverseoperator requires a preconditioner.");
274 linsolver_ = std::make_shared<Dune::Preconditioner2InverseOperator<VectorType>>(preconditioner_);
276 if constexpr (!Opm::is_gpu_operator_v<Operator> && !Opm::detail::is_multi_type_block_vector_v<VectorType>) {
277#if HAVE_SUITESPARSE_UMFPACK
278 if (solver_type == "umfpack") {
279 if constexpr (std::is_same_v<typename VectorType::field_type,float>) {
280 OPM_THROW(std::invalid_argument, "UMFPack cannot be used with floats");
282 using MatrixType = std::remove_const_t<std::remove_reference_t< decltype(linearoperator_for_solver_->getmat())>>;
283 linsolver_ = std::make_shared<Dune::UMFPack<MatrixType>>(linearoperator_for_solver_->getmat(), verbosity, false);
284 direct_solver_ = true;
288 } else if (solver_type == "gpubicgstab") {
290 *linearoperator_for_solver_,
302 OPM_THROW(std::invalid_argument,
303 "Properties: Solver " + solver_type + " not known.");
313 template < class Operator>
315 FlexibleSolver<Operator>::
316 recreateDirectSolver()
318#if HAVE_SUITESPARSE_UMFPACK
319 if constexpr (!Opm::is_gpu_operator_v<Operator> && !Opm::detail::is_multi_type_block_vector_v<VectorType>) {
320 if constexpr (std::is_same_v<typename VectorType::field_type, float>) {
321 OPM_THROW(std::invalid_argument, "UMFPack cannot be used with floats");
323 using MatrixType = std::remove_const_t<std::remove_reference_t< decltype(linearoperator_for_solver_->getmat())>>;
324 linsolver_ = std::make_shared<Dune::UMFPack<MatrixType>>(linearoperator_for_solver_->getmat(), 0, false);
328 OPM_THROW(std::logic_error, "Direct solver specified, but the FlexibleSolver class was not compiled with SuiteSparse support.");
335 template < class Operator>
336 template < class Comm>
342 const std::function< VectorType()> weightsCalculator,
343 std::size_t pressureIndex)
345 initOpPrecSp(op, prm, weightsCalculator, comm, pressureIndex);
346 initSolver(prm, comm);
355template< class Scalar, int N>
356using BV = Dune::BlockVector<Dune::FieldVector<Scalar, N>>;
357template< class Scalar, int N>
358using OBM = Dune::BCRSMatrix<Opm::MatrixBlock<Scalar, N, N>>;
361template< class Scalar, int N>
363template< class Scalar, int N>
369using Comm = Dune::OwnerOverlapCopyCommunication<int, int>;
370template< class Scalar, int N>
372template< class Scalar, int N>
374template< class Scalar, int N>
381#define INSTANTIATE_FLEXIBLESOLVER_OP(...) \
382 template class Dune::FlexibleSolver<__VA_ARGS__>; \
383 template Dune::FlexibleSolver<__VA_ARGS__>:: \
384 FlexibleSolver(__VA_ARGS__& op, \
386 const Opm::PropertyTree& prm, \
387 const std::function<typename __VA_ARGS__::domain_type()>& weightsCalculator, \
388 std::size_t pressureIndex);
390#define INSTANTIATE_FLEXIBLESOLVER(T,N) \
391 INSTANTIATE_FLEXIBLESOLVER_OP(SeqOpM<T,N>); \
392 INSTANTIATE_FLEXIBLESOLVER_OP(SeqOpW<T,N>); \
393 INSTANTIATE_FLEXIBLESOLVER_OP(ParOpM<T,N>); \
394 INSTANTIATE_FLEXIBLESOLVER_OP(ParOpW<T,N>); \
395 INSTANTIATE_FLEXIBLESOLVER_OP(ParOpD<T,N>);
399#define INSTANTIATE_FLEXIBLESOLVER_OP(...) \
400 template class Dune::FlexibleSolver<__VA_ARGS__>;
402#define INSTANTIATE_FLEXIBLESOLVER(T,N) \
403 INSTANTIATE_FLEXIBLESOLVER_OP(SeqOpM<T,N>); \
404 INSTANTIATE_FLEXIBLESOLVER_OP(SeqOpW<T,N>);
Dune::OverlappingSchwarzOperator< OBM< Scalar, N >, BV< Scalar, N >, BV< Scalar, N >, Comm > ParOpD Definition: FlexibleSolver_impl.hpp:375
Dune::BCRSMatrix< Opm::MatrixBlock< Scalar, N, N > > OBM Definition: FlexibleSolver_impl.hpp:358
Dune::BlockVector< Dune::FieldVector< Scalar, N > > BV Definition: FlexibleSolver_impl.hpp:356
Dune::OwnerOverlapCopyCommunication< int, int > Comm Definition: FlexibleSolver_impl.hpp:369
Dune::MatrixAdapter< OBM< Scalar, N >, BV< Scalar, N >, BV< Scalar, N > > SeqOpM Definition: FlexibleSolver_impl.hpp:362
Definition: PreconditionerWithUpdate.hpp:98
Definition: FlexibleSolver.hpp:45
virtual Dune::SolverCategory::Category category() const override Definition: FlexibleSolver_impl.hpp:135
virtual void apply(VectorType &x, VectorType &rhs, Dune::InverseOperatorResult &res) override Definition: FlexibleSolver_impl.hpp:96
typename Operator::domain_type VectorType Definition: FlexibleSolver.hpp:47
FlexibleSolver(Operator &op, const Opm::PropertyTree &prm, const std::function< VectorType()> &weightsCalculator, std::size_t pressureIndex) Create a sequential solver. Definition: FlexibleSolver_impl.hpp:71
AbstractPrecondType & preconditioner() Access the contained preconditioner. Definition: FlexibleSolver_impl.hpp:127
Dune linear operator that assumes ghost rows are ordered after interior rows. Avoids some computation... Definition: WellOperators.hpp:402
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:154
Hierarchical collection of key/value pairs. Definition: PropertyTree.hpp:39
T get(const std::string &key) const
std::optional< PropertyTree > get_child_optional(const std::string &key) const
Adapter to combine a matrix and another linear operator into a combined linear operator. Definition: WellOperators.hpp:299
Adapter to combine a matrix and another linear operator into a combined linear operator. Definition: WellOperators.hpp:225
Wraps a CUDA solver to work with CPU data. Definition: SolverAdapter.hpp:52
Definition: fvbaseprimaryvariables.hh:161
Definition: alignedallocator.hh:32
constexpr bool is_multi_type_block_vector_v Definition: FlexibleSolver_impl.hpp:55
Dune::InverseOperatorResult InverseOperatorResult Definition: GpuBridge.hpp:32
Definition: FlexibleSolver_impl.hpp:51
|