Skip to content
This repository was archived by the owner on Oct 22, 2025. It is now read-only.

Commit 12165c9

Browse files
committed
fix python binding
1 parent 8dda64a commit 12165c9

18 files changed

+939
-87
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"import numpy as np\n",
10+
"import plotly.figure_factory as ff\n",
11+
"import plotly.graph_objects as go\n",
12+
"from plotly.subplots import make_subplots\n",
13+
"import meshio, numpy, copy\n",
14+
"import meshplot as mp\n",
15+
"# import sys\n",
16+
"# import pathlib\n",
17+
"# sys.path.append(str(pathlib.Path(\"\").resolve().parent / \"build\" / \"release\" / \"python\")) # noqa\n",
18+
"\n",
19+
"from ipctk import *"
20+
]
21+
},
22+
{
23+
"cell_type": "code",
24+
"execution_count": null,
25+
"metadata": {},
26+
"outputs": [],
27+
"source": [
28+
"V = np.array([[0.5,0],[1.0,0],[1.5,0],[0.9,0.3],[1,0.1],[1.1,0.3],[1,-0.5]])\n",
29+
"E = np.array([[1,0],[2,1],[3,4],[4,5],[5,3],[0,6],[6,2]], dtype=int)\n",
30+
"F = np.array([])\n",
31+
"\n",
32+
"p = mp.plot(V, F, shading={\"width\": 200, \"height\": 200})\n",
33+
"p.add_points(V, shading={\"point_color\": \"green\", \"point_size\": 0.1})\n",
34+
"p.add_lines(V[E[:,0],:],V[E[:,1],:], shading={\"line_width\": 2})\n",
35+
"\n",
36+
"dhat=0.12\n",
37+
"param = ParameterType(dhat, 1, 0, 1, 0, 1, 200)\n",
38+
"mesh = CollisionMesh(V, E, F)"
39+
]
40+
},
41+
{
42+
"cell_type": "code",
43+
"execution_count": null,
44+
"metadata": {},
45+
"outputs": [],
46+
"source": [
47+
"# high order\n",
48+
"\n",
49+
"def potential_high_order(points):\n",
50+
" cs1 = SmoothCollisions2()\n",
51+
" cs1.use_high_order_quadrature = True\n",
52+
" cs1.build(mesh, points, param)\n",
53+
"\n",
54+
" B = SmoothPotential(param)\n",
55+
" # g = B.gradient(cs1, mesh, points)\n",
56+
"\n",
57+
" return B(cs1, mesh, points)"
58+
]
59+
},
60+
{
61+
"cell_type": "code",
62+
"execution_count": null,
63+
"metadata": {},
64+
"outputs": [],
65+
"source": [
66+
"cs1 = SmoothCollisions2()\n",
67+
"cs1.use_high_order_quadrature = True\n",
68+
"cs1.build(mesh, V, param)\n",
69+
"print(cs1.to_string(mesh, V, param))\n",
70+
"print(mesh.edges)"
71+
]
72+
},
73+
{
74+
"cell_type": "code",
75+
"execution_count": null,
76+
"metadata": {},
77+
"outputs": [],
78+
"source": [
79+
"# single point\n",
80+
"\n",
81+
"def potential_single_point(points):\n",
82+
" cs2 = SmoothCollisions2()\n",
83+
" cs2.use_high_order_quadrature = False\n",
84+
" cs2.build(mesh, points, param)\n",
85+
" \n",
86+
" B = SmoothPotential(param)\n",
87+
" # g = B.gradient(cs1, mesh, points)\n",
88+
"\n",
89+
" return B(cs2, mesh, points)"
90+
]
91+
},
92+
{
93+
"cell_type": "code",
94+
"execution_count": null,
95+
"metadata": {},
96+
"outputs": [],
97+
"source": [
98+
"# IPC\n",
99+
"\n",
100+
"def potential_IPC(points):\n",
101+
" cs3 = Collisions()\n",
102+
" cs3.build(mesh, points, param.dhat)\n",
103+
"\n",
104+
" B = BarrierPotential(param.dhat)\n",
105+
" # g = B.gradient(cs3, mesh, points)\n",
106+
"\n",
107+
" return B(cs3, mesh, points)"
108+
]
109+
},
110+
{
111+
"cell_type": "code",
112+
"execution_count": null,
113+
"metadata": {},
114+
"outputs": [],
115+
"source": [
116+
"print(potential_IPC(V), potential_single_point(V), potential_high_order(V))"
117+
]
118+
},
119+
{
120+
"cell_type": "code",
121+
"execution_count": null,
122+
"metadata": {},
123+
"outputs": [],
124+
"source": [
125+
"displacements = np.linspace(-0.1, 0.1, 200)\n",
126+
"pA = []\n",
127+
"pB = []\n",
128+
"pC = []\n",
129+
"\n",
130+
"for disp in displacements:\n",
131+
" V_disp = copy.deepcopy(V)\n",
132+
" V_disp[[3,4,5], 0] += disp\n",
133+
" \n",
134+
" pA.append(potential_IPC(V_disp))\n",
135+
" pB.append(potential_single_point(V_disp))\n",
136+
" pC.append(potential_high_order(V_disp))\n"
137+
]
138+
},
139+
{
140+
"cell_type": "code",
141+
"execution_count": null,
142+
"metadata": {},
143+
"outputs": [],
144+
"source": [
145+
"fig = go.Figure(data=[\n",
146+
" go.Scatter(x=displacements, y=pA, name=\"IPC\"),\n",
147+
" go.Scatter(x=displacements, y=pB, name=\"Single Point\"),\n",
148+
" go.Scatter(x=displacements, y=pC, name=\"Exact Quadrature\"),\n",
149+
"], layout=go.Layout(width=800, height=400))\n",
150+
"\n",
151+
"# fig.update_layout(\n",
152+
"# yaxis_type=\"log\"\n",
153+
"# )\n",
154+
"\n",
155+
"fig.show()"
156+
]
157+
},
158+
{
159+
"cell_type": "code",
160+
"execution_count": null,
161+
"metadata": {},
162+
"outputs": [],
163+
"source": []
164+
}
165+
],
166+
"metadata": {
167+
"kernelspec": {
168+
"display_name": "base",
169+
"language": "python",
170+
"name": "python3"
171+
},
172+
"language_info": {
173+
"codemirror_mode": {
174+
"name": "ipython",
175+
"version": 3
176+
},
177+
"file_extension": ".py",
178+
"mimetype": "text/x-python",
179+
"name": "python",
180+
"nbconvert_exporter": "python",
181+
"pygments_lexer": "ipython3",
182+
"version": "3.11.8"
183+
}
184+
},
185+
"nbformat": 4,
186+
"nbformat_minor": 2
187+
}

