diff --git a/python/py_mesh.cc b/python/py_mesh.cc index 0d9e265a5..9fa3dc05f 100644 --- a/python/py_mesh.cc +++ b/python/py_mesh.cc @@ -1,245 +1,274 @@ /** * Copyright (©) 2019-2023 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * This file is part of Akantu * * Akantu 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. * * Akantu 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 Akantu. If not, see <http://www.gnu.org/licenses/>. */ /* -------------------------------------------------------------------------- */ #include "aka_config.hh" /* -------------------------------------------------------------------------- */ #include "py_aka_array.hh" /* -------------------------------------------------------------------------- */ +#include <element_type_map.hh> +#include <fe_engine.hh> #include <mesh.hh> #include <mesh_accessor.hh> #include <mesh_utils.hh> /* -------------------------------------------------------------------------- */ #include <pybind11/pybind11.h> #include <pybind11/stl.h> /* -------------------------------------------------------------------------- */ namespace py = pybind11; /* -------------------------------------------------------------------------- */ namespace akantu { namespace { /* ------------------------------------------------------------------------ */ template <typename T> auto register_element_type_map_array(py::module & mod, const std::string & name) { auto element_type_map_class = py::class_<ElementTypeMapArray<T>, std::shared_ptr<ElementTypeMapArray<T>>>( mod, ("ElementTypeMapArray" + name).c_str()) .def(py::init<const ID &, const ID &>(), py::arg("id") = "by_element_type_array", py::arg("parent_id") = "no_parent") .def( "__call__", [](ElementTypeMapArray<T> & self, ElementType type, GhostType ghost_type) -> decltype(auto) { return self(type, ghost_type); }, py::arg("type"), py::arg("ghost_type") = _not_ghost, py::return_value_policy::reference, py::keep_alive<0, 1>()) .def( "elementTypes", - [](ElementTypeMapArray<T> & self, UInt _dim, + [](ElementTypeMapArray<T> & self, Int _dim, GhostType _ghost_type, ElementKind _kind) -> std::vector<ElementType> { auto types = self.elementTypes(_dim, _ghost_type, _kind); std::vector<ElementType> _types; for (auto && t : types) { _types.push_back(t); } return _types; }, py::arg("dim") = _all_dimensions, py::arg("ghost_type") = _not_ghost, py::arg("kind") = _ek_regular) .def( "initialize", [](ElementTypeMapArray<T> & self, const Mesh & mesh, GhostType ghost_type, Int nb_component, Int spatial_dimension, ElementKind element_kind, bool with_nb_element, bool with_nb_nodes_per_element, T default_value, bool do_not_default) { self.initialize( mesh, _ghost_type = ghost_type, _nb_component = nb_component, _spatial_dimension = (spatial_dimension == -2 ? mesh.getSpatialDimension() : spatial_dimension), _element_kind = element_kind, _with_nb_element = with_nb_element, _with_nb_nodes_per_element = with_nb_nodes_per_element, _default_value = default_value, _do_not_default = do_not_default); }, - py::arg("mesh"), py::arg("ghost_type") = _casper, + py::arg("mesh"), py::kw_only(), py::arg("ghost_type") = _casper, + py::arg("nb_component") = 1, py::arg("spatial_dimension") = -2, + py::arg("element_kind") = _ek_not_defined, + py::arg("with_nb_element") = false, + py::arg("with_nb_nodes_per_element") = false, + py::arg("default_value") = T{}, + py::arg("do_not_default") = false) + .def( + "initialize", + [](ElementTypeMapArray<T> & self, const FEEngine & fe_engine, + GhostType ghost_type, Int nb_component, + Int spatial_dimension, ElementKind element_kind, + bool with_nb_element, bool with_nb_nodes_per_element, + T default_value, bool do_not_default) { + self.initialize( + fe_engine, _ghost_type = ghost_type, + _nb_component = nb_component, + _spatial_dimension = + (spatial_dimension == -2 + ? fe_engine.getMesh().getSpatialDimension() + : spatial_dimension), + _element_kind = element_kind, + _with_nb_element = with_nb_element, + _with_nb_nodes_per_element = with_nb_nodes_per_element, + _default_value = default_value, + _do_not_default = do_not_default); + }, + py::arg("mesh"), py::kw_only(), py::arg("ghost_type") = _casper, py::arg("nb_component") = 1, py::arg("spatial_dimension") = -2, py::arg("element_kind") = _ek_not_defined, py::arg("with_nb_element") = false, py::arg("with_nb_nodes_per_element") = false, py::arg("default_value") = T{}, py::arg("do_not_default") = false); return element_type_map_class; } } // namespace /* -------------------------------------------------------------------------- */ void register_mesh(py::module & mod) { py::class_<Mesh::PeriodicSlaves>(mod, "PeriodicSlaves") .def( "__iter__", [](Mesh::PeriodicSlaves & _this) { return py::make_iterator(_this.begin(), _this.end()); }, py::keep_alive<0, 1>()); py::class_<MeshData>(mod, "MeshData") .def( "getElementalDataUInt", [](MeshData & _this, const ID & name) -> decltype(auto) { return _this.getElementalData<UInt>(name); }, py::return_value_policy::reference) .def( "getElementalDataReal", [](MeshData & _this, const ID & name) -> decltype(auto) { return _this.getElementalData<Real>(name); }, py::return_value_policy::reference); py::class_<Mesh, GroupManager, Dumpable, MeshData>(mod, "Mesh", py::multiple_inheritance()) .def(py::init<Int, const ID &>(), py::arg("spatial_dimension"), py::arg("id") = "mesh") .def("read", &Mesh::read, py::arg("filename"), py::arg("mesh_io_type") = _miot_auto, "read the mesh from a file") .def( "getNodes", [](Mesh & self) -> decltype(auto) { return self.getNodes(); }, py::return_value_policy::reference) .def("getNbNodes", &Mesh::getNbNodes) .def( "getConnectivity", [](Mesh & self, ElementType type) -> decltype(auto) { return self.getConnectivity(type); }, py::return_value_policy::reference) .def( "getConnectivities", [](Mesh & self) -> decltype(auto) { return self.getConnectivities(); }, py::return_value_policy::reference) .def( "addConnectivityType", [](Mesh & self, ElementType type, GhostType ghost_type) -> void { self.addConnectivityType(type, ghost_type); }, py::arg("type"), py::arg("ghost_type") = _not_ghost) .def("distribute", [](Mesh & self) { self.distribute(); }) .def("isDistributed", [](const Mesh & self) { return self.isDistributed(); }) .def("fillNodesToElements", &Mesh::fillNodesToElements, py::arg("dimension") = _all_dimensions) .def("getAssociatedElements", [](Mesh & self, const Idx & node, py::list list) { Array<Element> elements; self.getAssociatedElements(node, elements); for (auto && element : elements) { list.append(element); } }) .def("makePeriodic", [](Mesh & self, const SpatialDirection & direction) { self.makePeriodic(direction); }) .def( "getNbElement", [](Mesh & self, const Int spatial_dimension, GhostType ghost_type, ElementKind kind) { return self.getNbElement(spatial_dimension, ghost_type, kind); }, py::kw_only(), py::arg("spatial_dimension") = _all_dimensions, py::arg("ghost_type") = _not_ghost, py::arg("kind") = _ek_not_defined) .def( "getNbElement", [](Mesh & self, ElementType type, GhostType ghost_type) { return self.getNbElement(type, ghost_type); }, py::kw_only(), py::arg("type"), py::arg("ghost_type") = _not_ghost) .def_static( "getSpatialDimension", [](ElementType & type) { return Mesh::getSpatialDimension(type); }) .def( "getDataReal", [](Mesh & _this, const ID & name, ElementType type, GhostType ghost_type) -> decltype(auto) { return _this.getData<Real>(name, type, ghost_type); }, py::arg("name"), py::arg("type"), py::arg("ghost_type") = _not_ghost, py::return_value_policy::reference) .def( "hasDataReal", [](Mesh & _this, const ID & name, ElementType type, GhostType ghost_type) -> bool { return _this.hasData<Real>(name, type, ghost_type); }, py::arg("name"), py::arg("type"), py::arg("ghost_type") = _not_ghost) .def("isPeriodic", [](const Mesh & _this) { return _this.isPeriodic(); }) .def("getPeriodicMaster", &Mesh::getPeriodicMaster) .def("getPeriodicSlaves", &Mesh::getPeriodicSlaves) .def("isPeriodicSlave", &Mesh::isPeriodicSlave) .def("isPeriodicMaster", &Mesh::isPeriodicMaster) .def( "getMeshFacets", [](const Mesh & self) -> const Mesh & { return self.getMeshFacets(); }, py::return_value_policy::reference) .def("initMeshFacets", &Mesh::initMeshFacets, py::arg("id") = "mesh_facets", py::return_value_policy::reference); /* ------------------------------------------------------------------------ */ py::class_<MeshUtils>(mod, "MeshUtils") .def_static("buildFacets", &MeshUtils::buildFacets); py::class_<MeshAccessor>(mod, "MeshAccessor") .def(py::init<Mesh &>(), py::arg("mesh")) .def( "resizeConnectivity", [](MeshAccessor & self, Int new_size, ElementType type, GhostType gt) -> void { self.resizeConnectivity(new_size, type, gt); }, py::arg("new_size"), py::arg("type"), py::arg("ghost_type") = _not_ghost) .def( "resizeNodes", [](MeshAccessor & self, Int new_size) -> void { self.resizeNodes(new_size); }, py::arg("new_size")) .def("makeReady", &MeshAccessor::makeReady); register_element_type_map_array<Real>(mod, "Real"); register_element_type_map_array<UInt>(mod, "UInt"); register_element_type_map_array<Int>(mod, "Int"); register_element_type_map_array<bool>(mod, "bool"); // register_element_type_map_array<std::string>(mod, "String"); } } // namespace akantu