Map fragment dipole derivatives to system coordinates with hydrogen cap redistribution
Dipole derivatives have shape (3, 3*N) where each column corresponds to the derivative of dipole w.r.t. one Cartesian coordinate of one atom. Bond connectivity is accessed via sys_geom%bonds
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=dp), | intent(in) | :: | frag_dipole_derivs(:,:) |
(3, 3*natoms_frag) |
||
| integer, | intent(in) | :: | monomers(:) | |||
| type(system_geometry_t), | intent(in) | :: | sys_geom | |||
| real(kind=dp), | intent(inout) | :: | sys_dipole_derivs(:,:) |
(3, 3*total_atoms) |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| type(error_t), | private | :: | error | ||||
| type(physical_fragment_t), | private | :: | fragment |
subroutine map_fragment_to_system_dipole_derivatives(frag_dipole_derivs, monomers, sys_geom, sys_dipole_derivs) !! Map fragment dipole derivatives to system coordinates with hydrogen cap redistribution !! !! Dipole derivatives have shape (3, 3*N) where each column corresponds to !! the derivative of dipole w.r.t. one Cartesian coordinate of one atom. !! Bond connectivity is accessed via sys_geom%bonds use mqc_physical_fragment, only: build_fragment_from_indices, redistribute_cap_dipole_derivatives use mqc_error, only: error_t real(dp), intent(in) :: frag_dipole_derivs(:, :) !! (3, 3*natoms_frag) integer, intent(in) :: monomers(:) type(system_geometry_t), intent(in) :: sys_geom real(dp), intent(inout) :: sys_dipole_derivs(:, :) !! (3, 3*total_atoms) type(physical_fragment_t) :: fragment type(error_t) :: error ! Zero out sys_dipole_derivs = 0.0_dp if (allocated(sys_geom%bonds)) then ! Rebuild fragment to get local→global mapping and cap information call build_fragment_from_indices(sys_geom, monomers, fragment, error, sys_geom%bonds) call redistribute_cap_dipole_derivatives(fragment, frag_dipole_derivs, sys_dipole_derivs) call fragment%destroy() else ! Code path for fragments without hydrogen caps ! Map fragment dipole derivative columns to system positions (fixed-size monomers only) block integer :: i_mon, i_atom integer :: frag_atom_idx, sys_atom_idx integer :: frag_col_start, sys_col_start integer :: n_monomers n_monomers = size(monomers) frag_atom_idx = 0 ! Map each monomer's atoms do i_mon = 1, n_monomers do i_atom = 1, sys_geom%atoms_per_monomer frag_atom_idx = frag_atom_idx + 1 sys_atom_idx = (monomers(i_mon) - 1)*sys_geom%atoms_per_monomer + i_atom frag_col_start = (frag_atom_idx - 1)*3 + 1 sys_col_start = (sys_atom_idx - 1)*3 + 1 ! Copy the 3 columns (x, y, z derivatives) for this atom sys_dipole_derivs(:, sys_col_start:sys_col_start + 2) = & frag_dipole_derivs(:, frag_col_start:frag_col_start + 2) end do end do end block end if end subroutine map_fragment_to_system_dipole_derivatives