3.2-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 // Add the contributions to the dof source values
446 // We divide by the volume. In the local residual this will be multiplied with the same
447 // factor again. That's because the user specifies absolute values in kg/s.
448 const auto volume = scv.volume()*elemVolVars[scv].extrusionFactor();
449
450 for (const auto& ps : pointSourceMap_.at(key))
451 {
452 // we make a copy of the local point source here
453 auto pointSource = ps;
454
455 // Note: two concepts are implemented here. The PointSource property can be set to a
456 // customized point source function achieving variable point sources,
457 // see TimeDependentPointSource for an example. The second imitated the standard
458 // dumux source interface with solDependentPointSource / pointSourceAtPos, methods
459 // that can be overloaded in the actual problem class also achieving variable point sources.
460 // The first one is more convenient for simple function like a time dependent source.
461 // The second one might be more convenient for e.g. a solution dependent point source.
462
463 // we do an update e.g. used for TimeDependentPointSource
464 pointSource.update(asImp_(), element, fvGeometry, elemVolVars, scv);
465 // call convienience problem interface function
466 asImp_().pointSource(pointSource, element, fvGeometry, elemVolVars, scv);
467 // at last take care about multiplying with the correct volume
468 pointSource /= volume*pointSource.embeddings();
469 // add the point source values to the local residual
470 source += pointSource.values();
471 }
472 }
473
474 return source;
475 }
476
483 {
484 // clear the given point source maps in case it's not empty
485 pointSourceMap_.clear();
486
487 // get and apply point sources if any given in the problem
488 std::vector<PointSource> sources;
489 asImp_().addPointSources(sources);
490
491 // if there are point sources compute the DOF to point source map
492 if (!sources.empty())
493 {
494 // calculate point source locations and save them in a map
495 PointSourceHelper::computePointSourceMap(*gridGeometry_,
496 sources,
497 pointSourceMap_);
498 }
499 }
500
504 const PointSourceMap& pointSourceMap() const
505 { return pointSourceMap_; }
506
511 void applyInitialSolution(SolutionVector& sol) const
512 {
513 // set the initial values by forwarding to a specialized method
514 applyInitialSolutionImpl_(sol, std::integral_constant<bool, isBox>());
515 }
516
524 template<class Entity>
525 PrimaryVariables initial(const Entity& entity) const
526 {
527 static_assert(int(Entity::codimension) == 0 || int(Entity::codimension) == dim, "Entity must be element or vertex");
528 return asImp_().initialAtPos(entity.geometry().center());
529 }
530
536 PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
537 {
538 // Throw an exception (there is no reasonable default value
539 // for initial values)
540 DUNE_THROW(Dune::InvalidStateException,
541 "The problem does not provide "
542 "an initial() or an initialAtPos() method.");
543 }
544
554 template<class ElementSolution>
555 Scalar extrusionFactor(const Element& element,
556 const SubControlVolume& scv,
557 const ElementSolution& elemSol) const
558 {
559 // forward to generic interface
560 return asImp_().extrusionFactorAtPos(scv.center());
561 }
562
572 Scalar extrusionFactorAtPos(const GlobalPosition &globalPos) const
573 {
574 // As a default, i.e. if the user's problem does not overload
575 // any extrusion factor method, return 1.0
576 return 1.0;
577 }
578
579 // \}
580
582 const GridGeometry& gridGeometry() const
583 { return *gridGeometry_; }
584
586 const std::string& paramGroup() const
587 { return paramGroup_; }
588
589protected:
591 Implementation &asImp_()
592 { return *static_cast<Implementation *>(this); }
593
595 const Implementation &asImp_() const
596 { return *static_cast<const Implementation *>(this); }
597
598private:
602 void applyInitialSolutionImpl_(SolutionVector& sol, /*isBox=*/std::true_type) const
603 {
604 const auto numDofs = gridGeometry_->vertexMapper().size();
605 const auto numVert = gridGeometry_->gridView().size(dim);
606 sol.resize(numDofs);
607
608 // if there are more dofs than vertices (enriched nodal dofs), we have to
609 // call initial for all dofs at the nodes, coming from all neighboring elements.
610 if (numDofs != numVert)
611 {
612 std::vector<bool> dofVisited(numDofs, false);
613 for (const auto& element : elements(gridGeometry_->gridView()))
614 {
615 for (int i = 0; i < element.subEntities(dim); ++i)
616 {
617 const auto dofIdxGlobal = gridGeometry_->vertexMapper().subIndex(element, i, dim);
618
619 // forward to implementation if value at dof is not set yet
620 if (!dofVisited[dofIdxGlobal])
621 {
622 sol[dofIdxGlobal] = asImp_().initial(element.template subEntity<dim>(i));
623 dofVisited[dofIdxGlobal] = true;
624 }
625 }
626 }
627 }
628
629 // otherwise we directly loop over the vertices
630 else
631 {
632 for (const auto& vertex : vertices(gridGeometry_->gridView()))
633 {
634 const auto dofIdxGlobal = gridGeometry_->vertexMapper().index(vertex);
635 sol[dofIdxGlobal] = asImp_().initial(vertex);
636 }
637 }
638 }
639
643 void applyInitialSolutionImpl_(SolutionVector& sol, /*isBox=*/std::false_type) const
644 {
645 sol.resize(gridGeometry_->numDofs());
646 for (const auto& element : elements(gridGeometry_->gridView()))
647 {
648 const auto dofIdxGlobal = gridGeometry_->elementMapper().index(element);
649 sol[dofIdxGlobal] = asImp_().initial(element);
650 }
651 }
652
654 std::shared_ptr<const GridGeometry> gridGeometry_;
655
657 std::string paramGroup_;
658
660 std::string problemName_;
661
663 PointSourceMap pointSourceMap_;
664};
665
666} // end namespace Dumux
667
668#endif
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
The available discretization methods in Dumux.
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:482
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:586
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:525
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:595
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:555
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:511
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:504
const GridGeometry & gridGeometry() const
The finite volume grid geometry.
Definition: common/fvproblem.hh:582
Implementation & asImp_()
Returns the implementation of the problem (i.e. static polymorphism)
Definition: common/fvproblem.hh:591
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
PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
Evaluate the initial value for a control volume.
Definition: common/fvproblem.hh:536
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:572
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.