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

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : ! **************************************************************************************************
       8              : !> \brief Calculation of the non-local pseudopotential contribution to the core Hamiltonian
       9              : !>         <a|V(non-local)|b> = <a|p(l,i)>*h(i,j)*<p(l,j)|b>
      10              : !> \par History
      11              : !>      - refactered from qs_core_hamiltian [Joost VandeVondele, 2008-11-01]
      12              : !>      - full rewrite [jhu, 2009-01-23]
      13              : !>      - Extended by the derivatives for DFPT [Sandra Luber, Edward Ditler, 2021]
      14              : ! **************************************************************************************************
      15              : MODULE core_ppnl
      16              :    USE ai_angmom,                       ONLY: angmom
      17              :    USE ai_overlap,                      ONLY: overlap
      18              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      19              :                                               get_atomic_kind_set
      20              :    USE basis_set_types,                 ONLY: gto_basis_set_p_type,&
      21              :                                               gto_basis_set_type
      22              :    USE cp_dbcsr_api,                    ONLY: dbcsr_add,&
      23              :                                               dbcsr_get_block_p,&
      24              :                                               dbcsr_p_type
      25              :    USE external_potential_types,        ONLY: gth_potential_p_type,&
      26              :                                               gth_potential_type,&
      27              :                                               sgp_potential_p_type,&
      28              :                                               sgp_potential_type
      29              :    USE kinds,                           ONLY: dp,&
      30              :                                               int_8
      31              :    USE orbital_pointers,                ONLY: init_orbital_pointers,&
      32              :                                               nco,&
      33              :                                               ncoset
      34              :    USE particle_types,                  ONLY: particle_type
      35              :    USE qs_force_types,                  ONLY: qs_force_type
      36              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      37              :                                               get_qs_kind_set,&
      38              :                                               qs_kind_type
      39              :    USE qs_neighbor_list_types,          ONLY: neighbor_list_set_p_type
      40              :    USE sap_kind_types,                  ONLY: alist_type,&
      41              :                                               clist_type,&
      42              :                                               get_alist,&
      43              :                                               release_sap_int,&
      44              :                                               sap_int_type,&
      45              :                                               sap_sort
      46              :    USE upf_projector_integrals,         ONLY: upf_projector_init,&
      47              :                                               upf_projector_overlap,&
      48              :                                               upf_projector_type
      49              :    USE virial_methods,                  ONLY: virial_pair_force
      50              :    USE virial_types,                    ONLY: virial_type
      51              : 
      52              : !$ USE OMP_LIB, ONLY: omp_lock_kind, &
      53              : !$                    omp_init_lock, omp_set_lock, &
      54              : !$                    omp_unset_lock, omp_destroy_lock
      55              : 
      56              : #include "./base/base_uses.f90"
      57              : 
      58              :    IMPLICIT NONE
      59              : 
      60              :    PRIVATE
      61              : 
      62              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'core_ppnl'
      63              : 
      64              :    PUBLIC :: build_core_ppnl
      65              : 
      66              : CONTAINS
      67              : 
      68              : ! **************************************************************************************************
      69              : !> \brief ...
      70              : !> \param matrix_h ...
      71              : !> \param matrix_p ...
      72              : !> \param force ...
      73              : !> \param virial ...
      74              : !> \param calculate_forces ...
      75              : !> \param use_virial ...
      76              : !> \param nder ...
      77              : !> \param qs_kind_set ...
      78              : !> \param atomic_kind_set ...
      79              : !> \param particle_set ...
      80              : !> \param sab_orb ...
      81              : !> \param sap_ppnl ...
      82              : !> \param eps_ppnl ...
      83              : !> \param nimages ...
      84              : !> \param cell_to_index ...
      85              : !> \param basis_type ...
      86              : !> \param deltaR Weighting factors of the derivatives wrt. nuclear positions
      87              : !> \param matrix_l ...
      88              : !> \param atcore ...
      89              : ! **************************************************************************************************
      90        17370 :    SUBROUTINE build_core_ppnl(matrix_h, matrix_p, force, virial, calculate_forces, use_virial, nder, &
      91              :                               qs_kind_set, atomic_kind_set, particle_set, sab_orb, sap_ppnl, eps_ppnl, &
      92        17370 :                               nimages, cell_to_index, basis_type, deltaR, matrix_l, atcore)
      93              : 
      94              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_h, matrix_p
      95              :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
      96              :       TYPE(virial_type), POINTER                         :: virial
      97              :       LOGICAL, INTENT(IN)                                :: calculate_forces
      98              :       LOGICAL                                            :: use_virial
      99              :       INTEGER                                            :: nder
     100              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     101              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     102              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     103              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     104              :          POINTER                                         :: sab_orb, sap_ppnl
     105              :       REAL(KIND=dp), INTENT(IN)                          :: eps_ppnl
     106              :       INTEGER, INTENT(IN)                                :: nimages
     107              :       INTEGER, DIMENSION(:, :, :), OPTIONAL, POINTER     :: cell_to_index
     108              :       CHARACTER(LEN=*), INTENT(IN)                       :: basis_type
     109              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
     110              :          OPTIONAL                                        :: deltaR
     111              :       TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, &
     112              :          POINTER                                         :: matrix_l
     113              :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT), &
     114              :          OPTIONAL                                        :: atcore
     115              : 
     116              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'build_core_ppnl'
     117              : 
     118              :       INTEGER :: atom_a, first_col, handle, i, i_dim, iab, iac, iatom, ib, ibc, icol, ikind, &
     119              :          ilist, img, irow, iset, j, jatom, jb, jkind, jneighbor, kac, katom, kbc, kkind, l, &
     120              :          lc_max, lc_min, ldai, ldsab, lppnl, maxco, maxder, maxl, maxlgto, maxlppnl, maxppnl, &
     121              :          maxsgf, na, natom, nb, ncoa, ncoc, nkind, nlist, nneighbor, nnl, np, nppnl, nprjc, nseta, &
     122              :          nsgfa, prjc, sgfa, slot
     123        17370 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom_of_kind, kind_of
     124              :       INTEGER, DIMENSION(3)                              :: cell_b, cell_c
     125        17370 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, npgfa, nprj_ppnl, &
     126        17370 :                                                             nsgf_seta
     127        17370 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa
     128              :       LOGICAL                                            :: do_dR, do_gth, do_kp, do_soc, do_upf, &
     129              :                                                             doat, found, ppnl_present
     130              :       REAL(KIND=dp)                                      :: atk, dac, f0, ppnl_radius
     131        17370 :       REAL(KIND=dp), ALLOCATABLE                         :: upf_int(:, :, :)
     132        17370 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: radp
     133        17370 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: sab, work
     134        17370 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: ai_work, lab, work_l
     135              :       REAL(KIND=dp), DIMENSION(1)                        :: rprjc, zetc
     136              :       REAL(KIND=dp), DIMENSION(3)                        :: fa, fb, rab, rac, rbc
     137              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: pv_thread
     138              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
     139        17370 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set
     140              :       TYPE(gth_potential_type), POINTER                  :: gth_potential
     141        17370 :       TYPE(gth_potential_p_type), DIMENSION(:), POINTER  :: gpotential
     142              :       TYPE(clist_type), POINTER                          :: clist
     143              :       TYPE(alist_type), POINTER                          :: alist_ac, alist_bc
     144        34740 :       REAL(KIND=dp), DIMENSION(SIZE(particle_set))       :: at_thread
     145        17370 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: achint, acint, alkint, bchint, bcint, &
     146        17370 :                                                             blkint
     147        17370 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: cprj, h_block, l_block_x, l_block_y, &
     148        17370 :                                                             l_block_z, p_block, r_2block, &
     149        17370 :                                                             r_3block, rpgfa, sphi_a, vprj_ppnl, &
     150        17370 :                                                             wprj_ppnl, zeta
     151        17370 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: a_nl, alpha_ppnl, hprj, set_radius_a
     152        34740 :       REAL(KIND=dp), DIMENSION(3, SIZE(particle_set))    :: force_thread
     153        17370 :       TYPE(sap_int_type), DIMENSION(:), POINTER          :: sap_int
     154        17370 :       TYPE(sgp_potential_p_type), DIMENSION(:), POINTER  :: spotential
     155              :       TYPE(sgp_potential_type), POINTER                  :: sgp_potential
     156              :       TYPE(upf_projector_type), POINTER                  :: upf
     157              : 
     158              : !$    INTEGER(kind=omp_lock_kind), &
     159        17370 : !$       ALLOCATABLE, DIMENSION(:) :: locks
     160              : !$    INTEGER(KIND=int_8)                                :: iatom8
     161              : !$    INTEGER                                            :: lock_num, hash
     162              : !$    INTEGER, PARAMETER                                 :: nlock = 501
     163              : 
     164              :       MARK_USED(int_8)
     165              : 
     166        17370 :       do_dR = .FALSE.
     167           72 :       IF (PRESENT(deltaR)) do_dR = .TRUE.
     168        17370 :       doat = .FALSE.
     169        17370 :       IF (PRESENT(atcore)) doat = .TRUE.
     170        17370 :       IF ((calculate_forces .OR. doat) .AND. do_dR) THEN
     171            0 :          CPABORT("core_ppl: incompatible options")
     172              :       END IF
     173              : 
     174        17370 :       IF (calculate_forces) THEN
     175         6863 :          CALL timeset(routineN//"_forces", handle)
     176              :       ELSE
     177        10507 :          CALL timeset(routineN, handle)
     178              :       END IF
     179              : 
     180        17370 :       do_soc = PRESENT(matrix_l)
     181              : 
     182        17370 :       ppnl_present = ASSOCIATED(sap_ppnl)
     183              : 
     184        17370 :       IF (ppnl_present) THEN
     185              : 
     186        17370 :          nkind = SIZE(atomic_kind_set)
     187        17370 :          natom = SIZE(particle_set)
     188              : 
     189        17370 :          do_kp = (nimages > 1)
     190              : 
     191        17370 :          IF (do_kp) THEN
     192         1008 :             IF (PRESENT(cell_to_index)) THEN
     193         1008 :                CPASSERT(ASSOCIATED(cell_to_index))
     194              :             ELSE
     195            0 :                CPABORT("Missing cell_to_index for k-point calculation")
     196              :             END IF
     197              :          END IF
     198              : 
     199        17370 :          IF (calculate_forces .OR. doat) THEN
     200         6925 :             IF (SIZE(matrix_p, 1) == 2) THEN
     201         3042 :                DO img = 1, nimages
     202              :                   CALL dbcsr_add(matrix_p(1, img)%matrix, matrix_p(2, img)%matrix, &
     203         2332 :                                  alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
     204              :                   CALL dbcsr_add(matrix_p(2, img)%matrix, matrix_p(1, img)%matrix, &
     205         3042 :                                  alpha_scalar=-2.0_dp, beta_scalar=1.0_dp)
     206              :                END DO
     207              :             END IF
     208              :          END IF
     209              : 
     210        17370 :          maxder = ncoset(nder)
     211              : 
     212              :          CALL get_qs_kind_set(qs_kind_set, &
     213              :                               maxco=maxco, &
     214              :                               maxlgto=maxlgto, &
     215              :                               maxsgf=maxsgf, &
     216              :                               maxlppnl=maxlppnl, &
     217              :                               maxppnl=maxppnl, &
     218        17370 :                               basis_type=basis_type)
     219              : 
     220        17370 :          maxl = MAX(maxlgto, maxlppnl)
     221        17370 :          CALL init_orbital_pointers(maxl + nder + 1)
     222              : 
     223        17370 :          ldsab = MAX(maxco, ncoset(maxlppnl), maxsgf, maxppnl)
     224        17370 :          ldai = ncoset(maxl + nder + 1)
     225              : 
     226              :          ! sap_int needs to be shared as multiple threads need to access this
     227       118026 :          ALLOCATE (sap_int(nkind*nkind))
     228        83286 :          DO i = 1, nkind*nkind
     229        65916 :             NULLIFY (sap_int(i)%alist, sap_int(i)%asort, sap_int(i)%aindex)
     230        83286 :             sap_int(i)%nalist = 0
     231              :          END DO
     232              : 
     233              :          ! Set up direct access to basis and potential
     234       184266 :          ALLOCATE (basis_set(nkind), gpotential(nkind), spotential(nkind))
     235        49842 :          DO ikind = 1, nkind
     236        32472 :             CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, basis_type=basis_type)
     237        32472 :             IF (ASSOCIATED(orb_basis_set)) THEN
     238        32472 :                basis_set(ikind)%gto_basis_set => orb_basis_set
     239              :             ELSE
     240            0 :                NULLIFY (basis_set(ikind)%gto_basis_set)
     241              :             END IF
     242        32472 :             CALL get_qs_kind(qs_kind_set(ikind), gth_potential=gth_potential, sgp_potential=sgp_potential)
     243        32472 :             NULLIFY (gpotential(ikind)%gth_potential)
     244        32472 :             NULLIFY (spotential(ikind)%sgp_potential)
     245        49842 :             IF (ASSOCIATED(gth_potential)) THEN
     246        32204 :                gpotential(ikind)%gth_potential => gth_potential
     247        32204 :                IF (do_soc .AND. (.NOT. gth_potential%soc)) THEN
     248            0 :                   CPABORT("Spin-orbit coupling selected, but GTH potential without SOC parameters provided")
     249              :                END IF
     250          268 :             ELSE IF (ASSOCIATED(sgp_potential)) THEN
     251           34 :                spotential(ikind)%sgp_potential => sgp_potential
     252           34 :                IF (ALLOCATED(sgp_potential%upf_data)) THEN
     253           34 :                   IF (sgp_potential%upf_data%number_of_proj > 0) THEN
     254           18 :                      IF (sgp_potential%upf_projectors%degree < maxlgto + nder) THEN
     255           18 :                         CALL upf_projector_init(sgp_potential%upf_data, maxlgto + nder, sgp_potential%upf_projectors)
     256              :                      END IF
     257              :                   END IF
     258              :                END IF
     259           34 :                IF (do_soc .AND. ALLOCATED(sgp_potential%upf_data)) THEN
     260            0 :                   CPABORT("Spin-orbit UPF projectors are not supported")
     261              :                END IF
     262              :             END IF
     263              :          END DO
     264              : 
     265              :          ! Allocate sap int
     266      1155614 :          DO slot = 1, sap_ppnl(1)%nl_size
     267              : 
     268      1138244 :             ikind = sap_ppnl(1)%nlist_task(slot)%ikind
     269      1138244 :             kkind = sap_ppnl(1)%nlist_task(slot)%jkind
     270      1138244 :             iatom = sap_ppnl(1)%nlist_task(slot)%iatom
     271      1138244 :             katom = sap_ppnl(1)%nlist_task(slot)%jatom
     272      1138244 :             nlist = sap_ppnl(1)%nlist_task(slot)%nlist
     273      1138244 :             ilist = sap_ppnl(1)%nlist_task(slot)%ilist
     274      1138244 :             nneighbor = sap_ppnl(1)%nlist_task(slot)%nnode
     275              : 
     276      1138244 :             iac = ikind + nkind*(kkind - 1)
     277      1138244 :             IF (.NOT. ASSOCIATED(basis_set(ikind)%gto_basis_set)) CYCLE
     278      1138244 :             IF (.NOT. ASSOCIATED(gpotential(kkind)%gth_potential) .AND. &
     279              :                 .NOT. ASSOCIATED(spotential(kkind)%sgp_potential)) CYCLE
     280      1138244 :             IF (.NOT. ASSOCIATED(sap_int(iac)%alist)) THEN
     281        36080 :                sap_int(iac)%a_kind = ikind
     282        36080 :                sap_int(iac)%p_kind = kkind
     283        36080 :                sap_int(iac)%nalist = nlist
     284       181000 :                ALLOCATE (sap_int(iac)%alist(nlist))
     285       108840 :                DO i = 1, nlist
     286        72760 :                   NULLIFY (sap_int(iac)%alist(i)%clist)
     287        72760 :                   sap_int(iac)%alist(i)%aatom = 0
     288       108840 :                   sap_int(iac)%alist(i)%nclist = 0
     289              :                END DO
     290              :             END IF
     291      1155614 :             IF (.NOT. ASSOCIATED(sap_int(iac)%alist(ilist)%clist)) THEN
     292        72702 :                sap_int(iac)%alist(ilist)%aatom = iatom
     293        72702 :                sap_int(iac)%alist(ilist)%nclist = nneighbor
     294      1792562 :                ALLOCATE (sap_int(iac)%alist(ilist)%clist(nneighbor))
     295      1210946 :                DO i = 1, nneighbor
     296      1210946 :                   sap_int(iac)%alist(ilist)%clist(i)%catom = 0
     297              :                END DO
     298              :             END IF
     299              :          END DO
     300              : 
     301              :          ! Calculate the overlap integrals <a|p>
     302              : !$OMP PARALLEL &
     303              : !$OMP DEFAULT (NONE) &
     304              : !$OMP SHARED  (basis_set, gpotential, spotential, maxder, ncoset, &
     305              : !$OMP          sap_ppnl, sap_int, nkind, ldsab, ldai, nder, nco, do_soc ) &
     306              : !$OMP PRIVATE (ikind, kkind, iatom, katom, nlist, ilist, nneighbor, jneighbor, &
     307              : !$OMP          cell_c, rac, iac, first_sgfa, la_max, la_min, npgfa, nseta, nsgfa, nsgf_seta, &
     308              : !$OMP          slot, sphi_a, zeta, cprj, hprj, lppnl, nppnl, nprj_ppnl, &
     309              : !$OMP          do_upf, upf, upf_int, &
     310              : !$OMP          clist, iset, ncoa, sgfa, prjc, work, work_l, sab, lab, ai_work, nprjc, &
     311              : !$OMP          ppnl_radius, ncoc, rpgfa, first_col, vprj_ppnl, wprj_ppnl, i, j, l, do_gth, &
     312              : !$OMP          set_radius_a, rprjc, dac, lc_max, lc_min, zetc, alpha_ppnl, &
     313        17370 : !$OMP          na, nb, np, nnl, a_nl, radp, i_dim, ib, jb)
     314              : 
     315              :          ALLOCATE (sab(ldsab, ldsab*maxder), work(ldsab, ldsab*maxder))
     316              :          sab = 0.0_dp
     317              :          ALLOCATE (ai_work(ldai, ldai, ncoset(nder + 1)))
     318              :          ai_work = 0.0_dp
     319              :          IF (do_soc) THEN
     320              :             ALLOCATE (lab(ldsab, ldsab, 3), work_l(ldsab, ldsab, 3))
     321              :             lab = 0.0_dp
     322              :          END IF
     323              : 
     324              : !$OMP DO SCHEDULE(GUIDED)
     325              :          DO slot = 1, sap_ppnl(1)%nl_size
     326              : 
     327              :             ikind = sap_ppnl(1)%nlist_task(slot)%ikind
     328              :             kkind = sap_ppnl(1)%nlist_task(slot)%jkind
     329              :             iatom = sap_ppnl(1)%nlist_task(slot)%iatom
     330              :             katom = sap_ppnl(1)%nlist_task(slot)%jatom
     331              :             nlist = sap_ppnl(1)%nlist_task(slot)%nlist
     332              :             ilist = sap_ppnl(1)%nlist_task(slot)%ilist
     333              :             nneighbor = sap_ppnl(1)%nlist_task(slot)%nnode
     334              :             jneighbor = sap_ppnl(1)%nlist_task(slot)%inode
     335              :             cell_c(:) = sap_ppnl(1)%nlist_task(slot)%cell(:)
     336              :             rac(1:3) = sap_ppnl(1)%nlist_task(slot)%r(1:3)
     337              : 
     338              :             iac = ikind + nkind*(kkind - 1)
     339              :             IF (.NOT. ASSOCIATED(basis_set(ikind)%gto_basis_set)) CYCLE
     340              :             ! Get definition of basis set
     341              :             first_sgfa => basis_set(ikind)%gto_basis_set%first_sgf
     342              :             la_max => basis_set(ikind)%gto_basis_set%lmax
     343              :             la_min => basis_set(ikind)%gto_basis_set%lmin
     344              :             npgfa => basis_set(ikind)%gto_basis_set%npgf
     345              :             nseta = basis_set(ikind)%gto_basis_set%nset
     346              :             nsgfa = basis_set(ikind)%gto_basis_set%nsgf
     347              :             nsgf_seta => basis_set(ikind)%gto_basis_set%nsgf_set
     348              :             rpgfa => basis_set(ikind)%gto_basis_set%pgf_radius
     349              :             set_radius_a => basis_set(ikind)%gto_basis_set%set_radius
     350              :             sphi_a => basis_set(ikind)%gto_basis_set%sphi
     351              :             zeta => basis_set(ikind)%gto_basis_set%zet
     352              :             ! Get definition of PP projectors
     353              :             do_upf = .FALSE.
     354              :             IF (ASSOCIATED(gpotential(kkind)%gth_potential)) THEN
     355              :                ! GTH potential
     356              :                do_gth = .TRUE.
     357              :                alpha_ppnl => gpotential(kkind)%gth_potential%alpha_ppnl
     358              :                cprj => gpotential(kkind)%gth_potential%cprj
     359              :                lppnl = gpotential(kkind)%gth_potential%lppnl
     360              :                nppnl = gpotential(kkind)%gth_potential%nppnl
     361              :                nprj_ppnl => gpotential(kkind)%gth_potential%nprj_ppnl
     362              :                ppnl_radius = gpotential(kkind)%gth_potential%ppnl_radius
     363              :                vprj_ppnl => gpotential(kkind)%gth_potential%vprj_ppnl
     364              :                wprj_ppnl => gpotential(kkind)%gth_potential%wprj_ppnl
     365              :             ELSE IF (ASSOCIATED(spotential(kkind)%sgp_potential)) THEN
     366              :                ! SGP potential
     367              :                do_gth = .FALSE.
     368              :                nprjc = spotential(kkind)%sgp_potential%nppnl
     369              :                IF (nprjc == 0) CYCLE
     370              :                do_upf = ALLOCATED(spotential(kkind)%sgp_potential%upf_data)
     371              :                IF (do_upf) THEN
     372              :                   upf => spotential(kkind)%sgp_potential%upf_projectors
     373              :                   nppnl = upf%nproj
     374              :                ELSE
     375              :                   nnl = spotential(kkind)%sgp_potential%n_nonlocal
     376              :                   lppnl = spotential(kkind)%sgp_potential%lmax
     377              :                   a_nl => spotential(kkind)%sgp_potential%a_nonlocal
     378              :                   ppnl_radius = spotential(kkind)%sgp_potential%ppnl_radius
     379              :                   ALLOCATE (radp(nnl))
     380              :                   radp(:) = ppnl_radius
     381              :                   cprj => spotential(kkind)%sgp_potential%cprj_ppnl
     382              :                   hprj => spotential(kkind)%sgp_potential%vprj_ppnl
     383              :                   nppnl = SIZE(cprj, 2)
     384              :                END IF
     385              :             ELSE
     386              :                CYCLE
     387              :             END IF
     388              : 
     389              :             dac = SQRT(SUM(rac*rac))
     390              :             clist => sap_int(iac)%alist(ilist)%clist(jneighbor)
     391              :             clist%catom = katom
     392              :             clist%cell = cell_c
     393              :             clist%rac = rac
     394              :             ALLOCATE (clist%acint(nsgfa, nppnl, maxder), &
     395              :                       clist%achint(nsgfa, nppnl, maxder), &
     396              :                       clist%alint(nsgfa, nppnl, 3), &
     397              :                       clist%alkint(nsgfa, nppnl, 3))
     398              :             clist%acint = 0.0_dp
     399              :             clist%achint = 0.0_dp
     400              :             clist%alint = 0.0_dp
     401              :             clist%alkint = 0.0_dp
     402              : 
     403              :             clist%nsgf_cnt = 0
     404              :             NULLIFY (clist%sgf_list)
     405              :             DO iset = 1, nseta
     406              :                ncoa = npgfa(iset)*ncoset(la_max(iset))
     407              :                sgfa = first_sgfa(1, iset)
     408              :                IF (do_gth) THEN
     409              :                   ! GTH potential
     410              :                   prjc = 1
     411              :                   work = 0.0_dp
     412              :                   ! Screened projector channels must not retain SOC integrals
     413              :                   ! from the preceding shell set or atom/image pair.
     414              :                   IF (do_soc) work_l = 0.0_dp
     415              :                   DO l = 0, lppnl
     416              :                      nprjc = nprj_ppnl(l)*nco(l)
     417              :                      IF (nprjc == 0) CYCLE
     418              :                      rprjc(1) = ppnl_radius
     419              :                      IF (set_radius_a(iset) + rprjc(1) < dac) CYCLE
     420              :                      lc_max = l + 2*(nprj_ppnl(l) - 1)
     421              :                      lc_min = l
     422              :                      zetc(1) = alpha_ppnl(l)
     423              :                      ncoc = ncoset(lc_max)
     424              : 
     425              :                      ! Calculate the primitive overlap integrals
     426              :                      CALL overlap(la_max(iset), la_min(iset), npgfa(iset), rpgfa(:, iset), zeta(:, iset), &
     427              :                                   lc_max, lc_min, 1, rprjc, zetc, rac, dac, sab, nder, .TRUE., ai_work, ldai)
     428              :                      ! Transformation step projector functions (Cartesian -> spherical)
     429              :                      na = ncoa
     430              :                      nb = nprjc
     431              :                      np = ncoc
     432              :                      DO i = 1, maxder
     433              :                         first_col = (i - 1)*ldsab
     434              :                         ! CALL dgemm("N", "N", ncoa, nprjc, ncoc, 1.0_dp, sab(1, first_col + 1), SIZE(sab, 1), &
     435              :                         !            cprj(1, prjc), SIZE(cprj, 1), 0.0_dp, work(1, first_col + prjc), ldsab)
     436              :                         work(1:na, first_col + prjc:first_col + prjc + nb - 1) = &
     437              :                            MATMUL(sab(1:na, first_col + 1:first_col + np), cprj(1:np, prjc:prjc + nb - 1))
     438              :                      END DO
     439              : 
     440              :                      IF (do_soc) THEN
     441              :                         ! Calculate the primitive angular momentum integrals needed for spin-orbit coupling
     442              :                         lab = 0.0_dp
     443              :                         CALL angmom(la_max(iset), npgfa(iset), zeta(:, iset), rpgfa(:, iset), la_min(iset), &
     444              :                                     lc_max, 1, zetc, rprjc, -rac, [0._dp, 0._dp, 0._dp], lab)
     445              :                         DO i_dim = 1, 3
     446              :                            work_l(1:na, prjc:prjc + nb - 1, i_dim) = &
     447              :                               MATMUL(lab(1:na, 1:np, i_dim), cprj(1:np, prjc:prjc + nb - 1))
     448              :                         END DO
     449              :                      END IF
     450              : 
     451              :                      prjc = prjc + nprjc
     452              : 
     453              :                   END DO
     454              :                   na = nsgf_seta(iset)
     455              :                   nb = nppnl
     456              :                   np = ncoa
     457              :                   DO i = 1, maxder
     458              :                      first_col = (i - 1)*ldsab + 1
     459              :                      ! Contraction step (basis functions)
     460              :                      ! CALL dgemm("T", "N", nsgf_seta(iset), nppnl, ncoa, 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
     461              :                      !           work(1, first_col), ldsab, 0.0_dp, clist%acint(sgfa, 1, i), nsgfa)
     462              :                      clist%acint(sgfa:sgfa + na - 1, 1:nb, i) = &
     463              :                         MATMUL(TRANSPOSE(sphi_a(1:np, sgfa:sgfa + na - 1)), work(1:np, first_col:first_col + nb - 1))
     464              :                      ! Multiply with interaction matrix(h)
     465              :                      ! CALL dgemm("N", "N", nsgf_seta(iset), nppnl, nppnl, 1.0_dp, clist%acint(sgfa, 1, i), nsgfa, &
     466              :                      !            vprj_ppnl(1, 1), SIZE(vprj_ppnl, 1), 0.0_dp, clist%achint(sgfa, 1, i), nsgfa)
     467              :                      clist%achint(sgfa:sgfa + na - 1, 1:nb, i) = &
     468              :                         MATMUL(clist%acint(sgfa:sgfa + na - 1, 1:nb, i), vprj_ppnl(1:nb, 1:nb))
     469              :                   END DO
     470              :                   IF (do_soc) THEN
     471              :                      DO i_dim = 1, 3
     472              :                         clist%alint(sgfa:sgfa + na - 1, 1:nb, i_dim) = &
     473              :                            MATMUL(TRANSPOSE(sphi_a(1:np, sgfa:sgfa + na - 1)), work_l(1:np, 1:nb, i_dim))
     474              :                         clist%alkint(sgfa:sgfa + na - 1, 1:nb, i_dim) = &
     475              :                            MATMUL(clist%alint(sgfa:sgfa + na - 1, 1:nb, i_dim), wprj_ppnl(1:nb, 1:nb))
     476              :                      END DO
     477              :                   END IF
     478              :                ELSE IF (do_upf) THEN
     479              :                   na = nsgf_seta(iset)
     480              :                   nb = nppnl
     481              :                   np = ncoa
     482              :                   ALLOCATE (upf_int(np, nb, maxder))
     483              :                   CALL upf_projector_overlap(upf, la_max(iset), zeta(:npgfa(iset), iset), &
     484              :                                              rac, nder, upf_int)
     485              :                   DO i = 1, maxder
     486              :                      clist%acint(sgfa:sgfa + na - 1, 1:nb, i) = &
     487              :                         MATMUL(TRANSPOSE(sphi_a(1:np, sgfa:sgfa + na - 1)), upf_int(:, :, i))
     488              :                      clist%achint(sgfa:sgfa + na - 1, 1:nb, i) = &
     489              :                         MATMUL(clist%acint(sgfa:sgfa + na - 1, 1:nb, i), upf%d)
     490              :                   END DO
     491              :                   DEALLOCATE (upf_int)
     492              :                ELSE
     493              :                   ! SGP potential
     494              :                   ! Calculate the primitive overlap integrals
     495              :                   CALL overlap(la_max(iset), la_min(iset), npgfa(iset), rpgfa(:, iset), zeta(:, iset), &
     496              :                                lppnl, 0, nnl, radp, a_nl, rac, dac, sab, nder, .TRUE., ai_work, ldai)
     497              :                   na = nsgf_seta(iset)
     498              :                   nb = nppnl
     499              :                   np = ncoa
     500              :                   DO i = 1, maxder
     501              :                      first_col = (i - 1)*ldsab + 1
     502              :                      ! Transformation step projector functions (cartesian->spherical)
     503              :                      ! CALL dgemm("N", "N", ncoa, nppnl, nprjc, 1.0_dp, sab(1, first_col), ldsab, &
     504              :                      !            cprj(1, 1), SIZE(cprj, 1), 0.0_dp, work(1, 1), ldsab)
     505              :                      work(1:np, 1:nb) = MATMUL(sab(1:np, first_col:first_col + nprjc - 1), cprj(1:nprjc, 1:nb))
     506              :                      ! Contraction step (basis functions)
     507              :                      ! CALL dgemm("T", "N", nsgf_seta(iset), nppnl, ncoa, 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
     508              :                      !            work(1, 1), ldsab, 0.0_dp, clist%acint(sgfa, 1, i), nsgfa)
     509              :                      clist%acint(sgfa:sgfa + na - 1, 1:nb, i) = &
     510              :                         MATMUL(TRANSPOSE(sphi_a(1:np, sgfa:sgfa + na - 1)), work(1:np, 1:nb))
     511              :                      ! *** Multiply with interaction matrix(h) ***
     512              :                      ncoc = sgfa + nsgf_seta(iset) - 1
     513              :                      DO j = 1, nppnl
     514              :                         clist%achint(sgfa:ncoc, j, i) = clist%acint(sgfa:ncoc, j, i)*hprj(j)
     515              :                      END DO
     516              :                   END DO
     517              :                END IF
     518              :             END DO
     519              :             clist%maxac = MAXVAL(ABS(clist%acint(:, :, 1)))
     520              :             clist%maxach = MAXVAL(ABS(clist%achint(:, :, 1)))
     521              :             IF (.NOT. do_gth .AND. .NOT. do_upf) DEALLOCATE (radp)
     522              :          END DO
     523              : 
     524              :          DEALLOCATE (sab, ai_work, work)
     525              :          IF (do_soc) DEALLOCATE (lab, work_l)
     526              : !$OMP END PARALLEL
     527              : 
     528              :          ! Set up a sorting index
     529        17370 :          CALL sap_sort(sap_int)
     530              :          ! All integrals needed have been calculated and stored in sap_int
     531              :          ! We now calculate the Hamiltonian matrix elements
     532              : 
     533       277450 :          force_thread = 0.0_dp
     534        82390 :          at_thread = 0.0_dp
     535        17370 :          pv_thread = 0.0_dp
     536              : 
     537              : !$OMP PARALLEL &
     538              : !$OMP DEFAULT (NONE) &
     539              : !$OMP SHARED  (do_kp, basis_set, matrix_h, matrix_l, cell_to_index,&
     540              : !$OMP          sab_orb, matrix_p, sap_int, nkind, eps_ppnl, force, &
     541              : !$OMP          doat, do_dR, deltaR, maxder, nder, &
     542              : !$OMP          locks, virial, use_virial, calculate_forces, do_soc, natom) &
     543              : !$OMP PRIVATE (ikind, jkind, iatom, jatom, cell_b, rab, &
     544              : !$OMP          slot, iab, atom_a, f0, irow, icol, h_block, &
     545              : !$OMP          l_block_x, l_block_y, l_block_z, lock_num, &
     546              : !$OMP          r_2block, r_3block, atk, &
     547              : !$OMP          found,p_block, iac, ibc, alist_ac, alist_bc, acint, bcint, &
     548              : !$OMP          achint, bchint, alkint, blkint, &
     549              : !$OMP          na, np, nb, katom, j, fa, fb, rbc, rac, &
     550              : !$OMP          kkind, kac, kbc, i, img, hash, iatom8) &
     551        17370 : !$OMP REDUCTION (+ : at_thread, pv_thread, force_thread )
     552              : 
     553              : !$OMP SINGLE
     554              : !$       ALLOCATE (locks(nlock))
     555              : !$OMP END SINGLE
     556              : 
     557              : !$OMP DO
     558              : !$       DO lock_num = 1, nlock
     559              : !$          call omp_init_lock(locks(lock_num))
     560              : !$       END DO
     561              : !$OMP END DO
     562              : 
     563              : !$OMP DO SCHEDULE(GUIDED)
     564              :          DO slot = 1, sab_orb(1)%nl_size
     565              : 
     566              :             ikind = sab_orb(1)%nlist_task(slot)%ikind
     567              :             jkind = sab_orb(1)%nlist_task(slot)%jkind
     568              :             iatom = sab_orb(1)%nlist_task(slot)%iatom
     569              :             jatom = sab_orb(1)%nlist_task(slot)%jatom
     570              :             cell_b(:) = sab_orb(1)%nlist_task(slot)%cell(:)
     571              :             rab(1:3) = sab_orb(1)%nlist_task(slot)%r(1:3)
     572              : 
     573              :             IF (.NOT. ASSOCIATED(basis_set(ikind)%gto_basis_set)) CYCLE
     574              :             IF (.NOT. ASSOCIATED(basis_set(jkind)%gto_basis_set)) CYCLE
     575              : 
     576              :             iab = ikind + nkind*(jkind - 1)
     577              : 
     578              :             ! Use the symmetry of the first derivatives
     579              :             IF (iatom == jatom) THEN
     580              :                f0 = 1.0_dp
     581              :             ELSE
     582              :                f0 = 2.0_dp
     583              :             END IF
     584              : 
     585              :             IF (do_kp) THEN
     586              :                img = cell_to_index(cell_b(1), cell_b(2), cell_b(3))
     587              :             ELSE
     588              :                img = 1
     589              :             END IF
     590              : 
     591              :             ! Create matrix blocks for a new matrix block column
     592              :             IF (iatom <= jatom) THEN
     593              :                irow = iatom
     594              :                icol = jatom
     595              :             ELSE
     596              :                irow = jatom
     597              :                icol = iatom
     598              :             END IF
     599              :             NULLIFY (h_block)
     600              :             CALL dbcsr_get_block_p(matrix_h(1, img)%matrix, irow, icol, h_block, found)
     601              :             IF (do_soc) THEN
     602              :                NULLIFY (l_block_x, l_block_y, l_block_z)
     603              :                CALL dbcsr_get_block_p(matrix_l(1, img)%matrix, irow, icol, l_block_x, found)
     604              :                CALL dbcsr_get_block_p(matrix_l(2, img)%matrix, irow, icol, l_block_y, found)
     605              :                CALL dbcsr_get_block_p(matrix_l(3, img)%matrix, irow, icol, l_block_z, found)
     606              :             END IF
     607              : 
     608              :             IF (do_dR) THEN
     609              :                NULLIFY (r_2block, r_3block)
     610              :                CALL dbcsr_get_block_p(matrix_h(2, img)%matrix, irow, icol, r_2block, found)
     611              :                CALL dbcsr_get_block_p(matrix_h(3, img)%matrix, irow, icol, r_3block, found)
     612              :             END IF
     613              : 
     614              :             IF (calculate_forces .OR. doat) THEN
     615              :                NULLIFY (p_block)
     616              :                CALL dbcsr_get_block_p(matrix_p(1, img)%matrix, irow, icol, p_block, found)
     617              :             END IF
     618              : 
     619              :             ! loop over all kinds for projector atom
     620              :             IF (ASSOCIATED(h_block)) THEN
     621              : !$             iatom8 = INT(iatom - 1, int_8)*INT(natom, int_8) + INT(jatom, int_8)
     622              : !$             hash = INT(MOD(iatom8, INT(nlock, int_8)) + 1)
     623              : 
     624              :                DO kkind = 1, nkind
     625              :                   iac = ikind + nkind*(kkind - 1)
     626              :                   ibc = jkind + nkind*(kkind - 1)
     627              :                   IF (.NOT. ASSOCIATED(sap_int(iac)%alist)) CYCLE
     628              :                   IF (.NOT. ASSOCIATED(sap_int(ibc)%alist)) CYCLE
     629              :                   CALL get_alist(sap_int(iac), alist_ac, iatom)
     630              :                   CALL get_alist(sap_int(ibc), alist_bc, jatom)
     631              :                   IF (.NOT. ASSOCIATED(alist_ac)) CYCLE
     632              :                   IF (.NOT. ASSOCIATED(alist_bc)) CYCLE
     633              :                   DO kac = 1, alist_ac%nclist
     634              :                      DO kbc = 1, alist_bc%nclist
     635              :                         IF (alist_ac%clist(kac)%catom /= alist_bc%clist(kbc)%catom) CYCLE
     636              :                         IF (ALL(cell_b + alist_bc%clist(kbc)%cell - alist_ac%clist(kac)%cell == 0)) THEN
     637              :                            IF (alist_ac%clist(kac)%maxac*alist_bc%clist(kbc)%maxach < eps_ppnl) CYCLE
     638              :                            acint => alist_ac%clist(kac)%acint
     639              :                            bcint => alist_bc%clist(kbc)%acint
     640              :                            achint => alist_ac%clist(kac)%achint
     641              :                            bchint => alist_bc%clist(kbc)%achint
     642              :                            IF (do_soc) THEN
     643              :                               alkint => alist_ac%clist(kac)%alkint
     644              :                               blkint => alist_bc%clist(kbc)%alkint
     645              :                            END IF
     646              :                            na = SIZE(acint, 1)
     647              :                            np = SIZE(acint, 2)
     648              :                            nb = SIZE(bcint, 1)
     649              : !$                         CALL omp_set_lock(locks(hash))
     650              :                            IF (.NOT. do_dR) THEN
     651              :                               IF (iatom <= jatom) THEN
     652              :                                  h_block(1:na, 1:nb) = h_block(1:na, 1:nb) + &
     653              :                                                        MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     654              :                               ELSE
     655              :                                  h_block(1:nb, 1:na) = h_block(1:nb, 1:na) + &
     656              :                                                        MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 1)))
     657              :                               END IF
     658              :                            END IF
     659              :                            IF (do_soc) THEN
     660              :                               IF (iatom <= jatom) THEN
     661              :                                  l_block_x(1:na, 1:nb) = l_block_x(1:na, 1:nb) + &
     662              :                                                          MATMUL(alkint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     663              :                                  l_block_y(1:na, 1:nb) = l_block_y(1:na, 1:nb) + &
     664              :                                                          MATMUL(alkint(1:na, 1:np, 2), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     665              :                                  l_block_z(1:na, 1:nb) = l_block_z(1:na, 1:nb) + &
     666              :                                                          MATMUL(alkint(1:na, 1:np, 3), TRANSPOSE(bcint(1:nb, 1:np, 1)))
     667              : 
     668              :                               ELSE
     669              :                                  l_block_x(1:nb, 1:na) = l_block_x(1:nb, 1:na) + &
     670              :                                                          MATMUL(blkint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 1)))
     671              :                                  l_block_y(1:nb, 1:na) = l_block_y(1:nb, 1:na) + &
     672              :                                                          MATMUL(blkint(1:nb, 1:np, 2), TRANSPOSE(acint(1:na, 1:np, 1)))
     673              :                                  l_block_z(1:nb, 1:na) = l_block_z(1:nb, 1:na) + &
     674              :                                                          MATMUL(blkint(1:nb, 1:np, 3), TRANSPOSE(acint(1:na, 1:np, 1)))
     675              :                               END IF
     676              :                            END IF
     677              : !$                         CALL omp_unset_lock(locks(hash))
     678              :                            IF (calculate_forces) THEN
     679              :                               IF (ASSOCIATED(p_block)) THEN
     680              :                                  katom = alist_ac%clist(kac)%catom
     681              :                                  DO i = 1, 3
     682              :                                     j = i + 1
     683              :                                     IF (iatom <= jatom) THEN
     684              :                                        fa(i) = SUM(p_block(1:na, 1:nb)* &
     685              :                                                    MATMUL(acint(1:na, 1:np, j), TRANSPOSE(bchint(1:nb, 1:np, 1))))
     686              :                                        fb(i) = SUM(p_block(1:na, 1:nb)* &
     687              :                                                    MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, j))))
     688              :                                     ELSE
     689              :                                        fa(i) = SUM(p_block(1:nb, 1:na)* &
     690              :                                                    MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, j))))
     691              :                                        fb(i) = SUM(p_block(1:nb, 1:na)* &
     692              :                                                    MATMUL(bcint(1:nb, 1:np, j), TRANSPOSE(achint(1:na, 1:np, 1))))
     693              :                                     END IF
     694              :                                     force_thread(i, iatom) = force_thread(i, iatom) + f0*fa(i)
     695              :                                     force_thread(i, katom) = force_thread(i, katom) - f0*fa(i)
     696              :                                     force_thread(i, jatom) = force_thread(i, jatom) + f0*fb(i)
     697              :                                     force_thread(i, katom) = force_thread(i, katom) - f0*fb(i)
     698              :                                  END DO
     699              : 
     700              :                                  IF (use_virial) THEN
     701              :                                     rac = alist_ac%clist(kac)%rac
     702              :                                     rbc = alist_bc%clist(kbc)%rac
     703              :                                     CALL virial_pair_force(pv_thread, f0, fa, rac)
     704              :                                     CALL virial_pair_force(pv_thread, f0, fb, rbc)
     705              :                                  END IF
     706              :                               END IF
     707              :                            END IF
     708              : 
     709              :                            IF (do_dR) THEN
     710              :                               i = 1; j = 2
     711              :                               katom = alist_ac%clist(kac)%catom
     712              :                               IF (iatom <= jatom) THEN
     713              :                                  h_block(1:na, 1:nb) = h_block(1:na, 1:nb) + &
     714              :                                                        (deltaR(i, iatom) - deltaR(i, katom))* &
     715              :                                                        MATMUL(acint(1:na, 1:np, j), TRANSPOSE(bchint(1:nb, 1:np, 1)))
     716              : 
     717              :                                  h_block(1:na, 1:nb) = h_block(1:na, 1:nb) + &
     718              :                                                        (deltaR(i, jatom) - deltaR(i, katom))* &
     719              :                                                        MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, j)))
     720              :                               ELSE
     721              :                                  h_block(1:nb, 1:na) = h_block(1:nb, 1:na) + &
     722              :                                                        (deltaR(i, iatom) - deltaR(i, katom))* &
     723              :                                                        MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, j)))
     724              :                                  h_block(1:nb, 1:na) = h_block(1:nb, 1:na) + &
     725              :                                                        (deltaR(i, jatom) - deltaR(i, katom))* &
     726              :                                                        MATMUL(bcint(1:nb, 1:np, j), TRANSPOSE(achint(1:na, 1:np, 1)))
     727              :                               END IF
     728              : 
     729              :                               i = 2; j = 3
     730              :                               katom = alist_ac%clist(kac)%catom
     731              :                               IF (iatom <= jatom) THEN
     732              :                                  r_2block(1:na, 1:nb) = r_2block(1:na, 1:nb) + &
     733              :                                                         (deltaR(i, iatom) - deltaR(i, katom))* &
     734              :                                                         MATMUL(acint(1:na, 1:np, j), TRANSPOSE(bchint(1:nb, 1:np, 1)))
     735              : 
     736              :                                  r_2block(1:na, 1:nb) = r_2block(1:na, 1:nb) + &
     737              :                                                         (deltaR(i, jatom) - deltaR(i, katom))* &
     738              :                                                         MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, j)))
     739              :                               ELSE
     740              :                                  r_2block(1:nb, 1:na) = r_2block(1:nb, 1:na) + &
     741              :                                                         (deltaR(i, iatom) - deltaR(i, katom))* &
     742              :                                                         MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, j)))
     743              :                                  r_2block(1:nb, 1:na) = r_2block(1:nb, 1:na) + &
     744              :                                                         (deltaR(i, jatom) - deltaR(i, katom))* &
     745              :                                                         MATMUL(bcint(1:nb, 1:np, j), TRANSPOSE(achint(1:na, 1:np, 1)))
     746              :                               END IF
     747              : 
     748              :                               i = 3; j = 4
     749              :                               katom = alist_ac%clist(kac)%catom
     750              :                               IF (iatom <= jatom) THEN
     751              :                                  r_3block(1:na, 1:nb) = r_3block(1:na, 1:nb) + &
     752              :                                                         (deltaR(i, iatom) - deltaR(i, katom))* &
     753              :                                                         MATMUL(acint(1:na, 1:np, j), TRANSPOSE(bchint(1:nb, 1:np, 1)))
     754              : 
     755              :                                  r_3block(1:na, 1:nb) = r_3block(1:na, 1:nb) + &
     756              :                                                         (deltaR(i, jatom) - deltaR(i, katom))* &
     757              :                                                         MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, j)))
     758              :                               ELSE
     759              :                                  r_3block(1:nb, 1:na) = r_3block(1:nb, 1:na) + &
     760              :                                                         (deltaR(i, iatom) - deltaR(i, katom))* &
     761              :                                                         MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, j)))
     762              :                                  r_3block(1:nb, 1:na) = r_3block(1:nb, 1:na) + &
     763              :                                                         (deltaR(i, jatom) - deltaR(i, katom))* &
     764              :                                                         MATMUL(bcint(1:nb, 1:np, j), TRANSPOSE(achint(1:na, 1:np, 1)))
     765              :                               END IF
     766              : 
     767              :                            END IF
     768              :                            IF (doat) THEN
     769              :                               IF (ASSOCIATED(p_block)) THEN
     770              :                                  katom = alist_ac%clist(kac)%catom
     771              :                                  IF (iatom <= jatom) THEN
     772              :                                     atk = SUM(p_block(1:na, 1:nb)* &
     773              :                                               MATMUL(achint(1:na, 1:np, 1), TRANSPOSE(bcint(1:nb, 1:np, 1))))
     774              :                                  ELSE
     775              :                                     atk = SUM(p_block(1:nb, 1:na)* &
     776              :                                               MATMUL(bchint(1:nb, 1:np, 1), TRANSPOSE(acint(1:na, 1:np, 1))))
     777              :                                  END IF
     778              :                                  at_thread(katom) = at_thread(katom) + f0*atk
     779              :                               END IF
     780              :                            END IF
     781              :                            EXIT ! We have found a match and there can be only one single match
     782              :                         END IF
     783              :                      END DO
     784              :                   END DO
     785              :                END DO
     786              :             END IF
     787              :          END DO
     788              : 
     789              : !$OMP DO
     790              : !$       DO lock_num = 1, nlock
     791              : !$          call omp_destroy_lock(locks(lock_num))
     792              : !$       END DO
     793              : !$OMP END DO
     794              : 
     795              : !$OMP SINGLE
     796              : !$       DEALLOCATE (locks)
     797              : !$OMP END SINGLE NOWAIT
     798              : 
     799              : !$OMP END PARALLEL
     800              : 
     801        17370 :          CALL release_sap_int(sap_int)
     802              : 
     803        17370 :          DEALLOCATE (basis_set, gpotential, spotential)
     804        17370 :          IF (calculate_forces) THEN
     805         6863 :             CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind, kind_of=kind_of)
     806              : !$OMP DO
     807              :             DO iatom = 1, natom
     808        24865 :                atom_a = atom_of_kind(iatom)
     809        24865 :                ikind = kind_of(iatom)
     810        99460 :                force(ikind)%gth_ppnl(:, atom_a) = force(ikind)%gth_ppnl(:, atom_a) + force_thread(:, iatom)
     811              :             END DO
     812              : !$OMP END DO
     813         6863 :             DEALLOCATE (atom_of_kind, kind_of)
     814              :          END IF
     815              : 
     816        17370 :          IF (calculate_forces .AND. use_virial) THEN
     817        11284 :             virial%pv_ppnl = virial%pv_ppnl + pv_thread
     818        11284 :             virial%pv_virial = virial%pv_virial + pv_thread
     819              :          END IF
     820              : 
     821        17370 :          IF (doat) THEN
     822          280 :             atcore(1:natom) = atcore(1:natom) + at_thread
     823              :          END IF
     824              : 
     825        34740 :          IF (calculate_forces .OR. doat) THEN
     826              :             ! If LSD, then recover alpha density and beta density
     827              :             ! from the total density (1) and the spin density (2)
     828         6925 :             IF (SIZE(matrix_p, 1) == 2) THEN
     829         3042 :                DO img = 1, nimages
     830              :                   CALL dbcsr_add(matrix_p(1, img)%matrix, matrix_p(2, img)%matrix, &
     831         2332 :                                  alpha_scalar=0.5_dp, beta_scalar=0.5_dp)
     832              :                   CALL dbcsr_add(matrix_p(2, img)%matrix, matrix_p(1, img)%matrix, &
     833         3042 :                                  alpha_scalar=-1.0_dp, beta_scalar=1.0_dp)
     834              :                END DO
     835              :             END IF
     836              :          END IF
     837              : 
     838              :       END IF !ppnl_present
     839              : 
     840        17370 :       CALL timestop(handle)
     841              : 
     842        34740 :    END SUBROUTINE build_core_ppnl
     843              : 
     844              : END MODULE core_ppnl
        

Generated by: LCOV version 2.0-1