Compute force constants for each normal mode.
From the harmonic oscillator relation: ω² = k/μ → k = ω² × μ = eigenvalue × μ
Returns force constants in both atomic units (Hartree/Bohr²) and mdyne/Å.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=dp), | intent(in) | :: | eigenvalues(:) |
Eigenvalues from mass-weighted Hessian diagonalization (1/amu) |
||
| real(kind=dp), | intent(in) | :: | reduced_masses(:) |
Reduced masses in amu |
||
| real(kind=dp), | intent(out), | allocatable | :: | force_constants(:) |
Force constants in atomic units (Hartree/Bohr²) |
|
| real(kind=dp), | intent(out), | optional, | allocatable | :: | force_constants_mdyne(:) |
Force constants in mdyne/Å (common experimental unit) |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | k | ||||
| integer, | private | :: | n_modes |
subroutine compute_force_constants(eigenvalues, reduced_masses, force_constants, & force_constants_mdyne) !! Compute force constants for each normal mode. !! !! From the harmonic oscillator relation: !! ω² = k/μ → k = ω² × μ = eigenvalue × μ !! !! Returns force constants in both atomic units (Hartree/Bohr²) and mdyne/Å. real(dp), intent(in) :: eigenvalues(:) !! Eigenvalues from mass-weighted Hessian diagonalization (1/amu) real(dp), intent(in) :: reduced_masses(:) !! Reduced masses in amu real(dp), allocatable, intent(out) :: force_constants(:) !! Force constants in atomic units (Hartree/Bohr²) real(dp), allocatable, intent(out), optional :: force_constants_mdyne(:) !! Force constants in mdyne/Å (common experimental unit) integer :: n_modes, k n_modes = size(eigenvalues) allocate (force_constants(n_modes)) ! k = eigenvalue × μ (eigenvalue has units Hartree/(Bohr²·amu), μ in amu) ! So force_constant has units Hartree/Bohr² do k = 1, n_modes if (eigenvalues(k) >= 0.0_dp) then force_constants(k) = eigenvalues(k)*reduced_masses(k) else ! Imaginary frequency mode - report absolute value force_constants(k) = -abs(eigenvalues(k))*reduced_masses(k) end if end do ! Optionally convert to mdyne/Å if (present(force_constants_mdyne)) then allocate (force_constants_mdyne(n_modes)) force_constants_mdyne = force_constants*AU_TO_MDYNE_ANG end if end subroutine compute_force_constants