def GetStress(self, StrainTensor, time=None): # time not used here because this law require no time effect # initilialize values plasticity variables if required if self.__P is None: self.__P = np.zeros(len(StrainTensor[0])) self.__currentP = np.zeros(len(StrainTensor[0])) if self.__PlasticStrainTensor is None: self.__PlasticStrainTensor = listStrainTensor( np.zeros((6, len(StrainTensor[0])))) self.__currentPlasticStrainTensor = listStrainTensor( np.zeros((6, len(StrainTensor[0])))) H = self.GetHelas( ) #no change of basis because only isotropic behavior are considered sigma = listStressTensor([ sum([(StrainTensor[j] - self.__PlasticStrainTensor[j]) * H[i][j] for j in range(6)]) for i in range(6) ]) test = self.YieldFunction(sigma, self.__P) > self.__tol # print(sum(test)/len(test)*100) sigmaFull = np.array(sigma).T Ep = np.array(self.__PlasticStrainTensor).T # Ep = np.array(self.__currentPlasticStrainTensor).T for pg in range(len(sigmaFull)): if test[pg] > 0: sigma = listStressTensor(sigmaFull[pg]) p = self.__P[pg] iter = 0 while abs(self.YieldFunction(sigma, p)) > self.__tol: dphi_dp = self.HardeningFunctionDerivative(p) dphi_dsigma = np.array( self.YieldFunctionDerivativeSigma(sigma)) Lambda = dphi_dsigma #for associated plasticity B = sum([ sum([dphi_dsigma[j] * H[i][j] for j in range(6)]) * Lambda[i] for i in range(6) ]) dp = self.YieldFunction(sigma, p) / (B - dphi_dp) p += dp Ep[pg] += Lambda * dp sigma = listStressTensor([ sum([(StrainTensor[j][pg] - Ep[pg][j]) * H[i][j] for j in range(6)]) for i in range(6) ]) self.__currentP[pg] = p sigmaFull[pg] = sigma self.__currentPlasticStrainTensor = listStrainTensor(Ep.T) self.__currentSigma = listStressTensor(sigmaFull.T) # list of 6 objets return self.__currentSigma
def YieldFunctionDerivativeSigma(self, sigma): """ Derivative of the Yield Function with respect to the stress tensor defined in sigma sigma should be a listStressTensor object """ return listStressTensor((3 / 2) * np.array(sigma.deviatoric()) / sigma.vonMises()).toStrain()
def GetStress(self, StrainTensor): H = self.__ChangeBasisH(self.GetH()) sigma = listStressTensor([ sum([StrainTensor[j] * H[i][j] for j in range(6)]) for i in range(6) ]) return sigma # list of 6 objets
def GetStressTensor(self, U, constitutiveLaw, Type="Nodal"): """ Not a static method. Return the Stress Tensor of an assembly using the Voigt notation as a python list. The total displacement field and a ConstitutiveLaw have to be given. Can only be used for linear constitutive law. For non linear ones, use the GetStress method of the ConstitutiveLaw object. Options : - Type :"Nodal", "Element" or "GaussPoint" integration (default : "Nodal") See GetNodeResult, GetElementResult and GetGaussPointResult. example : S = SpecificAssembly.GetStressTensor(Problem.Problem.GetDoFSolution('all'), SpecificConstitutiveLaw) """ if isinstance(constitutiveLaw, str): constitutiveLaw = ConstitutiveLaw.GetAll()[constitutiveLaw] if Type == "Nodal": return listStressTensor([ self.GetNodeResult(e, U) if e != 0 else np.zeros(self.__Mesh.GetNumberOfNodes()) for e in constitutiveLaw.GetStressOperator() ]) elif Type == "Element": return listStressTensor([ self.GetElementResult(e, U) if e != 0 else np.zeros(self.__Mesh.GetNumberOfElements()) for e in constitutiveLaw.GetStressOperator() ]) elif Type == "GaussPoint": NumberOfGaussPointValues = self.__Mesh.GetNumberOfElements( ) * self.__nb_pg #Assembly.__saveOperator[(self.__Mesh.GetID(), self.__elmType, self.__nb_pg)][0].shape[0] return listStressTensor([ self.GetGaussPointResult(e, U) if e != 0 else np.zeros(NumberOfGaussPointValues) for e in constitutiveLaw.GetStressOperator() ]) else: assert 0, "Wrong argument for Type: use 'Nodal', 'Element', or 'GaussPoint'"
def GetCurrentStress(self): #same as GetPKII (used for small def) return listStressTensor(self.PKII.T)
def GetCauchy(self): return listStressTensor(self.Cauchy.T)
def GetKirchhoff(self): return listStressTensor(self.Kirchhoff.T)
def GetPKII(self): return listStressTensor(self.PKII.T)