version 3.10-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-FileCopyrightInfo: 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
24
25namespace Dumux {
26
33template<class TypeTag>
35{
40 using Element = typename GridView::template Codim<0>::Entity;
41 using FVElementGeometry = typename GetPropType<TypeTag, Properties::GridGeometry>::LocalView;
44 using SubControlVolume = typename GridGeometry::SubControlVolume;
45 using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace;
46 using Extrusion = Extrusion_t<GridGeometry>;
49 using ElementFluxVariablesCache = typename GetPropType<TypeTag, Properties::GridFluxVariablesCache>::LocalView;
51 using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView;
54
55public:
58
60 FVLocalResidual(const Problem* problem,
61 const TimeLoop* timeLoop = nullptr)
62 : problem_(problem)
63 , timeLoop_(timeLoop)
64 {}
65
71 // \{
72
87 const Element &element,
88 const GridGeometry& gridGeometry,
89 const GridVariables& gridVariables,
90 const SolutionVector& sol) const
91 {
92 // make sure FVElementGeometry and volume variables are bound to the element
93 const auto fvGeometry = localView(gridGeometry).bind(element);
94 const auto elemVolVars = localView(gridVariables.curGridVolVars()).bind(element, fvGeometry, sol);
95
96 ElementResidualVector storage(fvGeometry.numScv());
97
98 // calculate the amount of conservation each quantity inside
99 // all sub control volumes
100 for (auto&& scv : scvs(fvGeometry))
101 {
102 auto localScvIdx = scv.localDofIndex();
103 const auto& volVars = elemVolVars[scv];
104 storage[localScvIdx] = asImp().computeStorage(problem, scv, volVars);
105 storage[localScvIdx] *= Extrusion::volume(fvGeometry, scv) * volVars.extrusionFactor();
106 }
107
108 return storage;
109 }
110
111 // \}
112
117 // \{
118
131 ElementResidualVector evalStorage(const Element& element,
132 const FVElementGeometry& fvGeometry,
133 const ElementVolumeVariables& prevElemVolVars,
134 const ElementVolumeVariables& curElemVolVars) const
135 {
136 assert(timeLoop_ && "no time loop set for storage term evaluation");
137
138 // initialize the residual vector for all scvs in this element
139 ElementResidualVector residual(fvGeometry.numScv());
140
141 // evaluate the volume terms (storage + source terms)
142 // forward to the local residual specialized for the discretization methods
143 for (auto&& scv : scvs(fvGeometry))
144 asImp().evalStorage(residual, this->problem(), element, fvGeometry, prevElemVolVars, curElemVolVars, scv);
145
146 return residual;
147 }
148
150 const FVElementGeometry& fvGeometry,
151 const ElementVolumeVariables& elemVolVars,
152 const ElementFluxVariablesCache& elemFluxVarsCache,
153 const ElementBoundaryTypes &bcTypes) const
154 {
155 // initialize the residual vector for all scvs in this element
156 ElementResidualVector residual(fvGeometry.numScv());
157
158 // evaluate the volume terms (storage + source terms)
159 // forward to the local residual specialized for the discretization methods
160 for (auto&& scv : scvs(fvGeometry))
161 asImp().evalSource(residual, this->problem(), element, fvGeometry, elemVolVars, scv);
162
163 // forward to the local residual specialized for the discretization methods
164 for (auto&& scvf : scvfs(fvGeometry))
165 asImp().evalFlux(residual, this->problem(), element, fvGeometry, elemVolVars, bcTypes, elemFluxVarsCache, scvf);
166
167 return residual;
168 }
169
170 // \}
171
172
177 // \{
178
188 NumEqVector computeStorage(const Problem& problem,
189 const SubControlVolume& scv,
190 const VolumeVariables& volVars) const
191 {
192 DUNE_THROW(Dune::NotImplemented, "This model does not implement a storage method!");
193 }
194
208 NumEqVector computeSource(const Problem& problem,
209 const Element& element,
210 const FVElementGeometry& fvGeometry,
211 const ElementVolumeVariables& elemVolVars,
212 const SubControlVolume &scv) const
213 {
214 NumEqVector source(0.0);
215
216 // add contributions from volume flux sources
217 source += problem.source(element, fvGeometry, elemVolVars, scv);
218
219 // add contribution from possible point sources
220 if (!problem.pointSourceMap().empty())
221 source += problem.scvPointSources(element, fvGeometry, elemVolVars, scv);
222
223 return source;
224 }
225
240 NumEqVector computeFlux(const Problem& problem,
241 const Element& element,
242 const FVElementGeometry& fvGeometry,
243 const ElementVolumeVariables& elemVolVars,
244 const SubControlVolumeFace& scvf,
245 const ElementFluxVariablesCache& elemFluxVarsCache) const
246 {
247 DUNE_THROW(Dune::NotImplemented, "This model does not implement a flux method!");
248 }
249
250 // \}
251
256 // \{
257
274 const Problem& problem,
275 const Element& element,
276 const FVElementGeometry& fvGeometry,
277 const ElementVolumeVariables& prevElemVolVars,
278 const ElementVolumeVariables& curElemVolVars,
279 const SubControlVolume& scv) const
280 {
281 const auto& curVolVars = curElemVolVars[scv];
282 const auto& prevVolVars = prevElemVolVars[scv];
283
284 // mass balance within the element. this is the
285 // \f$\frac{m}{\partial t}\f$ term if using implicit or explicit
286 // euler as time discretization.
287 //
288 // TODO: We might need a more explicit way for
289 // doing the time discretization...
290
292 NumEqVector prevStorage = asImp().computeStorage(problem, scv, prevVolVars);
293 NumEqVector storage = asImp().computeStorage(problem, scv, curVolVars);
294
295 prevStorage *= prevVolVars.extrusionFactor();
296 storage *= curVolVars.extrusionFactor();
297
298 storage -= prevStorage;
299 storage *= Extrusion::volume(fvGeometry, scv);
300 storage /= timeLoop_->timeStepSize();
301
302 residual[scv.localDofIndex()] += storage;
303 }
304
319 const Problem& problem,
320 const Element& element,
321 const FVElementGeometry& fvGeometry,
322 const ElementVolumeVariables& curElemVolVars,
323 const SubControlVolume& scv) const
324 {
326 const auto& curVolVars = curElemVolVars[scv];
327 NumEqVector source = asImp().computeSource(problem, element, fvGeometry, curElemVolVars, scv);
328 source *= Extrusion::volume(fvGeometry, scv)*curVolVars.extrusionFactor();
329
331 residual[scv.localDofIndex()] -= source;
332 }
333
349 const Problem& problem,
350 const Element& element,
351 const FVElementGeometry& fvGeometry,
352 const ElementVolumeVariables& elemVolVars,
353 const ElementBoundaryTypes& elemBcTypes,
354 const ElementFluxVariablesCache& elemFluxVarsCache,
355 const SubControlVolumeFace& scvf) const {}
356
370 NumEqVector evalFlux(const Problem& problem,
371 const Element& element,
372 const FVElementGeometry& fvGeometry,
373 const ElementVolumeVariables& elemVolVars,
374 const ElementFluxVariablesCache& elemFluxVarsCache,
375 const SubControlVolumeFace& scvf) const
376 {
377 return asImp().evalFlux(problem, element, fvGeometry, elemVolVars, elemFluxVarsCache, scvf);
378 }
379
380 //\}
381
385 // \{
386
388 template<class PartialDerivativeMatrix>
389 void addStorageDerivatives(PartialDerivativeMatrix& partialDerivatives,
390 const Problem& problem,
391 const Element& element,
392 const FVElementGeometry& fvGeometry,
393 const VolumeVariables& curVolVars,
394 const SubControlVolume& scv) const
395 {
396 DUNE_THROW(Dune::NotImplemented, "analytic storage derivative");
397 }
398
400 template<class PartialDerivativeMatrix>
401 void addSourceDerivatives(PartialDerivativeMatrix& partialDerivatives,
402 const Problem& problem,
403 const Element& element,
404 const FVElementGeometry& fvGeometry,
405 const VolumeVariables& curVolVars,
406 const SubControlVolume& scv) const
407 {
408 DUNE_THROW(Dune::NotImplemented, "analytic source derivative");
409 }
410
412 template<class PartialDerivativeMatrices, class T = TypeTag>
413 std::enable_if_t<GetPropType<T, Properties::GridGeometry>::discMethod != DiscretizationMethods::box, void>
414 addFluxDerivatives(PartialDerivativeMatrices& derivativeMatrices,
415 const Problem& problem,
416 const Element& element,
417 const FVElementGeometry& fvGeometry,
418 const ElementVolumeVariables& curElemVolVars,
419 const ElementFluxVariablesCache& elemFluxVarsCache,
420 const SubControlVolumeFace& scvf) const
421 {
422 DUNE_THROW(Dune::NotImplemented, "analytic flux derivative for cell-centered models");
423 }
424
426 template<class JacobianMatrix, class T = TypeTag>
427 std::enable_if_t<GetPropType<T, Properties::GridGeometry>::discMethod == DiscretizationMethods::box, void>
428 addFluxDerivatives(JacobianMatrix& A,
429 const Problem& problem,
430 const Element& element,
431 const FVElementGeometry& fvGeometry,
432 const ElementVolumeVariables& curElemVolVars,
433 const ElementFluxVariablesCache& elemFluxVarsCache,
434 const SubControlVolumeFace& scvf) const
435 {
436 DUNE_THROW(Dune::NotImplemented, "analytic flux derivative for box models");
437 }
438
440 template<class PartialDerivativeMatrices>
441 void addCCDirichletFluxDerivatives(PartialDerivativeMatrices& derivativeMatrices,
442 const Problem& problem,
443 const Element& element,
444 const FVElementGeometry& fvGeometry,
445 const ElementVolumeVariables& curElemVolVars,
446 const ElementFluxVariablesCache& elemFluxVarsCache,
447 const SubControlVolumeFace& scvf) const
448 {
449 DUNE_THROW(Dune::NotImplemented, "analytic Dirichlet flux derivative");
450 }
451
453 template<class PartialDerivativeMatrices>
454 void addRobinFluxDerivatives(PartialDerivativeMatrices& derivativeMatrices,
455 const Problem& problem,
456 const Element& element,
457 const FVElementGeometry& fvGeometry,
458 const ElementVolumeVariables& curElemVolVars,
459 const ElementFluxVariablesCache& elemFluxVarsCache,
460 const SubControlVolumeFace& scvf) const
461 {
462 DUNE_THROW(Dune::NotImplemented, "analytic Robin flux derivative");
463 }
464
465 //\}
466
470 // \{
471
473 const Problem& problem() const
474 { return *problem_; }
475
478 const TimeLoop& timeLoop() const
479 { return *timeLoop_; }
480
482 bool isStationary() const
483 { return !timeLoop_; }
484
485 // \}
486protected:
487
488 Implementation &asImp()
489 { return *static_cast<Implementation*>(this); }
490
491 const Implementation &asImp() const
492 { return *static_cast<const Implementation*>(this); }
493
494private:
495 const Problem* problem_;
496 const TimeLoop* timeLoop_;
497};
498
499} // end namespace Dumux
500
501#endif
The element-wise residual for finite volume schemes.
Definition: fvlocalresidual.hh:35
Implementation & asImp()
Definition: fvlocalresidual.hh:488
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:208
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:454
NumEqVector computeStorage(const Problem &problem, const SubControlVolume &scv, const VolumeVariables &volVars) const
Calculate the source term of the equation.
Definition: fvlocalresidual.hh:188
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:348
const Problem & problem() const
the problem
Definition: fvlocalresidual.hh:473
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:401
const TimeLoop & timeLoop() const
Definition: fvlocalresidual.hh:478
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:389
bool isStationary() const
returns true if the residual is stationary
Definition: fvlocalresidual.hh:482
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:370
const Implementation & asImp() const
Definition: fvlocalresidual.hh:491
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
FVLocalResidual(const Problem *problem, const TimeLoop *timeLoop=nullptr)
the constructor
Definition: fvlocalresidual.hh:60
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:131
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:414
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:318
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:428
ElementResidualVector evalFluxAndSource(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const ElementBoundaryTypes &bcTypes) const
Definition: fvlocalresidual.hh:149
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:273
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:441
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:240
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
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.