GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/assembly/partialreassembler.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 115 156 73.7%
Functions: 32 1126 2.8%
Branches: 128 323 39.6%

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 Assembly
10 * \brief Detects which entries in the Jacobian have to be recomputed
11 */
12 #ifndef DUMUX_PARTIAL_REASSEMBLER_HH
13 #define DUMUX_PARTIAL_REASSEMBLER_HH
14
15 #include <algorithm>
16 #include <vector>
17
18 #include <dune/grid/common/gridenums.hh>
19 #include <dune/istl/multitypeblockvector.hh>
20
21 #include <dumux/io/format.hh>
22 #include <dumux/common/typetraits/isvalid.hh>
23 #include <dumux/discretization/method.hh>
24 #include <dumux/parallel/vectorcommdatahandle.hh>
25 #include <dumux/common/gridcapabilities.hh>
26
27 #include "entitycolor.hh"
28
29 namespace Dumux {
30
31 class DefaultPartialReassembler
32 {
33 public:
34 template<typename... Args>
35 DefaultPartialReassembler(Args&&... args)
36 { DUNE_THROW(Dune::InvalidStateException, "DefaultPartialReassembler should be never constructed!"); }
37
38 template<typename... Args>
39 void report(Args&&... args) {}
40
41 template<typename... Args>
42 void resetJacobian(Args&&... args) const {}
43
44 template<typename... Args>
45 void computeColors(Args&&... args) {}
46
47 template<typename... Args>
48 void resetColors(Args&&... args) {}
49
50 EntityColor dofColor(size_t idx) const
51 { return EntityColor::red; }
52
53 EntityColor elementColor(size_t idx) const
54 { return EntityColor::red; }
55
56 EntityColor vertexColor(size_t idx) const
57 { return EntityColor::red; }
58 };
59
60 //! the partial reassembler engine specialized for discretization methods
61 template<class Assembler, class DiscretizationMethod>
62 class PartialReassemblerEngine
63 {
64 public:
65 PartialReassemblerEngine(const Assembler&)
66 { DUNE_THROW(Dune::NotImplemented, "PartialReassembler for this discretization method!"); }
67
68 EntityColor elementColor(size_t idx) const
69 { return EntityColor::red; }
70
71 EntityColor dofColor(size_t idx) const
72 { return EntityColor::red; }
73
74 template<typename... Args>
75 std::size_t computeColors(Args&&... args) { return 0; }
76
77 template<typename... Args>
78 void resetJacobian(Args&&... args) const {}
79
80 template<typename... Args>
81 void resetColors(Args&&... args) {}
82 };
83
84 /*!
85 * \ingroup Assembly
86 * \brief The partial reassembler engine specialized for the box method
87 */
88 template<class Assembler>
89 class PartialReassemblerEngine<Assembler, DiscretizationMethods::Box>
90 {
91 using Scalar = typename Assembler::Scalar;
92 using GridGeometry = typename Assembler::GridGeometry;
93 using JacobianMatrix = typename Assembler::JacobianMatrix;
94 using VertexMapper = typename GridGeometry::VertexMapper;
95 static constexpr int dim = GridGeometry::GridView::dimension;
96
97 public:
98 5 PartialReassemblerEngine(const Assembler& assembler)
99 5 : elementColor_(assembler.gridGeometry().elementMapper().size(), EntityColor::red)
100
6/20
✗ Branch 4 not taken.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 5 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 5 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 5 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 5 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
20 , vertexColor_(assembler.gridGeometry().vertexMapper().size(), EntityColor::red)
101 5 {}
102
103 // returns number of green elements
104 1522 std::size_t computeColors(const Assembler& assembler,
105 const std::vector<Scalar>& distanceFromLastLinearization,
106 Scalar threshold)
107 {
108 1522 const auto& gridGeometry = assembler.gridGeometry();
109 1522 const auto& gridView = gridGeometry.gridView();
110 1522 const auto& elementMapper = gridGeometry.elementMapper();
111 1522 const auto& vertexMapper = gridGeometry.vertexMapper();
112
113 // set all vertices to green
114 3044 vertexColor_.assign(vertexColor_.size(), EntityColor::green);
115
116 // mark the red vertices
117
4/4
✓ Branch 0 taken 495308 times.
✓ Branch 1 taken 1522 times.
✓ Branch 2 taken 495308 times.
✓ Branch 3 taken 1522 times.
496830 for (unsigned int i = 0; i < vertexColor_.size(); ++i)
118 {
119 using std::max;
120
4/4
✓ Branch 0 taken 271032 times.
✓ Branch 1 taken 224276 times.
✓ Branch 2 taken 271032 times.
✓ Branch 3 taken 224276 times.
990616 if (distanceFromLastLinearization[i] > threshold)
121 // mark vertex as red if discrepancy is larger than
122 // the relative tolerance
123 542064 vertexColor_[i] = EntityColor::red;
124 }
125
126 // Mark all red elements
127
1/14
✓ Branch 1 taken 453834 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
453834 for (const auto& element : elements(gridView))
128 {
129 // find out whether the current element features a red vertex
130 bool isRed = false;
131
132 int numVertices = element.subEntities(dim);
133
134
2/2
✓ Branch 0 taken 1040161 times.
✓ Branch 1 taken 185616 times.
1225777 for (int i = 0; i < numVertices; ++i) {
135
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
1040161 int globalI = vertexMapper.subIndex(element, i, dim);
136
137
4/4
✓ Branch 0 taken 773465 times.
✓ Branch 1 taken 266696 times.
✓ Branch 2 taken 773465 times.
✓ Branch 3 taken 266696 times.
2080322 if (vertexColor_[globalI] == EntityColor::red) {
138 isRed = true;
139 break;
140 }
141 }
142
143
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
452312 int eIdx = elementMapper.index(element);
144 // if a vertex is red, the element color is also red, otherwise green
145
2/2
✓ Branch 0 taken 266696 times.
✓ Branch 1 taken 185616 times.
452312 if (isRed)
146 533392 elementColor_[eIdx] = EntityColor::red;
147 else
148 371232 elementColor_[eIdx] = EntityColor::green;
149 }
150
151 // mark orange vertices
152
1/14
✓ Branch 1 taken 453834 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
906146 for (const auto& element : elements(gridView))
153 {
154
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
452312 int eIdx = elementMapper.index(element);
155
156 // only red elements tint vertices yellow
157
4/4
✓ Branch 0 taken 266696 times.
✓ Branch 1 taken 185616 times.
✓ Branch 2 taken 266696 times.
✓ Branch 3 taken 185616 times.
904624 if (elementColor_[eIdx] == EntityColor::red)
158 {
159 int numVertices = element.subEntities(dim);
160
161
2/2
✓ Branch 0 taken 1066784 times.
✓ Branch 1 taken 266696 times.
1333480 for (int i = 0; i < numVertices; ++i) {
162
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
1066784 int globalI = vertexMapper.subIndex(element, i, dim);
163
164 // red vertices don't become orange
165
4/4
✓ Branch 0 taken 75465 times.
✓ Branch 1 taken 991319 times.
✓ Branch 2 taken 75465 times.
✓ Branch 3 taken 991319 times.
2133568 if (vertexColor_[globalI] != EntityColor::red)
166 75465 vertexColor_[globalI] = EntityColor::orange;
167 }
168 }
169 }
170
171 // at this point we communicate the yellow vertices to the
172 // neighboring processes because a neighbor process may not see
173 // the red vertex for yellow border vertices
174 VectorCommDataHandleMin<VertexMapper, std::vector<EntityColor>, dim>
175 1522 minHandle(vertexMapper, vertexColor_);
176 if constexpr (Detail::canCommunicate<typename GridGeometry::GridView::Traits::Grid, dim>)
177 1522 gridView.communicate(minHandle,
178 Dune::InteriorBorder_InteriorBorder_Interface,
179 Dune::ForwardCommunication);
180 else
181 DUNE_THROW(Dune::InvalidStateException, "Cannot call computeColors on multiple processes for a grid that cannot communicate codim-" << dim << "-entities.");
182
183 // mark yellow elements
184
1/14
✓ Branch 1 taken 453834 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
906146 for (const auto& element : elements(gridView))
185 {
186
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
452312 int eIdx = elementMapper.index(element);
187
188 // only treat non-red elements
189
4/4
✓ Branch 0 taken 185616 times.
✓ Branch 1 taken 266696 times.
✓ Branch 2 taken 185616 times.
✓ Branch 3 taken 266696 times.
904624 if (elementColor_[eIdx] != EntityColor::red)
190 {
191 // check whether the element features a orange vertex
192 bool isOrange = false;
193 int numVertices = element.subEntities(dim);
194
195
2/2
✓ Branch 0 taken 684119 times.
✓ Branch 1 taken 158770 times.
842889 for (int i = 0; i < numVertices; ++i) {
196
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
684119 int globalI = vertexMapper.subIndex(element, i, dim);
197
198
4/4
✓ Branch 0 taken 657273 times.
✓ Branch 1 taken 26846 times.
✓ Branch 2 taken 657273 times.
✓ Branch 3 taken 26846 times.
1368238 if (vertexColor_[globalI] == EntityColor::orange) {
199 isOrange = true;
200 break;
201 }
202 }
203
204
2/2
✓ Branch 0 taken 26846 times.
✓ Branch 1 taken 158770 times.
185616 if (isOrange)
205 53692 elementColor_[eIdx] = EntityColor::yellow;
206 }
207 }
208
209 // change orange vertices to yellow ones if it has at least
210 // one green element as a neighbor
211
1/14
✓ Branch 1 taken 453834 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
906146 for (const auto& element : elements(gridView))
212 {
213
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
452312 int eIdx = elementMapper.index(element);
214
215 // only green elements are considered
216
4/4
✓ Branch 0 taken 158770 times.
✓ Branch 1 taken 293542 times.
✓ Branch 2 taken 158770 times.
✓ Branch 3 taken 293542 times.
904624 if (elementColor_[eIdx] == EntityColor::green)
217 {
218 int numVertices = element.subEntities(dim);
219
220
2/2
✓ Branch 0 taken 635080 times.
✓ Branch 1 taken 158770 times.
793850 for (int i = 0; i < numVertices; ++i) {
221
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
635080 int globalI = vertexMapper.subIndex(element, i, dim);
222
223 // if a vertex is orange, recolor it to yellow
224
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 635080 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 635080 times.
1270160 if (vertexColor_[globalI] == EntityColor::orange)
225 vertexColor_[globalI] = EntityColor::yellow;
226 }
227 }
228 }
229
230 // demote the border orange vertices
231 VectorCommDataHandleMax<VertexMapper, std::vector<EntityColor>, dim>
232 1522 maxHandle(vertexMapper, vertexColor_);
233 if constexpr (Detail::canCommunicate<typename GridGeometry::GridView::Traits::Grid, dim>)
234 1522 gridView.communicate(maxHandle,
235 Dune::InteriorBorder_InteriorBorder_Interface,
236 Dune::ForwardCommunication);
237 else
238 DUNE_THROW(Dune::InvalidStateException, "Cannot call computeColors on multiple processes for a grid that cannot communicate codim-" << dim << "-entities.");
239
240 // promote the remaining orange vertices to red
241
4/4
✓ Branch 0 taken 495308 times.
✓ Branch 1 taken 1522 times.
✓ Branch 2 taken 495308 times.
✓ Branch 3 taken 1522 times.
498352 for (unsigned int i=0; i < vertexColor_.size(); ++i) {
242 // if a vertex is green or yellow don't do anything
243
5/6
✓ Branch 0 taken 307576 times.
✓ Branch 1 taken 187732 times.
✓ Branch 2 taken 307576 times.
✓ Branch 3 taken 187732 times.
✓ Branch 4 taken 307576 times.
✗ Branch 5 not taken.
990616 if (vertexColor_[i] == EntityColor::green || vertexColor_[i] == EntityColor::yellow)
244 continue;
245
246 // set the vertex to red
247 307576 vertexColor_[i] = EntityColor::red;
248 }
249
250 // count green elements
251 4566 return std::count_if(elementColor_.begin(), elementColor_.end(),
252 1522 [](EntityColor c){ return c == EntityColor::green; });
253 }
254
255 1522 void resetJacobian(Assembler& assembler) const
256 {
257 1522 auto& jacobian = assembler.jacobian();
258
259 // loop over all dofs
260
2/2
✓ Branch 0 taken 495308 times.
✓ Branch 1 taken 1522 times.
496830 for (unsigned int rowIdx = 0; rowIdx < jacobian.N(); ++rowIdx)
261 {
262 // reset all entries corresponding to a non-green vertex
263
4/4
✓ Branch 0 taken 372951 times.
✓ Branch 1 taken 122357 times.
✓ Branch 2 taken 372951 times.
✓ Branch 3 taken 122357 times.
990616 if (vertexColor_[rowIdx] != EntityColor::green)
264 {
265 // set all matrix entries in the row to 0
266 745902 auto colIt = jacobian[rowIdx].begin();
267 745902 const auto& colEndIt = jacobian[rowIdx].end();
268
4/4
✓ Branch 0 taken 3150528 times.
✓ Branch 1 taken 372951 times.
✓ Branch 2 taken 3150528 times.
✓ Branch 3 taken 372951 times.
7046958 for (; colIt != colEndIt; ++colIt) {
269 9451584 *colIt = 0.0;
270 }
271 }
272 }
273 1522 }
274
275 332 void resetColors()
276 {
277 664 elementColor_.assign(elementColor_.size(), EntityColor::red);
278 664 vertexColor_.assign(vertexColor_.size(), EntityColor::red);
279 332 }
280
281 EntityColor elementColor(size_t idx) const
282 904624 { return elementColor_[idx]; }
283
284 EntityColor vertexColor(size_t idx) const
285 { return vertexColor_[idx]; }
286
287 EntityColor dofColor(size_t idx) const
288 23435416 { return vertexColor_[idx]; }
289
290 private:
291 //! entity colors for partial reassembly
292 std::vector<EntityColor> elementColor_;
293 std::vector<EntityColor> vertexColor_;
294 };
295
296 /*!
297 * \ingroup Assembly
298 * \brief The partial reassembler engine specialized for the cellcentered TPFA method
299 */
300 template<class Assembler>
301 class PartialReassemblerEngine<Assembler, DiscretizationMethods::CCTpfa>
302 {
303 using Scalar = typename Assembler::Scalar;
304 using GridGeometry = typename Assembler::GridGeometry;
305 using JacobianMatrix = typename Assembler::JacobianMatrix;
306
307 public:
308 18 PartialReassemblerEngine(const Assembler& assembler)
309
1/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 18 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
72 : elementColor_(assembler.gridGeometry().elementMapper().size(), EntityColor::red)
310 {}
311
312 // returns number of green elements
313 3582 std::size_t computeColors(const Assembler& assembler,
314 const std::vector<Scalar>& distanceFromLastLinearization,
315 Scalar threshold)
316 {
317 3582 const auto& gridGeometry = assembler.gridGeometry();
318 3582 const auto& gridView = gridGeometry.gridView();
319 3582 const auto& elementMapper = gridGeometry.elementMapper();
320
321 // mark the red elements
322
4/14
✓ Branch 1 taken 5408622 times.
✓ Branch 2 taken 330 times.
✓ Branch 3 taken 131780 times.
✓ Branch 4 taken 330 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
10682542 for (const auto& element : elements(gridView))
323 {
324
0/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
5405370 int eIdx = elementMapper.index(element);
325
326
4/4
✓ Branch 0 taken 2121848 times.
✓ Branch 1 taken 3283522 times.
✓ Branch 2 taken 2121848 times.
✓ Branch 3 taken 3283522 times.
10810740 if (distanceFromLastLinearization[eIdx] > threshold)
327 {
328 // mark element as red if discrepancy is larger than
329 // the relative tolerance
330 4243696 elementColor_[eIdx] = EntityColor::red;
331 }
332 else
333 {
334 6567044 elementColor_[eIdx] = EntityColor::green;
335 }
336 }
337
338 // mark the neighbors also red
339 3582 const auto& connectivityMap = gridGeometry.connectivityMap();
340
4/4
✓ Branch 0 taken 3582 times.
✓ Branch 1 taken 5405370 times.
✓ Branch 2 taken 3582 times.
✓ Branch 3 taken 5405370 times.
5408952 for (unsigned eIdx = 0; eIdx < elementColor_.size(); ++eIdx)
341 {
342
4/4
✓ Branch 0 taken 3283522 times.
✓ Branch 1 taken 2121848 times.
✓ Branch 2 taken 3283522 times.
✓ Branch 3 taken 2121848 times.
10810740 if (elementColor_[eIdx] == EntityColor::red)
343 continue; // element is red already!
344
345
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3283522 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3283522 times.
6567044 if (distanceFromLastLinearization[eIdx] > threshold)
346 {
347 for (const auto& connectedDof : connectivityMap[eIdx])
348 elementColor_[connectedDof.globalJ] = EntityColor::red;
349 }
350 }
351
352 // count green elements
353 3582 return std::count_if(elementColor_.begin(), elementColor_.end(),
354 3582 [](EntityColor c){return c == EntityColor::green;});
355
356 }
357
358 3582 void resetJacobian(Assembler& assembler) const
359 {
360 3582 auto& jacobian = assembler.jacobian();
361 7164 const auto& connectivityMap = assembler.gridGeometry().connectivityMap();
362
363 // loop over all dofs
364
2/2
✓ Branch 0 taken 5405370 times.
✓ Branch 1 taken 3582 times.
5408952 for (unsigned int colIdx = 0; colIdx < jacobian.M(); ++colIdx)
365 {
366 // reset all entries corresponding to a non-green element
367
4/4
✓ Branch 0 taken 3477806 times.
✓ Branch 1 taken 1927564 times.
✓ Branch 2 taken 3477806 times.
✓ Branch 3 taken 1927564 times.
10810740 if (elementColor_[colIdx] != EntityColor::green)
368 {
369 // set all matrix entries in the column to 0
370 6955612 jacobian[colIdx][colIdx] = 0;
371
4/4
✓ Branch 0 taken 13420571 times.
✓ Branch 1 taken 3477806 times.
✓ Branch 2 taken 13420571 times.
✓ Branch 3 taken 3477806 times.
40752366 for (const auto& dataJ : connectivityMap[colIdx])
372 40261713 jacobian[dataJ.globalJ][colIdx] = 0;
373 }
374 }
375 3582 }
376
377 void resetColors()
378 {
379 961 elementColor_.assign(elementColor_.size(), EntityColor::red);
380 }
381
382 EntityColor elementColor(size_t idx) const
383 10810740 { return elementColor_[idx]; }
384
385 EntityColor dofColor(size_t idx) const
386 10810740 { return elementColor_[idx]; }
387
388 private:
389 //! entity colors for partial reassembly
390 std::vector<EntityColor> elementColor_;
391 };
392
393 /*!
394 * \ingroup Assembly
395 * \brief The partial reassembler engine specialized for the cellcentered MPFA method
396 */
397 template<class Assembler>
398 class PartialReassemblerEngine<Assembler, DiscretizationMethods::CCMpfa>
399 : public PartialReassemblerEngine<Assembler, DiscretizationMethods::CCTpfa>
400 {
401 using ParentType = PartialReassemblerEngine<Assembler, DiscretizationMethods::CCTpfa>;
402 public:
403 2 using ParentType::ParentType;
404 };
405
406 //! helper struct to determine whether the an engine class has vertex colors
407 struct hasVertexColor
408 {
409 template<class Engine>
410 auto operator()(Engine&& e) -> decltype(e.vertexColor(0)) {}
411 };
412
413 /*!
414 * \ingroup Assembly
415 * \brief detects which entries in the Jacobian have to be recomputed
416 * \tparam TypeTag The TypeTag
417 */
418 template<class Assembler>
419 class PartialReassembler
420 {
421 using Scalar = typename Assembler::Scalar;
422 using GridGeometry = typename Assembler::GridGeometry;
423 using JacobianMatrix = typename Assembler::JacobianMatrix;
424 using VertexMapper = typename GridGeometry::VertexMapper;
425
426 using DiscretizationMethod = typename GridGeometry::DiscretizationMethod;
427 using Engine = PartialReassemblerEngine<Assembler, DiscretizationMethod>;
428
429 public:
430
431 /*!
432 * \brief constructor
433 * \param assembler the assembler
434 */
435 23 PartialReassembler(const Assembler& assembler)
436 : engine_(assembler)
437
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
23 , greenElems_(0)
438 {
439
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
23 const auto& gridGeometry = assembler.gridGeometry();
440
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
46 totalElems_ = gridGeometry.elementMapper().size();
441
3/7
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 23 times.
✗ Branch 6 not taken.
46 totalElems_ = gridGeometry.gridView().comm().sum(totalElems_);
442 23 }
443
444 /*!
445 * \brief Determine the colors of entities for partial reassembly.
446 *
447 * The following approach is used:
448 *
449 * - Set all elements to 'green'
450 * - Mark all elements as 'red' which exhibit an relative error above
451 * the tolerance
452 * - Mark all neighbors of 'red' elements also 'red'
453 *
454 * \param assembler the assembler
455 * \param distanceFromLastLinearization The distance from the last linearization
456 * \param threshold Reassemble only if the distance from the last
457 * linearization is above this value.
458 */
459 void computeColors(const Assembler& assembler,
460 const std::vector<Scalar>& distanceFromLastLinearization,
461 Scalar threshold)
462 {
463 5104 greenElems_ = engine_.computeColors(assembler, distanceFromLastLinearization, threshold);
464 }
465
466 void resetColors()
467 {
468 1293 engine_.resetColors();
469 }
470
471 void resetJacobian(Assembler& assembler) const
472 {
473 5104 engine_.resetJacobian(assembler);
474 }
475
476 /*!
477 * \brief called by the assembler after successful assembly
478 */
479 template <class Communication>
480 5104 void report(const Communication& comm, std::ostream& outStream)
481 {
482
4/4
✓ Branch 0 taken 2854 times.
✓ Branch 1 taken 2250 times.
✓ Branch 2 taken 2854 times.
✓ Branch 3 taken 2250 times.
10208 if (comm.size() > 1)
483 2854 greenElems_ = comm.sum(greenElems_);
484
485 5104 const auto reassembledElems = totalElems_ - greenElems_;
486 5104 const auto width = Fmt::formatted_size("{}", totalElems_);
487
2/6
✓ Branch 2 taken 5104 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5104 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
5104 outStream << Fmt::format(", reassembled {:{}} ({:3}%) elements",
488 5104 reassembledElems, width, 100*reassembledElems/totalElems_);
489 5104 }
490
491 EntityColor elementColor(size_t idx) const
492
4/8
✓ Branch 0 taken 2029176 times.
✓ Branch 1 taken 3828506 times.
✓ Branch 2 taken 2029176 times.
✓ Branch 3 taken 3828506 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
11715364 { return engine_.elementColor(idx); }
493
494 EntityColor dofColor(size_t idx) const
495
8/8
✓ Branch 0 taken 12971536 times.
✓ Branch 1 taken 3656234 times.
✓ Branch 2 taken 12971536 times.
✓ Branch 3 taken 3656234 times.
✓ Branch 4 taken 307576 times.
✓ Branch 5 taken 187732 times.
✓ Branch 6 taken 307576 times.
✓ Branch 7 taken 187732 times.
34246156 { return engine_.dofColor(idx); }
496
497 template<bool enable = decltype(isValid(hasVertexColor()).template check<Engine>())::value,
498 typename std::enable_if_t<enable, int> = 0>
499 EntityColor vertexColor(size_t idx) const
500 { return engine_.vertexColor(idx); }
501
502 private:
503 Engine engine_;
504 size_t totalElems_;
505 size_t greenElems_;
506 };
507
508 } // namespace Dumux
509
510 #endif
511