GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/porousmediumflow/2p/griddatatransfer.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 108 108 100.0%
Functions: 24 24 100.0%
Branches: 150 238 63.0%

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 TwoPModel
10 * \brief Performs the transfer of data on a grid from before to after adaptation.
11 */
12
13 #ifndef DUMUX_TWOP_GRIDDATA_TRANSFER_HH
14 #define DUMUX_TWOP_GRIDDATA_TRANSFER_HH
15
16 #include <memory>
17
18 #include <dune/grid/common/partitionset.hh>
19 #include <dune/grid/utility/persistentcontainer.hh>
20
21 #include <dumux/common/properties.hh>
22
23 #include <dumux/discretization/method.hh>
24 #include <dumux/discretization/extrusion.hh>
25 #include <dumux/discretization/elementsolution.hh>
26 #include <dumux/geometry/volume.hh>
27 #include <dumux/porousmediumflow/2p/formulation.hh>
28 #include <dumux/adaptive/griddatatransfer.hh>
29
30 namespace Dumux {
31
32 /*!
33 * \ingroup TwoPModel
34 * \brief Class performing the transfer of data on a grid from before to after adaptation.
35 */
36 template<class TypeTag>
37 class TwoPGridDataTransfer : public GridDataTransfer<GetPropType<TypeTag, Properties::Grid>>
38 {
39 using Grid = GetPropType<TypeTag, Properties::Grid>;
40 using ParentType = GridDataTransfer<Grid>;
41 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
42 using Problem = GetPropType<TypeTag, Properties::Problem>;
43 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
44 using GridView = typename GridGeometry::GridView;
45 using FVElementGeometry = typename GridGeometry::LocalView;
46 using SubControlVolume = typename FVElementGeometry::SubControlVolume;
47 using Extrusion = Extrusion_t<GridGeometry>;
48 using GridVariables = GetPropType<TypeTag, Properties::GridVariables>;
49 using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>;
50 using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
51 using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>;
52 using Element = typename Grid::template Codim<0>::Entity;
53 using ElementSolution = std::decay_t<decltype(elementSolution(std::declval<Element>(),
54 std::declval<SolutionVector>(),
55 std::declval<GridGeometry>()))>;
56 using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
57 using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>;
58 using Indices = typename ModelTraits::Indices;
59
60 struct AdaptedValues
61 {
62 65 AdaptedValues() : associatedMass(0.0) {}
63 ElementSolution u;
64 int count = 0;
65 PrimaryVariables associatedMass;
66 bool wasLeaf = false;
67 };
68
69 using PersistentContainer = Dune::PersistentContainer<Grid, AdaptedValues>;
70
71 static constexpr int dim = Grid::dimension;
72 static constexpr int dimWorld = Grid::dimensionworld;
73 static constexpr bool isBox = GetPropType<TypeTag, Properties::GridGeometry>::discMethod == DiscretizationMethods::box;
74
75 // saturation primary variable index
76 enum { saturationIdx = Indices::saturationIdx };
77
78 // phase indices
79 enum
80 {
81 phase0Idx = FluidSystem::phase0Idx,
82 phase1Idx = FluidSystem::phase1Idx,
83 };
84
85 // formulations
86 static constexpr auto p0s1 = TwoPFormulation::p0s1;
87 static constexpr auto p1s0 = TwoPFormulation::p1s0;
88
89 // the formulation that is actually used
90 static constexpr auto formulation = ModelTraits::priVarFormulation();
91
92 // This won't work (mass conservative) for compressible fluids
93 static_assert(!FluidSystem::isCompressible(phase0Idx)
94 && !FluidSystem::isCompressible(phase1Idx),
95 "This adaption helper is only mass conservative for incompressible fluids!");
96
97 // check if the used formulation is implemented here
98 static_assert(formulation == p0s1 || formulation == p1s0, "Chosen formulation not known to the TwoPGridDataTransfer");
99
100 public:
101 /*!
102 * \brief Constructor
103 *
104 * \param problem The DuMuX problem to be solved
105 * \param gridGeometry The finite volume grid geometry
106 * \param gridVariables The secondary variables on the grid
107 * \param sol The solution (primary variables) on the grid
108 */
109 5 TwoPGridDataTransfer(std::shared_ptr<const Problem> problem,
110 std::shared_ptr<GridGeometry> gridGeometry,
111 std::shared_ptr<const GridVariables> gridVariables,
112 SolutionVector& sol)
113 : ParentType()
114 , problem_(problem)
115 , gridGeometry_(gridGeometry)
116 , gridVariables_(gridVariables)
117 , sol_(sol)
118
4/14
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5 times.
✓ Branch 10 taken 5 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
20 , adaptionMap_(gridGeometry->gridView().grid(), 0)
119 5 {}
120
121 /*!
122 * \brief Stores primary variables and additional data
123 *
124 * To reconstruct the solution in father elements, problem properties might
125 * need to be accessed. From upper level on downwards, the old solution is stored
126 * into a container object, before the grid is adapted. Father elements hold averaged
127 * information from the son cells for the case of the sons being coarsened.
128 */
129 15 void store(const Grid& grid) override
130 {
131 30 adaptionMap_.resize();
132
133
3/3
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 2 times.
55 for (auto level = grid.maxLevel(); level >= 0; level--)
134 {
135
2/4
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
85 auto fvGeometry = localView(*gridGeometry_);
136
13/18
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15530 times.
✓ Branch 7 taken 40 times.
✓ Branch 8 taken 15530 times.
✓ Branch 9 taken 5 times.
✓ Branch 10 taken 35 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 112414 times.
✓ Branch 13 taken 35 times.
✓ Branch 14 taken 96884 times.
✓ Branch 15 taken 35 times.
✓ Branch 17 taken 96884 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 96884 times.
✗ Branch 21 not taken.
112529 for (const auto& element : elements(grid.levelGridView(level)))
137 {
138 // get map entry
139 112414 auto& adaptedValues = adaptionMap_[element];
140
141 // put values in the map for leaf elements
142
5/5
✓ Branch 0 taken 12372 times.
✓ Branch 1 taken 100042 times.
✓ Branch 2 taken 12372 times.
✓ Branch 3 taken 80813 times.
✓ Branch 4 taken 19229 times.
127944 if (element.isLeaf())
143 {
144
1/2
✓ Branch 1 taken 90027 times.
✗ Branch 2 not taken.
90027 fvGeometry.bindElement(element);
145
146 // store current element solution
147
2/4
✓ Branch 1 taken 90027 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 90027 times.
✗ Branch 5 not taken.
180054 adaptedValues.u = ElementSolution(element, sol_, *gridGeometry_);
148
149 // compute mass in the scvs
150
4/4
✓ Branch 0 taken 127125 times.
✓ Branch 1 taken 90027 times.
✓ Branch 2 taken 49470 times.
✓ Branch 3 taken 12372 times.
356649 for (const auto& scv : scvs(fvGeometry))
151 {
152
1/2
✓ Branch 1 taken 127125 times.
✗ Branch 2 not taken.
127125 VolumeVariables volVars;
153
2/4
✓ Branch 1 taken 127125 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 127125 times.
✗ Branch 5 not taken.
254250 volVars.update(adaptedValues.u, *problem_, element, scv);
154
155 254250 const auto poreVolume = Extrusion::volume(fvGeometry, scv)*volVars.porosity();
156 381375 adaptedValues.associatedMass[phase1Idx] += poreVolume * volVars.density(phase1Idx) * volVars.saturation(phase1Idx);
157 508500 adaptedValues.associatedMass[phase0Idx] += poreVolume * volVars.density(phase0Idx) * volVars.saturation(phase0Idx);
158 }
159
160 // leaf elements always start with count = 1
161 90027 adaptedValues.count = 1;
162 90027 adaptedValues.wasLeaf = true;
163 }
164 // Average in father elements
165
5/5
✓ Branch 0 taken 12458 times.
✓ Branch 1 taken 99956 times.
✓ Branch 2 taken 12458 times.
✓ Branch 3 taken 79988 times.
✓ Branch 4 taken 19968 times.
127944 if (element.level() > 0)
166 {
167
1/2
✓ Branch 1 taken 89374 times.
✗ Branch 2 not taken.
89374 auto& adaptedValuesFather = adaptionMap_[element.father()];
168 // For some grids the father element is identical to the son element.
169 // In that case averaging is not necessary.
170
2/2
✓ Branch 0 taken 89322 times.
✓ Branch 1 taken 52 times.
89374 if(&adaptedValues != &adaptedValuesFather)
171 76916 storeAdaptionValues(adaptedValues, adaptedValuesFather);
172 }
173
174 // The vertices of the non-leaf elements exist on the leaf as well
175 // This element solution constructor uses the vertex mapper to obtain
176 // the privars at the vertices, thus, this works for non-leaf elements!
177
4/4
✓ Branch 0 taken 3158 times.
✓ Branch 1 taken 12372 times.
✓ Branch 2 taken 3158 times.
✓ Branch 3 taken 12372 times.
31060 if(isBox && !element.isLeaf())
178
2/4
✓ Branch 1 taken 3158 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3158 times.
✗ Branch 5 not taken.
6316 adaptedValues.u = ElementSolution(element, sol_, *gridGeometry_);
179 }
180 }
181 15 }
182
183 /*!
184 * \brief Reconstruct missing primary variables (where elements are created/deleted)
185 *
186 * To reconstruct the solution in father elements, problem properties might
187 * need to be accessed.
188 * Starting from the lowest level, the old solution is mapped on the new grid:
189 * Where coarsened, new cells get information from old father element.
190 * Where refined, a new solution is reconstructed from the old father cell,
191 * and then a new son is created. That is then stored into the general data
192 * structure (AdaptedValues).
193 */
194 15 void reconstruct(const Grid& grid) override
195 {
196 45 gridGeometry_->update(grid.leafGridView());
197 15 reconstruct_();
198 15 }
199
200 private:
201
202 15 void reconstruct_()
203 {
204 // resize stuff (grid might have changed)
205 30 adaptionMap_.resize();
206 30 sol_.resize(gridGeometry_->numDofs());
207
208 // vectors storing the mass associated with each vertex, when using the box method
209
1/5
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
15 std::vector<Scalar> massCoeff;
210
2/5
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
30 std::vector<Scalar> associatedMass;
211
212 if(isBox)
213 {
214
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
6 massCoeff.resize(gridGeometry_->numDofs(), 0.0);
215
3/8
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
6 associatedMass.resize(gridGeometry_->numDofs(), 0.0);
216 }
217
218 // iterate over leaf and reconstruct the solution
219
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
45 auto fvGeometry = localView(*gridGeometry_);
220
17/24
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 15 times.
✓ Branch 7 taken 15 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 15 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 11283 times.
✓ Branch 13 taken 15 times.
✓ Branch 14 taken 11283 times.
✓ Branch 15 taken 2 times.
✓ Branch 16 taken 13 times.
✓ Branch 17 taken 11283 times.
✓ Branch 18 taken 75234 times.
✓ Branch 19 taken 13 times.
✓ Branch 20 taken 86517 times.
✓ Branch 21 taken 13 times.
✓ Branch 23 taken 75234 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 75234 times.
✗ Branch 27 not taken.
86562 for (const auto& element : elements(gridGeometry_->gridView().grid().leafGridView(), Dune::Partitions::interior))
221 {
222
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 86517 times.
✓ Branch 2 taken 58794 times.
✓ Branch 3 taken 23711 times.
✓ Branch 4 taken 4012 times.
86517 if (!element.isNew())
223 {
224 66065 const auto& adaptedValues = adaptionMap_[element];
225
1/2
✓ Branch 1 taken 66065 times.
✗ Branch 2 not taken.
66065 fvGeometry.bindElement(element);
226
227 // obtain element solution from map (divide by count!)
228 66065 auto elemSol = adaptedValues.u;
229 if (!isBox)
230 58794 elemSol[0] /= adaptedValues.count;
231
232
2/4
✓ Branch 1 taken 66065 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 66065 times.
✗ Branch 5 not taken.
73336 const auto elementVolume = volume(element.geometry(), Extrusion{});
233
4/4
✓ Branch 0 taken 87868 times.
✓ Branch 1 taken 66065 times.
✓ Branch 2 taken 29074 times.
✓ Branch 3 taken 7271 times.
249072 for (const auto& scv : scvs(fvGeometry))
234 {
235
1/2
✓ Branch 1 taken 87868 times.
✗ Branch 2 not taken.
87868 VolumeVariables volVars;
236
2/4
✓ Branch 1 taken 87868 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 87868 times.
✗ Branch 5 not taken.
175736 volVars.update(elemSol, *problem_, element, scv);
237
238 // write solution at dof in current solution vector
239
4/4
✓ Branch 0 taken 4917 times.
✓ Branch 1 taken 53877 times.
✓ Branch 2 taken 4917 times.
✓ Branch 3 taken 53877 times.
175736 sol_[scv.dofIndex()] = elemSol[scv.localDofIndex()];
240
241
2/2
✓ Branch 0 taken 4917 times.
✓ Branch 1 taken 53877 times.
87868 const auto dofIdxGlobal = scv.dofIndex();
242 // For cc schemes, overwrite the saturation by a mass conservative one here
243 if (!isBox)
244 {
245 // only recalculate the saturations if element hasn't been leaf before adaptation
246
2/2
✓ Branch 0 taken 4917 times.
✓ Branch 1 taken 53877 times.
58794 if (!adaptedValues.wasLeaf)
247 {
248 if (formulation == p0s1)
249 {
250 9834 sol_[dofIdxGlobal][saturationIdx] = adaptedValues.associatedMass[phase1Idx];
251 19668 sol_[dofIdxGlobal][saturationIdx] /= elementVolume * volVars.density(phase1Idx) * volVars.porosity();
252 }
253 else if (formulation == p1s0)
254 {
255 sol_[dofIdxGlobal][saturationIdx] = adaptedValues.associatedMass[phase0Idx];
256 sol_[dofIdxGlobal][saturationIdx] /= elementVolume * volVars.density(phase0Idx) * volVars.porosity();
257 }
258 }
259 }
260
261 // For the box scheme, add mass & mass coefficient to container (saturations are recalculated at the end)
262 else
263 {
264 29074 const auto scvVolume = Extrusion::volume(fvGeometry, scv);
265 if (formulation == p0s1)
266 {
267 87222 massCoeff[dofIdxGlobal] += scvVolume * volVars.density(phase1Idx) * volVars.porosity();
268 87222 associatedMass[dofIdxGlobal] += scvVolume / elementVolume * adaptedValues.associatedMass[phase1Idx];
269 }
270 else if (formulation == p1s0)
271 {
272 massCoeff[dofIdxGlobal] += scvVolume * volVars.density(phase0Idx) * volVars.porosity();
273 associatedMass[dofIdxGlobal] += scvVolume / elementVolume * adaptedValues.associatedMass[phase0Idx];
274 }
275 }
276 }
277 }
278 else
279 {
280 // value is not in map, interpolate from father element
281
3/5
✗ Branch 0 not taken.
✓ Branch 1 taken 20452 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4012 times.
✓ Branch 4 taken 16440 times.
24464 assert(element.hasFather() && "new element does not have a father element!");
282
283 // find the ancestor element that existed on the old grid already
284
1/2
✓ Branch 1 taken 20452 times.
✗ Branch 2 not taken.
36892 auto fatherElement = element.father();
285
5/9
✗ Branch 0 not taken.
✓ Branch 1 taken 20796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16784 times.
✓ Branch 4 taken 4012 times.
✓ Branch 5 taken 344 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 344 times.
✗ Branch 8 not taken.
20796 while(fatherElement.isNew() && fatherElement.level() > 0)
286
1/2
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
344 fatherElement = fatherElement.father();
287
288 if(!isBox)
289 {
290 16440 const auto& adaptedValuesFather = adaptionMap_[fatherElement];
291
292 // obtain the mass contained in father
293 16440 Scalar massFather = 0.0;
294 if (formulation == p0s1)
295 16440 massFather = adaptedValuesFather.associatedMass[phase1Idx];
296 else if (formulation == p1s0)
297 massFather = adaptedValuesFather.associatedMass[phase0Idx];
298
299 // obtain the element solution through the father
300 16440 auto elemSolSon = adaptedValuesFather.u;
301 16440 elemSolSon[0] /= adaptedValuesFather.count;
302
303
1/2
✓ Branch 1 taken 16440 times.
✗ Branch 2 not taken.
16440 fvGeometry.bindElement(element);
304
305
2/2
✓ Branch 0 taken 16440 times.
✓ Branch 1 taken 16440 times.
32880 for (const auto& scv : scvs(fvGeometry))
306 {
307
1/2
✓ Branch 1 taken 16440 times.
✗ Branch 2 not taken.
16440 VolumeVariables volVars;
308
2/4
✓ Branch 1 taken 16440 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16440 times.
✗ Branch 5 not taken.
32880 volVars.update(elemSolSon, *problem_, element, scv);
309
310 // store constructed values of son in the current solution
311
2/4
✓ Branch 1 taken 16440 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16440 times.
✗ Branch 5 not taken.
32880 sol_[scv.dofIndex()] = elemSolSon[0];
312
313 // overwrite the saturation by a mass conservative one here
314 16440 Scalar massCoeffSon = 0.0;
315 if (formulation == p0s1)
316
3/6
✓ Branch 1 taken 16440 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16440 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 16440 times.
✗ Branch 8 not taken.
49320 massCoeffSon = Extrusion::volume(fvGeometry, scv) * volVars.density(phase1Idx) * volVars.porosity();
317 else if (formulation == p1s0)
318 massCoeffSon = Extrusion::volume(fvGeometry, scv) * volVars.density(phase0Idx) * volVars.porosity();
319 32880 sol_[scv.dofIndex()][saturationIdx] =
320
3/6
✓ Branch 1 taken 16440 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16440 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 16440 times.
✗ Branch 8 not taken.
32880 ( Extrusion::volume(fvGeometry, scv)/volume(fatherElement.geometry(), Extrusion{})*massFather )/massCoeffSon;
321 }
322 }
323 else
324 {
325 4012 auto& adaptedValuesFather = adaptionMap_[fatherElement];
326
327
1/2
✓ Branch 1 taken 4012 times.
✗ Branch 2 not taken.
4012 fvGeometry.bindElement(element);
328
329 // interpolate solution in the father to the vertices of the new son
330
2/4
✓ Branch 1 taken 4012 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4012 times.
✗ Branch 5 not taken.
8024 ElementSolution elemSolSon(element, sol_, *gridGeometry_);
331 4012 const auto fatherGeometry = fatherElement.geometry();
332
4/4
✓ Branch 0 taken 15875 times.
✓ Branch 1 taken 4012 times.
✓ Branch 2 taken 15875 times.
✓ Branch 3 taken 4012 times.
39774 for (const auto& scv : scvs(fvGeometry))
333
1/2
✓ Branch 1 taken 15875 times.
✗ Branch 2 not taken.
15875 elemSolSon[scv.localDofIndex()] = evalSolution(fatherElement,
334 fatherGeometry,
335
1/2
✓ Branch 1 taken 15875 times.
✗ Branch 2 not taken.
15875 adaptedValuesFather.u,
336 scv.dofPosition());
337
338 // compute mass & mass coefficients for the scvs (saturations are recalculated at the end)
339
1/2
✓ Branch 1 taken 4012 times.
✗ Branch 2 not taken.
4012 const auto fatherElementVolume = volume(fatherGeometry, Extrusion{});
340
4/4
✓ Branch 0 taken 15875 times.
✓ Branch 1 taken 4012 times.
✓ Branch 2 taken 15875 times.
✓ Branch 3 taken 4012 times.
39774 for (const auto& scv : scvs(fvGeometry))
341 {
342
1/2
✓ Branch 1 taken 15875 times.
✗ Branch 2 not taken.
15875 VolumeVariables volVars;
343
2/4
✓ Branch 1 taken 15875 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15875 times.
✗ Branch 5 not taken.
31750 volVars.update(elemSolSon, *problem_, element, scv);
344
345 15875 const auto dofIdxGlobal = scv.dofIndex();
346 15875 const auto scvVolume = Extrusion::volume(fvGeometry, scv);
347 if (formulation == p0s1)
348 {
349 47625 massCoeff[dofIdxGlobal] += scvVolume * volVars.density(phase1Idx) * volVars.porosity();
350 31750 associatedMass[dofIdxGlobal] += scvVolume / fatherElementVolume * adaptedValuesFather.associatedMass[phase1Idx];
351 }
352 else if (formulation == p1s0)
353 {
354 massCoeff[dofIdxGlobal] += scvVolume * volVars.density(phase0Idx) * volVars.porosity();
355 associatedMass[dofIdxGlobal] += scvVolume / fatherElementVolume * adaptedValuesFather.associatedMass[phase0Idx];
356 }
357
358 // store constructed (pressure) values of son in the current solution (saturation comes later)
359 47625 sol_[dofIdxGlobal] = elemSolSon[scv.localDofIndex()];
360 }
361 }
362 }
363 }
364
365 if(isBox)
366 {
367
6/6
✓ Branch 0 taken 11457 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 11457 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 11457 times.
✓ Branch 5 taken 2 times.
34373 for(std::size_t dofIdxGlobal = 0; dofIdxGlobal < gridGeometry_->numDofs(); dofIdxGlobal++)
368 57285 sol_[dofIdxGlobal][saturationIdx] = associatedMass[dofIdxGlobal] / massCoeff[dofIdxGlobal];
369 }
370
371 // reset entries in adaptation map
372
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
30 adaptionMap_.resize( typename PersistentContainer::Value() );
373 15 adaptionMap_.shrinkToFit();
374 43 adaptionMap_.fill( typename PersistentContainer::Value() );
375
376 //! TODO: fix adaptive simulations in parallel
377 //#if HAVE_MPI
378 // // communicate ghost data
379 // using SolutionTypes = typename GetProp<TypeTag, SolutionTypes>;
380 // using ElementMapper = typename SolutionTypes::ElementMapper;
381 // using DataHandle = VectorExchange<ElementMapper, std::vector<CellData> >;
382 // DataHandle dataHandle(problem.elementMapper(), this->cellDataGlobal());
383 // problem.gridView().template communicate<DataHandle>(dataHandle,
384 // Dune::InteriorBorder_All_Interface,
385 // Dune::ForwardCommunication);
386 //#endif
387 15 }
388
389 /*!
390 * \brief Stores sons entries into father element for averaging
391 *
392 * Sum up the adaptedValues (sons values) into father element. We store from leaf
393 * upwards, so sons are stored first, then cells on the next leaf (=fathers)
394 * can be averaged.
395 *
396 * \param adaptedValues Container for model-specific values to be adapted
397 * \param adaptedValuesFather Values to be adapted of father cell
398 */
399 76916 static void storeAdaptionValues(AdaptedValues& adaptedValues,
400 AdaptedValues& adaptedValuesFather)
401 {
402 // Add associated mass of the child to the one of the father
403 89322 adaptedValuesFather.associatedMass += adaptedValues.associatedMass;
404
405 if(!isBox)
406 {
407 // add the child's primary variables to the ones of father
408 // we have to divide the child's ones in case it was composed
409 // of several children as well!
410 76916 auto values = adaptedValues.u[0];
411 76916 values /= adaptedValues.count;
412 76916 adaptedValuesFather.u[0] += values;
413
414 // keep track of the number of children that composed this father
415 76916 adaptedValuesFather.count += 1;
416
417 // A father element is never leaf
418 76916 adaptedValuesFather.wasLeaf = false;
419 }
420 else
421 {
422 // For the box scheme, scaling of primary variables by count is obsolete
423 // Thus, we always want count = 1
424 12406 adaptedValuesFather.count = 1;
425
426 // A father element is never leaf
427 12406 adaptedValuesFather.wasLeaf = false;
428 }
429 76916 }
430
431 std::shared_ptr<const Problem> problem_;
432 std::shared_ptr<GridGeometry> gridGeometry_;
433 std::shared_ptr<const GridVariables> gridVariables_;
434 SolutionVector& sol_;
435 PersistentContainer adaptionMap_;
436 };
437
438 } // end namespace Dumux
439
440 #endif
441