def gen_strain_mode(CrystalType, Ord): #function: generate the strain mode for given crystal type(CrystalType) and order(Ord) StrainAll = gen_strain(1) CijkInd = symdata.coef_ind(CrystalType, Ord) CoefCoef = symdata.coef_crystal(CrystalType, Ord) CijkUniq = np.array(symdata.get_unique(CijkInd)) n_uniq = len(CijkUniq) Cijk = num2cijk(CijkUniq, Ord) StrainMode = np.zeros((n_uniq, 3, 3), dtype=float) #StrainModeCoef = np.zeros((n_uniq, n_uniq), dtype = float) StrainModeCoef = CoefStr(Ord) exec('StrainModeCoef.coef' + str(int(Ord)) + ' = np.zeros((n_uniq, n_uniq), dtype = float)') for i in range(2, int(Ord)): CijUniq = np.array(symdata.get_unique(symdata.coef_ind(CrystalType, i))) n_uniqi = len(CijUniq) exec('StrainModeCoef.coef' + str(i) + ' = np.zeros((n_uniq, n_uniqi), dtype = float)') count = 0 for i in range(0, len(StrainAll)): Straini = crydef.vec2matrix(StrainAll[i]) StrainModei = gen_cijk_coef(CrystalType, Straini, Ord) if i == 0: StrainMode[count, :, :] = Straini exec('StrainModeCoef.coef' + str(int(Ord)) + '[count, :] = StrainModei') for j in range(2, int(Ord)): exec('StrainModeCoef.coef' + str(j) + '[count, :] = gen_cijk_coef(CrystalType, Straini, j)') count = count + 1 else: StrainModetmp = np.zeros((count + 1, n_uniq), dtype=float) #print StrainMode[0, :] StrainModetmp[0:count, :] = eval('StrainModeCoef.coef' + str(int(Ord)) + '[0:count, :]') StrainModetmp[count, :] = StrainModei SMRank = np.linalg.matrix_rank(StrainModetmp) if SMRank == count + 1: #print SMRank exec('StrainModeCoef.coef' + str(int(Ord)) + '[count, :] = StrainModei') StrainMode[count, :, :] = Straini for j in range(2, int(Ord)): exec('StrainModeCoef.coef' + str(j) + '[count, :] = gen_cijk_coef(CrystalType, Straini, j)') #print StrainModei count = count + 1 if count == n_uniq: break #print StrainModeCoef #print StrainMode return (StrainModeCoef, StrainMode)
def print_cijk(CrystalType, Ord): #function: print the Cijk according to the crystal type and order CijkInd = symdata.coef_ind(CrystalType, Ord) CijkUniq = np.array(symdata.get_unique(CijkInd)) Cijk = num2cijk(CijkUniq, Ord) print(Cijk) return Cijk
def CoefForSingleMode(CrystalType, Ord, Strain): #function: generate the coefficient for a specified strain and crystal type # #Cijk = print_cijk(CrystalType, Ord) #print Cijk m = Strain.shape if len(m) == 1: m = 1 else: m = m[0] StrainMode = np.zeros((m, 3, 3)) StrainModeCoef = CoefStr(Ord) for i in range(2, int(Ord) + 1): CijUniq = np.array(symdata.get_unique(symdata.coef_ind(CrystalType, i))) n_uniq = len(CijUniq) exec('StrainModeCoef.coef' + str(i) + ' = np.zeros((m, n_uniq), dtype = float)') #StrainModeCoef = CoefStr(Ord) Cijk = CoefStr(Ord) for i in range(2, int(Ord) + 1): exec('Cijk.coef' + str(i) + ' = print_cijk(CrystalType, i)') for j in range(0, m): StrainM = crydef.vec2matrix(Strain[j, :]) StrainMode[j, :, :] = StrainM #print StrainM exec('StrainModeCoef.coef' + str(i) + '[j, :] = gen_cijk_coef(CrystalType, StrainM, i)') exec('print(StrainModeCoef.coef' + str(i) + ')') return (Cijk, StrainModeCoef, StrainMode)
def gen_cijk_coef(CrystalType, Strain, Ord): #function: generate the coefficients of independent elastic constant according to # the crystal type(CrystalType) and the strain(Strain) and order(Ord) (StrainOrd, StrainOrdCoef) = gen_strainord(Strain) CijkInd = symdata.coef_ind(CrystalType, Ord) CoefCoef = symdata.coef_crystal(CrystalType, Ord) (Cijk, CijkCoef) = gen_strain_coef(StrainOrd, StrainOrdCoef, Ord) CijkUniq = np.array(symdata.get_unique(CijkInd)) CoefStrain = np.zeros(len(CijkUniq)) CijkNum = cijk2num(Cijk, Ord) for i in range(0, len(CijkNum)): COrderi = CijkInd[CijkNum[i]] #print COrderi #print COrderi is list if type(COrderi) is list: for j in range(0, len(COrderi)): #print CijkNum #print CoefCoef[CijkNum[i]][j] #print CijkCoef[i] CoefOrderi = float(CoefCoef[CijkNum[i]][j]) * float( CijkCoef[i]) Index_CoefStrain = np.argwhere(CijkUniq == COrderi[j]) Index_CoefStrain = Index_CoefStrain[0][0] CoefStrain[Index_CoefStrain] = CoefStrain[ Index_CoefStrain] + CoefOrderi else: if COrderi != 0: CoefOrderi = float(CoefCoef[CijkNum[i]]) * float(CijkCoef[i]) Index_CoefStrain = np.argwhere(CijkUniq == COrderi) #print Index_CoefStrain Index_CoefStrain = Index_CoefStrain[0][0] CoefStrain[Index_CoefStrain] = CoefStrain[ Index_CoefStrain] + CoefOrderi return CoefStrain
def CoefForSingleMode(CrystalType='c1', Ord=3, Strain=np.array([[0.5, -2, -0.5, 1, 1, 0]])): ''' Generate the coefficient for specified strain modes Parameter --------- CrystalType: str The crystal type (symmetry), in Laue's group Ord: int The order of elastic constants Strain: 2D np.ndarray The strain modes, support multi-strain modes Note: in Voigt's notation and the size is nx6 e.g. np.array([[1, 1, 0, 2, 0, 0]]) Return ------ Cijk: elastic3rd.symmetry.symmetry.CoefStr object The independent elastic constants (in Ord order) StrainModeCoef: elastic3rd.symmetry.symmetry.CoefStr object The coefficients of independent elastic constants StrainMode: 3D np.ndarray The strain modes nx3x3 ''' m = Strain.shape if len(m) == 1: m = 1 else: m = m[0] StrainMode = np.zeros((m, 3, 3)) StrainModeCoef = CoefStr(Ord) for i in range(2, int(Ord) + 1): CijUniq = np.array(symdata.get_unique(symdata.coef_ind(CrystalType, i))) n_uniq = len(CijUniq) exec('StrainModeCoef.coef' + str(i) + ' = np.zeros((m, n_uniq), dtype = float)') #StrainModeCoef = CoefStr(Ord) Cijk = CoefStr(Ord) for i in range(2, int(Ord) + 1): exec('Cijk.coef' + str(i) + ' = print_cijk(CrystalType, i)') for j in range(0, m): StrainM = crydef.vec2matrix(Strain[j, :]) StrainMode[j, :, :] = StrainM #print StrainM exec('StrainModeCoef.coef' + str(i) + '[j, :] = gen_cijk_coef(CrystalType, StrainM, i)') exec('print(StrainModeCoef.coef' + str(i) + ')') return (Cijk, StrainModeCoef, StrainMode)
def gen_cijk_coef(CrystalType='c1', Strain=np.array([[1, 0, 0], [0, 1, 1], [0, 1, 0]]), Ord=3): ''' Generate the coefficients of independent elastic constants according to symmetry and strain and elastic constants order Parameter --------- CrystalType: str The crystal type, in Laue group Strain: 2D np.ndarray The strain in matrix/tensor format Ord: int The order of elasti constants Return ------ CoefStrain: 1D np.ndarray The coefficients of the independent elastic constants in current Strain The sequence is in order of the index, e.g. for cubicI, [111, 112, 123, 144, 155, 456] ''' (StrainOrd, StrainOrdCoef) = gen_strainord(Strain) CijkInd = symdata.coef_ind(CrystalType, Ord) CoefCoef = symdata.coef_crystal(CrystalType, Ord) (Cijk, CijkCoef) = gen_strain_coef(StrainOrd, StrainOrdCoef, Ord) CijkUniq = np.array(symdata.get_unique(CijkInd)) CoefStrain = np.zeros(len(CijkUniq)) CijkNum = cijk2num(Cijk, Ord) for i in range(0, len(CijkNum)): COrderi = CijkInd[CijkNum[i]] if type(COrderi) is list: for j in range(0, len(COrderi)): CoefOrderi = float(CoefCoef[CijkNum[i]][j]) * float( CijkCoef[i]) Index_CoefStrain = np.argwhere(CijkUniq == COrderi[j]) Index_CoefStrain = Index_CoefStrain[0][0] CoefStrain[Index_CoefStrain] = CoefStrain[ Index_CoefStrain] + CoefOrderi else: if COrderi != 0: CoefOrderi = float(CoefCoef[CijkNum[i]]) * float(CijkCoef[i]) Index_CoefStrain = np.argwhere(CijkUniq == COrderi) #print Index_CoefStrain Index_CoefStrain = Index_CoefStrain[0][0] CoefStrain[Index_CoefStrain] = CoefStrain[ Index_CoefStrain] + CoefOrderi return CoefStrain
def print_cijk(CrystalType='c1', Ord=3): ''' Print independent Cijk according to the crystal type and order Parameter --------- CrystalType: str The crystal type (symmetry), in Laue's group Ord: int The order of elastic constants Return ------ Cijk: np.ndarray The list of Cijk (order is determined by Ord) ''' CijkInd = symdata.coef_ind(CrystalType, Ord) CijkUniq = np.array(symdata.get_unique(CijkInd)) Cijk = num2cijk(CijkUniq, Ord) print(Cijk) return Cijk
def gen_strain_mode(CrystalType='c1', Ord=3): ''' Generate the strain mode for give symmetry and order Parameter --------- CrystalType: str The crystal type, in Laue group Ord: int The order of elastic constants Return ------ StrainModeCoef: elastic3rd.symmetry.symmetry.CoefStr object elastic3rd defined coefficients object It contains several attributes. e.g. CoefStr.coef2, CoefStr.coef3, ..., CoefStr.coefn, ... Here n equal to Ord In each attributes, it is a 2D np.ndarray StrainMode: 3D np.ndarray The strain mode in matrix/tesnsor format size: nx3x3, here n is the number of strain modes ''' StrainAll = gen_strain(1) CijkInd = symdata.coef_ind(CrystalType, Ord) CoefCoef = symdata.coef_crystal(CrystalType, Ord) CijkUniq = np.array(symdata.get_unique(CijkInd)) n_uniq = len(CijkUniq) Cijk = num2cijk(CijkUniq, Ord) StrainMode = np.zeros((n_uniq, 3, 3), dtype=float) StrainModeCoef = CoefStr(Ord) exec('StrainModeCoef.coef' + str(int(Ord)) + ' = np.zeros((n_uniq, n_uniq), dtype = float)') for i in range(2, int(Ord)): CijUniq = np.array(symdata.get_unique(symdata.coef_ind(CrystalType, i))) n_uniqi = len(CijUniq) exec('StrainModeCoef.coef' + str(i) + ' = np.zeros((n_uniq, n_uniqi), dtype = float)') count = 0 for i in range(0, len(StrainAll)): Straini = crydef.vec2matrix(StrainAll[i]) StrainModei = gen_cijk_coef(CrystalType, Straini, Ord) if i == 0: StrainMode[count, :, :] = Straini exec('StrainModeCoef.coef' + str(int(Ord)) + '[count, :] = StrainModei') for j in range(2, int(Ord)): exec('StrainModeCoef.coef' + str(j) + '[count, :] = gen_cijk_coef(CrystalType, Straini, j)') count = count + 1 else: StrainModetmp = np.zeros((count + 1, n_uniq), dtype=float) StrainModetmp[0:count, :] = eval('StrainModeCoef.coef' + str(int(Ord)) + '[0:count, :]') StrainModetmp[count, :] = StrainModei SMRank = np.linalg.matrix_rank(StrainModetmp) if SMRank == count + 1: exec('StrainModeCoef.coef' + str(int(Ord)) + '[count, :] = StrainModei') StrainMode[count, :, :] = Straini for j in range(2, int(Ord)): exec('StrainModeCoef.coef' + str(j) + '[count, :] = gen_cijk_coef(CrystalType, Straini, j)') count = count + 1 if count == n_uniq: break return (StrainModeCoef, StrainMode)