Пример #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 calc_coefs(sys):
    udrive = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
    mainD = os.path.join(udrive, sys)
    dips = np.load(os.path.join(mainD, "structures", f"FD{sys}_rotdips2021_test.npy"))
    molObj, gaussdat = pull_data(sys)
    scancoords = np.array(list(gaussdat.cartesians.keys()))
    sort_ind = np.lexsort((scancoords[:, 1], scancoords[:, 0]))
    sort_grid = scancoords[sort_ind, :]
    sort_dips = dips[sort_ind, :] 

    fd_ohs = Constants.convert(np.unique(sort_grid[:, 1]), "angstroms", to_AU=True)
    fd_oos = Constants.convert(np.unique(sort_grid[:, 0]), "angstroms", to_AU=True)
    FDgrid = np.array(np.meshgrid(fd_oos, fd_ohs)).T
    FDvaluesx = np.reshape(sort_dips[:, 0], (5, 5))
    FDvaluesy = np.reshape(sort_dips[:, 1], (5, 5))
    FDvaluesz = np.reshape(sort_dips[:, 2], (5, 5))
    eqDipole = np.array((FDvaluesx[2, 2], FDvaluesy[2, 2], FDvaluesz[2, 2]))
    xderivs = calc_derivs(fd_ohs, fd_oos, FDgrid, FDvaluesx)
    yderivs = calc_derivs(fd_ohs, fd_oos, FDgrid, FDvaluesy)
    zderivs = calc_derivs(fd_ohs, fd_oos, FDgrid, FDvaluesz)
    derivs = {'x': xderivs, 'y': yderivs, 'z': zderivs}
    fn = os.path.join(mainD, "Finite Scan Data", f"DipCoefs{sys}_smallscan.npz")
    np.savez(fn, x=xderivs, y=yderivs, z=zderivs, eqDip=eqDipole)
    print("eqDipole:", eqDipole)
    return derivs
Пример #3
0
 def run_tor_adiabats(self):
     from TorsionPOR import POR
     from Converter import Constants
     if "EmilData" in self.PORparams or "MixedData2" in self.PORparams:
         file_name = os.path.join(self.MoleculeInfo.MoleculeDir,
                                  "Emil_vOHenergies.txt")
         self.PORparams["EmilEnergies"] = np.loadtxt(file_name, skiprows=1)
     PORobj = POR(DVR_res=self.DegreeDVRresults,
                  fit_gmatrix=self.fittedGmatrix,
                  Velcoeffs=self.VelCoeffs,
                  params=self.PORparams)
     results = PORobj.solveHam(
     )  # returns a list of dictionaries for each torsional potential
     if "PrintResults" in self.PORparams:
         for i in np.arange(len(results)):
             bh = Constants.convert(results[i]["barrier"],
                                    "wavenumbers",
                                    to_AU=False)
             print(f"Barrier Height : {bh} cm^-1")
             energy = results[i]["energy"]
             ens = Constants.convert(energy, "wavenumbers", to_AU=False)
             print(
                 f"vOH = {i} : E0+ : {ens[0]}  E0- : {ens[1]} / {ens[1]-ens[0]:.3f} \n"
                 f"            E1+ : {ens[2]} / {ens[2]-ens[0]:.3f} E1- : {ens[3]} / {ens[3]-ens[0]:.3f} \n"
                 f"            E2+ : {ens[4]} / {ens[4]-ens[0]:.3f} E2- : {ens[5]} / {ens[5]-ens[0]:.3f} \n"
                 f"            E3+ : {ens[6]} / {ens[6]-ens[0]:.3f} E3- : {ens[7]} / {ens[7]-ens[0]:.3f} \n"
             )
     wfns = PORobj.PORwfns(
     )  # returns a list of arrays with each wfn for each torsional potential
     return results, wfns
