version 3.9.0
Loading...
Searching...
No Matches
facet/box/couplingmapper.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_BOX_FACETCOUPLING_MAPPER_HH
13#define DUMUX_BOX_FACETCOUPLING_MAPPER_HH
14
15#include <dune/common/indices.hh>
16
22
23namespace Dumux {
24
36template<class BulkFVG, class LowDimFVG, std::size_t bulkId, std::size_t lowDimId>
37class FacetCouplingMapper<BulkFVG, LowDimFVG, bulkId, lowDimId, DiscretizationMethods::Box>
38: public virtual FacetCouplingMapperBase<BulkFVG, LowDimFVG, bulkId, lowDimId>
39{
41 using LowDimElement = typename LowDimFVG::GridView::template Codim<0>::Entity;
42
43 // dimensions of the two grids
44 using BulkGridView = typename BulkFVG::GridView;
45 using LowDimGridView = typename LowDimFVG::GridView;
46 static constexpr int bulkDim = BulkGridView::dimension;
47 static constexpr int lowDimDim = LowDimGridView::dimension;
48
49public:
51 using ParentType::bulkGridId;
52 using ParentType::facetGridId;
53
62 template< class Embeddings >
63 void update(const BulkFVG& bulkFvGridGeometry,
64 const LowDimFVG& lowDimFvGridGeometry,
65 std::shared_ptr<const Embeddings> embeddings)
66 {
67 // forward to update function with instantiated vertex adapter
69 update(bulkFvGridGeometry, lowDimFvGridGeometry, embeddings, GridAdapter(embeddings));
70 }
71
80 template< class Embeddings, class CodimOneGridAdapter >
81 void update(const BulkFVG& bulkFvGridGeometry,
82 const LowDimFVG& lowDimFvGridGeometry,
83 std::shared_ptr<const Embeddings> embeddings,
84 const CodimOneGridAdapter& codimOneGridAdapter)
85 {
86 // define the policy how to add map entries for given lowdim element and adjoined entity indices
87 auto addCouplingEntryPolicy = [&] (auto&& adjoinedEntityIndices,
88 const LowDimElement& lowDimElement,
89 const LowDimFVG& lowDimFvGridGeometry,
90 const BulkFVG& bulkFvGridGeometry)
91 {
92 using LowDimIndexType = typename IndexTraits<LowDimGridView>::GridIndex;
93 using BulkIndexType = typename IndexTraits<BulkGridView>::GridIndex;
94
95 const auto lowDimElemIdx = lowDimFvGridGeometry.elementMapper().index(lowDimElement);
96 auto& lowDimData = this->couplingMap_(facetGridId, bulkGridId)[lowDimElemIdx];
97
98 // determine corner indices (in bulk grid indices)
99 const auto& eg = lowDimElement.geometry();
100 const auto numElementCorners = eg.corners();
101 std::vector<BulkIndexType> elementCorners(numElementCorners);
102 for (int i = 0; i < numElementCorners; ++i)
103 elementCorners[i] = codimOneGridAdapter.bulkGridVertexIndex(lowDimElement.template subEntity<lowDimDim>(i));
104
105 // save unsorted set of corner indices and search scvfs in adjoined entities
106 const auto unsortedElemCorners = elementCorners;
107 std::sort(elementCorners.begin(), elementCorners.end());
108
109 auto fvGeometry = localView(bulkFvGridGeometry);
110 for (auto bulkElemIdx : adjoinedEntityIndices)
111 {
112 const auto bulkElement = bulkFvGridGeometry.element(bulkElemIdx);
113 const auto bulkRefElem = referenceElement(bulkElement);
114
115 // find the bulk element facet that lies on this low dim element (assumes conformity!)
116 const auto coupledFacetIndex = [&]
117 {
118 bool found = false;
119 unsigned int coupledFacetIndex = 0;
120 std::vector<unsigned int> handledFacets;
121 for (const auto& is : intersections(bulkFvGridGeometry.gridView(), bulkElement))
122 {
123 // skip already handled facets (necessary for e.g. Dune::FoamGrid)
124 if (std::count(handledFacets.begin(), handledFacets.end(), is.indexInInside()))
125 continue;
126
127 handledFacets.push_back(is.indexInInside());
128
129 // determine if it lies on low dim element by comparing corner indices
130 const auto numCorners = is.geometry().corners();
131 std::vector<BulkIndexType> facetIndices(numCorners);
132 for (int i = 0; i < numCorners; ++i)
133 {
134 const auto vIdxLocal = bulkRefElem.subEntity(is.indexInInside(), 1, i, bulkDim);
135 facetIndices[i] = bulkFvGridGeometry.vertexMapper().vertexIndex(bulkElement.template subEntity<bulkDim>(vIdxLocal));
136 }
137
138 std::sort(facetIndices.begin(), facetIndices.end());
139 if ( std::equal(facetIndices.begin(), facetIndices.end(), elementCorners.begin(), elementCorners.end()) )
140 {
141 coupledFacetIndex = is.indexInInside();
142 found = true; break;
143 }
144 }
145
146 // ensure that we found the facet!
147 if (!found)
148 DUNE_THROW(Dune::InvalidStateException, "Could not find the bulk element coupling facet!");
149
150 return coupledFacetIndex;
151 }();
152
153 // we should always find numElementCorners coupling scvfs
154 fvGeometry.bindElement(bulkElement);
155
156 unsigned int foundCounter = 0;
157 std::vector<BulkIndexType> embeddedScvfIndices(numElementCorners);
158 for (const auto& scvf : scvfs(fvGeometry))
159 {
160 if (scvf.interiorBoundary() && scvf.facetIndexInElement() == coupledFacetIndex)
161 {
162 // we want to order the set of scvfs lying on the lower-dimensional element such that the i-th scvf
163 // coincides with the i-th low dim element corner. This will help later to identify which scvf fluxes
164 // enter which scv of the low dim element if the lower-dimensional domain uses the box scheme
165 const auto vIdxLocal = bulkRefElem.subEntity(coupledFacetIndex, 1, scvf.indexInElementFacet(), bulkDim);
166 const auto vIdxGlobal = bulkFvGridGeometry.vertexMapper().vertexIndex(bulkElement, vIdxLocal, bulkDim);
167 const auto it = std::find(unsortedElemCorners.begin(), unsortedElemCorners.end(), vIdxGlobal);
168 assert(it != unsortedElemCorners.end());
169 const auto lowDimElemLocalCornerIdx = std::distance(unsortedElemCorners.begin(), it);
170 embeddedScvfIndices[lowDimElemLocalCornerIdx] = scvf.index();
171 foundCounter++;
172 }
173 }
174
175 // ensure we found all scvfs
176 if (foundCounter != numElementCorners)
177 DUNE_THROW(Dune::InvalidStateException, "Found " << foundCounter << " instead of " << numElementCorners << " coupling scvfs in the bulk element");
178
179 // add each dof in the low dim element to coupling stencil of the bulk element
180 auto& bulkData = this->couplingMap_(bulkGridId, facetGridId)[bulkElemIdx];
181 const auto lowDimElementDofs = LowDimFVG::discMethod == DiscretizationMethods::box
182 ? this->extractNodalDofs_(lowDimElement, lowDimFvGridGeometry)
183 : std::vector<LowDimIndexType>({lowDimElemIdx});
184
185 for (auto lowDimDofIdx : lowDimElementDofs)
186 {
187 bulkData.couplingStencil.push_back(lowDimDofIdx);
188 auto& couplingScvfs = bulkData.dofToCouplingScvfMap[lowDimDofIdx];
189 couplingScvfs.insert(couplingScvfs.end(), embeddedScvfIndices.begin(), embeddedScvfIndices.end());
190 }
191
192 // add info on which scvfs coincide with which low dim element
193 bulkData.couplingElementStencil.push_back(lowDimElemIdx);
194 auto& elemToScvfMap = bulkData.elementToScvfMap[lowDimElemIdx];
195 elemToScvfMap.insert(elemToScvfMap.end(), embeddedScvfIndices.begin(), embeddedScvfIndices.end());
196
197 // add embedment and the bulk cell dofs to coupling stencil of low dim element
198 lowDimData.embedments.emplace_back(bulkElemIdx, std::move(embeddedScvfIndices));
199
200 const auto bulkElementDofs = this->extractNodalDofs_(bulkElement, bulkFvGridGeometry);
201 for (auto bulkDofIdx : bulkElementDofs)
202 lowDimData.couplingStencil.push_back(bulkDofIdx);
203 }
204 };
205
206 // let the parent do the update subject to the execution policy defined above
207 ParentType::update_(bulkFvGridGeometry, lowDimFvGridGeometry, embeddings, addCouplingEntryPolicy);
208
209 // coupling stencils might not be unique with the policy above
210 auto makeStencilUnique = [] (auto& data)
211 {
212 auto& cs = data.second.couplingStencil;
213 std::sort(cs.begin(), cs.end());
214 cs.erase( std::unique(cs.begin(), cs.end()), cs.end() );
215 };
216
217 auto& lowDimCouplingData = this->couplingMap_(facetGridId, bulkGridId);
218 std::for_each(lowDimCouplingData.begin(), lowDimCouplingData.end(), makeStencilUnique);
219
220 // bulk coupling stencil is only non-unique if box is used
221 if (LowDimFVG::discMethod == DiscretizationMethods::box)
222 {
223 auto& bulkCouplingData = this->couplingMap_(bulkGridId, facetGridId);
224 std::for_each(bulkCouplingData.begin(), bulkCouplingData.end(), makeStencilUnique);
225 }
226 }
227};
228
229} // end namespace Dumux
230
231#endif
Adapter that allows retrieving information on a d-dimensional grid for entities of a (d-1)-dimensiona...
Definition codimonegridadapter.hh:40
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:133
void update(const BulkFVG &bulkFvGridGeometry, const LowDimFVG &lowDimFvGridGeometry, std::shared_ptr< const Embeddings > embeddings, const CodimOneGridAdapter &codimOneGridAdapter)
Update coupling maps with a given grid adapter.
Definition facet/box/couplingmapper.hh:81
void update(const BulkFVG &bulkFvGridGeometry, const LowDimFVG &lowDimFvGridGeometry, std::shared_ptr< const Embeddings > embeddings)
Update coupling maps. This is the standard interface required by any mapper implementation.
Definition facet/box/couplingmapper.hh:63
Base class for the coupling mapper that sets up and stores the coupling maps between two domains of d...
Definition couplingmapperbase.hh:41
Implementation for the coupling mapper that sets up and stores the coupling maps between two domains ...
Definition facet/couplingmapper.hh:42
Adapter that allows retrieving information on a d-dimensional grid for entities of a (d-1)-dimensiona...
Base class for the coupling mapper that sets up and stores the coupling maps between two domains of d...
Implementation for the coupling mapper that sets up and stores the coupling maps between two domains ...
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition localview.hh:26
Defines the index types used for grid and local indices.
The available discretization methods in Dumux.
constexpr Box box
Definition method.hh:147
Definition adapt.hh:17
typename GridView::IndexSet::IndexType GridIndex
Definition indextraits.hh:27