(git:744416f)
Loading...
Searching...
No Matches
rpa_main.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 Routines to calculate RI-RPA energy
10!> \par History
11!> 06.2012 created [Mauro Del Ben]
12!> 04.2015 GW routines added [Jan Wilhelm]
13!> 10.2015 Cubic-scaling RPA routines added [Jan Wilhelm]
14!> 10.2018 Cubic-scaling SOS-MP2 added [Frederick Stein]
15!> 03.2019 Refactoring [Frederick Stein]
16! **************************************************************************************************
18 USE bibliography, ONLY: &
25 USE cp_cfm_types, ONLY: cp_cfm_type
26 USE cp_dbcsr_api, ONLY: dbcsr_add,&
35 USE cp_fm_types, ONLY: cp_fm_create,&
41 USE dbt_api, ONLY: dbt_type
48 maxsize,&
50 USE hfx_types, ONLY: block_ind_type,&
59 USE kinds, ONLY: dp,&
60 int_8
61 USE kpoint_types, ONLY: get_kpoint_info,&
64 USE machine, ONLY: m_flush,&
66 USE mathconstants, ONLY: pi,&
67 z_zero
68 USE message_passing, ONLY: mp_comm_type,&
73 USE mp2_ri_grad_util, ONLY: array2fm
74 USE mp2_types, ONLY: mp2_type,&
80 USE qs_mo_types, ONLY: get_mo_set,&
84 USE rpa_grad, ONLY: rpa_grad_copy_q,&
90 USE rpa_gw, ONLY: allocate_matrices_gw,&
116 calc_mat_q,&
125 USE util, ONLY: get_limit
126#include "./base/base_uses.f90"
127
128 IMPLICIT NONE
129
130 PRIVATE
131
132 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'rpa_main'
133
134 PUBLIC :: rpa_ri_compute_en
135
136CONTAINS
137
138! **************************************************************************************************
139!> \brief ...
140!> \param qs_env ...
141!> \param Erpa ...
142!> \param mp2_env ...
143!> \param BIb_C ...
144!> \param BIb_C_gw ...
145!> \param BIb_C_bse_ij ...
146!> \param BIb_C_bse_ab ...
147!> \param para_env ...
148!> \param para_env_sub ...
149!> \param color_sub ...
150!> \param gd_array ...
151!> \param gd_B_virtual ...
152!> \param gd_B_all ...
153!> \param gd_B_occ_bse ...
154!> \param gd_B_virt_bse ...
155!> \param mo_coeff ...
156!> \param fm_matrix_PQ ...
157!> \param fm_matrix_L_kpoints ...
158!> \param fm_matrix_Minv_L_kpoints ...
159!> \param fm_matrix_Minv ...
160!> \param fm_matrix_Minv_Vtrunc_Minv ...
161!> \param kpoints ...
162!> \param Eigenval ...
163!> \param nmo ...
164!> \param homo ...
165!> \param dimen_RI ...
166!> \param dimen_RI_red ...
167!> \param gw_corr_lev_occ ...
168!> \param gw_corr_lev_virt ...
169!> \param bse_lev_virt ...
170!> \param unit_nr ...
171!> \param do_ri_sos_laplace_mp2 ...
172!> \param my_do_gw ...
173!> \param do_im_time ...
174!> \param do_bse ...
175!> \param matrix_s ...
176!> \param mat_munu ...
177!> \param mat_P_global ...
178!> \param t_3c_M ...
179!> \param t_3c_O ...
180!> \param t_3c_O_compressed ...
181!> \param t_3c_O_ind ...
182!> \param starts_array_mc ...
183!> \param ends_array_mc ...
184!> \param starts_array_mc_block ...
185!> \param ends_array_mc_block ...
186!> \param calc_forces ...
187! **************************************************************************************************
188 SUBROUTINE rpa_ri_compute_en(qs_env, Erpa, mp2_env, BIb_C, BIb_C_gw, BIb_C_bse_ij, BIb_C_bse_ab, &
189 para_env, para_env_sub, color_sub, &
190 gd_array, gd_B_virtual, gd_B_all, gd_B_occ_bse, gd_B_virt_bse, &
191 mo_coeff, fm_matrix_PQ, fm_matrix_L_kpoints, fm_matrix_Minv_L_kpoints, &
192 fm_matrix_Minv, fm_matrix_Minv_Vtrunc_Minv, kpoints, &
193 Eigenval, nmo, homo, dimen_RI, dimen_RI_red, gw_corr_lev_occ, gw_corr_lev_virt, &
194 bse_lev_virt, &
195 unit_nr, do_ri_sos_laplace_mp2, my_do_gw, do_im_time, do_bse, matrix_s, &
196 mat_munu, mat_P_global, t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, &
197 starts_array_mc, ends_array_mc, &
198 starts_array_mc_block, ends_array_mc_block, calc_forces)
199
200 TYPE(qs_environment_type), POINTER :: qs_env
201 REAL(kind=dp), INTENT(OUT) :: erpa
202 TYPE(mp2_type), INTENT(INOUT) :: mp2_env
203 TYPE(three_dim_real_array), DIMENSION(:), &
204 INTENT(INOUT) :: bib_c, bib_c_gw, bib_c_bse_ij, &
205 bib_c_bse_ab
206 TYPE(mp_para_env_type), POINTER :: para_env, para_env_sub
207 INTEGER, INTENT(INOUT) :: color_sub
208 TYPE(group_dist_d1_type), INTENT(INOUT) :: gd_array
209 TYPE(group_dist_d1_type), DIMENSION(:), &
210 INTENT(INOUT) :: gd_b_virtual
211 TYPE(group_dist_d1_type), INTENT(INOUT) :: gd_b_all
212 TYPE(group_dist_d1_type), DIMENSION(:), &
213 INTENT(INOUT) :: gd_b_occ_bse, gd_b_virt_bse
214 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff
215 TYPE(cp_fm_type), INTENT(IN) :: fm_matrix_pq
216 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_matrix_l_kpoints, &
217 fm_matrix_minv_l_kpoints, &
218 fm_matrix_minv, &
219 fm_matrix_minv_vtrunc_minv
220 TYPE(kpoint_type), POINTER :: kpoints
221 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :), &
222 INTENT(INOUT) :: eigenval
223 INTEGER, INTENT(IN) :: nmo
224 INTEGER, DIMENSION(:), INTENT(IN) :: homo
225 INTEGER, INTENT(IN) :: dimen_ri, dimen_ri_red
226 INTEGER, DIMENSION(:), INTENT(IN) :: gw_corr_lev_occ, gw_corr_lev_virt, &
227 bse_lev_virt
228 INTEGER, INTENT(IN) :: unit_nr
229 LOGICAL, INTENT(IN) :: do_ri_sos_laplace_mp2, my_do_gw, &
230 do_im_time, do_bse
231 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
232 TYPE(dbcsr_p_type), INTENT(IN) :: mat_munu
233 TYPE(dbcsr_p_type), INTENT(INOUT) :: mat_p_global
234 TYPE(dbt_type) :: t_3c_m
235 TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :) :: t_3c_o
236 TYPE(hfx_compression_type), ALLOCATABLE, &
237 DIMENSION(:, :, :), INTENT(INOUT) :: t_3c_o_compressed
238 TYPE(block_ind_type), ALLOCATABLE, &
239 DIMENSION(:, :, :), INTENT(INOUT) :: t_3c_o_ind
240 INTEGER, ALLOCATABLE, DIMENSION(:), INTENT(IN) :: starts_array_mc, ends_array_mc, &
241 starts_array_mc_block, &
242 ends_array_mc_block
243 LOGICAL, INTENT(IN) :: calc_forces
244
245 CHARACTER(LEN=*), PARAMETER :: routinen = 'rpa_ri_compute_en'
246
247 INTEGER :: best_integ_group_size, best_num_integ_point, color_rpa_group, dimen_nm_gw, &
248 dimen_virt_square, handle, handle2, handle3, ierr, iib, input_num_integ_groups, &
249 integ_group_size, ispin, jjb, min_integ_group_size, my_group_l_end, my_group_l_size, &
250 my_group_l_start, my_nm_gw_end, my_nm_gw_size, my_nm_gw_start, ncol_block_mat, ngroup, &
251 nrow_block_mat, nspins, num_integ_group, num_integ_points, pos_integ_group
252 INTEGER(KIND=int_8) :: mem
253 INTEGER, ALLOCATABLE, DIMENSION(:) :: dimen_homo_square, dimen_ia, my_ab_comb_bse_end, &
254 my_ab_comb_bse_size, my_ab_comb_bse_start, my_ia_end, my_ia_size, my_ia_start, &
255 my_ij_comb_bse_end, my_ij_comb_bse_size, my_ij_comb_bse_start, virtual
256 LOGICAL :: do_kpoints_from_gamma, do_minimax_quad, &
257 my_open_shell, skip_integ_group_opt
258 REAL(kind=dp) :: allowed_memory, avail_mem, e_range, emax, emin, mem_for_iak, mem_for_qk, &
259 mem_min, mem_per_group, mem_per_rank, mem_per_repl, mem_real
260 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: eigenval_kp
261 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_mat_q, fm_mat_q_gemm, fm_mat_s, &
262 fm_mat_s_ab_bse, fm_mat_s_gw, &
263 fm_mat_s_ij_bse
264 TYPE(cp_fm_type), DIMENSION(1) :: fm_mat_r_gw
265 TYPE(mp_para_env_type), POINTER :: para_env_rpa
266 TYPE(two_dim_real_array), ALLOCATABLE, &
267 DIMENSION(:) :: bib_c_2d, bib_c_2d_bse_ab, &
268 bib_c_2d_bse_ij, bib_c_2d_gw
269
270 CALL timeset(routinen, handle)
271
272 CALL cite_reference(delben2013)
273 CALL cite_reference(delben2015)
274
275 IF (mp2_env%ri_rpa%exchange_correction == rpa_exchange_axk) THEN
276 CALL cite_reference(bates2013)
277 ELSE IF (mp2_env%ri_rpa%exchange_correction == rpa_exchange_sosex) THEN
278 CALL cite_reference(freeman1977)
279 CALL cite_reference(gruneis2009)
280 END IF
281 IF (mp2_env%ri_rpa%do_rse) THEN
282 CALL cite_reference(ren2011)
283 CALL cite_reference(ren2013)
284 END IF
285
286 IF (my_do_gw) THEN
287 CALL cite_reference(wilhelm2016a)
288 CALL cite_reference(wilhelm2017)
289 CALL cite_reference(wilhelm2018)
290 END IF
291
292 IF (do_im_time) THEN
293 CALL cite_reference(wilhelm2016b)
294 END IF
295
296 nspins = SIZE(homo)
297 my_open_shell = (nspins == 2)
298 ALLOCATE (virtual(nspins), dimen_ia(nspins), my_ia_end(nspins), my_ia_start(nspins), my_ia_size(nspins))
299 virtual(:) = nmo - homo(:)
300 dimen_ia(:) = virtual(:)*homo(:)
301
302 ALLOCATE (eigenval_kp(nmo, 1, nspins))
303 eigenval_kp(:, 1, :) = eigenval(:, :)
304
305 IF (do_im_time) mp2_env%ri_rpa%minimax_quad = .true.
306 do_minimax_quad = mp2_env%ri_rpa%minimax_quad
307
308 IF (do_ri_sos_laplace_mp2) THEN
309 num_integ_points = mp2_env%ri_laplace%n_quadrature
310 input_num_integ_groups = mp2_env%ri_laplace%num_integ_groups
311
312 ! check the range for the minimax approximation
313 e_range = mp2_env%e_range
314 IF (mp2_env%e_range <= 1.0_dp .OR. mp2_env%e_gap <= 0.0_dp) THEN
315 emin = huge(dp)
316 emax = 0.0_dp
317 DO ispin = 1, nspins
318 IF (homo(ispin) > 0) THEN
319 emin = min(emin, 2.0_dp*(eigenval(homo(ispin) + 1, ispin) - eigenval(homo(ispin), ispin)))
320 emax = max(emax, 2.0_dp*(maxval(eigenval(:, ispin)) - minval(eigenval(:, ispin))))
321 END IF
322 END DO
323 e_range = emax/emin
324 END IF
325 IF (e_range < 2.0_dp) e_range = 2.0_dp
326 ierr = 0
327 CALL check_exp_minimax_range(num_integ_points, e_range, ierr)
328 IF (ierr /= 0) THEN
329 jjb = num_integ_points - 1
330 DO iib = 1, jjb
331 num_integ_points = num_integ_points - 1
332 ierr = 0
333 CALL check_exp_minimax_range(num_integ_points, e_range, ierr)
334 IF (ierr == 0) EXIT
335 END DO
336 END IF
337 cpassert(num_integ_points >= 1)
338 ELSE
339 num_integ_points = mp2_env%ri_rpa%rpa_num_quad_points
340 input_num_integ_groups = mp2_env%ri_rpa%rpa_num_integ_groups
341 IF (my_do_gw .AND. do_minimax_quad) THEN
342 IF (num_integ_points > 34) THEN
343 IF (unit_nr > 0) THEN
344 CALL cp_warn(__location__, &
345 "The required number of quadrature point exceeds the maximum possible in the "// &
346 "Minimax quadrature scheme. The number of quadrature point has been reset to 30.")
347 END IF
348 num_integ_points = 30
349 END IF
350 ELSE
351 IF (do_minimax_quad .AND. num_integ_points > 20) THEN
352 IF (unit_nr > 0) THEN
353 CALL cp_warn(__location__, &
354 "The required number of quadrature point exceeds the maximum possible in the "// &
355 "Minimax quadrature scheme. The number of quadrature point has been reset to 20.")
356 END IF
357 num_integ_points = 20
358 END IF
359 END IF
360 END IF
361 allowed_memory = mp2_env%mp2_memory
362
363 CALL get_group_dist(gd_array, color_sub, my_group_l_start, my_group_l_end, my_group_l_size)
364
365 ngroup = para_env%num_pe/para_env_sub%num_pe
366
367 ! for imaginary time or periodic GW or BSE, we use all processors for a single frequency/time point
368 IF (do_im_time .OR. mp2_env%ri_g0w0%do_periodic .OR. do_bse) THEN
369
370 integ_group_size = ngroup
371 best_num_integ_point = num_integ_points
372
373 ELSE
374
375 ! Calculate available memory and create integral group according to that
376 ! mem_for_iaK is the memory needed for storing the 3 centre integrals
377 mem_for_iak = real(sum(dimen_ia), kind=dp)*dimen_ri_red*8.0_dp/(1024_dp**2)
378 mem_for_qk = real(dimen_ri_red, kind=dp)*nspins*dimen_ri_red*8.0_dp/(1024_dp**2)
379
380 CALL m_memory(mem)
381 mem_real = (mem + 1024*1024 - 1)/(1024*1024)
382 CALL para_env%min(mem_real)
383
384 mem_per_rank = 0.0_dp
385
386 ! B_ia_P
387 mem_per_repl = mem_for_iak
388 ! Q (regular and for dgemm)
389 mem_per_repl = mem_per_repl + 2.0_dp*mem_for_qk
390
391 IF (calc_forces) CALL rpa_grad_needed_mem(homo, virtual, dimen_ri_red, mem_per_rank, mem_per_repl, do_ri_sos_laplace_mp2)
392 CALL rpa_exchange_needed_mem(mp2_env, homo, virtual, dimen_ri_red, para_env, mem_per_rank, mem_per_repl)
393
394 mem_min = mem_per_repl/para_env%num_pe + mem_per_rank
395
396 IF (unit_nr > 0) THEN
397 WRITE (unit_nr, '(T3,A,T68,F9.2,A4)') 'RI_INFO| Minimum required memory per MPI process:', mem_min, ' MiB'
398 WRITE (unit_nr, '(T3,A,T68,F9.2,A4)') 'RI_INFO| Available memory per MPI process:', mem_real, ' MiB'
399 END IF
400
401 ! Use only the allowed amount of memory
402 mem_real = min(mem_real, allowed_memory)
403 ! For the memory estimate, we require the amount of required memory per replication group and the available memory
404 mem_real = mem_real - mem_per_rank
405
406 mem_per_group = mem_real*para_env_sub%num_pe
407
408 ! here we try to find the best rpa/laplace group size
409 skip_integ_group_opt = .false.
410
411 ! Check the input number of integration groups
412 IF (input_num_integ_groups > 0) THEN
413 IF (num_integ_points < input_num_integ_groups) THEN
414 IF (mod(ngroup, input_num_integ_groups) == 0) THEN
415 best_integ_group_size = ngroup/input_num_integ_groups
416 best_num_integ_point = (num_integ_points + input_num_integ_groups - 1)/input_num_integ_groups
417 skip_integ_group_opt = .true.
418 ELSE
419 IF (unit_nr > 0) WRITE (unit_nr, '(T3,A)') 'Total number of groups not multiple of NUM_INTEG_GROUPS'
420 END IF
421 ELSE
422 IF (unit_nr > 0) WRITE (unit_nr, '(T3,A)') 'Too many integration groups for the given number of quadrature points'
423 END IF
424 END IF
425
426 IF (.NOT. skip_integ_group_opt) THEN
427 best_integ_group_size = ngroup
428 best_num_integ_point = num_integ_points
429
430 min_integ_group_size = max(1, ngroup/num_integ_points)
431
432 integ_group_size = min_integ_group_size - 1
433 DO iib = min_integ_group_size + 1, ngroup
434 integ_group_size = integ_group_size + 1
435
436 ! check that the ngroup is a multiple of integ_group_size
437 IF (mod(ngroup, integ_group_size) /= 0) cycle
438
439 ! check for memory
440 avail_mem = integ_group_size*mem_per_group
441 IF (avail_mem < mem_per_repl) cycle
442
443 ! check that the integration groups have the same size
444 num_integ_group = ngroup/integ_group_size
445
446 best_num_integ_point = (num_integ_points + num_integ_group - 1)/num_integ_group
447 best_integ_group_size = integ_group_size
448
449 EXIT
450
451 END DO
452 END IF
453
454 integ_group_size = best_integ_group_size
455
456 END IF
457
458 IF (unit_nr > 0 .AND. .NOT. do_im_time) THEN
459 IF (do_ri_sos_laplace_mp2) THEN
460 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
461 "RI_INFO| Group size for laplace numerical integration:", integ_group_size*para_env_sub%num_pe
462 WRITE (unit=unit_nr, fmt="(T3,A)") &
463 "INTEG_INFO| MINIMAX approximation"
464 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
465 "INTEG_INFO| Number of integration points:", num_integ_points
466 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
467 "INTEG_INFO| Max. number of integration points per Laplace group:", best_num_integ_point
468 ELSE
469 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
470 "RI_INFO| Group size for frequency integration:", integ_group_size*para_env_sub%num_pe
471 IF (do_minimax_quad) THEN
472 WRITE (unit=unit_nr, fmt="(T3,A)") &
473 "INTEG_INFO| MINIMAX quadrature"
474 ELSE
475 WRITE (unit=unit_nr, fmt="(T3,A)") &
476 "INTEG_INFO| Clenshaw-Curtius quadrature"
477 END IF
478 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
479 "INTEG_INFO| Number of integration points:", num_integ_points
480 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
481 "INTEG_INFO| Max. number of integration points per RPA group:", best_num_integ_point
482 END IF
483 CALL m_flush(unit_nr)
484 END IF
485
486 num_integ_group = ngroup/integ_group_size
487
488 pos_integ_group = mod(color_sub, integ_group_size)
489 color_rpa_group = color_sub/integ_group_size
490
491 CALL timeset(routinen//"_reorder", handle2)
492
493 ! not necessary for imaginary time
494
495 ALLOCATE (bib_c_2d(nspins))
496
497 IF (.NOT. do_im_time) THEN
498
499 ! reorder the local data in such a way to help the next stage of matrix creation
500 ! now the data inside the group are divided into a ia x K matrix
501 DO ispin = 1, nspins
502 CALL calculate_bib_c_2d(bib_c_2d(ispin)%array, bib_c(ispin)%array, para_env_sub, dimen_ia(ispin), &
503 homo(ispin), virtual(ispin), gd_b_virtual(ispin), &
504 my_ia_size(ispin), my_ia_start(ispin), my_ia_end(ispin), my_group_l_size)
505
506 DEALLOCATE (bib_c(ispin)%array)
507 CALL release_group_dist(gd_b_virtual(ispin))
508
509 END DO
510
511 ! in the GW case, BIb_C_2D_gw is an nm x K matrix, with n: number of corr GW levels, m=nmo
512 IF (my_do_gw) THEN
513 ALLOCATE (bib_c_2d_gw(nspins))
514
515 CALL timeset(routinen//"_reorder_gw", handle3)
516
517 dimen_nm_gw = nmo*(gw_corr_lev_occ(1) + gw_corr_lev_virt(1))
518
519 ! The same for open shell
520 DO ispin = 1, nspins
521 CALL calculate_bib_c_2d(bib_c_2d_gw(ispin)%array, bib_c_gw(ispin)%array, para_env_sub, dimen_nm_gw, &
522 gw_corr_lev_occ(ispin) + gw_corr_lev_virt(ispin), nmo, gd_b_all, &
523 my_nm_gw_size, my_nm_gw_start, my_nm_gw_end, my_group_l_size)
524 DEALLOCATE (bib_c_gw(ispin)%array)
525 END DO
526
527 CALL release_group_dist(gd_b_all)
528
529 CALL timestop(handle3)
530
531 END IF
532 END IF
533
534 IF (do_bse) THEN
535
536 CALL timeset(routinen//"_reorder_bse1", handle3)
537
538 ALLOCATE (bib_c_2d_bse_ij(nspins), bib_c_2d_bse_ab(nspins))
539 ALLOCATE (dimen_homo_square(nspins))
540 ALLOCATE (my_ij_comb_bse_size(nspins), my_ij_comb_bse_start(nspins), my_ij_comb_bse_end(nspins))
541 ALLOCATE (my_ab_comb_bse_size(nspins), my_ab_comb_bse_start(nspins), my_ab_comb_bse_end(nspins))
542
543 ! We do not implement an explicit bse_lev_occ different to homo here, because the small number of occupied levels
544 ! does not critically influence the memory
545 DO ispin = 1, nspins
546 dimen_homo_square(ispin) = homo(ispin)**2
547 CALL calculate_bib_c_2d(bib_c_2d_bse_ij(ispin)%array, bib_c_bse_ij(ispin)%array, para_env_sub, &
548 dimen_homo_square(ispin), homo(ispin), homo(ispin), gd_b_occ_bse(ispin), &
549 my_ij_comb_bse_size(ispin), my_ij_comb_bse_start(ispin), &
550 my_ij_comb_bse_end(ispin), my_group_l_size)
551 DEALLOCATE (bib_c_bse_ij(ispin)%array)
552 CALL release_group_dist(gd_b_occ_bse(ispin))
553 END DO
554
555 CALL timestop(handle3)
556
557 CALL timeset(routinen//"_reorder_bse2", handle3)
558
559 ! bse_lev_virt(ispin) (hence dimen_virt_square) and gd_B_virt_bse(ispin) are per-spin
560 DO ispin = 1, nspins
561 dimen_virt_square = bse_lev_virt(ispin)**2
562 CALL calculate_bib_c_2d(bib_c_2d_bse_ab(ispin)%array, bib_c_bse_ab(ispin)%array, para_env_sub, &
563 dimen_virt_square, bse_lev_virt(ispin), bse_lev_virt(ispin), gd_b_virt_bse(ispin), &
564 my_ab_comb_bse_size(ispin), my_ab_comb_bse_start(ispin), &
565 my_ab_comb_bse_end(ispin), my_group_l_size)
566 DEALLOCATE (bib_c_bse_ab(ispin)%array)
567 CALL release_group_dist(gd_b_virt_bse(ispin))
568 END DO
569
570 CALL timestop(handle3)
571
572 END IF
573
574 CALL timestop(handle2)
575
576 IF (num_integ_group > 1) THEN
577 ALLOCATE (para_env_rpa)
578 CALL para_env_rpa%from_split(para_env, color_rpa_group)
579 ELSE
580 para_env_rpa => para_env
581 END IF
582
583 ! now create the matrices needed for the calculation, Q, S and G
584 ! Q and G will have omega dependence
585
586 IF (do_im_time) THEN
587 ALLOCATE (fm_mat_q(nspins), fm_mat_q_gemm(1), fm_mat_s(1))
588 ELSE
589 ALLOCATE (fm_mat_q(nspins), fm_mat_q_gemm(nspins), fm_mat_s(nspins))
590 END IF
591
592 CALL create_integ_mat(bib_c_2d, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
593 dimen_ri_red, dimen_ia, color_rpa_group, &
594 mp2_env%block_size_row, mp2_env%block_size_col, unit_nr, &
595 my_ia_size, my_ia_start, my_ia_end, &
596 my_group_l_size, my_group_l_start, my_group_l_end, &
597 para_env_rpa, fm_mat_s, nrow_block_mat, ncol_block_mat, &
598 dimen_ia_for_block_size=dimen_ia(1), &
599 do_im_time=do_im_time, fm_mat_q_gemm=fm_mat_q_gemm, fm_mat_q=fm_mat_q, qs_env=qs_env)
600
601 DEALLOCATE (bib_c_2d, my_ia_end, my_ia_size, my_ia_start)
602
603 ! for GW, we need other matrix fm_mat_S, always allocate the container to prevent crying compilers
604 ALLOCATE (fm_mat_s_gw(nspins))
605 IF (my_do_gw .AND. .NOT. do_im_time) THEN
606
607 CALL create_integ_mat(bib_c_2d_gw, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
608 dimen_ri_red, [dimen_nm_gw, dimen_nm_gw], color_rpa_group, &
609 mp2_env%block_size_row, mp2_env%block_size_col, unit_nr, &
610 [my_nm_gw_size, my_nm_gw_size], [my_nm_gw_start, my_nm_gw_start], [my_nm_gw_end, my_nm_gw_end], &
611 my_group_l_size, my_group_l_start, my_group_l_end, &
612 para_env_rpa, fm_mat_s_gw, nrow_block_mat, ncol_block_mat, &
613 fm_mat_q(1)%matrix_struct%context, fm_mat_q(1)%matrix_struct%context, &
614 fm_mat_q=fm_mat_r_gw)
615 DEALLOCATE (bib_c_2d_gw)
616
617 END IF
618
619 ! for Bethe-Salpeter, we need other matrix fm_mat_S (per spin; the ab slab dimension is spin-independent)
620 IF (do_bse) THEN
621 ALLOCATE (fm_mat_s_ij_bse(nspins), fm_mat_s_ab_bse(nspins))
622 CALL create_integ_mat(bib_c_2d_bse_ij, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
623 dimen_ri_red, dimen_homo_square, color_rpa_group, &
624 mp2_env%block_size_row, mp2_env%block_size_col, unit_nr, &
625 my_ij_comb_bse_size, my_ij_comb_bse_start, my_ij_comb_bse_end, &
626 my_group_l_size, my_group_l_start, my_group_l_end, &
627 para_env_rpa, fm_mat_s_ij_bse, nrow_block_mat, ncol_block_mat, &
628 fm_mat_q(1)%matrix_struct%context, fm_mat_q(1)%matrix_struct%context)
629
630 CALL create_integ_mat(bib_c_2d_bse_ab, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
631 dimen_ri_red, [(bse_lev_virt(ispin)**2, ispin=1, nspins)], color_rpa_group, &
632 mp2_env%block_size_row, mp2_env%block_size_col, unit_nr, &
633 my_ab_comb_bse_size, my_ab_comb_bse_start, my_ab_comb_bse_end, &
634 my_group_l_size, my_group_l_start, my_group_l_end, &
635 para_env_rpa, fm_mat_s_ab_bse, nrow_block_mat, ncol_block_mat, &
636 fm_mat_q(1)%matrix_struct%context, fm_mat_q(1)%matrix_struct%context)
637
638 END IF
639
640 do_kpoints_from_gamma = qs_env%mp2_env%ri_rpa_im_time%do_kpoints_from_Gamma
641 IF (do_kpoints_from_gamma) THEN
642 CALL get_bandstruc_and_k_dependent_mos(qs_env, eigenval_kp)
643 END IF
644
645 ! Now start the RPA calculation
646 ! cfm_mo_coeff will be deallocated here
647 CALL rpa_num_int(qs_env, erpa, mp2_env, para_env, para_env_rpa, para_env_sub, unit_nr, &
648 homo, virtual, dimen_ri, dimen_ri_red, dimen_ia, dimen_nm_gw, &
649 eigenval_kp, num_integ_points, num_integ_group, color_rpa_group, &
650 fm_matrix_pq, fm_mat_s, fm_mat_q_gemm, fm_mat_q, fm_mat_s_gw, fm_mat_r_gw(1), &
651 fm_mat_s_ij_bse, fm_mat_s_ab_bse, &
652 my_do_gw, do_bse, gw_corr_lev_occ, gw_corr_lev_virt, &
653 bse_lev_virt, &
654 do_minimax_quad, &
655 do_im_time, mo_coeff, &
656 fm_matrix_l_kpoints, fm_matrix_minv_l_kpoints, &
657 fm_matrix_minv, fm_matrix_minv_vtrunc_minv, mat_munu, mat_p_global, &
658 t_3c_m, t_3c_o, t_3c_o_compressed, t_3c_o_ind, &
659 starts_array_mc, ends_array_mc, &
660 starts_array_mc_block, ends_array_mc_block, &
661 matrix_s, do_kpoints_from_gamma, kpoints, gd_array, color_sub, &
662 do_ri_sos_laplace_mp2=do_ri_sos_laplace_mp2, calc_forces=calc_forces)
663
664 CALL release_group_dist(gd_array)
665
666 IF (num_integ_group > 1) CALL mp_para_env_release(para_env_rpa)
667
668 IF (.NOT. do_im_time) THEN
669 CALL cp_fm_release(fm_mat_q_gemm)
670 CALL cp_fm_release(fm_mat_s)
671 END IF
672 CALL cp_fm_release(fm_mat_q)
673
674 IF (my_do_gw .AND. .NOT. do_im_time) THEN
675 CALL cp_fm_release(fm_mat_s_gw)
676 CALL cp_fm_release(fm_mat_r_gw(1))
677 END IF
678
679 IF (do_bse) THEN
680 DO ispin = 1, nspins
681 CALL cp_fm_release(fm_mat_s_ij_bse(ispin))
682 CALL cp_fm_release(fm_mat_s_ab_bse(ispin))
683 END DO
684 DEALLOCATE (fm_mat_s_ij_bse, fm_mat_s_ab_bse)
685 END IF
686
687 CALL timestop(handle)
688
689 END SUBROUTINE rpa_ri_compute_en
690
691! **************************************************************************************************
692!> \brief reorder the local data in such a way to help the next stage of matrix creation;
693!> now the data inside the group are divided into a ia x K matrix (BIb_C_2D);
694!> Subroutine created to avoid massive double coding
695!> \param BIb_C_2D ...
696!> \param BIb_C ...
697!> \param para_env_sub ...
698!> \param dimen_ia ...
699!> \param homo ...
700!> \param virtual ...
701!> \param gd_B_virtual ...
702!> \param my_ia_size ...
703!> \param my_ia_start ...
704!> \param my_ia_end ...
705!> \param my_group_L_size ...
706!> \author Jan Wilhelm, 03/2015
707! **************************************************************************************************
708 SUBROUTINE calculate_bib_c_2d(BIb_C_2D, BIb_C, para_env_sub, dimen_ia, homo, virtual, &
709 gd_B_virtual, &
710 my_ia_size, my_ia_start, my_ia_end, my_group_L_size)
711
712 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :), &
713 INTENT(OUT) :: bib_c_2d
714 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :), &
715 INTENT(IN) :: bib_c
716 TYPE(mp_para_env_type), INTENT(IN) :: para_env_sub
717 INTEGER, INTENT(IN) :: dimen_ia, homo, virtual
718 TYPE(group_dist_d1_type), INTENT(INOUT) :: gd_b_virtual
719 INTEGER :: my_ia_size, my_ia_start, my_ia_end, &
720 my_group_l_size
721
722 INTEGER, PARAMETER :: occ_chunk = 128
723
724 INTEGER :: ia_global, iib, itmp(2), jjb, my_b_size, my_b_virtual_start, occ_high, occ_low, &
725 proc_receive, proc_send, proc_shift, rec_b_size, rec_b_virtual_end, rec_b_virtual_start
726 REAL(kind=dp), ALLOCATABLE, DIMENSION(:), TARGET :: bib_c_rec_1d
727 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: bib_c_rec
728
729 itmp = get_limit(dimen_ia, para_env_sub%num_pe, para_env_sub%mepos)
730 my_ia_start = itmp(1)
731 my_ia_end = itmp(2)
732 my_ia_size = my_ia_end - my_ia_start + 1
733
734 CALL get_group_dist(gd_b_virtual, para_env_sub%mepos, sizes=my_b_size, starts=my_b_virtual_start)
735
736 ! reorder data
737 ALLOCATE (bib_c_2d(my_group_l_size, my_ia_size))
738
739!$OMP PARALLEL DO DEFAULT(NONE) PRIVATE(jjB,ia_global) &
740!$OMP SHARED(homo,my_B_size,virtual,my_B_virtual_start,my_ia_start,my_ia_end,BIb_C,BIb_C_2D,&
741!$OMP my_group_L_size)
742 DO iib = 1, homo
743 DO jjb = 1, my_b_size
744 ia_global = (iib - 1)*virtual + my_b_virtual_start + jjb - 1
745 IF (ia_global >= my_ia_start .AND. ia_global <= my_ia_end) THEN
746 bib_c_2d(1:my_group_l_size, ia_global - my_ia_start + 1) = bib_c(1:my_group_l_size, jjb, iib)
747 END IF
748 END DO
749 END DO
750
751 IF (para_env_sub%num_pe > 1) THEN
752 ALLOCATE (bib_c_rec_1d(int(my_group_l_size, int_8)*maxsize(gd_b_virtual)*min(homo, occ_chunk)))
753 DO proc_shift = 1, para_env_sub%num_pe - 1
754 proc_send = modulo(para_env_sub%mepos + proc_shift, para_env_sub%num_pe)
755 proc_receive = modulo(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
756
757 CALL get_group_dist(gd_b_virtual, proc_receive, rec_b_virtual_start, rec_b_virtual_end, rec_b_size)
758
759 ! do this in chunks to avoid high memory overhead
760 DO occ_low = 1, homo, occ_chunk
761 occ_high = min(homo, occ_low + occ_chunk - 1)
762 bib_c_rec(1:my_group_l_size, 1:rec_b_size, 1:occ_high - occ_low + 1) => &
763 bib_c_rec_1d(1:int(my_group_l_size, int_8)*rec_b_size*(occ_high - occ_low + 1))
764 CALL para_env_sub%sendrecv(bib_c(:, :, occ_low:occ_high), proc_send, &
765 bib_c_rec(:, :, 1:occ_high - occ_low + 1), proc_receive)
766!$OMP PARALLEL DO DEFAULT(NONE) PRIVATE(jjB,ia_global) &
767!$OMP SHARED(occ_low,occ_high,rec_B_size,virtual,rec_B_virtual_start,my_ia_start,my_ia_end,BIb_C_rec,BIb_C_2D,&
768!$OMP my_group_L_size)
769 DO iib = occ_low, occ_high
770 DO jjb = 1, rec_b_size
771 ia_global = (iib - 1)*virtual + rec_b_virtual_start + jjb - 1
772 IF (ia_global >= my_ia_start .AND. ia_global <= my_ia_end) THEN
773 bib_c_2d(1:my_group_l_size, ia_global - my_ia_start + 1) = bib_c_rec(1:my_group_l_size, jjb, iib - occ_low + 1)
774 END IF
775 END DO
776 END DO
777 END DO
778
779 END DO
780 DEALLOCATE (bib_c_rec_1d)
781 END IF
782
783 END SUBROUTINE calculate_bib_c_2d
784
785! **************************************************************************************************
786!> \brief ...
787!> \param BIb_C_2D ...
788!> \param para_env ...
789!> \param para_env_sub ...
790!> \param color_sub ...
791!> \param ngroup ...
792!> \param integ_group_size ...
793!> \param dimen_RI ...
794!> \param dimen_ia ...
795!> \param color_rpa_group ...
796!> \param ext_row_block_size ...
797!> \param ext_col_block_size ...
798!> \param unit_nr ...
799!> \param my_ia_size ...
800!> \param my_ia_start ...
801!> \param my_ia_end ...
802!> \param my_group_L_size ...
803!> \param my_group_L_start ...
804!> \param my_group_L_end ...
805!> \param para_env_RPA ...
806!> \param fm_mat_S ...
807!> \param nrow_block_mat ...
808!> \param ncol_block_mat ...
809!> \param blacs_env_ext ...
810!> \param blacs_env_ext_S ...
811!> \param dimen_ia_for_block_size ...
812!> \param do_im_time ...
813!> \param fm_mat_Q_gemm ...
814!> \param fm_mat_Q ...
815!> \param qs_env ...
816! **************************************************************************************************
817 SUBROUTINE create_integ_mat(BIb_C_2D, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
818 dimen_RI, dimen_ia, color_rpa_group, &
819 ext_row_block_size, ext_col_block_size, unit_nr, &
820 my_ia_size, my_ia_start, my_ia_end, &
821 my_group_L_size, my_group_L_start, my_group_L_end, &
822 para_env_RPA, fm_mat_S, nrow_block_mat, ncol_block_mat, &
823 blacs_env_ext, blacs_env_ext_S, dimen_ia_for_block_size, &
824 do_im_time, fm_mat_Q_gemm, fm_mat_Q, qs_env)
825
826 TYPE(two_dim_real_array), DIMENSION(:), &
827 INTENT(INOUT) :: bib_c_2d
828 TYPE(mp_para_env_type), INTENT(IN) :: para_env, para_env_sub
829 INTEGER, INTENT(IN) :: color_sub, ngroup, integ_group_size, &
830 dimen_ri
831 INTEGER, DIMENSION(:), INTENT(IN) :: dimen_ia
832 INTEGER, INTENT(IN) :: color_rpa_group, ext_row_block_size, &
833 ext_col_block_size, unit_nr
834 INTEGER, DIMENSION(:), INTENT(IN) :: my_ia_size, my_ia_start, my_ia_end
835 INTEGER, INTENT(IN) :: my_group_l_size, my_group_l_start, &
836 my_group_l_end
837 TYPE(mp_para_env_type), INTENT(IN), POINTER :: para_env_rpa
838 TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT) :: fm_mat_s
839 INTEGER, INTENT(INOUT) :: nrow_block_mat, ncol_block_mat
840 TYPE(cp_blacs_env_type), OPTIONAL, POINTER :: blacs_env_ext, blacs_env_ext_s
841 INTEGER, INTENT(IN), OPTIONAL :: dimen_ia_for_block_size
842 LOGICAL, INTENT(IN), OPTIONAL :: do_im_time
843 TYPE(cp_fm_type), DIMENSION(:), OPTIONAL :: fm_mat_q_gemm, fm_mat_q
844 TYPE(qs_environment_type), INTENT(IN), OPTIONAL, &
845 POINTER :: qs_env
846
847 CHARACTER(LEN=*), PARAMETER :: routinen = 'create_integ_mat'
848
849 INTEGER :: col_row_proc_ratio, grid_2d(2), handle, &
850 iproc, iproc_col, iproc_row, ispin, &
851 mepos_in_rpa_group
852 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: group_grid_2_mepos
853 LOGICAL :: my_blacs_ext, my_blacs_s_ext, &
854 my_do_im_time
855 TYPE(cp_blacs_env_type), POINTER :: blacs_env, blacs_env_q
856 TYPE(cp_fm_struct_type), POINTER :: fm_struct
857 TYPE(group_dist_d1_type) :: gd_ia, gd_l
858
859 CALL timeset(routinen, handle)
860
861 cpassert(PRESENT(blacs_env_ext) .OR. PRESENT(dimen_ia_for_block_size))
862
863 my_blacs_ext = .false.
864 IF (PRESENT(blacs_env_ext)) my_blacs_ext = .true.
865
866 my_blacs_s_ext = .false.
867 IF (PRESENT(blacs_env_ext_s)) my_blacs_s_ext = .true.
868
869 my_do_im_time = .false.
870 IF (PRESENT(do_im_time)) my_do_im_time = do_im_time
871
872 NULLIFY (blacs_env)
873 ! create the RPA blacs env
874 IF (my_blacs_s_ext) THEN
875 blacs_env => blacs_env_ext_s
876 ELSE
877 IF (para_env_rpa%num_pe > 1) THEN
878 col_row_proc_ratio = max(1, dimen_ia_for_block_size/dimen_ri)
879
880 iproc_col = min(max(int(sqrt(real(para_env_rpa%num_pe*col_row_proc_ratio, kind=dp))), 1), para_env_rpa%num_pe) + 1
881 DO iproc = 1, para_env_rpa%num_pe
882 iproc_col = iproc_col - 1
883 IF (mod(para_env_rpa%num_pe, iproc_col) == 0) EXIT
884 END DO
885
886 iproc_row = para_env_rpa%num_pe/iproc_col
887 grid_2d(1) = iproc_row
888 grid_2d(2) = iproc_col
889 ELSE
890 grid_2d = 1
891 END IF
892 CALL cp_blacs_env_create(blacs_env=blacs_env, para_env=para_env_rpa, grid_2d=grid_2d)
893
894 IF (unit_nr > 0 .AND. .NOT. my_do_im_time) THEN
895 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
896 "MATRIX_INFO| Number row processes:", grid_2d(1)
897 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
898 "MATRIX_INFO| Number column processes:", grid_2d(2)
899 END IF
900
901 ! define the block_size for the row
902 IF (ext_row_block_size > 0) THEN
903 nrow_block_mat = ext_row_block_size
904 ELSE
905 nrow_block_mat = max(1, dimen_ri/grid_2d(1)/2)
906 END IF
907
908 ! define the block_size for the column
909 IF (ext_col_block_size > 0) THEN
910 ncol_block_mat = ext_col_block_size
911 ELSE
912 ncol_block_mat = max(1, dimen_ia_for_block_size/grid_2d(2)/2)
913 END IF
914
915 IF (unit_nr > 0 .AND. .NOT. my_do_im_time) THEN
916 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
917 "MATRIX_INFO| Row block size:", nrow_block_mat
918 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
919 "MATRIX_INFO| Column block size:", ncol_block_mat
920 END IF
921 END IF
922
923 IF (.NOT. my_do_im_time) THEN
924 DO ispin = 1, SIZE(bib_c_2d)
925 NULLIFY (fm_struct)
926 IF (my_blacs_ext) THEN
927 CALL cp_fm_struct_create(fm_struct, context=blacs_env, nrow_global=dimen_ri, &
928 ncol_global=dimen_ia(ispin), para_env=para_env_rpa)
929 ELSE
930 CALL cp_fm_struct_create(fm_struct, context=blacs_env, nrow_global=dimen_ri, &
931 ncol_global=dimen_ia(ispin), para_env=para_env_rpa, &
932 nrow_block=nrow_block_mat, ncol_block=ncol_block_mat, force_block=.true.)
933
934 END IF ! external blacs_env
935
936 CALL create_group_dist(gd_ia, my_ia_start(ispin), my_ia_end(ispin), my_ia_size(ispin), para_env_rpa)
937 CALL create_group_dist(gd_l, my_group_l_start, my_group_l_end, my_group_l_size, para_env_rpa)
938
939 ! create the info array
940
941 mepos_in_rpa_group = mod(color_sub, integ_group_size)
942 ALLOCATE (group_grid_2_mepos(0:integ_group_size - 1, 0:para_env_sub%num_pe - 1))
943 group_grid_2_mepos = 0
944 group_grid_2_mepos(mepos_in_rpa_group, para_env_sub%mepos) = para_env_rpa%mepos
945 CALL para_env_rpa%sum(group_grid_2_mepos)
946
947 CALL array2fm(bib_c_2d(ispin)%array, fm_struct, my_group_l_start, my_group_l_end, &
948 my_ia_start(ispin), my_ia_end(ispin), gd_l, gd_ia, &
949 group_grid_2_mepos, ngroup, para_env_sub%num_pe, fm_mat_s(ispin), &
950 integ_group_size, color_rpa_group)
951
952 DEALLOCATE (group_grid_2_mepos)
953 CALL cp_fm_struct_release(fm_struct)
954
955 ! deallocate the info array
956 CALL release_group_dist(gd_l)
957 CALL release_group_dist(gd_ia)
958
959 ! sum the local data across processes belonging to different RPA group.
960 IF (para_env_rpa%num_pe /= para_env%num_pe) THEN
961 block
962 TYPE(mp_comm_type) :: comm_exchange
963 comm_exchange = fm_mat_s(ispin)%matrix_struct%context%interconnect(para_env)
964 CALL comm_exchange%sum(fm_mat_s(ispin)%local_data)
965 CALL comm_exchange%free()
966 END block
967 END IF
968 END DO
969 END IF
970
971 IF (PRESENT(fm_mat_q_gemm) .AND. .NOT. my_do_im_time) THEN
972 ! create the Q matrix dimen_RIxdimen_RI where the result of the mat-mat-mult will be stored
973 NULLIFY (fm_struct)
974 CALL cp_fm_struct_create(fm_struct, context=blacs_env, nrow_global=dimen_ri, &
975 ncol_global=dimen_ri, para_env=para_env_rpa, &
976 nrow_block=nrow_block_mat, ncol_block=ncol_block_mat, force_block=.true.)
977 DO ispin = 1, SIZE(fm_mat_q_gemm)
978 CALL cp_fm_create(fm_mat_q_gemm(ispin), fm_struct, name="fm_mat_Q_gemm")
979 END DO
980 CALL cp_fm_struct_release(fm_struct)
981 END IF
982
983 IF (PRESENT(fm_mat_q)) THEN
984 NULLIFY (blacs_env_q)
985 IF (my_blacs_ext) THEN
986 blacs_env_q => blacs_env_ext
987 ELSE IF (para_env_rpa%num_pe == para_env%num_pe .AND. PRESENT(qs_env)) THEN
988 CALL get_qs_env(qs_env, blacs_env=blacs_env_q)
989 ELSE
990 CALL cp_blacs_env_create(blacs_env=blacs_env_q, para_env=para_env_rpa)
991 END IF
992 NULLIFY (fm_struct)
993 CALL cp_fm_struct_create(fm_struct, context=blacs_env_q, nrow_global=dimen_ri, &
994 ncol_global=dimen_ri, para_env=para_env_rpa)
995 DO ispin = 1, SIZE(fm_mat_q)
996 CALL cp_fm_create(fm_mat_q(ispin), fm_struct, name="fm_mat_Q", set_zero=.true.)
997 END DO
998
999 CALL cp_fm_struct_release(fm_struct)
1000
1001 IF (.NOT. (my_blacs_ext .OR. (para_env_rpa%num_pe == para_env%num_pe .AND. PRESENT(qs_env)))) THEN
1002 CALL cp_blacs_env_release(blacs_env_q)
1003 END IF
1004 END IF
1005
1006 ! release blacs_env
1007 IF (.NOT. my_blacs_s_ext) THEN
1008 CALL cp_blacs_env_release(blacs_env)
1009 ELSE
1010 NULLIFY (blacs_env)
1011 END IF
1012
1013 CALL timestop(handle)
1014
1015 END SUBROUTINE create_integ_mat
1016
1017! **************************************************************************************************
1018!> \brief ...
1019!> \param qs_env ...
1020!> \param Erpa ...
1021!> \param mp2_env ...
1022!> \param para_env ...
1023!> \param para_env_RPA ...
1024!> \param para_env_sub ...
1025!> \param unit_nr ...
1026!> \param homo ...
1027!> \param virtual ...
1028!> \param dimen_RI ...
1029!> \param dimen_RI_red ...
1030!> \param dimen_ia ...
1031!> \param dimen_nm_gw ...
1032!> \param Eigenval ...
1033!> \param num_integ_points ...
1034!> \param num_integ_group ...
1035!> \param color_rpa_group ...
1036!> \param fm_matrix_PQ ...
1037!> \param fm_mat_S ...
1038!> \param fm_mat_Q_gemm ...
1039!> \param fm_mat_Q ...
1040!> \param fm_mat_S_gw ...
1041!> \param fm_mat_R_gw ...
1042!> \param fm_mat_S_ij_bse ...
1043!> \param fm_mat_S_ab_bse ...
1044!> \param my_do_gw ...
1045!> \param do_bse ...
1046!> \param gw_corr_lev_occ ...
1047!> \param gw_corr_lev_virt ...
1048!> \param bse_lev_virt ...
1049!> \param do_minimax_quad ...
1050!> \param do_im_time ...
1051!> \param mo_coeff ...
1052!> \param fm_matrix_L_kpoints ...
1053!> \param fm_matrix_Minv_L_kpoints ...
1054!> \param fm_matrix_Minv ...
1055!> \param fm_matrix_Minv_Vtrunc_Minv ...
1056!> \param mat_munu ...
1057!> \param mat_P_global ...
1058!> \param t_3c_M ...
1059!> \param t_3c_O ...
1060!> \param t_3c_O_compressed ...
1061!> \param t_3c_O_ind ...
1062!> \param starts_array_mc ...
1063!> \param ends_array_mc ...
1064!> \param starts_array_mc_block ...
1065!> \param ends_array_mc_block ...
1066!> \param matrix_s ...
1067!> \param do_kpoints_from_Gamma ...
1068!> \param kpoints ...
1069!> \param gd_array ...
1070!> \param color_sub ...
1071!> \param do_ri_sos_laplace_mp2 ...
1072!> \param calc_forces ...
1073! **************************************************************************************************
1074 SUBROUTINE rpa_num_int(qs_env, Erpa, mp2_env, para_env, para_env_RPA, para_env_sub, unit_nr, &
1075 homo, virtual, dimen_RI, dimen_RI_red, dimen_ia, dimen_nm_gw, &
1076 Eigenval, num_integ_points, num_integ_group, color_rpa_group, &
1077 fm_matrix_PQ, fm_mat_S, fm_mat_Q_gemm, fm_mat_Q, fm_mat_S_gw, fm_mat_R_gw, &
1078 fm_mat_S_ij_bse, fm_mat_S_ab_bse, &
1079 my_do_gw, do_bse, gw_corr_lev_occ, gw_corr_lev_virt, &
1080 bse_lev_virt, &
1081 do_minimax_quad, do_im_time, mo_coeff, &
1082 fm_matrix_L_kpoints, fm_matrix_Minv_L_kpoints, &
1083 fm_matrix_Minv, fm_matrix_Minv_Vtrunc_Minv, mat_munu, mat_P_global, &
1084 t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, &
1085 starts_array_mc, ends_array_mc, &
1086 starts_array_mc_block, ends_array_mc_block, &
1087 matrix_s, do_kpoints_from_Gamma, kpoints, gd_array, color_sub, &
1088 do_ri_sos_laplace_mp2, calc_forces)
1089
1090 TYPE(qs_environment_type), POINTER :: qs_env
1091 REAL(kind=dp), INTENT(OUT) :: erpa
1092 TYPE(mp2_type) :: mp2_env
1093 TYPE(mp_para_env_type), POINTER :: para_env, para_env_rpa, para_env_sub
1094 INTEGER, INTENT(IN) :: unit_nr
1095 INTEGER, DIMENSION(:), INTENT(IN) :: homo, virtual
1096 INTEGER, INTENT(IN) :: dimen_ri, dimen_ri_red
1097 INTEGER, DIMENSION(:), INTENT(IN) :: dimen_ia
1098 INTEGER, INTENT(IN) :: dimen_nm_gw
1099 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :), &
1100 INTENT(INOUT) :: eigenval
1101 INTEGER, INTENT(IN) :: num_integ_points, num_integ_group, &
1102 color_rpa_group
1103 TYPE(cp_fm_type), INTENT(IN) :: fm_matrix_pq
1104 TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT) :: fm_mat_s
1105 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fm_mat_q_gemm, fm_mat_q, fm_mat_s_gw
1106 TYPE(cp_fm_type), INTENT(IN) :: fm_mat_r_gw
1107 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fm_mat_s_ij_bse, fm_mat_s_ab_bse
1108 LOGICAL, INTENT(IN) :: my_do_gw, do_bse
1109 INTEGER, DIMENSION(:), INTENT(IN) :: gw_corr_lev_occ, gw_corr_lev_virt, &
1110 bse_lev_virt
1111 LOGICAL, INTENT(IN) :: do_minimax_quad, do_im_time
1112 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff
1113 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_matrix_l_kpoints, &
1114 fm_matrix_minv_l_kpoints, &
1115 fm_matrix_minv, &
1116 fm_matrix_minv_vtrunc_minv
1117 TYPE(dbcsr_p_type), INTENT(IN) :: mat_munu
1118 TYPE(dbcsr_p_type), INTENT(INOUT) :: mat_p_global
1119 TYPE(dbt_type), INTENT(INOUT) :: t_3c_m
1120 TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :), &
1121 INTENT(INOUT) :: t_3c_o
1122 TYPE(hfx_compression_type), ALLOCATABLE, &
1123 DIMENSION(:, :, :), INTENT(INOUT) :: t_3c_o_compressed
1124 TYPE(block_ind_type), ALLOCATABLE, &
1125 DIMENSION(:, :, :), INTENT(INOUT) :: t_3c_o_ind
1126 INTEGER, ALLOCATABLE, DIMENSION(:), INTENT(IN) :: starts_array_mc, ends_array_mc, &
1127 starts_array_mc_block, &
1128 ends_array_mc_block
1129 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
1130 LOGICAL :: do_kpoints_from_gamma
1131 TYPE(kpoint_type), POINTER :: kpoints
1132 TYPE(group_dist_d1_type), INTENT(IN) :: gd_array
1133 INTEGER, INTENT(IN) :: color_sub
1134 LOGICAL, INTENT(IN) :: do_ri_sos_laplace_mp2, calc_forces
1135
1136 CHARACTER(LEN=*), PARAMETER :: routinen = 'rpa_num_int'
1137
1138 COMPLEX(KIND=dp), ALLOCATABLE, &
1139 DIMENSION(:, :, :, :) :: vec_sigma_c_gw
1140 INTEGER :: count_ev_sc_gw, cut_memory, group_size_p, gw_corr_lev_tot, handle, handle3, i, &
1141 ikp_local, ispin, iter_evgw, iter_sc_gw0, j, jquad, min_bsize, mm_style, nkp, &
1142 nkp_self_energy, nmo, nspins, num_3c_repl, num_cells_dm, num_fit_points, pspin, qspin, &
1143 size_p
1144 INTEGER(int_8) :: dbcsr_nflop
1145 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: index_to_cell_3c
1146 INTEGER, ALLOCATABLE, DIMENSION(:, :, :) :: cell_to_index_3c
1147 INTEGER, DIMENSION(:), POINTER :: col_blk_size, prim_blk_sizes, &
1148 ri_blk_sizes
1149 LOGICAL :: do_apply_ic_corr_to_gw, do_gw_im_time, do_ic_model, do_kpoints_cubic_rpa, &
1150 do_periodic, do_print, do_ri_sigma_x, exit_ev_gw, first_cycle, &
1151 first_cycle_periodic_correction, my_open_shell, print_ic_values
1152 LOGICAL, ALLOCATABLE, DIMENSION(:, :, :, :, :) :: has_mat_p_blocks
1153 REAL(kind=dp) :: alpha, dbcsr_time, e_exchange, e_exchange_corr, eps_filter, &
1154 eps_filter_im_time, ext_scaling, fermi_level_offset, fermi_level_offset_input, &
1155 my_flop_rate, omega, omega_max_fit, omega_old, tau, tau_old
1156 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: delta_corr, e_fermi, trace_qomega, &
1157 vec_omega_fit_gw, wkp_w
1158 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: vec_w_gw
1159 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: eigenval_last, eigenval_scf, &
1160 vec_sigma_x_gw
1161 TYPE(cp_cfm_type) :: cfm_mat_q
1162 TYPE(cp_cfm_type), ALLOCATABLE, DIMENSION(:) :: cfm_mo_coeff
1163 TYPE(cp_fm_type) :: fm_mat_q_static_bse_gemm, &
1164 fm_mat_ri_global_work, fm_mat_work
1165 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_mat_s_gw_work, fm_mat_s_ia_bse, &
1166 fm_mat_w
1167 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_mat_l_kpoints, fm_mat_minv_l_kpoints
1168 TYPE(dbcsr_p_type) :: mat_dm, mat_l, mat_m_p_munu_occ, &
1169 mat_m_p_munu_virt, mat_minvvminv
1170 TYPE(dbcsr_p_type), ALLOCATABLE, &
1171 DIMENSION(:, :, :) :: mat_p_omega
1172 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_berry_im_mo_mo, &
1173 matrix_berry_re_mo_mo
1174 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_p_omega_kp
1175 TYPE(dbcsr_type), POINTER :: mat_w, mat_work
1176 TYPE(dbt_type) :: t_3c_overl_int_ao_mo
1177 TYPE(dbt_type), ALLOCATABLE, DIMENSION(:) :: t_3c_overl_int_gw_ao, &
1178 t_3c_overl_int_gw_ri, &
1179 t_3c_overl_nnp_ic, &
1180 t_3c_overl_nnp_ic_reflected
1181 TYPE(dgemm_counter_type) :: dgemm_counter
1182 TYPE(hfx_compression_type), ALLOCATABLE, &
1183 DIMENSION(:) :: t_3c_o_mo_compressed
1184 TYPE(im_time_force_type) :: force_data
1185 TYPE(rpa_exchange_work_type) :: exchange_work
1186 TYPE(rpa_grad_type) :: rpa_grad
1187 TYPE(rpa_sigma_type) :: rpa_sigma
1188 TYPE(time_frequency_grid_type) :: time_frequency_grid
1189 TYPE(two_dim_int_array), ALLOCATABLE, DIMENSION(:) :: t_3c_o_mo_ind
1190
1191 CALL timeset(routinen, handle)
1192
1193 nspins = SIZE(homo)
1194 nmo = homo(1) + virtual(1)
1195
1196 my_open_shell = (nspins == 2)
1197
1198 do_gw_im_time = my_do_gw .AND. do_im_time
1199 do_ri_sigma_x = mp2_env%ri_g0w0%do_ri_Sigma_x
1200 do_ic_model = mp2_env%ri_g0w0%do_ic_model
1201 print_ic_values = mp2_env%ri_g0w0%print_ic_values
1202 do_periodic = mp2_env%ri_g0w0%do_periodic
1203 do_kpoints_cubic_rpa = mp2_env%ri_rpa_im_time%do_im_time_kpoints
1204
1205 ! For SOS-MP2 only gemm is implemented
1206 mm_style = wfc_mm_style_gemm
1207 IF (.NOT. do_ri_sos_laplace_mp2) mm_style = mp2_env%ri_rpa%mm_style
1208
1209 IF (my_do_gw) THEN
1210 ext_scaling = 0.2_dp
1211 omega_max_fit = mp2_env%ri_g0w0%omega_max_fit
1212 fermi_level_offset_input = mp2_env%ri_g0w0%fermi_level_offset
1213 iter_evgw = mp2_env%ri_g0w0%iter_evGW
1214 iter_sc_gw0 = mp2_env%ri_g0w0%iter_sc_GW0
1215 IF ((.NOT. do_im_time)) THEN
1216 IF (iter_sc_gw0 /= 1 .AND. iter_evgw /= 1) cpabort("Mixed scGW0/evGW not implemented.")
1217 ! in case of scGW0 with the N^4 algorithm, we use the evGW code but use the DFT eigenvalues for W
1218 IF (iter_sc_gw0 /= 1) iter_evgw = iter_sc_gw0
1219 END IF
1220 ELSE
1221 ext_scaling = 0.0_dp
1222 iter_evgw = 1
1223 iter_sc_gw0 = 1
1224 END IF
1225
1226 IF (do_kpoints_cubic_rpa .AND. do_ri_sos_laplace_mp2) THEN
1227 cpabort("RI-SOS-Laplace-MP2 with k-point-sampling is not implemented.")
1228 END IF
1229
1230 do_apply_ic_corr_to_gw = .false.
1231 IF (mp2_env%ri_g0w0%ic_corr_list(1)%array(1) > 0.0_dp) do_apply_ic_corr_to_gw = .true.
1232
1233 IF (do_im_time) THEN
1234 cpassert(do_minimax_quad .OR. do_ri_sos_laplace_mp2)
1235
1236 group_size_p = mp2_env%ri_rpa_im_time%group_size_P
1237 cut_memory = mp2_env%ri_rpa_im_time%cut_memory
1238 eps_filter = mp2_env%ri_rpa_im_time%eps_filter
1239 eps_filter_im_time = mp2_env%ri_rpa_im_time%eps_filter* &
1240 mp2_env%ri_rpa_im_time%eps_filter_factor
1241
1242 min_bsize = mp2_env%ri_rpa_im_time%min_bsize
1243
1244 CALL alloc_im_time(qs_env, para_env, dimen_ri, dimen_ri_red, &
1245 num_integ_points, nspins, fm_mat_q(1), cfm_mo_coeff, &
1246 fm_matrix_minv_l_kpoints, fm_matrix_l_kpoints, mat_p_global, &
1247 t_3c_o, matrix_s, kpoints, eps_filter_im_time, &
1248 cut_memory, nkp, num_cells_dm, num_3c_repl, &
1249 size_p, ikp_local, &
1250 index_to_cell_3c, &
1251 cell_to_index_3c, &
1252 col_blk_size, &
1253 do_ic_model, do_kpoints_cubic_rpa, &
1254 do_kpoints_from_gamma, do_ri_sigma_x, my_open_shell, &
1255 has_mat_p_blocks, wkp_w, &
1256 cfm_mat_q, fm_mat_minv_l_kpoints, fm_mat_l_kpoints, &
1257 fm_mat_ri_global_work, fm_mat_work, mat_dm, mat_l, mat_m_p_munu_occ, mat_m_p_munu_virt, &
1258 mat_minvvminv, mat_p_omega, mat_p_omega_kp, mat_work, mo_coeff)
1259
1260 IF (calc_forces) CALL init_im_time_forces(force_data, fm_matrix_pq, t_3c_m, unit_nr, mp2_env, qs_env)
1261
1262 IF (my_do_gw) THEN
1263
1264 CALL dbcsr_get_info(mat_p_global%matrix, &
1265 row_blk_size=ri_blk_sizes)
1266
1267 CALL dbcsr_get_info(matrix_s(1)%matrix, &
1268 row_blk_size=prim_blk_sizes)
1269
1270 gw_corr_lev_tot = gw_corr_lev_occ(1) + gw_corr_lev_virt(1)
1271
1272 IF (.NOT. do_kpoints_cubic_rpa) THEN
1273 CALL allocate_matrices_gw_im_time(gw_corr_lev_occ, gw_corr_lev_virt, homo, nmo, &
1274 num_integ_points, unit_nr, &
1275 ri_blk_sizes, do_ic_model, &
1276 para_env, fm_mat_w, fm_mat_q(1), &
1277 mo_coeff, &
1278 t_3c_overl_int_ao_mo, t_3c_o_mo_compressed, t_3c_o_mo_ind, &
1279 t_3c_overl_int_gw_ri, t_3c_overl_int_gw_ao, &
1280 starts_array_mc, ends_array_mc, &
1281 t_3c_overl_nnp_ic, t_3c_overl_nnp_ic_reflected, &
1282 matrix_s, mat_w, t_3c_o, &
1283 t_3c_o_compressed, t_3c_o_ind, &
1284 qs_env)
1285
1286 END IF
1287 END IF
1288
1289 END IF
1290 IF (do_ic_model) THEN
1291 ! image charge model only implemented for cubic scaling GW
1292 cpassert(do_gw_im_time)
1293 cpassert(.NOT. do_periodic)
1294 IF (cut_memory /= 1) cpabort("For IC, use MEMORY_CUT 1 in the LOW_SCALING section.")
1295 END IF
1296
1297 ALLOCATE (e_fermi(nspins))
1298 IF (do_minimax_quad .OR. do_ri_sos_laplace_mp2) THEN
1299 do_print = .NOT. do_ic_model
1300 CALL get_minimax_grid(para_env, unit_nr, homo, eigenval, num_integ_points, do_im_time, &
1301 do_ri_sos_laplace_mp2, do_print, &
1302 qs_env, do_gw_im_time, do_kpoints_cubic_rpa, e_fermi(1), time_frequency_grid)
1303
1304 !For sos_laplace_mp2 and low-scaling RPA, potentially need to store/retrieve the initial weights
1305 IF (qs_env%mp2_env%ri_rpa_im_time%keep_quad) THEN
1306 CALL keep_initial_quad(time_frequency_grid, do_ri_sos_laplace_mp2, do_im_time, unit_nr, qs_env)
1307 END IF
1308 ELSE
1309 IF (calc_forces) cpabort("Forces with Clenshaw-Curtis grid not implemented.")
1310 CALL get_clenshaw_grid(para_env, para_env_rpa, unit_nr, homo, virtual, eigenval, num_integ_points, &
1311 num_integ_group, color_rpa_group, fm_mat_s, my_do_gw, &
1312 ext_scaling, time_frequency_grid)
1313 END IF
1314
1315 ! This array is needed for RPA
1316 IF (.NOT. do_ri_sos_laplace_mp2) THEN
1317 ALLOCATE (trace_qomega(dimen_ri_red))
1318 END IF
1319
1320 IF (do_ri_sos_laplace_mp2 .AND. .NOT. do_im_time) THEN
1321 alpha = 1.0_dp
1322 ELSE IF (my_open_shell .OR. do_ri_sos_laplace_mp2) THEN
1323 alpha = 2.0_dp
1324 ELSE
1325 alpha = 4.0_dp
1326 END IF
1327 IF (my_do_gw) THEN
1328 CALL allocate_matrices_gw(vec_sigma_c_gw, color_rpa_group, dimen_nm_gw, &
1329 gw_corr_lev_occ, gw_corr_lev_virt, homo, &
1330 nmo, num_integ_group, unit_nr, &
1331 gw_corr_lev_tot, num_fit_points, omega_max_fit, &
1332 do_minimax_quad, do_periodic, do_ri_sigma_x,.NOT. do_im_time, &
1333 first_cycle_periodic_correction, &
1334 time_frequency_grid, eigenval, vec_omega_fit_gw, vec_sigma_x_gw, &
1335 delta_corr, eigenval_last, eigenval_scf, vec_w_gw, &
1336 fm_mat_s_gw, fm_mat_s_gw_work, &
1337 para_env, mp2_env, kpoints, nkp, nkp_self_energy, &
1338 do_kpoints_cubic_rpa, do_kpoints_from_gamma)
1339
1340 IF (do_bse) THEN
1341
1342 CALL cp_fm_create(fm_mat_q_static_bse_gemm, fm_mat_q_gemm(1)%matrix_struct, set_zero=.true.)
1343
1344 END IF
1345
1346 END IF
1347
1348 IF (calc_forces .AND. .NOT. do_im_time) CALL rpa_grad_create(rpa_grad, fm_mat_q(1), &
1349 fm_mat_s, homo, virtual, mp2_env, eigenval(:, 1, :), &
1350 unit_nr, do_ri_sos_laplace_mp2)
1351 IF (.NOT. do_im_time .AND. .NOT. do_ri_sos_laplace_mp2) THEN
1352 CALL exchange_work%create(qs_env, para_env_sub, mat_munu, dimen_ri_red, &
1353 fm_mat_s, fm_mat_q(1), fm_mat_q_gemm(1), homo, virtual)
1354 END IF
1355 erpa = 0.0_dp
1356 IF (mp2_env%ri_rpa%exchange_correction /= rpa_exchange_none) e_exchange = 0.0_dp
1357 first_cycle = .true.
1358 omega_old = 0.0_dp
1359 CALL dgemm_counter_init(dgemm_counter, unit_nr, mp2_env%ri_rpa%print_dgemm_info)
1360
1361 DO count_ev_sc_gw = 1, iter_evgw
1362 dbcsr_time = 0.0_dp
1363 dbcsr_nflop = 0
1364
1365 IF (do_ic_model) cycle
1366
1367 ! reset some values, important when doing eigenvalue self-consistent GW
1368 IF (my_do_gw) THEN
1369 erpa = 0.0_dp
1370 vec_sigma_c_gw = z_zero
1371 first_cycle = .true.
1372 END IF
1373
1374 ! calculate Q_PQ(it)
1375 IF (do_im_time) THEN ! not using Imaginary time
1376
1377 IF (.NOT. do_kpoints_cubic_rpa) THEN
1378 DO ispin = 1, nspins
1379 e_fermi(ispin) = (eigenval(homo(ispin), 1, ispin) + eigenval(homo(ispin) + 1, 1, ispin))*0.5_dp
1380 END DO
1381 END IF
1382
1383 tau = 0.0_dp
1384 tau_old = 0.0_dp
1385
1386 IF (unit_nr > 0) WRITE (unit=unit_nr, fmt="(/T3,A,T66,i15)") &
1387 "MEMORY_INFO| Memory cut:", cut_memory
1388 IF (unit_nr > 0) WRITE (unit=unit_nr, fmt="(T3,A,T66,ES15.2)") &
1389 "SPARSITY_INFO| Eps filter for M virt/occ tensors:", eps_filter
1390 IF (unit_nr > 0) WRITE (unit=unit_nr, fmt="(T3,A,T66,ES15.2)") &
1391 "SPARSITY_INFO| Eps filter for P matrix:", eps_filter_im_time
1392 IF (unit_nr > 0) WRITE (unit=unit_nr, fmt="(T3,A,T66,i15)") &
1393 "SPARSITY_INFO| Minimum tensor block size:", min_bsize
1394
1395 ! for evGW, we have to ensure that mat_P_omega is zero
1396 CALL zero_mat_p_omega(mat_p_omega(:, :, 1))
1397
1398 ! compute the matrix Q(it) and Fourier transform it directly to mat_P_omega(iw)
1399 CALL compute_mat_p_omega(mat_p_omega(:, :, 1), cfm_mo_coeff(1), homo(1), &
1400 mat_p_global, matrix_s, 1, &
1401 t_3c_m, t_3c_o, t_3c_o_compressed, t_3c_o_ind, &
1402 starts_array_mc, ends_array_mc, &
1403 starts_array_mc_block, ends_array_mc_block, &
1404 time_frequency_grid, e_fermi(1), eps_filter, alpha, &
1405 eps_filter_im_time, eigenval(:, 1, 1), nmo, &
1406 cut_memory, &
1407 unit_nr, mp2_env, para_env, &
1408 qs_env, do_kpoints_from_gamma, &
1409 index_to_cell_3c, cell_to_index_3c, &
1410 has_mat_p_blocks, do_ri_sos_laplace_mp2, &
1411 dbcsr_time, dbcsr_nflop)
1412
1413 ! the same for open shell, use the beta-spin MO coefficients
1414 IF (my_open_shell) THEN
1415 CALL zero_mat_p_omega(mat_p_omega(:, :, 2))
1416 CALL compute_mat_p_omega(mat_p_omega(:, :, 2), cfm_mo_coeff(2), homo(2), &
1417 mat_p_global, matrix_s, 2, &
1418 t_3c_m, t_3c_o, t_3c_o_compressed, t_3c_o_ind, &
1419 starts_array_mc, ends_array_mc, &
1420 starts_array_mc_block, ends_array_mc_block, &
1421 time_frequency_grid, e_fermi(2), eps_filter, alpha, &
1422 eps_filter_im_time, eigenval(:, 1, 2), nmo, &
1423 cut_memory, &
1424 unit_nr, mp2_env, para_env, &
1425 qs_env, do_kpoints_from_gamma, &
1426 index_to_cell_3c, cell_to_index_3c, &
1427 has_mat_p_blocks, do_ri_sos_laplace_mp2, &
1428 dbcsr_time, dbcsr_nflop)
1429
1430 !For RPA, we sum up the P matrices. If no force needed, can clean-up the beta spin one
1431 IF (.NOT. do_ri_sos_laplace_mp2) THEN
1432 DO j = 1, SIZE(mat_p_omega, 2)
1433 DO i = 1, SIZE(mat_p_omega, 1)
1434 CALL dbcsr_add(mat_p_omega(i, j, 1)%matrix, mat_p_omega(i, j, 2)%matrix, 1.0_dp, 1.0_dp)
1435 IF (.NOT. calc_forces) CALL dbcsr_clear(mat_p_omega(i, j, 2)%matrix)
1436 END DO
1437 END DO
1438 END IF
1439 END IF ! my_open_shell
1440
1441 END IF ! do im time
1442
1443 IF (mp2_env%ri_rpa%sigma_param /= sigma_none) THEN
1444 CALL rpa_sigma_create(rpa_sigma, mp2_env%ri_rpa%sigma_param, fm_mat_q(1), unit_nr, para_env)
1445 END IF
1446
1447 DO jquad = 1, num_integ_points
1448 IF (modulo(jquad, num_integ_group) /= color_rpa_group) cycle
1449
1450 CALL timeset(routinen//"_RPA_matrix_operations", handle3)
1451
1452 IF (do_ri_sos_laplace_mp2) THEN
1453 omega = time_frequency_grid%imaginary_time(jquad)
1454 ELSE
1455 omega = time_frequency_grid%frequency(jquad)
1456 END IF ! do_ri_sos_laplace_mp2
1457
1458 IF (do_im_time) THEN
1459 ! in case we do imag time, we already calculated fm_mat_Q by a Fourier transform from im. time
1460
1461 IF (.NOT. (do_kpoints_cubic_rpa .OR. do_kpoints_from_gamma)) THEN
1462
1463 DO ispin = 1, SIZE(mat_p_omega, 3)
1464 CALL contract_p_omega_with_mat_l(mat_p_omega(jquad, 1, ispin)%matrix, mat_l%matrix, mat_work, &
1465 eps_filter_im_time, fm_mat_work, dimen_ri, dimen_ri_red, &
1466 fm_mat_minv_l_kpoints(1, 1), fm_mat_q(ispin))
1467 END DO
1468 END IF
1469
1470 ELSE
1471 IF (unit_nr > 0) WRITE (unit=unit_nr, fmt="(T3, A, 1X, I3, 1X, A, 1X, I3)") &
1472 "INTEG_INFO| Started with Integration point", jquad, "of", num_integ_points
1473
1474 IF (first_cycle .AND. count_ev_sc_gw > 1) THEN
1475 IF (iter_sc_gw0 == 1) THEN
1476 DO ispin = 1, nspins
1477 CALL remove_scaling_factor_rpa(fm_mat_s(ispin), virtual(ispin), &
1478 eigenval_last(:, 1, ispin), homo(ispin), omega_old)
1479 END DO
1480 ELSE
1481 DO ispin = 1, nspins
1482 CALL remove_scaling_factor_rpa(fm_mat_s(ispin), virtual(ispin), &
1483 eigenval_scf(:, 1, ispin), homo(ispin), omega_old)
1484 END DO
1485 END IF
1486 END IF
1487
1488 IF (iter_sc_gw0 > 1) THEN
1489 DO ispin = 1, nspins
1490 CALL calc_mat_q(fm_mat_s(ispin), do_ri_sos_laplace_mp2, first_cycle, virtual(ispin), &
1491 eigenval_scf(:, 1, ispin), homo(ispin), omega, omega_old, jquad, mm_style, &
1492 dimen_ri_red, dimen_ia(ispin), alpha, fm_mat_q(ispin), &
1493 fm_mat_q_gemm(ispin), do_bse, fm_mat_q_static_bse_gemm, dgemm_counter, &
1494 num_integ_points, count_ev_sc_gw)
1495 END DO
1496
1497 ! For SOS-MP2 we need both matrices separately
1498 IF (.NOT. do_ri_sos_laplace_mp2) THEN
1499 DO ispin = 2, nspins
1500 CALL cp_fm_scale_and_add(alpha=1.0_dp, matrix_a=fm_mat_q(1), beta=1.0_dp, matrix_b=fm_mat_q(ispin))
1501 END DO
1502 END IF
1503 ELSE
1504 DO ispin = 1, nspins
1505 CALL calc_mat_q(fm_mat_s(ispin), do_ri_sos_laplace_mp2, first_cycle, virtual(ispin), &
1506 eigenval(:, 1, ispin), homo(ispin), omega, omega_old, jquad, mm_style, &
1507 dimen_ri_red, dimen_ia(ispin), alpha, fm_mat_q(ispin), &
1508 fm_mat_q_gemm(ispin), do_bse, fm_mat_q_static_bse_gemm, dgemm_counter, &
1509 num_integ_points, count_ev_sc_gw)
1510 END DO
1511 ! For open-shell BSE: the static screened-Coulomb polarizability is the
1512 ! sum over both spin channels. calc_mat_Q overwrites fm_mat_Q_static_bse_gemm
1513 ! per spin, so rebuild it here as the explicit spin sum at omega=0.
1514 IF (do_bse .AND. nspins > 1 .AND. jquad == num_integ_points .AND. &
1515 count_ev_sc_gw == 1) THEN
1516 CALL cp_fm_set_all(fm_mat_q_static_bse_gemm, 0.0_dp)
1517 DO ispin = 1, nspins
1518 CALL cp_fm_scale_and_add(1.0_dp, fm_mat_q_static_bse_gemm, &
1519 1.0_dp, fm_mat_q_gemm(ispin))
1520 END DO
1521 END IF
1522
1523 ! For SOS-MP2 we need both matrices separately
1524 IF (.NOT. do_ri_sos_laplace_mp2) THEN
1525 DO ispin = 2, nspins
1526 CALL cp_fm_scale_and_add(alpha=1.0_dp, matrix_a=fm_mat_q(1), beta=1.0_dp, matrix_b=fm_mat_q(ispin))
1527 END DO
1528 END IF
1529
1530 END IF
1531
1532 END IF ! im time
1533
1534 ! Calculate RPA exchange energy correction
1535 IF (mp2_env%ri_rpa%exchange_correction /= rpa_exchange_none) THEN
1536 e_exchange_corr = 0.0_dp
1537 CALL exchange_work%compute(fm_mat_q(1), eigenval(:, 1, :), fm_mat_s, omega, e_exchange_corr, mp2_env)
1538
1539 ! Evaluate the final exchange energy correction
1540 e_exchange = e_exchange + e_exchange_corr*time_frequency_grid%frequency_weights(jquad)
1541 END IF
1542
1543 ! for developing Sigma functional closed and open shell are taken cared for
1544 IF (mp2_env%ri_rpa%sigma_param /= sigma_none) THEN
1545 CALL rpa_sigma_matrix_spectral(rpa_sigma, fm_mat_q(1), time_frequency_grid%frequency_weights(jquad), para_env_rpa)
1546 END IF
1547
1548 IF (do_ri_sos_laplace_mp2) THEN
1549
1550 CALL sos_mp2_postprocessing(fm_mat_q, erpa, time_frequency_grid%time_weights_at_zero_frequency(jquad))
1551
1552 IF (calc_forces .AND. .NOT. do_im_time) THEN
1553 CALL rpa_grad_matrix_operations(mp2_env, rpa_grad, do_ri_sos_laplace_mp2, &
1554 fm_mat_q, fm_mat_q_gemm, dgemm_counter, fm_mat_s, omega, homo, virtual, &
1555 eigenval(:, 1, :), time_frequency_grid%time_weights_at_zero_frequency(jquad), &
1556 unit_nr)
1557 END IF
1558 ELSE
1559 IF (calc_forces .AND. .NOT. do_im_time) CALL rpa_grad_copy_q(fm_mat_q(1), rpa_grad)
1560
1561 CALL q_trace_and_add_unit_matrix(dimen_ri_red, trace_qomega, fm_mat_q(1))
1562
1563 IF (do_kpoints_cubic_rpa .OR. do_kpoints_from_gamma) THEN
1564 CALL invert_eps_compute_w_and_erpa_kp(dimen_ri, jquad, nkp, count_ev_sc_gw, para_env, &
1565 erpa, time_frequency_grid, &
1566 wkp_w, do_gw_im_time, do_ri_sigma_x, do_kpoints_from_gamma, &
1567 cfm_mat_q, ikp_local, &
1568 mat_p_omega(:, :, 1), mat_p_omega_kp, qs_env, eps_filter_im_time, unit_nr, &
1569 kpoints, fm_mat_minv_l_kpoints, fm_mat_l_kpoints, &
1570 fm_mat_w, fm_mat_ri_global_work, mat_minvvminv, &
1571 fm_matrix_minv, fm_matrix_minv_vtrunc_minv)
1572 ELSE
1573 CALL compute_erpa_by_freq_int(dimen_ri_red, trace_qomega, fm_mat_q(1), para_env_rpa, erpa, &
1574 time_frequency_grid%frequency_weights(jquad))
1575 END IF
1576
1577 IF (calc_forces .AND. .NOT. do_im_time) THEN
1578 CALL rpa_grad_matrix_operations(mp2_env, rpa_grad, do_ri_sos_laplace_mp2, &
1579 fm_mat_q, fm_mat_q_gemm, dgemm_counter, fm_mat_s, omega, homo, virtual, &
1580 eigenval(:, 1, :), time_frequency_grid%frequency_weights(jquad), unit_nr)
1581 END IF
1582 END IF ! do_ri_sos_laplace_mp2
1583
1584 ! save omega and reset the first_cycle flag
1585 first_cycle = .false.
1586 omega_old = omega
1587
1588 CALL timestop(handle3)
1589
1590 IF (my_do_gw) THEN
1591
1592 CALL get_fermi_level_offset(fermi_level_offset, fermi_level_offset_input, eigenval(:, 1, :), homo)
1593
1594 ! do_im_time = TRUE means low-scaling calculation
1595 IF (do_im_time) THEN
1596 ! only for molecules
1597 IF (.NOT. (do_kpoints_cubic_rpa .OR. do_kpoints_from_gamma)) THEN
1598 CALL compute_w_cubic_gw(fm_mat_w, fm_mat_q(1), fm_mat_work, dimen_ri, fm_mat_minv_l_kpoints, &
1599 time_frequency_grid, jquad, omega)
1600 END IF
1601 ELSE
1602 CALL compute_gw_self_energy(vec_sigma_c_gw, dimen_nm_gw, dimen_ri_red, gw_corr_lev_occ, &
1603 gw_corr_lev_virt, homo, jquad, nmo, num_fit_points, &
1604 do_im_time, do_periodic, first_cycle_periodic_correction, &
1605 fermi_level_offset, &
1606 omega, eigenval(:, 1, :), delta_corr, vec_omega_fit_gw, vec_w_gw, &
1607 time_frequency_grid, &
1608 fm_mat_q(1), fm_mat_r_gw, fm_mat_s_gw, &
1609 fm_mat_s_gw_work, mo_coeff(1), para_env, &
1610 para_env_rpa, matrix_berry_im_mo_mo, matrix_berry_re_mo_mo, &
1611 kpoints, qs_env, mp2_env)
1612 END IF
1613 END IF
1614
1615 IF (unit_nr > 0) CALL m_flush(unit_nr)
1616 CALL para_env_rpa%sync() ! sync to see output
1617
1618 END DO ! jquad
1619
1620 IF (mp2_env%ri_rpa%sigma_param /= sigma_none) THEN
1621 CALL finalize_rpa_sigma(rpa_sigma, unit_nr, mp2_env%ri_rpa%e_sigma_corr, para_env, do_minimax_quad)
1622 IF (do_minimax_quad) mp2_env%ri_rpa%e_sigma_corr = mp2_env%ri_rpa%e_sigma_corr/2.0_dp
1623 CALL para_env%sum(mp2_env%ri_rpa%e_sigma_corr)
1624 END IF
1625
1626 CALL para_env%sum(erpa)
1627
1628 IF (.NOT. (do_ri_sos_laplace_mp2)) THEN
1629 erpa = erpa/(pi*2.0_dp)
1630 IF (do_minimax_quad) erpa = erpa/2.0_dp
1631 END IF
1632
1633 IF (mp2_env%ri_rpa%exchange_correction /= rpa_exchange_none) THEN
1634 CALL para_env%sum(e_exchange)
1635 e_exchange = e_exchange/(pi*2.0_dp)
1636 IF (do_minimax_quad) e_exchange = e_exchange/2.0_dp
1637 mp2_env%ri_rpa%ener_exchange = e_exchange
1638 END IF
1639
1640 IF (calc_forces .AND. do_ri_sos_laplace_mp2 .AND. do_im_time) THEN
1641 IF (my_open_shell) THEN
1642 pspin = 1
1643 qspin = 2
1644 CALL calc_laplace_loop_forces(force_data, mat_p_omega(:, 1, :), t_3c_m, t_3c_o(1, 1), &
1645 t_3c_o_compressed(1, 1, :), t_3c_o_ind(1, 1, :), cfm_mo_coeff, homo, &
1646 starts_array_mc, ends_array_mc, starts_array_mc_block, &
1647 ends_array_mc_block, nmo, eigenval(:, 1, :), &
1648 time_frequency_grid, &
1649 cut_memory, pspin, qspin, my_open_shell, &
1650 unit_nr, dbcsr_time, dbcsr_nflop, mp2_env, qs_env)
1651 pspin = 2
1652 qspin = 1
1653 CALL calc_laplace_loop_forces(force_data, mat_p_omega(:, 1, :), t_3c_m, t_3c_o(1, 1), &
1654 t_3c_o_compressed(1, 1, :), t_3c_o_ind(1, 1, :), cfm_mo_coeff, homo, &
1655 starts_array_mc, ends_array_mc, starts_array_mc_block, &
1656 ends_array_mc_block, nmo, eigenval(:, 1, :), &
1657 time_frequency_grid, &
1658 cut_memory, pspin, qspin, my_open_shell, &
1659 unit_nr, dbcsr_time, dbcsr_nflop, mp2_env, qs_env)
1660
1661 ELSE
1662 pspin = 1
1663 qspin = 1
1664 CALL calc_laplace_loop_forces(force_data, mat_p_omega(:, 1, :), t_3c_m, t_3c_o(1, 1), &
1665 t_3c_o_compressed(1, 1, :), t_3c_o_ind(1, 1, :), cfm_mo_coeff, homo, &
1666 starts_array_mc, ends_array_mc, starts_array_mc_block, &
1667 ends_array_mc_block, nmo, eigenval(:, 1, :), &
1668 time_frequency_grid, &
1669 cut_memory, pspin, qspin, my_open_shell, &
1670 unit_nr, dbcsr_time, dbcsr_nflop, mp2_env, qs_env)
1671 END IF
1672 CALL calc_post_loop_forces(force_data, unit_nr, qs_env)
1673 END IF !laplace SOS-MP2
1674
1675 IF (calc_forces .AND. do_im_time .AND. .NOT. do_ri_sos_laplace_mp2) THEN
1676 DO ispin = 1, nspins
1677 CALL calc_rpa_loop_forces(force_data, mat_p_omega(:, 1, :), t_3c_m, t_3c_o(1, 1), &
1678 t_3c_o_compressed(1, 1, :), t_3c_o_ind(1, 1, :), cfm_mo_coeff, homo, &
1679 starts_array_mc, ends_array_mc, starts_array_mc_block, &
1680 ends_array_mc_block, nmo, eigenval(:, 1, :), &
1681 e_fermi(ispin), time_frequency_grid, cut_memory, ispin, my_open_shell, &
1682 unit_nr, dbcsr_time, &
1683 dbcsr_nflop, mp2_env, qs_env)
1684 END DO
1685 CALL calc_post_loop_forces(force_data, unit_nr, qs_env)
1686 END IF
1687
1688 IF (do_im_time) THEN
1689
1690 my_flop_rate = real(dbcsr_nflop, dp)/(1.0e09_dp*dbcsr_time)
1691 IF (unit_nr > 0) WRITE (unit=unit_nr, fmt="(/T3,A,T73,ES8.2)") &
1692 "PERFORMANCE| DBCSR total number of flops:", real(dbcsr_nflop*para_env%num_pe, dp)
1693 IF (unit_nr > 0) WRITE (unit=unit_nr, fmt="(T3,A,T66,F15.2)") &
1694 "PERFORMANCE| DBCSR total execution time:", dbcsr_time
1695 IF (unit_nr > 0) WRITE (unit=unit_nr, fmt="(T3,A,T66,F15.2)") &
1696 "PERFORMANCE| DBCSR flop rate (Gflops / MPI rank):", my_flop_rate
1697
1698 ELSE
1699
1700 CALL dgemm_counter_write(dgemm_counter, para_env)
1701
1702 END IF
1703
1704 ! GW: for low-scaling calculation: Compute self-energy Sigma(i*tau), Sigma(i*omega)
1705 ! for low-scaling and ordinary-scaling: analytic continuation from Sigma(iw) -> Sigma(w)
1706 ! and correction of quasiparticle energies e_n^GW
1707 IF (my_do_gw) THEN
1708
1709 CALL compute_qp_energies(vec_sigma_c_gw, count_ev_sc_gw, gw_corr_lev_occ, &
1710 gw_corr_lev_tot, gw_corr_lev_virt, homo, &
1711 nmo, num_fit_points, &
1712 unit_nr, do_apply_ic_corr_to_gw, do_im_time, &
1713 do_periodic, do_ri_sigma_x, first_cycle_periodic_correction, &
1714 e_fermi, eps_filter, fermi_level_offset, &
1715 delta_corr, eigenval, &
1716 eigenval_last, eigenval_scf, iter_sc_gw0, exit_ev_gw, &
1717 time_frequency_grid, vec_omega_fit_gw, vec_sigma_x_gw, &
1718 mp2_env%ri_g0w0%ic_corr_list, &
1719 cfm_mo_coeff, mo_coeff(1), fm_mat_w, para_env, &
1720 para_env_rpa, mat_dm, mat_minvvminv, &
1721 t_3c_o, t_3c_m, t_3c_overl_int_ao_mo, t_3c_o_compressed, t_3c_o_mo_compressed, &
1722 t_3c_o_ind, t_3c_o_mo_ind, &
1723 t_3c_overl_int_gw_ri, t_3c_overl_int_gw_ao, &
1724 matrix_berry_im_mo_mo, matrix_berry_re_mo_mo, mat_w, matrix_s, &
1725 kpoints, mp2_env, qs_env, nkp_self_energy, do_kpoints_cubic_rpa, &
1726 starts_array_mc, ends_array_mc)
1727
1728 ! if HOMO-LUMO gap differs by less than mp2_env%ri_g0w0%eps_ev_sc_iter, exit ev sc GW loop
1729 IF (exit_ev_gw) EXIT
1730
1731 END IF ! my_do_gw if
1732
1733 END DO ! evGW loop
1734
1735 IF (do_ic_model) THEN
1736
1737 IF (my_open_shell) THEN
1738
1739 CALL calculate_ic_correction(eigenval(:, 1, 1), mat_minvvminv%matrix, &
1740 t_3c_overl_nnp_ic(1), t_3c_overl_nnp_ic_reflected(1), &
1741 gw_corr_lev_tot, &
1742 gw_corr_lev_occ(1), gw_corr_lev_virt(1), homo(1), unit_nr, &
1743 print_ic_values, para_env, do_alpha=.true.)
1744
1745 CALL calculate_ic_correction(eigenval(:, 1, 2), mat_minvvminv%matrix, &
1746 t_3c_overl_nnp_ic(2), t_3c_overl_nnp_ic_reflected(2), &
1747 gw_corr_lev_tot, &
1748 gw_corr_lev_occ(2), gw_corr_lev_virt(2), homo(2), unit_nr, &
1749 print_ic_values, para_env, do_beta=.true.)
1750
1751 ELSE
1752
1753 CALL calculate_ic_correction(eigenval(:, 1, 1), mat_minvvminv%matrix, &
1754 t_3c_overl_nnp_ic(1), t_3c_overl_nnp_ic_reflected(1), &
1755 gw_corr_lev_tot, &
1756 gw_corr_lev_occ(1), gw_corr_lev_virt(1), homo(1), unit_nr, &
1757 print_ic_values, para_env)
1758
1759 END IF
1760
1761 END IF
1762
1763 ! postprocessing after GW for Bethe-Salpeter
1764 IF (do_bse) THEN
1765 ! Check used GW flavor; in Case of evGW we use W0 for BSE
1766 ! Use environment variable, since local iter_evGW is overwritten if evGW0 is invoked
1767 IF (mp2_env%ri_g0w0%iter_evGW > 1) THEN
1768 IF (unit_nr > 0) THEN
1769 CALL cp_warn(__location__, &
1770 "BSE@evGW applies W0, i.e. screening with DFT energies to the BSE!")
1771 END IF
1772 END IF
1773 ! Create a per-spin copy of fm_mat_S for usage in BSE
1774 ALLOCATE (fm_mat_s_ia_bse(nspins))
1775 DO ispin = 1, nspins
1776 CALL cp_fm_create(fm_mat_s_ia_bse(ispin), fm_mat_s(ispin)%matrix_struct)
1777 CALL cp_fm_to_fm(fm_mat_s(ispin), fm_mat_s_ia_bse(ispin))
1778 ! Remove energy/frequency factor from 3c-Integral for BSE
1779 IF (iter_sc_gw0 == 1) THEN
1780 CALL remove_scaling_factor_rpa(fm_mat_s_ia_bse(ispin), virtual(ispin), &
1781 eigenval_last(:, 1, ispin), homo(ispin), omega)
1782 ELSE
1783 CALL remove_scaling_factor_rpa(fm_mat_s_ia_bse(ispin), virtual(ispin), &
1784 eigenval_scf(:, 1, ispin), homo(ispin), omega)
1785 END IF
1786 END DO
1787 ! Main routine for all BSE postprocessing
1788 CALL start_bse_calculation(fm_mat_s_ia_bse, fm_mat_s_ij_bse, fm_mat_s_ab_bse, &
1789 fm_mat_q_static_bse_gemm, &
1790 eigenval, eigenval_scf, &
1791 homo, virtual, dimen_ri, dimen_ri_red, bse_lev_virt, &
1792 gd_array, color_sub, mp2_env, qs_env, mo_coeff, unit_nr)
1793 ! Release per-spin BSE-copy of fm_mat_S
1794 DO ispin = 1, nspins
1795 CALL cp_fm_release(fm_mat_s_ia_bse(ispin))
1796 END DO
1797 DEALLOCATE (fm_mat_s_ia_bse)
1798 END IF
1799
1800 IF (my_do_gw) THEN
1801 CALL deallocate_matrices_gw(fm_mat_s_gw_work, vec_w_gw, vec_sigma_c_gw, vec_omega_fit_gw, &
1802 mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw, &
1803 eigenval_last, eigenval_scf, do_periodic, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
1804 kpoints, vec_sigma_x_gw,.NOT. do_im_time)
1805 END IF
1806
1807 IF (do_im_time) THEN
1808
1809 CALL dealloc_im_time(cfm_mo_coeff, index_to_cell_3c, &
1810 cell_to_index_3c, do_ic_model, &
1811 do_kpoints_cubic_rpa, do_kpoints_from_gamma, do_ri_sigma_x, &
1812 has_mat_p_blocks, &
1813 wkp_w, cfm_mat_q, fm_mat_minv_l_kpoints, fm_mat_l_kpoints, &
1814 fm_matrix_minv, fm_matrix_minv_vtrunc_minv, fm_mat_ri_global_work, fm_mat_work, &
1815 mat_dm, mat_l, &
1816 mat_minvvminv, mat_p_omega, mat_p_omega_kp, &
1817 t_3c_m, t_3c_o, t_3c_o_compressed, t_3c_o_ind, mat_work, qs_env)
1818
1819 IF (my_do_gw) THEN
1820 CALL deallocate_matrices_gw_im_time(do_ic_model, do_kpoints_cubic_rpa, fm_mat_w, &
1821 t_3c_overl_int_ao_mo, t_3c_o_mo_compressed, t_3c_o_mo_ind, &
1822 t_3c_overl_int_gw_ri, t_3c_overl_int_gw_ao, &
1823 t_3c_overl_nnp_ic, t_3c_overl_nnp_ic_reflected, &
1824 mat_w, qs_env)
1825 END IF
1826
1827 END IF
1828
1829 IF (.NOT. do_im_time .AND. .NOT. do_ri_sos_laplace_mp2) CALL exchange_work%release()
1830
1831 IF (.NOT. do_ri_sos_laplace_mp2) THEN
1832 DEALLOCATE (trace_qomega)
1833 END IF
1834
1835 CALL time_frequency_grid_release(time_frequency_grid)
1836
1837 IF (do_im_time .AND. calc_forces) THEN
1838 CALL im_time_force_release(force_data)
1839 END IF
1840
1841 IF (calc_forces .AND. .NOT. do_im_time) CALL rpa_grad_finalize(rpa_grad, mp2_env, para_env_sub, para_env, &
1842 qs_env, gd_array, color_sub, do_ri_sos_laplace_mp2, &
1843 homo, virtual)
1844
1845 CALL timestop(handle)
1846
1847 END SUBROUTINE rpa_num_int
1848
1849! **************************************************************************************************
1850!> \brief ...
1851!> \param para_env ...
1852!> \param unit_nr ...
1853!> \param homo ...
1854!> \param Eigenval ...
1855!> \param num_integ_points ...
1856!> \param do_im_time ...
1857!> \param do_ri_sos_laplace_mp2 ...
1858!> \param do_print ...
1859!> \param qs_env ...
1860!> \param do_gw_im_time ...
1861!> \param do_kpoints_cubic_RPA ...
1862!> \param e_fermi ...
1863!> \param grid ...
1864! **************************************************************************************************
1865 SUBROUTINE get_minimax_grid(para_env, unit_nr, homo, Eigenval, num_integ_points, &
1866 do_im_time, do_ri_sos_laplace_mp2, do_print, qs_env, do_gw_im_time, &
1867 do_kpoints_cubic_RPA, e_fermi, grid)
1868
1869 TYPE(mp_para_env_type), INTENT(IN) :: para_env
1870 INTEGER, INTENT(IN) :: unit_nr
1871 INTEGER, DIMENSION(:), INTENT(IN) :: homo
1872 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: eigenval
1873 INTEGER, INTENT(IN) :: num_integ_points
1874 LOGICAL, INTENT(IN) :: do_im_time, do_ri_sos_laplace_mp2, &
1875 do_print
1876 TYPE(qs_environment_type), POINTER :: qs_env
1877 LOGICAL, INTENT(IN) :: do_gw_im_time, do_kpoints_cubic_rpa
1878 REAL(kind=dp), INTENT(OUT) :: e_fermi
1879 TYPE(time_frequency_grid_type), INTENT(OUT) :: grid
1880
1881 CHARACTER(LEN=*), PARAMETER :: routinen = 'get_minimax_grid'
1882 INTEGER, PARAMETER :: num_points_per_magnitude = 200
1883
1884 INTEGER :: handle, jquad
1885 LOGICAL :: used_external_backend
1886 REAL(kind=dp) :: e_range, emax, emin, max_error_min
1887
1888 CALL timeset(routinen, handle)
1889
1890 CALL determine_energy_range(qs_env, para_env, homo, eigenval, do_ri_sos_laplace_mp2, &
1891 do_kpoints_cubic_rpa, emin, emax, e_range, e_fermi)
1892
1893 ! Open-shell uses ONE minimax grid for the combined [min gap, max span] over both spins (the
1894 ! superset covers each channel, so it is accurate; per-spin grids would only be more efficient).
1895 IF (SIZE(homo) > 1) THEN
1896 CALL cp_hint(__location__, &
1897 "Open-shell RPA/GW uses one minimax grid spanning [min gap, max span] across "// &
1898 "both spin channels; raise QUADRATURE_POINTS if QP convergence is marginal for "// &
1899 "strongly spin-asymmetric systems.")
1900 END IF
1901
1902 CALL build_minimax_time_frequency_grid(num_integ_points, emin, emax, &
1903 qs_env%mp2_env%ri_g0w0%regularization_minimax, &
1904 num_points_per_magnitude, grid, &
1905 build_frequency=.NOT. do_ri_sos_laplace_mp2, &
1906 build_time=do_im_time .OR. do_ri_sos_laplace_mp2, &
1907 build_transforms=do_im_time .AND. .NOT. do_ri_sos_laplace_mp2, &
1908 build_sine=do_im_time .AND. (.NOT. do_ri_sos_laplace_mp2) .AND. do_gw_im_time, &
1909 time_scaling=merge(1.0_dp, 2.0_dp, do_ri_sos_laplace_mp2), &
1910 time_weight_scaling=merge(1.0_dp, 2.0_dp, do_ri_sos_laplace_mp2), &
1911 max_fit_error=max_error_min, print_warning=.true., unit_nr=unit_nr, &
1912 prefer_external_backend=.true., used_external_backend=used_external_backend)
1913
1914 ! Keep the native diagnostics and warning behavior in this RPA policy wrapper. The external
1915 ! backend reports its diagnostics from the grid builder.
1916 IF (used_external_backend) THEN
1917 CALL timestop(handle)
1918 RETURN
1919 END IF
1920
1921 IF (num_integ_points > 20 .AND. e_range < 100.0_dp) THEN
1922 IF (unit_nr > 0) THEN
1923 CALL cp_warn(__location__, &
1924 "You requested a large minimax grid (> 20 points) for a small minimax range R (R < 100). "// &
1925 "That may lead to numerical "// &
1926 "instabilities when computing minimax grid weights. You can prevent small ranges by choosing "// &
1927 "a larger basis set with higher angular momenta or alternatively using all-electron calculations.")
1928 END IF
1929 END IF
1930
1931 IF (.NOT. do_ri_sos_laplace_mp2) THEN
1932 IF (unit_nr > 0 .AND. do_print) THEN
1933 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
1934 "MINIMAX_INFO| Number of integration points:", num_integ_points
1935 WRITE (unit=unit_nr, fmt="(T3,A,T66,F15.4)") &
1936 "MINIMAX_INFO| Gap for the minimax approximation:", emin
1937 WRITE (unit=unit_nr, fmt="(T3,A,T66,F15.4)") &
1938 "MINIMAX_INFO| Range for the minimax approximation:", e_range
1939 WRITE (unit=unit_nr, fmt="(T3,A,T54,A,T72,A)") "MINIMAX_INFO| Minimax parameters:", "Weights", "Abscissas"
1940 DO jquad = 1, num_integ_points
1941 WRITE (unit=unit_nr, fmt="(T41,F20.10,F20.10)") &
1942 grid%frequency_weights(jquad)/emin, grid%frequency(jquad)/emin
1943 END DO
1944 CALL m_flush(unit_nr)
1945 END IF
1946 END IF
1947
1948 IF (do_im_time .OR. do_ri_sos_laplace_mp2) THEN
1949 IF (unit_nr > 0 .AND. do_print) THEN
1950 WRITE (unit=unit_nr, fmt="(T3,A,T66,F15.4)") &
1951 "MINIMAX_INFO| Range for the minimax approximation:", e_range
1952 WRITE (unit=unit_nr, fmt="(T3,A,T66,F15.4)") &
1953 "MINIMAX_INFO| Gap:", emin
1954 WRITE (unit=unit_nr, fmt="(T3,A,T54,A,T72,A)") &
1955 "MINIMAX_INFO| Minimax parameters of the time grid:", "Weights", "Abscissas"
1956 DO jquad = 1, num_integ_points
1957 WRITE (unit=unit_nr, fmt="(T41,F20.10,F20.10)") &
1958 grid%time_weights_at_zero_frequency(jquad)*emin, grid%imaginary_time(jquad)*emin
1959 END DO
1960 CALL m_flush(unit_nr)
1961 END IF
1962
1963 IF (unit_nr > 0 .AND. do_im_time .AND. do_gw_im_time .AND. .NOT. do_ri_sos_laplace_mp2) THEN
1964 WRITE (unit=unit_nr, fmt="(T3,A,T66,ES15.2)") &
1965 "MINIMAX_INFO| Maximum deviation among requested minimax transform fits:", max_error_min
1966 END IF
1967 END IF
1968
1969 CALL timestop(handle)
1970
1971 END SUBROUTINE get_minimax_grid
1972
1973! **************************************************************************************************
1974!> \brief Construct a Clenshaw-Curtis grid after determining its RPA scaling.
1975!> \param para_env ...
1976!> \param para_env_RPA ...
1977!> \param unit_nr ...
1978!> \param homo ...
1979!> \param virtual ...
1980!> \param Eigenval ...
1981!> \param num_integ_points ...
1982!> \param num_integ_group ...
1983!> \param color_rpa_group ...
1984!> \param fm_mat_S ...
1985!> \param my_do_gw ...
1986!> \param ext_scaling ...
1987!> \param grid ...
1988! **************************************************************************************************
1989 SUBROUTINE get_clenshaw_grid(para_env, para_env_RPA, unit_nr, homo, virtual, Eigenval, num_integ_points, &
1990 num_integ_group, color_rpa_group, fm_mat_S, my_do_gw, &
1991 ext_scaling, grid)
1992
1993 TYPE(mp_para_env_type), INTENT(IN) :: para_env, para_env_rpa
1994 INTEGER, INTENT(IN) :: unit_nr
1995 INTEGER, DIMENSION(:), INTENT(IN) :: homo, virtual
1996 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: eigenval
1997 INTEGER, INTENT(IN) :: num_integ_points, num_integ_group, &
1998 color_rpa_group
1999 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fm_mat_s
2000 LOGICAL, INTENT(IN) :: my_do_gw
2001 REAL(kind=dp), INTENT(IN) :: ext_scaling
2002 TYPE(time_frequency_grid_type), INTENT(OUT) :: grid
2003
2004 CHARACTER(LEN=*), PARAMETER :: routinen = 'get_clenshaw_grid'
2005
2006 INTEGER :: handle
2007 REAL(kind=dp) :: a_scaling
2008
2009 CALL timeset(routinen, handle)
2010
2011 CALL build_clenshaw_grid(num_integ_points, grid)
2012
2013 IF (my_do_gw .AND. ext_scaling > 0.0_dp) THEN
2014 a_scaling = ext_scaling
2015 ELSE
2016 CALL calc_scaling_factor(a_scaling, para_env, para_env_rpa, homo, virtual, eigenval, &
2017 num_integ_points, num_integ_group, color_rpa_group, &
2018 grid%frequency, grid%frequency_weights, fm_mat_s)
2019 END IF
2020
2021 IF (unit_nr > 0) WRITE (unit_nr, '(T3,A,T56,F25.5)') 'INTEG_INFO| Scaling parameter:', a_scaling
2022
2023 grid%frequency_weights(:) = grid%frequency_weights(:)*a_scaling
2024 grid%frequency(:) = a_scaling/tan(grid%frequency(:))
2025
2026 CALL timestop(handle)
2027
2028 END SUBROUTINE get_clenshaw_grid
2029
2030! **************************************************************************************************
2031!> \brief ...
2032!> \param a_scaling_ext ...
2033!> \param para_env ...
2034!> \param para_env_RPA ...
2035!> \param homo ...
2036!> \param virtual ...
2037!> \param Eigenval ...
2038!> \param num_integ_points ...
2039!> \param num_integ_group ...
2040!> \param color_rpa_group ...
2041!> \param tj_ext ...
2042!> \param wj_ext ...
2043!> \param fm_mat_S ...
2044! **************************************************************************************************
2045 SUBROUTINE calc_scaling_factor(a_scaling_ext, para_env, para_env_RPA, homo, virtual, Eigenval, &
2046 num_integ_points, num_integ_group, color_rpa_group, &
2047 tj_ext, wj_ext, fm_mat_S)
2048 REAL(kind=dp), INTENT(OUT) :: a_scaling_ext
2049 TYPE(mp_para_env_type), INTENT(IN) :: para_env, para_env_rpa
2050 INTEGER, DIMENSION(:), INTENT(IN) :: homo, virtual
2051 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: eigenval
2052 INTEGER, INTENT(IN) :: num_integ_points, num_integ_group, &
2053 color_rpa_group
2054 REAL(kind=dp), ALLOCATABLE, DIMENSION(:), &
2055 INTENT(IN) :: tj_ext, wj_ext
2056 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fm_mat_s
2057
2058 CHARACTER(LEN=*), PARAMETER :: routinen = 'calc_scaling_factor'
2059
2060 INTEGER :: handle, icycle, jquad, ncol_local, &
2061 ncol_local_beta, nspins
2062 LOGICAL :: my_open_shell
2063 REAL(kind=dp) :: a_high, a_low, a_scaling, conv_param, eps, first_deriv, left_term, &
2064 right_term, right_term_ref, right_term_ref_beta, step
2065 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: cottj, d_ia, d_ia_beta, iaia_ri, &
2066 iaia_ri_beta, m_ia, m_ia_beta
2067 TYPE(mp_para_env_type), POINTER :: para_env_col, para_env_col_beta
2068
2069 CALL timeset(routinen, handle)
2070
2071 nspins = SIZE(homo)
2072 my_open_shell = (nspins == 2)
2073
2074 eps = 1.0e-10_dp
2075
2076 ALLOCATE (cottj(num_integ_points))
2077
2078 ! calculate the cotangent of the abscissa tj
2079 DO jquad = 1, num_integ_points
2080 cottj(jquad) = 1.0_dp/tan(tj_ext(jquad))
2081 END DO
2082
2083 CALL calc_ia_ia_integrals(para_env_rpa, homo(1), virtual(1), ncol_local, right_term_ref, eigenval(:, 1, 1), &
2084 d_ia, iaia_ri, m_ia, fm_mat_s(1), para_env_col)
2085
2086 ! In the open shell case do point 1-2-3 for the beta spin
2087 IF (my_open_shell) THEN
2088 CALL calc_ia_ia_integrals(para_env_rpa, homo(2), virtual(2), ncol_local_beta, right_term_ref_beta, eigenval(:, 1, 2), &
2089 d_ia_beta, iaia_ri_beta, m_ia_beta, fm_mat_s(2), para_env_col_beta)
2090
2091 right_term_ref = right_term_ref + right_term_ref_beta
2092 END IF
2093
2094 ! bcast the result
2095 IF (para_env%mepos == 0) THEN
2096 CALL para_env%bcast(right_term_ref, 0)
2097 ELSE
2098 right_term_ref = 0.0_dp
2099 CALL para_env%bcast(right_term_ref, 0)
2100 END IF
2101
2102 ! 5) start iteration for solving the non-linear equation by bisection
2103 ! find limit, here step=0.5 seems a good compromise
2104 conv_param = 100.0_dp*epsilon(right_term_ref)
2105 step = 0.5_dp
2106 a_low = 0.0_dp
2107 a_high = step
2108 right_term = -right_term_ref
2109 DO icycle = 1, num_integ_points*2
2110 a_scaling = a_high
2111
2112 CALL calculate_objfunc(a_scaling, left_term, first_deriv, num_integ_points, my_open_shell, &
2113 m_ia, cottj, wj_ext, d_ia, d_ia_beta, m_ia_beta, &
2114 ncol_local, ncol_local_beta, num_integ_group, color_rpa_group, &
2115 para_env, para_env_col, para_env_col_beta)
2116 left_term = left_term/4.0_dp/pi*a_scaling
2117
2118 IF (abs(left_term) > abs(right_term) .OR. abs(left_term + right_term) <= conv_param) EXIT
2119 a_low = a_high
2120 a_high = a_high + step
2121
2122 END DO
2123
2124 IF (abs(left_term + right_term) >= conv_param) THEN
2125 IF (a_scaling >= 2*num_integ_points*step) THEN
2126 a_scaling = 1.0_dp
2127 ELSE
2128
2129 DO icycle = 1, num_integ_points*2
2130 a_scaling = (a_low + a_high)/2.0_dp
2131
2132 CALL calculate_objfunc(a_scaling, left_term, first_deriv, num_integ_points, my_open_shell, &
2133 m_ia, cottj, wj_ext, d_ia, d_ia_beta, m_ia_beta, &
2134 ncol_local, ncol_local_beta, num_integ_group, color_rpa_group, &
2135 para_env, para_env_col, para_env_col_beta)
2136 left_term = left_term/4.0_dp/pi*a_scaling
2137
2138 IF (abs(left_term) > abs(right_term)) THEN
2139 a_high = a_scaling
2140 ELSE
2141 a_low = a_scaling
2142 END IF
2143
2144 IF (abs(a_high - a_low) < 1.0e-5_dp) EXIT
2145
2146 END DO
2147
2148 END IF
2149 END IF
2150
2151 a_scaling_ext = a_scaling
2152 CALL para_env%bcast(a_scaling_ext, 0)
2153
2154 DEALLOCATE (cottj)
2155 DEALLOCATE (iaia_ri)
2156 DEALLOCATE (d_ia)
2157 DEALLOCATE (m_ia)
2158 CALL mp_para_env_release(para_env_col)
2159
2160 IF (my_open_shell) THEN
2161 DEALLOCATE (iaia_ri_beta)
2162 DEALLOCATE (d_ia_beta)
2163 DEALLOCATE (m_ia_beta)
2164 CALL mp_para_env_release(para_env_col_beta)
2165 END IF
2166
2167 CALL timestop(handle)
2168
2169 END SUBROUTINE calc_scaling_factor
2170
2171! **************************************************************************************************
2172!> \brief ...
2173!> \param para_env_RPA ...
2174!> \param homo ...
2175!> \param virtual ...
2176!> \param ncol_local ...
2177!> \param right_term_ref ...
2178!> \param Eigenval ...
2179!> \param D_ia ...
2180!> \param iaia_RI ...
2181!> \param M_ia ...
2182!> \param fm_mat_S ...
2183!> \param para_env_col ...
2184! **************************************************************************************************
2185 SUBROUTINE calc_ia_ia_integrals(para_env_RPA, homo, virtual, ncol_local, right_term_ref, Eigenval, &
2186 D_ia, iaia_RI, M_ia, fm_mat_S, para_env_col)
2187
2188 TYPE(mp_para_env_type), INTENT(IN) :: para_env_rpa
2189 INTEGER, INTENT(IN) :: homo, virtual
2190 INTEGER, INTENT(OUT) :: ncol_local
2191 REAL(kind=dp), INTENT(OUT) :: right_term_ref
2192 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: eigenval
2193 REAL(kind=dp), ALLOCATABLE, DIMENSION(:), &
2194 INTENT(OUT) :: d_ia, iaia_ri, m_ia
2195 TYPE(cp_fm_type), INTENT(IN) :: fm_mat_s
2196 TYPE(mp_para_env_type), POINTER :: para_env_col
2197
2198 CHARACTER(LEN=*), PARAMETER :: routinen = 'calc_ia_ia_integrals'
2199
2200 INTEGER :: avirt, color_col, color_row, handle, &
2201 i_global, iib, iocc, nrow_local
2202 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
2203 REAL(kind=dp) :: eigen_diff
2204 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: iaia_ri_dp
2205 TYPE(mp_para_env_type), POINTER :: para_env_row
2206
2207 CALL timeset(routinen, handle)
2208
2209 ! calculate the (ia|ia) RI integrals
2210 ! ----------------------------------
2211 ! 1) get info fm_mat_S
2212 CALL cp_fm_get_info(matrix=fm_mat_s, &
2213 nrow_local=nrow_local, &
2214 ncol_local=ncol_local, &
2215 row_indices=row_indices, &
2216 col_indices=col_indices)
2217
2218 ! allocate the local buffer of iaia_RI integrals (dp kind)
2219 ALLOCATE (iaia_ri_dp(ncol_local))
2220 iaia_ri_dp = 0.0_dp
2221
2222 ! 2) perform the local multiplication SUM_K (ia|K)*(ia|K)
2223 DO iib = 1, ncol_local
2224 iaia_ri_dp(iib) = iaia_ri_dp(iib) + dot_product(fm_mat_s%local_data(:, iib), fm_mat_s%local_data(:, iib))
2225 END DO
2226
2227 ! 3) sum the result with the processes of the RPA_group having the same columns
2228 ! _______ia______ _
2229 ! | | | | | | |
2230 ! --> | 1 | 5 | 9 | 13| SUM --> | |
2231 ! |___|__ |___|___| |_|
2232 ! | | | | | | |
2233 ! --> | 2 | 6 | 10| 14| SUM --> | |
2234 ! K |___|___|___|___| |_| (ia|ia)_RI
2235 ! | | | | | | |
2236 ! --> | 3 | 7 | 11| 15| SUM --> | |
2237 ! |___|___|___|___| |_|
2238 ! | | | | | | |
2239 ! --> | 4 | 8 | 12| 16| SUM --> | |
2240 ! |___|___|___|___| |_|
2241 !
2242
2243 color_col = fm_mat_s%matrix_struct%context%mepos(2)
2244 ALLOCATE (para_env_col)
2245 CALL para_env_col%from_split(para_env_rpa, color_col)
2246
2247 CALL para_env_col%sum(iaia_ri_dp)
2248
2249 ! convert the iaia_RI_dp into double-double precision
2250 ALLOCATE (iaia_ri(ncol_local))
2251 DO iib = 1, ncol_local
2252 iaia_ri(iib) = iaia_ri_dp(iib)
2253 END DO
2254 DEALLOCATE (iaia_ri_dp)
2255
2256 ! 4) calculate the right hand term, D_ia is the matrix containing the
2257 ! orbital energy differences, M_ia is the diagonal of the full RPA 'excitation'
2258 ! matrix
2259 ALLOCATE (d_ia(ncol_local))
2260
2261 ALLOCATE (m_ia(ncol_local))
2262
2263 DO iib = 1, ncol_local
2264 i_global = col_indices(iib)
2265
2266 iocc = max(1, i_global - 1)/virtual + 1
2267 avirt = i_global - (iocc - 1)*virtual
2268 eigen_diff = eigenval(avirt + homo) - eigenval(iocc)
2269
2270 d_ia(iib) = eigen_diff
2271 END DO
2272
2273 DO iib = 1, ncol_local
2274 m_ia(iib) = d_ia(iib)*d_ia(iib) + 2.0_dp*d_ia(iib)*iaia_ri(iib)
2275 END DO
2276
2277 right_term_ref = 0.0_dp
2278 DO iib = 1, ncol_local
2279 right_term_ref = right_term_ref + (sqrt(m_ia(iib)) - d_ia(iib) - iaia_ri(iib))
2280 END DO
2281 right_term_ref = right_term_ref/2.0_dp
2282
2283 ! sum the result with the processes of the RPA_group having the same row
2284 color_row = fm_mat_s%matrix_struct%context%mepos(1)
2285 ALLOCATE (para_env_row)
2286 CALL para_env_row%from_split(para_env_rpa, color_row)
2287
2288 ! allocate communication array for rows
2289 CALL para_env_row%sum(right_term_ref)
2290
2291 CALL mp_para_env_release(para_env_row)
2292
2293 CALL timestop(handle)
2294
2295 END SUBROUTINE calc_ia_ia_integrals
2296
2297! **************************************************************************************************
2298!> \brief ...
2299!> \param a_scaling ...
2300!> \param left_term ...
2301!> \param first_deriv ...
2302!> \param num_integ_points ...
2303!> \param my_open_shell ...
2304!> \param M_ia ...
2305!> \param cottj ...
2306!> \param wj ...
2307!> \param D_ia ...
2308!> \param D_ia_beta ...
2309!> \param M_ia_beta ...
2310!> \param ncol_local ...
2311!> \param ncol_local_beta ...
2312!> \param num_integ_group ...
2313!> \param color_rpa_group ...
2314!> \param para_env ...
2315!> \param para_env_col ...
2316!> \param para_env_col_beta ...
2317! **************************************************************************************************
2318 SUBROUTINE calculate_objfunc(a_scaling, left_term, first_deriv, num_integ_points, my_open_shell, &
2319 M_ia, cottj, wj, D_ia, D_ia_beta, M_ia_beta, &
2320 ncol_local, ncol_local_beta, num_integ_group, color_rpa_group, &
2321 para_env, para_env_col, para_env_col_beta)
2322 REAL(kind=dp), INTENT(IN) :: a_scaling
2323 REAL(kind=dp), INTENT(INOUT) :: left_term, first_deriv
2324 INTEGER, INTENT(IN) :: num_integ_points
2325 LOGICAL, INTENT(IN) :: my_open_shell
2326 REAL(kind=dp), ALLOCATABLE, DIMENSION(:), &
2327 INTENT(IN) :: m_ia, cottj, wj, d_ia, d_ia_beta, &
2328 m_ia_beta
2329 INTEGER, INTENT(IN) :: ncol_local, ncol_local_beta, &
2330 num_integ_group, color_rpa_group
2331 TYPE(mp_para_env_type), INTENT(IN) :: para_env, para_env_col
2332 TYPE(mp_para_env_type), POINTER :: para_env_col_beta
2333
2334 INTEGER :: iib, jquad
2335 REAL(kind=dp) :: first_deriv_beta, left_term_beta, omega
2336
2337 left_term = 0.0_dp
2338 first_deriv = 0.0_dp
2339 left_term_beta = 0.0_dp
2340 first_deriv_beta = 0.0_dp
2341 DO jquad = 1, num_integ_points
2342 ! parallelize over integration points
2343 IF (modulo(jquad, num_integ_group) /= color_rpa_group) cycle
2344 omega = a_scaling*cottj(jquad)
2345
2346 DO iib = 1, ncol_local
2347 ! parallelize over ia elements in the para_env_row group
2348 IF (modulo(iib, para_env_col%num_pe) /= para_env_col%mepos) cycle
2349 ! calculate left_term
2350 left_term = left_term + wj(jquad)* &
2351 (log(1.0_dp + (m_ia(iib) - d_ia(iib)**2)/(omega**2 + d_ia(iib)**2)) - &
2352 (m_ia(iib) - d_ia(iib)**2)/(omega**2 + d_ia(iib)**2))
2353 first_deriv = first_deriv + wj(jquad)*cottj(jquad)**2* &
2354 ((-m_ia(iib) + d_ia(iib)**2)**2/((omega**2 + d_ia(iib)**2)**2*(omega**2 + m_ia(iib))))
2355 END DO
2356
2357 IF (my_open_shell) THEN
2358 DO iib = 1, ncol_local_beta
2359 ! parallelize over ia elements in the para_env_row group
2360 IF (modulo(iib, para_env_col_beta%num_pe) /= para_env_col_beta%mepos) cycle
2361 ! calculate left_term
2362 left_term_beta = left_term_beta + wj(jquad)* &
2363 (log(1.0_dp + (m_ia_beta(iib) - d_ia_beta(iib)**2)/(omega**2 + d_ia_beta(iib)**2)) - &
2364 (m_ia_beta(iib) - d_ia_beta(iib)**2)/(omega**2 + d_ia_beta(iib)**2))
2365 first_deriv_beta = &
2366 first_deriv_beta + wj(jquad)*cottj(jquad)**2* &
2367 ((-m_ia_beta(iib) + d_ia_beta(iib)**2)**2/((omega**2 + d_ia_beta(iib)**2)**2*(omega**2 + m_ia_beta(iib))))
2368 END DO
2369 END IF
2370
2371 END DO
2372
2373 ! sum the contribution from all proc, starting form the row group
2374 CALL para_env%sum(left_term)
2375 CALL para_env%sum(first_deriv)
2376
2377 IF (my_open_shell) THEN
2378 CALL para_env%sum(left_term_beta)
2379 CALL para_env%sum(first_deriv_beta)
2380
2381 left_term = left_term + left_term_beta
2382 first_deriv = first_deriv + first_deriv_beta
2383 END IF
2384
2385 END SUBROUTINE calculate_objfunc
2386
2387! **************************************************************************************************
2388!> \brief ...
2389!> \param qs_env ...
2390!> \param para_env ...
2391!> \param gap ...
2392!> \param max_eig_diff ...
2393!> \param e_fermi ...
2394! **************************************************************************************************
2395 SUBROUTINE gap_and_max_eig_diff_kpoints(qs_env, para_env, gap, max_eig_diff, e_fermi)
2396
2397 TYPE(qs_environment_type), POINTER :: qs_env
2398 TYPE(mp_para_env_type), INTENT(IN) :: para_env
2399 REAL(kind=dp), INTENT(OUT) :: gap, max_eig_diff, e_fermi
2400
2401 CHARACTER(LEN=*), PARAMETER :: routinen = 'gap_and_max_eig_diff_kpoints'
2402
2403 INTEGER :: handle, homo, ikpgr, ispin, kplocal, &
2404 nmo, nspin
2405 INTEGER, DIMENSION(2) :: kp_range
2406 REAL(kind=dp) :: e_homo, e_homo_temp, e_lumo, e_lumo_temp
2407 REAL(kind=dp), DIMENSION(3) :: tmp
2408 REAL(kind=dp), DIMENSION(:), POINTER :: eigenvalues
2409 TYPE(kpoint_env_type), POINTER :: kp
2410 TYPE(kpoint_type), POINTER :: kpoint
2411 TYPE(mo_set_type), POINTER :: mo_set
2412
2413 CALL timeset(routinen, handle)
2414
2415 CALL get_qs_env(qs_env, &
2416 kpoints=kpoint)
2417
2418 mo_set => kpoint%kp_env(1)%kpoint_env%mos(1, 1)
2419 CALL get_mo_set(mo_set, nmo=nmo)
2420
2421 CALL get_kpoint_info(kpoint, kp_range=kp_range)
2422 kplocal = kp_range(2) - kp_range(1) + 1
2423
2424 gap = 1000.0_dp
2425 max_eig_diff = 0.0_dp
2426 e_homo = -1000.0_dp
2427 e_lumo = 1000.0_dp
2428
2429 DO ikpgr = 1, kplocal
2430 kp => kpoint%kp_env(ikpgr)%kpoint_env
2431 nspin = SIZE(kp%mos, 2)
2432 DO ispin = 1, nspin
2433 mo_set => kp%mos(1, ispin)
2434 CALL get_mo_set(mo_set, eigenvalues=eigenvalues, homo=homo)
2435 e_homo_temp = eigenvalues(homo)
2436 e_lumo_temp = eigenvalues(homo + 1)
2437
2438 IF (e_homo_temp > e_homo) e_homo = e_homo_temp
2439 IF (e_lumo_temp < e_lumo) e_lumo = e_lumo_temp
2440 IF (eigenvalues(nmo) - eigenvalues(1) > max_eig_diff) max_eig_diff = eigenvalues(nmo) - eigenvalues(1)
2441
2442 END DO
2443 END DO
2444
2445 ! Collect all three numbers in an array
2446 ! Reverse sign of lumo to reduce number of MPI calls
2447 tmp(1) = e_homo
2448 tmp(2) = -e_lumo
2449 tmp(3) = max_eig_diff
2450 CALL para_env%max(tmp)
2451
2452 gap = -tmp(2) - tmp(1)
2453 e_fermi = (tmp(1) - tmp(2))*0.5_dp
2454 max_eig_diff = tmp(3)
2455
2456 CALL timestop(handle)
2457
2458 END SUBROUTINE gap_and_max_eig_diff_kpoints
2459
2460! **************************************************************************************************
2461!> \brief returns minimal and maximal energy values for the E_range for the minimax grid selection
2462!> \param qs_env ...
2463!> \param para_env ...
2464!> \param homo index of the homo level for the respective spin channel
2465!> \param Eigenval eigenvalues
2466!> \param do_ri_sos_laplace_mp2 flag for SOS-MP2
2467!> \param do_kpoints_cubic_RPA flag for cubic-scaling RPA with k-points
2468!> \param Emin minimal eigenvalue difference (gap of the system)
2469!> \param Emax maximal eigenvalue difference
2470!> \param e_range ...
2471!> \param e_fermi Fermi level
2472! **************************************************************************************************
2473 SUBROUTINE determine_energy_range(qs_env, para_env, homo, Eigenval, do_ri_sos_laplace_mp2, &
2474 do_kpoints_cubic_RPA, Emin, Emax, e_range, e_fermi)
2475
2476 TYPE(qs_environment_type), POINTER :: qs_env
2477 TYPE(mp_para_env_type), INTENT(IN) :: para_env
2478 INTEGER, DIMENSION(:), INTENT(IN) :: homo
2479 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: eigenval
2480 LOGICAL, INTENT(IN) :: do_ri_sos_laplace_mp2, &
2481 do_kpoints_cubic_rpa
2482 REAL(kind=dp), INTENT(OUT) :: emin, emax, e_range, e_fermi
2483
2484 CHARACTER(LEN=*), PARAMETER :: routinen = 'determine_energy_range'
2485
2486 INTEGER :: handle, ispin, nspins
2487 LOGICAL :: my_do_kpoints
2488 TYPE(section_vals_type), POINTER :: input
2489
2490 CALL timeset(routinen, handle)
2491 ! Test for spin unrestricted
2492 nspins = SIZE(homo)
2493
2494 ! Test whether all necessary variables are available
2495 my_do_kpoints = .false.
2496 IF (.NOT. do_ri_sos_laplace_mp2) THEN
2497 my_do_kpoints = do_kpoints_cubic_rpa
2498 END IF
2499
2500 IF (my_do_kpoints) THEN
2501 CALL gap_and_max_eig_diff_kpoints(qs_env, para_env, emin, emax, e_fermi)
2502 e_range = emax/emin
2503 ELSE
2504 IF (qs_env%mp2_env%E_range <= 1.0_dp .OR. qs_env%mp2_env%E_gap <= 0.0_dp) THEN
2505 emin = huge(dp)
2506 emax = 0.0_dp
2507 DO ispin = 1, nspins
2508 IF (homo(ispin) > 0) THEN
2509 emin = min(emin, eigenval(homo(ispin) + 1, 1, ispin) - eigenval(homo(ispin), 1, ispin))
2510 emax = max(emax, maxval(eigenval(:, :, ispin)) - minval(eigenval(:, :, ispin)))
2511 END IF
2512 END DO
2513 e_range = emax/emin
2514 qs_env%mp2_env%e_range = e_range
2515 qs_env%mp2_env%e_gap = emin
2516
2517 CALL get_qs_env(qs_env, input=input)
2518 CALL section_vals_val_set(input, "DFT%XC%WF_CORRELATION%E_RANGE", r_val=e_range)
2519 CALL section_vals_val_set(input, "DFT%XC%WF_CORRELATION%E_GAP", r_val=emin)
2520 ELSE
2521 e_range = qs_env%mp2_env%E_range
2522 emin = qs_env%mp2_env%E_gap
2523 emax = emin*e_range
2524 END IF
2525 END IF
2526
2527 ! When we perform SOS-MP2, we need an additional factor of 2 for the energies (compare with mp2_laplace.F)
2528 ! We do not need weights etc. for the cosine transform
2529 ! We do not scale Emax because it is not needed for SOS-MP2
2530 IF (do_ri_sos_laplace_mp2) THEN
2531 emin = emin*2.0_dp
2532 emax = emax*2.0_dp
2533 END IF
2534
2535 CALL timestop(handle)
2536 END SUBROUTINE determine_energy_range
2537
2538END MODULE rpa_main
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public wilhelm2016b
integer, save, public delben2015
integer, save, public wilhelm2016a
integer, save, public wilhelm2018
integer, save, public delben2013
integer, save, public ren2013
integer, save, public wilhelm2017
integer, save, public ren2011
integer, save, public gruneis2009
integer, save, public freeman1977
integer, save, public bates2013
Main routines for GW + Bethe-Salpeter for computing electronic excitations.
Definition bse_main.F:14
subroutine, public start_bse_calculation(fm_mat_s_ia_bse, fm_mat_s_ij_bse, fm_mat_s_ab_bse, fm_mat_q_static_bse_gemm, eigenval, eigenval_scf, homo, virtual, dimen_ri, dimen_ri_red, bse_lev_virt, gd_array, color_sub, mp2_env, qs_env, mo_coeff, unit_nr)
Main subroutine managing BSE calculations.
Definition bse_main.F:92
methods related to the blacs parallel environment
subroutine, public cp_blacs_env_release(blacs_env)
releases the given blacs_env
subroutine, public cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
allocates and initializes a type that represent a blacs context
Represents a complex full matrix distributed on many processors.
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_clear(matrix)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
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_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
This is the start of a dbt_api, all publically needed functions are exported here....
Definition dbt_api.F:17
Counters to determine the performance of parallel DGEMMs.
elemental subroutine, public dgemm_counter_init(dgemm_counter, unit_nr, print_info)
Initialize a dgemm_counter.
subroutine, public dgemm_counter_write(dgemm_counter, para_env)
calculate and print flop rates
Types to describe group distributions.
elemental integer function, public maxsize(this)
...
Types and set/get functions for HFX.
Definition hfx_types.F:16
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public rpa_exchange_none
integer, parameter, public sigma_none
integer, parameter, public rpa_exchange_sosex
integer, parameter, public wfc_mm_style_gemm
integer, parameter, public rpa_exchange_axk
objects that represent the structure of input sections and the data contained in an input section
subroutine, public section_vals_val_set(section_vals, keyword_name, i_rep_section, i_rep_val, val, l_val, i_val, r_val, c_val, l_vals_ptr, i_vals_ptr, r_vals_ptr, c_vals_ptr)
sets the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public int_8
Definition kinds.F:54
integer, parameter, public dp
Definition kinds.F:34
Types and basic routines needed for a kpoint calculation.
subroutine, public get_kpoint_info(kpoint, kp_scheme, nkp_grid, kp_shift, symmetry, verbose, full_grid, use_real_wfn, eps_geo, parallel_group_size, kp_range, nkp, xkp, wkp, para_env, blacs_env_all, para_env_kp, para_env_inter_kp, blacs_env, kp_env, kp_aux_env, mpools, iogrp, nkp_groups, kp_dist, cell_to_index, index_to_cell, sab_nl, sab_nl_nosym, inversion_symmetry_only, symmetry_backend, symmetry_reduction_method, gamma_centered, lattice_fft)
Retrieve information from a kpoint environment.
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
subroutine, public m_memory(mem)
Returns the total amount of memory [bytes] in use, if known, zero otherwise.
Definition machine.F:440
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition machine.F:124
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
complex(kind=dp), parameter, public z_zero
Interface to the message passing library MPI.
subroutine, public mp_para_env_release(para_env)
releases the para object (to be called when you don't want anymore the shared copy of this object)
Routines to calculate the minimax coefficients in order to approximate 1/x as a sum over exponential ...
Definition minimax_exp.F:29
subroutine, public check_exp_minimax_range(k, rc, ierr)
Check that a minimax approximation is available for given input k, Rc. ierr == 0: everything ok ierr ...
Routines to calculate MP2 energy with laplace approach.
Definition mp2_laplace.F:13
subroutine, public sos_mp2_postprocessing(fm_mat_q, erpa, tau_wjquad)
...
Definition mp2_laplace.F:81
Routines for calculating RI-MP2 gradients.
subroutine, public array2fm(mat2d, fm_struct, my_start_row, my_end_row, my_start_col, my_end_col, gd_row, gd_col, group_grid_2_mepos, ngroup_row, ngroup_col, fm_mat, integ_group_size, color_group, do_release_mat)
redistribute local part of array to fm
Types needed for MP2 calculations.
Definition mp2_types.F:14
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
Auxiliary routines needed for RPA-exchange given blacs_env to another.
subroutine, public rpa_exchange_needed_mem(mp2_env, homo, virtual, dimen_ri, para_env, mem_per_rank, mem_per_repl)
...
Routines to calculate RI-RPA and SOS-MP2 gradients.
Definition rpa_grad.F:13
subroutine, public rpa_grad_finalize(rpa_grad, mp2_env, para_env_sub, para_env, qs_env, gd_array, color_sub, do_ri_sos_laplace_mp2, homo, virtual)
...
Definition rpa_grad.F:2034
subroutine, public rpa_grad_copy_q(fm_mat_q, rpa_grad)
...
Definition rpa_grad.F:713
pure subroutine, public rpa_grad_needed_mem(homo, virtual, dimen_ri, mem_per_rank, mem_per_repl, do_ri_sos_laplace_mp2)
Calculates the necessary minimum memory for the Gradient code ion MiB.
Definition rpa_grad.F:122
subroutine, public rpa_grad_create(rpa_grad, fm_mat_q, fm_mat_s, homo, virtual, mp2_env, eigenval, unit_nr, do_ri_sos_laplace_mp2)
Creates the arrays of a rpa_grad_type.
Definition rpa_grad.F:168
subroutine, public rpa_grad_matrix_operations(mp2_env, rpa_grad, do_ri_sos_laplace_mp2, fm_mat_q, fm_mat_q_gemm, dgemm_counter, fm_mat_s, omega, homo, virtual, eigenval, weight, unit_nr)
...
Definition rpa_grad.F:738
Routines to calculate image charge corrections.
Definition rpa_gw_ic.F:13
subroutine, public calculate_ic_correction(eigenval, mat_sinvvsinv, t_3c_overl_nnp_ic, t_3c_overl_nnp_ic_reflected, gw_corr_lev_tot, gw_corr_lev_occ, gw_corr_lev_virt, homo, unit_nr, print_ic_values, para_env, do_alpha, do_beta)
...
Definition rpa_gw_ic.F:58
Routines treating GW and RPA calculations with kpoints.
subroutine, public invert_eps_compute_w_and_erpa_kp(dimen_ri, jquad, nkp, count_ev_sc_gw, para_env, erpa, grid, wkp_w, do_gw_im_time, do_ri_sigma_x, do_kpoints_from_gamma, cfm_mat_q, ikp_local, mat_p_omega, mat_p_omega_kp, qs_env, eps_filter_im_time, unit_nr, kpoints, fm_mat_minv_l_kpoints, fm_matrix_l_kpoints, fm_mat_w, fm_mat_ri_global_work, mat_minvvminv, fm_matrix_minv, fm_matrix_minv_vtrunc_minv)
...
subroutine, public get_bandstruc_and_k_dependent_mos(qs_env, eigenval_kp)
...
Routines for GW, continuous development [Jan Wilhelm].
Definition rpa_gw.F:14
subroutine, public deallocate_matrices_gw(fm_mat_s_gw_work, vec_w_gw, vec_sigma_c_gw, vec_omega_fit_gw, vec_sigma_x_minus_vxc_gw, eigenval_last, eigenval_scf, do_periodic, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, kpoints, vec_sigma_x_gw, my_do_gw)
...
Definition rpa_gw.F:581
subroutine, public allocate_matrices_gw(vec_sigma_c_gw, color_rpa_group, dimen_nm_gw, gw_corr_lev_occ, gw_corr_lev_virt, homo, nmo, num_integ_group, unit_nr, gw_corr_lev_tot, num_fit_points, omega_max_fit, do_minimax_quad, do_periodic, do_ri_sigma_x, my_do_gw, first_cycle_periodic_correction, grid, eigenval, vec_omega_fit_gw, vec_sigma_x_gw, delta_corr, eigenval_last, eigenval_scf, vec_w_gw, fm_mat_s_gw, fm_mat_s_gw_work, para_env, mp2_env, kpoints, nkp, nkp_self_energy, do_kpoints_cubic_rpa, do_kpoints_from_gamma)
...
Definition rpa_gw.F:350
subroutine, public compute_gw_self_energy(vec_sigma_c_gw, dimen_nm_gw, dimen_ri, gw_corr_lev_occ, gw_corr_lev_virt, homo, jquad, nmo, num_fit_points, do_im_time, do_periodic, first_cycle_periodic_correction, fermi_level_offset, omega, eigenval, delta_corr, vec_omega_fit_gw, vec_w_gw, grid, fm_mat_q, fm_mat_r_gw, fm_mat_s_gw, fm_mat_s_gw_work, mo_coeff, para_env, para_env_rpa, matrix_berry_im_mo_mo, matrix_berry_re_mo_mo, kpoints, qs_env, mp2_env)
...
Definition rpa_gw.F:766
subroutine, public get_fermi_level_offset(fermi_level_offset, fermi_level_offset_input, eigenval, homo)
...
Definition rpa_gw.F:869
subroutine, public allocate_matrices_gw_im_time(gw_corr_lev_occ, gw_corr_lev_virt, homo, nmo, num_integ_points, unit_nr, ri_blk_sizes, do_ic_model, para_env, fm_mat_w, fm_mat_q, mo_coeff, t_3c_overl_int_ao_mo, t_3c_o_mo_compressed, t_3c_o_mo_ind, t_3c_overl_int_gw_ri, t_3c_overl_int_gw_ao, starts_array_mc, ends_array_mc, t_3c_overl_nnp_ic, t_3c_overl_nnp_ic_reflected, matrix_s, mat_w, t_3c_overl_int, t_3c_o_compressed, t_3c_o_ind, qs_env)
...
Definition rpa_gw.F:208
subroutine, public compute_w_cubic_gw(fm_mat_w, fm_mat_q, fm_mat_work, dimen_ri, fm_mat_l, grid, jquad, omega)
...
Definition rpa_gw.F:908
subroutine, public compute_qp_energies(vec_sigma_c_gw, count_ev_sc_gw, gw_corr_lev_occ, gw_corr_lev_tot, gw_corr_lev_virt, homo, nmo, num_fit_points, unit_nr, do_apply_ic_corr_to_gw, do_im_time, do_periodic, do_ri_sigma_x, first_cycle_periodic_correction, e_fermi, eps_filter, fermi_level_offset, delta_corr, eigenval, eigenval_last, eigenval_scf, iter_sc_gw0, exit_ev_gw, grid, vec_omega_fit_gw, vec_sigma_x_gw, ic_corr_list, cfm_mo_coeff, mo_coeff, fm_mat_w, para_env, para_env_rpa, mat_dm, mat_minvvminv, t_3c_o, t_3c_m, t_3c_overl_int_ao_mo, t_3c_o_compressed, t_3c_o_mo_compressed, t_3c_o_ind, t_3c_o_mo_ind, t_3c_overl_int_gw_ri, t_3c_overl_int_gw_ao, matrix_berry_im_mo_mo, matrix_berry_re_mo_mo, mat_w, matrix_s, kpoints, mp2_env, qs_env, nkp_self_energy, do_kpoints_cubic_rpa, starts_array_mc, ends_array_mc)
...
Definition rpa_gw.F:1175
subroutine, public deallocate_matrices_gw_im_time(do_ic_model, do_kpoints_cubic_rpa, fm_mat_w, t_3c_overl_int_ao_mo, t_3c_o_mo_compressed, t_3c_o_mo_ind, t_3c_overl_int_gw_ri, t_3c_overl_int_gw_ao, t_3c_overl_nnp_ic, t_3c_overl_nnp_ic_reflected, mat_w, qs_env)
...
Definition rpa_gw.F:653
Routines needed for cubic-scaling RPA and SOS-Laplace-MP2 forces.
subroutine, public calc_post_loop_forces(force_data, unit_nr, qs_env)
All the forces that can be calculated after the loop on the Laplace quaradture, using terms collected...
subroutine, public calc_rpa_loop_forces(force_data, mat_p_omega, t_3c_m, t_3c_o, t_3c_o_compressed, t_3c_o_ind, cfm_mo_coeff, homo, starts_array_mc, ends_array_mc, starts_array_mc_block, ends_array_mc_block, nmo, eigenval, e_fermi, grid, cut_memory, ispin, open_shell, unit_nr, dbcsr_time, dbcsr_nflop, mp2_env, qs_env)
Updates the cubic-scaling RPA contribution to the forces at each quadrature point....
subroutine, public calc_laplace_loop_forces(force_data, mat_p_omega, t_3c_m, t_3c_o, t_3c_o_compressed, t_3c_o_ind, cfm_mo_coeff, homo, starts_array_mc, ends_array_mc, starts_array_mc_block, ends_array_mc_block, nmo, eigenval, grid, cut_memory, pspin, qspin, open_shell, unit_nr, dbcsr_time, dbcsr_nflop, mp2_env, qs_env)
Updates the cubic-scaling SOS-Laplace-MP2 contribution to the forces at each quadrature point.
subroutine, public keep_initial_quad(grid, do_laplace, do_im_time, unit_nr, qs_env)
Overwrites the "optimal" Laplace quadrature with that of the first step.
subroutine, public init_im_time_forces(force_data, fm_matrix_pq, t_3c_m, unit_nr, mp2_env, qs_env)
Initializes and pre-calculates all needed tensors for the forces.
Types needed for cubic-scaling RPA and SOS-Laplace-MP2 forces.
subroutine, public im_time_force_release(force_data)
Cleans everything up.
Routines for low-scaling RPA/GW with imaginary time.
Definition rpa_im_time.F:13
subroutine, public zero_mat_p_omega(mat_p_omega)
...
subroutine, public compute_mat_p_omega(mat_p_omega, cfm_mo_coeff, homo, mat_p_global, matrix_s, ispin, t_3c_m, t_3c_o, t_3c_o_compressed, t_3c_o_ind, starts_array_mc, ends_array_mc, starts_array_mc_block, ends_array_mc_block, grid, e_fermi, eps_filter, alpha, eps_filter_im_time, eigenval, nmo, cut_memory, unit_nr, mp2_env, para_env, qs_env, do_kpoints_from_gamma, index_to_cell_3c, cell_to_index_3c, has_mat_p_blocks, do_ri_sos_laplace_mp2, dbcsr_time, dbcsr_nflop)
...
Routines to calculate RI-RPA energy.
Definition rpa_main.F:17
subroutine, public rpa_ri_compute_en(qs_env, erpa, mp2_env, bib_c, bib_c_gw, bib_c_bse_ij, bib_c_bse_ab, para_env, para_env_sub, color_sub, gd_array, gd_b_virtual, gd_b_all, gd_b_occ_bse, gd_b_virt_bse, mo_coeff, fm_matrix_pq, fm_matrix_l_kpoints, fm_matrix_minv_l_kpoints, fm_matrix_minv, fm_matrix_minv_vtrunc_minv, kpoints, eigenval, nmo, homo, dimen_ri, dimen_ri_red, gw_corr_lev_occ, gw_corr_lev_virt, bse_lev_virt, unit_nr, do_ri_sos_laplace_mp2, my_do_gw, do_im_time, do_bse, matrix_s, mat_munu, mat_p_global, t_3c_m, t_3c_o, t_3c_o_compressed, t_3c_o_ind, starts_array_mc, ends_array_mc, starts_array_mc_block, ends_array_mc_block, calc_forces)
...
Definition rpa_main.F:199
Routines to calculate RI-RPA energy and Sigma correction to the RPA energies using the cubic spline b...
subroutine, public rpa_sigma_create(rpa_sigma, sigma_param, fm_mat_q, unit_nr, para_env)
... Collect the Q(w) (fm_mat_Q) matrix to create rpa_sigma a derived type variable....
subroutine, public finalize_rpa_sigma(rpa_sigma, unit_nr, e_sigma_corr, para_env, do_minimax_quad)
... Save the calculated value of E_c correction to the global variable and memory clean.
subroutine, public rpa_sigma_matrix_spectral(rpa_sigma, fm_mat_q, wj, para_env_rpa)
... Diagonalize and store the eigenvalues of fm_mat_Q in rpa_sigmasigma_eigenvalue.
Utility functions for RPA calculations.
Definition rpa_util.F:13
subroutine, public alloc_im_time(qs_env, para_env, dimen_ri, dimen_ri_red, num_integ_points, nspins, fm_mat_q, cfm_mo_coeff, fm_matrix_minv_l_kpoints, fm_matrix_l_kpoints, mat_p_global, t_3c_o, matrix_s, kpoints, eps_filter_im_time, cut_memory, nkp, num_cells_dm, num_3c_repl, size_p, ikp_local, index_to_cell_3c, cell_to_index_3c, col_blk_size, do_ic_model, do_kpoints_cubic_rpa, do_kpoints_from_gamma, do_ri_sigma_x, my_open_shell, has_mat_p_blocks, wkp_w, cfm_mat_q, fm_mat_minv_l_kpoints, fm_mat_l_kpoints, fm_mat_ri_global_work, fm_mat_work, mat_dm, mat_l, mat_m_p_munu_occ, mat_m_p_munu_virt, mat_minvvminv, mat_p_omega, mat_p_omega_kp, mat_work, mo_coeff)
...
Definition rpa_util.F:145
subroutine, public compute_erpa_by_freq_int(dimen_ri, trace_qomega, fm_mat_q, para_env_rpa, erpa, wjquad)
...
Definition rpa_util.F:872
subroutine, public q_trace_and_add_unit_matrix(dimen_ri, trace_qomega, fm_mat_q)
...
Definition rpa_util.F:821
subroutine, public calc_mat_q(fm_mat_s, do_ri_sos_laplace_mp2, first_cycle, virtual, eigenval, homo, omega, omega_old, jquad, mm_style, dimen_ri, dimen_ia, alpha, fm_mat_q, fm_mat_q_gemm, do_bse, fm_mat_q_static_bse_gemm, dgemm_counter, num_integ_points, count_ev_sc_gw)
...
Definition rpa_util.F:604
subroutine, public contract_p_omega_with_mat_l(mat_p_omega, mat_l, mat_work, eps_filter_im_time, fm_mat_work, dimen_ri, dimen_ri_red, fm_mat_l, fm_mat_q)
...
Definition rpa_util.F:1192
subroutine, public dealloc_im_time(cfm_mo_coeff, index_to_cell_3c, cell_to_index_3c, do_ic_model, do_kpoints_cubic_rpa, do_kpoints_from_gamma, do_ri_sigma_x, has_mat_p_blocks, wkp_w, cfm_mat_q, fm_mat_minv_l_kpoints, fm_mat_l_kpoints, fm_matrix_minv, fm_matrix_minv_vtrunc_minv, fm_mat_ri_global_work, fm_mat_work, mat_dm, mat_l, mat_minvvminv, mat_p_omega, mat_p_omega_kp, t_3c_m, t_3c_o, t_3c_o_compressed, t_3c_o_ind, mat_work, qs_env)
...
Definition rpa_util.F:1052
subroutine, public remove_scaling_factor_rpa(fm_mat_s, virtual, eigenval_last, homo, omega_old)
...
Definition rpa_util.F:654
Definition and construction of time/frequency grids for correlation methods.
subroutine, public build_minimax_time_frequency_grid(num_points, energy_min, energy_max, regularization, num_points_per_magnitude, grid, build_frequency, build_time, build_transforms, build_sine, time_scaling, time_weight_scaling, max_fit_error, print_warning, unit_nr, prefer_external_backend, used_external_backend)
Build a minimax time/frequency grid through the common backend boundary.
subroutine, public build_clenshaw_grid(num_points, grid)
Build a Clenshaw-Curtis frequency grid.
subroutine, public time_frequency_grid_release(grid)
Release all data owned by a time_frequency_grid_type object.
All kind of helpful little routines.
Definition util.F:14
pure integer function, dimension(2), public get_limit(m, n, me)
divide m entries into n parts, return size of part me
Definition util.F:333
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
Represent a complex full matrix.
keeps the information about the structure of a full matrix
represent a full matrix
Keeps information about a specific k-point.
Contains information about kpoints.
stores all the informations relevant to an mpi environment