Skip to content

Commit 9aa3bb9

Browse files
committed
fixed timedependent simulation
1 parent 03842f4 commit 9aa3bb9

File tree

4 files changed

+159
-4
lines changed

4 files changed

+159
-4
lines changed

cmake/PolyfemPythonDownloadExternal.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ endfunction()
2727
function(polyfem_python_download_polyfem)
2828
polyfem_python_download_project(polyfem
2929
GIT_REPOSITORY https://github.com/polyfem/polyfem.git
30-
GIT_TAG 41005711400c3e5f0957f70d9f071b1a45d2d123
30+
GIT_TAG c679ec3b52e8be63d4e092fd2f315432045a73f5
3131
)
3232
endfunction()
3333

setup.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ def run(self):
2424
raise RuntimeError(
2525
"CMake must be installed to build the following extensions: , ".join(e.name for e in self.extensions))
2626

27-
# if platform.system() == "Windows":
27+
# self.debug = True
28+
2829
cmake_version = LooseVersion(re.search(r'version\s*([\d.]+)', out.decode()).group(1))
2930
if cmake_version < '3.1.0':
30-
raise RuntimeError("CMake >= 3.1.0 is required on Windows")
31+
raise RuntimeError("CMake >= 3.1.0 is required")
3132

3233
for ext in self.extensions:
3334
self.build_extension(ext)

src/binding.cpp

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <pybind11/pybind11.h>
1515
#include <pybind11/eigen.h>
1616
#include <pybind11/functional.h>
17+
#include <pybind11/stl.h>
1718

1819
namespace py = pybind11;
1920

@@ -111,6 +112,11 @@ PYBIND11_MODULE(polyfempy, m) {
111112
else
112113
polyfem::to_geogram_mesh_3d(V, F, M);
113114
s.load_mesh(M, [](const polyfem::RowVectorNd&){ return -1; }, true);
115+
116+
double boundary_id_threshold = s.args["boundary_id_threshold"];
117+
if(boundary_id_threshold <= 0)
118+
boundary_id_threshold = s.mesh->is_volume() ? 1e-2 : 1e-7;
119+
s.mesh->compute_boundary_ids(boundary_id_threshold);
114120
},
115121
"Loads a mesh from vertices and connectivity",
116122
py::arg("vertices"), py::arg("connectivity"))
@@ -162,7 +168,10 @@ PYBIND11_MODULE(polyfempy, m) {
162168
s.assemble_rhs();
163169
s.assemble_stiffness_mat();
164170

171+
s.solve_export_to_file = false;
172+
s.solution_frames.clear();
165173
s.solve_problem();
174+
s.solve_export_to_file = true;
166175
},
167176
"solve the pde")
168177

