version 3.11-dev
Loading...
Searching...
No Matches
assembly/localresidual.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-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_BASE_LOCAL_RESIDUAL_HH
13#define DUMUX_BASE_LOCAL_RESIDUAL_HH
14
15#include <cassert>
16
17#include <dune/common/exceptions.hh>
18
19#include <dumux/common/typetraits/localdofs_.hh>
28
29namespace Dumux::Experimental {
30
37template<class TypeTag>
39{
44 using Element = typename GridView::template Codim<0>::Entity;
45 using ElementDiscretization = typename GetPropType<TypeTag, Properties::GridGeometry>::LocalView;
48 using Extrusion = Extrusion_t<GridGeometry>;
50 using GridVariablesCache = typename GridVariables::GridVariablesCache;
51 using ElementVariables = typename GridVariablesCache::LocalView;
52 using TimeLoop = TimeLoopBase<Scalar>;
53
54public:
57
59 LocalResidual(const Problem* problem,
60 const TimeLoop* timeLoop = nullptr)
61 : problem_(problem)
62 , timeLoop_(timeLoop)
63 {}
64
69 // \{
70
81 ElementResidualVector evalStorage(const Element& element,
82 const ElementDiscretization& elemDisc,
83 const ElementVariables& prevElemVars,
84 const ElementVariables& curElemVars) const
85 {
86 assert(!this->isStationary() && "no time loop set for storage term evaluation");
87
88 // initialize the residual vector for all local dofs in this element
89 ElementResidualVector residual(Dumux::Detail::LocalDofs::numLocalDofs(elemDisc));
90
91 // evaluate the volume terms (storage + source terms)
92 // forward to the local residual specialized for the discretization methods
94 {
95 for (const auto& scv : scvs(elemDisc))
96 this->asImp().evalStorage(residual, this->problem(), element, elemDisc, prevElemVars, curElemVars, scv);
97 }
98
99 // allow for additional contributions (e.g. hybrid CVFE / FE schemes)
100 this->asImp().addToElementStorageResidual(residual, this->problem(), element, elemDisc, prevElemVars, curElemVars);
101
102 return residual;
103 }
104
114 const ElementDiscretization& elemDisc,
115 const ElementVariables& elemVars) const
116 {
117 // initialize the residual vector for all local dofs in this element
118 ElementResidualVector residual(Dumux::Detail::LocalDofs::numLocalDofs(elemDisc));
119
121 {
122 // evaluate the volume terms (storage + source terms)
123 // forward to the local residual specialized for the discretization methods
124 for (const auto& scv : scvs(elemDisc))
125 this->asImp().evalSource(residual, this->problem(), element, elemDisc, elemVars, scv);
126
127 // forward to the local residual specialized for the discretization methods
128 // TODO: Provide scvfs range only over interior scvfs
129 for (auto&& scvf : scvfs(elemDisc))
130 if(!scvf.boundary())
131 this->asImp().evalFlux(residual, this->problem(), element, elemDisc, elemVars, scvf);
132 }
133
134 // allow for additional contributions (e.g. hybrid CVFE / FE schemes)
135 this->asImp().addToElementFluxAndSourceResidual(residual, this->problem(), element, elemDisc, elemVars);
136
137 // add boundary flux contributions
138 this->asImp().addBoundaryFluxIntegral(residual, this->problem(), elemDisc, elemVars);
139
140 return residual;
141 }
142
145 const Problem& problem,
146 const Element& element,
147 const ElementDiscretization& elemDisc,
148 const ElementVariables& prevElemVars,
149 const ElementVariables& curElemVars) const
150 {}
151
154 const Problem& problem,
155 const Element& element,
156 const ElementDiscretization& elemDisc,
157 const ElementVariables& curElemVars) const
158 {}
159
162 const Problem& problem,
163 const ElementDiscretization& elemDisc,
164 const ElementVariables& elemVars) const
165 {
166 if(!elemDisc.hasBoundaryFaces())
167 return;
168
169 for (const auto& boundaryFace : boundaryFaces(elemDisc))
170 {
171 const auto& bcTypes = problem.boundaryTypes(elemDisc, boundaryFace);
172 if(!bcTypes.hasFluxBoundary())
173 continue;
174
177 problem.addFEBoundaryFluxIntegral(residual, elemDisc, elemVars, boundaryFace, bcTypes);
178
180 for(const auto& scvf : scvfs(elemDisc, boundaryFace))
181 problem.addFVBoundaryFluxIntegral(residual, elemDisc, elemVars, scvf, bcTypes);
182 }
183 }
184
185 // \}
186
191 // \{
192
203 template<class SubControlVolume>
204 NumEqVector storageIntegral(const ElementDiscretization& elemDisc,
205 const ElementVariables& elemVars,
206 const SubControlVolume& scv,
207 bool isPreviousTimeLevel) const
208 {
209 DUNE_THROW(Dune::NotImplemented, "This model does not implement a storageIntegral method!");
210 }
211
222 template<class SubControlVolume>
223 NumEqVector sourceIntegral(const ElementDiscretization& elemDisc,
224 const ElementVariables& elemVars,
225 const SubControlVolume& scv) const
226 {
227 NumEqVector source(0.0);
228
229 const auto& problem = this->asImp().problem();
230 for (const auto& qpData : CVFE::quadratureRule(elemDisc, scv))
231 source += qpData.weight() * problem.source(elemDisc, elemVars, qpData.ipData());
232
233 source *= elemVars[scv].extrusionFactor();
234
235 // add contribution from possible point sources
236 const auto& pointSources = problem.pointSources();
237 if (!pointSources.empty())
238 for (const auto& context : pointSources.contexts(elemDisc, scv))
239 {
240 auto psValues = pointSources.eval(elemDisc, elemVars, context);
241 source += psValues;
242 }
243
244 return source;
245 }
246
257 template<class SubControlVolumeFace>
258 NumEqVector fluxIntegral(const ElementDiscretization& elemDisc,
259 const ElementVariables& elemVars,
260 const SubControlVolumeFace& scvf) const
261 {
262 DUNE_THROW(Dune::NotImplemented, "This model does not implement a fluxIntegral method!");
263 }
264
265 // \}
266
271 // \{
272
286 template<class SubControlVolume>
288 const Problem& problem,
289 const Element& element,
290 const ElementDiscretization& elemDisc,
291 const ElementVariables& prevElemVars,
292 const ElementVariables& curElemVars,
293 const SubControlVolume& scv) const
294 {
295 // mass balance within the element. this is the
296 // \f$\frac{\partial S}{\partial t}\f$ term if using implicit or explicit
297 // euler as time discretization.
298 //
299 // TODO: We might need a more explicit way for
300 // doing the time discretization...
301
303 NumEqVector prevStorage = this->asImp().storageIntegral(elemDisc, prevElemVars, scv, /*previous time level?*/true);
304 NumEqVector storage = this->asImp().storageIntegral(elemDisc, curElemVars, scv, /*previous time level?*/false);
305
306 storage -= prevStorage;
307 storage /= timeLoop_->timeStepSize();
308
309 residual[scv.localDofIndex()] += storage;
310 }
311
324 template<class SubControlVolume>
326 const Problem& problem,
327 const Element& element,
328 const ElementDiscretization& elemDisc,
329 const ElementVariables& curElemVars,
330 const SubControlVolume& scv) const
331 {
333 NumEqVector source = this->asImp().sourceIntegral(elemDisc, curElemVars, scv);
335 residual[scv.localDofIndex()] -= source;
336 }
337
348 template<class SubControlVolumeFace>
350 const Problem& problem,
351 const Element& element,
352 const ElementDiscretization& elemDisc,
353 const ElementVariables& elemVars,
354 const SubControlVolumeFace& scvf) const {}
355
366 template<class SubControlVolumeFace>
367 NumEqVector evalFlux(const Problem& problem,
368 const Element& element,
369 const ElementDiscretization& elemDisc,
370 const ElementVariables& elemVars,
371 const SubControlVolumeFace& scvf) const
372 {
373 return asImp().evalFlux(problem, element, elemDisc, elemVars, scvf);
374 }
375
376 //\}
377
381 // \{
382
384 const Problem& problem() const
385 { return *problem_; }
386
389 const TimeLoop& timeLoop() const
390 { return *timeLoop_; }
391
393 bool isStationary() const
394 { return !timeLoop_; }
395
396 // \}
397
398protected:
399 Implementation& asImp()
400 { return *static_cast<Implementation*>(this); }
401
402 const Implementation& asImp() const
403 { return *static_cast<const Implementation*>(this); }
404
405private:
406 const Problem* problem_;
407 const TimeLoop* timeLoop_;
408};
409
410} // end namespace Dumux::Experimental
411
412#endif
GVC GridVariablesCache
export type of the grid variables cache
Definition discretization/gridvariables.hh:33
ElementResidualVector evalStorage(const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &prevElemVars, const ElementVariables &curElemVars) const
Compute the storage local residual, i.e. the deviation of the storage term from zero for instationary...
Definition assembly/localresidual.hh:81
LocalResidual(const Problem *problem, const TimeLoop *timeLoop=nullptr)
the constructor
Definition assembly/localresidual.hh:59
void evalSource(ElementResidualVector &residual, const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &curElemVars, const SubControlVolume &scv) const
Compute the source local residual, i.e. the deviation of the source term from zero.
Definition assembly/localresidual.hh:325
NumEqVector sourceIntegral(const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const SubControlVolume &scv) const
Calculate the source term integral of the equation.
Definition assembly/localresidual.hh:223
NumEqVector evalFlux(const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const SubControlVolumeFace &scvf) const
Compute the fluxes of the local residual.
Definition assembly/localresidual.hh:367
ElementResidualVector evalFluxAndSource(const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars) const
Compute the flux and source.
Definition assembly/localresidual.hh:113
const Problem & problem() const
the problem
Definition assembly/localresidual.hh:384
void addToElementStorageResidual(ElementResidualVector &residual, const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &prevElemVars, const ElementVariables &curElemVars) const
add additional storage contributions (e.g. hybrid CVFE or FE schemes)
Definition assembly/localresidual.hh:144
const TimeLoop & timeLoop() const
Definition assembly/localresidual.hh:389
bool isStationary() const
returns true if the residual is stationary
Definition assembly/localresidual.hh:393
const Implementation & asImp() const
Definition assembly/localresidual.hh:402
void evalFlux(ElementResidualVector &residual, const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const SubControlVolumeFace &scvf) const
Compute the fluxes of the local residual.
Definition assembly/localresidual.hh:349
NumEqVector storageIntegral(const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const SubControlVolume &scv, bool isPreviousTimeLevel) const
Calculate the source term integral of the equation.
Definition assembly/localresidual.hh:204
void addBoundaryFluxIntegral(ElementResidualVector &residual, const Problem &problem, const ElementDiscretization &elemDisc, const ElementVariables &elemVars) const
add boundary flux contributions
Definition assembly/localresidual.hh:161
void addToElementFluxAndSourceResidual(ElementResidualVector &residual, const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &curElemVars) const
add additional flux and source contributions (e.g. hybrid CVFE or FE schemes)
Definition assembly/localresidual.hh:153
Implementation & asImp()
Definition assembly/localresidual.hh:399
void evalStorage(ElementResidualVector &residual, const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &prevElemVars, const ElementVariables &curElemVars, const SubControlVolume &scv) const
Compute the storage local residual, i.e. the deviation of the storage term from zero for instationary...
Definition assembly/localresidual.hh:287
NumEqVector fluxIntegral(const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const SubControlVolumeFace &scvf) const
Calculate the flux integral of the equation.
Definition assembly/localresidual.hh:258
ReservedBlockVector< NumEqVector, Dumux::Detail::LocalDofs::maxNumLocalDofs< ElementDiscretization >()> ElementResidualVector
the container storing all element residuals
Definition assembly/localresidual.hh:56
Base class for all standard finite volume or finite element problems.
Definition common/problem.hh:39
A arithmetic block vector type based on DUNE's reserved vector.
Definition reservedblockvector.hh:26
Manages the handling of time dependent problems.
Definition common/timeloop.hh:84
The default time loop for instationary simulations.
Definition common/timeloop.hh:139
Defines all properties used in Dumux.
Manages the handling of time dependent problems.
Concept for pure finite-element discretizations (no FV structure).
Definition concepts.hh:50
Concept for finite-volume discretizations.
Definition concepts.hh:26
Concept for hybrid finite-element/finite-volume discretizations.
Definition concepts.hh:39
Concepts for discretization types.
Helper classes to compute the integration elements.
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
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
auto quadratureRule(const FVElementGeometry &fvGeometry, const typename FVElementGeometry::SubControlVolume &scv, QuadratureRules::MidpointQuadrature)
Midpoint quadrature for scv.
Definition quadraturerules.hh:159
Definition assembly/assembler.hh:44
std::ranges::range auto scvs(const FVElementGeometry &fvGeometry, const LocalDof &localDof)
Definition localdof.hh:82
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:257
A helper to deduce a vector with the same size as numbers of equations.
Point source types and helpers for handling point sources.
Quadrature rules over sub-control volumes and sub-control volume faces.
A arithmetic block vector type based on DUNE's reserved vector.