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 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 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 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 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 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 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 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), 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 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