@@ -239,7 +248,80 @@ PYBIND11_MODULE(polyfempy, m) {
239248
return py::make_tuple(fun, tfun);
240249
},
241250
"returns the von mises stresses and stress tensor averaged around a vertex on a densly sampled mesh, use 'vismesh_rel_area' to control density",
242-
py::arg("boundary_only") = bool(false));
251+
py::arg("boundary_only") = bool(false))
252+
253+
254+
255+
256+
////////////////////////////////////////////////////////////////////////////////////////////
257+
.def("get_sampled_points_frames", [](polyfem::State &s) {
258+
assert(!s.solution_frames.empty());
259+
260+
std::vector<Eigen::MatrixXd> pts;
261+
262+
for(const auto &sol : s.solution_frames){
263+
pts.push_back(sol.points);
264+
}
265+
266+
267+
return pts;
268+
},
269+
"returns the points frames for a time dependent problem on a densly sampled mesh, use 'vismesh_rel_area' to control density")
270+
271+
.def("get_sampled_connectivity_frames", [](polyfem::State &s) {
272+
assert(!s.solution_frames.empty());
273+
274+
std::vector<Eigen::MatrixXi> tets;
275+
276+
for(const auto &sol : s.solution_frames)
277+
tets.push_back(sol.connectivity);
278+
279+
280+
return tets;
281+
},
282+
"returns the connectivity frames for a time dependent problem on a densly sampled mesh, use 'vismesh_rel_area' to control density")
283+
284+
285+
.def("get_sampled_solution_frames", [](polyfem::State &s) {
286+
assert(!s.solution_frames.empty());
287+
288+
std::vector<Eigen::MatrixXd> fun;
289+
290+
for(const auto &sol : s.solution_frames){
291+
fun.push_back(sol.solution);
292+
}
293+
294+
295+
return fun;
296+
},
297+
"returns the solution frames for a time dependent problem on a densly sampled mesh, use 'vismesh_rel_area' to control density")
298+
299+
.def("get_sampled_mises_frames", [](polyfem::State &s) {
300+
assert(!s.solution_frames.empty());
301+
302+
std::vector<Eigen::MatrixXd> mises;
303+
304+
for(const auto &sol : s.solution_frames)
305+
mises.push_back(sol.scalar_value);
306+
307+
return mises;
308+
},
309+
"returns the von mises stresses frames on a densly sampled mesh, use 'vismesh_rel_area' to control density")
310+
311+
.def("get_sampled_mises_avg_frames", [](polyfem::State &s) {
312+
assert(!s.solution_frames.empty());
313+
314+
std::vector<Eigen::MatrixXd> mises;
315+
316+
for(const auto &sol : s.solution_frames)
317+
mises.push_back(sol.scalar_value_avg);
318+
319+
return mises;
320+
},
321+
"returns the von mises stresses per frame averaged around a vertex on a densly sampled mesh, use 'vismesh_rel_area' to control density");
322+
323+
324+
243325

244326
solver.doc() = "Polyfem solver";
245327

tests/gravity.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import unittest
2+
3+
import numpy as np
4+
import polyfempy as pf
5+
from utils import plot
6+
7+
8+
class Gravity(unittest.TestCase):
9+
def test_run(self):
10+
n_pts = 3
11+
12+
extend = np.linspace(0, 1, n_pts)
13+
x, y = np.meshgrid(extend, extend, sparse=False, indexing='xy')
14+
pts = np.column_stack((x.ravel(), y.ravel()))
15+
16+
17+
# Create connectivity
18+
faces = np.ndarray([(n_pts-1)**2, 4],dtype=np.int32)
19+
20+
index = 0
21+
for i in range(n_pts-1):
22+
for j in range(n_pts-1):
23+
faces[index, :] = np.array([
24+
j + i * n_pts,
25+
j+1 + i * n_pts,
26+
j+1 + (i+1) * n_pts,
27+
j + (i+1) * n_pts
28+
])
29+
index = index + 1
30+
31+
# create settings
32+
settings = pf.Settings()
33+
settings.discr_order = 1
34+
35+
settings.set_material_params("E", 2100)
36+
settings.set_material_params("nu", 0.3)
37+
38+
# We use a linear material model
39+
settings.tensor_formulation = pf.TensorFormulations.LinearElasticity
40+
41+
problem = pf.Gravity()
42+
settings.set_problem(problem)
43+
44+
solver = pf.Solver()
45+
solver.settings(str(settings))
46+
47+
# This time we are using pts and faces instead of loading from the disk
48+
solver.set_mesh(pts, faces)
49+
50+
solver.solve()
51+
52+
#Animation frame, last one
53+
frame = -1
54+
55+
# Get the solution
56+
pts = solver.get_sampled_points_frames()
57+
tets = solver.get_sampled_connectivity_frames()
58+
disp = solver.get_sampled_solution_frames()
59+
60+
61+
# diplace the mesh
62+
vertices = pts[frame] + disp[frame]
63+
64+
# and get the stresses
65+
mises = solver.get_sampled_mises_avg_frames()
66+
67+
# finally plot
68+
plot(vertices, tets[frame], mises[frame])
69+
70+
71+
if __name__ == '__main__':
72+
unittest.main()

0 commit comments

Comments
 (0)