mass_weight_hessian Subroutine

public subroutine mass_weight_hessian(hessian, element_numbers, mw_hessian)

Apply mass weighting to Hessian matrix.

H_mw(i,j) = H(i,j) / sqrt(m_i * m_j)

where m_i is the mass of the atom corresponding to coordinate i. Each atom contributes 3 coordinates (x, y, z).

Arguments

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

Input Hessian in Hartree/Bohr² (3N x 3N)

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

Atomic numbers for each atom (N atoms)

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

Mass-weighted Hessian (3N x 3N)


Calls

proc~~mass_weight_hessian~~CallsGraph proc~mass_weight_hessian mass_weight_hessian proc~element_mass element_mass proc~mass_weight_hessian->proc~element_mass

Called by

proc~~mass_weight_hessian~~CalledByGraph proc~mass_weight_hessian mass_weight_hessian proc~compute_vibrational_frequencies compute_vibrational_frequencies proc~compute_vibrational_frequencies->proc~mass_weight_hessian proc~compute_vibrational_analysis compute_vibrational_analysis proc~compute_vibrational_analysis->proc~compute_vibrational_frequencies proc~hessian_coordinator hessian_coordinator proc~hessian_coordinator->proc~compute_vibrational_frequencies proc~hessian_coordinator->proc~compute_vibrational_analysis proc~unfragmented_calculation unfragmented_calculation proc~unfragmented_calculation->proc~compute_vibrational_frequencies 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~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~serial_gmbe_pie_processor serial_gmbe_pie_processor proc~serial_gmbe_pie_processor->proc~compute_vibrational_analysis proc~distributed_unfragmented_hessian distributed_unfragmented_hessian proc~distributed_unfragmented_hessian->interface~hessian_coordinator 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~run_unfragmented_calculation run_unfragmented_calculation proc~run_unfragmented_calculation->interface~unfragmented_calculation proc~serial_fragment_processor serial_fragment_processor proc~serial_fragment_processor->proc~compute_mbe interface~distributed_unfragmented_hessian distributed_unfragmented_hessian interface~distributed_unfragmented_hessian->proc~distributed_unfragmented_hessian 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~run_calculation run_calculation proc~run_calculation->proc~run_unfragmented_calculation

Variables

Type Visibility Attributes Name Initial
integer, private :: i
integer, private :: iatom
integer, private :: icoord
real(kind=dp), private, allocatable :: inv_sqrt_mass(:)
integer, private :: j
real(kind=dp), private :: mass
integer, private :: n_atoms
integer, private :: n_coords

Source Code

   subroutine mass_weight_hessian(hessian, element_numbers, mw_hessian)
      !! Apply mass weighting to Hessian matrix.
      !!
      !! H_mw(i,j) = H(i,j) / sqrt(m_i * m_j)
      !!
      !! where m_i is the mass of the atom corresponding to coordinate i.
      !! Each atom contributes 3 coordinates (x, y, z).
      real(dp), intent(in) :: hessian(:, :)
         !! Input Hessian in Hartree/Bohr² (3*N x 3*N)
      integer, intent(in) :: element_numbers(:)
         !! Atomic numbers for each atom (N atoms)
      real(dp), allocatable, intent(out) :: mw_hessian(:, :)
         !! Mass-weighted Hessian (3*N x 3*N)

      real(dp), allocatable :: inv_sqrt_mass(:)
      integer :: n_atoms, n_coords, iatom, icoord, i, j
      real(dp) :: mass

      n_atoms = size(element_numbers)
      n_coords = 3*n_atoms

      ! Build inverse square root mass vector (each mass repeated 3x for x,y,z)
      allocate (inv_sqrt_mass(n_coords))
      do iatom = 1, n_atoms
         mass = element_mass(element_numbers(iatom))
         do icoord = 1, 3
            inv_sqrt_mass(3*(iatom - 1) + icoord) = 1.0_dp/sqrt(mass)
         end do
      end do

      ! Apply mass weighting: H_mw(i,j) = H(i,j) * inv_sqrt_mass(i) * inv_sqrt_mass(j)
      allocate (mw_hessian(n_coords, n_coords))
      do j = 1, n_coords
         do i = 1, n_coords
            mw_hessian(i, j) = hessian(i, j)*inv_sqrt_mass(i)*inv_sqrt_mass(j)
         end do
      end do

      deallocate (inv_sqrt_mass)

   end subroutine mass_weight_hessian