def print_file_path(mode, beads, cell, filedesc=sys.stdout, title="", key="", dimension="length", units="automatic", cell_units="automatic"): """Prints all the bead configurations, into a `mode` formatted file. Prints all the replicas for each time step separately, rather than all at once. Args: beads: A beads object giving the bead positions. cell: A cell object giving the system box. filedesc: An open writable file object. Defaults to standard output. """ if mode == "pdb": # special case for PDB if dimension != "length": raise ValueError("PDB Standard is only designed for atomic positions") if units == "automatic": units = "angstrom" if cell_units == "automatic": cell_units = "angstrom" # in general, "automatic" units are actually "atomic_units" else: if units == "automatic": units = "atomic_unit" if cell_units == "automatic": cell_units = "atomic_unit" cell_conv = unit_to_user("length", cell_units, 1.0) atoms_conv = unit_to_user(dimension, units, 1.0) title = title + ("%s{%s} cell{%s}" % (key, units, cell_units)) return _get_io_function(mode, "print_path")(beads=beads, cell=cell, filedesc=filedesc, cell_conv=cell_conv, atoms_conv=atoms_conv)
def print_instanton_geo(prefix, step, nbeads, natoms, names, q, pots, cell, shift, output_maker): outfile = output_maker.get_output(prefix + '_' + str(step) + '.ener', 'w') print >> outfile, ('#Bead Energy (eV)') for i in range(nbeads): print >> outfile, (str(i) + ' ' + str(units.unit_to_user('energy', "electronvolt", pots[i] - shift))) outfile.close() # print_file("xyz", pos[0], cell, out, title='positions{angstrom}') unit = 'angstrom' a, b, c, alpha, beta, gamma = mt.h2abc_deg(cell.h) outfile = output_maker.get_output(prefix + '_' + str(step) + '.xyz', 'w') for i in range(nbeads): print >> outfile, natoms print >> outfile, ('CELL(abcABC): %f %f %f %f %f %f cell{atomic_unit} Traj: positions{%s} Bead: %i' % (a, b, c, alpha, beta, gamma, unit, i)) for j in range(natoms): print >> outfile, names[j], \ str(units.unit_to_user('length', unit, q[i, 3 * j])), \ str(units.unit_to_user('length', unit, q[i, 3 * j + 1])), \ str(units.unit_to_user('length', unit, q[i, 3 * j + 2])) outfile.close()
def print_file(mode, atoms, cell, filedesc=sys.stdout, title="", key="", dimension="length", units="automatic", cell_units="automatic"): """Prints atom positions, or atom-vector properties, into a `mode` formatted file, using i-PI internal representation of atoms & cell. Does conversion and prepares formatted title line. Args: mode: I/O file format (e.g. "xyz") atoms: An atoms object containing the positions (or properties) of the atoms cell: A cell object containing the system box. filedesc: An open writable file object. Defaults to standard output. title: This gives a string to be appended to the comment line. key: Description of the property that is being output dimension: Dimensions of the property (e.g. "length") units: Units for the output (e.g. "angstrom") cell_units: Units for the cell (dimension length, e.g. "angstrom") """ if mode == "pdb": # special case for PDB if dimension != "length": raise ValueError("PDB Standard is only designed for atomic positions") if units == "automatic": units = "angstrom" if cell_units == "automatic": cell_units = "angstrom" if key == "": key = "positions" # in general, "automatic" units are actually "atomic_units" else: if units == "automatic": units = "atomic_unit" if cell_units == "automatic": cell_units = "atomic_unit" cell_conv = unit_to_user("length", cell_units, 1.0) atoms_conv = unit_to_user(dimension, units, 1.0) title = title + ("%s{%s} cell{%s}" % (key, units, cell_units)) print_file_raw(mode=mode, atoms=atoms, cell=cell, filedesc=filedesc, title=title, cell_conv=cell_conv, atoms_conv=atoms_conv)
def __init__(self, init_file, args_str, param_file, latency=1.0e-3, name="", pars=None, dopbc=True, threaded=False): """Initialises QUIP. Args: pars: Mandatory dictionary, giving the parameters needed by QUIP. """ if quippy is None: info("QUIPPY import failed", verbosity.low) raise quippy_exc # a socket to the communication library is created or linked super(FFQUIP, self).__init__(latency, name, pars, dopbc, threaded=threaded) self.init_file = init_file self.args_str = args_str self.param_file = param_file # Initializes an atoms object and the interaction potential self.atoms = quippy.Atoms(self.init_file) self.pot = quippy.Potential(self.args_str, param_filename=self.param_file) # Initializes the conversion factors from i-pi to QUIP self.len_conv = unit_to_user("length", "angstrom", 1) self.energy_conv = unit_to_user("energy", "electronvolt", 1) self.force_conv = unit_to_user("force", "ev/ang", 1)
def store(self, value, units=""): """Converts the data to the appropriate data type and units and stores it. Args: value: The raw data to be stored. units: Optional string giving the units that the data should be stored in. """ super(InputValue, self).store(value) if units != "": self.units.store(units) # User can define in the code the units to be printed self.value = value if self._dimension != "undefined": self.value *= unit_to_user(self._dimension, units, 1.0)
def write(self): """Outputs the required properties of the system. Note that properties are outputted using the same format as for the output to the xml checkpoint files, as specified in io_xml. Raises: KeyError: Raised if one of the properties specified in the output list are not contained in the property_dict member of properties. """ if softexit.triggered: return # don't write if we are about to exit! if not (self.system.simul.step + 1) % self.stride == 0: return self.out.write(" ") for what in self.outlist: try: quantity, dimension, unit = self.system.properties[what] if dimension != "" and unit != "": quantity = unit_to_user(dimension, unit, quantity) except KeyError: raise KeyError(what + " is not a recognized property") if not hasattr(quantity, "__len__"): self.out.write(write_type(float, quantity) + " ") else: for el in quantity: self.out.write(write_type(float, el) + " ") self.out.write("\n") self.nout += 1 if self.flush > 0 and self.nout >= self.flush: self.out.flush() os.fsync(self.out) # we REALLY want to print out! pretty please OS let us do it. self.nout = 0
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 totalEnergy(prefix, temp, ss=0, unit=''): """ Computes the virial centroid estimator for the total energy and PPI correction. """ # Adding fortran functions (when exist) sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90') fast_code = True try: import fortran except: fast_code = False print('WARNING: No compiled fortran module for fast calculations have been found.\n' 'Calculations will use a slower python script.') temperature = unit_to_internal("temperature", "kelvin", float(temp)) # simulation temperature skipSteps = int(ss) # steps to skip for thermalization f2_av, ePA_av, eVir_av, f2ePA_av = 0.0, 0.0, 0.0, 0.0 # some required sums fns_pos = sorted(glob.glob(prefix + ".pos*")) fns_for = sorted(glob.glob(prefix + ".for*")) fns_iU = glob.glob(prefix + ".out")[0] fn_out_en = prefix + ".total_energy.dat" # check that we found the same number of positions and forces files nbeads = len(fns_pos) if nbeads != len(fns_for): print fns_pos print fns_for raise ValueError("Mismatch between number of input files for forces and positions.") # print some information print 'temperature = {:f} K'.format(float(temp)) print print 'number of beads = {:d}'.format(nbeads) print print 'positions and forces file names:' for fn_pos, fn_for in zip(fns_pos, fns_for): print '{:s} {:s}'.format(fn_pos, fn_for) print print 'potential energy file: {:s}'.format(fns_iU) print print 'output file name:' print fn_out_en print # open input and output files ipos = [open(fn, "r") for fn in fns_pos] ifor = [open(fn, "r") for fn in fns_for] iU = open(fns_iU, "r") iE = open(fn_out_en, "w") # Some constants beta = 1.0 / (Constants.kb * temperature) const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2 const_2 = 1.5 * nbeads / beta const_3 = 1.5 / beta const_4 = Constants.kb**2 / Constants.hbar**2 const_5 = Constants.hbar**2 * beta**3 / (24.0 * nbeads**3) timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits(iU) # extracting simulation time # and potential energy units # Defining the output energy unit if unit == '': unit = potentialEnergyUnit iE.write("# Simulation time (in %s), virial total energy and PPI energy correction (in %s)\n" % (timeUnit, unit)) natoms = 0 ifr = 0 time0 = 0 q, f, m = None, None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print '\rProcessing frame {:d}'.format(ifr), sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ipos[i], output='arrays') if natoms == 0: m, natoms = ret["masses"], ret["natoms"] q = np.zeros((nbeads, 3 * natoms)) f = np.zeros((nbeads, 3 * natoms)) q[i, :] = ret["data"] f[i, :] = read_file("xyz", ifor[i], output='arrays')["data"] U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index) except EOFError: # finished reading files sys.exit(0) if ifr < skipSteps: time0 = time if ifr >= skipSteps: # PPI correction time -= time0 ePA, f2, f2ePA, eVir = 0.0, 0.0, 0.0, 0.0 if not fast_code: for j in range(nbeads): for i in range(natoms): f2 += np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i] for i in range(natoms): ePA -= np.dot(q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3]) * m[i] for j in range(nbeads - 1): for i in range(natoms): ePA -= np.dot(q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3]) * m[i] rc = np.zeros(3) for i in range(natoms): rc[:] = 0.0 for j in range(nbeads): rc[:] += q[j, i * 3:i * 3 + 3] rc[:] /= nbeads for j in range(nbeads): eVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) ePA *= const_1 ePA += const_2 * natoms + U f2ePA = f2 * ePA eVir /= 2.0 * nbeads eVir += const_3 * natoms + U else: f2 = fortran.f2divm(np.array(f, order='F'), np.array(m, order='F'), natoms, nbeads) ePA = fortran.findcoupling(np.array(q, order='F'), np.array(m, order='F'), temperature, natoms, nbeads) eVir = fortran.findcentroidvirialkineticenergy(np.array(f, order='F'), np.array(q, order='F'), natoms, nbeads) ePA *= const_4 ePA += const_2 * natoms + U f2ePA = f2 * ePA eVir += const_3 * natoms + U ePA_av += ePA f2_av += f2 f2ePA_av += f2ePA eVir_av += eVir ifr += 1 norm = float(ifr - skipSteps) dE = (3.0 * Constants.kb * temperature + ePA_av / norm) * f2_av / norm - f2ePA_av / norm dE *= const_5 dE = unit_to_user("energy", unit, dE) eVir = unit_to_user("energy", unit, eVir_av / norm) iE.write("%f %f %f\n" % (time, eVir, dE)) else: ifr += 1
def RDF(prefix, temp, A, B, nbins, r_min, r_max, ss=0, unit='angstrom'): # Adding fortran functions (when exist) sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90') try: import fortran except: print('WARNING: No compiled fortran module for fast calculations have been found.\n' 'Proceeding the calculations is not possible.') sys.exit(0) temperature = unit_to_internal("temperature", "kelvin", float(temp)) # simulation temperature skipSteps = int(ss) # steps to skip nbins = int(nbins) fns_pos = sorted(glob.glob(prefix + ".pos*")) fns_for = sorted(glob.glob(prefix + ".for*")) fn_out_rdf, fn_out_rdf_q = prefix + '.' + A + B + ".rdf.dat", prefix + '.' + A + B + ".rdf-ppi.dat" # check that we found the same number of positions and forces files nbeads = len(fns_pos) if nbeads != len(fns_for): print(fns_pos) print(fns_for) raise ValueError("Mismatch between number of input files for forces and positions.") # print some information print('temperature = {:f} K'.format(float(temp))) print() print('number of beads = {:d}'.format(nbeads)) print() print('positions and forces file names:') for fn_pos, fn_for in zip(fns_pos, fns_for): print('{:s} {:s}'.format(fn_pos, fn_for)) print() print('output file names:') print(fn_out_rdf) print(fn_out_rdf_q) print() # open input and output files ipos = [open(fn, "r") for fn in fns_pos] ifor = [open(fn, "r") for fn in fns_for] # iRDF, iRDFq = open(fn_out_rdf, "w"), open(fn_out_rdf_q, "w") # Species for RDF species = (A, B) speciesMass = np.array([Elements.mass(species[0]), Elements.mass(species[1])], order='F') r_min = unit_to_internal('length', unit, float(r_min)) # Minimal distance for RDF r_max = unit_to_internal('length', unit, float(r_max)) # Maximal distance for RDF dr = (r_max - r_min) / nbins # RDF step rdf = np.array([[r_min + (0.5 + i) * dr, 0] for i in range(nbins)], order='F') # conventional RDF # RDF auxiliary variables cell = None # simulation cell matrix inverseCell = None # inverse simulation sell matrix cellVolume = None # simulation cell volume natomsA = 0 # the total number of A type particles in the system natomsB = 0 # the total number of B type particles in the system # Here A and B are the types of elements used for RDF calculations # temp variables f2 = 0.0 # the sum of square forces divided by corresponding masses (f2/m) f2rdf = np.zeros(nbins, order='F') # the sum f2/m multiplied by the rdf at each time step frdf = np.zeros(nbins, order='F') # the sum of f/m multiplied by the rdf derivative at each time step natoms = 0 # total number of atoms ifr = 0 # time frame number pos, force, mass = None, None, None # positions, forces, and mass arrays noteof = True # end of file test variable while noteof: # Reading input files and calculating PPI correction if ifr % 100 == 0: print('\rProcessing frame {:d}'.format(ifr), end=' ') sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ipos[i], dimension='length') 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], dimension='force')["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 if ifr > skipSteps and ifr % 100 == 0: # 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 = np.copy(rdf) _f2rdf = np.copy(f2rdf) _frdf = np.copy(frdf) _rdf[:, 1] *= const / nbeads _f2 = 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 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 step(self, step=None): """ Does one simulation time step.""" activearrays = self.pre_step(step) fff = activearrays["old_f"] * (self.im.coef[1:] + self.im.coef[:-1]) / 2 f = (fff + self.im.f).reshape(self.im.dbeads.natoms * 3 * self.im.dbeads.nbeads, 1) banded = False banded = True if banded: # BANDED Version # MASS-scaled dyn_mat = get_dynmat(activearrays["hessian"], self.im.dbeads.m3, self.im.dbeads.nbeads) h_up_band = banded_hessian(dyn_mat, self.im, masses=False, shift=0.000000001) # create upper band matrix f = np.multiply(f, self.im.dbeads.m3.reshape(f.shape)**-0.5) # CARTESIAN # h_up_band = banded_hessian(activearrays["hessian"], self.im,masses=True) # create upper band matrix d = diag_banded(h_up_band) else: # FULL dimensions version h_0 = red2comp(activearrays["hessian"], self.im.dbeads.nbeads, self.im.dbeads.natoms, self.im.coef) h_test = np.add(self.im.h, h_0) # add spring terms to the physical hessian d, w = clean_hessian(h_test, self.im.dbeads.q, self.im.dbeads.natoms, self.im.dbeads.nbeads, self.im.dbeads.m, self.im.dbeads.m3, None) # CARTESIAN # d,w =np.linalg.eigh(h_test) #Cartesian info('\n@Lanczos: 1st freq {} cm^-1'.format(units.unit_to_user('frequency', 'inversecm', np.sign(d[0]) * np.sqrt(np.absolute(d[0])))), verbosity.medium) info('@Lanczos: 2nd freq {} cm^-1'.format(units.unit_to_user('frequency', 'inversecm', np.sign(d[1]) * np.sqrt(np.absolute(d[1])))), verbosity.medium) info('@Lanczos: 3rd freq {} cm^-1\n'.format(units.unit_to_user('frequency', 'inversecm', np.sign(d[2]) * np.sqrt(np.absolute(d[2])))), verbosity.medium) if d[0] > 0: if d[1] / 2 > d[0]: alpha = 1 lamb = (2 * d[0] + d[1]) / 4 else: alpha = (d[1] - d[0]) / d[1] lamb = (3 * d[0] + d[1]) / 4 # midpoint between b[0] and b[1]*(1-alpha/2) elif d[1] < 0: # Jeremy Richardson if (d[1] >= d[0] / 2): alpha = 1 lamb = (d[0] + 2 * d[1]) / 4 else: alpha = (d[0] - d[1]) / d[1] lamb = (d[0] + 3 * d[1]) / 4 # elif d[1] < 0: #Litman for Second Order Saddle point # alpha = 1 # lamb = (d[1] + d[2]) / 4 # print 'WARNING: We are not using the standard Nichols' # print 'd_x', d_x[0],d_x[1] else: # Only d[0] <0 alpha = 1 lamb = (d[0] + d[1]) / 4 if banded: h_up_band[-1, :] += - np.ones(h_up_band.shape[1]) * lamb d_x = invmul_banded(h_up_band, f) else: h_test = alpha * (h_test - np.eye(h_test.shape[0]) * lamb) d_x = np.linalg.solve(h_test, f) d_x.shape = self.im.dbeads.q.shape # MASS-scaled d_x = np.multiply(d_x, self.im.dbeads.m3**-0.5) # Rescale step if necessary if np.amax(np.absolute(d_x)) > activearrays["big_step"]: info("Step norm, scaled down to {}".format(activearrays["big_step"]), verbosity.low) d_x *= activearrays["big_step"] / np.amax(np.absolute(d_x)) # Get the new full-position d_x_full = self.fix.get_full_vector(d_x, t=1) new_x = self.optarrays["old_x"].copy() + d_x_full self.post_step(step, new_x, d_x, activearrays)
def totalEnergy(prefix, temp, ss=0, unit=''): """ Computes the virial centroid estimator for the total energy and PPI correction. """ # Adding fortran functions (when exist) sys.path.append(os.path.abspath(os.path.dirname(sys.argv[0]))[:-2] + 'f90') fast_code = True try: import fortran except: fast_code = False print( 'WARNING: No compiled fortran module for fast calculations have been found.\n' 'Calculations will use a slower python script.') temperature = unit_to_internal("temperature", "kelvin", float(temp)) # simulation temperature skipSteps = int(ss) # steps to skip for thermalization f2_av, ePA_av, eVir_av, f2ePA_av = 0.0, 0.0, 0.0, 0.0 # some required sums fns_pos = sorted(glob.glob(prefix + ".pos*")) fns_for = sorted(glob.glob(prefix + ".for*")) fns_iU = glob.glob(prefix + ".out")[0] fn_out_en = prefix + ".total_energy.dat" # check that we found the same number of positions and forces files nbeads = len(fns_pos) if nbeads != len(fns_for): print fns_pos print fns_for raise ValueError( "Mismatch between number of input files for forces and positions.") # print some information print 'temperature = {:f} K'.format(float(temp)) print print 'number of beads = {:d}'.format(nbeads) print print 'positions and forces file names:' for fn_pos, fn_for in zip(fns_pos, fns_for): print '{:s} {:s}'.format(fn_pos, fn_for) print print 'potential energy file: {:s}'.format(fns_iU) print print 'output file name:' print fn_out_en print # open input and output files ipos = [open(fn, "r") for fn in fns_pos] ifor = [open(fn, "r") for fn in fns_for] iU = open(fns_iU, "r") iE = open(fn_out_en, "w") # Some constants beta = 1.0 / (Constants.kb * temperature) const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2 const_2 = 1.5 * nbeads / beta const_3 = 1.5 / beta const_4 = Constants.kb**2 / Constants.hbar**2 const_5 = Constants.hbar**2 * beta**3 / (24.0 * nbeads**3) timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits( iU) # extracting simulation time # and potential energy units # Defining the output energy unit if unit == '': unit = potentialEnergyUnit iE.write( "# Simulation time (in %s), virial total energy and PPI energy correction (in %s)\n" % (timeUnit, unit)) natoms = 0 ifr = 0 time0 = 0 q, f, m = None, None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print '\rProcessing frame {:d}'.format(ifr), sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ipos[i], output='arrays') if natoms == 0: m, natoms = ret["masses"], ret["natoms"] q = np.zeros((nbeads, 3 * natoms)) f = np.zeros((nbeads, 3 * natoms)) q[i, :] = ret["data"] f[i, :] = read_file("xyz", ifor[i], output='arrays')["data"] U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index) except EOFError: # finished reading files sys.exit(0) if ifr < skipSteps: time0 = time if ifr >= skipSteps: # PPI correction time -= time0 ePA, f2, f2ePA, eVir = 0.0, 0.0, 0.0, 0.0 if not fast_code: for j in range(nbeads): for i in range(natoms): f2 += np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i] for i in range(natoms): ePA -= np.dot( q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3]) * m[i] for j in range(nbeads - 1): for i in range(natoms): ePA -= np.dot( q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3]) * m[i] rc = np.zeros(3) for i in range(natoms): rc[:] = 0.0 for j in range(nbeads): rc[:] += q[j, i * 3:i * 3 + 3] rc[:] /= nbeads for j in range(nbeads): eVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) ePA *= const_1 ePA += const_2 * natoms + U f2ePA = f2 * ePA eVir /= 2.0 * nbeads eVir += const_3 * natoms + U else: f2 = fortran.f2divm(np.array(f, order='F'), np.array(m, order='F'), natoms, nbeads) ePA = fortran.findcoupling(np.array(q, order='F'), np.array(m, order='F'), temperature, natoms, nbeads) eVir = fortran.findcentroidvirialkineticenergy( np.array(f, order='F'), np.array(q, order='F'), natoms, nbeads) ePA *= const_4 ePA += const_2 * natoms + U f2ePA = f2 * ePA eVir += const_3 * natoms + U ePA_av += ePA f2_av += f2 f2ePA_av += f2ePA eVir_av += eVir ifr += 1 norm = float(ifr - skipSteps) dE = (3.0 * Constants.kb * temperature + ePA_av / norm) * f2_av / norm - f2ePA_av / norm dE *= const_5 dE = unit_to_user("energy", unit, dE) eVir = unit_to_user("energy", unit, eVir_av / norm) iE.write("%f %f %f\n" % (time, eVir, dE)) else: ifr += 1
def 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 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 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 KPa_av, KVir_av, U_av, f2_av, f2KPa_av, f2U_av = ( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ) # some required sums fns_pos = sorted(glob.glob(prefix + ".pos*")) fns_for = sorted(glob.glob(prefix + ".for*")) fns_iU = glob.glob(prefix + ".out")[0] fn_out_en = prefix + ".energies.dat" # check that we found the same number of positions and forces files nbeads = len(fns_pos) if nbeads != len(fns_for): print(fns_pos) print(fns_for) raise ValueError( "Mismatch between number of input files for forces and positions.") # print some information print("temperature = {:f} K".format(float(temp))) print() print("number of beads = {:d}".format(nbeads)) print() print("positions and forces file names:") for fn_pos, fn_for in zip(fns_pos, fns_for): print("{:s} {:s}".format(fn_pos, fn_for)) print() print("potential energy file: {:s}".format(fns_iU)) print() print("output file name:") print(fn_out_en) print() # open input and output files ipos = [open(fn, "r") for fn in fns_pos] ifor = [open(fn, "r") for fn in fns_for] iU = open(fns_iU, "r") iE = open(fn_out_en, "w") # Some constants beta = 1.0 / (Constants.kb * temperature) const_1 = 0.5 * nbeads / (beta * Constants.hbar)**2 const_2 = 1.5 * nbeads / beta const_3 = 1.5 / beta const_4 = Constants.kb**2 / Constants.hbar**2 const_5 = Constants.hbar**2 * beta**3 / (24.0 * nbeads**3) const_6 = Constants.hbar**2 * beta**2 / (24.0 * nbeads**3) timeUnit, potentialEnergyUnit, potentialEnergy_index, time_index = extractUnits( iU) # extracting simulation time # and potential energy units # Defining the output energy unit if unit == "": unit = potentialEnergyUnit iE.write( "# Simulation time (in %s), improved total energy estimator, virial total energy estimator, and PPI " "correction for the total energy; improved potential energy estimator, potential energy estimatorand, " "PPI correction for the potential energy; improved kinetic energy estimator, virial kinetic energy " "estimator, and PPI correction for the kinetic energy (all in %s)\n" % (timeUnit, unit)) iE.close() natoms = 0 ifr = 0 time0 = 0 q, f, m = None, None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print("\rProcessing frame {:d}".format(ifr), end=" ") sys.stdout.flush() try: for i in range(nbeads): ret = read_file("xyz", ipos[i], dimension="length")["atoms"] if natoms == 0: m, natoms = ret.m, ret.natoms q = np.zeros((nbeads, 3 * natoms)) f = np.zeros((nbeads, 3 * natoms)) q[i, :] = ret.q f[i, :] = read_file("xyz", ifor[i], dimension="force")["atoms"].q U, time = read_U(iU, potentialEnergyUnit, potentialEnergy_index, time_index) except EOFError: # finished reading files sys.exit(0) if ifr < skipSteps: time0 = time if ifr >= skipSteps: # PPI correction time -= time0 KPa, f2, KVir = 0.0, 0.0, 0.0 if not fast_code: for j in range(nbeads): for i in range(natoms): f2 += (np.dot(f[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) / m[i]) for i in range(natoms): KPa -= (np.dot( q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], q[0, i * 3:i * 3 + 3] - q[nbeads - 1, i * 3:i * 3 + 3], ) * m[i]) for j in range(nbeads - 1): for i in range(natoms): KPa -= (np.dot( q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], q[j + 1, i * 3:i * 3 + 3] - q[j, i * 3:i * 3 + 3], ) * m[i]) rc = np.zeros(3) for i in range(natoms): rc[:] = 0.0 for j in range(nbeads): rc[:] += q[j, i * 3:i * 3 + 3] rc[:] /= nbeads for j in range(nbeads): KVir += np.dot(rc[:] - q[j, i * 3:i * 3 + 3], f[j, i * 3:i * 3 + 3]) KPa *= const_1 KPa += const_2 * natoms KVir /= 2.0 * nbeads KVir += const_3 * natoms else: f2 = fortran.f2divm(np.array(f, order="F"), np.array(m, order="F"), natoms, nbeads) KPa = fortran.findcoupling( np.array(q, order="F"), np.array(m, order="F"), temperature, natoms, nbeads, ) KVir = fortran.findcentroidvirialkineticenergy( np.array(f, order="F"), np.array(q, order="F"), natoms, nbeads) KPa *= const_4 KPa += const_2 * natoms KVir += const_3 * natoms f2_av += f2 KPa_av += KPa f2KPa_av += f2 * KPa U_av += U f2U_av += f2 * U KVir_av += KVir ifr += 1 norm = float(ifr - skipSteps) dU = 2 * f2_av / norm - beta * (f2U_av / norm - f2_av * U_av / norm**2) dU *= const_6 dU = unit_to_user("energy", unit, dU) dK = (Constants.kb * temperature + KPa_av / norm) * f2_av / norm - f2KPa_av / norm dK *= const_5 dK = unit_to_user("energy", unit, dK) U = unit_to_user("energy", unit, U_av / norm) KVir = unit_to_user("energy", unit, KVir_av / norm) iE = open(fn_out_en, "a") iE.write( "%f %f %f %f %f %f %f %f %f %f\n" % ( time, KVir + U + dK + dU, KVir + U, dK + dU, U + dU, U, dU, KVir + dK, KVir, dK, )) iE.close() else: ifr += 1
def effectiveTemperatures(prefix, temp, ss=0): """ Computes effective temperatures for a given (PI)MD dynamics. """ temperature = unit_to_internal("temperature", "kelvin", float(temp)) # simulation temperature skipSteps = int(ss) # steps to skip for thermalization f2_av = None # average square forces array names = None fns_for = sorted(glob.glob(prefix + ".for*")) fn_out = prefix + ".effective_temperatures.dat" nbeads = len(fns_for) # print some information print 'temperature = {:f} K'.format(float(temp)) print print 'number of beads = {:d}'.format(nbeads) print print 'forces file names:' for fn_for in fns_for: print '{:s}'.format(fn_for) print print 'output file name:' print fn_out print # open input and output files ifor = [open(fn, "r") for fn in fns_for] iOut = open(fn_out, "w") # Some constants const = Constants.hbar**2 / (12.0 * (nbeads * Constants.kb * temperature)**3) iOut.write("# Atom, Cartesian components of the effective temperature, average effective temperature (in Kelvin)\n") natoms = 0 ifr = 0 f, m = None, None while True: # Reading input files and calculating PPI correction if ifr % 100 == 0: print '\rProcessing frame {:d}'.format(ifr), 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()