def dipoleCoupling(allDipoles): numDipoles = len(allDipoles[:, 0]) #The dipoles are stored as nx3 coupling = 0 for i in range(numDipoles): tempNeigh = np.zeros((4, 2)) op.gothrough(allDipoles[0, :], allDipoles, tempNeigh) for j in range(3): coupling += np.dot(allDipoles[0, :], allDipoles[int(tempNeigh[j + 1, 0])]) return coupling / 24
def findNeighbor(coords, lattice): original_n = coords #Just being lazy NN = np.zeros((24, )) #Store the distance tempNN = np.zeros((48, 1)) #because of the double counting count = 0 for i in range(8): tempN = np.zeros((4, 2)) axis = np.zeros((3, 1)) op.gothrough(original_n[i, :], original_n, tempN) for j in range(3): tempNN[count] = tempN[j + 1, 1] count += 1 nnVec = original_n[int(tempN[j + 1, 0]), :] - original_n[i, :] axis[j] = determineAxis(nnVec) if axis[j] > 0: anotherN = original_n[int(tempN[j + 1, 0]), :] - lattice[int(axis[j] - 1), :] tempNN[count] = np.linalg.norm(anotherN - original_n[i, :]) count += 1 else: anotherN = original_n[int(tempN[j + 1, 0]), :] + lattice[ -int(axis[j] + 1), :] tempNN[count] = np.linalg.norm(anotherN - original_n[i, :]) count += 1 '''Remove Double Counting''' count = 0 NN[0] = tempNN[0] for i in range(48): count2 = 0 for j in range(count): if tempNN[i] == NN[j]: count2 += 1 break if count2 == 0: NN[count] = tempNN[i] count += 1 if count == 24: break else: continue return NN
def findMolecules(name): #import the coordinates lattice = np.zeros((3, 3)) original_pb = np.zeros((8, 3)) original_cl = np.zeros((24, 3)) original_c = np.zeros((8, 3)) original_n = np.zeros((8, 3)) original_h = np.zeros((48, 3)) op.in_coord(name, lattice, original_pb, original_cl, original_c, original_n, original_h) molecules = np.zeros((8, 3)) for i in range(8): tempN = np.zeros((3, 2)) op.gothrough(original_c[i, :], original_n, tempN) molecules[i] = original_n[int(tempN[0, 0]), :] - original_c[i, :] return molecules
def findDeviation(name): lattice = np.zeros((3, 3)) original_pb = np.zeros((8, 3)) original_cl = np.zeros((24, 3)) original_c = np.zeros((8, 3)) original_n = np.zeros((8, 3)) original_h = np.zeros((48, 3)) op.in_coord(name, lattice, original_pb, original_cl, original_c, original_n, original_h) #enlarge the unit cell by 8 times pb = np.zeros((64, 3)) cl = np.zeros((192, 3)) c = np.zeros((64, 3)) n = np.zeros((64, 3)) h = np.zeros((384, 3)) op.enlarge(original_pb, pb, lattice, 8) op.enlarge(original_cl, cl, lattice, 24) op.enlarge(original_c, c, lattice, 8) op.enlarge(original_n, n, lattice, 8) op.enlarge(original_h, h, lattice, 48) #find the center of C-N CNCenter = np.zeros((64, 3)) for i in range(64): temp = np.zeros((3, 2)) op.gothrough(n[i], c, temp) CNCenter[i] = 1 / 2 * (n[i] + c[int(temp[0, 0])]) #Find the 4 molecules that surround the Cl atoms. Take N atoms as indicator. Store the index cl_n = np.zeros((24, 4)) for i in range(24): temp = np.zeros((4, 2)) op.gothrough(original_cl[i], CNCenter, temp) if temp[-1, 1] > 6: print("There is something wrong my friend.") sys.exit() cl_n[i, :] = temp[:, 0] #Assume the ideal ideal hydrogen bond number is 1 for each Cl atom NumHBond = np.zeros((24, 1)) r0 = 2.2 B = 0.3 for i in range(24): for j in range(4): tempH = np.zeros((3, 2)) indexN = int(cl_n[i, j]) op.gothrough(n[indexN], h, tempH) for k in range(3): dij = np.linalg.norm(original_cl[i, :] - h[int(tempH[k, 0])]) NumHBond[i, 0] += countFD(r0, B, dij) deviation = np.zeros((8, 1)) deviation = np.square(NumHBond - 1) totDevi = np.sum(deviation) return totDevi
def euler(index_pb, original_pb, cl): pb = original_pb[int(index_pb), :] temp_cl = np.zeros((6, 2)) the_cl = np.zeros((6, 3)) op.gothrough(pb, cl, temp_cl) for i in range(6): the_cl[i, :] = cl[int(temp_cl[i][0]), :] #Determine the new x,y,z principal axis axis_index = np.full((3, 2), -1) #x-x, y-y, z-z max_xyz = np.zeros((3, 1)) for i in range(6): for j in range(i, 6, 1): for k in range(3): distance = abs(the_cl[i][k] - the_cl[j][k]) if distance > max_xyz[k]: max_xyz[k] = distance axis_index[k][0] = i axis_index[k][1] = j principal = np.zeros((3, 3)) #x,y,z new principal axis for i in range(3): principal[i, :] = the_cl[int(axis_index[i][0])] - the_cl[int( axis_index[i][1])] if principal[i][i] < 0: principal[i, :] = -1 * principal[i, :] principal[i, :] = principal[i, :] / np.linalg.norm(principal[i, :]) ##===z followed by y followed by x===#### alpha = ma.asin(-principal[2][1] / ma.sqrt(1 - principal[2][0]**2)) beta = ma.asin(principal[2][0]) gamma = ma.asin(-principal[1][0] / ma.sqrt(1 - principal[2][0]**2)) return alpha * 180 / ma.pi, beta * 180 / ma.pi, gamma * 180 / ma.pi
def findNHBond(name): #import the coordinates lattice = np.zeros((3,3)); original_pb = np.zeros((8,3)); original_cl = np.zeros((24,3)); original_c = np.zeros((8,3)); original_n = np.zeros((8,3)); original_h = np.zeros((48,3)); op.in_coord(name, lattice, original_pb, original_cl, original_c, original_n, original_h); #enlarge the unit cell by 8 times pb = np.zeros((64,3)); cl = np.zeros((192,3)); c = np.zeros((64,3)); n = np.zeros((64,3)); h = np.zeros((384,3)); op.enlarge(original_pb,pb,lattice,8); op.enlarge(original_cl,cl,lattice,24); op.enlarge(original_c,c,lattice,8); op.enlarge(original_n,n,lattice,8); op.enlarge(original_h,h,lattice,48); the_n = np.zeros((8,3)); index_n = np.zeros((8,1)); the_c = np.zeros((8,3)); index_c = np.zeros((8,1)); the_cl = np.zeros((8,12,3)); the_pb = np.zeros((8,8,3)); distance_o_cl = np.zeros((8,12)); distance_h_cl = np.zeros((8,3)); #first get one small cell count = 0; for i in range(64): temp_n = n[i]; temp_center = np.zeros((3,1)); temp_cn = np.zeros((64,2)); op.gothrough(temp_n,c,temp_cn); temp_c = c[int(temp_cn[0][0])]; op.midpoint(temp_c,temp_n,temp_center);#determine the center coordinate #determine the neighbor Cl atoms temp_o_cl = np.zeros((12,2)); op.gothrough(temp_center, cl, temp_o_cl); #determine the neighbor Pb atoms temp_o_pb = np.zeros((8,2)); op.gothrough(temp_center,pb,temp_o_pb); if temp_o_cl[11][1] > 5.5: continue; else: #determine the H(N) atoms in this unit cell temp_h_n = np.zeros((3,2)); op.gothrough(temp_n, h, temp_h_n); temp_nh_cl = np.zeros((3,2)); for j in range(3): op.gothrough(h[int(temp_h_n[j][0])],cl,temp_nh_cl[j,:]); #decide whether we choose this unit cell or not, trying to avoid overlap count2 = 0; for j in range(count+1): indicator1 = np.linalg.norm(temp_o_cl[:,1] - distance_o_cl[j,:]); indicator2 = np.linalg.norm(temp_nh_cl[:,1] - distance_h_cl[j,:]); # print(indicator1) # print(indicator2) if indicator1 > 0.0000001 and indicator2 > 0.0000001: count2 = count2 + 1; continue; else: break; if count2 == count+1: distance_o_cl[count,:] = temp_o_cl[:,1]; distance_h_cl[count,:] = temp_nh_cl[:,1]; the_n[count] = temp_n; the_c[count] = temp_c; index_n[count] = i; index_c[count] = temp_cn[0][0]; for k in range(12): the_cl[count][k] = cl[int(temp_o_cl[k][0])]; for k in range(8): the_pb[count][k] = pb[int(temp_o_pb[k][0])]; count = count + 1; #rearrange the chlorine atoms for i in range(8): op.rearrange(the_cl[i]); #After spliting into small cell, let's calculate the hydrogen bonds length. #Every Hydrogen atom keep its first two shortest distances between Cl the_nh = np.zeros((8,3,3)); the_ch = np.zeros((8,3,3)); for i in range(8): temp_h_n = np.zeros((3,2)); temp_h_c = np.zeros((3,2)); op.gothrough(the_n[i],h,temp_h_n); op.gothrough(the_c[i],h,temp_h_c); for j in range(3): the_nh[i][j] = h[int(temp_h_n[j][0])]; the_ch[i][j] = h[int(temp_h_c[j][0])]; #3rd method r0 = 2.2; B = 0.3; numHBond = np.zeros((8,1)); for i in range(8): for j in range(3): for k in range(12): dij = np.linalg.norm(the_nh[i][j] - the_cl[i][k]); numHBond[i,0] += countFD(r0,B,dij); #print(numHBond) aveBond = np.sum(numHBond)/24; return aveBond;
def findNHBond(name): #import the coordinates lattice = np.zeros((3, 3)) original_pb = np.zeros((8, 3)) original_cl = np.zeros((24, 3)) original_c = np.zeros((8, 3)) original_n = np.zeros((8, 3)) original_h = np.zeros((48, 3)) op.in_coord(name, lattice, original_pb, original_cl, original_c, original_n, original_h) #enlarge the unit cell by 8 times pb = np.zeros((64, 3)) cl = np.zeros((192, 3)) c = np.zeros((64, 3)) n = np.zeros((64, 3)) h = np.zeros((384, 3)) op.enlarge(original_pb, pb, lattice, 8) op.enlarge(original_cl, cl, lattice, 24) op.enlarge(original_c, c, lattice, 8) op.enlarge(original_n, n, lattice, 8) op.enlarge(original_h, h, lattice, 48) the_n = np.zeros((8, 3)) index_n = np.zeros((8, 1)) the_c = np.zeros((8, 3)) index_c = np.zeros((8, 1)) the_cl = np.zeros((8, 12, 3)) the_pb = np.zeros((8, 8, 3)) distance_o_cl = np.zeros((8, 12)) distance_h_cl = np.zeros((8, 3)) #first get one small cell count = 0 for i in range(64): temp_n = n[i] temp_center = np.zeros((3, 1)) temp_cn = np.zeros((64, 2)) op.gothrough(temp_n, c, temp_cn) temp_c = c[int(temp_cn[0][0])] op.midpoint(temp_c, temp_n, temp_center) #determine the center coordinate #determine the neighbor Cl atoms temp_o_cl = np.zeros((12, 2)) op.gothrough(temp_center, cl, temp_o_cl) #determine the neighbor Pb atoms temp_o_pb = np.zeros((8, 2)) op.gothrough(temp_center, pb, temp_o_pb) if temp_o_cl[11][1] > 5.5: continue else: #determine the H(N) atoms in this unit cell temp_h_n = np.zeros((3, 2)) op.gothrough(temp_n, h, temp_h_n) temp_nh_cl = np.zeros((3, 2)) for j in range(3): op.gothrough(h[int(temp_h_n[j][0])], cl, temp_nh_cl[j, :]) #decide whether we choose this unit cell or not, trying to avoid overlap count2 = 0 for j in range(count + 1): indicator1 = np.linalg.norm(temp_o_cl[:, 1] - distance_o_cl[j, :]) indicator2 = np.linalg.norm(temp_nh_cl[:, 1] - distance_h_cl[j, :]) # print(indicator1) # print(indicator2) if indicator1 > 0.0000001 and indicator2 > 0.0000001: count2 = count2 + 1 continue else: break if count2 == count + 1: distance_o_cl[count, :] = temp_o_cl[:, 1] distance_h_cl[count, :] = temp_nh_cl[:, 1] the_n[count] = temp_n the_c[count] = temp_c index_n[count] = i index_c[count] = temp_cn[0][0] for k in range(12): the_cl[count][k] = cl[int(temp_o_cl[k][0])] for k in range(8): the_pb[count][k] = pb[int(temp_o_pb[k][0])] count = count + 1 #rearrange the chlorine atoms for i in range(8): op.rearrange(the_cl[i]) #After spliting into small cell, let's calculate the hydrogen bonds length. the_nh = np.zeros((8, 3, 3)) the_ch = np.zeros((8, 3, 3)) for i in range(8): temp_h_n = np.zeros((3, 2)) temp_h_c = np.zeros((3, 2)) op.gothrough(the_n[i], h, temp_h_n) op.gothrough(the_c[i], h, temp_h_c) for j in range(3): the_nh[i][j] = h[int(temp_h_n[j][0])] the_ch[i][j] = h[int(temp_h_c[j][0])] #Now starting to calculate the LJ terms #For all Cl atoms in one small cell HCl_6LJ = np.zeros((8, 1)) HCl_12LJ = np.zeros((8, 1)) CHCl_6LJ = np.zeros((8, 1)) CHCl_12LJ = np.zeros((8, 1)) NCl_6LJ = np.zeros((8, 1)) NCl_12LJ = np.zeros((8, 1)) CCl_6LJ = np.zeros((8, 1)) CCl_12LJ = np.zeros((8, 1)) for i in range(8): for j in range(12): dij_NCl = np.linalg.norm(the_n[i] - the_cl[i, j]) dij_CCl = np.linalg.norm(the_c[i] - the_cl[i, j]) NCl_6LJ[i, 0] += count6LJ(dij_NCl) NCl_12LJ[i, 0] += count12LJ(dij_NCl) CCl_6LJ[i, 0] += count6LJ(dij_CCl) CCl_12LJ[i, 0] += count12LJ(dij_CCl) for j in range(3): for k in range(12): dij = np.linalg.norm(the_nh[i][j] - the_cl[i][k]) dij_CH = np.linalg.norm(the_ch[i][j] - the_cl[i][k]) HCl_6LJ[i, 0] += count6LJ(dij) HCl_12LJ[i, 0] += count12LJ(dij) CHCl_6LJ[i, 0] += count6LJ(dij_CH) CHCl_12LJ[i, 0] += count12LJ(dij_CH) #For the nearest 3 Cl atoms for H # for i in range(8): # for j in range(12): # dij_NCl = np.linalg.norm(the_n[i] - the_cl[i,j]); # NCl_6LJ[i,0] += count6LJ(dij_NCl); # NCl_12LJ[i,0] += count12LJ(dij_NCl); # # for j in range(3): # tempCl = np.zeros((3,2)); # op.gothrough(the_nh[i,j],the_cl[i],tempCl); # for k in range(3): # dij = tempCl[k,1]; # HCl_6LJ[i,0] += count6LJ(dij); # HCl_12LJ[i,0] += count12LJ(dij); return np.sum(HCl_6LJ), np.sum(HCl_12LJ), np.sum(CHCl_6LJ),\ np.sum(CHCl_12LJ),np.sum(NCl_6LJ), np.sum(NCl_12LJ),np.sum(CCl_6LJ), np.sum(CCl_12LJ)
def findChargeCenter(name): '''Atoms and Charge should be one-to-one correspondance''' #import the coordinates lattice = np.zeros((3, 3)) original_pb = np.zeros((8, 3)) original_cl = np.zeros((24, 3)) original_c = np.zeros((8, 3)) original_n = np.zeros((8, 3)) original_h = np.zeros((48, 3)) op.in_coord(name, lattice, original_pb, original_cl, original_c, original_n, original_h) #enlarge the unit cell by 8 times pb = np.zeros((64, 3)) cl = np.zeros((192, 3)) c = np.zeros((64, 3)) n = np.zeros((64, 3)) h = np.zeros((384, 3)) op.enlarge(original_pb, pb, lattice, 8) op.enlarge(original_cl, cl, lattice, 24) op.enlarge(original_c, c, lattice, 8) op.enlarge(original_n, n, lattice, 8) op.enlarge(original_h, h, lattice, 48) the_n = np.zeros((8, 3)) index_n = np.zeros((8, 1)) the_c = np.zeros((8, 3)) index_c = np.zeros((8, 1)) the_cl = np.zeros((8, 12, 3)) the_pb = np.zeros((8, 8, 3)) distance_o_cl = np.zeros((8, 12)) distance_h_cl = np.zeros((8, 3)) # mapToOrigin = np.zeros((8,2));# Tell which original molecule they actually correspond to # mapToOrigin[:,0] = np.arange(0,8,1); mapToOrigin = np.zeros((8, 1)) #first get one small cell count = 0 for i in range(64): temp_n = n[i] temp_center = np.zeros((3, 1)) temp_cn = np.zeros((64, 2)) op.gothrough(temp_n, c, temp_cn) temp_c = c[int(temp_cn[0][0])] op.midpoint(temp_c, temp_n, temp_center) #determine the center coordinate #determine the neighbor Cl atoms temp_o_cl = np.zeros((12, 2)) op.gothrough(temp_center, cl, temp_o_cl) #determine the neighbor Pb atoms temp_o_pb = np.zeros((8, 2)) op.gothrough(temp_center, pb, temp_o_pb) if temp_o_cl[11][1] > 5.5: continue else: #determine the H(N) atoms in this unit cell temp_h_n = np.zeros((3, 2)) op.gothrough(temp_n, h, temp_h_n) temp_nh_cl = np.zeros((3, 2)) for j in range(3): op.gothrough(h[int(temp_h_n[j][0])], cl, temp_nh_cl[j, :]) #decide whether we choose this unit cell or not, trying to avoid overlap count2 = 0 for j in range(count + 1): indicator1 = np.linalg.norm(temp_o_cl[:, 1] - distance_o_cl[j, :]) indicator2 = np.linalg.norm(temp_nh_cl[:, 1] - distance_h_cl[j, :]) if indicator1 > 0.0000001 and indicator2 > 0.0000001: count2 = count2 + 1 continue else: break if count2 == count + 1: distance_o_cl[count, :] = temp_o_cl[:, 1] distance_h_cl[count, :] = temp_nh_cl[:, 1] the_n[count] = temp_n the_c[count] = temp_c index_n[count] = i mapToOrigin[count] = i % 8 index_c[count] = temp_cn[0][0] for k in range(12): the_cl[count][k] = cl[int(temp_o_cl[k][0])] for k in range(8): the_pb[count][k] = pb[int(temp_o_pb[k][0])] count = count + 1 #rearrange the chlorine atoms for i in range(8): op.rearrange(the_cl[i]) #Find the hydrogen atoms in each of the cell the_nh = np.zeros((8, 3, 3)) the_ch = np.zeros((8, 3, 3)) for i in range(8): temp_h_n = np.zeros((3, 2)) temp_h_c = np.zeros((3, 2)) op.gothrough(the_n[i], h, temp_h_n) op.gothrough(the_c[i], h, temp_h_c) for j in range(3): the_nh[i][j] = h[int(temp_h_n[j][0])] the_ch[i][j] = h[int(temp_h_c[j][0])] '''Charges. Could be replaced with Bader Charge''' qCl = -1 qPb = 2 qC = -2 qN = -3 qH = 1 orgoCenter = np.zeros((8, 3)) inorgoCenter = np.zeros((8, 3)) for i in range(8): tempCenter = np.zeros((1, 3)) for j in range(8): tempCenter += abs(qPb) * the_pb[i][j][:] for j in range(12): tempCenter += abs(qCl) * the_cl[i][j][:] inorgoCenter[i, :] = tempCenter / (8 * abs(qPb) + 12 * abs(qCl)) pullBackFactor = np.round( np.matmul(np.linalg.inv(lattice), n[int(index_n[i])] - n[int(mapToOrigin[i])])) inorgoCenter[i, :] = inorgoCenter[i, :] - np.matmul( lattice, pullBackFactor) for i in range(8): tempCenter = np.zeros((1, 3)) for j in range(3): tempCenter += abs(qH) * the_nh[i][j][:] for j in range(3): tempCenter += abs(qH) * the_ch[i][j][:] tempCenter += abs(qC) * the_c[i, :] + abs(qN) * the_n[i, :] orgoCenter[i, :] = tempCenter / (6 * abs(qH) + abs(qC) + abs(qN)) pullBackFactor = np.round( np.matmul(np.linalg.inv(lattice), n[int(index_n[i])] - n[int(mapToOrigin[i])])) orgoCenter[i, :] = orgoCenter[i, :] - np.matmul( lattice, pullBackFactor) mapToOrigin = np.argsort(mapToOrigin, axis=0) orgo = orgoCenter[np.int64(mapToOrigin[:, 0]).reshape([8, 1]), [0, 1, 2]] inorgo = inorgoCenter[np.int64(mapToOrigin[:, 0]).reshape([8, 1]), [0, 1, 2]] return orgo, inorgo
NIcouple = np.zeros((200, 1)) NHighSymCouple = np.zeros((200, 1)) '''One body term''' d2 = np.zeros((200, 8)) d4 = np.zeros((200, 8)) for i in range(200): name = 'rand_' + str(i + 51) + '.xsf' NN[i, :], original_N = findNN(name) molecules[i] = findMolecules(name) #Find the nearest high symmetry position for j in range(8): tempHighSym = np.zeros((3, 2)) op.gothrough(original_N[j, :], highSym, tempHighSym) dipoleNHighSym[i, j, :] = original_N[j, :] - highSym[int( tempHighSym[0, 0])] d2[i] = np.square(np.linalg.norm(dipoleNHighSym[i], axis=1)) # d2[i] = np.square(np.linalg.norm(molecules[i],axis=1)); d4[i] = np.sum(np.power(dipoleNHighSym[i], 4), axis=1) # for j in range(8): # d2[i,j] = molecules[i,j,0]**2 + molecules[i,j,1]**2 + molecules[i,j,2]**2; # d4[i,j] = molecules[i,j,0]**4 + molecules[i,j,1]**4 + molecules[i,j,2]**4; print(np.sum(d2[i])) # print(molecules) # aveNN[i] = np.mean(NN[i,:]);
for j in range(4): for k in range(3): diff_pb[j][k] = round(diff_pb[j][k] / lattice[k][k]) all_pb[i][j] = all_pb[i][j] - np.matmul(diff_pb[j], lattice) for j in range(12): for k in range(3): diff_i[j][k] = round(diff_i[j][k] / lattice[k][k]) all_i[i][j] = all_i[i][j] - np.matmul(diff_i[j], lattice) '''Get the rotation of each molecule. phi, cos(theta)''' molecules = np.zeros((numStruct, 4, 2)) for i in range(numStruct): for j in range(4): tempN = np.zeros((3, 2)) op.gothrough(all_c[i][j], all_n[i], tempN) tempMolecule = all_n[i][int(tempN[0][0])] - all_c[i][j] tempMolecule = tempMolecule / np.linalg.norm(tempMolecule) molecules[i][j][1] = tempMolecule[2] x = tempMolecule[0] y = tempMolecule[1] if tempMolecule[1] > 0: molecules[i][j][0] = ma.acos(x / (x**2 + y**2)**0.5) / ma.pi * 180 else: molecules[i][j][0] = 360 - ma.acos( x / (x**2 + y**2)**0.5) / ma.pi * 180 fig1 = plt.figure(figsize=(20, 16)) mole1 = fig1.add_subplot(2, 2, 1) mole1.plot(molecules[:, 0, 0]) plt.title('Molecule 1', fontsize=20)