diff --git a/dumux/discretization/cellcentered/gridvolumevariables.hh b/dumux/discretization/cellcentered/gridvolumevariables.hh index b9b250ffd78686829fa1a33cfd07ec6a5724831d..21ad3d9edb5b61404b83ea8dbebdb64240af2861 100644 --- a/dumux/discretization/cellcentered/gridvolumevariables.hh +++ b/dumux/discretization/cellcentered/gridvolumevariables.hh @@ -80,25 +80,28 @@ public: volumeVariables_[scv.dofIndex()].update(elemSol, problem(), element, scv); } - // handle the boundary volume variables - for (auto&& scvf : scvfs(fvGeometry)) + if (fvGeometry.hasBoundaryScvf()) { - // if we are not on a boundary, skip the rest - if (!scvf.boundary()) - continue; - - // check if boundary is a pure dirichlet boundary - const auto bcTypes = problem().boundaryTypes(element, scvf); - if (bcTypes.hasOnlyDirichlet()) + // handle the boundary volume variables + for (auto&& scvf : scvfs(fvGeometry)) { - const auto insideScvIdx = scvf.insideScvIdx(); - const auto& insideScv = fvGeometry.scv(insideScvIdx); - const auto dirichletPriVars = elementSolution<typename FVGridGeometry::LocalView>(problem().dirichlet(element, scvf)); - - volumeVariables_[scvf.outsideScvIdx()].update(dirichletPriVars, - problem(), - element, - insideScv); + // if we are not on a boundary, skip the rest + if (!scvf.boundary()) + continue; + + // check if boundary is a pure dirichlet boundary + const auto bcTypes = problem().boundaryTypes(element, scvf); + if (bcTypes.hasOnlyDirichlet()) + { + const auto insideScvIdx = scvf.insideScvIdx(); + const auto& insideScv = fvGeometry.scv(insideScvIdx); + const auto dirichletPriVars = elementSolution<typename FVGridGeometry::LocalView>(problem().dirichlet(element, scvf)); + + volumeVariables_[scvf.outsideScvIdx()].update(dirichletPriVars, + problem(), + element, + insideScv); + } } } } diff --git a/dumux/discretization/cellcentered/tpfa/elementvolumevariables.hh b/dumux/discretization/cellcentered/tpfa/elementvolumevariables.hh index 9612e6c1ea50e0020e9f6b669b233a7e9d0d72ea..15f70efdbe7c0446035c3cf71e6a6456e0925f6e 100644 --- a/dumux/discretization/cellcentered/tpfa/elementvolumevariables.hh +++ b/dumux/discretization/cellcentered/tpfa/elementvolumevariables.hh @@ -152,28 +152,31 @@ public: ++localIdx; } - // Update boundary volume variables - for (auto&& scvf : scvfs(fvGeometry)) + if (fvGeometry.hasBoundaryScvf()) { - // if we are not on a boundary, skip to the next scvf - if (!scvf.boundary()) + // Update boundary volume variables + for (auto&& scvf : scvfs(fvGeometry)) + { + // if we are not on a boundary, skip to the next scvf + if (!scvf.boundary()) continue; - // check if boundary is a pure dirichlet boundary - const auto bcTypes = problem.boundaryTypes(element, scvf); - if (bcTypes.hasOnlyDirichlet()) - { - const auto dirichletPriVars = elementSolution<FVElementGeometry>(problem.dirichlet(element, scvf)); - - volumeVariables_.resize(localIdx+1); - volVarIndices_.resize(localIdx+1); - volumeVariables_[localIdx].update(dirichletPriVars, - problem, - element, - scvI); - volVarIndices_[localIdx] = scvf.outsideScvIdx(); - ++localIdx; - } + // check if boundary is a pure dirichlet boundary + const auto bcTypes = problem.boundaryTypes(element, scvf); + if (bcTypes.hasOnlyDirichlet()) + { + const auto dirichletPriVars = elementSolution<FVElementGeometry>(problem.dirichlet(element, scvf)); + + volumeVariables_.resize(localIdx+1); + volVarIndices_.resize(localIdx+1); + volumeVariables_[localIdx].update(dirichletPriVars, + problem, + element, + scvI); + volVarIndices_[localIdx] = scvf.outsideScvIdx(); + ++localIdx; + } + } } //! Check if user added additional DOF dependencies, i.e. the residual of DOF globalI depends diff --git a/dumux/discretization/cellcentered/tpfa/fvelementgeometry.hh b/dumux/discretization/cellcentered/tpfa/fvelementgeometry.hh index c1e4b4388b1de6558445f1bf0c03ac832179b029..3ccaf0ef026651cf5dd796658dd1d49838ab4bad 100644 --- a/dumux/discretization/cellcentered/tpfa/fvelementgeometry.hh +++ b/dumux/discretization/cellcentered/tpfa/fvelementgeometry.hh @@ -156,6 +156,10 @@ public: const FVGridGeometry& fvGridGeometry() const { return *fvGridGeometryPtr_; } + //! Returns whether one of the geometry's scvfs lies on a boundary + bool hasBoundaryScvf() const + { return fvGridGeometry().hasBoundaryScvf(scvIndices_[0]); } + private: const Element* elementPtr_; @@ -351,6 +355,10 @@ public: const FVGridGeometry& fvGridGeometry() const { return *fvGridGeometryPtr_; } + //! Returns whether one of the geometry's scvfs lies on a boundary + bool hasBoundaryScvf() const + { return hasBoundaryScvf_; } + private: IndexType findFlippedScvfIndex_(IndexType insideScvIdx, IndexType globalOutsideScvIdx) @@ -412,11 +420,15 @@ private: scvIndices.resize(scvfNeighborVolVarIndices.size() + 1); scvIndices[0] = eIdx; std::copy(scvfNeighborVolVarIndices.begin(), scvfNeighborVolVarIndices.end(), scvIndices.begin()+1); + + const bool onBoundary = intersection.boundary() && !intersection.neighbor(); + hasBoundaryScvf_ = (hasBoundaryScvf_ || onBoundary); + scvfs_.emplace_back(intersection, intersection.geometry(), scvFaceIndices[scvfCounter], scvIndices, - intersection.boundary() && !intersection.neighbor()); + onBoundary); scvfIndices_.emplace_back(scvFaceIndices[scvfCounter]); scvfCounter++; @@ -536,6 +548,8 @@ private: neighborScvs_.clear(); neighborScvfs_.clear(); flippedNeighborScvfIndices_.clear(); + + hasBoundaryScvf_ = false; } const Element* elementPtr_; //!< the element to which this fvgeometry is bound @@ -555,6 +569,8 @@ private: std::vector<IndexType> neighborScvfIndices_; std::vector<SubControlVolumeFace> neighborScvfs_; std::vector<std::vector<IndexType>> flippedNeighborScvfIndices_; + + bool hasBoundaryScvf_ = false; }; } // end namespace Dumux diff --git a/dumux/discretization/cellcentered/tpfa/fvgridgeometry.hh b/dumux/discretization/cellcentered/tpfa/fvgridgeometry.hh index be19deafec40f9c5f412c2b2c0021a12dfec0e4f..9d59a04246533e3b67f09611aa6e304795290d69 100644 --- a/dumux/discretization/cellcentered/tpfa/fvgridgeometry.hh +++ b/dumux/discretization/cellcentered/tpfa/fvgridgeometry.hh @@ -172,6 +172,7 @@ public: scvs_.resize(numScvs); scvfs_.reserve(numScvf); scvfIndicesOfScv_.resize(numScvs); + hasBoundaryScvf_.resize(numScvs, false); // Build the scvs and scv faces IndexType scvfIdx = 0; @@ -254,6 +255,8 @@ public: ScvfGridIndexStorage({eIdx, this->gridView().size(0) + numBoundaryScvf_++}), true); scvfsIndexSet.push_back(scvfIdx++); + + hasBoundaryScvf_[eIdx] = true; } } @@ -314,6 +317,10 @@ public: const ConnectivityMap &connectivityMap() const { return connectivityMap_; } + //! Returns whether one of the geometry's scvfs lies on a boundary + bool hasBoundaryScvf(IndexType eIdx) const + { return hasBoundaryScvf_[eIdx]; } + private: // find the scvf that has insideScvIdx in its outsideScvIdx list and outsideScvIdx as its insideScvIdx IndexType findFlippedScvfIndex_(IndexType insideScvIdx, IndexType outsideScvIdx) @@ -338,6 +345,7 @@ private: std::vector<SubControlVolumeFace> scvfs_; std::vector<std::vector<IndexType>> scvfIndicesOfScv_; IndexType numBoundaryScvf_; + std::vector<bool> hasBoundaryScvf_; //! needed for embedded surface and network grids (dim < dimWorld) std::vector<std::vector<IndexType>> flipScvfIndices_;