LCOV - code coverage report
Current view: top level - src - commutator_rpnl.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:4dc10b3) Lines: 100 199 50.3 %
Date: 2024-11-21 06:45:46 Functions: 2 4 50.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 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, &
     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, &
    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, &
    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 1.15