def Permittivity(self,StrainTensors,ElectricDisplacementx,elem=0,gcounter=0): mu1 = self.mu1 mu2 = self.mu2 mue = self.mue lamb = self.lamb eps_1 = self.eps_1 eps_2 = self.eps_2 eps_e = self.eps_e I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] D = ElectricDisplacementx.reshape(self.ndim,1) Dx = D.reshape(self.ndim) DD = np.dot(D.T,D)[0,0] D0D = np.dot(D,D.T) if self.ndim==2: trb = trace(b) + 1 else: trb = trace(b) self.dielectric_tensor = J/eps_1*np.linalg.inv(b) + 1./eps_2*I + \ 4.*J/eps_e*trb*I + \ 8.*J**3/mue/eps_e**2*(D0D + 0.5*DD*I) # TRANSFORM TENSORS TO THEIR ENTHALPY COUNTERPART H_Voigt = -np.linalg.inv(self.dielectric_tensor) return H_Voigt
def CauchyStress(self, StrainTensors, ElectricDisplacementx, elem=0, gcounter=0): mu1 = self.mu1 mu2 = self.mu2 lamb = self.lamb eps_1 = self.eps_1 I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] D = ElectricDisplacementx.reshape(self.ndim, 1) if self.ndim == 2: trb = trace(b) + 1 else: trb = trace(b) simga_mech = 2.0*mu1/J*b + \ 2.0*mu2/J*(trb*b - np.dot(b,b)) -\ 2.0*(mu1+2*mu2)/J*I +\ lamb*(J-1)*I sigma_electric = J / eps_1 * np.dot(D, D.T) sigma = simga_mech + sigma_electric return sigma
def CauchyStress(self,StrainTensors,ElectricDisplacementx,elem=0,gcounter=0): mu1 = self.mu1 mu2 = self.mu2 mue = self.mue lamb = self.lamb eps_2 = self.eps_2 eps_e = self.eps_e I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] D = ElectricDisplacementx.reshape(self.ndim,1) DD = np.dot(D.T,D)[0,0] D0D = np.dot(D,D.T) if self.ndim==2: trb = trace(b) + 1 else: trb = trace(b) sigma_mech = 2.0*mu1/J*b + \ 2.0*mu2/J*(trb*b - np.dot(b,b)) -\ 2.0*(mu1+2*mu2+6*mue)/J*I +\ lamb*(J-1)*I +\ 4.*mue/J*trb*b sigma_electric = 1./eps_2*(D0D - 0.5*DD*I) # REGULARISATION TERMS sigma_reg = 4.*J/eps_e*(DD*b + trb*D0D) + \ 4.0*J**3/mue/eps_e**2*DD*D0D sigma = sigma_mech + sigma_electric + sigma_reg return sigma
def CauchyStress(self,StrainTensors,ElectricFieldx=None,elem=0,gcounter=0): kappa = self.kappa mu = self.mu k1 = self.k1 k2 = self.k2 I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] F = StrainTensors['F'][gcounter] if self.ndim == 3: trb = trace(b) elif self.ndim == 2: trb = trace(b) + 1 stress = mu*J**(-5./3.)*(b - 1./3.*trb*I) if self.is_nearly_incompressible: stress += self.pressure*I else: stress += kappa*(J-1.)*I # Anisotropic contibution nfibres = self.anisotropic_orientations.shape[1] for i_fibre in range(nfibres): N = self.anisotropic_orientations[elem,i_fibre,:,None] FN = np.dot(F,N)[:,0] innerFN = einsum('i,i',FN,FN) outerFN = einsum('i,j',FN,FN) expo = np.exp(k2*(innerFN-1.)**2) stress += 2.*k1/J*(innerFN-1.)*expo*outerFN return stress
def Hessian(self, StrainTensors, ElectricFieldx=None, elem=0, gcounter=0): """Hessian split into isochoroic and volumetric parts""" I = StrainTensors['I'] b = StrainTensors['b'][gcounter] J = StrainTensors['J'][gcounter] mu = self.mu kappa = self.kappa # ISOCHORIC H_Voigt = 2*mu*J**(-5./3.)*(1./9.*trace(b)*einsum('ij,kl',I,I) - \ 1./3.*(einsum('ij,kl',b,I) + einsum('ij,kl',I,b)) +\ 1./6.*trace(b)*(einsum('ik,jl',I,I) + einsum('il,jk',I,I)) ) # VOLUMETRIC CHANGES if self.is_nearly_incompressible: H_Voigt += self.pressure * ( einsum('ij,kl', I, I) - (einsum('ik,jl', I, I) + einsum('il,jk', I, I))) else: H_Voigt += kappa * ( (2. * J - 1.) * einsum('ij,kl', I, I) - (J - 1.) * (einsum('ik,jl', I, I) + einsum('il,jk', I, I))) H_Voigt = Voigt(H_Voigt, 1) self.H_VoigtSize = H_Voigt.shape[0] return H_Voigt
def CauchyStress(self, StrainTensors, ElectricFieldx, elem=0, gcounter=0): alpha = self.alpha beta = self.beta kappa = self.kappa I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] F = StrainTensors['F'][gcounter] H = J * np.linalg.inv(F).T g = np.dot(H, H.T) bcross = trace(b) * b - np.dot(b, b) # b=np.dot(F,F.T) # stress = 2.*alpha*J**(-5/3.)*b - 2./3.*alpha*J**(-5/3.)*trace(b)*I + \ # beta*J**(-3)*trace(g)**(3./2.)*I - 3*beta*J**(-3)*trace(g)**(1./2.)*g + \ # +(kappa*(J-1.0))*I ##### if self.ndim == 2: trb = trace(b) + 1 trg = trace(g) + J**2 elif self.ndim == 3: trb = trace(b) trg = trace(g) stress = 2.*alpha*J**(-5/3.)*b - 2./3.*alpha*J**(-5/3.)*(trb)*I + \ beta*J**(-3)*(trg)**(3./2.)*I - 3*beta*J**(-3)*(trg)**(1./2.)*g + \ +(kappa*(J-1.0))*I return stress
def CauchyStress(self, StrainTensors, ElectricFieldx, elem=0, gcounter=0): I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] F = StrainTensors['F'][gcounter] H = J * np.linalg.inv(F).T N = self.anisotropic_orientations[elem][:, None] FN = np.dot(F, N) HN = np.dot(H, N)[:, 0] innerFN = np.dot(FN.T, FN)[0][0] innerHN = einsum('i,i', HN, HN) outerHN = einsum('i,j', HN, HN) E = self.E E_A = self.E_A v = self.nu gamma = self.gamma lamb = -(E_A * E * v) / (2. * E * v**2 + E_A * v - E_A) ut = (E**2 * v**2 + E_A * E * v**2 + E_A * E * v - E_A * E) / (2 * (v + 1) * (2 * E * v**2 + E_A * v - E_A)) beta = 0. eta_1 = (E_A**2 * v**2 - E_A**2 - 2 * E_A * E * v**2 + E_A * E + E**2 * v**2) / (4 * (gamma - 1) * (v + 1) * (2 * E * v**2 + E_A * v - E_A)) eta_2 = -(E_A**2 * v - E_A**2 + E_A * E - E_A * E * v) / ( 4 * (gamma - 1) * (2 * E * v**2 + E_A * v - E_A)) alpha = ut - 4 * gamma * beta - 2 * (1 - gamma) * eta_1 - 2 * ( 1 - gamma) * eta_2 alpha = alpha / 2. / gamma eta = [eta_1, eta_2] if self.ndim == 3: trb = trace(b) elif self.ndim == 2: trb = trace(b) + 1 stress = 2. * gamma * alpha / J * b + 2. * gamma * beta / J * ( trb * b - np.dot(b, b)) - ut / J * I + lamb * (J - 1.) * I # n=1 # m=2 # stressNCN_1 = self.CauchyStressNCN(StrainTensors,m,eta,gamma,FN,innerFN,elem,gcounter) # stressNGN_1 = self.CauchyStressNGN(StrainTensors,n,eta,gamma,innerHN,outerHN,elem,gcounter) # stress += stressNCN_1 # stress += stressNGN_1 for m in range(2, 4): stress += self.CauchyStressNCN(StrainTensors, m, eta[m - 2], gamma, FN, innerFN, elem, gcounter) stress += self.CauchyStressNGN(StrainTensors, 1., eta_1, gamma, innerHN, outerHN, elem, gcounter) stress += self.CauchyStressNGN(StrainTensors, 1., eta_2, gamma, innerHN, outerHN, elem, gcounter) # print stress return stress
def CauchyStress(self, StrainTensors, ElectricFieldx=None, elem=0, gcounter=0): I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] strain = StrainTensors['strain'][gcounter] # mu = self.mu # lamb = self.lamb # return 1.0*mu/J*b + (lamb*(J-1.0)-mu/J)*I mu = self.mu lamb = self.lamb # Jb = 1.27168554933 Jb = self.Jbar[elem] # CHECK IF THIS IS NECESSARY if self.ndim == 3: tre = trace(strain) elif self.ndim == 2: tre = trace(strain) + 1 sigma_linear = 2. * mu * strain + lamb * tre * I simga_nonlinear = 1.0 * mu / J * b + (lamb * (J - Jb) - mu / J) * I alp = 0.1 # simga = (1-alp)*simga_nonlinear + alp*sigma_linear simga = simga_nonlinear return simga
def Hessian(self,StrainTensors,ElectricDisplacementx,elem=0,gcounter=0): mu1 = self.mu1 mu2 = self.mu2 mue = self.mue lamb = self.lamb eps_1 = self.eps_1 eps_2 = self.eps_2 eps_e = self.eps_e I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] D = ElectricDisplacementx.reshape(self.ndim,1) Dx = D.reshape(self.ndim) DD = np.dot(D.T,D)[0,0] D0D = np.dot(D,D.T) if self.ndim==2: trb = trace(b) + 1 else: trb = trace(b) C_mech = 2.*mu2/J*(2*einsum('ij,kl',b,b) - einsum('ik,jl',b,b) - einsum('il,jk',b,b)) +\ 2.*(mu1+2.*mu2+6*mue)/J*( einsum("ik,jl",I,I)+einsum("il,jk",I,I) ) + \ lamb*(2.*J-1.)*einsum("ij,kl",I,I) - lamb*(J-1)*( einsum("ik,jl",I,I)+einsum("il,jk",I,I) ) +\ 8.*mue/J*einsum('ij,kl',b,b) C_elect = 1./eps_2*(0.5*DD*(einsum('ik,jl',I,I) + einsum('il,jk',I,I) + einsum('ij,kl',I,I) ) - \ einsum('ij,k,l',I,Dx,Dx) - einsum('i,j,kl',Dx,Dx,I)) # REGULARISATION TERMS C_reg = 8.*J/eps_e*( einsum('ij,k,l',b,Dx,Dx) + einsum('i,j,kl',Dx,Dx,b) ) + \ 8.*J**3/mue/eps_e**2*einsum('i,j,k,l',Dx,Dx,Dx,Dx) self.elasticity_tensor = C_mech + C_elect + C_reg self.coupling_tensor = 1./eps_2*(einsum('ik,j',I,Dx) + einsum('i,jk',Dx,I) - einsum('ij,k',I,Dx)) + \ 8*J/eps_e*einsum('ij,k',b,Dx) + 4*J/eps_e*trb*( einsum('ik,j',I,Dx) + einsum('i,jk',Dx,I) ) +\ 4.*J**3/mue/eps_e**2*DD* ( einsum('ik,j',I,Dx) + einsum('i,jk',Dx,I) ) + 8.*J**3/mue/eps_e**2*einsum('i,j,k',Dx,Dx,Dx) self.dielectric_tensor = J/eps_1*np.linalg.inv(b) + 1./eps_2*I + \ 4.*J/eps_e*trb*I + \ 8.*J**3/mue/eps_e**2*(D0D + 0.5*DD*I) # TRANSFORM TENSORS TO THEIR ENTHALPY COUNTERPART E_Voigt, P_Voigt, C_Voigt = self.legendre_transform.InternalEnergyToEnthalpy(self.dielectric_tensor, self.coupling_tensor, self.elasticity_tensor) # BUILD HESSIAN factor = -1. H1 = np.concatenate((C_Voigt,factor*P_Voigt),axis=1) H2 = np.concatenate((factor*P_Voigt.T,E_Voigt),axis=1) H_Voigt = np.concatenate((H1,H2),axis=0) return H_Voigt
def InternalEnergy(self,StrainTensors,ElectricFieldx,elem=0,gcounter=0): mu = self.mu lamb = self.lamb strain = StrainTensors['strain'][gcounter] if self.ndim == 3: tre = trace(strain) elif self.ndim == 2: tre = trace(strain) + 1 energy = lamb/2.*tre**2 + mu*np.einsum("ij,ij",strain,strain) return energy
def CauchyStress(self, StrainTensors, ElectricDisplacementx, elem=0, gcounter=0): mu = self.mu lamb = self.lamb d = self.ndim I = StrainTensors['I'] F = StrainTensors['F'][gcounter] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] u, s, vh = svd(F, full_matrices=True) vh = vh.T R = u.dot(vh.T) S = np.dot(vh, np.dot(np.diag(s), vh.T)) J2 = J**2 J3 = J**3 I1 = trace(S) I2 = trace(b) if self.ndim == 2: sigma = 2. * (1. + 1. / J2) * F - 2. * (1. + 1. / J) * R + ( 2. / J2) * (I1 - I2 / J) * dJdF(F) else: djdf = dJdF(F) C = np.dot(F.T, F) IC = trace(C) IIC = trace(C.dot(C)) IIStarC = 0.5 * (IC * IC - IIC) IS = trace(S) # IIS = trace(S.dot(S)); IIS = I2 IIStarS = 0.5 * (IS * IS - IIS) # % here's symmetric dirichlet dIIStarC = 2 * IC * F - 2. * b.dot(F) P = 2 * F + dIIStarC / J2 - (2. / J3) * IIStarC * djdf P = P - 2 * ((1 + IS / J) * R - (IIStarS / J2) * djdf - (1. / J) * F) P = P / 2. sigma = P makezero(sigma, 1e-12) # print(sigma) return sigma
def CauchyStress(self, StrainTensors, ElectricDisplacementx, elem=0, gcounter=0): mu1 = self.mu1s[elem] mu2 = self.mu2s[elem] mu3 = self.mu3s[elem] lamb = self.lambs[elem] eps_1 = self.eps_1s[elem] eps_2 = self.eps_2s[elem] eps_3 = self.eps_3s[elem] I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] F = StrainTensors['F'][gcounter] H = J * np.linalg.inv(F).T N = self.anisotropic_orientations[elem][:, None] FN = np.dot(F, N)[:, 0] HN = np.dot(H, N)[:, 0] outerFN = einsum('i,j', FN, FN) innerHN = einsum('i,i', HN, HN) outerHN = einsum('i,j', HN, HN) D = ElectricDisplacementx.reshape(self.ndim, 1) Dx = D.reshape(self.ndim) DD = np.dot(D.T, D)[0, 0] D0D = np.dot(D, D.T) if self.ndim == 3: trb = trace(b) elif self.ndim == 2: trb = trace(b) + 1. sigma_mech = 2.*mu1/J*b + \ 2.*mu2/J*(trb*b - np.dot(b,b)) - \ 2.*(mu1+2*mu2+mu3)/J*I + \ lamb*(J-1)*I +\ 2*mu3/J*outerFN +\ 2*mu3/J*innerHN*I - 2*mu3/J*outerHN sigma_electric = 1./eps_2*(D0D - 0.5*DD*I) +\ 2.*J*sqrt(mu3/eps_3)*D0D + 2*sqrt(mu3/eps_3)*(einsum('i,j',Dx,FN) + einsum('i,j',FN,Dx)) sigma = sigma_mech + sigma_electric return sigma
def CauchyStress(self, StrainTensors, ElectricDisplacementx, elem=0, gcounter=0): mu = self.mu mu1 = self.mu1 mu2 = self.mu2 lamb = self.lamb d = self.ndim I = StrainTensors['I'] F = StrainTensors['F'][gcounter] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] trb = trace(b) + 0 sigma = 2. / d * J**(-2. / d - 1.) * (-1. / d * trb * I + b) sigma *= (1. / d * J**(-2 / d) * trb - 1) sigma = mu * sigma sigma += 2.0*mu1/J*b + \ 2.0*mu2/J*(trb*b - np.dot(b,b)) -\ 2.0*(mu1+2*mu2)/J*I +\ lamb*(J-1)*I return sigma
def CauchyStress(self, StrainTensors, ElectricFieldx=None, elem=0, gcounter=0): I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] F = StrainTensors['F'][gcounter] C = np.dot(F.T, F) if np.isclose(J, 0) or J < 0: delta = np.sqrt(0.04 * J * J + 1e-8) J = 0.5 * (J + np.sqrt(J**2 + 4 * delta**2)) mu = self.mu lamb = self.lamb E = 0.5 * (C - I) stress = lamb * trace(E) * I + 2. * mu * E stress = 1. / J * np.dot(F, np.dot(stress, F.T)) # buggy # stress = mu/J*np.dot((b - I),b) + lamb/2./J * trace(b - I)*I return stress
def Hessian(self, StrainTensors, ElectricFieldx=0, elem=0, gcounter=0): """Hessian split into isochoroic and volumetric parts""" I = StrainTensors['I'] b = StrainTensors['b'][gcounter] J = StrainTensors['J'][gcounter] if np.isclose(J, 0) or J < 0: delta = np.sqrt(0.04 * J * J + 1e-8) # J = 0.5 * (J + np.sqrt(J**2 + 4 *delta**2)) mu = self.mu trb = trace(b) if self.ndim == 2: trb += 1. # ISOCHORIC H_Voigt = 2*mu*J**(-5./3.)*(1./9.*trb*einsum('ij,kl',I,I) - \ 1./3.*(einsum('ij,kl',b,I) + einsum('ij,kl',I,b)) +\ 1./6.*trb*(einsum('ik,jl',I,I) + einsum('il,jk',I,I)) ) # VOLUMETRIC # H_Voigt += self.pressure[elem]*(einsum('ij,kl',I,I) - (einsum('ik,jl',I,I) + einsum('il,jk',I,I))) H_Voigt += self.lamb * (2 * J - 1) * einsum( 'ij,kl', I, I) - self.lamb * (J - 1) * (einsum('ik,jl', I, I) + einsum('il,jk', I, I)) H_Voigt = Voigt(H_Voigt, 1) self.H_VoigtSize = H_Voigt.shape[0] return H_Voigt
def CauchyStress(self, StrainTensors, ElectricDisplacementx, elem=0, gcounter=0): d = self.ndim I = StrainTensors['I'] F = StrainTensors['F'][gcounter] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] if np.isclose(J, 0) or J < 0: delta = np.sqrt(0.04 * J * J + 1e-8) # J = 0.5 * (J + np.sqrt(J**2 + 4 *delta**2)) # J = 1. trb = trace(b) + 0 sigma = 2. / d * J**(-2. / d - 1.) * (-1. / d * trb * I + b) # sigma *= np.exp(1./d * J**(-2./d) * trb - 1) # print(F) # exit() return sigma
def CauchyStress(self, StrainTensors, ElectricDisplacementx, elem=0, gcounter=0): mu = self.mu lamb = self.lamb d = self.ndim I = StrainTensors['I'] F = StrainTensors['F'][gcounter] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] u, s, vh = svd(F, full_matrices=True) vh = vh.T R = u.dot(vh.T) S = np.dot(vh, np.dot(np.diag(s), vh.T)) IS = trace(S) sigma = 2. * (F - R) + (IS - self.ndim) * R # sigma = 2. * mu * (F - R) + 1 * lamb * (IS - 2) * R # print(sigma) # exit() return sigma
def Hessian(self, StrainTensors, ElectricDisplacementx, elem=0, gcounter=0): d = self.ndim I = StrainTensors['I'] F = StrainTensors['F'][gcounter] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] if np.isclose(J, 0) or J < 0: delta = np.sqrt(0.04 * J * J + 1e-8) # J = 0.5 * (J + np.sqrt(J**2 + 4 *delta**2)) # J = 1. trb = trace(b) + 0 C_Voigt = 4./d * J**(-1) * einsum("ij,kl", (-1./d * trb * I + b), (-1./d) * J**(-2./d) * I ) +\ 4./d**2 * J**(-1) * J**(-2./d) * (-einsum("ij,kl", I, b) + 0.5 * trb * (einsum("ik,jl",I,I)+einsum("il,jk",I,I)) ) # factor = np.exp(1./d * J**(-2./d) * trb - 1.) # sigma = 2./d * J**(-2./d - 1.) * (-1./d * trb * I + b) # C_Voigt = factor * (np.einsum("ij,kl", sigma, sigma) + C_Voigt) C_Voigt = Voigt(C_Voigt, 1) # s = np.linalg.svd(C_Voigt)[1] # if np.any(s < 0): # print(s) return C_Voigt
def InternalEnergy(self, StrainTensors, elem=0, gcounter=0): J = StrainTensors['J'][gcounter] F = StrainTensors['F'][gcounter] trc = trace(F.T.dot(F)) # self.delta = np.sqrt(1e-8 + min(self.minJ, 0.)**2 * 0.04) d = self.ndim delta = self.delta Jr = 0.5 * (J + np.sqrt(J**2 + delta**2)) if np.isclose(Jr, 0): Jr = 1e-10 energy = (1. / d * Jr**(-2. / d) * trc - 1.) # Neffs # energy += 0.02*(Jr**5 + 1./Jr**5 - 2.) # Garanzha # energy += (0.5*Jr - 1.0 + 0.5/Jr) * self.lamb # standard # energy += self.lamb * 0.5 * (Jr - 1.)**2 energy += self.lamb * LocallyInjectiveFunction(Jr) return energy
def CauchyStress(self, StrainTensors, ElectricDisplacementx, elem=0, gcounter=0): mu1 = self.mu1 mu2 = self.mu2 lamb = self.lamb eps_2 = self.eps_2 I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] D = ElectricDisplacementx.reshape(self.ndim, 1) DD = np.dot(D.T, D)[0, 0] trb = trace(b) if self.ndim == 2: trb += 1. simga_mech = 2.0*mu1/J*b + \ 2.0*mu2/J*(trb*b - np.dot(b,b)) -\ 2.0*(mu1+2*mu2)/J*I +\ lamb*(J-1.)*I sigma_electric = 1. / eps_2 * (np.dot(D, D.T) - 0.5 * DD * I) sigma = simga_mech + sigma_electric return sigma
def CauchyStress(self,StrainTensors,ElectricFieldx,elem=0,gcounter=0): mu = self.mu lamb = self.lamb eta = self.eta piezoelectric_tensor = self.P flexoelectric_tensor = self.f I = StrainTensors['I'] e = StrainTensors['strain'][gcounter] E = ElectricFieldx.reshape(self.ndim,1) tre = trace(e) if self.ndim==2: tre +=1. # REQUIRES CHECKS if self.ndim == 3: sigma_f = np.dot(flexoelectric_tensor,E) sigma_f = np.array([ [0.,-sigma_f[2],sigma_f[1]], [sigma_f[2],0.,-sigma_f[0]], [-sigma_f[1],sigma_f[0],0.], ]) else: # THIRD COMPONENT WHICH DOES NOT EXITS? sigma_f = np.zeros((self.ndim,self.ndim)) sigma = lamb*tre*I + 2.0*mu*e - UnVoigt(np.dot(piezoelectric_tensor,E)) + sigma_f return sigma
def CauchyStress(self, StrainTensors, ElectricFieldx, elem=0, gcounter=0): I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] F = StrainTensors['F'][gcounter] H = J * np.linalg.inv(F).T # N = np.array([-1.,0.]).reshape(2,1) N = self.anisotropic_orientations[elem, :, None] FN = np.dot(F, N) # HN = np.dot(H,N)[:,0] innerFN = np.dot(FN.T, FN)[0][0] outerFN = np.dot(FN, FN.T) # innerFN = einsum('i,i',FN,FN) # outerFN = einsum('i,j',FN,FN) bFN = np.dot(b, FN) E = self.E E_A = self.E_A G_A = self.G_A v = self.nu mu = self.mu alpha = E / 8.0 / (1. + v) beta = E / 8.0 / (1. + v) eta_1 = 4. * alpha - G_A lamb = -(3 * E) / (2 * (v + 1)) - (E * (-E * v**2 + E_A)) / ( (v + 1) * (2 * E * v**2 + E_A * v - E_A)) eta_2 = E/(4*(v + 1)) - (E_A*E*v)/(4*(2*E*v**2 + E_A*v - E_A)) + \ (E*(- E*v**2 + E_A))/(4*(v + 1)*(2*E*v**2 + E_A*v - E_A)) gamma = (E_A**2*(v - 1))/(8*(2*E*v**2 + E_A*v - E_A)) - G_A/2 + \ (E_A*E*v)/(4*(2*E*v**2 + E_A*v - E_A)) - \ (E*(- E*v**2 + E_A))/(8*(v + 1)*(2*E*v**2 + E_A*v - E_A)) ut = 2 * alpha + 4 * beta if self.ndim == 3: trb = trace(b) elif self.ndim == 2: trb = trace(b) + 1 stress = 2.*alpha/J*b + 2.*beta/J*(trb*b - np.dot(b,b)) - ut/J*I + lamb*(J-1.)*I + \ 2.*eta_1/J*outerFN + 2.*eta_2/J*(innerFN-1.)*b + 2.*eta_2/J*(trb-3.)*outerFN + \ 4.*gamma/J*(innerFN-1.)*outerFN - eta_1/J *(np.dot(bFN,FN.T)+np.dot(FN,bFN.T)) return stress
def Hessian(self, StrainTensors, ElectricFieldx=0, elem=0, gcounter=0): alpha = self.alpha beta = self.beta kappa = self.kappa I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] F = StrainTensors['F'][gcounter] # b=np.dot(F,F.T) H = J * np.linalg.inv(F).T g = np.dot(H, H.T) if self.ndim == 2: trb = trace(b) + 1 trg = trace(g) + J**2 elif self.ndim == 3: trb = trace(b) trg = trace(g) H_Voigt = -4/3.*alpha*J**(-5/3.)*( einsum('ij,kl',b,I) + einsum('ij,kl',I,b) ) + \ 4.*alpha/9.*J**(-5/3.)*trb*einsum('ij,kl',I,I) + \ 2/3.*alpha*J**(-5/3.)*trb*( einsum('il,jk',I,I) + einsum('ik,jl',I,I) ) + \ beta*J**(-3)*trg**(3./2.)* ( einsum('ij,kl',I,I) - einsum('ik,jl',I,I) - einsum('il,jk',I,I) ) - \ 3.*beta*J**(-3)*trg**(1./2.)*( einsum('ij,kl',I,g) + einsum('ij,kl',g,I) ) + \ 6.*beta*J**(-3)*trg**(1./2.)*( einsum('ik,jl',I,g) + einsum('il,jk',g,I) ) + \ 3.*beta*J**(-3)*trg**(-1./2.)*( einsum('ij,kl',g,g) ) + \ kappa*(2.0*J-1)*einsum('ij,kl',I,I) - kappa*(J-1)*(einsum('ik,jl',I,I)+einsum('il,jk',I,I)) # # # # WITH PRE-COMPUTED IDENTITY TENSORS # H_Voigt = -4/3.*alpha*J**(-5/3.)*( einsum('ij,kl',b,I) + einsum('ij,kl',I,b) ) + \ # 4.*alpha/9.*J**(-5/3.)*trb*self.Iijkl + \ # 2/3.*alpha*J**(-5/3.)*trb*self.Iikjl + \ # beta*J**(-3)*trg**(3./2.)*( self.Iijkl - self.Iikjl ) - \ # 3.*beta*J**(-3)*trg**(1./2.)*( einsum('ij,kl',I,g) + einsum('ij,kl',g,I) ) + \ # 6.*beta*J**(-3)*trg**(1./2.)*( einsum('ik,jl',I,g) + einsum('il,jk',g,I) ) + \ # 3.*beta*J**(-3)*trg**(-1./2.)*( einsum('ij,kl',g,g) ) + \ # kappa*(2.0*J-1)*self.Iijkl - kappa*(J-1)*self.Iikjl H_Voigt = Voigt(H_Voigt, 1) self.H_VoigtSize = H_Voigt.shape[0] return H_Voigt
def CauchyStress(self,StrainTensors,ElectricFieldx,elem=0,gcounter=0): lamb = self.lamb I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] if self.ndim == 3: trb = trace(b) elif self.ndim == 2: trb = trace(b) + 1 # stress = 2.0*alpha/J*b+2.0*beta/J*(trace(b)*b - np.dot(b,b)) + (lamb*(J-1.0)-4.0*beta-2.0*alpha/J)*I stress = 2.0*self.alpha/J*b+2.0*self.beta/J*(trb*b - np.dot(b,b)) + (lamb*(J-1.0)-4.0*self.beta-2.0*self.alpha/J)*I # print stress return stress
def CauchyStress(self, StrainTensors, ElectricFieldx, elem=0, gcounter=0): I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] mu = self.mu stress = mu * J**(-5. / 3.) * (b - 1. / 3. * trace(b) * I) stress += self.pressure[elem] * I return stress
def Hessian(self, StrainTensors, ElectricFieldx=0, elem=0, gcounter=0): """Hessian split into isochoroic and volumetric parts""" I = StrainTensors['I'] b = StrainTensors['b'][gcounter] J = StrainTensors['J'][gcounter] mu = self.mu # ISOCHORIC H_Voigt = 2*mu*J**(-5./3.)*(1./9.*trace(b)*einsum('ij,kl',I,I) - \ 1./3.*(einsum('ij,kl',b,I) + einsum('ij,kl',I,b)) +\ 1./6.*trace(b)*(einsum('ik,jl',I,I) + einsum('il,jk',I,I)) ) # VOLUMETRIC H_Voigt += self.pressure[elem]*(einsum('ij,kl',I,I) - (einsum('ik,jl',I,I) + einsum('il,jk',I,I))) H_Voigt = Voigt(H_Voigt,1) self.H_VoigtSize = H_Voigt.shape[0] return H_Voigt
def CauchyStress(self, StrainTensors, ElectricFieldx, elem=0, gcounter=0): strain = StrainTensors['strain'][gcounter] I = StrainTensors['I'] mu = self.mu lamb = self.lamb tre = trace(strain) if self.ndim == 2: tre += 1. return 2 * mu * strain + lamb * tre * I
def Hessian(self,StrainTensors,ElectricFieldx=None,elem=0,gcounter=0): kappa = self.kappa mu = self.mu k1 = self.k1 k2 = self.k2 I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] F = StrainTensors['F'][gcounter] if self.ndim == 3: trb = trace(b) elif self.ndim == 2: trb = trace(b) + 1 H_Voigt = 2.*mu*J**(-5./3.) * (1./9.*trb*einsum('ij,kl',I,I) - \ 1./3.*einsum('ij,kl',I,b) - 1./3.*einsum('ij,kl',b,I) + \ 1./6.*trb*(einsum('il,jk',I,I) + einsum('ik,jl',I,I)) ) if self.is_nearly_incompressible: H_Voigt += self.pressure*(einsum('ij,kl',I,I) - (einsum('ik,jl',I,I) + einsum('il,jk',I,I))) else: H_Voigt += kappa*((2.*J-1.)*einsum('ij,kl',I,I) - (J-1.)*(einsum('ik,jl',I,I) + einsum('il,jk',I,I))) # Anisotropic contibution nfibres = self.anisotropic_orientations.shape[1] for i_fibre in range(nfibres): N = self.anisotropic_orientations[elem,i_fibre,:,None] FN = np.dot(F,N)[:,0] innerFN = einsum('i,i',FN,FN) outerFN = einsum('i,j',FN,FN) expo = np.exp(k2*(innerFN-1.)**2) H_Voigt += 4.*k1/J*(1.+2.*k2*(innerFN-1.)**2)*expo*einsum('ij,kl',outerFN,outerFN) H_Voigt = Voigt(H_Voigt ,1) return H_Voigt
def CauchyStress(self,StrainTensors,ElectricDisplacementx,elem=0,gcounter=0): mu_v = self.mu_v mu1 = self.mu1 mu2 = self.mu2 lamb = self.lamb eps_2 = self.eps_2 I = StrainTensors['I'] J = StrainTensors['J'][gcounter] b = StrainTensors['b'][gcounter] strain = StrainTensors['strain'][gcounter] D = ElectricDisplacementx.reshape(self.ndim,1) DD = np.dot(D.T,D)[0,0] trb = trace(b) if self.ndim==2: trb += 1. simga_mech = 2.0*mu1/J*b + \ 2.0*mu2/J*(trb*b - np.dot(b,b)) -\ 2.0*(mu1+2*mu2)/J*I +\ lamb*(J-1.)*I sigma_electric = 1./eps_2*(np.dot(D,D.T) - 0.5*DD*I) # CHECK IF THIS IS NECESSARY if self.ndim == 3: tre = trace(strain) elif self.ndim == 2: tre = trace(strain) + 1 # USE FASTER TRACE FUNCTION sigma_linear = 2.*mu_v*strain + lamb*tre*I sigma = simga_mech + sigma_electric + sigma_linear return sigma
def CauchyStress(self,StrainTensors,ElectricFieldx,elem=0,gcounter=0): mu = self.mu lamb = self.lamb eta = self.eta piezoelectric_tensor = self.P flexoelectric_tensor = self.f I = StrainTensors['I'] e = StrainTensors['strain'][gcounter] E = ElectricFieldx.reshape(self.ndim,1) tre = trace(e) if self.ndim==2: tre +=1.