version 3.11-dev
fvlocalresidual.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_FV_LOCAL_RESIDUAL_HH
13#define DUMUX_FV_LOCAL_RESIDUAL_HH
14
15#include <dune/common/exceptions.hh>
16#include <dune/istl/bvector.hh>
17
18#include <dumux/common/typetraits/localdofs_.hh>
25
26namespace Dumux {
27
34template<class TypeTag>
36{
41 using Element = typename GridView::template Codim<0>::Entity;
42 using FVElementGeometry = typename GetPropType<TypeTag, Properties::GridGeometry>::LocalView;
45 using SubControlVolume = typename GridGeometry::SubControlVolume;
46 using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace;
47 using Extrusion = Extrusion_t<GridGeometry>;
50 using ElementFluxVariablesCache = typename GetPropType<TypeTag, Properties::GridFluxVariablesCache>::LocalView;
52 using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView;
55
56public:
59
61 FVLocalResidual(const Problem* problem,
62 const TimeLoop* timeLoop = nullptr)
63 : problem_(problem)
64 , timeLoop_(timeLoop)
65 {}
66
72 // \{
73
88 const Element &element,
89 const GridGeometry& gridGeometry,
90 const GridVariables& gridVariables,
91 const SolutionVector& sol) const
92 {
93 // make sure FVElementGeometry and volume variables are bound to the element
94 const auto fvGeometry = localView(gridGeometry).bind(element);
95 const auto elemVolVars = localView(gridVariables.curGridVolVars()).bind(element, fvGeometry, sol);
96
97 ElementResidualVector storage(fvGeometry.numScv());
98
99 // calculate the amount of conservation each quantity inside
100 // all sub control volumes
101 for (auto&& scv : scvs(fvGeometry))
102 {
103 auto localScvIdx = scv.localDofIndex();
104 const auto& volVars = elemVolVars[scv];
105 storage[localScvIdx] = asImp().computeStorage(problem, scv, volVars);
106 storage[localScvIdx] *= Extrusion::volume(fvGeometry, scv) * volVars.extrusionFactor();
107 }
108
109 return storage;
110 }
111
112 // \}
113
118 // \{
119
132 ElementResidualVector evalStorage(const Element& element,
133 const FVElementGeometry& fvGeometry,
134 const ElementVolumeVariables& prevElemVolVars,
135 const ElementVolumeVariables& curElemVolVars) const
136 {
137 assert(timeLoop_ && "no time loop set for storage term evaluation");
138
139 // initialize the residual vector for all scvs in this element
140 ElementResidualVector residual(fvGeometry.numScv());
141
142 // evaluate the volume terms (storage + source terms)
143 // forward to the local residual specialized for the discretization methods
144 for (auto&& scv : scvs(fvGeometry))
145 asImp().evalStorage(residual, this->problem(), element, fvGeometry, prevElemVolVars, curElemVolVars, scv);
146
147 return residual;
148 }
149
151 const FVElementGeometry& fvGeometry,
152 const ElementVolumeVariables& elemVolVars,
153 const ElementFluxVariablesCache& elemFluxVarsCache,
154 const ElementBoundaryTypes &bcTypes) const
155 {
156 // initialize the residual vector for all scvs in this element
157 ElementResidualVector residual(fvGeometry.numScv());
158
159 // evaluate the volume terms (storage + source terms)
160 // forward to the local residual specialized for the discretization methods
161 for (auto&& scv : scvs(fvGeometry))
162 asImp().evalSource(residual, this->problem(), element, fvGeometry, elemVolVars, scv);
163
164 // forward to the local residual specialized for the discretization methods
165 for (auto&& scvf : scvfs(fvGeometry))
166 asImp().evalFlux(residual, this->problem(), element, fvGeometry, elemVolVars, bcTypes, elemFluxVarsCache, scvf);
167
168 return residual;
169 }
170
171 // \}
172
173
178 // \{
179
189 NumEqVector computeStorage(const Problem& problem,
190 const SubControlVolume& scv,
191 const VolumeVariables& volVars) const
192 {
193 DUNE_THROW(Dune::NotImplemented, "This model does not implement a storage method!");
194 }
195
209 NumEqVector computeSource(const Problem& problem,
210 const Element& element,
211 const FVElementGeometry& fvGeometry,
212 const ElementVolumeVariables& elemVolVars,
213 const SubControlVolume &scv) const
214 {
215 NumEqVector source(0.0);
216
217 // add contributions from volume flux sources
218 source += problem.source(element, fvGeometry, elemVolVars, scv);
219
220 // add contribution from possible point sources
221 if (!problem.pointSourceMap().empty())
222 source += problem.scvPointSources(element, fvGeometry, elemVolVars, scv);
223
224 return source;
225 }
226
241 NumEqVector computeFlux(const Problem& problem,
242 const Element& element,
243 const FVElementGeometry& fvGeometry,
244 const ElementVolumeVariables& elemVolVars,
245 const SubControlVolumeFace& scvf,
246 const ElementFluxVariablesCache& elemFluxVarsCache) const
247 {
248 DUNE_THROW(Dune::NotImplemented, "This model does not implement a flux method!");
249 }
250
251 // \}
252
257 // \{
258
275 const Problem& problem,
276 const Element& element,
277 const FVElementGeometry& fvGeometry,
278 const ElementVolumeVariables& prevElemVolVars,
279 const ElementVolumeVariables& curElemVolVars,
280 const SubControlVolume& scv) const
281 {
282 const auto& curVolVars = curElemVolVars[scv];
283 const auto& prevVolVars = prevElemVolVars[scv];
284
285 // mass balance within the element. this is the
286 // \f$\frac{m}{\partial t}\f$ term if using implicit or explicit
287 // euler as time discretization.
288 //
289 // TODO: We might need a more explicit way for
290 // doing the time discretization...
291
293 NumEqVector prevStorage = asImp().computeStorage(problem, scv, prevVolVars);
294 NumEqVector storage = asImp().computeStorage(problem, scv, curVolVars);
295
296 prevStorage *= prevVolVars.extrusionFactor();
297 storage *= curVolVars.extrusionFactor();
298
299 storage -= prevStorage;
300 storage *= Extrusion::volume(fvGeometry, scv);
301 storage /= timeLoop_->timeStepSize();
302
303 residual[scv.localDofIndex()] += storage;
304 }
305
320 const Problem& problem,
321 const Element& element,
322 const FVElementGeometry& fvGeometry,
323 const ElementVolumeVariables& curElemVolVars,
324 const SubControlVolume& scv) const
325 {
327 const auto& curVolVars = curElemVolVars[scv];
328 NumEqVector source = asImp().computeSource(problem, element, fvGeometry, curElemVolVars, scv);
329 source *= Extrusion::volume(fvGeometry, scv)*curVolVars.extrusionFactor();
330
332 residual[scv.localDofIndex()] -= source;
333 }
334
350 const Problem& problem,
351 const Element& element,
352 const FVElementGeometry& fvGeometry,
353 const ElementVolumeVariables& elemVolVars,
354 const ElementBoundaryTypes& elemBcTypes,
355 const ElementFluxVariablesCache& elemFluxVarsCache,
356 const SubControlVolumeFace& scvf) const {}
357
371 NumEqVector evalFlux(const Problem& problem,
372 const Element& element,
373 const FVElementGeometry& fvGeometry,
374 const ElementVolumeVariables& elemVolVars,
375 const ElementFluxVariablesCache& elemFluxVarsCache,
376 const SubControlVolumeFace& scvf) const
377 {
378 return asImp().evalFlux(problem, element, fvGeometry, elemVolVars, elemFluxVarsCache, scvf);
379 }
380
381 //\}
382
386 // \{
387
389 template<class PartialDerivativeMatrix>
390 void addStorageDerivatives(PartialDerivativeMatrix& partialDerivatives,
391 const Problem& problem,
392 const Element& element,
393 const FVElementGeometry& fvGeometry,
394 const VolumeVariables& curVolVars,
395 const SubControlVolume& scv) const
396 {
397 DUNE_THROW(Dune::NotImplemented, "analytic storage derivative");
398 }
399
401 template<class PartialDerivativeMatrix>
402 void addSourceDerivatives(PartialDerivativeMatrix& partialDerivatives,
403 const Problem& problem,
404 const Element& element,
405 const FVElementGeometry& fvGeometry,
406 const VolumeVariables& curVolVars,
407 const SubControlVolume& scv) const
408 {
409 DUNE_THROW(Dune::NotImplemented, "analytic source derivative");
410 }
411
413 template<class PartialDerivativeMatrices, class T = TypeTag>
414 std::enable_if_t<GetPropType<T, Properties::GridGeometry>::discMethod != DiscretizationMethods::box, void>
415 addFluxDerivatives(PartialDerivativeMatrices& derivativeMatrices,
416 const Problem& problem,
417 const Element& element,
418 const FVElementGeometry& fvGeometry,
419 const ElementVolumeVariables& curElemVolVars,
420 const ElementFluxVariablesCache& elemFluxVarsCache,
421 const SubControlVolumeFace& scvf) const
422 {
423 DUNE_THROW(Dune::NotImplemented, "analytic flux derivative for cell-centered models");
424 }
425
427 template<class JacobianMatrix, class T = TypeTag>
428 std::enable_if_t<GetPropType<T, Properties::GridGeometry>::discMethod == DiscretizationMethods::box, void>
429 addFluxDerivatives(JacobianMatrix& A,
430 const Problem& problem,
431 const Element& element,
432 const FVElementGeometry& fvGeometry,
433 const ElementVolumeVariables& curElemVolVars,
434 const ElementFluxVariablesCache& elemFluxVarsCache,
435 const SubControlVolumeFace& scvf) const
436 {
437 DUNE_THROW(Dune::NotImplemented, "analytic flux derivative for box models");
438 }
439
441 template<class PartialDerivativeMatrices>
442 void addCCDirichletFluxDerivatives(PartialDerivativeMatrices& derivativeMatrices,
443 const Problem& problem,
444 const Element& element,
445 const FVElementGeometry& fvGeometry,
446 const ElementVolumeVariables& curElemVolVars,
447 const ElementFluxVariablesCache& elemFluxVarsCache,
448 const SubControlVolumeFace& scvf) const
449 {
450 DUNE_THROW(Dune::NotImplemented, "analytic Dirichlet flux derivative");
451 }
452
454 template<class PartialDerivativeMatrices>
455 void addRobinFluxDerivatives(PartialDerivativeMatrices& derivativeMatrices,
456 const Problem& problem,
457 const Element& element,
458 const FVElementGeometry& fvGeometry,
459 const ElementVolumeVariables& curElemVolVars,
460 const ElementFluxVariablesCache& elemFluxVarsCache,
461 const SubControlVolumeFace& scvf) const
462 {
463 DUNE_THROW(Dune::NotImplemented, "analytic Robin flux derivative");
464 }
465
466 //\}
467
471 // \{
472
474 const Problem& problem() const
475 { return *problem_; }
476
479 const TimeLoop& timeLoop() const
480 { return *timeLoop_; }
481
483 bool isStationary() const
484 { return !timeLoop_; }
485
486 // \}
487protected:
488
489 Implementation &asImp()
490 { return *static_cast<Implementation*>(this); }
491
492 const Implementation &asImp() const
493 { return *static_cast<const Implementation*>(this); }
494
495private:
496 const Problem* problem_;
497 const TimeLoop* timeLoop_;
498};
499
500} // end namespace Dumux
501
502#endif
The element-wise residual for finite volume schemes.
Definition: fvlocalresidual.hh:36
Implementation & asImp()
Definition: fvlocalresidual.hh:489
NumEqVector computeSource(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolume &scv) const
Calculate the source term of the equation.
Definition: fvlocalresidual.hh:209
void addRobinFluxDerivatives(PartialDerivativeMatrices &derivativeMatrices, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &curElemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
Compute the derivative of Robin type boundary conditions ("solution dependent Neumann")
Definition: fvlocalresidual.hh:455
NumEqVector computeStorage(const Problem &problem, const SubControlVolume &scv, const VolumeVariables &volVars) const
Calculate the source term of the equation.
Definition: fvlocalresidual.hh:189
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
Compute the flux local residual, i.e. the deviation of the flux term from zero.
Definition: fvlocalresidual.hh:349
const Problem & problem() const
the problem
Definition: fvlocalresidual.hh:474
void addSourceDerivatives(PartialDerivativeMatrix &partialDerivatives, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const VolumeVariables &curVolVars, const SubControlVolume &scv) const
Compute the derivative of the source residual.
Definition: fvlocalresidual.hh:402
const TimeLoop & timeLoop() const
Definition: fvlocalresidual.hh:479
void addStorageDerivatives(PartialDerivativeMatrix &partialDerivatives, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const VolumeVariables &curVolVars, const SubControlVolume &scv) const
Compute the derivative of the storage residual.
Definition: fvlocalresidual.hh:390
bool isStationary() const
returns true if the residual is stationary
Definition: fvlocalresidual.hh:483
NumEqVector evalFlux(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
Compute the flux local residual, i.e. the deviation of the flux term from zero.
Definition: fvlocalresidual.hh:371
const Implementation & asImp() const
Definition: fvlocalresidual.hh:492
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:87
FVLocalResidual(const Problem *problem, const TimeLoop *timeLoop=nullptr)
the constructor
Definition: fvlocalresidual.hh:61
ElementResidualVector evalStorage(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &prevElemVolVars, const ElementVolumeVariables &curElemVolVars) const
Compute the storage local residual, i.e. the deviation of the storage term from zero for instationary...
Definition: fvlocalresidual.hh:132
std::enable_if_t< GetPropType< T, Properties::GridGeometry >::discMethod !=DiscretizationMethods::box, void > addFluxDerivatives(PartialDerivativeMatrices &derivativeMatrices, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &curElemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
Compute the derivative of the flux residual.
Definition: fvlocalresidual.hh:415
void evalSource(ElementResidualVector &residual, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &curElemVolVars, const SubControlVolume &scv) const
Compute the source local residual, i.e. the deviation of the source term from zero.
Definition: fvlocalresidual.hh:319
std::enable_if_t< GetPropType< T, Properties::GridGeometry >::discMethod==DiscretizationMethods::box, void > addFluxDerivatives(JacobianMatrix &A, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &curElemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
Compute the derivative of the flux residual for the box method.
Definition: fvlocalresidual.hh:429
ElementResidualVector evalFluxAndSource(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const ElementBoundaryTypes &bcTypes) const
Definition: fvlocalresidual.hh:150
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: fvlocalresidual.hh:274
void addCCDirichletFluxDerivatives(PartialDerivativeMatrices &derivativeMatrices, const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &curElemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
Compute the derivative of the Dirichlet flux residual for cell-centered schemes.
Definition: fvlocalresidual.hh:442
NumEqVector computeFlux(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf, const ElementFluxVariablesCache &elemFluxVarsCache) const
Calculate the flux term of the equation.
Definition: fvlocalresidual.hh:241
A arithmetic block vector type based on DUNE's reserved vector.
Definition: reservedblockvector.hh:26
virtual Scalar timeStepSize() const =0
Returns the suggested time step length .
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.
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
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:26
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
The available discretization methods in Dumux.
constexpr Box box
Definition: method.hh:147
Definition: adapt.hh:17
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition: extrusion.hh:166
std::ranges::range auto scvs(const FVElementGeometry &fvGeometry, const LocalDof &localDof)
Definition: localdof.hh:79
A helper to deduce a vector with the same size as numbers of equations.
A arithmetic block vector type based on DUNE's reserved vector.