diff --git a/dumux/discretization/staggered/darcyslaw.hh b/dumux/discretization/staggered/darcyslaw.hh index a9d6fdf3aa580549544f00a86531dc22b56a9c9f..39ff0eb016e7411511851b8f06be611095a46f31 100644 --- a/dumux/discretization/staggered/darcyslaw.hh +++ b/dumux/discretization/staggered/darcyslaw.hh @@ -121,40 +121,11 @@ public: // hOutside -= rho*(gOutside*xOutside); // } // } -// -// const GlobalPosition vector = {1,0}; -// const Scalar angle = std::acos(scvFace.unitOuterNormal() * vector / scvFace.unitOuterNormal().two_norm() / vector.two_norm())*180.0/M_PI; -// const Scalar threshold = 1e-6; -// -// if(std::abs(angle) < threshold) + return 1.0; -// // else if(std::abs(angle-180) < threshold) -// // return -1.0; -// else -// return 0; -// -// // if(std::abs(angle) < threshold || std::abs(angle-180) < threshold) -// // return tij*(hInside - hOutside); -// // std::cout << "normal " << scvFace.unitOuterNormal() << std::endl; -// - } -// static Stencil pressureStencil(const Problem& problem, -// const Element& element, -// const FVElementGeometry& fvGeometry, -// const SubControlVolumeFace& scvFace) -// { -// Stencil pressureStencil; -// if (!scvFace.boundary()) -// { -// pressureStencil.push_back(scvFace.insideScvIdx()); -// pressureStencil.push_back(scvFace.outsideScvIdx()); -// } -// else -// pressureStencil.push_back(scvFace.insideScvIdx()); // -// return pressureStencil; -// } + } // The flux variables cache has to be bound to an element prior to flux calculations // During the binding, the transmissibilities will be computed and stored using the method below. @@ -164,75 +135,10 @@ public: const ElementVolumeVariables& elemVolVars, const SubControlVolumeFace& scvFace) { - Scalar tij; - - const auto insideScvIdx = scvFace.insideScvIdx(); - const auto& insideScv = fvGeometry.scv(insideScvIdx); - const auto& insideVolVars = elemVolVars[insideScvIdx]; - const auto insideK = problem.spatialParams().intrinsicPermeability(insideScv, insideVolVars); - Scalar ti = calculateOmega_(problem, scvFace, insideK, element, insideScv); - - if (!scvFace.boundary()) - { - const auto outsideScvIdx = scvFace.outsideScvIdx(); - // as we assemble fluxes from the neighbor to our element the outside index - // refers to the scv of our element, so we use the scv method - const auto& outsideScv = fvGeometry.scv(outsideScvIdx); - const auto outsideElement = fvGeometry.globalFvGeometry().element(outsideScvIdx); - const auto& outsideVolVars = elemVolVars[outsideScvIdx]; - const auto outsideK = problem.spatialParams().intrinsicPermeability(outsideScv, outsideVolVars); - Scalar tj = -1.0*calculateOmega_(problem, scvFace, outsideK, outsideElement, outsideScv); - - // check for division by zero! - if (ti*tj <= 0.0) - tij = 0; - else - tij = scvFace.area()*(ti * tj)/(ti + tj); - } - else - { - tij = scvFace.area()*ti; - } - - return tij; + return 0; } -private: - static Scalar calculateOmega_(const Problem& problem, - const SubControlVolumeFace& scvFace, - const DimWorldMatrix &K, - const Element& element, - const SubControlVolume &scv) - { - GlobalPosition Knormal; - K.mv(scvFace.unitOuterNormal(), Knormal); - - auto distanceVector = scvFace.center(); - distanceVector -= scv.center(); - distanceVector /= distanceVector.two_norm2(); - - Scalar omega = Knormal * distanceVector; - omega *= problem.boxExtrusionFactor(element, scv); - - return omega; - } - - static Scalar calculateOmega_(const Problem& problem, - const SubControlVolumeFace& scvFace, - const Scalar K, - const Element& element, - const SubControlVolume &scv) - { - auto distanceVector = scvFace.center(); - distanceVector -= scv.center(); - distanceVector /= distanceVector.two_norm2(); - - Scalar omega = K * (distanceVector * scvFace.unitOuterNormal()); - omega *= problem.boxExtrusionFactor(element, scv); - - return omega; - } }; } // end namespace diff --git a/dumux/discretization/staggered/elementfluxvariablescache.hh b/dumux/discretization/staggered/elementfluxvariablescache.hh new file mode 100644 index 0000000000000000000000000000000000000000..df74368908e4014e2806258feaab16672cb03cd1 --- /dev/null +++ b/dumux/discretization/staggered/elementfluxvariablescache.hh @@ -0,0 +1,214 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * \brief The global object of flux var caches + */ +#ifndef DUMUX_DISCRETIZATION_STAGGERED_ELEMENT_FLUXVARSCACHE_HH +#define DUMUX_DISCRETIZATION_STAGGERED_ELEMENT_FLUXVARSCACHE_HH + +#include <dumux/implicit/properties.hh> + +namespace Dumux +{ + +/*! + * \ingroup ImplicitModel + * \brief Base class for the stencil local flux variables cache + */ +template<class TypeTag, bool EnableGlobalFluxVariablesCache> +class StaggeredElementFluxVariablesCache; + +/*! + * \ingroup ImplicitModel + * \brief Spezialization when caching globally + */ +template<class TypeTag> +class StaggeredElementFluxVariablesCache<TypeTag, true> +{ + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using IndexType = typename GridView::IndexSet::IndexType; + using Element = typename GridView::template Codim<0>::Entity; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); + using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache); + using GlobalFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GlobalFluxVariablesCache); + using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace); + +public: + StaggeredElementFluxVariablesCache(const GlobalFluxVariablesCache& global) + : globalFluxVarsCachePtr_(&global) {} + + // Specialization for the global caching being enabled - do nothing here + void bindElement(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars) {} + + // Specialization for the global caching being enabled - do nothing here + void bind(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars) {} + + // Specialization for the global caching being enabled - do nothing here + void bindScvf(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf) {} + + // aStaggeredess operators in the case of caching + const FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) const + { return (*globalFluxVarsCachePtr_)[scvf.index()]; } + + //! The global object we are a restriction of + const GlobalFluxVariablesCache& globalFluxVarsCache() const + { return *globalFluxVarsCachePtr_; } + +private: + const GlobalFluxVariablesCache* globalFluxVarsCachePtr_; +}; + +/*! + * \ingroup ImplicitModel + * \brief Spezialization when not using global caching + */ +template<class TypeTag> +class StaggeredElementFluxVariablesCache<TypeTag, false> +{ + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using IndexType = typename GridView::IndexSet::IndexType; + using Element = typename GridView::template Codim<0>::Entity; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); + using FluxVariablesCache = typename GET_PROP_TYPE(TypeTag, FluxVariablesCache); + using GlobalFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, GlobalFluxVariablesCache); + using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace); + +public: + StaggeredElementFluxVariablesCache(const GlobalFluxVariablesCache& global) + : globalFluxVarsCachePtr_(&global) {} + + // This function has to be called prior to flux calculations on the element. + // Prepares the transmissibilities of the scv faces in an element. The FvGeometry is assumed to be bound. + void bindElement(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars) + { + // resizing of the cache + const auto numScvf = fvGeometry.numScvf(); + fluxVarsCache_.resize(numScvf); + globalScvfIndices_.resize(numScvf); + IndexType localScvfIdx = 0; + + // fill the containers + for (auto&& scvf : scvfs(fvGeometry)) + { + fluxVarsCache_[localScvfIdx].update(globalFluxVarsCache().problem_(), element, fvGeometry, elemVolVars, scvf); + globalScvfIndices_[localScvfIdx] = scvf.index(); + localScvfIdx++; + } + } + + // This function is called by the StaggeredLocalResidual before flux calculations during assembly. + // Prepares the transmissibilities of the scv faces in the stencil. The FvGeometries are assumed to be bound. + void bind(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars) + { + const auto globalI = globalFluxVarsCache().problem_().elementMapper().index(element); + const auto& neighborStencil = globalFluxVarsCache().problem_().model().stencils(element).neighborStencil(); + const auto numNeighbors = neighborStencil.size(); + + // find the number of scv faces that need to be prepared + auto numScvf = fvGeometry.numScvf(); + for (IndexType localIdxJ = 0; localIdxJ < numNeighbors; ++localIdxJ) + { + const auto& fluxVarIndicesJ = globalFluxVarsCache().problem_().model().localJacobian().assemblyMap()[globalI][localIdxJ]; + numScvf += fluxVarIndicesJ.size(); + } + + // fill the containers with the data on the scv faces inside the actual element + fluxVarsCache_.resize(numScvf); + globalScvfIndices_.resize(numScvf); + IndexType localScvfIdx = 0; + for (auto&& scvf : scvfs(fvGeometry)) + { + fluxVarsCache_[localScvfIdx].update(globalFluxVarsCache().problem_(), element, fvGeometry, elemVolVars, scvf); + globalScvfIndices_[localScvfIdx] = scvf.index(); + localScvfIdx++; + } + + // add required data on the scv faces in the neighboring elements + for (IndexType localIdxJ = 0; localIdxJ < numNeighbors; ++localIdxJ) + { + const auto& fluxVarIndicesJ = globalFluxVarsCache().problem_().model().localJacobian().assemblyMap()[globalI][localIdxJ]; + const auto elementJ = fvGeometry.globalFvGeometry().element(neighborStencil[localIdxJ]); + + for (auto fluxVarIdx : fluxVarIndicesJ) + { + auto&& scvfJ = fvGeometry.scvf(fluxVarIdx); + fluxVarsCache_[localScvfIdx].update(globalFluxVarsCache().problem_(), elementJ, fvGeometry, elemVolVars, scvfJ); + globalScvfIndices_[localScvfIdx] = scvfJ.index(); + localScvfIdx++; + } + } + } + + void bindScvf(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf) + { + fluxVarsCache_.resize(1); + globalScvfIndices_.resize(1); + + fluxVarsCache_[0].update(globalFluxVarsCache().problem_(), element, fvGeometry, elemVolVars, scvf); + globalScvfIndices_[0] = scvf.index(); + } + + // access operators in the case of no caching + const FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) const + { return fluxVarsCache_[getLocalScvfIdx_(scvf.index())]; } + + FluxVariablesCache& operator [](const SubControlVolumeFace& scvf) + { return fluxVarsCache_[getLocalScvfIdx_(scvf.index())]; } + + //! The global object we are a restriction of + const GlobalFluxVariablesCache& globalFluxVarsCache() const + { return *globalFluxVarsCachePtr_; } + +private: + const GlobalFluxVariablesCache* globalFluxVarsCachePtr_; + + // get index of scvf in the local container + int getLocalScvfIdx_(const int scvfIdx) const + { + auto it = std::find(globalScvfIndices_.begin(), globalScvfIndices_.end(), scvfIdx); + assert(it != globalScvfIndices_.end() && "Could not find the flux vars cache for scvfIdx"); + return std::distance(globalScvfIndices_.begin(), it); + } + + std::vector<FluxVariablesCache> fluxVarsCache_; + std::vector<IndexType> globalScvfIndices_; +}; + +} // end namespace + +#endif diff --git a/dumux/discretization/staggered/elementvolumevariables.hh b/dumux/discretization/staggered/elementvolumevariables.hh new file mode 100644 index 0000000000000000000000000000000000000000..0e8e8739974481a374a7c21bba6ceb2c0a783710 --- /dev/null +++ b/dumux/discretization/staggered/elementvolumevariables.hh @@ -0,0 +1,215 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * \brief The local (stencil) volume variables class for cell centered models + */ +#ifndef DUMUX_DISCRETIZATION_STAGGERED_ELEMENT_VOLUMEVARIABLES_HH +#define DUMUX_DISCRETIZATION_STAGGERED_ELEMENT_VOLUMEVARIABLES_HH + +#include <dumux/implicit/properties.hh> + +namespace Dumux +{ + +/*! + * \ingroup ImplicitModel + * \brief Base class for the volume variables vector + */ +template<class TypeTag, bool enableGlobalVolVarsCache> +class StaggeredElementVolumeVariables +{}; + +// specialization in case of storing the volume variables globally +template<class TypeTag> +class StaggeredElementVolumeVariables<TypeTag, /*enableGlobalVolVarsCache*/true> +{ + 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 FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); + using GlobalVolumeVariables = typename GET_PROP_TYPE(TypeTag, GlobalVolumeVariables); + using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume); + using IndexType = typename GridView::IndexSet::IndexType; + + static const int dim = GridView::dimension; + using Element = typename GridView::template Codim<0>::Entity; + +public: + //! Constructor + StaggeredElementVolumeVariables(const GlobalVolumeVariables& globalVolVars) + : globalVolVarsPtr_(&globalVolVars) {} + + const VolumeVariables& operator [](const SubControlVolume& scv) const + { return globalVolVars().volVars(scv.index()); } + + // operator for the access with an index + // needed for Staggered methods for the access to the boundary volume variables + const VolumeVariables& operator [](const IndexType scvIdx) const + { return globalVolVars().volVars(scvIdx); } + + // 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, + const FVElementGeometry& fvGeometry, + const SolutionVector& sol) + {} + + // function to prepare the vol vars within the element + void bindElement(const Element& element, + const FVElementGeometry& fvGeometry, + const SolutionVector& sol) + {} + + //! The global volume variables object we are a restriction of + const GlobalVolumeVariables& globalVolVars() const + { return *globalVolVarsPtr_; } + +private: + const GlobalVolumeVariables* globalVolVarsPtr_; +}; + + +// Specialization when the current volume variables are not stored +template<class TypeTag> +class StaggeredElementVolumeVariables<TypeTag, /*enableGlobalVolVarsCache*/false> +{ + 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 VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); + using GlobalVolumeVariables = typename GET_PROP_TYPE(TypeTag, GlobalVolumeVariables); + using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using IndexType = typename GridView::IndexSet::IndexType; + + static const int dim = GridView::dimension; + using Element = typename GridView::template Codim<0>::Entity; + +public: + + //! Constructor + StaggeredElementVolumeVariables(const GlobalVolumeVariables& globalVolVars) + : globalVolVarsPtr_(&globalVolVars) {} + + // Binding of an element, prepares the volume variables within the element stencil + // called by the local jacobian to prepare element assembly + void bind(const Element& element, + const FVElementGeometry& fvGeometry, + const SolutionVector& sol) + { + auto eIdx = globalVolVars().problem_().elementMapper().index(element); + + // stencil information + const auto& neighborStencil = globalVolVars().problem_().model().stencils(element).neighborStencil(); + const auto numDofs = neighborStencil.size() + 1; + + // resize local containers to the required size (for internal elements) + volumeVariables_.resize(numDofs); + volVarIndices_.resize(numDofs); + int localIdx = 0; + + // update the volume variables of the element at hand + auto&& scvI = fvGeometry.scv(eIdx); + volumeVariables_[localIdx].update(sol[eIdx], globalVolVars().problem_(), element, scvI); + volVarIndices_[localIdx] = scvI.index(); + ++localIdx; + + // Update the volume variables of the neighboring elements + for (auto globalJ : neighborStencil) + { + const auto& elementJ = fvGeometry.globalFvGeometry().element(globalJ); + auto&& scvJ = fvGeometry.scv(globalJ); + volumeVariables_[localIdx].update(sol[globalJ], globalVolVars().problem_(), elementJ, scvJ); + volVarIndices_[localIdx] = scvJ.index(); + ++localIdx; + } + + // 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 = globalVolVars().problem_().boundaryTypes(element, scvf); + if (bcTypes.hasOnlyDirichlet()) + { + const auto dirichletPriVars = globalVolVars().problem_().dirichlet(element, scvf); + + volumeVariables_.resize(localIdx+1); + volVarIndices_.resize(localIdx+1); + volumeVariables_[localIdx].update(dirichletPriVars, globalVolVars().problem_(), element, scvI); + volVarIndices_[localIdx] = scvf.outsideScvIdx(); + ++localIdx; + } + } + } + + // Binding of an element, prepares only the volume variables of the element + // specialization for Staggered models + void bindElement(const Element& element, + const FVElementGeometry& fvGeometry, + const SolutionVector& sol) + { + auto eIdx = globalVolVars().problem_().elementMapper().index(element); + volumeVariables_.resize(1); + volVarIndices_.resize(1); + + // update the volume variables of the element + auto&& scv = fvGeometry.scv(eIdx); + volumeVariables_[0].update(sol[eIdx], globalVolVars().problem_(), element, scv); + volVarIndices_[0] = scv.index(); + } + + const VolumeVariables& operator [](const SubControlVolume& scv) const + { return volumeVariables_[getLocalIdx_(scv.index())]; } + + VolumeVariables& operator [](const SubControlVolume& scv) + { return volumeVariables_[getLocalIdx_(scv.index())]; } + + const VolumeVariables& operator [](IndexType scvIdx) const + { return volumeVariables_[getLocalIdx_(scvIdx)]; } + + VolumeVariables& operator [](IndexType scvIdx) + { return volumeVariables_[getLocalIdx_(scvIdx)]; } + + //! The global volume variables object we are a restriction of + const GlobalVolumeVariables& globalVolVars() const + { return *globalVolVarsPtr_; } + +private: + const GlobalVolumeVariables* globalVolVarsPtr_; + + const int getLocalIdx_(const int volVarIdx) const + { + auto it = std::find(volVarIndices_.begin(), volVarIndices_.end(), volVarIdx); + assert(it != volVarIndices_.end() && "Could not find the current volume variables for volVarIdx!"); + return std::distance(volVarIndices_.begin(), it); + } + + std::vector<IndexType> volVarIndices_; + std::vector<VolumeVariables> volumeVariables_; +}; + +} // end namespace + +#endif diff --git a/dumux/discretization/staggered/globalfluxvariablescache.hh b/dumux/discretization/staggered/globalfluxvariablescache.hh index 8cd7bc756a7c26a450213d5f1a5ce612f6c2d7f0..21ceda9649b94d3244deacc6a8d4aa846dc8fa3a 100644 --- a/dumux/discretization/staggered/globalfluxvariablescache.hh +++ b/dumux/discretization/staggered/globalfluxvariablescache.hh @@ -20,11 +20,11 @@ * \file * \brief The global object of flux var caches */ -#ifndef DUMUX_DISCRETIZATION_CC_GLOBAL_FLUXVARSCACHE_HH -#define DUMUX_DISCRETIZATION_CC_GLOBAL_FLUXVARSCACHE_HH +#ifndef DUMUX_DISCRETIZATION_STAGGERED_GLOBAL_FLUXVARSCACHE_HH +#define DUMUX_DISCRETIZATION_STAGGERED_GLOBAL_FLUXVARSCACHE_HH #include <dumux/implicit/properties.hh> -#include <dumux/discretization/cellcentered/elementfluxvariablescache.hh> +#include <dumux/discretization/staggered/elementfluxvariablescache.hh> namespace Dumux { @@ -34,17 +34,17 @@ namespace Dumux * \brief Base class for the flux variables cache vector, we store one cache per face */ template<class TypeTag, bool EnableGlobalFluxVariablesCache> -class CCGlobalFluxVariablesCache; +class StaggeredGlobalFluxVariablesCache; /*! * \ingroup ImplicitModel * \brief Spezialization when caching globally */ template<class TypeTag> -class CCGlobalFluxVariablesCache<TypeTag, true> +class StaggeredGlobalFluxVariablesCache<TypeTag, true> { // the local class needs access to the problem - friend CCElementFluxVariablesCache<TypeTag, true>; + friend StaggeredElementFluxVariablesCache<TypeTag, true>; using Problem = typename GET_PROP_TYPE(TypeTag, Problem); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using IndexType = typename GridView::IndexSet::IndexType; @@ -80,7 +80,7 @@ public: * 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 ElementFluxVariablesCache localView(const CCGlobalFluxVariablesCache& global) + friend inline ElementFluxVariablesCache localView(const StaggeredGlobalFluxVariablesCache& global) { return ElementFluxVariablesCache(global); } private: @@ -105,10 +105,10 @@ private: * \brief Spezialization when not using global caching */ template<class TypeTag> -class CCGlobalFluxVariablesCache<TypeTag, false> +class StaggeredGlobalFluxVariablesCache<TypeTag, false> { // the local class needs access to the problem - friend CCElementFluxVariablesCache<TypeTag, false>; + friend StaggeredElementFluxVariablesCache<TypeTag, false>; using Problem = typename GET_PROP_TYPE(TypeTag, Problem); using ElementFluxVariablesCache = typename GET_PROP_TYPE(TypeTag, ElementFluxVariablesCache); @@ -122,7 +122,7 @@ public: * 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 ElementFluxVariablesCache localView(const CCGlobalFluxVariablesCache& global) + friend inline ElementFluxVariablesCache localView(const StaggeredGlobalFluxVariablesCache& global) { return ElementFluxVariablesCache(global); } private: diff --git a/dumux/discretization/staggered/globalvolumevariables.hh b/dumux/discretization/staggered/globalvolumevariables.hh new file mode 100644 index 0000000000000000000000000000000000000000..cea72bcffc194021be12fe54072cf643eccc8ea2 --- /dev/null +++ b/dumux/discretization/staggered/globalvolumevariables.hh @@ -0,0 +1,155 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * \brief The global volume variables class for cell centered models + */ +#ifndef DUMUX_DISCRETIZATION_STAGGERED_GLOBAL_VOLUMEVARIABLES_HH +#define DUMUX_DISCRETIZATION_STAGGERED_GLOBAL_VOLUMEVARIABLES_HH + +#include <dumux/implicit/properties.hh> +#include <dumux/discretization/cellcentered/elementvolumevariables.hh> + +namespace Dumux +{ + +/*! + * \ingroup ImplicitModel + * \brief Base class for the volume variables vector + */ +template<class TypeTag, bool enableGlobalVolVarsCache> +class StaggeredGlobalVolumeVariables +{}; + +//! specialization in case of storing the volume variables +template<class TypeTag> +class StaggeredGlobalVolumeVariables<TypeTag, /*enableGlobalVolVarsCache*/true> +{ + // The local class needs to access and change volVars + friend StaggeredElementVolumeVariables<TypeTag, true>; + // The local jacobian needs to access and change volVars for derivative calculation + friend typename GET_PROP_TYPE(TypeTag, LocalJacobian); + // as does the primary variable switch + friend class PrimaryVariableSwitch<TypeTag>; + friend typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch); + + 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 VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); + using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume); + using IndexType = typename GridView::IndexSet::IndexType; + + static const int dim = GridView::dimension; + using Element = typename GridView::template Codim<0>::Entity; + +public: + void update(Problem& problem, const SolutionVector& sol) + { + problemPtr_ = &problem; + + auto numScv = problem.model().globalFvGeometry().numScv(); + auto numBoundaryScvf = problem.model().globalFvGeometry().numBoundaryScvf(); + + volumeVariables_.resize(numScv + numBoundaryScvf); + for (const auto& element : elements(problem.gridView())) + { + auto fvGeometry = localView(problem.model().globalFvGeometry()); + fvGeometry.bindElement(element); + + for (auto&& scv : scvs(fvGeometry)) + volumeVariables_[scv.index()].update(sol[scv.dofIndex()], problem, element, scv); + + // handle the boundary volume variables + for (auto&& scvf : scvfs(fvGeometry)) + { + // 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 = problem.dirichlet(element, scvf); + + volumeVariables_[scvf.outsideScvIdx()].update(dirichletPriVars, problem, element, insideScv); + } + } + } + } + + /*! + * \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 ElementVolumeVariables localView(const StaggeredGlobalVolumeVariables& global) + { return ElementVolumeVariables(global); } + + const VolumeVariables& volVars(const IndexType scvIdx) const + { return volumeVariables_[scvIdx]; } + + VolumeVariables& volVars(const IndexType scvIdx) + { return volumeVariables_[scvIdx]; } +private: + const Problem& problem_() const + { return *problemPtr_; } + + const Problem* problemPtr_; + + std::vector<VolumeVariables> volumeVariables_; +}; + + +//! Specialization when the current volume variables are not stored globally +template<class TypeTag> +class StaggeredGlobalVolumeVariables<TypeTag, /*enableGlobalVolVarsCache*/false> +{ + // local class needs access to the problem + friend StaggeredElementVolumeVariables<TypeTag, false>; + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); + +public: + void update(Problem& problem, const SolutionVector& sol) + { problemPtr_ = &problem; } + + /*! + * \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 ElementVolumeVariables localView(const StaggeredGlobalVolumeVariables& global) + { return ElementVolumeVariables(global); } + +private: + Problem& problem_() const + { return *problemPtr_;} + + Problem* problemPtr_; +}; + +} // end namespace + +#endif diff --git a/dumux/discretization/staggered/stencils.hh b/dumux/discretization/staggered/stencils.hh index a5a38759f1ce62590f04624ffc814cce5f444a77..f8a0f42a3bb8c381e2d4efba28684b3294e31b6b 100644 --- a/dumux/discretization/staggered/stencils.hh +++ b/dumux/discretization/staggered/stencils.hh @@ -24,7 +24,7 @@ #define DUMUX_DISCRETIZATION_STAGGERED_STENCILS_HH #include <set> -#include <dumux/implicit/cellcentered/properties.hh> +#include <dumux/implicit/staggered/properties.hh> namespace Dumux { diff --git a/dumux/freeflow/staggered/fluxvariablescache.hh b/dumux/freeflow/staggered/fluxvariablescache.hh index 74aeabf631a5aa23db116acf91deea34ff1b4419..d690147a9b5afa257c13d05d2c9eaa7e3950563e 100644 --- a/dumux/freeflow/staggered/fluxvariablescache.hh +++ b/dumux/freeflow/staggered/fluxvariablescache.hh @@ -42,113 +42,6 @@ class FreeFlowFluxVariablesCacheImplementation template<class TypeTag> using FreeFlowFluxVariablesCache = FreeFlowFluxVariablesCacheImplementation<TypeTag, GET_PROP_VALUE(TypeTag, DiscretizationMethod)>; -// specialization for the Box Method -template<class TypeTag> -class FreeFlowFluxVariablesCacheImplementation<TypeTag, DiscretizationMethods::Box> -{ - 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 FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); - using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace); - using AdvectionType = typename GET_PROP_TYPE(TypeTag, AdvectionType); - using Element = typename GridView::template Codim<0>::Entity; - using IndexType = typename GridView::IndexSet::IndexType; - using Stencil = std::vector<IndexType>; - using TransmissibilityVector = std::vector<IndexType>; - - using CoordScalar = typename GridView::ctype; - static const int dim = GridView::dimension; - - using FeCache = Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1>; - using FeLocalBasis = typename FeCache::FiniteElementType::Traits::LocalBasisType; - using ShapeJacobian = typename FeLocalBasis::Traits::JacobianType; - using ShapeValue = typename Dune::FieldVector<Scalar, 1>; - using JacobianInverseTransposed = typename Element::Geometry::JacobianInverseTransposed; - -public: - - void update(const Problem& problem, - const Element& element, - const FVElementGeometry& fvGeometry, - const SubControlVolumeFace &scvf) - { - const auto geometry = element.geometry(); - const auto& localBasis = fvGeometry.feLocalBasis(); - - // evaluate shape functions and gradients at the integration point - const auto ipLocal = geometry.local(scvf.center()); - jacInvT_ = geometry.jacobianInverseTransposed(ipLocal); - localBasis.evaluateJacobian(ipLocal, shapeJacobian_); - //localBasis.evaluateFunction(ipLocal, shapeValue_); // do we need the shapeValues for the flux? - - // The stencil info is obsolete for the box method. - // It is here for compatibility with cc methods - stencil_ = Stencil(0); - } - - const std::vector<ShapeJacobian>& shapeJacobian() const - { return shapeJacobian_; } - - /* const std::vector<ShapeValue>& shapeValue() const - { return shapeValue_; }*/ - - const JacobianInverseTransposed& jacInvT() const - { return jacInvT_; } - - const Stencil& stencil() const - { - return stencil_; - } - -private: - std::vector<ShapeJacobian> shapeJacobian_; - //std::vector<ShapeValue> shapeValue_; - JacobianInverseTransposed jacInvT_; - - Stencil stencil_; -}; - -// specialization for the cell centered tpfa method -template<class TypeTag> -class FreeFlowFluxVariablesCacheImplementation<TypeTag, DiscretizationMethods::CCTpfa> -{ - 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 FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); - using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); - using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace); - using AdvectionType = typename GET_PROP_TYPE(TypeTag, AdvectionType); - using Element = typename GridView::template Codim<0>::Entity; - using IndexType = typename GridView::IndexSet::IndexType; - using Stencil = std::vector<IndexType>; - -public: - void update(const Problem& problem, - const Element& element, - const FVElementGeometry& fvGeometry, - const ElementVolumeVariables& elemVolVars, - const SubControlVolumeFace &scvf) - { - FluxVariables fluxVars; - stencil_ = fluxVars.computeStencil(problem, element, fvGeometry, scvf); - tij_ = AdvectionType::calculateTransmissibilities(problem, element, fvGeometry, elemVolVars, scvf); - } - - const Stencil& stencil() const - { return stencil_; } - - const Scalar& tij() const - { return tij_; } - -private: - Stencil stencil_; - Scalar tij_; -}; - // specialization for the cell centered tpfa method template<class TypeTag> class FreeFlowFluxVariablesCacheImplementation<TypeTag, DiscretizationMethods::Staggered> diff --git a/dumux/implicit/staggered/elementvolumevariables.hh b/dumux/implicit/staggered/elementvolumevariables.hh new file mode 100644 index 0000000000000000000000000000000000000000..6ee6a935958565e3a4c349410798a43f9e13f9e1 --- /dev/null +++ b/dumux/implicit/staggered/elementvolumevariables.hh @@ -0,0 +1,159 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * \brief Volume variables gathered on an element + */ +#ifndef DUMUX_STAGGERED_ELEMENT_VOLUME_VARIABLES_HH +#define DUMUX_STAGGERED_ELEMENT_VOLUME_VARIABLES_HH + +#include "properties.hh" + +namespace Dumux +{ + +/*! + * \ingroup CCModel + * \brief This class stores an array of VolumeVariables objects, one + * volume variables object for each of the element's vertices + */ +template<class TypeTag> +class StaggeredElementVolumeVariables +{ + typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; + typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; + typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; + typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; + typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; + typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes; + typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; + + typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; + typedef typename GridView::template Codim<0>::Entity Element; + +public: + /*! + * \brief The constructor. + */ + StaggeredElementVolumeVariables() + { } + + /*! + * \brief Construct the volume variables for all of vertices of an element. + * + * \param problem The problem which needs to be simulated. + * \param element The DUNE Codim<0> entity for which the volume variables ought to be calculated + * \param fvGeometry The finite volume geometry of the element + * \param oldSol Tells whether the model's previous or current solution should be used. + */ + void update(Problem &problem, + const Element &element, + const FVElementGeometry &fvGeometry, + bool oldSol) + { + oldSol_ = oldSol; + problem_ = &problem; + + int numNeighbors = fvGeometry.numNeighbors; + stencil_.resize(numNeighbors); + + for (int i = 0; i < numNeighbors; i++) + { + const Element& neighbor = fvGeometry.neighbors[i]; + stencil_[i] = problem.elementMapper().index(neighbor); + } + + // only treat boundary if current solution is evaluated + if (!oldSol) + { + // check if element intersects with the boundary + ElementBoundaryTypes elemBCTypes; + elemBCTypes.update(problem, element); + if (elemBCTypes.hasDirichlet() + || elemBCTypes.hasNeumann() + || elemBCTypes.hasOutflow()) + { + ghostVolVars_ = std::vector<VolumeVariables>(element.subEntities(1)); + isDirichlet_ = std::vector<bool>(element.subEntities(1), false); + + // add volume variables for the boundary faces + for (const auto& intersection : intersections(problem.gridView(), element)) + { + if (!intersection.boundary()) + continue; + + BoundaryTypes bcTypes; + problem.boundaryTypes(bcTypes, intersection); + + int fIdx = intersection.indexInInside(); + if (bcTypes.hasDirichlet()) + { + PrimaryVariables dirichletValues; + problem.dirichlet(dirichletValues, intersection); + + ghostVolVars_[fIdx].update(dirichletValues, + problem, + element, + fvGeometry, + /*scvIdx=*/0, + oldSol); + isDirichlet_[fIdx] = true; + } + } + } + } + } + + const VolumeVariables& operator [](const unsigned int i) const + { + if (i >= stencil_.size()) + { + assert(!oldSol_); // old boundary volVars don't exist + if (isDirichlet_[i - stencil_.size()]) // ghost volVars only exist for Dirichlet boundaries + return ghostVolVars_[i - stencil_.size()]; + else + return problem_->model().volVars(stencil_[0]); + } + else + { + if(!oldSol_) + return problem_->model().volVars(stencil_[i]); + else + return problem_->model().prevVolVars(stencil_[i]); + } + } + + VolumeVariables& operator [](const unsigned int i) + { + assert(!oldSol_); // old volVars should never be modified + assert(i < stencil_.size()); // boundary volVars should not be modified + return problem_->model().volVars(stencil_[i]); + } + +private: + bool oldSol_ = false; + std::vector<unsigned int> stencil_; + std::vector<VolumeVariables> ghostVolVars_; + std::vector<bool> isDirichlet_; + Problem* problem_; +}; + +} // namespace Dumux + +#endif diff --git a/dumux/implicit/staggered/localjacobian.hh b/dumux/implicit/staggered/localjacobian.hh index 1791521d0e38b9587bb28635eaca7931ad5c173d..719964d6996d46f36c3196872245a872267bb871 100644 --- a/dumux/implicit/staggered/localjacobian.hh +++ b/dumux/implicit/staggered/localjacobian.hh @@ -110,45 +110,6 @@ public: void init(Problem &problem) { ParentType::init(problem); - -// assemblyMap_.resize(problem.gridView().size(0)); -// for (const auto& element : elements(problem.gridView())) -// { -// // get a local finite volume geometry object that is bindable -// auto fvGeometryJ = localView(problem.model().globalFvGeometry()); -// -// auto globalI = problem.elementMapper().index(element); -// const auto& neighborStencil = this->model_().stencils(element).neighborStencil(); -// -// // assemblyMap_[globalI].reserve(neighborStencil.size()); -// for (auto globalJ : neighborStencil) -// { -// const auto& elementJ = fvGeometryJ.globalFvGeometry().element(globalJ); -// -// // find the flux vars needed for the calculation of the flux into element -// std::vector<IndexType> fluxVarIndices; -// -// // only non-ghost neighbors (J) have to be considered, derivatives from non-ghost to ghost dofs -// // are assembled when assembling the ghost element (I) -// if (elementJ.partitionType() != Dune::GhostEntity) -// { -// fvGeometryJ.bindElement(elementJ); -// for (auto&& scvFaceJ : scvfs(fvGeometryJ)) -// { -// auto fluxVarsIdx = scvFaceJ.index(); -// -// // if globalI is in flux var stencil, add to list -// FluxVariables fluxVars; -// const auto fluxStencil = fluxVars.computeStencil(problem, elementJ, fvGeometryJ, scvFaceJ); -// -// for (auto globalIdx : fluxStencil) -// if (globalIdx == globalI) -// fluxVarIndices.push_back(fluxVarsIdx); -// } -// } -// // assemblyMap_[globalI].emplace_back(std::move(fluxVarIndices)); -// } -// } } /*! diff --git a/dumux/implicit/staggered/propertydefaults.hh b/dumux/implicit/staggered/propertydefaults.hh index 1b385410ef3217973c131be0121db124dec21194..ae7e1ab4e2ad95e4970aed84f6610535d6b8f6cd 100644 --- a/dumux/implicit/staggered/propertydefaults.hh +++ b/dumux/implicit/staggered/propertydefaults.hh @@ -36,6 +36,12 @@ #include <dumux/discretization/methods.hh> #include <dumux/discretization/staggered/stencils.hh> +#include <dumux/discretization/staggered/globalfluxvariablescache.hh> +#include <dumux/discretization/staggered/elementfluxvariablescache.hh> + +#include <dumux/discretization/staggered/elementvolumevariables.hh> +#include <dumux/discretization/staggered/globalvolumevariables.hh> + #include <dumux/freeflow/staggered/fluxvariables.hh> #include <dumux/freeflow/staggered/fluxvariablescache.hh> @@ -93,10 +99,10 @@ SET_TYPE_PROP(StaggeredModel, ElementBoundaryTypes, Dumux::CCElementBoundaryType SET_TYPE_PROP(StaggeredModel, DofMapper, typename GET_PROP_TYPE(TypeTag, ElementMapper)); //! The global current volume variables vector class -SET_TYPE_PROP(StaggeredModel, GlobalVolumeVariables, Dumux::CCGlobalVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGlobalVolumeVariablesCache)>); +SET_TYPE_PROP(StaggeredModel, GlobalVolumeVariables, Dumux::StaggeredGlobalVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGlobalVolumeVariablesCache)>); //! The global flux variables cache vector class -SET_TYPE_PROP(StaggeredModel, GlobalFluxVariablesCache, Dumux::CCGlobalFluxVariablesCache<TypeTag, GET_PROP_VALUE(TypeTag, EnableGlobalFluxVariablesCache)>); +SET_TYPE_PROP(StaggeredModel, GlobalFluxVariablesCache, Dumux::StaggeredGlobalFluxVariablesCache<TypeTag, GET_PROP_VALUE(TypeTag, EnableGlobalFluxVariablesCache)>); //! The local jacobian operator SET_TYPE_PROP(StaggeredModel, LocalJacobian, Dumux::StaggeredLocalJacobian<TypeTag>); @@ -108,10 +114,10 @@ SET_TYPE_PROP(StaggeredModel, JacobianAssembler, Dumux::StaggeredAssembler<TypeT SET_TYPE_PROP(StaggeredModel, StencilsVector, Dumux::StaggeredStencilsVector<TypeTag>); //! The local flux variables cache vector class -SET_TYPE_PROP(StaggeredModel, ElementFluxVariablesCache, Dumux::CCElementFluxVariablesCache<TypeTag, GET_PROP_VALUE(TypeTag, EnableGlobalFluxVariablesCache)>); +SET_TYPE_PROP(StaggeredModel, ElementFluxVariablesCache, Dumux::StaggeredElementFluxVariablesCache<TypeTag, GET_PROP_VALUE(TypeTag, EnableGlobalFluxVariablesCache)>); //! The global previous volume variables vector class -SET_TYPE_PROP(StaggeredModel, ElementVolumeVariables, Dumux::CCElementVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGlobalVolumeVariablesCache)>); +SET_TYPE_PROP(StaggeredModel, ElementVolumeVariables, Dumux::StaggeredElementVolumeVariables<TypeTag, GET_PROP_VALUE(TypeTag, EnableGlobalVolumeVariablesCache)>); //! Set the BaseLocalResidual to StaggeredLocalResidual SET_TYPE_PROP(StaggeredModel, BaseLocalResidual, Dumux::StaggeredLocalResidual<TypeTag>); diff --git a/test/freeflow/staggered/staggeredtestproblem.hh b/test/freeflow/staggered/staggeredtestproblem.hh index 10082c27791c28934b19a5f4335f71b6d0742939..22720849cd8db10c975523c5a1ecfcd9ff38e70d 100644 --- a/test/freeflow/staggered/staggeredtestproblem.hh +++ b/test/freeflow/staggered/staggeredtestproblem.hh @@ -69,6 +69,9 @@ SET_TYPE_PROP(StaggeredTestProblem, Problem, Dumux::StaggeredTestProblem<TypeTag SET_BOOL_PROP(StaggeredTestProblem, EnableGlobalFVGeometryCache, true); +SET_BOOL_PROP(StaggeredTestProblem, EnableGlobalFluxVariablesCache, true); +SET_BOOL_PROP(StaggeredTestProblem, EnableGlobalVolumeVariablesCache, true); + // Enable gravity SET_BOOL_PROP(StaggeredTestProblem, ProblemEnableGravity, true);