15
15
#include < pybind11/eigen.h>
16
16
#include < pybind11/functional.h>
17
17
#include < pybind11/stl.h>
18
+ #include < pybind11/iostream.h>
18
19
19
20
namespace py = pybind11;
20
21
@@ -48,7 +49,7 @@ namespace {
48
49
GEO::CmdLine::import_arg_group (" pre" );
49
50
GEO::CmdLine::import_arg_group (" algo" );
50
51
51
- state.init_logger (" " , 2 , false );
52
+ state.init_logger (std::cout , 2 );
52
53
53
54
initialized = true ;
54
55
}
@@ -57,6 +58,8 @@ namespace {
57
58
}
58
59
59
60
PYBIND11_MODULE (polyfempy, m) {
61
+ add_ostream_redirect (m);
62
+
60
63
const auto &sa = py::class_<ScalarAssemblers>(m, " ScalarFormulations" );
61
64
for (auto &a : polyfem::AssemblerUtils::instance ().scalar_assemblers ())
62
65
sa.attr (a.c_str ()) = a;
@@ -71,6 +74,7 @@ PYBIND11_MODULE(polyfempy, m) {
71
74
72
75
.def (" settings" , [](polyfem::State &self, const py::object &json) {
73
76
init_globals (self);
77
+ py::scoped_ostream_redirect output;
74
78
const std::string json_string = py::str (json);
75
79
self.init (json::parse (json_string));
76
80
},
@@ -79,6 +83,7 @@ PYBIND11_MODULE(polyfempy, m) {
79
83
80
84
.def (" set_log_level" , [](polyfem::State &s, int log_level) {
81
85
init_globals (s);
86
+ py::scoped_ostream_redirect output;
82
87
log_level = std::max (0 , std::min (6 , log_level));
83
88
spdlog::set_level (static_cast <spdlog::level::level_enum>(log_level));
84
89
},
@@ -87,19 +92,22 @@ PYBIND11_MODULE(polyfempy, m) {
87
92
88
93
.def (" load_mesh_from_settings" , [](polyfem::State &s) {
89
94
init_globals (s);
95
+ py::scoped_ostream_redirect output;
90
96
s.load_mesh ();
91
97
},
92
98
" Loads a mesh from the 'mesh' field of the json and 'bc_tag' if any bc tags" )
93
99
94
100
.def (" load_mesh_from_path" , [](polyfem::State &s, const std::string &path) {
95
101
init_globals (s);
102
+ py::scoped_ostream_redirect output;
96
103
s.args [" mesh" ] = path;
97
104
s.load_mesh ();
98
105
},
99
106
" Loads a mesh from the path and 'bc_tag' from the json if any bc tags" ,
100
107
py::arg (" path" ))
101
108
.def (" load_mesh_from_path_and_tags" , [](polyfem::State &s, const std::string &path, const std::string &bc_tag) {
102
109
init_globals (s);
110
+ py::scoped_ostream_redirect output;
103
111
s.args [" mesh" ] = path;
104
112
s.args [" bc_tag" ] = bc_tag;
105
113
s.load_mesh ();
@@ -108,6 +116,7 @@ PYBIND11_MODULE(polyfempy, m) {
108
116
py::arg (" path" ), py::arg (" bc_tag_path" ))
109
117
.def (" set_mesh" , [](polyfem::State &s, const Eigen::MatrixXd &V, const Eigen::MatrixXi &F) {
110
118
init_globals (s);
119
+ py::scoped_ostream_redirect output;
111
120
112
121
if (V.cols () == 2 )
113
122
s.mesh = std::make_unique<polyfem::Mesh2D>();
@@ -123,18 +132,21 @@ PYBIND11_MODULE(polyfempy, m) {
123
132
124
133
.def (" set_boundary_side_set_from_bary" , [](polyfem::State &s, const std::function<int (const polyfem::RowVectorNd&)> &boundary_marker) {
125
134
init_globals (s);
135
+ py::scoped_ostream_redirect output;
126
136
s.mesh ->compute_boundary_ids (boundary_marker);
127
137
},
128
138
" Sets the side set for the boundary conditions, the functions takes the barycenter of the boundary (edge or face)" ,
129
139
py::arg (" boundary_marker" ))
130
140
.def (" set_boundary_side_set_from_bary_and_boundary" , [](polyfem::State &s, const std::function<int (const polyfem::RowVectorNd&, bool )> &boundary_marker) {
131
141
init_globals (s);
142
+ py::scoped_ostream_redirect output;
132
143
s.mesh ->compute_boundary_ids (boundary_marker);
133
144
},
134
145
" 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" ,
135
146
py::arg (" boundary_marker" ))
136
147
.def (" set_boundary_side_set_from_v_ids" , [](polyfem::State &s, const std::function<int (const std::vector<int >&, bool )> &boundary_marker) {
137
148
init_globals (s);
149
+ py::scoped_ostream_redirect output;
138
150
s.mesh ->compute_boundary_ids (boundary_marker);
139
151
},
140
152
" 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" ,
@@ -143,23 +155,33 @@ PYBIND11_MODULE(polyfempy, m) {
143
155
144
156
.def (" set_rhs_from_path" , [](polyfem::State &s, std::string &path) {
145
157
init_globals (s);
158
+ py::scoped_ostream_redirect output;
146
159
s.args [" rhs_path" ] = path;
147
160
},
148
161
" Loads the rhs from a file" ,
149
162
py::arg (" path" ))
150
163
.def (" set_rhs" , [](polyfem::State &s, const Eigen::MatrixXd &rhs) {
151
164
init_globals (s);
165
+ py::scoped_ostream_redirect output;
152
166
s.rhs_in = rhs;
153
167
},
154
168
" Sets the rhs" ,
155
169
py::arg (" matrix" ))
156
170
157
171
158
172
159
- .def (" solve " ,[](polyfem::State &s) {
173
+ .def (" compute_mesh_stats " ,[](polyfem::State &s) {
160
174
init_globals (s);
175
+ py::scoped_ostream_redirect output;
161
176
162
177
s.compute_mesh_stats ();
178
+ },
179
+ " compute statistics" )
180
+
181
+
182
+ .def (" solve" ,[](polyfem::State &s) {
183
+ init_globals (s);
184
+ py::scoped_ostream_redirect output;
163
185
164
186
s.build_basis ();
165
187
@@ -173,25 +195,31 @@ PYBIND11_MODULE(polyfempy, m) {
173
195
},
174
196
" solve the pde" )
175
197
176
- .def (" compute_errors" ,
177
- &polyfem::State::compute_errors,
178
- " compute the error" )
198
+ .def (" compute_errors" ,[](polyfem::State &s) {
199
+ init_globals (s);
200
+ py::scoped_ostream_redirect output;
201
+
202
+ s.compute_errors ();
203
+ },
204
+ " compute the error" )
179
205
180
206
.def (" get_log" , [](polyfem::State &s) {
207
+ py::scoped_ostream_redirect output;
181
208
std::stringstream ss;
182
209
s.save_json (ss);
183
210
return ss.str ();
184
211
},
185
212
" gets the log as json" )
186
213
187
- .def (" export_data" , & polyfem::State:: export_data, " exports all data specified in the settings" )
188
- .def (" export_vtu" , & polyfem::State:: save_vtu, " exports the solution as vtu" , py::arg (" path" ))
189
- .def (" export_wire" , & polyfem::State:: save_wire, " exports wireframe of the mesh" , py::arg (" path" ), py::arg (" isolines" ) = false )
214
+ .def (" export_data" , []( polyfem::State &s) { py::scoped_ostream_redirect output; s. export_data (); } , " exports all data specified in the settings" )
215
+ .def (" export_vtu" , []( polyfem::State &s, std::string &path) { py::scoped_ostream_redirect output; s. save_vtu (path); } , " exports the solution as vtu" , py::arg (" path" ))
216
+ .def (" export_wire" , []( polyfem::State &s, std::string &path, bool isolines) { py::scoped_ostream_redirect output; s. save_wire (path, isolines); } , " exports wireframe of the mesh" , py::arg (" path" ), py::arg (" isolines" ) = false )
190
217
191
218
192
219
.def (" get_solution" , [](const polyfem::State &s) { return s.sol ;}, " returns the solution" )
193
220
.def (" get_pressure" , [](const polyfem::State &s) { return s.pressure ;}, " returns the pressure" )
194
221
.def (" get_sampled_solution" , [](polyfem::State &s, bool boundary_only) {
222
+ py::scoped_ostream_redirect output;
195
223
Eigen::MatrixXd points;
196
224
Eigen::MatrixXi tets;
197
225
Eigen::MatrixXd discr;
@@ -213,6 +241,7 @@ PYBIND11_MODULE(polyfempy, m) {
213
241
py::arg (" boundary_only" ) = bool (false ))
214
242
215
243
.def (" get_stresses" , [](polyfem::State &s, bool boundary_only) {
244
+ py::scoped_ostream_redirect output;
216
245
Eigen::MatrixXd points;
217
246
Eigen::MatrixXi tets;
218
247
Eigen::MatrixXd discr;
@@ -232,6 +261,7 @@ PYBIND11_MODULE(polyfempy, m) {
232
261
py::arg (" boundary_only" ) = bool (false ))
233
262
234
263
.def (" get_sampled_mises" , [](polyfem::State &s, bool boundary_only) {
264
+ py::scoped_ostream_redirect output;
235
265
Eigen::MatrixXd points;
236
266
Eigen::MatrixXi tets;
237
267
Eigen::MatrixXd discr;
@@ -251,6 +281,7 @@ PYBIND11_MODULE(polyfempy, m) {
251
281
py::arg (" boundary_only" ) = bool (false ))
252
282
253
283
.def (" get_sampled_mises_avg" , [](polyfem::State &s, bool boundary_only) {
284
+ py::scoped_ostream_redirect output;
254
285
Eigen::MatrixXd points;
255
286
Eigen::MatrixXi tets;
256
287
Eigen::MatrixXd discr;
@@ -274,6 +305,7 @@ PYBIND11_MODULE(polyfempy, m) {
274
305
275
306
// //////////////////////////////////////////////////////////////////////////////////////////
276
307
.def (" get_sampled_points_frames" , [](polyfem::State &s) {
308
+ py::scoped_ostream_redirect output;
277
309
assert (!s.solution_frames .empty ());
278
310
279
311
std::vector<Eigen::MatrixXd> pts;
@@ -288,6 +320,7 @@ PYBIND11_MODULE(polyfempy, m) {
288
320
" returns the points frames for a time dependent problem on a densly sampled mesh, use 'vismesh_rel_area' to control density" )
289
321
290
322
.def (" get_sampled_connectivity_frames" , [](polyfem::State &s) {
323
+ py::scoped_ostream_redirect output;
291
324
assert (!s.solution_frames .empty ());
292
325
293
326
std::vector<Eigen::MatrixXi> tets;
@@ -302,6 +335,7 @@ PYBIND11_MODULE(polyfempy, m) {
302
335
303
336
304
337
.def (" get_sampled_solution_frames" , [](polyfem::State &s) {
338
+ py::scoped_ostream_redirect output;
305
339
assert (!s.solution_frames .empty ());
306
340
307
341
std::vector<Eigen::MatrixXd> fun;
@@ -316,6 +350,7 @@ PYBIND11_MODULE(polyfempy, m) {
316
350
" returns the solution frames for a time dependent problem on a densly sampled mesh, use 'vismesh_rel_area' to control density" )
317
351
318
352
.def (" get_sampled_mises_frames" , [](polyfem::State &s) {
353
+ py::scoped_ostream_redirect output;
319
354
assert (!s.solution_frames .empty ());
320
355
321
356
std::vector<Eigen::MatrixXd> mises;
@@ -328,6 +363,7 @@ PYBIND11_MODULE(polyfempy, m) {
328
363
" returns the von mises stresses frames on a densly sampled mesh, use 'vismesh_rel_area' to control density" )
329
364
330
365
.def (" get_sampled_mises_avg_frames" , [](polyfem::State &s) {
366
+ py::scoped_ostream_redirect output;
331
367
assert (!s.solution_frames .empty ());
332
368
333
369
std::vector<Eigen::MatrixXd> mises;
@@ -341,6 +377,7 @@ PYBIND11_MODULE(polyfempy, m) {
341
377
342
378
343
379
.def (" get_boundary_sidesets" , [](polyfem::State &s) {
380
+ py::scoped_ostream_redirect output;
344
381
Eigen::MatrixXd points;
345
382
Eigen::MatrixXi faces;
346
383
Eigen::MatrixXd sidesets;
0 commit comments