Пример #4
0
def make_Vel_plots(mol_res_obj):
    Vel = mol_res_obj.RxnPathResults["electronicE"][:, 1]
    Vel -= min(Vel)
    degrees = mol_res_obj.RxnPathResults["electronicE"][:, 0]
    plt.plot(degrees,
             Constants.convert(Vel, "wavenumbers", to_AU=False),
             "o",
             label="Vel")
    Vel_coeffs = fourier_coeffs(np.column_stack((np.radians(degrees), Vel)),
                                sin_order=6,
                                cos_order=6)
    Vel_fit = calc_curves(np.radians(np.arange(0, 360, 1)),
                          Vel_coeffs,
                          function="fourier")
    Vel_res = np.column_stack(
        (np.arange(0, 360,
                   1), Constants.convert(Vel_fit, "wavenumbers", to_AU=False)))
    max_arg1 = np.argmax(Vel_res[100:270, 1])
    print("Vel", Vel_res[max_arg1 + 100, :])
    plt.plot(Vel_res[:, 0], Vel_res[:, 1], "-b")
    Vel_ZPE = mol_res_obj.VelCoeffs
    velZPE = calc_curves(np.radians(np.arange(0, 360, 1)),
                         Vel_ZPE,
                         function="fourier")
    res = np.column_stack(
        (np.arange(0, 360,
                   1), Constants.convert(velZPE, "wavenumbers", to_AU=False)))
    max_arg = np.argmax(res[100:270, 1])
    print("Vel+ZPE", res[max_arg + 100, :])
    plt.plot(res[:, 0], res[:, 1], label="Vel+ZPE")
    plt.legend()
    plt.show()
 def printFreqs(self):
     from Converter import Constants
     Frr = self.force_constants[0]
     FRR = self.force_constants[1]
     print(
         "OO:",
         Constants.convert(np.sqrt(FRR / self.massdict["muOO"]),
                           "wavenumbers",
                           to_AU=False))
     print(
         "OH:",
         Constants.convert(np.sqrt(Frr / self.massdict["muOH"]),
                           "wavenumbers",
                           to_AU=False))
     print(
         "OOH:",
         Constants.convert(np.sqrt(Frr / self.massdict["muXH"]),
                           "wavenumbers",
                           to_AU=False))
     print(
         "ZPE:",
         Constants.convert((np.sqrt(FRR / self.massdict["muOO"])) / 2 +
                           (np.sqrt(Frr / self.massdict["muXH"])) / 2,
                           "wavenumbers",
                           to_AU=False))
Пример #6
0
 def interp_2D_dipoles(self):
     from functools import reduce
     from operator import mul
     from Converter import Constants
     from MolecularSys import MolecularOperations
     from scipy.interpolate import griddata
     # in bohr
     oos = MolecularOperations(self.molecule).calculateBonds(
         self.embeddedCoords, *self.scanCoords[0])
     ohs = MolecularOperations(self.molecule).calculateBonds(
         self.embeddedCoords, *self.scanCoords[1])
     MrOH = (oos / 2) - ohs
     MrOH = np.around(MrOH, 4)
     dip_vecs = self.embeddedDips
     if self.dimension == "2D":
         bigGrid = Constants.convert(self.TwoDres["grid"][0],
                                     "angstroms",
                                     to_AU=True)
         npts = reduce(mul, bigGrid.shape[:-1], 1)
         grid = np.reshape(bigGrid, (npts, bigGrid.shape[-1]))
         new_dips = np.zeros((npts, 3))
         for j in np.arange(3):
             if self.delta:
                 Doos = oos - Constants.convert(
                     self.molecule.OOmin, "angstroms", to_AU=True)
                 Dxhs = MrOH - Constants.convert(
                     self.molecule.XHmin, "angstroms", to_AU=True)
                 new_dips[:, j] = griddata(np.column_stack((Doos, Dxhs)),
                                           dip_vecs[:, j],
                                           grid,
                                           method="cubic",
                                           fill_value=np.min(dip_vecs[:,
                                                                      j]))
             else:
                 new_dips[:, j] = griddata(np.column_stack((oos, MrOH)),
                                           dip_vecs[:, j],
                                           grid,
                                           method="cubic",
                                           fill_value=np.min(dip_vecs[:,
                                                                      j]))
     else:  # this should interpolate grid to 1D DVR # of MrOHs x PES # of OOs (500 x 35)
         potz = self.OHDVRres["potential"]
         rxh = Constants.convert(np.unique(potz[:, :, 0]),
                                 "angstroms",
                                 to_AU=True)
         cut_dict = self.logData.cut_dictionary()
         roo = Constants.convert(np.array(list(cut_dict.keys())),
                                 "angstroms",
                                 to_AU=True)
         new_grid = np.meshgrid(roo, rxh, indexing="ij")
         grid = np.column_stack(
             (new_grid[0].flatten(), new_grid[1].flatten()))
         new_dips = np.zeros((len(grid), 3))
         for j in np.arange(3):
             new_dips[:, j] = griddata(np.column_stack((oos, MrOH)),
                                       dip_vecs[:, j],
                                       grid,
                                       method="cubic",
                                       fill_value=np.min(dip_vecs[:, j]))
     return grid, new_dips  # bohr & debye
