def energy(self): ans = 0 for e in range(self.Ne): model = Corotated(self.config.mu, self.config.lambd, self.F[e, :, :]) ans += self.vol[e] * model.psi() return ans
def Df(self): """Df = grad(f_int) = -Hessian(e)""" d, num_inside_pts = self.config.d, self.num_inside_pts df_dphi = np.zeros((d * num_inside_pts, d * num_inside_pts)) mu, lambd = self.config.mu, self.config.lambd for e in range(self.Ne): model = Corotated(mu, lambd, self.F[e, :, :]) dPdF = model.dPdF() for p in range(d + 1): mesh_i = (d + 1) * e + p i = self.mesh[mesh_i] for q in range(d + 1): mesh_j = (d + 1) * e + q # for mesh_j in self.incident_element[i]: j = self.mesh[mesh_j] vectori, vectorj = self.i_to_vectori[i], self.i_to_vectori[ j] if vectori != None and vectorj != None: for beta in range(d): for gamma in range(d): for alpha in range(d): for epsilon in range(d): df_dphi[vectori*d+beta, vectorj*d+alpha] -= \ self.vol[e]*dPdF[beta*d+gamma, alpha*d+epsilon]*self.grad_N[mesh_j,epsilon]*self.grad_N[mesh_i,gamma] return df_dphi
def del_f(self): """Blackbox function for CG""" d = self.config.d dP_function_list = [] for e in range(self.Ne): model = Corotated(self.config.mu, self.config.lambd, self.F[e, :, :]) dP_function_list.append(model.dP) def calculate_del_f(del_phi): ans = np.zeros(self.num_inside_pts * d) del_F_vector = self.del_F(del_phi) for e in range(self.Ne): dP = dP_function_list[e](del_F_vector[e]) for p in range(d + 1): i = self.mesh[(d + 1) * e + p] vectori = self.i_to_vectori[i] if vectori != None: for beta in range(d): for gamma in range(d): ans[d * vectori + beta] -= self.vol[e] * dP[ beta, gamma] * self.grad_N[(d + 1) * e + p, gamma] return ans df = LinearOperator((self.num_inside_pts * d, self.num_inside_pts * d), matvec=calculate_del_f) return df
def internal_force(self): """assembly external force vector based on current deformed_grid, Ds, F""" """f_int = -grad(e)""" d, num_inside_pts = self.config.d, self.num_inside_pts f = np.zeros(d * num_inside_pts) mu, lambd = self.config.mu, self.config.lambd for e in range(self.Ne): model = Corotated(mu, lambd, self.F[e, :, :]) P = model.P() for p in range(d + 1): i = self.mesh[(d+1)*e+p] vectori = self.i_to_vectori[i] if vectori != None: for beta in range(d): for gamma in range(d): f[d*vectori+beta] -= self.vol[e]*P[beta,gamma]*self.grad_N[(d+1)*e+p, gamma] # Add gravity f += self.gravity_force return f