81 void update(
const BulkFVG& bulkFvGridGeometry,
82 const LowDimFVG& lowDimFvGridGeometry,
83 std::shared_ptr<const Embeddings> embeddings,
87 auto addCouplingEntryPolicy = [&] (
auto&& adjoinedEntityIndices,
88 const LowDimElement& lowDimElement,
89 const LowDimFVG& lowDimFvGridGeometry,
90 const BulkFVG& bulkFvGridGeometry)
95 const auto lowDimElemIdx = lowDimFvGridGeometry.elementMapper().index(lowDimElement);
96 auto& lowDimData = this->couplingMap_(facetGridId, bulkGridId)[lowDimElemIdx];
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));
106 const auto unsortedElemCorners = elementCorners;
107 std::sort(elementCorners.begin(), elementCorners.end());
109 auto fvGeometry =
localView(bulkFvGridGeometry);
110 for (
auto bulkElemIdx : adjoinedEntityIndices)
112 const auto bulkElement = bulkFvGridGeometry.element(bulkElemIdx);
113 const auto bulkRefElem = referenceElement(bulkElement);
116 const auto coupledFacetIndex = [&]
119 unsigned int coupledFacetIndex = 0;
120 std::vector<unsigned int> handledFacets;
121 for (
const auto& is : intersections(bulkFvGridGeometry.gridView(), bulkElement))
124 if (std::count(handledFacets.begin(), handledFacets.end(), is.indexInInside()))
127 handledFacets.push_back(is.indexInInside());
130 const auto numCorners = is.geometry().corners();
131 std::vector<BulkIndexType> facetIndices(numCorners);
132 for (
int i = 0; i < numCorners; ++i)
134 const auto vIdxLocal = bulkRefElem.subEntity(is.indexInInside(), 1, i, bulkDim);
135 facetIndices[i] = bulkFvGridGeometry.vertexMapper().vertexIndex(bulkElement.template subEntity<bulkDim>(vIdxLocal));
138 std::sort(facetIndices.begin(), facetIndices.end());
139 if ( std::equal(facetIndices.begin(), facetIndices.end(), elementCorners.begin(), elementCorners.end()) )
141 coupledFacetIndex = is.indexInInside();
148 DUNE_THROW(Dune::InvalidStateException,
"Could not find the bulk element coupling facet!");
150 return coupledFacetIndex;
154 fvGeometry.bindElement(bulkElement);
156 unsigned int foundCounter = 0;
157 std::vector<BulkIndexType> embeddedScvfIndices(numElementCorners);
158 for (
const auto& scvf : scvfs(fvGeometry))
160 if (scvf.interiorBoundary() && scvf.facetIndexInElement() == coupledFacetIndex)
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();
176 if (foundCounter != numElementCorners)
177 DUNE_THROW(Dune::InvalidStateException,
"Found " << foundCounter <<
" instead of " << numElementCorners <<
" coupling scvfs in the bulk element");
180 auto& bulkData = this->couplingMap_(bulkGridId, facetGridId)[bulkElemIdx];
182 ? this->extractNodalDofs_(lowDimElement, lowDimFvGridGeometry)
183 : std::vector<LowDimIndexType>({lowDimElemIdx});
185 for (
auto lowDimDofIdx : lowDimElementDofs)
187 bulkData.couplingStencil.push_back(lowDimDofIdx);
188 auto& couplingScvfs = bulkData.dofToCouplingScvfMap[lowDimDofIdx];
189 couplingScvfs.insert(couplingScvfs.end(), embeddedScvfIndices.begin(), embeddedScvfIndices.end());
193 bulkData.couplingElementStencil.push_back(lowDimElemIdx);
194 auto& elemToScvfMap = bulkData.elementToScvfMap[lowDimElemIdx];
195 elemToScvfMap.insert(elemToScvfMap.end(), embeddedScvfIndices.begin(), embeddedScvfIndices.end());
198 lowDimData.embedments.emplace_back(bulkElemIdx, std::move(embeddedScvfIndices));
200 const auto bulkElementDofs = this->extractNodalDofs_(bulkElement, bulkFvGridGeometry);
201 for (
auto bulkDofIdx : bulkElementDofs)
202 lowDimData.couplingStencil.push_back(bulkDofIdx);
207 ParentType::update_(bulkFvGridGeometry, lowDimFvGridGeometry, embeddings, addCouplingEntryPolicy);
210 auto makeStencilUnique = [] (
auto& data)
212 auto& cs = data.second.couplingStencil;
213 std::sort(cs.begin(), cs.end());
214 cs.erase( std::unique(cs.begin(), cs.end()), cs.end() );
217 auto& lowDimCouplingData = this->couplingMap_(facetGridId, bulkGridId);
218 std::for_each(lowDimCouplingData.begin(), lowDimCouplingData.end(), makeStencilUnique);
223 auto& bulkCouplingData = this->couplingMap_(bulkGridId, facetGridId);
224 std::for_each(bulkCouplingData.begin(), bulkCouplingData.end(), makeStencilUnique);