GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/linear/istlsolverfactorybackend.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 83 91 91.2%
Functions: 144 216 66.7%
Branches: 138 396 34.8%

Line Branch Exec Source
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 // SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 /*!
8 * \file
9 * \ingroup Linear
10 * \brief Provides a generic linear solver based on the ISTL that chooses the
11 * solver and preconditioner at runtime
12 */
13
14 #ifndef DUMUX_LINEAR_ISTL_SOLVERFACTORYBACKEND_HH
15 #define DUMUX_LINEAR_ISTL_SOLVERFACTORYBACKEND_HH
16
17 #include <memory>
18
19 #include <dune/common/parallel/mpihelper.hh>
20 #include <dune/common/parametertree.hh>
21
22 #include "linearsolverparameters.hh"
23
24 // preconditioners
25 #include <dune/istl/preconditioners.hh>
26 #include <dune/istl/paamg/amg.hh>
27 #include "preconditioners.hh"
28
29 // solvers
30 #include <dune/istl/solvers.hh>
31 #include <dune/istl/solverfactory.hh>
32
33 #include <dumux/common/typetraits/matrix.hh>
34 #include <dumux/common/typetraits/vector.hh>
35 #include <dumux/linear/solver.hh>
36 #include <dumux/linear/parallelhelpers.hh>
37 #include <dumux/linear/istlsolverregistry.hh>
38 #include <dumux/linear/solvercategory.hh>
39
40 namespace Dumux {
41
42 // initSolverFactoriesForMultiTypeBlockMatrix differs in different compilation units,
43 // so we have it in an anonymous namespace
44 namespace {
45
46 /*!
47 * \brief Initializes the direct solvers, preconditioners and iterative solvers in
48 * the factories with the corresponding Matrix and Vector types.
49 * \note We currently consider only direct solvers and preconditioners provided by
50 * Dumux which, unlike the ones implemented in Dune, also support MultiTypeBlockMatrices.
51 * \note This function could be removed once Dune::initSolverFactories supports MultiTypeBlockMatrices.
52 * \tparam LinearOperator the linear operator type
53 */
54 template<class LinearOperator>
55 1 int initSolverFactoriesForMultiTypeBlockMatrix()
56 {
57 using M = typename LinearOperator::matrix_type;
58 using X = typename LinearOperator::range_type;
59 using Y = typename LinearOperator::domain_type;
60 using TL = Dune::TypeList<M,X,Y>;
61 1 auto& dsfac = Dune::DirectSolverFactory<M,X,Y>::instance();
62 1 Dune::addRegistryToFactory<TL>(dsfac, Dumux::MultiTypeBlockMatrixDirectSolverTag{});
63 1 auto& pfac = Dune::PreconditionerFactory<LinearOperator,X,Y>::instance();
64 1 Dune::addRegistryToFactory<TL>(pfac, Dumux::MultiTypeBlockMatrixPreconditionerTag{});
65 using TLS = Dune::TypeList<X,Y>;
66 1 auto& isfac = Dune::IterativeSolverFactory<X,Y>::instance();
67 1 return Dune::addRegistryToFactory<TLS>(isfac, Dune::IterativeSolverTag{});
68 }
69 } // end namespace
70
71 /*!
72 * \brief Initialize the solver factories for regular matrices or MultiTypeBlockMatrices
73 * \tparam Matrix the matrix
74 * \tparam LinearOperator the linear operator
75 *
76 * \note This function could be removed once Dune::initSolverFactories supports MultiTypeBlockMatrices.
77 */
78 template<class Matrix, class LinearOperator>
79 void initSolverFactories()
80 {
81 if constexpr (isMultiTypeBlockMatrix<Matrix>::value)
82 1 initSolverFactoriesForMultiTypeBlockMatrix<LinearOperator>();
83 else
84 42 Dune::initSolverFactories<LinearOperator>();
85 }
86
87 /*!
88 * \ingroup Linear
89 * \brief A linear solver using the dune-istl solver factory
90 * to choose the solver and preconditioner at runtime.
91 * \note the solvers are configured via the input file
92 */
93 template <class LinearSolverTraits, class LinearAlgebraTraits>
94 class IstlSolverFactoryBackend : public LinearSolver
95 {
96 using Matrix = typename LinearAlgebraTraits::Matrix;
97 using Vector = typename LinearAlgebraTraits::Vector;
98 using ScalarProduct = Dune::ScalarProduct<Vector>;
99 #if HAVE_MPI
100 using Comm = Dune::OwnerOverlapCopyCommunication<Dune::bigunsignedint<96>, int>;
101 #endif
102 public:
103
104 /*!
105 * \brief Construct the backend for the sequential case only
106 *
107 * \param paramGroup the parameter group for parameter lookup
108 */
109 3 IstlSolverFactoryBackend(const std::string& paramGroup = "")
110 : paramGroup_(paramGroup)
111
14/42
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✓ Branch 12 taken 3 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 3 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 3 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 3 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 3 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 3 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 3 times.
✗ Branch 31 not taken.
✓ Branch 33 taken 3 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 3 times.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✓ Branch 39 taken 3 times.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
6 , isParallel_(Dune::MPIHelper::getCommunication().size() > 1)
112 {
113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (isParallel_)
114 DUNE_THROW(Dune::InvalidStateException, "Using sequential constructor for parallel run. Use signature with gridView and dofMapper!");
115
116 3 firstCall_ = true;
117
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 initializeParameters_();
118
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
3 scalarProduct_ = std::make_shared<ScalarProduct>();
119 3 solverCategory_ = Dune::SolverCategory::sequential;
120 3 }
121
122 /*!
123 * \brief Construct the backend for parallel or sequential runs
124 *
125 * \param gridView the grid view for parallel communication via the grid
126 * \param dofMapper an index mapper for dof entities
127 * \param paramGroup the parameter group for parameter lookup
128 */
129 40 IstlSolverFactoryBackend(const typename LinearSolverTraits::GridView& gridView,
130 const typename LinearSolverTraits::DofMapper& dofMapper,
131 const std::string& paramGroup = "")
132 : paramGroup_(paramGroup)
133 #if HAVE_MPI
134
15/45
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 40 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 40 times.
✓ Branch 12 taken 40 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 40 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 24 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 24 times.
✓ Branch 21 taken 16 times.
✓ Branch 22 taken 24 times.
✓ Branch 24 taken 40 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 40 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 40 times.
✗ Branch 31 not taken.
✓ Branch 33 taken 40 times.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✓ Branch 36 taken 24 times.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
80 , isParallel_(gridView.comm().size() > 1)
135 #endif
136 {
137 40 firstCall_ = true;
138
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 initializeParameters_();
139 #if HAVE_MPI
140
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
40 solverCategory_ = Detail::solverCategory<LinearSolverTraits>(gridView);
141
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 12 times.
40 if (solverCategory_ != Dune::SolverCategory::sequential)
142 {
143
3/6
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 28 times.
28 parallelHelper_ = std::make_unique<ParallelISTLHelper<LinearSolverTraits>>(gridView, dofMapper);
144
7/9
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 12 times.
✓ Branch 8 taken 16 times.
28 comm_ = std::make_shared<Comm>(gridView.comm(), solverCategory_);
145
4/8
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 28 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 28 times.
56 scalarProduct_ = Dune::createScalarProduct<Vector>(*comm_, solverCategory_);
146
3/6
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 28 times.
✗ Branch 8 not taken.
84 parallelHelper_->createParallelIndexSet(*comm_);
147 }
148 else
149
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
12 scalarProduct_ = std::make_shared<ScalarProduct>();
150 #else
151 solverCategory_ = Dune::SolverCategory::sequential;
152 scalarProduct_ = std::make_shared<ScalarProduct>();
153 #endif
154 40 }
155
156 /*!
157 * \brief Solve a linear system.
158 *
159 * \param A the matrix
160 * \param x the seeked solution vector, containing the initial solution upon entry
161 * \param b the right hand side vector
162 */
163 bool solve(Matrix& A, Vector& x, Vector& b)
164 {
165 #if HAVE_MPI
166
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
1069 solveSequentialOrParallel_(A, x, b);
167 #else
168 solveSequential_(A, x, b);
169 #endif
170 1018 firstCall_ = false;
171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
1018 return result_.converged;
172 }
173
174 const Dune::InverseOperatorResult& result() const
175 {
176 return result_;
177 }
178
179 const std::string& name() const
180 {
181 return name_;
182 }
183
184 178 Scalar norm(const Vector& x) const
185 {
186 #if HAVE_MPI
187 if constexpr (LinearSolverTraits::canCommunicate && !isMultiTypeBlockVector<Vector>::value)
188 {
189
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 128 times.
178 if (solverCategory_ == Dune::SolverCategory::nonoverlapping)
190 {
191
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
100 auto y(x); // make a copy because the vector needs to be made consistent
192 using GV = typename LinearSolverTraits::GridView;
193 using DM = typename LinearSolverTraits::DofMapper;
194
4/8
✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 50 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 50 times.
✗ Branch 11 not taken.
200 ParallelVectorHelper<GV, DM, LinearSolverTraits::dofCodim> vectorHelper(parallelHelper_->gridView(), parallelHelper_->dofMapper());
195
1/2
✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
50 vectorHelper.makeNonOverlappingConsistent(y);
196
3/6
✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 50 times.
✗ Branch 7 not taken.
100 return scalarProduct_->norm(y);
197 }
198 }
199 #endif
200
2/4
✓ Branch 3 taken 17 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 17 times.
✗ Branch 7 not taken.
392 return scalarProduct_->norm(x);
201 }
202
203 private:
204
205 43 void initializeParameters_()
206 {
207 43 params_ = Dumux::LinearSolverParameters<LinearSolverTraits>::createParameterTree(paramGroup_);
208 43 checkMandatoryParameters_();
209
18/42
✓ Branch 1 taken 43 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 43 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 43 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 43 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 43 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 43 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 43 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 43 times.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 43 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 43 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 43 times.
✓ Branch 31 taken 43 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 1 times.
✓ Branch 34 taken 42 times.
✓ Branch 35 taken 1 times.
✓ Branch 36 taken 42 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 43 times.
✓ Branch 40 taken 43 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
173 name_ = params_.get<std::string>("preconditioner.type") + "-preconditioned " + params_.get<std::string>("type");
210
8/14
✓ Branch 1 taken 43 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 43 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 43 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 43 times.
✓ Branch 11 taken 3 times.
✓ Branch 12 taken 40 times.
✓ Branch 13 taken 3 times.
✓ Branch 14 taken 40 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
86 if (params_.get<int>("verbose", 0) > 0)
211 6 std::cout << "Initialized linear solver of type: " << name_ << std::endl;
212 43 }
213
214 43 void checkMandatoryParameters_()
215 {
216
6/14
✓ Branch 1 taken 43 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 43 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 43 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 43 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 43 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 43 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
86 if (!params_.hasKey("type"))
217 DUNE_THROW(Dune::InvalidStateException, "Solver factory needs \"LinearSolver.Type\" parameter to select the solver");
218
219
6/14
✓ Branch 1 taken 43 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 43 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 43 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 43 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 43 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 43 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
172 if (!params_.hasKey("preconditioner.type"))
220 DUNE_THROW(Dune::InvalidStateException, "Solver factory needs \"LinearSolver.Preconditioner.Type\" parameter to select the preconditioner");
221 43 }
222
223 #if HAVE_MPI
224 967 void solveSequentialOrParallel_(Matrix& A, Vector& x, Vector& b)
225 {
226 // Dune::MultiTypeBlockMatrix does not provide a ColIterator which is needed by Dune::NonoverlappingSchwarzOperator.
227 // We therefore can only solve these types of systems sequentially.
228 // TODO: This can be adapted once the situation in Dune ISTL changes.
229 if constexpr (LinearSolverTraits::canCommunicate && !isMultiTypeBlockMatrix<Matrix>::value)
230 {
231
2/2
✓ Branch 0 taken 680 times.
✓ Branch 1 taken 287 times.
967 if (isParallel_)
232 {
233
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 106 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 196 times.
✓ Branch 4 taken 98 times.
✓ Branch 5 taken 106 times.
1744 if (LinearSolverTraits::isNonOverlapping(parallelHelper_->gridView()))
234 {
235 using PTraits = typename LinearSolverTraits::template ParallelNonoverlapping<Matrix, Vector>;
236 286 solveParallel_<PTraits>(A, x, b);
237 }
238 else
239 {
240 using PTraits = typename LinearSolverTraits::template ParallelOverlapping<Matrix, Vector>;
241 394 solveParallel_<PTraits>(A, x, b);
242 }
243 }
244 else
245 287 solveSequential_(A, x, b);
246 }
247 else
248 {
249 51 solveSequential_(A, x, b);
250 }
251 967 }
252
253 template<class ParallelTraits>
254 1360 void solveParallel_(Matrix& A, Vector& x, Vector& b)
255 {
256 using LinearOperator = typename ParallelTraits::LinearOperator;
257
258
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 652 times.
1360 if (firstCall_)
259 56 initSolverFactories<Matrix, LinearOperator>();
260
261 2720 prepareLinearAlgebraParallel<LinearSolverTraits, ParallelTraits>(A, b, *parallelHelper_);
262
1/4
✓ Branch 2 taken 680 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4080 auto linearOperator = std::make_shared<LinearOperator>(A, *comm_);
263
264 // solve linear system
265
1/2
✓ Branch 1 taken 680 times.
✗ Branch 2 not taken.
1360 apply_(linearOperator, x, b);
266 1360 }
267 #endif // HAVE_MPI
268
269 338 void solveSequential_(Matrix& A, Vector& x, Vector& b)
270 {
271 // construct linear operator
272 using Traits = typename LinearSolverTraits::template Sequential<Matrix, Vector>;
273 using LinearOperator = typename Traits::LinearOperator;
274
1/4
✓ Branch 1 taken 338 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
676 auto linearOperator = std::make_shared<LinearOperator>(A);
275
276
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 323 times.
338 if (firstCall_)
277
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 initSolverFactories<Matrix, LinearOperator>();
278
279 // solve linear system
280
1/2
✓ Branch 1 taken 338 times.
✗ Branch 2 not taken.
338 apply_(linearOperator, x, b);
281 338 }
282
283 template<class LinearOperator>
284 1985 auto getSolverFromFactory_(std::shared_ptr<LinearOperator>& fop)
285 {
286 try {
287
3/12
✓ Branch 3 taken 1018 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1018 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1018 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
5955 return Dune::getSolverFromFactory(fop, params_);
288 } catch(Dune::Exception& e) {
289 std::cerr << "Dune::Exception during solver construction: " << e.what() << std::endl;
290 return std::decay_t<decltype(Dune::getSolverFromFactory(fop, params_))>();
291 }
292 }
293
294 template<class LinearOperator>
295 1985 void apply_(std::shared_ptr<LinearOperator>& fop, Vector& x, Vector& b)
296 {
297
1/4
✓ Branch 1 taken 1018 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
3970 auto solver = getSolverFromFactory_(fop);
298
299 // make solver constructor failure recoverable by throwing an exception
300 // on all processes if one or more processes fail
301
2/2
✓ Branch 0 taken 680 times.
✓ Branch 1 taken 338 times.
1985 bool success = static_cast<bool>(solver);
302 #if HAVE_MPI
303 1985 int successRemote = success;
304
2/2
✓ Branch 0 taken 680 times.
✓ Branch 1 taken 338 times.
1985 if (isParallel_)
305
3/6
✓ Branch 1 taken 680 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 680 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 680 times.
✗ Branch 8 not taken.
4080 successRemote = comm_->communicator().min(success);
306
307
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1018 times.
1985 if (!success)
308 DUNE_THROW(Dune::Exception, "Could not create ISTL solver");
309
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1018 times.
1985 else if (!successRemote)
310 DUNE_THROW(Dune::Exception, "Could not create ISTL solver on remote process");
311 #else
312 if (!success)
313 DUNE_THROW(Dune::Exception, "Could not create ISTL solver");
314 #endif
315
316 // solve linear system (here we assume that either all processes are successful or all fail)
317
2/4
✓ Branch 1 taken 1018 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1018 times.
✗ Branch 5 not taken.
3970 solver->apply(x, b, result_);
318 1985 }
319
320 const std::string paramGroup_;
321 #if HAVE_MPI
322 std::unique_ptr<ParallelISTLHelper<LinearSolverTraits>> parallelHelper_;
323 std::shared_ptr<Comm> comm_;
324 #endif
325 bool isParallel_ = false;
326 bool firstCall_;
327
328 std::shared_ptr<ScalarProduct> scalarProduct_;
329 Dune::SolverCategory::Category solverCategory_;
330 Dune::InverseOperatorResult result_;
331 Dune::ParameterTree params_;
332 std::string name_;
333 };
334
335 } // end namespace Dumux
336
337 #endif
338