Skip to content

Commit 7eae7cf

Browse files
committed
inv free compress square
1 parent ecdda4e commit 7eae7cf

6 files changed

Lines changed: 236 additions & 75 deletions

File tree

inv_free/MassSpringEnergy.py

Lines changed: 0 additions & 35 deletions
This file was deleted.

inv_free/NeoHookeanEnergy.py

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import utils
2+
import numpy as np
3+
import math
4+
5+
def polar_svd(F):
6+
[U, s, VT] = np.linalg.svd(F)
7+
if np.linalg.det(U) < 0:
8+
U[:, 1] = -U[:, 1]
9+
s[1] = -s[1]
10+
if np.linalg.det(VT) < 0:
11+
VT[1, :] = -VT[1, :]
12+
s[1] = -s[1]
13+
return [U, s, VT]
14+
15+
def dPsi_div_dsigma(s, mu, lam):
16+
ln_sigma_prod = math.log(s[0] * s[1])
17+
inv0 = 1.0 / s[0]
18+
dPsi_dsigma_0 = mu * (s[0] - inv0) + lam * inv0 * ln_sigma_prod
19+
inv1 = 1.0 / s[1]
20+
dPsi_dsigma_1 = mu * (s[1] - inv1) + lam * inv1 * ln_sigma_prod
21+
return [dPsi_dsigma_0, dPsi_dsigma_1]
22+
23+
def d2Psi_div_dsigma2(s, mu, lam):
24+
ln_sigma_prod = math.log(s[0] * s[1])
25+
inv2_0 = 1 / (s[0] * s[0])
26+
d2Psi_dsigma2_00 = mu * (1 + inv2_0) - lam * inv2_0 * (ln_sigma_prod - 1)
27+
inv2_1 = 1 / (s[1] * s[1])
28+
d2Psi_dsigma2_11 = mu * (1 + inv2_1) - lam * inv2_1 * (ln_sigma_prod - 1)
29+
d2Psi_dsigma2_01 = lam / (s[0] * s[1])
30+
return [[d2Psi_dsigma2_00, d2Psi_dsigma2_01], [d2Psi_dsigma2_01, d2Psi_dsigma2_11]]
31+
32+
def B_left_coef(s, mu, lam):
33+
sigma_prod = s[0] * s[1]
34+
return (mu + (mu - lam * math.log(sigma_prod)) / sigma_prod) / 2
35+
36+
def Psi(F, mu, lam):
37+
J = np.linalg.det(F)
38+
lnJ = math.log(J)
39+
return mu / 2 * (np.trace(np.transpose(F).dot(F)) - 2) - mu * lnJ + lam / 2 * lnJ * lnJ
40+
41+
def dPsi_div_dF(F, mu, lam):
42+
FinvT = np.transpose(np.linalg.inv(F))
43+
return mu * (F - FinvT) + lam * math.log(np.linalg.det(F)) * FinvT
44+
45+
def d2Psi_div_dF2(F, mu, lam):
46+
[U, sigma, VT] = polar_svd(F)
47+
48+
Psi_sigma_sigma = utils.make_PD(d2Psi_div_dsigma2(sigma, mu, lam))
49+
50+
B_left = B_left_coef(sigma, mu, lam)
51+
Psi_sigma = dPsi_div_dsigma(sigma, mu, lam)
52+
B_right = (Psi_sigma[0] + Psi_sigma[1]) / (2 * max(sigma[0] + sigma[1], 1e-6))
53+
B = utils.make_PD([[B_left + B_right, B_left - B_right], [B_left - B_right, B_left + B_right]])
54+
55+
M = np.array([[0, 0, 0, 0]] * 4)
56+
M[0, 0] = Psi_sigma_sigma[0, 0]
57+
M[0, 3] = Psi_sigma_sigma[0, 1]
58+
M[1, 1] = B[0, 0]
59+
M[1, 2] = B[0, 1]
60+
M[2, 1] = B[1, 0]
61+
M[2, 2] = B[1, 1]
62+
M[3, 0] = Psi_sigma_sigma[1, 0]
63+
M[3, 3] = Psi_sigma_sigma[1, 1]
64+
65+
dP_div_dF = np.array([[0, 0, 0, 0]] * 4)
66+
for j in range(0, 2):
67+
for i in range(0, 2):
68+
ij = j * 2 + i
69+
for s in range(0, 2):
70+
for r in range(0, 2):
71+
rs = s * 2 + r
72+
dP_div_dF[ij, rs] = M[0, 0] * U[i, 0] * VT[0, j] * U[r, 0] * VT[0, s] \
73+
+ M[0, 3] * U[i, 0] * VT[0, j] * U[r, 1] * VT[1, s] \
74+
+ M[1, 1] * U[i, 0] * VT[1, j] * U[r, 0] * VT[1, s] \
75+
+ M[1, 2] * U[i, 0] * VT[1, j] * U[r, 1] * VT[0, s] \
76+
+ M[2, 1] * U[i, 1] * VT[0, j] * U[r, 0] * VT[1, s] \
77+
+ M[2, 2] * U[i, 1] * VT[0, j] * U[r, 1] * VT[0, s] \
78+
+ M[3, 0] * U[i, 1] * VT[1, j] * U[r, 0] * VT[0, s] \
79+
+ M[3, 3] * U[i, 1] * VT[1, j] * U[r, 1] * VT[1, s]
80+
return dP_div_dF
81+
82+
def deformation_grad(x, elemVInd, IB):
83+
F = [x[elemVInd[1]] - x[elemVInd[0]], x[elemVInd[2]] - x[elemVInd[0]]]
84+
return np.transpose(F).dot(IB)
85+
86+
def dPsi_div_dx(P, IB): # applying chain-rule, dPsi_div_dx = dPsi_div_dF * dF_div_dx
87+
dPsi_dx_2 = P[0, 0] * IB[0, 0] + P[0, 1] * IB[0, 1]
88+
dPsi_dx_3 = P[1, 0] * IB[0, 0] + P[1, 1] * IB[0, 1]
89+
dPsi_dx_4 = P[0, 0] * IB[1, 0] + P[0, 1] * IB[1, 1]
90+
dPsi_dx_5 = P[1, 0] * IB[1, 0] + P[1, 1] * IB[1, 1]
91+
return [np.array([-dPsi_dx_2 - dPsi_dx_4, -dPsi_dx_3 - dPsi_dx_5]), np.array([dPsi_dx_2, dPsi_dx_3]), np.array([dPsi_dx_4, dPsi_dx_5])]
92+
93+
def d2Psi_div_dx2(dP_div_dF, IB): # applying chain-rule, d2Psi_div_dx2 = dF_div_dx^T * d2Psi_div_dF2 * dF_div_dx (note that d2F_div_dx2 = 0)
94+
intermediate = np.array([[0.0, 0.0, 0.0, 0.0]] * 6)
95+
for colI in range(0, 4):
96+
_000 = dP_div_dF[0, colI] * IB[0, 0]
97+
_010 = dP_div_dF[0, colI] * IB[1, 0]
98+
_101 = dP_div_dF[2, colI] * IB[0, 1]
99+
_111 = dP_div_dF[2, colI] * IB[1, 1]
100+
_200 = dP_div_dF[1, colI] * IB[0, 0]
101+
_210 = dP_div_dF[1, colI] * IB[1, 0]
102+
_301 = dP_div_dF[3, colI] * IB[0, 1]
103+
_311 = dP_div_dF[3, colI] * IB[1, 1]
104+
intermediate[2, colI] = _000 + _101
105+
intermediate[3, colI] = _200 + _301
106+
intermediate[4, colI] = _010 + _111
107+
intermediate[5, colI] = _210 + _311
108+
intermediate[0, colI] = -intermediate[2, colI] - intermediate[4, colI]
109+
intermediate[1, colI] = -intermediate[3, colI] - intermediate[5, colI]
110+
result = np.array([[0.0, 0.0, 0.0, 0.0, 0.0, 0.0]] * 6)
111+
for colI in range(0, 6):
112+
_000 = intermediate[colI, 0] * IB[0, 0]
113+
_010 = intermediate[colI, 0] * IB[1, 0]
114+
_101 = intermediate[colI, 2] * IB[0, 1]
115+
_111 = intermediate[colI, 2] * IB[1, 1]
116+
_200 = intermediate[colI, 1] * IB[0, 0]
117+
_210 = intermediate[colI, 1] * IB[1, 0]
118+
_301 = intermediate[colI, 3] * IB[0, 1]
119+
_311 = intermediate[colI, 3] * IB[1, 1]
120+
result[2, colI] = _000 + _101
121+
result[3, colI] = _200 + _301
122+
result[4, colI] = _010 + _111
123+
result[5, colI] = _210 + _311
124+
result[0, colI] = -_000 - _101 - _010 - _111
125+
result[1, colI] = -_200 - _301 - _210 - _311
126+
return result
127+
128+
def val(x, e, vol, IB, mu, lam):
129+
sum = 0.0
130+
for i in range(0, len(e)):
131+
F = deformation_grad(x, e[i], IB[i])
132+
sum += vol[i] * Psi(F, mu[i], lam[i])
133+
return sum
134+
135+
def grad(x, e, vol, IB, mu, lam):
136+
g = np.array([[0.0, 0.0]] * len(x))
137+
for i in range(0, len(e)):
138+
F = deformation_grad(x, e[i], IB[i])
139+
P = vol[i] * dPsi_div_dF(F, mu[i], lam[i])
140+
g_local = dPsi_div_dx(P, IB[i])
141+
for j in range(0, 3):
142+
g[e[i][j]] += g_local[j]
143+
return g
144+
145+
def hess(x, e, vol, IB, mu, lam):
146+
IJV = [[0] * (len(e) * 36), [0] * (len(e) * 36), np.array([0.0] * (len(e) * 36))]
147+
for i in range(0, len(e)):
148+
F = deformation_grad(x, e[i], IB[i])
149+
dP_div_dF = vol[i] * d2Psi_div_dF2(F, mu[i], lam[i])
150+
local_hess = d2Psi_div_dx2(dP_div_dF, IB[i])
151+
for xI in range(0, 3):
152+
for xJ in range(0, 3):
153+
for dI in range(0, 2):
154+
for dJ in range(0, 2):
155+
ind = i * 36 + (xI * 3 + xJ) * 4 + dI * 2 + dJ
156+
IJV[0][ind] = e[i][xI] * 2 + dI
157+
IJV[1][ind] = e[i][xJ] * 2 + dJ
158+
IJV[2][ind] = local_hess[xI * 2 + dI, xJ * 2 + dJ]
159+
return IJV
160+
161+
def init_step_size(x, e, p):
162+
alpha = 1
163+
for i in range(0, len(e)):
164+
x21 = x[e[i][1]] - x[e[i][0]]
165+
x31 = x[e[i][2]] - x[e[i][0]]
166+
p21 = p[e[i][1]] - p[e[i][0]]
167+
p31 = p[e[i][2]] - p[e[i][0]]
168+
detT = np.linalg.det(np.transpose([x21, x31]))
169+
a = np.linalg.det(np.transpose([p21, p31])) / detT
170+
b = (np.linalg.det(np.transpose([x21, p31])) + np.linalg.det(np.transpose([p21, x31]))) / detT
171+
c = 0.9 # solve for alpha that first brings the new volume to 0.1x the old volume for slackness
172+
critical_alpha = utils.smallest_positive_real_root_quad(a, b, c)
173+
if critical_alpha > 0:
174+
alpha = min(alpha, critical_alpha)
175+
return alpha

