Beispiel #1
0
    def run_harOH_DVR(self, plotPhasedWfns=False):
        """ Runs a harmonic approximation using DVR to be fast over the OH coordinate at every OO value."""
        from McUtils.Zachary import finite_difference
        dvr_1D = DVR("ColbertMiller1D")
        finite_dict = self.logData.finite_dict(midpoint=True)
        roos = np.array(list(finite_dict.keys()))
        potential_array = np.zeros((len(finite_dict), self.NumPts, 2))
        energies_array = np.zeros((len(finite_dict), self.desiredEnergies))
        wavefunctions_array = np.zeros(
            (len(finite_dict), self.NumPts, self.desiredEnergies))

        for j, n in enumerate(finite_dict):
            x = Constants.convert(finite_dict[n][:, 0],
                                  "angstroms",
                                  to_AU=True)
            min_idx = np.argmin(finite_dict[n][:, 1])
            sx = x - x[min_idx]
            y = finite_dict[n][:, 1]
            k = finite_difference(sx,
                                  y,
                                  2,
                                  end_point_precision=0,
                                  stencil=5,
                                  only_center=True)[0]
            mini = min(sx) - 1.0
            maxi = max(sx) + 1.0
            res = dvr_1D.run(potential_function="harmonic_oscillator",
                             k=k,
                             mass=self.massdict["muOOH"],
                             divs=self.NumPts,
                             domain=(mini, maxi),
                             num_wfns=self.desiredEnergies)
            potential = Constants.convert(res.potential_energy.diagonal(),
                                          "wavenumbers",
                                          to_AU=False)
            grid = Constants.convert((res.grid + x[min_idx]),
                                     "angstroms",
                                     to_AU=False)
            shiftgrid = (n / 2) + grid
            potential_array[j, :, 0] = shiftgrid
            potential_array[j, :, 1] = potential
            ens = Constants.convert((res.wavefunctions.energies + min(y)),
                                    "wavenumbers",
                                    to_AU=False)
            energies_array[j, :] = ens
            wavefunctions_array[j, :, :] = res.wavefunctions.wavefunctions
        epsilon_pots = np.column_stack((roos, energies_array[:, :4]))
        npz_filename = os.path.join(
            self.DVRdir,
            f"{self.method}_HarmOHDVR_energies{self.desiredEnergies}.npz")
        # data saved in wavenumbers/angstroms
        wavefuns_array = self.wfn_flipper(wavefunctions_array,
                                          plotPhasedWfns=plotPhasedWfns,
                                          pot_array=potential_array)
        np.savez(npz_filename,
                 method="harm",
                 potential=potential_array,
                 epsilonPots=epsilon_pots,
                 wfns_array=wavefuns_array)
        return npz_filename
 def run_2D_DVR(self):
     """Runs 2D DVR over the original 2D potential should take flat xy array, and flat 2D grid in ATOMIC UNITS"""
     from PyDVR import DVR, ResultsInterpreter
     from Converter import Constants
     import os
     dvr_2D = DVR("ColbertMillerND")
     xy = np.column_stack((self.grid[0].flatten(), self.grid[1].flatten()))
     ens = self.ModelHarmonicPotential().flatten()
     res = dvr_2D.run(potential_grid=np.column_stack((xy, ens)),
                      divs=(100, 100),
                      mass=[self.massdict["muOO"], self.massdict["muOH"]],
                      num_wfns=15,
                      domain=((min(xy[:, 0]), max(xy[:,
                                                     0])), (min(xy[:, 1]),
                                                            max(xy[:, 1]))),
                      results_class=ResultsInterpreter)
     dvr_grid = Constants.convert(res.grid, "angstroms", to_AU=False)
     dvr_pot = Constants.convert(res.potential_energy.diagonal(),
                                 "wavenumbers",
                                 to_AU=False)
     all_ens = Constants.convert(res.wavefunctions.energies,
                                 "wavenumbers",
                                 to_AU=False)
     ResultsInterpreter.wfn_contours(res)
     oh1oo0 = int(input("OH=1 OO=0 Wavefunction Index: "))
     oh1oo1 = int(input("OH=1 OO=1 Wavefunction Index: "))
     oh1oo2 = int(input("OH=1 OO=2 Wavefunction Index: "))
     ens = np.zeros(4)
     wfns = np.zeros((4, res.wavefunctions[0].data.shape[0]))
     for i, wf in enumerate(res.wavefunctions):
         wfn = wf.data
         if i == 0:
             wfns[0] = wfn
             ens[0] = all_ens[i]
         elif i == oh1oo0:
             wfns[1] = wfn
             ens[1] = all_ens[i]
         elif i == oh1oo1:
             wfns[2] = wfn
             ens[2] = all_ens[i]
         elif i == oh1oo2:
             wfns[3] = wfn
             ens[3] = all_ens[i]
         else:
             pass
     # data saved in wavenumbers/angstrom
     dvr_dir = os.path.join(self.molecule.mol_dir, "DVR Results")
     if self.CC:
         npz_filename = f"{dvr_dir}/HMP_wCC_2D_DVR_OHOO.npz"
     else:
         npz_filename = f"{dvr_dir}/HMP_2D_DVR_OHOO.npz"
     np.savez(npz_filename,
              grid=[dvr_grid],
              potential=[dvr_pot],
              vrwfn_idx=[0, oh1oo0, oh1oo1, oh1oo2],
              energy_array=ens,
              wfns_array=wfns)
     return npz_filename
