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 Calculate the plane wave density by collocating the primitive Gaussian
10 : !> functions (pgf).
11 : !> \par History
12 : !> - rewrote collocate for increased accuracy and speed
13 : !> - introduced the PGI hack for increased speed with that compiler
14 : !> (22.02.02)
15 : !> - Added Multiple Grid feature
16 : !> - new way to get over the grid (01.03.02)
17 : !> - removed timing calls since they were getting expensive
18 : !> - Updated with the new QS data structures (09.04.02,MK)
19 : !> - introduction of the real space grid type ( prelim. version JVdV 05.02)
20 : !> - parallel FFT (JGH 22.05.02)
21 : !> - multigrid arrays independent from density (JGH 30.08.02)
22 : !> - old density stored in g space (JGH 30.08.02)
23 : !> - distributed real space code (JGH 17.07.03)
24 : !> - refactoring and new loop ordering (JGH 23.11.03)
25 : !> - OpenMP parallelization (JGH 03.12.03)
26 : !> - Modified to compute tau (Joost 12.03)
27 : !> - removed the incremental density rebuild (Joost 01.04)
28 : !> - introduced realspace multigridding (Joost 02.04)
29 : !> - introduced map_consistent (Joost 02.04)
30 : !> - Addition of the subroutine calculate_atomic_charge_density (TdK, 08.05)
31 : !> - rewrite of the collocate/integrate kernels (Joost VandeVondele, 03.07)
32 : !> - Extended by the derivatives for DFPT [Sandra Luber, Edward Ditler, 2021]
33 : !> \author Matthias Krack (03.04.2001)
34 : !> 1) Joost VandeVondele (01.2002)
35 : !> Thomas D. Kuehne (04.08.2005)
36 : !> Ole Schuett (2020)
37 : ! **************************************************************************************************
38 : MODULE qs_collocate_density
39 : USE admm_types, ONLY: get_admm_env
40 : USE ao_util, ONLY: exp_radius_very_extended
41 : USE atomic_kind_types, ONLY: atomic_kind_type, &
42 : get_atomic_kind, &
43 : get_atomic_kind_set
44 : USE basis_set_types, ONLY: get_gto_basis_set, &
45 : gto_basis_set_type
46 : USE cell_types, ONLY: cell_type, &
47 : pbc
48 : USE cp_control_types, ONLY: dft_control_type
49 : USE cp_dbcsr_operations, ONLY: dbcsr_deallocate_matrix_set
50 : USE cp_fm_types, ONLY: cp_fm_get_element, &
51 : cp_fm_get_info, &
52 : cp_fm_type
53 : USE cp_dbcsr_api, ONLY: dbcsr_copy, &
54 : dbcsr_get_block_p, &
55 : dbcsr_p_type, &
56 : dbcsr_type
57 : USE external_potential_types, ONLY: get_potential, &
58 : gth_potential_type
59 : USE gaussian_gridlevels, ONLY: gaussian_gridlevel, &
60 : gridlevel_info_type
61 : USE grid_api, ONLY: &
62 : GRID_FUNC_AB, GRID_FUNC_CORE_X, GRID_FUNC_CORE_Y, GRID_FUNC_CORE_Z, GRID_FUNC_DAB_X, &
63 : GRID_FUNC_DAB_Y, GRID_FUNC_DAB_Z, GRID_FUNC_DABpADB_X, GRID_FUNC_DABpADB_Y, &
64 : GRID_FUNC_DABpADB_Z, GRID_FUNC_DADB, GRID_FUNC_DX, GRID_FUNC_DXDX, GRID_FUNC_DXDY, &
65 : GRID_FUNC_DY, GRID_FUNC_DYDY, GRID_FUNC_DYDZ, GRID_FUNC_DZ, GRID_FUNC_DZDX, &
66 : GRID_FUNC_DZDZ, collocate_pgf_product, grid_collocate_task_list
67 : USE input_constants, ONLY: &
68 : orb_dx2, orb_dxy, orb_dy2, orb_dyz, orb_dz2, orb_dzx, orb_px, orb_py, orb_pz, orb_s
69 : USE kinds, ONLY: default_string_length, &
70 : dp
71 : USE lri_environment_types, ONLY: lri_kind_type
72 : USE memory_utilities, ONLY: reallocate
73 : USE message_passing, ONLY: mp_comm_type
74 : USE orbital_pointers, ONLY: coset, &
75 : ncoset
76 : USE particle_types, ONLY: particle_type
77 : USE pw_env_types, ONLY: pw_env_get, &
78 : pw_env_type
79 : USE pw_methods, ONLY: pw_axpy, &
80 : pw_integrate_function, &
81 : pw_transfer, &
82 : pw_zero
83 : USE pw_pool_types, ONLY: pw_pool_p_type, &
84 : pw_pool_type, &
85 : pw_pools_create_pws, &
86 : pw_pools_give_back_pws
87 : USE pw_types, ONLY: pw_r3d_rs_type, &
88 : pw_c1d_gs_type, &
89 : pw_r3d_rs_type
90 : USE qs_environment_types, ONLY: get_qs_env, &
91 : qs_environment_type
92 : USE qs_kind_types, ONLY: get_qs_kind, &
93 : get_qs_kind_set, &
94 : qs_kind_type
95 : USE qs_ks_types, ONLY: get_ks_env, &
96 : qs_ks_env_type
97 : USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
98 : USE realspace_grid_types, ONLY: map_gaussian_here, &
99 : realspace_grid_desc_p_type, &
100 : realspace_grid_type, &
101 : rs_grid_zero, &
102 : transfer_rs2pw
103 : USE rs_pw_interface, ONLY: density_rs2pw
104 : USE task_list_methods, ONLY: rs_copy_to_buffer, &
105 : rs_distribute_matrix, &
106 : rs_scatter_matrices
107 : USE task_list_types, ONLY: atom_pair_type, &
108 : task_list_type, &
109 : task_type
110 :
111 : !$ USE OMP_LIB, ONLY: omp_get_max_threads, omp_get_thread_num, omp_get_num_threads
112 :
113 : #include "./base/base_uses.f90"
114 :
115 : IMPLICIT NONE
116 :
117 : PRIVATE
118 :
119 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_collocate_density'
120 : ! *** Public subroutines ***
121 :
122 : PUBLIC :: calculate_ppl_grid, &
123 : calculate_rho_core, &
124 : calculate_lri_rho_elec, &
125 : calculate_rho_single_gaussian, &
126 : calculate_rho_metal, &
127 : calculate_rho_resp_single, &
128 : calculate_rho_resp_all, &
129 : calculate_rho_elec, &
130 : calculate_drho_elec, &
131 : calculate_wavefunction, &
132 : collocate_function, &
133 : calculate_rho_nlcc, &
134 : calculate_drho_elec_dR, &
135 : calculate_drho_core, &
136 : collocate_single_gaussian
137 :
138 : INTERFACE calculate_rho_core
139 : MODULE PROCEDURE calculate_rho_core_r3d_rs
140 : MODULE PROCEDURE calculate_rho_core_c1d_gs
141 : END INTERFACE
142 :
143 : INTERFACE calculate_rho_resp_all
144 : MODULE PROCEDURE calculate_rho_resp_all_r3d_rs, calculate_rho_resp_all_c1d_gs
145 : END INTERFACE
146 :
147 : CONTAINS
148 :
149 : ! **************************************************************************************************
150 : !> \brief computes the density of the non-linear core correction on the grid
151 : !> \param rho_nlcc ...
152 : !> \param qs_env ...
153 : ! **************************************************************************************************
154 52 : SUBROUTINE calculate_rho_nlcc(rho_nlcc, qs_env)
155 :
156 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: rho_nlcc
157 : TYPE(qs_environment_type), POINTER :: qs_env
158 :
159 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho_nlcc'
160 :
161 : INTEGER :: atom_a, handle, iatom, iexp_nlcc, ikind, &
162 : ithread, j, n, natom, nc, nexp_nlcc, &
163 : ni, npme, nthread, subpatch_pattern
164 52 : INTEGER, DIMENSION(:), POINTER :: atom_list, cores, nct_nlcc
165 : LOGICAL :: nlcc
166 : REAL(KIND=dp) :: alpha, eps_rho_rspace, radius
167 : REAL(KIND=dp), DIMENSION(3) :: ra
168 52 : REAL(KIND=dp), DIMENSION(:), POINTER :: alpha_nlcc
169 52 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: cval_nlcc, pab
170 52 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
171 : TYPE(cell_type), POINTER :: cell
172 : TYPE(dft_control_type), POINTER :: dft_control
173 : TYPE(gth_potential_type), POINTER :: gth_potential
174 52 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
175 : TYPE(pw_env_type), POINTER :: pw_env
176 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
177 52 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
178 : TYPE(realspace_grid_type), POINTER :: rs_rho
179 :
180 52 : CALL timeset(routineN, handle)
181 :
182 52 : NULLIFY (cell, dft_control, pab, particle_set, atomic_kind_set, &
183 52 : qs_kind_set, atom_list, pw_env, rs_rho, auxbas_pw_pool, cores)
184 :
185 : CALL get_qs_env(qs_env=qs_env, &
186 : atomic_kind_set=atomic_kind_set, &
187 : qs_kind_set=qs_kind_set, &
188 : cell=cell, &
189 : dft_control=dft_control, &
190 : particle_set=particle_set, &
191 52 : pw_env=pw_env)
192 : CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
193 52 : auxbas_pw_pool=auxbas_pw_pool)
194 : ! be careful in parallel nsmax is chosen with multigrid in mind!
195 52 : CALL rs_grid_zero(rs_rho)
196 :
197 52 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
198 :
199 140 : DO ikind = 1, SIZE(atomic_kind_set)
200 88 : CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
201 88 : CALL get_qs_kind(qs_kind_set(ikind), gth_potential=gth_potential)
202 :
203 88 : IF (.NOT. ASSOCIATED(gth_potential)) CYCLE
204 : CALL get_potential(potential=gth_potential, nlcc_present=nlcc, nexp_nlcc=nexp_nlcc, &
205 88 : alpha_nlcc=alpha_nlcc, nct_nlcc=nct_nlcc, cval_nlcc=cval_nlcc)
206 :
207 88 : IF (.NOT. nlcc) CYCLE
208 :
209 368 : DO iexp_nlcc = 1, nexp_nlcc
210 :
211 70 : alpha = alpha_nlcc(iexp_nlcc)
212 70 : nc = nct_nlcc(iexp_nlcc)
213 :
214 70 : ni = ncoset(2*nc - 2)
215 210 : ALLOCATE (pab(ni, 1))
216 354 : pab = 0._dp
217 :
218 70 : nthread = 1
219 70 : ithread = 0
220 :
221 70 : CALL reallocate(cores, 1, natom)
222 70 : npme = 0
223 264 : cores = 0
224 :
225 : ! prepare core function
226 156 : DO j = 1, nc
227 70 : SELECT CASE (j)
228 : CASE (1)
229 70 : pab(1, 1) = cval_nlcc(1, iexp_nlcc)
230 : CASE (2)
231 16 : n = coset(2, 0, 0)
232 16 : pab(n, 1) = cval_nlcc(2, iexp_nlcc)/alpha**2
233 16 : n = coset(0, 2, 0)
234 16 : pab(n, 1) = cval_nlcc(2, iexp_nlcc)/alpha**2
235 16 : n = coset(0, 0, 2)
236 16 : pab(n, 1) = cval_nlcc(2, iexp_nlcc)/alpha**2
237 : CASE (3)
238 0 : n = coset(4, 0, 0)
239 0 : pab(n, 1) = cval_nlcc(3, iexp_nlcc)/alpha**4
240 0 : n = coset(0, 4, 0)
241 0 : pab(n, 1) = cval_nlcc(3, iexp_nlcc)/alpha**4
242 0 : n = coset(0, 0, 4)
243 0 : pab(n, 1) = cval_nlcc(3, iexp_nlcc)/alpha**4
244 0 : n = coset(2, 2, 0)
245 0 : pab(n, 1) = 2._dp*cval_nlcc(3, iexp_nlcc)/alpha**4
246 0 : n = coset(2, 0, 2)
247 0 : pab(n, 1) = 2._dp*cval_nlcc(3, iexp_nlcc)/alpha**4
248 0 : n = coset(0, 2, 2)
249 0 : pab(n, 1) = 2._dp*cval_nlcc(3, iexp_nlcc)/alpha**4
250 : CASE (4)
251 0 : n = coset(6, 0, 0)
252 0 : pab(n, 1) = cval_nlcc(4, iexp_nlcc)/alpha**6
253 0 : n = coset(0, 6, 0)
254 0 : pab(n, 1) = cval_nlcc(4, iexp_nlcc)/alpha**6
255 0 : n = coset(0, 0, 6)
256 0 : pab(n, 1) = cval_nlcc(4, iexp_nlcc)/alpha**6
257 0 : n = coset(4, 2, 0)
258 0 : pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
259 0 : n = coset(4, 0, 2)
260 0 : pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
261 0 : n = coset(2, 4, 0)
262 0 : pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
263 0 : n = coset(2, 0, 4)
264 0 : pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
265 0 : n = coset(0, 4, 2)
266 0 : pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
267 0 : n = coset(0, 2, 4)
268 0 : pab(n, 1) = 3._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
269 0 : n = coset(2, 2, 2)
270 0 : pab(n, 1) = 6._dp*cval_nlcc(4, iexp_nlcc)/alpha**6
271 : CASE DEFAULT
272 : CALL cp_abort(__LOCATION__, &
273 : "Only 1, 2, 3, 4 are supported as the "// &
274 86 : "value of j in calculate_rho_nlcc")
275 : END SELECT
276 : END DO
277 70 : IF (dft_control%nspins == 2) pab = pab*0.5_dp
278 :
279 264 : DO iatom = 1, natom
280 194 : atom_a = atom_list(iatom)
281 194 : ra(:) = pbc(particle_set(atom_a)%r, cell)
282 264 : IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
283 : ! replicated realspace grid, split the atoms up between procs
284 194 : IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
285 97 : npme = npme + 1
286 97 : cores(npme) = iatom
287 : END IF
288 : ELSE
289 0 : npme = npme + 1
290 0 : cores(npme) = iatom
291 : END IF
292 : END DO
293 :
294 167 : DO j = 1, npme
295 :
296 97 : iatom = cores(j)
297 97 : atom_a = atom_list(iatom)
298 97 : ra(:) = pbc(particle_set(atom_a)%r, cell)
299 97 : subpatch_pattern = 0
300 97 : ni = 2*nc - 2
301 : radius = exp_radius_very_extended(la_min=0, la_max=ni, lb_min=0, lb_max=0, &
302 : ra=ra, rb=ra, rp=ra, &
303 : zetp=1/(2*alpha**2), eps=eps_rho_rspace, &
304 : pab=pab, o1=0, o2=0, & ! without map_consistent
305 97 : prefactor=1.0_dp, cutoff=0.0_dp)
306 :
307 : CALL collocate_pgf_product(ni, 1/(2*alpha**2), 0, 0, 0.0_dp, 0, ra, &
308 : [0.0_dp, 0.0_dp, 0.0_dp], 1.0_dp, pab, 0, 0, rs_rho, &
309 : ga_gb_function=GRID_FUNC_AB, radius=radius, &
310 167 : use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
311 :
312 : END DO
313 :
314 158 : DEALLOCATE (pab)
315 :
316 : END DO
317 :
318 : END DO
319 :
320 52 : IF (ASSOCIATED(cores)) THEN
321 52 : DEALLOCATE (cores)
322 : END IF
323 :
324 52 : CALL transfer_rs2pw(rs_rho, rho_nlcc)
325 :
326 52 : CALL timestop(handle)
327 :
328 52 : END SUBROUTINE calculate_rho_nlcc
329 :
330 : ! **************************************************************************************************
331 : !> \brief computes the local pseudopotential (without erf term) on the grid
332 : !> \param vppl ...
333 : !> \param qs_env ...
334 : ! **************************************************************************************************
335 12 : SUBROUTINE calculate_ppl_grid(vppl, qs_env)
336 :
337 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: vppl
338 : TYPE(qs_environment_type), POINTER :: qs_env
339 :
340 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_ppl_grid'
341 :
342 : INTEGER :: atom_a, handle, iatom, ikind, ithread, &
343 : j, lppl, n, natom, ni, npme, nthread, &
344 : subpatch_pattern
345 12 : INTEGER, DIMENSION(:), POINTER :: atom_list, cores
346 : REAL(KIND=dp) :: alpha, eps_rho_rspace, radius
347 : REAL(KIND=dp), DIMENSION(3) :: ra
348 12 : REAL(KIND=dp), DIMENSION(:), POINTER :: cexp_ppl
349 12 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: pab
350 12 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
351 : TYPE(cell_type), POINTER :: cell
352 : TYPE(dft_control_type), POINTER :: dft_control
353 : TYPE(gth_potential_type), POINTER :: gth_potential
354 12 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
355 : TYPE(pw_env_type), POINTER :: pw_env
356 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
357 12 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
358 : TYPE(realspace_grid_type), POINTER :: rs_rho
359 :
360 12 : CALL timeset(routineN, handle)
361 :
362 12 : NULLIFY (cell, dft_control, pab, atomic_kind_set, qs_kind_set, particle_set, &
363 12 : atom_list, pw_env, rs_rho, auxbas_pw_pool, cores)
364 :
365 : CALL get_qs_env(qs_env=qs_env, &
366 : atomic_kind_set=atomic_kind_set, &
367 : qs_kind_set=qs_kind_set, &
368 : cell=cell, &
369 : dft_control=dft_control, &
370 : particle_set=particle_set, &
371 12 : pw_env=pw_env)
372 : CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
373 12 : auxbas_pw_pool=auxbas_pw_pool)
374 : ! be careful in parallel nsmax is chosen with multigrid in mind!
375 12 : CALL rs_grid_zero(rs_rho)
376 :
377 12 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
378 :
379 28 : DO ikind = 1, SIZE(atomic_kind_set)
380 16 : CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
381 16 : CALL get_qs_kind(qs_kind_set(ikind), gth_potential=gth_potential)
382 :
383 16 : IF (.NOT. ASSOCIATED(gth_potential)) CYCLE
384 16 : CALL get_potential(potential=gth_potential, alpha_ppl=alpha, nexp_ppl=lppl, cexp_ppl=cexp_ppl)
385 :
386 16 : IF (lppl <= 0) CYCLE
387 :
388 16 : ni = ncoset(2*lppl - 2)
389 48 : ALLOCATE (pab(ni, 1))
390 192 : pab = 0._dp
391 :
392 16 : nthread = 1
393 16 : ithread = 0
394 :
395 16 : CALL reallocate(cores, 1, natom)
396 16 : npme = 0
397 60 : cores = 0
398 :
399 : ! prepare core function
400 48 : DO j = 1, lppl
401 16 : SELECT CASE (j)
402 : CASE (1)
403 16 : pab(1, 1) = cexp_ppl(1)
404 : CASE (2)
405 16 : n = coset(2, 0, 0)
406 16 : pab(n, 1) = cexp_ppl(2)
407 16 : n = coset(0, 2, 0)
408 16 : pab(n, 1) = cexp_ppl(2)
409 16 : n = coset(0, 0, 2)
410 16 : pab(n, 1) = cexp_ppl(2)
411 : CASE (3)
412 0 : n = coset(4, 0, 0)
413 0 : pab(n, 1) = cexp_ppl(3)
414 0 : n = coset(0, 4, 0)
415 0 : pab(n, 1) = cexp_ppl(3)
416 0 : n = coset(0, 0, 4)
417 0 : pab(n, 1) = cexp_ppl(3)
418 0 : n = coset(2, 2, 0)
419 0 : pab(n, 1) = 2._dp*cexp_ppl(3)
420 0 : n = coset(2, 0, 2)
421 0 : pab(n, 1) = 2._dp*cexp_ppl(3)
422 0 : n = coset(0, 2, 2)
423 0 : pab(n, 1) = 2._dp*cexp_ppl(3)
424 : CASE (4)
425 0 : n = coset(6, 0, 0)
426 0 : pab(n, 1) = cexp_ppl(4)
427 0 : n = coset(0, 6, 0)
428 0 : pab(n, 1) = cexp_ppl(4)
429 0 : n = coset(0, 0, 6)
430 0 : pab(n, 1) = cexp_ppl(4)
431 0 : n = coset(4, 2, 0)
432 0 : pab(n, 1) = 3._dp*cexp_ppl(4)
433 0 : n = coset(4, 0, 2)
434 0 : pab(n, 1) = 3._dp*cexp_ppl(4)
435 0 : n = coset(2, 4, 0)
436 0 : pab(n, 1) = 3._dp*cexp_ppl(4)
437 0 : n = coset(2, 0, 4)
438 0 : pab(n, 1) = 3._dp*cexp_ppl(4)
439 0 : n = coset(0, 4, 2)
440 0 : pab(n, 1) = 3._dp*cexp_ppl(4)
441 0 : n = coset(0, 2, 4)
442 0 : pab(n, 1) = 3._dp*cexp_ppl(4)
443 0 : n = coset(2, 2, 2)
444 0 : pab(n, 1) = 6._dp*cexp_ppl(4)
445 : CASE DEFAULT
446 : CALL cp_abort(__LOCATION__, &
447 : "Only 1, 2, 3, 4 are supported as the "// &
448 32 : "value of j in calculate_ppl_grid")
449 : END SELECT
450 : END DO
451 :
452 60 : DO iatom = 1, natom
453 44 : atom_a = atom_list(iatom)
454 44 : ra(:) = pbc(particle_set(atom_a)%r, cell)
455 60 : IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
456 : ! replicated realspace grid, split the atoms up between procs
457 44 : IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
458 22 : npme = npme + 1
459 22 : cores(npme) = iatom
460 : END IF
461 : ELSE
462 0 : npme = npme + 1
463 0 : cores(npme) = iatom
464 : END IF
465 : END DO
466 :
467 16 : IF (npme > 0) THEN
468 36 : DO j = 1, npme
469 :
470 22 : iatom = cores(j)
471 22 : atom_a = atom_list(iatom)
472 22 : ra(:) = pbc(particle_set(atom_a)%r, cell)
473 22 : subpatch_pattern = 0
474 22 : ni = 2*lppl - 2
475 :
476 : radius = exp_radius_very_extended(la_min=0, la_max=ni, &
477 : lb_min=0, lb_max=0, &
478 : ra=ra, rb=ra, rp=ra, &
479 : zetp=alpha, eps=eps_rho_rspace, &
480 : pab=pab, o1=0, o2=0, & ! without map_consistent
481 22 : prefactor=1.0_dp, cutoff=0.0_dp)
482 :
483 : CALL collocate_pgf_product(ni, alpha, 0, 0, 0.0_dp, 0, ra, &
484 : [0.0_dp, 0.0_dp, 0.0_dp], 1.0_dp, pab, 0, 0, rs_rho, &
485 : radius=radius, ga_gb_function=GRID_FUNC_AB, &
486 36 : use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
487 :
488 : END DO
489 : END IF
490 :
491 60 : DEALLOCATE (pab)
492 :
493 : END DO
494 :
495 12 : IF (ASSOCIATED(cores)) THEN
496 12 : DEALLOCATE (cores)
497 : END IF
498 :
499 12 : CALL transfer_rs2pw(rs_rho, vppl)
500 :
501 12 : CALL timestop(handle)
502 :
503 12 : END SUBROUTINE calculate_ppl_grid
504 :
505 : ! **************************************************************************************************
506 : !> \brief Collocates the fitted lri density on a grid.
507 : !> \param lri_rho_g ...
508 : !> \param lri_rho_r ...
509 : !> \param qs_env ...
510 : !> \param lri_coef ...
511 : !> \param total_rho ...
512 : !> \param basis_type ...
513 : !> \param exact_1c_terms ...
514 : !> \param pmat replicated block diagonal density matrix (optional)
515 : !> \param atomlist list of atoms to be included (optional)
516 : !> \par History
517 : !> 04.2013
518 : !> \author Dorothea Golze
519 : ! **************************************************************************************************
520 1204 : SUBROUTINE calculate_lri_rho_elec(lri_rho_g, lri_rho_r, qs_env, &
521 1204 : lri_coef, total_rho, basis_type, exact_1c_terms, pmat, atomlist)
522 :
523 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: lri_rho_g
524 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: lri_rho_r
525 : TYPE(qs_environment_type), POINTER :: qs_env
526 : TYPE(lri_kind_type), DIMENSION(:), POINTER :: lri_coef
527 : REAL(KIND=dp), INTENT(OUT) :: total_rho
528 : CHARACTER(len=*), INTENT(IN) :: basis_type
529 : LOGICAL, INTENT(IN) :: exact_1c_terms
530 : TYPE(dbcsr_type), OPTIONAL :: pmat
531 : INTEGER, DIMENSION(:), OPTIONAL :: atomlist
532 :
533 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_lri_rho_elec'
534 :
535 : INTEGER :: atom_a, group_size, handle, iatom, igrid_level, ikind, ipgf, iset, jpgf, jset, &
536 : m1, maxco, maxsgf_set, my_pos, na1, natom, nb1, ncoa, ncob, nseta, offset, sgfa, sgfb
537 1204 : INTEGER, DIMENSION(:), POINTER :: atom_list, la_max, la_min, npgfa, nsgfa
538 1204 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa
539 : LOGICAL :: found
540 1204 : LOGICAL, ALLOCATABLE, DIMENSION(:) :: map_it
541 1204 : LOGICAL, ALLOCATABLE, DIMENSION(:, :) :: map_it2
542 : REAL(KIND=dp) :: eps_rho_rspace, radius, zetp
543 : REAL(KIND=dp), DIMENSION(3) :: ra
544 1204 : REAL(KIND=dp), DIMENSION(:), POINTER :: aci
545 1204 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: p_block, pab, sphi_a, work, zeta
546 1204 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
547 : TYPE(cell_type), POINTER :: cell
548 : TYPE(dft_control_type), POINTER :: dft_control
549 : TYPE(gridlevel_info_type), POINTER :: gridlevel_info
550 : TYPE(gto_basis_set_type), POINTER :: lri_basis_set, orb_basis_set
551 1204 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
552 : TYPE(pw_env_type), POINTER :: pw_env
553 1204 : TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
554 1204 : TYPE(pw_c1d_gs_type), ALLOCATABLE, DIMENSION(:) :: mgrid_gspace
555 1204 : TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:) :: mgrid_rspace
556 1204 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
557 1204 : TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_rho
558 : TYPE(realspace_grid_type), POINTER :: rs_grid
559 :
560 1204 : NULLIFY (aci, atomic_kind_set, qs_kind_set, atom_list, cell, &
561 1204 : dft_control, first_sgfa, gridlevel_info, la_max, &
562 1204 : la_min, lri_basis_set, npgfa, nsgfa, &
563 1204 : pab, particle_set, pw_env, pw_pools, rs_grid, rs_rho, sphi_a, &
564 1204 : work, zeta)
565 :
566 1204 : CALL timeset(routineN, handle)
567 :
568 1204 : IF (exact_1c_terms) THEN
569 48 : CPASSERT(PRESENT(pmat))
570 : END IF
571 :
572 : CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, &
573 : atomic_kind_set=atomic_kind_set, &
574 : cell=cell, particle_set=particle_set, &
575 : pw_env=pw_env, &
576 1204 : dft_control=dft_control)
577 :
578 1204 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
579 1204 : gridlevel_info => pw_env%gridlevel_info
580 :
581 : ! *** set up the pw multi-grids *** !
582 1204 : CPASSERT(ASSOCIATED(pw_env))
583 1204 : CALL pw_env_get(pw_env=pw_env, rs_grids=rs_rho, pw_pools=pw_pools)
584 :
585 1204 : CALL pw_pools_create_pws(pw_pools, mgrid_rspace)
586 :
587 1204 : CALL pw_pools_create_pws(pw_pools, mgrid_gspace)
588 :
589 : ! *** set up the rs multi-grids *** !
590 5960 : DO igrid_level = 1, gridlevel_info%ngrid_levels
591 5960 : CALL rs_grid_zero(rs_rho(igrid_level))
592 : END DO
593 :
594 : !take maxco from the LRI basis set!
595 : CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
596 1204 : maxco=maxco, basis_type=basis_type)
597 :
598 3612 : ALLOCATE (pab(maxco, 1))
599 1204 : offset = 0
600 1204 : my_pos = mgrid_rspace(1)%pw_grid%para%group%mepos
601 1204 : group_size = mgrid_rspace(1)%pw_grid%para%group%num_pe
602 :
603 3574 : DO ikind = 1, SIZE(atomic_kind_set)
604 :
605 2370 : CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
606 2370 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=lri_basis_set, basis_type=basis_type)
607 :
608 : !Take the lri basis set here!
609 : CALL get_gto_basis_set(gto_basis_set=lri_basis_set, lmax=la_max, &
610 : lmin=la_min, zet=zeta, nset=nseta, npgf=npgfa, &
611 2370 : sphi=sphi_a, first_sgf=first_sgfa, nsgf_set=nsgfa)
612 :
613 10714 : DO iatom = 1, natom
614 4770 : atom_a = atom_list(iatom)
615 4770 : IF (PRESENT(ATOMLIST)) THEN
616 1260 : IF (atomlist(atom_a) == 0) CYCLE
617 : END IF
618 4190 : ra(:) = pbc(particle_set(atom_a)%r, cell)
619 4190 : aci => lri_coef(ikind)%acoef(iatom, :)
620 :
621 67330 : m1 = MAXVAL(npgfa(1:nseta))
622 12570 : ALLOCATE (map_it(m1))
623 67330 : DO iset = 1, nseta
624 : ! collocate this set locally?
625 63140 : map_it = .FALSE.
626 131652 : DO ipgf = 1, npgfa(iset)
627 68512 : igrid_level = gaussian_gridlevel(gridlevel_info, zeta(ipgf, iset))
628 68512 : rs_grid => rs_rho(igrid_level)
629 131652 : map_it(ipgf) = map_gaussian_here(rs_grid, cell%h_inv, ra, offset, group_size, my_pos)
630 : END DO
631 63140 : offset = offset + 1
632 :
633 101586 : IF (ANY(map_it(1:npgfa(iset)))) THEN
634 31570 : sgfa = first_sgfa(1, iset)
635 31570 : ncoa = npgfa(iset)*ncoset(la_max(iset))
636 31570 : m1 = sgfa + nsgfa(iset) - 1
637 94710 : ALLOCATE (work(nsgfa(iset), 1))
638 476614 : work(1:nsgfa(iset), 1) = aci(sgfa:m1)
639 867677 : pab = 0._dp
640 :
641 : CALL dgemm("N", "N", ncoa, 1, nsgfa(iset), 1.0_dp, lri_basis_set%sphi(1, sgfa), &
642 : SIZE(lri_basis_set%sphi, 1), work(1, 1), SIZE(work, 1), 0.0_dp, pab(1, 1), &
643 31570 : SIZE(pab, 1))
644 :
645 65826 : DO ipgf = 1, npgfa(iset)
646 34256 : na1 = (ipgf - 1)*ncoset(la_max(iset))
647 34256 : igrid_level = gaussian_gridlevel(gridlevel_info, zeta(ipgf, iset))
648 34256 : rs_grid => rs_rho(igrid_level)
649 65826 : IF (map_it(ipgf)) THEN
650 : radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
651 : lb_min=0, lb_max=0, &
652 : ra=ra, rb=ra, rp=ra, &
653 : zetp=zeta(ipgf, iset), eps=eps_rho_rspace, &
654 34256 : prefactor=1.0_dp, cutoff=1.0_dp)
655 :
656 : CALL collocate_pgf_product(la_max=la_max(iset), &
657 : zeta=zeta(ipgf, iset), &
658 : la_min=la_min(iset), &
659 : lb_max=0, zetb=0.0_dp, lb_min=0, &
660 : ra=ra, rab=[0.0_dp, 0.0_dp, 0.0_dp], &
661 : scale=1._dp, &
662 : pab=pab, o1=na1, o2=0, &
663 : rsgrid=rs_grid, &
664 : radius=radius, &
665 34256 : ga_gb_function=GRID_FUNC_AB)
666 : END IF
667 : END DO
668 31570 : DEALLOCATE (work)
669 : END IF
670 : END DO
671 7140 : DEALLOCATE (map_it)
672 : END DO
673 : END DO
674 :
675 1204 : DEALLOCATE (pab)
676 :
677 : ! process the one-center terms
678 1204 : IF (exact_1c_terms) THEN
679 : ! find maximum numbers
680 48 : offset = 0
681 : CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
682 : maxco=maxco, &
683 : maxsgf_set=maxsgf_set, &
684 48 : basis_type="ORB")
685 336 : ALLOCATE (pab(maxco, maxco), work(maxco, maxsgf_set))
686 :
687 144 : DO ikind = 1, SIZE(atomic_kind_set)
688 96 : CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
689 96 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, basis_type="ORB")
690 : CALL get_gto_basis_set(gto_basis_set=orb_basis_set, lmax=la_max, &
691 : lmin=la_min, zet=zeta, nset=nseta, npgf=npgfa, &
692 96 : sphi=sphi_a, first_sgf=first_sgfa, nsgf_set=nsgfa)
693 528 : DO iatom = 1, natom
694 288 : atom_a = atom_list(iatom)
695 288 : ra(:) = pbc(particle_set(atom_a)%r, cell)
696 288 : CALL dbcsr_get_block_p(matrix=pmat, row=atom_a, col=atom_a, BLOCK=p_block, found=found)
697 576 : m1 = MAXVAL(npgfa(1:nseta))
698 1152 : ALLOCATE (map_it2(m1, m1))
699 576 : DO iset = 1, nseta
700 864 : DO jset = 1, nseta
701 : ! processor mappint
702 288 : map_it2 = .FALSE.
703 2304 : DO ipgf = 1, npgfa(iset)
704 16416 : DO jpgf = 1, npgfa(jset)
705 14112 : zetp = zeta(ipgf, iset) + zeta(jpgf, jset)
706 14112 : igrid_level = gaussian_gridlevel(gridlevel_info, zetp)
707 14112 : rs_grid => rs_rho(igrid_level)
708 16128 : map_it2(ipgf, jpgf) = map_gaussian_here(rs_grid, cell%h_inv, ra, offset, group_size, my_pos)
709 : END DO
710 : END DO
711 288 : offset = offset + 1
712 : !
713 8640 : IF (ANY(map_it2(1:npgfa(iset), 1:npgfa(jset)))) THEN
714 144 : ncoa = npgfa(iset)*ncoset(la_max(iset))
715 144 : sgfa = first_sgfa(1, iset)
716 144 : ncob = npgfa(jset)*ncoset(la_max(jset))
717 144 : sgfb = first_sgfa(1, jset)
718 : ! decontract density block
719 : CALL dgemm("N", "N", ncoa, nsgfa(jset), nsgfa(iset), &
720 : 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
721 : p_block(sgfa, sgfb), SIZE(p_block, 1), &
722 144 : 0.0_dp, work(1, 1), maxco)
723 : CALL dgemm("N", "T", ncoa, ncob, nsgfa(jset), &
724 : 1.0_dp, work(1, 1), maxco, &
725 : sphi_a(1, sgfb), SIZE(sphi_a, 1), &
726 144 : 0.0_dp, pab(1, 1), maxco)
727 1152 : DO ipgf = 1, npgfa(iset)
728 8208 : DO jpgf = 1, npgfa(jset)
729 7056 : zetp = zeta(ipgf, iset) + zeta(jpgf, jset)
730 7056 : igrid_level = gaussian_gridlevel(gridlevel_info, zetp)
731 7056 : rs_grid => rs_rho(igrid_level)
732 :
733 7056 : na1 = (ipgf - 1)*ncoset(la_max(iset))
734 7056 : nb1 = (jpgf - 1)*ncoset(la_max(jset))
735 :
736 8064 : IF (map_it2(ipgf, jpgf)) THEN
737 : radius = exp_radius_very_extended(la_min=la_min(iset), &
738 : la_max=la_max(iset), &
739 : lb_min=la_min(jset), &
740 : lb_max=la_max(jset), &
741 : ra=ra, rb=ra, rp=ra, &
742 : zetp=zetp, eps=eps_rho_rspace, &
743 7056 : prefactor=1.0_dp, cutoff=1.0_dp)
744 :
745 : CALL collocate_pgf_product( &
746 : la_max(iset), zeta(ipgf, iset), la_min(iset), &
747 : la_max(jset), zeta(jpgf, jset), la_min(jset), &
748 : ra, [0.0_dp, 0.0_dp, 0.0_dp], 1.0_dp, pab, na1, nb1, &
749 : rs_grid, &
750 7056 : radius=radius, ga_gb_function=GRID_FUNC_AB)
751 : END IF
752 : END DO
753 : END DO
754 : END IF
755 : END DO
756 : END DO
757 672 : DEALLOCATE (map_it2)
758 : !
759 : END DO
760 : END DO
761 96 : DEALLOCATE (pab, work)
762 : END IF
763 :
764 1204 : CALL pw_zero(lri_rho_g)
765 1204 : CALL pw_zero(lri_rho_r)
766 :
767 5960 : DO igrid_level = 1, gridlevel_info%ngrid_levels
768 4756 : CALL pw_zero(mgrid_rspace(igrid_level))
769 : CALL transfer_rs2pw(rs=rs_rho(igrid_level), &
770 5960 : pw=mgrid_rspace(igrid_level))
771 : END DO
772 :
773 5960 : DO igrid_level = 1, gridlevel_info%ngrid_levels
774 4756 : CALL pw_zero(mgrid_gspace(igrid_level))
775 : CALL pw_transfer(mgrid_rspace(igrid_level), &
776 4756 : mgrid_gspace(igrid_level))
777 5960 : CALL pw_axpy(mgrid_gspace(igrid_level), lri_rho_g)
778 : END DO
779 1204 : CALL pw_transfer(lri_rho_g, lri_rho_r)
780 1204 : total_rho = pw_integrate_function(lri_rho_r, isign=-1)
781 :
782 : ! *** give back the multi-grids *** !
783 1204 : CALL pw_pools_give_back_pws(pw_pools, mgrid_gspace)
784 1204 : CALL pw_pools_give_back_pws(pw_pools, mgrid_rspace)
785 :
786 1204 : CALL timestop(handle)
787 :
788 3612 : END SUBROUTINE calculate_lri_rho_elec
789 :
790 : #:for kind in ["r3d_rs", "c1d_gs"]
791 : ! **************************************************************************************************
792 : !> \brief computes the density of the core charges on the grid
793 : !> \param rho_core ...
794 : !> \param total_rho ...
795 : !> \param qs_env ...
796 : !> \param calpha ...
797 : !> \param ccore ...
798 : !> \param only_nopaw ...
799 : ! **************************************************************************************************
800 11220 : SUBROUTINE calculate_rho_core_${kind}$ (rho_core, total_rho, qs_env, calpha, ccore, only_nopaw)
801 :
802 : TYPE(pw_${kind}$_type), INTENT(INOUT) :: rho_core
803 : REAL(KIND=dp), INTENT(OUT) :: total_rho
804 : TYPE(qs_environment_type), POINTER :: qs_env
805 : REAL(KIND=dp), DIMENSION(:), OPTIONAL :: calpha, ccore
806 : LOGICAL, INTENT(IN), OPTIONAL :: only_nopaw
807 :
808 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho_core'
809 :
810 : INTEGER :: atom_a, handle, iatom, ikind, ithread, &
811 : j, natom, npme, nthread, &
812 : subpatch_pattern
813 11220 : INTEGER, DIMENSION(:), POINTER :: atom_list, cores
814 : LOGICAL :: my_only_nopaw, paw_atom
815 : REAL(KIND=dp) :: alpha, eps_rho_rspace, radius
816 : REAL(KIND=dp), DIMENSION(3) :: ra
817 11220 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: pab
818 11220 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
819 : TYPE(cell_type), POINTER :: cell
820 : TYPE(dft_control_type), POINTER :: dft_control
821 11220 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
822 : TYPE(pw_env_type), POINTER :: pw_env
823 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
824 : TYPE(pw_r3d_rs_type) :: rhoc_r
825 11220 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
826 : TYPE(realspace_grid_type), POINTER :: rs_rho
827 :
828 11220 : CALL timeset(routineN, handle)
829 11220 : NULLIFY (cell, dft_control, pab, atomic_kind_set, qs_kind_set, particle_set, &
830 11220 : atom_list, pw_env, rs_rho, auxbas_pw_pool, cores)
831 11220 : ALLOCATE (pab(1, 1))
832 :
833 11220 : my_only_nopaw = .FALSE.
834 11220 : IF (PRESENT(only_nopaw)) my_only_nopaw = only_nopaw
835 11220 : IF (PRESENT(calpha)) THEN
836 634 : CPASSERT(PRESENT(ccore))
837 : END IF
838 :
839 : CALL get_qs_env(qs_env=qs_env, &
840 : atomic_kind_set=atomic_kind_set, &
841 : qs_kind_set=qs_kind_set, &
842 : cell=cell, &
843 : dft_control=dft_control, &
844 : particle_set=particle_set, &
845 11220 : pw_env=pw_env)
846 : CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
847 11220 : auxbas_pw_pool=auxbas_pw_pool)
848 : ! be careful in parallel nsmax is chosen with multigrid in mind!
849 11220 : CALL rs_grid_zero(rs_rho)
850 :
851 11220 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
852 :
853 31169 : DO ikind = 1, SIZE(atomic_kind_set)
854 19949 : CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
855 19949 : IF (PRESENT(calpha)) THEN
856 1246 : alpha = calpha(ikind)
857 1246 : pab(1, 1) = ccore(ikind)
858 : ELSE
859 18703 : CALL get_qs_kind(qs_kind_set(ikind), paw_atom=paw_atom)
860 18703 : IF (my_only_nopaw .AND. paw_atom) CYCLE
861 : CALL get_qs_kind(qs_kind_set(ikind), alpha_core_charge=alpha, &
862 18495 : ccore_charge=pab(1, 1))
863 : END IF
864 :
865 19741 : IF (my_only_nopaw .AND. paw_atom) CYCLE
866 19741 : IF (alpha == 0.0_dp .OR. pab(1, 1) == 0.0_dp) CYCLE
867 :
868 19541 : nthread = 1
869 19541 : ithread = 0
870 :
871 19541 : CALL reallocate(cores, 1, natom)
872 19541 : npme = 0
873 63374 : cores = 0
874 :
875 63374 : DO iatom = 1, natom
876 63374 : IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
877 : ! replicated realspace grid, split the atoms up between procs
878 43002 : IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
879 21501 : npme = npme + 1
880 21501 : cores(npme) = iatom
881 : END IF
882 : ELSE
883 831 : npme = npme + 1
884 831 : cores(npme) = iatom
885 : END IF
886 : END DO
887 :
888 50710 : IF (npme > 0) THEN
889 37829 : DO j = 1, npme
890 :
891 22332 : iatom = cores(j)
892 22332 : atom_a = atom_list(iatom)
893 22332 : ra(:) = pbc(particle_set(atom_a)%r, cell)
894 22332 : subpatch_pattern = 0
895 : radius = exp_radius_very_extended(la_min=0, la_max=0, &
896 : lb_min=0, lb_max=0, &
897 : ra=ra, rb=ra, rp=ra, &
898 : zetp=alpha, eps=eps_rho_rspace, &
899 : pab=pab, o1=0, o2=0, & ! without map_consistent
900 22332 : prefactor=-1.0_dp, cutoff=0.0_dp)
901 :
902 : CALL collocate_pgf_product(0, alpha, 0, 0, 0.0_dp, 0, ra, &
903 : [0.0_dp, 0.0_dp, 0.0_dp], -1.0_dp, pab, 0, 0, rs_rho, &
904 : radius=radius, ga_gb_function=GRID_FUNC_AB, &
905 37829 : use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
906 :
907 : END DO
908 : END IF
909 :
910 : END DO
911 :
912 11220 : IF (ASSOCIATED(cores)) THEN
913 11208 : DEALLOCATE (cores)
914 : END IF
915 11220 : DEALLOCATE (pab)
916 :
917 11220 : CALL auxbas_pw_pool%create_pw(rhoc_r)
918 :
919 11220 : CALL transfer_rs2pw(rs_rho, rhoc_r)
920 :
921 11220 : total_rho = pw_integrate_function(rhoc_r, isign=-1)
922 :
923 11220 : CALL pw_transfer(rhoc_r, rho_core)
924 :
925 11220 : CALL auxbas_pw_pool%give_back_pw(rhoc_r)
926 :
927 11220 : CALL timestop(handle)
928 :
929 11220 : END SUBROUTINE calculate_rho_core_${kind}$
930 : #:endfor
931 :
932 : ! *****************************************************************************
933 : !> \brief Computes the derivative of the density of the core charges with
934 : !> respect to the nuclear coordinates on the grid.
935 : !> \param drho_core The resulting density derivative
936 : !> \param qs_env ...
937 : !> \param beta Derivative direction
938 : !> \param lambda Atom index
939 : !> \note SL November 2014, ED 2021
940 : ! **************************************************************************************************
941 216 : SUBROUTINE calculate_drho_core(drho_core, qs_env, beta, lambda)
942 :
943 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: drho_core
944 : TYPE(qs_environment_type), POINTER :: qs_env
945 : INTEGER, INTENT(IN) :: beta, lambda
946 :
947 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_drho_core'
948 :
949 : INTEGER :: atom_a, dabqadb_func, handle, iatom, &
950 : ikind, ithread, j, natom, npme, &
951 : nthread, subpatch_pattern
952 216 : INTEGER, DIMENSION(:), POINTER :: atom_list, cores
953 : REAL(KIND=dp) :: alpha, eps_rho_rspace, radius
954 : REAL(KIND=dp), DIMENSION(3) :: ra
955 216 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: pab
956 216 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
957 : TYPE(cell_type), POINTER :: cell
958 : TYPE(dft_control_type), POINTER :: dft_control
959 216 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
960 : TYPE(pw_env_type), POINTER :: pw_env
961 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
962 : TYPE(pw_r3d_rs_type) :: rhoc_r
963 216 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
964 : TYPE(realspace_grid_type), POINTER :: rs_rho
965 :
966 216 : CALL timeset(routineN, handle)
967 216 : NULLIFY (cell, dft_control, pab, atomic_kind_set, qs_kind_set, particle_set, &
968 216 : atom_list, pw_env, rs_rho, auxbas_pw_pool, cores)
969 216 : ALLOCATE (pab(1, 1))
970 :
971 : CALL get_qs_env(qs_env=qs_env, &
972 : atomic_kind_set=atomic_kind_set, &
973 : qs_kind_set=qs_kind_set, &
974 : cell=cell, &
975 : dft_control=dft_control, &
976 : particle_set=particle_set, &
977 216 : pw_env=pw_env)
978 : CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
979 216 : auxbas_pw_pool=auxbas_pw_pool)
980 : ! be careful in parallel nsmax is chosen with multigrid in mind!
981 216 : CALL rs_grid_zero(rs_rho)
982 :
983 216 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
984 :
985 288 : SELECT CASE (beta)
986 : CASE (1)
987 72 : dabqadb_func = GRID_FUNC_CORE_X
988 : CASE (2)
989 72 : dabqadb_func = GRID_FUNC_CORE_Y
990 : CASE (3)
991 72 : dabqadb_func = GRID_FUNC_CORE_Z
992 : CASE DEFAULT
993 216 : CPABORT("invalid beta")
994 : END SELECT
995 648 : DO ikind = 1, SIZE(atomic_kind_set)
996 432 : CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
997 : CALL get_qs_kind(qs_kind_set(ikind), &
998 432 : alpha_core_charge=alpha, ccore_charge=pab(1, 1))
999 :
1000 432 : IF (alpha == 0.0_dp .OR. pab(1, 1) == 0.0_dp) CYCLE
1001 :
1002 432 : nthread = 1
1003 432 : ithread = 0
1004 :
1005 432 : CALL reallocate(cores, 1, natom)
1006 432 : npme = 0
1007 1080 : cores = 0
1008 :
1009 1080 : DO iatom = 1, natom
1010 1080 : IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
1011 : ! replicated realspace grid, split the atoms up between procs
1012 648 : IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
1013 324 : npme = npme + 1
1014 324 : cores(npme) = iatom
1015 : END IF
1016 : ELSE
1017 0 : npme = npme + 1
1018 0 : cores(npme) = iatom
1019 : END IF
1020 : END DO
1021 :
1022 1080 : IF (npme > 0) THEN
1023 648 : DO j = 1, npme
1024 :
1025 324 : iatom = cores(j)
1026 324 : atom_a = atom_list(iatom)
1027 324 : IF (atom_a /= lambda) CYCLE
1028 108 : ra(:) = pbc(particle_set(atom_a)%r, cell)
1029 108 : subpatch_pattern = 0
1030 : radius = exp_radius_very_extended(la_min=0, la_max=0, &
1031 : lb_min=0, lb_max=0, &
1032 : ra=ra, rb=ra, rp=ra, &
1033 : zetp=alpha, eps=eps_rho_rspace, &
1034 : pab=pab, o1=0, o2=0, & ! without map_consistent
1035 108 : prefactor=-1.0_dp, cutoff=0.0_dp)
1036 :
1037 : CALL collocate_pgf_product(0, alpha, 0, 0, 0.0_dp, 0, ra, &
1038 : [0.0_dp, 0.0_dp, 0.0_dp], -1.0_dp, pab, 0, 0, rs_rho, &
1039 : radius=radius, ga_gb_function=dabqadb_func, &
1040 648 : use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
1041 :
1042 : END DO
1043 : END IF
1044 :
1045 : END DO
1046 :
1047 216 : IF (ASSOCIATED(cores)) THEN
1048 216 : DEALLOCATE (cores)
1049 : END IF
1050 216 : DEALLOCATE (pab)
1051 :
1052 216 : CALL auxbas_pw_pool%create_pw(rhoc_r)
1053 :
1054 216 : CALL transfer_rs2pw(rs_rho, rhoc_r)
1055 :
1056 216 : CALL pw_transfer(rhoc_r, drho_core)
1057 :
1058 216 : CALL auxbas_pw_pool%give_back_pw(rhoc_r)
1059 :
1060 216 : CALL timestop(handle)
1061 :
1062 216 : END SUBROUTINE calculate_drho_core
1063 :
1064 : ! **************************************************************************************************
1065 : !> \brief collocate a single Gaussian on the grid
1066 : !> \param rho_gb charge density generated by a single gaussian
1067 : !> \param qs_env qs environment
1068 : !> \param iatom_in atom index
1069 : !> \par History
1070 : !> 12.2011 created
1071 : !> \author Dorothea Golze
1072 : ! **************************************************************************************************
1073 4 : SUBROUTINE calculate_rho_single_gaussian(rho_gb, qs_env, iatom_in)
1074 :
1075 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_gb
1076 : TYPE(qs_environment_type), POINTER :: qs_env
1077 : INTEGER, INTENT(IN) :: iatom_in
1078 :
1079 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho_single_gaussian'
1080 :
1081 : INTEGER :: atom_a, handle, iatom, npme, &
1082 : subpatch_pattern
1083 : REAL(KIND=dp) :: eps_rho_rspace, radius
1084 : REAL(KIND=dp), DIMENSION(3) :: ra
1085 4 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: pab
1086 : TYPE(cell_type), POINTER :: cell
1087 : TYPE(dft_control_type), POINTER :: dft_control
1088 : TYPE(pw_env_type), POINTER :: pw_env
1089 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1090 : TYPE(pw_r3d_rs_type) :: rhoc_r
1091 : TYPE(realspace_grid_type), POINTER :: rs_rho
1092 :
1093 4 : CALL timeset(routineN, handle)
1094 4 : NULLIFY (cell, dft_control, pab, pw_env, rs_rho, auxbas_pw_pool)
1095 :
1096 4 : ALLOCATE (pab(1, 1))
1097 :
1098 : CALL get_qs_env(qs_env=qs_env, &
1099 : cell=cell, &
1100 : dft_control=dft_control, &
1101 4 : pw_env=pw_env)
1102 : CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
1103 4 : auxbas_pw_pool=auxbas_pw_pool)
1104 4 : CALL rs_grid_zero(rs_rho)
1105 :
1106 4 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
1107 4 : pab(1, 1) = 1.0_dp
1108 4 : iatom = iatom_in
1109 :
1110 4 : npme = 0
1111 :
1112 4 : IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
1113 4 : IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
1114 : npme = npme + 1
1115 : END IF
1116 : ELSE
1117 : npme = npme + 1
1118 : END IF
1119 :
1120 : IF (npme > 0) THEN
1121 2 : atom_a = qs_env%qmmm_env_qm%image_charge_pot%image_mm_list(iatom)
1122 2 : ra(:) = pbc(qs_env%qmmm_env_qm%image_charge_pot%particles_all(atom_a)%r, cell)
1123 2 : subpatch_pattern = 0
1124 : radius = exp_radius_very_extended(la_min=0, la_max=0, &
1125 : lb_min=0, lb_max=0, &
1126 : ra=ra, rb=ra, rp=ra, &
1127 : zetp=qs_env%qmmm_env_qm%image_charge_pot%eta, &
1128 : eps=eps_rho_rspace, &
1129 : pab=pab, o1=0, o2=0, & ! without map_consistent
1130 2 : prefactor=1.0_dp, cutoff=0.0_dp)
1131 :
1132 : CALL collocate_pgf_product(0, qs_env%qmmm_env_qm%image_charge_pot%eta, &
1133 : 0, 0, 0.0_dp, 0, ra, [0.0_dp, 0.0_dp, 0.0_dp], 1.0_dp, pab, 0, 0, rs_rho, &
1134 : radius=radius, ga_gb_function=GRID_FUNC_AB, &
1135 2 : use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
1136 : END IF
1137 :
1138 4 : DEALLOCATE (pab)
1139 :
1140 4 : CALL auxbas_pw_pool%create_pw(rhoc_r)
1141 :
1142 4 : CALL transfer_rs2pw(rs_rho, rhoc_r)
1143 :
1144 4 : CALL pw_transfer(rhoc_r, rho_gb)
1145 :
1146 4 : CALL auxbas_pw_pool%give_back_pw(rhoc_r)
1147 :
1148 4 : CALL timestop(handle)
1149 :
1150 4 : END SUBROUTINE calculate_rho_single_gaussian
1151 :
1152 : ! **************************************************************************************************
1153 : !> \brief computes the image charge density on the grid (including coeffcients)
1154 : !> \param rho_metal image charge density
1155 : !> \param coeff expansion coefficients of the image charge density, i.e.
1156 : !> rho_metal=sum_a c_a*g_a
1157 : !> \param total_rho_metal total induced image charge density
1158 : !> \param qs_env qs environment
1159 : !> \par History
1160 : !> 01.2012 created
1161 : !> \author Dorothea Golze
1162 : ! **************************************************************************************************
1163 90 : SUBROUTINE calculate_rho_metal(rho_metal, coeff, total_rho_metal, qs_env)
1164 :
1165 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_metal
1166 : REAL(KIND=dp), DIMENSION(:), POINTER :: coeff
1167 : REAL(KIND=dp), INTENT(OUT), OPTIONAL :: total_rho_metal
1168 : TYPE(qs_environment_type), POINTER :: qs_env
1169 :
1170 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho_metal'
1171 :
1172 : INTEGER :: atom_a, handle, iatom, j, natom, npme, &
1173 : subpatch_pattern
1174 90 : INTEGER, DIMENSION(:), POINTER :: cores
1175 : REAL(KIND=dp) :: eps_rho_rspace, radius
1176 : REAL(KIND=dp), DIMENSION(3) :: ra
1177 90 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: pab
1178 : TYPE(cell_type), POINTER :: cell
1179 : TYPE(dft_control_type), POINTER :: dft_control
1180 : TYPE(pw_env_type), POINTER :: pw_env
1181 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1182 : TYPE(pw_r3d_rs_type) :: rhoc_r
1183 : TYPE(realspace_grid_type), POINTER :: rs_rho
1184 :
1185 90 : CALL timeset(routineN, handle)
1186 :
1187 90 : NULLIFY (cell, dft_control, pab, pw_env, rs_rho, auxbas_pw_pool, cores)
1188 :
1189 90 : ALLOCATE (pab(1, 1))
1190 :
1191 : CALL get_qs_env(qs_env=qs_env, &
1192 : cell=cell, &
1193 : dft_control=dft_control, &
1194 90 : pw_env=pw_env)
1195 : CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
1196 90 : auxbas_pw_pool=auxbas_pw_pool)
1197 90 : CALL rs_grid_zero(rs_rho)
1198 :
1199 90 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
1200 90 : pab(1, 1) = 1.0_dp
1201 :
1202 90 : natom = SIZE(qs_env%qmmm_env_qm%image_charge_pot%image_mm_list)
1203 :
1204 90 : CALL reallocate(cores, 1, natom)
1205 90 : npme = 0
1206 270 : cores = 0
1207 :
1208 270 : DO iatom = 1, natom
1209 270 : IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
1210 180 : IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
1211 90 : npme = npme + 1
1212 90 : cores(npme) = iatom
1213 : END IF
1214 : ELSE
1215 0 : npme = npme + 1
1216 0 : cores(npme) = iatom
1217 : END IF
1218 : END DO
1219 :
1220 90 : IF (npme > 0) THEN
1221 180 : DO j = 1, npme
1222 90 : iatom = cores(j)
1223 90 : atom_a = qs_env%qmmm_env_qm%image_charge_pot%image_mm_list(iatom)
1224 90 : ra(:) = pbc(qs_env%qmmm_env_qm%image_charge_pot%particles_all(atom_a)%r, cell)
1225 90 : subpatch_pattern = 0
1226 : radius = exp_radius_very_extended(la_min=0, la_max=0, &
1227 : lb_min=0, lb_max=0, &
1228 : ra=ra, rb=ra, rp=ra, &
1229 : zetp=qs_env%qmmm_env_qm%image_charge_pot%eta, &
1230 : eps=eps_rho_rspace, &
1231 : pab=pab, o1=0, o2=0, & ! without map_consistent
1232 90 : prefactor=coeff(iatom), cutoff=0.0_dp)
1233 :
1234 : CALL collocate_pgf_product( &
1235 : 0, qs_env%qmmm_env_qm%image_charge_pot%eta, &
1236 : 0, 0, 0.0_dp, 0, ra, [0.0_dp, 0.0_dp, 0.0_dp], coeff(iatom), pab, 0, 0, rs_rho, &
1237 : radius=radius, ga_gb_function=GRID_FUNC_AB, &
1238 180 : use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
1239 : END DO
1240 : END IF
1241 :
1242 90 : DEALLOCATE (pab, cores)
1243 :
1244 90 : CALL auxbas_pw_pool%create_pw(rhoc_r)
1245 :
1246 90 : CALL transfer_rs2pw(rs_rho, rhoc_r)
1247 :
1248 90 : IF (PRESENT(total_rho_metal)) THEN
1249 : !minus sign: account for the fact that rho_metal has opposite sign
1250 90 : total_rho_metal = pw_integrate_function(rhoc_r, isign=-1)
1251 : END IF
1252 :
1253 90 : CALL pw_transfer(rhoc_r, rho_metal)
1254 90 : CALL auxbas_pw_pool%give_back_pw(rhoc_r)
1255 :
1256 90 : CALL timestop(handle)
1257 :
1258 90 : END SUBROUTINE calculate_rho_metal
1259 :
1260 : ! **************************************************************************************************
1261 : !> \brief collocate a single Gaussian on the grid for periodic RESP fitting
1262 : !> \param rho_gb charge density generated by a single gaussian
1263 : !> \param qs_env qs environment
1264 : !> \param eta width of single Gaussian
1265 : !> \param iatom_in atom index
1266 : !> \par History
1267 : !> 06.2012 created
1268 : !> \author Dorothea Golze
1269 : ! **************************************************************************************************
1270 66 : SUBROUTINE calculate_rho_resp_single(rho_gb, qs_env, eta, iatom_in)
1271 :
1272 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_gb
1273 : TYPE(qs_environment_type), POINTER :: qs_env
1274 : REAL(KIND=dp), INTENT(IN) :: eta
1275 : INTEGER, INTENT(IN) :: iatom_in
1276 :
1277 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho_resp_single'
1278 :
1279 : INTEGER :: handle, iatom, npme, subpatch_pattern
1280 : REAL(KIND=dp) :: eps_rho_rspace, radius
1281 : REAL(KIND=dp), DIMENSION(3) :: ra
1282 66 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: pab
1283 : TYPE(cell_type), POINTER :: cell
1284 : TYPE(dft_control_type), POINTER :: dft_control
1285 66 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1286 : TYPE(pw_env_type), POINTER :: pw_env
1287 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1288 : TYPE(pw_r3d_rs_type) :: rhoc_r
1289 : TYPE(realspace_grid_type), POINTER :: rs_rho
1290 :
1291 66 : CALL timeset(routineN, handle)
1292 66 : NULLIFY (cell, dft_control, pab, pw_env, rs_rho, auxbas_pw_pool, &
1293 66 : particle_set)
1294 :
1295 66 : ALLOCATE (pab(1, 1))
1296 :
1297 : CALL get_qs_env(qs_env=qs_env, &
1298 : cell=cell, &
1299 : dft_control=dft_control, &
1300 : particle_set=particle_set, &
1301 66 : pw_env=pw_env)
1302 : CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
1303 66 : auxbas_pw_pool=auxbas_pw_pool)
1304 66 : CALL rs_grid_zero(rs_rho)
1305 :
1306 66 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
1307 66 : pab(1, 1) = 1.0_dp
1308 66 : iatom = iatom_in
1309 :
1310 66 : npme = 0
1311 :
1312 66 : IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
1313 66 : IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
1314 : npme = npme + 1
1315 : END IF
1316 : ELSE
1317 : npme = npme + 1
1318 : END IF
1319 :
1320 : IF (npme > 0) THEN
1321 33 : ra(:) = pbc(particle_set(iatom)%r, cell)
1322 33 : subpatch_pattern = 0
1323 : radius = exp_radius_very_extended(la_min=0, la_max=0, &
1324 : lb_min=0, lb_max=0, &
1325 : ra=ra, rb=ra, rp=ra, &
1326 : zetp=eta, eps=eps_rho_rspace, &
1327 : pab=pab, o1=0, o2=0, & ! without map_consistent
1328 33 : prefactor=1.0_dp, cutoff=0.0_dp)
1329 :
1330 : CALL collocate_pgf_product(0, eta, 0, 0, 0.0_dp, 0, ra, &
1331 : [0.0_dp, 0.0_dp, 0.0_dp], 1.0_dp, pab, 0, 0, rs_rho, &
1332 : radius=radius, ga_gb_function=GRID_FUNC_AB, &
1333 33 : use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
1334 : END IF
1335 :
1336 66 : DEALLOCATE (pab)
1337 :
1338 66 : CALL auxbas_pw_pool%create_pw(rhoc_r)
1339 :
1340 66 : CALL transfer_rs2pw(rs_rho, rhoc_r)
1341 :
1342 66 : CALL pw_transfer(rhoc_r, rho_gb)
1343 :
1344 66 : CALL auxbas_pw_pool%give_back_pw(rhoc_r)
1345 :
1346 66 : CALL timestop(handle)
1347 :
1348 66 : END SUBROUTINE calculate_rho_resp_single
1349 :
1350 : #:for kind in ["r3d_rs", "c1d_gs"]
1351 : ! **************************************************************************************************
1352 : !> \brief computes the RESP charge density on a grid based on the RESP charges
1353 : !> \param rho_resp RESP charge density
1354 : !> \param coeff RESP charges, take care of normalization factor
1355 : !> (eta/pi)**1.5 later
1356 : !> \param natom number of atoms
1357 : !> \param eta width of single Gaussian
1358 : !> \param qs_env qs environment
1359 : !> \par History
1360 : !> 01.2012 created
1361 : !> \author Dorothea Golze
1362 : ! **************************************************************************************************
1363 24 : SUBROUTINE calculate_rho_resp_all_${kind}$ (rho_resp, coeff, natom, eta, qs_env)
1364 :
1365 : TYPE(pw_${kind}$_type), INTENT(INOUT) :: rho_resp
1366 : REAL(KIND=dp), DIMENSION(:), POINTER :: coeff
1367 : INTEGER, INTENT(IN) :: natom
1368 : REAL(KIND=dp), INTENT(IN) :: eta
1369 : TYPE(qs_environment_type), POINTER :: qs_env
1370 :
1371 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho_resp_all'
1372 :
1373 : INTEGER :: handle, iatom, j, npme, subpatch_pattern
1374 24 : INTEGER, DIMENSION(:), POINTER :: cores
1375 : REAL(KIND=dp) :: eps_rho_rspace, radius
1376 : REAL(KIND=dp), DIMENSION(3) :: ra
1377 24 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: pab
1378 : TYPE(cell_type), POINTER :: cell
1379 : TYPE(dft_control_type), POINTER :: dft_control
1380 24 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1381 : TYPE(pw_env_type), POINTER :: pw_env
1382 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1383 : TYPE(pw_r3d_rs_type) :: rhoc_r
1384 : TYPE(realspace_grid_type), POINTER :: rs_rho
1385 :
1386 24 : CALL timeset(routineN, handle)
1387 :
1388 24 : NULLIFY (cell, cores, dft_control, pab, pw_env, rs_rho, auxbas_pw_pool, &
1389 24 : particle_set)
1390 :
1391 24 : ALLOCATE (pab(1, 1))
1392 :
1393 : CALL get_qs_env(qs_env=qs_env, &
1394 : cell=cell, &
1395 : dft_control=dft_control, &
1396 : particle_set=particle_set, &
1397 24 : pw_env=pw_env)
1398 : CALL pw_env_get(pw_env, auxbas_rs_grid=rs_rho, &
1399 24 : auxbas_pw_pool=auxbas_pw_pool)
1400 24 : CALL rs_grid_zero(rs_rho)
1401 :
1402 24 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
1403 24 : pab(1, 1) = 1.0_dp
1404 :
1405 24 : CALL reallocate(cores, 1, natom)
1406 24 : npme = 0
1407 142 : cores = 0
1408 :
1409 142 : DO iatom = 1, natom
1410 142 : IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
1411 118 : IF (MODULO(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
1412 59 : npme = npme + 1
1413 59 : cores(npme) = iatom
1414 : END IF
1415 : ELSE
1416 0 : npme = npme + 1
1417 0 : cores(npme) = iatom
1418 : END IF
1419 : END DO
1420 :
1421 24 : IF (npme > 0) THEN
1422 83 : DO j = 1, npme
1423 59 : iatom = cores(j)
1424 59 : ra(:) = pbc(particle_set(iatom)%r, cell)
1425 59 : subpatch_pattern = 0
1426 : radius = exp_radius_very_extended(la_min=0, la_max=0, &
1427 : lb_min=0, lb_max=0, &
1428 : ra=ra, rb=ra, rp=ra, &
1429 : zetp=eta, eps=eps_rho_rspace, &
1430 : pab=pab, o1=0, o2=0, & ! without map_consistent
1431 59 : prefactor=coeff(iatom), cutoff=0.0_dp)
1432 :
1433 : CALL collocate_pgf_product( &
1434 : 0, eta, &
1435 : 0, 0, 0.0_dp, 0, ra, [0.0_dp, 0.0_dp, 0.0_dp], coeff(iatom), pab, 0, 0, rs_rho, &
1436 : radius=radius, ga_gb_function=GRID_FUNC_AB, &
1437 83 : use_subpatch=.TRUE., subpatch_pattern=subpatch_pattern)
1438 : END DO
1439 : END IF
1440 :
1441 24 : DEALLOCATE (pab, cores)
1442 :
1443 24 : CALL auxbas_pw_pool%create_pw(rhoc_r)
1444 :
1445 24 : CALL transfer_rs2pw(rs_rho, rhoc_r)
1446 :
1447 24 : CALL pw_transfer(rhoc_r, rho_resp)
1448 24 : CALL auxbas_pw_pool%give_back_pw(rhoc_r)
1449 :
1450 24 : CALL timestop(handle)
1451 :
1452 24 : END SUBROUTINE calculate_rho_resp_all_${kind}$
1453 : #:endfor
1454 :
1455 : ! **************************************************************************************************
1456 : !> \brief computes the density corresponding to a given density matrix on the grid
1457 : !> \param matrix_p ...
1458 : !> \param matrix_p_kp ...
1459 : !> \param rho ...
1460 : !> \param rho_gspace ...
1461 : !> \param total_rho ...
1462 : !> \param ks_env ...
1463 : !> \param soft_valid ...
1464 : !> \param compute_tau ...
1465 : !> \param compute_grad ...
1466 : !> \param basis_type ...
1467 : !> \param der_type ...
1468 : !> \param idir ...
1469 : !> \param task_list_external ...
1470 : !> \param pw_env_external ...
1471 : !> \par History
1472 : !> IAB (15-Feb-2010): Added OpenMP parallelisation to task loop
1473 : !> (c) The Numerical Algorithms Group (NAG) Ltd, 2010 on behalf of the HECToR project
1474 : !> Anything that is not the default ORB basis_type requires an external_task_list 12.2019, (A.Bussy)
1475 : !> Ole Schuett (2020): Migrated to C, see grid_api.F
1476 : !> \note
1477 : !> both rho and rho_gspace contain the new rho
1478 : !> (in real and g-space respectively)
1479 : ! **************************************************************************************************
1480 238534 : SUBROUTINE calculate_rho_elec(matrix_p, matrix_p_kp, rho, rho_gspace, total_rho, &
1481 : ks_env, soft_valid, compute_tau, compute_grad, &
1482 : basis_type, der_type, idir, task_list_external, pw_env_external)
1483 :
1484 : TYPE(dbcsr_type), OPTIONAL, TARGET :: matrix_p
1485 : TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
1486 : POINTER :: matrix_p_kp
1487 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: rho
1488 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_gspace
1489 : REAL(KIND=dp), INTENT(OUT), OPTIONAL :: total_rho
1490 : TYPE(qs_ks_env_type), POINTER :: ks_env
1491 : LOGICAL, INTENT(IN), OPTIONAL :: soft_valid, compute_tau, compute_grad
1492 : CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: basis_type
1493 : INTEGER, INTENT(IN), OPTIONAL :: der_type, idir
1494 : TYPE(task_list_type), OPTIONAL, POINTER :: task_list_external
1495 : TYPE(pw_env_type), OPTIONAL, POINTER :: pw_env_external
1496 :
1497 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho_elec'
1498 :
1499 : CHARACTER(LEN=default_string_length) :: my_basis_type
1500 : INTEGER :: ga_gb_function, handle, ilevel, img, &
1501 : nimages, nlevels
1502 : LOGICAL :: any_distributed, my_compute_grad, &
1503 : my_compute_tau, my_soft_valid
1504 238534 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_images
1505 : TYPE(dft_control_type), POINTER :: dft_control
1506 : TYPE(mp_comm_type) :: group
1507 : TYPE(pw_env_type), POINTER :: pw_env
1508 238534 : TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_rho
1509 : TYPE(task_list_type), POINTER :: task_list
1510 :
1511 238534 : CALL timeset(routineN, handle)
1512 :
1513 238534 : NULLIFY (matrix_images, dft_control, pw_env, rs_rho, task_list)
1514 :
1515 : ! Figure out which function to collocate.
1516 238534 : my_compute_tau = .FALSE.
1517 238534 : IF (PRESENT(compute_tau)) my_compute_tau = compute_tau
1518 238534 : my_compute_grad = .FALSE.
1519 238534 : IF (PRESENT(compute_grad)) my_compute_grad = compute_grad
1520 238534 : IF (PRESENT(der_type)) THEN
1521 84 : SELECT CASE (der_type)
1522 : CASE (orb_s)
1523 36 : ga_gb_function = GRID_FUNC_AB
1524 : CASE (orb_px)
1525 0 : ga_gb_function = GRID_FUNC_DX
1526 : CASE (orb_py)
1527 0 : ga_gb_function = GRID_FUNC_DY
1528 : CASE (orb_pz)
1529 12 : ga_gb_function = GRID_FUNC_DZ
1530 : CASE (orb_dxy)
1531 0 : ga_gb_function = GRID_FUNC_DXDY
1532 : CASE (orb_dyz)
1533 0 : ga_gb_function = GRID_FUNC_DYDZ
1534 : CASE (orb_dzx)
1535 0 : ga_gb_function = GRID_FUNC_DZDX
1536 : CASE (orb_dx2)
1537 0 : ga_gb_function = GRID_FUNC_DXDX
1538 : CASE (orb_dy2)
1539 0 : ga_gb_function = GRID_FUNC_DYDY
1540 : CASE (orb_dz2)
1541 0 : ga_gb_function = GRID_FUNC_DZDZ
1542 : CASE DEFAULT
1543 48 : CPABORT("Unknown der_type")
1544 : END SELECT
1545 238486 : ELSE IF (my_compute_tau) THEN
1546 6630 : ga_gb_function = GRID_FUNC_DADB
1547 231856 : ELSE IF (my_compute_grad) THEN
1548 324 : CPASSERT(PRESENT(idir))
1549 432 : SELECT CASE (idir)
1550 : CASE (1)
1551 108 : ga_gb_function = GRID_FUNC_DABpADB_X
1552 : CASE (2)
1553 108 : ga_gb_function = GRID_FUNC_DABpADB_Y
1554 : CASE (3)
1555 108 : ga_gb_function = GRID_FUNC_DABpADB_Z
1556 : CASE DEFAULT
1557 324 : CPABORT("invalid idir")
1558 : END SELECT
1559 : ELSE
1560 231532 : ga_gb_function = GRID_FUNC_AB
1561 : END IF
1562 :
1563 : ! Figure out which basis_type to use.
1564 238534 : my_basis_type = "ORB" ! by default, the full density is calculated
1565 238534 : IF (PRESENT(basis_type)) my_basis_type = basis_type
1566 238534 : CPASSERT(my_basis_type == "ORB" .OR. PRESENT(task_list_external))
1567 :
1568 : ! Figure out which task_list to use.
1569 238534 : my_soft_valid = .FALSE.
1570 238534 : IF (PRESENT(soft_valid)) my_soft_valid = soft_valid
1571 238534 : IF (PRESENT(task_list_external)) THEN
1572 45772 : task_list => task_list_external
1573 192762 : ELSE IF (my_soft_valid) THEN
1574 38370 : CALL get_ks_env(ks_env, task_list_soft=task_list)
1575 : ELSE
1576 154392 : CALL get_ks_env(ks_env, task_list=task_list)
1577 : END IF
1578 238534 : CPASSERT(ASSOCIATED(task_list))
1579 :
1580 : ! Figure out which pw_env to use.
1581 238534 : IF (PRESENT(pw_env_external)) THEN
1582 25002 : pw_env => pw_env_external
1583 : ELSE
1584 213532 : CALL get_ks_env(ks_env, pw_env=pw_env)
1585 : END IF
1586 238534 : CPASSERT(ASSOCIATED(pw_env))
1587 :
1588 : ! Get grids.
1589 238534 : CALL pw_env_get(pw_env, rs_grids=rs_rho)
1590 238534 : nlevels = SIZE(rs_rho)
1591 238534 : group = rs_rho(1)%desc%group
1592 :
1593 : ! Check if any of the grids is distributed.
1594 238534 : any_distributed = .FALSE.
1595 1181808 : DO ilevel = 1, nlevels
1596 2124174 : any_distributed = any_distributed .OR. rs_rho(ilevel)%desc%distributed
1597 : END DO
1598 :
1599 : ! Gather all matrix images in a single array.
1600 238534 : CALL get_ks_env(ks_env, dft_control=dft_control)
1601 238534 : nimages = dft_control%nimages
1602 1412742 : ALLOCATE (matrix_images(nimages))
1603 238534 : IF (PRESENT(matrix_p_kp)) THEN
1604 203772 : CPASSERT(.NOT. PRESENT(matrix_p))
1605 866150 : DO img = 1, nimages
1606 866150 : matrix_images(img)%matrix => matrix_p_kp(img)%matrix
1607 : END DO
1608 : ELSE
1609 34762 : CPASSERT(PRESENT(matrix_p) .AND. nimages == 1)
1610 34762 : matrix_images(1)%matrix => matrix_p
1611 : END IF
1612 :
1613 : ! Distribute matrix blocks.
1614 238534 : IF (any_distributed) THEN
1615 230 : CALL rs_scatter_matrices(matrix_images, task_list%pab_buffer, task_list, group)
1616 : ELSE
1617 238304 : CALL rs_copy_to_buffer(matrix_images, task_list%pab_buffer, task_list)
1618 : END IF
1619 238534 : DEALLOCATE (matrix_images)
1620 :
1621 : ! Map all tasks onto the grids
1622 : CALL grid_collocate_task_list(task_list=task_list%grid_task_list, &
1623 : ga_gb_function=ga_gb_function, &
1624 : pab_blocks=task_list%pab_buffer, &
1625 238534 : rs_grids=rs_rho)
1626 :
1627 : ! Merge realspace multi-grids into single planewave grid.
1628 238534 : CALL density_rs2pw(pw_env, rs_rho, rho, rho_gspace)
1629 238534 : IF (PRESENT(total_rho)) total_rho = pw_integrate_function(rho, isign=-1)
1630 :
1631 238534 : CALL timestop(handle)
1632 :
1633 238534 : END SUBROUTINE calculate_rho_elec
1634 :
1635 : ! **************************************************************************************************
1636 : !> \brief computes the gradient of the density corresponding to a given
1637 : !> density matrix on the grid
1638 : !> \param matrix_p ...
1639 : !> \param matrix_p_kp ...
1640 : !> \param drho ...
1641 : !> \param drho_gspace ...
1642 : !> \param qs_env ...
1643 : !> \param soft_valid ...
1644 : !> \param basis_type ...
1645 : !> \note this is an alternative to calculate the gradient through FFTs
1646 : ! **************************************************************************************************
1647 0 : SUBROUTINE calculate_drho_elec(matrix_p, matrix_p_kp, drho, drho_gspace, qs_env, &
1648 : soft_valid, basis_type)
1649 :
1650 : TYPE(dbcsr_type), OPTIONAL, TARGET :: matrix_p
1651 : TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
1652 : POINTER :: matrix_p_kp
1653 : TYPE(pw_r3d_rs_type), DIMENSION(3), INTENT(INOUT) :: drho
1654 : TYPE(pw_c1d_gs_type), DIMENSION(3), INTENT(INOUT) :: drho_gspace
1655 : TYPE(qs_environment_type), POINTER :: qs_env
1656 : LOGICAL, INTENT(IN), OPTIONAL :: soft_valid
1657 : CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: basis_type
1658 :
1659 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_drho_elec'
1660 :
1661 : CHARACTER(LEN=default_string_length) :: my_basis_type
1662 : INTEGER :: bcol, brow, dabqadb_func, handle, iatom, iatom_old, idir, igrid_level, ikind, &
1663 : ikind_old, img, img_old, ipgf, iset, iset_old, itask, ithread, jatom, jatom_old, jkind, &
1664 : jkind_old, jpgf, jset, jset_old, maxco, maxsgf_set, na1, na2, natoms, nb1, nb2, ncoa, &
1665 : ncob, nimages, nseta, nsetb, ntasks, nthread, sgfa, sgfb
1666 0 : INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min, npgfa, &
1667 0 : npgfb, nsgfa, nsgfb
1668 0 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
1669 : LOGICAL :: atom_pair_changed, distributed_rs_grids, &
1670 : do_kp, found, my_soft, use_subpatch
1671 : REAL(KIND=dp) :: eps_rho_rspace, f, prefactor, radius, &
1672 : scale, zetp
1673 : REAL(KIND=dp), DIMENSION(3) :: ra, rab, rab_inv, rb, rp
1674 0 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: p_block, pab, sphi_a, sphi_b, work, &
1675 0 : zeta, zetb
1676 0 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: pabt, workt
1677 0 : TYPE(atom_pair_type), DIMENSION(:), POINTER :: atom_pair_recv, atom_pair_send
1678 : TYPE(cell_type), POINTER :: cell
1679 0 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: deltap
1680 : TYPE(dft_control_type), POINTER :: dft_control
1681 : TYPE(gridlevel_info_type), POINTER :: gridlevel_info
1682 : TYPE(gto_basis_set_type), POINTER :: orb_basis_set
1683 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1684 0 : POINTER :: sab_orb
1685 0 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1686 : TYPE(pw_env_type), POINTER :: pw_env
1687 0 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1688 : TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
1689 0 : POINTER :: rs_descs
1690 0 : TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_rho
1691 : TYPE(task_list_type), POINTER :: task_list, task_list_soft
1692 0 : TYPE(task_type), DIMENSION(:), POINTER :: tasks
1693 :
1694 0 : CALL timeset(routineN, handle)
1695 :
1696 0 : CPASSERT(PRESENT(matrix_p) .OR. PRESENT(matrix_p_kp))
1697 0 : do_kp = PRESENT(matrix_p_kp)
1698 :
1699 0 : NULLIFY (cell, dft_control, orb_basis_set, deltap, qs_kind_set, &
1700 0 : sab_orb, particle_set, rs_rho, pw_env, rs_descs, la_max, la_min, &
1701 0 : lb_max, lb_min, npgfa, npgfb, nsgfa, nsgfb, p_block, sphi_a, &
1702 0 : sphi_b, zeta, zetb, first_sgfa, first_sgfb, tasks, pabt, workt)
1703 :
1704 : ! by default, the full density is calculated
1705 0 : my_soft = .FALSE.
1706 0 : IF (PRESENT(soft_valid)) my_soft = soft_valid
1707 :
1708 0 : IF (PRESENT(basis_type)) THEN
1709 0 : my_basis_type = basis_type
1710 : ELSE
1711 0 : my_basis_type = "ORB"
1712 : END IF
1713 :
1714 : CALL get_qs_env(qs_env=qs_env, &
1715 : qs_kind_set=qs_kind_set, &
1716 : cell=cell, &
1717 : dft_control=dft_control, &
1718 : particle_set=particle_set, &
1719 : sab_orb=sab_orb, &
1720 0 : pw_env=pw_env)
1721 :
1722 0 : SELECT CASE (my_basis_type)
1723 : CASE ("ORB")
1724 : CALL get_qs_env(qs_env=qs_env, &
1725 : task_list=task_list, &
1726 0 : task_list_soft=task_list_soft)
1727 : CASE ("AUX_FIT")
1728 : CALL get_qs_env(qs_env=qs_env, &
1729 0 : task_list_soft=task_list_soft)
1730 0 : CALL get_admm_env(qs_env%admm_env, task_list_aux_fit=task_list)
1731 : END SELECT
1732 :
1733 : ! *** assign from pw_env
1734 0 : gridlevel_info => pw_env%gridlevel_info
1735 :
1736 : ! *** Allocate work storage ***
1737 0 : nthread = 1
1738 : CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
1739 : maxco=maxco, &
1740 : maxsgf_set=maxsgf_set, &
1741 0 : basis_type=my_basis_type)
1742 0 : CALL reallocate(pabt, 1, maxco, 1, maxco, 0, nthread - 1)
1743 0 : CALL reallocate(workt, 1, maxco, 1, maxsgf_set, 0, nthread - 1)
1744 :
1745 : ! find maximum numbers
1746 0 : nimages = dft_control%nimages
1747 0 : CPASSERT(nimages == 1 .OR. do_kp)
1748 :
1749 0 : natoms = SIZE(particle_set)
1750 :
1751 : ! get the task lists
1752 0 : IF (my_soft) task_list => task_list_soft
1753 0 : CPASSERT(ASSOCIATED(task_list))
1754 0 : tasks => task_list%tasks
1755 0 : atom_pair_send => task_list%atom_pair_send
1756 0 : atom_pair_recv => task_list%atom_pair_recv
1757 0 : ntasks = task_list%ntasks
1758 :
1759 : ! *** set up the rs multi-grids
1760 0 : CPASSERT(ASSOCIATED(pw_env))
1761 0 : CALL pw_env_get(pw_env, rs_descs=rs_descs, rs_grids=rs_rho)
1762 0 : DO igrid_level = 1, gridlevel_info%ngrid_levels
1763 0 : distributed_rs_grids = rs_rho(igrid_level)%desc%distributed
1764 : END DO
1765 :
1766 0 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
1767 :
1768 : ! *** Initialize working density matrix ***
1769 : ! distributed rs grids require a matrix that will be changed
1770 : ! whereas this is not the case for replicated grids
1771 0 : ALLOCATE (deltap(nimages))
1772 0 : IF (distributed_rs_grids) THEN
1773 0 : DO img = 1, nimages
1774 : END DO
1775 : ! this matrix has no strict sparsity pattern in parallel
1776 : ! deltap%sparsity_id=-1
1777 0 : IF (do_kp) THEN
1778 0 : DO img = 1, nimages
1779 : CALL dbcsr_copy(deltap(img)%matrix, matrix_p_kp(img)%matrix, &
1780 0 : name="DeltaP")
1781 : END DO
1782 : ELSE
1783 0 : CALL dbcsr_copy(deltap(1)%matrix, matrix_p, name="DeltaP")
1784 : END IF
1785 : ELSE
1786 0 : IF (do_kp) THEN
1787 0 : DO img = 1, nimages
1788 0 : deltap(img)%matrix => matrix_p_kp(img)%matrix
1789 : END DO
1790 : ELSE
1791 0 : deltap(1)%matrix => matrix_p
1792 : END IF
1793 : END IF
1794 :
1795 : ! distribute the matrix
1796 0 : IF (distributed_rs_grids) THEN
1797 : CALL rs_distribute_matrix(rs_descs=rs_descs, pmats=deltap, &
1798 : atom_pair_send=atom_pair_send, atom_pair_recv=atom_pair_recv, &
1799 0 : nimages=nimages, scatter=.TRUE.)
1800 : END IF
1801 :
1802 : ! map all tasks on the grids
1803 :
1804 0 : ithread = 0
1805 0 : pab => pabt(:, :, ithread)
1806 0 : work => workt(:, :, ithread)
1807 :
1808 0 : loop_xyz: DO idir = 1, 3
1809 :
1810 0 : DO igrid_level = 1, gridlevel_info%ngrid_levels
1811 0 : CALL rs_grid_zero(rs_rho(igrid_level))
1812 : END DO
1813 :
1814 : iatom_old = -1; jatom_old = -1; iset_old = -1; jset_old = -1
1815 : ikind_old = -1; jkind_old = -1; img_old = -1
1816 0 : loop_tasks: DO itask = 1, ntasks
1817 :
1818 : !decode the atom pair and basis info
1819 0 : igrid_level = tasks(itask)%grid_level
1820 0 : img = tasks(itask)%image
1821 0 : iatom = tasks(itask)%iatom
1822 0 : jatom = tasks(itask)%jatom
1823 0 : iset = tasks(itask)%iset
1824 0 : jset = tasks(itask)%jset
1825 0 : ipgf = tasks(itask)%ipgf
1826 0 : jpgf = tasks(itask)%jpgf
1827 :
1828 0 : ikind = particle_set(iatom)%atomic_kind%kind_number
1829 0 : jkind = particle_set(jatom)%atomic_kind%kind_number
1830 :
1831 0 : IF (iatom /= iatom_old .OR. jatom /= jatom_old .OR. img /= img_old) THEN
1832 :
1833 0 : IF (iatom /= iatom_old) ra(:) = pbc(particle_set(iatom)%r, cell)
1834 :
1835 0 : IF (iatom <= jatom) THEN
1836 0 : brow = iatom
1837 0 : bcol = jatom
1838 : ELSE
1839 0 : brow = jatom
1840 0 : bcol = iatom
1841 : END IF
1842 :
1843 0 : IF (ikind /= ikind_old) THEN
1844 0 : IF (my_soft) THEN
1845 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, &
1846 0 : basis_type="ORB_SOFT")
1847 : ELSE
1848 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, &
1849 0 : basis_type=my_basis_type)
1850 : END IF
1851 : CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
1852 : first_sgf=first_sgfa, &
1853 : lmax=la_max, &
1854 : lmin=la_min, &
1855 : npgf=npgfa, &
1856 : nset=nseta, &
1857 : nsgf_set=nsgfa, &
1858 : sphi=sphi_a, &
1859 0 : zet=zeta)
1860 : END IF
1861 :
1862 0 : IF (jkind /= jkind_old) THEN
1863 0 : IF (my_soft) THEN
1864 : CALL get_qs_kind(qs_kind_set(jkind), basis_set=orb_basis_set, &
1865 0 : basis_type="ORB_SOFT")
1866 : ELSE
1867 : CALL get_qs_kind(qs_kind_set(jkind), basis_set=orb_basis_set, &
1868 0 : basis_type=my_basis_type)
1869 : END IF
1870 : CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
1871 : first_sgf=first_sgfb, &
1872 : lmax=lb_max, &
1873 : lmin=lb_min, &
1874 : npgf=npgfb, &
1875 : nset=nsetb, &
1876 : nsgf_set=nsgfb, &
1877 : sphi=sphi_b, &
1878 0 : zet=zetb)
1879 : END IF
1880 :
1881 : CALL dbcsr_get_block_p(matrix=deltap(img)%matrix, &
1882 0 : row=brow, col=bcol, BLOCK=p_block, found=found)
1883 0 : CPASSERT(found)
1884 :
1885 : iatom_old = iatom
1886 : jatom_old = jatom
1887 : ikind_old = ikind
1888 : jkind_old = jkind
1889 : img_old = img
1890 : atom_pair_changed = .TRUE.
1891 :
1892 : ELSE
1893 :
1894 : atom_pair_changed = .FALSE.
1895 :
1896 : END IF
1897 :
1898 0 : IF (atom_pair_changed .OR. iset_old /= iset .OR. jset_old /= jset) THEN
1899 :
1900 0 : ncoa = npgfa(iset)*ncoset(la_max(iset))
1901 0 : sgfa = first_sgfa(1, iset)
1902 0 : ncob = npgfb(jset)*ncoset(lb_max(jset))
1903 0 : sgfb = first_sgfb(1, jset)
1904 :
1905 0 : IF (iatom <= jatom) THEN
1906 : CALL dgemm("N", "N", ncoa, nsgfb(jset), nsgfa(iset), &
1907 : 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
1908 : p_block(sgfa, sgfb), SIZE(p_block, 1), &
1909 0 : 0.0_dp, work(1, 1), maxco)
1910 : CALL dgemm("N", "T", ncoa, ncob, nsgfb(jset), &
1911 : 1.0_dp, work(1, 1), maxco, &
1912 : sphi_b(1, sgfb), SIZE(sphi_b, 1), &
1913 0 : 0.0_dp, pab(1, 1), maxco)
1914 : ELSE
1915 : CALL dgemm("N", "N", ncob, nsgfa(iset), nsgfb(jset), &
1916 : 1.0_dp, sphi_b(1, sgfb), SIZE(sphi_b, 1), &
1917 : p_block(sgfb, sgfa), SIZE(p_block, 1), &
1918 0 : 0.0_dp, work(1, 1), maxco)
1919 : CALL dgemm("N", "T", ncob, ncoa, nsgfa(iset), &
1920 : 1.0_dp, work(1, 1), maxco, &
1921 : sphi_a(1, sgfa), SIZE(sphi_a, 1), &
1922 0 : 0.0_dp, pab(1, 1), maxco)
1923 : END IF
1924 :
1925 : iset_old = iset
1926 : jset_old = jset
1927 :
1928 : END IF
1929 :
1930 0 : rab(:) = tasks(itask)%rab
1931 0 : rb(:) = ra(:) + rab(:)
1932 0 : zetp = zeta(ipgf, iset) + zetb(jpgf, jset)
1933 :
1934 0 : f = zetb(jpgf, jset)/zetp
1935 0 : rp(:) = ra(:) + f*rab(:)
1936 0 : prefactor = EXP(-zeta(ipgf, iset)*f*DOT_PRODUCT(rab, rab))
1937 : radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
1938 : lb_min=lb_min(jset), lb_max=lb_max(jset), &
1939 : ra=ra, rb=rb, rp=rp, &
1940 : zetp=zeta(ipgf, iset), eps=eps_rho_rspace, &
1941 0 : prefactor=prefactor, cutoff=1.0_dp)
1942 :
1943 0 : na1 = (ipgf - 1)*ncoset(la_max(iset)) + 1
1944 0 : na2 = ipgf*ncoset(la_max(iset))
1945 0 : nb1 = (jpgf - 1)*ncoset(lb_max(jset)) + 1
1946 0 : nb2 = jpgf*ncoset(lb_max(jset))
1947 :
1948 : ! takes the density matrix symmetry in account, i.e. off-diagonal blocks need to be mapped 'twice'
1949 0 : IF (iatom == jatom .AND. img == 1) THEN
1950 0 : scale = 1.0_dp
1951 : ELSE
1952 0 : scale = 2.0_dp
1953 : END IF
1954 :
1955 : ! check whether we need to use fawzi's generalised collocation scheme
1956 0 : IF (rs_rho(igrid_level)%desc%distributed) THEN
1957 : !tasks(4,:) is 0 for replicated, 1 for distributed 2 for exceptional distributed tasks
1958 0 : IF (tasks(itask)%dist_type == 2) THEN
1959 0 : use_subpatch = .TRUE.
1960 : ELSE
1961 0 : use_subpatch = .FALSE.
1962 : END IF
1963 : ELSE
1964 0 : use_subpatch = .FALSE.
1965 : END IF
1966 :
1967 0 : SELECT CASE (idir)
1968 : CASE (1)
1969 0 : dabqadb_func = GRID_FUNC_DABpADB_X
1970 : CASE (2)
1971 0 : dabqadb_func = GRID_FUNC_DABpADB_Y
1972 : CASE (3)
1973 0 : dabqadb_func = GRID_FUNC_DABpADB_Z
1974 : CASE DEFAULT
1975 0 : CPABORT("invalid idir")
1976 : END SELECT
1977 :
1978 0 : IF (iatom <= jatom) THEN
1979 : CALL collocate_pgf_product( &
1980 : la_max(iset), zeta(ipgf, iset), la_min(iset), &
1981 : lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
1982 : ra, rab, scale, pab, na1 - 1, nb1 - 1, &
1983 : rs_rho(igrid_level), &
1984 : radius=radius, ga_gb_function=dabqadb_func, &
1985 0 : use_subpatch=use_subpatch, subpatch_pattern=tasks(itask)%subpatch_pattern)
1986 : ELSE
1987 0 : rab_inv = -rab
1988 : CALL collocate_pgf_product( &
1989 : lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
1990 : la_max(iset), zeta(ipgf, iset), la_min(iset), &
1991 : rb, rab_inv, scale, pab, nb1 - 1, na1 - 1, &
1992 : rs_rho(igrid_level), &
1993 : radius=radius, ga_gb_function=dabqadb_func, &
1994 0 : use_subpatch=use_subpatch, subpatch_pattern=tasks(itask)%subpatch_pattern)
1995 : END IF
1996 :
1997 : END DO loop_tasks
1998 :
1999 0 : CALL density_rs2pw(pw_env, rs_rho, drho(idir), drho_gspace(idir))
2000 :
2001 : END DO loop_xyz
2002 :
2003 : ! *** Release work storage ***
2004 0 : IF (distributed_rs_grids) THEN
2005 0 : CALL dbcsr_deallocate_matrix_set(deltap)
2006 : ELSE
2007 0 : DO img = 1, nimages
2008 0 : NULLIFY (deltap(img)%matrix)
2009 : END DO
2010 0 : DEALLOCATE (deltap)
2011 : END IF
2012 :
2013 0 : DEALLOCATE (pabt, workt)
2014 :
2015 0 : CALL timestop(handle)
2016 :
2017 0 : END SUBROUTINE calculate_drho_elec
2018 :
2019 : ! **************************************************************************************************
2020 : !> \brief Computes the gradient wrt. nuclear coordinates of a density on the grid
2021 : !> The density is given in terms of the density matrix_p
2022 : !> \param matrix_p Density matrix
2023 : !> \param matrix_p_kp ...
2024 : !> \param drho Density gradient on the grid
2025 : !> \param drho_gspace Density gradient on the reciprocal grid
2026 : !> \param qs_env ...
2027 : !> \param soft_valid ...
2028 : !> \param basis_type ...
2029 : !> \param beta Derivative direction
2030 : !> \param lambda Atom index
2031 : !> \note SL, ED 2021
2032 : !> Adapted from calculate_drho_elec
2033 : ! **************************************************************************************************
2034 252 : SUBROUTINE calculate_drho_elec_dR(matrix_p, matrix_p_kp, drho, drho_gspace, qs_env, &
2035 : soft_valid, basis_type, beta, lambda)
2036 :
2037 : TYPE(dbcsr_type), OPTIONAL, TARGET :: matrix_p
2038 : TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
2039 : POINTER :: matrix_p_kp
2040 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: drho
2041 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: drho_gspace
2042 : TYPE(qs_environment_type), POINTER :: qs_env
2043 : LOGICAL, INTENT(IN), OPTIONAL :: soft_valid
2044 : CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: basis_type
2045 : INTEGER, INTENT(IN) :: beta, lambda
2046 :
2047 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_drho_elec_dR'
2048 :
2049 : CHARACTER(LEN=default_string_length) :: my_basis_type
2050 : INTEGER :: bcol, brow, dabqadb_func, handle, iatom, iatom_old, igrid_level, ikind, &
2051 : ikind_old, img, img_old, ipgf, iset, iset_old, itask, ithread, jatom, jatom_old, jkind, &
2052 : jkind_old, jpgf, jset, jset_old, maxco, maxsgf_set, na1, na2, natoms, nb1, nb2, ncoa, &
2053 : ncob, nimages, nseta, nsetb, ntasks, nthread, sgfa, sgfb
2054 252 : INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min, npgfa, &
2055 252 : npgfb, nsgfa, nsgfb
2056 252 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
2057 : LOGICAL :: atom_pair_changed, distributed_rs_grids, &
2058 : do_kp, found, my_soft, use_subpatch
2059 : REAL(KIND=dp) :: eps_rho_rspace, f, prefactor, radius, &
2060 : scale, zetp
2061 : REAL(KIND=dp), DIMENSION(3) :: ra, rab, rab_inv, rb, rp
2062 252 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: p_block, pab, sphi_a, sphi_b, work, &
2063 252 : zeta, zetb
2064 252 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: pabt, workt
2065 252 : TYPE(atom_pair_type), DIMENSION(:), POINTER :: atom_pair_recv, atom_pair_send
2066 : TYPE(cell_type), POINTER :: cell
2067 252 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: deltap
2068 : TYPE(dft_control_type), POINTER :: dft_control
2069 : TYPE(gridlevel_info_type), POINTER :: gridlevel_info
2070 : TYPE(gto_basis_set_type), POINTER :: orb_basis_set
2071 252 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2072 : TYPE(pw_env_type), POINTER :: pw_env
2073 252 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2074 : TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
2075 252 : POINTER :: rs_descs
2076 252 : TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_rho
2077 : TYPE(task_list_type), POINTER :: task_list, task_list_soft
2078 252 : TYPE(task_type), DIMENSION(:), POINTER :: tasks
2079 :
2080 252 : CALL timeset(routineN, handle)
2081 :
2082 252 : CPASSERT(PRESENT(matrix_p) .OR. PRESENT(matrix_p_kp))
2083 252 : do_kp = PRESENT(matrix_p_kp)
2084 :
2085 252 : NULLIFY (cell, dft_control, orb_basis_set, deltap, qs_kind_set, &
2086 252 : particle_set, rs_rho, pw_env, rs_descs, la_max, la_min, lb_max, &
2087 252 : lb_min, npgfa, npgfb, nsgfa, nsgfb, p_block, sphi_a, sphi_b, &
2088 252 : zeta, zetb, first_sgfa, first_sgfb, tasks, pabt, workt)
2089 :
2090 : ! by default, the full density is calculated
2091 252 : my_soft = .FALSE.
2092 252 : IF (PRESENT(soft_valid)) my_soft = soft_valid
2093 :
2094 252 : IF (PRESENT(basis_type)) THEN
2095 0 : my_basis_type = basis_type
2096 : ELSE
2097 252 : my_basis_type = "ORB"
2098 : END IF
2099 :
2100 : CALL get_qs_env(qs_env=qs_env, &
2101 : qs_kind_set=qs_kind_set, &
2102 : cell=cell, &
2103 : dft_control=dft_control, &
2104 : particle_set=particle_set, &
2105 252 : pw_env=pw_env)
2106 :
2107 252 : SELECT CASE (my_basis_type)
2108 : CASE ("ORB")
2109 : CALL get_qs_env(qs_env=qs_env, &
2110 : task_list=task_list, &
2111 252 : task_list_soft=task_list_soft)
2112 : CASE ("AUX_FIT")
2113 : CALL get_qs_env(qs_env=qs_env, &
2114 0 : task_list_soft=task_list_soft)
2115 252 : CALL get_admm_env(qs_env%admm_env, task_list_aux_fit=task_list)
2116 : END SELECT
2117 :
2118 : ! *** assign from pw_env
2119 252 : gridlevel_info => pw_env%gridlevel_info
2120 :
2121 : ! *** Allocate work storage ***
2122 252 : nthread = 1
2123 : CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
2124 : maxco=maxco, &
2125 : maxsgf_set=maxsgf_set, &
2126 252 : basis_type=my_basis_type)
2127 252 : CALL reallocate(pabt, 1, maxco, 1, maxco, 0, nthread - 1)
2128 252 : CALL reallocate(workt, 1, maxco, 1, maxsgf_set, 0, nthread - 1)
2129 :
2130 : ! find maximum numbers
2131 252 : nimages = dft_control%nimages
2132 252 : CPASSERT(nimages == 1 .OR. do_kp)
2133 :
2134 252 : natoms = SIZE(particle_set)
2135 :
2136 : ! get the task lists
2137 252 : IF (my_soft) task_list => task_list_soft
2138 252 : CPASSERT(ASSOCIATED(task_list))
2139 252 : tasks => task_list%tasks
2140 252 : atom_pair_send => task_list%atom_pair_send
2141 252 : atom_pair_recv => task_list%atom_pair_recv
2142 252 : ntasks = task_list%ntasks
2143 :
2144 : ! *** set up the rs multi-grids
2145 252 : CPASSERT(ASSOCIATED(pw_env))
2146 252 : CALL pw_env_get(pw_env, rs_descs=rs_descs, rs_grids=rs_rho)
2147 774 : DO igrid_level = 1, gridlevel_info%ngrid_levels
2148 774 : distributed_rs_grids = rs_rho(igrid_level)%desc%distributed
2149 : END DO
2150 :
2151 252 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
2152 :
2153 : ! *** Initialize working density matrix ***
2154 : ! distributed rs grids require a matrix that will be changed
2155 : ! whereas this is not the case for replicated grids
2156 1008 : ALLOCATE (deltap(nimages))
2157 252 : IF (distributed_rs_grids) THEN
2158 0 : DO img = 1, nimages
2159 : END DO
2160 : ! this matrix has no strict sparsity pattern in parallel
2161 : ! deltap%sparsity_id=-1
2162 0 : IF (do_kp) THEN
2163 0 : DO img = 1, nimages
2164 : CALL dbcsr_copy(deltap(img)%matrix, matrix_p_kp(img)%matrix, &
2165 0 : name="DeltaP")
2166 : END DO
2167 : ELSE
2168 0 : CALL dbcsr_copy(deltap(1)%matrix, matrix_p, name="DeltaP")
2169 : END IF
2170 : ELSE
2171 252 : IF (do_kp) THEN
2172 0 : DO img = 1, nimages
2173 0 : deltap(img)%matrix => matrix_p_kp(img)%matrix
2174 : END DO
2175 : ELSE
2176 252 : deltap(1)%matrix => matrix_p
2177 : END IF
2178 : END IF
2179 :
2180 : ! distribute the matrix
2181 252 : IF (distributed_rs_grids) THEN
2182 : CALL rs_distribute_matrix(rs_descs=rs_descs, pmats=deltap, &
2183 : atom_pair_send=atom_pair_send, atom_pair_recv=atom_pair_recv, &
2184 0 : nimages=nimages, scatter=.TRUE.)
2185 : END IF
2186 :
2187 : ! map all tasks on the grids
2188 :
2189 252 : ithread = 0
2190 252 : pab => pabt(:, :, ithread)
2191 252 : work => workt(:, :, ithread)
2192 :
2193 774 : DO igrid_level = 1, gridlevel_info%ngrid_levels
2194 774 : CALL rs_grid_zero(rs_rho(igrid_level))
2195 : END DO
2196 :
2197 : iatom_old = -1; jatom_old = -1; iset_old = -1; jset_old = -1
2198 : ikind_old = -1; jkind_old = -1; img_old = -1
2199 16506 : loop_tasks: DO itask = 1, ntasks
2200 :
2201 : !decode the atom pair and basis info
2202 16254 : igrid_level = tasks(itask)%grid_level
2203 16254 : img = tasks(itask)%image
2204 16254 : iatom = tasks(itask)%iatom
2205 16254 : jatom = tasks(itask)%jatom
2206 16254 : iset = tasks(itask)%iset
2207 16254 : jset = tasks(itask)%jset
2208 16254 : ipgf = tasks(itask)%ipgf
2209 16254 : jpgf = tasks(itask)%jpgf
2210 :
2211 16254 : ikind = particle_set(iatom)%atomic_kind%kind_number
2212 16254 : jkind = particle_set(jatom)%atomic_kind%kind_number
2213 :
2214 16254 : IF (iatom /= iatom_old .OR. jatom /= jatom_old .OR. img /= img_old) THEN
2215 :
2216 1296 : IF (iatom /= iatom_old) ra(:) = pbc(particle_set(iatom)%r, cell)
2217 :
2218 1296 : IF (iatom <= jatom) THEN
2219 864 : brow = iatom
2220 864 : bcol = jatom
2221 : ELSE
2222 432 : brow = jatom
2223 432 : bcol = iatom
2224 : END IF
2225 :
2226 1296 : IF (ikind /= ikind_old) THEN
2227 252 : IF (my_soft) THEN
2228 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, &
2229 0 : basis_type="ORB_SOFT")
2230 : ELSE
2231 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, &
2232 252 : basis_type=my_basis_type)
2233 : END IF
2234 : CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
2235 : first_sgf=first_sgfa, &
2236 : lmax=la_max, &
2237 : lmin=la_min, &
2238 : npgf=npgfa, &
2239 : nset=nseta, &
2240 : nsgf_set=nsgfa, &
2241 : sphi=sphi_a, &
2242 252 : zet=zeta)
2243 : END IF
2244 :
2245 1296 : IF (jkind /= jkind_old) THEN
2246 864 : IF (my_soft) THEN
2247 : CALL get_qs_kind(qs_kind_set(jkind), basis_set=orb_basis_set, &
2248 0 : basis_type="ORB_SOFT")
2249 : ELSE
2250 : CALL get_qs_kind(qs_kind_set(jkind), basis_set=orb_basis_set, &
2251 864 : basis_type=my_basis_type)
2252 : END IF
2253 : CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
2254 : first_sgf=first_sgfb, &
2255 : lmax=lb_max, &
2256 : lmin=lb_min, &
2257 : npgf=npgfb, &
2258 : nset=nsetb, &
2259 : nsgf_set=nsgfb, &
2260 : sphi=sphi_b, &
2261 864 : zet=zetb)
2262 : END IF
2263 :
2264 : CALL dbcsr_get_block_p(matrix=deltap(img)%matrix, &
2265 1296 : row=brow, col=bcol, BLOCK=p_block, found=found)
2266 1296 : CPASSERT(found)
2267 :
2268 : iatom_old = iatom
2269 : jatom_old = jatom
2270 : ikind_old = ikind
2271 : jkind_old = jkind
2272 : img_old = img
2273 : atom_pair_changed = .TRUE.
2274 :
2275 : ELSE
2276 :
2277 : atom_pair_changed = .FALSE.
2278 :
2279 : END IF
2280 :
2281 16254 : IF (atom_pair_changed .OR. iset_old /= iset .OR. jset_old /= jset) THEN
2282 :
2283 1296 : ncoa = npgfa(iset)*ncoset(la_max(iset))
2284 1296 : sgfa = first_sgfa(1, iset)
2285 1296 : ncob = npgfb(jset)*ncoset(lb_max(jset))
2286 1296 : sgfb = first_sgfb(1, jset)
2287 :
2288 1296 : IF (iatom <= jatom) THEN
2289 : CALL dgemm("N", "N", ncoa, nsgfb(jset), nsgfa(iset), &
2290 : 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
2291 : p_block(sgfa, sgfb), SIZE(p_block, 1), &
2292 864 : 0.0_dp, work(1, 1), maxco)
2293 : CALL dgemm("N", "T", ncoa, ncob, nsgfb(jset), &
2294 : 1.0_dp, work(1, 1), maxco, &
2295 : sphi_b(1, sgfb), SIZE(sphi_b, 1), &
2296 864 : 0.0_dp, pab(1, 1), maxco)
2297 : ELSE
2298 : CALL dgemm("N", "N", ncob, nsgfa(iset), nsgfb(jset), &
2299 : 1.0_dp, sphi_b(1, sgfb), SIZE(sphi_b, 1), &
2300 : p_block(sgfb, sgfa), SIZE(p_block, 1), &
2301 432 : 0.0_dp, work(1, 1), maxco)
2302 : CALL dgemm("N", "T", ncob, ncoa, nsgfa(iset), &
2303 : 1.0_dp, work(1, 1), maxco, &
2304 : sphi_a(1, sgfa), SIZE(sphi_a, 1), &
2305 432 : 0.0_dp, pab(1, 1), maxco)
2306 : END IF
2307 :
2308 : iset_old = iset
2309 : jset_old = jset
2310 :
2311 : END IF
2312 :
2313 65016 : rab(:) = tasks(itask)%rab
2314 65016 : rb(:) = ra(:) + rab(:)
2315 16254 : zetp = zeta(ipgf, iset) + zetb(jpgf, jset)
2316 :
2317 16254 : f = zetb(jpgf, jset)/zetp
2318 65016 : rp(:) = ra(:) + f*rab(:)
2319 65016 : prefactor = EXP(-zeta(ipgf, iset)*f*DOT_PRODUCT(rab, rab))
2320 : radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
2321 : lb_min=lb_min(jset), lb_max=lb_max(jset), &
2322 : ra=ra, rb=rb, rp=rp, &
2323 : zetp=zetp, eps=eps_rho_rspace, &
2324 16254 : prefactor=prefactor, cutoff=1.0_dp)
2325 :
2326 16254 : na1 = (ipgf - 1)*ncoset(la_max(iset)) + 1
2327 16254 : na2 = ipgf*ncoset(la_max(iset))
2328 16254 : nb1 = (jpgf - 1)*ncoset(lb_max(jset)) + 1
2329 16254 : nb2 = jpgf*ncoset(lb_max(jset))
2330 :
2331 : ! takes the density matrix symmetry in account, i.e. off-diagonal blocks need to be mapped 'twice'
2332 16254 : IF (iatom == jatom .AND. img == 1) THEN
2333 8100 : scale = 1.0_dp
2334 : ELSE
2335 8154 : scale = 2.0_dp
2336 : END IF
2337 :
2338 : ! check whether we need to use fawzi's generalised collocation scheme
2339 16254 : IF (rs_rho(igrid_level)%desc%distributed) THEN
2340 : !tasks(4,:) is 0 for replicated, 1 for distributed 2 for exceptional distributed tasks
2341 0 : IF (tasks(itask)%dist_type == 2) THEN
2342 0 : use_subpatch = .TRUE.
2343 : ELSE
2344 0 : use_subpatch = .FALSE.
2345 : END IF
2346 : ELSE
2347 16254 : use_subpatch = .FALSE.
2348 : END IF
2349 :
2350 21672 : SELECT CASE (beta)
2351 : CASE (1)
2352 5418 : dabqadb_func = GRID_FUNC_DAB_X
2353 : CASE (2)
2354 5418 : dabqadb_func = GRID_FUNC_DAB_Y
2355 : CASE (3)
2356 5418 : dabqadb_func = GRID_FUNC_DAB_Z
2357 : CASE DEFAULT
2358 16254 : CPABORT("invalid beta")
2359 : END SELECT
2360 :
2361 16506 : IF (iatom <= jatom) THEN
2362 10854 : IF (iatom == lambda) THEN
2363 : CALL collocate_pgf_product( &
2364 : la_max(iset), zeta(ipgf, iset), la_min(iset), &
2365 : lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
2366 : ra, rab, scale, pab, na1 - 1, nb1 - 1, &
2367 : rsgrid=rs_rho(igrid_level), &
2368 : ga_gb_function=dabqadb_func, radius=radius, &
2369 : use_subpatch=use_subpatch, &
2370 3618 : subpatch_pattern=tasks(itask)%subpatch_pattern)
2371 : END IF
2372 10854 : IF (jatom == lambda) THEN
2373 : CALL collocate_pgf_product( &
2374 : la_max(iset), zeta(ipgf, iset), la_min(iset), &
2375 : lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
2376 : ra, rab, scale, pab, na1 - 1, nb1 - 1, &
2377 : rsgrid=rs_rho(igrid_level), &
2378 : ga_gb_function=dabqadb_func + 3, radius=radius, &
2379 : use_subpatch=use_subpatch, &
2380 3618 : subpatch_pattern=tasks(itask)%subpatch_pattern)
2381 : END IF
2382 : ELSE
2383 21600 : rab_inv = -rab
2384 5400 : IF (jatom == lambda) THEN
2385 : CALL collocate_pgf_product( &
2386 : lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
2387 : la_max(iset), zeta(ipgf, iset), la_min(iset), &
2388 : rb, rab_inv, scale, pab, nb1 - 1, na1 - 1, &
2389 : rs_rho(igrid_level), &
2390 : ga_gb_function=dabqadb_func, radius=radius, &
2391 : use_subpatch=use_subpatch, &
2392 1800 : subpatch_pattern=tasks(itask)%subpatch_pattern)
2393 : END IF
2394 5400 : IF (iatom == lambda) THEN
2395 : CALL collocate_pgf_product( &
2396 : lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
2397 : la_max(iset), zeta(ipgf, iset), la_min(iset), &
2398 : rb, rab_inv, scale, pab, nb1 - 1, na1 - 1, &
2399 : rs_rho(igrid_level), &
2400 : ga_gb_function=dabqadb_func + 3, radius=radius, &
2401 : use_subpatch=use_subpatch, &
2402 1800 : subpatch_pattern=tasks(itask)%subpatch_pattern)
2403 : END IF
2404 : END IF
2405 :
2406 : END DO loop_tasks
2407 :
2408 252 : CALL density_rs2pw(pw_env, rs_rho, drho, drho_gspace)
2409 :
2410 : ! *** Release work storage ***
2411 252 : IF (distributed_rs_grids) THEN
2412 0 : CALL dbcsr_deallocate_matrix_set(deltap)
2413 : ELSE
2414 504 : DO img = 1, nimages
2415 504 : NULLIFY (deltap(img)%matrix)
2416 : END DO
2417 252 : DEALLOCATE (deltap)
2418 : END IF
2419 :
2420 252 : DEALLOCATE (pabt, workt)
2421 :
2422 252 : CALL timestop(handle)
2423 :
2424 504 : END SUBROUTINE calculate_drho_elec_dR
2425 :
2426 : ! **************************************************************************************************
2427 : !> \brief maps a single gaussian on the grid
2428 : !> \param rho ...
2429 : !> \param rho_gspace ...
2430 : !> \param atomic_kind_set ...
2431 : !> \param qs_kind_set ...
2432 : !> \param cell ...
2433 : !> \param dft_control ...
2434 : !> \param particle_set ...
2435 : !> \param pw_env ...
2436 : !> \param required_function ...
2437 : !> \param basis_type ...
2438 : !> \par History
2439 : !> 08.2022 created from calculate_wavefunction
2440 : !> \note
2441 : !> modified calculate_wave function assuming that the collocation of only a single Gaussian is required.
2442 : !> chooses a basis function (in contrast to calculate_rho_core or calculate_rho_single_gaussian)
2443 : ! **************************************************************************************************
2444 28573 : SUBROUTINE collocate_single_gaussian(rho, rho_gspace, &
2445 : atomic_kind_set, qs_kind_set, cell, dft_control, particle_set, &
2446 : pw_env, required_function, basis_type)
2447 :
2448 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: rho
2449 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_gspace
2450 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
2451 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2452 : TYPE(cell_type), POINTER :: cell
2453 : TYPE(dft_control_type), POINTER :: dft_control
2454 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2455 : TYPE(pw_env_type), POINTER :: pw_env
2456 : INTEGER, INTENT(IN) :: required_function
2457 : CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: basis_type
2458 :
2459 : CHARACTER(LEN=*), PARAMETER :: routineN = 'collocate_single_gaussian'
2460 :
2461 : CHARACTER(LEN=default_string_length) :: my_basis_type
2462 : INTEGER :: group_size, handle, i, iatom, igrid_level, ikind, ipgf, iset, maxco, maxsgf_set, &
2463 : my_index, my_pos, na1, na2, natom, ncoa, nseta, offset, sgfa
2464 28573 : INTEGER, ALLOCATABLE, DIMENSION(:) :: where_is_the_point
2465 28573 : INTEGER, DIMENSION(:), POINTER :: la_max, la_min, npgfa, nsgfa
2466 28573 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa
2467 : LOGICAL :: found
2468 : REAL(KIND=dp) :: dab, eps_rho_rspace, radius, scale
2469 : REAL(KIND=dp), DIMENSION(3) :: ra
2470 28573 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: pab, sphi_a, zeta
2471 : TYPE(gridlevel_info_type), POINTER :: gridlevel_info
2472 : TYPE(gto_basis_set_type), POINTER :: orb_basis_set
2473 : TYPE(mp_comm_type) :: group
2474 28573 : TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
2475 28573 : TYPE(pw_c1d_gs_type), ALLOCATABLE, DIMENSION(:) :: mgrid_gspace
2476 28573 : TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:) :: mgrid_rspace
2477 28573 : TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_rho
2478 :
2479 28573 : IF (PRESENT(basis_type)) THEN
2480 28573 : my_basis_type = basis_type
2481 : ELSE
2482 0 : my_basis_type = "ORB"
2483 : END IF
2484 :
2485 28573 : CALL timeset(routineN, handle)
2486 :
2487 28573 : NULLIFY (orb_basis_set, pab, la_max, la_min, npgfa, nsgfa, sphi_a, &
2488 28573 : zeta, first_sgfa, rs_rho, pw_pools)
2489 :
2490 : ! *** set up the pw multi-grids
2491 28573 : CPASSERT(ASSOCIATED(pw_env))
2492 : CALL pw_env_get(pw_env, rs_grids=rs_rho, pw_pools=pw_pools, &
2493 28573 : gridlevel_info=gridlevel_info)
2494 :
2495 28573 : CALL pw_pools_create_pws(pw_pools, mgrid_gspace)
2496 28573 : CALL pw_pools_create_pws(pw_pools, mgrid_rspace)
2497 :
2498 : ! *** set up rs multi-grids
2499 142865 : DO igrid_level = 1, gridlevel_info%ngrid_levels
2500 142865 : CALL rs_grid_zero(rs_rho(igrid_level))
2501 : END DO
2502 :
2503 28573 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
2504 : ! *** Allocate work storage ***
2505 28573 : CALL get_atomic_kind_set(atomic_kind_set, natom=natom)
2506 : CALL get_qs_kind_set(qs_kind_set, &
2507 : maxco=maxco, &
2508 : maxsgf_set=maxsgf_set, &
2509 28573 : basis_type=my_basis_type)
2510 :
2511 85719 : ALLOCATE (pab(maxco, 1))
2512 :
2513 28573 : offset = 0
2514 28573 : group = mgrid_rspace(1)%pw_grid%para%group
2515 28573 : my_pos = mgrid_rspace(1)%pw_grid%para%group%mepos
2516 28573 : group_size = mgrid_rspace(1)%pw_grid%para%group%num_pe
2517 85719 : ALLOCATE (where_is_the_point(0:group_size - 1))
2518 :
2519 117551 : DO iatom = 1, natom
2520 88978 : ikind = particle_set(iatom)%atomic_kind%kind_number
2521 88978 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, basis_type=my_basis_type)
2522 : CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
2523 : first_sgf=first_sgfa, &
2524 : lmax=la_max, &
2525 : lmin=la_min, &
2526 : npgf=npgfa, &
2527 : nset=nseta, &
2528 : nsgf_set=nsgfa, &
2529 : sphi=sphi_a, &
2530 88978 : zet=zeta)
2531 88978 : ra(:) = pbc(particle_set(iatom)%r, cell)
2532 88978 : dab = 0.0_dp
2533 :
2534 1047571 : DO iset = 1, nseta
2535 :
2536 841042 : ncoa = npgfa(iset)*ncoset(la_max(iset))
2537 841042 : sgfa = first_sgfa(1, iset)
2538 :
2539 841042 : found = .FALSE.
2540 841042 : my_index = 0
2541 3176013 : DO i = 1, nsgfa(iset)
2542 3176013 : IF (offset + i == required_function) THEN
2543 : my_index = i
2544 : found = .TRUE.
2545 : EXIT
2546 : END IF
2547 : END DO
2548 :
2549 841042 : IF (found) THEN
2550 :
2551 523769 : pab(1:ncoa, 1) = sphi_a(1:ncoa, sgfa + my_index - 1)
2552 :
2553 58202 : DO ipgf = 1, npgfa(iset)
2554 :
2555 29629 : na1 = (ipgf - 1)*ncoset(la_max(iset)) + 1
2556 29629 : na2 = ipgf*ncoset(la_max(iset))
2557 :
2558 29629 : scale = 1.0_dp
2559 29629 : igrid_level = gaussian_gridlevel(gridlevel_info, zeta(ipgf, iset))
2560 :
2561 58202 : IF (map_gaussian_here(rs_rho(igrid_level), cell%h_inv, ra, offset, group_size, my_pos)) THEN
2562 : radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
2563 : lb_min=0, lb_max=0, ra=ra, rb=ra, rp=ra, &
2564 : zetp=zeta(ipgf, iset), eps=eps_rho_rspace, &
2565 27872 : prefactor=1.0_dp, cutoff=1.0_dp)
2566 :
2567 : CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), la_min(iset), &
2568 : 0, 0.0_dp, 0, &
2569 : ra, [0.0_dp, 0.0_dp, 0.0_dp], &
2570 : scale, pab, na1 - 1, 0, rs_rho(igrid_level), &
2571 27872 : radius=radius, ga_gb_function=GRID_FUNC_AB)
2572 : END IF
2573 :
2574 : END DO
2575 :
2576 : END IF
2577 :
2578 930020 : offset = offset + nsgfa(iset)
2579 :
2580 : END DO
2581 :
2582 : END DO
2583 :
2584 142865 : DO igrid_level = 1, gridlevel_info%ngrid_levels
2585 : CALL transfer_rs2pw(rs_rho(igrid_level), &
2586 142865 : mgrid_rspace(igrid_level))
2587 : END DO
2588 :
2589 28573 : CALL pw_zero(rho_gspace)
2590 142865 : DO igrid_level = 1, gridlevel_info%ngrid_levels
2591 : CALL pw_transfer(mgrid_rspace(igrid_level), &
2592 114292 : mgrid_gspace(igrid_level))
2593 142865 : CALL pw_axpy(mgrid_gspace(igrid_level), rho_gspace)
2594 : END DO
2595 :
2596 28573 : CALL pw_transfer(rho_gspace, rho)
2597 :
2598 : ! Release work storage
2599 28573 : DEALLOCATE (pab)
2600 :
2601 : ! give back the pw multi-grids
2602 28573 : CALL pw_pools_give_back_pws(pw_pools, mgrid_gspace)
2603 28573 : CALL pw_pools_give_back_pws(pw_pools, mgrid_rspace)
2604 :
2605 28573 : CALL timestop(handle)
2606 :
2607 114292 : END SUBROUTINE collocate_single_gaussian
2608 :
2609 : ! **************************************************************************************************
2610 : !> \brief maps a given wavefunction on the grid
2611 : !> \param mo_vectors ...
2612 : !> \param ivector ...
2613 : !> \param rho ...
2614 : !> \param rho_gspace ...
2615 : !> \param atomic_kind_set ...
2616 : !> \param qs_kind_set ...
2617 : !> \param cell ...
2618 : !> \param dft_control ...
2619 : !> \param particle_set ...
2620 : !> \param pw_env ...
2621 : !> \param basis_type ...
2622 : !> \par History
2623 : !> 08.2002 created [Joost VandeVondele]
2624 : !> 03.2006 made independent of qs_env [Joost VandeVondele]
2625 : !> 08.2024 call collocate_function [JGH]
2626 : ! **************************************************************************************************
2627 1399 : SUBROUTINE calculate_wavefunction(mo_vectors, ivector, rho, rho_gspace, &
2628 : atomic_kind_set, qs_kind_set, cell, dft_control, particle_set, &
2629 : pw_env, basis_type)
2630 : TYPE(cp_fm_type), INTENT(IN) :: mo_vectors
2631 : INTEGER, INTENT(IN) :: ivector
2632 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: rho
2633 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_gspace
2634 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
2635 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2636 : TYPE(cell_type), POINTER :: cell
2637 : TYPE(dft_control_type), POINTER :: dft_control
2638 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2639 : TYPE(pw_env_type), POINTER :: pw_env
2640 : CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: basis_type
2641 :
2642 : CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_wavefunction'
2643 :
2644 : INTEGER :: handle, i, nao
2645 : LOGICAL :: local
2646 : REAL(KIND=dp) :: eps_rho_rspace
2647 : REAL(KIND=dp), DIMENSION(:), POINTER :: eigenvector
2648 :
2649 1399 : CALL timeset(routineN, handle)
2650 :
2651 1399 : CALL cp_fm_get_info(matrix=mo_vectors, nrow_global=nao)
2652 4197 : ALLOCATE (eigenvector(nao))
2653 26203 : DO i = 1, nao
2654 26203 : CALL cp_fm_get_element(mo_vectors, i, ivector, eigenvector(i), local)
2655 : END DO
2656 :
2657 1399 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
2658 :
2659 : CALL collocate_function(eigenvector, rho, rho_gspace, &
2660 : atomic_kind_set, qs_kind_set, cell, particle_set, pw_env, &
2661 2798 : eps_rho_rspace, basis_type)
2662 :
2663 1399 : DEALLOCATE (eigenvector)
2664 :
2665 1399 : CALL timestop(handle)
2666 :
2667 1399 : END SUBROUTINE calculate_wavefunction
2668 :
2669 : ! **************************************************************************************************
2670 : !> \brief maps a given function on the grid
2671 : !> \param vector ...
2672 : !> \param rho ...
2673 : !> \param rho_gspace ...
2674 : !> \param atomic_kind_set ...
2675 : !> \param qs_kind_set ...
2676 : !> \param cell ...
2677 : !> \param particle_set ...
2678 : !> \param pw_env ...
2679 : !> \param eps_rho_rspace ...
2680 : !> \param basis_type ...
2681 : !> \par History
2682 : !> 08.2002 created [Joost VandeVondele]
2683 : !> 03.2006 made independent of qs_env [Joost VandeVondele]
2684 : !> 08.2024 specialized version from calculate_wavefunction [JGH]
2685 : !> \notes
2686 : !> modified calculate_rho_elec, should write the wavefunction represented by vector
2687 : !> it's presumably dominated by the FFT and the rs->pw and back routines
2688 : ! **************************************************************************************************
2689 39818 : SUBROUTINE collocate_function(vector, rho, rho_gspace, &
2690 : atomic_kind_set, qs_kind_set, cell, particle_set, pw_env, &
2691 : eps_rho_rspace, basis_type)
2692 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: vector
2693 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: rho
2694 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_gspace
2695 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
2696 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2697 : TYPE(cell_type), POINTER :: cell
2698 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2699 : TYPE(pw_env_type), POINTER :: pw_env
2700 : REAL(KIND=dp), INTENT(IN) :: eps_rho_rspace
2701 : CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: basis_type
2702 :
2703 : CHARACTER(LEN=*), PARAMETER :: routineN = 'collocate_function'
2704 :
2705 : CHARACTER(LEN=default_string_length) :: my_basis_type
2706 : INTEGER :: group_size, handle, i, iatom, igrid_level, ikind, ipgf, iset, maxco, maxsgf_set, &
2707 : my_pos, na1, na2, natom, ncoa, nseta, offset, sgfa
2708 19909 : INTEGER, ALLOCATABLE, DIMENSION(:) :: where_is_the_point
2709 19909 : INTEGER, DIMENSION(:), POINTER :: la_max, la_min, npgfa, nsgfa
2710 19909 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa
2711 : REAL(KIND=dp) :: dab, radius, scale
2712 : REAL(KIND=dp), DIMENSION(3) :: ra
2713 19909 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: pab, sphi_a, work, zeta
2714 : TYPE(gridlevel_info_type), POINTER :: gridlevel_info
2715 : TYPE(gto_basis_set_type), POINTER :: orb_basis_set
2716 : TYPE(mp_comm_type) :: group
2717 19909 : TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
2718 19909 : TYPE(pw_c1d_gs_type), ALLOCATABLE, DIMENSION(:) :: mgrid_gspace
2719 19909 : TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:) :: mgrid_rspace
2720 19909 : TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_rho
2721 :
2722 19909 : CALL timeset(routineN, handle)
2723 :
2724 19909 : IF (PRESENT(basis_type)) THEN
2725 18206 : my_basis_type = basis_type
2726 : ELSE
2727 1703 : my_basis_type = "ORB"
2728 : END IF
2729 :
2730 19909 : NULLIFY (orb_basis_set, pab, work, la_max, la_min, &
2731 19909 : npgfa, nsgfa, sphi_a, zeta, first_sgfa, rs_rho, pw_pools)
2732 :
2733 : ! *** set up the pw multi-grids
2734 19909 : CPASSERT(ASSOCIATED(pw_env))
2735 : CALL pw_env_get(pw_env, rs_grids=rs_rho, pw_pools=pw_pools, &
2736 19909 : gridlevel_info=gridlevel_info)
2737 :
2738 19909 : CALL pw_pools_create_pws(pw_pools, mgrid_gspace)
2739 19909 : CALL pw_pools_create_pws(pw_pools, mgrid_rspace)
2740 :
2741 : ! *** set up rs multi-grids
2742 99263 : DO igrid_level = 1, gridlevel_info%ngrid_levels
2743 99263 : CALL rs_grid_zero(rs_rho(igrid_level))
2744 : END DO
2745 :
2746 : ! *** Allocate work storage ***
2747 19909 : CALL get_atomic_kind_set(atomic_kind_set, natom=natom)
2748 : CALL get_qs_kind_set(qs_kind_set, &
2749 : maxco=maxco, &
2750 : maxsgf_set=maxsgf_set, &
2751 19909 : basis_type=my_basis_type)
2752 :
2753 59727 : ALLOCATE (pab(maxco, 1))
2754 39818 : ALLOCATE (work(maxco, 1))
2755 :
2756 19909 : offset = 0
2757 19909 : group = mgrid_rspace(1)%pw_grid%para%group
2758 19909 : my_pos = mgrid_rspace(1)%pw_grid%para%group%mepos
2759 19909 : group_size = mgrid_rspace(1)%pw_grid%para%group%num_pe
2760 59727 : ALLOCATE (where_is_the_point(0:group_size - 1))
2761 :
2762 82559 : DO iatom = 1, natom
2763 62650 : ikind = particle_set(iatom)%atomic_kind%kind_number
2764 62650 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, basis_type=my_basis_type)
2765 : CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
2766 : first_sgf=first_sgfa, &
2767 : lmax=la_max, &
2768 : lmin=la_min, &
2769 : npgf=npgfa, &
2770 : nset=nseta, &
2771 : nsgf_set=nsgfa, &
2772 : sphi=sphi_a, &
2773 62650 : zet=zeta)
2774 62650 : ra(:) = pbc(particle_set(iatom)%r, cell)
2775 62650 : dab = 0.0_dp
2776 :
2777 691140 : DO iset = 1, nseta
2778 :
2779 545931 : ncoa = npgfa(iset)*ncoset(la_max(iset))
2780 545931 : sgfa = first_sgfa(1, iset)
2781 :
2782 2111310 : DO i = 1, nsgfa(iset)
2783 2111310 : work(i, 1) = vector(offset + i)
2784 : END DO
2785 :
2786 : CALL dgemm("N", "N", ncoa, 1, nsgfa(iset), &
2787 : 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
2788 : work(1, 1), SIZE(work, 1), &
2789 545931 : 0.0_dp, pab(1, 1), SIZE(pab, 1))
2790 :
2791 1119647 : DO ipgf = 1, npgfa(iset)
2792 :
2793 573716 : na1 = (ipgf - 1)*ncoset(la_max(iset)) + 1
2794 573716 : na2 = ipgf*ncoset(la_max(iset))
2795 :
2796 573716 : scale = 1.0_dp
2797 573716 : igrid_level = gaussian_gridlevel(gridlevel_info, zeta(ipgf, iset))
2798 :
2799 1119647 : IF (map_gaussian_here(rs_rho(igrid_level), cell%h_inv, ra, offset, group_size, my_pos)) THEN
2800 : radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
2801 : lb_min=0, lb_max=0, ra=ra, rb=ra, rp=ra, &
2802 : zetp=zeta(ipgf, iset), eps=eps_rho_rspace, &
2803 523349 : prefactor=1.0_dp, cutoff=1.0_dp)
2804 :
2805 : CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), la_min(iset), &
2806 : 0, 0.0_dp, 0, &
2807 : ra, [0.0_dp, 0.0_dp, 0.0_dp], &
2808 : scale, pab, na1 - 1, 0, rs_rho(igrid_level), &
2809 523349 : radius=radius, ga_gb_function=GRID_FUNC_AB)
2810 : END IF
2811 :
2812 : END DO
2813 :
2814 608581 : offset = offset + nsgfa(iset)
2815 :
2816 : END DO
2817 :
2818 : END DO
2819 :
2820 99263 : DO igrid_level = 1, gridlevel_info%ngrid_levels
2821 : CALL transfer_rs2pw(rs_rho(igrid_level), &
2822 99263 : mgrid_rspace(igrid_level))
2823 : END DO
2824 :
2825 19909 : CALL pw_zero(rho_gspace)
2826 99263 : DO igrid_level = 1, gridlevel_info%ngrid_levels
2827 : CALL pw_transfer(mgrid_rspace(igrid_level), &
2828 79354 : mgrid_gspace(igrid_level))
2829 99263 : CALL pw_axpy(mgrid_gspace(igrid_level), rho_gspace)
2830 : END DO
2831 :
2832 19909 : CALL pw_transfer(rho_gspace, rho)
2833 :
2834 : ! Release work storage
2835 19909 : DEALLOCATE (pab)
2836 19909 : DEALLOCATE (work)
2837 :
2838 : ! give back the pw multi-grids
2839 19909 : CALL pw_pools_give_back_pws(pw_pools, mgrid_gspace)
2840 19909 : CALL pw_pools_give_back_pws(pw_pools, mgrid_rspace)
2841 :
2842 19909 : CALL timestop(handle)
2843 :
2844 59727 : END SUBROUTINE collocate_function
2845 :
2846 : END MODULE qs_collocate_density
|