inv_free/simulator.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@
1010
# simulation setup
1111
side_len = 1
1212
rho = 1000 # density of square
13-
k = 2e4 # spring stiffness
13+
E = 1e5 # Young's modulus
14+
nu = 0.4 # Poisson's ratio
1415
n_seg = 4 # num of segments per side of the square
1516
h = 0.01 # time step size in s
1617
DBC = [(n_seg + 1) * (n_seg + 1)] # dirichlet node index
1718
DBC_v = [np.array([0.0, -0.5])] # dirichlet node velocity
18-
DBC_limit = [np.array([0.0, -0.6])] # dirichlet node limit position
19+
DBC_limit = [np.array([0.0, -0.7])] # dirichlet node limit position
1920
ground_n = np.array([0.0, 1.0]) # normal of the slope
2021
ground_n /= np.linalg.norm(ground_n) # normalize ground normal vector just in case
2122
ground_o = np.array([0.0, -1.0]) # a point on the slope
@@ -26,12 +27,15 @@
2627
x = np.append(x, [[0.0, side_len * 0.6]], axis=0) # ceil origin (with normal [0.0, -1.0])
2728
v = np.array([[0.0, 0.0]] * len(x)) # velocity
2829
m = [rho * side_len * side_len / ((n_seg + 1) * (n_seg + 1))] * len(x) # calculate node mass evenly
29-
# rest length squared
30-
l2 = []
30+
# rest shape basis, volume, and lame parameters
31+
vol = [0.0] * len(e)
32+
IB = [np.array([[0.0, 0.0]] * 2)] * len(e)
3133
for i in range(0, len(e)):
32-
diff = x[e[i][0]] - x[e[i][1]]
33-
l2.append(diff.dot(diff))
34-
k = [k] * len(e) # spring stiffness
34+
TB = [x[e[i][1]] - x[e[i][0]], x[e[i][2]] - x[e[i][0]]]
35+
vol[i] = np.linalg.det(np.transpose(TB)) / 2
36+
IB[i] = np.linalg.inv(np.transpose(TB))
37+
mu_lame = [0.5 * E / (1 + nu)] * len(e)
38+
lam = [E * nu / ((1 + nu) * (1 - 2 * nu))] * len(e)
3539
# identify whether a node is Dirichlet
3640
is_DBC = [False] * len(x)
3741
for i in DBC:
@@ -64,14 +68,16 @@ def screen_projection(x):
6468
screen_projection([x[-1][0] - 3.0, x[-1][1]])) # ceil
6569
for eI in e:
6670
pygame.draw.aaline(screen, (0, 0, 255), screen_projection(x[eI[0]]), screen_projection(x[eI[1]]))
71+
pygame.draw.aaline(screen, (0, 0, 255), screen_projection(x[eI[1]]), screen_projection(x[eI[2]]))
72+
pygame.draw.aaline(screen, (0, 0, 255), screen_projection(x[eI[2]]), screen_projection(x[eI[0]]))
6773
for xId in range(0, len(x) - 1):
6874
xI = x[xId]
6975
pygame.draw.circle(screen, (0, 0, 255), screen_projection(xI), 0.1 * side_len / n_seg * scale)
7076