Пример #7
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 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
Пример #9
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
Пример #10
0
def make_PotWfnplots(ResDict, wfn_idx=[0, 1], ZPE=True, filename=None):
    """ Plot the potential curves and energy levels of the given transitions. If ZPE plots include the ZPE,
    else they are plotted with the ZPE subtracted off so that min(gsPot) = 0 """
    from FourierExpansions import calc_curves
    fig = plt.figure(figsize=(7, 8), dpi=600)
    x = np.linspace(0, 360, len(ResDict["eigvecs"][:, 0]))
    rad_x = np.radians(x)
    # create gs plot
    if len(ResDict["V"]) < 7:
        ResDict["V"] = np.hstack(
            (ResDict["V"], np.zeros(7 - len(ResDict["V"]))))
    gsPot = Constants.convert(calc_curves(rad_x,
                                          ResDict["V"],
                                          function="fourier"),
                              "wavenumbers",
                              to_AU=False)
    colors = ["b", "r", "g", "indigo", "teal", "mediumvioletred"]
    for i in wfn_idx:
        en0g = Constants.convert(ResDict['energy'][i],
                                 "wavenumbers",
                                 to_AU=False)
        if ZPE is False:
            en0g -= min(gsPot)
        wfn0g = ResDict["eigvecs"][:, i]
        if wfn0g[150] < wfn0g[0]:
            wfn0g *= -1
        plt_wfn0g = en0g + wfn0g * 500  # for aestheics only (on all wfn)
        plt.plot(x, np.repeat(en0g, len(x)), "-k", linewidth=2)
        plt.plot(x, plt_wfn0g, color=colors[i], linewidth=3)

        # en1g = Constants.convert(ResDict['energy'][tunnel_pair[1]], "wavenumbers", to_AU=False)
        # if ZPE is False:
        #     en1g -= min(gsPot)
        # wfn1g = ResDict["eigvecs"][:, tunnel_pair[1]]
        # if wfn1g[21] < wfn0g[0]:
        #     wfn1g *= -1
        # plt_wfn1g = en1g + ResDict["eigvecs"][:, tunnel_pair[1]] * 100
        # plt.plot(x, np.repeat(en1g, len(x)), "-k", linewidth=2)
        # plt.plot(x, plt_wfn1g, color=colors[tunnel_pair[1]], linewidth=3)

    if ZPE is False:
        gsPot -= min(gsPot)
    plt.plot(x, gsPot, "-k", linewidth=3)

    plt.xticks(np.arange(0, 390, 60))
    plt.xlabel(r"$\tau$ (Degrees)")
    plt.ylim(min(gsPot) - 20, min(gsPot) + 1020)
    plt.ylabel(r"Energy (cm$^{-1}$)", labelpad=15.0)
    if filename is None:
        plt.show()
    else:
        fig.savefig(f"{filename}.jpg", dpi=fig.dpi, bbox_inches="tight")
        print(f"Figure saved to {filename}")
        plt.close()
Пример #11
0
 def componentTMs(self, mark_pts, ylim=None, xlim=None):
     comp = ["X", "Y", "Z"]
     x = Constants.convert(self.tmObj.mus[0]["dipSurf"][:, 0, 0],
                           "angstroms",
                           to_AU=False)
     mus = self.tmObj.mus[1]["dipSurf"]
     bigGrid = Constants.convert(self.tmObj.tdms[0],
                                 "angstroms",
                                 to_AU=False)
     exMus = self.tmObj.tdms[1]
     labelNames = {
         "dipSurf": "Full",
         "quadOH": "Quadratic",
         "linOH": "Linear"
     }
     # colors = ["darkmagenta", "mediumslateblue", "mediumblue"]
     colors = ["C4", "C1", "C2"]
     ls = ["-.", "-", "--"]
     fig = plt.figure(figsize=(5, 5.5), dpi=600)
     for j, v in enumerate(comp):
         if j == 0:  # make only the x-component
             for i, t in enumerate(labelNames.keys()):
                 plt.plot(bigGrid,
                          exMus[t][:, j],
                          color=colors[i],
                          linestyle=ls[i],
                          label=labelNames[t],
                          linewidth=2.0)
             for l, pt in enumerate(x):
                 if pt == mark_pts[0] or pt == mark_pts[
                         1] or pt == mark_pts[2]:
                     plt.plot(pt,
                              mus[l, j],
                              "o",
                              color="red",
                              fillstyle="none")
                 else:
                     plt.plot(pt, mus[l, j], 'ok')
             if ylim is not None:
                 plt.ylim(*ylim)
             if xlim is not None:
                 plt.xlim(*xlim)
             plt.title(f"{v} Component TDM", size=18)
             plt.legend(fontsize=14, frameon=False)
             plt.xlabel("$\mathrm{R_{OO}}$ ($\mathrm{\AA}$)", size=16)
             plt.ylabel("Transition Dipole Moment (Debye)", size=16)
             plt.tight_layout()
             plt.savefig(
                 f"{self.fig_dir}/{self.molecule.MoleculeName}_{self.molecule.method}_{v}componentTDM_wNMarkers.png",
                 dpi=fig.dpi,
                 bbox_inches="tight")
             plt.close()
         else:
             pass
