GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/io/grid/porenetwork/gridmanager.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 137 173 79.2%
Functions: 42 54 77.8%
Branches: 185 578 32.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 PoreNetworkModels
10 * \brief Provides a grid manager for pore-network models
11 */
12 #ifndef DUMUX_PORE_NETWORK_GRID_MANAGER_HH
13 #define DUMUX_PORE_NETWORK_GRID_MANAGER_HH
14
15 #if HAVE_DUNE_FOAMGRID
16
17 #include <iostream>
18 #include <algorithm>
19 #include <vector>
20
21 #include <dune/common/classname.hh>
22 #include <dune/common/exceptions.hh>
23 #include <dune/common/timer.hh>
24
25 // FoamGrid specific includes
26 #include <dune/foamgrid/foamgrid.hh>
27 #include <dune/foamgrid/dgffoam.hh>
28
29 #include <dumux/common/parameters.hh>
30 #include <dumux/common/exceptions.hh>
31
32 #include "griddata.hh"
33 #include "structuredlatticegridcreator.hh"
34
35 namespace Dumux::PoreNetwork {
36
37 /*!
38 * \ingroup PoreNetworkModels
39 * \brief A grid manager for pore-network models
40 */
41 template<int dimWorld, class GData = Dumux::PoreNetwork::GridData<Dune::FoamGrid<1, dimWorld>>>
42 class GridManager
43 {
44 using GridType = Dune::FoamGrid<1, dimWorld>;
45 using Element = typename GridType::template Codim<0>::Entity;
46 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
47
48 public:
49 using Grid = GridType;
50 using GridData = GData;
51
52 57 void init(const std::string& paramGroup = "")
53 {
54 57 Dune::Timer timer;
55 57 paramGroup_ = paramGroup;
56
57 // First try to create it from a DGF file in GridParameterGroup.File
58
8/14
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 39 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 39 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 39 times.
✓ Branch 11 taken 18 times.
✓ Branch 12 taken 21 times.
✓ Branch 13 taken 18 times.
✓ Branch 14 taken 21 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
171 if (hasParamInGroup(paramGroup, "Grid.File"))
59 {
60
2/6
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
24 makeGridFromDgfFile(getParamFromGroup<std::string>(paramGroup, "Grid.File"));
61 24 loadBalance();
62 }
63 else // no grid file found
64 {
65 // create a structured grid (1D grid or lattice grid)
66
1/4
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
99 const auto numPores = getParamFromGroup<std::vector<unsigned int>>(paramGroup_, "Grid.NumPores");
67
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 18 times.
66 if (numPores.size() == 1)
68
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
5 createOneDGrid_(numPores[0]);
69
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
28 else if (numPores.size() == dimWorld)
70
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
28 makeGridFromStructuredLattice();
71 else
72 DUNE_THROW(ParameterException,
73 "Grid.NumPores parameter has wrong size " << numPores.size()
74 << ". Should be 1 (for 1D grid) or "
75 << dimWorld << " (for structured lattice grid)."
76 );
77
78
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
33 loadBalance();
79 }
80
81 57 timer.stop();
82
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 18 times.
57 const auto gridType = enableDgfGridPointer_ ? "grid from dgf file" : "generic grid from structured lattice";
83 171 std::cout << "Creating " << gridType << " with " << grid().leafGridView().size(0) << " elements and "
84 171 << grid().leafGridView().size(1) << " vertices took " << timer.elapsed() << " seconds." << std::endl;
85 57 }
86
87 /*!
88 * \brief Make a grid from a DGF file.
89 */
90 24 void makeGridFromDgfFile(const std::string& fileName)
91 {
92 // We found a file in the input file...does it have a supported extension?
93
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
48 const std::string extension = getFileExtension(fileName);
94
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
24 if (extension != "dgf")
95 DUNE_THROW(Dune::IOError, "Grid type " << Dune::className<Grid>() << " only supports DGF (*.dgf) but the specified filename has extension: *."<< extension);
96
97 24 enableDgfGridPointer_ = true;
98
9/20
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 18 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 18 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 18 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 18 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 18 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 18 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 18 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
120 dgfGridPtr() = Dune::GridPtr<Grid>(fileName.c_str(), Dune::MPIHelper::getCommunicator());
99
3/6
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 18 times.
24 gridData_ = std::make_shared<GridData>(dgfGridPtr_, paramGroup_);
100
101
3/6
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
24 if (getParamFromGroup<bool>(paramGroup_, "Grid.Sanitize", false))
102
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 sanitizeGrid();
103 24 }
104
105 /*!
106 * \brief Make a grid based on a structured lattice which allows to randomly delete elements based on Raoof et al. 2009
107 */
108 28 void makeGridFromStructuredLattice()
109 {
110 56 StructuredLatticeGridCreator<dimWorld> creator;
111
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
28 creator.init(paramGroup_);
112
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
28 gridPtr() = creator.gridPtr();
113
114
3/6
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 18 times.
28 gridData_ = std::make_shared<GridData>(gridPtr_, paramGroup_);
115
116
3/4
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 4 times.
28 if (getParamFromGroup<bool>(paramGroup_, "Grid.Sanitize", true))
117
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
20 sanitizeGrid();
118 else
119
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
16 std::cout << "\nWARNING: Set Grid.Sanitize = true in order to remove insular patches of elements not connected to the boundary." << std::endl;
120
121
2/4
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18 times.
✗ Branch 5 not taken.
56 gridData_->assignParameters();
122 28 }
123
124 /*!
125 * \brief Returns the filename extension of a given filename
126 */
127 24 std::string getFileExtension(const std::string& fileName) const
128 {
129
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
24 std::size_t i = fileName.rfind('.', fileName.length());
130
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
24 if (i != std::string::npos)
131 24 return(fileName.substr(i+1, fileName.length() - i));
132 else
133 DUNE_THROW(Dune::IOError, "Please provide and extension for your grid file ('"<< fileName << "')!");
134 return "";
135 }
136
137 /*!
138 * \brief Returns a reference to the grid.
139 */
140 488 Grid& grid()
141
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 267 times.
488 { return enableDgfGridPointer_ ? *dgfGridPtr() : *gridPtr(); }
142
143 /*!
144 * \brief Returns the grid data.
145 */
146 59 std::shared_ptr<GridData> getGridData() const
147 {
148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
59 if (!gridData_)
149 DUNE_THROW(Dune::IOError, "No grid data available");
150
151 59 return gridData_;
152 }
153
154 /*!
155 * \brief Call loadBalance() function of the grid.
156 */
157 57 void loadBalance()
158 {
159
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39 times.
57 if (Dune::MPIHelper::getCommunication().size() > 1)
160 {
161 // if we may have dgf parameters use load balancing of the dgf pointer
162 if (enableDgfGridPointer_)
163 {
164 dgfGridPtr().loadBalance();
165 // update the grid data
166 gridData_ = std::make_shared<GridData>(dgfGridPtr(), paramGroup_);
167 }
168 else
169 gridPtr()->loadBalance();
170 }
171 57 }
172
173 /*!
174 * \brief post-processing to remove insular groups of elements that are not connected to a Dirichlet boundary
175 */
176 40 void sanitizeGrid()
177 {
178 // evaluate the coordination numbers to check if all pores are connected to at least one throat
179
1/2
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
80 gridData_->getCoordinationNumbers();
180
181 // for dgf grid, copy the data to persistent containers
182
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 20 times.
40 if (enableDgfGridPointer_)
183 16 gridData_->copyDgfData();
184
185
2/2
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 4 times.
40 const auto gridView = grid().leafGridView();
186
4/6
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 4 times.
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
40 static const std::string sanitationMode = getParamFromGroup<std::string>(paramGroup_, "Grid.SanitationMode", "KeepLargestCluster");
187
188 // find the elements to keep, all others will be deleted
189 96 const auto keepElement = [&]
190 {
191
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
24 if (sanitationMode == "UsePoreLabels")
192 24 return findElementsConnectedToPoreLabel(gridView);
193
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
24 else if (sanitationMode == "KeepLargestCluster")
194 24 return findElementsInLargestCluster(gridView);
195 else
196 DUNE_THROW(Dune::IOError, sanitationMode << "is not a valid sanitation mode. Use KeepLargestCluster or UsePoreLabels.");
197
198
199 24 }();
200
201 120 if (std::none_of(keepElement.begin(), keepElement.end(), [](const bool i){return i;}))
202 DUNE_THROW(Dune::InvalidStateException, "sanitize() deleted all elements! Check your boundary face indices. "
203 << "If the problem persists, add at least one of your boundary face indices to PruningSeedIndices");
204
205 // remove the elements in the grid
206 40 std::size_t numDeletedElements = 0;
207
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
40 grid().preGrow();
208
5/6
✓ Branch 1 taken 44153 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 44153 times.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 44153 times.
44855 for (const auto& element : elements(gridView))
209 {
210
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 44153 times.
✓ Branch 2 taken 131 times.
✓ Branch 3 taken 44022 times.
44815 const auto eIdx = gridView.indexSet().index(element);
211
4/4
✓ Branch 0 taken 131 times.
✓ Branch 1 taken 44022 times.
✓ Branch 2 taken 131 times.
✓ Branch 3 taken 44022 times.
89630 if (!keepElement[eIdx])
212 {
213
2/4
✓ Branch 1 taken 131 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 131 times.
✗ Branch 5 not taken.
151 grid().removeElement(element);
214 151 ++numDeletedElements;
215 }
216 }
217 // triggers the grid growth process
218
2/4
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
40 grid().grow();
219
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
40 grid().postGrow();
220
221 // resize the parameters for dgf grids
222
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 20 times.
40 if (enableDgfGridPointer_)
223
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
16 gridData_->resizeParameterContainers();
224
225
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 17 times.
40 if (numDeletedElements > 0)
226
2/4
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
33 std::cout << "\nDeleted " << numDeletedElements << " isolated elements.\n" << std::endl;
227 40 }
228
229 /*!
230 * \brief Returns a vector of bool which entries are true for elements connected to pores at the boundary
231 * with a given pore label.
232 */
233 std::vector<bool> findElementsConnectedToPoreLabel(const typename Grid::LeafGridView& gridView) const
234 {
235 // pruning -- remove elements not connected to a Dirichlet boundary (marker == 1)
236 const auto pruningSeedIndices = getParamFromGroup<std::vector<int>>(paramGroup_, "Grid.PruningSeedIndices", std::vector<int>{1});
237 std::vector<bool> elementIsConnected(gridView.size(0), false);
238
239 auto boundaryIdx = [&](const auto& vertex)
240 {
241 if (enableDgfGridPointer_)
242 return static_cast<int>(dgfGridPtr_.parameters(vertex)[gridData_->parameterIndex("PoreLabel")]);
243 else
244 return static_cast<int>(gridData_->poreLabelAtPosForGenericGrid(vertex.geometry().center()));
245 };
246
247 for (const auto& element : elements(gridView))
248 {
249 const auto eIdx = gridView.indexSet().index(element);
250 if (elementIsConnected[eIdx])
251 continue;
252
253 // try to find a seed from which to start the search process
254 bool isSeed = false;
255 bool hasNeighbor = false;
256 for (const auto& intersection : intersections(gridView, element))
257 {
258 auto vertex = element.template subEntity<1>(intersection.indexInInside());
259 // seed found
260 if (std::any_of(pruningSeedIndices.begin(), pruningSeedIndices.end(),
261 [&]( const int i ){ return i == boundaryIdx(vertex); }))
262 {
263 isSeed = true;
264 // break;
265 }
266
267 if (intersection.neighbor())
268 hasNeighbor = true;
269 }
270
271 if (!hasNeighbor)
272 continue;
273
274 if (isSeed)
275 {
276 elementIsConnected[eIdx] = true;
277
278 // use iteration instead of recursion here because the recursion can get too deep
279 recursivelyFindConnectedElements_(gridView, element, elementIsConnected);
280 }
281 }
282
283 return elementIsConnected;
284 }
285
286 /*!
287 * \brief Returns a vector of bool which entries are true for elements located in the largest
288 * connected cluster of the network.
289 */
290 40 std::vector<bool> findElementsInLargestCluster(const typename Grid::LeafGridView& gridView) const
291 {
292 40 const auto clusteredElements = clusterElements(gridView);
293
294
3/6
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
120 const auto numClusters = *std::max_element(clusteredElements.begin(), clusteredElements.end()) + 1;
295
2/4
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
120 std::cout << "\nFound " << numClusters << " unconnected clusters." << std::endl;
296
297 // count number of elements in individual clusters
298
4/10
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 24 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
160 std::vector<std::size_t> clusterFrequency(numClusters);
299
4/4
✓ Branch 0 taken 44153 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 44153 times.
✓ Branch 3 taken 24 times.
89750 for (const auto clusterIdx : clusteredElements)
300 89630 clusterFrequency[clusterIdx] += 1;
301
302
3/6
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
120 const auto largestCluster = std::max_element(clusterFrequency.begin(), clusterFrequency.end());
303 80 const auto largestClusterIdx = std::distance(clusterFrequency.begin(), largestCluster);
304
305
1/4
✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
80 std::vector<bool> elementsInLargestCluster(gridView.size(0));
306
307
4/4
✓ Branch 0 taken 44153 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 44153 times.
✓ Branch 3 taken 24 times.
44855 for (int eIdx = 0; eIdx < clusteredElements.size(); ++eIdx)
308
4/4
✓ Branch 0 taken 44022 times.
✓ Branch 1 taken 131 times.
✓ Branch 2 taken 44022 times.
✓ Branch 3 taken 131 times.
89630 if (clusteredElements[eIdx] == largestClusterIdx)
309 133992 elementsInLargestCluster[eIdx] = true;
310
311 40 return elementsInLargestCluster;
312 }
313
314 /*!
315 * \brief Assigns a cluster index for each element.
316 */
317 40 std::vector<std::size_t> clusterElements(const typename Grid::LeafGridView& gridView) const
318 {
319 80 std::vector<std::size_t> elementInCluster(gridView.size(0), 0); // initially, all elements are in pseudo cluster 0
320 40 std::size_t clusterIdx = 0;
321
322
5/6
✓ Branch 1 taken 44153 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 44153 times.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 44153 times.
44855 for (const auto& element : elements(gridView))
323 {
324
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 44153 times.
✓ Branch 2 taken 89 times.
✓ Branch 3 taken 44064 times.
44815 const auto eIdx = gridView.indexSet().index(element);
325
4/4
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 44064 times.
✓ Branch 2 taken 89 times.
✓ Branch 3 taken 44064 times.
89630 if (elementInCluster[eIdx]) // element already is in a cluster
326 continue;
327
328 125 ++clusterIdx;
329 125 elementInCluster[eIdx] = clusterIdx;
330
331
1/2
✓ Branch 1 taken 89 times.
✗ Branch 2 not taken.
125 recursivelyFindConnectedElements_(gridView, element, elementInCluster, clusterIdx);
332 }
333
334 // make sure the clusters start with index zero
335
4/4
✓ Branch 0 taken 44153 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 44153 times.
✓ Branch 3 taken 24 times.
89750 for (auto& clusterIdx : elementInCluster)
336 44815 clusterIdx -= 1;
337
338 40 return elementInCluster;
339 }
340
341 protected:
342
343 /*!
344 * \brief Returns a reference to the grid pointer (std::shared_ptr<Grid>)
345 */
346 394 std::shared_ptr<Grid>& gridPtr()
347 {
348
1/2
✓ Branch 0 taken 288 times.
✗ Branch 1 not taken.
394 if(!enableDgfGridPointer_)
349 394 return gridPtr_;
350 else
351 DUNE_THROW(Dune::InvalidStateException, "You are using DGF. To get the grid pointer use method dgfGridPtr()!");
352 }
353
354 /*!
355 * \brief Returns a reference to the DGF grid pointer (Dune::GridPtr<Grid>).
356 */
357 151 Dune::GridPtr<Grid>& dgfGridPtr()
358 {
359
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
151 if(enableDgfGridPointer_)
360 151 return dgfGridPtr_;
361 else
362 DUNE_THROW(Dune::InvalidStateException, "The DGF grid pointer is only available if the grid was constructed with a DGF file!");
363 }
364
365 /*!
366 * \brief A state variable if the DGF Dune::GridPtr has been enabled.
367 * It is always enabled if a DGF grid file was used to create the grid.
368 */
369 bool enableDgfGridPointer_ = false;
370
371 std::shared_ptr<Grid> gridPtr_;
372 Dune::GridPtr<Grid> dgfGridPtr_;
373
374 std::shared_ptr<GridData> gridData_;
375
376 std::string paramGroup_;
377
378 private:
379
380 5 void createOneDGrid_(unsigned int numPores)
381 {
382 10 const auto lowerLeft = getParamFromGroup<GlobalPosition>(paramGroup_, "Grid.LowerLeft", GlobalPosition(0.0));
383 5 const auto upperRight = getParamFromGroup<GlobalPosition>(paramGroup_, "Grid.UpperRight");
384 5 const auto cells = numPores - 1;
385
386 // create a step vector
387 5 GlobalPosition step = upperRight;
388 10 step -= lowerLeft, step /= cells;
389
390 // make the grid (structured interval grid in dimworld space)
391 10 Dune::GridFactory<Grid> factory;
392
393 // create the vertices
394 5 GlobalPosition globalPos = lowerLeft;
395
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 42 times.
89 for (unsigned int vIdx = 0; vIdx <= cells; vIdx++, globalPos += step)
396
1/2
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
82 factory.insertVertex(globalPos);
397
398 // create the cells
399
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 3 times.
82 for(unsigned int eIdx = 0; eIdx < cells; eIdx++)
400
4/10
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 39 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 39 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 39 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
308 factory.insertElement(Dune::GeometryTypes::line, {eIdx, eIdx+1});
401
402
6/16
✓ 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 11 not taken.
✓ Branch 12 taken 3 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
5 gridPtr() = std::shared_ptr<Grid>(factory.createGrid());
403
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
5 gridData_ = std::make_shared<GridData>(gridPtr_, paramGroup_);
404
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
10 gridData_->assignParameters();
405 5 }
406
407 template<class T>
408 178 void recursivelyFindConnectedElements_(const typename Grid::LeafGridView& gridView,
409 const Element& element,
410 std::vector<T>& elementIsConnected,
411 T marker = 1) const
412 {
413 // use iteration instead of recursion here because the recursion can get too deep
414 356 std::stack<Element> elementStack;
415
1/2
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
178 elementStack.push(element);
416
4/4
✓ Branch 0 taken 44153 times.
✓ Branch 1 taken 89 times.
✓ Branch 2 taken 44153 times.
✓ Branch 3 taken 89 times.
176968 while (!elementStack.empty())
417 {
418
2/2
✓ Branch 0 taken 715 times.
✓ Branch 1 taken 43438 times.
89736 auto e = elementStack.top();
419 88306 elementStack.pop();
420
5/8
✓ Branch 1 taken 44153 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 793598 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 747292 times.
✓ Branch 11 taken 2153 times.
✓ Branch 13 taken 749445 times.
✗ Branch 14 not taken.
4933894 for (const auto& intersection : intersections(gridView, e))
421 {
422
4/4
✓ Branch 0 taken 747292 times.
✓ Branch 1 taken 2153 times.
✓ Branch 2 taken 747292 times.
✓ Branch 3 taken 2153 times.
2997780 if (!intersection.boundary())
423 {
424
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 747292 times.
1494584 auto outside = intersection.outside();
425
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 747292 times.
✓ Branch 2 taken 44064 times.
✓ Branch 3 taken 703228 times.
1494584 auto nIdx = gridView.indexSet().index(outside);
426
4/6
✓ Branch 0 taken 44064 times.
✓ Branch 1 taken 703228 times.
✓ Branch 2 taken 44064 times.
✓ Branch 3 taken 703228 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2989168 if (!elementIsConnected[nIdx])
427 {
428
0/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
88128 elementIsConnected[nIdx] = marker;
429
2/2
✓ Branch 0 taken 43349 times.
✓ Branch 1 taken 715 times.
88128 elementStack.push(outside);
430 }
431 }
432 }
433 }
434 178 }
435 };
436
437 }
438
439 #endif // HAVE_DUNE_FOAMGRID
440
441 #endif
442