python/src/collisions/collisions.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ void define_collisions(py::module_& m)
160160

161161
py::class_<SmoothCollisions<2>>(m, "SmoothCollisions2")
162162
.def(py::init())
163+
.def_readwrite("use_high_order_quadrature", &SmoothCollisions<2>::use_high_order_quadrature)
163164
.def(
164165
"build",
165166
py::overload_cast<

python/src/potentials/barrier_potential.cpp

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -76,21 +76,23 @@ void define_barrier_potential(py::module_& m)
7676
.def(
7777
"shape_derivative",
7878
py::overload_cast<
79-
const CollisionsBase&, const CollisionMesh&,
79+
const Collisions&, const CollisionMesh&,
8080
const Eigen::MatrixXd&>(
8181
&BarrierPotential::shape_derivative, py::const_),
8282
R"ipc_Qu8mg5v7(
8383
Compute the shape derivative of the potential.
8484
85-
std::runtime_error If the collision collisions were not built with shape derivatives enabled.
85+
std::runtime_error If the collision collisions were not built
86+
with shape derivatives enabled.
8687
8788
Parameters:
8889
collisions: The set of collisions.
8990
mesh: The collision mesh.
9091
vertices: Vertices of the collision mesh.
9192
9293
Returns:
93-
The derivative of the force with respect to X, the rest vertices.
94+
The derivative of the force with respect to X, the rest
95+
vertices.
9496
)ipc_Qu8mg5v7",
9597
py::arg("collisions"), py::arg("mesh"), py::arg("vertices"))
9698
.def(
@@ -142,7 +144,8 @@ void define_barrier_potential(py::module_& m)
142144
py::arg("project_hessian_to_psd") = false)
143145
.def(
144146
"shape_derivative",
145-
[](const DistanceBasedPotential& self, const Collision<4>& collision,
147+
[](const DistanceBasedPotential& self,
148+
const Collision<4>& collision,
146149
const std::array<long, 4>& vertex_ids,
147150
const VectorMax12d& rest_positions,
148151
const VectorMax12d& positions) {
@@ -180,33 +183,39 @@ void define_smooth_potential(py::module_& m)
180183
{
181184
py::class_<ParameterType>(m, "ParameterType")
182185
.def(
183-
py::init<const double&,const double&,const double&,const double&,const double&,
184-
const int&>(),
186+
py::init<
187+
const double&, const double&, const double&, const double&,
188+
const double&, const int&, const int&>(),
185189
R"ipc_Qu8mg5v7(
186190
Construct parameter set for smooth contact.
187191
188192
Parameters:
189193
dhat, alpha_t, beta_t, alpha_n, beta_n, r
190194
)ipc_Qu8mg5v7",
191-
py::arg("dhat"), py::arg("alpha_t"), py::arg("beta_t"), py::arg("alpha_n"),
192-
py::arg("beta_n"), py::arg("r"))
195+
py::arg("dhat"), py::arg("alpha_t"), py::arg("beta_t"),
196+
py::arg("alpha_n"), py::arg("beta_n"), py::arg("r"),
197+
py::arg("n_quadrature_samples"))
193198
.def(
194-
py::init<const double&,const double&,const double&,const int&>(),
199+
py::init<const double&, const double&, const double&, const int&>(),
195200
R"ipc_Qu8mg5v7(
196201
Construct parameter set for smooth contact.
197202
198203
Parameters:
199204
dhat, alpha_t, beta_t, r
200205
)ipc_Qu8mg5v7",
201-
py::arg("dhat"), py::arg("alpha_t"), py::arg("beta_t"), py::arg("r"))
206+
py::arg("dhat"), py::arg("alpha_t"), py::arg("beta_t"),
207+
py::arg("r"))
202208
.def_readonly("dhat", &ParameterType::dhat)
203209
.def_readonly("alpha_t", &ParameterType::alpha_t)
204210
.def_readonly("beta_t", &ParameterType::beta_t)
205211
.def_readonly("alpha_n", &ParameterType::alpha_n)
206212
.def_readonly("beta_n", &ParameterType::beta_n)
207-
.def_readonly("r", &ParameterType::r);
213+
.def_readonly("r", &ParameterType::r)
214+
.def_readonly(
215+
"n_quadrature_samples", &ParameterType::n_quadrature_samples);
208216

