version 3.8
cvfelocalresidual.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
13#ifndef DUMUX_CVFE_LOCAL_RESIDUAL_HH
14#define DUMUX_CVFE_LOCAL_RESIDUAL_HH
15
16#include <dune/common/std/type_traits.hh>
17#include <dune/geometry/type.hh>
18#include <dune/istl/matrix.hh>
19
24
25namespace Dumux::Detail {
26
27template<class Imp, class P, class G, class S, class V>
29 std::declval<Imp>().computeStorage(
30 std::declval<P>(), std::declval<G>(), std::declval<S>(), std::declval<V>(), true
31 )
32);
33
34template<class Imp, class P, class G, class S, class V>
35constexpr inline bool hasTimeInfoInterfaceCVFE()
36{ return Dune::Std::is_detected<TimeInfoInterfaceCVFEDetector, Imp, P, G, S, V>::value; }
37
38template<class Imp>
40 std::declval<Imp>().isOverlapping()
41);
42
43template<class Imp>
44constexpr inline bool hasScvfIsOverlapping()
45{ return Dune::Std::is_detected<SCVFIsOverlappingDetector, Imp>::value; }
46
47} // end namespace Dumux::Detail
48
49
50namespace Dumux {
51
58template<class TypeTag>
59class CVFELocalResidual : public FVLocalResidual<TypeTag>
60{
66 using GridView = typename GridGeometry::GridView;
67 using Element = typename GridView::template Codim<0>::Entity;
69 using FVElementGeometry = typename GridGeometry::LocalView;
71 using ElementVolumeVariables = typename GridVolumeVariables::LocalView;
72 using VolumeVariables = typename GridVolumeVariables::VolumeVariables;
73 using SubControlVolume = typename FVElementGeometry::SubControlVolume;
74 using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
75 using ElementFluxVariablesCache = typename GetPropType<TypeTag, Properties::GridFluxVariablesCache>::LocalView;
77 using NumEqVector = Dumux::NumEqVector<PrimaryVariables>;
78 using Extrusion = Extrusion_t<GridGeometry>;
79
80public:
82 using ParentType::ParentType;
83
86 const Problem& problem,
87 const Element& element,
88 const FVElementGeometry& fvGeometry,
89 const ElementVolumeVariables& elemVolVars,
90 const ElementBoundaryTypes& elemBcTypes,
91 const ElementFluxVariablesCache& elemFluxVarsCache,
92 const SubControlVolumeFace& scvf) const
93 {
94 const auto flux = evalFlux(problem, element, fvGeometry, elemVolVars, elemBcTypes, elemFluxVarsCache, scvf);
95 if (!scvf.boundary())
96 {
97 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
98 const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx());
99 residual[insideScv.localDofIndex()] += flux;
100
101 // for control-volume finite element schemes with overlapping control volumes
102 if constexpr (Detail::hasScvfIsOverlapping<SubControlVolumeFace>())
103 {
104 if (!scvf.isOverlapping())
105 residual[outsideScv.localDofIndex()] -= flux;
106 }
107 else
108 residual[outsideScv.localDofIndex()] -= flux;
109 }
110 else
111 {
112 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
113 residual[insideScv.localDofIndex()] += flux;
114 }
115 }
116
118 NumEqVector evalFlux(const Problem& problem,
119 const Element& element,
120 const FVElementGeometry& fvGeometry,
121 const ElementVolumeVariables& elemVolVars,
122 const ElementBoundaryTypes& elemBcTypes,
123 const ElementFluxVariablesCache& elemFluxVarsCache,
124 const SubControlVolumeFace& scvf) const
125 {
126 NumEqVector flux(0.0);
127
128 // inner faces
129 if (!scvf.boundary())
130 flux += this->asImp().computeFlux(problem, element, fvGeometry, elemVolVars, scvf, elemFluxVarsCache);
131
132 // boundary faces
133 else
134 {
135 const auto& scv = fvGeometry.scv(scvf.insideScvIdx());
136 const auto& bcTypes = elemBcTypes.get(fvGeometry, scv);
137
138 // Treat Neumann and Robin ("solution dependent Neumann") boundary conditions.
139 // For Dirichlet there is no addition to the residual here but they
140 // are enforced strongly by replacing the residual entry afterwards.
141 if (bcTypes.hasNeumann())
142 {
143 auto neumannFluxes = problem.neumann(element, fvGeometry, elemVolVars, elemFluxVarsCache, scvf);
144
145 // multiply neumann fluxes with the area and the extrusion factor
146 neumannFluxes *= Extrusion::area(fvGeometry, scvf)*elemVolVars[scv].extrusionFactor();
147
148 // only add fluxes to equations for which Neumann is set
149 for (int eqIdx = 0; eqIdx < NumEqVector::dimension; ++eqIdx)
150 if (bcTypes.isNeumann(eqIdx))
151 flux[eqIdx] += neumannFluxes[eqIdx];
152 }
153 }
154
155 return flux;
156 }
157
175 const Problem& problem,
176 const Element& element,
177 const FVElementGeometry& fvGeometry,
178 const ElementVolumeVariables& prevElemVolVars,
179 const ElementVolumeVariables& curElemVolVars,
180 const SubControlVolume& scv) const
181 {
182 const auto& curVolVars = curElemVolVars[scv];
183 const auto& prevVolVars = prevElemVolVars[scv];
184
185 // Compute storage with the model specific storage residual
186 // This addresses issues #792/#940 in ad-hoc way by additionally providing crude time level information (previous or current)
187 // to the low-level interfaces if this is supported by the LocalResidual implementation
188 NumEqVector prevStorage = computeStorageImpl_(problem, fvGeometry, scv, prevVolVars, /*previous time level?*/true);
189 NumEqVector storage = computeStorageImpl_(problem, fvGeometry, scv, curVolVars, /*previous time level?*/false);
190
191 prevStorage *= prevVolVars.extrusionFactor();
192 storage *= curVolVars.extrusionFactor();
193
194 storage -= prevStorage;
195 storage *= Extrusion::volume(fvGeometry, scv);
196 storage /= this->timeLoop().timeStepSize();
197
198 residual[scv.localDofIndex()] += storage;
199 }
200
201private:
202 NumEqVector computeStorageImpl_(const Problem& problem,
203 const FVElementGeometry& fvGeometry,
204 const SubControlVolume& scv,
205 const VolumeVariables& volVars,
206 [[maybe_unused]] bool isPreviousTimeStep) const
207 {
208 if constexpr (Detail::hasTimeInfoInterfaceCVFE<Implementation, Problem, FVElementGeometry, SubControlVolume, VolumeVariables>())
209 return this->asImp().computeStorage(problem, fvGeometry, scv, volVars, isPreviousTimeStep);
210 else
211 return this->asImp().computeStorage(problem, scv, volVars);
212 }
213};
214
215} // end namespace Dumux
216
217#endif
The element-wise residual for control-volume finite element schemes.
Definition: cvfelocalresidual.hh:60
NumEqVector evalFlux(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementBoundaryTypes &elemBcTypes, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
evaluate flux residuals for one sub control volume face
Definition: cvfelocalresidual.hh:118
void evalStorage(ElementResidualVector &residual, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &prevElemVolVars, const ElementVolumeVariables &curElemVolVars, const SubControlVolume &scv) const
Compute the storage local residual, i.e. the deviation of the storage term from zero for instationary...
Definition: cvfelocalresidual.hh:174
void evalFlux(ElementResidualVector &residual, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementBoundaryTypes &elemBcTypes, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
evaluate flux residuals for one sub control volume face and add to residual
Definition: cvfelocalresidual.hh:85
typename ParentType::ElementResidualVector ElementResidualVector
Definition: cvfelocalresidual.hh:81
The element-wise residual for finite volume schemes.
Definition: fvlocalresidual.hh:35
Implementation & asImp()
Definition: fvlocalresidual.hh:487
const Problem & problem() const
the problem
Definition: fvlocalresidual.hh:472
ReservedBlockVector< NumEqVector, FVElementGeometry::maxNumElementScvs > ElementResidualVector
the container storing all element residuals
Definition: fvlocalresidual.hh:57
const TimeLoop & timeLoop() const
Definition: fvlocalresidual.hh:477
ElementResidualVector evalStorage(const Problem &problem, const Element &element, const GridGeometry &gridGeometry, const GridVariables &gridVariables, const SolutionVector &sol) const
Compute the storage term for the current solution.
Definition: fvlocalresidual.hh:86
virtual Scalar timeStepSize() const =0
Returns the suggested time step length .
Defines all properties used in Dumux.
Helper classes to compute the integration elements.
The element-wise residual for finite volume schemes.
typename NumEqVectorTraits< PrimaryVariables >::type NumEqVector
A vector with the same size as numbers of equations This is the default implementation and has to be ...
Definition: numeqvector.hh:34
auto volume(const Geometry &geo, unsigned int integrationOrder=4)
The volume of a given geometry.
Definition: volume.hh:159
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:296
Distance implementation details.
Definition: cvfelocalresidual.hh:25
constexpr bool hasScvfIsOverlapping()
Definition: cvfelocalresidual.hh:44
constexpr bool hasTimeInfoInterfaceCVFE()
Definition: cvfelocalresidual.hh:35
decltype(std::declval< Imp >().computeStorage(std::declval< P >(), std::declval< G >(), std::declval< S >(), std::declval< V >(), true)) TimeInfoInterfaceCVFEDetector
Definition: cvfelocalresidual.hh:32
decltype(std::declval< Imp >().isOverlapping()) SCVFIsOverlappingDetector
Definition: cvfelocalresidual.hh:41
Definition: adapt.hh:17
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition: extrusion.hh:166
A helper to deduce a vector with the same size as numbers of equations.