Пример #12
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
Пример #13
0
def NormModeFreqs(fchk_names):
    """Calculate the normal mode frequencies"""
    from NormalModes import run
    data = DataClass(fchk_names)
    hess = data.hessian
    mass = Constants.convert(data.atomicmasses, "amu", to_AU=True)
    numCoords = 3 * len(mass)
    resAU = run(hess, numCoords, mass)
    freqsAU = np.sqrt(resAU["freq2"])
    freqs = Constants.convert(freqsAU, "wavenumbers", to_AU=False)
    # print(freqs)
    return freqs
Пример #14
0
def plot_g_matrix(mol_res_obj):
    gmats = mol_res_obj.Gmatrix[0]
    for level in np.arange(gmats.shape[0]):
        plt.plot(gmats[level, :, 0], Constants.convert(gmats[level, :, 1], "wavenumbers", to_AU=False),
                 label=f"vOH = {level}")

    new_a = np.delete(mol_res_obj.Gmatrix[1], 18, 0)
    plt.plot(new_a[:, 0], Constants.convert(new_a[:, 1], "wavenumbers", to_AU=False),
             "--m", label="EQ G Matrix")
    plt.xticks(np.arange(0, 390, 30))
    plt.xlabel("Torsion Angle (degrees)")
    plt.ylabel(r"G-Matrix Element ($cm^{-1}$)")
    plt.legend()
Пример #15
0
def get_bonds_angles(tor_angles, internal_coords):
    # pulls in the bond lengths and angles needed for the g matrix
    value_dict = dict()  # ultimately will be a nested dict value_dict[tor_angle][value]
    for i in tor_angles:
        internal_vals = dict()
        internal_coord = internal_coords[i]
        internal_vals["r12"] = Constants.convert(internal_coord["B6"][12], "angstroms", to_AU=True)  # pulls eq_roh
        internal_vals["r23"] = Constants.convert(internal_coord["B5"], "angstroms", to_AU=True)
        internal_vals["r34"] = Constants.convert(internal_coord["B4"], "angstroms", to_AU=True)
        internal_vals["phi123"] = np.radians(internal_coord["A5"])
        internal_vals["phi234"] = np.radians(internal_coord["A4"])
        internal_vals["tau1234"] = np.radians(internal_coord["D4"])
        value_dict[i] = internal_vals
    return value_dict  # values in bohr/radians
Пример #16
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
Пример #17
0
def COMcoords(data, massweight=True):
    """
    This function takes coords for Gaussian output and translates them to them to the center of mass
    and then mass-weights them
    :param data: FchkInterpreter class of data from a Gaussian fchk file
    :type data: class
    :return: array of coordinates shifted to the center of mass and mass weighted
    :rtype: np.array
    """
    mass = Constants.convert(data.atomicmasses, "amu", to_AU=True)
    tot_mass = np.sum(mass)
    # coords = Constants.convert(data.cartesians, "angstroms", to_AU=True)
    coords = data.cartesians
    COM = np.zeros(3)
    for i in range(3):
        mr = 0
        for j in np.arange(len(mass)):
            mr += mass[j] * coords[j, i]
        COM[i] = (1 / tot_mass) * mr
    x_coords = coords[:, 0] - COM[0]
    y_coords = coords[:, 1] - COM[1]
    z_coords = coords[:, 2] - COM[2]
    COM_coords = np.concatenate(
        (x_coords[:, np.newaxis], y_coords[:, np.newaxis],
         z_coords[:, np.newaxis]),
        axis=1)
    if massweight:
        mwCOM_coords = np.zeros(COM_coords.shape)
        for j in np.arange(len(mass)):
            mwCOM_coords[j, :] = np.sqrt(mass[j]) * COM_coords[j, :]
        fcoords = mwCOM_coords
    else:
        fcoords = COM_coords
    # print(fcoords)
    return fcoords
