Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Build up the plane wave density by collocating the primitive Gaussian
10 : !> functions (pgf).
11 : !> \par History
12 : !> Joost VandeVondele (02.2002)
13 : !> 1) rewrote collocate_pgf for increased accuracy and speed
14 : !> 2) collocate_core hack for PGI compiler
15 : !> 3) added multiple grid feature
16 : !> 4) new way to go over the grid
17 : !> Joost VandeVondele (05.2002)
18 : !> 1) prelim. introduction of the real space grid type
19 : !> JGH [30.08.02] multigrid arrays independent from potential
20 : !> JGH [17.07.03] distributed real space code
21 : !> JGH [23.11.03] refactoring and new loop ordering
22 : !> JGH [04.12.03] OpneMP parallelization of main loops
23 : !> Joost VandeVondele (12.2003)
24 : !> 1) modified to compute tau
25 : !> Joost removed incremental build feature
26 : !> Joost introduced map consistent
27 : !> Rewrote grid integration/collocation routines, [Joost VandeVondele,03.2007]
28 : !> \author Matthias Krack (03.04.2001)
29 : ! **************************************************************************************************
30 : MODULE qs_integrate_potential_single
31 : USE ao_util, ONLY: exp_radius_very_extended
32 : USE atomic_kind_types, ONLY: atomic_kind_type,&
33 : get_atomic_kind,&
34 : get_atomic_kind_set
35 : USE atprop_types, ONLY: atprop_array_init,&
36 : atprop_type
37 : USE basis_set_types, ONLY: get_gto_basis_set,&
38 : gto_basis_set_type
39 : USE cell_types, ONLY: cell_type,&
40 : pbc
41 : USE cp_control_types, ONLY: dft_control_type
42 : USE cp_dbcsr_api, ONLY: dbcsr_get_block_p,&
43 : dbcsr_type
44 : USE cp_log_handling, ONLY: cp_get_default_logger,&
45 : cp_logger_get_default_unit_nr,&
46 : cp_logger_type
47 : USE external_potential_types, ONLY: get_potential,&
48 : gth_potential_type
49 : USE gaussian_gridlevels, ONLY: gaussian_gridlevel,&
50 : gridlevel_info_type
51 : USE grid_api, ONLY: integrate_pgf_product
52 : USE kinds, ONLY: dp
53 : USE lri_environment_types, ONLY: lri_kind_type
54 : USE mathlib, ONLY: det_3x3
55 : USE memory_utilities, ONLY: reallocate
56 : USE message_passing, ONLY: mp_para_env_type
57 : USE orbital_pointers, ONLY: coset,&
58 : ncoset
59 : USE particle_types, ONLY: particle_type
60 : USE physcon, ONLY: pascal
61 : USE pw_env_types, ONLY: pw_env_get,&
62 : pw_env_type
63 : USE pw_types, ONLY: pw_r3d_rs_type
64 : USE qs_environment_types, ONLY: get_qs_env,&
65 : qs_environment_type
66 : USE qs_force_types, ONLY: qs_force_type
67 : USE qs_kind_types, ONLY: get_qs_kind,&
68 : get_qs_kind_set,&
69 : qs_kind_type
70 : USE qs_nlcc_methods, ONLY: get_nlcc_gaussians
71 : USE realspace_grid_types, ONLY: map_gaussian_here,&
72 : realspace_grid_type,&
73 : rs_grid_zero,&
74 : transfer_pw2rs
75 : USE rs_pw_interface, ONLY: potential_pw2rs
76 : USE virial_methods, ONLY: one_third_sum_diag
77 : USE virial_types, ONLY: virial_type
78 : #include "./base/base_uses.f90"
79 :
80 : IMPLICIT NONE
81 :
82 : PRIVATE
83 :
84 : LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .FALSE.
85 :
86 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_integrate_potential_single'
87 :
88 : ! *** Public subroutines ***
89 : ! *** Don't include this routines directly, use the interface to
90 : ! *** qs_integrate_potential
91 :
92 : PUBLIC :: integrate_v_rspace_one_center, &
93 : integrate_v_rspace_diagonal, &
94 : integrate_v_core_rspace, &
95 : integrate_v_gaussian_rspace, &
96 : integrate_function, &
97 : integrate_ppl_rspace, &
98 : integrate_rho_nlcc
99 :
100 : CONTAINS
101 :
102 : ! **************************************************************************************************
103 : !> \brief computes the forces/virial due to the local pseudopotential
104 : !> \param rho_rspace ...
105 : !> \param qs_env ...
106 : ! **************************************************************************************************
107 14 : SUBROUTINE integrate_ppl_rspace(rho_rspace, qs_env)
108 : TYPE(pw_r3d_rs_type), INTENT(IN) :: rho_rspace
109 : TYPE(qs_environment_type), POINTER :: qs_env
110 :
111 : CHARACTER(len=*), PARAMETER :: routineN = 'integrate_ppl_rspace'
112 :
113 : INTEGER :: atom_a, handle, iatom, ikind, j, lppl, &
114 : n, natom_of_kind, ni, npme
115 14 : INTEGER, DIMENSION(:), POINTER :: atom_list, cores
116 : LOGICAL :: use_virial
117 : REAL(KIND=dp) :: alpha, eps_rho_rspace, radius
118 : REAL(KIND=dp), DIMENSION(3) :: force_a, force_b, ra
119 : REAL(KIND=dp), DIMENSION(3, 3) :: my_virial_a, my_virial_b
120 14 : REAL(KIND=dp), DIMENSION(:), POINTER :: cexp_ppl
121 14 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: hab, pab
122 14 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
123 : TYPE(cell_type), POINTER :: cell
124 : TYPE(dft_control_type), POINTER :: dft_control
125 : TYPE(gth_potential_type), POINTER :: gth_potential
126 14 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
127 : TYPE(pw_env_type), POINTER :: pw_env
128 14 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
129 14 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
130 : TYPE(realspace_grid_type), POINTER :: rs_v
131 : TYPE(virial_type), POINTER :: virial
132 :
133 14 : CALL timeset(routineN, handle)
134 :
135 14 : NULLIFY (pw_env, cores)
136 :
137 14 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
138 14 : CALL pw_env_get(pw_env=pw_env, auxbas_rs_grid=rs_v)
139 :
140 14 : CALL transfer_pw2rs(rs_v, rho_rspace)
141 :
142 : CALL get_qs_env(qs_env=qs_env, &
143 : atomic_kind_set=atomic_kind_set, &
144 : qs_kind_set=qs_kind_set, &
145 : cell=cell, &
146 : dft_control=dft_control, &
147 : particle_set=particle_set, &
148 : pw_env=pw_env, &
149 14 : force=force, virial=virial)
150 :
151 14 : use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
152 :
153 14 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
154 :
155 34 : DO ikind = 1, SIZE(atomic_kind_set)
156 :
157 20 : CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom_of_kind, atom_list=atom_list)
158 20 : CALL get_qs_kind(qs_kind_set(ikind), gth_potential=gth_potential)
159 :
160 20 : IF (.NOT. ASSOCIATED(gth_potential)) CYCLE
161 20 : CALL get_potential(potential=gth_potential, alpha_ppl=alpha, nexp_ppl=lppl, cexp_ppl=cexp_ppl)
162 :
163 20 : IF (lppl <= 0) CYCLE
164 :
165 20 : ni = ncoset(2*lppl - 2)
166 80 : ALLOCATE (hab(ni, 1), pab(ni, 1))
167 240 : pab = 0._dp
168 :
169 20 : CALL reallocate(cores, 1, natom_of_kind)
170 20 : npme = 0
171 70 : cores = 0
172 :
173 : ! prepare core function
174 60 : DO j = 1, lppl
175 20 : SELECT CASE (j)
176 : CASE (1)
177 20 : pab(1, 1) = cexp_ppl(1)
178 : CASE (2)
179 20 : n = coset(2, 0, 0)
180 20 : pab(n, 1) = cexp_ppl(2)
181 20 : n = coset(0, 2, 0)
182 20 : pab(n, 1) = cexp_ppl(2)
183 20 : n = coset(0, 0, 2)
184 20 : pab(n, 1) = cexp_ppl(2)
185 : CASE (3)
186 0 : n = coset(4, 0, 0)
187 0 : pab(n, 1) = cexp_ppl(3)
188 0 : n = coset(0, 4, 0)
189 0 : pab(n, 1) = cexp_ppl(3)
190 0 : n = coset(0, 0, 4)
191 0 : pab(n, 1) = cexp_ppl(3)
192 0 : n = coset(2, 2, 0)
193 0 : pab(n, 1) = 2._dp*cexp_ppl(3)
194 0 : n = coset(2, 0, 2)
195 0 : pab(n, 1) = 2._dp*cexp_ppl(3)
196 0 : n = coset(0, 2, 2)
197 0 : pab(n, 1) = 2._dp*cexp_ppl(3)
198 : CASE (4)
199 0 : n = coset(6, 0, 0)
200 0 : pab(n, 1) = cexp_ppl(4)
201 0 : n = coset(0, 6, 0)
202 0 : pab(n, 1) = cexp_ppl(4)
203 0 : n = coset(0, 0, 6)
204 0 : pab(n, 1) = cexp_ppl(4)
205 0 : n = coset(4, 2, 0)
206 0 : pab(n, 1) = 3._dp*cexp_ppl(4)
207 0 : n = coset(4, 0, 2)
208 0 : pab(n, 1) = 3._dp*cexp_ppl(4)
209 0 : n = coset(2, 4, 0)
210 0 : pab(n, 1) = 3._dp*cexp_ppl(4)
211 0 : n = coset(2, 0, 4)
212 0 : pab(n, 1) = 3._dp*cexp_ppl(4)
213 0 : n = coset(0, 4, 2)
214 0 : pab(n, 1) = 3._dp*cexp_ppl(4)
215 0 : n = coset(0, 2, 4)
216 0 : pab(n, 1) = 3._dp*cexp_ppl(4)
217 0 : n = coset(2, 2, 2)
218 0 : pab(n, 1) = 6._dp*cexp_ppl(4)
219 : CASE DEFAULT
220 : CALL cp_abort(__LOCATION__, &
221 : "Only 1, 2, 3, 4 are supported as the "// &
222 40 : "value of j in integrate_ppl_rspace")
223 : END SELECT
224 : END DO
225 :
226 70 : DO iatom = 1, natom_of_kind
227 50 : atom_a = atom_list(iatom)
228 50 : ra(:) = pbc(particle_set(atom_a)%r, cell)
229 70 : IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed) THEN
230 : ! replicated realspace grid, split the atoms up between procs
231 50 : IF (MODULO(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos) THEN
232 25 : npme = npme + 1
233 25 : cores(npme) = iatom
234 : END IF
235 : ELSE
236 0 : npme = npme + 1
237 0 : cores(npme) = iatom
238 : END IF
239 : END DO
240 :
241 45 : DO j = 1, npme
242 :
243 25 : iatom = cores(j)
244 25 : atom_a = atom_list(iatom)
245 25 : ra(:) = pbc(particle_set(atom_a)%r, cell)
246 275 : hab(:, 1) = 0.0_dp
247 25 : force_a(:) = 0.0_dp
248 25 : force_b(:) = 0.0_dp
249 25 : IF (use_virial) THEN
250 0 : my_virial_a = 0.0_dp
251 0 : my_virial_b = 0.0_dp
252 : END IF
253 25 : ni = 2*lppl - 2
254 :
255 : radius = exp_radius_very_extended(la_min=0, la_max=ni, lb_min=0, lb_max=0, &
256 : ra=ra, rb=ra, rp=ra, &
257 : zetp=alpha, eps=eps_rho_rspace, &
258 : pab=pab, o1=0, o2=0, & ! without map_consistent
259 25 : prefactor=1.0_dp, cutoff=1.0_dp)
260 :
261 : CALL integrate_pgf_product(ni, alpha, 0, &
262 : 0, 0.0_dp, 0, ra, [0.0_dp, 0.0_dp, 0.0_dp], &
263 : rs_v, hab, pab=pab, o1=0, o2=0, &
264 : radius=radius, &
265 : calculate_forces=.TRUE., force_a=force_a, &
266 : force_b=force_b, use_virial=use_virial, my_virial_a=my_virial_a, &
267 25 : my_virial_b=my_virial_b, use_subpatch=.TRUE., subpatch_pattern=0)
268 :
269 : force(ikind)%gth_ppl(:, iatom) = &
270 100 : force(ikind)%gth_ppl(:, iatom) + force_a(:)*rho_rspace%pw_grid%dvol
271 :
272 45 : IF (use_virial) THEN
273 0 : virial%pv_ppl = virial%pv_ppl + my_virial_a*rho_rspace%pw_grid%dvol
274 0 : virial%pv_virial = virial%pv_virial + my_virial_a*rho_rspace%pw_grid%dvol
275 0 : CPABORT("Virial not debuged for CORE_PPL")
276 : END IF
277 : END DO
278 :
279 74 : DEALLOCATE (hab, pab)
280 :
281 : END DO
282 :
283 14 : DEALLOCATE (cores)
284 :
285 14 : CALL timestop(handle)
286 :
287 14 : END SUBROUTINE integrate_ppl_rspace
288 :
289 : ! **************************************************************************************************
290 : !> \brief computes the forces/virial due to the nlcc pseudopotential
291 : !> \param rho_rspace ...
292 : !> \param qs_env ...
293 : !> \param debug_forces ...
294 : !> \param debug_stress ...
295 : !> \param iotag ...
296 : ! **************************************************************************************************
297 66 : SUBROUTINE integrate_rho_nlcc(rho_rspace, qs_env, debug_forces, debug_stress, iotag)
298 : TYPE(pw_r3d_rs_type), INTENT(IN) :: rho_rspace
299 : TYPE(qs_environment_type), POINTER :: qs_env
300 : LOGICAL, INTENT(IN), OPTIONAL :: debug_forces, debug_stress
301 : CHARACTER(len=*), OPTIONAL :: iotag
302 :
303 : CHARACTER(len=*), PARAMETER :: routineN = 'integrate_rho_nlcc'
304 :
305 : CHARACTER(len=30) :: ftag, stag
306 : INTEGER :: atom_a, handle, iatom, iexp_nlcc, ikind, &
307 : iounit, j, n, natom, nc, nexp_nlcc, &
308 : ni, npme
309 66 : INTEGER, ALLOCATABLE, DIMENSION(:) :: nct_nlcc
310 66 : INTEGER, DIMENSION(:), POINTER :: atom_list, cores
311 : LOGICAL :: debfor, debstr, use_virial
312 : REAL(KIND=dp) :: alpha, eps_rho_rspace, fconv, radius
313 66 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: alpha_nlcc
314 66 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: cval_nlcc
315 : REAL(KIND=dp), DIMENSION(3) :: fodeb, force_a, force_b, ra
316 : REAL(KIND=dp), DIMENSION(3, 3) :: my_virial_a, my_virial_b, stdeb
317 66 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: hab, pab
318 66 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
319 : TYPE(cell_type), POINTER :: cell
320 : TYPE(cp_logger_type), POINTER :: logger
321 : TYPE(dft_control_type), POINTER :: dft_control
322 : TYPE(mp_para_env_type), POINTER :: para_env
323 66 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
324 : TYPE(pw_env_type), POINTER :: pw_env
325 66 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
326 66 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
327 : TYPE(realspace_grid_type), POINTER :: rs_v
328 : TYPE(virial_type), POINTER :: virial
329 :
330 66 : CALL timeset(routineN, handle)
331 :
332 66 : logger => cp_get_default_logger()
333 66 : IF (logger%para_env%is_source()) THEN
334 33 : iounit = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
335 : ELSE
336 : iounit = -1
337 : END IF
338 :
339 66 : NULLIFY (pw_env, cores)
340 :
341 66 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
342 66 : CALL pw_env_get(pw_env=pw_env, auxbas_rs_grid=rs_v)
343 :
344 66 : CALL transfer_pw2rs(rs_v, rho_rspace)
345 :
346 : CALL get_qs_env(qs_env=qs_env, &
347 : atomic_kind_set=atomic_kind_set, &
348 : qs_kind_set=qs_kind_set, &
349 : cell=cell, &
350 : dft_control=dft_control, &
351 : particle_set=particle_set, &
352 : pw_env=pw_env, &
353 : para_env=para_env, &
354 66 : force=force, virial=virial)
355 :
356 66 : use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
357 : !debug
358 66 : debfor = .FALSE.
359 66 : IF (PRESENT(debug_forces)) debfor = debug_forces
360 66 : debstr = .FALSE.
361 66 : IF (PRESENT(debug_stress)) debstr = debug_stress
362 66 : debstr = debstr .AND. use_virial
363 66 : IF (debstr) THEN
364 0 : fconv = 1.0E-9_dp*pascal/cell%deth
365 : END IF
366 66 : IF (PRESENT(iotag)) THEN
367 18 : ftag = "DEBUG :: "//ADJUSTL(iotag)
368 18 : stag = "STRESS| INT "//ADJUSTL(iotag)
369 : ELSE
370 48 : ftag = "DEBUG :: dnlcc*V(r) "
371 48 : stag = "STRESS| INT dnlcc*V(r) "
372 : END IF
373 :
374 90 : IF (debfor) fodeb(1:3) = force(1)%gth_nlcc(1:3, 1)
375 66 : IF (debstr) stdeb = virial%pv_nlcc
376 :
377 66 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
378 :
379 188 : DO ikind = 1, SIZE(atomic_kind_set)
380 :
381 122 : CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
382 122 : CALL get_nlcc_gaussians(qs_kind_set(ikind), alpha_nlcc, nct_nlcc, cval_nlcc)
383 122 : nexp_nlcc = SIZE(alpha_nlcc)
384 :
385 676 : DO iexp_nlcc = 1, nexp_nlcc
386 :
387 366 : alpha = alpha_nlcc(iexp_nlcc)
388 366 : nc = nct_nlcc(iexp_nlcc)
389 :
390 366 : ni = ncoset(2*nc - 2)
391 :
392 1464 : ALLOCATE (hab(ni, 1), pab(ni, 1))
393 1242 : pab = 0._dp
394 :
395 366 : CALL reallocate(cores, 1, natom)
396 366 : npme = 0
397 820 : cores = 0
398 :
399 : ! prepare core function
400 748 : DO j = 1, nc
401 366 : SELECT CASE (j)
402 : CASE (1)
403 366 : pab(1, 1) = cval_nlcc(1, iexp_nlcc)
404 : CASE (2)
405 16 : n = coset(2, 0, 0)
406 16 : pab(n, 1) = cval_nlcc(2, iexp_nlcc)/alpha**2
407 16 : n = coset(0, 2, 0)
408 16 : pab(n, 1) = cval_nlcc(2, iexp_nlcc)/alpha**2
409 16 : n = coset(0, 0, 2)
410 16 : pab(n, 1) = cval_nlcc(2, iexp_nlcc)/alpha**2
411 : CASE (3)
412 0 : n = coset(4, 0, 0)
413 0 : pab(n, 1) = cval_nlcc(3, iexp_nlcc)/alpha**4
414 0 : n = coset(0, 4, 0)
415 0 : pab(n, 1) = cval_nlcc(3, iexp_nlcc)/alpha**4
416 0 : n = coset(0, 0, 4)
417 0 : pab(n, 1) = cval_nlcc(3, iexp_nlcc)/alpha**4
418 0 : n = coset(2, 2, 0)
419 0 : pab(n, 1) = 2._dp*cval_nlcc(3, iexp_nlcc)/alpha**4
420 0 : n = coset(2, 0, 2)
421 0 : pab(n, 1) = 2._dp*cval_nlcc(3, iexp_nlcc)/alpha**4
422 0 : n = coset(0, 2, 2)
423 0 : pab(n, 1) = 2._dp*cval_nlcc(3, iexp_nlcc)/alpha**4
424 : CASE (4)
425 0 : n = coset(6, 0, 0)
426 0 : pab(n, 1) = cval_nlcc(4, iexp_nlcc)/alpha**6
427 0 : n = coset(0, 6, 0)
428 0 : pab(n, 1) = cval_nlcc(4, iexp_nlcc)/alpha**6
429 0 : n = coset(0, 0, 6)
430 0 : pab(n, 1) = cval_nlcc(4, iexp_nlcc)/alpha**6
431 0 : n = coset(4, 2, 0)
432 0 : pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
433 0 : n = coset(4, 0, 2)
434 0 : pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
435 0 : n = coset(2, 4, 0)
436 0 : pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
437 0 : n = coset(2, 0, 4)
438 0 : pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
439 0 : n = coset(0, 4, 2)
440 0 : pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
441 0 : n = coset(0, 2, 4)
442 0 : pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
443 0 : n = coset(2, 2, 2)
444 0 : pab(n, 1) = 6._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
445 : CASE DEFAULT
446 : CALL cp_abort(__LOCATION__, &
447 : "Only 1, 2, 3, 4 are supported as the "// &
448 382 : "value of j in integrate_rho_nlcc")
449 : END SELECT
450 : END DO
451 366 : IF (dft_control%nspins == 2) pab = pab*0.5_dp
452 :
453 820 : DO iatom = 1, natom
454 454 : atom_a = atom_list(iatom)
455 454 : ra(:) = pbc(particle_set(atom_a)%r, cell)
456 820 : IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed) THEN
457 : ! replicated realspace grid, split the atoms up between procs
458 454 : IF (MODULO(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos) THEN
459 227 : npme = npme + 1
460 227 : cores(npme) = iatom
461 : END IF
462 : ELSE
463 0 : npme = npme + 1
464 0 : cores(npme) = iatom
465 : END IF
466 : END DO
467 :
468 593 : DO j = 1, npme
469 :
470 227 : iatom = cores(j)
471 227 : atom_a = atom_list(iatom)
472 227 : ra(:) = pbc(particle_set(atom_a)%r, cell)
473 598 : hab(:, 1) = 0.0_dp
474 227 : force_a(:) = 0.0_dp
475 227 : force_b(:) = 0.0_dp
476 227 : IF (use_virial) THEN
477 48 : my_virial_a = 0.0_dp
478 48 : my_virial_b = 0.0_dp
479 : END IF
480 227 : ni = 2*nc - 2
481 :
482 : radius = exp_radius_very_extended(la_min=0, la_max=ni, lb_min=0, lb_max=0, &
483 : ra=ra, rb=ra, rp=ra, &
484 : zetp=1/(2*alpha**2), eps=eps_rho_rspace, &
485 : pab=pab, o1=0, o2=0, & ! without map_consistent
486 227 : prefactor=1.0_dp, cutoff=1.0_dp)
487 :
488 : CALL integrate_pgf_product(ni, 1/(2*alpha**2), 0, &
489 : 0, 0.0_dp, 0, ra, [0.0_dp, 0.0_dp, 0.0_dp], &
490 : rs_v, hab, pab=pab, o1=0, o2=0, &
491 : radius=radius, &
492 : calculate_forces=.TRUE., force_a=force_a, &
493 : force_b=force_b, use_virial=use_virial, my_virial_a=my_virial_a, &
494 227 : my_virial_b=my_virial_b, use_subpatch=.TRUE., subpatch_pattern=0)
495 :
496 : force(ikind)%gth_nlcc(:, iatom) = &
497 908 : force(ikind)%gth_nlcc(:, iatom) + force_a(:)*rho_rspace%pw_grid%dvol
498 :
499 593 : IF (use_virial) THEN
500 624 : virial%pv_nlcc = virial%pv_nlcc + my_virial_a*rho_rspace%pw_grid%dvol
501 624 : virial%pv_virial = virial%pv_virial + my_virial_a*rho_rspace%pw_grid%dvol
502 : END IF
503 : END DO
504 :
505 488 : DEALLOCATE (hab, pab)
506 :
507 : END DO
508 :
509 : END DO
510 :
511 66 : IF (ASSOCIATED(cores)) DEALLOCATE (cores)
512 :
513 66 : IF (debfor) THEN
514 32 : fodeb(1:3) = force(1)%gth_nlcc(1:3, 1) - fodeb(1:3)
515 8 : CALL para_env%sum(fodeb)
516 8 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") TRIM(ftag), fodeb
517 : END IF
518 66 : IF (debstr) THEN
519 0 : stdeb = fconv*(virial%pv_nlcc - stdeb)
520 0 : CALL para_env%sum(stdeb)
521 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
522 0 : TRIM(stag), one_third_sum_diag(stdeb), det_3x3(stdeb)
523 : END IF
524 :
525 66 : CALL timestop(handle)
526 :
527 132 : END SUBROUTINE integrate_rho_nlcc
528 :
529 : ! **************************************************************************************************
530 : !> \brief computes the forces/virial due to the ionic cores with a potential on
531 : !> grid
532 : !> \param v_rspace ...
533 : !> \param qs_env ...
534 : !> \param atecc ...
535 : !> \param calpha optional Gaussian exponents per kind replacing the core charge exponents
536 : !> \param ccore optional Gaussian coefficients per kind replacing the core charge coefficients
537 : ! **************************************************************************************************
538 8189 : SUBROUTINE integrate_v_core_rspace(v_rspace, qs_env, atecc, calpha, ccore)
539 : TYPE(pw_r3d_rs_type), INTENT(IN) :: v_rspace
540 : TYPE(qs_environment_type), POINTER :: qs_env
541 : REAL(KIND=dp), DIMENSION(:), OPTIONAL :: atecc, calpha, ccore
542 :
543 : CHARACTER(len=*), PARAMETER :: routineN = 'integrate_v_core_rspace'
544 :
545 : INTEGER :: atom_a, handle, iatom, ikind, j, natom, &
546 : natom_of_kind, npme
547 8189 : INTEGER, DIMENSION(:), POINTER :: atom_list, cores
548 : LOGICAL :: paw_atom, skip_fcore, use_virial
549 : REAL(KIND=dp) :: alpha_core_charge, ccore_charge, &
550 : eps_rho_rspace, radius
551 : REAL(KIND=dp), DIMENSION(3) :: force_a, force_b, ra
552 : REAL(KIND=dp), DIMENSION(3, 3) :: my_virial_a, my_virial_b
553 8189 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: hab, pab
554 8189 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
555 : TYPE(atprop_type), POINTER :: atprop
556 : TYPE(cell_type), POINTER :: cell
557 : TYPE(dft_control_type), POINTER :: dft_control
558 8189 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
559 : TYPE(pw_env_type), POINTER :: pw_env
560 8189 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
561 8189 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
562 : TYPE(realspace_grid_type), POINTER :: rs_v
563 : TYPE(virial_type), POINTER :: virial
564 :
565 8189 : CALL timeset(routineN, handle)
566 8189 : NULLIFY (virial, force, atprop, dft_control)
567 8189 : IF (PRESENT(calpha)) THEN
568 2 : CPASSERT(PRESENT(ccore))
569 : END IF
570 :
571 8189 : CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
572 :
573 : !If gapw, check for gpw kinds. This filtering applies to the core charges only;
574 : !user defined Gaussians (calpha/ccore) are always integrated
575 8189 : skip_fcore = .FALSE.
576 8189 : IF (dft_control%qs_control%gapw .AND. (.NOT. PRESENT(calpha))) THEN
577 880 : IF (.NOT. dft_control%qs_control%gapw_control%nopaw_as_gpw) skip_fcore = .TRUE.
578 : END IF
579 :
580 : IF (.NOT. skip_fcore) THEN
581 7397 : NULLIFY (pw_env)
582 7397 : ALLOCATE (cores(1))
583 7397 : ALLOCATE (hab(1, 1))
584 7397 : ALLOCATE (pab(1, 1))
585 :
586 7397 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
587 7397 : CALL pw_env_get(pw_env=pw_env, auxbas_rs_grid=rs_v)
588 :
589 7397 : CALL transfer_pw2rs(rs_v, v_rspace)
590 :
591 : CALL get_qs_env(qs_env=qs_env, &
592 : atomic_kind_set=atomic_kind_set, &
593 : qs_kind_set=qs_kind_set, &
594 : cell=cell, &
595 : dft_control=dft_control, &
596 : particle_set=particle_set, &
597 : pw_env=pw_env, &
598 : force=force, &
599 : virial=virial, &
600 7397 : atprop=atprop)
601 :
602 : ! atomic energy contributions
603 7397 : natom = SIZE(particle_set)
604 7397 : IF (ASSOCIATED(atprop)) THEN
605 7397 : CALL atprop_array_init(atprop%ateb, natom)
606 : END IF
607 :
608 7397 : use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
609 :
610 7397 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
611 :
612 20291 : DO ikind = 1, SIZE(atomic_kind_set)
613 :
614 12894 : CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom_of_kind, atom_list=atom_list)
615 12894 : CALL get_qs_kind(qs_kind_set(ikind), paw_atom=paw_atom)
616 :
617 12894 : IF (dft_control%qs_control%gapw .AND. paw_atom .AND. (.NOT. PRESENT(calpha))) CYCLE
618 :
619 12808 : IF (PRESENT(calpha)) THEN
620 : ! User defined Gaussians (e.g. the SCCS core fill) instead of the core charges
621 4 : alpha_core_charge = calpha(ikind)
622 4 : ccore_charge = ccore(ikind)
623 : ELSE
624 : CALL get_qs_kind(qs_kind_set(ikind), alpha_core_charge=alpha_core_charge, &
625 12804 : ccore_charge=ccore_charge)
626 : END IF
627 :
628 12808 : pab(1, 1) = -ccore_charge
629 12808 : IF (alpha_core_charge == 0.0_dp .OR. pab(1, 1) == 0.0_dp) CYCLE
630 :
631 12770 : CALL reallocate(cores, 1, natom_of_kind)
632 12770 : npme = 0
633 39149 : cores = 0
634 :
635 39149 : DO iatom = 1, natom_of_kind
636 26379 : atom_a = atom_list(iatom)
637 26379 : ra(:) = pbc(particle_set(atom_a)%r, cell)
638 39149 : IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed) THEN
639 : ! replicated realspace grid, split the atoms up between procs
640 25630 : IF (MODULO(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos) THEN
641 12815 : npme = npme + 1
642 12815 : cores(npme) = iatom
643 : END IF
644 : ELSE
645 749 : npme = npme + 1
646 749 : cores(npme) = iatom
647 : END IF
648 : END DO
649 :
650 46625 : DO j = 1, npme
651 :
652 13564 : iatom = cores(j)
653 13564 : atom_a = atom_list(iatom)
654 13564 : ra(:) = pbc(particle_set(atom_a)%r, cell)
655 13564 : hab(1, 1) = 0.0_dp
656 13564 : force_a(:) = 0.0_dp
657 13564 : force_b(:) = 0.0_dp
658 13564 : IF (use_virial) THEN
659 1749 : my_virial_a = 0.0_dp
660 1749 : my_virial_b = 0.0_dp
661 : END IF
662 :
663 : radius = exp_radius_very_extended(la_min=0, la_max=0, lb_min=0, lb_max=0, &
664 : ra=ra, rb=ra, rp=ra, &
665 : zetp=alpha_core_charge, eps=eps_rho_rspace, &
666 : pab=pab, o1=0, o2=0, & ! without map_consistent
667 13564 : prefactor=1.0_dp, cutoff=1.0_dp)
668 :
669 : CALL integrate_pgf_product(0, alpha_core_charge, 0, &
670 : 0, 0.0_dp, 0, ra, [0.0_dp, 0.0_dp, 0.0_dp], &
671 : rs_v, hab, pab=pab, o1=0, o2=0, &
672 : radius=radius, &
673 : calculate_forces=.TRUE., force_a=force_a, &
674 : force_b=force_b, use_virial=use_virial, my_virial_a=my_virial_a, &
675 13564 : my_virial_b=my_virial_b, use_subpatch=.TRUE., subpatch_pattern=0)
676 :
677 13564 : IF (ASSOCIATED(force)) THEN
678 53868 : force(ikind)%rho_core(:, iatom) = force(ikind)%rho_core(:, iatom) + force_a(:)
679 : END IF
680 13564 : IF (use_virial) THEN
681 22737 : virial%pv_ehartree = virial%pv_ehartree + my_virial_a
682 22737 : virial%pv_virial = virial%pv_virial + my_virial_a
683 : END IF
684 13564 : IF (ASSOCIATED(atprop) .AND. (.NOT. PRESENT(calpha))) THEN
685 13563 : atprop%ateb(atom_a) = atprop%ateb(atom_a) + 0.5_dp*hab(1, 1)*pab(1, 1)
686 : END IF
687 26458 : IF (PRESENT(atecc)) THEN
688 47 : atecc(atom_a) = atecc(atom_a) + 0.5_dp*hab(1, 1)*pab(1, 1)
689 : END IF
690 :
691 : END DO
692 :
693 : END DO
694 :
695 7397 : DEALLOCATE (hab, pab, cores)
696 :
697 : END IF
698 :
699 8189 : CALL timestop(handle)
700 :
701 8189 : END SUBROUTINE integrate_v_core_rspace
702 :
703 : ! **************************************************************************************************
704 : !> \brief computes the overlap of a set of Gaussians with a potential on grid
705 : !> \param v_rspace ...
706 : !> \param qs_env ...
707 : !> \param alpha ...
708 : !> \param ccore ...
709 : !> \param atecc ...
710 : ! **************************************************************************************************
711 2 : SUBROUTINE integrate_v_gaussian_rspace(v_rspace, qs_env, alpha, ccore, atecc)
712 : TYPE(pw_r3d_rs_type), INTENT(IN) :: v_rspace
713 : TYPE(qs_environment_type), POINTER :: qs_env
714 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: alpha, ccore
715 : REAL(KIND=dp), DIMENSION(:) :: atecc
716 :
717 : CHARACTER(len=*), PARAMETER :: routineN = 'integrate_v_gaussian_rspace'
718 :
719 : INTEGER :: atom_a, handle, iatom, ikind, j, natom, &
720 : natom_of_kind, npme
721 2 : INTEGER, DIMENSION(:), POINTER :: atom_list, cores
722 : REAL(KIND=dp) :: alpha_core_charge, eps_rho_rspace, radius
723 : REAL(KIND=dp), DIMENSION(3) :: ra
724 2 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: hab, pab
725 2 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
726 : TYPE(cell_type), POINTER :: cell
727 : TYPE(dft_control_type), POINTER :: dft_control
728 2 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
729 : TYPE(pw_env_type), POINTER :: pw_env
730 2 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
731 : TYPE(realspace_grid_type), POINTER :: rs_v
732 :
733 2 : CALL timeset(routineN, handle)
734 :
735 2 : CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
736 :
737 : !If gapw, check for gpw kinds
738 2 : CPASSERT(.NOT. dft_control%qs_control%gapw)
739 :
740 2 : NULLIFY (pw_env)
741 2 : ALLOCATE (cores(1))
742 2 : ALLOCATE (hab(1, 1))
743 2 : ALLOCATE (pab(1, 1))
744 :
745 2 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
746 2 : CALL pw_env_get(pw_env=pw_env, auxbas_rs_grid=rs_v)
747 :
748 2 : CALL transfer_pw2rs(rs_v, v_rspace)
749 :
750 : CALL get_qs_env(qs_env=qs_env, &
751 : atomic_kind_set=atomic_kind_set, &
752 : qs_kind_set=qs_kind_set, &
753 : cell=cell, &
754 : dft_control=dft_control, &
755 : particle_set=particle_set, &
756 2 : pw_env=pw_env)
757 :
758 : ! atomic energy contributions
759 2 : natom = SIZE(particle_set)
760 2 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
761 :
762 6 : DO ikind = 1, SIZE(atomic_kind_set)
763 :
764 4 : CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom_of_kind, atom_list=atom_list)
765 4 : pab(1, 1) = -ccore(ikind)
766 4 : alpha_core_charge = alpha(ikind)
767 4 : IF (alpha_core_charge == 0.0_dp .OR. pab(1, 1) == 0.0_dp) CYCLE
768 :
769 4 : CALL reallocate(cores, 1, natom_of_kind)
770 4 : npme = 0
771 10 : cores = 0
772 :
773 10 : DO iatom = 1, natom_of_kind
774 6 : atom_a = atom_list(iatom)
775 6 : ra(:) = pbc(particle_set(atom_a)%r, cell)
776 10 : IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed) THEN
777 : ! replicated realspace grid, split the atoms up between procs
778 6 : IF (MODULO(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos) THEN
779 3 : npme = npme + 1
780 3 : cores(npme) = iatom
781 : END IF
782 : ELSE
783 0 : npme = npme + 1
784 0 : cores(npme) = iatom
785 : END IF
786 : END DO
787 :
788 13 : DO j = 1, npme
789 :
790 3 : iatom = cores(j)
791 3 : atom_a = atom_list(iatom)
792 3 : ra(:) = pbc(particle_set(atom_a)%r, cell)
793 3 : hab(1, 1) = 0.0_dp
794 :
795 : radius = exp_radius_very_extended(la_min=0, la_max=0, lb_min=0, lb_max=0, &
796 : ra=ra, rb=ra, rp=ra, &
797 : zetp=alpha_core_charge, eps=eps_rho_rspace, &
798 : pab=pab, o1=0, o2=0, & ! without map_consistent
799 3 : prefactor=1.0_dp, cutoff=1.0_dp)
800 :
801 : CALL integrate_pgf_product(0, alpha_core_charge, 0, &
802 : 0, 0.0_dp, 0, ra, [0.0_dp, 0.0_dp, 0.0_dp], &
803 : rs_v, hab, pab=pab, o1=0, o2=0, &
804 : radius=radius, calculate_forces=.FALSE., &
805 3 : use_subpatch=.TRUE., subpatch_pattern=0)
806 7 : atecc(atom_a) = atecc(atom_a) + 0.5_dp*hab(1, 1)*pab(1, 1)
807 :
808 : END DO
809 :
810 : END DO
811 :
812 2 : DEALLOCATE (hab, pab, cores)
813 :
814 2 : CALL timestop(handle)
815 :
816 2 : END SUBROUTINE integrate_v_gaussian_rspace
817 : ! **************************************************************************************************
818 : !> \brief computes integrals of product of v_rspace times a one-center function
819 : !> required for LRIGPW
820 : !> \param v_rspace ...
821 : !> \param qs_env ...
822 : !> \param int_res ...
823 : !> \param calculate_forces ...
824 : !> \param basis_type ...
825 : !> \param atomlist ...
826 : !> \author Dorothea Golze
827 : ! **************************************************************************************************
828 1030 : SUBROUTINE integrate_v_rspace_one_center(v_rspace, qs_env, int_res, &
829 1030 : calculate_forces, basis_type, atomlist)
830 : TYPE(pw_r3d_rs_type), INTENT(IN) :: v_rspace
831 : TYPE(qs_environment_type), POINTER :: qs_env
832 : TYPE(lri_kind_type), DIMENSION(:), POINTER :: int_res
833 : LOGICAL, INTENT(IN) :: calculate_forces
834 : CHARACTER(len=*), INTENT(IN) :: basis_type
835 : INTEGER, DIMENSION(:), OPTIONAL :: atomlist
836 :
837 : CHARACTER(len=*), PARAMETER :: routineN = 'integrate_v_rspace_one_center'
838 :
839 : INTEGER :: atom_a, group_size, handle, i, iatom, igrid_level, ikind, ipgf, iset, m1, &
840 : max_npgf, maxco, maxsgf_set, my_pos, na1, natom_of_kind, ncoa, nkind, nseta, offset, sgfa
841 1030 : INTEGER, DIMENSION(:), POINTER :: atom_list, la_max, la_min, npgfa, &
842 1030 : nsgf_seta
843 1030 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa
844 : LOGICAL :: use_virial
845 1030 : LOGICAL, ALLOCATABLE, DIMENSION(:) :: map_it
846 : REAL(KIND=dp) :: eps_rho_rspace, radius
847 : REAL(KIND=dp), DIMENSION(3) :: force_a, force_b, ra
848 : REAL(KIND=dp), DIMENSION(3, 3) :: my_virial_a, my_virial_b
849 1030 : REAL(KIND=dp), DIMENSION(:), POINTER :: set_radius_a
850 1030 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: hab, pab, rpgfa, sphi_a, work_f, work_i, &
851 1030 : zeta
852 1030 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
853 : TYPE(cell_type), POINTER :: cell
854 : TYPE(dft_control_type), POINTER :: dft_control
855 : TYPE(gridlevel_info_type), POINTER :: gridlevel_info
856 : TYPE(gto_basis_set_type), POINTER :: lri_basis_set
857 1030 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
858 : TYPE(pw_env_type), POINTER :: pw_env
859 1030 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
860 1030 : TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_v
861 : TYPE(realspace_grid_type), POINTER :: rs_grid
862 : TYPE(virial_type), POINTER :: virial
863 :
864 1030 : CALL timeset(routineN, handle)
865 :
866 1030 : NULLIFY (atomic_kind_set, qs_kind_set, atom_list, cell, dft_control, &
867 1030 : first_sgfa, gridlevel_info, hab, la_max, la_min, lri_basis_set, &
868 1030 : npgfa, nsgf_seta, pab, particle_set, pw_env, rpgfa, &
869 1030 : rs_grid, rs_v, virial, set_radius_a, sphi_a, work_f, &
870 1030 : work_i, zeta)
871 :
872 1030 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
873 :
874 1030 : CALL pw_env_get(pw_env, rs_grids=rs_v)
875 5114 : DO i = 1, SIZE(rs_v)
876 5114 : CALL rs_grid_zero(rs_v(i))
877 : END DO
878 :
879 1030 : gridlevel_info => pw_env%gridlevel_info
880 :
881 1030 : CALL potential_pw2rs(rs_v, v_rspace, pw_env)
882 :
883 : CALL get_qs_env(qs_env=qs_env, &
884 : atomic_kind_set=atomic_kind_set, &
885 : qs_kind_set=qs_kind_set, &
886 : cell=cell, &
887 : dft_control=dft_control, &
888 : nkind=nkind, &
889 : particle_set=particle_set, &
890 : pw_env=pw_env, &
891 1030 : virial=virial)
892 :
893 1030 : use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
894 :
895 1030 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
896 :
897 1030 : offset = 0
898 1030 : my_pos = v_rspace%pw_grid%para%group%mepos
899 1030 : group_size = v_rspace%pw_grid%para%group%num_pe
900 :
901 3040 : DO ikind = 1, nkind
902 :
903 2010 : CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom_of_kind, atom_list=atom_list)
904 2010 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=lri_basis_set, basis_type=basis_type)
905 : CALL get_gto_basis_set(gto_basis_set=lri_basis_set, &
906 : first_sgf=first_sgfa, &
907 : lmax=la_max, &
908 : lmin=la_min, &
909 : maxco=maxco, &
910 : maxsgf_set=maxsgf_set, &
911 : npgf=npgfa, &
912 : nset=nseta, &
913 : nsgf_set=nsgf_seta, &
914 : pgf_radius=rpgfa, &
915 : set_radius=set_radius_a, &
916 : sphi=sphi_a, &
917 2010 : zet=zeta)
918 :
919 8040 : ALLOCATE (hab(maxco, 1), pab(maxco, 1))
920 50828 : hab = 0._dp
921 48818 : pab(:, 1) = 0._dp
922 30372 : max_npgf = MAXVAL(npgfa(1:nseta))
923 6030 : ALLOCATE (map_it(max_npgf))
924 6030 : ALLOCATE (work_i(maxsgf_set, 1))
925 2106 : IF (calculate_forces) ALLOCATE (work_f(maxsgf_set, 1))
926 :
927 5998 : DO iatom = 1, natom_of_kind
928 :
929 3988 : atom_a = atom_list(iatom)
930 3988 : IF (PRESENT(atomlist)) THEN
931 800 : IF (atomlist(atom_a) == 0) CYCLE
932 : END IF
933 3588 : ra(:) = pbc(particle_set(atom_a)%r, cell)
934 3588 : force_a(:) = 0._dp
935 3588 : force_b(:) = 0._dp
936 3588 : my_virial_a(:, :) = 0._dp
937 3588 : my_virial_b(:, :) = 0._dp
938 :
939 54974 : DO iset = 1, nseta
940 : !
941 51386 : map_it = .FALSE.
942 107264 : DO ipgf = 1, npgfa(iset)
943 55878 : igrid_level = gaussian_gridlevel(gridlevel_info, zeta(ipgf, iset))
944 55878 : rs_grid => rs_v(igrid_level)
945 107264 : map_it(ipgf) = map_gaussian_here(rs_grid, cell%h_inv, ra, offset, group_size, my_pos)
946 : END DO
947 51386 : offset = offset + 1
948 : !
949 82913 : IF (ANY(map_it(1:npgfa(iset)))) THEN
950 25693 : sgfa = first_sgfa(1, iset)
951 25693 : ncoa = npgfa(iset)*ncoset(la_max(iset))
952 504220 : hab(:, 1) = 0._dp
953 212423 : work_i(1:nsgf_seta(iset), 1) = 0.0_dp
954 :
955 : ! get fit coefficients for forces
956 25693 : IF (calculate_forces) THEN
957 1379 : m1 = sgfa + nsgf_seta(iset) - 1
958 9649 : work_f(1:nsgf_seta(iset), 1) = int_res(ikind)%acoef(iatom, sgfa:m1)
959 : CALL dgemm("N", "N", ncoa, 1, nsgf_seta(iset), 1.0_dp, sphi_a(1, sgfa), &
960 : SIZE(sphi_a, 1), work_f(1, 1), SIZE(work_f, 1), 0.0_dp, pab(1, 1), &
961 1379 : SIZE(pab, 1))
962 : END IF
963 :
964 53632 : DO ipgf = 1, npgfa(iset)
965 27939 : na1 = (ipgf - 1)*ncoset(la_max(iset))
966 27939 : igrid_level = gaussian_gridlevel(gridlevel_info, zeta(ipgf, iset))
967 27939 : rs_grid => rs_v(igrid_level)
968 :
969 : radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
970 : lb_min=0, lb_max=0, ra=ra, rb=ra, rp=ra, &
971 : zetp=zeta(ipgf, iset), eps=eps_rho_rspace, &
972 27939 : prefactor=1.0_dp, cutoff=1.0_dp)
973 :
974 53632 : IF (map_it(ipgf)) THEN
975 27939 : IF (.NOT. calculate_forces) THEN
976 : CALL integrate_pgf_product(la_max=la_max(iset), &
977 : zeta=zeta(ipgf, iset), la_min=la_min(iset), &
978 : lb_max=0, zetb=0.0_dp, lb_min=0, &
979 : ra=ra, rab=[0.0_dp, 0.0_dp, 0.0_dp], &
980 : rsgrid=rs_grid, &
981 : hab=hab, o1=na1, o2=0, radius=radius, &
982 26186 : calculate_forces=calculate_forces)
983 : ELSE
984 : CALL integrate_pgf_product(la_max=la_max(iset), &
985 : zeta=zeta(ipgf, iset), la_min=la_min(iset), &
986 : lb_max=0, zetb=0.0_dp, lb_min=0, &
987 : ra=ra, rab=[0.0_dp, 0.0_dp, 0.0_dp], &
988 : rsgrid=rs_grid, &
989 : hab=hab, pab=pab, o1=na1, o2=0, radius=radius, &
990 : calculate_forces=calculate_forces, &
991 : force_a=force_a, force_b=force_b, &
992 : use_virial=use_virial, &
993 1753 : my_virial_a=my_virial_a, my_virial_b=my_virial_b)
994 : END IF
995 : END IF
996 : END DO
997 : ! contract hab
998 : CALL dgemm("T", "N", nsgf_seta(iset), 1, ncoa, 1.0_dp, sphi_a(1, sgfa), &
999 25693 : SIZE(sphi_a, 1), hab(1, 1), SIZE(hab, 1), 0.0_dp, work_i(1, 1), SIZE(work_i, 1))
1000 :
1001 : int_res(ikind)%v_int(iatom, sgfa:sgfa - 1 + nsgf_seta(iset)) = &
1002 399153 : int_res(ikind)%v_int(iatom, sgfa:sgfa - 1 + nsgf_seta(iset)) + work_i(1:nsgf_seta(iset), 1)
1003 : END IF
1004 : END DO
1005 : !
1006 5598 : IF (calculate_forces) THEN
1007 808 : int_res(ikind)%v_dfdr(iatom, :) = int_res(ikind)%v_dfdr(iatom, :) + force_a(:)
1008 202 : IF (use_virial) THEN
1009 676 : virial%pv_lrigpw = virial%pv_lrigpw + my_virial_a
1010 676 : virial%pv_virial = virial%pv_virial + my_virial_a
1011 : END IF
1012 : END IF
1013 :
1014 : END DO
1015 :
1016 2010 : IF (calculate_forces) DEALLOCATE (work_f)
1017 2010 : DEALLOCATE (work_i, map_it)
1018 7060 : DEALLOCATE (hab, pab)
1019 : END DO
1020 :
1021 1030 : CALL timestop(handle)
1022 :
1023 2060 : END SUBROUTINE integrate_v_rspace_one_center
1024 :
1025 : ! **************************************************************************************************
1026 : !> \brief computes integrals of product of v_rspace times the diagonal block basis functions
1027 : !> required for LRIGPW with exact 1c terms
1028 : !> \param v_rspace ...
1029 : !> \param ksmat ...
1030 : !> \param pmat ...
1031 : !> \param qs_env ...
1032 : !> \param calculate_forces ...
1033 : !> \param basis_type ...
1034 : !> \author JGH
1035 : ! **************************************************************************************************
1036 36 : SUBROUTINE integrate_v_rspace_diagonal(v_rspace, ksmat, pmat, qs_env, calculate_forces, basis_type)
1037 : TYPE(pw_r3d_rs_type), INTENT(IN) :: v_rspace
1038 : TYPE(dbcsr_type), INTENT(INOUT) :: ksmat, pmat
1039 : TYPE(qs_environment_type), POINTER :: qs_env
1040 : LOGICAL, INTENT(IN) :: calculate_forces
1041 : CHARACTER(len=*), INTENT(IN) :: basis_type
1042 :
1043 : CHARACTER(len=*), PARAMETER :: routineN = 'integrate_v_rspace_diagonal'
1044 :
1045 : INTEGER :: atom_a, group_size, handle, iatom, igrid_level, ikind, ipgf, iset, jpgf, jset, &
1046 : m1, maxco, maxsgf_set, my_pos, na1, na2, natom_of_kind, nb1, nb2, ncoa, ncob, nkind, &
1047 : nseta, nsgfa, offset, sgfa, sgfb
1048 36 : INTEGER, DIMENSION(:), POINTER :: atom_list, la_max, la_min, npgfa, &
1049 36 : nsgf_seta
1050 36 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa
1051 : LOGICAL :: found, use_virial
1052 36 : LOGICAL, ALLOCATABLE, DIMENSION(:, :) :: map_it2
1053 : REAL(KIND=dp) :: eps_rho_rspace, radius, zetp
1054 : REAL(KIND=dp), DIMENSION(3) :: force_a, force_b, ra
1055 : REAL(KIND=dp), DIMENSION(3, 3) :: my_virial_a, my_virial_b
1056 36 : REAL(KIND=dp), DIMENSION(:), POINTER :: set_radius_a
1057 36 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: h_block, hab, hmat, p_block, pab, pblk, &
1058 36 : rpgfa, sphi_a, work, zeta
1059 36 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1060 : TYPE(cell_type), POINTER :: cell
1061 : TYPE(dft_control_type), POINTER :: dft_control
1062 : TYPE(gridlevel_info_type), POINTER :: gridlevel_info
1063 : TYPE(gto_basis_set_type), POINTER :: orb_basis_set
1064 : TYPE(mp_para_env_type), POINTER :: para_env
1065 36 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1066 : TYPE(pw_env_type), POINTER :: pw_env
1067 36 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
1068 36 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1069 36 : TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_v
1070 : TYPE(realspace_grid_type), POINTER :: rs_grid
1071 : TYPE(virial_type), POINTER :: virial
1072 :
1073 36 : CALL timeset(routineN, handle)
1074 :
1075 36 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
1076 36 : CALL pw_env_get(pw_env, rs_grids=rs_v)
1077 36 : CALL potential_pw2rs(rs_v, v_rspace, pw_env)
1078 :
1079 36 : gridlevel_info => pw_env%gridlevel_info
1080 :
1081 : CALL get_qs_env(qs_env=qs_env, &
1082 : atomic_kind_set=atomic_kind_set, &
1083 : qs_kind_set=qs_kind_set, &
1084 : cell=cell, &
1085 : dft_control=dft_control, &
1086 : nkind=nkind, &
1087 : particle_set=particle_set, &
1088 : force=force, &
1089 : virial=virial, &
1090 36 : para_env=para_env)
1091 :
1092 36 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
1093 36 : use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
1094 :
1095 36 : offset = 0
1096 36 : my_pos = v_rspace%pw_grid%para%group%mepos
1097 36 : group_size = v_rspace%pw_grid%para%group%num_pe
1098 :
1099 108 : DO ikind = 1, nkind
1100 :
1101 72 : CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom_of_kind, atom_list=atom_list)
1102 72 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, basis_type=basis_type)
1103 : CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
1104 : lmax=la_max, lmin=la_min, maxco=maxco, maxsgf_set=maxsgf_set, &
1105 : npgf=npgfa, nset=nseta, nsgf_set=nsgf_seta, nsgf=nsgfa, &
1106 : first_sgf=first_sgfa, pgf_radius=rpgfa, set_radius=set_radius_a, &
1107 72 : sphi=sphi_a, zet=zeta)
1108 :
1109 720 : ALLOCATE (hab(maxco, maxco), work(maxco, maxsgf_set), hmat(nsgfa, nsgfa))
1110 72 : IF (calculate_forces) ALLOCATE (pab(maxco, maxco), pblk(nsgfa, nsgfa))
1111 :
1112 288 : DO iatom = 1, natom_of_kind
1113 216 : atom_a = atom_list(iatom)
1114 216 : ra(:) = pbc(particle_set(atom_a)%r, cell)
1115 17640 : hmat = 0.0_dp
1116 216 : IF (calculate_forces) THEN
1117 0 : CALL dbcsr_get_block_p(matrix=pmat, row=atom_a, col=atom_a, BLOCK=p_block, found=found)
1118 0 : IF (found) THEN
1119 0 : pblk(1:nsgfa, 1:nsgfa) = p_block(1:nsgfa, 1:nsgfa)
1120 : ELSE
1121 0 : pblk = 0.0_dp
1122 : END IF
1123 0 : CALL para_env%sum(pblk)
1124 0 : force_a(:) = 0._dp
1125 0 : force_b(:) = 0._dp
1126 0 : IF (use_virial) THEN
1127 0 : my_virial_a = 0.0_dp
1128 0 : my_virial_b = 0.0_dp
1129 : END IF
1130 : END IF
1131 432 : m1 = MAXVAL(npgfa(1:nseta))
1132 864 : ALLOCATE (map_it2(m1, m1))
1133 432 : DO iset = 1, nseta
1134 216 : sgfa = first_sgfa(1, iset)
1135 216 : ncoa = npgfa(iset)*ncoset(la_max(iset))
1136 648 : DO jset = 1, nseta
1137 216 : sgfb = first_sgfa(1, jset)
1138 216 : ncob = npgfa(jset)*ncoset(la_max(jset))
1139 : !
1140 216 : map_it2 = .FALSE.
1141 1728 : DO ipgf = 1, npgfa(iset)
1142 12312 : DO jpgf = 1, npgfa(jset)
1143 10584 : zetp = zeta(ipgf, iset) + zeta(jpgf, jset)
1144 10584 : igrid_level = gaussian_gridlevel(gridlevel_info, zetp)
1145 10584 : rs_grid => rs_v(igrid_level)
1146 12096 : map_it2(ipgf, jpgf) = map_gaussian_here(rs_grid, cell%h_inv, ra, offset, group_size, my_pos)
1147 : END DO
1148 : END DO
1149 216 : offset = offset + 1
1150 : !
1151 6480 : IF (ANY(map_it2(1:npgfa(iset), 1:npgfa(jset)))) THEN
1152 237492 : hab(:, :) = 0._dp
1153 108 : IF (calculate_forces) THEN
1154 : CALL dgemm("N", "N", ncoa, nsgf_seta(jset), nsgf_seta(iset), &
1155 : 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
1156 : pblk(sgfa, sgfb), SIZE(pblk, 1), &
1157 0 : 0.0_dp, work(1, 1), SIZE(work, 1))
1158 : CALL dgemm("N", "T", ncoa, ncob, nsgf_seta(jset), &
1159 : 1.0_dp, work(1, 1), SIZE(work, 1), &
1160 : sphi_a(1, sgfb), SIZE(sphi_a, 1), &
1161 0 : 0.0_dp, pab(1, 1), SIZE(pab, 1))
1162 : END IF
1163 :
1164 864 : DO ipgf = 1, npgfa(iset)
1165 756 : na1 = (ipgf - 1)*ncoset(la_max(iset))
1166 756 : na2 = ipgf*ncoset(la_max(iset))
1167 6156 : DO jpgf = 1, npgfa(jset)
1168 5292 : nb1 = (jpgf - 1)*ncoset(la_max(jset))
1169 5292 : nb2 = jpgf*ncoset(la_max(jset))
1170 5292 : zetp = zeta(ipgf, iset) + zeta(jpgf, jset)
1171 5292 : igrid_level = gaussian_gridlevel(gridlevel_info, zetp)
1172 5292 : rs_grid => rs_v(igrid_level)
1173 :
1174 : radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
1175 : lb_min=la_min(jset), lb_max=la_max(jset), &
1176 : ra=ra, rb=ra, rp=ra, &
1177 : zetp=zetp, eps=eps_rho_rspace, &
1178 5292 : prefactor=1.0_dp, cutoff=1.0_dp)
1179 :
1180 6048 : IF (map_it2(ipgf, jpgf)) THEN
1181 5292 : IF (calculate_forces) THEN
1182 : CALL integrate_pgf_product( &
1183 : la_max(iset), zeta(ipgf, iset), la_min(iset), &
1184 : la_max(jset), zeta(jpgf, jset), la_min(jset), &
1185 : ra=ra, rab=[0.0_dp, 0.0_dp, 0.0_dp], &
1186 : rsgrid=rs_v(igrid_level), &
1187 : hab=hab, pab=pab, o1=na1, o2=nb1, &
1188 : radius=radius, &
1189 : calculate_forces=.TRUE., &
1190 : force_a=force_a, force_b=force_b, &
1191 0 : use_virial=use_virial, my_virial_a=my_virial_a, my_virial_b=my_virial_b)
1192 : ELSE
1193 : CALL integrate_pgf_product( &
1194 : la_max(iset), zeta(ipgf, iset), la_min(iset), &
1195 : la_max(jset), zeta(jpgf, jset), la_min(jset), &
1196 : ra=ra, rab=[0.0_dp, 0.0_dp, 0.0_dp], &
1197 : rsgrid=rs_v(igrid_level), &
1198 : hab=hab, o1=na1, o2=nb1, &
1199 : radius=radius, &
1200 5292 : calculate_forces=.FALSE.)
1201 : END IF
1202 : END IF
1203 : END DO
1204 : END DO
1205 : ! contract hab
1206 : CALL dgemm("N", "N", ncoa, nsgf_seta(jset), ncob, &
1207 : 1.0_dp, hab(1, 1), SIZE(hab, 1), &
1208 : sphi_a(1, sgfb), SIZE(sphi_a, 1), &
1209 108 : 0.0_dp, work(1, 1), SIZE(work, 1))
1210 : CALL dgemm("T", "N", nsgf_seta(iset), nsgf_seta(jset), ncoa, &
1211 : 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
1212 : work(1, 1), SIZE(work, 1), &
1213 108 : 1.0_dp, hmat(sgfa, sgfb), SIZE(hmat, 1))
1214 : END IF
1215 : END DO
1216 : END DO
1217 216 : DEALLOCATE (map_it2)
1218 : ! update KS matrix
1219 35064 : CALL para_env%sum(hmat)
1220 216 : CALL dbcsr_get_block_p(matrix=ksmat, row=atom_a, col=atom_a, BLOCK=h_block, found=found)
1221 216 : IF (found) THEN
1222 17532 : h_block(1:nsgfa, 1:nsgfa) = h_block(1:nsgfa, 1:nsgfa) + hmat(1:nsgfa, 1:nsgfa)
1223 : END IF
1224 504 : IF (calculate_forces) THEN
1225 0 : force(ikind)%rho_elec(:, iatom) = force(ikind)%rho_elec(:, iatom) + 2.0_dp*force_a(:)
1226 0 : IF (use_virial) THEN
1227 : IF (use_virial .AND. calculate_forces) THEN
1228 0 : virial%pv_lrigpw = virial%pv_lrigpw + 2.0_dp*my_virial_a
1229 0 : virial%pv_virial = virial%pv_virial + 2.0_dp*my_virial_a
1230 : END IF
1231 : END IF
1232 : END IF
1233 : END DO
1234 72 : DEALLOCATE (hab, work, hmat)
1235 252 : IF (calculate_forces) DEALLOCATE (pab, pblk)
1236 : END DO
1237 :
1238 36 : CALL timestop(handle)
1239 :
1240 72 : END SUBROUTINE integrate_v_rspace_diagonal
1241 :
1242 : ! **************************************************************************************************
1243 : !> \brief computes integrals of product of v_rspace times a basis function (vector function)
1244 : !> and possible forces
1245 : !> \param qs_env ...
1246 : !> \param v_rspace ...
1247 : !> \param f_coef ...
1248 : !> \param f_integral ...
1249 : !> \param calculate_forces ...
1250 : !> \param basis_type ...
1251 : !> \author JGH [8.2024]
1252 : ! **************************************************************************************************
1253 8 : SUBROUTINE integrate_function(qs_env, v_rspace, f_coef, f_integral, calculate_forces, basis_type)
1254 : TYPE(qs_environment_type), POINTER :: qs_env
1255 : TYPE(pw_r3d_rs_type), INTENT(IN) :: v_rspace
1256 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: f_coef
1257 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: f_integral
1258 : LOGICAL, INTENT(IN) :: calculate_forces
1259 : CHARACTER(len=*), INTENT(IN) :: basis_type
1260 :
1261 : CHARACTER(len=*), PARAMETER :: routineN = 'integrate_function'
1262 :
1263 : INTEGER :: atom_a, group_size, handle, i, iatom, igrid_level, ikind, ipgf, iset, maxco, &
1264 : maxsgf_set, my_pos, na1, natom, ncoa, nkind, nseta, offset, sgfa
1265 8 : INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind
1266 8 : INTEGER, DIMENSION(:), POINTER :: la_max, la_min, npgfa, nsgfa
1267 8 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa
1268 : LOGICAL :: use_virial
1269 : REAL(KIND=dp) :: eps_rho_rspace, radius
1270 : REAL(KIND=dp), DIMENSION(3) :: force_a, force_b, ra
1271 : REAL(KIND=dp), DIMENSION(3, 3) :: my_virial_a, my_virial_b
1272 8 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: hab, pab, sphi_a, work, zeta
1273 8 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1274 : TYPE(cell_type), POINTER :: cell
1275 : TYPE(dft_control_type), POINTER :: dft_control
1276 : TYPE(gridlevel_info_type), POINTER :: gridlevel_info
1277 : TYPE(gto_basis_set_type), POINTER :: orb_basis_set
1278 8 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1279 : TYPE(pw_env_type), POINTER :: pw_env
1280 8 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
1281 8 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1282 8 : TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_v
1283 : TYPE(realspace_grid_type), POINTER :: rs_grid
1284 : TYPE(virial_type), POINTER :: virial
1285 :
1286 8 : CALL timeset(routineN, handle)
1287 :
1288 8 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
1289 8 : gridlevel_info => pw_env%gridlevel_info
1290 :
1291 8 : CALL pw_env_get(pw_env, rs_grids=rs_v)
1292 8 : CALL potential_pw2rs(rs_v, v_rspace, pw_env)
1293 :
1294 : CALL get_qs_env(qs_env=qs_env, &
1295 : atomic_kind_set=atomic_kind_set, &
1296 : qs_kind_set=qs_kind_set, &
1297 : force=force, &
1298 : cell=cell, &
1299 : dft_control=dft_control, &
1300 : nkind=nkind, &
1301 : natom=natom, &
1302 : particle_set=particle_set, &
1303 : pw_env=pw_env, &
1304 8 : virial=virial)
1305 8 : CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, atom_of_kind=atom_of_kind)
1306 :
1307 8 : use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
1308 8 : IF (use_virial) THEN
1309 0 : CPABORT("Virial NYA")
1310 : END IF
1311 :
1312 8 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
1313 :
1314 : CALL get_qs_kind_set(qs_kind_set, &
1315 8 : maxco=maxco, maxsgf_set=maxsgf_set, basis_type=basis_type)
1316 40 : ALLOCATE (hab(maxco, 1), pab(maxco, 1), work(maxco, 1))
1317 :
1318 8 : offset = 0
1319 8 : my_pos = v_rspace%pw_grid%para%group%mepos
1320 8 : group_size = v_rspace%pw_grid%para%group%num_pe
1321 :
1322 40 : DO iatom = 1, natom
1323 32 : ikind = particle_set(iatom)%atomic_kind%kind_number
1324 32 : atom_a = atom_of_kind(iatom)
1325 32 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, basis_type=basis_type)
1326 : CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
1327 : first_sgf=first_sgfa, &
1328 : lmax=la_max, &
1329 : lmin=la_min, &
1330 : npgf=npgfa, &
1331 : nset=nseta, &
1332 : nsgf_set=nsgfa, &
1333 : sphi=sphi_a, &
1334 32 : zet=zeta)
1335 32 : ra(:) = pbc(particle_set(iatom)%r, cell)
1336 :
1337 32 : force_a(:) = 0._dp
1338 32 : force_b(:) = 0._dp
1339 32 : my_virial_a(:, :) = 0._dp
1340 32 : my_virial_b(:, :) = 0._dp
1341 :
1342 64 : DO iset = 1, nseta
1343 :
1344 32 : ncoa = npgfa(iset)*ncoset(la_max(iset))
1345 32 : sgfa = first_sgfa(1, iset)
1346 :
1347 288 : hab = 0._dp
1348 288 : pab = 0._dp
1349 :
1350 240 : DO i = 1, nsgfa(iset)
1351 240 : work(i, 1) = f_coef(offset + i)
1352 : END DO
1353 :
1354 : CALL dgemm("N", "N", ncoa, 1, nsgfa(iset), &
1355 : 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
1356 : work(1, 1), SIZE(work, 1), &
1357 32 : 0.0_dp, pab(1, 1), SIZE(pab, 1))
1358 :
1359 240 : DO ipgf = 1, npgfa(iset)
1360 :
1361 208 : na1 = (ipgf - 1)*ncoset(la_max(iset))
1362 :
1363 208 : igrid_level = gaussian_gridlevel(gridlevel_info, zeta(ipgf, iset))
1364 208 : rs_grid => rs_v(igrid_level)
1365 :
1366 240 : IF (map_gaussian_here(rs_grid, cell%h_inv, ra, offset, group_size, my_pos)) THEN
1367 : radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
1368 : lb_min=0, lb_max=0, ra=ra, rb=ra, rp=ra, &
1369 : zetp=zeta(ipgf, iset), eps=eps_rho_rspace, &
1370 104 : prefactor=1.0_dp, cutoff=1.0_dp)
1371 :
1372 104 : IF (calculate_forces) THEN
1373 : CALL integrate_pgf_product(la_max=la_max(iset), &
1374 : zeta=zeta(ipgf, iset), la_min=la_min(iset), &
1375 : lb_max=0, zetb=0.0_dp, lb_min=0, &
1376 : ra=ra, rab=[0.0_dp, 0.0_dp, 0.0_dp], &
1377 : rsgrid=rs_grid, &
1378 : hab=hab, pab=pab, o1=na1, o2=0, radius=radius, &
1379 : calculate_forces=.TRUE., &
1380 : force_a=force_a, force_b=force_b, &
1381 : use_virial=use_virial, &
1382 104 : my_virial_a=my_virial_a, my_virial_b=my_virial_b)
1383 : ELSE
1384 : CALL integrate_pgf_product(la_max=la_max(iset), &
1385 : zeta=zeta(ipgf, iset), la_min=la_min(iset), &
1386 : lb_max=0, zetb=0.0_dp, lb_min=0, &
1387 : ra=ra, rab=[0.0_dp, 0.0_dp, 0.0_dp], &
1388 : rsgrid=rs_grid, &
1389 : hab=hab, o1=na1, o2=0, radius=radius, &
1390 0 : calculate_forces=.FALSE.)
1391 : END IF
1392 :
1393 : END IF
1394 :
1395 : END DO
1396 : !
1397 : CALL dgemm("T", "N", nsgfa(iset), 1, ncoa, 1.0_dp, sphi_a(1, sgfa), &
1398 32 : SIZE(sphi_a, 1), hab(1, 1), SIZE(hab, 1), 0.0_dp, work(1, 1), SIZE(work, 1))
1399 240 : DO i = 1, nsgfa(iset)
1400 240 : f_integral(offset + i) = work(i, 1)
1401 : END DO
1402 :
1403 64 : offset = offset + nsgfa(iset)
1404 :
1405 : END DO
1406 :
1407 72 : IF (calculate_forces) THEN
1408 128 : force(ikind)%rho_elec(:, atom_a) = force(ikind)%rho_elec(:, atom_a) + force_a(:)
1409 32 : IF (use_virial) THEN
1410 0 : virial%pv_virial = virial%pv_virial + my_virial_a
1411 : END IF
1412 : END IF
1413 :
1414 : END DO
1415 :
1416 8 : DEALLOCATE (hab, pab, work)
1417 :
1418 8 : CALL timestop(handle)
1419 :
1420 24 : END SUBROUTINE integrate_function
1421 :
1422 : END MODULE qs_integrate_potential_single
|