finite_diff_dipole_derivatives Subroutine

public subroutine finite_diff_dipole_derivatives(n_atoms, forward_dipoles, backward_dipoles, displacement, dipole_derivatives)

Compute dipole moment derivatives via central finite differences

Computes: d_mu_k/d_x_j = (mu_k(+h) - mu_k(-h)) / (2h)

This is used for IR intensity calculations, where we need the dipole moment derivatives with respect to Cartesian nuclear coordinates.

Args: n_atoms: Number of atoms forward_dipoles: Dipoles at forward-displaced geometries (3n_atoms, 3) backward_dipoles: Dipoles at backward-displaced geometries (3n_atoms, 3) displacement: Step size in Bohr dipole_derivatives: Output derivatives (3, 3*n_atoms) in a.u.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: n_atoms
real(kind=dp), intent(in) :: forward_dipoles(:,:)

(3*n_atoms, 3)

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

(3*n_atoms, 3)

real(kind=dp), intent(in) :: displacement
real(kind=dp), intent(out), allocatable :: dipole_derivatives(:,:)

(3, 3*n_atoms)


Called by

proc~~finite_diff_dipole_derivatives~~CalledByGraph proc~finite_diff_dipole_derivatives finite_diff_dipole_derivatives proc~hessian_coordinator hessian_coordinator proc~hessian_coordinator->proc~finite_diff_dipole_derivatives proc~xtb_calc_hessian xtb_method_t%xtb_calc_hessian proc~xtb_calc_hessian->proc~finite_diff_dipole_derivatives interface~hessian_coordinator hessian_coordinator interface~hessian_coordinator->proc~hessian_coordinator proc~distributed_unfragmented_hessian distributed_unfragmented_hessian proc~distributed_unfragmented_hessian->interface~hessian_coordinator interface~distributed_unfragmented_hessian distributed_unfragmented_hessian interface~distributed_unfragmented_hessian->proc~distributed_unfragmented_hessian proc~run_unfragmented_calculation run_unfragmented_calculation proc~run_unfragmented_calculation->interface~distributed_unfragmented_hessian

Variables

Type Visibility Attributes Name Initial
integer, private :: j
integer, private :: k
integer, private :: n_coords

Source Code

   subroutine finite_diff_dipole_derivatives(n_atoms, forward_dipoles, backward_dipoles, &
                                             displacement, dipole_derivatives)
      !! Compute dipole moment derivatives via central finite differences
      !!
      !! Computes: d_mu_k/d_x_j = (mu_k(+h) - mu_k(-h)) / (2h)
      !!
      !! This is used for IR intensity calculations, where we need the dipole
      !! moment derivatives with respect to Cartesian nuclear coordinates.
      !!
      !! Args:
      !!   n_atoms: Number of atoms
      !!   forward_dipoles: Dipoles at forward-displaced geometries (3*n_atoms, 3)
      !!   backward_dipoles: Dipoles at backward-displaced geometries (3*n_atoms, 3)
      !!   displacement: Step size in Bohr
      !!   dipole_derivatives: Output derivatives (3, 3*n_atoms) in a.u.
      integer, intent(in) :: n_atoms
      real(dp), intent(in) :: forward_dipoles(:, :)   !! (3*n_atoms, 3)
      real(dp), intent(in) :: backward_dipoles(:, :)  !! (3*n_atoms, 3)
      real(dp), intent(in) :: displacement
      real(dp), intent(out), allocatable :: dipole_derivatives(:, :)  !! (3, 3*n_atoms)

      integer :: n_coords, j, k

      n_coords = 3*n_atoms
      allocate (dipole_derivatives(3, n_coords))

      ! Central difference: d_mu_k/d_x_j = (mu_k(x_j+h) - mu_k(x_j-h)) / (2h)
      do j = 1, n_coords       ! Cartesian coordinate index (which coordinate was displaced)
         do k = 1, 3           ! Dipole component (x, y, z)
            dipole_derivatives(k, j) = (forward_dipoles(j, k) - backward_dipoles(j, k))/ &
                                       (2.0_dp*displacement)
         end do
      end do

   end subroutine finite_diff_dipole_derivatives