LCOV - code coverage report
Current view: top level - src - commutator_rpnl.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:71c3ab0) Lines: 51.3 % 199 102
Test Date: 2026-07-25 06:35:44 Functions: 50.0 % 4 2

            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              : ! **************************************************************************************************
       8              : !> \brief Calculation of the non-local pseudopotential contribution to the core Hamiltonian
       9              : !>         <a|V(non-local)|b> = <a|p(l,i)>*h(i,j)*<p(l,j)|b>
      10              : !> \par History
      11              : !>      - refactered from qs_core_hamiltian [Joost VandeVondele, 2008-11-01]
      12              : !>      - full rewrite [jhu, 2009-01-23]
      13              : ! **************************************************************************************************
      14              : MODULE commutator_rpnl
      15              :    USE ai_moments,                      ONLY: moment
      16              :    USE ai_overlap,                      ONLY: overlap
      17              :    USE basis_set_types,                 ONLY: gto_basis_set_p_type,&
      18              :                                               gto_basis_set_type
      19              :    USE block_p_types,                   ONLY: block_p_type
      20              :    USE cell_types,                      ONLY: cell_type
      21              :    USE cp_dbcsr_api,                    ONLY: dbcsr_get_block_p,&
      22              :                                               dbcsr_p_type
      23              :    USE external_potential_types,        ONLY: gth_potential_p_type,&
      24              :                                               gth_potential_type,&
      25              :                                               sgp_potential_p_type,&
      26              :                                               sgp_potential_type
      27              :    USE kinds,                           ONLY: dp
      28              :    USE orbital_pointers,                ONLY: init_orbital_pointers,&
      29              :                                               nco,&
      30              :                                               ncoset
      31              :    USE particle_types,                  ONLY: particle_type
      32              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      33              :                                               get_qs_kind_set,&
      34              :                                               qs_kind_type
      35              :    USE qs_neighbor_list_types,          ONLY: get_iterator_info,&
      36              :                                               get_neighbor_list_set_p,&
      37              :                                               neighbor_list_iterate,&
      38              :                                               neighbor_list_iterator_create,&
      39              :                                               neighbor_list_iterator_p_type,&
      40              :                                               neighbor_list_iterator_release,&
      41              :                                               neighbor_list_set_p_type
      42              :    USE sap_kind_types,                  ONLY: alist_type,&
      43              :                                               build_sap_ints,&
      44              :                                               clist_type,&
      45              :                                               get_alist,&
      46              :                                               release_sap_int,&
      47              :                                               sap_int_type,&
      48              :                                               sap_sort
      49              : 
      50              : !$ USE OMP_LIB, ONLY: omp_get_max_threads, omp_get_thread_num, omp_get_num_threads
      51              : !$ USE OMP_LIB, ONLY: omp_lock_kind, &
      52              : !$                    omp_init_lock, omp_set_lock, &
      53              : !$                    omp_unset_lock, omp_destroy_lock
      54              : 
      55              : #include "./base/base_uses.f90"
      56              : 
      57              :    IMPLICIT NONE
      58              : 
      59              :    PRIVATE
      60              : 
      61              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'commutator_rpnl'
      62              : 
      63              :    PUBLIC :: build_com_rpnl, build_com_mom_nl, build_com_nl_mag, build_com_vnl_giao
      64              : 
      65              : CONTAINS
      66              : 
      67              : ! **************************************************************************************************
      68              : !> \brief ...
      69              : !> \param matrix_rv ...
      70              : !> \param qs_kind_set ...
      71              : !> \param sab_orb ...
      72              : !> \param sap_ppnl ...
      73              : !> \param eps_ppnl ...
      74              : ! **************************************************************************************************
      75            0 :    SUBROUTINE build_com_rpnl(matrix_rv, qs_kind_set, sab_orb, sap_ppnl, eps_ppnl)
      76              : 
      77              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_rv
      78              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
      79              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
      80              :          POINTER                                         :: sab_orb, sap_ppnl
      81              :       REAL(KIND=dp), INTENT(IN)                          :: eps_ppnl
      82              : 
      83              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'build_com_rpnl'
      84              : 
      85              :       INTEGER :: handle, i, iab, iac, iatom, ibc, icol, ikind, ilist, inode, irow, iset, jatom, &
      86              :          jkind, jneighbor, kac, katom, kbc, kkind, l, lc_max, lc_min, ldai, ldsab, lppnl, maxco, &
      87              :          maxder, maxl, maxlgto, maxlppnl, maxppnl, maxsgf, mepos, na, nb, ncoa, ncoc, nkind, &
      88              :          nlist, nneighbor, nnode, np, nppnl, nprjc, nseta, nsgfa, nthread, prjc, sgfa
      89              :       INTEGER, DIMENSION(3)                              :: cell_b, cell_c
      90            0 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, npgfa, nprj_ppnl, &
      91            0 :                                                             nsgf_seta
      92            0 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa
      93              :       LOGICAL                                            :: found, gpot, ppnl_present, spot
      94              :       REAL(KIND=dp)                                      :: dac, ppnl_radius
      95            0 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: ai_work, sab, work
      96              :       REAL(KIND=dp), DIMENSION(1)                        :: rprjc, zetc
      97              :       REAL(KIND=dp), DIMENSION(3)                        :: rab, rac
      98            0 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: alpha_ppnl, set_radius_a
      99            0 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: cprj, rpgfa, sphi_a, vprj_ppnl, x_block, &
     100            0 :                                                             y_block, z_block, zeta
     101            0 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: achint, acint, bchint, bcint
     102              :       TYPE(alist_type), POINTER                          :: alist_ac, alist_bc
     103              :       TYPE(clist_type), POINTER                          :: clist
     104            0 :       TYPE(gth_potential_p_type), DIMENSION(:), POINTER  :: gpotential
     105              :       TYPE(gth_potential_type), POINTER                  :: gth_potential
     106            0 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set
     107              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
     108              :       TYPE(neighbor_list_iterator_p_type), &
     109            0 :          DIMENSION(:), POINTER                           :: nl_iterator
     110            0 :       TYPE(sap_int_type), DIMENSION(:), POINTER          :: sap_int
     111            0 :       TYPE(sgp_potential_p_type), DIMENSION(:), POINTER  :: spotential
     112              :       TYPE(sgp_potential_type), POINTER                  :: sgp_potential
     113              : 
     114            0 :       CALL timeset(routineN, handle)
     115              : 
     116            0 :       ppnl_present = ASSOCIATED(sap_ppnl)
     117              : 
     118            0 :       IF (ppnl_present) THEN
     119              : 
     120            0 :          nkind = SIZE(qs_kind_set)
     121              : 
     122              :          CALL get_qs_kind_set(qs_kind_set, &
     123              :                               maxco=maxco, &
     124              :                               maxlgto=maxlgto, &
     125              :                               maxsgf=maxsgf, &
     126              :                               maxlppnl=maxlppnl, &
     127            0 :                               maxppnl=maxppnl)
     128              : 
     129            0 :          maxl = MAX(maxlgto, maxlppnl)
     130            0 :          CALL init_orbital_pointers(maxl + 1)
     131              : 
     132            0 :          ldsab = MAX(maxco, ncoset(maxlppnl), maxsgf, maxppnl)
     133            0 :          ldai = ncoset(maxl + 1)
     134              : 
     135              :          !sap_int needs to be shared as multiple threads need to access this
     136            0 :          ALLOCATE (sap_int(nkind*nkind))
     137            0 :          DO i = 1, nkind*nkind
     138            0 :             NULLIFY (sap_int(i)%alist, sap_int(i)%asort, sap_int(i)%aindex)
     139            0 :             sap_int(i)%nalist = 0
     140              :          END DO
     141              : 
     142              :          !set up direct access to basis and potential
     143            0 :          ALLOCATE (basis_set(nkind), gpotential(nkind), spotential(nkind))
     144            0 :          DO ikind = 1, nkind
     145            0 :             CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
     146            0 :             IF (ASSOCIATED(orb_basis_set)) THEN
     147            0 :                basis_set(ikind)%gto_basis_set => orb_basis_set
     148              :             ELSE
     149            0 :                NULLIFY (basis_set(ikind)%gto_basis_set)
     150              :             END IF
     151              :             CALL get_qs_kind(qs_kind_set(ikind), gth_potential=gth_potential, &
     152            0 :                              sgp_potential=sgp_potential)
     153            0 :             IF (ASSOCIATED(gth_potential)) THEN
     154            0 :                gpotential(ikind)%gth_potential => gth_potential
     155            0 :                NULLIFY (spotential(ikind)%sgp_potential)
     156            0 :             ELSE IF (ASSOCIATED(sgp_potential)) THEN
     157            0 :                spotential(ikind)%sgp_potential => sgp_potential
     158            0 :                NULLIFY (gpotential(ikind)%gth_potential)
     159              :             ELSE
     160            0 :                NULLIFY (gpotential(ikind)%gth_potential)
     161            0 :                NULLIFY (spotential(ikind)%sgp_potential)
     162              :             END IF
     163              :          END DO
     164              : 
     165            0 :          maxder = 4
     166              :          nthread = 1
     167            0 : !$       nthread = omp_get_max_threads()
     168              : 
     169              :          !calculate the overlap integrals <a|p>
     170            0 :          CALL neighbor_list_iterator_create(nl_iterator, sap_ppnl, nthread=nthread)
     171              : !$OMP PARALLEL &
     172              : !$OMP DEFAULT (NONE) &
     173              : !$OMP SHARED  (nl_iterator, basis_set, spotential, gpotential, maxder, ncoset, &
     174              : !$OMP          sap_int, nkind, ldsab,  ldai, nco ) &
     175              : !$OMP PRIVATE (mepos, ikind, kkind, iatom, katom, nlist, ilist, nneighbor, jneighbor, &
     176              : !$OMP          cell_c, rac, iac, first_sgfa, la_max, la_min, npgfa, nseta, nsgfa, nsgf_seta, &
     177              : !$OMP          sphi_a, zeta, cprj, lppnl, nppnl, nprj_ppnl, &
     178              : !$OMP          clist, iset, ncoa, sgfa, prjc, work, sab, ai_work, nprjc,  ppnl_radius, &
     179              : !$OMP          ncoc, rpgfa, vprj_ppnl, i, l, gpot, spot, &
     180            0 : !$OMP          set_radius_a, rprjc, dac, lc_max, lc_min, zetc, alpha_ppnl)
     181              :          mepos = 0
     182              : !$       mepos = omp_get_thread_num()
     183              : 
     184              :          ALLOCATE (sab(ldsab, ldsab, maxder), work(ldsab, ldsab, maxder))
     185              :          sab = 0.0_dp
     186              :          ALLOCATE (ai_work(ldai, ldai, 1))
     187              :          ai_work = 0.0_dp
     188              : 
     189              :          DO WHILE (neighbor_list_iterate(nl_iterator, mepos=mepos) == 0)
     190              :             CALL get_iterator_info(nl_iterator, mepos=mepos, ikind=ikind, jkind=kkind, iatom=iatom, &
     191              :                                    jatom=katom, nlist=nlist, ilist=ilist, nnode=nneighbor, inode=jneighbor, cell=cell_c, r=rac)
     192              :             iac = ikind + nkind*(kkind - 1)
     193              :             IF (.NOT. ASSOCIATED(basis_set(ikind)%gto_basis_set)) CYCLE
     194              :             gpot = ASSOCIATED(gpotential(kkind)%gth_potential)
     195              :             spot = ASSOCIATED(spotential(kkind)%sgp_potential)
     196              :             IF ((.NOT. gpot) .AND. (.NOT. spot)) CYCLE
     197              :             ! get definition of basis set
     198              :             first_sgfa => basis_set(ikind)%gto_basis_set%first_sgf
     199              :             la_max => basis_set(ikind)%gto_basis_set%lmax
     200              :             la_min => basis_set(ikind)%gto_basis_set%lmin
     201              :             npgfa => basis_set(ikind)%gto_basis_set%npgf
     202              :             nseta = basis_set(ikind)%gto_basis_set%nset
     203              :             nsgfa = basis_set(ikind)%gto_basis_set%nsgf
     204              :             nsgf_seta => basis_set(ikind)%gto_basis_set%nsgf_set
     205              :             rpgfa => basis_set(ikind)%gto_basis_set%pgf_radius
     206              :             set_radius_a => basis_set(ikind)%gto_basis_set%set_radius
     207              :             sphi_a => basis_set(ikind)%gto_basis_set%sphi
     208              :             zeta => basis_set(ikind)%gto_basis_set%zet
     209              :             nsgfa = basis_set(ikind)%gto_basis_set%nsgf
     210              : 
     211              :             ! get definition of PP projectors
     212              :             IF (gpot) THEN
     213              :                alpha_ppnl => gpotential(kkind)%gth_potential%alpha_ppnl
     214              :                cprj => gpotential(kkind)%gth_potential%cprj
     215              :                lppnl = gpotential(kkind)%gth_potential%lppnl
     216              :                nppnl = gpotential(kkind)%gth_potential%nppnl
     217              :                nprj_ppnl => gpotential(kkind)%gth_potential%nprj_ppnl
     218              :                ppnl_radius = gpotential(kkind)%gth_potential%ppnl_radius
     219              :                vprj_ppnl => gpotential(kkind)%gth_potential%vprj_ppnl
     220              :             ELSE IF (spot) THEN
     221              :                CPABORT('SGP not implemented')
     222              :             ELSE
     223              :                CPABORT('PPNL unknown')
     224              :             END IF
     225              : !$OMP CRITICAL(sap_int_critical)
     226              :             IF (.NOT. ASSOCIATED(sap_int(iac)%alist)) THEN
     227              :                sap_int(iac)%a_kind = ikind
     228              :                sap_int(iac)%p_kind = kkind
     229              :                sap_int(iac)%nalist = nlist
     230              :                ALLOCATE (sap_int(iac)%alist(nlist))
     231              :                DO i = 1, nlist
     232              :                   NULLIFY (sap_int(iac)%alist(i)%clist)
     233              :                   sap_int(iac)%alist(i)%aatom = 0
     234              :                   sap_int(iac)%alist(i)%nclist = 0
     235              :                END DO
     236              :             END IF
     237              :             IF (.NOT. ASSOCIATED(sap_int(iac)%alist(ilist)%clist)) THEN
     238              :                sap_int(iac)%alist(ilist)%aatom = iatom
     239              :                sap_int(iac)%alist(ilist)%nclist = nneighbor
     240              :                ALLOCATE (sap_int(iac)%alist(ilist)%clist(nneighbor))
     241              :                DO i = 1, nneighbor
     242              :                   sap_int(iac)%alist(ilist)%clist(i)%catom = 0
     243              :                END DO
     244              :             END IF
     245              : !$OMP END CRITICAL(sap_int_critical)
     246              :             dac = SQRT(SUM(rac*rac))
     247              :             clist => sap_int(iac)%alist(ilist)%clist(jneighbor)
     248              :             clist%catom = katom
     249              :             clist%cell = cell_c
     250              :             clist%rac = rac
     251              :             ALLOCATE (clist%acint(nsgfa, nppnl, maxder), &
     252              :                       clist%achint(nsgfa, nppnl, maxder))
     253              :             clist%acint = 0._dp
     254              :             clist%achint = 0._dp
     255              :             clist%nsgf_cnt = 0
     256              :             NULLIFY (clist%sgf_list)
     257              :             DO iset = 1, nseta
     258              :                ncoa = npgfa(iset)*ncoset(la_max(iset))
     259              :                sgfa = first_sgfa(1, iset)
     260              :                work = 0._dp
     261              :                prjc = 1
     262              :                DO l = 0, lppnl
     263              :                   nprjc = nprj_ppnl(l)*nco(l)
     264              :                   IF (nprjc == 0) CYCLE
     265              :                   rprjc(1) = ppnl_radius
     266              :                   IF (set_radius_a(iset) + rprjc(1) < dac) CYCLE
     267              :                   lc_max = l + 2*(nprj_ppnl(l) - 1)
     268              :                   lc_min = l
     269              :                   zetc(1) = alpha_ppnl(l)
     270              :                   ncoc = ncoset(lc_max)
     271              :                   ! Calculate the primitive overlap and dipole moment integrals
     272              :                   CALL overlap(la_max(iset), la_min(iset), npgfa(iset), rpgfa(:, iset), zeta(:, iset), &
     273              :                                lc_max, lc_min, 1, rprjc, zetc, rac, dac, sab(:, :, 1), 0, .FALSE., ai_work, ldai)
     274              :                   CALL moment(la_max(iset), npgfa(iset), zeta(:, iset), rpgfa(:, iset), la_min(iset), &
     275              :                               lc_max, 1, zetc, rprjc, 1, rac, [0._dp, 0._dp, 0._dp], sab(:, :, 2:4))
     276              :                   ! *** Transformation step projector functions (cartesian->spherical) ***
     277              :                   DO i = 1, maxder
     278              :                      CALL dgemm("N", "N", ncoa, nprjc, ncoc, 1.0_dp, sab(1, 1, i), ldsab, &
     279              :                                 cprj(1, prjc), SIZE(cprj, 1), 0.0_dp, work(1, 1, i), ldsab)
     280              :                   END DO
     281              :                   prjc = prjc + nprjc
     282              :                END DO
     283              :                DO i = 1, maxder
     284              :                   ! Contraction step (basis functions)
     285              :                   CALL dgemm("T", "N", nsgf_seta(iset), nppnl, ncoa, 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
     286              :                              work(1, 1, i), ldsab, 0.0_dp, clist%acint(sgfa, 1, i), nsgfa)
     287              :                   ! Multiply with interaction matrix(h)
     288              :                   CALL dgemm("N", "N", nsgf_seta(iset), nppnl, nppnl, 1.0_dp, clist%acint(sgfa, 1, i), nsgfa, &
     289              :                              vprj_ppnl(1, 1), SIZE(vprj_ppnl, 1), 0.0_dp, clist%achint(sgfa, 1, i), nsgfa)
     290              :                END DO
     291              :             END DO
     292              :             clist%maxac = MAXVAL(ABS(clist%acint(:, :, 1)))
     293              :             clist%maxach = MAXVAL(ABS(clist%achint(:, :, 1)))
     294              :          END DO
     295              : 
     296              :          DEALLOCATE (sab, ai_work, work)
     297              : !$OMP END PARALLEL
     298            0 :          CALL neighbor_list_iterator_release(nl_iterator)
     299              : 
     300              :          ! *** Set up a sorting index
     301            0 :          CALL sap_sort(sap_int)
     302              :          ! *** All integrals needed have been calculated and stored in sap_int
     303              :          ! *** We now calculate the Hamiltonian matrix elements
     304            0 :          CALL neighbor_list_iterator_create(nl_iterator, sab_orb, nthread=nthread)
     305              : 
     306              : !$OMP PARALLEL &
     307              : !$OMP DEFAULT (NONE) &
     308              : !$OMP SHARED  (nl_iterator, basis_set, matrix_rv, &
     309              : !$OMP          sap_int, nkind, eps_ppnl ) &
     310              : !$OMP PRIVATE (mepos, ikind, jkind, iatom, jatom, nlist, ilist, nnode, inode, cell_b, rab, &
     311              : !$OMP          iab, irow, icol, x_block, y_block, z_block, &
     312              : !$OMP          found, iac, ibc, alist_ac, alist_bc, acint, bcint, &
     313            0 : !$OMP          achint, bchint, na, np, nb, katom, rac, kkind, kac, kbc, i)
     314              : 
     315              :          mepos = 0
     316              : !$       mepos = omp_get_thread_num()
     317              : 
     318              :          DO WHILE (neighbor_list_iterate(nl_iterator, mepos=mepos) == 0)
     319              :             CALL get_iterator_info(nl_iterator, mepos=mepos, ikind=ikind, jkind=jkind, iatom=iatom, &
     320              :                                    jatom=jatom, nlist=nlist, ilist=ilist, nnode=nnode, inode=inode, cell=cell_b, r=rab)
     321              :             IF (.NOT. ASSOCIATED(basis_set(ikind)%gto_basis_set)) CYCLE
     322              :             IF (.NOT. ASSOCIATED(basis_set(jkind)%gto_basis_set)) CYCLE
     323              :             iab = ikind + nkind*(jkind - 1)
     324              : 
     325              :             ! *** Create matrix blocks for a new matrix block column ***
     326              :             IF (iatom <= jatom) THEN
     327              :                irow = iatom
     328              :                icol = jatom
     329              :             ELSE
     330              :                irow = jatom
     331              :                icol = iatom
     332              :             END IF
     333              :             CALL dbcsr_get_block_p(matrix_rv(1)%matrix, irow, icol, x_block, found)
     334              :             CALL dbcsr_get_block_p(matrix_rv(2)%matrix, irow, icol, y_block, found)
     335              :             CALL dbcsr_get_block_p(matrix_rv(3)%matrix, irow, icol, z_block, found)
     336              : 
     337              :             ! loop over all kinds for projector atom
     338              :             IF (ASSOCIATED(x_block) .AND. ASSOCIATED(y_block) .AND. ASSOCIATED(z_block)) THEN
     339              :                DO kkind = 1, nkind
     340              :                   iac = ikind + nkind*(kkind - 1)
     341              :                   ibc = jkind + nkind*(kkind - 1)
     342              :                   IF (.NOT. ASSOCIATED(sap_int(iac)%alist)) CYCLE
     343              :                   IF (.NOT. ASSOCIATED(sap_int(ibc)%alist)) CYCLE
     344              :                   CALL get_alist(sap_int(iac), alist_ac, iatom)
     345              :                   CALL get_alist(sap_int(ibc), alist_bc, jatom)
     346              :                   IF (.NOT. ASSOCIATED(alist_ac)) CYCLE
     347              :                   IF (.NOT. ASSOCIATED(alist_bc)) CYCLE
     348              :                   DO kac = 1, alist_ac%nclist
     349              :                      DO kbc = 1, alist_bc%nclist
     350              :                         IF (alist_ac%clist(kac)%catom /= alist_bc%clist(kbc)%catom) CYCLE
     351              :                         IF (ALL(cell_b + alist_bc%clist(kbc)%cell - alist_ac%clist(kac)%cell == 0)) THEN
     352              :                            IF (alist_ac%clist(kac)%maxac*alist_bc%clist(kbc)%maxach < eps_ppnl) CYCLE
     353              :                            acint => alist_ac%clist(kac)%acint
     354              :                            bcint => alist_bc%clist(kbc)%acint
     355              :                            achint => alist_ac%clist(kac)%achint
     356              :                            bchint => alist_bc%clist(kbc)%achint
     357              :                            na = SIZE(acint, 1)
     358              :                            np = SIZE(acint, 2)
     359              :                            nb = SIZE(bcint, 1)
     360              : !$OMP CRITICAL(h_block_critical)
     361              :                            IF (iatom <= jatom) THEN
     362              :                               ! Vnl*r
     363              :                               CALL dgemm("N", "T", na, nb, np, 1._dp, achint(1, 1, 1), na, &
     364              :                                          bcint(1, 1, 2), nb, 1.0_dp, x_block, SIZE(x_block, 1))
     365              :                               CALL dgemm("N", "T", na, nb, np, 1._dp, achint(1, 1, 1), na, &
     366              :                                          bcint(1, 1, 3), nb, 1.0_dp, y_block, SIZE(y_block, 1))
     367              :                               CALL dgemm("N", "T", na, nb, np, 1._dp, achint(1, 1, 1), na, &
     368              :                                          bcint(1, 1, 4), nb, 1.0_dp, z_block, SIZE(z_block, 1))
     369              :                               ! -r*Vnl
     370              :                               CALL dgemm("N", "T", na, nb, np, -1._dp, achint(1, 1, 2), na, &
     371              :                                          bcint(1, 1, 1), nb, 1.0_dp, x_block, SIZE(x_block, 1))
     372              :                               CALL dgemm("N", "T", na, nb, np, -1._dp, achint(1, 1, 3), na, &
     373              :                                          bcint(1, 1, 1), nb, 1.0_dp, y_block, SIZE(y_block, 1))
     374              :                               CALL dgemm("N", "T", na, nb, np, -1._dp, achint(1, 1, 4), na, &
     375              :                                          bcint(1, 1, 1), nb, 1.0_dp, z_block, SIZE(z_block, 1))
     376              :                            ELSE
     377              :                               ! Vnl*r
     378              :                               CALL dgemm("N", "T", nb, na, np, 1.0_dp, bchint(1, 1, 2), nb, &
     379              :                                          acint(1, 1, 1), na, 1.0_dp, x_block, SIZE(x_block, 1))
     380              :                               CALL dgemm("N", "T", nb, na, np, 1.0_dp, bchint(1, 1, 3), nb, &
     381              :                                          acint(1, 1, 1), na, 1.0_dp, y_block, SIZE(y_block, 1))
     382              :                               CALL dgemm("N", "T", nb, na, np, 1.0_dp, bchint(1, 1, 4), nb, &
     383              :                                          acint(1, 1, 1), na, 1.0_dp, z_block, SIZE(z_block, 1))
     384              :                               ! -r*Vnl
     385              :                               CALL dgemm("N", "T", nb, na, np, -1.0_dp, bchint(1, 1, 1), nb, &
     386              :                                          acint(1, 1, 2), na, 1.0_dp, x_block, SIZE(x_block, 1))
     387              :                               CALL dgemm("N", "T", nb, na, np, -1.0_dp, bchint(1, 1, 1), nb, &
     388              :                                          acint(1, 1, 3), na, 1.0_dp, y_block, SIZE(y_block, 1))
     389              :                               CALL dgemm("N", "T", nb, na, np, -1.0_dp, bchint(1, 1, 1), nb, &
     390              :                                          acint(1, 1, 4), na, 1.0_dp, z_block, SIZE(z_block, 1))
     391              :                            END IF
     392              : !$OMP END CRITICAL(h_block_critical)
     393              :                            EXIT ! We have found a match and there can be only one single match
     394              :                         END IF
     395              :                      END DO
     396              :                   END DO
     397              :                END DO
     398              :             END IF
     399              :          END DO
     400              : !$OMP END PARALLEL
     401            0 :          CALL neighbor_list_iterator_release(nl_iterator)
     402              : 
     403            0 :          CALL release_sap_int(sap_int)
     404              : 
     405            0 :          DEALLOCATE (basis_set, gpotential, spotential)
     406              : 
     407              :       END IF !ppnl_present
     408              : 
     409            0 :       CALL timestop(handle)
     410              : 
     411            0 :    END SUBROUTINE build_com_rpnl
     412              : 
     413              : ! **************************************************************************************************
     414              : !> \brief Calculate [r,Vnl] (matrix_rv), r x [r,Vnl] (matrix_rxrv)
     415              : !>        or [rr,Vnl] (matrix_rrv) in AO basis.
     416              : !>        Reference point is required for the two latter options
     417              : !>        Update: Calculate rxVnlxr (matrix_rvr) and rxrxVnl + Vnlxrxr (matrix_rrv_vrr)
     418              : !>        in AO basis. Added in the first place for current correction in
     419              : !>        the VG formalism (first order wrt vector potential).
     420              : !> \param qs_kind_set ...
     421              : !> \param sab_all ...
     422              : !> \param sap_ppnl ...
     423              : !> \param eps_ppnl ...
     424              : !> \param particle_set ...
     425              : !> \param cell ...
     426              : !> \param matrix_rv ...
     427              : !> \param matrix_rxrv ...
     428              : !> \param matrix_rrv ...
     429              : !> \param matrix_rvr ...
     430              : !> \param matrix_rrv_vrr ...
     431              : !> \param matrix_r_rxvr ...
     432              : !> \param matrix_rxvr_r ...
     433              : !> \param matrix_r_doublecom ...
     434              : !> \param pseudoatom ...
     435              : !> \param ref_point ...
     436              : ! **************************************************************************************************
     437          196 :    SUBROUTINE build_com_mom_nl(qs_kind_set, sab_all, sap_ppnl, eps_ppnl, particle_set, cell, matrix_rv, matrix_rxrv, &
     438          294 :                     matrix_rrv, matrix_rvr, matrix_rrv_vrr, matrix_r_rxvr, matrix_rxvr_r, matrix_r_doublecom, pseudoatom, ref_point)
     439              : 
     440              :       TYPE(qs_kind_type), DIMENSION(:), INTENT(IN), &
     441              :          POINTER                                         :: qs_kind_set
     442              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     443              :          INTENT(IN), POINTER                             :: sab_all, sap_ppnl
     444              :       REAL(KIND=dp), INTENT(IN)                          :: eps_ppnl
     445              :       TYPE(particle_type), DIMENSION(:), INTENT(IN), &
     446              :          POINTER                                         :: particle_set
     447              :       TYPE(cell_type), INTENT(IN), POINTER               :: cell
     448              :       TYPE(dbcsr_p_type), DIMENSION(:), INTENT(INOUT), &
     449              :          OPTIONAL                                        :: matrix_rv, matrix_rxrv, matrix_rrv, &
     450              :                                                             matrix_rvr, matrix_rrv_vrr
     451              :       TYPE(dbcsr_p_type), DIMENSION(:, :), &
     452              :          INTENT(INOUT), OPTIONAL                         :: matrix_r_rxvr, matrix_rxvr_r, &
     453              :                                                             matrix_r_doublecom
     454              :       INTEGER, INTENT(in), OPTIONAL                      :: pseudoatom
     455              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN), OPTIONAL  :: ref_point
     456              : 
     457              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'build_com_mom_nl'
     458              :       INTEGER, PARAMETER :: i_x = 2, i_xx = 5, i_xy = 6, i_xz = 7, i_y = 3, i_yx = i_xy, i_yy = 8, &
     459              :          i_yz = 9, i_z = 4, i_zx = i_xz, i_zy = i_yz, i_zz = 10
     460              : 
     461              :       INTEGER                                            :: handle, i, iab, iac, iatom, ibc, icol, &
     462              :                                                             ikind, ind, ind2, irow, jatom, jkind, &
     463              :                                                             kac, kbc, kkind, na, natom, nb, nkind, &
     464              :                                                             np, order, slot
     465              :       INTEGER, DIMENSION(3)                              :: cell_b
     466              :       LOGICAL :: asso_r_doublecom, asso_r_rxvr, asso_rrv, asso_rrv_vrr, asso_rv, asso_rvr, &
     467              :          asso_rxrv, asso_rxvr_r, do_symmetric, found, go, my_r_doublecom, my_r_rxvr, my_ref, &
     468              :          my_rrv, my_rrv_vrr, my_rv, my_rvr, my_rxrv, my_rxvr_r, periodic, ppnl_present
     469              :       REAL(KIND=dp), DIMENSION(3)                        :: rab, rf
     470           98 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: achint, acint, bchint, bcint
     471              :       TYPE(alist_type), POINTER                          :: alist_ac, alist_bc
     472           98 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:)      :: blocks_rrv, blocks_rrv_vrr, blocks_rv, &
     473           98 :                                                             blocks_rvr, blocks_rxrv
     474           98 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:, :)   :: blocks_r_doublecom, blocks_r_rxvr, &
     475           98 :                                                             blocks_rxvr_r
     476              :       TYPE(gto_basis_set_p_type), ALLOCATABLE, &
     477           98 :          DIMENSION(:)                                    :: basis_set
     478              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
     479           98 :       TYPE(sap_int_type), DIMENSION(:), POINTER          :: sap_int
     480              : 
     481              : !$    INTEGER(kind=omp_lock_kind), &
     482           98 : !$       ALLOCATABLE, DIMENSION(:) :: locks
     483              : !$    INTEGER                                            :: lock_num, hash
     484              : !$    INTEGER, PARAMETER                                 :: nlock = 501
     485              : 
     486           98 :       ppnl_present = ASSOCIATED(sap_ppnl)
     487           98 :       IF (.NOT. ppnl_present) RETURN
     488              : 
     489           76 :       CALL timeset(routineN, handle)
     490              : 
     491           76 :       my_r_doublecom = .FALSE.
     492           76 :       my_r_rxvr = .FALSE.
     493           76 :       my_rxvr_r = .FALSE.
     494           76 :       my_rxrv = .FALSE.
     495           76 :       my_rrv = .FALSE.
     496           76 :       my_rv = .FALSE.
     497           76 :       my_rvr = .FALSE.
     498           76 :       my_rrv_vrr = .FALSE.
     499           76 :       IF (PRESENT(matrix_r_doublecom)) my_r_doublecom = .TRUE.
     500           76 :       IF (PRESENT(matrix_r_rxvr)) my_r_rxvr = .TRUE.
     501           76 :       IF (PRESENT(matrix_rxvr_r)) my_rxvr_r = .TRUE.
     502           76 :       IF (PRESENT(matrix_rxrv)) my_rxrv = .TRUE.
     503           76 :       IF (PRESENT(matrix_rrv)) my_rrv = .TRUE.
     504           76 :       IF (PRESENT(matrix_rv)) my_rv = .TRUE.
     505           76 :       IF (PRESENT(matrix_rvr)) my_rvr = .TRUE.
     506           76 :       IF (PRESENT(matrix_rrv_vrr)) my_rrv_vrr = .TRUE.
     507           76 :       IF (.NOT. (my_rv .OR. my_rxrv .OR. my_rrv .OR. my_rvr .OR. my_rrv_vrr .OR. my_r_rxvr .OR. my_rxvr_r .OR. my_r_doublecom)) THEN
     508            0 :          CPABORT('No dbcsr matrix provided for commutator calculation!')
     509              :       END IF
     510              : 
     511           76 :       natom = SIZE(particle_set)
     512              : 
     513           76 :       IF (my_rxrv .OR. my_rrv .OR. my_r_rxvr .OR. my_rxvr_r .OR. my_r_doublecom) THEN
     514           48 :          order = 2
     515           48 :          CPASSERT(PRESENT(ref_point)) ! need reference point for r x [r,Vnl] and [rr,Vnl]
     516           28 :       ELSE IF (my_rvr .OR. my_rrv_vrr) THEN
     517            6 :          order = 2
     518              :       ELSE
     519           22 :          order = 1
     520              :       END IF
     521              : 
     522              :       ! When we want the double commutator [[Vnl, r], r], we also want to fix the pseudoatom
     523           76 :       IF (my_r_doublecom) THEN
     524            6 :          CPASSERT(PRESENT(pseudoatom))
     525              :       END IF
     526              : 
     527          184 :       periodic = ANY(cell%perd > 0)
     528           76 :       my_ref = .FALSE.
     529           76 :       IF (PRESENT(ref_point)) THEN
     530           54 :          IF (.NOT. periodic) THEN
     531           18 :             rf = ref_point
     532           18 :             my_ref = .TRUE.
     533              :          ELSE ! use my_ref = False in periodic case, corresponds to distributed ref point
     534           36 :             IF (order > 1) THEN
     535           36 :                CPWARN("Not clear how to define reference point for order > 1 in periodic cells.")
     536              :             END IF
     537              :          END IF
     538              :       END IF
     539              : 
     540           76 :       nkind = SIZE(qs_kind_set)
     541              : 
     542              :       !sap_int needs to be shared as multiple threads need to access this
     543           76 :       NULLIFY (sap_int)
     544          724 :       ALLOCATE (sap_int(nkind*nkind))
     545          572 :       DO i = 1, nkind*nkind
     546          496 :          NULLIFY (sap_int(i)%alist, sap_int(i)%asort, sap_int(i)%aindex)
     547          572 :          sap_int(i)%nalist = 0
     548              :       END DO
     549              : 
     550           76 :       IF (my_ref) THEN
     551              :          ! calculate integrals <a|x^n|p>
     552              :          CALL build_sap_ints(sap_int, sap_ppnl, qs_kind_set, order, moment_mode=.TRUE., refpoint=rf, &
     553           18 :                              particle_set=particle_set, cell=cell)
     554              :       ELSE
     555           58 :          CALL build_sap_ints(sap_int, sap_ppnl, qs_kind_set, order, moment_mode=.TRUE.)
     556              :       END IF
     557              : 
     558              :       ! *** Set up a sorting index
     559           76 :       CALL sap_sort(sap_int)
     560              : 
     561          412 :       ALLOCATE (basis_set(nkind))
     562          260 :       DO ikind = 1, nkind
     563          184 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
     564          260 :          IF (ASSOCIATED(orb_basis_set)) THEN
     565          184 :             basis_set(ikind)%gto_basis_set => orb_basis_set
     566              :          ELSE
     567            0 :             NULLIFY (basis_set(ikind)%gto_basis_set)
     568              :          END IF
     569              :       END DO
     570              : 
     571              :       ! *** All integrals needed have been calculated and stored in sap_int
     572              :       ! *** We now calculate the commutator matrix elements
     573           76 :       CALL get_neighbor_list_set_p(neighbor_list_sets=sab_all, symmetric=do_symmetric)
     574              : 
     575              : !$OMP PARALLEL &
     576              : !$OMP DEFAULT (NONE) &
     577              : !$OMP SHARED  (basis_set, matrix_rv, matrix_rxrv, matrix_rrv, &
     578              : !$OMP          matrix_rvr, matrix_rrv_vrr, matrix_r_doublecom, &
     579              : !$OMP          sap_int, natom, nkind, eps_ppnl, locks, sab_all, &
     580              : !$OMP          my_rv, my_rxrv, my_rrv, my_rvr, my_rrv_vrr, &
     581              : !$OMP          my_r_doublecom, &
     582              : !$OMP          matrix_r_rxvr, matrix_rxvr_r, my_r_rxvr, my_rxvr_r, &
     583              : !$OMP          pseudoatom, do_symmetric) &
     584              : !$OMP PRIVATE (ikind, jkind, iatom, jatom, cell_b, rab, &
     585              : !$OMP          iab, irow, icol, lock_num, &
     586              : !$OMP          blocks_rv, blocks_rxrv, blocks_rrv, blocks_rvr, blocks_rrv_vrr, &
     587              : !$OMP          blocks_r_rxvr, blocks_rxvr_r, blocks_r_doublecom, &
     588              : !$OMP          found, iac, ibc, alist_ac, alist_bc, &
     589              : !$OMP          na, np, nb, kkind, kac, kbc, i, &
     590              : !$OMP          go, asso_rv, asso_rxrv, asso_rrv, asso_rvr, asso_rrv_vrr, &
     591              : !$OMP          asso_r_rxvr, asso_rxvr_r, asso_r_doublecom, hash, &
     592           76 : !$OMP          acint, achint, bcint, bchint)
     593              : 
     594              : !$OMP SINGLE
     595              : !$    ALLOCATE (locks(nlock))
     596              : !$OMP END SINGLE
     597              : 
     598              : !$OMP DO
     599              : !$    DO lock_num = 1, nlock
     600              : !$       call omp_init_lock(locks(lock_num))
     601              : !$    END DO
     602              : !$OMP END DO
     603              : 
     604              : !$OMP DO SCHEDULE(GUIDED)
     605              : 
     606              :       DO slot = 1, sab_all(1)%nl_size
     607              : 
     608              :          ikind = sab_all(1)%nlist_task(slot)%ikind
     609              :          jkind = sab_all(1)%nlist_task(slot)%jkind
     610              :          iatom = sab_all(1)%nlist_task(slot)%iatom
     611              :          jatom = sab_all(1)%nlist_task(slot)%jatom
     612              :          cell_b(:) = sab_all(1)%nlist_task(slot)%cell(:)
     613              :          rab(1:3) = sab_all(1)%nlist_task(slot)%r(1:3)
     614              : 
     615              :          IF (.NOT. ASSOCIATED(basis_set(ikind)%gto_basis_set)) CYCLE
     616              :          IF (.NOT. ASSOCIATED(basis_set(jkind)%gto_basis_set)) CYCLE
     617              :          iab = ikind + nkind*(jkind - 1)
     618              : 
     619              :          IF (do_symmetric) THEN
     620              :             IF (iatom <= jatom) THEN
     621              :                irow = iatom
     622              :                icol = jatom
     623              :             ELSE
     624              :                irow = jatom
     625              :                icol = iatom
     626              :             END IF
     627              :          ELSE
     628              :             irow = iatom
     629              :             icol = jatom
     630              :          END IF
     631              : 
     632              :          ! allocate blocks
     633              :          IF (my_rv) THEN
     634              :             ALLOCATE (blocks_rv(3))
     635              :          END IF
     636              :          IF (my_rxrv) THEN
     637              :             ALLOCATE (blocks_rxrv(3))
     638              :          END IF
     639              :          IF (my_rrv) THEN
     640              :             ALLOCATE (blocks_rrv(6))
     641              :          END IF
     642              :          IF (my_rvr) THEN
     643              :             ALLOCATE (blocks_rvr(6))
     644              :          END IF
     645              :          IF (my_rrv_vrr) THEN
     646              :             ALLOCATE (blocks_rrv_vrr(6))
     647              :          END IF
     648              :          IF (my_r_rxvr) THEN
     649              :             ALLOCATE (blocks_r_rxvr(3, 3))
     650              :          END IF
     651              : 
     652              :          IF (my_rxvr_r) THEN
     653              :             ALLOCATE (blocks_rxvr_r(3, 3))
     654              :          END IF
     655              : 
     656              :          IF (my_r_doublecom) THEN
     657              :             ALLOCATE (blocks_r_doublecom(3, 3))
     658              :          END IF
     659              : 
     660              :          ! get blocks
     661              :          IF (my_rv) THEN
     662              :             DO ind = 1, 3
     663              :                CALL dbcsr_get_block_p(matrix_rv(ind)%matrix, irow, icol, blocks_rv(ind)%block, found)
     664              :             END DO
     665              :          END IF
     666              : 
     667              :          IF (my_rxrv) THEN
     668              :             DO ind = 1, 3
     669              :                CALL dbcsr_get_block_p(matrix_rxrv(ind)%matrix, irow, icol, blocks_rxrv(ind)%block, found)
     670              :                blocks_rxrv(ind)%block(:, :) = 0._dp
     671              :             END DO
     672              :          END IF
     673              : 
     674              :          IF (my_rrv) THEN
     675              :             DO ind = 1, 6
     676              :                CALL dbcsr_get_block_p(matrix_rrv(ind)%matrix, irow, icol, blocks_rrv(ind)%block, found)
     677              :             END DO
     678              :          END IF
     679              : 
     680              :          IF (my_rvr) THEN
     681              :             DO ind = 1, 6
     682              :                CALL dbcsr_get_block_p(matrix_rvr(ind)%matrix, irow, icol, blocks_rvr(ind)%block, found)
     683              :             END DO
     684              :          END IF
     685              : 
     686              :          IF (my_rrv_vrr) THEN
     687              :             DO ind = 1, 6
     688              :                CALL dbcsr_get_block_p(matrix_rrv_vrr(ind)%matrix, irow, icol, blocks_rrv_vrr(ind)%block, found)
     689              :             END DO
     690              :          END IF
     691              : 
     692              :          IF (my_r_rxvr) THEN
     693              :             DO ind = 1, 3
     694              :                DO ind2 = 1, 3
     695              :                   CALL dbcsr_get_block_p(matrix_r_rxvr(ind, ind2)%matrix, irow, icol, &
     696              :                                          blocks_r_rxvr(ind, ind2)%block, found)
     697              :                   blocks_r_rxvr(ind, ind2)%block(:, :) = 0._dp
     698              :                END DO
     699              :             END DO
     700              :          END IF
     701              : 
     702              :          IF (my_rxvr_r) THEN
     703              :             DO ind = 1, 3
     704              :                DO ind2 = 1, 3
     705              :                   CALL dbcsr_get_block_p(matrix_rxvr_r(ind, ind2)%matrix, irow, icol, &
     706              :                                          blocks_rxvr_r(ind, ind2)%block, found)
     707              :                   blocks_rxvr_r(ind, ind2)%block(:, :) = 0._dp
     708              :                END DO
     709              :             END DO
     710              :          END IF
     711              : 
     712              :          IF (my_r_doublecom) THEN
     713              :             DO ind = 1, 3
     714              :                DO ind2 = 1, 3
     715              :                   CALL dbcsr_get_block_p(matrix_r_doublecom(ind, ind2)%matrix, irow, icol, &
     716              :                                          blocks_r_doublecom(ind, ind2)%block, found)
     717              :                   blocks_r_doublecom(ind, ind2)%block(:, :) = 0._dp
     718              :                END DO
     719              :             END DO
     720              :          END IF
     721              : 
     722              :          ! check whether all blocks are associated
     723              :          go = .TRUE.
     724              :          IF (my_rv) THEN
     725              :             asso_rv = (ASSOCIATED(blocks_rv(1)%block) .AND. ASSOCIATED(blocks_rv(2)%block) .AND. &
     726              :                        ASSOCIATED(blocks_rv(3)%block))
     727              :             go = go .AND. asso_rv
     728              :          END IF
     729              : 
     730              :          IF (my_rxrv) THEN
     731              :             asso_rxrv = (ASSOCIATED(blocks_rxrv(1)%block) .AND. ASSOCIATED(blocks_rxrv(2)%block) .AND. &
     732              :                          ASSOCIATED(blocks_rxrv(3)%block))
     733              :             go = go .AND. asso_rxrv
     734              :          END IF
     735              : 
     736              :          IF (my_rrv) THEN
     737              :             asso_rrv = (ASSOCIATED(blocks_rrv(1)%block) .AND. ASSOCIATED(blocks_rrv(2)%block) .AND. &
     738              :                         ASSOCIATED(blocks_rrv(3)%block) .AND. ASSOCIATED(blocks_rrv(4)%block) .AND. &
     739              :                         ASSOCIATED(blocks_rrv(5)%block) .AND. ASSOCIATED(blocks_rrv(6)%block))
     740              :             go = go .AND. asso_rrv
     741              :          END IF
     742              : 
     743              :          IF (my_rvr) THEN
     744              :             asso_rvr = (ASSOCIATED(blocks_rvr(1)%block) .AND. ASSOCIATED(blocks_rvr(2)%block) .AND. &
     745              :                         ASSOCIATED(blocks_rvr(3)%block) .AND. ASSOCIATED(blocks_rvr(4)%block) .AND. &
     746              :                         ASSOCIATED(blocks_rvr(5)%block) .AND. ASSOCIATED(blocks_rvr(6)%block))
     747              :             go = go .AND. asso_rvr
     748              :          END IF
     749              : 
     750              :          IF (my_rrv_vrr) THEN
     751              :             asso_rrv_vrr = (ASSOCIATED(blocks_rrv_vrr(1)%block) .AND. ASSOCIATED(blocks_rrv_vrr(2)%block) .AND. &
     752              :                             ASSOCIATED(blocks_rrv_vrr(3)%block) .AND. ASSOCIATED(blocks_rrv_vrr(4)%block) .AND. &
     753              :                             ASSOCIATED(blocks_rrv_vrr(5)%block) .AND. ASSOCIATED(blocks_rrv_vrr(6)%block))
     754              :             go = go .AND. asso_rrv_vrr
     755              :          END IF
     756              : 
     757              :          IF (my_r_rxvr) THEN
     758              :             asso_r_rxvr = .TRUE.
     759              :             DO ind = 1, 3
     760              :                DO ind2 = 1, 3
     761              :                   asso_r_rxvr = asso_r_rxvr .AND. ASSOCIATED(blocks_r_rxvr(ind, ind2)%block)
     762              :                END DO
     763              :             END DO
     764              :             go = go .AND. asso_r_rxvr
     765              :          END IF
     766              : 
     767              :          IF (my_rxvr_r) THEN
     768              :             asso_rxvr_r = .TRUE.
     769              :             DO ind = 1, 3
     770              :                DO ind2 = 1, 3
     771              :                   asso_rxvr_r = asso_rxvr_r .AND. ASSOCIATED(blocks_rxvr_r(ind, ind2)%block)
     772              :                END DO
     773              :             END DO
     774              :             go = go .AND. asso_rxvr_r
     775              :          END IF
     776              : 
     777              :          IF (my_r_doublecom) THEN
     778              :             asso_r_doublecom = .TRUE.
     779              :             DO ind = 1, 3
     780              :                DO ind2 = 1, 3
     781              :                   asso_r_doublecom = asso_r_doublecom .AND. ASSOCIATED(blocks_r_doublecom(ind, ind2)%block)
     782              :                END DO
     783              :             END DO
     784              :             go = go .AND. asso_r_doublecom
     785              :          END IF
     786              : 
     787              :          ! loop over all kinds for projector atom
     788              :          ! < iatom | katom > h < katom | jatom >
     789              :          IF (go) THEN
     790              :             DO kkind = 1, nkind
     791              :                iac = ikind + nkind*(kkind - 1)
     792              :                ibc = jkind + nkind*(kkind - 1)
     793              :                IF (.NOT. ASSOCIATED(sap_int(iac)%alist)) CYCLE
     794              :                IF (.NOT. ASSOCIATED(sap_int(ibc)%alist)) CYCLE
     795              :                CALL get_alist(sap_int(iac), alist_ac, iatom)
     796              :                CALL get_alist(sap_int(ibc), alist_bc, jatom)
     797              :                IF (.NOT. ASSOCIATED(alist_ac)) CYCLE
     798              :                IF (.NOT. ASSOCIATED(alist_bc)) CYCLE
     799              :                DO kac = 1, alist_ac%nclist
     800              :                   DO kbc = 1, alist_bc%nclist
     801              :                      IF (alist_ac%clist(kac)%catom /= alist_bc%clist(kbc)%catom) CYCLE
     802              :                      IF (PRESENT(pseudoatom)) THEN
     803              :                         IF (alist_ac%clist(kac)%catom /= pseudoatom) CYCLE
     804              :                      END IF
     805              : 
     806              :                      IF (ALL(cell_b + alist_bc%clist(kbc)%cell - alist_ac%clist(kac)%cell == 0)) THEN
     807              :                         IF (alist_ac%clist(kac)%maxac*alist_bc%clist(kbc)%maxach < eps_ppnl) CYCLE
     808              :                         acint => alist_ac%clist(kac)%acint
     809              :                         bcint => alist_bc%clist(kbc)%acint
     810              :                         achint => alist_ac%clist(kac)%achint
     811              :                         bchint => alist_bc%clist(kbc)%achint
     812              :                         na = SIZE(acint, 1)
     813              :                         np = SIZE(acint, 2)
     814              :                         nb = SIZE(bcint, 1)
     815              : !$                      hash = MOD((iatom - 1)*natom + jatom, nlock) + 1
     816              : !$                      CALL omp_set_lock(locks(hash))
     817              :                         IF (my_rv) THEN
     818              :                            ! r*Vnl
     819              :                            ! with LAPACK
     820              :                            ! CALL dgemm("N", "T", na, nb, np, 1._dp, achint(1, 1, 2), na, &
     821              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rv(1)%block, SIZE(blocks_rv(1)%block, 1)) ! xV
     822              :                            ! CALL dgemm("N", "T", na, nb, np, 1._dp, achint(1, 1, 3), na, &
     823              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rv(2)%block, SIZE(blocks_rv(2)%block, 1)) ! yV
     824              :                            ! CALL dgemm("N", "T", na, nb, np, 1._dp, achint(1, 1, 4), na, &
     825              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rv(3)%block, SIZE(blocks_rv(3)%block, 1)) ! zV
     826              :                            IF (iatom <= jatom) THEN
     827              :                               ! with MATMUL
     828              :                               blocks_rv(1)%block(1:na, 1:nb) = blocks_rv(1)%block(1:na, 1:nb) + &
     829              :                                                                MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 1))) ! xV
     830              :                               blocks_rv(2)%block(1:na, 1:nb) = blocks_rv(2)%block(1:na, 1:nb) + &
     831              :                                                                MATMUL(achint(1:na, 1:np, 3), TRANSPOSE(bcint(1:nb, 1:np, 1))) ! yV
     832              :                               blocks_rv(3)%block(1:na, 1:nb) = blocks_rv(3)%block(1:na, 1:nb) + &
     833              :                                                                MATMUL(achint(1:na, 1:np, 4), TRANSPOSE(bcint(1:nb, 1:np, 1))) ! zV
     834              :                            ELSE
     835              :                               blocks_rv(1)%block(1:nb, 1:na) = blocks_rv(1)%block(1:nb, 1:na) + &
     836              :                                                                MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 1)))
     837              :                               blocks_rv(2)%block(1:nb, 1:na) = blocks_rv(2)%block(1:nb, 1:na) + &
     838              :                                                                MATMUL(bchint(1:nb, 1:np, 3), TRANSPOSE(acint(1:na, 1:np, 1)))
     839              :                               blocks_rv(3)%block(1:nb, 1:na) = blocks_rv(3)%block(1:nb, 1:na) + &
     840              :                                                                MATMUL(bchint(1:nb, 1:np, 4), TRANSPOSE(acint(1:na, 1:np, 1)))
     841              :                            END IF
     842              :                            ! -Vnl r
     843              :                            ! with LAPACK
     844              :                            ! CALL dgemm("N", "T", na, nb, np, -1._dp, achint(1, 1, 1), na, &
     845              :                            !            bcint(1, 1, 2), nb, 1.0_dp, blocks_rv(1)%block, SIZE(blocks_rv(1)%block, 1)) ! -Vx
     846              :                            ! CALL dgemm("N", "T", na, nb, np, -1._dp, achint(1, 1, 1), na, &
     847              :                            !            bcint(1, 1, 3), nb, 1.0_dp, blocks_rv(2)%block, SIZE(blocks_rv(2)%block, 1)) ! -Vy
     848              :                            ! CALL dgemm("N", "T", na, nb, np, -1._dp, achint(1, 1, 1), na, &
     849              :                            !            bcint(1, 1, 4), nb, 1.0_dp, blocks_rv(3)%block, SIZE(blocks_rv(3)%block, 1)) ! -Vz
     850              :                            ! with MATMUL
     851              :                            IF (iatom <= jatom) THEN
     852              :                               blocks_rv(1)%block(1:na, 1:nb) = blocks_rv(1)%block(1:na, 1:nb) - &
     853              :                                                                MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 2))) ! -Vx
     854              :                               blocks_rv(2)%block(1:na, 1:nb) = blocks_rv(2)%block(1:na, 1:nb) - &
     855              :                                                                MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 3))) ! -Vy
     856              :                               blocks_rv(3)%block(1:na, 1:nb) = blocks_rv(3)%block(1:na, 1:nb) - &
     857              :                                                                MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 4))) ! -Vz
     858              :                            ELSE
     859              :                               blocks_rv(1)%block(1:nb, 1:na) = blocks_rv(1)%block(1:nb, 1:na) - &
     860              :                                                                MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 2)))
     861              :                               blocks_rv(2)%block(1:nb, 1:na) = blocks_rv(2)%block(1:nb, 1:na) - &
     862              :                                                                MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 3)))
     863              :                               blocks_rv(3)%block(1:nb, 1:na) = blocks_rv(3)%block(1:nb, 1:na) - &
     864              :                                                                MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 4)))
     865              :                            END IF
     866              : 
     867              :                         END IF
     868              : 
     869              :                         IF (my_rxrv) THEN
     870              :                            ! x-component (y [z,Vnl] - z [y, Vnl])
     871              :                            IF (iatom <= jatom) THEN
     872              :                               ! yzV
     873              :                               blocks_rxrv(1)%block(1:na, 1:nb) = blocks_rxrv(1)%block(1:na, 1:nb) + &
     874              :                                                                  MATMUL(achint(1:na, 1:np, 9), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     875              :                               ! -yVz
     876              :                               blocks_rxrv(1)%block(1:na, 1:nb) = blocks_rxrv(1)%block(1:na, 1:nb) - &
     877              :                                                                  MATMUL(achint(1:na, 1:np, 3), TRANSPOSE(bcint(1:nb, 1:np, 4)))
     878              :                               ! -zyV
     879              :                               blocks_rxrv(1)%block(1:na, 1:nb) = blocks_rxrv(1)%block(1:na, 1:nb) - &
     880              :                                                                  MATMUL(achint(1:na, 1:np, 9), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     881              :                               ! zVy
     882              :                               blocks_rxrv(1)%block(1:na, 1:nb) = blocks_rxrv(1)%block(1:na, 1:nb) + &
     883              :                                                                  MATMUL(achint(1:na, 1:np, 4), TRANSPOSE(bcint(1:nb, 1:np, 3)))
     884              :                            ELSE
     885              :                               ! yzV
     886              :                               blocks_rxrv(1)%block(1:nb, 1:na) = blocks_rxrv(1)%block(1:nb, 1:na) + &
     887              :                                                                  MATMUL(bchint(1:nb, 1:np, 9), TRANSPOSE(acint(1:na, 1:np, 1)))
     888              :                               ! -yVz
     889              :                               blocks_rxrv(1)%block(1:nb, 1:na) = blocks_rxrv(1)%block(1:nb, 1:na) - &
     890              :                                                                  MATMUL(bchint(1:nb, 1:np, 3), TRANSPOSE(acint(1:na, 1:np, 4)))
     891              :                               ! -zyV
     892              :                               blocks_rxrv(1)%block(1:nb, 1:na) = blocks_rxrv(1)%block(1:nb, 1:na) - &
     893              :                                                                  MATMUL(bchint(1:nb, 1:np, 9), TRANSPOSE(acint(1:na, 1:np, 1)))
     894              :                               ! zVy
     895              :                               blocks_rxrv(1)%block(1:nb, 1:na) = blocks_rxrv(1)%block(1:nb, 1:na) + &
     896              :                                                                  MATMUL(bchint(1:nb, 1:np, 4), TRANSPOSE(acint(1:na, 1:np, 3)))
     897              :                            END IF
     898              : 
     899              :                            ! y-component (z [x,Vnl] - x [z, Vnl])
     900              :                            IF (iatom <= jatom) THEN
     901              :                               ! zxV
     902              :                               blocks_rxrv(2)%block(1:na, 1:nb) = blocks_rxrv(2)%block(1:na, 1:nb) + &
     903              :                                                                  MATMUL(achint(1:na, 1:np, 7), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     904              :                               ! -zVx
     905              :                               blocks_rxrv(2)%block(1:na, 1:nb) = blocks_rxrv(2)%block(1:na, 1:nb) - &
     906              :                                                                  MATMUL(achint(1:na, 1:np, 4), TRANSPOSE(bcint(1:nb, 1:np, 2)))
     907              :                               ! -xzV
     908              :                               blocks_rxrv(2)%block(1:na, 1:nb) = blocks_rxrv(2)%block(1:na, 1:nb) - &
     909              :                                                                  MATMUL(achint(1:na, 1:np, 7), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     910              :                               ! xVz
     911              :                               blocks_rxrv(2)%block(1:na, 1:nb) = blocks_rxrv(2)%block(1:na, 1:nb) + &
     912              :                                                                  MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 4)))
     913              :                            ELSE
     914              :                               ! zxV
     915              :                               blocks_rxrv(2)%block(1:nb, 1:na) = blocks_rxrv(2)%block(1:nb, 1:na) + &
     916              :                                                                  MATMUL(bchint(1:nb, 1:np, 7), TRANSPOSE(acint(1:na, 1:np, 1)))
     917              :                               ! -zVx
     918              :                               blocks_rxrv(2)%block(1:nb, 1:na) = blocks_rxrv(2)%block(1:nb, 1:na) - &
     919              :                                                                  MATMUL(bchint(1:nb, 1:np, 4), TRANSPOSE(acint(1:na, 1:np, 2)))
     920              :                               ! -xzV
     921              :                               blocks_rxrv(2)%block(1:nb, 1:na) = blocks_rxrv(2)%block(1:nb, 1:na) - &
     922              :                                                                  MATMUL(bchint(1:nb, 1:np, 7), TRANSPOSE(acint(1:na, 1:np, 1)))
     923              :                               ! xVz
     924              :                               blocks_rxrv(2)%block(1:nb, 1:na) = blocks_rxrv(2)%block(1:nb, 1:na) + &
     925              :                                                                  MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 4)))
     926              :                            END IF
     927              : 
     928              :                            ! z-component (x [y,Vnl] - y [x, Vnl])
     929              :                            IF (iatom <= jatom) THEN
     930              :                               ! xyV
     931              :                               blocks_rxrv(3)%block(1:na, 1:nb) = blocks_rxrv(3)%block(1:na, 1:nb) + &
     932              :                                                                  MATMUL(achint(1:na, 1:np, 6), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     933              :                               ! -xVy
     934              :                               blocks_rxrv(3)%block(1:na, 1:nb) = blocks_rxrv(3)%block(1:na, 1:nb) - &
     935              :                                                                  MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 3)))
     936              :                               ! -yxV
     937              :                               blocks_rxrv(3)%block(1:na, 1:nb) = blocks_rxrv(3)%block(1:na, 1:nb) - &
     938              :                                                                  MATMUL(achint(1:na, 1:np, 6), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     939              :                               ! zVx
     940              :                               blocks_rxrv(3)%block(1:na, 1:nb) = blocks_rxrv(3)%block(1:na, 1:nb) + &
     941              :                                                                  MATMUL(achint(1:na, 1:np, 3), TRANSPOSE(bcint(1:nb, 1:np, 2)))
     942              :                            ELSE
     943              :                               ! xyV
     944              :                               blocks_rxrv(3)%block(1:nb, 1:na) = blocks_rxrv(3)%block(1:nb, 1:na) + &
     945              :                                                                  MATMUL(bchint(1:nb, 1:np, 6), TRANSPOSE(acint(1:na, 1:np, 1)))
     946              :                               ! -xVy
     947              :                               blocks_rxrv(3)%block(1:nb, 1:na) = blocks_rxrv(3)%block(1:nb, 1:na) - &
     948              :                                                                  MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 3)))
     949              :                               ! -yxV
     950              :                               blocks_rxrv(3)%block(1:nb, 1:na) = blocks_rxrv(3)%block(1:nb, 1:na) - &
     951              :                                                                  MATMUL(bchint(1:nb, 1:np, 6), TRANSPOSE(acint(1:na, 1:np, 1)))
     952              :                               ! zVx
     953              :                               blocks_rxrv(3)%block(1:nb, 1:na) = blocks_rxrv(3)%block(1:nb, 1:na) + &
     954              :                                                                  MATMUL(bchint(1:nb, 1:np, 3), TRANSPOSE(acint(1:na, 1:np, 2)))
     955              :                            END IF
     956              :                         END IF
     957              : 
     958              :                         IF (my_rrv) THEN
     959              :                            ! r_alpha * r_beta * Vnl
     960              :                            IF (iatom <= jatom) THEN
     961              :                               ! xxV
     962              :                               blocks_rrv(1)%block(1:na, 1:nb) = blocks_rrv(1)%block(1:na, 1:nb) + &
     963              :                                                                 MATMUL(achint(1:na, 1:np, 5), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     964              :                               ! xyV
     965              :                               blocks_rrv(2)%block(1:na, 1:nb) = blocks_rrv(2)%block(1:na, 1:nb) + &
     966              :                                                                 MATMUL(achint(1:na, 1:np, 6), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     967              :                               ! xzV
     968              :                               blocks_rrv(3)%block(1:na, 1:nb) = blocks_rrv(3)%block(1:na, 1:nb) + &
     969              :                                                                 MATMUL(achint(1:na, 1:np, 7), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     970              :                               ! yyV
     971              :                               blocks_rrv(4)%block(1:na, 1:nb) = blocks_rrv(4)%block(1:na, 1:nb) + &
     972              :                                                                 MATMUL(achint(1:na, 1:np, 8), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     973              :                               ! yzV
     974              :                               blocks_rrv(5)%block(1:na, 1:nb) = blocks_rrv(5)%block(1:na, 1:nb) + &
     975              :                                                                 MATMUL(achint(1:na, 1:np, 9), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     976              :                               ! zzV
     977              :                               blocks_rrv(6)%block(1:na, 1:nb) = blocks_rrv(6)%block(1:na, 1:nb) + &
     978              :                                                                 MATMUL(achint(1:na, 1:np, 10), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     979              :                            ELSE
     980              :                               ! xxV
     981              :                               blocks_rrv(1)%block(1:nb, 1:na) = blocks_rrv(1)%block(1:nb, 1:na) + &
     982              :                                                                 MATMUL(bchint(1:nb, 1:np, 5), TRANSPOSE(acint(1:na, 1:np, 1)))
     983              :                               ! xyV
     984              :                               blocks_rrv(2)%block(1:nb, 1:na) = blocks_rrv(2)%block(1:nb, 1:na) + &
     985              :                                                                 MATMUL(bchint(1:nb, 1:np, 6), TRANSPOSE(acint(1:na, 1:np, 1)))
     986              :                               ! xzV
     987              :                               blocks_rrv(3)%block(1:nb, 1:na) = blocks_rrv(3)%block(1:nb, 1:na) + &
     988              :                                                                 MATMUL(bchint(1:nb, 1:np, 7), TRANSPOSE(acint(1:na, 1:np, 1)))
     989              :                               ! yyV
     990              :                               blocks_rrv(4)%block(1:nb, 1:na) = blocks_rrv(4)%block(1:nb, 1:na) + &
     991              :                                                                 MATMUL(bchint(1:nb, 1:np, 8), TRANSPOSE(acint(1:na, 1:np, 1)))
     992              :                               ! yzV
     993              :                               blocks_rrv(5)%block(1:nb, 1:na) = blocks_rrv(5)%block(1:nb, 1:na) + &
     994              :                                                                 MATMUL(bchint(1:nb, 1:np, 9), TRANSPOSE(acint(1:na, 1:np, 1)))
     995              :                               ! zzV
     996              :                               blocks_rrv(6)%block(1:nb, 1:na) = blocks_rrv(6)%block(1:nb, 1:na) + &
     997              :                                                                 MATMUL(bchint(1:nb, 1:np, 10), TRANSPOSE(acint(1:na, 1:np, 1)))
     998              :                            END IF
     999              : 
    1000              :                            ! - Vnl * r_alpha * r_beta
    1001              :                            IF (iatom <= jatom) THEN
    1002              :                               ! -Vxx
    1003              :                               blocks_rrv(1)%block(1:na, 1:nb) = blocks_rrv(1)%block(1:na, 1:nb) - &
    1004              :                                                                 MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 5)))
    1005              :                               ! -Vxy
    1006              :                               blocks_rrv(2)%block(1:na, 1:nb) = blocks_rrv(2)%block(1:na, 1:nb) - &
    1007              :                                                                 MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 6)))
    1008              :                               ! -Vxz
    1009              :                               blocks_rrv(3)%block(1:na, 1:nb) = blocks_rrv(3)%block(1:na, 1:nb) - &
    1010              :                                                                 MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 7)))
    1011              :                               ! -Vyy
    1012              :                               blocks_rrv(4)%block(1:na, 1:nb) = blocks_rrv(4)%block(1:na, 1:nb) - &
    1013              :                                                                 MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 8)))
    1014              :                               ! -Vyz
    1015              :                               blocks_rrv(5)%block(1:na, 1:nb) = blocks_rrv(5)%block(1:na, 1:nb) - &
    1016              :                                                                 MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 9)))
    1017              :                               ! -Vzz
    1018              :                               blocks_rrv(6)%block(1:na, 1:nb) = blocks_rrv(6)%block(1:na, 1:nb) - &
    1019              :                                                                 MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 10)))
    1020              :                            ELSE
    1021              :                               ! -Vxx
    1022              :                               blocks_rrv(1)%block(1:nb, 1:na) = blocks_rrv(1)%block(1:nb, 1:na) - &
    1023              :                                                                 MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 5)))
    1024              :                               ! -Vxy
    1025              :                               blocks_rrv(2)%block(1:nb, 1:na) = blocks_rrv(2)%block(1:nb, 1:na) - &
    1026              :                                                                 MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 6)))
    1027              :                               ! -Vxz
    1028              :                               blocks_rrv(3)%block(1:nb, 1:na) = blocks_rrv(3)%block(1:nb, 1:na) - &
    1029              :                                                                 MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 7)))
    1030              :                               ! -Vyy
    1031              :                               blocks_rrv(4)%block(1:nb, 1:na) = blocks_rrv(4)%block(1:nb, 1:na) - &
    1032              :                                                                 MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 8)))
    1033              :                               ! -Vyz
    1034              :                               blocks_rrv(5)%block(1:nb, 1:na) = blocks_rrv(5)%block(1:nb, 1:na) - &
    1035              :                                                                 MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 9)))
    1036              :                               ! -Vzz
    1037              :                               blocks_rrv(6)%block(1:nb, 1:na) = blocks_rrv(6)%block(1:nb, 1:na) - &
    1038              :                                                                 MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 10)))
    1039              :                            END IF
    1040              :                         END IF
    1041              : 
    1042              :                         IF (my_rvr) THEN
    1043              :                            ! r_alpha * Vnl * r_beta
    1044              :                            IF (iatom <= jatom) THEN
    1045              :                               ! xVx
    1046              :                               blocks_rvr(1)%block(1:na, 1:nb) = blocks_rvr(1)%block(1:na, 1:nb) + &
    1047              :                                                                 MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 2)))
    1048              :                               ! xVy
    1049              :                               blocks_rvr(2)%block(1:na, 1:nb) = blocks_rvr(2)%block(1:na, 1:nb) + &
    1050              :                                                                 MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 3)))
    1051              :                               ! xVz
    1052              :                               blocks_rvr(3)%block(1:na, 1:nb) = blocks_rvr(3)%block(1:na, 1:nb) + &
    1053              :                                                                 MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 4)))
    1054              :                               ! yVy
    1055              :                               blocks_rvr(4)%block(1:na, 1:nb) = blocks_rvr(4)%block(1:na, 1:nb) + &
    1056              :                                                                 MATMUL(achint(1:na, 1:np, 3), TRANSPOSE(bcint(1:nb, 1:np, 3)))
    1057              :                               ! yVz
    1058              :                               blocks_rvr(5)%block(1:na, 1:nb) = blocks_rvr(5)%block(1:na, 1:nb) + &
    1059              :                                                                 MATMUL(achint(1:na, 1:np, 3), TRANSPOSE(bcint(1:nb, 1:np, 4)))
    1060              :                               ! zVz
    1061              :                               blocks_rvr(6)%block(1:na, 1:nb) = blocks_rvr(6)%block(1:na, 1:nb) + &
    1062              :                                                                 MATMUL(achint(1:na, 1:np, 4), TRANSPOSE(bcint(1:nb, 1:np, 4)))
    1063              :                            ELSE
    1064              :                               ! xVx
    1065              :                               blocks_rvr(1)%block(1:nb, 1:na) = blocks_rvr(1)%block(1:nb, 1:na) + &
    1066              :                                                                 MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 2)))
    1067              :                               ! xVy
    1068              :                               blocks_rvr(2)%block(1:nb, 1:na) = blocks_rvr(2)%block(1:nb, 1:na) + &
    1069              :                                                                 MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 3)))
    1070              :                               ! xVz
    1071              :                               blocks_rvr(3)%block(1:nb, 1:na) = blocks_rvr(3)%block(1:nb, 1:na) + &
    1072              :                                                                 MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 4)))
    1073              :                               ! yVy
    1074              :                               blocks_rvr(4)%block(1:nb, 1:na) = blocks_rvr(4)%block(1:nb, 1:na) + &
    1075              :                                                                 MATMUL(bchint(1:nb, 1:np, 3), TRANSPOSE(acint(1:na, 1:np, 3)))
    1076              :                               ! yVz
    1077              :                               blocks_rvr(5)%block(1:nb, 1:na) = blocks_rvr(5)%block(1:nb, 1:na) + &
    1078              :                                                                 MATMUL(bchint(1:nb, 1:np, 3), TRANSPOSE(acint(1:na, 1:np, 4)))
    1079              :                               ! zVz
    1080              :                               blocks_rvr(6)%block(1:nb, 1:na) = blocks_rvr(6)%block(1:nb, 1:na) + &
    1081              :                                                                 MATMUL(bchint(1:nb, 1:np, 4), TRANSPOSE(acint(1:na, 1:np, 4)))
    1082              :                            END IF
    1083              :                         END IF
    1084              : 
    1085              :                         IF (my_rrv_vrr) THEN
    1086              :                            ! r_alpha * r_beta * Vnl
    1087              :                            IF (iatom <= jatom) THEN
    1088              :                               ! xxV
    1089              :                               blocks_rrv_vrr(1)%block(1:na, 1:nb) = blocks_rrv_vrr(1)%block(1:na, 1:nb) + &
    1090              :                                                                     MATMUL(achint(1:na, 1:np, 5), TRANSPOSE(bcint(1:nb, 1:np, 1)))
    1091              :                               ! xyV
    1092              :                               blocks_rrv_vrr(2)%block(1:na, 1:nb) = blocks_rrv_vrr(2)%block(1:na, 1:nb) + &
    1093              :                                                                     MATMUL(achint(1:na, 1:np, 6), TRANSPOSE(bcint(1:nb, 1:np, 1)))
    1094              :                               ! xzV
    1095              :                               blocks_rrv_vrr(3)%block(1:na, 1:nb) = blocks_rrv_vrr(3)%block(1:na, 1:nb) + &
    1096              :                                                                     MATMUL(achint(1:na, 1:np, 7), TRANSPOSE(bcint(1:nb, 1:np, 1)))
    1097              :                               ! yyV
    1098              :                               blocks_rrv_vrr(4)%block(1:na, 1:nb) = blocks_rrv_vrr(4)%block(1:na, 1:nb) + &
    1099              :                                                                     MATMUL(achint(1:na, 1:np, 8), TRANSPOSE(bcint(1:nb, 1:np, 1)))
    1100              :                               ! yzV
    1101              :                               blocks_rrv_vrr(5)%block(1:na, 1:nb) = blocks_rrv_vrr(5)%block(1:na, 1:nb) + &
    1102              :                                                                     MATMUL(achint(1:na, 1:np, 9), TRANSPOSE(bcint(1:nb, 1:np, 1)))
    1103              :                               ! zzV
    1104              :                               blocks_rrv_vrr(6)%block(1:na, 1:nb) = blocks_rrv_vrr(6)%block(1:na, 1:nb) + &
    1105              :                                                                     MATMUL(achint(1:na, 1:np, 10), TRANSPOSE(bcint(1:nb, 1:np, 1)))
    1106              :                            ELSE
    1107              :                               ! xxV
    1108              :                               blocks_rrv_vrr(1)%block(1:nb, 1:na) = blocks_rrv_vrr(1)%block(1:nb, 1:na) + &
    1109              :                                                                     MATMUL(bchint(1:nb, 1:np, 5), TRANSPOSE(acint(1:na, 1:np, 1)))
    1110              :                               ! xyV
    1111              :                               blocks_rrv_vrr(2)%block(1:nb, 1:na) = blocks_rrv_vrr(2)%block(1:nb, 1:na) + &
    1112              :                                                                     MATMUL(bchint(1:nb, 1:np, 6), TRANSPOSE(acint(1:na, 1:np, 1)))
    1113              :                               ! xzV
    1114              :                               blocks_rrv_vrr(3)%block(1:nb, 1:na) = blocks_rrv_vrr(3)%block(1:nb, 1:na) + &
    1115              :                                                                     MATMUL(bchint(1:nb, 1:np, 7), TRANSPOSE(acint(1:na, 1:np, 1)))
    1116              :                               ! yyV
    1117              :                               blocks_rrv_vrr(4)%block(1:nb, 1:na) = blocks_rrv_vrr(4)%block(1:nb, 1:na) + &
    1118              :                                                                     MATMUL(bchint(1:nb, 1:np, 8), TRANSPOSE(acint(1:na, 1:np, 1)))
    1119              :                               ! yzV
    1120              :                               blocks_rrv_vrr(5)%block(1:nb, 1:na) = blocks_rrv_vrr(5)%block(1:nb, 1:na) + &
    1121              :                                                                     MATMUL(bchint(1:nb, 1:np, 9), TRANSPOSE(acint(1:na, 1:np, 1)))
    1122              :                               ! zzV
    1123              :                               blocks_rrv_vrr(6)%block(1:nb, 1:na) = blocks_rrv_vrr(6)%block(1:nb, 1:na) + &
    1124              :                                                                     MATMUL(bchint(1:nb, 1:np, 10), TRANSPOSE(acint(1:na, 1:np, 1)))
    1125              :                            END IF
    1126              :                            ! + Vnl * r_alpha * r_beta
    1127              :                            IF (iatom <= jatom) THEN
    1128              :                               ! +Vxx
    1129              :                               blocks_rrv_vrr(1)%block(1:na, 1:nb) = blocks_rrv_vrr(1)%block(1:na, 1:nb) + &
    1130              :                                                                     MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 5)))
    1131              :                               ! +Vxy
    1132              :                               blocks_rrv_vrr(2)%block(1:na, 1:nb) = blocks_rrv_vrr(2)%block(1:na, 1:nb) + &
    1133              :                                                                     MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 6)))
    1134              :                               ! +Vxz
    1135              :                               blocks_rrv_vrr(3)%block(1:na, 1:nb) = blocks_rrv_vrr(3)%block(1:na, 1:nb) + &
    1136              :                                                                     MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 7)))
    1137              :                               ! +Vyy
    1138              :                               blocks_rrv_vrr(4)%block(1:na, 1:nb) = blocks_rrv_vrr(4)%block(1:na, 1:nb) + &
    1139              :                                                                     MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 8)))
    1140              :                               ! +Vyz
    1141              :                               blocks_rrv_vrr(5)%block(1:na, 1:nb) = blocks_rrv_vrr(5)%block(1:na, 1:nb) + &
    1142              :                                                                     MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 9)))
    1143              :                               ! +Vzz
    1144              :                               blocks_rrv_vrr(6)%block(1:na, 1:nb) = blocks_rrv_vrr(6)%block(1:na, 1:nb) + &
    1145              :                                                                     MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 10)))
    1146              :                            ELSE
    1147              :                               ! +Vxx
    1148              :                               blocks_rrv_vrr(1)%block(1:nb, 1:na) = blocks_rrv_vrr(1)%block(1:nb, 1:na) + &
    1149              :                                                                     MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 5)))
    1150              :                               ! +Vxy
    1151              :                               blocks_rrv_vrr(2)%block(1:nb, 1:na) = blocks_rrv_vrr(2)%block(1:nb, 1:na) + &
    1152              :                                                                     MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 6)))
    1153              :                               ! +Vxz
    1154              :                               blocks_rrv_vrr(3)%block(1:nb, 1:na) = blocks_rrv_vrr(3)%block(1:nb, 1:na) + &
    1155              :                                                                     MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 7)))
    1156              :                               ! +Vyy
    1157              :                               blocks_rrv_vrr(4)%block(1:nb, 1:na) = blocks_rrv_vrr(4)%block(1:nb, 1:na) + &
    1158              :                                                                     MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 8)))
    1159              :                               ! +Vyz
    1160              :                               blocks_rrv_vrr(5)%block(1:nb, 1:na) = blocks_rrv_vrr(5)%block(1:nb, 1:na) + &
    1161              :                                                                     MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 9)))
    1162              :                               ! +Vzz
    1163              :                               blocks_rrv_vrr(6)%block(1:nb, 1:na) = blocks_rrv_vrr(6)%block(1:nb, 1:na) + &
    1164              :                                                                     MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 10)))
    1165              :                            END IF
    1166              :                         END IF
    1167              : 
    1168              :                         ! The indices are stored in i_1, i_x, ..., i_zzz
    1169              : 
    1170              :                         ! TODO: is this set to zero before?
    1171              :                         IF (my_r_rxvr) THEN
    1172              :                            ! beta = 1
    1173              :                            ! matrix_r_rxvr(x, x) = x * y * V_nl * z  -  x * z * V_nl * y
    1174              :                            blocks_r_rxvr(1, 1)%block(1:na, 1:nb) = &
    1175              :                               blocks_r_rxvr(1, 1)%block(1:na, 1:nb) + &
    1176              :                               MATMUL(achint(1:na, 1:np, i_xy), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1177              :                            blocks_r_rxvr(1, 1)%block(1:na, 1:nb) = &
    1178              :                               blocks_r_rxvr(1, 1)%block(1:na, 1:nb) - &
    1179              :                               MATMUL(achint(1:na, 1:np, i_xz), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1180              : 
    1181              :                            ! matrix_r_rxvr(y, x) = x * z * V_nl * x  -  x * x * V_nl * z
    1182              :                            blocks_r_rxvr(2, 1)%block(1:na, 1:nb) = &
    1183              :                               blocks_r_rxvr(2, 1)%block(1:na, 1:nb) + &
    1184              :                               MATMUL(achint(1:na, 1:np, i_xz), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1185              :                            blocks_r_rxvr(2, 1)%block(1:na, 1:nb) = &
    1186              :                               blocks_r_rxvr(2, 1)%block(1:na, 1:nb) - &
    1187              :                               MATMUL(achint(1:na, 1:np, i_xx), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1188              : 
    1189              :                            ! matrix_r_rxvr(z, x) = x * x * V_nl * y  -  x * y * V_nl * x
    1190              :                            blocks_r_rxvr(3, 1)%block(1:na, 1:nb) = &
    1191              :                               blocks_r_rxvr(3, 1)%block(1:na, 1:nb) + &
    1192              :                               MATMUL(achint(1:na, 1:np, i_xx), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1193              :                            blocks_r_rxvr(3, 1)%block(1:na, 1:nb) = &
    1194              :                               blocks_r_rxvr(3, 1)%block(1:na, 1:nb) - &
    1195              :                               MATMUL(achint(1:na, 1:np, i_xy), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1196              : 
    1197              :                            ! beta = 2
    1198              :                            ! matrix_r_rxvr(x, y) = y * y * V_nl * z  -  y * z * V_nl * y
    1199              :                            blocks_r_rxvr(1, 2)%block(1:na, 1:nb) = &
    1200              :                               blocks_r_rxvr(1, 2)%block(1:na, 1:nb) + &
    1201              :                               MATMUL(achint(1:na, 1:np, i_yy), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1202              :                            blocks_r_rxvr(1, 2)%block(1:na, 1:nb) = &
    1203              :                               blocks_r_rxvr(1, 2)%block(1:na, 1:nb) - &
    1204              :                               MATMUL(achint(1:na, 1:np, i_yz), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1205              : 
    1206              :                            ! matrix_r_rxvr(y, y) = y * z * V_nl * x  -  y * x * V_nl * z
    1207              :                            blocks_r_rxvr(2, 2)%block(1:na, 1:nb) = &
    1208              :                               blocks_r_rxvr(2, 2)%block(1:na, 1:nb) + &
    1209              :                               MATMUL(achint(1:na, 1:np, i_yz), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1210              :                            blocks_r_rxvr(2, 2)%block(1:na, 1:nb) = &
    1211              :                               blocks_r_rxvr(2, 2)%block(1:na, 1:nb) - &
    1212              :                               MATMUL(achint(1:na, 1:np, i_yx), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1213              : 
    1214              :                            ! matrix_r_rxvr(z, y) = y * x * V_nl * y  -  y * y * V_nl * x
    1215              :                            blocks_r_rxvr(3, 2)%block(1:na, 1:nb) = &
    1216              :                               blocks_r_rxvr(3, 2)%block(1:na, 1:nb) + &
    1217              :                               MATMUL(achint(1:na, 1:np, i_yx), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1218              :                            blocks_r_rxvr(3, 2)%block(1:na, 1:nb) = &
    1219              :                               blocks_r_rxvr(3, 2)%block(1:na, 1:nb) - &
    1220              :                               MATMUL(achint(1:na, 1:np, i_yy), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1221              : 
    1222              :                            ! beta = 3
    1223              :                            ! matrix_r_rxvr(x, z) = z * y * V_nl * z  -  z * z * V_nl * y
    1224              :                            blocks_r_rxvr(1, 3)%block(1:na, 1:nb) = &
    1225              :                               blocks_r_rxvr(1, 3)%block(1:na, 1:nb) + &
    1226              :                               MATMUL(achint(1:na, 1:np, i_zy), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1227              :                            blocks_r_rxvr(1, 3)%block(1:na, 1:nb) = &
    1228              :                               blocks_r_rxvr(1, 3)%block(1:na, 1:nb) - &
    1229              :                               MATMUL(achint(1:na, 1:np, i_zz), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1230              : 
    1231              :                            ! matrix_r_rxvr(y, z) = z * z * V_nl * x  -  z * x * V_nl * z
    1232              :                            blocks_r_rxvr(2, 3)%block(1:na, 1:nb) = &
    1233              :                               blocks_r_rxvr(2, 3)%block(1:na, 1:nb) + &
    1234              :                               MATMUL(achint(1:na, 1:np, i_zz), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1235              :                            blocks_r_rxvr(2, 3)%block(1:na, 1:nb) = &
    1236              :                               blocks_r_rxvr(2, 3)%block(1:na, 1:nb) - &
    1237              :                               MATMUL(achint(1:na, 1:np, i_zx), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1238              : 
    1239              :                            ! matrix_r_rxvr(z, z) = z * x * V_nl * y  -  z * y * V_nl * x
    1240              :                            blocks_r_rxvr(3, 3)%block(1:na, 1:nb) = &
    1241              :                               blocks_r_rxvr(3, 3)%block(1:na, 1:nb) + &
    1242              :                               MATMUL(achint(1:na, 1:np, i_zx), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1243              :                            blocks_r_rxvr(3, 3)%block(1:na, 1:nb) = &
    1244              :                               blocks_r_rxvr(3, 3)%block(1:na, 1:nb) - &
    1245              :                               MATMUL(achint(1:na, 1:np, i_zy), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1246              : 
    1247              :                         END IF ! my_r_rxvr
    1248              : 
    1249              :                         ! The indices are stored in i_1, i_x, ..., i_zzz
    1250              :                         ! This will put into blocks_rxvr_r
    1251              :                         ! matrix_rxvr_r(alpha, beta) = sum_(gamma delta) epsilon_(alpha gamma delta)
    1252              :                         !                              r_gamma * V_nl * r_delta * r_beta
    1253              :                         IF (my_rxvr_r) THEN
    1254              :                            ! beta = 1
    1255              :                            ! matrix_rxvr_r(x, x) = yV zx - zV yx
    1256              :                            blocks_rxvr_r(1, 1)%block(1:na, 1:nb) = &
    1257              :                               blocks_rxvr_r(1, 1)%block(1:na, 1:nb) + &
    1258              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_zx)))
    1259              :                            blocks_rxvr_r(1, 1)%block(1:na, 1:nb) = &
    1260              :                               blocks_rxvr_r(1, 1)%block(1:na, 1:nb) - &
    1261              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_yx)))
    1262              : 
    1263              :                            ! matrix_rxvr_r(y, x) = zV xx - xV zx
    1264              :                            blocks_rxvr_r(2, 1)%block(1:na, 1:nb) = &
    1265              :                               blocks_rxvr_r(2, 1)%block(1:na, 1:nb) + &
    1266              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_xx)))
    1267              :                            blocks_rxvr_r(2, 1)%block(1:na, 1:nb) = &
    1268              :                               blocks_rxvr_r(2, 1)%block(1:na, 1:nb) - &
    1269              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_zx)))
    1270              : 
    1271              :                            ! matrix_rxvr_r(z, x) = xV yx - yV xx
    1272              :                            blocks_rxvr_r(3, 1)%block(1:na, 1:nb) = &
    1273              :                               blocks_rxvr_r(3, 1)%block(1:na, 1:nb) + &
    1274              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_yx)))
    1275              :                            blocks_rxvr_r(3, 1)%block(1:na, 1:nb) = &
    1276              :                               blocks_rxvr_r(3, 1)%block(1:na, 1:nb) - &
    1277              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_xx)))
    1278              : 
    1279              :                            ! beta = 2
    1280              :                            ! matrix_rxvr_r(x, y) = yV zy - zV yy
    1281              :                            blocks_rxvr_r(1, 2)%block(1:na, 1:nb) = &
    1282              :                               blocks_rxvr_r(1, 2)%block(1:na, 1:nb) + &
    1283              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_zy)))
    1284              :                            blocks_rxvr_r(1, 2)%block(1:na, 1:nb) = &
    1285              :                               blocks_rxvr_r(1, 2)%block(1:na, 1:nb) - &
    1286              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_yy)))
    1287              : 
    1288              :                            ! matrix_rxvr_r(y, y) = zV xy - xV zy
    1289              :                            blocks_rxvr_r(2, 2)%block(1:na, 1:nb) = &
    1290              :                               blocks_rxvr_r(2, 2)%block(1:na, 1:nb) + &
    1291              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_xy)))
    1292              :                            blocks_rxvr_r(2, 2)%block(1:na, 1:nb) = &
    1293              :                               blocks_rxvr_r(2, 2)%block(1:na, 1:nb) - &
    1294              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_zy)))
    1295              : 
    1296              :                            ! matrix_rxvr_r(z, y) = xV yy - yV xy
    1297              :                            blocks_rxvr_r(3, 2)%block(1:na, 1:nb) = &
    1298              :                               blocks_rxvr_r(3, 2)%block(1:na, 1:nb) + &
    1299              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_yy)))
    1300              :                            blocks_rxvr_r(3, 2)%block(1:na, 1:nb) = &
    1301              :                               blocks_rxvr_r(3, 2)%block(1:na, 1:nb) - &
    1302              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_xy)))
    1303              : 
    1304              :                            ! beta = 3
    1305              :                            ! matrix_rxvr_r(x, z) = yV zz - zV yz
    1306              :                            blocks_rxvr_r(1, 3)%block(1:na, 1:nb) = &
    1307              :                               blocks_rxvr_r(1, 3)%block(1:na, 1:nb) + &
    1308              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_zz)))
    1309              :                            blocks_rxvr_r(1, 3)%block(1:na, 1:nb) = &
    1310              :                               blocks_rxvr_r(1, 3)%block(1:na, 1:nb) - &
    1311              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_yz)))
    1312              : 
    1313              :                            ! matrix_rxvr_r(y, z) = zV xz - xV zz
    1314              :                            blocks_rxvr_r(2, 3)%block(1:na, 1:nb) = &
    1315              :                               blocks_rxvr_r(2, 3)%block(1:na, 1:nb) + &
    1316              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_xz)))
    1317              :                            blocks_rxvr_r(2, 3)%block(1:na, 1:nb) = &
    1318              :                               blocks_rxvr_r(2, 3)%block(1:na, 1:nb) - &
    1319              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_zz)))
    1320              : 
    1321              :                            ! matrix_rxvr_r(z, z) = xV yz - yV xz
    1322              :                            blocks_rxvr_r(3, 3)%block(1:na, 1:nb) = &
    1323              :                               blocks_rxvr_r(3, 3)%block(1:na, 1:nb) + &
    1324              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_yz)))
    1325              :                            blocks_rxvr_r(3, 3)%block(1:na, 1:nb) = &
    1326              :                               blocks_rxvr_r(3, 3)%block(1:na, 1:nb) - &
    1327              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_xz)))
    1328              : 
    1329              :                         END IF ! my_rxvr_r
    1330              : 
    1331              :                         ! matrix_r_doublecom(alpha, beta) = sum_(gamma delta) epsilon_(alpha gamma delta)
    1332              :                         !                                gamma V^pseudoatom beta delta - gamma beta V^pseudoatom delta
    1333              : 
    1334              :                         IF (my_r_doublecom) THEN
    1335              :                            ! beta = 1
    1336              :                            ! matrix_r_doublecom(x, x) = yV xz  -  zV xy  -  yxV z  +  zxV y
    1337              :                            blocks_r_doublecom(1, 1)%block(1:na, 1:nb) = &
    1338              :                               blocks_r_doublecom(1, 1)%block(1:na, 1:nb) + &
    1339              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_xz)))
    1340              :                            blocks_r_doublecom(1, 1)%block(1:na, 1:nb) = &
    1341              :                               blocks_r_doublecom(1, 1)%block(1:na, 1:nb) - &
    1342              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_xy)))
    1343              :                            blocks_r_doublecom(1, 1)%block(1:na, 1:nb) = &
    1344              :                               blocks_r_doublecom(1, 1)%block(1:na, 1:nb) - &
    1345              :                               MATMUL(achint(1:na, 1:np, i_yx), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1346              :                            blocks_r_doublecom(1, 1)%block(1:na, 1:nb) = &
    1347              :                               blocks_r_doublecom(1, 1)%block(1:na, 1:nb) + &
    1348              :                               MATMUL(achint(1:na, 1:np, i_zx), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1349              : 
    1350              :                            ! matrix_r_doublecom(y, x) = zV xx  -  xV xz  -  zxV x  +  xxV z
    1351              :                            blocks_r_doublecom(2, 1)%block(1:na, 1:nb) = &
    1352              :                               blocks_r_doublecom(2, 1)%block(1:na, 1:nb) + &
    1353              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_xx)))
    1354              :                            blocks_r_doublecom(2, 1)%block(1:na, 1:nb) = &
    1355              :                               blocks_r_doublecom(2, 1)%block(1:na, 1:nb) - &
    1356              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_xz)))
    1357              :                            blocks_r_doublecom(2, 1)%block(1:na, 1:nb) = &
    1358              :                               blocks_r_doublecom(2, 1)%block(1:na, 1:nb) - &
    1359              :                               MATMUL(achint(1:na, 1:np, i_zx), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1360              :                            blocks_r_doublecom(2, 1)%block(1:na, 1:nb) = &
    1361              :                               blocks_r_doublecom(2, 1)%block(1:na, 1:nb) + &
    1362              :                               MATMUL(achint(1:na, 1:np, i_xx), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1363              : 
    1364              :                            ! matrix_r_doublecom(z, x) = xV xy  -  yV xx  -  xxV y  +  yxV x
    1365              :                            blocks_r_doublecom(3, 1)%block(1:na, 1:nb) = &
    1366              :                               blocks_r_doublecom(3, 1)%block(1:na, 1:nb) + &
    1367              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_xy)))
    1368              :                            blocks_r_doublecom(3, 1)%block(1:na, 1:nb) = &
    1369              :                               blocks_r_doublecom(3, 1)%block(1:na, 1:nb) - &
    1370              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_xx)))
    1371              :                            blocks_r_doublecom(3, 1)%block(1:na, 1:nb) = &
    1372              :                               blocks_r_doublecom(3, 1)%block(1:na, 1:nb) - &
    1373              :                               MATMUL(achint(1:na, 1:np, i_xx), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1374              :                            blocks_r_doublecom(3, 1)%block(1:na, 1:nb) = &
    1375              :                               blocks_r_doublecom(3, 1)%block(1:na, 1:nb) + &
    1376              :                               MATMUL(achint(1:na, 1:np, i_yx), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1377              : 
    1378              :                            ! beta = 2
    1379              :                            ! matrix_r_doublecom(x, y) = yV yz  -  zV yy  -  yyV z  +  zyV y
    1380              :                            blocks_r_doublecom(1, 2)%block(1:na, 1:nb) = &
    1381              :                               blocks_r_doublecom(1, 2)%block(1:na, 1:nb) + &
    1382              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_yz)))
    1383              :                            blocks_r_doublecom(1, 2)%block(1:na, 1:nb) = &
    1384              :                               blocks_r_doublecom(1, 2)%block(1:na, 1:nb) - &
    1385              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_yy)))
    1386              :                            blocks_r_doublecom(1, 2)%block(1:na, 1:nb) = &
    1387              :                               blocks_r_doublecom(1, 2)%block(1:na, 1:nb) - &
    1388              :                               MATMUL(achint(1:na, 1:np, i_yy), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1389              :                            blocks_r_doublecom(1, 2)%block(1:na, 1:nb) = &
    1390              :                               blocks_r_doublecom(1, 2)%block(1:na, 1:nb) + &
    1391              :                               MATMUL(achint(1:na, 1:np, i_zy), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1392              : 
    1393              :                            ! matrix_r_doublecom(y, y) = zV yx  -  xV yz  -  zyV x  +  xyV z
    1394              :                            blocks_r_doublecom(2, 2)%block(1:na, 1:nb) = &
    1395              :                               blocks_r_doublecom(2, 2)%block(1:na, 1:nb) + &
    1396              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_yx)))
    1397              :                            blocks_r_doublecom(2, 2)%block(1:na, 1:nb) = &
    1398              :                               blocks_r_doublecom(2, 2)%block(1:na, 1:nb) - &
    1399              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_yz)))
    1400              :                            blocks_r_doublecom(2, 2)%block(1:na, 1:nb) = &
    1401              :                               blocks_r_doublecom(2, 2)%block(1:na, 1:nb) - &
    1402              :                               MATMUL(achint(1:na, 1:np, i_zy), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1403              :                            blocks_r_doublecom(2, 2)%block(1:na, 1:nb) = &
    1404              :                               blocks_r_doublecom(2, 2)%block(1:na, 1:nb) + &
    1405              :                               MATMUL(achint(1:na, 1:np, i_xy), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1406              : 
    1407              :                            ! matrix_r_doublecom(z, y) = xV yy  -  yV yx  -  xyV y  +  yyV x
    1408              :                            blocks_r_doublecom(3, 2)%block(1:na, 1:nb) = &
    1409              :                               blocks_r_doublecom(3, 2)%block(1:na, 1:nb) + &
    1410              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_yy)))
    1411              :                            blocks_r_doublecom(3, 2)%block(1:na, 1:nb) = &
    1412              :                               blocks_r_doublecom(3, 2)%block(1:na, 1:nb) - &
    1413              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_yx)))
    1414              :                            blocks_r_doublecom(3, 2)%block(1:na, 1:nb) = &
    1415              :                               blocks_r_doublecom(3, 2)%block(1:na, 1:nb) - &
    1416              :                               MATMUL(achint(1:na, 1:np, i_xy), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1417              :                            blocks_r_doublecom(3, 2)%block(1:na, 1:nb) = &
    1418              :                               blocks_r_doublecom(3, 2)%block(1:na, 1:nb) + &
    1419              :                               MATMUL(achint(1:na, 1:np, i_yy), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1420              : 
    1421              :                            ! beta = 3
    1422              :                            ! matrix_r_doublecom(x, z) = yV zz  -  zV zy  -  yzV z  +  zzV y
    1423              :                            blocks_r_doublecom(1, 3)%block(1:na, 1:nb) = &
    1424              :                               blocks_r_doublecom(1, 3)%block(1:na, 1:nb) + &
    1425              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_zz)))
    1426              :                            blocks_r_doublecom(1, 3)%block(1:na, 1:nb) = &
    1427              :                               blocks_r_doublecom(1, 3)%block(1:na, 1:nb) - &
    1428              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_zy)))
    1429              :                            blocks_r_doublecom(1, 3)%block(1:na, 1:nb) = &
    1430              :                               blocks_r_doublecom(1, 3)%block(1:na, 1:nb) - &
    1431              :                               MATMUL(achint(1:na, 1:np, i_yz), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1432              :                            blocks_r_doublecom(1, 3)%block(1:na, 1:nb) = &
    1433              :                               blocks_r_doublecom(1, 3)%block(1:na, 1:nb) + &
    1434              :                               MATMUL(achint(1:na, 1:np, i_zz), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1435              : 
    1436              :                            ! matrix_r_doublecom(y, z) = zV zx  -  xV zz  -  zzV x  +  xzV z
    1437              :                            blocks_r_doublecom(2, 3)%block(1:na, 1:nb) = &
    1438              :                               blocks_r_doublecom(2, 3)%block(1:na, 1:nb) + &
    1439              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_zx)))
    1440              :                            blocks_r_doublecom(2, 3)%block(1:na, 1:nb) = &
    1441              :                               blocks_r_doublecom(2, 3)%block(1:na, 1:nb) - &
    1442              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_zz)))
    1443              :                            blocks_r_doublecom(2, 3)%block(1:na, 1:nb) = &
    1444              :                               blocks_r_doublecom(2, 3)%block(1:na, 1:nb) - &
    1445              :                               MATMUL(achint(1:na, 1:np, i_zz), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1446              :                            blocks_r_doublecom(2, 3)%block(1:na, 1:nb) = &
    1447              :                               blocks_r_doublecom(2, 3)%block(1:na, 1:nb) + &
    1448              :                               MATMUL(achint(1:na, 1:np, i_xz), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1449              : 
    1450              :                            ! matrix_r_doublecom(z, z) = xV zy  -  yV zx  -  xzV y  +  yzV x
    1451              :                            blocks_r_doublecom(3, 3)%block(1:na, 1:nb) = &
    1452              :                               blocks_r_doublecom(3, 3)%block(1:na, 1:nb) + &
    1453              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_zy)))
    1454              :                            blocks_r_doublecom(3, 3)%block(1:na, 1:nb) = &
    1455              :                               blocks_r_doublecom(3, 3)%block(1:na, 1:nb) - &
    1456              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_zx)))
    1457              :                            blocks_r_doublecom(3, 3)%block(1:na, 1:nb) = &
    1458              :                               blocks_r_doublecom(3, 3)%block(1:na, 1:nb) - &
    1459              :                               MATMUL(achint(1:na, 1:np, i_xz), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1460              :                            blocks_r_doublecom(3, 3)%block(1:na, 1:nb) = &
    1461              :                               blocks_r_doublecom(3, 3)%block(1:na, 1:nb) + &
    1462              :                               MATMUL(achint(1:na, 1:np, i_yz), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1463              : 
    1464              :                         END IF ! my_r_doublecom
    1465              : !$                      CALL omp_unset_lock(locks(hash))
    1466              :                         EXIT ! We have found a match and there can be only one single match
    1467              :                      END IF
    1468              :                   END DO
    1469              :                END DO
    1470              :             END DO
    1471              :          END IF
    1472              :          IF (my_rv) THEN
    1473              :             DO ind = 1, 3
    1474              :                NULLIFY (blocks_rv(ind)%block)
    1475              :             END DO
    1476              :             DEALLOCATE (blocks_rv)
    1477              :          END IF
    1478              :          IF (my_rxrv) THEN
    1479              :             DO ind = 1, 3
    1480              :                NULLIFY (blocks_rxrv(ind)%block)
    1481              :             END DO
    1482              :             DEALLOCATE (blocks_rxrv)
    1483              :          END IF
    1484              :          IF (my_rrv) THEN
    1485              :             DO ind = 1, 6
    1486              :                NULLIFY (blocks_rrv(ind)%block)
    1487              :             END DO
    1488              :             DEALLOCATE (blocks_rrv)
    1489              :          END IF
    1490              :          IF (my_rvr) THEN
    1491              :             DO ind = 1, 6
    1492              :                NULLIFY (blocks_rvr(ind)%block)
    1493              :             END DO
    1494              :             DEALLOCATE (blocks_rvr)
    1495              :          END IF
    1496              :          IF (my_rrv_vrr) THEN
    1497              :             DO ind = 1, 6
    1498              :                NULLIFY (blocks_rrv_vrr(ind)%block)
    1499              :             END DO
    1500              :             DEALLOCATE (blocks_rrv_vrr)
    1501              :          END IF
    1502              :          IF (my_r_rxvr) THEN
    1503              :             DO ind = 1, 3
    1504              :                DO ind2 = 1, 3
    1505              :                   NULLIFY (blocks_r_rxvr(ind, ind2)%block)
    1506              :                END DO
    1507              :             END DO
    1508              :             DEALLOCATE (blocks_r_rxvr)
    1509              :          END IF
    1510              :          IF (my_rxvr_r) THEN
    1511              :             DO ind = 1, 3
    1512              :                DO ind2 = 1, 3
    1513              :                   NULLIFY (blocks_rxvr_r(ind, ind2)%block)
    1514              :                END DO
    1515              :             END DO
    1516              :             DEALLOCATE (blocks_rxvr_r)
    1517              :          END IF
    1518              :          IF (my_r_doublecom) THEN
    1519              :             DO ind = 1, 3
    1520              :                DO ind2 = 1, 3
    1521              :                   NULLIFY (blocks_r_doublecom(ind, ind2)%block)
    1522              :                END DO
    1523              :             END DO
    1524              :             DEALLOCATE (blocks_r_doublecom)
    1525              :          END IF
    1526              :       END DO
    1527              : 
    1528              : !$OMP DO
    1529              : !$    DO lock_num = 1, nlock
    1530              : !$       call omp_destroy_lock(locks(lock_num))
    1531              : !$    END DO
    1532              : !$OMP END DO
    1533              : 
    1534              : !$OMP SINGLE
    1535              : !$    DEALLOCATE (locks)
    1536              : !$OMP END SINGLE NOWAIT
    1537              : 
    1538              : !$OMP END PARALLEL
    1539              : 
    1540           76 :       CALL release_sap_int(sap_int)
    1541              : 
    1542           76 :       DEALLOCATE (basis_set)
    1543              : 
    1544           76 :       CALL timestop(handle)
    1545              : 
    1546          250 :    END SUBROUTINE build_com_mom_nl
    1547              : 
    1548              : ! **************************************************************************************************
    1549              : !> \brief calculate \sum_R_ps (R_ps - R_nu) x [V_nl, r] summing over all pseudized atoms R
    1550              : !> \param qs_kind_set ...
    1551              : !> \param sab_all ...
    1552              : !> \param sap_ppnl ...
    1553              : !> \param eps_ppnl ...
    1554              : !> \param particle_set ...
    1555              : !> \param matrix_mag_nl ...
    1556              : !> \param refpoint ...
    1557              : !> \param cell ...
    1558              : ! **************************************************************************************************
    1559            8 :    SUBROUTINE build_com_nl_mag(qs_kind_set, sab_all, sap_ppnl, eps_ppnl, particle_set, matrix_mag_nl, refpoint, cell)
    1560              : 
    1561              :       TYPE(qs_kind_type), DIMENSION(:), INTENT(IN), &
    1562              :          POINTER                                         :: qs_kind_set
    1563              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1564              :          INTENT(IN), POINTER                             :: sab_all, sap_ppnl
    1565              :       REAL(KIND=dp), INTENT(IN)                          :: eps_ppnl
    1566              :       TYPE(particle_type), DIMENSION(:), INTENT(IN), &
    1567              :          POINTER                                         :: particle_set
    1568              :       TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN), &
    1569              :          POINTER                                         :: matrix_mag_nl
    1570              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN), OPTIONAL  :: refpoint
    1571              :       TYPE(cell_type), INTENT(IN), OPTIONAL, POINTER     :: cell
    1572              : 
    1573              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'build_com_nl_mag'
    1574              : 
    1575              :       INTEGER                                            :: handle, iab, iac, iatom, ibc, icol, &
    1576              :                                                             ikind, ind, irow, jatom, jkind, kac, &
    1577              :                                                             kbc, kkind, na, natom, nb, nkind, np, &
    1578              :                                                             order, slot
    1579              :       INTEGER, DIMENSION(3)                              :: cell_b
    1580              :       LOGICAL                                            :: found, go, my_ref, ppnl_present
    1581              :       REAL(KIND=dp), DIMENSION(3)                        :: r_b, r_ps, rab
    1582            8 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: achint, acint, bchint, bcint
    1583              :       TYPE(alist_type), POINTER                          :: alist_ac, alist_bc
    1584            8 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:)      :: blocks_mag
    1585              :       TYPE(gto_basis_set_p_type), ALLOCATABLE, &
    1586            8 :          DIMENSION(:)                                    :: basis_set
    1587              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    1588            8 :       TYPE(sap_int_type), DIMENSION(:), POINTER          :: sap_int
    1589              : 
    1590              : !$    INTEGER(kind=omp_lock_kind), &
    1591            8 : !$       ALLOCATABLE, DIMENSION(:) :: locks
    1592              : !$    INTEGER                                            :: lock_num, hash
    1593              : !$    INTEGER, PARAMETER                                 :: nlock = 501
    1594              : 
    1595            8 :       ppnl_present = ASSOCIATED(sap_ppnl)
    1596            8 :       IF (.NOT. ppnl_present) RETURN
    1597              : 
    1598            8 :       CALL timeset(routineN, handle)
    1599              : 
    1600            8 :       my_ref = .FALSE.
    1601            8 :       IF (PRESENT(refpoint)) THEN
    1602            8 :          my_ref = .TRUE.
    1603            8 :          CPASSERT(PRESENT(cell))
    1604              :       END IF
    1605              : 
    1606            8 :       natom = SIZE(particle_set)
    1607            8 :       nkind = SIZE(qs_kind_set)
    1608              : 
    1609              :       ! allocate integral storage
    1610            8 :       NULLIFY (sap_int)
    1611           56 :       ALLOCATE (sap_int(nkind*nkind))
    1612           40 :       DO ind = 1, nkind*nkind
    1613           32 :          NULLIFY (sap_int(ind)%alist, sap_int(ind)%asort, sap_int(ind)%aindex)
    1614           40 :          sap_int(ind)%nalist = 0
    1615              :       END DO
    1616              : 
    1617              :       ! build integrals over GTO + projector functions, refpoint actually
    1618            8 :       order = 1   ! only need first moments (x, y, z)
    1619              :       ! refpoint actually does not matter in this case, i. e. (order = 1 .and. commutator)
    1620            8 :       IF (my_ref) THEN
    1621              :          CALL build_sap_ints(sap_int, sap_ppnl, qs_kind_set, order, moment_mode=.TRUE., refpoint=refpoint, &
    1622            8 :                              particle_set=particle_set, cell=cell)
    1623              :       ELSE
    1624            0 :          CALL build_sap_ints(sap_int, sap_ppnl, qs_kind_set, order, moment_mode=.TRUE.)
    1625              :       END IF
    1626              : 
    1627            8 :       CALL sap_sort(sap_int)
    1628              : 
    1629              :       ! get access to basis sets
    1630           40 :       ALLOCATE (basis_set(nkind))
    1631           24 :       DO ikind = 1, nkind
    1632           16 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
    1633           24 :          IF (ASSOCIATED(orb_basis_set)) THEN
    1634           16 :             basis_set(ikind)%gto_basis_set => orb_basis_set
    1635              :          ELSE
    1636            0 :             NULLIFY (basis_set(ikind)%gto_basis_set)
    1637              :          END IF
    1638              :       END DO
    1639              : 
    1640              : !$OMP PARALLEL &
    1641              : !$OMP DEFAULT (NONE) &
    1642              : !$OMP SHARED  (basis_set, matrix_mag_nl, sap_int, natom, nkind, eps_ppnl, locks, sab_all, &
    1643              : !$OMP          particle_set, my_ref, refpoint) &
    1644              : !$OMP PRIVATE (ikind, jkind, iatom, jatom, cell_b, rab, lock_num, &
    1645              : !$OMP          iab, irow, icol, blocks_mag, r_ps, r_b, go, hash, &
    1646              : !$OMP          found, iac, ibc, alist_ac, alist_bc, acint, bcint, &
    1647            8 : !$OMP          achint, bchint, na, np, nb, kkind, kac, kbc)
    1648              : 
    1649              : !$OMP SINGLE
    1650              : !$    ALLOCATE (locks(nlock))
    1651              : !$OMP END SINGLE
    1652              : 
    1653              : !$OMP DO
    1654              : !$    DO lock_num = 1, nlock
    1655              : !$       call omp_init_lock(locks(lock_num))
    1656              : !$    END DO
    1657              : !$OMP END DO
    1658              : 
    1659              : !$OMP DO SCHEDULE(GUIDED)
    1660              :       DO slot = 1, sab_all(1)%nl_size
    1661              :          ! get indices
    1662              :          ikind = sab_all(1)%nlist_task(slot)%ikind
    1663              :          jkind = sab_all(1)%nlist_task(slot)%jkind
    1664              :          iatom = sab_all(1)%nlist_task(slot)%iatom
    1665              :          jatom = sab_all(1)%nlist_task(slot)%jatom
    1666              :          cell_b(:) = sab_all(1)%nlist_task(slot)%cell(:)
    1667              :          rab(1:3) = sab_all(1)%nlist_task(slot)%r(1:3)
    1668              : 
    1669              :          IF (.NOT. ASSOCIATED(basis_set(ikind)%gto_basis_set)) CYCLE
    1670              :          IF (.NOT. ASSOCIATED(basis_set(jkind)%gto_basis_set)) CYCLE
    1671              :          iab = ikind + nkind*(jkind - 1)
    1672              : 
    1673              :          IF (iatom <= jatom) THEN
    1674              :             irow = iatom
    1675              :             icol = jatom
    1676              :          ELSE
    1677              :             irow = jatom
    1678              :             icol = iatom
    1679              :          END IF
    1680              : 
    1681              :          ! get blocks
    1682              :          ALLOCATE (blocks_mag(3))
    1683              :          DO ind = 1, 3
    1684              :             CALL dbcsr_get_block_p(matrix_mag_nl(ind)%matrix, irow, icol, blocks_mag(ind)%block, found)
    1685              :          END DO
    1686              : 
    1687              :          go = (ASSOCIATED(blocks_mag(1)%block) .AND. ASSOCIATED(blocks_mag(2)%block) .AND. ASSOCIATED(blocks_mag(3)%block))
    1688              : 
    1689              :          IF (go) THEN
    1690              :             DO kkind = 1, nkind
    1691              :                iac = ikind + nkind*(kkind - 1)
    1692              :                ibc = jkind + nkind*(kkind - 1)
    1693              :                IF (.NOT. ASSOCIATED(sap_int(iac)%alist)) CYCLE
    1694              :                IF (.NOT. ASSOCIATED(sap_int(ibc)%alist)) CYCLE
    1695              :                CALL get_alist(sap_int(iac), alist_ac, iatom)
    1696              :                CALL get_alist(sap_int(ibc), alist_bc, jatom)
    1697              :                IF (.NOT. ASSOCIATED(alist_ac)) CYCLE
    1698              :                IF (.NOT. ASSOCIATED(alist_bc)) CYCLE
    1699              :                DO kac = 1, alist_ac%nclist
    1700              :                   DO kbc = 1, alist_bc%nclist
    1701              :                      IF (alist_ac%clist(kac)%catom /= alist_bc%clist(kbc)%catom) CYCLE
    1702              :                      IF (ALL(cell_b + alist_bc%clist(kbc)%cell - alist_ac%clist(kac)%cell == 0)) THEN
    1703              :                         IF (alist_ac%clist(kac)%maxac*alist_bc%clist(kbc)%maxach < eps_ppnl) CYCLE
    1704              : 
    1705              :                         acint => alist_ac%clist(kac)%acint
    1706              :                         bcint => alist_bc%clist(kbc)%acint
    1707              :                         achint => alist_ac%clist(kac)%achint
    1708              :                         bchint => alist_bc%clist(kbc)%achint
    1709              :                         na = SIZE(acint, 1)
    1710              :                         np = SIZE(acint, 2)
    1711              :                         nb = SIZE(bcint, 1)
    1712              :                         ! Position of the pseudized atom
    1713              :                         r_ps = particle_set(alist_ac%clist(kac)%catom)%r
    1714              :                         r_b = refpoint
    1715              : 
    1716              : !$                      hash = MOD((iatom - 1)*natom + jatom, nlock) + 1
    1717              : !$                      CALL omp_set_lock(locks(hash))
    1718              :                         ! assemble integrals
    1719              :                         IF (iatom <= jatom) THEN
    1720              :                            blocks_mag(1)%block(1:na, 1:nb) = blocks_mag(1)%block(1:na, 1:nb) + &
    1721              :                                               (r_ps(2) - r_b(2))*(MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 4))) - &
    1722              :                                                  MATMUL(achint(1:na, 1:np, 4), TRANSPOSE(bcint(1:nb, 1:np, 1)))) & !   R_y [V_nl, z]
    1723              :                                             - (r_ps(3) - r_b(3))*(MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 3))) - &
    1724              :                                                  MATMUL(achint(1:na, 1:np, 3), TRANSPOSE(bcint(1:nb, 1:np, 1))))   ! - R_z [V_nl, y]
    1725              :                            blocks_mag(2)%block(1:na, 1:nb) = blocks_mag(2)%block(1:na, 1:nb) + &
    1726              :                                               (r_ps(3) - r_b(3))*(MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 2))) - &
    1727              :                                                  MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 1)))) & !   R_z [V_nl, x]
    1728              :                                             - (r_ps(1) - r_b(1))*(MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 4))) - &
    1729              :                                                  MATMUL(achint(1:na, 1:np, 4), TRANSPOSE(bcint(1:nb, 1:np, 1))))   ! - R_x [V_nl, z]
    1730              :                            blocks_mag(3)%block(1:na, 1:nb) = blocks_mag(3)%block(1:na, 1:nb) + &
    1731              :                                               (r_ps(1) - r_b(1))*(MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 3))) - &
    1732              :                                                 MATMUL(achint(1:na, 1:np, 3), TRANSPOSE(bcint(1:nb, 1:np, 1)))) &  !   R_x [V_nl, y]
    1733              :                                             - (r_ps(2) - r_b(2))*(MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 2))) - &
    1734              :                                                 MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 1))))    ! - R_y [V_nl, x]
    1735              :                         ELSE
    1736              :                            blocks_mag(1)%block(1:nb, 1:na) = blocks_mag(1)%block(1:nb, 1:na) + &
    1737              :                                               (r_ps(2) - r_b(2))*(MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 4))) - &
    1738              :                                                  MATMUL(bchint(1:nb, 1:np, 4), TRANSPOSE(acint(1:na, 1:np, 1)))) & !   R_y [V_nl, z]
    1739              :                                             - (r_ps(3) - r_b(3))*(MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 3))) - &
    1740              :                                                  MATMUL(bchint(1:nb, 1:np, 3), TRANSPOSE(acint(1:na, 1:np, 1))))   ! - R_z [V_nl, y]
    1741              :                            blocks_mag(2)%block(1:nb, 1:na) = blocks_mag(2)%block(1:nb, 1:na) + &
    1742              :                                               (r_ps(3) - r_b(3))*(MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 2))) - &
    1743              :                                                  MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 1)))) & !   R_z [V_nl, x]
    1744              :                                             - (r_ps(1) - r_b(1))*(MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 4))) - &
    1745              :                                                  MATMUL(bchint(1:nb, 1:np, 4), TRANSPOSE(acint(1:na, 1:np, 1))))   ! - R_x [V_nl, z]
    1746              :                            blocks_mag(3)%block(1:nb, 1:na) = blocks_mag(3)%block(1:nb, 1:na) + &
    1747              :                                               (r_ps(1) - r_b(1))*(MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 3))) - &
    1748              :                                                 MATMUL(bchint(1:nb, 1:np, 3), TRANSPOSE(acint(1:na, 1:np, 1)))) &  !   R_x [V_nl, y]
    1749              :                                             - (r_ps(2) - r_b(2))*(MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 2))) - &
    1750              :                                                 MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 1))))    ! - R_y [V_nl, x]
    1751              :                         END IF
    1752              : !$                      CALL omp_unset_lock(locks(hash))
    1753              :                         EXIT ! We have found a match and there can be only one single match
    1754              :                      END IF
    1755              :                   END DO
    1756              :                END DO
    1757              :             END DO
    1758              :          END IF
    1759              : 
    1760              :          DO ind = 1, 3
    1761              :             NULLIFY (blocks_mag(ind)%block)
    1762              :          END DO
    1763              :          DEALLOCATE (blocks_mag)
    1764              :       END DO
    1765              : 
    1766              : !$OMP DO
    1767              : !$    DO lock_num = 1, nlock
    1768              : !$       call omp_destroy_lock(locks(lock_num))
    1769              : !$    END DO
    1770              : !$OMP END DO
    1771              : 
    1772              : !$OMP SINGLE
    1773              : !$    DEALLOCATE (locks)
    1774              : !$OMP END SINGLE NOWAIT
    1775              : 
    1776              : !$OMP END PARALLEL
    1777              : 
    1778            8 :       DEALLOCATE (basis_set)
    1779            8 :       CALL release_sap_int(sap_int)
    1780              : 
    1781            8 :       CALL timestop(handle)
    1782              : 
    1783           16 :    END SUBROUTINE build_com_nl_mag
    1784              : 
    1785              : ! **************************************************************************************************
    1786              : !> \brief Calculate matrix_rv(gamma, delta) = < R^eta_gamma * Vnl * r_delta > for GIAOs
    1787              : !> \param qs_kind_set ...
    1788              : !> \param sab_all ...
    1789              : !> \param sap_ppnl ...
    1790              : !> \param eps_ppnl ...
    1791              : !> \param particle_set ...
    1792              : !> \param matrix_rv ...
    1793              : !> \param ref_point ...
    1794              : !> \param cell ...
    1795              : !> \param direction_Or If set to true: calculate Vnl * r_delta
    1796              : !>                     Otherwise       calculate r_delta * Vnl
    1797              : ! **************************************************************************************************
    1798            0 :    SUBROUTINE build_com_vnl_giao(qs_kind_set, sab_all, sap_ppnl, eps_ppnl, particle_set, &
    1799              :                                  matrix_rv, ref_point, cell, direction_Or)
    1800              : 
    1801              :       TYPE(qs_kind_type), DIMENSION(:), INTENT(IN), &
    1802              :          POINTER                                         :: qs_kind_set
    1803              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1804              :          INTENT(IN), POINTER                             :: sab_all, sap_ppnl
    1805              :       REAL(KIND=dp), INTENT(IN)                          :: eps_ppnl
    1806              :       TYPE(particle_type), DIMENSION(:), INTENT(IN), &
    1807              :          POINTER                                         :: particle_set
    1808              :       TYPE(dbcsr_p_type), DIMENSION(:, :), &
    1809              :          INTENT(INOUT), OPTIONAL, POINTER                :: matrix_rv
    1810              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN), OPTIONAL  :: ref_point
    1811              :       TYPE(cell_type), INTENT(IN), OPTIONAL, POINTER     :: cell
    1812              :       LOGICAL                                            :: direction_Or
    1813              : 
    1814              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'build_com_vnl_giao'
    1815              :       INTEGER, PARAMETER                                 :: i_1 = 1
    1816              : 
    1817              :       INTEGER                                            :: delta, gamma, handle, i, iab, iac, &
    1818              :                                                             iatom, ibc, icol, ikind, irow, j, &
    1819              :                                                             jatom, jkind, kac, kbc, kkind, na, &
    1820              :                                                             natom, nb, nkind, np, order, slot
    1821              :       INTEGER, DIMENSION(3)                              :: cell_b
    1822              :       LOGICAL                                            :: found, my_ref, ppnl_present
    1823              :       REAL(KIND=dp), DIMENSION(3)                        :: rab, rf
    1824            0 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: achint, acint, bchint, bcint
    1825              :       TYPE(alist_type), POINTER                          :: alist_ac, alist_bc
    1826            0 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:, :)   :: blocks_rv
    1827              :       TYPE(gto_basis_set_p_type), ALLOCATABLE, &
    1828            0 :          DIMENSION(:)                                    :: basis_set
    1829              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    1830            0 :       TYPE(sap_int_type), DIMENSION(:), POINTER          :: sap_int
    1831              : 
    1832              : !$    INTEGER(kind=omp_lock_kind), &
    1833            0 : !$       ALLOCATABLE, DIMENSION(:) :: locks
    1834              : !$    INTEGER                                            :: lock_num, hash
    1835              : !$    INTEGER, PARAMETER                                 :: nlock = 501
    1836              : 
    1837            0 :       ppnl_present = ASSOCIATED(sap_ppnl)
    1838            0 :       IF (.NOT. ppnl_present) RETURN
    1839              : 
    1840            0 :       CALL timeset(routineN, handle)
    1841              : 
    1842            0 :       natom = SIZE(particle_set)
    1843              : 
    1844            0 :       my_ref = .FALSE.
    1845            0 :       IF (PRESENT(ref_point)) THEN
    1846            0 :          CPASSERT(PRESENT(cell)) ! need cell as well if refpoint is provided
    1847            0 :          rf = ref_point
    1848            0 :          my_ref = .TRUE.
    1849              :       END IF
    1850              : 
    1851            0 :       nkind = SIZE(qs_kind_set)
    1852              : 
    1853              :       ! sap_int needs to be shared as multiple threads need to access this
    1854            0 :       NULLIFY (sap_int)
    1855            0 :       ALLOCATE (sap_int(nkind*nkind))
    1856            0 :       DO i = 1, nkind*nkind
    1857            0 :          NULLIFY (sap_int(i)%alist, sap_int(i)%asort, sap_int(i)%aindex)
    1858            0 :          sap_int(i)%nalist = 0
    1859              :       END DO
    1860              : 
    1861            0 :       order = 1
    1862            0 :       IF (my_ref) THEN
    1863              :          ! calculate integrals <a|x^n|p>
    1864              :          CALL build_sap_ints(sap_int, sap_ppnl, qs_kind_set, order, moment_mode=.TRUE., refpoint=rf, &
    1865            0 :                              particle_set=particle_set, cell=cell)
    1866              :       ELSE
    1867            0 :          CALL build_sap_ints(sap_int, sap_ppnl, qs_kind_set, order, moment_mode=.TRUE.)
    1868              :       END IF
    1869              : 
    1870              :       ! *** Set up a sorting index
    1871            0 :       CALL sap_sort(sap_int)
    1872              : 
    1873            0 :       ALLOCATE (basis_set(nkind))
    1874            0 :       DO ikind = 1, nkind
    1875            0 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
    1876            0 :          IF (ASSOCIATED(orb_basis_set)) THEN
    1877            0 :             basis_set(ikind)%gto_basis_set => orb_basis_set
    1878              :          ELSE
    1879            0 :             NULLIFY (basis_set(ikind)%gto_basis_set)
    1880              :          END IF
    1881              :       END DO
    1882              : 
    1883            0 :       CALL get_neighbor_list_set_p(neighbor_list_sets=sab_all)
    1884              :       ! *** All integrals needed have been calculated and stored in sap_int
    1885              :       ! *** We now calculate the commutator matrix elements
    1886              : 
    1887              : !$OMP PARALLEL &
    1888              : !$OMP DEFAULT (NONE) &
    1889              : !$OMP SHARED  (basis_set, matrix_rv, &
    1890              : !$OMP          sap_int, nkind, eps_ppnl, locks, sab_all, &
    1891              : !$OMP          particle_set, direction_Or) &
    1892              : !$OMP PRIVATE (ikind, jkind, iatom, jatom, cell_b, rab, &
    1893              : !$OMP          iab, irow, icol, blocks_rv, &
    1894              : !$OMP          found, iac, ibc, alist_ac, alist_bc, &
    1895              : !$OMP          na, np, nb, kkind, kac, kbc, i, lock_num, &
    1896            0 : !$OMP          hash, natom, delta, gamma, achint, bchint, acint, bcint)
    1897              : 
    1898              : !$OMP SINGLE
    1899              : !$    ALLOCATE (locks(nlock))
    1900              : !$OMP END SINGLE
    1901              : 
    1902              : !$OMP DO
    1903              : !$    DO lock_num = 1, nlock
    1904              : !$       call omp_init_lock(locks(lock_num))
    1905              : !$    END DO
    1906              : !$OMP END DO
    1907              : 
    1908              : !$OMP DO SCHEDULE(GUIDED)
    1909              : 
    1910              :       DO slot = 1, sab_all(1)%nl_size
    1911              : 
    1912              :          ikind = sab_all(1)%nlist_task(slot)%ikind
    1913              :          jkind = sab_all(1)%nlist_task(slot)%jkind
    1914              :          iatom = sab_all(1)%nlist_task(slot)%iatom
    1915              :          jatom = sab_all(1)%nlist_task(slot)%jatom
    1916              :          cell_b(:) = sab_all(1)%nlist_task(slot)%cell(:)
    1917              :          rab(1:3) = sab_all(1)%nlist_task(slot)%r(1:3)
    1918              : 
    1919              :          IF (.NOT. ASSOCIATED(basis_set(ikind)%gto_basis_set)) CYCLE
    1920              :          IF (.NOT. ASSOCIATED(basis_set(jkind)%gto_basis_set)) CYCLE
    1921              :          iab = ikind + nkind*(jkind - 1)
    1922              : 
    1923              :          irow = iatom
    1924              :          icol = jatom
    1925              : 
    1926              :          ! allocate blocks
    1927              :          ALLOCATE (blocks_rv(3, 3))
    1928              : 
    1929              :          ! get blocks
    1930              :          DO i = 1, 3
    1931              :             DO j = 1, 3
    1932              :                CALL dbcsr_get_block_p(matrix_rv(i, j)%matrix, irow, icol, &
    1933              :                                       blocks_rv(i, j)%block, found)
    1934              :                blocks_rv(i, j)%block(:, :) = 0.0_dp
    1935              :                CPASSERT(found)
    1936              :             END DO
    1937              :          END DO
    1938              : 
    1939              :          ! loop over all kinds for projector atom
    1940              :          ! < iatom | katom > h < katom | jatom >
    1941              :          DO kkind = 1, nkind
    1942              :             iac = ikind + nkind*(kkind - 1)
    1943              :             ibc = jkind + nkind*(kkind - 1)
    1944              :             IF (.NOT. ASSOCIATED(sap_int(iac)%alist)) CYCLE
    1945              :             IF (.NOT. ASSOCIATED(sap_int(ibc)%alist)) CYCLE
    1946              :             CALL get_alist(sap_int(iac), alist_ac, iatom)
    1947              :             CALL get_alist(sap_int(ibc), alist_bc, jatom)
    1948              :             IF (.NOT. ASSOCIATED(alist_ac)) CYCLE
    1949              :             IF (.NOT. ASSOCIATED(alist_bc)) CYCLE
    1950              :             DO kac = 1, alist_ac%nclist
    1951              :                DO kbc = 1, alist_bc%nclist
    1952              :                   IF (alist_ac%clist(kac)%catom /= alist_bc%clist(kbc)%catom) CYCLE
    1953              : 
    1954              :                   IF (ALL(cell_b + alist_bc%clist(kbc)%cell - alist_ac%clist(kac)%cell == 0)) THEN
    1955              :                      IF (alist_ac%clist(kac)%maxac*alist_bc%clist(kbc)%maxach < eps_ppnl) CYCLE
    1956              :                      acint => alist_ac%clist(kac)%acint
    1957              :                      bcint => alist_bc%clist(kbc)%acint
    1958              :                      achint => alist_ac%clist(kac)%achint
    1959              :                      bchint => alist_bc%clist(kbc)%achint
    1960              :                      na = SIZE(acint, 1)
    1961              :                      np = SIZE(acint, 2)
    1962              :                      nb = SIZE(bcint, 1)
    1963              : !$                   hash = MOD((iatom - 1)*natom + jatom, nlock) + 1
    1964              : !$                   CALL omp_set_lock(locks(hash))
    1965              : 
    1966              :                      !! The atom index is alist_ac%clist(kac)%catom
    1967              :                      ! The coordinate is particle_set(alist_ac%clist(kac)%catom)%r(:)
    1968              :                      IF (direction_Or) THEN  ! V * r_delta * (R^eta_gamma - R^nu_gamma)
    1969              :                         DO delta = 1, 3
    1970              :                            DO gamma = 1, 3
    1971              :                               blocks_rv(gamma, delta)%block(1:na, 1:nb) &
    1972              :                                  = blocks_rv(gamma, delta)%block(1:na, 1:nb) + &
    1973              :                                    MATMUL(achint(1:na, 1:np, i_1), TRANSPOSE(bcint(1:nb, 1:np, delta + 1))) &
    1974              :                                    *(particle_set(alist_ac%clist(kac)%catom)%r(gamma) - particle_set(jatom)%r(gamma))
    1975              :                            END DO
    1976              :                         END DO
    1977              :                      ELSE                   ! r_delta * V * (R^eta_gamma - R^nu_gamma)
    1978              :                         DO delta = 1, 3
    1979              :                            DO gamma = 1, 3
    1980              :                               blocks_rv(gamma, delta)%block(1:na, 1:nb) &
    1981              :                                  = blocks_rv(gamma, delta)%block(1:na, 1:nb) + &
    1982              :                                    MATMUL(achint(1:na, 1:np, delta + 1), TRANSPOSE(bcint(1:nb, 1:np, i_1))) &
    1983              :                                    *(particle_set(alist_ac%clist(kac)%catom)%r(gamma) - particle_set(jatom)%r(gamma))
    1984              :                            END DO
    1985              :                         END DO
    1986              :                      END IF
    1987              : 
    1988              : !$                   CALL omp_unset_lock(locks(hash))
    1989              :                      EXIT ! We have found a match and there can be only one single match
    1990              :                   END IF
    1991              :                END DO
    1992              :             END DO
    1993              :          END DO
    1994              :          DO delta = 1, 3
    1995              :             DO gamma = 1, 3
    1996              :                NULLIFY (blocks_rv(gamma, delta)%block)
    1997              :             END DO
    1998              :          END DO
    1999              :          DEALLOCATE (blocks_rv)
    2000              :       END DO
    2001              : 
    2002              : !$OMP DO
    2003              : !$    DO lock_num = 1, nlock
    2004              : !$       call omp_destroy_lock(locks(lock_num))
    2005              : !$    END DO
    2006              : !$OMP END DO
    2007              : 
    2008              : !$OMP SINGLE
    2009              : !$    DEALLOCATE (locks)
    2010              : !$OMP END SINGLE NOWAIT
    2011              : 
    2012              : !$OMP END PARALLEL
    2013              : 
    2014            0 :       CALL release_sap_int(sap_int)
    2015              : 
    2016            0 :       DEALLOCATE (basis_set)
    2017              : 
    2018            0 :       CALL timestop(handle)
    2019              : 
    2020            0 :    END SUBROUTINE build_com_vnl_giao
    2021              : 
    2022              : END MODULE commutator_rpnl
        

Generated by: LCOV version 2.0-1