63 isym, success, reason)
66 INTEGER,
INTENT(IN) :: ikred, isym
67 LOGICAL,
INTENT(OUT) :: success
68 CHARACTER(LEN=*),
INTENT(OUT) :: reason
70 COMPLEX(KIND=dp) :: coeff, phase
71 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: dst_coeff, src_coeff
72 INTEGER :: iao, iatom, ikind, imo, irow, irow_source, irow_target, irow_work, nao, natom, &
73 nmo, rot_slot, source_atom, source_dim, target_atom, target_dim
74 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ao_size, ao_start
75 LOGICAL :: reverse_phase, time_reversal
76 REAL(kind=
dp) :: arg, coskl, sinkl
77 REAL(kind=
dp),
DIMENSION(3) :: xkp_phase
78 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: rotmat
91 ALLOCATE (src_coeff(nao, nmo), dst_coeff(nao, nmo))
93 dst_coeff(:, :) = cmplx(0.0_dp, 0.0_dp, kind=
dp)
96 dst_coeff(:, :) = conjg(src_coeff)
102 IF (.NOT.
ASSOCIATED(qs_kpoint%kp_sym))
THEN
103 reason =
"SCF symmetry operation data are not available"
106 kpsym => qs_kpoint%kp_sym(ikred)%kpoint_sym
107 IF (.NOT.
ASSOCIATED(
kpsym))
THEN
108 reason =
"SCF k-point symmetry operation is not available"
111 IF (isym >
kpsym%nwred)
THEN
112 reason =
"SCF k-point symmetry operation index is out of range"
115 IF (.NOT.
ASSOCIATED(qs_kpoint%atype) .OR. .NOT.
ASSOCIATED(qs_kpoint%kind_rotmat))
THEN
116 reason =
"SCF atom mappings or basis rotation matrices are not available"
121 IF (rot_slot == 0)
THEN
122 reason =
"could not match the SCF symmetry operation to a basis rotation"
125 kind_rot => qs_kpoint%kind_rotmat(rot_slot, :)
126 natom =
SIZE(qs_kpoint%atype)
127 ALLOCATE (ao_start(natom), ao_size(natom))
130 ikind = qs_kpoint%atype(iatom)
131 IF (.NOT.
ASSOCIATED(kind_rot(ikind)%rmat))
THEN
132 reason =
"a required basis rotation matrix is not available"
135 ao_start(iatom) = irow
136 ao_size(iatom) =
SIZE(kind_rot(ikind)%rmat, 2)
137 irow = irow + ao_size(iatom)
139 IF (irow - 1 /= nao)
THEN
140 reason =
"atom-resolved AO dimensions do not match the MO coefficient matrix"
144 time_reversal =
kpsym%rotp(isym) < 0
145 reverse_phase = qs_kpoint%gamma_centered .AND. any(mod(qs_kpoint%nkp_grid, 2) == 0)
146 IF (
ASSOCIATED(
kpsym%phase_mode))
THEN
147 IF (
kpsym%phase_mode(isym) > 0) reverse_phase =
kpsym%phase_mode(isym) == 2
149 xkp_phase(1:3) =
kpsym%xkp(1:3, isym)
152 target_atom =
kpsym%f0(iatom, isym)
153 ikind = qs_kpoint%atype(source_atom)
154 rotmat => kind_rot(ikind)%rmat
155 source_dim = ao_size(source_atom)
156 target_dim = ao_size(target_atom)
157 IF (
SIZE(rotmat, 1) /= target_dim .OR.
SIZE(rotmat, 2) /= source_dim)
THEN
158 reason =
"basis rotation dimensions do not match the atom/AO symmetry transform"
161 arg = real(
kpsym%fcell_gauge(1, source_atom, isym), kind=
dp)*xkp_phase(1) + &
162 REAL(
kpsym%fcell_gauge(2, source_atom, isym), kind=
dp)*xkp_phase(2) + &
163 REAL(
kpsym%fcell_gauge(3, source_atom, isym), kind=
dp)*xkp_phase(3)
164 IF (
ASSOCIATED(
kpsym%kgphase))
THEN
165 arg = arg +
kpsym%kgphase(source_atom, isym)
167 IF (reverse_phase) arg = -arg
168 coskl = cos(
twopi*arg)
169 sinkl = sin(
twopi*arg)
171 DO irow_work = 1, source_dim
172 irow_source = ao_start(source_atom) + irow_work - 1
173 coeff = src_coeff(irow_source, imo)
174 IF (time_reversal) coeff = conjg(coeff)
175 phase = cmplx(coskl, sinkl, kind=
dp)*coeff
176 DO iao = 1, target_dim
177 irow_target = ao_start(target_atom) + iao - 1
178 dst_coeff(irow_target, imo) = dst_coeff(irow_target, imo) + &
179 rotmat(iao, irow_work)*phase
subroutine, public cp_cfm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
Extract a sub-matrix from the full matrix: op(target_m)(1:n_rows,1:n_cols) = fm(start_row:start_row+n...
subroutine, public cp_cfm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, matrix_struct, para_env)
Returns information about a full matrix.
subroutine, public cp_cfm_set_submatrix(matrix, new_values, start_row, start_col, n_rows, n_cols, alpha, beta, transpose)
Set a sub-matrix of the full matrix: matrix(start_row:start_row+n_rows,start_col:start_col+n_cols) = ...