57 dbt_clear, dbt_create, dbt_destroy, dbt_filter, dbt_iterator_blocks_left, &
58 dbt_iterator_next_block, dbt_iterator_start, dbt_iterator_stop, dbt_iterator_type, &
59 dbt_mp_environ_pgrid, dbt_pgrid_create, dbt_pgrid_destroy, dbt_pgrid_type, dbt_type
130#include "base/base_uses.f90"
141 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'gw_utils'
156 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_and_init_bs_env_for_gw'
160 CALL timeset(routinen, handle)
164 CALL read_gw_input_parameters(bs_env, bs_sec)
166 CALL print_header_and_input_parameters(bs_env)
168 CALL setup_ao_and_ri_basis_set(qs_env, bs_env)
170 CALL get_ri_basis_and_basis_function_indices(qs_env, bs_env)
172 CALL set_heuristic_parameters(bs_env, qs_env)
176 CALL setup_kpoints_chi_eps_w(bs_env, bs_env%kpoints_chi_eps_W)
179 CALL setup_cells_3c(qs_env, bs_env)
182 CALL set_parallelization_parameters(qs_env, bs_env)
184 CALL allocate_matrices(qs_env, bs_env)
186 CALL compute_v_xc(qs_env, bs_env)
188 CALL create_tensors(qs_env, bs_env)
190 SELECT CASE (bs_env%small_cell_full_kp_or_large_cell_Gamma)
193 CALL allocate_gw_eigenvalues(bs_env)
195 CALL check_sparsity_3c(qs_env, bs_env)
197 CALL set_sparsity_parallelization_parameters(bs_env)
199 CALL check_for_restart_files(qs_env, bs_env)
203 CALL compute_3c_integrals(qs_env, bs_env)
205 CALL setup_cells_delta_r(bs_env)
207 CALL setup_parallelization_delta_r(bs_env)
209 CALL allocate_matrices_small_cell_full_kp(qs_env, bs_env)
211 CALL trafo_v_xc_r_to_kp(qs_env, bs_env)
213 CALL heuristic_ri_regularization(qs_env, bs_env)
217 CALL setup_time_and_frequency_minimax_grid(bs_env)
225 IF (.NOT. bs_env%do_ldos .AND. .false.)
THEN
229 CALL timestop(handle)
243 CHARACTER(LEN=*),
PARAMETER :: routinen =
'de_init_bs_env'
246 LOGICAL :: retain_nl_3c, rirs_kernel
248 CALL timeset(routinen, handle)
256 retain_nl_3c = .false.
257 IF (
ASSOCIATED(bs_env%nl_3c%ij_list) .AND. (bs_env%rtp_method ==
rtp_method_bse))
THEN
259 retain_nl_3c = .NOT. rirs_kernel
262 IF (retain_nl_3c)
THEN
263 IF (bs_env%unit_nr > 0)
WRITE (bs_env%unit_nr, *)
"Retaining nl_3c for AO-RI RT-BSE self-energy"
270 CALL timestop(handle)
287 LOGICAL,
INTENT(OUT),
OPTIONAL :: rirs_kernel
290 LOGICAL :: my_rirs_kernel
294 NULLIFY (dft_control, input)
295 CALL get_qs_env(qs_env, dft_control=dft_control, input=input)
299 SELECT CASE (kernel_ri)
301 my_rirs_kernel = .true.
303 my_rirs_kernel = .false.
305 my_rirs_kernel = bs_env%do_gw_ri_rs
311 cpwarn(
"RI-RS kernels are implemented for linearized RT-BSE only; forcing AO")
313 my_rirs_kernel = .false.
316 IF (
PRESENT(rirs_kernel)) rirs_kernel = my_rirs_kernel
325 SUBROUTINE read_gw_input_parameters(bs_env, bs_sec)
329 CHARACTER(LEN=*),
PARAMETER :: routinen =
'read_gw_input_parameters'
334 CALL timeset(routinen, handle)
342 CALL section_vals_val_get(gw_sec,
"REGULARIZATION_MINIMAX", r_val=bs_env%input_regularization_minimax)
351 CALL section_vals_val_get(gw_sec,
"PRINT%PRINT_DBT_CONTRACT_VERBOSE", l_val=bs_env%print_contract_verbose)
355 CALL section_vals_val_get(gw_sec,
"CUTOFF_RADIUS_RL_RI", r_val=bs_env%ri_rs%cutoff_radius_ri_rs)
356 CALL section_vals_val_get(gw_sec,
"CUTOFF_RADIUS_RL_AO", r_val=bs_env%ri_rs%cutoff_radius_ri_ao)
357 CALL section_vals_val_get(gw_sec,
"N_PROCS_PER_ATOM_Z_LP", i_val=bs_env%ri_rs%n_procs_per_atom_z_lp)
363 IF (bs_env%print_contract)
THEN
364 bs_env%unit_nr_contract = bs_env%unit_nr
366 bs_env%unit_nr_contract = 0
368 CALL timestop(handle)
370 END SUBROUTINE read_gw_input_parameters
377 SUBROUTINE setup_ao_and_ri_basis_set(qs_env, bs_env)
381 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_AO_and_RI_basis_set'
383 INTEGER :: handle, natom, nkind
385 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
387 CALL timeset(routinen, handle)
390 qs_kind_set=qs_kind_set, &
391 particle_set=particle_set, &
392 natom=natom, nkind=nkind)
395 ALLOCATE (bs_env%sizes_RI(natom), bs_env%sizes_AO(natom))
396 ALLOCATE (bs_env%basis_set_RI(nkind), bs_env%basis_set_AO(nkind))
402 basis=bs_env%basis_set_RI)
404 basis=bs_env%basis_set_AO)
406 CALL timestop(handle)
408 END SUBROUTINE setup_ao_and_ri_basis_set
415 SUBROUTINE get_ri_basis_and_basis_function_indices(qs_env, bs_env)
419 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_RI_basis_and_basis_function_indices'
421 INTEGER :: handle, i_ri, iatom, ikind, iset, &
422 max_ao_bf_per_atom, n_ao_test, n_atom, &
423 n_kind, n_ri, nset, nsgf, u
424 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: kind_of
425 INTEGER,
DIMENSION(:),
POINTER :: l_max, l_min, nsgf_set
428 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
430 CALL timeset(routinen, handle)
433 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set)
435 n_kind =
SIZE(qs_kind_set)
436 n_atom = bs_env%n_atom
441 CALL get_qs_kind(qs_kind=qs_kind_set(ikind), basis_set=basis_set_a, &
443 IF (.NOT.
ASSOCIATED(basis_set_a))
THEN
444 CALL cp_abort(__location__, &
445 "At least one RI_AUX basis set was not explicitly invoked in &KIND-section.")
449 ALLOCATE (bs_env%i_RI_start_from_atom(n_atom))
450 ALLOCATE (bs_env%i_RI_end_from_atom(n_atom))
451 ALLOCATE (bs_env%i_ao_start_from_atom(n_atom))
452 ALLOCATE (bs_env%i_ao_end_from_atom(n_atom))
456 bs_env%i_RI_start_from_atom(iatom) = n_ri + 1
457 ikind = kind_of(iatom)
458 CALL get_qs_kind(qs_kind=qs_kind_set(ikind), nsgf=nsgf, basis_type=
"RI_AUX")
460 bs_env%i_RI_end_from_atom(iatom) = n_ri
464 max_ao_bf_per_atom = 0
467 bs_env%i_ao_start_from_atom(iatom) = n_ao_test + 1
468 ikind = kind_of(iatom)
469 CALL get_qs_kind(qs_kind=qs_kind_set(ikind), nsgf=nsgf, basis_type=
"ORB")
470 n_ao_test = n_ao_test + nsgf
471 bs_env%i_ao_end_from_atom(iatom) = n_ao_test
472 max_ao_bf_per_atom = max(max_ao_bf_per_atom, nsgf)
474 cpassert(n_ao_test == bs_env%n_ao)
475 bs_env%max_AO_bf_per_atom = max_ao_bf_per_atom
477 ALLOCATE (bs_env%l_RI(n_ri))
480 ikind = kind_of(iatom)
482 nset = bs_env%basis_set_RI(ikind)%gto_basis_set%nset
483 l_max => bs_env%basis_set_RI(ikind)%gto_basis_set%lmax
484 l_min => bs_env%basis_set_RI(ikind)%gto_basis_set%lmin
485 nsgf_set => bs_env%basis_set_RI(ikind)%gto_basis_set%nsgf_set
488 cpassert(l_max(iset) == l_min(iset))
489 bs_env%l_RI(i_ri + 1:i_ri + nsgf_set(iset)) = l_max(iset)
490 i_ri = i_ri + nsgf_set(iset)
494 cpassert(i_ri == n_ri)
499 WRITE (u, fmt=
"(T2,A)")
" "
500 WRITE (u, fmt=
"(T2,2A,T75,I8)")
"Number of auxiliary Gaussian basis functions ", &
504 CALL timestop(handle)
506 END SUBROUTINE get_ri_basis_and_basis_function_indices
513 SUBROUTINE setup_kpoints_chi_eps_w(bs_env, kpoints)
518 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_kpoints_chi_eps_W'
520 INTEGER :: handle, i_dim, n_dim, nkp, nkp_extra, &
522 INTEGER,
DIMENSION(3) :: nkp_grid, nkp_grid_extra, periodic
523 REAL(kind=
dp) :: exp_s_p, n_dim_inv
525 CALL timeset(routinen, handle)
531 kpoints%kp_scheme =
"GENERAL"
533 periodic(1:3) = bs_env%periodic(1:3)
535 cpassert(
SIZE(bs_env%nkp_grid_chi_eps_W_input) == 3)
537 IF (bs_env%nkp_grid_chi_eps_W_input(1) > 0 .AND. &
538 bs_env%nkp_grid_chi_eps_W_input(2) > 0 .AND. &
539 bs_env%nkp_grid_chi_eps_W_input(3) > 0)
THEN
542 SELECT CASE (periodic(i_dim))
545 nkp_grid_extra(i_dim) = 1
547 nkp_grid(i_dim) = bs_env%nkp_grid_chi_eps_W_input(i_dim)
548 nkp_grid_extra(i_dim) = nkp_grid(i_dim)*2
550 cpabort(
"Error in periodicity.")
554 ELSE IF (bs_env%nkp_grid_chi_eps_W_input(1) == -1 .AND. &
555 bs_env%nkp_grid_chi_eps_W_input(2) == -1 .AND. &
556 bs_env%nkp_grid_chi_eps_W_input(3) == -1)
THEN
561 cpassert(periodic(i_dim) == 0 .OR. periodic(i_dim) == 1)
563 SELECT CASE (periodic(i_dim))
566 nkp_grid_extra(i_dim) = 1
568 SELECT CASE (bs_env%small_cell_full_kp_or_large_cell_Gamma)
571 nkp_grid_extra(i_dim) = 6
573 nkp_grid(i_dim) = bs_env%kpoints_scf_desymm%nkp_grid(i_dim)*4
574 nkp_grid_extra(i_dim) = bs_env%kpoints_scf_desymm%nkp_grid(i_dim)*8
577 cpabort(
"Error in periodicity.")
584 cpabort(
"An error occured when setting up the k-mesh for W.")
588 nkp_orig = max(nkp_grid(1)*nkp_grid(2)*nkp_grid(3)/2, 1)
590 nkp_extra = nkp_grid_extra(1)*nkp_grid_extra(2)*nkp_grid_extra(3)/2
592 nkp = nkp_orig + nkp_extra
594 kpoints%nkp_grid(1:3) = nkp_grid(1:3)
597 bs_env%nkp_grid_chi_eps_W_orig(1:3) = nkp_grid(1:3)
598 bs_env%nkp_grid_chi_eps_W_extra(1:3) = nkp_grid_extra(1:3)
599 bs_env%nkp_chi_eps_W_orig = nkp_orig
600 bs_env%nkp_chi_eps_W_extra = nkp_extra
601 bs_env%nkp_chi_eps_W_orig_plus_extra = nkp
603 ALLOCATE (kpoints%xkp(3, nkp), kpoints%wkp(nkp))
604 ALLOCATE (bs_env%wkp_no_extra(nkp), bs_env%wkp_s_p(nkp))
606 CALL compute_xkp(kpoints%xkp, 1, nkp_orig, nkp_grid)
607 CALL compute_xkp(kpoints%xkp, nkp_orig + 1, nkp, nkp_grid_extra)
609 n_dim = sum(periodic)
612 kpoints%wkp(1) = 1.0_dp
613 bs_env%wkp_s_p(1) = 1.0_dp
614 bs_env%wkp_no_extra(1) = 1.0_dp
617 n_dim_inv = 1.0_dp/real(n_dim, kind=
dp)
620 CALL compute_wkp(kpoints%wkp(1:nkp_orig), nkp_orig, nkp_extra, n_dim_inv)
621 CALL compute_wkp(kpoints%wkp(nkp_orig + 1:nkp), nkp_extra, nkp_orig, n_dim_inv)
623 bs_env%wkp_no_extra(1:nkp_orig) = 0.0_dp
624 bs_env%wkp_no_extra(nkp_orig + 1:nkp) = 1.0_dp/real(nkp_extra, kind=
dp)
629 exp_s_p = 2.0_dp*n_dim_inv
630 CALL compute_wkp(bs_env%wkp_s_p(1:nkp_orig), nkp_orig, nkp_extra, exp_s_p)
631 CALL compute_wkp(bs_env%wkp_s_p(nkp_orig + 1:nkp), nkp_extra, nkp_orig, exp_s_p)
633 bs_env%wkp_s_p(1:nkp) = bs_env%wkp_no_extra(1:nkp)
638 IF (bs_env%approx_kp_extrapol)
THEN
639 bs_env%wkp_orig = 1.0_dp/real(nkp_orig, kind=
dp)
645 bs_env%nkp_chi_eps_W_batch = 4
647 bs_env%num_chi_eps_W_batches = (bs_env%nkp_chi_eps_W_orig_plus_extra - 1)/ &
648 bs_env%nkp_chi_eps_W_batch + 1
653 WRITE (u, fmt=
"(T2,A)")
" "
654 WRITE (u, fmt=
"(T2,1A,T71,3I4)") χε
"K-point mesh 1 for , , W", nkp_grid(1:3)
655 WRITE (u, fmt=
"(T2,2A,T71,3I4)") χε
"K-point mesh 2 for , , W ", &
656 "(for k-point extrapolation of W)", nkp_grid_extra(1:3)
657 WRITE (u, fmt=
"(T2,A,T80,L)")
"Approximate the k-point extrapolation", &
658 bs_env%approx_kp_extrapol
661 CALL timestop(handle)
663 END SUBROUTINE setup_kpoints_chi_eps_w
674 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: xkp
675 INTEGER :: ikp_start, ikp_end
676 INTEGER,
DIMENSION(3) :: grid
678 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_xkp'
680 INTEGER :: handle, i, ix, iy, iz
682 CALL timeset(routinen, handle)
689 IF (i > ikp_end) cycle
691 xkp(1, i) = real(2*ix - grid(1) - 1, kind=
dp)/(2._dp*real(grid(1), kind=
dp))
692 xkp(2, i) = real(2*iy - grid(2) - 1, kind=
dp)/(2._dp*real(grid(2), kind=
dp))
693 xkp(3, i) = real(2*iz - grid(3) - 1, kind=
dp)/(2._dp*real(grid(3), kind=
dp))
700 CALL timestop(handle)
711 SUBROUTINE compute_wkp(wkp, nkp_1, nkp_2, exponent)
712 REAL(kind=
dp),
DIMENSION(:) :: wkp
713 INTEGER :: nkp_1, nkp_2
714 REAL(kind=
dp) :: exponent
716 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_wkp'
719 REAL(kind=
dp) :: nkp_ratio
721 CALL timeset(routinen, handle)
723 nkp_ratio = real(nkp_2, kind=
dp)/real(nkp_1, kind=
dp)
725 wkp(:) = 1.0_dp/real(nkp_1, kind=
dp)/(1.0_dp - nkp_ratio**exponent)
727 CALL timestop(handle)
729 END SUBROUTINE compute_wkp
736 SUBROUTINE allocate_matrices(qs_env, bs_env)
740 CHARACTER(LEN=*),
PARAMETER :: routinen =
'allocate_matrices'
742 INTEGER :: handle, i_t
747 CALL timeset(routinen, handle)
749 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
751 fm_struct => bs_env%fm_ks_Gamma(1)%matrix_struct
756 NULLIFY (fm_struct_ri_global)
757 CALL cp_fm_struct_create(fm_struct_ri_global, context=blacs_env, nrow_global=bs_env%n_RI, &
758 ncol_global=bs_env%n_RI, para_env=para_env)
760 CALL cp_fm_create(bs_env%fm_chi_Gamma_freq, fm_struct_ri_global)
761 CALL cp_fm_create(bs_env%fm_W_MIC_freq, fm_struct_ri_global)
762 IF (bs_env%approx_kp_extrapol)
THEN
763 CALL cp_fm_create(bs_env%fm_W_MIC_freq_1_extra, fm_struct_ri_global)
764 CALL cp_fm_create(bs_env%fm_W_MIC_freq_1_no_extra, fm_struct_ri_global)
771 NULLIFY (blacs_env_tensor)
778 CALL create_mat_munu(bs_env%mat_ao_ao_tensor, qs_env, bs_env%eps_atom_grid_2d_mat, &
779 blacs_env_tensor, do_ri_aux_basis=.false.)
781 CALL create_mat_munu(bs_env%mat_RI_RI_tensor, qs_env, bs_env%eps_atom_grid_2d_mat, &
782 blacs_env_tensor, do_ri_aux_basis=.true.)
784 CALL create_mat_munu(bs_env%mat_RI_RI, qs_env, bs_env%eps_atom_grid_2d_mat, &
785 blacs_env, do_ri_aux_basis=.true.)
789 NULLIFY (bs_env%mat_chi_Gamma_tau)
792 DO i_t = 1, bs_env%num_time_freq_points
793 ALLOCATE (bs_env%mat_chi_Gamma_tau(i_t)%matrix)
794 CALL dbcsr_create(bs_env%mat_chi_Gamma_tau(i_t)%matrix, template=bs_env%mat_RI_RI%matrix)
797 CALL timestop(handle)
799 END SUBROUTINE allocate_matrices
805 SUBROUTINE allocate_gw_eigenvalues(bs_env)
808 CHARACTER(LEN=*),
PARAMETER :: routinen =
'allocate_GW_eigenvalues'
812 CALL timeset(routinen, handle)
814 ALLOCATE (bs_env%eigenval_G0W0(bs_env%n_ao, bs_env%nkp_bs_and_DOS, bs_env%n_spin))
815 ALLOCATE (bs_env%eigenval_HF(bs_env%n_ao, bs_env%nkp_bs_and_DOS, bs_env%n_spin))
817 CALL timestop(handle)
819 END SUBROUTINE allocate_gw_eigenvalues
826 SUBROUTINE create_tensors(qs_env, bs_env)
830 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_tensors'
834 CALL timeset(routinen, handle)
836 CALL init_interaction_radii(bs_env)
840 CALL create_3c_t(bs_env%t_RI_AO__AO, bs_env%para_env_tensor,
"(RI AO | AO)", [1, 2], [3], &
841 bs_env%sizes_RI, bs_env%sizes_AO, &
842 create_nl_3c=.true., nl_3c=bs_env%nl_3c, qs_env=qs_env)
843 CALL create_3c_t(bs_env%t_RI__AO_AO, bs_env%para_env_tensor,
"(RI | AO AO)", [1], [2, 3], &
844 bs_env%sizes_RI, bs_env%sizes_AO)
846 CALL create_2c_t(bs_env, bs_env%sizes_RI, bs_env%sizes_AO)
848 CALL timestop(handle)
850 END SUBROUTINE create_tensors
857 SUBROUTINE check_sparsity_3c(qs_env, bs_env)
861 CHARACTER(LEN=*),
PARAMETER :: routinen =
'check_sparsity_3c'
863 INTEGER :: handle, n_atom_step, ri_atom
864 INTEGER(int_8) :: non_zero_elements_sum, nze
865 REAL(
dp) :: max_dist_ao_atoms, occ, occupation_sum
866 REAL(kind=
dp) :: t1, t2
867 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_global_array
873 CALL timeset(routinen, handle)
878 ALLOCATE (t_3c_global_array(1, 1))
879 CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_global_array(1, 1))
883 ALLOCATE (bs_env%min_RI_idx_from_AO_AO_atom(bs_env%n_atom, bs_env%n_atom))
884 ALLOCATE (bs_env%max_RI_idx_from_AO_AO_atom(bs_env%n_atom, bs_env%n_atom))
885 ALLOCATE (bs_env%min_AO_idx_from_RI_AO_atom(bs_env%n_atom, bs_env%n_atom))
886 ALLOCATE (bs_env%max_AO_idx_from_RI_AO_atom(bs_env%n_atom, bs_env%n_atom))
887 bs_env%min_RI_idx_from_AO_AO_atom(:, :) = bs_env%n_RI
888 bs_env%max_RI_idx_from_AO_AO_atom(:, :) = 1
889 bs_env%min_AO_idx_from_RI_AO_atom(:, :) = bs_env%n_AO
890 bs_env%max_AO_idx_from_RI_AO_atom(:, :) = 1
892 CALL bs_env%para_env%sync()
895 occupation_sum = 0.0_dp
896 non_zero_elements_sum = 0
897 max_dist_ao_atoms = 0.0_dp
898 n_atom_step = int(sqrt(real(bs_env%n_atom, kind=
dp)))
900 DO ri_atom = 1, bs_env%n_atom, n_atom_step
906 int_eps=bs_env%eps_filter, &
907 basis_i=bs_env%basis_set_RI, &
908 basis_j=bs_env%basis_set_AO, &
909 basis_k=bs_env%basis_set_AO, &
910 bounds_i=[ri_atom, min(ri_atom + n_atom_step - 1, bs_env%n_atom)], &
911 potential_parameter=bs_env%ri_metric, &
912 desymmetrize=.false.)
914 CALL dbt_filter(t_3c_global_array(1, 1), bs_env%eps_filter)
916 CALL bs_env%para_env%sync()
919 non_zero_elements_sum = non_zero_elements_sum + nze
920 occupation_sum = occupation_sum + occ
922 CALL get_max_dist_ao_atoms(t_3c_global_array(1, 1), max_dist_ao_atoms, qs_env)
925 CALL get_i_j_atom_ranges(t_3c_global_array(1, 1), bs_env)
927 CALL dbt_clear(t_3c_global_array(1, 1))
934 bs_env%max_dist_AO_atoms = max_dist_ao_atoms
936 bs_env%occupation_3c_int = occupation_sum
938 CALL bs_env%para_env%min(bs_env%min_RI_idx_from_AO_AO_atom)
939 CALL bs_env%para_env%max(bs_env%max_RI_idx_from_AO_AO_atom)
940 CALL bs_env%para_env%min(bs_env%min_AO_idx_from_RI_AO_atom)
941 CALL bs_env%para_env%max(bs_env%max_AO_idx_from_RI_AO_atom)
943 CALL dbt_destroy(t_3c_global_array(1, 1))
944 DEALLOCATE (t_3c_global_array)
946 IF (bs_env%unit_nr > 0)
THEN
947 WRITE (bs_env%unit_nr,
'(T2,A)')
''
948 WRITE (bs_env%unit_nr,
'(T2,A,F27.1,A)') &
949 µν
'Computed 3-center integrals (|P), execution time', t2 - t1,
' s'
950 WRITE (bs_env%unit_nr,
'(T2,A,F48.3,A)') µν
'Percentage of non-zero (|P)', &
951 bs_env%occupation_3c_int*100,
' %'
952 WRITE (bs_env%unit_nr,
'(T2,A,F33.1,A)') µνµν
'Max. distance between , in non-zero (|P)', &
953 bs_env%max_dist_AO_atoms*
angstrom,
' A'
954 WRITE (bs_env%unit_nr,
'(T2,2A,I20,A)')
'Required memory if storing all 3-center ', &
955 µν
'integrals (|P)', int(real(non_zero_elements_sum, kind=
dp)*8.0e-9_dp),
' GB'
958 CALL timestop(handle)
960 END SUBROUTINE check_sparsity_3c
967 SUBROUTINE get_i_j_atom_ranges(t_3c, bs_env)
968 TYPE(dbt_type) :: t_3c
971 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_i_j_atom_ranges'
973 INTEGER :: handle, idx_ao_end, idx_ao_start, &
974 idx_ri_end, idx_ri_start
975 INTEGER,
DIMENSION(3) :: atom_ind
976 TYPE(dbt_iterator_type) :: iter
978 CALL timeset(routinen, handle)
986 CALL dbt_iterator_start(iter, t_3c)
987 DO WHILE (dbt_iterator_blocks_left(iter))
988 CALL dbt_iterator_next_block(iter, atom_ind)
991 idx_ri_start = bs_env%i_RI_start_from_atom(atom_ind(1))
992 idx_ri_end = bs_env%i_RI_end_from_atom(atom_ind(1))
994 idx_ao_start = bs_env%i_ao_start_from_atom(atom_ind(2))
995 idx_ao_end = bs_env%i_ao_end_from_atom(atom_ind(2))
999 bs_env%min_RI_idx_from_AO_AO_atom(atom_ind(2), atom_ind(3)) = &
1000 min(bs_env%min_RI_idx_from_AO_AO_atom(atom_ind(2), atom_ind(3)), idx_ri_start)
1002 bs_env%max_RI_idx_from_AO_AO_atom(atom_ind(2), atom_ind(3)) = &
1003 max(bs_env%max_RI_idx_from_AO_AO_atom(atom_ind(2), atom_ind(3)), idx_ri_end)
1006 bs_env%min_AO_idx_from_RI_AO_atom(atom_ind(1), atom_ind(3)) = &
1007 min(bs_env%min_AO_idx_from_RI_AO_atom(atom_ind(1), atom_ind(3)), idx_ao_start)
1009 bs_env%max_AO_idx_from_RI_AO_atom(atom_ind(1), atom_ind(3)) = &
1010 max(bs_env%max_AO_idx_from_RI_AO_atom(atom_ind(1), atom_ind(3)), idx_ao_end)
1013 CALL dbt_iterator_stop(iter)
1016 CALL timestop(handle)
1018 END SUBROUTINE get_i_j_atom_ranges
1026 SUBROUTINE create_2c_t(bs_env, sizes_RI, sizes_AO)
1028 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: sizes_ri, sizes_ao
1030 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_2c_t'
1033 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: dist_1, dist_2
1034 INTEGER,
DIMENSION(2) :: pdims_2d
1035 TYPE(dbt_pgrid_type) :: pgrid_2d
1037 CALL timeset(routinen, handle)
1042 CALL dbt_pgrid_create(bs_env%para_env_tensor, pdims_2d, pgrid_2d)
1044 CALL create_2c_tensor(bs_env%t_G, dist_1, dist_2, pgrid_2d, sizes_ao, sizes_ao, &
1046 DEALLOCATE (dist_1, dist_2)
1047 CALL create_2c_tensor(bs_env%t_chi, dist_1, dist_2, pgrid_2d, sizes_ri, sizes_ri, &
1049 DEALLOCATE (dist_1, dist_2)
1050 CALL create_2c_tensor(bs_env%t_W, dist_1, dist_2, pgrid_2d, sizes_ri, sizes_ri, &
1052 DEALLOCATE (dist_1, dist_2)
1053 CALL dbt_pgrid_destroy(pgrid_2d)
1055 CALL timestop(handle)
1057 END SUBROUTINE create_2c_t
1072 SUBROUTINE create_3c_t(tensor, para_env, tensor_name, map1, map2, sizes_RI, sizes_AO, &
1073 create_nl_3c, nl_3c, qs_env)
1076 CHARACTER(LEN=12) :: tensor_name
1077 INTEGER,
DIMENSION(:) :: map1, map2
1078 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: sizes_ri, sizes_ao
1079 LOGICAL,
OPTIONAL :: create_nl_3c
1083 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_3c_t'
1085 INTEGER :: handle, nkind
1086 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: dist_ao_1, dist_ao_2, dist_ri
1087 INTEGER,
DIMENSION(3) :: pcoord, pdims, pdims_3d
1088 LOGICAL :: my_create_nl_3c
1089 TYPE(dbt_pgrid_type) :: pgrid_3d
1094 CALL timeset(routinen, handle)
1097 CALL dbt_pgrid_create(para_env, pdims_3d, pgrid_3d)
1099 pgrid_3d, sizes_ri, sizes_ao, sizes_ao, &
1100 map1=map1, map2=map2, name=tensor_name)
1102 IF (
PRESENT(create_nl_3c))
THEN
1103 my_create_nl_3c = create_nl_3c
1105 my_create_nl_3c = .false.
1108 IF (my_create_nl_3c)
THEN
1109 CALL get_qs_env(qs_env, nkind=nkind, particle_set=particle_set)
1110 CALL dbt_mp_environ_pgrid(pgrid_3d, pdims, pcoord)
1111 CALL mp_comm_t3c_2%create(pgrid_3d%mp_comm_2d, 3, pdims)
1113 nkind, particle_set, mp_comm_t3c_2, own_comm=.true.)
1116 qs_env%bs_env%basis_set_RI, &
1117 qs_env%bs_env%basis_set_AO, &
1118 qs_env%bs_env%basis_set_AO, &
1119 dist_3d, qs_env%bs_env%ri_metric, &
1120 "GW_3c_nl", qs_env, own_dist=.true.)
1123 DEALLOCATE (dist_ri, dist_ao_1, dist_ao_2)
1124 CALL dbt_pgrid_destroy(pgrid_3d)
1126 CALL timestop(handle)
1128 END SUBROUTINE create_3c_t
1134 SUBROUTINE init_interaction_radii(bs_env)
1137 CHARACTER(LEN=*),
PARAMETER :: routinen =
'init_interaction_radii'
1139 INTEGER :: handle, ibasis
1142 CALL timeset(routinen, handle)
1144 DO ibasis = 1,
SIZE(bs_env%basis_set_AO)
1146 orb_basis => bs_env%basis_set_AO(ibasis)%gto_basis_set
1149 ri_basis => bs_env%basis_set_RI(ibasis)%gto_basis_set
1154 CALL timestop(handle)
1156 END SUBROUTINE init_interaction_radii
1164 SUBROUTINE get_max_dist_ao_atoms(t_3c_int, max_dist_AO_atoms, qs_env)
1165 TYPE(dbt_type) :: t_3c_int
1166 REAL(kind=
dp),
INTENT(INOUT) :: max_dist_ao_atoms
1169 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_max_dist_AO_atoms'
1171 INTEGER :: atom_1, atom_2, handle, num_cells
1172 INTEGER,
DIMENSION(3) :: atom_ind
1173 INTEGER,
DIMENSION(:, :),
POINTER :: index_to_cell
1174 REAL(kind=
dp) :: abs_rab
1175 REAL(kind=
dp),
DIMENSION(3) :: rab
1177 TYPE(dbt_iterator_type) :: iter
1181 CALL timeset(routinen, handle)
1183 NULLIFY (cell, particle_set, para_env)
1184 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set, para_env=para_env)
1195 CALL dbt_iterator_start(iter, t_3c_int)
1196 DO WHILE (dbt_iterator_blocks_left(iter))
1197 CALL dbt_iterator_next_block(iter, atom_ind)
1199 atom_1 = atom_ind(2)
1200 atom_2 = atom_ind(3)
1201 rab =
pbc(particle_set(atom_1)%r(1:3), particle_set(atom_2)%r(1:3), cell)
1202 abs_rab = sqrt(rab(1)**2 + rab(2)**2 + rab(3)**2)
1205 max_dist_ao_atoms = max(max_dist_ao_atoms, abs_rab)
1208 CALL dbt_iterator_stop(iter)
1211 CALL para_env%max(max_dist_ao_atoms)
1213 CALL timestop(handle)
1215 END SUBROUTINE get_max_dist_ao_atoms
1221 SUBROUTINE set_sparsity_parallelization_parameters(bs_env)
1224 CHARACTER(LEN=*),
PARAMETER :: routinen =
'set_sparsity_parallelization_parameters'
1226 INTEGER :: handle, i_ivl, il_ivl, j_ivl, n_atom_per_il_ivl, n_atom_per_ivl, n_intervals_i, &
1227 n_intervals_inner_loop_atoms, n_intervals_j, u
1228 INTEGER(KIND=int_8) :: input_memory_per_proc
1230 CALL timeset(routinen, handle)
1233 bs_env%safety_factor_memory = 0.10_dp
1235 input_memory_per_proc = int(bs_env%input_memory_per_proc_GB*1.0e9_dp, kind=
int_8)
1241 n_atom_per_ivl = int(sqrt(bs_env%safety_factor_memory*input_memory_per_proc &
1242 *bs_env%group_size_tensor/24/bs_env%n_RI &
1243 /sqrt(bs_env%occupation_3c_int)))/bs_env%max_AO_bf_per_atom
1245 n_intervals_i = (bs_env%n_atom_i - 1)/n_atom_per_ivl + 1
1246 n_intervals_j = (bs_env%n_atom_j - 1)/n_atom_per_ivl + 1
1248 bs_env%n_atom_per_interval_ij = n_atom_per_ivl
1249 bs_env%n_intervals_i = n_intervals_i
1250 bs_env%n_intervals_j = n_intervals_j
1252 ALLOCATE (bs_env%i_atom_intervals(2, n_intervals_i))
1253 ALLOCATE (bs_env%j_atom_intervals(2, n_intervals_j))
1255 DO i_ivl = 1, n_intervals_i
1256 bs_env%i_atom_intervals(1, i_ivl) = (i_ivl - 1)*n_atom_per_ivl + bs_env%atoms_i(1)
1257 bs_env%i_atom_intervals(2, i_ivl) = min(i_ivl*n_atom_per_ivl + bs_env%atoms_i(1) - 1, &
1261 DO j_ivl = 1, n_intervals_j
1262 bs_env%j_atom_intervals(1, j_ivl) = (j_ivl - 1)*n_atom_per_ivl + bs_env%atoms_j(1)
1263 bs_env%j_atom_intervals(2, j_ivl) = min(j_ivl*n_atom_per_ivl + bs_env%atoms_j(1) - 1, &
1267 ALLOCATE (bs_env%skip_Sigma_occ(n_intervals_i, n_intervals_j))
1268 ALLOCATE (bs_env%skip_Sigma_vir(n_intervals_i, n_intervals_j))
1269 bs_env%skip_Sigma_occ(:, :) = .false.
1270 bs_env%skip_Sigma_vir(:, :) = .false.
1271 bs_env%n_skip_chi = 0
1273 ALLOCATE (bs_env%skip_chi(n_intervals_i, n_intervals_j))
1274 bs_env%skip_chi(:, :) = .false.
1275 bs_env%n_skip_sigma = 0
1280 n_atom_per_il_ivl = min(int(bs_env%safety_factor_memory*input_memory_per_proc &
1281 *bs_env%group_size_tensor/n_atom_per_ivl &
1282 /bs_env%max_AO_bf_per_atom &
1283 /bs_env%n_RI/8/sqrt(bs_env%occupation_3c_int) &
1284 /bs_env%max_AO_bf_per_atom), bs_env%n_atom)
1286 n_intervals_inner_loop_atoms = (bs_env%n_atom - 1)/n_atom_per_il_ivl + 1
1288 bs_env%n_atom_per_IL_interval = n_atom_per_il_ivl
1289 bs_env%n_intervals_inner_loop_atoms = n_intervals_inner_loop_atoms
1291 ALLOCATE (bs_env%inner_loop_atom_intervals(2, n_intervals_inner_loop_atoms))
1292 DO il_ivl = 1, n_intervals_inner_loop_atoms
1293 bs_env%inner_loop_atom_intervals(1, il_ivl) = (il_ivl - 1)*n_atom_per_il_ivl + 1
1294 bs_env%inner_loop_atom_intervals(2, il_ivl) = min(il_ivl*n_atom_per_il_ivl, bs_env%n_atom)
1299 WRITE (u,
'(T2,A)')
''
1300 WRITE (u,
'(T2,A,I33)') λντνλτ
'Number of i and j atoms in M_P(), N_Q():', n_atom_per_ivl
1301 WRITE (u,
'(T2,A,I18)') µλνµµνµλ
'Number of inner loop atoms for in M_P = sum_ (|P) G_', &
1305 CALL timestop(handle)
1307 END SUBROUTINE set_sparsity_parallelization_parameters
1314 SUBROUTINE check_for_restart_files(qs_env, bs_env)
1318 CHARACTER(LEN=*),
PARAMETER :: routinen =
'check_for_restart_files'
1320 CHARACTER(LEN=9) :: frmt
1321 CHARACTER(len=default_path_length) :: f_chi, f_s_n, f_s_p, f_s_x, f_w_t, &
1322 prefix, project_name, z_lp_name
1323 INTEGER :: handle, i_spin, i_t_or_w, ind, n_spin, &
1324 num_time_freq_points
1325 LOGICAL :: chi_exists, sigma_neg_time_exists, &
1326 sigma_pos_time_exists, &
1327 sigma_x_spin_exists, w_time_exists, &
1332 CALL timeset(routinen, handle)
1334 num_time_freq_points = bs_env%num_time_freq_points
1335 n_spin = bs_env%n_spin
1337 ALLOCATE (bs_env%read_chi(num_time_freq_points))
1338 ALLOCATE (bs_env%calc_chi(num_time_freq_points))
1339 ALLOCATE (bs_env%Sigma_c_exists(num_time_freq_points, n_spin))
1347 WRITE (prefix,
'(2A)') trim(project_name),
"-RESTART_"
1348 bs_env%prefix = prefix
1350 bs_env%all_W_exist = .true.
1352 DO i_t_or_w = 1, num_time_freq_points
1354 IF (i_t_or_w < 10)
THEN
1355 WRITE (frmt,
'(A)')
'(3A,I1,A)'
1356 WRITE (f_chi, frmt) trim(prefix), bs_env%chi_name,
"_0", i_t_or_w,
".matrix"
1357 WRITE (f_w_t, frmt) trim(prefix), bs_env%W_time_name,
"_0", i_t_or_w,
".matrix"
1358 ELSE IF (i_t_or_w < 100)
THEN
1359 WRITE (frmt,
'(A)')
'(3A,I2,A)'
1360 WRITE (f_chi, frmt) trim(prefix), bs_env%chi_name,
"_", i_t_or_w,
".matrix"
1361 WRITE (f_w_t, frmt) trim(prefix), bs_env%W_time_name,
"_", i_t_or_w,
".matrix"
1363 cpabort(
'Please implement more than 99 time/frequency points.')
1366 INQUIRE (file=trim(f_chi), exist=chi_exists)
1367 INQUIRE (file=trim(f_w_t), exist=w_time_exists)
1369 bs_env%read_chi(i_t_or_w) = chi_exists
1370 bs_env%calc_chi(i_t_or_w) = .NOT. chi_exists
1372 bs_env%all_W_exist = bs_env%all_W_exist .AND. w_time_exists
1375 DO i_spin = 1, n_spin
1377 ind = i_t_or_w + (i_spin - 1)*num_time_freq_points
1380 WRITE (frmt,
'(A)')
'(3A,I1,A)'
1381 WRITE (f_s_p, frmt) trim(prefix), bs_env%Sigma_p_name,
"_0", ind,
".matrix"
1382 WRITE (f_s_n, frmt) trim(prefix), bs_env%Sigma_n_name,
"_0", ind,
".matrix"
1383 ELSE IF (ind < 100)
THEN
1384 WRITE (frmt,
'(A)')
'(3A,I2,A)'
1385 WRITE (f_s_p, frmt) trim(prefix), bs_env%Sigma_p_name,
"_", ind,
".matrix"
1386 WRITE (f_s_n, frmt) trim(prefix), bs_env%Sigma_n_name,
"_", ind,
".matrix"
1388 cpabort(
'Please implement more than 99 combined spin+freq indices.')
1391 INQUIRE (file=trim(f_s_p), exist=sigma_pos_time_exists)
1392 INQUIRE (file=trim(f_s_n), exist=sigma_neg_time_exists)
1394 bs_env%Sigma_c_exists(i_t_or_w, i_spin) = sigma_pos_time_exists .AND. &
1395 sigma_neg_time_exists
1404 WRITE (f_w_t,
'(3A,I1,A)') trim(prefix),
"W_freq_rtp",
"_0", 0,
".matrix"
1405 INQUIRE (file=trim(f_w_t), exist=w_time_exists)
1406 bs_env%all_W_exist = bs_env%all_W_exist .AND. w_time_exists
1410 IF (bs_env%do_gw_ri_rs)
THEN
1411 WRITE (z_lp_name,
'(3A)') trim(prefix),
"Z_lP",
".matrix"
1412 INQUIRE (file=trim(z_lp_name), exist=z_lp_exists)
1413 bs_env%ri_rs%Z_lP_exists = z_lp_exists
1416 IF (bs_env%all_W_exist)
THEN
1417 bs_env%read_chi(:) = .false.
1418 bs_env%calc_chi(:) = .false.
1421 bs_env%Sigma_x_exists = .true.
1422 DO i_spin = 1, n_spin
1423 WRITE (f_s_x,
'(3A,I1,A)') trim(prefix), bs_env%Sigma_x_name,
"_0", i_spin,
".matrix"
1424 INQUIRE (file=trim(f_s_x), exist=sigma_x_spin_exists)
1425 bs_env%Sigma_x_exists = bs_env%Sigma_x_exists .AND. sigma_x_spin_exists
1430 IF (any(bs_env%read_chi(:)) &
1431 .OR. any(bs_env%Sigma_c_exists) &
1432 .OR. bs_env%all_W_exist &
1433 .OR. bs_env%Sigma_x_exists &
1436 IF (qs_env%scf_env%iter_count /= 1)
THEN
1437 CALL cp_warn(__location__,
"SCF needed more than 1 step, "// &
1438 "which might lead to spurious GW results when using GW restart files. ")
1442 CALL timestop(handle)
1444 END SUBROUTINE check_for_restart_files
1451 SUBROUTINE set_parallelization_parameters(qs_env, bs_env)
1455 CHARACTER(LEN=*),
PARAMETER :: routinen =
'set_parallelization_parameters'
1457 INTEGER :: color_sub, dummy_1, dummy_2, handle, &
1458 num_pe, num_t_groups, u
1461 CALL timeset(routinen, handle)
1465 num_pe = para_env%num_pe
1468 IF (bs_env%group_size_tensor < 0 .OR. bs_env%group_size_tensor > num_pe)
THEN
1469 bs_env%group_size_tensor = num_pe
1473 IF (
modulo(num_pe, bs_env%group_size_tensor) /= 0)
THEN
1474 CALL find_good_group_size(num_pe, bs_env%group_size_tensor)
1478 color_sub = para_env%mepos/bs_env%group_size_tensor
1479 bs_env%tensor_group_color = color_sub
1481 ALLOCATE (bs_env%para_env_tensor)
1482 CALL bs_env%para_env_tensor%from_split(para_env, color_sub)
1484 num_t_groups = para_env%num_pe/bs_env%group_size_tensor
1485 bs_env%num_tensor_groups = num_t_groups
1487 CALL get_i_j_atoms(bs_env%atoms_i, bs_env%atoms_j, bs_env%n_atom_i, bs_env%n_atom_j, &
1490 ALLOCATE (bs_env%atoms_i_t_group(2, num_t_groups))
1491 ALLOCATE (bs_env%atoms_j_t_group(2, num_t_groups))
1492 DO color_sub = 0, num_t_groups - 1
1493 CALL get_i_j_atoms(bs_env%atoms_i_t_group(1:2, color_sub + 1), &
1494 bs_env%atoms_j_t_group(1:2, color_sub + 1), &
1495 dummy_1, dummy_2, color_sub, bs_env)
1500 WRITE (u,
'(T2,A,I47)')
'Group size for tensor operations', bs_env%group_size_tensor
1501 IF (bs_env%group_size_tensor > 1 .AND. bs_env%n_atom < 5)
THEN
1502 WRITE (u,
'(T2,A)')
'The requested group size is > 1 which can lead to bad performance.'
1503 WRITE (u,
'(T2,A)')
'Using more memory per MPI process might improve performance.'
1504 WRITE (u,
'(T2,A)')
'(Also increase MEMORY_PER_PROC when using more memory per process.)'
1508 CALL timestop(handle)
1510 END SUBROUTINE set_parallelization_parameters
1517 SUBROUTINE find_good_group_size(num_pe, group_size)
1519 INTEGER :: num_pe, group_size
1521 CHARACTER(LEN=*),
PARAMETER :: routinen =
'find_good_group_size'
1523 INTEGER :: group_size_minus, group_size_orig, &
1524 group_size_plus, handle, i_diff
1526 CALL timeset(routinen, handle)
1528 group_size_orig = group_size
1530 DO i_diff = 1, num_pe
1532 group_size_minus = group_size - i_diff
1534 IF (
modulo(num_pe, group_size_minus) == 0 .AND. group_size_minus > 0)
THEN
1535 group_size = group_size_minus
1539 group_size_plus = group_size + i_diff
1541 IF (
modulo(num_pe, group_size_plus) == 0 .AND. group_size_plus <= num_pe)
THEN
1542 group_size = group_size_plus
1548 IF (group_size_orig == group_size) cpabort(
"Group size error")
1550 CALL timestop(handle)
1552 END SUBROUTINE find_good_group_size
1563 SUBROUTINE get_i_j_atoms(atoms_i, atoms_j, n_atom_i, n_atom_j, color_sub, bs_env)
1565 INTEGER,
DIMENSION(2) :: atoms_i, atoms_j
1566 INTEGER :: n_atom_i, n_atom_j, color_sub
1569 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_i_j_atoms'
1571 INTEGER :: handle, i_atoms_per_group, i_group, &
1572 ipcol, ipcol_loop, iprow, iprow_loop, &
1573 j_atoms_per_group, npcol, nprow
1575 CALL timeset(routinen, handle)
1578 CALL square_mesh(nprow, npcol, bs_env%num_tensor_groups)
1581 DO ipcol_loop = 0, npcol - 1
1582 DO iprow_loop = 0, nprow - 1
1583 IF (i_group == color_sub)
THEN
1587 i_group = i_group + 1
1591 IF (
modulo(bs_env%n_atom, nprow) == 0)
THEN
1592 i_atoms_per_group = bs_env%n_atom/nprow
1594 i_atoms_per_group = bs_env%n_atom/nprow + 1
1597 IF (
modulo(bs_env%n_atom, npcol) == 0)
THEN
1598 j_atoms_per_group = bs_env%n_atom/npcol
1600 j_atoms_per_group = bs_env%n_atom/npcol + 1
1603 atoms_i(1) = iprow*i_atoms_per_group + 1
1604 atoms_i(2) = min((iprow + 1)*i_atoms_per_group, bs_env%n_atom)
1605 n_atom_i = atoms_i(2) - atoms_i(1) + 1
1607 atoms_j(1) = ipcol*j_atoms_per_group + 1
1608 atoms_j(2) = min((ipcol + 1)*j_atoms_per_group, bs_env%n_atom)
1609 n_atom_j = atoms_j(2) - atoms_j(1) + 1
1611 CALL timestop(handle)
1621 SUBROUTINE square_mesh(nprow, npcol, nproc)
1622 INTEGER :: nprow, npcol, nproc
1624 CHARACTER(LEN=*),
PARAMETER :: routinen =
'square_mesh'
1626 INTEGER :: gcd_max, handle, ipe, jpe
1628 CALL timeset(routinen, handle)
1631 DO ipe = 1, ceiling(sqrt(real(nproc,
dp)))
1633 IF (ipe*jpe /= nproc) cycle
1634 IF (
gcd(ipe, jpe) >= gcd_max)
THEN
1637 gcd_max =
gcd(ipe, jpe)
1641 CALL timestop(handle)
1643 END SUBROUTINE square_mesh
1650 SUBROUTINE set_heuristic_parameters(bs_env, qs_env)
1654 CHARACTER(LEN=*),
PARAMETER :: routinen =
'set_heuristic_parameters'
1656 INTEGER :: handle, u
1657 LOGICAL :: do_bvk_cell
1659 CALL timeset(routinen, handle)
1662 bs_env%num_points_per_magnitude = 200
1664 IF (bs_env%input_regularization_minimax > -1.0e-12_dp)
THEN
1665 bs_env%regularization_minimax = bs_env%input_regularization_minimax
1670 IF (sum(bs_env%periodic) /= 0 .OR. bs_env%num_time_freq_points >= 20)
THEN
1671 bs_env%regularization_minimax = 1.0e-6_dp
1673 bs_env%regularization_minimax = 0.0_dp
1677 bs_env%stabilize_exp = 70.0_dp
1678 bs_env%eps_atom_grid_2d_mat = 1.0e-50_dp
1681 bs_env%nparam_pade = 16
1685 bs_env%ri_metric%omega = 0.0_dp
1687 bs_env%ri_metric%filename =
"t_c_g.dat"
1689 bs_env%eps_eigval_mat_RI = 0.0_dp
1691 IF (bs_env%input_regularization_RI > -1.0e-12_dp)
THEN
1692 bs_env%regularization_RI = bs_env%input_regularization_RI
1697 bs_env%regularization_RI = 1.0e-2_dp
1700 IF (sum(bs_env%periodic) == 0) bs_env%regularization_RI = 0.0_dp
1708 rel_cutoff_trunc_coulomb_ri_x=0.5_dp, &
1709 cell_grid=bs_env%cell_grid_scf_desymm, &
1710 do_bvk_cell=do_bvk_cell)
1714 bs_env%heuristic_filter_factor = 1.0e-4
1718 WRITE (u, fmt=
"(T2,2A,F21.1,A)")
"Cutoff radius for the truncated Coulomb ", &
1719 Σ
"operator in ^x:", bs_env%trunc_coulomb%cutoff_radius*
angstrom, Å
" "
1720 WRITE (u, fmt=
"(T2,2A,F15.1,A)")
"Cutoff radius for the truncated Coulomb ", &
1721 "operator in RI metric:", bs_env%ri_metric%cutoff_radius*
angstrom, Å
" "
1722 WRITE (u, fmt=
"(T2,A,ES48.1)")
"Regularization parameter of RI ", bs_env%regularization_RI
1723 WRITE (u, fmt=
"(T2,A,ES38.1)")
"Regularization parameter of minimax grids", &
1724 bs_env%regularization_minimax
1725 WRITE (u, fmt=
"(T2,A,I53)")
"Lattice sum size for V(k):", bs_env%size_lattice_sum_V
1728 CALL timestop(handle)
1730 END SUBROUTINE set_heuristic_parameters
1736 SUBROUTINE print_header_and_input_parameters(bs_env)
1740 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_header_and_input_parameters'
1742 INTEGER :: handle, u
1744 CALL timeset(routinen, handle)
1749 WRITE (u,
'(T2,A)')
' '
1750 WRITE (u,
'(T2,A)') repeat(
'-', 79)
1751 WRITE (u,
'(T2,A,A78)')
'-',
'-'
1752 WRITE (u,
'(T2,A,A46,A32)')
'-',
'GW CALCULATION',
'-'
1753 WRITE (u,
'(T2,A,A78)')
'-',
'-'
1754 WRITE (u,
'(T2,A)') repeat(
'-', 79)
1755 WRITE (u,
'(T2,A)')
' '
1756 WRITE (u,
'(T2,A,I45)')
'Input: Number of time/freq. points', bs_env%num_time_freq_points
1757 WRITE (u,
"(T2,A,F44.1,A)") ωΣω
'Input: _max for fitting (i) (eV)', bs_env%freq_max_fit*
evolt
1758 WRITE (u,
'(T2,A,ES27.1)')
'Input: Filter threshold for sparse tensor operations', &
1760 WRITE (u,
"(T2,A,L55)")
'Input: Apply Hedin shift', bs_env%do_hedin_shift
1761 WRITE (u,
'(T2,A,F37.1,A)')
'Input: Available memory per MPI process', &
1762 bs_env%input_memory_per_proc_GB,
' GB'
1763 IF (bs_env%do_gw_ri_rs)
THEN
1764 WRITE (u,
'(A)')
' '
1765 WRITE (u,
'(T2,A,ES43.2)')
'Input: RI-RS Tikhonov regularization', &
1766 bs_env%ri_rs%tikhonov
1767 IF (bs_env%ri_rs%cutoff_radius_ri_rs > 0.0_dp)
THEN
1768 WRITE (u,
'(T2,A,F39.2,A)')
'Input: RI-RS integration sphere cutoff', &
1769 bs_env%ri_rs%cutoff_radius_ri_rs*
angstrom, Å
' '
1771 IF (bs_env%ri_rs%cutoff_radius_ri_ao > 0.0_dp)
THEN
1772 WRITE (u,
'(T2,A,F44.2,A)')
'Input: AO grid hard cutoff radius', &
1773 bs_env%ri_rs%cutoff_radius_ri_ao*
angstrom, Å
' '
1775 WRITE (u,
'(T2,A,I40)')
'Input: MPI ranks per atom in Z_lP solve', &
1776 bs_env%ri_rs%n_procs_per_atom_z_lp
1777 WRITE (u,
'(T2,A,L43)') χ
'Input: Keep sparsity in /G/W panels', &
1778 bs_env%ri_rs%keep_sparsity_rirs
1779 IF (bs_env%ri_rs%cutoff_radius_v_w > 0.0_dp)
THEN
1780 WRITE (u,
'(T2,A,F43.2,A)')
'Input: G/W panel truncation radius', &
1781 bs_env%ri_rs%cutoff_radius_v_w*
angstrom, Å
' '
1783 IF (bs_env%ri_rs%cutoff_radius_g_w > 0.0_dp)
THEN
1784 WRITE (u,
'(T2,A,F40.2,A)')
'Input: G/W operator truncation radius', &
1785 bs_env%ri_rs%cutoff_radius_g_w*
angstrom, Å
' '
1787 WRITE (u,
'(A)')
' '
1791 CALL timestop(handle)
1793 END SUBROUTINE print_header_and_input_parameters
1800 SUBROUTINE compute_v_xc(qs_env, bs_env)
1804 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_V_xc'
1806 INTEGER :: handle, img, ispin, myfun, nimages
1807 LOGICAL :: hf_present
1808 REAL(kind=
dp) :: energy_ex, energy_exc, energy_total, &
1810 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: mat_ks_without_v_xc
1811 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks_kp
1816 CALL timeset(routinen, handle)
1818 CALL get_qs_env(qs_env, input=input, energy=energy, dft_control=dft_control)
1821 nimages = dft_control%nimages
1822 dft_control%nimages = bs_env%nimages_scf
1830 hf_present = .false.
1831 IF (
ASSOCIATED(hf_section))
THEN
1834 IF (hf_present)
THEN
1841 energy_total = energy%total
1842 energy_exc = energy%exc
1843 energy_ex = energy%ex
1845 SELECT CASE (bs_env%small_cell_full_kp_or_large_cell_Gamma)
1848 NULLIFY (mat_ks_without_v_xc)
1851 DO ispin = 1, bs_env%n_spin
1852 ALLOCATE (mat_ks_without_v_xc(ispin)%matrix)
1853 IF (hf_present)
THEN
1854 CALL dbcsr_create(mat_ks_without_v_xc(ispin)%matrix, template=bs_env%mat_ao_ao%matrix, &
1855 matrix_type=dbcsr_type_symmetric)
1857 CALL dbcsr_create(mat_ks_without_v_xc(ispin)%matrix, template=bs_env%mat_ao_ao%matrix)
1863 ext_ks_matrix=mat_ks_without_v_xc)
1865 DO ispin = 1, bs_env%n_spin
1867 CALL cp_fm_create(bs_env%fm_V_xc_Gamma(ispin), bs_env%fm_s_Gamma%matrix_struct)
1868 CALL copy_dbcsr_to_fm(mat_ks_without_v_xc(ispin)%matrix, bs_env%fm_V_xc_Gamma(ispin))
1872 beta=1.0_dp, matrix_b=bs_env%fm_ks_Gamma(ispin))
1881 CALL get_qs_env(qs_env=qs_env, matrix_ks_kp=matrix_ks_kp)
1883 ALLOCATE (bs_env%fm_V_xc_R(dft_control%nimages, bs_env%n_spin))
1884 DO ispin = 1, bs_env%n_spin
1885 DO img = 1, dft_control%nimages
1887 CALL copy_dbcsr_to_fm(matrix_ks_kp(ispin, img)%matrix, bs_env%fm_work_mo(1))
1888 CALL cp_fm_create(bs_env%fm_V_xc_R(img, ispin), bs_env%fm_work_mo(1)%matrix_struct, &
1892 beta=1.0_dp, matrix_b=bs_env%fm_work_mo(1))
1899 energy%total = energy_total
1900 energy%exc = energy_exc
1901 energy%ex = energy_ex
1904 dft_control%nimages = nimages
1909 IF (hf_present)
THEN
1917 DO ispin = 1, bs_env%n_spin
1918 DO img = 1, dft_control%nimages
1920 CALL copy_dbcsr_to_fm(matrix_ks_kp(ispin, img)%matrix, bs_env%fm_work_mo(1))
1923 beta=1.0_dp, matrix_b=bs_env%fm_work_mo(1))
1928 CALL timestop(handle)
1930 END SUBROUTINE compute_v_xc
1936 SUBROUTINE setup_time_and_frequency_minimax_grid(bs_env)
1939 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_time_and_frequency_minimax_grid'
1941 INTEGER :: handle, homo, i_w, ierr, ispin, j_w, &
1942 n_mo, num_time_freq_points, u
1943 REAL(kind=
dp) :: e_max, e_max_ispin, e_min, e_min_ispin, &
1944 e_range, max_error_min
1945 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: points_and_weights
1947 CALL timeset(routinen, handle)
1950 num_time_freq_points = bs_env%num_time_freq_points
1952 ALLOCATE (bs_env%imag_freq_points(num_time_freq_points))
1953 ALLOCATE (bs_env%imag_time_points(num_time_freq_points))
1954 ALLOCATE (bs_env%imag_time_weights_freq_zero(num_time_freq_points))
1955 ALLOCATE (bs_env%weights_cos_t_to_w(num_time_freq_points, num_time_freq_points))
1956 ALLOCATE (bs_env%weights_cos_w_to_t(num_time_freq_points, num_time_freq_points))
1957 ALLOCATE (bs_env%weights_sin_t_to_w(num_time_freq_points, num_time_freq_points))
1962 DO ispin = 1, bs_env%n_spin
1963 homo = bs_env%n_occ(ispin)
1964 SELECT CASE (bs_env%small_cell_full_kp_or_large_cell_Gamma)
1966 e_min_ispin = bs_env%eigenval_scf_Gamma(homo + 1, ispin) - &
1967 bs_env%eigenval_scf_Gamma(homo, ispin)
1968 e_max_ispin = bs_env%eigenval_scf_Gamma(n_mo, ispin) - &
1969 bs_env%eigenval_scf_Gamma(1, ispin)
1971 e_min_ispin = minval(bs_env%eigenval_scf(homo + 1, :, ispin)) - &
1972 maxval(bs_env%eigenval_scf(homo, :, ispin))
1973 e_max_ispin = maxval(bs_env%eigenval_scf(n_mo, :, ispin)) - &
1974 minval(bs_env%eigenval_scf(1, :, ispin))
1976 e_min = min(e_min, e_min_ispin)
1977 e_max = max(e_max, e_max_ispin)
1982 IF (bs_env%n_spin > 1)
THEN
1983 CALL cp_hint(__location__, &
1984 "Open-shell GW uses one minimax grid spanning [min gap, max span] across both "// &
1985 "spin channels; raise NUM_TIME_FREQ_POINTS if QP convergence is marginal for "// &
1986 "strongly spin-asymmetric systems.")
1989 e_range = e_max/e_min
1991 ALLOCATE (points_and_weights(2*num_time_freq_points))
1994 IF (num_time_freq_points <= 20)
THEN
2002 bs_env%imag_freq_points(:) = points_and_weights(1:num_time_freq_points)*e_min
2005 bs_env%num_freq_points_fit = 0
2006 DO i_w = 1, num_time_freq_points
2007 IF (bs_env%imag_freq_points(i_w) < bs_env%freq_max_fit)
THEN
2008 bs_env%num_freq_points_fit = bs_env%num_freq_points_fit + 1
2013 ALLOCATE (bs_env%imag_freq_points_fit(bs_env%num_freq_points_fit))
2015 DO i_w = 1, num_time_freq_points
2016 IF (bs_env%imag_freq_points(i_w) < bs_env%freq_max_fit)
THEN
2018 bs_env%imag_freq_points_fit(j_w) = bs_env%imag_freq_points(i_w)
2024 IF (bs_env%num_freq_points_fit < bs_env%nparam_pade)
THEN
2025 bs_env%nparam_pade = bs_env%num_freq_points_fit
2029 IF (num_time_freq_points <= 20)
THEN
2035 bs_env%imag_time_points(:) = points_and_weights(1:num_time_freq_points)/(2.0_dp*e_min)
2036 bs_env%imag_time_weights_freq_zero(:) = points_and_weights(num_time_freq_points + 1:)/(e_min)
2038 DEALLOCATE (points_and_weights)
2042 WRITE (u,
'(T2,A)')
''
2043 WRITE (u,
'(T2,A,F55.2)')
'SCF direct band gap (eV)', e_min*
evolt
2044 WRITE (u,
'(T2,A,F53.2)')
'Max. SCF eigval diff. (eV)', e_max*
evolt
2045 WRITE (u,
'(T2,A,F55.2)')
'E-Range for minimax grid', e_range
2046 WRITE (u,
'(T2,A,I27)') é
'Number of Pad parameters for analytic continuation:', &
2048 WRITE (u,
'(T2,A)')
''
2058 bs_env%imag_time_points, &
2059 bs_env%weights_cos_t_to_w, &
2060 bs_env%imag_freq_points, &
2061 e_min, e_max, max_error_min, &
2062 bs_env%num_points_per_magnitude, &
2063 bs_env%regularization_minimax)
2067 bs_env%imag_time_points, &
2068 bs_env%weights_cos_w_to_t, &
2069 bs_env%imag_freq_points, &
2070 e_min, e_max, max_error_min, &
2071 bs_env%num_points_per_magnitude, &
2072 bs_env%regularization_minimax)
2076 bs_env%imag_time_points, &
2077 bs_env%weights_sin_t_to_w, &
2078 bs_env%imag_freq_points, &
2079 e_min, e_max, max_error_min, &
2080 bs_env%num_points_per_magnitude, &
2081 bs_env%regularization_minimax)
2083 CALL timestop(handle)
2085 END SUBROUTINE setup_time_and_frequency_minimax_grid
2092 SUBROUTINE setup_cells_3c(qs_env, bs_env)
2097 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_cells_3c'
2099 INTEGER :: atom_i, atom_j, atom_k, block_count, handle, i, i_cell_x, i_cell_x_max, &
2100 i_cell_x_min, i_size, ikind, img, j, j_cell, j_cell_max, j_cell_y, j_cell_y_max, &
2101 j_cell_y_min, j_size, k_cell, k_cell_max, k_cell_z, k_cell_z_max, k_cell_z_min, k_size, &
2102 nimage_pairs_3c, nimages_3c, nimages_3c_max, nkind, u
2103 INTEGER(KIND=int_8) :: mem_occ_per_proc
2104 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: kind_of, n_other_3c_images_max
2105 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: index_to_cell_3c_max, nblocks_3c_max
2106 INTEGER,
DIMENSION(3) :: cell_index, n_max
2107 REAL(kind=
dp) :: avail_mem_per_proc_gb, cell_dist, cell_radius_3c, dij, dik, djk, eps, &
2108 exp_min_ao, exp_min_ri, frobenius_norm, mem_3c_gb, mem_occ_per_proc_gb, radius_ao, &
2109 radius_ao_product, radius_ri
2110 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: exp_ao_kind, exp_ri_kind, &
2112 radius_ao_product_kind, radius_ri_kind
2113 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: int_3c
2114 REAL(kind=
dp),
DIMENSION(3) :: rij, rik, rjk, vec_cell_j, vec_cell_k
2115 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: exp_ao, exp_ri
2120 CALL timeset(routinen, handle)
2122 CALL get_qs_env(qs_env, nkind=nkind, atomic_kind_set=atomic_kind_set, particle_set=particle_set, cell=cell)
2124 ALLOCATE (exp_ao_kind(nkind), exp_ri_kind(nkind), radius_ao_kind(nkind), &
2125 radius_ao_product_kind(nkind), radius_ri_kind(nkind))
2127 exp_min_ri = 10.0_dp
2128 exp_min_ao = 10.0_dp
2129 exp_ri_kind = 10.0_dp
2130 exp_ao_kind = 10.0_dp
2132 eps = bs_env%eps_filter*bs_env%heuristic_filter_factor
2141 DO i = 1,
SIZE(exp_ri, 1)
2142 DO j = 1,
SIZE(exp_ri, 2)
2143 IF (exp_ri(i, j) < exp_min_ri .AND. exp_ri(i, j) > 1e-3_dp) exp_min_ri = exp_ri(i, j)
2144 IF (exp_ri(i, j) < exp_ri_kind(ikind) .AND. exp_ri(i, j) > 1e-3_dp)
THEN
2145 exp_ri_kind(ikind) = exp_ri(i, j)
2149 DO i = 1,
SIZE(exp_ao, 1)
2150 DO j = 1,
SIZE(exp_ao, 2)
2151 IF (exp_ao(i, j) < exp_min_ao .AND. exp_ao(i, j) > 1e-3_dp) exp_min_ao = exp_ao(i, j)
2152 IF (exp_ao(i, j) < exp_ao_kind(ikind) .AND. exp_ao(i, j) > 1e-3_dp)
THEN
2153 exp_ao_kind(ikind) = exp_ao(i, j)
2157 radius_ao_kind(ikind) = sqrt(-log(eps)/exp_ao_kind(ikind))
2158 radius_ao_product_kind(ikind) = sqrt(-log(eps)/(2.0_dp*exp_ao_kind(ikind)))
2159 radius_ri_kind(ikind) = sqrt(-log(eps)/exp_ri_kind(ikind))
2162 radius_ao = sqrt(-log(eps)/exp_min_ao)
2163 radius_ao_product = sqrt(-log(eps)/(2.0_dp*exp_min_ao))
2164 radius_ri = sqrt(-log(eps)/exp_min_ri)
2169 cell_radius_3c = radius_ao_product + radius_ri + bs_env%ri_metric%cutoff_radius
2171 n_max(1:3) = bs_env%periodic(1:3)*30
2182 DO i_cell_x = -n_max(1), n_max(1)
2183 DO j_cell_y = -n_max(2), n_max(2)
2184 DO k_cell_z = -n_max(3), n_max(3)
2186 cell_index(1:3) = [i_cell_x, j_cell_y, k_cell_z]
2188 CALL get_cell_dist(cell_index, bs_env%hmat, cell_dist)
2190 IF (cell_dist < cell_radius_3c)
THEN
2191 nimages_3c_max = nimages_3c_max + 1
2192 i_cell_x_min = min(i_cell_x_min, i_cell_x)
2193 i_cell_x_max = max(i_cell_x_max, i_cell_x)
2194 j_cell_y_min = min(j_cell_y_min, j_cell_y)
2195 j_cell_y_max = max(j_cell_y_max, j_cell_y)
2196 k_cell_z_min = min(k_cell_z_min, k_cell_z)
2197 k_cell_z_max = max(k_cell_z_max, k_cell_z)
2206 ALLOCATE (index_to_cell_3c_max(3, nimages_3c_max))
2209 DO i_cell_x = -n_max(1), n_max(1)
2210 DO j_cell_y = -n_max(2), n_max(2)
2211 DO k_cell_z = -n_max(3), n_max(3)
2213 cell_index(1:3) = [i_cell_x, j_cell_y, k_cell_z]
2215 CALL get_cell_dist(cell_index, bs_env%hmat, cell_dist)
2217 IF (cell_dist < cell_radius_3c)
THEN
2219 index_to_cell_3c_max(1:3, img) = cell_index(1:3)
2227 ALLOCATE (nblocks_3c_max(nimages_3c_max, nimages_3c_max))
2228 nblocks_3c_max(:, :) = 0
2231 DO j_cell = 1, nimages_3c_max
2232 DO k_cell = 1, nimages_3c_max
2234 DO atom_j = 1, bs_env%n_atom
2235 DO atom_k = 1, bs_env%n_atom
2236 DO atom_i = 1, bs_env%n_atom
2238 block_count = block_count + 1
2239 IF (
modulo(block_count, bs_env%para_env%num_pe) /= bs_env%para_env%mepos) cycle
2241 CALL scaled_to_real(vec_cell_j, real(index_to_cell_3c_max(1:3, j_cell), kind=
dp), cell)
2242 CALL scaled_to_real(vec_cell_k, real(index_to_cell_3c_max(1:3, k_cell), kind=
dp), cell)
2244 rij =
pbc(particle_set(atom_j)%r(:), cell) -
pbc(particle_set(atom_i)%r(:), cell) + vec_cell_j(:)
2245 rjk =
pbc(particle_set(atom_k)%r(:), cell) -
pbc(particle_set(atom_j)%r(:), cell) &
2246 + vec_cell_k(:) - vec_cell_j(:)
2247 rik(:) = rij(:) + rjk(:)
2251 IF (djk > radius_ao_kind(kind_of(atom_j)) + radius_ao_kind(kind_of(atom_k))) cycle
2252 IF (dij > radius_ao_kind(kind_of(atom_j)) + radius_ri_kind(kind_of(atom_i)) &
2253 + bs_env%ri_metric%cutoff_radius) cycle
2254 IF (dik > radius_ri_kind(kind_of(atom_i)) + radius_ao_kind(kind_of(atom_k)) &
2255 + bs_env%ri_metric%cutoff_radius) cycle
2257 j_size = bs_env%i_ao_end_from_atom(atom_j) - bs_env%i_ao_start_from_atom(atom_j) + 1
2258 k_size = bs_env%i_ao_end_from_atom(atom_k) - bs_env%i_ao_start_from_atom(atom_k) + 1
2259 i_size = bs_env%i_RI_end_from_atom(atom_i) - bs_env%i_RI_start_from_atom(atom_i) + 1
2261 ALLOCATE (int_3c(j_size, k_size, i_size))
2266 basis_j=bs_env%basis_set_AO, &
2267 basis_k=bs_env%basis_set_AO, &
2268 basis_i=bs_env%basis_set_RI, &
2269 cell_j=index_to_cell_3c_max(1:3, j_cell), &
2270 cell_k=index_to_cell_3c_max(1:3, k_cell), &
2271 atom_k=atom_k, atom_j=atom_j, atom_i=atom_i)
2273 frobenius_norm = sqrt(sum(int_3c(:, :, :)**2))
2279 IF (frobenius_norm > eps)
THEN
2280 nblocks_3c_max(j_cell, k_cell) = nblocks_3c_max(j_cell, k_cell) + 1
2290 CALL bs_env%para_env%sum(nblocks_3c_max)
2292 ALLOCATE (n_other_3c_images_max(nimages_3c_max))
2293 n_other_3c_images_max(:) = 0
2298 DO j_cell = 1, nimages_3c_max
2299 DO k_cell = 1, nimages_3c_max
2300 IF (nblocks_3c_max(j_cell, k_cell) > 0)
THEN
2301 n_other_3c_images_max(j_cell) = n_other_3c_images_max(j_cell) + 1
2302 nimage_pairs_3c = nimage_pairs_3c + 1
2306 IF (n_other_3c_images_max(j_cell) > 0) nimages_3c = nimages_3c + 1
2310 bs_env%nimages_3c = nimages_3c
2311 ALLOCATE (bs_env%index_to_cell_3c(3, nimages_3c))
2312 ALLOCATE (bs_env%cell_to_index_3c(i_cell_x_min:i_cell_x_max, &
2313 j_cell_y_min:j_cell_y_max, &
2314 k_cell_z_min:k_cell_z_max))
2315 bs_env%cell_to_index_3c(:, :, :) = -1
2317 ALLOCATE (bs_env%nblocks_3c(nimages_3c, nimages_3c))
2318 bs_env%nblocks_3c(nimages_3c, nimages_3c) = 0
2321 DO j_cell_max = 1, nimages_3c_max
2322 IF (n_other_3c_images_max(j_cell_max) == 0) cycle
2324 cell_index(1:3) = index_to_cell_3c_max(1:3, j_cell_max)
2325 bs_env%index_to_cell_3c(1:3, j_cell) = cell_index(1:3)
2326 bs_env%cell_to_index_3c(cell_index(1), cell_index(2), cell_index(3)) = j_cell
2329 DO k_cell_max = 1, nimages_3c_max
2330 IF (n_other_3c_images_max(k_cell_max) == 0) cycle
2333 bs_env%nblocks_3c(j_cell, k_cell) = nblocks_3c_max(j_cell_max, k_cell_max)
2339 mem_3c_gb = real(bs_env%n_RI, kind=
dp)*real(bs_env%n_ao, kind=
dp)**2 &
2340 *real(nimage_pairs_3c, kind=
dp)*8e-9_dp
2343 CALL bs_env%para_env%max(mem_occ_per_proc)
2345 mem_occ_per_proc_gb = real(mem_occ_per_proc, kind=
dp)/1.0e9_dp
2348 avail_mem_per_proc_gb = bs_env%input_memory_per_proc_GB - mem_occ_per_proc_gb
2351 bs_env%group_size_tensor = max(int(mem_3c_gb/avail_mem_per_proc_gb + 1.0_dp), 1)
2356 WRITE (u, fmt=
"(T2,A,F52.1,A)")
"Radius of atomic orbitals", radius_ao*
angstrom, Å
" "
2357 WRITE (u, fmt=
"(T2,A,F55.1,A)")
"Radius of RI functions", radius_ri*
angstrom, Å
" "
2358 WRITE (u, fmt=
"(T2,A,I47)")
"Number of cells for 3c integrals", nimages_3c
2359 WRITE (u, fmt=
"(T2,A,I42)")
"Number of cell pairs for 3c integrals", nimage_pairs_3c
2360 WRITE (u,
'(T2,A)')
''
2361 WRITE (u,
'(T2,A,F37.1,A)')
'Input: Available memory per MPI process', &
2362 bs_env%input_memory_per_proc_GB,
' GB'
2363 WRITE (u,
'(T2,A,F35.1,A)')
'Used memory per MPI process before GW run', &
2364 mem_occ_per_proc_gb,
' GB'
2365 WRITE (u,
'(T2,A,F44.1,A)')
'Memory of three-center integrals', mem_3c_gb,
' GB'
2368 CALL timestop(handle)
2370 END SUBROUTINE setup_cells_3c
2382 SUBROUTINE sum_two_r_grids(index_to_cell_1, index_to_cell_2, nimages_1, nimages_2, &
2383 index_to_cell, cell_to_index, nimages)
2385 INTEGER,
DIMENSION(:, :) :: index_to_cell_1, index_to_cell_2
2386 INTEGER :: nimages_1, nimages_2
2387 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: index_to_cell
2388 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
2391 CHARACTER(LEN=*),
PARAMETER :: routinen =
'sum_two_R_grids'
2393 INTEGER :: handle, i_dim, img_1, img_2, nimages_max
2394 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: index_to_cell_tmp
2395 INTEGER,
DIMENSION(3) :: cell_1, cell_2, r, r_max, r_min
2397 CALL timeset(routinen, handle)
2400 r_min(i_dim) = minval(index_to_cell_1(i_dim, :)) + minval(index_to_cell_2(i_dim, :))
2401 r_max(i_dim) = maxval(index_to_cell_1(i_dim, :)) + maxval(index_to_cell_2(i_dim, :))
2404 nimages_max = (r_max(1) - r_min(1) + 1)*(r_max(2) - r_min(2) + 1)*(r_max(3) - r_min(3) + 1)
2406 ALLOCATE (index_to_cell_tmp(3, nimages_max))
2407 index_to_cell_tmp(:, :) = -1
2409 ALLOCATE (cell_to_index(r_min(1):r_max(1), r_min(2):r_max(2), r_min(3):r_max(3)))
2410 cell_to_index(:, :, :) = -1
2414 DO img_1 = 1, nimages_1
2416 DO img_2 = 1, nimages_2
2418 cell_1(1:3) = index_to_cell_1(1:3, img_1)
2419 cell_2(1:3) = index_to_cell_2(1:3, img_2)
2421 r(1:3) = cell_1(1:3) + cell_2(1:3)
2424 IF (cell_to_index(r(1), r(2), r(3)) == -1)
THEN
2426 nimages = nimages + 1
2427 cell_to_index(r(1), r(2), r(3)) = nimages
2428 index_to_cell_tmp(1:3, nimages) = r(1:3)
2436 ALLOCATE (index_to_cell(3, nimages))
2437 index_to_cell(:, :) = index_to_cell_tmp(1:3, 1:nimages)
2439 CALL timestop(handle)
2441 END SUBROUTINE sum_two_r_grids
2448 SUBROUTINE compute_3c_integrals(qs_env, bs_env)
2453 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_3c_integrals'
2455 INTEGER :: handle, j_cell, k_cell, nimages_3c
2457 CALL timeset(routinen, handle)
2459 nimages_3c = bs_env%nimages_3c
2460 ALLOCATE (bs_env%t_3c_int(nimages_3c, nimages_3c))
2461 DO j_cell = 1, nimages_3c
2462 DO k_cell = 1, nimages_3c
2463 CALL dbt_create(bs_env%t_RI_AO__AO, bs_env%t_3c_int(j_cell, k_cell))
2468 bs_env%eps_filter, &
2471 int_eps=bs_env%eps_filter*0.05_dp, &
2472 basis_i=bs_env%basis_set_RI, &
2473 basis_j=bs_env%basis_set_AO, &
2474 basis_k=bs_env%basis_set_AO, &
2475 potential_parameter=bs_env%ri_metric, &
2476 desymmetrize=.false., do_kpoints=.true., cell_sym=.true., &
2477 cell_to_index_ext=bs_env%cell_to_index_3c)
2479 CALL bs_env%para_env%sync()
2481 CALL timestop(handle)
2483 END SUBROUTINE compute_3c_integrals
2491 SUBROUTINE get_cell_dist(cell_index, hmat, cell_dist)
2493 INTEGER,
DIMENSION(3) :: cell_index
2494 REAL(kind=
dp) :: hmat(3, 3), cell_dist
2496 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_cell_dist'
2498 INTEGER :: handle, i_dim
2499 INTEGER,
DIMENSION(3) :: cell_index_adj
2500 REAL(kind=
dp) :: cell_dist_3(3)
2502 CALL timeset(routinen, handle)
2507 IF (cell_index(i_dim) > 0) cell_index_adj(i_dim) = cell_index(i_dim) - 1
2508 IF (cell_index(i_dim) < 0) cell_index_adj(i_dim) = cell_index(i_dim) + 1
2509 IF (cell_index(i_dim) == 0) cell_index_adj(i_dim) = cell_index(i_dim)
2512 cell_dist_3(1:3) = matmul(hmat, real(cell_index_adj, kind=
dp))
2514 cell_dist = sqrt(abs(sum(cell_dist_3(1:3)**2)))
2516 CALL timestop(handle)
2518 END SUBROUTINE get_cell_dist
2527 SUBROUTINE setup_kpoints_scf_desymm(qs_env, bs_env, kpoints, do_print)
2532 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_kpoints_scf_desymm'
2534 INTEGER :: handle, i_cell_x, i_dim, img, j_cell_y, &
2535 k_cell_z, nimages, nkp, u
2536 INTEGER,
DIMENSION(3) :: cell_grid, cixd, nkp_grid
2541 CALL timeset(routinen, handle)
2546 CALL get_qs_env(qs_env=qs_env, kpoints=kpoints_scf)
2548 nkp_grid(1:3) = kpoints_scf%nkp_grid(1:3)
2549 nkp = nkp_grid(1)*nkp_grid(2)*nkp_grid(3)
2553 IF (bs_env%periodic(i_dim) == 1)
THEN
2554 cpassert(nkp_grid(i_dim) > 1)
2558 kpoints%kp_scheme =
"GENERAL"
2559 kpoints%nkp_grid(1:3) = nkp_grid(1:3)
2561 bs_env%nkp_scf_desymm = nkp
2563 ALLOCATE (kpoints%xkp(1:3, nkp))
2566 ALLOCATE (kpoints%wkp(nkp))
2567 kpoints%wkp(:) = 1.0_dp/real(nkp, kind=
dp)
2571 cell_grid(1:3) = nkp_grid(1:3) -
modulo(nkp_grid(1:3) + 1, 2)
2573 cixd(1:3) = cell_grid(1:3)/2
2575 nimages = cell_grid(1)*cell_grid(2)*cell_grid(3)
2577 bs_env%nimages_scf_desymm = nimages
2579 ALLOCATE (kpoints%cell_to_index(-cixd(1):cixd(1), -cixd(2):cixd(2), -cixd(3):cixd(3)))
2580 ALLOCATE (kpoints%index_to_cell(3, nimages))
2583 DO i_cell_x = -cixd(1), cixd(1)
2584 DO j_cell_y = -cixd(2), cixd(2)
2585 DO k_cell_z = -cixd(3), cixd(3)
2587 kpoints%cell_to_index(i_cell_x, j_cell_y, k_cell_z) = img
2588 kpoints%index_to_cell(1:3, img) = [i_cell_x, j_cell_y, k_cell_z]
2594 IF (u > 0 .AND. do_print)
THEN
2595 WRITE (u, fmt=
"(T2,A,I49)") χΣ
"Number of cells for G, , W, ", nimages
2598 CALL timestop(handle)
2600 END SUBROUTINE setup_kpoints_scf_desymm
2606 SUBROUTINE setup_cells_delta_r(bs_env)
2610 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_cells_Delta_R'
2614 CALL timeset(routinen, handle)
2619 CALL sum_two_r_grids(bs_env%index_to_cell_3c, &
2620 bs_env%index_to_cell_3c, &
2621 bs_env%nimages_3c, bs_env%nimages_3c, &
2622 bs_env%index_to_cell_Delta_R, &
2623 bs_env%cell_to_index_Delta_R, &
2624 bs_env%nimages_Delta_R)
2626 IF (bs_env%unit_nr > 0)
THEN
2627 WRITE (bs_env%unit_nr, fmt=
"(T2,A,I61)") Δ
"Number of cells R", bs_env%nimages_Delta_R
2630 CALL timestop(handle)
2632 END SUBROUTINE setup_cells_delta_r
2638 SUBROUTINE setup_parallelization_delta_r(bs_env)
2642 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_parallelization_Delta_R'
2644 INTEGER :: handle, i_cell_delta_r, i_task_local, &
2646 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: i_cell_delta_r_group, &
2647 n_tensor_ops_delta_r
2649 CALL timeset(routinen, handle)
2651 CALL compute_n_tensor_ops_delta_r(bs_env, n_tensor_ops_delta_r)
2653 CALL compute_delta_r_dist(bs_env, n_tensor_ops_delta_r, i_cell_delta_r_group, n_tasks_local)
2655 bs_env%n_tasks_Delta_R_local = n_tasks_local
2657 ALLOCATE (bs_env%task_Delta_R(n_tasks_local))
2660 DO i_cell_delta_r = 1, bs_env%nimages_Delta_R
2662 IF (i_cell_delta_r_group(i_cell_delta_r) /= bs_env%tensor_group_color) cycle
2664 i_task_local = i_task_local + 1
2666 bs_env%task_Delta_R(i_task_local) = i_cell_delta_r
2670 ALLOCATE (bs_env%skip_DR_chi(n_tasks_local))
2671 bs_env%skip_DR_chi(:) = .false.
2672 ALLOCATE (bs_env%skip_DR_Sigma(n_tasks_local))
2673 bs_env%skip_DR_Sigma(:) = .false.
2675 CALL allocate_skip_3xr(bs_env%skip_DR_R12_S_Goccx3c_chi, bs_env)
2676 CALL allocate_skip_3xr(bs_env%skip_DR_R12_S_Gvirx3c_chi, bs_env)
2677 CALL allocate_skip_3xr(bs_env%skip_DR_R_R2_MxM_chi, bs_env)
2679 CALL allocate_skip_3xr(bs_env%skip_DR_R1_S2_Gx3c_Sigma, bs_env)
2680 CALL allocate_skip_3xr(bs_env%skip_DR_R1_R_MxM_Sigma, bs_env)
2682 CALL timestop(handle)
2684 END SUBROUTINE setup_parallelization_delta_r
2691 SUBROUTINE allocate_skip_3xr(skip, bs_env)
2692 LOGICAL,
ALLOCATABLE,
DIMENSION(:, :, :) :: skip
2695 CHARACTER(LEN=*),
PARAMETER :: routinen =
'allocate_skip_3xR'
2699 CALL timeset(routinen, handle)
2701 ALLOCATE (skip(bs_env%n_tasks_Delta_R_local, bs_env%nimages_3c, bs_env%nimages_scf_desymm))
2702 skip(:, :, :) = .false.
2704 CALL timestop(handle)
2706 END SUBROUTINE allocate_skip_3xr
2715 SUBROUTINE compute_delta_r_dist(bs_env, n_tensor_ops_Delta_R, i_cell_Delta_R_group, n_tasks_local)
2717 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: n_tensor_ops_delta_r, &
2718 i_cell_delta_r_group
2719 INTEGER :: n_tasks_local
2721 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_Delta_R_dist'
2723 INTEGER :: handle, i_delta_r_max_op, i_group_min, &
2725 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: n_tensor_ops_delta_r_in_group
2727 CALL timeset(routinen, handle)
2729 nimages_delta_r = bs_env%nimages_Delta_R
2733 IF (u > 0 .AND. nimages_delta_r < bs_env%num_tensor_groups)
THEN
2734 WRITE (u, fmt=
"(T2,A,I5,A,I5,A)")
"There are only ", nimages_delta_r, &
2735 " tasks to work on but there are ", bs_env%num_tensor_groups,
" groups."
2736 WRITE (u, fmt=
"(T2,A)")
"Please reduce the number of MPI processes."
2737 WRITE (u,
'(T2,A)')
''
2740 ALLOCATE (n_tensor_ops_delta_r_in_group(bs_env%num_tensor_groups))
2741 n_tensor_ops_delta_r_in_group(:) = 0
2742 ALLOCATE (i_cell_delta_r_group(nimages_delta_r))
2743 i_cell_delta_r_group(:) = -1
2747 DO WHILE (any(n_tensor_ops_delta_r(:) /= 0))
2750 i_delta_r_max_op = maxloc(n_tensor_ops_delta_r, 1)
2753 i_group_min = minloc(n_tensor_ops_delta_r_in_group, 1)
2756 i_cell_delta_r_group(i_delta_r_max_op) = i_group_min - 1
2757 n_tensor_ops_delta_r_in_group(i_group_min) = n_tensor_ops_delta_r_in_group(i_group_min) + &
2758 n_tensor_ops_delta_r(i_delta_r_max_op)
2761 n_tensor_ops_delta_r(i_delta_r_max_op) = 0
2763 IF (bs_env%tensor_group_color == i_group_min - 1) n_tasks_local = n_tasks_local + 1
2767 CALL timestop(handle)
2769 END SUBROUTINE compute_delta_r_dist
2776 SUBROUTINE compute_n_tensor_ops_delta_r(bs_env, n_tensor_ops_Delta_R)
2778 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: n_tensor_ops_delta_r
2780 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_n_tensor_ops_Delta_R'
2782 INTEGER :: handle, i_cell_delta_r, i_cell_r, i_cell_r1, i_cell_r1_minus_r, i_cell_r2, &
2783 i_cell_r2_m_r1, i_cell_s1, i_cell_s1_m_r1_p_r2, i_cell_s1_minus_r, i_cell_s2, &
2785 INTEGER,
DIMENSION(3) :: cell_dr, cell_m_r1, cell_r, cell_r1, cell_r1_minus_r, cell_r2, &
2786 cell_r2_m_r1, cell_s1, cell_s1_m_r2_p_r1, cell_s1_minus_r, cell_s1_p_s2_m_r1, cell_s2
2787 LOGICAL :: cell_found
2789 CALL timeset(routinen, handle)
2791 nimages_delta_r = bs_env%nimages_Delta_R
2793 ALLOCATE (n_tensor_ops_delta_r(nimages_delta_r))
2794 n_tensor_ops_delta_r(:) = 0
2797 DO i_cell_delta_r = 1, nimages_delta_r
2799 IF (
modulo(i_cell_delta_r, bs_env%num_tensor_groups) /= bs_env%tensor_group_color) cycle
2801 DO i_cell_r1 = 1, bs_env%nimages_3c
2803 cell_r1(1:3) = bs_env%index_to_cell_3c(1:3, i_cell_r1)
2804 cell_dr(1:3) = bs_env%index_to_cell_Delta_R(1:3, i_cell_delta_r)
2807 CALL add_r(cell_r1, cell_dr, bs_env%index_to_cell_3c, cell_s1, &
2808 cell_found, bs_env%cell_to_index_3c, i_cell_s1)
2809 IF (.NOT. cell_found) cycle
2811 DO i_cell_r2 = 1, bs_env%nimages_scf_desymm
2813 cell_r2(1:3) = bs_env%kpoints_scf_desymm%index_to_cell(1:3, i_cell_r2)
2816 CALL add_r(cell_r2, -cell_r1, bs_env%index_to_cell_3c, cell_r2_m_r1, &
2817 cell_found, bs_env%cell_to_index_3c, i_cell_r2_m_r1)
2818 IF (.NOT. cell_found) cycle
2821 CALL add_r(cell_s1, cell_r2_m_r1, bs_env%index_to_cell_3c, cell_s1_m_r2_p_r1, &
2822 cell_found, bs_env%cell_to_index_3c, i_cell_s1_m_r1_p_r2)
2823 IF (.NOT. cell_found) cycle
2825 n_tensor_ops_delta_r(i_cell_delta_r) = n_tensor_ops_delta_r(i_cell_delta_r) + 1
2829 DO i_cell_s2 = 1, bs_env%nimages_scf_desymm
2831 cell_s2(1:3) = bs_env%kpoints_scf_desymm%index_to_cell(1:3, i_cell_s2)
2832 cell_m_r1(1:3) = -cell_r1(1:3)
2833 cell_s1_p_s2_m_r1(1:3) = cell_s1(1:3) + cell_s2(1:3) - cell_r1(1:3)
2836 IF (.NOT. cell_found) cycle
2839 IF (.NOT. cell_found) cycle
2843 DO i_cell_r = 1, bs_env%nimages_scf_desymm
2845 cell_r = bs_env%kpoints_scf_desymm%index_to_cell(1:3, i_cell_r)
2848 CALL add_r(cell_r1, -cell_r, bs_env%index_to_cell_3c, cell_r1_minus_r, &
2849 cell_found, bs_env%cell_to_index_3c, i_cell_r1_minus_r)
2850 IF (.NOT. cell_found) cycle
2853 CALL add_r(cell_s1, -cell_r, bs_env%index_to_cell_3c, cell_s1_minus_r, &
2854 cell_found, bs_env%cell_to_index_3c, i_cell_s1_minus_r)
2855 IF (.NOT. cell_found) cycle
2863 CALL bs_env%para_env%sum(n_tensor_ops_delta_r)
2865 CALL timestop(handle)
2867 END SUBROUTINE compute_n_tensor_ops_delta_r
2879 SUBROUTINE add_r(cell_1, cell_2, index_to_cell, cell_1_plus_2, cell_found, &
2880 cell_to_index, i_cell_1_plus_2)
2882 INTEGER,
DIMENSION(3) :: cell_1, cell_2
2883 INTEGER,
DIMENSION(:, :) :: index_to_cell
2884 INTEGER,
DIMENSION(3) :: cell_1_plus_2
2885 LOGICAL :: cell_found
2886 INTEGER,
DIMENSION(:, :, :),
INTENT(IN), &
2887 OPTIONAL,
POINTER :: cell_to_index
2888 INTEGER,
INTENT(OUT),
OPTIONAL :: i_cell_1_plus_2
2890 CHARACTER(LEN=*),
PARAMETER :: routinen =
'add_R'
2894 CALL timeset(routinen, handle)
2896 cell_1_plus_2(1:3) = cell_1(1:3) + cell_2(1:3)
2900 IF (
PRESENT(i_cell_1_plus_2))
THEN
2901 IF (cell_found)
THEN
2902 cpassert(
PRESENT(cell_to_index))
2903 i_cell_1_plus_2 = cell_to_index(cell_1_plus_2(1), cell_1_plus_2(2), cell_1_plus_2(3))
2905 i_cell_1_plus_2 = -1000
2909 CALL timestop(handle)
2911 END SUBROUTINE add_r
2920 INTEGER,
DIMENSION(3) :: cell
2921 INTEGER,
DIMENSION(:, :) :: index_to_cell
2922 LOGICAL :: cell_found
2924 CHARACTER(LEN=*),
PARAMETER :: routinen =
'is_cell_in_index_to_cell'
2926 INTEGER :: handle, i_cell, nimg
2927 INTEGER,
DIMENSION(3) :: cell_i
2929 CALL timeset(routinen, handle)
2931 nimg =
SIZE(index_to_cell, 2)
2933 cell_found = .false.
2937 cell_i(1:3) = index_to_cell(1:3, i_cell)
2939 IF (cell_i(1) == cell(1) .AND. cell_i(2) == cell(2) .AND. cell_i(3) == cell(3))
THEN
2945 CALL timestop(handle)
2954 SUBROUTINE allocate_matrices_small_cell_full_kp(qs_env, bs_env)
2958 CHARACTER(LEN=*),
PARAMETER :: routinen =
'allocate_matrices_small_cell_full_kp'
2960 INTEGER :: handle, i_spin, i_t, img, n_spin, &
2961 nimages_scf, num_time_freq_points
2965 CALL timeset(routinen, handle)
2967 nimages_scf = bs_env%nimages_scf_desymm
2968 num_time_freq_points = bs_env%num_time_freq_points
2969 n_spin = bs_env%n_spin
2971 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
2973 ALLOCATE (bs_env%fm_G_S(nimages_scf))
2974 ALLOCATE (bs_env%fm_Sigma_x_R(nimages_scf))
2975 ALLOCATE (bs_env%fm_chi_R_t(nimages_scf, num_time_freq_points))
2976 ALLOCATE (bs_env%fm_MWM_R_t(nimages_scf, num_time_freq_points))
2977 ALLOCATE (bs_env%fm_Sigma_c_R_neg_tau(nimages_scf, num_time_freq_points, n_spin))
2978 ALLOCATE (bs_env%fm_Sigma_c_R_pos_tau(nimages_scf, num_time_freq_points, n_spin))
2979 DO img = 1, nimages_scf
2980 CALL cp_fm_create(bs_env%fm_G_S(img), bs_env%fm_work_mo(1)%matrix_struct)
2981 CALL cp_fm_create(bs_env%fm_Sigma_x_R(img), bs_env%fm_work_mo(1)%matrix_struct)
2982 DO i_t = 1, num_time_freq_points
2983 CALL cp_fm_create(bs_env%fm_chi_R_t(img, i_t), bs_env%fm_RI_RI%matrix_struct)
2984 CALL cp_fm_create(bs_env%fm_MWM_R_t(img, i_t), bs_env%fm_RI_RI%matrix_struct)
2986 DO i_spin = 1, n_spin
2987 CALL cp_fm_create(bs_env%fm_Sigma_c_R_neg_tau(img, i_t, i_spin), &
2988 bs_env%fm_work_mo(1)%matrix_struct)
2989 CALL cp_fm_create(bs_env%fm_Sigma_c_R_pos_tau(img, i_t, i_spin), &
2990 bs_env%fm_work_mo(1)%matrix_struct)
2991 CALL cp_fm_set_all(bs_env%fm_Sigma_c_R_neg_tau(img, i_t, i_spin), 0.0_dp)
2992 CALL cp_fm_set_all(bs_env%fm_Sigma_c_R_pos_tau(img, i_t, i_spin), 0.0_dp)
2997 CALL timestop(handle)
2999 END SUBROUTINE allocate_matrices_small_cell_full_kp
3006 SUBROUTINE trafo_v_xc_r_to_kp(qs_env, bs_env)
3010 CHARACTER(LEN=*),
PARAMETER :: routinen =
'trafo_V_xc_R_to_kp'
3012 INTEGER :: handle, ikp, img, ispin, n_ao
3013 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index_scf
3014 TYPE(
cp_cfm_type) :: cfm_mo_coeff, cfm_tmp, cfm_v_xc
3016 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_ks
3021 CALL timeset(routinen, handle)
3025 CALL get_qs_env(qs_env, matrix_ks_kp=matrix_ks, kpoints=kpoints_scf)
3028 CALL get_kpoint_info(kpoints_scf, sab_nl=sab_nl, cell_to_index=cell_to_index_scf)
3030 CALL cp_cfm_create(cfm_v_xc, bs_env%cfm_work_mo%matrix_struct)
3031 CALL cp_cfm_create(cfm_mo_coeff, bs_env%cfm_work_mo%matrix_struct)
3032 CALL cp_cfm_create(cfm_tmp, bs_env%cfm_work_mo%matrix_struct)
3033 CALL cp_fm_create(fm_v_xc_re, bs_env%cfm_work_mo%matrix_struct)
3035 DO img = 1, bs_env%nimages_scf
3036 DO ispin = 1, bs_env%n_spin
3038 CALL dbcsr_set(matrix_ks(ispin, img)%matrix, 0.0_dp)
3039 CALL copy_fm_to_dbcsr(bs_env%fm_V_xc_R(img, ispin), matrix_ks(ispin, img)%matrix)
3043 ALLOCATE (bs_env%v_xc_n(n_ao, bs_env%nkp_bs_and_DOS, bs_env%n_spin))
3045 DO ispin = 1, bs_env%n_spin
3046 DO ikp = 1, bs_env%nkp_bs_and_DOS
3049 CALL rsmat_to_kp(matrix_ks, ispin, bs_env%kpoints_DOS%xkp(1:3, ikp), &
3050 cell_to_index_scf, sab_nl, bs_env, cfm_v_xc)
3053 CALL cp_cfm_to_cfm(bs_env%cfm_mo_coeff_kp(ikp, ispin), cfm_mo_coeff)
3077 CALL timestop(handle)
3079 END SUBROUTINE trafo_v_xc_r_to_kp
3086 SUBROUTINE heuristic_ri_regularization(qs_env, bs_env)
3090 CHARACTER(LEN=*),
PARAMETER :: routinen =
'heuristic_RI_regularization'
3092 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: m
3093 INTEGER :: handle, ikp, ikp_local, n_ri, nkp, &
3095 REAL(kind=
dp) :: cond_nr, cond_nr_max, max_ev, &
3096 max_ev_ikp, min_ev, min_ev_ikp
3097 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: m_r
3099 CALL timeset(routinen, handle)
3102 CALL get_v_tr_r(m_r, bs_env%ri_metric, 0.0_dp, bs_env, qs_env)
3104 nkp = bs_env%nkp_chi_eps_W_orig_plus_extra
3110 IF (
modulo(ikp, bs_env%para_env%num_pe) /= bs_env%para_env%mepos) cycle
3111 nkp_local = nkp_local + 1
3114 ALLOCATE (m(n_ri, n_ri, nkp_local))
3117 cond_nr_max = 0.0_dp
3124 IF (
modulo(ikp, bs_env%para_env%num_pe) /= bs_env%para_env%mepos) cycle
3126 ikp_local = ikp_local + 1
3129 CALL rs_to_kp(m_r, m(:, :, ikp_local), &
3130 bs_env%kpoints_scf_desymm%index_to_cell, &
3131 bs_env%kpoints_chi_eps_W%xkp(1:3, ikp))
3134 CALL power(m(:, :, ikp_local), 1.0_dp, 0.0_dp, cond_nr, min_ev_ikp, max_ev_ikp)
3136 IF (cond_nr > cond_nr_max) cond_nr_max = cond_nr
3137 IF (max_ev_ikp > max_ev) max_ev = max_ev_ikp
3138 IF (min_ev_ikp < min_ev) min_ev = min_ev_ikp
3142 CALL bs_env%para_env%max(cond_nr_max)
3143 CALL bs_env%para_env%min(min_ev)
3144 CALL bs_env%para_env%max(max_ev)
3148 WRITE (u, fmt=
"(T2,A,ES34.1)")
"Min. abs. eigenvalue of RI metric matrix M(k)", min_ev
3149 WRITE (u, fmt=
"(T2,A,ES34.1)")
"Max. abs. eigenvalue of RI metric matrix M(k)", max_ev
3150 WRITE (u, fmt=
"(T2,A,ES50.1)")
"Max. condition number of M(k)", cond_nr_max
3153 CALL timestop(handle)
3155 END SUBROUTINE heuristic_ri_regularization
3165 SUBROUTINE get_v_tr_r(V_tr_R, pot_type, regularization_RI, bs_env, qs_env)
3166 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: v_tr_r
3168 REAL(kind=
dp) :: regularization_ri
3172 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_V_tr_R'
3174 INTEGER :: handle, img, nimages_scf_desymm
3175 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: sizes_ri
3176 INTEGER,
DIMENSION(:),
POINTER :: col_bsize, row_bsize
3178 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_v_tr_r
3180 TYPE(
dbcsr_type),
ALLOCATABLE,
DIMENSION(:) :: mat_v_tr_r
3185 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
3187 CALL timeset(routinen, handle)
3189 NULLIFY (sab_ri, dist_2d)
3192 blacs_env=blacs_env, &
3193 distribution_2d=dist_2d, &
3194 qs_kind_set=qs_kind_set, &
3195 particle_set=particle_set)
3197 ALLOCATE (sizes_ri(bs_env%n_atom))
3198 CALL get_particle_set(particle_set, qs_kind_set, nsgf=sizes_ri, basis=bs_env%basis_set_RI)
3200 pot_type,
"2c_nl_RI", qs_env, sym_ij=.false., &
3203 ALLOCATE (row_bsize(
SIZE(sizes_ri)))
3204 ALLOCATE (col_bsize(
SIZE(sizes_ri)))
3205 row_bsize(:) = sizes_ri
3206 col_bsize(:) = sizes_ri
3208 nimages_scf_desymm = bs_env%nimages_scf_desymm
3209 ALLOCATE (mat_v_tr_r(nimages_scf_desymm))
3210 CALL dbcsr_create(mat_v_tr_r(1),
"(RI|RI)", dbcsr_dist, dbcsr_type_no_symmetry, &
3211 row_bsize, col_bsize)
3212 DEALLOCATE (row_bsize, col_bsize)
3214 DO img = 2, nimages_scf_desymm
3215 CALL dbcsr_create(mat_v_tr_r(img), template=mat_v_tr_r(1))
3219 bs_env%basis_set_RI, pot_type, do_kpoints=.true., &
3220 ext_kpoints=bs_env%kpoints_scf_desymm, &
3221 regularization_ri=regularization_ri)
3223 ALLOCATE (fm_v_tr_r(nimages_scf_desymm))
3224 DO img = 1, nimages_scf_desymm
3225 CALL cp_fm_create(fm_v_tr_r(img), bs_env%fm_RI_RI%matrix_struct)
3230 IF (.NOT.
ALLOCATED(v_tr_r))
THEN
3231 ALLOCATE (v_tr_r(bs_env%n_RI, bs_env%n_RI, nimages_scf_desymm))
3240 CALL timestop(handle)
3253 SUBROUTINE power(matrix, exponent, eps, cond_nr, min_ev, max_ev)
3254 COMPLEX(KIND=dp),
DIMENSION(:, :) :: matrix
3255 REAL(kind=
dp) :: exponent, eps
3256 REAL(kind=
dp),
OPTIONAL :: cond_nr, min_ev, max_ev
3258 CHARACTER(len=*),
PARAMETER :: routinen =
'power'
3260 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: eigenvectors
3261 INTEGER :: handle, i, n
3262 REAL(kind=
dp) :: pos_eval
3263 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues
3265 CALL timeset(routinen, handle)
3268 matrix(:, :) = 0.5_dp*(matrix(:, :) + conjg(transpose(matrix(:, :))))
3271 ALLOCATE (eigenvalues(n), eigenvectors(n, n))
3274 IF (
PRESENT(cond_nr)) cond_nr = maxval(abs(eigenvalues))/minval(abs(eigenvalues))
3275 IF (
PRESENT(min_ev)) min_ev = minval(abs(eigenvalues))
3276 IF (
PRESENT(max_ev)) max_ev = maxval(abs(eigenvalues))
3279 IF (eps < eigenvalues(i))
THEN
3280 pos_eval = (eigenvalues(i))**(0.5_dp*exponent)
3284 eigenvectors(:, i) = eigenvectors(:, i)*pos_eval
3287 CALL zgemm(
"N",
"C", n, n, n,
z_one, eigenvectors, n, eigenvectors, n,
z_zero, matrix, n)
3289 DEALLOCATE (eigenvalues, eigenvectors)
3291 CALL timestop(handle)
3293 END SUBROUTINE power
3304 REAL(kind=
dp),
DIMENSION(:, :, :) :: sigma_c_n_time, sigma_c_n_freq
3307 CHARACTER(LEN=*),
PARAMETER :: routinen =
'time_to_freq'
3309 INTEGER :: handle, i_t, j_w, n_occ
3310 REAL(kind=
dp) :: freq_j, time_i, w_cos_ij, w_sin_ij
3311 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: sigma_c_n_cos_time, sigma_c_n_sin_time
3313 CALL timeset(routinen, handle)
3315 ALLOCATE (sigma_c_n_cos_time(bs_env%n_ao, bs_env%num_time_freq_points))
3316 ALLOCATE (sigma_c_n_sin_time(bs_env%n_ao, bs_env%num_time_freq_points))
3318 sigma_c_n_cos_time(:, :) = 0.5_dp*(sigma_c_n_time(:, :, 1) + sigma_c_n_time(:, :, 2))
3319 sigma_c_n_sin_time(:, :) = 0.5_dp*(sigma_c_n_time(:, :, 1) - sigma_c_n_time(:, :, 2))
3321 sigma_c_n_freq(:, :, :) = 0.0_dp
3323 DO i_t = 1, bs_env%num_time_freq_points
3325 DO j_w = 1, bs_env%num_time_freq_points
3327 freq_j = bs_env%imag_freq_points(j_w)
3328 time_i = bs_env%imag_time_points(i_t)
3330 w_cos_ij = bs_env%weights_cos_t_to_w(j_w, i_t)*cos(freq_j*time_i)
3331 w_sin_ij = bs_env%weights_sin_t_to_w(j_w, i_t)*sin(freq_j*time_i)
3334 sigma_c_n_freq(:, j_w, 1) = sigma_c_n_freq(:, j_w, 1) + &
3335 w_cos_ij*sigma_c_n_cos_time(:, i_t)
3338 sigma_c_n_freq(:, j_w, 2) = sigma_c_n_freq(:, j_w, 2) + &
3339 w_sin_ij*sigma_c_n_sin_time(:, i_t)
3348 n_occ = bs_env%n_occ(ispin)
3349 sigma_c_n_freq(1:n_occ, :, 2) = -sigma_c_n_freq(1:n_occ, :, 2)
3351 CALL timestop(handle)
3366 eigenval_scf, ikp, ispin)
3369 REAL(kind=
dp),
DIMENSION(:, :, :) :: sigma_c_ikp_n_freq
3370 REAL(kind=
dp),
DIMENSION(:) :: sigma_x_ikp_n, v_xc_ikp_n, eigenval_scf
3371 INTEGER :: ikp, ispin
3373 CHARACTER(LEN=*),
PARAMETER :: routinen =
'analyt_conti_and_print'
3375 CHARACTER(len=3) :: occ_vir
3376 CHARACTER(len=default_path_length) :: fname
3377 INTEGER :: handle, i_mo, ikp_for_print, iunit, &
3379 LOGICAL :: is_bandstruc_kpoint, print_dos_kpoints, &
3381 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: dummy, sigma_c_ikp_n_qp
3383 CALL timeset(routinen, handle)
3386 ALLOCATE (dummy(n_mo), sigma_c_ikp_n_qp(n_mo))
3387 sigma_c_ikp_n_qp(:) = 0.0_dp
3392 IF (
modulo(i_mo, bs_env%para_env%num_pe) /= bs_env%para_env%mepos) cycle
3395 bs_env%imag_freq_points_fit, dummy, dummy, &
3396 sigma_c_ikp_n_freq(:, 1:bs_env%num_freq_points_fit, 1)*
z_one + &
3397 sigma_c_ikp_n_freq(:, 1:bs_env%num_freq_points_fit, 2)*
gaussi, &
3398 sigma_x_ikp_n(:) - v_xc_ikp_n(:), &
3399 eigenval_scf(:), eigenval_scf(:), &
3400 bs_env%do_hedin_shift, &
3401 i_mo, bs_env%n_occ(ispin), bs_env%n_vir(ispin), &
3402 bs_env%nparam_pade, bs_env%num_freq_points_fit, &
3404 0.0_dp, .true., .false., 1, e_fermi_ext=bs_env%e_fermi(ispin))
3407 CALL bs_env%para_env%sum(sigma_c_ikp_n_qp)
3409 CALL correct_obvious_fitting_fails(sigma_c_ikp_n_qp, ispin, bs_env)
3411 bs_env%eigenval_G0W0(:, ikp, ispin) = eigenval_scf(:) + &
3412 sigma_c_ikp_n_qp(:) + &
3413 sigma_x_ikp_n(:) - &
3416 bs_env%eigenval_HF(:, ikp, ispin) = eigenval_scf(:) + sigma_x_ikp_n(:) - v_xc_ikp_n(:)
3419 print_dos_kpoints = (bs_env%nkp_only_bs <= 0)
3421 is_bandstruc_kpoint = (ikp > bs_env%nkp_only_DOS)
3422 print_ikp = print_dos_kpoints .OR. is_bandstruc_kpoint
3424 IF (bs_env%para_env%is_source() .AND. print_ikp)
THEN
3426 IF (print_dos_kpoints)
THEN
3427 nkp = bs_env%nkp_only_DOS
3430 nkp = bs_env%nkp_only_bs
3431 ikp_for_print = ikp - bs_env%nkp_only_DOS
3434 fname =
"bandstructure_SCF_and_G0W0"
3436 IF (ikp_for_print == 1 .AND. ispin == 1)
THEN
3437 CALL open_file(trim(fname), unit_number=iunit, file_status=
"REPLACE", &
3438 file_action=
"WRITE")
3440 CALL open_file(trim(fname), unit_number=iunit, file_status=
"OLD", &
3441 file_action=
"WRITE", file_position=
"APPEND")
3444 WRITE (iunit,
"(A)")
" "
3445 WRITE (iunit,
"(A10,I7,A25,3F10.4,T90,A7,I2)")
"kpoint: ", ikp_for_print,
"coordinate: ", &
3446 bs_env%kpoints_DOS%xkp(:, ikp),
"spin: ", ispin
3447 WRITE (iunit,
"(A)")
" "
3448 WRITE (iunit,
"(A5,A12,3A17,A16,A18)")
"n",
"k", ϵ
"_nk^DFT (eV)", Σ
"^c_nk (eV)", &
3449 Σ
"^x_nk (eV)",
"v_nk^xc (eV)", ϵ
"_nk^G0W0 (eV)"
3450 WRITE (iunit,
"(A)")
" "
3453 IF (i_mo <= bs_env%n_occ(ispin)) occ_vir =
'occ'
3454 IF (i_mo > bs_env%n_occ(ispin)) occ_vir =
'vir'
3455 WRITE (iunit,
"(I5,3A,I5,4F16.3,F17.3)") i_mo,
' (', occ_vir,
') ', ikp_for_print, &
3456 eigenval_scf(i_mo)*
evolt, &
3457 sigma_c_ikp_n_qp(i_mo)*
evolt, &
3458 sigma_x_ikp_n(i_mo)*
evolt, &
3459 v_xc_ikp_n(i_mo)*
evolt, &
3460 bs_env%eigenval_G0W0(i_mo, ikp, ispin)*
evolt
3463 WRITE (iunit,
"(A)")
" "
3469 CALL timestop(handle)
3479 SUBROUTINE correct_obvious_fitting_fails(Sigma_c_ikp_n_qp, ispin, bs_env)
3480 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: sigma_c_ikp_n_qp
3484 CHARACTER(LEN=*),
PARAMETER :: routinen =
'correct_obvious_fitting_fails'
3486 INTEGER :: handle, homo, i_mo, j_mo, &
3487 n_levels_scissor, n_mo
3488 LOGICAL :: is_occ, is_vir
3489 REAL(kind=
dp) :: sum_sigma_c
3491 CALL timeset(routinen, handle)
3494 homo = bs_env%n_occ(ispin)
3499 IF (abs(sigma_c_ikp_n_qp(i_mo)) > 13.0_dp/
evolt)
THEN
3501 is_occ = (i_mo <= homo)
3502 is_vir = (i_mo > homo)
3504 n_levels_scissor = 0
3505 sum_sigma_c = 0.0_dp
3511 IF (is_occ .AND. j_mo > homo) cycle
3512 IF (is_vir .AND. j_mo <= homo) cycle
3513 IF (abs(i_mo - j_mo) > 10) cycle
3514 IF (i_mo == j_mo) cycle
3516 n_levels_scissor = n_levels_scissor + 1
3517 sum_sigma_c = sum_sigma_c + sigma_c_ikp_n_qp(j_mo)
3522 sigma_c_ikp_n_qp(i_mo) = sum_sigma_c/real(n_levels_scissor, kind=
dp)
3528 CALL timestop(handle)
3530 END SUBROUTINE correct_obvious_fitting_fails
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
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.
subroutine, public get_gto_basis_set(gto_basis_set, name, aliases, norm_type, kind_radius, ncgf, nset, nsgf, cgf_symbol, sgf_symbol, norm_cgf, set_radius, lmax, lmin, lx, ly, lz, m, ncgf_set, npgf, nsgf_set, nshell, cphi, pgf_radius, sphi, scon, zet, first_cgf, first_sgf, l, last_cgf, last_sgf, n, gcc, maxco, maxl, maxpgf, maxsgf_set, maxshell, maxso, nco_sum, npgf_sum, nshell_sum, maxder, short_kind_radius, npgf_seg_sum, ccon)
...
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.
subroutine, public scaled_to_real(r, s, cell)
Transform scaled cell coordinates real coordinates. r=h*s.
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 cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_cfm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_distribution_release(dist)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_dist2d_to_dist(dist2d, dist)
Creates a DBCSR distribution from a distribution_2d.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
Utility routines to open and close files. Tracking of preconnections.
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
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
subroutine, public cp_fm_get_diag(matrix, diag)
returns the diagonal elements of a fm
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
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....
stores a mapping of 2D info (e.g. matrix) on a 2D processor distribution (i.e. blacs grid) where cpus...
subroutine, public fm_to_local_array(fm_s, array_s, weight, add)
...
Utility method to build 3-center integrals for small cell GW.
subroutine, public build_3c_integral_block(int_3c, qs_env, potential_parameter, basis_j, basis_k, basis_i, cell_j, cell_k, cell_i, atom_j, atom_k, atom_i, j_bf_start_from_atom, k_bf_start_from_atom, i_bf_start_from_atom)
...
subroutine, public get_v_tr_r(v_tr_r, pot_type, regularization_ri, bs_env, qs_env)
...
subroutine, public time_to_freq(bs_env, sigma_c_n_time, sigma_c_n_freq, ispin)
...
subroutine, public rtbse_resolve_rirs_flag(qs_env, bs_env, rirs_kernel)
Resolve the linRTBSE RI-RS kernel switch from the KERNEL_RI input and the GW default.
subroutine, public compute_xkp(xkp, ikp_start, ikp_end, grid)
...
subroutine, public analyt_conti_and_print(bs_env, sigma_c_ikp_n_freq, sigma_x_ikp_n, v_xc_ikp_n, eigenval_scf, ikp, ispin)
...
subroutine, public create_and_init_bs_env_for_gw(qs_env, bs_env, bs_sec)
...
subroutine, public add_r(cell_1, cell_2, index_to_cell, cell_1_plus_2, cell_found, cell_to_index, i_cell_1_plus_2)
...
subroutine, public de_init_bs_env(qs_env, bs_env)
Releases the memory-heavy GW intermediates that cannot be freed in bs_env_release,...
subroutine, public get_i_j_atoms(atoms_i, atoms_j, n_atom_i, n_atom_j, color_sub, bs_env)
...
subroutine, public power(matrix, exponent, eps, cond_nr, min_ev, max_ev)
...
subroutine, public is_cell_in_index_to_cell(cell, index_to_cell, cell_found)
...
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
integer, parameter, public default_path_length
Implements transformations from k-space to R-space for Fortran array matrices.
subroutine, public rs_to_kp(rs_real, ks_complex, index_to_cell, xkp, deriv_direction, hmat)
Integrate RS matrices (stored as Fortran array) into a kpoint matrix at given kp.
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)
Retrieve information from a kpoint environment.
subroutine, public kpoint_create(kpoint)
Create a kpoint environment.
2- and 3-center electron repulsion integral routines based on libint2 Currently available operators: ...
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.
subroutine, public m_memory(mem)
Returns the total amount of memory [bytes] in use, if known, zero otherwise.
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public z_one
complex(kind=dp), parameter, public gaussi
complex(kind=dp), parameter, public z_zero
Collection of simple mathematical functions and subroutines.
subroutine, public diag_complex(matrix, eigenvectors, eigenvalues)
Diagonalizes a local complex Hermitian matrix using LAPACK. Based on cp_cfm_heevd.
elemental integer function, public gcd(a, b)
computes the greatest common divisor of two number
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 ...
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^...
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...
Calls routines to get RI integrals and calculate total energies.
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.
Routines to calculate frequency and time grids (integration points and weights) for correlation metho...
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)
...
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)
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)
Framework for 2c-integrals for RI.
subroutine, public trunc_coulomb_for_exchange(qs_env, trunc_coulomb, rel_cutoff_trunc_coulomb_ri_x, cell_grid, do_bvk_cell)
...
basic linear algebra operations for full matrixes
Define methods related to particle_type.
subroutine, public get_particle_set(particle_set, qs_kind_set, first_sgf, last_sgf, nsgf, nmao, basis, ncgf)
Get the components of a particle set.
Define the data structure for the particle information.
Definition of physical constants:
real(kind=dp), parameter, public evolt
real(kind=dp), parameter, public angstrom
subroutine, public rsmat_to_kp(mat_rs, ispin, xkp, cell_to_index_scf, sab_nl, bs_env, cfm_kp, imag_rs_mat)
...
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.
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, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, 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_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, hund_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, proj_shell_charge, lr_atom, do_mtlr, u_j_loop, ao_coef, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, 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, ext_xc_section)
routine where the real calculations are made: the KS matrix is calculated
Define the neighbor list data types and the corresponding functionality.
subroutine, public release_neighbor_list_sets(nlists)
releases an array of neighbor_list_sets
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.
subroutine, public build_2c_integrals(t2c, filter_eps, qs_env, nl_2c, basis_i, basis_j, potential_parameter, do_kpoints, do_hfx_kpoints, ext_kpoints, regularization_ri)
...
subroutine, public build_2c_neighbor_lists(ij_list, basis_i, basis_j, potential_parameter, name, qs_env, sym_ij, molecular, dist_2d, pot_to_rad)
Build 2-center neighborlists adapted to different operators This mainly wraps build_neighbor_lists fo...
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, cell_sym, bounds_i, bounds_j, bounds_k, ri_range, img_to_ri_cell, cell_to_index_ext)
Build 3-center integral tensor.
subroutine, public neighbor_list_3c_destroy(ijk_list)
Destroy 3c neighborlist.
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.
Routines for GW, continuous development [Jan Wilhelm].
subroutine, public continuation_pade(vec_gw_energ, vec_omega_fit_gw, z_value, m_value, vec_sigma_c_gw, vec_sigma_x_minus_vxc_gw, eigenval, eigenval_scf, do_hedin_shift, n_level_gw, gw_corr_lev_occ, gw_corr_lev_vir, nparam_pade, num_fit_points, crossing_search, homo, fermi_level_offset, do_gw_im_time, print_self_energy, count_ev_sc_gw, vec_gw_dos, dos_lower_bound, dos_precision, ndos, min_level_self_energy, max_level_self_energy, dos_eta, dos_min, dos_max, e_fermi_ext)
perform analytic continuation with pade approximation
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
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
type of a logger, at the moment it contains just a print level starting at which level it should be l...
distributes pairs on a 2d grid of processors
Contains information about kpoints.
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.