LCOV - code coverage report
Current view: top level - src - qs_property_symmetry.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:9ccafda) Lines: 96.3 % 54 52
Test Date: 2026-10-15 00:55:44 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 Cell-gauge scalar/spinor reconstruction on independent complete property meshes.
      10              : !> \author Thomas D. Kuehne, tkuehne@cp2k.org
      11              : ! **************************************************************************************************
      12              : MODULE qs_property_symmetry
      13              :    USE cell_types,                      ONLY: cell_type
      14              :    USE input_cp2k_kpoints,              ONLY: use_k290_kpoint_symmetry,&
      15              :                                               use_spglib_kpoint_backend,&
      16              :                                               use_spglib_kpoint_symmetry
      17              :    USE kinds,                           ONLY: dp
      18              :    USE kpoint_methods,                  ONLY: kpoint_initialize
      19              :    USE kpoint_mo_symmetry_methods,      ONLY: kpoint_cell_gauge_action,&
      20              :                                               kpoint_same_periodic
      21              :    USE kpoint_types,                    ONLY: kpoint_create,&
      22              :                                               kpoint_sym_type,&
      23              :                                               kpoint_type
      24              :    USE particle_types,                  ONLY: particle_type
      25              :    USE qs_basis_rotation_methods,       ONLY: qs_basis_rotation
      26              :    USE qs_environment_types,            ONLY: get_qs_env,&
      27              :                                               qs_environment_type
      28              :    USE topology_symmetry,               ONLY: spin_rotation,&
      29              :                                               transform_spinor_frame
      30              : #include "./base/base_uses.f90"
      31              : 
      32              :    IMPLICIT NONE
      33              :    PRIVATE
      34              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_property_symmetry'
      35              :    PUBLIC :: property_symmetry_plan, property_symmetry_frame
      36              : CONTAINS
      37              : ! **************************************************************************************************
      38              : !> \brief Construct a geometric orbit plan; each reconstructed frame still needs H/S validation.
      39              : !> \param qs_env Frozen property environment
      40              : !> \param k Full mesh in fractional reciprocal coordinates
      41              : !> \param grid Complete Gamma-centered property mesh dimensions
      42              : !> \param projection Cartesian periodic-space projector
      43              : !> \param backend Existing K290 or SPGLIB backend identifier
      44              : !> \param tolerance Geometric symmetry tolerance
      45              : !> \param points Owned irreducible k-point object; caller must release it
      46              : !> \param representative Source irreducible index for each full point
      47              : !> \param operation Source-to-target operation, zero identity or minus one time reversal
      48              : ! **************************************************************************************************
      49            8 :    SUBROUTINE property_symmetry_plan(qs_env, k, grid, projection, backend, tolerance, points, representative, operation)
      50              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      51              :       REAL(dp), INTENT(IN)                               :: k(:, :)
      52              :       INTEGER, INTENT(IN)                                :: grid(3)
      53              :       REAL(dp), INTENT(IN)                               :: projection(3, 3)
      54              :       INTEGER, INTENT(IN)                                :: backend
      55              :       REAL(dp), INTENT(IN)                               :: tolerance
      56              :       TYPE(kpoint_type), POINTER                         :: points
      57              :       INTEGER, ALLOCATABLE, INTENT(OUT)                  :: representative(:), operation(:)
      58              : 
      59              :       INTEGER                                            :: ik, ir, is, nk
      60              :       REAL(dp)                                           :: r(3, 3)
      61              :       TYPE(cell_type), POINTER                           :: cell
      62              :       TYPE(kpoint_sym_type), POINTER                     :: sym
      63            8 :       TYPE(particle_type), POINTER                       :: particles(:)
      64              : 
      65            8 :       CALL get_qs_env(qs_env, cell=cell, particle_set=particles)
      66            8 :       nk = SIZE(k, 2)
      67            8 :       CALL kpoint_create(points)
      68            8 :       points%kp_scheme = 'MONKHORST-PACK'
      69           32 :       points%nkp_grid = grid
      70            8 :       points%gamma_centered = .TRUE.
      71            8 :       points%symmetry = .TRUE.
      72            8 :       points%symmetry_backend = backend
      73            8 :       points%symmetry_reduction_method = use_k290_kpoint_symmetry
      74            8 :       IF (backend == use_spglib_kpoint_backend) points%symmetry_reduction_method = use_spglib_kpoint_symmetry
      75            8 :       points%eps_geo = tolerance
      76            8 :       CALL kpoint_initialize(points, particles, cell)
      77            8 :       CALL qs_basis_rotation(qs_env, points)
      78           32 :       ALLOCATE (representative(nk), operation(nk))
      79            8 :       representative = 0
      80            8 :       operation = 0
      81           68 :       DO ik = 1, nk
      82          146 :          DO ir = 1, points%nkp
      83          138 :             IF (kpoint_same_periodic(k(:, ik), points%xkp(:, ir))) THEN
      84           28 :                representative(ik) = ir
      85           28 :                EXIT
      86              :             END IF
      87          440 :             IF (kpoint_same_periodic(k(:, ik), -points%xkp(:, ir))) THEN
      88            4 :                representative(ik) = ir
      89            4 :                operation(ik) = -1
      90              :                EXIT
      91              :             END IF
      92          106 :             sym => points%kp_sym(ir)%kpoint_sym
      93          106 :             IF (.NOT. sym%apply_symmetry) CYCLE
      94         2542 :             DO is = 1, sym%nwred
      95         2508 :                IF (.NOT. kpoint_same_periodic(k(:, ik), sym%xkp(:, is))) CYCLE
      96          364 :                r = sym%rot(:, :, is)
      97         2548 :                IF (MAXVAL(ABS(MATMUL(r, MATMUL(projection, TRANSPOSE(r))) - projection)) > 1.e-9_dp) CYCLE
      98           28 :                representative(ik) = ir
      99           28 :                operation(ik) = is
     100           62 :                EXIT
     101              :             END DO
     102           62 :             IF (representative(ik) > 0) EXIT
     103              :          END DO
     104              :       END DO
     105           68 :       IF (ANY(representative == 0)) THEN
     106            0 :          CPABORT('Property symmetry orbit does not preserve the periodic subspace.')
     107              :       END IF
     108            8 :    END SUBROUTINE property_symmetry_plan
     109              : ! **************************************************************************************************
     110              : !> \brief Reconstruct a target eigenframe with atomic image phases and physical SU(2)/Theta action.
     111              : !> \param points Property symmetry plan
     112              : !> \param representative Source index
     113              : !> \param operation Signed operation index
     114              : !> \param k Target point in the cell Fourier gauge
     115              : !> \param source Source eigenframe
     116              : !> \param soc Whether the frame is spin-major doubled
     117              : !> \param TARGET Reconstructed frame, not rediagonalized or gauge-aligned
     118              : !> \param rotation Cartesian spatial rotation for property tensors
     119              : !> \param antiunitary Whether physical time reversal was applied
     120              : !> \param status Zero on success; the caller must additionally check the target H/S eigensystem
     121              : ! **************************************************************************************************
     122           16 :    SUBROUTINE property_symmetry_frame(points, representative, operation, k, source, soc, TARGET, &
     123              :                                       rotation, antiunitary, status)
     124              :       TYPE(kpoint_type), POINTER                         :: points
     125              :       INTEGER, INTENT(IN)                                :: representative, operation
     126              :       REAL(dp), INTENT(IN)                               :: k(3)
     127              :       COMPLEX(dp), INTENT(IN)                            :: source(:, :)
     128              :       LOGICAL, INTENT(IN)                                :: soc
     129              :       COMPLEX(dp), INTENT(OUT)                           :: target(:, :)
     130              :       REAL(dp), INTENT(OUT)                              :: rotation(3, 3)
     131              :       LOGICAL, INTENT(OUT)                               :: antiunitary
     132              :       INTEGER, INTENT(OUT)                               :: status
     133              : 
     134              :       COMPLEX(dp)                                        :: spin(2, 2)
     135              :       COMPLEX(dp), ALLOCATABLE                           :: orbital(:, :)
     136              :       INTEGER                                            :: n
     137              : 
     138           16 :       n = SIZE(source, 1)
     139           16 :       IF (soc) n = n/2
     140           64 :       ALLOCATE (orbital(n, n))
     141           16 :       CALL kpoint_cell_gauge_action(points, representative, operation, k, orbital, rotation, antiunitary, status)
     142           16 :       IF (status /= 0) RETURN
     143           16 :       IF (soc) THEN
     144           12 :          CALL spin_rotation(rotation, spin, 1.e-9_dp, status)
     145           12 :          IF (status /= 0) RETURN
     146              :          ! CP2K assembles SOC with (sigma_x,-sigma_y,sigma_z), the conjugate spin representation.
     147           84 :          spin = CONJG(spin)
     148           12 :          CALL transform_spinor_frame(orbital, spin, source, antiunitary, TARGET, 1.e-9_dp, status)
     149            4 :       ELSE IF (antiunitary) THEN
     150            0 :          TARGET = MATMUL(orbital, CONJG(source))
     151              :       ELSE
     152        19036 :          TARGET = MATMUL(orbital, source)
     153              :       END IF
     154           32 :    END SUBROUTINE property_symmetry_frame
     155              : END MODULE qs_property_symmetry
        

Generated by: LCOV version 2.0-1