22#ifndef DUMUX_BOX_FACETCOUPLING_MAPPER_HH
23#define DUMUX_BOX_FACETCOUPLING_MAPPER_HH
25#include <dune/common/indices.hh>
46template<
class BulkFVG,
class LowDimFVG, std::
size_t bulkId, std::
size_t lowDimId>
51 using LowDimElement =
typename LowDimFVG::GridView::template Codim<0>::Entity;
54 using BulkGridView =
typename BulkFVG::GridView;
55 using LowDimGridView =
typename LowDimFVG::GridView;
56 static constexpr int bulkDim = BulkGridView::dimension;
57 static constexpr int lowDimDim = LowDimGridView::dimension;
61 using ParentType::bulkGridId;
62 using ParentType::facetGridId;
72 template<
class Embeddings >
73 void update(
const BulkFVG& bulkFvGridGeometry,
74 const LowDimFVG& lowDimFvGridGeometry,
75 std::shared_ptr<const Embeddings> embeddings)
79 update(bulkFvGridGeometry, lowDimFvGridGeometry, embeddings, GridAdapter(embeddings));
90 template<
class Embeddings,
class CodimOneGr
idAdapter >
91 void update(
const BulkFVG& bulkFvGridGeometry,
92 const LowDimFVG& lowDimFvGridGeometry,
93 std::shared_ptr<const Embeddings> embeddings,
97 auto addCouplingEntryPolicy = [&] (
auto&& adjoinedEntityIndices,
98 const LowDimElement& lowDimElement,
99 const LowDimFVG& lowDimFvGridGeometry,
100 const BulkFVG& bulkFvGridGeometry)
105 const auto lowDimElemIdx = lowDimFvGridGeometry.elementMapper().index(lowDimElement);
106 auto& lowDimData = this->couplingMap_(facetGridId, bulkGridId)[lowDimElemIdx];
109 const auto& eg = lowDimElement.geometry();
110 const auto numElementCorners = eg.corners();
111 std::vector<BulkIndexType> elementCorners(numElementCorners);
112 for (
int i = 0; i < numElementCorners; ++i)
113 elementCorners[i] = codimOneGridAdapter.
bulkGridVertexIndex(lowDimElement.template subEntity<lowDimDim>(i));
116 const auto unsortedElemCorners = elementCorners;
117 std::sort(elementCorners.begin(), elementCorners.end());
119 auto fvGeometry =
localView(bulkFvGridGeometry);
120 for (
auto bulkElemIdx : adjoinedEntityIndices)
122 const auto bulkElement = bulkFvGridGeometry.element(bulkElemIdx);
123 const auto bulkRefElem = referenceElement(bulkElement);
126 const auto coupledFacetIndex = [&]
129 unsigned int coupledFacetIndex = 0;
130 std::vector<unsigned int> handledFacets;
131 for (
const auto& is : intersections(bulkFvGridGeometry.gridView(), bulkElement))
134 if (std::count(handledFacets.begin(), handledFacets.end(), is.indexInInside()))
137 handledFacets.push_back(is.indexInInside());
140 const auto numCorners = is.geometry().corners();
141 std::vector<BulkIndexType> facetIndices(
numCorners);
144 const auto vIdxLocal = bulkRefElem.subEntity(is.indexInInside(), 1, i, bulkDim);
145 facetIndices[i] = bulkFvGridGeometry.vertexMapper().vertexIndex(bulkElement.template subEntity<bulkDim>(vIdxLocal));
148 std::sort(facetIndices.begin(), facetIndices.end());
149 if ( std::equal(facetIndices.begin(), facetIndices.end(), elementCorners.begin(), elementCorners.end()) )
151 coupledFacetIndex = is.indexInInside();
158 DUNE_THROW(Dune::InvalidStateException,
"Could not find the bulk element coupling facet!");
160 return coupledFacetIndex;
164 fvGeometry.bindElement(bulkElement);
166 unsigned int foundCounter = 0;
167 std::vector<BulkIndexType> embeddedScvfIndices(numElementCorners);
168 for (
const auto& scvf : scvfs(fvGeometry))
170 if (scvf.interiorBoundary() && scvf.facetIndexInElement() == coupledFacetIndex)
175 const auto vIdxLocal = bulkRefElem.subEntity(coupledFacetIndex, 1, scvf.indexInElementFacet(), bulkDim);
176 const auto vIdxGlobal = bulkFvGridGeometry.vertexMapper().vertexIndex(bulkElement, vIdxLocal, bulkDim);
177 const auto it = std::find(unsortedElemCorners.begin(), unsortedElemCorners.end(), vIdxGlobal);
178 assert(it != unsortedElemCorners.end());
179 const auto lowDimElemLocalCornerIdx =
std::distance(unsortedElemCorners.begin(), it);
180 embeddedScvfIndices[lowDimElemLocalCornerIdx] = scvf.index();
186 if (foundCounter != numElementCorners)
187 DUNE_THROW(Dune::InvalidStateException,
"Found " << foundCounter <<
" instead of " << numElementCorners <<
" coupling scvfs in the bulk element");
190 auto& bulkData = this->couplingMap_(bulkGridId, facetGridId)[bulkElemIdx];
192 ? this->extractNodalDofs_(lowDimElement, lowDimFvGridGeometry)
193 : std::vector<LowDimIndexType>({lowDimElemIdx});
195 for (
auto lowDimDofIdx : lowDimElementDofs)
197 bulkData.couplingStencil.push_back(lowDimDofIdx);
198 auto& couplingScvfs = bulkData.dofToCouplingScvfMap[lowDimDofIdx];
199 couplingScvfs.insert(couplingScvfs.end(), embeddedScvfIndices.begin(), embeddedScvfIndices.end());
203 bulkData.couplingElementStencil.push_back(lowDimElemIdx);
204 auto& elemToScvfMap = bulkData.elementToScvfMap[lowDimElemIdx];
205 elemToScvfMap.insert(elemToScvfMap.end(), embeddedScvfIndices.begin(), embeddedScvfIndices.end());
208 lowDimData.embedments.emplace_back(bulkElemIdx, std::move(embeddedScvfIndices));
210 const auto bulkElementDofs = this->extractNodalDofs_(bulkElement, bulkFvGridGeometry);
211 for (
auto bulkDofIdx : bulkElementDofs)
212 lowDimData.couplingStencil.push_back(bulkDofIdx);
217 ParentType::update_(bulkFvGridGeometry, lowDimFvGridGeometry, embeddings, addCouplingEntryPolicy);
220 auto makeStencilUnique = [] (
auto& data)
222 auto& cs = data.second.couplingStencil;
223 std::sort(cs.begin(), cs.end());
224 cs.erase( std::unique(cs.begin(), cs.end()), cs.end() );
227 auto& lowDimCouplingData = this->couplingMap_(facetGridId, bulkGridId);
228 std::for_each(lowDimCouplingData.begin(), lowDimCouplingData.end(), makeStencilUnique);
233 auto& bulkCouplingData = this->couplingMap_(bulkGridId, facetGridId);
234 std::for_each(bulkCouplingData.begin(), bulkCouplingData.end(), makeStencilUnique);
Defines the index types used for grid and local indices.
The available discretization methods in Dumux.
static ctype distance(const Dune::FieldVector< ctype, dimWorld > &a, const Dune::FieldVector< ctype, dimWorld > &b)
Compute the shortest distance between two points.
Definition: distance.hh:292
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
constexpr Box box
Definition: method.hh:139
std::size_t numCorners(Shape shape)
Returns the number of corners of a given geometry.
Definition: throatproperties.hh:215
typename GridView::IndexSet::IndexType GridIndex
Definition: indextraits.hh:39
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:91
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:73
Adapter that allows retrieving information on a d-dimensional grid for entities of a (d-1)-dimensiona...
Definition: codimonegridadapter.hh:52
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:145
Implementation for the coupling mapper that sets up and stores the coupling maps between two domains ...
Definition: facet/couplingmapper.hh:52
Base class for the coupling mapper that sets up and stores the coupling maps between two domains of d...
Definition: couplingmapperbase.hh:51