Skip to content

Commit 1034605

Browse files
committed
self-contact find boundary
1 parent 0cd23f0 commit 1034605

3 files changed

Lines changed: 23 additions & 3 deletions

File tree

self_contact/readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Inversion-free Hyperelastic Solids Simulation
22

3-
Two squares falling onto the ground under gravity, contacting with each other, is simulated with an inversion-free hyperelastic potential and IPC with implicit Euler time integration.
3+
Two squares falling onto the ground under gravity, contacting with each other, and then compressed by a ceiling is simulated with an inversion-free hyperelastic potential and IPC with implicit Euler time integration.
44
Each time step is solved by minimizing the Incremental Potential with the projected Newton method.
55

66
## Dependencies

self_contact/simulator.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Mass-Spring Solids Simulation
1+
# FEM Solids Simulation
22

33
import numpy as np # numpy for linear algebra
44
import pygame # pygame for visualization
@@ -26,6 +26,7 @@
2626
[x, e] = square_mesh.generate(side_len, n_seg) # node positions and triangle node indices of the top square
2727
e = np.append(e, np.array(e) + [len(x)] * 3, axis=0) # add triangle node indices of the bottom square
2828
x = np.append(x, x + [side_len * 0.1, -side_len * 1.1], axis=0) # add node positions of the bottom square
29+
[bp, be] = square_mesh.find_boundary(e) # find boundary points and edges for self-contact
2930
x = np.append(x, [[0.0, side_len * 0.6]], axis=0) # ceil origin (with normal [0.0, -1.0])
3031
v = np.array([[0.0, 0.0]] * len(x)) # velocity
3132
m = [rho * side_len * side_len / ((n_seg + 1) * (n_seg + 1))] * len(x) # calculate node mass evenly

self_contact/square_mesh.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,23 @@ def generate(side_length, n_seg):
2020
e.append([i * (n_seg + 1) + j, (i + 1) * (n_seg + 1) + j, (i + 1) * (n_seg + 1) + j + 1])
2121
e.append([i * (n_seg + 1) + j, (i + 1) * (n_seg + 1) + j + 1, i * (n_seg + 1) + j + 1])
2222

23-
return [x, e]
23+
return [x, e]
24+
25+
def find_boundary(e):
26+
# index all half-edges for fast query
27+
edge_set = set()
28+
for i in range(0, len(e)):
29+
for j in range(0, 3):
30+
edge_set.add((e[i][j], e[i][(j + 1) % 3]))
31+
32+
# find boundary points and edges
33+
bp_set = set()
34+
be = []
35+
for eI in edge_set:
36+
if (eI[1], eI[0]) not in edge_set:
37+
# if the inverse edge of a half-edge does not exist,
38+
# then it is a boundary edge
39+
be.append([eI[0], eI[1]])
40+
bp_set.add(eI[0])
41+
bp_set.add(eI[1])
42+
return [list(bp_set), be]

0 commit comments

Comments
 (0)