diff --git a/python/dune/xt/functions/expression.cc b/python/dune/xt/functions/expression.cc index 6938bdd87502b6fd25ecad836e660f5aa0f89472..770510b1b5013afc6f6f301e9372839727a81bad 100644 --- a/python/dune/xt/functions/expression.cc +++ b/python/dune/xt/functions/expression.cc @@ -19,10 +19,244 @@ #include <dune/pybindxi/pybind11.h> #include <dune/pybindxi/stl.h> +#include <dune/xt/common/string.hh> +#include <dune/xt/grid/gridprovider/provider.hh> +#include <dune/xt/grid/type_traits.hh> +#include <dune/xt/functions/expression.hh> + +#include <python/dune/xt/common/fvector.hh> +#include <python/dune/xt/common/fmatrix.hh> #include <python/dune/xt/common/bindings.hh> +#include <python/dune/xt/grid/traits.hh> #include <python/dune/xt/common/exceptions.bindings.hh> -#include "expression.hh" +namespace Dune { +namespace XT { +namespace Functions { +namespace bindings { + + +template <size_t d, size_t r = 1, size_t rC = 1, class R = double> +class ExpressionFunction +{ + using type = Functions::ExpressionFunction<d, r, rC, R>; + using base_type = Functions::FunctionInterface<d, r, rC, R>; + using bound_type = pybind11::class_<type, base_type>; + + template <size_t r_ = r, size_t rC_ = rC, bool anything = true> // the matrix-valued case + struct addbind + { + static void ctor(bound_type& c) + { + namespace py = pybind11; + using namespace pybind11::literals; + + c.def(py::init<const std::string&, + const Common::FieldMatrix<std::string, r, rC>&, + const Common::FieldVector<Common::FieldMatrix<std::string, rC, d>, r>&, + const size_t, + const std::string>(), + "variable"_a, + "expressions"_a, + "gradient_expressions"_a, + "order"_a, + "name"_a = type::static_id()); + c.def(py::init<const std::string&, + const Common::FieldMatrix<std::string, r, rC>&, + const size_t, + const std::string>(), + "variable"_a, + "expressions"_a, + "order"_a, + "name"_a = type::static_id()); + } // ... ctor(...) + + static void factory(pybind11::module& m, const std::string& ClassId) + { + namespace py = pybind11; + using namespace pybind11::literals; + + m.def(ClassId.c_str(), + [](Grid::bindings::Dimension<d> /*dim_domain*/, + const std::string& variable, + const Common::FieldMatrix<std::string, r, rC>& expressions, + const Common::FieldVector<Common::FieldMatrix<std::string, rC, d>, r>& gradient_expressions, + const size_t order, + const std::string& name) { return type(variable, expressions, gradient_expressions, order, name); }, + "dim_domain"_a, + "variable"_a, + "expressions"_a, + "gradient_expressions"_a, + "order"_a, + "name"_a = type::static_id()); + m.def(ClassId.c_str(), + [](Grid::bindings::Dimension<d> /*dim_domain*/, + const std::string& variable, + const Common::FieldMatrix<std::string, r, rC>& expressions, + const size_t order, + const std::string& name) { return type(variable, expressions, order, name); }, + "dim_domain"_a, + "variable"_a, + "expressions"_a, + "order"_a, + "name"_a = type::static_id()); + } // ... factory(...) + }; // struct addbind, the matrix-valued case + + template <size_t r_, bool anything> // the vector-valued case + struct addbind<r_, 1, anything> + { + static void ctor(bound_type& c) + { + namespace py = pybind11; + using namespace pybind11::literals; + + c.def(py::init<const std::string&, + const Common::FieldVector<std::string, r>&, + const Common::FieldMatrix<std::string, r, d>&, + const size_t, + const std::string>(), + "variable"_a, + "expressions"_a, + "gradient_expressions"_a, + "order"_a, + "name"_a = type::static_id()); + c.def(py::init<const std::string&, const Common::FieldVector<std::string, r>&, const size_t, const std::string>(), + "variable"_a, + "expressions"_a, + "order"_a, + "name"_a = type::static_id()); + } // ... ctor(...) + + static void factory(pybind11::module& m, const std::string& ClassId) + { + namespace py = pybind11; + using namespace pybind11::literals; + + m.def(ClassId.c_str(), + [](Grid::bindings::Dimension<d> /*dim_domain*/, + const std::string& variable, + const Common::FieldVector<std::string, r>& expressions, + const Common::FieldMatrix<std::string, r, d>& gradient_expressions, + const size_t order, + const std::string& name) { return type(variable, expressions, gradient_expressions, order, name); }, + "dim_domain"_a, + "variable"_a, + "expressions"_a, + "gradient_expressions"_a, + "order"_a, + "name"_a = type::static_id()); + m.def(ClassId.c_str(), + [](Grid::bindings::Dimension<d> /*dim_domain*/, + const std::string& variable, + const Common::FieldVector<std::string, r>& expressions, + const size_t order, + const std::string& name) { return type(variable, expressions, order, name); }, + "dim_domain"_a, + "variable"_a, + "expressions"_a, + "order"_a, + "name"_a = type::static_id()); + } // ... factory(...) + }; // struct addbind, the vector-valued case + + template <bool anything> + struct addbind<1, 1, anything> // the scalar case + { + static void ctor(bound_type& c) + { + namespace py = pybind11; + using namespace pybind11::literals; + + c.def(py::init([](const std::string& variable, + const std::string& expression, + const Common::FieldVector<std::string, d>& gradient_expressions, + const size_t order, + const std::string& name) { + Common::FieldMatrix<std::string, 1, d> gradient_expressions_mat; + gradient_expressions_mat[0] = gradient_expressions; + return new type( + variable, Common::FieldVector<std::string, 1>(expression), gradient_expressions_mat, order, name); + }), + "variable"_a, + "expression"_a, + "gradient_expressions"_a, + "order"_a, + "name"_a = type::static_id()); + c.def(py::init([](const std::string& variable, + const std::string& expression, + const size_t order, + const std::string& name) { + return new type(variable, Common::FieldVector<std::string, 1>(expression), order, name); + }), + "variable"_a, + "expression"_a, + "order"_a, + "name"_a = type::static_id()); + } // ... ctor(...) + + static void factory(pybind11::module& m, const std::string& ClassId) + { + namespace py = pybind11; + using namespace pybind11::literals; + + m.def(ClassId.c_str(), + [](Grid::bindings::Dimension<d> /*dim_domain*/, + const std::string& variable, + const std::string& expression, + const Common::FieldVector<std::string, d>& gradient_expressions, + const size_t order, + const std::string& name) { + Common::FieldMatrix<std::string, 1, d> gradient_expressions_mat; + gradient_expressions_mat[0] = gradient_expressions; + return new type( + variable, Common::FieldVector<std::string, 1>(expression), gradient_expressions_mat, order, name); + }, + "dim_domain"_a, + "variable"_a, + "expression"_a, + "gradient_expressions"_a, + "order"_a, + "name"_a = type::static_id()); + m.def(ClassId.c_str(), + [](Grid::bindings::Dimension<d> /*dim_domain*/, + const std::string& variable, + const std::string& expression, + const size_t order, + const std::string& name) { return new type(variable, expression, order, name); }, + "dim_domain"_a, + "variable"_a, + "expression"_a, + "order"_a, + "name"_a = type::static_id()); + } // ... factory(...) + }; // struct addbind, the scalar case + +public: + static bound_type bind(pybind11::module& m, const std::string& class_id = "expression_function") + { + namespace py = pybind11; + using namespace pybind11::literals; + + std::string class_name = class_id + "_" + Common::to_string(d) + "_to_" + Common::to_string(r); + if (rC > 1) + class_name += "x" + Common::to_string(rC); + class_name += "d"; + const auto ClassName = Common::to_camel_case(class_name); + bound_type c(m, ClassName.c_str(), XT::Common::to_camel_case(class_id).c_str()); + addbind<>::ctor(c); + + addbind<>::factory(m, Common::to_camel_case(class_id)); + + return c; + } +}; // class ExpressionFunction + + +} // namespace bindings +} // namespace Functions +} // namespace XT +} // namespace Dune PYBIND11_MODULE(_functions_expression, m) @@ -30,28 +264,27 @@ PYBIND11_MODULE(_functions_expression, m) namespace py = pybind11; py::module::import("dune.xt.common"); + py::module::import("dune.xt.grid"); py::module::import("dune.xt.la"); py::module::import("dune.xt.functions._functions_function_interface_1d"); py::module::import("dune.xt.functions._functions_function_interface_2d"); py::module::import("dune.xt.functions._functions_function_interface_3d"); - using namespace Dune::XT::Functions; - - bind_ExpressionFunction<1, 1, 1>(m); - bind_ExpressionFunction<1, 2, 1>(m); - bind_ExpressionFunction<1, 2, 2>(m); - bind_ExpressionFunction<1, 3, 1>(m); - bind_ExpressionFunction<1, 3, 3>(m); - - bind_ExpressionFunction<2, 1, 1>(m); - bind_ExpressionFunction<2, 2, 1>(m); - bind_ExpressionFunction<2, 2, 2>(m); - bind_ExpressionFunction<2, 3, 1>(m); - bind_ExpressionFunction<2, 3, 3>(m); - - bind_ExpressionFunction<3, 1, 1>(m); - bind_ExpressionFunction<3, 2, 1>(m); - bind_ExpressionFunction<3, 2, 2>(m); - bind_ExpressionFunction<3, 3, 1>(m); - bind_ExpressionFunction<3, 3, 3>(m); -} + Dune::XT::Functions::bindings::ExpressionFunction<1, 1, 1>::bind(m); + Dune::XT::Functions::bindings::ExpressionFunction<1, 2, 1>::bind(m); + Dune::XT::Functions::bindings::ExpressionFunction<1, 2, 2>::bind(m); + Dune::XT::Functions::bindings::ExpressionFunction<1, 3, 1>::bind(m); + Dune::XT::Functions::bindings::ExpressionFunction<1, 3, 3>::bind(m); + + Dune::XT::Functions::bindings::ExpressionFunction<2, 1, 1>::bind(m); + Dune::XT::Functions::bindings::ExpressionFunction<2, 2, 1>::bind(m); + Dune::XT::Functions::bindings::ExpressionFunction<2, 2, 2>::bind(m); + Dune::XT::Functions::bindings::ExpressionFunction<2, 3, 1>::bind(m); + Dune::XT::Functions::bindings::ExpressionFunction<2, 3, 3>::bind(m); + + Dune::XT::Functions::bindings::ExpressionFunction<3, 1, 1>::bind(m); + Dune::XT::Functions::bindings::ExpressionFunction<3, 2, 1>::bind(m); + Dune::XT::Functions::bindings::ExpressionFunction<3, 2, 2>::bind(m); + Dune::XT::Functions::bindings::ExpressionFunction<3, 3, 1>::bind(m); + Dune::XT::Functions::bindings::ExpressionFunction<3, 3, 3>::bind(m); +} // PYBIND11_MODULE(...) diff --git a/python/dune/xt/functions/expression.hh b/python/dune/xt/functions/expression.hh deleted file mode 100644 index 9fb741bf714cc839dcc19cd0d02f1d5df9e182a2..0000000000000000000000000000000000000000 --- a/python/dune/xt/functions/expression.hh +++ /dev/null @@ -1,280 +0,0 @@ -// This file is part of the dune-xt project: -// https://github.com/dune-community/dune-xt -// Copyright 2009-2020 dune-xt developers and contributors. All rights reserved. -// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause) -// or GPL-2.0+ (http://opensource.org/licenses/gpl-license) -// with "runtime exception" (http://www.dune-project.org/license.html) -// Authors: -// Felix Schindler (2016 - 2017, 2019) -// René Fritze (2018 - 2019) -// Tim Keil (2018) -// Tobias Leibner (2018 - 2020) - -#ifndef PYTHON_DUNE_XT_FUNCTIONS_EXPRESSION_HH -#define PYTHON_DUNE_XT_FUNCTIONS_EXPRESSION_HH - -#include <dune/pybindxi/pybind11.h> -#include <dune/pybindxi/stl.h> - -#include <dune/xt/common/string.hh> -#include <dune/xt/grid/type_traits.hh> -#include <dune/xt/grid/gridprovider/provider.hh> -#include <dune/xt/functions/expression.hh> -#include <python/dune/xt/common/fvector.hh> -#include <python/dune/xt/common/fmatrix.hh> - -namespace Dune { -namespace XT { -namespace Functions { -namespace internal { - - -template <size_t d, size_t r, size_t rC> -struct addbind_ExpressionFunction_scalar_ctor -{ - template <class C> - void operator()(C& /*c*/, const std::string& /*static_id*/) - {} -}; - -template <size_t d, size_t r> -struct addbind_ExpressionFunction_scalar_ctor<d, r, 1> -{ - template <class C> - void operator()(C& c, const std::string& static_id) - { - namespace py = pybind11; - using namespace pybind11::literals; - - c.def(py::init<const std::string, - const Common::FieldVector<std::string, r>, - const Common::FieldMatrix<std::string, r, d>, - const size_t, - const std::string>(), - "variable"_a, - "expressions"_a, - "gradient_expressions"_a, - "order"_a, - "name"_a = static_id); - - c.def(py::init<const std::string, const Common::FieldVector<std::string, r>, const size_t, const std::string>(), - "variable"_a, - "expressions"_a, - "order"_a, - "name"_a = static_id); - } -}; // struct addbind_ExpressionFunction_scalar_ctor<1, 1> - - -} // namespace internal - - -/** - * \note We would like to drop the d template paremter and use either of -\code -static const size_t d = G::dimension; -static const constexpr size_t d = G::dimension; -\endcode - * but this triggers a bug in gcc-4.9 and we thus need to use G::dimension - * everywhere: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59937 - */ -template <size_t d, size_t r> -pybind11::class_<ExpressionFunction<d, r, 3, double>, FunctionInterface<d, r, 3, double>> -bind_ExpressionFunction(pybind11::module& m, std::integral_constant<int, 3>) -{ - namespace py = pybind11; - using namespace pybind11::literals; - const size_t rC = 3; - using R = double; - - using I = FunctionInterface<d, r, rC, R>; - using C = ExpressionFunction<d, r, rC, R>; - - const std::string c_name = - "ExpressionFunction__" + Common::to_string(d) + "d_to_" + Common::to_string(r) + "x" + Common::to_string(rC); - py::class_<C, I> c(m, std::string(c_name).c_str(), std::string(c_name).c_str()); - - internal::addbind_ExpressionFunction_scalar_ctor<d, r, rC>()(c, C::static_id()); - c.def(py::init<const std::string, - const Common::FieldMatrix<std::string, r, rC>, - const Common::FieldVector<Common::FieldMatrix<std::string, rC, d>, r>, - const size_t, - const std::string>(), - "variable"_a, - "expressions"_a, - "gradient_expressions"_a, - "order"_a, - "name"_a = C::static_id()); - - c.def(py::init<const std::string, const Common::FieldMatrix<std::string, r, rC>, const size_t, const std::string>(), - "variable"_a, - "expressions"_a, - "order"_a, - "name"_a = C::static_id()); - - c.def_property_readonly("static_id", [](const C& /*self*/) { return C::static_id(); }); - - const std::string make_name = "make_expression_function_" + Common::to_string(r) + "x" + Common::to_string(rC); - m.def(std::string(make_name).c_str(), - [](const std::string& variable, - const Common::FieldMatrix<std::string, r, rC>& expression, - const Common::FieldVector<Common::FieldMatrix<std::string, rC, d>, r>& gradient_expressions, - const size_t& order, - const std::string& name) { return C(variable, expression, gradient_expressions, order, name); }, - "variable"_a, - "expression"_a, - "gradient_expressions"_a, - "order"_a, - "name"_a = C::static_id()); - - m.def(std::string(make_name).c_str(), - [](const std::string& variable, - const Common::FieldMatrix<std::string, r, rC>& expression, - const size_t& order, - const std::string& name) { return C(variable, expression, order, name); }, - "variable"_a, - "expression"_a, - "order"_a, - "name"_a = C::static_id()); - - return c; -} // ... bind_ExpressionFunction(...) - -template <size_t d, size_t r> -pybind11::class_<ExpressionFunction<d, r, 2, double>, FunctionInterface<d, r, 2, double>> -bind_ExpressionFunction(pybind11::module& m, std::integral_constant<int, 2>) -{ - namespace py = pybind11; - using namespace pybind11::literals; - - const size_t rC = 2; - using R = double; - - using I = FunctionInterface<d, r, rC, R>; - using C = ExpressionFunction<d, r, rC, R>; - - const std::string c_name = - "ExpressionFunction__" + Common::to_string(d) + "d_to_" + Common::to_string(r) + "x" + Common::to_string(rC); - py::class_<C, I> c(m, std::string(c_name).c_str(), std::string(c_name).c_str()); - - internal::addbind_ExpressionFunction_scalar_ctor<d, r, rC>()(c, C::static_id()); - c.def(py::init<const std::string, - const Common::FieldMatrix<std::string, r, rC>, - const Common::FieldVector<Common::FieldMatrix<std::string, rC, d>, r>, - const size_t, - const std::string>(), - "variable"_a, - "expressions"_a, - "gradient_expressions"_a, - "order"_a, - "name"_a = C::static_id()); - - c.def(py::init<const std::string, const Common::FieldMatrix<std::string, r, rC>, const size_t, const std::string>(), - "variable"_a, - "expressions"_a, - "order"_a, - "name"_a = C::static_id()); - - c.def_property_readonly("static_id", [](const C& /*self*/) { return C::static_id(); }); - - const std::string make_name = "make_expression_function_" + Common::to_string(r) + "x" + Common::to_string(rC); - m.def(std::string(make_name).c_str(), - [](const std::string& variable, - const Common::FieldMatrix<std::string, r, rC>& expression, - const Common::FieldVector<Common::FieldMatrix<std::string, rC, d>, r>& gradient_expressions, - const size_t& order, - const std::string& name) { return C(variable, expression, gradient_expressions, order, name); }, - "variable"_a, - "expression"_a, - "gradient_expressions"_a, - "order"_a, - "name"_a = C::static_id()); - - m.def(std::string(make_name).c_str(), - [](const std::string& variable, - const Common::FieldMatrix<std::string, r, rC>& expression, - const size_t& order, - const std::string& name) { return C(variable, expression, order, name); }, - "variable"_a, - "expression"_a, - "order"_a, - "name"_a = C::static_id()); - - return c; -} // ... bind_ExpressionFunction(...) - -template <size_t d, size_t r> -pybind11::class_<ExpressionFunction<d, r, 1, double>, FunctionInterface<d, r, 1, double>> -bind_ExpressionFunction(pybind11::module& m, std::integral_constant<int, 1>) -{ - namespace py = pybind11; - using namespace pybind11::literals; - const size_t rC = 1; - using R = double; - - using I = FunctionInterface<d, r, rC, R>; - using C = ExpressionFunction<d, r, rC, R>; - - const std::string c_name = - "ExpressionFunction__" + Common::to_string(d) + "d_to_" + Common::to_string(r) + "x" + Common::to_string(1); - py::class_<C, I> c(m, std::string(c_name).c_str(), std::string(c_name).c_str()); - - internal::addbind_ExpressionFunction_scalar_ctor<d, r, 1>()(c, C::static_id()); - c.def(py::init<const std::string, - const Common::FieldVector<std::string, r>, - const Common::FieldMatrix<std::string, r, d>, - const size_t, - const std::string>(), - "variable"_a, - "expressions"_a, - "gradient_expressions"_a, - "order"_a, - "name"_a = C::static_id()); - - c.def(py::init<const std::string, const Common::FieldVector<std::string, r>, const size_t, const std::string>(), - "variable"_a, - "expressions"_a, - "order"_a, - "name"_a = C::static_id()); - - c.def_property_readonly("static_id", [](const C& /*self*/) { return C::static_id(); }); - - const std::string make_name = "make_expression_function_" + Common::to_string(r) + "x" + Common::to_string(1); - m.def(std::string(make_name).c_str(), - [](const std::string& variable, - const Common::FieldVector<std::string, r>& expression, - const Common::FieldMatrix<std::string, r, d>& gradient_expressions, - const size_t& order, - const std::string& name) { return C(variable, expression, gradient_expressions, order, name); }, - "variable"_a, - "expression"_a, - "gradient_expressions"_a, - "order"_a, - "name"_a = C::static_id()); - - m.def(std::string(make_name).c_str(), - [](const std::string& variable, - const Common::FieldVector<std::string, r>& expression, - const size_t& order, - const std::string& name) { return C(variable, expression, order, name); }, - "variable"_a, - "expression"_a, - "order"_a, - "name"_a = C::static_id()); - - return c; -} - - -template <size_t d, size_t r, size_t rC> -pybind11::class_<ExpressionFunction<d, r, rC, double>> bind_ExpressionFunction(pybind11::module& m) -{ - return bind_ExpressionFunction<d, r>(m, std::integral_constant<int, rC>()); -} // ... bind_ExpressionFunction(...) - - -} // namespace Functions -} // namespace XT -} // namespace Dune - -#endif // PYTHON_DUNE_XT_FUNCTIONS_EXPRESSION_HH