(git:3db43b4)
Loading...
Searching...
No Matches
qs_active_space_utils.F
Go to the documentation of this file.
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 Contains utility routines for the active space module
10!> \par History
11!> 04.2023 created [SB]
12!> \author SB
13! **************************************************************************************************
15
16 USE cp_dbcsr_api, ONLY: dbcsr_csr_type
20 USE kinds, ONLY: dp
25#include "./base/base_uses.f90"
26
27 IMPLICIT NONE
28
29 PRIVATE
30
31 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_active_space_utils'
32
34
35CONTAINS
36
37! **************************************************************************************************
38!> \brief Copy a (square portion) of a `cp_fm_type` matrix to a standard 1D Fortran array
39!> \param source_matrix the matrix from where the data is taken
40!> \param target_array the array were the data is copied to
41!> \param row_index a list containing the row subspace indices
42!> \param col_index a list containing the column subspace indices
43! **************************************************************************************************
44 SUBROUTINE subspace_matrix_to_array(source_matrix, target_array, row_index, col_index)
45 TYPE(cp_fm_type), INTENT(IN) :: source_matrix
46 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: target_array
47 INTEGER, DIMENSION(:), INTENT(IN) :: row_index, col_index
48
49 INTEGER :: i, i_sub, j, j_sub, max_col, max_row, &
50 ncols, nrows
51 REAL(kind=dp) :: mval
52
53 CALL cp_fm_get_info(source_matrix, nrow_global=max_row, ncol_global=max_col)
54 nrows = SIZE(row_index)
55 ncols = SIZE(col_index)
56
57 cpassert(maxval(row_index) <= max_row)
58 cpassert(maxval(col_index) <= max_col)
59 cpassert(minval(row_index) > 0)
60 cpassert(minval(col_index) > 0)
61 cpassert(nrows <= max_row)
62 cpassert(ncols <= max_col)
63
64 cpassert(SIZE(target_array) == nrows*ncols)
65
66 DO j = 1, ncols
67 j_sub = col_index(j)
68 DO i = 1, nrows
69 i_sub = row_index(i)
70 CALL cp_fm_get_element(source_matrix, i_sub, j_sub, mval)
71 target_array(i + (j - 1)*nrows) = mval
72 END DO
73 END DO
74 END SUBROUTINE subspace_matrix_to_array
75
76! **************************************************************************************************
77!> \brief Copy the eri tensor for spins isp1 and isp2 to a standard 1D Fortran array
78!> \param eri_env the eri environment
79!> \param array the 1D Fortran array where the eri are copied to
80!> \param active_orbitals a list containing the active orbitals indices
81!> \param spin1 the spin of the bra
82!> \param spin2 the spin of the ket
83! **************************************************************************************************
84 SUBROUTINE eri_to_array(eri_env, array, active_orbitals, spin1, spin2)
85 TYPE(eri_type), INTENT(IN) :: eri_env
86 REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: array
87 INTEGER, DIMENSION(:, :), INTENT(IN) :: active_orbitals
88 INTEGER, INTENT(IN) :: spin1, spin2
89
90 INTEGER :: i, i1, i12, i12l, i2, i3, i34, i34l, i4, &
91 ijkl, ijlk, irptr, j, jikl, jilk, k, &
92 klij, klji, l, lkij, lkji, nindex, &
93 nmo_active, nmo_max
94 REAL(kind=dp) :: erival
95 TYPE(dbcsr_csr_type), POINTER :: eri
96 TYPE(mp_comm_type) :: mp_group
97
98 nmo_active = SIZE(active_orbitals, 1)
99 nmo_max = eri_env%norb
100 nindex = (nmo_max*(nmo_max + 1))/2
101 IF (spin1 == 1 .AND. spin2 == 1) THEN
102 eri => eri_env%eri(1)%csr_mat
103 ELSE IF ((spin1 == 1 .AND. spin2 == 2) .OR. (spin1 == 2 .AND. spin2 == 1)) THEN
104 eri => eri_env%eri(2)%csr_mat
105 ELSE
106 eri => eri_env%eri(3)%csr_mat
107 END IF
108
109 CALL mp_group%set_handle(eri%mp_group%get_handle())
110
111 array = 0.0_dp
112
113 DO i = 1, nmo_active
114 i1 = active_orbitals(i, spin1)
115 DO j = i, nmo_active
116 i2 = active_orbitals(j, spin1)
117 i12 = csr_idx_to_combined(i1, i2, nmo_max)
118 IF (mod(i12 - 1, eri_env%comm_exchange%num_pe) == eri_env%comm_exchange%mepos) THEN
119 i12l = (i12 - 1)/eri_env%comm_exchange%num_pe + 1
120 irptr = eri%rowptr_local(i12l) - 1
121 DO i34l = 1, eri%nzerow_local(i12l)
122 i34 = eri%colind_local(irptr + i34l)
123 CALL csr_idx_from_combined(i34, nmo_max, i3, i4)
124! The FINDLOC intrinsic function of the Fortran 2008 standard is only available since GCC 9
125! That is why we use a custom-made implementation of this function for this compiler
126#if __GNUC__ < 9
127 k = cp_findloc(active_orbitals(:, spin2), i3)
128 l = cp_findloc(active_orbitals(:, spin2), i4)
129#else
130 k = findloc(active_orbitals(:, spin2), i3, dim=1)
131 l = findloc(active_orbitals(:, spin2), i4, dim=1)
132#endif
133 erival = eri%nzval_local%r_dp(irptr + i34l)
134
135 ! 8-fold permutational symmetry
136 ijkl = i + (j - 1)*nmo_active + (k - 1)*nmo_active**2 + (l - 1)*nmo_active**3
137 jikl = j + (i - 1)*nmo_active + (k - 1)*nmo_active**2 + (l - 1)*nmo_active**3
138 ijlk = i + (j - 1)*nmo_active + (l - 1)*nmo_active**2 + (k - 1)*nmo_active**3
139 jilk = j + (i - 1)*nmo_active + (l - 1)*nmo_active**2 + (k - 1)*nmo_active**3
140 array(ijkl) = erival
141 array(jikl) = erival
142 array(ijlk) = erival
143 array(jilk) = erival
144 IF (spin1 == spin2) THEN
145 klij = k + (l - 1)*nmo_active + (i - 1)*nmo_active**2 + (j - 1)*nmo_active**3
146 lkij = l + (k - 1)*nmo_active + (i - 1)*nmo_active**2 + (j - 1)*nmo_active**3
147 klji = k + (l - 1)*nmo_active + (j - 1)*nmo_active**2 + (i - 1)*nmo_active**3
148 lkji = l + (k - 1)*nmo_active + (j - 1)*nmo_active**2 + (i - 1)*nmo_active**3
149 array(klij) = erival
150 array(lkij) = erival
151 array(klji) = erival
152 array(lkji) = erival
153 END IF
154 END DO
155 END IF
156 END DO
157 END DO
158 CALL mp_group%sum(array)
159
160 END SUBROUTINE eri_to_array
161
162#if __GNUC__ < 9
163! **************************************************************************************************
164!> \brief This function implements the FINDLOC function of the Fortran 2008 standard for the case needed above
165!> To be removed as soon GCC 8 is dropped.
166!> \param array ...
167!> \param value ...
168!> \return ...
169! **************************************************************************************************
170 PURE INTEGER FUNCTION cp_findloc(array, value) RESULT(loc)
171 INTEGER, DIMENSION(:), INTENT(IN) :: array
172 INTEGER, INTENT(IN) :: value
173
174 INTEGER :: idx
175
176 loc = 0
177
178 DO idx = 1, SIZE(array)
179 IF (array(idx) == value) THEN
180 loc = idx
181 RETURN
182 END IF
183 END DO
184
185 END FUNCTION cp_findloc
186#endif
187
188END MODULE qs_active_space_utils
static GRID_HOST_DEVICE int idx(const orbital a)
Return coset index of given orbital angular momentum.
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_get_element(matrix, irow_global, icol_global, alpha, local)
returns an element of a fm this value is valid on every cpu using this call is expensive
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Interface to the message passing library MPI.
The types needed for the calculation of active space Hamiltonians.
subroutine, public csr_idx_from_combined(ij, n, i, j)
extracts indices i and j from combined index ij
integer function, public csr_idx_to_combined(i, j, n)
calculates combined index (ij)
Contains utility routines for the active space module.
subroutine, public eri_to_array(eri_env, array, active_orbitals, spin1, spin2)
Copy the eri tensor for spins isp1 and isp2 to a standard 1D Fortran array.
subroutine, public subspace_matrix_to_array(source_matrix, target_array, row_index, col_index)
Copy a (square portion) of a cp_fm_type matrix to a standard 1D Fortran array.
represent a full matrix