def calc_scaled_Vcoeffs(self): from FourierExpansions import calc_curves from scaleTORpotentials import calc_scaled_Vcoeffs if len(self.Velcoeffs) == 7: energy = calc_curves(np.radians(np.arange(0, 360, 1)), self.Velcoeffs) order = 6 ens_to_calc = self.DVRresults["energies"].shape[ 1] - 1 # subtract 1 for degree column elif len(self.Velcoeffs) == 5: energy = calc_curves(np.radians(np.arange(0, 360, 1)), self.Velcoeffs, function="4cos") ens_to_calc = 6 order = 4 else: raise Exception( f"Expansion order of {len(self.Velcoeffs)-1} currently not supported" ) energy_dat = np.column_stack((np.arange(0, 360, 1), energy)) scaled_coeffs = calc_scaled_Vcoeffs(energy_dat, self.Vcoeffs, ens_to_calc, barrier_height=self.barrier_height, scaling_factor=self.scaling_factor, order=order) return scaled_coeffs
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 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
def calc_barrier(self, pot_coeffs): from FourierExpansions import calc_curves rad = np.radians(np.arange(0, 360, 1)) if self.PORparams["Vexpansion"] is "fourth": pot_curve = calc_curves(rad, pot_coeffs, function="4cos") else: pot_curve = calc_curves(rad, pot_coeffs, function="cos") energy_dat = np.column_stack((np.degrees(rad), pot_curve)) 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] return true_bh
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}")
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()
def plot_fourier(self): from Converter import Constants from FourierExpansions import fourier_coeffs, calc_curves, calc_cos_coefs import matplotlib.pyplot as plt interp_degree = np.linspace(0, 360, 100) interp_rad = np.radians(np.linspace(0, 360, 100)) EE = np.copy(self.RxnPathResults["electronicE"]) EE[:, 0] = np.radians(EE[:, 0]) cos_coeffs, sin_coeffs = fourier_coeffs(EE, cos_order=6, sin_order=6) coeff2 = calc_cos_coefs(EE) print("cos", cos_coeffs) print("sin", sin_coeffs) interpE = calc_curves(interp_rad, [cos_coeffs, sin_coeffs], function="fourier") interp2 = calc_curves(interp_rad, coeff2, function="cos") plt.plot(self.RxnPathResults["electronicE"][:, 0], self.RxnPathResults["electronicE"][:, 1], "o") plt.plot(interp_degree, interpE) plt.plot(interp_degree, interp2) plt.show()
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()
def RotCoeffs(RotationConstants): from FourierExpansions import calc_cos_coefs, calc_curves Mcoefs = np.zeros((7, 3)) # [num_coeffs, (ABC)] x = np.radians(np.linspace(0, 360, len(RotationConstants))) for c, val in enumerate(["A", "B", "C"]): # fit to 6th order cos functions data = np.column_stack((x, RotationConstants[:, c] * 6579689.7)) Mcoefs[:, c] = calc_cos_coefs(data) y = calc_curves(np.radians(np.arange(0, 361, 1)), Mcoefs[:, c] / 6579689.7, function="cos") return Mcoefs
def fit_TDM(self, TDM): from FourierExpansions import fourier_coeffs, calc_curves tdm_x = np.radians(np.linspace(0, 360, len(TDM[:, 0]))) x = np.radians(np.linspace(0, 360, len(self.tor_results[0]["eigvecs"]))) fittedTDM = np.zeros((len(x), 3)) for c, val in enumerate(["A", "B", "C"]): coeffs = fourier_coeffs(np.column_stack((tdm_x, TDM[:, c])), cos_order=6, sin_order=6) fittedTDM[:, c] = calc_curves(x, coeffs, function="fourier") return fittedTDM
def get_kinE(self): # final KE consists of three parts: T_j,j', G(tau), and d^2G/dtau^2 from FourierExpansions import calc_curves import matplotlib.pyplot as plt Tmat = self.get_T() # nxn plt.matshow(Tmat) G_tau = calc_curves(self.grid, self.GmatCoeffs, function="fourier") # dG2_tau = self.calc_Gderivs() # G2_mat = np.diag(dG2_tau) # project gmat out to diagonal like potential # calculate KE matrix kinE = np.zeros((self.nPts, self.nPts)) for j in range(len(self.grid)): for j_prime in range(j+1): kinE[j, j_prime] = (1/2)*(Tmat[j, j_prime]*(G_tau[j]+G_tau[j_prime])) #-G2_mat[j, j_prime]) kinE[j_prime, j] = (1/2)*(Tmat[j, j_prime]*(G_tau[j]+G_tau[j_prime])) #-G2_mat[j, j_prime]) return kinE
def get_pot(self): from FourierExpansions import calc_curves PC = [] for t in np.arange(len(self.PotentialCoeffs)): pot = self.PotentialCoeffs[t] g = self.GmatCoeffs[t] coeffs = np.zeros(len(pot)) if t == 1: for i, val in enumerate(pot): coeffs[i] = val - ((i+1)**2*g[i]*0.25) # watch this. a fix to f****d up Gmat derivs else: for i, val in enumerate(pot): coeffs[i] = val - (i**2*g[i]*0.25) # watch this. a fix to f****d up Gmat derivs PC.append(coeffs) pot_vals = calc_curves(self.grid, PC, function="fourier") pot = np.diag(pot_vals) return pot
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()
def make_one_Potplot(ResDict, ZPE=False, filename=None): """send in the res dict of the one level you want""" from FourierExpansions import calc_curves fig = plt.figure(figsize=(7, 8), dpi=600) x = np.linspace(0, 360, 100) rad_x = np.linspace(0, 2 * np.pi, 100) Pot = Constants.convert(calc_curves(rad_x, ResDict["V"], function="fourier"), "wavenumbers", to_AU=False) enX = np.linspace(180 / 3, 2 * 180 - 180 / 3, 10) colors = ["b", "r", "g", "indigo", "teal", "mediumvioletred"] for i in np.arange(6): en = Constants.convert(ResDict['energy'][i], "wavenumbers", to_AU=False) if ZPE is False: en -= min(Pot) if i % 2 == 0: # if even (lower) plt.plot(enX, np.repeat(en, len(enX)), "-", color=colors[i], linewidth=2.5) else: # if odd (upper) plt.plot(enX, np.repeat(en, len(enX)), "--", color=colors[i], linewidth=2.5) if ZPE is False: Pot -= min(Pot) plt.plot(x, Pot, '-k', linewidth=2.5, zorder=1) plt.ylabel(r"V($\tau$) [cm$^{-1}$]", labelpad=15.0) plt.ylim(0, 610) plt.xlabel(r"$\tau$ [Degrees]") plt.xticks(np.arange(60, 360, 60)) plt.xlim(60, 300) 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()
def make_ZPEplot(twoDcoeffs, fullcoeffs): from FourierExpansions import calc_curves ZPEcoeffs = fullcoeffs - twoDcoeffs ZPE = calc_curves(np.radians(np.arange(0, 360, 1)), ZPEcoeffs, function="cos") ZPE_cm = Constants.convert(ZPE, "wavenumbers", to_AU=False) fig = plt.figure(figsize=(4, 4), dpi=600) plt.plot(np.arange(0, 360, 1), ZPE_cm, color="k", linewidth=3.0) plt.plot(np.linspace(0, 360, 10), np.repeat(0, 10), color="k") # plt.plot(np.repeat(113, 10), np.linspace(-10, 10, 10), '--', color="gray", label=r"$\tau_{eq}$") # plt.plot(np.repeat(247, 10), np.linspace(-10, 10, 10), '--', color="gray") # plt.legend() plt.ylim(-10, 10) plt.xticks(np.arange(0, 390, 60)) plt.xlim(0, 360) plt.ylabel(r"$\Delta$ ZPVE (cm$^{-1}$)") plt.xlabel(r"$\tau$ (Degrees)") plt.savefig("Figure_ZPE.jpg", dpi=fig.dpi, bbox_inches="tight")
def plot_TDM(self, filename=None): import matplotlib.pyplot as plt from FourierExpansions import calc_curves params = { 'text.usetex': False, 'mathtext.fontset': 'dejavusans', 'font.size': 18 } plt.rc('axes', labelsize=20) plt.rc('axes', labelsize=20) plt.rcParams.update(params) for Tstring in self.transition: fig = plt.figure(figsize=(7, 8), dpi=600) TDM = self.calc_TDM(Tstring) if self.MatSize > 1: M_coeffs = self.calc_Mcoeffs(TDM) degrees = np.linspace(0, 360, len(TDM)) plt.plot(degrees, np.repeat(0, len(degrees)), "-k", linewidth=3) colors = ["C0", "C1", "C2"] for c, val in enumerate(["A", "B", "C"]): plt.plot(degrees, TDM[:, c] / 0.393456, 'o', color=colors[c], label=r"$\alpha$ = % s" % val) if self.MatSize > 1: if val == "C": line = calc_curves(np.radians(np.linspace(0, 360)), M_coeffs[:, c], function="sin") # print(Tstring, line[0]/ 0.393456, line[-1]/ 0.393456) else: line = calc_curves(np.radians(np.linspace(0, 360)), M_coeffs[:, c], function="cos") plt.plot(np.linspace(0, 360), line / 0.393456, "-", color=colors[c], linewidth=3, label=r"$\alpha$ = % s" % val) else: plt.plot(degrees, TDM[:, c] / 0.393456, '-', color=colors[c], linewidth=3) plt.plot(np.repeat(113, 10), np.linspace(-0.1, 0.1, 10), '--', color="gray", label=r"$\tau_{eq}$") plt.plot(np.repeat(247, 10), np.linspace(-0.1, 0.1, 10), '--', color="gray") if Tstring[-1] is "1": plt.ylim(-0.07, 0.07) plt.legend(loc="lower left") elif Tstring[-1] is "2": plt.ylim(-0.020, 0.020) plt.legend(loc="upper left") elif Tstring[-1] is "3": plt.ylim(-0.004, 0.004) plt.legend(loc="upper left") elif Tstring[-1] is "4": plt.ylim(-0.001, 0.001) plt.legend(loc="lower left") elif Tstring[-1] is "5": plt.ylim(-0.0003, 0.0003) plt.legend(loc="lower left") plt.ylabel(r"$M^{\alpha}_{0 \rightarrow % s}$ (Debye)" % Tstring[-1]) plt.xlim(-10, 370) plt.xlabel(r"$\tau$ (Degrees)") plt.xticks(np.arange(0, 390, 60)) if filename is None: plt.show() else: fig.savefig(f"{filename}_{Tstring[0]}{Tstring[-1]}_eq.jpg", dpi=fig.dpi, bbox_inches="tight") print(f"Figure saved to {filename}_{Tstring[0]}{Tstring[-1]}")
def calculate_VelwZPE(self): from Converter import Constants from FourierExpansions import calc_cos_coefs, calc_4cos_coefs, fourier_coeffs, calc_curves degree_vals = np.linspace(0, 360, len(self.MoleculeInfo.TorFiles)) norm_grad = self.RxnPathResults["norm_grad"] idx = np.where(norm_grad[:, 1] > 4E-4) new_degree = degree_vals[idx] Vel = self.RxnPathResults["electronicE"][:, 1] Vel_ZPE_dict = dict() ZPE_dict = dict() for i, j in enumerate(degree_vals): freqs = self.RxnPathResults[j]["freqs"] # in hartree # print(np.column_stack((j, freqs[-1]))) nonzero_freqs = freqs[ 7:-1] # throw out translations/rotations and OH frequency nonzero_freqs_har = Constants.convert(nonzero_freqs, "wavenumbers", to_AU=True) ZPE = np.sum(nonzero_freqs_har) / 2 if j in new_degree: if self.PORparams["twoD"]: # "twoD" in self.PORparams and Vel_ZPE_dict[j] = Vel[i] else: Vel_ZPE_dict[j] = Vel[i] + ZPE ZPE_dict[j] = ZPE else: pass if "EmilData" in self.PORparams or "MixedData1" in self.PORparams: # put together ZPE print("CCSD Vel") ZPE = np.array([(d, v) for d, v in ZPE_dict.items()]) sort_idxZ = np.argsort(ZPE[:, 0]) ZPE = ZPE[sort_idxZ] ZPE[:, 0] = np.radians(ZPE[:, 0]) fit_ZPE = calc_4cos_coefs(ZPE) # zpe_y = calc_curves(np.radians(np.arange(0, 360, 1)), fit_ZPE, function="4cos") emil_angles = self.RxnPathResults["EmilelectronicE"][:, 0] emil_ZPE = calc_curves(np.radians(emil_angles), fit_ZPE, function="4cos") Vel_ZPE = np.column_stack( (np.radians(emil_angles), emil_ZPE + self.RxnPathResults["EmilelectronicE"][:, 1])) VelwZPE_coeffs1 = calc_4cos_coefs(Vel_ZPE) new_x = np.radians(np.arange(0, 360, 1)) y = calc_curves(new_x, VelwZPE_coeffs1, function="4cos") y -= min(y) # shift curve so minima are at 0 instead of negative VelwZPE_coeffs = calc_4cos_coefs(np.column_stack((new_x, y))) npy_name = f"{self.MoleculeInfo.MoleculeName}_Emil_Velcoeffs_4order.npy" csv_name = f"{self.MoleculeInfo.MoleculeName}_Emil_Velcoeffs_4order.csv" else: print("DFT Vel") Vel_ZPE = np.array([(d, v) for d, v in Vel_ZPE_dict.items()]) sort_idx = np.argsort(Vel_ZPE[:, 0]) Vel_ZPE = Vel_ZPE[sort_idx] Vel_ZPE[:, 0] = np.radians(Vel_ZPE[:, 0]) new_x = np.radians(np.arange(0, 360, 1)) if "MixedData2" in self.PORparams or self.PORparams[ "Vexpansion"] is "fourth": VelwZPE_coeffs1 = calc_4cos_coefs(Vel_ZPE) y = calc_curves(new_x, VelwZPE_coeffs1, function="4cos") y -= min( y) # shift curve so minima are at 0 instead of negative VelwZPE_coeffs = calc_4cos_coefs(np.column_stack((new_x, y))) npy_name = f"{self.MoleculeInfo.MoleculeName}_Velcoeffs_4order.npy" csv_name = f"{self.MoleculeInfo.MoleculeName}_Velcoeffs_4order.csv" elif self.PORparams["None"] and self.PORparams["twoD"]: VelwZPE_coeffs1 = fourier_coeffs(Vel_ZPE) y = calc_curves(new_x, VelwZPE_coeffs1, function="fourier") y -= min( y) # shift curve so minima are at 0 instead of negative VelwZPE_coeffs = fourier_coeffs(np.column_stack((new_x, y))) npy_name = f"{self.MoleculeInfo.MoleculeName}_Velcoeffs_6cos6sin_2D.npy" csv_name = f"{self.MoleculeInfo.MoleculeName}_Velcoeffs_6cos6sin_2D.csv" elif self.PORparams["None"] and self.PORparams["twoD"] is False: VelwZPE_coeffs1 = fourier_coeffs(Vel_ZPE) y = calc_curves(new_x, VelwZPE_coeffs1, function="fourier") y -= min( y) # shift curve so minima are at 0 instead of negative VelwZPE_coeffs = fourier_coeffs(np.column_stack((new_x, y))) npy_name = f"{self.MoleculeInfo.MoleculeName}_Velcoeffs_6cos6sin.npy" csv_name = f"{self.MoleculeInfo.MoleculeName}_Velcoeffs_6cos6sin.csv" elif self.PORparams["twoD"]: VelwZPE_coeffs1 = calc_cos_coefs(Vel_ZPE) y = calc_curves(new_x, VelwZPE_coeffs1) y -= min( y) # shift curve so minima are at 0 instead of negative VelwZPE_coeffs = calc_cos_coefs(np.column_stack((new_x, y))) npy_name = f"{self.MoleculeInfo.MoleculeName}_Velcoeffs_6order_2D.npy" csv_name = f"{self.MoleculeInfo.MoleculeName}_Velcoeffs_6order_2D.csv" else: VelwZPE_coeffs1 = calc_cos_coefs(Vel_ZPE) y = calc_curves(new_x, VelwZPE_coeffs1) y -= min( y) # shift curve so minima are at 0 instead of negative VelwZPE_coeffs = calc_cos_coefs(np.column_stack((new_x, y))) npy_name = f"{self.MoleculeInfo.MoleculeName}_Velcoeffs_6order.npy" csv_name = f"{self.MoleculeInfo.MoleculeName}_Velcoeffs_6order.csv" # save results np.save(os.path.join(self.MoleculeInfo.MoleculeDir, npy_name), VelwZPE_coeffs) np.savetxt(os.path.join(self.MoleculeInfo.MoleculeDir, csv_name), VelwZPE_coeffs) return os.path.join(self.MoleculeInfo.MoleculeDir, npy_name)
def make_diff_freq_plots(self): from FourierExpansions import calc_cos_coefs, calc_curves import matplotlib.pyplot as plt params = { 'text.usetex': False, 'mathtext.fontset': 'dejavusans', 'font.size': 14 } plt.rcParams.update(params) degree1 = np.arange(10, 110, 10) degree4 = np.arange(120, 180, 10) degree2 = np.arange(190, 250, 10) degree3 = np.arange(260, 360, 10) degrees = np.concatenate((degree1, degree4, degree2, degree3)) freq_data = np.zeros((len(degrees), 49)) sel = [x for x in range(49) if x not in list(range(8)) + [29, 48]] for i, deg in enumerate(degrees): # pull the frequencies freqs = self.RxnPathResults[deg]["freqs"] freq_data[i] = np.column_stack((deg, *freqs)) # add in data from Mark dat = np.loadtxt("stat_no_tor_tor_freqs.csv", delimiter=",") freq_data = np.concatenate((freq_data, dat), axis=0) sym_dict = dict() for idx, deg in enumerate(freq_data[:, 0]): # symmeterize the frequencies if deg > 180: friend = 180 - (deg - 180) else: friend = 180 + (180 - deg) pos = np.where(freq_data[:, 0] == friend)[0] if len(pos) == 0: sym_dict[deg] = freq_data[idx, 1:] sym_dict[friend] = freq_data[idx, 1:] else: val1 = freq_data[idx, 1:] val2 = freq_data[pos[0], 1:] sym_dict[deg] = (val1 + val2) / 2 sym_dict[friend] = (val1 + val2) / 2 sym_data = np.column_stack( [list(sym_dict.keys()), list(sym_dict.values())]) key_idxs = np.argsort(list(sym_dict.keys())) sym_data = sym_data[key_idxs] # subtract eq frequencies and divide by 2 for ZPE eq_freqs = np.loadtxt("no_tor_tor_freqs.csv", delimiter=",") plt_sym_data = np.zeros((len(sym_data), 49)) plt_sym_data[:, 0] = sym_data[:, 0] for i in np.arange(1, sym_data.shape[1]): plt_sym_data[:, i] = (sym_data[:, i] - eq_freqs[i - 1]) / 2 # fit OOH and OH to cos function expansions x_deg = np.arange(10, 351, 1) x_rad = np.radians(x_deg) eq_idx = np.argwhere(x_deg == 112)[0] OOH = plt_sym_data[:, 29] OOH_coefs = calc_cos_coefs( np.column_stack([np.radians(plt_sym_data[:, 0]), OOH])) yOOH = calc_curves(x_rad, OOH_coefs) yOOH -= yOOH[eq_idx[0]] plt.plot(x_deg, yOOH, "-r", linewidth=2.5, zorder=50, label="OOH Bend") # plt.plot(plt_sym_data[:, 0], OOH, "--r", linewidth=2.5, zorder=50, label="OOH Bend") OH = plt_sym_data[:, 48] OH_coefs = calc_cos_coefs( np.column_stack([np.radians(plt_sym_data[:, 0]), OH])) yOH = calc_curves(x_rad, OH_coefs) yOH -= yOH[eq_idx[0]] plt.plot(x_deg, yOH, "-g", linewidth=2.5, zorder=50, label="OH Stretch") # plt.plot(plt_sym_data[:, 0], OH, "--g", linewidth=2.5, zorder=50, label="OH Stretch") # for i in sel: # plt.plot(plt_sym_data[:, 0], plt_sym_data[:, i], color="gray", linewidth=1.5) # plot sum of modes - OOH and OH eq_freqss = np.concatenate([[1000], eq_freqs]) eq_sum = np.sum(eq_freqss[sel]) mode_y = np.zeros(len(plt_sym_data)) for j, d in enumerate(plt_sym_data[:, 0]): mode_sum = np.sum(sym_data[j, sel]) mode_y[j] = (mode_sum - eq_sum) / 2 y_coeffs = calc_cos_coefs( np.column_stack([np.radians(plt_sym_data[:, 0]), mode_y])) y_vals = calc_curves(x_rad, y_coeffs) y_vals -= y_vals[eq_idx[0]] plt.plot(x_deg, y_vals, color="k", linewidth=2.5, label=r"$\Delta$ZPE - OOH Bend - OH Stretch") # # pot sum of modes - OH # mode_y2 = np.zeros(len(plt_sym_data)) # sel2 = [x for x in range(49) if x not in list(range(8)) + [48]] # eq_sum2 = np.sum(eq_freqss[sel2]) # for j, d in enumerate(plt_sym_data[:, 0]): # mode_sum = np.sum(sym_data[j, sel2]) # mode_y2[j] = (mode_sum-eq_sum2)/2 # y_coeffs2 = calc_cos_coefs(np.column_stack([np.radians(plt_sym_data[:, 0]), mode_y2])) # y_vals2 = calc_curves(np.radians(np.arange(10, 351, 1)), y_coeffs2) # plt.plot(np.arange(10, 351, 1), y_vals2, color="k", linewidth=2.5, label=r"$\Delta$ZPE - OH Stretch") plt.legend() plt.xticks(np.arange(30, 330, 30)) plt.xlim(30, 330) plt.xlabel(r"$\tau$ [Degrees]") plt.ylim(-30, 30) plt.ylabel(r"$\Delta$ ZPE [wavenumbers]") plt.show()
def make_Potplots(gsRes, esRes, numStates=4, potfunc="cos", 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 f, (ax, ax2) = plt.subplots(2, 1, sharex="all", figsize=(7, 8), dpi=600) x = np.linspace(0, 360, 100) rad_x = np.linspace(0, 2 * np.pi, 100) # create gs plot if len(gsRes["V"]) < 7: gsRes["V"] = np.hstack((gsRes["V"], np.zeros(7 - len(gsRes["V"])))) esRes["V"] = np.hstack((esRes["V"], np.zeros(7 - len(esRes["V"])))) gsPot = Constants.convert(calc_curves(rad_x, gsRes["V"], function=potfunc), "wavenumbers", to_AU=False) esPot = Constants.convert(calc_curves(rad_x, esRes["V"], function=potfunc), "wavenumbers", to_AU=False) enX = np.linspace(180 / 3, 2 * 180 - 180 / 3, 10) colors = ["b", "r", "g", "indigo", "teal", "mediumvioletred"] for i in np.arange(numStates): en = Constants.convert(gsRes['energy'][i], "wavenumbers", to_AU=False) ene = Constants.convert(esRes['energy'][i], "wavenumbers", to_AU=False) if ZPE is False: en -= min(gsPot) ene -= min(gsPot) if i % 2 == 0: # if even (lower) ax2.plot(enX, np.repeat(en, len(enX)), "-", color=colors[i], linewidth=2.5) ax.plot(enX, np.repeat(ene, len(enX)), "-", color=colors[i], linewidth=2.5) else: # if odd (upper) ax2.plot(enX, np.repeat(en, len(enX)), "--", color=colors[i], linewidth=2.5) ax.plot(enX, np.repeat(ene, len(enX)), "--", color=colors[i], linewidth=2.5) if ZPE is False: esPot -= min(gsPot) gsPot -= min(gsPot) ax2.plot(x, gsPot, '-k', linewidth=2.5, zorder=1) ax.plot(x, esPot, '-k', linewidth=2.5, zorder=1) # hide the spines between ax and ax2 ax.spines['bottom'].set_visible(False) ax2.spines['top'].set_visible(False) ax.axes.set_xticks(np.arange(0, 390, 60)) ax.xaxis.tick_top() # create tick marks on top of plot ax.tick_params(labeltop=False) # get rid of ticks on top ax2.xaxis.tick_bottom() d = .015 # how big to make the diagonal lines in axes coordinates # arguments to pass to plot, just so we don't keep repeating them kwargs = dict(transform=ax.transAxes, color='k', clip_on=False) ax.plot((-d, +d), (-d, +d), **kwargs) # top-left diagonal ax.plot((1 - d, 1 + d), (-d, +d), **kwargs) # top-right diagonal kwargs.update(transform=ax2.transAxes) # switch to the bottom axes ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs) # bottom-left diagonal ax2.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs) # bottom-right diagonal # add big axis for labels f.add_subplot(111, frameon=False) plt.tick_params(labelcolor="none", top=False, bottom=False, left=False, right=False) plt.ylabel(r"Energy (cm$^{-1}$)", labelpad=15.0) plt.xlabel(r"$\tau (Degrees)$") if filename is None: plt.show() else: f.savefig(f"{filename}.jpg", dpi=f.dpi, bbox_inches="tight") print(f"Figure saved to {filename}")