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  Copyright (C) 2012-2013 by Andreas Lauser
5  Copyright (C) 2011 by Markus Wolff
6 
7  This file is part of the Open Porous Media project (OPM).
8 
9  OPM is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 2 of the License, or
12  (at your option) any later version.
13 
14  OPM is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with OPM. If not, see <http://www.gnu.org/licenses/>.
21 */
26 #ifndef EWOMS_SUPER_LU_BACKEND_HH
27 #define EWOMS_SUPER_LU_BACKEND_HH
28 
29 #if HAVE_SUPERLU
30 
32 
33 #include <ewoms/istl/solvers.hh>
34 #include <dune/istl/superlu.hh>
35 #include <dune/common/fmatrix.hh>
36 
37 namespace Ewoms {
38 namespace Properties {
39 // forward declaration of the required property tags
40 NEW_PROP_TAG(Problem);
41 NEW_PROP_TAG(Scalar);
42 NEW_PROP_TAG(NumEq);
43 NEW_PROP_TAG(LinearSolverVerbosity);
44 NEW_PROP_TAG(LinearSolverBackend);
45 
46 NEW_TYPE_TAG(SuperLULinearSolver);
47 } // namespace Properties
48 } // namespace Ewoms
49 
50 namespace Ewoms {
51 namespace Linear {
52 template <class Scalar, class TypeTag, class Problem, class Matrix, class Vector>
53 class SuperLUSolve_;
54 
59 template <class TypeTag>
60 class SuperLUBackend
61 {
62  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
63  typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
64 
65 public:
66  SuperLUBackend(const Problem &problem) : problem_(problem)
67  {}
68 
69  static void registerParameters()
70  {
71  EWOMS_REGISTER_PARAM(TypeTag, int, LinearSolverVerbosity,
72  "The verbosity level of the linear solver");
73  }
74 
75  template <class Matrix, class Vector>
76  bool solve(const Matrix &A, Vector &x, const Vector &b)
77  { return SuperLUSolve_<Scalar, TypeTag, Problem, Matrix, Vector>::solve_(problem_, A, x, b); }
78 
79 private:
80  const Problem &problem_;
81 };
82 
83 template <class Scalar, class TypeTag, class Problem, class Matrix, class Vector>
84 class SuperLUSolve_
85 {
86 public:
87  static bool solve_(const Problem &problem, const Matrix &A, Vector &x, const Vector &b)
88  {
89  Vector bTmp(b);
90 
91  int verbosity = EWOMS_GET_PARAM(TypeTag, int, LinearSolverVerbosity);
92  Dune::InverseOperatorResult result;
93  Dune::SuperLU<Matrix> solver(A, verbosity > 0);
94  solver.apply(x, bTmp, result);
95 
96  if (result.converged) {
97  // make sure that the result only contains finite values.
98  Scalar tmp = 0;
99  for (unsigned i = 0; i < x.size(); ++i) {
100  const auto &xi = x[i];
101  for (int j = 0; j < Vector::block_type::dimension; ++j)
102  tmp += xi[j];
103  }
104  result.converged = std::isfinite(tmp);
105  }
106 
107  return result.converged;
108  }
109 };
110 
111 // the following is required to make the SuperLU adapter of dune-istl happy with
112 // quadruple precision math on Dune 2.4. this is because the most which SuperLU can
113 // handle is double precision (i.e., the linear systems of equations are always solved
114 // with at most double precision if chosing SuperLU as the linear solver...)
115 #if DUNE_VERSION_NEWER(DUNE_COMMON, 2,4) && HAVE_QUAD
116 template <class TypeTag, class Problem, class Matrix, class Vector>
117 class SuperLUSolve_<__float128, TypeTag, Problem, Matrix, Vector>
118 {
119 public:
120  static bool solve_(const Problem &problem,
121  const Matrix &A,
122  Vector &x,
123  const Vector &b)
124  {
125  static const int numEq = GET_PROP_VALUE(TypeTag, NumEq);
126  typedef Dune::FieldVector<double, numEq> DoubleEqVector;
127  typedef Dune::FieldMatrix<double, numEq, numEq> DoubleEqMatrix;
128  typedef Dune::BlockVector<DoubleEqVector> DoubleVector;
129  typedef Dune::BCRSMatrix<DoubleEqMatrix> DoubleMatrix;
130 
131  // copy the inputs into the double precision data structures
132  DoubleVector bDouble(b);
133  DoubleVector xDouble(x);
134  DoubleMatrix ADouble(A);
135 
136  bool res =
137  SuperLUSolve_<double, TypeTag, Problem, Matrix, Vector>::solve_(problem,
138  ADouble,
139  xDouble,
140  bDouble);
141 
142  // copy the result back into the quadruple precision vector.
143  x = xDouble;
144 
145  return res;
146  }
147 };
148 #endif
149 
150 } // namespace Linear
151 } // namespace Ewoms
152 
153 namespace Ewoms {
154 namespace Properties {
155 SET_INT_PROP(SuperLULinearSolver, LinearSolverVerbosity, 0);
156 SET_TYPE_PROP(SuperLULinearSolver, LinearSolverBackend,
157  Ewoms::Linear::SuperLUBackend<TypeTag>);
158 } // namespace Properties
159 } // namespace Ewoms
160 
161 #endif // HAVE_SUPERLU
162 
163 #endif
Copy of dune-istl's linear solvers with added support for pluggable convergence criteria.
#define GET_PROP_VALUE(TypeTag, PropTagName)
Access the value attribute of a property for a type tag.
Definition: propertysystem.hh:468
#define GET_PROP_TYPE(TypeTag, PropTagName)
Access the type attribute of a property for a type tag.
Definition: propertysystem.hh:485
SET_INT_PROP(NumericModel, GridGlobalRefinements, 0)
NEW_PROP_TAG(Grid)
The type of the DUNE grid.
This file provides the infrastructure to retrieve run-time parameters.
SET_TYPE_PROP(NumericModel, Scalar, double)
Set the default type of scalar values to double.
Definition: baseauxiliarymodule.hh:35
#define EWOMS_REGISTER_PARAM(TypeTag, ParamType, ParamName, Description)
Register a run-time parameter.
Definition: parametersystem.hh:64
NEW_TYPE_TAG(AuxModule)
#define EWOMS_GET_PARAM(TypeTag, ParamType, ParamName)
Retrieve a runtime parameter.
Definition: parametersystem.hh:95