Skip to content

Commit

Permalink
Fixed temperature scanning
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Paton authored and Robert Paton committed Aug 10, 2017
1 parent 4a1e754 commit b9774f0
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 47 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ This correction from 1 atm to 1 mol/l is responsible for the addition 1.89 kcal/

#### Example 4: Analyzing the Gibbs energy across an interval of temperatures 300-1000 K with a stepsize of 100 K, applying a (Truhlar type) cut-off of 100 cm<sup>-1</sup>
```python
python GoodVibes.py examples/methylaniline.out –ti 300,1000,100 –qh truhlar –f 100
python GoodVibes.py examples/methylaniline.out –-ti '300,1000,100' –q truhlar –f 100

H/au T.S/au T.qh-S/au G(T)/au qh-G(T)/au
***************************************************************************************************************************
**********************************************************************************************************
o examples/methylaniline.out @ 300.0 -326.514399 0.040005 0.040005 -326.554404 -326.554404
o examples/methylaniline.out @ 400.0 -326.508735 0.059816 0.059816 -326.568551 -326.568551
o examples/methylaniline.out @ 500.0 -326.501670 0.082625 0.082625 -326.584296 -326.584296
Expand All @@ -85,7 +85,7 @@ o examples/methylaniline.out @ 1000.0 -326.452307 0.232169 0.232169

```

Note that the energy and ZPE are not printed in this instance since they are temperature-independent. The Truhlar-type quasiharmonic correction sets all frequencies below than 100 cm<sup>-1</sup> to a value of 100.
Note that the energy and ZPE are not printed in this instance since they are temperature-independent. The Truhlar-type quasiharmonic correction sets all frequencies below than 100 cm<sup>-1</sup> to a value of 100. Constant pressure is assumed, so that the concentration is recomputed at each temperature.

