(git:3add494)
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-2024 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_fm_types, ONLY: cp_fm_get_element,&
18  cp_fm_type
19  USE dbcsr_api, ONLY: dbcsr_csr_type
20  USE kinds, ONLY: dp
21  USE message_passing, ONLY: mp_comm_type
24  eri_type,&
26 #include "./base/base_uses.f90"
27 
28  IMPLICIT NONE
29 
30  PRIVATE
31 
32  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_active_space_utils'
33 
35 
36 CONTAINS
37 
38 ! **************************************************************************************************
39 !> \brief Copy a (square portion) of a `cp_fm_type` matrix to a standard 1D Fortran array
40 !> \param source_matrix the matrix from where the data is taken
41 !> \param target_array the array were the data is copied to
42 !> \param row_index a list containing the row subspace indices
43 !> \param col_index a list containing the column subspace indices
44 ! **************************************************************************************************
45  SUBROUTINE subspace_matrix_to_array(source_matrix, target_array, row_index, col_index)
46  TYPE(cp_fm_type), INTENT(IN) :: source_matrix
47  REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: target_array
48  INTEGER, DIMENSION(:), INTENT(IN) :: row_index, col_index
49 
50  INTEGER :: i, i_sub, j, j_sub, max_col, max_row, &
51  ncols, nrows
52  REAL(kind=dp) :: mval
53 
54  CALL cp_fm_get_info(source_matrix, nrow_global=max_row, ncol_global=max_col)
55  nrows = SIZE(row_index)
56  ncols = SIZE(col_index)
57 
58  cpassert(maxval(row_index) <= max_row)
59  cpassert(maxval(col_index) <= max_col)
60  cpassert(minval(row_index) > 0)
61  cpassert(minval(col_index) > 0)
62  cpassert(nrows <= max_row)
63  cpassert(ncols <= max_col)
64 
65  cpassert(SIZE(target_array) == nrows*ncols)
66 
67  DO j = 1, ncols
68  j_sub = col_index(j)
69  DO i = 1, nrows
70  i_sub = row_index(i)
71  CALL cp_fm_get_element(source_matrix, i_sub, j_sub, mval)
72  target_array(i + (j - 1)*nrows) = mval
73  END DO
74  END DO
75  END SUBROUTINE subspace_matrix_to_array
76 
77 ! **************************************************************************************************
78 !> \brief Copy the eri tensor for spins isp1 and isp2 to a standard 1D Fortran array
79 !> \param eri_env the eri environment
80 !> \param array the 1D Fortran array where the eri are copied to
81 !> \param active_orbitals a list containing the active orbitals indices
82 !> \param spin1 the spin of the bra
83 !> \param spin2 the spin of the ket
84 ! **************************************************************************************************
85  SUBROUTINE eri_to_array(eri_env, array, active_orbitals, spin1, spin2)
86  TYPE(eri_type), INTENT(IN) :: eri_env
87  REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: array
88  INTEGER, DIMENSION(:, :), INTENT(IN) :: active_orbitals
89  INTEGER, INTENT(IN) :: spin1, spin2
90 
91  INTEGER :: i, i1, i12, i12l, i2, i3, i34, i34l, i4, &
92  ijkl, ijlk, irptr, j, jikl, jilk, k, &
93  klij, klji, l, lkij, lkji, nindex, &
94  nmo_active, nmo_max
95  INTEGER, DIMENSION(2) :: irange
96  REAL(kind=dp) :: erival
97  TYPE(dbcsr_csr_type), POINTER :: eri
98  TYPE(mp_comm_type) :: mp_group
99 
100  nmo_active = SIZE(active_orbitals, 1)
101  nmo_max = eri_env%norb
102  nindex = (nmo_max*(nmo_max + 1))/2
103  IF (spin1 == 1 .AND. spin2 == 1) THEN
104  eri => eri_env%eri(1)%csr_mat
105  ELSE IF ((spin1 == 1 .AND. spin2 == 2) .OR. (spin1 == 2 .AND. spin2 == 1)) THEN
106  eri => eri_env%eri(2)%csr_mat
107  ELSE
108  eri => eri_env%eri(3)%csr_mat
109  END IF
110 
111  CALL mp_group%set_handle(eri%mp_group%get_handle())
112  irange = get_irange_csr(nindex, mp_group)
113 
114  array = 0.0_dp
115 
116  DO i = 1, nmo_active
117  i1 = active_orbitals(i, spin1)
118  DO j = i, nmo_active
119  i2 = active_orbitals(j, spin1)
120  i12 = csr_idx_to_combined(i1, i2, nmo_max)
121  IF (i12 >= irange(1) .AND. i12 <= irange(2)) THEN
122  i12l = i12 - irange(1) + 1
123  irptr = eri%rowptr_local(i12l) - 1
124  DO i34l = 1, eri%nzerow_local(i12l)
125  i34 = eri%colind_local(irptr + i34l)
126  CALL csr_idx_from_combined(i34, nmo_max, i3, i4)
127 ! The FINDLOC intrinsic function of the Fortran 2008 standard is only available since GCC 9
128 ! That is why we use a custom-made implementation of this function for this compiler
129 #if __GNUC__ < 9
130  k = cp_findloc(active_orbitals(:, spin2), i3)
131  l = cp_findloc(active_orbitals(:, spin2), i4)
132 #else
133  k = findloc(active_orbitals(:, spin2), i3, dim=1)
134  l = findloc(active_orbitals(:, spin2), i4, dim=1)
135 #endif
136  erival = eri%nzval_local%r_dp(irptr + i34l)
137 
138  ! 8-fold permutational symmetry
139  ijkl = i + (j - 1)*nmo_active + (k - 1)*nmo_active**2 + (l - 1)*nmo_active**3
140  jikl = j + (i - 1)*nmo_active + (k - 1)*nmo_active**2 + (l - 1)*nmo_active**3
141  ijlk = i + (j - 1)*nmo_active + (l - 1)*nmo_active**2 + (k - 1)*nmo_active**3
142  jilk = j + (i - 1)*nmo_active + (l - 1)*nmo_active**2 + (k - 1)*nmo_active**3
143  array(ijkl) = erival
144  array(jikl) = erival
145  array(ijlk) = erival
146  array(jilk) = erival
147  IF (spin1 == spin2) THEN
148  klij = k + (l - 1)*nmo_active + (i - 1)*nmo_active**2 + (j - 1)*nmo_active**3
149  lkij = l + (k - 1)*nmo_active + (i - 1)*nmo_active**2 + (j - 1)*nmo_active**3
150  klji = k + (l - 1)*nmo_active + (j - 1)*nmo_active**2 + (i - 1)*nmo_active**3
151  lkji = l + (k - 1)*nmo_active + (j - 1)*nmo_active**2 + (i - 1)*nmo_active**3
152  array(klij) = erival
153  array(lkij) = erival
154  array(klji) = erival
155  array(lkji) = erival
156  END IF
157  END DO
158  END IF
159  END DO
160  END DO
161  CALL mp_group%sum(array)
162 
163  END SUBROUTINE eri_to_array
164 
165 #if __GNUC__ < 9
166 ! **************************************************************************************************
167 !> \brief This function implements the FINDLOC function of the Fortran 2008 standard for the case needed above
168 !> To be removed as soon GCC 8 is dropped.
169 !> \param array ...
170 !> \param value ...
171 !> \return ...
172 ! **************************************************************************************************
173  PURE INTEGER FUNCTION cp_findloc(array, value) RESULT(loc)
174  INTEGER, DIMENSION(:), INTENT(IN) :: array
175  INTEGER, INTENT(IN) :: value
176 
177  INTEGER :: idx
178 
179  loc = 0
180 
181  DO idx = 1, SIZE(array)
182  IF (array(idx) == value) THEN
183  loc = idx
184  RETURN
185  END IF
186  END DO
187 
188  END FUNCTION cp_findloc
189 #endif
190 
191 END MODULE qs_active_space_utils
static GRID_HOST_DEVICE int idx(const orbital a)
Return coset index of given orbital angular momentum.
Definition: grid_common.h:153
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
Definition: cp_fm_types.F:1016
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
Definition: cp_fm_types.F:643
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)
integer function, dimension(2), public get_irange_csr(nindex, mp_group)
calculates index range for processor in group mp_group
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.