Skip to content

Commit 72db557

Browse files
committed
removed fric from self-contact
1 parent 9149060 commit 72db557

6 files changed

Lines changed: 23 additions & 86 deletions

File tree

self_contact/BarrierEnergy.py

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -147,18 +147,4 @@ def compute_mu_lambda(x, n, o, bp, be, contact_area, mu):
147147
if d < dhat:
148148
s = d / dhat
149149
mu_lambda[i] = mu * -contact_area[i] * dhat * (kappa / 2 * (math.log(s) / dhat + (s - 1) / d))
150-
# self-contact
151-
mu_lambda_self = []
152-
dhat_sqr = dhat * dhat
153-
for xI in bp:
154-
for eI in be:
155-
if xI != eI[0] and xI != eI[1]: # do not consider a point and its incident edge
156-
d_sqr = PE.val(x[xI], x[eI[0]], x[eI[1]])
157-
if d_sqr < dhat_sqr:
158-
s = d_sqr / dhat_sqr
159-
# since d_sqr is used, need to divide by 8 not 2 here for consistency to linear elasticity
160-
# also, lambda = -\partial b / \partial d = -(\partial b / \partial d^2) * (\partial d^2 / \partial d)
161-
mu_lam = mu * -contact_area[xI] * dhat * (kappa / 8 * (math.log(s) / dhat_sqr + (s - 1) / d_sqr)) * 2 * math.sqrt(d_sqr)
162-
[n, r] = PE.tangent(x[xI], x[eI[0]], x[eI[1]]) # normal and closest point parameterization on the edge
163-
mu_lambda_self.append([xI, eI[0], eI[1], mu_lam, n, r])
164-
return [mu_lambda, mu_lambda_self]
150+
return mu_lambda

self_contact/FrictionEnergy.py

Lines changed: 3 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,44 +23,27 @@ def f_hess_term(vbarnorm, epsv):
2323
else:
2424
return -1.0 / (epsv * epsv)
2525

26-
def val(v, mu_lambda, mu_lambda_self, hhat, n):
26+
def val(v, mu_lambda, hhat, n):
2727
sum = 0.0
2828
# floor:
2929
T = np.identity(2) - np.outer(n, n) # tangent of slope is constant
3030
for i in range(0, len(v)):
3131
if mu_lambda[i] > 0:
3232
vbar = np.transpose(T).dot(v[i])
3333
sum += mu_lambda[i] * f0(np.linalg.norm(vbar), epsv, hhat)
34-
# self-contact:
35-
for i in range(0, len(mu_lambda_self)):
36-
[xI, eI0, eI1, mu_lam, n, r] = mu_lambda_self[i]
37-
T = np.identity(2) - np.outer(n, n)
38-
rel_v = v[xI] - ((1 - r) * v[eI0] + r * v[eI1])
39-
vbar = np.transpose(T).dot(rel_v)
40-
sum += mu_lam * f0(np.linalg.norm(vbar), epsv, hhat)
4134
return sum
4235

43-
def grad(v, mu_lambda, mu_lambda_self, hhat, n):
36+
def grad(v, mu_lambda, hhat, n):
4437
g = np.array([[0.0, 0.0]] * len(v))
4538
# floor:
4639
T = np.identity(2) - np.outer(n, n) # tangent of slope is constant
4740
for i in range(0, len(v)):
4841
if mu_lambda[i] > 0:
4942
vbar = np.transpose(T).dot(v[i])
5043
g[i] = mu_lambda[i] * f1_div_vbarnorm(np.linalg.norm(vbar), epsv) * T.dot(vbar)
51-
# self-contact:
52-
for i in range(0, len(mu_lambda_self)):
53-
[xI, eI0, eI1, mu_lam, n, r] = mu_lambda_self[i]
54-
T = np.identity(2) - np.outer(n, n)
55-
rel_v = v[xI] - ((1 - r) * v[eI0] + r * v[eI1])
56-
vbar = np.transpose(T).dot(rel_v)
57-
g_rel_v = mu_lam * f1_div_vbarnorm(np.linalg.norm(vbar), epsv) * T.dot(vbar)
58-
g[xI] += g_rel_v
59-
g[eI0] += g_rel_v * -(1 - r)
60-
g[eI1] += g_rel_v * -r
6144
return g
6245