209-
py::class_<SmoothContactPotential<SmoothCollisions<2>>>(m, "SmoothPotential")
217+
py::class_<SmoothContactPotential<SmoothCollisions<2>>>(
218+
m, "SmoothPotential")
210219
.def(
211220
py::init<const ParameterType&>(),
212221
R"ipc_Qu8mg5v7(
@@ -221,7 +230,9 @@ void define_smooth_potential(py::module_& m)
221230
py::overload_cast<
222231
const SmoothCollisions<2>&, const CollisionMesh&,
223232
const Eigen::MatrixXd&>(
224-
&SmoothContactPotential<SmoothCollisions<2>>::Potential::operator(), py::const_),
233+
&SmoothContactPotential<
234+
SmoothCollisions<2>>::Potential::operator(),
235+
py::const_),
225236
R"ipc_Qu8mg5v7(
226237
Compute the barrier potential for a set of collisions.
227238
@@ -239,7 +250,9 @@ void define_smooth_potential(py::module_& m)
239250
py::overload_cast<
240251
const SmoothCollisions<2>&, const CollisionMesh&,
241252
const Eigen::MatrixXd&>(
242-
&SmoothContactPotential<SmoothCollisions<2>>::Potential::gradient, py::const_),
253+
&SmoothContactPotential<
254+
SmoothCollisions<2>>::Potential::gradient,
255+
py::const_),
243256
R"ipc_Qu8mg5v7(
244257
Compute the gradient of the barrier potential.
245258
@@ -255,8 +268,11 @@ void define_smooth_potential(py::module_& m)
255268
.def(
256269
"hessian",
257270
py::overload_cast<
258-
const SmoothCollisions<2>&, const CollisionMesh&, const Eigen::MatrixXd&,
259-
const bool>(&SmoothContactPotential<SmoothCollisions<2>>::Potential::hessian, py::const_),
271+
const SmoothCollisions<2>&, const CollisionMesh&,
272+
const Eigen::MatrixXd&, const bool>(
273+
&SmoothContactPotential<
274+
SmoothCollisions<2>>::Potential::hessian,
275+
py::const_),
260276
R"ipc_Qu8mg5v7(
261277
Compute the hessian of the barrier potential.
262278
@@ -273,8 +289,10 @@ void define_smooth_potential(py::module_& m)
273289
py::arg("project_hessian_to_psd") = false)
274290
.def(
275291
"__call__",
276-
py::overload_cast<const SmoothCollision<6>&, const Vector<double, -1, 18>&>(
277-
&SmoothContactPotential<SmoothCollisions<2>>::operator(), py::const_),
292+
py::overload_cast<
293+
const SmoothCollision<6>&, const Vector<double, -1, 18>&>(
294+
&SmoothContactPotential<SmoothCollisions<2>>::operator(),
295+
py::const_),
278296
R"ipc_Qu8mg5v7(
279297
Compute the potential for a single collision.
280298
@@ -288,8 +306,10 @@ void define_smooth_potential(py::module_& m)
288306
py::arg("collision"), py::arg("x"))
289307
.def(
290308
"gradient",
291-
py::overload_cast<const SmoothCollision<6>&, const Vector<double, -1, 18>&>(
292-
&SmoothContactPotential<SmoothCollisions<2>>::gradient, py::const_),
309+
py::overload_cast<
310+
const SmoothCollision<6>&, const Vector<double, -1, 18>&>(
311+
&SmoothContactPotential<SmoothCollisions<2>>::gradient,
312+
py::const_),
293313
R"ipc_Qu8mg5v7(
294314
Compute the gradient of the potential for a single collision.
295315
@@ -304,8 +324,10 @@ void define_smooth_potential(py::module_& m)
304324
.def(
305325
"hessian",
306326
py::overload_cast<
307-
const SmoothCollision<6>&, const Vector<double, -1, 18>&, const bool>(
308-
&SmoothContactPotential<SmoothCollisions<2>>::hessian, py::const_),
327+
const SmoothCollision<6>&, const Vector<double, -1, 18>&,
328+
const bool>(
329+
&SmoothContactPotential<SmoothCollisions<2>>::hessian,
330+
py::const_),
309331
R"ipc_Qu8mg5v7(
310332
Compute the hessian of the potential for a single collision.
311333

src/ipc/friction/friction_collisions.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
namespace ipc {
1313

1414
template <int dim>
15-
void FrictionCollisions::build(
15+
void FrictionCollisions::build_for_smooth_contact(
1616
const CollisionMesh& mesh,
1717
const Eigen::MatrixXd& vertices,
1818
const SmoothCollisions<dim>& collisions,
@@ -137,7 +137,7 @@ void FrictionCollisions::build(
137137
}
138138

139139
template
140-
void FrictionCollisions::build<2>(
140+
void FrictionCollisions::build_for_smooth_contact<2>(
141141
const CollisionMesh& mesh,
142142
const Eigen::MatrixXd& vertices,
143143
const SmoothCollisions<2>& collisions,
@@ -147,7 +147,7 @@ void FrictionCollisions::build<2>(
147147
const std::function<double(double, double)>& blend_mu);
148148

149149
template
150-
void FrictionCollisions::build<3>(
150+
void FrictionCollisions::build_for_smooth_contact<3>(
151151
const CollisionMesh& mesh,
152152
const Eigen::MatrixXd& vertices,
153153
const SmoothCollisions<3>& collisions,

0 commit comments

Comments
 (0)