Skip to content

Commit 7de3da8

Browse files
committed
ground n and o as parameter
1 parent 0b1b564 commit 7de3da8

3 files changed

Lines changed: 26 additions & 26 deletions

File tree

friction/BarrierEnergy.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33

44
dhat = 0.01
55
kappa = 1e5
6-
n = np.array([0.0, 1.0]) #TODO: make as parameter
7-
o = np.array([0.0, -1.0])
86

9-
def val(x, y_ground, contact_area):
7+
def val(x, n, o, contact_area):
108
sum = 0.0
119
for i in range(0, len(x)):
1210
d = n.dot(x[i] - o)
@@ -15,7 +13,7 @@ def val(x, y_ground, contact_area):
1513
sum += contact_area[i] * dhat * kappa / 2 * (s - 1) * math.log(s)
1614
return sum
1715

18-
def grad(x, y_ground, contact_area):
16+
def grad(x, n, o, contact_area):
1917
g = np.array([[0.0, 0.0]] * len(x))
2018
for i in range(0, len(x)):
2119
d = n.dot(x[i] - o)
@@ -24,7 +22,7 @@ def grad(x, y_ground, contact_area):
2422
g[i] = contact_area[i] * dhat * (kappa / 2 * (math.log(s) / dhat + (s - 1) / d)) * n
2523
return g
2624

27-
def hess(x, y_ground, contact_area):
25+
def hess(x, n, o, contact_area):
2826
IJV = [[0] * 0, [0] * 0, np.array([0.0] * 0)]
2927
for i in range(0, len(x)):
3028
d = n.dot(x[i] - o)
@@ -37,7 +35,7 @@ def hess(x, y_ground, contact_area):
3735
IJV[2] = np.append(IJV[2], local_hess[r, c])
3836
return IJV
3937

40-
def init_step_size(x, y_ground, p):
38+
def init_step_size(x, n, o, p):
4139
alpha = 1
4240
for i in range(0, len(x)):
4341
p_n = p[i].dot(n)

friction/simulator.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
n_seg = 4 # num of segments per side of the square
1515
h = 0.01 # time step size in s
1616
DBC = [] # no nodes need to be fixed
17-
ground_n = np.array([0.0, 1.0]) # height of the planar ground
18-
ground_o = np.array([0.0, -1.0])
17+
ground_n = np.array([0.0, 1.0]) # normal of the slope
18+
ground_o = np.array([0.0, -1.0]) # a point on the slope
1919

2020
# initialize simulation
2121
[x, e] = square_mesh.generate(side_len, n_seg) # node positions and edge node indices
@@ -32,6 +32,7 @@
3232
for i in DBC:
3333
is_DBC[i] = True
3434
contact_area = [side_len / n_seg] * len(x) # perimeter split to each node
35+
ground_n /= np.linalg.norm(ground_n) # normalize ground normal vector just in case
3536

3637
# simulation with visualization
3738
resolution = np.array([900, 900])
@@ -53,7 +54,8 @@ def screen_projection(x):
5354

5455
# fill the background and draw the square
5556
screen.fill((255, 255, 255))
56-
pygame.draw.aaline(screen, (0, 0, 255), screen_projection([-2, y_ground]), screen_projection([2, y_ground])) # ground
57+
pygame.draw.aaline(screen, (0, 0, 255), screen_projection([ground_o[0] - 3.0 * ground_n[1], ground_o[1] + 3.0 * ground_n[0]]),
58+
screen_projection([ground_o[0] + 3.0 * ground_n[1], ground_o[1] - 3.0 * ground_n[0]])) # ground
5759
for eI in e:
5860
pygame.draw.aaline(screen, (0, 0, 255), screen_projection(x[eI[0]]), screen_projection(x[eI[1]]))
5961
for xI in x:
@@ -62,7 +64,7 @@ def screen_projection(x):
6264
pygame.display.flip() # flip the display
6365

6466
# step forward simulation and wait for screen refresh
65-
[x, v] = time_integrator.step_forward(x, e, v, m, l2, k, y_ground, contact_area, is_DBC, h, 1e-2)
67+
[x, v] = time_integrator.step_forward(x, e, v, m, l2, k, ground_n, ground_o, contact_area, is_DBC, h, 1e-2)
6668
time_step += 1
6769
pygame.time.wait(int(h * 1000))
6870

friction/time_integrator.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,52 +11,52 @@
1111
import GravityEnergy
1212
import BarrierEnergy
1313

14-
def step_forward(x, e, v, m, l2, k, y_ground, contact_area, is_DBC, h, tol):
14+
def step_forward(x, e, v, m, l2, k, n, o, contact_area, is_DBC, h, tol):
1515
x_tilde = x + v * h # implicit Euler predictive position
1616
x_n = copy.deepcopy(x)
1717

