def read_lammps_data(fname="data.lammps", atom_style='atomic', specorder=None): nsys = NAPSystem() if specorder is None: nsys.specorder = [] else: nsys.specorder = specorder f = open(fname, 'r') mode = 'None' iatm = 0 symbol = None nsys.alc = 1.0 xy = 0.0 xz = 0.0 yz = 0.0 for line in f.readlines(): data = line.split() if mode == 'None': if 'atoms' in line: natm = int(data[0]) sids = [0 for i in range(natm)] poss = np.zeros((natm, 3)) vels = np.zeros((natm, 3)) frcs = np.zeros((natm, 3)) elif 'atom types' in line: nspcs = int(data[0]) elif 'xlo' in line: xlo = float(data[0]) xhi = float(data[1]) elif 'ylo' in line: ylo = float(data[0]) yhi = float(data[1]) elif 'zlo' in line: zlo = float(data[0]) zhi = float(data[1]) elif 'xy' in line: xy = float(data[0]) xz = float(data[1]) yz = float(data[2]) elif 'Atoms' in line: mode = 'Atoms' #...Cell info (xhi,xlo,...) should already be read # nsys.a1 = np.array([xhi-xlo,xy,xz],dtype=float) # nsys.a2 = np.array([0.0,yhi-ylo,yz],dtype=float) # nsys.a3 = np.array([0.0,0.0,zhi-zlo],dtype=float) nsys.a1 = np.array([xhi - xlo, 0.0, 0.0], dtype=float) nsys.a2 = np.array([xy, yhi - ylo, 0.0], dtype=float) nsys.a3 = np.array([xz, yz, zhi - zlo], dtype=float) hmat = nsys.get_hmat() hmati = np.linalg.inv(hmat) continue elif mode == 'Atoms': if len(data) >= 5 and iatm < natm: idat = 0 # ai = Atom() idat += 1 # ai.set_sid(int(data[idat])) sid = int(data[idat]) sids[iatm] = sid if nsys.specorder: symbol = nsys.specorder[sid - 1] # if symbol and ai.symbol != symbol: # ai.set_symbol(symbol) # if atom_style == 'charge': # idat += 1 # chg = float(data[idat]) # # ai.set_aux('charge',chg) # if aux_names and 'charge' not in aux_names: idat += 1 x0 = float(data[idat]) idat += 1 y0 = float(data[idat]) idat += 1 z0 = float(data[idat]) x = hmati[0, 0] * x0 + hmati[0, 1] * y0 + hmati[0, 2] * z0 y = hmati[1, 0] * x0 + hmati[1, 1] * y0 + hmati[1, 2] * z0 z = hmati[2, 0] * x0 + hmati[2, 1] * y0 + hmati[2, 2] * z0 x = pbc(x) y = pbc(y) z = pbc(z) poss[iatm, :] = [x, y, z] iatm += 1 f.close() nsys.atoms[['x', 'y', 'z']] = poss nsys.atoms[['vx', 'vy', 'vz']] = vels nsys.atoms[['fx', 'fy', 'fz']] = frcs nsys.atoms['sid'] = sids return nsys
def read_dump(fname="dump", specorder=None): nsys = NAPSystem() f = open(fname, 'r') mode = 'None' ixyz = 0 iatm = 0 natm = -1 symbol = None if specorder is None: nsys.specorder = [] else: nsys.specorder = specorder nsys.alc = 1.0 xy = 0.0 xz = 0.0 yz = 0.0 aux_exists = { 'x': -1, 'y': -1, 'z': -1, 'xu': -1, 'yu': -1, 'zu': -1, 'fx': -1, 'fy': -1, 'fz': -1, 'ekin': -1, 'epot': -1, 'sxx': -1, 'syy': -1, 'szz': -1, 'syz': -1, 'sxz': -1, 'sxy': -1, 'chg': -1, 'chi': -1 } ivx = -1 ivy = -1 ivz = -1 ifx = -1 ify = -1 ifz = -1 for line in f.readlines(): data = line.split() if 'ITEM' in line: if 'NUMBER OF ATOMS' in line: mode = 'NUMBER OF ATOMS' continue elif 'BOX BOUNDS' in line: mode = 'BOX BOUNDS' continue elif 'ATOMS' in line: mode = 'ATOMS' aux_names = [name for i, name in enumerate(data) if i > 1] aux_names.remove('id') aux_names.remove('type') if ('x' not in aux_names and 'xu' not in aux_names) or \ ('y' not in aux_names and 'zu' not in aux_names) or \ ('z' not in aux_names and 'zu' not in aux_names): raise ValueError( 'Not enough coordinate info.\nCheck the dump file format.' ) try: ix = aux_names.index('x') + 2 except Exception: ix = aux_names.index('xu') + 2 try: iy = aux_names.index('y') + 2 except Exception: iy = aux_names.index('yu') + 2 try: iz = aux_names.index('z') + 2 # iauxstart = 5 except Exception: iz = aux_names.index('zu') + 2 # iauxstart = 5 try: ivx = aux_names.index('vx') + 2 ivy = aux_names.index('vy') + 2 ivz = aux_names.index('vz') + 2 # iauxstart = 8 except Exception: pass try: ifx = aux_names.index('fx') + 2 ify = aux_names.index('fy') + 2 ifz = aux_names.index('fz') + 2 except Exception: pass # for s in ('x','xu','y','yu','z','zu','vx','vy','vz'): # if s in aux_names: # aux_names.remove(s) if len(aux_names) > 0: auxs = np.zeros((natm, len(aux_names))) continue elif 'TIMESTEP' in line: mode = 'TIMESTEP' continue if mode == 'TIMESTEP': timestep = int(data[0]) elif mode == 'NUMBER OF ATOMS': natm = int(data[0]) sids = [0 for i in range(natm)] # poss = [ np.zeros(3) for i in range(natm) ] # vels = [ np.zeros(3) for i in range(natm) ] # frcs = [ np.zeros(3) for i in range(natm) ] poss = np.zeros((natm, 3)) vels = np.zeros((natm, 3)) frcs = np.zeros((natm, 3)) elif mode == 'BOX BOUNDS': if ixyz == 0: xlo_bound = float(data[0]) xhi_bound = float(data[1]) if len(data) > 2: xy = float(data[2]) elif ixyz == 1: ylo_bound = float(data[0]) yhi_bound = float(data[1]) if len(data) > 2: xz = float(data[2]) elif ixyz == 2: zlo_bound = float(data[0]) zhi_bound = float(data[1]) if len(data) > 2: yz = float(data[2]) ixyz += 1 if ixyz > 2: xlo = xlo_bound - min(0.0, xy, xz, xy + xz) xhi = xhi_bound - max(0.0, xy, xz, xy + xz) ylo = ylo_bound - min(0.0, yz) yhi = yhi_bound - max(0.0, yz) zlo = zlo_bound zhi = zhi_bound #...Original definition of lattice vectors could be different # from this, because the definition in dump format # requires y,z-components of vector a1 to be zero. nsys.a1 = np.array([xhi - xlo, 0., 0.], dtype=float) nsys.a2 = np.array([xy, yhi - ylo, 0.], dtype=float) nsys.a3 = np.array([xz, yz, zhi - zlo], dtype=float) hmat = nsys.get_hmat() hmati = nsys.get_hmat_inv() elif mode == 'ATOMS': if iatm < natm: symbol = None if data[1].isdigit(): sid = int(data[1]) sids[iatm] = sid symbol = nsys.specorder[sid - 1] else: symbol = data[1] if symbol not in nsys.specorder: nsys.specorder.append(symbol) sid = nsys.specorder.index(symbol) + 1 sids[iatm] = sid r0 = [float(data[ix]), float(data[iy]), float(data[iz])] if ivx > 0 and ivy > 0 and ivz > 0: v0 = [float(data[ivx]), float(data[ivy]), float(data[ivz])] else: v0 = [0., 0., 0.] if ifx > 0 and ify > 0 and ifz > 0: f0 = [float(data[ifx]), float(data[ify]), float(data[ifz])] else: f0 = [0., 0., 0.] sr = np.dot(hmati, r0) sv = np.dot(hmati, v0) sr[0] = pbc(sr[0]) sr[1] = pbc(sr[1]) sr[2] = pbc(sr[2]) # poss[iatm][:] = sr[:] # vels[iatm][:] = sv[:] poss[iatm, :] = sr[:] vels[iatm, :] = sv[:] frcs[iatm, :] = f0[:] if len(aux_names) > 0: # auxs[iatm,:] = [ float(x) for x in data[iauxstart:] ] auxs[iatm, :] = [float(x) for x in data[2:]] iatm += 1 nsys.atoms[['x', 'y', 'z']] = poss nsys.atoms[['vx', 'vy', 'vz']] = vels nsys.atoms[['fx', 'fy', 'fz']] = frcs nsys.atoms['sid'] = sids for ia in range(len(aux_names)): name = aux_names[ia] if name in ('x', 'xu', 'y', 'yu', 'z', 'zu', 'vx', 'vy', 'vz', 'fx', 'fy', 'fz'): continue aux = auxs[:, ia] nsys.atoms[name] = aux.tolist() f.close() return nsys
def to_given_vector(infile,specorder,a1new,a2new,a3new): psys = NAPSystem(fname=infile,specorder=specorder) psys.assign_pbc() psys.a1 = psys.a1 *psys.alc psys.a2 = psys.a2 *psys.alc psys.a3 = psys.a3 *psys.alc psys.alc = 1.0 print('a1 = ',psys.a1) print('a2 = ',psys.a2) print('a3 = ',psys.a3) pos = psys.get_real_positions() spos = psys.get_scaled_positions() for i in range(min(len(psys.atoms),10)): a = psys.atoms[i] print('{0:5d} {1:s}'.format(a.id,a.symbol) +' {0:12.5f} {1:12.5f} {2:12.5f}'.format(spos[i,0], spos[i,1], spos[i,2]) +' {0:12.5f} {1:12.5f} {2:12.5f}'.format(pos[i,0], pos[i,1], pos[i,2])) # print(psys.get_scaled_positions()) # print(psys.get_real_positions()) # sa1new = np.zeros(3,dtype=float) # sa2new = np.zeros(3,dtype=float) # sa3new = np.zeros(3,dtype=float) #tmp = raw_input('Input new a1 vector: ') #a1new[:] = [ float(x) for x in tmp.split(',') ] # sa1new[:] = [ 0.5, 0.5, 0.0] #tmp = raw_input('Input new a2 vector: ') #a2new[:] = [ float(x) for x in tmp.split(',') ] # sa2new[:] = [ 0.0, 1.0, 0.0 ] #tmp = raw_input('Input new a3 vector: ') #a3new[:] = [ float(x) for x in tmp.split(',') ] # sa3new[:] = [ 0.5, 0.5, 1.0 ] hmat = psys.get_hmat() a1new = np.dot(hmat,sa1new) a2new = np.dot(hmat,sa2new) a3new = np.dot(hmat,sa3new) print('new a1 in hmat_orig =',sa1new) print('new a2 in hmat_orig =',sa2new) print('new a3 in hmat_orig =',sa3new) print('new a1 =',a1new) print('new a2 =',a2new) print('new a3 =',a3new) psnew = NAPSystem(specorder=specorder) psnew.set_lattice(psys.alc,a1new,a2new,a3new) # Expand the original system for the search of atoms to be included # in the new system. # First, compute how much we have to expand the original system hi = np.linalg.inv(hmat) icsa1new = [0,0,0] icsa2new = [0,0,0] icsa3new = [0,0,0] for i in range(3): if sa1new[i] < 0.0: icsa1new[i] = int(sa1new[i]-1.0) else: icsa1new[i] = int(sa1new[i]+1.0) if sa2new[i] < 0.0: icsa2new[i] = int(sa2new[i]-1.0) else: icsa2new[i] = int(sa2new[i]+1.0) if sa3new[i] < 0.0: icsa3new[i] = int(sa3new[i]-1.0) else: icsa3new[i] = int(sa3new[i]+1.0) print(icsa1new) print(icsa2new) print(icsa3new) for i in range(3): if icsa1new[i] == 0: raise RuntimeError('icsa1new[i] == 0') if icsa2new[i] == 0: raise RuntimeError('icsa2new[i] == 0') if icsa3new[i] == 0: raise RuntimeError('icsa3new[i] == 0') irange1 = (min(icsa1new[0],icsa2new[0],icsa3new[0]), max(icsa1new[0],icsa2new[0],icsa3new[0])) irange2 = (min(icsa1new[1],icsa2new[1],icsa3new[1]), max(icsa1new[1],icsa2new[1],icsa3new[1])) irange3 = (min(icsa1new[2],icsa2new[2],icsa3new[2]), max(icsa1new[2],icsa2new[2],icsa3new[2])) print('irange1: ',irange1) print('irange2: ',irange2) print('irange3: ',irange3) expos = [] symbols = psys.get_symbols() print('symbols :',symbols) exsymbols = [] print('Expanding the original system...') for n3 in range(min(0,irange3[0]),irange3[1]): for n2 in range(min(0,irange2[0]),irange2[1]): for n1 in range(min(0,irange1[0]),irange1[1]): for ia in range(len(spos)): sposi = copy.deepcopy(spos[ia]) sposi[0] += n1 sposi[1] += n2 sposi[2] += n3 posi = np.dot(hmat,sposi) symbol = symbols[ia] # print(ia,n1,n2,n3,symbol,sposi) expos.append(posi) exsymbols.append(symbol) print('Extracting the atoms inside the new unit vectors...') hmat= psnew.get_hmat() hi = np.linalg.inv(hmat) for ia,posi in enumerate(expos): sposi = np.dot(hi,posi) if 0.0 <= sposi[0] < 1.0 and \ 0.0 <= sposi[1] < 1.0 and \ 0.0 <= sposi[2] < 1.0: atom = Atom() symbol = exsymbols[ia] print('{0:5d} {1:s}'.format(ia,symbol) +' {0:12.5f} {1:12.5f} {2:12.5f}'.format(sposi[0], sposi[1], sposi[2])) atom.set_symbol(symbol) atom.set_pos(sposi[0],sposi[1],sposi[2]) psnew.add_atom(atom) tmp = None #tmp = raw_input('Input periodic shift vector if you want: ') tmp = ' 0.5, 0.0, 0.5' if tmp: shift = [ float(x) for x in tmp.split(',')] for a in psnew.atoms: a.pos[0] += shift[0] a.pos[1] += shift[1] a.pos[2] += shift[2] psnew.assign_pbc() psnew.write_POSCAR(infile+'.new') print('Check '+infile+'.new')
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 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
if __name__ == '__main__': args = docopt(__doc__) niter = int(args['-n']) dltmax = float(args['-d']) mdexec = args['--mdexec'] if niter < 2: raise ValueError('NITER {0:d} should be larger than 1.'.format(niter)) if niter % 2 == 0: niter += 1 nsys0 = NAPSystem(fname='pmdini') os.system('cp pmdini pmdini.bak') hmat0 = nsys0.get_hmat() print('Original H-matrix:') print(hmat0) # al,hmat0,natm= read_pmd() hmax = np.max(hmat0) print('Maximum in H-matrix elements = ', hmax) outfile1 = open(outfname, 'w') #...get reference energy os.system(mdexec + ' > out.pmd') erg0 = float(subprocess.check_output("cat erg.pmd", shell=True)) #erg0= float(commands.getoutput("grep 'potential energy' out.pmd | tail -n1 | awk '{print $3}'")) # print ' {0:10.4f} {1:15.7f} {2:15.7f} {3:15.7f}'.format(0.0,erg0,erg0,erg0) # outfile1.write(' {0:10.4f} {1:15.7f} {2:15.7f} {3:15.7f}\n'.format(0.0,erg0,erg0,erg0)) dltmin = -dltmax ddlt = (dltmax - dltmin) / (niter - 1)