Bottom-up computation of n-body dipole derivative correction Mirrors MBE Hessian logic but for dipole derivatives Bond connectivity is accessed via sys_geom%bonds
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int64), | intent(in) | :: | fragment_idx | |||
| integer, | intent(in) | :: | fragment(:) | |||
| type(fragment_lookup_t), | intent(in) | :: | lookup | |||
| type(calculation_result_t), | intent(in) | :: | results(:) | |||
| real(kind=dp), | intent(inout) | :: | delta_dipole_derivs(:,:,:) |
(3, 3*total_atoms, fragment_count) |
||
| integer, | intent(in) | :: | n | |||
| type(system_geometry_t), | intent(in) | :: | sys_geom |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| logical, | private | :: | has_next | ||||
| integer, | private | :: | i | ||||
| integer, | private | :: | indices(MAX_MBE_LEVEL) | ||||
| integer, | private | :: | subset(MAX_MBE_LEVEL) | ||||
| integer(kind=int64), | private | :: | subset_idx | ||||
| integer, | private | :: | subset_size |
subroutine compute_mbe_dipole_derivatives(fragment_idx, fragment, lookup, results, delta_dipole_derivs, n, sys_geom) !! Bottom-up computation of n-body dipole derivative correction !! Mirrors MBE Hessian logic but for dipole derivatives !! Bond connectivity is accessed via sys_geom%bonds use mqc_result_types, only: calculation_result_t use mqc_error, only: error_t integer(int64), intent(in) :: fragment_idx integer, intent(in) :: fragment(:), n type(fragment_lookup_t), intent(in) :: lookup type(calculation_result_t), intent(in) :: results(:) real(dp), intent(inout) :: delta_dipole_derivs(:, :, :) !! (3, 3*total_atoms, fragment_count) type(system_geometry_t), intent(in) :: sys_geom integer :: subset_size, i integer :: indices(MAX_MBE_LEVEL), subset(MAX_MBE_LEVEL) ! Stack arrays to avoid heap contention integer(int64) :: subset_idx logical :: has_next ! Start with the full n-mer dipole derivatives mapped to system coordinates call map_fragment_to_system_dipole_derivatives(results(fragment_idx)%dipole_derivatives, fragment, & sys_geom, delta_dipole_derivs(:, :, fragment_idx)) ! Subtract all proper subsets (size 1 to n-1) do subset_size = 1, n - 1 ! Initialize first combination do i = 1, subset_size indices(i) = i end do has_next = .true. do while (has_next) do i = 1, subset_size subset(i) = fragment(indices(i)) end do subset_idx = lookup%find(subset(1:subset_size), subset_size) if (subset_idx > 0) then ! Subtract this subset's delta dipole derivatives delta_dipole_derivs(:, :, fragment_idx) = delta_dipole_derivs(:, :, fragment_idx) - & delta_dipole_derivs(:, :, subset_idx) end if call get_next_combination(indices, subset_size, n, has_next) end do end do end subroutine compute_mbe_dipole_derivatives