Пример #18
0
def calc_all_RotConstants(molInfo_obj,
                          torWfn_coefs,
                          numstates,
                          vOH,
                          filetags=""):
    import csv
    from Converter import Constants
    degrees = np.arange(0, 370, 10)
    rots = np.zeros((len(degrees), 3))
    with open(f"RotationalConstants_vOH{vOH}{filetags}.csv",
              mode="w") as results:
        results_writer = csv.writer(results, delimiter=',')
        results_writer.writerow(["initial", "final", "A", "B", "C"])
        for d, val in enumerate([
                "000", "010", "020", "030", "040", "050", "060", "070", "080",
                "090", "100", "110", "120", "130", "140", "150", "160", "170",
                "180", "190", "200", "210", "220", "230", "240", "250", "260",
                "270", "280", "290", "300", "310", "320", "330", "340", "350",
                "360"
        ]):
            rots[d] = RotConstants(molInfo_obj, f"tbhp_{val}.log")
        R_coeffs = RotCoeffs(rots)
        R_mat = RotationMatrix(R_coeffs)
        for State in np.arange(numstates):
            matEl = np.zeros(3)
            for c, val in enumerate(["A", "B",
                                     "C"]):  # loop through components
                supere = np.dot(R_mat[c, :, :], torWfn_coefs[:, State].T)
                matEl_au = np.dot(torWfn_coefs[:, State], supere)
                matEl[c] = Constants.convert(matEl_au,
                                             "wavenumbers",
                                             to_AU=False)
            results_writer.writerow([State, State, *matEl])
Пример #19
0
 def calc_Vcoeffs(self):
     from Converter import Constants
     from FourierExpansions import calc_cos_coefs, calc_4cos_coefs
     print("Using DFT for all potentials...")
     dvr_energies = self.DVRresults["energies"]  # [degrees vOH=0 ... vOH=6]
     dvr_energies[:, 1:] = Constants.convert(dvr_energies[:, 1:],
                                             "wavenumbers",
                                             to_AU=True)
     coeff_dict = dict()  # build coeff dict
     rad = np.radians(dvr_energies[:, 0])
     coeff_dict["Vel"] = self.Velcoeffs
     if "Vexpansion" in self.PORparams:
         if self.PORparams["Vexpansion"] == "fourth":
             print("Expaning potential coefficients to four tau")
             for i in np.arange(
                     1,
                     dvr_energies.shape[1]):  # loop through saved energies
                 energies = np.column_stack((rad, dvr_energies[:, i]))
                 coeff_dict[f"V{i - 1}"] = calc_4cos_coefs(energies)
         elif self.PORparams["Vexpansion"] == "sixth":
             print("Expaning potential coefficients to six tau")
             for i in np.arange(
                     1,
                     dvr_energies.shape[1]):  # loop through saved energies
                 energies = np.column_stack((rad, dvr_energies[:, i]))
                 coeff_dict[f"V{i - 1}"] = calc_cos_coefs(energies)
     else:
         raise Exception(
             f"Can not expand to {self.PORparams['Vexpansion']}")
     return coeff_dict
Пример #20
0
 def calc_stat_intensity(self, values=None):
     from FourierExpansions import calc_curves
     from collections import OrderedDict
     if values is None:
         values = np.arange(230, 280, 10)
     else:
         pass
     OH_0coefs = self.tor_results[0][0]["V"]
     all_intensities = OrderedDict()
     for Tstring in self.transition:  # should be a list of strings
         TDM = self.calc_TDM(Tstring)
         degrees = np.linspace(0, 360, len(TDM))
         OH_excoefs = self.tor_results[0][int(Tstring[-1])]["V"]
         intensity = np.zeros((len(values), 3))
         for i, value in enumerate(values):
             idx = np.argwhere(degrees == value)[0][0]
             OH_0 = calc_curves(value, OH_0coefs)
             OH_ex = calc_curves(value, OH_excoefs)
             freq = OH_ex - OH_0
             freq_wave = Constants.convert(freq, "wavenumbers", to_AU=False)
             print("\n")
             print(f"Stationary Frequency {Tstring}: {freq_wave}")
             for c, val in enumerate(["A", "B",
                                      "C"]):  # loop through components
                 intensity[i, c] = (abs(
                     TDM[idx, c]))**2 * freq_wave * 2.506 / (
                         0.393456**2)  # convert to km/mol
                 # print(f"Stationary Intensity @ {value} {val} : {intensity[i, c]}")
             # print(f"Total Intensity {value} : ", np.sum(intensity[i, :]))
             all_intensities[Tstring] = np.sum(intensity[i, :])
             oStrength = np.sum(intensity[i, :]) / 5.33E6
             print(f"Oscillator Strength @ {value} : {oStrength}")
     return all_intensities
