GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/multidomain/facet/cellcentered/mpfa/couplingmapper.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 67 68 98.5%
Functions: 44 64 68.8%
Branches: 70 140 50.0%

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::FacetCouplingMapper
11 */
12 #ifndef DUMUX_CCMPFA_FACETCOUPLING_MAPPER_HH
13 #define DUMUX_CCMPFA_FACETCOUPLING_MAPPER_HH
14
15 #include <dune/common/indices.hh>
16 #include <dune/common/float_cmp.hh>
17
18 #include <dumux/common/indextraits.hh>
19 #include <dumux/discretization/method.hh>
20 #include <dumux/multidomain/facet/couplingmapper.hh>
21 #include <dumux/multidomain/facet/couplingmapperbase.hh>
22 #include <dumux/multidomain/facet/codimonegridadapter.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 * This specialization is for the bulk domain using the cell-centered
31 * scheme with multi-point flux approximation.
32 *
33 * \tparam BulkFVG The d-dimensional finite-volume grid geometry
34 * \tparam LowDimFVG The (d-1)-dimensional finite-volume grid geometry
35 * \tparam bulkId The index of the bulk grid within the hierarchy of grids
36 * \tparam lowDimId The index of the facet grid within the hierarchy of grids
37 */
38 template<class BulkFVG, class LowDimFVG, std::size_t bulkId, std::size_t lowDimId>
39 20 class FacetCouplingMapper<BulkFVG, LowDimFVG, bulkId, lowDimId, DiscretizationMethods::CCMpfa>
40 : public virtual FacetCouplingMapperBase<BulkFVG, LowDimFVG, bulkId, lowDimId>
41 {
42 using ParentType = FacetCouplingMapperBase<BulkFVG, LowDimFVG, bulkId, lowDimId>;
43
44 using BulkFVElementGeometry = typename BulkFVG::LocalView;
45 using BulkSubControlVolumeFace = typename BulkFVG::SubControlVolumeFace;
46
47 using BulkIndexType = typename IndexTraits<typename BulkFVG::GridView>::GridIndex;
48 using LowDimIndexType = typename IndexTraits<typename LowDimFVG::GridView>::GridIndex;
49
50 using LowDimElement = typename LowDimFVG::GridView::template Codim<0>::Entity;
51 using GlobalPosition = typename LowDimElement::Geometry::GlobalCoordinate;
52 static constexpr int lowDimDim = LowDimFVG::GridView::dimension;
53
54 public:
55 //! export domain ids
56 using ParentType::bulkGridId;
57 using ParentType::facetGridId;
58
59 /*!
60 * \brief Update coupling maps. This is the standard
61 * interface required by any mapper implementation.
62 *
63 * \param bulkFvGridGeometry The finite-volume grid geometry of the bulk grid
64 * \param lowDimFvGridGeometry The finite-volume grid geometry of the lower-dimensional grid
65 * \param embeddings Class that contains the embedments among the grids and entity insertion indices
66 */
67 template< class Embeddings >
68 16 void update(const BulkFVG& bulkFvGridGeometry,
69 const LowDimFVG& lowDimFvGridGeometry,
70 std::shared_ptr<const Embeddings> embeddings)
71 {
72 // forward to update function with instantiated vertex adapter
73 using GridAdapter = CodimOneGridAdapter<Embeddings, bulkGridId, facetGridId>;
74
4/12
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 16 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 16 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 16 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
32 update(bulkFvGridGeometry, lowDimFvGridGeometry, embeddings, GridAdapter(embeddings));
75 16 }
76
77 /*!
78 * \brief Update coupling maps. This is the standard
79 * interface required by any mapper implementation.
80 *
81 * \param bulkFvGridGeometry The finite-volume grid geometry of the bulk grid
82 * \param lowDimFvGridGeometry The finite-volume grid geometry of the lower-dimensional grid
83 * \param embeddings Class that contains the embedments among the grids and entity insertion indices
84 * \param codimOneGridAdapter Allows direct access to data on the bulk grid for lowdim grid entities
85 */
86 template< class Embeddings, class CodimOneGridAdapter >
87 16 void update(const BulkFVG& bulkFvGridGeometry,
88 const LowDimFVG& lowDimFvGridGeometry,
89 std::shared_ptr<const Embeddings> embeddings,
90 const CodimOneGridAdapter& codimOneGridAdapter)
91 {
92 // define the policy how to add map entries for given lowdim element and adjoined entity indices
93 4276 auto addCouplingEntryPolicy = [&] (auto&& adjoinedEntityIndices,
94 const LowDimElement& lowDimElement,
95 const LowDimFVG& lowDimFvGridGeometry,
96 508 const BulkFVG& bulkFvGridGeometry)
97 {
98 1016 const auto lowDimElemIdx = lowDimFvGridGeometry.elementMapper().index(lowDimElement);
99 1016 auto& lowDimData = this->couplingMap_(facetGridId, bulkGridId)[lowDimElemIdx];
100
101 // determine corner indices (in bulk grid indices)
102 508 const auto& lowDimGeometry = lowDimElement.geometry();
103 508 const auto numElementCorners = lowDimElement.subEntities(lowDimDim);
104
1/2
✓ Branch 2 taken 128 times.
✗ Branch 3 not taken.
1652 std::vector<BulkIndexType> elemCornerIndices(numElementCorners);
105
2/2
✓ Branch 0 taken 1144 times.
✓ Branch 1 taken 508 times.
1652 for (int i = 0; i < numElementCorners; ++i)
106
2/6
✓ Branch 1 taken 1144 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1144 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2288 elemCornerIndices[i] = codimOneGridAdapter.bulkGridVertexIndex(lowDimElement.template subEntity<lowDimDim>(i));
107
108 // Find the scvfs in the adjoined entities coinciding with the low dim element
109
3/8
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 380 times.
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1016 auto fvGeometry = localView(bulkFvGridGeometry);
110
4/4
✓ Branch 0 taken 996 times.
✓ Branch 1 taken 508 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 508 times.
3516 for (auto bulkElemIdx : adjoinedEntityIndices)
111 {
112
1/2
✓ Branch 1 taken 996 times.
✗ Branch 2 not taken.
1864 const auto bulkElement = bulkFvGridGeometry.element(bulkElemIdx);
113
1/2
✓ Branch 1 taken 996 times.
✗ Branch 2 not taken.
996 fvGeometry.bind(bulkElement);
114
115 1992 std::vector<BulkIndexType> embeddedScvfIndices;
116
5/6
✓ Branch 0 taken 8552 times.
✓ Branch 1 taken 996 times.
✓ Branch 2 taken 8552 times.
✓ Branch 3 taken 996 times.
✓ Branch 4 taken 3072 times.
✗ Branch 5 not taken.
10544 for (const auto& scvf : scvfs(fvGeometry))
117 {
118 // for non-boundary faces, it suffices to check if one
119 // of the outside scv indices is in the set of embedments
120
2/2
✓ Branch 0 taken 8458 times.
✓ Branch 1 taken 94 times.
8552 if (!scvf.boundary())
121 {
122
2/2
✓ Branch 0 taken 2208 times.
✓ Branch 1 taken 6250 times.
42290 if ( std::count(adjoinedEntityIndices.begin(), adjoinedEntityIndices.end(), scvf.outsideScvIdx()) )
123
1/2
✓ Branch 1 taken 2208 times.
✗ Branch 2 not taken.
2208 embeddedScvfIndices.push_back(scvf.index());
124 }
125
126 // otherwise, do float comparison of element and scvf facet corner
127 else
128 {
129
1/2
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
94 const auto eps = lowDimGeometry.volume()*1e-8;
130
1/2
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
110 const auto diffVec = lowDimGeometry.center()-fvGeometry.facetCorner(scvf);
131
132
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 54 times.
188 if ( Dune::FloatCmp::eq<GlobalPosition, Dune::FloatCmp::CmpStyle::absolute>(diffVec, GlobalPosition(0.0), eps) )
133
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 embeddedScvfIndices.push_back(scvf.index());
134 }
135 }
136
137 // Error tracking. The boundary scvf detection might has to be improved for very fine grids!?
138
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 996 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 996 times.
1992 if ( embeddedScvfIndices.size() != numElementCorners )
139 DUNE_THROW(Dune::InvalidStateException, "Could not find all coupling scvfs in embedment");
140
141 // add each dof in the low dim element to coupling stencil of the bulk element and vice versa
142
2/4
✓ Branch 1 taken 996 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 996 times.
✗ Branch 5 not taken.
1992 auto& bulkData = this->couplingMap_(bulkGridId, facetGridId)[bulkElemIdx];
143
4/10
✓ Branch 1 taken 996 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 996 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 996 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 996 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
3984 const auto lowDimElementDofs = LowDimFVG::discMethod == DiscretizationMethods::box
144 ? this->extractNodalDofs_(lowDimElement, lowDimFvGridGeometry)
145 : std::vector<LowDimIndexType>( {lowDimElemIdx} );
146
147 // add coupling info to all elements/scvfs in interaction volumes
148
4/4
✓ Branch 0 taken 996 times.
✓ Branch 1 taken 996 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 996 times.
3984 for (auto dofIdx : lowDimElementDofs)
149
4/4
✓ Branch 0 taken 2248 times.
✓ Branch 1 taken 996 times.
✓ Branch 2 taken 2248 times.
✓ Branch 3 taken 996 times.
7484 for (auto scvfIdx : embeddedScvfIndices)
150
1/2
✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
3728 this->addCouplingsFromIV_(bulkFvGridGeometry, fvGeometry.scvf(scvfIdx), fvGeometry, lowDimElemIdx, dofIdx);
151
152 // sort the scvfs according to the corners of the low dim element if box is used
153 // that allows identifying which scvf flux enters which low dim scv later
154 if (LowDimFVG::discMethod == DiscretizationMethods::box)
155 {
156 const auto copy = embeddedScvfIndices;
157
158 for (unsigned int i = 0; i < numElementCorners; ++i)
159 {
160 const auto& scvf = fvGeometry.scvf(copy[i]);
161 auto it = std::find(elemCornerIndices.begin(), elemCornerIndices.end(), scvf.vertexIndex());
162 assert(it != elemCornerIndices.end());
163 embeddedScvfIndices[ std::distance(elemCornerIndices.begin(), it) ] = copy[i];
164 }
165 }
166
167 // add info on which scvfs coincide with which low dim element
168
1/2
✓ Branch 1 taken 996 times.
✗ Branch 2 not taken.
996 auto& elemToScvfMap = bulkData.elementToScvfMap[lowDimElemIdx];
169
5/12
✓ Branch 1 taken 996 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 996 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 996 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 996 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 996 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
4980 elemToScvfMap.insert(elemToScvfMap.end(), embeddedScvfIndices.begin(), embeddedScvfIndices.end());
170
171 // add embedment
172
1/2
✓ Branch 1 taken 996 times.
✗ Branch 2 not taken.
996 lowDimData.embedments.emplace_back( bulkElemIdx, std::move(embeddedScvfIndices) );
173 }
174 };
175
176 // let the parent do the update subject to the execution policy defined above
177
2/6
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
16 ParentType::update_(bulkFvGridGeometry, lowDimFvGridGeometry, embeddings, addCouplingEntryPolicy);
178
179 // lambda to make a container unique
180 28156 auto makeUnique = [] (auto& c)
181 {
182 42234 std::sort(c.begin(), c.end());
183 70390 c.erase( std::unique(c.begin(), c.end()), c.end() );
184 };
185
186 // lambda to make bulk coupling map entry unique
187 4102 auto makeBulkMapEntryUnique = [&makeUnique] (auto& data)
188 {
189 2043 makeUnique(data.second.couplingStencil);
190 2043 makeUnique(data.second.couplingElementStencil);
191 6129 std::for_each(data.second.dofToCouplingScvfMap.begin(),
192 data.second.dofToCouplingScvfMap.end(),
193 9484 [&makeUnique] (auto& pair) { makeUnique(pair.second); });
194 };
195
196 // make bulk map unique
197 16 auto& bulkCouplingData = this->couplingMap_(bulkGridId, facetGridId);
198 48 std::for_each(bulkCouplingData.begin(), bulkCouplingData.end(), makeBulkMapEntryUnique);
199
200 // coupling stencils might not be unique in lowdim domain
201 16 auto& lowDimCouplingData = this->couplingMap_(facetGridId, bulkGridId);
202 48 std::for_each(lowDimCouplingData.begin(),
203 lowDimCouplingData.end(),
204 508 [&makeUnique] (auto& pair) { makeUnique(pair.second.couplingStencil); });
205 16 }
206
207 private:
208 void addCouplingsFromIV_(const BulkFVG& bulkFvGridGeometry,
209 const BulkSubControlVolumeFace& scvf,
210 const BulkFVElementGeometry& fvGeometry,
211 LowDimIndexType lowDimElemIdx,
212 LowDimIndexType lowDimDofIdx)
213 {
214
1/2
✓ Branch 1 taken 2248 times.
✗ Branch 2 not taken.
2248 const auto& gridIvIndexSets = bulkFvGridGeometry.gridInteractionVolumeIndexSets();
215 2248 if (bulkFvGridGeometry.vertexUsesSecondaryInteractionVolume(scvf.vertexIndex()))
216 addCouplingsFromIVIndexSet_(gridIvIndexSets.secondaryIndexSet(scvf), fvGeometry, lowDimElemIdx, lowDimDofIdx);
217 else
218
2/4
✓ Branch 1 taken 2248 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2248 times.
✗ Branch 5 not taken.
4496 addCouplingsFromIVIndexSet_(gridIvIndexSets.primaryIndexSet(scvf), fvGeometry, lowDimElemIdx, lowDimDofIdx);
219 }
220
221 template< class IVIndexSet >
222 2248 void addCouplingsFromIVIndexSet_(const IVIndexSet& indexSet,
223 const BulkFVElementGeometry& fvGeometry,
224 LowDimIndexType lowDimElemIdx,
225 LowDimIndexType lowDimDofIdx)
226 {
227 4496 auto& lowDimData = this->couplingMap_(facetGridId, bulkGridId)[lowDimElemIdx];
228
4/4
✓ Branch 0 taken 24010 times.
✓ Branch 1 taken 2248 times.
✓ Branch 2 taken 24010 times.
✓ Branch 3 taken 2248 times.
33002 for (auto bulkElemIdx : indexSet.gridScvIndices())
229 {
230 48020 auto& bulkData = this->couplingMap_(bulkGridId, facetGridId)[bulkElemIdx];
231
232 24010 lowDimData.couplingStencil.push_back( bulkElemIdx );
233 24010 bulkData.couplingStencil.push_back( lowDimDofIdx );
234 24010 bulkData.couplingElementStencil.push_back( lowDimElemIdx );
235 }
236
237 // insert scvf couplings stemming from this interaction volume
238
4/4
✓ Branch 0 taken 65332 times.
✓ Branch 1 taken 2248 times.
✓ Branch 2 taken 65332 times.
✓ Branch 3 taken 2248 times.
139656 for (auto scvfIdx : indexSet.gridScvfIndices())
239 {
240 65332 const auto& scvf = fvGeometry.scvf(scvfIdx);
241 130664 auto& bulkData = this->couplingMap_(bulkGridId, facetGridId)[scvf.insideScvIdx()];
242 65332 auto& couplingScvfs = bulkData.dofToCouplingScvfMap[lowDimDofIdx];
243 195996 couplingScvfs.insert(couplingScvfs.end(), scvfIdx);
244 }
245 2248 }
246 };
247
248 } // end namespace Dumux
249
250 #endif
251