compute_rotational_thermo Subroutine

public pure subroutine compute_rotational_thermo(moments, temperature, symmetry_number, is_linear, E, S, Cv)

Compute rotational contributions to thermodynamic properties.

Uses rigid rotor approximation (classical limit, high T). For nonlinear: E = 3/2 RT, Cv = 3/2 R For linear: E = RT, Cv = R

Arguments

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

Principal moments in amu*Angstrom^2

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

Temperature in K

integer, intent(in) :: symmetry_number

Rotational symmetry number

logical, intent(in) :: is_linear

True if linear molecule

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

Thermal energy in Hartree

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_rotational_thermo~~CalledByGraph proc~compute_rotational_thermo compute_rotational_thermo proc~compute_thermochemistry compute_thermochemistry proc~compute_thermochemistry->proc~compute_rotational_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 :: T
integer, private :: i
real(kind=dp), private :: qr
real(kind=dp), private :: sigma
real(kind=dp), private :: theta_rot(3)

Source Code

   pure subroutine compute_rotational_thermo(moments, temperature, symmetry_number, is_linear, E, S, Cv)
      !! Compute rotational contributions to thermodynamic properties.
      !!
      !! Uses rigid rotor approximation (classical limit, high T).
      !! For nonlinear: E = 3/2 RT, Cv = 3/2 R
      !! For linear: E = RT, Cv = R
      real(dp), intent(in) :: moments(3)      !! Principal moments in amu*Angstrom^2
      real(dp), intent(in) :: temperature     !! Temperature in K
      integer, intent(in) :: symmetry_number  !! Rotational symmetry number
      logical, intent(in) :: is_linear        !! True if linear molecule
      real(dp), intent(out) :: E              !! Thermal energy in Hartree
      real(dp), intent(out) :: S              !! Entropy in cal/(mol*K)
      real(dp), intent(out) :: Cv             !! Heat capacity in cal/(mol*K)

      real(dp) :: theta_rot(3)
      real(dp) :: T, sigma
      real(dp) :: qr
      integer :: i

      T = temperature
      sigma = real(symmetry_number, dp)

      ! Calculate rotational temperatures: theta_rot = h^2 / (8*pi^2*I*k_B)
      ! For I in amu*Angstrom^2:
      !   I_SI = I * 1.66054e-47 kg*m^2
      !   theta_rot = h^2 / (8*pi^2 * I_SI * k_B)
      !             = (6.62607e-34)^2 / (8 * pi^2 * 1.66054e-47 * 1.38065e-23 * I)
      !             = ROTTEMP_AMUA2_TO_K / I  [K]
      do i = 1, 3
         if (moments(i) > LINEAR_THRESHOLD) then
            theta_rot(i) = ROTTEMP_AMUA2_TO_K/moments(i)
         else
            theta_rot(i) = 0.0_dp
         end if
      end do

      if (is_linear) then
         ! Linear molecule: 2 rotational degrees of freedom
         E = R_HARTREE*T
         Cv = R_CALMOLK

         ! S = R * [1 + ln(T / (sigma * theta_rot))]
         ! Use the average of the two non-zero theta values
         if (theta_rot(3) > 0.0_dp) then
            qr = T/(sigma*theta_rot(3))
            S = R_CALMOLK*(1.0_dp + log(qr))
         else
            S = 0.0_dp
         end if
      else
         ! Nonlinear molecule: 3 rotational degrees of freedom
         E = 1.5_dp*R_HARTREE*T
         Cv = 1.5_dp*R_CALMOLK

         ! S = R * [3/2 + ln(sqrt(pi) * T^(3/2) / (sigma * sqrt(theta_A*theta_B*theta_C)))]
         if (theta_rot(1) > 0.0_dp .and. theta_rot(2) > 0.0_dp .and. theta_rot(3) > 0.0_dp) then
            qr = sqrt(PI)*(T**1.5_dp)/(sigma*sqrt(theta_rot(1)*theta_rot(2)*theta_rot(3)))
            S = R_CALMOLK*(1.5_dp + log(qr))
         else
            S = 0.0_dp
         end if
      end if

   end subroutine compute_rotational_thermo