diff --git a/python/wrap/model.cpp b/python/wrap/model.cpp index 738c963..a389556 100644 --- a/python/wrap/model.cpp +++ b/python/wrap/model.cpp @@ -1,235 +1,209 @@ /** * @file * * @author Lucas Frérot * * @section LICENSE * * Copyright (©) 2017 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Tamaas is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Tamaas 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 Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Tamaas. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "model.hh" +#include "model_extensions.hh" #include "adhesion_functional.hh" #include "functional.hh" #include "integral_operator.hh" #include "model_dumper.hh" #include "model_factory.hh" #include "numpy.hh" #include "residual.hh" #include "wrap.hh" #include /* -------------------------------------------------------------------------- */ __BEGIN_TAMAAS__ -namespace functional { -namespace wrap { -/// Class for extension of Functional in python -class PyFunctional : public Functional { -public: - using Functional::Functional; - - // Overriding pure virtual functions - Real computeF(GridBase& variable, GridBase& dual) const override { - PYBIND11_OVERLOAD_PURE(Real, Functional, computeF, variable, dual); - } - - void computeGradF(GridBase& variable, - GridBase& gradient) const override { - PYBIND11_OVERLOAD_PURE(void, Functional, computeGradF, variable, gradient); - } -}; -} -} namespace wrap { using namespace py::literals; -class PyModelDumper : public ModelDumper { -public: - using ModelDumper::ModelDumper; - - void dump(Model* model) override { - PYBIND11_OVERLOAD_PURE(void, ModelDumper, dump, model); - } -}; - /// Wrap functional classes void wrapFunctionals(py::module& mod) { py::class_ func( mod, "Functional"); func.def(py::init<>()) .def("computeF", &functional::Functional::computeF) .def("computeGradF", &functional::Functional::computeGradF); py::class_ adh(mod, "AdhesionFunctional", func); adh.def_property("parameters", &functional::AdhesionFunctional::getParameters, &functional::AdhesionFunctional::setParameters) // legacy wrapper code .def("setParameters", &functional::AdhesionFunctional::setParameters); py::class_( mod, "ExponentialAdhesionFunctional", adh) .def(py::init&>(), "surface"_a); py::class_( mod, "MaugisAdhesionFunctional", adh) .def(py::init&>(), "surface"_a); py::class_( mod, "SquaredExponentialAdhesionFunctional", adh) .def(py::init&>(), "surface"_a); } template std::unique_ptr> instanciateFromNumpy(numpy& num) { std::unique_ptr> result = nullptr; switch (num.ndim()) { case 2: result = std::make_unique>>(num); return result; case 3: result = std::make_unique>>(num); return result; case 4: result = std::make_unique>>(num); return result; default: TAMAAS_EXCEPTION("instanciateFromNumpy expects the last dimension of numpy " "array to be the number of components"); } } /// Wrap IntegralOperator void wrapIntegralOperator(py::module& mod) { py::class_(mod, "IntegralOperator") .def("apply", [](IntegralOperator& op, numpy input, numpy output) { auto in = instanciateFromNumpy(input); auto out = instanciateFromNumpy(output); op.apply(*in, *out); }) .def("updateFromModel", &IntegralOperator::updateFromModel) .def("getModel", &IntegralOperator::getModel, py::return_value_policy::reference) .def("getKind", &IntegralOperator::getKind) .def("getType", &IntegralOperator::getType); } /// Wrap BEEngine classes void wrapBEEngine(py::module& mod) { py::class_(mod, "BEEngine") .def("solveNeumann", &BEEngine::solveNeumann) .def("solveDirichlet", &BEEngine::solveDirichlet) .def("getModel", &BEEngine::getModel, py::return_value_policy::reference); } /// Wrap Models void wrapModelClass(py::module& mod) { py::enum_(mod, "model_type") .value("basic_1d", model_type::basic_1d) .value("basic_2d", model_type::basic_2d) .value("surface_1d", model_type::surface_1d) .value("surface_2d", model_type::surface_2d) .value("volume_1d", model_type::volume_1d) .value("volume_2d", model_type::volume_2d); py::class_(mod, "Model") .def("setElasticity", &Model::setElasticity, "E"_a, "nu"_a) .def_property("E", &Model::getYoungModulus, &Model::setYoungModulus) .def_property("nu", &Model::getPoissonRatio, &Model::setPoissonRatio) .def("getHertzModulus", &Model::getHertzModulus) .def("getYoungModulus", &Model::getYoungModulus) .def("getShearModulus", &Model::getShearModulus) .def("getPoissonRatio", &Model::getPoissonRatio) .def("getTraction", (GridBase & (Model::*)()) & Model::getTraction) .def("getDisplacement", (GridBase & (Model::*)()) & Model::getDisplacement) .def("getSystemSize", &Model::getSystemSize) .def("getDiscretization", &Model::getDiscretization) .def("getBoundarySystemSize", &Model::getBoundarySystemSize) .def("getBoundaryDiscretization", &Model::getBoundaryDiscretization) .def("solveNeumann", &Model::solveNeumann) .def("solveDirichlet", &Model::solveDirichlet) .def("dump", &Model::dump) .def("setDumper", &Model::setDumper, "dumper"_a) .def("getBEEngine", &Model::getBEEngine, py::return_value_policy::reference) .def("getIntegralOperator", &Model::getIntegralOperator, "operator_name"_a, py::return_value_policy::reference) .def("applyElasticity", [](Model& model, numpy stress, numpy strain) { auto out = instanciateFromNumpy(stress); auto in = instanciateFromNumpy(strain); model.applyElasticity(*out, *in); }) .def("__repr__", [](const Model& m) { std::stringstream ss; ss << m; return ss.str(); }); py::class_>( mod, "ModelDumper") .def(py::init<>()) .def("dump", &ModelDumper::dump, "model"_a); } /// Wrap factory for models void wrapModelFactory(py::module& mod) { py::class_(mod, "ModelFactory") .def_static("createModel", &ModelFactory::createModel, "model_type"_a, "system_size"_a, "discretization"_a) .def_static("createResidual", &ModelFactory::createResidual, "model_type"_a, "hardening"_a, "sigma_y"_a); } /// Wrap residual class void wrapResidual(py::module& mod) { // TODO adapt to n-dim - py::class_(mod, "Residual") + py::class_(mod, "Residual") + .def(py::init()) .def("computeResidual", [](Residual& res, Grid& x) { res.computeResidual(x); }) .def("computeStress", [](Residual& res, Grid& x) { res.computeStress(x); }) .def("updateState", [](Residual& res, Grid& x) { res.updateState(x); }) .def("computeResidualDisplacement", [](Residual& res, Grid& x) { res.computeResidualDisplacement(x); }) .def("getVector", &Residual::getVector) .def("getPlasticStrain", &Residual::getPlasticStrain) .def("getStress", &Residual::getStress); } void wrapModel(py::module& mod) { wrapBEEngine(mod); wrapModelClass(mod); wrapModelFactory(mod); wrapFunctionals(mod); wrapResidual(mod); } } // namespace wrap __END_TAMAAS__ diff --git a/python/wrap/model_extensions.hh b/python/wrap/model_extensions.hh new file mode 100644 index 0000000..308c011 --- /dev/null +++ b/python/wrap/model_extensions.hh @@ -0,0 +1,111 @@ +/** + * @file + * + * @author Lucas Frérot + * + * @section LICENSE + * + * Copyright (©) 2017 EPFL (Ecole Polytechnique Fédérale de + * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des + * Solides) + * + * Tamaas is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * Tamaas 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 Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Tamaas. If not, see . + * + */ +/* -------------------------------------------------------------------------- */ +#include "model.hh" +#include "functional.hh" +#include "model_dumper.hh" +#include "residual.hh" +#include "wrap.hh" +#include +/* -------------------------------------------------------------------------- */ +namespace tamaas { +/* -------------------------------------------------------------------------- */ + +namespace functional { +namespace wrap { +/// Class for extension of Functional in python +class PyFunctional : public Functional { +public: + using Functional::Functional; + + // Overriding pure virtual functions + Real computeF(GridBase& variable, GridBase& dual) const override { + PYBIND11_OVERLOAD_PURE(Real, Functional, computeF, variable, dual); + } + + void computeGradF(GridBase& variable, + GridBase& gradient) const override { + PYBIND11_OVERLOAD_PURE(void, Functional, computeGradF, variable, gradient); + } +}; +} // namespace wrap +} // namespace functional +/* -------------------------------------------------------------------------- */ +namespace wrap { + +/* -------------------------------------------------------------------------- */ +class PyModelDumper : public ModelDumper { +public: + using ModelDumper::ModelDumper; + + void dump(Model* model) override { + PYBIND11_OVERLOAD_PURE(void, ModelDumper, dump, model); + } +}; + +/* -------------------------------------------------------------------------- */ +class PyResidual : public Residual { +public: + using Residual::Residual; + + void computeResidual(GridBase& strain_increment) override { + PYBIND11_OVERLOAD_PURE(void, Residual, computeResidual, strain_increment); + } + + void computeStress(GridBase& strain_increment) override { + PYBIND11_OVERLOAD_PURE(void, Residual, computeStress, strain_increment); + } + + void updateState(GridBase& converged_strain_increment) override { + PYBIND11_OVERLOAD_PURE(void, Residual, updateState, + converged_strain_increment); + } + + const GridBase& getVector() const override { + PYBIND11_OVERLOAD_PURE(const GridBase&, Residual, getVector); + } + + const GridBase& getPlasticStrain() const override { + PYBIND11_OVERLOAD_PURE(const GridBase&, Residual, getPlasticStrain); + } + + + const GridBase& getStress() const override { + PYBIND11_OVERLOAD_PURE(const GridBase&, Residual, getStress); + } + + void + computeResidualDisplacement(GridBase& strain_increment) override { + PYBIND11_OVERLOAD_PURE(void, Residual, computeResidualDisplacement, + strain_increment); + } +}; + +/* -------------------------------------------------------------------------- */ + +} // namespace wrap +/* -------------------------------------------------------------------------- */ +} // namespace tamaas