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

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Analytic translations of finite or periodized Gaussian AO functions.
      10              : !> \author Thomas D. Kuehne, tkuehne@cp2k.org
      11              : ! **************************************************************************************************
      12              : MODULE qs_ao_translations
      13              :    USE ai_contraction,                  ONLY: block_add,&
      14              :                                               contraction
      15              :    USE ai_overlap,                      ONLY: overlap_ab
      16              :    USE basis_set_types,                 ONLY: gto_basis_set_p_type,&
      17              :                                               gto_basis_set_type
      18              :    USE cell_types,                      ONLY: cell_type
      19              :    USE cp_dbcsr_api,                    ONLY: dbcsr_create,&
      20              :                                               dbcsr_distribution_get,&
      21              :                                               dbcsr_distribution_type,&
      22              :                                               dbcsr_finalize,&
      23              :                                               dbcsr_get_info,&
      24              :                                               dbcsr_p_type,&
      25              :                                               dbcsr_put_block,&
      26              :                                               dbcsr_type_no_symmetry
      27              :    USE kinds,                           ONLY: dp
      28              :    USE message_passing,                 ONLY: mp_para_env_type
      29              :    USE orbital_pointers,                ONLY: ncoset
      30              :    USE particle_types,                  ONLY: particle_type
      31              :    USE qs_environment_types,            ONLY: get_qs_env,&
      32              :                                               qs_environment_type
      33              :    USE qs_integral_utils,               ONLY: basis_set_list_setup,&
      34              :                                               get_memory_usage
      35              :    USE qs_kind_types,                   ONLY: qs_kind_type
      36              : #include "./base/base_uses.f90"
      37              : 
      38              :    IMPLICIT NONE
      39              :    PRIVATE
      40              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_ao_translations'
      41              :    PUBLIC :: ao_translation_matrices
      42              : CONTAINS
      43              : ! **************************************************************************************************
      44              : !> \brief Overlaps with translated ket Gaussians, U(a) psi(r) = psi(r+a).
      45              : !> \param qs_env Quickstep environment supplying primitive AOs and their distribution
      46              : !> \param shifts Cartesian translation vectors in internal bohr
      47              : !> \param translations Newly allocated nonsymmetric primitive-size matrices, released by caller
      48              : !> \param periodic_grid If present, sum images of the grid-expanded periodic cell; otherwise finite
      49              : !> \note Arbitrary shifts use their own overlap screening, not the SCF neighbour list.
      50              : ! **************************************************************************************************
      51           16 :    SUBROUTINE ao_translation_matrices(qs_env, shifts, translations, periodic_grid)
      52              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      53              :       REAL(dp), INTENT(IN)                               :: shifts(:, :)
      54              :       TYPE(dbcsr_p_type), POINTER                        :: translations(:)
      55              :       INTEGER, INTENT(IN), OPTIONAL                      :: periodic_grid(3)
      56              : 
      57              :       INTEGER                                            :: axis, ia, ib, iset, it, jset, ka, kb, &
      58              :                                                             ld, lower(3), na, nb, nx, ny, nz, sa, &
      59              :                                                             sb, upper(3)
      60           16 :       INTEGER, POINTER                                   :: col_dist(:), pgrid(:, :), row_dist(:)
      61              :       LOGICAL                                            :: do_kpoints
      62              :       REAL(dp)                                           :: distance, h(3, 3), hinv(3, 3), &
      63              :                                                             offset(3), rab(3), radius, reach(3), &
      64              :                                                             scaled(3)
      65           16 :       REAL(dp), ALLOCATABLE                              :: block(:, :), integrals(:, :), work(:, :)
      66              :       TYPE(cell_type), POINTER                           :: cell
      67              :       TYPE(dbcsr_distribution_type)                      :: distribution
      68           16 :       TYPE(dbcsr_p_type), POINTER                        :: matrix_s(:, :)
      69           16 :       TYPE(gto_basis_set_p_type), ALLOCATABLE            :: bases(:)
      70              :       TYPE(gto_basis_set_type), POINTER                  :: a, b
      71              :       TYPE(mp_para_env_type), POINTER                    :: para_env
      72           16 :       TYPE(particle_type), POINTER                       :: particles(:)
      73           16 :       TYPE(qs_kind_type), POINTER                        :: kinds(:)
      74              : 
      75              :       CALL get_qs_env(qs_env, cell=cell, do_kpoints=do_kpoints, matrix_s_kp=matrix_s, &
      76           16 :                       para_env=para_env, particle_set=particles, qs_kind_set=kinds)
      77           16 :       h = 0.0_dp
      78           16 :       hinv = 0.0_dp
      79           16 :       reach = 0.0_dp
      80           16 :       IF (PRESENT(periodic_grid)) THEN
      81           56 :          CPASSERT(ALL(periodic_grid >= 1))
      82           56 :          CPASSERT(ALL(periodic_grid == 1 .OR. cell%perd /= 0))
      83           56 :          DO axis = 1, 3
      84          168 :             h(:, axis) = cell%hmat(:, axis)*periodic_grid(axis)
      85          168 :             hinv(axis, :) = cell%h_inv(axis, :)/periodic_grid(axis)
      86          182 :             IF (cell%perd(axis) /= 0) reach(axis) = SQRT(SUM(hinv(axis, :)**2))
      87              :          END DO
      88            8 :       ELSE IF (ANY(cell%perd /= 0) .OR. do_kpoints) THEN
      89            0 :          CPABORT('Finite AO translations require isolated Gamma systems.')
      90              :       END IF
      91           16 :       CPASSERT(SIZE(shifts, 1) == 3)
      92           64 :       ALLOCATE (bases(SIZE(kinds)))
      93           16 :       CALL basis_set_list_setup(bases, 'ORB', kinds)
      94           16 :       ld = get_memory_usage(kinds, 'ORB')
      95          146 :       ALLOCATE (integrals(ld, ld), work(ld, ld), translations(SIZE(shifts, 2)))
      96           16 :       CALL dbcsr_get_info(matrix_s(1, 1)%matrix, distribution=distribution)
      97           16 :       CALL dbcsr_distribution_get(distribution, pgrid=pgrid, row_dist=row_dist, col_dist=col_dist)
      98           34 :       DO it = 1, SIZE(shifts, 2)
      99           18 :          ALLOCATE (translations(it)%matrix)
     100              :          CALL dbcsr_create(translations(it)%matrix, template=matrix_s(1, 1)%matrix, &
     101           18 :                            name='AO TRANSLATION', matrix_type=dbcsr_type_no_symmetry)
     102           44 :          DO ia = 1, SIZE(particles)
     103           26 :             ka = particles(ia)%atomic_kind%kind_number
     104           26 :             a => bases(ka)%gto_basis_set
     105           26 :             IF (.NOT. ASSOCIATED(a)) CYCLE
     106           90 :             DO ib = 1, SIZE(particles)
     107           46 :                IF (pgrid(row_dist(ia), col_dist(ib)) /= para_env%mepos) CYCLE
     108           23 :                kb = particles(ib)%atomic_kind%kind_number
     109           23 :                b => bases(kb)%gto_basis_set
     110           23 :                IF (.NOT. ASSOCIATED(b)) CYCLE
     111           92 :                offset = particles(ib)%r - particles(ia)%r - shifts(:, it)
     112           23 :                lower = 0
     113           23 :                upper = 0
     114           23 :                IF (PRESENT(periodic_grid)) THEN
     115              :                   ! Reciprocal-plane distances bound every image, including skew cells.
     116          195 :                   scaled = MATMUL(hinv, offset)
     117           75 :                   radius = MAXVAL(a%set_radius) + MAXVAL(b%set_radius)
     118           60 :                   DO axis = 1, 3
     119           45 :                      IF (cell%perd(axis) == 0) CYCLE
     120           45 :                      lower(axis) = CEILING(-scaled(axis) - radius*reach(axis))
     121           60 :                      upper(axis) = FLOOR(-scaled(axis) + radius*reach(axis))
     122              :                   END DO
     123              :                END IF
     124           92 :                ALLOCATE (block(a%nsgf, b%nsgf))
     125           23 :                block = 0.0_dp
     126          106 :                DO nz = lower(3), upper(3)
     127          489 :                   DO ny = lower(2), upper(2)
     128         1099 :                      DO nx = lower(1), upper(1)
     129        12027 :                         rab = offset + MATMUL(h, REAL([nx, ny, nz], dp))
     130         2532 :                         distance = SQRT(SUM(rab**2))
     131         2274 :                         DO iset = 1, a%nset
     132         1258 :                            sa = a%first_sgf(1, iset)
     133         1258 :                            na = a%npgf(iset)*(ncoset(a%lmax(iset)) - ncoset(a%lmin(iset) - 1))
     134         4399 :                            DO jset = 1, b%nset
     135         2508 :                               IF (a%set_radius(iset) + b%set_radius(jset) < distance) CYCLE
     136         1540 :                               sb = b%first_sgf(1, jset)
     137         1540 :                               nb = b%npgf(jset)*(ncoset(b%lmax(jset)) - ncoset(b%lmin(jset) - 1))
     138              :                               CALL overlap_ab(a%lmax(iset), a%lmin(iset), a%npgf(iset), &
     139              :                                               a%pgf_radius(:, iset), a%zet(:, iset), &
     140              :                                               b%lmax(jset), b%lmin(jset), b%npgf(jset), &
     141         1540 :                                               b%pgf_radius(:, jset), b%zet(:, jset), rab, sab=integrals)
     142              :                               CALL contraction(integrals, work, ca=a%scon(:, sa:), na=na, ma=a%nsgf_set(iset), &
     143              :                                                cb=b%scon(:, sb:), nb=nb, mb=b%nsgf_set(jset), &
     144         1540 :                                                fscale=1.0_dp, trans=.FALSE.)
     145              :                               CALL block_add('IN', work, a%nsgf_set(iset), b%nsgf_set(jset), &
     146         3766 :                                              block, sa, sb, trans=.FALSE.)
     147              :                            END DO
     148              :                         END DO
     149              :                      END DO
     150              :                   END DO
     151              :                END DO
     152          989 :                IF (MAXVAL(ABS(block)) > 0.0_dp) CALL dbcsr_put_block(translations(it)%matrix, ia, ib, block)
     153           72 :                DEALLOCATE (block)
     154              :             END DO
     155              :          END DO
     156           34 :          CALL dbcsr_finalize(translations(it)%matrix)
     157              :       END DO
     158           48 :    END SUBROUTINE ao_translation_matrices
     159              : END MODULE qs_ao_translations
        

Generated by: LCOV version 2.0-1