25#ifndef DUMUX_VERTEX_ENRICHMENT_HELPER_HH
26#define DUMUX_VERTEX_ENRICHMENT_HELPER_HH
30#include <unordered_map>
31#include <unordered_set>
33#include <dune/common/exceptions.hh>
34#include <dune/common/reservedvector.hh>
36#include <dune/geometry/referenceelements.hh>
37#include <dune/grid/common/mcmgmapper.hh>
55template<
class Gr
idView,
class CodimOneGr
idView >
58 static constexpr int dim = GridView::dimension;
59 static constexpr int dimWorld = GridView::dimensionworld;
60 static_assert(dim == 2 || dim == 3,
"Grid dimension must be two or three");
61 static_assert(dimWorld == int(CodimOneGridView::dimensionworld),
"world dimension mismatch");
63 using Intersection =
typename GridView::Intersection;
64 using ReferenceElements =
typename Dune::ReferenceElements<typename GridView::ctype, dim>;
65 using MCMGMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
67 using Element =
typename GridView::template Codim<0>::Entity;
68 using GlobalPosition =
typename Element::Geometry::GlobalCoordinate;
70 using ElementPath = std::vector< GridIndexType >;
71 using NodalElementPaths = std::vector< std::vector<ElementPath> >;
90 template<
class IndexMap,
class CodimOneGr
idAdapter >
91 static std::size_t
enrich(IndexMap& indexMap,
92 const std::vector<bool>& vertexMarkers,
93 const GridView& gridView,
94 const MCMGMapper& vertexMapper,
95 const MCMGMapper& elementMapper,
96 const CodimOneGridView& codimOneGridView,
100 NodalElementPaths nodalPaths(gridView.size(dim));
101 for (
const auto& e : elements(gridView))
103 const auto eIdx = elementMapper.index(e);
105 std::vector<unsigned int> handledFacets;
106 const auto refElement = ReferenceElements::general(e.type());
107 for (
const auto& is : intersections(gridView, e))
114 if (std::find(handledFacets.begin(), handledFacets.end(), is.indexInInside()) != handledFacets.end())
118 const auto numCorners = is.geometry().corners();
119 std::vector<GridIndexType> faceVertexIndices(numCorners);
120 for (
int i = 0; i < numCorners; ++i)
121 faceVertexIndices[i] = vertexMapper.subIndex( e,
122 refElement.subEntity(is.indexInInside(), 1, i, dim),
128 handledFacets.push_back(is.indexInInside());
129 for (
int i = 0; i < numCorners; ++i)
132 const auto vIdxGlobal = faceVertexIndices[i];
133 if (!vertexMarkers[vIdxGlobal])
138 for (
const auto& path : nodalPaths[vIdxGlobal])
139 if (std::find(path.begin(), path.end(), eIdx) != path.end())
140 { found =
true;
break; }
151 path.push_back(eIdx);
152 continuePathSearch_(path, gridView, elementMapper, vertexMapper, codimOneGridAdapter, e, refElement, is, vIdxGlobal);
153 nodalPaths[vIdxGlobal].emplace_back(std::move(path));
161 std::vector<std::size_t> bulkVertexIndexOffsets(gridView.size(dim), 0);
162 for (
const auto& v : vertices(gridView))
164 const auto vIdx = vertexMapper.index(v);
165 if (vertexMarkers[vIdx])
166 bulkVertexIndexOffsets[vIdx] = nodalPaths[vIdx].size()-1;
170 std::size_t sumOffset = 0;
171 std::size_t size = 0;
172 for (
auto& nodalOffset : bulkVertexIndexOffsets)
174 const auto os = nodalOffset;
175 nodalOffset = sumOffset;
177 size += (os == 0) ? 1 : os + 1;
181 for (
const auto& e : elements(gridView))
183 const auto& eg = e.geometry();
184 const auto eIdx = elementMapper.index(e);
185 for (
int i = 0; i < eg.corners(); ++i)
187 const auto origVIdx = vertexMapper.subIndex(e, i, dim);
190 if (!vertexMarkers[origVIdx])
191 indexMap[eIdx][i] += bulkVertexIndexOffsets[origVIdx];
197 const auto& paths = nodalPaths[ origVIdx ];
198 for (
int pathIdx = 0; pathIdx < paths.size(); ++pathIdx)
200 const auto& curPath = paths[pathIdx];
201 if ( std::find(curPath.begin(), curPath.end(), eIdx) != curPath.end() )
203 indexMap[eIdx][i] += bulkVertexIndexOffsets[origVIdx] + pathIdx;
210 DUNE_THROW(Dune::InvalidStateException,
"Element not found in any path");
220 template<
class ReferenceElement,
class CodimOneGr
idAdapter >
221 static void continuePathSearch_(ElementPath& path,
222 const GridView& gridView,
223 const MCMGMapper& elementMapper,
224 const MCMGMapper& vertexMapper,
226 const Element& element,
227 const ReferenceElement& refElement,
228 const Intersection& prevIntersection,
229 GridIndexType vIdxGlobal)
232 static constexpr int numIsToFind = dim == 3 ? 2 : 1;
235 unsigned int foundCounter = 0;
236 std::vector<unsigned int> handledFacets;
237 for (
const auto& is : intersections(gridView, element))
240 if (is.indexInInside() == prevIntersection.indexInInside())
244 if (std::count(handledFacets.begin(), handledFacets.end(), is.indexInInside()))
248 const auto numCorners = is.geometry().corners();
249 std::vector<GridIndexType> faceVertexIndices(numCorners);
250 for (
int i = 0; i < numCorners; ++i)
251 faceVertexIndices[i] = vertexMapper.subIndex( element,
252 refElement.subEntity(is.indexInInside(), 1, i, dim),
256 if (std::find(faceVertexIndices.begin(), faceVertexIndices.end(), vIdxGlobal) != faceVertexIndices.end())
259 handledFacets.push_back(is.indexInInside());
271 const auto outsideElement = is.outside();
272 const auto outsideElemIdx = elementMapper.index(outsideElement);
273 if (std::find(path.begin(), path.end(), outsideElemIdx) == path.end())
275 const auto idxInOutside = is.indexInOutside();
276 const auto outsideRefElement = ReferenceElements::general(outsideElement.type());
277 path.push_back(outsideElemIdx);
280 for (
const auto& outsideIs : intersections(gridView, outsideElement))
282 if (outsideIs.indexInInside() == idxInOutside)
285 if (foundCounter == numIsToFind)
286 return continuePathSearch_(path,
298 continuePathSearch_(path,
313 if (foundCounter != numIsToFind)
314 DUNE_THROW(Dune::InvalidStateException,
"Found " << foundCounter <<
" instead of " << numIsToFind <<
" intersections around vertex");
Defines the index types used for grid and local indices.
Define some often used mathematical functions.
typename GridView::IndexSet::IndexType GridIndex
Definition: indextraits.hh:39
Adapter that allows retrieving information on a d-dimensional grid for entities of a (d-1)-dimensiona...
Definition: codimonegridadapter.hh:53
bool composeFacetElement(const IndexStorage &bulkVertexIndices) const
Returns true if a given set of bulk vertex indices make up a facet grid element.
Definition: codimonegridadapter.hh:194
Specialization of the enrichment helper class for 2d grids. In this case, we look for two-dimensional...
Definition: enrichmenthelper.hh:57
static std::size_t enrich(IndexMap &indexMap, const std::vector< bool > &vertexMarkers, const GridView &gridView, const MCMGMapper &vertexMapper, const MCMGMapper &elementMapper, const CodimOneGridView &codimOneGridView, const CodimOneGridAdapter &codimOneGridAdapter)
Enriches the dof map subject to a (dim-1)-dimensional grid.
Definition: enrichmenthelper.hh:91