LCOV - code coverage report
Current view: top level - src - qs_operators_ao.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:5c1df3d) Lines: 98.7 % 300 296
Test Date: 2026-09-14 06:34:43 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_cossin,&
      16              :                                               cossin
      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        13960 :    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              :       INTEGER :: handle, i, iatom, icol, ikind, inode, irow, iset, jatom, jkind, jset, last_jatom, &
      87              :          ldsa, ldsb, ldwork, ncoa, ncob, nkind, nkvec, nseta, nsetb, reim, sgfa, sgfb
      88              :       INTEGER, DIMENSION(3)                              :: perd0
      89        13960 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, lb_max, lb_min, npgfa, &
      90        13960 :                                                             npgfb, nsgfa, nsgfb
      91        13960 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, first_sgfb
      92              :       LOGICAL                                            :: found, my_force_periodic, new_atom_b
      93              :       REAL(KIND=dp)                                      :: dab
      94              :       REAL(KIND=dp), DIMENSION(3)                        :: ra, rab, rb
      95        13960 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: set_radius_a, set_radius_b
      96        13960 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: cosab, rpgfa, rpgfb, sinab, sphi_a, &
      97        13960 :                                                             sphi_b, work, zeta, zetb
      98        13960 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:, :)   :: op_cossin
      99              :       TYPE(cell_type), POINTER                           :: cell
     100        13960 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set_list
     101              :       TYPE(gto_basis_set_type), POINTER                  :: basis_set_a, basis_set_b
     102              :       TYPE(neighbor_list_iterator_p_type), &
     103        13960 :          DIMENSION(:), POINTER                           :: nl_iterator
     104              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     105        13960 :          POINTER                                         :: sab_orb
     106        13960 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     107        13960 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     108              :       TYPE(qs_kind_type), POINTER                        :: qs_kind
     109              : 
     110        13960 :       CALL timeset(routineN, handle)
     111              : 
     112        13960 :       CPASSERT(SIZE(kvec, 1) == 3)
     113        13960 :       nkvec = SIZE(kvec, 2)
     114        13960 :       CPASSERT(nkvec > 0)
     115        13960 :       CPASSERT(SIZE(op_sm_set, 1) == 2)
     116        13960 :       CPASSERT(SIZE(op_sm_set, 2) == nkvec)
     117        28964 :       DO i = 1, nkvec
     118        58972 :          DO reim = 1, 2
     119        30008 :             CPASSERT(ASSOCIATED(op_sm_set(reim, i)%matrix))
     120        30008 :             CPASSERT(dbcsr_has_symmetry(op_sm_set(reim, i)%matrix))
     121        45012 :             CALL dbcsr_set(op_sm_set(reim, i)%matrix, 0.0_dp)
     122              :          END DO
     123              :       END DO
     124              : 
     125        13960 :       NULLIFY (qs_kind, qs_kind_set, particle_set, sab_orb, cell)
     126              :       CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, &
     127        13960 :                       particle_set=particle_set, cell=cell, sab_orb=sab_orb)
     128        13960 :       CPASSERT(ASSOCIATED(cell))
     129        13960 :       CPASSERT(ASSOCIATED(qs_kind_set))
     130        13960 :       CPASSERT(ASSOCIATED(particle_set))
     131        13960 :       IF (PRESENT(cell_external)) THEN
     132          504 :          CPASSERT(ASSOCIATED(cell_external))
     133          504 :          cell => cell_external
     134              :       END IF
     135              : 
     136        13960 :       IF (PRESENT(sab_orb_external)) THEN
     137        11160 :          CPASSERT(ASSOCIATED(sab_orb_external))
     138        11160 :          sab_orb => sab_orb_external
     139              :       END IF
     140        13960 :       CPASSERT(ASSOCIATED(sab_orb))
     141              : 
     142        13960 :       my_force_periodic = .FALSE.
     143        13960 :       IF (PRESENT(force_periodic)) my_force_periodic = force_periodic
     144          504 :       IF (my_force_periodic) THEN
     145         2016 :          perd0(:) = cell%perd(:)
     146         2016 :          cell%perd(:) = 1
     147              :       END IF
     148              : 
     149        13960 :       nkind = SIZE(qs_kind_set)
     150        16760 :       CALL get_qs_kind_set(qs_kind_set=qs_kind_set, maxco=ldwork, basis_type=basis_type)
     151       111680 :       ALLOCATE (cosab(ldwork, ldwork), sinab(ldwork, ldwork), work(ldwork, ldwork))
     152              : 
     153        86892 :       ALLOCATE (op_cossin(2, nkvec))
     154              : 
     155        69662 :       ALLOCATE (basis_set_list(nkind))
     156        41742 :       DO ikind = 1, nkind
     157        27782 :          qs_kind => qs_kind_set(ikind)
     158        27782 :          CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set_a, basis_type=basis_type)
     159        41742 :          IF (ASSOCIATED(basis_set_a)) THEN
     160        27782 :             basis_set_list(ikind)%gto_basis_set => basis_set_a
     161              :          ELSE
     162            0 :             NULLIFY (basis_set_list(ikind)%gto_basis_set)
     163              :          END IF
     164              :       END DO
     165              : 
     166        13960 :       last_jatom = 0
     167        13960 :       CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
     168       309559 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     169              :          CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, inode=inode, &
     170       295599 :                                 iatom=iatom, jatom=jatom, r=rab)
     171       295599 :          basis_set_a => basis_set_list(ikind)%gto_basis_set
     172       295599 :          IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
     173       295599 :          basis_set_b => basis_set_list(jkind)%gto_basis_set
     174       295599 :          IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
     175              : 
     176       295599 :          ra(:) = pbc(particle_set(iatom)%r(:), cell)
     177      1182396 :          rb(:) = ra(:) + rab(:)
     178              : 
     179       295599 :          first_sgfa => basis_set_a%first_sgf
     180       295599 :          la_max => basis_set_a%lmax
     181       295599 :          la_min => basis_set_a%lmin
     182       295599 :          npgfa => basis_set_a%npgf
     183       295599 :          nsgfa => basis_set_a%nsgf_set
     184       295599 :          rpgfa => basis_set_a%pgf_radius
     185       295599 :          set_radius_a => basis_set_a%set_radius
     186       295599 :          sphi_a => basis_set_a%sphi
     187       295599 :          zeta => basis_set_a%zet
     188              : 
     189       295599 :          first_sgfb => basis_set_b%first_sgf
     190       295599 :          lb_max => basis_set_b%lmax
     191       295599 :          lb_min => basis_set_b%lmin
     192       295599 :          npgfb => basis_set_b%npgf
     193       295599 :          nsgfb => basis_set_b%nsgf_set
     194       295599 :          rpgfb => basis_set_b%pgf_radius
     195       295599 :          set_radius_b => basis_set_b%set_radius
     196       295599 :          sphi_b => basis_set_b%sphi
     197       295599 :          zetb => basis_set_b%zet
     198              : 
     199       295599 :          nseta = basis_set_a%nset
     200       295599 :          nsetb = basis_set_b%nset
     201       295599 :          ldsa = SIZE(sphi_a, 1)
     202       295599 :          ldsb = SIZE(sphi_b, 1)
     203       295599 :          IF (inode == 1) last_jatom = 0
     204              : 
     205       295599 :          IF (jatom /= last_jatom) THEN
     206              :             new_atom_b = .TRUE.
     207              :             last_jatom = jatom
     208              :          ELSE
     209              :             new_atom_b = .FALSE.
     210              :          END IF
     211              : 
     212              :          IF (new_atom_b) THEN
     213        62003 :             IF (iatom <= jatom) THEN
     214        38072 :                irow = iatom
     215        38072 :                icol = jatom
     216              :             ELSE
     217        23931 :                irow = jatom
     218        23931 :                icol = iatom
     219              :             END IF
     220              : 
     221       162356 :             DO i = 1, nkvec
     222       301059 :                DO reim = 1, 2
     223       200706 :                   NULLIFY (op_cossin(reim, i)%block)
     224              :                   CALL dbcsr_get_block_p(matrix=op_sm_set(reim, i)%matrix, &
     225       301059 :                                          row=irow, col=icol, block=op_cossin(reim, i)%block, found=found)
     226              :                END DO
     227       162356 :                IF (ASSOCIATED(op_cossin(1, i)%block) .NEQV. ASSOCIATED(op_cossin(2, i)%block)) THEN
     228            0 :                   CPABORT("cosine and sine blocks should have the same topology")
     229              :                END IF
     230              :             END DO
     231              :          END IF
     232              : 
     233      1182396 :          dab = NORM2(rab)
     234      1104555 :          DO iset = 1, nseta
     235       794996 :             ncoa = npgfa(iset)*ncoset(la_max(iset))
     236       794996 :             sgfa = first_sgfa(1, iset)
     237      4143076 :             DO jset = 1, nsetb
     238      3052481 :                IF (set_radius_a(iset) + set_radius_b(jset) < dab) CYCLE
     239      1094156 :                ncob = npgfb(jset)*ncoset(lb_max(jset))
     240      1094156 :                sgfb = first_sgfb(1, jset)
     241              : 
     242      3296636 :                DO i = 1, nkvec
     243      1407484 :                   IF (.NOT. ASSOCIATED(op_cossin(1, i)%block)) CYCLE
     244              :                   CALL cossin(la_max(iset), npgfa(iset), zeta(:, iset), rpgfa(:, iset), &
     245              :                               la_min(iset), lb_max(jset), npgfb(jset), zetb(:, jset), &
     246      1407484 :                               rpgfb(:, jset), lb_min(jset), ra, rb, kvec(:, i), cosab, sinab)
     247              :                   CALL contract_cossin(op_cossin(1, i)%block, op_cossin(2, i)%block, &
     248              :                                        iatom, ncoa, nsgfa(iset), sgfa, sphi_a, ldsa, &
     249              :                                        jatom, ncob, nsgfb(jset), sgfb, sphi_b, ldsb, &
     250      4459965 :                                        cosab, sinab, ldwork, work, ldwork)
     251              :                END DO
     252              :             END DO
     253              :          END DO
     254              :       END DO
     255        13960 :       CALL neighbor_list_iterator_release(nl_iterator)
     256              : 
     257        13960 :       DEALLOCATE (op_cossin, cosab, sinab, work, basis_set_list)
     258              : 
     259        15472 :       IF (my_force_periodic) cell%perd(:) = perd0(:)
     260              : 
     261        13960 :       CALL timestop(handle)
     262        13960 :    END SUBROUTINE build_exp_ikr_matrix
     263              : 
     264              : ! **************************************************************************************************
     265              : !> \brief   Calculation of the linear momentum matrix <mu|∂|nu> over
     266              : !>          Cartesian Gaussian functions.
     267              : !> \param qs_env ...
     268              : !> \param matrix ...
     269              : !> \param minimum_image take into account only the first neighbors in the lists
     270              : !> \date    27.02.2009
     271              : !> \author  VW
     272              : !> \version 1.0
     273              : ! **************************************************************************************************
     274         1296 :    SUBROUTINE build_lin_mom_matrix(qs_env, matrix, minimum_image)
     275              : 
     276              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     277              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix
     278              :       LOGICAL, INTENT(IN), OPTIONAL                      :: minimum_image
     279              : 
     280              :       CHARACTER(len=*), PARAMETER :: routineN = 'build_lin_mom_matrix'
     281              : 
     282              :       INTEGER :: handle, i, iatom, icol, ikind, inode, irow, iset, jatom, jkind, jset, last_jatom, &
     283              :          ldai, maxco, maxlgto, maxsgf, ncoa, ncob, nkind, nseta, nsetb, sgfa, sgfb
     284         1296 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, lb_max, npgfa, npgfb, nsgfa, &
     285         1296 :                                                             nsgfb
     286         1296 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, first_sgfb
     287              :       LOGICAL                                            :: do_symmetric, found, my_minimum_image, &
     288              :                                                             new_atom_b
     289              :       REAL(KIND=dp)                                      :: alpha, dab, Lxo2, Lyo2, Lzo2
     290         1296 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), TARGET   :: rr_work
     291         1296 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: work
     292              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
     293              :          TARGET                                          :: intab
     294              :       REAL(KIND=dp), DIMENSION(3)                        :: rab
     295         1296 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: set_radius_a, set_radius_b
     296         1296 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: rpgfa, rpgfb, sphi_a, sphi_b, zeta, zetb
     297         1296 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:)      :: integral
     298              :       TYPE(cell_type), POINTER                           :: cell
     299         1296 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set_list
     300              :       TYPE(gto_basis_set_type), POINTER                  :: basis_set_a, basis_set_b
     301              :       TYPE(neighbor_list_iterator_p_type), &
     302         1296 :          DIMENSION(:), POINTER                           :: nl_iterator
     303              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     304         1296 :          POINTER                                         :: sab_nl
     305         1296 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     306              :       TYPE(qs_kind_type), POINTER                        :: qs_kind
     307              : 
     308         1296 :       CALL timeset(routineN, handle)
     309              : 
     310         1296 :       NULLIFY (cell, sab_nl, qs_kind_set)
     311              : 
     312              :       CALL get_qs_env(qs_env=qs_env, &
     313              :                       qs_kind_set=qs_kind_set, &
     314         1296 :                       cell=cell)
     315              : 
     316         1296 :       nkind = SIZE(qs_kind_set)
     317              : 
     318         1296 :       my_minimum_image = .FALSE.
     319         1296 :       IF (PRESENT(minimum_image)) THEN
     320           44 :          my_minimum_image = minimum_image
     321          176 :          Lxo2 = NORM2(cell%hmat(:, 1))/2.0_dp
     322          176 :          Lyo2 = NORM2(cell%hmat(:, 2))/2.0_dp
     323          176 :          Lzo2 = NORM2(cell%hmat(:, 3))/2.0_dp
     324              :       END IF
     325              : 
     326              :       ! Take into account the symmetry of the input matrix
     327         1296 :       do_symmetric = dbcsr_has_symmetry(matrix(1)%matrix)
     328         1296 :       IF (do_symmetric) THEN
     329         1294 :          CALL get_qs_env(qs_env=qs_env, sab_orb=sab_nl)
     330              :       ELSE
     331            2 :          CALL get_qs_env(qs_env=qs_env, sab_all=sab_nl)
     332              :       END IF
     333              : !   *** Allocate work storage ***
     334              : 
     335              :       CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
     336              :                            maxco=maxco, &
     337              :                            maxlgto=maxlgto, &
     338         1296 :                            maxsgf=maxsgf)
     339              : 
     340         1296 :       ldai = ncoset(maxlgto + 1)
     341         1296 :       CALL init_orbital_pointers(ldai)
     342              : 
     343        16848 :       ALLOCATE (rr_work(ldai*ldai*3), intab(maxco, maxco, 3), work(maxco, maxsgf), integral(3))
     344         1296 :       rr_work(:) = 0.0_dp
     345         1296 :       intab(:, :, :) = 0.0_dp
     346         1296 :       work(:, :) = 0.0_dp
     347              : 
     348         6132 :       ALLOCATE (basis_set_list(nkind))
     349         3540 :       DO ikind = 1, nkind
     350         2244 :          qs_kind => qs_kind_set(ikind)
     351         2244 :          CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set_a)
     352         3540 :          IF (ASSOCIATED(basis_set_a)) THEN
     353         2244 :             basis_set_list(ikind)%gto_basis_set => basis_set_a
     354              :          ELSE
     355            0 :             NULLIFY (basis_set_list(ikind)%gto_basis_set)
     356              :          END IF
     357              :       END DO
     358         1296 :       CALL neighbor_list_iterator_create(nl_iterator, sab_nl)
     359        75246 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     360              :          CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, inode=inode, &
     361        73950 :                                 iatom=iatom, jatom=jatom, r=rab)
     362        73950 :          basis_set_a => basis_set_list(ikind)%gto_basis_set
     363        73950 :          IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
     364        73950 :          basis_set_b => basis_set_list(jkind)%gto_basis_set
     365        73950 :          IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
     366              :          ! basis ikind
     367        73950 :          first_sgfa => basis_set_a%first_sgf
     368        73950 :          la_max => basis_set_a%lmax
     369        73950 :          npgfa => basis_set_a%npgf
     370        73950 :          nseta = basis_set_a%nset
     371        73950 :          nsgfa => basis_set_a%nsgf_set
     372        73950 :          rpgfa => basis_set_a%pgf_radius
     373        73950 :          set_radius_a => basis_set_a%set_radius
     374        73950 :          sphi_a => basis_set_a%sphi
     375        73950 :          zeta => basis_set_a%zet
     376              :          ! basis jkind
     377        73950 :          first_sgfb => basis_set_b%first_sgf
     378        73950 :          lb_max => basis_set_b%lmax
     379        73950 :          npgfb => basis_set_b%npgf
     380        73950 :          nsetb = basis_set_b%nset
     381        73950 :          nsgfb => basis_set_b%nsgf_set
     382        73950 :          rpgfb => basis_set_b%pgf_radius
     383        73950 :          set_radius_b => basis_set_b%set_radius
     384        73950 :          sphi_b => basis_set_b%sphi
     385        73950 :          zetb => basis_set_b%zet
     386              : 
     387        73950 :          IF (inode == 1) last_jatom = 0
     388              : 
     389        73950 :          IF (my_minimum_image) THEN
     390        26557 :             IF (ANY(ABS(rab(:)) > [Lxo2, Lyo2, Lzo2])) CYCLE
     391              :          END IF
     392              : 
     393        70486 :          IF (jatom /= last_jatom) THEN
     394              :             new_atom_b = .TRUE.
     395              :             last_jatom = jatom
     396              :          ELSE
     397              :             new_atom_b = .FALSE.
     398              :          END IF
     399              : 
     400              :          IF (new_atom_b) THEN
     401        13954 :             alpha = 1.0_dp
     402        13954 :             IF (do_symmetric) THEN
     403        13945 :                IF (iatom <= jatom) THEN
     404         7673 :                   irow = iatom
     405         7673 :                   icol = jatom
     406              :                ELSE
     407         6272 :                   irow = jatom
     408         6272 :                   icol = iatom
     409         6272 :                   IF (dbcsr_get_matrix_type(matrix(1)%matrix) == dbcsr_type_antisymmetric) THEN
     410        12544 :                      alpha = -1.0_dp
     411              :                   END IF
     412              :                END IF
     413              :             ELSE
     414            9 :                irow = iatom
     415            9 :                icol = jatom
     416              :             END IF
     417              : 
     418        55816 :             DO i = 1, 3
     419        41862 :                NULLIFY (integral(i)%block)
     420              :                CALL dbcsr_get_block_p(matrix=matrix(i)%matrix, &
     421        41862 :                                       row=irow, col=icol, BLOCK=integral(i)%block, found=found)
     422        55816 :                CPASSERT(ASSOCIATED(INTEGRAL(i)%block))
     423              :             END DO
     424              :          END IF
     425              : 
     426       281944 :          dab = NORM2(rab)
     427              : 
     428       221378 :          DO iset = 1, nseta
     429              : 
     430       149596 :             ncoa = npgfa(iset)*ncoset(la_max(iset))
     431       149596 :             sgfa = first_sgfa(1, iset)
     432              : 
     433       567203 :             DO jset = 1, nsetb
     434              : 
     435       347121 :                IF (set_radius_a(iset) + set_radius_b(jset) < dab) CYCLE
     436              : 
     437       149387 :                ncob = npgfb(jset)*ncoset(lb_max(jset))
     438       149387 :                sgfb = first_sgfb(1, jset)
     439              : 
     440              :                ! *** Calculate the primitive fermi contact integrals ***
     441              : 
     442              :                ! Keep the full primitive layout used by the contraction below.
     443              :                CALL overlap_ab(la_max(iset), 0, npgfa(iset), &
     444              :                                rpgfa(:, iset), zeta(:, iset), &
     445              :                                lb_max(jset), 0, npgfb(jset), &
     446              :                                rpgfb(:, jset), zetb(:, jset), &
     447       149387 :                                rab, dab=intab, rr_work=rr_work)
     448              : 
     449              :                ! *** Contraction step ***
     450              : 
     451       747144 :                DO i = 1, 3
     452              : 
     453              :                   CALL dgemm("N", "N", ncoa, nsgfb(jset), ncob, &
     454              :                              1.0_dp, intab(1, 1, i), SIZE(intab, 1), &
     455              :                              sphi_b(1, sgfb), SIZE(sphi_b, 1), &
     456       448161 :                              0.0_dp, work(1, 1), SIZE(work, 1))
     457              : 
     458       795282 :                   IF (do_symmetric) THEN
     459       448134 :                      IF (iatom <= jatom) THEN
     460              : 
     461              :                         CALL dgemm("T", "N", nsgfa(iset), nsgfb(jset), ncoa, &
     462              :                                    1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
     463              :                                    work(1, 1), SIZE(work, 1), &
     464              :                                    1.0_dp, integral(i)%block(sgfa, sgfb), &
     465       276486 :                                    SIZE(integral(i)%block, 1))
     466              : 
     467              :                      ELSE
     468              : 
     469              :                         CALL dgemm("T", "N", nsgfb(jset), nsgfa(iset), ncoa, &
     470              :                                    alpha, work(1, 1), SIZE(work, 1), &
     471              :                                    sphi_a(1, sgfa), SIZE(sphi_a, 1), &
     472              :                                    1.0_dp, integral(i)%block(sgfb, sgfa), &
     473       171648 :                                    SIZE(integral(i)%block, 1))
     474              : 
     475              :                      END IF
     476              :                   ELSE
     477              :                      CALL dgemm("T", "N", nsgfa(iset), nsgfb(jset), ncoa, &
     478              :                                 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
     479              :                                 work(1, 1), SIZE(work, 1), &
     480              :                                 1.0_dp, integral(i)%block(sgfa, sgfb), &
     481           27 :                                 SIZE(integral(i)%block, 1))
     482              :                   END IF
     483              : 
     484              :                END DO
     485              : 
     486              :             END DO
     487              : 
     488              :          END DO
     489              : 
     490              :       END DO
     491         1296 :       CALL neighbor_list_iterator_release(nl_iterator)
     492              : 
     493              :       ! *** Release work storage ***
     494              : 
     495         1296 :       DEALLOCATE (intab, rr_work, work, integral, basis_set_list)
     496              : 
     497         1296 :       CALL timestop(handle)
     498              : 
     499         3888 :    END SUBROUTINE build_lin_mom_matrix
     500              : 
     501              : ! **************************************************************************************************
     502              : !> \brief   Calculation of the angular momentum matrix over
     503              : !>          Cartesian Gaussian functions.
     504              : !> \param qs_env ...
     505              : !> \param matrix ...
     506              : !> \param rc ...
     507              : !> \date    27.02.2009
     508              : !> \author  VW
     509              : !> \version 1.0
     510              : ! **************************************************************************************************
     511              : 
     512         1250 :    SUBROUTINE build_ang_mom_matrix(qs_env, matrix, rc)
     513              : 
     514              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     515              :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix
     516              :       REAL(dp), DIMENSION(:), INTENT(IN)                 :: rc
     517              : 
     518              :       CHARACTER(len=*), PARAMETER :: routineN = 'build_ang_mom_matrix'
     519              : 
     520              :       INTEGER :: handle, i, iatom, icol, ikind, inode, irow, iset, jatom, jkind, jset, last_jatom, &
     521              :          maxco, maxsgf, ncoa, ncob, nkind, nseta, nsetb, sgfa, sgfb
     522         1250 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, lb_max, lb_min, npgfa, &
     523         1250 :                                                             npgfb, nsgfa, nsgfb
     524         1250 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, first_sgfb
     525              :       LOGICAL                                            :: found, new_atom_b
     526              :       REAL(KIND=dp)                                      :: dab
     527         1250 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: work
     528              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: intab
     529              :       REAL(KIND=dp), DIMENSION(3)                        :: ra, rab, rac, rbc
     530         1250 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: set_radius_a, set_radius_b
     531         1250 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: rpgfa, rpgfb, sphi_a, sphi_b, zeta, zetb
     532         1250 :       TYPE(block_p_type), ALLOCATABLE, DIMENSION(:)      :: integral
     533              :       TYPE(cell_type), POINTER                           :: cell
     534         1250 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: basis_set_list
     535              :       TYPE(gto_basis_set_type), POINTER                  :: basis_set_a, basis_set_b
     536              :       TYPE(neighbor_list_iterator_p_type), &
     537         1250 :          DIMENSION(:), POINTER                           :: nl_iterator
     538              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     539         1250 :          POINTER                                         :: sab_all
     540         1250 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     541         1250 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     542              :       TYPE(qs_kind_type), POINTER                        :: qs_kind
     543              : 
     544         1250 :       CALL timeset(routineN, handle)
     545              : 
     546              :       CALL get_qs_env(qs_env=qs_env, &
     547              :                       qs_kind_set=qs_kind_set, &
     548              :                       particle_set=particle_set, &
     549              :                       sab_all=sab_all, &
     550         1250 :                       cell=cell)
     551              : 
     552         1250 :       nkind = SIZE(qs_kind_set)
     553              : 
     554              : !   *** Allocate work storage ***
     555              : 
     556              :       CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
     557              :                            maxco=maxco, &
     558         1250 :                            maxsgf=maxsgf)
     559              : 
     560        13750 :       ALLOCATE (intab(maxco, maxco, 3), work(maxco, maxsgf), integral(3))
     561         1250 :       intab(:, :, :) = 0.0_dp
     562         1250 :       work(:, :) = 0.0_dp
     563              : 
     564         5796 :       ALLOCATE (basis_set_list(nkind))
     565         3296 :       DO ikind = 1, nkind
     566         2046 :          qs_kind => qs_kind_set(ikind)
     567         2046 :          CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set_a)
     568         3296 :          IF (ASSOCIATED(basis_set_a)) THEN
     569         2046 :             basis_set_list(ikind)%gto_basis_set => basis_set_a
     570              :          ELSE
     571            0 :             NULLIFY (basis_set_list(ikind)%gto_basis_set)
     572              :          END IF
     573              :       END DO
     574         1250 :       CALL neighbor_list_iterator_create(nl_iterator, sab_all)
     575        94981 :       DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     576              :          CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, inode=inode, &
     577        93731 :                                 iatom=iatom, jatom=jatom, r=rab)
     578        93731 :          basis_set_a => basis_set_list(ikind)%gto_basis_set
     579        93731 :          IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
     580        93731 :          basis_set_b => basis_set_list(jkind)%gto_basis_set
     581        93731 :          IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
     582        93731 :          ra = pbc(particle_set(iatom)%r, cell)
     583              :          ! basis ikind
     584        93731 :          first_sgfa => basis_set_a%first_sgf
     585        93731 :          la_max => basis_set_a%lmax
     586        93731 :          la_min => basis_set_a%lmin
     587        93731 :          npgfa => basis_set_a%npgf
     588        93731 :          nseta = basis_set_a%nset
     589        93731 :          nsgfa => basis_set_a%nsgf_set
     590        93731 :          rpgfa => basis_set_a%pgf_radius
     591        93731 :          set_radius_a => basis_set_a%set_radius
     592        93731 :          sphi_a => basis_set_a%sphi
     593        93731 :          zeta => basis_set_a%zet
     594              :          ! basis jkind
     595        93731 :          first_sgfb => basis_set_b%first_sgf
     596        93731 :          lb_max => basis_set_b%lmax
     597        93731 :          lb_min => basis_set_b%lmin
     598        93731 :          npgfb => basis_set_b%npgf
     599        93731 :          nsetb = basis_set_b%nset
     600        93731 :          nsgfb => basis_set_b%nsgf_set
     601        93731 :          rpgfb => basis_set_b%pgf_radius
     602        93731 :          set_radius_b => basis_set_b%set_radius
     603        93731 :          sphi_b => basis_set_b%sphi
     604        93731 :          zetb => basis_set_b%zet
     605              : 
     606        93731 :          IF (inode == 1) last_jatom = 0
     607              : 
     608        93731 :          IF (jatom /= last_jatom) THEN
     609              :             new_atom_b = .TRUE.
     610              :             last_jatom = jatom
     611              :          ELSE
     612              :             new_atom_b = .FALSE.
     613              :          END IF
     614              : 
     615              :          IF (new_atom_b) THEN
     616              :             !IF (iatom <= jatom) THEN
     617         5987 :             irow = iatom
     618         5987 :             icol = jatom
     619              :             !ELSE
     620              :             !   irow = jatom
     621              :             !   icol = iatom
     622              :             !END IF
     623              : 
     624        23948 :             DO i = 1, 3
     625        17961 :                NULLIFY (INTEGRAL(i)%block)
     626              :                CALL dbcsr_get_block_p(matrix=matrix(i)%matrix, &
     627        17961 :                                       row=irow, col=icol, BLOCK=INTEGRAL(i)%block, found=found)
     628        23948 :                CPASSERT(found .AND. ASSOCIATED(INTEGRAL(i)%block))
     629              :             END DO
     630              :          END IF
     631              : 
     632       374924 :          dab = NORM2(rab)
     633              : 
     634       312058 :          DO iset = 1, nseta
     635              : 
     636       217077 :             ncoa = npgfa(iset)*ncoset(la_max(iset))
     637       217077 :             sgfa = first_sgfa(1, iset)
     638              : 
     639       837307 :             DO jset = 1, nsetb
     640              : 
     641       526499 :                IF (set_radius_a(iset) + set_radius_b(jset) < dab) CYCLE
     642              : 
     643              :                !IF(PRESENT(wancen)) THEN
     644              :                !   rc = wancen
     645       201893 :                rac = pbc(rc, ra, cell)
     646       807572 :                rbc = rac + rab
     647              :                !ELSE
     648              :                !   rc(1:3) = rb(1:3)
     649              :                !   rac(1:3) = -rab(1:3)
     650              :                !   rbc(1:3) = 0.0_dp
     651              :                !ENDIF
     652              : 
     653       201893 :                ncob = npgfb(jset)*ncoset(lb_max(jset))
     654       201893 :                sgfb = first_sgfb(1, jset)
     655              : 
     656              :                ! *** Calculate the primitive angular momentum integrals ***
     657              : 
     658              :                CALL angmom(la_max(iset), npgfa(iset), zeta(:, iset), rpgfa(:, iset), la_min(iset), &
     659       201893 :                            lb_max(jset), npgfb(jset), zetb(:, jset), rpgfb(:, jset), rac, rbc, intab)
     660              : 
     661              :                ! *** Contraction step ***
     662              : 
     663      1024649 :                DO i = 1, 3
     664              : 
     665              :                   CALL dgemm("N", "N", ncoa, nsgfb(jset), ncob, &
     666              :                              1.0_dp, intab(1, 1, i), SIZE(intab, 1), &
     667              :                              sphi_b(1, sgfb), SIZE(sphi_b, 1), &
     668       605679 :                              0.0_dp, work(1, 1), SIZE(work, 1))
     669              : 
     670              :                   !IF (iatom <= jatom) THEN
     671              : 
     672              :                   CALL dgemm("T", "N", nsgfa(iset), nsgfb(jset), ncoa, &
     673              :                              1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
     674              :                              work(1, 1), SIZE(work, 1), &
     675              :                              1.0_dp, integral(i)%block(sgfa, sgfb), &
     676      1132178 :                              SIZE(integral(i)%block, 1))
     677              : 
     678              :                   !ELSE
     679              :                   !
     680              :                   !   CALL dgemm("T","N",nsgfb(jset),nsgfa(iset),ncoa,&
     681              :                   !              -1.0_dp,work(1,1),SIZE(work,1),&
     682              :                   !              sphi_a(1,sgfa),SIZE(sphi_a,1),&
     683              :                   !              1.0_dp,integral(i)%block(sgfb,sgfa),&
     684              :                   !              SIZE(integral(i)%block,1))
     685              :                   !
     686              :                   !ENDIF
     687              : 
     688              :                END DO
     689              : 
     690              :             END DO
     691              : 
     692              :          END DO
     693              : 
     694              :       END DO
     695         1250 :       CALL neighbor_list_iterator_release(nl_iterator)
     696              : 
     697              :       ! *** Release work storage ***
     698              : 
     699         1250 :       DEALLOCATE (intab, work, integral, basis_set_list)
     700              : 
     701              : !   *** Print the spin orbit matrix, if requested ***
     702              : 
     703              :       !IF (BTEST(cp_print_key_should_output(logger%iter_info,&
     704              :       !     qs_env%input,"DFT%PRINT%AO_MATRICES/ANGULAR_MOMENTUM"),cp_p_file)) THEN
     705              :       !   iw = cp_print_key_unit_nr(logger,qs_env%input,"DFT%PRINT%AO_MATRICES/ANGULAR_MOMENTUM",&
     706              :       !        extension=".Log")
     707              :       !   CALL cp_dbcsr_write_sparse_matrix(matrix(1)%matrix,4,6,qs_env,para_env,output_unit=iw)
     708              :       !   CALL cp_dbcsr_write_sparse_matrix(matrix(2)%matrix,4,6,qs_env,para_env,output_unit=iw)
     709              :       !   CALL cp_dbcsr_write_sparse_matrix(matrix(3)%matrix,4,6,qs_env,para_env,output_unit=iw)
     710              :       !   CALL cp_print_key_finished_output(iw,logger,qs_env%input,&
     711              :       !        "DFT%PRINT%AO_MATRICES/ANGULAR_MOMENTUM")
     712              :       !END IF
     713              : 
     714         1250 :       CALL timestop(handle)
     715              : 
     716         2500 :    END SUBROUTINE build_ang_mom_matrix
     717              : 
     718              : ! **************************************************************************************************
     719              : END MODULE qs_operators_ao
        

Generated by: LCOV version 2.0-1