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 |