Пример #21
0
def scale_barrier(energy_dat, barrier_height, scaling_factor):
    """finds the minima and cuts those points between, scales barrier and returns full data set back"""
    print(f"Beginning Electronic Barrier Scaling")
    energy_dat[:, 0] = np.radians(energy_dat[:, 0])
    mins = np.argsort(energy_dat[:, 1])
    mins = np.sort(mins[:2])
    center = energy_dat[mins[0]:mins[-1]+1, :]
    max_idx = np.argmax(center[:, 1])
    true_bh = center[max_idx, 1] - center[0, 1]
    print(f"True Barrier Height: {Constants.convert(true_bh, 'wavenumbers', to_AU=False)} cm ^-1")
    if barrier_height is None:  # scale based on scaling factor
        new_center = np.column_stack((center[:, 0], scaling_factor * center[:, 1]))
        max_idx = np.argmax(new_center[:, 1])
        scaled_bh = new_center[max_idx, 1] - new_center[0, 1]
        print(f"Scaled Barrier Height: {Constants.convert(scaled_bh, 'wavenumbers', to_AU=False)} cm ^-1")
        print(f"using a scaling factor of {scaling_factor}")
        left = energy_dat[0:mins[0], :]
        right = energy_dat[mins[-1] + 1:, :]
        scaled_energies = np.vstack((left, new_center, right))
    elif scaling_factor is None:  # scale to a defined barrier height
        barrier_har = Constants.convert(barrier_height, "wavenumbers", to_AU=True)
        scaling_factor = barrier_har / true_bh
        print(f"Scaling Factor: {scaling_factor}")
        print(f"Scaled Barrier Height: {barrier_height} cm^-1")
        new_center = np.column_stack((center[:, 0], scaling_factor*center[:, 1]))
        left = energy_dat[0:mins[0], :]
        right = energy_dat[mins[-1]+1:, :]
        scaled_energies = np.vstack((left, new_center, right))
    else:
        raise Exception("Can not scale with barrier_height or scaling_factor undefined")
    return scaling_factor, scaled_energies  # float64, [degree, energy]
Пример #22
0
 def make_scan_plots(self, grid=False, contour=True):
     plt.rcParams.update({'font.size': 20})
     fig = plt.figure(dpi=600)
     if grid:
         pts = np.array(list(self.logData.cartesians.keys()))
         plt.plot(pts[:, 0], pts[:, 1], 'ok', markersize=1.5)
         # plt.close()
     if contour:
         pts = self.logData.rawenergies
         pot = pts[:, 2]
         potwv = Constants.convert(pot, "wavenumbers", to_AU=False)
         potwv[potwv > 24000] = 24000
         plt.tricontourf(pts[:, 0],
                         pts[:, 1],
                         potwv,
                         cmap='viridis',
                         levels=8)
         cb = plt.colorbar()
         cb.set_label("Energy ($\mathrm{cm^{-1}}$)")
         plt.tricontour(pts[:, 0], pts[:, 1], potwv, colors='k', levels=8)
         plt.xlabel("$\mathrm{R_{OO}}$ ($\mathrm{\AA}$)")
         plt.ylabel("$\mathrm{r_{XH}}$ ($\mathrm{\AA}$)")
         # plt.axis("off")
         plt.savefig(
             f"{self.fig_dir}/{self.molecule.MoleculeName}_XH_OOpot.png",
             dpi=fig.dpi,
             bbox_inches="tight")
Пример #23
0
def make_pot_comp_plot(fullporRes, filename=None):
    from FourierExpansions import calc_curves
    fig = plt.figure(figsize=(4, 4), dpi=600)
    x = np.linspace(0, 360, 100)
    rad_x = np.linspace(0, 2 * np.pi, 100)
    colors = [
        "b", "r", "goldenrod", "indigo", "mediumseagreen", "darkturquoise"
    ]
    for i, porRes in enumerate(fullporRes):
        if len(porRes["V"]) < 7:
            porRes["V"] = np.hstack(
                (porRes["V"], np.zeros(7 - len(porRes["V"]))))
        Pot = Constants.convert(calc_curves(rad_x, porRes["V"]),
                                "wavenumbers",
                                to_AU=False)
        Pot -= min(Pot)
        plt.plot(x, Pot, color=colors[i], label=r"v$_\mathrm{OH}$ = % s" % i)
    plt.ylabel(
        r"$V_{\mathrm{v_{OH}}}^\mathrm{eff.}$($\tau$) - "
        r"$V_{\mathrm{v_{OH}}}^\mathrm{eff.}$($\tau_\mathrm{min}$)(cm$^{-1}$)")
    plt.xlabel(r"$\tau$ (Degrees)")
    plt.xticks(np.arange(0, 450, 90))
    plt.xlim(0, 360)
    plt.legend()
    if filename is None:
        plt.show()
    else:
        fig.savefig(f"{filename}.jpg", dpi=fig.dpi, bbox_inches="tight")
        print(f"Figure saved to {filename}")
