diff --git a/dumux/assembly/staggeredlocalassembler.hh b/dumux/assembly/staggeredlocalassembler.hh index 488ff6d96804494b8cfb1c7c1177fb2a1c80027b..f363cf2c041fa490d6860165b0bd4434d01cdc81 100644 --- a/dumux/assembly/staggeredlocalassembler.hh +++ b/dumux/assembly/staggeredlocalassembler.hh @@ -116,14 +116,16 @@ public: elemFluxVarsCache.bind(element, fvGeometry, curElemVolVars); auto curElemeFaceVars = localView(gridVariables.curGridFaceVars()); - auto prevElemeFaceVars = localView(gridVariables.prevGridFaceVars()); curElemeFaceVars.bind(element, fvGeometry, curSol); - prevElemeFaceVars.bind(element, fvGeometry, curSol); //TODO: stationary const bool isStationary = localResidual.isStationary(); auto prevElemVolVars = localView(gridVariables.prevGridVolVars()); + auto prevElemeFaceVars = localView(gridVariables.prevGridFaceVars()); if (!isStationary) + { prevElemVolVars.bindElement(element, fvGeometry, localResidual.prevSol()); + prevElemeFaceVars.bindElement(element, fvGeometry, localResidual.prevSol()); + } // for compatibility with box models ElementBoundaryTypes elemBcTypes; @@ -608,12 +610,12 @@ private: { return gridVolVars.volVars(scv); } template<class T = TypeTag> - static typename std::enable_if<!GET_PROP_VALUE(T, EnableGlobalVolumeVariablesCache), FaceVariables&>::type //TODO: introduce correct property + static typename std::enable_if<!GET_PROP_VALUE(T, EnableGlobalFaceVariablesCache), FaceVariables&>::type getFaceVarAccess(GlobalFaceVars& gridFaceVars, ElementFaceVariables& elemFaceVars, const SubControlVolumeFace& scvf) { return elemFaceVars[scvf]; } template<class T = TypeTag> - static typename std::enable_if<GET_PROP_VALUE(T, EnableGlobalVolumeVariablesCache), FaceVariables&>::type + static typename std::enable_if<GET_PROP_VALUE(T, EnableGlobalFaceVariablesCache), FaceVariables&>::type getFaceVarAccess(GlobalFaceVars& gridFaceVars, ElementFaceVariables& elemFaceVars, const SubControlVolumeFace& scvf) { return gridFaceVars.faceVars(scvf.index()); } }; diff --git a/dumux/discretization/staggered/elementfacevariables.hh b/dumux/discretization/staggered/elementfacevariables.hh index 6bc70023581c76dfc20d4166b78e1b051502a00f..b9ab9e87f191d906fdb7a6a6063c4d335c54a1c9 100644 --- a/dumux/discretization/staggered/elementfacevariables.hh +++ b/dumux/discretization/staggered/elementfacevariables.hh @@ -62,13 +62,20 @@ public: { return globalFaceVars().faceVars(scvfIdx); } - //! For compatibility reasons with the case of not storing the vol vars. + //! For compatibility reasons with the case of not storing the face vars. //! function to be called before assembling an element, preparing the vol vars within the stencil void bind(const Element& element, const FVElementGeometry& fvGeometry, const SolutionVector& sol) {} + // Binding of an element, prepares only the face variables of the element + // specialization for Staggered models + void bindElement(const Element& element, + const FVElementGeometry& fvGeometry, + const SolutionVector& sol) + {} + //! The global volume variables object we are a restriction of const GlobalFaceVars& globalFaceVars() const @@ -96,6 +103,23 @@ class StaggeredElementFaceVariables<TypeTag, /*enableGlobalFaceVarsCache*/false> typename DofTypeIndices::FaceIdx faceIdx; public: + + StaggeredElementFaceVariables(const GlobalFaceVars& globalFacesVars) : globalFaceVarsPtr_(&globalFacesVars) {} + + const FaceVariables& operator [](const SubControlVolumeFace& scvf) const + { return faceVariables_[scvf.localFaceIdx()]; } + + // operator for the access with an index + const FaceVariables& operator [](const IndexType scvfIdx) const + { return faceVariables_[getLocalIdx_(scvfIdx)]; } + + FaceVariables& operator [](const SubControlVolumeFace& scvf) + { return faceVariables_[scvf.localFaceIdx()]; } + + // operator for the access with an index + FaceVariables& operator [](const IndexType scvfIdx) + { return faceVariables_[getLocalIdx_(scvfIdx)]; } + //! For compatibility reasons with the case of not storing the vol vars. //! function to be called before assembling an element, preparing the vol vars within the stencil void bind(const Element& element, @@ -103,15 +127,45 @@ public: const SolutionVector& sol) { faceVariables_.resize(fvGeometry.numScvf()); + faceVarIndices_.resize(fvGeometry.numScvf()); for(auto&& scvf : scvfs(fvGeometry)) { - // TODO: do proper update - // faceVariables_[scvf.localFaceIdx()].update(sol[faceIdx], problem_(), element, fvGeometry, scvf) + faceVariables_[scvf.localFaceIdx()].update(sol[faceIdx], globalFaceVars().problem(), element, fvGeometry, scvf); + faceVarIndices_[scvf.localFaceIdx()] = scvf.index(); + } + } + // Binding of an element, prepares only the face variables of the element + // specialization for Staggered models + void bindElement(const Element& element, + const FVElementGeometry& fvGeometry, + const SolutionVector& sol) + { + faceVariables_.resize(fvGeometry.numScvf()); + faceVarIndices_.resize(fvGeometry.numScvf()); + + for(auto&& scvf : scvfs(fvGeometry)) + { + faceVariables_[scvf.localFaceIdx()].updateOwnFaceOnly(sol[faceIdx][scvf.dofIndex()]); + faceVarIndices_[scvf.localFaceIdx()] = scvf.index(); } } + + //! The global volume variables object we are a restriction of + const GlobalFaceVars& globalFaceVars() const + { return *globalFaceVarsPtr_; } + private: + + const int getLocalIdx_(const int scvfIdx) const + { + auto it = std::find(faceVarIndices_.begin(), faceVarIndices_.end(), scvfIdx); + assert(it != faceVarIndices_.end() && "Could not find the current face variables for scvfIdx!"); + return std::distance(faceVarIndices_.begin(), it); + } + + const GlobalFaceVars* globalFaceVarsPtr_; std::vector<IndexType> faceVarIndices_; std::vector<FaceVariables> faceVariables_; }; diff --git a/dumux/discretization/staggered/globalfacevariables.hh b/dumux/discretization/staggered/globalfacevariables.hh index 22985ad413ce474ffc010df5f65004ba174834b1..f368f250da120fc90bad067e4be0eea2fba402e6 100644 --- a/dumux/discretization/staggered/globalfacevariables.hh +++ b/dumux/discretization/staggered/globalfacevariables.hh @@ -34,8 +34,12 @@ namespace Properties NEW_PROP_TAG(ElementFaceVariables); } -template<class TypeTag> +template<class TypeTag, bool enableGlobalFaceVarsCache> class StaggeredGlobalFaceVariables +{}; + +template<class TypeTag> +class StaggeredGlobalFaceVariables<TypeTag, /*enableGlobalFaceVarsCache*/true> { using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using Problem = typename GET_PROP_TYPE(TypeTag, Problem); @@ -65,7 +69,7 @@ public: for(auto&& scvf : scvfs(fvGeometry)) { - faceVariables_[scvf.index()].update(faceSol, problem_(), element, fvGeometry, scvf); + faceVariables_[scvf.index()].update(faceSol, problem(), element, fvGeometry, scvf); } } } @@ -85,15 +89,55 @@ public: friend inline ElementFaceVariables localView(const StaggeredGlobalFaceVariables& global) { return ElementFaceVariables(global); } -private: - const Problem& problem_() const + const Problem& problem() const { return *problemPtr_; } +private: + const Problem* problemPtr_; std::vector<FaceVariables> faceVariables_; }; +template<class TypeTag> +class StaggeredGlobalFaceVariables<TypeTag, /*enableGlobalFaceVarsCache*/false> +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); + using FaceVariables = typename GET_PROP_TYPE(TypeTag, FaceVariables); + using ElementFaceVariables = typename GET_PROP_TYPE(TypeTag, ElementFaceVariables); + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using IndexType = typename GridView::IndexSet::IndexType; + + using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices); + typename DofTypeIndices::CellCenterIdx cellCenterIdx; + typename DofTypeIndices::FaceIdx faceIdx; + +public: + StaggeredGlobalFaceVariables(const Problem& problem) : problemPtr_(&problem) {} + + void update(const FVGridGeometry& fvGridGeometry, const SolutionVector& sol) + { } + + /*! + * \brief Return a local restriction of this global object + * The local object is only functional after calling its bind/bindElement method + * This is a free function that will be found by means of ADL + */ + friend inline ElementFaceVariables localView(const StaggeredGlobalFaceVariables& global) + { return ElementFaceVariables(global); } + + const Problem& problem() const + { return *problemPtr_; } + + +private: + + const Problem* problemPtr_; +}; + } // end namespace diff --git a/dumux/discretization/staggered/properties.hh b/dumux/discretization/staggered/properties.hh index eee1b8aaded7a2079fa3db996252d9a9b3868b07..079b85b8daa83677cff822b0ef8e07bb011298b8 100644 --- a/dumux/discretization/staggered/properties.hh +++ b/dumux/discretization/staggered/properties.hh @@ -92,7 +92,7 @@ public: typedef Dumux::CCSubControlVolume<ScvGeometry, IndexType> type; }; -SET_TYPE_PROP(StaggeredModel, GlobalFaceVars, Dumux::StaggeredGlobalFaceVariables<TypeTag>); +SET_TYPE_PROP(StaggeredModel, GlobalFaceVars, Dumux::StaggeredGlobalFaceVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGlobalFaceVariablesCache)>); //! Set the default for the ElementBoundaryTypes SET_TYPE_PROP(StaggeredModel, ElementBoundaryTypes, Dumux::CCElementBoundaryTypes<TypeTag>); diff --git a/dumux/freeflow/staggered/velocityoutput.hh b/dumux/freeflow/staggered/velocityoutput.hh index e3f7e333f38032de8cb826580454008511a2d045..75484aa8527660fbadf691acc04208b5d98c92d7 100644 --- a/dumux/freeflow/staggered/velocityoutput.hh +++ b/dumux/freeflow/staggered/velocityoutput.hh @@ -107,15 +107,16 @@ public: const Element& element, int phaseIdx) { + auto elemFaceVars = localView(gridVariables_.curGridFaceVars()); + elemFaceVars.bindElement(element, fvGeometry, sol_); for (auto&& scv : scvs(fvGeometry)) { auto dofIdxGlobal = scv.dofIndex(); for (auto&& scvf : scvfs(fvGeometry)) { - auto& origFaceVars = gridVariables_.curGridFaceVars().faceVars(scvf.index()); auto dirIdx = scvf.directionIndex(); - velocity[dofIdxGlobal][dirIdx] += 0.5*origFaceVars.velocitySelf(); + velocity[dofIdxGlobal][dirIdx] += 0.5*elemFaceVars[scvf].velocitySelf(); } } }