Beispiel #3
0
 def run_harOO_DVR(self, OHDVRres=None, plotPhasedWfns=False):
     """Fits epsilon potentials to a harmonic oscillator and then runs an OO DVR over it"""
     from McUtils.Zachary import finite_difference
     dvr_1D = DVR("ColbertMiller1D")
     OHresults = np.load(OHDVRres)
     epsi_pots = OHresults["epsilonPots"]
     potential_array = np.zeros((2, self.NumPts, 2))
     energies_array = np.zeros((2, self.desiredEnergies))
     wavefunctions_array = np.zeros((2, self.NumPts, self.desiredEnergies))
     x = Constants.convert(epsi_pots[:, 0], "angstroms", to_AU=True)
     for j in np.arange(2):
         en = Constants.convert(epsi_pots[:, j + 1],
                                "wavenumbers",
                                to_AU=True)
         minE_idx = np.argmin(en)
         en_s = en[minE_idx - 2:minE_idx + 3]
         sx = x - x[minE_idx]
         k = finite_difference(sx[minE_idx - 2:minE_idx + 3],
                               en_s,
                               2,
                               end_point_precision=0,
                               stencil=5,
                               only_center=True)[0]
         mini = min(sx) - 1.0
         maxi = max(sx) + 0.5
         res = dvr_1D.run(potential_function="harmonic_oscillator",
                          k=k,
                          mass=self.massdict["muOO"],
                          divs=self.NumPts,
                          domain=(mini, maxi),
                          num_wfns=self.desiredEnergies)
         potential = Constants.convert(res.potential_energy.diagonal() +
                                       en[minE_idx],
                                       "wavenumbers",
                                       to_AU=False)
         potential_array[j, :, 0] = Constants.convert(
             (res.grid + x[minE_idx]), "angstroms", to_AU=False)
         potential_array[j, :, 1] = potential
         ens = Constants.convert(res.wavefunctions.energies + en[minE_idx],
                                 "wavenumbers",
                                 to_AU=False)
         energies_array[j, :] = ens
         wavefunctions_array[j, :, :] = res.wavefunctions.wavefunctions
     npz_filename = os.path.join(
         self.DVRdir,
         f"{self.method}_harmOODVR_w{OHresults['method']}OHDVR_energies{self.desiredEnergies}.npz"
     )
     # data saved in wavenumbers/angstroms
     wavefuns_array = self.wfn_flipper(wavefunctions_array,
                                       plotPhasedWfns=plotPhasedWfns,
                                       pot_array=potential_array)
     np.savez(npz_filename,
              potential=potential_array,
              energy_array=energies_array,
              wfns_array=wavefuns_array)
     return npz_filename
Beispiel #4
0
 def run_2D_DVR(self):
     """Runs 2D DVR over the original 2D potential"""
     dvr_2D = DVR("ColbertMillerND")
     npz_filename = os.path.join(self.DVRdir, f"{self.method}_2D_DVR.npz")
     twoD_grid = self.logData.rawenergies
     xy = Constants.convert(twoD_grid[:, :2], "angstroms", to_AU=True)
     en = twoD_grid[:, 2]
     en[en > 0.228] = 0.228  # set stricter limit
     res = dvr_2D.run(potential_grid=np.column_stack((xy, twoD_grid[:, 2])),
                      divs=(100, 100),
                      mass=[self.massdict["muOO"], self.massdict["muOOH"]],
                      num_wfns=15,
                      domain=((min(xy[:, 0]), max(xy[:,
                                                     0])), (min(xy[:, 1]),
                                                            max(xy[:, 1]))),
                      results_class=ResultsInterpreter)
     dvr_grid = Constants.convert(res.grid, "angstroms", to_AU=False)
     dvr_pot = Constants.convert(res.potential_energy.diagonal(),
                                 "wavenumbers",
                                 to_AU=False)
     all_ens = Constants.convert(res.wavefunctions.energies,
                                 "wavenumbers",
                                 to_AU=False)
     ResultsInterpreter.wfn_contours(res)
     oh1oo0 = int(input("OH=1 OO=0 Wavefunction Index: "))
     oh1oo1 = int(input("OH=1 OO=1 Wavefunction Index: "))
     oh1oo2 = int(input("OH=1 OO=2 Wavefunction Index: "))
     ens = np.zeros(4)
     wfns = np.zeros((4, res.wavefunctions[0].data.shape[0]))
     for i, wf in enumerate(res.wavefunctions):
         wfn = wf.data
         if i == 0:
             wfns[0] = wfn
             ens[0] = all_ens[i]
         elif i == oh1oo0:
             wfns[1] = wfn
             ens[1] = all_ens[i]
         elif i == oh1oo1:
             wfns[2] = wfn
             ens[2] = all_ens[i]
         elif i == oh1oo2:
             wfns[3] = wfn
             ens[3] = all_ens[i]
         else:
             pass
     # data saved in wavenumbers/angstroms
     np.savez(npz_filename,
              grid=[dvr_grid],
              potential=[dvr_pot],
              vrwfn_idx=[0, oh1oo0, oh1oo1, oh1oo2],
              energy_array=ens,
              wfns_array=wfns)
     return npz_filename
