diff --git a/python/py_akantu_pybind11_compatibility.hh b/python/py_akantu_pybind11_compatibility.hh new file mode 100644 index 000000000..ea512ea51 --- /dev/null +++ b/python/py_akantu_pybind11_compatibility.hh @@ -0,0 +1,11 @@ +#ifndef PY_AKANTU_PYBIND11_COMPATIBILITY_HH_ +#define PY_AKANTU_PYBIND11_COMPATIBILITY_HH_ + +#if not defined(PYBIND11_OVERRIDE) +#define PYBIND11_OVERRIDE PYBIND11_OVERLOAD +#define PYBIND11_OVERRIDE_NAME PYBIND11_OVERLOAD_NAME +#define PYBIND11_OVERRIDE_PURE PYBIND11_OVERLOAD_PURE +#define PYBIND11_OVERRIDE_PURE_NAME PYBIND11_OVERLOAD_PURE_NAME +#endif + +#endif // PY_AKANTU_PYBIND11_COMPATIBILITY_HH_ diff --git a/python/py_boundary_conditions.cc b/python/py_boundary_conditions.cc index 892ec0b84..9db4b44b5 100644 --- a/python/py_boundary_conditions.cc +++ b/python/py_boundary_conditions.cc @@ -1,97 +1,98 @@ /* -------------------------------------------------------------------------- */ #include "py_boundary_conditions.hh" #include "py_aka_array.hh" +#include "py_akantu_pybind11_compatibility.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ -//#include #include -//#include /* -------------------------------------------------------------------------- */ namespace py = pybind11; namespace akantu { -/* -------------------------------------------------------------------------- */ - -template -class PyDirichletFunctor : public daughter { -public: - /* Inherit the constructors */ - using daughter::daughter; - - /* Trampoline (need one for each virtual function) */ - void operator()(UInt node, Vector & flags, Vector & primal, - const Vector & coord) const override { - // NOLINTNEXTLINE - PYBIND11_OVERLOAD_NAME(void, daughter, "__call__", operator(), node, flags, - primal, coord); - } -}; -/* -------------------------------------------------------------------------- */ - -template -class PyNeumannFunctor : public daughter { -public: - /* Inherit the constructors */ - using daughter::daughter; - - /* Trampoline (need one for each virtual function) */ - void operator()(const IntegrationPoint & quad_point, Vector & dual, - const Vector & coord, - const Vector & normals) const override { - // NOLINTNEXTLINE - PYBIND11_OVERLOAD_PURE_NAME(void, daughter, "__call__", operator(), - quad_point, dual, coord, normals); +namespace { + /* ------------------------------------------------------------------------ */ + template + class PyDirichletFunctor : public daughter { + public: + /* Inherit the constructors */ + using daughter::daughter; + + /* Trampoline (need one for each virtual function) */ + void operator()(UInt node, Vector & flags, Vector & primal, + const Vector & coord) const override { + // NOLINTNEXTLINE + PYBIND11_OVERRIDE_NAME(void, daughter, "__call__", operator(), node, + flags, primal, coord); + } + }; + + /* ------------------------------------------------------------------------ */ + template + class PyNeumannFunctor : public daughter { + public: + /* Inherit the constructors */ + using daughter::daughter; + + /* Trampoline (need one for each virtual function) */ + void operator()(const IntegrationPoint & quad_point, Vector & dual, + const Vector & coord, + const Vector & normals) const override { + // NOLINTNEXTLINE + PYBIND11_OVERRIDE_PURE_NAME(void, daughter, "__call__", operator(), + quad_point, dual, coord, normals); + } + }; + + /* ------------------------------------------------------------------------ */ + template + decltype(auto) register_dirichlet_functor(py::module mod, const char * name, + Constructor && cons) { + py::class_, + BC::Dirichlet::DirichletFunctor>(mod, name) + .def(cons); } -}; -/* -------------------------------------------------------------------------- */ - -template -decltype(auto) register_dirichlet_functor(py::module mod, const char * name, + /* ------------------------------------------------------------------------ */ + template + decltype(auto) register_neumann_functor(py::module mod, const char * name, Constructor && cons) { - py::class_, - BC::Dirichlet::DirichletFunctor>(mod, name) - .def(cons); -} -template -decltype(auto) register_neumann_functor(py::module mod, const char * name, - Constructor && cons) { - py::class_, BC::Neumann::NeumannFunctor>( - mod, name) - .def(cons); -} + py::class_, BC::Neumann::NeumannFunctor>( + mod, name) + .def(cons); + } +} // namespace /* -------------------------------------------------------------------------- */ void register_boundary_conditions(py::module & mod) { py::class_(mod, "BCFunctor"); py::class_, BC::Functor>(mod, "DirichletFunctor") .def(py::init()) .def(py::init()); py::class_, BC::Functor>( mod, "NeumannFunctor") .def(py::init()); register_dirichlet_functor( mod, "FixedValue", py::init()); register_dirichlet_functor( mod, "IncrementValue", py::init()); register_dirichlet_functor( mod, "Increment", py::init &>()); register_neumann_functor( mod, "FromHigherDim", py::init &>()); register_neumann_functor( mod, "FromSameDim", py::init &>()); register_neumann_functor(mod, "FreeBoundary", py::init()); } } // namespace akantu diff --git a/python/py_material.cc b/python/py_material.cc index e374fe7d9..2d074e8c0 100644 --- a/python/py_material.cc +++ b/python/py_material.cc @@ -1,182 +1,178 @@ /* -------------------------------------------------------------------------- */ +#include "py_akantu_pybind11_compatibility.hh" #include "py_aka_array.hh" /* -------------------------------------------------------------------------- */ #include #if defined(AKANTU_COHESIVE_ELEMENT) #include #endif #include /* -------------------------------------------------------------------------- */ #include #include #include /* -------------------------------------------------------------------------- */ namespace py = pybind11; /* -------------------------------------------------------------------------- */ -#if not defined(PYBIND11_OVERRIDE) -#define PYBIND11_OVERRIDE PYBIND11_OVERLOAD -#define PYBIND11_OVERRIDE_PURE PYBIND11_OVERLOAD_PURE -#endif - namespace akantu { namespace { template class PyMaterial : public _Material { public: /* Inherit the constructors */ using _Material::_Material; ~PyMaterial() override = default; void initMaterial() override { // NOLINTNEXTLINE PYBIND11_OVERRIDE(void, _Material, initMaterial, ); }; void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost) override { // NOLINTNEXTLINE PYBIND11_OVERRIDE_PURE(void, _Material, computeStress, el_type, ghost_type); } void computeTangentModuli(ElementType el_type, Array & tangent_matrix, GhostType ghost_type = _not_ghost) override { // NOLINTNEXTLINE PYBIND11_OVERRIDE(void, _Material, computeTangentModuli, el_type, tangent_matrix, ghost_type); } void computePotentialEnergy(ElementType el_type) override { // NOLINTNEXTLINE PYBIND11_OVERRIDE(void, _Material, computePotentialEnergy, el_type); } Real getPushWaveSpeed(const Element & element) const override { // NOLINTNEXTLINE PYBIND11_OVERRIDE(Real, _Material, getPushWaveSpeed, element); } Real getShearWaveSpeed(const Element & element) const override { // NOLINTNEXTLINE PYBIND11_OVERRIDE(Real, _Material, getShearWaveSpeed, element); } template void registerInternal(const std::string & name, UInt nb_component) { auto && internal = std::make_shared>(name, *this); AKANTU_DEBUG_INFO("alloc internal " << name << " " << &this->internals[name]); internal->initialize(nb_component); this->internals[name] = internal; } protected: std::map> internals; }; /* ------------------------------------------------------------------------ */ template void register_internal_field(py::module & mod, const std::string & name) { py::class_, ElementTypeMapArray, std::shared_ptr>>( mod, ("InternalField" + name).c_str()); } /* ------------------------------------------------------------------------ */ template decltype(auto) register_material_classes(py::module & mod, const std::string & name) { return py::class_<_Material, Material, Parsable, PyMaterial<_Material>>( mod, name.c_str(), py::multiple_inheritance()) .def(py::init()); } } // namespace /* -------------------------------------------------------------------------- */ void register_material(py::module & mod) { py::class_(mod, "MaterialFactory") .def_static( "getInstance", []() -> MaterialFactory & { return Material::getFactory(); }, py::return_value_policy::reference) .def("registerAllocator", [](MaterialFactory & self, const std::string id, py::function func) { self.registerAllocator( id, [func, id](UInt dim, const ID & /*unused*/, SolidMechanicsModel & model, const ID & option) -> std::unique_ptr { py::object obj = func(dim, id, model, option); auto & ptr = py::cast(obj); obj.release(); return std::unique_ptr(&ptr); }); }) .def("getPossibleAllocators", &MaterialFactory::getPossibleAllocators); register_internal_field(mod, "Real"); register_internal_field(mod, "UInt"); py::class_>( mod, "Material", py::multiple_inheritance()) .def(py::init()) .def( "getGradU", [](Material & self, ElementType el_type, GhostType ghost_type = _not_ghost) -> decltype(auto) { return self.getGradU(el_type, ghost_type); }, py::arg("el_type"), py::arg("ghost_type") = _not_ghost, py::return_value_policy::reference) .def( "getStress", [](Material & self, ElementType el_type, GhostType ghost_type = _not_ghost) -> decltype(auto) { return self.getStress(el_type, ghost_type); }, py::arg("el_type"), py::arg("ghost_type") = _not_ghost, py::return_value_policy::reference) .def( "getPotentialEnergy", [](Material & self, ElementType el_type) -> decltype(auto) { return self.getPotentialEnergy(el_type); }, py::return_value_policy::reference) .def("initMaterial", &Material::initMaterial) .def("getModel", &Material::getModel) .def("registerInternalReal", [](Material & self, const std::string & name, UInt nb_component) { return dynamic_cast &>(self) .registerInternal(name, nb_component); }) .def("registerInternalUInt", [](Material & self, const std::string & name, UInt nb_component) { return dynamic_cast &>(self) .registerInternal(name, nb_component); }) .def( "getInternalReal", [](Material & self, const ID & id) -> decltype(auto) { return self.getInternal(id); }, py::arg("id"), py::return_value_policy::reference) .def( "getInternalUInt", [](Material & self, const ID & id) -> decltype(auto) { return self.getInternal(id); }, py::arg("id"), py::return_value_policy::reference) .def( "getElementFilter", [](Material & self) -> decltype(auto) { return self.getElementFilter(); }, py::return_value_policy::reference); register_material_classes>(mod, "MaterialElastic2D"); register_material_classes>(mod, "MaterialElastic3D"); } } // namespace akantu diff --git a/python/py_material_selector.cc b/python/py_material_selector.cc index f05d1d244..81a58bc43 100644 --- a/python/py_material_selector.cc +++ b/python/py_material_selector.cc @@ -1,85 +1,86 @@ +/* -------------------------------------------------------------------------- */ #include "py_material_selector.hh" - +#include "py_akantu_pybind11_compatibility.hh" /* -------------------------------------------------------------------------- */ #include #include #if defined(AKANTU_COHESIVE_ELEMENT) #include #include #endif /* -------------------------------------------------------------------------- */ #include #include #include /* -------------------------------------------------------------------------- */ namespace py = pybind11; /* -------------------------------------------------------------------------- */ namespace akantu { namespace { template class PyMaterialSelector : public Base { public: /* Inherit the constructors */ using Base::Base; ~PyMaterialSelector() override = default; UInt operator()(const Element & element) override { // NOLINTNEXTLINE PYBIND11_OVERRIDE_NAME(UInt, MaterialSelector, "__call__", operator(), element); } }; template decltype(auto) register_material_selectors(py::module & mod, const std::string & class_name) { return py::class_, std::shared_ptr>( mod, class_name.c_str()); } } // namespace void register_material_selector(py::module & mod) { - py::class_, - std::shared_ptr>(mod, "MaterialSelector") + py::class_, + std::shared_ptr>(mod, "MaterialSelector") .def(py::init()) .def("setFallback", [](MaterialSelector & self, UInt f) { self.setFallback(f); }) .def("setFallback", [](MaterialSelector & self, const std::shared_ptr & fallback_selector) { self.setFallback(fallback_selector); }) .def("__call__", &MaterialSelector::operator()); register_material_selectors( mod, "DefaultMaterialSelector") .def(py::init>()); register_material_selectors>( mod, "MeshDataMaterialSelectorString") .def(py::init(), py::arg("name"), py::arg("model"), py::arg("first_index") = 1); #if defined(AKANTU_COHESIVE_ELEMENT) register_material_selectors( mod, "DefaultMaterialCohesiveSelector") .def(py::init()); register_material_selectors( mod, "MeshDataMaterialCohesiveSelector") .def(py::init()); register_material_selectors( mod, "MaterialCohesiveRulesSelector") .def(py::init(), py::arg("model"), py::arg("rules"), py::arg("mesh_data_id") = "physical_names"); #endif } } // namespace akantu