1818
# Newton loop
1919
iter = 0
20-
E_last = IP_val(x, e, x_tilde, m, l2, k, y_ground, contact_area, h)
21-
p = search_dir(x, e, x_tilde, m, l2, k, y_ground, contact_area, is_DBC, h)
20+
E_last = IP_val(x, e, x_tilde, m, l2, k, n, o, contact_area, h)
21+
p = search_dir(x, e, x_tilde, m, l2, k, n, o, contact_area, is_DBC, h)
2222
while LA.norm(p, inf) / h > tol:
2323
print('Iteration', iter, ':')
2424
print('residual =', LA.norm(p, inf) / h)
2525

2626
# filter line search
27-
alpha = BarrierEnergy.init_step_size(x, y_ground, p) # avoid interpenetration and tunneling
28-
while IP_val(x + alpha * p, e, x_tilde, m, l2, k, y_ground, contact_area, h) > E_last:
27+
alpha = BarrierEnergy.init_step_size(x, n, o, p) # avoid interpenetration and tunneling
28+
while IP_val(x + alpha * p, e, x_tilde, m, l2, k, n, o, contact_area, h) > E_last:
2929
alpha /= 2
3030
print('step size =', alpha)
3131

3232
x += alpha * p
33-
E_last = IP_val(x, e, x_tilde, m, l2, k, y_ground, contact_area, h)
34-
p = search_dir(x, e, x_tilde, m, l2, k, y_ground, contact_area, is_DBC, h)
33+
E_last = IP_val(x, e, x_tilde, m, l2, k, n, o, contact_area, h)
34+
p = search_dir(x, e, x_tilde, m, l2, k, n, o, contact_area, is_DBC, h)
3535
iter += 1
3636

3737
v = (x - x_n) / h # implicit Euler velocity update
3838
return [x, v]
3939

40-
def IP_val(x, e, x_tilde, m, l2, k, y_ground, contact_area, h):
41-
return InertiaEnergy.val(x, x_tilde, m) + h * h * (MassSpringEnergy.val(x, e, l2, k) + GravityEnergy.val(x, m) + BarrierEnergy.val(x, y_ground, contact_area)) # implicit Euler
40+
def IP_val(x, e, x_tilde, m, l2, k, n, o, contact_area, h):
41+
return InertiaEnergy.val(x, x_tilde, m) + h * h * (MassSpringEnergy.val(x, e, l2, k) + GravityEnergy.val(x, m) + BarrierEnergy.val(x, n, o, contact_area)) # implicit Euler
4242

43-
def IP_grad(x, e, x_tilde, m, l2, k, y_ground, contact_area, h):
44-
return InertiaEnergy.grad(x, x_tilde, m) + h * h * (MassSpringEnergy.grad(x, e, l2, k) + GravityEnergy.grad(x, m) + BarrierEnergy.grad(x, y_ground, contact_area)) # implicit Euler
43+
def IP_grad(x, e, x_tilde, m, l2, k, n, o, contact_area, h):
44+
return InertiaEnergy.grad(x, x_tilde, m) + h * h * (MassSpringEnergy.grad(x, e, l2, k) + GravityEnergy.grad(x, m) + BarrierEnergy.grad(x, n, o, contact_area)) # implicit Euler
4545

46-
def IP_hess(x, e, x_tilde, m, l2, k, y_ground, contact_area, h):
46+
def IP_hess(x, e, x_tilde, m, l2, k, n, o, contact_area, h):
4747
IJV_In = InertiaEnergy.hess(x, x_tilde, m)
4848
IJV_MS = MassSpringEnergy.hess(x, e, l2, k)
49-
IJV_B = BarrierEnergy.hess(x, y_ground, contact_area)
49+
IJV_B = BarrierEnergy.hess(x, n, o, contact_area)
5050
IJV_MS[2] *= h * h # implicit Euler
5151
IJV_B[2] *= h * h # implicit Euler
5252
IJV_In_MS = np.append(IJV_In, IJV_MS, axis=1)
5353
IJV = np.append(IJV_In_MS, IJV_B, axis=1)
5454
H = sparse.coo_matrix((IJV[2], (IJV[0], IJV[1])), shape=(len(x) * 2, len(x) * 2)).tocsr()
5555
return H
5656

57-
def search_dir(x, e, x_tilde, m, l2, k, y_ground, contact_area, is_DBC, h):
58-
projected_hess = IP_hess(x, e, x_tilde, m, l2, k, y_ground, contact_area, h)
59-
reshaped_grad = IP_grad(x, e, x_tilde, m, l2, k, y_ground, contact_area, h).reshape(len(x) * 2, 1)
57+
def search_dir(x, e, x_tilde, m, l2, k, n, o, contact_area, is_DBC, h):
58+
projected_hess = IP_hess(x, e, x_tilde, m, l2, k, n, o, contact_area, h)
59+
reshaped_grad = IP_grad(x, e, x_tilde, m, l2, k, n, o, contact_area, h).reshape(len(x) * 2, 1)
6060
# eliminate DOF by modifying gradient and Hessian for DBC:
6161
for i, j in zip(*projected_hess.nonzero()):
6262
if is_DBC[int(i / 2)] | is_DBC[int(j / 2)]:

0 commit comments

Comments
 (0)