def getSlipLength(bgf_file, trj_file, ff_file, interval, n_step, n_avg_step, silent=False): """ This calculates the profile of averaged velocity according to r. NOTE: This is different from averaged velocity profile according to r. """ # const PI = math.pi vdw_r_C = 1.7 # init timestep = 0 l_timestep = [] line = [] n_header = 0 output = "" t1 = 0 t2 = 0 # clock myBGF = bgf.BgfFile(bgf_file) myTRJ = open(trj_file) myTRJ.seek(0) myPkl = open( trj_file + ".profile.r_ave_vel-s" + str(n_step) + "k" + str(n_skip) + ".pickle", 'w') #f_dump = open(trj_file + ".profile.r_ave_vel.dump", 'w') #dump = ""; # how many steps to go? n_timestep = len(lt.getTrjInfo(trj_file, silent=False)) if n_step == 0: n_step = n_timestep if not silent: print("The trajectory contains " + str(n_timestep) + " timesteps.") # extract aNos of CNT in the BGF file aNo_CNT = [] aNo_WAT_O = [] aNo_WAT_all = [] for atom in myBGF.a: # Carbons in CNT if "CNT" in atom.rName: aNo_CNT.append(atom.aNo) # Oxygen in water if "WAT" in atom.rName and "O" in atom.aName: aNo_WAT_O.append(atom.aNo) N_CNT = len(aNo_CNT) # the number of CNT atoms # check if there exists water properly if len(aNo_WAT_O) == 0: nu.die("No water molecules in the BGF file.") if len(aNo_CNT) == 0: nu.die("No CNT molecules in the BGF file.") # Find header of the trajectory file while 1: templine = myTRJ.readline() line.append(templine.strip('\n').strip('ITEM: ')) n_header += 1 if "ITEM: ATOMS" in templine: break # INITIAL trajectory information timestep = int(line[1]) natoms = int(line[3]) boxsize = [ line[5].split(' ')[0], line[5].split(' ')[1], line[6].split(' ')[0], line[6].split(' ')[1], line[7].split(' ')[0], line[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] keywords = line[8].strip('ATOMS ') # for every shot in the trajectory file update BGF and manipulate dumpatom = get_line(trj_file) processed_step = 0 t1 = t2 = 0 elapsed_time = 0 # calculate radius_CNT avg_radius_CNT = 0.0 x_CNT = 0.0 y_CNT = 0.0 if not silent: print( "Calculating the average radius of CNT throughout the averaging steps" ) while 1: ### Show progress t1 = time.time() remaining_time = elapsed_time * (n_step - processed_step) ### Read try: chunk = [next(dumpatom) for i in range(natoms + n_header)] except StopIteration: break # skip if necessary if processed_step <= n_skip: processed_step += 1 continue timestep = int(chunk[1]) l_timestep.append(timestep) natoms = int(chunk[3]) boxsize = [ chunk[5].split(' ')[0], chunk[5].split(' ')[1], chunk[6].split(' ')[0], chunk[6].split(' ')[1], chunk[7].split(' ')[0], chunk[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])] keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ') sys.stdout.write('\r' + "Fetched timestep: " + str(timestep) + " (Remaining time: " + "{0:4.1f}".format(remaining_time) + " seconds, " + "{0:4.1f} minutes".format(remaining_time / 60) + ")") sys.stdout.flush() ### update myBGF with trajectory information ### natom_bgf = len(myBGF.a) # number of atoms in BGF file mode = 'unwrapped' # assume that "dump 1 all custom 100 ${sname}${rtemp}K.nvt.lammps id type xu yu zu vx vy vz" in lammps input # actual coordinate coordinfo = chunk[9:] # modified for fast treatment for atomline in coordinfo: atomcoord = atomline.split(' ') atom = myBGF.getAtom(int(atomcoord[0])) atom.x = float(atomcoord[2]) atom.y = float(atomcoord[3]) atom.z = float(atomcoord[4]) try: for i in range(0, 3): myBGF.CRYSTX[i] = boxsize[i] except: pass # apply periodic condition #myBGF = bgftools.periodicMoleculeSort(myBGF, 0, True) ### myBGF update complete! ### # for CNT atoms, calculate some properties min_x_CNT = 0.0 max_x_CNT = 0.0 radius_CNT = 0.0 height_CNT = 0.0 aNo_WAT_O_not_in_CNT = [] temp = [] min_y_CNT = 0.0 max_y_CNT = 0.0 min_z_CNT = 0.0 max_z_CNT = 0.0 CNT_orientation = "" l_radius_CNT = [] l_x_CNT = [] l_y_CNT = [] for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) # center of CNT l_x_CNT.append(atom.x) l_y_CNT.append(atom.y) # height if atom.z < min_z_CNT: min_z_CNT = atom.z if atom.z > max_z_CNT: max_z_CNT = atom.z x_CNT, a = nu.meanstdv(l_x_CNT) y_CNT, a = nu.meanstdv(l_y_CNT) z_diff = max_z_CNT - min_z_CNT # radius of CNT for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) l_radius_CNT.append( math.sqrt((atom.x - x_CNT)**2 + (atom.y - y_CNT)**2)) radius_CNT, a = nu.meanstdv(l_radius_CNT) l_avg_radius_CNT.append(radius_CNT) if processed_step > 3: break avg_radius_CNT, s = nu.meanstdv(l_avg_radius_CNT) bins = np.arange(0.0, math.ceil(radius_CNT), interval) l_radial_vz_profile = np.zeros(len(bins) - 1) if not silent: print("\nAveraged CNT radius: " + str(avg_radius_CNT) + " A") if not silent: print("CNT center: " + str([x_CNT, y_CNT])) # calculate properties myTRJ.close() myTRJ = open(trj_file) myTRJ.seek(0) dumpatom = get_line(trj_file) processed_step = 0 r = [] vz = [] # data container while 1: data = dict() # stores [r vz] for a timestep ### Show progress t1 = time.time() remaining_time = elapsed_time * (n_step - processed_step) ### Read try: chunk = [next(dumpatom) for i in range(natoms + n_header)] except StopIteration: break if processed_step <= n_skip: processed_step += 1 continue timestep = int(chunk[1]) l_timestep.append(timestep) natoms = int(chunk[3]) boxsize = [ chunk[5].split(' ')[0], chunk[5].split(' ')[1], chunk[6].split(' ')[0], chunk[6].split(' ')[1], chunk[7].split(' ')[0], chunk[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])] keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ') sys.stdout.write('\r' + "Fetched timestep: " + str(timestep) + " (Remaining time: " + "{0:4.1f}".format(remaining_time) + " seconds, " + "{0:4.1f} minutes".format(remaining_time / 60) + ")") sys.stdout.flush() ### update myBGF with trajectory information ### natom_bgf = len(myBGF.a) # number of atoms in BGF file if not natom_bgf == natoms: nu.die( "Number of atoms in trajectory file does not match with BGF file." ) mode = 'unwrapped' # assume that "dump 1 all custom 100 ${sname}${rtemp}K.nvt.lammps id type xu yu zu vx vy vz" in lammps input # actual coordinate coordinfo = chunk[9:] # modified for fast treatment for atomline in coordinfo: atomcoord = atomline.split(' ') atom = myBGF.getAtom(int(atomcoord[0])) atom.x = float(atomcoord[2]) atom.y = float(atomcoord[3]) atom.z = float(atomcoord[4]) atom.vx = float(atomcoord[5]) atom.vy = float(atomcoord[6]) atom.vz = float(atomcoord[7]) try: for i in range(0, 3): myBGF.CRYSTX[i] = boxsize[i] except: pass #nu.warn("Crystal information error: is this file not periodic?") # apply periodic condition myBGF = bgftools.periodicMoleculeSort(myBGF, 0, True) ### myBGF update complete! ### # calculate z-directional velocity of water molecules wrt r vcm = sum vi mi / sum mi atom = myBGF.getAtom(aNo_WAT_O[0]) mass_O = bgftools.getMass(myBGF, [aNo_WAT_O[0]], ff_file) atom = myBGF.getAtom(atom.CONECT[0]) mass_H = bgftools.getMass(myBGF, [atom.aNo], ff_file) mass_H2O = mass_O + 2 * mass_H # H2O mass for ano in aNo_WAT_O: atom = myBGF.getAtom(ano) # oxygen # com & velocity calculation cmx = atom.x * mass_O cmy = atom.y * mass_O vcmz = atom.vz * mass_O for ano2 in atom.CONECT: atom2 = myBGF.getAtom(ano2) cmx += atom2.x * mass_H cmy += atom2.y * mass_H vcmz += atom2.vz * mass_H cmx /= mass_H2O cmy /= mass_H2O vcmz /= mass_H2O dist = math.sqrt((x_CNT - cmx)**2 + (y_CNT - cmy)**2) r.append(dist) vz.append(vcmz * 10**5) # LAMMPS real unit conversion for velocity # timestep mark for starting average if l_avg_count == []: n_avg_count_step = timestep l_avg_count.append(timestep) # if the time has come.. average! if len(l_avg_count) == n_avg_step or processed_step == n_timestep - 1: if not silent: print(" Averaging invoked at timestep " + str(timestep) + " (" + str(len(l_avg_count)) + " points)") # binning vz = np.array(vz) sum_vz = np.ma.array(np.histogram(r, bins, weights=vz)[0]) sum_vz2 = np.ma.array(np.histogram(r, bins, weights=vz * vz)[0]) n_vz = np.ma.array(np.histogram(r, bins)[0]) #mask_n = ma.masked_values(n_vz, 0) mean = sum_vz / n_vz std = np.sqrt(sum_vz2 / n_vz - mean * mean) mean = np.ma.fix_invalid(mean, fill_value=0.0).data std = np.ma.fix_invalid(std, fill_value=0.0).data n_vz = np.ma.fix_invalid(n_vz, fill_value=0).data if len(mean) != len(bins) - 1 or len(std) != len(bins) - 1: nu.die("on numpy masked_array calculation!") l_result.append([l_avg_count, bins, n_vz, mean, std]) # reset r = [] vz = [] l_radial_vz_profile = np.zeros(len(bins) - 1) l_avg_count = [] t2 = time.time() # time mark elapsed_time = t2 - t1 processed_step += 1 #f_dump.write(dump) pkl.dump(l_result, myPkl) print('') return 1
def countWater(bgf_file, trj_file, n_step, watercopy, ff_file, silent=False): ### const PI = math.pi vdw_r_C = 1.7 ### init timestep = 0 l_timestep = [] line = [] n_header = 0 t1 = 0 t2 = 0 # clock myBGF = bgf.BgfFile(bgf_file) myTRJ = open(trj_file) myTRJ.seek(0) global out_file if out_file == "": out_file = "countWater5.profile" print("The result will be recorded to the file " + out_file + " ...") ftemp = open(out_file, 'w') ftemp.write(str(sys.argv) + "\n") ftemp.write("t" + '\t' + "n_O" + '\t' + "r_CNT" + '\t' + "std_r" + '\t' + "min_x" + '\t' + "max_x" + '\t' + "min_y" + '\t' + "max_y" + '\t' + "min_z" + '\t' + "max_z" + '\t' + "l_NT" + '\t' + "replNum" + '\t' + "copyNum" + '\t' + "n_WAT" + '\t' + "remark" + '\n') curr_dir = os.path.abspath(".") temp_dir = curr_dir + "/countWAT5/" print(temp_dir) if not os.path.isdir(temp_dir): os.makedirs(temp_dir) ### how many steps to go? n_timestep = len(lt.getTrjInfo(trj_file)) if n_step == 0: n_step = n_timestep print(" ..The trajectory contains " + str(n_timestep) + " timesteps.") print("The script will proceed for the first " + str(n_step) + " timesteps.") ### read mass from ff_file atominfo = dict() try: parse = ff_file.split(" ") except: nu.die( "Error occurred when reading the force field file.. Check your " + str(ff_file)) else: if not silent: print("Found " + str(len(parse)) + " Cerius2 Force Fields.") for i in parse: FF = dreiding.loadFF(i) temp_atominfo = dreiding.loadAtomTypes(FF) atominfo.update(temp_atominfo) ### extract aNos of CNT in the BGF file aNo_CNT = [] aNo_WAT_O = [] aNo_WAT_all = [] mass_CNT = [] for atom in myBGF.a: # Carbons in CNT or atoms in BNNT if "NT" in atom.rName: aNo_CNT.append(atom.aNo) ffType = string.strip(atom.ffType) try: aMass = atominfo[ffType]['MASS'] except: nu.die("Cannot read the atom type " + str(atom.ffType) + " in the data file.") mass_CNT.append(aMass) # Oxygen in water if "WAT" in atom.rName and "O" in atom.aName: aNo_WAT_O.append(atom.aNo) N_CNT = len(aNo_CNT) # the number of CNT atoms ### check if there exists water properly if len(aNo_WAT_O) == 0: nu.die("No water molecules in the BGF file.") if len(aNo_CNT) == 0: nu.die("No CNT molecules in the BGF file.") ### Find header of the trajectory file while 1: templine = myTRJ.readline() line.append(templine.strip('\n').strip('ITEM: ')) n_header += 1 if "ITEM: ATOMS" in templine: break ### INITIAL trajectory information timestep = int(line[1]) natoms = int(line[3]) boxsize = [ line[5].split(' ')[0], line[5].split(' ')[1], line[6].split(' ')[0], line[6].split(' ')[1], line[7].split(' ')[0], line[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] keywords = line[8].strip('ATOMS ') # for every shot in the trajectory file update BGF and manipulate dumpatom = get_line(trj_file) processed_step = 0 t1 = t2 = 0 elapsed_time = 0 while 1: ### Show progress t1 = time.time() remaining_time = elapsed_time * (n_step - processed_step) sys.stdout.write('\r' + "Reading timestep.. " + str(timestep) + " (Remaining time: " + "{0:4.1f}".format(remaining_time) + " seconds, " + "{0:4.1f} minutes".format(remaining_time / 60) + ")") sys.stdout.flush() if processed_step == n_step: break ### Read myBGF = bgf.BgfFile(bgf_file) try: chunk = [next(dumpatom) for i in range(natoms + n_header)] except StopIteration: break timestep = int(chunk[1]) natoms = int(chunk[3]) boxsize = [ chunk[5].split(' ')[0], chunk[5].split(' ')[1], chunk[6].split(' ')[0], chunk[6].split(' ')[1], chunk[7].split(' ')[0], chunk[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])] keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ') mode = 'unwrapped' # assume that "dump 1 all custom 100 ${sname}${rtemp}K.nvt.lammps id type xu yu zu vx vy vz" in lammps input # actual coordinate coordinfo = chunk[9:] # load atom coordinates from chunk for atomline in coordinfo: atomcoord = atomline.split(' ') atom = myBGF.getAtom(int(atomcoord[0])) atom.x = float(atomcoord[2]) atom.y = float(atomcoord[3]) atom.z = float(atomcoord[4]) ### convert atom coordinates to lists CNT = [] WATER = [] for atom in myBGF.a: if "NT" in atom.rName: CNT.append([atom.x, atom.y, atom.z]) if "WAT" in atom.rName and "O" in atom.ffType: WATER.append([atom.x, atom.y, atom.z]) CNT = np.array(CNT) n_CNT = len(CNT) # CNT coordinates WATER = np.array(WATER) # Water coordinates WATERONLY = np.copy(WATER) boxsize = np.array(boxsize) ### initialize for the moment of inertia and the center of mass calculation U = 0 Ut = 0 Uv = 0 Ixx = 0 Ixy = 0 Ixz = 0 Iyx = 0 Iyy = 0 Iyz = 0 Izx = 0 Izy = 0 Izz = 0 Mx = 0 My = 0 Mz = 0 ### transpose "all atoms in BGF": move COM of CNT as origin Mx, My, Mz = np.average(CNT, axis=0, weights=mass_CNT) # CoM of CNT COM = np.array([[Mx, My, Mz]]) CNT = CNT - COM + boxsize / 2.0 # move WATER = WATER - COM + boxsize / 2.0 ### apply PBC WATER = np.mod(WATER, boxsize) ### save coordinates to BGF before rotation myBGF2 = bgf.BgfFile() for index, i in enumerate(CNT): newatom = bgf.BgfAtom() newatom.x, newatom.y, newatom.z = i newatom.aNo = index newatom.aName = 'C' + str(index) newatom.rName = 'CNT' newatom.ffType = 'C_' newatom.chain = 'A' newatom.rNo = 1 myBGF2.addAtom(newatom) for index, i in enumerate(WATER): newatom = bgf.BgfAtom() newatom.x, newatom.y, newatom.z = i newatom.aNo = index + n_CNT newatom.aName = 'O' newatom.rName = 'WAT' newatom.ffType = 'OW' newatom.chain = 'O' newatom.rNo = 100 myBGF2.addAtom(newatom) myBGF2.REMARK.append('TIMESTEP ' + str(timestep)) myBGF2.PERIOD = "111" myBGF2.AXES = "ZYX" myBGF2.SGNAME = "P 1 1 1" myBGF2.CELLS = [-1, 1, -1, 1, -1, 1] myBGF2.CRYSTX = [boxsize[0], boxsize[1], boxsize[2], 90.0, 90.0, 90.0] myBGF2.saveBGF(temp_dir + bgf_file.split(".bgf")[0] + "." + str(timestep) + ".bgf") ### move CM of CNT to origin CNT = CNT - boxsize / 2.0 WATER = WATER - boxsize / 2.0 ### how the CNT is lying across the periodic box? for atom in CNT: min_x_CNT, min_y_CNT, min_z_CNT = CNT.min(axis=0) max_x_CNT, max_y_CNT, max_z_CNT = CNT.max(axis=0) margin = 5.0 ### copy water molecules max_x_axis = int(round((max_x_CNT + margin) / boxsize[0])) min_x_axis = int(round((min_x_CNT - margin) / boxsize[0])) max_y_axis = int(round((max_y_CNT + margin) / boxsize[1])) min_y_axis = int(round((min_y_CNT - margin) / boxsize[1])) max_z_axis = int(round((max_z_CNT + margin) / boxsize[2])) min_z_axis = int(round((min_z_CNT - margin) / boxsize[2])) replNum = (min_x_axis, max_x_axis, min_y_axis, max_y_axis, min_z_axis, max_z_axis) copyNum = 0 remark = "" if watercopy: for x in range(min_x_axis, max_x_axis + 1): remark += "x: " if x != 0: WATER2 = np.copy(WATERONLY) dx = np.array([[boxsize[0] * x, 0, 0]]) WATER2 = WATER2 + dx WATER = np.concatenate((WATER, WATER2)) copyNum += 1 remark += str(x) + " " for y in range(min_y_axis, max_y_axis + 1): remark += "y: " if y != 0: WATER2 = np.copy(WATERONLY) dy = np.array([[0, boxsize[1] * y, 0]]) WATER2 = WATER2 + dy WATER = np.concatenate((WATER, WATER2)) copyNum += 1 remark += str(y) + " " for z in range(min_z_axis, max_z_axis + 1): remark += "z: " if z != 0: WATER2 = np.copy(WATERONLY) dz = np.array([[0, 0, boxsize[2] * z]]) WATER2 = WATER2 + dz WATER = np.concatenate((WATER, WATER2)) copyNum += 1 remark += str(z) + " " ''' ### WATER distribution check x_axis = np.linspace(WATER[:,0].min(), WATER[:,0].max(), 10) y_axis = np.linspace(WATER[:,1].min(), WATER[:,1].max(), 10) z_axis = np.linspace(WATER[:,2].min(), WATER[:,2].max(), 10) x_hist, _ = np.histogram(WATER[:,0], x_axis, normed=True) y_hist, _ = np.histogram(WATER[:,1], y_axis, normed=True) z_hist, _ = np.histogram(WATER[:,2], z_axis, normed=True) remark += " xdist: " for i in x_hist: remark += "{0:6.3f}".format(i) remark += " ydist: " for i in y_hist: remark += "{0:6.3f}".format(i) remark += " zdist: " for i in z_hist: remark += "{0:6.3f}".format(i) ''' ### MI of CNT calculation for atom in CNT: Ixx += (atom[1]**2 + atom[2]**2) / N_CNT Iyy += (atom[0]**2 + atom[2]**2) / N_CNT Izz += (atom[0]**2 + atom[1]**2) / N_CNT Ixy -= (atom[0] * atom[1]) / N_CNT Ixz -= (atom[0] * atom[2]) / N_CNT Iyz -= (atom[1] * atom[2]) / N_CNT I = np.array([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]]) # the moment of inertia tensor eigval, eigvec = np.linalg.eig( I) # eigval[0] is the minimum among the values. U = np.matrix(eigvec) Ut = U.T ### box rotation for atom in CNT: v = np.matrix([atom[0], atom[1], atom[2]]).T Uv = Ut * v atom[0] = float(Uv[2]) atom[1] = float(Uv[1]) atom[2] = float(Uv[0]) # CNT rotation for atom in WATER: v = np.matrix([atom[0], atom[1], atom[2]]).T Uv = Ut * v atom[0] = float(Uv[2]) atom[1] = float(Uv[1]) atom[2] = float(Uv[0]) # water rotation ### save coordinates to BGF after rotation myBGF2 = bgf.BgfFile() for index, i in enumerate(CNT): newatom = bgf.BgfAtom() newatom.x, newatom.y, newatom.z = i newatom.aNo = index newatom.aName = 'C' + str(index) newatom.rName = 'CNT' newatom.ffType = 'C_' newatom.chain = 'A' newatom.rNo = 1 myBGF2.addAtom(newatom) for index, i in enumerate(WATER): newatom = bgf.BgfAtom() newatom.x, newatom.y, newatom.z = i newatom.aNo = index + n_CNT newatom.aName = 'O' newatom.rName = 'WAT' newatom.ffType = 'OW' newatom.chain = 'O' newatom.rNo = 100 myBGF2.addAtom(newatom) myBGF2.REMARK.append('TIMESTEP ' + str(timestep)) myBGF2.PERIOD = "111" myBGF2.AXES = "ZYX" myBGF2.SGNAME = "P 1 1 1" myBGF2.CELLS = [-1, 1, -1, 1, -1, 1] myBGF2.CRYSTX = [boxsize[0], boxsize[1], boxsize[2], 90.0, 90.0, 90.0] myBGF2.saveBGF(temp_dir + bgf_file.split(".bgf")[0] + "." + str(timestep) + ".rot.bgf") ### CNT height _, _, min_z_CNT = CNT.min(axis=0) _, _, max_z_CNT = CNT.max(axis=0) height_CNT = max_z_CNT - min_z_CNT ### CNT radius x_CNT, y_CNT, z_CNT = np.mean(CNT, axis=0) x_std_CNT, y_std_CNT, z_std_CNT = np.std(CNT, axis=0) if x_std_CNT > 1.0 or y_std_CNT > 1.0: remark += "" ### radius of CNT l_r_CNT = [] for atom in CNT: l_r_CNT.append( math.sqrt((atom[0] - x_CNT)**2 + (atom[1] - y_CNT)**2)) r_CNT = np.mean(l_r_CNT) std_r_CNT = np.std(l_r_CNT) ### get water molecules in CNT # inside the CNT := min_z_CNT <= z <= max_z_CNT and (x - (x_diff/2))**2 + (y - (y_diff/2))**2 < r_CNT**2 # aNo_WAT_O_atoms: molecules which O atom is within CNT # we don't need to calculate H atoms. Let's consider only O atoms ##### margin = 0.0 # water molecules far from the margin will be only considered WAT_in_CNT = [] for atom in WATER: dist_sq = (atom[0] - x_CNT)**2 + (atom[1] - y_CNT)**2 if min_z_CNT + margin <= atom[2] and atom[ 2] <= max_z_CNT - margin and dist_sq < r_CNT**2: WAT_in_CNT.append(atom) n_WAT_in_CNT = len(WAT_in_CNT) ''' ### WATER bad contact check: copy-failure-proof: NEED CORRECTION WAT1 = []; WAT2 = []; for index1, i in enumerate(WAT_in_CNT): for j in WATER[index1:]: WAT1.append(i); WAT2.append(j); WAT1 = np.array(WAT1); WAT2 = np.array(WAT2) min_dists = np.min(np.dstack(((WAT1 - WAT2) % boxsize, (WAT2 - WAT1) % boxsize)), axis = 2) dists = np.sqrt(np.sum(min_dists ** 2, axis = 1)) for d in dists: if d > 0 and d < 1.0: remark += "Bad contacts" + str(d) continue; ''' d = "{0:8.3f}" e = "{0:6.1f}" output = "{0:<10}".format(timestep) + str( n_WAT_in_CNT ) + ' | ' + d.format(r_CNT) + d.format(std_r_CNT) + ' | ' + e.format( boxsize[0] ) + e.format(boxsize[1]) + e.format(boxsize[2]) + ' | ' + e.format( min_x_CNT) + e.format(max_x_CNT) + e.format(min_y_CNT) + e.format( max_y_CNT) + e.format(min_z_CNT) + e.format( max_z_CNT) + ' | ' + e.format(height_CNT) + ' | ' + str( replNum) + '\t' + str(copyNum) + '\t' + str( len(WATER)) + '\t' + str(remark) + '\n' ftemp.write(output) sys.stdout.flush() t2 = time.time() # time mark elapsed_time = t2 - t1 processed_step += 1 print('') ftemp.close() print("Numbers of water molecules are written in " + out_file + " ..Done.") return 1
def getBestShot(bgf_file, dat_file, trj_file, log_file, ff_file, keyword, saveBgfFlag, n_sample, silent=False): ### init timestep = 0 l_timestep = [] line = [] n_header = 0 yes_velocity = False yes_image = False mode = "" t1 = 0 t2 = 0 # clock myBGF = bgf.BgfFile(bgf_file) myTRJ = open(trj_file) myTRJ.seek(0) ### LAMMPS Trajectory # how many steps to go? if not silent: print("** Loading LAMMPS Trajectory **\n") if not os.path.exists(trj_file): nu.die("Please check the LAMMPS trajectory file.") l_timestep = lt.getTrjInfo(trj_file) n_timestep = len(l_timestep) if not silent: print("\nThe trajectory contains " + str(n_timestep) + " timesteps.") # Find header of the trajectory file while 1: templine = myTRJ.readline() line.append(templine.strip('\n').strip('ITEM: ')) n_header += 1 if "ITEM: ATOMS" in templine: break # INITIAL trajectory information timestep = int(line[1]) natoms = int(line[3]) boxsize = [ line[5].split(' ')[0], line[5].split(' ')[1], line[6].split(' ')[0], line[6].split(' ')[1], line[7].split(' ')[0], line[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] keywords = line[8].strip('ATOMS ') # Find modes if 'vx' in keywords: if not silent: print("Found velocities information from the trajectory.") yes_velocity = True if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords: mode = 'scaled' elif 'x' in keywords or 'y' in keywords or 'z' in keywords: mode = 'normal' elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords: mode = 'unwrapped' if 'ix' in keywords or 'iy' in keywords or 'iz' in keywords: yes_image = True # scan trajectory to get timesteps dumpatom = get_line(trj_file) # get working path workingpath = os.getcwd() if not silent: print( '\n** Analyzing LAMMPS Log to find the timestep closest to the average "' + keyword + '" **\n') # read keywords from log file logdata = LAMMPS_getLogData.getLogData(log_file, "", keyword, silent=False) logdata2 = [] for i in logdata: if i[0] in l_timestep: logdata2.append(i) logdata2.sort(key=sortkey) # truncate if not silent: print("Only the last " + str(n_sample) + " snapshots will be used to calculate the average.") logdata2 = logdata2[-n_sample:] # average temp_avg = 0 for i in logdata2: temp_avg += float(i[1]) temp_avg /= len(logdata2) # deviation dev = [] for i in logdata2: dev.append([i[0], abs(float(i[1]) - temp_avg)]) dev.sort(key=sortkeymin) if not silent: print("Found the timestep " + str(dev[0][0]) + " has the value closest to the average " + keyword + " (value: " + str(temp_avg) + ", deviation: " + str(dev[0][1]) + ")") ### REMARK: dev[0] has the smallest deviation from the average # get trajectory myTRJ.seek(0) dumpatom = get_line(trj_file) while 1: try: chunk = [next(dumpatom) for i in range(natoms + n_header)] except StopIteration: break # only treat the designated timestep timestep = int(chunk[1]) if timestep != int(dev[0][0]): continue natoms = int(chunk[3]) boxsize = [ chunk[5].split(' ')[0], chunk[5].split(' ')[1], chunk[6].split(' ')[0], chunk[6].split(' ')[1], chunk[7].split(' ')[0], chunk[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])] keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ') ### update myBGF with trajectory information ### natom_bgf = len(myBGF.a) # number of atoms in BGF file if not natom_bgf == natoms: nu.die( "Number of atoms in trajectory file does not match with BGF file." ) # actual coordinate coordinfo = chunk[9:] info = hash() # assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz'] for atomline in coordinfo: atomcoord = atomline.split(' ') atomNo = int(atomcoord[0]) if mode == 'scaled': info[atomNo]['x'] = float(atomcoord[2]) * boxsize[0] info[atomNo]['y'] = float(atomcoord[3]) * boxsize[1] info[atomNo]['z'] = float(atomcoord[4]) * boxsize[2] elif mode == 'unwrapped': info[atomNo]['x'] = float(atomcoord[2]) info[atomNo]['y'] = float(atomcoord[3]) info[atomNo]['z'] = float(atomcoord[4]) elif mode == 'normal': # images if yes_image: ix_index = keywords.index('ix') iy_index = keywords.index('iy') iz_index = keywords.index('iz') info[atomNo]['x'] = (int(atomcoord[ix_index]) * boxsize[0]) + float(atomcoord[2]) info[atomNo]['y'] = (int(atomcoord[iy_index]) * boxsize[1]) + float(atomcoord[3]) info[atomNo]['z'] = (int(atomcoord[iz_index]) * boxsize[2]) + float(atomcoord[4]) else: info[atomNo]['x'] = float(atomcoord[2]) info[atomNo]['y'] = float(atomcoord[3]) info[atomNo]['z'] = float(atomcoord[4]) # velocities if yes_velocity: vx_index = keywords.index('vx') vy_index = keywords.index('vy') vz_index = keywords.index('vz') info[atomNo]['vx'] = float(atomcoord[vx_index]) info[atomNo]['vy'] = float(atomcoord[vy_index]) info[atomNo]['vz'] = float(atomcoord[vz_index]) print("") if not silent: print("** New system size: %12.6f %12.6f %12.6f" % (boxsize[0], boxsize[1], boxsize[2])) for i in range(0, 3): myBGF.CRYSTX[i] = boxsize[i] if saveBgfFlag: myBGF.REMARK.append("From the " + str(timestep) + " of " + trj_file + " in " + workingpath + " and " + bgf_file + " by " + str(sys.argv[0])) myBGF.REMARK.append( "n_samples: %d / %s average: %8.3f / stdev of the snapshot: %8.3f" % (n_sample, keyword, temp_avg, dev[0][1])) new_bgf_filename = bgf_file[:-4] + "." + str(timestep) + ".bgf" for atom in myBGF.a: atom.x = info[atom.aNo]['x'] atom.y = info[atom.aNo]['y'] atom.z = info[atom.aNo]['z'] #myBGF = bgftools.periodicMoleculeSort(myBGF, 0, [], ff_file=ff_file, silent=True) # pbc wrap myBGF.saveBGF(new_bgf_filename) if not silent: print("The snapshot is saved in BGF file " + new_bgf_filename) if dat_file: ### LAMMPS Data dat_atoms = [] if not silent: print("** Loading LAMMPS Data **\n") if not os.path.exists(dat_file): nu.die("Please check the LAMMPS data file.") f_dat_file = open(dat_file) temp = f_dat_file.read().split('\n') dat_atom_start = temp.index('Atoms') dat_atom_end = temp.index('Bonds') dat_atoms = temp[dat_atom_start + 1:dat_atom_end] f_dat_file.close() ### update LAMMPS data file ### myDAT = open(dat_file) new_dat_filename = dat_file + "." + keyword + "." + str(timestep) myNewDAT = open(new_dat_filename, 'w') linecount = 0 while 1: line = myDAT.readline() if not line: break if linecount == 0: output = line.strip( "\n") + " and updated with timestep " + str( timestep) + " in " + trj_file + "\n" linecount += 1 myNewDAT.write(output) continue if "xlo " in line: output = "\t" + " {0:>10.6f} {1:>10.6f}".format( 0.0, boxsize[0]) + " xlo xhi\n" myNewDAT.write(output) continue elif "ylo " in line: output = "\t" + " {0:>10.6f} {1:>10.6f}".format( 0.0, boxsize[1]) + " ylo yhi\n" myNewDAT.write(output) continue elif "zlo " in line: output = "\t" + " {0:>10.6f} {1:>10.6f}".format( 0.0, boxsize[2]) + " zlo zhi\n" myNewDAT.write(output) continue if not "Atoms" in line: myNewDAT.write(line) else: myNewDAT.write("Atoms\n\n") for i in dat_atoms: if len(i) == 0: continue parse = i.split() atomNo = int(parse[0]) molNo = int(parse[1]) atomTypeNo = int(parse[2]) atom = myBGF.getAtom(atomNo) if atom.aNo != atomNo or atom.rNo != molNo: nu.die( "BGF and data file mismatch. Please check both files." ) else: output = "{0:>8} {1:>8} {2:>8} {3:10.5f} {4:10.5f} {5:10.5f} {6:10.5f} {7:10.5f} {8:10.5f} {9:10.5f}".format( atom.aNo, atom.rNo, atomTypeNo, atom.charge, atom.x, atom.y, atom.z, float(parse[7]), float(parse[8]), float(parse[9])) + "\n" myNewDAT.write(output) # Write velocities if yes_velocity: myNewDAT.write("\n\nVelocities\n\n") for i in dat_atoms: if len(i) == 0: continue parse = i.split() atomNo = int(parse[0]) output = "{0:>8} {1:12.8f} {2:12.8f} {3:12.8f}\n".format( atomNo, info[atomNo]['vx'], info[atomNo]['vy'], info[atomNo]['vz']) myNewDAT.write(output) # consume for i in range(len(dat_atoms)): line = myDAT.readline() myNewDAT.write("\n") if not silent: print("The snapshot is saved in LAMMPS data file " + new_dat_filename) print('') return 1
def getVelocity(bgf_file, trj_file, n_step, silent=False): # const PI = math.pi vdw_r_C = 1.7 # init timestep = 0 l_timestep = [] line = [] n_header = 0 t1 = 0 t2 = 0 # clock l_data = [] # stores vz l_avg_radius_CNT = [] myBGF = bgf.BgfFile(bgf_file) myTRJ = open(trj_file) myTRJ.seek(0) # how many steps to go? n_timestep = len(lt.getTrjInfo(trj_file)) if n_step == 0: n_step = n_timestep print("The trajectory contains " + str(n_timestep) + " timesteps.") print("The script will proceed for the last " + str(n_step) + " timesteps.") # extract aNos of CNT in the BGF file aNo_CNT = [] aNo_WAT_O = [] aNo_WAT_all = [] for atom in myBGF.a: # Carbons in CNT if "CNT" in atom.rName: aNo_CNT.append(atom.aNo) # Oxygen in water if "WAT" in atom.rName and "O" in atom.aName: aNo_WAT_O.append(atom.aNo) N_CNT = len(aNo_CNT) # the number of CNT atoms # check if there exists water properly if len(aNo_WAT_O) == 0: nu.die("No water molecules in the BGF file.") if len(aNo_CNT) == 0: nu.die("No CNT molecules in the BGF file.") # Find header of the trajectory file while 1: templine = myTRJ.readline() line.append(templine.strip('\n').strip('ITEM: ')) n_header += 1 if "ITEM: ATOMS" in templine: break # INITIAL trajectory information timestep = int(line[1]) natoms = int(line[3]) boxsize = [ line[5].split(' ')[0], line[5].split(' ')[1], line[6].split(' ')[0], line[6].split(' ')[1], line[7].split(' ')[0], line[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] keywords = line[8].strip('ATOMS ') # for every shot in the trajectory file update BGF and manipulate dumpatom = get_line(trj_file) processed_step = 0 t1 = t2 = 0 elapsed_time = 0 while 1: ### Show progress t1 = time.time() remaining_time = elapsed_time * (n_step - processed_step) sys.stdout.write('\r' + "Reading timestep.. " + str(timestep) + " (Remaining time: " + "{0:4.1f}".format(remaining_time) + " seconds, " + "{0:4.1f} minutes".format(remaining_time / 60) + ")") sys.stdout.flush() if processed_step == n_step: break ### Read try: chunk = [next(dumpatom) for i in range(natoms + n_header)] except StopIteration: break timestep = int(chunk[1]) natoms = int(chunk[3]) boxsize = [ chunk[5].split(' ')[0], chunk[5].split(' ')[1], chunk[6].split(' ')[0], chunk[6].split(' ')[1], chunk[7].split(' ')[0], chunk[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])] keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ') ### update myBGF with trajectory information ### natom_bgf = len(myBGF.a) # number of atoms in BGF file if not natom_bgf == natoms: nu.die( "Number of atoms in trajectory file does not match with BGF file." ) mode = 'unwrapped' # assume that "dump 1 all custom 100 ${sname}${rtemp}K.nvt.lammps id type xu yu zu vx vy vz" in lammps input # actual coordinate coordinfo = chunk[9:] del (chunk) # modified for fast treatment for atomline in coordinfo: atomcoord = atomline.split(' ') atom = myBGF.getAtom(int(atomcoord[0])) atom.x = float(atomcoord[2]) atom.y = float(atomcoord[3]) atom.z = float(atomcoord[4]) atom.vx = float(atomcoord[5]) atom.vy = float(atomcoord[6]) atom.vz = float(atomcoord[7]) try: for i in range(0, 3): myBGF.CRYSTX[i] = boxsize[i] except: pass #nu.warn("Crystal information error: is this file not periodic?") # apply periodic condition myBGF = bgftools.periodicMoleculeSort(myBGF, 0, True) ### myBGF update complete! ### #aNo_WAT_O_in_CNT = copy.deepcopy(aNo_WAT_O) # for CNT atoms, calculate some properties min_x_CNT = 1000.0 max_x_CNT = -1000.0 radius_CNT = 0.0 height_CNT = 0.0 temp = [] min_y_CNT = 1000.0 max_y_CNT = -1000.0 min_z_CNT = 1000.0 max_z_CNT = -1000.0 CNT_orientation = "" l_radius_CNT = [] l_x_CNT = [] l_y_CNT = [] for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) # center of CNT l_x_CNT.append(atom.x) l_y_CNT.append(atom.y) # height if atom.z < min_z_CNT: min_z_CNT = atom.z if atom.z > max_z_CNT: max_z_CNT = atom.z x_CNT, a = nu.meanstdv(l_x_CNT) y_CNT, a = nu.meanstdv(l_y_CNT) z_diff = max_z_CNT - min_z_CNT # radius of CNT for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) l_radius_CNT.append( math.sqrt((atom.x - x_CNT)**2 + (atom.y - y_CNT)**2)) radius_CNT, a = nu.meanstdv(l_radius_CNT) l_avg_radius_CNT.append(radius_CNT) ### get water molecules in CNT # inside the CNT := min_z_CNT <= z <= max_z_CNT and (x - (x_diff/2))**2 + (y - (y_diff/2))**2 < radius_CNT**2 # aNo_WAT_O_atoms: molecules which O atom is within CNT # we don't need to calculate H atoms. Let's consider only O atoms margin = 0.0 # water molecules far from the margin will be only considered aNo_WAT_O_in_CNT = [] for aNo in aNo_WAT_O: atom = myBGF.getAtom(aNo) dist_sq = (atom.x - x_CNT)**2 + (atom.y - y_CNT)**2 if "WAT" in atom.rName and "O" in atom.ffType and min_z_CNT + margin <= atom.z and atom.z <= max_z_CNT - margin and dist_sq < radius_CNT**2: aNo_WAT_O_in_CNT.append(aNo) else: pass ### record number of water molecules in CNT l_data.append([timestep, len(aNo_WAT_O_in_CNT), radius_CNT, z_diff]) #sys.stdout.write('Done ') #sys.stdout.flush() t2 = time.time() # time mark elapsed_time = t2 - t1 processed_step += 1 print('') ftemp = open("countWater.profile", 'w') ftemp.write(str(sys.argv)) for i in l_data: output = str(i[0]) + '\t' + str(i[1]) + '\t' + str(i[2]) + '\t' + str( i[3]) + '\n' ftemp.write(output) ftemp.close() print( "numbers of water molecules are written in countWater.profile ..Done.") return 1
def getVelocity(bgf_file, trj_file, n_step, silent=False): # const PI = math.pi vdw_r_C = 1.7 # init timestep = 0 l_timestep = [] line = [] n_header = 0 t1 = 0 t2 = 0 # clock l_data = [] # stores vz l_avg_radius_CNT = [] myBGF = bgf.BgfFile(bgf_file) myTRJ = open(trj_file) myTRJ.seek(0) ftemp = open("countWater42.profile", 'w') ftemp.write(str(sys.argv) + "\n") curr_dir = os.path.abspath(".") temp_dir = curr_dir + "/CountWAT42/" if not os.path.isdir(temp_dir): os.makedirs(temp_dir) # how many steps to go? n_timestep = len(lt.getTrjInfo(trj_file)) if n_step == 0: n_step = n_timestep print(" ..The trajectory contains " + str(n_timestep) + " timesteps.") print("The script will proceed for the last " + str(n_step) + " timesteps.") # extract aNos of CNT in the BGF file aNo_CNT = [] aNo_WAT_O = [] aNo_WAT_all = [] for atom in myBGF.a: # Carbons in CNT or atoms in BNNT if "NT" in atom.rName: aNo_CNT.append(atom.aNo) # Oxygen in water if "WAT" in atom.rName and "O" in atom.aName: aNo_WAT_O.append(atom.aNo) N_CNT = len(aNo_CNT) # the number of CNT atoms # check if there exists water properly if len(aNo_WAT_O) == 0: nu.die("No water molecules in the BGF file.") if len(aNo_CNT) == 0: nu.die("No CNT molecules in the BGF file.") # Find header of the trajectory file while 1: templine = myTRJ.readline() line.append(templine.strip('\n').strip('ITEM: ')) n_header += 1 if "ITEM: ATOMS" in templine: break # INITIAL trajectory information timestep = int(line[1]) natoms = int(line[3]) boxsize = [ line[5].split(' ')[0], line[5].split(' ')[1], line[6].split(' ')[0], line[6].split(' ')[1], line[7].split(' ')[0], line[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] keywords = line[8].strip('ATOMS ') # for every shot in the trajectory file update BGF and manipulate dumpatom = get_line(trj_file) processed_step = 0 t1 = t2 = 0 elapsed_time = 0 while 1: ### Show progress t1 = time.time() remaining_time = elapsed_time * (n_step - processed_step) sys.stdout.write('\r' + "Reading timestep.. " + str(timestep) + " (Remaining time: " + "{0:4.1f}".format(remaining_time) + " seconds, " + "{0:4.1f} minutes".format(remaining_time / 60) + ")") sys.stdout.flush() if processed_step == n_step: break ### Read try: chunk = [next(dumpatom) for i in range(natoms + n_header)] except StopIteration: break timestep = int(chunk[1]) natoms = int(chunk[3]) boxsize = [ chunk[5].split(' ')[0], chunk[5].split(' ')[1], chunk[6].split(' ')[0], chunk[6].split(' ')[1], chunk[7].split(' ')[0], chunk[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])] keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ') ### update myBGF with trajectory information ### natom_bgf = len(myBGF.a) # number of atoms in BGF file if not natom_bgf == natoms: nu.die( "Number of atoms in trajectory file does not match with BGF file." ) mode = 'unwrapped' # assume that "dump 1 all custom 100 ${sname}${rtemp}K.nvt.lammps id type xu yu zu vx vy vz" in lammps input # actual coordinate coordinfo = chunk[9:] # modified for fast treatment for atomline in coordinfo: atomcoord = atomline.split(' ') atom = myBGF.getAtom(int(atomcoord[0])) atom.x = float(atomcoord[2]) atom.y = float(atomcoord[3]) atom.z = float(atomcoord[4]) atom.vx = float(atomcoord[5]) atom.vy = float(atomcoord[6]) atom.vz = float(atomcoord[7]) if myBGF.CRYSTX != []: for i in range(0, 3): myBGF.CRYSTX[i] = boxsize[i] else: nu.warn("Crystal information error: is this file not periodic?") for i in range(0, 3): myBGF.CRYSTX.append(boxsize[i]) ### myBGF update complete! ### ### align CNT to z axis # initialize for the moment of inertia and the center of mass calculation U = 0 Ut = 0 Uv = 0 Ixx = 0 Ixy = 0 Ixz = 0 Iyx = 0 Iyy = 0 Iyz = 0 Izx = 0 Izy = 0 Izz = 0 Mx = 0 My = 0 Mz = 0 # set COM of CNT as origin Mx = 0 My = 0 Mz = 0 # Center of mass of CNT for atom in myBGF.a: if "NT" in atom.rName: Mx += atom.x / N_CNT My += atom.y / N_CNT Mz += atom.z / N_CNT for atom in myBGF.a: atom.x -= Mx # move atom.y -= My atom.z -= Mz # calculate the moment of inertia (MI) and the center of mass (COM) of CNT from "myBGF" for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) Ixx += (atom.y**2 + atom.z**2) / N_CNT Iyy += (atom.x**2 + atom.z**2) / N_CNT Izz += (atom.x**2 + atom.y**2) / N_CNT Ixy -= (atom.x * atom.y) / N_CNT Ixz -= (atom.x * atom.z) / N_CNT Iyz -= (atom.y * atom.z) / N_CNT # the moment of inertia tensor I = np.array([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]]) # eigenvalue & eigenvector calculation eigval, eigvec = np.linalg.eig( I) # eigval[0] is the minimum among the values. # rearrange the U vector U = np.matrix(eigvec) Ut = U.T # "myBGF" rotation for atom in myBGF.a: v = np.matrix([atom.x, atom.y, atom.z]).T Uv = Ut * v atom.x = float(Uv[2]) atom.y = float(Uv[1]) atom.z = float(Uv[0]) #dimension = np.matrix(boxsize).T #boxsize_prime = np.array(np.dot(Ut, dimension).T) boxsize_prime = np.transpose( np.dot(Ut, np.transpose(np.array(boxsize)))) # new pbc from jackjack5 print(boxsize) print(boxsize_prime) # move atoms to box center for atom in myBGF.a: atom.x -= boxsize_prime[0] / 2 atom.y -= boxsize_prime[1] / 2 atom.z -= boxsize_prime[2] / 2 myBGF.saveBGF(temp_dir + bgf_file.split(".bgf")[0] + "." + str(timestep) + ".beforepbc.bgf") myBGF = bgftools.periodicMoleculeSort(myBGF, 0, myBGF.CRYSTX) myBGF.saveBGF(temp_dir + bgf_file.split(".bgf")[0] + "." + str(timestep) + ".bgf") # for CNT atoms, calculate some properties min_x_CNT = 1000.0 max_x_CNT = -1000.0 radius_CNT = 0.0 height_CNT = 0.0 min_y_CNT = 1000.0 max_y_CNT = -1000.0 min_z_CNT = 1000.0 max_z_CNT = -1000.0 l_radius_CNT = [] l_x_CNT = [] l_y_CNT = [] for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) # center of CNT l_x_CNT.append(atom.x) l_y_CNT.append(atom.y) # height if atom.z < min_z_CNT: min_z_CNT = atom.z if atom.z > max_z_CNT: max_z_CNT = atom.z x_CNT, a = nu.meanstdv(l_x_CNT) y_CNT, a = nu.meanstdv(l_y_CNT) z_diff = max_z_CNT - min_z_CNT height_CNT = z_diff # radius of CNT for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) l_radius_CNT.append( math.sqrt((atom.x - x_CNT)**2 + (atom.y - y_CNT)**2)) radius_CNT, a = nu.meanstdv(l_radius_CNT) l_avg_radius_CNT.append(radius_CNT) ### get water molecules in CNT # inside the CNT := min_z_CNT <= z <= max_z_CNT and (x - (x_diff/2))**2 + (y - (y_diff/2))**2 < radius_CNT**2 # aNo_WAT_O_atoms: molecules which O atom is within CNT # we don't need to calculate H atoms. Let's consider only O atoms margin = 0.0 # water molecules far from the margin will be only considered aNo_WAT_O_in_CNT = [] for aNo in aNo_WAT_O: atom = myBGF.getAtom(aNo) dist_sq = (atom.x - x_CNT)**2 + (atom.y - y_CNT)**2 if "WAT" in atom.rName and "O" in atom.ffType and min_z_CNT + margin <= atom.z and atom.z <= max_z_CNT - margin and dist_sq < radius_CNT**2: aNo_WAT_O_in_CNT.append(aNo) else: pass ### record number of water molecules in CNT #l_data.append([timestep, len(aNo_WAT_O_in_CNT), radius_CNT, z_diff]) #output = str(timestep) + '\t' + str(len(aNo_WAT_O_in_CNT)) + '\t' + str(radius_CNT) + '\t' + str(z_diff) + '\n' output = str(timestep) + '\t' + str( len(aNo_WAT_O_in_CNT)) + '\t' + str(radius_CNT) + '\t' + str( min_z_CNT) + '\t' + str(max_z_CNT) + '\t' + str( z_diff) + '\t' + str(height_CNT) + '\t' + str( len(aNo_CNT)) + '\n' # debug ftemp.write(output) #sys.stdout.write('Done ') sys.stdout.flush() t2 = time.time() # time mark elapsed_time = t2 - t1 processed_step += 1 print('') ftemp.close() print( "numbers of water molecules are written in countWater.profile ..Done.") return 1
def countWater(bgf_file, trj_file, n_step, n_water, silent=False): ### const PI = math.pi vdw_r_C = 1.7 ### init timestep = 0 l_timestep = [] line = [] n_header = 0 t1 = 0 t2 = 0 # clock myBGF = bgf.BgfFile(bgf_file) myTRJ = open(trj_file) myTRJ.seek(0) global out_file if out_file == "": out_file = "waterPosition.profile" print("The result will be recorded to the file " + out_file + " ...") ftemp = open(out_file, 'w') ftemp.write(str(sys.argv) + "\n") ftemp.write(str(os.path.abspath('.') + "\n")) curr_dir = os.path.abspath(".") ### how many steps to go? n_timestep = len(lt.getTrjInfo(trj_file)) if n_step == 0: n_step = n_timestep print(" ..The trajectory contains " + str(n_timestep) + " timesteps.") print("The script will proceed for the first " + str(n_step) + " timesteps.") ### extract aNos of CNT in the BGF file aNo_CNT = [] aNo_WAT_O = [] for atom in myBGF.a: # Oxygen in water if "WAT" in atom.rName and "O" in atom.aName and "I" in atom.chain: aNo_WAT_O.append(atom.aNo) ### Draw O atoms to trace n_trace = n_water if len(aNo_WAT_O) < n_water: nu.die( 'Cannot draw %d molecules out of %d water molecules in the system!' % (n_water, len(aNo_WAT_O))) aNo_WAT_trace = random.sample(aNo_WAT_O, n_trace) # convert aNo as rNo _ = [] for i in aNo_WAT_trace: _.append(myBGF.getAtom(i).rNo) output = "resid " + ''.join("%d\t" % i for i in _) + '\n' ftemp.write(output) print(output) ### check if there exists water properly if len(aNo_WAT_O) == 0: nu.die("No water molecules in the BGF file.") ### Find header of the trajectory file while 1: templine = myTRJ.readline() line.append(templine.strip('\n').strip('ITEM: ')) n_header += 1 if "ITEM: ATOMS" in templine: break ### INITIAL trajectory information timestep = int(line[1]) natoms = int(line[3]) boxsize = [ line[5].split(' ')[0], line[5].split(' ')[1], line[6].split(' ')[0], line[6].split(' ')[1], line[7].split(' ')[0], line[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] keywords = line[8].strip('ATOMS ') # for every shot in the trajectory file update BGF and manipulate dumpatom = get_line(trj_file) processed_step = 0 t1 = t2 = 0 elapsed_time = 0 while 1: ### Show progress t1 = time.time() remaining_time = elapsed_time * (n_step - processed_step) sys.stdout.write('\r' + "Reading timestep.. " + str(timestep) + " (Remaining time: " + "{0:4.1f}".format(remaining_time) + " seconds, " + "{0:4.1f} minutes".format(remaining_time / 60) + ")") sys.stdout.flush() if processed_step == n_step: break ### Read coord = dict() try: chunk = [next(dumpatom) for i in range(natoms + n_header)] except StopIteration: break timestep = int(chunk[1]) natoms = int(chunk[3]) boxsize = [ chunk[5].split(' ')[0], chunk[5].split(' ')[1], chunk[6].split(' ')[0], chunk[6].split(' ')[1], chunk[7].split(' ')[0], chunk[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])] keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ') mode = 'unwrapped' # assume that "dump 1 all custom 100 ${sname}${rtemp}K.nvt.lammps id type xu yu zu vx vy vz" in lammps input # actual coordinate coordinfo = chunk[9:] # load atom coordinates from chunk for atomline in coordinfo: atomcoord = atomline.split(' ') coord[int(atomcoord[0])] = [ float(atomcoord[2]), float(atomcoord[3]), float(atomcoord[4]) ] ### convert atom coordinates to lists WATER = [] for atom in myBGF.a: if atom.aNo in aNo_WAT_trace: WATER.append(coord[atom.aNo][2]) WATER = np.array(WATER) # chosen water coordinates ### write output output = str(timestep) + "\t" + ''.join("%8.5f\t" % i for i in WATER) + '\n' ftemp.write(output) sys.stdout.flush() ### time t2 = time.time() # time mark elapsed_time = t2 - t1 processed_step += 1 print('') ftemp.close() print("Numbers of water molecules are written in " + out_file + " ..Done.") return 1
def myfunction(bgf_file, trj_file, n_step, out_file, silent=False): # const PI = math.pi vdw_r_C = 1.7 # init timestep = 0 l_timestep = [] line = [] n_header = 0 t1 = 0 t2 = 0 # clock # environments myBGF = bgf.BgfFile(bgf_file) # load BGF myTRJ = open(trj_file) # load LAMMPS trj myTRJ.seek(0) out_file = "myfunction.dat" f_out_file = open(out_file, 'w') # data will be recorded here f_out_file.write(str(sys.argv) + "\n") curr_dir = os.path.abspath(".") temp_dir = curr_dir + "/data/" if not os.path.isdir(temp_dir): os.makedirs(temp_dir) print("* Current directory: " + curr_dir) print("* Temp directory: " + temp_dir) # variables pass # scan LAMMPS trj to count how many shots in the file n_timestep = len(lt.getTrjInfo(trj_file)) if n_step == 0: n_step = n_timestep print(" ..The trajectory contains " + str(n_timestep) + " timesteps.") print("The script will proceed for the last " + str(n_step) + " timesteps.") # prepare something with BGF file for atom in myBGF.a: # do something pass ### Read trajectory file header while 1: templine = myTRJ.readline() line.append(templine.strip('\n').strip('ITEM: ')) n_header += 1 if "ITEM: ATOMS" in templine: break # initial trajectory information timestep = int(line[1]) natoms = int(line[3]) boxsize = [ line[5].split(' ')[0], line[5].split(' ')[1], line[6].split(' ')[0], line[6].split(' ')[1], line[7].split(' ')[0], line[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] keywords = line[8].strip('ATOMS ') # launch LAMMPS trj file dumpatom = get_line(trj_file) ### loop over trj and do the analysis processed_step = 0 # counter t1 = t2 = 0 elapsed_time = 0 # timer: calculate ETA while 1: # Show progress t1 = time.time() remaining_time = elapsed_time * (n_step - processed_step) sys.stdout.write('\r' + "Reading timestep.. " + str(timestep) + " (Remaining time: " + "{0:4.1f}".format(remaining_time) + " seconds, " + "{0:4.1f} minutes".format(remaining_time / 60) + ")") sys.stdout.flush() # stop analysis if requested n_step reached if processed_step == n_step: break # Read a shot from the trj file try: chunk = [next(dumpatom) for i in range(natoms + n_header)] except StopIteration: break timestep = int(chunk[1]) natoms = int(chunk[3]) boxsize = [ chunk[5].split(' ')[0], chunk[5].split(' ')[1], chunk[6].split(' ')[0], chunk[6].split(' ')[1], chunk[7].split(' ')[0], chunk[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])] keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ') ### update myBGF with trajectory information ### natom_bgf = len(myBGF.a) # number of atoms in BGF file if not natom_bgf == natoms: nu.die( "Number of atoms in trajectory file does not match with BGF file." ) mode = 'unwrapped' # assume that "dump 1 all custom 100 ${sname}${rtemp}K.nvt.lammps id type xu yu zu vx vy vz" in lammps input # actual coordinate coordinfo = chunk[9:] # modified for fast treatment for atomline in coordinfo: atomcoord = atomline.split(' ') atom = myBGF.getAtom(int(atomcoord[0])) atom.x = float(atomcoord[2]) atom.y = float(atomcoord[3]) atom.z = float(atomcoord[4]) atom.vx = float(atomcoord[5]) atom.vy = float(atomcoord[6]) atom.vz = float(atomcoord[7]) if myBGF.CRYSTX != []: for i in range(0, 3): myBGF.CRYSTX[i] = boxsize[i] else: nu.warn("Crystal information error: is this file not periodic?") for i in range(0, 3): myBGF.CRYSTX.append(boxsize[i]) # pbc wrap if required myBGF = bgftools.periodicMoleculeSort(myBGF, 0, myBGF.CRYSTX) ### do some analysis """ asdflkjhasdlkfjadslkfjasdlkvjbaldskjfha;lsiefhja;lsejkfblnkdsjvb """ ### record data output = str(timestep) + '\t' + str(123) + '\n' f_out_file.write(output) ### update timer sys.stdout.flush() t2 = time.time() # time mark elapsed_time = t2 - t1 processed_step += 1 print('') f_out_file.close() print("numbers of water molecules are written in " + out_file + " ..Done.") return 1
def densityProfile(bgf_file, trj_file, ff_file, out_file, direction, cnt_direction, interval, avg_timestep, silent=False): nu.warn( "LAMMPS trajectory with NPT simulations will give you the wrong result." ) ### init timestep = 0 l_timestep = [] line = [] n_header = 0 t1 = 0 t2 = 0 # clock vector = [0, 0, 1] # the axis of interest. in the acetone-water case, z direction. atominfo = dict() # atom data extracted from ff_file result = dict() axis = 0 # 1: x-axis, 2: y-axis, 3: z-axis ### direction if "x" in direction: axis = 0 elif "y" in direction: axis = 1 elif "z" in direction: axis = 2 else: nu.die("Error on reading direction.") ### CNT direction if "x" in cnt_direction: cnt_direction = 0 elif "y" in cnt_direction: cnt_direction = 1 elif "z" in cnt_direction: cnt_direction = 2 else: nu.die("Error on reading CNT direction.") ### open files myBGF = bgf.BgfFile(bgf_file) myTRJ = open(trj_file) myTRJ.seek(0) f_out_file = open(out_file + ".dat", 'w') f_avg_out_file = open(out_file + ".average.dat", 'w') f_pickle = open(out_file + ".pickle", 'w') f_avg_pickle = open(out_file + ".average.pickle", 'w') ### read residues from bgf_file residue = set() # kind of residues in BGF file dict_residue = dict() # stores residue numbers per each residue. RES1: [1, 2, ..], RES2: [6, 7, ..] for i in myBGF.a: rname = string.strip(i.rName) residue.add(rname) output = "" for i in residue: output += i + " " if not silent: print("Found " + str(len(residue)) + " residues in BGF file: " + str(output)) residue = list(residue) residue.append('TOTAL') for index, i in enumerate(residue): dict_residue[i] = index n_residue = len(residue) # number of residues (including total) ### if no CNT the die if "CNT" not in residue: nu.die( "It seems that the BGF file does not contain any CNT atoms. Exiting." ) ### extract aNos of CNT in the BGF file aNo_CNT = [] for atom in myBGF.a: # Carbons in CNT if "CNT" in atom.rName: aNo_CNT.append(atom.aNo) ### read mass from ff_file try: parse = ff_file.split(" ") except: nu.die( "Error occurred when reading the force field file.. Check your " + str(ff_file)) else: if not silent: print("Found " + str(len(parse)) + " Cerius2 Force Fields.") for i in parse: FF = dreiding.loadFF(i) temp_atominfo = dreiding.loadAtomTypes(FF) atominfo.update(temp_atominfo) ### read trajectory file # how many steps to go? n_timestep = len(lt.getTrjInfo(trj_file)) if not silent: print("The trajectory contains " + str(n_timestep) + " timesteps.") # Find header of the trajectory file while 1: templine = myTRJ.readline() line.append(templine.strip('\n').strip('ITEM: ')) n_header += 1 if "ITEM: ATOMS" in templine: break # INITIAL trajectory information timestep = int(line[1]) natoms = int(line[3]) boxsize = [ line[5].split(' ')[0], line[5].split(' ')[1], line[6].split(' ')[0], line[6].split(' ')[1], line[7].split(' ')[0], line[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])] keywords = line[8].strip('ATOMS ') initial_boxsize = copy.deepcopy(boxsize) # for every shot in the trajectory file update BGF and manipulate dumpatom = get_line(trj_file) processed_step = 0 t1 = t2 = 0 elapsed_time = 0 while 1: try: chunk = [next(dumpatom) for i in range(natoms + n_header)] except StopIteration: break timestep = int(chunk[1]) l_timestep.append(timestep) natoms = int(chunk[3]) boxsize = [ chunk[5].split(' ')[0], chunk[5].split(' ')[1], chunk[6].split(' ')[0], chunk[6].split(' ')[1], chunk[7].split(' ')[0], chunk[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])] keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ') ### if the box size changes, then stop (only takes NVT trajectory) for i in range(3): if abs(initial_boxsize[i] - boxsize[i]) > 0.1: nu.die( "Simulation box change detected in the trajectory file. NVT trajectory is required to continue." ) ### Show progress t1 = time.time() remaining_time = elapsed_time * (n_timestep - processed_step) sys.stdout.write('\r' + "Reading timestep.. " + str(timestep) + " (Elapsed time for the previous step: " + "{0:4.1f}".format(elapsed_time) + " seconds, Remaining time: " + "{0:4.1f}".format(remaining_time) + " seconds = " + "{0:4.1f} minutes".format(remaining_time / 60) + ")") sys.stdout.flush() processed_step += 1 ### update myBGF with trajectory information ### natom_bgf = len(myBGF.a) # number of atoms in BGF file if not natom_bgf == natoms: nu.die( "Number of atoms in trajectory file does not match with BGF file." ) mode = "" if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords: mode = 'scaled' elif 'x' in keywords or 'y' in keywords or 'z' in keywords: mode = 'normal' elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords: mode = 'unwrapped' # actual coordinate coordinfo = chunk[9:] # assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz'] for atomline in coordinfo: atomcoord = atomline.split(' ') atom = myBGF.getAtom(int(atomcoord[0])) if mode == 'scaled': atom.x = float(atomcoord[2]) * boxsize[0] atom.y = float(atomcoord[3]) * boxsize[1] atom.z = float(atomcoord[4]) * boxsize[2] elif mode == 'unwrapped': atom.x = float(atomcoord[2]) atom.y = float(atomcoord[3]) atom.z = float(atomcoord[4]) elif mode == 'normal': try: ix_index = keywords.index('ix') iy_index = keywords.index('iy') iz_index = keywords.index('iz') except ValueError: nu.warn( "No image information no the trajectory file. Will be treated as unwrapped." ) atom.x = float(atomcoord[2]) atom.y = float(atomcoord[3]) atom.z = float(atomcoord[4]) else: atom.x = (int(atomcoord[ix_index]) * boxsize[0]) + float( atomcoord[2]) atom.y = (int(atomcoord[iy_index]) * boxsize[1]) + float( atomcoord[3]) atom.z = (int(atomcoord[iz_index]) * boxsize[2]) + float( atomcoord[4]) try: for i in range(0, 3): myBGF.CRYSTX[i] = boxsize[i] except: pass #nu.warn("Crystal information error: is this file not periodic?") # apply periodic condition myBGF = bgftools.periodicMoleculeSort(myBGF, 0) ### DONE for updating trj on BGF file ### ### Do whatever I want: density profile ### find the CNT center radius_CNT = 0 cntx = cnty = cntz = 0 natoms_CNT = len(aNo_CNT) for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) cntx += atom.x cnty += atom.y cntz += atom.z cntx /= natoms_CNT cnty /= natoms_CNT cntz = natoms_CNT ### make a bin diagonal_length = 0.0 box_height = boxsize[cnt_direction] radial_bin_length = 0.0 x_length = boxsize[0] / 2 y_length = boxsize[1] / 2 z_length = boxsize[2] / 2 if cnt_direction == 0: diagonal_length = math.sqrt(boxsize[1]**2 + boxsize[2]**2) / 2 radial_bin_length = min(diagonal_length, y_length, z_length) elif cnt_direction == 1: diagonal_length = math.sqrt(boxsize[0]**2 + boxsize[2]**2) / 2 radial_bin_length = min(diagonal_length, x_length, z_length) elif cnt_direction == 2: diagonal_length = math.sqrt(boxsize[0]**2 + boxsize[1]**2) / 2 radial_bin_length = min(diagonal_length, y_length, z_length) # choose the shortest length among diagonal and half size of the box length #radial_bin_length = min(diagonal_length, boxsize[0]/2, boxsize[1]/2, boxsize[2]/2) bin = np.arange(0.0, math.ceil(radial_bin_length), interval) ### for every atoms, get atom coordinate and its type positions = [] # atom positions. [ res1, res2, ..., total ] masses = [] # used for a weight for histogram. [ res1, res2, ..., total ] hist = [] bin_edges = [] for i in range(n_residue): positions.append([]) masses.append([]) hist.append([]) bin_edges.append([]) for atom in myBGF.a: coord = [atom.x, atom.y, atom.z] dist = 0 # calculate radial distance from CNT center to atom if cnt_direction == 0: dist = math.sqrt((atom.y - cnty)**2 + (atom.z - cntz)**2) elif cnt_direction == 1: dist = math.sqrt((atom.x - cntx)**2 + (atom.z - cntz)**2) elif cnt_direction == 2: dist = math.sqrt((atom.x - cntx)**2 + (atom.y - cnty)**2) # total positions[-1].append(dist) masses[-1].append(atominfo[atom.ffType]['MASS']) # residues positions[dict_residue[atom.rName.strip()]].append(dist) masses[dict_residue[atom.rName.strip()]].append( atominfo[atom.ffType]['MASS']) ### histogram for i in range(n_residue): hist[i], bin_edges[i] = np.histogram(positions[i], bins=bin, weights=masses[i]) ### divide by volume for density vol = [] for j in range(len(hist[0])): vol.append(math.pi * (bin_edges[0][j + 1]**2 - bin_edges[0][j]**2) * box_height) for i in range(n_residue): hist[i] = hist[i] / 6.022 / vol * 10.0 # density ### store temp = dict() for i in range(n_residue): temp2 = dict() temp2['HIST'] = hist[i] temp2['BIN_EDGES'] = bin_edges[i] temp[residue[i]] = temp2 result[timestep] = temp ### end of loop: check elapsed time t2 = time.time() # time mark elapsed_time = t2 - t1 ### calculate average values if not silent: print("\nAveraging the last " + str(avg_timestep) + " timesteps..") avg_timesteps = l_timestep[-avg_timestep:] avg_hist = [] avg_bin_edges = [] for i in range(n_residue): avg_hist.append( np.zeros(len(result[l_timestep[-avg_timestep]]['TOTAL']['HIST']))) #avg_bin_edges.append(np.zeros(len(result[-avg_timestep]['TOTAL']['BIN_EDGES']))); for t in avg_timesteps: for r in result[t]: avg_hist[dict_residue[r]] += result[t][r]['HIST'] for i in range(n_residue): avg_hist[i] /= len(avg_timesteps) # normalize temp_avg = dict() # residue --- HIST, BIN_EDGES for i in residue: temp2 = dict() temp2['HIST'] = avg_hist[dict_residue[i]] temp2['BIN_EDGES'] = bin_edges[0] temp_avg[i] = temp2 ### write up a average data to file output = str(avg_timestep) + "\n" for r in temp_avg: output += str(r) + "\n" for index, i in enumerate(temp_avg[r]['HIST']): output += str( temp_avg[r]['BIN_EDGES'][index]) + "\t" + str(i) + "\n" output += "\n" f_avg_out_file.write(output) ### write up a whole data to file output = "" tkey = result.keys() tkey.sort() for t in tkey: output += str(t) + "\n" rkey = result[t].keys() rkey.sort() for r in rkey: output += str(r) + "\n" for index, i in enumerate(result[t][r]['HIST']): output += str( result[t][r]['BIN_EDGES'][index]) + "\t" + str(i) + "\n" output += "\n" output += "\n" f_out_file.write(output) ### write up a pickle object if not silent: print("Writing pickle object..") pickle.dump(result, f_pickle) f_pickle.close() pickle.dump(temp, f_avg_pickle) f_avg_pickle.close() ### return print('') return 1
def trj2data(dat_file, trj_file, step, skipVelocity, silent=False): # init timestep = 0 l_timestep = [] line = [] n_header = 0 t1 = 0 t2 = 0 # clock myBGF = bgf.BgfFile(bgf_file) myTRJ = open(trj_file) myTRJ.seek(0) ### LAMMPS Data dat_atoms = [] if not silent: print("== Step 1. Loading LAMMPS Data") if not os.path.exists(dat_file): nu.die("Please check the LAMMPS data file.") f_dat_file = open(dat_file) temp = f_dat_file.read().split('\n') dat_atom_start = temp.index('Atoms') dat_atom_end = temp.index('Bonds') dat_atoms = temp[dat_atom_start + 1:dat_atom_end] f_dat_file.close() ### LAMMPS Trajectory # how many steps to go? if not silent: print("== Step 2. Loading LAMMPS Trajectory") n_timestep = len(lt.getTrjInfo(trj_file)) print("The trajectory contains " + str(n_timestep) + " timesteps.") # Find header of the trajectory file while 1: templine = myTRJ.readline() line.append(templine.strip('\n').strip('ITEM: ')) n_header += 1 if "ITEM: ATOMS" in templine: break # INITIAL trajectory information timestep = int(line[1]) natoms = int(line[3]) boxsize = [ line[5].split(' ')[0], line[5].split(' ')[1], line[6].split(' ')[0], line[6].split(' ')[1], line[7].split(' ')[0], line[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] keywords = line[8].strip('ATOMS ') # for every shot in the trajectory file update BGF and manipulate dumpatom = get_line(trj_file) processed_step = 0 t1 = t2 = 0 elapsed_time = 0 if not silent: print("== Step 3. Reading LAMMPS Trajectory") while 1: try: chunk = [next(dumpatom) for i in range(natoms + n_header)] except StopIteration: break timestep = int(chunk[1]) natoms = int(chunk[3]) boxsize = [ chunk[5].split(' ')[0], chunk[5].split(' ')[1], chunk[6].split(' ')[0], chunk[6].split(' ')[1], chunk[7].split(' ')[0], chunk[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])] keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ') ### Show progress t1 = time.time() remaining_time = elapsed_time * (n_timestep - processed_step) sys.stdout.write('\r' + "Reading timestep.. " + str(timestep) + " (Elapsed time for the previous step: " + "{0:4.1f}".format(elapsed_time) + " seconds, Remaining time: " + "{0:4.1f}".format(remaining_time) + " seconds = " + "{0:4.1f} minutes".format(remaining_time / 60) + ")") sys.stdout.flush() processed_step += 1 ### if step is specified, then save only for that step. if step != "": if timestep == step: pass else: continue else: pass ### update myBGF with trajectory information ### natom_bgf = len(myBGF.a) # number of atoms in BGF file if not natom_bgf == natoms: nu.die( "Number of atoms in trajectory file does not match with BGF file." ) mode = "" if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords: mode = 'scaled' elif 'x' in keywords or 'y' in keywords or 'z' in keywords: mode = 'normal' elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords: mode = 'unwrapped' flagVelocity = False if 'vx' in keywords or 'vy' in keywords or 'vz' in keywords: flagVelocity = True # actual coordinate coordinfo = chunk[9:] # assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz'] for atomline in coordinfo: atomcoord = atomline.split(' ') atom = myBGF.getAtom(int(atomcoord[0])) if mode == 'scaled': atom.x = float(atomcoord[2]) * boxsize[0] atom.y = float(atomcoord[3]) * boxsize[1] atom.z = float(atomcoord[4]) * boxsize[2] elif mode == 'unwrapped': atom.x = float(atomcoord[2]) atom.y = float(atomcoord[3]) atom.z = float(atomcoord[4]) elif mode == 'normal': try: ix_index = keywords.index('ix') iy_index = keywords.index('iy') iz_index = keywords.index('iz') except ValueError: nu.warn( "No image information no the trajectory file. Will be treated as unwrapped." ) atom.x = float(atomcoord[2]) atom.y = float(atomcoord[3]) atom.z = float(atomcoord[4]) else: atom.x = (int(atomcoord[ix_index]) * boxsize[0]) + float( atomcoord[2]) atom.y = (int(atomcoord[iy_index]) * boxsize[1]) + float( atomcoord[3]) atom.z = (int(atomcoord[iz_index]) * boxsize[2]) + float( atomcoord[4]) if not skipVelocity: if flagVelocity == True: atom.vx = float(atomcoord[5]) atom.vy = float(atomcoord[6]) atom.vz = float(atomcoord[7]) try: for i in range(0, 3): myBGF.CRYSTX[i] = boxsize[i] except: pass #nu.warn("Crystal information error: is this file not periodic?") # apply periodic condition myBGF = bgftools.periodicMoleculeSort(myBGF, 0) #myBGF.saveBGF(bgf_file[:-4] + "." + str(timestep) + ".trjupdated.bgf") ### myBGF update complete! ### ### update LAMMPS data file ### myDAT = open(dat_file) myNewDAT = open(dat_file + "." + str(timestep), 'w') linecount = 0 while 1: line = myDAT.readline() if not line: break if linecount == 0: output = line.strip( "\n") + " and updated with timestep " + str( timestep) + " in " + trj_file + "\n" linecount += 1 myNewDAT.write(output) continue if "xlo " in line: output = "\t" + " {0:>10.6f} {1:>10.6f}".format( 0.0, boxsize[0]) + " xlo xhi\n" myNewDAT.write(output) continue elif "ylo " in line: output = "\t" + " {0:>10.6f} {1:>10.6f}".format( 0.0, boxsize[1]) + " ylo yhi\n" myNewDAT.write(output) continue elif "zlo " in line: output = "\t" + " {0:>10.6f} {1:>10.6f}".format( 0.0, boxsize[2]) + " zlo zhi\n" myNewDAT.write(output) continue if not "Atoms" in line: myNewDAT.write(line) else: myNewDAT.write("Atoms\n\n") for i in dat_atoms: if len(i) == 0: continue parse = i.split() atomNo = int(parse[0]) molNo = int(parse[1]) atomTypeNo = int(parse[2]) atom = myBGF.getAtom(atomNo) if atom.aNo != atomNo or atom.rNo != molNo: nu.die( "BGF and data file mismatch. Please check both files." ) else: output = "{0:>8} {1:>8} {2:>8} {3:10.5f} {4:10.5f} {5:10.5f} {6:10.5f} {7:12.8f} {8:12.8f} {9:12.8f}".format( atom.aNo, atom.rNo, atomTypeNo, atom.charge, atom.x, atom.y, atom.z, atom.vx, atom.vy, atom.vz) + "\n" myNewDAT.write(output) # consume for i in range(len(dat_atoms)): line = myDAT.readline() myNewDAT.write("\n") t2 = time.time() # time mark elapsed_time = t2 - t1 print('') return 1
def countWaterCNT(bgf_file, trj_file, fixed, silent): # init timestep = 0; l_timestep = []; line = []; n_header = 0; output = ""; radius_CNTs = []; t1 = 0; t2 = 0; # clock radius_CNT = 0.0; myBGF = bgf.BgfFile(bgf_file) myTRJ = open(trj_file) myTRJ.seek(0) # how many steps to go? #wc_trj_file = popen("grep TIMESTEP " + trj_file + " | wc -l ").read() #n_timestep = int(wc_trj_file.split()[0]); n_timestep = len(lt.getTrjInfo(trj_file)) print("The trajectory contains " + str(n_timestep) + " timesteps.") # extract aNos of CNT in the BGF file aNo_CNT = [] for atom in myBGF.a: # Carbons in CNT if "CNT" in atom.rName: aNo_CNT.append(atom.aNo) N_CNT = len(aNo_CNT) # the number of CNT atoms # Find header of the trajectory file while 1: templine = myTRJ.readline() line.append(templine.strip('\n').strip('ITEM: ')) n_header += 1 if "ITEM: ATOMS" in templine: break; # INITIAL trajectory information timestep = int(line[1]) natoms = int(line[3]) boxsize = [line[5].split(' ')[0], line[5].split(' ')[1], line[6].split(' ')[0], line[6].split(' ')[1], line[7].split(' ')[0], line[7].split(' ')[1]] boxsize = [float(i) for i in boxsize] keywords = line[8].strip('ATOMS ') # for every shot in the trajectory file update BGF and manipulate dumpatom = get_line(trj_file) processed_step = 0; t1 = t2 = 0; elapsed_time = 0; while 1: try: chunk = [next(dumpatom) for i in range(natoms+n_header)] except StopIteration: break; timestep = int(chunk[1]) natoms = int(chunk[3]) boxsize = [chunk[5].split(' ')[0], chunk[5].split(' ')[1], chunk[6].split(' ')[0], chunk[6].split(' ')[1], chunk[7].split(' ')[0], chunk[7].split(' ')[1]]; boxsize = [float(i) for i in boxsize]; boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])] keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ') ### Show progress t1 = time.time(); remaining_time = elapsed_time * (n_timestep - processed_step) sys.stdout.write('\r' + "Reading timestep.. " + str(timestep) + " (Elapsed time for the previous step: " + "{0:4.1f}".format(elapsed_time) + " seconds, Remaining time: " + "{0:4.1f}".format(remaining_time) + " seconds = " + "{0:4.1f} minutes".format(remaining_time/60) + ") " + str(radius_CNT)) sys.stdout.flush() processed_step += 1; ### if step is specified, then save only for that step. if step != 0: if timestep == step: pass; else: continue; else: pass; ### update myBGF with trajectory information ### natom_bgf = len(myBGF.a) # number of atoms in BGF file if not natom_bgf == natoms: nu.die("Number of atoms in trajectory file does not match with BGF file.") mode = "" if 'xs' in keywords or 'ys' in keywords or 'zs' in keywords: mode = 'scaled' elif 'x' in keywords or 'y' in keywords or 'z' in keywords: mode = 'normal' elif 'xu' in keywords or 'yu' in keywords or 'zu' in keywords: mode = 'unwrapped' # actual coordinate coordinfo = chunk[9:] # assume that coordinfo is similar to ['id', 'type', 'xs', 'ys', 'zs', 'ix', 'iy', 'iz'] for atomline in coordinfo: atomcoord = atomline.split(' ') atom = myBGF.getAtom(int(atomcoord[0])) if mode == 'scaled': atom.x = float(atomcoord[2]) * boxsize[0] atom.y = float(atomcoord[3]) * boxsize[1] atom.z = float(atomcoord[4]) * boxsize[2] elif mode == 'unwrapped': atom.x = float(atomcoord[2]) atom.y = float(atomcoord[3]) atom.z = float(atomcoord[4]) elif mode == 'normal': try: ix_index = keywords.index('ix') iy_index = keywords.index('iy') iz_index = keywords.index('iz') except ValueError: nu.warn("No image information no the trajectory file. Will be treated as unwrapped.") atom.x = float(atomcoord[2]) atom.y = float(atomcoord[3]) atom.z = float(atomcoord[4]) else: atom.x = (int(atomcoord[ix_index]) * boxsize[0]) + float(atomcoord[2]) atom.y = (int(atomcoord[iy_index]) * boxsize[1]) + float(atomcoord[3]) atom.z = (int(atomcoord[iz_index]) * boxsize[2]) + float(atomcoord[4]) try: for i in range(0, 3): myBGF.CRYSTX[i] = boxsize[i] except: pass; #nu.warn("Crystal information error: is this file not periodic?") # apply periodic condition myBGF = bgftools.periodicMoleculeSort(myBGF, 0) #myBGF.saveBGF(bgf_file[:-4] + "." + str(timestep) + ".trjupdated.bgf") ### myBGF update complete! ### if not fixed: ### rotate cnt to x axis # initialize for the moment of inertia and the center of mass calculation U = 0; Ut = 0; Uv = 0; Ixx = 0; Ixy = 0; Ixz = 0; Iyx = 0; Iyy = 0; Iyz = 0; Izx = 0; Izy = 0; Izz = 0; Mx = 0; My = 0; Mz = 0; # transpose for "all atoms in BGF": move COM of CNT as origin # com of CNT Mx = 0; My = 0; Mz = 0; for atom in myBGF.a: if "CNT" in atom.rName: Mx += atom.x / N_CNT My += atom.y / N_CNT Mz += atom.z / N_CNT # move for atom in myBGF.a: atom.x -= Mx atom.y -= My atom.z -= Mz # calculate the moment of inertia (MI) and the center of mass (COM) of CNT from "myBGF" for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) Ixx += (atom.y**2 + atom.z**2) / N_CNT Iyy += (atom.x**2 + atom.z**2) / N_CNT Izz += (atom.x**2 + atom.y**2) / N_CNT Ixy -= (atom.x * atom.y) / N_CNT Ixz -= (atom.x * atom.z) / N_CNT Iyz -= (atom.y * atom.z) / N_CNT # the moment of inertia tensor I = numpy.array([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]]) # eigenvalue & eigenvector calculation eigval, eigvec = numpy.linalg.eig(I) # eigval[0] is the minimum among the values. # rearrange the U vector U = numpy.matrix(eigvec) Ut = U.T # "myBGF" rotation for atom in myBGF.a: v = numpy.matrix([atom.x, atom.y, atom.z]).T Uv = Ut * v atom.x = float(Uv[0]) atom.y = float(Uv[1]) atom.z = float(Uv[2]) # for CNT atoms, calculate some properties min_x_CNT = 0.0; max_x_CNT = 0.0; height_CNT = 0.0; aNo_MtOH_C_not_in_CNT = []; temp = []; min_y_CNT = 0.0; max_y_CNT = 0.0; min_z_CNT = 0.0; max_z_CNT = 0.0; CNT_orientation = ""; # check the orientation of CNT for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) # minimum and maximum x coord of CNT: this will be the height of CNT if atom.x < min_x_CNT: min_x_CNT = atom.x if atom.x > max_x_CNT: max_x_CNT = atom.x if atom.y < min_y_CNT: min_y_CNT = atom.y if atom.y > max_y_CNT: max_y_CNT = atom.y if atom.z < min_z_CNT: min_z_CNT = atom.z if atom.z > max_z_CNT: max_z_CNT = atom.z x_diff = max_x_CNT - min_x_CNT y_diff = max_y_CNT - min_y_CNT z_diff = max_z_CNT - min_z_CNT if x_diff > y_diff and x_diff > z_diff: # CNT is aligned along x axis height_CNT = x_diff CNT_orientation = "x" elif y_diff > x_diff and y_diff > z_diff: # CNT is aligned along y axis height_CNT = y_diff CNT_orientation = "y" elif z_diff > x_diff and z_diff > y_diff: # CNT is aligned along z axis height_CNT = z_diff CNT_orientation = "z" if CNT_orientation == "x": for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) radius_CNT += math.sqrt(atom.y**2 + atom.z**2) # average radius of CNT elif CNT_orientation == "y": for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) radius_CNT += math.sqrt(atom.x**2 + atom.z**2) # average radius of CNT elif CNT_orientation == "z": for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) radius_CNT += math.sqrt(atom.x**2 + atom.y**2) # average radius of CNT radius_CNT = radius_CNT / N_CNT radius_CNTs.append(radius_CNT) output += str(timestep) + '\t' + str(radius_CNT) + '\n' #if not silent: print(str(timestep) + '\t' + str(radius_CNT) + '\n') # write output #myBGF.saveBGF(bgf_file[:-4] + "." + str(timestep) + ".bgf") #myBGF2.saveBGF(bgf_file[:-4] + "." + str(timestep) + ".bgf") t2 = time.time() # time mark elapsed_time = t2 - t1; #print(output) m, s = nu.meanstdv(radius_CNTs) output += "average: " + '\t' + str(m) + '\t' + str(s) + '\n' print('') print(output) return 1
def getSlipLength(bgf_file, trj_file, force_profile, silent=False): """ This calculates the profile of averaged velocity according to r. NOTE: This is different from averaged velocity profile according to r. """ # const PI = math.pi vdw_r_C = 1.7 # init timestep = 0 l_timestep = [] line = [] n_header = 0 output = "" t1 = 0 t2 = 0 # clock output += "t\tforce\tarea\tvz\tvisc\tsliplen\n" l_radial_vz_profile = [] l_avg_data = [] l_result = [] l_avg_count = [] n_avg_count_step = 0 myBGF = bgf.BgfFile(bgf_file) myTRJ = open(trj_file) myTRJ.seek(0) myOUT = open(trj_file + ".sliplength.profile", 'w') # how many steps to go? if not silent: print("Scanning trajectory file..") l_timestep = lt.getTrjInfo(trj_file, silent=False) n_timestep = len(l_timestep) if not silent: print("\nThe trajectory contains " + str(n_timestep) + " timesteps.") # read force data from force profile if not silent: print("Reading force profile..") f_fp = open(force_profile) force = dict() while 1: line = f_fp.readline() if not line: break if line[0] == "#": continue parse = line.split() step = int(parse[0]) force[step] = float(parse[1]) # extract aNos of CNT in the BGF file aNo_CNT = [] aNo_WAT_O = [] aNo_WAT_all = [] for atom in myBGF.a: # Carbons in CNT if "CNT" in atom.rName: aNo_CNT.append(atom.aNo) # Oxygen in water if "WAT" in atom.rName and "O" in atom.aName: aNo_WAT_O.append(atom.aNo) N_CNT = len(aNo_CNT) # the number of CNT atoms # check if there exists water properly if len(aNo_WAT_O) == 0: nu.die("No water molecules in the BGF file.") if len(aNo_CNT) == 0: nu.die("No CNT molecules in the BGF file.") t1 = t2 = 0 elapsed_time = 0 # Find header of the trajectory file line = [] n_header = 0 while 1: templine = myTRJ.readline() line.append(templine.strip('\n').strip('ITEM: ')) n_header += 1 if "ITEM: ATOMS" in templine: break # INITIAL trajectory information timestep = int(line[1]) natoms = int(line[3]) boxsize = [ line[5].split(' ')[0], line[5].split(' ')[1], line[6].split(' ')[0], line[6].split(' ')[1], line[7].split(' ')[0], line[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] keywords = line[8].strip('ATOMS ') # calculate properties dumpatom = get_line(trj_file) processed_step = 0 while 1: ### Show progress t1 = time.time() remaining_time = elapsed_time * (n_timestep - processed_step) ### Read try: chunk = [next(dumpatom) for i in range(natoms + n_header)] except StopIteration: break timestep = int(chunk[1]) l_timestep.append(timestep) natoms = int(chunk[3]) boxsize = [ chunk[5].split(' ')[0], chunk[5].split(' ')[1], chunk[6].split(' ')[0], chunk[6].split(' ')[1], chunk[7].split(' ')[0], chunk[7].split(' ')[1] ] boxsize = [float(i) for i in boxsize] boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])] keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ') sys.stdout.write('\r' + "Fetched timestep: " + str(timestep) + " (Remaining time: " + "{0:4.1f}".format(remaining_time) + " seconds, " + "{0:4.1f} minutes".format(remaining_time / 60) + ")") sys.stdout.flush() if timestep == 0: continue ### update myBGF with trajectory information ### natom_bgf = len(myBGF.a) # number of atoms in BGF file if not natom_bgf == natoms: nu.die( "Number of atoms in trajectory file does not match with BGF file." ) mode = 'unwrapped' # assume that "dump 1 all custom 100 ${sname}${rtemp}K.nvt.lammps id type xu yu zu vx vy vz" in lammps input # actual coordinate coordinfo = chunk[9:] # modified for fast treatment for atomline in coordinfo: atomcoord = atomline.split(' ') atom = myBGF.getAtom(int(atomcoord[0])) atom.vx = float(atomcoord[5]) atom.vy = float(atomcoord[6]) atom.vz = float(atomcoord[7]) ### myBGF update complete! ### # calculate z-directional velocity of water molecules wrt r vcm = sum vi mi / sum mi mass_O = 16.0000 mass_H = 1.008 mass_H2O = mass_O + 2 * mass_H # H2O mass vz = [] # data container # z velocity calculation for ano in aNo_WAT_O: atom = myBGF.getAtom(ano) # oxygen vcmz = atom.vz * mass_O for ano2 in atom.CONECT: atom2 = myBGF.getAtom(ano2) # hydrogens vcmz += atom2.vz * mass_H vcmz /= mass_H2O vz.append(vcmz * (10**5)) # velocity in A/fs -> m/s avg_vz, _ = nu.meanstdv(vz) f = force[timestep] * (6.95e9) l = f / A / avg_vz # lambda b = v / l * 1e9 # slip length output += str(timestep) + "\t" + str(force[timestep]) + "\t" + str( A) + "\t" + str(avg_vz) + "\t" + str(v) + "\t" + str(b) + "\n" t2 = time.time() # time mark elapsed_time = t2 - t1 processed_step += 1 myOUT.write(output) myOUT.close() print('') return 1
def getVelocity(bgf_file, trj_file, n_step, silent=False): # const PI = math.pi vdw_r_C = 1.7 # init timestep = 0; l_timestep = []; line = []; n_header = 0; t1 = 0; t2 = 0; # clock l_data = []; # stores vz l_avg_radius_CNT = []; myBGF = bgf.BgfFile(bgf_file) myTRJ = open(trj_file) myTRJ.seek(0) ftemp = open("countWater4.profile.test", 'w') ftemp.write(str(sys.argv) + "\n") curr_dir = os.path.abspath(".") temp_dir = curr_dir + "/CountWAT5/" print(temp_dir) if not os.path.isdir(temp_dir): os.makedirs(temp_dir) # how many steps to go? n_timestep = len(lt.getTrjInfo(trj_file)) if n_step == 0: n_step = n_timestep; print(" ..The trajectory contains " + str(n_timestep) + " timesteps.") print("The script will proceed for the last " + str(n_step) + " timesteps.") # extract aNos of CNT in the BGF file aNo_CNT = [] aNo_WAT_O = [] aNo_WAT_all = [] for atom in myBGF.a: # Carbons in CNT or atoms in BNNT if "NT" in atom.rName: aNo_CNT.append(atom.aNo) # Oxygen in water if "WAT" in atom.rName and "O" in atom.aName: aNo_WAT_O.append(atom.aNo) N_CNT = len(aNo_CNT) # the number of CNT atoms # check if there exists water properly if len(aNo_WAT_O) == 0: nu.die("No water molecules in the BGF file.") if len(aNo_CNT) == 0: nu.die("No CNT molecules in the BGF file.") # Find header of the trajectory file while 1: templine = myTRJ.readline() line.append(templine.strip('\n').strip('ITEM: ')) n_header += 1 if "ITEM: ATOMS" in templine: break; # INITIAL trajectory information timestep = int(line[1]) natoms = int(line[3]) boxsize = [line[5].split(' ')[0], line[5].split(' ')[1], line[6].split(' ')[0], line[6].split(' ')[1], line[7].split(' ')[0], line[7].split(' ')[1]] boxsize = [float(i) for i in boxsize] keywords = line[8].strip('ATOMS ') # for every shot in the trajectory file update BGF and manipulate dumpatom = get_line(trj_file) processed_step = 0; t1 = t2 = 0; elapsed_time = 0; while 1: ### tester if processed_step == 50: break; ### Show progress t1 = time.time(); remaining_time = elapsed_time * (n_step - processed_step) sys.stdout.write('\r' + "Reading timestep.. " + str(timestep) + " (Remaining time: " + "{0:4.1f}".format(remaining_time) + " seconds, " + "{0:4.1f} minutes".format(remaining_time/60) + ")") sys.stdout.flush() if processed_step == n_step: break; ### Read myBGF = bgf.BgfFile(bgf_file) try: chunk = [next(dumpatom) for i in range(natoms+n_header)] except StopIteration: break; timestep = int(chunk[1]) natoms = int(chunk[3]) boxsize = [chunk[5].split(' ')[0], chunk[5].split(' ')[1], chunk[6].split(' ')[0], chunk[6].split(' ')[1], chunk[7].split(' ')[0], chunk[7].split(' ')[1]]; boxsize = [float(i) for i in boxsize]; boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])] keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ') ### update myBGF with trajectory information ### natom_bgf = len(myBGF.a) # number of atoms in BGF file if not natom_bgf == natoms: nu.die("Number of atoms in trajectory file does not match with BGF file.") mode = 'unwrapped' # assume that "dump 1 all custom 100 ${sname}${rtemp}K.nvt.lammps id type xu yu zu vx vy vz" in lammps input # actual coordinate coordinfo = chunk[9:] # modified for fast treatment for atomline in coordinfo: atomcoord = atomline.split(' ') atom = myBGF.getAtom(int(atomcoord[0])) atom.x = float(atomcoord[2]) atom.y = float(atomcoord[3]) atom.z = float(atomcoord[4]) atom.vx = float(atomcoord[5]) atom.vy = float(atomcoord[6]) atom.vz = float(atomcoord[7]) ### myBGF update complete! ### ### align CNT to z axis # initialize for the moment of inertia and the center of mass calculation U = 0; Ut = 0; Uv = 0; Ixx = 0; Ixy = 0; Ixz = 0; Iyx = 0; Iyy = 0; Iyz = 0; Izx = 0; Izy = 0; Izz = 0; Mx = 0; My = 0; Mz = 0; # transpose "all atoms in BGF": move COM of CNT as origin # com of CNT (important: only one CNT!) Mx = 0; My = 0; Mz = 0; min_x_CNT = 0.0; max_x_CNT = 0.0; min_y_CNT = 0.0; max_y_CNT = 0.0; min_z_CNT = 0.0; max_z_CNT = 0.0; for atom in myBGF.a: if "NT" in atom.rName: Mx += atom.x / N_CNT My += atom.y / N_CNT Mz += atom.z / N_CNT ### before we proceed to calculate MI first check how the CNT is lying across the periodic box if atom.x < min_x_CNT: min_x_CNT = atom.x if atom.x > max_x_CNT: max_x_CNT = atom.x if atom.y < min_y_CNT: min_y_CNT = atom.y if atom.y > max_y_CNT: max_y_CNT = atom.y if atom.z < min_z_CNT: min_z_CNT = atom.z if atom.z > max_z_CNT: max_z_CNT = atom.z max_x_axis = int(math.ceil(max_x_CNT/boxsize[0])) min_x_axis = int(math.floor(min_x_CNT/boxsize[0])) max_y_axis = int(math.ceil(max_y_CNT/boxsize[1])) min_y_axis = int(math.floor(min_y_CNT/boxsize[1])) max_z_axis = int(math.ceil(max_z_CNT/boxsize[2])) min_z_axis = int(math.floor(min_z_CNT/boxsize[2])) replNum = (min_x_axis, max_x_axis, min_y_axis, max_y_axis, min_z_axis, max_z_axis) copyNum = 0 ### copy water molecules for x in range(min_x_axis, max_x_axis): if x != 0: myBGF2 = copy.deepcopy(myBGF) bgf.moveBGF(myBGF2, boxsize[0]*x, 0, 0) myBGF = myBGF.merge(myBGF2) copyNum += 1 for y in range(min_y_axis, max_y_axis): if y != 0: myBGF2 = copy.deepcopy(myBGF) bgf.moveBGF(myBGF2, 0, boxsize[1]*y, 0) myBGF = myBGF.merge(myBGF2) copyNum += 1 for z in range(min_z_axis, max_z_axis): if z != 0: myBGF2 = copy.deepcopy(myBGF) bgf.moveBGF(myBGF2, 0, 0, boxsize[2]*z) myBGF = myBGF.merge(myBGF2) copyNum += 1 print(str(replNum) + " " + str(copyNum) + " natoms: " + str(len(myBGF.a))) ### now continute to MI calculation # move atoms to box center COM = nu.array([[Mx, My, Mz]]) CNT = CNT - COM ''' for atom in myBGF.a: atom.x -= Mx atom.y -= My atom.z -= Mz ''' # calculate the moment of inertia (MI) and the center of mass (COM) of CNT from "myBGF" for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) Ixx += (atom.y**2 + atom.z**2) / N_CNT Iyy += (atom.x**2 + atom.z**2) / N_CNT Izz += (atom.x**2 + atom.y**2) / N_CNT Ixy -= (atom.x * atom.y) / N_CNT Ixz -= (atom.x * atom.z) / N_CNT Iyz -= (atom.y * atom.z) / N_CNT # the moment of inertia tensor I = np.array([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]]) # eigenvalue & eigenvector calculation eigval, eigvec = np.linalg.eig(I) # eigval[0] is the minimum among the values. # rearrange the U vector U = np.matrix(eigvec) Ut = U.T # "myBGF" rotation for atom in myBGF.a: v = np.matrix([atom.x, atom.y, atom.z]).T Uv = Ut * v atom.x = float(Uv[2]) atom.y = float(Uv[1]) atom.z = float(Uv[0]) # for CNT atoms, calculate some properties min_x_CNT = 1000.0; max_x_CNT = -1000.0; radius_CNT = 0.0; height_CNT = 0.0; min_y_CNT = 1000.0; max_y_CNT = -1000.0; min_z_CNT = 1000.0; max_z_CNT = -1000.0; CNT_orientation = "-" # move origin to box center for atom in myBGF.a: atom.x += boxsize[0]/2.0 atom.y += boxsize[1]/2.0 atom.z += boxsize[2]/2.0 #myBGF = bgftools.periodicMoleculeSort(myBGF, 0, myBGF.CRYSTX) ##### testestestest ### update PBC information myBGF.PERIOD = "111" myBGF.AXES = "ZYX" myBGF.SGNAME = "P 1 1 1\n" myBGF.CELLS = [-1, 1, -1, 1, -1, 1] if myBGF.CRYSTX != []: for i in range(0, 3): myBGF.CRYSTX[i] = boxsize[i] else: for i in range(0, 3): myBGF.CRYSTX.append(boxsize[i]) myBGF.CRYSTX += [90.0, 90.0, 90.0] myBGF.saveBGF(temp_dir + bgf_file.split(".bgf")[0] + "." + str(timestep) + ".bgf") l_radius_CNT = []; l_x_CNT = []; l_y_CNT = []; for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) # center of CNT l_x_CNT.append(atom.x) l_y_CNT.append(atom.y) # height if atom.z < min_z_CNT: min_z_CNT = atom.z if atom.z > max_z_CNT: max_z_CNT = atom.z x_CNT, a = nu.meanstdv(l_x_CNT) y_CNT, a = nu.meanstdv(l_y_CNT) z_diff = max_z_CNT - min_z_CNT height_CNT = z_diff # radius of CNT for aNo in aNo_CNT: atom = myBGF.getAtom(aNo) l_radius_CNT.append( math.sqrt( (atom.x - x_CNT)**2 + (atom.y - y_CNT)**2 )) radius_CNT, a = nu.meanstdv(l_radius_CNT) l_avg_radius_CNT.append(radius_CNT) ### get water molecules in CNT # inside the CNT := min_z_CNT <= z <= max_z_CNT and (x - (x_diff/2))**2 + (y - (y_diff/2))**2 < radius_CNT**2 # aNo_WAT_O_atoms: molecules which O atom is within CNT # we don't need to calculate H atoms. Let's consider only O atoms margin = 0.0; # water molecules far from the margin will be only considered aNo_WAT_O_in_CNT = [] for aNo in aNo_WAT_O: atom = myBGF.getAtom(aNo) dist_sq = (atom.x - x_CNT)**2 + (atom.y - y_CNT)**2 if "WAT" in atom.rName and "O" in atom.ffType and min_z_CNT + margin <= atom.z and atom.z <= max_z_CNT - margin and dist_sq < radius_CNT**2: aNo_WAT_O_in_CNT.append(aNo) else: pass; #output = str(timestep) + '\t' + str(len(aNo_WAT_O_in_CNT)) + '\t' + str(radius_CNT) + '\t' + str(z_diff) + '\n' output = str(timestep) + '\t' + str(len(aNo_WAT_O_in_CNT)) + '\t' + str(radius_CNT) + '\t' + str(boxsize[0]/2) + '\t' + str(boxsize[1]/2) + '\t' + str(min_z_CNT) + '\t' + str(max_z_CNT) + '\t' + str(z_diff) + '\t' + str(height_CNT) + '\t' + str(len(aNo_CNT)) + '\t' + str(replNum) + '\t' + str(copyNum) + '\n' # debug ftemp.write(output) #sys.stdout.write('Done ') sys.stdout.flush() t2 = time.time() # time mark elapsed_time = t2 - t1; processed_step += 1; print('') ftemp.close() print("numbers of water molecules are written in countWater.profile ..Done.") return 1