14 USE omp_lib,
ONLY: omp_get_num_threads,&
57 dbt_batched_contract_finalize, dbt_batched_contract_init, dbt_clear, dbt_contract, &
58 dbt_copy, dbt_copy_matrix_to_tensor, dbt_copy_tensor_to_matrix, dbt_create, &
59 dbt_default_distvec, dbt_destroy, dbt_distribution_destroy, dbt_distribution_new, &
60 dbt_distribution_type, dbt_filter, dbt_get_block, dbt_get_info, dbt_get_num_blocks_total, &
61 dbt_iterator_blocks_left, dbt_iterator_next_block, dbt_iterator_start, dbt_iterator_stop, &
62 dbt_iterator_type, dbt_mp_environ_pgrid, dbt_nd_mp_comm, dbt_pgrid_create, &
63 dbt_pgrid_destroy, dbt_pgrid_type, dbt_put_block, dbt_reserve_blocks, dbt_scale, dbt_type
119#include "./base/base_uses.f90"
129 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'hfx_ri'
138 SUBROUTINE switch_ri_flavor(ri_data, qs_env)
139 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
140 TYPE(qs_environment_type),
POINTER :: qs_env
142 CHARACTER(LEN=*),
PARAMETER :: routineN =
'switch_ri_flavor'
144 INTEGER :: handle, n_mem, new_flavor
145 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
146 TYPE(dft_control_type),
POINTER :: dft_control
147 TYPE(mp_para_env_type),
POINTER :: para_env
148 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
149 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
151 NULLIFY (qs_kind_set, particle_set, atomic_kind_set, para_env, dft_control)
153 CALL timeset(routinen, handle)
155 CALL get_qs_env(qs_env, para_env=para_env, dft_control=dft_control, atomic_kind_set=atomic_kind_set, &
156 particle_set=particle_set, qs_kind_set=qs_kind_set)
160 IF (ri_data%flavor ==
ri_pmat)
THEN
165 ri_data%flavor = new_flavor
167 n_mem = ri_data%n_mem_input
168 ri_data%n_mem_input = ri_data%n_mem_flavor_switch
169 ri_data%n_mem_flavor_switch = n_mem
171 CALL hfx_ri_init(ri_data, qs_kind_set, particle_set, atomic_kind_set, para_env)
176 IF (ri_data%flavor ==
ri_pmat)
THEN
177 CALL hfx_ri_pre_scf_pmat(qs_env, ri_data)
179 CALL hfx_ri_pre_scf_mo(qs_env, ri_data, dft_control%nspins)
182 IF (ri_data%unit_nr > 0)
THEN
183 IF (ri_data%flavor ==
ri_pmat)
THEN
184 WRITE (ri_data%unit_nr,
'(T2,A)')
"HFX_RI_INFO| temporarily switched to RI_FLAVOR RHO"
186 WRITE (ri_data%unit_nr,
'(T2,A)')
"HFX_RI_INFO| temporarily switched to RI_FLAVOR MO"
190 CALL timestop(handle)
192 END SUBROUTINE switch_ri_flavor
204 SUBROUTINE hfx_ri_pre_scf_mo(qs_env, ri_data, nspins)
205 TYPE(qs_environment_type),
POINTER :: qs_env
206 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
207 INTEGER,
INTENT(IN) :: nspins
209 CHARACTER(LEN=*),
PARAMETER :: routineN =
'hfx_ri_pre_scf_mo'
211 INTEGER :: handle, handle2, ispin, n_dependent, &
212 unit_nr, unit_nr_dbcsr
213 REAL(KIND=
dp) :: threshold
214 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
215 TYPE(dbcsr_type),
DIMENSION(1) :: dbcsr_work_1, dbcsr_work_2, t_2c_int_mat, t_2c_op_pot, &
216 t_2c_op_pot_sqrt, t_2c_op_pot_sqrt_inv, t_2c_op_RI, t_2c_op_RI_inv
217 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:) :: t_2c_int, t_2c_work
218 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_int
219 TYPE(mp_para_env_type),
POINTER :: para_env
221 CALL timeset(routinen, handle)
223 unit_nr_dbcsr = ri_data%unit_nr_dbcsr
224 unit_nr = ri_data%unit_nr
226 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
228 CALL timeset(routinen//
"_int", handle2)
230 ALLOCATE (t_2c_int(1), t_2c_work(1), t_3c_int(1, 1))
233 CALL timestop(handle2)
235 CALL timeset(routinen//
"_2c", handle2)
236 IF (.NOT. ri_data%same_op)
THEN
237 SELECT CASE (ri_data%t2c_method)
239 CALL dbcsr_create(t_2c_op_ri_inv(1), template=t_2c_op_ri(1), matrix_type=dbcsr_type_no_symmetry)
240 threshold = max(ri_data%filter_eps, 1.0e-12_dp)
241 CALL invert_hotelling(t_2c_op_ri_inv(1), t_2c_op_ri(1), threshold=threshold, silent=.false.)
243 CALL dbcsr_copy(t_2c_op_ri_inv(1), t_2c_op_ri(1))
247 CALL dbcsr_copy(t_2c_op_ri_inv(1), t_2c_op_ri(1))
248 CALL cp_dbcsr_power(t_2c_op_ri_inv(1), -1.0_dp, ri_data%eps_eigval, n_dependent, &
249 para_env, blacs_env, verbose=ri_data%unit_nr_dbcsr > 0)
252 IF (ri_data%check_2c_inv)
THEN
253 CALL check_inverse(t_2c_op_ri_inv(1), t_2c_op_ri(1), unit_nr=unit_nr)
258 SELECT CASE (ri_data%t2c_method)
260 CALL dbcsr_create(t_2c_op_pot_sqrt(1), template=t_2c_op_pot(1), matrix_type=dbcsr_type_symmetric)
261 CALL dbcsr_create(t_2c_op_pot_sqrt_inv(1), template=t_2c_op_pot(1), matrix_type=dbcsr_type_symmetric)
263 ri_data%filter_eps, ri_data%t2c_sqrt_order, ri_data%eps_lanczos, &
264 ri_data%max_iter_lanczos)
268 CALL dbcsr_copy(t_2c_op_pot_sqrt(1), t_2c_op_pot(1))
269 CALL cp_dbcsr_power(t_2c_op_pot_sqrt(1), 0.5_dp, ri_data%eps_eigval, n_dependent, &
270 para_env, blacs_env, verbose=ri_data%unit_nr_dbcsr > 0)
274 CALL dbt_create(t_2c_op_ri_inv(1), t_2c_work(1))
275 CALL dbt_copy_matrix_to_tensor(t_2c_op_ri_inv(1), t_2c_work(1))
276 CALL dbt_copy(t_2c_work(1), ri_data%t_2c_inv(1, 1), move_data=.true.)
277 CALL dbt_destroy(t_2c_work(1))
278 CALL dbt_filter(ri_data%t_2c_inv(1, 1), ri_data%filter_eps)
280 CALL dbt_create(t_2c_op_pot(1), t_2c_work(1))
281 CALL dbt_copy_matrix_to_tensor(t_2c_op_pot(1), t_2c_work(1))
282 CALL dbt_copy(t_2c_work(1), ri_data%t_2c_pot(1, 1), move_data=.true.)
283 CALL dbt_destroy(t_2c_work(1))
284 CALL dbt_filter(ri_data%t_2c_pot(1, 1), ri_data%filter_eps)
286 IF (ri_data%check_2c_inv)
THEN
287 CALL check_sqrt(t_2c_op_pot(1), matrix_sqrt=t_2c_op_pot_sqrt(1), unit_nr=unit_nr)
289 CALL dbcsr_create(t_2c_int_mat(1), template=t_2c_op_pot(1), matrix_type=dbcsr_type_no_symmetry)
290 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, t_2c_op_ri_inv(1), t_2c_op_pot_sqrt(1), &
291 0.0_dp, t_2c_int_mat(1), filter_eps=ri_data%filter_eps)
295 SELECT CASE (ri_data%t2c_method)
297 CALL dbcsr_create(t_2c_int_mat(1), template=t_2c_op_pot(1), matrix_type=dbcsr_type_symmetric)
298 CALL dbcsr_create(t_2c_op_pot_sqrt(1), template=t_2c_op_pot(1), matrix_type=dbcsr_type_symmetric)
300 ri_data%filter_eps, ri_data%t2c_sqrt_order, ri_data%eps_lanczos, &
301 ri_data%max_iter_lanczos)
304 CALL dbcsr_copy(t_2c_int_mat(1), t_2c_op_pot(1))
305 CALL cp_dbcsr_power(t_2c_int_mat(1), -0.5_dp, ri_data%eps_eigval, n_dependent, &
306 para_env, blacs_env, verbose=ri_data%unit_nr_dbcsr > 0)
308 IF (ri_data%check_2c_inv)
THEN
309 CALL check_sqrt(t_2c_op_pot(1), matrix_sqrt_inv=t_2c_int_mat(1), unit_nr=unit_nr)
313 CALL dbcsr_copy(dbcsr_work_1(1), t_2c_int_mat(1))
314 CALL dbcsr_create(dbcsr_work_2(1), template=t_2c_int_mat(1))
315 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, dbcsr_work_1(1), t_2c_int_mat(1), 0.0_dp, dbcsr_work_2(1))
317 CALL dbt_create(dbcsr_work_2(1), t_2c_work(1))
318 CALL dbt_copy_matrix_to_tensor(dbcsr_work_2(1), t_2c_work(1))
320 CALL dbt_copy(t_2c_work(1), ri_data%t_2c_inv(1, 1), move_data=.true.)
321 CALL dbt_destroy(t_2c_work(1))
322 CALL dbt_filter(ri_data%t_2c_inv(1, 1), ri_data%filter_eps)
327 CALL dbt_create(t_2c_int_mat(1), t_2c_int(1), name=
"(RI|RI)")
328 CALL dbt_copy_matrix_to_tensor(t_2c_int_mat(1), t_2c_int(1))
331 CALL dbt_copy(t_2c_int(1), ri_data%t_2c_int(ispin, 1))
333 CALL dbt_destroy(t_2c_int(1))
334 CALL timestop(handle2)
336 CALL timeset(routinen//
"_3c", handle2)
337 CALL dbt_copy(t_3c_int(1, 1), ri_data%t_3c_int_ctr_1(1, 1), order=[2, 1, 3], move_data=.true.)
338 CALL dbt_filter(ri_data%t_3c_int_ctr_1(1, 1), ri_data%filter_eps)
339 CALL dbt_copy(ri_data%t_3c_int_ctr_1(1, 1), ri_data%t_3c_int_ctr_2(1, 1))
340 CALL dbt_destroy(t_3c_int(1, 1))
341 CALL timestop(handle2)
343 CALL timestop(handle)
355 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix_1, matrix_2
356 CHARACTER(len=*),
INTENT(IN),
OPTIONAL :: name
357 INTEGER,
INTENT(IN) :: unit_nr
359 CHARACTER(len=default_string_length) :: name_prv
360 REAL(kind=
dp) :: error, frob_matrix, frob_matrix_base
363 IF (
PRESENT(name))
THEN
375 error = frob_matrix/frob_matrix_base
376 IF (unit_nr > 0)
THEN
377 WRITE (unit=unit_nr, fmt=
"(T3,A,A,A,T73,ES8.1)") &
378 "HFX_RI_INFO| Error for INV(", trim(name_prv),
"):", error
392 SUBROUTINE check_sqrt(matrix, matrix_sqrt, matrix_sqrt_inv, name, unit_nr)
394 TYPE(
dbcsr_type),
INTENT(IN),
OPTIONAL :: matrix_sqrt, matrix_sqrt_inv
395 CHARACTER(len=*),
INTENT(IN),
OPTIONAL :: name
396 INTEGER,
INTENT(IN) :: unit_nr
398 CHARACTER(len=default_string_length) :: name_prv
399 REAL(kind=
dp) :: frob_matrix
402 IF (
PRESENT(name))
THEN
407 IF (
PRESENT(matrix_sqrt))
THEN
412 CALL dbcsr_add(matrix_tmp, matrix, 1.0_dp, -1.0_dp)
414 IF (unit_nr > 0)
THEN
415 WRITE (unit=unit_nr, fmt=
"(T3,A,A,A,T73,ES8.1)") &
416 "HFX_RI_INFO| Error for SQRT(", trim(name_prv),
"):", frob_matrix
422 IF (
PRESENT(matrix_sqrt_inv))
THEN
425 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_sqrt_inv, matrix_copy, &
427 CALL check_inverse(matrix_tmp, matrix, name=
"SQRT("//trim(name_prv)//
")", unit_nr=unit_nr)
451 TYPE(
dbcsr_type),
DIMENSION(:),
INTENT(OUT) :: t_2c_int_ri, t_2c_int_pot
452 TYPE(dbt_type),
DIMENSION(:, :) :: t_3c_int
453 LOGICAL,
INTENT(IN),
OPTIONAL :: do_kpoints
455 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_pre_scf_calc_tensors'
458 INTEGER :: handle, i_img, i_mem, ibasis, j_img, &
459 n_mem, natom, nblks, nimg, nkind, &
461 INTEGER(int_8) :: nze
462 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: dist_ao_1, dist_ao_2, dist_ri, dist_ri_ext, &
463 ends_array_mc_block_int, ends_array_mc_int, sizes_ao, sizes_ri, sizes_ri_ext, &
464 sizes_ri_ext_split, starts_array_mc_block_int, starts_array_mc_int
465 INTEGER,
DIMENSION(3) :: pcoord, pdims
466 INTEGER,
DIMENSION(:),
POINTER :: col_bsize, row_bsize
467 LOGICAL :: converged, do_kpoints_prv
468 REAL(
dp) :: max_ev, min_ev, occ, ri_range
471 TYPE(dbt_distribution_type) :: t_dist
472 TYPE(dbt_pgrid_type) :: pgrid
473 TYPE(dbt_type) :: t_3c_tmp
474 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_int_batched
479 DIMENSION(:),
TARGET :: basis_set_ao, basis_set_ri
485 POINTER :: nl_2c_pot, nl_2c_ri
487 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
490 CALL timeset(routinen, handle)
491 NULLIFY (col_bsize, row_bsize, dist_2d, nl_2c_pot, nl_2c_ri, &
492 particle_set, qs_kind_set, ks_env, para_env)
494 CALL get_qs_env(qs_env, natom=natom, nkind=nkind, qs_kind_set=qs_kind_set, particle_set=particle_set, &
495 distribution_2d=dist_2d, ks_env=ks_env, dft_control=dft_control, para_env=para_env)
498 do_kpoints_prv = .false.
499 IF (
PRESENT(do_kpoints)) do_kpoints_prv = do_kpoints
501 IF (do_kpoints_prv)
THEN
503 ri_range = ri_data%kp_RI_range
506 ALLOCATE (sizes_ri(natom), sizes_ao(natom))
507 ALLOCATE (basis_set_ri(nkind), basis_set_ao(nkind))
509 CALL get_particle_set(particle_set, qs_kind_set, nsgf=sizes_ri, basis=basis_set_ri)
511 CALL get_particle_set(particle_set, qs_kind_set, nsgf=sizes_ao, basis=basis_set_ao)
513 DO ibasis = 1,
SIZE(basis_set_ao)
514 orb_basis => basis_set_ao(ibasis)%gto_basis_set
515 ri_basis => basis_set_ri(ibasis)%gto_basis_set
523 n_mem = ri_data%n_mem
525 starts_array_mc_block_int, ends_array_mc_block_int)
527 DEALLOCATE (starts_array_mc_int, ends_array_mc_int)
530 IF (.NOT. do_kpoints_prv)
THEN
535 CALL dbt_pgrid_create(para_env, pdims, pgrid, tensor_dims=[max(1, natom/(n_mem*nthreads)), natom, natom])
537 ALLOCATE (t_3c_int_batched(1, 1))
538 CALL create_3c_tensor(t_3c_int_batched(1, 1), dist_ri, dist_ao_1, dist_ao_2, pgrid, &
539 sizes_ri, sizes_ao, sizes_ao, map1=[1], map2=[2, 3], &
542 CALL get_qs_env(qs_env, nkind=nkind, particle_set=particle_set, atomic_kind_set=atomic_kind_set)
543 CALL dbt_mp_environ_pgrid(pgrid, pdims, pcoord)
544 CALL mp_comm_t3c%create(pgrid%mp_comm_2d, 3, pdims)
546 nkind, particle_set, mp_comm_t3c, own_comm=.true.)
547 DEALLOCATE (dist_ri, dist_ao_1, dist_ao_2)
549 CALL create_3c_tensor(t_3c_int(1, 1), dist_ri, dist_ao_1, dist_ao_2, ri_data%pgrid, &
550 ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
551 map1=[1], map2=[2, 3], &
552 name=
"O (RI AO | AO)")
555 "HFX_3c_nl", qs_env, op_pos=1, sym_jk=.true., own_dist=.true.)
559 basis_set_ri, basis_set_ao, basis_set_ao, &
560 ri_data%ri_metric, int_eps=ri_data%eps_schwarz, op_pos=1, &
561 desymmetrize=.false., &
562 bounds_i=[starts_array_mc_block_int(i_mem), ends_array_mc_block_int(i_mem)])
563 CALL dbt_copy(t_3c_int_batched(1, 1), t_3c_int(1, 1), summation=.true., move_data=.true.)
564 CALL dbt_filter(t_3c_int(1, 1), ri_data%filter_eps/2)
567 CALL dbt_destroy(t_3c_int_batched(1, 1))
571 CALL dbt_create(t_3c_int(1, 1), t_3c_tmp)
573 IF (ri_data%flavor ==
ri_pmat)
THEN
575 CALL dbt_copy(t_3c_int(1, 1), t_3c_tmp)
576 CALL dbt_copy(t_3c_tmp, t_3c_int(1, 1), order=[1, 3, 2], summation=.true., move_data=.true.)
580 CALL dbt_filter(t_3c_int(1, 1), ri_data%filter_eps)
582 CALL dbt_filter(t_3c_int(1, 1), ri_data%filter_eps_storage/2)
585 CALL dbt_destroy(t_3c_tmp)
592 CALL dbt_pgrid_create(para_env, pdims, pgrid, tensor_dims=[natom, natom, max(1, natom/(n_mem*nthreads))])
596 nblks =
SIZE(ri_data%bsizes_RI_split)
597 ALLOCATE (sizes_ri_ext(natom*ri_data%ncell_RI), sizes_ri_ext_split(nblks*ri_data%ncell_RI))
598 DO i_img = 1, ri_data%ncell_RI
599 sizes_ri_ext((i_img - 1)*natom + 1:i_img*natom) = sizes_ri(:)
600 sizes_ri_ext_split((i_img - 1)*nblks + 1:i_img*nblks) = ri_data%bsizes_RI_split(:)
604 pgrid, sizes_ao, sizes_ao, sizes_ri, map1=[1, 2], map2=[3], &
606 CALL dbt_destroy(t_3c_tmp)
609 ALLOCATE (dist_ri_ext(natom*ri_data%ncell_RI))
610 DO i_img = 1, ri_data%ncell_RI
611 dist_ri_ext((i_img - 1)*natom + 1:i_img*natom) = dist_ri(:)
614 ALLOCATE (t_3c_int_batched(nimg, 1))
615 CALL dbt_distribution_new(t_dist, pgrid, dist_ao_1, dist_ao_2, dist_ri_ext)
616 CALL dbt_create(t_3c_int_batched(1, 1),
"KP_3c_ints", t_dist, [1, 2], [3], &
617 sizes_ao, sizes_ao, sizes_ri_ext)
619 CALL dbt_create(t_3c_int_batched(1, 1), t_3c_int_batched(i_img, 1))
621 CALL dbt_distribution_destroy(t_dist)
623 CALL get_qs_env(qs_env, nkind=nkind, particle_set=particle_set, atomic_kind_set=atomic_kind_set)
624 CALL dbt_mp_environ_pgrid(pgrid, pdims, pcoord)
625 CALL mp_comm_t3c%create(pgrid%mp_comm_2d, 3, pdims)
627 nkind, particle_set, mp_comm_t3c, own_comm=.true.)
628 DEALLOCATE (dist_ri, dist_ao_1, dist_ao_2)
632 "HFX_3c_nl", qs_env, op_pos=2, sym_ij=.false., own_dist=.true.)
634 CALL create_3c_tensor(t_3c_int(1, 1), dist_ri, dist_ao_1, dist_ao_2, ri_data%pgrid, &
635 sizes_ri_ext_split, ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
636 map1=[1], map2=[2, 3], &
637 name=
"O (RI AO | AO)")
639 CALL dbt_create(t_3c_int(1, 1), t_3c_int(1, j_img))
642 CALL dbt_create(t_3c_int(1, 1), t_3c_tmp)
645 basis_set_ao, basis_set_ao, basis_set_ri, &
646 ri_data%ri_metric, int_eps=ri_data%eps_schwarz, op_pos=2, &
647 desymmetrize=.false., do_kpoints=.true., do_hfx_kpoints=.true., &
648 bounds_k=[starts_array_mc_block_int(i_mem), ends_array_mc_block_int(i_mem)], &
649 ri_range=ri_range, img_to_ri_cell=ri_data%img_to_RI_cell)
655 CALL dbt_copy(t_3c_int_batched(i_img, 1), t_3c_tmp, order=[3, 2, 1], move_data=.true.)
656 CALL dbt_filter(t_3c_tmp, ri_data%filter_eps)
657 CALL dbt_copy(t_3c_tmp, t_3c_int(1, i_img), order=[1, 3, 2], &
658 summation=.true., move_data=.true.)
664 CALL dbt_destroy(t_3c_int_batched(i_img, 1))
666 DEALLOCATE (t_3c_int_batched)
668 CALL dbt_destroy(t_3c_tmp)
670 CALL dbt_pgrid_destroy(pgrid)
673 "HFX_2c_nl_pot", qs_env, sym_ij=.NOT. do_kpoints_prv, &
677 ALLOCATE (row_bsize(
SIZE(sizes_ri)))
678 ALLOCATE (col_bsize(
SIZE(sizes_ri)))
679 row_bsize(:) = sizes_ri
680 col_bsize(:) = sizes_ri
683 symm = dbcsr_type_symmetric
684 IF (do_kpoints_prv) symm = dbcsr_type_no_symmetry
686 CALL dbcsr_create(t_2c_int_pot(1),
"(R|P) HFX", dbcsr_dist, symm, row_bsize, col_bsize)
688 CALL dbcsr_create(t_2c_int_pot(i_img), template=t_2c_int_pot(1))
691 IF (.NOT. ri_data%same_op)
THEN
692 CALL dbcsr_create(t_2c_int_ri(1),
"(R|P) HFX", dbcsr_dist, symm, row_bsize, col_bsize)
694 CALL dbcsr_create(t_2c_int_ri(i_img), template=t_2c_int_ri(1))
697 DEALLOCATE (col_bsize, row_bsize)
701 CALL build_2c_integrals(t_2c_int_pot, ri_data%filter_eps_2c, qs_env, nl_2c_pot, basis_set_ri, basis_set_ri, &
702 ri_data%hfx_pot, do_kpoints=do_kpoints_prv, do_hfx_kpoints=do_kpoints_prv)
705 IF (.NOT. ri_data%same_op)
THEN
707 "HFX_2c_nl_RI", qs_env, sym_ij=.NOT. do_kpoints_prv, &
710 CALL build_2c_integrals(t_2c_int_ri, ri_data%filter_eps_2c, qs_env, nl_2c_ri, basis_set_ri, basis_set_ri, &
711 ri_data%ri_metric, do_kpoints=do_kpoints_prv, do_hfx_kpoints=do_kpoints_prv)
716 DO ibasis = 1,
SIZE(basis_set_ao)
717 orb_basis => basis_set_ao(ibasis)%gto_basis_set
718 ri_basis => basis_set_ri(ibasis)%gto_basis_set
724 IF (ri_data%calc_condnum)
THEN
725 CALL arnoldi_extremal(t_2c_int_pot(1), max_ev, min_ev, threshold=ri_data%eps_lanczos, &
726 max_iter=ri_data%max_iter_lanczos, converged=converged)
728 IF (.NOT. converged)
THEN
729 cpwarn(
"Not converged: unreliable condition number estimate of (P|Q) matrix (HFX potential).")
732 IF (ri_data%unit_nr > 0)
THEN
733 WRITE (ri_data%unit_nr,
'(T2,A)')
"2-Norm Condition Number of (P|Q) integrals (HFX potential)"
735 WRITE (ri_data%unit_nr,
'(T4,A,ES11.3E3,T32,A,ES11.3E3,A4,ES11.3E3,T63,A,F8.4)') &
736 "CN : max/min ev: ", max_ev,
" / ", min_ev,
"=", max_ev/min_ev,
"Log(2-CN):", log10(max_ev/min_ev)
738 WRITE (ri_data%unit_nr,
'(T4,A,ES11.3E3,T32,A,ES11.3E3,T63,A)') &
739 "CN : max/min ev: ", max_ev,
" / ", min_ev,
"Log(CN): infinity"
743 IF (.NOT. ri_data%same_op)
THEN
744 CALL arnoldi_extremal(t_2c_int_ri(1), max_ev, min_ev, threshold=ri_data%eps_lanczos, &
745 max_iter=ri_data%max_iter_lanczos, converged=converged)
747 IF (.NOT. converged)
THEN
748 cpwarn(
"Not converged: unreliable condition number estimate of (P|Q) matrix (RI metric).")
751 IF (ri_data%unit_nr > 0)
THEN
752 WRITE (ri_data%unit_nr,
'(T2,A)')
"2-Norm Condition Number of (P|Q) integrals (RI metric)"
754 WRITE (ri_data%unit_nr,
'(T4,A,ES11.3E3,T32,A,ES11.3E3,A4,ES11.3E3,T63,A,F8.4)') &
755 "CN : max/min ev: ", max_ev,
" / ", min_ev,
"=", max_ev/min_ev,
"Log(2-CN):", log10(max_ev/min_ev)
757 WRITE (ri_data%unit_nr,
'(T4,A,ES11.3E3,T32,A,ES11.3E3,T63,A)') &
758 "CN : max/min ev: ", max_ev,
" / ", min_ev,
"Log(CN): infinity"
764 CALL timestop(handle)
775 SUBROUTINE hfx_ri_pre_scf_pmat(qs_env, ri_data)
779 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_pre_scf_Pmat'
781 INTEGER :: handle, handle2, i_mem, j_mem, &
782 n_dependent, unit_nr, unit_nr_dbcsr
783 INTEGER(int_8) :: nflop, nze, nze_o
784 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: batch_ranges_ao, batch_ranges_ri
785 INTEGER,
DIMENSION(2, 1) :: bounds_i
786 INTEGER,
DIMENSION(2, 2) :: bounds_j
787 INTEGER,
DIMENSION(3) :: dims_3c
788 REAL(kind=
dp) :: compression_factor, memory_3c, occ, &
791 TYPE(
dbcsr_type),
DIMENSION(1) :: t_2c_int_mat, t_2c_op_pot, t_2c_op_ri, &
793 TYPE(dbt_type) :: t_3c_2
794 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:) :: t_2c_int, t_2c_work
795 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_int_1
798 CALL timeset(routinen, handle)
800 unit_nr_dbcsr = ri_data%unit_nr_dbcsr
801 unit_nr = ri_data%unit_nr
803 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
805 CALL timeset(routinen//
"_int", handle2)
807 ALLOCATE (t_2c_int(1), t_2c_work(1), t_3c_int_1(1, 1))
810 CALL dbt_copy(t_3c_int_1(1, 1), ri_data%t_3c_int_ctr_3(1, 1), order=[1, 2, 3], move_data=.true.)
812 CALL dbt_destroy(t_3c_int_1(1, 1))
814 CALL timestop(handle2)
816 CALL timeset(routinen//
"_2c", handle2)
818 IF (ri_data%same_op) t_2c_op_ri(1) = t_2c_op_pot(1)
819 CALL dbcsr_create(t_2c_int_mat(1), template=t_2c_op_ri(1), matrix_type=dbcsr_type_no_symmetry)
820 threshold = max(ri_data%filter_eps, 1.0e-12_dp)
822 SELECT CASE (ri_data%t2c_method)
825 threshold=threshold, silent=.false.)
827 CALL dbcsr_copy(t_2c_int_mat(1), t_2c_op_ri(1))
831 CALL dbcsr_copy(t_2c_int_mat(1), t_2c_op_ri(1))
832 CALL cp_dbcsr_power(t_2c_int_mat(1), -1.0_dp, ri_data%eps_eigval, n_dependent, &
833 para_env, blacs_env, verbose=ri_data%unit_nr_dbcsr > 0)
836 IF (ri_data%check_2c_inv)
THEN
837 CALL check_inverse(t_2c_int_mat(1), t_2c_op_ri(1), unit_nr=unit_nr)
841 CALL dbt_create(t_2c_int_mat(1), t_2c_work(1))
842 CALL dbt_copy_matrix_to_tensor(t_2c_int_mat(1), t_2c_work(1))
843 CALL dbt_copy(t_2c_work(1), ri_data%t_2c_inv(1, 1), move_data=.true.)
844 CALL dbt_destroy(t_2c_work(1))
845 CALL dbt_filter(ri_data%t_2c_inv(1, 1), ri_data%filter_eps)
846 IF (.NOT. ri_data%same_op)
THEN
848 CALL dbt_create(t_2c_op_pot(1), t_2c_work(1))
849 CALL dbt_copy_matrix_to_tensor(t_2c_op_pot(1), t_2c_work(1))
850 CALL dbt_copy(t_2c_work(1), ri_data%t_2c_pot(1, 1), move_data=.true.)
851 CALL dbt_destroy(t_2c_work(1))
852 CALL dbt_filter(ri_data%t_2c_pot(1, 1), ri_data%filter_eps)
855 IF (ri_data%same_op)
THEN
858 CALL dbcsr_create(t_2c_tmp(1), template=t_2c_op_ri(1), matrix_type=dbcsr_type_no_symmetry)
859 CALL dbcsr_create(t_2c_tmp_2(1), template=t_2c_op_ri(1), matrix_type=dbcsr_type_no_symmetry)
861 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, t_2c_int_mat(1), t_2c_op_pot(1), 0.0_dp, t_2c_tmp(1), &
862 filter_eps=ri_data%filter_eps)
865 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, t_2c_tmp(1), t_2c_int_mat(1), 0.0_dp, t_2c_tmp_2(1), &
866 filter_eps=ri_data%filter_eps)
869 t_2c_int_mat(1) = t_2c_tmp_2(1)
872 CALL dbt_create(t_2c_int_mat(1), t_2c_int(1), name=
"(RI|RI)")
873 CALL dbt_copy_matrix_to_tensor(t_2c_int_mat(1), t_2c_int(1))
875 CALL dbt_copy(t_2c_int(1), ri_data%t_2c_int(1, 1), move_data=.true.)
876 CALL dbt_destroy(t_2c_int(1))
877 CALL dbt_filter(ri_data%t_2c_int(1, 1), ri_data%filter_eps)
879 CALL timestop(handle2)
881 CALL dbt_create(ri_data%t_3c_int_ctr_3(1, 1), t_3c_2)
883 CALL dbt_get_info(ri_data%t_3c_int_ctr_3(1, 1), nfull_total=dims_3c)
888 ALLOCATE (batch_ranges_ri(ri_data%n_mem_RI + 1))
889 ALLOCATE (batch_ranges_ao(ri_data%n_mem + 1))
890 batch_ranges_ri(:ri_data%n_mem_RI) = ri_data%starts_array_RI_mem_block(:)
891 batch_ranges_ri(ri_data%n_mem_RI + 1) = ri_data%ends_array_RI_mem_block(ri_data%n_mem_RI) + 1
892 batch_ranges_ao(:ri_data%n_mem) = ri_data%starts_array_mem_block(:)
893 batch_ranges_ao(ri_data%n_mem + 1) = ri_data%ends_array_mem_block(ri_data%n_mem) + 1
895 CALL dbt_batched_contract_init(ri_data%t_3c_int_ctr_3(1, 1), batch_range_1=batch_ranges_ri, &
896 batch_range_2=batch_ranges_ao)
897 CALL dbt_batched_contract_init(t_3c_2, batch_range_1=batch_ranges_ri, &
898 batch_range_2=batch_ranges_ao)
900 DO i_mem = 1, ri_data%n_mem_RI
901 bounds_i(:, 1) = [ri_data%starts_array_RI_mem(i_mem), ri_data%ends_array_RI_mem(i_mem)]
903 CALL dbt_batched_contract_init(ri_data%t_2c_int(1, 1))
904 DO j_mem = 1, ri_data%n_mem
905 bounds_j(:, 1) = [ri_data%starts_array_mem(j_mem), ri_data%ends_array_mem(j_mem)]
906 bounds_j(:, 2) = [1, dims_3c(3)]
907 CALL timeset(routinen//
"_RIx3C", handle2)
908 CALL dbt_contract(1.0_dp, ri_data%t_2c_int(1, 1), ri_data%t_3c_int_ctr_3(1, 1), &
910 contract_1=[2], notcontract_1=[1], &
911 contract_2=[1], notcontract_2=[2, 3], &
912 map_1=[1], map_2=[2, 3], filter_eps=ri_data%filter_eps_storage, &
915 unit_nr=unit_nr_dbcsr, &
918 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
919 CALL timestop(handle2)
921 CALL timeset(routinen//
"_copy_2", handle2)
922 CALL dbt_copy(t_3c_2, ri_data%t_3c_int_ctr_1(1, 1), order=[2, 1, 3], move_data=.true.)
927 CALL compress_tensor(ri_data%t_3c_int_ctr_1(1, 1), ri_data%blk_indices(j_mem, i_mem)%ind, &
928 ri_data%store_3c(j_mem, i_mem), ri_data%filter_eps_storage, memory_3c)
930 CALL timestop(handle2)
932 CALL dbt_batched_contract_finalize(ri_data%t_2c_int(1, 1))
934 CALL dbt_batched_contract_finalize(t_3c_2)
935 CALL dbt_batched_contract_finalize(ri_data%t_3c_int_ctr_3(1, 1))
937 CALL para_env%sum(memory_3c)
938 compression_factor = real(nze_o,
dp)*1.0e-06*8.0_dp/memory_3c
940 IF (unit_nr > 0)
THEN
941 WRITE (unit=unit_nr, fmt=
"((T3,A,T66,F11.2,A4))") &
942 "MEMORY_INFO| Memory for 3-center HFX integrals (compressed):", memory_3c,
' MiB'
944 WRITE (unit=unit_nr, fmt=
"((T3,A,T60,F21.2))") &
945 "MEMORY_INFO| Compression factor: ", compression_factor
948 CALL dbt_clear(ri_data%t_2c_int(1, 1))
949 CALL dbt_destroy(t_3c_2)
951 CALL dbt_copy(ri_data%t_3c_int_ctr_3(1, 1), ri_data%t_3c_int_ctr_2(1, 1), order=[2, 1, 3], move_data=.true.)
953 CALL timestop(handle)
960 SUBROUTINE sort_unique_blkind_2d(blk_ind)
961 INTEGER,
ALLOCATABLE,
DIMENSION(:, :), &
962 INTENT(INOUT) :: blk_ind
964 INTEGER :: end_ind, iblk, iblk_all, irow, nblk, &
966 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ind_1, ind_2, sort_1, sort_2
967 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: blk_ind_tmp
969 nblk =
SIZE(blk_ind, 1)
971 ALLOCATE (sort_1(nblk))
972 ALLOCATE (ind_1(nblk))
974 sort_1(:) = blk_ind(:, 1)
975 CALL sort(sort_1, nblk, ind_1)
977 blk_ind(:, :) = blk_ind(ind_1, :)
981 DO WHILE (start_ind <= nblk)
982 irow = blk_ind(start_ind, 1)
985 IF (end_ind + 1 <= nblk)
THEN
986 DO WHILE (blk_ind(end_ind + 1, 1) == irow)
987 end_ind = end_ind + 1
988 IF (end_ind + 1 > nblk)
EXIT
992 ncols = end_ind - start_ind + 1
993 ALLOCATE (sort_2(ncols))
994 ALLOCATE (ind_2(ncols))
995 sort_2(:) = blk_ind(start_ind:end_ind, 2)
996 CALL sort(sort_2, ncols, ind_2)
997 ind_2 = ind_2 + start_ind - 1
999 blk_ind(start_ind:end_ind, :) = blk_ind(ind_2, :)
1000 start_ind = end_ind + 1
1002 DEALLOCATE (sort_2, ind_2)
1005 ALLOCATE (blk_ind_tmp(nblk, 2))
1009 DO iblk_all = 1, nblk
1011 IF (all(blk_ind_tmp(iblk, :) == blk_ind(iblk_all, :)))
THEN
1016 blk_ind_tmp(iblk, :) = blk_ind(iblk_all, :)
1020 DEALLOCATE (blk_ind)
1021 ALLOCATE (blk_ind(nblk, 2))
1023 blk_ind(:, :) = blk_ind_tmp(:nblk, :)
1040 geometry_did_change, nspins, hf_fraction)
1043 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: ks_matrix
1044 REAL(kind=
dp),
INTENT(OUT) :: ehfx
1048 LOGICAL,
INTENT(IN) :: geometry_did_change
1049 INTEGER,
INTENT(IN) :: nspins
1050 REAL(kind=
dp),
INTENT(IN) :: hf_fraction
1052 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_update_ks'
1054 CHARACTER(1) :: mtype
1055 INTEGER :: handle, handle2, i, ispin, j
1056 INTEGER(int_8) :: nblks
1057 INTEGER,
DIMENSION(2) :: homo
1058 LOGICAL :: is_antisymmetric
1059 REAL(
dp) :: etmp,
fac
1060 REAL(kind=
dp),
DIMENSION(:),
POINTER :: mo_eigenvalues
1062 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: my_ks_matrix, my_rho_ao
1067 CALL timeset(routinen, handle)
1069 IF (nspins == 1)
THEN
1070 fac = 0.5_dp*hf_fraction
1072 fac = 1.0_dp*hf_fraction
1076 NULLIFY (my_ks_matrix, my_rho_ao)
1078 is_antisymmetric = mtype == dbcsr_type_antisymmetric
1079 IF (is_antisymmetric)
THEN
1080 ALLOCATE (my_ks_matrix(
SIZE(ks_matrix, 1),
SIZE(ks_matrix, 2)))
1081 ALLOCATE (my_rho_ao(
SIZE(rho_ao, 1),
SIZE(rho_ao, 2)))
1083 DO i = 1,
SIZE(ks_matrix, 1)
1084 DO j = 1,
SIZE(ks_matrix, 2)
1085 ALLOCATE (my_ks_matrix(i, j)%matrix, my_rho_ao(i, j)%matrix)
1086 CALL dbcsr_create(my_ks_matrix(i, j)%matrix, template=ks_matrix(i, j)%matrix, &
1087 matrix_type=dbcsr_type_no_symmetry)
1089 CALL dbcsr_create(my_rho_ao(i, j)%matrix, template=rho_ao(i, j)%matrix, &
1090 matrix_type=dbcsr_type_no_symmetry)
1095 my_ks_matrix => ks_matrix
1102 IF (ri_data%input_flavor ==
ri_mo .AND. (.NOT.
PRESENT(mos)) .AND. ri_data%flavor ==
ri_mo)
THEN
1103 CALL switch_ri_flavor(ri_data, qs_env)
1104 ELSE IF (ri_data%input_flavor ==
ri_mo .AND.
PRESENT(mos) .AND. ri_data%flavor ==
ri_pmat)
THEN
1105 CALL switch_ri_flavor(ri_data, qs_env)
1108 SELECT CASE (ri_data%flavor)
1110 cpassert(
PRESENT(mos))
1111 CALL timeset(routinen//
"_MO", handle2)
1113 DO ispin = 1, nspins
1114 NULLIFY (mo_coeff_b_tmp)
1115 cpassert(mos(ispin)%uniform_occupation)
1116 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, eigenvalues=mo_eigenvalues, mo_coeff_b=mo_coeff_b_tmp)
1118 IF (.NOT. mos(ispin)%use_mo_coeff_b)
CALL copy_fm_to_dbcsr(mo_coeff, mo_coeff_b_tmp)
1119 CALL dbcsr_copy(mo_coeff_b(ispin), mo_coeff_b_tmp)
1122 DO ispin = 1, nspins
1123 CALL dbcsr_scale(mo_coeff_b(ispin), sqrt(mos(ispin)%maxocc))
1124 homo(ispin) = mos(ispin)%homo
1127 CALL timestop(handle2)
1129 CALL hfx_ri_update_ks_mo(qs_env, ri_data, my_ks_matrix, mo_coeff_b, homo, &
1130 geometry_did_change, nspins,
fac)
1135 DO ispin = 1,
SIZE(my_rho_ao, 1)
1137 CALL para_env%sum(nblks)
1138 IF (nblks == 0)
THEN
1139 cpabort(
"received empty density matrix")
1143 CALL hfx_ri_update_ks_pmat(qs_env, ri_data, my_ks_matrix, my_rho_ao, &
1144 geometry_did_change, nspins,
fac)
1148 DO ispin = 1, nspins
1152 DO ispin = 1, nspins
1153 CALL dbcsr_filter(my_ks_matrix(ispin, 1)%matrix, ri_data%filter_eps)
1156 CALL timeset(routinen//
"_energy", handle2)
1159 DO ispin = 1, nspins
1160 CALL dbcsr_dot(my_ks_matrix(ispin, 1)%matrix, my_rho_ao(ispin, 1)%matrix, &
1162 ehfx = ehfx + 0.5_dp*etmp
1165 CALL timestop(handle2)
1168 IF (is_antisymmetric)
THEN
1169 DO i = 1,
SIZE(ks_matrix, 1)
1170 DO j = 1,
SIZE(ks_matrix, 2)
1179 CALL timestop(handle)
1197 SUBROUTINE hfx_ri_update_ks_mo(qs_env, ri_data, ks_matrix, mo_coeff, &
1198 homo, geometry_did_change, nspins, fac)
1202 TYPE(
dbcsr_type),
DIMENSION(:),
INTENT(IN) :: mo_coeff
1203 INTEGER,
DIMENSION(:) :: homo
1204 LOGICAL,
INTENT(IN) :: geometry_did_change
1205 INTEGER,
INTENT(IN) :: nspins
1206 REAL(
dp),
INTENT(IN) ::
fac
1208 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_update_ks_mo'
1210 INTEGER :: bsize, bsum, comm_2d_handle, handle, &
1211 handle2, i_mem, iblock, iproc, ispin, &
1212 n_mem, n_mos, nblock, unit_nr_dbcsr
1213 INTEGER(int_8) :: nblks, nflop
1214 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: batch_ranges_1, batch_ranges_2, dist1, dist2, dist3, &
1215 mem_end, mem_end_block_1, mem_end_block_2, mem_size, mem_start, mem_start_block_1, &
1216 mem_start_block_2, mo_bsizes_1, mo_bsizes_2
1217 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: bounds
1218 INTEGER,
DIMENSION(2) :: pdims_2d
1219 INTEGER,
DIMENSION(3) :: pdims
1220 LOGICAL :: do_initialize
1223 TYPE(dbt_pgrid_type) :: pgrid, pgrid_2d
1224 TYPE(dbt_type) :: ks_t, ks_t_mat, mo_coeff_t, &
1226 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_int_mo_1, t_3c_int_mo_2
1230 CALL timeset(routinen, handle)
1232 cpassert(
SIZE(ks_matrix, 2) == 1)
1234 unit_nr_dbcsr = ri_data%unit_nr_dbcsr
1236 IF (geometry_did_change)
THEN
1237 CALL hfx_ri_pre_scf_mo(qs_env, ri_data, nspins)
1240 nblks = dbt_get_num_blocks_total(ri_data%t_3c_int_ctr_1(1, 1))
1241 IF (nblks == 0)
THEN
1242 cpabort(
"3-center integrals are not available (first call requires geometry_did_change=.TRUE.)")
1245 DO ispin = 1, nspins
1246 nblks = dbt_get_num_blocks_total(ri_data%t_2c_int(ispin, 1))
1247 IF (nblks == 0)
THEN
1248 cpabort(
"2-center integrals are not available (first call requires geometry_did_change=.TRUE.)")
1252 IF (.NOT.
ALLOCATED(ri_data%t_3c_int_mo))
THEN
1253 do_initialize = .true.
1254 cpassert(.NOT.
ALLOCATED(ri_data%t_3c_ctr_RI))
1255 cpassert(.NOT.
ALLOCATED(ri_data%t_3c_ctr_KS))
1256 cpassert(.NOT.
ALLOCATED(ri_data%t_3c_ctr_KS_copy))
1257 ALLOCATE (ri_data%t_3c_int_mo(nspins, 1, 1))
1258 ALLOCATE (ri_data%t_3c_ctr_RI(nspins, 1, 1))
1259 ALLOCATE (ri_data%t_3c_ctr_KS(nspins, 1, 1))
1260 ALLOCATE (ri_data%t_3c_ctr_KS_copy(nspins, 1, 1))
1262 do_initialize = .false.
1267 ALLOCATE (bounds(2, 1))
1269 CALL dbcsr_get_info(ks_matrix(1, 1)%matrix, distribution=ks_dist)
1272 CALL comm_2d%set_handle(comm_2d_handle)
1273 pgrid_2d = dbt_nd_mp_comm(comm_2d, [1], [2], pdims_2d=pdims_2d)
1275 CALL create_2c_tensor(ks_t, dist1, dist2, pgrid_2d, ri_data%bsizes_AO_fit, ri_data%bsizes_AO_fit, &
1278 DEALLOCATE (dist1, dist2)
1280 CALL para_env%sync()
1283 ALLOCATE (t_3c_int_mo_1(1, 1), t_3c_int_mo_2(1, 1))
1284 DO ispin = 1, nspins
1287 ALLOCATE (mo_bsizes_2(n_mos))
1291 mem_start_block_2, mem_end_block_2)
1292 n_mem = ri_data%n_mem
1293 ALLOCATE (mem_size(n_mem))
1296 bsize = sum(mo_bsizes_2(mem_start_block_2(i_mem):mem_end_block_2(i_mem)))
1297 mem_size(i_mem) = bsize
1301 ALLOCATE (mem_start_block_1(n_mem))
1302 ALLOCATE (mem_end_block_1(n_mem))
1303 nblock =
SIZE(mo_bsizes_1)
1309 cpassert(iblock <= nblock)
1310 bsum = bsum + mo_bsizes_1(iblock)
1311 IF (bsum == mem_size(i_mem))
THEN
1312 IF (i_mem == 1)
THEN
1313 mem_start_block_1(i_mem) = 1
1315 mem_start_block_1(i_mem) = mem_end_block_1(i_mem - 1) + 1
1317 mem_end_block_1(i_mem) = iblock
1323 ALLOCATE (batch_ranges_1(ri_data%n_mem + 1))
1324 batch_ranges_1(:ri_data%n_mem) = mem_start_block_1(:)
1325 batch_ranges_1(ri_data%n_mem + 1) = mem_end_block_1(ri_data%n_mem) + 1
1327 ALLOCATE (batch_ranges_2(ri_data%n_mem + 1))
1328 batch_ranges_2(:ri_data%n_mem) = mem_start_block_2(:)
1329 batch_ranges_2(ri_data%n_mem + 1) = mem_end_block_2(ri_data%n_mem) + 1
1331 iproc = para_env%mepos
1333 CALL create_3c_tensor(t_3c_int_mo_1(1, 1), dist1, dist2, dist3, ri_data%pgrid_1, &
1334 ri_data%bsizes_AO_split, ri_data%bsizes_RI_split, mo_bsizes_1, &
1336 name=
"(AO RI | MO)")
1338 DEALLOCATE (dist1, dist2, dist3)
1340 CALL create_3c_tensor(t_3c_int_mo_2(1, 1), dist1, dist2, dist3, ri_data%pgrid_2, &
1341 mo_bsizes_1, ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, &
1343 name=
"(MO | RI AO)")
1345 DEALLOCATE (dist1, dist2, dist3)
1347 CALL create_2c_tensor(mo_coeff_t_split, dist1, dist2, pgrid_2d, ri_data%bsizes_AO_split, mo_bsizes_1, &
1350 DEALLOCATE (dist1, dist2)
1352 cpassert(homo(ispin)/ri_data%n_mem > 0)
1354 IF (do_initialize)
THEN
1357 CALL dbt_pgrid_create(para_env, pdims, pgrid, &
1358 tensor_dims=[
SIZE(ri_data%bsizes_RI_fit), &
1359 (homo(ispin) - 1)/ri_data%n_mem + 1, &
1360 SIZE(ri_data%bsizes_AO_fit)])
1361 CALL create_3c_tensor(ri_data%t_3c_int_mo(ispin, 1, 1), dist1, dist2, dist3, pgrid, &
1362 ri_data%bsizes_RI_fit, mo_bsizes_2, ri_data%bsizes_AO_fit, &
1364 name=
"(RI | MO AO)")
1366 DEALLOCATE (dist1, dist2, dist3)
1368 CALL create_3c_tensor(ri_data%t_3c_ctr_KS(ispin, 1, 1), dist1, dist2, dist3, pgrid, &
1369 ri_data%bsizes_RI_fit, mo_bsizes_2, ri_data%bsizes_AO_fit, &
1371 name=
"(RI MO | AO)")
1372 DEALLOCATE (dist1, dist2, dist3)
1373 CALL dbt_pgrid_destroy(pgrid)
1375 CALL dbt_create(ri_data%t_3c_int_mo(ispin, 1, 1), ri_data%t_3c_ctr_RI(ispin, 1, 1), name=
"(RI | MO AO)")
1376 CALL dbt_create(ri_data%t_3c_ctr_KS(ispin, 1, 1), ri_data%t_3c_ctr_KS_copy(ispin, 1, 1))
1379 CALL dbt_create(mo_coeff(ispin), mo_coeff_t, name=
"MO coeffs")
1380 CALL dbt_copy_matrix_to_tensor(mo_coeff(ispin), mo_coeff_t)
1381 CALL dbt_copy(mo_coeff_t, mo_coeff_t_split, move_data=.true.)
1382 CALL dbt_filter(mo_coeff_t_split, ri_data%filter_eps_mo)
1383 CALL dbt_destroy(mo_coeff_t)
1385 CALL dbt_batched_contract_init(ks_t)
1386 CALL dbt_batched_contract_init(ri_data%t_3c_ctr_KS(ispin, 1, 1), batch_range_2=batch_ranges_2)
1387 CALL dbt_batched_contract_init(ri_data%t_3c_ctr_KS_copy(ispin, 1, 1), batch_range_2=batch_ranges_2)
1389 CALL dbt_batched_contract_init(ri_data%t_2c_int(ispin, 1))
1390 CALL dbt_batched_contract_init(ri_data%t_3c_int_mo(ispin, 1, 1), batch_range_2=batch_ranges_2)
1391 CALL dbt_batched_contract_init(ri_data%t_3c_ctr_RI(ispin, 1, 1), batch_range_2=batch_ranges_2)
1395 bounds(:, 1) = [mem_start(i_mem), mem_end(i_mem)]
1397 CALL dbt_batched_contract_init(mo_coeff_t_split)
1398 CALL dbt_batched_contract_init(ri_data%t_3c_int_ctr_1(1, 1))
1399 CALL dbt_batched_contract_init(t_3c_int_mo_1(1, 1), &
1400 batch_range_3=batch_ranges_1)
1401 CALL timeset(routinen//
"_MOx3C_R", handle2)
1402 CALL dbt_contract(1.0_dp, mo_coeff_t_split, ri_data%t_3c_int_ctr_1(1, 1), &
1403 0.0_dp, t_3c_int_mo_1(1, 1), &
1404 contract_1=[1], notcontract_1=[2], &
1405 contract_2=[3], notcontract_2=[1, 2], &
1406 map_1=[3], map_2=[1, 2], &
1408 filter_eps=ri_data%filter_eps_mo/2, &
1409 unit_nr=unit_nr_dbcsr, &
1410 move_data=.false., &
1413 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
1415 CALL timestop(handle2)
1416 CALL dbt_batched_contract_finalize(mo_coeff_t_split)
1417 CALL dbt_batched_contract_finalize(ri_data%t_3c_int_ctr_1(1, 1))
1418 CALL dbt_batched_contract_finalize(t_3c_int_mo_1(1, 1))
1420 CALL timeset(routinen//
"_copy_1", handle2)
1421 CALL dbt_copy(t_3c_int_mo_1(1, 1), ri_data%t_3c_int_mo(ispin, 1, 1), order=[3, 1, 2], move_data=.true.)
1422 CALL timestop(handle2)
1424 CALL dbt_batched_contract_init(mo_coeff_t_split)
1425 CALL dbt_batched_contract_init(ri_data%t_3c_int_ctr_2(1, 1))
1426 CALL dbt_batched_contract_init(t_3c_int_mo_2(1, 1), &
1427 batch_range_1=batch_ranges_1)
1429 CALL timeset(routinen//
"_MOx3C_L", handle2)
1430 CALL dbt_contract(1.0_dp, mo_coeff_t_split, ri_data%t_3c_int_ctr_2(1, 1), &
1431 0.0_dp, t_3c_int_mo_2(1, 1), &
1432 contract_1=[1], notcontract_1=[2], &
1433 contract_2=[1], notcontract_2=[2, 3], &
1434 map_1=[1], map_2=[2, 3], &
1436 filter_eps=ri_data%filter_eps_mo/2, &
1437 unit_nr=unit_nr_dbcsr, &
1438 move_data=.false., &
1441 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
1443 CALL timestop(handle2)
1445 CALL dbt_batched_contract_finalize(mo_coeff_t_split)
1446 CALL dbt_batched_contract_finalize(ri_data%t_3c_int_ctr_2(1, 1))
1447 CALL dbt_batched_contract_finalize(t_3c_int_mo_2(1, 1))
1449 CALL timeset(routinen//
"_copy_1", handle2)
1450 CALL dbt_copy(t_3c_int_mo_2(1, 1), ri_data%t_3c_int_mo(ispin, 1, 1), order=[2, 1, 3], &
1451 summation=.true., move_data=.true.)
1453 CALL dbt_filter(ri_data%t_3c_int_mo(ispin, 1, 1), ri_data%filter_eps_mo)
1454 CALL timestop(handle2)
1456 CALL timeset(routinen//
"_RIx3C", handle2)
1458 CALL dbt_contract(1.0_dp, ri_data%t_2c_int(ispin, 1), ri_data%t_3c_int_mo(ispin, 1, 1), &
1459 0.0_dp, ri_data%t_3c_ctr_RI(ispin, 1, 1), &
1460 contract_1=[1], notcontract_1=[2], &
1461 contract_2=[1], notcontract_2=[2, 3], &
1462 map_1=[1], map_2=[2, 3], filter_eps=ri_data%filter_eps, &
1463 unit_nr=unit_nr_dbcsr, &
1466 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
1468 CALL timestop(handle2)
1470 CALL timeset(routinen//
"_copy_2", handle2)
1473 CALL dbt_copy(ri_data%t_3c_ctr_RI(ispin, 1, 1), ri_data%t_3c_ctr_KS(ispin, 1, 1), move_data=.true.)
1474 CALL dbt_copy(ri_data%t_3c_ctr_KS(ispin, 1, 1), ri_data%t_3c_ctr_KS_copy(ispin, 1, 1))
1475 CALL timestop(handle2)
1477 CALL timeset(routinen//
"_3Cx3C", handle2)
1478 CALL dbt_contract(-
fac, ri_data%t_3c_ctr_KS(ispin, 1, 1), ri_data%t_3c_ctr_KS_copy(ispin, 1, 1), &
1480 contract_1=[1, 2], notcontract_1=[3], &
1481 contract_2=[1, 2], notcontract_2=[3], &
1482 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps/n_mem, &
1483 unit_nr=unit_nr_dbcsr, move_data=.true., &
1486 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
1488 CALL timestop(handle2)
1491 CALL dbt_batched_contract_finalize(ks_t)
1492 CALL dbt_batched_contract_finalize(ri_data%t_3c_ctr_KS(ispin, 1, 1))
1493 CALL dbt_batched_contract_finalize(ri_data%t_3c_ctr_KS_copy(ispin, 1, 1))
1495 CALL dbt_batched_contract_finalize(ri_data%t_2c_int(ispin, 1))
1496 CALL dbt_batched_contract_finalize(ri_data%t_3c_int_mo(ispin, 1, 1))
1497 CALL dbt_batched_contract_finalize(ri_data%t_3c_ctr_RI(ispin, 1, 1))
1499 CALL dbt_destroy(t_3c_int_mo_1(1, 1))
1500 CALL dbt_destroy(t_3c_int_mo_2(1, 1))
1501 CALL dbt_clear(ri_data%t_3c_int_mo(ispin, 1, 1))
1503 CALL dbt_destroy(mo_coeff_t_split)
1505 CALL dbt_filter(ks_t, ri_data%filter_eps)
1507 CALL dbt_create(ks_matrix(ispin, 1)%matrix, ks_t_mat)
1508 CALL dbt_copy(ks_t, ks_t_mat, move_data=.true.)
1509 CALL dbt_copy_tensor_to_matrix(ks_t_mat, ks_matrix(ispin, 1)%matrix, summation=.true.)
1510 CALL dbt_destroy(ks_t_mat)
1512 DEALLOCATE (mem_end, mem_start, mo_bsizes_2, mem_size, mem_start_block_1, mem_end_block_1, &
1513 mem_start_block_2, mem_end_block_2, batch_ranges_1, batch_ranges_2)
1517 CALL dbt_pgrid_destroy(pgrid_2d)
1518 CALL dbt_destroy(ks_t)
1520 CALL para_env%sync()
1523 ri_data%dbcsr_time = ri_data%dbcsr_time + t2 - t1
1525 CALL timestop(handle)
1542 SUBROUTINE hfx_ri_update_ks_pmat(qs_env, ri_data, ks_matrix, rho_ao, &
1543 geometry_did_change, nspins, fac)
1546 TYPE(
dbcsr_p_type),
DIMENSION(:, :) :: ks_matrix, rho_ao
1547 LOGICAL,
INTENT(IN) :: geometry_did_change
1548 INTEGER,
INTENT(IN) :: nspins
1549 REAL(
dp),
INTENT(IN) ::
fac
1551 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_update_ks_Pmat'
1553 INTEGER :: handle, handle2, i_mem, ispin, j_mem, &
1554 n_mem, n_mem_ri, unit_nr, unit_nr_dbcsr
1555 INTEGER(int_8) :: flops_ks_max, flops_p_max, nblks, nflop, &
1556 nze, nze_3c, nze_3c_1, nze_3c_2, &
1558 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: batch_ranges_ao, batch_ranges_ri, dist1, &
1560 INTEGER,
DIMENSION(2, 1) :: bounds_i
1561 INTEGER,
DIMENSION(2, 2) :: bounds_ij, bounds_j
1562 INTEGER,
DIMENSION(3) :: dims_3c
1563 REAL(
dp) :: memory_3c, occ, occ_3c, occ_3c_1, &
1564 occ_3c_2, occ_ks, occ_rho, t1, t2, &
1566 TYPE(dbt_type) :: ks_t, ks_tmp, rho_ao_tmp, t_3c_1, &
1570 IF (.NOT.
fac > epsilon(0.0_dp))
RETURN
1572 CALL timeset(routinen, handle)
1577 unit_nr_dbcsr = ri_data%unit_nr_dbcsr
1578 unit_nr = ri_data%unit_nr
1582 cpassert(
SIZE(ks_matrix, 2) == 1)
1584 IF (geometry_did_change)
THEN
1585 CALL hfx_ri_pre_scf_pmat(qs_env, ri_data)
1586 DO ispin = 1, nspins
1587 CALL dbt_scale(ri_data%rho_ao_t(ispin, 1), 0.0_dp)
1588 CALL dbt_scale(ri_data%ks_t(ispin, 1), 0.0_dp)
1592 nblks = dbt_get_num_blocks_total(ri_data%t_3c_int_ctr_2(1, 1))
1593 IF (nblks == 0)
THEN
1594 cpabort(
"3-center integrals are not available (first call requires geometry_did_change=.TRUE.)")
1597 n_mem = ri_data%n_mem
1598 n_mem_ri = ri_data%n_mem_RI
1600 CALL dbt_create(ks_matrix(1, 1)%matrix, ks_tmp)
1601 CALL dbt_create(rho_ao(1, 1)%matrix, rho_ao_tmp)
1604 ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
1606 DEALLOCATE (dist1, dist2)
1608 CALL dbt_create(ri_data%t_3c_int_ctr_2(1, 1), t_3c_1)
1609 CALL dbt_create(ri_data%t_3c_int_ctr_1(1, 1), t_3c_3)
1611 CALL para_env%sync()
1614 flops_ks_max = 0; flops_p_max = 0
1616 ALLOCATE (batch_ranges_ri(ri_data%n_mem_RI + 1))
1617 ALLOCATE (batch_ranges_ao(ri_data%n_mem + 1))
1618 batch_ranges_ri(:ri_data%n_mem_RI) = ri_data%starts_array_RI_mem_block(:)
1619 batch_ranges_ri(ri_data%n_mem_RI + 1) = ri_data%ends_array_RI_mem_block(ri_data%n_mem_RI) + 1
1620 batch_ranges_ao(:ri_data%n_mem) = ri_data%starts_array_mem_block(:)
1621 batch_ranges_ao(ri_data%n_mem + 1) = ri_data%ends_array_mem_block(ri_data%n_mem) + 1
1624 DO ispin = 1, nspins
1635 CALL dbt_copy_matrix_to_tensor(rho_ao(ispin, 1)%matrix, rho_ao_tmp)
1638 CALL dbt_scale(ri_data%rho_ao_t(ispin, 1), -1.0_dp)
1639 CALL dbt_copy(rho_ao_tmp, ri_data%rho_ao_t(ispin, 1), summation=.true., move_data=.true.)
1643 CALL dbt_batched_contract_init(ri_data%t_3c_int_ctr_1(1, 1), batch_range_1=batch_ranges_ao, &
1644 batch_range_2=batch_ranges_ri)
1645 CALL dbt_batched_contract_init(t_3c_3, batch_range_1=batch_ranges_ao, batch_range_2=batch_ranges_ri)
1647 CALL dbt_create(ri_data%t_3c_int_ctr_1(1, 1), tensor_old)
1651 CALL dbt_batched_contract_init(ri_data%rho_ao_t(ispin, 1))
1652 CALL dbt_batched_contract_init(ri_data%t_3c_int_ctr_2(1, 1), batch_range_2=batch_ranges_ri, &
1653 batch_range_3=batch_ranges_ao)
1654 CALL dbt_batched_contract_init(t_3c_1, batch_range_2=batch_ranges_ri, batch_range_3=batch_ranges_ao)
1655 DO j_mem = 1, n_mem_ri
1657 CALL timeset(routinen//
"_Px3C", handle2)
1659 CALL dbt_get_info(t_3c_1, nfull_total=dims_3c)
1660 bounds_i(:, 1) = [ri_data%starts_array_mem(i_mem), ri_data%ends_array_mem(i_mem)]
1661 bounds_j(:, 1) = [1, dims_3c(1)]
1662 bounds_j(:, 2) = [ri_data%starts_array_RI_mem(j_mem), ri_data%ends_array_RI_mem(j_mem)]
1664 CALL dbt_contract(1.0_dp, ri_data%rho_ao_t(ispin, 1), ri_data%t_3c_int_ctr_2(1, 1), &
1666 contract_1=[2], notcontract_1=[1], &
1667 contract_2=[3], notcontract_2=[1, 2], &
1668 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
1669 bounds_2=bounds_i, &
1670 bounds_3=bounds_j, &
1671 unit_nr=unit_nr_dbcsr, &
1674 CALL timestop(handle2)
1676 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
1679 nze_3c_1 = nze_3c_1 + nze
1680 occ_3c_1 = occ_3c_1 + occ
1682 CALL timeset(routinen//
"_copy_2", handle2)
1683 CALL dbt_copy(t_3c_1, t_3c_3, order=[3, 2, 1], move_data=.true.)
1684 CALL timestop(handle2)
1686 bounds_ij(:, 1) = [ri_data%starts_array_mem(i_mem), ri_data%ends_array_mem(i_mem)]
1687 bounds_ij(:, 2) = [ri_data%starts_array_RI_mem(j_mem), ri_data%ends_array_RI_mem(j_mem)]
1690 ri_data%store_3c(i_mem, j_mem), ri_data%filter_eps_storage)
1692 CALL dbt_copy(tensor_old, ri_data%t_3c_int_ctr_1(1, 1), move_data=.true.)
1695 nze_3c_2 = nze_3c_2 + nze
1696 occ_3c_2 = occ_3c_2 + occ
1697 CALL timeset(routinen//
"_KS", handle2)
1698 CALL dbt_batched_contract_init(ks_t)
1699 CALL dbt_contract(-
fac, ri_data%t_3c_int_ctr_1(1, 1), t_3c_3, &
1701 contract_1=[1, 2], notcontract_1=[3], &
1702 contract_2=[1, 2], notcontract_2=[3], &
1703 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps/n_mem, &
1704 bounds_1=bounds_ij, &
1705 unit_nr=unit_nr_dbcsr, &
1706 flop=nflop, move_data=.true.)
1708 CALL dbt_batched_contract_finalize(ks_t, unit_nr=unit_nr_dbcsr)
1709 CALL timestop(handle2)
1711 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
1714 CALL dbt_batched_contract_finalize(ri_data%rho_ao_t(ispin, 1), unit_nr=unit_nr_dbcsr)
1715 CALL dbt_batched_contract_finalize(ri_data%t_3c_int_ctr_2(1, 1))
1716 CALL dbt_batched_contract_finalize(t_3c_1)
1718 CALL dbt_batched_contract_finalize(ri_data%t_3c_int_ctr_1(1, 1))
1719 CALL dbt_batched_contract_finalize(t_3c_3)
1722 DO j_mem = 1, n_mem_ri
1723 associate(blk_indices => ri_data%blk_indices(i_mem, j_mem), t_3c => ri_data%t_3c_int_ctr_1(1, 1))
1725 ri_data%store_3c(i_mem, j_mem), ri_data%filter_eps_storage)
1726 CALL dbt_copy(tensor_old, t_3c, move_data=.true.)
1729 CALL compress_tensor(t_3c, blk_indices%ind, ri_data%store_3c(i_mem, j_mem), &
1730 ri_data%filter_eps_storage, unused)
1735 CALL dbt_destroy(tensor_old)
1740 CALL dbt_copy_matrix_to_tensor(rho_ao(ispin, 1)%matrix, rho_ao_tmp)
1741 CALL dbt_copy(rho_ao_tmp, ri_data%rho_ao_t(ispin, 1), move_data=.true.)
1742 CALL dbt_copy(ks_t, ri_data%ks_t(ispin, 1), summation=.true., move_data=.true.)
1744 CALL dbt_copy(ri_data%ks_t(ispin, 1), ks_tmp)
1745 CALL dbt_copy_tensor_to_matrix(ks_tmp, ks_matrix(ispin, 1)%matrix, summation=.true.)
1746 CALL dbt_clear(ks_tmp)
1748 IF (unit_nr > 0 .AND. geometry_did_change)
THEN
1749 WRITE (unit_nr,
'(T6,A,T63,ES7.1,1X,A1,1X,F7.3,A1)') &
1750 'Occupancy of density matrix P:', real(nze_rho,
dp),
'/', occ_rho*100,
'%'
1751 WRITE (unit_nr,
'(T6,A,T63,ES7.1,1X,A1,1X,F7.3,A1)') &
1752 'Occupancy of 3c ints:', real(nze_3c,
dp),
'/', occ_3c*100,
'%'
1753 WRITE (unit_nr,
'(T6,A,T63,ES7.1,1X,A1,1X,F7.3,A1)') &
1754 'Occupancy after contraction with K:', real(nze_3c_2,
dp),
'/', occ_3c_2*100,
'%'
1755 WRITE (unit_nr,
'(T6,A,T63,ES7.1,1X,A1,1X,F7.3,A1)') &
1756 'Occupancy after contraction with P:', real(nze_3c_1,
dp),
'/', occ_3c_1*100,
'%'
1757 WRITE (unit_nr,
'(T6,A,T63,ES7.1,1X,A1,1X,F7.3,A1)') &
1758 'Occupancy of Kohn-Sham matrix:', real(nze_ks,
dp),
'/', occ_ks*100,
'%'
1763 CALL para_env%sync()
1766 ri_data%dbcsr_time = ri_data%dbcsr_time + t2 - t1
1768 CALL dbt_destroy(t_3c_1)
1769 CALL dbt_destroy(t_3c_3)
1771 CALL dbt_destroy(rho_ao_tmp)
1772 CALL dbt_destroy(ks_t)
1773 CALL dbt_destroy(ks_tmp)
1775 CALL timestop(handle)
1789 SUBROUTINE hfx_ri_forces_mo(qs_env, ri_data, nspins, hf_fraction, mo_coeff, use_virial)
1791 TYPE(qs_environment_type),
POINTER :: qs_env
1792 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
1793 INTEGER,
INTENT(IN) :: nspins
1794 REAL(dp),
INTENT(IN) :: hf_fraction
1795 TYPE(dbcsr_type),
DIMENSION(:),
INTENT(IN) :: mo_coeff
1796 LOGICAL,
INTENT(IN),
OPTIONAL :: use_virial
1798 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_forces_mo'
1800 INTEGER :: dummy_int, handle, i_mem, i_xyz, ibasis, ispin, j_mem, k_mem, n_mem, n_mem_input, &
1801 n_mem_input_ri, n_mem_ri, n_mem_ri_fit, n_mos, natom, nkind, unit_nr_dbcsr
1802 INTEGER(int_8) :: nflop
1803 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_of_kind, batch_blk_end, batch_blk_start, &
1804 batch_end, batch_end_ri, batch_end_ri_fit, batch_ranges, batch_ranges_ri, &
1805 batch_ranges_ri_fit, batch_start, batch_start_ri, batch_start_ri_fit, bsizes_mo, dist1, &
1806 dist2, dist3, idx_to_at_ao, idx_to_at_ri, kind_of
1807 INTEGER,
DIMENSION(2, 1) :: bounds_ctr_1d
1808 INTEGER,
DIMENSION(2, 2) :: bounds_ctr_2d
1809 INTEGER,
DIMENSION(3) :: pdims
1810 LOGICAL :: use_virial_prv
1811 REAL(dp) :: pref, spin_fac, t1, t2
1812 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
1813 TYPE(block_ind_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_der_ao_ind, t_3c_der_ri_ind
1814 TYPE(cell_type),
POINTER :: cell
1815 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s
1816 TYPE(dbt_pgrid_type) :: pgrid_1, pgrid_2
1817 TYPE(dbt_type) :: t_2c_ri, t_2c_ri_inv, t_2c_ri_met, t_2c_ri_pq, t_2c_tmp, t_3c_0, t_3c_1, &
1818 t_3c_2, t_3c_3, t_3c_4, t_3c_5, t_3c_6, t_3c_ao_ri_ao, t_3c_ao_ri_mo, t_3c_desymm, &
1819 t_3c_mo_ri_ao, t_3c_mo_ri_mo, t_3c_ri_ao_ao, t_3c_ri_ctr, t_3c_ri_mo_mo, &
1820 t_3c_ri_mo_mo_fit, t_3c_work, t_mo_coeff, t_mo_cpy
1821 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:) :: t_2c_der_metric, t_2c_der_ri, t_2c_mo_ao, &
1822 t_2c_mo_ao_ctr, t_3c_der_ao, t_3c_der_ao_ctr_1, t_3c_der_ri, t_3c_der_ri_ctr_1, &
1824 TYPE(dft_control_type),
POINTER :: dft_control
1825 TYPE(gto_basis_set_p_type),
ALLOCATABLE, &
1826 DIMENSION(:),
TARGET :: basis_set_ao, basis_set_ri
1827 TYPE(gto_basis_set_type),
POINTER :: orb_basis, ri_basis
1828 TYPE(hfx_compression_type),
ALLOCATABLE, &
1829 DIMENSION(:, :) :: t_3c_der_ao_comp, t_3c_der_ri_comp
1830 TYPE(mp_para_env_type),
POINTER :: para_env
1831 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
1832 TYPE(qs_force_type),
DIMENSION(:),
POINTER :: force
1833 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
1844 use_virial_prv = .false.
1845 IF (
PRESENT(use_virial)) use_virial_prv = use_virial
1846 IF (use_virial_prv)
THEN
1847 cpabort(
"Stress tensor with RI-HFX MO flavor not implemented.")
1850 unit_nr_dbcsr = ri_data%unit_nr_dbcsr
1852 CALL get_qs_env(qs_env, natom=natom, particle_set=particle_set, nkind=nkind, &
1853 atomic_kind_set=atomic_kind_set, cell=cell, force=force, &
1854 matrix_s=matrix_s, para_env=para_env, dft_control=dft_control, &
1855 qs_kind_set=qs_kind_set)
1858 CALL dbt_pgrid_create(para_env, pdims, pgrid_1, tensor_dims=[
SIZE(ri_data%bsizes_AO_split), &
1859 SIZE(ri_data%bsizes_RI_split), &
1860 SIZE(ri_data%bsizes_AO_split)])
1862 CALL dbt_pgrid_create(para_env, pdims, pgrid_2, tensor_dims=[
SIZE(ri_data%bsizes_RI_split), &
1863 SIZE(ri_data%bsizes_AO_split), &
1864 SIZE(ri_data%bsizes_AO_split)])
1866 CALL create_3c_tensor(t_3c_ao_ri_ao, dist1, dist2, dist3, pgrid_1, &
1867 ri_data%bsizes_AO_split, ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, &
1868 [1, 2], [3], name=
"(AO RI | AO)")
1869 DEALLOCATE (dist1, dist2, dist3)
1870 CALL create_3c_tensor(t_3c_ri_ao_ao, dist1, dist2, dist3, pgrid_2, &
1871 ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
1872 [1], [2, 3], name=
"(RI | AO AO)")
1873 DEALLOCATE (dist1, dist2, dist3)
1875 ALLOCATE (basis_set_ri(nkind), basis_set_ao(nkind))
1876 CALL basis_set_list_setup(basis_set_ri, ri_data%ri_basis_type, qs_kind_set)
1877 CALL get_particle_set(particle_set, qs_kind_set, basis=basis_set_ri)
1878 CALL basis_set_list_setup(basis_set_ao, ri_data%orb_basis_type, qs_kind_set)
1879 CALL get_particle_set(particle_set, qs_kind_set, basis=basis_set_ao)
1881 DO ibasis = 1,
SIZE(basis_set_ao)
1882 orb_basis => basis_set_ao(ibasis)%gto_basis_set
1883 CALL init_interaction_radii_orb_basis(orb_basis, ri_data%eps_pgf_orb)
1884 ri_basis => basis_set_ri(ibasis)%gto_basis_set
1885 CALL init_interaction_radii_orb_basis(ri_basis, ri_data%eps_pgf_orb)
1888 ALLOCATE (t_2c_der_metric(3), t_2c_der_ri(3), t_2c_mo_ao(3), t_2c_mo_ao_ctr(3), t_3c_der_ao(3), &
1889 t_3c_der_ao_ctr_1(3), t_3c_der_ri(3), t_3c_der_ri_ctr_1(3), t_3c_der_ri_ctr_2(3))
1892 CALL precalc_derivatives(t_3c_der_ri_comp, t_3c_der_ao_comp, t_3c_der_ri_ind, t_3c_der_ao_ind, &
1893 t_2c_der_ri, t_2c_der_metric, t_3c_ri_ao_ao, &
1894 basis_set_ao, basis_set_ri, ri_data, qs_env)
1896 DO ibasis = 1,
SIZE(basis_set_ao)
1897 orb_basis => basis_set_ao(ibasis)%gto_basis_set
1898 ri_basis => basis_set_ri(ibasis)%gto_basis_set
1899 CALL init_interaction_radii_orb_basis(orb_basis, dft_control%qs_control%eps_pgf_orb)
1900 CALL init_interaction_radii_orb_basis(ri_basis, dft_control%qs_control%eps_pgf_orb)
1903 n_mem =
SIZE(t_3c_der_ri_comp, 1)
1905 CALL dbt_create(t_3c_ao_ri_ao, t_3c_der_ri(i_xyz))
1906 CALL dbt_create(t_3c_ao_ri_ao, t_3c_der_ao(i_xyz))
1909 CALL decompress_tensor(t_3c_ri_ao_ao, t_3c_der_ri_ind(i_mem, i_xyz)%ind, &
1910 t_3c_der_ri_comp(i_mem, i_xyz), ri_data%filter_eps_storage)
1911 CALL dbt_copy(t_3c_ri_ao_ao, t_3c_der_ri(i_xyz), order=[2, 1, 3], move_data=.true., summation=.true.)
1913 CALL decompress_tensor(t_3c_ri_ao_ao, t_3c_der_ao_ind(i_mem, i_xyz)%ind, &
1914 t_3c_der_ao_comp(i_mem, i_xyz), ri_data%filter_eps_storage)
1915 CALL dbt_copy(t_3c_ri_ao_ao, t_3c_der_ao(i_xyz), order=[2, 1, 3], move_data=.true., summation=.true.)
1921 CALL dealloc_containers(t_3c_der_ao_comp(i_mem, i_xyz), dummy_int)
1922 CALL dealloc_containers(t_3c_der_ri_comp(i_mem, i_xyz), dummy_int)
1925 DEALLOCATE (t_3c_der_ao_ind, t_3c_der_ri_ind)
1928 CALL dbt_create(t_3c_ao_ri_ao, t_3c_desymm)
1929 CALL dbt_copy(ri_data%t_3c_int_ctr_1(1, 1), t_3c_desymm)
1930 CALL dbt_copy(ri_data%t_3c_int_ctr_1(1, 1), t_3c_desymm, order=[3, 2, 1], &
1931 summation=.true., move_data=.true.)
1933 CALL dbt_destroy(t_3c_ao_ri_ao)
1934 CALL dbt_destroy(t_3c_ri_ao_ao)
1938 IF (nspins == 2) spin_fac = 1.0_dp
1940 ALLOCATE (idx_to_at_ri(
SIZE(ri_data%bsizes_RI_split)))
1941 CALL get_idx_to_atom(idx_to_at_ri, ri_data%bsizes_RI_split, ri_data%bsizes_RI)
1943 ALLOCATE (idx_to_at_ao(
SIZE(ri_data%bsizes_AO_split)))
1944 CALL get_idx_to_atom(idx_to_at_ao, ri_data%bsizes_AO_split, ri_data%bsizes_AO)
1946 CALL get_atomic_kind_set(atomic_kind_set, kind_of=kind_of, atom_of_kind=atom_of_kind)
1949 CALL create_2c_tensor(t_2c_ri, dist1, dist2, ri_data%pgrid_2d, &
1950 ri_data%bsizes_RI_split, ri_data%bsizes_RI_split, name=
"(RI | RI)")
1951 DEALLOCATE (dist1, dist2)
1953 CALL create_2c_tensor(t_2c_ri_pq, dist1, dist2, ri_data%pgrid_2d, &
1954 ri_data%bsizes_RI_fit, ri_data%bsizes_RI_fit, name=
"(RI | RI)")
1955 DEALLOCATE (dist1, dist2)
1957 IF (.NOT. ri_data%same_op)
THEN
1959 CALL dbt_create(t_2c_ri_pq, t_2c_ri_inv)
1960 CALL dbt_create(t_2c_ri_pq, t_2c_ri_met)
1961 CALL dbt_create(ri_data%t_2c_inv(1, 1), t_2c_tmp)
1963 CALL dbt_contract(1.0_dp, ri_data%t_2c_inv(1, 1), ri_data%t_2c_pot(1, 1), &
1965 contract_1=[2], notcontract_1=[1], &
1966 contract_2=[1], notcontract_2=[2], &
1967 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
1968 unit_nr=unit_nr_dbcsr, flop=nflop)
1969 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
1971 CALL dbt_copy(t_2c_tmp, t_2c_ri_inv, move_data=.true.)
1972 CALL dbt_destroy(t_2c_tmp)
1977 n_mem_input = floor((ri_data%n_mem_input - 0.1_dp)**(1._dp/3._dp)) + 1
1978 n_mem_input_ri = floor((ri_data%n_mem_input - 0.1_dp)/n_mem_input**2) + 1
1981 n_mem_ri = n_mem_input_ri
1982 CALL create_tensor_batches(ri_data%bsizes_RI_split, n_mem_ri, batch_start_ri, batch_end_ri, &
1983 batch_blk_start, batch_blk_end)
1984 ALLOCATE (batch_ranges_ri(n_mem_ri + 1))
1985 batch_ranges_ri(1:n_mem_ri) = batch_blk_start(1:n_mem_ri)
1986 batch_ranges_ri(n_mem_ri + 1) = batch_blk_end(n_mem_ri) + 1
1987 DEALLOCATE (batch_blk_start, batch_blk_end)
1989 n_mem_ri_fit = n_mem_input_ri
1990 CALL create_tensor_batches(ri_data%bsizes_RI_fit, n_mem_ri_fit, batch_start_ri_fit, batch_end_ri_fit, &
1991 batch_blk_start, batch_blk_end)
1992 ALLOCATE (batch_ranges_ri_fit(n_mem_ri_fit + 1))
1993 batch_ranges_ri_fit(1:n_mem_ri_fit) = batch_blk_start(1:n_mem_ri_fit)
1994 batch_ranges_ri_fit(n_mem_ri_fit + 1) = batch_blk_end(n_mem_ri_fit) + 1
1995 DEALLOCATE (batch_blk_start, batch_blk_end)
1997 DO ispin = 1, nspins
2000 CALL dbcsr_get_info(mo_coeff(ispin), nfullcols_total=n_mos)
2002 CALL split_block_sizes([n_mos], bsizes_mo, max_size=floor(sqrt(ri_data%max_bsize_MO - 0.1)) + 1)
2006 CALL create_tensor_batches(bsizes_mo, n_mem, batch_start, batch_end, &
2007 batch_blk_start, batch_blk_end)
2008 ALLOCATE (batch_ranges(n_mem + 1))
2009 batch_ranges(1:n_mem) = batch_blk_start(1:n_mem)
2010 batch_ranges(n_mem + 1) = batch_blk_end(n_mem) + 1
2011 DEALLOCATE (batch_blk_start, batch_blk_end)
2014 CALL create_2c_tensor(t_mo_coeff, dist1, dist2, ri_data%pgrid_2d, bsizes_mo, &
2015 ri_data%bsizes_AO_split, name=
"MO coeffs")
2016 DEALLOCATE (dist1, dist2)
2017 CALL dbt_create(mo_coeff(ispin), t_2c_tmp, name=
"MO coeffs")
2018 CALL dbt_copy_matrix_to_tensor(mo_coeff(ispin), t_2c_tmp)
2019 CALL dbt_copy(t_2c_tmp, t_mo_coeff, order=[2, 1], move_data=.true.)
2020 CALL dbt_destroy(t_2c_tmp)
2022 CALL dbt_create(t_mo_coeff, t_mo_cpy)
2023 CALL dbt_copy(t_mo_coeff, t_mo_cpy)
2025 CALL dbt_create(t_mo_coeff, t_2c_mo_ao_ctr(i_xyz))
2026 CALL dbt_create(t_mo_coeff, t_2c_mo_ao(i_xyz))
2029 CALL create_3c_tensor(t_3c_ao_ri_mo, dist1, dist2, dist3, pgrid_1, ri_data%bsizes_AO_split, &
2030 ri_data%bsizes_RI_split, bsizes_mo, [1, 2], [3], name=
"(AO RI| MO)")
2031 DEALLOCATE (dist1, dist2, dist3)
2033 CALL dbt_create(t_3c_ao_ri_mo, t_3c_0)
2034 CALL dbt_destroy(t_3c_ao_ri_mo)
2036 CALL create_3c_tensor(t_3c_mo_ri_ao, dist1, dist2, dist3, pgrid_1, bsizes_mo, ri_data%bsizes_RI_split, &
2037 ri_data%bsizes_AO_split, [1, 2], [3], name=
"(MO RI | AO)")
2038 DEALLOCATE (dist1, dist2, dist3)
2039 CALL dbt_create(t_3c_mo_ri_ao, t_3c_1)
2042 CALL dbt_create(t_3c_mo_ri_ao, t_3c_der_ri_ctr_1(i_xyz))
2043 CALL dbt_create(t_3c_mo_ri_ao, t_3c_der_ao_ctr_1(i_xyz))
2046 CALL create_3c_tensor(t_3c_mo_ri_mo, dist1, dist2, dist3, pgrid_1, bsizes_mo, &
2047 ri_data%bsizes_RI_split, bsizes_mo, [1, 2], [3], name=
"(MO RI | MO)")
2048 DEALLOCATE (dist1, dist2, dist3)
2049 CALL dbt_create(t_3c_mo_ri_mo, t_3c_work)
2051 CALL create_3c_tensor(t_3c_ri_mo_mo, dist1, dist2, dist3, pgrid_2, ri_data%bsizes_RI_split, &
2052 bsizes_mo, bsizes_mo, [1], [2, 3], name=
"(RI| MO MO)")
2053 DEALLOCATE (dist1, dist2, dist3)
2055 CALL dbt_create(t_3c_ri_mo_mo, t_3c_2)
2056 CALL dbt_create(t_3c_ri_mo_mo, t_3c_3)
2057 CALL dbt_create(t_3c_ri_mo_mo, t_3c_ri_ctr)
2059 CALL dbt_create(t_3c_ri_mo_mo, t_3c_der_ri_ctr_2(i_xyz))
2064 CALL create_3c_tensor(t_3c_ri_mo_mo_fit, dist1, dist2, dist3, pgrid_2, ri_data%bsizes_RI_fit, &
2065 bsizes_mo, bsizes_mo, [1], [2, 3], name=
"(RI| MO MO)")
2066 DEALLOCATE (dist1, dist2, dist3)
2068 CALL dbt_create(t_3c_ri_mo_mo_fit, t_3c_4)
2069 CALL dbt_create(t_3c_ri_mo_mo_fit, t_3c_5)
2070 CALL dbt_create(t_3c_ri_mo_mo_fit, t_3c_6)
2072 CALL dbt_batched_contract_init(t_3c_desymm, batch_range_2=batch_ranges_ri)
2073 CALL dbt_batched_contract_init(t_3c_0, batch_range_2=batch_ranges_ri, batch_range_3=batch_ranges)
2076 CALL dbt_batched_contract_init(t_3c_der_ao(i_xyz), batch_range_2=batch_ranges_ri)
2077 CALL dbt_batched_contract_init(t_3c_der_ri(i_xyz), batch_range_2=batch_ranges_ri)
2080 CALL para_env%sync()
2086 bounds_ctr_1d(1, 1) = batch_start(i_mem)
2087 bounds_ctr_1d(2, 1) = batch_end(i_mem)
2089 bounds_ctr_2d(1, 1) = 1
2090 bounds_ctr_2d(2, 1) = sum(ri_data%bsizes_AO)
2093 CALL timeset(routinen//
"_AO2MO_1", handle)
2094 CALL dbt_batched_contract_init(t_mo_coeff)
2095 DO k_mem = 1, n_mem_ri
2096 bounds_ctr_2d(1, 2) = batch_start_ri(k_mem)
2097 bounds_ctr_2d(2, 2) = batch_end_ri(k_mem)
2099 CALL dbt_contract(1.0_dp, t_mo_coeff, t_3c_desymm, &
2101 contract_1=[2], notcontract_1=[1], &
2102 contract_2=[3], notcontract_2=[1, 2], &
2103 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
2104 bounds_2=bounds_ctr_1d, &
2105 bounds_3=bounds_ctr_2d, &
2106 unit_nr=unit_nr_dbcsr, flop=nflop)
2107 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2109 CALL dbt_copy(t_3c_0, t_3c_1, order=[3, 2, 1], move_data=.true.)
2112 DO k_mem = 1, n_mem_ri
2113 bounds_ctr_2d(1, 2) = batch_start_ri(k_mem)
2114 bounds_ctr_2d(2, 2) = batch_end_ri(k_mem)
2116 CALL dbt_contract(1.0_dp, t_mo_coeff, t_3c_der_ao(i_xyz), &
2118 contract_1=[2], notcontract_1=[1], &
2119 contract_2=[3], notcontract_2=[1, 2], &
2120 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
2121 bounds_2=bounds_ctr_1d, &
2122 bounds_3=bounds_ctr_2d, &
2123 unit_nr=unit_nr_dbcsr, flop=nflop)
2124 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2126 CALL dbt_copy(t_3c_0, t_3c_der_ao_ctr_1(i_xyz), order=[3, 2, 1], move_data=.true.)
2128 DO k_mem = 1, n_mem_ri
2129 bounds_ctr_2d(1, 2) = batch_start_ri(k_mem)
2130 bounds_ctr_2d(2, 2) = batch_end_ri(k_mem)
2132 CALL dbt_contract(1.0_dp, t_mo_coeff, t_3c_der_ri(i_xyz), &
2134 contract_1=[2], notcontract_1=[1], &
2135 contract_2=[3], notcontract_2=[1, 2], &
2136 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
2137 bounds_2=bounds_ctr_1d, &
2138 bounds_3=bounds_ctr_2d, &
2139 unit_nr=unit_nr_dbcsr, flop=nflop)
2140 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2142 CALL dbt_copy(t_3c_0, t_3c_der_ri_ctr_1(i_xyz), order=[3, 2, 1], move_data=.true.)
2144 CALL dbt_batched_contract_finalize(t_mo_coeff)
2145 CALL timestop(handle)
2147 CALL dbt_batched_contract_init(t_3c_1, batch_range_1=batch_ranges, batch_range_2=batch_ranges_ri)
2148 CALL dbt_batched_contract_init(t_3c_work, batch_range_1=batch_ranges, batch_range_2=batch_ranges_ri, &
2149 batch_range_3=batch_ranges)
2150 CALL dbt_batched_contract_init(t_3c_2, batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2151 CALL dbt_batched_contract_init(t_3c_3, batch_range_1=batch_ranges_ri, &
2152 batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2154 CALL dbt_batched_contract_init(t_3c_4, batch_range_1=batch_ranges_ri_fit, &
2155 batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2156 CALL dbt_batched_contract_init(t_3c_5, batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2159 CALL dbt_batched_contract_init(t_3c_der_ri_ctr_1(i_xyz), batch_range_1=batch_ranges, &
2160 batch_range_2=batch_ranges_ri)
2161 CALL dbt_batched_contract_init(t_3c_der_ao_ctr_1(i_xyz), batch_range_1=batch_ranges, &
2162 batch_range_2=batch_ranges_ri)
2166 IF (.NOT. ri_data%same_op)
THEN
2167 CALL dbt_batched_contract_init(t_3c_6, batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2172 bounds_ctr_1d(1, 1) = batch_start(j_mem)
2173 bounds_ctr_1d(2, 1) = batch_end(j_mem)
2175 bounds_ctr_2d(1, 1) = batch_start(i_mem)
2176 bounds_ctr_2d(2, 1) = batch_end(i_mem)
2179 CALL timeset(routinen//
"_AO2MO_2", handle)
2180 CALL dbt_batched_contract_init(t_mo_coeff)
2181 DO k_mem = 1, n_mem_ri
2182 bounds_ctr_2d(1, 2) = batch_start_ri(k_mem)
2183 bounds_ctr_2d(2, 2) = batch_end_ri(k_mem)
2185 CALL dbt_contract(1.0_dp, t_mo_coeff, t_3c_1, &
2186 1.0_dp, t_3c_work, &
2187 contract_1=[2], notcontract_1=[1], &
2188 contract_2=[3], notcontract_2=[1, 2], &
2189 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
2190 bounds_2=bounds_ctr_1d, &
2191 bounds_3=bounds_ctr_2d, &
2192 unit_nr=unit_nr_dbcsr, flop=nflop)
2193 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2195 CALL dbt_batched_contract_finalize(t_mo_coeff)
2196 CALL timestop(handle)
2198 bounds_ctr_2d(1, 1) = batch_start(i_mem)
2199 bounds_ctr_2d(2, 1) = batch_end(i_mem)
2200 bounds_ctr_2d(1, 2) = batch_start(j_mem)
2201 bounds_ctr_2d(2, 2) = batch_end(j_mem)
2204 CALL timeset(routinen//
"_2c_inv", handle)
2205 CALL dbt_copy(t_3c_work, t_3c_3, order=[2, 1, 3], move_data=.true.)
2206 DO k_mem = 1, n_mem_ri
2207 bounds_ctr_1d(1, 1) = batch_start_ri(k_mem)
2208 bounds_ctr_1d(2, 1) = batch_end_ri(k_mem)
2210 CALL dbt_batched_contract_init(ri_data%t_2c_inv(1, 1))
2211 CALL dbt_contract(1.0_dp, ri_data%t_2c_inv(1, 1), t_3c_3, &
2213 contract_1=[2], notcontract_1=[1], &
2214 contract_2=[1], notcontract_2=[2, 3], &
2215 map_1=[1], map_2=[2, 3], filter_eps=ri_data%filter_eps, &
2216 bounds_1=bounds_ctr_1d, &
2217 bounds_3=bounds_ctr_2d, &
2218 unit_nr=unit_nr_dbcsr, flop=nflop)
2219 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2220 CALL dbt_batched_contract_finalize(ri_data%t_2c_inv(1, 1))
2222 CALL dbt_copy(t_3c_ri_mo_mo, t_3c_3)
2223 CALL timestop(handle)
2226 bounds_ctr_1d(1, 1) = batch_start(j_mem)
2227 bounds_ctr_1d(2, 1) = batch_end(j_mem)
2229 bounds_ctr_2d(1, 1) = batch_start(i_mem)
2230 bounds_ctr_2d(2, 1) = batch_end(i_mem)
2232 CALL timeset(routinen//
"_AO2MO_2", handle)
2233 CALL dbt_batched_contract_init(t_mo_coeff)
2235 DO k_mem = 1, n_mem_ri
2236 bounds_ctr_2d(1, 2) = batch_start_ri(k_mem)
2237 bounds_ctr_2d(2, 2) = batch_end_ri(k_mem)
2239 CALL dbt_contract(1.0_dp, t_mo_coeff, t_3c_der_ri_ctr_1(i_xyz), &
2240 1.0_dp, t_3c_work, &
2241 contract_1=[2], notcontract_1=[1], &
2242 contract_2=[3], notcontract_2=[1, 2], &
2243 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
2244 bounds_2=bounds_ctr_1d, &
2245 bounds_3=bounds_ctr_2d, &
2246 unit_nr=unit_nr_dbcsr, flop=nflop)
2247 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2249 CALL dbt_copy(t_3c_work, t_3c_der_ri_ctr_2(i_xyz), order=[2, 1, 3], move_data=.true.)
2251 CALL dbt_batched_contract_finalize(t_mo_coeff)
2252 CALL timestop(handle)
2254 bounds_ctr_2d(1, 1) = batch_start(i_mem)
2255 bounds_ctr_2d(2, 1) = batch_end(i_mem)
2256 bounds_ctr_2d(1, 2) = batch_start(j_mem)
2257 bounds_ctr_2d(2, 2) = batch_end(j_mem)
2260 CALL timeset(routinen//
"_PQ_der", handle)
2261 CALL dbt_copy(t_3c_2, t_3c_4, move_data=.true.)
2262 CALL dbt_copy(t_3c_4, t_3c_5)
2263 DO k_mem = 1, n_mem_ri_fit
2264 bounds_ctr_1d(1, 1) = batch_start_ri_fit(k_mem)
2265 bounds_ctr_1d(2, 1) = batch_end_ri_fit(k_mem)
2267 CALL dbt_batched_contract_init(t_2c_ri_pq)
2268 CALL dbt_contract(1.0_dp, t_3c_4, t_3c_5, &
2269 1.0_dp, t_2c_ri_pq, &
2270 contract_1=[2, 3], notcontract_1=[1], &
2271 contract_2=[2, 3], notcontract_2=[1], &
2272 bounds_1=bounds_ctr_2d, &
2273 bounds_2=bounds_ctr_1d, &
2274 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2275 unit_nr=unit_nr_dbcsr, flop=nflop)
2276 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2277 CALL dbt_batched_contract_finalize(t_2c_ri_pq)
2279 CALL timestop(handle)
2282 IF (.NOT. ri_data%same_op)
THEN
2283 CALL timeset(routinen//
"_metric", handle)
2284 DO k_mem = 1, n_mem_ri_fit
2285 bounds_ctr_1d(1, 1) = batch_start_ri_fit(k_mem)
2286 bounds_ctr_1d(2, 1) = batch_end_ri_fit(k_mem)
2288 CALL dbt_batched_contract_init(t_2c_ri_inv)
2289 CALL dbt_contract(1.0_dp, t_2c_ri_inv, t_3c_4, &
2291 contract_1=[2], notcontract_1=[1], &
2292 contract_2=[1], notcontract_2=[2, 3], &
2293 bounds_1=bounds_ctr_1d, &
2294 bounds_3=bounds_ctr_2d, &
2295 map_1=[1], map_2=[2, 3], filter_eps=ri_data%filter_eps, &
2296 unit_nr=unit_nr_dbcsr, flop=nflop)
2297 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2298 CALL dbt_batched_contract_finalize(t_2c_ri_inv)
2300 CALL dbt_copy(t_3c_6, t_3c_4, move_data=.true.)
2303 DO k_mem = 1, n_mem_ri_fit
2304 bounds_ctr_1d(1, 1) = batch_start_ri_fit(k_mem)
2305 bounds_ctr_1d(2, 1) = batch_end_ri_fit(k_mem)
2307 CALL dbt_batched_contract_init(t_2c_ri_met)
2308 CALL dbt_contract(1.0_dp, t_3c_4, t_3c_5, &
2309 1.0_dp, t_2c_ri_met, &
2310 contract_1=[2, 3], notcontract_1=[1], &
2311 contract_2=[2, 3], notcontract_2=[1], &
2312 bounds_1=bounds_ctr_2d, &
2313 bounds_2=bounds_ctr_1d, &
2314 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2315 unit_nr=unit_nr_dbcsr, flop=nflop)
2316 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2317 CALL dbt_batched_contract_finalize(t_2c_ri_met)
2319 CALL timestop(handle)
2321 CALL dbt_copy(t_3c_ri_mo_mo_fit, t_3c_5)
2326 CALL timeset(routinen//
"_3c_RI", handle)
2327 pref = -0.5_dp*2.0_dp*hf_fraction*spin_fac
2328 CALL dbt_copy(t_3c_4, t_3c_ri_ctr, move_data=.true.)
2331 CALL timestop(handle)
2335 bounds_ctr_2d(1, 1) = batch_start(i_mem)
2336 bounds_ctr_2d(2, 1) = batch_end(i_mem)
2338 bounds_ctr_1d(1, 1) = batch_start(j_mem)
2339 bounds_ctr_1d(2, 1) = batch_end(j_mem)
2341 CALL timeset(routinen//
"_3c_AO", handle)
2342 CALL dbt_copy(t_3c_ri_ctr, t_3c_work, order=[2, 1, 3], move_data=.true.)
2345 CALL dbt_batched_contract_init(t_2c_mo_ao_ctr(i_xyz))
2346 DO k_mem = 1, n_mem_ri
2347 bounds_ctr_2d(1, 2) = batch_start_ri(k_mem)
2348 bounds_ctr_2d(2, 2) = batch_end_ri(k_mem)
2350 CALL dbt_contract(1.0_dp, t_3c_work, t_3c_der_ao_ctr_1(i_xyz), &
2351 1.0_dp, t_2c_mo_ao_ctr(i_xyz), &
2352 contract_1=[1, 2], notcontract_1=[3], &
2353 contract_2=[1, 2], notcontract_2=[3], &
2354 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2355 bounds_1=bounds_ctr_2d, &
2356 bounds_2=bounds_ctr_1d, &
2357 unit_nr=unit_nr_dbcsr, flop=nflop)
2358 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2360 CALL dbt_batched_contract_finalize(t_2c_mo_ao_ctr(i_xyz))
2362 CALL timestop(handle)
2365 CALL dbt_batched_contract_finalize(t_3c_1)
2366 CALL dbt_batched_contract_finalize(t_3c_work)
2367 CALL dbt_batched_contract_finalize(t_3c_2)
2368 CALL dbt_batched_contract_finalize(t_3c_3)
2369 CALL dbt_batched_contract_finalize(t_3c_4)
2370 CALL dbt_batched_contract_finalize(t_3c_5)
2373 CALL dbt_batched_contract_finalize(t_3c_der_ri_ctr_1(i_xyz))
2374 CALL dbt_batched_contract_finalize(t_3c_der_ao_ctr_1(i_xyz))
2377 IF (.NOT. ri_data%same_op)
THEN
2378 CALL dbt_batched_contract_finalize(t_3c_6)
2382 CALL dbt_batched_contract_finalize(t_3c_desymm)
2383 CALL dbt_batched_contract_finalize(t_3c_0)
2386 CALL dbt_batched_contract_finalize(t_3c_der_ao(i_xyz))
2387 CALL dbt_batched_contract_finalize(t_3c_der_ri(i_xyz))
2391 pref = -0.5_dp*4.0_dp*hf_fraction*spin_fac
2393 CALL dbt_copy(t_2c_mo_ao_ctr(i_xyz), t_2c_mo_ao(i_xyz), move_data=.true.)
2394 CALL get_mo_ao_force(force, t_mo_cpy, t_2c_mo_ao(i_xyz), atom_of_kind, kind_of, idx_to_at_ao, pref, i_xyz)
2395 CALL dbt_clear(t_2c_mo_ao(i_xyz))
2399 pref = 0.5_dp*hf_fraction*spin_fac
2400 IF (.NOT. ri_data%same_op) pref = -pref
2403 CALL dbt_copy(t_2c_ri_pq, t_2c_ri, move_data=.true.)
2405 kind_of, idx_to_at_ri, pref)
2406 CALL dbt_clear(t_2c_ri)
2409 IF (.NOT. ri_data%same_op)
THEN
2410 pref = 0.5_dp*2.0_dp*hf_fraction*spin_fac
2412 CALL dbt_copy(t_2c_ri_met, t_2c_ri, move_data=.true.)
2414 kind_of, idx_to_at_ri, pref)
2415 CALL dbt_clear(t_2c_ri)
2418 CALL dbt_destroy(t_3c_0)
2419 CALL dbt_destroy(t_3c_1)
2420 CALL dbt_destroy(t_3c_2)
2421 CALL dbt_destroy(t_3c_3)
2422 CALL dbt_destroy(t_3c_4)
2423 CALL dbt_destroy(t_3c_5)
2424 CALL dbt_destroy(t_3c_6)
2425 CALL dbt_destroy(t_3c_work)
2426 CALL dbt_destroy(t_3c_ri_ctr)
2427 CALL dbt_destroy(t_3c_mo_ri_ao)
2428 CALL dbt_destroy(t_3c_mo_ri_mo)
2429 CALL dbt_destroy(t_3c_ri_mo_mo)
2430 CALL dbt_destroy(t_3c_ri_mo_mo_fit)
2431 CALL dbt_destroy(t_mo_coeff)
2432 CALL dbt_destroy(t_mo_cpy)
2434 CALL dbt_destroy(t_2c_mo_ao(i_xyz))
2435 CALL dbt_destroy(t_2c_mo_ao_ctr(i_xyz))
2436 CALL dbt_destroy(t_3c_der_ri_ctr_1(i_xyz))
2437 CALL dbt_destroy(t_3c_der_ao_ctr_1(i_xyz))
2438 CALL dbt_destroy(t_3c_der_ri_ctr_2(i_xyz))
2440 DEALLOCATE (batch_ranges, batch_start, batch_end)
2444 CALL dbt_pgrid_destroy(pgrid_1)
2445 CALL dbt_pgrid_destroy(pgrid_2)
2446 CALL dbt_destroy(t_3c_desymm)
2447 CALL dbt_destroy(t_2c_ri)
2448 CALL dbt_destroy(t_2c_ri_pq)
2449 IF (.NOT. ri_data%same_op)
THEN
2450 CALL dbt_destroy(t_2c_ri_met)
2451 CALL dbt_destroy(t_2c_ri_inv)
2454 CALL dbt_destroy(t_3c_der_ao(i_xyz))
2455 CALL dbt_destroy(t_3c_der_ri(i_xyz))
2456 CALL dbt_destroy(t_2c_der_ri(i_xyz))
2457 IF (.NOT. ri_data%same_op)
CALL dbt_destroy(t_2c_der_metric(i_xyz))
2459 CALL dbt_copy(ri_data%t_3c_int_ctr_2(1, 1), ri_data%t_3c_int_ctr_1(1, 1))
2461 CALL para_env%sync()
2464 ri_data%dbcsr_time = ri_data%dbcsr_time + t2 - t1
2466 END SUBROUTINE hfx_ri_forces_mo
2480 SUBROUTINE hfx_ri_forces_pmat(qs_env, ri_data, nspins, hf_fraction, rho_ao, rho_ao_resp, &
2481 use_virial, resp_only, rescale_factor)
2483 TYPE(qs_environment_type),
POINTER :: qs_env
2484 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
2485 INTEGER,
INTENT(IN) :: nspins
2486 REAL(dp),
INTENT(IN) :: hf_fraction
2487 TYPE(dbcsr_p_type),
DIMENSION(:, :) :: rho_ao
2488 TYPE(dbcsr_p_type),
DIMENSION(:),
OPTIONAL :: rho_ao_resp
2489 LOGICAL,
INTENT(IN),
OPTIONAL :: use_virial, resp_only
2490 REAL(dp),
INTENT(IN),
OPTIONAL :: rescale_factor
2492 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_forces_Pmat'
2494 INTEGER :: dummy_int, handle, i_mem, i_spin, i_xyz, &
2495 ibasis, j_mem, j_xyz, k_mem, k_xyz, &
2496 n_mem, n_mem_ri, natom, nkind, &
2498 INTEGER(int_8) :: nflop
2499 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_of_kind, batch_end, batch_end_ri, batch_ranges, &
2500 batch_ranges_ri, batch_start, batch_start_ri, dist1, dist2, dist3, idx_to_at_ao, &
2501 idx_to_at_ri, kind_of
2502 INTEGER,
DIMENSION(2, 1) :: ibounds, jbounds, kbounds
2503 INTEGER,
DIMENSION(2, 2) :: ijbounds
2504 INTEGER,
DIMENSION(2, 3) :: bounds_cpy
2505 INTEGER,
DIMENSION(:),
POINTER :: col_bsize, row_bsize
2506 LOGICAL :: do_resp, resp_only_prv, use_virial_prv
2507 REAL(dp) :: pref, spin_fac, t1, t2
2508 REAL(dp),
DIMENSION(3, 3) :: work_virial
2509 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
2510 TYPE(block_ind_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_der_ao_ind, t_3c_der_ri_ind
2511 TYPE(cell_type),
POINTER :: cell
2512 TYPE(dbcsr_distribution_type),
POINTER :: dbcsr_dist
2513 TYPE(dbcsr_type) :: dbcsr_tmp, virial_trace
2514 TYPE(dbt_type) :: rho_ao_1, rho_ao_2, t_2c_ri, t_2c_ri_tmp, t_2c_tmp, t_2c_virial, t_3c_1, &
2515 t_3c_2, t_3c_3, t_3c_4, t_3c_5, t_3c_ao_ri_ao, t_3c_help_1, t_3c_help_2, t_3c_int, &
2516 t_3c_int_2, t_3c_ri_ao_ao, t_3c_sparse, t_3c_virial, t_r, t_svs
2517 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:) :: t_2c_der_metric, t_2c_der_ri, &
2518 t_3c_der_ao, t_3c_der_ri
2519 TYPE(dft_control_type),
POINTER :: dft_control
2520 TYPE(gto_basis_set_p_type),
ALLOCATABLE, &
2521 DIMENSION(:),
TARGET :: basis_set_ao, basis_set_ri
2522 TYPE(gto_basis_set_type),
POINTER :: orb_basis, ri_basis
2523 TYPE(hfx_compression_type),
ALLOCATABLE, &
2524 DIMENSION(:, :) :: t_3c_der_ao_comp, t_3c_der_ri_comp
2525 TYPE(mp_para_env_type),
POINTER :: para_env
2526 TYPE(neighbor_list_3c_type) :: nl_3c
2527 TYPE(neighbor_list_set_p_type),
DIMENSION(:), &
2528 POINTER :: nl_2c_met, nl_2c_pot
2529 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
2530 TYPE(qs_force_type),
DIMENSION(:),
POINTER :: force
2531 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2532 TYPE(virial_type),
POINTER :: virial
2546 NULLIFY (particle_set, virial, cell, force, atomic_kind_set, nl_2c_pot, nl_2c_met)
2547 NULLIFY (orb_basis, ri_basis, qs_kind_set, particle_set, dft_control, dbcsr_dist)
2549 use_virial_prv = .false.
2550 IF (
PRESENT(use_virial)) use_virial_prv = use_virial
2553 IF (
PRESENT(rho_ao_resp))
THEN
2554 IF (
ASSOCIATED(rho_ao_resp(1)%matrix)) do_resp = .true.
2557 resp_only_prv = .false.
2558 IF (
PRESENT(resp_only)) resp_only_prv = resp_only
2560 unit_nr_dbcsr = ri_data%unit_nr_dbcsr
2562 CALL get_qs_env(qs_env, natom=natom, particle_set=particle_set, nkind=nkind, &
2563 atomic_kind_set=atomic_kind_set, virial=virial, &
2564 cell=cell, force=force, para_env=para_env, dft_control=dft_control, &
2565 qs_kind_set=qs_kind_set, dbcsr_dist=dbcsr_dist)
2567 CALL create_3c_tensor(t_3c_ao_ri_ao, dist1, dist2, dist3, ri_data%pgrid_1, &
2568 ri_data%bsizes_AO_split, ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, &
2569 [1, 2], [3], name=
"(AO RI | AO)")
2570 DEALLOCATE (dist1, dist2, dist3)
2572 CALL create_3c_tensor(t_3c_ri_ao_ao, dist1, dist2, dist3, ri_data%pgrid_2, &
2573 ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
2574 [1], [2, 3], name=
"(RI | AO AO)")
2575 DEALLOCATE (dist1, dist2, dist3)
2577 ALLOCATE (basis_set_ri(nkind), basis_set_ao(nkind))
2578 CALL basis_set_list_setup(basis_set_ri, ri_data%ri_basis_type, qs_kind_set)
2579 CALL get_particle_set(particle_set, qs_kind_set, basis=basis_set_ri)
2580 CALL basis_set_list_setup(basis_set_ao, ri_data%orb_basis_type, qs_kind_set)
2581 CALL get_particle_set(particle_set, qs_kind_set, basis=basis_set_ao)
2583 DO ibasis = 1,
SIZE(basis_set_ao)
2584 orb_basis => basis_set_ao(ibasis)%gto_basis_set
2585 CALL init_interaction_radii_orb_basis(orb_basis, ri_data%eps_pgf_orb)
2586 ri_basis => basis_set_ri(ibasis)%gto_basis_set
2587 CALL init_interaction_radii_orb_basis(ri_basis, ri_data%eps_pgf_orb)
2591 ALLOCATE (t_2c_der_metric(3), t_2c_der_ri(3), t_3c_der_ao(3), t_3c_der_ri(3))
2592 IF (use_virial)
THEN
2593 CALL precalc_derivatives(t_3c_der_ri_comp, t_3c_der_ao_comp, t_3c_der_ri_ind, t_3c_der_ao_ind, &
2594 t_2c_der_ri, t_2c_der_metric, t_3c_ri_ao_ao, &
2595 basis_set_ao, basis_set_ri, ri_data, qs_env, &
2596 nl_2c_pot=nl_2c_pot, nl_2c_met=nl_2c_met, &
2597 nl_3c_out=nl_3c, t_3c_virial=t_3c_virial)
2599 ALLOCATE (col_bsize(natom), row_bsize(natom))
2600 col_bsize(:) = ri_data%bsizes_RI
2601 row_bsize(:) = ri_data%bsizes_RI
2602 CALL dbcsr_create(virial_trace,
"virial_trace", dbcsr_dist, dbcsr_type_no_symmetry, row_bsize, col_bsize)
2603 CALL dbt_create(virial_trace, t_2c_virial)
2604 DEALLOCATE (col_bsize, row_bsize)
2606 CALL precalc_derivatives(t_3c_der_ri_comp, t_3c_der_ao_comp, t_3c_der_ri_ind, t_3c_der_ao_ind, &
2607 t_2c_der_ri, t_2c_der_metric, t_3c_ri_ao_ao, &
2608 basis_set_ao, basis_set_ri, ri_data, qs_env)
2612 CALL dbt_create(t_3c_ri_ao_ao, t_3c_sparse)
2614 DO i_mem = 1,
SIZE(t_3c_der_ri_comp, 1)
2615 CALL decompress_tensor(t_3c_ri_ao_ao, t_3c_der_ri_ind(i_mem, i_xyz)%ind, &
2616 t_3c_der_ri_comp(i_mem, i_xyz), ri_data%filter_eps_storage)
2617 CALL dbt_copy(t_3c_ri_ao_ao, t_3c_sparse, summation=.true., move_data=.true.)
2619 CALL decompress_tensor(t_3c_ri_ao_ao, t_3c_der_ao_ind(i_mem, i_xyz)%ind, &
2620 t_3c_der_ao_comp(i_mem, i_xyz), ri_data%filter_eps_storage)
2621 CALL dbt_copy(t_3c_ri_ao_ao, t_3c_sparse, summation=.true.)
2622 CALL dbt_copy(t_3c_ri_ao_ao, t_3c_sparse, order=[1, 3, 2], summation=.true., move_data=.true.)
2627 CALL dbt_create(t_3c_ri_ao_ao, t_3c_der_ri(i_xyz))
2628 CALL dbt_create(t_3c_ri_ao_ao, t_3c_der_ao(i_xyz))
2633 IF (nspins == 2) spin_fac = 1.0_dp
2634 IF (
PRESENT(rescale_factor)) spin_fac = spin_fac*rescale_factor
2636 ALLOCATE (idx_to_at_ri(
SIZE(ri_data%bsizes_RI_split)))
2637 CALL get_idx_to_atom(idx_to_at_ri, ri_data%bsizes_RI_split, ri_data%bsizes_RI)
2639 ALLOCATE (idx_to_at_ao(
SIZE(ri_data%bsizes_AO_split)))
2640 CALL get_idx_to_atom(idx_to_at_ao, ri_data%bsizes_AO_split, ri_data%bsizes_AO)
2642 CALL get_atomic_kind_set(atomic_kind_set, kind_of=kind_of, atom_of_kind=atom_of_kind)
2645 n_mem = ri_data%n_mem
2646 ALLOCATE (batch_start(n_mem), batch_end(n_mem))
2647 batch_start(:) = ri_data%starts_array_mem(:)
2648 batch_end(:) = ri_data%ends_array_mem(:)
2650 ALLOCATE (batch_ranges(n_mem + 1))
2651 batch_ranges(:n_mem) = ri_data%starts_array_mem_block(:)
2652 batch_ranges(n_mem + 1) = ri_data%ends_array_mem_block(n_mem) + 1
2654 n_mem_ri = ri_data%n_mem_RI
2655 ALLOCATE (batch_start_ri(n_mem_ri), batch_end_ri(n_mem_ri))
2656 batch_start_ri(:) = ri_data%starts_array_RI_mem(:)
2657 batch_end_ri(:) = ri_data%ends_array_RI_mem(:)
2659 ALLOCATE (batch_ranges_ri(n_mem_ri + 1))
2660 batch_ranges_ri(:n_mem_ri) = ri_data%starts_array_RI_mem_block(:)
2661 batch_ranges_ri(n_mem_ri + 1) = ri_data%ends_array_RI_mem_block(n_mem_ri) + 1
2664 CALL create_2c_tensor(rho_ao_1, dist1, dist2, ri_data%pgrid_2d, &
2665 ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
2667 DEALLOCATE (dist1, dist2)
2668 CALL dbt_create(rho_ao_1, rho_ao_2)
2670 CALL create_2c_tensor(t_2c_ri, dist1, dist2, ri_data%pgrid_2d, &
2671 ri_data%bsizes_RI_split, ri_data%bsizes_RI_split, name=
"(RI | RI)")
2672 DEALLOCATE (dist1, dist2)
2673 CALL dbt_create(t_2c_ri, t_svs)
2674 CALL dbt_create(t_2c_ri, t_r)
2675 CALL dbt_create(t_2c_ri, t_2c_ri_tmp)
2677 CALL dbt_create(t_3c_ao_ri_ao, t_3c_1)
2678 CALL dbt_create(t_3c_ao_ri_ao, t_3c_2)
2679 CALL dbt_create(t_3c_ri_ao_ao, t_3c_3)
2680 CALL dbt_create(t_3c_ri_ao_ao, t_3c_4)
2681 CALL dbt_create(t_3c_ri_ao_ao, t_3c_5)
2682 CALL dbt_create(t_3c_ri_ao_ao, t_3c_help_1)
2683 CALL dbt_create(t_3c_ri_ao_ao, t_3c_help_2)
2685 CALL dbt_create(t_3c_ao_ri_ao, t_3c_int)
2686 CALL dbt_copy(ri_data%t_3c_int_ctr_2(1, 1), t_3c_int)
2688 CALL dbt_create(t_3c_ri_ao_ao, t_3c_int_2)
2690 CALL para_env%sync()
2694 IF (.NOT. ri_data%same_op)
THEN
2696 CALL dbt_contract(1.0_dp, ri_data%t_2c_inv(1, 1), ri_data%t_2c_pot(1, 1), 0.0_dp, t_2c_ri, &
2697 contract_1=[2], notcontract_1=[1], &
2698 contract_2=[1], notcontract_2=[2], &
2699 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2700 unit_nr=unit_nr_dbcsr, flop=nflop)
2701 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2703 CALL dbt_contract(1.0_dp, t_2c_ri, ri_data%t_2c_inv(1, 1), 0.0_dp, t_svs, &
2704 contract_1=[2], notcontract_1=[1], &
2705 contract_2=[1], notcontract_2=[2], &
2706 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2707 unit_nr=unit_nr_dbcsr, flop=nflop)
2708 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2711 CALL dbt_copy(ri_data%t_2c_inv(1, 1), t_svs)
2714 CALL dbt_batched_contract_init(t_3c_int, batch_range_1=batch_ranges, batch_range_3=batch_ranges)
2715 CALL dbt_batched_contract_init(t_3c_int_2, batch_range_1=batch_ranges_ri, &
2716 batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2717 CALL dbt_batched_contract_init(t_3c_1, batch_range_1=batch_ranges, batch_range_3=batch_ranges)
2718 CALL dbt_batched_contract_init(t_3c_2, batch_range_1=batch_ranges, batch_range_3=batch_ranges)
2719 CALL dbt_batched_contract_init(t_3c_3, batch_range_1=batch_ranges_ri, &
2720 batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2721 CALL dbt_batched_contract_init(t_3c_4, batch_range_1=batch_ranges_ri, &
2722 batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2723 CALL dbt_batched_contract_init(t_3c_5, batch_range_1=batch_ranges_ri, &
2724 batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2725 CALL dbt_batched_contract_init(t_3c_sparse, batch_range_1=batch_ranges_ri, &
2726 batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2728 DO i_spin = 1, nspins
2731 CALL dbt_create(rho_ao(i_spin, 1)%matrix, t_2c_tmp)
2732 CALL dbt_copy_matrix_to_tensor(rho_ao(i_spin, 1)%matrix, t_2c_tmp)
2733 CALL dbt_copy(t_2c_tmp, rho_ao_1, move_data=.true.)
2734 CALL dbt_destroy(t_2c_tmp)
2736 IF (.NOT. do_resp)
THEN
2737 CALL dbt_copy(rho_ao_1, rho_ao_2)
2738 ELSE IF (do_resp .AND. resp_only_prv)
THEN
2740 CALL dbt_create(rho_ao_resp(i_spin)%matrix, t_2c_tmp)
2741 CALL dbt_copy_matrix_to_tensor(rho_ao_resp(i_spin)%matrix, t_2c_tmp)
2742 CALL dbt_copy(t_2c_tmp, rho_ao_2)
2744 CALL dbt_copy(t_2c_tmp, rho_ao_2, summation=.true., move_data=.true.)
2745 CALL dbt_destroy(t_2c_tmp)
2749 CALL dbt_copy(rho_ao_1, rho_ao_2)
2750 CALL dbcsr_create(dbcsr_tmp, template=rho_ao_resp(i_spin)%matrix)
2751 CALL dbcsr_add(dbcsr_tmp, rho_ao_resp(i_spin)%matrix, 0.0_dp, -1.0_dp)
2752 CALL dbt_create(dbcsr_tmp, t_2c_tmp)
2753 CALL dbt_copy_matrix_to_tensor(dbcsr_tmp, t_2c_tmp)
2754 CALL dbt_copy(t_2c_tmp, rho_ao_1, summation=.true., move_data=.true.)
2755 CALL dbcsr_release(dbcsr_tmp)
2757 CALL dbt_copy_matrix_to_tensor(rho_ao_resp(i_spin)%matrix, t_2c_tmp)
2758 CALL dbt_copy(t_2c_tmp, rho_ao_2, summation=.true., move_data=.true.)
2759 CALL dbt_destroy(t_2c_tmp)
2762 work_virial = 0.0_dp
2764 CALL timeset(routinen//
"_3c", handle)
2767 ibounds(:, 1) = [batch_start(i_mem), batch_end(i_mem)]
2769 CALL dbt_batched_contract_init(rho_ao_1)
2770 CALL dbt_contract(1.0_dp, rho_ao_1, t_3c_int, 0.0_dp, t_3c_1, &
2771 contract_1=[1], notcontract_1=[2], &
2772 contract_2=[3], notcontract_2=[1, 2], &
2773 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
2774 bounds_2=ibounds, unit_nr=unit_nr_dbcsr, flop=nflop)
2775 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2776 CALL dbt_batched_contract_finalize(rho_ao_1)
2778 CALL dbt_copy(t_3c_1, t_3c_2, order=[3, 2, 1], move_data=.true.)
2781 jbounds(:, 1) = [batch_start(j_mem), batch_end(j_mem)]
2783 CALL dbt_batched_contract_init(rho_ao_2)
2784 CALL dbt_contract(1.0_dp, rho_ao_2, t_3c_2, 0.0_dp, t_3c_1, &
2785 contract_1=[1], notcontract_1=[2], &
2786 contract_2=[3], notcontract_2=[1, 2], &
2787 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
2788 bounds_2=jbounds, unit_nr=unit_nr_dbcsr, flop=nflop)
2789 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2790 CALL dbt_batched_contract_finalize(rho_ao_2)
2792 bounds_cpy(:, 1) = [batch_start(i_mem), batch_end(i_mem)]
2793 bounds_cpy(:, 2) = [1, sum(ri_data%bsizes_RI)]
2794 bounds_cpy(:, 3) = [batch_start(j_mem), batch_end(j_mem)]
2795 CALL dbt_copy(t_3c_int, t_3c_int_2, order=[2, 1, 3], bounds=bounds_cpy)
2796 CALL dbt_copy(t_3c_1, t_3c_3, order=[2, 1, 3], move_data=.true.)
2798 DO k_mem = 1, n_mem_ri
2799 kbounds(:, 1) = [batch_start_ri(k_mem), batch_end_ri(k_mem)]
2801 bounds_cpy(:, 1) = [batch_start_ri(k_mem), batch_end_ri(k_mem)]
2802 bounds_cpy(:, 2) = [batch_start(i_mem), batch_end(i_mem)]
2803 bounds_cpy(:, 3) = [batch_start(j_mem), batch_end(j_mem)]
2804 CALL dbt_copy(t_3c_sparse, t_3c_4, bounds=bounds_cpy)
2807 CALL dbt_batched_contract_init(t_svs)
2808 CALL dbt_contract(1.0_dp, t_svs, t_3c_3, 0.0_dp, t_3c_4, &
2809 contract_1=[2], notcontract_1=[1], &
2810 contract_2=[1], notcontract_2=[2, 3], &
2811 map_1=[1], map_2=[2, 3], filter_eps=ri_data%filter_eps, &
2812 retain_sparsity=.true., unit_nr=unit_nr_dbcsr, flop=nflop)
2813 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2814 CALL dbt_batched_contract_finalize(t_svs)
2816 CALL dbt_copy(t_3c_4, t_3c_5, summation=.true., move_data=.true.)
2818 ijbounds(:, 1) = ibounds(:, 1)
2819 ijbounds(:, 2) = jbounds(:, 1)
2822 CALL dbt_batched_contract_init(t_r)
2823 CALL dbt_contract(1.0_dp, t_3c_int_2, t_3c_3, 1.0_dp, t_r, &
2824 contract_1=[2, 3], notcontract_1=[1], &
2825 contract_2=[2, 3], notcontract_2=[1], &
2826 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2827 bounds_1=ijbounds, bounds_3=kbounds, &
2828 unit_nr=unit_nr_dbcsr, flop=nflop)
2829 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2830 CALL dbt_batched_contract_finalize(t_r)
2835 CALL dbt_copy(t_3c_5, t_3c_help_1, move_data=.true.)
2838 pref = -0.5_dp*2.0_dp*hf_fraction*spin_fac
2840 DO k_mem = 1,
SIZE(t_3c_der_ri_comp, 1)
2842 CALL dbt_clear(t_3c_der_ri(i_xyz))
2843 CALL decompress_tensor(t_3c_der_ri(i_xyz), t_3c_der_ri_ind(k_mem, i_xyz)%ind, &
2844 t_3c_der_ri_comp(k_mem, i_xyz), ri_data%filter_eps_storage)
2850 pref = -0.5_dp*4.0_dp*hf_fraction*spin_fac
2853 CALL dbt_copy(t_3c_help_1, t_3c_help_2, order=[1, 3, 2])
2856 DO k_mem = 1,
SIZE(t_3c_der_ao_comp, 1)
2858 CALL dbt_clear(t_3c_der_ao(i_xyz))
2859 CALL decompress_tensor(t_3c_der_ao(i_xyz), t_3c_der_ao_ind(k_mem, i_xyz)%ind, &
2860 t_3c_der_ao_comp(k_mem, i_xyz), ri_data%filter_eps_storage)
2863 idx_to_at_ao, pref, deriv_dim=2)
2867 idx_to_at_ao, pref, deriv_dim=2)
2872 IF (use_virial)
THEN
2873 pref = -0.5_dp*2.0_dp*hf_fraction*spin_fac
2874 CALL dbt_copy(t_3c_help_1, t_3c_virial, move_data=.true.)
2875 CALL calc_3c_virial(work_virial, t_3c_virial, pref, qs_env, nl_3c, basis_set_ri, &
2876 basis_set_ao, basis_set_ao, ri_data%ri_metric, &
2877 der_eps=ri_data%eps_schwarz_forces, op_pos=1)
2879 CALL dbt_clear(t_3c_virial)
2882 CALL dbt_clear(t_3c_help_1)
2883 CALL dbt_clear(t_3c_help_2)
2885 CALL timestop(handle)
2887 CALL timeset(routinen//
"_2c", handle)
2890 CALL dbt_contract(1.0_dp, ri_data%t_2c_inv(1, 1), t_r, 0.0_dp, t_2c_ri_tmp, &
2891 contract_1=[2], notcontract_1=[1], &
2892 contract_2=[1], notcontract_2=[2], &
2893 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2894 unit_nr=unit_nr_dbcsr, flop=nflop)
2895 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2897 CALL dbt_contract(1.0_dp, t_2c_ri_tmp, ri_data%t_2c_inv(1, 1), 0.0_dp, t_2c_ri, &
2898 contract_1=[2], notcontract_1=[1], &
2899 contract_2=[1], notcontract_2=[2], &
2900 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2901 unit_nr=unit_nr_dbcsr, flop=nflop)
2902 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2905 pref = 0.5_dp*hf_fraction*spin_fac
2906 IF (.NOT. ri_data%same_op) pref = -pref
2907 CALL get_2c_der_force(force, t_2c_ri, t_2c_der_ri, atom_of_kind, kind_of, idx_to_at_ri, pref)
2910 IF (use_virial_prv)
THEN
2911 CALL dbt_copy(t_2c_ri, t_2c_virial)
2912 CALL dbt_copy_tensor_to_matrix(t_2c_virial, virial_trace)
2913 CALL calc_2c_virial(work_virial, virial_trace, pref, qs_env, nl_2c_pot, &
2914 basis_set_ri, basis_set_ri, ri_data%hfx_pot)
2918 IF (.NOT. ri_data%same_op)
THEN
2919 CALL dbt_contract(1.0_dp, t_2c_ri, ri_data%t_2c_pot(1, 1), 0.0_dp, t_2c_ri_tmp, &
2920 contract_1=[2], notcontract_1=[1], &
2921 contract_2=[1], notcontract_2=[2], &
2922 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2923 unit_nr=unit_nr_dbcsr, flop=nflop)
2924 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2926 CALL dbt_contract(1.0_dp, t_2c_ri_tmp, ri_data%t_2c_inv(1, 1), 0.0_dp, t_2c_ri, &
2927 contract_1=[2], notcontract_1=[1], &
2928 contract_2=[1], notcontract_2=[2], &
2929 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2930 unit_nr=unit_nr_dbcsr, flop=nflop)
2931 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2933 pref = 0.5_dp*2.0_dp*hf_fraction*spin_fac
2934 CALL get_2c_der_force(force, t_2c_ri, t_2c_der_metric, atom_of_kind, kind_of, idx_to_at_ri, pref)
2936 IF (use_virial_prv)
THEN
2937 CALL dbt_copy(t_2c_ri, t_2c_virial)
2938 CALL dbt_copy_tensor_to_matrix(t_2c_virial, virial_trace)
2939 CALL calc_2c_virial(work_virial, virial_trace, pref, qs_env, nl_2c_met, &
2940 basis_set_ri, basis_set_ri, ri_data%ri_metric)
2943 CALL dbt_clear(t_2c_ri)
2944 CALL dbt_clear(t_2c_ri_tmp)
2946 CALL dbt_clear(t_3c_help_1)
2947 CALL dbt_clear(t_3c_help_2)
2948 CALL timestop(handle)
2950 IF (use_virial_prv)
THEN
2954 virial%pv_fock_4c(i_xyz, j_xyz) = virial%pv_fock_4c(i_xyz, j_xyz) &
2955 + work_virial(i_xyz, k_xyz)*cell%hmat(j_xyz, k_xyz)
2962 CALL dbt_batched_contract_finalize(t_3c_int)
2963 CALL dbt_batched_contract_finalize(t_3c_int_2)
2964 CALL dbt_batched_contract_finalize(t_3c_1)
2965 CALL dbt_batched_contract_finalize(t_3c_2)
2966 CALL dbt_batched_contract_finalize(t_3c_3)
2967 CALL dbt_batched_contract_finalize(t_3c_4)
2968 CALL dbt_batched_contract_finalize(t_3c_5)
2969 CALL dbt_batched_contract_finalize(t_3c_sparse)
2971 CALL para_env%sync()
2974 CALL dbt_copy(t_3c_int, ri_data%t_3c_int_ctr_2(1, 1), move_data=.true.)
2977 CALL dbt_destroy(rho_ao_1)
2978 CALL dbt_destroy(rho_ao_2)
2979 CALL dbt_destroy(t_3c_ao_ri_ao)
2980 CALL dbt_destroy(t_3c_ri_ao_ao)
2981 CALL dbt_destroy(t_3c_int)
2982 CALL dbt_destroy(t_3c_int_2)
2983 CALL dbt_destroy(t_3c_1)
2984 CALL dbt_destroy(t_3c_2)
2985 CALL dbt_destroy(t_3c_3)
2986 CALL dbt_destroy(t_3c_4)
2987 CALL dbt_destroy(t_3c_5)
2988 CALL dbt_destroy(t_3c_help_1)
2989 CALL dbt_destroy(t_3c_help_2)
2990 CALL dbt_destroy(t_3c_sparse)
2991 CALL dbt_destroy(t_svs)
2992 CALL dbt_destroy(t_r)
2993 CALL dbt_destroy(t_2c_ri)
2994 CALL dbt_destroy(t_2c_ri_tmp)
2997 CALL dbt_destroy(t_3c_der_ri(i_xyz))
2998 CALL dbt_destroy(t_3c_der_ao(i_xyz))
2999 CALL dbt_destroy(t_2c_der_ri(i_xyz))
3000 IF (.NOT. ri_data%same_op)
CALL dbt_destroy(t_2c_der_metric(i_xyz))
3004 DO i_mem = 1,
SIZE(t_3c_der_ao_comp, 1)
3005 CALL dealloc_containers(t_3c_der_ao_comp(i_mem, i_xyz), dummy_int)
3006 CALL dealloc_containers(t_3c_der_ri_comp(i_mem, i_xyz), dummy_int)
3009 DEALLOCATE (t_3c_der_ao_ind, t_3c_der_ri_ind)
3011 DO ibasis = 1,
SIZE(basis_set_ao)
3012 orb_basis => basis_set_ao(ibasis)%gto_basis_set
3013 ri_basis => basis_set_ri(ibasis)%gto_basis_set
3014 CALL init_interaction_radii_orb_basis(orb_basis, dft_control%qs_control%eps_pgf_orb)
3015 CALL init_interaction_radii_orb_basis(ri_basis, dft_control%qs_control%eps_pgf_orb)
3018 IF (use_virial)
THEN
3019 CALL release_neighbor_list_sets(nl_2c_met)
3020 CALL release_neighbor_list_sets(nl_2c_pot)
3021 CALL neighbor_list_3c_destroy(nl_3c)
3022 CALL dbcsr_release(virial_trace)
3023 CALL dbt_destroy(t_2c_virial)
3024 CALL dbt_destroy(t_3c_virial)
3027 END SUBROUTINE hfx_ri_forces_pmat
3043 mos, use_virial, resp_only, rescale_factor)
3045 TYPE(qs_environment_type),
POINTER :: qs_env
3046 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
3047 INTEGER,
INTENT(IN) :: nspins
3048 REAL(kind=dp),
INTENT(IN) :: hf_fraction
3049 TYPE(dbcsr_p_type),
DIMENSION(:, :),
OPTIONAL :: rho_ao
3050 TYPE(dbcsr_p_type),
DIMENSION(:),
OPTIONAL :: rho_ao_resp
3051 TYPE(mo_set_type),
DIMENSION(:),
INTENT(IN), &
3053 LOGICAL,
INTENT(IN),
OPTIONAL :: use_virial, resp_only
3054 REAL(dp),
INTENT(IN),
OPTIONAL :: rescale_factor
3056 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_update_forces'
3058 INTEGER :: handle, ispin
3059 INTEGER,
DIMENSION(2) :: homo
3060 REAL(kind=dp),
DIMENSION(:),
POINTER :: mo_eigenvalues
3061 TYPE(cp_fm_type),
POINTER :: mo_coeff
3062 TYPE(dbcsr_type),
DIMENSION(2) :: mo_coeff_b
3063 TYPE(dbcsr_type),
POINTER :: mo_coeff_b_tmp
3065 CALL timeset(routinen, handle)
3067 SELECT CASE (ri_data%flavor)
3070 DO ispin = 1, nspins
3071 NULLIFY (mo_coeff_b_tmp)
3072 cpassert(mos(ispin)%uniform_occupation)
3073 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, eigenvalues=mo_eigenvalues, mo_coeff_b=mo_coeff_b_tmp)
3075 IF (.NOT. mos(ispin)%use_mo_coeff_b)
CALL copy_fm_to_dbcsr(mo_coeff, mo_coeff_b_tmp)
3076 CALL dbcsr_copy(mo_coeff_b(ispin), mo_coeff_b_tmp)
3079 DO ispin = 1, nspins
3080 CALL dbcsr_scale(mo_coeff_b(ispin), sqrt(mos(ispin)%maxocc))
3081 homo(ispin) = mos(ispin)%homo
3084 CALL hfx_ri_forces_mo(qs_env, ri_data, nspins, hf_fraction, mo_coeff_b, use_virial)
3088 CALL hfx_ri_forces_pmat(qs_env, ri_data, nspins, hf_fraction, rho_ao, rho_ao_resp, use_virial, &
3089 resp_only, rescale_factor)
3092 DO ispin = 1, nspins
3093 CALL dbcsr_release(mo_coeff_b(ispin))
3096 CALL timestop(handle)
3118 SUBROUTINE precalc_derivatives(t_3c_der_RI_comp, t_3c_der_AO_comp, t_3c_der_RI_ind, t_3c_der_AO_ind, &
3119 t_2c_der_RI, t_2c_der_metric, ri_ao_ao_template, &
3120 basis_set_AO, basis_set_RI, ri_data, qs_env, &
3121 nl_2c_pot, nl_2c_met, nl_3c_out, t_3c_virial)
3123 TYPE(hfx_compression_type),
ALLOCATABLE, &
3124 DIMENSION(:, :),
INTENT(INOUT) :: t_3c_der_ri_comp, t_3c_der_ao_comp
3125 TYPE(block_ind_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_der_ri_ind, t_3c_der_ao_ind
3126 TYPE(dbt_type),
DIMENSION(3),
INTENT(OUT) :: t_2c_der_ri, t_2c_der_metric
3127 TYPE(dbt_type),
INTENT(INOUT) :: ri_ao_ao_template
3128 TYPE(gto_basis_set_p_type),
ALLOCATABLE, &
3129 DIMENSION(:),
TARGET :: basis_set_ao, basis_set_ri
3130 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
3131 TYPE(qs_environment_type),
POINTER :: qs_env
3132 TYPE(neighbor_list_set_p_type),
DIMENSION(:), &
3133 OPTIONAL,
POINTER :: nl_2c_pot, nl_2c_met
3134 TYPE(neighbor_list_3c_type),
OPTIONAL :: nl_3c_out
3135 TYPE(dbt_type),
INTENT(INOUT),
OPTIONAL :: t_3c_virial
3137 CHARACTER(LEN=*),
PARAMETER :: routinen =
'precalc_derivatives'
3139 INTEGER :: handle, i_mem, i_xyz, n_mem, natom, &
3141 INTEGER(int_8) :: nze, nze_tot
3142 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: dist1, dist2, dist_ao_1, dist_ao_2, &
3143 dist_ri, dummy_end, dummy_start, &
3144 end_blocks, start_blocks
3145 INTEGER,
DIMENSION(3) :: pcoord, pdims
3146 INTEGER,
DIMENSION(:),
POINTER :: col_bsize, row_bsize
3147 REAL(dp) :: compression_factor, memory, occ
3148 TYPE(dbcsr_distribution_type) :: dbcsr_dist
3149 TYPE(dbcsr_type),
DIMENSION(1, 3) :: t_2c_der_metric_prv, t_2c_der_ri_prv
3150 TYPE(dbt_pgrid_type) :: pgrid
3151 TYPE(dbt_type) :: t_2c_template, t_2c_tmp, t_3c_template
3152 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:, :, :) :: t_3c_der_ao_prv, t_3c_der_ri_prv
3153 TYPE(dft_control_type),
POINTER :: dft_control
3154 TYPE(distribution_2d_type),
POINTER :: dist_2d
3155 TYPE(distribution_3d_type) :: dist_3d, dist_3d_out
3156 TYPE(mp_cart_type) :: mp_comm_t3c, mp_comm_t3c_out
3157 TYPE(mp_para_env_type),
POINTER :: para_env
3158 TYPE(neighbor_list_3c_type) :: nl_3c
3159 TYPE(neighbor_list_set_p_type),
DIMENSION(:), &
3161 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
3162 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
3164 NULLIFY (qs_kind_set, dist_2d, nl_2c, particle_set, dft_control, para_env)
3166 CALL timeset(routinen, handle)
3168 CALL get_qs_env(qs_env, nkind=nkind, qs_kind_set=qs_kind_set, distribution_2d=dist_2d, natom=natom, &
3169 particle_set=particle_set, dft_control=dft_control, para_env=para_env)
3176 CALL dbt_pgrid_create(para_env, pdims, pgrid, tensor_dims=[max(1, natom/(ri_data%n_mem*nthreads)), natom, natom])
3178 CALL create_3c_tensor(t_3c_template, dist_ri, dist_ao_1, dist_ao_2, pgrid, &
3179 ri_data%bsizes_RI, ri_data%bsizes_AO, ri_data%bsizes_AO, &
3180 map1=[1], map2=[2, 3], &
3181 name=
"der (RI AO | AO)")
3183 ALLOCATE (t_3c_der_ao_prv(1, 1, 3), t_3c_der_ri_prv(1, 1, 3))
3185 CALL dbt_create(t_3c_template, t_3c_der_ri_prv(1, 1, i_xyz))
3186 CALL dbt_create(t_3c_template, t_3c_der_ao_prv(1, 1, i_xyz))
3188 IF (
PRESENT(t_3c_virial))
THEN
3189 CALL dbt_create(t_3c_template, t_3c_virial)
3191 CALL dbt_destroy(t_3c_template)
3193 CALL dbt_mp_environ_pgrid(pgrid, pdims, pcoord)
3194 CALL mp_comm_t3c%create(pgrid%mp_comm_2d, 3, pdims)
3195 CALL distribution_3d_create(dist_3d, dist_ri, dist_ao_1, dist_ao_2, &
3196 nkind, particle_set, mp_comm_t3c, own_comm=.true.)
3198 CALL build_3c_neighbor_lists(nl_3c, basis_set_ri, basis_set_ao, basis_set_ao, dist_3d, ri_data%ri_metric, &
3199 "HFX_3c_nl", qs_env, op_pos=1, sym_jk=.true., own_dist=.true.)
3201 IF (
PRESENT(nl_3c_out))
THEN
3202 CALL dbt_mp_environ_pgrid(pgrid, pdims, pcoord)
3203 CALL mp_comm_t3c_out%create(pgrid%mp_comm_2d, 3, pdims)
3204 CALL distribution_3d_create(dist_3d_out, dist_ri, dist_ao_1, dist_ao_2, &
3205 nkind, particle_set, mp_comm_t3c_out, own_comm=.true.)
3206 CALL build_3c_neighbor_lists(nl_3c_out, basis_set_ri, basis_set_ao, basis_set_ao, dist_3d_out, &
3207 ri_data%ri_metric,
"HFX_3c_nl", qs_env, op_pos=1, sym_jk=.false., &
3210 DEALLOCATE (dist_ri, dist_ao_1, dist_ao_2)
3211 CALL dbt_pgrid_destroy(pgrid)
3213 n_mem = ri_data%n_mem
3214 CALL create_tensor_batches(ri_data%bsizes_RI, n_mem, dummy_start, dummy_end, &
3215 start_blocks, end_blocks)
3216 DEALLOCATE (dummy_start, dummy_end)
3218 ALLOCATE (t_3c_der_ao_comp(n_mem, 3), t_3c_der_ri_comp(n_mem, 3))
3219 ALLOCATE (t_3c_der_ao_ind(n_mem, 3), t_3c_der_ri_ind(n_mem, 3))
3224 CALL build_3c_derivatives(t_3c_der_ri_prv, t_3c_der_ao_prv, ri_data%filter_eps, qs_env, &
3225 nl_3c, basis_set_ri, basis_set_ao, basis_set_ao, &
3226 ri_data%ri_metric, der_eps=ri_data%eps_schwarz_forces, op_pos=1, &
3227 bounds_i=[start_blocks(i_mem), end_blocks(i_mem)])
3230 CALL dbt_copy(t_3c_der_ri_prv(1, 1, i_xyz), ri_ao_ao_template, move_data=.true.)
3231 CALL dbt_filter(ri_ao_ao_template, ri_data%filter_eps)
3232 CALL get_tensor_occupancy(ri_ao_ao_template, nze, occ)
3233 nze_tot = nze_tot + nze
3235 CALL alloc_containers(t_3c_der_ri_comp(i_mem, i_xyz), 1)
3236 CALL compress_tensor(ri_ao_ao_template, t_3c_der_ri_ind(i_mem, i_xyz)%ind, &
3237 t_3c_der_ri_comp(i_mem, i_xyz), ri_data%filter_eps_storage, memory)
3238 CALL dbt_clear(ri_ao_ao_template)
3241 CALL dbt_copy(t_3c_der_ao_prv(1, 1, i_xyz), ri_ao_ao_template, order=[1, 3, 2], move_data=.true.)
3242 CALL dbt_filter(ri_ao_ao_template, ri_data%filter_eps)
3243 CALL get_tensor_occupancy(ri_ao_ao_template, nze, occ)
3244 nze_tot = nze_tot + nze
3246 CALL alloc_containers(t_3c_der_ao_comp(i_mem, i_xyz), 1)
3247 CALL compress_tensor(ri_ao_ao_template, t_3c_der_ao_ind(i_mem, i_xyz)%ind, &
3248 t_3c_der_ao_comp(i_mem, i_xyz), ri_data%filter_eps_storage, memory)
3249 CALL dbt_clear(ri_ao_ao_template)
3253 CALL neighbor_list_3c_destroy(nl_3c)
3255 CALL dbt_destroy(t_3c_der_ri_prv(1, 1, i_xyz))
3256 CALL dbt_destroy(t_3c_der_ao_prv(1, 1, i_xyz))
3259 CALL para_env%sum(memory)
3260 compression_factor = real(nze_tot, dp)*1.0e-06*8.0_dp/memory
3261 IF (ri_data%unit_nr > 0)
THEN
3262 WRITE (unit=ri_data%unit_nr, fmt=
"((T3,A,T66,F11.2,A4))") &
3263 "MEMORY_INFO| Memory for 3-center HFX derivatives (compressed):", memory,
' MiB'
3265 WRITE (unit=ri_data%unit_nr, fmt=
"((T3,A,T60,F21.2))") &
3266 "MEMORY_INFO| Compression factor: ", compression_factor
3270 CALL cp_dbcsr_dist2d_to_dist(dist_2d, dbcsr_dist)
3271 ALLOCATE (row_bsize(
SIZE(ri_data%bsizes_RI)))
3272 ALLOCATE (col_bsize(
SIZE(ri_data%bsizes_RI)))
3273 row_bsize(:) = ri_data%bsizes_RI
3274 col_bsize(:) = ri_data%bsizes_RI
3276 CALL build_2c_neighbor_lists(nl_2c, basis_set_ri, basis_set_ri, ri_data%hfx_pot, &
3277 "HFX_2c_nl_pot", qs_env, sym_ij=.true., dist_2d=dist_2d)
3280 CALL dbcsr_create(t_2c_der_ri_prv(1, i_xyz),
"(R|P) HFX der", dbcsr_dist, &
3281 dbcsr_type_antisymmetric, row_bsize, col_bsize)
3284 CALL build_2c_derivatives(t_2c_der_ri_prv, ri_data%filter_eps_2c, qs_env, nl_2c, basis_set_ri, &
3285 basis_set_ri, ri_data%hfx_pot)
3286 CALL release_neighbor_list_sets(nl_2c)
3288 IF (
PRESENT(nl_2c_pot))
THEN
3290 CALL build_2c_neighbor_lists(nl_2c_pot, basis_set_ri, basis_set_ri, ri_data%hfx_pot, &
3291 "HFX_2c_nl_pot", qs_env, sym_ij=.false., dist_2d=dist_2d)
3295 CALL create_2c_tensor(t_2c_template, dist1, dist2, ri_data%pgrid_2d, ri_data%bsizes_RI_split, &
3296 ri_data%bsizes_RI_split, name=
'(RI| RI)')
3297 DEALLOCATE (dist1, dist2)
3300 CALL dbt_create(t_2c_der_ri_prv(1, i_xyz), t_2c_tmp)
3301 CALL dbt_copy_matrix_to_tensor(t_2c_der_ri_prv(1, i_xyz), t_2c_tmp)
3303 CALL dbt_create(t_2c_template, t_2c_der_ri(i_xyz))
3304 CALL dbt_copy(t_2c_tmp, t_2c_der_ri(i_xyz), move_data=.true.)
3306 CALL dbt_destroy(t_2c_tmp)
3307 CALL dbcsr_release(t_2c_der_ri_prv(1, i_xyz))
3311 IF (.NOT. ri_data%same_op)
THEN
3313 CALL build_2c_neighbor_lists(nl_2c, basis_set_ri, basis_set_ri, ri_data%ri_metric, &
3314 "HFX_2c_nl_RI", qs_env, sym_ij=.true., dist_2d=dist_2d)
3317 CALL dbcsr_create(t_2c_der_metric_prv(1, i_xyz),
"(R|P) HFX der", dbcsr_dist, &
3318 dbcsr_type_antisymmetric, row_bsize, col_bsize)
3321 CALL build_2c_derivatives(t_2c_der_metric_prv, ri_data%filter_eps_2c, qs_env, nl_2c, &
3322 basis_set_ri, basis_set_ri, ri_data%ri_metric)
3323 CALL release_neighbor_list_sets(nl_2c)
3325 IF (
PRESENT(nl_2c_met))
THEN
3327 CALL build_2c_neighbor_lists(nl_2c_met, basis_set_ri, basis_set_ri, ri_data%ri_metric, &
3328 "HFX_2c_nl_RI", qs_env, sym_ij=.false., dist_2d=dist_2d)
3332 CALL dbt_create(t_2c_der_metric_prv(1, i_xyz), t_2c_tmp)
3333 CALL dbt_copy_matrix_to_tensor(t_2c_der_metric_prv(1, i_xyz), t_2c_tmp)
3335 CALL dbt_create(t_2c_template, t_2c_der_metric(i_xyz))
3336 CALL dbt_copy(t_2c_tmp, t_2c_der_metric(i_xyz), move_data=.true.)
3338 CALL dbt_destroy(t_2c_tmp)
3339 CALL dbcsr_release(t_2c_der_metric_prv(1, i_xyz))
3344 CALL dbt_destroy(t_2c_template)
3345 CALL dbcsr_distribution_release(dbcsr_dist)
3346 DEALLOCATE (row_bsize, col_bsize)
3348 CALL timestop(handle)
3350 END SUBROUTINE precalc_derivatives
3367 pref, do_mp2, deriv_dim)
3369 TYPE(qs_force_type),
DIMENSION(:),
POINTER :: force
3370 TYPE(dbt_type),
INTENT(INOUT) :: t_3c_contr
3371 TYPE(dbt_type),
DIMENSION(3),
INTENT(INOUT) :: t_3c_der
3372 INTEGER,
DIMENSION(:),
INTENT(IN) :: atom_of_kind, kind_of, idx_to_at
3373 REAL(dp),
INTENT(IN) :: pref
3374 LOGICAL,
INTENT(IN),
OPTIONAL :: do_mp2
3375 INTEGER,
INTENT(IN),
OPTIONAL :: deriv_dim
3377 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_force_from_3c_trace'
3379 INTEGER :: deriv_dim_prv, handle, i_xyz, iat, &
3380 iat_of_kind, ikind, j_xyz
3381 INTEGER,
DIMENSION(3) :: ind
3382 LOGICAL :: do_mp2_prv, found
3383 REAL(dp) :: new_force
3384 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :, :),
TARGET :: contr_blk, der_blk
3385 REAL(dp),
DIMENSION(3) :: scoord
3386 TYPE(dbt_iterator_type) :: iter
3388 CALL timeset(routinen, handle)
3390 do_mp2_prv = .false.
3391 IF (
PRESENT(do_mp2)) do_mp2_prv = do_mp2
3394 IF (
PRESENT(deriv_dim)) deriv_dim_prv = deriv_dim
3400 CALL dbt_iterator_start(iter, t_3c_der(i_xyz))
3401 DO WHILE (dbt_iterator_blocks_left(iter))
3402 CALL dbt_iterator_next_block(iter, ind)
3404 CALL dbt_get_block(t_3c_der(i_xyz), ind, der_blk, found)
3406 CALL dbt_get_block(t_3c_contr, ind, contr_blk, found)
3411 new_force = pref*sum(der_blk(:, :, :)*contr_blk(:, :, :))
3414 iat = idx_to_at(ind(deriv_dim_prv))
3415 iat_of_kind = atom_of_kind(iat)
3416 ikind = kind_of(iat)
3418 IF (.NOT. do_mp2_prv)
THEN
3420 force(ikind)%fock_4c(i_xyz, iat_of_kind) = force(ikind)%fock_4c(i_xyz, iat_of_kind) &
3424 force(ikind)%mp2_non_sep(i_xyz, iat_of_kind) = force(ikind)%mp2_non_sep(i_xyz, iat_of_kind) &
3428 DEALLOCATE (contr_blk)
3430 DEALLOCATE (der_blk)
3432 CALL dbt_iterator_stop(iter)
3435 CALL timestop(handle)
3453 pref, do_mp2, do_ovlp)
3455 TYPE(qs_force_type),
DIMENSION(:),
POINTER :: force
3456 TYPE(dbt_type),
INTENT(INOUT) :: t_2c_contr
3457 TYPE(dbt_type),
DIMENSION(3),
INTENT(INOUT) :: t_2c_der
3458 INTEGER,
DIMENSION(:),
INTENT(IN) :: atom_of_kind, kind_of, idx_to_at
3459 REAL(dp),
INTENT(IN) :: pref
3460 LOGICAL,
INTENT(IN),
OPTIONAL :: do_mp2, do_ovlp
3462 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_2c_der_force'
3464 INTEGER :: handle, i_xyz, iat, iat_of_kind, ikind, &
3465 j_xyz, jat, jat_of_kind, jkind
3466 INTEGER,
DIMENSION(2) :: ind
3467 LOGICAL :: do_mp2_prv, do_ovlp_prv, found
3468 REAL(dp) :: new_force
3469 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :),
TARGET :: contr_blk, der_blk
3470 REAL(dp),
DIMENSION(3) :: scoord
3471 TYPE(dbt_iterator_type) :: iter
3476 CALL timeset(routinen, handle)
3478 do_mp2_prv = .false.
3479 IF (
PRESENT(do_mp2)) do_mp2_prv = do_mp2
3481 do_ovlp_prv = .false.
3482 IF (
PRESENT(do_ovlp)) do_ovlp_prv = do_ovlp
3489 CALL dbt_iterator_start(iter, t_2c_der(i_xyz))
3490 DO WHILE (dbt_iterator_blocks_left(iter))
3491 CALL dbt_iterator_next_block(iter, ind)
3493 IF (ind(1) == ind(2)) cycle
3495 CALL dbt_get_block(t_2c_der(i_xyz), ind, der_blk, found)
3497 CALL dbt_get_block(t_2c_contr, ind, contr_blk, found)
3503 new_force = pref*sum(der_blk(:, :)*contr_blk(:, :))
3505 iat = idx_to_at(ind(1))
3506 iat_of_kind = atom_of_kind(iat)
3507 ikind = kind_of(iat)
3509 IF (do_mp2_prv)
THEN
3511 force(ikind)%mp2_non_sep(i_xyz, iat_of_kind) = force(ikind)%mp2_non_sep(i_xyz, iat_of_kind) &
3513 ELSE IF (do_ovlp_prv)
THEN
3515 force(ikind)%overlap(i_xyz, iat_of_kind) = force(ikind)%overlap(i_xyz, iat_of_kind) &
3519 force(ikind)%fock_4c(i_xyz, iat_of_kind) = force(ikind)%fock_4c(i_xyz, iat_of_kind) &
3523 jat = idx_to_at(ind(2))
3524 jat_of_kind = atom_of_kind(jat)
3525 jkind = kind_of(jat)
3527 IF (do_mp2_prv)
THEN
3529 force(jkind)%mp2_non_sep(i_xyz, jat_of_kind) = force(jkind)%mp2_non_sep(i_xyz, jat_of_kind) &
3531 ELSE IF (do_ovlp_prv)
THEN
3533 force(jkind)%overlap(i_xyz, jat_of_kind) = force(jkind)%overlap(i_xyz, jat_of_kind) &
3537 force(jkind)%fock_4c(i_xyz, jat_of_kind) = force(jkind)%fock_4c(i_xyz, jat_of_kind) &
3541 DEALLOCATE (contr_blk)
3544 DEALLOCATE (der_blk)
3546 CALL dbt_iterator_stop(iter)
3550 CALL timestop(handle)
3566 SUBROUTINE get_mo_ao_force(force, t_mo_coeff, t_2c_MO_AO, atom_of_kind, kind_of, idx_to_at, pref, i_xyz)
3568 TYPE(qs_force_type),
DIMENSION(:),
POINTER :: force
3569 TYPE(dbt_type),
INTENT(INOUT) :: t_mo_coeff, t_2c_mo_ao
3570 INTEGER,
DIMENSION(:),
INTENT(IN) :: atom_of_kind, kind_of, idx_to_at
3571 REAL(dp),
INTENT(IN) :: pref
3572 INTEGER,
INTENT(IN) :: i_xyz
3574 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_MO_AO_force'
3576 INTEGER :: handle, iat, iat_of_kind, ikind, j_xyz
3577 INTEGER,
DIMENSION(2) :: ind
3579 REAL(dp) :: new_force
3580 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :),
TARGET :: mo_ao_blk, mo_coeff_blk
3581 REAL(dp),
DIMENSION(3) :: scoord
3582 TYPE(dbt_iterator_type) :: iter
3584 CALL timeset(routinen, handle)
3589 CALL dbt_iterator_start(iter, t_2c_mo_ao)
3590 DO WHILE (dbt_iterator_blocks_left(iter))
3591 CALL dbt_iterator_next_block(iter, ind)
3593 CALL dbt_get_block(t_2c_mo_ao, ind, mo_ao_blk, found)
3595 CALL dbt_get_block(t_mo_coeff, ind, mo_coeff_blk, found)
3599 new_force = pref*sum(mo_ao_blk(:, :)*mo_coeff_blk(:, :))
3601 iat = idx_to_at(ind(2))
3602 iat_of_kind = atom_of_kind(iat)
3603 ikind = kind_of(iat)
3606 force(ikind)%fock_4c(i_xyz, iat_of_kind) = force(ikind)%fock_4c(i_xyz, iat_of_kind) &
3609 DEALLOCATE (mo_coeff_blk)
3612 DEALLOCATE (mo_ao_blk)
3614 CALL dbt_iterator_stop(iter)
3617 CALL timestop(handle)
3619 END SUBROUTINE get_mo_ao_force
3628 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
3629 TYPE(qs_environment_type),
POINTER :: qs_env
3631 CHARACTER(Len=2) :: symbol
3632 CHARACTER(Len=8) :: rifmt
3633 INTEGER :: atype, i_ri, ia, ib, ibasis, ikind, &
3634 iset, isgf, ishell, iso, l, m, natom, &
3635 ncols, nkind, nrows, nset, nsgf, &
3637 INTEGER,
DIMENSION(3) :: periodic
3638 INTEGER,
DIMENSION(:),
POINTER :: npgf, nshell
3639 INTEGER,
DIMENSION(:, :),
POINTER :: lshell
3640 LOGICAL :: mult_by_s, print_density, &
3641 print_ri_metric, skip_ri_metric
3642 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: density_coeffs, density_coeffs_2
3643 REAL(dp),
DIMENSION(3, 3) :: hmat
3644 REAL(dp),
DIMENSION(:, :),
POINTER :: zet
3645 REAL(dp),
DIMENSION(:, :, :),
POINTER :: gcc
3646 TYPE(cell_type),
POINTER :: cell
3647 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
3648 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
3649 TYPE(cp_fm_type) :: matrix_s_fm
3650 TYPE(cp_logger_type),
POINTER :: logger
3651 TYPE(dbcsr_p_type),
DIMENSION(:, :),
POINTER :: rho_ao
3652 TYPE(dbcsr_type),
DIMENSION(1) :: matrix_s
3653 TYPE(dft_control_type),
POINTER :: dft_control
3654 TYPE(gto_basis_set_p_type),
ALLOCATABLE, &
3655 DIMENSION(:),
TARGET :: basis_set_ao, basis_set_ri
3656 TYPE(gto_basis_set_type),
POINTER :: orb_basis, ri_basis
3657 TYPE(mp_para_env_type),
POINTER :: para_env
3658 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
3659 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
3660 TYPE(qs_rho_type),
POINTER :: rho
3661 TYPE(section_vals_type),
POINTER :: input, print_section
3663 NULLIFY (rho_ao, input, print_section, logger, rho, particle_set, qs_kind_set, ri_basis, &
3664 para_env, blacs_env, fm_struct, orb_basis, dft_control)
3666 CALL get_qs_env(qs_env, input=input, dft_control=dft_control)
3667 logger => cp_get_default_logger()
3668 print_density = .false.
3669 print_ri_metric = .false.
3672 print_section => section_vals_get_subs_vals(input,
"DFT%XC%HF%RI%PRINT")
3673 IF (btest(cp_print_key_should_output(logger%iter_info, print_section,
"RI_DENSITY_COEFFS"), &
3674 cp_p_file)) print_density = .true.
3675 IF (btest(cp_print_key_should_output(logger%iter_info, print_section,
"RI_METRIC_2C_INTS"), &
3676 cp_p_file)) print_ri_metric = .true.
3679 IF (print_density .OR. print_ri_metric)
THEN
3682 CALL get_qs_env(qs_env, nkind=nkind, qs_kind_set=qs_kind_set, particle_set=particle_set)
3683 ALLOCATE (basis_set_ri(nkind), basis_set_ao(nkind))
3684 CALL basis_set_list_setup(basis_set_ri, ri_data%ri_basis_type, qs_kind_set)
3685 CALL get_particle_set(particle_set, qs_kind_set, basis=basis_set_ri)
3686 CALL basis_set_list_setup(basis_set_ao, ri_data%orb_basis_type, qs_kind_set)
3687 CALL get_particle_set(particle_set, qs_kind_set, basis=basis_set_ao)
3689 DO ibasis = 1, nkind
3690 ri_basis => basis_set_ri(ibasis)%gto_basis_set
3691 CALL init_interaction_radii_orb_basis(ri_basis, ri_data%eps_pgf_orb)
3692 orb_basis => basis_set_ao(ibasis)%gto_basis_set
3693 CALL init_interaction_radii_orb_basis(orb_basis, ri_data%eps_pgf_orb)
3697 IF (print_density)
THEN
3698 CALL get_qs_env(qs_env, rho=rho)
3699 CALL qs_rho_get(rho, rho_ao_kp=rho_ao)
3700 nspins =
SIZE(rho_ao, 1)
3702 CALL section_vals_val_get(print_section,
"RI_DENSITY_COEFFS%MULTIPLY_BY_RI_2C_INTEGRALS", l_val=mult_by_s)
3703 CALL section_vals_val_get(print_section,
"RI_DENSITY_COEFFS%SKIP_RI_METRIC", l_val=skip_ri_metric)
3705 IF (mult_by_s .AND. skip_ri_metric)
THEN
3706 cpabort(
"MULTIPLY_BY_RI_2C_INTEGRALS and SKIP_RI_METRIC are mutually exclusive.")
3709 CALL get_ri_density_coeffs(density_coeffs, rho_ao, 1, basis_set_ao, basis_set_ri, &
3710 mult_by_s, skip_ri_metric, ri_data, qs_env)
3712 CALL get_ri_density_coeffs(density_coeffs_2, rho_ao, 2, basis_set_ao, basis_set_ri, &
3713 mult_by_s, skip_ri_metric, ri_data, qs_env)
3715 unit_nr = cp_print_key_unit_nr(logger, input,
"DFT%XC%HF%RI%PRINT%RI_DENSITY_COEFFS", &
3716 extension=
".dat", file_status=
"REPLACE", &
3717 file_action=
"WRITE", file_form=
"FORMATTED")
3719 CALL section_vals_val_get(print_section,
"RI_DENSITY_COEFFS%FILE_FORMAT", c_val=rifmt)
3720 CALL uppercase(rifmt)
3722 IF (unit_nr > 0)
THEN
3727 IF (nspins == 1)
THEN
3728 WRITE (unit_nr, fmt=
"(A,A,A)") &
3729 "# Coefficients of the electronic density projected on the RI_HFX basis for ", &
3730 trim(logger%iter_info%project_name),
" project"
3731 DO i_ri = 1,
SIZE(density_coeffs)
3732 WRITE (unit_nr, fmt=
"(F20.12)") density_coeffs(i_ri)
3735 WRITE (unit_nr, fmt=
"(A,A,A)") &
3736 "# Coefficients of the electronic density projected on the RI_HFX basis for ", &
3737 trim(logger%iter_info%project_name),
" project. Spin up, spin down"
3738 DO i_ri = 1,
SIZE(density_coeffs)
3739 WRITE (unit_nr, fmt=
"(F20.12,F20.12)") density_coeffs(i_ri), density_coeffs_2(i_ri)
3743 WRITE (unit_nr, fmt=
"(A,A,A)") &
3744 "# Coefficients of the electronic density projected on the RI_HFX basis for ", &
3745 trim(logger%iter_info%project_name),
" project"
3747 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
3748 CALL get_cell(cell, periodic=periodic, h=hmat)
3749 natom =
SIZE(particle_set)
3752 CALL get_atomic_kind(particle_set(ia)%atomic_kind, kind_number=ikind)
3753 ri_basis => basis_set_ri(ikind)%gto_basis_set
3754 CALL get_gto_basis_set(gto_basis_set=ri_basis, nsgf=nsgf)
3757 IF (nspins == 1)
THEN
3758 WRITE (unit_nr, fmt=
"(I10,3I7,F20.12)") ib, ia, ikind, ibasis, &
3761 WRITE (unit_nr, fmt=
"(I10,3I7,F20.12,F20.12)") ib, ia, ikind, ibasis, &
3762 density_coeffs(ib), density_coeffs_2(ib)
3766 WRITE (unit_nr, fmt=
"(A)")
"# Cell Periodicity "
3767 WRITE (unit_nr, fmt=
"(3I5)") periodic
3768 WRITE (unit_nr, fmt=
"(A)")
"# Cell Matrix [Bohr]"
3769 WRITE (unit_nr, fmt=
"(3F20.12)") hmat(1, 1:3)
3770 WRITE (unit_nr, fmt=
"(3F20.12)") hmat(2, 1:3)
3771 WRITE (unit_nr, fmt=
"(3F20.12)") hmat(3, 1:3)
3772 WRITE (unit_nr, fmt=
"(A)")
"# El Type Number Coordinates [Bohr]"
3774 CALL get_atomic_kind(atomic_kind=particle_set(ia)%atomic_kind, &
3775 kind_number=atype, element_symbol=symbol)
3776 WRITE (unit_nr, fmt=
"(2X,A2,I5,I10,3F20.12)") symbol, atype, ia, particle_set(ia)%r(1:3)
3778 WRITE (unit_nr, fmt=
"(A)")
"# Basis Set Information"
3779 DO ibasis = 1, nkind
3780 ri_basis => basis_set_ri(ibasis)%gto_basis_set
3781 CALL get_gto_basis_set(gto_basis_set=ri_basis, nsgf=nsgf, npgf=npgf, &
3783 nset=nset, nshell=nshell, l=lshell)
3784 WRITE (unit_nr, fmt=
"(A)")
"# Basis Functions"
3785 WRITE (unit_nr, fmt=
"(I7,I15)") ibasis, nsgf
3786 WRITE (unit_nr, fmt=
"(A)")
"# Nr. l m set shell "
3789 DO ishell = 1, nshell(iset)
3790 l = lshell(ishell, iset)
3794 WRITE (unit_nr, fmt=
"(I6,I7,I8,2I8)") isgf, l, m, iset, ishell
3798 WRITE (unit_nr, fmt=
"(A)")
"# Basis set exponents and contractions "
3800 WRITE (unit_nr, fmt=
"(I7)") iset
3801 WRITE (unit_nr, fmt=
"(A)")
"# Exponent Shells ... "
3802 DO m = 1, npgf(iset)
3803 WRITE (unit_nr, fmt=
"(E18.12,50F18.12)") zet(m, iset), gcc(m, 1:nshell(iset), iset)
3811 CALL cp_print_key_finished_output(unit_nr, logger, input,
"DFT%XC%HF%RI%PRINT%RI_DENSITY_COEFFS")
3814 IF (print_ri_metric)
THEN
3816 CALL calc_ri_2c_ints(matrix_s, basis_set_ri, ri_data, qs_env)
3819 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
3820 CALL dbcsr_get_info(matrix_s(1), nfullrows_total=nrows, nfullcols_total=ncols)
3821 CALL cp_fm_struct_create(fm_struct, context=blacs_env, para_env=para_env, &
3822 nrow_global=nrows, ncol_global=ncols)
3823 CALL cp_fm_create(matrix_s_fm, fm_struct)
3825 CALL copy_dbcsr_to_fm(matrix_s(1), matrix_s_fm)
3826 CALL dbcsr_release(matrix_s(1))
3828 unit_nr = cp_print_key_unit_nr(logger, input,
"DFT%XC%HF%RI%PRINT%RI_METRIC_2C_INTS", &
3829 extension=
".fm", file_status=
"REPLACE", &
3830 file_action=
"WRITE", file_form=
"UNFORMATTED")
3831 CALL cp_fm_write_unformatted(matrix_s_fm, unit_nr)
3833 CALL cp_print_key_finished_output(unit_nr, logger, input,
"DFT%XC%HF%RI%PRINT%RI_METRIC_2C_INTS")
3835 CALL cp_fm_struct_release(fm_struct)
3836 CALL cp_fm_release(matrix_s_fm)
3840 IF (print_density .OR. print_ri_metric)
THEN
3841 DO ibasis = 1, nkind
3842 ri_basis => basis_set_ri(ibasis)%gto_basis_set
3843 CALL init_interaction_radii_orb_basis(ri_basis, dft_control%qs_control%eps_pgf_orb)
3844 orb_basis => basis_set_ao(ibasis)%gto_basis_set
3845 CALL init_interaction_radii_orb_basis(orb_basis, dft_control%qs_control%eps_pgf_orb)
3858 SUBROUTINE calc_ri_2c_ints(matrix_s, basis_set_RI, ri_data, qs_env)
3860 TYPE(dbcsr_type),
DIMENSION(1) :: matrix_s
3861 TYPE(gto_basis_set_p_type),
DIMENSION(:) :: basis_set_ri
3862 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
3863 TYPE(qs_environment_type),
POINTER :: qs_env
3865 INTEGER,
DIMENSION(:),
POINTER :: col_bsize, row_bsize
3866 TYPE(dbcsr_distribution_type) :: dbcsr_dist
3867 TYPE(distribution_2d_type),
POINTER :: dist_2d
3868 TYPE(neighbor_list_set_p_type),
DIMENSION(:), &
3871 NULLIFY (nl_2c, dist_2d, row_bsize, col_bsize)
3873 CALL get_qs_env(qs_env, distribution_2d=dist_2d)
3874 CALL cp_dbcsr_dist2d_to_dist(dist_2d, dbcsr_dist)
3875 ALLOCATE (row_bsize(
SIZE(ri_data%bsizes_RI)))
3876 ALLOCATE (col_bsize(
SIZE(ri_data%bsizes_RI)))
3877 row_bsize(:) = ri_data%bsizes_RI
3878 col_bsize(:) = ri_data%bsizes_RI
3880 CALL dbcsr_create(matrix_s(1),
"RI metric", dbcsr_dist, dbcsr_type_symmetric, row_bsize, col_bsize)
3882 CALL build_2c_neighbor_lists(nl_2c, basis_set_ri, basis_set_ri, ri_data%ri_metric, &
3883 "HFX_2c_nl_pot", qs_env, sym_ij=.true., dist_2d=dist_2d)
3884 CALL build_2c_integrals(matrix_s, ri_data%filter_eps_2c, qs_env, nl_2c, basis_set_ri, &
3885 basis_set_ri, ri_data%ri_metric)
3887 CALL release_neighbor_list_sets(nl_2c)
3888 CALL dbcsr_distribution_release(dbcsr_dist)
3889 DEALLOCATE (row_bsize, col_bsize)
3891 END SUBROUTINE calc_ri_2c_ints
3905 SUBROUTINE get_ri_density_coeffs(density_coeffs, rho_ao, ispin, basis_set_AO, basis_set_RI, &
3906 multiply_by_S, skip_ri_metric, ri_data, qs_env)
3908 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: density_coeffs
3909 TYPE(dbcsr_p_type),
DIMENSION(:, :) :: rho_ao
3910 INTEGER,
INTENT(IN) :: ispin
3911 TYPE(gto_basis_set_p_type),
DIMENSION(:) :: basis_set_ao, basis_set_ri
3912 LOGICAL,
INTENT(IN) :: multiply_by_s, skip_ri_metric
3913 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
3914 TYPE(qs_environment_type),
POINTER :: qs_env
3916 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_RI_density_coeffs'
3918 INTEGER :: a, b, handle, i_mem,
idx, n_dependent, &
3919 n_mem, n_mem_ri, natom, &
3920 nblk_per_thread, nblks, nkind
3921 INTEGER(int_8) :: nze
3922 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: batch_block_end, batch_block_start, &
3923 dist1, dist2, dist3, dummy1, dummy2, &
3925 INTEGER,
DIMENSION(2) :: ind, pdims_2d
3926 INTEGER,
DIMENSION(2, 3) :: bounds_cpy
3927 INTEGER,
DIMENSION(3) :: dims_3c, pcoord_3d, pdims_3d
3928 LOGICAL :: calc_ints, found
3929 REAL(dp) :: occ, threshold
3930 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :) :: blk
3931 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: blk_3d
3932 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
3933 TYPE(dbcsr_type) :: ri_2c_inv
3934 TYPE(dbcsr_type),
DIMENSION(1) :: ri_2c_ints
3935 TYPE(dbt_distribution_type) :: dist_2d, dist_3d
3936 TYPE(dbt_iterator_type) :: iter
3937 TYPE(dbt_pgrid_type) :: pgrid_2d, pgrid_3d
3938 TYPE(dbt_type) :: density_coeffs_t, density_tmp, rho_ao_t, &
3939 rho_ao_t_3d, rho_ao_tmp, t2c_ri_ints, &
3940 t2c_ri_inv, t2c_ri_tmp
3941 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_int_batched
3942 TYPE(dft_control_type),
POINTER :: dft_control
3943 TYPE(distribution_3d_type) :: dist_nl3c
3944 TYPE(mp_cart_type) :: mp_comm_t3c
3945 TYPE(mp_para_env_type),
POINTER :: para_env
3946 TYPE(neighbor_list_3c_type) :: nl_3c
3947 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
3948 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
3950 NULLIFY (dft_control, para_env, blacs_env, particle_set, qs_kind_set)
3952 CALL timeset(routinen, handle)
3958 IF (.NOT. ri_data%flavor == ri_pmat)
THEN
3959 cpabort(
"Can only calculate and print the RI density coefficients within the RHO flavor of RI-HFX")
3962 CALL get_qs_env(qs_env, dft_control=dft_control, para_env=para_env, blacs_env=blacs_env, nkind=nkind, &
3963 particle_set=particle_set, qs_kind_set=qs_kind_set, natom=natom)
3964 n_mem = ri_data%n_mem
3965 n_mem_ri = ri_data%n_mem_RI
3968 IF (.NOT. skip_ri_metric)
THEN
3969 CALL calc_ri_2c_ints(ri_2c_ints, basis_set_ri, ri_data, qs_env)
3970 CALL dbcsr_create(ri_2c_inv, template=ri_2c_ints(1), matrix_type=dbcsr_type_no_symmetry)
3972 SELECT CASE (ri_data%t2c_method)
3973 CASE (hfx_ri_do_2c_iter)
3974 threshold = max(ri_data%filter_eps, 1.0e-12_dp)
3975 CALL invert_hotelling(ri_2c_inv, ri_2c_ints(1), threshold=threshold, silent=.false.)
3976 CASE (hfx_ri_do_2c_cholesky)
3977 CALL dbcsr_copy(ri_2c_inv, ri_2c_ints(1))
3978 CALL cp_dbcsr_cholesky_decompose(ri_2c_inv, para_env=para_env, blacs_env=blacs_env)
3979 CALL cp_dbcsr_cholesky_invert(ri_2c_inv, para_env=para_env, blacs_env=blacs_env, uplo_to_full=.true.)
3980 CASE (hfx_ri_do_2c_diag)
3981 CALL dbcsr_copy(ri_2c_inv, ri_2c_ints(1))
3982 CALL cp_dbcsr_power(ri_2c_inv, -1.0_dp, ri_data%eps_eigval, n_dependent, &
3983 para_env, blacs_env, verbose=ri_data%unit_nr_dbcsr > 0)
3986 CALL dbt_create(ri_2c_ints(1), t2c_ri_tmp)
3987 CALL create_2c_tensor(t2c_ri_ints, dist1, dist2, ri_data%pgrid_2d, &
3988 ri_data%bsizes_RI_split, ri_data%bsizes_RI_split, &
3990 CALL dbt_create(t2c_ri_ints, t2c_ri_inv)
3992 CALL dbt_copy_matrix_to_tensor(ri_2c_ints(1), t2c_ri_tmp)
3993 CALL dbt_copy(t2c_ri_tmp, t2c_ri_ints, move_data=.true.)
3994 CALL dbt_filter(t2c_ri_ints, ri_data%filter_eps)
3996 CALL dbt_copy_matrix_to_tensor(ri_2c_inv, t2c_ri_tmp)
3997 CALL dbt_copy(t2c_ri_tmp, t2c_ri_inv, move_data=.true.)
3998 CALL dbt_filter(t2c_ri_inv, ri_data%filter_eps)
4000 CALL dbcsr_release(ri_2c_ints(1))
4001 CALL dbcsr_release(ri_2c_inv)
4002 CALL dbt_destroy(t2c_ri_tmp)
4003 DEALLOCATE (dist1, dist2)
4007 CALL dbt_create(rho_ao(ispin, 1)%matrix, rho_ao_tmp)
4008 CALL create_2c_tensor(rho_ao_t, dist1, dist2, ri_data%pgrid_2d, &
4009 ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
4011 DEALLOCATE (dist1, dist2)
4013 CALL dbt_copy_matrix_to_tensor(rho_ao(ispin, 1)%matrix, rho_ao_tmp)
4014 CALL dbt_copy(rho_ao_tmp, rho_ao_t, move_data=.true.)
4015 CALL dbt_filter(rho_ao_t, ri_data%filter_eps)
4016 CALL dbt_destroy(rho_ao_tmp)
4019 ALLOCATE (dist1(
SIZE(ri_data%bsizes_AO_split)), dist2(
SIZE(ri_data%bsizes_AO_split)), dist3(1))
4021 CALL dbt_get_info(rho_ao_t, pdims=pdims_2d, proc_dist_1=dist1, proc_dist_2=dist2)
4022 CALL dbt_default_distvec(1, 1, [1], dist3)
4024 pdims_3d(1) = pdims_2d(1)
4025 pdims_3d(2) = pdims_2d(2)
4028 CALL dbt_pgrid_create(para_env, pdims_3d, pgrid_3d)
4029 CALL dbt_distribution_new(dist_3d, pgrid_3d, dist1, dist2, dist3)
4030 CALL dbt_create(rho_ao_t_3d,
"rho_ao_3d", dist_3d, [1, 2], [3], ri_data%bsizes_AO_split, &
4031 ri_data%bsizes_AO_split, [1])
4032 DEALLOCATE (dist1, dist2, dist3)
4033 CALL dbt_pgrid_destroy(pgrid_3d)
4034 CALL dbt_distribution_destroy(dist_3d)
4041 CALL dbt_iterator_start(iter, rho_ao_t)
4042 DO WHILE (dbt_iterator_blocks_left(iter))
4043 CALL dbt_iterator_next_block(iter, ind)
4044 CALL dbt_get_block(rho_ao_t, ind, blk, found)
4051 CALL dbt_iterator_stop(iter)
4054 ALLOCATE (idx1(nblks),
idx2(nblks),
idx3(nblks))
4060 CALL dbt_iterator_start(iter, rho_ao_t)
4061 DO WHILE (dbt_iterator_blocks_left(iter))
4062 CALL dbt_iterator_next_block(iter, ind)
4063 CALL dbt_get_block(rho_ao_t, ind, blk, found)
4067 idx1(nblks) = ind(1)
4068 idx2(nblks) = ind(2)
4073 CALL dbt_iterator_stop(iter)
4077 nblk_per_thread = nblks/omp_get_num_threads() + 1
4078 a = omp_get_thread_num()*nblk_per_thread + 1
4079 b = min(a + nblk_per_thread, nblks)
4080 CALL dbt_reserve_blocks(rho_ao_t_3d, idx1(a:b),
idx2(a:b),
idx3(a:b))
4086 CALL dbt_iterator_start(iter, rho_ao_t)
4087 DO WHILE (dbt_iterator_blocks_left(iter))
4088 CALL dbt_iterator_next_block(iter, ind)
4089 CALL dbt_get_block(rho_ao_t, ind, blk, found)
4091 ALLOCATE (blk_3d(
SIZE(blk, 1),
SIZE(blk, 2), 1))
4092 blk_3d(:, :, 1) = blk(:, :)
4094 CALL dbt_put_block(rho_ao_t_3d, [ind(1), ind(2), 1], [
SIZE(blk, 1),
SIZE(blk, 2), 1], blk_3d)
4096 DEALLOCATE (blk, blk_3d)
4099 CALL dbt_iterator_stop(iter)
4103 pdims_2d(1) = para_env%num_pe
4106 ALLOCATE (dist1(
SIZE(ri_data%bsizes_RI_split)), dist2(1))
4107 CALL dbt_default_distvec(
SIZE(ri_data%bsizes_RI_split), pdims_2d(1), ri_data%bsizes_RI_split, dist1)
4108 CALL dbt_default_distvec(1, pdims_2d(2), [1], dist2)
4110 CALL dbt_pgrid_create(para_env, pdims_2d, pgrid_2d)
4111 CALL dbt_distribution_new(dist_2d, pgrid_2d, dist1, dist2)
4112 CALL dbt_create(density_coeffs_t,
"density_coeffs", dist_2d, [1], [2], ri_data%bsizes_RI_split, [1])
4113 CALL dbt_create(density_coeffs_t, density_tmp)
4114 DEALLOCATE (dist1, dist2)
4115 CALL dbt_pgrid_destroy(pgrid_2d)
4116 CALL dbt_distribution_destroy(dist_2d)
4118 CALL dbt_get_info(ri_data%t_3c_int_ctr_3(1, 1), nfull_total=dims_3c)
4122 CALL dbt_pgrid_create(para_env, pdims_3d, pgrid_3d, tensor_dims=[max(1, natom/n_mem), natom, natom])
4123 ALLOCATE (t_3c_int_batched(1, 1))
4124 CALL create_3c_tensor(t_3c_int_batched(1, 1), dist1, dist2, dist3, pgrid_3d, &
4125 ri_data%bsizes_RI, ri_data%bsizes_AO, ri_data%bsizes_AO, map1=[1], map2=[2, 3], &
4126 name=
"(RI | AO AO)")
4128 CALL dbt_mp_environ_pgrid(pgrid_3d, pdims_3d, pcoord_3d)
4129 CALL mp_comm_t3c%create(pgrid_3d%mp_comm_2d, 3, pdims_3d)
4130 CALL distribution_3d_create(dist_nl3c, dist1, dist2, dist3, nkind, particle_set, &
4131 mp_comm_t3c, own_comm=.true.)
4132 DEALLOCATE (dist1, dist2, dist3)
4133 CALL dbt_pgrid_destroy(pgrid_3d)
4135 CALL build_3c_neighbor_lists(nl_3c, basis_set_ri, basis_set_ao, basis_set_ao, dist_nl3c, ri_data%ri_metric, &
4136 "HFX_3c_nl", qs_env, op_pos=1, sym_jk=.true., own_dist=.true.)
4138 n_mem = ri_data%n_mem
4139 CALL create_tensor_batches(ri_data%bsizes_RI, n_mem, dummy1, dummy2, batch_block_start, batch_block_end)
4142 CALL get_tensor_occupancy(ri_data%t_3c_int_ctr_2(1, 1), nze, occ)
4143 IF (nze == 0) calc_ints = .true.
4147 CALL build_3c_integrals(t_3c_int_batched, ri_data%filter_eps, qs_env, nl_3c, &
4148 basis_set_ri, basis_set_ao, basis_set_ao, &
4149 ri_data%ri_metric, int_eps=ri_data%eps_schwarz, op_pos=1, &
4150 desymmetrize=.false., &
4151 bounds_i=[batch_block_start(i_mem), batch_block_end(i_mem)])
4152 CALL dbt_copy(t_3c_int_batched(1, 1), ri_data%t_3c_int_ctr_3(1, 1), order=[1, 3, 2])
4153 CALL dbt_copy(t_3c_int_batched(1, 1), ri_data%t_3c_int_ctr_3(1, 1), move_data=.true., summation=.true.)
4154 CALL dbt_filter(ri_data%t_3c_int_ctr_3(1, 1), ri_data%filter_eps)
4156 bounds_cpy(:, 2) = [sum(ri_data%bsizes_RI(1:batch_block_start(i_mem) - 1)) + 1, &
4157 sum(ri_data%bsizes_RI(1:batch_block_end(i_mem)))]
4158 bounds_cpy(:, 1) = [1, sum(ri_data%bsizes_AO)]
4159 bounds_cpy(:, 3) = [1, sum(ri_data%bsizes_AO)]
4160 CALL dbt_copy(ri_data%t_3c_int_ctr_2(1, 1), ri_data%t_3c_int_ctr_3(1, 1), &
4161 order=[2, 1, 3], bounds=bounds_cpy)
4165 CALL dbt_contract(1.0_dp, ri_data%t_3c_int_ctr_3(1, 1), rho_ao_t_3d, 0.0_dp, density_tmp, &
4166 contract_1=[2, 3], notcontract_1=[1], &
4167 contract_2=[1, 2], notcontract_2=[3], &
4168 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps)
4169 CALL dbt_clear(ri_data%t_3c_int_ctr_3(1, 1))
4171 IF (skip_ri_metric)
THEN
4172 CALL dbt_copy(density_tmp, density_coeffs_t, move_data=.true.)
4175 CALL dbt_contract(1.0_dp, t2c_ri_inv, density_tmp, 1.0_dp, density_coeffs_t, &
4176 contract_1=[2], notcontract_1=[1], &
4177 contract_2=[1], notcontract_2=[2], &
4178 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps)
4182 CALL neighbor_list_3c_destroy(nl_3c)
4184 IF (multiply_by_s)
THEN
4185 CALL dbt_contract(1.0_dp, t2c_ri_ints, density_coeffs_t, 0.0_dp, density_tmp, &
4186 contract_1=[2], notcontract_1=[1], &
4187 contract_2=[1], notcontract_2=[2], &
4188 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps)
4189 CALL dbt_copy(density_tmp, density_coeffs_t, move_data=.true.)
4192 ALLOCATE (density_coeffs(sum(ri_data%bsizes_RI)))
4193 density_coeffs = 0.0
4198 CALL dbt_iterator_start(iter, density_coeffs_t)
4199 DO WHILE (dbt_iterator_blocks_left(iter))
4200 CALL dbt_iterator_next_block(iter, ind)
4201 CALL dbt_get_block(density_coeffs_t, ind, blk, found)
4204 idx = sum(ri_data%bsizes_RI_split(1:ind(1) - 1))
4206 density_coeffs(
idx + 1:
idx + ri_data%bsizes_RI_split(ind(1))) = blk(:, 1)
4211 CALL dbt_iterator_stop(iter)
4213 CALL para_env%sum(density_coeffs)
4215 CALL dbt_destroy(density_tmp)
4216 CALL dbt_destroy(rho_ao_t)
4217 CALL dbt_destroy(rho_ao_t_3d)
4218 CALL dbt_destroy(density_coeffs_t)
4219 CALL dbt_destroy(t_3c_int_batched(1, 1))
4221 IF (.NOT. skip_ri_metric)
THEN
4222 CALL dbt_destroy(t2c_ri_ints)
4223 CALL dbt_destroy(t2c_ri_inv)
4226 CALL timestop(handle)
4228 END SUBROUTINE get_ri_density_coeffs
4238 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: idx_to_at
4239 INTEGER,
DIMENSION(:),
INTENT(IN) :: bsizes_split, bsizes_orig
4241 INTEGER :: full_sum, iat, iblk, split_sum
4244 full_sum = bsizes_orig(iat)
4246 DO iblk = 1,
SIZE(bsizes_split)
4247 split_sum = split_sum + bsizes_split(iblk)
4249 IF (split_sum .GT. full_sum)
THEN
4251 full_sum = full_sum + bsizes_orig(iat)
4254 idx_to_at(iblk) = iat
4264 FUNCTION my_sqrt(values)
4265 REAL(kind=dp),
DIMENSION(:),
INTENT(IN) :: values
4266 REAL(kind=dp),
DIMENSION(SIZE(values)) :: my_sqrt
4268 my_sqrt = sqrt(values)
4276 FUNCTION my_invsqrt(values)
4277 REAL(kind=dp),
DIMENSION(:),
INTENT(IN) :: values
4278 REAL(kind=dp),
DIMENSION(SIZE(values)) :: my_invsqrt
4280 my_invsqrt = sqrt(1.0_dp/values)
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.
arnoldi iteration using dbcsr
subroutine, public arnoldi_extremal(matrix_a, max_ev, min_ev, converged, threshold, max_iter)
simple wrapper to estimate extremal eigenvalues with arnoldi, using the old lanczos interface this hi...
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
subroutine, public get_gto_basis_set(gto_basis_set, name, aliases, norm_type, kind_radius, ncgf, nset, nsgf, cgf_symbol, sgf_symbol, norm_cgf, set_radius, lmax, lmin, lx, ly, lz, m, ncgf_set, npgf, nsgf_set, nshell, cphi, pgf_radius, sphi, scon, zet, first_cgf, first_sgf, l, last_cgf, last_sgf, n, gcc, maxco, maxl, maxpgf, maxsgf_set, maxshell, maxso, nco_sum, npgf_sum, nshell_sum, maxder, short_kind_radius, npgf_seg_sum)
...
Handles all functions related to the CELL.
subroutine, public get_cell(cell, alpha, beta, gamma, deth, orthorhombic, abc, periodic, h, h_inv, symmetry_id, tag)
Get informations about a simulation cell.
methods related to the blacs parallel environment
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_distribution_release(dist)
...
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
subroutine, public dbcsr_desymmetrize(matrix_a, matrix_b)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_filter(matrix, eps)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_complete_redistribute(matrix, redist)
...
integer function, public dbcsr_get_num_blocks(matrix)
...
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)
...
Interface to (sca)lapack for the Cholesky based procedures.
subroutine, public cp_dbcsr_cholesky_decompose(matrix, n, para_env, blacs_env)
used to replace a symmetric positive def. matrix M with its cholesky decomposition U: M = U^T * U,...
subroutine, public cp_dbcsr_cholesky_invert(matrix, n, para_env, blacs_env, uplo_to_full)
used to replace the cholesky decomposition by the inverse
subroutine, public dbcsr_add_on_diag(matrix, alpha)
Adds the given scalar to the diagonal of the matrix. Reserves any missing diagonal blocks.
real(dp) function, public dbcsr_frobenius_norm(matrix)
Compute the frobenius norm of a dbcsr matrix.
subroutine, public dbcsr_dot(matrix_a, matrix_b, trace)
Computes the dot product of two matrices, also known as the trace of their matrix product.
Interface to (sca)lapack for the Cholesky based procedures.
subroutine, public cp_dbcsr_power(matrix, exponent, threshold, n_dependent, para_env, blacs_env, verbose, eigenvectors, eigenvalues)
...
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_dist2d_to_dist(dist2d, dist)
Creates a DBCSR distribution from a distribution_2d.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
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_write_unformatted(fm, unit)
...
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
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...
This is the start of a dbt_api, all publically needed functions are exported here....
stores a mapping of 2D info (e.g. matrix) on a 2D processor distribution (i.e. blacs grid) where cpus...
subroutine, public hfx_ri_update_ks(qs_env, ri_data, ks_matrix, ehfx, mos, rho_ao, geometry_did_change, nspins, hf_fraction)
...
subroutine, public check_inverse(matrix_1, matrix_2, name, unit_nr)
...
subroutine, public get_force_from_3c_trace(force, t_3c_contr, t_3c_der, atom_of_kind, kind_of, idx_to_at, pref, do_mp2, deriv_dim)
This routines calculates the force contribution from a trace over 3D tensors, i.e....
subroutine, public get_idx_to_atom(idx_to_at, bsizes_split, bsizes_orig)
a small utility function that returns the atom corresponding to a block of a split tensor
subroutine, public hfx_ri_pre_scf_calc_tensors(qs_env, ri_data, t_2c_int_ri, t_2c_int_pot, t_3c_int, do_kpoints)
Calculate 2-center and 3-center integrals.
subroutine, public hfx_ri_update_forces(qs_env, ri_data, nspins, hf_fraction, rho_ao, rho_ao_resp, mos, use_virial, resp_only, rescale_factor)
the general routine that calls the relevant force code
subroutine, public print_ri_hfx(ri_data, qs_env)
Print RI-HFX quantities, as required by the PRINT subsection.
subroutine, public get_2c_der_force(force, t_2c_contr, t_2c_der, atom_of_kind, kind_of, idx_to_at, pref, do_mp2, do_ovlp)
Update the forces due to the derivative of the a 2-center product d/dR (Q|R)
Types and set/get functions for HFX.
subroutine, public alloc_containers(data, bin_size)
...
subroutine, public dealloc_containers(data, memory_usage)
...
subroutine, public hfx_ri_init(ri_data, qs_kind_set, particle_set, atomic_kind_set, para_env)
...
subroutine, public hfx_ri_release(ri_data, write_stats)
...
Routines useful for iterative matrix calculations.
subroutine, public invert_hotelling(matrix_inverse, matrix, threshold, use_inv_as_guess, norm_convergence, filter_eps, accelerator_order, max_iter_lanczos, eps_lanczos, silent)
invert a symmetric positive definite matrix by Hotelling's method explicit symmetrization makes this ...
subroutine, public matrix_sqrt_newton_schulz(matrix_sqrt, matrix_sqrt_inv, matrix, threshold, order, eps_lanczos, max_iter_lanczos, symmetrize, converged, iounit)
compute the sqrt of a matrix via the sign function and the corresponding Newton-Schulz iterations the...
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
integer, parameter, public default_string_length
Machine interface based on Fortran 2003 and POSIX.
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Interface to the message passing library MPI.
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public nso
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.
Calculate the interaction radii for the operator matrix calculation.
subroutine, public init_interaction_radii_orb_basis(orb_basis_set, eps_pgf_orb, eps_pgf_short)
...
Define the quickstep kind type and their sub types.
Definition and initialisation of the mo data type.
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
Define the neighbor list data types and the corresponding functionality.
subroutine, public release_neighbor_list_sets(nlists)
releases an array of neighbor_list_sets
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
Utility methods to build 3-center integral tensors of various types.
subroutine, public distribution_3d_create(dist_3d, dist1, dist2, dist3, nkind, particle_set, mp_comm_3d, own_comm)
Create a 3d distribution.
subroutine, public create_2c_tensor(t2c, dist_1, dist_2, pgrid, sizes_1, sizes_2, order, name)
...
subroutine, public split_block_sizes(blk_sizes, blk_sizes_split, max_size)
...
subroutine, public create_tensor_batches(sizes, nbatches, starts_array, ends_array, starts_array_block, ends_array_block)
...
subroutine, public create_3c_tensor(t3c, dist_1, dist_2, dist_3, pgrid, sizes_1, sizes_2, sizes_3, map1, map2, name)
...
Utility methods to build 3-center integral tensors of various types.
subroutine, public build_2c_integrals(t2c, filter_eps, qs_env, nl_2c, basis_i, basis_j, potential_parameter, do_kpoints, do_hfx_kpoints, ext_kpoints, regularization_ri)
...
subroutine, public calc_3c_virial(work_virial, t3c_trace, pref, qs_env, nl_3c, basis_i, basis_j, basis_k, potential_parameter, der_eps, op_pos)
Calculates the 3c virial contributions on the fly.
subroutine, public build_3c_derivatives(t3c_der_i, t3c_der_k, filter_eps, qs_env, nl_3c, basis_i, basis_j, basis_k, potential_parameter, der_eps, op_pos, do_kpoints, do_hfx_kpoints, bounds_i, bounds_j, bounds_k, ri_range, img_to_ri_cell)
Build 3-center derivative tensors.
subroutine, public build_2c_neighbor_lists(ij_list, basis_i, basis_j, potential_parameter, name, qs_env, sym_ij, molecular, dist_2d, pot_to_rad)
Build 2-center neighborlists adapted to different operators This mainly wraps build_neighbor_lists fo...
subroutine, public build_3c_integrals(t3c, filter_eps, qs_env, nl_3c, basis_i, basis_j, basis_k, potential_parameter, int_eps, op_pos, do_kpoints, do_hfx_kpoints, desymmetrize, cell_sym, bounds_i, bounds_j, bounds_k, ri_range, img_to_ri_cell, cell_to_index_ext)
Build 3-center integral tensor.
subroutine, public compress_tensor(tensor, blk_indices, compressed, eps, memory)
...
subroutine, public neighbor_list_3c_destroy(ijk_list)
Destroy 3c neighborlist.
subroutine, public calc_2c_virial(work_virial, t2c_trace, pref, qs_env, nl_2c, basis_i, basis_j, potential_parameter)
Calculates the virial coming from 2c derivatives on the fly.
subroutine, public decompress_tensor(tensor, blk_indices, compressed, eps)
...
subroutine, public build_2c_derivatives(t2c_der, filter_eps, qs_env, nl_2c, basis_i, basis_j, potential_parameter, do_kpoints)
Calculates the derivatives of 2-center integrals, wrt to the first center.
subroutine, public get_tensor_occupancy(tensor, nze, occ)
...
subroutine, public build_3c_neighbor_lists(ijk_list, basis_i, basis_j, basis_k, dist_3d, potential_parameter, name, qs_env, sym_ij, sym_jk, sym_ik, molecular, op_pos, own_dist)
Build a 3-center neighbor list.
Utilities for string manipulations.
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.
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...
distributes pairs on a 2d grid of processors
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.
calculation environment to calculate the ks matrix, holds all the needed vars. assumes that the core ...
keeps the density in various representations, keeping track of which ones are valid.