diff --git a/dumux/discretization/staggered/globalfvgeometry.hh b/dumux/discretization/staggered/globalfvgeometry.hh index bcfb8d03c1629d4b6b543f8cc2702d60372d8e17..333265e638312f163b071905f21784e0d36b5daf 100644 --- a/dumux/discretization/staggered/globalfvgeometry.hh +++ b/dumux/discretization/staggered/globalfvgeometry.hh @@ -28,6 +28,7 @@ #include <dumux/common/elementmap.hh> #include <dumux/implicit/staggered/properties.hh> #include <dumux/discretization/staggered/fvelementgeometry.hh> +#include <dumux/discretization/staggered/staggeredgeometryhelper.hh> namespace Dumux { @@ -63,6 +64,8 @@ class StaggeredGlobalFVGeometry<TypeTag, true> dimWorld = GridView::dimensionworld }; + using GeometryHelper = StaggeredGeometryHelper<GridView, dim>; + public: //! Constructor StaggeredGlobalFVGeometry(const GridView& gridView) @@ -110,7 +113,6 @@ public: elementMap_.clear(); // determine size of containers - const int numElements = gridView_.size(0); IndexType numScvs = gridView_.size(0); IndexType numScvf = 0; for (const auto& element : elements(gridView_)) @@ -128,6 +130,12 @@ public: for (const auto& element : elements(gridView_)) { auto eIdx = problem.elementMapper().index(element); + + // get the element geometry +// auto elementGeometry = element.geometry(); +// GeometryHelper geometryHelper(elementGeometry); + + scvs_[eIdx] = SubControlVolume(element.geometry(), eIdx); // fill the element map with seeds @@ -138,22 +146,8 @@ public: scvfsIndexSet.reserve(element.subEntities(1)); for (const auto& intersection : intersections(gridView_, element)) { - //TODO: use proper intersection mapper! - const auto inIdx = intersection.indexInInside(); - const auto globalIsIdx = gridView_.indexSet().subIndex(element, inIdx, dim-1) + numElements; - - int oppoSiteIdx; - - if(inIdx % 2) // face index is odd - { - oppoSiteIdx = inIdx -1; - } - else - { - oppoSiteIdx = inIdx +1; - } + GeometryHelper geometryHelper(intersection, gridView_); -// std::cout << "faceSelf: " << inIdx << ", oppo: " << oppoSiteIdx << std::endl; // inner sub control volume faces if (intersection.neighbor()) { @@ -162,7 +156,7 @@ public: intersection.geometry(), scvfIdx, std::vector<IndexType>({eIdx, nIdx}), - globalIsIdx + geometryHelper ); scvfsIndexSet.push_back(scvfIdx++); } @@ -173,7 +167,7 @@ public: intersection.geometry(), scvfIdx, std::vector<IndexType>({eIdx, gridView_.size(0) + numBoundaryScvf_++}), - globalIsIdx + geometryHelper ); scvfsIndexSet.push_back(scvfIdx++); } diff --git a/dumux/discretization/staggered/staggeredgeometryhelper.hh b/dumux/discretization/staggered/staggeredgeometryhelper.hh index 6d7339bbde20ce589f657a5e78c8abad3d27a054..5a81f1368f8bc4cfbaf7236c18e223a282ad35bf 100644 --- a/dumux/discretization/staggered/staggeredgeometryhelper.hh +++ b/dumux/discretization/staggered/staggeredgeometryhelper.hh @@ -32,8 +32,67 @@ namespace Dumux { +//! Create sub control volumes and sub control volume face geometries +template<class GridView, int dim> +class StaggeredGeometryHelper; +//! A class to create sub control volume and sub control volume face geometries per element +template <class GridView> +class StaggeredGeometryHelper<GridView, 2> +{ + using Scalar = typename GridView::ctype; + static const int dim = GridView::dimension; + static const int dimWorld = GridView::dimensionworld; + + using ScvGeometry = Dune::CachedMultiLinearGeometry<Scalar, dim, dimWorld>; + using ScvfGeometry = Dune::CachedMultiLinearGeometry<Scalar, dim-1, dimWorld>; + + using GlobalPosition = typename ScvGeometry::GlobalCoordinate; + using PointVector = std::vector<GlobalPosition>; + + using Element = typename GridView::template Codim<0>::Entity; + using Intersection = typename GridView::Intersection; + + using ReferenceElements = typename Dune::ReferenceElements<Scalar, dim>; + + //! the maximum number of helper points used to construct the geometries + //! Using a statically sized point array is much faster than dynamic allocation + static constexpr int maxPoints = 9; + +public: + + StaggeredGeometryHelper(const Intersection& intersection, const GridView& gridView) + : intersection_(intersection), elementGeometry_(intersection.inside().geometry()), gridView_(gridView)//, corners_(geometry.corners()) + { + } + + int dofIdxSelf() const + { + //TODO: use proper intersection mapper! + const auto inIdx = intersection_.indexInInside(); + const int numElements = gridView_.size(0); + return gridView_.indexSet().subIndex(intersection_.inside(), inIdx, dim-1) + numElements; + } + + int dofIdxOpposite() const + { + //TODO: use proper intersection mapper! + const auto inIdx = intersection_.indexInInside(); + const int numElements = gridView_.size(0); + const int localOppositeIdx = (inIdx % 2) ? (inIdx - 1) : (inIdx + 1); + return gridView_.indexSet().subIndex(intersection_.inside(), localOppositeIdx, dim-1) + numElements; + } + +private: + const Intersection& intersection_; + const typename Element::Geometry& elementGeometry_; //! Reference to the element geometry + const GridView gridView_; +// GlobalPosition p[maxPoints]; // the points needed for construction of the geometries +// std::size_t corners_; // number of element corners + +}; + } // end namespace Dumux #endif diff --git a/dumux/discretization/staggered/subcontrolvolumeface.hh b/dumux/discretization/staggered/subcontrolvolumeface.hh index a137e17722c9ebb04dd5ce1bf593570ce23b0922..b00a83e396dca4d84a58990bba58db13e2d8ad74 100644 --- a/dumux/discretization/staggered/subcontrolvolumeface.hh +++ b/dumux/discretization/staggered/subcontrolvolumeface.hh @@ -72,12 +72,12 @@ public: StaggeredSubControlVolumeFace() = default; //! Constructor with intersection - template <class Intersection> + template <class Intersection, class GeometryHelper> StaggeredSubControlVolumeFace(const Intersection& is, const typename Intersection::Geometry& isGeometry, IndexType scvfIndex, const std::vector<IndexType>& scvIndices, - const int selfIdx + const GeometryHelper& geometryHelper ) : ParentType(), geomType_(isGeometry.type()), @@ -86,19 +86,14 @@ public: unitOuterNormal_(is.centerUnitOuterNormal()), scvfIndex_(scvfIndex), scvIndices_(scvIndices), - boundary_(is.boundary()), - selfIdx_(selfIdx) + boundary_(is.boundary()) { corners_.resize(isGeometry.corners()); for (int i = 0; i < isGeometry.corners(); ++i) corners_[i] = isGeometry.corner(i); -// subfaces_.resize(2); - -// const auto& element = is.inside(); -// const int inIdx = is.indexInInside(); -// gridView.indexSet().subIndex(element, inIdx, dimWorld-1); - + selfIdx_ = geometryHelper.dofIdxSelf(); + oppositeIdx_ = geometryHelper.dofIdxOpposite(); } /*//! The copy constrcutor diff --git a/test/discretization/staggered/test_staggered.cc b/test/discretization/staggered/test_staggered.cc index 1c3a0f9217926162121325e84f2d01c54d5d7b51..2a798b6412ae151daaa1179fbc8942a555721a2c 100644 --- a/test/discretization/staggered/test_staggered.cc +++ b/test/discretization/staggered/test_staggered.cc @@ -133,7 +133,7 @@ int main (int argc, char *argv[]) try for (auto&& scvf : scvfs(fvGeometry)) { - std::cout << "-- scvf " << scvf.index() << " ip at: " << scvf.ipGlobal(); + std::cout << "-- scvf " << scvf.index() << " ip at: " << scvf.ipGlobal() << ", doIdx (self): " << scvf.dofIndexSelf() << ", doIdx (opposite): " << scvf.dofIndexOpposite(); if (scvf.boundary()) std::cout << " (on boundary)."; std::cout << std::endl; }