LCOV - code coverage report
Current view: top level - src - topology_tqc.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:92574dc) Lines: 100.0 % 41 41
Test Date: 2026-09-24 01:27:39 Functions: 100.0 % 2 2

            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 Exact inversion-subgroup EBR and symmetry-indicator analysis (spinful TR).
      10              : !> \note These are symmetry signatures, not a complete topological classification.
      11              : ! **************************************************************************************************
      12              : MODULE topology_tqc
      13              :    IMPLICIT NONE
      14              :    PRIVATE
      15              :    PUBLIC :: inversion_indicators, inversion_ebr_signature
      16              : CONTAINS
      17              : 
      18              : ! **************************************************************************************************
      19              : !> \brief Fu--Kane indices and inversion indicator with an explicit sign convention.
      20              : !> \param odd Number of odd Kramers pairs at each TRIM, x-bit fastest
      21              : !> \param pairs Number of occupied Kramers pairs
      22              : !> \param DIMENSION Two (kz=0 plane) or three (full reciprocal torus)
      23              : !> \param strong Plane index in 2D, strong index in 3D
      24              : !> \param weak Three weak indices in 3D; -1 (unavailable) in 2D
      25              : !> \param z4 sum(odd) mod 4 in 3D; -1 (unavailable) in 2D
      26              : !> \param status Zero on valid input
      27              : ! **************************************************************************************************
      28        13326 :    SUBROUTINE inversion_indicators(odd, pairs, DIMENSION, strong, weak, z4, status)
      29              :       INTEGER, INTENT(IN)                                :: odd(:), pairs, DIMENSION
      30              :       INTEGER, INTENT(OUT)                               :: strong, weak(3), z4, status
      31              : 
      32              :       INTEGER                                            :: axis, k
      33              : 
      34        13326 :       status = -1
      35        13326 :       strong = -1
      36        53304 :       weak = -1
      37        13326 :       z4 = -1
      38        13326 :       IF (DIMENSION < 2 .OR. DIMENSION > 3) RETURN
      39        13326 :       IF (SIZE(odd) /= 2**DIMENSION .OR. pairs < 1 .OR. pairs > 1000000) RETURN
      40       238540 :       IF (ANY(odd < 0) .OR. ANY(odd > pairs)) RETURN
      41       119270 :       strong = MOD(SUM(odd), 2)
      42        13326 :       IF (DIMENSION == 3) THEN
      43       118440 :          z4 = MOD(SUM(odd), 4)
      44        13160 :          weak = 0
      45        52640 :          DO axis = 1, 3
      46       368480 :             DO k = 0, 7
      47       355320 :                IF (BTEST(k, axis - 1)) weak(axis) = weak(axis) + odd(k + 1)
      48              :             END DO
      49              :          END DO
      50        52640 :          weak = MOD(weak, 2)
      51              :       END IF
      52        13326 :       status = 0
      53              :    END SUBROUTINE inversion_indicators
      54              : 
      55              : ! **************************************************************************************************
      56              : !> \brief Exact signed/nonnegative EBR-signature test for the inversion subgroup.
      57              : !> \param odd Odd Kramers pairs, x-bit fastest, 4 or 8 TRIM
      58              : !> \param pairs Selected number of Kramers pairs
      59              : !> \param signed_atomic Signature belongs to the integer lattice of atomic signatures
      60              : !> \param nonnegative_atomic A physical nonnegative EBR-signature decomposition exists
      61              : !> \param coefficients Even/odd local-parity EBR coefficients at the 2^d inversion centers
      62              : !> \param status Zero on valid input, coefficients valid only if nonnegative_atomic
      63              : !> \note EBR at r=a/2 has inversion character s*(-1)^(a.k). Fourier inversion
      64              : !>       determines the differences between even/odd multiplicities exactly.
      65              : !>       No database or floating-point integer decision is used.
      66              : ! **************************************************************************************************
      67        13328 :    SUBROUTINE inversion_ebr_signature(odd, pairs, signed_atomic, nonnegative_atomic, coefficients, status)
      68              :       INTEGER, INTENT(IN)                                :: odd(:), pairs
      69              :       LOGICAL, INTENT(OUT)                               :: signed_atomic, nonnegative_atomic
      70              :       INTEGER, INTENT(OUT)                               :: coefficients(:, :), status
      71              : 
      72              :       INTEGER                                            :: a, k, n, numerator, spare, &
      73        13328 :                                                             difference(SIZE(odd))
      74              : 
      75        13328 :       status = -1
      76        13328 :       signed_atomic = .FALSE.
      77        13328 :       nonnegative_atomic = .FALSE.
      78       331208 :       coefficients = 0
      79        13328 :       n = SIZE(odd)
      80        13328 :       IF (n /= 4 .AND. n /= 8) RETURN
      81        13328 :       IF (SIZE(coefficients, 1) /= 2 .OR. SIZE(coefficients, 2) /= n) RETURN
      82       225232 :       IF (pairs < 1 .OR. pairs > 1000000 .OR. ANY(odd < 0) .OR. ANY(odd > pairs)) RETURN
      83        13326 :       status = 0
      84        22606 :       DO a = 0, n - 1
      85              :          numerator = 0
      86       196364 :          DO k = 0, n - 1
      87       196364 :             numerator = numerator + (-1)**POPCNT(IAND(a, k))*(pairs - 2*odd(k + 1))
      88              :          END DO
      89        22004 :          IF (MOD(numerator, n) /= 0) RETURN
      90         9882 :          difference(a + 1) = numerator/n
      91              :       END DO
      92         5082 :       IF (MOD(pairs - SUM(difference), 2) /= 0) RETURN
      93          602 :       signed_atomic = .TRUE.
      94         5082 :       spare = pairs - SUM(ABS(difference))
      95          602 :       IF (spare < 0) RETURN
      96          360 :       nonnegative_atomic = .TRUE.
      97         2968 :       coefficients(1, :) = MAX(difference, 0)
      98         2968 :       coefficients(2, :) = MAX(-difference, 0)
      99         1080 :       coefficients(:, 1) = coefficients(:, 1) + spare/2
     100              :    END SUBROUTINE inversion_ebr_signature
     101              : END MODULE topology_tqc
        

Generated by: LCOV version 2.0-1