def get_UoRT(self, T): """Calculates the dimensionless internal energy :math:`\\frac {U^{qRRHO}}{RT} = \\sum_{i}\\omega_i\\frac{U^{RRHO}}{RT} + \\frac{1}{2}(1-\\omega_i)` :math:`\\frac {U^{RRHO}_{i}}{RT} = \\frac{\\Theta_i}{T} \\bigg( \\frac{1}{2} + \\frac{\\exp(-\\frac{\\Theta_i}{T})}{1-\\exp(-\\frac{ \\Theta_i}{T})}\\bigg)` Parameters ---------- T : float Temperature in K Returns ------- UoRT_vib : float Vibrational dimensionless internal energy """ UoRT_QRRHO = [] valid_wavenumbers = _get_valid_vib_wavenumbers( wavenumbers=self.vib_wavenumbers, substitute=self.imaginary_substitute) vib_temperatures = c.wavenumber_to_temp(valid_wavenumbers) scaled_wavenumbers = self._get_scaled_wavenumber(valid_wavenumbers) for theta_i, w_i in zip(vib_temperatures, scaled_wavenumbers): UoRT_RRHO = self._get_UoRT_RRHO(T=T, vib_temperature=theta_i) UoRT_QRRHO.append(w_i * UoRT_RRHO + (1. - w_i) * 0.5) return np.sum(UoRT_QRRHO)
def get_CvoR(self, T): """Calculates the dimensionless heat capacity at constant volume :math:`\\frac {C_{v}^{qRRHO}}{R} = \\sum_{i}\\omega_i\\frac{C_{v,i} ^{RRHO}}{R} + \\frac{1}{2}(1-\\omega_i)` :math:`\\frac{C_{v}^{RRHO}}{R} = \\sum_{i}\\exp \\bigg(-\\frac{ \\Theta_i}{T}\\bigg) \\bigg(\\frac{\\Theta_i}{T}\\frac{1}{1-\\exp(- \\frac{\\Theta_i}{T})}\\bigg)^2` Parameters ---------- T : float Temperature in K Returns ------- CvoR_vib : float Vibrational dimensionless heat capacity at constant volume """ CvoR = [] valid_wavenumbers = _get_valid_vib_wavenumbers( wavenumbers=self.vib_wavenumbers, substitute=self.imaginary_substitute) vib_temperatures = c.wavenumber_to_temp(valid_wavenumbers) vib_dimless = vib_temperatures / T scaled_wavenumbers = self._get_scaled_wavenumber(valid_wavenumbers) for vib_dimless_i, w_i in zip(vib_dimless, scaled_wavenumbers): CvoR_RRHO = np.exp(-vib_dimless_i) \ * (vib_dimless_i/(1. - np.exp(-vib_dimless_i)))**2 CvoR.append(w_i * CvoR_RRHO + 0.5 * (1. - w_i)) return np.sum(CvoR)
def get_ZPE(self): """Calculates the zero point energy :math:`ZPE=\\frac{1}{2}k_b\\sum_i \\Theta_{V,i}` Returns ------- zpe : float Zero point energy in eV """ valid_wavenumbers = _get_valid_vib_wavenumbers( wavenumbers=self.vib_wavenumbers, substitute=self.imaginary_substitute) vib_temperatures = c.wavenumber_to_temp(valid_wavenumbers) return 0.5 * c.kb('eV/K') * np.sum(vib_temperatures)
def get_ZPE(self): """Calculates the zero point energy :math:`ZPE=\\frac{1}{2}k_b\\sum_i \\omega_i\\Theta_{V,i}` Returns ------- zpe : float Zero point energy in eV """ zpe = [] valid_wavenumbers = _get_valid_vib_wavenumbers( wavenumbers=self.vib_wavenumbers, substitute=self.imaginary_substitute) vib_temperatures = c.wavenumber_to_temp(valid_wavenumbers) scaled_wavenumbers = self._get_scaled_wavenumber(valid_wavenumbers) for theta_i, w_i in zip(vib_temperatures, scaled_wavenumbers): zpe = 0.5 * c.kb('eV/K') * theta_i * w_i return np.sum(zpe)
def _get_vib_dimless(wavenumbers, T, substitute=None): """Calculates dimensionless temperatures for the wavenumbers and temperature specified Parameters ---------- wavenumbers : (N,) np.ndarray Wavenumbers in 1/cm T : float Temperature in K substitute : float, optional Value to use to replace imaginary frequencies. If not specified, imaginary frequencies are ignored. Default is None Returns ------- vib_dimless : (N,) np.ndarray Vibrational temperatures normalized by T """ valid_wavenumbers = _get_valid_vib_wavenumbers(wavenumbers=wavenumbers, substitute=substitute) vib_dimless = c.wavenumber_to_temp(valid_wavenumbers) / T return vib_dimless
def get_SoR(self, T): """Calculates the dimensionless entropy :math:`\\frac{S^{qRRHO}}{R}=\\sum_i\\omega_i\\frac{S_i^{H}}{R}+(1- \\omega_i)\\frac{S_i^{RRHO}}{R}` :math:`\\frac {S^{RRHO}_i}{R} = \\frac{1}{2} + \\log \\bigg(\\bigg[ \\frac{8\\pi^3\\mu'_ik_BT}{h^2}\\bigg]^{\\frac{1}{2}}\\bigg)` :math:`\\frac {S^{H}_i}{R}=\\bigg(\\frac{\\Theta_i}{T}\\bigg)\\frac{1} {\\exp(\\frac{\\Theta_i}{T})-1}-\\log\\bigg(1-\\exp(\\frac{-\\Theta_i} {T})\\bigg)` Parameters ---------- T : float Temperature in K Returns ------- SoR_vib : float Vibrational dimensionless entropy """ SoR_QRRHO = [] valid_wavenumbers = _get_valid_vib_wavenumbers( wavenumbers=self.vib_wavenumbers, substitute=self.imaginary_substitute) vib_temperatures = c.wavenumber_to_temp(valid_wavenumbers) scaled_inertia = self._get_scaled_inertia(valid_wavenumbers) scaled_wavenumbers = self._get_scaled_wavenumber(valid_wavenumbers) for theta_i, mu_i, w_i in zip(vib_temperatures, scaled_inertia, scaled_wavenumbers): SoR_H = self._get_SoR_H(T=T, vib_temperature=theta_i) SoR_RRHO = self._get_SoR_RRHO(T=T, vib_inertia=mu_i) SoR_QRRHO.append(w_i * SoR_H + (1. - w_i) * SoR_RRHO) return np.sum(SoR_QRRHO)
def test_wavenumber_to_temp(self): self.assertAlmostEqual(c.wavenumber_to_temp(1.), 1.4387773538277204)