Skip to content

Commit

Permalink
change integration scheme
Browse files Browse the repository at this point in the history
The old scheme using nquad only worked fast because the value of the integral was below the absolute tolerance, and it wasn't very accurate
after fixing the numerical issue nquad takes impractically long
since the integration is over a fit to data points we don't even know the function well enough for an nquad calculation to make sense
for this reason I've used simpsons rule for integration which is much faster and should be just as accurate
we still fit and use function evaluations for convenience
  • Loading branch information
mjohnson541 committed Dec 13, 2019
1 parent 982ad86 commit 77bfecb
Showing 1 changed file with 15 additions and 5 deletions.
20 changes: 15 additions & 5 deletions rmgpy/statmech/ndTorsions.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import os
import os.path
import subprocess
import itertools

import numdifftools as nd
import numpy as np
Expand Down Expand Up @@ -597,12 +598,22 @@ def calc_partition_function(self, T):
"""
calculate the classical/semiclassical partition function at a given temperature
"""
rngs = [(0.0, 2.0 * np.pi) for x in range(len(self.pivots))]

def f(*phis):
return self.rootD(*phis) * np.exp(-self.V(*phis) / (constants.R * T))

intg = inte.nquad(f, ranges=rngs)[0]
return (self.rootD(*phis)) * np.exp(-self.V(*phis) / (constants.R * T))

rphis = np.linspace(0, 2.0*np.pi, 30)
Imat = np.zeros([len(rphis) for i in range(len(self.pivots))])
it = itertools.product(*[list(range(len(rphis))) for i in range(len(self.pivots))])

for coords in it:
Imat[coords] = f(*rphis[np.array(coords)])

for i in range(len(self.pivots)):
Imat = inte.simps(Imat, rphis)

intg = Imat

Q = intg * (2.0 * np.pi * constants.kB * T / constants.h**2) ** (len(self.pivots) / 2.0) / np.prod(self.sigmas)

if self.semiclassical:
Expand All @@ -612,7 +623,6 @@ def f(*phis):
x = constants.h * freqs / (constants.kB * T)
out = x / (1.0 - np.exp(-x))
Q *= np.prod(out)

return Q

def get_partition_function(self, T):
Expand Down

0 comments on commit 77bfecb

Please sign in to comment.