3.2-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
vertexmapper.hh
Go to the documentation of this file.
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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
19
25#ifndef DUMUX_ENRICHED_VERTEX_DOF_MAPPER_HH
26#define DUMUX_ENRICHED_VERTEX_DOF_MAPPER_HH
27
28#include <vector>
29
30#include <dune/common/exceptions.hh>
31#include <dune/common/timer.hh>
32
33#include <dune/grid/common/mcmgmapper.hh>
34#include <dune/geometry/referenceelements.hh>
35
36#include "enrichmenthelper.hh"
37
38namespace Dumux {
39
48{
49
50public:
65 template< class GridView,
66 class VertexMapper,
67 class CodimOneGridView,
69 static void markVerticesForEnrichment(std::vector<bool>& vertexMarkers,
70 const GridView& gridView,
71 const VertexMapper& vertexMapper,
72 const CodimOneGridView& codimOneGridView,
73 const CodimOneGridAdapter& codimOneGridAdapter)
74 {
75 static constexpr int dim = GridView::dimension;
76 static_assert(CodimOneGridView::dimension == dim-1, "Grid dimension mismatch");
77
78 // reset the markers
79 vertexMarkers.assign(gridView.size(dim), false);
80
81 // first find all bulk grid vertices on the boundary
82 std::vector<bool> isOnBoundary(gridView.size(dim), false);
83 using ReferenceElements = typename Dune::ReferenceElements<typename GridView::ctype, dim>;
84 for (const auto& e : elements(gridView))
85 {
86 const auto refElem = ReferenceElements::general(e.type());
87 for (const auto& is : intersections(gridView, e))
88 if (is.boundary())
89 for (int i = 0; i < is.geometry().corners(); ++i)
90 isOnBoundary[ vertexMapper.subIndex( e,
91 refElem.subEntity(is.indexInInside(), 1, i, dim),
92 dim ) ] = true;
93 }
94
95 // for now, set all markers to true for vertices on codim one grid
96 for (const auto& vertex : vertices(codimOneGridView))
97 vertexMarkers[codimOneGridAdapter.bulkGridVertexIndex(vertex)] = true;
98
99 // unmark where necessary
100 using CodimOneReferenceElements = typename Dune::ReferenceElements<typename CodimOneGridView::ctype, dim-1>;
101 for (const auto& codimOneElement : elements(codimOneGridView))
102 {
103 // if a codimension one element has less than two embedments we do not need to enrich
104 if (codimOneGridAdapter.numEmbedments(codimOneElement) < 2)
105 for (int i = 0; i < codimOneElement.subEntities(dim-1); ++i)
106 vertexMarkers[ codimOneGridAdapter.bulkGridVertexIndex(codimOneElement.template subEntity<dim-1>(i)) ] = false;
107
108 // otherwise, we check for immersed boundaries where we also must not enrich
109 else
110 {
111 const auto refElem = CodimOneReferenceElements::general(codimOneElement.type());
112 for (const auto& intersection : intersections(codimOneGridView, codimOneElement))
113 {
114 // skip if intersection is not on boundary
115 if (!intersection.boundary())
116 continue;
117
118 // obtain all grid indices of the intersection corners
119 const auto numCorners = intersection.geometry().corners();
120 std::vector<typename GridView::IndexSet::IndexType> vertexIndices(numCorners);
121 for (int i = 0; i < numCorners; ++i)
122 {
123 const auto vIdxLocal = refElem.subEntity(intersection.indexInInside(), 1, i, dim-1);
124 vertexIndices[i] = codimOneGridAdapter.bulkGridVertexIndex( codimOneElement.template subEntity<dim-1>(vIdxLocal) );
125 }
126
127 // if any of the vertices is on an immersed boudnary, we must not enrich any of them
128 if (std::any_of(vertexIndices.begin(), vertexIndices.end(), [&isOnBoundary] (auto idx) { return !isOnBoundary[idx]; }))
129 std::for_each(vertexIndices.begin(), vertexIndices.end(), [&vertexMarkers] (auto idx) { vertexMarkers[idx] = false; });
130 }
131 }
132 }
133 }
134};
135
144template<class GV>
146{
147 static constexpr int dim = GV::dimension;
148 static_assert(dim > 1, "Vertex dof enrichment mapper currently only works for dim > 1!");
149
150 using GIType = typename GV::IndexSet::IndexType;
151 using Vertex = typename GV::template Codim<dim>::Entity;
152 using Element = typename GV::template Codim<0>::Entity;
153 using MCMGMapper = Dune::MultipleCodimMultipleGeomTypeMapper<GV>;
154
155public:
157 using GridView = GV;
159 using GridIndexType = GIType;
160
162 EnrichedVertexDofMapper(const GV& gridView)
163 : gridView_(gridView)
164 , elementMapper_(gridView, Dune::mcmgElementLayout())
165 , vertexMapper_(gridView, Dune::mcmgVertexLayout())
166 {
167 initialize_();
168 }
169
171 EnrichedVertexDofMapper(const GV& gridView, Dune::MCMGLayout layout)
172 : EnrichedVertexDofMapper(gridView)
173 {
174 if ( !( static_cast<bool>(layout(Dune::GeometryTypes::vertex, dim)) ) )
175 DUNE_THROW(Dune::InvalidStateException, "Vertex mapper only makes sense for vertex layout!");
176 }
177
179 GridIndexType subIndex(const Element& e, unsigned int i, unsigned int codim) const
180 {
181 assert(codim == dim && "Only element corners can be mapped by this mapper");
182 return indexMap_[elementMapper_.index(e)][i];
183 }
184
186 GridIndexType vertexIndex(const Element& e, unsigned int i, unsigned int codim) const
187 {
188 assert(codim == dim && "Only element corners can be mapped by this mapper");
189 return vertexMapper_.subIndex(e, i, codim);
190 }
191
193 GridIndexType vertexIndex(const Vertex& v) const
194 {
195 assert(Vertex::Geometry::mydimension == 0 && "Only vertices can be mapped by this mapper");
196 return vertexMapper_.index(v);
197 }
198
203 template< class EntityType >
204 GridIndexType index(const EntityType& e) const
205 {
206 if (hasEnrichedVertices_)
207 DUNE_THROW(Dune::InvalidStateException, "Index map contains enriched vertex dofs. Direct mapping from vertex to index not possible.");
208
209 assert(EntityType::Geometry::mydimension == 0 && "Only vertices can be mapped by this mapper");
210 return vertexMapper_.index(e);
211 }
212
214 std::size_t size() const
215 { return size_; }
216
218 bool isEnriched(const Vertex& v)
219 { return isEnriched_[ vertexMapper_.index(v) ]; }
220
223 void update()
224 {
225 initialize_();
226 }
227
239 template<class CodimOneGridView, class CodimOneGridAdapter>
240 void enrich(const CodimOneGridView& codimOneGridView,
241 const CodimOneGridAdapter& codimOneGridAdapter,
242 bool verbose = false)
243 {
244 static const int codimOneDim = CodimOneGridView::dimension;
245 static_assert(codimOneDim == dim-1, "Grid dimension mismatch!");
246 static_assert(codimOneDim == 2 || codimOneDim == 1, "Inadmissible codimension one grid dimension");
247 static_assert(int(CodimOneGridView::dimensionworld) == int(GV::dimensionworld), "Grid world dimension mismatch");
248
249 // keep track of time
250 Dune::Timer watch;
251
252 // mark vertices for enrichment using the indicator
253 EnrichmentIndicator::markVerticesForEnrichment(isEnriched_, gridView_, vertexMapper_, codimOneGridView, codimOneGridAdapter);
254
255 // let the helper class do the enrichment of the index map
257 isEnriched_,
258 gridView_,
259 vertexMapper_,
260 elementMapper_,
261 codimOneGridView,
262 codimOneGridAdapter);
263
264 // check if new index map contains enriched dofs
265 hasEnrichedVertices_ = std::any_of(isEnriched_.begin(), isEnriched_.end(), [] (bool isEnriched) { return isEnriched; });
266
267 if (verbose)
268 std::cout << "Vertex dof enrichment took " << watch.elapsed() << " seconds." << std::endl;
269 }
270
271private:
272
274 void initialize_()
275 {
276 size_ = gridView_.size(dim);
277 hasEnrichedVertices_ = false;
278 indexMap_.resize(gridView_.size(0));
279 isEnriched_.resize(gridView_.size(dim), false);
280 for (const auto& e : elements(gridView_))
281 {
282 const auto numCorners = e.geometry().corners();
283 const auto eIdxGlobal = elementMapper_.index(e);
284 indexMap_[eIdxGlobal].resize(numCorners);
285 for (unsigned int i = 0; i < numCorners; ++i)
286 indexMap_[eIdxGlobal][i] = vertexMapper_.subIndex(e, i, dim);
287 }
288 }
289
290 // data members
291 std::size_t size_;
292 const GV gridView_;
293 MCMGMapper elementMapper_;
294 MCMGMapper vertexMapper_;
295 bool hasEnrichedVertices_;
296 std::vector<bool> isEnriched_;
297 std::vector< std::vector<GIType> > indexMap_;
298};
299
300} // end namespace Dumux
301
302#endif
Definition: adapt.hh:29
Definition: common/pdesolver.hh:35
Adapter that allows retrieving information on a d-dimensional grid for entities of a (d-1)-dimensiona...
Definition: codimonegridadapter.hh:53
std::size_t numEmbedments(const FacetGridElement &e) const
Returns the number of d-dimensional elements in which the given (d-1)-dimensional element is embedded...
Definition: codimonegridadapter.hh:240
BulkIndexType bulkGridVertexIndex(const FacetGridVertex &v) const
Returns the index within the d-dimensional grid of a vertex of the (d-1)-dimensional grid.
Definition: codimonegridadapter.hh:147
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
An indicator class used to mark vertices for enrichment. This implementation marks all vertices of a ...
Definition: vertexmapper.hh:48
static void markVerticesForEnrichment(std::vector< bool > &vertexMarkers, const GridView &gridView, const VertexMapper &vertexMapper, const CodimOneGridView &codimOneGridView, const CodimOneGridAdapter &codimOneGridAdapter)
Function that marks vertices for enrichment. This implementation works on the basis of a facet-confor...
Definition: vertexmapper.hh:69
A vertex mapper that allows for enrichment of nodes. Indication on where to enrich the nodes is done ...
Definition: vertexmapper.hh:146
void enrich(const CodimOneGridView &codimOneGridView, const CodimOneGridAdapter &codimOneGridAdapter, bool verbose=false)
Enriches the dof map subject to a (dim-1)-dimensional grid.
Definition: vertexmapper.hh:240
std::size_t size() const
returns the number of dofs managed by this mapper
Definition: vertexmapper.hh:214
void update()
Definition: vertexmapper.hh:223
GridIndexType vertexIndex(const Element &e, unsigned int i, unsigned int codim) const
map nodal subentity of codim 0 entity to the grid vertex index
Definition: vertexmapper.hh:186
GridIndexType index(const EntityType &e) const
Definition: vertexmapper.hh:204
EnrichedVertexDofMapper(const GV &gridView)
the constructor
Definition: vertexmapper.hh:162
GridIndexType vertexIndex(const Vertex &v) const
map nodal entity to the grid vertex index
Definition: vertexmapper.hh:193
GIType GridIndexType
export the grid index type
Definition: vertexmapper.hh:159
GridIndexType subIndex(const Element &e, unsigned int i, unsigned int codim) const
map nodal subentity of codim 0 entity to the grid dof
Definition: vertexmapper.hh:179
GV GridView
export the underlying grid view type
Definition: vertexmapper.hh:157
EnrichedVertexDofMapper(const GV &gridView, Dune::MCMGLayout layout)
constructor taking a layout as additional argument (for compatibility)
Definition: vertexmapper.hh:171
bool isEnriched(const Vertex &v)
returns true if a vertex dof had been enriched
Definition: vertexmapper.hh:218