def main(prefix, lag): verbosity.level = "low" lag = int(lag) # hard-coded prefixes for kinetic energy components (kin=diagonal bit, kod=off-diagonal) ikin = open(prefix + ".kin.xyz", "r") ikod = open(prefix + ".kod.xyz", "r") otag = open(prefix + ".ktag_" + str(lag) + ".xyz", "w") natoms = 0 ifr = 0 cbuf = 2 * lag + 1 while True: try: ret = read_file("xyz", ikin) tk = ret["atoms"] kin = dstrip(tk.q) ret = read_file("xyz", ikod) kod = dstrip(ret["atoms"].q) if natoms == 0: # initializes vectors natoms = len(kin) / 3 ktbuf = np.zeros((cbuf, natoms, 3, 3), float) # implement the buffer as a circular one so one doesn't need to re-allocate and storage is continuous nkt = np.zeros((natoms, 3, 3), float) mkt = np.zeros((natoms, 3, 3), float) akt = np.zeros((natoms, 3), float) mea = np.zeros((natoms, 3), float) mev = np.zeros((natoms, 3, 3), float) nkt[:, 0, 0] = kin[0:natoms * 3:3] nkt[:, 1, 1] = kin[1:natoms * 3:3] nkt[:, 2, 2] = kin[2:natoms * 3:3] nkt[:, 0, 1] = nkt[:, 1, 0] = kod[0:natoms * 3:3] nkt[:, 0, 2] = nkt[:, 2, 0] = kod[1:natoms * 3:3] nkt[:, 2, 1] = nkt[:, 1, 2] = kod[2:natoms * 3:3] except EOFError: # Finished reading sys.exit(0) ktbuf[ifr % cbuf] = nkt if ifr >= (2 * lag): # now we can compute the mean tensor, and estimate the components of the kinetic energy mkt[:] = 0.0; tw = 0.0 for j in range(cbuf): w = 1.0 - np.abs(j - lag) * 1.0 / lag; mkt += w * ktbuf[(ifr - j) % cbuf]; tw += w; mkt *= 1.0 / tw # computes the eigenvalues of the TAG tensor for i in range(natoms): [mea[i], mev[i]] = np.linalg.eigh(mkt[i]) otag.write("%d\n# TAG eigenvalues e1 e2 e3 with lag %d. Frame: %d\n" % (natoms, lag, ifr - lag)) for i in range(natoms): otag.write("%6s %15.7e %15.7e %15.7e\n" % (tk.names[i], mea[i, 0], mea[i, 1], mea[i, 2])) ifr += 1
def read_qcpc(self): """ Read in next instances of centroid positions and momenta """ ret = read_file("xyz", self.fqc) # , readcell=True) self.qpos = ret["atoms"] ret = read_file("xyz", self.fpc) # , readcell=True) self.ppos = ret["atoms"] self.qc[:] = self.qpos.q self.pc[:] = self.ppos.q
def step(self, step=None): """Does one replay time step.""" self.ptime = 0.0 self.ttime = 0.0 self.qtime = -time.time() while True: self.rstep += 1 try: if self.intraj.mode == "xyz": for b in self.beads: myframe = read_file("xyz", self.rfile) myatoms = myframe["atoms"] mycell = myframe["cell"] myatoms.q *= unit_to_internal("length", self.intraj.units, 1.0) mycell.h *= unit_to_internal("length", self.intraj.units, 1.0) b.q[:] = myatoms.q self.cell.h[:] = mycell.h elif self.intraj.mode == "pdb": for b in self.beads: myatoms, mycell = read_file("pdb", self.rfile) myatoms.q *= unit_to_internal("length", self.intraj.units, 1.0) mycell.h *= unit_to_internal("length", self.intraj.units, 1.0) b.q[:] = myatoms.q self.cell.h[:] = mycell.h elif self.intraj.mode == "chk" or self.intraj.mode == "checkpoint": # TODO: Adapt the new `Simulation.load_from_xml`? # reads configuration from a checkpoint file xmlchk = xml_parse_file(self.rfile) # Parses the file. from ipi.inputs.simulation import InputSimulation simchk = InputSimulation() simchk.parse(xmlchk.fields[0][1]) mycell = simchk.cell.fetch() mybeads = simchk.beads.fetch() self.cell.h[:] = mycell.h self.beads.q[:] = mybeads.q softexit.trigger(" # Read single checkpoint") except EOFError: softexit.trigger(" # Finished reading re-run trajectory") if (step is None) or (self.rstep > step): break self.qtime += time.time()
def main(prefix, suffix="pos", unitconv="1.0"): ipos = [] imode = [] for filename in sorted(glob.glob(prefix + "." + suffix + "*")): imode.append(filename.split(".")[-1]) ipos.append(open(filename, "r")) nbeads = len(ipos) natoms = 0 ifr = 0 while True: try: for i in range(nbeads): ret = read_file(imode[i], ipos[i]) pos = ret["atoms"] cell = ret["cell"] if natoms == 0: natoms = pos.natoms beads = Beads(natoms, nbeads) cell.h *= float(unitconv) beads[i].q = pos.q * float(unitconv) beads.names = pos.names except EOFError: # finished reading files sys.exit(0) print_file_path("pdb", beads, cell) ifr += 1
def test_read_file(prepare_read_file): file_type, filedesc, output_type, expected_q, expected_cell, expected_names, unit_conv_cell, unit_conv_q = prepare_read_file returned_q = np.array([]) returned_cell = np.array([]) returned_names = [] while True: try: output = io.read_file(file_type, filedesc, output=output_type) except EOFError: break if output_type.strip() != 'objects': returned_q = np.concatenate([returned_q, output['data']]) returned_cell = output['cell'].flatten() elif output_type.strip() == 'objects': returned_q = np.concatenate([returned_q, output['atoms'].q]) returned_cell = output['cell'].h.flatten() returned_names += output['atoms'].names.tolist() npt.assert_almost_equal(expected_q * unit_conv_q, returned_q, 5) npt.assert_almost_equal(expected_cell.flatten() * unit_conv_cell, returned_cell, 5) if output_type.strip() == 'objects': assert all([ expected_names[_ii] == returned_names[_ii] for _ii in xrange(len(expected_names)) ])
def main(prefix, suffix="pos", unitconv="1.0"): ipos = [] imode = [] for filename in sorted(glob.glob(prefix + "." + suffix + "*")): imode.append(filename.split(".")[-1]) ipos.append(open(filename, "r")) nbeads = len(ipos) natoms = 0 ifr = 0 while True: try: for i in range(nbeads): ret = read_file(imode[i], ipos[i]) pos = ret["atoms"] cell = ret["cell"] if natoms == 0: natoms = pos.natoms beads = Beads(natoms, nbeads) cell.h *= float(unitconv) beads[i].q = pos.q * float(unitconv) beads.names = pos.names except EOFError: # finished reading files sys.exit(0) print_file_path("pdb", beads, cell) ifr += 1
def init_file(mode, filename, dimension="length", units="automatic", cell_units="automatic"): """Reads a @mode file and returns the data contained in it. Args: mode: Type of file that should be read. filename: A string giving the name of the pdb file to be read from. Returns: A list of Atoms objects as read from each frame of the pdb file, and a Cell object as read from the final pdb frame. """ rfile = open(filename, "r") ratoms = [] info("Initializing from file %s. Dimension: %s, units: %s, cell_units: %s" % (filename, dimension, units, cell_units), verbosity.low) while True: # while loop, so that more than one configuration can be given # so multiple beads can be initialized at once. try: ret = read_file(mode, rfile, dimension=dimension, units=units, cell_units=cell_units) except EOFError: break ratoms.append(ret["atoms"]) return ratoms, ret["cell"] # if multiple frames, the last cell is returned
def init_file(mode, filename, dimension="length", units="automatic", cell_units="automatic"): """Reads a @mode file and returns the data contained in it. Args: mode: Type of file that should be read. filename: A string giving the name of the pdb file to be read from. Returns: A list of Atoms objects as read from each frame of the pdb file, and a Cell object as read from the final pdb frame. """ rfile = open(filename, "r") ratoms = [] info( " # Initializing from file %s. Dimension: %s, units: %s, cell_units: %s" % (filename, dimension, units, cell_units), verbosity.low) while True: # while loop, so that more than one configuration can be given # so multiple beads can be initialized at once. try: ret = read_file(mode, rfile, dimension=dimension, units=units, cell_units=cell_units) except EOFError: break ratoms.append(ret["atoms"]) return ratoms, ret["cell"] # if multiple frames, the last cell is returned
def test_read_file(prepare_read_file): file_type, filedesc, output_type, expected_q, expected_cell, expected_names, unit_conv_cell, unit_conv_q = prepare_read_file returned_q = np.array([]) returned_cell = np.array([]) returned_names = [] while True: try: output = io.read_file(file_type, filedesc, output=output_type) except EOFError: break if output_type.strip() != 'objects': returned_q = np.concatenate([returned_q, output['data']]) returned_cell = output['cell'].flatten() elif output_type.strip() == 'objects': returned_q = np.concatenate([returned_q, output['atoms'].q]) returned_cell = output['cell'].h.flatten() returned_names += output['atoms'].names.tolist() npt.assert_almost_equal(expected_q * unit_conv_q, returned_q, 5) npt.assert_almost_equal(expected_cell.flatten() * unit_conv_cell, returned_cell, 5) if output_type.strip() == 'objects': assert all([expected_names[_ii] == returned_names[_ii] for _ii in xrange(len(expected_names))])
def main(filename, imode, omode): ipos = open(filename, "r") ifr = 0 # extracts the dimension, its units and the cell_units from the first frame ret = read_file_raw(imode, ipos) ipos.close() comment = ret["comment"] cell_units = get_cell_units(comment, imode) key, dim, dim_units = get_key_dim_units(comment, imode) ipos = open(filename, "r") while True: try: ret = read_file(imode, ipos) pos = ret["atoms"] cell = ret["cell"] except EOFError: # finished reading files sys.exit(0) print_file( omode, pos, cell, filedesc=sys.stdout, title="", key=key, dimension=dim, units=dim_units, cell_units=cell_units, ) ifr += 1
def __init__( self, latency=1.0e-3, name="", pars=None, dopbc=False, threaded=False, init_file="", plumeddat="", plumedstep=0, ): """Initialises FFPlumed. Args: pars: Optional dictionary, giving the parameters needed by the driver. """ # a socket to the communication library is created or linked if plumed is None: raise ImportError( "Cannot find plumed libraries to link to a FFPlumed object/") super(FFPlumed, self).__init__(latency, name, pars, dopbc=False, threaded=threaded) self.plumed = plumed.Plumed() self.plumeddat = plumeddat self.plumedstep = plumedstep self.init_file = init_file if self.init_file.mode == "xyz": infile = open(self.init_file.value, "r") myframe = read_file(self.init_file.mode, infile) myatoms = myframe["atoms"] mycell = myframe["cell"] myatoms.q *= unit_to_internal("length", self.init_file.units, 1.0) mycell.h *= unit_to_internal("length", self.init_file.units, 1.0) self.natoms = myatoms.natoms self.plumed.cmd("setNatoms", self.natoms) self.plumed.cmd("setPlumedDat", self.plumeddat) self.plumed.cmd("setTimestep", 1.0) self.plumed.cmd( "setMDEnergyUnits", 2625.4996 ) # Pass a pointer to the conversion factor between the energy unit used in your code and kJ mol-1 self.plumed.cmd( "setMDLengthUnits", 0.052917721 ) # Pass a pointer to the conversion factor between the length unit used in your code and nm self.plumed.cmd("setMDTimeUnits", 2.4188843e-05) self.plumedrestart = False if self.plumedstep > 0: # we are restarting, signal that PLUMED should continue self.plumedrestart = True self.plumed.cmd("setRestart", 1) self.plumed.cmd("init") self.charges = dstrip(myatoms.q) * 0.0 self.masses = dstrip(myatoms.m) self.lastq = np.zeros(3 * self.natoms)
def test_read_xyz2(): """Tests that mode/xyz files are read correctly.""" with open(local("test.pos_0.xyz"), "r") as f: ret = read_file("xyz", f) atoms = ret["atoms"] assert len(atoms) == 3 assert_equal(pos_xyz, atoms.q)
def test_read_pdb(): """Tests that pdb files are read correctly.""" with open(local("test.pos_0.pdb"), "r") as f: ret = read_file("pdb", f) atoms = ret["atoms"] assert len(atoms) == 3 assert_equal(pos_pdb, atoms.q)
def test_read_pdb(): """Tests that pdb files are read correctly.""" with open(local("test.pos_0.pdb"), "r") as f: ret = read_file("pdb", f) atoms = ret["atoms"] assert len(atoms) == 3 assert_equal(pos_pdb, atoms.q)
def test_read_xyz2(): """Tests that mode/xyz files are read correctly.""" with open(local("test.pos_0.xyz"), "r") as f: ret = read_file("xyz", f) atoms = ret["atoms"] assert len(atoms) == 3 assert_equal(pos_xyz, atoms.q)
def main(filename, natoms): ipos=open(filename,"r") imode=filename[-3:] natoms = int(natoms) ifr = 0 nn = 2.5 while True: try: ret = read_file(imode,ipos,readcell=True) pos = ret["atoms"] cell = ret["cell"] q=depstrip(pos.q).copy() cell.array_pbc(q) natin = pos.natoms q.shape=(natin,3) s=np.dot(depstrip(cell.ih),q.T).T # now replicate in scaled coordinates nrep = int((natoms/natin*nn)**(1./3.)) natrep = natin*(2*nrep+1)**3 ns = np.zeros((natrep,3)) ik = 0 for ix in range(-nrep,nrep+1): for iy in range(-nrep,nrep+1): for iz in range(-nrep,nrep+1): for i in range(natin): ns[ik] = s[i]+[ix,iy,iz] ik+=1 ns = np.dot(depstrip(cell.h),ns.T).T # now removes atoms until we only have natoms d = np.zeros(natrep) for i in range(natrep): d[i] = np.sqrt(np.dot(ns[i],ns[i])) di = np.argsort(d) npos = Atoms(natoms) for i in range(natoms): npos.q[3*i:3*(i+1)]=ns[di[i]] except EOFError: # finished reading files sys.exit(0) print_file("pdb",npos, cell) ifr+=1
def main(filename, natoms): ipos = open(filename, "r") imode = filename[-3:] natoms = int(natoms) ifr = 0 nn = 2.5 while True: try: ret = read_file(imode, ipos, readcell=True) pos = ret["atoms"] cell = ret["cell"] q = depstrip(pos.q).copy() cell.array_pbc(q) natin = pos.natoms q.shape = (natin, 3) s = np.dot(depstrip(cell.ih), q.T).T # now replicate in scaled coordinates nrep = int((natoms / natin * nn)**(1. / 3.)) natrep = natin * (2 * nrep + 1)**3 ns = np.zeros((natrep, 3)) ik = 0 for ix in range(-nrep, nrep + 1): for iy in range(-nrep, nrep + 1): for iz in range(-nrep, nrep + 1): for i in range(natin): ns[ik] = s[i] + [ix, iy, iz] ik += 1 ns = np.dot(depstrip(cell.h), ns.T).T # now removes atoms until we only have natoms d = np.zeros(natrep) for i in range(natrep): d[i] = np.sqrt(np.dot(ns[i], ns[i])) di = np.argsort(d) npos = Atoms(natoms) for i in range(natoms): npos.q[3 * i:3 * (i + 1)] = ns[di[i]] except EOFError: # finished reading files sys.exit(0) print_file("pdb", npos, cell) ifr += 1
def main(filename): ipos = open(filename, "rb") ifr = 0 while True: try: ret = read_file("bin", ipos) pos = ret["atoms"] cell = ret["cell"] cell.array_pbc(pos.q) except EOFError: # finished reading files sys.exit(0) print_file("xyz", pos, cell) ifr += 1
def main(filename): ipos = open(filename, "r") natoms = 0 ifr = 0 while True: try: ret = read_file("xyz", ipos) pos = ret["atoms"] cell = ret["cell"] cell.array_pbc(pos.q) except EOFError: # finished reading files sys.exit(0) print_file("bin", pos, cell) ifr += 1
def main(filename, wrap=True): ipos = open(filename, "r") if (wrap == "False"): wrap = False natoms = 0 ifr = 0 while True: try: ret = read_file("xyz", ipos, readcell=True) pos = ret["atoms"] cell = ret["cell"] if (wrap): cell.array_pbc(pos.q) except EOFError: # finished reading files sys.exit(0) print_file("pdb", pos, cell) ifr += 1
def main(filename, wrap=True): ipos = open(filename, "r") if(wrap == "False"): wrap = False natoms = 0 ifr = 0 while True: try: ret = read_file("xyz", ipos) pos = ret["atoms"] cell = ret["cell"] if(wrap): cell.array_pbc(pos.q) except EOFError: # finished reading files sys.exit(0) print_file("pdb", pos, cell) ifr += 1
def __init__(self, latency=1.0e-3, name="", pars=None, dopbc=False, init_file="", plumeddat="", precision=8, plumedstep=0): """Initialises FFPlumed. Args: pars: Optional dictionary, giving the parameters needed by the driver. """ # a socket to the communication library is created or linked if plumed is None: raise ImportError("Cannot find plumed libraries to link to a FFPlumed object/") super(FFPlumed, self).__init__(latency, name, pars, dopbc=False) self.plumed = plumed.Plumed(precision) self.precision = precision self.plumeddat = plumeddat self.plumedstep = plumedstep self.init_file = init_file if self.init_file.mode == "xyz": infile = open(self.init_file.value, "r") myframe = read_file(self.init_file.mode, infile) myatoms = myframe['atoms'] mycell = myframe['cell'] myatoms.q *= unit_to_internal("length", self.init_file.units, 1.0) mycell.h *= unit_to_internal("length", self.init_file.units, 1.0) self.natoms = myatoms.natoms self.plumed.cmd("setNatoms", self.natoms) self.plumed.cmd("setPlumedDat", self.plumeddat) self.plumed.cmd("setTimestep", 1.) self.plumed.cmd("setMDEnergyUnits", 2625.4996) # Pass a pointer to the conversion factor between the energy unit used in your code and kJ mol-1 self.plumed.cmd("setMDLengthUnits", 0.052917721) # Pass a pointer to the conversion factor between the length unit used in your code and nm self.plumed.cmd("setMDTimeUnits", 2.4188843e-05) self.plumedrestart = False if self.plumedstep > 0: # we are restarting, signal that PLUMED should continue self.plumedrestart = True self.plumed.cmd("setRestart", 1) self.plumed.cmd("init") self.charges = dstrip(myatoms.q) * 0.0 self.masses = dstrip(myatoms.m) self.lastq = np.zeros(3 * self.natoms)
def init_file(mode, filename): """Reads a @mode file and returns the data contained in it. Args: mode: Type of file that should be read. filename: A string giving the name of the pdb file to be read from. Returns: A list of Atoms objects as read from each frame of the pdb file, and a Cell object as read from the final pdb frame. """ rfile = open(filename, "r") ratoms = [] while True: #while loop, so that more than one configuration can be given #so multiple beads can be initialized at once. try: ret = read_file(mode, rfile) except EOFError: break ratoms.append(ret["atoms"]) return ratoms, ret["cell"] # if multiple frames, the last cell is returned
def main(filename, imode, omode): ipos = open(filename, "r") natoms = 0 ifr = 0 # extracts the dimension, its units and the cell_units from the first frame ret = read_file_raw(imode, ipos) ipos.close() comment = ret['comment'] cell_units = get_cell_units(comment, imode) key, dim, dim_units = get_key_dim_units(comment, imode) ipos = open(filename, "r") while True: try: ret = read_file(imode, ipos) pos = ret["atoms"] cell = ret["cell"] except EOFError: # finished reading files sys.exit(0) print_file(omode, pos, cell, filedesc=sys.stdout, title="", key=key, dimension=dim, units=dim_units, cell_units=cell_units) ifr += 1
def totalEnergy(prefix, temp, ss=0, unit=''): """ Computes the virial centroid estimator for the total energy and PPI correction. """ # Adding fortran functions (when exist) sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90') fast_code = True try: import fortran except: fast_code = False print('WARNING: No compiled fortran module for fast calculations have been found.\n' 'Calculations will use a slower python script.') temperature = unit_to_internal("temperature", "kelvin", float(temp)) # simulation temperature skipSteps = int(ss) # steps to skip for thermalization f2_av, ePA_av, eVir_av, f2ePA_av = 0.0, 0.0, 0.0, 0.0 # some required sums fns_pos = sorted(glob.glob(prefix + ".pos*")) fns_for = sorted(glob.glob(prefix + ".for*")) fns_iU = glob.glob(prefix + ".out")[0] fn_out_en = prefix + ".total_energy.dat" # check that we found the same number of positions and forces files nbeads = len(fns_pos) if nbeads != len(fns_for): print fns_pos print fns_for raise ValueError("Mismatch between number of input files for forces and positions.") # print some information print 'temperature = {:f} K'.format(float(temp)) print print 'number of beads = {:d}'.format(nbeads) print print 'positions and forces file names:' for fn_pos, fn_for in zip(fns_pos, fns_for): print '{:s} {:s}'.format(fn_pos, fn_for) print print 'potential energy file: {:s}'.format(fns_iU) print print 'output file name:' print fn_out_en print # open input and output files ipos = [open(fn, "r") for fn in fns_pos] ifor = [open(fn, "r") for fn in fns_for] iU = open(fns_iU, "r") iE = open(fn_out_en, "w") # Some constants beta = 1.0 / (Constants.kb * temperature) const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2 const_2 = 1.5 * nbeads / beta const_3 = 1.5 / beta const_4 = Constants.kb**2 / Constants.hbar**2 const_5 = Constants.hbar**2 * beta**3 / (24.0 * nbeads**3) timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits(iU) # extracting simulation time # and potential energy units # Defining the output energy unit if unit == '': unit = potentialEnergyUnit iE.write("# Simulation time (in %s), virial total energy and PPI energy correction (in %s)\n" % (timeUnit, unit)) natoms = 0 ifr = 0 time0 = 0 q, f, m = None, None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print '\rProcessing frame {:d}'.format(ifr), sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ipos[i], output='arrays') if natoms == 0: m, natoms = ret["masses"], ret["natoms"] q = np.zeros((nbeads, 3 * natoms)) f = np.zeros((nbeads, 3 * natoms)) q[i, :] = ret["data"] f[i, :] = read_file("xyz", ifor[i], output='arrays')["data"] U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index) except EOFError: # finished reading files sys.exit(0) if ifr < skipSteps: time0 = time if ifr >= skipSteps: # PPI correction time -= time0 ePA, f2, f2ePA, eVir = 0.0, 0.0, 0.0, 0.0 if not fast_code: for j in range(nbeads): for i in range(natoms): f2 += np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i] for i in range(natoms): ePA -= np.dot(q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3]) * m[i] for j in range(nbeads - 1): for i in range(natoms): ePA -= np.dot(q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3]) * m[i] rc = np.zeros(3) for i in range(natoms): rc[:] = 0.0 for j in range(nbeads): rc[:] += q[j, i * 3:i * 3 + 3] rc[:] /= nbeads for j in range(nbeads): eVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) ePA *= const_1 ePA += const_2 * natoms + U f2ePA = f2 * ePA eVir /= 2.0 * nbeads eVir += const_3 * natoms + U else: f2 = fortran.f2divm(np.array(f, order='F'), np.array(m, order='F'), natoms, nbeads) ePA = fortran.findcoupling(np.array(q, order='F'), np.array(m, order='F'), temperature, natoms, nbeads) eVir = fortran.findcentroidvirialkineticenergy(np.array(f, order='F'), np.array(q, order='F'), natoms, nbeads) ePA *= const_4 ePA += const_2 * natoms + U f2ePA = f2 * ePA eVir += const_3 * natoms + U ePA_av += ePA f2_av += f2 f2ePA_av += f2ePA eVir_av += eVir ifr += 1 norm = float(ifr - skipSteps) dE = (3.0 * Constants.kb * temperature + ePA_av / norm) * f2_av / norm - f2ePA_av / norm dE *= const_5 dE = unit_to_user("energy", unit, dE) eVir = unit_to_user("energy", unit, eVir_av / norm) iE.write("%f %f %f\n" % (time, eVir, dE)) else: ifr += 1
def RDF(prefix, temp, A, B, nbins, r_min, r_max, ss=0, unit='angstrom'): # Adding fortran functions (when exist) sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90') try: import fortran except: print( 'WARNING: No compiled fortran module for fast calculations have been found.\n' 'Proceeding the calculations is not possible.') sys.exit(0) temperature = unit_to_internal("temperature", "kelvin", float(temp)) # simulation temperature skipSteps = int(ss) # steps to skip nbins = int(nbins) fns_pos = sorted(glob.glob(prefix + ".pos*")) fns_for = sorted(glob.glob(prefix + ".for*")) fn_out_rdf, fn_out_rdf_q = prefix + '.' + A + B + ".rdf.dat", prefix + '.' + A + B + ".rdf-ppi.dat" # check that we found the same number of positions and forces files nbeads = len(fns_pos) if nbeads != len(fns_for): print fns_pos print fns_for raise ValueError( "Mismatch between number of input files for forces and positions.") # print some information print 'temperature = {:f} K'.format(float(temp)) print print 'number of beads = {:d}'.format(nbeads) print print 'positions and forces file names:' for fn_pos, fn_for in zip(fns_pos, fns_for): print '{:s} {:s}'.format(fn_pos, fn_for) print print 'output file names:' print fn_out_rdf print fn_out_rdf_q print # open input and output files ipos = [open(fn, "r") for fn in fns_pos] ifor = [open(fn, "r") for fn in fns_for] #iRDF, iRDFq = open(fn_out_rdf, "w"), open(fn_out_rdf_q, "w") # Species for RDF species = (A, B) speciesMass = np.array( [Elements.mass(species[0]), Elements.mass(species[1])], order='F') r_min = unit_to_internal('length', unit, float(r_min)) # Minimal distance for RDF r_max = unit_to_internal('length', unit, float(r_max)) # Maximal distance for RDF dr = (r_max - r_min) / nbins # RDF step rdf = np.array([[r_min + (0.5 + i) * dr, 0] for i in range(nbins)], order='F') # conventional RDF # RDF auxiliary variables cell = None # simulation cell matrix inverseCell = None # inverse simulation sell matrix cellVolume = None # simulation cell volume natomsA = 0 # the total number of A type particles in the system natomsB = 0 # the total number of B type particles in the system # Here A and B are the types of elements used for RDF calculations # temp variables f2 = 0.0 # the sum of square forces divided by corresponding masses (f2/m) f2rdf = np.zeros( nbins, order='F') # the sum f2/m multiplied by the rdf at each time step frdf = np.zeros( nbins, order='F' ) # the sum of f/m multiplied by the rdf derivative at each time step natoms = 0 # total number of atoms ifr = 0 # time frame number pos, force, mass = None, None, None # positions, forces, and mass arrays noteof = True # end of file test variable while noteof: # Reading input files and calculating PPI correction if ifr % 100 == 0: print '\rProcessing frame {:d}'.format(ifr), sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ipos[i]) if natoms == 0: mass, natoms = ret["atoms"].m, ret["atoms"].natoms pos = np.zeros((nbeads, 3 * natoms), order='F') force = np.zeros((nbeads, 3 * natoms), order='F') cell = ret["cell"].h inverseCell = ret["cell"].get_ih() cellVolume = ret["cell"].get_volume() pos[i, :] = ret["atoms"].q force[i, :] = read_file("xyz", ifor[i])["atoms"].q except EOFError: # finished reading files noteof = False if noteof: if ifr >= skipSteps: # RDF calculations species_A = [ 3 * i + j for i in np.where(mass == speciesMass[0])[0] for j in range(3) ] species_B = [ 3 * i + j for i in np.where(mass == speciesMass[1])[0] for j in range(3) ] natomsA = len(species_A) natomsB = len(species_B) posA = np.zeros((nbeads, natomsA), order='F') posB = np.zeros((nbeads, natomsB), order='F') forA = np.zeros((nbeads, natomsA), order='F') forB = np.zeros((nbeads, natomsB), order='F') for bead in range(nbeads): posA[bead, :] = pos[bead, species_A] forA[bead, :] = force[bead, species_A] posB[bead, :] = pos[bead, species_B] forB[bead, :] = force[bead, species_B] # RDF amd PPI RDF calculations f2temp = fortran.f2divm(force, mass, natoms, nbeads) f2 += f2temp fortran.updateqrdf(rdf, f2rdf, frdf, posA, posB, forA, forB, natomsA / 3, natomsB / 3, nbins, r_min, r_max, cell, inverseCell, nbeads, f2temp, speciesMass[0], speciesMass[1]) ifr += 1 else: ifr += 1 # Some constants const = 1.0 / float(ifr - skipSteps) alpha = Constants.hbar**2 / (24.0 * nbeads**3 * (temperature * Constants.kb)**3) beta = Constants.hbar**2 / (12.0 * nbeads**3 * (temperature * Constants.kb)**2) # Normalization rdf[:, 1] *= const / nbeads f2 *= alpha * const f2rdf[:] *= alpha * const frdf[:] *= beta * const # PPI correction rdfQ = np.copy(rdf) for bin in range(nbins): rdfQ[bin, 1] += (rdf[bin, 1] * f2 - f2rdf[bin] / nbeads) rdfQ[bin, 1] -= frdf[bin] / 2.0 # Creating RDF from N(r) const, dr = cellVolume / (4 * np.pi / 3.0), rdf[1, 0] - rdf[0, 0] for bin in range(nbins): rdf[bin, 1] = const * rdf[bin, 1] / ((rdf[bin, 0] + 0.5 * dr)**3 - (rdf[bin, 0] - 0.5 * dr)**3) rdfQ[bin, 1] = const * rdfQ[bin, 1] / ((rdfQ[bin, 0] + 0.5 * dr)**3 - (rdfQ[bin, 0] - 0.5 * dr)**3) for bin in range(nbins): rdf[bin, 0] = unit_to_user('length', unit, rdf[bin, 0]) rdfQ[bin, 0] = unit_to_user('length', unit, rdfQ[bin, 0]) # Writing the results into files np.savetxt(fn_out_rdf, rdf) np.savetxt(fn_out_rdf_q, rdfQ)
def heat_capacity(prefix, temp, ss=0): """ Computes a virial centroid estimator for the heat capacity and PPI correction. """ # Adding fortran functions (when exist) sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90') fast_code = True try: import fortran except: fast_code = False print( 'WARNING: No compiled fortran module for fast calculations have been found.\n' 'Calculations will use a slower python script.') temperature = unit_to_internal("temperature", "kelvin", float(temp)) # simulation temperature skipSteps = int(ss) # steps to skip for thermalization # some required sums KPa_av, KVir_av, U_av, f2_av, f2KPa_av, f2U_av, EVir_av, EEVir_av, f2E_av, f2E2_av = \ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 fns_pos = sorted(glob.glob(prefix + ".pos*")) fns_for = sorted(glob.glob(prefix + ".for*")) fns_iU = glob.glob(prefix + ".out")[0] fn_out_en = prefix + ".heat_capacity.dat" # check that we found the same number of positions and forces files nbeads = len(fns_pos) if nbeads != len(fns_for): print fns_pos print fns_for raise ValueError( "Mismatch between number of input files for forces and positions.") # print some information print 'temperature = {:f} K'.format(float(temp)) print print 'number of beads = {:d}'.format(nbeads) print print 'positions and forces file names:' for fn_pos, fn_for in zip(fns_pos, fns_for): print '{:s} {:s}'.format(fn_pos, fn_for) print print 'potential energy file: {:s}'.format(fns_iU) print print 'output file name:' print fn_out_en print # open input and output files ipos = [open(fn, "r") for fn in fns_pos] ifor = [open(fn, "r") for fn in fns_for] iU = open(fns_iU, "r") iC = open(fn_out_en, "w") # Some constants beta = 1.0 / (Constants.kb * temperature) const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2 const_2 = 1.5 * nbeads / beta const_3 = 1.5 / beta const_4 = Constants.kb**2 / Constants.hbar**2 const_5 = Constants.hbar**2 * beta**3 / (24.0 * nbeads**3) const_6 = Constants.hbar**2 * beta**2 / (24.0 * nbeads**3) const_7 = Constants.kb * beta**2 timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits( iU) # extracting simulation time # and potential energy units iC.write( "# Simulation time (in %s), centroid virial heat capacity estimator and PPI correction\n" % timeUnit) natoms = 0 ifr = 0 time0 = 0 q, f, m = None, None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print '\rProcessing frame {:d}'.format(ifr), sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ipos[i], output='arrays') if natoms == 0: m, natoms = ret["masses"], ret["natoms"] q = np.zeros((nbeads, 3 * natoms)) f = np.zeros((nbeads, 3 * natoms)) q[i, :] = ret["data"] f[i, :] = read_file("xyz", ifor[i], output='arrays')["data"] U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index) except EOFError: # finished reading files sys.exit(0) if ifr < skipSteps: time0 = time if ifr >= skipSteps: # PPI correction time -= time0 KPa, f2, KVir = 0.0, 0.0, 0.0 if not fast_code: for j in range(nbeads): for i in range(natoms): f2 += np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i] for i in range(natoms): KPa -= np.dot( q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3]) * m[i] for j in range(nbeads - 1): for i in range(natoms): KPa -= np.dot( q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3]) * m[i] rc = np.zeros(3) for i in range(natoms): rc[:] = 0.0 for j in range(nbeads): rc[:] += q[j, i * 3:i * 3 + 3] rc[:] /= nbeads for j in range(nbeads): KVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) KPa *= const_1 KPa += const_2 * natoms KVir /= 2.0 * nbeads KVir += const_3 * natoms else: f2 = fortran.f2divm(np.array(f, order='F'), np.array(m, order='F'), natoms, nbeads) KPa = fortran.findcoupling(np.array(q, order='F'), np.array(m, order='F'), temperature, natoms, nbeads) KVir = fortran.findcentroidvirialkineticenergy( np.array(f, order='F'), np.array(q, order='F'), natoms, nbeads) KPa *= const_4 KPa += const_2 * natoms KVir += const_3 * natoms f2_av += f2 KPa_av += KPa f2KPa_av += f2 * KPa U_av += U f2U_av += f2 * U KVir_av += KVir EVir_av += KVir + U EEVir_av += (KVir + U) * (KPa + U) f2E_av += f2 * (KPa + U) f2E2_av += f2 * (KPa + U)**2 ifr += 1 norm = float(ifr - skipSteps) dU = 2 * f2_av / norm - beta * (f2U_av / norm - f2_av * U_av / norm**2) dU *= const_6 dK = (Constants.kb * temperature + KPa_av / norm) * f2_av / norm - f2KPa_av / norm dK *= const_5 C = EEVir_av / norm - (EVir_av / norm)**2 + 1.5 * natoms / beta**2 C *= const_7 dC = (10 + C + 3*beta*EVir_av/norm)*beta*f2_av*const_6/norm - \ (6 + beta*EVir_av/norm)*beta*(dK + dU) + 2*beta*dK - \ const_6*(f2E2_av/norm - f2E_av*(KPa_av + U_av)/norm**2)*beta**3 iC.write("%f %f %f\n" % (time, C, dC)) else: ifr += 1
def get_atoms(fin): """Reads atoms object from file @fin.""" with open(local(fin), "r") as f: ret = read_file("xyz", f) return ret["atoms"]
def energies(prefix, temp, ss=0, unit=''): """ Computes the virial centroid estimator for the total energy and PPI correction. """ # Adding fortran functions (when exist) sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90') fast_code = True try: import fortran except: fast_code = False print('WARNING: No compiled fortran module for fast calculations have been found.\n' 'Calculations will use a slower python script.') temperature = unit_to_internal("temperature", "kelvin", float(temp)) # simulation temperature skipSteps = int(ss) # steps to skip for thermalization KPa_av, KVir_av, U_av, f2_av, f2KPa_av, f2U_av = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 # some required sums fns_pos = sorted(glob.glob(prefix + ".pos*")) fns_for = sorted(glob.glob(prefix + ".for*")) fns_iU = glob.glob(prefix + ".out")[0] fn_out_en = prefix + ".energies.dat" # check that we found the same number of positions and forces files nbeads = len(fns_pos) if nbeads != len(fns_for): print fns_pos print fns_for raise ValueError("Mismatch between number of input files for forces and positions.") # print some information print 'temperature = {:f} K'.format(float(temp)) print print 'number of beads = {:d}'.format(nbeads) print print 'positions and forces file names:' for fn_pos, fn_for in zip(fns_pos, fns_for): print '{:s} {:s}'.format(fn_pos, fn_for) print print 'potential energy file: {:s}'.format(fns_iU) print print 'output file name:' print fn_out_en print # open input and output files ipos = [open(fn, "r") for fn in fns_pos] ifor = [open(fn, "r") for fn in fns_for] iU = open(fns_iU, "r") iE = open(fn_out_en, "w") # Some constants beta = 1.0 / (Constants.kb * temperature) const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2 const_2 = 1.5 * nbeads / beta const_3 = 1.5 / beta const_4 = Constants.kb**2 / Constants.hbar**2 const_5 = Constants.hbar**2 * beta**3 / (24.0 * nbeads**3) const_6 = Constants.hbar**2 * beta**2 / (24.0 * nbeads**3) timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits(iU) # extracting simulation time # and potential energy units # Defining the output energy unit if unit == '': unit = potentialEnergyUnit iE.write("# Simulation time (in %s), improved total energy estimator, virial total energy estimator, and PPI " "correction for the total energy; improved potential energy estimator, potential energy estimatorand, " "PPI correction for the potential energy; improved kinetic energy estimator, virial kinetic energy " "estimator, and PPI correction for the kinetic energy (all in %s)\n" % (timeUnit, unit)) iE.close() natoms = 0 ifr = 0 time0 = 0 q, f, m = None, None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print '\rProcessing frame {:d}'.format(ifr), sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ipos[i], dimension='length')["atoms"] if natoms == 0: m, natoms = ret.m, ret.natoms q = np.zeros((nbeads, 3 * natoms)) f = np.zeros((nbeads, 3 * natoms)) q[i, :] = ret.q f[i, :] = read_file("xyz", ifor[i], dimension='force')["atoms"].q U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index) except EOFError: # finished reading files sys.exit(0) if ifr < skipSteps: time0 = time if ifr >= skipSteps: # PPI correction time -= time0 KPa, f2, KVir = 0.0, 0.0, 0.0 if not fast_code: for j in range(nbeads): for i in range(natoms): f2 += np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i] for i in range(natoms): KPa -= np.dot(q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3]) * m[i] for j in range(nbeads - 1): for i in range(natoms): KPa -= np.dot(q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3]) * m[i] rc = np.zeros(3) for i in range(natoms): rc[:] = 0.0 for j in range(nbeads): rc[:] += q[j, i * 3:i * 3 + 3] rc[:] /= nbeads for j in range(nbeads): KVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) KPa *= const_1 KPa += const_2 * natoms KVir /= 2.0 * nbeads KVir += const_3 * natoms else: f2 = fortran.f2divm(np.array(f, order='F'), np.array(m, order='F'), natoms, nbeads) KPa = fortran.findcoupling(np.array(q, order='F'), np.array(m, order='F'), temperature, natoms, nbeads) KVir = fortran.findcentroidvirialkineticenergy(np.array(f, order='F'), np.array(q, order='F'), natoms, nbeads) KPa *= const_4 KPa += const_2 * natoms KVir += const_3 * natoms f2_av += f2 KPa_av += KPa f2KPa_av += f2 * KPa U_av += U f2U_av += f2 * U KVir_av += KVir ifr += 1 norm = float(ifr - skipSteps) dU = 2 * f2_av / norm - beta * (f2U_av / norm - f2_av * U_av / norm**2) dU *= const_6 dU = unit_to_user("energy", unit, dU) dK = (Constants.kb * temperature + KPa_av / norm) * f2_av / norm - f2KPa_av / norm dK *= const_5 dK = unit_to_user("energy", unit, dK) U = unit_to_user("energy", unit, U_av / norm) KVir = unit_to_user("energy", unit, KVir_av / norm) iE = open(fn_out_en, "a") iE.write("%f %f %f %f %f %f %f %f %f %f\n" % (time, KVir + U + dK + dU, KVir + U, dK + dU, U + dU, U, dU, KVir + dK, KVir, dK)) iE.close() else: ifr += 1
def heatCapacity(prefix, temp, ss=0): """ Computes a primitive estimator for the heat capacity and PPI correction. """ # Adding fortran functions (when exist) sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + "f90") fast_code = True try: import fortran except ImportError: fast_code = False print( "WARNING: No compiled fortran module for fast calculations have been found.\n" "Calculations will use a slower python script." ) temperature = unit_to_internal( "temperature", "kelvin", float(temp) ) # simulation temperature skipSteps = int(ss) # steps to skip for thermalization # some required sums KPa_av, U_av, f2_av, f2KPa_av, f2U_av, E2_av, f2E_av, f2E2_av = ( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ) fns_pos = sorted(glob.glob(prefix + ".pos*")) fns_for = sorted(glob.glob(prefix + ".for*")) fns_iU = glob.glob(prefix + ".out")[0] fn_out_en = prefix + ".heat_capacity.dat" # check that we found the same number of positions and forces files nbeads = len(fns_pos) if nbeads != len(fns_for): print(fns_pos) print(fns_for) raise ValueError( "Mismatch between number of input files for forces and positions." ) # print some information print("temperature = {:f} K".format(float(temp))) print() print("number of beads = {:d}".format(nbeads)) print() print("positions and forces file names:") for fn_pos, fn_for in zip(fns_pos, fns_for): print("{:s} {:s}".format(fn_pos, fn_for)) print() print("potential energy file: {:s}".format(fns_iU)) print() print("output file name:") print(fn_out_en) print() # open input and output files ipos = [open(fn, "r") for fn in fns_pos] ifor = [open(fn, "r") for fn in fns_for] iU = open(fns_iU, "r") iC = open(fn_out_en, "w") # Some constants beta = 1.0 / (Constants.kb * temperature) const_1 = 0.5 * nbeads / (beta * Constants.hbar) ** 2 const_2 = 1.5 * nbeads / beta const_3 = Constants.kb ** 2 / Constants.hbar ** 2 const_4 = Constants.hbar ** 2 * beta ** 2 / (24.0 * nbeads ** 3) const_5 = Constants.kb * beta ** 2 timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits( iU ) # extracting simulation time # and potential energy units iC.write( "# Simulation time (in %s), improved heat capacity estimator, primitive heat capacity estimator, " "and PPI correction for the heat capacity\n" % timeUnit ) iC.close() natoms = 0 ifr = 0 time0 = 0 q, f, m = None, None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print("\rProcessing frame {:d}".format(ifr), end=" ") sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ipos[i], dimension="length")["atoms"] if natoms == 0: m, natoms = ret.m, ret.natoms q = np.zeros((nbeads, 3 * natoms)) f = np.zeros((nbeads, 3 * natoms)) q[i, :] = ret.q f[i, :] = read_file("xyz", ifor[i], dimension="force")["atoms"].q U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index) except EOFError: # finished reading files sys.exit(0) if ifr < skipSteps: time0 = time if ifr >= skipSteps: # PPI correction time -= time0 KPa, f2 = 0.0, 0.0 if not fast_code: for j in range(nbeads): for i in range(natoms): f2 += ( np.dot(f[j, i * 3 : i * 3 + 3], f[j, i * 3 : i * 3 + 3]) / m[i] ) for i in range(natoms): KPa -= ( np.dot( q[0, i * 3 : i * 3 + 3] - q[nbeads - 1, i * 3 : i * 3 + 3], q[0, i * 3 : i * 3 + 3] - q[nbeads - 1, i * 3 : i * 3 + 3], ) * m[i] ) for j in range(nbeads - 1): for i in range(natoms): KPa -= ( np.dot( q[j + 1, i * 3 : i * 3 + 3] - q[j, i * 3 : i * 3 + 3], q[j + 1, i * 3 : i * 3 + 3] - q[j, i * 3 : i * 3 + 3], ) * m[i] ) KPa *= const_1 KPa += const_2 * natoms else: f2 = fortran.f2divm( np.array(f, order="F"), np.array(m, order="F"), natoms, nbeads ) KPa = fortran.findcoupling( np.array(q, order="F"), np.array(m, order="F"), temperature, natoms, nbeads, ) KPa *= const_3 KPa += const_2 * natoms f2_av += f2 KPa_av += KPa f2KPa_av += f2 * KPa U_av += U f2U_av += f2 * U E2_av += (KPa + U) ** 2 f2E2_av += f2 * (KPa + U) ** 2 ifr += 1 norm = float(ifr - skipSteps) dU = 2 * f2_av / norm - beta * (f2U_av / norm - f2_av * U_av / norm ** 2) dU *= const_4 dK = f2_av / norm - beta * (f2KPa_av / norm - f2_av * KPa_av / norm ** 2) dK *= const_4 C = ( E2_av / norm - ((KPa_av + U_av) / norm) ** 2 + (2.0 / beta) * KPa_av / norm - 1.5 * nbeads * natoms / beta ** 2 ) C *= const_5 dC = ( 2 * (5 + 3 * beta * (KPa_av + U_av) / norm) * beta * f2_av * const_4 / norm - 2 * (3 + beta * (KPa_av + U_av) / norm) * beta * (dK + dU) + 2 * beta * dK - const_4 * (f2E2_av / norm - f2_av * E2_av / norm ** 2) * beta ** 3 ) iC = open(fn_out_en, "a") iC.write("%f %f %f %f\n" % (time, C + dC, C, dC)) iC.close() else: ifr += 1
def kineticEnergy(prefix, temp, ss=0, unit=""): """ Computes the virial centroid estimator for the kinetic energy and PPI correction. """ # Adding fortran functions (when exist) sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + "f90") fast_code = True try: import fortran except ImportError: fast_code = False print( "WARNING: No compiled fortran module for fast calculations have been found.\n" "Calculations will use a slower python script.") temperature = unit_to_internal("temperature", "kelvin", float(temp)) # simulation temperature skipSteps = int(ss) # steps to skip for thermalization f2_av, KPa_av, KVir_av, f2KPa_av = 0.0, 0.0, 0.0, 0.0 # some required sums fns_pos = sorted(glob.glob(prefix + ".pos*")) fns_for = sorted(glob.glob(prefix + ".for*")) fns_iU = glob.glob(prefix + ".out")[0] fn_out_en = prefix + ".kinetic_energy.dat" # check that we found the same number of positions and forces files nbeads = len(fns_pos) if nbeads != len(fns_for): print(fns_pos) print(fns_for) raise ValueError( "Mismatch between number of input files for forces and positions.") # print some information print("temperature = {:f} K".format(float(temp))) print() print("number of beads = {:d}".format(nbeads)) print() print("positions and forces file names:") for fn_pos, fn_for in zip(fns_pos, fns_for): print("{:s} {:s}".format(fn_pos, fn_for)) print() print("potential energy file: {:s}".format(fns_iU)) print() print("output file name:") print(fn_out_en) print() # open input and output files ipos = [open(fn, "r") for fn in fns_pos] ifor = [open(fn, "r") for fn in fns_for] iU = open(fns_iU, "r") iE = open(fn_out_en, "w") # Some constants beta = 1.0 / (Constants.kb * temperature) const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2 const_2 = 1.5 * nbeads / beta const_3 = 1.5 / beta const_4 = Constants.kb**2 / Constants.hbar**2 const_5 = Constants.hbar**2 * beta**3 / (24.0 * nbeads**3) timeUnit, potentialEnergyUnit, time_index = extractUnits( iU) # extracting simulation time # and potential energy units # Defining the output energy unit if unit == "": unit = potentialEnergyUnit iE.write( "# Simulation time (in %s), virial kinetic energy and PPI kinetic energy corrections (in %s)\n" % (timeUnit, unit)) natoms = 0 ifr = 0 time0 = 0 q, f, m = None, None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print("\rProcessing frame {:d}".format(ifr), end=" ") sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ipos[i], output="arrays") if natoms == 0: m, natoms = ret["masses"], ret["natoms"] q = np.zeros((nbeads, 3 * natoms)) f = np.zeros((nbeads, 3 * natoms)) q[i, :] = ret["data"] f[i, :] = read_file("xyz", ifor[i], output="arrays")["data"] time = read_time(iU, time_index) except EOFError: # finished reading files sys.exit(0) if ifr < skipSteps: time0 = time if ifr >= skipSteps: # PPI correction time -= time0 KPa, f2, KVir = 0.0, 0.0, 0.0 if not fast_code: for j in range(nbeads): for i in range(natoms): f2 += (np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i]) for i in range(natoms): KPa -= (np.dot( q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], ) * m[i]) for j in range(nbeads - 1): for i in range(natoms): KPa -= (np.dot( q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], ) * m[i]) rc = np.zeros(3) for i in range(natoms): rc[:] = 0.0 for j in range(nbeads): rc[:] += q[j, i * 3:i * 3 + 3] rc[:] /= nbeads for j in range(nbeads): KVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) KPa *= const_1 KPa += const_2 * natoms KVir /= 2.0 * nbeads KVir += const_3 * natoms else: f2 = fortran.f2divm(np.array(f, order="F"), np.array(m, order="F"), natoms, nbeads) KPa = fortran.findcoupling( np.array(q, order="F"), np.array(m, order="F"), temperature, natoms, nbeads, ) KVir = fortran.findcentroidvirialkineticenergy( np.array(f, order="F"), np.array(q, order="F"), natoms, nbeads) KPa *= const_4 KPa += const_2 * natoms KVir += const_3 * natoms f2_av += f2 KPa_av += KPa f2KPa_av += f2 * KPa KVir_av += KVir ifr += 1 norm = float(ifr - skipSteps) dK = (Constants.kb * temperature + KPa_av / norm) * f2_av / norm - f2KPa_av / norm dK *= const_5 dK = unit_to_user("energy", unit, dK) eVir = unit_to_user("energy", unit, KVir_av / norm) iE.write("%f %f %f\n" % (time, eVir, dK)) else: ifr += 1
def get_atoms(fin): """Reads atoms object from file @fin.""" with open(local(fin), "r") as f: ret = read_file("xyz", f) return ret["atoms"]
def main(prefix, temp): T = float(temp) fns_pos = sorted(glob.glob(prefix + ".pos*")) fns_for = sorted(glob.glob(prefix + ".for*")) fn_out_kin = prefix + ".kin.xyz" fn_out_kod = prefix + ".kod.xyz" # check that we found the same number of positions and forces files nbeads = len(fns_pos) if nbeads != len(fns_for): print fns_pos print fns_for raise ValueError( "Mismatch between number of input files for forces and positions.") # print some information print 'temperature = {:f} K'.format(T) print print 'number of beads = {:d}'.format(nbeads) print print 'positions and forces file names:' for fn_pos, fn_for in zip(fns_pos, fns_for): print '{:s} {:s}'.format(fn_pos, fn_for) print print 'output file names:' print fn_out_kin print fn_out_kod print temp = unit_to_internal("energy", "kelvin", T) # open input and output files ipos = [open(fn, "r") for fn in fns_pos] ifor = [open(fn, "r") for fn in fns_for] ikin = open(fn_out_kin, "w") ikod = open(fn_out_kod, "w") natoms = 0 ifr = 0 while True: # print progress if ifr % 100 == 0: print '\rProcessing frame {:d}'.format(ifr), sys.stdout.flush() # load one frame try: for i in range(nbeads): ret = read_file("xyz", ipos[i]) pos = ret["atoms"] ret = read_file("xyz", ifor[i]) force = ret["atoms"] if natoms == 0: natoms = pos.natoms beads = Beads(natoms, nbeads) forces = Beads(natoms, nbeads) kcv = np.zeros((natoms, 6), float) beads[i].q = pos.q forces[i].q = force.q except EOFError: # finished reading files break # calculate kinetic energies q = dstrip(beads.q) f = dstrip(forces.q) qc = dstrip(beads.qc) kcv[:] = 0 for j in range(nbeads): for i in range(natoms): kcv[i, 0] += (q[j, i * 3 + 0] - qc[i * 3 + 0]) * f[j, i * 3 + 0] kcv[i, 1] += (q[j, i * 3 + 1] - qc[i * 3 + 1]) * f[j, i * 3 + 1] kcv[i, 2] += (q[j, i * 3 + 2] - qc[i * 3 + 2]) * f[j, i * 3 + 2] kcv[i, 3] += ( q[j, i * 3 + 0] - qc[i * 3 + 0]) * f[j, i * 3 + 1] + ( q[j, i * 3 + 1] - qc[i * 3 + 1]) * f[j, i * 3 + 0] kcv[i, 4] += ( q[j, i * 3 + 0] - qc[i * 3 + 0]) * f[j, i * 3 + 2] + ( q[j, i * 3 + 2] - qc[i * 3 + 2]) * f[j, i * 3 + 0] kcv[i, 5] += ( q[j, i * 3 + 1] - qc[i * 3 + 1]) * f[j, i * 3 + 2] + ( q[j, i * 3 + 2] - qc[i * 3 + 2]) * f[j, i * 3 + 1] kcv *= -0.5 / nbeads kcv[:, 0:3] += 0.5 * Constants.kb * temp kcv[:, 3:6] *= 0.5 # write output ikin.write( "%d\n# Centroid-virial kinetic energy estimator [a.u.] - diagonal terms: xx yy zz\n" % natoms) ikod.write( "%d\n# Centroid-virial kinetic energy estimator [a.u.] - off-diag terms: xy xz yz\n" % natoms) for i in range(natoms): ikin.write("%8s %12.5e %12.5e %12.5e\n" % (pos.names[i], kcv[i, 0], kcv[i, 1], kcv[i, 2])) ikod.write("%8s %12.5e %12.5e %12.5e\n" % (pos.names[i], kcv[i, 3], kcv[i, 4], kcv[i, 5])) ifr += 1 print '\rProcessed {:d} frames.'.format(ifr) ikin.close() ikod.close()
def totalEnergy(prefix, temp, ss=0): """ Computes the virial centroid estimator for the total energy and PPI correction. """ global temperature, skipSteps temperature = unit_to_internal("temperature", "kelvin", float(temp)) skipSteps = int(ss) f2_av, ePA_av, eVir_av, f2ePA_av = ( 0.0, 0.0, 0.0, 0.0, ) # average square forces, virial and primitive energy # estimators, and the product of the primitive energy estimator and square forces ipos = [] # input positions files for filename in sorted(glob.glob(prefix + ".pos*")): ipos.append(open(filename, "r")) ifor = [] # input forces files for filename in sorted(glob.glob(prefix + ".for*")): ifor.append(open(filename, "r")) iU = None # input potential energy and simulation time file for filename in sorted(glob.glob(prefix + ".out")): iU = open(filename, "r") global potentialEnergyUnit, timeUnit timeUnit, potentialEnergyUnit = extractUnits( iU) # extracting simulation time and potential energy units iE = open(prefix + ".energy" + ".dat", "w") iE.write( "# Simulation time (in %s), virial total energy and PPI energy correction (in %s)\n" % (timeUnit, potentialEnergyUnit)) nbeads = len(ipos) if nbeads != len(ifor): raise ValueError( "Mismatch between number of output files for forces and positions") natoms = 0 ifr = 0 time0 = 0 q, f, m = None, None, None while True: # Reading input files and calculating PPI correction try: for i in range(nbeads): ret = read_file("xyz", ipos[i]) m, n = ret["masses"], ret["atoms"].natoms pos = unit_to_internal(ret["units"][0], ret["units"][1], ret["atoms"].q) ret = read_file("xyz", ifor[i]) force = unit_to_internal(ret["units"][0], ret["units"][1], ret["atoms"].q) if natoms == 0: natoms = n q = np.zeros((nbeads, 3 * natoms)) f = np.zeros((nbeads, 3 * natoms)) q[i, :] = pos f[i, :] = force time, U = read_U(iU) except EOFError: # finished reading files sys.exit(0) if ifr < skipSteps: time0 = time if ifr >= skipSteps: # PPI correction time -= time0 ePA, f2, f2ePA = 0.0, 0.0, 0.0 eVir, rc = 0.0, np.zeros(3) for j in range(nbeads): for i in range(natoms): f2 += ( np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i]) for i in range(natoms): ePA -= (np.dot( q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], ) * m[i]) for j in range(nbeads - 1): for i in range(natoms): ePA -= (np.dot( q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], ) * m[i]) for i in range(natoms): rc[:] = 0.0 for j in range(nbeads): rc[:] += q[j, i * 3:i * 3 + 3] rc[:] /= nbeads for j in range(nbeads): eVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) ePA *= (0.5 * nbeads * (Constants.kb * temperature)**2 / Constants.hbar**2) ePA += 0.5 * nbeads * (3 * natoms) * Constants.kb * temperature + U f2ePA = f2 * ePA eVir /= 2.0 * nbeads eVir += 0.5 * (3 * natoms) * Constants.kb * temperature + U ePA_av += ePA f2_av += f2 f2ePA_av += f2ePA eVir_av += eVir ifr += 1 print((ifr - skipSteps )) # Printing current time frame (excluding thermalization) dE = (3.0 * Constants.kb * temperature + ePA_av / float(ifr - skipSteps)) * f2_av / float( ifr - skipSteps) - f2ePA_av / float(ifr - skipSteps) dE *= Constants.hbar**2 / ( 24.0 * (nbeads * Constants.kb * temperature)**3) dE = unit_to_user( "energy", potentialEnergyUnit, dE) # Output in the same unit as potential energy eVir = unit_to_user( "energy", potentialEnergyUnit, eVir_av / float(ifr - skipSteps)) # Output in the same unit # as potential energy iE.write("%f %f %f\n" % (time, eVir, dE)) else: ifr += 1
# OPEN AND READ ###########################################################3 if input_geo != 'None' or chk != 'None': if manual: if (os.path.exists(input_geo)): ipos = open(input_geo, "r") else: print "We can't find %s " % input_geo sys.exit() pos = list() nbeads = 0 while True: try: ret = read_file("xyz", ipos) pos.append(ret["atoms"]) cell = ret["cell"] nbeads += 1 except EOFError: # finished reading files break ipos.close() natoms = pos[0].natoms atom = pos[0] # Compose the half ring polymer. q = np.vstack([i.q for i in pos]) else: from ipi.engine.simulation import Simulation if (os.path.exists(chk)): simulation = Simulation.load_from_xml(chk,
def heatCapacity(prefix, temp, ss=0): """ Computes a primitive estimator for the heat capacity and PPI correction. """ # Adding fortran functions (when exist) sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90') fast_code = True try: import fortran except: fast_code = False print('WARNING: No compiled fortran module for fast calculations have been found.\n' 'Calculations will use a slower python script.') temperature = unit_to_internal("temperature", "kelvin", float(temp)) # simulation temperature skipSteps = int(ss) # steps to skip for thermalization # some required sums KPa_av, U_av, f2_av, f2KPa_av, f2U_av, E2_av, f2E_av, f2E2_av = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 fns_pos = sorted(glob.glob(prefix + ".pos*")) fns_for = sorted(glob.glob(prefix + ".for*")) fns_iU = glob.glob(prefix + ".out")[0] fn_out_en = prefix + ".heat_capacity.dat" # check that we found the same number of positions and forces files nbeads = len(fns_pos) if nbeads != len(fns_for): print fns_pos print fns_for raise ValueError("Mismatch between number of input files for forces and positions.") # print some information print 'temperature = {:f} K'.format(float(temp)) print print 'number of beads = {:d}'.format(nbeads) print print 'positions and forces file names:' for fn_pos, fn_for in zip(fns_pos, fns_for): print '{:s} {:s}'.format(fn_pos, fn_for) print print 'potential energy file: {:s}'.format(fns_iU) print print 'output file name:' print fn_out_en print # open input and output files ipos = [open(fn, "r") for fn in fns_pos] ifor = [open(fn, "r") for fn in fns_for] iU = open(fns_iU, "r") iC = open(fn_out_en, "w") # Some constants beta = 1.0 / (Constants.kb * temperature) const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2 const_2 = 1.5 * nbeads / beta const_3 = Constants.kb**2 / Constants.hbar**2 const_4 = Constants.hbar**2 * beta**2 / (24.0 * nbeads**3) const_5 = Constants.kb * beta**2 timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits(iU) # extracting simulation time # and potential energy units iC.write("# Simulation time (in %s), improved heat capacity estimator, primitive heat capacity estimator, " "and PPI correction for the heat capacity\n" % timeUnit) iC.close() natoms = 0 ifr = 0 time0 = 0 q, f, m = None, None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print '\rProcessing frame {:d}'.format(ifr), sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ipos[i], dimension='length')["atoms"] if natoms == 0: m, natoms = ret.m, ret.natoms q = np.zeros((nbeads, 3 * natoms)) f = np.zeros((nbeads, 3 * natoms)) q[i, :] = ret.q f[i, :] = read_file("xyz", ifor[i], dimension='force')["atoms"].q U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index) except EOFError: # finished reading files sys.exit(0) if ifr < skipSteps: time0 = time if ifr >= skipSteps: # PPI correction time -= time0 KPa, f2 = 0.0, 0.0 if not fast_code: for j in range(nbeads): for i in range(natoms): f2 += np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i] for i in range(natoms): KPa -= np.dot(q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3]) * m[i] for j in range(nbeads - 1): for i in range(natoms): KPa -= np.dot(q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3]) * m[i] KPa *= const_1 KPa += const_2 * natoms else: f2 = fortran.f2divm(np.array(f, order='F'), np.array(m, order='F'), natoms, nbeads) KPa = fortran.findcoupling(np.array(q, order='F'), np.array(m, order='F'), temperature, natoms, nbeads) KPa *= const_3 KPa += const_2 * natoms f2_av += f2 KPa_av += KPa f2KPa_av += f2 * KPa U_av += U f2U_av += f2 * U E2_av += (KPa + U)**2 f2E2_av += f2 * (KPa + U)**2 ifr += 1 norm = float(ifr - skipSteps) dU = 2 * f2_av / norm - beta * (f2U_av / norm - f2_av * U_av / norm**2) dU *= const_4 dK = f2_av / norm - beta * (f2KPa_av / norm - f2_av * KPa_av / norm**2) dK *= const_4 C = E2_av / norm - ((KPa_av + U_av) / norm)**2 + (2.0 / beta) * KPa_av / norm - 1.5 * nbeads * natoms / beta**2 C *= const_5 dC = 2 * (5 + 3 * beta * (KPa_av + U_av) / norm) * beta * f2_av * const_4 / norm - \ 2 * (3 + beta * (KPa_av + U_av) / norm) * beta * (dK + dU) + 2 * beta * dK - \ const_4 * (f2E2_av / norm - f2_av * E2_av / norm**2) * beta**3 iC = open(fn_out_en, "a") iC.write("%f %f %f %f\n" % (time, C + dC, C, dC)) iC.close() else: ifr += 1
def effectiveTemperatures(prefix, temp, ss=0): """ Computes effective temperatures for a given (PI)MD dynamics. """ temperature = unit_to_internal("temperature", "kelvin", float(temp)) # simulation temperature skipSteps = int(ss) # steps to skip for thermalization f2_av = None # average square forces array names = None fns_for = sorted(glob.glob(prefix + ".for*")) fn_out = prefix + ".effective_temperatures.dat" nbeads = len(fns_for) # print some information print 'temperature = {:f} K'.format(float(temp)) print print 'number of beads = {:d}'.format(nbeads) print print 'forces file names:' for fn_for in fns_for: print '{:s}'.format(fn_for) print print 'output file name:' print fn_out print # open input and output files ifor = [open(fn, "r") for fn in fns_for] iOut = open(fn_out, "w") # Some constants const = Constants.hbar**2 / (12.0 * (nbeads * Constants.kb * temperature)**3) iOut.write("# Atom, Cartesian components of the effective temperature, average effective temperature (in Kelvin)\n") natoms = 0 ifr = 0 f, m = None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print '\rProcessing frame {:d}'.format(ifr), sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ifor[i], dimension='force')["atoms"] if natoms == 0: m, natoms, names = ret.m, ret.natoms, ret.names f = np.zeros((nbeads, 3 * natoms)) f2_av = np.zeros(3 * natoms) f[i, :] = ret.q except EOFError: # finished reading files break if ifr >= skipSteps: # PPI correction f2 = np.zeros(3 * natoms) for i in range(natoms): for j in range(nbeads): f2[i * 3:i * 3 + 3] += f[j, i * 3:i * 3 + 3]**2 / m[i] f2_av[:] += f2[:] ifr += 1 else: ifr += 1 dT = const * f2_av / float(ifr - skipSteps) temperature = unit_to_user("temperature", "kelvin", temperature) for i in range(natoms): iOut.write("%s %f %f %f %f\n" % (names[i], temperature * (1 + dT[i * 3]), temperature * (1 + dT[i * 3 + 1]), temperature * (1 + dT[i * 3 + 2]), temperature * (1 + np.sum(dT[i * 3:i * 3 + 3]) / 3.0))) for f in ifor: f.close() iOut.close()
def potentialEnergy(prefix, temp, ss=0, unit=''): """ Computes the estimator for the potential energy and PPI correction. """ # Adding fortran functions (when exist) sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90') fast_code = True try: import fortran except: fast_code = False print( 'WARNING: No compiled fortran module for fast calculations have been found.\n' 'Calculations will use a slower python script.') temperature = unit_to_internal("temperature", "kelvin", float(temp)) # simulation temperature skipSteps = int(ss) # steps to skip for thermalization f2_av, U_av, f2U_av = 0.0, 0.0, 0.0 # some required sums fns_for = sorted(glob.glob(prefix + ".for*")) fns_iU = glob.glob(prefix + ".out")[0] fn_out_en = prefix + ".potential_energy.dat" # Extracting the number of beads nbeads = len(fns_for) # print some information print 'temperature = {:f} K'.format(float(temp)) print print 'number of beads = {:d}'.format(nbeads) print print 'forces file names:' for fn_for in fns_for: print '{:s}'.format(fn_for) print print 'potential energy file: {:s}'.format(fns_iU) print print 'output file name:' print fn_out_en print # open input and output files ifor = [open(fn, "r") for fn in fns_for] iU = open(fns_iU, "r") iE = open(fn_out_en, "w") # Some constants beta = 1.0 / (Constants.kb * temperature) const = Constants.hbar**2 * beta**2 / (24.0 * nbeads**3) timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits( iU) # extracting simulation time # and potential energy units # Defining the output energy unit if unit == '': unit = potentialEnergyUnit iE.write( "# Simulation time (in %s), potential energy and PPI potential energy corrections (in %s)\n" % (timeUnit, unit)) natoms = 0 ifr = 0 time0 = 0 f, m = None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print '\rProcessing frame {:d}'.format(ifr), sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ifor[i], output='arrays') if natoms == 0: m, natoms = ret["masses"], ret["natoms"] f = np.zeros((nbeads, 3 * natoms)) f[i, :] = ret["data"] U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index) except EOFError: # finished reading files sys.exit(0) if ifr < skipSteps: time0 = time if ifr >= skipSteps: # PPI correction time -= time0 f2 = 0.0 if not fast_code: for j in range(nbeads): for i in range(natoms): f2 += np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i] else: f2 = fortran.f2divm(np.array(f, order='F'), np.array(m, order='F'), natoms, nbeads) U_av += U f2_av += f2 f2U_av += f2 * U ifr += 1 norm = float(ifr - skipSteps) dU = 2.0 * f2_av / norm - beta * (f2U_av / norm - f2_av * U_av / norm**2) dU *= const dU = unit_to_user("energy", unit, dU) U = unit_to_user("energy", unit, U_av / float(ifr - skipSteps)) iE.write("%f %f %f\n" % (time, U, dU)) else: ifr += 1
def compute_acf(input_file, output_prefix, maximum_lag, block_length, length_zeropadding, spectral_windowing, labels, timestep, skip, der): # stores the arguments ifile = str(input_file) ofile = str(output_prefix) mlag = int(maximum_lag) bsize = int(block_length) npad = int(length_zeropadding) ftbox = str(spectral_windowing) labels = str(labels) timestep = str(timestep).split() fskip = int(skip) #checks for errors if (mlag <= 0): raise ValueError("MAXIMUM_LAG should be a non-negative integer.") if (npad < 0): raise ValueError( "LENGTH_ZEROPADDING should be a non-negative integer.") if (bsize <= 2 * mlag): if (bsize == -1): bsize = 2 * mlag else: raise ValueError( "LENGTH_BLOCK should be greater than or equal to 2 * MAXIMUM_LAG." ) #reads one frame. ff = open(ifile) rr = read_file("xyz", ff, output="array") ff.close() #appends "der" to output file in case the acf of the derivative is desired if (der == True): ofile = ofile + "_der" #stores the indices of the "chosen" atoms. ndof = len(rr['data']) if ("*" in labels): labelbool = np.ones(ndof / 3, bool) else: labelbool = np.zeros(ndof / 3, bool) for l in labels: labelbool = np.logical_or(labelbool, rr['names'] == l) nspecies = labelbool.sum() #initializes variables. nblocks = 0 dt = unit_to_internal("time", timestep[1], float(timestep[0])) data = np.zeros((bsize, nspecies, 3), float) fvvacf = np.zeros(bsize / 2 + 1, float) time = np.asarray(range(mlag + 1)) * dt omega = np.asarray(range(2 * (mlag + npad))) / float( 2 * (mlag + npad)) * (2 * np.pi / dt) #selects window function for fft. if (ftbox == "none"): win = np.ones(2 * mlag + 1, float) elif (ftbox == "cosine-hanning"): win = np.hanning(2 * mlag + 1) elif (ftbox == "cosine-hamming"): win = np.hamming(2 * mlag + 1) elif (ftbox == "cosine-blackman"): win = np.blackman(2 * mlag + 1) elif (ftbox == "triangle-bartlett"): win = np.bartlett(2 * mlag + 1) ff = open(ifile) #Skips the first fskip frames for x in xrange(fskip): rr = read_file("xyz", ff, output="array") while True: try: #Reads the data in blocks. for i in range(bsize): rr = read_file("xyz", ff, output="array") data[i] = rr['data'].reshape((ndof / 3, 3))[labelbool] if (der == True): data = np.gradient(data, axis=0) / dt #Computes the Fourier transform of the data. fdata = np.fft.rfft(data, axis=0) #Computes the Fourier transform of the vvac applying the convolution theorem. tfvvacf = fdata * np.conjugate(fdata) #Averages over all species and sums over the x,y,z directions. Also multiplies with the time step and a prefactor of (2pi)^-1. macf = 3.0 * np.real(np.mean( tfvvacf, axis=(1, 2))) * dt / (2 * np.pi) / bsize fvvacf += macf nblocks += 1 except EOFError: break ff.close() #Performs the block average of the Fourier transform. fvvacf = fvvacf / nblocks #Computes the inverse Fourier transform to get the vvac. vvacf = np.fft.irfft(fvvacf)[:mlag + 1] np.savetxt(ofile + "_acf.data", np.vstack((time, vvacf)).T[:mlag + npad]) #Applies window in one direction and pads the vvac with zeroes. pvvacf = np.append(vvacf * win[mlag:], np.zeros(npad)) #Recomputes the Fourier transform assuming the data is an even function of time. fpvvacf = np.fft.hfft(pvvacf) np.savetxt(ofile + "_facf.data", np.vstack((omega, fpvvacf)).T[:mlag + npad])
def main(prefix, temp): temp = unit_to_internal("energy", "kelvin", float(temp)) ipos = [] for filename in sorted(glob.glob(prefix + ".pos*")): ipos.append(open(filename, "r")) ifor = [] for filename in sorted(glob.glob(prefix + ".for*")): ifor.append(open(filename, "r")) ivacfim = open(prefix + ".imvacf", "w") nbeads = len(ipos) if (nbeads != len(ifor)): raise ValueError( "Mismatch between number of output files for forces and positions") natoms = 0 ifr = 0 while True: try: for i in range(nbeads): ret = read_file("xyz", ipos[i]) pos = ret["atoms"] ret = read_file("xyz", ifor[i]) force = ret["atoms"] if natoms == 0: natoms = pos.natoms beads = Beads(natoms, nbeads) forces = Beads(natoms, nbeads) beads[i].q = pos.q beads[i].m = pos.m forces[i].q = force.q except EOFError: # finished reading files break if (ifr == 0): cim = np.zeros((natoms, nbeads + 1), float) q = dstrip(beads.q) f = dstrip(forces.q) m = dstrip(beads.m) qc = dstrip(beads.qc) for j in range(nbeads + 1): for i in range(natoms): dummy = [(q[(j + k) % nbeads, 3 * i:3 * (i + 1)] - qc[3 * i:3 * (i + 1)]) * (-f[k, 3 * i:3 * (i + 1)]) for k in range(nbeads)] cim[i, j] = cim[i, j] + np.sum(dummy) / (nbeads * m[i]) cim[i, j] += 3. * Constants.kb * temp / m[i] ifr += 1 print 'Frame: ', ifr cim[:, :] = cim[:, :] / ifr fullcim = np.zeros(len(cim)) for j in range(nbeads + 1): fullcim[j] = np.sum([i for i in cim[:, j]]) ivacfim.write( "# Imaginary time autocorrelation, averaged through the whole simulation -- beta*hbar is %f \n" % (Constants.hbar / (Constants.kb * temp))) for islice in range(nbeads + 1): ivacfim.write("%f %12.5e \n" % (float(islice) / float(nbeads), fullcim[islice]))
def step(self, step=None): """Does one replay time step.""" self.ptime = 0.0 self.ttime = 0.0 self.qtime = -time.time() # If wildcard is used, check that it is consistent with Nbeads wildcard_used = False if any(char in self.intraj.value for char in "*?[]"): wildcard_used = True if len(self.rfile) != len(self.beads): info( "Error: if a wildcard is used for replay, then " "the number of files should be equal to the number of beads.", verbosity.low, ) softexit.trigger(" # Error in replay input.") while True: self.rstep += 1 try: if self.intraj.mode == "xyz": for bindex, b in enumerate(self.beads): if wildcard_used: myframe = read_file("xyz", self.rfile[bindex]) else: myframe = read_file("xyz", self.rfile) myatoms = myframe["atoms"] mycell = myframe["cell"] myatoms.q *= unit_to_internal("length", self.intraj.units, 1.0) mycell.h *= unit_to_internal("length", self.intraj.units, 1.0) b.q[:] = myatoms.q elif self.intraj.mode == "pdb": for bindex, b in enumerate(self.beads): if wildcard_used: myatoms, mycell = read_file( "pdb", self.rfile[bindex]) else: myatoms, mycell = read_file("pdb", self.rfile) myatoms.q *= unit_to_internal("length", self.intraj.units, 1.0) mycell.h *= unit_to_internal("length", self.intraj.units, 1.0) b.q[:] = myatoms.q elif self.intraj.mode == "chk" or self.intraj.mode == "checkpoint": # TODO: Adapt the new `Simulation.load_from_xml`? # reads configuration from a checkpoint file xmlchk = xml_parse_file(self.rfile) # Parses the file. from ipi.inputs.simulation import InputSimulation simchk = InputSimulation() simchk.parse(xmlchk.fields[0][1]) mycell = simchk.cell.fetch() mybeads = simchk.beads.fetch() self.beads.q[:] = mybeads.q softexit.trigger(" # Read single checkpoint") # do not assign cell if it contains an invalid value (typically missing cell in the input) if mycell.V > 0: self.cell.h[:] = mycell.h except EOFError: softexit.trigger(" # Finished reading re-run trajectory") if (step is None) or (self.rstep > step): break self.qtime += time.time()
def potentialEnergy(prefix, temp, ss=0, unit=''): """ Computes the estimator for the potential energy and PPI correction. """ # Adding fortran functions (when exist) sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90') fast_code = True try: import fortran except: fast_code = False print('WARNING: No compiled fortran module for fast calculations have been found.\n' 'Calculations will use a slower python script.') temperature = unit_to_internal("temperature", "kelvin", float(temp)) # simulation temperature skipSteps = int(ss) # steps to skip for thermalization f2_av, U_av, f2U_av = 0.0, 0.0, 0.0 # some required sums fns_for = sorted(glob.glob(prefix + ".for*")) fns_iU = glob.glob(prefix + ".out")[0] fn_out_en = prefix + ".potential_energy.dat" # Extracting the number of beads nbeads = len(fns_for) # print some information print 'temperature = {:f} K'.format(float(temp)) print print 'number of beads = {:d}'.format(nbeads) print print 'forces file names:' for fn_for in fns_for: print '{:s}'.format(fn_for) print print 'potential energy file: {:s}'.format(fns_iU) print print 'output file name:' print fn_out_en print # open input and output files ifor = [open(fn, "r") for fn in fns_for] iU = open(fns_iU, "r") iE = open(fn_out_en, "w") # Some constants beta = 1.0 / (Constants.kb * temperature) const = Constants.hbar**2 * beta**2 / (24.0 * nbeads**3) timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits(iU) # extracting simulation time # and potential energy units # Defining the output energy unit if unit == '': unit = potentialEnergyUnit iE.write("# Simulation time (in %s), potential energy and PPI potential energy corrections (in %s)\n" % (timeUnit, unit)) natoms = 0 ifr = 0 time0 = 0 f, m = None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print '\rProcessing frame {:d}'.format(ifr), sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ifor[i], output='arrays') if natoms == 0: m, natoms = ret["masses"], ret["natoms"] f = np.zeros((nbeads, 3 * natoms)) f[i, :] = ret["data"] U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index) except EOFError: # finished reading files sys.exit(0) if ifr < skipSteps: time0 = time if ifr >= skipSteps: # PPI correction time -= time0 f2 = 0.0 if not fast_code: for j in range(nbeads): for i in range(natoms): f2 += np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i] else: f2 = fortran.f2divm(np.array(f, order='F'), np.array(m, order='F'), natoms, nbeads) U_av += U f2_av += f2 f2U_av += f2 * U ifr += 1 norm = float(ifr - skipSteps) dU = 2.0 * f2_av / norm - beta * (f2U_av / norm - f2_av * U_av / norm**2) dU *= const dU = unit_to_user("energy", unit, dU) U = unit_to_user("energy", unit, U_av / float(ifr - skipSteps)) iE.write("%f %f %f\n" % (time, U, dU)) else: ifr += 1
def main(prefix, lag): verbosity.level = "low" lag = int(lag) # hard-coded prefixes for kinetic energy components (kin=diagonal bit, kod=off-diagonal) ikin = open(prefix + ".kin.xyz", "r") ikod = open(prefix + ".kod.xyz", "r") otag = open(prefix + ".ktag_" + str(lag) + ".xyz", "w") natoms = 0 ifr = 0 cbuf = 2 * lag + 1 while True: try: ret = read_file("xyz", ikin) tk = ret["atoms"] kin = dstrip(tk.q) ret = read_file("xyz", ikod) kod = dstrip(ret["atoms"].q) if natoms == 0: # initializes vectors natoms = len(kin) / 3 ktbuf = np.zeros( (cbuf, natoms, 3, 3), float ) # implement the buffer as a circular one so one doesn't need to re-allocate and storage is continuous nkt = np.zeros((natoms, 3, 3), float) mkt = np.zeros((natoms, 3, 3), float) # akt = np.zeros((natoms, 3), float) mea = np.zeros((natoms, 3), float) mev = np.zeros((natoms, 3, 3), float) nkt[:, 0, 0] = kin[0:natoms * 3:3] nkt[:, 1, 1] = kin[1:natoms * 3:3] nkt[:, 2, 2] = kin[2:natoms * 3:3] nkt[:, 0, 1] = nkt[:, 1, 0] = kod[0:natoms * 3:3] nkt[:, 0, 2] = nkt[:, 2, 0] = kod[1:natoms * 3:3] nkt[:, 2, 1] = nkt[:, 1, 2] = kod[2:natoms * 3:3] except EOFError: # Finished reading sys.exit(0) ktbuf[ifr % cbuf] = nkt if ifr >= (2 * lag): # now we can compute the mean tensor, and estimate the components of the kinetic energy mkt[:] = 0.0 tw = 0.0 for j in range(cbuf): w = 1.0 - np.abs(j - lag) * 1.0 / lag mkt += w * ktbuf[(ifr - j) % cbuf] tw += w mkt *= 1.0 / tw # computes the eigenvalues of the TAG tensor for i in range(natoms): [mea[i], mev[i]] = np.linalg.eigh(mkt[i]) otag.write( "%d\n# TAG eigenvalues e1 e2 e3 with lag %d. Frame: %d\n" % (natoms, lag, ifr - lag)) for i in range(natoms): otag.write("%6s %15.7e %15.7e %15.7e\n" % (tk.names[i], mea[i, 0], mea[i, 1], mea[i, 2])) ifr += 1
def energies(prefix, temp, ss=0, unit=''): """ Computes the virial centroid estimator for the total energy and PPI correction. """ # Adding fortran functions (when exist) sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90') fast_code = True try: import fortran except: fast_code = False print( 'WARNING: No compiled fortran module for fast calculations have been found.\n' 'Calculations will use a slower python script.') temperature = unit_to_internal("temperature", "kelvin", float(temp)) # simulation temperature skipSteps = int(ss) # steps to skip for thermalization KPa_av, KVir_av, U_av, f2_av, f2KPa_av, f2U_av = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 # some required sums fns_pos = sorted(glob.glob(prefix + ".pos*")) fns_for = sorted(glob.glob(prefix + ".for*")) fns_iU = glob.glob(prefix + ".out")[0] fn_out_en = prefix + ".energies.dat" # check that we found the same number of positions and forces files nbeads = len(fns_pos) if nbeads != len(fns_for): print(fns_pos) print(fns_for) raise ValueError( "Mismatch between number of input files for forces and positions.") # print some information print('temperature = {:f} K'.format(float(temp))) print() print('number of beads = {:d}'.format(nbeads)) print() print('positions and forces file names:') for fn_pos, fn_for in zip(fns_pos, fns_for): print('{:s} {:s}'.format(fn_pos, fn_for)) print() print('potential energy file: {:s}'.format(fns_iU)) print() print('output file name:') print(fn_out_en) print() # open input and output files ipos = [open(fn, "r") for fn in fns_pos] ifor = [open(fn, "r") for fn in fns_for] iU = open(fns_iU, "r") iE = open(fn_out_en, "w") # Some constants beta = 1.0 / (Constants.kb * temperature) const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2 const_2 = 1.5 * nbeads / beta const_3 = 1.5 / beta const_4 = Constants.kb**2 / Constants.hbar**2 const_5 = Constants.hbar**2 * beta**3 / (24.0 * nbeads**3) const_6 = Constants.hbar**2 * beta**2 / (24.0 * nbeads**3) timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits( iU) # extracting simulation time # and potential energy units # Defining the output energy unit if unit == '': unit = potentialEnergyUnit iE.write( "# Simulation time (in %s), improved total energy estimator, virial total energy estimator, and PPI " "correction for the total energy; improved potential energy estimator, potential energy estimatorand, " "PPI correction for the potential energy; improved kinetic energy estimator, virial kinetic energy " "estimator, and PPI correction for the kinetic energy (all in %s)\n" % (timeUnit, unit)) iE.close() natoms = 0 ifr = 0 time0 = 0 q, f, m = None, None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print('\rProcessing frame {:d}'.format(ifr), end=' ') sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ipos[i], dimension='length')["atoms"] if natoms == 0: m, natoms = ret.m, ret.natoms q = np.zeros((nbeads, 3 * natoms)) f = np.zeros((nbeads, 3 * natoms)) q[i, :] = ret.q f[i, :] = read_file("xyz", ifor[i], dimension='force')["atoms"].q U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index) except EOFError: # finished reading files sys.exit(0) if ifr < skipSteps: time0 = time if ifr >= skipSteps: # PPI correction time -= time0 KPa, f2, KVir = 0.0, 0.0, 0.0 if not fast_code: for j in range(nbeads): for i in range(natoms): f2 += np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i] for i in range(natoms): KPa -= np.dot( q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3]) * m[i] for j in range(nbeads - 1): for i in range(natoms): KPa -= np.dot( q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3]) * m[i] rc = np.zeros(3) for i in range(natoms): rc[:] = 0.0 for j in range(nbeads): rc[:] += q[j, i * 3:i * 3 + 3] rc[:] /= nbeads for j in range(nbeads): KVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) KPa *= const_1 KPa += const_2 * natoms KVir /= 2.0 * nbeads KVir += const_3 * natoms else: f2 = fortran.f2divm(np.array(f, order='F'), np.array(m, order='F'), natoms, nbeads) KPa = fortran.findcoupling(np.array(q, order='F'), np.array(m, order='F'), temperature, natoms, nbeads) KVir = fortran.findcentroidvirialkineticenergy( np.array(f, order='F'), np.array(q, order='F'), natoms, nbeads) KPa *= const_4 KPa += const_2 * natoms KVir += const_3 * natoms f2_av += f2 KPa_av += KPa f2KPa_av += f2 * KPa U_av += U f2U_av += f2 * U KVir_av += KVir ifr += 1 norm = float(ifr - skipSteps) dU = 2 * f2_av / norm - beta * (f2U_av / norm - f2_av * U_av / norm**2) dU *= const_6 dU = unit_to_user("energy", unit, dU) dK = (Constants.kb * temperature + KPa_av / norm) * f2_av / norm - f2KPa_av / norm dK *= const_5 dK = unit_to_user("energy", unit, dK) U = unit_to_user("energy", unit, U_av / norm) KVir = unit_to_user("energy", unit, KVir_av / norm) iE = open(fn_out_en, "a") iE.write( "%f %f %f %f %f %f %f %f %f %f\n" % (time, KVir + U + dK + dU, KVir + U, dK + dU, U + dU, U, dU, KVir + dK, KVir, dK)) iE.close() else: ifr += 1
def effectiveTemperatures(prefix, temp, ss=0): """ Computes effective temperatures for a given (PI)MD dynamics. """ temperature = unit_to_internal( "temperature", "kelvin", float(temp) ) # simulation temperature skipSteps = int(ss) # steps to skip for thermalization f2_av = None # average square forces array names = None fns_for = sorted(glob.glob(prefix + ".for*")) fn_out = prefix + ".effective_temperatures.dat" nbeads = len(fns_for) # print some information print("temperature = {:f} K".format(float(temp))) print() print("number of beads = {:d}".format(nbeads)) print() print("forces file names:") for fn_for in fns_for: print("{:s}".format(fn_for)) print() print("output file name:") print(fn_out) print() # open input and output files ifor = [open(fn, "r") for fn in fns_for] iOut = open(fn_out, "w") # Some constants const = Constants.hbar**2 / (12.0 * (nbeads * Constants.kb * temperature) ** 3) iOut.write( "# Atom, Cartesian components of the effective temperature, average effective temperature (in Kelvin)\n" ) natoms = 0 ifr = 0 f, m = None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print("\rProcessing frame {:d}".format(ifr), end=" ") sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ifor[i], dimension="force")["atoms"] if natoms == 0: m, natoms, names = ret.m, ret.natoms, ret.names f = np.zeros((nbeads, 3 * natoms)) f2_av = np.zeros(3 * natoms) f[i, :] = ret.q except EOFError: # finished reading files break if ifr >= skipSteps: # PPI correction f2 = np.zeros(3 * natoms) for i in range(natoms): for j in range(nbeads): f2[i * 3 : i * 3 + 3] += f[j, i * 3 : i * 3 + 3] ** 2 / m[i] f2_av[:] += f2[:] ifr += 1 else: ifr += 1 dT = const * f2_av / float(ifr - skipSteps) temperature = unit_to_user("temperature", "kelvin", temperature) for i in range(natoms): iOut.write( "%s %f %f %f %f\n" % ( names[i], temperature * (1 + dT[i * 3]), temperature * (1 + dT[i * 3 + 1]), temperature * (1 + dT[i * 3 + 2]), temperature * (1 + np.sum(dT[i * 3 : i * 3 + 3]) / 3.0), ) ) for f in ifor: f.close() iOut.close()
# OPEN AND READ ###########################################################3 if input_geo != 'None' or chk != 'None': if manual: if (os.path.exists(input_geo)): ipos = open(input_geo, "r") else: print "We can't find %s " % input_geo sys.exit() pos = list() nbeads = 0 while True: try: ret = read_file("xyz", ipos) pos.append(ret["atoms"]) cell = ret["cell"] nbeads += 1 except EOFError: # finished reading files break ipos.close() natoms = pos[0].natoms atom = pos[0] # Compose the half ring polymer. q = np.vstack([i.q for i in pos]) else: from ipi.engine.simulation import Simulation if (os.path.exists(chk)): simulation = Simulation.load_from_xml(chk, custom_verbosity='low', request_banner=False)
def totalEnergy(prefix, temp, ss=0): """ Computes the virial centroid estimator for the total energy and PPI correction. """ global temperature, skipSteps temperature = unit_to_internal("temperature", "kelvin", float(temp)) skipSteps = int(ss) f2_av, ePA_av, eVir_av, f2ePA_av = 0.0, 0.0, 0.0, 0.0 # average square forces, virial and primitive energy # estimators, and the product of the primitive energy estimator and square forces ipos = [] # input positions files for filename in sorted(glob.glob(prefix + ".pos*")): ipos.append(open(filename, "r")) ifor = [] # input forces files for filename in sorted(glob.glob(prefix + ".for*")): ifor.append(open(filename, "r")) iU = None # input potential energy and simulation time file for filename in sorted(glob.glob(prefix + ".out")): iU = open(filename, "r") global potentialEnergyUnit, timeUnit timeUnit, potentialEnergyUnit = extractUnits(iU) # extracting simulation time and potential energy units iE = open(prefix + ".energy" + ".dat", "w") iE.write("# Simulation time (in %s), virial total energy and PPI energy correction (in %s)\n" % (timeUnit, potentialEnergyUnit)) nbeads = len(ipos) if (nbeads != len(ifor)): raise ValueError("Mismatch between number of output files for forces and positions") natoms = 0 ifr = 0 time0 = 0 q, f, m = None, None, None while True: # Reading input files and calculating PPI correction try: for i in range(nbeads): ret = read_file("xyz", ipos[i]) m, n = ret["masses"], ret["atoms"].natoms pos = unit_to_internal(ret["units"][0], ret["units"][1], ret["atoms"].q) ret = read_file("xyz", ifor[i]) force = unit_to_internal(ret["units"][0], ret["units"][1], ret["atoms"].q) if natoms == 0: natoms = n q = np.zeros((nbeads, 3 * natoms)) f = np.zeros((nbeads, 3 * natoms)) q[i, :] = pos f[i, :] = force time, U = read_U(iU) except EOFError: # finished reading files sys.exit(0) if ifr < skipSteps: time0 = time if ifr >= skipSteps: # PPI correction time -= time0 ePA, f2, f2ePA = 0.0, 0.0, 0.0 eVir, rc = 0.0, np.zeros(3) for j in range(nbeads): for i in range(natoms): f2 += np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i] for i in range(natoms): ePA -= np.dot(q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3]) * m[i] for j in range(nbeads - 1): for i in range(natoms): ePA -= np.dot(q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3]) * m[i] for i in range(natoms): rc[:] = 0.0 for j in range(nbeads): rc[:] += q[j, i * 3:i * 3 + 3] rc[:] /= nbeads for j in range(nbeads): eVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) ePA *= 0.5 * nbeads * (Constants.kb * temperature)**2 / Constants.hbar**2 ePA += 0.5 * nbeads * (3 * natoms) * Constants.kb * temperature + U f2ePA = f2 * ePA eVir /= 2.0 * nbeads eVir += 0.5 * (3 * natoms) * Constants.kb * temperature + U ePA_av += ePA f2_av += f2 f2ePA_av += f2ePA eVir_av += eVir ifr += 1 print(ifr - skipSteps) # Printing current time frame (excluding thermalization) dE = (3.0 * Constants.kb * temperature + ePA_av / float(ifr - skipSteps)) * f2_av / float(ifr - skipSteps) - \ f2ePA_av / float(ifr - skipSteps) dE *= Constants.hbar**2 / (24.0 * (nbeads * Constants.kb * temperature)**3) dE = unit_to_user("energy", potentialEnergyUnit, dE) # Output in the same unit as potential energy eVir = unit_to_user("energy", potentialEnergyUnit, eVir_av / float(ifr - skipSteps)) # Output in the same unit # as potential energy iE.write("%f %f %f\n" % (time, eVir, dE)) else: ifr += 1
def main(prefix, temp): T = float(temp) fns_pos = sorted(glob.glob(prefix + ".pos*")) fns_for = sorted(glob.glob(prefix + ".for*")) fn_out_kin = prefix + ".kin.xyz" fn_out_kod = prefix + ".kod.xyz" # check that we found the same number of positions and forces files nbeads = len(fns_pos) if nbeads != len(fns_for): print fns_pos print fns_for raise ValueError("Mismatch between number of input files for forces and positions.") # print some information print 'temperature = {:f} K'.format(T) print print 'number of beads = {:d}'.format(nbeads) print print 'positions and forces file names:' for fn_pos, fn_for in zip(fns_pos, fns_for): print '{:s} {:s}'.format(fn_pos, fn_for) print print 'output file names:' print fn_out_kin print fn_out_kod print temp = unit_to_internal("energy", "kelvin", T) # open input and output files ipos = [open(fn, "r") for fn in fns_pos] ifor = [open(fn, "r") for fn in fns_for] ikin = open(fn_out_kin, "w") ikod = open(fn_out_kod, "w") natoms = 0 ifr = 0 while True: # print progress if ifr % 100 == 0: print '\rProcessing frame {:d}'.format(ifr), sys.stdout.flush() # load one frame try: for i in range(nbeads): ret = read_file("xyz", ipos[i]) pos = ret["atoms"] ret = read_file("xyz", ifor[i]) force = ret["atoms"] if natoms == 0: natoms = pos.natoms beads = Beads(natoms, nbeads) forces = Beads(natoms, nbeads) kcv = np.zeros((natoms, 6), float) beads[i].q = pos.q forces[i].q = force.q except EOFError: # finished reading files break # calculate kinetic energies q = dstrip(beads.q) f = dstrip(forces.q) qc = dstrip(beads.qc) kcv[:] = 0 for j in range(nbeads): for i in range(natoms): kcv[i, 0] += (q[j, i * 3 + 0] - qc[i * 3 + 0]) * f[j, i * 3 + 0] kcv[i, 1] += (q[j, i * 3 + 1] - qc[i * 3 + 1]) * f[j, i * 3 + 1] kcv[i, 2] += (q[j, i * 3 + 2] - qc[i * 3 + 2]) * f[j, i * 3 + 2] kcv[i, 3] += (q[j, i * 3 + 0] - qc[i * 3 + 0]) * f[j, i * 3 + 1] + (q[j, i * 3 + 1] - qc[i * 3 + 1]) * f[j, i * 3 + 0] kcv[i, 4] += (q[j, i * 3 + 0] - qc[i * 3 + 0]) * f[j, i * 3 + 2] + (q[j, i * 3 + 2] - qc[i * 3 + 2]) * f[j, i * 3 + 0] kcv[i, 5] += (q[j, i * 3 + 1] - qc[i * 3 + 1]) * f[j, i * 3 + 2] + (q[j, i * 3 + 2] - qc[i * 3 + 2]) * f[j, i * 3 + 1] kcv *= -0.5 / nbeads kcv[:, 0:3] += 0.5 * Constants.kb * temp kcv[:, 3:6] *= 0.5 # write output ikin.write("%d\n# Centroid-virial kinetic energy estimator [a.u.] - diagonal terms: xx yy zz\n" % natoms) ikod.write("%d\n# Centroid-virial kinetic energy estimator [a.u.] - off-diag terms: xy xz yz\n" % natoms) for i in range(natoms): ikin.write("%8s %12.5e %12.5e %12.5e\n" % (pos.names[i], kcv[i, 0], kcv[i, 1], kcv[i, 2])) ikod.write("%8s %12.5e %12.5e %12.5e\n" % (pos.names[i], kcv[i, 3], kcv[i, 4], kcv[i, 5])) ifr += 1 print '\rProcessed {:d} frames.'.format(ifr) ikin.close() ikod.close()