13#ifndef DUMUX_PORE_NETWORK_GRID_MANAGER_HH
14#define DUMUX_PORE_NETWORK_GRID_MANAGER_HH
22#include <dune/common/classname.hh>
23#include <dune/common/exceptions.hh>
24#include <dune/common/timer.hh>
27#include <dune/foamgrid/foamgrid.hh>
28#include <dune/foamgrid/dgffoam.hh>
42template<
int dimWorld,
class GData = Dumux::PoreNetwork::Gr
idData<Dune::FoamGr
id<1, dimWorld>>>
45 using GridType = Dune::FoamGrid<1, dimWorld>;
46 using Element =
typename GridType::template Codim<0>::Entity;
47 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
53 void init(
const std::string& paramGroup =
"")
68 if (numPores.size() == 1)
69 createOneDGrid_(numPores[0]);
70 else if (numPores.size() == dimWorld)
74 "Grid.NumPores parameter has wrong size " << numPores.size()
75 <<
". Should be 1 (for 1D grid) or "
76 << dimWorld <<
" (for structured lattice grid)."
83 const auto gridType =
enableDgfGridPointer_ ?
"grid from dgf file" :
"generic grid from structured lattice";
84 std::cout <<
"Creating " << gridType <<
" with " <<
grid().leafGridView().size(0) <<
" elements and "
85 <<
grid().leafGridView().size(1) <<
" vertices took " << timer.elapsed() <<
" seconds." << std::endl;
95 if (extension !=
"dgf")
96 DUNE_THROW(Dune::IOError,
"Grid type " << Dune::className<Grid>() <<
" only supports DGF (*.dgf) but the specified filename has extension: *."<< extension);
99 dgfGridPtr() = Dune::GridPtr<Grid>(fileName.c_str(), Dune::MPIHelper::getCommunicator());
120 std::cout <<
"\nWARNING: Set Grid.Sanitize = true in order to remove insular patches of elements not connected to the boundary." << std::endl;
130 std::size_t i = fileName.rfind(
'.', fileName.length());
131 if (i != std::string::npos)
132 return(fileName.substr(i+1, fileName.length() - i));
134 DUNE_THROW(Dune::IOError,
"Please provide and extension for your grid file ('"<< fileName <<
"')!");
150 DUNE_THROW(Dune::IOError,
"No grid data available");
160 if (Dune::MPIHelper::getCommunication().size() > 1)
186 const auto gridView =
grid().leafGridView();
190 const auto keepElement = [&]
192 if (sanitationMode ==
"UsePoreLabels")
194 else if (sanitationMode ==
"KeepLargestCluster")
197 DUNE_THROW(Dune::IOError, sanitationMode <<
"is not a valid sanitation mode. Use KeepLargestCluster or UsePoreLabels.");
202 if (std::none_of(keepElement.begin(), keepElement.end(), [](
const bool i){return i;}))
203 DUNE_THROW(Dune::InvalidStateException,
"sanitize() deleted all elements! Check your boundary face indices. "
204 <<
"If the problem persists, add at least one of your boundary face indices to PruningSeedIndices");
207 std::size_t numDeletedElements = 0;
209 for (
const auto& element : elements(gridView))
211 const auto eIdx = gridView.indexSet().index(element);
212 if (!keepElement[eIdx])
214 grid().removeElement(element);
215 ++numDeletedElements;
226 if (numDeletedElements > 0)
227 std::cout <<
"\nDeleted " << numDeletedElements <<
" isolated elements.\n" << std::endl;
238 std::vector<bool> elementIsConnected(gridView.size(0),
false);
240 auto boundaryIdx = [&](
const auto& vertex)
243 return static_cast<int>(
dgfGridPtr_.parameters(vertex)[
gridData_->parameterIndex(
"PoreLabel")]);
245 return static_cast<int>(
gridData_->poreLabelAtPosForGenericGrid(vertex.geometry().center()));
248 for (
const auto& element : elements(gridView))
250 const auto eIdx = gridView.indexSet().index(element);
251 if (elementIsConnected[eIdx])
256 bool hasNeighbor =
false;
257 for (
const auto& intersection : intersections(gridView, element))
259 auto vertex = element.template subEntity<1>(intersection.indexInInside());
261 if (std::any_of(pruningSeedIndices.begin(), pruningSeedIndices.end(),
262 [&](
const int i ){ return i == boundaryIdx(vertex); }))
268 if (intersection.neighbor())
277 elementIsConnected[eIdx] =
true;
280 recursivelyFindConnectedElements_(gridView, element, elementIsConnected);
284 return elementIsConnected;
295 const auto numClusters = *std::max_element(clusteredElements.begin(), clusteredElements.end()) + 1;
296 std::cout <<
"\nFound " << numClusters <<
" unconnected clusters." << std::endl;
299 std::vector<std::size_t> clusterFrequency(numClusters);
300 for (
const auto clusterIdx : clusteredElements)
301 clusterFrequency[clusterIdx] += 1;
303 const auto largestCluster = std::max_element(clusterFrequency.begin(), clusterFrequency.end());
304 const auto largestClusterIdx = std::distance(clusterFrequency.begin(), largestCluster);
306 std::vector<bool> elementsInLargestCluster(gridView.size(0));
308 for (
int eIdx = 0; eIdx < clusteredElements.size(); ++eIdx)
309 if (clusteredElements[eIdx] == largestClusterIdx)
310 elementsInLargestCluster[eIdx] =
true;
312 return elementsInLargestCluster;
318 std::vector<std::size_t>
clusterElements(
const typename Grid::LeafGridView& gridView)
const
320 std::vector<std::size_t> elementInCluster(gridView.size(0), 0);
321 std::size_t clusterIdx = 0;
323 for (
const auto& element : elements(gridView))
325 const auto eIdx = gridView.indexSet().index(element);
326 if (elementInCluster[eIdx])
330 elementInCluster[eIdx] = clusterIdx;
332 recursivelyFindConnectedElements_(gridView, element, elementInCluster, clusterIdx);
336 for (
auto& clusterIdx : elementInCluster)
339 return elementInCluster;
352 DUNE_THROW(Dune::InvalidStateException,
"You are using DGF. To get the grid pointer use method dgfGridPtr()!");
363 DUNE_THROW(Dune::InvalidStateException,
"The DGF grid pointer is only available if the grid was constructed with a DGF file!");
381 void createOneDGrid_(
unsigned int numPores)
385 const auto cells = numPores - 1;
388 GlobalPosition step = upperRight;
389 step -= lowerLeft, step /= cells;
392 Dune::GridFactory<Grid> factory;
395 GlobalPosition globalPos = lowerLeft;
396 for (
unsigned int vIdx = 0; vIdx <= cells; vIdx++, globalPos += step)
397 factory.insertVertex(globalPos);
400 for(
unsigned int eIdx = 0; eIdx < cells; eIdx++)
401 factory.insertElement(Dune::GeometryTypes::line, {eIdx, eIdx+1});
403 gridPtr() = std::shared_ptr<Grid>(factory.createGrid());
409 void recursivelyFindConnectedElements_(
const typename Grid::LeafGridView& gridView,
410 const Element& element,
411 std::vector<T>& elementIsConnected,
415 std::stack<Element> elementStack;
416 elementStack.push(element);
417 while (!elementStack.empty())
419 auto e = elementStack.top();
421 for (
const auto& intersection : intersections(gridView, e))
423 if (!intersection.boundary())
425 auto outside = intersection.outside();
426 auto nIdx = gridView.indexSet().index(outside);
427 if (!elementIsConnected[nIdx])
429 elementIsConnected[nIdx] = marker;
430 elementStack.push(outside);
Exception thrown if a run-time parameter is not specified correctly.
Definition exceptions.hh:48
A grid manager for pore-network models.
Definition io/grid/porenetwork/gridmanager.hh:44
std::vector< bool > findElementsInLargestCluster(const typename Grid::LeafGridView &gridView) const
Returns a vector of bool which entries are true for elements located in the largest connected cluster...
Definition io/grid/porenetwork/gridmanager.hh:291
Dune::GridPtr< Grid > dgfGridPtr_
Definition io/grid/porenetwork/gridmanager.hh:373
std::vector< std::size_t > clusterElements(const typename Grid::LeafGridView &gridView) const
Assigns a cluster index for each element.
Definition io/grid/porenetwork/gridmanager.hh:318
std::string paramGroup_
Definition io/grid/porenetwork/gridmanager.hh:377
bool enableDgfGridPointer_
A state variable if the DGF Dune::GridPtr has been enabled. It is always enabled if a DGF grid file w...
Definition io/grid/porenetwork/gridmanager.hh:370
void makeGridFromStructuredLattice()
Make a grid based on a structured lattice which allows to randomly delete elements based on Raoof et ...
Definition io/grid/porenetwork/gridmanager.hh:109
std::shared_ptr< GridData > getGridData() const
Returns the grid data.
Definition io/grid/porenetwork/gridmanager.hh:147
GData GridData
Definition io/grid/porenetwork/gridmanager.hh:51
void init(const std::string ¶mGroup="")
Definition io/grid/porenetwork/gridmanager.hh:53
void loadBalance()
Call loadBalance() function of the grid.
Definition io/grid/porenetwork/gridmanager.hh:158
Dune::GridPtr< Grid > & dgfGridPtr()
Returns a reference to the DGF grid pointer (Dune::GridPtr<Grid>).
Definition io/grid/porenetwork/gridmanager.hh:358
std::string getFileExtension(const std::string &fileName) const
Returns the filename extension of a given filename.
Definition io/grid/porenetwork/gridmanager.hh:128
std::vector< bool > findElementsConnectedToPoreLabel(const typename Grid::LeafGridView &gridView) const
Returns a vector of bool which entries are true for elements connected to pores at the boundary with ...
Definition io/grid/porenetwork/gridmanager.hh:234
std::shared_ptr< Grid > & gridPtr()
Returns a reference to the grid pointer (std::shared_ptr<Grid>).
Definition io/grid/porenetwork/gridmanager.hh:347
std::shared_ptr< GridData > gridData_
Definition io/grid/porenetwork/gridmanager.hh:375
GridType Grid
Definition io/grid/porenetwork/gridmanager.hh:50
std::shared_ptr< Grid > gridPtr_
Definition io/grid/porenetwork/gridmanager.hh:372
Grid & grid()
Returns a reference to the grid.
Definition io/grid/porenetwork/gridmanager.hh:141
void sanitizeGrid()
post-processing to remove insular groups of elements that are not connected to a Dirichlet boundary
Definition io/grid/porenetwork/gridmanager.hh:177
void makeGridFromDgfFile(const std::string &fileName)
Make a grid from a DGF file.
Definition io/grid/porenetwork/gridmanager.hh:91
Creates a network grid from a structured lattice. Connections can be randomly deleted.
Definition structuredlatticegridcreator.hh:60
std::shared_ptr< Grid > & gridPtr()
Returns a reference to the grid pointer (std::shared_ptr<Grid>).
Definition structuredlatticegridcreator.hh:130
void init(const std::string ¶mGroup="")
Definition structuredlatticegridcreator.hh:80
Some exceptions thrown in DuMux.
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:149
bool hasParamInGroup(const std::string ¶mGroup, const std::string ¶m)
Check whether a key exists in the parameter tree with a model group prefix.
Definition parameters.hh:165
Definition discretization/porenetwork/fvelementgeometry.hh:24
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Class for grid data attached to dgf or gmsh grid files.
Creates a network grid from a structured lattice. Connections can be randomly deleted.