63-
def hess(v, mu_lambda, mu_lambda_self, hhat, n):
46+
def hess(v, mu_lambda, hhat, n):
6447
IJV = [[0] * 0, [0] * 0, np.array([0.0] * 0)]
6548
# floor:
6649
T = np.identity(2) - np.outer(n, n) # tangent of slope is constant
@@ -77,24 +60,4 @@ def hess(v, mu_lambda, mu_lambda_self, hhat, n):
7760
IJV[0].append(i * 2 + r)
7861
IJV[1].append(i * 2 + c)
7962
IJV[2] = np.append(IJV[2], local_hess[r, c])
80-
# self-contact:
81-
for i in range(0, len(mu_lambda_self)):
82-
[xI, eI0, eI1, mu_lam, n, r] = mu_lambda_self[i]
83-
T = np.identity(2) - np.outer(n, n)
84-
rel_v = v[xI] - ((1 - r) * v[eI0] + r * v[eI1])
85-
vbar = np.transpose(T).dot(rel_v)
86-
vbarnorm = np.linalg.norm(vbar)
87-
inner_term = f1_div_vbarnorm(vbarnorm, epsv) * np.identity(2)
88-
if vbarnorm != 0:
89-
inner_term += f_hess_term(vbarnorm, epsv) / vbarnorm * np.outer(vbar, vbar)
90-
hess_rel_v = mu_lam * T.dot(utils.make_PD(inner_term)).dot(np.transpose(T)) / hhat
91-
index = [xI, eI0, eI1]
92-
d_rel_v_dv = [1, -(1 - r), -r]
93-
for nI in range(0, 3):
94-
for nJ in range(0, 3):
95-
for c in range(0, 2):
96-
for r in range(0, 2):
97-
IJV[0].append(index[nI] * 2 + r)
98-
IJV[1].append(index[nJ] * 2 + c)
99-
IJV[2] = np.append(IJV[2], d_rel_v_dv[nI] * d_rel_v_dv[nJ] * hess_rel_v[r, c])
10063
return IJV

self_contact/distance/PointEdgeDistance.py

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,4 @@ def hess(p, e0, e1):
4545
np.reshape([H_PP[2, 0:2], np.array([0.0, 0.0]), H_PP[2, 2:4]], (1, 6))[0], \
4646
np.reshape([H_PP[3, 0:2], np.array([0.0, 0.0]), H_PP[3, 2:4]], (1, 6))[0]])
4747
else: # point(p)-line(e0e1) expression
48-
return PL.hess(p, e0, e1)
49-
50-
# compute normal and the parameterization of the closest point on the edge
51-
def tangent(p, e0, e1):
52-
e = e1 - e0
53-
ratio = np.dot(e, p - e0) / np.dot(e, e)
54-
if ratio < 0: # point(p)-point(e0) expression
55-
n = p - e0
56-
elif ratio > 1: # point(p)-point(e1) expression
57-
n = p - e1
58-
else: # point(p)-line(e0e1) expression
59-
n = p - ((1 - ratio) * e0 + ratio * e1)
60-
return [n / np.linalg.norm(n), ratio]
48+
return PL.hess(p, e0, e1)

self_contact/simulator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
ground_n = np.array([0.0, 1.0]) # normal of the slope
2121
ground_n /= np.linalg.norm(ground_n) # normalize ground normal vector just in case
2222
ground_o = np.array([0.0, -1.0]) # a point on the slope
23-
mu = 0.11 # friction coefficient of the slope
23+
mu = 0.4 # friction coefficient of the slope
2424

2525
# initialize simulation
2626
[x, e] = square_mesh.generate(side_len, n_seg) # node positions and triangle node indices of the top square

