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 = 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 = 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 gen_strain_mode(CrystalType, Ord): #function: generate the strain mode for given crystal type(CrystalType) and order(Ord) CijkInd = symdata.coef_ind(CrystalType, Ord) CoefCoef = symdata.coef_crystal(CrystalType, Ord) CijkUniq = np.array(symdata.get_unique(CijkInd)) n_uniq = len(CijkUniq) #print(n_uniq) if (Ord % 2.0 == 0) and (n_uniq > 5): #n_uniq > 5 keep doubt? to do n_row = int(math.ceil(n_uniq / 6.) * 6.) #+ 6 else: n_row = int(math.ceil(n_uniq / 6.) * 6.) #print(n_row) Cijk = symmetry.num2cijk(CijkUniq, Ord) StrainMode = np.zeros((int(math.ceil(n_row / 6.)), 3, 3), dtype=float) #StrainModeCoef = np.zeros((n_row, n_uniq), dtype = float) StrainModeCoef = symmetry.CoefStr(Ord) exec('StrainModeCoef.coef' + str(int(Ord)) + ' = np.zeros((n_row, 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_row, n_uniqi), dtype = float)') if n_uniq < 6: #The ord must be 2 StrainAll = gen_strain(1) for i in range(0, len(StrainAll)): StrainModei = symmetry.vec2matrix(StrainAll[i]) StrainModeCoefi = gen_cijk_coef(CrystalType, StrainModei, Ord) SMRank = np.linalg.matrix_rank(StrainModeCoefi) if SMRank == n_uniq: StrainMode[0, :, :] = StrainModei StrainModeCoef = StrainModeCoefi break else: print("Begin of generate the full-rank database.\n") StrainAll = gen_fullrank_db(CrystalType, Ord) print("The full-rank database were generated.\n") #StrainAll = gen_alldiff_db() #print StrainAll n_strain = len(StrainAll) #print(n_strain) for j in range(0, n_strain): count = 0 flag = 0 for i in range(j, n_strain): Straini = StrainAll[i, :, :] StrainModei = gen_cijk_coef(CrystalType, Straini, Ord) if count == 0: exec('StrainModeCoef.coef' + str(int(Ord)) + '[0:6, :] = StrainModei') #StrainModeCoef[0:6, :] = StrainModei StrainMode[count, :, :] = Straini for k in range(2, int(Ord)): exec( 'StrainModeCoef.coef' + str(int(k)) + '[0:6, :] = gen_cijk_coef(CrystalType, Straini, k)' ) count = count + 1 #''' if n_uniq == 6: flag = 1 break #''' else: StrainModetmp = np.zeros((6 * (count + 1), n_uniq), dtype=float) StrainModetmp[0:6 * count, :] = eval('StrainModeCoef.coef' + str(int(Ord)) + '[0:6*count, :]') StrainModetmp[6 * count:6 * (count + 1), :] = StrainModei SMRank = np.linalg.matrix_rank(StrainModetmp) #print(SMRank) #print(n_uniq) #print(count) ### NOTE: the default is SMRank == 6*(count + 1) RnkLst = [ 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108, 114, 120, 126 ] #if SMRank == 6*(count + 1) or SMRank == n_uniq: if SMRank > (RnkLst[count] - 1) or SMRank == n_uniq: #if SMRank > 5*(count + 1) or SMRank == n_uniq: #exec('print(StrainModeCoef.coef' + str(int(Ord)) + ')') #print(StrainModei) exec('StrainModeCoef.coef' + str(int(Ord)) + '[6*count:6*(count + 1), :] = StrainModei') StrainMode[count, :, :] = Straini for k in range(2, int(Ord)): exec( 'StrainModeCoef.coef' + str(k) + '[6*count:6*(count + 1), :] = gen_cijk_coef(CrystalType, Straini, k)' ) count = count + 1 if SMRank == n_uniq: print(SMRank) flag = 1 break if flag == 1: break return (StrainModeCoef, StrainMode)