25 USE dbt_api,
ONLY: dbt_get_block,&
26 dbt_iterator_blocks_left,&
27 dbt_iterator_next_block,&
48#include "./base/base_uses.f90"
53 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'xas_tdp_kernel'
80 SUBROUTINE kernel_coulomb_xc(coul_ker, xc_ker, donor_state, xas_tdp_env, xas_tdp_control, qs_env)
89 CHARACTER(len=*),
PARAMETER :: routinen =
'kernel_coulomb_xc'
91 INTEGER :: batch_size, bo(2), handle, i, ibatch, &
92 iex, lb, natom, nbatch, ndo_mo, &
93 ndo_so, nex_atom, nsgfp, ri_atom, &
95 INTEGER,
DIMENSION(:),
POINTER :: blk_size
96 LOGICAL :: do_coulomb, do_sc, do_sf, do_sg, do_tp, &
98 REAL(
dp),
DIMENSION(:, :),
POINTER :: pq
103 NULLIFY (contr1_int, pq, para_env, dist, blk_size)
106 ndo_mo = donor_state%ndo_mo
107 do_xc = xas_tdp_control%do_xc
108 do_sg = xas_tdp_control%do_singlet
109 do_tp = xas_tdp_control%do_triplet
110 do_sc = xas_tdp_control%do_spin_cons
111 do_sf = xas_tdp_control%do_spin_flip
112 ndo_so = ndo_mo;
IF (xas_tdp_control%do_uks) ndo_so = 2*ndo_mo
113 ri_atom = donor_state%at_index
114 CALL get_qs_env(qs_env, natom=natom, para_env=para_env)
115 do_coulomb = xas_tdp_control%do_coulomb
116 dist => donor_state%dbcsr_dist
117 blk_size => donor_state%blk_size
120 IF ((.NOT. do_coulomb) .AND. (.NOT. do_xc))
RETURN
122 CALL timeset(routinen, handle)
125 CALL contract2_ao_to_domo(contr1_int,
"COULOMB", donor_state, xas_tdp_env, xas_tdp_control, qs_env)
128 IF (do_coulomb)
CALL coulomb(coul_ker, contr1_int, dist, blk_size, xas_tdp_env, &
129 xas_tdp_control, qs_env)
138 pq => xas_tdp_env%ri_inv_coul
143 IF (.NOT. xas_tdp_env%fxc_avail)
THEN
148 nex_atom =
SIZE(xas_tdp_env%ex_atom_indices)
151 DO ibatch = 0, nbatch - 1
154 DO iex = bo(1), bo(2)
156 IF (xas_tdp_env%ex_atom_indices(iex) == ri_atom)
THEN
157 source = ibatch*batch_size
166 lb = 1;
IF (do_sf .AND. .NOT. do_sc) lb = 4
167 ub = 2;
IF (do_sc) ub = 3;
IF (do_sf) ub = 4
169 IF (.NOT.
ASSOCIATED(xas_tdp_env%ri_fxc(ri_atom, i)%array))
THEN
170 ALLOCATE (xas_tdp_env%ri_fxc(ri_atom, i)%array(nsgfp, nsgfp))
172 CALL para_env%bcast(xas_tdp_env%ri_fxc(ri_atom, i)%array, source)
175 xas_tdp_env%fxc_avail = .true.
179 IF (do_sg .OR. do_tp)
THEN
180 CALL rcs_xc(xc_ker(1)%matrix, xc_ker(2)%matrix, contr1_int, dist, blk_size, &
181 donor_state, xas_tdp_env, xas_tdp_control, qs_env)
185 CALL sc_os_xc(xc_ker(3)%matrix, contr1_int, dist, blk_size, donor_state, &
186 xas_tdp_env, xas_tdp_control, qs_env)
190 CALL ondiag_sf_os_xc(xc_ker(4)%matrix, contr1_int, dist, blk_size, donor_state, &
191 xas_tdp_env, xas_tdp_control, qs_env)
199 CALL timestop(handle)
214 SUBROUTINE coulomb(coul_ker, contr1_int, dist, blk_size, xas_tdp_env, xas_tdp_control, qs_env)
219 INTEGER,
DIMENSION(:),
POINTER :: blk_size
224 LOGICAL :: quadrants(3)
225 REAL(
dp),
DIMENSION(:, :),
POINTER :: pq
226 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: lhs_int, rhs_int
229 NULLIFY (pq, rhs_int, lhs_int)
232 pq => xas_tdp_env%ri_inv_coul
235 CALL dbcsr_create(work_mat, name=
"WORK", matrix_type=dbcsr_type_no_symmetry, dist=dist, &
236 row_blk_size=blk_size, col_blk_size=blk_size)
239 rhs_int => contr1_int
240 ALLOCATE (lhs_int(
SIZE(contr1_int)))
241 CALL copy_ri_contr_int(lhs_int, rhs_int)
246 IF (xas_tdp_control%do_roks)
THEN
247 quadrants = [.true., .true., .true.]
249 quadrants = [.true., .false., .false.]
251 CALL ri_int_product(work_mat, lhs_int, rhs_int, quadrants, qs_env, &
252 eps_filter=xas_tdp_control%eps_filter)
256 CALL dbcsr_create(coul_ker, name=
"COULOMB KERNEL", matrix_type=dbcsr_type_symmetric, dist=dist, &
257 row_blk_size=blk_size, col_blk_size=blk_size)
264 END SUBROUTINE coulomb
279 SUBROUTINE sc_os_xc(xc_ker, contr1_int_PQ, dist, blk_size, donor_state, xas_tdp_env, &
280 xas_tdp_control, qs_env)
283 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: contr1_int_pq
285 INTEGER,
DIMENSION(:),
POINTER :: blk_size
291 INTEGER :: ndo_mo, ri_atom
292 LOGICAL :: quadrants(3)
293 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: lhs_int, rhs_int
296 NULLIFY (lhs_int, rhs_int)
299 ndo_mo = donor_state%ndo_mo
300 ri_atom = donor_state%at_index
302 CALL dbcsr_create(work_mat, name=
"WORK", matrix_type=dbcsr_type_no_symmetry, dist=dist, &
303 row_blk_size=blk_size, col_blk_size=blk_size)
305 rhs_int => contr1_int_pq
306 ALLOCATE (lhs_int(
SIZE(contr1_int_pq)))
309 IF (xas_tdp_control%do_uks)
THEN
316 quadrants = [.true., .false., .false.]
320 CALL copy_ri_contr_int(lhs_int(1:ndo_mo), rhs_int(1:ndo_mo))
321 CALL ri_all_blocks_mm(lhs_int(1:ndo_mo), xas_tdp_env%ri_fxc(ri_atom, 1)%array)
322 CALL ri_int_product(work_mat, lhs_int(1:ndo_mo), rhs_int(1:ndo_mo), quadrants, qs_env, &
323 eps_filter=xas_tdp_control%eps_filter)
326 quadrants = [.false., .true., .false.]
329 CALL copy_ri_contr_int(lhs_int(1:ndo_mo), rhs_int(1:ndo_mo))
330 CALL ri_all_blocks_mm(lhs_int(1:ndo_mo), xas_tdp_env%ri_fxc(ri_atom, 2)%array)
331 CALL ri_int_product(work_mat, lhs_int(1:ndo_mo), rhs_int(ndo_mo + 1:2*ndo_mo), &
332 quadrants, qs_env, eps_filter=xas_tdp_control%eps_filter)
335 quadrants = [.false., .false., .true.]
338 CALL copy_ri_contr_int(lhs_int(ndo_mo + 1:2*ndo_mo), rhs_int(ndo_mo + 1:2*ndo_mo))
339 CALL ri_all_blocks_mm(lhs_int(ndo_mo + 1:2*ndo_mo), xas_tdp_env%ri_fxc(ri_atom, 3)%array)
340 CALL ri_int_product(work_mat, lhs_int(ndo_mo + 1:2*ndo_mo), rhs_int(ndo_mo + 1:2*ndo_mo), &
341 quadrants, qs_env, eps_filter=xas_tdp_control%eps_filter)
343 ELSE IF (xas_tdp_control%do_roks)
THEN
349 quadrants = [.true., .false., .false.]
352 CALL copy_ri_contr_int(lhs_int, rhs_int)
354 CALL ri_int_product(work_mat, lhs_int, rhs_int, quadrants, qs_env, &
355 eps_filter=xas_tdp_control%eps_filter)
358 quadrants = [.false., .true., .false.]
361 CALL copy_ri_contr_int(lhs_int, rhs_int)
363 CALL ri_int_product(work_mat, lhs_int, rhs_int, quadrants, qs_env, &
364 eps_filter=xas_tdp_control%eps_filter)
367 quadrants = [.false., .false., .true.]
370 CALL copy_ri_contr_int(lhs_int, rhs_int)
372 CALL ri_int_product(work_mat, lhs_int, rhs_int, quadrants, qs_env, &
373 eps_filter=xas_tdp_control%eps_filter)
379 CALL dbcsr_create(xc_ker, name=
"SC OS XC KERNEL", matrix_type=dbcsr_type_symmetric, dist=dist, &
380 row_blk_size=blk_size, col_blk_size=blk_size)
387 END SUBROUTINE sc_os_xc
404 SUBROUTINE ondiag_sf_os_xc(xc_ker, contr1_int_PQ, dist, blk_size, donor_state, xas_tdp_env, &
405 xas_tdp_control, qs_env)
408 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: contr1_int_pq
410 INTEGER,
DIMENSION(:),
POINTER :: blk_size
416 INTEGER :: ndo_mo, ri_atom
417 LOGICAL :: quadrants(3)
418 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: lhs_int, rhs_int
421 NULLIFY (lhs_int, rhs_int)
424 ndo_mo = donor_state%ndo_mo
425 ri_atom = donor_state%at_index
427 CALL dbcsr_create(work_mat, name=
"WORK", matrix_type=dbcsr_type_no_symmetry, dist=dist, &
428 row_blk_size=blk_size, col_blk_size=blk_size)
432 rhs_int => contr1_int_pq
433 ALLOCATE (lhs_int(
SIZE(contr1_int_pq)))
434 CALL copy_ri_contr_int(lhs_int, rhs_int)
438 IF (xas_tdp_control%do_uks)
THEN
445 quadrants = [.true., .false., .false.]
446 CALL ri_int_product(work_mat, lhs_int(1:ndo_mo), rhs_int(1:ndo_mo), quadrants, qs_env, &
447 eps_filter=xas_tdp_control%eps_filter)
450 quadrants = [.false., .false., .true.]
451 CALL ri_int_product(work_mat, lhs_int(ndo_mo + 1:2*ndo_mo), rhs_int(ndo_mo + 1:2*ndo_mo), &
452 quadrants, qs_env, eps_filter=xas_tdp_control%eps_filter)
454 ELSE IF (xas_tdp_control%do_roks)
THEN
459 quadrants = [.true., .false., .true.]
460 CALL ri_int_product(work_mat, lhs_int, rhs_int, quadrants, qs_env, &
461 eps_filter=xas_tdp_control%eps_filter)
467 CALL dbcsr_create(xc_ker, name=
"ON-DIAG SF OS XC KERNEL", matrix_type=dbcsr_type_symmetric, &
468 dist=dist, row_blk_size=blk_size, col_blk_size=blk_size)
475 END SUBROUTINE ondiag_sf_os_xc
492 SUBROUTINE rcs_xc(sg_xc_ker, tp_xc_ker, contr1_int_PQ, dist, blk_size, donor_state, &
493 xas_tdp_env, xas_tdp_control, qs_env)
495 TYPE(
dbcsr_type),
INTENT(INOUT) :: sg_xc_ker, tp_xc_ker
496 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: contr1_int_pq
498 INTEGER,
DIMENSION(:),
POINTER :: blk_size
504 INTEGER :: nsgfp, ri_atom
505 LOGICAL :: quadrants(3)
506 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: fxc
507 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: lhs_int, rhs_int
510 NULLIFY (lhs_int, rhs_int)
513 ri_atom = donor_state%at_index
514 nsgfp =
SIZE(xas_tdp_env%ri_fxc(ri_atom, 1)%array, 1)
515 rhs_int => contr1_int_pq
516 ALLOCATE (lhs_int(
SIZE(contr1_int_pq)))
519 ALLOCATE (fxc(nsgfp, nsgfp))
520 CALL dbcsr_create(work_mat, name=
"WORK", matrix_type=dbcsr_type_no_symmetry, dist=dist, &
521 row_blk_size=blk_size, col_blk_size=blk_size)
524 IF (xas_tdp_control%do_singlet)
THEN
527 CALL dcopy(nsgfp*nsgfp, xas_tdp_env%ri_fxc(ri_atom, 1)%array, 1, fxc, 1)
528 CALL daxpy(nsgfp*nsgfp, 1.0_dp, xas_tdp_env%ri_fxc(ri_atom, 2)%array, 1, fxc, 1)
531 CALL copy_ri_contr_int(lhs_int, rhs_int)
535 quadrants = [.true., .false., .false.]
536 CALL ri_int_product(work_mat, lhs_int, rhs_int, quadrants, qs_env, &
537 eps_filter=xas_tdp_control%eps_filter)
541 CALL dbcsr_create(sg_xc_ker, name=
"XC SINGLET KERNEL", matrix_type=dbcsr_type_symmetric, &
542 dist=dist, row_blk_size=blk_size, col_blk_size=blk_size)
547 IF (xas_tdp_control%do_triplet)
THEN
550 CALL dcopy(nsgfp*nsgfp, xas_tdp_env%ri_fxc(ri_atom, 1)%array, 1, fxc, 1)
551 CALL daxpy(nsgfp*nsgfp, -1.0_dp, xas_tdp_env%ri_fxc(ri_atom, 2)%array, 1, fxc, 1)
554 CALL copy_ri_contr_int(lhs_int, rhs_int)
558 quadrants = [.true., .false., .false.]
559 CALL ri_int_product(work_mat, lhs_int, rhs_int, quadrants, qs_env, &
560 eps_filter=xas_tdp_control%eps_filter)
564 CALL dbcsr_create(tp_xc_ker, name=
"XC TRIPLET KERNEL", matrix_type=dbcsr_type_symmetric, &
565 dist=dist, row_blk_size=blk_size, col_blk_size=blk_size)
575 END SUBROUTINE rcs_xc
602 CHARACTER(len=*),
PARAMETER :: routinen =
'kernel_exchange'
605 INTEGER,
DIMENSION(:),
POINTER :: blk_size
610 NULLIFY (contr1_int, dist, blk_size)
613 IF (.NOT. xas_tdp_control%do_hfx)
RETURN
615 CALL timeset(routinen, handle)
617 dist => donor_state%dbcsr_dist
618 blk_size => donor_state%blk_size
621 do_off_sc = (.NOT. xas_tdp_control%tamm_dancoff) .AND. &
622 (xas_tdp_control%do_spin_cons .OR. xas_tdp_control%do_singlet .OR. xas_tdp_control%do_triplet)
625 CALL contract2_ao_to_domo(contr1_int,
"EXCHANGE", donor_state, xas_tdp_env, xas_tdp_control, qs_env)
628 CALL ondiag_ex(ex_ker(1)%matrix, contr1_int, dist, blk_size, donor_state, xas_tdp_env, &
629 xas_tdp_control, qs_env)
633 CALL offdiag_ex_sc(ex_ker(2)%matrix, contr1_int, dist, blk_size, donor_state, &
634 xas_tdp_env, xas_tdp_control, qs_env)
640 CALL timestop(handle)
659 SUBROUTINE ondiag_ex(ondiag_ex_ker, contr1_int, dist, blk_size, donor_state, xas_tdp_env, &
660 xas_tdp_control, qs_env)
662 TYPE(
dbcsr_type),
INTENT(INOUT) :: ondiag_ex_ker
665 INTEGER,
DIMENSION(:),
POINTER :: blk_size
671 INTEGER :: group, iblk, iso, jblk, jso, nblk, &
672 ndo_mo, ndo_so, nsgfa, nsgfp, ri_atom, &
674 INTEGER,
DIMENSION(:),
POINTER :: col_dist, col_dist_work, row_dist, &
676 INTEGER,
DIMENSION(:, :),
POINTER :: pgrid
677 LOGICAL :: do_roks, do_uks, found
678 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: coeffs, ri_coeffs
679 REAL(
dp),
DIMENSION(:, :),
POINTER :: aiq, pblock, pq
683 TYPE(
dbcsr_type) :: abij, mats_desymm, work_mat
686 NULLIFY (para_env, matrix_s, pblock, aiq, row_dist, col_dist, row_dist_work, col_dist_work, pgrid)
693 ndo_mo = donor_state%ndo_mo
694 ri_atom = donor_state%at_index
695 do_roks = xas_tdp_control%do_roks
696 do_uks = xas_tdp_control%do_uks
697 ndo_so = ndo_mo;
IF (do_uks) ndo_so = 2*ndo_mo
698 pq => xas_tdp_env%ri_inv_ex
700 CALL get_qs_env(qs_env, para_env=para_env, matrix_s=matrix_s, natom=nblk)
702 nsgfa =
SIZE(donor_state%contract_coeffs, 1)
703 ALLOCATE (coeffs(nsgfp, ndo_so), ri_coeffs(nsgfp, ndo_so))
711 CALL dbcsr_create(abij, template=mats_desymm, name=
"(ab|IJ)", dist=opt_dbcsr_dist)
720 ALLOCATE (row_dist_work(ndo_so*nblk))
721 ALLOCATE (col_dist_work(ndo_so*nblk))
723 row_dist_work((iso - 1)*nblk + 1:iso*nblk) = row_dist(:)
724 col_dist_work((iso - 1)*nblk + 1:iso*nblk) = col_dist(:)
728 col_dist=col_dist_work)
730 CALL dbcsr_create(work_mat, name=
"WORK", matrix_type=dbcsr_type_no_symmetry, dist=work_dbcsr_dist, &
731 row_blk_size=blk_size, col_blk_size=blk_size)
738 IF (para_env%mepos == source)
THEN
741 ALLOCATE (aiq(nsgfa, nsgfp))
743 CALL para_env%bcast(aiq, source)
746 CALL dgemm(
'T',
'N', nsgfp, ndo_so, nsgfa, 1.0_dp, aiq, nsgfa, donor_state%contract_coeffs, &
747 nsgfa, 0.0_dp, coeffs, nsgfp)
750 CALL dgemm(
'N',
'N', nsgfp, ndo_so, nsgfp, 1.0_dp, pq, nsgfp, coeffs, nsgfp, 0.0_dp, &
753 IF (.NOT. para_env%mepos == source)
DEALLOCATE (aiq)
759 IF (do_uks .AND. (iso <= ndo_mo .AND. jso > ndo_mo)) cycle
763 CALL contract3_ri_to_domos(xas_tdp_env%ri_3c_ex, ri_coeffs(:, jso), abij, ri_atom)
770 IF (iso == jso .AND. jblk < iblk) cycle
775 CALL dbcsr_put_block(work_mat, (iso - 1)*nblk + iblk, (jso - 1)*nblk + jblk, pblock)
782 (ndo_so + jso - 1)*nblk + jblk, pblock)
793 CALL dbcsr_create(ondiag_ex_ker, name=
"ONDIAG EX KERNEL", matrix_type=dbcsr_type_symmetric, &
794 dist=dist, row_blk_size=blk_size, col_blk_size=blk_size)
802 DEALLOCATE (col_dist_work, row_dist_work)
804 END SUBROUTINE ondiag_ex
820 SUBROUTINE offdiag_ex_sc(offdiag_ex_ker, contr1_int, dist, blk_size, donor_state, xas_tdp_env, &
821 xas_tdp_control, qs_env)
823 TYPE(
dbcsr_type),
INTENT(INOUT) :: offdiag_ex_ker
826 INTEGER,
DIMENSION(:),
POINTER :: blk_size
833 LOGICAL :: do_roks, do_uks, quadrants(3)
834 REAL(
dp),
DIMENSION(:, :),
POINTER :: pq
835 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: lhs_int, rhs_int
838 NULLIFY (pq, lhs_int, rhs_int)
841 ndo_mo = donor_state%ndo_mo
842 do_roks = xas_tdp_control%do_roks
843 do_uks = xas_tdp_control%do_uks
844 pq => xas_tdp_env%ri_inv_ex
846 rhs_int => contr1_int
847 ALLOCATE (lhs_int(
SIZE(contr1_int)))
848 CALL copy_ri_contr_int(lhs_int, rhs_int)
855 CALL dbcsr_create(work_mat, name=
"WORK", matrix_type=dbcsr_type_no_symmetry, dist=dist, &
856 row_blk_size=blk_size, col_blk_size=blk_size)
862 quadrants = [.true., .false., .true.]
863 CALL ri_int_product(work_mat, lhs_int, rhs_int, quadrants, qs_env, &
864 eps_filter=xas_tdp_control%eps_filter, mo_transpose=.true.)
866 ELSE IF (do_uks)
THEN
869 quadrants = [.true., .false., .false.]
870 CALL ri_int_product(work_mat, lhs_int(1:ndo_mo), rhs_int(1:ndo_mo), quadrants, &
871 qs_env, eps_filter=xas_tdp_control%eps_filter, mo_transpose=.true.)
873 quadrants = [.false., .false., .true.]
874 CALL ri_int_product(work_mat, lhs_int(ndo_mo + 1:2*ndo_mo), rhs_int(ndo_mo + 1:2*ndo_mo), &
875 quadrants, qs_env, eps_filter=xas_tdp_control%eps_filter, mo_transpose=.true.)
878 quadrants = [.true., .false., .false.]
879 CALL ri_int_product(work_mat, lhs_int, rhs_int, quadrants, qs_env, &
880 eps_filter=xas_tdp_control%eps_filter, mo_transpose=.true.)
885 CALL dbcsr_create(offdiag_ex_ker, name=
"OFFDIAG EX KERNEL", matrix_type=dbcsr_type_symmetric, &
886 dist=dist, row_blk_size=blk_size, col_blk_size=blk_size)
893 END SUBROUTINE offdiag_ex_sc
905 INTEGER,
INTENT(IN) :: ri_atom
908 INTEGER :: i, iblk, jblk, max_nblks, nblks
909 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: reserve_cols, reserve_rows
922 CALL dbcsr_create(work, template=matrix_s(1)%matrix, dist=dist)
930 ALLOCATE (reserve_rows(max_nblks), reserve_cols(max_nblks))
938 IF (iblk == ri_atom .OR. jblk == ri_atom)
THEN
940 reserve_rows(nblks) = iblk
941 reserve_cols(nblks) = jblk
946 DO i = 1,
SIZE(matrices)
947 CALL dbcsr_reserve_blocks(matrices(i)%matrix, rows=reserve_rows(1:nblks), cols=reserve_cols(1:nblks))
974 CHARACTER(len=*),
INTENT(IN) :: op_type
980 CHARACTER(len=*),
PARAMETER :: routinen =
'contract2_AO_to_doMO'
982 INTEGER :: handle, i, imo, ispin, katom, kkind, &
983 natom, ndo_mo, ndo_so, nkind, nspins
984 INTEGER,
DIMENSION(:),
POINTER :: ri_blk_size, std_blk_size
986 REAL(
dp),
DIMENSION(:, :),
POINTER :: coeffs
988 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrices, matrix_s
990 TYPE(dbt_type),
POINTER :: pq_x
995 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
997 NULLIFY (matrix_s, std_blk_size, ri_blk_size, qs_kind_set, ri_basis, pq_x)
998 NULLIFY (ai_p, p_ib, work, matrices, coeffs, opt_dist2d, particle_set)
1000 CALL timeset(routinen, handle)
1003 CALL get_qs_env(qs_env, natom=natom, matrix_s=matrix_s, qs_kind_set=qs_kind_set, para_env=para_env)
1004 ndo_mo = donor_state%ndo_mo
1005 kkind = donor_state%kind_index
1006 katom = donor_state%at_index
1008 pq_x => xas_tdp_env%ri_3c_coul
1009 opt_dist2d => xas_tdp_env%opt_dist2d_coul
1010 IF (op_type ==
"EXCHANGE")
THEN
1011 cpassert(
ASSOCIATED(xas_tdp_env%ri_3c_ex))
1012 pq_x => xas_tdp_env%ri_3c_ex
1013 opt_dist2d => xas_tdp_env%opt_dist2d_ex
1015 do_uks = xas_tdp_control%do_uks
1016 nspins = 1;
IF (do_uks) nspins = 2
1017 ndo_so = nspins*ndo_mo
1020 CALL dbcsr_get_info(matrix_s(1)%matrix, col_blk_size=std_blk_size)
1022 CALL get_qs_env(qs_env, particle_set=particle_set, nkind=nkind)
1023 ALLOCATE (ri_basis(nkind), ri_blk_size(natom))
1025 CALL get_particle_set(particle_set, qs_kind_set, nsgf=ri_blk_size, basis=ri_basis)
1030 ALLOCATE (ai_p, p_ib, work, matrices(2))
1031 CALL dbcsr_create(ai_p, dist=opt_dbcsr_dist, matrix_type=dbcsr_type_no_symmetry, name=
"(aI|P)", &
1032 row_blk_size=std_blk_size, col_blk_size=ri_blk_size)
1034 CALL dbcsr_create(p_ib, dist=opt_dbcsr_dist, matrix_type=dbcsr_type_no_symmetry, name=
"(P|Ib)", &
1035 row_blk_size=ri_blk_size, col_blk_size=std_blk_size)
1038 matrices(1)%matrix => ai_p; matrices(2)%matrix => p_ib
1040 DEALLOCATE (matrices)
1043 ALLOCATE (contr_int(ndo_so))
1045 ALLOCATE (contr_int(i)%matrix)
1046 CALL dbcsr_create(matrix=contr_int(i)%matrix, template=matrix_s(1)%matrix, &
1047 matrix_type=dbcsr_type_no_symmetry, row_blk_size=std_blk_size, &
1048 col_blk_size=ri_blk_size)
1052 coeffs => donor_state%contract_coeffs
1054 DO ispin = 1, nspins
1061 CALL contract2_ao_to_domo_low(pq_x, coeffs(:, (ispin - 1)*ndo_mo + imo), ai_p, p_ib, katom)
1065 CALL dbcsr_add(work, ai_p, 1.0_dp, 1.0_dp)
1067 CALL dbcsr_filter(contr_int((ispin - 1)*ndo_mo + imo)%matrix, 1.0e-16_dp)
1077 DEALLOCATE (ri_blk_size, ai_p, p_ib, work, ri_basis)
1079 CALL timestop(handle)
1092 SUBROUTINE contract3_ri_to_domos(ab_Q, vec, mat_abIJ, atom_k)
1094 TYPE(dbt_type) :: ab_q
1095 REAL(
dp),
DIMENSION(:),
INTENT(IN) :: vec
1097 INTEGER,
INTENT(IN) :: atom_k
1099 CHARACTER(len=*),
PARAMETER :: routinen =
'contract3_RI_to_doMOs'
1101 INTEGER :: handle, i, iatom, ind(3), j, jatom, katom
1102 LOGICAL :: found, t_found
1104 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: iabc
1105 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: pblock
1107 TYPE(dbt_iterator_type) :: iter
1111 CALL timeset(routinen, handle)
1116 CALL dbt_iterator_start(iter, ab_q)
1117 DO WHILE (dbt_iterator_blocks_left(iter))
1118 CALL dbt_iterator_next_block(iter, ind)
1124 IF (.NOT. atom_k == katom) cycle
1127 IF (iatom == jatom) prefac = 0.5_dp
1129 CALL dbt_get_block(ab_q, ind, iabc, t_found)
1132 IF ((.NOT. found) .OR. (.NOT. t_found)) cycle
1134 DO i = 1,
SIZE(pblock, 1)
1135 DO j = 1,
SIZE(pblock, 2)
1137 pblock(i, j) = pblock(i, j) + prefac*dot_product(vec(:), iabc(i, j, :))
1143 CALL dbt_iterator_stop(iter)
1149 CALL dbcsr_add(mat_abij, work, 1.0_dp, 1.0_dp)
1152 CALL timestop(handle)
1154 END SUBROUTINE contract3_ri_to_domos
1172 SUBROUTINE contract2_ao_to_domo_low(ab_Q, vec, mat_aIb, mat_bIa, atom_k)
1174 TYPE(dbt_type) :: ab_q
1175 REAL(
dp),
DIMENSION(:),
INTENT(IN) :: vec
1176 TYPE(
dbcsr_type),
INTENT(INOUT) :: mat_aib, mat_bia
1177 INTEGER,
INTENT(IN) :: atom_k
1179 CHARACTER(LEN=*),
PARAMETER :: routinen =
'contract2_AO_to_doMO_low'
1181 INTEGER :: handle, i, iatom, ind(3), j, jatom, &
1183 INTEGER,
DIMENSION(:),
POINTER :: atom_blk_size
1184 LOGICAL :: found, t_found
1185 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: iabc
1186 REAL(
dp),
DIMENSION(:, :),
POINTER :: pblock
1187 TYPE(dbt_iterator_type) :: iter
1189 NULLIFY (atom_blk_size, pblock)
1191 CALL timeset(routinen, handle)
1198 CALL dbt_iterator_start(iter, ab_q)
1199 DO WHILE (dbt_iterator_blocks_left(iter))
1200 CALL dbt_iterator_next_block(iter, ind)
1206 IF (atom_k .NE. katom) cycle
1208 CALL dbt_get_block(ab_q, ind, iabc, t_found)
1209 IF (.NOT. t_found) cycle
1212 IF (jatom == atom_k)
THEN
1213 s1 = atom_blk_size(iatom)
1216 CALL dbcsr_get_block_p(matrix=mat_aib, row=iatom, col=jatom, block=pblock, found=found)
1222 pblock(i, j) = pblock(i, j) + dot_product(vec, iabc(i, :, j))
1229 IF (iatom == jatom) cycle
1230 IF (iatom == atom_k)
THEN
1232 s2 = atom_blk_size(jatom)
1234 CALL dbcsr_get_block_p(matrix=mat_bia, row=iatom, col=jatom, block=pblock, found=found)
1240 pblock(i, j) = pblock(i, j) + dot_product(vec, iabc(:, j, i))
1248 CALL dbt_iterator_stop(iter)
1251 CALL timestop(handle)
1253 END SUBROUTINE contract2_ao_to_domo_low
1265 REAL(
dp),
DIMENSION(:, :),
INTENT(IN) :: pq
1267 INTEGER :: iblk, imo, jblk, ndo_mo, s1, s2
1269 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: work
1270 REAL(
dp),
DIMENSION(:, :),
POINTER :: pblock
1275 ndo_mo =
SIZE(contr_int)
1285 s1 =
SIZE(pblock, 1)
1286 s2 =
SIZE(pblock, 2)
1287 ALLOCATE (work(s1, s2))
1288 CALL dgemm(
'N',
'N', s1, s2, s2, 1.0_dp, pblock, s1, pq, s2, 0.0_dp, work, s1)
1289 CALL dcopy(s1*s2, work, 1, pblock, 1)
1305 SUBROUTINE copy_ri_contr_int(new_int, ref_int)
1307 TYPE(
dbcsr_p_type),
DIMENSION(:),
INTENT(INOUT) :: new_int
1308 TYPE(
dbcsr_p_type),
DIMENSION(:),
INTENT(IN) :: ref_int
1310 INTEGER :: iso, ndo_so
1312 cpassert(
SIZE(new_int) ==
SIZE(ref_int))
1313 ndo_so =
SIZE(ref_int)
1316 IF (.NOT.
ASSOCIATED(new_int(iso)%matrix))
ALLOCATE (new_int(iso)%matrix)
1317 CALL dbcsr_copy(new_int(iso)%matrix, ref_int(iso)%matrix)
1320 END SUBROUTINE copy_ri_contr_int
1336 SUBROUTINE ri_int_product(kernel, lhs_int, rhs_int, quadrants, qs_env, eps_filter, mo_transpose)
1339 TYPE(
dbcsr_p_type),
DIMENSION(:),
INTENT(IN) :: lhs_int, rhs_int
1340 LOGICAL,
DIMENSION(3),
INTENT(IN) :: quadrants
1342 REAL(
dp),
INTENT(IN),
OPTIONAL :: eps_filter
1343 LOGICAL,
INTENT(IN),
OPTIONAL :: mo_transpose
1345 INTEGER :: i, iblk, iso, j, jblk, jso, nblk, ndo_so
1346 LOGICAL :: found, my_mt
1347 REAL(
dp),
DIMENSION(:, :),
POINTER :: pblock
1352 NULLIFY (matrix_s, pblock)
1355 cpassert(
SIZE(lhs_int) ==
SIZE(rhs_int))
1356 cpassert(any(quadrants))
1357 ndo_so =
SIZE(lhs_int)
1358 CALL get_qs_env(qs_env, matrix_s=matrix_s, natom=nblk)
1359 CALL dbcsr_create(prod, template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
1361 IF (
PRESENT(mo_transpose)) my_mt = mo_transpose
1369 IF (.NOT. quadrants(2) .AND. jso < iso) cycle
1377 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, lhs_int(i)%matrix, rhs_int(j)%matrix, &
1378 0.0_dp, prod, filter_eps=eps_filter)
1385 IF ((iso == jso .AND. jblk < iblk) .AND. .NOT. quadrants(2)) cycle
1393 IF (quadrants(1))
THEN
1394 CALL dbcsr_put_block(kernel, (iso - 1)*nblk + iblk, (jso - 1)*nblk + jblk, pblock)
1398 IF (quadrants(2))
THEN
1399 CALL dbcsr_put_block(kernel, (iso - 1)*nblk + iblk, (ndo_so + jso - 1)*nblk + jblk, pblock)
1403 IF (quadrants(3))
THEN
1404 CALL dbcsr_put_block(kernel, (ndo_so + iso - 1)*nblk + iblk, (ndo_so + jso - 1)*nblk + jblk, pblock)
1418 END SUBROUTINE ri_int_product
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.
subroutine, public dbcsr_transposed(transposed, normal, shallow_data_copy, transpose_distribution, use_distribution)
...
subroutine, public dbcsr_distribution_release(dist)
...
subroutine, public dbcsr_distribution_new(dist, template, group, pgrid, row_dist, col_dist, reuse_arrays)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_desymmetrize(matrix_a, matrix_b)
...
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_reserve_blocks(matrix, rows, cols)
...
subroutine, public dbcsr_get_stored_coordinates(matrix, row, column, processor)
...
subroutine, public dbcsr_filter(matrix, eps)
...
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_complete_redistribute(matrix, redist)
...
integer function, public dbcsr_get_num_blocks(matrix)
...
subroutine, public dbcsr_put_block(matrix, row, col, block, summation)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
subroutine, public dbcsr_distribution_get(dist, row_dist, col_dist, nrows, ncols, has_threads, group, mynode, numnodes, nprows, npcols, myprow, mypcol, pgrid, subgroups_defined, prow_group, pcol_group)
...
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_dist2d_to_dist(dist2d, dist)
Creates a DBCSR distribution from a distribution_2d.
This is the start of a dbt_api, all publically needed functions are exported here....
stores a mapping of 2D info (e.g. matrix) on a 2D processor distribution (i.e. blacs grid) where cpus...
Defines the basic variable types.
integer, parameter, public dp
Interface to the message passing library MPI.
Define methods related to particle_type.
subroutine, public get_particle_set(particle_set, qs_kind_set, first_sgf, last_sgf, nsgf, nmao, basis)
Get the components of a particle set.
Define the data structure for the particle information.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, 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)
Get the QUICKSTEP environment.
Some utility functions for the calculation of integrals.
subroutine, public basis_set_list_setup(basis_set_list, basis_type, qs_kind_set)
Set up an easy accessible list of the basis sets for all kinds.
Define the quickstep kind type and their sub types.
All kind of helpful little routines.
pure integer function, dimension(2), public get_limit(m, n, me)
divide m entries into n parts, return size of part me
All the kernel specific subroutines for XAS TDP calculations.
subroutine, public kernel_coulomb_xc(coul_ker, xc_ker, donor_state, xas_tdp_env, xas_tdp_control, qs_env)
Computes, if asked for it, the Coulomb and XC kernel matrices, in the usuall matrix format.
subroutine, public contract2_ao_to_domo(contr_int, op_type, donor_state, xas_tdp_env, xas_tdp_control, qs_env)
Contract the ri 3-center integrals stored in a tensor with repect to the donor MOs coeffs,...
subroutine, public kernel_exchange(ex_ker, donor_state, xas_tdp_env, xas_tdp_control, qs_env)
Computes the exact exchange kernel matrix using RI. Returns an array of 2 matrices,...
subroutine, public reserve_contraction_blocks(matrices, ri_atom, qs_env)
Reserves the blocks in of a dbcsr matrix as needed for RI 3-center contraction (aI|P)
subroutine, public ri_all_blocks_mm(contr_int, pq)
Multiply all the blocks of a contracted RI integral (aI|P) by a matrix of type (P|....
Define XAS TDP control type and associated create, release, etc subroutines, as well as XAS TDP envir...
subroutine, public get_proc_batch_sizes(batch_size, nbatch, nex_atom, nprocs)
Uses heuristics to determine a good batching of the processros for fxc integration.
distributes pairs on a 2d grid of processors
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.
Type containing informations about a single donor state.
Type containing control information for TDP XAS calculations.
Type containing informations such as inputs and results for TDP XAS calculations.