(git:97501a3)
Loading...
Searching...
No Matches
qs_active_space_types.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief The types needed for the calculation of active space Hamiltonians
10!> \par History
11!> 04.2016 created [JGH]
12!> \author JGH
13! **************************************************************************************************
15
16 USE cp_dbcsr_api, ONLY: dbcsr_csr_destroy,&
17 dbcsr_csr_p_type,&
20 USE cp_fm_types, ONLY: cp_fm_release,&
23 USE kinds, ONLY: default_path_length,&
24 dp
28#include "./base/base_uses.f90"
29
30 IMPLICIT NONE
31 PRIVATE
32
33 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_active_space_types'
34
38
39! **************************************************************************************************
40!> \brief Quantities needed for AS determination
41!> \author JGH
42! **************************************************************************************************
43 TYPE eri_gpw_type
44 LOGICAL :: redo_poisson = .false.
45 LOGICAL :: store_wfn = .false.
46 REAL(KIND=dp) :: cutoff = 0.0_dp
47 REAL(KIND=dp) :: rel_cutoff = 0.0_dp
48 REAL(KIND=dp) :: eps_grid = 0.0_dp
49 REAL(KIND=dp) :: eps_filter = 0.0_dp
50 INTEGER :: print_level = 0
51 INTEGER :: group_size = 0
52 END TYPE eri_gpw_type
53
55 INTEGER :: method = 0
56 INTEGER :: operator = 0
57 LOGICAL :: enlarge_cell = .false.
58 REAL(kind=dp) :: omega = 0.0_dp
59 INTEGER, DIMENSION(3) :: periodicity = 0
60 REAL(kind=dp), DIMENSION(3) :: eri_cell = 0
61 REAL(kind=dp), DIMENSION(3) :: eri_cell_angles = 0
62 REAL(kind=dp) :: cutoff_radius = 0.0_dp
63 REAL(kind=dp) :: eps_integral = 0.0_dp
64 TYPE(eri_gpw_type) :: eri_gpw = eri_gpw_type()
65 TYPE(dbcsr_csr_p_type), &
66 DIMENSION(:), POINTER :: eri => null()
67 INTEGER :: norb = 0
68
69 CONTAINS
70 PROCEDURE :: eri_foreach => eri_type_eri_foreach
71 END TYPE eri_type
72
73! **************************************************************************************************
74!> \brief Abstract function object for the `eri_type_eri_foreach` method
75! **************************************************************************************************
76 TYPE, ABSTRACT :: eri_type_eri_element_func
77 CONTAINS
78 PROCEDURE(eri_type_eri_element_func_interface), DEFERRED :: func
80
82 INTEGER :: nelec_active = 0
83 INTEGER :: nelec_inactive = 0
84 INTEGER :: nelec_total = 0
85 INTEGER, POINTER, DIMENSION(:, :) :: active_orbitals => null()
86 INTEGER, POINTER, DIMENSION(:, :) :: inactive_orbitals => null()
87 INTEGER :: nmo_active = 0
88 INTEGER :: nmo_inactive = 0
89 INTEGER :: multiplicity = 0
90 INTEGER :: nspins = 0
91 LOGICAL :: molecule = .false.
92 INTEGER :: model = 0
93 REAL(kind=dp) :: energy_total = 0.0_dp
94 REAL(kind=dp) :: energy_ref = 0.0_dp
95 REAL(kind=dp) :: energy_inactive = 0.0_dp
96 REAL(kind=dp) :: energy_active = 0.0_dp
97 REAL(kind=dp) :: alpha = 0.0_dp
98 LOGICAL :: do_scf_embedding = .false.
99 LOGICAL :: qcschema = .false.
100 LOGICAL :: fcidump = .false.
101 CHARACTER(LEN=default_path_length) :: qcschema_filename = ''
102 TYPE(eri_type) :: eri = eri_type()
103 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos_active => null()
104 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos_inactive => null()
105 TYPE(cp_fm_type), DIMENSION(:), POINTER :: p_active => null()
106 TYPE(cp_fm_type), DIMENSION(:), POINTER :: ks_sub => null()
107 TYPE(cp_fm_type), DIMENSION(:), POINTER :: vxc_sub => null()
108 TYPE(cp_fm_type), DIMENSION(:), POINTER :: h_sub => null()
109 TYPE(cp_fm_type), DIMENSION(:), POINTER :: fock_sub => null()
110 TYPE(cp_fm_type), DIMENSION(:), POINTER :: sab_sub => null()
111 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: pmat_inactive => null()
112 END TYPE active_space_type
113
114 abstract INTERFACE
115! **************************************************************************************************
116!> \brief The function signature to be implemented by a child of `eri_type_eri_element_func`
117!> \param this object reference
118!> \param i i-index
119!> \param j j-index
120!> \param k k-index
121!> \param l l-index
122!> \param val value of the integral at (i,j,k.l)
123!> \return True if the ERI foreach loop should continue, false, if not
124! **************************************************************************************************
125 LOGICAL FUNCTION eri_type_eri_element_func_interface(this, i, j, k, l, val)
127 CLASS(eri_type_eri_element_func), INTENT(inout) :: this
128 INTEGER, INTENT(in) :: i, j, k, l
129 REAL(kind=dp), INTENT(in) :: val
131 END INTERFACE
132
133! **************************************************************************************************
134
135CONTAINS
136
137! **************************************************************************************************
138!> \brief Creates an active space environment type, nullifying all quantities.
139!> \param active_space_env the active space environment to be initialized
140! **************************************************************************************************
141 SUBROUTINE create_active_space_type(active_space_env)
142 TYPE(active_space_type), POINTER :: active_space_env
143
144 IF (ASSOCIATED(active_space_env)) THEN
145 CALL release_active_space_type(active_space_env)
146 END IF
147
148 ALLOCATE (active_space_env)
149 NULLIFY (active_space_env%active_orbitals, active_space_env%inactive_orbitals)
150 NULLIFY (active_space_env%mos_active, active_space_env%mos_inactive)
151 NULLIFY (active_space_env%ks_sub, active_space_env%p_active)
152 NULLIFY (active_space_env%vxc_sub, active_space_env%h_sub)
153 NULLIFY (active_space_env%fock_sub, active_space_env%pmat_inactive)
154
155 END SUBROUTINE create_active_space_type
156
157! **************************************************************************************************
158!> \brief Releases all quantities in the active space environment.
159!> \param active_space_env the active space environment to be released
160! **************************************************************************************************
161 SUBROUTINE release_active_space_type(active_space_env)
162 TYPE(active_space_type), POINTER :: active_space_env
163
164 INTEGER :: imo
165
166 IF (ASSOCIATED(active_space_env)) THEN
167
168 IF (ASSOCIATED(active_space_env%active_orbitals)) THEN
169 DEALLOCATE (active_space_env%active_orbitals)
170 END IF
171
172 IF (ASSOCIATED(active_space_env%inactive_orbitals)) THEN
173 DEALLOCATE (active_space_env%inactive_orbitals)
174 END IF
175
176 IF (ASSOCIATED(active_space_env%mos_active)) THEN
177 DO imo = 1, SIZE(active_space_env%mos_active)
178 CALL deallocate_mo_set(active_space_env%mos_active(imo))
179 END DO
180 DEALLOCATE (active_space_env%mos_active)
181 END IF
182
183 IF (ASSOCIATED(active_space_env%mos_inactive)) THEN
184 DO imo = 1, SIZE(active_space_env%mos_inactive)
185 CALL deallocate_mo_set(active_space_env%mos_inactive(imo))
186 END DO
187 DEALLOCATE (active_space_env%mos_inactive)
188 END IF
189
190 CALL release_eri_type(active_space_env%eri)
191
192 CALL cp_fm_release(active_space_env%p_active)
193 CALL cp_fm_release(active_space_env%ks_sub)
194 CALL cp_fm_release(active_space_env%vxc_sub)
195 CALL cp_fm_release(active_space_env%h_sub)
196 CALL cp_fm_release(active_space_env%fock_sub)
197 CALL cp_fm_release(active_space_env%sab_sub)
198
199 IF (ASSOCIATED(active_space_env%pmat_inactive)) &
200 CALL dbcsr_deallocate_matrix_set(active_space_env%pmat_inactive)
201
202 DEALLOCATE (active_space_env)
203 END IF
204
205 END SUBROUTINE release_active_space_type
206
207! **************************************************************************************************
208!> \brief Releases the ERI environment type.
209!> \param eri_env the ERI environment to be released
210! **************************************************************************************************
211 SUBROUTINE release_eri_type(eri_env)
212 TYPE(eri_type) :: eri_env
213
214 INTEGER :: i
215
216 IF (ASSOCIATED(eri_env%eri)) THEN
217
218 DO i = 1, SIZE(eri_env%eri)
219 CALL dbcsr_csr_destroy(eri_env%eri(i)%csr_mat)
220 DEALLOCATE (eri_env%eri(i)%csr_mat)
221 END DO
222 DEALLOCATE (eri_env%eri)
223
224 END IF
225
226 END SUBROUTINE release_eri_type
227
228! **************************************************************************************************
229!> \brief calculates combined index (ij)
230!> \param i Index j
231!> \param j Index i
232!> \param n Dimension in i or j direction
233!> \returns The combined index
234!> \par History
235!> 04.2016 created [JGH]
236! **************************************************************************************************
237 INTEGER FUNCTION csr_idx_to_combined(i, j, n) RESULT(ij)
238 INTEGER, INTENT(IN) :: i, j, n
239
240 cpassert(i <= j)
241 cpassert(i <= n)
242 cpassert(j <= n)
243
244 ij = (i - 1)*n - ((i - 1)*(i - 2))/2 + (j - i + 1)
245
246 cpassert(ij <= (n*(n + 1))/2 .AND. 0 <= ij)
247
248 END FUNCTION csr_idx_to_combined
249
250! **************************************************************************************************
251!> \brief extracts indices i and j from combined index ij
252!> \param ij The combined index
253!> \param n Dimension in i or j direction
254!> \param i Resulting i index
255!> \param j Resulting j index
256!> \par History
257!> 04.2016 created [JGH]
258! **************************************************************************************************
259 SUBROUTINE csr_idx_from_combined(ij, n, i, j)
260 INTEGER, INTENT(IN) :: ij, n
261 INTEGER, INTENT(OUT) :: i, j
262
263 INTEGER :: m, m0
264
265 m = max(ij/n, 1)
266 DO i = m, n
267 m0 = (i - 1)*n - ((i - 1)*(i - 2))/2
268 j = ij - m0 + i - 1
269 IF (j <= n) EXIT
270 END DO
271
272 cpassert(i > 0 .AND. i <= n)
273 cpassert(j > 0 .AND. j <= n)
274 cpassert(i <= j)
275
276 END SUBROUTINE csr_idx_from_combined
277
278! **************************************************************************************************
279!> \brief calculates index range for processor in group mp_group
280!> \param nindex the number of indices
281!> \param mp_group message-passing group ID
282!> \return a range tuple
283!> \par History
284!> 04.2016 created [JGH]
285! **************************************************************************************************
286 FUNCTION get_irange_csr(nindex, mp_group) RESULT(irange)
288 INTEGER, INTENT(IN) :: nindex
289
290 CLASS(mp_comm_type), INTENT(IN) :: mp_group
291 INTEGER, DIMENSION(2) :: irange
292
293 REAL(kind=dp) :: rat
294
295 associate(numtask => mp_group%num_pe, taskid => mp_group%mepos)
296
297 IF (numtask == 1 .AND. taskid == 0) THEN
298 irange(1) = 1
299 irange(2) = nindex
300 ELSEIF (numtask >= nindex) THEN
301 IF (taskid >= nindex) THEN
302 irange(1) = 1
303 irange(2) = 0
304 ELSE
305 irange(1) = taskid + 1
306 irange(2) = taskid + 1
307 END IF
308 ELSE
309 rat = real(nindex, kind=dp)/real(numtask, kind=dp)
310 irange(1) = nint(rat*taskid) + 1
311 irange(2) = nint(rat*taskid + rat)
312 END IF
313 END associate
314
315 END FUNCTION get_irange_csr
316
317! **************************************************************************************************
318!> \brief Calls the provided function for each element in the ERI
319!> \param this object reference
320!> \param nspin The spin number
321!> \param active_orbitals the active orbital indices
322!> \param fobj The function object from which to call `func(i, j, k, l, val)`
323!> \param spin1 the first spin value
324!> \param spin2 the second spin value
325!> \par History
326!> 04.2016 created [JHU]
327!> 06.2016 factored out from qs_a_s_methods:fcidump [TMU]
328!> \note Calls MPI, must be executed on all ranks.
329! **************************************************************************************************
330 SUBROUTINE eri_type_eri_foreach(this, nspin, active_orbitals, fobj, spin1, spin2)
331 CLASS(eri_type), INTENT(in) :: this
332 CLASS(eri_type_eri_element_func) :: fobj
333 INTEGER, DIMENSION(:, :), INTENT(IN) :: active_orbitals
334 INTEGER, OPTIONAL :: spin1, spin2
335 INTEGER :: i1, i12, i12l, i2, i3, i34, i34l, i4, m1, m2, m3, m4, &
336 irange(2), irptr, nspin, nindex, nmo, proc, nonzero_elements_local
337 INTEGER, ALLOCATABLE, DIMENSION(:) :: colind, offsets, nonzero_elements_global
338 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: erival
339 REAL(kind=dp) :: erint
340 TYPE(mp_comm_type) :: mp_group
341
342 IF (.NOT. PRESENT(spin1)) THEN
343 spin1 = nspin
344 END IF
345 IF (.NOT. PRESENT(spin2)) THEN
346 spin2 = nspin
347 END IF
348
349 associate(eri => this%eri(nspin)%csr_mat, norb => this%norb)
350 nindex = (norb*(norb + 1))/2
351 CALL mp_group%set_handle(eri%mp_group%get_handle())
352 nmo = SIZE(active_orbitals, 1)
353 ! Irrelevant in case of half-transformed integrals
354 irange = get_irange_csr(nindex, mp_group)
355 ALLOCATE (erival(nindex), colind(nindex))
356
357 IF (this%method == eri_method_gpw_ht) THEN
358 ALLOCATE (offsets(0:mp_group%num_pe - 1), &
359 nonzero_elements_global(0:mp_group%num_pe - 1))
360 END IF
361
362 DO m1 = 1, nmo
363 i1 = active_orbitals(m1, spin1)
364 DO m2 = m1, nmo
365 i2 = active_orbitals(m2, spin1)
366 i12 = csr_idx_to_combined(i1, i2, norb)
367
368 IF (this%method == eri_method_gpw_ht) THEN
369 ! In case of half-transformed integrals, every process might carry integrals of a row
370 ! The number of integrals varies between processes and rows (related to the randomized
371 ! distribution of matrix blocks)
372
373 ! 1) Collect the amount of local data from each process
374 nonzero_elements_local = eri%nzerow_local(i12)
375 CALL mp_group%allgather(nonzero_elements_local, nonzero_elements_global)
376
377 ! 2) Prepare arrays for communication (calculate the offsets and the total number of elements)
378 offsets(0) = 0
379 DO proc = 1, mp_group%num_pe - 1
380 offsets(proc) = offsets(proc - 1) + nonzero_elements_global(proc - 1)
381 END DO
382 nindex = offsets(mp_group%num_pe - 1) + nonzero_elements_global(mp_group%num_pe - 1)
383 irptr = eri%rowptr_local(i12)
384
385 ! Exchange actual data
386 CALL mp_group%allgatherv(eri%colind_local(irptr:irptr + nonzero_elements_local - 1), &
387 colind(1:nindex), nonzero_elements_global, offsets)
388 CALL mp_group%allgatherv(eri%nzval_local%r_dp(irptr:irptr + nonzero_elements_local - 1), &
389 erival(1:nindex), nonzero_elements_global, offsets)
390 ELSE
391 ! Here, the rows are distributed among the processes such that each process
392 ! carries all integral of a set of rows
393 IF (i12 >= irange(1) .AND. i12 <= irange(2)) THEN
394 i12l = i12 - irange(1) + 1
395 irptr = eri%rowptr_local(i12l)
396 nindex = eri%nzerow_local(i12l)
397 colind(1:nindex) = eri%colind_local(irptr:irptr + nindex - 1)
398 erival(1:nindex) = eri%nzval_local%r_dp(irptr:irptr + nindex - 1)
399 ELSE
400 erival = 0.0_dp
401 colind = 0
402 nindex = 0
403 END IF
404
405 ! Thus, a simple summation is sufficient
406 CALL mp_group%sum(nindex)
407 CALL mp_group%sum(colind(1:nindex))
408 CALL mp_group%sum(erival(1:nindex))
409 END IF
410
411 DO i34l = 1, nindex
412 i34 = colind(i34l)
413 erint = erival(i34l)
414 CALL csr_idx_from_combined(i34, norb, i3, i4)
415
416 DO m3 = 1, nmo
417 IF (active_orbitals(m3, spin2) == i3) THEN
418 EXIT
419 END IF
420 END DO
421
422 DO m4 = 1, nmo
423 IF (active_orbitals(m4, spin2) == i4) THEN
424 EXIT
425 END IF
426 END DO
427
428 ! terminate the loop prematurely if the function returns false
429 IF (.NOT. fobj%func(m1, m2, m3, m4, erint)) RETURN
430 END DO
431
432 END DO
433 END DO
434 END associate
435 END SUBROUTINE eri_type_eri_foreach
436
437END MODULE qs_active_space_types
The function signature to be implemented by a child of eri_type_eri_element_func
DBCSR operations in CP2K.
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public eri_method_gpw_ht
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_path_length
Definition kinds.F:58
Interface to the message passing library MPI.
The module to read/write QCSchema HDF5 files for interfacing CP2K with other programs.
Definition qcschema.F:14
The types needed for the calculation of active space Hamiltonians.
subroutine, public release_active_space_type(active_space_env)
Releases all quantities in the active space environment.
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
subroutine, public create_active_space_type(active_space_env)
Creates an active space environment type, nullifying all quantities.
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
subroutine, public deallocate_mo_set(mo_set)
Deallocate a wavefunction data structure.
represent a full matrix
Abstract function object for the eri_type_eri_foreach method.