Beispiel #5
0
 def run_OO_DVR(self, OHDVRres=None, plotPhasedWfns=False):
     """Runs OO DVR over the epsilon potentials"""
     from PotentialHandlers import Potentials1D
     dvr_1D = DVR("ColbertMiller1D")
     OHresults = np.load(OHDVRres)
     epsi_pots = OHresults["epsilonPots"]
     potential_array = np.zeros((2, self.NumPts, 2))
     energies_array = np.zeros((2, self.desiredEnergies))
     wavefunctions_array = np.zeros((2, self.NumPts, self.desiredEnergies))
     x = Constants.convert(epsi_pots[:, 0], "angstroms", to_AU=True)
     mini = min(x) - 0.3
     maxi = max(x) + 0.15
     for j in np.arange(2):
         en = Constants.convert(epsi_pots[:, j + 1],
                                "wavenumbers",
                                to_AU=True)
         res = dvr_1D.run(potential_function=Potentials1D().potlint(x, en),
                          mass=self.massdict["muOO"],
                          divs=self.NumPts,
                          domain=(mini, maxi),
                          num_wfns=self.desiredEnergies)
         potential = Constants.convert(res.potential_energy.diagonal(),
                                       "wavenumbers",
                                       to_AU=False)
         grid = Constants.convert(res.grid, "angstroms", to_AU=False)
         potential_array[j, :, 0] = grid
         potential_array[j, :, 1] = potential
         min_idx = np.argmin(potential)
         print(j, grid[min_idx], potential[min_idx])
         ens = Constants.convert(res.wavefunctions.energies,
                                 "wavenumbers",
                                 to_AU=False)
         print(j, ens)
         energies_array[j, :] = ens
         wavefunctions_array[j, :, :] = res.wavefunctions.wavefunctions
     npz_filename = os.path.join(
         self.DVRdir,
         f"{self.method}_OODVR_w{OHresults['method']}OHDVR_energies{self.desiredEnergies}.npz"
     )
     # data saved in wavenumbers/angstroms
     wavefuns_array = self.wfn_flipper(wavefunctions_array,
                                       plotPhasedWfns=plotPhasedWfns,
                                       pot_array=potential_array)
     np.savez(npz_filename,
              potential=potential_array,
              energy_array=energies_array,
              wfns_array=wavefuns_array)
     return npz_filename
Beispiel #6
0
    def run_anharOH_DVR(self, plotPhasedWfns=False):
        """ Runs anharmonic DVR over the OH coordinate at every OO value."""
        from PotentialHandlers import Potentials1D
        dvr_1D = DVR("ColbertMiller1D")
        cut_dict = self.logData.cut_dictionary()
        roos = np.array(list(cut_dict.keys()))
        potential_array = np.zeros((len(cut_dict), self.NumPts, 2))
        energies_array = np.zeros((len(cut_dict), self.desiredEnergies))
        wavefunctions_array = np.zeros(
            (len(cut_dict), self.NumPts, self.desiredEnergies))

        for j, n in enumerate(cut_dict):
            x = Constants.convert(cut_dict[n][:, 0], "angstroms", to_AU=True)
            mini = min(x) - 0.3
            maxi = max(x) + 0.3
            en = cut_dict[n][:, 1]
            res = dvr_1D.run(potential_function=Potentials1D().potlint(x, en),
                             mass=self.massdict["muOOH"],
                             divs=self.NumPts,
                             domain=(mini, maxi),
                             num_wfns=self.desiredEnergies)
            potential = Constants.convert(res.potential_energy.diagonal(),
                                          "wavenumbers",
                                          to_AU=False)
            grid = Constants.convert(res.grid, "angstroms", to_AU=False)
            # shiftgrid = (n/2) + grid
            potential_array[j, :, 0] = grid  # shiftgrid
            potential_array[j, :, 1] = potential
            ens = Constants.convert(res.wavefunctions.energies,
                                    "wavenumbers",
                                    to_AU=False)
            energies_array[j, :] = ens
            wavefunctions_array[j, :, :] = res.wavefunctions.wavefunctions
        epsilon_pots = np.column_stack((roos, energies_array[:, :4]))
        npz_filename = os.path.join(
            self.DVRdir,
            f"{self.method}_AnharmOHDVR_energies{self.desiredEnergies}.npz")
        # data saved in wavenumbers/angstroms
        wavefuns_array = self.wfn_flipper(wavefunctions_array,
                                          plotPhasedWfns=plotPhasedWfns,
                                          pot_array=potential_array)
        np.savez(npz_filename,
                 method="anharm",
                 potential=potential_array,
                 epsilonPots=epsilon_pots,
                 wfns_array=wavefuns_array)
        return npz_filename
