LCOV - code coverage report
Current view: top level - src - commutator_rpnl.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:42dac4a) Lines: 50.3 % 199 100
Test Date: 2025-07-25 12:55:17 Functions: 50.0 % 4 2

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2025 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              :             ELSEIF (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          116 :    SUBROUTINE build_com_mom_nl(qs_kind_set, sab_all, sap_ppnl, eps_ppnl, particle_set, cell, matrix_rv, matrix_rxrv, &
     438          174 :                     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           58 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: achint, acint, bchint, bcint
     471              :       TYPE(alist_type), POINTER                          :: alist_ac, alist_bc
     472           58 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:)      :: blocks_rrv, blocks_rrv_vrr, blocks_rv, &
     473           58 :                                                             blocks_rvr, blocks_rxrv
     474           58 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:, :)   :: blocks_r_doublecom, blocks_r_rxvr, &
     475           58 :                                                             blocks_rxvr_r
     476              :       TYPE(gto_basis_set_p_type), ALLOCATABLE, &
     477           58 :          DIMENSION(:)                                    :: basis_set
     478              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
     479           58 :       TYPE(sap_int_type), DIMENSION(:), POINTER          :: sap_int
     480              : 
     481              : !$    INTEGER(kind=omp_lock_kind), &
     482           58 : !$       ALLOCATABLE, DIMENSION(:) :: locks
     483              : !$    INTEGER                                            :: lock_num, hash
     484              : !$    INTEGER, PARAMETER                                 :: nlock = 501
     485              : 
     486           58 :       ppnl_present = ASSOCIATED(sap_ppnl)
     487           58 :       IF (.NOT. ppnl_present) RETURN
     488              : 
     489           36 :       CALL timeset(routineN, handle)
     490              : 
     491           36 :       my_r_doublecom = .FALSE.
     492           36 :       my_r_rxvr = .FALSE.
     493           36 :       my_rxvr_r = .FALSE.
     494           36 :       my_rxrv = .FALSE.
     495           36 :       my_rrv = .FALSE.
     496           36 :       my_rv = .FALSE.
     497           36 :       my_rvr = .FALSE.
     498           36 :       my_rrv_vrr = .FALSE.
     499           36 :       IF (PRESENT(matrix_r_doublecom)) my_r_doublecom = .TRUE.
     500           36 :       IF (PRESENT(matrix_r_rxvr)) my_r_rxvr = .TRUE.
     501           36 :       IF (PRESENT(matrix_rxvr_r)) my_rxvr_r = .TRUE.
     502           36 :       IF (PRESENT(matrix_rxrv)) my_rxrv = .TRUE.
     503           36 :       IF (PRESENT(matrix_rrv)) my_rrv = .TRUE.
     504           36 :       IF (PRESENT(matrix_rv)) my_rv = .TRUE.
     505           36 :       IF (PRESENT(matrix_rvr)) my_rvr = .TRUE.
     506           36 :       IF (PRESENT(matrix_rrv_vrr)) my_rrv_vrr = .TRUE.
     507           36 :       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           36 :       natom = SIZE(particle_set)
     512              : 
     513           36 :       IF (my_rxrv .OR. my_rrv .OR. my_r_rxvr .OR. my_rxvr_r .OR. my_r_doublecom) THEN
     514           16 :          order = 2
     515           16 :          CPASSERT(PRESENT(ref_point)) ! need reference point for r x [r,Vnl] and [rr,Vnl]
     516           20 :       ELSE IF (my_rvr .OR. my_rrv_vrr) THEN
     517            2 :          order = 2
     518              :       ELSE
     519           18 :          order = 1
     520              :       END IF
     521              : 
     522              :       ! When we want the double commutator [[Vnl, r], r], we also want to fix the pseudoatom
     523           36 :       IF (my_r_doublecom) THEN
     524            6 :          CPASSERT(PRESENT(pseudoatom))
     525              :       END IF
     526              : 
     527          144 :       periodic = ANY(cell%perd > 0)
     528           36 :       my_ref = .FALSE.
     529           36 :       IF (PRESENT(ref_point)) THEN
     530           18 :          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            0 :             IF (order .GT. 1) THEN
     535            0 :                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           36 :       nkind = SIZE(qs_kind_set)
     541              : 
     542              :       !sap_int needs to be shared as multiple threads need to access this
     543           36 :       NULLIFY (sap_int)
     544          252 :       ALLOCATE (sap_int(nkind*nkind))
     545          180 :       DO i = 1, nkind*nkind
     546          144 :          NULLIFY (sap_int(i)%alist, sap_int(i)%asort, sap_int(i)%aindex)
     547          180 :          sap_int(i)%nalist = 0
     548              :       END DO
     549              : 
     550           36 :       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           18 :          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           36 :       CALL sap_sort(sap_int)
     560              : 
     561          180 :       ALLOCATE (basis_set(nkind))
     562          108 :       DO ikind = 1, nkind
     563           72 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
     564          108 :          IF (ASSOCIATED(orb_basis_set)) THEN
     565           72 :             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           36 :       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           36 : !$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              :                            ! with LAPACK
     872              :                            ! CALL dgemm("N", "T", na, nb, np, 1.0_dp, achint(1, 1, 9), na, &
     873              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rxrv(1)%block, SIZE(blocks_rxrv(1)%block, 1)) ! yzV
     874              :                            ! CALL dgemm("N", "T", na, nb, np, -1.0_dp, achint(1, 1, 3), na, &
     875              :                            !            bcint(1, 1, 4), nb, 1.0_dp, blocks_rxrv(1)%block, SIZE(blocks_rxrv(1)%block, 1)) ! -yVz
     876              :                            ! CALL dgemm("N", "T", na, nb, np, -1.0_dp, achint(1, 1, 9), na, &
     877              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rxrv(1)%block, SIZE(blocks_rxrv(1)%block, 1)) ! -zyV
     878              :                            ! CALL dgemm("N", "T", na, nb, np, 1.0_dp, achint(1, 1, 4), na, &
     879              :                            !            bcint(1, 1, 3), nb, 1.0_dp, blocks_rxrv(1)%block, SIZE(blocks_rxrv(1)%block, 1)) ! zVy
     880              :                            ! with MATMUL
     881              :                            IF (iatom <= jatom) THEN
     882              :                               blocks_rxrv(1)%block(1:na, 1:nb) = blocks_rxrv(1)%block(1:na, 1:nb) + &
     883              :                                                                  MATMUL(achint(1:na, 1:np, 9), TRANSPOSE(bcint(1:nb, 1:np, 1)))    ! yzV
     884              :                               blocks_rxrv(1)%block(1:na, 1:nb) = blocks_rxrv(1)%block(1:na, 1:nb) - &
     885              :                                                                  MATMUL(achint(1:na, 1:np, 3), TRANSPOSE(bcint(1:nb, 1:np, 4)))    ! -yVz
     886              :                               blocks_rxrv(1)%block(1:na, 1:nb) = blocks_rxrv(1)%block(1:na, 1:nb) - &
     887              :                                                                  MATMUL(achint(1:na, 1:np, 9), TRANSPOSE(bcint(1:nb, 1:np, 1)))    ! -zyV
     888              :                               blocks_rxrv(1)%block(1:na, 1:nb) = blocks_rxrv(1)%block(1:na, 1:nb) + &
     889              :                                                                  MATMUL(achint(1:na, 1:np, 4), TRANSPOSE(bcint(1:nb, 1:np, 3)))    ! zVy
     890              :                            ELSE
     891              :                               blocks_rxrv(1)%block(1:nb, 1:na) = blocks_rxrv(1)%block(1:nb, 1:na) + &
     892              :                                                                  MATMUL(bchint(1:nb, 1:np, 9), TRANSPOSE(acint(1:na, 1:np, 1)))    ! yzV
     893              :                               blocks_rxrv(1)%block(1:nb, 1:na) = blocks_rxrv(1)%block(1:nb, 1:na) - &
     894              :                                                                  MATMUL(bchint(1:nb, 1:np, 3), TRANSPOSE(acint(1:na, 1:np, 4)))    ! -yVz
     895              :                               blocks_rxrv(1)%block(1:nb, 1:na) = blocks_rxrv(1)%block(1:nb, 1:na) - &
     896              :                                                                  MATMUL(bchint(1:nb, 1:np, 9), TRANSPOSE(acint(1:na, 1:np, 1)))    ! -zyV
     897              :                               blocks_rxrv(1)%block(1:nb, 1:na) = blocks_rxrv(1)%block(1:nb, 1:na) + &
     898              :                                                                  MATMUL(bchint(1:nb, 1:np, 4), TRANSPOSE(acint(1:na, 1:np, 3)))    ! zVy
     899              :                            END IF
     900              : 
     901              :                            ! y-component (z [x,Vnl] - x [z, Vnl])
     902              :                            ! with LAPACK
     903              :                            ! CALL dgemm("N", "T", na, nb, np, 1.0_dp, achint(1, 1, 7), na, &
     904              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rxrv(2)%block, SIZE(blocks_rxrv(2)%block, 1)) ! zxV
     905              :                            ! CALL dgemm("N", "T", na, nb, np, -1.0_dp, achint(1, 1, 4), na, &
     906              :                            !            bcint(1, 1, 2), nb, 1.0_dp, blocks_rxrv(2)%block, SIZE(blocks_rxrv(2)%block, 1)) ! -zVx
     907              :                            ! CALL dgemm("N", "T", na, nb, np, -1.0_dp, achint(1, 1, 7), na, &
     908              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rxrv(2)%block, SIZE(blocks_rxrv(2)%block, 1)) ! -xzV
     909              :                            ! CALL dgemm("N", "T", na, nb, np, 1.0_dp, achint(1, 1, 2), na, &
     910              :                            !            bcint(1, 1, 4), nb, 1.0_dp, blocks_rxrv(2)%block, SIZE(blocks_rxrv(2)%block, 1)) ! xVz
     911              :                            ! with MATMUL
     912              :                            IF (iatom <= jatom) THEN
     913              :                               blocks_rxrv(2)%block(1:na, 1:nb) = blocks_rxrv(2)%block(1:na, 1:nb) + &
     914              :                                                                  MATMUL(achint(1:na, 1:np, 7), TRANSPOSE(bcint(1:nb, 1:np, 1)))    ! zxV
     915              :                               blocks_rxrv(2)%block(1:na, 1:nb) = blocks_rxrv(2)%block(1:na, 1:nb) - &
     916              :                                                                  MATMUL(achint(1:na, 1:np, 4), TRANSPOSE(bcint(1:nb, 1:np, 2)))    ! -zVx
     917              :                               blocks_rxrv(2)%block(1:na, 1:nb) = blocks_rxrv(2)%block(1:na, 1:nb) - &
     918              :                                                                  MATMUL(achint(1:na, 1:np, 7), TRANSPOSE(bcint(1:nb, 1:np, 1)))    ! -xzV
     919              :                               blocks_rxrv(2)%block(1:na, 1:nb) = blocks_rxrv(2)%block(1:na, 1:nb) + &
     920              :                                                                  MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 4)))    ! xVz
     921              :                            ELSE
     922              :                               blocks_rxrv(2)%block(1:nb, 1:na) = blocks_rxrv(2)%block(1:nb, 1:na) + &
     923              :                                                                  MATMUL(bchint(1:nb, 1:np, 7), TRANSPOSE(acint(1:na, 1:np, 1)))    ! zxV
     924              :                               blocks_rxrv(2)%block(1:nb, 1:na) = blocks_rxrv(2)%block(1:nb, 1:na) - &
     925              :                                                                  MATMUL(bchint(1:nb, 1:np, 4), TRANSPOSE(acint(1:na, 1:np, 2)))    ! -zVx
     926              :                               blocks_rxrv(2)%block(1:nb, 1:na) = blocks_rxrv(2)%block(1:nb, 1:na) - &
     927              :                                                                  MATMUL(bchint(1:nb, 1:np, 7), TRANSPOSE(acint(1:na, 1:np, 1)))    ! -xzV
     928              :                               blocks_rxrv(2)%block(1:nb, 1:na) = blocks_rxrv(2)%block(1:nb, 1:na) + &
     929              :                                                                  MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 4)))    ! xVz
     930              :                            END IF
     931              : 
     932              :                            ! z-component (x [y,Vnl] - y [x, Vnl])
     933              :                            ! with LAPACK
     934              :                            ! CALL dgemm("N", "T", na, nb, np, 1.0_dp, achint(1, 1, 6), na, &
     935              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rxrv(3)%block, SIZE(blocks_rxrv(3)%block, 1)) ! xyV
     936              :                            ! CALL dgemm("N", "T", na, nb, np, -1.0_dp, achint(1, 1, 2), na, &
     937              :                            !            bcint(1, 1, 3), nb, 1.0_dp, blocks_rxrv(3)%block, SIZE(blocks_rxrv(3)%block, 1)) ! -xVy
     938              :                            ! CALL dgemm("N", "T", na, nb, np, -1.0_dp, achint(1, 1, 6), na, &
     939              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rxrv(3)%block, SIZE(blocks_rxrv(3)%block, 1)) ! -yxV
     940              :                            ! CALL dgemm("N", "T", na, nb, np, 1.0_dp, achint(1, 1, 3), na, &
     941              :                            !            bcint(1, 1, 2), nb, 1.0_dp, blocks_rxrv(3)%block, SIZE(blocks_rxrv(3)%block, 1)) ! yVx
     942              :                            ! with MATMUL
     943              :                            IF (iatom <= jatom) THEN
     944              :                               blocks_rxrv(3)%block(1:na, 1:nb) = blocks_rxrv(3)%block(1:na, 1:nb) + &
     945              :                                                                  MATMUL(achint(1:na, 1:np, 6), TRANSPOSE(bcint(1:nb, 1:np, 1)))    ! xyV
     946              :                               blocks_rxrv(3)%block(1:na, 1:nb) = blocks_rxrv(3)%block(1:na, 1:nb) - &
     947              :                                                                  MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 3)))    ! -xVy
     948              :                               blocks_rxrv(3)%block(1:na, 1:nb) = blocks_rxrv(3)%block(1:na, 1:nb) - &
     949              :                                                                  MATMUL(achint(1:na, 1:np, 6), TRANSPOSE(bcint(1:nb, 1:np, 1)))    ! -yxV
     950              :                               blocks_rxrv(3)%block(1:na, 1:nb) = blocks_rxrv(3)%block(1:na, 1:nb) + &
     951              :                                                                  MATMUL(achint(1:na, 1:np, 3), TRANSPOSE(bcint(1:nb, 1:np, 2)))    ! zVx
     952              :                            ELSE
     953              :                               blocks_rxrv(3)%block(1:nb, 1:na) = blocks_rxrv(3)%block(1:nb, 1:na) + &
     954              :                                                                  MATMUL(bchint(1:nb, 1:np, 6), TRANSPOSE(acint(1:na, 1:np, 1)))    ! xyV
     955              :                               blocks_rxrv(3)%block(1:nb, 1:na) = blocks_rxrv(3)%block(1:nb, 1:na) - &
     956              :                                                                  MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 3)))    ! -xVy
     957              :                               blocks_rxrv(3)%block(1:nb, 1:na) = blocks_rxrv(3)%block(1:nb, 1:na) - &
     958              :                                                                  MATMUL(bchint(1:nb, 1:np, 6), TRANSPOSE(acint(1:na, 1:np, 1)))    ! -yxV
     959              :                               blocks_rxrv(3)%block(1:nb, 1:na) = blocks_rxrv(3)%block(1:nb, 1:na) + &
     960              :                                                                  MATMUL(bchint(1:nb, 1:np, 3), TRANSPOSE(acint(1:na, 1:np, 2)))    ! zVx
     961              :                            END IF
     962              :                         END IF
     963              : 
     964              :                         IF (my_rrv) THEN
     965              :                            ! r_alpha * r_beta * Vnl
     966              :                            ! with LAPACK
     967              :                            ! CALL dgemm("N", "T", na, nb, np, 1._dp, achint(1, 1, 5), na, &
     968              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rrv(1)%block, SIZE(blocks_rrv(1)%block, 1)) ! xxV
     969              :                            ! CALL dgemm("N", "T", na, nb, np, 1._dp, achint(1, 1, 6), na, &
     970              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rrv(2)%block, SIZE(blocks_rrv(2)%block, 1)) ! xyV
     971              :                            ! CALL dgemm("N", "T", na, nb, np, 1._dp, achint(1, 1, 7), na, &
     972              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rrv(3)%block, SIZE(blocks_rrv(3)%block, 1)) ! xzV
     973              :                            ! CALL dgemm("N", "T", na, nb, np, 1._dp, achint(1, 1, 8), na, &
     974              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rrv(4)%block, SIZE(blocks_rrv(4)%block, 1)) ! yyV
     975              :                            ! CALL dgemm("N", "T", na, nb, np, 1._dp, achint(1, 1, 9), na, &
     976              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rrv(5)%block, SIZE(blocks_rrv(5)%block, 1)) ! yzV
     977              :                            ! CALL dgemm("N", "T", na, nb, np, 1._dp, achint(1, 1, 10), na, &
     978              :                            !            bcint(1, 1, 1), nb, 1.0_dp, blocks_rrv(6)%block, SIZE(blocks_rrv(6)%block, 1)) ! zzV
     979              :                            ! with MATMUL
     980              :                            IF (iatom <= jatom) THEN
     981              :                               blocks_rrv(1)%block(1:na, 1:nb) = blocks_rrv(1)%block(1:na, 1:nb) + &
     982              :                                                                 MATMUL(achint(1:na, 1:np, 5), TRANSPOSE(bcint(1:nb, 1:np, 1)))   ! xxV
     983              :                               blocks_rrv(2)%block(1:na, 1:nb) = blocks_rrv(2)%block(1:na, 1:nb) + &
     984              :                                                                 MATMUL(achint(1:na, 1:np, 6), TRANSPOSE(bcint(1:nb, 1:np, 1)))   ! xyV
     985              :                               blocks_rrv(3)%block(1:na, 1:nb) = blocks_rrv(3)%block(1:na, 1:nb) + &
     986              :                                                                 MATMUL(achint(1:na, 1:np, 7), TRANSPOSE(bcint(1:nb, 1:np, 1)))   ! xzV
     987              :                               blocks_rrv(4)%block(1:na, 1:nb) = blocks_rrv(4)%block(1:na, 1:nb) + &
     988              :                                                                 MATMUL(achint(1:na, 1:np, 8), TRANSPOSE(bcint(1:nb, 1:np, 1)))   ! yyV
     989              :                               blocks_rrv(5)%block(1:na, 1:nb) = blocks_rrv(5)%block(1:na, 1:nb) + &
     990              :                                                                 MATMUL(achint(1:na, 1:np, 9), TRANSPOSE(bcint(1:nb, 1:np, 1)))   ! yzV
     991              :                               blocks_rrv(6)%block(1:na, 1:nb) = blocks_rrv(6)%block(1:na, 1:nb) + &
     992              :                                                                 MATMUL(achint(1:na, 1:np, 10), TRANSPOSE(bcint(1:nb, 1:np, 1)))   ! zzV
     993              :                            ELSE
     994              :                               blocks_rrv(1)%block(1:nb, 1:na) = blocks_rrv(1)%block(1:nb, 1:na) + &
     995              :                                                                 MATMUL(bchint(1:nb, 1:np, 5), TRANSPOSE(acint(1:na, 1:np, 1)))   ! xxV
     996              :                               blocks_rrv(2)%block(1:nb, 1:na) = blocks_rrv(2)%block(1:nb, 1:na) + &
     997              :                                                                 MATMUL(bchint(1:nb, 1:np, 6), TRANSPOSE(acint(1:na, 1:np, 1)))   ! xyV
     998              :                               blocks_rrv(3)%block(1:nb, 1:na) = blocks_rrv(3)%block(1:nb, 1:na) + &
     999              :                                                                 MATMUL(bchint(1:nb, 1:np, 7), TRANSPOSE(acint(1:na, 1:np, 1)))   ! xzV
    1000              :                               blocks_rrv(4)%block(1:nb, 1:na) = blocks_rrv(4)%block(1:nb, 1:na) + &
    1001              :                                                                 MATMUL(bchint(1:nb, 1:np, 8), TRANSPOSE(acint(1:na, 1:np, 1)))   ! yyV
    1002              :                               blocks_rrv(5)%block(1:nb, 1:na) = blocks_rrv(5)%block(1:nb, 1:na) + &
    1003              :                                                                 MATMUL(bchint(1:nb, 1:np, 9), TRANSPOSE(acint(1:na, 1:np, 1)))   ! yzV
    1004              :                               blocks_rrv(6)%block(1:nb, 1:na) = blocks_rrv(6)%block(1:nb, 1:na) + &
    1005              :                                                                 MATMUL(bchint(1:nb, 1:np, 10), TRANSPOSE(acint(1:na, 1:np, 1)))   ! zzV
    1006              :                            END IF
    1007              : 
    1008              :                            ! - Vnl * r_alpha * r_beta
    1009              :                            ! with LAPACK
    1010              :                            ! CALL dgemm("N", "T", na, nb, np, -1._dp, achint(1, 1, 1), na, &
    1011              :                            !            bcint(1, 1, 5), nb, 1.0_dp, blocks_rrv(1)%block, SIZE(blocks_rrv(1)%block, 1)) ! Vxx
    1012              :                            ! CALL dgemm("N", "T", na, nb, np, -1._dp, achint(1, 1, 1), na, &
    1013              :                            !            bcint(1, 1, 6), nb, 1.0_dp, blocks_rrv(2)%block, SIZE(blocks_rrv(2)%block, 1)) ! Vxy
    1014              :                            ! CALL dgemm("N", "T", na, nb, np, -1._dp, achint(1, 1, 1), na, &
    1015              :                            !            bcint(1, 1, 7), nb, 1.0_dp, blocks_rrv(3)%block, SIZE(blocks_rrv(3)%block, 1)) ! Vxz
    1016              :                            ! CALL dgemm("N", "T", na, nb, np, -1._dp, achint(1, 1, 1), na, &
    1017              :                            !            bcint(1, 1, 8), nb, 1.0_dp, blocks_rrv(4)%block, SIZE(blocks_rrv(4)%block, 1)) ! Vyy
    1018              :                            ! CALL dgemm("N", "T", na, nb, np, -1._dp, achint(1, 1, 1), na, &
    1019              :                            !            bcint(1, 1, 9), nb, 1.0_dp, blocks_rrv(5)%block, SIZE(blocks_rrv(5)%block, 1)) ! Vyz
    1020              :                            ! CALL dgemm("N", "T", na, nb, np, -1._dp, achint(1, 1, 1), na, &
    1021              :                            !            bcint(1, 1, 10), nb, 1.0_dp, blocks_rrv(6)%block, SIZE(blocks_rrv(6)%block, 1)) ! Vzz
    1022              :                            ! with MATMUL
    1023              :                            IF (iatom <= jatom) THEN
    1024              :                               blocks_rrv(1)%block(1:na, 1:nb) = blocks_rrv(1)%block(1:na, 1:nb) - &
    1025              :                                                                 MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 5)))   ! -Vxx
    1026              :                               blocks_rrv(2)%block(1:na, 1:nb) = blocks_rrv(2)%block(1:na, 1:nb) - &
    1027              :                                                                 MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 6)))   ! -Vxy
    1028              :                               blocks_rrv(3)%block(1:na, 1:nb) = blocks_rrv(3)%block(1:na, 1:nb) - &
    1029              :                                                                 MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 7)))   ! -Vxz
    1030              :                               blocks_rrv(4)%block(1:na, 1:nb) = blocks_rrv(4)%block(1:na, 1:nb) - &
    1031              :                                                                 MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 8)))   ! -Vyy
    1032              :                               blocks_rrv(5)%block(1:na, 1:nb) = blocks_rrv(5)%block(1:na, 1:nb) - &
    1033              :                                                                 MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 9)))   ! -Vyz
    1034              :                               blocks_rrv(6)%block(1:na, 1:nb) = blocks_rrv(6)%block(1:na, 1:nb) - &
    1035              :                                                                 MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 10)))   ! -Vzz
    1036              :                            ELSE
    1037              :                               blocks_rrv(1)%block(1:nb, 1:na) = blocks_rrv(1)%block(1:nb, 1:na) - &
    1038              :                                                                 MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 5)))   ! -Vxx
    1039              :                               blocks_rrv(2)%block(1:nb, 1:na) = blocks_rrv(2)%block(1:nb, 1:na) - &
    1040              :                                                                 MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 6)))   ! -Vxy
    1041              :                               blocks_rrv(3)%block(1:nb, 1:na) = blocks_rrv(3)%block(1:nb, 1:na) - &
    1042              :                                                                 MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 7)))   ! -Vxz
    1043              :                               blocks_rrv(4)%block(1:nb, 1:na) = blocks_rrv(4)%block(1:nb, 1:na) - &
    1044              :                                                                 MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 8)))   ! -Vyy
    1045              :                               blocks_rrv(5)%block(1:nb, 1:na) = blocks_rrv(5)%block(1:nb, 1:na) - &
    1046              :                                                                 MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 9)))   ! -Vyz
    1047              :                               blocks_rrv(6)%block(1:nb, 1:na) = blocks_rrv(6)%block(1:nb, 1:na) - &
    1048              :                                                                 MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 10)))   ! -Vzz
    1049              :                            END IF
    1050              :                         END IF
    1051              : 
    1052              :                         IF (my_rvr) THEN
    1053              :                            ! r_alpha * Vnl * r_beta
    1054              :                            IF (iatom <= jatom) THEN
    1055              :                               blocks_rvr(1)%block(1:na, 1:nb) = blocks_rvr(1)%block(1:na, 1:nb) + &
    1056              :                                                                 MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 2)))   ! xVx
    1057              :                               blocks_rvr(2)%block(1:na, 1:nb) = blocks_rvr(2)%block(1:na, 1:nb) + &
    1058              :                                                                 MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 3)))   ! xVy
    1059              :                               blocks_rvr(3)%block(1:na, 1:nb) = blocks_rvr(3)%block(1:na, 1:nb) + &
    1060              :                                                                 MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 4)))   ! xVz
    1061              :                               blocks_rvr(4)%block(1:na, 1:nb) = blocks_rvr(4)%block(1:na, 1:nb) + &
    1062              :                                                                 MATMUL(achint(1:na, 1:np, 3), TRANSPOSE(bcint(1:nb, 1:np, 3)))   ! yVy
    1063              :                               blocks_rvr(5)%block(1:na, 1:nb) = blocks_rvr(5)%block(1:na, 1:nb) + &
    1064              :                                                                 MATMUL(achint(1:na, 1:np, 3), TRANSPOSE(bcint(1:nb, 1:np, 4)))   ! yVz
    1065              :                               blocks_rvr(6)%block(1:na, 1:nb) = blocks_rvr(6)%block(1:na, 1:nb) + &
    1066              :                                                                 MATMUL(achint(1:na, 1:np, 4), TRANSPOSE(bcint(1:nb, 1:np, 4)))   ! zVz
    1067              :                            ELSE
    1068              :                               blocks_rvr(1)%block(1:nb, 1:na) = blocks_rvr(1)%block(1:nb, 1:na) + &
    1069              :                                                                 MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 2)))   ! xVx
    1070              :                               blocks_rvr(2)%block(1:nb, 1:na) = blocks_rvr(2)%block(1:nb, 1:na) + &
    1071              :                                                                 MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 3)))   ! xVy
    1072              :                               blocks_rvr(3)%block(1:nb, 1:na) = blocks_rvr(3)%block(1:nb, 1:na) + &
    1073              :                                                                 MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 4)))   ! xVz
    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)))   ! yVy
    1076              :                               blocks_rvr(5)%block(1:nb, 1:na) = blocks_rvr(5)%block(1:nb, 1:na) + &
    1077              :                                                                 MATMUL(bchint(1:nb, 1:np, 3), TRANSPOSE(acint(1:na, 1:np, 4)))   ! yVz
    1078              :                               blocks_rvr(6)%block(1:nb, 1:na) = blocks_rvr(6)%block(1:nb, 1:na) + &
    1079              :                                                                 MATMUL(bchint(1:nb, 1:np, 4), TRANSPOSE(acint(1:na, 1:np, 4)))   ! zVz
    1080              :                            END IF
    1081              :                         END IF
    1082              : 
    1083              :                         IF (my_rrv_vrr) THEN
    1084              :                            ! r_alpha * r_beta * Vnl
    1085              :                            IF (iatom <= jatom) THEN
    1086              :                               blocks_rrv_vrr(1)%block(1:na, 1:nb) = blocks_rrv_vrr(1)%block(1:na, 1:nb) + &
    1087              :                                                                     MATMUL(achint(1:na, 1:np, 5), TRANSPOSE(bcint(1:nb, 1:np, 1)))   ! xxV
    1088              :                               blocks_rrv_vrr(2)%block(1:na, 1:nb) = blocks_rrv_vrr(2)%block(1:na, 1:nb) + &
    1089              :                                                                     MATMUL(achint(1:na, 1:np, 6), TRANSPOSE(bcint(1:nb, 1:np, 1)))   ! xyV
    1090              :                               blocks_rrv_vrr(3)%block(1:na, 1:nb) = blocks_rrv_vrr(3)%block(1:na, 1:nb) + &
    1091              :                                                                     MATMUL(achint(1:na, 1:np, 7), TRANSPOSE(bcint(1:nb, 1:np, 1)))   ! xzV
    1092              :                               blocks_rrv_vrr(4)%block(1:na, 1:nb) = blocks_rrv_vrr(4)%block(1:na, 1:nb) + &
    1093              :                                                                     MATMUL(achint(1:na, 1:np, 8), TRANSPOSE(bcint(1:nb, 1:np, 1)))   ! yyV
    1094              :                               blocks_rrv_vrr(5)%block(1:na, 1:nb) = blocks_rrv_vrr(5)%block(1:na, 1:nb) + &
    1095              :                                                                     MATMUL(achint(1:na, 1:np, 9), TRANSPOSE(bcint(1:nb, 1:np, 1)))   ! yzV
    1096              :                               blocks_rrv_vrr(6)%block(1:na, 1:nb) = blocks_rrv_vrr(6)%block(1:na, 1:nb) + &
    1097              :                                                              MATMUL(achint(1:na, 1:np, 10), TRANSPOSE(bcint(1:nb, 1:np, 1)))   ! zzV
    1098              :                            ELSE
    1099              :                               blocks_rrv_vrr(1)%block(1:nb, 1:na) = blocks_rrv_vrr(1)%block(1:nb, 1:na) + &
    1100              :                                                                     MATMUL(bchint(1:nb, 1:np, 5), TRANSPOSE(acint(1:na, 1:np, 1)))   ! xxV
    1101              :                               blocks_rrv_vrr(2)%block(1:nb, 1:na) = blocks_rrv_vrr(2)%block(1:nb, 1:na) + &
    1102              :                                                                     MATMUL(bchint(1:nb, 1:np, 6), TRANSPOSE(acint(1:na, 1:np, 1)))   ! xyV
    1103              :                               blocks_rrv_vrr(3)%block(1:nb, 1:na) = blocks_rrv_vrr(3)%block(1:nb, 1:na) + &
    1104              :                                                                     MATMUL(bchint(1:nb, 1:np, 7), TRANSPOSE(acint(1:na, 1:np, 1)))   ! xzV
    1105              :                               blocks_rrv_vrr(4)%block(1:nb, 1:na) = blocks_rrv_vrr(4)%block(1:nb, 1:na) + &
    1106              :                                                                     MATMUL(bchint(1:nb, 1:np, 8), TRANSPOSE(acint(1:na, 1:np, 1)))   ! yyV
    1107              :                               blocks_rrv_vrr(5)%block(1:nb, 1:na) = blocks_rrv_vrr(5)%block(1:nb, 1:na) + &
    1108              :                                                                     MATMUL(bchint(1:nb, 1:np, 9), TRANSPOSE(acint(1:na, 1:np, 1)))   ! yzV
    1109              :                               blocks_rrv_vrr(6)%block(1:nb, 1:na) = blocks_rrv_vrr(6)%block(1:nb, 1:na) + &
    1110              :                                                              MATMUL(bchint(1:nb, 1:np, 10), TRANSPOSE(acint(1:na, 1:np, 1)))   ! zzV
    1111              :                            END IF
    1112              :                            ! + Vnl * r_alpha * r_beta
    1113              :                            IF (iatom <= jatom) THEN
    1114              :                               blocks_rrv_vrr(1)%block(1:na, 1:nb) = blocks_rrv_vrr(1)%block(1:na, 1:nb) + &
    1115              :                                                                     MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 5)))   ! +Vxx
    1116              :                               blocks_rrv_vrr(2)%block(1:na, 1:nb) = blocks_rrv_vrr(2)%block(1:na, 1:nb) + &
    1117              :                                                                     MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 6)))   ! +Vxy
    1118              :                               blocks_rrv_vrr(3)%block(1:na, 1:nb) = blocks_rrv_vrr(3)%block(1:na, 1:nb) + &
    1119              :                                                                     MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 7)))   ! +Vxz
    1120              :                               blocks_rrv_vrr(4)%block(1:na, 1:nb) = blocks_rrv_vrr(4)%block(1:na, 1:nb) + &
    1121              :                                                                     MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 8)))   ! +Vyy
    1122              :                               blocks_rrv_vrr(5)%block(1:na, 1:nb) = blocks_rrv_vrr(5)%block(1:na, 1:nb) + &
    1123              :                                                                     MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 9)))   ! +Vyz
    1124              :                               blocks_rrv_vrr(6)%block(1:na, 1:nb) = blocks_rrv_vrr(6)%block(1:na, 1:nb) + &
    1125              :                                                             MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 10)))   ! +Vzz
    1126              :                            ELSE
    1127              :                               blocks_rrv_vrr(1)%block(1:nb, 1:na) = blocks_rrv_vrr(1)%block(1:nb, 1:na) + &
    1128              :                                                                     MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 5)))   ! +Vxx
    1129              :                               blocks_rrv_vrr(2)%block(1:nb, 1:na) = blocks_rrv_vrr(2)%block(1:nb, 1:na) + &
    1130              :                                                                     MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 6)))   ! +Vxy
    1131              :                               blocks_rrv_vrr(3)%block(1:nb, 1:na) = blocks_rrv_vrr(3)%block(1:nb, 1:na) + &
    1132              :                                                                     MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 7)))   ! +Vxz
    1133              :                               blocks_rrv_vrr(4)%block(1:nb, 1:na) = blocks_rrv_vrr(4)%block(1:nb, 1:na) + &
    1134              :                                                                     MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 8)))   ! +Vyy
    1135              :                               blocks_rrv_vrr(5)%block(1:nb, 1:na) = blocks_rrv_vrr(5)%block(1:nb, 1:na) + &
    1136              :                                                                     MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 9)))   ! +Vyz
    1137              :                               blocks_rrv_vrr(6)%block(1:nb, 1:na) = blocks_rrv_vrr(6)%block(1:nb, 1:na) + &
    1138              :                                                             MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 10)))   ! +Vzz
    1139              :                            END IF
    1140              :                         END IF
    1141              : 
    1142              :                         ! The indices are stored in i_1, i_x, ..., i_zzz
    1143              :                         ! matrix_r_rxvr(alpha, beta)
    1144              :                         !  = sum_(gamma delta) epsilon_(alpha gamma delta)
    1145              :                         !      (r_beta * r_gamma * V_nl * r_delta - r_beta * r_gamma * r_delta * V_nl)
    1146              :                         !  = sum_(gamma delta) epsilon_(alpha gamma delta) r_beta * r_gamma * V_nl * r_delta
    1147              : 
    1148              :                         ! TODO: is this set to zero before?
    1149              :                         IF (my_r_rxvr) THEN
    1150              :                            ! beta = 1
    1151              :                            ! matrix_r_rxvr(x, x) = x * y * V_nl * z  -  x * z * V_nl * y
    1152              :                            blocks_r_rxvr(1, 1)%block(1:na, 1:nb) = &
    1153              :                               blocks_r_rxvr(1, 1)%block(1:na, 1:nb) + &
    1154              :                               MATMUL(achint(1:na, 1:np, i_xy), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1155              :                            blocks_r_rxvr(1, 1)%block(1:na, 1:nb) = &
    1156              :                               blocks_r_rxvr(1, 1)%block(1:na, 1:nb) - &
    1157              :                               MATMUL(achint(1:na, 1:np, i_xz), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1158              : 
    1159              :                            ! matrix_r_rxvr(y, x) = x * z * V_nl * x  -  x * x * V_nl * z
    1160              :                            blocks_r_rxvr(2, 1)%block(1:na, 1:nb) = &
    1161              :                               blocks_r_rxvr(2, 1)%block(1:na, 1:nb) + &
    1162              :                               MATMUL(achint(1:na, 1:np, i_xz), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1163              :                            blocks_r_rxvr(2, 1)%block(1:na, 1:nb) = &
    1164              :                               blocks_r_rxvr(2, 1)%block(1:na, 1:nb) - &
    1165              :                               MATMUL(achint(1:na, 1:np, i_xx), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1166              : 
    1167              :                            ! matrix_r_rxvr(z, x) = x * x * V_nl * y  -  x * y * V_nl * x
    1168              :                            blocks_r_rxvr(3, 1)%block(1:na, 1:nb) = &
    1169              :                               blocks_r_rxvr(3, 1)%block(1:na, 1:nb) + &
    1170              :                               MATMUL(achint(1:na, 1:np, i_xx), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1171              :                            blocks_r_rxvr(3, 1)%block(1:na, 1:nb) = &
    1172              :                               blocks_r_rxvr(3, 1)%block(1:na, 1:nb) - &
    1173              :                               MATMUL(achint(1:na, 1:np, i_xy), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1174              : 
    1175              :                            ! beta = 2
    1176              :                            ! matrix_r_rxvr(x, y) = y * y * V_nl * z  -  y * z * V_nl * y
    1177              :                            blocks_r_rxvr(1, 2)%block(1:na, 1:nb) = &
    1178              :                               blocks_r_rxvr(1, 2)%block(1:na, 1:nb) + &
    1179              :                               MATMUL(achint(1:na, 1:np, i_yy), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1180              :                            blocks_r_rxvr(1, 2)%block(1:na, 1:nb) = &
    1181              :                               blocks_r_rxvr(1, 2)%block(1:na, 1:nb) - &
    1182              :                               MATMUL(achint(1:na, 1:np, i_yz), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1183              : 
    1184              :                            ! matrix_r_rxvr(y, y) = y * z * V_nl * x  -  y * x * V_nl * z
    1185              :                            blocks_r_rxvr(2, 2)%block(1:na, 1:nb) = &
    1186              :                               blocks_r_rxvr(2, 2)%block(1:na, 1:nb) + &
    1187              :                               MATMUL(achint(1:na, 1:np, i_yz), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1188              :                            blocks_r_rxvr(2, 2)%block(1:na, 1:nb) = &
    1189              :                               blocks_r_rxvr(2, 2)%block(1:na, 1:nb) - &
    1190              :                               MATMUL(achint(1:na, 1:np, i_yx), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1191              : 
    1192              :                            ! matrix_r_rxvr(z, y) = y * x * V_nl * y  -  y * y * V_nl * x
    1193              :                            blocks_r_rxvr(3, 2)%block(1:na, 1:nb) = &
    1194              :                               blocks_r_rxvr(3, 2)%block(1:na, 1:nb) + &
    1195              :                               MATMUL(achint(1:na, 1:np, i_yx), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1196              :                            blocks_r_rxvr(3, 2)%block(1:na, 1:nb) = &
    1197              :                               blocks_r_rxvr(3, 2)%block(1:na, 1:nb) - &
    1198              :                               MATMUL(achint(1:na, 1:np, i_yy), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1199              : 
    1200              :                            ! beta = 3
    1201              :                            ! matrix_r_rxvr(x, z) = z * y * V_nl * z  -  z * z * V_nl * y
    1202              :                            blocks_r_rxvr(1, 3)%block(1:na, 1:nb) = &
    1203              :                               blocks_r_rxvr(1, 3)%block(1:na, 1:nb) + &
    1204              :                               MATMUL(achint(1:na, 1:np, i_zy), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1205              :                            blocks_r_rxvr(1, 3)%block(1:na, 1:nb) = &
    1206              :                               blocks_r_rxvr(1, 3)%block(1:na, 1:nb) - &
    1207              :                               MATMUL(achint(1:na, 1:np, i_zz), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1208              : 
    1209              :                            ! matrix_r_rxvr(y, z) = z * z * V_nl * x  -  z * x * V_nl * z
    1210              :                            blocks_r_rxvr(2, 3)%block(1:na, 1:nb) = &
    1211              :                               blocks_r_rxvr(2, 3)%block(1:na, 1:nb) + &
    1212              :                               MATMUL(achint(1:na, 1:np, i_zz), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1213              :                            blocks_r_rxvr(2, 3)%block(1:na, 1:nb) = &
    1214              :                               blocks_r_rxvr(2, 3)%block(1:na, 1:nb) - &
    1215              :                               MATMUL(achint(1:na, 1:np, i_zx), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1216              : 
    1217              :                            ! matrix_r_rxvr(z, z) = z * x * V_nl * y  -  z * y * V_nl * x
    1218              :                            blocks_r_rxvr(3, 3)%block(1:na, 1:nb) = &
    1219              :                               blocks_r_rxvr(3, 3)%block(1:na, 1:nb) + &
    1220              :                               MATMUL(achint(1:na, 1:np, i_zx), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1221              :                            blocks_r_rxvr(3, 3)%block(1:na, 1:nb) = &
    1222              :                               blocks_r_rxvr(3, 3)%block(1:na, 1:nb) - &
    1223              :                               MATMUL(achint(1:na, 1:np, i_zy), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1224              : 
    1225              :                         END IF ! my_r_rxvr
    1226              : 
    1227              :                         ! The indices are stored in i_1, i_x, ..., i_zzz
    1228              :                         ! This will put into blocks_rxvr_r
    1229              :                         ! matrix_rxvr_r(alpha, beta) = sum_(gamma delta) epsilon_(alpha gamma delta)
    1230              :                         !                              r_gamma * V_nl * r_delta * r_beta
    1231              :                         IF (my_rxvr_r) THEN
    1232              :                            ! beta = 1
    1233              :                            ! matrix_rxvr_r(x, x) = yV zx - zV yx
    1234              :                            blocks_rxvr_r(1, 1)%block(1:na, 1:nb) = &
    1235              :                               blocks_rxvr_r(1, 1)%block(1:na, 1:nb) + &
    1236              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_zx)))
    1237              :                            blocks_rxvr_r(1, 1)%block(1:na, 1:nb) = &
    1238              :                               blocks_rxvr_r(1, 1)%block(1:na, 1:nb) - &
    1239              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_yx)))
    1240              : 
    1241              :                            ! matrix_rxvr_r(y, x) = zV xx - xV zx
    1242              :                            blocks_rxvr_r(2, 1)%block(1:na, 1:nb) = &
    1243              :                               blocks_rxvr_r(2, 1)%block(1:na, 1:nb) + &
    1244              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_xx)))
    1245              :                            blocks_rxvr_r(2, 1)%block(1:na, 1:nb) = &
    1246              :                               blocks_rxvr_r(2, 1)%block(1:na, 1:nb) - &
    1247              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_zx)))
    1248              : 
    1249              :                            ! matrix_rxvr_r(z, x) = xV yx - yV xx
    1250              :                            blocks_rxvr_r(3, 1)%block(1:na, 1:nb) = &
    1251              :                               blocks_rxvr_r(3, 1)%block(1:na, 1:nb) + &
    1252              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_yx)))
    1253              :                            blocks_rxvr_r(3, 1)%block(1:na, 1:nb) = &
    1254              :                               blocks_rxvr_r(3, 1)%block(1:na, 1:nb) - &
    1255              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_xx)))
    1256              : 
    1257              :                            ! beta = 2
    1258              :                            ! matrix_rxvr_r(x, y) = yV zy - zV yy
    1259              :                            blocks_rxvr_r(1, 2)%block(1:na, 1:nb) = &
    1260              :                               blocks_rxvr_r(1, 2)%block(1:na, 1:nb) + &
    1261              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_zy)))
    1262              :                            blocks_rxvr_r(1, 2)%block(1:na, 1:nb) = &
    1263              :                               blocks_rxvr_r(1, 2)%block(1:na, 1:nb) - &
    1264              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_yy)))
    1265              : 
    1266              :                            ! matrix_rxvr_r(y, y) = zV xy - xV zy
    1267              :                            blocks_rxvr_r(2, 2)%block(1:na, 1:nb) = &
    1268              :                               blocks_rxvr_r(2, 2)%block(1:na, 1:nb) + &
    1269              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_xy)))
    1270              :                            blocks_rxvr_r(2, 2)%block(1:na, 1:nb) = &
    1271              :                               blocks_rxvr_r(2, 2)%block(1:na, 1:nb) - &
    1272              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_zy)))
    1273              : 
    1274              :                            ! matrix_rxvr_r(z, y) = xV yy - yV xy
    1275              :                            blocks_rxvr_r(3, 2)%block(1:na, 1:nb) = &
    1276              :                               blocks_rxvr_r(3, 2)%block(1:na, 1:nb) + &
    1277              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_yy)))
    1278              :                            blocks_rxvr_r(3, 2)%block(1:na, 1:nb) = &
    1279              :                               blocks_rxvr_r(3, 2)%block(1:na, 1:nb) - &
    1280              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_xy)))
    1281              : 
    1282              :                            ! beta = 3
    1283              :                            ! matrix_rxvr_r(x, z) = yV zz - zV yz
    1284              :                            blocks_rxvr_r(1, 3)%block(1:na, 1:nb) = &
    1285              :                               blocks_rxvr_r(1, 3)%block(1:na, 1:nb) + &
    1286              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_zz)))
    1287              :                            blocks_rxvr_r(1, 3)%block(1:na, 1:nb) = &
    1288              :                               blocks_rxvr_r(1, 3)%block(1:na, 1:nb) - &
    1289              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_yz)))
    1290              : 
    1291              :                            ! matrix_rxvr_r(y, z) = zV xz - xV zz
    1292              :                            blocks_rxvr_r(2, 3)%block(1:na, 1:nb) = &
    1293              :                               blocks_rxvr_r(2, 3)%block(1:na, 1:nb) + &
    1294              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_xz)))
    1295              :                            blocks_rxvr_r(2, 3)%block(1:na, 1:nb) = &
    1296              :                               blocks_rxvr_r(2, 3)%block(1:na, 1:nb) - &
    1297              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_zz)))
    1298              : 
    1299              :                            ! matrix_rxvr_r(z, z) = xV yz - yV xz
    1300              :                            blocks_rxvr_r(3, 3)%block(1:na, 1:nb) = &
    1301              :                               blocks_rxvr_r(3, 3)%block(1:na, 1:nb) + &
    1302              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_yz)))
    1303              :                            blocks_rxvr_r(3, 3)%block(1:na, 1:nb) = &
    1304              :                               blocks_rxvr_r(3, 3)%block(1:na, 1:nb) - &
    1305              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_xz)))
    1306              : 
    1307              :                         END IF ! my_rxvr_r
    1308              : 
    1309              :                         ! matrix_r_doublecom(alpha, beta) = sum_(gamma delta) epsilon_(alpha gamma delta)
    1310              :                         !                                gamma V^pseudoatom beta delta - gamma beta V^pseudoatom delta
    1311              : 
    1312              :                         IF (my_r_doublecom) THEN
    1313              :                            ! beta = 1
    1314              :                            ! matrix_r_doublecom(x, x) = yV xz  -  zV xy  -  yxV z  +  zxV y
    1315              :                            blocks_r_doublecom(1, 1)%block(1:na, 1:nb) = &
    1316              :                               blocks_r_doublecom(1, 1)%block(1:na, 1:nb) + &
    1317              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_xz)))
    1318              :                            blocks_r_doublecom(1, 1)%block(1:na, 1:nb) = &
    1319              :                               blocks_r_doublecom(1, 1)%block(1:na, 1:nb) - &
    1320              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_xy)))
    1321              :                            blocks_r_doublecom(1, 1)%block(1:na, 1:nb) = &
    1322              :                               blocks_r_doublecom(1, 1)%block(1:na, 1:nb) - &
    1323              :                               MATMUL(achint(1:na, 1:np, i_yx), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1324              :                            blocks_r_doublecom(1, 1)%block(1:na, 1:nb) = &
    1325              :                               blocks_r_doublecom(1, 1)%block(1:na, 1:nb) + &
    1326              :                               MATMUL(achint(1:na, 1:np, i_zx), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1327              : 
    1328              :                            ! matrix_r_doublecom(y, x) = zV xx  -  xV xz  -  zxV x  +  xxV z
    1329              :                            blocks_r_doublecom(2, 1)%block(1:na, 1:nb) = &
    1330              :                               blocks_r_doublecom(2, 1)%block(1:na, 1:nb) + &
    1331              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_xx)))
    1332              :                            blocks_r_doublecom(2, 1)%block(1:na, 1:nb) = &
    1333              :                               blocks_r_doublecom(2, 1)%block(1:na, 1:nb) - &
    1334              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_xz)))
    1335              :                            blocks_r_doublecom(2, 1)%block(1:na, 1:nb) = &
    1336              :                               blocks_r_doublecom(2, 1)%block(1:na, 1:nb) - &
    1337              :                               MATMUL(achint(1:na, 1:np, i_zx), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1338              :                            blocks_r_doublecom(2, 1)%block(1:na, 1:nb) = &
    1339              :                               blocks_r_doublecom(2, 1)%block(1:na, 1:nb) + &
    1340              :                               MATMUL(achint(1:na, 1:np, i_xx), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1341              : 
    1342              :                            ! matrix_r_doublecom(z, x) = xV xy  -  yV xx  -  xxV y  +  yxV x
    1343              :                            blocks_r_doublecom(3, 1)%block(1:na, 1:nb) = &
    1344              :                               blocks_r_doublecom(3, 1)%block(1:na, 1:nb) + &
    1345              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_xy)))
    1346              :                            blocks_r_doublecom(3, 1)%block(1:na, 1:nb) = &
    1347              :                               blocks_r_doublecom(3, 1)%block(1:na, 1:nb) - &
    1348              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_xx)))
    1349              :                            blocks_r_doublecom(3, 1)%block(1:na, 1:nb) = &
    1350              :                               blocks_r_doublecom(3, 1)%block(1:na, 1:nb) - &
    1351              :                               MATMUL(achint(1:na, 1:np, i_xx), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1352              :                            blocks_r_doublecom(3, 1)%block(1:na, 1:nb) = &
    1353              :                               blocks_r_doublecom(3, 1)%block(1:na, 1:nb) + &
    1354              :                               MATMUL(achint(1:na, 1:np, i_yx), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1355              : 
    1356              :                            ! beta = 2
    1357              :                            ! matrix_r_doublecom(x, y) = yV yz  -  zV yy  -  yyV z  +  zyV y
    1358              :                            blocks_r_doublecom(1, 2)%block(1:na, 1:nb) = &
    1359              :                               blocks_r_doublecom(1, 2)%block(1:na, 1:nb) + &
    1360              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_yz)))
    1361              :                            blocks_r_doublecom(1, 2)%block(1:na, 1:nb) = &
    1362              :                               blocks_r_doublecom(1, 2)%block(1:na, 1:nb) - &
    1363              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_yy)))
    1364              :                            blocks_r_doublecom(1, 2)%block(1:na, 1:nb) = &
    1365              :                               blocks_r_doublecom(1, 2)%block(1:na, 1:nb) - &
    1366              :                               MATMUL(achint(1:na, 1:np, i_yy), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1367              :                            blocks_r_doublecom(1, 2)%block(1:na, 1:nb) = &
    1368              :                               blocks_r_doublecom(1, 2)%block(1:na, 1:nb) + &
    1369              :                               MATMUL(achint(1:na, 1:np, i_zy), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1370              : 
    1371              :                            ! matrix_r_doublecom(y, y) = zV yx  -  xV yz  -  zyV x  +  xyV z
    1372              :                            blocks_r_doublecom(2, 2)%block(1:na, 1:nb) = &
    1373              :                               blocks_r_doublecom(2, 2)%block(1:na, 1:nb) + &
    1374              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_yx)))
    1375              :                            blocks_r_doublecom(2, 2)%block(1:na, 1:nb) = &
    1376              :                               blocks_r_doublecom(2, 2)%block(1:na, 1:nb) - &
    1377              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_yz)))
    1378              :                            blocks_r_doublecom(2, 2)%block(1:na, 1:nb) = &
    1379              :                               blocks_r_doublecom(2, 2)%block(1:na, 1:nb) - &
    1380              :                               MATMUL(achint(1:na, 1:np, i_zy), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1381              :                            blocks_r_doublecom(2, 2)%block(1:na, 1:nb) = &
    1382              :                               blocks_r_doublecom(2, 2)%block(1:na, 1:nb) + &
    1383              :                               MATMUL(achint(1:na, 1:np, i_xy), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1384              : 
    1385              :                            ! matrix_r_doublecom(z, y) = xV yy  -  yV yx  -  xyV y  +  yyV x
    1386              :                            blocks_r_doublecom(3, 2)%block(1:na, 1:nb) = &
    1387              :                               blocks_r_doublecom(3, 2)%block(1:na, 1:nb) + &
    1388              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_yy)))
    1389              :                            blocks_r_doublecom(3, 2)%block(1:na, 1:nb) = &
    1390              :                               blocks_r_doublecom(3, 2)%block(1:na, 1:nb) - &
    1391              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_yx)))
    1392              :                            blocks_r_doublecom(3, 2)%block(1:na, 1:nb) = &
    1393              :                               blocks_r_doublecom(3, 2)%block(1:na, 1:nb) - &
    1394              :                               MATMUL(achint(1:na, 1:np, i_xy), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1395              :                            blocks_r_doublecom(3, 2)%block(1:na, 1:nb) = &
    1396              :                               blocks_r_doublecom(3, 2)%block(1:na, 1:nb) + &
    1397              :                               MATMUL(achint(1:na, 1:np, i_yy), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1398              : 
    1399              :                            ! beta = 3
    1400              :                            ! matrix_r_doublecom(x, z) = yV zz  -  zV zy  -  yzV z  +  zzV y
    1401              :                            blocks_r_doublecom(1, 3)%block(1:na, 1:nb) = &
    1402              :                               blocks_r_doublecom(1, 3)%block(1:na, 1:nb) + &
    1403              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_zz)))
    1404              :                            blocks_r_doublecom(1, 3)%block(1:na, 1:nb) = &
    1405              :                               blocks_r_doublecom(1, 3)%block(1:na, 1:nb) - &
    1406              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_zy)))
    1407              :                            blocks_r_doublecom(1, 3)%block(1:na, 1:nb) = &
    1408              :                               blocks_r_doublecom(1, 3)%block(1:na, 1:nb) - &
    1409              :                               MATMUL(achint(1:na, 1:np, i_yz), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1410              :                            blocks_r_doublecom(1, 3)%block(1:na, 1:nb) = &
    1411              :                               blocks_r_doublecom(1, 3)%block(1:na, 1:nb) + &
    1412              :                               MATMUL(achint(1:na, 1:np, i_zz), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1413              : 
    1414              :                            ! matrix_r_doublecom(y, z) = zV zx  -  xV zz  -  zzV x  +  xzV z
    1415              :                            blocks_r_doublecom(2, 3)%block(1:na, 1:nb) = &
    1416              :                               blocks_r_doublecom(2, 3)%block(1:na, 1:nb) + &
    1417              :                               MATMUL(achint(1:na, 1:np, i_z), TRANSPOSE(bcint(1:nb, 1:np, i_zx)))
    1418              :                            blocks_r_doublecom(2, 3)%block(1:na, 1:nb) = &
    1419              :                               blocks_r_doublecom(2, 3)%block(1:na, 1:nb) - &
    1420              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_zz)))
    1421              :                            blocks_r_doublecom(2, 3)%block(1:na, 1:nb) = &
    1422              :                               blocks_r_doublecom(2, 3)%block(1:na, 1:nb) - &
    1423              :                               MATMUL(achint(1:na, 1:np, i_zz), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1424              :                            blocks_r_doublecom(2, 3)%block(1:na, 1:nb) = &
    1425              :                               blocks_r_doublecom(2, 3)%block(1:na, 1:nb) + &
    1426              :                               MATMUL(achint(1:na, 1:np, i_xz), TRANSPOSE(bcint(1:nb, 1:np, i_z)))
    1427              : 
    1428              :                            ! matrix_r_doublecom(z, z) = xV zy  -  yV zx  -  xzV y  +  yzV x
    1429              :                            blocks_r_doublecom(3, 3)%block(1:na, 1:nb) = &
    1430              :                               blocks_r_doublecom(3, 3)%block(1:na, 1:nb) + &
    1431              :                               MATMUL(achint(1:na, 1:np, i_x), TRANSPOSE(bcint(1:nb, 1:np, i_zy)))
    1432              :                            blocks_r_doublecom(3, 3)%block(1:na, 1:nb) = &
    1433              :                               blocks_r_doublecom(3, 3)%block(1:na, 1:nb) - &
    1434              :                               MATMUL(achint(1:na, 1:np, i_y), TRANSPOSE(bcint(1:nb, 1:np, i_zx)))
    1435              :                            blocks_r_doublecom(3, 3)%block(1:na, 1:nb) = &
    1436              :                               blocks_r_doublecom(3, 3)%block(1:na, 1:nb) - &
    1437              :                               MATMUL(achint(1:na, 1:np, i_xz), TRANSPOSE(bcint(1:nb, 1:np, i_y)))
    1438              :                            blocks_r_doublecom(3, 3)%block(1:na, 1:nb) = &
    1439              :                               blocks_r_doublecom(3, 3)%block(1:na, 1:nb) + &
    1440              :                               MATMUL(achint(1:na, 1:np, i_yz), TRANSPOSE(bcint(1:nb, 1:np, i_x)))
    1441              : 
    1442              :                         END IF ! my_r_doublecom
    1443              : !$                      CALL omp_unset_lock(locks(hash))
    1444              :                         EXIT ! We have found a match and there can be only one single match
    1445              :                      END IF
    1446              :                   END DO
    1447              :                END DO
    1448              :             END DO
    1449              :          END IF
    1450              :          IF (my_rv) THEN
    1451              :             DO ind = 1, 3
    1452              :                NULLIFY (blocks_rv(ind)%block)
    1453              :             END DO
    1454              :             DEALLOCATE (blocks_rv)
    1455              :          END IF
    1456              :          IF (my_rxrv) THEN
    1457              :             DO ind = 1, 3
    1458              :                NULLIFY (blocks_rxrv(ind)%block)
    1459              :             END DO
    1460              :             DEALLOCATE (blocks_rxrv)
    1461              :          END IF
    1462              :          IF (my_rrv) THEN
    1463              :             DO ind = 1, 6
    1464              :                NULLIFY (blocks_rrv(ind)%block)
    1465              :             END DO
    1466              :             DEALLOCATE (blocks_rrv)
    1467              :          END IF
    1468              :          IF (my_rvr) THEN
    1469              :             DO ind = 1, 6
    1470              :                NULLIFY (blocks_rvr(ind)%block)
    1471              :             END DO
    1472              :             DEALLOCATE (blocks_rvr)
    1473              :          END IF
    1474              :          IF (my_rrv_vrr) THEN
    1475              :             DO ind = 1, 6
    1476              :                NULLIFY (blocks_rrv_vrr(ind)%block)
    1477              :             END DO
    1478              :             DEALLOCATE (blocks_rrv_vrr)
    1479              :          END IF
    1480              :          IF (my_r_rxvr) THEN
    1481              :             DO ind = 1, 3
    1482              :                DO ind2 = 1, 3
    1483              :                   NULLIFY (blocks_r_rxvr(ind, ind2)%block)
    1484              :                END DO
    1485              :             END DO
    1486              :             DEALLOCATE (blocks_r_rxvr)
    1487              :          END IF
    1488              :          IF (my_rxvr_r) THEN
    1489              :             DO ind = 1, 3
    1490              :                DO ind2 = 1, 3
    1491              :                   NULLIFY (blocks_rxvr_r(ind, ind2)%block)
    1492              :                END DO
    1493              :             END DO
    1494              :             DEALLOCATE (blocks_rxvr_r)
    1495              :          END IF
    1496              :          IF (my_r_doublecom) THEN
    1497              :             DO ind = 1, 3
    1498              :                DO ind2 = 1, 3
    1499              :                   NULLIFY (blocks_r_doublecom(ind, ind2)%block)
    1500              :                END DO
    1501              :             END DO
    1502              :             DEALLOCATE (blocks_r_doublecom)
    1503              :          END IF
    1504              :       END DO
    1505              : 
    1506              : !$OMP DO
    1507              : !$    DO lock_num = 1, nlock
    1508              : !$       call omp_destroy_lock(locks(lock_num))
    1509              : !$    END DO
    1510              : !$OMP END DO
    1511              : 
    1512              : !$OMP SINGLE
    1513              : !$    DEALLOCATE (locks)
    1514              : !$OMP END SINGLE NOWAIT
    1515              : 
    1516              : !$OMP END PARALLEL
    1517              : 
    1518           36 :       CALL release_sap_int(sap_int)
    1519              : 
    1520           36 :       DEALLOCATE (basis_set)
    1521              : 
    1522           36 :       CALL timestop(handle)
    1523              : 
    1524          130 :    END SUBROUTINE build_com_mom_nl
    1525              : 
    1526              : ! **************************************************************************************************
    1527              : !> \brief calculate \sum_R_ps (R_ps - R_nu) x [V_nl, r] summing over all pseudized atoms R
    1528              : !> \param qs_kind_set ...
    1529              : !> \param sab_all ...
    1530              : !> \param sap_ppnl ...
    1531              : !> \param eps_ppnl ...
    1532              : !> \param particle_set ...
    1533              : !> \param matrix_mag_nl ...
    1534              : !> \param refpoint ...
    1535              : !> \param cell ...
    1536              : ! **************************************************************************************************
    1537            8 :    SUBROUTINE build_com_nl_mag(qs_kind_set, sab_all, sap_ppnl, eps_ppnl, particle_set, matrix_mag_nl, refpoint, cell)
    1538              : 
    1539              :       TYPE(qs_kind_type), DIMENSION(:), INTENT(IN), &
    1540              :          POINTER                                         :: qs_kind_set
    1541              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1542              :          INTENT(IN), POINTER                             :: sab_all, sap_ppnl
    1543              :       REAL(KIND=dp), INTENT(IN)                          :: eps_ppnl
    1544              :       TYPE(particle_type), DIMENSION(:), INTENT(IN), &
    1545              :          POINTER                                         :: particle_set
    1546              :       TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN), &
    1547              :          POINTER                                         :: matrix_mag_nl
    1548              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN), OPTIONAL  :: refpoint
    1549              :       TYPE(cell_type), INTENT(IN), OPTIONAL, POINTER     :: cell
    1550              : 
    1551              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'build_com_nl_mag'
    1552              : 
    1553              :       INTEGER                                            :: handle, iab, iac, iatom, ibc, icol, &
    1554              :                                                             ikind, ind, irow, jatom, jkind, kac, &
    1555              :                                                             kbc, kkind, na, natom, nb, nkind, np, &
    1556              :                                                             order, slot
    1557              :       INTEGER, DIMENSION(3)                              :: cell_b
    1558              :       LOGICAL                                            :: found, go, my_ref, ppnl_present
    1559              :       REAL(KIND=dp), DIMENSION(3)                        :: r_b, r_ps, rab
    1560            8 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: achint, acint, bchint, bcint
    1561              :       TYPE(alist_type), POINTER                          :: alist_ac, alist_bc
    1562            8 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:)      :: blocks_mag
    1563              :       TYPE(gto_basis_set_p_type), ALLOCATABLE, &
    1564            8 :          DIMENSION(:)                                    :: basis_set
    1565              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    1566            8 :       TYPE(sap_int_type), DIMENSION(:), POINTER          :: sap_int
    1567              : 
    1568              : !$    INTEGER(kind=omp_lock_kind), &
    1569            8 : !$       ALLOCATABLE, DIMENSION(:) :: locks
    1570              : !$    INTEGER                                            :: lock_num, hash
    1571              : !$    INTEGER, PARAMETER                                 :: nlock = 501
    1572              : 
    1573            8 :       ppnl_present = ASSOCIATED(sap_ppnl)
    1574            8 :       IF (.NOT. ppnl_present) RETURN
    1575              : 
    1576            8 :       CALL timeset(routineN, handle)
    1577              : 
    1578            8 :       my_ref = .FALSE.
    1579            8 :       IF (PRESENT(refpoint)) THEN
    1580            8 :          my_ref = .TRUE.
    1581            8 :          CPASSERT(PRESENT(cell))
    1582              :       END IF
    1583              : 
    1584            8 :       natom = SIZE(particle_set)
    1585            8 :       nkind = SIZE(qs_kind_set)
    1586              : 
    1587              :       ! allocate integral storage
    1588            8 :       NULLIFY (sap_int)
    1589           56 :       ALLOCATE (sap_int(nkind*nkind))
    1590           40 :       DO ind = 1, nkind*nkind
    1591           32 :          NULLIFY (sap_int(ind)%alist, sap_int(ind)%asort, sap_int(ind)%aindex)
    1592           40 :          sap_int(ind)%nalist = 0
    1593              :       END DO
    1594              : 
    1595              :       ! build integrals over GTO + projector functions, refpoint actually
    1596            8 :       order = 1   ! only need first moments (x, y, z)
    1597              :       ! refpoint actually does not matter in this case, i. e. (order = 1 .and. commutator)
    1598            8 :       IF (my_ref) THEN
    1599              :          CALL build_sap_ints(sap_int, sap_ppnl, qs_kind_set, order, moment_mode=.TRUE., refpoint=refpoint, &
    1600            8 :                              particle_set=particle_set, cell=cell)
    1601              :       ELSE
    1602            0 :          CALL build_sap_ints(sap_int, sap_ppnl, qs_kind_set, order, moment_mode=.TRUE.)
    1603              :       END IF
    1604              : 
    1605            8 :       CALL sap_sort(sap_int)
    1606              : 
    1607              :       ! get access to basis sets
    1608           40 :       ALLOCATE (basis_set(nkind))
    1609           24 :       DO ikind = 1, nkind
    1610           16 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
    1611           24 :          IF (ASSOCIATED(orb_basis_set)) THEN
    1612           16 :             basis_set(ikind)%gto_basis_set => orb_basis_set
    1613              :          ELSE
    1614            0 :             NULLIFY (basis_set(ikind)%gto_basis_set)
    1615              :          END IF
    1616              :       END DO
    1617              : 
    1618              : !$OMP PARALLEL &
    1619              : !$OMP DEFAULT (NONE) &
    1620              : !$OMP SHARED  (basis_set, matrix_mag_nl, sap_int, natom, nkind, eps_ppnl, locks, sab_all, &
    1621              : !$OMP          particle_set, my_ref, refpoint) &
    1622              : !$OMP PRIVATE (ikind, jkind, iatom, jatom, cell_b, rab, lock_num, &
    1623              : !$OMP          iab, irow, icol, blocks_mag, r_ps, r_b, go, hash, &
    1624              : !$OMP          found, iac, ibc, alist_ac, alist_bc, acint, bcint, &
    1625            8 : !$OMP          achint, bchint, na, np, nb, kkind, kac, kbc)
    1626              : 
    1627              : !$OMP SINGLE
    1628              : !$    ALLOCATE (locks(nlock))
    1629              : !$OMP END SINGLE
    1630              : 
    1631              : !$OMP DO
    1632              : !$    DO lock_num = 1, nlock
    1633              : !$       call omp_init_lock(locks(lock_num))
    1634              : !$    END DO
    1635              : !$OMP END DO
    1636              : 
    1637              : !$OMP DO SCHEDULE(GUIDED)
    1638              :       DO slot = 1, sab_all(1)%nl_size
    1639              :          ! get indices
    1640              :          ikind = sab_all(1)%nlist_task(slot)%ikind
    1641              :          jkind = sab_all(1)%nlist_task(slot)%jkind
    1642              :          iatom = sab_all(1)%nlist_task(slot)%iatom
    1643              :          jatom = sab_all(1)%nlist_task(slot)%jatom
    1644              :          cell_b(:) = sab_all(1)%nlist_task(slot)%cell(:)
    1645              :          rab(1:3) = sab_all(1)%nlist_task(slot)%r(1:3)
    1646              : 
    1647              :          IF (.NOT. ASSOCIATED(basis_set(ikind)%gto_basis_set)) CYCLE
    1648              :          IF (.NOT. ASSOCIATED(basis_set(jkind)%gto_basis_set)) CYCLE
    1649              :          iab = ikind + nkind*(jkind - 1)
    1650              : 
    1651              :          IF (iatom <= jatom) THEN
    1652              :             irow = iatom
    1653              :             icol = jatom
    1654              :          ELSE
    1655              :             irow = jatom
    1656              :             icol = iatom
    1657              :          END IF
    1658              : 
    1659              :          ! get blocks
    1660              :          ALLOCATE (blocks_mag(3))
    1661              :          DO ind = 1, 3
    1662              :             CALL dbcsr_get_block_p(matrix_mag_nl(ind)%matrix, irow, icol, blocks_mag(ind)%block, found)
    1663              :          END DO
    1664              : 
    1665              :          go = (ASSOCIATED(blocks_mag(1)%block) .AND. ASSOCIATED(blocks_mag(2)%block) .AND. ASSOCIATED(blocks_mag(3)%block))
    1666              : 
    1667              :          IF (go) THEN
    1668              :             DO kkind = 1, nkind
    1669              :                iac = ikind + nkind*(kkind - 1)
    1670              :                ibc = jkind + nkind*(kkind - 1)
    1671              :                IF (.NOT. ASSOCIATED(sap_int(iac)%alist)) CYCLE
    1672              :                IF (.NOT. ASSOCIATED(sap_int(ibc)%alist)) CYCLE
    1673              :                CALL get_alist(sap_int(iac), alist_ac, iatom)
    1674              :                CALL get_alist(sap_int(ibc), alist_bc, jatom)
    1675              :                IF (.NOT. ASSOCIATED(alist_ac)) CYCLE
    1676              :                IF (.NOT. ASSOCIATED(alist_bc)) CYCLE
    1677              :                DO kac = 1, alist_ac%nclist
    1678              :                   DO kbc = 1, alist_bc%nclist
    1679              :                      IF (alist_ac%clist(kac)%catom /= alist_bc%clist(kbc)%catom) CYCLE
    1680              :                      IF (ALL(cell_b + alist_bc%clist(kbc)%cell - alist_ac%clist(kac)%cell == 0)) THEN
    1681              :                         IF (alist_ac%clist(kac)%maxac*alist_bc%clist(kbc)%maxach < eps_ppnl) CYCLE
    1682              : 
    1683              :                         acint => alist_ac%clist(kac)%acint
    1684              :                         bcint => alist_bc%clist(kbc)%acint
    1685              :                         achint => alist_ac%clist(kac)%achint
    1686              :                         bchint => alist_bc%clist(kbc)%achint
    1687              :                         na = SIZE(acint, 1)
    1688              :                         np = SIZE(acint, 2)
    1689              :                         nb = SIZE(bcint, 1)
    1690              :                         ! Position of the pseudized atom
    1691              :                         r_ps = particle_set(alist_ac%clist(kac)%catom)%r
    1692              :                         r_b = refpoint
    1693              : 
    1694              : !$                      hash = MOD((iatom - 1)*natom + jatom, nlock) + 1
    1695              : !$                      CALL omp_set_lock(locks(hash))
    1696              :                         ! assemble integrals
    1697              :                         IF (iatom <= jatom) THEN
    1698              :                            blocks_mag(1)%block(1:na, 1:nb) = blocks_mag(1)%block(1:na, 1:nb) + &
    1699              :                                               (r_ps(2) - r_b(2))*(MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 4))) - &
    1700              :                                                  MATMUL(achint(1:na, 1:np, 4), TRANSPOSE(bcint(1:nb, 1:np, 1)))) & !   R_y [V_nl, z]
    1701              :                                             - (r_ps(3) - r_b(3))*(MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 3))) - &
    1702              :                                                  MATMUL(achint(1:na, 1:np, 3), TRANSPOSE(bcint(1:nb, 1:np, 1))))   ! - R_z [V_nl, y]
    1703              :                            blocks_mag(2)%block(1:na, 1:nb) = blocks_mag(2)%block(1:na, 1:nb) + &
    1704              :                                               (r_ps(3) - r_b(3))*(MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 2))) - &
    1705              :                                                  MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 1)))) & !   R_z [V_nl, x]
    1706              :                                             - (r_ps(1) - r_b(1))*(MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 4))) - &
    1707              :                                                  MATMUL(achint(1:na, 1:np, 4), TRANSPOSE(bcint(1:nb, 1:np, 1))))   ! - R_x [V_nl, z]
    1708              :                            blocks_mag(3)%block(1:na, 1:nb) = blocks_mag(3)%block(1:na, 1:nb) + &
    1709              :                                               (r_ps(1) - r_b(1))*(MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 3))) - &
    1710              :                                                 MATMUL(achint(1:na, 1:np, 3), TRANSPOSE(bcint(1:nb, 1:np, 1)))) &  !   R_x [V_nl, y]
    1711              :                                             - (r_ps(2) - r_b(2))*(MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 2))) - &
    1712              :                                                 MATMUL(achint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 1))))    ! - R_y [V_nl, x]
    1713              :                         ELSE
    1714              :                            blocks_mag(1)%block(1:nb, 1:na) = blocks_mag(1)%block(1:nb, 1:na) + &
    1715              :                                               (r_ps(2) - r_b(2))*(MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 4))) - &
    1716              :                                                  MATMUL(bchint(1:nb, 1:np, 4), TRANSPOSE(acint(1:na, 1:np, 1)))) & !   R_y [V_nl, z]
    1717              :                                             - (r_ps(3) - r_b(3))*(MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 3))) - &
    1718              :                                                  MATMUL(bchint(1:nb, 1:np, 3), TRANSPOSE(acint(1:na, 1:np, 1))))   ! - R_z [V_nl, y]
    1719              :                            blocks_mag(2)%block(1:nb, 1:na) = blocks_mag(2)%block(1:nb, 1:na) + &
    1720              :                                               (r_ps(3) - r_b(3))*(MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 2))) - &
    1721              :                                                  MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 1)))) & !   R_z [V_nl, x]
    1722              :                                             - (r_ps(1) - r_b(1))*(MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 4))) - &
    1723              :                                                  MATMUL(bchint(1:nb, 1:np, 4), TRANSPOSE(acint(1:na, 1:np, 1))))   ! - R_x [V_nl, z]
    1724              :                            blocks_mag(3)%block(1:nb, 1:na) = blocks_mag(3)%block(1:nb, 1:na) + &
    1725              :                                               (r_ps(1) - r_b(1))*(MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 3))) - &
    1726              :                                                 MATMUL(bchint(1:nb, 1:np, 3), TRANSPOSE(acint(1:na, 1:np, 1)))) &  !   R_x [V_nl, y]
    1727              :                                             - (r_ps(2) - r_b(2))*(MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 2))) - &
    1728              :                                                 MATMUL(bchint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 1))))    ! - R_y [V_nl, x]
    1729              :                         END IF
    1730              : !$                      CALL omp_unset_lock(locks(hash))
    1731              :                         EXIT ! We have found a match and there can be only one single match
    1732              :                      END IF
    1733              :                   END DO
    1734              :                END DO
    1735              :             END DO
    1736              :          END IF
    1737              : 
    1738              :          DO ind = 1, 3
    1739              :             NULLIFY (blocks_mag(ind)%block)
    1740              :          END DO
    1741              :          DEALLOCATE (blocks_mag)
    1742              :       END DO
    1743              : 
    1744              : !$OMP DO
    1745              : !$    DO lock_num = 1, nlock
    1746              : !$       call omp_destroy_lock(locks(lock_num))
    1747              : !$    END DO
    1748              : !$OMP END DO
    1749              : 
    1750              : !$OMP SINGLE
    1751              : !$    DEALLOCATE (locks)
    1752              : !$OMP END SINGLE NOWAIT
    1753              : 
    1754              : !$OMP END PARALLEL
    1755              : 
    1756            8 :       DEALLOCATE (basis_set)
    1757            8 :       CALL release_sap_int(sap_int)
    1758              : 
    1759            8 :       CALL timestop(handle)
    1760              : 
    1761           16 :    END SUBROUTINE build_com_nl_mag
    1762              : 
    1763              : ! **************************************************************************************************
    1764              : !> \brief Calculate matrix_rv(gamma, delta) = < R^eta_gamma * Vnl * r_delta > for GIAOs
    1765              : !> \param qs_kind_set ...
    1766              : !> \param sab_all ...
    1767              : !> \param sap_ppnl ...
    1768              : !> \param eps_ppnl ...
    1769              : !> \param particle_set ...
    1770              : !> \param matrix_rv ...
    1771              : !> \param ref_point ...
    1772              : !> \param cell ...
    1773              : !> \param direction_Or If set to true: calculate Vnl * r_delta
    1774              : !>                     Otherwise       calculate r_delta * Vnl
    1775              : ! **************************************************************************************************
    1776            0 :    SUBROUTINE build_com_vnl_giao(qs_kind_set, sab_all, sap_ppnl, eps_ppnl, particle_set, &
    1777              :                                  matrix_rv, ref_point, cell, direction_Or)
    1778              : 
    1779              :       TYPE(qs_kind_type), DIMENSION(:), INTENT(IN), &
    1780              :          POINTER                                         :: qs_kind_set
    1781              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
    1782              :          INTENT(IN), POINTER                             :: sab_all, sap_ppnl
    1783              :       REAL(KIND=dp), INTENT(IN)                          :: eps_ppnl
    1784              :       TYPE(particle_type), DIMENSION(:), INTENT(IN), &
    1785              :          POINTER                                         :: particle_set
    1786              :       TYPE(dbcsr_p_type), DIMENSION(:, :), &
    1787              :          INTENT(INOUT), OPTIONAL, POINTER                :: matrix_rv
    1788              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN), OPTIONAL  :: ref_point
    1789              :       TYPE(cell_type), INTENT(IN), OPTIONAL, POINTER     :: cell
    1790              :       LOGICAL                                            :: direction_Or
    1791              : 
    1792              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'build_com_vnl_giao'
    1793              :       INTEGER, PARAMETER                                 :: i_1 = 1
    1794              : 
    1795              :       INTEGER                                            :: delta, gamma, handle, i, iab, iac, &
    1796              :                                                             iatom, ibc, icol, ikind, irow, j, &
    1797              :                                                             jatom, jkind, kac, kbc, kkind, na, &
    1798              :                                                             natom, nb, nkind, np, order, slot
    1799              :       INTEGER, DIMENSION(3)                              :: cell_b
    1800              :       LOGICAL                                            :: found, my_ref, ppnl_present
    1801              :       REAL(KIND=dp), DIMENSION(3)                        :: rab, rf
    1802            0 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: achint, acint, bchint, bcint
    1803              :       TYPE(alist_type), POINTER                          :: alist_ac, alist_bc
    1804            0 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:, :)   :: blocks_rv
    1805              :       TYPE(gto_basis_set_p_type), ALLOCATABLE, &
    1806            0 :          DIMENSION(:)                                    :: basis_set
    1807              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
    1808            0 :       TYPE(sap_int_type), DIMENSION(:), POINTER          :: sap_int
    1809              : 
    1810              : !$    INTEGER(kind=omp_lock_kind), &
    1811            0 : !$       ALLOCATABLE, DIMENSION(:) :: locks
    1812              : !$    INTEGER                                            :: lock_num, hash
    1813              : !$    INTEGER, PARAMETER                                 :: nlock = 501
    1814              : 
    1815            0 :       ppnl_present = ASSOCIATED(sap_ppnl)
    1816            0 :       IF (.NOT. ppnl_present) RETURN
    1817              : 
    1818            0 :       CALL timeset(routineN, handle)
    1819              : 
    1820            0 :       natom = SIZE(particle_set)
    1821              : 
    1822            0 :       my_ref = .FALSE.
    1823            0 :       IF (PRESENT(ref_point)) THEN
    1824            0 :          CPASSERT(PRESENT(cell)) ! need cell as well if refpoint is provided
    1825            0 :          rf = ref_point
    1826            0 :          my_ref = .TRUE.
    1827              :       END IF
    1828              : 
    1829            0 :       nkind = SIZE(qs_kind_set)
    1830              : 
    1831              :       ! sap_int needs to be shared as multiple threads need to access this
    1832            0 :       NULLIFY (sap_int)
    1833            0 :       ALLOCATE (sap_int(nkind*nkind))
    1834            0 :       DO i = 1, nkind*nkind
    1835            0 :          NULLIFY (sap_int(i)%alist, sap_int(i)%asort, sap_int(i)%aindex)
    1836            0 :          sap_int(i)%nalist = 0
    1837              :       END DO
    1838              : 
    1839            0 :       order = 1
    1840            0 :       IF (my_ref) THEN
    1841              :          ! calculate integrals <a|x^n|p>
    1842              :          CALL build_sap_ints(sap_int, sap_ppnl, qs_kind_set, order, moment_mode=.TRUE., refpoint=rf, &
    1843            0 :                              particle_set=particle_set, cell=cell)
    1844              :       ELSE
    1845            0 :          CALL build_sap_ints(sap_int, sap_ppnl, qs_kind_set, order, moment_mode=.TRUE.)
    1846              :       END IF
    1847              : 
    1848              :       ! *** Set up a sorting index
    1849            0 :       CALL sap_sort(sap_int)
    1850              : 
    1851            0 :       ALLOCATE (basis_set(nkind))
    1852            0 :       DO ikind = 1, nkind
    1853            0 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
    1854            0 :          IF (ASSOCIATED(orb_basis_set)) THEN
    1855            0 :             basis_set(ikind)%gto_basis_set => orb_basis_set
    1856              :          ELSE
    1857            0 :             NULLIFY (basis_set(ikind)%gto_basis_set)
    1858              :          END IF
    1859              :       END DO
    1860              : 
    1861            0 :       CALL get_neighbor_list_set_p(neighbor_list_sets=sab_all)
    1862              :       ! *** All integrals needed have been calculated and stored in sap_int
    1863              :       ! *** We now calculate the commutator matrix elements
    1864              : 
    1865              : !$OMP PARALLEL &
    1866              : !$OMP DEFAULT (NONE) &
    1867              : !$OMP SHARED  (basis_set, matrix_rv, &
    1868              : !$OMP          sap_int, nkind, eps_ppnl, locks, sab_all, &
    1869              : !$OMP          particle_set, direction_Or) &
    1870              : !$OMP PRIVATE (ikind, jkind, iatom, jatom, cell_b, rab, &
    1871              : !$OMP          iab, irow, icol, blocks_rv, &
    1872              : !$OMP          found, iac, ibc, alist_ac, alist_bc, &
    1873              : !$OMP          na, np, nb, kkind, kac, kbc, i, lock_num, &
    1874            0 : !$OMP          hash, natom, delta, gamma, achint, bchint, acint, bcint)
    1875              : 
    1876              : !$OMP SINGLE
    1877              : !$    ALLOCATE (locks(nlock))
    1878              : !$OMP END SINGLE
    1879              : 
    1880              : !$OMP DO
    1881              : !$    DO lock_num = 1, nlock
    1882              : !$       call omp_init_lock(locks(lock_num))
    1883              : !$    END DO
    1884              : !$OMP END DO
    1885              : 
    1886              : !$OMP DO SCHEDULE(GUIDED)
    1887              : 
    1888              :       DO slot = 1, sab_all(1)%nl_size
    1889              : 
    1890              :          ikind = sab_all(1)%nlist_task(slot)%ikind
    1891              :          jkind = sab_all(1)%nlist_task(slot)%jkind
    1892              :          iatom = sab_all(1)%nlist_task(slot)%iatom
    1893              :          jatom = sab_all(1)%nlist_task(slot)%jatom
    1894              :          cell_b(:) = sab_all(1)%nlist_task(slot)%cell(:)
    1895              :          rab(1:3) = sab_all(1)%nlist_task(slot)%r(1:3)
    1896              : 
    1897              :          IF (.NOT. ASSOCIATED(basis_set(ikind)%gto_basis_set)) CYCLE
    1898              :          IF (.NOT. ASSOCIATED(basis_set(jkind)%gto_basis_set)) CYCLE
    1899              :          iab = ikind + nkind*(jkind - 1)
    1900              : 
    1901              :          irow = iatom
    1902              :          icol = jatom
    1903              : 
    1904              :          ! allocate blocks
    1905              :          ALLOCATE (blocks_rv(3, 3))
    1906              : 
    1907              :          ! get blocks
    1908              :          DO i = 1, 3
    1909              :             DO j = 1, 3
    1910              :                CALL dbcsr_get_block_p(matrix_rv(i, j)%matrix, irow, icol, &
    1911              :                                       blocks_rv(i, j)%block, found)
    1912              :                blocks_rv(i, j)%block(:, :) = 0.0_dp
    1913              :                CPASSERT(found)
    1914              :             END DO
    1915              :          END DO
    1916              : 
    1917              :          ! loop over all kinds for projector atom
    1918              :          ! < iatom | katom > h < katom | jatom >
    1919              :          DO kkind = 1, nkind
    1920              :             iac = ikind + nkind*(kkind - 1)
    1921              :             ibc = jkind + nkind*(kkind - 1)
    1922              :             IF (.NOT. ASSOCIATED(sap_int(iac)%alist)) CYCLE
    1923              :             IF (.NOT. ASSOCIATED(sap_int(ibc)%alist)) CYCLE
    1924              :             CALL get_alist(sap_int(iac), alist_ac, iatom)
    1925              :             CALL get_alist(sap_int(ibc), alist_bc, jatom)
    1926              :             IF (.NOT. ASSOCIATED(alist_ac)) CYCLE
    1927              :             IF (.NOT. ASSOCIATED(alist_bc)) CYCLE
    1928              :             DO kac = 1, alist_ac%nclist
    1929              :                DO kbc = 1, alist_bc%nclist
    1930              :                   IF (alist_ac%clist(kac)%catom /= alist_bc%clist(kbc)%catom) CYCLE
    1931              : 
    1932              :                   IF (ALL(cell_b + alist_bc%clist(kbc)%cell - alist_ac%clist(kac)%cell == 0)) THEN
    1933              :                      IF (alist_ac%clist(kac)%maxac*alist_bc%clist(kbc)%maxach < eps_ppnl) CYCLE
    1934              :                      acint => alist_ac%clist(kac)%acint
    1935              :                      bcint => alist_bc%clist(kbc)%acint
    1936              :                      achint => alist_ac%clist(kac)%achint
    1937              :                      bchint => alist_bc%clist(kbc)%achint
    1938              :                      na = SIZE(acint, 1)
    1939              :                      np = SIZE(acint, 2)
    1940              :                      nb = SIZE(bcint, 1)
    1941              : !$                   hash = MOD((iatom - 1)*natom + jatom, nlock) + 1
    1942              : !$                   CALL omp_set_lock(locks(hash))
    1943              : 
    1944              :                      !! The atom index is alist_ac%clist(kac)%catom
    1945              :                      ! The coordinate is particle_set(alist_ac%clist(kac)%catom)%r(:)
    1946              :                      IF (direction_Or) THEN  ! V * r_delta * (R^eta_gamma - R^nu_gamma)
    1947              :                         DO delta = 1, 3
    1948              :                            DO gamma = 1, 3
    1949              :                               blocks_rv(gamma, delta)%block(1:na, 1:nb) &
    1950              :                                  = blocks_rv(gamma, delta)%block(1:na, 1:nb) + &
    1951              :                                    MATMUL(achint(1:na, 1:np, i_1), TRANSPOSE(bcint(1:nb, 1:np, delta + 1))) &
    1952              :                                    *(particle_set(alist_ac%clist(kac)%catom)%r(gamma) - particle_set(jatom)%r(gamma))
    1953              :                            END DO
    1954              :                         END DO
    1955              :                      ELSE                   ! r_delta * V * (R^eta_gamma - R^nu_gamma)
    1956              :                         DO delta = 1, 3
    1957              :                            DO gamma = 1, 3
    1958              :                               blocks_rv(gamma, delta)%block(1:na, 1:nb) &
    1959              :                                  = blocks_rv(gamma, delta)%block(1:na, 1:nb) + &
    1960              :                                    MATMUL(achint(1:na, 1:np, delta + 1), TRANSPOSE(bcint(1:nb, 1:np, i_1))) &
    1961              :                                    *(particle_set(alist_ac%clist(kac)%catom)%r(gamma) - particle_set(jatom)%r(gamma))
    1962              :                            END DO
    1963              :                         END DO
    1964              :                      END IF
    1965              : 
    1966              : !$                   CALL omp_unset_lock(locks(hash))
    1967              :                      EXIT ! We have found a match and there can be only one single match
    1968              :                   END IF
    1969              :                END DO
    1970              :             END DO
    1971              :          END DO
    1972              :          DO delta = 1, 3
    1973              :             DO gamma = 1, 3
    1974              :                NULLIFY (blocks_rv(gamma, delta)%block)
    1975              :             END DO
    1976              :          END DO
    1977              :          DEALLOCATE (blocks_rv)
    1978              :       END DO
    1979              : 
    1980              : !$OMP DO
    1981              : !$    DO lock_num = 1, nlock
    1982              : !$       call omp_destroy_lock(locks(lock_num))
    1983              : !$    END DO
    1984              : !$OMP END DO
    1985              : 
    1986              : !$OMP SINGLE
    1987              : !$    DEALLOCATE (locks)
    1988              : !$OMP END SINGLE NOWAIT
    1989              : 
    1990              : !$OMP END PARALLEL
    1991              : 
    1992            0 :       CALL release_sap_int(sap_int)
    1993              : 
    1994            0 :       DEALLOCATE (basis_set)
    1995              : 
    1996            0 :       CALL timestop(handle)
    1997              : 
    1998            0 :    END SUBROUTINE build_com_vnl_giao
    1999              : 
    2000              : END MODULE commutator_rpnl
        

Generated by: LCOV version 2.0-1