compute_vibrational_thermo Subroutine

public pure subroutine compute_vibrational_thermo(frequencies, n_freqs, temperature, E, S, Cv)

Compute vibrational contributions to thermodynamic properties.

Uses quantum harmonic oscillator partition function. E_vib = R * sum(theta_v * [1/(exp(u)-1)]) where u = theta_v/T S_vib = R * sum([u/(exp(u)-1) - ln(1-exp(-u))]) Cv_vib = R * sum(u^2 * exp(u) / (exp(u)-1)^2)

Note: ZPE is NOT included here (computed separately).

Arguments

Type IntentOptional Attributes Name
real(kind=dp), intent(in) :: frequencies(:)

Frequencies in cm^-1

integer, intent(in) :: n_freqs

Number of frequencies

real(kind=dp), intent(in) :: temperature

Temperature in K

real(kind=dp), intent(out) :: E

Thermal energy in Hartree (excluding ZPE)

real(kind=dp), intent(out) :: S

Entropy in cal/(mol*K)

real(kind=dp), intent(out) :: Cv

Heat capacity in cal/(mol*K)


Called by

proc~~compute_vibrational_thermo~~CalledByGraph proc~compute_vibrational_thermo compute_vibrational_thermo proc~compute_thermochemistry compute_thermochemistry proc~compute_thermochemistry->proc~compute_vibrational_thermo proc~compute_mbe compute_mbe proc~compute_mbe->proc~compute_thermochemistry proc~print_vibrational_analysis print_vibrational_analysis proc~compute_mbe->proc~print_vibrational_analysis proc~gmbe_pie_coordinator gmbe_pie_coordinator proc~gmbe_pie_coordinator->proc~compute_thermochemistry proc~gmbe_pie_coordinator->proc~print_vibrational_analysis proc~hessian_coordinator hessian_coordinator proc~hessian_coordinator->proc~compute_thermochemistry proc~hessian_coordinator->proc~print_vibrational_analysis proc~print_vibrational_analysis->proc~compute_thermochemistry proc~serial_gmbe_pie_processor serial_gmbe_pie_processor proc~serial_gmbe_pie_processor->proc~compute_thermochemistry proc~serial_gmbe_pie_processor->proc~print_vibrational_analysis proc~unfragmented_calculation unfragmented_calculation proc~unfragmented_calculation->proc~compute_thermochemistry proc~unfragmented_calculation->proc~print_vibrational_analysis interface~hessian_coordinator hessian_coordinator interface~hessian_coordinator->proc~hessian_coordinator interface~unfragmented_calculation unfragmented_calculation interface~unfragmented_calculation->proc~unfragmented_calculation proc~compute_gmbe compute_gmbe proc~compute_gmbe->proc~print_vibrational_analysis proc~global_coordinator global_coordinator proc~global_coordinator->proc~compute_mbe proc~gmbe_run_distributed gmbe_context_t%gmbe_run_distributed proc~gmbe_run_distributed->proc~gmbe_pie_coordinator proc~gmbe_run_serial gmbe_context_t%gmbe_run_serial proc~gmbe_run_serial->proc~serial_gmbe_pie_processor proc~serial_fragment_processor serial_fragment_processor proc~serial_fragment_processor->proc~compute_mbe interface~global_coordinator global_coordinator interface~global_coordinator->proc~global_coordinator interface~serial_fragment_processor serial_fragment_processor interface~serial_fragment_processor->proc~serial_fragment_processor proc~distributed_unfragmented_hessian distributed_unfragmented_hessian proc~distributed_unfragmented_hessian->interface~hessian_coordinator proc~run_unfragmented_calculation run_unfragmented_calculation proc~run_unfragmented_calculation->interface~unfragmented_calculation interface~distributed_unfragmented_hessian distributed_unfragmented_hessian interface~distributed_unfragmented_hessian->proc~distributed_unfragmented_hessian proc~mbe_run_distributed mbe_context_t%mbe_run_distributed proc~mbe_run_distributed->interface~global_coordinator proc~mbe_run_serial mbe_context_t%mbe_run_serial proc~mbe_run_serial->interface~serial_fragment_processor proc~run_calculation run_calculation proc~run_calculation->proc~run_unfragmented_calculation

Variables

Type Visibility Attributes Name Initial
real(kind=dp), private :: Cv_sum
real(kind=dp), private :: E_sum
real(kind=dp), private :: S_sum
real(kind=dp), private :: T
real(kind=dp), private :: exp_neg_u
real(kind=dp), private :: exp_u
real(kind=dp), private :: freq
integer, private :: i
real(kind=dp), private :: theta_v
real(kind=dp), private :: u

Source Code

   pure subroutine compute_vibrational_thermo(frequencies, n_freqs, temperature, E, S, Cv)
      !! Compute vibrational contributions to thermodynamic properties.
      !!
      !! Uses quantum harmonic oscillator partition function.
      !! E_vib = R * sum(theta_v * [1/(exp(u)-1)]) where u = theta_v/T
      !! S_vib = R * sum([u/(exp(u)-1) - ln(1-exp(-u))])
      !! Cv_vib = R * sum(u^2 * exp(u) / (exp(u)-1)^2)
      !!
      !! Note: ZPE is NOT included here (computed separately).
      real(dp), intent(in) :: frequencies(:)  !! Frequencies in cm^-1
      integer, intent(in) :: n_freqs          !! Number of frequencies
      real(dp), intent(in) :: temperature     !! Temperature in K
      real(dp), intent(out) :: E              !! Thermal energy in Hartree (excluding ZPE)
      real(dp), intent(out) :: S              !! Entropy in cal/(mol*K)
      real(dp), intent(out) :: Cv             !! Heat capacity in cal/(mol*K)

      integer :: i
      real(dp) :: T, freq, theta_v, u
      real(dp) :: exp_u, exp_neg_u
      real(dp) :: E_sum, S_sum, Cv_sum

      T = temperature
      E_sum = 0.0_dp
      S_sum = 0.0_dp
      Cv_sum = 0.0_dp

      do i = 1, n_freqs
         freq = frequencies(i)

         ! Skip imaginary and near-zero frequencies
         if (freq <= IMAG_FREQ_THRESHOLD) cycle
         if (freq < 10.0_dp) cycle  ! Skip very low frequencies (likely trans/rot residuals)

         ! Vibrational temperature: theta_v = h*c*nu / k = 1.4388 * nu (cm^-1)
         theta_v = CM1_TO_KELVIN*freq

         ! Reduced temperature ratio
         u = theta_v/T

         ! Avoid numerical issues for very large u (very low T or high freq)
         if (u > VIB_CLASSICAL_LIMIT) then
            ! Classical limit: modes are frozen out
            cycle
         end if

         exp_u = exp(u)
         exp_neg_u = exp(-u)

         ! Energy contribution (excluding ZPE): theta_v / (exp(u) - 1)
         E_sum = E_sum + theta_v/(exp_u - 1.0_dp)

         ! Entropy contribution: u/(exp(u)-1) - ln(1-exp(-u))
         S_sum = S_sum + u/(exp_u - 1.0_dp) - log(1.0_dp - exp_neg_u)

         ! Heat capacity contribution: u^2 * exp(u) / (exp(u)-1)^2
         Cv_sum = Cv_sum + (u*u*exp_u)/((exp_u - 1.0_dp)**2)
      end do

      ! Convert to proper units
      E = KB_HARTREE*E_sum           ! Hartree
      S = R_CALMOLK*S_sum            ! cal/(mol*K)
      Cv = R_CALMOLK*Cv_sum          ! cal/(mol*K)

   end subroutine compute_vibrational_thermo