compute_ir_intensities Subroutine

public subroutine compute_ir_intensities(dipole_derivatives, eigenvectors, element_numbers, ir_intensities)

Compute IR intensities from dipole derivatives and normal modes.

IR intensities are computed by transforming Cartesian dipole derivatives to normal mode coordinates and computing the squared magnitude.

For each normal mode i: trdip(k) = Σ_j dipd(k,j) * L(j,i) * 1/√m_j IR(i) = AU_TO_KMMOL * (trdip(1)² + trdip(2)² + trdip(3)²)

where: dipd(k,j) = ∂μ_k/∂x_j (Cartesian dipole derivative) L(j,i) = mass-weighted eigenvector component m_j = atomic mass for coordinate j

Arguments

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

Cartesian dipole derivatives (3, 3*N) in atomic units

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

Mass-weighted eigenvectors from Hessian diagonalization (3N x 3N)

integer, intent(in) :: element_numbers(:)

Atomic numbers for each atom (N atoms)

real(kind=dp), intent(out), allocatable :: ir_intensities(:)

IR intensities in km/mol (one per mode)


Calls

proc~~compute_ir_intensities~~CallsGraph proc~compute_ir_intensities compute_ir_intensities proc~element_mass element_mass proc~compute_ir_intensities->proc~element_mass

Called by

proc~~compute_ir_intensities~~CalledByGraph proc~compute_ir_intensities compute_ir_intensities proc~compute_vibrational_analysis compute_vibrational_analysis proc~compute_vibrational_analysis->proc~compute_ir_intensities proc~compute_gmbe compute_gmbe proc~compute_gmbe->proc~compute_vibrational_analysis proc~compute_mbe compute_mbe proc~compute_mbe->proc~compute_vibrational_analysis proc~gmbe_pie_coordinator gmbe_pie_coordinator proc~gmbe_pie_coordinator->proc~compute_vibrational_analysis proc~hessian_coordinator hessian_coordinator proc~hessian_coordinator->proc~compute_vibrational_analysis proc~serial_gmbe_pie_processor serial_gmbe_pie_processor proc~serial_gmbe_pie_processor->proc~compute_vibrational_analysis proc~unfragmented_calculation unfragmented_calculation proc~unfragmented_calculation->proc~compute_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~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
integer, private :: i
integer, private :: iatom
real(kind=dp), private :: inv_sqrt_mass
integer, private :: j
integer, private :: k
real(kind=dp), private :: mass
integer, private :: n_atoms
integer, private :: n_coords
real(kind=dp), private :: trdip(3)

Source Code

   subroutine compute_ir_intensities(dipole_derivatives, eigenvectors, element_numbers, ir_intensities)
      !! Compute IR intensities from dipole derivatives and normal modes.
      !!
      !! IR intensities are computed by transforming Cartesian dipole derivatives
      !! to normal mode coordinates and computing the squared magnitude.
      !!
      !! For each normal mode i:
      !!   trdip(k) = Σ_j dipd(k,j) * L(j,i) * 1/√m_j
      !!   IR(i) = AU_TO_KMMOL * (trdip(1)² + trdip(2)² + trdip(3)²)
      !!
      !! where:
      !!   dipd(k,j) = ∂μ_k/∂x_j (Cartesian dipole derivative)
      !!   L(j,i) = mass-weighted eigenvector component
      !!   m_j = atomic mass for coordinate j
      !!
      real(dp), intent(in) :: dipole_derivatives(:, :)
         !! Cartesian dipole derivatives (3, 3*N) in atomic units
      real(dp), intent(in) :: eigenvectors(:, :)
         !! Mass-weighted eigenvectors from Hessian diagonalization (3*N x 3*N)
      integer, intent(in) :: element_numbers(:)
         !! Atomic numbers for each atom (N atoms)
      real(dp), allocatable, intent(out) :: ir_intensities(:)
         !! IR intensities in km/mol (one per mode)

      integer :: n_atoms, n_coords, iatom, i, j, k
      real(dp) :: mass, inv_sqrt_mass, trdip(3)

      n_atoms = size(element_numbers)
      n_coords = 3*n_atoms

      allocate (ir_intensities(n_coords))

      ! For each normal mode i
      do i = 1, n_coords
         trdip = 0.0_dp

         ! Transform dipole derivative from Cartesian to normal mode coordinates
         ! trdip(k) = Σ_j dipd(k,j) * L(j,i) * amass_au(j)
         ! where amass_au(j) = 1/√(m_j in atomic units) = 1/√(m_amu * AMU_TO_AU)
         ! This matches xtb's formula in hessian.F90 lines 526-535
         do j = 1, n_coords
            iatom = (j - 1)/3 + 1
            mass = element_mass(element_numbers(iatom))
            ! Convert mass to atomic units (electron masses) before taking sqrt
            inv_sqrt_mass = 1.0_dp/sqrt(mass*AMU_TO_AU)

            do k = 1, 3  ! x, y, z components of dipole
               trdip(k) = trdip(k) + dipole_derivatives(k, j)*eigenvectors(j, i)*inv_sqrt_mass
            end do
         end do

         ! IR intensity = |dμ/dQ|² * conversion factor
         ir_intensities(i) = AU_TO_KMMOL*(trdip(1)**2 + trdip(2)**2 + trdip(3)**2)
      end do

   end subroutine compute_ir_intensities