#### Example 5: Analyzing the Gibbs Energy using scaled vibrational frequencies
```python
Expand Down
81 changes: 37 additions & 44 deletions goodvibes/GoodVibes.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def calc_rotational_entropy(zpe, linear, symmno, roconst, temperature):
Strans = 0 (atomic) ; R(Ln(q)+1) (linear); R(Ln(q)+3/2) (non-linear)
"""
# monatomic
if roconst == [0.0,0.0,0.0]: return 0.0
if roconst == [0.0,0.0,0.0] or zpe == 0.0: entropy = 0.0
rotemp = [const * PLANCK_CONSTANT * 1e9 / BOLTZMANN_CONSTANT for const in roconst]

# diatomic
Expand All @@ -196,8 +196,6 @@ def calc_rotational_entropy(zpe, linear, symmno, roconst, temperature):

qrot = qrot/symmno

if zpe == 0.0: entropy = 0.0 # monatomic

if linear == 1: entropy = GAS_CONSTANT * (math.log(qrot) + 1)
else: entropy = GAS_CONSTANT * (math.log(qrot) + 1.5)
return entropy
Expand Down Expand Up @@ -261,16 +259,8 @@ def __init__(self, file, QH, FREQ_CUTOFF, temperature, conc, freq_scale_factor,
# if spc specified will take last Energy from file, otherwise will break after freq calc
if link > freqloc and spc == False: break

<<<<<<< Updated upstream
# Iterate over output
#for line in g09_output:
# look for low frequencies
#if line.find("Proceeding to internal job step")!= -1: frequency_wn = [] #resets the array if frequencies have been calculated more than once
if line.startswith(' Frequencies --'):
=======
# Iterate over output: look out for low frequencies
if line.strip().startswith('Frequencies --'):
>>>>>>> Stashed changes
for i in range(2,5):
try:
x = float(line.strip().split()[i])
Expand Down Expand Up @@ -299,21 +289,21 @@ def __init__(self, file, QH, FREQ_CUTOFF, temperature, conc, freq_scale_factor,
cutoffs = [FREQ_CUTOFF for freq in frequency_wn]

# Translational and electronic contributions to the energy and entropy do not depend on frequencies
Utrans = calc_translational_energy(options.temperature)
Strans = calc_translational_entropy(molecular_mass, conc, options.temperature, solv)
Utrans = calc_translational_energy(temperature)
Strans = calc_translational_entropy(molecular_mass, conc, temperature, solv)
Selec = calc_electronic_entropy(mult)

# Rotational and Vibrational contributions to the energy entropy
if len(frequency_wn) > 0:
ZPE = calc_zeropoint_energy(frequency_wn, freq_scale_factor)
Urot = calc_rotational_energy(self.zero_point_corr, symmno, options.temperature, linear_mol)
Uvib = calc_vibrational_energy(frequency_wn, options.temperature, freq_scale_factor)
Srot = calc_rotational_entropy(self.zero_point_corr, linear_mol, symmno, roconst, options.temperature)
Urot = calc_rotational_energy(self.zero_point_corr, symmno, temperature, linear_mol)
Uvib = calc_vibrational_energy(frequency_wn, temperature, freq_scale_factor)
Srot = calc_rotational_entropy(self.zero_point_corr, linear_mol, symmno, roconst, temperature)

# Calculate harmonic entropy, free-rotor entropy and damping function for each frequency
Svib_rrho = calc_rrho_entropy(frequency_wn, options.temperature, freq_scale_factor)
if FREQ_CUTOFF > 0.0: Svib_rrqho = calc_rrho_entropy(cutoffs, options.temperature,1.0)
Svib_free_rot = calc_freerot_entropy(frequency_wn, options.temperature, freq_scale_factor)
Svib_rrho = calc_rrho_entropy(frequency_wn, temperature, freq_scale_factor)
if FREQ_CUTOFF > 0.0: Svib_rrqho = calc_rrho_entropy(cutoffs, temperature, 1.0)
Svib_free_rot = calc_freerot_entropy(frequency_wn, temperature, freq_scale_factor)
damp = calc_damp(frequency_wn, FREQ_CUTOFF)

# Compute entropy (cal/mol/K) using the two values and damping function
Expand All @@ -326,21 +316,23 @@ def __init__(self, file, QH, FREQ_CUTOFF, temperature, conc, freq_scale_factor,
else: vib_entropy.append(Svib_rrqho[j])
else: vib_entropy.append(Svib_rrho[j])
qh_Svib, h_Svib = sum(vib_entropy), sum(Svib_rrho)
# for monatomic species only

# monatomic species have no vibrational or rotational degrees of freedom
else: ZPE, Urot, Uvib, Srot, h_Svib, qh_Svib = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0

# Add all terms (au) to get Free energy - perform separately for harmonic and quasi-harmonic values out of interest
# All units are converted to a.u. here
self.enthalpy = self.scf_energy + (Utrans + Urot + Uvib + GAS_CONSTANT * options.temperature) / j_to_au
self.enthalpy = self.scf_energy + (Utrans + Urot + Uvib + GAS_CONSTANT * temperature) / j_to_au
self.zpe = ZPE / j_to_au
self.entropy = (Strans + Srot + h_Svib + Selec) / j_to_au
self.qh_entropy = (Strans + Srot + qh_Svib + Selec) / j_to_au
self.gibbs_free_energy = self.enthalpy - options.temperature * self.entropy
self.qh_gibbs_free_energy = self.enthalpy - options.temperature * self.qh_entropy
self.gibbs_free_energy = self.enthalpy - temperature * self.entropy
self.qh_gibbs_free_energy = self.enthalpy - temperature * self.qh_entropy

if __name__ == "__main__":
# Takes arguments: gaussian_output_files
log = Logger("Goodvibes","dat", "output")

# get command line inputs
parser = OptionParser(usage="Usage: %prog [options] <input1>.log <input2>.log ...")
parser.add_option("-t", dest="temperature", action="store",
Expand All @@ -357,18 +349,18 @@ def __init__(self, file, QH, FREQ_CUTOFF, temperature, conc, freq_scale_factor,
help="Solvent (H2O, toluene, DMF, AcOH, chloroform) (default none)", default="none", type="string", metavar="SOLV")
parser.add_option("--spc", dest="spc", action="store_true",
help="Indicates linked single point corrections (default False)", default=False, metavar="SOLV")
parser.add_option("--ti", dest="temperature_interval", action="store",
help="initial temp, final temp, step size (K)", default=False, metavar="TI")
parser.add_option("--ci", dest="conc_interval", action="store",
help="initial conc, final conc, step size (mol/l)", default=False, metavar="CI")

(options, args) = parser.parse_args()
# case insensitive
options.QH = options.QH.lower()

# Default variables
files, temperature_interval, conc_interval = [], [], []
files = []
if len(sys.argv) > 1:
for elem, next_elem in zip(sys.argv[1:], sys.argv[2:]):
if elem == "-ti": temperature_interval = list(eval(next_elem))
elif elem == "-ci": conc = list(next_elem)

# get the filenames
for elem in sys.argv[1:]:
try:
Expand All @@ -378,13 +370,13 @@ def __init__(self, file, QH, FREQ_CUTOFF, temperature, conc, freq_scale_factor,

start = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime())
log.Write(" GoodVibes v" + __version__ + " " + start)
log.Write("\n REF: " + goodvibes_ref +"\n")
log.Write("\n REF: " + goodvibes_ref +"\n\n")

log.Write("\n Temperature = "+str(options.temperature)+" Kelvin")
if options.temperature_interval == False: log.Write(" Temperature = "+str(options.temperature)+" Kelvin")
# If not at standard temp, need to correct the molarity of 1 atmosphere
if options.conc == 0.040876:
options.conc = atmos/(GAS_CONSTANT*options.temperature)
log.Write(" Concn = 1 atm"); conc_ini="None"
log.Write(" Pressure = 1 atm"); conc_ini="None"
else: log.Write(" Concn = "+str(options.conc)+" mol/l"); conc_ini="None"

# attempts to automatically obtain frequency scale factor. Requires all outputs to be same level of theory
Expand Down Expand Up @@ -414,7 +406,7 @@ def all_same(items): return all(x == items[0] for x in items)
if options.spc == "True": log.Write("\n Link job: combining final single point energy with thermal corrections")

# Standard mode: tabulate thermochemistry ouput from file(s) at a single temperature and concentration
if len(temperature_interval) == 0 and len(conc_interval) == 0:
if options.temperature_interval == False and options.conc_interval == False:
#log.Write("\n\n "+"Structure".ljust(39))
log.Write("\n\n " + '{:<39} {:>13} {:>10} {:>13} {:>10} {:>10} {:>13} {:>13}'.format("Structure", "E/au", "ZPE/au", "H/au", "T.S/au", "T.qh-S/au", "G(T)/au", "qh-G(T)/au"))
log.Write("\n"+stars)
Expand All @@ -429,26 +421,27 @@ def all_same(items): return all(x == items[0] for x in items)
log.Write("\n"+stars+"\n")

#Running a variable temperature analysis of the enthalpy, entropy and the free energy
if len(temperature_interval) != 0:
elif options.temperature_interval != False:
temperature_interval = [float(temp) for temp in options.temperature_interval.split(',')]
# If no temperature step was defined, divide the region into 10
if len(temperature_interval) == 2: temperature_interval.append((temperature_interval[1]-temperature_interval[0])/10.0)
log.Write("\n\n Running a temperature analysis of the enthalpy, entropy and the entropy between")
log.Write("\n\n Variable-Temperature analysis of the enthalpy, entropy and the entropy at a constant pressure between")
log.Write("\n T_init: %.1f, T_final: %.1f, T_interval: %.1f" % (temperature_interval[0], temperature_interval[1], temperature_interval[2]))
temperature = float(temperature_interval[0])

log.Write("\n\n "+"Structure".ljust(39))
log.Write('{:>13} {:>13} {:>10} {:>10} {:>13} {:>13}'.format("Temp/K", "H/au", "T.S/au", "T.qh-S/au", "G(T)/au", "qh-G(T)/au"))
log.Write("\n\n " + '{:<39} {:>13} {:>24} {:>10} {:>10} {:>13} {:>13}'.format("Structure", "Temp/K", "H/au", "T.S/au", "T.qh-S/au", "G(T)/au", "qh-G(T)/au"))

for file in files:
log.Write("\n"+stars[:120])
log.Write("\n"+stars)
for i in range(int(temperature_interval[0]), int(temperature_interval[1]+1), int(temperature_interval[2])):
temperature = float(i)
log.Write("\no "+file.ljust(39))
log.Write('{:13.1f}'.format(temperature))
if conc_ini == "None": options.conc = atmos/(GAS_CONSTANT*temperature)
bbe = calc_bbe(file, options.QH, options.freq_cutoff, temperature, options.conc, freq_scale_factor, solv, options.spc)
temp, conc = float(i), atmos / GAS_CONSTANT / float(i)
log.Write("\no "+'{:<39} {:13.1f}'.format(file.split(".")[0], temp))
bbe = calc_bbe(file, options.QH, options.freq_cutoff, temp, conc, options.freq_scale_factor, options.solv, options.spc)
if not hasattr(bbe,"gibbs_free_energy"): log.Write("Warning! Couldn't find frequency information ...\n")
else:
if all(getattr(bbe, attrib) for attrib in ["enthalpy", "entropy", "qh_entropy", "gibbs_free_energy", "qh_gibbs_free_energy"]):
log.Write('{:13.6f} {:10.6f} {:10.6f} {:13.6f} {:13.6f}'.format(bbe.enthalpy, (temperature * bbe.entropy), (temperature * bbe.qh_entropy), bbe.gibbs_free_energy, bbe.qh_gibbs_free_energy))
log.Write("\n"+stars[:120]+"\n")
log.Write(' {:24.6f} {:10.6f} {:10.6f} {:13.6f} {:13.6f}'.format(bbe.enthalpy, (temp * bbe.entropy), (temp * bbe.qh_entropy), bbe.gibbs_free_energy, bbe.qh_gibbs_free_energy))
log.Write("\n"+stars+"\n")

# close the log
log.Finalize()

0 comments on commit b9774f0

Please sign in to comment.