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).
| Type | Intent | Optional | 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) |
| 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 |
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