self_contact/time_integrator.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
def step_forward(x, e, v, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, mu, is_DBC, DBC, DBC_v, DBC_limit, h, tol):
1717
x_tilde = x + v * h # implicit Euler predictive position
1818
x_n = copy.deepcopy(x)
19-
[mu_lambda, mu_lambda_self] = BarrierEnergy.compute_mu_lambda(x, n, o, bp, be, contact_area, mu) # compute mu * lambda for each node using x^n
19+
mu_lambda = BarrierEnergy.compute_mu_lambda(x, n, o, bp, be, contact_area, mu) # compute mu * lambda for each node using x^n
2020
DBC_target = [] # target position of each DBC in the current time step
2121
for i in range(0, len(DBC)):
2222
if (DBC_limit[i] - x_n[DBC[i]]).dot(DBC_v[i]) > 0:
@@ -27,52 +27,52 @@ def step_forward(x, e, v, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area,
2727

2828
# Newton loop
2929
iter = 0
30-
E_last = IP_val(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, (x - x_n) / h, mu_lambda, mu_lambda_self, DBC, DBC_target, DBC_stiff, h)
31-
[p, DBC_satisfied] = search_dir(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, (x - x_n) / h, mu_lambda, mu_lambda_self, is_DBC, DBC, DBC_target, DBC_stiff, tol, h)
30+
E_last = IP_val(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, (x - x_n) / h, mu_lambda, DBC, DBC_target, DBC_stiff, h)
31+
[p, DBC_satisfied] = search_dir(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, (x - x_n) / h, mu_lambda, is_DBC, DBC, DBC_target, DBC_stiff, tol, h)
3232
while (LA.norm(p, inf) / h > tol) | (sum(DBC_satisfied) != len(DBC)): # also check whether all DBCs are satisfied
3333
print('Iteration', iter, ':')
3434
print('residual =', LA.norm(p, inf) / h)
3535

3636
if (LA.norm(p, inf) / h <= tol) & (sum(DBC_satisfied) != len(DBC)):
3737
# increase DBC stiffness and recompute energy value record
3838
DBC_stiff *= 2
39-
E_last = IP_val(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, (x - x_n) / h, mu_lambda, mu_lambda_self, DBC, DBC_target, DBC_stiff, h)
39+
E_last = IP_val(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, (x - x_n) / h, mu_lambda, DBC, DBC_target, DBC_stiff, h)
4040

4141
# filter line search
4242
alpha = min(BarrierEnergy.init_step_size(x, n, o, bp, be, p), NeoHookeanEnergy.init_step_size(x, e, p)) # avoid interpenetration, tunneling, and inversion
43-
while IP_val(x + alpha * p, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, (x + alpha * p - x_n) / h, mu_lambda, mu_lambda_self, DBC, DBC_target, DBC_stiff, h) > E_last:
43+
while IP_val(x + alpha * p, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, (x + alpha * p - x_n) / h, mu_lambda, DBC, DBC_target, DBC_stiff, h) > E_last:
4444
alpha /= 2
4545
print('step size =', alpha)
4646

4747
x += alpha * p
48-
E_last = IP_val(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, (x - x_n) / h, mu_lambda, mu_lambda_self, DBC, DBC_target, DBC_stiff, h)
49-
[p, DBC_satisfied] = search_dir(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, (x - x_n) / h, mu_lambda, mu_lambda_self, is_DBC, DBC, DBC_target, DBC_stiff, tol, h)
48+
E_last = IP_val(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, (x - x_n) / h, mu_lambda, DBC, DBC_target, DBC_stiff, h)
49+
[p, DBC_satisfied] = search_dir(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, (x - x_n) / h, mu_lambda, is_DBC, DBC, DBC_target, DBC_stiff, tol, h)
5050
iter += 1
5151

5252
v = (x - x_n) / h # implicit Euler velocity update
5353
return [x, v]
5454

55-
def IP_val(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, v, mu_lambda, mu_lambda_self, DBC, DBC_target, DBC_stiff, h):
55+
def IP_val(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, v, mu_lambda, DBC, DBC_target, DBC_stiff, h):
5656
return InertiaEnergy.val(x, x_tilde, m) + h * h * ( # implicit Euler
5757
NeoHookeanEnergy.val(x, e, vol, IB, mu_lame, lam) +
5858
GravityEnergy.val(x, m) +
5959
BarrierEnergy.val(x, n, o, bp, be, contact_area) +
60-
FrictionEnergy.val(v, mu_lambda, mu_lambda_self, h, n)
60+
FrictionEnergy.val(v, mu_lambda, h, n)
6161
) + SpringEnergy.val(x, m, DBC, DBC_target, DBC_stiff)
6262

63-
def IP_grad(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, v, mu_lambda, mu_lambda_self, DBC, DBC_target, DBC_stiff, h):
63+
def IP_grad(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, v, mu_lambda, DBC, DBC_target, DBC_stiff, h):
6464
return InertiaEnergy.grad(x, x_tilde, m) + h * h * ( # implicit Euler
6565
NeoHookeanEnergy.grad(x, e, vol, IB, mu_lame, lam) +
6666
GravityEnergy.grad(x, m) +
6767
BarrierEnergy.grad(x, n, o, bp, be, contact_area) +
68-
FrictionEnergy.grad(v, mu_lambda, mu_lambda_self, h, n)
68+
FrictionEnergy.grad(v, mu_lambda, h, n)
6969
) + SpringEnergy.grad(x, m, DBC, DBC_target, DBC_stiff)
7070

71-
def IP_hess(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, v, mu_lambda, mu_lambda_self, DBC, DBC_target, DBC_stiff, h):
71+
def IP_hess(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, v, mu_lambda, DBC, DBC_target, DBC_stiff, h):
7272
IJV_In = InertiaEnergy.hess(x, x_tilde, m)
7373
IJV_MS = NeoHookeanEnergy.hess(x, e, vol, IB, mu_lame, lam)
7474
IJV_B = BarrierEnergy.hess(x, n, o, bp, be, contact_area)
75-
IJV_F = FrictionEnergy.hess(v, mu_lambda, mu_lambda_self, h, n)
75+
IJV_F = FrictionEnergy.hess(v, mu_lambda, h, n)
7676
IJV_S = SpringEnergy.hess(x, m, DBC, DBC_target, DBC_stiff)
7777
IJV_MS[2] *= h * h # implicit Euler
7878
IJV_B[2] *= h * h # implicit Euler
@@ -84,9 +84,9 @@ def IP_hess(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area,
8484
H = sparse.coo_matrix((IJV[2], (IJV[0], IJV[1])), shape=(len(x) * 2, len(x) * 2)).tocsr()
8585
return H
8686

87-
def search_dir(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, v, mu_lambda, mu_lambda_self, is_DBC, DBC, DBC_target, DBC_stiff, tol, h):
88-
projected_hess = IP_hess(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, v, mu_lambda, mu_lambda_self, DBC, DBC_target, DBC_stiff, h)
89-
reshaped_grad = IP_grad(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, v, mu_lambda, mu_lambda_self, DBC, DBC_target, DBC_stiff, h).reshape(len(x) * 2, 1)
87+
def search_dir(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, v, mu_lambda, is_DBC, DBC, DBC_target, DBC_stiff, tol, h):
88+
projected_hess = IP_hess(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, v, mu_lambda, DBC, DBC_target, DBC_stiff, h)
89+
reshaped_grad = IP_grad(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, bp, be, contact_area, v, mu_lambda, DBC, DBC_target, DBC_stiff, h).reshape(len(x) * 2, 1)
9090
# check whether each DBC is satisfied
9191
DBC_satisfied = [False] * len(x)
9292
for i in range(0, len(DBC)):

self_friction/simulator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
ground_n = np.array([0.0, 1.0]) # normal of the slope
2121
ground_n /= np.linalg.norm(ground_n) # normalize ground normal vector just in case
2222
ground_o = np.array([0.0, -1.0]) # a point on the slope
23-
mu = 0.2 # friction coefficient of the slope
23+
mu = 0.4 # friction coefficient of the slope
2424

2525
# initialize simulation
2626
[x, e] = square_mesh.generate(side_len, n_seg) # node positions and triangle node indices of the top square

0 commit comments

Comments
 (0)