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
|