32 dbcsr_type_no_symmetry
95#include "./base/base_uses.f90"
101 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'gw_non_periodic_ri_rs'
109 INTEGER(KIND=int_8),
PARAMETER,
PRIVATE :: dbcsr_msg_elem_limit = int(huge(0_int_4),
int_8)
127 CHARACTER(LEN=*),
PARAMETER :: routinen =
'gw_calc_non_periodic_ri_rs'
130 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_sigma_x_gamma, fm_w_time
131 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :, :) :: fm_sigma_c_gamma_time
133 CALL timeset(routinen, handle)
157 bs_env%ri_rs%mat_phi_mu_l)
162 CALL print_ri_rs_memory_estimate(qs_env, bs_env)
176 bs_env%ri_rs%mat_phi_mu_l, bs_env%ri_rs%mat_Z_lP)
178 bs_env%ri_rs%grid_built = .true.
188 CALL get_mat_chi_gamma_tau(bs_env, bs_env%mat_chi_Gamma_tau, &
189 bs_env%ri_rs%mat_phi_mu_l, bs_env%ri_rs%mat_Z_lP)
195 CALL compute_w(bs_env, qs_env, bs_env%mat_chi_Gamma_tau, fm_w_time)
205 CALL compute_sigma_x(bs_env, qs_env, bs_env%ri_rs%mat_phi_mu_l, &
206 bs_env%ri_rs%mat_Z_lP, fm_sigma_x_gamma)
215 CALL compute_sigma_c(bs_env, fm_w_time, bs_env%ri_rs%mat_phi_mu_l, &
216 bs_env%ri_rs%mat_Z_lP, fm_sigma_c_gamma_time)
227 CALL timestop(handle)
246 CHARACTER(LEN=*),
PARAMETER :: routinen =
'precompute_ri_rs_radii'
248 INTEGER :: handle, i, iatom, ikind, j, natom, nkind
249 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: kind_of
251 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: alpha_min_ao_kind, alpha_min_ri_kind
252 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: zet_ao, zet_ri
256 CALL timeset(routinen, handle)
258 CALL get_qs_env(qs_env, nkind=nkind, atomic_kind_set=atomic_kind_set, &
259 particle_set=particle_set)
260 natom =
SIZE(particle_set)
262 eps = bs_env%eps_filter
264 ALLOCATE (alpha_min_ao_kind(nkind), alpha_min_ri_kind(nkind))
265 alpha_min_ao_kind = huge(1.0_dp)
266 alpha_min_ri_kind = huge(1.0_dp)
269 zet_ao => bs_env%basis_set_AO(ikind)%gto_basis_set%zet
270 zet_ri => bs_env%basis_set_RI(ikind)%gto_basis_set%zet
272 DO i = 1,
SIZE(zet_ao, 1)
273 DO j = 1,
SIZE(zet_ao, 2)
274 IF (zet_ao(i, j) > 1.0e-3_dp)
then
275 alpha_min_ao_kind(ikind) = min(alpha_min_ao_kind(ikind), zet_ao(i, j))
279 DO i = 1,
SIZE(zet_ri, 1)
280 DO j = 1,
SIZE(zet_ri, 2)
281 IF (zet_ri(i, j) > 1.0e-3_dp)
then
282 alpha_min_ri_kind(ikind) = min(alpha_min_ri_kind(ikind), zet_ri(i, j))
290 ALLOCATE (bs_env%ri_rs%radius_ao_per_atom(natom))
291 ALLOCATE (bs_env%ri_rs%radius_ri_per_atom(natom))
293 ikind = kind_of(iatom)
294 bs_env%ri_rs%radius_ao_per_atom(iatom) = sqrt(-log(eps)/alpha_min_ao_kind(ikind))
295 bs_env%ri_rs%radius_ri_per_atom(iatom) = sqrt(-log(eps)/alpha_min_ri_kind(ikind))
298 IF (bs_env%unit_nr > 0)
THEN
299 WRITE (bs_env%unit_nr,
'(T2,A)') Å
'Per-kind RI-RS basis radii ():'
300 WRITE (bs_env%unit_nr,
'(T4,A6,2X,A4,2A14)')
'Kind',
'Elem', Å
'r_AO ()', Å
'r_RI ()'
302 WRITE (bs_env%unit_nr,
'(T4,I6,2X,A4,2F14.4)') &
304 atomic_kind_set(ikind)%element_symbol, &
305 sqrt(-log(eps)/alpha_min_ao_kind(ikind))*
angstrom, &
306 sqrt(-log(eps)/alpha_min_ri_kind(ikind))*
angstrom
308 WRITE (bs_env%unit_nr,
'(A)')
' '
311 DEALLOCATE (alpha_min_ao_kind, alpha_min_ri_kind, kind_of)
313 CALL timestop(handle)
323 SUBROUTINE morton_split3(a, x)
324 INTEGER(KIND=int_8),
INTENT(IN) :: a
325 INTEGER(KIND=int_8),
INTENT(OUT) :: x
327 x = iand(a, int(z
'1FFFFF',
int_8))
328 x = iand(ior(x, ishft(x, 32)), int(z
'1F00000000FFFF',
int_8))
329 x = iand(ior(x, ishft(x, 16)), int(z
'1F0000FF0000FF',
int_8))
330 x = iand(ior(x, ishft(x, 8)), int(z
'100F00F00F00F00F',
int_8))
331 x = iand(ior(x, ishft(x, 4)), int(z
'10C30C30C30C30C3',
int_8))
332 x = iand(ior(x, ishft(x, 2)), int(z
'1249249249249249',
int_8))
333 END SUBROUTINE morton_split3
346 SUBROUTINE spatial_atom_order(particle_set, order)
348 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: order
350 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spatial_atom_order'
351 INTEGER,
PARAMETER :: nbits = 21
353 INTEGER :: handle, ia, k, natom
354 INTEGER(KIND=int_8) :: cmax, ic(3), m1, m2, m3
355 INTEGER(KIND=int_8),
ALLOCATABLE :: mcode(:)
356 REAL(kind=
dp) :: hi(3), lo(3), span(3)
358 CALL timeset(routinen, handle)
360 natom =
SIZE(particle_set)
361 ALLOCATE (order(natom), mcode(natom))
362 cmax = ishft(1_int_8, nbits) - 1_int_8
365 hi(:) = -huge(1.0_dp)
368 lo(k) = min(lo(k), particle_set(ia)%r(k))
369 hi(k) = max(hi(k), particle_set(ia)%r(k))
372 span(:) = hi(:) - lo(:)
374 IF (span(k) <= 0.0_dp) span(k) = 1.0_dp
379 ic(k) = int(((particle_set(ia)%r(k) - lo(k))/span(k))*real(cmax,
dp),
int_8)
380 ic(k) = min(cmax, max(0_int_8, ic(k)))
382 CALL morton_split3(ic(1), m1)
383 CALL morton_split3(ic(2), m2)
384 CALL morton_split3(ic(3), m3)
385 mcode(ia) = ior(ior(m1, ishft(m2, 1)), ishft(m3, 2))
389 CALL sort(mcode, natom, order)
393 CALL timestop(handle)
395 END SUBROUTINE spatial_atom_order
409 REAL(kind=
dp),
ALLOCATABLE,
INTENT(OUT) :: ri_rs_grid_points(:, :)
411 CHARACTER(LEN=*),
PARAMETER :: routinen =
'ri_rs_grid_assembler'
413 INTEGER :: atom_idx, end_idx, handle, i_layout, &
414 ikind, j, natom, nkind, start_idx, &
416 INTEGER,
ALLOCATABLE :: atom_order(:), atom_to_kind(:), &
417 ri_rs_grid_offsets(:)
418 REAL(kind=
dp) :: atomic_center(3)
422 CALL timeset(routinen, handle)
425 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, particle_set=particle_set)
427 nkind =
SIZE(atomic_kind_set)
428 natom =
SIZE(particle_set)
431 CALL build_grid_cache(bs_env, atomic_kind_set)
434 ALLOCATE (ri_rs_grid_offsets(natom + 1))
435 ALLOCATE (atom_to_kind(natom))
440 IF (
ALLOCATED(bs_env%ri_rs%grid_atom_boundaries))
DEALLOCATE (bs_env%ri_rs%grid_atom_boundaries)
441 ALLOCATE (bs_env%ri_rs%grid_atom_boundaries(natom + 1))
446 DO j = 1,
SIZE(atomic_kind_set(ikind)%atom_list)
447 atom_to_kind(atomic_kind_set(ikind)%atom_list(j)) = ikind
455 CALL spatial_atom_order(particle_set, atom_order)
458 DO i_layout = 1, natom
459 atom_idx = atom_order(i_layout)
460 ikind = atom_to_kind(atom_idx)
461 ri_rs_grid_offsets(atom_idx) = total_grid_npts + 1
462 bs_env%ri_rs%grid_atom_boundaries(i_layout) = total_grid_npts + 1
463 total_grid_npts = total_grid_npts + bs_env%ri_rs%grid_cache(ikind)%npts
466 ri_rs_grid_offsets(natom + 1) = total_grid_npts + 1
467 bs_env%ri_rs%grid_atom_boundaries(natom + 1) = total_grid_npts + 1
469 IF (bs_env%unit_nr > 0)
THEN
470 WRITE (bs_env%unit_nr, fmt=
"(T2,A,T69,I12)") &
471 'Total grid points used for RI-RS:', total_grid_npts
472 WRITE (bs_env%unit_nr,
"(A)")
' '
476 ALLOCATE (ri_rs_grid_points(3, total_grid_npts))
484 DO atom_idx = 1, natom
485 ikind = atom_to_kind(atom_idx)
486 atomic_center(:) = particle_set(atom_idx)%r(:)
488 start_idx = ri_rs_grid_offsets(atom_idx)
489 end_idx = start_idx + bs_env%ri_rs%grid_cache(ikind)%npts - 1
492 ri_rs_grid_points(1, start_idx:end_idx) = bs_env%ri_rs%grid_cache(ikind)%raw_points(1, :) + atomic_center(1)
493 ri_rs_grid_points(2, start_idx:end_idx) = bs_env%ri_rs%grid_cache(ikind)%raw_points(2, :) + atomic_center(2)
494 ri_rs_grid_points(3, start_idx:end_idx) = bs_env%ri_rs%grid_cache(ikind)%raw_points(3, :) + atomic_center(3)
500 IF (
ALLOCATED(bs_env%ri_rs%grid_cache))
THEN
502 IF (
ALLOCATED(bs_env%ri_rs%grid_cache(ikind)%raw_points))
DEALLOCATE (bs_env%ri_rs%grid_cache(ikind)%raw_points)
504 DEALLOCATE (bs_env%ri_rs%grid_cache)
507 DEALLOCATE (atom_order, atom_to_kind, ri_rs_grid_offsets)
509 CALL timestop(handle)
518 SUBROUTINE build_grid_cache(bs_env, atomic_kind_set)
523 CHARACTER(LEN=*),
PARAMETER :: routinen =
'build_grid_cache'
525 CHARACTER(LEN=default_path_length) :: filename, full_path, line
526 CHARACTER(LEN=default_string_length) :: atom_sym, suffix
527 INTEGER :: colon_idx, handle, i, ierr, ikind, &
529 REAL(kind=
dp) :: pt(3)
531 CALL timeset(routinen, handle)
534 IF (bs_env%ri_rs%grid_select == 1)
THEN
535 suffix =
"_def2-tzvp-rs.ion"
536 ELSE IF (bs_env%ri_rs%grid_select == 2)
THEN
537 suffix =
"_cc-pvtz-rs.ion"
538 ELSE IF (bs_env%ri_rs%grid_select == 3)
THEN
539 IF (len_trim(bs_env%ri_rs%grid_file_suffix) > 0)
THEN
540 suffix = trim(bs_env%ri_rs%grid_file_suffix)
545 cpabort(
"Unknown grid_select (1=def2-TZVPP, 2=cc-pVTZ, 3=user-provided).")
548 nkind =
SIZE(atomic_kind_set)
549 IF (.NOT.
ALLOCATED(bs_env%ri_rs%grid_cache))
ALLOCATE (bs_env%ri_rs%grid_cache(nkind))
552 atom_sym = trim(atomic_kind_set(ikind)%element_symbol)
553 filename = trim(atom_sym)//trim(suffix)
555 full_path =
"ri_rs_grid/"//trim(filename)
557 CALL open_file(file_name=trim(full_path), unit_number=iunit, &
558 file_action=
"READ", file_status=
"OLD")
561 bs_env%ri_rs%grid_cache(ikind)%npts = 0
563 READ (iunit,
'(A)', iostat=ierr) line
565 IF (index(line,
'n points') > 0)
THEN
566 colon_idx = index(line,
':')
567 READ (line(colon_idx + 1:), *) bs_env%ri_rs%grid_cache(ikind)%npts
573 ALLOCATE (bs_env%ri_rs%grid_cache(ikind)%raw_points(3, bs_env%ri_rs%grid_cache(ikind)%npts))
577 READ (iunit,
'(A)', iostat=ierr) line
579 IF (index(line,
'<grid_points>') > 0)
EXIT
583 DO i = 1, bs_env%ri_rs%grid_cache(ikind)%npts
584 READ (iunit, *, iostat=ierr) pt(1), pt(2), pt(3)
586 cpabort(
"Unexpected EOF in grid file ")
588 bs_env%ri_rs%grid_cache(ikind)%raw_points(:, i) = pt(:)
594 CALL timestop(handle)
596 END SUBROUTINE build_grid_cache
617 REAL(kind=
dp),
ALLOCATABLE,
INTENT(INOUT) :: ri_rs_grid_points(:, :)
620 CHARACTER(LEN=*),
PARAMETER :: routinen =
'atomic_basis_at_grid_point'
622 INTEGER :: bs_eff, c_size, dimen_orb, handle, i, i_blk, ia, iatom, natom, npcol, nprow, &
623 num_grid_chunks, r_end, r_start, remaining, run, safe_max, total_grid_npts
624 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: blk_row_start, first_sgf
625 INTEGER,
DIMENSION(:),
POINTER :: c_blk_sizes, col_dist, &
626 r_blk_sizes, row_dist
627 REAL(kind=
dp) :: r2_threshold
628 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: atom_col_buffer
635 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
637 CALL timeset(routinen, handle)
640 CALL get_qs_env(qs_env, cell=cell, atomic_kind_set=atomic_kind_set, &
641 qs_kind_set=qs_kind_set, particle_set=particle_set, &
644 natom =
SIZE(particle_set)
645 total_grid_npts =
SIZE(ri_rs_grid_points, 2)
648 ALLOCATE (first_sgf(natom + 1))
656 ALLOCATE (c_blk_sizes(natom))
658 c_blk_sizes(iatom) = first_sgf(iatom + 1) - first_sgf(iatom)
665 CALL get_qs_env(qs_env, dbcsr_dist=dbcsr_dist_ks)
669 safe_max = int(0.5_dp*real(dbcsr_msg_elem_limit,
dp)*real(max(min(nprow, npcol), 1),
dp)/ &
670 REAL(total_grid_npts,
dp))
671 safe_max = max(1, safe_max)
679 run = bs_env%ri_rs%grid_atom_boundaries(ia + 1) - bs_env%ri_rs%grid_atom_boundaries(ia)
680 IF (run > 0) num_grid_chunks = num_grid_chunks + (run + bs_eff - 1)/bs_eff
682 ALLOCATE (r_blk_sizes(num_grid_chunks), blk_row_start(num_grid_chunks))
686 remaining = bs_env%ri_rs%grid_atom_boundaries(ia + 1) - bs_env%ri_rs%grid_atom_boundaries(ia)
687 DO WHILE (remaining > 0)
689 r_blk_sizes(i_blk) = min(bs_eff, remaining)
690 blk_row_start(i_blk) = r_start
691 r_start = r_start + r_blk_sizes(i_blk)
692 remaining = remaining - r_blk_sizes(i_blk)
696 IF (bs_env%unit_nr > 0)
THEN
697 WRITE (bs_env%unit_nr,
'(T2,A,T69,I12)')
'RI-RS grid row-blocks of phi(mu,l)', num_grid_chunks
698 WRITE (bs_env%unit_nr,
'(T2,A,T69,I12)')
'RI-RS grid points per block (max)', bs_eff
703 IF (
ALLOCATED(bs_env%ri_rs%atom_centers))
DEALLOCATE (bs_env%ri_rs%atom_centers)
704 ALLOCATE (bs_env%ri_rs%atom_centers(3, natom))
706 bs_env%ri_rs%atom_centers(1:3, iatom) = particle_set(iatom)%r(1:3)
710 IF (bs_env%ri_rs%cutoff_radius_v_w > 0.0_dp)
THEN
711 IF (
ALLOCATED(bs_env%ri_rs%chunk_centroids))
DEALLOCATE (bs_env%ri_rs%chunk_centroids)
712 ALLOCATE (bs_env%ri_rs%chunk_centroids(3, num_grid_chunks))
713 DO i_blk = 1, num_grid_chunks
714 r_start = blk_row_start(i_blk)
715 r_end = r_start + r_blk_sizes(i_blk) - 1
716 bs_env%ri_rs%chunk_centroids(1, i_blk) = &
717 sum(ri_rs_grid_points(1, r_start:r_end))/real(r_blk_sizes(i_blk),
dp)
718 bs_env%ri_rs%chunk_centroids(2, i_blk) = &
719 sum(ri_rs_grid_points(2, r_start:r_end))/real(r_blk_sizes(i_blk),
dp)
720 bs_env%ri_rs%chunk_centroids(3, i_blk) = &
721 sum(ri_rs_grid_points(3, r_start:r_end))/real(r_blk_sizes(i_blk),
dp)
727 ALLOCATE (row_dist(num_grid_chunks))
728 DO i = 1, num_grid_chunks
729 row_dist(i) = mod(i - 1, nprow)
732 ALLOCATE (col_dist(natom))
734 col_dist(i) = mod(i - 1, npcol)
739 row_dist=row_dist, col_dist=col_dist)
741 CALL dbcsr_create(mat_phi_mu_l, name=
"phi_val_sparse", dist=dist, &
742 matrix_type=dbcsr_type_no_symmetry, &
743 row_blk_size=r_blk_sizes, col_blk_size=c_blk_sizes)
749 DO iatom = para_env%mepos + 1, natom, para_env%num_pe
751 c_size = c_blk_sizes(iatom)
754 ALLOCATE (atom_col_buffer(total_grid_npts, c_size))
755 atom_col_buffer = 0.0_dp
761 IF (bs_env%ri_rs%cutoff_radius_ri_ao > 0.0_dp)
THEN
762 r2_threshold = bs_env%ri_rs%cutoff_radius_ri_ao**2
764 r2_threshold = bs_env%ri_rs%radius_ao_per_atom(iatom)**2
766 CALL fill_phi_for_atom(atom_col_buffer, ri_rs_grid_points, total_grid_npts, &
767 iatom, particle_set, qs_kind_set, cell, r2_threshold)
770 DO i_blk = 1, num_grid_chunks
771 r_start = blk_row_start(i_blk)
772 r_end = r_start + r_blk_sizes(i_blk) - 1
775 IF (maxval(abs(atom_col_buffer(r_start:r_end, 1:c_size))) > bs_env%eps_filter)
THEN
777 block=atom_col_buffer(r_start:r_end, 1:c_size))
781 DEALLOCATE (atom_col_buffer)
787 CALL print_matrix_occupation(mat_phi_mu_l, φμ
'(,l)', para_env, bs_env%unit_nr)
792 DEALLOCATE (first_sgf, r_blk_sizes, c_blk_sizes, row_dist, col_dist, blk_row_start)
795 CALL timestop(handle)
816 SUBROUTINE fill_phi_for_atom(phi_val, ri_rs_grid, npts, iatom, &
817 particle_set, qs_kind_set, cell, r2_threshold)
819 REAL(kind=
dp),
INTENT(INOUT) :: phi_val(:, :)
820 INTEGER,
INTENT(IN) :: npts
821 REAL(kind=
dp),
INTENT(IN) :: ri_rs_grid(3, npts)
822 INTEGER,
INTENT(IN) :: iatom
824 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
826 REAL(kind=
dp),
INTENT(IN) :: r2_threshold
828 CHARACTER(LEN=*),
PARAMETER :: routinen =
'fill_phi_for_atom'
830 INTEGER :: first_sgf, handle, i_pt, ico, iend_co, &
831 ikind, ipgf, iset, isgf, ishell, &
832 istart_co, l, last_sgf, lx, ly, lz, &
833 n_cart_total, row_idx
834 REAL(kind=
dp) :: alpha, dist_vec(3), exp_val, poly, r2, &
838 CALL timeset(routinen, handle)
841 ikind = particle_set(iatom)%atomic_kind%kind_number
842 CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, basis_type=
"ORB")
843 IF (.NOT.
ASSOCIATED(orb_basis_set))
THEN
844 CALL timestop(handle)
848 r_atom = particle_set(iatom)%r
858 dist_vec =
pbc(ri_rs_grid(:, i_pt) - r_atom, cell)
859 r2 = dot_product(dist_vec, dist_vec)
860 IF (r2 > r2_threshold) cycle
862 DO iset = 1, orb_basis_set%nset
863 n_cart_total =
ncoset(orb_basis_set%lmax(iset))
865 DO ishell = 1, orb_basis_set%nshell(iset)
866 l = orb_basis_set%l(ishell, iset)
867 istart_co =
ncoset(l - 1) + 1
870 first_sgf = orb_basis_set%first_sgf(ishell, iset)
871 last_sgf = orb_basis_set%last_sgf(ishell, iset)
873 DO ipgf = 1, orb_basis_set%npgf(iset)
874 alpha = orb_basis_set%zet(ipgf, iset)
875 exp_val = exp(-alpha*r2)
877 DO isgf = first_sgf, last_sgf
878 DO ico = istart_co, iend_co
879 row_idx = (ipgf - 1)*n_cart_total + ico
880 weight = orb_basis_set%sphi(row_idx, isgf)
884 poly = (dist_vec(1)**lx)*(dist_vec(2)**ly)*(dist_vec(3)**lz)
886 phi_val(i_pt, isgf) = phi_val(i_pt, isgf) + (weight*poly*exp_val)
896 CALL timestop(handle)
898 END SUBROUTINE fill_phi_for_atom
912 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
913 INTEGER,
INTENT(OUT) :: first_sgf(:), total_sgf
915 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_basis_offsets'
917 INTEGER :: handle, iatom, ikind, nsgf
919 CALL timeset(routinen, handle)
922 DO iatom = 1,
SIZE(particle_set)
923 first_sgf(iatom) = total_sgf + 1
924 ikind = particle_set(iatom)%atomic_kind%kind_number
925 CALL get_qs_kind(qs_kind_set(ikind), nsgf=nsgf, basis_type=
"ORB")
926 total_sgf = total_sgf + nsgf
928 first_sgf(
SIZE(particle_set) + 1) = total_sgf + 1
930 CALL timestop(handle)
960 REAL(kind=
dp),
ALLOCATABLE,
INTENT(INOUT) :: ri_rs_grid_points(:, :)
961 TYPE(
dbcsr_type),
INTENT(INOUT) :: mat_phi_mu_l
964 CHARACTER(LEN=*),
PARAMETER :: key =
'PROPERTIES%BANDSTRUCTURE%GW%PRINT%RESTART', &
965 routinen =
'compute_coeff_Z_lP'
967 INTEGER :: atom_j_mepos, atom_j_stride, atom_p, g, handle, handle_dpotrf, handle_dpotrs, &
968 i_blk,
idx, info, iphase, j, max_ao_size, my_group, n_ao_total, n_big, n_done, &
969 n_groups, n_loc_ri, n_local_grid, n_my_atoms, n_small, natom, next_pct, &
970 npcol_phi, num_grid_chunks, p_loop_atom, phase_hi
971 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: big_list, local_grid_idx, &
972 my_atoms_a, my_atoms_b, &
973 n_local_grid_atom, row_offset, small_list
974 INTEGER,
DIMENSION(:),
POINTER :: col_dist_ri, r_blk_sizes, &
975 ri_blk_sizes, row_dist_grid
976 LOGICAL :: do_scatter, use_dist
977 REAL(kind=
dp) :: balance_a, balance_b, cutoff_ri, r_c, t1
978 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cutoff_ri_per_atom, d_vec_local
979 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: d_local, d_lp_local, phi_local
990 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
993 CALL timeset(routinen, handle)
997 CALL get_qs_env(qs_env, para_env=para_env, particle_set=particle_set, input=input, &
998 qs_kind_set=qs_kind_set, cell=cell, atomic_kind_set=atomic_kind_set)
1000 NULLIFY (para_env_sub, blacs_env_sub)
1002 natom =
SIZE(bs_env%i_RI_start_from_atom)
1003 n_ao_total = bs_env%i_ao_end_from_atom(natom)
1010 CALL dbcsr_get_info(mat_phi_mu_l, row_blk_size=r_blk_sizes, distribution=dist_phi)
1013 num_grid_chunks =
SIZE(r_blk_sizes)
1015 ALLOCATE (row_offset(num_grid_chunks))
1017 DO i_blk = 2, num_grid_chunks
1018 row_offset(i_blk) = row_offset(i_blk - 1) + r_blk_sizes(i_blk - 1)
1021 ALLOCATE (ri_blk_sizes(natom), col_dist_ri(natom))
1022 DO atom_p = 1, natom
1023 ri_blk_sizes(atom_p) = bs_env%i_RI_end_from_atom(atom_p) - bs_env%i_RI_start_from_atom(atom_p) + 1
1024 col_dist_ri(atom_p) = mod(atom_p - 1, npcol_phi)
1029 IF (bs_env%ri_rs%Z_lP_exists)
THEN
1031 distribution=dist_z, &
1032 matrix_new=mat_z_lp)
1033 IF (bs_env%unit_nr > 0)
THEN
1034 WRITE (bs_env%unit_nr,
'(T2,A,T57,A,F7.1,A)') &
1035 'Read Z_lP from file ',
' Execution time',
m_walltime() - t1,
' s'
1039 WRITE (bs_env%unit_nr,
'(T2,A)') &
1040 '*** NOTE: Z_lP restart must match the current (spatial) grid row ordering ***'
1041 WRITE (bs_env%unit_nr,
'(A)')
' '
1045 CALL dbcsr_create(mat_z_lp, name=
"mat_Z_lP", dist=dist_z, &
1046 matrix_type=dbcsr_type_no_symmetry, &
1047 row_blk_size=r_blk_sizes, col_blk_size=ri_blk_sizes)
1051 DO j = 1,
SIZE(bs_env%i_ao_start_from_atom)
1052 max_ao_size = max(max_ao_size, bs_env%i_ao_end_from_atom(j) - bs_env%i_ao_start_from_atom(j) + 1)
1060 ALLOCATE (cutoff_ri_per_atom(natom))
1062 IF (bs_env%ri_rs%cutoff_radius_ri_rs > 0.0_dp)
THEN
1063 cutoff_ri_per_atom(:) = bs_env%ri_rs%cutoff_radius_ri_rs
1065 r_c = bs_env%ri_metric%cutoff_radius
1066 DO p_loop_atom = 1, natom
1067 cutoff_ri_per_atom(p_loop_atom) = &
1068 r_c + bs_env%ri_rs%radius_ri_per_atom(p_loop_atom)
1072 CALL print_sphere_cutoff_table(bs_env, atomic_kind_set, particle_set, cutoff_ri_per_atom)
1080 CALL classify_z_lp_atoms(bs_env, para_env, ri_rs_grid_points, particle_set, &
1081 cutoff_ri_per_atom, ri_blk_sizes, n_ao_total, &
1082 n_local_grid_atom, small_list, n_small, big_list, n_big, g)
1087 CALL lpt_assign_atoms(small_list, n_small, n_local_grid_atom, para_env%num_pe, &
1088 para_env%mepos, my_atoms_a, balance_a)
1090 n_groups = para_env%num_pe/g
1091 my_group = min(para_env%mepos/g, n_groups - 1)
1092 CALL lpt_assign_atoms(big_list, n_big, n_local_grid_atom, n_groups, my_group, &
1093 my_atoms_b, balance_b)
1095 ALLOCATE (my_atoms_b(0))
1100 n_my_atoms =
SIZE(my_atoms_a) +
SIZE(my_atoms_b)
1104 IF (bs_env%unit_nr > 0)
THEN
1105 WRITE (bs_env%unit_nr,
'(T2,A,I7,A,I8,A)') &
1106 'RI-RS Z_lP solver: ', n_small,
' atoms single-rank (BLAS), ', n_big, &
1107 ' atoms distributed'
1108 IF (n_small > 0)
WRITE (bs_env%unit_nr,
'(T4,A,F18.2)') &
1109 'estimated single-rank load balance (max/mean cost per rank)', balance_a
1111 WRITE (bs_env%unit_nr,
'(T4,A,I44,A)') &
1112 'distributed subgroup size G', g,
' ranks'
1113 WRITE (bs_env%unit_nr,
'(T4,A,F17.2)') &
1114 'estimated distributed load balance (max/mean cost per group)', balance_b
1116 WRITE (bs_env%unit_nr,
'(A)')
' '
1121 basis_j=bs_env%basis_set_AO, basis_k=bs_env%basis_set_AO, &
1122 basis_i=bs_env%basis_set_RI)
1132 IF (iphase == 1)
THEN
1136 phase_hi =
SIZE(my_atoms_a)
1138 IF (n_big == 0) cycle
1140 n_groups = para_env%num_pe/g
1141 my_group = min(para_env%mepos/g, n_groups - 1)
1142 ALLOCATE (para_env_sub)
1143 CALL para_env_sub%from_split(para_env, my_group)
1145 atom_j_mepos = para_env_sub%mepos
1146 atom_j_stride = para_env_sub%num_pe
1149 phase_hi =
SIZE(my_atoms_b)
1152 DO idx = 1, phase_hi
1153 IF (iphase == 1)
THEN
1154 atom_p = my_atoms_a(
idx)
1156 atom_p = my_atoms_b(
idx)
1159 n_loc_ri = ri_blk_sizes(atom_p)
1160 cutoff_ri = cutoff_ri_per_atom(atom_p)
1167 CALL build_phi_on_sphere(bs_env, particle_set, qs_kind_set, cell, &
1168 ri_rs_grid_points, atom_p, cutoff_ri, n_ao_total, &
1169 local_grid_idx, n_local_grid, phi_local)
1174 ALLOCATE (d_lp_local(n_local_grid, n_loc_ri))
1177 CALL compute_d_lp(bs_env, ctx_3c, phi_local, d_lp_local, n_local_grid, &
1178 n_loc_ri, atom_p, max_ao_size, atom_j_mepos, atom_j_stride)
1183 CALL para_env_sub%sum(d_lp_local)
1190 ALLOCATE (d_vec_local(n_local_grid))
1192 IF (.NOT. use_dist)
THEN
1193 CALL build_gram_jacobi_blas(phi_local, n_local_grid, n_ao_total, &
1194 bs_env%ri_rs%tikhonov, d_local, d_vec_local)
1199 CALL build_jacobi_diag_from_phi(phi_local, n_local_grid, n_ao_total, &
1206 CALL scale_rows_by_diag(d_lp_local, d_vec_local, n_local_grid, n_loc_ri)
1212 IF (.NOT. use_dist)
THEN
1213 CALL timeset(routinen//
"_dpotrf", handle_dpotrf)
1214 CALL dpotrf(
'L', n_local_grid, d_local, n_local_grid, info)
1215 CALL timestop(handle_dpotrf)
1216 CALL timeset(routinen//
"_dpotrs", handle_dpotrs)
1217 CALL dpotrs(
'L', n_local_grid, n_loc_ri, d_local, n_local_grid, &
1218 d_lp_local, n_local_grid, info)
1219 CALL timestop(handle_dpotrs)
1220 DEALLOCATE (d_local)
1223 n_local_grid, n_ao_total, n_loc_ri, &
1224 bs_env%ri_rs%tikhonov, &
1225 para_env_sub, blacs_env_sub, &
1226 fm_struct_d, fm_struct_b, fm_d, fm_b, info)
1232 CALL scale_rows_by_diag(d_lp_local, d_vec_local, n_local_grid, n_loc_ri)
1238 IF (use_dist) do_scatter = (para_env_sub%mepos == 0)
1239 IF (do_scatter)
THEN
1240 CALL scatter_z_columns(mat_z_lp, d_lp_local, local_grid_idx, n_local_grid, &
1241 n_loc_ri, atom_p, r_blk_sizes, row_offset, &
1245 DEALLOCATE (d_vec_local, d_lp_local)
1246 DEALLOCATE (local_grid_idx, phi_local)
1250 IF (bs_env%unit_nr > 0 .AND. n_my_atoms > 0)
THEN
1251 DO WHILE (next_pct <= 100 .AND. n_done*100 >= next_pct*n_my_atoms)
1252 WRITE (bs_env%unit_nr,
'(T2,A,I57,A)')
'Computing Z_lP:', next_pct,
' % done'
1253 next_pct = next_pct + 25
1259 IF (iphase == 2)
THEN
1261 CALL para_env_sub%free()
1262 DEALLOCATE (para_env_sub)
1266 DEALLOCATE (cutoff_ri_per_atom)
1267 DEALLOCATE (small_list, big_list)
1273 CALL print_matrix_occupation(mat_z_lp,
'Z(l,P)', para_env, bs_env%unit_nr)
1275 IF (bs_env%unit_nr > 0)
THEN
1276 WRITE (bs_env%unit_nr,
'(A)')
' '
1277 WRITE (bs_env%unit_nr,
'(T2,A,T57,A,F7.1,A)') &
1278 'Computed Z_lP ',
' Execution time',
m_walltime() - t1,
' s'
1279 WRITE (bs_env%unit_nr,
'(A)')
' '
1285 CALL dbcsr_binary_write(matrix=mat_z_lp, filepath=trim(bs_env%prefix)//
"Z_lP.matrix")
1290 DEALLOCATE (row_offset, ri_blk_sizes, col_dist_ri)
1293 DEALLOCATE (ri_rs_grid_points)
1295 CALL timestop(handle)
1306 SUBROUTINE print_sphere_cutoff_table(bs_env, atomic_kind_set, particle_set, cutoff_ri_per_atom)
1311 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: cutoff_ri_per_atom
1312 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_sphere_cutoff_table'
1316 INTEGER :: iatom, ikind, nkind
1317 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cutoff_ri_per_kind
1319 CALL timeset(routinen, handle)
1321 IF (bs_env%unit_nr <= 0)
THEN
1322 CALL timestop(handle)
1326 nkind =
SIZE(atomic_kind_set)
1327 ALLOCATE (cutoff_ri_per_kind(nkind))
1328 cutoff_ri_per_kind(:) = 0.0_dp
1330 DO iatom = 1,
SIZE(particle_set)
1331 ikind = particle_set(iatom)%atomic_kind%kind_number
1332 cutoff_ri_per_kind(ikind) = max(cutoff_ri_per_kind(ikind), cutoff_ri_per_atom(iatom))
1335 WRITE (bs_env%unit_nr,
'(T2,A)') Å
'Per-kind maximum RI-RS sphere cutoff ():'
1336 WRITE (bs_env%unit_nr,
'(T4,A4,A14)')
'Kind', Å
'cutoff ()'
1338 WRITE (bs_env%unit_nr,
'(T4,A4,F14.4)') &
1339 atomic_kind_set(ikind)%element_symbol, &
1342 WRITE (bs_env%unit_nr,
'(A)')
' '
1344 DEALLOCATE (cutoff_ri_per_kind)
1346 CALL timestop(handle)
1348 END SUBROUTINE print_sphere_cutoff_table
1380 SUBROUTINE classify_z_lp_atoms(bs_env, para_env, ri_rs_grid_points, particle_set, &
1381 cutoff_ri_per_atom, ri_blk_sizes, n_ao_total, &
1382 n_local_grid_atom, small_list, n_small, big_list, n_big, G)
1388 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: ri_rs_grid_points
1391 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: cutoff_ri_per_atom
1392 INTEGER,
DIMENSION(:),
INTENT(IN) :: ri_blk_sizes
1393 INTEGER,
INTENT(IN) :: n_ao_total
1394 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: n_local_grid_atom, small_list, big_list
1395 INTEGER,
INTENT(OUT) :: n_small, n_big, g
1396 CHARACTER(LEN=*),
PARAMETER :: routinen =
'classify_z_lp_atoms'
1401 REAL(kind=
dp),
PARAMETER :: mem_safety = 0.8_dp
1405 REAL(kind=
dp),
PARAMETER :: scalapack_loc_limit = 2.0e9_dp
1407 INTEGER :: g_atom, g_int32, g_int32_max, l, &
1408 n_grid_total, n_local_grid, natom, &
1409 nthreads_cls, p_loop_atom
1410 LOGICAL :: auto_mode
1411 REAL(kind=
dp) :: budget_bytes, cutoff_ri, dlp_bytes, &
1412 mem_avail_gb, ng, nri, peak_bytes, &
1414 REAL(kind=
dp),
DIMENSION(3) :: pos_p
1416 CALL timeset(routinen, handle)
1418 natom =
SIZE(particle_set)
1419 n_grid_total =
SIZE(ri_rs_grid_points, 2)
1424 ALLOCATE (n_local_grid_atom(natom), small_list(natom), big_list(natom))
1425 DO p_loop_atom = 1, natom
1426 pos_p(:) = particle_set(p_loop_atom)%r(:)
1427 cutoff_ri = cutoff_ri_per_atom(p_loop_atom)
1429 DO l = 1, n_grid_total
1430 IF (sum((ri_rs_grid_points(1:3, l) - pos_p(1:3))**2) <= cutoff_ri**2)
then
1431 n_local_grid = n_local_grid + 1
1434 n_local_grid_atom(p_loop_atom) = n_local_grid
1442 auto_mode = (bs_env%ri_rs%n_procs_per_atom_z_lp <= 0)
1443 CALL ri_rs_mem_avail_per_proc_gb(bs_env, mem_avail_gb)
1444 budget_bytes = mem_safety*mem_avail_gb*1.0e9_dp
1451 IF (bs_env%ri_rs%n_procs_per_atom_z_lp == 1)
THEN
1453 DO p_loop_atom = 1, natom
1454 n_small = n_small + 1
1455 small_list(n_small) = p_loop_atom
1457 ELSE IF (mem_avail_gb <= 0.0_dp)
THEN
1460 IF (bs_env%unit_nr > 0)
then
1461 cpwarn(
"RI-RS Z_lP: no meminfo; single-rank solve for all atoms")
1463 DO p_loop_atom = 1, natom
1464 n_small = n_small + 1
1465 small_list(n_small) = p_loop_atom
1469 DO p_loop_atom = 1, natom
1470 ng = real(n_local_grid_atom(p_loop_atom),
dp)
1471 g_int32_max = max(g_int32_max, ceiling(ng*ng/scalapack_loc_limit))
1473 big_list(n_big) = p_loop_atom
1475 g = min(bs_env%ri_rs%n_procs_per_atom_z_lp, para_env%num_pe)
1476 IF (g < g_int32_max)
THEN
1477 g = min(g_int32_max, para_env%num_pe)
1478 IF (bs_env%unit_nr > 0)
then
1479 cpwarn(
"RI-RS Z_lP: raised G to avoid ScaLAPACK overflow")
1486 DO p_loop_atom = 1, natom
1487 ng = real(n_local_grid_atom(p_loop_atom),
dp)
1488 nri = real(ri_blk_sizes(p_loop_atom),
dp)
1489 phi_bytes = 8.0_dp*ng*real(n_ao_total,
dp)
1490 dlp_bytes = 8.0_dp*ng*nri*real(1 + nthreads_cls,
dp)
1491 peak_bytes = 8.0_dp*ng*ng + phi_bytes + dlp_bytes
1492 IF (peak_bytes <= budget_bytes)
THEN
1493 n_small = n_small + 1
1494 small_list(n_small) = p_loop_atom
1497 big_list(n_big) = p_loop_atom
1500 g_int32 = ceiling(ng*ng/scalapack_loc_limit)
1501 g_int32_max = max(g_int32_max, g_int32)
1502 g_atom = max(g_atom, g_int32, &
1503 ceiling(8.0_dp*ng*ng/max(budget_bytes - phi_bytes - dlp_bytes, 1.0_dp)))
1509 IF (g_atom > para_env%num_pe)
THEN
1510 IF (bs_env%unit_nr > 0)
THEN
1511 WRITE (bs_env%unit_nr,
'(T2,A)') &
1512 'RI-RS Z_lP: an atom is too large to fit even distributed over all '// &
1513 'ranks. Add nodes, use fewer MPI ranks/node, lower CUTOFF_RADIUS_RL_RI, '// &
1514 'or raise EPS_FILTER (more grid screening).'
1516 cpabort(
"RI-RS Z_lP: atom too large even fully distributed")
1518 g = min(max(g_atom, 2), para_env%num_pe)
1522 g = min(bs_env%ri_rs%n_procs_per_atom_z_lp, para_env%num_pe)
1523 IF (g < g_int32_max)
THEN
1524 g = min(g_int32_max, para_env%num_pe)
1525 IF (bs_env%unit_nr > 0)
then
1526 cpwarn(
"RI-RS Z_lP: raised G to avoid ScaLAPACK overflow")
1528 ELSE IF (g < g_atom .AND. bs_env%unit_nr > 0)
THEN
1529 cpwarn(
"RI-RS Z_lP: N_PROCS_PER_ATOM_Z_LP too small for the largest atom")
1535 CALL timestop(handle)
1537 END SUBROUTINE classify_z_lp_atoms
1553 SUBROUTINE build_phi_on_sphere(bs_env, particle_set, qs_kind_set, cell, ri_rs_grid_points, &
1554 atom_P, cutoff_ri, n_ao_total, local_grid_idx, n_local_grid, &
1559 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
1561 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: ri_rs_grid_points
1562 INTEGER,
INTENT(IN) :: atom_p
1563 REAL(kind=
dp),
INTENT(IN) :: cutoff_ri
1564 INTEGER,
INTENT(IN) :: n_ao_total
1565 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: local_grid_idx
1566 INTEGER,
INTENT(OUT) :: n_local_grid
1567 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :), &
1568 INTENT(OUT) :: phi_local
1570 CHARACTER(LEN=*),
PARAMETER :: routinen =
'build_phi_on_sphere'
1572 INTEGER :: col_end, col_start, handle, j, k, l, &
1573 loc_idx, n_grid_total, n_keep, &
1575 REAL(kind=
dp) :: d_sp, dist, r2_threshold
1576 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: w_pt
1577 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: phi_keep, sphere_grid
1578 REAL(kind=
dp),
DIMENSION(3) :: pos_p
1580 CALL timeset(routinen, handle)
1582 n_grid_total =
SIZE(ri_rs_grid_points, 2)
1583 pos_p(:) = particle_set(atom_p)%r(:)
1586 DO l = 1, n_grid_total
1587 dist = sqrt(sum((ri_rs_grid_points(1:3, l) - pos_p(1:3))**2))
1588 IF (dist <= cutoff_ri) n_local_grid = n_local_grid + 1
1591 ALLOCATE (local_grid_idx(n_local_grid))
1594 DO l = 1, n_grid_total
1595 dist = sqrt(sum((ri_rs_grid_points(1:3, l) - pos_p(1:3))**2))
1596 IF (dist <= cutoff_ri)
THEN
1597 n_local_grid = n_local_grid + 1
1598 local_grid_idx(n_local_grid) = l
1602 ALLOCATE (sphere_grid(3, n_local_grid))
1603 DO loc_idx = 1, n_local_grid
1604 sphere_grid(:, loc_idx) = ri_rs_grid_points(:, local_grid_idx(loc_idx))
1607 ALLOCATE (phi_local(n_local_grid, n_ao_total))
1610 DO source_atom = 1,
SIZE(particle_set)
1611 d_sp = norm2(particle_set(source_atom)%r(:) - pos_p(:))
1612 IF (d_sp > bs_env%ri_rs%radius_ao_per_atom(source_atom) + cutoff_ri) cycle
1614 col_start = bs_env%i_ao_start_from_atom(source_atom)
1615 col_end = bs_env%i_ao_end_from_atom(source_atom)
1618 IF (bs_env%ri_rs%cutoff_radius_ri_ao > 0.0_dp)
THEN
1619 r2_threshold = bs_env%ri_rs%cutoff_radius_ri_ao**2
1621 r2_threshold = bs_env%ri_rs%radius_ao_per_atom(source_atom)**2
1624 CALL fill_phi_for_atom(phi_local(:, col_start:col_end), sphere_grid, &
1625 n_local_grid, source_atom, particle_set, qs_kind_set, &
1629 DEALLOCATE (sphere_grid)
1631 IF (n_local_grid > 0)
THEN
1632 ALLOCATE (w_pt(n_local_grid))
1636 DO l = 1, n_local_grid
1638 DO j = 1, n_ao_total
1639 w_pt(l) = max(w_pt(l), abs(phi_local(l, j)))
1643 n_keep = count(w_pt > bs_env%eps_filter)
1644 IF (n_keep < n_local_grid)
THEN
1645 ALLOCATE (phi_keep(n_keep, n_ao_total))
1647 DO l = 1, n_local_grid
1648 IF (w_pt(l) > bs_env%eps_filter)
THEN
1650 phi_keep(k, :) = phi_local(l, :)
1651 local_grid_idx(k) = local_grid_idx(l)
1654 CALL move_alloc(phi_keep, phi_local)
1655 n_local_grid = n_keep
1660 CALL timestop(handle)
1662 END SUBROUTINE build_phi_on_sphere
1678 SUBROUTINE build_gram_jacobi_blas(phi_local, n_local_grid, n_ao_total, tikhonov, D_local, &
1681 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: phi_local
1682 INTEGER,
INTENT(IN) :: n_local_grid, n_ao_total
1683 REAL(kind=
dp),
INTENT(IN) :: tikhonov
1684 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :), &
1685 INTENT(OUT) :: d_local
1686 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: d_vec_local
1688 CHARACTER(LEN=*),
PARAMETER :: routinen =
'build_gram_jacobi_blas'
1690 INTEGER :: handle, handle_dsyrk, i, j
1692 CALL timeset(routinen, handle)
1694 ALLOCATE (d_local(n_local_grid, n_local_grid))
1698 CALL timeset(routinen//
"_dsyrk", handle_dsyrk)
1699 CALL dsyrk(
"L",
"N", n_local_grid, n_ao_total, 1.0_dp, phi_local, &
1700 n_local_grid, 0.0_dp, d_local, n_local_grid)
1701 CALL timestop(handle_dsyrk)
1708 DO i = 1, n_local_grid
1709 d_local(i, i) = d_local(i, i)**2
1710 d_vec_local(i) = 1.0_dp/sqrt(max(d_local(i, i), 1.0e-16_dp))
1711 d_local(i, i) = (d_local(i, i)*d_vec_local(i)**2) + tikhonov
1720 DO j = 1, n_local_grid
1721 DO i = j + 1, n_local_grid
1722 d_local(i, j) = d_local(i, j)**2
1723 d_local(i, j) = d_local(i, j)*d_vec_local(i)*d_vec_local(j)
1724 d_local(j, i) = d_local(i, j)
1729 CALL timestop(handle)
1731 END SUBROUTINE build_gram_jacobi_blas
1742 SUBROUTINE build_jacobi_diag_from_phi(phi_local, n_local_grid, n_ao_total, d_vec_local)
1744 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: phi_local
1745 INTEGER,
INTENT(IN) :: n_local_grid, n_ao_total
1746 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: d_vec_local
1747 CHARACTER(LEN=*),
PARAMETER :: routinen =
'build_jacobi_diag_from_phi'
1753 CALL timeset(routinen, handle)
1759 DO i = 1, n_local_grid
1760 d_vec_local(i) = 0.0_dp
1761 DO j = 1, n_ao_total
1762 d_vec_local(i) = d_vec_local(i) + phi_local(i, j)*phi_local(i, j)
1764 d_vec_local(i) = 1.0_dp/max(d_vec_local(i), 1.0e-16_dp)
1768 CALL timestop(handle)
1770 END SUBROUTINE build_jacobi_diag_from_phi
1781 SUBROUTINE scale_rows_by_diag(d_lp_local, d_vec_local, n_local_grid, n_loc_ri)
1783 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: d_lp_local
1784 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: d_vec_local
1785 INTEGER,
INTENT(IN) :: n_local_grid, n_loc_ri
1786 CHARACTER(LEN=*),
PARAMETER :: routinen =
'scale_rows_by_diag'
1792 CALL timeset(routinen, handle)
1798 DO j_ri = 1, n_loc_ri
1799 DO i = 1, n_local_grid
1800 d_lp_local(i, j_ri) = d_lp_local(i, j_ri)*d_vec_local(i)
1805 CALL timestop(handle)
1807 END SUBROUTINE scale_rows_by_diag
1822 SUBROUTINE scatter_z_columns(mat_Z_lP, d_lp_local, local_grid_idx, n_local_grid, n_loc_ri, &
1823 atom_P, r_blk_sizes, row_offset, eps_filter)
1826 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: d_lp_local
1827 INTEGER,
DIMENSION(:),
INTENT(IN) :: local_grid_idx
1828 INTEGER,
INTENT(IN) :: n_local_grid, n_loc_ri, atom_p
1829 INTEGER,
DIMENSION(:),
INTENT(IN) :: r_blk_sizes, row_offset
1830 REAL(kind=
dp),
INTENT(IN) :: eps_filter
1831 CHARACTER(LEN=*),
PARAMETER :: routinen =
'scatter_z_columns'
1834 INTEGER :: current_chunk_size, g_pt, i_blk, &
1835 loc_ptr, r_end, r_start
1836 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: z_blk
1838 CALL timeset(routinen, handle)
1840 ALLOCATE (z_blk(maxval(r_blk_sizes), n_loc_ri))
1843 DO i_blk = 1,
SIZE(r_blk_sizes)
1844 r_start = row_offset(i_blk) + 1
1845 r_end = row_offset(i_blk) + r_blk_sizes(i_blk)
1846 current_chunk_size = r_blk_sizes(i_blk)
1851 DO WHILE (loc_ptr <= n_local_grid)
1852 g_pt = local_grid_idx(loc_ptr)
1853 IF (g_pt > r_end)
EXIT
1854 z_blk(g_pt - r_start + 1, 1:n_loc_ri) = d_lp_local(loc_ptr, 1:n_loc_ri)
1855 loc_ptr = loc_ptr + 1
1858 IF (maxval(abs(z_blk(1:current_chunk_size, 1:n_loc_ri))) > eps_filter)
THEN
1860 block=z_blk(1:current_chunk_size, 1:n_loc_ri))
1866 CALL timestop(handle)
1868 END SUBROUTINE scatter_z_columns
1883 SUBROUTINE lpt_assign_atoms(atom_list, n_atoms, n_local_grid_atom, n_workers, my_worker, &
1884 my_atoms, max_over_mean)
1886 INTEGER,
DIMENSION(:),
INTENT(IN) :: atom_list
1887 INTEGER,
INTENT(IN) :: n_atoms
1888 INTEGER,
DIMENSION(:),
INTENT(IN) :: n_local_grid_atom
1889 INTEGER,
INTENT(IN) :: n_workers, my_worker
1890 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: my_atoms
1891 REAL(kind=
dp),
INTENT(OUT) :: max_over_mean
1892 CHARACTER(LEN=*),
PARAMETER :: routinen =
'lpt_assign_atoms'
1895 INTEGER :: i, iw, n_mine, w_min
1896 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: mine_tmp, perm
1897 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cost, load
1899 CALL timeset(routinen, handle)
1901 max_over_mean = 1.0_dp
1902 IF (n_atoms <= 0)
THEN
1903 ALLOCATE (my_atoms(0))
1904 CALL timestop(handle)
1908 ALLOCATE (cost(n_atoms), perm(n_atoms), mine_tmp(n_atoms), load(n_workers))
1910 cost(i) = real(n_local_grid_atom(atom_list(i)),
dp)**3
1912 CALL sort(cost, n_atoms, perm)
1916 DO i = n_atoms, 1, -1
1918 DO iw = 2, n_workers
1919 IF (load(iw) < load(w_min)) w_min = iw
1921 load(w_min) = load(w_min) + cost(i)
1922 IF (w_min - 1 == my_worker)
THEN
1924 mine_tmp(n_mine) = atom_list(perm(i))
1928 ALLOCATE (my_atoms(n_mine))
1929 my_atoms(:) = mine_tmp(1:n_mine)
1930 IF (sum(load) > 0.0_dp) max_over_mean = maxval(load)*real(n_workers,
dp)/sum(load)
1932 CALL timestop(handle)
1934 END SUBROUTINE lpt_assign_atoms
1953 SUBROUTINE compute_d_lp(bs_env, ctx, phi_val, d_lp, n_grid_total, n_loc_ri, atom_P, &
1954 max_ao_size, atom_j_mepos, atom_j_stride)
1958 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: phi_val
1959 INTEGER,
INTENT(IN) :: n_grid_total, n_loc_ri
1960 REAL(kind=
dp),
INTENT(INOUT) :: d_lp(n_grid_total, n_loc_ri)
1961 INTEGER,
INTENT(IN) :: atom_p, max_ao_size, atom_j_mepos, &
1964 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_d_lp'
1965 INTEGER,
PARAMETER :: grid_chunk = 1024
1967 INTEGER :: atom_j, atom_k, c, handle, &
1968 handle_dgemm, j, jk_idx, &
1969 jsize, jstart, k, ksize, kstart, l, &
1972 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: d_lp_prv, int_2d_prv, rho_chunk
1973 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: int_3c_prv
1976 CALL timeset(routinen, handle)
1985 ALLOCATE (int_3c_prv(max_ao_size, max_ao_size, n_loc_ri))
1986 ALLOCATE (int_2d_prv(max_ao_size*max_ao_size, n_loc_ri))
1987 ALLOCATE (rho_chunk(grid_chunk, max_ao_size*max_ao_size))
1988 ALLOCATE (d_lp_prv(n_grid_total, n_loc_ri))
1989 d_lp_prv(:, :) = 0.0_dp
1995 DO atom_j = atom_j_mepos + 1,
SIZE(bs_env%i_ao_start_from_atom), atom_j_stride
1996 DO atom_k = 1,
SIZE(bs_env%i_ao_start_from_atom)
1997 jstart = bs_env%i_ao_start_from_atom(atom_j)
1998 jsize = bs_env%i_ao_end_from_atom(atom_j) - jstart + 1
1999 kstart = bs_env%i_ao_start_from_atom(atom_k)
2000 ksize = bs_env%i_ao_end_from_atom(atom_k) - kstart + 1
2002 int_3c_prv(1:jsize, 1:ksize, 1:n_loc_ri) = 0.0_dp
2007 ctx, ws, atom_j=atom_j, atom_k=atom_k, atom_i=atom_p, &
2016 jk_idx = (k - 1)*jsize + j
2017 int_2d_prv(jk_idx, ri) = int_3c_prv(j, k, ri)
2024 DO l0 = 1, n_grid_total, grid_chunk
2025 c = min(grid_chunk, n_grid_total - l0 + 1)
2028 jk_idx = (k - 1)*jsize + j
2030 rho_chunk(l, jk_idx) = phi_val(l0 + l - 1, jstart + j - 1)* &
2031 phi_val(l0 + l - 1, kstart + k - 1)
2035 CALL timeset(routinen//
"_dgemm", handle_dgemm)
2036 CALL dgemm(
"N",
"N", c, n_loc_ri, jsize*ksize, &
2037 1.0_dp, rho_chunk, grid_chunk, &
2038 int_2d_prv, max_ao_size*max_ao_size, &
2039 1.0_dp, d_lp_prv(l0, 1), n_grid_total)
2040 CALL timestop(handle_dgemm)
2047 d_lp(1:n_grid_total, 1:n_loc_ri) = d_lp(1:n_grid_total, 1:n_loc_ri) + &
2048 d_lp_prv(1:n_grid_total, 1:n_loc_ri)
2051 DEALLOCATE (int_3c_prv, int_2d_prv, rho_chunk, d_lp_prv)
2056 CALL timestop(handle)
2058 END SUBROUTINE compute_d_lp
2086 tikhonov, para_env_sub, blacs_env_sub, &
2087 fm_struct_D, fm_struct_b, fm_D, fm_b, info)
2089 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: phi_local
2090 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: d_vec
2091 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: d_lp
2092 INTEGER,
INTENT(IN) :: n_loc, n_ao, n_rhs
2093 REAL(kind=
dp),
INTENT(IN) :: tikhonov
2097 TYPE(
cp_fm_type),
INTENT(INOUT) :: fm_d, fm_b
2098 INTEGER,
INTENT(OUT) :: info
2100 CHARACTER(LEN=*),
PARAMETER :: routinen =
'solve_D_lp_distributed'
2102 INTEGER :: handle, i_loc, ig, j_loc, jg, &
2103 ncol_local, nrow_local
2104 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
2105 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
2106 POINTER :: local_data
2108 CALL timeset(routinen, handle)
2111 NULLIFY (fm_struct_d, fm_struct_b)
2113 context=blacs_env_sub, &
2114 nrow_global=n_loc, ncol_global=n_loc)
2116 context=blacs_env_sub, &
2117 nrow_global=n_loc, ncol_global=n_rhs)
2127 CALL cp_fm_get_info(fm_d, nrow_local=nrow_local, ncol_local=ncol_local, &
2128 row_indices=row_indices, col_indices=col_indices, &
2129 local_data=local_data)
2131 IF (nrow_local > 0 .AND. ncol_local > 0)
THEN
2133 INTEGER,
PARAMETER :: ntile = 1024
2134 INTEGER :: ib, ie, jb, je, mb, kb, ti, tj, handle_dgemm
2135 REAL(kind=
dp),
ALLOCATABLE :: gram_t(:, :), phi_cols_t(:, :), phi_rows_t(:, :)
2136 ALLOCATE (phi_rows_t(ntile, n_ao), phi_cols_t(n_ao, ntile), gram_t(ntile, ntile))
2137 DO ib = 1, nrow_local, ntile
2138 ie = min(ib + ntile - 1, nrow_local)
2145 phi_rows_t(ti, j_loc) = phi_local(row_indices(ib + ti - 1), j_loc)
2149 DO jb = 1, ncol_local, ntile
2150 je = min(jb + ntile - 1, ncol_local)
2157 phi_cols_t(i_loc, tj) = phi_local(col_indices(jb + tj - 1), i_loc)
2161 CALL timeset(routinen//
"_dgemm", handle_dgemm)
2162 CALL dgemm(
'N',
'N', mb, kb, n_ao, &
2163 1.0_dp, phi_rows_t, ntile, phi_cols_t, n_ao, &
2164 0.0_dp, gram_t, ntile)
2165 CALL timestop(handle_dgemm)
2171 jg = col_indices(jb + tj - 1)
2173 ig = row_indices(ib + ti - 1)
2174 local_data(ib + ti - 1, jb + tj - 1) = &
2175 gram_t(ti, tj)*gram_t(ti, tj)*d_vec(ig)*d_vec(jg)
2177 local_data(ib + ti - 1, jb + tj - 1) = &
2178 local_data(ib + ti - 1, jb + tj - 1) + tikhonov
2185 DEALLOCATE (phi_rows_t, phi_cols_t, gram_t)
2196 cpabort(
"pdpotrf failed in solve_D_lp_distributed")
2202 cpabort(
"pdpotrs failed in solve_D_lp_distributed")
2213 CALL timestop(handle)
2229 SUBROUTINE get_mat_chi_gamma_tau(bs_env, mat_chi_Gamma_tau, mat_phi_mu_l, mat_Z_lP)
2231 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
2232 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: mat_chi_gamma_tau
2233 TYPE(dbcsr_type),
INTENT(INOUT) :: mat_phi_mu_l, mat_z_lp
2235 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_mat_chi_Gamma_tau'
2237 INTEGER :: handle, i_t, ispin, n_panels
2238 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: pan_first, pan_last
2239 REAL(kind=dp) :: grid_occ, t1, tau
2240 TYPE(dbcsr_type) :: matrix_g_occ_ao, matrix_g_vir_ao
2242 CALL timeset(routinen, handle)
2247 CALL resolve_grid_panels(bs_env, mat_phi_mu_l, pan_first, pan_last)
2249 n_panels =
SIZE(pan_first)
2250 IF (bs_env%unit_nr > 0)
THEN
2251 WRITE (bs_env%unit_nr,
'(T2,A,I44)') χΣ
'Number of batches for , matrices', n_panels
2252 CALL m_flush(bs_env%unit_nr)
2260 DO i_t = 1, bs_env%num_time_freq_points
2262 tau = bs_env%imag_time_points(i_t)
2264 DO ispin = 1, bs_env%n_spin
2267 CALL build_g_ao(bs_env, tau, ispin, .true., .false., mat_phi_mu_l, matrix_g_occ_ao)
2268 CALL build_g_ao(bs_env, tau, ispin, .false., .true., mat_phi_mu_l, matrix_g_vir_ao)
2271 CALL contract_grid_panels(l_a=mat_phi_mu_l, m_a=matrix_g_occ_ao, &
2272 l_b=mat_phi_mu_l, m_b=matrix_g_vir_ao, &
2273 l_out=mat_z_lp, mat_out=mat_chi_gamma_tau(i_t)%matrix, &
2274 scale=bs_env%spin_degeneracy, eps=bs_env%eps_filter, &
2275 para_env=bs_env%para_env, &
2276 pan_first=pan_first, pan_last=pan_last, &
2277 lb_eq_la=.true., lout_eq_la=.false., &
2278 zero_out=(ispin == 1), &
2279 keep_sparsity=bs_env%ri_rs%keep_sparsity_rirs, &
2280 centroids=bs_env%ri_rs%chunk_centroids, &
2281 cutoff=bs_env%ri_rs%cutoff_radius_v_w, &
2282 grid_occupation=grid_occ)
2284 CALL dbcsr_release(matrix_g_occ_ao)
2285 CALL dbcsr_release(matrix_g_vir_ao)
2290 IF (i_t == 1 .AND. bs_env%unit_nr > 0)
THEN
2291 WRITE (bs_env%unit_nr,
'(A)')
' '
2292 WRITE (bs_env%unit_nr,
'(T2,A,F17.2,A)') &
2293 'Occupation of non-zero elements of G(l,l'χ
'), (l,l''), W(l,l'')', &
2294 grid_occ*100.0_dp,
' %'
2295 WRITE (bs_env%unit_nr,
'(A)')
' '
2296 CALL m_flush(bs_env%unit_nr)
2299 CALL print_matrix_occupation(mat_chi_gamma_tau(i_t)%matrix, χ
'(P,Q)', &
2300 bs_env%para_env, bs_env%unit_nr)
2303 IF (bs_env%unit_nr > 0)
THEN
2304 WRITE (bs_env%unit_nr,
'(T2,A,I13,A,I3,A,F7.1,A)') &
2305 χτ
'Computed (i,k=0) for time point', i_t,
' /', bs_env%num_time_freq_points, &
2306 ', Execution time', m_walltime() - t1,
' s'
2311 IF (bs_env%unit_nr > 0)
WRITE (bs_env%unit_nr,
'(A)')
' '
2313 CALL timestop(handle)
2315 END SUBROUTINE get_mat_chi_gamma_tau
2324 SUBROUTINE print_matrix_occupation(matrix, label, para_env, unit_nr)
2326 TYPE(dbcsr_type),
INTENT(IN) :: matrix
2327 CHARACTER(LEN=*),
INTENT(IN) :: label
2328 TYPE(mp_para_env_type),
INTENT(IN),
POINTER :: para_env
2329 INTEGER,
INTENT(IN) :: unit_nr
2330 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_matrix_occupation'
2334 REAL(kind=dp) :: frac_2p31, max_loc, occ
2336 CALL timeset(routinen, handle)
2338 occ = dbcsr_get_occupation(matrix)
2339 max_loc = real(dbcsr_get_data_size(matrix), dp)
2340 CALL para_env%max(max_loc)
2342 IF (unit_nr > 0)
THEN
2343 frac_2p31 = max_loc/real(dbcsr_msg_elem_limit, dp)
2344 WRITE (unit_nr,
'(A)')
' '
2345 WRITE (unit_nr,
'(T2,A,F36.2,A)') &
2346 'Occupation of non-zero elements of '//trim(label), occ*100.0_dp,
' %'
2347 IF (frac_2p31 > 0.5_dp)
then
2348 WRITE (unit_nr,
'(T4,A)')
'*** WARNING: max/rank approaching 2^31 -- DBCSR overflow risk ***'
2350 CALL m_flush(unit_nr)
2353 CALL timestop(handle)
2355 END SUBROUTINE print_matrix_occupation
2366 SUBROUTINE mask_grid_blocks_near_panel(centroids, blk0, blk1, cutoff, used)
2368 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: centroids
2369 INTEGER,
INTENT(IN) :: blk0, blk1
2370 REAL(kind=dp),
INTENT(IN) :: cutoff
2371 LOGICAL,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: used
2372 CHARACTER(LEN=*),
PARAMETER :: routinen =
'mask_grid_blocks_near_panel'
2376 REAL(kind=dp) :: cutoff2, d2, dx
2377 REAL(kind=dp),
DIMENSION(3) :: hi, lo
2379 CALL timeset(routinen, handle)
2382 lo(:) = minval(centroids(:, blk0:blk1), dim=2)
2383 hi(:) = maxval(centroids(:, blk0:blk1), dim=2)
2385 ALLOCATE (used(
SIZE(centroids, 2)))
2386 DO c = 1,
SIZE(centroids, 2)
2389 dx = max(0.0_dp, lo(k) - centroids(k, c), centroids(k, c) - hi(k))
2392 used(c) = (d2 <= cutoff2)
2395 CALL timestop(handle)
2397 END SUBROUTINE mask_grid_blocks_near_panel
2411 SUBROUTINE panel_template_elems(r_blk_sizes, centroids, used, blk0, blk1, cutoff, nze_tmpl)
2413 INTEGER,
DIMENSION(:),
INTENT(IN) :: r_blk_sizes
2414 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: centroids
2415 LOGICAL,
DIMENSION(:),
INTENT(IN) :: used
2416 INTEGER,
INTENT(IN) :: blk0, blk1
2417 REAL(kind=dp),
INTENT(IN) :: cutoff
2418 INTEGER(KIND=int_8),
INTENT(OUT) :: nze_tmpl
2419 CHARACTER(LEN=*),
PARAMETER :: routinen =
'panel_template_elems'
2422 INTEGER :: c, ib, n_used
2423 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: used_idx
2424 REAL(kind=dp) :: cutoff2
2426 CALL timeset(routinen, handle)
2429 n_used = count(used)
2430 ALLOCATE (used_idx(n_used))
2432 DO c = 1,
SIZE(used)
2435 used_idx(n_used) = c
2445 IF (sum((centroids(:, ib) - centroids(:, used_idx(c)))**2) <= cutoff2)
then
2446 nze_tmpl = nze_tmpl + int(r_blk_sizes(ib), int_8)*int(r_blk_sizes(used_idx(c)), int_8)
2452 CALL timestop(handle)
2454 END SUBROUTINE panel_template_elems
2471 SUBROUTINE panel_mem_estimate_gb(nze_tmpl, pan_rows, width, n_grid_total, n_RI, n_ao, &
2474 INTEGER(KIND=int_8),
INTENT(IN) :: nze_tmpl
2475 INTEGER,
INTENT(IN) :: pan_rows, width, n_grid_total, n_ri, &
2477 REAL(kind=dp),
INTENT(OUT) :: mem_gb
2479 REAL(kind=dp) :: f_near
2481 f_near = real(width, dp)/real(max(n_grid_total, 1), dp)
2482 mem_gb = (3.0_dp*real(nze_tmpl, dp) + &
2483 REAL(pan_rows, dp)*f_near*(2.0_dp*
REAL(n_RI, dp) +
REAL(n_ao, dp)))* &
2484 8.0_dp/
REAL(MAX(n_procs, 1), dp)*1.0e-9_dp
2486 END SUBROUTINE panel_mem_estimate_gb
2506 SUBROUTINE plan_grid_panels(r_blk_sizes, panel_size, min_dim, pan_first, pan_last, &
2507 centroids, cutoff, n_RI, n_ao, n_procs, mem_budget_GB, &
2508 honor_exact, unsafe)
2510 INTEGER,
DIMENSION(:),
INTENT(IN) :: r_blk_sizes
2511 INTEGER,
INTENT(IN) :: panel_size, min_dim
2512 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: pan_first, pan_last
2513 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN),
OPTIONAL :: centroids
2514 REAL(kind=dp),
INTENT(IN),
OPTIONAL :: cutoff
2515 INTEGER,
INTENT(IN),
OPTIONAL :: n_ri, n_ao, n_procs
2516 REAL(kind=dp),
INTENT(IN),
OPTIONAL :: mem_budget_gb
2517 LOGICAL,
INTENT(IN),
OPTIONAL :: honor_exact
2518 LOGICAL,
INTENT(OUT),
OPTIONAL :: unsafe
2519 CHARACTER(LEN=*),
PARAMETER :: routinen =
'plan_grid_panels'
2521 INTEGER :: blk0, blk1, ib, n_grid_blocks, &
2522 n_grid_total, n_panels, rows_acc, &
2524 INTEGER(KIND=int_8) :: msg, nze_tmpl, side
2525 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: tmp_first, tmp_last
2526 LOGICAL :: fits, my_honor_exact, my_unsafe, &
2528 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: used
2529 REAL(kind=dp) :: f_near, mem_gb
2532 CALL timeset(routinen, handle)
2534 use_cutoff =
PRESENT(centroids) .AND.
PRESENT(cutoff)
2535 IF (use_cutoff) use_cutoff = cutoff > 0.0_dp
2536 IF (use_cutoff)
THEN
2537 cpassert(
PRESENT(n_ri) .AND.
PRESENT(n_ao) .AND.
PRESENT(n_procs))
2542 my_honor_exact = .false.
2543 IF (
PRESENT(honor_exact)) my_honor_exact = honor_exact
2546 n_grid_blocks =
SIZE(r_blk_sizes)
2547 n_grid_total = sum(r_blk_sizes)
2548 ALLOCATE (tmp_first(n_grid_blocks), tmp_last(n_grid_blocks))
2552 DO WHILE (blk0 <= n_grid_blocks)
2557 DO ib = blk0, n_grid_blocks
2558 rows_acc = rows_acc + r_blk_sizes(ib)
2560 IF (rows_acc >=
target)
EXIT
2562 IF (.NOT. use_cutoff .OR. blk1 == blk0)
EXIT
2563 CALL mask_grid_blocks_near_panel(centroids, blk0, blk1, cutoff, used)
2564 width = sum(r_blk_sizes, mask=used)
2565 CALL panel_template_elems(r_blk_sizes, centroids, used, blk0, blk1, cutoff, nze_tmpl)
2566 f_near = real(width, dp)/real(max(n_grid_total, 1), dp)
2567 side = int(real(rows_acc, dp)*f_near*real(max(n_ri, n_ao), dp), int_8)
2568 msg = max(nze_tmpl, side)/int(max(min_dim, 1), int_8)
2569 fits = (msg <= dbcsr_msg_elem_limit/4)
2570 IF (fits .AND.
PRESENT(mem_budget_gb))
THEN
2571 IF (mem_budget_gb > 0.0_dp)
THEN
2572 CALL panel_mem_estimate_gb(nze_tmpl, rows_acc, width, n_grid_total, &
2573 n_ri, n_ao, n_procs, mem_gb)
2574 fits = (mem_gb <= mem_budget_gb)
2581 IF (my_honor_exact)
THEN
2583 IF (.NOT. fits) my_unsafe = .true.
2587 target = max(1, min(
target, rows_acc)/2)
2589 n_panels = n_panels + 1
2590 tmp_first(n_panels) = blk0
2591 tmp_last(n_panels) = blk1
2595 ALLOCATE (pan_first(n_panels), pan_last(n_panels))
2596 pan_first(:) = tmp_first(1:n_panels)
2597 pan_last(:) = tmp_last(1:n_panels)
2598 DEALLOCATE (tmp_first, tmp_last)
2600 IF (
PRESENT(unsafe)) unsafe = my_unsafe
2602 CALL timestop(handle)
2604 END SUBROUTINE plan_grid_panels
2613 SUBROUTINE resolve_grid_panels(bs_env, mat_phi_mu_l, pan_first, pan_last)
2615 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
2616 TYPE(dbcsr_type),
INTENT(INOUT) :: mat_phi_mu_l
2617 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: pan_first, pan_last
2618 CHARACTER(LEN=*),
PARAMETER :: routinen =
'resolve_grid_panels'
2620 INTEGER :: min_dim, n_grid_total, n_panels_req, &
2621 npcols, nprows, panel_size, safe_max
2622 INTEGER,
DIMENSION(:),
POINTER :: r_blk_sizes
2623 LOGICAL :: honor_exact, panels_unsafe, use_cutoff
2624 REAL(kind=dp) :: mem_avail_gb, mem_budget_gb
2625 TYPE(dbcsr_distribution_type) :: dist
2628 CALL timeset(routinen, handle)
2630 IF (
ALLOCATED(bs_env%ri_rs%pan_first))
THEN
2631 ALLOCATE (pan_first, source=bs_env%ri_rs%pan_first)
2632 ALLOCATE (pan_last, source=bs_env%ri_rs%pan_last)
2633 CALL timestop(handle)
2637 use_cutoff = bs_env%ri_rs%cutoff_radius_v_w > 0.0_dp .AND. &
2638 ALLOCATED(bs_env%ri_rs%chunk_centroids)
2644 CALL dbcsr_get_info(mat_phi_mu_l, nfullrows_total=n_grid_total, row_blk_size=r_blk_sizes, &
2646 CALL dbcsr_distribution_get(dist, nprows=nprows, npcols=npcols)
2647 min_dim = max(min(nprows, npcols), 1)
2652 IF (use_cutoff)
THEN
2653 safe_max = n_grid_total
2655 safe_max = int(0.5_dp*real(dbcsr_msg_elem_limit, dp)*real(min_dim, dp)/ &
2656 REAL(n_grid_total, dp))
2657 safe_max = max(1, min(safe_max, n_grid_total))
2663 n_panels_req = bs_env%ri_rs%n_panels
2664 honor_exact = (n_panels_req > 1)
2665 panels_unsafe = .false.
2666 IF (n_panels_req > 1)
THEN
2671 panel_size = min((n_grid_total + n_panels_req - 1)/n_panels_req, safe_max)
2674 panel_size = safe_max
2676 panel_size = max(1, panel_size)
2678 IF (use_cutoff)
THEN
2680 CALL ri_rs_mem_avail_per_proc_gb(bs_env, mem_avail_gb)
2681 mem_budget_gb = 0.5_dp*mem_avail_gb
2682 CALL plan_grid_panels(r_blk_sizes, panel_size, min_dim, pan_first, pan_last, &
2683 centroids=bs_env%ri_rs%chunk_centroids, &
2684 cutoff=bs_env%ri_rs%cutoff_radius_v_w, &
2685 n_ri=bs_env%n_RI, n_ao=bs_env%n_ao, &
2686 n_procs=bs_env%para_env%num_pe, mem_budget_gb=mem_budget_gb, &
2687 honor_exact=honor_exact, unsafe=panels_unsafe)
2689 CALL plan_grid_panels(r_blk_sizes, panel_size, min_dim, pan_first, pan_last)
2692 IF (honor_exact .AND. panels_unsafe .AND. bs_env%unit_nr > 0)
THEN
2693 WRITE (bs_env%unit_nr,
'(T2,A,I0,A)') &
2694 '*** WARNING: N_PANELS = ', n_panels_req,
' used as requested, but one or more '// &
2695 'panels exceed the DBCSR 32-bit message / memory-budget safety limit. The run may '// &
2696 'abort or swap; increase N_PANELS if it does. ***'
2699 ALLOCATE (bs_env%ri_rs%pan_first, source=pan_first)
2700 ALLOCATE (bs_env%ri_rs%pan_last, source=pan_last)
2702 CALL timestop(handle)
2704 END SUBROUTINE resolve_grid_panels
2714 SUBROUTINE ri_rs_mem_avail_per_proc_gb(bs_env, mem_avail_GB)
2715 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
2716 REAL(kind=dp),
INTENT(OUT) :: mem_avail_gb
2717 CHARACTER(LEN=*),
PARAMETER :: routinen =
'ri_rs_mem_avail_per_proc_GB'
2719 CHARACTER(LEN=default_string_length) :: hostname
2720 INTEGER :: host_hash, ic, n_procs, ranks_per_node
2721 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: all_host_hashes
2722 INTEGER(KIND=int_8) :: h8, mem_buffers, mem_cached, mem_free, &
2723 mem_likely_free, mem_sreclaimable, &
2727 CALL timeset(routinen, handle)
2729 n_procs = bs_env%para_env%num_pe
2730 CALL m_hostnm(hostname)
2732 DO ic = 1, len_trim(hostname)
2733 h8 = mod(h8*127_int_8 + int(ichar(hostname(ic:ic)), int_8), 2147483647_int_8)
2736 ALLOCATE (all_host_hashes(n_procs))
2737 CALL bs_env%para_env%allgather(host_hash, all_host_hashes)
2738 ranks_per_node = max(count(all_host_hashes == host_hash), 1)
2739 DEALLOCATE (all_host_hashes)
2741 CALL m_memory_details(memtotal=mem_total, memfree=mem_free, buffers=mem_buffers, &
2742 cached=mem_cached, slab=mem_slab, sreclaimable=mem_sreclaimable, &
2743 memlikelyfree=mem_likely_free)
2744 mem_avail_gb = real(mem_likely_free, dp)*1.0e-9_dp/real(ranks_per_node, dp)
2745 CALL bs_env%para_env%min(mem_avail_gb)
2747 CALL timestop(handle)
2749 END SUBROUTINE ri_rs_mem_avail_per_proc_gb
2756 SUBROUTINE print_ri_rs_memory_estimate(qs_env, bs_env)
2760 TYPE(qs_environment_type),
POINTER :: qs_env
2761 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
2763 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_ri_rs_memory_estimate'
2765 INTEGER :: handle, iatom, ipan, l, &
2767 n_ao_total, n_grid_total, &
2768 n_local_grid, n_loc_ri_max, n_procs, &
2769 n_procs_per_atom, n_ri, n_threads, &
2770 natom, pan_rows, pan_width
2771 INTEGER(KIND=int_8) :: nze_tmpl
2772 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: pan_first, pan_last
2773 INTEGER,
DIMENSION(:),
POINTER :: r_blk_sizes
2774 LOGICAL :: use_cutoff
2775 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: grid_used
2776 REAL(kind=dp) :: cutoff_ri, mem_avail_gb, mem_d_local_gb, &
2777 mem_dlp_gb, mem_pan_gb, mem_panels_gb, &
2778 mem_phi_local_gb, mem_z_lp_gb, &
2779 mem_zlp_peak_gb, pos_p(3)
2780 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
2782 CALL timeset(routinen, handle)
2784 CALL dbcsr_get_info(bs_env%ri_rs%mat_phi_mu_l, nfullrows_total=n_grid_total, &
2785 row_blk_size=r_blk_sizes)
2787 n_procs = bs_env%para_env%num_pe
2791 mem_z_lp_gb = real(n_grid_total, dp)*real(n_ri, dp)*8.0_dp/ &
2792 REAL(n_procs, dp)*1.0e-9_dp
2799 use_cutoff = bs_env%ri_rs%cutoff_radius_v_w > 0.0_dp .AND. &
2800 ALLOCATED(bs_env%ri_rs%chunk_centroids)
2801 CALL resolve_grid_panels(bs_env, bs_env%ri_rs%mat_phi_mu_l, pan_first, pan_last)
2802 mem_panels_gb = 0.0_dp
2803 DO ipan = 1,
SIZE(pan_first)
2804 pan_rows = sum(r_blk_sizes(pan_first(ipan):pan_last(ipan)))
2805 IF (use_cutoff)
THEN
2806 CALL mask_grid_blocks_near_panel(bs_env%ri_rs%chunk_centroids, pan_first(ipan), &
2807 pan_last(ipan), bs_env%ri_rs%cutoff_radius_v_w, &
2809 pan_width = sum(r_blk_sizes, mask=grid_used)
2810 CALL panel_template_elems(r_blk_sizes, bs_env%ri_rs%chunk_centroids, &
2811 grid_used, pan_first(ipan), pan_last(ipan), &
2812 bs_env%ri_rs%cutoff_radius_v_w, nze_tmpl)
2813 CALL panel_mem_estimate_gb(nze_tmpl, pan_rows, pan_width, n_grid_total, &
2814 n_ri, bs_env%n_ao, n_procs, mem_pan_gb)
2816 pan_width = n_grid_total
2817 mem_pan_gb = (3.0_dp*real(pan_rows, dp)*real(pan_width, dp) + &
2818 2.0_dp*real(pan_rows, dp)*real(n_ri, dp))* &
2819 8.0_dp/real(n_procs, dp)*1.0e-9_dp
2821 mem_panels_gb = max(mem_panels_gb, mem_pan_gb)
2823 mem_panels_gb = mem_panels_gb + &
2824 REAL(n_ri, dp)*
REAL(n_ri, dp)*8.0_dp/
REAL(n_procs, dp)*1.0e-9_dp
2835 CALL get_qs_env(qs_env, particle_set=particle_set)
2836 natom =
SIZE(particle_set)
2837 n_ao_total = bs_env%i_ao_end_from_atom(natom)
2839 max_n_local_grid = 0
2842 IF (bs_env%ri_rs%cutoff_radius_ri_rs > 0.0_dp)
THEN
2843 cutoff_ri = bs_env%ri_rs%cutoff_radius_ri_rs
2845 cutoff_ri = bs_env%ri_metric%cutoff_radius + bs_env%ri_rs%radius_ri_per_atom(iatom)
2847 pos_p(:) = particle_set(iatom)%r(:)
2849 DO l = 1, n_grid_total
2850 IF (sum((bs_env%ri_rs%grid_points(1:3, l) - pos_p(1:3))**2) <= cutoff_ri**2)
then
2851 n_local_grid = n_local_grid + 1
2854 max_n_local_grid = max(max_n_local_grid, n_local_grid)
2855 n_loc_ri_max = max(n_loc_ri_max, &
2856 bs_env%i_RI_end_from_atom(iatom) - bs_env%i_RI_start_from_atom(iatom) + 1)
2859 n_procs_per_atom = min(max(bs_env%ri_rs%n_procs_per_atom_z_lp, 1), n_procs)
2865 IF (n_procs_per_atom > 1)
THEN
2866 mem_d_local_gb = real(max_n_local_grid, dp)**2*8.0_dp/real(n_procs_per_atom, dp)*1.0e-9_dp
2868 mem_d_local_gb = real(max_n_local_grid, dp)**2*8.0_dp*1.0e-9_dp
2870 mem_phi_local_gb = real(max_n_local_grid, dp)*real(n_ao_total, dp)*8.0_dp*1.0e-9_dp
2871 mem_dlp_gb = real(max_n_local_grid, dp)*real(n_loc_ri_max, dp)*8.0_dp* &
2872 REAL(1 + n_threads, dp)*1.0e-9_dp
2873 mem_zlp_peak_gb = mem_d_local_gb + mem_phi_local_gb + mem_dlp_gb
2877 CALL ri_rs_mem_avail_per_proc_gb(bs_env, mem_avail_gb)
2879 IF (bs_env%unit_nr > 0)
THEN
2880 WRITE (bs_env%unit_nr,
'(A)')
' '
2881 WRITE (bs_env%unit_nr,
'(T2,A)')
'RI-RS memory estimate per MPI process:'
2882 WRITE (bs_env%unit_nr,
'(T4,A,F37.2,A)') &
2883 'Available memory per process (system)', mem_avail_gb,
' GB'
2884 WRITE (bs_env%unit_nr,
'(T4,A,F18.2,A)') &
2885 'Required for Z_lP (dense upper bound; actual is sparser)', mem_z_lp_gb,
' GB'
2886 WRITE (bs_env%unit_nr,
'(T4,A,F25.2,A)') &
2887 χΣ
'Required for , W, panels (peak per panel step)', mem_panels_gb,
' GB'
2888 WRITE (bs_env%unit_nr,
'(T4,A,F17.2,A)') &
2889 φ
'Required for Z_lP solve peak (D_local+, worst-case atom)', mem_zlp_peak_gb,
' GB'
2890 WRITE (bs_env%unit_nr,
'(T6,A,I21,A,F10.2,A)') &
2891 'worst-case n_local_grid', max_n_local_grid,
' points (D_local', mem_d_local_gb,
' GB)'
2892 WRITE (bs_env%unit_nr,
'(A)')
' '
2894 IF (mem_avail_gb > 0.0_dp .AND. mem_z_lp_gb > mem_avail_gb)
THEN
2895 WRITE (bs_env%unit_nr,
'(T2,A)') &
2896 '*** WARNING: Estimated Z_lP memory exceeds available memory per process ***'
2897 WRITE (bs_env%unit_nr,
'(T4,A,F6.2,A,F6.2,A)') &
2898 'Z_lP upper bound: ', mem_z_lp_gb,
' GB > available: ', mem_avail_gb,
' GB'
2899 WRITE (bs_env%unit_nr,
'(T4,A)') &
2900 ×
'Z_lP (n_grid n_RI) is distributed across all MPI ranks. To reduce per-rank'
2901 WRITE (bs_env%unit_nr,
'(T4,A)') &
2902 'memory: add more nodes, use fewer MPI ranks per node, or increase'
2903 WRITE (bs_env%unit_nr,
'(T4,A)') &
2904 'N_PROCS_PER_ATOM_Z_LP to distribute each atom block via ScaLAPACK (reduces'
2905 WRITE (bs_env%unit_nr,
'(T4,A)') &
2906 'per-rank memory by ~1/G where G = N_PROCS_PER_ATOM_Z_LP).'
2907 WRITE (bs_env%unit_nr,
'(A)')
' '
2909 IF (mem_avail_gb > 0.0_dp .AND. mem_panels_gb > mem_avail_gb)
THEN
2910 WRITE (bs_env%unit_nr,
'(T2,A)') &
2911 χΣ
'*** WARNING: Estimated /W/ panel memory exceeds available memory per process ***'
2912 WRITE (bs_env%unit_nr,
'(T4,A,F6.2,A,F6.2,A)') &
2913 'Panel peak estimate: ', mem_panels_gb,
' GB > available: ', mem_avail_gb,
' GB'
2914 WRITE (bs_env%unit_nr,
'(T4,A)') &
2915 ××
'Panel memory scales as ~3panel_sizen_grid / n_procs. Options:'
2916 WRITE (bs_env%unit_nr,
'(T4,A)') &
2917 ' - More nodes or fewer MPI ranks per node (increases n_procs, reduces share)'
2918 WRITE (bs_env%unit_nr,
'(T4,A)') &
2919 →
' - Increase N_PANELS (more, smaller panels less peak memory per step)'
2920 WRITE (bs_env%unit_nr,
'(A)')
' '
2922 IF (mem_avail_gb > 0.0_dp .AND. mem_zlp_peak_gb > mem_avail_gb)
THEN
2923 WRITE (bs_env%unit_nr,
'(T2,A)') &
2924 '*** WARNING: Estimated Z_lP solve peak exceeds available memory per process ***'
2925 WRITE (bs_env%unit_nr,
'(T4,A,F8.2,A,F8.2,A)') &
2926 'Z_lP solve peak: ', mem_zlp_peak_gb,
' GB > available: ', mem_avail_gb,
' GB'
2927 WRITE (bs_env%unit_nr,
'(T4,A)') &
2928 'The per-atom Gram matrix D_local(n_local_grid, n_local_grid) dominates and scales'
2929 WRITE (bs_env%unit_nr,
'(T4,A)') &
2930 'as n_local_grid^2. It is NOT balanced across ranks (the rank owning the atom with'
2931 WRITE (bs_env%unit_nr,
'(T4,A)') &
2932 'the largest integration sphere peaks well above the average). Options:'
2933 WRITE (bs_env%unit_nr,
'(T4,A)') &
2934 ' - Increase N_PROCS_PER_ATOM_Z_LP=G to distribute D_local block-cyclic via'
2935 WRITE (bs_env%unit_nr,
'(T4,A)') &
2936 ' ScaLAPACK (reduces the D_local term by ~1/G; no accuracy loss)'
2937 WRITE (bs_env%unit_nr,
'(T4,A)') &
2938 ' - Reduce the RI-RS sphere cutoff (CUTOFF_RADIUS_RL_RI): D_local shrinks as'
2939 WRITE (bs_env%unit_nr,
'(T4,A)') &
2940 ' n_local_grid^2, but this trades accuracy'
2941 WRITE (bs_env%unit_nr,
'(T4,A)') &
2942 ' - Fewer MPI ranks per node (more memory per rank for the peak atom)'
2943 WRITE (bs_env%unit_nr,
'(A)')
' '
2947 CALL timestop(handle)
2949 END SUBROUTINE print_ri_rs_memory_estimate
2964 SUBROUTINE build_geo_template_panel(L_pan, L_full, centroids, cutoff, blk0, A_template, col_map)
2965 TYPE(dbcsr_type),
INTENT(IN) :: l_pan, l_full
2966 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: centroids
2967 REAL(kind=dp),
INTENT(IN) :: cutoff
2968 INTEGER,
INTENT(IN) :: blk0
2969 TYPE(dbcsr_type),
INTENT(OUT) :: a_template
2970 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: col_map
2972 CHARACTER(LEN=*),
PARAMETER :: routinen =
'build_geo_template_panel'
2974 INTEGER :: c, cg, cs, handle, my_pcol, my_prow, &
2975 n_grid_blks, n_pan_blks, npcols, &
2977 INTEGER,
DIMENSION(:),
POINTER :: grid_blk_sizes, pan_blk_sizes
2978 REAL(kind=dp) :: cutoff2
2979 REAL(kind=dp),
ALLOCATABLE :: zero_blk(:, :)
2980 TYPE(dbcsr_distribution_type) :: dist
2982 CALL timeset(routinen, handle)
2985 CALL dbcsr_get_info(l_pan, nblkrows_total=n_pan_blks, row_blk_size=pan_blk_sizes)
2986 CALL dbcsr_get_info(l_full, nblkrows_total=n_grid_blks, row_blk_size=grid_blk_sizes)
2990 CALL create_product_matrix(l_pan, l_full,
'N',
'T', a_template)
2991 CALL dbcsr_get_info(a_template, distribution=dist)
2992 CALL dbcsr_distribution_get(dist, nprows=nprows, npcols=npcols, &
2993 myprow=my_prow, mypcol=my_pcol)
2995 ALLOCATE (zero_blk(maxval(pan_blk_sizes(1:n_pan_blks)), &
2996 maxval(grid_blk_sizes(1:n_grid_blks))))
2997 zero_blk(:, :) = 0.0_dp
2999 DO r = 1, n_pan_blks
3000 IF (mod(r - 1, nprows) /= my_prow) cycle
3001 rs = pan_blk_sizes(r)
3002 DO c = 1, n_grid_blks
3003 IF (mod(c - 1, npcols) /= my_pcol) cycle
3005 IF (
PRESENT(col_map)) cg = col_map(c)
3006 IF ((centroids(1, blk0 + r - 1) - centroids(1, cg))**2 + &
3007 (centroids(2, blk0 + r - 1) - centroids(2, cg))**2 + &
3008 (centroids(3, blk0 + r - 1) - centroids(3, cg))**2 <= cutoff2)
THEN
3009 cs = grid_blk_sizes(c)
3010 CALL dbcsr_put_block(a_template, r, c, zero_blk(1:rs, 1:cs))
3014 CALL dbcsr_finalize(a_template)
3016 DEALLOCATE (zero_blk)
3017 CALL timestop(handle)
3019 END SUBROUTINE build_geo_template_panel
3031 SUBROUTINE extract_grid_panel(mat_full, blk0, blk1, mat_panel)
3033 TYPE(dbcsr_type),
INTENT(INOUT) :: mat_full
3034 INTEGER,
INTENT(IN) :: blk0, blk1
3035 TYPE(dbcsr_type),
INTENT(OUT) :: mat_panel
3036 CHARACTER(LEN=*),
PARAMETER :: routinen =
'extract_grid_panel'
3038 INTEGER :: ib, jb, npb
3039 INTEGER,
DIMENSION(:),
POINTER :: col_blk_full, col_dist_full, &
3040 row_blk_full, row_blk_pan, &
3041 row_dist_full, row_dist_pan
3042 REAL(kind=dp),
DIMENSION(:, :),
POINTER :: blk
3043 TYPE(dbcsr_distribution_type) :: dist_full, dist_pan
3044 TYPE(dbcsr_iterator_type) :: iter
3047 CALL timeset(routinen, handle)
3049 CALL dbcsr_get_info(mat_full, distribution=dist_full, &
3050 row_blk_size=row_blk_full, col_blk_size=col_blk_full)
3051 CALL dbcsr_distribution_get(dist_full, row_dist=row_dist_full, col_dist=col_dist_full)
3053 npb = blk1 - blk0 + 1
3054 ALLOCATE (row_dist_pan(npb), row_blk_pan(npb))
3055 row_dist_pan(:) = row_dist_full(blk0:blk1)
3056 row_blk_pan(:) = row_blk_full(blk0:blk1)
3058 CALL dbcsr_distribution_new(dist_pan, template=dist_full, &
3059 row_dist=row_dist_pan, col_dist=col_dist_full)
3060 CALL dbcsr_create(mat_panel, name=
"grid_panel", dist=dist_pan, &
3061 matrix_type=dbcsr_type_no_symmetry, &
3062 row_blk_size=row_blk_pan, col_blk_size=col_blk_full)
3064 CALL dbcsr_iterator_start(iter, mat_full)
3065 DO WHILE (dbcsr_iterator_blocks_left(iter))
3066 CALL dbcsr_iterator_next_block(iter, ib, jb, blk)
3067 IF (ib < blk0 .OR. ib > blk1) cycle
3068 CALL dbcsr_put_block(mat_panel, ib - blk0 + 1, jb, blk)
3070 CALL dbcsr_iterator_stop(iter)
3071 CALL dbcsr_finalize(mat_panel)
3073 CALL dbcsr_distribution_release(dist_pan)
3074 DEALLOCATE (row_dist_pan, row_blk_pan)
3076 CALL timestop(handle)
3078 END SUBROUTINE extract_grid_panel
3088 SUBROUTINE collect_used_col_blocks(matrix, para_env, used)
3090 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix
3091 TYPE(mp_para_env_type),
INTENT(IN),
POINTER :: para_env
3092 LOGICAL,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: used
3093 CHARACTER(LEN=*),
PARAMETER :: routinen =
'collect_used_col_blocks'
3095 INTEGER :: ib, jb, nblkcols
3096 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: iused
3097 REAL(kind=dp),
DIMENSION(:, :),
POINTER :: blk
3098 TYPE(dbcsr_iterator_type) :: iter
3101 CALL timeset(routinen, handle)
3103 CALL dbcsr_get_info(matrix, nblkcols_total=nblkcols)
3104 ALLOCATE (iused(nblkcols))
3107 CALL dbcsr_iterator_start(iter, matrix)
3108 DO WHILE (dbcsr_iterator_blocks_left(iter))
3109 CALL dbcsr_iterator_next_block(iter, ib, jb, blk)
3112 CALL dbcsr_iterator_stop(iter)
3114 CALL para_env%sum(iused)
3116 ALLOCATE (used(nblkcols))
3117 used(:) = (iused(:) > 0)
3120 CALL timestop(handle)
3122 END SUBROUTINE collect_used_col_blocks
3135 SUBROUTINE extract_masked_blocks(mat_full, used, mat_out, compress_rows, blk_map)
3137 TYPE(dbcsr_type),
INTENT(INOUT) :: mat_full
3138 LOGICAL,
DIMENSION(:),
INTENT(IN) :: used
3139 TYPE(dbcsr_type),
INTENT(OUT) :: mat_out
3140 LOGICAL,
INTENT(IN) :: compress_rows
3141 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT), &
3144 CHARACTER(LEN=*),
PARAMETER :: routinen =
'extract_masked_blocks'
3146 INTEGER :: ib, jb, n_blk, n_sub, r
3147 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: inv_map
3148 INTEGER,
DIMENSION(:),
POINTER :: blk_full, blk_sub, col_blk_full, &
3149 col_dist_full, dist_full_1d, &
3150 dist_sub_1d, row_blk_full, &
3152 REAL(kind=dp),
DIMENSION(:, :),
POINTER :: blk
3153 TYPE(dbcsr_distribution_type) :: dist_full, dist_sub
3154 TYPE(dbcsr_iterator_type) :: iter
3157 CALL timeset(routinen, handle)
3159 CALL dbcsr_get_info(mat_full, distribution=dist_full, &
3160 row_blk_size=row_blk_full, col_blk_size=col_blk_full)
3161 CALL dbcsr_distribution_get(dist_full, row_dist=row_dist_full, col_dist=col_dist_full)
3163 IF (compress_rows)
THEN
3164 blk_full => row_blk_full
3165 dist_full_1d => row_dist_full
3167 blk_full => col_blk_full
3168 dist_full_1d => col_dist_full
3170 n_blk =
SIZE(blk_full)
3174 ALLOCATE (inv_map(n_blk), blk_sub(n_sub), dist_sub_1d(n_sub))
3175 IF (
PRESENT(blk_map))
ALLOCATE (blk_map(n_sub))
3182 blk_sub(r) = blk_full(ib)
3183 dist_sub_1d(r) = dist_full_1d(ib)
3184 IF (
PRESENT(blk_map)) blk_map(r) = ib
3188 IF (compress_rows)
THEN
3189 CALL dbcsr_distribution_new(dist_sub, template=dist_full, &
3190 row_dist=dist_sub_1d, col_dist=col_dist_full)
3191 CALL dbcsr_create(mat_out, name=
"row_subset", dist=dist_sub, &
3192 matrix_type=dbcsr_type_no_symmetry, &
3193 row_blk_size=blk_sub, col_blk_size=col_blk_full)
3195 CALL dbcsr_distribution_new(dist_sub, template=dist_full, &
3196 row_dist=row_dist_full, col_dist=dist_sub_1d)
3197 CALL dbcsr_create(mat_out, name=
"col_subset", dist=dist_sub, &
3198 matrix_type=dbcsr_type_no_symmetry, &
3199 row_blk_size=row_blk_full, col_blk_size=blk_sub)
3202 CALL dbcsr_iterator_start(iter, mat_full)
3203 DO WHILE (dbcsr_iterator_blocks_left(iter))
3204 CALL dbcsr_iterator_next_block(iter, ib, jb, blk)
3205 IF (compress_rows)
THEN
3206 IF (inv_map(ib) > 0)
CALL dbcsr_put_block(mat_out, inv_map(ib), jb, blk)
3208 IF (inv_map(jb) > 0)
CALL dbcsr_put_block(mat_out, ib, inv_map(jb), blk)
3211 CALL dbcsr_iterator_stop(iter)
3212 CALL dbcsr_finalize(mat_out)
3214 CALL dbcsr_distribution_release(dist_sub)
3215 DEALLOCATE (inv_map, blk_sub, dist_sub_1d)
3217 CALL timestop(handle)
3219 END SUBROUTINE extract_masked_blocks
3229 SUBROUTINE reserve_blocks_within_radius(matrix, centers, radius)
3231 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix
3232 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: centers
3233 REAL(kind=dp),
INTENT(IN) :: radius
3235 CHARACTER(LEN=*),
PARAMETER :: routinen =
'reserve_blocks_within_radius'
3237 INTEGER :: handle, i, j, my_pcol, my_prow, &
3239 INTEGER,
DIMENSION(:),
POINTER :: col_blk, col_dist, row_blk, row_dist
3240 REAL(kind=dp) :: radius2
3241 REAL(kind=dp),
ALLOCATABLE :: zero_blk(:, :)
3242 TYPE(dbcsr_distribution_type) :: dist
3244 CALL timeset(routinen, handle)
3246 CALL dbcsr_get_info(matrix, nblkrows_total=nblkrows, nblkcols_total=nblkcols, &
3247 row_blk_size=row_blk, col_blk_size=col_blk, distribution=dist)
3248 CALL dbcsr_distribution_get(dist, row_dist=row_dist, col_dist=col_dist, &
3249 myprow=my_prow, mypcol=my_pcol)
3250 cpassert(nblkrows ==
SIZE(centers, 2))
3251 cpassert(nblkcols ==
SIZE(centers, 2))
3254 ALLOCATE (zero_blk(maxval(row_blk(1:nblkrows)), maxval(col_blk(1:nblkcols))))
3255 zero_blk(:, :) = 0.0_dp
3258 IF (row_dist(i) /= my_prow) cycle
3260 IF (col_dist(j) /= my_pcol) cycle
3261 IF ((centers(1, i) - centers(1, j))**2 + (centers(2, i) - centers(2, j))**2 + &
3262 (centers(3, i) - centers(3, j))**2 <= radius2)
THEN
3263 CALL dbcsr_put_block(matrix, i, j, zero_blk(1:row_blk(i), 1:col_blk(j)))
3267 CALL dbcsr_finalize(matrix)
3269 DEALLOCATE (zero_blk)
3270 CALL timestop(handle)
3272 END SUBROUTINE reserve_blocks_within_radius
3284 SUBROUTINE create_product_matrix(mat_left, mat_right, transa, transb, mat_out)
3286 TYPE(dbcsr_type),
INTENT(IN) :: mat_left, mat_right
3287 CHARACTER(LEN=1),
INTENT(IN) :: transa, transb
3288 TYPE(dbcsr_type),
INTENT(OUT) :: mat_out
3289 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_product_matrix'
3291 INTEGER :: i, npcols, nprows
3292 INTEGER,
DIMENSION(:),
POINTER :: col_blk_l, col_blk_r, out_col_blk, &
3293 out_col_dist, out_row_blk, out_row_dist, &
3294 row_blk_l, row_blk_r
3295 TYPE(dbcsr_distribution_type) :: dist_l, dist_out
3298 CALL timeset(routinen, handle)
3300 CALL dbcsr_get_info(mat_left, distribution=dist_l, row_blk_size=row_blk_l, col_blk_size=col_blk_l)
3301 CALL dbcsr_get_info(mat_right, row_blk_size=row_blk_r, col_blk_size=col_blk_r)
3302 CALL dbcsr_distribution_get(dist_l, nprows=nprows, npcols=npcols)
3307 IF (transa ==
'N')
THEN
3308 out_row_blk => row_blk_l
3310 out_row_blk => col_blk_l
3312 IF (transb ==
'N')
THEN
3313 out_col_blk => col_blk_r
3315 out_col_blk => row_blk_r
3318 ALLOCATE (out_row_dist(
SIZE(out_row_blk)), out_col_dist(
SIZE(out_col_blk)))
3319 DO i = 1,
SIZE(out_row_blk)
3320 out_row_dist(i) = mod(i - 1, nprows)
3322 DO i = 1,
SIZE(out_col_blk)
3323 out_col_dist(i) = mod(i - 1, npcols)
3326 CALL dbcsr_distribution_new(dist_out, template=dist_l, &
3327 row_dist=out_row_dist, col_dist=out_col_dist)
3328 CALL dbcsr_create(mat_out, name=
"panel_product", dist=dist_out, &
3329 matrix_type=dbcsr_type_no_symmetry, &
3330 row_blk_size=out_row_blk, col_blk_size=out_col_blk)
3331 CALL dbcsr_distribution_release(dist_out)
3332 DEALLOCATE (out_row_dist, out_col_dist)
3334 CALL timestop(handle)
3336 END SUBROUTINE create_product_matrix
3348 SUBROUTINE build_g_ao(bs_env, tau, ispin, occ, vir, template, matrix_G_ao)
3350 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
3351 REAL(kind=dp),
INTENT(IN) :: tau
3352 INTEGER,
INTENT(IN) :: ispin
3353 LOGICAL,
INTENT(IN) :: occ, vir
3354 TYPE(dbcsr_type),
INTENT(INOUT) :: template
3355 TYPE(dbcsr_type),
INTENT(OUT) :: matrix_g_ao
3356 CHARACTER(LEN=*),
PARAMETER :: routinen =
'build_G_ao'
3358 INTEGER,
DIMENSION(:),
POINTER :: blk_ao, dist_row_ao
3359 TYPE(cp_fm_type),
POINTER :: fm_g
3360 TYPE(dbcsr_distribution_type) :: dist_ao_ao
3363 CALL timeset(routinen, handle)
3366 fm_g => bs_env%fm_Gocc
3368 fm_g => bs_env%fm_Gvir
3371 CALL g_occ_vir(bs_env, tau, fm_g, ispin, occ=occ, vir=vir)
3373 CALL setup_square_topology(template, dist_ao_ao, blk_ao, dist_row_ao)
3374 CALL dbcsr_create(matrix_g_ao, name=
"G_ao", dist=dist_ao_ao, &
3375 matrix_type=dbcsr_type_no_symmetry, &
3376 row_blk_size=blk_ao, col_blk_size=blk_ao)
3380 IF (bs_env%ri_rs%cutoff_radius_g_w > 0.0_dp .AND. &
3381 ALLOCATED(bs_env%ri_rs%atom_centers))
THEN
3382 CALL reserve_blocks_within_radius(matrix_g_ao, bs_env%ri_rs%atom_centers, &
3383 bs_env%ri_rs%cutoff_radius_g_w)
3384 CALL copy_fm_to_dbcsr(fm_g, matrix_g_ao, keep_sparsity=.true.)
3386 CALL copy_fm_to_dbcsr(fm_g, matrix_g_ao, keep_sparsity=.false.)
3388 CALL dbcsr_filter(matrix_g_ao, bs_env%eps_filter)
3391 CALL release_square_topology(dist=dist_ao_ao, mapped_dist=dist_row_ao)
3393 CALL timestop(handle)
3395 END SUBROUTINE build_g_ao
3427 SUBROUTINE contract_grid_panels(L_A, M_A, L_B, M_B, L_out, mat_out, scale, eps, para_env, &
3428 pan_first, pan_last, lb_eq_la, lout_eq_la, zero_out, &
3429 keep_sparsity, centroids, cutoff, grid_occupation)
3431 TYPE(dbcsr_type),
INTENT(INOUT),
TARGET :: l_a
3432 TYPE(dbcsr_type),
INTENT(INOUT) :: m_a
3433 TYPE(dbcsr_type),
INTENT(INOUT),
TARGET :: l_b
3434 TYPE(dbcsr_type),
INTENT(INOUT) :: m_b
3435 TYPE(dbcsr_type),
INTENT(INOUT),
TARGET :: l_out
3436 TYPE(dbcsr_type),
INTENT(INOUT) :: mat_out
3437 REAL(kind=dp),
INTENT(IN) :: scale, eps
3438 TYPE(mp_para_env_type),
INTENT(IN),
POINTER :: para_env
3439 INTEGER,
DIMENSION(:),
INTENT(IN) :: pan_first, pan_last
3440 LOGICAL,
INTENT(IN) :: lb_eq_la, lout_eq_la, zero_out
3441 LOGICAL,
INTENT(IN),
OPTIONAL :: keep_sparsity
3442 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN),
OPTIONAL :: centroids
3443 REAL(kind=dp),
INTENT(IN),
OPTIONAL :: cutoff
3444 REAL(kind=dp),
INTENT(OUT),
OPTIONAL :: grid_occupation
3446 CHARACTER(LEN=*),
PARAMETER :: routinen =
'contract_grid_panels'
3448 INTEGER :: blk0, blk1, handle, ipan, &
3449 n_grid_total, ncols_pan, nrows_pan
3450 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: gmap
3451 LOGICAL :: my_keep_sparsity, use_cutoff
3452 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: grid_used, useda, usedb
3453 TYPE(dbcsr_type) :: a_pan, b_pan, c_pan, la_pan, la_panc, &
3454 lb_pan, lb_panc, lout_pan, ma_sub, &
3455 mb_sub, tmp2, tmpa, tmpb
3456 TYPE(dbcsr_type),
POINTER :: rb_a, rb_b, rb_out
3457 TYPE(dbcsr_type),
TARGET :: la_near, lb_near, lout_near
3459 CALL timeset(routinen, handle)
3461 my_keep_sparsity = .false.
3462 IF (
PRESENT(keep_sparsity)) my_keep_sparsity = keep_sparsity
3463 use_cutoff =
PRESENT(centroids) .AND.
PRESENT(cutoff)
3464 IF (use_cutoff) use_cutoff = cutoff > 0.0_dp
3465 IF (
PRESENT(grid_occupation)) grid_occupation = 0.0_dp
3467 CALL dbcsr_get_info(l_a, nfullrows_total=n_grid_total)
3469 IF (zero_out)
CALL dbcsr_set(mat_out, 0.0_dp)
3471 DO ipan = 1,
SIZE(pan_first)
3472 blk0 = pan_first(ipan)
3473 blk1 = pan_last(ipan)
3476 CALL extract_grid_panel(l_a, blk0, blk1, la_pan)
3477 IF (.NOT. lb_eq_la)
CALL extract_grid_panel(l_b, blk0, blk1, lb_pan)
3478 IF (.NOT. lout_eq_la)
CALL extract_grid_panel(l_out, blk0, blk1, lout_pan)
3483 CALL collect_used_col_blocks(la_pan, para_env, useda)
3484 IF (.NOT. lb_eq_la)
THEN
3485 CALL collect_used_col_blocks(lb_pan, para_env, usedb)
3487 IF (
ALLOCATED(usedb))
DEALLOCATE (usedb)
3488 ALLOCATE (usedb, source=useda)
3490 IF (.NOT. (any(useda) .AND. any(usedb)))
THEN
3492 CALL dbcsr_release(la_pan)
3493 IF (.NOT. lb_eq_la)
CALL dbcsr_release(lb_pan)
3494 IF (.NOT. lout_eq_la)
CALL dbcsr_release(lout_pan)
3502 IF (use_cutoff)
THEN
3503 CALL mask_grid_blocks_near_panel(centroids, blk0, blk1, cutoff, grid_used)
3504 CALL extract_masked_blocks(l_a, grid_used, la_near, compress_rows=.true., blk_map=gmap)
3505 IF (.NOT. lb_eq_la)
CALL extract_masked_blocks(l_b, grid_used, lb_near, compress_rows=.true.)
3506 IF (.NOT. lout_eq_la)
CALL extract_masked_blocks(l_out, grid_used, lout_near, compress_rows=.true.)
3513 ELSE IF (use_cutoff)
THEN
3518 IF (lout_eq_la)
THEN
3520 ELSE IF (use_cutoff)
THEN
3530 CALL extract_masked_blocks(la_pan, useda, la_panc, compress_rows=.false.)
3531 CALL extract_masked_blocks(m_a, useda, ma_sub, compress_rows=.true.)
3532 CALL create_product_matrix(la_panc, ma_sub,
'N',
'N', tmpa)
3533 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, la_panc, ma_sub, 0.0_dp, tmpa, filter_eps=eps)
3534 CALL dbcsr_release(ma_sub)
3535 IF (use_cutoff)
THEN
3536 CALL build_geo_template_panel(la_pan, la_near, centroids, cutoff, blk0, a_pan, &
3539 CALL create_product_matrix(tmpa, rb_a,
'N',
'T', a_pan)
3541 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpa, rb_a, 0.0_dp, a_pan, &
3542 filter_eps=eps, retain_sparsity=use_cutoff)
3543 CALL dbcsr_release(tmpa)
3550 IF (
PRESENT(grid_occupation))
THEN
3551 CALL dbcsr_get_info(a_pan, nfullrows_total=nrows_pan, nfullcols_total=ncols_pan)
3552 grid_occupation = grid_occupation + dbcsr_get_occupation(a_pan)* &
3553 REAL(ncols_pan, dp)*
REAL(nrows_pan, dp)/ &
3554 (
REAL(n_grid_total, dp)*
REAL(n_grid_total, dp))
3561 CALL extract_masked_blocks(m_b, useda, mb_sub, compress_rows=.true.)
3562 CALL create_product_matrix(la_panc, mb_sub,
'N',
'N', tmpb)
3563 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, la_panc, mb_sub, 0.0_dp, tmpb, filter_eps=eps)
3565 CALL extract_masked_blocks(lb_pan, usedb, lb_panc, compress_rows=.false.)
3566 CALL extract_masked_blocks(m_b, usedb, mb_sub, compress_rows=.true.)
3567 CALL create_product_matrix(lb_panc, mb_sub,
'N',
'N', tmpb)
3568 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, lb_panc, mb_sub, 0.0_dp, tmpb, filter_eps=eps)
3569 CALL dbcsr_release(lb_panc)
3571 CALL dbcsr_release(mb_sub)
3572 IF (my_keep_sparsity)
THEN
3573 CALL dbcsr_create(b_pan, template=a_pan)
3574 CALL dbcsr_copy(b_pan, a_pan)
3575 CALL dbcsr_set(b_pan, 0.0_dp)
3576 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpb, rb_b, 0.0_dp, b_pan, &
3577 filter_eps=eps, retain_sparsity=.true.)
3579 CALL create_product_matrix(tmpb, rb_b,
'N',
'T', b_pan)
3580 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpb, rb_b, 0.0_dp, b_pan, filter_eps=eps)
3582 CALL dbcsr_release(tmpb)
3583 CALL dbcsr_release(la_panc)
3586 CALL dbcsr_create(c_pan, template=a_pan)
3587 CALL hadamard_product(a_pan, b_pan, c_pan, scale)
3588 CALL dbcsr_release(a_pan)
3589 CALL dbcsr_release(b_pan)
3592 CALL create_product_matrix(c_pan, rb_out,
'N',
'N', tmp2)
3593 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, c_pan, rb_out, 0.0_dp, tmp2, filter_eps=eps)
3594 CALL dbcsr_release(c_pan)
3597 IF (lout_eq_la)
THEN
3598 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, la_pan, tmp2, 1.0_dp, mat_out, filter_eps=eps)
3600 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, lout_pan, tmp2, 1.0_dp, mat_out, filter_eps=eps)
3601 CALL dbcsr_release(lout_pan)
3603 CALL dbcsr_release(tmp2)
3604 IF (.NOT. lb_eq_la)
CALL dbcsr_release(lb_pan)
3605 CALL dbcsr_release(la_pan)
3606 IF (use_cutoff)
THEN
3607 CALL dbcsr_release(la_near)
3608 IF (.NOT. lb_eq_la)
CALL dbcsr_release(lb_near)
3609 IF (.NOT. lout_eq_la)
CALL dbcsr_release(lout_near)
3614 CALL timestop(handle)
3616 END SUBROUTINE contract_grid_panels
3642 SUBROUTINE contract_grid_panels_sigma_c(mat_phi, mat_Z, mat_G_occ_ao, mat_G_vir_ao, &
3643 mat_W_aux, mat_Sigma_neg, mat_Sigma_pos, eps, para_env, &
3644 pan_first, pan_last, keep_sparsity, centroids, cutoff)
3646 TYPE(dbcsr_type),
INTENT(INOUT),
TARGET :: mat_phi, mat_z
3647 TYPE(dbcsr_type),
INTENT(INOUT) :: mat_g_occ_ao, mat_g_vir_ao, mat_w_aux
3648 TYPE(dbcsr_type),
INTENT(INOUT) :: mat_sigma_neg, mat_sigma_pos
3649 REAL(kind=dp),
INTENT(IN) :: eps
3650 TYPE(mp_para_env_type),
INTENT(IN),
POINTER :: para_env
3651 INTEGER,
DIMENSION(:),
INTENT(IN) :: pan_first, pan_last
3652 LOGICAL,
INTENT(IN),
OPTIONAL :: keep_sparsity
3653 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN),
OPTIONAL :: centroids
3654 REAL(kind=dp),
INTENT(IN),
OPTIONAL :: cutoff
3656 CHARACTER(LEN=*),
PARAMETER :: routinen =
'contract_grid_panels_sigma_c'
3658 INTEGER :: blk0, blk1, handle, ipan
3659 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: gmap
3660 LOGICAL :: my_keep_sparsity, use_cutoff
3661 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: grid_used, used_ao, used_ri
3662 TYPE(dbcsr_type) :: a_occ, a_vir, c_pan, g_occ_sub, &
3663 g_vir_sub, phi_pan, phi_panc, tmp2, &
3664 tmpa, tmpb, w_pan, w_sub, z_pan, &
3666 TYPE(dbcsr_type),
POINTER :: rb_phi, rb_z
3667 TYPE(dbcsr_type),
TARGET :: phi_near, z_near
3669 CALL timeset(routinen, handle)
3671 my_keep_sparsity = .false.
3672 IF (
PRESENT(keep_sparsity)) my_keep_sparsity = keep_sparsity
3673 use_cutoff =
PRESENT(centroids) .AND.
PRESENT(cutoff)
3674 IF (use_cutoff) use_cutoff = cutoff > 0.0_dp
3676 CALL dbcsr_set(mat_sigma_neg, 0.0_dp)
3677 CALL dbcsr_set(mat_sigma_pos, 0.0_dp)
3679 DO ipan = 1,
SIZE(pan_first)
3680 blk0 = pan_first(ipan)
3681 blk1 = pan_last(ipan)
3683 CALL extract_grid_panel(mat_phi, blk0, blk1, phi_pan)
3684 CALL extract_grid_panel(mat_z, blk0, blk1, z_pan)
3688 CALL collect_used_col_blocks(phi_pan, para_env, used_ao)
3689 CALL collect_used_col_blocks(z_pan, para_env, used_ri)
3690 IF (.NOT. (any(used_ao) .AND. any(used_ri)))
THEN
3691 CALL dbcsr_release(phi_pan)
3692 CALL dbcsr_release(z_pan)
3698 IF (use_cutoff)
THEN
3699 CALL mask_grid_blocks_near_panel(centroids, blk0, blk1, cutoff, grid_used)
3700 CALL extract_masked_blocks(mat_phi, grid_used, phi_near, compress_rows=.true., blk_map=gmap)
3701 CALL extract_masked_blocks(mat_z, grid_used, z_near, compress_rows=.true.)
3709 CALL extract_masked_blocks(phi_pan, used_ao, phi_panc, compress_rows=.false.)
3710 CALL extract_masked_blocks(z_pan, used_ri, z_panc, compress_rows=.false.)
3711 CALL extract_masked_blocks(mat_g_occ_ao, used_ao, g_occ_sub, compress_rows=.true.)
3712 CALL extract_masked_blocks(mat_g_vir_ao, used_ao, g_vir_sub, compress_rows=.true.)
3713 CALL extract_masked_blocks(mat_w_aux, used_ri, w_sub, compress_rows=.true.)
3718 CALL create_product_matrix(phi_panc, g_occ_sub,
'N',
'N', tmpa)
3719 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, phi_panc, g_occ_sub, 0.0_dp, tmpa, filter_eps=eps)
3720 IF (use_cutoff)
THEN
3721 CALL build_geo_template_panel(phi_pan, phi_near, centroids, cutoff, blk0, a_occ, &
3724 CALL create_product_matrix(tmpa, rb_phi,
'N',
'T', a_occ)
3726 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpa, rb_phi, 0.0_dp, a_occ, &
3727 filter_eps=eps, retain_sparsity=use_cutoff)
3728 CALL dbcsr_release(tmpa)
3729 CALL dbcsr_release(g_occ_sub)
3732 CALL create_product_matrix(phi_panc, g_vir_sub,
'N',
'N', tmpa)
3733 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, phi_panc, g_vir_sub, 0.0_dp, tmpa, filter_eps=eps)
3734 IF (use_cutoff)
THEN
3735 CALL build_geo_template_panel(phi_pan, phi_near, centroids, cutoff, blk0, a_vir, &
3738 CALL create_product_matrix(tmpa, rb_phi,
'N',
'T', a_vir)
3740 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpa, rb_phi, 0.0_dp, a_vir, &
3741 filter_eps=eps, retain_sparsity=use_cutoff)
3742 CALL dbcsr_release(tmpa)
3743 CALL dbcsr_release(g_vir_sub)
3749 CALL create_product_matrix(z_panc, w_sub,
'N',
'N', tmpb)
3750 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, z_panc, w_sub, 0.0_dp, tmpb, filter_eps=eps)
3751 IF (my_keep_sparsity)
THEN
3752 CALL dbcsr_create(w_pan, template=a_occ)
3753 CALL dbcsr_copy(w_pan, a_occ)
3754 CALL dbcsr_add(w_pan, a_vir, 1.0_dp, 1.0_dp)
3755 CALL dbcsr_set(w_pan, 0.0_dp)
3756 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpb, rb_z, 0.0_dp, w_pan, &
3757 filter_eps=eps, retain_sparsity=.true.)
3759 CALL create_product_matrix(tmpb, rb_z,
'N',
'T', w_pan)
3760 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, tmpb, rb_z, 0.0_dp, w_pan, filter_eps=eps)
3762 CALL dbcsr_release(tmpb)
3763 CALL dbcsr_release(w_sub)
3764 CALL dbcsr_release(phi_panc)
3765 CALL dbcsr_release(z_panc)
3768 CALL dbcsr_create(c_pan, template=a_occ)
3769 CALL hadamard_product(a_occ, w_pan, c_pan, 1.0_dp)
3770 CALL dbcsr_release(a_occ)
3771 CALL create_product_matrix(c_pan, rb_phi,
'N',
'N', tmp2)
3772 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, c_pan, rb_phi, 0.0_dp, tmp2, filter_eps=eps)
3773 CALL dbcsr_release(c_pan)
3774 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, phi_pan, tmp2, 1.0_dp, mat_sigma_neg, filter_eps=eps)
3775 CALL dbcsr_release(tmp2)
3778 CALL dbcsr_create(c_pan, template=a_vir)
3779 CALL hadamard_product(a_vir, w_pan, c_pan, 1.0_dp)
3780 CALL dbcsr_release(a_vir)
3781 CALL create_product_matrix(c_pan, rb_phi,
'N',
'N', tmp2)
3782 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, c_pan, rb_phi, 0.0_dp, tmp2, filter_eps=eps)
3783 CALL dbcsr_release(c_pan)
3784 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, phi_pan, tmp2, 1.0_dp, mat_sigma_pos, filter_eps=eps)
3785 CALL dbcsr_release(tmp2)
3787 CALL dbcsr_release(w_pan)
3788 CALL dbcsr_release(z_pan)
3789 CALL dbcsr_release(phi_pan)
3790 IF (use_cutoff)
THEN
3791 CALL dbcsr_release(phi_near)
3792 CALL dbcsr_release(z_near)
3797 CALL timestop(handle)
3799 END SUBROUTINE contract_grid_panels_sigma_c
3808 SUBROUTINE hadamard_product(matrix_A, matrix_B, matrix_C, fac)
3810 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_a, matrix_b, matrix_c
3811 REAL(kind=dp),
INTENT(IN) ::
fac
3813 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hadamard_product'
3815 INTEGER :: col, handle, row
3817 REAL(kind=dp),
DIMENSION(:, :),
POINTER :: blk_b, blk_c
3818 TYPE(dbcsr_iterator_type) :: iter
3820 CALL timeset(routinen, handle)
3822 CALL dbcsr_copy(matrix_c, matrix_a)
3824 CALL dbcsr_iterator_start(iter, matrix_c)
3825 DO WHILE (dbcsr_iterator_blocks_left(iter))
3826 CALL dbcsr_iterator_next_block(iter, row, col, blk_c)
3828 CALL dbcsr_get_block_p(matrix_b, row, col, blk_b, found)
3831 blk_c(:, :) =
fac*blk_c(:, :)*blk_b(:, :)
3834 blk_c(:, :) = 0.0_dp
3837 CALL dbcsr_iterator_stop(iter)
3839 CALL timestop(handle)
3841 END SUBROUTINE hadamard_product
3857 SUBROUTINE compute_w(bs_env, qs_env, mat_chi_Gamma_tau, fm_W_time)
3858 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
3859 TYPE(qs_environment_type),
POINTER :: qs_env
3860 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: mat_chi_gamma_tau
3861 TYPE(cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_w_time
3863 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_W'
3865 INTEGER :: handle, i_t, j_w
3867 TYPE(cp_fm_type) :: fm_m_inv_v_sqrt, fm_v, fm_v_sqrt
3869 CALL timeset(routinen, handle)
3873 CALL create_fm_w_mic_time(bs_env, fm_w_time)
3876 CALL cp_fm_create(fm_v, bs_env%fm_RI_RI%matrix_struct)
3877 CALL cp_fm_create(fm_v_sqrt, bs_env%fm_RI_RI%matrix_struct)
3878 CALL cp_fm_create(fm_m_inv_v_sqrt, bs_env%fm_RI_RI%matrix_struct)
3881 CALL compute_v_minvvsqrt(bs_env, qs_env, fm_v, fm_v_sqrt, fm_m_inv_v_sqrt)
3884 DO j_w = 1, bs_env%num_time_freq_points
3886 CALL compute_fm_chi_gamma_freq(bs_env, bs_env%fm_chi_Gamma_freq, j_w, mat_chi_gamma_tau)
3890 CALL compute_fm_w_freq(bs_env, bs_env%fm_chi_Gamma_freq, fm_v_sqrt, &
3891 fm_m_inv_v_sqrt, bs_env%fm_W_MIC_freq)
3894 CALL fourier_transform_w_to_t(bs_env, fm_w_time, bs_env%fm_W_MIC_freq, j_w)
3898 CALL multiply_fm_w_mic_time_with_minv_gamma(bs_env, qs_env, fm_w_time)
3900 IF (bs_env%unit_nr > 0)
THEN
3901 WRITE (bs_env%unit_nr,
'(T2,A,T58,A,F7.1,A)') &
3902 τ
'Computed W(i),',
' Execution time', m_walltime() - t1,
' s'
3905 CALL dbcsr_deallocate_matrix_set(mat_chi_gamma_tau)
3908 CALL cp_fm_release(fm_v)
3909 CALL cp_fm_release(fm_v_sqrt)
3910 CALL cp_fm_release(fm_m_inv_v_sqrt)
3913 IF (bs_env%rtp_method == rtp_method_bse)
THEN
3915 CALL cp_fm_create(bs_env%fm_W_MIC_freq_zero, bs_env%fm_W_MIC_freq%matrix_struct)
3917 CALL cp_fm_set_all(bs_env%fm_W_MIC_freq_zero, 0.0_dp)
3919 DO i_t = 1, bs_env%num_time_freq_points
3921 CALL cp_fm_scale_and_add(1.0_dp, bs_env%fm_W_MIC_freq_zero, &
3922 bs_env%imag_time_weights_freq_zero(i_t), fm_w_time(i_t))
3925 CALL fm_write(bs_env%fm_W_MIC_freq_zero, 0,
"W_freq_rtp", qs_env)
3927 IF (bs_env%unit_nr > 0)
THEN
3928 WRITE (bs_env%unit_nr,
'(T2,A,T57,A,F7.1,A)') &
3929 'Computed W(0),',
' Execution time', m_walltime() - t1,
' s'
3933 IF (bs_env%unit_nr > 0)
WRITE (bs_env%unit_nr,
'(A)')
' '
3935 CALL timestop(handle)
3937 END SUBROUTINE compute_w
3949 SUBROUTINE compute_v_minvvsqrt(bs_env, qs_env, fm_V, fm_V_sqrt, fm_Minv_Vsqrt)
3950 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
3951 TYPE(qs_environment_type),
POINTER :: qs_env
3952 TYPE(cp_fm_type),
INTENT(INOUT) :: fm_v, fm_v_sqrt, fm_minv_vsqrt
3954 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_V_MinvVsqrt'
3956 INTEGER :: handle, info, n_ri, ndep
3957 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
3958 TYPE(cell_type),
POINTER :: cell
3959 TYPE(cp_fm_type) :: fm_work
3960 TYPE(cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :) :: fm_m
3961 TYPE(dbcsr_p_type),
DIMENSION(:, :),
POINTER :: mat_v_kp
3962 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
3963 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
3965 CALL timeset(routinen, handle)
3968 CALL cp_fm_create(fm_work, fm_v%matrix_struct)
3973 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell, &
3974 qs_kind_set=qs_kind_set, atomic_kind_set=atomic_kind_set)
3976 ALLOCATE (mat_v_kp(1:1, 1:2))
3977 NULLIFY (mat_v_kp(1, 1)%matrix, mat_v_kp(1, 2)%matrix)
3978 ALLOCATE (mat_v_kp(1, 1)%matrix, mat_v_kp(1, 2)%matrix)
3980 CALL dbcsr_create(mat_v_kp(1, 1)%matrix, template=bs_env%mat_RI_RI%matrix)
3981 CALL dbcsr_reserve_all_blocks(mat_v_kp(1, 1)%matrix)
3982 CALL dbcsr_set(mat_v_kp(1, 1)%matrix, 0.0_dp)
3985 CALL dbcsr_create(mat_v_kp(1, 2)%matrix, template=bs_env%mat_RI_RI%matrix)
3986 CALL dbcsr_reserve_all_blocks(mat_v_kp(1, 2)%matrix)
3987 CALL dbcsr_set(mat_v_kp(1, 2)%matrix, 0.0_dp)
3989 bs_env%kpoints_chi_eps_W%nkp_grid = bs_env%nkp_grid_chi_eps_W_orig
3991 CALL build_2c_coulomb_matrix_kp(mat_v_kp, bs_env%kpoints_chi_eps_W,
"RI_AUX", cell, &
3992 particle_set, qs_kind_set, atomic_kind_set, &
3993 bs_env%size_lattice_sum_V, operator_coulomb, 1, 1)
3996 CALL copy_dbcsr_to_fm(mat_v_kp(1, 1)%matrix, fm_v)
3998 CALL dbcsr_deallocate_matrix(mat_v_kp(1, 1)%matrix)
3999 CALL dbcsr_deallocate_matrix(mat_v_kp(1, 2)%matrix)
4000 DEALLOCATE (mat_v_kp)
4005 CALL ri_2c_integral_mat(qs_env, fm_m, fm_v, n_ri, bs_env%ri_metric, &
4006 do_kpoints=.false., regularization_ri=bs_env%regularization_RI)
4011 CALL cp_fm_cholesky_decompose(fm_m(1, 1), info_out=info)
4013 CALL cp_fm_cholesky_invert(fm_m(1, 1))
4014 CALL cp_fm_uplo_to_full(fm_m(1, 1), fm_work)
4017 CALL cp_fm_power(fm_m(1, 1), fm_work, -1.0_dp, bs_env%eps_eigval_mat_RI, ndep)
4018 CALL cp_fm_to_fm(fm_work, fm_m(1, 1))
4024 CALL cp_fm_to_fm(fm_v, fm_v_sqrt)
4025 CALL cp_fm_cholesky_decompose(fm_v_sqrt, info_out=info)
4027 CALL clean_lower_part(fm_v_sqrt)
4029 CALL cp_fm_power(fm_v, fm_v_sqrt, 0.5_dp, bs_env%eps_eigval_mat_RI, ndep)
4035 CALL parallel_gemm(
"N",
"T", n_ri, n_ri, n_ri, 1.0_dp, fm_m(1, 1), fm_v_sqrt, &
4036 0.0_dp, fm_minv_vsqrt)
4038 CALL cp_fm_release(fm_m)
4039 CALL cp_fm_release(fm_work)
4041 CALL timestop(handle)
4043 END SUBROUTINE compute_v_minvvsqrt
4057 SUBROUTINE compute_fm_w_freq(bs_env, fm_chi_freq_j, fm_V_sqrt, fm_Minv_Vsqrt, fm_W_freq_j)
4058 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
4059 TYPE(cp_fm_type),
INTENT(IN) :: fm_chi_freq_j, fm_v_sqrt, fm_minv_vsqrt
4060 TYPE(cp_fm_type),
INTENT(INOUT) :: fm_w_freq_j
4062 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_fm_W_freq'
4064 INTEGER :: handle, info, n_ri, ndep
4065 TYPE(cp_fm_type) :: fm_eps_freq_j, fm_work
4067 CALL timeset(routinen, handle)
4071 CALL cp_fm_create(fm_eps_freq_j, fm_chi_freq_j%matrix_struct)
4072 CALL cp_fm_create(fm_work, fm_chi_freq_j%matrix_struct)
4078 CALL parallel_gemm(
'N',
'N', n_ri, n_ri, n_ri, 1.0_dp, &
4079 fm_chi_freq_j, fm_minv_vsqrt, 0.0_dp, fm_work)
4082 CALL parallel_gemm(
'T',
'N', n_ri, n_ri, n_ri, 1.0_dp, &
4083 fm_minv_vsqrt, fm_work, 0.0_dp, fm_eps_freq_j)
4086 CALL fm_add_on_diag(fm_eps_freq_j, 1.0_dp)
4089 CALL cp_fm_uplo_to_full(fm_eps_freq_j, fm_work)
4096 CALL cp_fm_cholesky_decompose(fm_eps_freq_j, info_out=info)
4100 CALL cp_fm_cholesky_invert(fm_eps_freq_j)
4101 CALL cp_fm_uplo_to_full(fm_eps_freq_j, fm_work)
4104 CALL cp_fm_power(fm_eps_freq_j, fm_work, -1.0_dp, bs_env%eps_eigval_mat_RI, ndep)
4105 CALL cp_fm_to_fm(fm_work, fm_eps_freq_j)
4109 CALL fm_add_on_diag(fm_eps_freq_j, -1.0_dp)
4112 CALL parallel_gemm(
'N',
'N', n_ri, n_ri, n_ri, 1.0_dp, fm_eps_freq_j, fm_v_sqrt, &
4116 CALL parallel_gemm(
'T',
'N', n_ri, n_ri, n_ri, 1.0_dp, fm_v_sqrt, fm_work, &
4117 0.0_dp, fm_w_freq_j)
4120 CALL cp_fm_release(fm_work)
4121 CALL cp_fm_release(fm_eps_freq_j)
4123 CALL timestop(handle)
4125 END SUBROUTINE compute_fm_w_freq
4132 SUBROUTINE fm_add_on_diag(fm, alpha)
4133 TYPE(cp_fm_type),
INTENT(INOUT) :: fm
4134 REAL(kind=dp),
INTENT(IN) :: alpha
4136 CHARACTER(LEN=*),
PARAMETER :: routinen =
'fm_add_on_diag'
4138 INTEGER :: handle, i_global, i_row, j_col, &
4139 j_global, ncol_local, nrow_local
4140 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
4142 CALL timeset(routinen, handle)
4144 CALL cp_fm_get_info(matrix=fm, &
4145 nrow_local=nrow_local, &
4146 ncol_local=ncol_local, &
4147 row_indices=row_indices, &
4148 col_indices=col_indices)
4150 DO j_col = 1, ncol_local
4151 j_global = col_indices(j_col)
4152 DO i_row = 1, nrow_local
4153 i_global = row_indices(i_row)
4154 IF (j_global == i_global)
THEN
4155 fm%local_data(i_row, j_col) = fm%local_data(i_row, j_col) + alpha
4160 CALL timestop(handle)
4162 END SUBROUTINE fm_add_on_diag
4168 SUBROUTINE clean_lower_part(fm_mat)
4169 TYPE(cp_fm_type) :: fm_mat
4171 CHARACTER(LEN=*),
PARAMETER :: routinen =
'clean_lower_part'
4173 INTEGER :: handle, i_row, j_col, j_global, &
4174 ncol_local, nrow_local
4175 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
4177 CALL timeset(routinen, handle)
4179 CALL cp_fm_get_info(matrix=fm_mat, &
4180 nrow_local=nrow_local, ncol_local=ncol_local, &
4181 row_indices=row_indices, col_indices=col_indices)
4183 DO j_col = 1, ncol_local
4184 j_global = col_indices(j_col)
4185 DO i_row = 1, nrow_local
4186 IF (j_global < row_indices(i_row)) fm_mat%local_data(i_row, j_col) = 0.0_dp
4190 CALL timestop(handle)
4192 END SUBROUTINE clean_lower_part
4205 SUBROUTINE compute_sigma_x(bs_env, qs_env, mat_phi_mu_l, mat_Z_lP, fm_Sigma_x_Gamma)
4207 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
4208 TYPE(qs_environment_type),
POINTER :: qs_env
4209 TYPE(dbcsr_type),
INTENT(INOUT) :: mat_phi_mu_l, mat_z_lp
4210 TYPE(cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_sigma_x_gamma
4212 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_Sigma_x'
4214 INTEGER :: handle, ispin
4215 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: pan_first, pan_last
4216 INTEGER,
DIMENSION(:),
POINTER :: blk_aux, dist_row_aux
4218 TYPE(cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :) :: fm_vtr_gamma
4219 TYPE(dbcsr_distribution_type) :: dist_aux_aux
4220 TYPE(dbcsr_type) :: mat_sigma_x_gamma, matrix_d_ao, &
4223 CALL timeset(routinen, handle)
4227 ALLOCATE (fm_sigma_x_gamma(bs_env%n_spin))
4228 DO ispin = 1, bs_env%n_spin
4229 CALL cp_fm_create(fm_sigma_x_gamma(ispin), bs_env%fm_s_Gamma%matrix_struct)
4232 CALL dbcsr_create(mat_sigma_x_gamma, template=bs_env%mat_ao_ao%matrix)
4234 CALL resolve_grid_panels(bs_env, mat_phi_mu_l, pan_first, pan_last)
4239 CALL setup_square_topology(mat_z_lp, dist_aux_aux, blk_aux, dist_row_aux)
4241 CALL ri_2c_integral_mat(qs_env, fm_vtr_gamma, bs_env%fm_RI_RI, bs_env%n_RI, &
4242 bs_env%trunc_coulomb, do_kpoints=.false.)
4245 CALL multiply_fm_w_mic_time_with_minv_gamma(bs_env, qs_env, fm_vtr_gamma(:, 1))
4247 CALL dbcsr_create(matrix_v_aux,
"V_aux", dist_aux_aux, dbcsr_type_no_symmetry, blk_aux, blk_aux)
4249 IF (bs_env%ri_rs%cutoff_radius_g_w > 0.0_dp .AND. &
4250 ALLOCATED(bs_env%ri_rs%atom_centers))
THEN
4251 CALL reserve_blocks_within_radius(matrix_v_aux, bs_env%ri_rs%atom_centers, &
4252 bs_env%ri_rs%cutoff_radius_g_w)
4253 CALL copy_fm_to_dbcsr(fm_vtr_gamma(1, 1), matrix_v_aux, keep_sparsity=.true.)
4255 CALL copy_fm_to_dbcsr(fm_vtr_gamma(1, 1), matrix_v_aux, keep_sparsity=.false.)
4257 CALL dbcsr_filter(matrix_v_aux, bs_env%eps_filter)
4264 DO ispin = 1, bs_env%n_spin
4267 CALL build_g_ao(bs_env, 0.0_dp, ispin, .true., .false., mat_phi_mu_l, matrix_d_ao)
4269 CALL contract_grid_panels(l_a=mat_phi_mu_l, m_a=matrix_d_ao, &
4270 l_b=mat_z_lp, m_b=matrix_v_aux, &
4271 l_out=mat_phi_mu_l, mat_out=mat_sigma_x_gamma, &
4272 scale=1.0_dp, eps=bs_env%eps_filter, &
4273 para_env=bs_env%para_env, &
4274 pan_first=pan_first, pan_last=pan_last, &
4275 lb_eq_la=.false., lout_eq_la=.true., zero_out=.true., &
4276 keep_sparsity=bs_env%ri_rs%keep_sparsity_rirs, &
4277 centroids=bs_env%ri_rs%chunk_centroids, &
4278 cutoff=bs_env%ri_rs%cutoff_radius_v_w)
4279 CALL dbcsr_scale(mat_sigma_x_gamma, -1.0_dp)
4281 CALL dbcsr_release(matrix_d_ao)
4284 CALL copy_dbcsr_to_fm(mat_sigma_x_gamma, fm_sigma_x_gamma(ispin))
4288 IF (bs_env%unit_nr > 0)
THEN
4289 WRITE (bs_env%unit_nr,
'(T2,A,T58,A,F7.1,A)') &
4290 Σ
'Computed ^x(k=0),',
' Execution time', m_walltime() - t1,
' s'
4291 WRITE (bs_env%unit_nr,
'(A)')
' '
4297 CALL dbcsr_release(matrix_v_aux)
4298 CALL dbcsr_release(mat_sigma_x_gamma)
4299 CALL release_square_topology(dist=dist_aux_aux, mapped_dist=dist_row_aux)
4301 CALL cp_fm_release(fm_vtr_gamma)
4303 CALL timestop(handle)
4305 END SUBROUTINE compute_sigma_x
4317 SUBROUTINE compute_sigma_c(bs_env, fm_W_time, mat_phi_mu_l, mat_Z_lP, fm_Sigma_c_Gamma_time)
4319 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
4320 TYPE(cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_w_time
4321 TYPE(dbcsr_type),
INTENT(INOUT) :: mat_phi_mu_l, mat_z_lp
4322 TYPE(cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :, :) :: fm_sigma_c_gamma_time
4324 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_Sigma_c'
4326 INTEGER :: handle, i_t, ispin
4327 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: pan_first, pan_last
4328 INTEGER,
DIMENSION(:),
POINTER :: blk_aux, dist_row_aux
4329 REAL(kind=dp) :: t1, tau
4330 TYPE(dbcsr_distribution_type) :: dist_aux_aux
4331 TYPE(dbcsr_p_type),
DIMENSION(:, :),
POINTER :: mat_sigma_neg_tau, mat_sigma_pos_tau
4332 TYPE(dbcsr_type) :: matrix_g_occ_ao, matrix_g_vir_ao, &
4335 CALL timeset(routinen, handle)
4340 CALL setup_square_topology(mat_z_lp, dist_aux_aux, blk_aux, dist_row_aux)
4342 CALL resolve_grid_panels(bs_env, mat_phi_mu_l, pan_first, pan_last)
4345 NULLIFY (mat_sigma_neg_tau, mat_sigma_pos_tau)
4346 ALLOCATE (mat_sigma_neg_tau(bs_env%num_time_freq_points, bs_env%n_spin))
4347 ALLOCATE (mat_sigma_pos_tau(bs_env%num_time_freq_points, bs_env%n_spin))
4349 DO i_t = 1, bs_env%num_time_freq_points
4350 DO ispin = 1, bs_env%n_spin
4351 ALLOCATE (mat_sigma_neg_tau(i_t, ispin)%matrix)
4352 ALLOCATE (mat_sigma_pos_tau(i_t, ispin)%matrix)
4353 CALL dbcsr_create(mat_sigma_neg_tau(i_t, ispin)%matrix, template=bs_env%mat_ao_ao%matrix)
4354 CALL dbcsr_create(mat_sigma_pos_tau(i_t, ispin)%matrix, template=bs_env%mat_ao_ao%matrix)
4363 DO i_t = 1, bs_env%num_time_freq_points
4364 tau = bs_env%imag_time_points(i_t)
4366 CALL dbcsr_create(matrix_w_aux,
"W_aux", dist_aux_aux, dbcsr_type_no_symmetry, blk_aux, blk_aux)
4367 IF (bs_env%ri_rs%cutoff_radius_g_w > 0.0_dp .AND. &
4368 ALLOCATED(bs_env%ri_rs%atom_centers))
THEN
4369 CALL reserve_blocks_within_radius(matrix_w_aux, bs_env%ri_rs%atom_centers, &
4370 bs_env%ri_rs%cutoff_radius_g_w)
4371 CALL copy_fm_to_dbcsr(fm_w_time(i_t), matrix_w_aux, keep_sparsity=.true.)
4373 CALL copy_fm_to_dbcsr(fm_w_time(i_t), matrix_w_aux, keep_sparsity=.false.)
4375 CALL dbcsr_filter(matrix_w_aux, bs_env%eps_filter)
4377 DO ispin = 1, bs_env%n_spin
4381 CALL build_g_ao(bs_env, tau, ispin, .true., .false., mat_phi_mu_l, matrix_g_occ_ao)
4382 CALL build_g_ao(bs_env, tau, ispin, .false., .true., mat_phi_mu_l, matrix_g_vir_ao)
4385 CALL contract_grid_panels_sigma_c(mat_phi=mat_phi_mu_l, mat_z=mat_z_lp, &
4386 mat_g_occ_ao=matrix_g_occ_ao, &
4387 mat_g_vir_ao=matrix_g_vir_ao, &
4388 mat_w_aux=matrix_w_aux, &
4389 mat_sigma_neg=mat_sigma_neg_tau(i_t, ispin)%matrix, &
4390 mat_sigma_pos=mat_sigma_pos_tau(i_t, ispin)%matrix, &
4391 eps=bs_env%eps_filter, &
4392 para_env=bs_env%para_env, &
4393 pan_first=pan_first, pan_last=pan_last, &
4394 keep_sparsity=bs_env%ri_rs%keep_sparsity_rirs, &
4395 centroids=bs_env%ri_rs%chunk_centroids, &
4396 cutoff=bs_env%ri_rs%cutoff_radius_v_w)
4397 CALL dbcsr_scale(mat_sigma_neg_tau(i_t, ispin)%matrix, -1.0_dp)
4399 CALL dbcsr_release(matrix_g_occ_ao)
4400 CALL dbcsr_release(matrix_g_vir_ao)
4402 IF (bs_env%unit_nr > 0)
THEN
4403 WRITE (bs_env%unit_nr,
'(T2,A,I15,A,I3,A,F7.1,A)') &
4404 Στ
'Computed ^c(i) for time point', i_t,
' /', bs_env%num_time_freq_points, &
4405 ', Execution time', m_walltime() - t1,
' s'
4410 CALL dbcsr_release(matrix_w_aux)
4414 IF (bs_env%unit_nr > 0)
WRITE (bs_env%unit_nr,
'(A)')
' '
4419 CALL fill_fm_sigma_c_gamma_time(fm_sigma_c_gamma_time, bs_env, &
4420 mat_sigma_pos_tau, mat_sigma_neg_tau)
4422 CALL cp_fm_release(fm_w_time)
4424 CALL dbcsr_deallocate_matrix_set(mat_sigma_neg_tau)
4425 CALL dbcsr_deallocate_matrix_set(mat_sigma_pos_tau)
4427 CALL release_square_topology(dist=dist_aux_aux, mapped_dist=dist_row_aux)
4429 CALL delete_unnecessary_files(bs_env)
4430 CALL timestop(handle)
4432 END SUBROUTINE compute_sigma_c
4441 SUBROUTINE setup_square_topology(matrix_template, square_dist, blk_sizes, mapped_dist)
4443 TYPE(dbcsr_type),
INTENT(IN) :: matrix_template
4444 TYPE(dbcsr_distribution_type),
INTENT(OUT) :: square_dist
4445 INTEGER,
DIMENSION(:),
INTENT(OUT),
POINTER :: blk_sizes, mapped_dist
4447 CHARACTER(LEN=*),
PARAMETER :: routinen =
'setup_square_topology'
4449 INTEGER :: handle, i, nprows
4450 INTEGER,
DIMENSION(:),
POINTER :: col_blk, col_dist
4451 TYPE(dbcsr_distribution_type) :: dist_template
4453 CALL timeset(routinen, handle)
4455 CALL dbcsr_get_info(matrix_template, distribution=dist_template, col_blk_size=col_blk)
4456 CALL dbcsr_distribution_get(dist_template, col_dist=col_dist, nprows=nprows)
4458 blk_sizes => col_blk
4459 ALLOCATE (mapped_dist(
SIZE(blk_sizes)))
4460 DO i = 1,
SIZE(blk_sizes)
4461 mapped_dist(i) = mod(i - 1, nprows)
4463 CALL dbcsr_distribution_new(square_dist, template=dist_template, &
4464 row_dist=mapped_dist, col_dist=col_dist)
4466 CALL timestop(handle)
4468 END SUBROUTINE setup_square_topology
4475 SUBROUTINE release_square_topology(dist, mapped_dist)
4477 TYPE(dbcsr_distribution_type),
INTENT(INOUT) :: dist
4478 INTEGER,
DIMENSION(:),
INTENT(INOUT),
POINTER :: mapped_dist
4480 CALL dbcsr_distribution_release(dist)
4481 IF (
ASSOCIATED(mapped_dist))
THEN
4482 DEALLOCATE (mapped_dist)
4483 NULLIFY (mapped_dist)
4486 END SUBROUTINE release_square_topology
static GRID_HOST_DEVICE double fac(const int i)
Factorial function, e.g. fac(5) = 5! = 120.
static GRID_HOST_DEVICE int idx(const orbital a)
Return coset index of given orbital angular momentum.
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
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.
Handles all functions related to the CELL.
constants for the different operators of the 2c-integrals
integer, parameter, public operator_coulomb
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
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_get_block_p(matrix, row, col, block, found, row_size, col_size)
...
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)
...
subroutine, public dbcsr_binary_write(matrix, filepath)
...
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_binary_read(filepath, distribution, matrix_new)
...
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)
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....
subroutine, public cp_fm_uplo_to_full(matrix, work, uplo)
given a triangular matrix according to uplo, computes the corresponding full matrix
various cholesky decomposition related routines
subroutine, public cp_fm_cholesky_solve(matrix, matrixb, n, info_out)
solves A*X = B for X, given the Cholesky decomposition U of the symmetric positive def....
subroutine, public cp_fm_cholesky_invert(matrix, n, info_out)
used to replace the cholesky decomposition by the inverse
subroutine, public cp_fm_cholesky_decompose(matrix, n, info_out)
used to replace a symmetric positive def. matrix M with its cholesky decomposition U: M = U^T * U,...
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
subroutine, public cp_fm_power(matrix, work, exponent, threshold, n_dependent, verbose, eigvals)
...
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_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_submatrix(fm, new_values, start_row, start_col, n_rows, n_cols, alpha, beta, transpose)
sets a submatrix of a full matrix fm(start_row:start_row+n_rows,start_col:start_col+n_cols) = alpha*o...
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
subroutine, public cp_fm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
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...
integer, parameter, public cp_p_file
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
Utility method to build 3-center integrals for small cell GW.
subroutine, public build_3c_integral_block_ctx(int_3c, ctx, ws, atom_j, atom_k, atom_i, cell_j, cell_k, cell_i, j_offset, k_offset, i_offset, screened)
Computes the 3c integral block (mu(atom_j) nu(atom_k) | P(atom_i)) for ONE atom triple,...
subroutine, public gw_3c_ws_create(ws, ctx)
Creates a per-thread 3c workspace: libint object + LIBXSMM contraction buffers.
subroutine, public gw_3c_ws_release(ws)
Releases a per-thread 3c workspace.
subroutine, public gw_3c_ctx_release(ctx)
Releases the shared 3c-integral context.
subroutine, public gw_3c_ctx_create(ctx, qs_env, potential_parameter, basis_j, basis_k, basis_i)
Builds the shared 3c-integral context: screening radii, basis maxima, contracted sphi tables,...
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 delete_unnecessary_files(bs_env)
...
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 fm_write(fm, matrix_index, matrix_name, qs_env)
...
subroutine, public compute_qp_energies(bs_env, qs_env, fm_sigma_x_gamma, fm_sigma_c_gamma_time)
...
subroutine, public multiply_fm_w_mic_time_with_minv_gamma(bs_env, qs_env, fm_w_mic_time)
...
subroutine, public g_occ_vir(bs_env, tau, fm_g_gamma, ispin, occ, vir)
...
subroutine, public create_fm_w_mic_time(bs_env, fm_w_mic_time)
...
subroutine, public fourier_transform_w_to_t(bs_env, fm_w_mic_time, fm_w_mic_freq_j, j_w)
...
GW using RI-RS Approximation for molecules.
subroutine, public ri_rs_grid_assembler(qs_env, bs_env, ri_rs_grid_points)
Compute grid points for RI-RS Right now based on Ivan and Xavier implementation JCP 150,...
subroutine, public precompute_ri_rs_radii(qs_env, bs_env)
Compute per-atom AO and RI basis radii from the most diffuse Gaussian primitive in the AO ("ORB") and...
subroutine, public gw_calc_non_periodic_ri_rs(qs_env, bs_env)
GW calculation using RI-RS formalism for molecules.
subroutine, public atomic_basis_at_grid_point(qs_env, 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...
subroutine, public get_basis_offsets(particle_set, qs_kind_set, first_sgf, total_sgf)
Computes the AO basis offsets: first_sgf(iatom) is the global index of the first spherical Gaussian f...
subroutine, public solve_d_lp_distributed(phi_local, d_vec, d_lp, n_loc, n_ao, n_rhs, tikhonov, para_env_sub, blacs_env_sub, fm_struct_d, fm_struct_b, fm_d, fm_b, info)
Distributed pdpotrf/pdpotrs solve of D x = b for one atom of the RI-RS Z_lP build (Phase B,...
subroutine, public compute_coeff_z_lp(qs_env, bs_env, ri_rs_grid_points, mat_phi_mu_l, mat_z_lp)
Computes the RI-RS fitting coefficients Z_lP by solving, independently for every RI atom P,...
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 int_8
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
integer, parameter, public int_4
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
subroutine, public m_memory_details(memtotal, memfree, buffers, cached, slab, sreclaimable, memlikelyfree)
get more detailed memory info, all units are bytes. the only 'useful' option is MemLikelyFree which i...
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
subroutine, public m_hostnm(hname)
...
Interface to the message passing library MPI.
Framework for 2c-integrals for RI.
subroutine, public ri_2c_integral_mat(qs_env, fm_matrix_minv_l_kpoints, fm_matrix_l, dimen_ri, ri_metric, do_kpoints, kpoints, put_mat_ks_env, regularization_ri, ikp_ext, do_build_cell_index)
...
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public ncoset
integer, dimension(:, :), allocatable, public indco
basic linear algebra operations for full matrixes
Define the data structure for the particle information.
Definition of physical constants:
real(kind=dp), parameter, public angstrom
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.
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.
All kind of helpful little routines.
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...
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...
Shared read-only context for repeated 3-center integral block builds: screening parameters,...
Per-thread workspace for 3-center integral block builds: libint object + contraction buffers....
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.