80#include "./base/base_uses.f90"
86 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'gw_ri_rs_non_periodic'
103 CHARACTER(LEN=*),
PARAMETER :: routinen =
'gw_calc_ri_rs_non_periodic'
106 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_sigma_x_gamma, fm_w_time
108 CALL timeset(routinen, handle)
132 bs_env%ri_rs%mat_phi_mu_l)
137 CALL print_ri_rs_memory_estimate(bs_env)
150 CALL compute_z_lp(qs_env, bs_env, bs_env%ri_rs%grid_points, &
151 bs_env%ri_rs%mat_phi_mu_l, bs_env%ri_rs%mat_Z_lP)
155 bs_env%ri_rs%grid_built = .true.
158 label=
'Memory per MPI process after computing Z_lP:')
168 CALL get_mat_chi_gamma_tau(bs_env, bs_env%mat_chi_Gamma_tau, &
169 bs_env%ri_rs%mat_phi_mu_l, bs_env%ri_rs%mat_Z_lP)
175 CALL compute_w(bs_env, qs_env, bs_env%mat_chi_Gamma_tau, fm_w_time)
185 CALL compute_sigma_x(bs_env, qs_env, bs_env%ri_rs%mat_phi_mu_l, &
186 bs_env%ri_rs%mat_Z_lP, fm_sigma_x_gamma)
200 CALL compute_sigma_c_and_qp_energies(bs_env, fm_w_time, fm_sigma_x_gamma)
204 CALL timestop(handle)
224 SUBROUTINE compute_sigma_c_and_qp_energies(bs_env, fm_W_time, fm_Sigma_x_Gamma)
227 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_w_time, fm_sigma_x_gamma
229 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_Sigma_c_and_QP_energies'
231 INTEGER :: handle, i_iter, n_iter
233 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: eigenval_scf_gamma_dft
234 REAL(kind=
dp),
DIMENSION(2) :: e_fermi_dft
235 REAL(kind=
dp),
DIMENSION(3, 2) :: band_prev
236 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :, :) :: fm_sigma_c_gamma_time
238 CALL timeset(routinen, handle)
242 CALL init_evgw0(bs_env, n_iter, band_prev, eigenval_scf_gamma_dft, e_fermi_dft)
245 DO i_iter = 1, n_iter
247 bs_env%ri_rs%evgw0_i_iter = i_iter
253 CALL compute_sigma_c(bs_env, fm_w_time, bs_env%ri_rs%mat_phi_mu_l, &
254 bs_env%ri_rs%mat_Z_lP, fm_sigma_c_gamma_time)
258 CALL compute_qp_energies(bs_env, fm_sigma_x_gamma, fm_sigma_c_gamma_time)
260 IF (bs_env%gw_flavour ==
g0w0)
EXIT
262 CALL print_evgw0_band_edges(bs_env, band_prev, i_iter, n_iter, converged)
264 IF (i_iter == n_iter .OR. converged)
EXIT
269 CALL update_eigenvalues_g(bs_env)
275 CALL reset_and_clean_bs_env(bs_env, eigenval_scf_gamma_dft, e_fermi_dft, fm_sigma_x_gamma)
279 CALL timestop(handle)
281 END SUBROUTINE compute_sigma_c_and_qp_energies
293 SUBROUTINE init_evgw0(bs_env, n_iter, band_prev, eigenval_scf_Gamma_dft, e_fermi_dft)
296 INTEGER,
INTENT(OUT) :: n_iter
297 REAL(kind=
dp),
DIMENSION(3, 2),
INTENT(OUT) :: band_prev
298 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :), &
299 INTENT(OUT) :: eigenval_scf_gamma_dft
300 REAL(kind=
dp),
DIMENSION(2),
INTENT(OUT) :: e_fermi_dft
302 CHARACTER(LEN=*),
PARAMETER :: routinen =
'init_evGW0'
306 CALL timeset(routinen, handle)
309 band_prev(:, :) = 0.0_dp
310 e_fermi_dft(:) = 0.0_dp
312 IF (bs_env%gw_flavour ==
evgw0)
THEN
313 n_iter = bs_env%ri_rs%evgw0_iter
316 bs_env%eigenval_evGW0(:, :, :) = bs_env%eigenval_scf(:, :, :)
318 ALLOCATE (eigenval_scf_gamma_dft, source=bs_env%eigenval_scf_Gamma)
319 e_fermi_dft(:) = bs_env%e_fermi(:)
322 CALL timestop(handle)
324 END SUBROUTINE init_evgw0
332 SUBROUTINE update_eigenvalues_g(bs_env)
336 CHARACTER(LEN=*),
PARAMETER :: routinen =
'update_eigenvalues_G'
338 INTEGER :: handle, i_mo, ispin
340 CALL timeset(routinen, handle)
343 bs_env%eigenval_evGW0(:, :, :) = bs_env%eigenval_GW(:, :, :)
345 DO ispin = 1, bs_env%n_spin
347 DO i_mo = 1, bs_env%n_mo_retained
348 bs_env%eigenval_scf_Gamma(i_mo, ispin) = bs_env%eigenval_GW(i_mo, 1, ispin)
350 bs_env%e_fermi(ispin) = &
351 0.5_dp*(bs_env%eigenval_GW(bs_env%n_occ(ispin), 1, ispin) + &
352 bs_env%eigenval_GW(bs_env%n_occ(ispin) + 1, 1, ispin))
355 CALL timestop(handle)
357 END SUBROUTINE update_eigenvalues_g
366 SUBROUTINE reset_and_clean_bs_env(bs_env, eigenval_scf_Gamma_dft, e_fermi_dft, fm_Sigma_x_Gamma)
369 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :), &
370 INTENT(INOUT) :: eigenval_scf_gamma_dft
371 REAL(kind=
dp),
DIMENSION(2),
INTENT(IN) :: e_fermi_dft
372 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_sigma_x_gamma
374 CHARACTER(LEN=*),
PARAMETER :: routinen =
'reset_and_clean_bs_env'
378 CALL timeset(routinen, handle)
380 IF (bs_env%gw_flavour ==
evgw0)
THEN
382 bs_env%eigenval_evGW0(:, :, :) = bs_env%eigenval_GW(:, :, :)
384 bs_env%eigenval_scf_Gamma(:, :) = eigenval_scf_gamma_dft(:, :)
385 bs_env%e_fermi(:) = e_fermi_dft(:)
386 DEALLOCATE (eigenval_scf_gamma_dft)
390 CALL timestop(handle)
392 END SUBROUTINE reset_and_clean_bs_env
402 SUBROUTINE print_evgw0_band_edges(bs_env, band_prev, i_iter, n_iter, converged)
405 REAL(kind=
dp),
DIMENSION(3, 2),
INTENT(INOUT) :: band_prev
406 INTEGER,
INTENT(IN) :: i_iter, n_iter
407 LOGICAL,
INTENT(OUT) :: converged
409 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_evGW0_band_edges'
411 INTEGER :: handle, homo, ispin, u
412 REAL(kind=
dp) :: max_delta
413 REAL(kind=
dp),
DIMENSION(3) :: band
415 CALL timeset(routinen, handle)
419 converged = (i_iter > 1)
424 WRITE (u,
'(T2,A)') repeat(
'-', 79)
425 WRITE (u,
'(T2,A,I4,A,I4)')
'evGW0 cycle', i_iter,
' /', n_iter
426 WRITE (u,
'(T2,A)') repeat(
'-', 79)
429 DO ispin = 1, bs_env%n_spin
431 homo = bs_env%n_occ(ispin)
432 band(1) = bs_env%eigenval_GW(homo, 1, ispin)
433 band(2) = bs_env%eigenval_GW(homo + 1, 1, ispin)
434 band(3) = band(2) - band(1)
437 max_delta = max(max_delta, maxval(abs(band(:) - band_prev(:, ispin))))
441 IF (bs_env%n_spin == 2)
WRITE (u,
'(T2,A,I0)')
'Spin ', ispin
442 WRITE (u,
'(T2,A,T61,F20.3)')
'evGW0 HOMO (eV)', band(1)*
evolt
443 WRITE (u,
'(T2,A,T61,F20.3)')
'evGW0 LUMO (eV)', band(2)*
evolt
444 WRITE (u,
'(T2,A,T61,F20.3)')
'evGW0 HOMO-LUMO gap (eV)', band(3)*
evolt
447 band_prev(:, ispin) = band(:)
452 converged = (max_delta < bs_env%ri_rs%evgw0_eps_iter)
453 IF (u > 0)
WRITE (u,
'(T2,A,T61,F20.6)')
'Max. change to previous cycle (eV)', &
457 IF (u > 0)
WRITE (u,
'(T2,A)') repeat(
'-', 79)
462 WRITE (u,
'(T2,A,I4,A)') &
463 'evGW0 eigenvalue self-consistency reached in', i_iter,
' cycles.'
466 ELSE IF (i_iter == n_iter)
THEN
467 CALL cp_warn(__location__, &
468 "The evGW0 eigenvalue self-consistency cycle did not converge "// &
469 "within MAX_ITER cycles. The reported quasiparticle energies are "// &
470 "those of the last cycle.")
473 CALL timestop(handle)
475 END SUBROUTINE print_evgw0_band_edges
494 REAL(kind=
dp),
ALLOCATABLE,
INTENT(INOUT) :: ri_rs_grid_points(:, :)
497 CHARACTER(LEN=*),
PARAMETER :: routinen =
'atomic_basis_at_grid_point'
499 INTEGER :: bs_eff, c_size, handle, i, i_blk, ia, iatom, ikind, natom, npcol, nprow, &
500 num_grid_chunks, r_end, r_start, remaining, run, safe_max
501 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: blk_row_start
502 INTEGER,
DIMENSION(:),
POINTER :: col_dist, r_blk_sizes, row_dist, sizes_ao
503 REAL(kind=
dp) :: r2_threshold
504 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: atom_col_buffer
511 CALL timeset(routinen, handle)
513 natom = bs_env%n_atom
514 cell => bs_env%ri_rs%cell
515 para_env => bs_env%para_env
516 particle_set => bs_env%ri_rs%particle_set
517 sizes_ao => bs_env%sizes_AO
518 cpassert(
ASSOCIATED(cell))
519 cpassert(
ASSOCIATED(para_env))
520 cpassert(
ASSOCIATED(particle_set))
521 cpassert(
SIZE(sizes_ao) == natom)
522 cpassert(
SIZE(ri_rs_grid_points, 2) == bs_env%ri_rs%n_grid_points)
532 CALL dbcsr_get_info(bs_env%mat_ao_ao%matrix, distribution=dbcsr_dist_ks)
536 safe_max = int(0.5_dp*real(bs_env%dbcsr_msg_elem_limit,
dp)* &
537 REAL(max(min(nprow, npcol), 1),
dp)/ &
538 REAL(bs_env%ri_rs%n_grid_points,
dp))
539 safe_max = max(1, safe_max)
547 run = bs_env%ri_rs%grid_atom_boundaries(ia + 1) - bs_env%ri_rs%grid_atom_boundaries(ia)
548 IF (run > 0) num_grid_chunks = num_grid_chunks + (run + bs_eff - 1)/bs_eff
550 ALLOCATE (r_blk_sizes(num_grid_chunks), blk_row_start(num_grid_chunks))
554 remaining = bs_env%ri_rs%grid_atom_boundaries(ia + 1) - bs_env%ri_rs%grid_atom_boundaries(ia)
555 DO WHILE (remaining > 0)
557 r_blk_sizes(i_blk) = min(bs_eff, remaining)
558 blk_row_start(i_blk) = r_start
559 r_start = r_start + r_blk_sizes(i_blk)
560 remaining = remaining - r_blk_sizes(i_blk)
564 IF (bs_env%unit_nr > 0)
THEN
566 WRITE (bs_env%unit_nr,
'(T2,A,T71,I12)') &
567 'RI-RS grid row-blocks of ϕ_μ(r_l)', num_grid_chunks
568 WRITE (bs_env%unit_nr,
'(T2,A,T69,I12)')
'RI-RS grid points per block (max)', bs_eff
573 IF (
ALLOCATED(bs_env%ri_rs%atom_centers))
DEALLOCATE (bs_env%ri_rs%atom_centers)
574 ALLOCATE (bs_env%ri_rs%atom_centers(3, natom))
576 bs_env%ri_rs%atom_centers(1:3, iatom) = particle_set(iatom)%r(1:3)
582 IF (bs_env%ri_rs%cutoff_radius_v_w > 0.0_dp .OR. &
583 bs_env%ri_rs%cutoff_radius_w0 > 0.0_dp)
THEN
584 IF (
ALLOCATED(bs_env%ri_rs%chunk_centroids))
DEALLOCATE (bs_env%ri_rs%chunk_centroids)
585 ALLOCATE (bs_env%ri_rs%chunk_centroids(3, num_grid_chunks))
586 DO i_blk = 1, num_grid_chunks
587 r_start = blk_row_start(i_blk)
588 r_end = r_start + r_blk_sizes(i_blk) - 1
589 bs_env%ri_rs%chunk_centroids(1, i_blk) = &
590 sum(ri_rs_grid_points(1, r_start:r_end))/real(r_blk_sizes(i_blk),
dp)
591 bs_env%ri_rs%chunk_centroids(2, i_blk) = &
592 sum(ri_rs_grid_points(2, r_start:r_end))/real(r_blk_sizes(i_blk),
dp)
593 bs_env%ri_rs%chunk_centroids(3, i_blk) = &
594 sum(ri_rs_grid_points(3, r_start:r_end))/real(r_blk_sizes(i_blk),
dp)
600 ALLOCATE (row_dist(num_grid_chunks))
601 DO i = 1, num_grid_chunks
602 row_dist(i) = mod(i - 1, nprow)
605 ALLOCATE (col_dist(natom))
607 col_dist(i) = mod(i - 1, npcol)
612 row_dist=row_dist, col_dist=col_dist)
614 CALL dbcsr_create(mat_phi_mu_l, name=
"phi_val_sparse", dist=dist, &
615 matrix_type=dbcsr_type_no_symmetry, &
616 row_blk_size=r_blk_sizes, col_blk_size=sizes_ao)
622 DO iatom = para_env%mepos + 1, natom, para_env%num_pe
624 c_size = sizes_ao(iatom)
627 ALLOCATE (atom_col_buffer(bs_env%ri_rs%n_grid_points, c_size))
628 atom_col_buffer = 0.0_dp
634 IF (bs_env%ri_rs%cutoff_radius_ri_ao > 0.0_dp)
THEN
635 r2_threshold = bs_env%ri_rs%cutoff_radius_ri_ao**2
637 r2_threshold = bs_env%ri_rs%radius_ao_per_atom(iatom)**2
639 ikind = particle_set(iatom)%atomic_kind%kind_number
640 ao_basis => bs_env%basis_set_AO(ikind)%gto_basis_set
642 particle_set(iatom)%r, cell, cutoff_squared=r2_threshold)
645 DO i_blk = 1, num_grid_chunks
646 r_start = blk_row_start(i_blk)
647 r_end = r_start + r_blk_sizes(i_blk) - 1
650 IF (maxval(abs(atom_col_buffer(r_start:r_end, 1:c_size))) > bs_env%eps_filter)
THEN
652 block=atom_col_buffer(r_start:r_end, 1:c_size))
656 DEALLOCATE (atom_col_buffer)
662 IF (bs_env%unit_nr > 0)
WRITE (bs_env%unit_nr,
'(A)')
' '
663 CALL print_matrix_occupation(mat_phi_mu_l,
'ϕ_μ(r_l)', bs_env)
668 DEALLOCATE (r_blk_sizes, row_dist, col_dist, blk_row_start)
671 CALL timestop(handle)
682 SUBROUTINE get_mat_chi_gamma_tau(bs_env, mat_chi_Gamma_tau, mat_phi_mu_l, mat_Z_lP)
685 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: mat_chi_gamma_tau
686 TYPE(
dbcsr_type),
INTENT(INOUT) :: mat_phi_mu_l, mat_z_lp
688 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_mat_chi_Gamma_tau'
690 INTEGER :: handle, i_t, ispin, n_panels
691 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: pan_first, pan_last
692 REAL(kind=
dp) :: grid_occ, t1, tau
693 TYPE(
dbcsr_type) :: matrix_g_occ_ao, matrix_g_vir_ao
695 CALL timeset(routinen, handle)
700 CALL resolve_grid_panels(bs_env, mat_phi_mu_l, pan_first, pan_last)
702 n_panels =
SIZE(pan_first)
703 IF (bs_env%unit_nr > 0)
THEN
704 WRITE (bs_env%unit_nr,
'(T2,A,T74,I9)') &
705 'Number of batches for χ, Σ matrices', n_panels
706 WRITE (bs_env%unit_nr,
'(A)')
' '
715 DO i_t = 1, bs_env%num_time_freq_points
717 tau = bs_env%time_frequency_grid%imaginary_time(i_t)
719 DO ispin = 1, bs_env%n_spin
722 CALL build_g_ao(bs_env, tau, ispin, .true., .false., mat_phi_mu_l, matrix_g_occ_ao)
723 CALL build_g_ao(bs_env, tau, ispin, .false., .true., mat_phi_mu_l, matrix_g_vir_ao)
726 CALL contract_grid_panels(l_a=mat_phi_mu_l, m_a=matrix_g_occ_ao, &
727 l_b=mat_phi_mu_l, m_b=matrix_g_vir_ao, &
728 l_out=mat_z_lp, mat_out=mat_chi_gamma_tau(i_t)%matrix, &
729 scale=bs_env%spin_degeneracy, eps=bs_env%eps_filter, &
730 para_env=bs_env%para_env, &
731 pan_first=pan_first, pan_last=pan_last, &
732 lb_eq_la=.true., lout_eq_la=.false., &
733 zero_out=(ispin == 1), &
734 keep_sparsity=bs_env%ri_rs%keep_sparsity_rirs, &
735 centroids=bs_env%ri_rs%chunk_centroids, &
736 cutoff=bs_env%ri_rs%cutoff_radius_v_w, &
737 grid_occupation=grid_occ)
746 CALL print_matrix_occupation(mat_z_lp,
'Z_lP', bs_env)
747 IF (bs_env%unit_nr > 0)
THEN
748 WRITE (bs_env%unit_nr,
'(T2,A,T73,F7.2,A)') &
749 'Percentage of non-zero matrix elements in G_ll'', χ_ll'', W_ll''', &
750 grid_occ*100.0_dp,
' %'
753 CALL print_matrix_occupation(mat_chi_gamma_tau(i_t)%matrix,
'χ_PQ', bs_env, &
754 suffix=
' for time point 1')
755 IF (bs_env%unit_nr > 0)
WRITE (bs_env%unit_nr,
'(A)')
' '
758 IF (bs_env%unit_nr > 0)
THEN
759 WRITE (bs_env%unit_nr,
'(T2,A,I13,A,I3,A,F7.1,A)') &
760 'Computed χ(iτ,k=0) for time point', i_t,
' /', bs_env%num_time_freq_points, &
766 IF (bs_env%unit_nr > 0)
WRITE (bs_env%unit_nr,
'(A)')
' '
768 CALL timestop(handle)
770 END SUBROUTINE get_mat_chi_gamma_tau
781 SUBROUTINE mask_grid_blocks_near_panel(centroids, blk0, blk1, cutoff, used)
783 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: centroids
784 INTEGER,
INTENT(IN) :: blk0, blk1
785 REAL(kind=
dp),
INTENT(IN) :: cutoff
786 LOGICAL,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: used
788 CHARACTER(LEN=*),
PARAMETER :: routinen =
'mask_grid_blocks_near_panel'
790 INTEGER :: c, handle, k
791 REAL(kind=
dp) :: cutoff2, d2, dx
792 REAL(kind=
dp),
DIMENSION(3) :: hi, lo
794 CALL timeset(routinen, handle)
797 lo(:) = minval(centroids(:, blk0:blk1), dim=2)
798 hi(:) = maxval(centroids(:, blk0:blk1), dim=2)
800 ALLOCATE (used(
SIZE(centroids, 2)))
801 DO c = 1,
SIZE(centroids, 2)
804 dx = max(0.0_dp, lo(k) - centroids(k, c), centroids(k, c) - hi(k))
807 used(c) = (d2 <= cutoff2)
810 CALL timestop(handle)
812 END SUBROUTINE mask_grid_blocks_near_panel
826 SUBROUTINE panel_template_elems(r_blk_sizes, centroids, used, blk0, blk1, cutoff, nze_tmpl)
828 INTEGER,
DIMENSION(:),
INTENT(IN) :: r_blk_sizes
829 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: centroids
830 LOGICAL,
DIMENSION(:),
INTENT(IN) :: used
831 INTEGER,
INTENT(IN) :: blk0, blk1
832 REAL(kind=
dp),
INTENT(IN) :: cutoff
833 INTEGER(KIND=int_8),
INTENT(OUT) :: nze_tmpl
835 CHARACTER(LEN=*),
PARAMETER :: routinen =
'panel_template_elems'
837 INTEGER :: c, handle, ib, n_used
838 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: used_idx
839 REAL(kind=
dp) :: cutoff2
841 CALL timeset(routinen, handle)
845 ALLOCATE (used_idx(n_used))
860 IF (sum((centroids(:, ib) - centroids(:, used_idx(c)))**2) <= cutoff2)
THEN
861 nze_tmpl = nze_tmpl + int(r_blk_sizes(ib),
int_8)*int(r_blk_sizes(used_idx(c)),
int_8)
867 CALL timestop(handle)
869 END SUBROUTINE panel_template_elems
886 SUBROUTINE panel_mem_estimate_gb(nze_tmpl, pan_rows, width, n_grid_total, n_RI, n_ao, &
889 INTEGER(KIND=int_8),
INTENT(IN) :: nze_tmpl
890 INTEGER,
INTENT(IN) :: pan_rows, width, n_grid_total, n_ri, &
892 REAL(kind=
dp),
INTENT(OUT) :: mem_gb
894 REAL(kind=
dp) :: f_near
896 f_near = real(width,
dp)/real(max(n_grid_total, 1),
dp)
897 mem_gb = (3.0_dp*real(nze_tmpl,
dp) + &
898 REAL(pan_rows,
dp)*f_near*(2.0_dp*
REAL(n_RI, dp) +
REAL(n_ao,
dp)))* &
899 8.0_dp/
REAL(MAX(n_procs, 1),
dp)*1.0e-9_dp
901 END SUBROUTINE panel_mem_estimate_gb
924 SUBROUTINE plan_grid_panels(bs_env, r_blk_sizes, panel_size, min_dim, pan_first, pan_last, &
925 centroids, cutoff, n_RI, n_ao, n_procs, mem_budget_GB, &
929 INTEGER,
DIMENSION(:),
INTENT(IN) :: r_blk_sizes
930 INTEGER,
INTENT(IN) :: panel_size, min_dim
931 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: pan_first, pan_last
932 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
933 OPTIONAL :: centroids
934 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: cutoff
935 INTEGER,
INTENT(IN),
OPTIONAL :: n_ri, n_ao, n_procs
936 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: mem_budget_gb
937 LOGICAL,
INTENT(IN),
OPTIONAL :: honor_exact
938 LOGICAL,
INTENT(OUT),
OPTIONAL :: unsafe
940 CHARACTER(LEN=*),
PARAMETER :: routinen =
'plan_grid_panels'
942 INTEGER :: blk0, blk1, handle, ib, n_grid_blocks, &
943 n_grid_total, n_panels, rows_acc, &
945 INTEGER(KIND=int_8) :: msg, nze_tmpl, side
946 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: tmp_first, tmp_last
947 LOGICAL :: fits, my_honor_exact, my_unsafe, &
949 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: used
950 REAL(kind=
dp) :: f_near, mem_gb
952 CALL timeset(routinen, handle)
954 use_cutoff =
PRESENT(centroids) .AND.
PRESENT(cutoff)
955 IF (use_cutoff) use_cutoff = cutoff > 0.0_dp
957 cpassert(
PRESENT(n_ri) .AND.
PRESENT(n_ao) .AND.
PRESENT(n_procs))
962 my_honor_exact = .false.
963 IF (
PRESENT(honor_exact)) my_honor_exact = honor_exact
966 n_grid_blocks =
SIZE(r_blk_sizes)
967 n_grid_total = sum(r_blk_sizes)
968 ALLOCATE (tmp_first(n_grid_blocks), tmp_last(n_grid_blocks))
972 DO WHILE (blk0 <= n_grid_blocks)
977 DO ib = blk0, n_grid_blocks
978 rows_acc = rows_acc + r_blk_sizes(ib)
980 IF (rows_acc >=
TARGET)
EXIT
982 IF (.NOT. use_cutoff .OR. blk1 == blk0)
EXIT
983 CALL mask_grid_blocks_near_panel(centroids, blk0, blk1, cutoff, used)
984 width = sum(r_blk_sizes, mask=used)
985 CALL panel_template_elems(r_blk_sizes, centroids, used, blk0, blk1, cutoff, nze_tmpl)
986 f_near = real(width,
dp)/real(max(n_grid_total, 1),
dp)
987 side = int(real(rows_acc,
dp)*f_near*real(max(n_ri, n_ao),
dp),
int_8)
988 msg = max(nze_tmpl, side)/int(max(min_dim, 1),
int_8)
989 fits = (msg <= bs_env%dbcsr_msg_elem_limit/4)
990 IF (fits .AND.
PRESENT(mem_budget_gb))
THEN
991 IF (mem_budget_gb > 0.0_dp)
THEN
992 CALL panel_mem_estimate_gb(nze_tmpl, rows_acc, width, n_grid_total, &
993 n_ri, n_ao, n_procs, mem_gb)
994 fits = (mem_gb <= mem_budget_gb)
1001 IF (my_honor_exact)
THEN
1003 IF (.NOT. fits) my_unsafe = .true.
1007 TARGET = max(1, min(
TARGET, rows_acc)/2)
1009 n_panels = n_panels + 1
1010 tmp_first(n_panels) = blk0
1011 tmp_last(n_panels) = blk1
1015 ALLOCATE (pan_first(n_panels), pan_last(n_panels))
1016 pan_first(:) = tmp_first(1:n_panels)
1017 pan_last(:) = tmp_last(1:n_panels)
1018 DEALLOCATE (tmp_first, tmp_last)
1020 IF (
PRESENT(unsafe)) unsafe = my_unsafe
1022 CALL timestop(handle)
1024 END SUBROUTINE plan_grid_panels
1033 SUBROUTINE resolve_grid_panels(bs_env, mat_phi_mu_l, pan_first, pan_last)
1036 TYPE(
dbcsr_type),
INTENT(INOUT) :: mat_phi_mu_l
1037 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: pan_first, pan_last
1039 CHARACTER(LEN=*),
PARAMETER :: routinen =
'resolve_grid_panels'
1041 CHARACTER(LEN=max_line_length) :: msg
1042 INTEGER :: handle, min_dim, n_grid_total, &
1043 n_panels_req, npcols, nprows, &
1044 panel_size, safe_max
1045 INTEGER,
DIMENSION(:),
POINTER :: r_blk_sizes
1046 LOGICAL :: honor_exact, panels_unsafe, use_cutoff
1047 REAL(kind=
dp) :: mem_avail_gb, mem_budget_gb
1050 CALL timeset(routinen, handle)
1052 IF (
ALLOCATED(bs_env%ri_rs%pan_first))
THEN
1053 ALLOCATE (pan_first, source=bs_env%ri_rs%pan_first)
1054 ALLOCATE (pan_last, source=bs_env%ri_rs%pan_last)
1055 CALL timestop(handle)
1059 use_cutoff = bs_env%ri_rs%cutoff_radius_v_w > 0.0_dp .AND. &
1060 ALLOCATED(bs_env%ri_rs%chunk_centroids)
1066 CALL dbcsr_get_info(mat_phi_mu_l, nfullrows_total=n_grid_total, row_blk_size=r_blk_sizes, &
1069 min_dim = max(min(nprows, npcols), 1)
1074 IF (use_cutoff)
THEN
1075 safe_max = n_grid_total
1077 safe_max = int(0.5_dp*real(bs_env%dbcsr_msg_elem_limit,
dp)*real(min_dim,
dp)/ &
1078 REAL(n_grid_total,
dp))
1079 safe_max = max(1, min(safe_max, n_grid_total))
1085 n_panels_req = bs_env%ri_rs%n_panels
1086 honor_exact = (n_panels_req > 1)
1087 panels_unsafe = .false.
1088 IF (n_panels_req > 1)
THEN
1093 panel_size = min((n_grid_total + n_panels_req - 1)/n_panels_req, safe_max)
1096 panel_size = safe_max
1098 panel_size = max(1, panel_size)
1100 IF (use_cutoff)
THEN
1103 mem_budget_gb = 0.5_dp*mem_avail_gb
1104 CALL plan_grid_panels(bs_env, r_blk_sizes, panel_size, min_dim, pan_first, pan_last, &
1105 centroids=bs_env%ri_rs%chunk_centroids, &
1106 cutoff=bs_env%ri_rs%cutoff_radius_v_w, &
1107 n_ri=bs_env%n_RI, n_ao=bs_env%n_ao, &
1108 n_procs=bs_env%para_env%num_pe, mem_budget_gb=mem_budget_gb, &
1109 honor_exact=honor_exact, unsafe=panels_unsafe)
1111 CALL plan_grid_panels(bs_env, r_blk_sizes, panel_size, min_dim, pan_first, pan_last)
1114 IF (honor_exact .AND. panels_unsafe)
THEN
1115 WRITE (msg,
'(A,I0,A)') &
1116 "N_PANELS = ", n_panels_req,
" is used as requested, but one or more panels "// &
1117 "exceed the DBCSR 32-bit message length or the memory budget. The run may abort "// &
1118 "or swap; increase N_PANELS if it does."
1122 ALLOCATE (bs_env%ri_rs%pan_first, source=pan_first)
1123 ALLOCATE (bs_env%ri_rs%pan_last, source=pan_last)
1125 CALL timestop(handle)
1127 END SUBROUTINE resolve_grid_panels
1133 SUBROUTINE print_ri_rs_memory_estimate(bs_env)
1139 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_ri_rs_memory_estimate'
1141 CHARACTER(LEN=max_line_length) :: msg
1142 INTEGER :: handle, iatom, ipan, l, &
1143 max_n_ao_used, max_n_local_grid, &
1144 n_ao_used_atom, n_grid_total, &
1145 n_local_grid, n_loc_ri_max, n_procs, &
1146 n_procs_per_atom, n_ri, n_threads, &
1147 natom, pan_rows, pan_width
1148 INTEGER(KIND=int_8) :: nze_tmpl
1149 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: pan_first, pan_last
1150 INTEGER,
DIMENSION(:),
POINTER :: r_blk_sizes
1151 LOGICAL :: use_cutoff
1152 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: grid_used
1153 REAL(kind=
dp) :: cutoff_ri, mem_avail_gb, mem_d_local_gb, &
1154 mem_dlp_gb, mem_pan_gb, mem_panels_gb, &
1155 mem_phi_local_gb, mem_z_lp_gb, &
1156 mem_zlp_peak_gb, pos_p(3)
1159 CALL timeset(routinen, handle)
1161 n_grid_total = bs_env%ri_rs%n_grid_points
1162 CALL dbcsr_get_info(bs_env%ri_rs%mat_phi_mu_l, row_blk_size=r_blk_sizes)
1163 cpassert(sum(r_blk_sizes) == n_grid_total)
1165 n_procs = bs_env%para_env%num_pe
1169 mem_z_lp_gb = real(n_grid_total,
dp)*real(n_ri,
dp)*8.0_dp/ &
1170 REAL(n_procs,
dp)*1.0e-9_dp
1177 use_cutoff = bs_env%ri_rs%cutoff_radius_v_w > 0.0_dp .AND. &
1178 ALLOCATED(bs_env%ri_rs%chunk_centroids)
1179 CALL resolve_grid_panels(bs_env, bs_env%ri_rs%mat_phi_mu_l, pan_first, pan_last)
1180 mem_panels_gb = 0.0_dp
1181 DO ipan = 1,
SIZE(pan_first)
1182 pan_rows = sum(r_blk_sizes(pan_first(ipan):pan_last(ipan)))
1183 IF (use_cutoff)
THEN
1184 CALL mask_grid_blocks_near_panel(bs_env%ri_rs%chunk_centroids, pan_first(ipan), &
1185 pan_last(ipan), bs_env%ri_rs%cutoff_radius_v_w, &
1187 pan_width = sum(r_blk_sizes, mask=grid_used)
1188 CALL panel_template_elems(r_blk_sizes, bs_env%ri_rs%chunk_centroids, &
1189 grid_used, pan_first(ipan), pan_last(ipan), &
1190 bs_env%ri_rs%cutoff_radius_v_w, nze_tmpl)
1191 CALL panel_mem_estimate_gb(nze_tmpl, pan_rows, pan_width, n_grid_total, &
1192 n_ri, bs_env%n_ao, n_procs, mem_pan_gb)
1194 pan_width = n_grid_total
1195 mem_pan_gb = (3.0_dp*real(pan_rows,
dp)*real(pan_width,
dp) + &
1196 2.0_dp*real(pan_rows,
dp)*real(n_ri,
dp))* &
1197 8.0_dp/real(n_procs,
dp)*1.0e-9_dp
1199 mem_panels_gb = max(mem_panels_gb, mem_pan_gb)
1201 mem_panels_gb = mem_panels_gb + &
1202 REAL(n_ri,
dp)*
REAL(n_ri,
dp)*8.0_dp/
REAL(n_procs,
dp)*1.0e-9_dp
1213 particle_set => bs_env%ri_rs%particle_set
1214 cpassert(
ASSOCIATED(particle_set))
1215 natom = bs_env%n_atom
1217 max_n_local_grid = 0
1221 IF (bs_env%ri_rs%cutoff_radius_ri_rs > 0.0_dp)
THEN
1222 cutoff_ri = bs_env%ri_rs%cutoff_radius_ri_rs
1224 cutoff_ri = bs_env%ri_metric%cutoff_radius + bs_env%ri_rs%radius_ri_per_atom(iatom)
1226 pos_p(:) = particle_set(iatom)%r(:)
1228 DO l = 1, n_grid_total
1229 IF (sum((bs_env%ri_rs%grid_points(1:3, l) - pos_p(1:3))**2) <= cutoff_ri**2)
THEN
1230 n_local_grid = n_local_grid + 1
1233 max_n_local_grid = max(max_n_local_grid, n_local_grid)
1234 CALL get_n_ao_in_sphere(bs_env, iatom, cutoff_ri, n_ao_used_atom)
1235 max_n_ao_used = max(max_n_ao_used, n_ao_used_atom)
1236 n_loc_ri_max = max(n_loc_ri_max, &
1237 bs_env%i_RI_end_from_atom(iatom) - bs_env%i_RI_start_from_atom(iatom) + 1)
1240 n_procs_per_atom = min(max(bs_env%ri_rs%n_procs_per_atom_z_lp, 1), n_procs)
1246 IF (n_procs_per_atom > 1)
THEN
1247 mem_d_local_gb = real(max_n_local_grid,
dp)**2*8.0_dp/real(n_procs_per_atom,
dp)*1.0e-9_dp
1249 mem_d_local_gb = real(max_n_local_grid,
dp)**2*8.0_dp*1.0e-9_dp
1251 mem_phi_local_gb = real(max_n_local_grid,
dp)*real(max_n_ao_used,
dp)*8.0_dp*1.0e-9_dp
1252 mem_dlp_gb = real(max_n_local_grid,
dp)*real(n_loc_ri_max,
dp)*8.0_dp* &
1253 REAL(1 + n_threads,
dp)*1.0e-9_dp
1254 mem_zlp_peak_gb = mem_d_local_gb + mem_phi_local_gb + mem_dlp_gb
1260 IF (bs_env%unit_nr > 0)
THEN
1261 WRITE (bs_env%unit_nr,
'(A)')
' '
1262 WRITE (bs_env%unit_nr,
'(T2,A)')
'RI-RS memory estimate per MPI process:'
1263 WRITE (bs_env%unit_nr,
'(T4,A,F37.2,A)') &
1264 'Available memory per process (system)', mem_avail_gb,
' GB'
1265 WRITE (bs_env%unit_nr,
'(T4,A,F18.2,A)') &
1266 'Required for Z_lP (dense upper bound; actual is sparser)', mem_z_lp_gb,
' GB'
1267 WRITE (bs_env%unit_nr,
'(T4,A,F25.2,A)') &
1268 'Required for χ, W, Σ panels (peak per panel step)', mem_panels_gb,
' GB'
1269 WRITE (bs_env%unit_nr,
'(T4,A,F17.2,A)') &
1270 'Required for Z_lP solve peak (D_local+ϕ, worst-case atom)', mem_zlp_peak_gb,
' GB'
1271 WRITE (bs_env%unit_nr,
'(T4,A,T69,I12)') &
1272 'Worst-case local-grid number of grid points:', max_n_local_grid
1273 WRITE (bs_env%unit_nr,
'(T4,A,T69,F9.2,A)') &
1274 'Worst-case memory D_local:', mem_d_local_gb,
' GB'
1278 IF (mem_avail_gb > 0.0_dp .AND. mem_z_lp_gb > mem_avail_gb)
THEN
1279 WRITE (msg,
'(A,F0.2,A,F0.2,A)') &
1280 "The estimated memory for Z_lP, ", mem_z_lp_gb,
" GB per process, exceeds the "// &
1281 "available ", mem_avail_gb,
" GB. Z_lP (n_grid x n_RI) is distributed across all "// &
1282 "MPI ranks, so add nodes, use fewer MPI ranks per node, or raise "// &
1283 "N_PROCS_PER_ATOM_Z_LP to distribute each atom block via ScaLAPACK, which reduces "// &
1284 "the per-rank memory roughly by the number of ranks per atom."
1288 IF (mem_avail_gb > 0.0_dp .AND. mem_panels_gb > mem_avail_gb)
THEN
1289 WRITE (msg,
'(A,F0.2,A,F0.2,A)') &
1290 "The estimated peak memory of the chi/W/Sigma panels, ", mem_panels_gb, &
1291 " GB per process, exceeds the available ", mem_avail_gb,
" GB. Panel memory "// &
1292 "scales roughly as 3*panel_size*n_grid/n_procs, so add nodes, use fewer MPI ranks "// &
1293 "per node, or raise N_PANELS for more but smaller panels."
1297 IF (mem_avail_gb > 0.0_dp .AND. mem_zlp_peak_gb > mem_avail_gb)
THEN
1298 WRITE (msg,
'(A,F0.2,A,F0.2,A)') &
1299 "The estimated peak memory of the Z_lP solve, ", mem_zlp_peak_gb, &
1300 " GB per process, exceeds the available ", mem_avail_gb, &
1301 " GB. The per-atom matrix D'_ll' dominates and "// &
1302 "scales as n_local_grid^2, and it is not balanced across ranks: the rank owning "// &
1303 "the atom with the largest integration sphere peaks well above the average. "// &
1304 "Either raise N_PROCS_PER_ATOM_Z_LP to distribute D_local block-cyclic via "// &
1305 "ScaLAPACK, which reduces that term roughly by the number of ranks per atom at no "// &
1306 "loss of accuracy, or lower CUTOFF_RADIUS_RL_RI, which shrinks D_local as "// &
1307 "n_local_grid^2 but trades accuracy, or use fewer MPI ranks per node so that each "// &
1308 "rank has more memory for the peak atom."
1312 CALL timestop(handle)
1314 END SUBROUTINE print_ri_rs_memory_estimate
1329 SUBROUTINE build_geo_template_panel(L_pan, L_full, centroids, cutoff, blk0, A_template, col_map)
1330 TYPE(
dbcsr_type),
INTENT(IN) :: l_pan, l_full
1331 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: centroids
1332 REAL(kind=
dp),
INTENT(IN) :: cutoff
1333 INTEGER,
INTENT(IN) :: blk0
1335 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: col_map
1337 CHARACTER(LEN=*),
PARAMETER :: routinen =
'build_geo_template_panel'
1339 INTEGER :: c, cg, cs, handle, my_pcol, my_prow, &
1340 n_grid_blks, n_pan_blks, npcols, &
1342 INTEGER,
DIMENSION(:),
POINTER :: grid_blk_sizes, pan_blk_sizes
1343 REAL(kind=
dp) :: cutoff2
1344 REAL(kind=
dp),
ALLOCATABLE :: zero_blk(:, :)
1347 CALL timeset(routinen, handle)
1350 CALL dbcsr_get_info(l_pan, nblkrows_total=n_pan_blks, row_blk_size=pan_blk_sizes)
1351 CALL dbcsr_get_info(l_full, nblkrows_total=n_grid_blks, row_blk_size=grid_blk_sizes)
1355 CALL create_product_matrix(l_pan, l_full,
'N',
'T', a_template)
1358 myprow=my_prow, mypcol=my_pcol)
1360 ALLOCATE (zero_blk(maxval(pan_blk_sizes(1:n_pan_blks)), &
1361 maxval(grid_blk_sizes(1:n_grid_blks))))
1362 zero_blk(:, :) = 0.0_dp
1364 DO r = 1, n_pan_blks
1365 IF (mod(r - 1, nprows) /= my_prow) cycle
1366 rs = pan_blk_sizes(r)
1367 DO c = 1, n_grid_blks
1368 IF (mod(c - 1, npcols) /= my_pcol) cycle
1370 IF (
PRESENT(col_map)) cg = col_map(c)
1371 IF ((centroids(1, blk0 + r - 1) - centroids(1, cg))**2 + &
1372 (centroids(2, blk0 + r - 1) - centroids(2, cg))**2 + &
1373 (centroids(3, blk0 + r - 1) - centroids(3, cg))**2 <= cutoff2)
THEN
1374 cs = grid_blk_sizes(c)
1381 DEALLOCATE (zero_blk)
1382 CALL timestop(handle)
1384 END SUBROUTINE build_geo_template_panel
1396 SUBROUTINE extract_grid_panel(mat_full, blk0, blk1, mat_panel)
1399 INTEGER,
INTENT(IN) :: blk0, blk1
1402 CHARACTER(LEN=*),
PARAMETER :: routinen =
'extract_grid_panel'
1404 INTEGER :: handle, ib, jb, npb
1405 INTEGER,
DIMENSION(:),
POINTER :: col_blk_full, col_dist_full, &
1406 row_blk_full, row_blk_pan, &
1407 row_dist_full, row_dist_pan
1408 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: blk
1412 CALL timeset(routinen, handle)
1415 row_blk_size=row_blk_full, col_blk_size=col_blk_full)
1418 npb = blk1 - blk0 + 1
1419 ALLOCATE (row_dist_pan(npb), row_blk_pan(npb))
1420 row_dist_pan(:) = row_dist_full(blk0:blk1)
1421 row_blk_pan(:) = row_blk_full(blk0:blk1)
1424 row_dist=row_dist_pan, col_dist=col_dist_full)
1425 CALL dbcsr_create(mat_panel, name=
"grid_panel", dist=dist_pan, &
1426 matrix_type=dbcsr_type_no_symmetry, &
1427 row_blk_size=row_blk_pan, col_blk_size=col_blk_full)
1432 IF (ib < blk0 .OR. ib > blk1) cycle
1439 DEALLOCATE (row_dist_pan, row_blk_pan)
1441 CALL timestop(handle)
1443 END SUBROUTINE extract_grid_panel
1453 SUBROUTINE collect_used_col_blocks(matrix, para_env, used)
1457 LOGICAL,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: used
1459 CHARACTER(LEN=*),
PARAMETER :: routinen =
'collect_used_col_blocks'
1461 INTEGER :: handle, ib, jb, nblkcols
1462 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: iused
1463 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: blk
1466 CALL timeset(routinen, handle)
1469 ALLOCATE (iused(nblkcols))
1479 CALL para_env%sum(iused)
1481 ALLOCATE (used(nblkcols))
1482 used(:) = (iused(:) > 0)
1485 CALL timestop(handle)
1487 END SUBROUTINE collect_used_col_blocks
1500 SUBROUTINE extract_masked_blocks(mat_full, used, mat_out, compress_rows, blk_map)
1503 LOGICAL,
DIMENSION(:),
INTENT(IN) :: used
1505 LOGICAL,
INTENT(IN) :: compress_rows
1506 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT), &
1509 CHARACTER(LEN=*),
PARAMETER :: routinen =
'extract_masked_blocks'
1511 INTEGER :: handle, ib, jb, n_blk, n_sub, r
1512 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: inv_map
1513 INTEGER,
DIMENSION(:),
POINTER :: blk_full, blk_sub, col_blk_full, &
1514 col_dist_full, dist_full_1d, &
1515 dist_sub_1d, row_blk_full, &
1517 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: blk
1521 CALL timeset(routinen, handle)
1524 row_blk_size=row_blk_full, col_blk_size=col_blk_full)
1527 IF (compress_rows)
THEN
1528 blk_full => row_blk_full
1529 dist_full_1d => row_dist_full
1531 blk_full => col_blk_full
1532 dist_full_1d => col_dist_full
1534 n_blk =
SIZE(blk_full)
1538 ALLOCATE (inv_map(n_blk), blk_sub(n_sub), dist_sub_1d(n_sub))
1539 IF (
PRESENT(blk_map))
ALLOCATE (blk_map(n_sub))
1546 blk_sub(r) = blk_full(ib)
1547 dist_sub_1d(r) = dist_full_1d(ib)
1548 IF (
PRESENT(blk_map)) blk_map(r) = ib
1552 IF (compress_rows)
THEN
1554 row_dist=dist_sub_1d, col_dist=col_dist_full)
1555 CALL dbcsr_create(mat_out, name=
"row_subset", dist=dist_sub, &
1556 matrix_type=dbcsr_type_no_symmetry, &
1557 row_blk_size=blk_sub, col_blk_size=col_blk_full)
1560 row_dist=row_dist_full, col_dist=dist_sub_1d)
1561 CALL dbcsr_create(mat_out, name=
"col_subset", dist=dist_sub, &
1562 matrix_type=dbcsr_type_no_symmetry, &
1563 row_blk_size=row_blk_full, col_blk_size=blk_sub)
1569 IF (compress_rows)
THEN
1570 IF (inv_map(ib) > 0)
CALL dbcsr_put_block(mat_out, inv_map(ib), jb, blk)
1572 IF (inv_map(jb) > 0)
CALL dbcsr_put_block(mat_out, ib, inv_map(jb), blk)
1579 DEALLOCATE (inv_map, blk_sub, dist_sub_1d)
1581 CALL timestop(handle)
1583 END SUBROUTINE extract_masked_blocks
1598 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: centers
1599 REAL(kind=
dp),
INTENT(IN) :: radius
1601 CHARACTER(LEN=*),
PARAMETER :: routinen =
'reserve_blocks_within_radius'
1603 INTEGER :: handle, i, j, my_pcol, my_prow, &
1605 INTEGER,
DIMENSION(:),
POINTER :: col_blk, col_dist, row_blk, row_dist
1606 REAL(kind=
dp) :: radius2
1607 REAL(kind=
dp),
ALLOCATABLE :: zero_blk(:, :)
1610 CALL timeset(routinen, handle)
1612 CALL dbcsr_get_info(matrix, nblkrows_total=nblkrows, nblkcols_total=nblkcols, &
1613 row_blk_size=row_blk, col_blk_size=col_blk, distribution=dist)
1615 myprow=my_prow, mypcol=my_pcol)
1616 cpassert(nblkrows ==
SIZE(centers, 2))
1617 cpassert(nblkcols ==
SIZE(centers, 2))
1620 ALLOCATE (zero_blk(maxval(row_blk(1:nblkrows)), maxval(col_blk(1:nblkcols))))
1621 zero_blk(:, :) = 0.0_dp
1624 IF (row_dist(i) /= my_prow) cycle
1626 IF (col_dist(j) /= my_pcol) cycle
1627 IF ((centers(1, i) - centers(1, j))**2 + (centers(2, i) - centers(2, j))**2 + &
1628 (centers(3, i) - centers(3, j))**2 <= radius2)
THEN
1629 CALL dbcsr_put_block(matrix, i, j, zero_blk(1:row_blk(i), 1:col_blk(j)))
1635 DEALLOCATE (zero_blk)
1636 CALL timestop(handle)
1650 SUBROUTINE create_product_matrix(mat_left, mat_right, transa, transb, mat_out)
1652 TYPE(
dbcsr_type),
INTENT(IN) :: mat_left, mat_right
1653 CHARACTER(LEN=1),
INTENT(IN) :: transa, transb
1656 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_product_matrix'
1658 INTEGER :: handle, i, npcols, nprows
1659 INTEGER,
DIMENSION(:),
POINTER :: col_blk_l, col_blk_r, out_col_blk, &
1660 out_col_dist, out_row_blk, &
1661 out_row_dist, row_blk_l, row_blk_r
1664 CALL timeset(routinen, handle)
1666 CALL dbcsr_get_info(mat_left, distribution=dist_l, row_blk_size=row_blk_l, col_blk_size=col_blk_l)
1667 CALL dbcsr_get_info(mat_right, row_blk_size=row_blk_r, col_blk_size=col_blk_r)
1673 IF (transa ==
'N')
THEN
1674 out_row_blk => row_blk_l
1676 out_row_blk => col_blk_l
1678 IF (transb ==
'N')
THEN
1679 out_col_blk => col_blk_r
1681 out_col_blk => row_blk_r
1684 ALLOCATE (out_row_dist(
SIZE(out_row_blk)), out_col_dist(
SIZE(out_col_blk)))
1685 DO i = 1,
SIZE(out_row_blk)
1686 out_row_dist(i) = mod(i - 1, nprows)
1688 DO i = 1,
SIZE(out_col_blk)
1689 out_col_dist(i) = mod(i - 1, npcols)
1693 row_dist=out_row_dist, col_dist=out_col_dist)
1694 CALL dbcsr_create(mat_out, name=
"panel_product", dist=dist_out, &
1695 matrix_type=dbcsr_type_no_symmetry, &
1696 row_blk_size=out_row_blk, col_blk_size=out_col_blk)
1698 DEALLOCATE (out_row_dist, out_col_dist)
1700 CALL timestop(handle)
1702 END SUBROUTINE create_product_matrix
1714 SUBROUTINE build_g_ao(bs_env, tau, ispin, occ, vir, template, matrix_G_ao)
1717 REAL(kind=
dp),
INTENT(IN) :: tau
1718 INTEGER,
INTENT(IN) :: ispin
1719 LOGICAL,
INTENT(IN) :: occ, vir
1723 CHARACTER(LEN=*),
PARAMETER :: routinen =
'build_G_ao'
1726 INTEGER,
DIMENSION(:),
POINTER :: blk_ao, dist_row_ao
1730 CALL timeset(routinen, handle)
1733 fm_g => bs_env%fm_Gocc
1735 fm_g => bs_env%fm_Gvir
1738 CALL g_occ_vir(bs_env, tau, fm_g, ispin, occ=occ, vir=vir)
1740 CALL setup_square_topology(template, dist_ao_ao, blk_ao, dist_row_ao)
1741 CALL dbcsr_create(matrix_g_ao, name=
"G_ao", dist=dist_ao_ao, &
1742 matrix_type=dbcsr_type_no_symmetry, &
1743 row_blk_size=blk_ao, col_blk_size=blk_ao)
1747 IF (bs_env%ri_rs%cutoff_radius_g_w > 0.0_dp .AND. &
1748 ALLOCATED(bs_env%ri_rs%atom_centers))
THEN
1750 bs_env%ri_rs%cutoff_radius_g_w)
1758 CALL release_square_topology(dist=dist_ao_ao, mapped_dist=dist_row_ao)
1760 CALL timestop(handle)
1762 END SUBROUTINE build_g_ao
1794 SUBROUTINE contract_grid_panels(L_A, M_A, L_B, M_B, L_out, mat_out, scale, eps, para_env, &
1795 pan_first, pan_last, lb_eq_la, lout_eq_la, zero_out, &
1796 keep_sparsity, centroids, cutoff, grid_occupation)
1798 TYPE(
dbcsr_type),
INTENT(INOUT),
TARGET :: l_a
1800 TYPE(
dbcsr_type),
INTENT(INOUT),
TARGET :: l_b
1802 TYPE(
dbcsr_type),
INTENT(INOUT),
TARGET :: l_out
1804 REAL(kind=
dp),
INTENT(IN) :: scale, eps
1806 INTEGER,
DIMENSION(:),
INTENT(IN) :: pan_first, pan_last
1807 LOGICAL,
INTENT(IN) :: lb_eq_la, lout_eq_la, zero_out
1808 LOGICAL,
INTENT(IN),
OPTIONAL :: keep_sparsity
1809 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
1810 OPTIONAL :: centroids
1811 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: cutoff
1812 REAL(kind=
dp),
INTENT(OUT),
OPTIONAL :: grid_occupation
1814 CHARACTER(LEN=*),
PARAMETER :: routinen =
'contract_grid_panels'
1816 INTEGER :: blk0, blk1, handle, ipan, n_grid_total, &
1817 ncols_pan, nrows_pan
1818 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: gmap
1819 LOGICAL :: my_keep_sparsity, use_cutoff
1820 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: grid_used, useda, usedb
1821 TYPE(
dbcsr_type) :: a_pan, b_pan, c_pan, la_pan, la_panc, &
1822 lb_pan, lb_panc, lout_pan, ma_sub, &
1823 mb_sub, tmp2, tmpa, tmpb
1824 TYPE(
dbcsr_type),
POINTER :: rb_a, rb_b, rb_out
1825 TYPE(
dbcsr_type),
TARGET :: la_near, lb_near, lout_near
1827 CALL timeset(routinen, handle)
1829 my_keep_sparsity = .false.
1830 IF (
PRESENT(keep_sparsity)) my_keep_sparsity = keep_sparsity
1831 use_cutoff =
PRESENT(centroids) .AND.
PRESENT(cutoff)
1832 IF (use_cutoff) use_cutoff = cutoff > 0.0_dp
1833 IF (
PRESENT(grid_occupation)) grid_occupation = 0.0_dp
1837 IF (zero_out)
CALL dbcsr_set(mat_out, 0.0_dp)
1839 DO ipan = 1,
SIZE(pan_first)
1840 blk0 = pan_first(ipan)
1841 blk1 = pan_last(ipan)
1844 CALL extract_grid_panel(l_a, blk0, blk1, la_pan)
1845 IF (.NOT. lb_eq_la)
CALL extract_grid_panel(l_b, blk0, blk1, lb_pan)
1846 IF (.NOT. lout_eq_la)
CALL extract_grid_panel(l_out, blk0, blk1, lout_pan)
1851 CALL collect_used_col_blocks(la_pan, para_env, useda)
1852 IF (.NOT. lb_eq_la)
THEN
1853 CALL collect_used_col_blocks(lb_pan, para_env, usedb)
1855 IF (
ALLOCATED(usedb))
DEALLOCATE (usedb)
1856 ALLOCATE (usedb, source=useda)
1858 IF (.NOT. (any(useda) .AND. any(usedb)))
THEN
1870 IF (use_cutoff)
THEN
1871 CALL mask_grid_blocks_near_panel(centroids, blk0, blk1, cutoff, grid_used)
1872 CALL extract_masked_blocks(l_a, grid_used, la_near, compress_rows=.true., blk_map=gmap)
1873 IF (.NOT. lb_eq_la)
CALL extract_masked_blocks(l_b, grid_used, lb_near, compress_rows=.true.)
1874 IF (.NOT. lout_eq_la)
CALL extract_masked_blocks(l_out, grid_used, lout_near, compress_rows=.true.)
1881 ELSE IF (use_cutoff)
THEN
1886 IF (lout_eq_la)
THEN
1888 ELSE IF (use_cutoff)
THEN
1898 CALL extract_masked_blocks(la_pan, useda, la_panc, compress_rows=.false.)
1899 CALL extract_masked_blocks(m_a, useda, ma_sub, compress_rows=.true.)
1900 CALL create_product_matrix(la_panc, ma_sub,
'N',
'N', tmpa)
1901 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, la_panc, ma_sub, 0.0_dp, tmpa, filter_eps=eps)
1903 IF (use_cutoff)
THEN
1904 CALL build_geo_template_panel(la_pan, la_near, centroids, cutoff, blk0, a_pan, &
1907 CALL create_product_matrix(tmpa, rb_a,
'N',
'T', a_pan)
1909 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpa, rb_a, 0.0_dp, a_pan, &
1910 filter_eps=eps, retain_sparsity=use_cutoff)
1918 IF (
PRESENT(grid_occupation))
THEN
1919 CALL dbcsr_get_info(a_pan, nfullrows_total=nrows_pan, nfullcols_total=ncols_pan)
1921 REAL(ncols_pan,
dp)*
REAL(nrows_pan,
dp)/ &
1922 (
REAL(n_grid_total,
dp)*
REAL(n_grid_total,
dp))
1929 CALL extract_masked_blocks(m_b, useda, mb_sub, compress_rows=.true.)
1930 CALL create_product_matrix(la_panc, mb_sub,
'N',
'N', tmpb)
1931 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, la_panc, mb_sub, 0.0_dp, tmpb, filter_eps=eps)
1933 CALL extract_masked_blocks(lb_pan, usedb, lb_panc, compress_rows=.false.)
1934 CALL extract_masked_blocks(m_b, usedb, mb_sub, compress_rows=.true.)
1935 CALL create_product_matrix(lb_panc, mb_sub,
'N',
'N', tmpb)
1936 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, lb_panc, mb_sub, 0.0_dp, tmpb, filter_eps=eps)
1940 IF (my_keep_sparsity)
THEN
1946 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpb, rb_b, 0.0_dp, b_pan, &
1947 retain_sparsity=.true.)
1949 CALL create_product_matrix(tmpb, rb_b,
'N',
'T', b_pan)
1950 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpb, rb_b, 0.0_dp, b_pan, filter_eps=eps)
1962 CALL create_product_matrix(c_pan, rb_out,
'N',
'N', tmp2)
1963 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, c_pan, rb_out, 0.0_dp, tmp2, filter_eps=eps)
1967 IF (lout_eq_la)
THEN
1968 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, la_pan, tmp2, 1.0_dp, mat_out, filter_eps=eps)
1970 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, lout_pan, tmp2, 1.0_dp, mat_out, filter_eps=eps)
1976 IF (use_cutoff)
THEN
1984 CALL timestop(handle)
1986 END SUBROUTINE contract_grid_panels
2012 SUBROUTINE contract_grid_panels_sigma_c(mat_phi, mat_Z, mat_G_occ_ao, mat_G_vir_ao, &
2013 mat_W_aux, mat_Sigma_neg, mat_Sigma_pos, eps, para_env, &
2014 pan_first, pan_last, keep_sparsity, centroids, cutoff)
2016 TYPE(
dbcsr_type),
INTENT(INOUT),
TARGET :: mat_phi, mat_z
2017 TYPE(
dbcsr_type),
INTENT(INOUT) :: mat_g_occ_ao, mat_g_vir_ao, mat_w_aux, &
2018 mat_sigma_neg, mat_sigma_pos
2019 REAL(kind=
dp),
INTENT(IN) :: eps
2021 INTEGER,
DIMENSION(:),
INTENT(IN) :: pan_first, pan_last
2022 LOGICAL,
INTENT(IN),
OPTIONAL :: keep_sparsity
2023 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
2024 OPTIONAL :: centroids
2025 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: cutoff
2027 CHARACTER(LEN=*),
PARAMETER :: routinen =
'contract_grid_panels_sigma_c'
2029 INTEGER :: blk0, blk1, handle, ipan
2030 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: gmap
2031 LOGICAL :: my_keep_sparsity, use_cutoff
2032 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: grid_used, used_ao, used_ri
2033 TYPE(
dbcsr_type) :: a_occ, a_vir, c_pan, g_occ_sub, &
2034 g_vir_sub, phi_pan, phi_panc, tmp2, &
2035 tmpa, tmpb, w_pan, w_sub, z_pan, z_panc
2039 CALL timeset(routinen, handle)
2041 my_keep_sparsity = .false.
2042 IF (
PRESENT(keep_sparsity)) my_keep_sparsity = keep_sparsity
2043 use_cutoff =
PRESENT(centroids) .AND.
PRESENT(cutoff)
2044 IF (use_cutoff) use_cutoff = cutoff > 0.0_dp
2049 DO ipan = 1,
SIZE(pan_first)
2050 blk0 = pan_first(ipan)
2051 blk1 = pan_last(ipan)
2053 CALL extract_grid_panel(mat_phi, blk0, blk1, phi_pan)
2054 CALL extract_grid_panel(mat_z, blk0, blk1, z_pan)
2058 CALL collect_used_col_blocks(phi_pan, para_env, used_ao)
2059 CALL collect_used_col_blocks(z_pan, para_env, used_ri)
2060 IF (.NOT. (any(used_ao) .AND. any(used_ri)))
THEN
2068 IF (use_cutoff)
THEN
2069 CALL mask_grid_blocks_near_panel(centroids, blk0, blk1, cutoff, grid_used)
2070 CALL extract_masked_blocks(mat_phi, grid_used, phi_near, compress_rows=.true., blk_map=gmap)
2071 CALL extract_masked_blocks(mat_z, grid_used, z_near, compress_rows=.true.)
2079 CALL extract_masked_blocks(phi_pan, used_ao, phi_panc, compress_rows=.false.)
2080 CALL extract_masked_blocks(z_pan, used_ri, z_panc, compress_rows=.false.)
2081 CALL extract_masked_blocks(mat_g_occ_ao, used_ao, g_occ_sub, compress_rows=.true.)
2082 CALL extract_masked_blocks(mat_g_vir_ao, used_ao, g_vir_sub, compress_rows=.true.)
2083 CALL extract_masked_blocks(mat_w_aux, used_ri, w_sub, compress_rows=.true.)
2088 CALL create_product_matrix(phi_panc, g_occ_sub,
'N',
'N', tmpa)
2089 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, phi_panc, g_occ_sub, 0.0_dp, tmpa, filter_eps=eps)
2090 IF (use_cutoff)
THEN
2091 CALL build_geo_template_panel(phi_pan, phi_near, centroids, cutoff, blk0, a_occ, &
2094 CALL create_product_matrix(tmpa, rb_phi,
'N',
'T', a_occ)
2096 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpa, rb_phi, 0.0_dp, a_occ, &
2097 filter_eps=eps, retain_sparsity=use_cutoff)
2102 CALL create_product_matrix(phi_panc, g_vir_sub,
'N',
'N', tmpa)
2103 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, phi_panc, g_vir_sub, 0.0_dp, tmpa, filter_eps=eps)
2104 IF (use_cutoff)
THEN
2105 CALL build_geo_template_panel(phi_pan, phi_near, centroids, cutoff, blk0, a_vir, &
2108 CALL create_product_matrix(tmpa, rb_phi,
'N',
'T', a_vir)
2110 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpa, rb_phi, 0.0_dp, a_vir, &
2111 filter_eps=eps, retain_sparsity=use_cutoff)
2119 CALL create_product_matrix(z_panc, w_sub,
'N',
'N', tmpb)
2120 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, z_panc, w_sub, 0.0_dp, tmpb, filter_eps=eps)
2121 IF (my_keep_sparsity)
THEN
2124 CALL dbcsr_add(w_pan, a_vir, 1.0_dp, 1.0_dp)
2128 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpb, rb_z, 0.0_dp, w_pan, &
2129 retain_sparsity=.true.)
2131 CALL create_product_matrix(tmpb, rb_z,
'N',
'T', w_pan)
2132 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpb, rb_z, 0.0_dp, w_pan, filter_eps=eps)
2143 CALL create_product_matrix(c_pan, rb_phi,
'N',
'N', tmp2)
2144 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, c_pan, rb_phi, 0.0_dp, tmp2, filter_eps=eps)
2146 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, phi_pan, tmp2, 1.0_dp, mat_sigma_neg, filter_eps=eps)
2153 CALL create_product_matrix(c_pan, rb_phi,
'N',
'N', tmp2)
2154 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, c_pan, rb_phi, 0.0_dp, tmp2, filter_eps=eps)
2156 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, phi_pan, tmp2, 1.0_dp, mat_sigma_pos, filter_eps=eps)
2162 IF (use_cutoff)
THEN
2169 CALL timestop(handle)
2171 END SUBROUTINE contract_grid_panels_sigma_c
2187 SUBROUTINE compute_w(bs_env, qs_env, mat_chi_Gamma_tau, fm_W_time)
2190 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: mat_chi_gamma_tau
2191 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_w_time
2193 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_W'
2195 INTEGER :: handle, i_t, j_w
2197 TYPE(
cp_fm_type) :: fm_m_inv_v_sqrt, fm_v, fm_v_sqrt
2199 CALL timeset(routinen, handle)
2207 CALL cp_fm_create(fm_v_sqrt, bs_env%fm_RI_RI%matrix_struct)
2208 CALL cp_fm_create(fm_m_inv_v_sqrt, bs_env%fm_RI_RI%matrix_struct)
2211 CALL compute_v_minvvsqrt(bs_env, qs_env, fm_v, fm_v_sqrt, fm_m_inv_v_sqrt)
2214 DO j_w = 1, bs_env%num_time_freq_points
2220 CALL compute_fm_w_freq(bs_env, bs_env%fm_chi_Gamma_freq, fm_v_sqrt, &
2221 fm_m_inv_v_sqrt, bs_env%fm_W_MIC_freq)
2230 IF (bs_env%unit_nr > 0)
THEN
2231 WRITE (bs_env%unit_nr,
'(T2,A,T58,A,F7.1,A)') &
2232 'Computed W(iτ),',
' Execution time',
m_walltime() - t1,
' s'
2245 CALL cp_fm_create(bs_env%fm_W_MIC_freq_zero, bs_env%fm_W_MIC_freq%matrix_struct)
2249 DO i_t = 1, bs_env%num_time_freq_points
2252 bs_env%time_frequency_grid%time_weights_at_zero_frequency(i_t), fm_w_time(i_t))
2255 CALL fm_write(bs_env%fm_W_MIC_freq_zero, 0,
"W_freq_rtp", qs_env)
2257 IF (bs_env%unit_nr > 0)
THEN
2258 WRITE (bs_env%unit_nr,
'(T2,A,T57,A,F7.1,A)') &
2259 'Computed W(0),',
' Execution time',
m_walltime() - t1,
' s'
2263 IF (bs_env%unit_nr > 0)
WRITE (bs_env%unit_nr,
'(A)')
' '
2265 CALL timestop(handle)
2267 END SUBROUTINE compute_w
2279 SUBROUTINE compute_v_minvvsqrt(bs_env, qs_env, fm_V, fm_V_sqrt, fm_Minv_Vsqrt)
2282 TYPE(
cp_fm_type),
INTENT(INOUT) :: fm_v, fm_v_sqrt, fm_minv_vsqrt
2284 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_V_MinvVsqrt'
2289 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: mat_v_kp
2291 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2293 CALL timeset(routinen, handle)
2295 IF (bs_env%auto_ri%enabled)
THEN
2305 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell, &
2306 qs_kind_set=qs_kind_set)
2307 atomic_kind_set => bs_env%ri_rs%atomic_kind_set
2309 ALLOCATE (mat_v_kp(1:1, 1:2))
2310 NULLIFY (mat_v_kp(1, 1)%matrix, mat_v_kp(1, 2)%matrix)
2311 ALLOCATE (mat_v_kp(1, 1)%matrix, mat_v_kp(1, 2)%matrix)
2312 CALL dbcsr_create(mat_v_kp(1, 1)%matrix, template=bs_env%mat_RI_RI%matrix)
2314 CALL dbcsr_set(mat_v_kp(1, 1)%matrix, 0.0_dp)
2315 CALL dbcsr_create(mat_v_kp(1, 2)%matrix, template=bs_env%mat_RI_RI%matrix)
2318 CALL dbcsr_set(mat_v_kp(1, 2)%matrix, 0.0_dp)
2320 bs_env%kpoints_chi_eps_W%nkp_grid = bs_env%nkp_grid_chi_eps_W_orig
2322 particle_set, qs_kind_set, atomic_kind_set, &
2328 DEALLOCATE (mat_v_kp)
2334 CALL fm_sqrt(fm_v, fm_v_sqrt, bs_env%eps_eigval_mat_RI, bs_env%unit_nr)
2339 CALL parallel_gemm(
"N",
"T", bs_env%n_RI, bs_env%n_RI, bs_env%n_RI, 1.0_dp, &
2340 bs_env%fm_Minv_Gamma, fm_v_sqrt, 0.0_dp, fm_minv_vsqrt)
2342 CALL timestop(handle)
2344 END SUBROUTINE compute_v_minvvsqrt
2358 SUBROUTINE compute_fm_w_freq(bs_env, fm_chi_freq_j, fm_V_sqrt, fm_Minv_Vsqrt, fm_W_freq_j)
2360 TYPE(
cp_fm_type),
INTENT(IN) :: fm_chi_freq_j, fm_v_sqrt, fm_minv_vsqrt
2361 TYPE(
cp_fm_type),
INTENT(INOUT) :: fm_w_freq_j
2363 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_fm_W_freq'
2365 INTEGER :: handle, n_ri
2368 CALL timeset(routinen, handle)
2372 CALL cp_fm_create(fm_eps_freq_j, fm_chi_freq_j%matrix_struct)
2373 CALL cp_fm_create(fm_work, fm_chi_freq_j%matrix_struct)
2380 fm_chi_freq_j, fm_minv_vsqrt, 0.0_dp, fm_work)
2384 fm_minv_vsqrt, fm_work, 0.0_dp, fm_eps_freq_j)
2387 CALL fm_add_on_diag(fm_eps_freq_j, 1.0_dp)
2397 CALL fm_invert(fm_eps_freq_j, bs_env%eps_eigval_mat_RI, bs_env%unit_nr)
2400 CALL fm_add_on_diag(fm_eps_freq_j, -1.0_dp)
2409 CALL timestop(handle)
2411 END SUBROUTINE compute_fm_w_freq
2418 SUBROUTINE fm_add_on_diag(fm, alpha)
2420 REAL(kind=
dp),
INTENT(IN) :: alpha
2422 CHARACTER(LEN=*),
PARAMETER :: routinen =
'fm_add_on_diag'
2424 INTEGER :: handle, i_global, i_row, j_col, &
2425 j_global, ncol_local, nrow_local
2426 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
2428 CALL timeset(routinen, handle)
2431 nrow_local=nrow_local, &
2432 ncol_local=ncol_local, &
2433 row_indices=row_indices, &
2434 col_indices=col_indices)
2436 DO j_col = 1, ncol_local
2437 j_global = col_indices(j_col)
2438 DO i_row = 1, nrow_local
2439 i_global = row_indices(i_row)
2440 IF (j_global == i_global)
THEN
2441 fm%local_data(i_row, j_col) = fm%local_data(i_row, j_col) + alpha
2446 CALL timestop(handle)
2448 END SUBROUTINE fm_add_on_diag
2461 SUBROUTINE compute_sigma_x(bs_env, qs_env, mat_phi_mu_l, mat_Z_lP, fm_Sigma_x_Gamma)
2465 TYPE(
dbcsr_type),
INTENT(INOUT) :: mat_phi_mu_l, mat_z_lp
2466 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_sigma_x_gamma
2468 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_Sigma_x'
2470 INTEGER :: handle, ispin
2471 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: pan_first, pan_last
2472 INTEGER,
DIMENSION(:),
POINTER :: blk_aux, dist_row_aux
2474 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :) :: fm_vtr_gamma
2476 TYPE(
dbcsr_type) :: mat_sigma_x_gamma, matrix_d_ao, &
2479 CALL timeset(routinen, handle)
2483 ALLOCATE (fm_sigma_x_gamma(bs_env%n_spin))
2484 DO ispin = 1, bs_env%n_spin
2485 CALL cp_fm_create(fm_sigma_x_gamma(ispin), bs_env%fm_s_Gamma%matrix_struct)
2488 CALL dbcsr_create(mat_sigma_x_gamma, template=bs_env%mat_ao_ao%matrix)
2490 CALL resolve_grid_panels(bs_env, mat_phi_mu_l, pan_first, pan_last)
2495 CALL setup_square_topology(mat_z_lp, dist_aux_aux, blk_aux, dist_row_aux)
2497 IF (bs_env%auto_ri%enabled)
THEN
2498 ALLOCATE (fm_vtr_gamma(1, 1))
2499 CALL cp_fm_create(fm_vtr_gamma(1, 1), bs_env%fm_RI_RI%matrix_struct)
2500 CALL cp_fm_to_fm(bs_env%auto_ri%V_pq, fm_vtr_gamma(1, 1))
2502 CALL ri_2c_integral_mat(qs_env, fm_vtr_gamma, bs_env%fm_RI_RI%matrix_struct, bs_env%n_RI, &
2503 bs_env%trunc_coulomb)
2509 CALL dbcsr_create(matrix_v_aux,
"V_aux", dist_aux_aux, dbcsr_type_no_symmetry, blk_aux, blk_aux)
2511 IF (bs_env%ri_rs%cutoff_radius_g_w > 0.0_dp .AND.
ALLOCATED(bs_env%ri_rs%atom_centers))
THEN
2513 bs_env%ri_rs%cutoff_radius_g_w)
2514 CALL copy_fm_to_dbcsr(fm_vtr_gamma(1, 1), matrix_v_aux, keep_sparsity=.true.)
2516 CALL copy_fm_to_dbcsr(fm_vtr_gamma(1, 1), matrix_v_aux, keep_sparsity=.false.)
2525 DO ispin = 1, bs_env%n_spin
2528 CALL build_g_ao(bs_env, 0.0_dp, ispin, .true., .false., mat_phi_mu_l, matrix_d_ao)
2530 CALL contract_grid_panels(l_a=mat_phi_mu_l, m_a=matrix_d_ao, &
2531 l_b=mat_z_lp, m_b=matrix_v_aux, &
2532 l_out=mat_phi_mu_l, mat_out=mat_sigma_x_gamma, &
2533 scale=1.0_dp, eps=bs_env%eps_filter, &
2534 para_env=bs_env%para_env, &
2535 pan_first=pan_first, pan_last=pan_last, &
2536 lb_eq_la=.false., lout_eq_la=.true., zero_out=.true., &
2537 keep_sparsity=bs_env%ri_rs%keep_sparsity_rirs, &
2538 centroids=bs_env%ri_rs%chunk_centroids, &
2539 cutoff=bs_env%ri_rs%cutoff_radius_v_w)
2549 IF (bs_env%unit_nr > 0)
THEN
2550 WRITE (bs_env%unit_nr,
'(T2,A,T58,A,F7.1,A)') &
2551 'Computed Σ^x(k=0),',
' Execution time',
m_walltime() - t1,
' s'
2552 WRITE (bs_env%unit_nr,
'(A)')
' '
2560 CALL release_square_topology(dist=dist_aux_aux, mapped_dist=dist_row_aux)
2564 CALL timestop(handle)
2566 END SUBROUTINE compute_sigma_x
2578 SUBROUTINE compute_sigma_c(bs_env, fm_W_time, mat_phi_mu_l, mat_Z_lP, fm_Sigma_c_Gamma_time)
2581 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_w_time
2582 TYPE(
dbcsr_type),
INTENT(INOUT) :: mat_phi_mu_l, mat_z_lp
2583 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :, :) :: fm_sigma_c_gamma_time
2585 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_Sigma_c'
2587 INTEGER :: handle, i_t, ispin
2588 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: pan_first, pan_last
2589 INTEGER,
DIMENSION(:),
POINTER :: blk_aux, dist_row_aux
2590 REAL(kind=
dp) :: t1, tau
2592 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: mat_sigma_neg_tau, mat_sigma_pos_tau
2593 TYPE(
dbcsr_type) :: matrix_g_occ_ao, matrix_g_vir_ao, &
2596 CALL timeset(routinen, handle)
2601 CALL setup_square_topology(mat_z_lp, dist_aux_aux, blk_aux, dist_row_aux)
2603 CALL resolve_grid_panels(bs_env, mat_phi_mu_l, pan_first, pan_last)
2606 NULLIFY (mat_sigma_neg_tau, mat_sigma_pos_tau)
2607 ALLOCATE (mat_sigma_neg_tau(bs_env%num_time_freq_points, bs_env%n_spin))
2608 ALLOCATE (mat_sigma_pos_tau(bs_env%num_time_freq_points, bs_env%n_spin))
2610 DO i_t = 1, bs_env%num_time_freq_points
2611 DO ispin = 1, bs_env%n_spin
2612 ALLOCATE (mat_sigma_neg_tau(i_t, ispin)%matrix)
2613 ALLOCATE (mat_sigma_pos_tau(i_t, ispin)%matrix)
2614 CALL dbcsr_create(mat_sigma_neg_tau(i_t, ispin)%matrix, template=bs_env%mat_ao_ao%matrix)
2615 CALL dbcsr_create(mat_sigma_pos_tau(i_t, ispin)%matrix, template=bs_env%mat_ao_ao%matrix)
2624 DO i_t = 1, bs_env%num_time_freq_points
2625 tau = bs_env%time_frequency_grid%imaginary_time(i_t)
2627 CALL dbcsr_create(matrix_w_aux,
"W_aux", dist_aux_aux, dbcsr_type_no_symmetry, &
2629 IF (bs_env%ri_rs%cutoff_radius_g_w > 0.0_dp .AND.
ALLOCATED(bs_env%ri_rs%atom_centers))
THEN
2631 bs_env%ri_rs%cutoff_radius_g_w)
2638 DO ispin = 1, bs_env%n_spin
2642 CALL build_g_ao(bs_env, tau, ispin, .true., .false., mat_phi_mu_l, matrix_g_occ_ao)
2643 CALL build_g_ao(bs_env, tau, ispin, .false., .true., mat_phi_mu_l, matrix_g_vir_ao)
2646 CALL contract_grid_panels_sigma_c(mat_phi=mat_phi_mu_l, mat_z=mat_z_lp, &
2647 mat_g_occ_ao=matrix_g_occ_ao, &
2648 mat_g_vir_ao=matrix_g_vir_ao, &
2649 mat_w_aux=matrix_w_aux, &
2650 mat_sigma_neg=mat_sigma_neg_tau(i_t, ispin)%matrix, &
2651 mat_sigma_pos=mat_sigma_pos_tau(i_t, ispin)%matrix, &
2652 eps=bs_env%eps_filter, &
2653 para_env=bs_env%para_env, &
2654 pan_first=pan_first, pan_last=pan_last, &
2655 keep_sparsity=bs_env%ri_rs%keep_sparsity_rirs, &
2656 centroids=bs_env%ri_rs%chunk_centroids, &
2657 cutoff=bs_env%ri_rs%cutoff_radius_v_w)
2658 CALL dbcsr_scale(mat_sigma_neg_tau(i_t, ispin)%matrix, -1.0_dp)
2663 IF (bs_env%unit_nr > 0)
THEN
2664 WRITE (bs_env%unit_nr,
'(T2,A,I15,A,I3,A,F7.1,A)') &
2665 'Computed Σ^c(iτ) for time point', i_t,
' /', bs_env%num_time_freq_points, &
2679 mat_sigma_pos_tau, mat_sigma_neg_tau)
2686 CALL release_square_topology(dist=dist_aux_aux, mapped_dist=dist_row_aux)
2688 CALL timestop(handle)
2690 END SUBROUTINE compute_sigma_c
2699 SUBROUTINE setup_square_topology(matrix_template, square_dist, blk_sizes, mapped_dist)
2701 TYPE(
dbcsr_type),
INTENT(IN) :: matrix_template
2703 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: blk_sizes, mapped_dist
2705 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_square_topology'
2707 INTEGER :: handle, i, nprows
2708 INTEGER,
DIMENSION(:),
POINTER :: col_blk, col_dist
2711 CALL timeset(routinen, handle)
2713 CALL dbcsr_get_info(matrix_template, distribution=dist_template, col_blk_size=col_blk)
2716 blk_sizes => col_blk
2717 ALLOCATE (mapped_dist(
SIZE(blk_sizes)))
2718 DO i = 1,
SIZE(blk_sizes)
2719 mapped_dist(i) = mod(i - 1, nprows)
2722 row_dist=mapped_dist, col_dist=col_dist)
2724 CALL timestop(handle)
2726 END SUBROUTINE setup_square_topology
2733 SUBROUTINE release_square_topology(dist, mapped_dist)
2736 INTEGER,
DIMENSION(:),
INTENT(INOUT),
POINTER :: mapped_dist
2739 IF (
ASSOCIATED(mapped_dist))
THEN
2740 DEALLOCATE (mapped_dist)
2741 NULLIFY (mapped_dist)
2744 END SUBROUTINE release_square_topology
2753 SUBROUTINE compute_qp_energies(bs_env, fm_Sigma_x_Gamma, fm_Sigma_c_Gamma_time)
2756 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_sigma_x_gamma
2757 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :, :) :: fm_sigma_c_gamma_time
2759 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_QP_energies'
2761 INTEGER :: handle, ispin, j_t
2762 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: sigma_x_n, v_xc_n
2763 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: sigma_c_n_freq, sigma_c_n_time
2764 TYPE(
cp_fm_type) :: fm_ks, fm_mos, fm_s, fm_work
2766 CALL timeset(routinen, handle)
2768 CALL cp_fm_create(fm_ks, bs_env%fm_s_Gamma%matrix_struct)
2769 CALL cp_fm_create(fm_s, bs_env%fm_s_Gamma%matrix_struct)
2770 CALL cp_fm_create(fm_mos, bs_env%fm_s_Gamma%matrix_struct)
2771 CALL cp_fm_create(fm_work, bs_env%fm_s_Gamma%matrix_struct)
2773 ALLOCATE (v_xc_n(bs_env%n_ao), sigma_x_n(bs_env%n_ao))
2774 ALLOCATE (sigma_c_n_time(bs_env%n_ao, bs_env%num_time_freq_points, 2))
2775 ALLOCATE (sigma_c_n_freq(bs_env%n_ao, bs_env%num_time_freq_points, 2))
2777 DO ispin = 1, bs_env%n_spin
2780 CALL cp_fm_to_fm(bs_env%fm_ks_Gamma(ispin), fm_ks)
2782 CALL cp_fm_geeig(fm_ks, fm_s, fm_mos, bs_env%eigenval_scf(:, 1, ispin), fm_work)
2785 CALL to_gamma_and_mo_real(v_xc_n, bs_env%fm_V_xc_Gamma(ispin), fm_mos)
2786 CALL to_gamma_and_mo_real(sigma_x_n, fm_sigma_x_gamma(ispin), fm_mos)
2789 DO j_t = 1, bs_env%num_time_freq_points
2790 CALL to_gamma_and_mo_real(sigma_c_n_time(:, j_t, 1), &
2791 fm_sigma_c_gamma_time(j_t, 1, ispin), fm_mos)
2792 CALL to_gamma_and_mo_real(sigma_c_n_time(:, j_t, 2), &
2793 fm_sigma_c_gamma_time(j_t, 2, ispin), fm_mos)
2797 CALL time_to_freq(bs_env, sigma_c_n_time, sigma_c_n_freq, ispin)
2801 bs_env%eigenval_scf(:, 1, ispin), 1, ispin)
2815 CALL timestop(handle)
2817 END SUBROUTINE compute_qp_energies
2825 SUBROUTINE to_gamma_and_mo_real(array_n, fm_Gamma, fm_mos)
2827 REAL(kind=
dp),
DIMENSION(:) :: array_n
2830 CHARACTER(LEN=*),
PARAMETER :: routinen =
'to_Gamma_and_mo_real'
2835 CALL timeset(routinen, handle)
2846 CALL timestop(handle)
2848 END SUBROUTINE to_gamma_and_mo_real
2857 SUBROUTINE get_n_ao_in_sphere(bs_env, atom_P, cutoff_ri, n_ao_used)
2860 INTEGER,
INTENT(IN) :: atom_p
2861 REAL(kind=
dp),
INTENT(IN) :: cutoff_ri
2862 INTEGER,
INTENT(OUT) :: n_ao_used
2864 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_n_ao_in_sphere'
2866 INTEGER :: handle, ri_atom
2868 CALL timeset(routinen, handle)
2871 DO ri_atom = 1, bs_env%n_atom
2872 IF (norm2(bs_env%ri_rs%particle_set(ri_atom)%r(:) - &
2873 bs_env%ri_rs%particle_set(atom_p)%r(:)) > &
2874 bs_env%ri_rs%radius_ao_per_atom(ri_atom) + cutoff_ri) cycle
2875 n_ao_used = n_ao_used + bs_env%i_ao_end_from_atom(ri_atom) - &
2876 bs_env%i_ao_start_from_atom(ri_atom) + 1
2879 CALL timestop(handle)
2881 END SUBROUTINE get_n_ao_in_sphere
2890 SUBROUTINE print_matrix_occupation(matrix, label, bs_env, suffix)
2893 CHARACTER(LEN=*),
INTENT(IN) :: label
2895 CHARACTER(LEN=*),
INTENT(IN),
OPTIONAL :: suffix
2897 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_matrix_occupation'
2899 CHARACTER(LEN=32) :: output_format
2900 CHARACTER(LEN=max_line_length) :: msg, output_label
2901 INTEGER :: handle, i, unicode_shift
2902 REAL(kind=
dp) :: frac_2p31, max_loc, occ
2904 CALL timeset(routinen, handle)
2908 CALL bs_env%para_env%max(max_loc)
2910 IF (bs_env%unit_nr > 0)
THEN
2911 frac_2p31 = max_loc/real(bs_env%dbcsr_msg_elem_limit,
dp)
2912 output_label =
'Percentage of non-zero matrix elements in '//trim(label)
2913 IF (
PRESENT(suffix)) output_label = trim(output_label)//trim(suffix)
2917 DO i = 1, len_trim(output_label)
2918 IF (iand(iachar(output_label(i:i)), 192) == 128) unicode_shift = unicode_shift + 1
2920 WRITE (output_format,
'(A,I0,A)')
'(T2,A,T', 72 + unicode_shift,
',F7.2,A)'
2921 WRITE (bs_env%unit_nr, output_format) trim(output_label), occ*100.0_dp,
' %'
2922 IF (frac_2p31 > 0.5_dp)
THEN
2923 WRITE (msg,
'(3A,F0.2,A)') &
2924 "The largest per-rank message of ", trim(label),
" reaches ", frac_2p31, &
2925 " of the 32-bit limit that DBCSR uses for its message length. Beyond it the "// &
2926 "length overflows and multiply_cannon fails. Reduce the per-rank block size, "// &
2927 "for instance with more MPI ranks or a larger N_PANELS."
2933 CALL timestop(handle)
2935 END SUBROUTINE print_matrix_occupation
Define the atomic kind types and their sub types.
Handles all functions related to the CELL.
constants for the different operators of the 2c-integrals
integer, parameter, public operator_coulomb
subroutine, public dbcsr_distribution_release(dist)
...
integer function, public dbcsr_get_data_size(matrix)
...
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
subroutine, public dbcsr_distribution_new(dist, template, group, pgrid, row_dist, col_dist, reuse_arrays)
...
subroutine, public dbcsr_deallocate_matrix(matrix)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset, transposed)
...
subroutine, public dbcsr_filter(matrix, eps)
...
real(kind=dp) function, public dbcsr_get_occupation(matrix)
...
subroutine, public dbcsr_finalize(matrix)
...
subroutine, public dbcsr_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_put_block(matrix, row, col, block, summation)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
subroutine, public dbcsr_distribution_get(dist, row_dist, col_dist, nrows, ncols, has_threads, group, mynode, numnodes, nprows, npcols, myprow, mypcol, pgrid, subgroups_defined, prow_group, pcol_group)
...
subroutine, public dbcsr_reserve_all_blocks(matrix)
Reserves all blocks.
DBCSR operations in CP2K.
integer, save, public max_elements_per_block
subroutine, public copy_dbcsr_to_fm(matrix, fm, plan)
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.
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....
subroutine, public cp_fm_uplo_to_full(matrix, work, uplo)
given a triangular matrix according to uplo, computes the corresponding full matrix
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
subroutine, public cp_fm_geeig(amatrix, bmatrix, eigenvectors, eigenvalues, work)
General Eigenvalue Problem AX = BXE. Use cuSOLVERMp directly when requested and large enough; otherwi...
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_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
Computes the RI-RS fitting matrix Z_lP.
subroutine, public compute_z_lp(qs_env, bs_env, ri_rs_grid_points, mat_phi_mu_l, mat_z_lp)
Computes Z_lP for (1) a tabulated RI basis set or (2) an on-the-fly generated RI basis set.
Main setup file for RI-RS grids {r_l}.
subroutine, public setup_ri_rs_grid(bs_env, grid_points)
Get RI-RS grid points {r_l}, either by on-the-fly optimization or reading pretabulated atomic grids.
GW using RI-RS Approximation for molecules.
subroutine, public gw_calc_ri_rs_non_periodic(qs_env, bs_env)
GW calculation using RI-RS formalism for molecules.
subroutine, public reserve_blocks_within_radius(matrix, centers, radius)
Pre-seeds a square blocked DBCSR matrix with zero blocks only for block pairs whose centers lie withi...
subroutine, public atomic_basis_at_grid_point(bs_env, ri_rs_grid_points, mat_phi_mu_l)
Evaluates the AO basis on the RI-RS grid and stores it as the sparse DBCSR matrix ϕ_μl = ϕ_μ(r_l) (ro...
Common setup operations used by the periodic and non-periodic GW RI-RS implementations.
subroutine, public precompute_ri_rs_radii(bs_env)
Compute per-atom AO and RI basis radii from the most diffuse Gaussian primitive in the AO ("ORB") and...
subroutine, public evaluate_ao_basis_on_points(phi, grid_points, basis, source_position, cell, dphi, cutoff_squared)
Evaluate one explicitly supplied contracted Gaussian basis on Cartesian points.
Routines from paper [Graml2024].
subroutine, public compute_fm_chi_gamma_freq(bs_env, fm_chi_gamma_freq, j_w, mat_chi_gamma_tau)
...
subroutine, public fourier_transform_w_to_t(bs_env, fm_w_mic_time, fm_w_mic_freq_j, j_w)
...
subroutine, public fm_write(fm, matrix_index, matrix_name, qs_env)
...
subroutine, public create_fm_w_mic_time(bs_env, fm_w_mic_time)
...
subroutine, public fill_fm_sigma_c_gamma_time(fm_sigma_c_gamma_time, bs_env, mat_sigma_pos_tau, mat_sigma_neg_tau)
...
subroutine, public g_occ_vir(bs_env, tau, fm_g_gamma, ispin, occ, vir)
...
subroutine, public delete_unnecessary_files(bs_env)
...
Common DBCSR matrix operations used by GW modules.
subroutine, public hadamard_product(matrix_a, matrix_b, matrix_c, factor)
Computes the scaled element-wise product C = factor (A ◦ B) while preserving the block structure of A...
Full-matrix operations not provided by the CP2K FM packages.
subroutine, public fm_invert(matrix_a, eigenvalue_threshold, unit_nr)
Inverts a symmetric matrix. First, Cholesky decomposition is tried. If it fails, the matrix is diagon...
subroutine, public fm_sqrt(matrix_a, matrix_b, eigenvalue_threshold, unit_nr)
For input A, computes B such that B^T B=A. First, Cholesky decomposition is tried....
subroutine, public time_to_freq(bs_env, sigma_c_n_time, sigma_c_n_freq, ispin)
...
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 de_init_bs_env(qs_env, bs_env)
Releases the memory-heavy GW intermediates that cannot be freed in bs_env_release,...
Defines the basic variable types.
integer, parameter, public max_line_length
integer, parameter, public int_8
integer, parameter, public dp
Routines to compute the Coulomb integral V_(alpha beta)(k) for a k-point k using lattice summation in...
subroutine, public build_2c_coulomb_matrix_kp(matrix_v_kp, kpoints, basis_type, cell, particle_set, qs_kind_set, atomic_kind_set, size_lattice_sum, operator_type, ikp_start, ikp_end)
...
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Interface to the message passing library MPI.
subroutine, public mp_mem_avail_per_rank_gb(comm, mem_avail_gb)
Memory that is currently free on the node, per MPI rank of that node, in GB.
subroutine, public mp_print_mem_per_rank(comm, unit_nr, label)
Prints the memory available to and used by a single MPI rank at the moment of the call....
Framework for 2c-integrals for RI.
subroutine, public ri_2c_integral_mat(qs_env, fm_matrix_minv_l_gamma, fm_matrix_l_struct, dimen_ri, ri_metric, put_mat_ks_env, regularization_ri)
...
basic linear algebra operations for full matrixes
Define the data structure for the particle information.
Definition of physical constants:
real(kind=dp), parameter, public evolt
subroutine, public get_all_vbm_cbm_bandgaps(bs_env)
...
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.
Define the quickstep kind type and their sub types.
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.