def process_units(comment, cell, data, names, masses, natoms, dimension="automatic", units="automatic", cell_units="automatic", mode="xyz"): """Convert the data in the file according to the units written in the i-PI format. Args: comment: cell: data: names: masses: output: Returns: """ dimension, units, cell_units = auto_units(comment, dimension, units, cell_units, mode) info("Interpreting input with dimension %s, units %s and cell units %s" % (dimension, units, cell_units), verbosity.high) # Units transformation cell *= unit_to_internal('length', cell_units, 1) # cell units transformation data *= unit_to_internal(dimension, units, 1) # units transformation # Return data as i-PI structures cell = Cell(cell) atoms = Atoms(natoms) atoms.q[:] = data atoms.names[:] = names atoms.m[:] = masses return { "atoms": atoms, "cell": cell, }
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 fetch(self): """Returns the stored data in the user defined units.""" super(InputValue, self).fetch() if self._dimension != "undefined": print "returning ", self.value * unit_to_internal( self._dimension, self.units.fetch(), 1.0) return self.value * unit_to_internal(self._dimension, self.units.fetch(), 1.0) else: return self.value
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 __call__(self, cell, pos): """Get energies, forces, and stresses from the librascal model""" pos_rascal = unit_to_user("length", "angstrom", pos) cell_rascal = unit_to_user("length", "angstrom", cell) # Do the actual calculation pot, force, stress = self.rascal_calc.calculate( pos_rascal, cell_rascal) pot_ipi = unit_to_internal("energy", "electronvolt", pot) force_ipi = unit_to_internal("force", "ev/ang", force) # The rascal stress is normalized by the cell volume (in rascal units) vir_rascal = -1 * stress * det_ut3x3(cell_rascal) vir_ipi = unit_to_internal("energy", "electronvolt", vir_rascal) extras = "" return pot_ipi, force_ipi, vir_ipi, extras
def process_units( comment, cell, data, names, masses, natoms, dimension="automatic", units="automatic", cell_units="automatic", mode="xyz", ): """Convert the data in the file according to the units written in the i-PI format. Args: comment: cell: data: names: masses: output: Returns: """ dimension, units, cell_units = auto_units(comment, dimension, units, cell_units, mode) info( " # Interpreting input with dimension %s, units %s and cell units %s" % (dimension, units, cell_units), verbosity.high, ) # Units transformation cell *= unit_to_internal("length", cell_units, 1) # cell units transformation data *= unit_to_internal(dimension, units, 1) # units transformation # Return data as i-PI structures cell = Cell(cell) atoms = Atoms(natoms) atoms.q[:] = data atoms.names[:] = names atoms.m[:] = masses return { "atoms": atoms, "cell": cell, }
def gleacf(path2iipi, path2ivvac, oprefix, action, nrows, stride, dparam): # opens & parses the i-pi input file ifile = open(path2iipi, "r") xmlrestart = io_xml.xml_parse_file(ifile) ifile.close() isimul = InputSimulation() isimul.parse(xmlrestart.fields[0][1]) simul = isimul.fetch() # parses the drift and diffusion matrices of the GLE thermostat. ttype = str(type(simul.syslist[0].motion.thermostat).__name__) kbT = float(simul.syslist[0].ensemble.temp) simul.syslist[0].motion.thermostat.temp = kbT if (ttype == "ThermoGLE"): Ap = simul.syslist[0].motion.thermostat.A * unit_to_internal( "time", dt[1], float(dt[0])) Cp = simul.syslist[0].motion.thermostat.C / kbT Dp = np.dot(Ap, Cp) + np.dot(Cp, Ap.T) elif (ttype == "ThermoLangevin"): Ap = np.asarray( [1.0 / simul.syslist[0].motion.thermostat.tau]).reshape( (1, 1)) * unit_to_internal("time", dt[1], float(dt[0])) Cp = np.asarray([1.0]).reshape((1, 1)) Dp = np.dot(Ap, Cp) + np.dot(Cp, Ap.T) # imports the vvac function. ivvac = input_vvac(path2ivvac, nrows, stride) ix = ivvac[:, 0] iy = ivvac[:, 1] # computes the vvac kernel print "# computing the kernel." ker = gleKernel(ix, Ap, Dp) # (de-)convolutes the spectrum if (action == "conv"): print "# printing the output spectrum." output_vvac((ix, np.dot(iy, ker.T)), oprefix, input_vvac(path2ivvac, nrows, 1)) elif (action == "deconv"): print "# deconvoluting the input spectrum." oy = ISRA(ix, ker, iy, dparam, oprefix)
def fetch(self): """Returns the stored data in the user defined units.""" super(InputValue, self).fetch() rval = self.value if self._dimension != "undefined": rval *= unit_to_internal(self._dimension, self.units.fetch(), 1.0) return rval
def process_units(comment, cell, qatoms, names, masses, output='objects'): """ Converts the data in the file according to the units written in the ipi format. """ # Extracting trajectory units family, unit = 'undefined', '' is_comment_useful = filter(None, [key.search(comment.strip()) for key in traj_re]) if len(is_comment_useful) > 0: traj = is_comment_useful[0].group()[:-1].split('{') family, unit = traj_dict[traj[0]]['dimension'], traj[1] # Extracting cell units cell_unit = '' tmp = cell_unit_re.search(comment) if tmp is not None: cell_unit = tmp.group(1) # Units transformation cell *= unit_to_internal('length', cell_unit, 1) # cell units transformation qatoms *= unit_to_internal(family, unit, 1) # units transformation if output == 'objects': cell = Cell(cell) atoms = Atoms(len(names)) atoms.q[:] = qatoms atoms.names[:] = names atoms.m[:] = masses return { "atoms": atoms, "cell": cell, } else: return { "data": qatoms, "masses": masses, "names": names, "natoms": len(names), "cell": cell, }
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 step(self): """Does one simulation time step.""" self.ptime = self.ttime = 0 self.qtime = -time.time() try: if (self.intraj.mode == "xyz"): for b in self.beads: myatoms = read_xyz(self.rfile) myatoms.q *= unit_to_internal("length", self.intraj.units, 1.0) b.q[:] = myatoms.q elif (self.intraj.mode == "pdb"): for b in self.beads: myatoms, mycell = read_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"): # 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") self.qtime += time.time()
def step(self): """Does one simulation time step.""" self.ptime = self.ttime = 0 self.qtime = -time.time() try: if self.intraj.mode == "xyz": for b in self.beads: myatoms = read_xyz(self.rfile) myatoms.q *= unit_to_internal("length", self.intraj.units, 1.0) b.q[:] = myatoms.q elif self.intraj.mode == "pdb": for b in self.beads: myatoms, mycell = read_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": # 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") self.qtime += time.time()
def gleacf(path2iipi, path2ivvac, oprefix, action, nrows, stride, dparam): # opens & parses the i-pi input file ifile = open(path2iipi, "r") xmlrestart = io_xml.xml_parse_file(ifile) ifile.close() isimul = InputSimulation() isimul.parse(xmlrestart.fields[0][1]) simul = isimul.fetch() # parses the drift and diffusion matrices of the GLE thermostat. ttype = str(type(simul.syslist[0].motion.thermostat).__name__) kbT = float(simul.syslist[0].ensemble.temp) simul.syslist[0].motion.thermostat.temp = kbT if(ttype == "ThermoGLE"): Ap = simul.syslist[0].motion.thermostat.A * unit_to_internal("time", dt[1], float(dt[0])) Cp = simul.syslist[0].motion.thermostat.C / kbT Dp = np.dot(Ap, Cp) + np.dot(Cp, Ap.T) elif(ttype == "ThermoLangevin"): Ap = np.asarray([1.0 / simul.syslist[0].motion.thermostat.tau]).reshape((1, 1)) * unit_to_internal("time", dt[1], float(dt[0])) Cp = np.asarray([1.0]).reshape((1, 1)) Dp = np.dot(Ap, Cp) + np.dot(Cp, Ap.T) # imports the vvac function. ivvac = input_vvac(path2ivvac, nrows, stride) ix = ivvac[:, 0] iy = ivvac[:, 1] # computes the vvac kernel print "# computing the kernel." ker = gleKernel(ix, Ap, Dp) # (de-)convolutes the spectrum if(action == "conv"): print "# printing the output spectrum." output_vvac((ix, np.dot(iy, ker.T)), oprefix, input_vvac(path2ivvac, nrows, 1)) elif(action == "deconv"): print "# deconvoluting the input spectrum." oy = ISRA(ix, ker, iy, dparam, oprefix)
def read_U(filedesc, potentialEnergyUnit, potentialEnergy_index, time_index): """Takes a file which contains simulation time and potential energy information and returns these data. Potential energy is transformed into internal units. Args: filedesc: An open readable file object. Returns: The simulation time and potential energy of the system. """ line = filedesc.readline() if line == "": raise EOFError("The file descriptor hit EOF.") line = line.strip().split() time = float(line[time_index]) U = float(line[potentialEnergy_index]) U = unit_to_internal("energy", potentialEnergyUnit, U) return U, time
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 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 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 main(inputfile, prefix="PTW-", ttemp="300.0", skip="2000"): txtemp = ttemp ttemp = unit_to_internal("energy", "kelvin", float(ttemp)) skip = int(skip) # opens & parses the input file ifile = open(inputfile, "r") verbosity.level = "quiet" verbosity.lock = True xmlrestart = io_xml.xml_parse_file(ifile) # Parses the file. ifile.close() isimul = InputSimulation() isimul.parse(xmlrestart.fields[0][1]) verbosity.level = "quiet" banner() print( "# Printing out temperature re-weighing factors for a parallel tempering simulation" ) simul = isimul.fetch() if simul.mode != "paratemp": raise ValueError( "Simulation does not look like a parallel tempering one.") # reconstructs the list of the property and trajectory files that have been output # and that should be re-ordered lprop = [] # list of property files # ltraj = [] # list of trajectory files tlist = simul.paratemp.temp_list nsys = len(simul.syslist) for o in simul.outtemplate: if (type(o) is CheckpointOutput ): # properties and trajectories are output per system pass elif type(o) is PropertyOutput: nprop = [] isys = 0 for s in simul.syslist: # create multiple copies if s.prefix != "": filename = s.prefix + "_" + o.filename else: filename = o.filename ofilename = (prefix + (("%0" + str( int(1 + np.floor(np.log(len(simul.syslist)) / np.log(10)))) + "d") % (isys)) + "_" + o.filename) nprop.append({ "filename": filename, "ofilename": ofilename, "stride": o.stride, "ifile": open(filename, "r"), "ofile": None, }) isys += 1 lprop.append(nprop) ptfile = open("PARATEMP", "r") # these are variables used to compute the weighting factors tprops = [] vfields = [] refpots = [] vunits = [] nw = [] tw = [] tw2 = [] repot = re.compile(" ([0-9]*) *--> potential") reunit = re.compile("{(.*)}") # now reads files one frame at a time, and re-direct output to the appropriate location irep = np.zeros(nsys, int) while True: # reads one line from PARATEMP index file line = ptfile.readline() line = line.split() try: if len(line) == 0: raise EOFError step = int(line[0]) irep[:] = line[1:] wk = 0 for prop in lprop: for isys in range(nsys): sprop = prop[isys] if step % sprop["stride"] == 0: # property transfer iline = sprop["ifile"].readline() if len(iline) == 0: raise EOFError while iline[ 0] == "#": # fast forward if line is a comment # checks if we have one single file with potential energies rm = repot.search(iline) if not (rm is None) and not (prop in tprops): tprops.append(prop) for p in prop: p["ofile"] = open(p["ofilename"], "w") p["ofile"].write( "# column 1 --> ptlogweight: ln of re-weighing factor with target temperature %s K\n" % (txtemp)) vfields.append(int(rm.group(1)) - 1) refpots.append(np.zeros(nsys)) nw.append(np.zeros(nsys)) tw.append(np.zeros(nsys)) tw2.append(np.zeros(nsys)) rm = reunit.search(iline) if rm: vunits.append(rm.group(1)) else: vunits.append("atomic_unit") iline = sprop["ifile"].readline() if prop in tprops: # do temperature weighing pot = unit_to_internal( "energy", vunits[wk], float(iline.split()[vfields[wk]])) ir = irep[isys] if nw[wk][ir] == 0: refpots[wk][ ir] = pot # picks the first value as a reference potential to avoid insane absolute values of the logweight temp = tlist[ir] lw = (pot - refpots[wk][ir]) * (1 / temp - 1 / ttemp) if ( step > skip ): # computes trajectory weights avoiding the initial - possibly insane - values if nw[wk][ir] == 0: tw[wk][ir] = lw tw2[wk][ir] = lw else: tw[wk][ir] = logsumlog((tw[wk][ir], 1), (lw, 1))[0] tw2[wk][ir] = logsumlog((tw2[wk][ir], 1), (2 * lw, 1))[0] nw[wk][ir] += 1 prop[ir]["ofile"].write("%15.7e\n" % (lw)) if isys == nsys - 1: wk += 1 except EOFError: # print out trajectory weights based on PRSA 2011, assuming that observables and weights are weakly correlated wk = 0 fpw = open(prefix + "WEIGHTS", "w") fpw.write("# Global trajectory weights for temperature %s K\n" % (txtemp)) fpw.write( "# Please cite M. Ceriotti, G. A. Brain, O. Riordan, D.E. Manolopoulos, " + "The inefficiency of re-weighted sampling and the curse of system size in high-order path integration. " + "Proceedings of the Royal Society A, 468(2137), 2-17 (2011) \n" ) for prop in lprop: if prop in tprops: for ir in range(nsys): fpw.write("%s %15.7e \n" % ( prop[ir]["ofilename"], 1.0 / (np.exp(tw2[wk][ir] - 2 * tw[wk][ir]) * nw[wk][ir]), )) wk += 1 break
def init_stage1(self, simul): """Initializes the simulation -- first stage. Takes a simulation object, and uses all the data in the initialization queue to fill up the beads and cell data needed to run the simulation. Args: simul: A simulation object to be initialized. Raises: ValueError: Raised if there is a problem with the initialization, if something that should have been has not been, or if the objects that have been specified are not compatible with each other. """ if simul.beads.nbeads == 0: fpos = fmom = fmass = flab = fcell = False # we don't have an explicitly defined beads object yet else: fpos = fmom = fmass = flab = fcell = True for (k, v) in self.queue: info(" # Initializer (stage 1) parsing " + str(k) + " object.", verbosity.high) if k == "cell": if v.mode == "manual": rh = v.value.reshape((3, 3)) * unit_to_internal("length", v.units, 1.0) elif v.mode == "chk": rh = init_chk(v.value)[1].h elif init_file(v.mode, v.value)[1].h.trace() == -3: # In case the file do not contain any # + cell parameters, the diagonal elements of the cell will be # +set to -1 from the io_units and nothing is read here. continue else: rh = init_file(v.mode, v.value, cell_units=v.units)[1].h if fcell: warning("Overwriting previous cell parameters", verbosity.low) simul.cell.h = rh if simul.cell.V == 0.0: ValueError("Cell provided has zero volume") fcell = True elif k == "masses": if simul.beads.nbeads == 0: raise ValueError("Cannot initialize the masses before the size of the system is known") if fmass: warning("Overwriting previous atomic masses", verbosity.medium) if v.mode == "manual": rm = v.value * unit_to_internal("mass", v.units, 1.0) else: rm = init_beads(v, self.nbeads).m if v.bead < 0: # we are initializing the path if (fmom and fmass): warning("Rescaling momenta to make up for changed mass", verbosity.medium) simul.beads.p /= simul.beads.sm3 # go to mass-scaled momenta, that are mass-invariant if v.index < 0: simul.beads.m = rm else: # we are initializing a specific atom simul.beads.m[v.index:v.index + 1] = rm if (fmom and fmass): # finishes correcting the momenta simul.beads.p *= simul.beads.sm3 # back to normal momenta else: raise ValueError("Cannot change the mass of a single bead") fmass = True elif k == "labels": if simul.beads.nbeads == 0: raise ValueError("Cannot initialize the labels before the size of the system is known") if flab: warning("Overwriting previous atomic labels", verbosity.medium) if v.mode == "manual": rn = v.value else: rn = init_beads(v, self.nbeads).names if v.bead < 0: # we are initializing the path if v.index < 0: simul.beads.names = rn else: # we are initializing a specific atom simul.beads.names[v.index:v.index + 1] = rn else: raise ValueError("Cannot change the label of a single bead") flab = True elif k == "positions": if fpos: warning("Overwriting previous atomic positions", verbosity.medium) # read the atomic positions as a vector rq = init_vector(v, self.nbeads, dimension="length", units=v.units) nbeads, natoms = rq.shape natoms /= 3 # check if we must initialize the simulation beads if simul.beads.nbeads == 0: if v.index >= 0: raise ValueError("Cannot initialize single atoms before the size of the system is known") simul.beads.resize(natoms, self.nbeads) set_vector(v, simul.beads.q, rq) fpos = True elif (k == "velocities" or k == "momenta") and v.mode == "thermal": # intercept here thermal initialization, so we don't need to check further down if fmom: warning("Overwriting previous atomic momenta", verbosity.medium) if simul.beads.natoms == 0: raise ValueError("Cannot initialize momenta before the size of the system is known.") if not fmass: raise ValueError("Trying to resample velocities before having masses.") rtemp = v.value * unit_to_internal("temperature", v.units, 1.0) if rtemp <= 0: warning("Using the simulation temperature to resample velocities", verbosity.low) rtemp = simul.ensemble.temp else: info(" # Resampling velocities at temperature %s %s" % (v.value, v.units), verbosity.low) # pull together a mock initialization to get NM masses right # without too much code duplication if v.bead >= 0: raise ValueError("Cannot thermalize a single bead") if v.index >= 0: rnatoms = 1 else: rnatoms = simul.beads.natoms rbeads = Beads(rnatoms, simul.beads.nbeads) if v.index < 0: rbeads.m[:] = simul.beads.m else: rbeads.m[:] = simul.beads.m[v.index] rnm = NormalModes(mode=simul.nm.mode, transform_method=simul.nm.transform_method, freqs=simul.nm.nm_freqs) rens = Ensemble(temp=simul.ensemble.temp) rmv = Motion() rnm.bind(rens, rmv, rbeads) # then we exploit the sync magic to do a complicated initialization # in the NM representation # with (possibly) shifted-frequencies NM rnm.pnm = simul.prng.gvec((rbeads.nbeads, 3 * rbeads.natoms)) * np.sqrt(rnm.dynm3) * np.sqrt(rbeads.nbeads * rtemp * Constants.kb) if v.index < 0: simul.beads.p = rbeads.p else: simul.beads.p[:, 3 * v.index:3 * (v.index + 1)] = rbeads.p fmom = True elif k == "momenta": if fmom: warning("Overwriting previous atomic momenta", verbosity.medium) # read the atomic momenta as a vector rp = init_vector(v, self.nbeads, momenta=True, dimension="momentum", units=v.units) nbeads, natoms = rp.shape natoms /= 3 # checks if we must initialize the simulation beads if simul.beads.nbeads == 0: if v.index >= 0: raise ValueError("Cannot initialize single atoms before the size of the system is known") simul.beads.resize(natoms, self.nbeads) rp *= np.sqrt(self.nbeads / nbeads) set_vector(v, simul.beads.p, rp) fmom = True elif k == "velocities": if fmom: warning("Overwriting previous atomic momenta", verbosity.medium) # read the atomic velocities as a vector rv = init_vector(v, self.nbeads, dimension="velocity", units=v.units) nbeads, natoms = rv.shape natoms /= 3 # checks if we must initialize the simulation beads if simul.beads.nbeads == 0 or not fmass: ValueError("Cannot initialize velocities before the masses of the atoms are known") simul.beads.resize(natoms, self.nbeads) warning("Initializing from velocities uses the previously defined masses -- not the masses inferred from the file -- to build momenta", verbosity.low) if v.index >= 0: rv *= simul.beads.m[v.index] else: for ev in rv: ev *= simul.beads.m3[0] rv *= np.sqrt(self.nbeads / nbeads) set_vector(v, simul.beads.p, rv) fmom = True elif k == "gle": pass # thermostats must be initialised in a second stage if simul.beads.natoms == 0: raise ValueError("Initializer could not initialize the atomic positions") if simul.cell.V == 0: raise ValueError("Initializer could not initialize the cell") for i in range(simul.beads.natoms): if simul.beads.m[i] <= 0: raise ValueError("Initializer could not initialize the masses") if simul.beads.names[i] == "": raise ValueError("Initializer could not initialize the atom labels") if not fmom: warning("Momenta not specified in initialize. Will start with zero velocity if they are not specified in beads.", verbosity.low)
def contract_trajectory(fns_in, fn_out_template, n_new, cell_units_in, cell_units_out): verbosity.level = "low" n = len(fns_in) # Generate output file names. if n_new == 1: fns_out = [fn_out_template] else: fns_out = [fn_out_template.format(i) for i in range(n_new)] print("Contracting {:d} beads to {:d} beads.".format(n, n_new)) print() print("input file names:") for fn in fns_in: print(fn) print() print("output file names:") for fn in fns_out: print(fn) print() # Open input trajectory iterators. trjs_in = [iter_file_name_raw(fn) for fn in fns_in] mode = os.path.splitext(fn)[-1] # Open output files. fs_out = [open_backup(fn, "w") for fn in fns_out] mode_out = os.path.splitext(fn_out_template)[-1] # prepare ring polymer rescaler rescale = nm_rescale(n, n_new) # Loop over all frames. i_frame = 0 while True: try: # Get the frames for all beads. frames = [trj.next() for trj in trjs_in] except StopIteration: # Stop when any of the trajectories runs out of frames. break # gets units from first frame dimension, units, cell_units = auto_units(comment=frames[0]["comment"], cell_units=cell_units_in) if cell_units_out == "automatic": cell_units_out = cell_units # re-use units unless otherwise specified # Consistency check. h = frames[0]["cell"] natoms = len(frames[0]["data"]) / 3 for i in range(n): # Check that all the cells are the same. if (frames[i]["cell"] != h).any(): msg = "Cell for beads {:d} and {:d} differ in frame {:d}." raise ValueError(msg.format(0, i, i_frame)) # Check that the numbers of atoms are the same. if len(frames[i]["data"]) != 3 * natoms: msg = "Different numbers of atoms for beads {:d} and {:d} in frame {:d}." raise ValueError(msg.format(0, i, i_frame)) cell = Cell() cell.h = frames[0]["cell"] atoms = Atoms(natoms) atoms.names = frames[0]["names"] # Compose the ring polymer. q = np.vstack([frame["data"] for frame in frames]) * unit_to_internal(dimension, units, 1) # units transformation # Contract the coordinates to `n_new` beads. q_c = rescale.b1tob2(q) # Save the output data. for i, f_out in enumerate(fs_out): atoms.q = q_c[i, :] print_file(mode_out, atoms, cell, f_out, dimension=dimension, units=units, cell_units=cell_units_out) # Count frames and print information on progress. i_frame += 1 if i_frame % 100 == 0: print("\rframe {:d}".format(i_frame), end="") sys.stdout.flush() for f_out in fs_out: f_out.close() print() print() print("Processed {:d} frames.".format(i_frame))
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 test_case_insensitive(): angstrom = units.unit_to_internal('length', 'angstrom', 1.0) Angstrom = units.unit_to_internal('length', 'Angstrom', 1.0)
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 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 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 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_raw("xyz", ff) 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_raw("xyz", ff) while True: try: # Reads the data in blocks. for i in range(bsize): rr = read_file_raw("xyz", ff) 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])
print 'We have a half ring polymer made of %i beads and %i atoms.' % (nbeads, natoms) print 'We will expand the ring polymer to get a half polymer of %i beads.' % nbeadsNew # Compose the full ring polymer. #q2 = np.concatenate((q, np.flipud(q)), axis=0) # Make the rpc step #rpc = nm_rescale(2 * nbeads, 2 * nbeadsNew) #new_q = rpc.b1tob2(q2)[0:nbeadsNew] rpc = nm_rescale(nbeads, nbeadsNew, np.asarray(range(natoms))) # We use open path RPC new_q = rpc.b1tob2(q) # Print out = open("NEW_INSTANTON.xyz", "w") for i in range(nbeadsNew): atom.q = new_q[i] / unit_to_internal("length", "angstrom", 1.0) # Go back to angstrom print_file("xyz", atom, cell, out, title='cell{atomic_unit} Traj: positions{angstrom}') # print_file("xyz",pos[0],cell,out,title='cell }') out.close() print 'The new Instanton geometry (half polymer) was generated' print 'Check NEW_INSTANTON.xyz' print '' print 'Remeber to change the number of beads (%i) in your input' % nbeadsNew print '' if input_hess != 'None' or chk != 'None': if manual: if (os.path.exists(input_hess)): hess = open(input_hess, "r")
def main(inputfile, prefix="PTW-", ttemp="300.0", skip="2000"): txtemp = ttemp ttemp = unit_to_internal("energy", "kelvin", float(ttemp)) skip = int(skip) # opens & parses the input file ifile = open(inputfile, "r") verbosity.level = "quiet" verbosity.lock = True xmlrestart = io_xml.xml_parse_file(ifile) # Parses the file. ifile.close() isimul = InputSimulation() isimul.parse(xmlrestart.fields[0][1]) verbosity.level = "quiet" banner() print "# Printing out temperature re-weighing factors for a parallel tempering simulation" simul = isimul.fetch() if simul.mode != "paratemp": raise ValueError("Simulation does not look like a parallel tempering one.") # reconstructs the list of the property and trajectory files that have been output # and that should be re-ordered lprop = [] # list of property files ltraj = [] # list of trajectory files tlist = simul.paratemp.temp_list nsys = len(simul.syslist) for o in simul.outtemplate: if type(o) is CheckpointOutput: # properties and trajectories are output per system pass elif type(o) is PropertyOutput: nprop = [] isys = 0 for s in simul.syslist: # create multiple copies if s.prefix != "": filename = s.prefix + "_" + o.filename else: filename = o.filename ofilename = prefix + (("%0" + str(int(1 + np.floor(np.log(len(simul.syslist)) / np.log(10)))) + "d") % (isys)) + "_" + o.filename nprop.append({"filename": filename, "ofilename": ofilename, "stride": o.stride, "ifile": open(filename, "r"), "ofile": None }) isys += 1 lprop.append(nprop) ptfile = open("PARATEMP", "r") # these are variables used to compute the weighting factors tprops = [] vfields = [] refpots = [] vunits = [] nw = [] tw = [] tw2 = [] repot = re.compile(' ([0-9]*) *--> potential') reunit = re.compile('{(.*)}') # now reads files one frame at a time, and re-direct output to the appropriate location irep = np.zeros(nsys, int) while True: # reads one line from PARATEMP index file line = ptfile.readline() line = line.split() try: if len(line) == 0: raise EOFError step = int(line[0]) irep[:] = line[1:] wk = 0 for prop in lprop: for isys in range(nsys): sprop = prop[isys] if step % sprop["stride"] == 0: # property transfer iline = sprop["ifile"].readline() if len(iline) == 0: raise EOFError while iline[0] == "#": # fast forward if line is a comment # checks if we have one single file with potential energies rm = repot.search(iline) if not (rm is None) and not (prop in tprops): tprops.append(prop) for p in prop: p["ofile"] = open(p["ofilename"], "w") p["ofile"].write("# column 1 --> ptlogweight: ln of re-weighing factor with target temperature %s K\n" % (txtemp)) vfields.append(int(rm.group(1)) - 1) refpots.append(np.zeros(nsys)) nw.append(np.zeros(nsys)) tw.append(np.zeros(nsys)) tw2.append(np.zeros(nsys)) rm = reunit.search(iline) if rm: vunits.append(rm.group(1)) else: vunits.append("atomic_unit") iline = sprop["ifile"].readline() if prop in tprops: # do temperature weighing pot = unit_to_internal("energy", vunits[wk], float(iline.split()[vfields[wk]])) ir = irep[isys] if (nw[wk][ir] == 0): refpots[wk][ir] = pot # picks the first value as a reference potential to avoid insane absolute values of the logweight temp = tlist[ir] lw = (pot - refpots[wk][ir]) * (1 / temp - 1 / ttemp) if step > skip: # computes trajectory weights avoiding the initial - possibly insane - values if nw[wk][ir] == 0: tw[wk][ir] = lw tw2[wk][ir] = lw else: tw[wk][ir] = logsumlog((tw[wk][ir], 1), (lw, 1))[0] tw2[wk][ir] = logsumlog((tw2[wk][ir], 1), (2 * lw, 1))[0] nw[wk][ir] += 1 prop[ir]["ofile"].write("%15.7e\n" % (lw)) if isys == nsys - 1: wk += 1 except EOFError: # print out trajectory weights based on PRSA 2011, assuming that observables and weights are weakly correlated wk = 0 fpw = open(prefix + "WEIGHTS", "w") fpw.write("# Global trajectory weights for temperature %s K\n" % (txtemp)) fpw.write("# Please cite M. Ceriotti, G. A. Brain, O. Riordan, D.E. Manolopoulos, " + "The inefficiency of re-weighted sampling and the curse of system size in high-order path integration. " + "Proceedings of the Royal Society A, 468(2137), 2-17 (2011) \n") for prop in lprop: if prop in tprops: for ir in range(nsys): fpw.write("%s %15.7e \n" % (prop[ir]["ofilename"], 1.0 / (np.exp(tw2[wk][ir] - 2 * tw[wk][ir]) * nw[wk][ir]))) wk += 1 break
# See the "licenses" directory for full license information. import filecmp import os import numpy as np from numpy.testing import assert_equal from common import local from ipi.utils.units import unit_to_internal from ipi.utils.io import iter_file, read_file, print_file pos_xyz = np.array([i for i in range(3 * 3)]) pos_pdb = unit_to_internal("length", "angstrom", pos_xyz) def test_read_xyz(): """Tests that 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_iter_xyz(): """Tests that xyz files with multiple frames are read correctly."""
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 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 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 test_case_insensitive(): angstrom = units.unit_to_internal("length", "angstrom", 1.0) Angstrom = units.unit_to_internal("length", "Angstrom", 1.0) if angstrom != Angstrom: raise ValueError("angstrom != Angstrom")
def init_stage1(self, simul): """Initializes the simulation -- first stage. Takes a simulation object, and uses all the data in the initialization queue to fill up the beads and cell data needed to run the simulation. Args: simul: A simulation object to be initialized. Raises: ValueError: Raised if there is a problem with the initialization, if something that should have been has not been, or if the objects that have been specified are not compatible with each other. """ if simul.beads.nbeads == 0: fpos = fmom = fmass = flab = fcell = False # we don't have an explicitly defined beads object yet else: fpos = fmom = fmass = flab = fcell = True for (k, v) in self.queue: info(" # Initializer (stage 1) parsing " + str(k) + " object.", verbosity.high) if k == "cell": if fcell: warning("Overwriting previous cell parameters", verbosity.medium) if v.mode == "pdb": rh = init_pdb(v.value)[1].h elif v.mode == "chk": rh = init_chk(v.value)[1].h else: rh = v.value.reshape((3, 3)) rh *= unit_to_internal("length", v.units, 1.0) simul.cell.h = rh if simul.cell.V == 0.0: ValueError("Cell provided has zero volume") fcell = True elif k == "masses": if simul.beads.nbeads == 0: raise ValueError( "Cannot initialize the masses before the size of the system is known" ) if fmass: warning("Overwriting previous atomic masses", verbosity.medium) if v.mode == "manual": rm = v.value else: rm = init_beads(v, self.nbeads).m rm *= unit_to_internal("mass", v.units, 1.0) if v.bead < 0: # we are initializing the path if (fmom and fmass): warning( "Rescaling momenta to make up for changed mass", verbosity.medium) simul.beads.p /= simul.beads.sm3 # go to mass-scaled momenta, that are mass-invariant if v.index < 0: simul.beads.m = rm else: # we are initializing a specific atom simul.beads.m[v.index:v.index + 1] = rm if (fmom and fmass): # finishes correcting the momenta simul.beads.p *= simul.beads.sm3 # back to normal momenta else: raise ValueError("Cannot change the mass of a single bead") fmass = True elif k == "labels": if simul.beads.nbeads == 0: raise ValueError( "Cannot initialize the labels before the size of the system is known" ) if flab: warning("Overwriting previous atomic labels", verbosity.medium) if v.mode == "manual": rn = v.value else: rn = init_beads(v, self.nbeads).names if v.bead < 0: # we are initializing the path if v.index < 0: simul.beads.names = rn else: # we are initializing a specific atom simul.beads.names[v.index:v.index + 1] = rn else: raise ValueError( "Cannot change the label of a single bead") flab = True elif k == "positions": if fpos: warning("Overwriting previous atomic positions", verbosity.medium) # read the atomic positions as a vector rq = init_vector(v, self.nbeads) rq *= unit_to_internal("length", v.units, 1.0) (nbeads, natoms) = rq.shape natoms /= 3 # check if we must initialize the simulation beads if simul.beads.nbeads == 0: if v.index >= 0: raise ValueError( "Cannot initialize single atoms before the size of the system is known" ) simul.beads.resize(natoms, self.nbeads) set_vector(v, simul.beads.q, rq) fpos = True elif ( k == "velocities" or k == "momenta" ) and v.mode == "thermal": # intercept here thermal initialization, so we don't need to check further down if fmom: warning("Overwriting previous atomic momenta", verbosity.medium) if simul.beads.natoms == 0: raise ValueError( "Cannot initialize momenta before the size of the system is known." ) if not fmass: raise ValueError( "Trying to resample velocities before having masses.") rtemp = v.value * unit_to_internal("temperature", v.units, 1.0) if rtemp <= 0: warning( "Using the simulation temperature to resample velocities", verbosity.low) rtemp = simul.ensemble.temp else: info( " # Resampling velocities at temperature %s %s" % (v.value, v.units), verbosity.low) # pull together a mock initialization to get NM masses right #without too much code duplication if v.bead >= 0: raise ValueError("Cannot thermalize a single bead") if v.index >= 0: rnatoms = 1 else: rnatoms = simul.beads.natoms rbeads = Beads(rnatoms, simul.beads.nbeads) if v.index < 0: rbeads.m[:] = simul.beads.m else: rbeads.m[:] = simul.beads.m[v.index] rnm = NormalModes(mode=simul.nm.mode, transform_method=simul.nm.transform_method, freqs=simul.nm.nm_freqs) rens = Ensemble(dt=simul.ensemble.dt, temp=simul.ensemble.temp) rnm.bind(rbeads, rens) # then we exploit the sync magic to do a complicated initialization # in the NM representation # with (possibly) shifted-frequencies NM rnm.pnm = simul.prng.gvec( (rbeads.nbeads, 3 * rbeads.natoms)) * np.sqrt( rnm.dynm3) * np.sqrt( rbeads.nbeads * rtemp * Constants.kb) if v.index < 0: simul.beads.p = rbeads.p else: simul.beads.p[:, 3 * v.index:3 * (v.index + 1)] = rbeads.p fmom = True elif k == "momenta": if fmom: warning("Overwriting previous atomic momenta", verbosity.medium) # read the atomic momenta as a vector rp = init_vector(v, self.nbeads, momenta=True) rp *= unit_to_internal("momentum", v.units, 1.0) (nbeads, natoms) = rp.shape natoms /= 3 # checks if we must initialize the simulation beads if simul.beads.nbeads == 0: if v.index >= 0: raise ValueError( "Cannot initialize single atoms before the size of the system is known" ) simul.beads.resize(natoms, self.nbeads) rp *= np.sqrt(self.nbeads / nbeads) set_vector(v, simul.beads.p, rp) fmom = True elif k == "velocities": if fmom: warning("Overwriting previous atomic momenta", verbosity.medium) # read the atomic velocities as a vector rv = init_vector(v, self.nbeads) rv *= unit_to_internal("velocity", v.units, 1.0) (nbeads, natoms) = rv.shape natoms /= 3 # checks if we must initialize the simulation beads if simul.beads.nbeads == 0 or not fmass: ValueError( "Cannot initialize velocities before the masses of the atoms are known" ) simul.beads.resize(natoms, self.nbeads) warning( "Initializing from velocities uses the previously defined masses -- not the masses inferred from the file -- to build momenta", verbosity.low) if v.index >= 0: rv *= simul.beads.m[v.index] elif v.bead >= 0: rv *= simul.beads.m3[0] else: rv *= simul.beads.m3 rv *= np.sqrt(self.nbeads / nbeads) set_vector(v, simul.beads.p, rv) fmom = True elif k == "thermostat": pass # thermostats must be initialized in a second stage if simul.beads.natoms == 0: raise ValueError( "Initializer could not initialize the atomic positions") if simul.cell.V == 0: raise ValueError("Initializer could not initialize the cell") for i in range(simul.beads.natoms): if simul.beads.m[i] <= 0: raise ValueError("Initializer could not initialize the masses") if simul.beads.names[i] == "": raise ValueError( "Initializer could not initialize the atom labels") if not fmom: warning( "Momenta not specified in initialize. Will start with zero velocity if they are not specified in beads.", verbosity.low)
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 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
# This file is part of i-PI. # i-PI Copyright (C) 2014-2015 i-PI developers # See the "licenses" directory for full license information. import filecmp import os import numpy as np from numpy.testing import assert_equal from ipi_tests.unit_tests.common.folder import local from ipi.utils.units import unit_to_internal from ipi.utils.io import iter_file, read_file, print_file pos_xyz = np.array([i for i in range(3 * 3)]) pos_pdb = unit_to_internal("length", "angstrom", pos_xyz) def test_read_xyz(): """Tests that 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_iter_xyz(): """Tests that xyz files with multiple frames are read correctly."""
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()
# if not (os.path.exists(ipi_path)): # print 'We can not find ipi in %s' %ipi_path # print 'Please correct the path' # sys.exit() # sys.path.insert(0, ipi_path) from ipi.engine.simulation import Simulation from ipi.utils.units import unit_to_internal, Constants from ipi.utils.instools import red2comp from ipi.utils.hesstools import clean_hessian from ipi.engine.motion.instanton import SpringMapper # np.set_printoptions(precision=6, suppress=True, threshold=np.nan) # UNITS K2au = unit_to_internal("temperature", "kelvin", 1.0) kb = Constants.kb hbar = Constants.hbar eV2au = unit_to_internal("energy", "electronvolt", 1.0) cal2au = unit_to_internal("energy", "cal/mol", 1.0) cm2au = unit_to_internal("frequency", "hertz", 1.0) * 3e10 # INPUT parser = argparse.ArgumentParser( description="""Post-processing routine in order to obtain different quantities from an instanton (or instanton related) calculation. These quantities can be used for the calculation of rates or tunneling splittings in the instanton approximation.""" ) parser.add_argument("input", help="Restart file") parser.add_argument( "-c", "--case", default=False,
print 'We will expand the ring polymer to get a half polymer of %i beads.' % nbeadsNew # Compose the full ring polymer. #q2 = np.concatenate((q, np.flipud(q)), axis=0) # Make the rpc step #rpc = nm_rescale(2 * nbeads, 2 * nbeadsNew) #new_q = rpc.b1tob2(q2)[0:nbeadsNew] rpc = nm_rescale(nbeads, nbeadsNew, np.asarray(range(natoms))) # We use open path RPC new_q = rpc.b1tob2(q) # Print out = open("NEW_INSTANTON.xyz", "w") for i in range(nbeadsNew): atom.q = new_q[i] / unit_to_internal("length", "angstrom", 1.0) # Go back to angstrom print_file("xyz", atom, cell, out, title='cell{atomic_unit} Traj: positions{angstrom}') # print_file("xyz",pos[0],cell,out,title='cell }') out.close() print 'The new Instanton geometry (half polymer) was generated' print 'Check NEW_INSTANTON.xyz' print '' print 'Remeber to change the number of beads (%i) in your input' % nbeadsNew print '' if input_hess != 'None' or chk != 'None':
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()
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 contract_trajectory(fns_in, fn_out_template, n_new, cell_units_in, cell_units_out): verbosity.level = "low" n = len(fns_in) # Generate output file names. if n_new == 1: fns_out = [fn_out_template] else: fns_out = [fn_out_template.format(i) for i in range(n_new)] print("Contracting {:d} beads to {:d} beads.".format(n, n_new)) print() print("input file names:") for fn in fns_in: print(fn) print() print("output file names:") for fn in fns_out: print(fn) print() # Open input trajectory iterators. trjs_in = [iter_file_name_raw(fn) for fn in fns_in] mode = os.path.splitext(fn)[-1] # Open output files. fs_out = [open_backup(fn, "w") for fn in fns_out] mode_out = os.path.splitext(fn_out_template)[-1] # prepare ring polymer rescaler rescale = nm_rescale(n, n_new) # Loop over all frames. i_frame = 0 while True: try: # Get the frames for all beads. frames = [trj.next() for trj in trjs_in] except StopIteration: # Stop when any of the trajectories runs out of frames. break # gets units from first frame dimension, units, cell_units = auto_units(comment=frames[0]["comment"], cell_units=cell_units_in) if cell_units_out == "automatic": cell_units_out = cell_units # re-use units unless otherwise specified # Consistency check. h = frames[0]["cell"] natoms = len(frames[0]["data"]) / 3 for i in range(n): # Check that all the cells are the same. if (frames[i]["cell"] != h).any(): msg = "Cell for beads {:d} and {:d} differ in frame {:d}." raise ValueError(msg.format(0, i, i_frame)) # Check that the numbers of atoms are the same. if len(frames[i]["data"]) != 3 * natoms: msg = "Different numbers of atoms for beads {:d} and {:d} in frame {:d}." raise ValueError(msg.format(0, i, i_frame)) cell = Cell() cell.h = frames[0]["cell"] atoms = Atoms(natoms) atoms.names = frames[0]["names"] # Compose the ring polymer. q = np.vstack([frame["data"] for frame in frames]) * unit_to_internal( dimension, units, 1) # units transformation # Contract the coordinates to `n_new` beads. q_c = rescale.b1tob2(q) # Save the output data. for i, f_out in enumerate(fs_out): atoms.q = q_c[i, :] print_file(mode_out, atoms, cell, f_out, dimension=dimension, units=units, cell_units=cell_units_out) # Count frames and print information on progress. i_frame += 1 if i_frame % 100 == 0: print("\rframe {:d}".format(i_frame), end="") sys.stdout.flush() for f_out in fs_out: f_out.close() print() print() print("Processed {:d} frames.".format(i_frame))
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_raw("xyz", ff) 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) time = np.asarray(list(range(mlag + 1))) * dt omega = np.asarray(list(range(2 * (mlag + npad)))) / float( 2 * (mlag + npad)) * (2 * np.pi / dt) fvvacf = omega.copy() * 0.0 fvvacf2 = fvvacf.copy() * 0.0 vvacf = time.copy() * 0.0 vvacf2 = time.copy() * 0.0 # 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 range(fskip): rr = read_file_raw("xyz", ff) while True: try: # Reads the data in blocks. for i in range(bsize): rr = read_file_raw("xyz", ff) 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. mfvvacf = 3.0 * np.real(np.mean( tfvvacf, axis=(1, 2))) * dt / (2 * np.pi) / bsize # Computes the inverse Fourier transform to get the vvac. mvvacf = np.fft.irfft(mfvvacf)[:mlag + 1] # Applies window in one direction and pads the vvac with zeroes. mpvvacf = np.append(mvvacf * win[mlag:], np.zeros(npad)) # Recomputes the Fourier transform assuming the data is an even function of time. mfpvvacf = np.fft.hfft(mpvvacf) # Accumulates the (f)acfs and their squares. fvvacf += mfpvvacf fvvacf2 += mfpvvacf**2 vvacf += mvvacf vvacf2 += mvvacf**2 nblocks += 1 except EOFError: break ff.close() # Performs the block average of the Fourier transform. fvvacf = fvvacf / nblocks fvvacf_err = np.sqrt(fvvacf2 / nblocks - fvvacf**2) np.savetxt(ofile + "_facf.data", np.c_[omega, fvvacf, fvvacf_err][:mlag + npad]) # Computes the inverse Fourier transform to get the vvac. vvacf = vvacf / nblocks vvacf_err = np.sqrt(vvacf2 / nblocks - vvacf**2) np.savetxt(ofile + "_acf.data", np.c_[time, vvacf, vvacf_err][:mlag + npad])
# if not (os.path.exists(ipi_path)): # print 'We can not find ipi in %s' %ipi_path # print 'Please correct the path' # sys.exit() # sys.path.insert(0, ipi_path) from ipi.engine.simulation import Simulation from ipi.utils.units import unit_to_internal, unit_to_user, Constants, Elements from ipi.utils.instools import red2comp, clean_hessian from ipi.engine.motion.instanton import SpringMapper np.set_printoptions(precision=6, suppress=True, threshold=np.nan) # UNITS K2au = unit_to_internal("temperature", "kelvin", 1.0) kb = Constants.kb hbar = Constants.hbar eV2au = unit_to_internal("energy", "electronvolt", 1.0) cal2au = unit_to_internal("energy", "cal/mol", 1.0) au2hz = unit_to_internal("frequency", "hertz", 1.0) cm2au = au2hz * 3e10 # INPUT parser = argparse.ArgumentParser(description="""Post-processing routine in order to obtain different quantities from an instanton (or instanton related) calculation. These quantities can be used for the calculation of rates or tunneling splittings in the instanton approximation.""") parser.add_argument('input', help="Restart file") parser.add_argument('-c', '--case', default=False, help="Type of the calculation to analyse. Options: 'instanton', 'reactant' or 'TS'.") parser.add_argument('-t', '--temperature', type=float, default=0.0, help="Temperature in K.") parser.add_argument('-asr', '--asr', default='poly', help="Removes the zero frequency vibrational modes depending on the symmerty of the system") parser.add_argument('-e', '--energy_shift', type=float, default=0.0, help="Zero of energy in eV") parser.add_argument('-f', '--filter', default=[], help='List of atoms indexes to filter (i.e. eliminate its componentes in the position,mass and hessian arrays. It is 0 based.', type=int, action='append')