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-FileCopyrightText: 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 Assembly | ||
10 | * \brief Helper function to generate Jacobian pattern for different discretization methods | ||
11 | */ | ||
12 | #ifndef DUMUX_JACOBIAN_PATTERN_HH | ||
13 | #define DUMUX_JACOBIAN_PATTERN_HH | ||
14 | |||
15 | #include <type_traits> | ||
16 | #include <dune/istl/matrixindexset.hh> | ||
17 | #include <dumux/discretization/method.hh> | ||
18 | |||
19 | namespace Dumux { | ||
20 | |||
21 | /*! | ||
22 | * \ingroup Assembly | ||
23 | * \brief Helper function to generate Jacobian pattern for cell-centered methods | ||
24 | */ | ||
25 | template<bool isImplicit, class GridGeometry, | ||
26 | typename std::enable_if_t<( (GridGeometry::discMethod == DiscretizationMethods::cctpfa) | ||
27 | || (GridGeometry::discMethod == DiscretizationMethods::ccmpfa) ), int> = 0> | ||
28 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
621 | Dune::MatrixIndexSet getJacobianPattern(const GridGeometry& gridGeometry) |
29 | { | ||
30 |
1/2✓ Branch 1 taken 457 times.
✗ Branch 2 not taken.
|
621 | const auto numDofs = gridGeometry.numDofs(); |
31 | 621 | Dune::MatrixIndexSet pattern; | |
32 |
1/2✓ Branch 1 taken 457 times.
✗ Branch 2 not taken.
|
621 | pattern.resize(numDofs, numDofs); |
33 | |||
34 | // matrix pattern for implicit Jacobians | ||
35 | if (isImplicit) | ||
36 | { | ||
37 |
2/2✓ Branch 0 taken 2175280 times.
✓ Branch 1 taken 447 times.
|
3505077 | for (unsigned int globalI = 0; globalI < numDofs; ++globalI) |
38 | { | ||
39 | 3504474 | pattern.add(globalI, globalI); | |
40 |
2/2✓ Branch 0 taken 10610988 times.
✓ Branch 1 taken 2175280 times.
|
21277960 | for (const auto& dataJ : gridGeometry.connectivityMap()[globalI]) |
41 |
1/2✓ Branch 1 taken 10610988 times.
✗ Branch 2 not taken.
|
17773486 | pattern.add(dataJ.globalJ, globalI); |
42 | } | ||
43 | } | ||
44 | |||
45 | // matrix pattern for explicit Jacobians -> diagonal matrix | ||
46 | else | ||
47 | { | ||
48 |
2/2✓ Branch 0 taken 18092 times.
✓ Branch 1 taken 10 times.
|
31202 | for (unsigned int globalI = 0; globalI < numDofs; ++globalI) |
49 | 31184 | pattern.add(globalI, globalI); | |
50 | } | ||
51 | |||
52 | 621 | return pattern; | |
53 | ✗ | } | |
54 | |||
55 | /*! | ||
56 | * \ingroup Assembly | ||
57 | * \brief Helper function to generate Jacobian pattern for the staggered method | ||
58 | */ | ||
59 | template<bool isImplicit, class GridGeometry, | ||
60 | typename std::enable_if_t<( (GridGeometry::discMethod == DiscretizationMethods::staggered) ), int> = 0> | ||
61 | 204 | auto getJacobianPattern(const GridGeometry& gridGeometry) | |
62 | { | ||
63 | // resize the jacobian and the residual | ||
64 | 204 | const auto numDofs = gridGeometry.numDofs(); | |
65 | 204 | Dune::MatrixIndexSet pattern(numDofs, numDofs); | |
66 | |||
67 |
1/2✓ Branch 1 taken 102 times.
✗ Branch 2 not taken.
|
204 | const auto& connectivityMap = gridGeometry.connectivityMap(); |
68 | |||
69 | 204 | auto fvGeometry = localView(gridGeometry); | |
70 | // evaluate the actual pattern | ||
71 |
4/8✓ Branch 1 taken 102 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 179280 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14006 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 14000 times.
✗ Branch 10 not taken.
|
1075308 | for (const auto& element : elements(gridGeometry.gridView())) |
72 | { | ||
73 | if(gridGeometry.isCellCenter()) | ||
74 | { | ||
75 | // the global index of the element at hand | ||
76 | static constexpr auto cellCenterIdx = GridGeometry::cellCenterIdx(); | ||
77 |
3/5✓ Branch 1 taken 7000 times.
✓ Branch 2 taken 82592 times.
✓ Branch 4 taken 7000 times.
✗ Branch 5 not taken.
✗ Branch 3 not taken.
|
179184 | const auto ccGlobalI = gridGeometry.elementMapper().index(element); |
78 | 179184 | pattern.add(ccGlobalI, ccGlobalI); | |
79 |
2/2✓ Branch 0 taken 352542 times.
✓ Branch 1 taken 89592 times.
|
884268 | for (auto&& ccGlobalJ : connectivityMap(cellCenterIdx, cellCenterIdx, ccGlobalI)) |
80 |
1/2✓ Branch 1 taken 352542 times.
✗ Branch 2 not taken.
|
705084 | pattern.add(ccGlobalI, ccGlobalJ); |
81 | } | ||
82 | else | ||
83 | { | ||
84 | static constexpr auto faceIdx = GridGeometry::faceIdx(); | ||
85 |
1/2✓ Branch 1 taken 7000 times.
✗ Branch 2 not taken.
|
179184 | fvGeometry.bindElement(element); |
86 | |||
87 | // loop over sub control faces | ||
88 |
3/4✓ Branch 1 taken 358368 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 358368 times.
✓ Branch 4 taken 89592 times.
|
895920 | for (auto&& scvf : scvfs(fvGeometry)) |
89 | { | ||
90 |
1/2✓ Branch 1 taken 358368 times.
✗ Branch 2 not taken.
|
716736 | const auto faceGlobalI = scvf.dofIndex(); |
91 | 716736 | pattern.add(faceGlobalI, faceGlobalI); | |
92 |
2/2✓ Branch 0 taken 2554872 times.
✓ Branch 1 taken 358368 times.
|
5826480 | for (auto&& faceGlobalJ : connectivityMap(faceIdx, faceIdx, scvf.index())) |
93 |
1/2✓ Branch 1 taken 2554872 times.
✗ Branch 2 not taken.
|
5109744 | pattern.add(faceGlobalI, faceGlobalJ); |
94 | } | ||
95 | } | ||
96 | } | ||
97 | |||
98 | 204 | return pattern; | |
99 | ✗ | } | |
100 | |||
101 | /*! | ||
102 | * \ingroup Assembly | ||
103 | * \brief Helper function to generate Jacobian pattern for finite element scheme | ||
104 | */ | ||
105 | template<class FEBasis> | ||
106 | 21 | Dune::MatrixIndexSet getFEJacobianPattern(const FEBasis& feBasis) | |
107 | { | ||
108 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
21 | const auto numDofs = feBasis.size(); |
109 | |||
110 | 21 | Dune::MatrixIndexSet pattern; | |
111 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
21 | pattern.resize(numDofs, numDofs); |
112 | |||
113 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
21 | auto localView = feBasis.localView(); |
114 | // matrix pattern for implicit Jacobians | ||
115 |
5/7✓ Branch 1 taken 16 times.
✓ Branch 2 taken 13 times.
✓ Branch 4 taken 77216 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 77200 times.
✗ Branch 8 not taken.
✓ Branch 3 taken 1 times.
|
232573 | for (const auto& element : elements(feBasis.gridView())) |
116 | { | ||
117 |
1/2✓ Branch 1 taken 77213 times.
✗ Branch 2 not taken.
|
77526 | localView.bind(element); |
118 | |||
119 | 77526 | const auto& finiteElement = localView.tree().finiteElement(); | |
120 | 77526 | const auto numLocalDofs = finiteElement.localBasis().size(); | |
121 |
2/2✓ Branch 0 taken 195139 times.
✓ Branch 1 taken 77213 times.
|
274904 | for (std::size_t i = 0; i < numLocalDofs; i++) |
122 | { | ||
123 | 197378 | const auto dofIdxI = localView.index(i); | |
124 |
2/2✓ Branch 0 taken 678817 times.
✓ Branch 1 taken 195139 times.
|
894112 | for (std::size_t j = 0; j < numLocalDofs; j++) |
125 | { | ||
126 |
1/2✓ Branch 1 taken 678817 times.
✗ Branch 2 not taken.
|
696734 | const auto dofIdxJ = localView.index(j); |
127 |
1/2✓ Branch 1 taken 678817 times.
✗ Branch 2 not taken.
|
696734 | pattern.add(dofIdxI, dofIdxJ); |
128 | } | ||
129 | } | ||
130 | } | ||
131 | |||
132 | 21 | return pattern; | |
133 | 21 | } | |
134 | |||
135 | /*! | ||
136 | * \ingroup Assembly | ||
137 | * \brief Helper function to generate Jacobian pattern for finite element scheme | ||
138 | * \note This interface is for compatibility with the other schemes. The pattern | ||
139 | * in fem is the same independent of the time discretization scheme. | ||
140 | */ | ||
141 | template<bool isImplicit, class GridGeometry, | ||
142 | typename std::enable_if_t<(GridGeometry::discMethod == DiscretizationMethods::fem), int> = 0> | ||
143 | Dune::MatrixIndexSet getJacobianPattern(const GridGeometry& gridGeometry) | ||
144 | { return getFEJacobianPattern(gridGeometry.feBasis()); } | ||
145 | |||
146 | /*! | ||
147 | * \ingroup Assembly | ||
148 | * \brief Helper function to generate Jacobian pattern for the face-centered methods | ||
149 | */ | ||
150 | template<bool isImplicit, class GridGeometry, | ||
151 | typename std::enable_if_t<(GridGeometry::discMethod == DiscretizationMethods::fcstaggered), int> = 0> | ||
152 | 78 | Dune::MatrixIndexSet getJacobianPattern(const GridGeometry& gridGeometry) | |
153 | { | ||
154 | // resize the jacobian and the residual | ||
155 | 78 | const auto numDofs = gridGeometry.numDofs(); | |
156 | 78 | Dune::MatrixIndexSet pattern(numDofs, numDofs); | |
157 | |||
158 |
1/2✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
|
78 | const auto& connectivityMap = gridGeometry.connectivityMap(); |
159 | 78 | auto fvGeometry = localView(gridGeometry); | |
160 | |||
161 | // set the pattern | ||
162 |
11/15✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 371431 times.
✓ Branch 5 taken 100 times.
✓ Branch 7 taken 13591 times.
✓ Branch 8 taken 3 times.
✓ Branch 10 taken 3536 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3536 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 3536 times.
✓ Branch 16 taken 6 times.
✓ Branch 6 taken 14279 times.
✓ Branch 9 taken 1935 times.
✗ Branch 3 not taken.
|
1161901 | for (const auto& element : elements(gridGeometry.gridView())) |
163 | { | ||
164 | 399304 | fvGeometry.bind(element); | |
165 |
5/5✓ Branch 1 taken 1484312 times.
✓ Branch 2 taken 68302 times.
✓ Branch 3 taken 1484312 times.
✓ Branch 4 taken 439396 times.
✓ Branch 5 taken 16138 times.
|
1939846 | for (const auto& scv : scvs(fvGeometry)) |
166 | { | ||
167 |
1/2✓ Branch 1 taken 1552614 times.
✗ Branch 2 not taken.
|
1552614 | const auto globalI = scv.dofIndex(); |
168 | 1552614 | pattern.add(globalI, globalI); | |
169 | |||
170 |
2/2✓ Branch 0 taken 10834006 times.
✓ Branch 1 taken 1552614 times.
|
12386620 | for (const auto& scvIdxJ : connectivityMap[scv.index()]) |
171 | { | ||
172 |
3/5✗ Branch 0 not taken.
✓ Branch 1 taken 10751126 times.
✓ Branch 3 taken 506822 times.
✗ Branch 4 not taken.
✓ Branch 2 taken 82880 times.
|
10834006 | const auto globalJ = fvGeometry.scv(scvIdxJ).dofIndex(); |
173 | 10834006 | pattern.add(globalI, globalJ); | |
174 | |||
175 |
2/2✓ Branch 0 taken 334548 times.
✓ Branch 1 taken 10499458 times.
|
10834006 | if (gridGeometry.isPeriodic()) |
176 | { | ||
177 |
1/2✓ Branch 0 taken 1650 times.
✗ Branch 1 not taken.
|
334548 | if (gridGeometry.dofOnPeriodicBoundary(globalI) && globalI != globalJ) |
178 | { | ||
179 |
1/2✓ Branch 1 taken 1650 times.
✗ Branch 2 not taken.
|
1650 | const auto globalIP = gridGeometry.periodicallyMappedDof(globalI); |
180 |
1/2✓ Branch 1 taken 1650 times.
✗ Branch 2 not taken.
|
1650 | pattern.add(globalIP, globalI); |
181 | 1650 | pattern.add(globalI, globalIP); | |
182 | |||
183 |
2/2✓ Branch 0 taken 825 times.
✓ Branch 1 taken 825 times.
|
1650 | if (globalI > globalIP) |
184 | 825 | pattern.add(globalIP, globalJ); | |
185 | } | ||
186 | } | ||
187 | } | ||
188 | } | ||
189 | } | ||
190 | |||
191 | 78 | return pattern; | |
192 | ✗ | } | |
193 | |||
194 | /*! | ||
195 | * \ingroup Assembly | ||
196 | * \brief Compute the Jacobian matrix sparsity pattern for control volume finite element schemes | ||
197 | */ | ||
198 | template<bool isImplicit, class GridGeometry, | ||
199 | typename std::enable_if_t<DiscretizationMethods::isCVFE<typename GridGeometry::DiscretizationMethod>, int> = 0> | ||
200 |
1/3✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
334 | Dune::MatrixIndexSet getJacobianPattern(const GridGeometry& gridGeometry) |
201 | { | ||
202 | // resize the jacobian and the residual | ||
203 | 334 | const auto numDofs = gridGeometry.numDofs(); | |
204 |
1/2✓ Branch 2 taken 207 times.
✗ Branch 3 not taken.
|
334 | Dune::MatrixIndexSet pattern(numDofs, numDofs); |
205 | |||
206 | // matrix pattern for implicit Jacobians | ||
207 | if constexpr (isImplicit) | ||
208 | { | ||
209 | 254 | auto fvGeometry = localView(gridGeometry); | |
210 |
12/15✓ Branch 1 taken 209 times.
✓ Branch 2 taken 43346 times.
✓ Branch 4 taken 458083 times.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 54970 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 119136 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 119136 times.
✓ Branch 13 taken 51 times.
✓ Branch 16 taken 22 times.
✗ Branch 17 not taken.
✓ Branch 3 taken 10056 times.
✓ Branch 6 taken 314505 times.
✓ Branch 9 taken 943 times.
|
1963367 | for (const auto& element : elements(gridGeometry.gridView())) |
211 | { | ||
212 |
1/2✓ Branch 1 taken 534838 times.
✗ Branch 2 not taken.
|
905144 | fvGeometry.bindElement(element); |
213 |
2/2✓ Branch 0 taken 2365716 times.
✓ Branch 1 taken 620406 times.
|
4365700 | for (const auto& scv : scvs(fvGeometry)) |
214 | { | ||
215 | 3460556 | const auto globalI = scv.dofIndex(); | |
216 |
3/4✓ Branch 1 taken 9831894 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9831894 times.
✓ Branch 4 taken 2365716 times.
|
17744974 | for (const auto& scvJ : scvs(fvGeometry)) |
217 | { | ||
218 |
1/2✓ Branch 1 taken 9831894 times.
✗ Branch 2 not taken.
|
14284418 | const auto globalJ = scvJ.dofIndex(); |
219 | 14284418 | pattern.add(globalI, globalJ); | |
220 | |||
221 |
2/2✓ Branch 0 taken 160000 times.
✓ Branch 1 taken 8607986 times.
|
14284418 | if (gridGeometry.isPeriodic()) |
222 | { | ||
223 |
2/2✓ Branch 0 taken 1200 times.
✓ Branch 1 taken 400 times.
|
160000 | if (gridGeometry.dofOnPeriodicBoundary(globalI) && globalI != globalJ) |
224 | { | ||
225 |
1/2✓ Branch 1 taken 1200 times.
✗ Branch 2 not taken.
|
1200 | const auto globalIP = gridGeometry.periodicallyMappedDof(globalI); |
226 |
1/2✓ Branch 1 taken 1200 times.
✗ Branch 2 not taken.
|
1200 | pattern.add(globalIP, globalI); |
227 | 1200 | pattern.add(globalI, globalIP); | |
228 | |||
229 |
2/2✓ Branch 0 taken 600 times.
✓ Branch 1 taken 600 times.
|
1200 | if (globalI > globalIP) |
230 | 600 | pattern.add(globalIP, globalJ); | |
231 | } | ||
232 | } | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | 206 | } | |
237 | |||
238 | // matrix pattern for explicit Jacobians -> diagonal matrix | ||
239 | else | ||
240 | { | ||
241 |
2/2✓ Branch 1 taken 6404 times.
✓ Branch 2 taken 4 times.
|
7612 | for (unsigned int globalI = 0; globalI < numDofs; ++globalI) |
242 | 7606 | pattern.add(globalI, globalI); | |
243 | } | ||
244 | |||
245 | 334 | return pattern; | |
246 | ✗ | } | |
247 | |||
248 | |||
249 | } // namespace Dumux | ||
250 | |||
251 | #endif | ||
252 |