LCOV - code coverage report
Current view: top level - src - topology_inversion.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:92574dc) Lines: 100.0 % 48 48
Test Date: 2026-09-24 01:27:39 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 Inversion action on CP2K Gaussian Bloch coefficients, including lattice phases.
      10              : ! **************************************************************************************************
      11              : MODULE topology_inversion
      12              :    USE atomic_kind_types,               ONLY: get_atomic_kind
      13              :    USE basis_set_types,                 ONLY: gto_basis_set_type
      14              :    USE cell_types,                      ONLY: cell_type,&
      15              :                                               pbc
      16              :    USE ieee_arithmetic,                 ONLY: ieee_is_finite
      17              :    USE kinds,                           ONLY: dp
      18              :    USE mathconstants,                   ONLY: twopi
      19              :    USE particle_types,                  ONLY: particle_type
      20              :    USE qs_environment_types,            ONLY: get_qs_env,&
      21              :                                               qs_environment_type
      22              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      23              :                                               qs_kind_type
      24              : 
      25              :    IMPLICIT NONE
      26              :    PRIVATE
      27              :    PUBLIC :: gaussian_inversion_action
      28              : CONTAINS
      29              : 
      30              : ! **************************************************************************************************
      31              : !> \brief Construct sparse AO inversion at a TRIM for the operation r -> 2*center-r.
      32              : !> \param qs_env Electronic environment
      33              : !> \param k Fractional reciprocal coordinate at a TRIM
      34              : !> \param center Fractional inversion center in the user's cell setting
      35              : !> \param mapping Target AO row for every source row
      36              : !> \param phase AO parity times exp(+2*pi*i*k.L), with 2c-r_a=r_b+L
      37              : !> \param tolerance Geometry tolerance in Bohr
      38              : !> \param status Zero on success, negative if geometry/basis/periodicity is incompatible
      39              : ! **************************************************************************************************
      40           32 :    SUBROUTINE gaussian_inversion_action(qs_env, k, center, mapping, phase, tolerance, status)
      41              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      42              :       REAL(KIND=dp), INTENT(IN)                          :: k(3), center(3)
      43              :       INTEGER, INTENT(OUT)                               :: mapping(:)
      44              :       COMPLEX(KIND=dp), INTENT(OUT)                      :: phase(:)
      45              :       REAL(KIND=dp), INTENT(IN)                          :: tolerance
      46              :       INTEGER, INTENT(OUT)                               :: status
      47              : 
      48              :       INTEGER                                            :: a, b, found, i, iset, l, n, shell, total
      49           32 :       INTEGER, ALLOCATABLE                               :: kind(:), offset(:), TARGET(:)
      50              :       REAL(KIND=dp)                                      :: angle, delta(3), image(3)
      51           32 :       REAL(KIND=dp), ALLOCATABLE                         :: position(:, :)
      52              :       TYPE(cell_type), POINTER                           :: cell
      53              :       TYPE(gto_basis_set_type), POINTER                  :: basis
      54           32 :       TYPE(particle_type), POINTER                       :: particles(:)
      55           32 :       TYPE(qs_kind_type), POINTER                        :: kinds_set(:)
      56              : 
      57           32 :       status = -1
      58          552 :       mapping = 0
      59          552 :       phase = CMPLX(0, 0, dp)
      60           32 :       IF (tolerance <= 0.0_dp .OR. SIZE(phase) /= SIZE(mapping)) RETURN
      61          128 :       IF (.NOT. ieee_is_finite(tolerance) .OR. .NOT. ALL(ieee_is_finite(center))) RETURN
      62          128 :       IF (.NOT. ALL(ieee_is_finite(k))) RETURN
      63          128 :       IF (MAXVAL(ABS(2*k - NINT(2*k))) > 1.e-8_dp) RETURN
      64           32 :       CALL get_qs_env(qs_env, cell=cell, particle_set=particles, qs_kind_set=kinds_set)
      65          128 :       IF (ANY(cell%perd /= 1)) RETURN
      66           32 :       n = SIZE(particles)
      67          224 :       ALLOCATE (KIND(n), offset(n), TARGET(n), position(3, n))
      68           72 :       total = 0
      69           72 :       DO a = 1, n
      70           40 :          CALL get_atomic_kind(particles(a)%atomic_kind, kind_number=KIND(a))
      71           40 :          CALL get_qs_kind(kinds_set(KIND(a)), basis_set=basis)
      72           40 :          IF (.NOT. ASSOCIATED(basis)) RETURN
      73           40 :          offset(a) = total
      74           40 :          total = total + basis%nsgf
      75          672 :          position(:, a) = MATMUL(cell%h_inv, pbc(particles(a)%r, cell))
      76              :       END DO
      77           32 :       IF (total /= SIZE(mapping)) RETURN
      78           72 :       DO a = 1, n
      79              :          found = 0
      80           96 :          DO b = 1, n
      81           56 :             IF (KIND(a) /= KIND(b)) CYCLE
      82          224 :             delta = 2*center - position(:, a) - position(:, b)
      83         1064 :             IF (SQRT(SUM(MATMUL(cell%hmat, delta - NINT(delta))**2)) > tolerance) CYCLE
      84           40 :             found = found + 1
      85           80 :             TARGET(a) = b
      86              :          END DO
      87           72 :          IF (found /= 1) RETURN
      88              :       END DO
      89           72 :       DO a = 1, n
      90           40 :          b = TARGET(a)
      91           40 :          IF (TARGET(b) /= a) RETURN
      92          160 :          image = REAL(NINT(2*center - position(:, a) - position(:, b)), dp)
      93          160 :          angle = twopi*DOT_PRODUCT(k, image)
      94           40 :          CALL get_qs_kind(kinds_set(KIND(a)), basis_set=basis)
      95          136 :          DO iset = 1, basis%nset
      96          304 :             DO shell = 1, basis%nshell(iset)
      97          200 :                l = basis%l(shell, iset)
      98          784 :                DO i = basis%first_sgf(shell, iset), basis%last_sgf(shell, iset)
      99          520 :                   mapping(offset(a) + i) = offset(b) + i
     100          720 :                   phase(offset(a) + i) = (-1)**l*CMPLX(COS(angle), SIN(angle), dp)
     101              :                END DO
     102              :             END DO
     103              :          END DO
     104              :       END DO
     105          552 :       IF (ANY(mapping == 0)) RETURN
     106           32 :       status = 0
     107           64 :    END SUBROUTINE gaussian_inversion_action
     108              : END MODULE topology_inversion
        

Generated by: LCOV version 2.0-1