diff --git a/processing/post/addStrainTensors.py b/processing/post/addStrainTensors.py index 2d62c31ae..7addc450a 100755 --- a/processing/post/addStrainTensors.py +++ b/processing/post/addStrainTensors.py @@ -136,9 +136,9 @@ for name in filenames: for column in items['tensor']['column']: # loop over all requested defgrads F = np.array(list(map(float,table.data[column:column+items['tensor']['dim']])),'d').reshape(items['tensor']['shape']) (U,S,Vh) = np.linalg.svd(F) # singular value decomposition - R = np.dot(U,Vh) # rotation of polar decomposition - stretch['U'] = np.dot(np.linalg.inv(R),F) # F = RU - stretch['V'] = np.dot(F,np.linalg.inv(R)) # F = VR + R_inv = np.linalg.inv(np.dot(U,Vh)) # inverse rotation of polar decomposition + stretch['U'] = np.dot(R_inv,F) # F = RU + stretch['V'] = np.dot(F,R_inv) # F = VR for theStretch in stretches: stretch[theStretch] = np.where(abs(stretch[theStretch]) < 1e-12, 0, stretch[theStretch]) # kill nasty noisy data diff --git a/python/damask/dadf5.py b/python/damask/dadf5.py index 716747288..a96f4cfdb 100644 --- a/python/damask/dadf5.py +++ b/python/damask/dadf5.py @@ -224,7 +224,7 @@ class DADF5(): def add_determinant(self,a): - """Adds the determinan of a tensor""" + """Adds the determinant of a tensor""" # ToDo: The output unit should be the input unit args = [{'label':a,'shape':[3,3],'unit':None}] result = {'label':'det({})'.format(a), @@ -233,6 +233,33 @@ class DADF5(): self.add_generic_pointwise(np.linalg.det,args,result) + + def add_strain_tensors(self,defgrad='F'): + """Adds a strain definition""" + def strain(defgrad): + (U,S,Vh) = np.linalg.svd(defgrad) # singular value decomposition + R_inv = np.linalg.inv(np.dot(U,Vh)) # inverse rotation of polar decomposition + U = np.dot(R_inv,defgrad) # F = RU + U = np.where(abs(U) < 1e-12, 0, U) # kill nasty noisy data + (D,V) = np.linalg.eig(U) # eigen decomposition (of symmetric matrix) + neg = np.where(D < 0.0) # find negative eigenvalues ... + D[neg] *= -1. # ... flip value ... + V[:,neg] *= -1. # ... and vector + for i,eigval in enumerate(D): + if np.dot(V[:,i],V[:,(i+1)%3]) != 0.0: # check each vector for orthogonality + V[:,(i+1)%3] = np.cross(V[:,(i+2)%3],V[:,i]) # correct next vector + V[:,(i+1)%3] /= np.sqrt(np.dot(V[:,(i+1)%3],V[:,(i+1)%3].conj())) # and renormalize (hyperphobic?) + d = np.log(D) # operate on eigenvalues of U o r V + return np.dot(V,np.dot(np.diag(d),V.T)).real # build tensor back from eigenvalue/vector basis + + # ToDo: The output unit should be the input unit + args = [{'label':defgrad,'shape':[3,3],'unit':None}] + result = {'label':'strain({})'.format(defgrad), + 'unit':'-', + 'Description': 'strain (ln(V)) of a deformation gradient'} + + self.add_generic_pointwise(strain,args,result) + def get_fitting(self,data): groups = []