Line | Branch | Exec | Source |
---|---|---|---|
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 | // | ||
7 | /*! | ||
8 | * \file | ||
9 | * \ingroup FacetCoupling | ||
10 | * \copydoc Dumux::FacetCouplingMapperBase | ||
11 | */ | ||
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> | ||
22 | #include <dumux/common/indextraits.hh> | ||
23 | |||
24 | namespace Dumux { | ||
25 | |||
26 | /*! | ||
27 | * \ingroup FacetCoupling | ||
28 | * \brief Base class for the coupling mapper that sets up and stores | ||
29 | * the coupling maps between two domains of dimension d and (d-1). | ||
30 | * | ||
31 | * \tparam BulkFVG the d-dimensional finite-volume grid geometry | ||
32 | * \tparam LowDimFVG the (d-1)-dimensional finite-volume grid geometry | ||
33 | * \tparam bulkId The index of the bulk grid within the hierarchy of grids | ||
34 | * \tparam lowDimId The index of the facet grid within the hierarchy of grids | ||
35 | */ | ||
36 | template< class BulkFVG, | ||
37 | class LowDimFVG, | ||
38 | std::size_t bulkId, | ||
39 | std::size_t lowDimId> | ||
40 | 140 | class FacetCouplingMapperBase | |
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 | |||
72 | /*! | ||
73 | * \brief Data structure to store coupling data on the | ||
74 | * lower-dimensional grid as seen from the bulk grid. | ||
75 | */ | ||
76 | ✗ | struct BulkCouplingData | |
77 | { | ||
78 | //! dof indices of the lower-dimensional domain coupled to this element | ||
79 | std::vector< LowDimIndexType > couplingStencil; | ||
80 | |||
81 | //! indices of the elements in the stencil of this bulk element | ||
82 | std::vector< LowDimIndexType > couplingElementStencil; | ||
83 | |||
84 | //! For each dof in coupling stencil, we store a list of scvfs whose fluxes depend on it | ||
85 | std::unordered_map< LowDimIndexType, std::vector<BulkIndexType> > dofToCouplingScvfMap; | ||
86 | |||
87 | //! For each embedded low dim element, we store the scvfs that coincide with it | ||
88 | std::unordered_map< LowDimIndexType, std::vector<BulkIndexType> > elementToScvfMap; | ||
89 | }; | ||
90 | |||
91 | /*! | ||
92 | * \brief Data structure to store coupling data on the | ||
93 | * bulk grid as seen from the lower-dimensional grid. | ||
94 | */ | ||
95 | ✗ | struct LowDimCouplingData | |
96 | { | ||
97 | //! indices of the bulk dofs coupled to this element | ||
98 | std::vector< BulkIndexType > couplingStencil; | ||
99 | |||
100 | //! for each bulk neighbor we store a list of scvfs that coincide with the low dim element | ||
101 | using Embedment = std::pair< BulkIndexType, std::vector<BulkIndexType> >; | ||
102 | std::vector< Embedment > embedments; | ||
103 | }; | ||
104 | |||
105 | //! data structures used for the coupling maps | ||
106 | using BulkCouplingMap = std::unordered_map<BulkIndexType, BulkCouplingData>; | ||
107 | using LowDimCouplingMap = std::unordered_map<LowDimIndexType, LowDimCouplingData>; | ||
108 | |||
109 | //! Coupling stencil types to facilitate type export below | ||
110 | using LowDimStencil = std::vector<LowDimIndexType>; | ||
111 | using BulkStencil = std::vector<BulkIndexType>; | ||
112 | |||
113 | //! The grid id type | ||
114 | template<std::size_t id> | ||
115 | using GridIdType = Dune::index_constant<id>; | ||
116 | |||
117 | public: | ||
118 | //! Export grid ids | ||
119 | static constexpr auto bulkGridId = GridIdType<bulkId>(); | ||
120 | static constexpr auto facetGridId = GridIdType<lowDimId>(); | ||
121 | |||
122 | //! Export the stencil type for the provided grid index | ||
123 | template<std::size_t id> | ||
124 | using Stencil = typename std::conditional<id == bulkId, BulkStencil, LowDimStencil>::type; | ||
125 | |||
126 | //! Export the coupling map type | ||
127 | template<std::size_t i, std::size_t j> | ||
128 | using CouplingMap = typename std::conditional<i == bulkId, BulkCouplingMap, LowDimCouplingMap>::type; | ||
129 | |||
130 | //! Allow retrievment of grid id for a given grid dimension | ||
131 | template<int dim> | ||
132 | static constexpr GridIdType< (dim == bulkDim ? bulkId : lowDimId) > gridId() | ||
133 | { return GridIdType< (dim == bulkDim ? bulkId : lowDimId) >(); } | ||
134 | |||
135 | /*! | ||
136 | * \brief Update coupling maps. This is the standard interface | ||
137 | * and has to be overloaded by the implementation. | ||
138 | */ | ||
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 | |||
145 | //! returns coupling data for bulk -> lowDim | ||
146 | ✗ | const BulkCouplingMap& couplingMap(GridIdType<bulkId>, GridIdType<lowDimId>) const | |
147 |
5/9✗ Branch 3 not taken.
✓ Branch 4 taken 83416 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 69760 times.
✓ Branch 7 taken 96 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 4224 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1056 times.
|
25738186 | { return bulkCouplingData_; } |
148 | |||
149 | //! returns coupling data for lowDim -> bulk | ||
150 | ✗ | const LowDimCouplingMap& couplingMap(GridIdType<lowDimId>, GridIdType<bulkId>) const | |
151 | 965574 | { return lowDimCouplingData_; } | |
152 | |||
153 | protected: | ||
154 | |||
155 | /*! | ||
156 | * \brief Update coupling maps. | ||
157 | * | ||
158 | * \param bulkFvGridGeometry The finite-volume grid geometry of the bulk grid | ||
159 | * \param lowDimFvGridGeometry The finite-volume grid geometry of the lower-dimensional grid | ||
160 | * \param embeddings Class that contains the embedments and allows obtaining entity insertion indices | ||
161 | * \param addCouplingEntryPolicy Policy for adding coupling entries starting from a lower-dimensional | ||
162 | * element and corresponding adjoined higher-dimensional entity indices | ||
163 | */ | ||
164 | template< class Embeddings, typename AddCouplingEntryPolicy > | ||
165 | 112 | 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 | 112 | bulkCouplingData_.clear(); | |
175 | 112 | lowDimCouplingData_.clear(); | |
176 | |||
177 | // set up maps between element indices and insertion indices | ||
178 |
1/2✓ Branch 2 taken 84 times.
✗ Branch 3 not taken.
|
224 | const auto bulkInsertionToElemIdxMap = makeInsertionToGridIndexMap_(embeddings, bulkFvGridGeometry); |
179 | |||
180 | // set up coupling maps coming from the low dim domain | ||
181 |
5/6✓ Branch 2 taken 2698 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 2698 times.
✓ Branch 5 taken 84 times.
✓ Branch 7 taken 2698 times.
✗ Branch 8 not taken.
|
3514 | for (const auto& element : elements(lowDimFvGridGeometry.gridView())) |
182 | { | ||
183 |
4/8✓ Branch 1 taken 2698 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2698 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1520 times.
✓ Branch 7 taken 1178 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
11738 | auto adjoinedEntities = embeddings->template adjoinedEntityIndices<lowDimId>(element); |
184 | |||
185 | // proceed only if element is embedded | ||
186 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2698 times.
|
3290 | if (adjoinedEntities.size() == 0) |
187 | ✗ | continue; | |
188 | |||
189 | // turn (insertion) indices into actual grid element indices ... | ||
190 |
2/3✓ Branch 1 taken 1248 times.
✓ Branch 2 taken 4120 times.
✗ Branch 3 not taken.
|
6616 | std::for_each(adjoinedEntities.begin(), adjoinedEntities.end(), [&] (auto& idx) { idx = bulkInsertionToElemIdxMap.at(idx); }); |
191 | |||
192 | // ... and add them | ||
193 |
1/2✓ Branch 1 taken 2698 times.
✗ Branch 2 not taken.
|
3290 | addCouplingEntryPolicy(std::move(adjoinedEntities), element, lowDimFvGridGeometry, bulkFvGridGeometry); |
194 | } | ||
195 | 112 | } | |
196 | |||
197 | //! Creates a container with the nodal dofs within an element | ||
198 | template< class GridGeometry> | ||
199 | std::vector< typename IndexTraits<typename GridGeometry::GridView>::GridIndex > | ||
200 | 3680 | 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 |
0/2✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
3680 | const auto numCorners = element.subEntities(dim); |
207 |
0/4✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
7360 | std::vector< GridIndexType > nodalDofs(numCorners); |
208 |
2/2✓ Branch 0 taken 7576 times.
✓ Branch 1 taken 1968 times.
|
17808 | for (unsigned int i = 0; i < numCorners; ++i) |
209 |
2/4✓ Branch 1 taken 7576 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7576 times.
✗ Branch 5 not taken.
|
28256 | nodalDofs[i] = gridGeometry.vertexMapper().subIndex(element, i, dim); |
210 | |||
211 | 3680 | return nodalDofs; | |
212 | } | ||
213 | |||
214 | //! returns non-const coupling data for bulk -> lowDim | ||
215 | ✗ | BulkCouplingMap& couplingMap_(GridIdType<bulkId>, GridIdType<lowDimId>) | |
216 |
4/7✓ Branch 1 taken 3700 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 996 times.
✓ Branch 4 taken 640 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 32 times.
✗ Branch 7 not taken.
|
94748 | { return bulkCouplingData_; } |
217 | |||
218 | //! returns non-const coupling data for lowDim -> bulk | ||
219 | ✗ | LowDimCouplingMap& couplingMap_(GridIdType<lowDimId>, GridIdType<bulkId>) | |
220 | 4988 | { return lowDimCouplingData_; } | |
221 | |||
222 | private: | ||
223 | |||
224 | //! Creates the map from element insertion index to grid element index | ||
225 | template< class Embeddings, class GridGeometry> | ||
226 | std::unordered_map< typename IndexTraits<typename GridGeometry::GridView>::GridIndex, typename IndexTraits<typename GridGeometry::GridView>::GridIndex > | ||
227 | 84 | makeInsertionToGridIndexMap_(std::shared_ptr<const Embeddings> embeddings, const GridGeometry& gridGeometry) const | |
228 | { | ||
229 | using GridIndexType = typename IndexTraits<typename GridGeometry::GridView>::GridIndex; | ||
230 | |||
231 |
1/2✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
|
84 | std::unordered_map< GridIndexType, GridIndexType > map; |
232 |
13/16✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 56 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 40 times.
✓ Branch 7 taken 56 times.
✓ Branch 8 taken 40 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 55 times.
✓ Branch 11 taken 40 times.
✓ Branch 12 taken 143532 times.
✓ Branch 13 taken 55 times.
✓ Branch 14 taken 143532 times.
✓ Branch 15 taken 55 times.
✓ Branch 17 taken 143532 times.
✗ Branch 18 not taken.
|
308050 | for (const auto& e : elements(gridGeometry.gridView())) |
233 |
7/14✓ Branch 1 taken 143572 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 143572 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 143572 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 143572 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 143572 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 143572 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 143572 times.
✗ Branch 20 not taken.
|
307756 | map.insert( std::make_pair( embeddings->template insertionIndex<bulkId>(e), gridGeometry.elementMapper().index(e) ) ); |
234 | |||
235 | 84 | return map; | |
236 | } | ||
237 | |||
238 | BulkCouplingMap bulkCouplingData_; //!< stores data on the coupled elements for each bulk element | ||
239 | LowDimCouplingMap lowDimCouplingData_; //!< stores data on the coupled elements for each low dim element | ||
240 | }; | ||
241 | |||
242 | } // end namespace Dumux | ||
243 | |||
244 | #endif | ||
245 |