Ejemplo n.º 1
0
def run_OH_DVR(cut_dict, extrapolate=0, NumPts=1000, desiredEnergies=3, plotPhasedWfns=False):
    """ Runs anharmonic DVR over the OH coordinate at every degree value."""
    from Converter import Constants, Potentials1D
    dvr_1D = DVR("ColbertMiller1D")
    degrees = np.array(list(cut_dict.keys()))
    potential_array = np.zeros((len(cut_dict), NumPts, 2))
    energies_array = np.zeros((len(cut_dict), desiredEnergies))
    wavefunctions_array = np.zeros((len(cut_dict), NumPts, desiredEnergies))
    mO = Constants.mass("O", to_AU=True)
    mH = Constants.mass("H", to_AU=True)
    muOH = 1/(1/mO + 1/mH)

    for j, n in enumerate(cut_dict):
        x = Constants.convert(cut_dict[n][:, 0], "angstroms", to_AU=True)
        en = cut_dict[n][:, 1] - np.min(cut_dict[n][:, 1])
        # subtract minimum at each cut to eliminate the electronic component since we fit our adiabats without it.
        res = dvr_1D.run(potential_function=Potentials1D().potlint(x, en), mass=muOH,
                         divs=NumPts, domain=(min(x)-extrapolate, max(x)+extrapolate), num_wfns=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
        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((degrees, energies_array[:, :desiredEnergies+1]))
    # data saved in wavenumbers/degrees
    wavefuns_array = wfn_flipper(wavefunctions_array, plotPhasedWfns=plotPhasedWfns, pot_array=potential_array)
    return potential_array, epsilon_pots, wavefuns_array
def find_FancyF(FD_file, woo=None, woh=None):
    from Converter import Constants
    from McUtils.Zachary import finite_difference
    mO = Constants.mass("O", to_AU=True)
    mH = Constants.mass("H", to_AU=True)
    freqoo = Constants.convert(woo, "wavenumbers", to_AU=True)
    muOO = mO / 2
    freqoh = Constants.convert(woh, "wavenumbers", to_AU=True)
    muOH = ((2 * mO) * mH) / ((2 * mO) + mH)
    finite_vals = np.loadtxt(FD_file, skiprows=7)
    finite_vals = finite_vals[:, 2:]
    finite_vals[:, 0] *= 2
    ens = finite_vals[:, 2]
    print(
        "Energy Difference from Minimum: ",
        Constants.convert(finite_vals[:, 2] - min(finite_vals[:, 2]),
                          "wavenumbers",
                          to_AU=False))
    ohDiffs = np.array([
        ens[1] - ens[0], ens[6] - ens[5], ens[11] - ens[10], ens[16] - ens[15],
        ens[21] - ens[20]
    ])
    print("OH energy differences: ",
          Constants.convert(ohDiffs, "wavenumbers", to_AU=False))
    finite_vals[:, :2] = Constants.convert(
        finite_vals[:, :2], "angstroms",
        to_AU=True)  # convert to bohr for math
    idx = np.lexsort(
        (finite_vals[:, 0], finite_vals[:,
                                        1]))  # resort so same oh different oo
    finite_vals = finite_vals[idx]
    finite_vals = finite_vals.reshape((5, 5, 3))
    FR = np.zeros(5)
    # compute first derivative wrt oo FR
    for j in range(finite_vals.shape[0]):
        x = finite_vals[j, :, 0]  # roos
        y = finite_vals[j, :, 2]  # energies
        print("OO energy difference: ",
              Constants.convert((y[1] - y[0]), "wavenumbers", to_AU=False))
        FR[j] = finite_difference(x,
                                  y,
                                  1,
                                  end_point_precision=0,
                                  stencil=5,
                                  only_center=True)[0]
    print(f"FR: {FR}")
    # compute mixed derivative FrrR
    FrrR = finite_difference(finite_vals[:, 1, 1],
                             FR,
                             2,
                             end_point_precision=0,
                             stencil=5,
                             only_center=True)[0]
    print(f"FrrR: {FrrR}")
    Qoo = np.sqrt(1 / muOO / freqoo)
    Qoh = np.sqrt(1 / muOH / freqoh)
    fancyF = FrrR * Qoh**2 * Qoo
    return Constants.convert(fancyF, "wavenumbers", to_AU=False)
 def get_reducedmass(self):
     from Converter import Constants
     mO = Constants.mass("O", to_AU=True)
     mH = Constants.mass("H", to_AU=True)
     massdict = dict()
     muXH = ((2 * mO) * mH) / ((2 * mO) + mH)
     massdict["muXH"] = muXH
     muOH = 1 / (1 / mO + 1 / mH)
     massdict["muOH"] = muOH
     muOO = mO / 2
     massdict["muOO"] = muOO
     return massdict
Ejemplo n.º 4
0
 def get_reducedmass(self):
     mO = Constants.mass("O", to_AU=True)
     mH = Constants.mass("H", to_AU=True)
     mD = Constants.mass("D", to_AU=True)
     massdict = dict()
     muOOH = ((2 * mO) * mH) / ((2 * mO) + mH)
     massdict["muOOH"] = muOOH
     muOOD = ((2 * mO) * mD) / ((2 * mO) + mD)
     massdict["muOOD"] = muOOD
     muOH = 1 / (1 / mO + 1 / mH)
     massdict["muOH"] = muOH
     muOO = mO / 2
     massdict["muOO"] = muOO
     return massdict
Ejemplo n.º 5
0
 def mass_array(self):
     from Converter import Constants
     if self._mass_array is None:
         m = np.array(
             [Constants.mass(x, to_AU=True) for x in self.atom_array])
         self._mass_array = m  # returns masses in AMU
     return self._mass_array
Ejemplo n.º 6
0
def run_DVR(Epot_array, extrapolate=0, NumPts=1000, desiredEnergies=3):
    """ Runs anharmonic DVR over the OH coordinate at every degree value."""
    from Converter import Constants, Potentials1D
    dvr_1D = DVR("ColbertMiller1D")
    mO = Constants.mass("O", to_AU=True)
    mH = Constants.mass("H", to_AU=True)
    muOH = 1/(1/mO + 1/mH)

    x = Constants.convert(Epot_array[:, 0], "angstroms", to_AU=True)
    en = Epot_array[:, 1] - np.min(Epot_array[:, 1])
    res = dvr_1D.run(potential_function=Potentials1D().potlint(x, en), mass=muOH,
                     divs=NumPts, domain=(min(x)-extrapolate, max(x)+extrapolate), num_wfns=desiredEnergies)
    ens = Constants.convert(res.wavefunctions.energies, "wavenumbers", to_AU=False)
    energies_array = ens  # wavenumbers
    wavefunctions_array = np.column_stack((res.grid, res.wavefunctions.wavefunctions))  # bohr
    # np.savetxt("EqTOR_wfns_forMark.dat", wavefunctions_array)
    return energies_array, wavefunctions_array
 def find_FancyF(self):
     import os
     from Converter import Constants
     from McUtils.Zachary import finite_difference
     mO = Constants.mass("O", to_AU=True)
     mH = Constants.mass("H", to_AU=True)
     freqoo = Constants.convert(self.omegaOO, "wavenumbers", to_AU=True)
     muOO = mO / 2
     freqoh = Constants.convert(self.omegaOH, "wavenumbers", to_AU=True)
     muOH = ((2 * mO) * mH) / ((2 * mO) + mH)
     fs_dir = os.path.join(self.molecule.mol_dir, "Finite Scan Data",
                           "twoD")
     if self.molecule.MoleculeName == "H9O4pls":
         finite_vals = np.loadtxt(f"{fs_dir}/2D_finiteSPEtet_01_008.dat",
                                  skiprows=7)
     elif self.molecule.MoleculeName == "H7O3pls":
         finite_vals = np.loadtxt(f"{fs_dir}/2D_finiteSPEtri_01_008.dat",
                                  skiprows=7)
     else:
         raise Exception("Can't compute FancyF of that molecule")
     finite_vals = finite_vals[:, 2:]
     finite_vals[:, 0] *= 2  # multiply OO/2 by 2 for OO values
     finite_vals[:, :2] = Constants.convert(
         finite_vals[:, :2], "angstroms",
         to_AU=True)  # convert OO/OH to bohr
     finite_vals[:, 2] -= min(
         finite_vals[:, 2])  # shift minimum to 0 so that energies match
     FDgrid = np.array(
         np.meshgrid(np.unique(finite_vals[:, 0]),
                     np.unique(finite_vals[:, 1]))).T  # create mesh OO/OH
     FDvalues = np.reshape(finite_vals[:, 2], (5, 5))
     FrrR = finite_difference(FDgrid,
                              FDvalues, (1, 2),
                              stencil=(5, 5),
                              accuracy=0,
                              end_point_precision=0,
                              only_center=True)[0, 0]
     Qoo = np.sqrt(1 / muOO / freqoo)
     Qoh = np.sqrt(1 / muOH / freqoh)
     fancyF = FrrR * Qoh**2 * Qoo
     return Constants.convert(fancyF, "wavenumbers", to_AU=False)
 def getMass(self):
     """Uses self.atom_str and Converter.py to create a mass array based off of the molecule. """
     from Converter import Constants
     masses = np.array([Constants.mass(a, to_AU=True) for a in self.atom_str])
     return masses