3.1-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
common/fvproblem.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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
24#ifndef DUMUX_COMMON_FV_PROBLEM_HH
25#define DUMUX_COMMON_FV_PROBLEM_HH
26
27#include <memory>
28#include <map>
29
30#include <dune/common/fvector.hh>
31#include <dune/grid/common/gridenums.hh>
32
36
37namespace Dumux {
38
48template<class TypeTag>
50{
51 using Implementation = GetPropType<TypeTag, Properties::Problem>;
52
54 using FVElementGeometry = typename GridGeometry::LocalView;
55 using GridView = typename GridGeometry::GridView;
56 using SubControlVolume = typename FVElementGeometry::SubControlVolume;
57 using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
58 using Element = typename GridView::template Codim<0>::Entity;
59 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
60
61 enum { dim = GridView::dimension };
62
65 using PointSourceMap = std::map< std::pair<std::size_t, std::size_t>,
66 std::vector<PointSource> >;
67
69 using ElementFluxVariablesCache = typename GetPropType<TypeTag, Properties::GridFluxVariablesCache>::LocalView;
70 using ElementVolumeVariables = typename GridVariables::GridVolumeVariables::LocalView;
71 using VolumeVariables = typename ElementVolumeVariables::VolumeVariables;
72
74
75 static constexpr bool isBox = GridGeometry::discMethod == DiscretizationMethod::box;
76 static constexpr bool isStaggered = GridGeometry::discMethod == DiscretizationMethod::staggered;
77
82
83public:
85 struct Traits
86 {
87 using Scalar = FVProblem::Scalar;
88 using PrimaryVariables = FVProblem::PrimaryVariables;
89 using NumEqVector = FVProblem::NumEqVector;
90 using BoundaryTypes = FVProblem::BoundaryTypes;
91 };
92
98 FVProblem(std::shared_ptr<const GridGeometry> gridGeometry, const std::string& paramGroup = "")
99 : gridGeometry_(gridGeometry)
100 , paramGroup_(paramGroup)
101 {
102 // set a default name for the problem
103 problemName_ = getParamFromGroup<std::string>(paramGroup, "Problem.Name");
104 }
105
113 const std::string& name() const
114 {
115 return problemName_;
116 }
117
127 void setName(const std::string& newName)
128 {
129 problemName_ = newName;
130 }
131
135 // \{
136
144 BoundaryTypes boundaryTypes(const Element &element,
145 const SubControlVolume &scv) const
146 {
147 if (!isBox)
148 DUNE_THROW(Dune::InvalidStateException,
149 "boundaryTypes(..., scv) called for cell-centered method.");
150
151 // forward it to the method which only takes the global coordinate
152 return asImp_().boundaryTypesAtPos(scv.dofPosition());
153 }
154
162 BoundaryTypes boundaryTypes(const Element &element,
163 const SubControlVolumeFace &scvf) const
164 {
165 if (isBox)
166 DUNE_THROW(Dune::InvalidStateException,
167 "boundaryTypes(..., scvf) called for box method.");
168
169 // forward it to the method which only takes the global coordinate
170 return asImp_().boundaryTypesAtPos(scvf.ipGlobal());
171 }
172
179 BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
180 {
183 BoundaryTypes bcTypes;
184 bcTypes.setAllDirichlet();
185 return bcTypes;
186 }
187
198 PrimaryVariables dirichlet(const Element &element, const SubControlVolumeFace &scvf) const
199 {
200 // forward it to the method which only takes the global coordinate
201 if (isBox)
202 {
203 DUNE_THROW(Dune::InvalidStateException, "dirichlet(scvf) called for box method.");
204 }
205 else
206 return asImp_().dirichletAtPos(scvf.ipGlobal());
207 }
208
219 PrimaryVariables dirichlet(const Element &element, const SubControlVolume &scv) const
220 {
221 // forward it to the method which only takes the global coordinate
222 if (!isBox && !isStaggered)
223 {
224 DUNE_THROW(Dune::InvalidStateException, "dirichlet(scv) called for other than box or staggered method.");
225 }
226 else
227 return asImp_().dirichletAtPos(scv.dofPosition());
228 }
229
238 PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const
239 {
240 // Throw an exception (there is no reasonable default value
241 // for Dirichlet conditions)
242 DUNE_THROW(Dune::InvalidStateException,
243 "The problem specifies that some boundary "
244 "segments are dirichlet, but does not provide "
245 "a dirichlet() or a dirichletAtPos() method.");
246 }
247
265 { return false; }
266
283 NumEqVector neumann(const Element& element,
284 const FVElementGeometry& fvGeometry,
285 const ElementVolumeVariables& elemVolVars,
286 const ElementFluxVariablesCache& elemFluxVarsCache,
287 const SubControlVolumeFace& scvf) const
288 {
289 // forward it to the interface with only the global position
290 return asImp_().neumannAtPos(scvf.ipGlobal());
291 }
292
302 NumEqVector neumannAtPos(const GlobalPosition &globalPos) const
303 {
306 return NumEqVector(0.0);
307 }
308
327 NumEqVector source(const Element &element,
328 const FVElementGeometry& fvGeometry,
329 const ElementVolumeVariables& elemVolVars,
330 const SubControlVolume &scv) const
331 {
332 // forward to solution independent, fully-implicit specific interface
333 return asImp_().sourceAtPos(scv.center());
334 }
335
349 NumEqVector sourceAtPos(const GlobalPosition &globalPos) const
350 {
353 return NumEqVector(0.0);
354 }
355
369 void addPointSources(std::vector<PointSource>& pointSources) const {}
370
390 void pointSource(PointSource& source,
391 const Element &element,
392 const FVElementGeometry& fvGeometry,
393 const ElementVolumeVariables& elemVolVars,
394 const SubControlVolume &scv) const
395 {
396 // forward to space dependent interface method
397 asImp_().pointSourceAtPos(source, source.position());
398 }
399
415 void pointSourceAtPos(PointSource& pointSource,
416 const GlobalPosition &globalPos) const {}
417
422 template<class MatrixBlock>
423 void addSourceDerivatives(MatrixBlock& block,
424 const Element& element,
425 const FVElementGeometry& fvGeometry,
426 const VolumeVariables& volVars,
427 const SubControlVolume& scv) const {}
428
435 NumEqVector scvPointSources(const Element &element,
436 const FVElementGeometry& fvGeometry,
437 const ElementVolumeVariables& elemVolVars,
438 const SubControlVolume &scv) const
439 {
440 NumEqVector source(0);
441 auto scvIdx = scv.indexInElement();
442 auto key = std::make_pair(gridGeometry_->elementMapper().index(element), scvIdx);
443 if (pointSourceMap_.count(key))
444 {
445 // call the solDependent function. Herein the user might fill/add values to the point sources
446 // we make a copy of the local point sources here
447 auto pointSources = pointSourceMap_.at(key);
448
449 // Add the contributions to the dof source values
450 // We divide by the volume. In the local residual this will be multiplied with the same
451 // factor again. That's because the user specifies absolute values in kg/s.
452 const auto volume = scv.volume()*elemVolVars[scv].extrusionFactor();
453
454 for (auto&& pointSource : pointSources)
455 {
456 // Note: two concepts are implemented here. The PointSource property can be set to a
457 // customized point source function achieving variable point sources,
458 // see TimeDependentPointSource for an example. The second imitated the standard
459 // dumux source interface with solDependentPointSource / pointSourceAtPos, methods
460 // that can be overloaded in the actual problem class also achieving variable point sources.
461 // The first one is more convenient for simple function like a time dependent source.
462 // The second one might be more convenient for e.g. a solution dependent point source.
463
464 // we do an update e.g. used for TimeDependentPointSource
465 pointSource.update(asImp_(), element, fvGeometry, elemVolVars, scv);
466 // call convienience problem interface function
467 asImp_().pointSource(pointSource, element, fvGeometry, elemVolVars, scv);
468 // at last take care about multiplying with the correct volume
469 pointSource /= volume*pointSource.embeddings();
470 // add the point source values to the local residual
471 source += pointSource.values();
472 }
473 }
474
475 return source;
476 }
477
484 {
485 // clear the given point source maps in case it's not empty
486 pointSourceMap_.clear();
487
488 // get and apply point sources if any given in the problem
489 std::vector<PointSource> sources;
490 asImp_().addPointSources(sources);
491
492 // if there are point sources compute the DOF to point source map
493 if (!sources.empty())
494 {
495 // calculate point source locations and save them in a map
496 PointSourceHelper::computePointSourceMap(*gridGeometry_,
497 sources,
498 pointSourceMap_);
499 }
500 }
501
505 const PointSourceMap& pointSourceMap() const
506 { return pointSourceMap_; }
507
512 void applyInitialSolution(SolutionVector& sol) const
513 {
514 // set the initial values by forwarding to a specialized method
515 applyInitialSolutionImpl_(sol, std::integral_constant<bool, isBox>());
516 }
517
525 template<class Entity>
526 PrimaryVariables initial(const Entity& entity) const
527 {
528 static_assert(int(Entity::codimension) == 0 || int(Entity::codimension) == dim, "Entity must be element or vertex");
529 return asImp_().initialAtPos(entity.geometry().center());
530 }
531
537 PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
538 {
539 // Throw an exception (there is no reasonable default value
540 // for initial values)
541 DUNE_THROW(Dune::InvalidStateException,
542 "The problem does not provide "
543 "an initial() or an initialAtPos() method.");
544 }
545
555 template<class ElementSolution>
556 Scalar extrusionFactor(const Element& element,
557 const SubControlVolume& scv,
558 const ElementSolution& elemSol) const
559 {
560 // forward to generic interface
561 return asImp_().extrusionFactorAtPos(scv.center());
562 }
563
573 Scalar extrusionFactorAtPos(const GlobalPosition &globalPos) const
574 {
575 // As a default, i.e. if the user's problem does not overload
576 // any extrusion factor method, return 1.0
577 return 1.0;
578 }
579
580 // \}
581
583 [[deprecated("Use gridGeometry() instead. fvGridGeometry() will be removed after 3.1!")]]
584 const GridGeometry& fvGridGeometry() const
585 { return gridGeometry(); }
586
588 const GridGeometry& gridGeometry() const
589 { return *gridGeometry_; }
590
592 const std::string& paramGroup() const
593 { return paramGroup_; }
594
595protected:
597 Implementation &asImp_()
598 { return *static_cast<Implementation *>(this); }
599
601 const Implementation &asImp_() const
602 { return *static_cast<const Implementation *>(this); }
603
604private:
608 void applyInitialSolutionImpl_(SolutionVector& sol, /*isBox=*/std::true_type) const
609 {
610 const auto numDofs = gridGeometry_->vertexMapper().size();
611 const auto numVert = gridGeometry_->gridView().size(dim);
612 sol.resize(numDofs);
613
614 // if there are more dofs than vertices (enriched nodal dofs), we have to
615 // call initial for all dofs at the nodes, coming from all neighboring elements.
616 if (numDofs != numVert)
617 {
618 std::vector<bool> dofVisited(numDofs, false);
619 for (const auto& element : elements(gridGeometry_->gridView()))
620 {
621 for (int i = 0; i < element.subEntities(dim); ++i)
622 {
623 const auto dofIdxGlobal = gridGeometry_->vertexMapper().subIndex(element, i, dim);
624
625 // forward to implementation if value at dof is not set yet
626 if (!dofVisited[dofIdxGlobal])
627 {
628 sol[dofIdxGlobal] = asImp_().initial(element.template subEntity<dim>(i));
629 dofVisited[dofIdxGlobal] = true;
630 }
631 }
632 }
633 }
634
635 // otherwise we directly loop over the vertices
636 else
637 {
638 for (const auto& vertex : vertices(gridGeometry_->gridView()))
639 {
640 const auto dofIdxGlobal = gridGeometry_->vertexMapper().index(vertex);
641 sol[dofIdxGlobal] = asImp_().initial(vertex);
642 }
643 }
644 }
645
649 void applyInitialSolutionImpl_(SolutionVector& sol, /*isBox=*/std::false_type) const
650 {
651 sol.resize(gridGeometry_->numDofs());
652 for (const auto& element : elements(gridGeometry_->gridView()))
653 {
654 const auto dofIdxGlobal = gridGeometry_->elementMapper().index(element);
655 sol[dofIdxGlobal] = asImp_().initial(element);
656 }
657 }
658
660 std::shared_ptr<const GridGeometry> gridGeometry_;
661
663 std::string paramGroup_;
664
666 std::string problemName_;
667
669 PointSourceMap pointSourceMap_;
670};
671
672} // end namespace Dumux
673
674#endif
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
The available discretization methods in Dumux.
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:149
Base class for all finite-volume problems.
Definition: common/fvproblem.hh:50
void computePointSourceMap()
Compute the point source map, i.e. which scvs have point source contributions.
Definition: common/fvproblem.hh:483
const std::string & name() const
The problem name.
Definition: common/fvproblem.hh:113
NumEqVector scvPointSources(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolume &scv) const
Adds contribution of point sources for a specific sub control volume to the values....
Definition: common/fvproblem.hh:435
const std::string & paramGroup() const
The parameter group in which to retrieve runtime parameters.
Definition: common/fvproblem.hh:592
NumEqVector neumannAtPos(const GlobalPosition &globalPos) const
Evaluate the boundary conditions for a neumann boundary segment.
Definition: common/fvproblem.hh:302
void setName(const std::string &newName)
Set the problem name.
Definition: common/fvproblem.hh:127
PrimaryVariables initial(const Entity &entity) const
Evaluate the initial value for an element (for cell-centered models) or vertex (for box / vertex-cent...
Definition: common/fvproblem.hh:526
NumEqVector sourceAtPos(const GlobalPosition &globalPos) const
Evaluate the source term for all phases within a given sub-control-volume.
Definition: common/fvproblem.hh:349
const Implementation & asImp_() const
Returns the implementation of the problem (i.e. static polymorphism)
Definition: common/fvproblem.hh:601
PrimaryVariables dirichlet(const Element &element, const SubControlVolume &scv) const
Evaluate the boundary conditions for a dirichlet control volume.
Definition: common/fvproblem.hh:219
Scalar extrusionFactor(const Element &element, const SubControlVolume &scv, const ElementSolution &elemSol) const
Return how much the domain is extruded at a given sub-control volume.
Definition: common/fvproblem.hh:556
FVProblem(std::shared_ptr< const GridGeometry > gridGeometry, const std::string &paramGroup="")
Constructor.
Definition: common/fvproblem.hh:98
void applyInitialSolution(SolutionVector &sol) const
Applies the initial solution for all degrees of freedom of the grid.
Definition: common/fvproblem.hh:512
void addPointSources(std::vector< PointSource > &pointSources) const
Applies a vector of point sources. The point sources are possibly solution dependent.
Definition: common/fvproblem.hh:369
PrimaryVariables dirichlet(const Element &element, const SubControlVolumeFace &scvf) const
Evaluate the boundary conditions for a dirichlet control volume face.
Definition: common/fvproblem.hh:198
NumEqVector source(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolume &scv) const
Evaluate the source term for all phases within a given sub-control-volume.
Definition: common/fvproblem.hh:327
void addSourceDerivatives(MatrixBlock &block, const Element &element, const FVElementGeometry &fvGeometry, const VolumeVariables &volVars, const SubControlVolume &scv) const
Add source term derivative to the Jacobian.
Definition: common/fvproblem.hh:423
BoundaryTypes boundaryTypes(const Element &element, const SubControlVolumeFace &scvf) const
Specifies which kind of boundary condition should be used for which equation on a given boundary segm...
Definition: common/fvproblem.hh:162
const PointSourceMap & pointSourceMap() const
Get the point source map. It stores the point sources per scv.
Definition: common/fvproblem.hh:505
const GridGeometry & gridGeometry() const
The finite volume grid geometry.
Definition: common/fvproblem.hh:588
Implementation & asImp_()
Returns the implementation of the problem (i.e. static polymorphism)
Definition: common/fvproblem.hh:597
PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const
Evaluate the boundary conditions for a dirichlet control volume.
Definition: common/fvproblem.hh:238
BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
Specifies which kind of boundary condition should be used for which equation on a given boundary segm...
Definition: common/fvproblem.hh:179
void pointSourceAtPos(PointSource &pointSource, const GlobalPosition &globalPos) const
Evaluate the point sources (added by addPointSources) for all phases within a given sub-control-volum...
Definition: common/fvproblem.hh:415
void pointSource(PointSource &source, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolume &scv) const
Evaluate the point sources (added by addPointSources) for all phases within a given sub-control-volum...
Definition: common/fvproblem.hh:390
NumEqVector neumann(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
Evaluate the boundary conditions for a neumann boundary segment.
Definition: common/fvproblem.hh:283
const GridGeometry & fvGridGeometry() const
The finite volume grid geometry.
Definition: common/fvproblem.hh:584
PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
Evaluate the initial value for a control volume.
Definition: common/fvproblem.hh:537
static constexpr bool enableInternalDirichletConstraints()
If internal Dirichlet contraints are enabled Enables / disables internal (non-boundary) Dirichlet con...
Definition: common/fvproblem.hh:264
Scalar extrusionFactorAtPos(const GlobalPosition &globalPos) const
Return how much the domain is extruded at a given position.
Definition: common/fvproblem.hh:573
BoundaryTypes boundaryTypes(const Element &element, const SubControlVolume &scv) const
Specifies which kind of boundary condition should be used for which equation on a given boundary segm...
Definition: common/fvproblem.hh:144
export traits of this problem
Definition: common/fvproblem.hh:86
FVProblem::PrimaryVariables PrimaryVariables
Definition: common/fvproblem.hh:88
FVProblem::BoundaryTypes BoundaryTypes
Definition: common/fvproblem.hh:90
FVProblem::Scalar Scalar
Definition: common/fvproblem.hh:87
FVProblem::NumEqVector NumEqVector
Definition: common/fvproblem.hh:89
Declares all properties used in Dumux.