def read_pmd(fname='pmdini', specorder=None): nsys = NAPSystem() if specorder is not None: nsys.specorder = specorder incatm = 0 with open(fname, 'r') as f: iline = 0 symbol = None for line in f.readlines(): if line[0] in ('#', '!'): # comment line if 'specorder:' in line: # overwrite specorder if specified in file data = line.split() specorder = [d for d in data[2:len(data)]] if nsys.specorder and set( nsys.specorder) != set(specorder): print(' WARNING: specorders are inconsistent, ' + 'use one in the file.') nsys.specorder = specorder else: if nsys.specorder is None or len(nsys.specorder) == 0: raise ValueError( 'Specorder must be specified via the file or an argument.' ) iline = iline + 1 data = line.split() # 1st: lattice constant if iline == 1: nsys.alc = float(data[0]) # 2nd-4th: cell vectors elif iline == 2: nsys.a1 = np.array([float(x) for x in data]) elif iline == 3: nsys.a2 = np.array([float(x) for x in data]) elif iline == 4: nsys.a3 = np.array([float(x) for x in data]) # 5th-7th: velocity of cell vectors elif 5 <= iline <= 7: pass # 8th: num of atoms elif iline == 8: 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)) # 9th-: atom positions else: if incatm > natm: break fdata = [float(x) for x in data] tag = fdata[0] sid, ifmv, num = decode_tag(tag) # poss[incatm][:] = fdata[1:4] # vels[incatm][:] = fdata[4:7] poss[incatm, :] = fdata[1:4] vels[incatm, :] = fdata[4:7] sids[incatm] = sid incatm += 1 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_CHGCAR(fname='CHGCAR', specorder=None): """ Read CHGCAR file and get information of cell, atoms, and volumetric data. Parameters ---------- fname : str File name to be read. """ nsys = NAPSystem() with open(fname, 'r') as f: # 1st line: comment f.readline() # 2nd: lattice constant nsys.alc = float(f.readline().split()[0]) # 3rd-5th: cell vectors nsys.a1 = np.array([float(x) for x in f.readline().split()]) nsys.a2 = np.array([float(x) for x in f.readline().split()]) nsys.a3 = np.array([float(x) for x in f.readline().split()]) # 6th: species names or number of each species buff = f.readline().split() if not buff[0].isdigit(): spcs = copy.deepcopy(buff) buff = f.readline().split() if specorder is None: nsys.specorder = spcs else: nsys.specorder = specorder for s in spcs: if s not in nsys.specorder: nsys.specorder.append(s) num_species = np.array([int(n) for n in buff]) try: spcs except NameError: spcs = nsys.specorder #...Check number of species in POSCAR file and in specorder if len(num_species) > len(nsys.specorder): msg = ''' ers of species in POSCAR is greater than the one in specorder, which should be the same or less. er of species in POSCAR = {0:d} need to specify the species order correctly with --specorder option. '''.format(len(num_species)) raise ValueError(msg) natm = np.sum(num_species) sids = [0 for i in range(natm)] poss = np.zeros((natm, 3)) vels = np.zeros((natm, 3)) frcs = np.zeros((natm, 3)) #print("Number of atoms = {0:5d}".format(natm)) # 7th or 8th line: comment c7 = f.readline() if c7[0] in ('s', 'S'): c7 = f.readline() if c7[0] in ('c', 'C'): # positions are in Cartesian coordinate hi = nsys.get_hmat_inv() coord = 'cartesian' else: # such as "Direct" coord = 'scaled' #...Atom positions for i in range(natm): buff = f.readline().split() sid = 1 m = 0 sindex = 0 for n in num_species: m += n if i < m: if spcs and nsys.specorder: sid = nsys.specorder.index(spcs[sindex]) + 1 break sid += 1 sindex += 1 sids[i] = sid pos = [float(buff[0]), float(buff[1]), float(buff[2])] if coord == 'cartesian': x1, x2, x3 = cartesian_to_scaled(hi, pos[0], pos[1], pos[2]) elif coord == 'scaled': x1, x2, x3 = pos[0], pos[1], pos[2] poss[i][:] = [x1, x2, x3] #...Up to here, code should be the same as read_POSCAR, in case of CHGCAR lines follow nsys.atoms[['x', 'y', 'z']] = poss nsys.atoms[['vx', 'vy', 'vz']] = vels nsys.atoms[['fx', 'fy', 'fz']] = frcs nsys.atoms['sid'] = sids #...Read volumetric data f.readline() # should be one blank line ndiv = [int(x) for x in f.readline().split()] ndata = ndiv[0] * ndiv[1] * ndiv[2] voldata = np.zeros(ndata) inc = 0 while True: line = [float(d) for d in f.readline().split()] for d in line: voldata[inc] = d inc += 1 if inc >= ndata: break #...Stop reading CHGCAR file here, ignoring the rest of file nsys.ndiv = copy.copy(ndiv) nsys.voldata = np.reshape(voldata, ndiv, order='F') return nsys
def read_xsf(fname="xsf", specorder=None): from nappy.elements import get_symbol_from_number nsys = NAPSystem() if specorder is None: nsys.specorder = [] else: nsys.specorder = specorder f = open(fname, 'r') mode = 'None' ixyz = 0 iatm = 0 natm = -1 for line in f.readlines(): if 'CRYSTAL' in line: mode = 'CRYSTAL' continue elif 'PRIMVEC' in line: mode = 'PRIMVEC' continue elif 'PRIMCOORD' in line: mode = 'PRIMCOORD' # Before going further, create inversed h-matrix hi = nsys.get_hmat_inv() # print 'Inversed h-matrix:' # print hi continue if mode == 'CRYSTAL': pass elif mode == 'PRIMVEC': if ixyz == 0: arr = [float(x) for x in line.split()] nsys.a1[0] = arr[0] nsys.a1[1] = arr[1] nsys.a1[2] = arr[2] elif ixyz == 1: arr = [float(x) for x in line.split()] nsys.a2[0] = arr[0] nsys.a2[1] = arr[1] nsys.a2[2] = arr[2] elif ixyz == 2: arr = [float(x) for x in line.split()] nsys.a3[0] = arr[0] nsys.a3[1] = arr[1] nsys.a3[2] = arr[2] ixyz += 1 elif mode == 'PRIMCOORD': data = line.split() if len(data) == 1: 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)) continue elif len(data) == 2: natm = int(data[0]) nspcs = int(data[1]) sids = [0 for i in range(natm)] poss = np.zeros((natm, 3)) vels = np.zeros((natm, 3)) frcs = np.zeros((natm, 3)) continue elif len(data) == 4 or len(data) == 7: if iatm >= natm: continue symbol = get_symbol_from_number(int(data[0])) if symbol not in nsys.specorder: nsys.specorder.append(symbol) sid = nsys.specorder.index(symbol) + 1 sids[iatm] = sid # ai.set_sid(sid) xc = float(data[1]) yc = float(data[2]) zc = float(data[3]) xi, yi, zi = cartesian_to_scaled(hi, xc, yc, zc) poss[iatm, :] = [xi, yi, zi] # print 'iatm,symbol,sid,xc,yc,zc = ',iatm,symbol,sid,xc,yc,zc else: continue iatm += 1 nsys.alc = 1.0 nsys.atoms[['x', 'y', 'z']] = poss nsys.atoms[['vx', 'vy', 'vz']] = vels nsys.atoms[['fx', 'fy', 'fz']] = frcs nsys.atoms['sid'] = sids f.close() return nsys
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 read_POSCAR(fname='POSCAR', specorder=None): nsys = NAPSystem() with open(fname, 'r') as f: # 1st line: comment f.readline() # 2nd: lattice constant nsys.alc = float(f.readline().split()[0]) # 3rd-5th: cell vectors nsys.a1 = np.array([float(x) for x in f.readline().split()]) nsys.a2 = np.array([float(x) for x in f.readline().split()]) nsys.a3 = np.array([float(x) for x in f.readline().split()]) # 6th: species names or number of each species buff = f.readline().split() if not buff[0].isdigit(): spcs = copy.deepcopy(buff) buff = f.readline().split() if specorder is None: nsys.specorder = spcs else: nsys.specorder = specorder for s in spcs: if s not in nsys.specorder: nsys.specorder.append(s) num_species = np.array([int(n) for n in buff]) try: spcs except NameError: spcs = nsys.specorder #...Check number of species in POSCAR file and in specorder if len(num_species) > len(nsys.specorder): msg = ''' ers of species in POSCAR is greater than the one in specorder, which should be the same or less. er of species in POSCAR = {0:d} need to specify the species order correctly with --specorder option. '''.format(len(num_species)) raise ValueError(msg) natm = np.sum(num_species) 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)) #print("Number of atoms = {0:5d}".format(natm)) # 7th or 8th line: comment c7 = f.readline() if c7[0] in ('s', 'S'): c7 = f.readline() if c7[0] in ('c', 'C'): # positions are in Cartesian coordinate hi = nsys.get_hmat_inv() coord = 'cartesian' else: # such as "Direct" coord = 'scaled' #...Atom positions for i in range(natm): buff = f.readline().split() sid = 1 m = 0 sindex = 0 for n in num_species: m += n if i < m: if spcs and nsys.specorder: sid = nsys.specorder.index(spcs[sindex]) + 1 break sid += 1 sindex += 1 sids[i] = sid pos = [float(buff[0]), float(buff[1]), float(buff[2])] if coord == 'cartesian': x1, x2, x3 = cartesian_to_scaled(hi, pos[0], pos[1], pos[2]) elif coord == 'scaled': x1, x2, x3 = pos[0], pos[1], pos[2] poss[i, :] = [x1, x2, x3] nsys.atoms[['x', 'y', 'z']] = poss nsys.atoms[['vx', 'vy', 'vz']] = vels nsys.atoms[['fx', 'fy', 'fz']] = frcs nsys.atoms['sid'] = sids return nsys