def update(self, uNod, mater): """ update strain and stress tensors of the element from the displacement field 'uNod' with the material model 'mater' """ # dshape = np.shape(self.dshape) # dshape = (npg, npN, dim) # npg is the number of gauss points to integration # npN is the number of nodes in each element # dim is the dimention of the problem. If 2D -> dim = 2 npg = self.getNpg() for i in range(npg): # loop on integration points # compute CG stretch tensor and GL strain tensor G = self.gradient(self.dshape[i], uNod) F = G + tensor.I(len(G)) self.F[i] = F # store deformation gradient at integration point i C = tensor.rightCauchyGreen(F) self.E_GL[i] = 0.5 * (C - tensor.I(len(C))) # compute spatial description # from scipy.linalg.polar() method with u=R and p=V, _, V = polar(F, side='left') # replace pure zeros by very low values to prevent "nan" in np.log(V) V[V < 1e-10] = 1e-15 self.hencky[i] = np.log(V) # ln(V) with F = V.R, "true" strain b = tensor.leftCauchyGreen(F) self.E_EA[i] = 0.5 * (tensor.I(len(b)) - tensor.inv(b)) ### if (mater == 0): # skip next lines: do not compute stress # print("Whahat") continue # compute PK2 stress tensor and material tangent operator M=2*dS/dC # print("type(mater) = " + str(type(mater))) # print("mater = " + str(mater)) (PK2, M) = mater.stress_stiffness(C) # compute PK1 stress and lagrangian tangent operator K = dP/dF # print("PK2 = ") # print(PK2) # print("F = ") # print(F) self.PK1[i] = tensor.PK2toPK1(F, PK2) # print("PK1[i] = ") # print(self.PK1[i]) # print("PK1[i] = ") # print(self.PK1[i]) self.K[i] = tensor.MaterialToLagrangian(F, PK2, M) # compute cauchy stress (spatial description) self.sigma[i] = tensor.PK1toCauchy(F, self.PK1[i])
def stress(self, C): """ Compute 2nd Piola-Kirchhoff stress PK2 = 2*dphi/dC = lambda * tr(E) * I + 2 * mu * E """ dim = len(C) PK2 = tensor.tensor(dim) lamda = self.get1LAME() mu = self.get2LAME() E = tensor.tensor(dim) E = 0.5 * (C - tensor.I(dim)) II = tensor.I(dim) PK2 = lamda * tensor.trace(E) * II + 2 * mu * E return PK2
def potential(self, C): """ Compute hyperelastic potential: phi = lamdabda/2 * tr(E)^2 - mu*(E:E) """ lamda = self.get1LAME() mu = self.get2LAME() EL = 0.5 * (C - tensor.I(len(C))) # Lagrangian strain E phi = lamda / 2. * (tensor.trace(EL))**2 + mu * np.tensordot(EL, EL, 2) return phi
def stiffness(self, C): """ Compute material tangent M = 2*dS/dC """ dim = len(C) lamda = self.get1LAME() mu = self.get2LAME() I = tensor.I(dim) IxI = tensor.outerProd4(I, I) IIsym = tensor.IISym(dim) M = lamda * IxI + 2 * mu * IIsym return M
def compute_materialtangent(self): # ============================================================================================= #%% Compute error on material tangent operator by finite (central) difference of stress # ============================================================================================= d = self.FE_model.dim DC = 1.e-5 TOLMAX = 1.e-3 PRECISION = 1.e-16 printerror = False e = 1 # element KerrMax = 1e-30 for e in range(self.FE_model.nElements()): Ed = self.E[e].reshape(d, d) # Lagrange deformation Cd = 2 * Ed + tensor.I(d) # right Cauchy-Green tensor Sp = tensor.tensor(d) # S(C+DC/2) Piola Kirchhoff II tensor "plus" # S(C-DC/2) Piola Kirchhoff II tensor "minus" Sm = tensor.tensor(d) S = self.FE_model.material.stress(Cd) # Lagrangian tangent operator 2*dS/dC M = self.FE_model.material.stiffness(Cd) for k in range(d): for l in range(d): Cd[k, l] += DC / 2. Sp = self.FE_model.material.stress(Cd) Cd[k, l] -= DC Sm = self.FE_model.material.stress(Cd) Cd[k, l] += DC / 2. # come back to before perturbation for i in range(d): for j in range(d): Knum = (Sp[i, j] - Sm[i, j] + Sp[j, i] - Sm[j, i]) / DC # 2*(Sp-Sm + Sp-Sm)/2/DC # K_ijkl = ( S_ij(C_kl+DC/2) - S_ji(C_kl-DC/2) ) SYM if (np.fabs(M[i, j, k, l]) > 1.0): Ktest = np.fabs(M[i, j, k, l]) else: Ktest = 1.0 Kerr = np.fabs(M[i, j, k, l] - Knum) / Ktest if (Kerr > KerrMax): KerrMax = Kerr if (printerror) and (Kerr > TOLMAX) and (np.fabs(Knum) > PRECISION): print('%d %d %d %d %13.6e %13.6e %13.6e' % (i, j, k, l, M[i, j, k, l], Knum, Kerr)) # print('Maximal error = %13.6e' % KerrMax) if KerrMax > TOLMAX: msg = "Material tangent not valided: KerrMax = %.2e" % KerrMax raise Exception(msg)
def compute_stress(self): # ============================================================================================= #%% Compute error on stress by finite (central) difference of energy potential # ============================================================================================= d = self.FE_model.getDim() DC = 1.e-5 TOLMAX = 1.e-3 PRECISION = 1.e-16 printerror = True e = 1 # element SerrMax = 1e-30 nElements = self.FE_model.nElements() for e in range(nElements): Ed = self.E[e].reshape(d, d) # Lagrange deformation Cd = 2 * Ed + tensor.I(d) # right Cauchy-Green tensor S = self.FE_model.material.stress(Cd) for i in range(d): for j in range(d): Cd[i, j] += DC / 2. # phi(C_ij + DC/2), potential plus phip = self.FE_model.material.potential(Cd) Cd[i, j] -= DC phim = self.FE_model.material.potential(Cd) Cd[i, j] += DC / 2. # come back to before perturbation # S_ij = 2*(phi(C_ij+DC/2) - phi(C_ij-DC/2))/DC Snum = 2 * (phip - phim) / DC if (np.fabs(S[i, j]) > 1.0): Stest = np.fabs(S[i, j]) else: Stest = 1.0 Serr = np.fabs(S[i, j] - Snum) / Stest if (Serr > SerrMax): SerrMax = Serr if (printerror) and (Serr > TOLMAX) and (np.fabs(Snum) > PRECISION): print('%d %d %13.6e %13.6e %13.6e' % (i, j, S[i, j], Snum, Serr)) # print('Maximal error = %13.6e' % SerrMax) if SerrMax > TOLMAX: msg = "Stress computation not valided: SerrMax = %.2e" % SerrMax raise Exception(msg)
def stress(self, C): """ Compute 2nd Piola-Kirchhoff stress """ dim = len(C) PK2 = tensor.tensor(dim) detC = tensor.det(C) detF = np.sqrt(detC) lnJ = np.log(detF) lamda = self.get1LAME() mu = self.get2LAME() invC = tensor.inv(C) I = tensor.I(dim) PK2 = mu * (I - invC) + lamda * lnJ * invC return PK2
def I(): tensor.I()
v[0] = 1.0 v[1] = 2.0 #to access the elements of an array you must use brackets. Paranthesis are restricted to the call of functions. print("v =\n", v) # # --- Test methods for 2nd-order tensors # print("\nTest methods for 2nd-order tensors") print("==================================") # Create a 2nd-order tensor, initialized to zero. A = tensor.tensor() print("\nA =\n", A) # Compute identity 2nd-order tensor I = tensor.I() print("\nI =\n", I) # Tensor product of two vectors B = tensor.outerProd(v, v) print("\nB =\n", B) # Compute determinant detB = tensor.det(B) print("\ndetB =\n", detB) # Compute trace trB = tensor.trace(B) print("\ntrB =\n", trB) # Non symmetrical tensor