Beispiel #7
0
import glob as glob
import matplotlib.pyplot as plt

H = 1.007825
O = 15.994915
avo = 6.02213670000e23
me = 9.109383560000e-28
mO = (O / avo) / me
mH = (H / avo) / me
muOH = ((2*mO)*mH)/((2*mO)+mH)
muOO = mO/2
angtobohr = 1.88973

main_dir = os.path.dirname(os.path.dirname(__file__))
scan_dir = os.path.join(main_dir, '2D Scans')
dvr_2D = DVR("ColbertMillerND")


def regular_grid(grid, vals, interp_kind='cubic', fillvalues=False, plot=False):
    import matplotlib.pyplot as plt
    from scipy import interpolate
    x = grid[:, 0]
    xvals = np.unique(x)
    xyzz = np.column_stack((x, grid[:, 1], vals))
    slices = [xyzz[x == xv] for xv in xvals]
    maxx = max(len(slIce) for slIce in slices)
    idx = np.argmax([len(slIce) for slIce in slices])
    rnge = sorted(slices[idx][:, 1])
    sgrid = np.empty((0, 3))
    for slICE in slices:
        slICE = slICE[slICE[:, 1].argsort()]
Beispiel #8
0
 def test_energies_3D(self):
     dvr_3D = DVR("ColbertMillerND")
     res = dvr_3D.run(potential_function=self.ho_3D, domain=((-5, 5),)*3, divs=(15,)*3)
     # print(res[0][:5], file=sys.stderr)gg
     self.assertIsInstance(res[0], np.ndarray)
Beispiel #9
0
 def test_energies_2D(self):
     dvr_2D = DVR("ColbertMillerND")
     res = dvr_2D.run(potential_function=self.ho_2D, divs=(25, 25))
     # print(res[0][:5], file=sys.stderr)
     self.assertIsInstance(res[0], np.ndarray)
Beispiel #10
0
 def test_energies_1D(self):
     dvr_1D = DVR("ColbertMiller1D")
     e, wf = dvr_1D.run(potential_function=self.ho, divs=150)
     # print(e[:5], file=sys.stderr)
     self.assertIsInstance(e, np.ndarray)
Beispiel #11
0
 def test_1D(self):
     dvr_1D = DVR("ColbertMiller1D")
     pot = dvr_1D.run(potential_function=self.ho, result='potential_energy')
     self.assertIsInstance(pot, np.ndarray)
Beispiel #12
0
import matplotlib.pyplot as plt
from PyDVR.DVR import *
from McUtils.Plots import ContourPlot
from scipy import interpolate
import eckartRotation as eckin
from GaussianHandler import LogInterpreter
import glob as glob
"""Messy implementation of 2D DVR used for checks of adiabatic approximation, The approximation is good.
 But all of this code is complete crap."""
main_dir = os.path.dirname(os.path.dirname(__file__))
dvr_2D = DVR("ColbertMillerND")
H = 1.007825
O = 15.994915
avo = 6.02213670000e23
me = 9.109383560000e-28
mO = (O / avo) / me
mH = (H / avo) / me
muOH = ((2 * mO) * mH) / ((2 * mO) + mH)
muOO = mO / 2

scan_dir = os.path.join(main_dir, '2D Scans')
dat = np.loadtxt(os.path.join(scan_dir, '2Dgrid_rigid_har_new.dat'))
dat[:, :2] *= 1.88973
dat[:, 2] -= min(dat[:, 2])

big_x = np.arange(
    min(dat[:, 0]) - (0.3),
    max(dat[:, 0]) + (0.15), (0.06 * 1.88973))
big_y = np.arange(
    min(dat[:, 1]) - (0.3),
    max(dat[:, 1]) + (0.15), (0.06 * 1.88973))