11#include < polyfem/State.hpp>
22#include < polyfem/AssemblerUtils.hpp>
33#include < polyfem/Logger.hpp>
4+ #include < polyfem/MeshUtils.hpp>
45
56#include < geogram/basic/command_line.h>
67#include < geogram/basic/command_line_args.h>
1213
1314#include < pybind11/pybind11.h>
1415#include < pybind11/eigen.h>
16+ #include < pybind11/functional.h>
1517
1618namespace py = pybind11;
1719
@@ -60,10 +62,6 @@ PYBIND11_MODULE(polyfempy, m) {
6062 for (auto &a : polyfem::AssemblerUtils::instance ().tensor_assemblers ())
6163 ta.attr (a.c_str ()) = a;
6264
63-
64- // TODO:
65- // load mesh with lambda and V, F
66-
6765 py::class_<polyfem::State>(m, " Solver" )
6866 .def (py::init<>())
6967 .def (" settings" , [](polyfem::State &s, const std::string &json) {
@@ -81,17 +79,42 @@ PYBIND11_MODULE(polyfempy, m) {
8179 init_globals ();
8280 s.load_mesh ();
8381 }, " Loads a mesh from the 'mesh' field of the json and 'bc_tag' if any bc tags" )
84- .def (" load_mesh" , [](polyfem::State &s, std::string &path) {
82+ .def (" load_mesh" , [](polyfem::State &s, const std::string &path) {
8583 init_globals ();
8684 s.args [" mesh" ] = path;
8785 s.load_mesh ();
8886 }, " Loads a mesh from the path and 'bc_tag' from the json if any bc tags" )
89- .def (" load_mesh" , [](polyfem::State &s, std::string &path, std::string &bc_tag) {
87+ .def (" load_mesh" , [](polyfem::State &s, const std::string &path, const std::string &bc_tag) {
9088 init_globals ();
9189 s.args [" mesh" ] = path;
9290 s.args [" bc_tag" ] = bc_tag;
9391 s.load_mesh ();
9492 }, " Loads a mesh and bc_tags from path" )
93+ .def (" set_mesh" , [](polyfem::State &s, const Eigen::MatrixXd &V, const Eigen::MatrixXi &F) {
94+ init_globals ();
95+
96+ GEO::Mesh M;
97+ if (V.cols () == 2 )
98+ polyfem::to_geogram_mesh (V, F, M);
99+ else
100+ polyfem::to_geogram_mesh_3d (V, F, M);
101+ s.load_mesh (M, [](const polyfem::RowVectorNd&){ return -1 ; }, true );
102+ }, " Loads a mesh from vertices and connectivity" )
103+
104+
105+ .def (" set_boundary_side_set_from_bary" , [](polyfem::State &s, const std::function<int (const polyfem::RowVectorNd&)> &boundary_marker) {
106+ init_globals ();
107+ s.mesh ->compute_boundary_ids (boundary_marker);
108+ }, " Sets the side set for the boundary conditions, the functions takes the barycenter of the boundary (edge or face)" )
109+ .def (" set_boundary_side_set_from_bary_and_boundary" , [](polyfem::State &s, const std::function<int (const polyfem::RowVectorNd&, bool )> &boundary_marker) {
110+ init_globals ();
111+ s.mesh ->compute_boundary_ids (boundary_marker);
112+ }, " Sets the side set for the boundary conditions, the functions takes the barycenter of the boundary (edge or face) and a flag that says if the element is boundary" )
113+ .def (" set_boundary_side_set_from_v_ids" , [](polyfem::State &s, const std::function<int (const std::vector<int >&, bool )> &boundary_marker) {
114+ init_globals ();
115+ s.mesh ->compute_boundary_ids (boundary_marker);
116+ }, " Sets the side set for the boundary conditions, the functions takes the sorted list of vertex id and a flag that says if the element is boundary" )
117+
95118
96119 .def (" set_rhs" , [](polyfem::State &s, std::string &path) {
97120 init_globals ();
@@ -143,7 +166,39 @@ PYBIND11_MODULE(polyfempy, m) {
143166
144167 s.interpolate_function (points.rows (), s.sol , fun, boundary_only);
145168 return py::make_tuple (points, tets, fun);
146- }, " returns the solution on a densly sampled mesh, use 'vismesh_rel_area' to control density" ,
147- py::arg (" boundary_only" ) = bool (false ));
169+ }, " returns the solution on a densly sampled mesh, use 'vismesh_rel_area' to control density" , py::arg (" boundary_only" ) = bool (false ))
170+ .def (" get_stresses" , [](polyfem::State &s, bool boundary_only) {
171+ Eigen::MatrixXd points;
172+ Eigen::MatrixXi tets;
173+ Eigen::MatrixXd discr;
174+ Eigen::MatrixXd fun;
175+
176+ s.build_vis_mesh (points, tets, discr);
177+ s.compute_tensor_value (points.rows (), s.sol , fun, boundary_only);
178+
179+ return fun;
180+ }, " returns the stress tensor on a densly sampled mesh, use 'vismesh_rel_area' to control density" , py::arg (" boundary_only" ) = bool (false ))
181+ .def (" get_sampled_mises" , [](polyfem::State &s, bool boundary_only) {
182+ Eigen::MatrixXd points;
183+ Eigen::MatrixXi tets;
184+ Eigen::MatrixXd discr;
185+ Eigen::MatrixXd fun;
186+
187+ s.build_vis_mesh (points, tets, discr);
188+ s.compute_scalar_value (points.rows (), s.sol , fun, boundary_only);
189+
190+ return fun;
191+ }, " returns the von mises stresses on a densly sampled mesh, use 'vismesh_rel_area' to control density" , py::arg (" boundary_only" ) = bool (false ))
192+ .def (" get_sampled_mises_avg" , [](polyfem::State &s, bool boundary_only) {
193+ Eigen::MatrixXd points;
194+ Eigen::MatrixXi tets;
195+ Eigen::MatrixXd discr;
196+ Eigen::MatrixXd fun, tfun;
197+
198+ s.build_vis_mesh (points, tets, discr);
199+ s.average_grad_based_function (points.rows (), s.sol , fun, tfun, boundary_only);
200+
201+ return py::make_tuple (fun, tfun);
202+ }, " returns the von mises stresses and stress tensor averaged around a vertex on a densly sampled mesh, use 'vismesh_rel_area' to control density" , py::arg (" boundary_only" ) = bool (false ));
148203
149204}
0 commit comments