(git:374b731)
Loading...
Searching...
No Matches
gw_utils.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief
10!> \author Jan Wilhelm
11!> \date 07.2023
12! **************************************************************************************************
17 USE bibliography, ONLY: graml2024,&
18 cite_reference
19 USE cell_types, ONLY: cell_type,&
20 pbc
32 USE cp_fm_types, ONLY: cp_fm_create,&
37 USE dbcsr_api, ONLY: dbcsr_create,&
38 dbcsr_p_type
39 USE dbt_api, ONLY: &
40 dbt_clear, dbt_create, dbt_destroy, dbt_filter, dbt_iterator_blocks_left, &
41 dbt_iterator_next_block, dbt_iterator_start, dbt_iterator_stop, dbt_iterator_type, &
42 dbt_mp_environ_pgrid, dbt_pgrid_create, dbt_pgrid_destroy, dbt_pgrid_type, dbt_type
49 USE kinds, ONLY: default_string_length,&
50 dp,&
51 int_8
53 USE kpoint_types, ONLY: kpoint_create,&
57 USE machine, ONLY: m_memory,&
59 USE mathlib, ONLY: gcd
60 USE message_passing, ONLY: mp_cart_type,&
66 USE mp2_gpw, ONLY: create_mat_munu
73 USE physcon, ONLY: angstrom,&
74 evolt
82 USE qs_kind_types, ONLY: get_qs_kind,&
95#include "base/base_uses.f90"
96
97 IMPLICIT NONE
98
99 PRIVATE
100
103
104 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'gw_utils'
105
106CONTAINS
107
108! **************************************************************************************************
109!> \brief ...
110!> \param qs_env ...
111!> \param bs_env ...
112!> \param bs_sec ...
113! **************************************************************************************************
114 SUBROUTINE create_and_init_bs_env_for_gw(qs_env, bs_env, bs_sec)
115 TYPE(qs_environment_type), POINTER :: qs_env
116 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
117 TYPE(section_vals_type), POINTER :: bs_sec
118
119 CHARACTER(LEN=*), PARAMETER :: routinen = 'create_and_init_bs_env_for_gw'
120
121 INTEGER :: handle
122
123 CALL timeset(routinen, handle)
124
125 CALL cite_reference(graml2024)
126
127 CALL read_gw_input_parameters(bs_env, bs_sec)
128
129 CALL print_header_and_input_parameters(bs_env)
130
131 CALL setup_ao_and_ri_basis_set(qs_env, bs_env)
132
133 CALL get_ri_basis_and_basis_function_indices(qs_env, bs_env)
134
135 CALL setup_kpoints_chi_eps_w(qs_env, bs_env, bs_env%kpoints_chi_eps_W)
136
137 CALL set_heuristic_parameters(bs_env, qs_env)
138
139 CALL set_parallelization_parameters(qs_env, bs_env)
140
141 CALL allocate_and_fill_matrices_and_arrays(qs_env, bs_env)
142
144
145 CALL create_tensors(qs_env, bs_env)
146
147 CALL set_sparsity_parallelization_parameters(bs_env)
148
149 CALL check_for_restart_files(qs_env, bs_env)
150
151 CALL compute_fm_v_xc_gamma(qs_env, bs_env)
152
153 CALL setup_time_and_frequency_minimax_grid(bs_env)
154
155 ! free memory in qs_env; only if one is not calculating the LDOS because
156 ! we need real-space grid operations in pw_env, task_list for the LDOS
157 ! Recommendation in case of memory issues: first perform GW calculation without calculating
158 ! LDOS (to safe memor). Then, use GW restart files
159 ! in a subsequent calculation to calculate the LDOS
160 IF (.NOT. bs_env%do_ldos) THEN
161 CALL qs_env_part_release(qs_env)
162 END IF
163
164 CALL timestop(handle)
165
166 END SUBROUTINE create_and_init_bs_env_for_gw
167
168! **************************************************************************************************
169!> \brief ...
170!> \param bs_env ...
171! **************************************************************************************************
172 SUBROUTINE de_init_bs_env(bs_env)
173 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
174
175 CHARACTER(LEN=*), PARAMETER :: routinen = 'de_init_bs_env'
176
177 INTEGER :: handle
178
179 CALL timeset(routinen, handle)
180 ! deallocate quantities here which:
181 ! 1. cannot be deallocated in bs_env_release due to circular dependencies
182 ! 2. consume a lot of memory and should not be kept until the quantity is
183 ! deallocated in bs_env_release
184
185 IF (ASSOCIATED(bs_env%nl_3c%ij_list)) CALL neighbor_list_3c_destroy(bs_env%nl_3c)
186
188
189 CALL timestop(handle)
190
191 END SUBROUTINE de_init_bs_env
192
193! **************************************************************************************************
194!> \brief ...
195!> \param bs_env ...
196!> \param bs_sec ...
197! **************************************************************************************************
198 SUBROUTINE read_gw_input_parameters(bs_env, bs_sec)
199 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
200 TYPE(section_vals_type), POINTER :: bs_sec
201
202 CHARACTER(LEN=*), PARAMETER :: routinen = 'read_gw_input_parameters'
203
204 INTEGER :: handle
205 TYPE(section_vals_type), POINTER :: gw_sec
206
207 CALL timeset(routinen, handle)
208
209 NULLIFY (gw_sec)
210 gw_sec => section_vals_get_subs_vals(bs_sec, "GW")
211
212 CALL section_vals_val_get(gw_sec, "NUM_TIME_FREQ_POINTS", i_val=bs_env%num_time_freq_points)
213 CALL section_vals_val_get(gw_sec, "EPS_FILTER", r_val=bs_env%eps_filter)
214 CALL section_vals_val_get(gw_sec, "MEMORY_PER_PROC", r_val=bs_env%input_memory_per_proc_GB)
215 CALL section_vals_val_get(gw_sec, "APPROX_KP_EXTRAPOL", l_val=bs_env%approx_kp_extrapol)
216
217 CALL timestop(handle)
218
219 END SUBROUTINE read_gw_input_parameters
220
221! **************************************************************************************************
222!> \brief ...
223!> \param qs_env ...
224!> \param bs_env ...
225! **************************************************************************************************
226 SUBROUTINE setup_ao_and_ri_basis_set(qs_env, bs_env)
227 TYPE(qs_environment_type), POINTER :: qs_env
228 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
229
230 CHARACTER(LEN=*), PARAMETER :: routinen = 'setup_AO_and_RI_basis_set'
231
232 INTEGER :: handle, natom, nkind
233 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
234 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
235
236 CALL timeset(routinen, handle)
237
238 CALL get_qs_env(qs_env, &
239 qs_kind_set=qs_kind_set, &
240 particle_set=particle_set, &
241 natom=natom, nkind=nkind)
242
243 ! set up basis
244 ALLOCATE (bs_env%sizes_RI(natom), bs_env%sizes_AO(natom))
245 ALLOCATE (bs_env%basis_set_RI(nkind), bs_env%basis_set_AO(nkind))
246
247 CALL basis_set_list_setup(bs_env%basis_set_RI, "RI_AUX", qs_kind_set)
248 CALL basis_set_list_setup(bs_env%basis_set_AO, "ORB", qs_kind_set)
249
250 CALL get_particle_set(particle_set, qs_kind_set, nsgf=bs_env%sizes_RI, &
251 basis=bs_env%basis_set_RI)
252 CALL get_particle_set(particle_set, qs_kind_set, nsgf=bs_env%sizes_AO, &
253 basis=bs_env%basis_set_AO)
254
255 CALL timestop(handle)
256
257 END SUBROUTINE setup_ao_and_ri_basis_set
258
259! **************************************************************************************************
260!> \brief ...
261!> \param qs_env ...
262!> \param bs_env ...
263! **************************************************************************************************
264 SUBROUTINE get_ri_basis_and_basis_function_indices(qs_env, bs_env)
265 TYPE(qs_environment_type), POINTER :: qs_env
266 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
267
268 CHARACTER(LEN=*), PARAMETER :: routinen = 'get_RI_basis_and_basis_function_indices'
269
270 INTEGER :: handle, i_ri, iatom, ikind, iset, &
271 max_ao_bf_per_atom, n_ao_test, n_atom, &
272 n_kind, n_ri, nset, nsgf, u
273 INTEGER, ALLOCATABLE, DIMENSION(:) :: kind_of
274 INTEGER, DIMENSION(:), POINTER :: l_max, l_min, nsgf_set
275 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
276 TYPE(gto_basis_set_type), POINTER :: basis_set_a
277 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
278
279 CALL timeset(routinen, handle)
280
281 ! determine RI basis set size
282 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set)
283
284 n_kind = SIZE(qs_kind_set)
285 n_atom = bs_env%n_atom
286
287 CALL get_atomic_kind_set(atomic_kind_set, kind_of=kind_of)
288
289 DO ikind = 1, n_kind
290 CALL get_qs_kind(qs_kind=qs_kind_set(ikind), basis_set=basis_set_a, &
291 basis_type="RI_AUX")
292 cpassert(ASSOCIATED(basis_set_a))
293 END DO
294
295 ALLOCATE (bs_env%i_RI_start_from_atom(n_atom))
296 ALLOCATE (bs_env%i_RI_end_from_atom(n_atom))
297 ALLOCATE (bs_env%i_ao_start_from_atom(n_atom))
298 ALLOCATE (bs_env%i_ao_end_from_atom(n_atom))
299
300 n_ri = 0
301 DO iatom = 1, n_atom
302 bs_env%i_RI_start_from_atom(iatom) = n_ri + 1
303 ikind = kind_of(iatom)
304 CALL get_qs_kind(qs_kind=qs_kind_set(ikind), nsgf=nsgf, basis_type="RI_AUX")
305 n_ri = n_ri + nsgf
306 bs_env%i_RI_end_from_atom(iatom) = n_ri
307 END DO
308 bs_env%n_RI = n_ri
309
310 max_ao_bf_per_atom = 0
311 n_ao_test = 0
312 DO iatom = 1, n_atom
313 bs_env%i_ao_start_from_atom(iatom) = n_ao_test + 1
314 ikind = kind_of(iatom)
315 CALL get_qs_kind(qs_kind=qs_kind_set(ikind), nsgf=nsgf, basis_type="ORB")
316 n_ao_test = n_ao_test + nsgf
317 bs_env%i_ao_end_from_atom(iatom) = n_ao_test
318 max_ao_bf_per_atom = max(max_ao_bf_per_atom, nsgf)
319 END DO
320 cpassert(n_ao_test == bs_env%n_ao)
321 bs_env%max_AO_bf_per_atom = max_ao_bf_per_atom
322
323 ALLOCATE (bs_env%l_RI(n_ri))
324 i_ri = 0
325 DO iatom = 1, n_atom
326 ikind = kind_of(iatom)
327
328 nset = bs_env%basis_set_RI(ikind)%gto_basis_set%nset
329 l_max => bs_env%basis_set_RI(ikind)%gto_basis_set%lmax
330 l_min => bs_env%basis_set_RI(ikind)%gto_basis_set%lmin
331 nsgf_set => bs_env%basis_set_RI(ikind)%gto_basis_set%nsgf_set
332
333 DO iset = 1, nset
334 cpassert(l_max(iset) == l_min(iset))
335 bs_env%l_RI(i_ri + 1:i_ri + nsgf_set(iset)) = l_max(iset)
336 i_ri = i_ri + nsgf_set(iset)
337 END DO
338
339 END DO
340 cpassert(i_ri == n_ri)
341
342 u = bs_env%unit_nr
343
344 IF (u > 0) THEN
345 WRITE (unit=u, fmt="(T2,A)") " "
346 WRITE (unit=u, fmt="(T2,2A,T75,I8)") "Number of auxiliary Gaussian basis functions ", &
347 χε"for , , W", n_ri
348 END IF
349
350 CALL timestop(handle)
351
352 END SUBROUTINE get_ri_basis_and_basis_function_indices
353
354! **************************************************************************************************
355!> \brief ...
356!> \param qs_env ...
357!> \param bs_env ...
358!> \param kpoints ...
359! **************************************************************************************************
360 SUBROUTINE setup_kpoints_chi_eps_w(qs_env, bs_env, kpoints)
361
362 TYPE(qs_environment_type), POINTER :: qs_env
363 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
364 TYPE(kpoint_type), POINTER :: kpoints
365
366 CHARACTER(LEN=*), PARAMETER :: routinen = 'setup_kpoints_chi_eps_W'
367
368 INTEGER :: handle, i_dim, n_dim, nkp, nkp_extra, &
369 nkp_orig, u
370 INTEGER, DIMENSION(3) :: nkp_grid, nkp_grid_extra, periodic
371 REAL(kind=dp) :: exp_s_p, n_dim_inv
372
373 CALL timeset(routinen, handle)
374
375 ! routine adapted from mp2_integrals.F
376 NULLIFY (kpoints)
377 CALL kpoint_create(kpoints)
378
379 kpoints%kp_scheme = "GENERAL"
380
381 periodic(1:3) = bs_env%periodic(1:3)
382
383 DO i_dim = 1, 3
384
385 cpassert(periodic(i_dim) == 0 .OR. periodic(i_dim) == 1)
386
387 IF (periodic(i_dim) == 1) nkp_grid(i_dim) = 4
388 IF (periodic(i_dim) == 0) nkp_grid(i_dim) = 1
389
390 IF (periodic(i_dim) == 1) THEN
391 ! only even k-meshes in periodic direction implemented
392 cpassert(modulo(nkp_grid(i_dim), 2) == 0)
393 END IF
394 IF (periodic(i_dim) == 0) THEN
395 ! single k-kpoint in non-periodic direction needed
396 cpassert(nkp_grid(i_dim) == 1)
397 END IF
398
399 IF (periodic(i_dim) == 1) nkp_grid_extra(i_dim) = nkp_grid(i_dim) + 2
400 IF (periodic(i_dim) == 0) nkp_grid_extra(i_dim) = 1
401
402 END DO
403
404 nkp_orig = max(nkp_grid(1)*nkp_grid(2)*nkp_grid(3)/2, 1)
405
406 nkp_extra = nkp_grid_extra(1)*nkp_grid_extra(2)*nkp_grid_extra(3)/2
407
408 nkp = nkp_orig + nkp_extra
409
410 kpoints%nkp_grid(1:3) = nkp_grid(1:3)
411 kpoints%nkp = nkp
412
413 bs_env%nkp_grid_chi_eps_W_orig(1:3) = nkp_grid(1:3)
414 bs_env%nkp_grid_chi_eps_W_extra(1:3) = nkp_grid_extra(1:3)
415 bs_env%nkp_chi_eps_W_orig = nkp_orig
416 bs_env%nkp_chi_eps_W_extra = nkp_extra
417 bs_env%nkp_chi_eps_W_orig_plus_extra = nkp
418
419 ALLOCATE (kpoints%xkp(3, nkp), kpoints%wkp(nkp))
420 ALLOCATE (bs_env%wkp_no_extra(nkp), bs_env%wkp_s_p(nkp))
421
422 CALL compute_xkp(kpoints%xkp, 1, nkp_orig, nkp_grid)
423 CALL compute_xkp(kpoints%xkp, nkp_orig + 1, nkp, nkp_grid_extra)
424
425 n_dim = sum(periodic)
426 IF (n_dim == 0) THEN
427 ! molecules
428 kpoints%wkp(1) = 1.0_dp
429 bs_env%wkp_s_p(1) = 1.0_dp
430 bs_env%wkp_no_extra(1) = 1.0_dp
431 ELSE
432
433 n_dim_inv = 1.0_dp/real(n_dim, kind=dp)
434
435 ! k-point weights are chosen to automatically extrapolate the k-point mesh
436 CALL compute_wkp(kpoints%wkp(1:nkp_orig), nkp_orig, nkp_extra, n_dim_inv)
437 CALL compute_wkp(kpoints%wkp(nkp_orig + 1:nkp), nkp_extra, nkp_orig, n_dim_inv)
438
439 bs_env%wkp_no_extra(1:nkp_orig) = 0.0_dp
440 bs_env%wkp_no_extra(nkp_orig + 1:nkp) = 1.0_dp/real(nkp_extra, kind=dp)
441
442 IF (n_dim == 3) THEN
443 ! W_PQ(k) for an s-function P and a p-function Q diverges as 1/k at k=0
444 ! (instead of 1/k^2 for P and Q both being s-functions).
445 exp_s_p = 2.0_dp*n_dim_inv
446 CALL compute_wkp(bs_env%wkp_s_p(1:nkp_orig), nkp_orig, nkp_extra, exp_s_p)
447 CALL compute_wkp(bs_env%wkp_s_p(nkp_orig + 1:nkp), nkp_extra, nkp_orig, exp_s_p)
448 ELSE
449 bs_env%wkp_s_p(1:nkp) = bs_env%wkp_no_extra(1:nkp)
450 END IF
451
452 END IF
453
454 IF (bs_env%approx_kp_extrapol) THEN
455 bs_env%wkp_orig = 1.0_dp/real(nkp_orig, kind=dp)
456 END IF
457
458 CALL kpoint_init_cell_index_simple(kpoints, qs_env)
459
460 ! heuristic parameter: how many k-points for χ, ε, and W are used simultaneously
461 ! (less simultaneous k-points: less memory, but more computational effort because of
462 ! recomputation of V(k))
463 bs_env%nkp_chi_eps_W_batch = 4
464
465 bs_env%num_chi_eps_W_batches = (bs_env%nkp_chi_eps_W_orig_plus_extra - 1)/ &
466 bs_env%nkp_chi_eps_W_batch + 1
467
468 u = bs_env%unit_nr
469
470 IF (u > 0) THEN
471 WRITE (unit=u, fmt="(T2,A)") " "
472 WRITE (unit=u, fmt="(T2,1A,T71,3I4)") χε"K-point mesh 1 for , , W", nkp_grid(1:3)
473 WRITE (unit=u, fmt="(T2,2A,T71,3I4)") χε"K-point mesh 2 for , , W ", &
474 "(for k-point extrapolation of W)", nkp_grid_extra(1:3)
475 WRITE (unit=u, fmt="(T2,A,T80,L)") "Approximate the k-point extrapolation", &
476 bs_env%approx_kp_extrapol
477 END IF
478
479 CALL timestop(handle)
480
481 END SUBROUTINE setup_kpoints_chi_eps_w
482
483! **************************************************************************************************
484!> \brief ...
485!> \param kpoints ...
486!> \param qs_env ...
487! **************************************************************************************************
488 SUBROUTINE kpoint_init_cell_index_simple(kpoints, qs_env)
489
490 TYPE(kpoint_type), POINTER :: kpoints
491 TYPE(qs_environment_type), POINTER :: qs_env
492
493 CHARACTER(LEN=*), PARAMETER :: routinen = 'kpoint_init_cell_index_simple'
494
495 INTEGER :: handle
496 TYPE(dft_control_type), POINTER :: dft_control
497 TYPE(mp_para_env_type), POINTER :: para_env
498 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
499 POINTER :: sab_orb
500
501 CALL timeset(routinen, handle)
502
503 NULLIFY (dft_control, para_env, sab_orb)
504 CALL get_qs_env(qs_env=qs_env, para_env=para_env, dft_control=dft_control, sab_orb=sab_orb)
505 CALL kpoint_init_cell_index(kpoints, sab_orb, para_env, dft_control)
506
507 CALL timestop(handle)
508
509 END SUBROUTINE kpoint_init_cell_index_simple
510
511! **************************************************************************************************
512!> \brief ...
513!> \param xkp ...
514!> \param ikp_start ...
515!> \param ikp_end ...
516!> \param grid ...
517! **************************************************************************************************
518 SUBROUTINE compute_xkp(xkp, ikp_start, ikp_end, grid)
519
520 REAL(kind=dp), DIMENSION(:, :), POINTER :: xkp
521 INTEGER :: ikp_start, ikp_end
522 INTEGER, DIMENSION(3) :: grid
523
524 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_xkp'
525
526 INTEGER :: handle, i, ix, iy, iz
527
528 CALL timeset(routinen, handle)
529
530 i = ikp_start
531 DO ix = 1, grid(1)
532 DO iy = 1, grid(2)
533 DO iz = 1, grid(3)
534
535 IF (i > ikp_end) cycle
536
537 xkp(1, i) = real(2*ix - grid(1) - 1, kind=dp)/(2._dp*real(grid(1), kind=dp))
538 xkp(2, i) = real(2*iy - grid(2) - 1, kind=dp)/(2._dp*real(grid(2), kind=dp))
539 xkp(3, i) = real(2*iz - grid(3) - 1, kind=dp)/(2._dp*real(grid(3), kind=dp))
540 i = i + 1
541
542 END DO
543 END DO
544 END DO
545
546 CALL timestop(handle)
547
548 END SUBROUTINE compute_xkp
549
550! **************************************************************************************************
551!> \brief ...
552!> \param wkp ...
553!> \param nkp_1 ...
554!> \param nkp_2 ...
555!> \param exponent ...
556! **************************************************************************************************
557 SUBROUTINE compute_wkp(wkp, nkp_1, nkp_2, exponent)
558 REAL(kind=dp), DIMENSION(:) :: wkp
559 INTEGER :: nkp_1, nkp_2
560 REAL(kind=dp) :: exponent
561
562 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_wkp'
563
564 INTEGER :: handle
565 REAL(kind=dp) :: nkp_ratio
566
567 CALL timeset(routinen, handle)
568
569 nkp_ratio = real(nkp_2, kind=dp)/real(nkp_1, kind=dp)
570
571 wkp(:) = 1.0_dp/real(nkp_1, kind=dp)/(1.0_dp - nkp_ratio**exponent)
572
573 CALL timestop(handle)
574
575 END SUBROUTINE
576
577! **************************************************************************************************
578!> \brief ...
579!> \param qs_env ...
580!> \param bs_env ...
581! **************************************************************************************************
582 SUBROUTINE allocate_and_fill_matrices_and_arrays(qs_env, bs_env)
583 TYPE(qs_environment_type), POINTER :: qs_env
584 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
585
586 CHARACTER(LEN=*), PARAMETER :: routinen = 'allocate_and_fill_matrices_and_arrays'
587
588 INTEGER :: handle, i_t, num_time_freq_points
589 TYPE(cp_blacs_env_type), POINTER :: blacs_env, blacs_env_tensor
590 TYPE(cp_fm_struct_type), POINTER :: fm_struct, fm_struct_ri_global
591 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
592 TYPE(mp_para_env_type), POINTER :: para_env
593
594 CALL timeset(routinen, handle)
595
596 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env, matrix_s=matrix_s)
597
598 fm_struct => bs_env%fm_ks_Gamma(1)%matrix_struct
599
600 CALL cp_fm_create(bs_env%fm_Gocc, fm_struct)
601 CALL cp_fm_create(bs_env%fm_Gvir, fm_struct)
602 CALL cp_fm_create(bs_env%fm_h_G0W0_Gamma, fm_struct)
603
604 NULLIFY (fm_struct_ri_global)
605 CALL cp_fm_struct_create(fm_struct_ri_global, context=blacs_env, nrow_global=bs_env%n_RI, &
606 ncol_global=bs_env%n_RI, para_env=para_env)
607 CALL cp_fm_create(bs_env%fm_RI_RI, fm_struct_ri_global)
608 CALL cp_fm_create(bs_env%fm_chi_Gamma_freq, fm_struct_ri_global)
609 CALL cp_fm_create(bs_env%fm_W_MIC_freq, fm_struct_ri_global)
610 IF (bs_env%approx_kp_extrapol) THEN
611 CALL cp_fm_create(bs_env%fm_W_MIC_freq_1_extra, fm_struct_ri_global)
612 CALL cp_fm_create(bs_env%fm_W_MIC_freq_1_no_extra, fm_struct_ri_global)
613 CALL cp_fm_set_all(bs_env%fm_W_MIC_freq_1_extra, 0.0_dp)
614 CALL cp_fm_set_all(bs_env%fm_W_MIC_freq_1_no_extra, 0.0_dp)
615 END IF
616 CALL cp_fm_struct_release(fm_struct_ri_global)
617
618 ALLOCATE (bs_env%eigenval_G0W0(bs_env%n_ao, bs_env%nkp_DOS, bs_env%n_spin))
619
620 num_time_freq_points = bs_env%num_time_freq_points
621
622 ALLOCATE (bs_env%imag_freq_points(num_time_freq_points))
623 ALLOCATE (bs_env%imag_time_points(num_time_freq_points))
624 ALLOCATE (bs_env%weights_cos_t_to_w(num_time_freq_points, num_time_freq_points))
625 ALLOCATE (bs_env%weights_cos_w_to_t(num_time_freq_points, num_time_freq_points))
626 ALLOCATE (bs_env%weights_sin_t_to_w(num_time_freq_points, num_time_freq_points))
627
628 ! create blacs_env for subgroups of tensor operations
629 NULLIFY (blacs_env_tensor)
630 CALL cp_blacs_env_create(blacs_env=blacs_env_tensor, para_env=bs_env%para_env_tensor)
631
632 ! allocate dbcsr matrices in the tensor subgroup; actually, one only needs a small
633 ! subset of blocks in the tensor subgroup, however, all atomic blocks are allocated.
634 ! One might think of creating a dbcsr matrix with only the blocks that are needed
635 ! in the tensor subgroup
636 CALL create_mat_munu(bs_env%mat_ao_ao_tensor, qs_env, bs_env%eps_atom_grid_2d_mat, &
637 blacs_env_tensor, do_ri_aux_basis=.false.)
638
639 CALL create_mat_munu(bs_env%mat_RI_RI_tensor, qs_env, bs_env%eps_atom_grid_2d_mat, &
640 blacs_env_tensor, do_ri_aux_basis=.true.)
641
642 CALL create_mat_munu(bs_env%mat_RI_RI, qs_env, bs_env%eps_atom_grid_2d_mat, &
643 blacs_env, do_ri_aux_basis=.true.)
644
645 CALL cp_blacs_env_release(blacs_env_tensor)
646
647 NULLIFY (bs_env%mat_chi_Gamma_tau)
648 CALL dbcsr_allocate_matrix_set(bs_env%mat_chi_Gamma_tau, bs_env%num_time_freq_points)
649
650 DO i_t = 1, bs_env%num_time_freq_points
651 ALLOCATE (bs_env%mat_chi_Gamma_tau(i_t)%matrix)
652 CALL dbcsr_create(bs_env%mat_chi_Gamma_tau(i_t)%matrix, template=bs_env%mat_RI_RI%matrix)
653 END DO
654
655 CALL timestop(handle)
656
657 END SUBROUTINE allocate_and_fill_matrices_and_arrays
658
659! **************************************************************************************************
660!> \brief ...
661!> \param qs_env ...
662!> \param bs_env ...
663! **************************************************************************************************
664 SUBROUTINE create_tensors(qs_env, bs_env)
665 TYPE(qs_environment_type), POINTER :: qs_env
666 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
667
668 CHARACTER(LEN=*), PARAMETER :: routinen = 'create_tensors'
669
670 INTEGER :: handle, n_atom_step, ri_atom
671 INTEGER(int_8) :: mem, non_zero_elements_sum, nze
672 REAL(dp) :: max_dist_ao_atoms, occ, occupation_sum
673 TYPE(dbt_type) :: t_3c_global
674 TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :) :: t_3c_global_array
675 TYPE(neighbor_list_3c_type) :: nl_3c_global
676
677 CALL timeset(routinen, handle)
678
679 ! be careful: routine needs bs_env%eps_3c_int which is set in set_heuristic_parameters
680 CALL init_interaction_radii(bs_env)
681
682 ! split blocks does not improve load balancing/efficienfy for tensor contraction, so we go
683 ! with the standard atomic blocks
684 CALL create_3c_t(bs_env%t_RI_AO__AO, bs_env%para_env_tensor, "(RI AO | AO)", [1, 2], [3], &
685 bs_env%sizes_RI, bs_env%sizes_AO, &
686 create_nl_3c=.true., nl_3c=bs_env%nl_3c, qs_env=qs_env)
687 CALL create_3c_t(bs_env%t_RI__AO_AO, bs_env%para_env_tensor, "(RI | AO AO)", [1], [2, 3], &
688 bs_env%sizes_RI, bs_env%sizes_AO)
689
690 CALL create_2c_t(bs_env, bs_env%sizes_RI, bs_env%sizes_AO)
691
692 ! check the sparsity of 3c integral tensor (µν|P); calculate maximum distance between
693 ! AO atoms µ, ν where at least a single integral (µν|P) is larger than the filter threshold
694 CALL create_3c_t(t_3c_global, bs_env%para_env, "(RI AO | AO)", [1, 2], [3], &
695 bs_env%sizes_RI, bs_env%sizes_AO, &
696 create_nl_3c=.true., nl_3c=nl_3c_global, qs_env=qs_env)
697
698 CALL m_memory(mem)
699 CALL bs_env%para_env%max(mem)
700
701 ALLOCATE (t_3c_global_array(1, 1))
702 CALL dbt_create(t_3c_global, t_3c_global_array(1, 1))
703
704 CALL bs_env%para_env%sync()
705 bs_env%t1 = m_walltime()
706
707 occupation_sum = 0.0_dp
708 non_zero_elements_sum = 0
709 max_dist_ao_atoms = 0.0_dp
710 n_atom_step = int(sqrt(real(bs_env%n_atom, kind=dp)))
711 ! do not compute full 3c integrals at once because it may cause out of memory
712 DO ri_atom = 1, bs_env%n_atom, n_atom_step
713
714 CALL build_3c_integrals(t_3c_global_array, &
715 bs_env%eps_filter, &
716 qs_env, &
717 nl_3c_global, &
718 int_eps=bs_env%eps_3c_int, &
719 basis_i=bs_env%basis_set_RI, &
720 basis_j=bs_env%basis_set_AO, &
721 basis_k=bs_env%basis_set_AO, &
722 bounds_i=[ri_atom, min(ri_atom + n_atom_step - 1, bs_env%n_atom)], &
723 potential_parameter=bs_env%ri_metric, &
724 desymmetrize=.false.)
725
726 CALL dbt_filter(t_3c_global_array(1, 1), bs_env%eps_filter)
727
728 CALL bs_env%para_env%sync()
729
730 CALL get_tensor_occupancy(t_3c_global_array(1, 1), nze, occ)
731 non_zero_elements_sum = non_zero_elements_sum + nze
732 occupation_sum = occupation_sum + occ
733
734 CALL get_max_dist_ao_atoms(t_3c_global_array(1, 1), max_dist_ao_atoms, qs_env)
735
736 CALL dbt_clear(t_3c_global_array(1, 1))
737
738 END DO
739
740 bs_env%t2 = m_walltime()
741
742 bs_env%occupation_3c_int = occupation_sum
743 bs_env%max_dist_AO_atoms = max_dist_ao_atoms
744
745 CALL dbt_destroy(t_3c_global)
746 CALL dbt_destroy(t_3c_global_array(1, 1))
747 DEALLOCATE (t_3c_global_array)
748
749 CALL neighbor_list_3c_destroy(nl_3c_global)
750
751 IF (bs_env%unit_nr > 0) THEN
752 WRITE (bs_env%unit_nr, '(T2,A)') ''
753 WRITE (bs_env%unit_nr, '(T2,A,F27.1,A)') &
754 µν'Computed 3-center integrals (|P), execution time', bs_env%t2 - bs_env%t1, ' s'
755 WRITE (bs_env%unit_nr, '(T2,A,F48.3,A)') µν'Percentage of non-zero (|P)', &
756 occupation_sum*100, ' %'
757 WRITE (bs_env%unit_nr, '(T2,A,F33.1,A)') µνµν'Max. distance between , in non-zero (|P)', &
758 max_dist_ao_atoms*angstrom, ' A'
759 WRITE (bs_env%unit_nr, '(T2,2A,I20,A)') 'Required memory if storing all 3-center ', &
760 µν'integrals (|P)', int(real(non_zero_elements_sum, kind=dp)*8.0e-9_dp), ' GB'
761 END IF
762
763 CALL timestop(handle)
764
765 END SUBROUTINE create_tensors
766
767! **************************************************************************************************
768!> \brief ...
769!> \param bs_env ...
770!> \param sizes_RI ...
771!> \param sizes_AO ...
772! **************************************************************************************************
773 SUBROUTINE create_2c_t(bs_env, sizes_RI, sizes_AO)
774 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
775 INTEGER, ALLOCATABLE, DIMENSION(:) :: sizes_ri, sizes_ao
776
777 CHARACTER(LEN=*), PARAMETER :: routinen = 'create_2c_t'
778
779 INTEGER :: handle
780 INTEGER, ALLOCATABLE, DIMENSION(:) :: dist_1, dist_2
781 INTEGER, DIMENSION(2) :: pdims_2d
782 TYPE(dbt_pgrid_type) :: pgrid_2d
783
784 CALL timeset(routinen, handle)
785
786 ! inspired from rpa_im_time.F / hfx_types.F
787
788 pdims_2d = 0
789 CALL dbt_pgrid_create(bs_env%para_env_tensor, pdims_2d, pgrid_2d)
790
791 CALL create_2c_tensor(bs_env%t_G, dist_1, dist_2, pgrid_2d, sizes_ao, sizes_ao, &
792 name="(AO | AO)")
793 DEALLOCATE (dist_1, dist_2)
794 CALL create_2c_tensor(bs_env%t_chi, dist_1, dist_2, pgrid_2d, sizes_ri, sizes_ri, &
795 name="(RI | RI)")
796 DEALLOCATE (dist_1, dist_2)
797 CALL create_2c_tensor(bs_env%t_W, dist_1, dist_2, pgrid_2d, sizes_ri, sizes_ri, &
798 name="(RI | RI)")
799 DEALLOCATE (dist_1, dist_2)
800 CALL dbt_pgrid_destroy(pgrid_2d)
801
802 CALL timestop(handle)
803
804 END SUBROUTINE create_2c_t
805
806! **************************************************************************************************
807!> \brief ...
808!> \param tensor ...
809!> \param para_env ...
810!> \param tensor_name ...
811!> \param map1 ...
812!> \param map2 ...
813!> \param sizes_RI ...
814!> \param sizes_AO ...
815!> \param create_nl_3c ...
816!> \param nl_3c ...
817!> \param qs_env ...
818! **************************************************************************************************
819 SUBROUTINE create_3c_t(tensor, para_env, tensor_name, map1, map2, sizes_RI, sizes_AO, &
820 create_nl_3c, nl_3c, qs_env)
821 TYPE(dbt_type) :: tensor
822 TYPE(mp_para_env_type), POINTER :: para_env
823 CHARACTER(LEN=12) :: tensor_name
824 INTEGER, DIMENSION(:) :: map1, map2
825 INTEGER, ALLOCATABLE, DIMENSION(:) :: sizes_ri, sizes_ao
826 LOGICAL, OPTIONAL :: create_nl_3c
827 TYPE(neighbor_list_3c_type), OPTIONAL :: nl_3c
828 TYPE(qs_environment_type), OPTIONAL, POINTER :: qs_env
829
830 CHARACTER(LEN=*), PARAMETER :: routinen = 'create_3c_t'
831
832 INTEGER :: handle, nkind
833 INTEGER, ALLOCATABLE, DIMENSION(:) :: dist_ao_1, dist_ao_2, dist_ri
834 INTEGER, DIMENSION(3) :: pcoord, pdims, pdims_3d
835 LOGICAL :: my_create_nl_3c
836 TYPE(dbt_pgrid_type) :: pgrid_3d
837 TYPE(distribution_3d_type) :: dist_3d
838 TYPE(mp_cart_type) :: mp_comm_t3c_2
839 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
840
841 CALL timeset(routinen, handle)
842
843 pdims_3d = 0
844 CALL dbt_pgrid_create(para_env, pdims_3d, pgrid_3d)
845 CALL create_3c_tensor(tensor, dist_ri, dist_ao_1, dist_ao_2, &
846 pgrid_3d, sizes_ri, sizes_ao, sizes_ao, &
847 map1=map1, map2=map2, name=tensor_name)
848
849 IF (PRESENT(create_nl_3c)) THEN
850 my_create_nl_3c = create_nl_3c
851 ELSE
852 my_create_nl_3c = .false.
853 END IF
854
855 IF (my_create_nl_3c) THEN
856 CALL get_qs_env(qs_env, nkind=nkind, particle_set=particle_set)
857 CALL dbt_mp_environ_pgrid(pgrid_3d, pdims, pcoord)
858 CALL mp_comm_t3c_2%create(pgrid_3d%mp_comm_2d, 3, pdims)
859 CALL distribution_3d_create(dist_3d, dist_ri, dist_ao_1, dist_ao_2, &
860 nkind, particle_set, mp_comm_t3c_2, own_comm=.true.)
861
862 CALL build_3c_neighbor_lists(nl_3c, &
863 qs_env%bs_env%basis_set_RI, &
864 qs_env%bs_env%basis_set_AO, &
865 qs_env%bs_env%basis_set_AO, &
866 dist_3d, qs_env%bs_env%ri_metric, &
867 "GW_3c_nl", qs_env, own_dist=.true.)
868 END IF
869
870 DEALLOCATE (dist_ri, dist_ao_1, dist_ao_2)
871 CALL dbt_pgrid_destroy(pgrid_3d)
872
873 CALL timestop(handle)
874
875 END SUBROUTINE create_3c_t
876
877! **************************************************************************************************
878!> \brief ...
879!> \param bs_env ...
880! **************************************************************************************************
881 SUBROUTINE init_interaction_radii(bs_env)
882 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
883
884 CHARACTER(LEN=*), PARAMETER :: routinen = 'init_interaction_radii'
885
886 INTEGER :: handle, ibasis
887 TYPE(gto_basis_set_type), POINTER :: orb_basis, ri_basis
888
889 CALL timeset(routinen, handle)
890
891 DO ibasis = 1, SIZE(bs_env%basis_set_AO)
892
893 orb_basis => bs_env%basis_set_AO(ibasis)%gto_basis_set
894 CALL init_interaction_radii_orb_basis(orb_basis, bs_env%eps_3c_int)
895
896 ri_basis => bs_env%basis_set_RI(ibasis)%gto_basis_set
897 CALL init_interaction_radii_orb_basis(ri_basis, bs_env%eps_3c_int)
898
899 END DO
900
901 CALL timestop(handle)
902
903 END SUBROUTINE init_interaction_radii
904
905! **************************************************************************************************
906!> \brief ...
907!> \param t_3c_int ...
908!> \param max_dist_AO_atoms ...
909!> \param qs_env ...
910! **************************************************************************************************
911 SUBROUTINE get_max_dist_ao_atoms(t_3c_int, max_dist_AO_atoms, qs_env)
912 TYPE(dbt_type) :: t_3c_int
913 REAL(kind=dp) :: max_dist_ao_atoms
914 TYPE(qs_environment_type), POINTER :: qs_env
915
916 CHARACTER(LEN=*), PARAMETER :: routinen = 'get_max_dist_AO_atoms'
917
918 INTEGER :: atom_1, atom_2, handle, num_cells
919 INTEGER, DIMENSION(3) :: atom_ind
920 INTEGER, DIMENSION(:, :), POINTER :: index_to_cell
921 REAL(kind=dp) :: abs_rab
922 REAL(kind=dp), DIMENSION(3) :: rab
923 REAL(kind=dp), DIMENSION(3, 3) :: hmat
924 TYPE(cell_type), POINTER :: cell
925 TYPE(dbt_iterator_type) :: iter
926 TYPE(mp_para_env_type), POINTER :: para_env
927 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
928
929 CALL timeset(routinen, handle)
930
931 NULLIFY (cell, particle_set, para_env)
932 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set, para_env=para_env)
933
934!$OMP PARALLEL DEFAULT(NONE) &
935!$OMP SHARED(t_3c_int, max_dist_AO_atoms, num_cells, index_to_cell, hmat, particle_set, cell) &
936!$OMP PRIVATE(iter,atom_ind,rab, abs_rab, atom_1, atom_2)
937 CALL dbt_iterator_start(iter, t_3c_int)
938 DO WHILE (dbt_iterator_blocks_left(iter))
939 CALL dbt_iterator_next_block(iter, atom_ind)
940
941 atom_1 = atom_ind(2)
942 atom_2 = atom_ind(3)
943
944 rab = pbc(particle_set(atom_1)%r(1:3), particle_set(atom_2)%r(1:3), cell)
945
946 abs_rab = sqrt(rab(1)**2 + rab(2)**2 + rab(3)**2)
947
948 max_dist_ao_atoms = max(max_dist_ao_atoms, abs_rab)
949
950 END DO
951 CALL dbt_iterator_stop(iter)
952!$OMP END PARALLEL
953
954 CALL para_env%max(max_dist_ao_atoms)
955
956 CALL timestop(handle)
957
958 END SUBROUTINE get_max_dist_ao_atoms
959
960! **************************************************************************************************
961!> \brief ...
962!> \param bs_env ...
963! **************************************************************************************************
964 SUBROUTINE set_sparsity_parallelization_parameters(bs_env)
965 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
966
967 CHARACTER(LEN=*), PARAMETER :: routinen = 'set_sparsity_parallelization_parameters'
968
969 INTEGER :: handle, i_ivl, il_ivl, j_ivl, n_atom_per_il_ivl, n_atom_per_ivl, n_intervals_i, &
970 n_intervals_inner_loop_atoms, n_intervals_j, u
971
972 CALL timeset(routinen, handle)
973
974 ! heuristic parameter to prevent out of memory
975 bs_env%safety_factor_memory = 0.10_dp
976
977 ! choose atomic range for λ ("i_atom"), ν ("j_atom") in
978 ! M_λνP(iτ) = sum_µ (µν|P) G^occ_µλ(i|τ|,k=0)
979 ! N_νλQ(iτ) = sum_σ (σλ|Q) G^vir_σν(i|τ|,k=0)
980 ! such that M and N fit into the memory
981 n_atom_per_ivl = int(sqrt(bs_env%safety_factor_memory*bs_env%input_memory_per_proc &
982 *bs_env%group_size_tensor/24/bs_env%n_RI &
983 /sqrt(bs_env%occupation_3c_int)))/bs_env%max_AO_bf_per_atom
984
985 n_intervals_i = (bs_env%n_atom_i - 1)/n_atom_per_ivl + 1
986 n_intervals_j = (bs_env%n_atom_j - 1)/n_atom_per_ivl + 1
987
988 bs_env%n_atom_per_interval_ij = n_atom_per_ivl
989 bs_env%n_intervals_i = n_intervals_i
990 bs_env%n_intervals_j = n_intervals_j
991
992 ALLOCATE (bs_env%i_atom_intervals(2, n_intervals_i))
993 ALLOCATE (bs_env%j_atom_intervals(2, n_intervals_j))
994
995 DO i_ivl = 1, n_intervals_i
996 bs_env%i_atom_intervals(1, i_ivl) = (i_ivl - 1)*n_atom_per_ivl + bs_env%atoms_i(1)
997 bs_env%i_atom_intervals(2, i_ivl) = min(i_ivl*n_atom_per_ivl + bs_env%atoms_i(1) - 1, &
998 bs_env%atoms_i(2))
999 END DO
1000
1001 DO j_ivl = 1, n_intervals_j
1002 bs_env%j_atom_intervals(1, j_ivl) = (j_ivl - 1)*n_atom_per_ivl + bs_env%atoms_j(1)
1003 bs_env%j_atom_intervals(2, j_ivl) = min(j_ivl*n_atom_per_ivl + bs_env%atoms_j(1) - 1, &
1004 bs_env%atoms_j(2))
1005 END DO
1006
1007 ALLOCATE (bs_env%skip_Sigma_occ(n_intervals_i, n_intervals_j))
1008 ALLOCATE (bs_env%skip_Sigma_vir(n_intervals_i, n_intervals_j))
1009 bs_env%skip_Sigma_occ(:, :) = .false.
1010 bs_env%skip_Sigma_vir(:, :) = .false.
1011
1012 ! choose atomic range for µ and σ ("inner loop (IL) atom") in
1013 ! M_λνP(iτ) = sum_µ (µν|P) G^occ_µλ(i|τ|,k=0)
1014 ! N_νλQ(iτ) = sum_σ (σλ|Q) G^vir_σν(i|τ|,k=0)
1015 n_atom_per_il_ivl = min(int(bs_env%safety_factor_memory*bs_env%input_memory_per_proc &
1016 *bs_env%group_size_tensor/n_atom_per_ivl &
1017 /bs_env%max_AO_bf_per_atom &
1018 /bs_env%n_RI/8/sqrt(bs_env%occupation_3c_int) &
1019 /bs_env%max_AO_bf_per_atom), bs_env%n_atom)
1020
1021 n_intervals_inner_loop_atoms = (bs_env%n_atom - 1)/n_atom_per_il_ivl + 1
1022
1023 bs_env%n_atom_per_IL_interval = n_atom_per_il_ivl
1024 bs_env%n_intervals_inner_loop_atoms = n_intervals_inner_loop_atoms
1025
1026 ALLOCATE (bs_env%inner_loop_atom_intervals(2, n_intervals_inner_loop_atoms))
1027 DO il_ivl = 1, n_intervals_inner_loop_atoms
1028 bs_env%inner_loop_atom_intervals(1, il_ivl) = (il_ivl - 1)*n_atom_per_il_ivl + 1
1029 bs_env%inner_loop_atom_intervals(2, il_ivl) = min(il_ivl*n_atom_per_il_ivl, bs_env%n_atom)
1030 END DO
1031
1032 u = bs_env%unit_nr
1033 IF (u > 0) THEN
1034 WRITE (u, '(T2,A)') ''
1035 WRITE (u, '(T2,A,I33)') λντνλτ'Number of i and j atoms in M_P(), N_Q():', n_atom_per_ivl
1036 WRITE (u, '(T2,A,I18)') µλνµµνµλ'Number of inner loop atoms for in M_P = sum_ (|P) G_', &
1037 n_atom_per_il_ivl
1038 END IF
1039
1040 CALL timestop(handle)
1041
1042 END SUBROUTINE set_sparsity_parallelization_parameters
1043
1044! **************************************************************************************************
1045!> \brief ...
1046!> \param qs_env ...
1047!> \param bs_env ...
1048! **************************************************************************************************
1049 SUBROUTINE check_for_restart_files(qs_env, bs_env)
1050 TYPE(qs_environment_type), POINTER :: qs_env
1051 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1052
1053 CHARACTER(LEN=*), PARAMETER :: routinen = 'check_for_restart_files'
1054
1055 CHARACTER(LEN=9) :: frmt
1056 CHARACTER(LEN=default_string_length) :: f_chi, f_s_n, f_s_p, f_s_x, f_w_t, &
1057 prefix, project_name
1058 INTEGER :: handle, i_spin, i_t_or_w, ind, n_spin, &
1059 num_time_freq_points
1060 LOGICAL :: chi_exists, sigma_neg_time_exists, &
1061 sigma_pos_time_exists, &
1062 sigma_x_spin_exists, w_time_exists
1063 TYPE(cp_logger_type), POINTER :: logger
1064 TYPE(section_vals_type), POINTER :: input, print_key
1065
1066 CALL timeset(routinen, handle)
1067
1068 num_time_freq_points = bs_env%num_time_freq_points
1069 n_spin = bs_env%n_spin
1070
1071 ALLOCATE (bs_env%read_chi(num_time_freq_points))
1072 ALLOCATE (bs_env%calc_chi(num_time_freq_points))
1073 ALLOCATE (bs_env%Sigma_c_exists(num_time_freq_points, n_spin))
1074
1075 CALL get_qs_env(qs_env, input=input)
1076
1077 logger => cp_get_default_logger()
1078 print_key => section_vals_get_subs_vals(input, 'PROPERTIES%BANDSTRUCTURE%GW%PRINT%RESTART')
1079 project_name = cp_print_key_generate_filename(logger, print_key, extension="", &
1080 my_local=.false.)
1081 WRITE (prefix, '(2A)') trim(project_name), "-RESTART_"
1082 bs_env%prefix = prefix
1083
1084 bs_env%all_W_exist = .true.
1085
1086 DO i_t_or_w = 1, num_time_freq_points
1087
1088 IF (i_t_or_w < 10) THEN
1089 WRITE (frmt, '(A)') '(3A,I1,A)'
1090 WRITE (f_chi, frmt) trim(prefix), bs_env%chi_name, "_0", i_t_or_w, ".matrix"
1091 WRITE (f_w_t, frmt) trim(prefix), bs_env%W_time_name, "_0", i_t_or_w, ".matrix"
1092 ELSE IF (i_t_or_w < 100) THEN
1093 WRITE (frmt, '(A)') '(3A,I2,A)'
1094 WRITE (f_chi, frmt) trim(prefix), bs_env%chi_name, "_", i_t_or_w, ".matrix"
1095 WRITE (f_w_t, frmt) trim(prefix), bs_env%W_time_name, "_", i_t_or_w, ".matrix"
1096 ELSE
1097 cpabort('Please implement more than 99 time/frequency points.')
1098 END IF
1099
1100 INQUIRE (file=trim(f_chi), exist=chi_exists)
1101 INQUIRE (file=trim(f_w_t), exist=w_time_exists)
1102
1103 bs_env%read_chi(i_t_or_w) = chi_exists
1104 bs_env%calc_chi(i_t_or_w) = .NOT. chi_exists
1105
1106 bs_env%all_W_exist = bs_env%all_W_exist .AND. w_time_exists
1107
1108 ! the self-energy is spin-dependent
1109 DO i_spin = 1, n_spin
1110
1111 ind = i_t_or_w + (i_spin - 1)*num_time_freq_points
1112
1113 IF (ind < 10) THEN
1114 WRITE (frmt, '(A)') '(3A,I1,A)'
1115 WRITE (f_s_p, frmt) trim(prefix), bs_env%Sigma_p_name, "_0", ind, ".matrix"
1116 WRITE (f_s_n, frmt) trim(prefix), bs_env%Sigma_n_name, "_0", ind, ".matrix"
1117 ELSE IF (i_t_or_w < 100) THEN
1118 WRITE (frmt, '(A)') '(3A,I2,A)'
1119 WRITE (f_s_p, frmt) trim(prefix), bs_env%Sigma_p_name, "_", ind, ".matrix"
1120 WRITE (f_s_n, frmt) trim(prefix), bs_env%Sigma_n_name, "_", ind, ".matrix"
1121 END IF
1122
1123 INQUIRE (file=trim(f_s_p), exist=sigma_pos_time_exists)
1124 INQUIRE (file=trim(f_s_n), exist=sigma_neg_time_exists)
1125
1126 bs_env%Sigma_c_exists(i_t_or_w, i_spin) = sigma_pos_time_exists .AND. &
1127 sigma_neg_time_exists
1128
1129 END DO
1130
1131 END DO
1132
1133 IF (bs_env%all_W_exist) THEN
1134 bs_env%read_chi(:) = .false.
1135 bs_env%calc_chi(:) = .false.
1136 END IF
1137
1138 bs_env%Sigma_x_exists = .true.
1139 DO i_spin = 1, n_spin
1140 WRITE (f_s_x, '(3A,I1,A)') trim(prefix), bs_env%Sigma_x_name, "_0", i_spin, ".matrix"
1141 INQUIRE (file=trim(f_s_x), exist=sigma_x_spin_exists)
1142 bs_env%Sigma_x_exists = bs_env%Sigma_x_exists .AND. sigma_x_spin_exists
1143 END DO
1144
1145 CALL timestop(handle)
1146
1147 END SUBROUTINE check_for_restart_files
1148
1149! **************************************************************************************************
1150!> \brief ...
1151!> \param qs_env ...
1152!> \param bs_env ...
1153! **************************************************************************************************
1154 SUBROUTINE set_parallelization_parameters(qs_env, bs_env)
1155 TYPE(qs_environment_type), POINTER :: qs_env
1156 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1157
1158 CHARACTER(LEN=*), PARAMETER :: routinen = 'set_parallelization_parameters'
1159
1160 INTEGER :: color_sub, dummy_1, dummy_2, handle, &
1161 num_pe, num_t_groups, u
1162 INTEGER(KIND=int_8) :: mem
1163 TYPE(mp_para_env_type), POINTER :: para_env
1164
1165 CALL timeset(routinen, handle)
1166
1167 CALL get_qs_env(qs_env, para_env=para_env)
1168
1169 num_pe = para_env%num_pe
1170 ! use all processors for the group (in principle, number could be changed, but performance
1171 ! seems to be best for a single group with all MPI processes per group)
1172 bs_env%group_size_tensor = num_pe
1173
1174 ! group_size_tensor must divide num_pe without rest; otherwise everything will be complicated
1175 IF (modulo(num_pe, bs_env%group_size_tensor) .NE. 0) THEN
1176 CALL find_good_group_size(num_pe, bs_env%group_size_tensor)
1177 END IF
1178
1179 ! para_env_tensor for tensor subgroups
1180 color_sub = para_env%mepos/bs_env%group_size_tensor
1181 bs_env%tensor_group_color = color_sub
1182
1183 ALLOCATE (bs_env%para_env_tensor)
1184 CALL bs_env%para_env_tensor%from_split(para_env, color_sub)
1185
1186 num_t_groups = para_env%num_pe/bs_env%group_size_tensor
1187 bs_env%num_tensor_groups = num_t_groups
1188
1189 CALL get_i_j_atoms(bs_env%atoms_i, bs_env%atoms_j, bs_env%n_atom_i, bs_env%n_atom_j, &
1190 color_sub, bs_env)
1191
1192 ALLOCATE (bs_env%atoms_i_t_group(2, num_t_groups))
1193 ALLOCATE (bs_env%atoms_j_t_group(2, num_t_groups))
1194 DO color_sub = 0, num_t_groups - 1
1195 CALL get_i_j_atoms(bs_env%atoms_i_t_group(1:2, color_sub + 1), &
1196 bs_env%atoms_j_t_group(1:2, color_sub + 1), &
1197 dummy_1, dummy_2, color_sub, bs_env)
1198 END DO
1199
1200 CALL m_memory(mem)
1201 CALL bs_env%para_env%max(mem)
1202
1203 bs_env%input_memory_per_proc = int(bs_env%input_memory_per_proc_GB*1.0e9_dp, kind=int_8)
1204
1205 u = bs_env%unit_nr
1206 IF (u > 0) THEN
1207 WRITE (u, '(T2,A)') ''
1208 WRITE (u, '(T2,A,I47)') 'Group size for tensor operations', bs_env%group_size_tensor
1209 WRITE (u, '(T2,A)') ''
1210 WRITE (u, '(T2,A,F37.1,A)') 'Input: Available memory per MPI process', &
1211 bs_env%input_memory_per_proc_GB, ' GB'
1212 WRITE (u, '(T2,A,F35.1,A)') 'Used memory per MPI process before GW run', &
1213 REAL(mem, kind=dp)/1.e9_dp, ' GB'
1214 END IF
1215
1216 CALL timestop(handle)
1217
1218 END SUBROUTINE set_parallelization_parameters
1219
1220! **************************************************************************************************
1221!> \brief ...
1222!> \param num_pe ...
1223!> \param group_size ...
1224! **************************************************************************************************
1225 SUBROUTINE find_good_group_size(num_pe, group_size)
1226
1227 INTEGER :: num_pe, group_size
1228
1229 CHARACTER(LEN=*), PARAMETER :: routinen = 'find_good_group_size'
1230
1231 INTEGER :: group_size_minus, group_size_orig, &
1232 group_size_plus, handle, i_diff
1233
1234 CALL timeset(routinen, handle)
1235
1236 group_size_orig = group_size
1237
1238 DO i_diff = 1, num_pe
1239
1240 group_size_minus = group_size - i_diff
1241
1242 IF (modulo(num_pe, group_size_minus) == 0 .AND. group_size_minus > 0) THEN
1243 group_size = group_size_minus
1244 EXIT
1245 END IF
1246
1247 group_size_plus = group_size + i_diff
1248
1249 IF (modulo(num_pe, group_size_plus) == 0 .AND. group_size_plus <= num_pe) THEN
1250 group_size = group_size_plus
1251 EXIT
1252 END IF
1253
1254 END DO
1255
1256 IF (group_size_orig == group_size) cpabort("Group size error")
1257
1258 CALL timestop(handle)
1259
1260 END SUBROUTINE find_good_group_size
1261
1262! **************************************************************************************************
1263!> \brief ...
1264!> \param atoms_i ...
1265!> \param atoms_j ...
1266!> \param n_atom_i ...
1267!> \param n_atom_j ...
1268!> \param color_sub ...
1269!> \param bs_env ...
1270! **************************************************************************************************
1271 SUBROUTINE get_i_j_atoms(atoms_i, atoms_j, n_atom_i, n_atom_j, color_sub, bs_env)
1272
1273 INTEGER, DIMENSION(2) :: atoms_i, atoms_j
1274 INTEGER :: n_atom_i, n_atom_j, color_sub
1275 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1276
1277 CHARACTER(LEN=*), PARAMETER :: routinen = 'get_i_j_atoms'
1278
1279 INTEGER :: handle, i_atoms_per_group, i_group, &
1280 ipcol, ipcol_loop, iprow, iprow_loop, &
1281 j_atoms_per_group, npcol, nprow
1282
1283 CALL timeset(routinen, handle)
1284
1285 ! create a square mesh of tensor groups for iatom and jatom; code from blacs_env_create
1286 CALL square_mesh(nprow, npcol, bs_env%num_tensor_groups)
1287
1288 i_group = 0
1289 DO ipcol_loop = 0, npcol - 1
1290 DO iprow_loop = 0, nprow - 1
1291 IF (i_group == color_sub) THEN
1292 iprow = iprow_loop
1293 ipcol = ipcol_loop
1294 END IF
1295 i_group = i_group + 1
1296 END DO
1297 END DO
1298
1299 IF (modulo(bs_env%n_atom, nprow) == 0) THEN
1300 i_atoms_per_group = bs_env%n_atom/nprow
1301 ELSE
1302 i_atoms_per_group = bs_env%n_atom/nprow + 1
1303 END IF
1304
1305 IF (modulo(bs_env%n_atom, npcol) == 0) THEN
1306 j_atoms_per_group = bs_env%n_atom/npcol
1307 ELSE
1308 j_atoms_per_group = bs_env%n_atom/npcol + 1
1309 END IF
1310
1311 atoms_i(1) = iprow*i_atoms_per_group + 1
1312 atoms_i(2) = min((iprow + 1)*i_atoms_per_group, bs_env%n_atom)
1313 n_atom_i = atoms_i(2) - atoms_i(1) + 1
1314
1315 atoms_j(1) = ipcol*j_atoms_per_group + 1
1316 atoms_j(2) = min((ipcol + 1)*j_atoms_per_group, bs_env%n_atom)
1317 n_atom_j = atoms_j(2) - atoms_j(1) + 1
1318
1319 CALL timestop(handle)
1320
1321 END SUBROUTINE get_i_j_atoms
1322
1323! **************************************************************************************************
1324!> \brief ...
1325!> \param nprow ...
1326!> \param npcol ...
1327!> \param nproc ...
1328! **************************************************************************************************
1329 SUBROUTINE square_mesh(nprow, npcol, nproc)
1330 INTEGER :: nprow, npcol, nproc
1331
1332 CHARACTER(LEN=*), PARAMETER :: routinen = 'square_mesh'
1333
1334 INTEGER :: gcd_max, handle, ipe, jpe
1335
1336 CALL timeset(routinen, handle)
1337
1338 gcd_max = -1
1339 DO ipe = 1, ceiling(sqrt(real(nproc, dp)))
1340 jpe = nproc/ipe
1341 IF (ipe*jpe .NE. nproc) cycle
1342 IF (gcd(ipe, jpe) >= gcd_max) THEN
1343 nprow = ipe
1344 npcol = jpe
1345 gcd_max = gcd(ipe, jpe)
1346 END IF
1347 END DO
1348
1349 CALL timestop(handle)
1350
1351 END SUBROUTINE square_mesh
1352
1353! **************************************************************************************************
1354!> \brief ...
1355!> \param bs_env ...
1356!> \param qs_env ...
1357! **************************************************************************************************
1358 SUBROUTINE set_heuristic_parameters(bs_env, qs_env)
1359 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1360 TYPE(qs_environment_type), OPTIONAL, POINTER :: qs_env
1361
1362 CHARACTER(LEN=*), PARAMETER :: routinen = 'set_heuristic_parameters'
1363
1364 INTEGER :: handle
1365
1366 CALL timeset(routinen, handle)
1367
1368 ! use the same threshold for computing 3-center integrals (µν|P) as for filtering
1369 ! tensor operations
1370 bs_env%eps_3c_int = bs_env%eps_filter
1371
1372 ! Determines number of cells used for summing the cells R in the Coulomb matrix,
1373 ! V_PQ(k) = \sum_R <P,cell=0 | 1/r | Q,cell=R>. SIZE_LATTICE_SUM_V 3 gives
1374 ! good convergence
1375 bs_env%size_lattice_sum_V = 3
1376
1377 ! for generating numerically stable minimax Fourier integration weights
1378 bs_env%num_points_per_magnitude = 200
1379
1380 ! for periodic systems and for 20 minimax points, we use a regularized minimax mesh
1381 ! (from experience: regularized minimax meshes converges faster for periodic systems
1382 ! and for 20 pts)
1383 IF (sum(bs_env%periodic) .NE. 0 .OR. bs_env%num_time_freq_points == 20) THEN
1384 bs_env%regularization_minimax = 1.0e-6_dp
1385 ELSE
1386 bs_env%regularization_minimax = 0.0_dp
1387 END IF
1388
1389 bs_env%stabilize_exp = 70.0_dp
1390 bs_env%eps_atom_grid_2d_mat = 1.0e-50_dp
1391
1392 ! only use interval ω in [0, 27.211 eV] (1 Hartree = 27.211 eV) for virt, and ω in
1393 ! [-27.211 eV, 0] for occ for use in analytic continuation of
1394 ! self-energy Σ^c_n(iω,k) -> Σ^c_n(ϵ,k)
1395 bs_env%freq_max_fit = 1.0_dp
1396
1397 ! use a 16-parameter Padé fit
1398 bs_env%nparam_pade = 16
1399
1400 ! minimum block size for tensor operations, taken from MP2/RPA input
1401 bs_env%min_block_size = 5
1402
1403 ! resolution of the identity with the truncated Coulomb metric, cutoff radius 3 Angström
1404 bs_env%ri_metric%potential_type = do_potential_truncated
1405 bs_env%ri_metric%omega = 0.0_dp
1406 ! cutoff radius = 3 Angström
1407 bs_env%ri_metric%cutoff_radius = 3.0_dp/angstrom
1408 bs_env%ri_metric%filename = "t_c_g.dat"
1409
1410 bs_env%eps_eigval_mat_RI = 0.0_dp
1411
1412 ! for periodic systems, we use the regularized resolution of the identity
1413 IF (sum(bs_env%periodic) == 0) THEN
1414 bs_env%regularization_RI = 0.0_dp
1415 ELSE
1416 bs_env%regularization_RI = 1.0e-2_dp
1417 END IF
1418
1419 ! truncated Coulomb operator for exchange self-energy
1420 ! (see details in Guidon, VandeVondele, Hutter, JCTC 5, 3010 (2009) and references therein)
1421 CALL setup_trunc_coulomb_pot_for_exchange_self_energy(qs_env, bs_env%trunc_coulomb, &
1422 rel_cutoff_trunc_coulomb_ri_x=0.5_dp)
1423
1424 CALL timestop(handle)
1425
1426 END SUBROUTINE set_heuristic_parameters
1427
1428! **************************************************************************************************
1429!> \brief ...
1430!> \param bs_env ...
1431! **************************************************************************************************
1432 SUBROUTINE print_header_and_input_parameters(bs_env)
1433
1434 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1435
1436 CHARACTER(LEN=*), PARAMETER :: routinen = 'print_header_and_input_parameters'
1437
1438 INTEGER :: handle, u
1439
1440 CALL timeset(routinen, handle)
1441
1442 u = bs_env%unit_nr
1443
1444 IF (u > 0) THEN
1445 WRITE (u, *) ' '
1446 WRITE (u, '(T2,2A)') '------------------------------------------------', &
1447 '-------------------------------'
1448 WRITE (u, '(T2,2A)') '- ', &
1449 ' -'
1450 WRITE (u, '(T2,2A)') '- GW CALCULATION ', &
1451 ' -'
1452 WRITE (u, '(T2,2A)') '- ', &
1453 ' -'
1454 WRITE (u, '(T2,2A)') '------------------------------------------------', &
1455 '-------------------------------'
1456 WRITE (u, '(T2,A)') ' '
1457 WRITE (u, '(T2,A,I45)') 'Input: Number of time/freq. points', bs_env%num_time_freq_points
1458 WRITE (u, '(T2,A,ES27.1)') 'Input: Filter threshold for sparse tensor operations', &
1459 bs_env%eps_filter
1460 END IF
1461
1462 CALL timestop(handle)
1463
1464 END SUBROUTINE print_header_and_input_parameters
1465
1466! **************************************************************************************************
1467!> \brief ...
1468!> \param qs_env ...
1469!> \param bs_env ...
1470! **************************************************************************************************
1471 SUBROUTINE compute_fm_v_xc_gamma(qs_env, bs_env)
1472 TYPE(qs_environment_type), POINTER :: qs_env
1473 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1474
1475 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_fm_V_xc_Gamma'
1476
1477 INTEGER :: handle, ispin, myfun, nimages
1478 REAL(kind=dp) :: energy_ex, energy_exc, energy_total
1479 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_ks_without_v_xc
1480 TYPE(dft_control_type), POINTER :: dft_control
1481 TYPE(qs_energy_type), POINTER :: energy
1482 TYPE(section_vals_type), POINTER :: input, xc_section
1483
1484 CALL timeset(routinen, handle)
1485
1486 CALL get_qs_env(qs_env, input=input, energy=energy, dft_control=dft_control)
1487
1488 ! previously, dft_control%nimages set to # neighbor cells, revert for Γ-only KS matrix
1489 nimages = dft_control%nimages
1490 dft_control%nimages = 1
1491
1492 ! we need to reset XC functional, therefore, get XC input
1493 xc_section => section_vals_get_subs_vals(input, "DFT%XC")
1494 CALL section_vals_val_get(xc_section, "XC_FUNCTIONAL%_SECTION_PARAMETERS_", i_val=myfun)
1495 CALL section_vals_val_set(xc_section, "XC_FUNCTIONAL%_SECTION_PARAMETERS_", i_val=xc_none)
1496
1497 ! save the energy before the energy gets updated
1498 energy_total = energy%total
1499 energy_exc = energy%exc
1500 energy_ex = energy%ex
1501
1502 NULLIFY (mat_ks_without_v_xc)
1503 CALL dbcsr_allocate_matrix_set(mat_ks_without_v_xc, bs_env%n_spin)
1504
1505 DO ispin = 1, bs_env%n_spin
1506 ALLOCATE (mat_ks_without_v_xc(ispin)%matrix)
1507 CALL dbcsr_create(mat_ks_without_v_xc(ispin)%matrix, template=bs_env%mat_ao_ao%matrix)
1508 END DO
1509
1510 ! calculate KS-matrix without XC
1511 CALL qs_ks_build_kohn_sham_matrix(qs_env, calculate_forces=.false., just_energy=.false., &
1512 ext_ks_matrix=mat_ks_without_v_xc)
1513
1514 DO ispin = 1, bs_env%n_spin
1515 ! transfer dbcsr matrix to fm
1516 CALL cp_fm_create(bs_env%fm_V_xc_Gamma(ispin), bs_env%fm_s_Gamma%matrix_struct)
1517 CALL copy_dbcsr_to_fm(mat_ks_without_v_xc(ispin)%matrix, bs_env%fm_V_xc_Gamma(ispin))
1518
1519 ! finally compute the xc potential in the AO basis
1520 CALL cp_fm_scale_and_add(alpha=-1.0_dp, matrix_a=bs_env%fm_V_xc_Gamma(ispin), &
1521 beta=1.0_dp, matrix_b=bs_env%fm_ks_Gamma(ispin))
1522 END DO
1523
1524 ! set back the energy
1525 energy%total = energy_total
1526 energy%exc = energy_exc
1527 energy%ex = energy_ex
1528
1529 ! set back nimages
1530 dft_control%nimages = nimages
1531
1532 ! set the DFT functional and HF fraction back
1533 CALL section_vals_val_set(xc_section, "XC_FUNCTIONAL%_SECTION_PARAMETERS_", &
1534 i_val=myfun)
1535
1536 CALL dbcsr_deallocate_matrix_set(mat_ks_without_v_xc)
1537
1538 CALL timestop(handle)
1539
1540 END SUBROUTINE compute_fm_v_xc_gamma
1541
1542! **************************************************************************************************
1543!> \brief ...
1544!> \param bs_env ...
1545! **************************************************************************************************
1546 SUBROUTINE setup_time_and_frequency_minimax_grid(bs_env)
1547 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1548
1549 CHARACTER(LEN=*), PARAMETER :: routinen = 'setup_time_and_frequency_minimax_grid'
1550
1551 INTEGER :: handle, homo, i_w, ierr, j_w, n_mo, &
1552 num_time_freq_points, u
1553 REAL(kind=dp) :: e_max, e_min, e_range, max_error_min
1554 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: points_and_weights
1555
1556 CALL timeset(routinen, handle)
1557
1558 homo = bs_env%n_occ(1)
1559 n_mo = bs_env%n_ao
1560 num_time_freq_points = bs_env%num_time_freq_points
1561
1562 ! minimum and maximum difference between eigenvalues of unoccupied and an occupied MOs
1563 e_min = minval(bs_env%eigenval_scf_Gamma(homo + 1, :)) - &
1564 maxval(bs_env%eigenval_scf_Gamma(homo, :))
1565 e_max = maxval(bs_env%eigenval_scf_Gamma(n_mo, :)) - &
1566 minval(bs_env%eigenval_scf_Gamma(1, :))
1567
1568 e_range = e_max/e_min
1569
1570 ALLOCATE (points_and_weights(2*num_time_freq_points))
1571
1572 ! frequency points
1573 IF (num_time_freq_points .LE. 20) THEN
1574 CALL get_rpa_minimax_coeff(num_time_freq_points, e_range, points_and_weights, ierr, .false.)
1575 ELSE
1576 CALL get_rpa_minimax_coeff_larger_grid(num_time_freq_points, e_range, points_and_weights)
1577 END IF
1578
1579 ! one needs to scale the minimax grids, see Azizi, Wilhelm, Golze, Panades-Barrueta,
1580 ! Giantomassi, Rinke, Draxl, Gonze et al., 2 publications
1581 bs_env%imag_freq_points(:) = points_and_weights(1:num_time_freq_points)*e_min
1582
1583 ! determine number of fit points in the interval [0,ω_max] for virt, or [-ω_max,0] for occ
1584 bs_env%num_freq_points_fit = 0
1585 DO i_w = 1, bs_env%num_time_freq_points
1586 IF (bs_env%imag_freq_points(i_w) < bs_env%freq_max_fit) THEN
1587 bs_env%num_freq_points_fit = bs_env%num_freq_points_fit + 1
1588 END IF
1589 END DO
1590
1591 ! iω values for the analytic continuation Σ^c_n(iω,k) -> Σ^c_n(ϵ,k)
1592 ALLOCATE (bs_env%imag_freq_points_fit(bs_env%num_freq_points_fit))
1593 j_w = 0
1594 DO i_w = 1, bs_env%num_time_freq_points
1595 IF (bs_env%imag_freq_points(i_w) < bs_env%freq_max_fit) THEN
1596 j_w = j_w + 1
1597 bs_env%imag_freq_points_fit(j_w) = bs_env%imag_freq_points(i_w)
1598 END IF
1599 END DO
1600
1601 ! reset the number of Padé parameters if smaller than the number of
1602 ! imaginary-frequency points for the fit
1603 IF (bs_env%num_freq_points_fit < bs_env%nparam_pade) THEN
1604 bs_env%nparam_pade = bs_env%num_freq_points_fit
1605 END IF
1606
1607 ! time points
1608 IF (num_time_freq_points .LE. 20) THEN
1609 CALL get_exp_minimax_coeff(num_time_freq_points, e_range, points_and_weights)
1610 ELSE
1611 CALL get_exp_minimax_coeff_gw(num_time_freq_points, e_range, points_and_weights)
1612 END IF
1613
1614 bs_env%imag_time_points(:) = points_and_weights(1:num_time_freq_points)/(2.0_dp*e_min)
1615
1616 DEALLOCATE (points_and_weights)
1617
1618 ! in minimax grids, Fourier transforms t -> w and w -> t are split using
1619 ! e^(iwt) = cos(wt) + i sin(wt); we thus calculate weights for trafos with a cos and
1620 ! sine prefactor; details in Azizi, Wilhelm, Golze, Giantomassi, Panades-Barrueta,
1621 ! Rinke, Draxl, Gonze et al., 2 publications
1622
1623 ! cosine transform weights imaginary time to imaginary frequency
1624 CALL get_l_sq_wghts_cos_tf_t_to_w(num_time_freq_points, &
1625 bs_env%imag_time_points, &
1626 bs_env%weights_cos_t_to_w, &
1627 bs_env%imag_freq_points, &
1628 e_min, e_max, max_error_min, &
1629 bs_env%num_points_per_magnitude, &
1630 bs_env%regularization_minimax)
1631
1632 ! cosine transform weights imaginary frequency to imaginary time
1633 CALL get_l_sq_wghts_cos_tf_w_to_t(num_time_freq_points, &
1634 bs_env%imag_time_points, &
1635 bs_env%weights_cos_w_to_t, &
1636 bs_env%imag_freq_points, &
1637 e_min, e_max, max_error_min, &
1638 bs_env%num_points_per_magnitude, &
1639 bs_env%regularization_minimax)
1640
1641 ! sine transform weights imaginary time to imaginary frequency
1642 CALL get_l_sq_wghts_sin_tf_t_to_w(num_time_freq_points, &
1643 bs_env%imag_time_points, &
1644 bs_env%weights_sin_t_to_w, &
1645 bs_env%imag_freq_points, &
1646 e_min, e_max, max_error_min, &
1647 bs_env%num_points_per_magnitude, &
1648 bs_env%regularization_minimax)
1649
1650 u = bs_env%unit_nr
1651 IF (u > 0) THEN
1652 WRITE (u, '(T2,A)') ''
1653 WRITE (u, '(T2,A,F44.2)') Γ'SCF direct band gap at -point (eV)', e_min*evolt
1654 WRITE (u, '(T2,A,F42.2)') Γ'Max. SCF eigval diff. at -point (eV)', e_max*evolt
1655 WRITE (u, '(T2,A,F55.2)') 'E-Range for minimax grid', e_range
1656 WRITE (u, '(T2,A,I27)') é'Number of Pad parameters for analytic continuation:', &
1657 bs_env%nparam_pade
1658 WRITE (u, '(T2,A)') ''
1659 END IF
1660 CALL timestop(handle)
1661
1662 END SUBROUTINE setup_time_and_frequency_minimax_grid
1663
1664END MODULE gw_utils
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
struct tensor_ tensor
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public graml2024
Handles all functions related to the CELL.
Definition cell_types.F:15
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
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
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_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, use_sp)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
character(len=default_path_length) function, public cp_print_key_generate_filename(logger, print_key, middle_name, extension, my_local)
Utility function that returns a unit number to write the print key. Might open a file with a unique f...
This is the start of a dbt_api, all publically needed functions are exported here....
Definition dbt_api.F:17
subroutine, public de_init_bs_env(bs_env)
...
Definition gw_utils.F:173
subroutine, public compute_xkp(xkp, ikp_start, ikp_end, grid)
...
Definition gw_utils.F:519
subroutine, public create_and_init_bs_env_for_gw(qs_env, bs_env, bs_sec)
...
Definition gw_utils.F:115
subroutine, public kpoint_init_cell_index_simple(kpoints, qs_env)
...
Definition gw_utils.F:489
subroutine, public get_i_j_atoms(atoms_i, atoms_j, n_atom_i, n_atom_j, color_sub, bs_env)
...
Definition gw_utils.F:1272
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_potential_truncated
integer, parameter, public xc_none
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
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns 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
integer, parameter, public default_string_length
Definition kinds.F:57
Routines needed for kpoint calculation.
subroutine, public kpoint_init_cell_index(kpoint, sab_nl, para_env, dft_control)
Generates the mapping of cell indices and linear RS index CELL (0,0,0) is always mapped to index 1.
Types and basic routines needed for a kpoint calculation.
subroutine, public kpoint_create(kpoint)
Create a kpoint environment.
Interface to the Libint-Library or a c++ wrapper.
subroutine, public cp_libint_static_cleanup()
subroutine, public cp_libint_static_init()
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:332
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition machine.F:123
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
elemental integer function, public gcd(a, b)
computes the greatest common divisor of two number
Definition mathlib.F:1291
Interface to the message passing library MPI.
Routines to calculate the minimax coefficients in order to approximate 1/x as a sum over exponential ...
subroutine, public get_exp_minimax_coeff_gw(k, e_range, aw)
...
Routines to calculate the minimax coefficients in order to approximate 1/x as a sum over exponential ...
Definition minimax_exp.F:29
subroutine, public get_exp_minimax_coeff(k, rc, aw, mm_error, which_coeffs)
Get best minimax approximation for given input parameters. Automatically chooses the most exact set o...
Routines to calculate the minimax coefficients for approximating 1/x as 1/x ~ 1/pi SUM_{i}^{K} w_i x^...
Definition minimax_rpa.F:14
subroutine, public get_rpa_minimax_coeff_larger_grid(k, e_range, aw)
...
subroutine, public get_rpa_minimax_coeff(k, e_range, aw, ierr, print_warning)
The a_i and w_i coefficient are stored in aw such that the first 1:K elements correspond to a_i and t...
Definition minimax_rpa.F:41
Calls routines to get RI integrals and calculate total energies.
Definition mp2_gpw.F:14
subroutine, public create_mat_munu(mat_munu, qs_env, eps_grid, blacs_env_sub, do_ri_aux_basis, do_mixed_basis, group_size_prim, do_alloc_blocks_from_nbl, do_kpoints, sab_orb_sub, dbcsr_sym_type)
Encapsulate the building of dbcsr_matrix mat_munu.
Definition mp2_gpw.F:952
Routines to calculate frequency and time grids (integration points and weights) for correlation metho...
Definition mp2_grids.F:14
subroutine, public get_l_sq_wghts_cos_tf_w_to_t(num_integ_points, tau_tj, weights_cos_tf_w_to_t, omega_tj, e_min, e_max, max_error, num_points_per_magnitude, regularization)
...
Definition mp2_grids.F:1239
subroutine, public get_l_sq_wghts_cos_tf_t_to_w(num_integ_points, tau_tj, weights_cos_tf_t_to_w, omega_tj, e_min, e_max, max_error, num_points_per_magnitude, regularization)
Calculate integration weights for the tau grid (in dependency of the omega node)
Definition mp2_grids.F:740
subroutine, public get_l_sq_wghts_sin_tf_t_to_w(num_integ_points, tau_tj, weights_sin_tf_t_to_w, omega_tj, e_min, e_max, max_error, num_points_per_magnitude, regularization)
Calculate integration weights for the tau grid (in dependency of the omega node)
Definition mp2_grids.F:876
Framework for 2c-integrals for RI.
Definition mp2_ri_2c.F:14
subroutine, public setup_trunc_coulomb_pot_for_exchange_self_energy(qs_env, trunc_coulomb, rel_cutoff_trunc_coulomb_ri_x)
...
Definition mp2_ri_2c.F:1606
Define methods related to particle_type.
subroutine, public get_particle_set(particle_set, qs_kind_set, first_sgf, last_sgf, nsgf, nmao, basis)
Get the components of a particle set.
Define the data structure for the particle information.
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public evolt
Definition physcon.F:183
real(kind=dp), parameter, public angstrom
Definition physcon.F:144
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, 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_nonbond, sab_almo, sab_kp, sab_kp_nosym, 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, 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, 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, ecoul_1c, rho0_s_rs, rho0_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, 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, rhs)
Get the QUICKSTEP environment.
subroutine, public qs_env_part_release(qs_env)
releases part of the given qs_env in order to save memory
Some utility functions for the calculation of integrals.
subroutine, public basis_set_list_setup(basis_set_list, basis_type, qs_kind_set)
Set up an easy accessible list of the basis sets for all kinds.
Calculate the interaction radii for the operator matrix calculation.
subroutine, public init_interaction_radii_orb_basis(orb_basis_set, eps_pgf_orb, eps_pgf_short)
...
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_r3d_rs_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, floating, name, element_symbol, pao_basis_size, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
routines that build the Kohn-Sham matrix (i.e calculate the coulomb and xc parts
subroutine, public qs_ks_build_kohn_sham_matrix(qs_env, calculate_forces, just_energy, print_active, ext_ks_matrix)
routine where the real calculations are made: the KS matrix is calculated
Define the neighbor list data types and the corresponding functionality.
Utility methods to build 3-center integral tensors of various types.
subroutine, public distribution_3d_create(dist_3d, dist1, dist2, dist3, nkind, particle_set, mp_comm_3d, own_comm)
Create a 3d distribution.
subroutine, public create_2c_tensor(t2c, dist_1, dist_2, pgrid, sizes_1, sizes_2, order, name)
...
subroutine, public create_3c_tensor(t3c, dist_1, dist_2, dist_3, pgrid, sizes_1, sizes_2, sizes_3, map1, map2, name)
...
Utility methods to build 3-center integral tensors of various types.
Definition qs_tensors.F:11
subroutine, public neighbor_list_3c_destroy(ijk_list)
Destroy 3c neighborlist.
Definition qs_tensors.F:383
subroutine, public get_tensor_occupancy(tensor, nze, occ)
...
subroutine, public build_3c_neighbor_lists(ijk_list, basis_i, basis_j, basis_k, dist_3d, potential_parameter, name, qs_env, sym_ij, sym_jk, sym_ik, molecular, op_pos, own_dist)
Build a 3-center neighbor list.
Definition qs_tensors.F:282
subroutine, public build_3c_integrals(t3c, filter_eps, qs_env, nl_3c, basis_i, basis_j, basis_k, potential_parameter, int_eps, op_pos, do_kpoints, do_hfx_kpoints, desymmetrize, bounds_i, bounds_j, bounds_k, ri_range, img_to_ri_cell)
Build 3-center integral tensor.
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
Contains information about kpoints.
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.