14 USE omp_lib,
ONLY: omp_get_num_threads,&
44 USE dbcsr_api,
ONLY: &
45 dbcsr_add, dbcsr_add_on_diag, dbcsr_complete_redistribute, dbcsr_copy, dbcsr_create, &
46 dbcsr_desymmetrize, dbcsr_distribution_get, dbcsr_distribution_release, &
47 dbcsr_distribution_type, dbcsr_dot, dbcsr_filter, dbcsr_frobenius_norm, dbcsr_get_info, &
48 dbcsr_get_num_blocks, dbcsr_multiply, dbcsr_p_type, dbcsr_release, dbcsr_scale, &
49 dbcsr_type, dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, dbcsr_type_symmetric
51 dbt_batched_contract_finalize, dbt_batched_contract_init, dbt_clear, dbt_contract, &
52 dbt_copy, dbt_copy_matrix_to_tensor, dbt_copy_tensor_to_matrix, dbt_create, &
53 dbt_default_distvec, dbt_destroy, dbt_distribution_destroy, dbt_distribution_new, &
54 dbt_distribution_type, dbt_filter, dbt_get_block, dbt_get_info, dbt_get_num_blocks_total, &
55 dbt_iterator_blocks_left, dbt_iterator_next_block, dbt_iterator_start, dbt_iterator_stop, &
56 dbt_iterator_type, dbt_mp_environ_pgrid, dbt_nd_mp_comm, dbt_pgrid_create, &
57 dbt_pgrid_destroy, dbt_pgrid_type, dbt_put_block, dbt_reserve_blocks, dbt_scale, dbt_type
62 hfx_compression_type,&
106 distribution_3d_type,&
107 neighbor_list_3c_type,&
111 #include "./base/base_uses.f90"
121 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'hfx_ri'
130 SUBROUTINE switch_ri_flavor(ri_data, qs_env)
131 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
132 TYPE(qs_environment_type),
POINTER :: qs_env
134 CHARACTER(LEN=*),
PARAMETER :: routineN =
'switch_ri_flavor'
136 INTEGER :: handle, n_mem, new_flavor
137 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
138 TYPE(dft_control_type),
POINTER :: dft_control
139 TYPE(mp_para_env_type),
POINTER :: para_env
140 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
141 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
143 NULLIFY (qs_kind_set, particle_set, atomic_kind_set, para_env, dft_control)
145 CALL timeset(routinen, handle)
147 CALL get_qs_env(qs_env, para_env=para_env, dft_control=dft_control, atomic_kind_set=atomic_kind_set, &
148 particle_set=particle_set, qs_kind_set=qs_kind_set)
152 IF (ri_data%flavor ==
ri_pmat)
THEN
157 ri_data%flavor = new_flavor
159 n_mem = ri_data%n_mem_input
160 ri_data%n_mem_input = ri_data%n_mem_flavor_switch
161 ri_data%n_mem_flavor_switch = n_mem
163 CALL hfx_ri_init(ri_data, qs_kind_set, particle_set, atomic_kind_set, para_env)
168 IF (ri_data%flavor ==
ri_pmat)
THEN
169 CALL hfx_ri_pre_scf_pmat(qs_env, ri_data)
171 CALL hfx_ri_pre_scf_mo(qs_env, ri_data, dft_control%nspins)
174 IF (ri_data%unit_nr > 0)
THEN
175 IF (ri_data%flavor ==
ri_pmat)
THEN
176 WRITE (ri_data%unit_nr,
'(T2,A)')
"HFX_RI_INFO| temporarily switched to RI_FLAVOR RHO"
178 WRITE (ri_data%unit_nr,
'(T2,A)')
"HFX_RI_INFO| temporarily switched to RI_FLAVOR MO"
182 CALL timestop(handle)
184 END SUBROUTINE switch_ri_flavor
196 SUBROUTINE hfx_ri_pre_scf_mo(qs_env, ri_data, nspins)
197 TYPE(qs_environment_type),
POINTER :: qs_env
198 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
199 INTEGER,
INTENT(IN) :: nspins
201 CHARACTER(LEN=*),
PARAMETER :: routineN =
'hfx_ri_pre_scf_mo'
203 INTEGER :: handle, handle2, ispin, n_dependent, &
204 unit_nr, unit_nr_dbcsr
205 REAL(KIND=
dp) :: threshold
206 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
207 TYPE(dbcsr_type),
DIMENSION(1) :: dbcsr_work_1, dbcsr_work_2, t_2c_int_mat, t_2c_op_pot, &
208 t_2c_op_pot_sqrt, t_2c_op_pot_sqrt_inv, t_2c_op_RI, t_2c_op_RI_inv
209 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:) :: t_2c_int, t_2c_work
210 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_int
211 TYPE(mp_para_env_type),
POINTER :: para_env
213 CALL timeset(routinen, handle)
215 unit_nr_dbcsr = ri_data%unit_nr_dbcsr
216 unit_nr = ri_data%unit_nr
218 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
220 CALL timeset(routinen//
"_int", handle2)
222 ALLOCATE (t_2c_int(1), t_2c_work(1), t_3c_int(1, 1))
225 CALL timestop(handle2)
227 CALL timeset(routinen//
"_2c", handle2)
228 IF (.NOT. ri_data%same_op)
THEN
229 SELECT CASE (ri_data%t2c_method)
231 CALL dbcsr_create(t_2c_op_ri_inv(1), template=t_2c_op_ri(1), matrix_type=dbcsr_type_no_symmetry)
232 threshold = max(ri_data%filter_eps, 1.0e-12_dp)
233 CALL invert_hotelling(t_2c_op_ri_inv(1), t_2c_op_ri(1), threshold=threshold, silent=.false.)
235 CALL dbcsr_copy(t_2c_op_ri_inv(1), t_2c_op_ri(1))
239 CALL dbcsr_copy(t_2c_op_ri_inv(1), t_2c_op_ri(1))
240 CALL cp_dbcsr_power(t_2c_op_ri_inv(1), -1.0_dp, ri_data%eps_eigval, n_dependent, &
241 para_env, blacs_env, verbose=ri_data%unit_nr_dbcsr > 0)
244 IF (ri_data%check_2c_inv)
THEN
245 CALL check_inverse(t_2c_op_ri_inv(1), t_2c_op_ri(1), unit_nr=unit_nr)
248 CALL dbcsr_release(t_2c_op_ri(1))
250 SELECT CASE (ri_data%t2c_method)
252 CALL dbcsr_create(t_2c_op_pot_sqrt(1), template=t_2c_op_pot(1), matrix_type=dbcsr_type_symmetric)
253 CALL dbcsr_create(t_2c_op_pot_sqrt_inv(1), template=t_2c_op_pot(1), matrix_type=dbcsr_type_symmetric)
255 ri_data%filter_eps, ri_data%t2c_sqrt_order, ri_data%eps_lanczos, &
256 ri_data%max_iter_lanczos)
258 CALL dbcsr_release(t_2c_op_pot_sqrt_inv(1))
260 CALL dbcsr_copy(t_2c_op_pot_sqrt(1), t_2c_op_pot(1))
261 CALL cp_dbcsr_power(t_2c_op_pot_sqrt(1), 0.5_dp, ri_data%eps_eigval, n_dependent, &
262 para_env, blacs_env, verbose=ri_data%unit_nr_dbcsr > 0)
266 CALL dbt_create(t_2c_op_ri_inv(1), t_2c_work(1))
267 CALL dbt_copy_matrix_to_tensor(t_2c_op_ri_inv(1), t_2c_work(1))
268 CALL dbt_copy(t_2c_work(1), ri_data%t_2c_inv(1, 1), move_data=.true.)
269 CALL dbt_destroy(t_2c_work(1))
270 CALL dbt_filter(ri_data%t_2c_inv(1, 1), ri_data%filter_eps)
272 CALL dbt_create(t_2c_op_pot(1), t_2c_work(1))
273 CALL dbt_copy_matrix_to_tensor(t_2c_op_pot(1), t_2c_work(1))
274 CALL dbt_copy(t_2c_work(1), ri_data%t_2c_pot(1, 1), move_data=.true.)
275 CALL dbt_destroy(t_2c_work(1))
276 CALL dbt_filter(ri_data%t_2c_pot(1, 1), ri_data%filter_eps)
278 IF (ri_data%check_2c_inv)
THEN
279 CALL check_sqrt(t_2c_op_pot(1), matrix_sqrt=t_2c_op_pot_sqrt(1), unit_nr=unit_nr)
281 CALL dbcsr_create(t_2c_int_mat(1), template=t_2c_op_pot(1), matrix_type=dbcsr_type_no_symmetry)
282 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, t_2c_op_ri_inv(1), t_2c_op_pot_sqrt(1), &
283 0.0_dp, t_2c_int_mat(1), filter_eps=ri_data%filter_eps)
284 CALL dbcsr_release(t_2c_op_ri_inv(1))
285 CALL dbcsr_release(t_2c_op_pot_sqrt(1))
287 SELECT CASE (ri_data%t2c_method)
289 CALL dbcsr_create(t_2c_int_mat(1), template=t_2c_op_pot(1), matrix_type=dbcsr_type_symmetric)
290 CALL dbcsr_create(t_2c_op_pot_sqrt(1), template=t_2c_op_pot(1), matrix_type=dbcsr_type_symmetric)
292 ri_data%filter_eps, ri_data%t2c_sqrt_order, ri_data%eps_lanczos, &
293 ri_data%max_iter_lanczos)
294 CALL dbcsr_release(t_2c_op_pot_sqrt(1))
296 CALL dbcsr_copy(t_2c_int_mat(1), t_2c_op_pot(1))
297 CALL cp_dbcsr_power(t_2c_int_mat(1), -0.5_dp, ri_data%eps_eigval, n_dependent, &
298 para_env, blacs_env, verbose=ri_data%unit_nr_dbcsr > 0)
300 IF (ri_data%check_2c_inv)
THEN
301 CALL check_sqrt(t_2c_op_pot(1), matrix_sqrt_inv=t_2c_int_mat(1), unit_nr=unit_nr)
305 CALL dbcsr_copy(dbcsr_work_1(1), t_2c_int_mat(1))
306 CALL dbcsr_create(dbcsr_work_2(1), template=t_2c_int_mat(1))
307 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, dbcsr_work_1(1), t_2c_int_mat(1), 0.0_dp, dbcsr_work_2(1))
308 CALL dbcsr_release(dbcsr_work_1(1))
309 CALL dbt_create(dbcsr_work_2(1), t_2c_work(1))
310 CALL dbt_copy_matrix_to_tensor(dbcsr_work_2(1), t_2c_work(1))
311 CALL dbcsr_release(dbcsr_work_2(1))
312 CALL dbt_copy(t_2c_work(1), ri_data%t_2c_inv(1, 1), move_data=.true.)
313 CALL dbt_destroy(t_2c_work(1))
314 CALL dbt_filter(ri_data%t_2c_inv(1, 1), ri_data%filter_eps)
317 CALL dbcsr_release(t_2c_op_pot(1))
319 CALL dbt_create(t_2c_int_mat(1), t_2c_int(1), name=
"(RI|RI)")
320 CALL dbt_copy_matrix_to_tensor(t_2c_int_mat(1), t_2c_int(1))
321 CALL dbcsr_release(t_2c_int_mat(1))
323 CALL dbt_copy(t_2c_int(1), ri_data%t_2c_int(ispin, 1))
325 CALL dbt_destroy(t_2c_int(1))
326 CALL timestop(handle2)
328 CALL timeset(routinen//
"_3c", handle2)
329 CALL dbt_copy(t_3c_int(1, 1), ri_data%t_3c_int_ctr_1(1, 1), order=[2, 1, 3], move_data=.true.)
330 CALL dbt_filter(ri_data%t_3c_int_ctr_1(1, 1), ri_data%filter_eps)
331 CALL dbt_copy(ri_data%t_3c_int_ctr_1(1, 1), ri_data%t_3c_int_ctr_2(1, 1))
332 CALL dbt_destroy(t_3c_int(1, 1))
333 CALL timestop(handle2)
335 CALL timestop(handle)
347 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_1, matrix_2
348 CHARACTER(len=*),
INTENT(IN),
OPTIONAL :: name
349 INTEGER,
INTENT(IN) :: unit_nr
351 CHARACTER(len=default_string_length) :: name_prv
352 REAL(kind=
dp) :: error, frob_matrix, frob_matrix_base
353 TYPE(dbcsr_type) :: matrix_tmp
355 IF (
PRESENT(name))
THEN
358 CALL dbcsr_get_info(matrix_1, name=name_prv)
361 CALL dbcsr_create(matrix_tmp, template=matrix_1)
362 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_1, matrix_2, &
364 frob_matrix_base = dbcsr_frobenius_norm(matrix_tmp)
365 CALL dbcsr_add_on_diag(matrix_tmp, -1.0_dp)
366 frob_matrix = dbcsr_frobenius_norm(matrix_tmp)
367 error = frob_matrix/frob_matrix_base
368 IF (unit_nr > 0)
THEN
369 WRITE (unit=unit_nr, fmt=
"(T3,A,A,A,T73,ES8.1)") &
370 "HFX_RI_INFO| Error for INV(", trim(name_prv),
"):", error
373 CALL dbcsr_release(matrix_tmp)
384 SUBROUTINE check_sqrt(matrix, matrix_sqrt, matrix_sqrt_inv, name, unit_nr)
385 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix
386 TYPE(dbcsr_type),
INTENT(IN),
OPTIONAL :: matrix_sqrt, matrix_sqrt_inv
387 CHARACTER(len=*),
INTENT(IN),
OPTIONAL :: name
388 INTEGER,
INTENT(IN) :: unit_nr
390 CHARACTER(len=default_string_length) :: name_prv
391 REAL(kind=
dp) :: frob_matrix
392 TYPE(dbcsr_type) :: matrix_copy, matrix_tmp
394 IF (
PRESENT(name))
THEN
397 CALL dbcsr_get_info(matrix, name=name_prv)
399 IF (
PRESENT(matrix_sqrt))
THEN
400 CALL dbcsr_create(matrix_tmp, template=matrix)
401 CALL dbcsr_copy(matrix_copy, matrix_sqrt)
402 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_sqrt, matrix_copy, &
404 CALL dbcsr_add(matrix_tmp, matrix, 1.0_dp, -1.0_dp)
405 frob_matrix = dbcsr_frobenius_norm(matrix_tmp)
406 IF (unit_nr > 0)
THEN
407 WRITE (unit=unit_nr, fmt=
"(T3,A,A,A,T73,ES8.1)") &
408 "HFX_RI_INFO| Error for SQRT(", trim(name_prv),
"):", frob_matrix
410 CALL dbcsr_release(matrix_tmp)
411 CALL dbcsr_release(matrix_copy)
414 IF (
PRESENT(matrix_sqrt_inv))
THEN
415 CALL dbcsr_create(matrix_tmp, template=matrix)
416 CALL dbcsr_copy(matrix_copy, matrix_sqrt_inv)
417 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_sqrt_inv, matrix_copy, &
419 CALL check_inverse(matrix_tmp, matrix, name=
"SQRT("//trim(name_prv)//
")", unit_nr=unit_nr)
420 CALL dbcsr_release(matrix_tmp)
421 CALL dbcsr_release(matrix_copy)
441 TYPE(qs_environment_type),
POINTER :: qs_env
442 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
443 TYPE(dbcsr_type),
DIMENSION(:),
INTENT(OUT) :: t_2c_int_ri, t_2c_int_pot
444 TYPE(dbt_type),
DIMENSION(:, :) :: t_3c_int
445 LOGICAL,
INTENT(IN),
OPTIONAL :: do_kpoints
447 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_pre_scf_calc_tensors'
450 INTEGER :: handle, i_img, i_mem, ibasis, j_img, &
451 n_mem, natom, nblks, nimg, nkind, &
453 INTEGER(int_8) :: nze
454 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: dist_ao_1, dist_ao_2, dist_ri, dist_ri_ext, &
455 ends_array_mc_block_int, ends_array_mc_int, sizes_ao, sizes_ri, sizes_ri_ext, &
456 sizes_ri_ext_split, starts_array_mc_block_int, starts_array_mc_int
457 INTEGER,
DIMENSION(3) :: pcoord, pdims
458 INTEGER,
DIMENSION(:),
POINTER :: col_bsize, row_bsize
459 LOGICAL :: converged, do_kpoints_prv
460 REAL(
dp) :: max_ev, min_ev, occ, ri_range
461 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
462 TYPE(dbcsr_distribution_type) :: dbcsr_dist
463 TYPE(dbt_distribution_type) :: t_dist
464 TYPE(dbt_pgrid_type) :: pgrid
465 TYPE(dbt_type) :: t_3c_tmp
466 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_int_batched
467 TYPE(dft_control_type),
POINTER :: dft_control
468 TYPE(distribution_2d_type),
POINTER :: dist_2d
469 TYPE(distribution_3d_type) :: dist_3d
470 TYPE(gto_basis_set_p_type),
ALLOCATABLE, &
471 DIMENSION(:),
TARGET :: basis_set_ao, basis_set_ri
472 TYPE(gto_basis_set_type),
POINTER :: orb_basis, ri_basis
473 TYPE(mp_cart_type) :: mp_comm_t3c
474 TYPE(mp_para_env_type),
POINTER :: para_env
475 TYPE(neighbor_list_3c_type) :: nl_3c
476 TYPE(neighbor_list_set_p_type),
DIMENSION(:), &
477 POINTER :: nl_2c_pot, nl_2c_ri
478 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
479 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
480 TYPE(qs_ks_env_type),
POINTER :: ks_env
482 CALL timeset(routinen, handle)
483 NULLIFY (col_bsize, row_bsize, dist_2d, nl_2c_pot, nl_2c_ri, &
484 particle_set, qs_kind_set, ks_env, para_env)
486 CALL get_qs_env(qs_env, natom=natom, nkind=nkind, qs_kind_set=qs_kind_set, particle_set=particle_set, &
487 distribution_2d=dist_2d, ks_env=ks_env, dft_control=dft_control, para_env=para_env)
490 do_kpoints_prv = .false.
491 IF (
PRESENT(do_kpoints)) do_kpoints_prv = do_kpoints
493 IF (do_kpoints_prv)
THEN
495 ri_range = ri_data%kp_RI_range
498 ALLOCATE (sizes_ri(natom), sizes_ao(natom))
499 ALLOCATE (basis_set_ri(nkind), basis_set_ao(nkind))
501 CALL get_particle_set(particle_set, qs_kind_set, nsgf=sizes_ri, basis=basis_set_ri)
503 CALL get_particle_set(particle_set, qs_kind_set, nsgf=sizes_ao, basis=basis_set_ao)
505 DO ibasis = 1,
SIZE(basis_set_ao)
506 orb_basis => basis_set_ao(ibasis)%gto_basis_set
507 ri_basis => basis_set_ri(ibasis)%gto_basis_set
515 n_mem = ri_data%n_mem
517 starts_array_mc_block_int, ends_array_mc_block_int)
519 DEALLOCATE (starts_array_mc_int, ends_array_mc_int)
522 IF (.NOT. do_kpoints_prv)
THEN
527 CALL dbt_pgrid_create(para_env, pdims, pgrid, tensor_dims=[max(1, natom/(n_mem*nthreads)), natom, natom])
529 ALLOCATE (t_3c_int_batched(1, 1))
530 CALL create_3c_tensor(t_3c_int_batched(1, 1), dist_ri, dist_ao_1, dist_ao_2, pgrid, &
531 sizes_ri, sizes_ao, sizes_ao, map1=[1], map2=[2, 3], &
534 CALL get_qs_env(qs_env, nkind=nkind, particle_set=particle_set, atomic_kind_set=atomic_kind_set)
535 CALL dbt_mp_environ_pgrid(pgrid, pdims, pcoord)
536 CALL mp_comm_t3c%create(pgrid%mp_comm_2d, 3, pdims)
538 nkind, particle_set, mp_comm_t3c, own_comm=.true.)
539 DEALLOCATE (dist_ri, dist_ao_1, dist_ao_2)
541 CALL create_3c_tensor(t_3c_int(1, 1), dist_ri, dist_ao_1, dist_ao_2, ri_data%pgrid, &
542 ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
543 map1=[1], map2=[2, 3], &
544 name=
"O (RI AO | AO)")
547 "HFX_3c_nl", qs_env, op_pos=1, sym_jk=.true., own_dist=.true.)
551 basis_set_ri, basis_set_ao, basis_set_ao, &
552 ri_data%ri_metric, int_eps=ri_data%eps_schwarz, op_pos=1, &
553 desymmetrize=.false., &
554 bounds_i=[starts_array_mc_block_int(i_mem), ends_array_mc_block_int(i_mem)])
555 CALL dbt_copy(t_3c_int_batched(1, 1), t_3c_int(1, 1), summation=.true., move_data=.true.)
556 CALL dbt_filter(t_3c_int(1, 1), ri_data%filter_eps/2)
559 CALL dbt_destroy(t_3c_int_batched(1, 1))
563 CALL dbt_create(t_3c_int(1, 1), t_3c_tmp)
565 IF (ri_data%flavor ==
ri_pmat)
THEN
567 CALL dbt_copy(t_3c_int(1, 1), t_3c_tmp)
568 CALL dbt_copy(t_3c_tmp, t_3c_int(1, 1), order=[1, 3, 2], summation=.true., move_data=.true.)
572 CALL dbt_filter(t_3c_int(1, 1), ri_data%filter_eps)
574 CALL dbt_filter(t_3c_int(1, 1), ri_data%filter_eps_storage/2)
577 CALL dbt_destroy(t_3c_tmp)
584 CALL dbt_pgrid_create(para_env, pdims, pgrid, tensor_dims=[natom, natom, max(1, natom/(n_mem*nthreads))])
588 nblks =
SIZE(ri_data%bsizes_RI_split)
589 ALLOCATE (sizes_ri_ext(natom*ri_data%ncell_RI), sizes_ri_ext_split(nblks*ri_data%ncell_RI))
590 DO i_img = 1, ri_data%ncell_RI
591 sizes_ri_ext((i_img - 1)*natom + 1:i_img*natom) = sizes_ri(:)
592 sizes_ri_ext_split((i_img - 1)*nblks + 1:i_img*nblks) = ri_data%bsizes_RI_split(:)
596 pgrid, sizes_ao, sizes_ao, sizes_ri, map1=[1, 2], map2=[3], &
598 CALL dbt_destroy(t_3c_tmp)
601 ALLOCATE (dist_ri_ext(natom*ri_data%ncell_RI))
602 DO i_img = 1, ri_data%ncell_RI
603 dist_ri_ext((i_img - 1)*natom + 1:i_img*natom) = dist_ri(:)
606 ALLOCATE (t_3c_int_batched(nimg, 1))
607 CALL dbt_distribution_new(t_dist, pgrid, dist_ao_1, dist_ao_2, dist_ri_ext)
608 CALL dbt_create(t_3c_int_batched(1, 1),
"KP_3c_ints", t_dist, [1, 2], [3], &
609 sizes_ao, sizes_ao, sizes_ri_ext)
611 CALL dbt_create(t_3c_int_batched(1, 1), t_3c_int_batched(i_img, 1))
613 CALL dbt_distribution_destroy(t_dist)
615 CALL get_qs_env(qs_env, nkind=nkind, particle_set=particle_set, atomic_kind_set=atomic_kind_set)
616 CALL dbt_mp_environ_pgrid(pgrid, pdims, pcoord)
617 CALL mp_comm_t3c%create(pgrid%mp_comm_2d, 3, pdims)
619 nkind, particle_set, mp_comm_t3c, own_comm=.true.)
620 DEALLOCATE (dist_ri, dist_ao_1, dist_ao_2)
624 "HFX_3c_nl", qs_env, op_pos=2, sym_ij=.false., own_dist=.true.)
626 CALL create_3c_tensor(t_3c_int(1, 1), dist_ri, dist_ao_1, dist_ao_2, ri_data%pgrid, &
627 sizes_ri_ext_split, ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
628 map1=[1], map2=[2, 3], &
629 name=
"O (RI AO | AO)")
631 CALL dbt_create(t_3c_int(1, 1), t_3c_int(1, j_img))
634 CALL dbt_create(t_3c_int(1, 1), t_3c_tmp)
637 basis_set_ao, basis_set_ao, basis_set_ri, &
638 ri_data%ri_metric, int_eps=ri_data%eps_schwarz, op_pos=2, &
639 desymmetrize=.false., do_kpoints=.true., do_hfx_kpoints=.true., &
640 bounds_k=[starts_array_mc_block_int(i_mem), ends_array_mc_block_int(i_mem)], &
641 ri_range=ri_range, img_to_ri_cell=ri_data%img_to_RI_cell)
647 CALL dbt_copy(t_3c_int_batched(i_img, 1), t_3c_tmp, order=[3, 2, 1], move_data=.true.)
648 CALL dbt_filter(t_3c_tmp, ri_data%filter_eps)
649 CALL dbt_copy(t_3c_tmp, t_3c_int(1, i_img), order=[1, 3, 2], &
650 summation=.true., move_data=.true.)
656 CALL dbt_destroy(t_3c_int_batched(i_img, 1))
658 DEALLOCATE (t_3c_int_batched)
660 CALL dbt_destroy(t_3c_tmp)
662 CALL dbt_pgrid_destroy(pgrid)
665 "HFX_2c_nl_pot", qs_env, sym_ij=.NOT. do_kpoints_prv, &
669 ALLOCATE (row_bsize(
SIZE(sizes_ri)))
670 ALLOCATE (col_bsize(
SIZE(sizes_ri)))
671 row_bsize(:) = sizes_ri
672 col_bsize(:) = sizes_ri
675 symm = dbcsr_type_symmetric
676 IF (do_kpoints_prv) symm = dbcsr_type_no_symmetry
678 CALL dbcsr_create(t_2c_int_pot(1),
"(R|P) HFX", dbcsr_dist, symm, row_bsize, col_bsize)
680 CALL dbcsr_create(t_2c_int_pot(i_img), template=t_2c_int_pot(1))
683 IF (.NOT. ri_data%same_op)
THEN
684 CALL dbcsr_create(t_2c_int_ri(1),
"(R|P) HFX", dbcsr_dist, symm, row_bsize, col_bsize)
686 CALL dbcsr_create(t_2c_int_ri(i_img), template=t_2c_int_ri(1))
689 DEALLOCATE (col_bsize, row_bsize)
691 CALL dbcsr_distribution_release(dbcsr_dist)
693 CALL build_2c_integrals(t_2c_int_pot, ri_data%filter_eps_2c, qs_env, nl_2c_pot, basis_set_ri, basis_set_ri, &
694 ri_data%hfx_pot, do_kpoints=do_kpoints_prv, do_hfx_kpoints=do_kpoints_prv)
697 IF (.NOT. ri_data%same_op)
THEN
699 "HFX_2c_nl_RI", qs_env, sym_ij=.NOT. do_kpoints_prv, &
702 CALL build_2c_integrals(t_2c_int_ri, ri_data%filter_eps_2c, qs_env, nl_2c_ri, basis_set_ri, basis_set_ri, &
703 ri_data%ri_metric, do_kpoints=do_kpoints_prv, do_hfx_kpoints=do_kpoints_prv)
708 DO ibasis = 1,
SIZE(basis_set_ao)
709 orb_basis => basis_set_ao(ibasis)%gto_basis_set
710 ri_basis => basis_set_ri(ibasis)%gto_basis_set
716 IF (ri_data%calc_condnum)
THEN
717 CALL arnoldi_extremal(t_2c_int_pot(1), max_ev, min_ev, threshold=ri_data%eps_lanczos, &
718 max_iter=ri_data%max_iter_lanczos, converged=converged)
720 IF (.NOT. converged)
THEN
721 cpwarn(
"Condition number estimate of (P|Q) (HFX potential) is not reliable (not converged).")
724 IF (ri_data%unit_nr > 0)
THEN
725 WRITE (ri_data%unit_nr,
'(T2,A)')
"2-Norm Condition Number of (P|Q) integrals (HFX potential)"
727 WRITE (ri_data%unit_nr,
'(T4,A,ES11.3E3,T32,A,ES11.3E3,A4,ES11.3E3,T63,A,F8.4)') &
728 "CN : max/min ev: ", max_ev,
" / ", min_ev,
"=", max_ev/min_ev,
"Log(2-CN):", log10(max_ev/min_ev)
730 WRITE (ri_data%unit_nr,
'(T4,A,ES11.3E3,T32,A,ES11.3E3,T63,A)') &
731 "CN : max/min ev: ", max_ev,
" / ", min_ev,
"Log(CN): infinity"
735 IF (.NOT. ri_data%same_op)
THEN
736 CALL arnoldi_extremal(t_2c_int_ri(1), max_ev, min_ev, threshold=ri_data%eps_lanczos, &
737 max_iter=ri_data%max_iter_lanczos, converged=converged)
739 IF (.NOT. converged)
THEN
740 cpwarn(
"Condition number estimate of (P|Q) matrix (RI metric) is not reliable (not converged).")
743 IF (ri_data%unit_nr > 0)
THEN
744 WRITE (ri_data%unit_nr,
'(T2,A)')
"2-Norm Condition Number of (P|Q) integrals (RI metric)"
746 WRITE (ri_data%unit_nr,
'(T4,A,ES11.3E3,T32,A,ES11.3E3,A4,ES11.3E3,T63,A,F8.4)') &
747 "CN : max/min ev: ", max_ev,
" / ", min_ev,
"=", max_ev/min_ev,
"Log(2-CN):", log10(max_ev/min_ev)
749 WRITE (ri_data%unit_nr,
'(T4,A,ES11.3E3,T32,A,ES11.3E3,T63,A)') &
750 "CN : max/min ev: ", max_ev,
" / ", min_ev,
"Log(CN): infinity"
756 CALL timestop(handle)
767 SUBROUTINE hfx_ri_pre_scf_pmat(qs_env, ri_data)
768 TYPE(qs_environment_type),
POINTER :: qs_env
769 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
771 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_pre_scf_Pmat'
773 INTEGER :: handle, handle2, i_mem, j_mem, &
774 n_dependent, unit_nr, unit_nr_dbcsr
775 INTEGER(int_8) :: nflop, nze, nze_o
776 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: batch_ranges_ao, batch_ranges_ri
777 INTEGER,
DIMENSION(2, 1) :: bounds_i
778 INTEGER,
DIMENSION(2, 2) :: bounds_j
779 INTEGER,
DIMENSION(3) :: dims_3c
780 REAL(kind=
dp) :: compression_factor, memory_3c, occ, &
782 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
783 TYPE(dbcsr_type),
DIMENSION(1) :: t_2c_int_mat, t_2c_op_pot, t_2c_op_ri, &
785 TYPE(dbt_type) :: t_3c_2
786 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:) :: t_2c_int, t_2c_work
787 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_int_1
788 TYPE(mp_para_env_type),
POINTER :: para_env
790 CALL timeset(routinen, handle)
792 unit_nr_dbcsr = ri_data%unit_nr_dbcsr
793 unit_nr = ri_data%unit_nr
795 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
797 CALL timeset(routinen//
"_int", handle2)
799 ALLOCATE (t_2c_int(1), t_2c_work(1), t_3c_int_1(1, 1))
802 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.)
804 CALL dbt_destroy(t_3c_int_1(1, 1))
806 CALL timestop(handle2)
808 CALL timeset(routinen//
"_2c", handle2)
810 IF (ri_data%same_op) t_2c_op_ri(1) = t_2c_op_pot(1)
811 CALL dbcsr_create(t_2c_int_mat(1), template=t_2c_op_ri(1), matrix_type=dbcsr_type_no_symmetry)
812 threshold = max(ri_data%filter_eps, 1.0e-12_dp)
814 SELECT CASE (ri_data%t2c_method)
817 threshold=threshold, silent=.false.)
819 CALL dbcsr_copy(t_2c_int_mat(1), t_2c_op_ri(1))
823 CALL dbcsr_copy(t_2c_int_mat(1), t_2c_op_ri(1))
824 CALL cp_dbcsr_power(t_2c_int_mat(1), -1.0_dp, ri_data%eps_eigval, n_dependent, &
825 para_env, blacs_env, verbose=ri_data%unit_nr_dbcsr > 0)
828 IF (ri_data%check_2c_inv)
THEN
829 CALL check_inverse(t_2c_int_mat(1), t_2c_op_ri(1), unit_nr=unit_nr)
833 CALL dbt_create(t_2c_int_mat(1), t_2c_work(1))
834 CALL dbt_copy_matrix_to_tensor(t_2c_int_mat(1), t_2c_work(1))
835 CALL dbt_copy(t_2c_work(1), ri_data%t_2c_inv(1, 1), move_data=.true.)
836 CALL dbt_destroy(t_2c_work(1))
837 CALL dbt_filter(ri_data%t_2c_inv(1, 1), ri_data%filter_eps)
838 IF (.NOT. ri_data%same_op)
THEN
840 CALL dbt_create(t_2c_op_pot(1), t_2c_work(1))
841 CALL dbt_copy_matrix_to_tensor(t_2c_op_pot(1), t_2c_work(1))
842 CALL dbt_copy(t_2c_work(1), ri_data%t_2c_pot(1, 1), move_data=.true.)
843 CALL dbt_destroy(t_2c_work(1))
844 CALL dbt_filter(ri_data%t_2c_pot(1, 1), ri_data%filter_eps)
847 IF (ri_data%same_op)
THEN
848 CALL dbcsr_release(t_2c_op_pot(1))
850 CALL dbcsr_create(t_2c_tmp(1), template=t_2c_op_ri(1), matrix_type=dbcsr_type_no_symmetry)
851 CALL dbcsr_create(t_2c_tmp_2(1), template=t_2c_op_ri(1), matrix_type=dbcsr_type_no_symmetry)
852 CALL dbcsr_release(t_2c_op_ri(1))
853 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), &
854 filter_eps=ri_data%filter_eps)
856 CALL dbcsr_release(t_2c_op_pot(1))
857 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), &
858 filter_eps=ri_data%filter_eps)
859 CALL dbcsr_release(t_2c_tmp(1))
860 CALL dbcsr_release(t_2c_int_mat(1))
861 t_2c_int_mat(1) = t_2c_tmp_2(1)
864 CALL dbt_create(t_2c_int_mat(1), t_2c_int(1), name=
"(RI|RI)")
865 CALL dbt_copy_matrix_to_tensor(t_2c_int_mat(1), t_2c_int(1))
866 CALL dbcsr_release(t_2c_int_mat(1))
867 CALL dbt_copy(t_2c_int(1), ri_data%t_2c_int(1, 1), move_data=.true.)
868 CALL dbt_destroy(t_2c_int(1))
869 CALL dbt_filter(ri_data%t_2c_int(1, 1), ri_data%filter_eps)
871 CALL timestop(handle2)
873 CALL dbt_create(ri_data%t_3c_int_ctr_3(1, 1), t_3c_2)
875 CALL dbt_get_info(ri_data%t_3c_int_ctr_3(1, 1), nfull_total=dims_3c)
880 ALLOCATE (batch_ranges_ri(ri_data%n_mem_RI + 1))
881 ALLOCATE (batch_ranges_ao(ri_data%n_mem + 1))
882 batch_ranges_ri(:ri_data%n_mem_RI) = ri_data%starts_array_RI_mem_block(:)
883 batch_ranges_ri(ri_data%n_mem_RI + 1) = ri_data%ends_array_RI_mem_block(ri_data%n_mem_RI) + 1
884 batch_ranges_ao(:ri_data%n_mem) = ri_data%starts_array_mem_block(:)
885 batch_ranges_ao(ri_data%n_mem + 1) = ri_data%ends_array_mem_block(ri_data%n_mem) + 1
887 CALL dbt_batched_contract_init(ri_data%t_3c_int_ctr_3(1, 1), batch_range_1=batch_ranges_ri, &
888 batch_range_2=batch_ranges_ao)
889 CALL dbt_batched_contract_init(t_3c_2, batch_range_1=batch_ranges_ri, &
890 batch_range_2=batch_ranges_ao)
892 DO i_mem = 1, ri_data%n_mem_RI
893 bounds_i(:, 1) = [ri_data%starts_array_RI_mem(i_mem), ri_data%ends_array_RI_mem(i_mem)]
895 CALL dbt_batched_contract_init(ri_data%t_2c_int(1, 1))
896 DO j_mem = 1, ri_data%n_mem
897 bounds_j(:, 1) = [ri_data%starts_array_mem(j_mem), ri_data%ends_array_mem(j_mem)]
898 bounds_j(:, 2) = [1, dims_3c(3)]
899 CALL timeset(routinen//
"_RIx3C", handle2)
900 CALL dbt_contract(1.0_dp, ri_data%t_2c_int(1, 1), ri_data%t_3c_int_ctr_3(1, 1), &
902 contract_1=[2], notcontract_1=[1], &
903 contract_2=[1], notcontract_2=[2, 3], &
904 map_1=[1], map_2=[2, 3], filter_eps=ri_data%filter_eps_storage, &
907 unit_nr=unit_nr_dbcsr, &
910 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
911 CALL timestop(handle2)
913 CALL timeset(routinen//
"_copy_2", handle2)
914 CALL dbt_copy(t_3c_2, ri_data%t_3c_int_ctr_1(1, 1), order=[2, 1, 3], move_data=.true.)
919 CALL compress_tensor(ri_data%t_3c_int_ctr_1(1, 1), ri_data%blk_indices(j_mem, i_mem)%ind, &
920 ri_data%store_3c(j_mem, i_mem), ri_data%filter_eps_storage, memory_3c)
922 CALL timestop(handle2)
924 CALL dbt_batched_contract_finalize(ri_data%t_2c_int(1, 1))
926 CALL dbt_batched_contract_finalize(t_3c_2)
927 CALL dbt_batched_contract_finalize(ri_data%t_3c_int_ctr_3(1, 1))
929 CALL para_env%sum(memory_3c)
930 compression_factor = real(nze_o,
dp)*1.0e-06*8.0_dp/memory_3c
932 IF (unit_nr > 0)
THEN
933 WRITE (unit=unit_nr, fmt=
"((T3,A,T66,F11.2,A4))") &
934 "MEMORY_INFO| Memory for 3-center HFX integrals (compressed):", memory_3c,
' MiB'
936 WRITE (unit=unit_nr, fmt=
"((T3,A,T60,F21.2))") &
937 "MEMORY_INFO| Compression factor: ", compression_factor
940 CALL dbt_clear(ri_data%t_2c_int(1, 1))
941 CALL dbt_destroy(t_3c_2)
943 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.)
945 CALL timestop(handle)
952 SUBROUTINE sort_unique_blkind_2d(blk_ind)
953 INTEGER,
ALLOCATABLE,
DIMENSION(:, :), &
954 INTENT(INOUT) :: blk_ind
956 INTEGER :: end_ind, iblk, iblk_all, irow, nblk, &
958 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ind_1, ind_2, sort_1, sort_2
959 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: blk_ind_tmp
961 nblk =
SIZE(blk_ind, 1)
963 ALLOCATE (sort_1(nblk))
964 ALLOCATE (ind_1(nblk))
966 sort_1(:) = blk_ind(:, 1)
967 CALL sort(sort_1, nblk, ind_1)
969 blk_ind(:, :) = blk_ind(ind_1, :)
973 DO WHILE (start_ind <= nblk)
974 irow = blk_ind(start_ind, 1)
977 IF (end_ind + 1 <= nblk)
THEN
978 DO WHILE (blk_ind(end_ind + 1, 1) == irow)
979 end_ind = end_ind + 1
980 IF (end_ind + 1 > nblk)
EXIT
984 ncols = end_ind - start_ind + 1
985 ALLOCATE (sort_2(ncols))
986 ALLOCATE (ind_2(ncols))
987 sort_2(:) = blk_ind(start_ind:end_ind, 2)
988 CALL sort(sort_2, ncols, ind_2)
989 ind_2 = ind_2 + start_ind - 1
991 blk_ind(start_ind:end_ind, :) = blk_ind(ind_2, :)
992 start_ind = end_ind + 1
994 DEALLOCATE (sort_2, ind_2)
997 ALLOCATE (blk_ind_tmp(nblk, 2))
1001 DO iblk_all = 1, nblk
1003 IF (all(blk_ind_tmp(iblk, :) == blk_ind(iblk_all, :)))
THEN
1008 blk_ind_tmp(iblk, :) = blk_ind(iblk_all, :)
1012 DEALLOCATE (blk_ind)
1013 ALLOCATE (blk_ind(nblk, 2))
1015 blk_ind(:, :) = blk_ind_tmp(:nblk, :)
1032 geometry_did_change, nspins, hf_fraction)
1033 TYPE(qs_environment_type),
POINTER :: qs_env
1034 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
1035 TYPE(dbcsr_p_type),
DIMENSION(:, :),
POINTER :: ks_matrix
1036 REAL(kind=
dp),
INTENT(OUT) :: ehfx
1037 TYPE(mo_set_type),
DIMENSION(:),
INTENT(IN), &
1039 TYPE(dbcsr_p_type),
DIMENSION(:, :),
POINTER :: rho_ao
1040 LOGICAL,
INTENT(IN) :: geometry_did_change
1041 INTEGER,
INTENT(IN) :: nspins
1042 REAL(kind=
dp),
INTENT(IN) :: hf_fraction
1044 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_update_ks'
1046 CHARACTER(1) :: mtype
1047 INTEGER :: handle, handle2, i, ispin, j
1048 INTEGER(int_8) :: nblks
1049 INTEGER,
DIMENSION(2) :: homo
1050 LOGICAL :: is_antisymmetric
1051 REAL(
dp) :: etmp,
fac
1052 REAL(kind=
dp),
DIMENSION(:),
POINTER :: mo_eigenvalues
1053 TYPE(cp_fm_type),
POINTER :: mo_coeff
1054 TYPE(dbcsr_p_type),
DIMENSION(:, :),
POINTER :: my_ks_matrix, my_rho_ao
1055 TYPE(dbcsr_type),
DIMENSION(2) :: mo_coeff_b
1056 TYPE(dbcsr_type),
POINTER :: mo_coeff_b_tmp
1057 TYPE(mp_para_env_type),
POINTER :: para_env
1059 CALL timeset(routinen, handle)
1061 IF (nspins == 1)
THEN
1062 fac = 0.5_dp*hf_fraction
1064 fac = 1.0_dp*hf_fraction
1068 NULLIFY (my_ks_matrix, my_rho_ao)
1069 CALL dbcsr_get_info(ks_matrix(1, 1)%matrix, matrix_type=mtype)
1070 is_antisymmetric = mtype == dbcsr_type_antisymmetric
1071 IF (is_antisymmetric)
THEN
1072 ALLOCATE (my_ks_matrix(
SIZE(ks_matrix, 1),
SIZE(ks_matrix, 2)))
1073 ALLOCATE (my_rho_ao(
SIZE(rho_ao, 1),
SIZE(rho_ao, 2)))
1075 DO i = 1,
SIZE(ks_matrix, 1)
1076 DO j = 1,
SIZE(ks_matrix, 2)
1077 ALLOCATE (my_ks_matrix(i, j)%matrix, my_rho_ao(i, j)%matrix)
1078 CALL dbcsr_create(my_ks_matrix(i, j)%matrix, template=ks_matrix(i, j)%matrix, &
1079 matrix_type=dbcsr_type_no_symmetry)
1080 CALL dbcsr_desymmetrize(ks_matrix(i, j)%matrix, my_ks_matrix(i, j)%matrix)
1081 CALL dbcsr_create(my_rho_ao(i, j)%matrix, template=rho_ao(i, j)%matrix, &
1082 matrix_type=dbcsr_type_no_symmetry)
1083 CALL dbcsr_desymmetrize(rho_ao(i, j)%matrix, my_rho_ao(i, j)%matrix)
1087 my_ks_matrix => ks_matrix
1094 IF (ri_data%input_flavor ==
ri_mo .AND. (.NOT.
PRESENT(mos)) .AND. ri_data%flavor ==
ri_mo)
THEN
1095 CALL switch_ri_flavor(ri_data, qs_env)
1096 ELSE IF (ri_data%input_flavor ==
ri_mo .AND.
PRESENT(mos) .AND. ri_data%flavor ==
ri_pmat)
THEN
1097 CALL switch_ri_flavor(ri_data, qs_env)
1100 SELECT CASE (ri_data%flavor)
1102 cpassert(
PRESENT(mos))
1103 CALL timeset(routinen//
"_MO", handle2)
1105 DO ispin = 1, nspins
1106 NULLIFY (mo_coeff_b_tmp)
1107 cpassert(mos(ispin)%uniform_occupation)
1108 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, eigenvalues=mo_eigenvalues, mo_coeff_b=mo_coeff_b_tmp)
1110 IF (.NOT. mos(ispin)%use_mo_coeff_b)
CALL copy_fm_to_dbcsr(mo_coeff, mo_coeff_b_tmp)
1111 CALL dbcsr_copy(mo_coeff_b(ispin), mo_coeff_b_tmp)
1114 DO ispin = 1, nspins
1115 CALL dbcsr_scale(mo_coeff_b(ispin), sqrt(mos(ispin)%maxocc))
1116 homo(ispin) = mos(ispin)%homo
1119 CALL timestop(handle2)
1121 CALL hfx_ri_update_ks_mo(qs_env, ri_data, my_ks_matrix, mo_coeff_b, homo, &
1122 geometry_did_change, nspins,
fac)
1127 DO ispin = 1,
SIZE(my_rho_ao, 1)
1128 nblks = dbcsr_get_num_blocks(my_rho_ao(ispin, 1)%matrix)
1129 CALL para_env%sum(nblks)
1130 IF (nblks == 0)
THEN
1131 cpabort(
"received empty density matrix")
1135 CALL hfx_ri_update_ks_pmat(qs_env, ri_data, my_ks_matrix, my_rho_ao, &
1136 geometry_did_change, nspins,
fac)
1140 DO ispin = 1, nspins
1141 CALL dbcsr_release(mo_coeff_b(ispin))
1144 DO ispin = 1, nspins
1145 CALL dbcsr_filter(my_ks_matrix(ispin, 1)%matrix, ri_data%filter_eps)
1148 CALL timeset(routinen//
"_energy", handle2)
1151 DO ispin = 1, nspins
1152 CALL dbcsr_dot(my_ks_matrix(ispin, 1)%matrix, my_rho_ao(ispin, 1)%matrix, &
1154 ehfx = ehfx + 0.5_dp*etmp
1157 CALL timestop(handle2)
1160 IF (is_antisymmetric)
THEN
1161 DO i = 1,
SIZE(ks_matrix, 1)
1162 DO j = 1,
SIZE(ks_matrix, 2)
1163 CALL dbcsr_complete_redistribute(my_ks_matrix(i, j)%matrix, ks_matrix(i, j)%matrix)
1164 CALL dbcsr_complete_redistribute(my_rho_ao(i, j)%matrix, rho_ao(i, j)%matrix)
1171 CALL timestop(handle)
1189 SUBROUTINE hfx_ri_update_ks_mo(qs_env, ri_data, ks_matrix, mo_coeff, &
1190 homo, geometry_did_change, nspins, fac)
1191 TYPE(qs_environment_type),
POINTER :: qs_env
1192 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
1193 TYPE(dbcsr_p_type),
DIMENSION(:, :) :: ks_matrix
1194 TYPE(dbcsr_type),
DIMENSION(:),
INTENT(IN) :: mo_coeff
1195 INTEGER,
DIMENSION(:) :: homo
1196 LOGICAL,
INTENT(IN) :: geometry_did_change
1197 INTEGER,
INTENT(IN) :: nspins
1198 REAL(
dp),
INTENT(IN) ::
fac
1200 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_update_ks_mo'
1202 INTEGER :: bsize, bsum, comm_2d_handle, handle, &
1203 handle2, i_mem, iblock, iproc, ispin, &
1204 n_mem, n_mos, nblock, unit_nr_dbcsr
1205 INTEGER(int_8) :: nblks, nflop
1206 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: batch_ranges_1, batch_ranges_2, dist1, dist2, dist3, &
1207 mem_end, mem_end_block_1, mem_end_block_2, mem_size, mem_start, mem_start_block_1, &
1208 mem_start_block_2, mo_bsizes_1, mo_bsizes_2
1209 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: bounds
1210 INTEGER,
DIMENSION(2) :: pdims_2d
1211 INTEGER,
DIMENSION(3) :: pdims
1212 LOGICAL :: do_initialize
1214 TYPE(dbcsr_distribution_type) :: ks_dist
1215 TYPE(dbt_pgrid_type) :: pgrid, pgrid_2d
1216 TYPE(dbt_type) :: ks_t, ks_t_mat, mo_coeff_t, &
1218 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_int_mo_1, t_3c_int_mo_2
1219 TYPE(mp_comm_type) :: comm_2d
1220 TYPE(mp_para_env_type),
POINTER :: para_env
1222 CALL timeset(routinen, handle)
1224 cpassert(
SIZE(ks_matrix, 2) == 1)
1226 unit_nr_dbcsr = ri_data%unit_nr_dbcsr
1228 IF (geometry_did_change)
THEN
1229 CALL hfx_ri_pre_scf_mo(qs_env, ri_data, nspins)
1232 nblks = dbt_get_num_blocks_total(ri_data%t_3c_int_ctr_1(1, 1))
1233 IF (nblks == 0)
THEN
1234 cpabort(
"3-center integrals are not available (first call requires geometry_did_change=.TRUE.)")
1237 DO ispin = 1, nspins
1238 nblks = dbt_get_num_blocks_total(ri_data%t_2c_int(ispin, 1))
1239 IF (nblks == 0)
THEN
1240 cpabort(
"2-center integrals are not available (first call requires geometry_did_change=.TRUE.)")
1244 IF (.NOT.
ALLOCATED(ri_data%t_3c_int_mo))
THEN
1245 do_initialize = .true.
1246 cpassert(.NOT.
ALLOCATED(ri_data%t_3c_ctr_RI))
1247 cpassert(.NOT.
ALLOCATED(ri_data%t_3c_ctr_KS))
1248 cpassert(.NOT.
ALLOCATED(ri_data%t_3c_ctr_KS_copy))
1249 ALLOCATE (ri_data%t_3c_int_mo(nspins, 1, 1))
1250 ALLOCATE (ri_data%t_3c_ctr_RI(nspins, 1, 1))
1251 ALLOCATE (ri_data%t_3c_ctr_KS(nspins, 1, 1))
1252 ALLOCATE (ri_data%t_3c_ctr_KS_copy(nspins, 1, 1))
1254 do_initialize = .false.
1259 ALLOCATE (bounds(2, 1))
1261 CALL dbcsr_get_info(ks_matrix(1, 1)%matrix, distribution=ks_dist)
1262 CALL dbcsr_distribution_get(ks_dist, group=comm_2d_handle, nprows=pdims_2d(1), npcols=pdims_2d(2))
1264 CALL comm_2d%set_handle(comm_2d_handle)
1265 pgrid_2d = dbt_nd_mp_comm(comm_2d, [1], [2], pdims_2d=pdims_2d)
1267 CALL create_2c_tensor(ks_t, dist1, dist2, pgrid_2d, ri_data%bsizes_AO_fit, ri_data%bsizes_AO_fit, &
1270 DEALLOCATE (dist1, dist2)
1272 CALL para_env%sync()
1275 ALLOCATE (t_3c_int_mo_1(1, 1), t_3c_int_mo_2(1, 1))
1276 DO ispin = 1, nspins
1278 CALL dbcsr_get_info(mo_coeff(ispin), nfullcols_total=n_mos)
1279 ALLOCATE (mo_bsizes_2(n_mos))
1283 mem_start_block_2, mem_end_block_2)
1284 n_mem = ri_data%n_mem
1285 ALLOCATE (mem_size(n_mem))
1288 bsize = sum(mo_bsizes_2(mem_start_block_2(i_mem):mem_end_block_2(i_mem)))
1289 mem_size(i_mem) = bsize
1293 ALLOCATE (mem_start_block_1(n_mem))
1294 ALLOCATE (mem_end_block_1(n_mem))
1295 nblock =
SIZE(mo_bsizes_1)
1301 cpassert(iblock <= nblock)
1302 bsum = bsum + mo_bsizes_1(iblock)
1303 IF (bsum == mem_size(i_mem))
THEN
1304 IF (i_mem == 1)
THEN
1305 mem_start_block_1(i_mem) = 1
1307 mem_start_block_1(i_mem) = mem_end_block_1(i_mem - 1) + 1
1309 mem_end_block_1(i_mem) = iblock
1315 ALLOCATE (batch_ranges_1(ri_data%n_mem + 1))
1316 batch_ranges_1(:ri_data%n_mem) = mem_start_block_1(:)
1317 batch_ranges_1(ri_data%n_mem + 1) = mem_end_block_1(ri_data%n_mem) + 1
1319 ALLOCATE (batch_ranges_2(ri_data%n_mem + 1))
1320 batch_ranges_2(:ri_data%n_mem) = mem_start_block_2(:)
1321 batch_ranges_2(ri_data%n_mem + 1) = mem_end_block_2(ri_data%n_mem) + 1
1323 iproc = para_env%mepos
1325 CALL create_3c_tensor(t_3c_int_mo_1(1, 1), dist1, dist2, dist3, ri_data%pgrid_1, &
1326 ri_data%bsizes_AO_split, ri_data%bsizes_RI_split, mo_bsizes_1, &
1328 name=
"(AO RI | MO)")
1330 DEALLOCATE (dist1, dist2, dist3)
1332 CALL create_3c_tensor(t_3c_int_mo_2(1, 1), dist1, dist2, dist3, ri_data%pgrid_2, &
1333 mo_bsizes_1, ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, &
1335 name=
"(MO | RI AO)")
1337 DEALLOCATE (dist1, dist2, dist3)
1339 CALL create_2c_tensor(mo_coeff_t_split, dist1, dist2, pgrid_2d, ri_data%bsizes_AO_split, mo_bsizes_1, &
1342 DEALLOCATE (dist1, dist2)
1344 cpassert(homo(ispin)/ri_data%n_mem > 0)
1346 IF (do_initialize)
THEN
1349 CALL dbt_pgrid_create(para_env, pdims, pgrid, &
1350 tensor_dims=[
SIZE(ri_data%bsizes_RI_fit), &
1351 (homo(ispin) - 1)/ri_data%n_mem + 1, &
1352 SIZE(ri_data%bsizes_AO_fit)])
1353 CALL create_3c_tensor(ri_data%t_3c_int_mo(ispin, 1, 1), dist1, dist2, dist3, pgrid, &
1354 ri_data%bsizes_RI_fit, mo_bsizes_2, ri_data%bsizes_AO_fit, &
1356 name=
"(RI | MO AO)")
1358 DEALLOCATE (dist1, dist2, dist3)
1360 CALL create_3c_tensor(ri_data%t_3c_ctr_KS(ispin, 1, 1), dist1, dist2, dist3, pgrid, &
1361 ri_data%bsizes_RI_fit, mo_bsizes_2, ri_data%bsizes_AO_fit, &
1363 name=
"(RI MO | AO)")
1364 DEALLOCATE (dist1, dist2, dist3)
1365 CALL dbt_pgrid_destroy(pgrid)
1367 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)")
1368 CALL dbt_create(ri_data%t_3c_ctr_KS(ispin, 1, 1), ri_data%t_3c_ctr_KS_copy(ispin, 1, 1))
1371 CALL dbt_create(mo_coeff(ispin), mo_coeff_t, name=
"MO coeffs")
1372 CALL dbt_copy_matrix_to_tensor(mo_coeff(ispin), mo_coeff_t)
1373 CALL dbt_copy(mo_coeff_t, mo_coeff_t_split, move_data=.true.)
1374 CALL dbt_filter(mo_coeff_t_split, ri_data%filter_eps_mo)
1375 CALL dbt_destroy(mo_coeff_t)
1377 CALL dbt_batched_contract_init(ks_t)
1378 CALL dbt_batched_contract_init(ri_data%t_3c_ctr_KS(ispin, 1, 1), batch_range_2=batch_ranges_2)
1379 CALL dbt_batched_contract_init(ri_data%t_3c_ctr_KS_copy(ispin, 1, 1), batch_range_2=batch_ranges_2)
1381 CALL dbt_batched_contract_init(ri_data%t_2c_int(ispin, 1))
1382 CALL dbt_batched_contract_init(ri_data%t_3c_int_mo(ispin, 1, 1), batch_range_2=batch_ranges_2)
1383 CALL dbt_batched_contract_init(ri_data%t_3c_ctr_RI(ispin, 1, 1), batch_range_2=batch_ranges_2)
1387 bounds(:, 1) = [mem_start(i_mem), mem_end(i_mem)]
1389 CALL dbt_batched_contract_init(mo_coeff_t_split)
1390 CALL dbt_batched_contract_init(ri_data%t_3c_int_ctr_1(1, 1))
1391 CALL dbt_batched_contract_init(t_3c_int_mo_1(1, 1), &
1392 batch_range_3=batch_ranges_1)
1393 CALL timeset(routinen//
"_MOx3C_R", handle2)
1394 CALL dbt_contract(1.0_dp, mo_coeff_t_split, ri_data%t_3c_int_ctr_1(1, 1), &
1395 0.0_dp, t_3c_int_mo_1(1, 1), &
1396 contract_1=[1], notcontract_1=[2], &
1397 contract_2=[3], notcontract_2=[1, 2], &
1398 map_1=[3], map_2=[1, 2], &
1400 filter_eps=ri_data%filter_eps_mo/2, &
1401 unit_nr=unit_nr_dbcsr, &
1402 move_data=.false., &
1405 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
1407 CALL timestop(handle2)
1408 CALL dbt_batched_contract_finalize(mo_coeff_t_split)
1409 CALL dbt_batched_contract_finalize(ri_data%t_3c_int_ctr_1(1, 1))
1410 CALL dbt_batched_contract_finalize(t_3c_int_mo_1(1, 1))
1412 CALL timeset(routinen//
"_copy_1", handle2)
1413 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.)
1414 CALL timestop(handle2)
1416 CALL dbt_batched_contract_init(mo_coeff_t_split)
1417 CALL dbt_batched_contract_init(ri_data%t_3c_int_ctr_2(1, 1))
1418 CALL dbt_batched_contract_init(t_3c_int_mo_2(1, 1), &
1419 batch_range_1=batch_ranges_1)
1421 CALL timeset(routinen//
"_MOx3C_L", handle2)
1422 CALL dbt_contract(1.0_dp, mo_coeff_t_split, ri_data%t_3c_int_ctr_2(1, 1), &
1423 0.0_dp, t_3c_int_mo_2(1, 1), &
1424 contract_1=[1], notcontract_1=[2], &
1425 contract_2=[1], notcontract_2=[2, 3], &
1426 map_1=[1], map_2=[2, 3], &
1428 filter_eps=ri_data%filter_eps_mo/2, &
1429 unit_nr=unit_nr_dbcsr, &
1430 move_data=.false., &
1433 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
1435 CALL timestop(handle2)
1437 CALL dbt_batched_contract_finalize(mo_coeff_t_split)
1438 CALL dbt_batched_contract_finalize(ri_data%t_3c_int_ctr_2(1, 1))
1439 CALL dbt_batched_contract_finalize(t_3c_int_mo_2(1, 1))
1441 CALL timeset(routinen//
"_copy_1", handle2)
1442 CALL dbt_copy(t_3c_int_mo_2(1, 1), ri_data%t_3c_int_mo(ispin, 1, 1), order=[2, 1, 3], &
1443 summation=.true., move_data=.true.)
1445 CALL dbt_filter(ri_data%t_3c_int_mo(ispin, 1, 1), ri_data%filter_eps_mo)
1446 CALL timestop(handle2)
1448 CALL timeset(routinen//
"_RIx3C", handle2)
1450 CALL dbt_contract(1.0_dp, ri_data%t_2c_int(ispin, 1), ri_data%t_3c_int_mo(ispin, 1, 1), &
1451 0.0_dp, ri_data%t_3c_ctr_RI(ispin, 1, 1), &
1452 contract_1=[1], notcontract_1=[2], &
1453 contract_2=[1], notcontract_2=[2, 3], &
1454 map_1=[1], map_2=[2, 3], filter_eps=ri_data%filter_eps, &
1455 unit_nr=unit_nr_dbcsr, &
1458 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
1460 CALL timestop(handle2)
1462 CALL timeset(routinen//
"_copy_2", handle2)
1465 CALL dbt_copy(ri_data%t_3c_ctr_RI(ispin, 1, 1), ri_data%t_3c_ctr_KS(ispin, 1, 1), move_data=.true.)
1466 CALL dbt_copy(ri_data%t_3c_ctr_KS(ispin, 1, 1), ri_data%t_3c_ctr_KS_copy(ispin, 1, 1))
1467 CALL timestop(handle2)
1469 CALL timeset(routinen//
"_3Cx3C", handle2)
1470 CALL dbt_contract(-
fac, ri_data%t_3c_ctr_KS(ispin, 1, 1), ri_data%t_3c_ctr_KS_copy(ispin, 1, 1), &
1472 contract_1=[1, 2], notcontract_1=[3], &
1473 contract_2=[1, 2], notcontract_2=[3], &
1474 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps/n_mem, &
1475 unit_nr=unit_nr_dbcsr, move_data=.true., &
1478 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
1480 CALL timestop(handle2)
1483 CALL dbt_batched_contract_finalize(ks_t)
1484 CALL dbt_batched_contract_finalize(ri_data%t_3c_ctr_KS(ispin, 1, 1))
1485 CALL dbt_batched_contract_finalize(ri_data%t_3c_ctr_KS_copy(ispin, 1, 1))
1487 CALL dbt_batched_contract_finalize(ri_data%t_2c_int(ispin, 1))
1488 CALL dbt_batched_contract_finalize(ri_data%t_3c_int_mo(ispin, 1, 1))
1489 CALL dbt_batched_contract_finalize(ri_data%t_3c_ctr_RI(ispin, 1, 1))
1491 CALL dbt_destroy(t_3c_int_mo_1(1, 1))
1492 CALL dbt_destroy(t_3c_int_mo_2(1, 1))
1493 CALL dbt_clear(ri_data%t_3c_int_mo(ispin, 1, 1))
1495 CALL dbt_destroy(mo_coeff_t_split)
1497 CALL dbt_filter(ks_t, ri_data%filter_eps)
1499 CALL dbt_create(ks_matrix(ispin, 1)%matrix, ks_t_mat)
1500 CALL dbt_copy(ks_t, ks_t_mat, move_data=.true.)
1501 CALL dbt_copy_tensor_to_matrix(ks_t_mat, ks_matrix(ispin, 1)%matrix, summation=.true.)
1502 CALL dbt_destroy(ks_t_mat)
1504 DEALLOCATE (mem_end, mem_start, mo_bsizes_2, mem_size, mem_start_block_1, mem_end_block_1, &
1505 mem_start_block_2, mem_end_block_2, batch_ranges_1, batch_ranges_2)
1509 CALL dbt_pgrid_destroy(pgrid_2d)
1510 CALL dbt_destroy(ks_t)
1512 CALL para_env%sync()
1515 ri_data%dbcsr_time = ri_data%dbcsr_time + t2 - t1
1517 CALL timestop(handle)
1534 SUBROUTINE hfx_ri_update_ks_pmat(qs_env, ri_data, ks_matrix, rho_ao, &
1535 geometry_did_change, nspins, fac)
1536 TYPE(qs_environment_type),
POINTER :: qs_env
1537 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
1538 TYPE(dbcsr_p_type),
DIMENSION(:, :) :: ks_matrix, rho_ao
1539 LOGICAL,
INTENT(IN) :: geometry_did_change
1540 INTEGER,
INTENT(IN) :: nspins
1541 REAL(
dp),
INTENT(IN) ::
fac
1543 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_update_ks_Pmat'
1545 INTEGER :: handle, handle2, i_mem, ispin, j_mem, &
1546 n_mem, n_mem_ri, unit_nr, unit_nr_dbcsr
1547 INTEGER(int_8) :: flops_ks_max, flops_p_max, nblks, nflop, &
1548 nze, nze_3c, nze_3c_1, nze_3c_2, &
1550 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: batch_ranges_ao, batch_ranges_ri, dist1, &
1552 INTEGER,
DIMENSION(2, 1) :: bounds_i
1553 INTEGER,
DIMENSION(2, 2) :: bounds_ij, bounds_j
1554 INTEGER,
DIMENSION(3) :: dims_3c
1555 REAL(
dp) :: memory_3c, occ, occ_3c, occ_3c_1, &
1556 occ_3c_2, occ_ks, occ_rho, t1, t2, &
1558 TYPE(dbt_type) :: ks_t, ks_tmp, rho_ao_tmp, t_3c_1, &
1560 TYPE(mp_para_env_type),
POINTER :: para_env
1562 IF (.NOT.
fac > epsilon(0.0_dp))
RETURN
1564 CALL timeset(routinen, handle)
1569 unit_nr_dbcsr = ri_data%unit_nr_dbcsr
1570 unit_nr = ri_data%unit_nr
1574 cpassert(
SIZE(ks_matrix, 2) == 1)
1576 IF (geometry_did_change)
THEN
1577 CALL hfx_ri_pre_scf_pmat(qs_env, ri_data)
1578 DO ispin = 1, nspins
1579 CALL dbt_scale(ri_data%rho_ao_t(ispin, 1), 0.0_dp)
1580 CALL dbt_scale(ri_data%ks_t(ispin, 1), 0.0_dp)
1584 nblks = dbt_get_num_blocks_total(ri_data%t_3c_int_ctr_2(1, 1))
1585 IF (nblks == 0)
THEN
1586 cpabort(
"3-center integrals are not available (first call requires geometry_did_change=.TRUE.)")
1589 n_mem = ri_data%n_mem
1590 n_mem_ri = ri_data%n_mem_RI
1592 CALL dbt_create(ks_matrix(1, 1)%matrix, ks_tmp)
1593 CALL dbt_create(rho_ao(1, 1)%matrix, rho_ao_tmp)
1596 ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
1598 DEALLOCATE (dist1, dist2)
1600 CALL dbt_create(ri_data%t_3c_int_ctr_2(1, 1), t_3c_1)
1601 CALL dbt_create(ri_data%t_3c_int_ctr_1(1, 1), t_3c_3)
1603 CALL para_env%sync()
1606 flops_ks_max = 0; flops_p_max = 0
1608 ALLOCATE (batch_ranges_ri(ri_data%n_mem_RI + 1))
1609 ALLOCATE (batch_ranges_ao(ri_data%n_mem + 1))
1610 batch_ranges_ri(:ri_data%n_mem_RI) = ri_data%starts_array_RI_mem_block(:)
1611 batch_ranges_ri(ri_data%n_mem_RI + 1) = ri_data%ends_array_RI_mem_block(ri_data%n_mem_RI) + 1
1612 batch_ranges_ao(:ri_data%n_mem) = ri_data%starts_array_mem_block(:)
1613 batch_ranges_ao(ri_data%n_mem + 1) = ri_data%ends_array_mem_block(ri_data%n_mem) + 1
1616 DO ispin = 1, nspins
1627 CALL dbt_copy_matrix_to_tensor(rho_ao(ispin, 1)%matrix, rho_ao_tmp)
1630 CALL dbt_scale(ri_data%rho_ao_t(ispin, 1), -1.0_dp)
1631 CALL dbt_copy(rho_ao_tmp, ri_data%rho_ao_t(ispin, 1), summation=.true., move_data=.true.)
1635 CALL dbt_batched_contract_init(ri_data%t_3c_int_ctr_1(1, 1), batch_range_1=batch_ranges_ao, &
1636 batch_range_2=batch_ranges_ri)
1637 CALL dbt_batched_contract_init(t_3c_3, batch_range_1=batch_ranges_ao, batch_range_2=batch_ranges_ri)
1639 CALL dbt_create(ri_data%t_3c_int_ctr_1(1, 1), tensor_old)
1643 CALL dbt_batched_contract_init(ri_data%rho_ao_t(ispin, 1))
1644 CALL dbt_batched_contract_init(ri_data%t_3c_int_ctr_2(1, 1), batch_range_2=batch_ranges_ri, &
1645 batch_range_3=batch_ranges_ao)
1646 CALL dbt_batched_contract_init(t_3c_1, batch_range_2=batch_ranges_ri, batch_range_3=batch_ranges_ao)
1647 DO j_mem = 1, n_mem_ri
1649 CALL timeset(routinen//
"_Px3C", handle2)
1651 CALL dbt_get_info(t_3c_1, nfull_total=dims_3c)
1652 bounds_i(:, 1) = [ri_data%starts_array_mem(i_mem), ri_data%ends_array_mem(i_mem)]
1653 bounds_j(:, 1) = [1, dims_3c(1)]
1654 bounds_j(:, 2) = [ri_data%starts_array_RI_mem(j_mem), ri_data%ends_array_RI_mem(j_mem)]
1656 CALL dbt_contract(1.0_dp, ri_data%rho_ao_t(ispin, 1), ri_data%t_3c_int_ctr_2(1, 1), &
1658 contract_1=[2], notcontract_1=[1], &
1659 contract_2=[3], notcontract_2=[1, 2], &
1660 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
1661 bounds_2=bounds_i, &
1662 bounds_3=bounds_j, &
1663 unit_nr=unit_nr_dbcsr, &
1666 CALL timestop(handle2)
1668 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
1671 nze_3c_1 = nze_3c_1 + nze
1672 occ_3c_1 = occ_3c_1 + occ
1674 CALL timeset(routinen//
"_copy_2", handle2)
1675 CALL dbt_copy(t_3c_1, t_3c_3, order=[3, 2, 1], move_data=.true.)
1676 CALL timestop(handle2)
1678 bounds_ij(:, 1) = [ri_data%starts_array_mem(i_mem), ri_data%ends_array_mem(i_mem)]
1679 bounds_ij(:, 2) = [ri_data%starts_array_RI_mem(j_mem), ri_data%ends_array_RI_mem(j_mem)]
1682 ri_data%store_3c(i_mem, j_mem), ri_data%filter_eps_storage)
1684 CALL dbt_copy(tensor_old, ri_data%t_3c_int_ctr_1(1, 1), move_data=.true.)
1687 nze_3c_2 = nze_3c_2 + nze
1688 occ_3c_2 = occ_3c_2 + occ
1689 CALL timeset(routinen//
"_KS", handle2)
1690 CALL dbt_batched_contract_init(ks_t)
1691 CALL dbt_contract(-
fac, ri_data%t_3c_int_ctr_1(1, 1), t_3c_3, &
1693 contract_1=[1, 2], notcontract_1=[3], &
1694 contract_2=[1, 2], notcontract_2=[3], &
1695 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps/n_mem, &
1696 bounds_1=bounds_ij, &
1697 unit_nr=unit_nr_dbcsr, &
1698 flop=nflop, move_data=.true.)
1700 CALL dbt_batched_contract_finalize(ks_t, unit_nr=unit_nr_dbcsr)
1701 CALL timestop(handle2)
1703 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
1706 CALL dbt_batched_contract_finalize(ri_data%rho_ao_t(ispin, 1), unit_nr=unit_nr_dbcsr)
1707 CALL dbt_batched_contract_finalize(ri_data%t_3c_int_ctr_2(1, 1))
1708 CALL dbt_batched_contract_finalize(t_3c_1)
1710 CALL dbt_batched_contract_finalize(ri_data%t_3c_int_ctr_1(1, 1))
1711 CALL dbt_batched_contract_finalize(t_3c_3)
1714 DO j_mem = 1, n_mem_ri
1715 associate(blk_indices => ri_data%blk_indices(i_mem, j_mem), t_3c => ri_data%t_3c_int_ctr_1(1, 1))
1717 ri_data%store_3c(i_mem, j_mem), ri_data%filter_eps_storage)
1718 CALL dbt_copy(tensor_old, t_3c, move_data=.true.)
1721 CALL compress_tensor(t_3c, blk_indices%ind, ri_data%store_3c(i_mem, j_mem), &
1722 ri_data%filter_eps_storage, unused)
1727 CALL dbt_destroy(tensor_old)
1732 CALL dbt_copy_matrix_to_tensor(rho_ao(ispin, 1)%matrix, rho_ao_tmp)
1733 CALL dbt_copy(rho_ao_tmp, ri_data%rho_ao_t(ispin, 1), move_data=.true.)
1734 CALL dbt_copy(ks_t, ri_data%ks_t(ispin, 1), summation=.true., move_data=.true.)
1736 CALL dbt_copy(ri_data%ks_t(ispin, 1), ks_tmp)
1737 CALL dbt_copy_tensor_to_matrix(ks_tmp, ks_matrix(ispin, 1)%matrix, summation=.true.)
1738 CALL dbt_clear(ks_tmp)
1740 IF (unit_nr > 0 .AND. geometry_did_change)
THEN
1741 WRITE (unit_nr,
'(T6,A,T63,ES7.1,1X,A1,1X,F7.3,A1)') &
1742 'Occupancy of density matrix P:', real(nze_rho,
dp),
'/', occ_rho*100,
'%'
1743 WRITE (unit_nr,
'(T6,A,T63,ES7.1,1X,A1,1X,F7.3,A1)') &
1744 'Occupancy of 3c ints:', real(nze_3c,
dp),
'/', occ_3c*100,
'%'
1745 WRITE (unit_nr,
'(T6,A,T63,ES7.1,1X,A1,1X,F7.3,A1)') &
1746 'Occupancy after contraction with K:', real(nze_3c_2,
dp),
'/', occ_3c_2*100,
'%'
1747 WRITE (unit_nr,
'(T6,A,T63,ES7.1,1X,A1,1X,F7.3,A1)') &
1748 'Occupancy after contraction with P:', real(nze_3c_1,
dp),
'/', occ_3c_1*100,
'%'
1749 WRITE (unit_nr,
'(T6,A,T63,ES7.1,1X,A1,1X,F7.3,A1)') &
1750 'Occupancy of Kohn-Sham matrix:', real(nze_ks,
dp),
'/', occ_ks*100,
'%'
1755 CALL para_env%sync()
1758 ri_data%dbcsr_time = ri_data%dbcsr_time + t2 - t1
1760 CALL dbt_destroy(t_3c_1)
1761 CALL dbt_destroy(t_3c_3)
1763 CALL dbt_destroy(rho_ao_tmp)
1764 CALL dbt_destroy(ks_t)
1765 CALL dbt_destroy(ks_tmp)
1767 CALL timestop(handle)
1781 SUBROUTINE hfx_ri_forces_mo(qs_env, ri_data, nspins, hf_fraction, mo_coeff, use_virial)
1783 TYPE(qs_environment_type),
POINTER :: qs_env
1784 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
1785 INTEGER,
INTENT(IN) :: nspins
1786 REAL(dp),
INTENT(IN) :: hf_fraction
1787 TYPE(dbcsr_type),
DIMENSION(:),
INTENT(IN) :: mo_coeff
1788 LOGICAL,
INTENT(IN),
OPTIONAL :: use_virial
1790 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_forces_mo'
1792 INTEGER :: dummy_int, handle, i_mem, i_xyz, ibasis, ispin, j_mem, k_mem, n_mem, n_mem_input, &
1793 n_mem_input_ri, n_mem_ri, n_mem_ri_fit, n_mos, natom, nkind, unit_nr_dbcsr
1794 INTEGER(int_8) :: nflop
1795 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_of_kind, batch_blk_end, batch_blk_start, &
1796 batch_end, batch_end_ri, batch_end_ri_fit, batch_ranges, batch_ranges_ri, &
1797 batch_ranges_ri_fit, batch_start, batch_start_ri, batch_start_ri_fit, bsizes_mo, dist1, &
1798 dist2, dist3, idx_to_at_ao, idx_to_at_ri, kind_of
1799 INTEGER,
DIMENSION(2, 1) :: bounds_ctr_1d
1800 INTEGER,
DIMENSION(2, 2) :: bounds_ctr_2d
1801 INTEGER,
DIMENSION(3) :: pdims
1802 LOGICAL :: use_virial_prv
1803 REAL(dp) :: pref, spin_fac, t1, t2
1804 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
1805 TYPE(block_ind_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_der_ao_ind, t_3c_der_ri_ind
1806 TYPE(cell_type),
POINTER :: cell
1807 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s
1808 TYPE(dbt_pgrid_type) :: pgrid_1, pgrid_2
1809 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, &
1810 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, &
1811 t_3c_mo_ri_ao, t_3c_mo_ri_mo, t_3c_ri_ao_ao, t_3c_ri_ctr, t_3c_ri_mo_mo, &
1812 t_3c_ri_mo_mo_fit, t_3c_work, t_mo_coeff, t_mo_cpy
1813 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:) :: t_2c_der_metric, t_2c_der_ri, t_2c_mo_ao, &
1814 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, &
1816 TYPE(dft_control_type),
POINTER :: dft_control
1817 TYPE(gto_basis_set_p_type),
ALLOCATABLE, &
1818 DIMENSION(:),
TARGET :: basis_set_ao, basis_set_ri
1819 TYPE(gto_basis_set_type),
POINTER :: orb_basis, ri_basis
1820 TYPE(hfx_compression_type),
ALLOCATABLE, &
1821 DIMENSION(:, :) :: t_3c_der_ao_comp, t_3c_der_ri_comp
1822 TYPE(mp_para_env_type),
POINTER :: para_env
1823 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
1824 TYPE(qs_force_type),
DIMENSION(:),
POINTER :: force
1825 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
1836 use_virial_prv = .false.
1837 IF (
PRESENT(use_virial)) use_virial_prv = use_virial
1838 IF (use_virial_prv)
THEN
1839 cpabort(
"Stress tensor with RI-HFX MO flavor not implemented.")
1842 unit_nr_dbcsr = ri_data%unit_nr_dbcsr
1844 CALL get_qs_env(qs_env, natom=natom, particle_set=particle_set, nkind=nkind, &
1845 atomic_kind_set=atomic_kind_set, cell=cell, force=force, &
1846 matrix_s=matrix_s, para_env=para_env, dft_control=dft_control, &
1847 qs_kind_set=qs_kind_set)
1850 CALL dbt_pgrid_create(para_env, pdims, pgrid_1, tensor_dims=[
SIZE(ri_data%bsizes_AO_split), &
1851 SIZE(ri_data%bsizes_RI_split), &
1852 SIZE(ri_data%bsizes_AO_split)])
1854 CALL dbt_pgrid_create(para_env, pdims, pgrid_2, tensor_dims=[
SIZE(ri_data%bsizes_RI_split), &
1855 SIZE(ri_data%bsizes_AO_split), &
1856 SIZE(ri_data%bsizes_AO_split)])
1858 CALL create_3c_tensor(t_3c_ao_ri_ao, dist1, dist2, dist3, pgrid_1, &
1859 ri_data%bsizes_AO_split, ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, &
1860 [1, 2], [3], name=
"(AO RI | AO)")
1861 DEALLOCATE (dist1, dist2, dist3)
1862 CALL create_3c_tensor(t_3c_ri_ao_ao, dist1, dist2, dist3, pgrid_2, &
1863 ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
1864 [1], [2, 3], name=
"(RI | AO AO)")
1865 DEALLOCATE (dist1, dist2, dist3)
1867 ALLOCATE (basis_set_ri(nkind), basis_set_ao(nkind))
1868 CALL basis_set_list_setup(basis_set_ri, ri_data%ri_basis_type, qs_kind_set)
1869 CALL get_particle_set(particle_set, qs_kind_set, basis=basis_set_ri)
1870 CALL basis_set_list_setup(basis_set_ao, ri_data%orb_basis_type, qs_kind_set)
1871 CALL get_particle_set(particle_set, qs_kind_set, basis=basis_set_ao)
1873 DO ibasis = 1,
SIZE(basis_set_ao)
1874 orb_basis => basis_set_ao(ibasis)%gto_basis_set
1875 CALL init_interaction_radii_orb_basis(orb_basis, ri_data%eps_pgf_orb)
1876 ri_basis => basis_set_ri(ibasis)%gto_basis_set
1877 CALL init_interaction_radii_orb_basis(ri_basis, ri_data%eps_pgf_orb)
1880 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), &
1881 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))
1884 CALL precalc_derivatives(t_3c_der_ri_comp, t_3c_der_ao_comp, t_3c_der_ri_ind, t_3c_der_ao_ind, &
1885 t_2c_der_ri, t_2c_der_metric, t_3c_ri_ao_ao, &
1886 basis_set_ao, basis_set_ri, ri_data, qs_env)
1888 DO ibasis = 1,
SIZE(basis_set_ao)
1889 orb_basis => basis_set_ao(ibasis)%gto_basis_set
1890 ri_basis => basis_set_ri(ibasis)%gto_basis_set
1891 CALL init_interaction_radii_orb_basis(orb_basis, dft_control%qs_control%eps_pgf_orb)
1892 CALL init_interaction_radii_orb_basis(ri_basis, dft_control%qs_control%eps_pgf_orb)
1895 n_mem =
SIZE(t_3c_der_ri_comp, 1)
1897 CALL dbt_create(t_3c_ao_ri_ao, t_3c_der_ri(i_xyz))
1898 CALL dbt_create(t_3c_ao_ri_ao, t_3c_der_ao(i_xyz))
1901 CALL decompress_tensor(t_3c_ri_ao_ao, t_3c_der_ri_ind(i_mem, i_xyz)%ind, &
1902 t_3c_der_ri_comp(i_mem, i_xyz), ri_data%filter_eps_storage)
1903 CALL dbt_copy(t_3c_ri_ao_ao, t_3c_der_ri(i_xyz), order=[2, 1, 3], move_data=.true., summation=.true.)
1905 CALL decompress_tensor(t_3c_ri_ao_ao, t_3c_der_ao_ind(i_mem, i_xyz)%ind, &
1906 t_3c_der_ao_comp(i_mem, i_xyz), ri_data%filter_eps_storage)
1907 CALL dbt_copy(t_3c_ri_ao_ao, t_3c_der_ao(i_xyz), order=[2, 1, 3], move_data=.true., summation=.true.)
1913 CALL dealloc_containers(t_3c_der_ao_comp(i_mem, i_xyz), dummy_int)
1914 CALL dealloc_containers(t_3c_der_ri_comp(i_mem, i_xyz), dummy_int)
1917 DEALLOCATE (t_3c_der_ao_ind, t_3c_der_ri_ind)
1920 CALL dbt_create(t_3c_ao_ri_ao, t_3c_desymm)
1921 CALL dbt_copy(ri_data%t_3c_int_ctr_1(1, 1), t_3c_desymm)
1922 CALL dbt_copy(ri_data%t_3c_int_ctr_1(1, 1), t_3c_desymm, order=[3, 2, 1], &
1923 summation=.true., move_data=.true.)
1925 CALL dbt_destroy(t_3c_ao_ri_ao)
1926 CALL dbt_destroy(t_3c_ri_ao_ao)
1930 IF (nspins == 2) spin_fac = 1.0_dp
1932 ALLOCATE (idx_to_at_ri(
SIZE(ri_data%bsizes_RI_split)))
1933 CALL get_idx_to_atom(idx_to_at_ri, ri_data%bsizes_RI_split, ri_data%bsizes_RI)
1935 ALLOCATE (idx_to_at_ao(
SIZE(ri_data%bsizes_AO_split)))
1936 CALL get_idx_to_atom(idx_to_at_ao, ri_data%bsizes_AO_split, ri_data%bsizes_AO)
1938 CALL get_atomic_kind_set(atomic_kind_set, kind_of=kind_of, atom_of_kind=atom_of_kind)
1941 CALL create_2c_tensor(t_2c_ri, dist1, dist2, ri_data%pgrid_2d, &
1942 ri_data%bsizes_RI_split, ri_data%bsizes_RI_split, name=
"(RI | RI)")
1943 DEALLOCATE (dist1, dist2)
1945 CALL create_2c_tensor(t_2c_ri_pq, dist1, dist2, ri_data%pgrid_2d, &
1946 ri_data%bsizes_RI_fit, ri_data%bsizes_RI_fit, name=
"(RI | RI)")
1947 DEALLOCATE (dist1, dist2)
1949 IF (.NOT. ri_data%same_op)
THEN
1951 CALL dbt_create(t_2c_ri_pq, t_2c_ri_inv)
1952 CALL dbt_create(t_2c_ri_pq, t_2c_ri_met)
1953 CALL dbt_create(ri_data%t_2c_inv(1, 1), t_2c_tmp)
1955 CALL dbt_contract(1.0_dp, ri_data%t_2c_inv(1, 1), ri_data%t_2c_pot(1, 1), &
1957 contract_1=[2], notcontract_1=[1], &
1958 contract_2=[1], notcontract_2=[2], &
1959 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
1960 unit_nr=unit_nr_dbcsr, flop=nflop)
1961 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
1963 CALL dbt_copy(t_2c_tmp, t_2c_ri_inv, move_data=.true.)
1964 CALL dbt_destroy(t_2c_tmp)
1969 n_mem_input = floor((ri_data%n_mem_input - 0.1_dp)**(1._dp/3._dp)) + 1
1970 n_mem_input_ri = floor((ri_data%n_mem_input - 0.1_dp)/n_mem_input**2) + 1
1973 n_mem_ri = n_mem_input_ri
1974 CALL create_tensor_batches(ri_data%bsizes_RI_split, n_mem_ri, batch_start_ri, batch_end_ri, &
1975 batch_blk_start, batch_blk_end)
1976 ALLOCATE (batch_ranges_ri(n_mem_ri + 1))
1977 batch_ranges_ri(1:n_mem_ri) = batch_blk_start(1:n_mem_ri)
1978 batch_ranges_ri(n_mem_ri + 1) = batch_blk_end(n_mem_ri) + 1
1979 DEALLOCATE (batch_blk_start, batch_blk_end)
1981 n_mem_ri_fit = n_mem_input_ri
1982 CALL create_tensor_batches(ri_data%bsizes_RI_fit, n_mem_ri_fit, batch_start_ri_fit, batch_end_ri_fit, &
1983 batch_blk_start, batch_blk_end)
1984 ALLOCATE (batch_ranges_ri_fit(n_mem_ri_fit + 1))
1985 batch_ranges_ri_fit(1:n_mem_ri_fit) = batch_blk_start(1:n_mem_ri_fit)
1986 batch_ranges_ri_fit(n_mem_ri_fit + 1) = batch_blk_end(n_mem_ri_fit) + 1
1987 DEALLOCATE (batch_blk_start, batch_blk_end)
1989 DO ispin = 1, nspins
1992 CALL dbcsr_get_info(mo_coeff(ispin), nfullcols_total=n_mos)
1994 CALL split_block_sizes([n_mos], bsizes_mo, max_size=floor(sqrt(ri_data%max_bsize_MO - 0.1)) + 1)
1998 CALL create_tensor_batches(bsizes_mo, n_mem, batch_start, batch_end, &
1999 batch_blk_start, batch_blk_end)
2000 ALLOCATE (batch_ranges(n_mem + 1))
2001 batch_ranges(1:n_mem) = batch_blk_start(1:n_mem)
2002 batch_ranges(n_mem + 1) = batch_blk_end(n_mem) + 1
2003 DEALLOCATE (batch_blk_start, batch_blk_end)
2006 CALL create_2c_tensor(t_mo_coeff, dist1, dist2, ri_data%pgrid_2d, bsizes_mo, &
2007 ri_data%bsizes_AO_split, name=
"MO coeffs")
2008 DEALLOCATE (dist1, dist2)
2009 CALL dbt_create(mo_coeff(ispin), t_2c_tmp, name=
"MO coeffs")
2010 CALL dbt_copy_matrix_to_tensor(mo_coeff(ispin), t_2c_tmp)
2011 CALL dbt_copy(t_2c_tmp, t_mo_coeff, order=[2, 1], move_data=.true.)
2012 CALL dbt_destroy(t_2c_tmp)
2014 CALL dbt_create(t_mo_coeff, t_mo_cpy)
2015 CALL dbt_copy(t_mo_coeff, t_mo_cpy)
2017 CALL dbt_create(t_mo_coeff, t_2c_mo_ao_ctr(i_xyz))
2018 CALL dbt_create(t_mo_coeff, t_2c_mo_ao(i_xyz))
2021 CALL create_3c_tensor(t_3c_ao_ri_mo, dist1, dist2, dist3, pgrid_1, ri_data%bsizes_AO_split, &
2022 ri_data%bsizes_RI_split, bsizes_mo, [1, 2], [3], name=
"(AO RI| MO)")
2023 DEALLOCATE (dist1, dist2, dist3)
2025 CALL dbt_create(t_3c_ao_ri_mo, t_3c_0)
2026 CALL dbt_destroy(t_3c_ao_ri_mo)
2028 CALL create_3c_tensor(t_3c_mo_ri_ao, dist1, dist2, dist3, pgrid_1, bsizes_mo, ri_data%bsizes_RI_split, &
2029 ri_data%bsizes_AO_split, [1, 2], [3], name=
"(MO RI | AO)")
2030 DEALLOCATE (dist1, dist2, dist3)
2031 CALL dbt_create(t_3c_mo_ri_ao, t_3c_1)
2034 CALL dbt_create(t_3c_mo_ri_ao, t_3c_der_ri_ctr_1(i_xyz))
2035 CALL dbt_create(t_3c_mo_ri_ao, t_3c_der_ao_ctr_1(i_xyz))
2038 CALL create_3c_tensor(t_3c_mo_ri_mo, dist1, dist2, dist3, pgrid_1, bsizes_mo, &
2039 ri_data%bsizes_RI_split, bsizes_mo, [1, 2], [3], name=
"(MO RI | MO)")
2040 DEALLOCATE (dist1, dist2, dist3)
2041 CALL dbt_create(t_3c_mo_ri_mo, t_3c_work)
2043 CALL create_3c_tensor(t_3c_ri_mo_mo, dist1, dist2, dist3, pgrid_2, ri_data%bsizes_RI_split, &
2044 bsizes_mo, bsizes_mo, [1], [2, 3], name=
"(RI| MO MO)")
2045 DEALLOCATE (dist1, dist2, dist3)
2047 CALL dbt_create(t_3c_ri_mo_mo, t_3c_2)
2048 CALL dbt_create(t_3c_ri_mo_mo, t_3c_3)
2049 CALL dbt_create(t_3c_ri_mo_mo, t_3c_ri_ctr)
2051 CALL dbt_create(t_3c_ri_mo_mo, t_3c_der_ri_ctr_2(i_xyz))
2056 CALL create_3c_tensor(t_3c_ri_mo_mo_fit, dist1, dist2, dist3, pgrid_2, ri_data%bsizes_RI_fit, &
2057 bsizes_mo, bsizes_mo, [1], [2, 3], name=
"(RI| MO MO)")
2058 DEALLOCATE (dist1, dist2, dist3)
2060 CALL dbt_create(t_3c_ri_mo_mo_fit, t_3c_4)
2061 CALL dbt_create(t_3c_ri_mo_mo_fit, t_3c_5)
2062 CALL dbt_create(t_3c_ri_mo_mo_fit, t_3c_6)
2064 CALL dbt_batched_contract_init(t_3c_desymm, batch_range_2=batch_ranges_ri)
2065 CALL dbt_batched_contract_init(t_3c_0, batch_range_2=batch_ranges_ri, batch_range_3=batch_ranges)
2068 CALL dbt_batched_contract_init(t_3c_der_ao(i_xyz), batch_range_2=batch_ranges_ri)
2069 CALL dbt_batched_contract_init(t_3c_der_ri(i_xyz), batch_range_2=batch_ranges_ri)
2072 CALL para_env%sync()
2078 bounds_ctr_1d(1, 1) = batch_start(i_mem)
2079 bounds_ctr_1d(2, 1) = batch_end(i_mem)
2081 bounds_ctr_2d(1, 1) = 1
2082 bounds_ctr_2d(2, 1) = sum(ri_data%bsizes_AO)
2085 CALL timeset(routinen//
"_AO2MO_1", handle)
2086 CALL dbt_batched_contract_init(t_mo_coeff)
2087 DO k_mem = 1, n_mem_ri
2088 bounds_ctr_2d(1, 2) = batch_start_ri(k_mem)
2089 bounds_ctr_2d(2, 2) = batch_end_ri(k_mem)
2091 CALL dbt_contract(1.0_dp, t_mo_coeff, t_3c_desymm, &
2093 contract_1=[2], notcontract_1=[1], &
2094 contract_2=[3], notcontract_2=[1, 2], &
2095 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
2096 bounds_2=bounds_ctr_1d, &
2097 bounds_3=bounds_ctr_2d, &
2098 unit_nr=unit_nr_dbcsr, flop=nflop)
2099 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2101 CALL dbt_copy(t_3c_0, t_3c_1, order=[3, 2, 1], move_data=.true.)
2104 DO k_mem = 1, n_mem_ri
2105 bounds_ctr_2d(1, 2) = batch_start_ri(k_mem)
2106 bounds_ctr_2d(2, 2) = batch_end_ri(k_mem)
2108 CALL dbt_contract(1.0_dp, t_mo_coeff, t_3c_der_ao(i_xyz), &
2110 contract_1=[2], notcontract_1=[1], &
2111 contract_2=[3], notcontract_2=[1, 2], &
2112 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
2113 bounds_2=bounds_ctr_1d, &
2114 bounds_3=bounds_ctr_2d, &
2115 unit_nr=unit_nr_dbcsr, flop=nflop)
2116 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2118 CALL dbt_copy(t_3c_0, t_3c_der_ao_ctr_1(i_xyz), order=[3, 2, 1], move_data=.true.)
2120 DO k_mem = 1, n_mem_ri
2121 bounds_ctr_2d(1, 2) = batch_start_ri(k_mem)
2122 bounds_ctr_2d(2, 2) = batch_end_ri(k_mem)
2124 CALL dbt_contract(1.0_dp, t_mo_coeff, t_3c_der_ri(i_xyz), &
2126 contract_1=[2], notcontract_1=[1], &
2127 contract_2=[3], notcontract_2=[1, 2], &
2128 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
2129 bounds_2=bounds_ctr_1d, &
2130 bounds_3=bounds_ctr_2d, &
2131 unit_nr=unit_nr_dbcsr, flop=nflop)
2132 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2134 CALL dbt_copy(t_3c_0, t_3c_der_ri_ctr_1(i_xyz), order=[3, 2, 1], move_data=.true.)
2136 CALL dbt_batched_contract_finalize(t_mo_coeff)
2137 CALL timestop(handle)
2139 CALL dbt_batched_contract_init(t_3c_1, batch_range_1=batch_ranges, batch_range_2=batch_ranges_ri)
2140 CALL dbt_batched_contract_init(t_3c_work, batch_range_1=batch_ranges, batch_range_2=batch_ranges_ri, &
2141 batch_range_3=batch_ranges)
2142 CALL dbt_batched_contract_init(t_3c_2, batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2143 CALL dbt_batched_contract_init(t_3c_3, batch_range_1=batch_ranges_ri, &
2144 batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2146 CALL dbt_batched_contract_init(t_3c_4, batch_range_1=batch_ranges_ri_fit, &
2147 batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2148 CALL dbt_batched_contract_init(t_3c_5, batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2151 CALL dbt_batched_contract_init(t_3c_der_ri_ctr_1(i_xyz), batch_range_1=batch_ranges, &
2152 batch_range_2=batch_ranges_ri)
2153 CALL dbt_batched_contract_init(t_3c_der_ao_ctr_1(i_xyz), batch_range_1=batch_ranges, &
2154 batch_range_2=batch_ranges_ri)
2158 IF (.NOT. ri_data%same_op)
THEN
2159 CALL dbt_batched_contract_init(t_3c_6, batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2164 bounds_ctr_1d(1, 1) = batch_start(j_mem)
2165 bounds_ctr_1d(2, 1) = batch_end(j_mem)
2167 bounds_ctr_2d(1, 1) = batch_start(i_mem)
2168 bounds_ctr_2d(2, 1) = batch_end(i_mem)
2171 CALL timeset(routinen//
"_AO2MO_2", handle)
2172 CALL dbt_batched_contract_init(t_mo_coeff)
2173 DO k_mem = 1, n_mem_ri
2174 bounds_ctr_2d(1, 2) = batch_start_ri(k_mem)
2175 bounds_ctr_2d(2, 2) = batch_end_ri(k_mem)
2177 CALL dbt_contract(1.0_dp, t_mo_coeff, t_3c_1, &
2178 1.0_dp, t_3c_work, &
2179 contract_1=[2], notcontract_1=[1], &
2180 contract_2=[3], notcontract_2=[1, 2], &
2181 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
2182 bounds_2=bounds_ctr_1d, &
2183 bounds_3=bounds_ctr_2d, &
2184 unit_nr=unit_nr_dbcsr, flop=nflop)
2185 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2187 CALL dbt_batched_contract_finalize(t_mo_coeff)
2188 CALL timestop(handle)
2190 bounds_ctr_2d(1, 1) = batch_start(i_mem)
2191 bounds_ctr_2d(2, 1) = batch_end(i_mem)
2192 bounds_ctr_2d(1, 2) = batch_start(j_mem)
2193 bounds_ctr_2d(2, 2) = batch_end(j_mem)
2196 CALL timeset(routinen//
"_2c_inv", handle)
2197 CALL dbt_copy(t_3c_work, t_3c_3, order=[2, 1, 3], move_data=.true.)
2198 DO k_mem = 1, n_mem_ri
2199 bounds_ctr_1d(1, 1) = batch_start_ri(k_mem)
2200 bounds_ctr_1d(2, 1) = batch_end_ri(k_mem)
2202 CALL dbt_batched_contract_init(ri_data%t_2c_inv(1, 1))
2203 CALL dbt_contract(1.0_dp, ri_data%t_2c_inv(1, 1), t_3c_3, &
2205 contract_1=[2], notcontract_1=[1], &
2206 contract_2=[1], notcontract_2=[2, 3], &
2207 map_1=[1], map_2=[2, 3], filter_eps=ri_data%filter_eps, &
2208 bounds_1=bounds_ctr_1d, &
2209 bounds_3=bounds_ctr_2d, &
2210 unit_nr=unit_nr_dbcsr, flop=nflop)
2211 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2212 CALL dbt_batched_contract_finalize(ri_data%t_2c_inv(1, 1))
2214 CALL dbt_copy(t_3c_ri_mo_mo, t_3c_3)
2215 CALL timestop(handle)
2218 bounds_ctr_1d(1, 1) = batch_start(j_mem)
2219 bounds_ctr_1d(2, 1) = batch_end(j_mem)
2221 bounds_ctr_2d(1, 1) = batch_start(i_mem)
2222 bounds_ctr_2d(2, 1) = batch_end(i_mem)
2224 CALL timeset(routinen//
"_AO2MO_2", handle)
2225 CALL dbt_batched_contract_init(t_mo_coeff)
2227 DO k_mem = 1, n_mem_ri
2228 bounds_ctr_2d(1, 2) = batch_start_ri(k_mem)
2229 bounds_ctr_2d(2, 2) = batch_end_ri(k_mem)
2231 CALL dbt_contract(1.0_dp, t_mo_coeff, t_3c_der_ri_ctr_1(i_xyz), &
2232 1.0_dp, t_3c_work, &
2233 contract_1=[2], notcontract_1=[1], &
2234 contract_2=[3], notcontract_2=[1, 2], &
2235 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
2236 bounds_2=bounds_ctr_1d, &
2237 bounds_3=bounds_ctr_2d, &
2238 unit_nr=unit_nr_dbcsr, flop=nflop)
2239 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2241 CALL dbt_copy(t_3c_work, t_3c_der_ri_ctr_2(i_xyz), order=[2, 1, 3], move_data=.true.)
2243 CALL dbt_batched_contract_finalize(t_mo_coeff)
2244 CALL timestop(handle)
2246 bounds_ctr_2d(1, 1) = batch_start(i_mem)
2247 bounds_ctr_2d(2, 1) = batch_end(i_mem)
2248 bounds_ctr_2d(1, 2) = batch_start(j_mem)
2249 bounds_ctr_2d(2, 2) = batch_end(j_mem)
2252 CALL timeset(routinen//
"_PQ_der", handle)
2253 CALL dbt_copy(t_3c_2, t_3c_4, move_data=.true.)
2254 CALL dbt_copy(t_3c_4, t_3c_5)
2255 DO k_mem = 1, n_mem_ri_fit
2256 bounds_ctr_1d(1, 1) = batch_start_ri_fit(k_mem)
2257 bounds_ctr_1d(2, 1) = batch_end_ri_fit(k_mem)
2259 CALL dbt_batched_contract_init(t_2c_ri_pq)
2260 CALL dbt_contract(1.0_dp, t_3c_4, t_3c_5, &
2261 1.0_dp, t_2c_ri_pq, &
2262 contract_1=[2, 3], notcontract_1=[1], &
2263 contract_2=[2, 3], notcontract_2=[1], &
2264 bounds_1=bounds_ctr_2d, &
2265 bounds_2=bounds_ctr_1d, &
2266 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2267 unit_nr=unit_nr_dbcsr, flop=nflop)
2268 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2269 CALL dbt_batched_contract_finalize(t_2c_ri_pq)
2271 CALL timestop(handle)
2274 IF (.NOT. ri_data%same_op)
THEN
2275 CALL timeset(routinen//
"_metric", handle)
2276 DO k_mem = 1, n_mem_ri_fit
2277 bounds_ctr_1d(1, 1) = batch_start_ri_fit(k_mem)
2278 bounds_ctr_1d(2, 1) = batch_end_ri_fit(k_mem)
2280 CALL dbt_batched_contract_init(t_2c_ri_inv)
2281 CALL dbt_contract(1.0_dp, t_2c_ri_inv, t_3c_4, &
2283 contract_1=[2], notcontract_1=[1], &
2284 contract_2=[1], notcontract_2=[2, 3], &
2285 bounds_1=bounds_ctr_1d, &
2286 bounds_3=bounds_ctr_2d, &
2287 map_1=[1], map_2=[2, 3], filter_eps=ri_data%filter_eps, &
2288 unit_nr=unit_nr_dbcsr, flop=nflop)
2289 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2290 CALL dbt_batched_contract_finalize(t_2c_ri_inv)
2292 CALL dbt_copy(t_3c_6, t_3c_4, move_data=.true.)
2295 DO k_mem = 1, n_mem_ri_fit
2296 bounds_ctr_1d(1, 1) = batch_start_ri_fit(k_mem)
2297 bounds_ctr_1d(2, 1) = batch_end_ri_fit(k_mem)
2299 CALL dbt_batched_contract_init(t_2c_ri_met)
2300 CALL dbt_contract(1.0_dp, t_3c_4, t_3c_5, &
2301 1.0_dp, t_2c_ri_met, &
2302 contract_1=[2, 3], notcontract_1=[1], &
2303 contract_2=[2, 3], notcontract_2=[1], &
2304 bounds_1=bounds_ctr_2d, &
2305 bounds_2=bounds_ctr_1d, &
2306 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2307 unit_nr=unit_nr_dbcsr, flop=nflop)
2308 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2309 CALL dbt_batched_contract_finalize(t_2c_ri_met)
2311 CALL timestop(handle)
2313 CALL dbt_copy(t_3c_ri_mo_mo_fit, t_3c_5)
2318 CALL timeset(routinen//
"_3c_RI", handle)
2319 pref = -0.5_dp*2.0_dp*hf_fraction*spin_fac
2320 CALL dbt_copy(t_3c_4, t_3c_ri_ctr, move_data=.true.)
2323 CALL timestop(handle)
2327 bounds_ctr_2d(1, 1) = batch_start(i_mem)
2328 bounds_ctr_2d(2, 1) = batch_end(i_mem)
2330 bounds_ctr_1d(1, 1) = batch_start(j_mem)
2331 bounds_ctr_1d(2, 1) = batch_end(j_mem)
2333 CALL timeset(routinen//
"_3c_AO", handle)
2334 CALL dbt_copy(t_3c_ri_ctr, t_3c_work, order=[2, 1, 3], move_data=.true.)
2337 CALL dbt_batched_contract_init(t_2c_mo_ao_ctr(i_xyz))
2338 DO k_mem = 1, n_mem_ri
2339 bounds_ctr_2d(1, 2) = batch_start_ri(k_mem)
2340 bounds_ctr_2d(2, 2) = batch_end_ri(k_mem)
2342 CALL dbt_contract(1.0_dp, t_3c_work, t_3c_der_ao_ctr_1(i_xyz), &
2343 1.0_dp, t_2c_mo_ao_ctr(i_xyz), &
2344 contract_1=[1, 2], notcontract_1=[3], &
2345 contract_2=[1, 2], notcontract_2=[3], &
2346 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2347 bounds_1=bounds_ctr_2d, &
2348 bounds_2=bounds_ctr_1d, &
2349 unit_nr=unit_nr_dbcsr, flop=nflop)
2350 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2352 CALL dbt_batched_contract_finalize(t_2c_mo_ao_ctr(i_xyz))
2354 CALL timestop(handle)
2357 CALL dbt_batched_contract_finalize(t_3c_1)
2358 CALL dbt_batched_contract_finalize(t_3c_work)
2359 CALL dbt_batched_contract_finalize(t_3c_2)
2360 CALL dbt_batched_contract_finalize(t_3c_3)
2361 CALL dbt_batched_contract_finalize(t_3c_4)
2362 CALL dbt_batched_contract_finalize(t_3c_5)
2365 CALL dbt_batched_contract_finalize(t_3c_der_ri_ctr_1(i_xyz))
2366 CALL dbt_batched_contract_finalize(t_3c_der_ao_ctr_1(i_xyz))
2369 IF (.NOT. ri_data%same_op)
THEN
2370 CALL dbt_batched_contract_finalize(t_3c_6)
2374 CALL dbt_batched_contract_finalize(t_3c_desymm)
2375 CALL dbt_batched_contract_finalize(t_3c_0)
2378 CALL dbt_batched_contract_finalize(t_3c_der_ao(i_xyz))
2379 CALL dbt_batched_contract_finalize(t_3c_der_ri(i_xyz))
2383 pref = -0.5_dp*4.0_dp*hf_fraction*spin_fac
2385 CALL dbt_copy(t_2c_mo_ao_ctr(i_xyz), t_2c_mo_ao(i_xyz), move_data=.true.)
2386 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)
2387 CALL dbt_clear(t_2c_mo_ao(i_xyz))
2391 pref = 0.5_dp*hf_fraction*spin_fac
2392 IF (.NOT. ri_data%same_op) pref = -pref
2395 CALL dbt_copy(t_2c_ri_pq, t_2c_ri, move_data=.true.)
2397 kind_of, idx_to_at_ri, pref)
2398 CALL dbt_clear(t_2c_ri)
2401 IF (.NOT. ri_data%same_op)
THEN
2402 pref = 0.5_dp*2.0_dp*hf_fraction*spin_fac
2404 CALL dbt_copy(t_2c_ri_met, t_2c_ri, move_data=.true.)
2406 kind_of, idx_to_at_ri, pref)
2407 CALL dbt_clear(t_2c_ri)
2410 CALL dbt_destroy(t_3c_0)
2411 CALL dbt_destroy(t_3c_1)
2412 CALL dbt_destroy(t_3c_2)
2413 CALL dbt_destroy(t_3c_3)
2414 CALL dbt_destroy(t_3c_4)
2415 CALL dbt_destroy(t_3c_5)
2416 CALL dbt_destroy(t_3c_6)
2417 CALL dbt_destroy(t_3c_work)
2418 CALL dbt_destroy(t_3c_ri_ctr)
2419 CALL dbt_destroy(t_3c_mo_ri_ao)
2420 CALL dbt_destroy(t_3c_mo_ri_mo)
2421 CALL dbt_destroy(t_3c_ri_mo_mo)
2422 CALL dbt_destroy(t_3c_ri_mo_mo_fit)
2423 CALL dbt_destroy(t_mo_coeff)
2424 CALL dbt_destroy(t_mo_cpy)
2426 CALL dbt_destroy(t_2c_mo_ao(i_xyz))
2427 CALL dbt_destroy(t_2c_mo_ao_ctr(i_xyz))
2428 CALL dbt_destroy(t_3c_der_ri_ctr_1(i_xyz))
2429 CALL dbt_destroy(t_3c_der_ao_ctr_1(i_xyz))
2430 CALL dbt_destroy(t_3c_der_ri_ctr_2(i_xyz))
2432 DEALLOCATE (batch_ranges, batch_start, batch_end)
2436 CALL dbt_pgrid_destroy(pgrid_1)
2437 CALL dbt_pgrid_destroy(pgrid_2)
2438 CALL dbt_destroy(t_3c_desymm)
2439 CALL dbt_destroy(t_2c_ri)
2440 CALL dbt_destroy(t_2c_ri_pq)
2441 IF (.NOT. ri_data%same_op)
THEN
2442 CALL dbt_destroy(t_2c_ri_met)
2443 CALL dbt_destroy(t_2c_ri_inv)
2446 CALL dbt_destroy(t_3c_der_ao(i_xyz))
2447 CALL dbt_destroy(t_3c_der_ri(i_xyz))
2448 CALL dbt_destroy(t_2c_der_ri(i_xyz))
2449 IF (.NOT. ri_data%same_op)
CALL dbt_destroy(t_2c_der_metric(i_xyz))
2451 CALL dbt_copy(ri_data%t_3c_int_ctr_2(1, 1), ri_data%t_3c_int_ctr_1(1, 1))
2453 CALL para_env%sync()
2456 ri_data%dbcsr_time = ri_data%dbcsr_time + t2 - t1
2458 END SUBROUTINE hfx_ri_forces_mo
2472 SUBROUTINE hfx_ri_forces_pmat(qs_env, ri_data, nspins, hf_fraction, rho_ao, rho_ao_resp, &
2473 use_virial, resp_only, rescale_factor)
2475 TYPE(qs_environment_type),
POINTER :: qs_env
2476 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
2477 INTEGER,
INTENT(IN) :: nspins
2478 REAL(dp),
INTENT(IN) :: hf_fraction
2479 TYPE(dbcsr_p_type),
DIMENSION(:, :) :: rho_ao
2480 TYPE(dbcsr_p_type),
DIMENSION(:),
OPTIONAL :: rho_ao_resp
2481 LOGICAL,
INTENT(IN),
OPTIONAL :: use_virial, resp_only
2482 REAL(dp),
INTENT(IN),
OPTIONAL :: rescale_factor
2484 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_forces_Pmat'
2486 INTEGER :: dummy_int, handle, i_mem, i_spin, i_xyz, &
2487 ibasis, j_mem, j_xyz, k_mem, k_xyz, &
2488 n_mem, n_mem_ri, natom, nkind, &
2490 INTEGER(int_8) :: nflop
2491 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom_of_kind, batch_end, batch_end_ri, batch_ranges, &
2492 batch_ranges_ri, batch_start, batch_start_ri, dist1, dist2, dist3, idx_to_at_ao, &
2493 idx_to_at_ri, kind_of
2494 INTEGER,
DIMENSION(2, 1) :: ibounds, jbounds, kbounds
2495 INTEGER,
DIMENSION(2, 2) :: ijbounds
2496 INTEGER,
DIMENSION(2, 3) :: bounds_cpy
2497 INTEGER,
DIMENSION(:),
POINTER :: col_bsize, row_bsize
2498 LOGICAL :: do_resp, resp_only_prv, use_virial_prv
2499 REAL(dp) :: pref, spin_fac, t1, t2
2500 REAL(dp),
DIMENSION(3, 3) :: work_virial
2501 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
2502 TYPE(block_ind_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_der_ao_ind, t_3c_der_ri_ind
2503 TYPE(cell_type),
POINTER :: cell
2504 TYPE(dbcsr_distribution_type),
POINTER :: dbcsr_dist
2505 TYPE(dbcsr_type) :: dbcsr_tmp, virial_trace
2506 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, &
2507 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, &
2508 t_3c_int_2, t_3c_ri_ao_ao, t_3c_sparse, t_3c_virial, t_r, t_svs
2509 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:) :: t_2c_der_metric, t_2c_der_ri, &
2510 t_3c_der_ao, t_3c_der_ri
2511 TYPE(dft_control_type),
POINTER :: dft_control
2512 TYPE(gto_basis_set_p_type),
ALLOCATABLE, &
2513 DIMENSION(:),
TARGET :: basis_set_ao, basis_set_ri
2514 TYPE(gto_basis_set_type),
POINTER :: orb_basis, ri_basis
2515 TYPE(hfx_compression_type),
ALLOCATABLE, &
2516 DIMENSION(:, :) :: t_3c_der_ao_comp, t_3c_der_ri_comp
2517 TYPE(mp_para_env_type),
POINTER :: para_env
2518 TYPE(neighbor_list_3c_type) :: nl_3c
2519 TYPE(neighbor_list_set_p_type),
DIMENSION(:), &
2520 POINTER :: nl_2c_met, nl_2c_pot
2521 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
2522 TYPE(qs_force_type),
DIMENSION(:),
POINTER :: force
2523 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2524 TYPE(virial_type),
POINTER :: virial
2538 NULLIFY (particle_set, virial, cell, force, atomic_kind_set, nl_2c_pot, nl_2c_met)
2539 NULLIFY (orb_basis, ri_basis, qs_kind_set, particle_set, dft_control, dbcsr_dist)
2541 use_virial_prv = .false.
2542 IF (
PRESENT(use_virial)) use_virial_prv = use_virial
2545 IF (
PRESENT(rho_ao_resp))
THEN
2546 IF (
ASSOCIATED(rho_ao_resp(1)%matrix)) do_resp = .true.
2549 resp_only_prv = .false.
2550 IF (
PRESENT(resp_only)) resp_only_prv = resp_only
2552 unit_nr_dbcsr = ri_data%unit_nr_dbcsr
2554 CALL get_qs_env(qs_env, natom=natom, particle_set=particle_set, nkind=nkind, &
2555 atomic_kind_set=atomic_kind_set, virial=virial, &
2556 cell=cell, force=force, para_env=para_env, dft_control=dft_control, &
2557 qs_kind_set=qs_kind_set, dbcsr_dist=dbcsr_dist)
2559 CALL create_3c_tensor(t_3c_ao_ri_ao, dist1, dist2, dist3, ri_data%pgrid_1, &
2560 ri_data%bsizes_AO_split, ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, &
2561 [1, 2], [3], name=
"(AO RI | AO)")
2562 DEALLOCATE (dist1, dist2, dist3)
2564 CALL create_3c_tensor(t_3c_ri_ao_ao, dist1, dist2, dist3, ri_data%pgrid_2, &
2565 ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
2566 [1], [2, 3], name=
"(RI | AO AO)")
2567 DEALLOCATE (dist1, dist2, dist3)
2569 ALLOCATE (basis_set_ri(nkind), basis_set_ao(nkind))
2570 CALL basis_set_list_setup(basis_set_ri, ri_data%ri_basis_type, qs_kind_set)
2571 CALL get_particle_set(particle_set, qs_kind_set, basis=basis_set_ri)
2572 CALL basis_set_list_setup(basis_set_ao, ri_data%orb_basis_type, qs_kind_set)
2573 CALL get_particle_set(particle_set, qs_kind_set, basis=basis_set_ao)
2575 DO ibasis = 1,
SIZE(basis_set_ao)
2576 orb_basis => basis_set_ao(ibasis)%gto_basis_set
2577 CALL init_interaction_radii_orb_basis(orb_basis, ri_data%eps_pgf_orb)
2578 ri_basis => basis_set_ri(ibasis)%gto_basis_set
2579 CALL init_interaction_radii_orb_basis(ri_basis, ri_data%eps_pgf_orb)
2583 ALLOCATE (t_2c_der_metric(3), t_2c_der_ri(3), t_3c_der_ao(3), t_3c_der_ri(3))
2584 IF (use_virial)
THEN
2585 CALL precalc_derivatives(t_3c_der_ri_comp, t_3c_der_ao_comp, t_3c_der_ri_ind, t_3c_der_ao_ind, &
2586 t_2c_der_ri, t_2c_der_metric, t_3c_ri_ao_ao, &
2587 basis_set_ao, basis_set_ri, ri_data, qs_env, &
2588 nl_2c_pot=nl_2c_pot, nl_2c_met=nl_2c_met, &
2589 nl_3c_out=nl_3c, t_3c_virial=t_3c_virial)
2591 ALLOCATE (col_bsize(natom), row_bsize(natom))
2592 col_bsize(:) = ri_data%bsizes_RI
2593 row_bsize(:) = ri_data%bsizes_RI
2594 CALL dbcsr_create(virial_trace,
"virial_trace", dbcsr_dist, dbcsr_type_no_symmetry, row_bsize, col_bsize)
2595 CALL dbt_create(virial_trace, t_2c_virial)
2596 DEALLOCATE (col_bsize, row_bsize)
2598 CALL precalc_derivatives(t_3c_der_ri_comp, t_3c_der_ao_comp, t_3c_der_ri_ind, t_3c_der_ao_ind, &
2599 t_2c_der_ri, t_2c_der_metric, t_3c_ri_ao_ao, &
2600 basis_set_ao, basis_set_ri, ri_data, qs_env)
2604 CALL dbt_create(t_3c_ri_ao_ao, t_3c_sparse)
2606 DO i_mem = 1,
SIZE(t_3c_der_ri_comp, 1)
2607 CALL decompress_tensor(t_3c_ri_ao_ao, t_3c_der_ri_ind(i_mem, i_xyz)%ind, &
2608 t_3c_der_ri_comp(i_mem, i_xyz), ri_data%filter_eps_storage)
2609 CALL dbt_copy(t_3c_ri_ao_ao, t_3c_sparse, summation=.true., move_data=.true.)
2611 CALL decompress_tensor(t_3c_ri_ao_ao, t_3c_der_ao_ind(i_mem, i_xyz)%ind, &
2612 t_3c_der_ao_comp(i_mem, i_xyz), ri_data%filter_eps_storage)
2613 CALL dbt_copy(t_3c_ri_ao_ao, t_3c_sparse, summation=.true.)
2614 CALL dbt_copy(t_3c_ri_ao_ao, t_3c_sparse, order=[1, 3, 2], summation=.true., move_data=.true.)
2619 CALL dbt_create(t_3c_ri_ao_ao, t_3c_der_ri(i_xyz))
2620 CALL dbt_create(t_3c_ri_ao_ao, t_3c_der_ao(i_xyz))
2625 IF (nspins == 2) spin_fac = 1.0_dp
2626 IF (
PRESENT(rescale_factor)) spin_fac = spin_fac*rescale_factor
2628 ALLOCATE (idx_to_at_ri(
SIZE(ri_data%bsizes_RI_split)))
2629 CALL get_idx_to_atom(idx_to_at_ri, ri_data%bsizes_RI_split, ri_data%bsizes_RI)
2631 ALLOCATE (idx_to_at_ao(
SIZE(ri_data%bsizes_AO_split)))
2632 CALL get_idx_to_atom(idx_to_at_ao, ri_data%bsizes_AO_split, ri_data%bsizes_AO)
2634 CALL get_atomic_kind_set(atomic_kind_set, kind_of=kind_of, atom_of_kind=atom_of_kind)
2637 n_mem = ri_data%n_mem
2638 ALLOCATE (batch_start(n_mem), batch_end(n_mem))
2639 batch_start(:) = ri_data%starts_array_mem(:)
2640 batch_end(:) = ri_data%ends_array_mem(:)
2642 ALLOCATE (batch_ranges(n_mem + 1))
2643 batch_ranges(:n_mem) = ri_data%starts_array_mem_block(:)
2644 batch_ranges(n_mem + 1) = ri_data%ends_array_mem_block(n_mem) + 1
2646 n_mem_ri = ri_data%n_mem_RI
2647 ALLOCATE (batch_start_ri(n_mem_ri), batch_end_ri(n_mem_ri))
2648 batch_start_ri(:) = ri_data%starts_array_RI_mem(:)
2649 batch_end_ri(:) = ri_data%ends_array_RI_mem(:)
2651 ALLOCATE (batch_ranges_ri(n_mem_ri + 1))
2652 batch_ranges_ri(:n_mem_ri) = ri_data%starts_array_RI_mem_block(:)
2653 batch_ranges_ri(n_mem_ri + 1) = ri_data%ends_array_RI_mem_block(n_mem_ri) + 1
2656 CALL create_2c_tensor(rho_ao_1, dist1, dist2, ri_data%pgrid_2d, &
2657 ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
2659 DEALLOCATE (dist1, dist2)
2660 CALL dbt_create(rho_ao_1, rho_ao_2)
2662 CALL create_2c_tensor(t_2c_ri, dist1, dist2, ri_data%pgrid_2d, &
2663 ri_data%bsizes_RI_split, ri_data%bsizes_RI_split, name=
"(RI | RI)")
2664 DEALLOCATE (dist1, dist2)
2665 CALL dbt_create(t_2c_ri, t_svs)
2666 CALL dbt_create(t_2c_ri, t_r)
2667 CALL dbt_create(t_2c_ri, t_2c_ri_tmp)
2669 CALL dbt_create(t_3c_ao_ri_ao, t_3c_1)
2670 CALL dbt_create(t_3c_ao_ri_ao, t_3c_2)
2671 CALL dbt_create(t_3c_ri_ao_ao, t_3c_3)
2672 CALL dbt_create(t_3c_ri_ao_ao, t_3c_4)
2673 CALL dbt_create(t_3c_ri_ao_ao, t_3c_5)
2674 CALL dbt_create(t_3c_ri_ao_ao, t_3c_help_1)
2675 CALL dbt_create(t_3c_ri_ao_ao, t_3c_help_2)
2677 CALL dbt_create(t_3c_ao_ri_ao, t_3c_int)
2678 CALL dbt_copy(ri_data%t_3c_int_ctr_2(1, 1), t_3c_int)
2680 CALL dbt_create(t_3c_ri_ao_ao, t_3c_int_2)
2682 CALL para_env%sync()
2686 IF (.NOT. ri_data%same_op)
THEN
2688 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, &
2689 contract_1=[2], notcontract_1=[1], &
2690 contract_2=[1], notcontract_2=[2], &
2691 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2692 unit_nr=unit_nr_dbcsr, flop=nflop)
2693 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2695 CALL dbt_contract(1.0_dp, t_2c_ri, ri_data%t_2c_inv(1, 1), 0.0_dp, t_svs, &
2696 contract_1=[2], notcontract_1=[1], &
2697 contract_2=[1], notcontract_2=[2], &
2698 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2699 unit_nr=unit_nr_dbcsr, flop=nflop)
2700 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2703 CALL dbt_copy(ri_data%t_2c_inv(1, 1), t_svs)
2706 CALL dbt_batched_contract_init(t_3c_int, batch_range_1=batch_ranges, batch_range_3=batch_ranges)
2707 CALL dbt_batched_contract_init(t_3c_int_2, batch_range_1=batch_ranges_ri, &
2708 batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2709 CALL dbt_batched_contract_init(t_3c_1, batch_range_1=batch_ranges, batch_range_3=batch_ranges)
2710 CALL dbt_batched_contract_init(t_3c_2, batch_range_1=batch_ranges, batch_range_3=batch_ranges)
2711 CALL dbt_batched_contract_init(t_3c_3, batch_range_1=batch_ranges_ri, &
2712 batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2713 CALL dbt_batched_contract_init(t_3c_4, batch_range_1=batch_ranges_ri, &
2714 batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2715 CALL dbt_batched_contract_init(t_3c_5, 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_sparse, batch_range_1=batch_ranges_ri, &
2718 batch_range_2=batch_ranges, batch_range_3=batch_ranges)
2720 DO i_spin = 1, nspins
2723 CALL dbt_create(rho_ao(i_spin, 1)%matrix, t_2c_tmp)
2724 CALL dbt_copy_matrix_to_tensor(rho_ao(i_spin, 1)%matrix, t_2c_tmp)
2725 CALL dbt_copy(t_2c_tmp, rho_ao_1, move_data=.true.)
2726 CALL dbt_destroy(t_2c_tmp)
2728 IF (.NOT. do_resp)
THEN
2729 CALL dbt_copy(rho_ao_1, rho_ao_2)
2730 ELSE IF (do_resp .AND. resp_only_prv)
THEN
2732 CALL dbt_create(rho_ao_resp(i_spin)%matrix, t_2c_tmp)
2733 CALL dbt_copy_matrix_to_tensor(rho_ao_resp(i_spin)%matrix, t_2c_tmp)
2734 CALL dbt_copy(t_2c_tmp, rho_ao_2)
2736 CALL dbt_copy(t_2c_tmp, rho_ao_2, summation=.true., move_data=.true.)
2737 CALL dbt_destroy(t_2c_tmp)
2741 CALL dbt_copy(rho_ao_1, rho_ao_2)
2742 CALL dbcsr_create(dbcsr_tmp, template=rho_ao_resp(i_spin)%matrix)
2743 CALL dbcsr_add(dbcsr_tmp, rho_ao_resp(i_spin)%matrix, 0.0_dp, -1.0_dp)
2744 CALL dbt_create(dbcsr_tmp, t_2c_tmp)
2745 CALL dbt_copy_matrix_to_tensor(dbcsr_tmp, t_2c_tmp)
2746 CALL dbt_copy(t_2c_tmp, rho_ao_1, summation=.true., move_data=.true.)
2747 CALL dbcsr_release(dbcsr_tmp)
2749 CALL dbt_copy_matrix_to_tensor(rho_ao_resp(i_spin)%matrix, t_2c_tmp)
2750 CALL dbt_copy(t_2c_tmp, rho_ao_2, summation=.true., move_data=.true.)
2751 CALL dbt_destroy(t_2c_tmp)
2754 work_virial = 0.0_dp
2756 CALL timeset(routinen//
"_3c", handle)
2759 ibounds(:, 1) = [batch_start(i_mem), batch_end(i_mem)]
2761 CALL dbt_batched_contract_init(rho_ao_1)
2762 CALL dbt_contract(1.0_dp, rho_ao_1, t_3c_int, 0.0_dp, t_3c_1, &
2763 contract_1=[1], notcontract_1=[2], &
2764 contract_2=[3], notcontract_2=[1, 2], &
2765 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
2766 bounds_2=ibounds, unit_nr=unit_nr_dbcsr, flop=nflop)
2767 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2768 CALL dbt_batched_contract_finalize(rho_ao_1)
2770 CALL dbt_copy(t_3c_1, t_3c_2, order=[3, 2, 1], move_data=.true.)
2773 jbounds(:, 1) = [batch_start(j_mem), batch_end(j_mem)]
2775 CALL dbt_batched_contract_init(rho_ao_2)
2776 CALL dbt_contract(1.0_dp, rho_ao_2, t_3c_2, 0.0_dp, t_3c_1, &
2777 contract_1=[1], notcontract_1=[2], &
2778 contract_2=[3], notcontract_2=[1, 2], &
2779 map_1=[3], map_2=[1, 2], filter_eps=ri_data%filter_eps, &
2780 bounds_2=jbounds, unit_nr=unit_nr_dbcsr, flop=nflop)
2781 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2782 CALL dbt_batched_contract_finalize(rho_ao_2)
2784 bounds_cpy(:, 1) = [batch_start(i_mem), batch_end(i_mem)]
2785 bounds_cpy(:, 2) = [1, sum(ri_data%bsizes_RI)]
2786 bounds_cpy(:, 3) = [batch_start(j_mem), batch_end(j_mem)]
2787 CALL dbt_copy(t_3c_int, t_3c_int_2, order=[2, 1, 3], bounds=bounds_cpy)
2788 CALL dbt_copy(t_3c_1, t_3c_3, order=[2, 1, 3], move_data=.true.)
2790 DO k_mem = 1, n_mem_ri
2791 kbounds(:, 1) = [batch_start_ri(k_mem), batch_end_ri(k_mem)]
2793 bounds_cpy(:, 1) = [batch_start_ri(k_mem), batch_end_ri(k_mem)]
2794 bounds_cpy(:, 2) = [batch_start(i_mem), batch_end(i_mem)]
2795 bounds_cpy(:, 3) = [batch_start(j_mem), batch_end(j_mem)]
2796 CALL dbt_copy(t_3c_sparse, t_3c_4, bounds=bounds_cpy)
2799 CALL dbt_batched_contract_init(t_svs)
2800 CALL dbt_contract(1.0_dp, t_svs, t_3c_3, 0.0_dp, t_3c_4, &
2801 contract_1=[2], notcontract_1=[1], &
2802 contract_2=[1], notcontract_2=[2, 3], &
2803 map_1=[1], map_2=[2, 3], filter_eps=ri_data%filter_eps, &
2804 retain_sparsity=.true., unit_nr=unit_nr_dbcsr, flop=nflop)
2805 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2806 CALL dbt_batched_contract_finalize(t_svs)
2808 CALL dbt_copy(t_3c_4, t_3c_5, summation=.true., move_data=.true.)
2810 ijbounds(:, 1) = ibounds(:, 1)
2811 ijbounds(:, 2) = jbounds(:, 1)
2814 CALL dbt_batched_contract_init(t_r)
2815 CALL dbt_contract(1.0_dp, t_3c_int_2, t_3c_3, 1.0_dp, t_r, &
2816 contract_1=[2, 3], notcontract_1=[1], &
2817 contract_2=[2, 3], notcontract_2=[1], &
2818 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2819 bounds_1=ijbounds, bounds_3=kbounds, &
2820 unit_nr=unit_nr_dbcsr, flop=nflop)
2821 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2822 CALL dbt_batched_contract_finalize(t_r)
2827 CALL dbt_copy(t_3c_5, t_3c_help_1, move_data=.true.)
2830 pref = -0.5_dp*2.0_dp*hf_fraction*spin_fac
2832 DO k_mem = 1,
SIZE(t_3c_der_ri_comp, 1)
2834 CALL dbt_clear(t_3c_der_ri(i_xyz))
2835 CALL decompress_tensor(t_3c_der_ri(i_xyz), t_3c_der_ri_ind(k_mem, i_xyz)%ind, &
2836 t_3c_der_ri_comp(k_mem, i_xyz), ri_data%filter_eps_storage)
2842 pref = -0.5_dp*4.0_dp*hf_fraction*spin_fac
2845 CALL dbt_copy(t_3c_help_1, t_3c_help_2, order=[1, 3, 2])
2848 DO k_mem = 1,
SIZE(t_3c_der_ao_comp, 1)
2850 CALL dbt_clear(t_3c_der_ao(i_xyz))
2851 CALL decompress_tensor(t_3c_der_ao(i_xyz), t_3c_der_ao_ind(k_mem, i_xyz)%ind, &
2852 t_3c_der_ao_comp(k_mem, i_xyz), ri_data%filter_eps_storage)
2855 idx_to_at_ao, pref, deriv_dim=2)
2859 idx_to_at_ao, pref, deriv_dim=2)
2864 IF (use_virial)
THEN
2865 pref = -0.5_dp*2.0_dp*hf_fraction*spin_fac
2866 CALL dbt_copy(t_3c_help_1, t_3c_virial, move_data=.true.)
2867 CALL calc_3c_virial(work_virial, t_3c_virial, pref, qs_env, nl_3c, basis_set_ri, &
2868 basis_set_ao, basis_set_ao, ri_data%ri_metric, &
2869 der_eps=ri_data%eps_schwarz_forces, op_pos=1)
2871 CALL dbt_clear(t_3c_virial)
2874 CALL dbt_clear(t_3c_help_1)
2875 CALL dbt_clear(t_3c_help_2)
2877 CALL timestop(handle)
2879 CALL timeset(routinen//
"_2c", handle)
2882 CALL dbt_contract(1.0_dp, ri_data%t_2c_inv(1, 1), t_r, 0.0_dp, t_2c_ri_tmp, &
2883 contract_1=[2], notcontract_1=[1], &
2884 contract_2=[1], notcontract_2=[2], &
2885 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2886 unit_nr=unit_nr_dbcsr, flop=nflop)
2887 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2889 CALL dbt_contract(1.0_dp, t_2c_ri_tmp, ri_data%t_2c_inv(1, 1), 0.0_dp, t_2c_ri, &
2890 contract_1=[2], notcontract_1=[1], &
2891 contract_2=[1], notcontract_2=[2], &
2892 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2893 unit_nr=unit_nr_dbcsr, flop=nflop)
2894 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2897 pref = 0.5_dp*hf_fraction*spin_fac
2898 IF (.NOT. ri_data%same_op) pref = -pref
2899 CALL get_2c_der_force(force, t_2c_ri, t_2c_der_ri, atom_of_kind, kind_of, idx_to_at_ri, pref)
2902 IF (use_virial_prv)
THEN
2903 CALL dbt_copy(t_2c_ri, t_2c_virial)
2904 CALL dbt_copy_tensor_to_matrix(t_2c_virial, virial_trace)
2905 CALL calc_2c_virial(work_virial, virial_trace, pref, qs_env, nl_2c_pot, &
2906 basis_set_ri, basis_set_ri, ri_data%hfx_pot)
2910 IF (.NOT. ri_data%same_op)
THEN
2911 CALL dbt_contract(1.0_dp, t_2c_ri, ri_data%t_2c_pot(1, 1), 0.0_dp, t_2c_ri_tmp, &
2912 contract_1=[2], notcontract_1=[1], &
2913 contract_2=[1], notcontract_2=[2], &
2914 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2915 unit_nr=unit_nr_dbcsr, flop=nflop)
2916 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2918 CALL dbt_contract(1.0_dp, t_2c_ri_tmp, ri_data%t_2c_inv(1, 1), 0.0_dp, t_2c_ri, &
2919 contract_1=[2], notcontract_1=[1], &
2920 contract_2=[1], notcontract_2=[2], &
2921 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps, &
2922 unit_nr=unit_nr_dbcsr, flop=nflop)
2923 ri_data%dbcsr_nflop = ri_data%dbcsr_nflop + nflop
2925 pref = 0.5_dp*2.0_dp*hf_fraction*spin_fac
2926 CALL get_2c_der_force(force, t_2c_ri, t_2c_der_metric, atom_of_kind, kind_of, idx_to_at_ri, pref)
2928 IF (use_virial_prv)
THEN
2929 CALL dbt_copy(t_2c_ri, t_2c_virial)
2930 CALL dbt_copy_tensor_to_matrix(t_2c_virial, virial_trace)
2931 CALL calc_2c_virial(work_virial, virial_trace, pref, qs_env, nl_2c_met, &
2932 basis_set_ri, basis_set_ri, ri_data%ri_metric)
2935 CALL dbt_clear(t_2c_ri)
2936 CALL dbt_clear(t_2c_ri_tmp)
2938 CALL dbt_clear(t_3c_help_1)
2939 CALL dbt_clear(t_3c_help_2)
2940 CALL timestop(handle)
2942 IF (use_virial_prv)
THEN
2946 virial%pv_fock_4c(i_xyz, j_xyz) = virial%pv_fock_4c(i_xyz, j_xyz) &
2947 + work_virial(i_xyz, k_xyz)*cell%hmat(j_xyz, k_xyz)
2954 CALL dbt_batched_contract_finalize(t_3c_int)
2955 CALL dbt_batched_contract_finalize(t_3c_int_2)
2956 CALL dbt_batched_contract_finalize(t_3c_1)
2957 CALL dbt_batched_contract_finalize(t_3c_2)
2958 CALL dbt_batched_contract_finalize(t_3c_3)
2959 CALL dbt_batched_contract_finalize(t_3c_4)
2960 CALL dbt_batched_contract_finalize(t_3c_5)
2961 CALL dbt_batched_contract_finalize(t_3c_sparse)
2963 CALL para_env%sync()
2966 CALL dbt_copy(t_3c_int, ri_data%t_3c_int_ctr_2(1, 1), move_data=.true.)
2969 CALL dbt_destroy(rho_ao_1)
2970 CALL dbt_destroy(rho_ao_2)
2971 CALL dbt_destroy(t_3c_ao_ri_ao)
2972 CALL dbt_destroy(t_3c_ri_ao_ao)
2973 CALL dbt_destroy(t_3c_int)
2974 CALL dbt_destroy(t_3c_int_2)
2975 CALL dbt_destroy(t_3c_1)
2976 CALL dbt_destroy(t_3c_2)
2977 CALL dbt_destroy(t_3c_3)
2978 CALL dbt_destroy(t_3c_4)
2979 CALL dbt_destroy(t_3c_5)
2980 CALL dbt_destroy(t_3c_help_1)
2981 CALL dbt_destroy(t_3c_help_2)
2982 CALL dbt_destroy(t_3c_sparse)
2983 CALL dbt_destroy(t_svs)
2984 CALL dbt_destroy(t_r)
2985 CALL dbt_destroy(t_2c_ri)
2986 CALL dbt_destroy(t_2c_ri_tmp)
2989 CALL dbt_destroy(t_3c_der_ri(i_xyz))
2990 CALL dbt_destroy(t_3c_der_ao(i_xyz))
2991 CALL dbt_destroy(t_2c_der_ri(i_xyz))
2992 IF (.NOT. ri_data%same_op)
CALL dbt_destroy(t_2c_der_metric(i_xyz))
2996 DO i_mem = 1,
SIZE(t_3c_der_ao_comp, 1)
2997 CALL dealloc_containers(t_3c_der_ao_comp(i_mem, i_xyz), dummy_int)
2998 CALL dealloc_containers(t_3c_der_ri_comp(i_mem, i_xyz), dummy_int)
3001 DEALLOCATE (t_3c_der_ao_ind, t_3c_der_ri_ind)
3003 DO ibasis = 1,
SIZE(basis_set_ao)
3004 orb_basis => basis_set_ao(ibasis)%gto_basis_set
3005 ri_basis => basis_set_ri(ibasis)%gto_basis_set
3006 CALL init_interaction_radii_orb_basis(orb_basis, dft_control%qs_control%eps_pgf_orb)
3007 CALL init_interaction_radii_orb_basis(ri_basis, dft_control%qs_control%eps_pgf_orb)
3010 IF (use_virial)
THEN
3011 CALL release_neighbor_list_sets(nl_2c_met)
3012 CALL release_neighbor_list_sets(nl_2c_pot)
3013 CALL neighbor_list_3c_destroy(nl_3c)
3014 CALL dbcsr_release(virial_trace)
3015 CALL dbt_destroy(t_2c_virial)
3016 CALL dbt_destroy(t_3c_virial)
3019 END SUBROUTINE hfx_ri_forces_pmat
3035 mos, use_virial, resp_only, rescale_factor)
3037 TYPE(qs_environment_type),
POINTER :: qs_env
3038 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
3039 INTEGER,
INTENT(IN) :: nspins
3040 REAL(kind=dp),
INTENT(IN) :: hf_fraction
3041 TYPE(dbcsr_p_type),
DIMENSION(:, :),
OPTIONAL :: rho_ao
3042 TYPE(dbcsr_p_type),
DIMENSION(:),
OPTIONAL :: rho_ao_resp
3043 TYPE(mo_set_type),
DIMENSION(:),
INTENT(IN), &
3045 LOGICAL,
INTENT(IN),
OPTIONAL :: use_virial, resp_only
3046 REAL(dp),
INTENT(IN),
OPTIONAL :: rescale_factor
3048 CHARACTER(LEN=*),
PARAMETER :: routinen =
'hfx_ri_update_forces'
3050 INTEGER :: handle, ispin
3051 INTEGER,
DIMENSION(2) :: homo
3052 REAL(kind=dp),
DIMENSION(:),
POINTER :: mo_eigenvalues
3053 TYPE(cp_fm_type),
POINTER :: mo_coeff
3054 TYPE(dbcsr_type),
DIMENSION(2) :: mo_coeff_b
3055 TYPE(dbcsr_type),
POINTER :: mo_coeff_b_tmp
3057 CALL timeset(routinen, handle)
3059 SELECT CASE (ri_data%flavor)
3062 DO ispin = 1, nspins
3063 NULLIFY (mo_coeff_b_tmp)
3064 cpassert(mos(ispin)%uniform_occupation)
3065 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, eigenvalues=mo_eigenvalues, mo_coeff_b=mo_coeff_b_tmp)
3067 IF (.NOT. mos(ispin)%use_mo_coeff_b)
CALL copy_fm_to_dbcsr(mo_coeff, mo_coeff_b_tmp)
3068 CALL dbcsr_copy(mo_coeff_b(ispin), mo_coeff_b_tmp)
3071 DO ispin = 1, nspins
3072 CALL dbcsr_scale(mo_coeff_b(ispin), sqrt(mos(ispin)%maxocc))
3073 homo(ispin) = mos(ispin)%homo
3076 CALL hfx_ri_forces_mo(qs_env, ri_data, nspins, hf_fraction, mo_coeff_b, use_virial)
3080 CALL hfx_ri_forces_pmat(qs_env, ri_data, nspins, hf_fraction, rho_ao, rho_ao_resp, use_virial, &
3081 resp_only, rescale_factor)
3084 DO ispin = 1, nspins
3085 CALL dbcsr_release(mo_coeff_b(ispin))
3088 CALL timestop(handle)
3110 SUBROUTINE precalc_derivatives(t_3c_der_RI_comp, t_3c_der_AO_comp, t_3c_der_RI_ind, t_3c_der_AO_ind, &
3111 t_2c_der_RI, t_2c_der_metric, ri_ao_ao_template, &
3112 basis_set_AO, basis_set_RI, ri_data, qs_env, &
3113 nl_2c_pot, nl_2c_met, nl_3c_out, t_3c_virial)
3115 TYPE(hfx_compression_type),
ALLOCATABLE, &
3116 DIMENSION(:, :),
INTENT(INOUT) :: t_3c_der_ri_comp, t_3c_der_ao_comp
3117 TYPE(block_ind_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_der_ri_ind, t_3c_der_ao_ind
3118 TYPE(dbt_type),
DIMENSION(3),
INTENT(OUT) :: t_2c_der_ri, t_2c_der_metric
3119 TYPE(dbt_type),
INTENT(INOUT) :: ri_ao_ao_template
3120 TYPE(gto_basis_set_p_type),
ALLOCATABLE, &
3121 DIMENSION(:),
TARGET :: basis_set_ao, basis_set_ri
3122 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
3123 TYPE(qs_environment_type),
POINTER :: qs_env
3124 TYPE(neighbor_list_set_p_type),
DIMENSION(:), &
3125 OPTIONAL,
POINTER :: nl_2c_pot, nl_2c_met
3126 TYPE(neighbor_list_3c_type),
OPTIONAL :: nl_3c_out
3127 TYPE(dbt_type),
INTENT(INOUT),
OPTIONAL :: t_3c_virial
3129 CHARACTER(LEN=*),
PARAMETER :: routinen =
'precalc_derivatives'
3131 INTEGER :: handle, i_mem, i_xyz, n_mem, natom, &
3133 INTEGER(int_8) :: nze, nze_tot
3134 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: dist1, dist2, dist_ao_1, dist_ao_2, &
3135 dist_ri, dummy_end, dummy_start, &
3136 end_blocks, start_blocks
3137 INTEGER,
DIMENSION(3) :: pcoord, pdims
3138 INTEGER,
DIMENSION(:),
POINTER :: col_bsize, row_bsize
3139 REAL(dp) :: compression_factor, memory, occ
3140 TYPE(dbcsr_distribution_type) :: dbcsr_dist
3141 TYPE(dbcsr_type),
DIMENSION(1, 3) :: t_2c_der_metric_prv, t_2c_der_ri_prv
3142 TYPE(dbt_pgrid_type) :: pgrid
3143 TYPE(dbt_type) :: t_2c_template, t_2c_tmp, t_3c_template
3144 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:, :, :) :: t_3c_der_ao_prv, t_3c_der_ri_prv
3145 TYPE(dft_control_type),
POINTER :: dft_control
3146 TYPE(distribution_2d_type),
POINTER :: dist_2d
3147 TYPE(distribution_3d_type) :: dist_3d, dist_3d_out
3148 TYPE(mp_cart_type) :: mp_comm_t3c, mp_comm_t3c_out
3149 TYPE(mp_para_env_type),
POINTER :: para_env
3150 TYPE(neighbor_list_3c_type) :: nl_3c
3151 TYPE(neighbor_list_set_p_type),
DIMENSION(:), &
3153 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
3154 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
3156 NULLIFY (qs_kind_set, dist_2d, nl_2c, particle_set, dft_control, para_env)
3158 CALL timeset(routinen, handle)
3160 CALL get_qs_env(qs_env, nkind=nkind, qs_kind_set=qs_kind_set, distribution_2d=dist_2d, natom=natom, &
3161 particle_set=particle_set, dft_control=dft_control, para_env=para_env)
3168 CALL dbt_pgrid_create(para_env, pdims, pgrid, tensor_dims=[max(1, natom/(ri_data%n_mem*nthreads)), natom, natom])
3170 CALL create_3c_tensor(t_3c_template, dist_ri, dist_ao_1, dist_ao_2, pgrid, &
3171 ri_data%bsizes_RI, ri_data%bsizes_AO, ri_data%bsizes_AO, &
3172 map1=[1], map2=[2, 3], &
3173 name=
"der (RI AO | AO)")
3175 ALLOCATE (t_3c_der_ao_prv(1, 1, 3), t_3c_der_ri_prv(1, 1, 3))
3177 CALL dbt_create(t_3c_template, t_3c_der_ri_prv(1, 1, i_xyz))
3178 CALL dbt_create(t_3c_template, t_3c_der_ao_prv(1, 1, i_xyz))
3180 IF (
PRESENT(t_3c_virial))
THEN
3181 CALL dbt_create(t_3c_template, t_3c_virial)
3183 CALL dbt_destroy(t_3c_template)
3185 CALL dbt_mp_environ_pgrid(pgrid, pdims, pcoord)
3186 CALL mp_comm_t3c%create(pgrid%mp_comm_2d, 3, pdims)
3187 CALL distribution_3d_create(dist_3d, dist_ri, dist_ao_1, dist_ao_2, &
3188 nkind, particle_set, mp_comm_t3c, own_comm=.true.)
3190 CALL build_3c_neighbor_lists(nl_3c, basis_set_ri, basis_set_ao, basis_set_ao, dist_3d, ri_data%ri_metric, &
3191 "HFX_3c_nl", qs_env, op_pos=1, sym_jk=.true., own_dist=.true.)
3193 IF (
PRESENT(nl_3c_out))
THEN
3194 CALL dbt_mp_environ_pgrid(pgrid, pdims, pcoord)
3195 CALL mp_comm_t3c_out%create(pgrid%mp_comm_2d, 3, pdims)
3196 CALL distribution_3d_create(dist_3d_out, dist_ri, dist_ao_1, dist_ao_2, &
3197 nkind, particle_set, mp_comm_t3c_out, own_comm=.true.)
3198 CALL build_3c_neighbor_lists(nl_3c_out, basis_set_ri, basis_set_ao, basis_set_ao, dist_3d_out, &
3199 ri_data%ri_metric,
"HFX_3c_nl", qs_env, op_pos=1, sym_jk=.false., &
3202 DEALLOCATE (dist_ri, dist_ao_1, dist_ao_2)
3203 CALL dbt_pgrid_destroy(pgrid)
3205 n_mem = ri_data%n_mem
3206 CALL create_tensor_batches(ri_data%bsizes_RI, n_mem, dummy_start, dummy_end, &
3207 start_blocks, end_blocks)
3208 DEALLOCATE (dummy_start, dummy_end)
3210 ALLOCATE (t_3c_der_ao_comp(n_mem, 3), t_3c_der_ri_comp(n_mem, 3))
3211 ALLOCATE (t_3c_der_ao_ind(n_mem, 3), t_3c_der_ri_ind(n_mem, 3))
3216 CALL build_3c_derivatives(t_3c_der_ri_prv, t_3c_der_ao_prv, ri_data%filter_eps, qs_env, &
3217 nl_3c, basis_set_ri, basis_set_ao, basis_set_ao, &
3218 ri_data%ri_metric, der_eps=ri_data%eps_schwarz_forces, op_pos=1, &
3219 bounds_i=[start_blocks(i_mem), end_blocks(i_mem)])
3222 CALL dbt_copy(t_3c_der_ri_prv(1, 1, i_xyz), ri_ao_ao_template, move_data=.true.)
3223 CALL dbt_filter(ri_ao_ao_template, ri_data%filter_eps)
3224 CALL get_tensor_occupancy(ri_ao_ao_template, nze, occ)
3225 nze_tot = nze_tot + nze
3227 CALL alloc_containers(t_3c_der_ri_comp(i_mem, i_xyz), 1)
3228 CALL compress_tensor(ri_ao_ao_template, t_3c_der_ri_ind(i_mem, i_xyz)%ind, &
3229 t_3c_der_ri_comp(i_mem, i_xyz), ri_data%filter_eps_storage, memory)
3230 CALL dbt_clear(ri_ao_ao_template)
3233 CALL dbt_copy(t_3c_der_ao_prv(1, 1, i_xyz), ri_ao_ao_template, order=[1, 3, 2], move_data=.true.)
3234 CALL dbt_filter(ri_ao_ao_template, ri_data%filter_eps)
3235 CALL get_tensor_occupancy(ri_ao_ao_template, nze, occ)
3236 nze_tot = nze_tot + nze
3238 CALL alloc_containers(t_3c_der_ao_comp(i_mem, i_xyz), 1)
3239 CALL compress_tensor(ri_ao_ao_template, t_3c_der_ao_ind(i_mem, i_xyz)%ind, &
3240 t_3c_der_ao_comp(i_mem, i_xyz), ri_data%filter_eps_storage, memory)
3241 CALL dbt_clear(ri_ao_ao_template)
3245 CALL neighbor_list_3c_destroy(nl_3c)
3247 CALL dbt_destroy(t_3c_der_ri_prv(1, 1, i_xyz))
3248 CALL dbt_destroy(t_3c_der_ao_prv(1, 1, i_xyz))
3251 CALL para_env%sum(memory)
3252 compression_factor = real(nze_tot, dp)*1.0e-06*8.0_dp/memory
3253 IF (ri_data%unit_nr > 0)
THEN
3254 WRITE (unit=ri_data%unit_nr, fmt=
"((T3,A,T66,F11.2,A4))") &
3255 "MEMORY_INFO| Memory for 3-center HFX derivatives (compressed):", memory,
' MiB'
3257 WRITE (unit=ri_data%unit_nr, fmt=
"((T3,A,T60,F21.2))") &
3258 "MEMORY_INFO| Compression factor: ", compression_factor
3262 CALL cp_dbcsr_dist2d_to_dist(dist_2d, dbcsr_dist)
3263 ALLOCATE (row_bsize(
SIZE(ri_data%bsizes_RI)))
3264 ALLOCATE (col_bsize(
SIZE(ri_data%bsizes_RI)))
3265 row_bsize(:) = ri_data%bsizes_RI
3266 col_bsize(:) = ri_data%bsizes_RI
3268 CALL build_2c_neighbor_lists(nl_2c, basis_set_ri, basis_set_ri, ri_data%hfx_pot, &
3269 "HFX_2c_nl_pot", qs_env, sym_ij=.true., dist_2d=dist_2d)
3272 CALL dbcsr_create(t_2c_der_ri_prv(1, i_xyz),
"(R|P) HFX der", dbcsr_dist, &
3273 dbcsr_type_antisymmetric, row_bsize, col_bsize)
3276 CALL build_2c_derivatives(t_2c_der_ri_prv, ri_data%filter_eps_2c, qs_env, nl_2c, basis_set_ri, &
3277 basis_set_ri, ri_data%hfx_pot)
3278 CALL release_neighbor_list_sets(nl_2c)
3280 IF (
PRESENT(nl_2c_pot))
THEN
3282 CALL build_2c_neighbor_lists(nl_2c_pot, basis_set_ri, basis_set_ri, ri_data%hfx_pot, &
3283 "HFX_2c_nl_pot", qs_env, sym_ij=.false., dist_2d=dist_2d)
3287 CALL create_2c_tensor(t_2c_template, dist1, dist2, ri_data%pgrid_2d, ri_data%bsizes_RI_split, &
3288 ri_data%bsizes_RI_split, name=
'(RI| RI)')
3289 DEALLOCATE (dist1, dist2)
3292 CALL dbt_create(t_2c_der_ri_prv(1, i_xyz), t_2c_tmp)
3293 CALL dbt_copy_matrix_to_tensor(t_2c_der_ri_prv(1, i_xyz), t_2c_tmp)
3295 CALL dbt_create(t_2c_template, t_2c_der_ri(i_xyz))
3296 CALL dbt_copy(t_2c_tmp, t_2c_der_ri(i_xyz), move_data=.true.)
3298 CALL dbt_destroy(t_2c_tmp)
3299 CALL dbcsr_release(t_2c_der_ri_prv(1, i_xyz))
3303 IF (.NOT. ri_data%same_op)
THEN
3305 CALL build_2c_neighbor_lists(nl_2c, basis_set_ri, basis_set_ri, ri_data%ri_metric, &
3306 "HFX_2c_nl_RI", qs_env, sym_ij=.true., dist_2d=dist_2d)
3309 CALL dbcsr_create(t_2c_der_metric_prv(1, i_xyz),
"(R|P) HFX der", dbcsr_dist, &
3310 dbcsr_type_antisymmetric, row_bsize, col_bsize)
3313 CALL build_2c_derivatives(t_2c_der_metric_prv, ri_data%filter_eps_2c, qs_env, nl_2c, &
3314 basis_set_ri, basis_set_ri, ri_data%ri_metric)
3315 CALL release_neighbor_list_sets(nl_2c)
3317 IF (
PRESENT(nl_2c_met))
THEN
3319 CALL build_2c_neighbor_lists(nl_2c_met, basis_set_ri, basis_set_ri, ri_data%ri_metric, &
3320 "HFX_2c_nl_RI", qs_env, sym_ij=.false., dist_2d=dist_2d)
3324 CALL dbt_create(t_2c_der_metric_prv(1, i_xyz), t_2c_tmp)
3325 CALL dbt_copy_matrix_to_tensor(t_2c_der_metric_prv(1, i_xyz), t_2c_tmp)
3327 CALL dbt_create(t_2c_template, t_2c_der_metric(i_xyz))
3328 CALL dbt_copy(t_2c_tmp, t_2c_der_metric(i_xyz), move_data=.true.)
3330 CALL dbt_destroy(t_2c_tmp)
3331 CALL dbcsr_release(t_2c_der_metric_prv(1, i_xyz))
3336 CALL dbt_destroy(t_2c_template)
3337 CALL dbcsr_distribution_release(dbcsr_dist)
3338 DEALLOCATE (row_bsize, col_bsize)
3340 CALL timestop(handle)
3342 END SUBROUTINE precalc_derivatives
3359 pref, do_mp2, deriv_dim)
3361 TYPE(qs_force_type),
DIMENSION(:),
POINTER :: force
3362 TYPE(dbt_type),
INTENT(INOUT) :: t_3c_contr
3363 TYPE(dbt_type),
DIMENSION(3),
INTENT(INOUT) :: t_3c_der
3364 INTEGER,
DIMENSION(:),
INTENT(IN) :: atom_of_kind, kind_of, idx_to_at
3365 REAL(dp),
INTENT(IN) :: pref
3366 LOGICAL,
INTENT(IN),
OPTIONAL :: do_mp2
3367 INTEGER,
INTENT(IN),
OPTIONAL :: deriv_dim
3369 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_force_from_3c_trace'
3371 INTEGER :: deriv_dim_prv, handle, i_xyz, iat, &
3372 iat_of_kind, ikind, j_xyz
3373 INTEGER,
DIMENSION(3) :: ind
3374 LOGICAL :: do_mp2_prv, found
3375 REAL(dp) :: new_force
3376 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :, :),
TARGET :: contr_blk, der_blk
3377 REAL(dp),
DIMENSION(3) :: scoord
3378 TYPE(dbt_iterator_type) :: iter
3380 CALL timeset(routinen, handle)
3382 do_mp2_prv = .false.
3383 IF (
PRESENT(do_mp2)) do_mp2_prv = do_mp2
3386 IF (
PRESENT(deriv_dim)) deriv_dim_prv = deriv_dim
3392 CALL dbt_iterator_start(iter, t_3c_der(i_xyz))
3393 DO WHILE (dbt_iterator_blocks_left(iter))
3394 CALL dbt_iterator_next_block(iter, ind)
3396 CALL dbt_get_block(t_3c_der(i_xyz), ind, der_blk, found)
3398 CALL dbt_get_block(t_3c_contr, ind, contr_blk, found)
3403 new_force = pref*sum(der_blk(:, :, :)*contr_blk(:, :, :))
3406 iat = idx_to_at(ind(deriv_dim_prv))
3407 iat_of_kind = atom_of_kind(iat)
3408 ikind = kind_of(iat)
3410 IF (.NOT. do_mp2_prv)
THEN
3412 force(ikind)%fock_4c(i_xyz, iat_of_kind) = force(ikind)%fock_4c(i_xyz, iat_of_kind) &
3416 force(ikind)%mp2_non_sep(i_xyz, iat_of_kind) = force(ikind)%mp2_non_sep(i_xyz, iat_of_kind) &
3420 DEALLOCATE (contr_blk)
3422 DEALLOCATE (der_blk)
3424 CALL dbt_iterator_stop(iter)
3427 CALL timestop(handle)
3445 pref, do_mp2, do_ovlp)
3447 TYPE(qs_force_type),
DIMENSION(:),
POINTER :: force
3448 TYPE(dbt_type),
INTENT(INOUT) :: t_2c_contr
3449 TYPE(dbt_type),
DIMENSION(3),
INTENT(INOUT) :: t_2c_der
3450 INTEGER,
DIMENSION(:),
INTENT(IN) :: atom_of_kind, kind_of, idx_to_at
3451 REAL(dp),
INTENT(IN) :: pref
3452 LOGICAL,
INTENT(IN),
OPTIONAL :: do_mp2, do_ovlp
3454 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_2c_der_force'
3456 INTEGER :: handle, i_xyz, iat, iat_of_kind, ikind, &
3457 j_xyz, jat, jat_of_kind, jkind
3458 INTEGER,
DIMENSION(2) :: ind
3459 LOGICAL :: do_mp2_prv, do_ovlp_prv, found
3460 REAL(dp) :: new_force
3461 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :),
TARGET :: contr_blk, der_blk
3462 REAL(dp),
DIMENSION(3) :: scoord
3463 TYPE(dbt_iterator_type) :: iter
3468 CALL timeset(routinen, handle)
3470 do_mp2_prv = .false.
3471 IF (
PRESENT(do_mp2)) do_mp2_prv = do_mp2
3473 do_ovlp_prv = .false.
3474 IF (
PRESENT(do_ovlp)) do_ovlp_prv = do_ovlp
3481 CALL dbt_iterator_start(iter, t_2c_der(i_xyz))
3482 DO WHILE (dbt_iterator_blocks_left(iter))
3483 CALL dbt_iterator_next_block(iter, ind)
3485 IF (ind(1) == ind(2)) cycle
3487 CALL dbt_get_block(t_2c_der(i_xyz), ind, der_blk, found)
3489 CALL dbt_get_block(t_2c_contr, ind, contr_blk, found)
3495 new_force = pref*sum(der_blk(:, :)*contr_blk(:, :))
3497 iat = idx_to_at(ind(1))
3498 iat_of_kind = atom_of_kind(iat)
3499 ikind = kind_of(iat)
3501 IF (do_mp2_prv)
THEN
3503 force(ikind)%mp2_non_sep(i_xyz, iat_of_kind) = force(ikind)%mp2_non_sep(i_xyz, iat_of_kind) &
3505 ELSE IF (do_ovlp_prv)
THEN
3507 force(ikind)%overlap(i_xyz, iat_of_kind) = force(ikind)%overlap(i_xyz, iat_of_kind) &
3511 force(ikind)%fock_4c(i_xyz, iat_of_kind) = force(ikind)%fock_4c(i_xyz, iat_of_kind) &
3515 jat = idx_to_at(ind(2))
3516 jat_of_kind = atom_of_kind(jat)
3517 jkind = kind_of(jat)
3519 IF (do_mp2_prv)
THEN
3521 force(jkind)%mp2_non_sep(i_xyz, jat_of_kind) = force(jkind)%mp2_non_sep(i_xyz, jat_of_kind) &
3523 ELSE IF (do_ovlp_prv)
THEN
3525 force(jkind)%overlap(i_xyz, jat_of_kind) = force(jkind)%overlap(i_xyz, jat_of_kind) &
3529 force(jkind)%fock_4c(i_xyz, jat_of_kind) = force(jkind)%fock_4c(i_xyz, jat_of_kind) &
3533 DEALLOCATE (contr_blk)
3536 DEALLOCATE (der_blk)
3538 CALL dbt_iterator_stop(iter)
3542 CALL timestop(handle)
3558 SUBROUTINE get_mo_ao_force(force, t_mo_coeff, t_2c_MO_AO, atom_of_kind, kind_of, idx_to_at, pref, i_xyz)
3560 TYPE(qs_force_type),
DIMENSION(:),
POINTER :: force
3561 TYPE(dbt_type),
INTENT(INOUT) :: t_mo_coeff, t_2c_mo_ao
3562 INTEGER,
DIMENSION(:),
INTENT(IN) :: atom_of_kind, kind_of, idx_to_at
3563 REAL(dp),
INTENT(IN) :: pref
3564 INTEGER,
INTENT(IN) :: i_xyz
3566 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_MO_AO_force'
3568 INTEGER :: handle, iat, iat_of_kind, ikind, j_xyz
3569 INTEGER,
DIMENSION(2) :: ind
3571 REAL(dp) :: new_force
3572 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :),
TARGET :: mo_ao_blk, mo_coeff_blk
3573 REAL(dp),
DIMENSION(3) :: scoord
3574 TYPE(dbt_iterator_type) :: iter
3576 CALL timeset(routinen, handle)
3581 CALL dbt_iterator_start(iter, t_2c_mo_ao)
3582 DO WHILE (dbt_iterator_blocks_left(iter))
3583 CALL dbt_iterator_next_block(iter, ind)
3585 CALL dbt_get_block(t_2c_mo_ao, ind, mo_ao_blk, found)
3587 CALL dbt_get_block(t_mo_coeff, ind, mo_coeff_blk, found)
3591 new_force = pref*sum(mo_ao_blk(:, :)*mo_coeff_blk(:, :))
3593 iat = idx_to_at(ind(2))
3594 iat_of_kind = atom_of_kind(iat)
3595 ikind = kind_of(iat)
3598 force(ikind)%fock_4c(i_xyz, iat_of_kind) = force(ikind)%fock_4c(i_xyz, iat_of_kind) &
3601 DEALLOCATE (mo_coeff_blk)
3604 DEALLOCATE (mo_ao_blk)
3606 CALL dbt_iterator_stop(iter)
3609 CALL timestop(handle)
3611 END SUBROUTINE get_mo_ao_force
3620 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
3621 TYPE(qs_environment_type),
POINTER :: qs_env
3623 INTEGER :: i_ri, ibasis, nkind, nspins, unit_nr
3624 INTEGER,
DIMENSION(:),
POINTER :: col_bsize, row_bsize
3625 LOGICAL :: mult_by_s, print_density, print_ri_metric
3626 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: density_coeffs, density_coeffs_2
3627 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
3628 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
3629 TYPE(cp_fm_type) :: matrix_s_fm
3630 TYPE(cp_logger_type),
POINTER :: logger
3631 TYPE(dbcsr_distribution_type) :: dbcsr_dist
3632 TYPE(dbcsr_p_type),
DIMENSION(:, :),
POINTER :: rho_ao
3633 TYPE(dbcsr_type),
DIMENSION(1) :: matrix_s
3634 TYPE(dft_control_type),
POINTER :: dft_control
3635 TYPE(distribution_2d_type),
POINTER :: dist_2d
3636 TYPE(gto_basis_set_p_type),
ALLOCATABLE, &
3637 DIMENSION(:),
TARGET :: basis_set_ao, basis_set_ri
3638 TYPE(gto_basis_set_type),
POINTER :: orb_basis, ri_basis
3639 TYPE(mp_para_env_type),
POINTER :: para_env
3640 TYPE(neighbor_list_set_p_type),
DIMENSION(:), &
3642 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
3643 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
3644 TYPE(qs_rho_type),
POINTER :: rho
3645 TYPE(section_vals_type),
POINTER :: input, print_section
3647 NULLIFY (rho_ao, input, print_section, logger, rho, particle_set, qs_kind_set, ri_basis, nl_2c, &
3648 dist_2d, col_bsize, row_bsize, para_env, blacs_env, fm_struct, orb_basis, dft_control)
3650 CALL get_qs_env(qs_env, input=input, dft_control=dft_control)
3651 logger => cp_get_default_logger()
3652 print_density = .false.
3653 print_ri_metric = .false.
3656 print_section => section_vals_get_subs_vals(input,
"DFT%XC%HF%RI%PRINT")
3657 IF (btest(cp_print_key_should_output(logger%iter_info, print_section,
"RI_DENSITY_COEFFS"), &
3658 cp_p_file)) print_density = .true.
3659 IF (btest(cp_print_key_should_output(logger%iter_info, print_section,
"RI_METRIC_2C_INTS"), &
3660 cp_p_file)) print_ri_metric = .true.
3663 IF (print_density .OR. print_ri_metric)
THEN
3667 CALL get_qs_env(qs_env, nkind=nkind, qs_kind_set=qs_kind_set, particle_set=particle_set, &
3668 distribution_2d=dist_2d, para_env=para_env, blacs_env=blacs_env)
3669 ALLOCATE (basis_set_ri(nkind), basis_set_ao(nkind))
3670 CALL basis_set_list_setup(basis_set_ri, ri_data%ri_basis_type, qs_kind_set)
3671 CALL get_particle_set(particle_set, qs_kind_set, basis=basis_set_ri)
3672 CALL basis_set_list_setup(basis_set_ao, ri_data%orb_basis_type, qs_kind_set)
3673 CALL get_particle_set(particle_set, qs_kind_set, basis=basis_set_ao)
3675 DO ibasis = 1, nkind
3676 ri_basis => basis_set_ri(ibasis)%gto_basis_set
3677 CALL init_interaction_radii_orb_basis(ri_basis, ri_data%eps_pgf_orb)
3678 orb_basis => basis_set_ao(ibasis)%gto_basis_set
3679 CALL init_interaction_radii_orb_basis(orb_basis, ri_data%eps_pgf_orb)
3682 CALL cp_dbcsr_dist2d_to_dist(dist_2d, dbcsr_dist)
3683 ALLOCATE (row_bsize(
SIZE(ri_data%bsizes_RI)))
3684 ALLOCATE (col_bsize(
SIZE(ri_data%bsizes_RI)))
3685 row_bsize(:) = ri_data%bsizes_RI
3686 col_bsize(:) = ri_data%bsizes_RI
3688 CALL dbcsr_create(matrix_s(1),
"RI metric", dbcsr_dist, dbcsr_type_symmetric, row_bsize, col_bsize)
3690 CALL build_2c_neighbor_lists(nl_2c, basis_set_ri, basis_set_ri, ri_data%ri_metric, &
3691 "HFX_2c_nl_pot", qs_env, sym_ij=.true., dist_2d=dist_2d)
3692 CALL build_2c_integrals(matrix_s, ri_data%filter_eps_2c, qs_env, nl_2c, basis_set_ri, &
3693 basis_set_ri, ri_data%ri_metric)
3695 CALL release_neighbor_list_sets(nl_2c)
3696 CALL dbcsr_distribution_release(dbcsr_dist)
3699 IF (print_density)
THEN
3700 CALL get_qs_env(qs_env, rho=rho)
3701 CALL qs_rho_get(rho, rho_ao_kp=rho_ao)
3702 nspins =
SIZE(rho_ao, 1)
3704 CALL section_vals_val_get(print_section,
"RI_DENSITY_COEFFS%MULTIPLY_BY_RI_2C_INTEGRALS", l_val=mult_by_s)
3706 CALL get_ri_density_coeffs(density_coeffs, matrix_s(1), rho_ao, 1, basis_set_ao, basis_set_ri, &
3707 mult_by_s, ri_data, qs_env)
3709 CALL get_ri_density_coeffs(density_coeffs_2, matrix_s(1), rho_ao, 2, basis_set_ao, &
3710 basis_set_ri, mult_by_s, ri_data, qs_env)
3712 unit_nr = cp_print_key_unit_nr(logger, input,
"DFT%XC%HF%RI%PRINT%RI_DENSITY_COEFFS", &
3713 extension=
".dat", file_status=
"REPLACE", &
3714 file_action=
"WRITE", file_form=
"FORMATTED")
3716 IF (unit_nr > 0)
THEN
3717 IF (nspins == 1)
THEN
3718 WRITE (unit_nr, fmt=
"(A,A,A)") &
3719 "# Coefficients of the electronic density projected on the RI_HFX basis for ", &
3720 trim(logger%iter_info%project_name),
" project"
3721 DO i_ri = 1,
SIZE(density_coeffs)
3722 WRITE (unit_nr, fmt=
"(F20.12)") density_coeffs(i_ri)
3725 WRITE (unit_nr, fmt=
"(A,A,A)") &
3726 "# Coefficients of the electronic density projected on the RI_HFX basis for ", &
3727 trim(logger%iter_info%project_name),
" project. Spin up, spin down"
3728 DO i_ri = 1,
SIZE(density_coeffs)
3729 WRITE (unit_nr, fmt=
"(F20.12,F20.12)") density_coeffs(i_ri), density_coeffs_2(i_ri)
3734 CALL cp_print_key_finished_output(unit_nr, logger, input,
"DFT%XC%HF%RI%PRINT%RI_DENSITY_COEFFS")
3737 IF (print_ri_metric)
THEN
3740 CALL cp_fm_struct_create(fm_struct, context=blacs_env, para_env=para_env, &
3741 nrow_global=sum(row_bsize), ncol_global=sum(col_bsize))
3742 CALL cp_fm_create(matrix_s_fm, fm_struct)
3744 CALL copy_dbcsr_to_fm(matrix_s(1), matrix_s_fm)
3746 unit_nr = cp_print_key_unit_nr(logger, input,
"DFT%XC%HF%RI%PRINT%RI_METRIC_2C_INTS", &
3747 extension=
".fm", file_status=
"REPLACE", &
3748 file_action=
"WRITE", file_form=
"UNFORMATTED")
3749 CALL cp_fm_write_unformatted(matrix_s_fm, unit_nr)
3751 CALL cp_print_key_finished_output(unit_nr, logger, input,
"DFT%XC%HF%RI%PRINT%RI_METRIC_2C_INTS")
3753 CALL cp_fm_struct_release(fm_struct)
3754 CALL cp_fm_release(matrix_s_fm)
3758 IF (print_density .OR. print_ri_metric)
THEN
3759 DO ibasis = 1, nkind
3760 ri_basis => basis_set_ri(ibasis)%gto_basis_set
3761 CALL init_interaction_radii_orb_basis(ri_basis, dft_control%qs_control%eps_pgf_orb)
3762 orb_basis => basis_set_ao(ibasis)%gto_basis_set
3763 CALL init_interaction_radii_orb_basis(orb_basis, dft_control%qs_control%eps_pgf_orb)
3766 CALL dbcsr_release(matrix_s(1))
3767 DEALLOCATE (row_bsize, col_bsize)
3784 SUBROUTINE get_ri_density_coeffs(density_coeffs, ri_2c_ints, rho_ao, ispin, basis_set_AO, &
3785 basis_set_RI, multiply_by_S, ri_data, qs_env)
3787 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: density_coeffs
3788 TYPE(dbcsr_type),
INTENT(INOUT) :: ri_2c_ints
3789 TYPE(dbcsr_p_type),
DIMENSION(:, :) :: rho_ao
3790 INTEGER,
INTENT(IN) :: ispin
3791 TYPE(gto_basis_set_p_type),
DIMENSION(:) :: basis_set_ao, basis_set_ri
3792 LOGICAL,
INTENT(IN) :: multiply_by_s
3793 TYPE(hfx_ri_type),
INTENT(INOUT) :: ri_data
3794 TYPE(qs_environment_type),
POINTER :: qs_env
3796 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_RI_density_coeffs'
3798 INTEGER :: a, b, handle, i_mem,
idx, n_dependent, &
3799 n_mem, n_mem_ri, natom, &
3800 nblk_per_thread, nblks, nkind
3801 INTEGER(int_8) :: nze
3802 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: batch_block_end, batch_block_start, &
3803 dist1, dist2, dist3, dummy1, dummy2, &
3805 INTEGER,
DIMENSION(2) :: ind, pdims_2d
3806 INTEGER,
DIMENSION(2, 3) :: bounds_cpy
3807 INTEGER,
DIMENSION(3) :: dims_3c, pcoord_3d, pdims_3d
3808 LOGICAL :: calc_ints, found
3809 REAL(dp) :: occ, threshold
3810 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :) :: blk
3811 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: blk_3d
3812 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
3813 TYPE(dbcsr_type) :: ri_2c_inv
3814 TYPE(dbt_distribution_type) :: dist_2d, dist_3d
3815 TYPE(dbt_iterator_type) :: iter
3816 TYPE(dbt_pgrid_type) :: pgrid_2d, pgrid_3d
3817 TYPE(dbt_type) :: density_coeffs_t, density_tmp, rho_ao_t, &
3818 rho_ao_t_3d, rho_ao_tmp, t2c_ri_ints, &
3819 t2c_ri_inv, t2c_ri_tmp
3820 TYPE(dbt_type),
ALLOCATABLE,
DIMENSION(:, :) :: t_3c_int_batched
3821 TYPE(dft_control_type),
POINTER :: dft_control
3822 TYPE(distribution_3d_type) :: dist_nl3c
3823 TYPE(mp_cart_type) :: mp_comm_t3c
3824 TYPE(mp_para_env_type),
POINTER :: para_env
3825 TYPE(neighbor_list_3c_type) :: nl_3c
3826 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
3827 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
3829 NULLIFY (dft_control, para_env, blacs_env, particle_set, qs_kind_set)
3831 CALL timeset(routinen, handle)
3837 IF (.NOT. ri_data%flavor == ri_pmat)
THEN
3838 cpabort(
"Can only calculate and print the RI density coefficients within the RHO flavor of RI-HFX")
3841 CALL get_qs_env(qs_env, dft_control=dft_control, para_env=para_env, blacs_env=blacs_env, nkind=nkind, &
3842 particle_set=particle_set, qs_kind_set=qs_kind_set, natom=natom)
3843 n_mem = ri_data%n_mem
3844 n_mem_ri = ri_data%n_mem_RI
3847 CALL dbcsr_create(ri_2c_inv, template=ri_2c_ints, matrix_type=dbcsr_type_no_symmetry)
3849 SELECT CASE (ri_data%t2c_method)
3850 CASE (hfx_ri_do_2c_iter)
3851 threshold = max(ri_data%filter_eps, 1.0e-12_dp)
3852 CALL invert_hotelling(ri_2c_inv, ri_2c_ints, threshold=threshold, silent=.false.)
3853 CASE (hfx_ri_do_2c_cholesky)
3854 CALL dbcsr_copy(ri_2c_inv, ri_2c_ints)
3855 CALL cp_dbcsr_cholesky_decompose(ri_2c_inv, para_env=para_env, blacs_env=blacs_env)
3856 CALL cp_dbcsr_cholesky_invert(ri_2c_inv, para_env=para_env, blacs_env=blacs_env, upper_to_full=.true.)
3857 CASE (hfx_ri_do_2c_diag)
3858 CALL dbcsr_copy(ri_2c_inv, ri_2c_ints)
3859 CALL cp_dbcsr_power(ri_2c_inv, -1.0_dp, ri_data%eps_eigval, n_dependent, &
3860 para_env, blacs_env, verbose=ri_data%unit_nr_dbcsr > 0)
3863 CALL dbt_create(ri_2c_ints, t2c_ri_tmp)
3864 CALL create_2c_tensor(t2c_ri_ints, dist1, dist2, ri_data%pgrid_2d, &
3865 ri_data%bsizes_RI_split, ri_data%bsizes_RI_split, &
3867 CALL dbt_create(t2c_ri_ints, t2c_ri_inv)
3869 CALL dbt_copy_matrix_to_tensor(ri_2c_ints, t2c_ri_tmp)
3870 CALL dbt_copy(t2c_ri_tmp, t2c_ri_ints, move_data=.true.)
3871 CALL dbt_filter(t2c_ri_ints, ri_data%filter_eps)
3873 CALL dbt_copy_matrix_to_tensor(ri_2c_inv, t2c_ri_tmp)
3874 CALL dbt_copy(t2c_ri_tmp, t2c_ri_inv, move_data=.true.)
3875 CALL dbt_filter(t2c_ri_inv, ri_data%filter_eps)
3877 CALL dbcsr_release(ri_2c_inv)
3878 CALL dbt_destroy(t2c_ri_tmp)
3879 DEALLOCATE (dist1, dist2)
3882 CALL dbt_create(rho_ao(ispin, 1)%matrix, rho_ao_tmp)
3883 CALL create_2c_tensor(rho_ao_t, dist1, dist2, ri_data%pgrid_2d, &
3884 ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
3886 DEALLOCATE (dist1, dist2)
3888 CALL dbt_copy_matrix_to_tensor(rho_ao(ispin, 1)%matrix, rho_ao_tmp)
3889 CALL dbt_copy(rho_ao_tmp, rho_ao_t, move_data=.true.)
3890 CALL dbt_filter(rho_ao_t, ri_data%filter_eps)
3891 CALL dbt_destroy(rho_ao_tmp)
3894 ALLOCATE (dist1(
SIZE(ri_data%bsizes_AO_split)), dist2(
SIZE(ri_data%bsizes_AO_split)), dist3(1))
3896 CALL dbt_get_info(rho_ao_t, pdims=pdims_2d, proc_dist_1=dist1, proc_dist_2=dist2)
3897 CALL dbt_default_distvec(1, 1, [1], dist3)
3899 pdims_3d(1) = pdims_2d(1)
3900 pdims_3d(2) = pdims_2d(2)
3903 CALL dbt_pgrid_create(para_env, pdims_3d, pgrid_3d)
3904 CALL dbt_distribution_new(dist_3d, pgrid_3d, dist1, dist2, dist3)
3905 CALL dbt_create(rho_ao_t_3d,
"rho_ao_3d", dist_3d, [1, 2], [3], ri_data%bsizes_AO_split, &
3906 ri_data%bsizes_AO_split, [1])
3907 DEALLOCATE (dist1, dist2, dist3)
3908 CALL dbt_pgrid_destroy(pgrid_3d)
3909 CALL dbt_distribution_destroy(dist_3d)
3916 CALL dbt_iterator_start(iter, rho_ao_t)
3917 DO WHILE (dbt_iterator_blocks_left(iter))
3918 CALL dbt_iterator_next_block(iter, ind)
3919 CALL dbt_get_block(rho_ao_t, ind, blk, found)
3926 CALL dbt_iterator_stop(iter)
3929 ALLOCATE (idx1(nblks),
idx2(nblks),
idx3(nblks))
3935 CALL dbt_iterator_start(iter, rho_ao_t)
3936 DO WHILE (dbt_iterator_blocks_left(iter))
3937 CALL dbt_iterator_next_block(iter, ind)
3938 CALL dbt_get_block(rho_ao_t, ind, blk, found)
3942 idx1(nblks) = ind(1)
3943 idx2(nblks) = ind(2)
3948 CALL dbt_iterator_stop(iter)
3952 nblk_per_thread = nblks/omp_get_num_threads() + 1
3953 a = omp_get_thread_num()*nblk_per_thread + 1
3954 b = min(a + nblk_per_thread, nblks)
3955 CALL dbt_reserve_blocks(rho_ao_t_3d, idx1(a:b),
idx2(a:b),
idx3(a:b))
3961 CALL dbt_iterator_start(iter, rho_ao_t)
3962 DO WHILE (dbt_iterator_blocks_left(iter))
3963 CALL dbt_iterator_next_block(iter, ind)
3964 CALL dbt_get_block(rho_ao_t, ind, blk, found)
3966 ALLOCATE (blk_3d(
SIZE(blk, 1),
SIZE(blk, 2), 1))
3967 blk_3d(:, :, 1) = blk(:, :)
3969 CALL dbt_put_block(rho_ao_t_3d, [ind(1), ind(2), 1], [
SIZE(blk, 1),
SIZE(blk, 2), 1], blk_3d)
3971 DEALLOCATE (blk, blk_3d)
3974 CALL dbt_iterator_stop(iter)
3978 pdims_2d(1) = para_env%num_pe
3981 ALLOCATE (dist1(
SIZE(ri_data%bsizes_RI_split)), dist2(1))
3982 CALL dbt_default_distvec(
SIZE(ri_data%bsizes_RI_split), pdims_2d(1), ri_data%bsizes_RI_split, dist1)
3983 CALL dbt_default_distvec(1, pdims_2d(2), [1], dist2)
3985 CALL dbt_pgrid_create(para_env, pdims_2d, pgrid_2d)
3986 CALL dbt_distribution_new(dist_2d, pgrid_2d, dist1, dist2)
3987 CALL dbt_create(density_coeffs_t,
"density_coeffs", dist_2d, [1], [2], ri_data%bsizes_RI_split, [1])
3988 CALL dbt_create(density_coeffs_t, density_tmp)
3989 DEALLOCATE (dist1, dist2)
3990 CALL dbt_pgrid_destroy(pgrid_2d)
3991 CALL dbt_distribution_destroy(dist_2d)
3993 CALL dbt_get_info(ri_data%t_3c_int_ctr_3(1, 1), nfull_total=dims_3c)
3997 CALL dbt_pgrid_create(para_env, pdims_3d, pgrid_3d, tensor_dims=[max(1, natom/n_mem), natom, natom])
3998 ALLOCATE (t_3c_int_batched(1, 1))
3999 CALL create_3c_tensor(t_3c_int_batched(1, 1), dist1, dist2, dist3, pgrid_3d, &
4000 ri_data%bsizes_RI, ri_data%bsizes_AO, ri_data%bsizes_AO, map1=[1], map2=[2, 3], &
4001 name=
"(RI | AO AO)")
4003 CALL dbt_mp_environ_pgrid(pgrid_3d, pdims_3d, pcoord_3d)
4004 CALL mp_comm_t3c%create(pgrid_3d%mp_comm_2d, 3, pdims_3d)
4005 CALL distribution_3d_create(dist_nl3c, dist1, dist2, dist3, nkind, particle_set, &
4006 mp_comm_t3c, own_comm=.true.)
4007 DEALLOCATE (dist1, dist2, dist3)
4008 CALL dbt_pgrid_destroy(pgrid_3d)
4010 CALL build_3c_neighbor_lists(nl_3c, basis_set_ri, basis_set_ao, basis_set_ao, dist_nl3c, ri_data%ri_metric, &
4011 "HFX_3c_nl", qs_env, op_pos=1, sym_jk=.true., own_dist=.true.)
4013 n_mem = ri_data%n_mem
4014 CALL create_tensor_batches(ri_data%bsizes_RI, n_mem, dummy1, dummy2, batch_block_start, batch_block_end)
4017 CALL get_tensor_occupancy(ri_data%t_3c_int_ctr_2(1, 1), nze, occ)
4018 IF (nze == 0) calc_ints = .true.
4022 CALL build_3c_integrals(t_3c_int_batched, ri_data%filter_eps, qs_env, nl_3c, &
4023 basis_set_ri, basis_set_ao, basis_set_ao, &
4024 ri_data%ri_metric, int_eps=ri_data%eps_schwarz, op_pos=1, &
4025 desymmetrize=.false., &
4026 bounds_i=[batch_block_start(i_mem), batch_block_end(i_mem)])
4027 CALL dbt_copy(t_3c_int_batched(1, 1), ri_data%t_3c_int_ctr_3(1, 1), order=[1, 3, 2])
4028 CALL dbt_copy(t_3c_int_batched(1, 1), ri_data%t_3c_int_ctr_3(1, 1), move_data=.true., summation=.true.)
4029 CALL dbt_filter(ri_data%t_3c_int_ctr_3(1, 1), ri_data%filter_eps)
4031 bounds_cpy(:, 2) = [sum(ri_data%bsizes_RI(1:batch_block_start(i_mem) - 1)) + 1, &
4032 sum(ri_data%bsizes_RI(1:batch_block_end(i_mem)))]
4033 bounds_cpy(:, 1) = [1, sum(ri_data%bsizes_AO)]
4034 bounds_cpy(:, 3) = [1, sum(ri_data%bsizes_AO)]
4035 CALL dbt_copy(ri_data%t_3c_int_ctr_2(1, 1), ri_data%t_3c_int_ctr_3(1, 1), &
4036 order=[2, 1, 3], bounds=bounds_cpy)
4040 CALL dbt_contract(1.0_dp, ri_data%t_3c_int_ctr_3(1, 1), rho_ao_t_3d, 0.0_dp, density_tmp, &
4041 contract_1=[2, 3], notcontract_1=[1], &
4042 contract_2=[1, 2], notcontract_2=[3], &
4043 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps)
4044 CALL dbt_clear(ri_data%t_3c_int_ctr_3(1, 1))
4047 CALL dbt_contract(1.0_dp, t2c_ri_inv, density_tmp, 1.0_dp, density_coeffs_t, &
4048 contract_1=[2], notcontract_1=[1], &
4049 contract_2=[1], notcontract_2=[2], &
4050 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps)
4053 CALL neighbor_list_3c_destroy(nl_3c)
4055 IF (multiply_by_s)
THEN
4056 CALL dbt_contract(1.0_dp, t2c_ri_ints, density_coeffs_t, 0.0_dp, density_tmp, &
4057 contract_1=[2], notcontract_1=[1], &
4058 contract_2=[1], notcontract_2=[2], &
4059 map_1=[1], map_2=[2], filter_eps=ri_data%filter_eps)
4060 CALL dbt_copy(density_tmp, density_coeffs_t, move_data=.true.)
4063 ALLOCATE (density_coeffs(sum(ri_data%bsizes_RI)))
4064 density_coeffs = 0.0
4069 CALL dbt_iterator_start(iter, density_coeffs_t)
4070 DO WHILE (dbt_iterator_blocks_left(iter))
4071 CALL dbt_iterator_next_block(iter, ind)
4072 CALL dbt_get_block(density_coeffs_t, ind, blk, found)
4075 idx = sum(ri_data%bsizes_RI_split(1:ind(1) - 1))
4077 density_coeffs(
idx + 1:
idx + ri_data%bsizes_RI_split(ind(1))) = blk(:, 1)
4082 CALL dbt_iterator_stop(iter)
4084 CALL para_env%sum(density_coeffs)
4086 CALL dbt_destroy(t2c_ri_ints)
4087 CALL dbt_destroy(t2c_ri_inv)
4088 CALL dbt_destroy(density_tmp)
4089 CALL dbt_destroy(rho_ao_t)
4090 CALL dbt_destroy(rho_ao_t_3d)
4091 CALL dbt_destroy(density_coeffs_t)
4092 CALL dbt_destroy(t_3c_int_batched(1, 1))
4094 CALL timestop(handle)
4096 END SUBROUTINE get_ri_density_coeffs
4106 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: idx_to_at
4107 INTEGER,
DIMENSION(:),
INTENT(IN) :: bsizes_split, bsizes_orig
4109 INTEGER :: full_sum, iat, iblk, split_sum
4112 full_sum = bsizes_orig(iat)
4114 DO iblk = 1,
SIZE(bsizes_split)
4115 split_sum = split_sum + bsizes_split(iblk)
4117 IF (split_sum .GT. full_sum)
THEN
4119 full_sum = full_sum + bsizes_orig(iat)
4122 idx_to_at(iblk) = iat
4132 FUNCTION my_sqrt(values)
4133 REAL(kind=dp),
DIMENSION(:),
INTENT(IN) :: values
4134 REAL(kind=dp),
DIMENSION(SIZE(values)) :: my_sqrt
4136 my_sqrt = sqrt(values)
4144 FUNCTION my_invsqrt(values)
4145 REAL(kind=dp),
DIMENSION(:),
INTENT(IN) :: values
4146 REAL(kind=dp),
DIMENSION(SIZE(values)) :: my_invsqrt
4148 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.
Handles all functions related to the CELL.
methods related to the blacs parallel environment
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
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, upper_to_full)
used to replace the cholesky decomposition by the inverse
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 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 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_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 dealloc_containers(DATA, memory_usage)
...
subroutine, public alloc_containers(DATA, bin_size)
...
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 matrix_sqrt_newton_schulz(matrix_sqrt, matrix_sqrt_inv, matrix, threshold, order, eps_lanczos, max_iter_lanczos, symmetrize, converged)
compute the sqrt of a matrix via the sign function and the corresponding Newton-Schulz iterations the...
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 ...
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.
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_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, 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, 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 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_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_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 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.
subroutine, public build_2c_integrals(t2c, filter_eps, qs_env, nl_2c, basis_i, basis_j, potential_parameter, do_kpoints, do_hfx_kpoints, ext_kpoints, regularization_RI)
...
subroutine, public build_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, bounds_i, bounds_j, bounds_k, RI_range, img_to_RI_cell)
Build 3-center integral tensor.
All kind of helpful little routines.