LCOV - code coverage report
Current view: top level - src - qs_vcd_ao.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:9ccafda) Lines: 97.5 % 438 427
Test Date: 2026-10-15 00:55:44 Functions: 100.0 % 10 10

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : MODULE qs_vcd_ao
       8              : 
       9              :    USE ai_cartesian_operators,          ONLY: apply_cartesian_operator
      10              :    USE ai_contraction,                  ONLY: block_add,&
      11              :                                               contraction
      12              :    USE ai_kinetic,                      ONLY: kinetic
      13              :    USE ai_overlap_ppl,                  ONLY: ppl_integral
      14              :    USE ao_util,                         ONLY: exp_radius_very_extended
      15              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      16              :                                               get_atomic_kind_set
      17              :    USE basis_set_types,                 ONLY: get_gto_basis_set,&
      18              :                                               gto_basis_set_p_type,&
      19              :                                               gto_basis_set_type
      20              :    USE block_p_types,                   ONLY: block_p_type
      21              :    USE cell_types,                      ONLY: cell_type,&
      22              :                                               pbc
      23              :    USE cp_control_types,                ONLY: dft_control_type
      24              :    USE cp_dbcsr_api,                    ONLY: &
      25              :         dbcsr_add, dbcsr_copy, dbcsr_desymmetrize, dbcsr_distribution_get, &
      26              :         dbcsr_distribution_type, dbcsr_finalize, dbcsr_get_block_p, dbcsr_get_info, dbcsr_init_p, &
      27              :         dbcsr_p_type, dbcsr_scale, dbcsr_set, dbcsr_work_create
      28              :    USE cp_dbcsr_operations,             ONLY: dbcsr_allocate_matrix_set,&
      29              :                                               dbcsr_deallocate_matrix_set
      30              :    USE external_potential_types,        ONLY: get_potential,&
      31              :                                               gth_potential_type,&
      32              :                                               sgp_potential_type
      33              :    USE gaussian_gridlevels,             ONLY: gridlevel_info_type
      34              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      35              :                                               section_vals_type
      36              :    USE kinds,                           ONLY: default_string_length,&
      37              :                                               dp,&
      38              :                                               int_8
      39              :    USE memory_utilities,                ONLY: reallocate
      40              :    USE message_passing,                 ONLY: mp_comm_type
      41              :    USE orbital_pointers,                ONLY: init_orbital_pointers,&
      42              :                                               ncoset
      43              :    USE particle_types,                  ONLY: particle_type
      44              :    USE pw_env_types,                    ONLY: pw_env_get,&
      45              :                                               pw_env_type
      46              :    USE pw_methods,                      ONLY: pw_axpy,&
      47              :                                               pw_zero
      48              :    USE pw_pool_types,                   ONLY: pw_pool_type
      49              :    USE pw_types,                        ONLY: pw_r3d_rs_type
      50              :    USE qs_energy_types,                 ONLY: qs_energy_type
      51              :    USE qs_environment_types,            ONLY: get_qs_env,&
      52              :                                               qs_environment_type
      53              :    USE qs_integral_utils,               ONLY: basis_set_list_setup,&
      54              :                                               get_memory_usage
      55              :    USE qs_integrate_potential,          ONLY: integrate_pgf_product
      56              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      57              :                                               get_qs_kind_set,&
      58              :                                               qs_kind_type
      59              :    USE qs_ks_types,                     ONLY: qs_ks_env_type
      60              :    USE qs_linres_types,                 ONLY: vcd_env_type
      61              :    USE qs_moments,                      ONLY: build_local_moment_matrix
      62              :    USE qs_neighbor_list_types,          ONLY: &
      63              :         get_iterator_info, get_neighbor_list_set_p, neighbor_list_iterate, &
      64              :         neighbor_list_iterator_create, neighbor_list_iterator_p_type, &
      65              :         neighbor_list_iterator_release, neighbor_list_set_p_type, nl_set_sub_iterator, &
      66              :         nl_sub_iterate
      67              :    USE qs_rho_types,                    ONLY: qs_rho_type
      68              :    USE qs_vxc,                          ONLY: qs_vxc_create
      69              :    USE realspace_grid_types,            ONLY: realspace_grid_type
      70              :    USE rs_pw_interface,                 ONLY: potential_pw2rs
      71              :    USE sap_kind_types,                  ONLY: alist_type,&
      72              :                                               build_sap_ints,&
      73              :                                               get_alist,&
      74              :                                               release_sap_int,&
      75              :                                               sap_int_type,&
      76              :                                               sap_sort
      77              :    USE task_list_types,                 ONLY: atom_pair_type,&
      78              :                                               task_list_type,&
      79              :                                               task_type
      80              :    USE upf_local_integrals,             ONLY: upf_local_init,&
      81              :                                               upf_local_matrix
      82              :    USE virial_types,                    ONLY: virial_type
      83              : 
      84              : !$ USE OMP_LIB, ONLY: omp_get_max_threads, omp_get_thread_num, omp_get_num_threads
      85              : !$ USE OMP_LIB, ONLY: omp_lock_kind, &
      86              : !$                    omp_init_lock, omp_set_lock, &
      87              : !$                    omp_unset_lock, omp_destroy_lock
      88              : 
      89              : #include "./base/base_uses.f90"
      90              : 
      91              :    IMPLICIT NONE
      92              : 
      93              :    PRIVATE
      94              : 
      95              : ! *** Global parameters ***
      96              : 
      97              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_vcd_ao'
      98              :    INTEGER, PARAMETER :: bi_1 = 1, bi_x = 2, bi_y = 3, bi_z = 4, bi_xx = 5, &
      99              :                          bi_xy = 6, bi_xz = 7, bi_yy = 8, bi_yz = 9, bi_zz = 10
     100              :    INTEGER, DIMENSION(3), PARAMETER :: bi_r = [bi_x, bi_y, bi_z]
     101              :    INTEGER, DIMENSION(3, 3), PARAMETER :: bi_rr = RESHAPE([bi_xx, bi_xy, bi_xz, bi_xy, bi_yy, bi_yz, &
     102              :                                                            bi_xz, bi_yz, bi_zz], [3, 3])
     103              : 
     104              : ! *** Public subroutines ***
     105              : 
     106              :    PUBLIC :: build_dSdV_matrix, build_com_rpnl_r, &
     107              :              hr_mult_by_delta_3d, build_dcom_rpnl, &
     108              :              build_matrix_hr_rh
     109              : 
     110              : CONTAINS
     111              : 
     112              : ! **************************************************************************************************
     113              : !> \brief Build the matrix Hr*delta_nu^\lambda - rH*delta_mu^\lambda
     114              : !> \param vcd_env ...
     115              : !> \param qs_env ...
     116              : !> \param rc ...
     117              : !> \author Edward Ditler
     118              : ! **************************************************************************************************
     119           38 :    SUBROUTINE build_matrix_hr_rh(vcd_env, qs_env, rc)
     120              :       TYPE(vcd_env_type)                                 :: vcd_env
     121              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     122              :       REAL(dp), DIMENSION(3)                             :: rc
     123              : 
     124              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'build_matrix_hr_rh'
     125              :       INTEGER, PARAMETER                                 :: ispin = 1
     126              : 
     127              :       INTEGER                                            :: handle, i
     128              :       TYPE(cell_type), POINTER                           :: cell
     129              :       TYPE(dft_control_type), POINTER                    :: dft_control
     130              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     131           38 :          POINTER                                         :: sab_all, sap_ppnl
     132           38 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     133           38 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     134              : 
     135           38 :       CALL timeset(routineN, handle)
     136              : 
     137              :       CALL get_qs_env(qs_env=qs_env, &
     138              :                       dft_control=dft_control, &
     139              :                       particle_set=particle_set, &
     140              :                       sab_all=sab_all, &
     141              :                       sap_ppnl=sap_ppnl, &
     142              :                       qs_kind_set=qs_kind_set, &
     143           38 :                       cell=cell)
     144              : 
     145          152 :       DO i = 1, 3
     146          114 :          CALL dbcsr_set(vcd_env%matrix_hr(ispin, i)%matrix, 0._dp)
     147          152 :          CALL dbcsr_set(vcd_env%matrix_rh(ispin, i)%matrix, 0._dp)
     148              :       END DO
     149              : 
     150              :       ASSOCIATE (matrix_hr_1d => vcd_env%matrix_hr(ispin, 1:3), &
     151              :                  matrix_rh_1d => vcd_env%matrix_rh(ispin, 1:3))
     152              :          CALL build_rpnl_matrices(matrix_hr_1d, matrix_rh_1d, qs_kind_set, particle_set, sab_all, sap_ppnl, &
     153           38 :                                   dft_control%qs_control%eps_ppnl, cell, rc)
     154           38 :          CALL build_tr_matrices(matrix_hr_1d, matrix_rh_1d, qs_env, qs_kind_set, "ORB", sab_all, rc)
     155           38 :          CALL build_rcore_matrices(matrix_hr_1d, matrix_rh_1d, qs_env, qs_kind_set, "ORB", sab_all, rc)
     156           76 :          CALL build_vhxc_matrices(vcd_env%matrix_hr, vcd_env%matrix_rh, qs_env, rc)
     157              :       END ASSOCIATE
     158              : 
     159           38 :       CALL timestop(handle)
     160           38 :    END SUBROUTINE build_matrix_hr_rh
     161              : 
     162              : ! **************************************************************************************************
     163              : !> \brief Build the ordered products V_nl*r and r*V_nl.
     164              : !> \param matrix_vr ...
     165              : !> \param matrix_rv ...
     166              : !> \param qs_kind_set ...
     167              : !> \param particle_set ...
     168              : !> \param sab_all ...
     169              : !> \param sap_ppnl ...
     170              : !> \param eps_ppnl ...
     171              : !> \param cell ...
     172              : !> \param ref_point ...
     173              : !> \author Edward Ditler, Tomas Zimmermann
     174              : ! **************************************************************************************************
     175           38 :    SUBROUTINE build_rpnl_matrices(matrix_vr, matrix_rv, qs_kind_set, particle_set, sab_all, sap_ppnl, eps_ppnl, &
     176              :                                   cell, ref_point)
     177              : 
     178              :       TYPE(dbcsr_p_type), DIMENSION(:)                   :: matrix_vr, matrix_rv
     179              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     180              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     181              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     182              :          POINTER                                         :: sab_all, sap_ppnl
     183              :       REAL(KIND=dp), INTENT(IN)                          :: eps_ppnl
     184              :       TYPE(cell_type), INTENT(IN), OPTIONAL, POINTER     :: cell
     185              :       REAL(KIND=dp), DIMENSION(3)                        :: ref_point
     186              : 
     187              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'build_rpnl_matrices'
     188              : 
     189              :       INTEGER                                            :: handle, i, iab, iac, iatom, ibc, icol, &
     190              :                                                             ikind, irow, jatom, jkind, kac, kbc, &
     191              :                                                             kkind, na, natom, nb, nkind, np, slot
     192              :       INTEGER, DIMENSION(3)                              :: cell_b
     193              :       LOGICAL                                            :: found, ppnl_present
     194           38 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: achint, acint, bchint, bcint
     195              :       TYPE(alist_type), POINTER                          :: alist_ac, alist_bc
     196          266 :       TYPE(block_p_type), DIMENSION(3)                   :: blocks_rv, blocks_vr
     197           38 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set
     198              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
     199           38 :       TYPE(sap_int_type), DIMENSION(:), POINTER          :: sap_int
     200              : 
     201              : !$    INTEGER(kind=omp_lock_kind), &
     202           38 : !$       ALLOCATABLE, DIMENSION(:) :: locks
     203              : !$    INTEGER                                            :: lock_num, hash
     204              : !$    INTEGER, PARAMETER                                 :: nlock = 501
     205              : 
     206           38 :       ppnl_present = ASSOCIATED(sap_ppnl)
     207           38 :       IF (.NOT. ppnl_present) RETURN
     208              : 
     209           38 :       CALL timeset(routineN, handle)
     210           38 :       nkind = SIZE(qs_kind_set)
     211           38 :       natom = SIZE(particle_set)
     212              : 
     213              :       ! sap_int needs to be shared as multiple threads need to access this
     214           38 :       NULLIFY (sap_int)
     215          266 :       ALLOCATE (sap_int(nkind*nkind))
     216          190 :       DO i = 1, nkind*nkind
     217          152 :          NULLIFY (sap_int(i)%alist, sap_int(i)%asort, sap_int(i)%aindex)
     218          190 :          sap_int(i)%nalist = 0
     219              :       END DO
     220              : 
     221              :       MARK_USED(ref_point)
     222              :       ! "nder" in moment_mode is "order"
     223              :       CALL build_sap_ints(sap_int, sap_ppnl, qs_kind_set, nder=1, moment_mode=.TRUE., &
     224           38 :                           particle_set=particle_set, cell=cell, refpoint=ref_point)
     225              : 
     226              :       ! *** Set up a sorting index
     227           38 :       CALL sap_sort(sap_int)
     228              : 
     229          190 :       ALLOCATE (basis_set(nkind))
     230          114 :       DO ikind = 1, nkind
     231           76 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
     232          114 :          IF (ASSOCIATED(orb_basis_set)) THEN
     233           76 :             basis_set(ikind)%gto_basis_set => orb_basis_set
     234              :          ELSE
     235            0 :             NULLIFY (basis_set(ikind)%gto_basis_set)
     236              :          END IF
     237              :       END DO
     238              : 
     239              :       ! *** All integrals needed have been calculated and stored in sap_int
     240              :       ! *** We now calculate the ordered product matrix elements
     241              : 
     242              : !$OMP PARALLEL &
     243              : !$OMP DEFAULT (NONE) &
     244              : !$OMP SHARED  (basis_set, matrix_vr, matrix_rv, &
     245              : !$OMP          sap_int, nkind, eps_ppnl, locks, sab_all) &
     246              : !$OMP PRIVATE (ikind, jkind, iatom, jatom, cell_b, &
     247              : !$OMP          iab, irow, icol, blocks_vr, blocks_rv, &
     248              : !$OMP          found, iac, ibc, alist_ac, alist_bc, &
     249              : !$OMP          na, np, nb, kkind, kac, kbc, i, lock_num, &
     250           38 : !$OMP          hash, natom, acint, bcint, achint, bchint)
     251              : 
     252              : !$OMP SINGLE
     253              : !$    ALLOCATE (locks(nlock))
     254              : !$OMP END SINGLE
     255              : 
     256              : !$OMP DO
     257              : !$    DO lock_num = 1, nlock
     258              : !$       call omp_init_lock(locks(lock_num))
     259              : !$    END DO
     260              : !$OMP END DO
     261              : 
     262              : !$OMP DO SCHEDULE(GUIDED)
     263              : 
     264              :       DO slot = 1, sab_all(1)%nl_size
     265              : 
     266              :          ikind = sab_all(1)%nlist_task(slot)%ikind
     267              :          jkind = sab_all(1)%nlist_task(slot)%jkind
     268              :          iatom = sab_all(1)%nlist_task(slot)%iatom
     269              :          jatom = sab_all(1)%nlist_task(slot)%jatom
     270              :          cell_b(:) = sab_all(1)%nlist_task(slot)%cell(:)
     271              : 
     272              :          IF (.NOT. ASSOCIATED(basis_set(ikind)%gto_basis_set)) CYCLE
     273              :          IF (.NOT. ASSOCIATED(basis_set(jkind)%gto_basis_set)) CYCLE
     274              :          iab = ikind + nkind*(jkind - 1)
     275              : 
     276              :          ! *** Create matrix blocks for a new matrix block column ***
     277              :          irow = iatom
     278              :          icol = jatom
     279              :          DO i = 1, 3
     280              :             CALL dbcsr_get_block_p(matrix_vr(i)%matrix, irow, icol, blocks_vr(i)%block, found)
     281              :             CPASSERT(found)
     282              :             CALL dbcsr_get_block_p(matrix_rv(i)%matrix, irow, icol, blocks_rv(i)%block, found)
     283              :             CPASSERT(found)
     284              :          END DO
     285              : 
     286              :          ! loop over all kinds for projector atom
     287              :          DO kkind = 1, nkind
     288              :             iac = ikind + nkind*(kkind - 1)
     289              :             ibc = jkind + nkind*(kkind - 1)
     290              :             IF (.NOT. ASSOCIATED(sap_int(iac)%alist)) CYCLE
     291              :             IF (.NOT. ASSOCIATED(sap_int(ibc)%alist)) CYCLE
     292              :             CALL get_alist(sap_int(iac), alist_ac, iatom)
     293              :             CALL get_alist(sap_int(ibc), alist_bc, jatom)
     294              : 
     295              :             IF (.NOT. ASSOCIATED(alist_ac)) CYCLE
     296              :             IF (.NOT. ASSOCIATED(alist_bc)) CYCLE
     297              :             DO kac = 1, alist_ac%nclist
     298              :                DO kbc = 1, alist_bc%nclist
     299              :                   IF (alist_ac%clist(kac)%catom /= alist_bc%clist(kbc)%catom) CYCLE
     300              :                   IF (ALL(cell_b + alist_bc%clist(kbc)%cell - alist_ac%clist(kac)%cell == 0)) THEN
     301              :                      IF (alist_ac%clist(kac)%maxac*alist_bc%clist(kbc)%maxach < eps_ppnl) CYCLE
     302              :                      acint => alist_ac%clist(kac)%acint
     303              :                      bcint => alist_bc%clist(kbc)%acint
     304              :                      achint => alist_ac%clist(kac)%achint
     305              :                      bchint => alist_bc%clist(kbc)%achint
     306              :                      na = SIZE(acint, 1)
     307              :                      np = SIZE(acint, 2)
     308              :                      nb = SIZE(bcint, 1)
     309              : !$                   hash = MOD((iatom - 1)*natom + jatom, nlock) + 1
     310              : !$                   CALL omp_set_lock(locks(hash))
     311              :                      DO i = 1, 3
     312              :                         ! Vnl*r
     313              :                         blocks_vr(i)%block(1:na, 1:nb) = blocks_vr(i)%block(1:na, 1:nb) + &
     314              :                                                          MATMUL(achint(1:na, 1:np, 1), &
     315              :                                                                 TRANSPOSE(bcint(1:nb, 1:np, i + 1)))
     316              :                         ! r*Vnl
     317              :                         blocks_rv(i)%block(1:na, 1:nb) = blocks_rv(i)%block(1:na, 1:nb) + &
     318              :                                                          MATMUL(achint(1:na, 1:np, i + 1), &
     319              :                                                                 TRANSPOSE(bcint(1:nb, 1:np, 1)))
     320              :                      END DO
     321              : !$                   CALL omp_unset_lock(locks(hash))
     322              :                      EXIT ! We have found a match and there can be only one single match
     323              :                   END IF
     324              :                END DO
     325              :             END DO
     326              :          END DO
     327              :          DO i = 1, 3
     328              :             NULLIFY (blocks_vr(i)%block)
     329              :             NULLIFY (blocks_rv(i)%block)
     330              :          END DO
     331              :       END DO
     332              : 
     333              : !$OMP DO
     334              : !$    DO lock_num = 1, nlock
     335              : !$       call omp_destroy_lock(locks(lock_num))
     336              : !$    END DO
     337              : !$OMP END DO
     338              : 
     339              : !$OMP SINGLE
     340              : !$    DEALLOCATE (locks)
     341              : !$OMP END SINGLE NOWAIT
     342              : 
     343              : !$OMP END PARALLEL
     344              : 
     345           38 :       CALL release_sap_int(sap_int)
     346              : 
     347           38 :       DEALLOCATE (basis_set)
     348              : 
     349           38 :       CALL timestop(handle)
     350              : 
     351          114 :    END SUBROUTINE build_rpnl_matrices
     352              : 
     353              : ! **************************************************************************************************
     354              : !> \brief   Calculation of the product Tr or rT over Cartesian Gaussian functions.
     355              : !> \param   matrix_tr ...
     356              : !> \param matrix_rt ...
     357              : !> \param   qs_env ...
     358              : !> \param   qs_kind_set ...
     359              : !> \param   basis_type basis set to be used
     360              : !> \param   sab_nl pair list (must be consistent with basis sets!)
     361              : !> \param   rc ...
     362              : !> \date    11.10.2010
     363              : !> \par     History
     364              : !>          Ported from qs_overlap, replaces code in build_core_hamiltonian
     365              : !>          Refactoring [07.2014] JGH
     366              : !>          Simplify options and use new kinetic energy integral routine
     367              : !>          Adapted from qs_kinetic [07.2016]
     368              : !>          Adapted from the kinetic position-product recurrence [2021] by ED
     369              : !> \author  JGH
     370              : !> \version 1.0
     371              : ! **************************************************************************************************
     372           38 :    SUBROUTINE build_tr_matrices(matrix_tr, matrix_rt, qs_env, qs_kind_set, basis_type, sab_nl, rc)
     373              : 
     374              :       TYPE(dbcsr_p_type), DIMENSION(:)                   :: matrix_tr, matrix_rt
     375              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     376              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     377              :       CHARACTER(LEN=*), INTENT(IN)                       :: basis_type
     378              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     379              :          POINTER                                         :: sab_nl
     380              :       REAL(KIND=dp), DIMENSION(3)                        :: rc
     381              : 
     382              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'build_tr_matrices'
     383              : 
     384              :       INTEGER                                            :: handle, i, iatom, icol, ikind, ir, irow, &
     385              :                                                             iset, jatom, jkind, jset, ldsab, ltab, &
     386              :                                                             natom, ncoa, ncob, nkind, nseta, &
     387              :                                                             nsetb, sgfa, sgfb, slot
     388              :       INTEGER, DIMENSION(3)                              :: cell
     389           38 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, lb_max, lb_min, npgfa, &
     390           38 :                                                             npgfb, nsgfa, nsgfb
     391           38 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, first_sgfb
     392              :       LOGICAL                                            :: do_symmetric, found, trans
     393              :       REAL(KIND=dp)                                      :: tab
     394           38 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: qab, tkab
     395           38 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: kab
     396              :       REAL(KIND=dp), DIMENSION(3)                        :: ra, rab, rac, rb, rbc
     397           38 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: set_radius_a, set_radius_b
     398           38 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: rpgfa, rpgfb, scon_a, scon_b, zeta, zetb
     399          342 :       TYPE(block_p_type), DIMENSION(3, 2)                :: blocks_tr
     400              :       TYPE(cell_type), POINTER                           :: qs_cell
     401           38 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set_list
     402              :       TYPE(gto_basis_set_type), POINTER                  :: basis_set_a, basis_set_b
     403           38 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     404              : 
     405              : !$    INTEGER(kind=omp_lock_kind), &
     406           38 : !$       ALLOCATABLE, DIMENSION(:) :: locks
     407              : !$    INTEGER                                            :: lock_num, hash, hash1, hash2
     408              : !$    INTEGER(KIND=int_8)                                :: iatom8
     409              : !$    INTEGER, PARAMETER                                 :: nlock = 501
     410              : 
     411              :       MARK_USED(int_8)
     412              : 
     413           38 :       CALL timeset(routineN, handle)
     414              : 
     415           38 :       nkind = SIZE(qs_kind_set)
     416              : 
     417              :       ! check for symmetry
     418           38 :       CPASSERT(SIZE(sab_nl) > 0)
     419           38 :       CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
     420              : 
     421              :       ! prepare basis set
     422          190 :       ALLOCATE (basis_set_list(nkind))
     423           38 :       CALL basis_set_list_setup(basis_set_list, basis_type, qs_kind_set)
     424              : 
     425              :       ! *** Allocate work storage ***
     426           38 :       ldsab = get_memory_usage(qs_kind_set, basis_type)
     427              : 
     428              :       CALL get_qs_env(qs_env=qs_env, &
     429              :                       particle_set=particle_set, &
     430              :                       cell=qs_cell, &
     431           38 :                       natom=natom)
     432              : 
     433              : !$OMP PARALLEL DEFAULT(NONE) &
     434              : !$OMP SHARED (ldsab,do_symmetric, sab_nl, rc,&
     435              : !$OMP         ncoset,matrix_tr,matrix_rt,basis_set_list,qs_cell,natom,locks)  &
     436              : !$OMP PRIVATE (blocks_tr,kab,qab,tab,ikind,jkind,iatom,jatom,rab,rac,rbc,cell, &
     437              : !$OMP          basis_set_a, basis_set_b, nseta, ncoa, ncob, ltab, nsetb, tkab, &
     438              : !$OMP          irow, icol, found, trans, sgfa, sgfb, iset, jset, i, &
     439              : !$OMP          hash, hash1, hash2, iatom8, slot, lock_num) &
     440              : !$OMP PRIVATE (first_sgfa, la_max, la_min, npgfa, nsgfa, rpgfa, set_radius_a, zeta, scon_a) &
     441              : !$OMP PRIVATE (first_sgfb, lb_max, lb_min, npgfb, nsgfb, rpgfb, set_radius_b, zetb, scon_b) &
     442              : !$OMP SHARED(particle_set) &
     443           38 : !$OMP PRIVATE(ra, rb)
     444              : 
     445              : !$OMP SINGLE
     446              : !$    ALLOCATE (locks(nlock))
     447              : !$OMP END SINGLE
     448              : 
     449              : !$OMP DO
     450              : !$    DO lock_num = 1, nlock
     451              : !$       call omp_init_lock(locks(lock_num))
     452              : !$    END DO
     453              : !$OMP END DO
     454              : 
     455              :       ALLOCATE (kab(ldsab, ldsab, 3), qab(ldsab, ldsab))
     456              : 
     457              : !$OMP DO SCHEDULE(GUIDED)
     458              :       DO slot = 1, sab_nl(1)%nl_size
     459              : 
     460              :          ikind = sab_nl(1)%nlist_task(slot)%ikind
     461              :          jkind = sab_nl(1)%nlist_task(slot)%jkind
     462              :          iatom = sab_nl(1)%nlist_task(slot)%iatom
     463              :          jatom = sab_nl(1)%nlist_task(slot)%jatom
     464              :          cell(:) = sab_nl(1)%nlist_task(slot)%cell(:)
     465              :          rab(1:3) = sab_nl(1)%nlist_task(slot)%r(1:3)
     466              : 
     467              :          basis_set_a => basis_set_list(ikind)%gto_basis_set
     468              :          IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
     469              :          basis_set_b => basis_set_list(jkind)%gto_basis_set
     470              :          IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
     471              : 
     472              : !$       iatom8 = INT(iatom - 1, int_8)*INT(natom, int_8) + INT(jatom, int_8)
     473              : !$       hash1 = INT(MOD(iatom8, INT(nlock, int_8)) + 1)
     474              : 
     475              :          ! basis ikind
     476              :          first_sgfa => basis_set_a%first_sgf
     477              :          la_max => basis_set_a%lmax
     478              :          la_min => basis_set_a%lmin
     479              :          npgfa => basis_set_a%npgf
     480              :          nsgfa => basis_set_a%nsgf_set
     481              :          rpgfa => basis_set_a%pgf_radius
     482              :          set_radius_a => basis_set_a%set_radius
     483              :          scon_a => basis_set_a%scon
     484              :          zeta => basis_set_a%zet
     485              :          ! basis jkind
     486              :          first_sgfb => basis_set_b%first_sgf
     487              :          lb_max => basis_set_b%lmax
     488              :          lb_min => basis_set_b%lmin
     489              :          npgfb => basis_set_b%npgf
     490              :          nsgfb => basis_set_b%nsgf_set
     491              :          rpgfb => basis_set_b%pgf_radius
     492              :          set_radius_b => basis_set_b%set_radius
     493              :          scon_b => basis_set_b%scon
     494              :          zetb => basis_set_b%zet
     495              : 
     496              :          nseta = basis_set_a%nset
     497              :          nsetb = basis_set_b%nset
     498              : 
     499              :          IF (do_symmetric) THEN
     500              :             IF (iatom <= jatom) THEN
     501              :                irow = iatom
     502              :                icol = jatom
     503              :             ELSE
     504              :                irow = jatom
     505              :                icol = iatom
     506              :             END IF
     507              :          ELSE
     508              :             irow = iatom
     509              :             icol = jatom
     510              :          END IF
     511              :          DO ir = 1, 3
     512              :             NULLIFY (blocks_tr(ir, 1)%block)
     513              :             CALL dbcsr_get_block_p(matrix=matrix_tr(ir)%matrix, &
     514              :                                    row=irow, col=icol, BLOCK=blocks_tr(ir, 1)%block, found=found)
     515              :             CPASSERT(found)
     516              :             NULLIFY (blocks_tr(ir, 2)%block)
     517              :             CALL dbcsr_get_block_p(matrix=matrix_rt(ir)%matrix, &
     518              :                                    row=irow, col=icol, BLOCK=blocks_tr(ir, 2)%block, found=found)
     519              :             CPASSERT(found)
     520              :          END DO
     521              : 
     522              :          ! The kinetic integrals depend only on rab (also for the screening)
     523              :          tab = NORM2(rab)
     524              : 
     525              :          ! With and without MIC, rab(:) is the vector giving us the coordinates of rb.
     526              :          ra = pbc(particle_set(iatom)%r(:), qs_cell)
     527              :          rb(:) = ra(:) + rab(:)
     528              :          rac = pbc(rc, ra, qs_cell)
     529              :          rbc = rac + rab
     530              : 
     531              :          trans = do_symmetric .AND. (iatom > jatom)
     532              : 
     533              :          DO iset = 1, nseta
     534              : 
     535              :             ncoa = npgfa(iset)*(ncoset(la_max(iset)) - ncoset(la_min(iset) - 1))
     536              :             sgfa = first_sgfa(1, iset)
     537              : 
     538              :             DO jset = 1, nsetb
     539              : 
     540              :                IF (set_radius_a(iset) + set_radius_b(jset) < tab) CYCLE
     541              : 
     542              : !$             hash2 = MOD((iset - 1)*nsetb + jset, nlock) + 1
     543              : !$             hash = MOD(hash1 + hash2, nlock) + 1
     544              : 
     545              :                ncob = npgfb(jset)*(ncoset(lb_max(jset)) - ncoset(lb_min(jset) - 1))
     546              :                sgfb = first_sgfb(1, jset)
     547              : 
     548              :                ! calculate integrals
     549              :                ltab = MAX(npgfa(iset)*ncoset(la_max(iset) + 1), npgfb(jset)*ncoset(lb_max(jset) + 1))
     550              :                ALLOCATE (tkab(ltab, ltab))
     551              :                CALL kinetic(la_max(iset) + 1, la_min(iset), npgfa(iset), rpgfa(:, iset), zeta(:, iset), &
     552              :                             lb_max(jset) + 1, lb_min(jset), npgfb(jset), rpgfb(:, jset), zetb(:, jset), &
     553              :                             rab, tkab)
     554              :                ! Ordered products T*r and r*T
     555              :                DO i = 1, 2
     556              :                   CALL apply_cartesian_operator(la_max(iset), la_min(iset), npgfa(iset), &
     557              :                                                 lb_max(jset), lb_min(jset), npgfb(jset), tkab, kab, &
     558              :                                                 right=(i == 1), derivative=.FALSE., origin=MERGE(rbc, rac, i == 1))
     559              :                   DO ir = 1, 3
     560              :                      CALL contraction(kab(:, :, ir), qab, ca=scon_a(:, sgfa:), na=ncoa, ma=nsgfa(iset), &
     561              :                                       cb=scon_b(:, sgfb:), nb=ncob, mb=nsgfb(jset), trans=trans)
     562              : 
     563              : !$                   CALL omp_set_lock(locks(hash))
     564              :                      CALL block_add("IN", qab, nsgfa(iset), nsgfb(jset), blocks_tr(ir, i)%block, &
     565              :                                     sgfa, sgfb, trans=trans)
     566              : !$                   CALL omp_unset_lock(locks(hash))
     567              :                   END DO
     568              :                END DO
     569              :                DEALLOCATE (tkab)
     570              : 
     571              :             END DO
     572              :          END DO
     573              :       END DO !iterator
     574              :       DEALLOCATE (kab, qab)
     575              : !$OMP DO
     576              : !$    DO lock_num = 1, nlock
     577              : !$       call omp_destroy_lock(locks(lock_num))
     578              : !$    END DO
     579              : !$OMP END DO
     580              : 
     581              : !$OMP SINGLE
     582              : !$    DEALLOCATE (locks)
     583              : !$OMP END SINGLE NOWAIT
     584              : 
     585              : !$OMP END PARALLEL
     586              : 
     587              :       ! Release work storage
     588           38 :       DEALLOCATE (basis_set_list)
     589           38 :       CALL timestop(handle)
     590              : 
     591          152 :    END SUBROUTINE build_tr_matrices
     592              : 
     593              : ! **************************************************************************************************
     594              : !> \brief Build the ordered products V_core*r and r*V_core.
     595              : !> \param matrix_rcore_hr ...
     596              : !> \param matrix_rcore_rh ...
     597              : !> \param qs_env ...
     598              : !> \param qs_kind_set ...
     599              : !> \param basis_type ...
     600              : !> \param sab_nl ...
     601              : !> \param rf ...
     602              : !> \author Edward Ditler, Tomas Zimmermann
     603              : ! **************************************************************************************************
     604           38 :    SUBROUTINE build_rcore_matrices(matrix_rcore_hr, matrix_rcore_rh, qs_env, qs_kind_set, basis_type, sab_nl, rf)
     605              :       TYPE(dbcsr_p_type), DIMENSION(:)                   :: matrix_rcore_hr, matrix_rcore_rh
     606              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     607              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     608              :       CHARACTER(LEN=*)                                   :: basis_type
     609              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     610              :          POINTER                                         :: sab_nl
     611              :       REAL(KIND=dp), DIMENSION(3)                        :: rf
     612              : 
     613              :       CHARACTER(len=*), PARAMETER :: routineN = 'build_rcore_matrices'
     614              :       INTEGER, PARAMETER                                 :: nexp_max = 30
     615              : 
     616              :       INTEGER :: atom_a, atom_b, handle, i, iatom, icol, idir, ikind, inode, irow, iset, jatom, &
     617              :          jkind, jset, katom, kkind, ldai, ldsab, maxco, maxder, maxl, maxlgto, maxlppl, maxnset, &
     618              :          maxsgf, mepos, n_local, ncoa, ncob, nder, nexp_lpot, nexp_ppl, nimages, nkind, nloc, &
     619              :          nseta, nsetb, nthread, sgfa, sgfb
     620           38 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind
     621              :       INTEGER, DIMENSION(1:10)                           :: nrloc
     622              :       INTEGER, DIMENSION(3)                              :: cellind
     623           38 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, lb_max, lb_min, &
     624           38 :                                                             nct_lpot, npgfa, npgfb, nsgfa, nsgfb
     625           38 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, first_sgfb
     626              :       INTEGER, DIMENSION(nexp_max)                       :: nct_ppl
     627              :       LOGICAL                                            :: do_symmetric, do_upf, dokp, ecp_local, &
     628              :                                                             ecp_semi_local, found, lpotextended
     629              :       REAL(KIND=dp)                                      :: alpha, dab, dac, dbc, ppl_radius
     630           38 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: hab, qab
     631           38 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: ppl_work, rhab, work
     632              :       REAL(KIND=dp), DIMENSION(1:10)                     :: aloc, bloc
     633              :       REAL(KIND=dp), DIMENSION(3)                        :: ra, rab, rac, raf, rb, rbc
     634              :       REAL(KIND=dp), DIMENSION(4, nexp_max)              :: cval_ppl
     635           76 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: a_local, alpha_lpot, c_local, cexp_ppl, &
     636           38 :                                                             set_radius_a, set_radius_b
     637           38 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: cval_lpot, rpgfa, rpgfb, scon_a, scon_b, &
     638           38 :                                                             sphi_a, sphi_b, zeta, zetb
     639              :       REAL(KIND=dp), DIMENSION(nexp_max)                 :: alpha_ppl
     640           38 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     641          342 :       TYPE(block_p_type), DIMENSION(3, 2)                :: blocks_rcore
     642              :       TYPE(cell_type), POINTER                           :: cell
     643              :       TYPE(gth_potential_type), POINTER                  :: gth_potential
     644           38 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set_list
     645              :       TYPE(gto_basis_set_type), POINTER                  :: basis_set_a, basis_set_b
     646              :       TYPE(neighbor_list_iterator_p_type), &
     647           76 :          DIMENSION(:), POINTER                           :: ap_iterator, nl_iterator
     648              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     649           38 :          POINTER                                         :: sac_ppl
     650           38 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     651              :       TYPE(sgp_potential_type), POINTER                  :: sgp_potential
     652              : 
     653           38 :       CALL timeset(routineN, handle)
     654              : 
     655              :       CALL get_qs_env(qs_env=qs_env, &
     656              :                       atomic_kind_set=atomic_kind_set, &
     657              :                       qs_kind_set=qs_kind_set, &
     658              :                       particle_set=particle_set, &
     659              :                       sac_ppl=sac_ppl, &
     660           38 :                       cell=cell)
     661              : 
     662              :       ! check for symmetry
     663           38 :       CPASSERT(SIZE(sab_nl) > 0)
     664           38 :       CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
     665              : 
     666           38 :       nkind = SIZE(qs_kind_set)
     667              : 
     668              :       ! prepare basis set
     669          190 :       ALLOCATE (basis_set_list(nkind))
     670           38 :       CALL basis_set_list_setup(basis_set_list, basis_type, qs_kind_set)
     671              : 
     672           38 :       nder = 0
     673           38 :       nimages = 1
     674              : 
     675              :       alpha_ppl = 0
     676              :       nct_ppl = 0
     677              :       cval_ppl = 0
     678              : 
     679           38 :       nkind = SIZE(atomic_kind_set)
     680              : 
     681           38 :       dokp = (nimages > 1)
     682              : 
     683           38 :       CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, atom_of_kind=atom_of_kind)
     684              : 
     685           38 :       maxder = ncoset(nder)
     686              : 
     687              :       CALL get_qs_kind_set(qs_kind_set, maxco=maxco, maxlgto=maxlgto, &
     688              :                            maxsgf=maxsgf, maxnset=maxnset, maxlppl=maxlppl, &
     689           38 :                            basis_type=basis_type)
     690              : 
     691           38 :       maxl = MAX(maxlgto, maxlppl)
     692           38 :       CALL init_orbital_pointers(2*maxl + 2*nder + 2)
     693              : 
     694              :       !tz: maxco in maxco*ncoset(maxlgto+1) is an overkill,
     695              :       !    properly there should be maxpgf*ncoset(maxlgto+1), but maxpgf is difficult to get
     696           38 :       ldsab = MAX(maxco, ncoset(maxlppl), maxsgf, maxlppl, maxco*ncoset(maxlgto + 1))
     697           38 :       ldai = ncoset(2*maxlgto + 2)
     698              : 
     699          114 :       DO ikind = 1, nkind
     700              :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_set_a, basis_type=basis_type, &
     701           76 :                           sgp_potential=sgp_potential)
     702           76 :          IF (ASSOCIATED(sgp_potential)) THEN
     703            0 :             IF (ALLOCATED(sgp_potential%upf_data)) THEN
     704            0 :                IF (sgp_potential%upf_local%radial%degree < 2*maxlgto + 2) THEN
     705              :                   CALL upf_local_init(sgp_potential%upf_data, sgp_potential%alpha_core_charge, &
     706            0 :                                       2*maxlgto + 2, sgp_potential%upf_local)
     707              :                END IF
     708              :             END IF
     709              :          END IF
     710          114 :          IF (ASSOCIATED(basis_set_a)) THEN
     711           76 :             basis_set_list(ikind)%gto_basis_set => basis_set_a
     712              :          ELSE
     713            0 :             NULLIFY (basis_set_list(ikind)%gto_basis_set)
     714              :          END IF
     715              :       END DO
     716              : 
     717              :       nthread = 1
     718           38 : !$    nthread = omp_get_max_threads()
     719              : 
     720           38 :       CALL neighbor_list_iterator_create(nl_iterator, sab_nl, nthread=nthread)
     721              : 
     722              :       ! iterator for basis/potential list
     723           38 :       CALL neighbor_list_iterator_create(ap_iterator, sac_ppl, search=.TRUE., nthread=nthread)
     724              : 
     725              : !$OMP PARALLEL &
     726              : !$OMP DEFAULT (NONE) &
     727              : !$OMP SHARED  (nl_iterator, ap_iterator, basis_set_list, &
     728              : !$OMP          atomic_kind_set, qs_kind_set, particle_set, &
     729              : !$OMP          sab_nl, sac_ppl, nthread, ncoset, nkind, &
     730              : !$OMP          atom_of_kind, ldsab,  maxnset, maxder, &
     731              : !$OMP          maxlgto, nder, maxco, dokp, cell) &
     732              : !$OMP SHARED (matrix_rcore_hr, matrix_rcore_rh, rf) &
     733              : !$OMP PRIVATE (ikind, jkind, inode, iatom, jatom, rab, basis_set_a, basis_set_b, atom_a) &
     734              : !$OMP PRIVATE (atom_b) &
     735              : !$OMP PRIVATE (nsetb) &
     736              : !$OMP PRIVATE (dab, irow, icol, blocks_rcore, found, iset, ncoa, i) &
     737              : !$OMP PRIVATE (sgfa, jset, ncob, sgfb, work, hab, rhab, kkind, nseta) &
     738              : !$OMP PRIVATE (gth_potential, sgp_potential, alpha, cexp_ppl, lpotextended) &
     739              : !$OMP PRIVATE (ppl_radius, nexp_lpot, nexp_ppl, alpha_ppl, alpha_lpot, nct_ppl) &
     740              : !$OMP PRIVATE (ecp_semi_local, nct_lpot, cval_ppl, cval_lpot, rac, dac, rbc, dbc) &
     741              : !$OMP PRIVATE (mepos) &
     742              : !$OMP PRIVATE (katom, ppl_work, cellind, ecp_local) &
     743              : !$OMP PRIVATE (first_sgfa, la_max, la_min, npgfa, nsgfa, rpgfa, set_radius_a, sphi_a, zeta, scon_a) &
     744              : !$OMP PRIVATE (first_sgfb, lb_max, lb_min, npgfb, nsgfb, rpgfb, set_radius_b, sphi_b, zetb, scon_b) &
     745              : !$OMP PRIVATE (nloc, nrloc, aloc, bloc, n_local, a_local, c_local, ldai) &
     746           38 : !$OMP PRIVATE (ra, rb, qab, raf, do_upf)
     747              : 
     748              :       mepos = 0
     749              : !$    mepos = omp_get_thread_num()
     750              : 
     751              :       ALLOCATE (hab(ldsab, ldsab), rhab(ldsab, ldsab, 3), work(ldsab, ldsab*(nder + 1), 3))
     752              :       ALLOCATE (qab(ldsab, ldsab))
     753              : 
     754              :       ldai = ncoset(2*maxlgto + 2)
     755              :       ALLOCATE (ppl_work(ldai, ldai, MAX(maxder, 2*maxlgto + 2 + 1)))
     756              : 
     757              :       DO WHILE (neighbor_list_iterate(nl_iterator, mepos=mepos) == 0)
     758              : 
     759              :          CALL get_iterator_info(nl_iterator, mepos=mepos, ikind=ikind, jkind=jkind, inode=inode, &
     760              :                                 iatom=iatom, jatom=jatom, r=rab, cell=cellind)
     761              : 
     762              :          basis_set_a => basis_set_list(ikind)%gto_basis_set
     763              :          IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
     764              :          basis_set_b => basis_set_list(jkind)%gto_basis_set
     765              :          IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
     766              : 
     767              :          atom_a = atom_of_kind(iatom)
     768              :          atom_b = atom_of_kind(jatom)
     769              : 
     770              :          ! basis ikind
     771              :          first_sgfa => basis_set_a%first_sgf
     772              :          la_max => basis_set_a%lmax
     773              :          la_min => basis_set_a%lmin
     774              :          npgfa => basis_set_a%npgf
     775              :          nsgfa => basis_set_a%nsgf_set
     776              :          rpgfa => basis_set_a%pgf_radius
     777              :          set_radius_a => basis_set_a%set_radius
     778              :          sphi_a => basis_set_a%sphi
     779              :          zeta => basis_set_a%zet
     780              :          scon_a => basis_set_a%scon
     781              :          ! basis jkind
     782              :          first_sgfb => basis_set_b%first_sgf
     783              :          lb_max => basis_set_b%lmax
     784              :          lb_min => basis_set_b%lmin
     785              :          npgfb => basis_set_b%npgf
     786              :          nsgfb => basis_set_b%nsgf_set
     787              :          rpgfb => basis_set_b%pgf_radius
     788              :          set_radius_b => basis_set_b%set_radius
     789              :          sphi_b => basis_set_b%sphi
     790              :          zetb => basis_set_b%zet
     791              :          scon_b => basis_set_b%scon
     792              : 
     793              :          nseta = basis_set_a%nset
     794              :          nsetb = basis_set_b%nset
     795              : 
     796              :          ! *** Create matrix blocks for a new matrix block column ***
     797              :          irow = iatom
     798              :          icol = jatom
     799              : 
     800              :          DO idir = 1, 3
     801              :             NULLIFY (blocks_rcore(idir, 1)%block)
     802              :             CALL dbcsr_get_block_p(matrix=matrix_rcore_hr(idir)%matrix, &
     803              :                                    row=irow, col=icol, BLOCK=blocks_rcore(idir, 1)%block, found=found)
     804              :             CPASSERT(found)
     805              :             NULLIFY (blocks_rcore(idir, 2)%block)
     806              :             CALL dbcsr_get_block_p(matrix=matrix_rcore_rh(idir)%matrix, &
     807              :                                    row=irow, col=icol, BLOCK=blocks_rcore(idir, 2)%block, found=found)
     808              :             CPASSERT(found)
     809              :          END DO
     810              : 
     811              :          dab = NORM2(rab)
     812              :          ra = pbc(particle_set(iatom)%r(:), cell)
     813              :          rb(:) = ra(:) + rab(:)
     814              : 
     815              :          raf = pbc(rf, ra, cell)
     816              : 
     817              :          ! loop over all kinds for pseudopotential atoms
     818              :          DO kkind = 1, nkind
     819              :             CALL get_qs_kind(qs_kind_set(kkind), gth_potential=gth_potential, &
     820              :                              sgp_potential=sgp_potential)
     821              :             do_upf = .FALSE.
     822              :             IF (ASSOCIATED(gth_potential)) THEN
     823              :                CALL get_potential(potential=gth_potential, &
     824              :                                   alpha_ppl=alpha, cexp_ppl=cexp_ppl, &
     825              :                                   lpot_present=lpotextended, ppl_radius=ppl_radius)
     826              :                nexp_ppl = 1
     827              :                alpha_ppl(1) = alpha
     828              :                nct_ppl(1) = SIZE(cexp_ppl)
     829              :                cval_ppl(1:nct_ppl(1), 1) = cexp_ppl(1:nct_ppl(1))
     830              :                IF (lpotextended) THEN
     831              :                   CALL get_potential(potential=gth_potential, &
     832              :                                      nexp_lpot=nexp_lpot, alpha_lpot=alpha_lpot, nct_lpot=nct_lpot, cval_lpot=cval_lpot)
     833              :                   CPASSERT(nexp_lpot < nexp_max)
     834              :                   nexp_ppl = nexp_lpot + 1
     835              :                   alpha_ppl(2:nexp_lpot + 1) = alpha_lpot(1:nexp_lpot)
     836              :                   nct_ppl(2:nexp_lpot + 1) = nct_lpot(1:nexp_lpot)
     837              :                   DO i = 1, nexp_lpot
     838              :                      cval_ppl(1:nct_lpot(i), i + 1) = cval_lpot(1:nct_lpot(i), i)
     839              :                   END DO
     840              :                END IF
     841              :             ELSE IF (ASSOCIATED(sgp_potential)) THEN
     842              :                CALL get_potential(potential=sgp_potential, ecp_local=ecp_local, ecp_semi_local=ecp_semi_local, &
     843              :                                   ppl_radius=ppl_radius)
     844              :                do_upf = ALLOCATED(sgp_potential%upf_data)
     845              :                IF (do_upf) THEN
     846              :                   CPASSERT(.NOT. ecp_local .AND. .NOT. ecp_semi_local)
     847              :                ELSE IF (ecp_local) THEN
     848              :                   CALL get_potential(potential=sgp_potential, nloc=nloc, nrloc=nrloc, aloc=aloc, bloc=bloc)
     849              :                   IF (SUM(ABS(aloc(1:nloc))) < 1.0e-12_dp) CYCLE
     850              :                   nexp_ppl = nloc
     851              :                   CPASSERT(nexp_ppl <= nexp_max)
     852              :                   nct_ppl(1:nloc) = nrloc(1:nloc) - 1
     853              :                   alpha_ppl(1:nloc) = bloc(1:nloc)
     854              :                   cval_ppl(1, 1:nloc) = aloc(1:nloc)
     855              :                ELSE
     856              :                   CALL get_potential(potential=sgp_potential, n_local=n_local, a_local=a_local, c_local=c_local)
     857              :                   nexp_ppl = n_local
     858              :                   CPASSERT(nexp_ppl <= nexp_max)
     859              :                   nct_ppl(1:n_local) = 1
     860              :                   alpha_ppl(1:n_local) = a_local(1:n_local)
     861              :                   cval_ppl(1, 1:n_local) = c_local(1:n_local)
     862              :                END IF
     863              :                IF (ecp_semi_local) THEN
     864              :                   CPABORT("VCD with semi-local ECPs not implemented")
     865              :                END IF
     866              :             ELSE
     867              :                CYCLE
     868              :             END IF
     869              : 
     870              :             CALL nl_set_sub_iterator(ap_iterator, ikind, kkind, iatom, mepos=mepos)
     871              : 
     872              :             DO WHILE (nl_sub_iterate(ap_iterator, mepos=mepos) == 0)
     873              : 
     874              :                CALL get_iterator_info(ap_iterator, mepos=mepos, jatom=katom, r=rac)
     875              :                dac = SQRT(SUM(rac*rac))
     876              :                rbc(:) = rac(:) - rab(:)
     877              :                dbc = SQRT(SUM(rbc*rbc))
     878              :                IF ((MAXVAL(set_radius_a(:)) + ppl_radius < dac) .OR. &
     879              :                    (MAXVAL(set_radius_b(:)) + ppl_radius < dbc)) THEN
     880              :                   CYCLE
     881              :                END IF
     882              :                DO iset = 1, nseta
     883              :                   IF (set_radius_a(iset) + ppl_radius < dac) CYCLE
     884              :                   ncoa = npgfa(iset)*ncoset(la_max(iset))
     885              :                   !                  ncoa = npgfa(iset)*(ncoset(la_max(iset))-ncoset(la_min(iset)-1))
     886              :                   sgfa = first_sgfa(1, iset)
     887              :                   DO jset = 1, nsetb
     888              :                      IF (set_radius_b(jset) + ppl_radius < dbc) CYCLE
     889              :                      ncob = npgfb(jset)*ncoset(lb_max(jset))
     890              :                      !                     ncob = npgfb(jset)*(ncoset(lb_max(jset))-ncoset(lb_min(jset)-1))
     891              :                      sgfb = first_sgfb(1, jset)
     892              :                      IF (set_radius_a(iset) + set_radius_b(jset) < dab) CYCLE
     893              :                      ! *** Calculate the GTH pseudo potential forces ***
     894              :                      hab = 0
     895              :                      rhab = 0
     896              :                      ppl_work = 0
     897              :                      work = 0
     898              : 
     899              :                      IF (do_upf) THEN
     900              :                         CALL upf_local_matrix(sgp_potential%upf_local, &
     901              :                                               la_max(iset) + 1, zeta(:npgfa(iset), iset), &
     902              :                                               lb_max(jset) + 1, zetb(:npgfb(jset), jset), rab, rac, &
     903              :                                               hab(:npgfa(iset)*ncoset(la_max(iset) + 1), :npgfb(jset)*ncoset(lb_max(jset) + 1)))
     904              :                      ELSE
     905              :                         CALL ppl_integral( &
     906              :                            la_max(iset) + 1, la_min(iset), npgfa(iset), &
     907              :                            rpgfa(:, iset), zeta(:, iset), &
     908              :                            lb_max(jset) + 1, lb_min(jset), npgfb(jset), &
     909              :                            rpgfb(:, jset), zetb(:, jset), &
     910              :                            nexp_ppl, alpha_ppl, nct_ppl, cval_ppl, ppl_radius, &
     911              :                            rab, dab, rac, dac, rbc, dbc, hab(:, :), ppl_work)
     912              :                      END IF
     913              : 
     914              :                      ! product with r
     915              :                      CALL apply_cartesian_operator(la_max(iset), 0, npgfa(iset), lb_max(jset), 0, npgfb(jset), &
     916              :                                                    hab, rhab, right=.FALSE., derivative=.FALSE., origin=raf)
     917              : 
     918              :                      DO idir = 1, 3
     919              :                         CALL dgemm("N", "N", ncoa, nsgfb(jset), ncob, &
     920              :                                    1.0_dp, rhab(1, 1, idir), SIZE(rhab, 1), &
     921              :                                    sphi_b(1, sgfb), SIZE(sphi_b, 1), &
     922              :                                    0.0_dp, work(1, 1, idir), SIZE(work, 1))
     923              : !$OMP CRITICAL(h_block_critical)
     924              :                         DO i = 1, 2
     925              :                            CALL dgemm("T", "N", nsgfa(iset), nsgfb(jset), ncoa, &
     926              :                                       1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
     927              :                                       work(1, 1, idir), SIZE(work, 1), &
     928              :                                       1.0_dp, blocks_rcore(idir, i)%block(sgfa, sgfb), &
     929              :                                       SIZE(blocks_rcore(idir, i)%block, 1))
     930              :                         END DO
     931              : !$OMP END CRITICAL(h_block_critical)
     932              :                      END DO
     933              :                   END DO
     934              :                END DO
     935              :             END DO
     936              :          END DO
     937              :       END DO ! iterator
     938              : 
     939              :       DEALLOCATE (hab, rhab, work, ppl_work)
     940              : 
     941              : !$OMP END PARALLEL
     942              : 
     943           38 :       CALL neighbor_list_iterator_release(ap_iterator)
     944           38 :       CALL neighbor_list_iterator_release(nl_iterator)
     945              : 
     946           38 :       DEALLOCATE (atom_of_kind, basis_set_list)
     947              : 
     948           38 :       CALL timestop(handle)
     949              : 
     950          190 :    END SUBROUTINE build_rcore_matrices
     951              : 
     952              : ! **************************************************************************************************
     953              : !> \brief Build the ordered Hartree+XC products V_HXC*r and r*V_HXC.
     954              : !> \param matrix_hr ...
     955              : !> \param matrix_rh ...
     956              : !> \param qs_env ...
     957              : !> \param rc ...
     958              : !> \author Edward Ditler, Tomas Zimmermann
     959              : ! **************************************************************************************************
     960           38 :    SUBROUTINE build_vhxc_matrices(matrix_hr, matrix_rh, qs_env, rc)
     961              :       TYPE(dbcsr_p_type), DIMENSION(:, :), &
     962              :          INTENT(INOUT), POINTER                          :: matrix_hr, matrix_rh
     963              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     964              :       REAL(KIND=dp), DIMENSION(3)                        :: rc
     965              : 
     966              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'build_vhxc_matrices'
     967              :       INTEGER, PARAMETER                                 :: nspins = 1
     968              : 
     969              :       INTEGER                                            :: handle, idir, ispin
     970              :       REAL(kind=dp)                                      :: edisp
     971           38 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks
     972           38 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_rvxc, matrix_rvxc_desymm
     973              :       TYPE(pw_env_type), POINTER                         :: pw_env
     974              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     975           38 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: v_rspace, v_tau_rspace
     976              :       TYPE(pw_r3d_rs_type), POINTER                      :: v_hartree_rspace
     977              :       TYPE(qs_energy_type), POINTER                      :: energy
     978              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     979              :       TYPE(qs_rho_type), POINTER                         :: rho_struct
     980              :       TYPE(section_vals_type), POINTER                   :: input, xc_section
     981              : 
     982           38 :       CALL timeset(routineN, handle)
     983              : 
     984              :       CALL get_qs_env(qs_env, matrix_ks=matrix_ks, &
     985              :                       ks_env=ks_env, &
     986              :                       pw_env=pw_env, &
     987              :                       input=input, &
     988              :                       v_hartree_rspace=v_hartree_rspace, &
     989           38 :                       energy=energy)
     990              : 
     991           38 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     992              : 
     993           38 :       NULLIFY (matrix_rvxc, matrix_rvxc_desymm)
     994           38 :       CALL dbcsr_allocate_matrix_set(matrix_rvxc, nspins, 3)
     995           38 :       CALL dbcsr_allocate_matrix_set(matrix_rvxc_desymm, nspins, 3)
     996              : 
     997           76 :       DO ispin = 1, nspins
     998          190 :          DO idir = 1, 3
     999          114 :             CALL dbcsr_init_p(matrix_rvxc(ispin, idir)%matrix)
    1000          114 :             CALL dbcsr_init_p(matrix_rvxc_desymm(ispin, idir)%matrix)
    1001              : 
    1002          114 :             CALL dbcsr_copy(matrix_rvxc_desymm(ispin, idir)%matrix, matrix_hr(1, 1)%matrix)
    1003          114 :             CALL dbcsr_set(matrix_rvxc_desymm(ispin, idir)%matrix, 0._dp)
    1004              : 
    1005          114 :             CALL dbcsr_copy(matrix_rvxc(ispin, idir)%matrix, matrix_ks(ispin)%matrix)
    1006          152 :             CALL dbcsr_set(matrix_rvxc(ispin, idir)%matrix, 0.0_dp)
    1007              :          END DO
    1008              :       END DO
    1009              : 
    1010           38 :       xc_section => section_vals_get_subs_vals(input, "DFT%XC")
    1011           38 :       CALL get_qs_env(qs_env=qs_env, rho=rho_struct)
    1012              : 
    1013           38 :       NULLIFY (v_rspace)
    1014           38 :       NULLIFY (v_tau_rspace)
    1015              :       CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho_struct, xc_section=xc_section, &
    1016              :                          vxc_rho=v_rspace, vxc_tau=v_tau_rspace, exc=energy%exc, &
    1017              :                          edisp=edisp, dispersion_env=qs_env%dispersion_env, &
    1018           38 :                          just_energy=.FALSE.)
    1019              : 
    1020           38 :       IF (.NOT. ASSOCIATED(v_rspace)) THEN
    1021            0 :          ALLOCATE (v_rspace(nspins))
    1022            0 :          DO ispin = 1, nspins
    1023            0 :             CALL auxbas_pw_pool%create_pw(v_rspace(ispin))
    1024            0 :             CALL pw_zero(v_rspace(ispin))
    1025              :          END DO
    1026              :       END IF
    1027              : 
    1028           76 :       DO ispin = 1, nspins
    1029           38 :          CALL pw_axpy(v_hartree_rspace, v_rspace(ispin), 1.0_dp/v_hartree_rspace%pw_grid%dvol)
    1030              :          CALL integrate_rv_rspace(v_rspace=v_rspace(ispin), hmat=matrix_rvxc(ispin, :), qs_env=qs_env, &
    1031           38 :                                   rc=rc)
    1032              : 
    1033          190 :          DO idir = 1, 3
    1034          114 :             CALL dbcsr_scale(matrix_rvxc(ispin, idir)%matrix, v_rspace(ispin)%pw_grid%dvol)
    1035          114 :             CALL dbcsr_desymmetrize(matrix_rvxc(ispin, idir)%matrix, matrix_rvxc_desymm(ispin, idir)%matrix)
    1036          114 :             CALL dbcsr_add(matrix_hr(ispin, idir)%matrix, matrix_rvxc_desymm(ispin, idir)%matrix, 1.0_dp, 1.0_dp)
    1037          152 :             CALL dbcsr_add(matrix_rh(ispin, idir)%matrix, matrix_rvxc_desymm(ispin, idir)%matrix, 1.0_dp, 1.0_dp)
    1038              :          END DO
    1039              :       END DO
    1040              : 
    1041              :       ! return pw grids
    1042           76 :       DO ispin = 1, nspins
    1043           76 :          CALL auxbas_pw_pool%give_back_pw(v_rspace(ispin))
    1044              :       END DO
    1045           38 :       DEALLOCATE (v_rspace)
    1046              : 
    1047           38 :       CALL dbcsr_deallocate_matrix_set(matrix_rvxc)
    1048           38 :       CALL dbcsr_deallocate_matrix_set(matrix_rvxc_desymm)
    1049              : 
    1050           38 :       CALL timestop(handle)
    1051              : 
    1052           38 :    END SUBROUTINE build_vhxc_matrices
    1053              : 
    1054              : ! **************************************************************************************************
    1055              : !> \brief Calculates the integrals < mu | r * V | nu >
    1056              : !>        There is no direction_Or argument, because the potentials commute with r
    1057              : !>        This routine uses integrate_pgf_product directly. It could probably be rewritten to use
    1058              : !>          the new task_list interface.
    1059              : !> \param v_rspace ...
    1060              : !> \param hmat ...
    1061              : !> \param qs_env ...
    1062              : !> \param rc ...
    1063              : !> \author Edward Ditler
    1064              : ! **************************************************************************************************
    1065           38 :    SUBROUTINE integrate_rv_rspace(v_rspace, hmat, qs_env, rc)
    1066              : 
    1067              :       TYPE(pw_r3d_rs_type)                               :: v_rspace
    1068              :       TYPE(dbcsr_p_type), DIMENSION(:), INTENT(INOUT)    :: hmat
    1069              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1070              :       REAL(KIND=dp), DIMENSION(3)                        :: rc
    1071              : 
    1072              :       CHARACTER(len=*), PARAMETER :: routineN = 'integrate_rv_rspace'
    1073              : 
    1074              :       CHARACTER(len=default_string_length)               :: my_basis_type
    1075              :       INTEGER :: bcol, brow, handle, iatom, idir, igrid_level, ikind, ikind_old, ilevel, img, &
    1076              :          ipair, ipgf, ipgf_new, iset, iset_new, iset_old, itask, ithread, jatom, jkind, jkind_old, &
    1077              :          jpgf, jpgf_new, jset, jset_new, jset_old, ldsab, maxco, maxlgto, maxpgf, maxset, &
    1078              :          maxsgf_set, na1, na2, natom, nb1, nb2, ncoa, ncoa_full, ncob, ncob_full, nkind, nseta, &
    1079              :          nsetb, nthread, sgfa, sgfb
    1080           38 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, lb_max, lb_min, npgfa, &
    1081           38 :                                                             npgfb, nsgfa, nsgfb
    1082           38 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, first_sgfb
    1083              :       LOGICAL :: atom_pair_changed, atom_pair_done, distributed_grids, found, has_threads, &
    1084              :          my_compute_tau, my_gapw, new_set_pair_coming
    1085              :       REAL(KIND=dp)                                      :: eps_rho_rspace, f, prefactor, radius, &
    1086              :                                                             zetp
    1087              :       REAL(KIND=dp), DIMENSION(3)                        :: ra, rab, rab_inv, rac, rb, rbc, rp
    1088           38 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: set_radius_a, set_radius_b
    1089           38 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: hab, sphi_a, sphi_b, work, zeta, zetb
    1090           38 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: habt, rhab, workt
    1091           38 :       TYPE(atom_pair_type), DIMENSION(:), POINTER        :: atom_pair_recv, atom_pair_send
    1092           38 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1093           38 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:)      :: h_block
    1094              :       TYPE(cell_type), POINTER                           :: cell
    1095              :       TYPE(dbcsr_distribution_type)                      :: dist
    1096              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1097              :       TYPE(gridlevel_info_type), POINTER                 :: gridlevel_info
    1098              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    1099              :       TYPE(mp_comm_type)                                 :: group
    1100           38 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1101              :       TYPE(pw_env_type), POINTER                         :: pw_env
    1102           38 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1103           38 :       TYPE(realspace_grid_type), DIMENSION(:), POINTER   :: rs_v
    1104              :       TYPE(task_list_type), POINTER                      :: task_list, task_list_soft
    1105           38 :       TYPE(task_type), DIMENSION(:), POINTER             :: tasks
    1106              :       TYPE(virial_type), POINTER                         :: virial
    1107              : 
    1108           38 :       CALL timeset(routineN, handle)
    1109              : 
    1110           38 :       my_compute_tau = .FALSE.
    1111           38 :       my_gapw = .FALSE.
    1112           38 :       my_basis_type = "ORB"
    1113              : 
    1114              :       ! get the task lists
    1115              :       CALL get_qs_env(qs_env=qs_env, &
    1116              :                       task_list=task_list, &
    1117           38 :                       task_list_soft=task_list_soft)
    1118           38 :       CPASSERT(ASSOCIATED(task_list))
    1119              : 
    1120              :       ! the information on the grids is provided through pw_env
    1121              :       ! pw_env has to be the parent env for the potential grid (input)
    1122              :       ! there is an option to provide an external grid
    1123           38 :       CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
    1124           38 :       CPASSERT(ASSOCIATED(pw_env))
    1125              : 
    1126              :       ! get all the general information on the system we are working on
    1127              :       CALL get_qs_env(qs_env=qs_env, &
    1128              :                       atomic_kind_set=atomic_kind_set, &
    1129              :                       qs_kind_set=qs_kind_set, &
    1130              :                       cell=cell, &
    1131              :                       dft_control=dft_control, &
    1132              :                       particle_set=particle_set, &
    1133              :                       virial=virial, &
    1134           38 :                       natom=natom)
    1135              : 
    1136           38 :       rab = 0._dp
    1137           38 :       rac = 0._dp
    1138              :       rbc = 0._dp
    1139              : 
    1140              :       ! short cuts to task list variables
    1141           38 :       tasks => task_list%tasks
    1142           38 :       atom_pair_send => task_list%atom_pair_send
    1143           38 :       atom_pair_recv => task_list%atom_pair_recv
    1144              : 
    1145           38 :       CPASSERT(ASSOCIATED(pw_env))
    1146           38 :       CALL pw_env_get(pw_env, rs_grids=rs_v)
    1147              : 
    1148              :       ! get mpi group from rs_v
    1149           38 :       group = rs_v(1)%desc%group
    1150              : 
    1151              :       ! assign from pw_env
    1152           38 :       gridlevel_info => pw_env%gridlevel_info
    1153              : 
    1154              :       ! transform the potential on the rs_multigrids
    1155           38 :       CALL potential_pw2rs(rs_v, v_rspace, pw_env)
    1156              : 
    1157           38 :       nkind = SIZE(qs_kind_set)
    1158              : 
    1159              :       ! needs to be consistent with rho_rspace
    1160           38 :       eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
    1161              : 
    1162              :       CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
    1163              :                            maxco=maxco, &
    1164              :                            maxlgto=maxlgto, &
    1165              :                            maxsgf_set=maxsgf_set, &
    1166           38 :                            basis_type=my_basis_type)
    1167              : 
    1168           38 :       distributed_grids = .FALSE.
    1169          190 :       DO igrid_level = 1, gridlevel_info%ngrid_levels
    1170           38 :          IF (rs_v(igrid_level)%desc%distributed) THEN
    1171          152 :             distributed_grids = .TRUE.
    1172              :          END IF
    1173              :       END DO
    1174              : 
    1175              :       nthread = 1
    1176           38 : !$    nthread = omp_get_max_threads()
    1177              : 
    1178              :       ! get maximum numbers
    1179           38 :       maxset = 0
    1180           38 :       maxpgf = 0
    1181          114 :       DO ikind = 1, nkind
    1182              :          CALL get_qs_kind(qs_kind_set(ikind), &
    1183           76 :                           basis_set=orb_basis_set, basis_type=my_basis_type)
    1184              : 
    1185           76 :          IF (.NOT. ASSOCIATED(orb_basis_set)) CYCLE
    1186              : 
    1187              :          CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    1188           76 :                                 npgf=npgfa, nset=nseta)
    1189              : 
    1190           76 :          maxset = MAX(nseta, maxset)
    1191          190 :          maxpgf = MAX(MAXVAL(npgfa), maxpgf)
    1192              :       END DO
    1193              : 
    1194           38 :       ldsab = MAX(maxco, maxsgf_set, maxpgf*ncoset(maxlgto + 1))
    1195              : 
    1196              :       !   *** Allocate work storage ***
    1197           38 :       NULLIFY (habt, workt)
    1198           38 :       CALL reallocate(habt, 1, ldsab, 1, ldsab, 0, nthread)
    1199           38 :       CALL reallocate(workt, 1, ldsab, 1, maxsgf_set, 0, nthread)
    1200          190 :       ALLOCATE (rhab(ldsab, ldsab, 3))
    1201              : 
    1202          152 :       ALLOCATE (h_block(3))
    1203              : 
    1204           38 :       ithread = 0
    1205           38 : !$    ithread = omp_get_thread_num()
    1206           38 :       work => workt(:, :, ithread)
    1207           38 :       hab => habt(:, :, ithread)
    1208        62358 :       hab(:, :) = 0._dp
    1209              : 
    1210           38 :       iset_old = -1; jset_old = -1
    1211           38 :       ikind_old = -1; jkind_old = -1
    1212              : 
    1213              :       ! Here we loop over gridlevels first, finalising the matrix after each grid level is
    1214              :       ! completed.  On each grid level, we loop over atom pairs, which will only access
    1215              :       ! a single block of each matrix, so with OpenMP, each matrix block is only touched
    1216              :       ! by a single thread for each grid level
    1217          190 :       loop_gridlevels: DO igrid_level = 1, gridlevel_info%ngrid_levels
    1218          608 :          DO idir = 1, 3
    1219          456 :             CALL dbcsr_work_create(hmat(idir)%matrix, work_mutable=.TRUE., n=nthread)
    1220          456 :             CALL dbcsr_get_info(hmat(idir)%matrix, distribution=dist)
    1221          456 :             CALL dbcsr_distribution_get(dist, has_threads=has_threads)
    1222          456 : !$          IF (.NOT. has_threads) &
    1223          608 : !$             CPABORT("No thread distribution defined.")
    1224              :          END DO
    1225              : 
    1226          494 :          loop_pairs: DO ipair = 1, task_list%npairs(igrid_level)
    1227         2299 :          loop_tasks: DO itask = task_list%taskstart(ipair, igrid_level), task_list%taskstop(ipair, igrid_level)
    1228         1805 :             ilevel = tasks(itask)%grid_level
    1229         1805 :             img = tasks(itask)%image
    1230         1805 :             iatom = tasks(itask)%iatom
    1231         1805 :             jatom = tasks(itask)%jatom
    1232         1805 :             iset = tasks(itask)%iset
    1233         1805 :             jset = tasks(itask)%jset
    1234         1805 :             ipgf = tasks(itask)%ipgf
    1235         1805 :             jpgf = tasks(itask)%jpgf
    1236         1805 :             CPASSERT(img == 1)
    1237              : 
    1238              :             ! At the start of a block of tasks, get atom data (and kind data, if needed)
    1239         1805 :             IF (itask == task_list%taskstart(ipair, igrid_level)) THEN
    1240              : 
    1241          342 :                ikind = particle_set(iatom)%atomic_kind%kind_number
    1242          342 :                jkind = particle_set(jatom)%atomic_kind%kind_number
    1243              : 
    1244          342 :                IF (iatom <= jatom) THEN
    1245          228 :                   brow = iatom
    1246          228 :                   bcol = jatom
    1247              :                ELSE
    1248          114 :                   brow = jatom
    1249          114 :                   bcol = iatom
    1250              :                END IF
    1251              : 
    1252          342 :                IF (ikind /= ikind_old) THEN
    1253              :                   CALL get_qs_kind(qs_kind_set(ikind), &
    1254           38 :                                    basis_set=orb_basis_set, basis_type=my_basis_type)
    1255              : 
    1256              :                   CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    1257              :                                          first_sgf=first_sgfa, &
    1258              :                                          lmax=la_max, &
    1259              :                                          lmin=la_min, &
    1260              :                                          npgf=npgfa, &
    1261              :                                          nset=nseta, &
    1262              :                                          nsgf_set=nsgfa, &
    1263              :                                          set_radius=set_radius_a, &
    1264              :                                          sphi=sphi_a, &
    1265           38 :                                          zet=zeta)
    1266              :                END IF
    1267              : 
    1268          342 :                IF (jkind /= jkind_old) THEN
    1269              :                   CALL get_qs_kind(qs_kind_set(jkind), &
    1270          228 :                                    basis_set=orb_basis_set, basis_type=my_basis_type)
    1271              :                   CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
    1272              :                                          first_sgf=first_sgfb, &
    1273              :                                          lmax=lb_max, &
    1274              :                                          lmin=lb_min, &
    1275              :                                          npgf=npgfb, &
    1276              :                                          nset=nsetb, &
    1277              :                                          nsgf_set=nsgfb, &
    1278              :                                          set_radius=set_radius_b, &
    1279              :                                          sphi=sphi_b, &
    1280          228 :                                          zet=zetb)
    1281              : 
    1282              :                END IF
    1283              : 
    1284         1368 :                DO idir = 1, 3
    1285         1026 :                   NULLIFY (h_block(idir)%block)
    1286         1026 :                   CALL dbcsr_get_block_p(hmat(idir)%matrix, brow, bcol, h_block(idir)%block, found)
    1287         1368 :                   CPASSERT(found)
    1288              :                END DO
    1289              : 
    1290              :                ikind_old = ikind
    1291              :                jkind_old = jkind
    1292              : 
    1293              :                atom_pair_changed = .TRUE.
    1294              : 
    1295              :             ELSE
    1296              : 
    1297              :                atom_pair_changed = .FALSE.
    1298              : 
    1299              :             END IF
    1300              : 
    1301         1805 :             IF (atom_pair_changed .OR. iset_old /= iset .OR. jset_old /= jset) THEN
    1302              :                ! We reuse the hab(:, :) array to put the new integrals in.
    1303              : 
    1304          342 :                ncoa = npgfa(iset)*ncoset(la_max(iset))
    1305          342 :                ncoa_full = npgfa(iset)*ncoset(la_max(iset) + 1)
    1306          342 :                sgfa = first_sgfa(1, iset)
    1307          342 :                ncob = npgfb(jset)*ncoset(lb_max(jset))
    1308          342 :                ncob_full = npgfb(jset)*ncoset(lb_max(jset) + 1)
    1309          342 :                sgfb = first_sgfb(1, jset)
    1310              : 
    1311          342 :                IF (iatom <= jatom) THEN
    1312       162108 :                   hab(1:ncoa_full, 1:ncob_full) = 0._dp
    1313              :                ELSE
    1314        53010 :                   hab(1:ncob_full, 1:ncoa_full) = 0._dp
    1315              :                END IF
    1316              : 
    1317              :                iset_old = iset
    1318              :                jset_old = jset
    1319              : 
    1320              :             END IF
    1321              : 
    1322         7220 :             rab = tasks(itask)%rab
    1323              :             ! With and without MIC, rab(:) is the vector giving us the coordinates of rb.
    1324         1805 :             ra = pbc(particle_set(iatom)%r(:), cell)
    1325         7220 :             rb(:) = ra(:) + rab(:)
    1326         1805 :             rac = pbc(rc, ra, cell)
    1327         7220 :             rbc = rac + rab
    1328              : 
    1329         1805 :             zetp = zeta(ipgf, iset) + zetb(jpgf, jset)
    1330         1805 :             f = zetb(jpgf, jset)/zetp
    1331         7220 :             rp(:) = ra(:) + f*rab(:)
    1332              : 
    1333         7220 :             prefactor = EXP(-zeta(ipgf, iset)*f*DOT_PRODUCT(rab, rab))
    1334              :             radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
    1335              :                                               lb_min=lb_min(jset), lb_max=lb_max(jset), &
    1336              :                                               ra=ra, rb=rb, rp=rp, &
    1337              :                                               zetp=zetp, eps=eps_rho_rspace, &
    1338         1805 :                                               prefactor=prefactor, cutoff=1.0_dp)
    1339              : 
    1340         1805 :             na1 = (ipgf - 1)*ncoset(la_max(iset) + 1) + 1
    1341         1805 :             na2 = ipgf*ncoset(la_max(iset) + 1)
    1342         1805 :             nb1 = (jpgf - 1)*ncoset(lb_max(jset) + 1) + 1
    1343         1805 :             nb2 = jpgf*ncoset(lb_max(jset) + 1)
    1344              : 
    1345         1805 :             IF (iatom <= jatom) THEN
    1346              :                CALL integrate_pgf_product( &
    1347              :                   la_max(iset) + 1, zeta(ipgf, iset), la_min(iset), &
    1348              :                   lb_max(jset) + 1, zetb(jpgf, jset), lb_min(jset), &
    1349              :                   ra, rab, rs_v(igrid_level), &
    1350              :                   hab, o1=na1 - 1, o2=nb1 - 1, &
    1351              :                   radius=radius, &
    1352         1216 :                   calculate_forces=.FALSE.)
    1353              :             ELSE
    1354         2356 :                rab_inv = -rab
    1355              :                CALL integrate_pgf_product( &
    1356              :                   lb_max(jset) + 1, zetb(jpgf, jset), lb_min(jset), &
    1357              :                   la_max(iset) + 1, zeta(ipgf, iset), la_min(iset), &
    1358              :                   rb, rab_inv, rs_v(igrid_level), &
    1359              :                   hab, o1=nb1 - 1, o2=na1 - 1, &
    1360              :                   radius=radius, &
    1361          589 :                   calculate_forces=.FALSE.)
    1362              :             END IF
    1363              : 
    1364         1805 :             new_set_pair_coming = .FALSE.
    1365         1805 :             atom_pair_done = .FALSE.
    1366         1805 :             IF (itask < task_list%taskstop(ipair, igrid_level)) THEN
    1367         1463 :                ilevel = tasks(itask + 1)%grid_level
    1368         1463 :                img = tasks(itask + 1)%image
    1369         1463 :                iatom = tasks(itask + 1)%iatom
    1370         1463 :                jatom = tasks(itask + 1)%jatom
    1371         1463 :                iset_new = tasks(itask + 1)%iset
    1372         1463 :                jset_new = tasks(itask + 1)%jset
    1373         1463 :                ipgf_new = tasks(itask + 1)%ipgf
    1374         1463 :                jpgf_new = tasks(itask + 1)%jpgf
    1375         1463 :                IF (iset_new /= iset .OR. jset_new /= jset) THEN
    1376              :                   new_set_pair_coming = .TRUE.
    1377              :                END IF
    1378              :             ELSE
    1379              :                ! do not forget the last block
    1380              :                new_set_pair_coming = .TRUE.
    1381         1805 :                atom_pair_done = .TRUE.
    1382              :             END IF
    1383              : 
    1384          342 :             IF (new_set_pair_coming) THEN
    1385              :                ! Increase lx, ly, lz by one to account for the | r * b >
    1386          342 :                IF (iatom <= jatom) THEN
    1387              :                   CALL apply_cartesian_operator(la_max(iset), 0, npgfa(iset), lb_max(jset), 0, npgfb(jset), &
    1388          228 :                                                 hab, rhab, right=.FALSE., derivative=.FALSE., origin=rac)
    1389              : 
    1390              :                ELSE
    1391              :                   CALL apply_cartesian_operator(lb_max(jset), 0, npgfb(jset), la_max(iset), 0, npgfa(iset), &
    1392          114 :                                                 hab, rhab, right=.TRUE., derivative=.FALSE., origin=rac)
    1393              :                END IF
    1394              : 
    1395              :                ! contract the block into h if we're done with the current set pair
    1396         1368 :                DO idir = 1, 3
    1397         1368 :                   IF (iatom <= jatom) THEN
    1398       112860 :                      work = 0._dp
    1399       301815 :                      work(1:ncoa, 1:nsgfb(jset)) = MATMUL(rhab(1:ncoa, 1:ncob, idir), sphi_b(1:ncob, sgfb:sgfb + nsgfb(jset) - 1))
    1400              :                      h_block(idir)%block(sgfa:sgfa + nsgfa(iset) - 1, sgfb:sgfb + nsgfb(jset) - 1) = &
    1401              :                         h_block(idir)%block(sgfa:sgfa + nsgfa(iset) - 1, sgfb:sgfb + nsgfb(jset) - 1) + &
    1402        69255 :                         MATMUL(TRANSPOSE(sphi_a(1:ncoa, sgfa:sgfa + nsgfa(iset) - 1)), work(1:ncoa, 1:nsgfb(jset)))
    1403              :                   ELSE
    1404        36252 :                      work(1:ncob, 1:nsgfa(iset)) = MATMUL(rhab(1:ncob, 1:ncoa, idir), sphi_a(1:ncoa, sgfa:sgfa + nsgfa(iset) - 1))
    1405              :                      h_block(idir)%block(sgfb:sgfb + nsgfb(jset) - 1, sgfa:sgfa + nsgfa(iset) - 1) = &
    1406              :                         h_block(idir)%block(sgfb:sgfb + nsgfb(jset) - 1, sgfa:sgfa + nsgfa(iset) - 1) + &
    1407        15903 :                         MATMUL(TRANSPOSE(sphi_b(1:ncob, sgfb:sgfb + nsgfb(jset) - 1)), work(1:ncob, 1:nsgfa(iset)))
    1408              :                   END IF
    1409              :                END DO
    1410              :             END IF
    1411              : 
    1412              :          END DO loop_tasks
    1413              :          END DO loop_pairs
    1414              : 
    1415          646 :          DO idir = 1, 3
    1416          608 :             CALL dbcsr_finalize(hmat(idir)%matrix)
    1417              :          END DO
    1418              : 
    1419              :       END DO loop_gridlevels
    1420              : 
    1421              :       !   *** Release work storage ***
    1422           38 :       DEALLOCATE (habt, rhab, workt, h_block)
    1423              : 
    1424           38 :       CALL timestop(handle)
    1425              : 
    1426           76 :    END SUBROUTINE integrate_rv_rspace
    1427              : 
    1428              : ! **************************************************************************************************
    1429              : !> \brief Builds the overlap derivative wrt nuclear velocities
    1430              : !>         dS/dV = < mu | r | nu > * (nu - mu)
    1431              : !> \param qs_env ...
    1432              : !> \param matrix_dsdv ...
    1433              : !> \param deltaR ...
    1434              : !> \param rcc ...
    1435              : !> \author Edward Ditler
    1436              : ! **************************************************************************************************
    1437            6 :    SUBROUTINE build_dSdV_matrix(qs_env, matrix_dsdv, deltaR, rcc)
    1438              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1439              :       TYPE(dbcsr_p_type), DIMENSION(:)                   :: matrix_dsdv
    1440              :       REAL(KIND=dp), DIMENSION(:, :)                     :: deltaR
    1441              :       REAL(KIND=dp), DIMENSION(3)                        :: rcc
    1442              : 
    1443              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'build_dSdV_matrix'
    1444              : 
    1445              :       INTEGER                                            :: handle, i
    1446            6 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks, my_matrix_dsdv, &
    1447            6 :                                                             my_matrix_dsdv2, my_matrix_mom
    1448              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1449            6 :          POINTER                                         :: sab_all
    1450            6 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1451              : 
    1452            6 :       CALL timeset(routineN, handle)
    1453              : 
    1454            6 :       NULLIFY (my_matrix_mom, my_matrix_dsdv, my_matrix_dsdv2, sab_all, qs_kind_set)
    1455              : 
    1456              :       CALL get_qs_env(qs_env=qs_env, &
    1457              :                       sab_all=sab_all, &
    1458              :                       qs_kind_set=qs_kind_set, &
    1459            6 :                       matrix_ks=matrix_ks)
    1460              : 
    1461              :       ! my_matrix_mom is needed because build_local_moment only works correctly with symmetric matrices
    1462            6 :       CALL dbcsr_allocate_matrix_set(my_matrix_dsdv, 3)
    1463            6 :       CALL dbcsr_allocate_matrix_set(my_matrix_dsdv2, 3)
    1464            6 :       CALL dbcsr_allocate_matrix_set(my_matrix_mom, 3)
    1465              : 
    1466           24 :       DO i = 1, 3
    1467           18 :          ALLOCATE (my_matrix_dsdv(i)%matrix)
    1468           18 :          ALLOCATE (my_matrix_dsdv2(i)%matrix)
    1469           18 :          ALLOCATE (my_matrix_mom(i)%matrix)
    1470              : 
    1471           18 :          CALL dbcsr_copy(my_matrix_dsdv(i)%matrix, matrix_dsdv(i)%matrix)
    1472           18 :          CALL dbcsr_copy(my_matrix_dsdv2(i)%matrix, matrix_dsdv(i)%matrix)
    1473           18 :          CALL dbcsr_copy(my_matrix_mom(i)%matrix, matrix_ks(1)%matrix)
    1474              : 
    1475           18 :          CALL dbcsr_set(my_matrix_dsdv2(i)%matrix, 0.0_dp)
    1476           18 :          CALL dbcsr_set(my_matrix_dsdv(i)%matrix, 0.0_dp)
    1477           18 :          CALL dbcsr_set(my_matrix_mom(i)%matrix, 0.0_dp)
    1478           24 :          CALL dbcsr_set(matrix_dsdv(i)%matrix, 0.0_dp)
    1479              :       END DO
    1480              : 
    1481              :       CALL build_local_moment_matrix(qs_env, my_matrix_mom, 1, ref_point=rcc, &
    1482            6 :                                      neighbor_image=.TRUE.)
    1483              : 
    1484           24 :       DO i = 1, 3
    1485           18 :          CALL dbcsr_desymmetrize(my_matrix_mom(i)%matrix, my_matrix_dsdv(i)%matrix)
    1486           24 :          CALL dbcsr_copy(my_matrix_dsdv2(i)%matrix, my_matrix_dsdv(i)%matrix)
    1487              :       END DO
    1488              : 
    1489              :       ! delta_nu^A <mu|r|nu>
    1490              :       CALL hr_mult_by_delta_3d(my_matrix_dsdv, qs_kind_set, "ORB", sab_all, &
    1491            6 :                                deltaR, direction_Or=.TRUE.)
    1492              :       ! -delta_mu^A <mu|r|nu>
    1493              :       CALL hr_mult_by_delta_3d(my_matrix_dsdv2, qs_kind_set, "ORB", sab_all, &
    1494            6 :                                deltaR, direction_Or=.FALSE.)
    1495           24 :       DO i = 1, 3
    1496           18 :          CALL dbcsr_copy(matrix_dsdv(i)%matrix, my_matrix_dsdv(i)%matrix)
    1497           24 :          CALL dbcsr_add(matrix_dsdv(i)%matrix, my_matrix_dsdv2(i)%matrix, 1.0_dp, -1.0_dp)
    1498              :       END DO
    1499              : 
    1500            6 :       CALL dbcsr_deallocate_matrix_set(my_matrix_dsdv)
    1501            6 :       CALL dbcsr_deallocate_matrix_set(my_matrix_dsdv2)
    1502            6 :       CALL dbcsr_deallocate_matrix_set(my_matrix_mom)
    1503              : 
    1504            6 :       CALL timestop(handle)
    1505              : 
    1506            6 :    END SUBROUTINE build_dSdV_matrix
    1507              : 
    1508              : ! **************************************************************************************************
    1509              : !> \brief Build the two ordered nonlocal second-position products.
    1510              : !> \param matrix_rcomr ...
    1511              : !> \param matrix_rrcom ...
    1512              : !> \param qs_kind_set ...
    1513              : !> \param sab_all ...
    1514              : !> \param sap_ppnl ...
    1515              : !> \param eps_ppnl ...
    1516              : !> \param particle_set ...
    1517              : !> \param cell ...
    1518              : !> \author Edward Ditler, Tomas Zimmermann
    1519              : ! **************************************************************************************************
    1520            2 :    SUBROUTINE build_com_rpnl_r(matrix_rcomr, matrix_rrcom, qs_kind_set, sab_all, sap_ppnl, eps_ppnl, &
    1521              :                                particle_set, cell)
    1522              : 
    1523              :       TYPE(dbcsr_p_type), DIMENSION(:, :)                :: matrix_rcomr, matrix_rrcom
    1524              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1525              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1526              :          POINTER                                         :: sab_all, sap_ppnl
    1527              :       REAL(KIND=dp), INTENT(IN)                          :: eps_ppnl
    1528              :       TYPE(particle_type), DIMENSION(:), INTENT(IN), &
    1529              :          POINTER                                         :: particle_set
    1530              :       TYPE(cell_type), POINTER                           :: cell
    1531              : 
    1532              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'build_com_rpnl_r'
    1533              : 
    1534              :       INTEGER                                            :: handle, i, iab, iac, iatom, ibc, icol, &
    1535              :                                                             ikind, irow, j, jatom, jkind, kac, &
    1536              :                                                             kbc, kkind, na, natom, nb, nkind, np, &
    1537              :                                                             slot
    1538              :       INTEGER, DIMENSION(3)                              :: cell_b
    1539              :       LOGICAL                                            :: found, ppnl_present
    1540              :       REAL(KIND=dp), DIMENSION(3)                        :: rab
    1541            2 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: achint, acint, bchint, bcint
    1542              :       TYPE(alist_type), POINTER                          :: alist_ac, alist_bc
    1543           54 :       TYPE(block_p_type), DIMENSION(3, 3, 2)             :: blocks_rvr
    1544            2 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set
    1545              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    1546            2 :       TYPE(sap_int_type), DIMENSION(:), POINTER          :: sap_int
    1547              : 
    1548              : !$    INTEGER(kind=omp_lock_kind), &
    1549            2 : !$       ALLOCATABLE, DIMENSION(:) :: locks
    1550              : !$    INTEGER                                            :: lock_num, hash
    1551              : !$    INTEGER, PARAMETER                                 :: nlock = 501
    1552              : 
    1553            2 :       ppnl_present = ASSOCIATED(sap_ppnl)
    1554            2 :       IF (.NOT. ppnl_present) RETURN
    1555              : 
    1556            2 :       CALL timeset(routineN, handle)
    1557            2 :       nkind = SIZE(qs_kind_set)
    1558            2 :       natom = SIZE(particle_set)
    1559              : 
    1560              :       ! sap_int needs to be shared as multiple threads need to access this
    1561            2 :       NULLIFY (sap_int)
    1562           14 :       ALLOCATE (sap_int(nkind*nkind))
    1563           10 :       DO i = 1, nkind*nkind
    1564            8 :          NULLIFY (sap_int(i)%alist, sap_int(i)%asort, sap_int(i)%aindex)
    1565           10 :          sap_int(i)%nalist = 0
    1566              :       END DO
    1567              : 
    1568              :       ! We put zero as a reference point, because actually in the integrals we need two different ones:
    1569              :       !  < a | (r - R^\lambda_\beta) * [V, r_\alpha - R^\eta_\alpha] | b >
    1570              :       !  The first reference point can be added in a seperate step as the term will be
    1571              :       !        - R^\lambda_\beta * < a | [V, r_\alpha] | b >
    1572              :       !      = + R^\lambda_\beta * < a | [r_\alpha, V] | b >
    1573              :       !  The second reference point is not important, because it disappears in the commutator
    1574              :       CALL build_sap_ints(sap_int, sap_ppnl, qs_kind_set, nder=2, moment_mode=.TRUE., &
    1575            2 :                           particle_set=particle_set, cell=cell, refpoint=[0._dp, 0._dp, 0._dp])
    1576              : 
    1577              :       ! *** Set up a sorting index
    1578            2 :       CALL sap_sort(sap_int)
    1579              : 
    1580           10 :       ALLOCATE (basis_set(nkind))
    1581            6 :       DO ikind = 1, nkind
    1582            4 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
    1583            6 :          IF (ASSOCIATED(orb_basis_set)) THEN
    1584            4 :             basis_set(ikind)%gto_basis_set => orb_basis_set
    1585              :          ELSE
    1586            0 :             NULLIFY (basis_set(ikind)%gto_basis_set)
    1587              :          END IF
    1588              :       END DO
    1589              : 
    1590              :       ! *** All integrals needed have been calculated and stored in sap_int
    1591              :       ! *** We now calculate the ordered second-position product matrix elements
    1592              : 
    1593              : !$OMP PARALLEL &
    1594              : !$OMP DEFAULT (NONE) &
    1595              : !$OMP SHARED  (basis_set, matrix_rcomr, matrix_rrcom, &
    1596              : !$OMP          sap_int, nkind, eps_ppnl, locks, sab_all) &
    1597              : !$OMP PRIVATE (ikind, jkind, iatom, jatom, cell_b, rab, &
    1598              : !$OMP          iab, irow, icol, blocks_rvr, lock_num, &
    1599              : !$OMP          found, iac, ibc, alist_ac, alist_bc, &
    1600              : !$OMP          na, np, nb, kkind, kac, kbc, i, j, &
    1601            2 : !$OMP          hash, natom, acint, bcint, achint, bchint)
    1602              : 
    1603              : !$OMP SINGLE
    1604              : !$    ALLOCATE (locks(nlock))
    1605              : !$OMP END SINGLE
    1606              : 
    1607              : !$OMP DO
    1608              : !$    DO lock_num = 1, nlock
    1609              : !$       call omp_init_lock(locks(lock_num))
    1610              : !$    END DO
    1611              : !$OMP END DO
    1612              : 
    1613              : !$OMP DO SCHEDULE(GUIDED)
    1614              : 
    1615              :       DO slot = 1, sab_all(1)%nl_size
    1616              : 
    1617              :          ikind = sab_all(1)%nlist_task(slot)%ikind
    1618              :          jkind = sab_all(1)%nlist_task(slot)%jkind
    1619              :          iatom = sab_all(1)%nlist_task(slot)%iatom
    1620              :          jatom = sab_all(1)%nlist_task(slot)%jatom
    1621              :          cell_b(:) = sab_all(1)%nlist_task(slot)%cell(:)
    1622              :          rab(1:3) = sab_all(1)%nlist_task(slot)%r(1:3)
    1623              : 
    1624              :          IF (.NOT. ASSOCIATED(basis_set(ikind)%gto_basis_set)) CYCLE
    1625              :          IF (.NOT. ASSOCIATED(basis_set(jkind)%gto_basis_set)) CYCLE
    1626              :          iab = ikind + nkind*(jkind - 1)
    1627              : 
    1628              :          ! *** Create matrix blocks for a new matrix block column ***
    1629              :          irow = iatom
    1630              :          icol = jatom
    1631              :          DO i = 1, 3
    1632              :             DO j = 1, 3
    1633              :                ! t_alpha = MOD(i - 1, 3) + 1
    1634              :                ! t_beta = FLOOR(REAL(i - 1, dp)/3._dp) + 1
    1635              : 
    1636              :                CALL dbcsr_get_block_p(matrix_rcomr(i, j)%matrix, irow, icol, blocks_rvr(i, j, 1)%block, found)
    1637              :                CPASSERT(found)
    1638              :                CALL dbcsr_get_block_p(matrix_rrcom(i, j)%matrix, irow, icol, blocks_rvr(i, j, 2)%block, found)
    1639              :                CPASSERT(found)
    1640              :             END DO
    1641              :          END DO
    1642              : 
    1643              :          ! loop over all kinds for projector atom
    1644              :          DO kkind = 1, nkind
    1645              :             iac = ikind + nkind*(kkind - 1)
    1646              :             ibc = jkind + nkind*(kkind - 1)
    1647              :             IF (.NOT. ASSOCIATED(sap_int(iac)%alist)) CYCLE
    1648              :             IF (.NOT. ASSOCIATED(sap_int(ibc)%alist)) CYCLE
    1649              :             CALL get_alist(sap_int(iac), alist_ac, iatom)
    1650              :             CALL get_alist(sap_int(ibc), alist_bc, jatom)
    1651              :             IF (.NOT. ASSOCIATED(alist_ac)) CYCLE
    1652              :             IF (.NOT. ASSOCIATED(alist_bc)) CYCLE
    1653              :             DO kac = 1, alist_ac%nclist
    1654              :                DO kbc = 1, alist_bc%nclist
    1655              :                   IF (alist_ac%clist(kac)%catom /= alist_bc%clist(kbc)%catom) CYCLE
    1656              : 
    1657              :                   ! Some documention, considering the C1 O1 O2 molecule
    1658              :                   ! The integrals are <a|p>
    1659              :                   ! sap_int(1:2, 1:2) -> [(a=C, p=C), (a=C, p=O), (a=O, p=C), (a=O, p=0)]
    1660              :                   ! the (a=O, p=C) entry has an alist
    1661              :                   !  alist has two elements: O1, O2
    1662              :                   !     alist(O1) -> clist(C1)%acint are the integrals
    1663              :                   !     alist(O2) -> clist(C1)%acint are the integrals
    1664              : 
    1665              :                   IF (ALL(cell_b + alist_bc%clist(kbc)%cell - alist_ac%clist(kac)%cell == 0)) THEN
    1666              :                      IF (alist_ac%clist(kac)%maxac*alist_bc%clist(kbc)%maxach < eps_ppnl) CYCLE
    1667              :                      acint => alist_ac%clist(kac)%acint
    1668              :                      bcint => alist_bc%clist(kbc)%acint
    1669              :                      achint => alist_ac%clist(kac)%achint
    1670              :                      bchint => alist_bc%clist(kbc)%achint
    1671              :                      na = SIZE(acint, 1)
    1672              :                      np = SIZE(acint, 2)
    1673              :                      nb = SIZE(bcint, 1)
    1674              : !$                   hash = MOD((iatom - 1)*natom + jatom, nlock) + 1
    1675              : !$                   CALL omp_set_lock(locks(hash))
    1676              : 
    1677              :                      DO i = 1, 3
    1678              :                         DO j = 1, 3
    1679              :                            ! matrix_rcomr(i, j) = (Vnl*r_i)*r_j - (r_i*Vnl)*r_j
    1680              :                            blocks_rvr(i, j, 1)%block(1:na, 1:nb) = blocks_rvr(i, j, 1)%block(1:na, 1:nb) + &
    1681              :                                                      MATMUL(achint(1:na, 1:np, bi_1), TRANSPOSE(bcint(1:nb, 1:np, bi_rr(i, j)))) - &
    1682              :                                                           MATMUL(achint(1:na, 1:np, bi_r(i)), TRANSPOSE(bcint(1:nb, 1:np, bi_r(j))))
    1683              : 
    1684              :                            ! matrix_rrcom(i, j) = r_j*(Vnl*r_i) - r_j*(r_i*Vnl)
    1685              :                            blocks_rvr(i, j, 2)%block(1:na, 1:nb) = blocks_rvr(i, j, 2)%block(1:na, 1:nb) + &
    1686              :                                                       MATMUL(achint(1:na, 1:np, bi_r(j)), TRANSPOSE(bcint(1:nb, 1:np, bi_r(i)))) - &
    1687              :                                                          MATMUL(achint(1:na, 1:np, bi_rr(i, j)), TRANSPOSE(bcint(1:nb, 1:np, bi_1)))
    1688              :                         END DO
    1689              :                      END DO
    1690              : 
    1691              : !$                   CALL omp_unset_lock(locks(hash))
    1692              :                      EXIT ! We have found a match and there can be only one single match
    1693              :                   END IF
    1694              :                END DO
    1695              :             END DO
    1696              :          END DO
    1697              :          DO i = 1, 3
    1698              :             DO j = 1, 3
    1699              :                NULLIFY (blocks_rvr(i, j, 1)%block)
    1700              :                NULLIFY (blocks_rvr(i, j, 2)%block)
    1701              :             END DO
    1702              :          END DO
    1703              :       END DO
    1704              : 
    1705              : !$OMP DO
    1706              : !$    DO lock_num = 1, nlock
    1707              : !$       call omp_destroy_lock(locks(lock_num))
    1708              : !$    END DO
    1709              : !$OMP END DO
    1710              : 
    1711              : !$OMP SINGLE
    1712              : !$    DEALLOCATE (locks)
    1713              : !$OMP END SINGLE NOWAIT
    1714              : 
    1715              : !$OMP END PARALLEL
    1716              : 
    1717            2 :       CALL release_sap_int(sap_int)
    1718              : 
    1719            2 :       DEALLOCATE (basis_set)
    1720              : 
    1721            2 :       CALL timestop(handle)
    1722              : 
    1723            6 :    END SUBROUTINE build_com_rpnl_r
    1724              : 
    1725              : ! **************************************************************************************************
    1726              : !> \brief Calculate the double commutator [[Vnl, r], r]
    1727              : !> \param matrix_rv ...
    1728              : !> \param qs_kind_set ...
    1729              : !> \param sab_orb ...
    1730              : !> \param sap_ppnl ...
    1731              : !> \param eps_ppnl ...
    1732              : !> \param particle_set ...
    1733              : !> \param pseudoatom Only consider pseudopotentials on atom lambda
    1734              : !> \author Edward Ditler
    1735              : ! **************************************************************************************************
    1736            6 :    SUBROUTINE build_dcom_rpnl(matrix_rv, qs_kind_set, sab_orb, sap_ppnl, eps_ppnl, particle_set, pseudoatom)
    1737              : 
    1738              :       TYPE(dbcsr_p_type), DIMENSION(:, :)                :: matrix_rv
    1739              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1740              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1741              :          POINTER                                         :: sab_orb, sap_ppnl
    1742              :       REAL(KIND=dp), INTENT(IN)                          :: eps_ppnl
    1743              :       TYPE(particle_type), DIMENSION(:), INTENT(IN), &
    1744              :          POINTER                                         :: particle_set
    1745              :       INTEGER, INTENT(IN)                                :: pseudoatom
    1746              : 
    1747              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'build_dcom_rpnl'
    1748              : 
    1749              :       INTEGER                                            :: handle, i, iab, iac, iatom, ibc, icol, &
    1750              :                                                             ikind, irow, j, jatom, jkind, kac, &
    1751              :                                                             kbc, kkind, na, natom, nb, nkind, np, &
    1752              :                                                             slot
    1753              :       INTEGER, DIMENSION(3)                              :: cell_b
    1754              :       LOGICAL                                            :: found, ppnl_present
    1755              :       REAL(KIND=dp), DIMENSION(3)                        :: rab
    1756            6 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: achint, acint, bchint, bcint
    1757              :       TYPE(alist_type), POINTER                          :: alist_ac, alist_bc
    1758           78 :       TYPE(block_p_type), DIMENSION(3, 3)                :: blocks_rv
    1759            6 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set
    1760              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    1761            6 :       TYPE(sap_int_type), DIMENSION(:), POINTER          :: sap_int
    1762              : 
    1763              : !$    INTEGER(kind=omp_lock_kind), &
    1764            6 : !$       ALLOCATABLE, DIMENSION(:) :: locks
    1765              : !$    INTEGER                                            :: lock_num, hash
    1766              : !$    INTEGER, PARAMETER                                 :: nlock = 501
    1767              : 
    1768            6 :       ppnl_present = ASSOCIATED(sap_ppnl)
    1769            6 :       IF (.NOT. ppnl_present) RETURN
    1770              : 
    1771            6 :       CALL timeset(routineN, handle)
    1772            6 :       nkind = SIZE(qs_kind_set)
    1773            6 :       natom = SIZE(particle_set)
    1774              : 
    1775              :       ! sap_int needs to be shared as multiple threads need to access this
    1776            6 :       NULLIFY (sap_int)
    1777           42 :       ALLOCATE (sap_int(nkind*nkind))
    1778           30 :       DO i = 1, nkind*nkind
    1779           24 :          NULLIFY (sap_int(i)%alist, sap_int(i)%asort, sap_int(i)%aindex)
    1780           30 :          sap_int(i)%nalist = 0
    1781              :       END DO
    1782              : 
    1783              :       ! "nder" in moment_mode is "order"
    1784              :       CALL build_sap_ints(sap_int, sap_ppnl, qs_kind_set, nder=2, moment_mode=.TRUE., &
    1785            6 :                           particle_set=particle_set, pseudoatom=pseudoatom)
    1786              : 
    1787              :       ! *** Set up a sorting index
    1788            6 :       CALL sap_sort(sap_int)
    1789              : 
    1790           30 :       ALLOCATE (basis_set(nkind))
    1791           18 :       DO ikind = 1, nkind
    1792           12 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
    1793           18 :          IF (ASSOCIATED(orb_basis_set)) THEN
    1794           12 :             basis_set(ikind)%gto_basis_set => orb_basis_set
    1795              :          ELSE
    1796            0 :             NULLIFY (basis_set(ikind)%gto_basis_set)
    1797              :          END IF
    1798              :       END DO
    1799              : 
    1800              :       ! *** All integrals needed have been calculated and stored in sap_int
    1801              :       ! *** We now calculate the commutator matrix elements
    1802              : 
    1803              : !$OMP PARALLEL &
    1804              : !$OMP DEFAULT (NONE) &
    1805              : !$OMP SHARED  (basis_set, matrix_rv, &
    1806              : !$OMP          sap_int, nkind, eps_ppnl, locks, sab_orb) &
    1807              : !$OMP PRIVATE (ikind, jkind, iatom, jatom, cell_b, rab, &
    1808              : !$OMP          iab, irow, icol, blocks_rv, lock_num, &
    1809              : !$OMP          found, iac, ibc, alist_ac, alist_bc, &
    1810              : !$OMP          na, np, nb, kkind, kac, kbc, i, j, &
    1811            6 : !$OMP          hash, natom, acint, bcint, achint, bchint)
    1812              : 
    1813              : !$OMP SINGLE
    1814              : !$    ALLOCATE (locks(nlock))
    1815              : !$OMP END SINGLE
    1816              : 
    1817              : !$OMP DO
    1818              : !$    DO lock_num = 1, nlock
    1819              : !$       call omp_init_lock(locks(lock_num))
    1820              : !$    END DO
    1821              : !$OMP END DO
    1822              : 
    1823              : !$OMP DO SCHEDULE(GUIDED)
    1824              : 
    1825              :       DO slot = 1, sab_orb(1)%nl_size
    1826              : 
    1827              :          ikind = sab_orb(1)%nlist_task(slot)%ikind
    1828              :          jkind = sab_orb(1)%nlist_task(slot)%jkind
    1829              :          iatom = sab_orb(1)%nlist_task(slot)%iatom
    1830              :          jatom = sab_orb(1)%nlist_task(slot)%jatom
    1831              :          cell_b(:) = sab_orb(1)%nlist_task(slot)%cell(:)
    1832              :          rab(1:3) = sab_orb(1)%nlist_task(slot)%r(1:3)
    1833              : 
    1834              :          IF (.NOT. ASSOCIATED(basis_set(ikind)%gto_basis_set)) CYCLE
    1835              :          IF (.NOT. ASSOCIATED(basis_set(jkind)%gto_basis_set)) CYCLE
    1836              :          iab = ikind + nkind*(jkind - 1)
    1837              : 
    1838              :          ! *** Create matrix blocks for a new matrix block column ***
    1839              :          IF (iatom <= jatom) THEN
    1840              :             irow = iatom
    1841              :             icol = jatom
    1842              :          ELSE
    1843              :             irow = jatom
    1844              :             icol = iatom
    1845              :          END IF
    1846              : 
    1847              :          DO i = 1, 3
    1848              :             DO j = 1, 3
    1849              :                CALL dbcsr_get_block_p(matrix_rv(i, j)%matrix, irow, icol, blocks_rv(i, j)%block, found)
    1850              :                blocks_rv(i, j)%block = 0._dp
    1851              :                CPASSERT(found)
    1852              :             END DO
    1853              :          END DO
    1854              : 
    1855              :          ! loop over all kinds for projector atom
    1856              :          DO kkind = 1, nkind
    1857              :             iac = ikind + nkind*(kkind - 1)
    1858              :             ibc = jkind + nkind*(kkind - 1)
    1859              :             IF (.NOT. ASSOCIATED(sap_int(iac)%alist)) CYCLE
    1860              :             IF (.NOT. ASSOCIATED(sap_int(ibc)%alist)) CYCLE
    1861              :             CALL get_alist(sap_int(iac), alist_ac, iatom)
    1862              :             CALL get_alist(sap_int(ibc), alist_bc, jatom)
    1863              :             IF (.NOT. ASSOCIATED(alist_ac)) CYCLE
    1864              :             IF (.NOT. ASSOCIATED(alist_bc)) CYCLE
    1865              :             DO kac = 1, alist_ac%nclist
    1866              :                DO kbc = 1, alist_bc%nclist
    1867              :                   IF (alist_ac%clist(kac)%catom /= alist_bc%clist(kbc)%catom) CYCLE
    1868              :                   IF (ALL(cell_b + alist_bc%clist(kbc)%cell - alist_ac%clist(kac)%cell == 0)) THEN
    1869              :                      IF (alist_ac%clist(kac)%maxac*alist_bc%clist(kbc)%maxach < eps_ppnl) CYCLE
    1870              :                      acint => alist_ac%clist(kac)%acint
    1871              :                      bcint => alist_bc%clist(kbc)%acint
    1872              :                      achint => alist_ac%clist(kac)%achint
    1873              :                      bchint => alist_bc%clist(kbc)%achint
    1874              :                      na = SIZE(acint, 1)
    1875              :                      np = SIZE(acint, 2)
    1876              :                      nb = SIZE(bcint, 1)
    1877              : !$                   hash = MOD((iatom - 1)*natom + jatom, nlock) + 1
    1878              : !$                   CALL omp_set_lock(locks(hash))
    1879              :                      ! Template:
    1880              :                      ! blocks_rv(1)%block(1:na, 1:nb) = blocks_rv(1)%block(1:na, 1:nb) + &
    1881              :                      !                                  MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 1))) ! xV
    1882              :                      IF (iatom <= jatom) THEN
    1883              :                         ! r_alpha*Vnl*r_beta
    1884              :                         blocks_rv(1, 1)%block(1:na, 1:nb) = blocks_rv(1, 1)%block(1:na, 1:nb) + &
    1885              :                                                             MATMUL(achint(1:na, 1:np, bi_x), TRANSPOSE(bcint(1:nb, 1:np, bi_x)))
    1886              : 
    1887              :                         blocks_rv(1, 2)%block(1:na, 1:nb) = blocks_rv(1, 2)%block(1:na, 1:nb) + &
    1888              :                                                             MATMUL(achint(1:na, 1:np, bi_x), TRANSPOSE(bcint(1:nb, 1:np, bi_y)))
    1889              : 
    1890              :                         blocks_rv(1, 3)%block(1:na, 1:nb) = blocks_rv(1, 3)%block(1:na, 1:nb) + &
    1891              :                                                             MATMUL(achint(1:na, 1:np, bi_x), TRANSPOSE(bcint(1:nb, 1:np, bi_z)))
    1892              : 
    1893              :                         blocks_rv(2, 1)%block(1:na, 1:nb) = blocks_rv(2, 1)%block(1:na, 1:nb) + &
    1894              :                                                             MATMUL(achint(1:na, 1:np, bi_y), TRANSPOSE(bcint(1:nb, 1:np, bi_x)))
    1895              : 
    1896              :                         blocks_rv(2, 2)%block(1:na, 1:nb) = blocks_rv(2, 2)%block(1:na, 1:nb) + &
    1897              :                                                             MATMUL(achint(1:na, 1:np, bi_y), TRANSPOSE(bcint(1:nb, 1:np, bi_y)))
    1898              : 
    1899              :                         blocks_rv(2, 3)%block(1:na, 1:nb) = blocks_rv(2, 3)%block(1:na, 1:nb) + &
    1900              :                                                             MATMUL(achint(1:na, 1:np, bi_y), TRANSPOSE(bcint(1:nb, 1:np, bi_z)))
    1901              : 
    1902              :                         blocks_rv(3, 1)%block(1:na, 1:nb) = blocks_rv(3, 1)%block(1:na, 1:nb) + &
    1903              :                                                             MATMUL(achint(1:na, 1:np, bi_z), TRANSPOSE(bcint(1:nb, 1:np, bi_x)))
    1904              : 
    1905              :                         blocks_rv(3, 2)%block(1:na, 1:nb) = blocks_rv(3, 2)%block(1:na, 1:nb) + &
    1906              :                                                             MATMUL(achint(1:na, 1:np, bi_z), TRANSPOSE(bcint(1:nb, 1:np, bi_y)))
    1907              : 
    1908              :                         blocks_rv(3, 3)%block(1:na, 1:nb) = blocks_rv(3, 3)%block(1:na, 1:nb) + &
    1909              :                                                             MATMUL(achint(1:na, 1:np, bi_z), TRANSPOSE(bcint(1:nb, 1:np, bi_z)))
    1910              : 
    1911              :                         ! -r_alpha*r_beta*Vnl
    1912              :                         blocks_rv(1, 1)%block(1:na, 1:nb) = blocks_rv(1, 1)%block(1:na, 1:nb) - &
    1913              :                                                             MATMUL(achint(1:na, 1:np, bi_xx), TRANSPOSE(bcint(1:nb, 1:np, bi_1)))
    1914              : 
    1915              :                         blocks_rv(1, 2)%block(1:na, 1:nb) = blocks_rv(1, 2)%block(1:na, 1:nb) - &
    1916              :                                                             MATMUL(achint(1:na, 1:np, bi_xy), TRANSPOSE(bcint(1:nb, 1:np, bi_1)))
    1917              : 
    1918              :                         blocks_rv(1, 3)%block(1:na, 1:nb) = blocks_rv(1, 3)%block(1:na, 1:nb) - &
    1919              :                                                             MATMUL(achint(1:na, 1:np, bi_xz), TRANSPOSE(bcint(1:nb, 1:np, bi_1)))
    1920              : 
    1921              :                         blocks_rv(2, 1)%block(1:na, 1:nb) = blocks_rv(2, 1)%block(1:na, 1:nb) - &
    1922              :                                                             MATMUL(achint(1:na, 1:np, bi_xy), TRANSPOSE(bcint(1:nb, 1:np, bi_1)))
    1923              : 
    1924              :                         blocks_rv(2, 2)%block(1:na, 1:nb) = blocks_rv(2, 2)%block(1:na, 1:nb) - &
    1925              :                                                             MATMUL(achint(1:na, 1:np, bi_yy), TRANSPOSE(bcint(1:nb, 1:np, bi_1)))
    1926              : 
    1927              :                         blocks_rv(2, 3)%block(1:na, 1:nb) = blocks_rv(2, 3)%block(1:na, 1:nb) - &
    1928              :                                                             MATMUL(achint(1:na, 1:np, bi_yz), TRANSPOSE(bcint(1:nb, 1:np, bi_1)))
    1929              : 
    1930              :                         blocks_rv(3, 1)%block(1:na, 1:nb) = blocks_rv(3, 1)%block(1:na, 1:nb) - &
    1931              :                                                             MATMUL(achint(1:na, 1:np, bi_xz), TRANSPOSE(bcint(1:nb, 1:np, bi_1)))
    1932              : 
    1933              :                         blocks_rv(3, 2)%block(1:na, 1:nb) = blocks_rv(3, 2)%block(1:na, 1:nb) - &
    1934              :                                                             MATMUL(achint(1:na, 1:np, bi_yz), TRANSPOSE(bcint(1:nb, 1:np, bi_1)))
    1935              : 
    1936              :                         blocks_rv(3, 3)%block(1:na, 1:nb) = blocks_rv(3, 3)%block(1:na, 1:nb) - &
    1937              :                                                             MATMUL(achint(1:na, 1:np, bi_zz), TRANSPOSE(bcint(1:nb, 1:np, bi_1)))
    1938              : 
    1939              :                         ! -Vnl*r_beta*r_alpha
    1940              :                         blocks_rv(1, 1)%block(1:na, 1:nb) = blocks_rv(1, 1)%block(1:na, 1:nb) - &
    1941              :                                                             MATMUL(achint(1:na, 1:np, bi_1), TRANSPOSE(bcint(1:nb, 1:np, bi_xx)))
    1942              : 
    1943              :                         blocks_rv(1, 2)%block(1:na, 1:nb) = blocks_rv(1, 2)%block(1:na, 1:nb) - &
    1944              :                                                             MATMUL(achint(1:na, 1:np, bi_1), TRANSPOSE(bcint(1:nb, 1:np, bi_xy)))
    1945              : 
    1946              :                         blocks_rv(1, 3)%block(1:na, 1:nb) = blocks_rv(1, 3)%block(1:na, 1:nb) - &
    1947              :                                                             MATMUL(achint(1:na, 1:np, bi_1), TRANSPOSE(bcint(1:nb, 1:np, bi_xz)))
    1948              : 
    1949              :                         blocks_rv(2, 1)%block(1:na, 1:nb) = blocks_rv(2, 1)%block(1:na, 1:nb) - &
    1950              :                                                             MATMUL(achint(1:na, 1:np, bi_1), TRANSPOSE(bcint(1:nb, 1:np, bi_xy)))
    1951              : 
    1952              :                         blocks_rv(2, 2)%block(1:na, 1:nb) = blocks_rv(2, 2)%block(1:na, 1:nb) - &
    1953              :                                                             MATMUL(achint(1:na, 1:np, bi_1), TRANSPOSE(bcint(1:nb, 1:np, bi_yy)))
    1954              : 
    1955              :                         blocks_rv(2, 3)%block(1:na, 1:nb) = blocks_rv(2, 3)%block(1:na, 1:nb) - &
    1956              :                                                             MATMUL(achint(1:na, 1:np, bi_1), TRANSPOSE(bcint(1:nb, 1:np, bi_yz)))
    1957              : 
    1958              :                         blocks_rv(3, 1)%block(1:na, 1:nb) = blocks_rv(3, 1)%block(1:na, 1:nb) - &
    1959              :                                                             MATMUL(achint(1:na, 1:np, bi_1), TRANSPOSE(bcint(1:nb, 1:np, bi_xz)))
    1960              : 
    1961              :                         blocks_rv(3, 2)%block(1:na, 1:nb) = blocks_rv(3, 2)%block(1:na, 1:nb) - &
    1962              :                                                             MATMUL(achint(1:na, 1:np, bi_1), TRANSPOSE(bcint(1:nb, 1:np, bi_yz)))
    1963              : 
    1964              :                         blocks_rv(3, 3)%block(1:na, 1:nb) = blocks_rv(3, 3)%block(1:na, 1:nb) - &
    1965              :                                                             MATMUL(achint(1:na, 1:np, bi_1), TRANSPOSE(bcint(1:nb, 1:np, bi_zz)))
    1966              : 
    1967              :                         ! +r_beta*Vnl*r_alpha
    1968              :                         blocks_rv(1, 1)%block(1:na, 1:nb) = blocks_rv(1, 1)%block(1:na, 1:nb) + &
    1969              :                                                             MATMUL(achint(1:na, 1:np, bi_x), TRANSPOSE(bcint(1:nb, 1:np, bi_x)))
    1970              : 
    1971              :                         blocks_rv(1, 2)%block(1:na, 1:nb) = blocks_rv(1, 2)%block(1:na, 1:nb) + &
    1972              :                                                             MATMUL(achint(1:na, 1:np, bi_y), TRANSPOSE(bcint(1:nb, 1:np, bi_x)))
    1973              : 
    1974              :                         blocks_rv(1, 3)%block(1:na, 1:nb) = blocks_rv(1, 3)%block(1:na, 1:nb) + &
    1975              :                                                             MATMUL(achint(1:na, 1:np, bi_z), TRANSPOSE(bcint(1:nb, 1:np, bi_x)))
    1976              : 
    1977              :                         blocks_rv(2, 1)%block(1:na, 1:nb) = blocks_rv(2, 1)%block(1:na, 1:nb) + &
    1978              :                                                             MATMUL(achint(1:na, 1:np, bi_x), TRANSPOSE(bcint(1:nb, 1:np, bi_y)))
    1979              : 
    1980              :                         blocks_rv(2, 2)%block(1:na, 1:nb) = blocks_rv(2, 2)%block(1:na, 1:nb) + &
    1981              :                                                             MATMUL(achint(1:na, 1:np, bi_y), TRANSPOSE(bcint(1:nb, 1:np, bi_y)))
    1982              : 
    1983              :                         blocks_rv(2, 3)%block(1:na, 1:nb) = blocks_rv(2, 3)%block(1:na, 1:nb) + &
    1984              :                                                             MATMUL(achint(1:na, 1:np, bi_z), TRANSPOSE(bcint(1:nb, 1:np, bi_y)))
    1985              : 
    1986              :                         blocks_rv(3, 1)%block(1:na, 1:nb) = blocks_rv(3, 1)%block(1:na, 1:nb) + &
    1987              :                                                             MATMUL(achint(1:na, 1:np, bi_x), TRANSPOSE(bcint(1:nb, 1:np, bi_z)))
    1988              : 
    1989              :                         blocks_rv(3, 2)%block(1:na, 1:nb) = blocks_rv(3, 2)%block(1:na, 1:nb) + &
    1990              :                                                             MATMUL(achint(1:na, 1:np, bi_y), TRANSPOSE(bcint(1:nb, 1:np, bi_z)))
    1991              : 
    1992              :                         blocks_rv(3, 3)%block(1:na, 1:nb) = blocks_rv(3, 3)%block(1:na, 1:nb) + &
    1993              :                                                             MATMUL(achint(1:na, 1:np, bi_z), TRANSPOSE(bcint(1:nb, 1:np, bi_z)))
    1994              :                      ELSE
    1995              :                         ! r_alpha*Vnl*r_beta
    1996              :                         blocks_rv(1, 1)%block(1:nb, 1:na) = blocks_rv(1, 1)%block(1:nb, 1:na) + &
    1997              :                                                             MATMUL(bchint(1:nb, 1:np, bi_x), TRANSPOSE(acint(1:na, 1:np, bi_x)))
    1998              : 
    1999              :                         blocks_rv(1, 2)%block(1:nb, 1:na) = blocks_rv(1, 2)%block(1:nb, 1:na) + &
    2000              :                                                             MATMUL(bchint(1:nb, 1:np, bi_x), TRANSPOSE(acint(1:na, 1:np, bi_y)))
    2001              : 
    2002              :                         blocks_rv(1, 3)%block(1:nb, 1:na) = blocks_rv(1, 3)%block(1:nb, 1:na) + &
    2003              :                                                             MATMUL(bchint(1:nb, 1:np, bi_x), TRANSPOSE(acint(1:na, 1:np, bi_z)))
    2004              : 
    2005              :                         blocks_rv(2, 1)%block(1:nb, 1:na) = blocks_rv(2, 1)%block(1:nb, 1:na) + &
    2006              :                                                             MATMUL(bchint(1:nb, 1:np, bi_y), TRANSPOSE(acint(1:na, 1:np, bi_x)))
    2007              : 
    2008              :                         blocks_rv(2, 2)%block(1:nb, 1:na) = blocks_rv(2, 2)%block(1:nb, 1:na) + &
    2009              :                                                             MATMUL(bchint(1:nb, 1:np, bi_y), TRANSPOSE(acint(1:na, 1:np, bi_y)))
    2010              : 
    2011              :                         blocks_rv(2, 3)%block(1:nb, 1:na) = blocks_rv(2, 3)%block(1:nb, 1:na) + &
    2012              :                                                             MATMUL(bchint(1:nb, 1:np, bi_y), TRANSPOSE(acint(1:na, 1:np, bi_z)))
    2013              : 
    2014              :                         blocks_rv(3, 1)%block(1:nb, 1:na) = blocks_rv(3, 1)%block(1:nb, 1:na) + &
    2015              :                                                             MATMUL(bchint(1:nb, 1:np, bi_z), TRANSPOSE(acint(1:na, 1:np, bi_x)))
    2016              : 
    2017              :                         blocks_rv(3, 2)%block(1:nb, 1:na) = blocks_rv(3, 2)%block(1:nb, 1:na) + &
    2018              :                                                             MATMUL(bchint(1:nb, 1:np, bi_z), TRANSPOSE(acint(1:na, 1:np, bi_y)))
    2019              : 
    2020              :                         blocks_rv(3, 3)%block(1:nb, 1:na) = blocks_rv(3, 3)%block(1:nb, 1:na) + &
    2021              :                                                             MATMUL(bchint(1:nb, 1:np, bi_z), TRANSPOSE(acint(1:na, 1:np, bi_z)))
    2022              : 
    2023              :                         ! -r_alpha*r_beta*Vnl
    2024              :                         blocks_rv(1, 1)%block(1:nb, 1:na) = blocks_rv(1, 1)%block(1:nb, 1:na) - &
    2025              :                                                             MATMUL(bchint(1:nb, 1:np, bi_xx), TRANSPOSE(acint(1:na, 1:np, bi_1)))
    2026              : 
    2027              :                         blocks_rv(1, 2)%block(1:nb, 1:na) = blocks_rv(1, 2)%block(1:nb, 1:na) - &
    2028              :                                                             MATMUL(bchint(1:nb, 1:np, bi_xy), TRANSPOSE(acint(1:na, 1:np, bi_1)))
    2029              : 
    2030              :                         blocks_rv(1, 3)%block(1:nb, 1:na) = blocks_rv(1, 3)%block(1:nb, 1:na) - &
    2031              :                                                             MATMUL(bchint(1:nb, 1:np, bi_xz), TRANSPOSE(acint(1:na, 1:np, bi_1)))
    2032              : 
    2033              :                         blocks_rv(2, 1)%block(1:nb, 1:na) = blocks_rv(2, 1)%block(1:nb, 1:na) - &
    2034              :                                                             MATMUL(bchint(1:nb, 1:np, bi_xy), TRANSPOSE(acint(1:na, 1:np, bi_1)))
    2035              : 
    2036              :                         blocks_rv(2, 2)%block(1:nb, 1:na) = blocks_rv(2, 2)%block(1:nb, 1:na) - &
    2037              :                                                             MATMUL(bchint(1:nb, 1:np, bi_yy), TRANSPOSE(acint(1:na, 1:np, bi_1)))
    2038              : 
    2039              :                         blocks_rv(2, 3)%block(1:nb, 1:na) = blocks_rv(2, 3)%block(1:nb, 1:na) - &
    2040              :                                                             MATMUL(bchint(1:nb, 1:np, bi_yz), TRANSPOSE(acint(1:na, 1:np, bi_1)))
    2041              : 
    2042              :                         blocks_rv(3, 1)%block(1:nb, 1:na) = blocks_rv(3, 1)%block(1:nb, 1:na) - &
    2043              :                                                             MATMUL(bchint(1:nb, 1:np, bi_xz), TRANSPOSE(acint(1:na, 1:np, bi_1)))
    2044              : 
    2045              :                         blocks_rv(3, 2)%block(1:nb, 1:na) = blocks_rv(3, 2)%block(1:nb, 1:na) - &
    2046              :                                                             MATMUL(bchint(1:nb, 1:np, bi_yz), TRANSPOSE(acint(1:na, 1:np, bi_1)))
    2047              : 
    2048              :                         blocks_rv(3, 3)%block(1:nb, 1:na) = blocks_rv(3, 3)%block(1:nb, 1:na) - &
    2049              :                                                             MATMUL(bchint(1:nb, 1:np, bi_zz), TRANSPOSE(acint(1:na, 1:np, bi_1)))
    2050              : 
    2051              :                         ! -Vnl*r_beta*r_alpha
    2052              :                         blocks_rv(1, 1)%block(1:nb, 1:na) = blocks_rv(1, 1)%block(1:nb, 1:na) - &
    2053              :                                                             MATMUL(bchint(1:nb, 1:np, bi_1), TRANSPOSE(acint(1:na, 1:np, bi_xx)))
    2054              : 
    2055              :                         blocks_rv(1, 2)%block(1:nb, 1:na) = blocks_rv(1, 2)%block(1:nb, 1:na) - &
    2056              :                                                             MATMUL(bchint(1:nb, 1:np, bi_1), TRANSPOSE(acint(1:na, 1:np, bi_xy)))
    2057              : 
    2058              :                         blocks_rv(1, 3)%block(1:nb, 1:na) = blocks_rv(1, 3)%block(1:nb, 1:na) - &
    2059              :                                                             MATMUL(bchint(1:nb, 1:np, bi_1), TRANSPOSE(acint(1:na, 1:np, bi_xz)))
    2060              : 
    2061              :                         blocks_rv(2, 1)%block(1:nb, 1:na) = blocks_rv(2, 1)%block(1:nb, 1:na) - &
    2062              :                                                             MATMUL(bchint(1:nb, 1:np, bi_1), TRANSPOSE(acint(1:na, 1:np, bi_xy)))
    2063              : 
    2064              :                         blocks_rv(2, 2)%block(1:nb, 1:na) = blocks_rv(2, 2)%block(1:nb, 1:na) - &
    2065              :                                                             MATMUL(bchint(1:nb, 1:np, bi_1), TRANSPOSE(acint(1:na, 1:np, bi_yy)))
    2066              : 
    2067              :                         blocks_rv(2, 3)%block(1:nb, 1:na) = blocks_rv(2, 3)%block(1:nb, 1:na) - &
    2068              :                                                             MATMUL(bchint(1:nb, 1:np, bi_1), TRANSPOSE(acint(1:na, 1:np, bi_yz)))
    2069              : 
    2070              :                         blocks_rv(3, 1)%block(1:nb, 1:na) = blocks_rv(3, 1)%block(1:nb, 1:na) - &
    2071              :                                                             MATMUL(bchint(1:nb, 1:np, bi_1), TRANSPOSE(acint(1:na, 1:np, bi_xz)))
    2072              : 
    2073              :                         blocks_rv(3, 2)%block(1:nb, 1:na) = blocks_rv(3, 2)%block(1:nb, 1:na) - &
    2074              :                                                             MATMUL(bchint(1:nb, 1:np, bi_1), TRANSPOSE(acint(1:na, 1:np, bi_yz)))
    2075              : 
    2076              :                         blocks_rv(3, 3)%block(1:nb, 1:na) = blocks_rv(3, 3)%block(1:nb, 1:na) - &
    2077              :                                                             MATMUL(bchint(1:nb, 1:np, bi_1), TRANSPOSE(acint(1:na, 1:np, bi_zz)))
    2078              : 
    2079              :                         ! +r_beta*Vnl*r_alpha
    2080              :                         blocks_rv(1, 1)%block(1:nb, 1:na) = blocks_rv(1, 1)%block(1:nb, 1:na) + &
    2081              :                                                             MATMUL(bchint(1:nb, 1:np, bi_x), TRANSPOSE(acint(1:na, 1:np, bi_x)))
    2082              : 
    2083              :                         blocks_rv(1, 2)%block(1:nb, 1:na) = blocks_rv(1, 2)%block(1:nb, 1:na) + &
    2084              :                                                             MATMUL(bchint(1:nb, 1:np, bi_y), TRANSPOSE(acint(1:na, 1:np, bi_x)))
    2085              : 
    2086              :                         blocks_rv(1, 3)%block(1:nb, 1:na) = blocks_rv(1, 3)%block(1:nb, 1:na) + &
    2087              :                                                             MATMUL(bchint(1:nb, 1:np, bi_z), TRANSPOSE(acint(1:na, 1:np, bi_x)))
    2088              : 
    2089              :                         blocks_rv(2, 1)%block(1:nb, 1:na) = blocks_rv(2, 1)%block(1:nb, 1:na) + &
    2090              :                                                             MATMUL(bchint(1:nb, 1:np, bi_x), TRANSPOSE(acint(1:na, 1:np, bi_y)))
    2091              : 
    2092              :                         blocks_rv(2, 2)%block(1:nb, 1:na) = blocks_rv(2, 2)%block(1:nb, 1:na) + &
    2093              :                                                             MATMUL(bchint(1:nb, 1:np, bi_y), TRANSPOSE(acint(1:na, 1:np, bi_y)))
    2094              : 
    2095              :                         blocks_rv(2, 3)%block(1:nb, 1:na) = blocks_rv(2, 3)%block(1:nb, 1:na) + &
    2096              :                                                             MATMUL(bchint(1:nb, 1:np, bi_z), TRANSPOSE(acint(1:na, 1:np, bi_y)))
    2097              : 
    2098              :                         blocks_rv(3, 1)%block(1:nb, 1:na) = blocks_rv(3, 1)%block(1:nb, 1:na) + &
    2099              :                                                             MATMUL(bchint(1:nb, 1:np, bi_x), TRANSPOSE(acint(1:na, 1:np, bi_z)))
    2100              : 
    2101              :                         blocks_rv(3, 2)%block(1:nb, 1:na) = blocks_rv(3, 2)%block(1:nb, 1:na) + &
    2102              :                                                             MATMUL(bchint(1:nb, 1:np, bi_y), TRANSPOSE(acint(1:na, 1:np, bi_z)))
    2103              : 
    2104              :                         blocks_rv(3, 3)%block(1:nb, 1:na) = blocks_rv(3, 3)%block(1:nb, 1:na) + &
    2105              :                                                             MATMUL(bchint(1:nb, 1:np, bi_z), TRANSPOSE(acint(1:na, 1:np, bi_z)))
    2106              : 
    2107              :                      END IF
    2108              : !$                   CALL omp_unset_lock(locks(hash))
    2109              :                      EXIT ! We have found a match and there can be only one single match
    2110              :                   END IF
    2111              :                END DO
    2112              :             END DO
    2113              :          END DO
    2114              :          DO i = 1, 3
    2115              :             NULLIFY (blocks_rv(i, 1)%block)
    2116              :             NULLIFY (blocks_rv(i, 2)%block)
    2117              :             NULLIFY (blocks_rv(i, 3)%block)
    2118              :          END DO
    2119              :       END DO
    2120              : 
    2121              : !$OMP DO
    2122              : !$    DO lock_num = 1, nlock
    2123              : !$       call omp_destroy_lock(locks(lock_num))
    2124              : !$    END DO
    2125              : !$OMP END DO
    2126              : 
    2127              : !$OMP SINGLE
    2128              : !$    DEALLOCATE (locks)
    2129              : !$OMP END SINGLE NOWAIT
    2130              : 
    2131              : !$OMP END PARALLEL
    2132              : 
    2133            6 :       CALL release_sap_int(sap_int)
    2134              : 
    2135            6 :       DEALLOCATE (basis_set)
    2136              : 
    2137            6 :       CALL timestop(handle)
    2138              : 
    2139           18 :    END SUBROUTINE build_dcom_rpnl
    2140              : 
    2141              : ! **************************************************************************************************
    2142              : !> \brief Apply the operator \delta_\mu^\lambda to zero out all elements of the matrix
    2143              : !>         which don't fulfill the condition.
    2144              : !>        Operates on matrix_hr(1:3) instead of a single matrix
    2145              : !> \param matrix_hr ...
    2146              : !> \param qs_kind_set ...
    2147              : !> \param basis_type ...
    2148              : !> \param sab_nl ...
    2149              : !> \param deltaR ...
    2150              : !> \param direction_Or ...
    2151              : !> \author Edward Ditler
    2152              : ! **************************************************************************************************
    2153           18 :    SUBROUTINE hr_mult_by_delta_3d(matrix_hr, qs_kind_set, basis_type, sab_nl, deltaR, direction_Or)
    2154              : 
    2155              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_hr
    2156              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    2157              :       CHARACTER(LEN=*), INTENT(IN)                       :: basis_type
    2158              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    2159              :          POINTER                                         :: sab_nl
    2160              :       REAL(KIND=dp), DIMENSION(:, :)                     :: deltaR
    2161              :       LOGICAL                                            :: direction_Or
    2162              : 
    2163              :       CHARACTER(len=*), PARAMETER :: routineN = 'hr_mult_by_delta_3d'
    2164              : 
    2165              :       INTEGER                                            :: handle, iatom, icol, ikind, ir, irow, &
    2166              :                                                             jatom, jkind, ldsab, mepos, nkind, &
    2167              :                                                             nseta, nsetb, nthread
    2168              :       INTEGER, DIMENSION(3)                              :: cell
    2169           18 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, lb_max, lb_min, npgfa, &
    2170           18 :                                                             npgfb, nsgfa, nsgfb
    2171           18 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, first_sgfb
    2172              :       LOGICAL                                            :: do_symmetric, found
    2173              :       REAL(KIND=dp), DIMENSION(3)                        :: rab
    2174           18 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: set_radius_a, set_radius_b
    2175           18 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: kx_block, ky_block, kz_block, rpgfa, &
    2176           18 :                                                             rpgfb, scon_a, scon_b, sphi_a, sphi_b, &
    2177           18 :                                                             zeta, zetb
    2178           18 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set_list
    2179              :       TYPE(gto_basis_set_type), POINTER                  :: basis_set_a, basis_set_b
    2180              :       TYPE(neighbor_list_iterator_p_type), &
    2181           18 :          DIMENSION(:), POINTER                           :: nl_iterator
    2182              : 
    2183           18 :       CALL timeset(routineN, handle)
    2184              : 
    2185           18 :       nkind = SIZE(qs_kind_set)
    2186              : 
    2187              :       ! check for symmetry
    2188           18 :       CPASSERT(SIZE(sab_nl) > 0)
    2189           18 :       CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
    2190              : 
    2191              :       ! prepare basis set
    2192           90 :       ALLOCATE (basis_set_list(nkind))
    2193           18 :       CALL basis_set_list_setup(basis_set_list, basis_type, qs_kind_set)
    2194              : 
    2195              :       ! *** Allocate work storage ***
    2196           18 :       ldsab = get_memory_usage(qs_kind_set, basis_type)
    2197              : 
    2198              :       nthread = 1
    2199           18 : !$    nthread = omp_get_max_threads()
    2200              :       ! Iterate of neighbor list
    2201           18 :       CALL neighbor_list_iterator_create(nl_iterator, sab_nl, nthread=nthread)
    2202              : 
    2203              : !$OMP PARALLEL DEFAULT(NONE) &
    2204              : !$OMP SHARED (nthread,ldsab,nl_iterator, do_symmetric) &
    2205              : !$OMP SHARED (ncoset,matrix_hr,basis_set_list) &
    2206              : !$OMP SHARED (direction_or, deltar) &
    2207              : !$OMP PRIVATE (kx_block,ky_block,kz_block,mepos,ikind,jkind,iatom,jatom,rab,cell) &
    2208              : !$OMP PRIVATE (basis_set_a,basis_set_b) &
    2209              : !$OMP PRIVATE (nseta, nsetb) &
    2210              : !$OMP PRIVATE (first_sgfa, la_max, la_min, npgfa, nsgfa, rpgfa, set_radius_a, sphi_a, zeta, scon_a) &
    2211              : !$OMP PRIVATE (first_sgfb, lb_max, lb_min, npgfb, nsgfb, rpgfb, set_radius_b, sphi_b, zetb, scon_b) &
    2212           18 : !$OMP PRIVATE (irow, icol, found)
    2213              : 
    2214              :       mepos = 0
    2215              : !$    mepos = omp_get_thread_num()
    2216              : 
    2217              :       DO WHILE (neighbor_list_iterate(nl_iterator, mepos=mepos) == 0)
    2218              :          CALL get_iterator_info(nl_iterator, mepos=mepos, ikind=ikind, jkind=jkind, &
    2219              :                                 iatom=iatom, jatom=jatom, r=rab, cell=cell)
    2220              :          basis_set_a => basis_set_list(ikind)%gto_basis_set
    2221              :          IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
    2222              :          basis_set_b => basis_set_list(jkind)%gto_basis_set
    2223              :          IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
    2224              :          ! basis ikind
    2225              :          first_sgfa => basis_set_a%first_sgf
    2226              :          la_max => basis_set_a%lmax
    2227              :          la_min => basis_set_a%lmin
    2228              :          npgfa => basis_set_a%npgf
    2229              :          nsgfa => basis_set_a%nsgf_set
    2230              :          rpgfa => basis_set_a%pgf_radius
    2231              :          set_radius_a => basis_set_a%set_radius
    2232              :          sphi_a => basis_set_a%sphi
    2233              :          zeta => basis_set_a%zet
    2234              :          scon_a => basis_set_a%scon
    2235              :          ! basis jkind
    2236              :          first_sgfb => basis_set_b%first_sgf
    2237              :          lb_max => basis_set_b%lmax
    2238              :          lb_min => basis_set_b%lmin
    2239              :          npgfb => basis_set_b%npgf
    2240              :          nsgfb => basis_set_b%nsgf_set
    2241              :          rpgfb => basis_set_b%pgf_radius
    2242              :          set_radius_b => basis_set_b%set_radius
    2243              :          sphi_b => basis_set_b%sphi
    2244              :          zetb => basis_set_b%zet
    2245              :          scon_b => basis_set_b%scon
    2246              : 
    2247              :          nseta = basis_set_a%nset
    2248              :          nsetb = basis_set_b%nset
    2249              : 
    2250              :          IF (do_symmetric) THEN
    2251              :             IF (iatom <= jatom) THEN
    2252              :                irow = iatom
    2253              :                icol = jatom
    2254              :             ELSE
    2255              :                irow = jatom
    2256              :                icol = iatom
    2257              :             END IF
    2258              :          ELSE
    2259              :             irow = iatom
    2260              :             icol = jatom
    2261              :          END IF
    2262              : 
    2263              :          NULLIFY (kx_block, ky_block, kz_block)
    2264              :          CALL dbcsr_get_block_p(matrix_hr(1)%matrix, irow, icol, kx_block, found)
    2265              :          CPASSERT(found)
    2266              :          CALL dbcsr_get_block_p(matrix_hr(2)%matrix, irow, icol, ky_block, found)
    2267              :          CPASSERT(found)
    2268              :          CALL dbcsr_get_block_p(matrix_hr(3)%matrix, irow, icol, kz_block, found)
    2269              :          CPASSERT(found)
    2270              : 
    2271              :          IF (direction_Or) THEN
    2272              :             DO ir = 1, 3
    2273              : !$OMP CRITICAL(blockadd)
    2274              :                SELECT CASE (ir)
    2275              :                CASE (1)
    2276              :                   kx_block(:, :) = kx_block(:, :)*deltaR(ir, jatom)
    2277              :                CASE (2)
    2278              :                   ky_block(:, :) = ky_block(:, :)*deltaR(ir, jatom)
    2279              :                CASE (3)
    2280              :                   kz_block(:, :) = kz_block(:, :)*deltaR(ir, jatom)
    2281              :                END SELECT
    2282              : !$OMP END CRITICAL(blockadd)
    2283              :             END DO
    2284              :          ELSE
    2285              :             DO ir = 1, 3
    2286              : !$OMP CRITICAL(blockadd)
    2287              :                SELECT CASE (ir)
    2288              :                CASE (1)
    2289              :                   kx_block(:, :) = kx_block(:, :)*deltaR(ir, iatom)
    2290              :                CASE (2)
    2291              :                   ky_block(:, :) = ky_block(:, :)*deltaR(ir, iatom)
    2292              :                CASE (3)
    2293              :                   kz_block(:, :) = kz_block(:, :)*deltaR(ir, iatom)
    2294              :                END SELECT
    2295              : !$OMP END CRITICAL(blockadd)
    2296              :             END DO
    2297              :          END IF
    2298              :       END DO
    2299              : !$OMP END PARALLEL
    2300           18 :       CALL neighbor_list_iterator_release(nl_iterator)
    2301              : 
    2302              :       ! Release work storage
    2303           18 :       DEALLOCATE (basis_set_list)
    2304              : 
    2305           18 :       CALL timestop(handle)
    2306              : 
    2307           36 :    END SUBROUTINE hr_mult_by_delta_3d
    2308              : 
    2309         1026 : END MODULE qs_vcd_ao
        

Generated by: LCOV version 2.0-1