def get_list_high_energy(gsmpls,threshold): emin = 1e+30 highsmpls = [] ergs = [] for i,s in enumerate(gsmpls): smpldir = s[0] erg = s[1] #atoms = read(smpldir+'/POSCAR',format='vasp') atoms = NAPSystem(fname=smpldir+"/pos",ffmt='pmd') natm = atoms.num_atoms() erg /= natm ergs.append(erg) emin = min(erg,emin) for i,s in enumerate(gsmpls): smpldir = s[0] erg = ergs[i] if erg-emin > threshold: highsmpls.append(smpldir) return highsmpls
def get_list_high_energy(gsmpls,threshold): emin = 1e+30 highsmpls = [] ergs = [] for i,s in enumerate(gsmpls): smpldir = s[0] erg = s[1] #atoms = read(smpldir+'/POSCAR',format='vasp') atoms = NAPSystem(fname=smpldir+"/pos",format='pmd') natm = atoms.num_atoms() erg /= natm ergs.append(erg) emin = min(erg,emin) for i,s in enumerate(gsmpls): smpldir = s[0] erg = ergs[i] if erg-emin > threshold: highsmpls.append(smpldir) return highsmpls
################################################ Main routine ########## if __name__ == "__main__": args = docopt(__doc__) rcut = float(args['--cutoff']) execname = args['--exec'] infname = args['PMDINI'] plot = args['--plot'] #print(args) sys0 = NAPSystem() sys0.read_pmd(infname) sys0.write_POSCAR() print(' POSCAR was written.') natm0 = sys0.num_atoms() h0 = np.zeros((3, 3)) h0[0] = sys0.a1 * sys0.alc h0[1] = sys0.a2 * sys0.alc h0[2] = sys0.a3 * sys0.alc n1, n2, n3 = calc_extention_ratio(h0, rcut) print("n1,n2,n3 = {0:d} {1:d} {2:d}".format(n1, n2, n3)) # Make displaced POSCARS via phonopy os.system("phonopy -d --dim=\"{0:d} {1:d} {2:d}\"".format(n1, n2, n3)) with open('phonopy_disp.yaml', 'r') as f: disp = yaml.load(f) # Make directories for the calculation of those POSCARS poscars = glob.glob("POSCAR-[0-9]??")
def make_polycrystal(grns, uc, n1, n2, n3, two_dim=False): """ THIS ROUTINE IS NOT THAT UNIVERSAL. Each grain has to have neighboring grains within a supercell, otherwise there will be some unexpecting grain boundries. In order to do so, the system should be large enough and the number of grains should be large enough. """ #...Calc the minimum bond distance in unit cell and use it as penetration depth dmin = 1.0e+30 for i in range(uc.num_atoms() - 1): for j in range(i + 1, uc.num_atoms()): dij = uc.get_distance(i, j) dmin = min(dij, dmin) print(' Minimum bond distance in the unitcell: ', dmin) dmin = dmin * DMIN_RATE penetration_depth = dmin * 2 print(' Minimum bond distance allowed in the new system: ', dmin) sv, nsv = shift_vector(two_dim) # print(' nsv =',nsv) # for i in range(nsv): # print(' i,sv[i]=',i,sv[i]) system = NAPSystem(specorder=uc.specorder) system.set_lattice(uc.alc, uc.a1 * n1, uc.a2 * n2, uc.a3 * n3) hmat = np.zeros((3, 3)) hmat[0] = system.a1 * system.alc hmat[1] = system.a2 * system.alc hmat[2] = system.a3 * system.alc hmati = np.linalg.inv(hmat) ix0 = -n1 / 2 - 1 ix1 = n1 / 2 + 2 iy0 = -n2 / 2 - 1 iy1 = n2 / 2 + 2 iz0 = -n3 / 2 - 1 iz1 = n3 / 2 + 2 if two_dim: if n3 != 1: raise ValueError('n3 should be 1 in case two_dim is ON.') iz0 = 0 iz1 = 1 print(' x range = ', ix0, ix1) print(' y range = ', iy0, iy1) print(' z range = ', iz0, iz1) for ig in range(len(grns)): grain = grns[ig] rmat = grain.rmat # Rotation matrix of the grain pi = grain.point # Grain center in reduced coordinate api = np.dot(hmat, pi) # Grain center in Cartessian coordinate print(' grain-ID = ', ig + 1) for ix in range(ix0, ix1): # print('ix=',ix) for iy in range(iy0, iy1): for iz in range(iz0, iz1): for m in range(len(uc.atoms)): rt = np.zeros((3, )) rt[0] = (uc.atoms[m].pos[0] + ix) / n1 rt[1] = (uc.atoms[m].pos[1] + iy) / n2 rt[2] = (uc.atoms[m].pos[2] + iz) / n3 #...rt to absolute position art = np.dot(hmat, rt) #...Rotate ari = np.dot(rmat, art) #...Shift origin to the grain center ari[0] = ari[0] + api[0] ari[1] = ari[1] + api[1] ari[2] = ari[2] + api[2] #...check distance from all the grain points di = distance(ari, api, two_dim) isOutside = False for jg in range(len(grns)): gj = grns[jg] for isv in range(nsv): pj = gj.point if jg == ig: if not two_dim and isv == 13: continue elif two_dim and isv == 4: continue svi = sv[isv] pj = pj + svi apj = np.dot(hmat, pj) dj = distance(ari, apj, two_dim) if dj + penetration_depth < di: # Allow some penetration here isOutside = True break if isOutside: break if isOutside: break #...here ri is inside this grain, register it atom = Atom() #...Cartessian coord to reduced coord ri = np.dot(hmati, ari) ri[0] = pbc(ri[0]) ri[1] = pbc(ri[1]) ri[2] = pbc(ri[2]) atom.set_pos(ri[0], ri[1], ri[2]) atom.set_symbol(uc.atoms[m].symbol) system.add_atom(atom) #...remove too-close atoms at the grain boundaries print(' Making pair list in order to remove close atoms...') print(' Number of atoms: ', system.num_atoms()) system.make_pair_list(RCUT) system.write('POSCAR_orig') short_pairs = [] # dmin2= dmin**2 # xij= np.zeros((3,)) print(' Making the list of SHORT pairs...') for ia in range(system.num_atoms()): # ai= system.atoms[ia] # pi= ai.pos nlst = system.nlspr[ia] lst = system.lspr[ia] for j in range(nlst): ja = lst[j] if ja > ia: continue dij = system.get_distance(ia, ja) if dij < dmin: short_pairs.append((ia, ja, dij)) # aj= system.atoms[ja] # pj= aj.pos # xij[0]= pj[0]-pi[0] -anint(pj[0]-pi[0]) # xij[1]= pj[1]-pi[1] -anint(pj[1]-pi[1]) # xij[2]= pj[2]-pi[2] -anint(pj[2]-pi[2]) # xij= np.dot(hmat,xij) # d2= xij[0]**2 +xij[1]**2 +xij[2]**2 # if d2 < dmin2: # if not ia in ls_remove: # ls_remove.append(ia) # elif not ja in ls_remove: # ls_remove.append(ja) # print('ia,len(ls_remove)=',ia,len(ls_remove)) print(' Number of short pairs: ', len(short_pairs)) #...Remove only relevant atoms, not all the atoms in the short_pairs. ls_remove = [] ls_not_remove = [] for pair in short_pairs: ia = pair[0] ja = pair[1] if ia not in ls_not_remove and ja not in ls_not_remove: ls_remove.append(ia) ls_not_remove.append(ja) elif ia not in ls_not_remove: ls_remove.append(ia) elif ja not in ls_not_remove: ls_remove.append(ja) else: # Both atoms are already in not_remove list, which should be avoided. ls_not_remove.remove(ia) ls_remove.append(ia) ls_not_remove.append(ja) #...Remove double registered IDs ls_remove = uniq(ls_remove) print(' Number of to be removed atoms: ', len(ls_remove)) # print(' Number of to be removed atoms: ',len(ls_remove)) #...one of two will survive # print(' One of two too-close atoms will survive...') # count= [ ls_remove.count(ls_remove[i]) for i in range(len(ls_remove))] # for i in range(0,len(ls_remove),2): # if count[i] > count[i+1]: # ls_remove[i+1]= -1 # elif count[i] < count[i+1]: # ls_remove[i]= -1 # else: # n= int(random()*2.0) # 0 or 1 # ls_remove[i+n]= -1 ls_remove.sort() # for ia in range(len(ls_remove)-1,-1,-1): # n= ls_remove[ia] # if ia != len(ls_remove)-1: # if n == nprev: continue # system.atoms.pop(n) # nprev= n for i in reversed(range(len(ls_remove))): ia = ls_remove[i] system.atoms.pop(ia) return system
def make_polycrystal(grns,uc,n1,n2,n3,two_dim=False): """ THIS ROUTINE IS NOT THAT UNIVERSAL. Each grain has to have neighboring grains within a supercell, otherwise there will be some unexpecting grain boundries. In order to do so, the system should be large enough and the number of grains should be large enough. """ #...Calc the minimum bond distance in unit cell and use it as penetration depth dmin = 1.0e+30 for i in range(uc.num_atoms()-1): for j in range(i+1,uc.num_atoms()): dij = uc.get_distance(i,j) dmin = min(dij,dmin) print(' Minimum bond distance in the unitcell: ',dmin) dmin = dmin *DMIN_RATE penetration_depth = dmin*2 print(' Minimum bond distance allowed in the new system: ',dmin) sv,nsv= shift_vector(two_dim) # print(' nsv =',nsv) # for i in range(nsv): # print(' i,sv[i]=',i,sv[i]) nsys= NAPSystem(specorder=uc.specorder) nsys.set_lattice(uc.alc,uc.a1*n1,uc.a2*n2,uc.a3*n3) hmat = nsys.get_hmat() hmati = nsys.get_hmat_inv() nmax = n1*n2*n3 *uc.num_atoms() sidsl = np.zeros(nmax,dtype=int) symsl = [] possl = np.zeros((nmax,3)) velsl = np.zeros((nmax,3)) frcsl = np.zeros((nmax,3)) ix0 = -n1/2-1 ix1 = n1/2+2 iy0 = -n2/2-1 iy1 = n2/2+2 iz0 = -n3/2-1 iz1 = n3/2+2 if two_dim: if n3 != 1: raise ValueError('n3 should be 1 in case two_dim is ON.') iz0 = 0 iz1 = 1 print(' x range = ',ix0,ix1) print(' y range = ',iy0,iy1) print(' z range = ',iz0,iz1) inc = 0 for ig in range(len(grns)): grain= grns[ig] rmat= grain.rmat # Rotation matrix of the grain pi= grain.point # Grain center in reduced coordinate api= np.dot(hmat,pi) # Grain center in Cartessian coordinate print(' grain-ID = ',ig+1) for ix in range(ix0,ix1): # print('ix=',ix) for iy in range(iy0,iy1): for iz in range(iz0,iz1): for m in range(uc.num_atoms()): sidt = uc.get_atom_attr(m,'sid') rt= np.zeros((3,)) pm = uc.get_atom_attr(m,'pos') rt[0]= (pm[0]+ix)/n1 rt[1]= (pm[1]+iy)/n2 rt[2]= (pm[2]+iz)/n3 #...rt to absolute position art= np.dot(hmat,rt) #...Rotate ari= np.dot(rmat,art) #...Shift origin to the grain center ari[0]= ari[0]+api[0] ari[1]= ari[1]+api[1] ari[2]= ari[2]+api[2] #...check distance from all the grain points di= distance(ari,api,two_dim) isOutside= False for jg in range(len(grns)): gj= grns[jg] for isv in range(nsv): pj= gj.point if jg == ig: if not two_dim and isv == 13: continue elif two_dim and isv == 4: continue svi= sv[isv] pj= pj +svi apj = np.dot(hmat,pj) dj= distance(ari,apj,two_dim) if dj +penetration_depth < di: # Allow some penetration here isOutside= True break if isOutside: break if isOutside: break #...here ri is inside this grain, register it #...Cartessian coord to reduced coord ri = np.dot(hmati,ari) ri[0]= pbc(ri[0]) ri[1]= pbc(ri[1]) ri[2]= pbc(ri[2]) sidsl[inc] = sidt possl[inc] = ri velsl[inc,:] = 0.0 frcsl[inc,:] = 0.0 symsl.append(nsys.specorder[sidt-1]) inc += 1 if inc > nmax: raise ValueError('inc > nmax') #...Create filled arrays from non-filled ones poss = np.array(possl[:inc]) vels = np.array(velsl[:inc]) frcs = np.array(frcsl[:inc]) nsys.add_atoms(symsl,poss,vels,frcs) #...remove too-close atoms at the grain boundaries print(' Making pair list in order to remove close atoms...') print(' Number of atoms: ',nsys.num_atoms()) nsys.make_pair_list(RCUT) nsys.write('POSCAR_orig') short_pairs = [] # dmin2= dmin**2 # xij= np.zeros((3,)) print(' Making the list of SHORT pairs...') for ia in range(nsys.num_atoms()): lst= nsys.get_atom_attr(ia,'lspr') for j in range(len(lst)): ja= lst[j] if ja > ia: continue dij = nsys.get_distance(ia,ja) if dij < dmin: short_pairs.append((ia,ja,dij)) print(' Number of short pairs: ',len(short_pairs)) #...Remove only relevant atoms, not all the atoms in the short_pairs. ls_remove = [] ls_not_remove = [] for pair in short_pairs: ia = pair[0] ja = pair[1] if ia not in ls_not_remove and ja not in ls_not_remove: ls_remove.append(ia) ls_not_remove.append(ja) elif ia not in ls_not_remove: ls_remove.append(ia) elif ja not in ls_not_remove: ls_remove.append(ja) else: # Both atoms are already in not_remove list, which should be avoided. ls_not_remove.remove(ia) ls_remove.append(ia) ls_not_remove.append(ja) #...Remove double registered IDs ls_remove = uniq(ls_remove) print(' Number of to be removed atoms: ',len(ls_remove)) nsys.remove_atoms(*ls_remove) return nsys
def make_polycrystal(grns,uc,n1,n2,n3,two_dim=False): """ THIS ROUTINE IS NOT THAT UNIVERSAL. Each grain has to have neighboring grains within a supercell, otherwise there will be some unexpecting grain boundries. In order to do so, the system should be large enough and the number of grains should be large enough. """ #...Calc the minimum bond distance in unit cell and use it as penetration depth dmin = 1.0e+30 for i in range(uc.num_atoms()-1): for j in range(i+1,uc.num_atoms()): dij = uc.get_distance(i,j) dmin = min(dij,dmin) print(' Minimum bond distance in the unitcell: ',dmin) dmin = dmin *DMIN_RATE penetration_depth = dmin*2 print(' Minimum bond distance allowed in the new system: ',dmin) sv,nsv= shift_vector(two_dim) # print(' nsv =',nsv) # for i in range(nsv): # print(' i,sv[i]=',i,sv[i]) system= NAPSystem(specorder=uc.specorder) system.set_lattice(uc.alc,uc.a1*n1,uc.a2*n2,uc.a3*n3) hmat= np.zeros((3,3)) hmat[0]= system.a1 *system.alc hmat[1]= system.a2 *system.alc hmat[2]= system.a3 *system.alc hmati= np.linalg.inv(hmat) ix0 = -n1/2-1 ix1 = n1/2+2 iy0 = -n2/2-1 iy1 = n2/2+2 iz0 = -n3/2-1 iz1 = n3/2+2 if two_dim: if n3 != 1: raise ValueError('n3 should be 1 in case two_dim is ON.') iz0 = 0 iz1 = 1 print(' x range = ',ix0,ix1) print(' y range = ',iy0,iy1) print(' z range = ',iz0,iz1) for ig in range(len(grns)): grain= grns[ig] rmat= grain.rmat # Rotation matrix of the grain pi= grain.point # Grain center in reduced coordinate api= np.dot(hmat,pi) # Grain center in Cartessian coordinate print(' grain-ID = ',ig+1) for ix in range(ix0,ix1): # print('ix=',ix) for iy in range(iy0,iy1): for iz in range(iz0,iz1): for m in range(len(uc.atoms)): rt= np.zeros((3,)) rt[0]= (uc.atoms[m].pos[0]+ix)/n1 rt[1]= (uc.atoms[m].pos[1]+iy)/n2 rt[2]= (uc.atoms[m].pos[2]+iz)/n3 #...rt to absolute position art= np.dot(hmat,rt) #...Rotate ari= np.dot(rmat,art) #...Shift origin to the grain center ari[0]= ari[0]+api[0] ari[1]= ari[1]+api[1] ari[2]= ari[2]+api[2] #...check distance from all the grain points di= distance(ari,api,two_dim) isOutside= False for jg in range(len(grns)): gj= grns[jg] for isv in range(nsv): pj= gj.point if jg == ig: if not two_dim and isv == 13: continue elif two_dim and isv == 4: continue svi= sv[isv] pj= pj +svi apj = np.dot(hmat,pj) dj= distance(ari,apj,two_dim) if dj +penetration_depth < di: # Allow some penetration here isOutside= True break if isOutside: break if isOutside: break #...here ri is inside this grain, register it atom= Atom() #...Cartessian coord to reduced coord ri = np.dot(hmati,ari) ri[0]= pbc(ri[0]) ri[1]= pbc(ri[1]) ri[2]= pbc(ri[2]) atom.set_pos(ri[0],ri[1],ri[2]) atom.set_symbol(uc.atoms[m].symbol) system.add_atom(atom) #...remove too-close atoms at the grain boundaries print(' Making pair list in order to remove close atoms...') print(' Number of atoms: ',system.num_atoms()) system.make_pair_list(RCUT) system.write('POSCAR_orig') short_pairs = [] # dmin2= dmin**2 # xij= np.zeros((3,)) print(' Making the list of SHORT pairs...') for ia in range(system.num_atoms()): # ai= system.atoms[ia] # pi= ai.pos nlst= system.nlspr[ia] lst= system.lspr[ia] for j in range(nlst): ja= lst[j] if ja > ia: continue dij = system.get_distance(ia,ja) if dij < dmin: short_pairs.append((ia,ja,dij)) # aj= system.atoms[ja] # pj= aj.pos # xij[0]= pj[0]-pi[0] -anint(pj[0]-pi[0]) # xij[1]= pj[1]-pi[1] -anint(pj[1]-pi[1]) # xij[2]= pj[2]-pi[2] -anint(pj[2]-pi[2]) # xij= np.dot(hmat,xij) # d2= xij[0]**2 +xij[1]**2 +xij[2]**2 # if d2 < dmin2: # if not ia in ls_remove: # ls_remove.append(ia) # elif not ja in ls_remove: # ls_remove.append(ja) # print('ia,len(ls_remove)=',ia,len(ls_remove)) print(' Number of short pairs: ',len(short_pairs)) #...Remove only relevant atoms, not all the atoms in the short_pairs. ls_remove = [] ls_not_remove = [] for pair in short_pairs: ia = pair[0] ja = pair[1] if ia not in ls_not_remove and ja not in ls_not_remove: ls_remove.append(ia) ls_not_remove.append(ja) elif ia not in ls_not_remove: ls_remove.append(ia) elif ja not in ls_not_remove: ls_remove.append(ja) else: # Both atoms are already in not_remove list, which should be avoided. ls_not_remove.remove(ia) ls_remove.append(ia) ls_not_remove.append(ja) #...Remove double registered IDs ls_remove = uniq(ls_remove) print(' Number of to be removed atoms: ',len(ls_remove)) # print(' Number of to be removed atoms: ',len(ls_remove)) #...one of two will survive # print(' One of two too-close atoms will survive...') # count= [ ls_remove.count(ls_remove[i]) for i in range(len(ls_remove))] # for i in range(0,len(ls_remove),2): # if count[i] > count[i+1]: # ls_remove[i+1]= -1 # elif count[i] < count[i+1]: # ls_remove[i]= -1 # else: # n= int(random()*2.0) # 0 or 1 # ls_remove[i+n]= -1 ls_remove.sort() # for ia in range(len(ls_remove)-1,-1,-1): # n= ls_remove[ia] # if ia != len(ls_remove)-1: # if n == nprev: continue # system.atoms.pop(n) # nprev= n for i in reversed(range(len(ls_remove))): ia = ls_remove[i] system.atoms.pop(ia) return system
def get_msd(files, ids0, nmeasure, nshift, specorder=None): """ Compute MSD of specified species-ID from sequential structure FILES. Parameters ---------- files: list List of files used for the MSD calculation. ids0: list List of atom-IDs (starting from 1) whose MSDs are to be computed. nmeasure: int Number of staggered lanes to compute MSD for better statistics. nshift: int Number of files to be skipped for each staggered lane. specorder: list Order of species. Returns ------- msd : Numpy array of dimension, (len(files),nmeasure,3). """ if specorder is not None: nsys = NAPSystem(fname=files[0], specorder=specorder) else: nsys = NAPSystem(fname=files[0], ) specorder = copy.copy(nsys.specorder) nspc = len(specorder) if ids0 is not None: ids = [i - 1 for i in ids0] sids = nsys.atoms.sid naps = [0 for i in len(specorder)] for i in ids0: sid = sids[i] naps[sid - 1] += 1 else: ids = [i for i in range(nsys.num_atoms())] naps = nsys.natm_per_species() symbols = nsys.get_symbols() p0 = np.zeros((nmeasure, len(ids), 3)) pp = np.zeros((len(ids), 3)) # msd= np.zeros((len(files),nmeasure,nspc,3)) msd = np.zeros( (len(files) - (nmeasure - 1) * nshift + 1, nmeasure, nspc, 3)) npbc = np.zeros((len(ids), 3)) hmat = np.zeros((3, 3)) for ifile in range(len(files)): fname = files[ifile] sys.stdout.write( '\r{0:5d}/{1:d}: {2:s}'.format(ifile + 1, len(files), fname), ) sys.stdout.flush() if ifile != 0: nsys = NAPSystem(fname=fname, specorder=specorder) poss = nsys.atoms.pos sids = nsys.atoms.sid hmat = nsys.get_hmat() for ia, idi in enumerate(ids): # #...human-readable ID to computer-oriented ID # i= idi - 1 pi = poss[idi] sid = sids[idi] - 1 if ifile == 0: pp[ia, :] = pi[:] else: #...correct periodic motion dev = pi - pp[ia] if dev[0] > 0.5: npbc[ia, 0] += -1.0 elif dev[0] < -0.5: npbc[ia, 0] += 1.0 if dev[1] > 0.5: npbc[ia, 1] += -1.0 elif dev[1] < -0.5: npbc[ia, 1] += 1.0 if dev[2] > 0.5: npbc[ia, 2] += -1.0 elif dev[2] < -0.5: npbc[ia, 2] += 1.0 # print npbc #...store current position pp[ia, :] = pi[:] for nm in range(nmeasure): if ifile == nm * nshift: p0[nm, ia, 0] = pi[0] + npbc[ia, 0] p0[nm, ia, 1] = pi[1] + npbc[ia, 1] p0[nm, ia, 2] = pi[2] + npbc[ia, 2] if nm * nshift < ifile <= (nm + 1) * nshift: #...normalized to absolute dev[0] = pi[0] + npbc[ia, 0] - p0[nm, ia, 0] dev[1] = pi[1] + npbc[ia, 1] - p0[nm, ia, 1] dev[2] = pi[2] + npbc[ia, 2] - p0[nm, ia, 2] dev = np.dot(hmat, dev) msd[ifile - nm * nshift, nm, sid, 0] += dev[0]**2 msd[ifile - nm * nshift, nm, sid, 1] += dev[1]**2 msd[ifile - nm * nshift, nm, sid, 2] += dev[2]**2 for ifile in range(len(files)): for nm in range(nmeasure): if nm * nshift < ifile <= (nm + 1) * nshift: msd[ifile - nm * nshift, nm, :, 0] /= naps[:] msd[ifile - nm * nshift, nm, :, 1] /= naps[:] msd[ifile - nm * nshift, nm, :, 2] /= naps[:] print('') return msd, specorder