version 3.10-dev
couplingmapperbase.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// SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_FACETCOUPLING_MAPPER_BASE_HH
13#define DUMUX_FACETCOUPLING_MAPPER_BASE_HH
14
15#include <vector>
16#include <unordered_map>
17#include <algorithm>
18#include <memory>
19
20#include <dune/common/indices.hh>
21#include <dune/common/exceptions.hh>
23
24namespace Dumux {
25
36template< class BulkFVG,
37 class LowDimFVG,
38 std::size_t bulkId,
39 std::size_t lowDimId>
41{
42 using BulkGridView = typename BulkFVG::GridView;
43 using BulkIndexType = typename IndexTraits<BulkGridView>::GridIndex;
44
45 using LowDimGridView = typename LowDimFVG::GridView;
46 using LowDimElement = typename LowDimGridView::template Codim<0>::Entity;
47 using LowDimIndexType = typename IndexTraits<LowDimGridView>::GridIndex;
48
49 // make sure the grid geometry combination makes sense
50 static constexpr int bulkDim = BulkGridView::dimension;
51 static constexpr int lowDimDim = LowDimGridView::dimension;
52 static_assert(bulkDim == lowDimDim+1, "Lower-dimensional geometry is not of codim 1 w.r.t. bulk geometry!");
53
54 // discretization method of the bulk domain
55 static constexpr auto bulkDiscMethod = BulkFVG::discMethod;
56
57 // helper struct to check validity of the given domain id offset
58 template< class Embeddings >
59 class IsValidDomainId
60 {
61 using GCBulkGridView = typename Embeddings::template GridView<bulkId>;
62 using GCLowDimGridView = typename Embeddings::template GridView<lowDimId>;
63 static constexpr bool bulkMatch = std::is_same<GCBulkGridView, BulkGridView>::value;
64 static constexpr bool lowDimMatch = std::is_same<GCLowDimGridView, LowDimGridView>::value;
65 static_assert(bulkMatch, "The bulk domain id does not match the provided bulk grid geometry");
66 static_assert(lowDimMatch, "The lowDim domain id does not match the provided lowDim grid geometry");
67
68 public:
69 static constexpr bool value = bulkMatch && lowDimMatch;
70 };
71
76 struct BulkCouplingData
77 {
79 std::vector< LowDimIndexType > couplingStencil;
80
82 std::vector< LowDimIndexType > couplingElementStencil;
83
85 std::unordered_map< LowDimIndexType, std::vector<BulkIndexType> > dofToCouplingScvfMap;
86
88 std::unordered_map< LowDimIndexType, std::vector<BulkIndexType> > elementToScvfMap;
89 };
90
95 struct LowDimCouplingData
96 {
98 std::vector< BulkIndexType > couplingStencil;
99
101 using Embedment = std::pair< BulkIndexType, std::vector<BulkIndexType> >;
102 std::vector< Embedment > embedments;
103 };
104
106 using BulkCouplingMap = std::unordered_map<BulkIndexType, BulkCouplingData>;
107 using LowDimCouplingMap = std::unordered_map<LowDimIndexType, LowDimCouplingData>;
108
110 using LowDimStencil = std::vector<LowDimIndexType>;
111 using BulkStencil = std::vector<BulkIndexType>;
112
114 template<std::size_t id>
115 using GridIdType = Dune::index_constant<id>;
116
117public:
119 static constexpr auto bulkGridId = GridIdType<bulkId>();
120 static constexpr auto facetGridId = GridIdType<lowDimId>();
121
123 template<std::size_t id>
124 using Stencil = typename std::conditional<id == bulkId, BulkStencil, LowDimStencil>::type;
125
127 template<std::size_t i, std::size_t j>
128 using CouplingMap = typename std::conditional<i == bulkId, BulkCouplingMap, LowDimCouplingMap>::type;
129
131 template<int dim>
132 static constexpr GridIdType< (dim == bulkDim ? bulkId : lowDimId) > gridId()
133 { return GridIdType< (dim == bulkDim ? bulkId : lowDimId) >(); }
134
139 template< class Embeddings >
140 void update(const BulkFVG& bulkFvGridGeometry,
141 const LowDimFVG& lowDimFvGridGeometry,
142 std::shared_ptr<const Embeddings> embeddings)
143 { DUNE_THROW(Dune::NotImplemented, "Implementation does not provide an update() function."); }
144
146 const BulkCouplingMap& couplingMap(GridIdType<bulkId>, GridIdType<lowDimId>) const
147 { return bulkCouplingData_; }
148
150 const LowDimCouplingMap& couplingMap(GridIdType<lowDimId>, GridIdType<bulkId>) const
151 { return lowDimCouplingData_; }
152
153protected:
154
164 template< class Embeddings, typename AddCouplingEntryPolicy >
165 void update_(const BulkFVG& bulkFvGridGeometry,
166 const LowDimFVG& lowDimFvGridGeometry,
167 std::shared_ptr<const Embeddings> embeddings,
168 AddCouplingEntryPolicy&& addCouplingEntryPolicy)
169 {
170 // some static assertions on the grid creator
171 static_assert(IsValidDomainId<Embeddings>::value, "Grid type mismatch. Please review the provided domain id offset.");
172
173 // clear data
174 bulkCouplingData_.clear();
175 lowDimCouplingData_.clear();
176
177 // set up maps between element indices and insertion indices
178 const auto bulkInsertionToElemIdxMap = makeInsertionToGridIndexMap_(embeddings, bulkFvGridGeometry);
179
180 // set up coupling maps coming from the low dim domain
181 for (const auto& element : elements(lowDimFvGridGeometry.gridView()))
182 {
183 auto adjoinedEntities = embeddings->template adjoinedEntityIndices<lowDimId>(element);
184
185 // proceed only if element is embedded
186 if (adjoinedEntities.size() == 0)
187 continue;
188
189 // turn (insertion) indices into actual grid element indices ...
190 std::for_each(adjoinedEntities.begin(), adjoinedEntities.end(), [&] (auto& idx) { idx = bulkInsertionToElemIdxMap.at(idx); });
191
192 // ... and add them
193 addCouplingEntryPolicy(std::move(adjoinedEntities), element, lowDimFvGridGeometry, bulkFvGridGeometry);
194 }
195 }
196
198 template< class GridGeometry>
199 std::vector< typename IndexTraits<typename GridGeometry::GridView>::GridIndex >
200 extractNodalDofs_(const typename GridGeometry::GridView::template Codim<0>::Entity& element,
201 const GridGeometry& gridGeometry)
202 {
203 static constexpr int dim = GridGeometry::GridView::dimension;
204 using GridIndexType = typename IndexTraits<typename GridGeometry::GridView>::GridIndex;
205
206 const auto numCorners = element.subEntities(dim);
207 std::vector< GridIndexType > nodalDofs(numCorners);
208 for (unsigned int i = 0; i < numCorners; ++i)
209 nodalDofs[i] = gridGeometry.vertexMapper().subIndex(element, i, dim);
210
211 return nodalDofs;
212 }
213
215 BulkCouplingMap& couplingMap_(GridIdType<bulkId>, GridIdType<lowDimId>)
216 { return bulkCouplingData_; }
217
219 LowDimCouplingMap& couplingMap_(GridIdType<lowDimId>, GridIdType<bulkId>)
220 { return lowDimCouplingData_; }
221
222private:
223
225 template< class Embeddings, class GridGeometry>
226 std::unordered_map< typename IndexTraits<typename GridGeometry::GridView>::GridIndex, typename IndexTraits<typename GridGeometry::GridView>::GridIndex >
227 makeInsertionToGridIndexMap_(std::shared_ptr<const Embeddings> embeddings, const GridGeometry& gridGeometry) const
228 {
229 using GridIndexType = typename IndexTraits<typename GridGeometry::GridView>::GridIndex;
230
231 std::unordered_map< GridIndexType, GridIndexType > map;
232 for (const auto& e : elements(gridGeometry.gridView()))
233 map.insert( std::make_pair( embeddings->template insertionIndex<bulkId>(e), gridGeometry.elementMapper().index(e) ) );
234
235 return map;
236 }
237
238 BulkCouplingMap bulkCouplingData_;
239 LowDimCouplingMap lowDimCouplingData_;
240};
241
242} // end namespace Dumux
243
244#endif
Base class for the coupling mapper that sets up and stores the coupling maps between two domains of d...
Definition: couplingmapperbase.hh:41
const BulkCouplingMap & couplingMap(GridIdType< bulkId >, GridIdType< lowDimId >) const
returns coupling data for bulk -> lowDim
Definition: couplingmapperbase.hh:146
static constexpr GridIdType<(dim==bulkDim ? bulkId :lowDimId) > gridId()
Allow retrievment of grid id for a given grid dimension.
Definition: couplingmapperbase.hh:132
static constexpr auto facetGridId
Definition: couplingmapperbase.hh:120
typename std::conditional< id==bulkId, BulkStencil, LowDimStencil >::type Stencil
Export the stencil type for the provided grid index.
Definition: couplingmapperbase.hh:124
std::vector< typename IndexTraits< typename GridGeometry::GridView >::GridIndex > extractNodalDofs_(const typename GridGeometry::GridView::template Codim< 0 >::Entity &element, const GridGeometry &gridGeometry)
Creates a container with the nodal dofs within an element.
Definition: couplingmapperbase.hh:200
void update(const BulkFVG &bulkFvGridGeometry, const LowDimFVG &lowDimFvGridGeometry, std::shared_ptr< const Embeddings > embeddings)
Update coupling maps. This is the standard interface and has to be overloaded by the implementation.
Definition: couplingmapperbase.hh:140
LowDimCouplingMap & couplingMap_(GridIdType< lowDimId >, GridIdType< bulkId >)
returns non-const coupling data for lowDim -> bulk
Definition: couplingmapperbase.hh:219
const LowDimCouplingMap & couplingMap(GridIdType< lowDimId >, GridIdType< bulkId >) const
returns coupling data for lowDim -> bulk
Definition: couplingmapperbase.hh:150
void update_(const BulkFVG &bulkFvGridGeometry, const LowDimFVG &lowDimFvGridGeometry, std::shared_ptr< const Embeddings > embeddings, AddCouplingEntryPolicy &&addCouplingEntryPolicy)
Update coupling maps.
Definition: couplingmapperbase.hh:165
static constexpr auto bulkGridId
Export grid ids.
Definition: couplingmapperbase.hh:119
typename std::conditional< i==bulkId, BulkCouplingMap, LowDimCouplingMap >::type CouplingMap
Export the coupling map type.
Definition: couplingmapperbase.hh:128
BulkCouplingMap & couplingMap_(GridIdType< bulkId >, GridIdType< lowDimId >)
returns non-const coupling data for bulk -> lowDim
Definition: couplingmapperbase.hh:215
Defines the index types used for grid and local indices.
std::size_t numCorners(Shape shape)
Returns the number of corners of a given geometry.
Definition: throatproperties.hh:220
Definition: adapt.hh:17
typename GridView::IndexSet::IndexType GridIndex
Definition: indextraits.hh:27