LCOV - code coverage report
Current view: top level - src - qs_operators_ao.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:62906da) Lines: 98.7 % 301 297
Test Date: 2026-10-24 01:17:15 Functions: 100.0 % 3 3

            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              : ! **************************************************************************************************
       9              : !> \par History
      10              : !>      created 07.2005
      11              : !> \author MI (07.2005)
      12              : ! **************************************************************************************************
      13              : MODULE qs_operators_ao
      14              :    USE ai_angmom,                       ONLY: angmom
      15              :    USE ai_moments,                      ONLY: contract_expikr,&
      16              :                                               expikr
      17              :    USE ai_overlap,                      ONLY: overlap_ab
      18              :    USE basis_set_types,                 ONLY: gto_basis_set_p_type,&
      19              :                                               gto_basis_set_type
      20              :    USE block_p_types,                   ONLY: block_p_type
      21              :    USE cell_types,                      ONLY: cell_type,&
      22              :                                               pbc
      23              :    USE cp_dbcsr_api,                    ONLY: dbcsr_get_block_p,&
      24              :                                               dbcsr_get_matrix_type,&
      25              :                                               dbcsr_has_symmetry,&
      26              :                                               dbcsr_p_type,&
      27              :                                               dbcsr_set,&
      28              :                                               dbcsr_type_antisymmetric
      29              :    USE kinds,                           ONLY: dp
      30              :    USE orbital_pointers,                ONLY: init_orbital_pointers,&
      31              :                                               ncoset
      32              :    USE particle_types,                  ONLY: particle_type
      33              :    USE qs_environment_types,            ONLY: get_qs_env,&
      34              :                                               qs_environment_type
      35              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      36              :                                               get_qs_kind_set,&
      37              :                                               qs_kind_type
      38              :    USE qs_neighbor_list_types,          ONLY: get_iterator_info,&
      39              :                                               neighbor_list_iterate,&
      40              :                                               neighbor_list_iterator_create,&
      41              :                                               neighbor_list_iterator_p_type,&
      42              :                                               neighbor_list_iterator_release,&
      43              :                                               neighbor_list_set_p_type
      44              : #include "./base/base_uses.f90"
      45              : 
      46              :    IMPLICIT NONE
      47              :    PRIVATE
      48              : 
      49              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_operators_ao'
      50              : 
      51              : ! *** Public subroutines ***
      52              : 
      53              :    PUBLIC :: build_exp_ikr_matrix
      54              :    PUBLIC :: build_lin_mom_matrix, build_ang_mom_matrix
      55              : 
      56              : CONTAINS
      57              : 
      58              : ! **************************************************************************************************
      59              : !> \brief Build real and imaginary AO matrices for exp(i*k*r).
      60              : !> \param qs_env ...
      61              : !> \param op_sm_set op_sm_set(1, i) is the cosine matrix and op_sm_set(2, i) is the sine matrix
      62              : !>        for kvec(:, i)
      63              : !> \param kvec Cartesian wave vectors, one column for each output matrix pair
      64              : !> \param sab_orb_external optional neighbor list used instead of the default orbital list
      65              : !> \param basis_type optional basis-set name
      66              : !> \param force_periodic temporarily use all three periodic directions
      67              : !> \param cell_external optional cell used for coordinate folding and periodicity
      68              : !> \author CP2K developers
      69              : !> \note The cosine and sine matrices must be preallocated with matching symmetric
      70              : !>       DBCSR topology. The matrices are overwritten from zero and only canonical
      71              : !>       atom-pair blocks are written.
      72              : ! **************************************************************************************************
      73        13972 :    SUBROUTINE build_exp_ikr_matrix(qs_env, op_sm_set, kvec, sab_orb_external, basis_type, force_periodic, cell_external)
      74              : 
      75              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      76              :       TYPE(dbcsr_p_type), DIMENSION(:, :)                :: op_sm_set
      77              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: kvec
      78              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
      79              :          OPTIONAL, POINTER                               :: sab_orb_external
      80              :       CHARACTER(LEN=*), OPTIONAL                         :: basis_type
      81              :       LOGICAL, OPTIONAL                                  :: force_periodic
      82              :       TYPE(cell_type), OPTIONAL, POINTER                 :: cell_external
      83              : 
      84              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'build_exp_ikr_matrix'
      85              : 
      86              :       COMPLEX(KIND=dp), ALLOCATABLE                      :: expab(:, :)
      87              :       INTEGER :: handle, i, iatom, icol, ikind, inode, irow, iset, jatom, jkind, jset, last_jatom, &
      88              :          ldsa, ldsb, ldwork, ncoa, ncob, nkind, nkvec, nseta, nsetb, reim, sgfa, sgfb
      89              :       INTEGER, DIMENSION(3)                              :: perd0
      90        13972 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, lb_max, lb_min, npgfa, &
      91        13972 :                                                             npgfb, nsgfa, nsgfb
      92        13972 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, first_sgfb
      93              :       LOGICAL                                            :: found, my_force_periodic, new_atom_b
      94              :       REAL(KIND=dp)                                      :: dab
      95              :       REAL(KIND=dp), DIMENSION(3)                        :: ra, rab, rb
      96        13972 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: set_radius_a, set_radius_b
      97        13972 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: rpgfa, rpgfb, sphi_a, sphi_b, work, &
      98        13972 :                                                             zeta, zetb
      99        13972 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:, :)   :: op_cossin
     100              :       TYPE(cell_type), POINTER                           :: cell
     101        13972 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set_list
     102              :       TYPE(gto_basis_set_type), POINTER                  :: basis_set_a, basis_set_b
     103              :       TYPE(neighbor_list_iterator_p_type), &
     104        13972 :          DIMENSION(:), POINTER                           :: nl_iterator
     105              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     106        13972 :          POINTER                                         :: sab_orb
     107        13972 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     108        13972 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     109              :       TYPE(qs_kind_type), POINTER                        :: qs_kind
     110              : 
     111        13972 :       CALL timeset(routineN, handle)
     112              : 
     113        13972 :       CPASSERT(SIZE(kvec, 1) == 3)
     114        13972 :       nkvec = SIZE(kvec, 2)
     115        13972 :       CPASSERT(nkvec > 0)
     116        13972 :       CPASSERT(SIZE(op_sm_set, 1) == 2)
     117        13972 :       CPASSERT(SIZE(op_sm_set, 2) == nkvec)
     118        28968 :       DO i = 1, nkvec
     119        58960 :          DO reim = 1, 2
     120        29992 :             CPASSERT(ASSOCIATED(op_sm_set(reim, i)%matrix))
     121        29992 :             CPASSERT(dbcsr_has_symmetry(op_sm_set(reim, i)%matrix))
     122        44988 :             CALL dbcsr_set(op_sm_set(reim, i)%matrix, 0.0_dp)
     123              :          END DO
     124              :       END DO
     125              : 
     126        13972 :       NULLIFY (qs_kind, qs_kind_set, particle_set, sab_orb, cell)
     127              :       CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, &
     128        13972 :                       particle_set=particle_set, cell=cell, sab_orb=sab_orb)
     129        13972 :       CPASSERT(ASSOCIATED(cell))
     130        13972 :       CPASSERT(ASSOCIATED(qs_kind_set))
     131        13972 :       CPASSERT(ASSOCIATED(particle_set))
     132        13972 :       IF (PRESENT(cell_external)) THEN
     133          494 :          CPASSERT(ASSOCIATED(cell_external))
     134          494 :          cell => cell_external
     135              :       END IF
     136              : 
     137        13972 :       IF (PRESENT(sab_orb_external)) THEN
     138        11160 :          CPASSERT(ASSOCIATED(sab_orb_external))
     139        11160 :          sab_orb => sab_orb_external
     140              :       END IF
     141        13972 :       CPASSERT(ASSOCIATED(sab_orb))
     142              : 
     143        13972 :       my_force_periodic = .FALSE.
     144        13972 :       IF (PRESENT(force_periodic)) my_force_periodic = force_periodic
     145        55888 :       perd0(:) = -1
     146        13972 :       IF (my_force_periodic) THEN
     147         1976 :          perd0(:) = cell%perd(:)
     148         1976 :          cell%perd(:) = 1
     149              :       END IF
     150              : 
     151        13972 :       nkind = SIZE(qs_kind_set)
     152        16784 :       CALL get_qs_kind_set(qs_kind_set=qs_kind_set, maxco=ldwork, basis_type=basis_type)
     153        97804 :       ALLOCATE (expab(ldwork, ldwork), work(ldwork, ldwork))
     154              : 
     155        86904 :       ALLOCATE (op_cossin(2, nkvec))
     156              : 
     157        69720 :       ALLOCATE (basis_set_list(nkind))
     158        41776 :       DO ikind = 1, nkind
     159        27804 :          qs_kind => qs_kind_set(ikind)
     160        27804 :          CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set_a, basis_type=basis_type)
     161        41776 :          IF (ASSOCIATED(basis_set_a)) THEN
     162        27804 :             basis_set_list(ikind)%gto_basis_set => basis_set_a
     163              :          ELSE
     164            0 :             NULLIFY (basis_set_list(ikind)%gto_basis_set)
     165              :          END IF
     166              :       END DO
     167              : 
     168        13972 :       last_jatom = 0
     169        13972 :       CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
     170       310101 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     171              :          CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, inode=inode, &
     172       296129 :                                 iatom=iatom, jatom=jatom, r=rab)
     173       296129 :          basis_set_a => basis_set_list(ikind)%gto_basis_set
     174       296129 :          IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
     175       296129 :          basis_set_b => basis_set_list(jkind)%gto_basis_set
     176       296129 :          IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
     177              : 
     178       296129 :          ra(:) = pbc(particle_set(iatom)%r(:), cell)
     179      1184516 :          rb(:) = ra(:) + rab(:)
     180              : 
     181       296129 :          first_sgfa => basis_set_a%first_sgf
     182       296129 :          la_max => basis_set_a%lmax
     183       296129 :          la_min => basis_set_a%lmin
     184       296129 :          npgfa => basis_set_a%npgf
     185       296129 :          nsgfa => basis_set_a%nsgf_set
     186       296129 :          rpgfa => basis_set_a%pgf_radius
     187       296129 :          set_radius_a => basis_set_a%set_radius
     188       296129 :          sphi_a => basis_set_a%sphi
     189       296129 :          zeta => basis_set_a%zet
     190              : 
     191       296129 :          first_sgfb => basis_set_b%first_sgf
     192       296129 :          lb_max => basis_set_b%lmax
     193       296129 :          lb_min => basis_set_b%lmin
     194       296129 :          npgfb => basis_set_b%npgf
     195       296129 :          nsgfb => basis_set_b%nsgf_set
     196       296129 :          rpgfb => basis_set_b%pgf_radius
     197       296129 :          set_radius_b => basis_set_b%set_radius
     198       296129 :          sphi_b => basis_set_b%sphi
     199       296129 :          zetb => basis_set_b%zet
     200              : 
     201       296129 :          nseta = basis_set_a%nset
     202       296129 :          nsetb = basis_set_b%nset
     203       296129 :          ldsa = SIZE(sphi_a, 1)
     204       296129 :          ldsb = SIZE(sphi_b, 1)
     205       296129 :          IF (inode == 1) last_jatom = 0
     206              : 
     207       296129 :          IF (jatom /= last_jatom) THEN
     208              :             new_atom_b = .TRUE.
     209              :             last_jatom = jatom
     210              :          ELSE
     211              :             new_atom_b = .FALSE.
     212              :          END IF
     213              : 
     214              :          IF (new_atom_b) THEN
     215        62032 :             IF (iatom <= jatom) THEN
     216        38092 :                irow = iatom
     217        38092 :                icol = jatom
     218              :             ELSE
     219        23940 :                irow = jatom
     220        23940 :                icol = iatom
     221              :             END IF
     222              : 
     223       162360 :             DO i = 1, nkvec
     224       300984 :                DO reim = 1, 2
     225       200656 :                   NULLIFY (op_cossin(reim, i)%block)
     226              :                   CALL dbcsr_get_block_p(matrix=op_sm_set(reim, i)%matrix, &
     227       300984 :                                          row=irow, col=icol, block=op_cossin(reim, i)%block, found=found)
     228              :                END DO
     229       162360 :                IF (ASSOCIATED(op_cossin(1, i)%block) .NEQV. ASSOCIATED(op_cossin(2, i)%block)) THEN
     230            0 :                   CPABORT("cosine and sine blocks should have the same topology")
     231              :                END IF
     232              :             END DO
     233              :          END IF
     234              : 
     235      1184516 :          dab = NORM2(rab)
     236      1106157 :          DO iset = 1, nseta
     237       796056 :             ncoa = npgfa(iset)*ncoset(la_max(iset))
     238       796056 :             sgfa = first_sgfa(1, iset)
     239      4146786 :             DO jset = 1, nsetb
     240      3054601 :                IF (set_radius_a(iset) + set_radius_b(jset) < dab) CYCLE
     241      1095147 :                ncob = npgfb(jset)*ncoset(lb_max(jset))
     242      1095147 :                sgfb = first_sgfb(1, jset)
     243              : 
     244      3297566 :                DO i = 1, nkvec
     245      1406363 :                   IF (.NOT. ASSOCIATED(op_cossin(1, i)%block)) CYCLE
     246              :                   CALL expikr(la_max(iset), npgfa(iset), zeta(:, iset), rpgfa(:, iset), &
     247              :                               la_min(iset), lb_max(jset), npgfb(jset), zetb(:, jset), &
     248      1406363 :                               rpgfb(:, jset), lb_min(jset), ra, rb, kvec(:, i), expab)
     249              :                   CALL contract_expikr(op_cossin(1, i)%block, op_cossin(2, i)%block, &
     250              :                                        iatom, ncoa, nsgfa(iset), sgfa, sphi_a, ldsa, &
     251              :                                        jatom, ncob, nsgfb(jset), sgfb, sphi_b, ldsb, &
     252      4460964 :                                        expab, work, ldwork)
     253              :                END DO
     254              :             END DO
     255              :          END DO
     256              :       END DO
     257        13972 :       CALL neighbor_list_iterator_release(nl_iterator)
     258              : 
     259        13972 :       DEALLOCATE (op_cossin, expab, work, basis_set_list)
     260              : 
     261        15454 :       IF (my_force_periodic) cell%perd(:) = perd0(:)
     262              : 
     263        13972 :       CALL timestop(handle)
     264        13972 :    END SUBROUTINE build_exp_ikr_matrix
     265              : 
     266              : ! **************************************************************************************************
     267              : !> \brief   Calculation of the linear momentum matrix <mu|∂|nu> over
     268              : !>          Cartesian Gaussian functions.
     269              : !> \param qs_env ...
     270              : !> \param matrix ...
     271              : !> \param minimum_image take into account only the first neighbors in the lists
     272              : !> \date    27.02.2009
     273              : !> \author  VW
     274              : !> \version 1.0
     275              : ! **************************************************************************************************
     276         1246 :    SUBROUTINE build_lin_mom_matrix(qs_env, matrix, minimum_image)
     277              : 
     278              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     279              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix
     280              :       LOGICAL, INTENT(IN), OPTIONAL                      :: minimum_image
     281              : 
     282              :       CHARACTER(len=*), PARAMETER :: routineN = 'build_lin_mom_matrix'
     283              : 
     284              :       INTEGER :: handle, i, iatom, icol, ikind, inode, irow, iset, jatom, jkind, jset, last_jatom, &
     285              :          ldai, maxco, maxlgto, maxsgf, ncoa, ncob, nkind, nseta, nsetb, sgfa, sgfb
     286         1246 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, lb_max, npgfa, npgfb, nsgfa, &
     287         1246 :                                                             nsgfb
     288         1246 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, first_sgfb
     289              :       LOGICAL                                            :: do_symmetric, found, my_minimum_image, &
     290              :                                                             new_atom_b
     291              :       REAL(KIND=dp)                                      :: alpha, dab, Lxo2, Lyo2, Lzo2
     292         1246 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), TARGET   :: rr_work
     293         1246 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: work
     294              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
     295              :          TARGET                                          :: intab
     296              :       REAL(KIND=dp), DIMENSION(3)                        :: rab
     297         1246 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: set_radius_a, set_radius_b
     298         1246 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: rpgfa, rpgfb, sphi_a, sphi_b, zeta, zetb
     299         1246 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:)      :: integral
     300              :       TYPE(cell_type), POINTER                           :: cell
     301         1246 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set_list
     302              :       TYPE(gto_basis_set_type), POINTER                  :: basis_set_a, basis_set_b
     303              :       TYPE(neighbor_list_iterator_p_type), &
     304         1246 :          DIMENSION(:), POINTER                           :: nl_iterator
     305              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     306         1246 :          POINTER                                         :: sab_nl
     307         1246 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     308              :       TYPE(qs_kind_type), POINTER                        :: qs_kind
     309              : 
     310         1246 :       CALL timeset(routineN, handle)
     311              : 
     312         1246 :       NULLIFY (cell, sab_nl, qs_kind_set)
     313              : 
     314              :       CALL get_qs_env(qs_env=qs_env, &
     315              :                       qs_kind_set=qs_kind_set, &
     316         1246 :                       cell=cell)
     317              : 
     318         1246 :       nkind = SIZE(qs_kind_set)
     319              : 
     320         1246 :       my_minimum_image = .FALSE.
     321         1246 :       IF (PRESENT(minimum_image)) THEN
     322           44 :          my_minimum_image = minimum_image
     323          176 :          Lxo2 = NORM2(cell%hmat(:, 1))/2.0_dp
     324          176 :          Lyo2 = NORM2(cell%hmat(:, 2))/2.0_dp
     325          176 :          Lzo2 = NORM2(cell%hmat(:, 3))/2.0_dp
     326              :       END IF
     327              : 
     328              :       ! Take into account the symmetry of the input matrix
     329         1246 :       do_symmetric = dbcsr_has_symmetry(matrix(1)%matrix)
     330         1246 :       IF (do_symmetric) THEN
     331         1244 :          CALL get_qs_env(qs_env=qs_env, sab_orb=sab_nl)
     332              :       ELSE
     333            2 :          CALL get_qs_env(qs_env=qs_env, sab_all=sab_nl)
     334              :       END IF
     335              : !   *** Allocate work storage ***
     336              : 
     337              :       CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
     338              :                            maxco=maxco, &
     339              :                            maxlgto=maxlgto, &
     340         1246 :                            maxsgf=maxsgf)
     341              : 
     342         1246 :       ldai = ncoset(maxlgto + 1)
     343         1246 :       CALL init_orbital_pointers(ldai)
     344              : 
     345        16198 :       ALLOCATE (rr_work(ldai*ldai*3), intab(maxco, maxco, 3), work(maxco, maxsgf), integral(3))
     346         1246 :       rr_work(:) = 0.0_dp
     347         1246 :       intab(:, :, :) = 0.0_dp
     348         1246 :       work(:, :) = 0.0_dp
     349              : 
     350         5892 :       ALLOCATE (basis_set_list(nkind))
     351         3400 :       DO ikind = 1, nkind
     352         2154 :          qs_kind => qs_kind_set(ikind)
     353         2154 :          CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set_a)
     354         3400 :          IF (ASSOCIATED(basis_set_a)) THEN
     355         2154 :             basis_set_list(ikind)%gto_basis_set => basis_set_a
     356              :          ELSE
     357            0 :             NULLIFY (basis_set_list(ikind)%gto_basis_set)
     358              :          END IF
     359              :       END DO
     360         1246 :       CALL neighbor_list_iterator_create(nl_iterator, sab_nl)
     361        72446 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     362              :          CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, inode=inode, &
     363        71200 :                                 iatom=iatom, jatom=jatom, r=rab)
     364        71200 :          basis_set_a => basis_set_list(ikind)%gto_basis_set
     365        71200 :          IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
     366        71200 :          basis_set_b => basis_set_list(jkind)%gto_basis_set
     367        71200 :          IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
     368              :          ! basis ikind
     369        71200 :          first_sgfa => basis_set_a%first_sgf
     370        71200 :          la_max => basis_set_a%lmax
     371        71200 :          npgfa => basis_set_a%npgf
     372        71200 :          nseta = basis_set_a%nset
     373        71200 :          nsgfa => basis_set_a%nsgf_set
     374        71200 :          rpgfa => basis_set_a%pgf_radius
     375        71200 :          set_radius_a => basis_set_a%set_radius
     376        71200 :          sphi_a => basis_set_a%sphi
     377        71200 :          zeta => basis_set_a%zet
     378              :          ! basis jkind
     379        71200 :          first_sgfb => basis_set_b%first_sgf
     380        71200 :          lb_max => basis_set_b%lmax
     381        71200 :          npgfb => basis_set_b%npgf
     382        71200 :          nsetb = basis_set_b%nset
     383        71200 :          nsgfb => basis_set_b%nsgf_set
     384        71200 :          rpgfb => basis_set_b%pgf_radius
     385        71200 :          set_radius_b => basis_set_b%set_radius
     386        71200 :          sphi_b => basis_set_b%sphi
     387        71200 :          zetb => basis_set_b%zet
     388              : 
     389        71200 :          IF (inode == 1) last_jatom = 0
     390              : 
     391        71200 :          IF (my_minimum_image) THEN
     392        26557 :             IF (ANY(ABS(rab(:)) > [Lxo2, Lyo2, Lzo2])) CYCLE
     393              :          END IF
     394              : 
     395        67736 :          IF (jatom /= last_jatom) THEN
     396              :             new_atom_b = .TRUE.
     397              :             last_jatom = jatom
     398              :          ELSE
     399              :             new_atom_b = .FALSE.
     400              :          END IF
     401              : 
     402              :          IF (new_atom_b) THEN
     403        13819 :             alpha = 1.0_dp
     404        13819 :             IF (do_symmetric) THEN
     405        13810 :                IF (iatom <= jatom) THEN
     406         7583 :                   irow = iatom
     407         7583 :                   icol = jatom
     408              :                ELSE
     409         6227 :                   irow = jatom
     410         6227 :                   icol = iatom
     411         6227 :                   IF (dbcsr_get_matrix_type(matrix(1)%matrix) == dbcsr_type_antisymmetric) THEN
     412        12454 :                      alpha = -1.0_dp
     413              :                   END IF
     414              :                END IF
     415              :             ELSE
     416            9 :                irow = iatom
     417            9 :                icol = jatom
     418              :             END IF
     419              : 
     420        55276 :             DO i = 1, 3
     421        41457 :                NULLIFY (integral(i)%block)
     422              :                CALL dbcsr_get_block_p(matrix=matrix(i)%matrix, &
     423        41457 :                                       row=irow, col=icol, BLOCK=integral(i)%block, found=found)
     424        55276 :                CPASSERT(ASSOCIATED(INTEGRAL(i)%block))
     425              :             END DO
     426              :          END IF
     427              : 
     428       270944 :          dab = NORM2(rab)
     429              : 
     430       213078 :          DO iset = 1, nseta
     431              : 
     432       144096 :             ncoa = npgfa(iset)*ncoset(la_max(iset))
     433       144096 :             sgfa = first_sgfa(1, iset)
     434              : 
     435       547953 :             DO jset = 1, nsetb
     436              : 
     437       336121 :                IF (set_radius_a(iset) + set_radius_b(jset) < dab) CYCLE
     438              : 
     439       144107 :                ncob = npgfb(jset)*ncoset(lb_max(jset))
     440       144107 :                sgfb = first_sgfb(1, jset)
     441              : 
     442              :                ! *** Calculate the primitive fermi contact integrals ***
     443              : 
     444              :                ! Keep the full primitive layout used by the contraction below.
     445              :                CALL overlap_ab(la_max(iset), 0, npgfa(iset), &
     446              :                                rpgfa(:, iset), zeta(:, iset), &
     447              :                                lb_max(jset), 0, npgfb(jset), &
     448              :                                rpgfb(:, jset), zetb(:, jset), &
     449       144107 :                                rab, dab=intab, rr_work=rr_work)
     450              : 
     451              :                ! *** Contraction step ***
     452              : 
     453       720524 :                DO i = 1, 3
     454              : 
     455              :                   CALL dgemm("N", "N", ncoa, nsgfb(jset), ncob, &
     456              :                              1.0_dp, intab(1, 1, i), SIZE(intab, 1), &
     457              :                              sphi_b(1, sgfb), SIZE(sphi_b, 1), &
     458       432321 :                              0.0_dp, work(1, 1), SIZE(work, 1))
     459              : 
     460       768442 :                   IF (do_symmetric) THEN
     461       432294 :                      IF (iatom <= jatom) THEN
     462              : 
     463              :                         CALL dgemm("T", "N", nsgfa(iset), nsgfb(jset), ncoa, &
     464              :                                    1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
     465              :                                    work(1, 1), SIZE(work, 1), &
     466              :                                    1.0_dp, integral(i)%block(sgfa, sgfb), &
     467       266226 :                                    SIZE(integral(i)%block, 1))
     468              : 
     469              :                      ELSE
     470              : 
     471              :                         CALL dgemm("T", "N", nsgfb(jset), nsgfa(iset), ncoa, &
     472              :                                    alpha, work(1, 1), SIZE(work, 1), &
     473              :                                    sphi_a(1, sgfa), SIZE(sphi_a, 1), &
     474              :                                    1.0_dp, integral(i)%block(sgfb, sgfa), &
     475       166068 :                                    SIZE(integral(i)%block, 1))
     476              : 
     477              :                      END IF
     478              :                   ELSE
     479              :                      CALL dgemm("T", "N", nsgfa(iset), nsgfb(jset), ncoa, &
     480              :                                 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
     481              :                                 work(1, 1), SIZE(work, 1), &
     482              :                                 1.0_dp, integral(i)%block(sgfa, sgfb), &
     483           27 :                                 SIZE(integral(i)%block, 1))
     484              :                   END IF
     485              : 
     486              :                END DO
     487              : 
     488              :             END DO
     489              : 
     490              :          END DO
     491              : 
     492              :       END DO
     493         1246 :       CALL neighbor_list_iterator_release(nl_iterator)
     494              : 
     495              :       ! *** Release work storage ***
     496              : 
     497         1246 :       DEALLOCATE (intab, rr_work, work, integral, basis_set_list)
     498              : 
     499         1246 :       CALL timestop(handle)
     500              : 
     501         3738 :    END SUBROUTINE build_lin_mom_matrix
     502              : 
     503              : ! **************************************************************************************************
     504              : !> \brief   Calculation of the angular momentum matrix over
     505              : !>          Cartesian Gaussian functions.
     506              : !> \param qs_env ...
     507              : !> \param matrix ...
     508              : !> \param rc ...
     509              : !> \date    27.02.2009
     510              : !> \author  VW
     511              : !> \version 1.0
     512              : ! **************************************************************************************************
     513              : 
     514         1194 :    SUBROUTINE build_ang_mom_matrix(qs_env, matrix, rc)
     515              : 
     516              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     517              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix
     518              :       REAL(dp), DIMENSION(:), INTENT(IN)                 :: rc
     519              : 
     520              :       CHARACTER(len=*), PARAMETER :: routineN = 'build_ang_mom_matrix'
     521              : 
     522              :       INTEGER :: handle, i, iatom, icol, ikind, inode, irow, iset, jatom, jkind, jset, last_jatom, &
     523              :          maxco, maxsgf, ncoa, ncob, nkind, nseta, nsetb, sgfa, sgfb
     524         1194 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, lb_max, lb_min, npgfa, &
     525         1194 :                                                             npgfb, nsgfa, nsgfb
     526         1194 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, first_sgfb
     527              :       LOGICAL                                            :: found, new_atom_b
     528              :       REAL(KIND=dp)                                      :: dab
     529         1194 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: work
     530              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: intab
     531              :       REAL(KIND=dp), DIMENSION(3)                        :: ra, rab, rac, rbc
     532         1194 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: set_radius_a, set_radius_b
     533         1194 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: rpgfa, rpgfb, sphi_a, sphi_b, zeta, zetb
     534         1194 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:)      :: integral
     535              :       TYPE(cell_type), POINTER                           :: cell
     536         1194 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set_list
     537              :       TYPE(gto_basis_set_type), POINTER                  :: basis_set_a, basis_set_b
     538              :       TYPE(neighbor_list_iterator_p_type), &
     539         1194 :          DIMENSION(:), POINTER                           :: nl_iterator
     540              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     541         1194 :          POINTER                                         :: sab_all
     542         1194 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     543         1194 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     544              :       TYPE(qs_kind_type), POINTER                        :: qs_kind
     545              : 
     546         1194 :       CALL timeset(routineN, handle)
     547              : 
     548              :       CALL get_qs_env(qs_env=qs_env, &
     549              :                       qs_kind_set=qs_kind_set, &
     550              :                       particle_set=particle_set, &
     551              :                       sab_all=sab_all, &
     552         1194 :                       cell=cell)
     553              : 
     554         1194 :       nkind = SIZE(qs_kind_set)
     555              : 
     556              : !   *** Allocate work storage ***
     557              : 
     558              :       CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
     559              :                            maxco=maxco, &
     560         1194 :                            maxsgf=maxsgf)
     561              : 
     562        13134 :       ALLOCATE (intab(maxco, maxco, 3), work(maxco, maxsgf), integral(3))
     563         1194 :       intab(:, :, :) = 0.0_dp
     564         1194 :       work(:, :) = 0.0_dp
     565              : 
     566         5540 :       ALLOCATE (basis_set_list(nkind))
     567         3152 :       DO ikind = 1, nkind
     568         1958 :          qs_kind => qs_kind_set(ikind)
     569         1958 :          CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set_a)
     570         3152 :          IF (ASSOCIATED(basis_set_a)) THEN
     571         1958 :             basis_set_list(ikind)%gto_basis_set => basis_set_a
     572              :          ELSE
     573            0 :             NULLIFY (basis_set_list(ikind)%gto_basis_set)
     574              :          END IF
     575              :       END DO
     576         1194 :       CALL neighbor_list_iterator_create(nl_iterator, sab_all)
     577        90709 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     578              :          CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, inode=inode, &
     579        89515 :                                 iatom=iatom, jatom=jatom, r=rab)
     580        89515 :          basis_set_a => basis_set_list(ikind)%gto_basis_set
     581        89515 :          IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
     582        89515 :          basis_set_b => basis_set_list(jkind)%gto_basis_set
     583        89515 :          IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
     584        89515 :          ra = pbc(particle_set(iatom)%r, cell)
     585              :          ! basis ikind
     586        89515 :          first_sgfa => basis_set_a%first_sgf
     587        89515 :          la_max => basis_set_a%lmax
     588        89515 :          la_min => basis_set_a%lmin
     589        89515 :          npgfa => basis_set_a%npgf
     590        89515 :          nseta = basis_set_a%nset
     591        89515 :          nsgfa => basis_set_a%nsgf_set
     592        89515 :          rpgfa => basis_set_a%pgf_radius
     593        89515 :          set_radius_a => basis_set_a%set_radius
     594        89515 :          sphi_a => basis_set_a%sphi
     595        89515 :          zeta => basis_set_a%zet
     596              :          ! basis jkind
     597        89515 :          first_sgfb => basis_set_b%first_sgf
     598        89515 :          lb_max => basis_set_b%lmax
     599        89515 :          lb_min => basis_set_b%lmin
     600        89515 :          npgfb => basis_set_b%npgf
     601        89515 :          nsetb = basis_set_b%nset
     602        89515 :          nsgfb => basis_set_b%nsgf_set
     603        89515 :          rpgfb => basis_set_b%pgf_radius
     604        89515 :          set_radius_b => basis_set_b%set_radius
     605        89515 :          sphi_b => basis_set_b%sphi
     606        89515 :          zetb => basis_set_b%zet
     607              : 
     608        89515 :          IF (inode == 1) last_jatom = 0
     609              : 
     610        89515 :          IF (jatom /= last_jatom) THEN
     611              :             new_atom_b = .TRUE.
     612              :             last_jatom = jatom
     613              :          ELSE
     614              :             new_atom_b = .FALSE.
     615              :          END IF
     616              : 
     617              :          IF (new_atom_b) THEN
     618              :             !IF (iatom <= jatom) THEN
     619         5795 :             irow = iatom
     620         5795 :             icol = jatom
     621              :             !ELSE
     622              :             !   irow = jatom
     623              :             !   icol = iatom
     624              :             !END IF
     625              : 
     626        23180 :             DO i = 1, 3
     627        17385 :                NULLIFY (INTEGRAL(i)%block)
     628              :                CALL dbcsr_get_block_p(matrix=matrix(i)%matrix, &
     629        17385 :                                       row=irow, col=icol, BLOCK=INTEGRAL(i)%block, found=found)
     630        23180 :                CPASSERT(found .AND. ASSOCIATED(INTEGRAL(i)%block))
     631              :             END DO
     632              :          END IF
     633              : 
     634       358060 :          dab = NORM2(rab)
     635              : 
     636       299354 :          DO iset = 1, nseta
     637              : 
     638       208645 :             ncoa = npgfa(iset)*ncoset(la_max(iset))
     639       208645 :             sgfa = first_sgfa(1, iset)
     640              : 
     641       807795 :             DO jset = 1, nsetb
     642              : 
     643       509635 :                IF (set_radius_a(iset) + set_radius_b(jset) < dab) CYCLE
     644              : 
     645              :                !IF(PRESENT(wancen)) THEN
     646              :                !   rc = wancen
     647       193525 :                rac = pbc(rc, ra, cell)
     648       774100 :                rbc = rac + rab
     649              :                !ELSE
     650              :                !   rc(1:3) = rb(1:3)
     651              :                !   rac(1:3) = -rab(1:3)
     652              :                !   rbc(1:3) = 0.0_dp
     653              :                !ENDIF
     654              : 
     655       193525 :                ncob = npgfb(jset)*ncoset(lb_max(jset))
     656       193525 :                sgfb = first_sgfb(1, jset)
     657              : 
     658              :                ! *** Calculate the primitive angular momentum integrals ***
     659              : 
     660              :                CALL angmom(la_max(iset), npgfa(iset), zeta(:, iset), rpgfa(:, iset), la_min(iset), &
     661       193525 :                            lb_max(jset), npgfb(jset), zetb(:, jset), rpgfb(:, jset), rac, rbc, intab)
     662              : 
     663              :                ! *** Contraction step ***
     664              : 
     665       982745 :                DO i = 1, 3
     666              : 
     667              :                   CALL dgemm("N", "N", ncoa, nsgfb(jset), ncob, &
     668              :                              1.0_dp, intab(1, 1, i), SIZE(intab, 1), &
     669              :                              sphi_b(1, sgfb), SIZE(sphi_b, 1), &
     670       580575 :                              0.0_dp, work(1, 1), SIZE(work, 1))
     671              : 
     672              :                   !IF (iatom <= jatom) THEN
     673              : 
     674              :                   CALL dgemm("T", "N", nsgfa(iset), nsgfb(jset), ncoa, &
     675              :                              1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
     676              :                              work(1, 1), SIZE(work, 1), &
     677              :                              1.0_dp, integral(i)%block(sgfa, sgfb), &
     678      1090210 :                              SIZE(integral(i)%block, 1))
     679              : 
     680              :                   !ELSE
     681              :                   !
     682              :                   !   CALL dgemm("T","N",nsgfb(jset),nsgfa(iset),ncoa,&
     683              :                   !              -1.0_dp,work(1,1),SIZE(work,1),&
     684              :                   !              sphi_a(1,sgfa),SIZE(sphi_a,1),&
     685              :                   !              1.0_dp,integral(i)%block(sgfb,sgfa),&
     686              :                   !              SIZE(integral(i)%block,1))
     687              :                   !
     688              :                   !ENDIF
     689              : 
     690              :                END DO
     691              : 
     692              :             END DO
     693              : 
     694              :          END DO
     695              : 
     696              :       END DO
     697         1194 :       CALL neighbor_list_iterator_release(nl_iterator)
     698              : 
     699              :       ! *** Release work storage ***
     700              : 
     701         1194 :       DEALLOCATE (intab, work, integral, basis_set_list)
     702              : 
     703              : !   *** Print the spin orbit matrix, if requested ***
     704              : 
     705              :       !IF (BTEST(cp_print_key_should_output(logger%iter_info,&
     706              :       !     qs_env%input,"DFT%PRINT%AO_MATRICES/ANGULAR_MOMENTUM"),cp_p_file)) THEN
     707              :       !   iw = cp_print_key_unit_nr(logger,qs_env%input,"DFT%PRINT%AO_MATRICES/ANGULAR_MOMENTUM",&
     708              :       !        extension=".Log")
     709              :       !   CALL cp_dbcsr_write_sparse_matrix(matrix(1)%matrix,4,6,qs_env,para_env,output_unit=iw)
     710              :       !   CALL cp_dbcsr_write_sparse_matrix(matrix(2)%matrix,4,6,qs_env,para_env,output_unit=iw)
     711              :       !   CALL cp_dbcsr_write_sparse_matrix(matrix(3)%matrix,4,6,qs_env,para_env,output_unit=iw)
     712              :       !   CALL cp_print_key_finished_output(iw,logger,qs_env%input,&
     713              :       !        "DFT%PRINT%AO_MATRICES/ANGULAR_MOMENTUM")
     714              :       !END IF
     715              : 
     716         1194 :       CALL timestop(handle)
     717              : 
     718         2388 :    END SUBROUTINE build_ang_mom_matrix
     719              : 
     720              : ! **************************************************************************************************
     721              : END MODULE qs_operators_ao
        

Generated by: LCOV version 2.0-1