Compute zero-point vibrational energy from frequencies.
ZPE = (1/2) * h * sum(nu_i) for all real frequencies. Imaginary frequencies (negative values) are skipped with a warning.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=dp), | intent(in) | :: | frequencies(:) |
Vibrational frequencies in cm^-1 |
||
| integer, | intent(in) | :: | n_freqs |
Total number of frequencies |
||
| integer, | intent(out) | :: | n_real |
Number of real (positive) frequencies used |
||
| real(kind=dp), | intent(out) | :: | zpe_hartree |
ZPE in Hartree |
||
| real(kind=dp), | intent(out) | :: | zpe_kcalmol |
ZPE in kcal/mol |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=dp), | private | :: | freq_sum | ||||
| integer, | private | :: | i | ||||
| integer, | private | :: | n_imag |
subroutine compute_zpe(frequencies, n_freqs, n_real, zpe_hartree, zpe_kcalmol) !! Compute zero-point vibrational energy from frequencies. !! !! ZPE = (1/2) * h * sum(nu_i) for all real frequencies. !! Imaginary frequencies (negative values) are skipped with a warning. real(dp), intent(in) :: frequencies(:) !! Vibrational frequencies in cm^-1 integer, intent(in) :: n_freqs !! Total number of frequencies integer, intent(out) :: n_real !! Number of real (positive) frequencies used real(dp), intent(out) :: zpe_hartree !! ZPE in Hartree real(dp), intent(out) :: zpe_kcalmol !! ZPE in kcal/mol integer :: i real(dp) :: freq_sum integer :: n_imag freq_sum = 0.0_dp n_real = 0 n_imag = 0 do i = 1, n_freqs if (frequencies(i) > IMAG_FREQ_THRESHOLD) then freq_sum = freq_sum + frequencies(i) n_real = n_real + 1 else if (frequencies(i) < IMAG_FREQ_THRESHOLD) then n_imag = n_imag + 1 end if ! Frequencies exactly at threshold (typically trans/rot modes ~0) are skipped end do if (n_imag > 0) then call logger%warning("Thermochemistry: "//trim(adjustl(to_char(n_imag)))// & " imaginary frequency(ies) skipped") end if ! ZPE = 0.5 * sum(h * c * nu) where nu is in cm^-1 ! In atomic units: ZPE = 0.5 * sum(nu * CM1_TO_KELVIN * KB_HARTREE) ! Actually: h*c*nu [cm^-1] = h*c*nu [J] = nu * CM1_TO_KELVIN * k_B [J] ! So ZPE [Hartree] = 0.5 * sum(nu) * CM1_TO_KELVIN * KB_HARTREE zpe_hartree = 0.5_dp*freq_sum*CM1_TO_KELVIN*KB_HARTREE zpe_kcalmol = zpe_hartree*HARTREE_TO_KCALMOL end subroutine compute_zpe