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