14#ifndef DUMUX_DISCRETIZATION_CCTPFA_FV_GRID_GEOMETRY_HH
15#define DUMUX_DISCRETIZATION_CCTPFA_FV_GRID_GEOMETRY_HH
42template<
class Gr
idView,
class MapperTraits = DefaultMapperTraits<Gr
idView>>
49 template<
class Gr
idGeometry>
52 template<
class Gr
idGeometry,
bool enableCache>
59 static constexpr int maxNumScvfNeighbors = int(GridView::dimension)<int(GridView::dimensionworld) ? 8 : 1<<(GridView::dimension-1);
68template<
class GridView,
69 bool enableGridGeometryCache =
false,
79template<
class GV,
class Traits>
85 using ConnectivityMap =
typename Traits::template ConnectivityMap<ThisType>;
87 using Element =
typename GV::template Codim<0>::Entity;
89 static const int dim = GV::dimension;
90 static const int dimWorld = GV::dimensionworld;
96 using LocalView =
typename Traits::template LocalView<ThisType, true>;
98 using SubControlVolume =
typename Traits::SubControlVolume;
100 using SubControlVolumeFace =
typename Traits::SubControlVolumeFace;
104 using DofMapper =
typename Traits::ElementMapper;
110 static constexpr DiscretizationMethod discMethod{};
113 static constexpr int maxElementStencilSize = LocalView::maxNumElementScvfs*Traits::maxNumScvfNeighbors + 1;
120 : ParentType(std::move(gg))
121 , periodicGridTraits_(this->gridView().grid())
125 DUNE_THROW(Dune::InvalidStateException,
"The cctpfa discretization method needs at least an overlap of 1 for parallel computations. "
126 <<
" Set the parameter \"Grid.Overlap\" in the input file.");
132 CCTpfaFVGridGeometry(
const GridView& gridView)
133 : CCTpfaFVGridGeometry(std::make_shared<BasicGridGeometry>(gridView))
138 const DofMapper& dofMapper()
const
139 {
return this->elementMapper(); }
142 std::size_t numScv()
const
148 std::size_t numScvf()
const
150 return scvfs_.size();
154 std::size_t numBoundaryScvf()
const
156 return numBoundaryScvf_;
160 std::size_t numDofs()
const
161 {
return this->gridView().size(0); }
165 void update(
const GridView& gridView)
167 ParentType::update(gridView);
172 void update(GridView&& gridView)
174 ParentType::update(std::move(gridView));
179 const SubControlVolume& scv(GridIndexType scvIdx)
const
181 return scvs_[scvIdx];
185 const SubControlVolumeFace& scvf(GridIndexType scvfIdx)
const
187 return scvfs_[scvfIdx];
192 const SubControlVolumeFace& flipScvf(GridIndexType scvfIdx,
unsigned int outsideScvfIdx = 0)
const
194 return scvfs_[flipScvfIndices_[scvfIdx][outsideScvfIdx]];
198 const std::vector<GridIndexType>& scvfIndicesOfScv(GridIndexType scvIdx)
const
200 return scvfIndicesOfScv_[scvIdx];
207 const ConnectivityMap &connectivityMap()
const
208 {
return connectivityMap_; }
211 bool hasBoundaryScvf(GridIndexType eIdx)
const
212 {
return hasBoundaryScvf_[eIdx]; }
221 scvfIndicesOfScv_.clear();
222 flipScvfIndices_.clear();
225 std::size_t numScvs = numDofs();
226 std::size_t numScvf = 0;
227 for (
const auto& element : elements(this->gridView()))
228 numScvf +=
element.subEntities(1);
231 scvs_.resize(numScvs);
232 scvfs_.reserve(numScvf);
233 scvfIndicesOfScv_.resize(numScvs);
234 hasBoundaryScvf_.assign(numScvs,
false);
237 GridIndexType scvfIdx = 0;
238 numBoundaryScvf_ = 0;
239 for (
const auto& element : elements(this->gridView()))
241 const auto eIdx = this->elementMapper().index(element);
242 scvs_[eIdx] = SubControlVolume(
element.geometry(), eIdx);
245 std::vector<GridIndexType> scvfsIndexSet;
246 scvfsIndexSet.reserve(
element.subEntities(1));
250 using ScvfGridIndexStorage =
typename SubControlVolumeFace::Traits::GridIndexStorage;
251 std::vector<ScvfGridIndexStorage> outsideIndices;
255 outsideIndices.resize(
element.subEntities(1));
256 std::for_each(outsideIndices.begin(), outsideIndices.end(), [eIdx] (
auto& nIndices) { nIndices.push_back(eIdx); });
259 for (
const auto& intersection : intersections(this->gridView(), element))
261 if (intersection.neighbor())
263 const auto nIdx = this->elementMapper().index( intersection.outside() );
264 outsideIndices[intersection.indexInInside()].push_back(nIdx);
269 for (
const auto& intersection : intersections(this->gridView(), element))
272 if (intersection.neighbor())
275 if (periodicGridTraits_.isPeriodic(intersection))
280 const auto nIdx = this->elementMapper().index(intersection.outside());
281 scvfs_.emplace_back(intersection,
282 intersection.geometry(),
284 ScvfGridIndexStorage({eIdx, nIdx}),
286 scvfsIndexSet.push_back(scvfIdx++);
292 auto indexInInside = intersection.indexInInside();
294 if (outsideIndices[indexInInside].empty())
298 scvfs_.emplace_back(intersection,
299 intersection.geometry(),
301 outsideIndices[indexInInside],
303 scvfsIndexSet.push_back(scvfIdx++);
304 outsideIndices[indexInInside].clear();
309 else if (intersection.boundary())
311 scvfs_.emplace_back(intersection,
312 intersection.geometry(),
314 ScvfGridIndexStorage({eIdx,
static_cast<GridIndexType
>(this->gridView().size(0) + numBoundaryScvf_++)}),
316 scvfsIndexSet.push_back(scvfIdx++);
318 hasBoundaryScvf_[eIdx] =
true;
323 scvfIndicesOfScv_[eIdx] = scvfsIndexSet;
327 if (dim < dimWorld || this->isPeriodic())
329 flipScvfIndices_.resize(scvfs_.size());
330 for (
auto&& scvf : scvfs_)
335 flipScvfIndices_[scvf.index()].resize(scvf.numOutsideScvs());
336 const auto insideScvIdx = scvf.insideScvIdx();
338 for (
unsigned int i = 0; i < scvf.numOutsideScvs(); ++i)
339 flipScvfIndices_[scvf.index()][i] = findFlippedScvfIndex_(insideScvIdx, scvf.outsideScvIdx(i));
344 connectivityMap_.update(*
this);
348 GridIndexType findFlippedScvfIndex_(GridIndexType insideScvIdx, GridIndexType outsideScvIdx)
351 for (
auto outsideScvfIndex : scvfIndicesOfScv_[outsideScvIdx])
353 const auto& outsideScvf = this->scvf(outsideScvfIndex);
354 for (
unsigned int j = 0; j < outsideScvf.numOutsideScvs(); ++j)
355 if (outsideScvf.outsideScvIdx(j) == insideScvIdx)
356 return outsideScvf.index();
359 DUNE_THROW(Dune::InvalidStateException,
"No flipped version of this scvf found!");
363 ConnectivityMap connectivityMap_;
366 std::vector<SubControlVolume> scvs_;
367 std::vector<SubControlVolumeFace> scvfs_;
368 std::vector<std::vector<GridIndexType>> scvfIndicesOfScv_;
369 std::size_t numBoundaryScvf_;
370 std::vector<bool> hasBoundaryScvf_;
373 std::vector<std::vector<GridIndexType>> flipScvfIndices_;
375 PeriodicGridTraits<typename GridView::Grid> periodicGridTraits_;
385template<
class GV,
class Traits>
389 using ThisType = CCTpfaFVGridGeometry<GV, false, Traits>;
390 using ParentType = BaseGridGeometry<GV, Traits>;
391 using ConnectivityMap =
typename Traits::template ConnectivityMap<ThisType>;
394 using Element =
typename GV::template Codim<0>::Entity;
396 static const int dim = GV::dimension;
397 static const int dimWorld = GV::dimensionworld;
399 using ScvfGridIndexStorage =
typename Traits::SubControlVolumeFace::Traits::GridIndexStorage;
400 using NeighborVolVarIndices =
typename std::conditional_t< (dim<dimWorld),
401 ScvfGridIndexStorage,
402 Dune::ReservedVector<GridIndexType, 1> >;
408 using LocalView =
typename Traits::template LocalView<ThisType, false>;
410 using SubControlVolume =
typename Traits::SubControlVolume;
412 using SubControlVolumeFace =
typename Traits::SubControlVolumeFace;
416 using DofMapper =
typename Traits::ElementMapper;
418 using SupportsPeriodicity =
typename PeriodicGridTraits<typename GV::Grid>::SupportsPeriodicity;
421 using DiscretizationMethod = DiscretizationMethods::CCTpfa;
422 static constexpr DiscretizationMethod discMethod{};
425 static constexpr int maxElementStencilSize = LocalView::maxNumElementScvfs*Traits::maxNumScvfNeighbors + 1;
431 CCTpfaFVGridGeometry(std::shared_ptr<BasicGridGeometry> gg)
432 : ParentType(std::move(gg))
433 , periodicGridTraits_(this->gridView().grid())
437 DUNE_THROW(Dune::InvalidStateException,
"The cctpfa discretization method needs at least an overlap of 1 for parallel computations. "
438 <<
" Set the parameter \"Grid.Overlap\" in the input file.");
444 CCTpfaFVGridGeometry(
const GridView& gridView)
445 : CCTpfaFVGridGeometry(std::make_shared<BasicGridGeometry>(gridView))
450 const DofMapper& dofMapper()
const
451 {
return this->elementMapper(); }
454 std::size_t numScv()
const
460 std::size_t numScvf()
const
466 std::size_t numBoundaryScvf()
const
468 return numBoundaryScvf_;
472 std::size_t numDofs()
const
473 {
return this->gridView().size(0); }
476 void update(
const GridView& gridView)
478 ParentType::update(gridView);
483 void update(GridView&& gridView)
485 ParentType::update(std::move(gridView));
489 const std::vector<GridIndexType>& scvfIndicesOfScv(GridIndexType scvIdx)
const
490 {
return scvfIndicesOfScv_[scvIdx]; }
493 const std::vector<NeighborVolVarIndices>& neighborVolVarIndices(GridIndexType scvIdx)
const
494 {
return neighborVolVarIndices_[scvIdx]; }
500 const ConnectivityMap &connectivityMap()
const
501 {
return connectivityMap_; }
508 scvfIndicesOfScv_.clear();
509 neighborVolVarIndices_.clear();
512 numScvs_ = numDofs();
514 numBoundaryScvf_ = 0;
515 scvfIndicesOfScv_.resize(numScvs_);
516 neighborVolVarIndices_.resize(numScvs_);
519 for (
const auto& element : elements(this->gridView()))
521 const auto eIdx = this->elementMapper().index(element);
524 auto numLocalFaces =
element.subEntities(1);
525 std::vector<GridIndexType> scvfsIndexSet;
526 std::vector<NeighborVolVarIndices> neighborVolVarIndexSet;
527 scvfsIndexSet.reserve(numLocalFaces);
528 neighborVolVarIndexSet.reserve(numLocalFaces);
532 std::vector<NeighborVolVarIndices> outsideIndices;
535 outsideIndices.resize(numLocalFaces);
536 for (
const auto& intersection : intersections(this->gridView(), element))
538 if (intersection.neighbor())
540 const auto nIdx = this->elementMapper().index(intersection.outside());
541 outsideIndices[intersection.indexInInside()].push_back(nIdx);
546 for (
const auto& intersection : intersections(this->gridView(), element))
549 if (intersection.neighbor())
552 if (periodicGridTraits_.isPeriodic(intersection))
557 scvfsIndexSet.push_back(numScvf_++);
558 const auto nIdx = this->elementMapper().index(intersection.outside());
559 neighborVolVarIndexSet.emplace_back(NeighborVolVarIndices({nIdx}));
565 auto indexInInside = intersection.indexInInside();
567 if (outsideIndices[indexInInside].empty())
571 scvfsIndexSet.push_back(numScvf_++);
572 neighborVolVarIndexSet.emplace_back(std::move(outsideIndices[indexInInside]));
573 outsideIndices[indexInInside].clear();
578 else if (intersection.boundary())
580 scvfsIndexSet.push_back(numScvf_++);
581 neighborVolVarIndexSet.emplace_back(NeighborVolVarIndices({
static_cast<GridIndexType
>(numScvs_ + numBoundaryScvf_++)}));
586 scvfIndicesOfScv_[eIdx] = scvfsIndexSet;
587 neighborVolVarIndices_[eIdx] = neighborVolVarIndexSet;
591 connectivityMap_.update(*
this);
595 std::size_t numScvs_;
596 std::size_t numScvf_;
597 std::size_t numBoundaryScvf_;
600 ConnectivityMap connectivityMap_;
603 std::vector<std::vector<GridIndexType>> scvfIndicesOfScv_;
604 std::vector<std::vector<NeighborVolVarIndices>> neighborVolVarIndices_;
606 PeriodicGridTraits<typename GridView::Grid> periodicGridTraits_;
Base class for grid geometries.
Stores the face indices corresponding to the neighbors of an element that contribute to the derivativ...
Check the overlap size for different discretization methods.
Base class for all grid geometries.
Definition basegridgeometry.hh:52
An implementation of a grid geometry with some basic features.
Definition basicgridgeometry.hh:37
A simple version of the connectivity map for cellcentered schemes. This implementation works for sche...
Definition cellcentered/connectivitymap.hh:41
Sub control volumes for cell-centered discretization schemes.
Definition discretization/cellcentered/subcontrolvolume.hh:47
Stencil-local finite volume geometry (scvs and scvfs) for cell-centered TPFA models This builds up th...
Definition discretization/cellcentered/tpfa/fvelementgeometry.hh:53
The finite volume geometry (scvs and scvfs) for cell-centered TPFA models on a grid view This builds ...
Definition discretization/cellcentered/tpfa/fvgridgeometry.hh:71
The sub control volume face.
Definition discretization/cellcentered/tpfa/subcontrolvolumeface.hh:78
Traits extracting the public Extrusion type from T Defaults to NoExtrusion if no such type is found.
Definition extrusion.hh:155
Definition periodicgridtraits.hh:121
Defines the default element and vertex mapper types.
Sub control volumes for cell-centered discretization schemes.
Stencil-local finite volume geometry (scvs and scvfs) for cell-centered TPFA models This builds up th...
The sub control volume face.
Helper classes to compute the integration elements.
Dune::Std::detected_or_t< Dumux::BasicGridGeometry< GV, typename T::ElementMapper, typename T::VertexMapper >, Detail::SpecifiesBaseGridGeometry, T > BasicGridGeometry_t
Type of the basic grid geometry implementation used as backend.
Definition basegridgeometry.hh:38
The available discretization methods in Dumux.
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:166
Grid properties related to periodicity.
The default traits for the tpfa finite volume grid geometry Defines the scv and scvf types and the ma...
Definition discretization/cellcentered/tpfa/fvgridgeometry.hh:45
CCTpfaFVElementGeometry< GridGeometry, enableCache > LocalView
Definition discretization/cellcentered/tpfa/fvgridgeometry.hh:53
CCTpfaSubControlVolumeFace< GridView > SubControlVolumeFace
Definition discretization/cellcentered/tpfa/fvgridgeometry.hh:47
CCSimpleConnectivityMap< GridGeometry > ConnectivityMap
Definition discretization/cellcentered/tpfa/fvgridgeometry.hh:50
CCSubControlVolume< GridView > SubControlVolume
Definition discretization/cellcentered/tpfa/fvgridgeometry.hh:46
static constexpr int maxNumScvfNeighbors
Definition discretization/cellcentered/tpfa/fvgridgeometry.hh:59
static bool isValid(const GridView &gridView) noexcept
Definition checkoverlapsize.hh:30
typename GridView::IndexSet::IndexType GridIndex
Definition indextraits.hh:27
Definition periodicgridtraits.hh:34