7177
pygame.display.flip() # flip the display
7278

7379
# step forward simulation and wait for screen refresh
74-
[x, v] = time_integrator.step_forward(x, e, v, m, l2, k, ground_n, ground_o, contact_area, mu, is_DBC, DBC, DBC_v, DBC_limit, h, 1e-2)
80+
[x, v] = time_integrator.step_forward(x, e, v, m, vol, IB, mu_lame, lam, ground_n, ground_o, contact_area, mu, is_DBC, DBC, DBC_v, DBC_limit, h, 1e-2)
7581
time_step += 1
7682
pygame.time.wait(int(h * 1000))
7783

inv_free/square_mesh.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,16 @@ def generate(side_length, n_seg):
88
for j in range(0, n_seg + 1):
99
x[i * (n_seg + 1) + j] = [-side_length / 2 + i * step, -side_length / 2 + j * step]
1010

11-
# connect the nodes with edges
11+
# connect the nodes with triangle elements
1212
e = []
13-
# horizontal edges
14-
for i in range(0, n_seg):
15-
for j in range(0, n_seg + 1):
16-
e.append([i * (n_seg + 1) + j, (i + 1) * (n_seg + 1) + j])
17-
# vertical edges
18-
for i in range(0, n_seg + 1):
19-
for j in range(0, n_seg):
20-
e.append([i * (n_seg + 1) + j, i * (n_seg + 1) + j + 1])
21-
# diagonals
2213
for i in range(0, n_seg):
2314
for j in range(0, n_seg):
24-
e.append([i * (n_seg + 1) + j, (i + 1) * (n_seg + 1) + j + 1])
25-
e.append([(i + 1) * (n_seg + 1) + j, i * (n_seg + 1) + j + 1])
15+
# triangulate each cell following a symmetric pattern:
16+
if (i % 2)^(j % 2):
17+
e.append([i * (n_seg + 1) + j, (i + 1) * (n_seg + 1) + j, i * (n_seg + 1) + j + 1])
18+
e.append([(i + 1) * (n_seg + 1) + j, (i + 1) * (n_seg + 1) + j + 1, i * (n_seg + 1) + j + 1])
19+
else:
20+
e.append([i * (n_seg + 1) + j, (i + 1) * (n_seg + 1) + j, (i + 1) * (n_seg + 1) + j + 1])
21+
e.append([i * (n_seg + 1) + j, (i + 1) * (n_seg + 1) + j + 1, i * (n_seg + 1) + j + 1])
2622