Пример #24
0
    def make_adiabatplots(self):
        from scipy import interpolate, optimize
        mini_pot = self.logData.minimum_pot()
        eps = self.OHDVRresults["epsilonPots"]
        oo_energies = self.OODVRresults["energy_array"]
        fig = plt.figure(figsize=(5, 6), dpi=600)
        plt.rcParams.update({'font.size': 16})
        grid = self.OODVRresults["potential"][0][:, 0]
        # plot electronic energy
        E = Constants.convert(mini_pot[:, 2], "wavenumbers", to_AU=False).T
        roos = mini_pot[:, 0]
        tck = interpolate.splrep(roos, E, s=0)
        E_fit = interpolate.splev(grid, tck, der=0)
        plt.plot(grid, E_fit, '-k', linewidth=6.0)
        # plot epsilon curves and energy levels
        colors = ["royalblue", "crimson"]
        for i in range(2):  # plot curves
            pot = eps[:, i + 1]
            en_level = oo_energies[i, :]
            print(f"{self.OHDVRresults['method']} Frequency OO(OH={i}): ",
                  en_level[1] - en_level[0])
            print(f"{self.OHDVRresults['method']} Ground State(OH={i}): ",
                  en_level[0])
            tck = interpolate.splrep(eps[:, 0], pot, s=0)
            pot_fit = interpolate.splev(grid, tck, der=0)
            # plot minimum line
            # if i == 0:
            #     min_idx = np.argmin(pot_fit)
            #     print("minimum OO: ", grid[min_idx])
            #     plt.plot(np.repeat(grid[min_idx], 100), np.linspace(0, 8000, 100), "--C7", linewidth=3.0)
            plt.plot(grid, pot_fit, colors[i], linewidth=6.0)
            for j in range(2):  # plot levels
                # -- if levels aren't plotting check xl and xr and make sure they are making actual vectors.
                xl = optimize.root(
                    lambda x: interpolate.splev(x, tck, der=0) - en_level[j],
                    grid[0],
                    method="lm").x
                xr = optimize.root(
                    lambda x: interpolate.splev(x, tck, der=0) - en_level[j],
                    grid[-1],
                    method="lm").x
                enl_x = np.linspace(xr[0], xl[0], 10)
                E = [en_level[j]] * len(enl_x)
                plt.plot(enl_x, E, colors[i], linewidth=4.0)
        print(f"{self.OHDVRresults['method']} Frequency OH: ",
              oo_energies[1, 0] - oo_energies[0, 0])

        # plt.title(f"{self.molecule.method} {self.OHDVRresults['method']} OH")
        plt.yticks(fontsize=20)
        plt.ylim(-100, 8000)
        plt.xticks(fontsize=20)
        plt.xlim(2, 3.5)
        plt.tight_layout()
        plt.axis('off')
        plt.savefig(
            f"{self.fig_dir}/{self.molecule.MoleculeName}_adiabatplot_{self.OHDVR}OH{self.OODVR}OO_noaxis.pdf",
            dpi=fig.dpi,
            bbox_inches="tight",
            transparent=True)
        plt.close()
    def getHarmonicPotOH(self, plotV=None):
        Frr = self.force_constants[0]
        FRR = self.force_constants[1]
        oh_HO = 1 / 2 * Frr * (self.grid[1]**2)
        OO_HO = 1 / 2 * FRR * (self.grid[0]**2)
        if self.CC:
            V_HO = OO_HO + oh_HO + (self.CubicCoupling * self.grid[1]**2 *
                                    self.grid[0])
        else:
            V_HO = OO_HO + oh_HO

        if plotV is not None:
            from Converter import Constants
            import matplotlib.pyplot as plt
            V_HOwave = Constants.convert(V_HO, "wavenumbers", to_AU=False)
            V_HOwave[V_HOwave > 25000] = 25000
            plt.contour(self.grid[0],
                        self.grid[1],
                        V_HOwave,
                        colors='k',
                        levels=10)
            plt.contourf(self.grid[0],
                         self.grid[1],
                         V_HOwave,
                         cmap='viridis',
                         levels=10)
            plt.colorbar()
            plt.xlabel("Delta OO")
            plt.ylabel("Delta OH")
            plt.show()
            # plt.savefig(plotV)
            # plt.close()
        return V_HO
