3.1-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
codimonegridadapter.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_FACETCOUPLING_CODIM_ONE_GRID_ADAPTER_HH
26#define DUMUX_FACETCOUPLING_CODIM_ONE_GRID_ADAPTER_HH
27
28#include <cassert>
29#include <vector>
30
31#include <dune/grid/common/mcmgmapper.hh>
32#include <dune/geometry/referenceelements.hh>
33
35
36namespace Dumux {
37
50template<class Embeddings, int bulkGridId = 0, int facetGridId = 1>
52{
53 // Extract some types of the facet-conforming grid of codimension one
54 using FacetGridView = typename Embeddings::template GridView<facetGridId>;
55 using FacetGridVertex = typename FacetGridView::template Codim<FacetGridView::dimension>::Entity;
56 using FacetGridElement = typename FacetGridView::template Codim<0>::Entity;
57 using FacetGridIndexType = typename IndexTraits<FacetGridView>::GridIndex;
58
59 // Extract some types of the bulk grid
60 using BulkGridView = typename Embeddings::template GridView<bulkGridId>;
61 using BulkMapper = Dune::MultipleCodimMultipleGeomTypeMapper<BulkGridView>;
62 using BulkReferenceElements = typename Dune::ReferenceElements<typename BulkGridView::ctype, BulkGridView::dimension>;
63 using BulkGridElement = typename BulkGridView::template Codim<0>::Entity;
64 using BulkGridIntersection = typename BulkGridView::Intersection;
65 using BulkGridVertex = typename BulkGridView::template Codim<BulkGridView::dimension>::Entity;
66 using BulkIndexType = typename IndexTraits<BulkGridView>::GridIndex;
67
68 // check if provided id combination makes sense
69 static_assert( int(FacetGridView::dimension) == int(BulkGridView::dimension) - 1,
70 "Grid dimension mismatch! Please check the provided domain ids!" );
71 static_assert( int(FacetGridView::dimensionworld) == int(BulkGridView::dimensionworld),
72 "Grid world dimension mismatch! All grids must have the same world dimension" );
73
74public:
75
77 CodimOneGridAdapter(std::shared_ptr<const Embeddings> embeddings)
78 : embeddingsPtr_(embeddings)
79 , bulkVertexMapper_(embeddings->template gridView<bulkGridId>(), Dune::mcmgVertexLayout())
80 {
81 // bulk insertion to grid index map
82 const auto& bulkGridView = embeddings->template gridView<bulkGridId>();
83 bulkInsertionToGridVIdx_.resize(bulkGridView.size(BulkGridView::dimension));
84 for (const auto& v : vertices(bulkGridView))
85 bulkInsertionToGridVIdx_[embeddings->template insertionIndex<bulkGridId>(v)] = bulkVertexMapper_.index(v);
86
87 // Determine map from the hierarchy's vertex idx to bulk insertion idx
88 // There is one unique set of vertex indices within the hierarchy.
89 // Obtain the hierarchy indices that make up the bulk grid. These
90 // are ordered corresponding to their insertion (thus loopIdx = insertionIdx)
91 hierarchyToBulkInsertionIdx_.resize(embeddingsPtr_->numVerticesInHierarchy());
92 bulkGridHasHierarchyVertex_.resize(embeddingsPtr_->numVerticesInHierarchy(), false);
93 const auto& bulkHierarchyIndices = embeddingsPtr_->gridHierarchyIndices(bulkGridId);
94 for (std::size_t insIdx = 0; insIdx < bulkHierarchyIndices.size(); ++insIdx)
95 {
96 hierarchyToBulkInsertionIdx_[ bulkHierarchyIndices[insIdx] ] = insIdx;
97 bulkGridHasHierarchyVertex_[ bulkHierarchyIndices[insIdx] ] = true;
98 }
99
100 // determine which bulk vertices lie on facet elements
101 bulkVertexIsOnFacetGrid_.resize(bulkGridView.size(BulkGridView::dimension), false);
102 const auto& facetGridView = embeddings->template gridView<facetGridId>();
103 for (const auto& v : vertices(facetGridView))
104 {
105 const auto insIdx = embeddings->template insertionIndex<facetGridId>(v);
106 const auto hierarchyInsIdx = embeddings->gridHierarchyIndices(facetGridId)[insIdx];
107
108 if (bulkGridHasHierarchyVertex_[hierarchyInsIdx])
109 bulkVertexIsOnFacetGrid_[ getBulkGridVertexIndex_(hierarchyInsIdx) ] = true;
110 }
111
112 // determine the bulk vertex indices that make up facet elements & connectivity
113 facetElementCorners_.resize(facetGridView.size(0));
114 facetElementsAtBulkVertex_.resize(bulkGridView.size(BulkGridView::dimension));
115
116 std::size_t facetElementCounter = 0;
117 for (const auto& element : elements(facetGridView))
118 {
119 if (isEmbedded(element))
120 {
121 // obtain the bulk vertex indices of the corners of this element
122 const auto numCorners = element.subEntities(FacetGridView::dimension);
123 std::vector<BulkIndexType> cornerIndices(numCorners);
124 for (int i = 0; i < numCorners; ++i)
125 cornerIndices[i] = bulkGridVertexIndex(element.template subEntity<FacetGridView::dimension>(i));
126
127 // update connectivity map facetVertex -> facetElements
128 for (auto bulkVIdx : cornerIndices)
129 facetElementsAtBulkVertex_[bulkVIdx].push_back(facetElementCounter);
130
131 // update facet elements (identified by corners - store them sorted!)
132 std::sort(cornerIndices.begin(), cornerIndices.end());
133 facetElementCorners_[facetElementCounter] = std::move(cornerIndices);
134 }
135
136 facetElementCounter++;
137 }
138 }
139
146 BulkIndexType bulkGridVertexIndex(const FacetGridVertex& v) const
147 {
148 const auto insIdx = embeddingsPtr_->template insertionIndex<facetGridId>(v);
149 const auto hierarchyInsIdx = embeddingsPtr_->gridHierarchyIndices(facetGridId)[insIdx];
150 return getBulkGridVertexIndex_(hierarchyInsIdx);
151 }
152
157 bool isOnFacetGrid(const BulkGridVertex& v) const
158 {
159 const auto bulkInsIdx = embeddingsPtr_->template insertionIndex<bulkGridId>(v);
160 const auto bulkVIdx = bulkInsertionToGridVIdx_[bulkInsIdx];
161 return bulkVertexIsOnFacetGrid_[bulkVIdx];
162 }
163
170 bool isOnFacetGrid(const BulkGridElement& element, const BulkGridIntersection& intersection) const
171 {
172 // Intersection lies on facet grid, if the corners of the intersection make up a facet element
173 const auto refElement = BulkReferenceElements::general(element.type());
174 const auto numCorners = intersection.geometry().corners();
175 const auto facetIdx = intersection.indexInInside();
176
177 std::vector<BulkIndexType> cornerIndices(numCorners);
178 for (int i = 0; i < numCorners; ++i)
179 cornerIndices[i] = bulkVertexMapper_.subIndex( element,
180 refElement.subEntity(facetIdx, 1, i, BulkGridView::dimension),
181 BulkGridView::dimension );
182
183 return composeFacetElement(cornerIndices);
184 }
185
192 template<class IndexStorage>
193 bool composeFacetElement(const IndexStorage& bulkVertexIndices) const
194 {
195 // set up a vector containing all element indices the vertices are connected to
196 std::vector<std::size_t> facetElemIndices;
197 for (auto bulkVIdx : bulkVertexIndices)
198 facetElemIndices.insert( facetElemIndices.end(),
199 facetElementsAtBulkVertex_[bulkVIdx].begin(),
200 facetElementsAtBulkVertex_[bulkVIdx].end() );
201
202 // if no facet elements are connected to the vertices this is not on facet grid
203 if (facetElemIndices.size() == 0)
204 return false;
205
206 // make the container unique
207 std::sort(facetElemIndices.begin(), facetElemIndices.end());
208 facetElemIndices.erase(std::unique(facetElemIndices.begin(), facetElemIndices.end()), facetElemIndices.end());
209
210 // check if given indices make up a facet element
211 auto cornerIndexCopy = bulkVertexIndices;
212 std::sort(cornerIndexCopy.begin(), cornerIndexCopy.end());
213 for (const auto& facetElemIdx : facetElemIndices)
214 {
215 const auto& facetElemCorners = facetElementCorners_[facetElemIdx];
216 if (facetElemCorners.size() != cornerIndexCopy.size())
217 continue;
218
219 if ( std::equal(cornerIndexCopy.begin(), cornerIndexCopy.end(),
220 facetElemCorners.begin(), facetElemCorners.end()) )
221 return true;
222 }
223
224 // no corresponding facet element found
225 return false;
226 }
227
232 bool isEmbedded(const FacetGridElement& e) const
233 { return numEmbedments(e) > 0; }
234
239 std::size_t numEmbedments(const FacetGridElement& e) const
240 { return embeddingsPtr_->template adjoinedEntityIndices<facetGridId>(e).size(); }
241
242private:
244 BulkIndexType getBulkGridVertexIndex_(BulkIndexType hierarchyInsertionIdx) const
245 {
246 assert(bulkGridHasHierarchyVertex_[hierarchyInsertionIdx]);
247 return bulkInsertionToGridVIdx_[ hierarchyToBulkInsertionIdx_[hierarchyInsertionIdx] ];
248 }
249
250 // shared pointer to the embedment data
251 std::shared_ptr<const Embeddings> embeddingsPtr_;
252
253 // vertex mapper of the bulk grid
254 BulkMapper bulkVertexMapper_;
255
256 // data stored on grid vertices
257 std::vector<bool> bulkVertexIsOnFacetGrid_;
258 std::vector<BulkIndexType> bulkInsertionToGridVIdx_;
259 std::vector<BulkIndexType> hierarchyToBulkInsertionIdx_;
260 std::vector<bool> bulkGridHasHierarchyVertex_;
261
262 // data stored for elements on the codim one grid
263 std::vector< std::vector<BulkIndexType> > facetElementsAtBulkVertex_;
264 std::vector< std::vector<BulkIndexType> > facetElementCorners_;
265};
266
267} // end namespace Dumux
268
269#endif
Defines the index types used for grid and local indices.
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
Definition: common/properties/model.hh:34
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:52
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:193
bool isOnFacetGrid(const BulkGridVertex &v) const
Returns true if the vertex of the d-dimensional grid with the given vertex index also exists on the (...
Definition: codimonegridadapter.hh:157
CodimOneGridAdapter(std::shared_ptr< const Embeddings > embeddings)
The constructor.
Definition: codimonegridadapter.hh:77
bool isEmbedded(const FacetGridElement &e) const
Returns true if a (d-1)-dimensional element is embedded in the d-dimensional domain.
Definition: codimonegridadapter.hh:232
bool isOnFacetGrid(const BulkGridElement &element, const BulkGridIntersection &intersection) const
Returns true if the given intersection coincides with a facet grid.
Definition: codimonegridadapter.hh:170
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:239
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:146