(git:ed6f26b)
Loading...
Searching...
No Matches
mp2_eri_gpw.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Routines to calculate 2c- and 3c-integrals for RI with GPW
10!> \par History
11!> 07.2019 separated from mp2_integrals.F [Frederick Stein]
12! **************************************************************************************************
17 USE cell_types, ONLY: cell_type,&
18 pbc
20 USE cp_dbcsr_api, ONLY: dbcsr_p_type,&
29 USE kinds, ONLY: dp
31 USE mathconstants, ONLY: fourpi
33 USE orbital_pointers, ONLY: ncoset
35 USE pw_env_methods, ONLY: pw_env_create,&
37 USE pw_env_types, ONLY: pw_env_get,&
40 USE pw_methods, ONLY: &
47 USE pw_types, ONLY: pw_c1d_gs_type,&
55 USE qs_integrate_potential, ONLY: integrate_pgf_product,&
56 integrate_v_rspace
57 USE qs_kind_types, ONLY: get_qs_kind,&
70
71!$ USE OMP_LIB, ONLY: omp_get_max_threads, omp_get_thread_num
72#include "./base/base_uses.f90"
73
74 IMPLICIT NONE
75
76 PRIVATE
77
78 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'mp2_eri_gpw'
79
83
84CONTAINS
85
86! **************************************************************************************************
87!> \brief ...
88!> \param psi_L ...
89!> \param rho_g ...
90!> \param atomic_kind_set ...
91!> \param qs_kind_set ...
92!> \param cell ...
93!> \param dft_control ...
94!> \param particle_set ...
95!> \param pw_env_sub ...
96!> \param external_vector ...
97!> \param poisson_env ...
98!> \param rho_r ...
99!> \param pot_g ...
100!> \param potential_parameter ...
101!> \param mat_munu ...
102!> \param qs_env ...
103!> \param task_list_sub ...
104! **************************************************************************************************
105 SUBROUTINE mp2_eri_3c_integrate_gpw(psi_L, rho_g, atomic_kind_set, qs_kind_set, &
106 cell, dft_control, particle_set, &
107 pw_env_sub, external_vector, poisson_env, rho_r, pot_g, &
108 potential_parameter, mat_munu, qs_env, task_list_sub)
109
110 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: psi_l
111 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_g
112 TYPE(atomic_kind_type), DIMENSION(:), INTENT(IN), &
113 POINTER :: atomic_kind_set
114 TYPE(qs_kind_type), DIMENSION(:), INTENT(IN), &
115 POINTER :: qs_kind_set
116 TYPE(cell_type), INTENT(IN), POINTER :: cell
117 TYPE(dft_control_type), INTENT(IN), POINTER :: dft_control
118 TYPE(particle_type), DIMENSION(:), INTENT(IN), &
119 POINTER :: particle_set
120 TYPE(pw_env_type), INTENT(IN), POINTER :: pw_env_sub
121 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: external_vector
122 TYPE(pw_poisson_type), INTENT(IN), POINTER :: poisson_env
123 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: rho_r
124 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: pot_g
125 TYPE(libint_potential_type), INTENT(IN) :: potential_parameter
126 TYPE(dbcsr_p_type), INTENT(INOUT) :: mat_munu
127 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
128 TYPE(task_list_type), INTENT(IN), POINTER :: task_list_sub
129
130 CHARACTER(LEN=*), PARAMETER :: routinen = 'mp2_eri_3c_integrate_gpw'
131
132 INTEGER :: handle
133
134 CALL timeset(routinen, handle)
135
136 ! pseudo psi_L
137 CALL collocate_function(external_vector, psi_l, rho_g, atomic_kind_set, &
138 qs_kind_set, cell, particle_set, pw_env_sub, &
139 dft_control%qs_control%eps_rho_rspace, basis_type="RI_AUX")
140
141 CALL calc_potential_gpw(rho_r, rho_g, poisson_env, pot_g, potential_parameter)
142
143 ! and finally (K|mu nu)
144 CALL dbcsr_set(mat_munu%matrix, 0.0_dp)
145 CALL integrate_v_rspace(rho_r, hmat=mat_munu, qs_env=qs_env, &
146 calculate_forces=.false., compute_tau=.false., gapw=.false., &
147 pw_env_external=pw_env_sub, task_list_external=task_list_sub)
148
149 CALL timestop(handle)
150
151 END SUBROUTINE mp2_eri_3c_integrate_gpw
152
153! **************************************************************************************************
154!> \brief Integrates the potential of an RI function
155!> \param qs_env ...
156!> \param para_env_sub ...
157!> \param my_group_L_start ...
158!> \param my_group_L_end ...
159!> \param natom ...
160!> \param potential_parameter ...
161!> \param sab_orb_sub ...
162!> \param L_local_col ...
163!> \param kind_of ...
164! **************************************************************************************************
165 SUBROUTINE mp2_eri_2c_integrate_gpw(qs_env, para_env_sub, my_group_L_start, my_group_L_end, &
166 natom, potential_parameter, sab_orb_sub, L_local_col, kind_of)
167
168 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
169 TYPE(mp_para_env_type), INTENT(IN), POINTER :: para_env_sub
170 INTEGER, INTENT(IN) :: my_group_l_start, my_group_l_end, natom
171 TYPE(libint_potential_type), INTENT(IN) :: potential_parameter
172 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
173 INTENT(IN), POINTER :: sab_orb_sub
174 REAL(kind=dp), DIMENSION(:, :), INTENT(OUT) :: l_local_col
175 INTEGER, DIMENSION(:), INTENT(IN) :: kind_of
176
177 CHARACTER(LEN=*), PARAMETER :: routinen = 'mp2_eri_2c_integrate_gpw'
178
179 INTEGER :: dir, handle, handle2, i_counter, iatom, igrid_level, ikind, ipgf, iset, lb(3), &
180 lll, location(3), max_nseta, na1, na2, ncoa, nseta, offset, sgfa, tp(3), ub(3)
181 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: offset_2d
182 INTEGER, DIMENSION(:), POINTER :: la_max, la_min, npgfa, nsgfa
183 INTEGER, DIMENSION(:, :), POINTER :: first_sgfa
184 LOGICAL :: map_it_here, use_subpatch
185 REAL(kind=dp) :: cutoff_old, radius, relative_cutoff_old
186 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: e_cutoff_old
187 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: i_ab
188 REAL(kind=dp), DIMENSION(3) :: ra
189 REAL(kind=dp), DIMENSION(:), POINTER :: set_radius_a
190 REAL(kind=dp), DIMENSION(:, :), POINTER :: i_tmp2, rpgfa, sphi_a, zeta
191 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
192 TYPE(cell_type), POINTER :: cell
193 TYPE(dft_control_type), POINTER :: dft_control
194 TYPE(gto_basis_set_type), POINTER :: basis_set_a
195 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
196 TYPE(pw_c1d_gs_type) :: pot_g, rho_g
197 TYPE(pw_env_type), POINTER :: pw_env_sub
198 TYPE(pw_poisson_type), POINTER :: poisson_env
199 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
200 TYPE(pw_r3d_rs_type) :: psi_l, rho_r
201 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
202 TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
203 POINTER :: rs_descs
204 TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_v
205 TYPE(task_list_type), POINTER :: task_list_sub
206
207 CALL timeset(routinen, handle)
208
209 CALL prepare_gpw(qs_env, dft_control, e_cutoff_old, cutoff_old, relative_cutoff_old, para_env_sub, pw_env_sub, &
210 auxbas_pw_pool, poisson_env, task_list_sub, rho_r, rho_g, pot_g, psi_l, sab_orb_sub)
211
212 CALL get_qs_env(qs_env, cell=cell, qs_kind_set=qs_kind_set, atomic_kind_set=atomic_kind_set, particle_set=particle_set)
213
214 l_local_col = 0.0_dp
215
216 i_counter = 0
217 DO lll = my_group_l_start, my_group_l_end
218 i_counter = i_counter + 1
219
220 ! pseudo psi_L
221 CALL collocate_single_gaussian(psi_l, rho_g, atomic_kind_set, &
222 qs_kind_set, cell, dft_control, particle_set, pw_env_sub, &
223 required_function=lll, basis_type="RI_AUX")
224
225 CALL timeset(routinen//"_pot_lm", handle2)
226
227 CALL calc_potential_gpw(rho_r, rho_g, poisson_env, pot_g, potential_parameter)
228
229 NULLIFY (rs_v)
230 NULLIFY (rs_descs)
231 CALL pw_env_get(pw_env_sub, rs_descs=rs_descs, rs_grids=rs_v)
232 CALL potential_pw2rs(rs_v, rho_r, pw_env_sub)
233
234 CALL timestop(handle2)
235
236 offset = 0
237 ! Prepare offset ahead of OMP parallel loop
238 CALL get_qs_kind_set(qs_kind_set=qs_kind_set, maxnset=max_nseta, basis_type="RI_AUX")
239 ALLOCATE (offset_2d(max_nseta, natom))
240
241 DO iatom = 1, natom
242 ikind = kind_of(iatom)
243 CALL get_qs_kind(qs_kind=qs_kind_set(ikind), basis_set=basis_set_a, basis_type="RI_AUX")
244 nseta = basis_set_a%nset
245 nsgfa => basis_set_a%nsgf_set
246 DO iset = 1, nseta
247 offset = offset + nsgfa(iset)
248 offset_2d(iset, iatom) = offset
249 END DO
250 END DO
251
252 ! integrate the little bastards
253 !$OMP PARALLEL DO DEFAULT(NONE) &
254 !$OMP SHARED(natom, particle_set, cell, pw_env_sub, rs_v, offset_2d, &
255 !$OMP qs_kind_set, ncoset, para_env_sub, dft_control, i_counter, &
256 !$OMP kind_of, l_local_col) &
257 !$OMP PRIVATE(iatom, ikind, basis_set_a, first_sgfa, la_max, la_min, npgfa, &
258 !$OMP nseta, nsgfa, rpgfa, set_radius_a, sphi_a, zeta, &
259 !$OMP ra, iset, ncoa, I_tmp2, I_ab, igrid_level, &
260 !$OMP map_it_here, dir, tp, lb, ub, location, ipgf, &
261 !$OMP sgfa, na1, na2, radius, offset, use_subpatch)
262 DO iatom = 1, natom
263 ikind = kind_of(iatom)
264 CALL get_qs_kind(qs_kind=qs_kind_set(ikind), basis_set=basis_set_a, basis_type="RI_AUX")
265
266 first_sgfa => basis_set_a%first_sgf
267 la_max => basis_set_a%lmax
268 la_min => basis_set_a%lmin
269 npgfa => basis_set_a%npgf
270 nseta = basis_set_a%nset
271 nsgfa => basis_set_a%nsgf_set
272 rpgfa => basis_set_a%pgf_radius
273 set_radius_a => basis_set_a%set_radius
274 sphi_a => basis_set_a%sphi
275 zeta => basis_set_a%zet
276
277 ra(:) = pbc(particle_set(iatom)%r, cell)
278
279 DO iset = 1, nseta
280 ncoa = npgfa(iset)*ncoset(la_max(iset))
281 sgfa = first_sgfa(1, iset)
282
283 ALLOCATE (i_tmp2(ncoa, 1))
284 i_tmp2 = 0.0_dp
285 ALLOCATE (i_ab(nsgfa(iset), 1))
286 i_ab = 0.0_dp
287
288 offset = offset_2d(iset, iatom)
289
290 igrid_level = gaussian_gridlevel(pw_env_sub%gridlevel_info, minval(zeta(:, iset)))
291 use_subpatch = .NOT. all(rs_v(igrid_level)%desc%perd == 1)
292
293 IF (map_gaussian_here(rs_v(igrid_level), cell%h_inv, ra, &
294 offset, para_env_sub%num_pe, para_env_sub%mepos)) THEN
295 DO ipgf = 1, npgfa(iset)
296 sgfa = first_sgfa(1, iset)
297 na1 = (ipgf - 1)*ncoset(la_max(iset)) + 1
298 na2 = ipgf*ncoset(la_max(iset))
299 igrid_level = gaussian_gridlevel(pw_env_sub%gridlevel_info, zeta(ipgf, iset))
300
301 radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
302 lb_min=0, lb_max=0, ra=ra, rb=ra, rp=ra, &
303 zetp=zeta(ipgf, iset), &
304 eps=dft_control%qs_control%eps_gvg_rspace, &
305 prefactor=1.0_dp, cutoff=1.0_dp)
306
307 CALL integrate_pgf_product( &
308 la_max=la_max(iset), zeta=zeta(ipgf, iset), la_min=la_min(iset), &
309 lb_max=0, zetb=0.0_dp, lb_min=0, &
310 ra=ra, rab=(/0.0_dp, 0.0_dp, 0.0_dp/), &
311 rsgrid=rs_v(igrid_level), &
312 hab=i_tmp2, &
313 o1=na1 - 1, &
314 o2=0, &
315 radius=radius, &
316 calculate_forces=.false., &
317 use_subpatch=use_subpatch, &
318 subpatch_pattern=0)
319 END DO
320
321 CALL dgemm("T", "N", nsgfa(iset), 1, ncoa, &
322 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
323 i_tmp2(1, 1), SIZE(i_tmp2, 1), &
324 1.0_dp, i_ab(1, 1), SIZE(i_ab, 1))
325
326 l_local_col(offset - nsgfa(iset) + 1:offset, i_counter) = i_ab(1:nsgfa(iset), 1)
327 END IF
328
329 DEALLOCATE (i_tmp2)
330 DEALLOCATE (i_ab)
331
332 END DO
333 END DO
334 !$OMP END PARALLEL DO
335 DEALLOCATE (offset_2d)
336
337 END DO
338
339 CALL para_env_sub%sum(l_local_col)
340
341 CALL cleanup_gpw(qs_env, e_cutoff_old, cutoff_old, relative_cutoff_old, para_env_sub, pw_env_sub, &
342 task_list_sub, auxbas_pw_pool, rho_r, rho_g, pot_g, psi_l)
343
344 CALL timestop(handle)
345
346 END SUBROUTINE
347
348! **************************************************************************************************
349!> \brief Integrates the potential of a RI function obtaining the forces and stress tensor
350!> \param rho_r ...
351!> \param LLL ...
352!> \param rho_g ...
353!> \param atomic_kind_set ...
354!> \param qs_kind_set ...
355!> \param particle_set ...
356!> \param cell ...
357!> \param pw_env_sub ...
358!> \param poisson_env ...
359!> \param pot_g ...
360!> \param potential_parameter ...
361!> \param use_virial ...
362!> \param rho_g_copy ...
363!> \param dvg ...
364!> \param kind_of ...
365!> \param atom_of_kind ...
366!> \param G_PQ_local ...
367!> \param force ...
368!> \param h_stress ...
369!> \param para_env_sub ...
370!> \param dft_control ...
371!> \param psi_L ...
372!> \param factor ...
373! **************************************************************************************************
374 SUBROUTINE integrate_potential_forces_2c(rho_r, LLL, rho_g, atomic_kind_set, &
375 qs_kind_set, particle_set, cell, pw_env_sub, poisson_env, pot_g, &
376 potential_parameter, use_virial, rho_g_copy, dvg, &
377 kind_of, atom_of_kind, G_PQ_local, force, h_stress, para_env_sub, &
378 dft_control, psi_L, factor)
379
380 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: rho_r
381 INTEGER, INTENT(IN) :: lll
382 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_g
383 TYPE(atomic_kind_type), DIMENSION(:), INTENT(IN), &
384 POINTER :: atomic_kind_set
385 TYPE(qs_kind_type), DIMENSION(:), INTENT(IN), &
386 POINTER :: qs_kind_set
387 TYPE(particle_type), DIMENSION(:), INTENT(IN), &
388 POINTER :: particle_set
389 TYPE(cell_type), INTENT(IN), POINTER :: cell
390 TYPE(pw_env_type), INTENT(IN), POINTER :: pw_env_sub
391 TYPE(pw_poisson_type), INTENT(IN), POINTER :: poisson_env
392 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: pot_g
393 TYPE(libint_potential_type), INTENT(IN) :: potential_parameter
394 LOGICAL, INTENT(IN) :: use_virial
395 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_g_copy, dvg(3)
396 INTEGER, DIMENSION(:), INTENT(IN) :: kind_of, atom_of_kind
397 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: g_pq_local
398 TYPE(qs_force_type), DIMENSION(:), INTENT(IN), &
399 POINTER :: force
400 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT) :: h_stress
401 TYPE(mp_para_env_type), INTENT(IN) :: para_env_sub
402 TYPE(dft_control_type), INTENT(IN), POINTER :: dft_control
403 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: psi_l
404 REAL(kind=dp), INTENT(IN) :: factor
405
406 CHARACTER(LEN=*), PARAMETER :: routinen = 'integrate_potential_forces_2c'
407
408 INTEGER :: handle, handle2
409
410 CALL timeset(routinen, handle)
411
412 ! calculate potential associated to the single aux function
413 CALL timeset(routinen//"_wf_pot", handle2)
414 ! pseudo psi_L
415 CALL pw_zero(rho_r)
416 CALL pw_zero(rho_g)
417 CALL collocate_single_gaussian(rho_r, rho_g, atomic_kind_set, &
418 qs_kind_set, cell, dft_control, particle_set, &
419 pw_env_sub, required_function=lll, basis_type='RI_AUX')
420 IF (use_virial) THEN
421 CALL calc_potential_gpw(rho_r, rho_g, poisson_env, pot_g, potential_parameter, dvg)
422 ELSE
423 CALL calc_potential_gpw(rho_r, rho_g, poisson_env, pot_g, potential_parameter)
424 END IF
425 CALL timestop(handle2)
426
427 IF (use_virial) THEN
428 ! make a copy of the density in G space
429 CALL pw_copy(rho_g, rho_g_copy)
430
431 ! add the volume contribution to the virial due to
432 ! the (P|Q) integrals, first we put the full gamme_PQ
433 ! pseudo wave-function into grid in order to calculate the
434 ! hartree potential derivatives
435 CALL pw_zero(psi_l)
436 CALL pw_zero(rho_g)
437 CALL collocate_function(0.5_dp*factor*g_pq_local, psi_l, rho_g, atomic_kind_set, &
438 qs_kind_set, cell, particle_set, pw_env_sub, &
439 dft_control%qs_control%eps_rho_rspace, &
440 basis_type="RI_AUX")
441 ! transfer to reciprocal space and calculate potential
442 CALL calc_potential_gpw(psi_l, rho_g, poisson_env, pot_g, potential_parameter, no_transfer=.true.)
443 ! update virial with volume term (first calculate hartree like energy (diagonal part of the virial))
444 CALL virial_gpw_potential(rho_g_copy, pot_g, rho_g, dvg, h_stress, potential_parameter, para_env_sub)
445 END IF
446
447 ! integrate the potential of the single gaussian and update
448 ! 2-center forces with Gamma_PQ
449 CALL integrate_potential(pw_env_sub, rho_r, kind_of, atom_of_kind, particle_set, qs_kind_set, &
450 -0.25_dp*factor*g_pq_local, cell, force, use_virial, h_stress, para_env_sub, dft_control)
451
452 CALL timestop(handle)
453 END SUBROUTINE integrate_potential_forces_2c
454
455! **************************************************************************************************
456!> \brief Takes the precomputed potential of an RI wave-function and determines matrix element and
457!> gradients with product of Gaussians
458!> \param mat_munu ...
459!> \param rho_r ...
460!> \param matrix_P_munu ...
461!> \param qs_env ...
462!> \param pw_env_sub ...
463!> \param task_list_sub ...
464! **************************************************************************************************
465 SUBROUTINE integrate_potential_forces_3c_1c(mat_munu, rho_r, matrix_P_munu, qs_env, pw_env_sub, &
466 task_list_sub)
467
468 TYPE(dbcsr_p_type), INTENT(INOUT) :: mat_munu
469 TYPE(pw_r3d_rs_type), INTENT(IN) :: rho_r
470 TYPE(dbcsr_p_type), INTENT(IN) :: matrix_p_munu
471 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
472 TYPE(pw_env_type), INTENT(IN), POINTER :: pw_env_sub
473 TYPE(task_list_type), INTENT(INOUT), POINTER :: task_list_sub
474
475 CHARACTER(LEN=*), PARAMETER :: routinen = 'integrate_potential_forces_3c_1c'
476
477 INTEGER :: handle
478
479 CALL timeset(routinen, handle)
480
481 ! integrate the potential of the single gaussian and update
482 ! 3-center forces
483 CALL dbcsr_set(mat_munu%matrix, 0.0_dp)
484 CALL integrate_v_rspace(rho_r, hmat=mat_munu, pmat=matrix_p_munu, &
485 qs_env=qs_env, calculate_forces=.true., compute_tau=.false., gapw=.false., &
486 pw_env_external=pw_env_sub, &
487 task_list_external=task_list_sub)
488
489 CALL timestop(handle)
491
492! **************************************************************************************************
493!> \brief Integrates potential of two Gaussians to a potential
494!> \param matrix_P_munu ...
495!> \param rho_r ...
496!> \param rho_g ...
497!> \param task_list_sub ...
498!> \param pw_env_sub ...
499!> \param potential_parameter ...
500!> \param ks_env ...
501!> \param poisson_env ...
502!> \param pot_g ...
503!> \param use_virial ...
504!> \param rho_g_copy ...
505!> \param dvg ...
506!> \param h_stress ...
507!> \param para_env_sub ...
508!> \param kind_of ...
509!> \param atom_of_kind ...
510!> \param qs_kind_set ...
511!> \param particle_set ...
512!> \param cell ...
513!> \param LLL ...
514!> \param force ...
515!> \param dft_control ...
516! **************************************************************************************************
517 SUBROUTINE integrate_potential_forces_3c_2c(matrix_P_munu, rho_r, rho_g, task_list_sub, pw_env_sub, &
518 potential_parameter, &
519 ks_env, poisson_env, pot_g, use_virial, rho_g_copy, dvg, &
520 h_stress, para_env_sub, kind_of, atom_of_kind, &
521 qs_kind_set, particle_set, cell, LLL, force, dft_control)
522
523 TYPE(dbcsr_p_type), INTENT(IN) :: matrix_p_munu
524 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: rho_r
525 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_g
526 TYPE(task_list_type), INTENT(IN), POINTER :: task_list_sub
527 TYPE(pw_env_type), INTENT(IN), POINTER :: pw_env_sub
528 TYPE(libint_potential_type), INTENT(IN) :: potential_parameter
529 TYPE(qs_ks_env_type), INTENT(IN), POINTER :: ks_env
530 TYPE(pw_poisson_type), INTENT(IN), POINTER :: poisson_env
531 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: pot_g
532 LOGICAL, INTENT(IN) :: use_virial
533 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_g_copy
534 TYPE(pw_c1d_gs_type), INTENT(IN) :: dvg(3)
535 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT) :: h_stress
536 TYPE(mp_para_env_type), INTENT(IN) :: para_env_sub
537 INTEGER, DIMENSION(:), INTENT(IN) :: kind_of, atom_of_kind
538 TYPE(qs_kind_type), DIMENSION(:), INTENT(IN), &
539 POINTER :: qs_kind_set
540 TYPE(particle_type), DIMENSION(:), INTENT(IN), &
541 POINTER :: particle_set
542 TYPE(cell_type), INTENT(IN), POINTER :: cell
543 INTEGER, INTENT(IN) :: lll
544 TYPE(qs_force_type), DIMENSION(:), INTENT(IN), &
545 POINTER :: force
546 TYPE(dft_control_type), INTENT(IN), POINTER :: dft_control
547
548 CHARACTER(LEN=*), PARAMETER :: routinen = 'integrate_potential_forces_3c_2c'
549
550 INTEGER :: atom_a, handle, handle2, iatom, &
551 igrid_level, ikind, iorb, ipgf, iset, &
552 na1, na2, ncoa, nseta, offset, sgfa
553 INTEGER, DIMENSION(:), POINTER :: la_max, la_min, npgfa, nsgfa
554 INTEGER, DIMENSION(:, :), POINTER :: first_sgfa
555 LOGICAL :: map_it_here, skip_shell, use_subpatch
556 REAL(kind=dp) :: radius
557 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: i_ab
558 REAL(kind=dp), DIMENSION(3) :: force_a, force_b, ra
559 REAL(kind=dp), DIMENSION(3, 3) :: my_virial_a, my_virial_b
560 REAL(kind=dp), DIMENSION(:), POINTER :: set_radius_a
561 REAL(kind=dp), DIMENSION(:, :), POINTER :: i_tmp2, pab, rpgfa, sphi_a, zeta
562 TYPE(gto_basis_set_type), POINTER :: basis_set_a
563 TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
564 POINTER :: rs_descs
565 TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_v
566
567 CALL timeset(routinen, handle)
568
569 ! put the gamma density on grid
570 CALL timeset(routinen//"_Gpot", handle2)
571 CALL pw_zero(rho_r)
572 CALL pw_zero(rho_g)
573 CALL calculate_rho_elec(matrix_p=matrix_p_munu%matrix, &
574 rho=rho_r, &
575 rho_gspace=rho_g, &
576 task_list_external=task_list_sub, &
577 pw_env_external=pw_env_sub, &
578 ks_env=ks_env)
579 ! calculate associated hartree potential
580 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
581 CALL calc_potential_gpw(rho_r, rho_g, poisson_env, pot_g, potential_parameter)
582 CALL timestop(handle2)
583
584 IF (use_virial) CALL virial_gpw_potential(rho_g_copy, pot_g, rho_g, dvg, h_stress, potential_parameter, para_env_sub)
585
586 ! integrate potential with auxiliary basis function derivatives
587 NULLIFY (rs_v)
588 NULLIFY (rs_descs)
589 CALL pw_env_get(pw_env_sub, rs_descs=rs_descs, rs_grids=rs_v)
590 CALL potential_pw2rs(rs_v, rho_r, pw_env_sub)
591
592 offset = 0
593 DO iatom = 1, SIZE(kind_of)
594 ikind = kind_of(iatom)
595 atom_a = atom_of_kind(iatom)
596 CALL get_qs_kind(qs_kind=qs_kind_set(ikind), basis_set=basis_set_a, &
597 basis_type="RI_AUX")
598
599 first_sgfa => basis_set_a%first_sgf
600 la_max => basis_set_a%lmax
601 la_min => basis_set_a%lmin
602 npgfa => basis_set_a%npgf
603 nseta = basis_set_a%nset
604 nsgfa => basis_set_a%nsgf_set
605 rpgfa => basis_set_a%pgf_radius
606 set_radius_a => basis_set_a%set_radius
607 sphi_a => basis_set_a%sphi
608 zeta => basis_set_a%zet
609
610 ra(:) = pbc(particle_set(iatom)%r, cell)
611
612 force_a(:) = 0.0_dp
613 force_b(:) = 0.0_dp
614 IF (use_virial) THEN
615 my_virial_a = 0.0_dp
616 my_virial_b = 0.0_dp
617 END IF
618
619 DO iset = 1, nseta
620 ncoa = npgfa(iset)*ncoset(la_max(iset))
621 sgfa = first_sgfa(1, iset)
622
623 ALLOCATE (i_tmp2(ncoa, 1))
624 i_tmp2 = 0.0_dp
625 ALLOCATE (i_ab(nsgfa(iset), 1))
626 i_ab = 0.0_dp
627 ALLOCATE (pab(ncoa, 1))
628 pab = 0.0_dp
629
630 skip_shell = .true.
631 DO iorb = 1, nsgfa(iset)
632 IF (iorb + offset == lll) THEN
633 i_ab(iorb, 1) = 1.0_dp
634 skip_shell = .false.
635 END IF
636 END DO
637
638 IF (skip_shell) THEN
639 offset = offset + nsgfa(iset)
640 DEALLOCATE (i_tmp2)
641 DEALLOCATE (i_ab)
642 DEALLOCATE (pab)
643 cycle
644 END IF
645
646 CALL dgemm("N", "N", ncoa, 1, nsgfa(iset), &
647 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
648 i_ab(1, 1), SIZE(i_ab, 1), &
649 0.0_dp, pab(1, 1), SIZE(pab, 1))
650 DEALLOCATE (i_ab)
651
652 igrid_level = gaussian_gridlevel(pw_env_sub%gridlevel_info, minval(zeta(:, iset)))
653 map_it_here = .false.
654 use_subpatch = .NOT. all(rs_v(igrid_level)%desc%perd == 1)
655
656 IF (map_gaussian_here(rs_v(igrid_level), cell%h_inv, ra, offset, para_env_sub%num_pe, para_env_sub%mepos)) THEN
657 DO ipgf = 1, npgfa(iset)
658 na1 = (ipgf - 1)*ncoset(la_max(iset)) + 1
659 na2 = ipgf*ncoset(la_max(iset))
660 igrid_level = gaussian_gridlevel(pw_env_sub%gridlevel_info, zeta(ipgf, iset))
661
662 radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
663 lb_min=0, lb_max=0, ra=ra, rb=ra, rp=ra, &
664 zetp=zeta(ipgf, iset), &
665 eps=dft_control%qs_control%eps_gvg_rspace, &
666 prefactor=1.0_dp, cutoff=1.0_dp)
667
668 CALL integrate_pgf_product(la_max=la_max(iset), zeta=zeta(ipgf, iset)/2.0_dp, la_min=la_min(iset), &
669 lb_max=0, zetb=zeta(ipgf, iset)/2.0_dp, lb_min=0, &
670 ra=ra, rab=(/0.0_dp, 0.0_dp, 0.0_dp/), &
671 rsgrid=rs_v(igrid_level), &
672 hab=i_tmp2, &
673 pab=pab, &
674 o1=na1 - 1, &
675 o2=0, &
676 radius=radius, &
677 calculate_forces=.true., &
678 force_a=force_a, force_b=force_b, &
679 use_virial=use_virial, &
680 my_virial_a=my_virial_a, &
681 my_virial_b=my_virial_b, &
682 use_subpatch=use_subpatch, &
683 subpatch_pattern=0)
684 END DO
685 END IF
686
687 DEALLOCATE (i_tmp2)
688 DEALLOCATE (pab)
689
690 offset = offset + nsgfa(iset)
691
692 END DO
693
694 force(ikind)%rho_elec(:, atom_a) = &
695 force(ikind)%rho_elec(:, atom_a) + force_a(:) + force_b(:)
696 IF (use_virial) THEN
697 h_stress = h_stress + my_virial_a + my_virial_b
698 END IF
699 END DO
700
701 CALL timestop(handle)
702
704
705! **************************************************************************************************
706!> \brief Calculates stress tensor contribution from the operator
707!> \param rho_g_copy ...
708!> \param pot_g ...
709!> \param rho_g ...
710!> \param dvg ...
711!> \param h_stress ...
712!> \param potential_parameter ...
713!> \param para_env_sub ...
714! **************************************************************************************************
715 SUBROUTINE virial_gpw_potential(rho_g_copy, pot_g, rho_g, dvg, h_stress, potential_parameter, para_env_sub)
716
717 TYPE(pw_c1d_gs_type), INTENT(IN) :: rho_g_copy, pot_g
718 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_g
719 TYPE(pw_c1d_gs_type), INTENT(IN) :: dvg(3)
720 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT) :: h_stress
721 TYPE(libint_potential_type), INTENT(IN) :: potential_parameter
722 TYPE(mp_para_env_type), INTENT(IN) :: para_env_sub
723
724 CHARACTER(LEN=*), PARAMETER :: routinen = 'virial_gpw_potential'
725
726 INTEGER :: alpha, beta, handle
727 INTEGER, DIMENSION(3) :: comp
728 REAL(kind=dp) :: e_hartree
729
730 ! add the volume contribution
731 CALL timeset(routinen, handle)
732 e_hartree = 0.0_dp
733 e_hartree = pw_integral_ab(rho_g_copy, pot_g)
734
735 DO alpha = 1, 3
736 comp = 0
737 comp(alpha) = 1
738 CALL pw_copy(pot_g, rho_g)
739 CALL pw_derive(rho_g, comp)
740 CALL factor_virial_gpw(rho_g, potential_parameter)
741 h_stress(alpha, alpha) = h_stress(alpha, alpha) - e_hartree/real(para_env_sub%num_pe, dp)
742 DO beta = alpha, 3
743 h_stress(alpha, beta) = h_stress(alpha, beta) &
744 - 2.0_dp*pw_integral_ab(rho_g, dvg(beta))/fourpi/real(para_env_sub%num_pe, dp)
745 h_stress(beta, alpha) = h_stress(alpha, beta)
746 END DO
747 END DO
748
749 CALL timestop(handle)
750 END SUBROUTINE virial_gpw_potential
751
752! **************************************************************************************************
753!> \brief Multiplies a potential in g space with the factor ln(V(g)/Vc(g))' with Vc(g) being the
754!> Fourier-transformed of the Coulomg potential
755!> \param pw ...
756!> \param potential_parameter parameters of potential V(g)
757! **************************************************************************************************
758 SUBROUTINE factor_virial_gpw(pw, potential_parameter)
759 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: pw
760 TYPE(libint_potential_type), INTENT(IN) :: potential_parameter
761
762 SELECT CASE (potential_parameter%potential_type)
764 RETURN
765 CASE (do_potential_long)
766 CALL pw_log_deriv_gauss(pw, potential_parameter%omega)
767 CASE (do_potential_short)
768 CALL pw_log_deriv_compl_gauss(pw, potential_parameter%omega)
770 CALL pw_log_deriv_mix_cl(pw, potential_parameter%omega, &
771 potential_parameter%scale_coulomb, potential_parameter%scale_longrange)
773 CALL pw_log_deriv_trunc(pw, potential_parameter%cutoff_radius)
774 CASE (do_potential_id)
775 CALL pw_zero(pw)
776 CASE DEFAULT
777 cpabort("Unknown potential type")
778 END SELECT
779
780 END SUBROUTINE factor_virial_gpw
781
782! **************************************************************************************************
783!> \brief Integrate potential of RI function with RI function
784!> \param pw_env_sub ...
785!> \param pot_r ...
786!> \param kind_of ...
787!> \param atom_of_kind ...
788!> \param particle_set ...
789!> \param qs_kind_set ...
790!> \param G_PQ_local ...
791!> \param cell ...
792!> \param force ...
793!> \param use_virial ...
794!> \param h_stress ...
795!> \param para_env_sub ...
796!> \param dft_control ...
797! **************************************************************************************************
798 SUBROUTINE integrate_potential(pw_env_sub, pot_r, kind_of, atom_of_kind, particle_set, qs_kind_set, &
799 G_PQ_local, cell, force, use_virial, h_stress, para_env_sub, dft_control)
800
801 TYPE(pw_env_type), INTENT(IN), POINTER :: pw_env_sub
802 TYPE(pw_r3d_rs_type), INTENT(IN) :: pot_r
803 INTEGER, DIMENSION(:), INTENT(IN) :: kind_of, atom_of_kind
804 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
805 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
806 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: g_pq_local
807 TYPE(cell_type), INTENT(IN), POINTER :: cell
808 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
809 LOGICAL, INTENT(IN) :: use_virial
810 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT) :: h_stress
811 TYPE(mp_para_env_type), INTENT(IN) :: para_env_sub
812 TYPE(dft_control_type), INTENT(IN), POINTER :: dft_control
813
814 CHARACTER(LEN=*), PARAMETER :: routinen = 'integrate_potential'
815
816 INTEGER :: atom_a, handle, iatom, igrid_level, &
817 ikind, ipgf, iset, na1, na2, ncoa, &
818 nseta, offset, sgfa
819 INTEGER, DIMENSION(:), POINTER :: la_max, la_min, npgfa, nsgfa
820 INTEGER, DIMENSION(:, :), POINTER :: first_sgfa
821 LOGICAL :: use_subpatch
822 REAL(kind=dp) :: radius
823 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: i_ab
824 REAL(kind=dp), DIMENSION(3) :: force_a, force_b, ra
825 REAL(kind=dp), DIMENSION(3, 3) :: my_virial_a, my_virial_b
826 REAL(kind=dp), DIMENSION(:), POINTER :: set_radius_a
827 REAL(kind=dp), DIMENSION(:, :), POINTER :: i_tmp2, pab, rpgfa, sphi_a, zeta
828 TYPE(gto_basis_set_type), POINTER :: basis_set_a
829 TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
830 POINTER :: rs_descs
831 TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_v
832
833 CALL timeset(routinen, handle)
834
835 NULLIFY (rs_v)
836 NULLIFY (rs_descs)
837 CALL pw_env_get(pw_env_sub, rs_descs=rs_descs, rs_grids=rs_v)
838 CALL potential_pw2rs(rs_v, pot_r, pw_env_sub)
839
840 offset = 0
841 DO iatom = 1, SIZE(kind_of)
842 ikind = kind_of(iatom)
843 atom_a = atom_of_kind(iatom)
844 CALL get_qs_kind(qs_kind=qs_kind_set(ikind), basis_set=basis_set_a, &
845 basis_type="RI_AUX")
846
847 first_sgfa => basis_set_a%first_sgf
848 la_max => basis_set_a%lmax
849 la_min => basis_set_a%lmin
850 npgfa => basis_set_a%npgf
851 nseta = basis_set_a%nset
852 nsgfa => basis_set_a%nsgf_set
853 rpgfa => basis_set_a%pgf_radius
854 set_radius_a => basis_set_a%set_radius
855 sphi_a => basis_set_a%sphi
856 zeta => basis_set_a%zet
857
858 ra(:) = pbc(particle_set(iatom)%r, cell)
859
860 force_a(:) = 0.0_dp
861 force_b(:) = 0.0_dp
862 IF (use_virial) THEN
863 my_virial_a = 0.0_dp
864 my_virial_b = 0.0_dp
865 END IF
866
867 DO iset = 1, nseta
868 ncoa = npgfa(iset)*ncoset(la_max(iset))
869 sgfa = first_sgfa(1, iset)
870
871 ALLOCATE (i_tmp2(ncoa, 1))
872 i_tmp2 = 0.0_dp
873 ALLOCATE (i_ab(nsgfa(iset), 1))
874 i_ab = 0.0_dp
875 ALLOCATE (pab(ncoa, 1))
876 pab = 0.0_dp
877
878 i_ab(1:nsgfa(iset), 1) = -4.0_dp*g_pq_local(offset + 1:offset + nsgfa(iset))
879
880 CALL dgemm("N", "N", ncoa, 1, nsgfa(iset), &
881 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
882 i_ab(1, 1), SIZE(i_ab, 1), &
883 0.0_dp, pab(1, 1), SIZE(pab, 1))
884
885 i_ab = 0.0_dp
886
887 igrid_level = gaussian_gridlevel(pw_env_sub%gridlevel_info, minval(zeta(:, iset)))
888 use_subpatch = .NOT. all(rs_v(igrid_level)%desc%perd == 1)
889
890 IF (map_gaussian_here(rs_v(igrid_level), cell%h_inv, ra, offset, para_env_sub%num_pe, para_env_sub%mepos)) THEN
891 DO ipgf = 1, npgfa(iset)
892 na1 = (ipgf - 1)*ncoset(la_max(iset)) + 1
893 na2 = ipgf*ncoset(la_max(iset))
894 igrid_level = gaussian_gridlevel(pw_env_sub%gridlevel_info, zeta(ipgf, iset))
895
896 radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
897 lb_min=0, lb_max=0, ra=ra, rb=ra, rp=ra, &
898 zetp=zeta(ipgf, iset), &
899 eps=dft_control%qs_control%eps_gvg_rspace, &
900 prefactor=1.0_dp, cutoff=1.0_dp)
901
902 CALL integrate_pgf_product(la_max=la_max(iset), zeta=zeta(ipgf, iset)/2.0_dp, la_min=la_min(iset), &
903 lb_max=0, zetb=zeta(ipgf, iset)/2.0_dp, lb_min=0, &
904 ra=ra, rab=(/0.0_dp, 0.0_dp, 0.0_dp/), &
905 rsgrid=rs_v(igrid_level), &
906 hab=i_tmp2, &
907 pab=pab, &
908 o1=na1 - 1, &
909 o2=0, &
910 radius=radius, &
911 calculate_forces=.true., &
912 force_a=force_a, force_b=force_b, &
913 use_virial=use_virial, &
914 my_virial_a=my_virial_a, &
915 my_virial_b=my_virial_b, &
916 use_subpatch=use_subpatch, &
917 subpatch_pattern=0)
918
919 END DO
920
921 END IF
922
923 DEALLOCATE (i_tmp2)
924 DEALLOCATE (i_ab)
925 DEALLOCATE (pab)
926
927 offset = offset + nsgfa(iset)
928
929 END DO
930
931 force(ikind)%rho_elec(:, atom_a) = &
932 force(ikind)%rho_elec(:, atom_a) + force_a(:) + force_b
933 IF (use_virial) THEN
934 h_stress = h_stress + my_virial_a + my_virial_b
935 END IF
936 END DO
937
938 CALL timestop(handle)
939
940 END SUBROUTINE
941
942! **************************************************************************************************
943!> \brief Prepares GPW calculation for RI-MP2/RI-RPA
944!> \param qs_env ...
945!> \param dft_control ...
946!> \param e_cutoff_old ...
947!> \param cutoff_old ...
948!> \param relative_cutoff_old ...
949!> \param para_env_sub ...
950!> \param pw_env_sub ...
951!> \param auxbas_pw_pool ...
952!> \param poisson_env ...
953!> \param task_list_sub ...
954!> \param rho_r ...
955!> \param rho_g ...
956!> \param pot_g ...
957!> \param psi_L ...
958!> \param sab_orb_sub ...
959! **************************************************************************************************
960 SUBROUTINE prepare_gpw(qs_env, dft_control, e_cutoff_old, cutoff_old, relative_cutoff_old, para_env_sub, pw_env_sub, &
961 auxbas_pw_pool, poisson_env, task_list_sub, rho_r, rho_g, pot_g, psi_L, sab_orb_sub)
962 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
963 TYPE(dft_control_type), INTENT(IN), POINTER :: dft_control
964 REAL(kind=dp), ALLOCATABLE, DIMENSION(:), &
965 INTENT(OUT) :: e_cutoff_old
966 REAL(kind=dp), INTENT(OUT) :: cutoff_old, relative_cutoff_old
967 TYPE(mp_para_env_type), INTENT(IN), POINTER :: para_env_sub
968 TYPE(pw_env_type), POINTER :: pw_env_sub
969 TYPE(pw_pool_type), INTENT(IN), POINTER :: auxbas_pw_pool
970 TYPE(pw_poisson_type), INTENT(IN), POINTER :: poisson_env
971 TYPE(task_list_type), POINTER :: task_list_sub
972 TYPE(pw_r3d_rs_type), INTENT(OUT) :: rho_r
973 TYPE(pw_c1d_gs_type), INTENT(OUT) :: rho_g, pot_g
974 TYPE(pw_r3d_rs_type), INTENT(OUT) :: psi_l
975 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
976 INTENT(IN), POINTER :: sab_orb_sub
977
978 CHARACTER(LEN=*), PARAMETER :: routinen = 'prepare_gpw'
979
980 INTEGER :: handle, i_multigrid, n_multigrid
981 LOGICAL :: skip_load_balance_distributed
982 REAL(kind=dp) :: progression_factor
983 TYPE(qs_ks_env_type), POINTER :: ks_env
984
985 CALL timeset(routinen, handle)
986
987 CALL get_qs_env(qs_env, dft_control=dft_control, ks_env=ks_env)
988
989 ! hack hack hack XXXXXXXXXXXXXXX rebuilds the pw_en with the new cutoffs
990 progression_factor = dft_control%qs_control%progression_factor
991 n_multigrid = SIZE(dft_control%qs_control%e_cutoff)
992 ALLOCATE (e_cutoff_old(n_multigrid))
993 e_cutoff_old(:) = dft_control%qs_control%e_cutoff
994 cutoff_old = dft_control%qs_control%cutoff
995
996 dft_control%qs_control%cutoff = qs_env%mp2_env%mp2_gpw%cutoff*0.5_dp
997 dft_control%qs_control%e_cutoff(1) = dft_control%qs_control%cutoff
998 DO i_multigrid = 2, n_multigrid
999 dft_control%qs_control%e_cutoff(i_multigrid) = dft_control%qs_control%e_cutoff(i_multigrid - 1) &
1000 /progression_factor
1001 END DO
1002
1003 relative_cutoff_old = dft_control%qs_control%relative_cutoff
1004 dft_control%qs_control%relative_cutoff = qs_env%mp2_env%mp2_gpw%relative_cutoff*0.5_dp
1005
1006 ! a pw_env
1007 NULLIFY (pw_env_sub)
1008 CALL pw_env_create(pw_env_sub)
1009 CALL pw_env_rebuild(pw_env_sub, qs_env, para_env_sub)
1010
1011 CALL pw_env_get(pw_env_sub, auxbas_pw_pool=auxbas_pw_pool, &
1012 poisson_env=poisson_env)
1013 ! hack hack hack XXXXXXXXXXXXXXX
1014
1015 ! now we need a task list, hard code skip_load_balance_distributed
1016 NULLIFY (task_list_sub)
1017 skip_load_balance_distributed = dft_control%qs_control%skip_load_balance_distributed
1018 CALL allocate_task_list(task_list_sub)
1019 CALL generate_qs_task_list(ks_env, task_list_sub, &
1020 reorder_rs_grid_ranks=.true., soft_valid=.false., &
1021 skip_load_balance_distributed=skip_load_balance_distributed, &
1022 pw_env_external=pw_env_sub, sab_orb_external=sab_orb_sub)
1023
1024 ! get some of the grids ready
1025 CALL auxbas_pw_pool%create_pw(rho_r)
1026 CALL auxbas_pw_pool%create_pw(rho_g)
1027 CALL auxbas_pw_pool%create_pw(pot_g)
1028 CALL auxbas_pw_pool%create_pw(psi_l)
1029
1030 ! run the FFT once, to set up buffers and to take into account the memory
1031 CALL pw_zero(rho_r)
1032 CALL pw_transfer(rho_r, rho_g)
1033
1034 CALL timestop(handle)
1035
1036 END SUBROUTINE prepare_gpw
1037
1038! **************************************************************************************************
1039!> \brief Cleanup GPW integration for RI-MP2/RI-RPA
1040!> \param qs_env ...
1041!> \param e_cutoff_old ...
1042!> \param cutoff_old ...
1043!> \param relative_cutoff_old ...
1044!> \param para_env_sub ...
1045!> \param pw_env_sub ...
1046!> \param task_list_sub ...
1047!> \param auxbas_pw_pool ...
1048!> \param rho_r ...
1049!> \param rho_g ...
1050!> \param pot_g ...
1051!> \param psi_L ...
1052! **************************************************************************************************
1053 SUBROUTINE cleanup_gpw(qs_env, e_cutoff_old, cutoff_old, relative_cutoff_old, para_env_sub, pw_env_sub, &
1054 task_list_sub, auxbas_pw_pool, rho_r, rho_g, pot_g, psi_L)
1055 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
1056 REAL(kind=dp), ALLOCATABLE, DIMENSION(:), &
1057 INTENT(IN) :: e_cutoff_old
1058 REAL(kind=dp), INTENT(IN) :: cutoff_old, relative_cutoff_old
1059 TYPE(mp_para_env_type), INTENT(IN) :: para_env_sub
1060 TYPE(pw_env_type), POINTER :: pw_env_sub
1061 TYPE(task_list_type), POINTER :: task_list_sub
1062 TYPE(pw_pool_type), INTENT(IN), POINTER :: auxbas_pw_pool
1063 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: rho_r
1064 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_g, pot_g
1065 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: psi_l
1066
1067 CHARACTER(LEN=*), PARAMETER :: routinen = 'cleanup_gpw'
1068
1069 INTEGER :: handle
1070 TYPE(dft_control_type), POINTER :: dft_control
1071
1072 CALL timeset(routinen, handle)
1073
1074 ! and now free the whole lot
1075 CALL auxbas_pw_pool%give_back_pw(rho_r)
1076 CALL auxbas_pw_pool%give_back_pw(rho_g)
1077 CALL auxbas_pw_pool%give_back_pw(pot_g)
1078 CALL auxbas_pw_pool%give_back_pw(psi_l)
1079
1080 CALL deallocate_task_list(task_list_sub)
1081 CALL pw_env_release(pw_env_sub, para_env=para_env_sub)
1082
1083 CALL get_qs_env(qs_env, dft_control=dft_control)
1084
1085 ! restore the initial value of the cutoff
1086 dft_control%qs_control%e_cutoff = e_cutoff_old
1087 dft_control%qs_control%cutoff = cutoff_old
1088 dft_control%qs_control%relative_cutoff = relative_cutoff_old
1089
1090 CALL timestop(handle)
1091
1092 END SUBROUTINE cleanup_gpw
1093
1094! **************************************************************************************************
1095!> \brief Calculates potential from a given density in g-space
1096!> \param pot_r on output: potential in r space
1097!> \param rho_g on input: rho in g space
1098!> \param poisson_env ...
1099!> \param pot_g on output: potential in g space
1100!> \param potential_parameter Potential parameters, if not provided, assume Coulomb potential
1101!> \param dvg in output: first derivatives of the corresponding Coulomb potential
1102!> \param no_transfer whether NOT to transform potential from g-space to r-space (default: do it)
1103! **************************************************************************************************
1104 SUBROUTINE calc_potential_gpw(pot_r, rho_g, poisson_env, pot_g, potential_parameter, dvg, no_transfer)
1105 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: pot_r
1106 TYPE(pw_c1d_gs_type), INTENT(IN) :: rho_g
1107 TYPE(pw_poisson_type), INTENT(IN), POINTER :: poisson_env
1108 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: pot_g
1109 TYPE(libint_potential_type), INTENT(IN), OPTIONAL :: potential_parameter
1110 TYPE(pw_c1d_gs_type), DIMENSION(3), &
1111 INTENT(INOUT), OPTIONAL :: dvg
1112 LOGICAL, INTENT(IN), OPTIONAL :: no_transfer
1113
1114 CHARACTER(LEN=*), PARAMETER :: routinen = 'calc_potential_gpw'
1115
1116 INTEGER :: comp(3), handle, idir, my_potential_type
1117 LOGICAL :: my_transfer
1118
1119 CALL timeset(routinen, handle)
1120
1121 my_potential_type = do_potential_coulomb
1122 IF (PRESENT(potential_parameter)) THEN
1123 my_potential_type = potential_parameter%potential_type
1124 END IF
1125
1126 my_transfer = .true.
1127 IF (PRESENT(no_transfer)) my_transfer = .NOT. no_transfer
1128
1129 ! in case we do Coulomb metric for RI, we need the Coulomb operator, but for RI with the
1130 ! overlap metric, we do not need the Coulomb operator
1131 IF (my_potential_type /= do_potential_id) THEN
1132 IF (PRESENT(dvg)) THEN
1133 CALL pw_poisson_solve(poisson_env, rho_g, vhartree=pot_g, dvhartree=dvg)
1134 ELSE
1135 CALL pw_poisson_solve(poisson_env, rho_g, vhartree=pot_g)
1136 END IF
1137 IF (my_potential_type == do_potential_long) CALL pw_gauss_damp(pot_g, potential_parameter%omega)
1138 IF (my_potential_type == do_potential_short) CALL pw_compl_gauss_damp(pot_g, potential_parameter%omega)
1139 IF (my_potential_type == do_potential_truncated) CALL pw_truncated(pot_g, potential_parameter%cutoff_radius)
1140 IF (my_potential_type == do_potential_mix_cl) CALL pw_gauss_damp_mix(pot_g, potential_parameter%omega, &
1141 potential_parameter%scale_coulomb, &
1142 potential_parameter%scale_longrange)
1143 IF (my_transfer) CALL pw_transfer(pot_g, pot_r)
1144 ELSE
1145 ! If we use an overlap metric, make sure to use the correct potential=density on output
1146 CALL pw_copy(rho_g, pot_g)
1147 IF (PRESENT(dvg)) THEN
1148 DO idir = 1, 3
1149 CALL pw_copy(pot_g, dvg(idir))
1150 comp = 0
1151 comp(idir) = 1
1152 CALL pw_derive(dvg(idir), comp)
1153 END DO
1154 END IF
1155 IF (my_transfer) CALL pw_transfer(rho_g, pot_r)
1156 END IF
1157
1158 IF (my_transfer) CALL pw_scale(pot_r, pot_r%pw_grid%dvol)
1159 CALL timestop(handle)
1160
1161 END SUBROUTINE calc_potential_gpw
1162
1163END MODULE mp2_eri_gpw
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
All kind of helpful little routines.
Definition ao_util.F:14
real(kind=dp) function, public exp_radius_very_extended(la_min, la_max, lb_min, lb_max, pab, o1, o2, ra, rb, rp, zetp, eps, prefactor, cutoff, epsabs)
computes the radius of the Gaussian outside of which it is smaller than eps
Definition ao_util.F:209
Define the atomic kind types and their sub types.
Handles all functions related to the CELL.
Definition cell_types.F:15
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_set(matrix, alpha)
...
integer function, public gaussian_gridlevel(gridlevel_info, exponent)
...
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_potential_mix_cl
integer, parameter, public do_potential_truncated
integer, parameter, public do_potential_id
integer, parameter, public do_potential_coulomb
integer, parameter, public do_potential_short
integer, parameter, public do_potential_long
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
2- and 3-center electron repulsion integral routines based on libint2 Currently available operators: ...
Definition of mathematical constants and functions.
real(kind=dp), parameter, public fourpi
Interface to the message passing library MPI.
Routines to calculate 2c- and 3c-integrals for RI with GPW.
Definition mp2_eri_gpw.F:13
subroutine, public integrate_potential_forces_3c_2c(matrix_p_munu, rho_r, rho_g, task_list_sub, pw_env_sub, potential_parameter, ks_env, poisson_env, pot_g, use_virial, rho_g_copy, dvg, h_stress, para_env_sub, kind_of, atom_of_kind, qs_kind_set, particle_set, cell, lll, force, dft_control)
Integrates potential of two Gaussians to a potential.
subroutine, public mp2_eri_2c_integrate_gpw(qs_env, para_env_sub, my_group_l_start, my_group_l_end, natom, potential_parameter, sab_orb_sub, l_local_col, kind_of)
Integrates the potential of an RI function.
subroutine, public prepare_gpw(qs_env, dft_control, e_cutoff_old, cutoff_old, relative_cutoff_old, para_env_sub, pw_env_sub, auxbas_pw_pool, poisson_env, task_list_sub, rho_r, rho_g, pot_g, psi_l, sab_orb_sub)
Prepares GPW calculation for RI-MP2/RI-RPA.
subroutine, public integrate_potential_forces_2c(rho_r, lll, rho_g, atomic_kind_set, qs_kind_set, particle_set, cell, pw_env_sub, poisson_env, pot_g, potential_parameter, use_virial, rho_g_copy, dvg, kind_of, atom_of_kind, g_pq_local, force, h_stress, para_env_sub, dft_control, psi_l, factor)
Integrates the potential of a RI function obtaining the forces and stress tensor.
subroutine, public virial_gpw_potential(rho_g_copy, pot_g, rho_g, dvg, h_stress, potential_parameter, para_env_sub)
Calculates stress tensor contribution from the operator.
subroutine, public mp2_eri_3c_integrate_gpw(psi_l, rho_g, atomic_kind_set, qs_kind_set, cell, dft_control, particle_set, pw_env_sub, external_vector, poisson_env, rho_r, pot_g, potential_parameter, mat_munu, qs_env, task_list_sub)
...
subroutine, public calc_potential_gpw(pot_r, rho_g, poisson_env, pot_g, potential_parameter, dvg, no_transfer)
Calculates potential from a given density in g-space.
subroutine, public integrate_potential_forces_3c_1c(mat_munu, rho_r, matrix_p_munu, qs_env, pw_env_sub, task_list_sub)
Takes the precomputed potential of an RI wave-function and determines matrix element and gradients wi...
subroutine, public cleanup_gpw(qs_env, e_cutoff_old, cutoff_old, relative_cutoff_old, para_env_sub, pw_env_sub, task_list_sub, auxbas_pw_pool, rho_r, rho_g, pot_g, psi_l)
Cleanup GPW integration for RI-MP2/RI-RPA.
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public ncoset
Define the data structure for the particle information.
methods of pw_env that have dependence on qs_env
subroutine, public pw_env_rebuild(pw_env, qs_env, external_para_env)
rebuilds the pw_env data (necessary if cell or cutoffs change)
subroutine, public pw_env_create(pw_env)
creates a pw_env, if qs_env is given calls pw_env_rebuild
container for various plainwaves related things
subroutine, public pw_env_release(pw_env, para_env)
releases the given pw_env (see doc/ReferenceCounting.html)
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
subroutine, public pw_log_deriv_trunc(pw, rcutoff)
Multiply all data points with the logarithmic derivative of the complementary cosine This function is...
subroutine, public pw_gauss_damp(pw, omega)
Multiply all data points with a Gaussian damping factor Needed for longrange Coulomb potential V(\vec...
subroutine, public pw_log_deriv_compl_gauss(pw, omega)
Multiply all data points with the logarithmic derivative of the complementary Gaussian damping factor...
subroutine, public pw_log_deriv_gauss(pw, omega)
Multiply all data points with the logarithmic derivative of a Gaussian.
subroutine, public pw_gauss_damp_mix(pw, omega, scale_coul, scale_long)
Multiply all data points with a Gaussian damping factor and mixes it with the original function Neede...
subroutine, public pw_truncated(pw, rcutoff)
Multiply all data points with a complementary cosine Needed for truncated Coulomb potential V(\vec r)...
subroutine, public pw_derive(pw, n)
Calculate the derivative of a plane wave vector.
subroutine, public pw_compl_gauss_damp(pw, omega)
Multiply all data points with a Gaussian damping factor Needed for longrange Coulomb potential V(\vec...
subroutine, public pw_log_deriv_mix_cl(pw, omega, scale_coul, scale_long)
Multiply all data points with the logarithmic derivative of the mixed longrange/Coulomb potential Nee...
functions related to the poisson solver on regular grids
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Calculate the plane wave density by collocating the primitive Gaussian functions (pgf).
subroutine, public calculate_rho_elec(matrix_p, matrix_p_kp, rho, rho_gspace, total_rho, ks_env, soft_valid, compute_tau, compute_grad, basis_type, der_type, idir, task_list_external, pw_env_external)
computes the density corresponding to a given density matrix on the grid
subroutine, public collocate_function(vector, rho, rho_gspace, atomic_kind_set, qs_kind_set, cell, particle_set, pw_env, eps_rho_rspace, basis_type)
maps a given function on the grid
subroutine, public collocate_single_gaussian(rho, rho_gspace, atomic_kind_set, qs_kind_set, cell, dft_control, particle_set, pw_env, required_function, basis_type)
maps a single gaussian on the grid
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs)
Get the QUICKSTEP environment.
Integrate single or product functions over a potential on a RS grid.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
subroutine, public get_qs_kind_set(qs_kind_set, all_potential_present, tnadd_potential_present, gth_potential_present, sgp_potential_present, paw_atom_present, dft_plus_u_atom_present, maxcgf, maxsgf, maxco, maxco_proj, maxgtops, maxlgto, maxlprj, maxnset, maxsgf_set, ncgf, npgf, nset, nsgf, nshell, maxpol, maxlppl, maxlppnl, maxppnl, nelectron, maxder, max_ngrid_rad, max_sph_harm, maxg_iso_not0, lmax_rho0, basis_rcut, basis_type, total_zeff_corr, npgf_seg)
Get attributes of an atomic kind set.
Define the neighbor list data types and the corresponding functionality.
pure logical function, public map_gaussian_here(rs_grid, h_inv, ra, offset, group_size, my_pos)
...
Transfers densities from PW to RS grids and potentials from PW to RS.
subroutine, public potential_pw2rs(rs_v, v_rspace, pw_env)
transfers a potential from a pw_grid to a vector of realspace multigrids
generate the tasks lists used by collocate and integrate routines
subroutine, public generate_qs_task_list(ks_env, task_list, reorder_rs_grid_ranks, skip_load_balance_distributed, soft_valid, basis_type, pw_env_external, sab_orb_external)
...
types for task lists
subroutine, public deallocate_task_list(task_list)
deallocates the components and the object itself
subroutine, public allocate_task_list(task_list)
allocates and initialised the components of the task_list_type
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
stores all the informations relevant to an mpi environment
contained for different pw related things
environment for the poisson solver
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Provides all information about a quickstep kind.
calculation environment to calculate the ks matrix, holds all the needed vars. assumes that the core ...