Пример #26
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
Пример #27
0
 def ohWfn_PAs(self, **kwargs):
     from matplotlib.lines import Line2D
     potz = self.OHDVRresults["potential"]
     wfns = self.OHDVRresults["wfns_array"]
     eps = self.OHDVRresults["epsilonPots"]
     roos = eps[:, 0]
     colors = ["grey", "red", "orange", "deeppink"]
     for i, j in enumerate(roos):
         print("Roo : ", j)
         print("Energies : ", eps[i, :])
         fig = plt.figure(dpi=600, facecolor="white")
         ax1 = plt.axes()
         ax1.get_xaxis().tick_bottom()
         ax1.axes.get_yaxis().set_visible(False)
         ax1.spines["top"].set_visible(False)
         ax1.spines["left"].set_visible(False)
         ax1.spines["right"].set_visible(False)
         for k in np.arange(2):
             plt.plot(potz[i, :, 0], (wfns[i, :, k]**2),
                      linewidth=3.0,
                      color=colors[k + 1],
                      label="$\psi_{%d_{XH}}$" % k)
             if k == 0:
                 # calc width (std dev) = sqrt(<x^2>-<x>^2)
                 bohr = Constants.convert(potz[i, :, 0],
                                          "angstroms",
                                          to_AU=True)
                 ket1 = bohr**2 * wfns[i, :, k]
                 x2 = np.dot(wfns[i, :, 0], ket1)
                 ket2 = bohr * wfns[i, :, k]
                 x_square = np.dot(wfns[i, :, k], ket2)**2
                 width = np.sqrt(x2 - x_square)
                 print(f"{k} width : ",
                       Constants.convert(width, "angstroms", to_AU=False))
         plt.ylim(-0.001, 0.025)
         plt.xlim(-0.4, 0.7)
         # ax1.add_artist(Line2D((-0.4, 0.7), (-0.001, -0.001), color='k', linewidth=2))
         plt.xlabel("$\mathrm{r_{XH}}$ ($\mathrm{\AA}$)", size=16)
         # plt.ylabel("Probability Amplitude", size=16)
         plt.legend(fontsize=14, frameon=False)
         plt.title(f"Roo = {j}", size=16)
         plt.tight_layout()
         plt.savefig(
             f"{self.wfn_dir}/{self.molecule.method}_{self.OHDVR}_OHPAs_Roo_{j}_test.png",
             dpi=fig.dpi,
             bbox_inches="tight")
         plt.close()
Пример #28
0
def make_scaledPots(mol_res_obj):
    from FourierExpansions import calc_curves
    x = np.linspace(0, 2 * np.pi, 100)
    Vel = calc_curves(x, mol_res_obj.Velcoefs)
    newVel = mol_res_obj.Vcoeffs[
        "Vel"]  # MolecularResults hold coefficient dict for 1 specific pot/scaling
    Vel_scaled = calc_curves(x, newVel)
    Vel_wave = Constants.convert(Vel, "wavenumbers", to_AU=False)
    Vel_scaled_wave = Constants.convert(Vel_scaled, "wavenumbers", to_AU=False)
    plt.plot(
        x,
        Vel_scaled_wave,
        "-g",
        label=f"Scaled Energy with Barrier {mol_res_obj.barrier_height} $cm^-1$"
    )
    plt.plot(x, Vel_wave, "-k", label=f"Electronic Energy + R Path")
    plt.show()
Пример #29
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
Пример #30
0
def make_Vel_plots(mol_res_obj):
    Vel = mol_res_obj.RxnPathResults["electronicE"][:, 1]
    Vel -= min(Vel)
    degrees = mol_res_obj.RxnPathResults["electronicE"][:, 0]
    plt.plot(degrees, Constants.convert(Vel, "wavenumbers", to_AU=False))
    print(
        np.column_stack(
            (degrees, Constants.convert(Vel, "wavenumbers", to_AU=False))))
    Vel_ZPE = mol_res_obj.VelCoeffs
    velZPE = calc_curves(np.radians(np.arange(0, 360, 1)), Vel_ZPE)
    res = np.column_stack(
        (np.arange(0, 360,
                   1), Constants.convert(velZPE, "wavenumbers", to_AU=False)))
    print(res[180])
    plt.plot(np.arange(0, 360, 1),
             Constants.convert(velZPE, "wavenumbers", to_AU=False))
    plt.show()