version 3.10-dev
python/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// 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_PYTHON_COMMON_FVPROBLEM_HH
13#define DUMUX_PYTHON_COMMON_FVPROBLEM_HH
14
15#include <string>
16#include <memory>
17#include <tuple>
18
19#include <dune/common/fvector.hh>
20#include <dune/common/exceptions.hh>
21#include <dune/python/pybind11/pybind11.h>
22
28
29namespace Dumux::Python {
30
35template<class GridGeometry_, class SpatialParams_, class PrimaryVariables, bool enableInternalDirichletConstraints_>
37{
38public:
39 using GridGeometry = GridGeometry_;
40 using SpatialParams = SpatialParams_;
41 using Scalar = typename GridGeometry::GridView::ctype;
42 using NumEqVector = Dune::FieldVector<Scalar, PrimaryVariables::dimension>;
43 using Element = typename GridGeometry::GridView::template Codim<0>::Entity;
44 using FVElementGeometry = typename GridGeometry::LocalView;
45 using SubControlVolume = typename GridGeometry::SubControlVolume;
46 using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace;
47 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
48
49 static constexpr bool isBox = GridGeometry::discMethod == DiscretizationMethods::box;
50 static constexpr std::size_t numEq = static_cast<std::size_t>(PrimaryVariables::dimension);
52
54 using PointSourceMap = std::map< std::pair<std::size_t, std::size_t>,
55 std::vector<PointSource> >;
56
57 FVProblem(std::shared_ptr<const GridGeometry> gridGeometry,
58 std::shared_ptr<const SpatialParams> spatialParams,
59 pybind11::object pyProblem)
60 : gridGeometry_(gridGeometry)
61 , pyProblem_(pyProblem)
62 , name_("python_problem")
63 , paramGroup_("")
64 , spatialParams_(spatialParams)
65 , pointSourceMap_()
66 {
67 if (pybind11::hasattr(pyProblem_, "name"))
68 name_ = pyProblem.attr("name")().template cast<std::string>();
69
70 if (pybind11::hasattr(pyProblem_, "paramGroup"))
71 paramGroup_ = pyProblem.attr("paramGroup")().template cast<std::string>();
72 }
73
74 FVProblem(std::shared_ptr<const GridGeometry> gridGeometry,
75 pybind11::object pyProblem)
76 : FVProblem(gridGeometry, std::make_shared<SpatialParams>(gridGeometry), pyProblem)
77 {}
78
79 const std::string& name() const
80 { return name_; }
81
82 const std::string& paramGroup() const
83 { return paramGroup_; }
84
86 const SubControlVolume &scv) const
87 {
88 if constexpr (!isBox)
89 DUNE_THROW(Dune::InvalidStateException, "boundaryTypes(..., scv) called for cell-centered method.");
90 else
91 {
92 if (pybind11::hasattr(pyProblem_, "boundaryTypes"))
93 return pyProblem_.attr("boundaryTypes")(element, scv).template cast<BoundaryTypes>();
94 else
95 return pyProblem_.attr("boundaryTypesAtPos")(scv.dofPosition()).template cast<BoundaryTypes>();
96 }
97 }
98
100 const SubControlVolumeFace &scvf) const
101 {
102 if constexpr (isBox)
103 DUNE_THROW(Dune::InvalidStateException, "boundaryTypes(..., scvf) called for box method.");
104 else
105 {
106 if (pybind11::hasattr(pyProblem_, "boundaryTypes"))
107 return pyProblem_.attr("boundaryTypes")(element, scvf).template cast<BoundaryTypes>();
108 else
109 return pyProblem_.attr("boundaryTypesAtPos")(scvf.ipGlobal()).template cast<BoundaryTypes>();
110 }
111 }
112
113 PrimaryVariables dirichlet(const Element &element,
114 const SubControlVolume &scv) const
115 {
116 if constexpr (!isBox)
117 DUNE_THROW(Dune::InvalidStateException, "dirichlet(scv) called for cell-centered method.");
118 else
119 {
120 if (pybind11::hasattr(pyProblem_, "dirichlet"))
121 return pyProblem_.attr("dirichlet")(element, scv).template cast<PrimaryVariables>();
122 else
123 return pyProblem_.attr("dirichletAtPos")(scv.dofPosition()).template cast<PrimaryVariables>();
124 }
125 }
126
127 PrimaryVariables dirichlet(const Element &element,
128 const SubControlVolumeFace &scvf) const
129 {
130 if constexpr (isBox)
131 DUNE_THROW(Dune::InvalidStateException, "dirichlet(scvf) called for box method.");
132 else
133 {
134 if (pybind11::hasattr(pyProblem_, "dirichlet"))
135 return pyProblem_.attr("dirichlet")(element, scvf).template cast<PrimaryVariables>();
136 else
137 return pyProblem_.attr("dirichletAtPos")(scvf.ipGlobal()).template cast<PrimaryVariables>();
138 }
139 }
140
141 template<class ElementVolumeVariables, class ElementFluxVariablesCache>
143 const FVElementGeometry& fvGeometry,
144 const ElementVolumeVariables& elemVolVars,
145 const ElementFluxVariablesCache& elemFluxVarsCache,
146 const SubControlVolumeFace& scvf) const
147 {
148 if (pybind11::hasattr(pyProblem_, "neumann"))
149 return pyProblem_.attr("neumann")(element, fvGeometry, scvf).template cast<NumEqVector>();
150 else
151 return pyProblem_.attr("neumannAtPos")(scvf.ipGlobal()).template cast<NumEqVector>();
152 }
153
154 template<class ElementVolumeVariables>
155 NumEqVector source(const Element &element,
156 const FVElementGeometry& fvGeometry,
157 const ElementVolumeVariables& elemVolVars,
158 const SubControlVolume &scv) const
159 {
160 if (pybind11::hasattr(pyProblem_, "source"))
161 return pyProblem_.attr("source")(element, fvGeometry, scv).template cast<NumEqVector>();
162 else
163 return pyProblem_.attr("sourceAtPos")(scv.dofPosition()).template cast<NumEqVector>();
164 }
165
166 NumEqVector sourceAtPos(const GlobalPosition &globalPos) const
167 {
168 return pyProblem_.attr("sourceAtPos")(globalPos).template cast<NumEqVector>();
169 }
170
171 template<class ElementVolumeVariables>
173 const FVElementGeometry& fvGeometry,
174 const ElementVolumeVariables& elemVolVars,
175 const SubControlVolume& scv) const
176 {
177 if (pybind11::hasattr(pyProblem_, "scvPointSources"))
178 return pyProblem_.attr("scvPointSources")(element, fvGeometry, scv).template cast<NumEqVector>();
179 else
180 return NumEqVector(0.0);
181 }
182
184 {
185 return pointSourceMap_;
186 }
187
188 template<class Entity>
189 PrimaryVariables initial(const Entity& entity) const
190 {
191 return pyProblem_.attr("initial")(entity).template cast<PrimaryVariables>();
192 }
193
195 { return enableInternalDirichletConstraints_; }
196
201 template<class MatrixBlock, class VolumeVariables>
202 void addSourceDerivatives(MatrixBlock& block,
203 const Element& element,
204 const FVElementGeometry& fvGeometry,
205 const VolumeVariables& volVars,
206 const SubControlVolume& scv) const
207 {
208 if (pybind11::hasattr(pyProblem_, "addSourceDerivatives"))
209 pyProblem_.attr("addSourceDerivatives")(block, element, fvGeometry, scv);
210 }
211
213 { return *gridGeometry_; }
214
217 { return *spatialParams_; }
218
219private:
220 std::shared_ptr<const GridGeometry> gridGeometry_;
221 pybind11::object pyProblem_;
222 std::string name_;
223 std::string paramGroup_;
224 std::shared_ptr<const SpatialParams> spatialParams_;
225 PointSourceMap pointSourceMap_;
226};
227
228// Python wrapper for the above FVProblem C++ class
229template<class Problem, class... options>
230void registerFVProblem(pybind11::handle scope, pybind11::class_<Problem, options...> cls)
231{
232 using pybind11::operator""_a;
233 using namespace Dune::Python;
234
235 using GridGeometry = typename Problem::GridGeometry;
236 using SpatialParams = typename Problem::SpatialParams;
237 cls.def(pybind11::init([](std::shared_ptr<const GridGeometry> gridGeometry,
238 std::shared_ptr<const SpatialParams> spatialParams,
239 pybind11::object p){
240 return std::make_shared<Problem>(gridGeometry, spatialParams, p);
241 }));
242 cls.def(pybind11::init([](std::shared_ptr<const GridGeometry> gridGeometry,
243 pybind11::object p){
244 return std::make_shared<Problem>(gridGeometry, p);
245 }));
246
247 cls.def_property_readonly("name", &Problem::name);
248 cls.def_property_readonly("numEq", [](Problem&){ return Problem::numEq; });
249 cls.def_property_readonly("gridGeometry", &Problem::gridGeometry);
250
251 using GridView = typename GridGeometry::GridView;
252 using Element = typename GridView::template Codim<0>::Entity;
253 using Vertex = typename GridView::template Codim<GridView::dimension>::Entity;
254
255 if constexpr (Problem::isBox)
256 {
257 using SCV = typename Problem::SubControlVolume;
258 cls.def("boundaryTypes", pybind11::overload_cast<const Element&, const SCV&>(&Problem::boundaryTypes, pybind11::const_), "element"_a, "scv"_a);
259 cls.def("dirichlet", pybind11::overload_cast<const Element&, const SCV&>(&Problem::dirichlet, pybind11::const_), "element"_a, "scv"_a);
260 }
261 else
262 {
263 using SCVF = typename Problem::SubControlVolumeFace;
264 cls.def("boundaryTypes", pybind11::overload_cast<const Element&, const SCVF&>(&Problem::boundaryTypes, pybind11::const_), "element"_a, "scvf"_a);
265 cls.def("dirichlet", pybind11::overload_cast<const Element&, const SCVF&>(&Problem::dirichlet, pybind11::const_), "element"_a, "scvf"_a);
266 }
267
268 cls.def("neumann", &Problem::template neumann<decltype(std::ignore), decltype(std::ignore)>);
269 cls.def("source", &Problem::template source<decltype(std::ignore)>);
270 cls.def("sourceAtPos", &Problem::sourceAtPos);
271 cls.def("initial", &Problem::template initial<Element>);
272 cls.def("initial", &Problem::template initial<Vertex>);
273}
274
275} // end namespace Dumux::Python
276
277#endif
Class to specify the type of a boundary.
Definition: common/boundarytypes.hh:26
A point source base class.
Definition: pointsource.hh:39
A C++ wrapper for a Python problem.
Definition: python/common/fvproblem.hh:37
NumEqVector source(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolume &scv) const
Definition: python/common/fvproblem.hh:155
static constexpr bool enableInternalDirichletConstraints()
Definition: python/common/fvproblem.hh:194
const SpatialParams & spatialParams() const
Return a reference to the underlying spatial parameters.
Definition: python/common/fvproblem.hh:216
typename GridGeometry::GridView::ctype Scalar
Definition: python/common/fvproblem.hh:41
BoundaryTypes boundaryTypes(const Element &element, const SubControlVolume &scv) const
Definition: python/common/fvproblem.hh:85
PrimaryVariables dirichlet(const Element &element, const SubControlVolume &scv) const
Definition: python/common/fvproblem.hh:113
typename GridGeometry::SubControlVolume SubControlVolume
Definition: python/common/fvproblem.hh:45
FVProblem(std::shared_ptr< const GridGeometry > gridGeometry, pybind11::object pyProblem)
Definition: python/common/fvproblem.hh:74
FVProblem(std::shared_ptr< const GridGeometry > gridGeometry, std::shared_ptr< const SpatialParams > spatialParams, pybind11::object pyProblem)
Definition: python/common/fvproblem.hh:57
static constexpr std::size_t numEq
Definition: python/common/fvproblem.hh:50
const std::string & name() const
Definition: python/common/fvproblem.hh:79
const GridGeometry & gridGeometry() const
Definition: python/common/fvproblem.hh:212
typename Element::Geometry::GlobalCoordinate GlobalPosition
Definition: python/common/fvproblem.hh:47
const std::string & paramGroup() const
Definition: python/common/fvproblem.hh:82
PrimaryVariables dirichlet(const Element &element, const SubControlVolumeFace &scvf) const
Definition: python/common/fvproblem.hh:127
std::map< std::pair< std::size_t, std::size_t >, std::vector< PointSource > > PointSourceMap
Definition: python/common/fvproblem.hh:55
typename GridGeometry::SubControlVolumeFace SubControlVolumeFace
Definition: python/common/fvproblem.hh:46
NumEqVector scvPointSources(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolume &scv) const
Definition: python/common/fvproblem.hh:172
NumEqVector sourceAtPos(const GlobalPosition &globalPos) const
Definition: python/common/fvproblem.hh:166
NumEqVector neumann(const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const SubControlVolumeFace &scvf) const
Definition: python/common/fvproblem.hh:142
Dune::FieldVector< Scalar, PrimaryVariables::dimension > NumEqVector
Definition: python/common/fvproblem.hh:42
const PointSourceMap & pointSourceMap() const
Definition: python/common/fvproblem.hh:183
typename GridGeometry::GridView::template Codim< 0 >::Entity Element
Definition: python/common/fvproblem.hh:43
static constexpr bool isBox
Definition: python/common/fvproblem.hh:49
BoundaryTypes boundaryTypes(const Element &element, const SubControlVolumeFace &scvf) const
Definition: python/common/fvproblem.hh:99
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: python/common/fvproblem.hh:202
GridGeometry_ GridGeometry
Definition: python/common/fvproblem.hh:39
SpatialParams_ SpatialParams
Definition: python/common/fvproblem.hh:40
typename GridGeometry::LocalView FVElementGeometry
Definition: python/common/fvproblem.hh:44
PrimaryVariables initial(const Entity &entity) const
Definition: python/common/fvproblem.hh:189
Class to specify the type of a boundary.
The available discretization methods in Dumux.
constexpr Box box
Definition: method.hh:147
Definition: python/assembly/fvassembler.hh:18
void registerFVProblem(pybind11::handle scope, pybind11::class_< Problem, options... > cls)
Definition: python/common/fvproblem.hh:230
A point source class, i.e. sources located at a single point in space.
TODO: docme!
Basic spatial parameters to be used with finite-volume schemes.