2723
return [x, e]

inv_free/time_integrator.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
from scipy.sparse.linalg import spsolve
88

99
import InertiaEnergy
10-
import MassSpringEnergy
10+
import NeoHookeanEnergy
1111
import GravityEnergy
1212
import BarrierEnergy
1313
import FrictionEnergy
1414
import SpringEnergy
1515

16-
def step_forward(x, e, v, m, l2, k, n, o, contact_area, mu, is_DBC, DBC, DBC_v, DBC_limit, h, tol):
16+
def step_forward(x, e, v, m, vol, IB, mu_lame, lam, n, o, 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)
1919
mu_lambda = BarrierEnergy.compute_mu_lambda(x, n, o, contact_area, mu) # compute mu * lambda for each node using x^n
@@ -23,54 +23,54 @@ def step_forward(x, e, v, m, l2, k, n, o, contact_area, mu, is_DBC, DBC, DBC_v,
2323
DBC_target.append(x_n[DBC[i]] + h * DBC_v[i])
2424
else:
2525
DBC_target.append(x_n[DBC[i]])
26-
DBC_stiff = 10 # initialize stiffness for DBC springs
26+
DBC_stiff = 1000 # initialize stiffness for DBC springs
2727

2828
# Newton loop
2929
iter = 0
30-
E_last = IP_val(x, e, x_tilde, m, l2, k, n, o, 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, l2, k, n, o, contact_area, (x - x_n) / h, mu_lambda, 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, 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, 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, l2, k, n, o, contact_area, (x - x_n) / h, mu_lambda, DBC, DBC_target, DBC_stiff, h)
39+
E_last = IP_val(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, contact_area, (x - x_n) / h, mu_lambda, DBC, DBC_target, DBC_stiff, h)
4040

4141
# filter line search
42-
alpha = BarrierEnergy.init_step_size(x, n, o, p) # avoid interpenetration and tunneling
43-
while IP_val(x + alpha * p, e, x_tilde, m, l2, k, n, o, contact_area, (x - x_n) / h, mu_lambda, DBC, DBC_target, DBC_stiff, h) > E_last:
42+
alpha = min(BarrierEnergy.init_step_size(x, n, o, 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, contact_area, (x - 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, l2, k, n, o, 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, l2, k, n, o, contact_area, (x - x_n) / h, mu_lambda, 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, 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, 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, l2, k, n, o, contact_area, v, mu_lambda, DBC, DBC_target, DBC_stiff, h):
55+
def IP_val(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, contact_area, v, mu_lambda, DBC, DBC_target, DBC_stiff, h):
5656
return InertiaEnergy.val(x, x_tilde, m) + h * h * ( # implicit Euler
57-
MassSpringEnergy.val(x, e, l2, k) +
57+
NeoHookeanEnergy.val(x, e, vol, IB, mu_lame, lam) +
5858
GravityEnergy.val(x, m) +
5959
BarrierEnergy.val(x, n, o, contact_area) +
6060
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, l2, k, n, o, contact_area, v, mu_lambda, DBC, DBC_target, DBC_stiff, h):
63+
def IP_grad(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, contact_area, v, mu_lambda, DBC, DBC_target, DBC_stiff, h):
6464
return InertiaEnergy.grad(x, x_tilde, m) + h * h * ( # implicit Euler
65-
MassSpringEnergy.grad(x, e, l2, k) +
65+
NeoHookeanEnergy.grad(x, e, vol, IB, mu_lame, lam) +
6666
GravityEnergy.grad(x, m) +
6767
BarrierEnergy.grad(x, n, o, contact_area) +
6868
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, l2, k, n, o, contact_area, v, mu_lambda, DBC, DBC_target, DBC_stiff, h):
71+
def IP_hess(x, e, x_tilde, m, vol, IB, mu_lame, lam, n, o, contact_area, v, mu_lambda, DBC, DBC_target, DBC_stiff, h):
7272
IJV_In = InertiaEnergy.hess(x, x_tilde, m)
73-
IJV_MS = MassSpringEnergy.hess(x, e, l2, k)
73+
IJV_MS = NeoHookeanEnergy.hess(x, e, vol, IB, mu_lame, lam)
7474
IJV_B = BarrierEnergy.hess(x, n, o, contact_area)
7575
IJV_F = FrictionEnergy.hess(v, mu_lambda, h, n)
7676
IJV_S = SpringEnergy.hess(x, m, DBC, DBC_target, DBC_stiff)
@@ -84,9 +84,9 @@ def IP_hess(x, e, x_tilde, m, l2, k, n, o, contact_area, v, mu_lambda, DBC, DBC_
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, l2, k, n, o, contact_area, v, mu_lambda, is_DBC, DBC, DBC_target, DBC_stiff, tol, h):
88-
projected_hess = IP_hess(x, e, x_tilde, m, l2, k, n, o, contact_area, v, mu_lambda, DBC, DBC_target, DBC_stiff, h)
89-
reshaped_grad = IP_grad(x, e, x_tilde, m, l2, k, n, o, contact_area, v, mu_lambda, 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, 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, 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, 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)):

0 commit comments

Comments
 (0)