77from scipy .sparse .linalg import spsolve
88
99import InertiaEnergy
10- import MassSpringEnergy
10+ import NeoHookeanEnergy
1111import GravityEnergy
1212import BarrierEnergy
1313import FrictionEnergy
1414import 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