94 using GridView =
typename GG::GridView;
99 using Element =
typename GridView::template Codim<0>::Entity;
109 template<
class CellCenterOrFaceFVGr
idGeometry>
111 : gridGeometryPtr_(&
gridGeometry.actualGridGeometry()) {}
120 return scvf(this->
gridGeometry().localToGlobalScvfIndex(eIdx, localScvfIdx));
127 if (scvIdx == scvIndices_[0])
130 return neighborScvs_[findLocalIndex_(scvIdx, neighborScvIndices_)];
137 auto it = std::find(scvfIndices_.begin(), scvfIndices_.end(), scvfIdx);
138 if (it != scvfIndices_.end())
139 return scvfs_[std::distance(scvfIndices_.begin(), it)];
141 return neighborScvfs_[findLocalIndex_(scvfIdx, neighborScvfIndices_)];
149 friend inline Dune::IteratorRange<typename std::array<SubControlVolume, 1>::const_iterator>
152 using IteratorType =
typename std::array<SubControlVolume, 1>::const_iterator;
153 return Dune::IteratorRange<IteratorType>(g.scvs_.begin(), g.scvs_.end());
161 friend inline Dune::IteratorRange<typename std::vector<SubControlVolumeFace>::const_iterator>
164 using IteratorType =
typename std::vector<SubControlVolumeFace>::const_iterator;
165 return Dune::IteratorRange<IteratorType>(g.scvfs_.begin(), g.scvfs_.end());
170 {
return scvs_.size(); }
174 {
return scvfs_.size(); }
184 return std::move(*
this);
199 return std::move(*
this);
204 { this->bindElement_(
element); }
208 {
return static_cast<bool>(element_); }
212 {
return *element_; }
216 {
return *gridGeometryPtr_; }
220 {
return hasBoundaryScvf_; }
224 void bindElement_(
const Element& element)
228 scvfs_.reserve(element.subEntities(1));
229 scvfIndices_.reserve(element.subEntities(1));
230 makeElementGeometries_();
235 void bind_(
const Element& element)
237 bindElement_(element);
239 neighborScvs_.reserve(element.subEntities(1));
240 neighborScvfIndices_.reserve(element.subEntities(1));
241 neighborScvfs_.reserve(element.subEntities(1));
243 std::vector<GridIndexType> handledNeighbors;
244 handledNeighbors.reserve(element.subEntities(1));
245 for (
const auto& intersection : intersections(gridGeometry().gridView(), element))
247 if (intersection.neighbor())
249 const auto outside = intersection.outside();
250 const auto outsideIdx = gridGeometry().elementMapper().index(outside);
253 if ( std::find(handledNeighbors.begin(), handledNeighbors.end(), outsideIdx) == handledNeighbors.end() )
255 makeNeighborGeometries_(outside, outsideIdx);
256 handledNeighbors.push_back(outsideIdx);
263 void makeElementGeometries_()
265 const auto&
element = *element_;
266 const auto eIdx = gridGeometry().elementMapper().index(element);
267 scvs_[0] = SubControlVolume(
element.geometry(), eIdx);
268 scvIndices_[0] = eIdx;
270 const auto& scvFaceIndices = gridGeometry().scvfIndicesOfScv(eIdx);
271 const auto& neighborVolVarIndices = gridGeometry().neighborVolVarIndices(eIdx);
273 typename GridGeometry::GeometryHelper geometryHelper(element, gridGeometry().gridView());
276 for (
const auto& intersection : intersections(gridGeometry().gridView(), element))
278 const auto& scvfNeighborVolVarIndex = neighborVolVarIndices[scvfCounter];
280 if (intersection.neighbor() || intersection.boundary())
282 geometryHelper.updateLocalFace(gridGeometry().intersectionMapper(), intersection);
283 std::vector<GridIndexType> scvIndices{eIdx, scvfNeighborVolVarIndex};
284 scvfs_.emplace_back(intersection,
285 intersection.geometry(),
286 scvFaceIndices[scvfCounter],
289 scvfIndices_.emplace_back(scvFaceIndices[scvfCounter]);
292 if (intersection.boundary())
293 hasBoundaryScvf_ =
true;
299 void makeNeighborGeometries_(
const Element& element,
const GridIndexType eIdx)
304 neighborScvs_.emplace_back(
element.geometry(), eIdx);
305 neighborScvIndices_.push_back(eIdx);
307 const auto& scvFaceIndices = gridGeometry().scvfIndicesOfScv(eIdx);
308 const auto& neighborVolVarIndices = gridGeometry().neighborVolVarIndices(eIdx);
310 typename GridGeometry::GeometryHelper geometryHelper(element, gridGeometry().gridView());
313 for (
const auto& intersection : intersections(gridGeometry().gridView(), element))
315 const auto& scvfNeighborVolVarIndex = neighborVolVarIndices[scvfCounter];
316 geometryHelper.updateLocalFace(gridGeometry().intersectionMapper(), intersection);
318 if (intersection.neighbor())
321 if (intersection.outside() == *element_)
323 std::vector<GridIndexType> scvIndices{eIdx, scvfNeighborVolVarIndex};
324 neighborScvfs_.emplace_back(intersection,
325 intersection.geometry(),
326 scvFaceIndices[scvfCounter],
330 neighborScvfIndices_.push_back(scvFaceIndices[scvfCounter]);
334 else if (intersection.boundary())
339 const LocalIndexType findLocalIndex_(
const GridIndexType idx,
340 const std::vector<GridIndexType>& indices)
const
342 auto it = std::find(indices.begin(), indices.end(), idx);
343 assert(it != indices.end() &&
"Could not find the scv/scvf! Make sure to properly bind this class!");
344 return std::distance(indices.begin(), it);
350 scvfIndices_.clear();
353 neighborScvIndices_.clear();
354 neighborScvfIndices_.clear();
355 neighborScvs_.clear();
356 neighborScvfs_.clear();
358 hasBoundaryScvf_ =
false;
361 std::optional<Element> element_;
362 const GridGeometry* gridGeometryPtr_;
365 std::array<GridIndexType, 1> scvIndices_;
366 std::array<SubControlVolume, 1> scvs_;
368 std::vector<GridIndexType> scvfIndices_;
369 std::vector<SubControlVolumeFace> scvfs_;
371 std::vector<GridIndexType> neighborScvIndices_;
372 std::vector<SubControlVolume> neighborScvs_;
374 std::vector<GridIndexType> neighborScvfIndices_;
375 std::vector<SubControlVolumeFace> neighborScvfs_;
377 bool hasBoundaryScvf_ =
false;