superlubackend.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
27#ifndef EWOMS_SUPER_LU_BACKEND_HH
28#define EWOMS_SUPER_LU_BACKEND_HH
29
30#if HAVE_SUPERLU
31
32#include <opm/models/linear/istlsparsematrixbackend.hh>
35
36#include <opm/material/common/Unused.hpp>
37
38#include <dune/istl/superlu.hh>
39#include <dune/common/fmatrix.hh>
40#include <dune/common/version.hh>
41
42namespace Opm::Properties::TTag {
43struct SuperLULinearSolver {};
44} // namespace Opm::Properties::TTag
45
46namespace Opm {
47namespace Linear {
48template <class Scalar, class TypeTag, class Matrix, class Vector>
49class SuperLUSolve_;
50
55template <class TypeTag>
56class SuperLUBackend
57{
58 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
59 using Simulator = GetPropType<TypeTag, Properties::Simulator>;
60 using SparseMatrixAdapter = GetPropType<TypeTag, Properties::SparseMatrixAdapter>;
61 using Matrix = typename SparseMatrixAdapter::block_type;
62
63 static_assert(std::is_same<SparseMatrixAdapter, IstlSparseMatrixAdapter<MatrixBlock>::value,
64 "The SuperLU linear solver backend requires the IstlSparseMatrixAdapter");
65
66public:
67 SuperLUBackend(Simulator&)
68 {}
69
70 static void registerParameters()
71 {
72 Parameters::registerParam<TypeTag, Properties::LinearSolverVerbosity>
73 ("The verbosity level of the linear solver");
74 }
75
82 void eraseMatrix()
83 { }
84
85 void prepare(const SparseMatrixAdapter& M, const Vector& b)
86 { }
87
88 void setResidual(const Vector& b)
89 { b_ = &b; }
90
91 void getResidual(Vector& b) const
92 { b = *b_; }
93
94 void setMatrix(const SparseMatrixAdapter& M)
95 { M_ = &M; }
96
97 bool solve(Vector& x)
98 { return SuperLUSolve_<Scalar, TypeTag, Matrix, Vector>::solve_(*M_, x, *b_); }
99
100private:
101 const Matrix* M_;
102 Vector* b_;
103};
104
105template <class Scalar, class TypeTag, class Matrix, class Vector>
106class SuperLUSolve_
107{
108public:
109 static bool solve_(const Matrix& A, Vector& x, const Vector& b)
110 {
111 Vector bTmp(b);
112
113 int verbosity = Parameters::get<TypeTag, Properties::LinearSolverVerbosity>();
114 Dune::InverseOperatorResult result;
115 Dune::SuperLU<Matrix> solver(A, verbosity > 0);
116 solver.apply(x, bTmp, result);
117
118 if (result.converged) {
119 // make sure that the result only contains finite values.
120 Scalar tmp = 0;
121 for (unsigned i = 0; i < x.size(); ++i) {
122 const auto& xi = x[i];
123 for (unsigned j = 0; j < Vector::block_type::dimension; ++j)
124 tmp += xi[j];
125 }
126 result.converged = std::isfinite(tmp);
127 }
128
129 return result.converged;
130 }
131};
132
133// the following is required to make the SuperLU adapter of dune-istl happy with
134// quadruple precision math on Dune 2.4. this is because the most which SuperLU can
135// handle is double precision (i.e., the linear systems of equations are always solved
136// with at most double precision if chosing SuperLU as the linear solver...)
137#if HAVE_QUAD
138template <class TypeTag, class Matrix, class Vector>
139class SuperLUSolve_<__float128, TypeTag, Matrix, Vector>
140{
141public:
142 static bool solve_(const Matrix& A,
143 Vector& x,
144 const Vector& b)
145 {
146 static const int numEq = getPropValue<TypeTag, Properties::NumEq>();
147 using DoubleEqVector = Dune::FieldVector<double, numEq>;
148 using DoubleEqMatrix = Dune::FieldMatrix<double, numEq, numEq>;
149 using DoubleVector = Dune::BlockVector<DoubleEqVector>;
150 using DoubleMatrix = Dune::BCRSMatrix<DoubleEqMatrix>;
151
152 // copy the inputs into the double precision data structures
153 DoubleVector bDouble(b);
154 DoubleVector xDouble(x);
155 DoubleMatrix ADouble(A);
156
157 bool res =
158 SuperLUSolve_<double, TypeTag, Matrix, Vector>::solve_(ADouble,
159 xDouble,
160 bDouble);
161
162 // copy the result back into the quadruple precision vector.
163 x = xDouble;
164
165 return res;
166 }
167};
168#endif
169
170} // namespace Linear
171} // namespace Opm
172
173namespace Opm::Properties {
174
175template<class TypeTag>
176struct LinearSolverVerbosity<TypeTag, TTag::SuperLULinearSolver> { static constexpr int value = 0; };
177template<class TypeTag>
178struct LinearSolverBackend<TypeTag, TTag::SuperLULinearSolver> { using type = Opm::Linear::SuperLUBackend<TypeTag>; };
179
180} // namespace Opm::Properties
181
182#endif // HAVE_SUPERLU
183
184#endif
Declares the properties required by the black oil model.
The generic type tag for problems using the immiscible multi-phase model.
Definition: blackoilmodel.hh:74
Definition: blackoilmodel.hh:72
Definition: blackoilboundaryratevector.hh:37
This file provides the infrastructure to retrieve run-time parameters.
UndefinedProperty type
Definition: linalgproperties.hh:38