Skip to content
Snippets Groups Projects
Commit 11aa7bef authored by Yue Wang's avatar Yue Wang
Browse files

Merge branch 'cherry-pick-790bdaee' into 'releases/3.5'

Merge branch 'feature/spatialparams_python' into 'master'

See merge request !3091
parents a795ca64 f97a945f
No related branches found
No related tags found
2 merge requests!3298Draft: Merge branch 'fix/deprecated-attribute' into 'master',!3091Merge branch 'feature/spatialparams_python' into 'master'
Pipeline #16000 failed
+2
Showing
with 478 additions and 211 deletions
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <dumux/common/boundarytypes.hh> #include <dumux/common/boundarytypes.hh>
#include <dumux/discretization/method.hh> #include <dumux/discretization/method.hh>
#include <dumux/python/common/boundarytypes.hh> #include <dumux/python/common/boundarytypes.hh>
#include <dumux/python/common/fvspatialparams.hh>
namespace Dumux::Python { namespace Dumux::Python {
...@@ -42,12 +43,13 @@ namespace Dumux::Python { ...@@ -42,12 +43,13 @@ namespace Dumux::Python {
* \ingroup Common * \ingroup Common
* \brief A C++ wrapper for a Python problem * \brief A C++ wrapper for a Python problem
*/ */
template<class GridGeometry_, class PrimaryVariables, bool enableInternalDirichletConstraints_> template<class GridGeometry_, class SpatialParams_, class PrimaryVariables, bool enableInternalDirichletConstraints_>
class FVProblem class FVProblem
{ {
public: public:
using GridGeometry = GridGeometry_; using GridGeometry = GridGeometry_;
using Scalar = typename PrimaryVariables::value_type; using SpatialParams = SpatialParams_;
using Scalar = typename GridGeometry::GridView::ctype;
using NumEqVector = Dune::FieldVector<Scalar, PrimaryVariables::dimension>; using NumEqVector = Dune::FieldVector<Scalar, PrimaryVariables::dimension>;
using Element = typename GridGeometry::GridView::template Codim<0>::Entity; using Element = typename GridGeometry::GridView::template Codim<0>::Entity;
using FVElementGeometry = typename GridGeometry::LocalView; using FVElementGeometry = typename GridGeometry::LocalView;
...@@ -60,11 +62,13 @@ public: ...@@ -60,11 +62,13 @@ public:
using BoundaryTypes = Dumux::BoundaryTypes<PrimaryVariables::dimension>; using BoundaryTypes = Dumux::BoundaryTypes<PrimaryVariables::dimension>;
FVProblem(std::shared_ptr<const GridGeometry> gridGeometry, FVProblem(std::shared_ptr<const GridGeometry> gridGeometry,
std::shared_ptr<const SpatialParams> spatialParams,
pybind11::object pyProblem) pybind11::object pyProblem)
: gridGeometry_(gridGeometry) : gridGeometry_(gridGeometry)
, pyProblem_(pyProblem) , pyProblem_(pyProblem)
, name_("python_problem") , name_("python_problem")
, paramGroup_("") , paramGroup_("")
, spatialParams_(spatialParams)
{ {
if (pybind11::hasattr(pyProblem_, "name")) if (pybind11::hasattr(pyProblem_, "name"))
name_ = pyProblem.attr("name")().template cast<std::string>(); name_ = pyProblem.attr("name")().template cast<std::string>();
...@@ -73,6 +77,11 @@ public: ...@@ -73,6 +77,11 @@ public:
paramGroup_ = pyProblem.attr("paramGroup")().template cast<std::string>(); paramGroup_ = pyProblem.attr("paramGroup")().template cast<std::string>();
} }
FVProblem(std::shared_ptr<const GridGeometry> gridGeometry,
pybind11::object pyProblem)
: FVProblem(gridGeometry, std::make_shared<SpatialParams>(gridGeometry), pyProblem)
{}
const std::string& name() const const std::string& name() const
{ return name_; } { return name_; }
...@@ -183,19 +192,6 @@ public: ...@@ -183,19 +192,6 @@ public:
return pyProblem_.attr("initial")(entity).template cast<PrimaryVariables>(); return pyProblem_.attr("initial")(entity).template cast<PrimaryVariables>();
} }
template<class ElementSolution>
Scalar extrusionFactor(const Element& element,
const SubControlVolume& scv,
const ElementSolution& elemSol) const
{
return pyProblem_.attr("extrusionFactor")(element, scv).template cast<Scalar>();
}
Scalar temperatureAtPos(const GlobalPosition& globalPos) const
{
return pyProblem_.attr("temperatureAtPos")(globalPos).template cast<Scalar>();
}
static constexpr bool enableInternalDirichletConstraints() static constexpr bool enableInternalDirichletConstraints()
{ return enableInternalDirichletConstraints_; } { return enableInternalDirichletConstraints_; }
...@@ -214,14 +210,39 @@ public: ...@@ -214,14 +210,39 @@ public:
pyProblem_.attr("addSourceDerivatives")(block, element, fvGeometry, scv); pyProblem_.attr("addSourceDerivatives")(block, element, fvGeometry, scv);
} }
[[deprecated("extrusionFactorAtPos() should now be defined in the spatial params. This interface will be removed after 3.5.")]]
Scalar extrusionFactorAtPos(const GlobalPosition &globalPos, double defaultValue = 1.0) const
{ return 1.0; }
template<class ElementSolution>
[[deprecated("extrusionFactor() should now be defined in the spatial params. This interface will be removed after 3.5.")]]
Scalar extrusionFactor(const Element& element,
const SubControlVolume& scv,
const ElementSolution& elemSol,
double defaultValue = 1.0) const
{ return this->extrusionFactorAtPos(scv.center()); }
[[deprecated("temperatureAtPos() should now be defined in the spatial params. This interface will be removed after 3.5.")]]
Scalar temperatureAtPos(const GlobalPosition &globalPos, int defaultValue = 1) const
{ return 293.0; }
[[deprecated("temperature() should now be defined in the spatial params. This interface will be removed after 3.5.")]]
Scalar temperature(int defaultValue = 1) const
{ return this->temperature(GlobalPosition(0.0)); }
const GridGeometry& gridGeometry() const const GridGeometry& gridGeometry() const
{ return *gridGeometry_; } { return *gridGeometry_; }
//! Return a reference to the underlying spatial parameters
const SpatialParams& spatialParams() const
{ return *spatialParams_; }
private: private:
std::shared_ptr<const GridGeometry> gridGeometry_; std::shared_ptr<const GridGeometry> gridGeometry_;
pybind11::object pyProblem_; pybind11::object pyProblem_;
std::string name_; std::string name_;
std::string paramGroup_; std::string paramGroup_;
std::shared_ptr<const SpatialParams> spatialParams_;
}; };
// Python wrapper for the above FVProblem C++ class // Python wrapper for the above FVProblem C++ class
...@@ -232,6 +253,12 @@ void registerFVProblem(pybind11::handle scope, pybind11::class_<Problem, options ...@@ -232,6 +253,12 @@ void registerFVProblem(pybind11::handle scope, pybind11::class_<Problem, options
using namespace Dune::Python; using namespace Dune::Python;
using GridGeometry = typename Problem::GridGeometry; using GridGeometry = typename Problem::GridGeometry;
using SpatialParams = typename Problem::SpatialParams;
cls.def(pybind11::init([](std::shared_ptr<const GridGeometry> gridGeometry,
std::shared_ptr<const SpatialParams> spatialParams,
pybind11::object p){
return std::make_shared<Problem>(gridGeometry, spatialParams, p);
}));
cls.def(pybind11::init([](std::shared_ptr<const GridGeometry> gridGeometry, cls.def(pybind11::init([](std::shared_ptr<const GridGeometry> gridGeometry,
pybind11::object p){ pybind11::object p){
return std::make_shared<Problem>(gridGeometry, p); return std::make_shared<Problem>(gridGeometry, p);
...@@ -263,7 +290,6 @@ void registerFVProblem(pybind11::handle scope, pybind11::class_<Problem, options ...@@ -263,7 +290,6 @@ void registerFVProblem(pybind11::handle scope, pybind11::class_<Problem, options
cls.def("sourceAtPos", &Problem::sourceAtPos); cls.def("sourceAtPos", &Problem::sourceAtPos);
cls.def("initial", &Problem::template initial<Element>); cls.def("initial", &Problem::template initial<Element>);
cls.def("initial", &Problem::template initial<Vertex>); cls.def("initial", &Problem::template initial<Vertex>);
cls.def("extrusionFactor", &Problem::template extrusionFactor<decltype(std::ignore)>);
} }
} // end namespace Dumux::Python } // end namespace Dumux::Python
......
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
/*!
* \file
* \ingroup Common
* \ingroup SpatialParameters
* \brief Basic spatial parameters to be used with finite-volume schemes.
*/
#ifndef DUMUX_PYTHON_COMMON_FVSPATIALPARAMS_HH
#define DUMUX_PYTHON_COMMON_FVSPATIALPARAMS_HH
#include <memory>
#include <dune/common/fvector.hh>
#include <dune/common/exceptions.hh>
#include <dumux/common/parameters.hh>
#include <dune/python/pybind11/pybind11.h>
namespace Dumux::Python {
/*!
* \ingroup Common
* \ingroup SpatialParameters
* \brief The base class for spatial parameters used with finite-volume schemes.
*/
template<class GridGeometry_>
class FVSpatialParams
{
public:
using GridGeometry = GridGeometry_;
using GridView = typename GridGeometry::GridView;
using Scalar = typename GridView::ctype;
using Element = typename GridView::template Codim<0>::Entity;
using SubControlVolume = typename GridGeometry::SubControlVolume;
static constexpr bool isBox = GridGeometry::discMethod == DiscretizationMethods::box;
static constexpr int dimWorld = GridView::dimensionworld;
using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
using GravityVector = Dune::FieldVector<Scalar, dimWorld>;
FVSpatialParams(std::shared_ptr<const GridGeometry> gridGeometry,
pybind11::object pySpatialParameters)
: gridGeometry_(gridGeometry)
, pySpatialParameters_(pySpatialParameters)
, gravity_(0.0)
{
if (getParam<bool>("Problem.EnableGravity"))
gravity_[dimWorld-1] = -9.81;
}
FVSpatialParams(std::shared_ptr<const GridGeometry> gridGeometry)
: gridGeometry_(gridGeometry)
, pySpatialParameters_{}
, gravity_(0.0)
{
if (getParam<bool>("Problem.EnableGravity"))
gravity_[dimWorld-1] = -9.81;
}
/*!
* \brief Return how much the domain is extruded at a given sub-control volume.
*
* This means the factor by which a lower-dimensional (1D or 2D)
* entity needs to be expanded to get a full dimensional cell. The
* default is 1.0 which means that 1D problems are actually
* thought as pipes with a cross section of 1 m^2 and 2D problems
* are assumed to extend 1 m to the back.
*/
template<class ElementSolution>
Scalar extrusionFactor(const Element& element,
const SubControlVolume& scv,
const ElementSolution& elemSol) const
{
if (pySpatialParameters_)
{
if (pybind11::hasattr(pySpatialParameters_, "extrusionFactor"))
return pySpatialParameters_.attr("extrusionFactor")(element, scv, elemSol).template cast<Scalar>();
else if (pybind11::hasattr(pySpatialParameters_, "extrusionFactorAtPos"))
return pySpatialParameters_.attr("extrusionFactorAtPos")(scv.dofPosition()).template cast<Scalar>();
}
// default
return 1.0;
}
/*!
* \brief Return the temperature in the given sub-control volume.
*/
template<class ElementSolution>
Scalar temperature(const Element& element,
const SubControlVolume& scv,
const ElementSolution& elemSol) const
{
if (pySpatialParameters_)
{
if (pybind11::hasattr(pySpatialParameters_, "temperature"))
return pySpatialParameters_.attr("temperature")(element, scv, elemSol).template cast<Scalar>();
else if (pybind11::hasattr(pySpatialParameters_, "temperatureAtPos"))
return pySpatialParameters_.attr("temperatureAtPos")(scv.dofPosition()).template cast<Scalar>();
}
// default
return 283.15;
}
/*!
* \brief Returns the acceleration due to gravity \f$\mathrm{[m/s^2]}\f$.
*
* The default behaviour is a constant gravity vector;
* if the <tt>Problem.EnableGravity</tt> parameter is true,
* \f$\boldsymbol{g} = ( 0,\dots,\ -9.81)^T \f$,
* else \f$\boldsymbol{g} = ( 0,\dots, 0)^T \f$.
*
* \param pos the spatial position at which to evaulate the gravity vector
*/
const GravityVector& gravity(const GlobalPosition& pos) const
{ return gravity_; }
//! The finite volume grid geometry
const GridGeometry& gridGeometry() const
{ return *gridGeometry_; }
private:
std::shared_ptr<const GridGeometry> gridGeometry_;
pybind11::object pySpatialParameters_;
GravityVector gravity_;
};
// Python wrapper for the above FVProblem C++ class
template<class SpatialParams, class... options>
void registerFVSpatialParams(pybind11::handle scope, pybind11::class_<SpatialParams, options...> cls)
{
using pybind11::operator""_a;
using GridGeometry = typename SpatialParams::GridGeometry;
cls.def(pybind11::init([](std::shared_ptr<const GridGeometry> gridGeometry, pybind11::object p){
return std::make_shared<SpatialParams>(gridGeometry, p);
}));
cls.def("extrusionFactor", &SpatialParams::template extrusionFactor<decltype(std::ignore)>);
cls.def("temperature", &SpatialParams::template temperature<decltype(std::ignore)>);
cls.def("gravity", &SpatialParams::gravity);
cls.def_property_readonly("gridGeometry", &SpatialParams::gridGeometry);
}
} // namespace Dumux::Python
#endif
add_subdirectory(components) add_subdirectory(components)
add_subdirectory(fluidsystems) add_subdirectory(fluidsystems)
add_subdirectory(spatialparams)
file(GLOB DUMUX_PYTHON_MATERIAL_SPATIALPARAMS_HEADERS *.hh *.inc)
install(FILES ${DUMUX_PYTHON_MATERIAL_SPATIALPARAMS_HEADERS}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/python/material/spatialparams)
...@@ -35,11 +35,11 @@ namespace Dumux::Python { ...@@ -35,11 +35,11 @@ namespace Dumux::Python {
* \ingroup PorousmediumflowModels * \ingroup PorousmediumflowModels
* \brief A C++ wrapper for a Python PorousMediumFlow problem * \brief A C++ wrapper for a Python PorousMediumFlow problem
*/ */
template<class GridGeometry_, class PrimaryVariables, class SpatialParams_, template<class GridGeometry_, class SpatialParams_, class PrimaryVariables, bool enableInternalDirichletConstraints>
bool enableInternalDirichletConstraints> class PorousMediumFlowProblem
class PorousMediumFlowProblem : public FVProblem<GridGeometry_, PrimaryVariables, enableInternalDirichletConstraints> : public Dumux::Python::FVProblem<GridGeometry_, SpatialParams_, PrimaryVariables, enableInternalDirichletConstraints>
{ {
using ParentType = FVProblem<GridGeometry_, PrimaryVariables, enableInternalDirichletConstraints>; using ParentType = Dumux::Python::FVProblem<GridGeometry_, SpatialParams_, PrimaryVariables, enableInternalDirichletConstraints>;
public: public:
using GridGeometry = GridGeometry_; using GridGeometry = GridGeometry_;
using SpatialParams = SpatialParams_; using SpatialParams = SpatialParams_;
...@@ -58,7 +58,7 @@ public: ...@@ -58,7 +58,7 @@ public:
PorousMediumFlowProblem(std::shared_ptr<const GridGeometry> gridGeometry, PorousMediumFlowProblem(std::shared_ptr<const GridGeometry> gridGeometry,
std::shared_ptr<const SpatialParams> spatialParams, std::shared_ptr<const SpatialParams> spatialParams,
pybind11::object pyProblem) pybind11::object pyProblem)
: ParentType(gridGeometry, pyProblem) : ParentType(gridGeometry, spatialParams, pyProblem)
, spatialParams_(spatialParams) , spatialParams_(spatialParams)
{} {}
...@@ -79,7 +79,7 @@ void registerPorousMediumFlowProblem(pybind11::handle scope, pybind11::class_<Pr ...@@ -79,7 +79,7 @@ void registerPorousMediumFlowProblem(pybind11::handle scope, pybind11::class_<Pr
using GridGeometry = typename Problem::GridGeometry; using GridGeometry = typename Problem::GridGeometry;
using SpatialParams = typename Problem::SpatialParams; using SpatialParams = typename Problem::SpatialParams;
cls.def(pybind11::init([](std::shared_ptr<const GridGeometry> gridGeometry, cls.def(pybind11::init([](std::shared_ptr<const GridGeometry> gridGeometry,
std::shared_ptr<const SpatialParams> spatialParams, std::shared_ptr<SpatialParams> spatialParams,
pybind11::object p){ pybind11::object p){
return std::make_shared<Problem>(gridGeometry, spatialParams, p); return std::make_shared<Problem>(gridGeometry, spatialParams, p);
})); }));
...@@ -109,7 +109,6 @@ void registerPorousMediumFlowProblem(pybind11::handle scope, pybind11::class_<Pr ...@@ -109,7 +109,6 @@ void registerPorousMediumFlowProblem(pybind11::handle scope, pybind11::class_<Pr
cls.def("sourceAtPos", &Problem::sourceAtPos); cls.def("sourceAtPos", &Problem::sourceAtPos);
cls.def("initial", &Problem::template initial<Element>); cls.def("initial", &Problem::template initial<Element>);
cls.def("initial", &Problem::template initial<Vertex>); cls.def("initial", &Problem::template initial<Vertex>);
cls.def("extrusionFactor", &Problem::template extrusionFactor<decltype(std::ignore)>);
cls.def("gridGeometry", &Problem::gridGeometry); cls.def("gridGeometry", &Problem::gridGeometry);
cls.def("spatialParams", &Problem::spatialParams); cls.def("spatialParams", &Problem::spatialParams);
} }
......
...@@ -21,33 +21,32 @@ ...@@ -21,33 +21,32 @@
* \brief TODO: docme! * \brief TODO: docme!
*/ */
#ifndef DUMUX_PYTHON_MATERIAL_SPATIAL_PARAMS_HH #ifndef DUMUX_PYTHON_POROUSMEDIUMFLOW_FVSPATIALPARAMS_1P_HH
#define DUMUX_PYTHON_MATERIAL_SPATIAL_PARAMS_HH #define DUMUX_PYTHON_POROUSMEDIUMFLOW_FVSPATIALPARAMS_1P_HH
#include <dune/python/pybind11/pybind11.h> #include <dune/python/pybind11/pybind11.h>
#include <dune/python/pybind11/stl.h> #include <dune/python/pybind11/stl.h>
#include <dumux/material/spatialparams/fv1p.hh> #include <dumux/python/common/fvspatialparams.hh>
namespace Dumux::Python { namespace Dumux::Python {
template<class GridGeometry, class Scalar, class PT> template<class GridGeometry_, class PT>
class FVSpatialParamsOneP class FVSpatialParamsOneP
: public Dumux::FVSpatialParamsOneP<GridGeometry, Scalar, FVSpatialParamsOneP<GridGeometry, Scalar, PT>> : public Dumux::Python::FVSpatialParams<GridGeometry_>
{ {
using ThisType = FVSpatialParamsOneP<GridGeometry, Scalar, PT>; using ThisType = Dumux::Python::FVSpatialParamsOneP<GridGeometry_, PT>;
using ParentType = Dumux::FVSpatialParamsOneP<GridGeometry, Scalar, ThisType>; using ParentType = Dumux::Python::FVSpatialParams<GridGeometry_>;
public:
using GridGeometry = GridGeometry_;
using Scalar = typename GridGeometry::GridView::ctype;
using Element = typename GridGeometry::GridView::template Codim<0>::Entity; using Element = typename GridGeometry::GridView::template Codim<0>::Entity;
using SubControlVolume = typename GridGeometry::SubControlVolume; using SubControlVolume = typename GridGeometry::SubControlVolume;
using GlobalPosition = typename GridGeometry::GridView::template Codim<0>::Geometry::GlobalCoordinate;
public:
using PermeabilityType = PT; using PermeabilityType = PT;
FVSpatialParamsOneP(std::shared_ptr<const GridGeometry> gridGeometry, FVSpatialParamsOneP(std::shared_ptr<const GridGeometry> gridGeometry,
pybind11::object pySpatialParams) pybind11::object pySpatialParams)
: ParentType(gridGeometry) : ParentType(gridGeometry, pySpatialParams)
, pySpatialParams_(pySpatialParams) , pySpatialParams_(pySpatialParams)
{} {}
...@@ -64,8 +63,8 @@ public: ...@@ -64,8 +63,8 @@ public:
template<class ElementSolution> template<class ElementSolution>
Scalar porosity(const Element& element, Scalar porosity(const Element& element,
const SubControlVolume& scv, const SubControlVolume& scv,
const ElementSolution& elemSol) const const ElementSolution& elemSol) const
{ {
if (pybind11::hasattr(pySpatialParams_, "porosity")) if (pybind11::hasattr(pySpatialParams_, "porosity"))
return pySpatialParams_.attr("porosity")(element, scv, elemSol).template cast<Scalar>(); return pySpatialParams_.attr("porosity")(element, scv, elemSol).template cast<Scalar>();
...@@ -73,24 +72,41 @@ public: ...@@ -73,24 +72,41 @@ public:
return pySpatialParams_.attr("porosityAtPos")(scv.center()).template cast<Scalar>(); return pySpatialParams_.attr("porosityAtPos")(scv.center()).template cast<Scalar>();
} }
template<class SolidSystem, class ElementSolution>
Scalar inertVolumeFraction(const Element& element,
const SubControlVolume& scv,
const ElementSolution& elemSol,
int compIdx) const
{
if (pybind11::hasattr(pySpatialParams_, "inertVolumeFraction"))
return pySpatialParams_.attr("inertVolumeFraction")(element, scv, elemSol, compIdx).template cast<Scalar>();
else if (pybind11::hasattr(pySpatialParams_, "inertVolumeFractionAtPos"))
return pySpatialParams_.attr("inertVolumeFractionAtPos")(scv.center(), compIdx).template cast<Scalar>();
else
return 1.0 - this->porosity(element, scv, elemSol);
}
static constexpr bool evaluatePermeabilityAtScvfIP()
{ return false; }
private: private:
pybind11::object pySpatialParams_; pybind11::object pySpatialParams_;
}; };
template <class SpatialParams, class... options>
void registerFVSpatialParamsOneP(pybind11::handle scope, pybind11::class_<SpatialParams, options...> cls)
template <class SP, class... options>
void registerOnePSpatialParams(pybind11::handle scope,
pybind11::class_<SP, options...> cls)
{ {
using pybind11::operator""_a; using pybind11::operator""_a;
using GridGeometry = std::decay_t<decltype(std::declval<SP>().gridGeometry())>; using GridGeometry = typename SpatialParams::GridGeometry;
cls.def(pybind11::init([](std::shared_ptr<GridGeometry> gridGeometry, pybind11::object sp){ cls.def(pybind11::init([](std::shared_ptr<const GridGeometry> gridGeometry, pybind11::object p){
return std::make_shared<SP>(gridGeometry, sp); return std::make_shared<SpatialParams>(gridGeometry, p);
})); }));
cls.def("gravity", &SP::gravity); cls.def("permeability", &SpatialParams::template permeability<decltype(std::ignore)>);
cls.def("porosity", &SpatialParams::template porosity<decltype(std::ignore)>);
cls.def("inertVolumeFraction", &SpatialParams::template inertVolumeFraction<decltype(std::ignore), decltype(std::ignore)>);
} }
} // namespace Dumux::Python } // namespace Dumux::Python
......
add_python_targets(common add_python_targets(common
__init__ __init__
boundarytypes
fvproblem
fvspatialparams
properties properties
) )
......
...@@ -7,67 +7,9 @@ from dune.generator.generator import SimpleGenerator ...@@ -7,67 +7,9 @@ from dune.generator.generator import SimpleGenerator
from dune.common.hashit import hashIt from dune.common.hashit import hashIt
from dumux.common.properties import Model, Property from dumux.common.properties import Model, Property
from dumux.common.boundarytypes import BoundaryTypes
from dumux.common.fvproblem import FVProblem
from dumux.common.fvspatialparams import FVSpatialParams
from dumux.wrapping import cppWrapperCreator, cppWrapperClassAlias from dumux.wrapping import cppWrapperCreator, cppWrapperClassAlias
from ._common import * from ._common import *
@cppWrapperCreator
def _createFVProblemDecorator(gridGeometry, enableInternalDirichletConstraints=False):
"""A problem decorator generator for Python problems
from dumux.common import FVProblem
@FVProblem(gridGeometry)
class MyProblem:
...
"""
def createModule(numEq):
priVarType = f"Dune::FieldVector<double, {numEq}>"
ggType = gridGeometry._typeName
enableIntDirConstraint = "true" if enableInternalDirichletConstraints else "false"
problemType = f"Dumux::Python::FVProblem<{ggType}, {priVarType}, {enableIntDirConstraint}>"
includes = gridGeometry._includes + ["dumux/python/common/fvproblem.hh"]
moduleName = "fvproblem_" + hashIt(problemType)
holderType = f"std::shared_ptr<{problemType}>"
generator = SimpleGenerator("FVProblem", "Dumux::Python")
module = generator.load(includes, problemType, moduleName, options=[holderType])
return module
def decorateFVProblem(cls):
module = createModule(cls.numEq)
def createFVProblem():
return module.FVProblem(gridGeometry, cls())
return createFVProblem
return decorateFVProblem
@cppWrapperClassAlias(creator=_createFVProblemDecorator)
class FVProblem:
"""Class alias used to decorate a Python finite volume problem"""
@cppWrapperCreator
def _createBoundaryTypes(numEq=1):
"""Create BoundaryTypes instances"""
# only compile this once per numEq
cacheKey = f"BoundaryTypes_{numEq}"
try:
return globals()[cacheKey]()
except KeyError:
includes = ["dumux/python/common/boundarytypes.hh"]
typeName = f"Dumux::BoundaryTypes<{numEq}>"
moduleName = "boundarytypes_" + hashIt(typeName)
generator = SimpleGenerator("BoundaryTypes", "Dumux::Python")
module = generator.load(includes, typeName, moduleName)
globals().update({cacheKey: module.BoundaryTypes})
return globals()[cacheKey]()
@cppWrapperClassAlias(creator=_createBoundaryTypes)
class BoundaryTypes:
"""Class alias used to create a BoundaryTypes instance"""
"""
Boundary types generator
"""
from dune.generator.generator import SimpleGenerator
from dune.common.hashit import hashIt
from dumux.wrapping import cppWrapperCreator, cppWrapperClassAlias
@cppWrapperCreator
def _createBoundaryTypes(numEq=1):
"""Create BoundaryTypes instances"""
# only compile this once per numEq
cacheKey = f"BoundaryTypes_{numEq}"
try:
return globals()[cacheKey]()
except KeyError:
includes = ["dumux/python/common/boundarytypes.hh"]
typeName = f"Dumux::BoundaryTypes<{numEq}>"
moduleName = "boundarytypes_" + hashIt(typeName)
generator = SimpleGenerator("BoundaryTypes", "Dumux::Python")
module = generator.load(includes, typeName, moduleName)
globals().update({cacheKey: module.BoundaryTypes})
return globals()[cacheKey]()
@cppWrapperClassAlias(creator=_createBoundaryTypes)
class BoundaryTypes:
"""Class alias used to create a BoundaryTypes instance"""
"""
Finite volume problem generator
"""
from dune.generator.generator import SimpleGenerator
from dune.common.hashit import hashIt
from dumux.wrapping import cppWrapperCreator, cppWrapperClassAlias
@cppWrapperCreator
def _createFVProblemDecorator(
gridGeometry, spatialParams=None, enableInternalDirichletConstraints=False
):
"""A problem decorator generator for Python problems
from dumux.common import FVProblem
@FVProblem(gridGeometry)
class MyProblem:
...
"""
def createModule(numEq):
ggType = gridGeometry._typeName
if spatialParams is not None:
spType = spatialParams._typeName
else:
spType = f"Dumux::Python::FVSpatialParams<{ggType}>"
priVarType = f"Dune::FieldVector<double, {numEq}>"
enableIntDirConstraint = "true" if enableInternalDirichletConstraints else "false"
problemType = (
f"Dumux::Python::FVProblem<{ggType}, {spType}, {priVarType}, {enableIntDirConstraint}>"
)
includes = gridGeometry._includes + ["dumux/python/common/fvproblem.hh"]
moduleName = "fvproblem_" + hashIt(problemType)
holderType = f"std::shared_ptr<{problemType}>"
generator = SimpleGenerator("FVProblem", "Dumux::Python")
module = generator.load(includes, problemType, moduleName, options=[holderType])
return module
def decorateFVProblem(cls):
module = createModule(cls.numEq)
def createFVProblem():
if spatialParams is not None:
return module.FVProblem(gridGeometry, spatialParams, cls())
return module.FVProblem(gridGeometry, cls())
return createFVProblem
return decorateFVProblem
@cppWrapperClassAlias(creator=_createFVProblemDecorator)
class FVProblem:
"""Class alias used to decorate a Python finite volume problem"""
"""
Finite volume spatial params generator
"""
from dune.generator.generator import SimpleGenerator
from dune.common.hashit import hashIt
from dumux.wrapping import cppWrapperCreator, cppWrapperClassAlias
@cppWrapperCreator
def _createFVSpatialParamsDecorator(gridGeometry):
"""A spatial params decorator generator for Python spatial params
from dumux.common import FVSpatialParams
@FVSpatialParams(gridGeometry)
class MySpatialParams:
...
"""
def createModule():
ggType = gridGeometry._typeName
spatialParamsType = f"Dumux::Python::FVSpatialParams<{ggType}>"
includes = gridGeometry._includes + ["dumux/python/common/fvspatialparams.hh"]
moduleName = "fvspatialparams_" + hashIt(spatialParamsType)
holderType = f"std::shared_ptr<{spatialParamsType}>"
generator = SimpleGenerator("FVSpatialParams", "Dumux::Python")
module = generator.load(includes, spatialParamsType, moduleName, options=[holderType])
return module
def decorateFVSpatialParams(cls):
module = createModule()
def createFVSpatialParams():
return module.FVSpatialParams(gridGeometry, cls())
return createFVSpatialParams
return decorateFVSpatialParams
@cppWrapperClassAlias(creator=_createFVSpatialParamsDecorator)
class FVSpatialParams:
"""Class alias used to decorate a Python Finite Volume Spatial Params"""
add_subdirectory(components) add_subdirectory(components)
add_subdirectory(fluidsystems) add_subdirectory(fluidsystems)
add_subdirectory(spatialparams)
add_python_targets(material add_python_targets(material
__init__ __init__
......
...@@ -2,4 +2,3 @@ ...@@ -2,4 +2,3 @@
from dumux.material.fluidsystems import FluidSystem from dumux.material.fluidsystems import FluidSystem
from dumux.material.components import Component from dumux.material.components import Component
from dumux.material.spatialparams import OnePSpatialParams
add_python_targets(spatialparams
__init__
)
"""Spatial parameter classes"""
import numpy as np
from dune.generator.generator import SimpleGenerator
from dune.common.hashit import hashIt
from dumux.common import Property
from dumux.wrapping import cppWrapperCreator, cppWrapperClassAlias
@cppWrapperCreator
def _createOnePSpatialParamsDecorator(*, gridGeometry, scalar: Property = None):
"""Turn a Python spatial parameter class into an C++/Python hybrid class"""
dim = gridGeometry.gridView.dimensionworld
includes = gridGeometry._includes + [
"dumux/python/material/spatialparams/spatialparams.hh",
"dune/common/fmatrix.hh",
]
if scalar is None:
scalar = Property.fromCppType("double")
scalarType = scalar.cppType
permType = f"Dune::FieldMatrix<{scalarType}, {dim}, {dim}>"
typeName = (
f"Dumux::Python::FVSpatialParamsOneP<{gridGeometry._typeName}, {scalarType}, {permType}>"
)
moduleName = f"spatialparams_{hashIt(typeName)}"
def decorateOnePSpatialParams(cls):
generator = SimpleGenerator("OnePSpatialParams", "Dumux::Python")
module = generator.load(includes, typeName, moduleName, holder="std::shared_ptr")
def maybeConvertScalarToMatrix(permeabilityValue):
if isinstance(permeabilityValue, float):
matrix = np.zeros(shape=(dim, dim))
np.fill_diagonal(matrix, permeabilityValue)
return matrix.tolist()
return permeabilityValue
class Permeability:
"""Permeability decorator to make sure permeability has correct type"""
def __init__(self, permeabilityFunction):
self.permeabilityFunction = permeabilityFunction
def __call__(self, element, scv, elemSol):
result = self.permeabilityFunction(element, scv, elemSol)
return maybeConvertScalarToMatrix(result)
class PermeabilityAtPos:
"""PermeabilityAtPos decorator to make sure permeability has correct type"""
def __init__(self, permeabilityFunction):
self.permeabilityFunction = permeabilityFunction
def __call__(self, globalPos):
result = self.permeabilityFunction(globalPos)
return maybeConvertScalarToMatrix(result)
def createSpatialParams():
spatialParams = cls()
if hasattr(cls, "permeability"):
cls.permeability = Permeability(spatialParams.permeability)
if hasattr(cls, "permeabilityAtPos"):
cls.permeabilityAtPos = PermeabilityAtPos(spatialParams.permeabilityAtPos)
return module.OnePSpatialParams(gridGeometry, spatialParams)
return createSpatialParams
return decorateOnePSpatialParams
@cppWrapperClassAlias(creator=_createOnePSpatialParamsDecorator)
class OnePSpatialParams:
"""Class alias used to decorate Python spatial parameter implementations"""
"""Classes and functions related to the porousmedium flow models""" """Classes and functions related to the porousmedium flow models"""
import numpy as np
from dune.generator.generator import SimpleGenerator from dune.generator.generator import SimpleGenerator
from dune.common.hashit import hashIt from dune.common.hashit import hashIt
from dumux.common import Property
from dumux.wrapping import cppWrapperCreator, cppWrapperClassAlias from dumux.wrapping import cppWrapperCreator, cppWrapperClassAlias
...@@ -24,7 +26,7 @@ def _createPorousMediumFlowProblemDecorator( ...@@ -24,7 +26,7 @@ def _createPorousMediumFlowProblemDecorator(
spType = spatialParams._typeName spType = spatialParams._typeName
enableIDC = "true" if enableInternalDirichletConstraints else "false" enableIDC = "true" if enableInternalDirichletConstraints else "false"
problemType = ( problemType = (
"Dumux::Python::PorousMediumFlowProblem" f"<{ggType}, {priVars}, {spType}, {enableIDC}>" "Dumux::Python::PorousMediumFlowProblem" f"<{ggType}, {spType}, {priVars}, {enableIDC}>"
) )
includes = [ includes = [
*(gridGeometry._includes), *(gridGeometry._includes),
...@@ -79,3 +81,73 @@ def _createPorousMediumFlowVelocityOutput(*, gridVariables): ...@@ -79,3 +81,73 @@ def _createPorousMediumFlowVelocityOutput(*, gridVariables):
@cppWrapperClassAlias(creator=_createPorousMediumFlowVelocityOutput) @cppWrapperClassAlias(creator=_createPorousMediumFlowVelocityOutput)
class PorousMediumFlowVelocityOutput: class PorousMediumFlowVelocityOutput:
"""A class alias used to create PorousMediumFlowVelocityOutput instances""" """A class alias used to create PorousMediumFlowVelocityOutput instances"""
@cppWrapperCreator
def _createFVSpatialParamsOnePDecorator(gridGeometry):
"""A spatial params decorator generator for Python spatial params
from dumux.common import FVSpatialParamsOneP
FVSpatialParamsOneP(gridGeometry)
class MySpatialParams:
...
"""
dim = gridGeometry.gridView.dimensionworld
scalar = Property.fromCppType("double")
scalarType = scalar.cppType
permType = f"Dune::FieldMatrix<{scalarType}, {dim}, {dim}>"
def decorateFVSpatialParamsOneP(cls):
ggType = gridGeometry._typeName
spatialParamsType = f"Dumux::Python::FVSpatialParamsOneP<{ggType}, {permType}>"
includes = gridGeometry._includes + ["dumux/python/porousmediumflow/spatialparams.hh"]
includes += ["dumux/python/common/fvspatialparams.hh"]
moduleName = "fvspatialparamsonep_" + hashIt(spatialParamsType)
holderType = f"std::shared_ptr<{spatialParamsType}>"
generator = SimpleGenerator("FVSpatialParamsOneP", "Dumux::Python")
module = generator.load(includes, spatialParamsType, moduleName, options=[holderType])
def maybeConvertScalarToMatrix(permeabilityValue):
if isinstance(permeabilityValue, float):
matrix = np.zeros(shape=(dim, dim))
np.fill_diagonal(matrix, permeabilityValue)
return matrix.tolist()
return permeabilityValue
class Permeability:
"""Permeability decorator to make sure permeability has correct type"""
def __init__(self, permeabilityFunction):
self.permeabilityFunction = permeabilityFunction
def __call__(self, element, scv, elemSol):
result = self.permeabilityFunction(element, scv, elemSol)
return maybeConvertScalarToMatrix(result)
class PermeabilityAtPos:
"""PermeabilityAtPos decorator to make sure permeability has correct type"""
def __init__(self, permeabilityFunction):
self.permeabilityFunction = permeabilityFunction
def __call__(self, globalPos):
result = self.permeabilityFunction(globalPos)
return maybeConvertScalarToMatrix(result)
def createFVSpatialParamsOneP():
spatialParams = cls()
if hasattr(cls, "permeability"):
cls.permeability = Permeability(spatialParams.permeability)
if hasattr(cls, "permeabilityAtPos"):
cls.permeabilityAtPos = PermeabilityAtPos(spatialParams.permeabilityAtPos)
return module.FVSpatialParamsOneP(gridGeometry, cls())
return createFVSpatialParamsOneP
return decorateFVSpatialParamsOneP
@cppWrapperClassAlias(creator=_createFVSpatialParamsOnePDecorator)
class FVSpatialParamsOneP:
"""Class alias used to decorate a Python Finite Volume Spatial Params"""
...@@ -9,8 +9,12 @@ from dumux.common import initParameters, printParameters, getParam ...@@ -9,8 +9,12 @@ from dumux.common import initParameters, printParameters, getParam
from dumux.common import BoundaryTypes, Model, Property from dumux.common import BoundaryTypes, Model, Property
from dumux.discretization import GridGeometry, GridVariables from dumux.discretization import GridGeometry, GridVariables
from dumux.assembly import FVAssembler from dumux.assembly import FVAssembler
from dumux.porousmediumflow import PorousMediumFlowProblem, PorousMediumFlowVelocityOutput from dumux.porousmediumflow import (
from dumux.material import FluidSystem, Component, OnePSpatialParams PorousMediumFlowProblem,
PorousMediumFlowVelocityOutput,
FVSpatialParamsOneP,
)
from dumux.material import FluidSystem, Component
from dumux.io import VtkOutputModule from dumux.io import VtkOutputModule
# Initialize parameters # Initialize parameters
...@@ -52,7 +56,7 @@ model["FluidSystem"] = Property.fromInstance(onePLiquid) ...@@ -52,7 +56,7 @@ model["FluidSystem"] = Property.fromInstance(onePLiquid)
# Define the spatial parameters # Define the spatial parameters
@OnePSpatialParams(gridGeometry=gridGeometry) @FVSpatialParamsOneP(gridGeometry=gridGeometry)
class SpatialParams: class SpatialParams:
dimWorld = gridGeometry.gridView.dimWorld dimWorld = gridGeometry.gridView.dimWorld
lensLowerLeft = [0.2, 0.2] lensLowerLeft = [0.2, 0.2]
...@@ -80,13 +84,11 @@ class SpatialParams: ...@@ -80,13 +84,11 @@ class SpatialParams:
return 0.4 return 0.4
# and set them as a model property
spatialParams = SpatialParams() spatialParams = SpatialParams()
model["SpatialParams"] = Property.fromInstance(spatialParams) model["SpatialParams"] = Property.fromInstance(spatialParams)
# Define the problem # Define the problem
@PorousMediumFlowProblem(gridGeometry, spatialParams) @PorousMediumFlowProblem(gridGeometry=gridGeometry, spatialParams=spatialParams)
class Problem: class Problem:
numEq = 1 numEq = 1
...@@ -108,12 +110,6 @@ class Problem: ...@@ -108,12 +110,6 @@ class Problem:
def sourceAtPos(self, globalPos): def sourceAtPos(self, globalPos):
return 0.0 return 0.0
def extrusionFactor(self, element, scv):
return 1.0
def temperatureAtPos(self, globalPos):
return 283.15
def name(self): def name(self):
return "python_problem" return "python_problem"
......
...@@ -29,12 +29,12 @@ gridGeometry = GridGeometry(gridView, discMethod="cctpfa") ...@@ -29,12 +29,12 @@ gridGeometry = GridGeometry(gridView, discMethod="cctpfa")
elementMapper = gridView.indexSet elementMapper = gridView.indexSet
############################################## ################################################
# Define problem (inital/boundary condtions) # # Define problem (initial/boundary conditions) #
############################################## ################################################
@FVProblem(gridGeometry) @FVProblem(gridGeometry=gridGeometry)
class Problem: class Problem:
numEq = 1 numEq = 1
......
...@@ -27,7 +27,7 @@ gridView = structuredGrid([0, 0, 0], [1, 1, 1], [3, 3, 3]) ...@@ -27,7 +27,7 @@ gridView = structuredGrid([0, 0, 0], [1, 1, 1], [3, 3, 3])
gridGeometry = GridGeometry(gridView, discMethod="box") gridGeometry = GridGeometry(gridView, discMethod="box")
@FVProblem(gridGeometry) @FVProblem(gridGeometry=gridGeometry)
class Problem: class Problem:
numEq = 2 numEq = 2
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment