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 given the response wavefunctions obtained by the application
10 : !> of the (rxp), p, and ((dk-dl)xp) operators,
11 : !> here the current density vector (jx, jy, jz)
12 : !> is computed for the 3 directions of the magnetic field (Bx, By, Bz)
13 : !> \par History
14 : !> created 02-2006 [MI]
15 : !> \author MI
16 : ! **************************************************************************************************
17 : MODULE qs_linres_current
18 : USE ao_util, ONLY: exp_radius_very_extended
19 : USE basis_set_types, ONLY: get_gto_basis_set,&
20 : gto_basis_set_p_type,&
21 : gto_basis_set_type
22 : USE cell_types, ONLY: cell_type,&
23 : pbc
24 : USE cp_array_utils, ONLY: cp_2d_i_p_type,&
25 : cp_2d_r_p_type
26 : USE cp_control_types, ONLY: dft_control_type
27 : USE cp_dbcsr_api, ONLY: &
28 : dbcsr_convert_offsets_to_sizes, dbcsr_copy, dbcsr_create, dbcsr_deallocate_matrix, &
29 : dbcsr_distribution_type, dbcsr_finalize, dbcsr_get_block_p, dbcsr_p_type, dbcsr_put_block, &
30 : dbcsr_set, dbcsr_type, dbcsr_type_antisymmetric, dbcsr_type_no_symmetry
31 : USE cp_dbcsr_cp2k_link, ONLY: cp_dbcsr_alloc_block_from_nbl
32 : USE cp_dbcsr_operations, ONLY: cp_dbcsr_plus_fm_fm_t,&
33 : cp_dbcsr_sm_fm_multiply,&
34 : dbcsr_allocate_matrix_set,&
35 : dbcsr_deallocate_matrix_set
36 : USE cp_fm_basic_linalg, ONLY: cp_fm_scale_and_add,&
37 : cp_fm_trace
38 : USE cp_fm_struct, ONLY: cp_fm_struct_create,&
39 : cp_fm_struct_release,&
40 : cp_fm_struct_type
41 : USE cp_fm_types, ONLY: cp_fm_create,&
42 : cp_fm_release,&
43 : cp_fm_set_all,&
44 : cp_fm_to_fm,&
45 : cp_fm_type
46 : USE cp_log_handling, ONLY: cp_get_default_logger,&
47 : cp_logger_get_default_io_unit,&
48 : cp_logger_type,&
49 : cp_to_string
50 : USE cp_output_handling, ONLY: cp_p_file,&
51 : cp_print_key_finished_output,&
52 : cp_print_key_should_output,&
53 : cp_print_key_unit_nr
54 : USE cp_realspace_grid_cube, ONLY: cp_pw_to_cube
55 : USE cube_utils, ONLY: compute_cube_center,&
56 : cube_info_type,&
57 : return_cube
58 : USE gaussian_gridlevels, ONLY: gridlevel_info_type
59 : USE grid_api, ONLY: &
60 : GRID_FUNC_AB, GRID_FUNC_ADBmDAB_X, GRID_FUNC_ADBmDAB_Y, GRID_FUNC_ADBmDAB_Z, &
61 : GRID_FUNC_ARDBmDARB_XX, GRID_FUNC_ARDBmDARB_XY, GRID_FUNC_ARDBmDARB_XZ, &
62 : GRID_FUNC_ARDBmDARB_YX, GRID_FUNC_ARDBmDARB_YY, GRID_FUNC_ARDBmDARB_YZ, &
63 : GRID_FUNC_ARDBmDARB_ZX, GRID_FUNC_ARDBmDARB_ZY, GRID_FUNC_ARDBmDARB_ZZ, &
64 : collocate_pgf_product
65 : USE input_constants, ONLY: current_gauge_atom
66 : USE input_section_types, ONLY: section_get_ivals,&
67 : section_get_lval,&
68 : section_vals_get_subs_vals,&
69 : section_vals_type
70 : USE kinds, ONLY: default_path_length,&
71 : default_string_length,&
72 : dp,&
73 : int_8
74 : USE mathconstants, ONLY: twopi
75 : USE memory_utilities, ONLY: reallocate
76 : USE message_passing, ONLY: mp_para_env_type
77 : USE orbital_pointers, ONLY: ncoset
78 : USE particle_list_types, ONLY: particle_list_type
79 : USE particle_methods, ONLY: get_particle_set
80 : USE particle_types, ONLY: particle_type
81 : USE pw_env_types, ONLY: pw_env_get,&
82 : pw_env_type
83 : USE pw_methods, ONLY: pw_axpy,&
84 : pw_integrate_function,&
85 : pw_scale,&
86 : pw_zero
87 : USE pw_pool_types, ONLY: pw_pool_type
88 : USE pw_types, ONLY: 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_linres_atom_current, ONLY: calculate_jrho_atom,&
96 : calculate_jrho_atom_coeff,&
97 : calculate_jrho_atom_rad
98 : USE qs_linres_op, ONLY: fac_vecp,&
99 : fm_scale_by_pbc_AC,&
100 : ind_m2,&
101 : set_vecp,&
102 : set_vecp_rev
103 : USE qs_linres_types, ONLY: current_env_type,&
104 : get_current_env
105 : USE qs_matrix_pools, ONLY: qs_matrix_pools_type
106 : USE qs_mo_types, ONLY: get_mo_set,&
107 : mo_set_type
108 : USE qs_moments, ONLY: build_local_moments_der_matrix
109 : USE qs_neighbor_list_types, ONLY: get_iterator_info,&
110 : neighbor_list_iterate,&
111 : neighbor_list_iterator_create,&
112 : neighbor_list_iterator_p_type,&
113 : neighbor_list_iterator_release,&
114 : neighbor_list_set_p_type
115 : USE qs_operators_ao, ONLY: build_lin_mom_matrix
116 : USE qs_rho_types, ONLY: qs_rho_get
117 : USE qs_subsys_types, ONLY: qs_subsys_get,&
118 : qs_subsys_type
119 : USE realspace_grid_types, ONLY: realspace_grid_desc_p_type,&
120 : realspace_grid_desc_type,&
121 : realspace_grid_type,&
122 : rs_grid_create,&
123 : rs_grid_mult_and_add,&
124 : rs_grid_release,&
125 : rs_grid_zero
126 : USE rs_pw_interface, ONLY: density_rs2pw
127 : USE task_list_methods, ONLY: distribute_tasks,&
128 : rs_distribute_matrix,&
129 : task_list_inner_loop
130 : USE task_list_types, ONLY: atom_pair_type,&
131 : reallocate_tasks,&
132 : task_type
133 : #include "./base/base_uses.f90"
134 :
135 : IMPLICIT NONE
136 :
137 : PRIVATE
138 :
139 : ! *** Public subroutines ***
140 : PUBLIC :: current_build_current, current_build_chi, calculate_jrho_resp
141 :
142 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_linres_current'
143 :
144 : TYPE box_type
145 : INTEGER :: n = -1
146 : REAL(dp), POINTER, DIMENSION(:, :) :: r => NULL()
147 : END TYPE box_type
148 : REAL(dp), DIMENSION(3, 3, 3), PARAMETER :: Levi_Civita = RESHAPE([ &
149 : 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp, -1.0_dp, 0.0_dp, 1.0_dp, 0.0_dp, &
150 : 0.0_dp, 0.0_dp, 1.0_dp, 0.0_dp, 0.0_dp, 0.0_dp, -1.0_dp, 0.0_dp, 0.0_dp, &
151 : 0.0_dp, -1.0_dp, 0.0_dp, 1.0_dp, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp], [3, 3, 3])
152 :
153 : CONTAINS
154 :
155 : ! **************************************************************************************************
156 : !> \brief First calculate the density matrixes, for each component of the current
157 : !> they are 3 because of the r dependent terms
158 : !> Next it collocates on the grid to have J(r)
159 : !> In the GAPW case one need to collocate on the PW grid only the soft part
160 : !> while the rest goes on Lebedev grids
161 : !> The contributions to the shift and to the susceptibility will be
162 : !> calculated separately and added only at the end
163 : !> The calculation of the shift tensor is performed on the position of the atoms
164 : !> and on other selected points in real space summing up the contributions
165 : !> from the PW grid current density and the local densities
166 : !> Spline interpolation is used
167 : !> \param current_env ...
168 : !> \param qs_env ...
169 : !> \param iB ...
170 : !> \author MI
171 : !> \note
172 : !> The susceptibility is needed to compute the G=0 term of the shift
173 : !> in reciprocal space. \chi_{ij} = \int (r x Jj)_i
174 : !> (where Jj id the current density generated by the field in direction j)
175 : !> To calculate the susceptibility on the PW grids it is necessary to apply
176 : !> the position operator yet another time.
177 : !> This cannot be done on directly on the full J(r) because it is not localized
178 : !> Therefore it is done state by state (see linres_nmr_shift)
179 : ! **************************************************************************************************
180 492 : SUBROUTINE current_build_current(current_env, qs_env, iB)
181 : !
182 : TYPE(current_env_type) :: current_env
183 : TYPE(qs_environment_type), POINTER :: qs_env
184 : INTEGER, INTENT(IN) :: iB
185 :
186 : CHARACTER(LEN=*), PARAMETER :: routineN = 'current_build_current'
187 :
188 : CHARACTER(LEN=default_path_length) :: ext, filename, my_pos
189 : INTEGER :: handle, idir, iiB, iiiB, ispin, istate, &
190 : j, jstate, nao, natom, nmo, nspins, &
191 : nstates(2), output_unit, unit_nr
192 492 : INTEGER, ALLOCATABLE, DIMENSION(:) :: first_sgf, last_sgf
193 492 : INTEGER, DIMENSION(:), POINTER :: row_blk_sizes
194 : LOGICAL :: append_cube, gapw, mpi_io
195 : REAL(dp) :: dk(3), jrho_tot_G(3, 3), &
196 : jrho_tot_R(3, 3), maxocc, scale_fac
197 492 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: ddk
198 : REAL(dp), EXTERNAL :: DDOT
199 : TYPE(cell_type), POINTER :: cell
200 492 : TYPE(cp_2d_i_p_type), DIMENSION(:), POINTER :: center_list
201 492 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: p_psi1, psi1
202 492 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: psi0_order
203 492 : TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: psi1_D, psi1_p, psi1_rxp
204 : TYPE(cp_fm_type), POINTER :: mo_coeff
205 : TYPE(cp_logger_type), POINTER :: logger
206 : TYPE(dbcsr_distribution_type), POINTER :: dbcsr_dist
207 492 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: density_matrix0, density_matrix_a, &
208 492 : density_matrix_ii, density_matrix_iii
209 : TYPE(dft_control_type), POINTER :: dft_control
210 492 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
211 : TYPE(mp_para_env_type), POINTER :: para_env
212 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
213 492 : POINTER :: sab_all
214 : TYPE(particle_list_type), POINTER :: particles
215 492 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
216 492 : TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: jrho1_g
217 : TYPE(pw_env_type), POINTER :: pw_env
218 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
219 : TYPE(pw_r3d_rs_type) :: wf_r
220 492 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: jrho1_r
221 492 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
222 : TYPE(qs_matrix_pools_type), POINTER :: mpools
223 : TYPE(qs_subsys_type), POINTER :: subsys
224 : TYPE(realspace_grid_desc_type), POINTER :: auxbas_rs_desc
225 : TYPE(section_vals_type), POINTER :: current_section
226 :
227 492 : CALL timeset(routineN, handle)
228 : !
229 492 : NULLIFY (logger, current_section, density_matrix0, density_matrix_a, &
230 492 : density_matrix_ii, density_matrix_iii, cell, dft_control, mos, &
231 492 : particle_set, pw_env, auxbas_rs_desc, auxbas_pw_pool, &
232 492 : para_env, center_list, mo_coeff, jrho1_r, jrho1_g, &
233 492 : psi1_p, psi1_D, psi1_rxp, sab_all, qs_kind_set)
234 :
235 492 : logger => cp_get_default_logger()
236 492 : output_unit = cp_logger_get_default_io_unit(logger)
237 : !
238 : !
239 : CALL get_current_env(current_env=current_env, &
240 : center_list=center_list, &
241 : psi1_rxp=psi1_rxp, &
242 : psi1_D=psi1_D, &
243 : psi1_p=psi1_p, &
244 : psi0_order=psi0_order, &
245 : nstates=nstates, &
246 492 : nao=nao)
247 : !
248 : !
249 : CALL get_qs_env(qs_env=qs_env, &
250 : cell=cell, &
251 : dft_control=dft_control, &
252 : mos=mos, &
253 : mpools=mpools, &
254 : pw_env=pw_env, &
255 : para_env=para_env, &
256 : subsys=subsys, &
257 : sab_all=sab_all, &
258 : particle_set=particle_set, &
259 : qs_kind_set=qs_kind_set, &
260 492 : dbcsr_dist=dbcsr_dist)
261 :
262 492 : CALL qs_subsys_get(subsys, particles=particles)
263 :
264 492 : gapw = dft_control%qs_control%gapw
265 492 : nspins = dft_control%nspins
266 492 : natom = SIZE(particle_set, 1)
267 : !
268 : ! allocate temporary arrays
269 3396 : ALLOCATE (psi1(nspins), p_psi1(nspins))
270 1206 : DO ispin = 1, nspins
271 714 : CALL cp_fm_create(psi1(ispin), psi0_order(ispin)%matrix_struct)
272 714 : CALL cp_fm_create(p_psi1(ispin), psi0_order(ispin)%matrix_struct)
273 714 : CALL cp_fm_set_all(psi1(ispin), 0.0_dp)
274 1206 : CALL cp_fm_set_all(p_psi1(ispin), 0.0_dp)
275 : END DO
276 : !
277 : !
278 492 : CALL dbcsr_allocate_matrix_set(density_matrix0, nspins)
279 492 : CALL dbcsr_allocate_matrix_set(density_matrix_a, nspins)
280 492 : CALL dbcsr_allocate_matrix_set(density_matrix_ii, nspins)
281 492 : CALL dbcsr_allocate_matrix_set(density_matrix_iii, nspins)
282 : !
283 : ! prepare for allocation
284 1476 : ALLOCATE (first_sgf(natom))
285 984 : ALLOCATE (last_sgf(natom))
286 : CALL get_particle_set(particle_set, qs_kind_set, &
287 : first_sgf=first_sgf, &
288 492 : last_sgf=last_sgf)
289 984 : ALLOCATE (row_blk_sizes(natom))
290 492 : CALL dbcsr_convert_offsets_to_sizes(first_sgf, row_blk_sizes, last_sgf)
291 492 : DEALLOCATE (first_sgf)
292 492 : DEALLOCATE (last_sgf)
293 : !
294 : !
295 1206 : DO ispin = 1, nspins
296 : !
297 : !density_matrix0
298 714 : ALLOCATE (density_matrix0(ispin)%matrix)
299 : CALL dbcsr_create(matrix=density_matrix0(ispin)%matrix, &
300 : name="density_matrix0", &
301 : dist=dbcsr_dist, matrix_type=dbcsr_type_no_symmetry, &
302 : row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
303 714 : mutable_work=.TRUE.)
304 714 : CALL cp_dbcsr_alloc_block_from_nbl(density_matrix0(ispin)%matrix, sab_all)
305 : !
306 : !density_matrix_a
307 714 : ALLOCATE (density_matrix_a(ispin)%matrix)
308 : CALL dbcsr_copy(density_matrix_a(ispin)%matrix, density_matrix0(ispin)%matrix, &
309 714 : name="density_matrix_a")
310 : !
311 : !density_matrix_ii
312 714 : ALLOCATE (density_matrix_ii(ispin)%matrix)
313 : CALL dbcsr_copy(density_matrix_ii(ispin)%matrix, density_matrix0(ispin)%matrix, &
314 714 : name="density_matrix_ii")
315 : !
316 : !density_matrix_iii
317 714 : ALLOCATE (density_matrix_iii(ispin)%matrix)
318 : CALL dbcsr_copy(density_matrix_iii(ispin)%matrix, density_matrix0(ispin)%matrix, &
319 1206 : name="density_matrix_iii")
320 : END DO
321 : !
322 492 : DEALLOCATE (row_blk_sizes)
323 : !
324 : !
325 492 : current_section => section_vals_get_subs_vals(qs_env%input, "PROPERTIES%LINRES%CURRENT")
326 : !
327 : !
328 492 : jrho_tot_G = 0.0_dp
329 492 : jrho_tot_R = 0.0_dp
330 : !
331 : ! Lets go!
332 492 : CALL set_vecp(iB, iiB, iiiB)
333 1206 : DO ispin = 1, nspins
334 714 : nmo = nstates(ispin)
335 714 : mo_coeff => psi0_order(ispin)
336 : !maxocc = max_occ(ispin)
337 : !
338 714 : CALL get_mo_set(mo_set=mos(ispin), maxocc=maxocc)
339 : !
340 : !
341 : ! Build the first density matrix
342 714 : CALL dbcsr_set(density_matrix0(ispin)%matrix, 0.0_dp)
343 : CALL cp_dbcsr_plus_fm_fm_t(sparse_matrix=density_matrix0(ispin)%matrix, &
344 : matrix_v=mo_coeff, matrix_g=mo_coeff, &
345 714 : ncol=nmo, alpha=maxocc)
346 : !
347 : ! Allocate buffer vectors
348 2142 : ALLOCATE (ddk(3, nmo))
349 : !
350 : ! Construct the 3 density matrices for the field in direction iB
351 : !
352 : ! First the full matrix psi_a_iB
353 : ASSOCIATE (psi_a_iB => psi1(ispin), psi_buf => p_psi1(ispin))
354 714 : CALL cp_fm_set_all(psi_a_iB, 0.0_dp)
355 714 : CALL cp_fm_set_all(psi_buf, 0.0_dp)
356 : ! psi_a_iB = - (R_\nu-dk)_ii psi1_piiiB + (R_\nu-dk)_iii psi1_piiB
357 : !
358 : ! contributions from the response psi1_p_ii and psi1_p_iii
359 4296 : DO istate = 1, current_env%nbr_center(ispin)
360 14328 : dk(1:3) = current_env%centers_set(ispin)%array(1:3, istate)
361 : !
362 : ! Copy the vector in the full matrix psi1
363 : !nstate_loc = center_list(ispin)%array(1,icenter+1)-center_list(ispin)%array(1,icenter)
364 8922 : DO j = center_list(ispin)%array(1, istate), center_list(ispin)%array(1, istate + 1) - 1
365 4626 : jstate = center_list(ispin)%array(2, j)
366 4626 : CALL cp_fm_to_fm(psi1_p(ispin, iiB), psi_a_iB, 1, jstate, jstate)
367 4626 : CALL cp_fm_to_fm(psi1_p(ispin, iiiB), psi_buf, 1, jstate, jstate)
368 22086 : ddk(:, jstate) = dk(1:3)
369 : END DO
370 : END DO ! istate
371 714 : CALL fm_scale_by_pbc_AC(psi_a_iB, current_env%basisfun_center, ddk, cell, iiiB)
372 714 : CALL fm_scale_by_pbc_AC(psi_buf, current_env%basisfun_center, ddk, cell, iiB)
373 714 : CALL cp_fm_scale_and_add(-1.0_dp, psi_a_iB, 1.0_dp, psi_buf)
374 : !
375 : !psi_a_iB = psi_a_iB + psi1_rxp
376 : !
377 : ! contribution from the response psi1_rxp
378 714 : CALL cp_fm_scale_and_add(-1.0_dp, psi_a_iB, 1.0_dp, psi1_rxp(ispin, iB))
379 : !
380 : !psi_a_iB = psi_a_iB - psi1_D
381 714 : IF (current_env%full) THEN
382 : !
383 : ! contribution from the response psi1_D
384 582 : CALL cp_fm_scale_and_add(1.0_dp, psi_a_iB, -1.0_dp, psi1_D(ispin, iB))
385 : END IF
386 : !
387 : ! Multiply by the occupation number for the density matrix
388 : !
389 : ! Build the first density matrix
390 714 : CALL dbcsr_set(density_matrix_a(ispin)%matrix, 0.0_dp)
391 : CALL cp_dbcsr_plus_fm_fm_t(sparse_matrix=density_matrix_a(ispin)%matrix, &
392 : matrix_v=mo_coeff, matrix_g=psi_a_iB, &
393 1428 : ncol=nmo, alpha=maxocc)
394 : END ASSOCIATE
395 : !
396 : ! Build the second density matrix
397 714 : CALL dbcsr_set(density_matrix_iii(ispin)%matrix, 0.0_dp)
398 : CALL cp_dbcsr_plus_fm_fm_t(sparse_matrix=density_matrix_iii(ispin)%matrix, &
399 : matrix_v=mo_coeff, matrix_g=psi1_p(ispin, iiiB), &
400 714 : ncol=nmo, alpha=maxocc)
401 : !
402 : ! Build the third density matrix
403 714 : CALL dbcsr_set(density_matrix_ii(ispin)%matrix, 0.0_dp)
404 : CALL cp_dbcsr_plus_fm_fm_t(sparse_matrix=density_matrix_ii(ispin)%matrix, &
405 : matrix_v=mo_coeff, matrix_g=psi1_p(ispin, iiB), &
406 714 : ncol=nmo, alpha=maxocc)
407 2856 : DO idir = 1, 3
408 : !
409 : ! Calculate the current density on the pw grid (only soft if GAPW)
410 : ! idir is the cartesian component of the response current density
411 : ! generated by the magnetic field pointing in cartesian direction iB
412 : ! Use the qs_rho_type already used for rho during the scf
413 2142 : CALL qs_rho_get(current_env%jrho1_set(idir)%rho, rho_r=jrho1_r)
414 2142 : CALL qs_rho_get(current_env%jrho1_set(idir)%rho, rho_g=jrho1_g)
415 : ASSOCIATE (jrho_rspace => jrho1_r(ispin), jrho_gspace => jrho1_g(ispin))
416 2142 : CALL pw_zero(jrho_rspace)
417 2142 : CALL pw_zero(jrho_gspace)
418 : CALL calculate_jrho_resp(density_matrix0(ispin)%matrix, &
419 : density_matrix_a(ispin)%matrix, &
420 : density_matrix_ii(ispin)%matrix, &
421 : density_matrix_iii(ispin)%matrix, &
422 : iB, idir, jrho_rspace, jrho_gspace, qs_env, &
423 2142 : current_env, gapw)
424 :
425 2142 : scale_fac = cell%deth/twopi
426 2142 : CALL pw_scale(jrho_rspace, scale_fac)
427 2142 : CALL pw_scale(jrho_gspace, scale_fac)
428 :
429 2142 : jrho_tot_G(idir, iB) = pw_integrate_function(jrho_gspace, isign=-1)
430 4284 : jrho_tot_R(idir, iB) = pw_integrate_function(jrho_rspace, isign=-1)
431 : END ASSOCIATE
432 :
433 2856 : IF (output_unit > 0) THEN
434 : WRITE (output_unit, '(T2,2(A,E24.16))') 'Integrated j_'&
435 1071 : &//ACHAR(idir + 119)//ACHAR(iB + 119)//'(r): G-space=', &
436 2142 : jrho_tot_G(idir, iB), ' R-space=', jrho_tot_R(idir, iB)
437 : END IF
438 : !
439 : END DO ! idir
440 : !
441 : ! Deallocate buffer vectors
442 1920 : DEALLOCATE (ddk)
443 : !
444 : END DO ! ispin
445 :
446 492 : IF (gapw) THEN
447 1152 : DO idir = 1, 3
448 : !
449 : ! compute the atomic response current densities on the spherical grids
450 : ! First the sparse matrices are multiplied by the expansion coefficients
451 : ! this is the equivalent of the CPC for the charge density
452 : CALL calculate_jrho_atom_coeff(qs_env, current_env, &
453 : density_matrix0, &
454 : density_matrix_a, &
455 : density_matrix_ii, &
456 : density_matrix_iii, &
457 864 : iB, idir)
458 : !
459 : ! Then the radial parts are computed on the local radial grid, atom by atom
460 : ! 8 functions are computed for each atom, per grid point
461 : ! and per LM angular momentum. The multiplication by the Clebsh-Gordon
462 : ! coefficients or they correspondent for the derivatives, is also done here
463 864 : CALL calculate_jrho_atom_rad(qs_env, current_env, idir)
464 : !
465 : ! The current on the atomic grids
466 1152 : CALL calculate_jrho_atom(current_env, qs_env, iB, idir)
467 : END DO ! idir
468 : END IF
469 : !
470 : ! Cube files
471 492 : IF (BTEST(cp_print_key_should_output(logger%iter_info, current_section,&
472 : & "PRINT%CURRENT_CUBES"), cp_p_file)) THEN
473 0 : append_cube = section_get_lval(current_section, "PRINT%CURRENT_CUBES%APPEND")
474 0 : my_pos = "REWIND"
475 0 : IF (append_cube) THEN
476 0 : my_pos = "APPEND"
477 : END IF
478 : !
479 : CALL pw_env_get(pw_env, auxbas_rs_desc=auxbas_rs_desc, &
480 0 : auxbas_pw_pool=auxbas_pw_pool)
481 : !
482 0 : CALL auxbas_pw_pool%create_pw(wf_r)
483 : !
484 0 : DO idir = 1, 3
485 0 : CALL pw_zero(wf_r)
486 0 : CALL qs_rho_get(current_env%jrho1_set(idir)%rho, rho_r=jrho1_r)
487 0 : DO ispin = 1, nspins
488 0 : CALL pw_axpy(jrho1_r(ispin), wf_r, 1.0_dp)
489 : END DO
490 : !
491 0 : IF (gapw) THEN
492 : ! Add the local hard and soft contributions
493 : ! This can be done atom by atom by a spline extrapolation of the values
494 : ! on the spherical grid to the grid points.
495 0 : CPABORT("GAPW needs to be finalized")
496 : END IF
497 0 : filename = "jresp"
498 0 : mpi_io = .TRUE.
499 0 : WRITE (ext, '(a2,I1,a2,I1,a5)') "iB", iB, "_d", idir, ".cube"
500 0 : WRITE (ext, '(a2,a1,a2,a1,a5)') "iB", ACHAR(iB + 119), "_d", ACHAR(idir + 119), ".cube"
501 : unit_nr = cp_print_key_unit_nr(logger, current_section, "PRINT%CURRENT_CUBES", &
502 : extension=TRIM(ext), middle_name=TRIM(filename), &
503 : log_filename=.FALSE., file_position=my_pos, &
504 0 : mpi_io=mpi_io)
505 :
506 : CALL cp_pw_to_cube(wf_r, unit_nr, "RESPONSE CURRENT DENSITY ", &
507 : particles=particles, &
508 : stride=section_get_ivals(current_section, "PRINT%CURRENT_CUBES%STRIDE"), &
509 0 : mpi_io=mpi_io)
510 : CALL cp_print_key_finished_output(unit_nr, logger, current_section,&
511 0 : & "PRINT%CURRENT_CUBES", mpi_io=mpi_io)
512 : END DO
513 : !
514 0 : CALL auxbas_pw_pool%give_back_pw(wf_r)
515 : END IF ! current cube
516 : !
517 : ! Integrated current response checksum
518 492 : IF (output_unit > 0) THEN
519 246 : WRITE (output_unit, '(T2,A,E24.16)') 'CheckSum R-integrated j=', &
520 492 : SQRT(DDOT(9, jrho_tot_R(1, 1), 1, jrho_tot_R(1, 1), 1))
521 : END IF
522 : !
523 : !
524 : ! Dellocate grids for the calculation of jrho and the shift
525 492 : CALL cp_fm_release(psi1)
526 492 : CALL cp_fm_release(p_psi1)
527 :
528 492 : CALL dbcsr_deallocate_matrix_set(density_matrix0)
529 492 : CALL dbcsr_deallocate_matrix_set(density_matrix_a)
530 492 : CALL dbcsr_deallocate_matrix_set(density_matrix_ii)
531 492 : CALL dbcsr_deallocate_matrix_set(density_matrix_iii)
532 : !
533 : ! Finalize
534 492 : CALL timestop(handle)
535 : !
536 1476 : END SUBROUTINE current_build_current
537 :
538 : ! **************************************************************************************************
539 : !> \brief Calculation of the idir component of the response current density
540 : !> in the presence of a constant magnetic field in direction iB
541 : !> the current density is collocated on the pw grid in real space
542 : !> \param mat_d0 ...
543 : !> \param mat_jp ...
544 : !> \param mat_jp_rii ...
545 : !> \param mat_jp_riii ...
546 : !> \param iB ...
547 : !> \param idir ...
548 : !> \param current_rs ...
549 : !> \param current_gs ...
550 : !> \param qs_env ...
551 : !> \param current_env ...
552 : !> \param soft_valid ...
553 : !> \param retain_rsgrid ...
554 : !> \note
555 : !> The collocate is done in three parts, one for each density matrix
556 : !> In all cases the density matrices and therefore the collocation
557 : !> are not symmetric, that means that all the pairs (ab and ba) have
558 : !> to be considered separately
559 : !>
560 : !> mat_jp_{\mu\nu} is multiplied by
561 : !> f_{\mu\nu} = \phi_{\mu} (d\phi_{\nu}/dr)_{idir} -
562 : !> (d\phi_{\mu}/dr)_{idir} \phi_{\nu}
563 : !>
564 : !> mat_jp_rii_{\mu\nu} is multiplied by
565 : !> f_{\mu\nu} = \phi_{\mu} (r - R_{\nu})_{iiiB} (d\phi_{\nu}/dr)_{idir} -
566 : !> (d\phi_{\mu}/dr)_{idir} (r - R_{\nu})_{iiiB} \phi_{\nu} +
567 : !> \phi_{\mu} \phi_{\nu} (last term only if iiiB=idir)
568 : !>
569 : !> mat_jp_riii_{\mu\nu} is multiplied by
570 : !> (be careful: change in sign with respect to previous)
571 : !> f_{\mu\nu} = -\phi_{\mu} (r - R_{\nu})_{iiB} (d\phi_{\nu}/dr)_{idir} +
572 : !> (d\phi_{\mu}/dr)_{idir} (r - R_{\nu})_{iiB} \phi_{\nu} -
573 : !> \phi_{\mu} \phi_{\nu} (last term only if iiB=idir)
574 : !>
575 : !> All the terms sum up to the same grid
576 : ! **************************************************************************************************
577 2286 : SUBROUTINE calculate_jrho_resp(mat_d0, mat_jp, mat_jp_rii, mat_jp_riii, iB, idir, &
578 : current_rs, current_gs, qs_env, current_env, soft_valid, retain_rsgrid)
579 :
580 : TYPE(dbcsr_type), POINTER :: mat_d0, mat_jp, mat_jp_rii, mat_jp_riii
581 : INTEGER, INTENT(IN) :: iB, idir
582 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: current_rs
583 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: current_gs
584 : TYPE(qs_environment_type), POINTER :: qs_env
585 : TYPE(current_env_type) :: current_env
586 : LOGICAL, INTENT(IN), OPTIONAL :: soft_valid, retain_rsgrid
587 :
588 : CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_jrho_resp'
589 : INTEGER, PARAMETER :: max_tasks = 2000
590 :
591 : CHARACTER(LEN=default_string_length) :: basis_type
592 : INTEGER :: adbmdab_func, bcol, brow, cindex, curr_tasks, handle, i, iatom, iatom_old, idir2, &
593 : igrid_level, iiB, iiiB, ikind, ikind_old, ipgf, iset, iset_old, itask, ithread, jatom, &
594 : jatom_old, jkind, jkind_old, jpgf, jset, jset_old, maxco, maxpgf, maxset, maxsgf, &
595 : maxsgf_set, na1, na2, natom, nb1, nb2, ncoa, ncob, nimages, nkind, nseta, nsetb, ntasks, &
596 : nthread, sgfa, sgfb
597 2286 : INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min, npgfa, &
598 2286 : npgfb, nsgfa, nsgfb
599 2286 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
600 : LOGICAL :: atom_pair_changed, den_found, &
601 : den_found_a, distributed_rs_grids, &
602 : do_igaim, my_retain_rsgrid, my_soft
603 2286 : REAL(dp), DIMENSION(:, :, :), POINTER :: my_current, my_gauge, my_rho
604 : REAL(KIND=dp) :: eps_rho_rspace, f, kind_radius_a, &
605 : kind_radius_b, Lxo2, Lyo2, Lzo2, &
606 : prefactor, radius, scale, scale2, zetp
607 : REAL(KIND=dp), DIMENSION(3) :: ra, rab, rb, rp
608 2286 : REAL(KIND=dp), DIMENSION(:), POINTER :: set_radius_a, set_radius_b
609 2286 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: jp_block_a, jp_block_b, jp_block_c, jp_block_d, &
610 2286 : jpab_a, jpab_b, jpab_c, jpab_d, rpgfa, rpgfb, sphi_a, sphi_b, work, zeta, zetb
611 2286 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: jpabt_a, jpabt_b, jpabt_c, jpabt_d, workt
612 2286 : TYPE(atom_pair_type), DIMENSION(:), POINTER :: atom_pair_recv, atom_pair_send
613 : TYPE(cell_type), POINTER :: cell
614 2286 : TYPE(cube_info_type), DIMENSION(:), POINTER :: cube_info
615 2286 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: deltajp_a, deltajp_b, deltajp_c, &
616 2286 : deltajp_d
617 : TYPE(dbcsr_type), POINTER :: mat_a, mat_b, mat_c, mat_d
618 : TYPE(dft_control_type), POINTER :: dft_control
619 : TYPE(gridlevel_info_type), POINTER :: gridlevel_info
620 2286 : TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list
621 : TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b, orb_basis_set
622 : TYPE(mp_para_env_type), POINTER :: para_env
623 : TYPE(neighbor_list_iterator_p_type), &
624 2286 : DIMENSION(:), POINTER :: nl_iterator
625 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
626 2286 : POINTER :: sab_orb
627 2286 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
628 : TYPE(pw_env_type), POINTER :: pw_env
629 2286 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
630 : TYPE(qs_kind_type), POINTER :: qs_kind
631 : TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
632 2286 : POINTER :: rs_descs
633 2286 : TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_current, rs_rho
634 : TYPE(realspace_grid_type), DIMENSION(:, :), &
635 2286 : POINTER :: rs_gauge
636 2286 : TYPE(task_type), DIMENSION(:), POINTER :: tasks
637 :
638 2286 : NULLIFY (qs_kind, cell, dft_control, orb_basis_set, rs_rho, &
639 2286 : qs_kind_set, sab_orb, particle_set, rs_current, pw_env, &
640 2286 : rs_descs, para_env, set_radius_a, set_radius_b, la_max, la_min, &
641 2286 : lb_max, lb_min, npgfa, npgfb, nsgfa, nsgfb, rpgfa, rpgfb, &
642 2286 : sphi_a, sphi_b, zeta, zetb, first_sgfa, first_sgfb, tasks, &
643 2286 : workt, mat_a, mat_b, mat_c, mat_d, rs_gauge)
644 2286 : NULLIFY (deltajp_a, deltajp_b, deltajp_c, deltajp_d)
645 2286 : NULLIFY (jp_block_a, jp_block_b, jp_block_c, jp_block_d)
646 2286 : NULLIFY (jpabt_a, jpabt_b, jpabt_c, jpabt_d)
647 2286 : NULLIFY (atom_pair_send, atom_pair_recv)
648 :
649 2286 : CALL timeset(routineN, handle)
650 :
651 : !
652 : ! Set pointers for the different gauge
653 : ! If do_igaim is False the current_env is never needed
654 2286 : do_igaim = current_env%gauge == current_gauge_atom
655 :
656 2286 : mat_a => mat_jp
657 2286 : mat_b => mat_jp_rii
658 2286 : mat_c => mat_jp_riii
659 2286 : IF (do_igaim) mat_d => mat_d0
660 :
661 2286 : my_retain_rsgrid = .FALSE.
662 2286 : IF (PRESENT(retain_rsgrid)) my_retain_rsgrid = retain_rsgrid
663 :
664 : CALL get_qs_env(qs_env=qs_env, &
665 : qs_kind_set=qs_kind_set, &
666 : cell=cell, &
667 : dft_control=dft_control, &
668 : particle_set=particle_set, &
669 : sab_all=sab_orb, &
670 : para_env=para_env, &
671 2286 : pw_env=pw_env)
672 :
673 2286 : IF (do_igaim) CALL get_current_env(current_env=current_env, rs_gauge=rs_gauge)
674 :
675 : ! Component of appearing in the vector product rxp, iiB and iiiB
676 2286 : CALL set_vecp(iB, iiB, iiiB)
677 : !
678 : !
679 2286 : scale2 = 0.0_dp
680 2286 : idir2 = 1
681 2286 : IF (idir /= iB) THEN
682 1428 : CALL set_vecp_rev(idir, iB, idir2)
683 1428 : scale2 = fac_vecp(idir, iB, idir2)
684 : END IF
685 : !
686 : ! *** assign from pw_env
687 2286 : gridlevel_info => pw_env%gridlevel_info
688 2286 : cube_info => pw_env%cube_info
689 :
690 : ! Check that the neighbor list with all the pairs is associated
691 2286 : CPASSERT(ASSOCIATED(sab_orb))
692 : ! *** set up the pw multi-grids
693 2286 : CPASSERT(ASSOCIATED(pw_env))
694 2286 : CALL pw_env_get(pw_env, rs_descs=rs_descs, rs_grids=rs_rho)
695 :
696 2286 : distributed_rs_grids = .FALSE.
697 11394 : DO igrid_level = 1, gridlevel_info%ngrid_levels
698 38718 : IF (.NOT. ALL(rs_descs(igrid_level)%rs_desc%perd == 1)) THEN
699 0 : distributed_rs_grids = .TRUE.
700 : END IF
701 : END DO
702 2286 : eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
703 2286 : nthread = 1
704 :
705 : ! *** Allocate work storage ***
706 : CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
707 : maxco=maxco, &
708 : maxsgf=maxsgf, &
709 2286 : maxsgf_set=maxsgf_set)
710 :
711 9144 : Lxo2 = SQRT(SUM(cell%hmat(:, 1)**2))/2.0_dp
712 9144 : Lyo2 = SQRT(SUM(cell%hmat(:, 2)**2))/2.0_dp
713 9144 : Lzo2 = SQRT(SUM(cell%hmat(:, 3)**2))/2.0_dp
714 :
715 2286 : my_soft = .FALSE.
716 2286 : IF (PRESENT(soft_valid)) my_soft = soft_valid
717 2142 : IF (my_soft) THEN
718 1260 : basis_type = "ORB_SOFT"
719 : ELSE
720 1026 : basis_type = "ORB"
721 : END IF
722 :
723 2286 : nkind = SIZE(qs_kind_set)
724 :
725 2286 : CALL reallocate(jpabt_a, 1, maxco, 1, maxco, 0, nthread - 1)
726 2286 : CALL reallocate(jpabt_b, 1, maxco, 1, maxco, 0, nthread - 1)
727 2286 : CALL reallocate(jpabt_c, 1, maxco, 1, maxco, 0, nthread - 1)
728 2286 : CALL reallocate(jpabt_d, 1, maxco, 1, maxco, 0, nthread - 1)
729 2286 : CALL reallocate(workt, 1, maxco, 1, maxsgf_set, 0, nthread - 1)
730 2286 : CALL reallocate_tasks(tasks, max_tasks)
731 :
732 2286 : ntasks = 0
733 2286 : curr_tasks = SIZE(tasks)
734 :
735 : ! get maximum numbers
736 2286 : natom = SIZE(particle_set)
737 2286 : maxset = 0
738 2286 : maxpgf = 0
739 :
740 : ! hard code matrix index (no kpoints)
741 2286 : nimages = dft_control%nimages
742 2286 : CPASSERT(nimages == 1)
743 2286 : cindex = 1
744 :
745 6126 : DO ikind = 1, nkind
746 3840 : qs_kind => qs_kind_set(ikind)
747 :
748 3840 : CALL get_qs_kind(qs_kind=qs_kind, basis_set=orb_basis_set)
749 :
750 3840 : IF (.NOT. ASSOCIATED(orb_basis_set)) CYCLE
751 :
752 3840 : CALL get_gto_basis_set(gto_basis_set=orb_basis_set, npgf=npgfa, nset=nseta)
753 3840 : maxset = MAX(nseta, maxset)
754 15696 : maxpgf = MAX(MAXVAL(npgfa), maxpgf)
755 : END DO
756 :
757 : ! *** Initialize working density matrix ***
758 :
759 : ! distributed rs grids require a matrix that will be changed (distribute_tasks)
760 : ! whereas this is not the case for replicated grids
761 11430 : ALLOCATE (deltajp_a(1), deltajp_b(1), deltajp_c(1), deltajp_d(1))
762 2286 : IF (distributed_rs_grids) THEN
763 0 : ALLOCATE (deltajp_a(1)%matrix, deltajp_b(1)%matrix, deltajp_c(1)%matrix)
764 0 : IF (do_igaim) THEN
765 0 : ALLOCATE (deltajp_d(1)%matrix)
766 : END IF
767 :
768 0 : CALL dbcsr_create(deltajp_a(1)%matrix, template=mat_a, name='deltajp_a')
769 0 : CALL dbcsr_create(deltajp_b(1)%matrix, template=mat_a, name='deltajp_b')
770 0 : CALL dbcsr_create(deltajp_c(1)%matrix, template=mat_a, name='deltajp_c')
771 0 : IF (do_igaim) CALL dbcsr_create(deltajp_d(1)%matrix, template=mat_a, name='deltajp_d')
772 : ELSE
773 2286 : deltajp_a(1)%matrix => mat_a !mat_jp
774 2286 : deltajp_b(1)%matrix => mat_b !mat_jp_rii
775 2286 : deltajp_c(1)%matrix => mat_c !mat_jp_riii
776 2286 : IF (do_igaim) deltajp_d(1)%matrix => mat_d !mat_d0
777 : END IF
778 :
779 10698 : ALLOCATE (basis_set_list(nkind))
780 6126 : DO ikind = 1, nkind
781 3840 : qs_kind => qs_kind_set(ikind)
782 3840 : CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set_a, basis_type=basis_type)
783 6126 : IF (ASSOCIATED(basis_set_a)) THEN
784 3840 : basis_set_list(ikind)%gto_basis_set => basis_set_a
785 : ELSE
786 0 : NULLIFY (basis_set_list(ikind)%gto_basis_set)
787 : END IF
788 : END DO
789 2286 : CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
790 182301 : DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
791 180015 : CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, iatom=iatom, jatom=jatom, r=rab)
792 180015 : basis_set_a => basis_set_list(ikind)%gto_basis_set
793 180015 : IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
794 180015 : basis_set_b => basis_set_list(jkind)%gto_basis_set
795 180015 : IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
796 180015 : ra(:) = pbc(particle_set(iatom)%r, cell)
797 : ! basis ikind
798 180015 : first_sgfa => basis_set_a%first_sgf
799 180015 : la_max => basis_set_a%lmax
800 180015 : la_min => basis_set_a%lmin
801 180015 : npgfa => basis_set_a%npgf
802 180015 : nseta = basis_set_a%nset
803 180015 : nsgfa => basis_set_a%nsgf_set
804 180015 : rpgfa => basis_set_a%pgf_radius
805 180015 : set_radius_a => basis_set_a%set_radius
806 180015 : kind_radius_a = basis_set_a%kind_radius
807 180015 : sphi_a => basis_set_a%sphi
808 180015 : zeta => basis_set_a%zet
809 : ! basis jkind
810 180015 : first_sgfb => basis_set_b%first_sgf
811 180015 : lb_max => basis_set_b%lmax
812 180015 : lb_min => basis_set_b%lmin
813 180015 : npgfb => basis_set_b%npgf
814 180015 : nsetb = basis_set_b%nset
815 180015 : nsgfb => basis_set_b%nsgf_set
816 180015 : rpgfb => basis_set_b%pgf_radius
817 180015 : set_radius_b => basis_set_b%set_radius
818 180015 : kind_radius_b = basis_set_b%kind_radius
819 180015 : sphi_b => basis_set_b%sphi
820 180015 : zetb => basis_set_b%zet
821 :
822 180015 : IF (ABS(rab(1)) > Lxo2 .OR. ABS(rab(2)) > Lyo2 .OR. ABS(rab(3)) > Lzo2) THEN
823 : CYCLE
824 : END IF
825 :
826 11178 : brow = iatom
827 11178 : bcol = jatom
828 :
829 : CALL dbcsr_get_block_p(matrix=mat_a, row=brow, col=bcol, &
830 11178 : block=jp_block_a, found=den_found_a)
831 : CALL dbcsr_get_block_p(matrix=mat_b, row=brow, col=bcol, &
832 11178 : block=jp_block_b, found=den_found)
833 : CALL dbcsr_get_block_p(matrix=mat_c, row=brow, col=bcol, &
834 11178 : block=jp_block_c, found=den_found)
835 11178 : IF (do_igaim) CALL dbcsr_get_block_p(matrix=mat_d, row=brow, col=bcol, &
836 2961 : block=jp_block_d, found=den_found)
837 :
838 11178 : IF (.NOT. ASSOCIATED(jp_block_a)) CYCLE
839 :
840 11061 : IF (distributed_rs_grids) THEN
841 0 : CALL dbcsr_put_block(deltajp_a(1)%matrix, brow, bcol, jp_block_a)
842 0 : CALL dbcsr_put_block(deltajp_b(1)%matrix, brow, bcol, jp_block_b)
843 0 : CALL dbcsr_put_block(deltajp_c(1)%matrix, brow, bcol, jp_block_c)
844 0 : IF (do_igaim) THEN
845 0 : CALL dbcsr_put_block(deltajp_d(1)%matrix, brow, bcol, jp_block_d)
846 : END IF
847 : END IF
848 :
849 : CALL task_list_inner_loop(tasks, ntasks, curr_tasks, rs_descs, &
850 : dft_control, cube_info, gridlevel_info, cindex, &
851 : iatom, jatom, rpgfa, rpgfb, zeta, zetb, kind_radius_b, &
852 : set_radius_a, set_radius_b, ra, rab, &
853 180015 : la_max, la_min, lb_max, lb_min, npgfa, npgfb, nseta, nsetb)
854 :
855 : END DO
856 2286 : CALL neighbor_list_iterator_release(nl_iterator)
857 :
858 2286 : DEALLOCATE (basis_set_list)
859 :
860 2286 : IF (distributed_rs_grids) THEN
861 0 : CALL dbcsr_finalize(deltajp_a(1)%matrix)
862 0 : CALL dbcsr_finalize(deltajp_b(1)%matrix)
863 0 : CALL dbcsr_finalize(deltajp_c(1)%matrix)
864 0 : IF (do_igaim) CALL dbcsr_finalize(deltajp_d(1)%matrix)
865 : END IF
866 :
867 : ! sorts / redistributes the task list
868 : CALL distribute_tasks(rs_descs=rs_descs, ntasks=ntasks, natoms=natom, tasks=tasks, &
869 : atom_pair_send=atom_pair_send, atom_pair_recv=atom_pair_recv, &
870 : symmetric=.FALSE., reorder_rs_grid_ranks=.TRUE., &
871 2286 : skip_load_balance_distributed=.FALSE.)
872 :
873 50256 : ALLOCATE (rs_current(gridlevel_info%ngrid_levels))
874 :
875 11394 : DO igrid_level = 1, gridlevel_info%ngrid_levels
876 : ! Here we need to reallocate the distributed rs_grids, which may have been reordered
877 : ! by distribute_tasks
878 9108 : IF (rs_descs(igrid_level)%rs_desc%distributed .AND. .NOT. my_retain_rsgrid) THEN
879 0 : CALL rs_grid_release(rs_rho(igrid_level))
880 0 : CALL rs_grid_create(rs_rho(igrid_level), rs_descs(igrid_level)%rs_desc)
881 : END IF
882 9108 : CALL rs_grid_zero(rs_rho(igrid_level))
883 9108 : CALL rs_grid_create(rs_current(igrid_level), rs_descs(igrid_level)%rs_desc)
884 11394 : CALL rs_grid_zero(rs_current(igrid_level))
885 : END DO
886 :
887 : !
888 : ! we need to build the gauge here
889 2286 : IF (.NOT. current_env%gauge_init .AND. do_igaim) THEN
890 28 : CALL current_set_gauge(current_env, qs_env)
891 28 : current_env%gauge_init = .TRUE.
892 : END IF
893 : !
894 : ! for any case double check the bounds !
895 360 : IF (do_igaim) THEN
896 1764 : DO igrid_level = 1, gridlevel_info%ngrid_levels
897 1404 : my_rho => rs_rho(igrid_level)%r
898 1404 : my_current => rs_current(igrid_level)%r
899 : IF (LBOUND(my_rho, 3) /= LBOUND(my_current, 3) .OR. &
900 : LBOUND(my_rho, 2) /= LBOUND(my_current, 2) .OR. &
901 : LBOUND(my_rho, 1) /= LBOUND(my_current, 1) .OR. &
902 : UBOUND(my_rho, 3) /= UBOUND(my_current, 3) .OR. &
903 18252 : UBOUND(my_rho, 2) /= UBOUND(my_current, 2) .OR. &
904 : UBOUND(my_rho, 1) /= UBOUND(my_current, 1)) THEN
905 0 : WRITE (*, *) 'LBOUND(my_rho,3),LBOUND(my_current,3)', LBOUND(my_rho, 3), LBOUND(my_current, 3)
906 0 : WRITE (*, *) 'LBOUND(my_rho,2),LBOUND(my_current,2)', LBOUND(my_rho, 2), LBOUND(my_current, 2)
907 0 : WRITE (*, *) 'LBOUND(my_rho,1),LBOUND(my_current,1)', LBOUND(my_rho, 1), LBOUND(my_current, 1)
908 0 : WRITE (*, *) 'UBOUND(my_rho,3),UBOUND(my_current,3)', UBOUND(my_rho, 3), UBOUND(my_current, 3)
909 0 : WRITE (*, *) 'UBOUND(my_rho,2),UBOUND(my_current,2)', UBOUND(my_rho, 2), UBOUND(my_current, 2)
910 0 : WRITE (*, *) 'UBOUND(my_rho,1),UBOUND(my_current,1)', UBOUND(my_rho, 1), UBOUND(my_current, 1)
911 0 : CPABORT("Bug")
912 : END IF
913 :
914 1404 : my_gauge => rs_gauge(1, igrid_level)%r
915 : IF (LBOUND(my_rho, 3) /= LBOUND(my_gauge, 3) .OR. &
916 : LBOUND(my_rho, 2) /= LBOUND(my_gauge, 2) .OR. &
917 : LBOUND(my_rho, 1) /= LBOUND(my_gauge, 1) .OR. &
918 : UBOUND(my_rho, 3) /= UBOUND(my_gauge, 3) .OR. &
919 16848 : UBOUND(my_rho, 2) /= UBOUND(my_gauge, 2) .OR. &
920 360 : UBOUND(my_rho, 1) /= UBOUND(my_gauge, 1)) THEN
921 0 : WRITE (*, *) 'LBOUND(my_rho,3),LBOUND(my_gauge,3)', LBOUND(my_rho, 3), LBOUND(my_gauge, 3)
922 0 : WRITE (*, *) 'LBOUND(my_rho,2),LBOUND(my_gauge,2)', LBOUND(my_rho, 2), LBOUND(my_gauge, 2)
923 0 : WRITE (*, *) 'LBOUND(my_rho,1),LBOUND(my_gauge,1)', LBOUND(my_rho, 1), LBOUND(my_gauge, 1)
924 0 : WRITE (*, *) 'UBOUND(my_rho,3),UbOUND(my_gauge,3)', UBOUND(my_rho, 3), UBOUND(my_gauge, 3)
925 0 : WRITE (*, *) 'UBOUND(my_rho,2),UBOUND(my_gauge,2)', UBOUND(my_rho, 2), UBOUND(my_gauge, 2)
926 0 : WRITE (*, *) 'UBOUND(my_rho,1),UBOUND(my_gauge,1)', UBOUND(my_rho, 1), UBOUND(my_gauge, 1)
927 0 : CPABORT("Bug")
928 : END IF
929 : END DO
930 : END IF
931 : !
932 : !-------------------------------------------------------------
933 :
934 2286 : IF (distributed_rs_grids) THEN
935 : CALL rs_distribute_matrix(rs_descs=rs_descs, pmats=deltajp_a, &
936 : atom_pair_send=atom_pair_send, atom_pair_recv=atom_pair_recv, &
937 0 : nimages=nimages, scatter=.TRUE.)
938 : CALL rs_distribute_matrix(rs_descs=rs_descs, pmats=deltajp_b, &
939 : atom_pair_send=atom_pair_send, atom_pair_recv=atom_pair_recv, &
940 0 : nimages=nimages, scatter=.TRUE.)
941 : CALL rs_distribute_matrix(rs_descs=rs_descs, pmats=deltajp_c, &
942 : atom_pair_send=atom_pair_send, atom_pair_recv=atom_pair_recv, &
943 0 : nimages=nimages, scatter=.TRUE.)
944 0 : IF (do_igaim) CALL rs_distribute_matrix(rs_descs=rs_descs, pmats=deltajp_d, &
945 : atom_pair_send=atom_pair_send, atom_pair_recv=atom_pair_recv, &
946 0 : nimages=nimages, scatter=.TRUE.)
947 : END IF
948 :
949 2286 : ithread = 0
950 2286 : jpab_a => jpabt_a(:, :, ithread)
951 2286 : jpab_b => jpabt_b(:, :, ithread)
952 2286 : jpab_c => jpabt_c(:, :, ithread)
953 2286 : IF (do_igaim) jpab_d => jpabt_d(:, :, ithread)
954 2286 : work => workt(:, :, ithread)
955 :
956 2286 : iatom_old = -1; jatom_old = -1; iset_old = -1; jset_old = -1
957 2286 : ikind_old = -1; jkind_old = -1
958 :
959 156348 : loop_tasks: DO itask = 1, ntasks
960 154062 : igrid_level = tasks(itask)%grid_level
961 154062 : cindex = tasks(itask)%image
962 154062 : iatom = tasks(itask)%iatom
963 154062 : jatom = tasks(itask)%jatom
964 154062 : iset = tasks(itask)%iset
965 154062 : jset = tasks(itask)%jset
966 154062 : ipgf = tasks(itask)%ipgf
967 154062 : jpgf = tasks(itask)%jpgf
968 :
969 : ! apparently generalised collocation not implemented correctly yet
970 154062 : CPASSERT(tasks(itask)%dist_type /= 2)
971 :
972 154062 : IF (iatom /= iatom_old .OR. jatom /= jatom_old) THEN
973 :
974 23058 : ikind = particle_set(iatom)%atomic_kind%kind_number
975 23058 : jkind = particle_set(jatom)%atomic_kind%kind_number
976 :
977 23058 : IF (iatom /= iatom_old) ra(:) = pbc(particle_set(iatom)%r, cell)
978 :
979 23058 : brow = iatom
980 23058 : bcol = jatom
981 :
982 23058 : IF (ikind /= ikind_old) THEN
983 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, &
984 3342 : basis_type=basis_type)
985 :
986 : CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
987 : first_sgf=first_sgfa, &
988 : lmax=la_max, &
989 : lmin=la_min, &
990 : npgf=npgfa, &
991 : nset=nseta, &
992 : nsgf_set=nsgfa, &
993 : pgf_radius=rpgfa, &
994 : set_radius=set_radius_a, &
995 : sphi=sphi_a, &
996 3342 : zet=zeta)
997 : END IF
998 :
999 23058 : IF (jkind /= jkind_old) THEN
1000 :
1001 : CALL get_qs_kind(qs_kind_set(jkind), &
1002 12252 : basis_set=orb_basis_set, basis_type=basis_type)
1003 :
1004 : CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
1005 : first_sgf=first_sgfb, &
1006 : kind_radius=kind_radius_b, &
1007 : lmax=lb_max, &
1008 : lmin=lb_min, &
1009 : npgf=npgfb, &
1010 : nset=nsetb, &
1011 : nsgf_set=nsgfb, &
1012 : pgf_radius=rpgfb, &
1013 : set_radius=set_radius_b, &
1014 : sphi=sphi_b, &
1015 12252 : zet=zetb)
1016 :
1017 : END IF
1018 :
1019 : CALL dbcsr_get_block_p(matrix=deltajp_a(1)%matrix, row=brow, col=bcol, &
1020 23058 : block=jp_block_a, found=den_found)
1021 : CALL dbcsr_get_block_p(matrix=deltajp_b(1)%matrix, row=brow, col=bcol, &
1022 23058 : block=jp_block_b, found=den_found)
1023 : CALL dbcsr_get_block_p(matrix=deltajp_c(1)%matrix, row=brow, col=bcol, &
1024 23058 : block=jp_block_c, found=den_found)
1025 23058 : IF (do_igaim) CALL dbcsr_get_block_p(matrix=deltajp_d(1)%matrix, row=brow, col=bcol, &
1026 5229 : block=jp_block_d, found=den_found)
1027 :
1028 23058 : IF (.NOT. ASSOCIATED(jp_block_a)) THEN
1029 0 : CPABORT("p_block not associated in deltap")
1030 : END IF
1031 :
1032 : iatom_old = iatom
1033 : jatom_old = jatom
1034 : ikind_old = ikind
1035 : jkind_old = jkind
1036 :
1037 : atom_pair_changed = .TRUE.
1038 :
1039 : ELSE
1040 :
1041 : atom_pair_changed = .FALSE.
1042 :
1043 : END IF
1044 :
1045 154062 : IF (atom_pair_changed .OR. iset_old /= iset .OR. jset_old /= jset) THEN
1046 :
1047 55695 : ncoa = npgfa(iset)*ncoset(la_max(iset))
1048 55695 : sgfa = first_sgfa(1, iset)
1049 55695 : ncob = npgfb(jset)*ncoset(lb_max(jset))
1050 55695 : sgfb = first_sgfb(1, jset)
1051 : ! Decontraction step for the selected blocks of the 3 density matrices
1052 :
1053 : CALL dgemm("N", "N", ncoa, nsgfb(jset), nsgfa(iset), &
1054 : 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
1055 : jp_block_a(sgfa, sgfb), SIZE(jp_block_a, 1), &
1056 55695 : 0.0_dp, work(1, 1), maxco)
1057 : CALL dgemm("N", "T", ncoa, ncob, nsgfb(jset), &
1058 : 1.0_dp, work(1, 1), maxco, &
1059 : sphi_b(1, sgfb), SIZE(sphi_b, 1), &
1060 55695 : 0.0_dp, jpab_a(1, 1), maxco)
1061 :
1062 : CALL dgemm("N", "N", ncoa, nsgfb(jset), nsgfa(iset), &
1063 : 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
1064 : jp_block_b(sgfa, sgfb), SIZE(jp_block_b, 1), &
1065 55695 : 0.0_dp, work(1, 1), maxco)
1066 : CALL dgemm("N", "T", ncoa, ncob, nsgfb(jset), &
1067 : 1.0_dp, work(1, 1), maxco, &
1068 : sphi_b(1, sgfb), SIZE(sphi_b, 1), &
1069 55695 : 0.0_dp, jpab_b(1, 1), maxco)
1070 :
1071 : CALL dgemm("N", "N", ncoa, nsgfb(jset), nsgfa(iset), &
1072 : 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
1073 : jp_block_c(sgfa, sgfb), SIZE(jp_block_c, 1), &
1074 55695 : 0.0_dp, work(1, 1), maxco)
1075 : CALL dgemm("N", "T", ncoa, ncob, nsgfb(jset), &
1076 : 1.0_dp, work(1, 1), maxco, &
1077 : sphi_b(1, sgfb), SIZE(sphi_b, 1), &
1078 55695 : 0.0_dp, jpab_c(1, 1), maxco)
1079 :
1080 55695 : IF (do_igaim) THEN
1081 : CALL dgemm("N", "N", ncoa, nsgfb(jset), nsgfa(iset), &
1082 : 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
1083 : jp_block_d(sgfa, sgfb), SIZE(jp_block_d, 1), &
1084 12105 : 0.0_dp, work(1, 1), maxco)
1085 : CALL dgemm("N", "T", ncoa, ncob, nsgfb(jset), &
1086 : 1.0_dp, work(1, 1), maxco, &
1087 : sphi_b(1, sgfb), SIZE(sphi_b, 1), &
1088 12105 : 0.0_dp, jpab_d(1, 1), maxco)
1089 : END IF
1090 :
1091 : iset_old = iset
1092 : jset_old = jset
1093 :
1094 : END IF
1095 :
1096 51354 : SELECT CASE (idir)
1097 : CASE (1)
1098 51354 : adbmdab_func = GRID_FUNC_ADBmDAB_X
1099 : CASE (2)
1100 51354 : adbmdab_func = GRID_FUNC_ADBmDAB_Y
1101 : CASE (3)
1102 51354 : adbmdab_func = GRID_FUNC_ADBmDAB_Z
1103 : CASE DEFAULT
1104 154062 : CPABORT("invalid idir")
1105 : END SELECT
1106 :
1107 616248 : rab(:) = tasks(itask)%rab
1108 616248 : rb(:) = ra(:) + rab(:)
1109 154062 : zetp = zeta(ipgf, iset) + zetb(jpgf, jset)
1110 154062 : f = zetb(jpgf, jset)/zetp
1111 616248 : prefactor = EXP(-zeta(ipgf, iset)*f*DOT_PRODUCT(rab, rab))
1112 616248 : rp(:) = ra(:) + f*rab(:)
1113 :
1114 154062 : na1 = (ipgf - 1)*ncoset(la_max(iset)) + 1
1115 154062 : na2 = ipgf*ncoset(la_max(iset))
1116 154062 : nb1 = (jpgf - 1)*ncoset(lb_max(jset)) + 1
1117 154062 : nb2 = jpgf*ncoset(lb_max(jset))
1118 :
1119 : ! Four calls to the general collocate density, to multply the correct function
1120 : ! to each density matrix
1121 :
1122 : !
1123 : ! here the decontracted mat_jp_{ab} is multiplied by
1124 : ! f_{ab} = g_{a} (dg_{b}/dr)_{idir} - (dg_{a}/dr)_{idir} g_{b}
1125 154062 : scale = 1.0_dp
1126 : radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
1127 : lb_min=lb_min(jset), lb_max=lb_max(jset), &
1128 : ra=ra, rb=rb, rp=rp, zetp=zetp, eps=eps_rho_rspace, &
1129 154062 : prefactor=prefactor, cutoff=1.0_dp)
1130 :
1131 : CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), &
1132 : la_min(iset), lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
1133 : ra, rab, scale, jpab_a, na1 - 1, nb1 - 1, &
1134 : rs_current(igrid_level), &
1135 154062 : radius=radius, ga_gb_function=adbmdab_func)
1136 156348 : IF (do_igaim) THEN
1137 : ! here the decontracted mat_jb_{ab} is multiplied by
1138 : ! f_{ab} = g_{a} * g_{b} ! THIS GOES OUTSIDE THE LOOP !
1139 20574 : IF (scale2 /= 0.0_dp) THEN
1140 : CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), &
1141 : la_min(iset), lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
1142 : ra, rab, scale2, jpab_d, na1 - 1, nb1 - 1, &
1143 : rs_rho(igrid_level), &
1144 13716 : radius=radius, ga_gb_function=GRID_FUNC_AB)
1145 : END IF !rm
1146 : ! here the decontracted mat_jp_rii{ab} is multiplied by
1147 : ! f_{ab} = g_{a} (d(r) - R_{b})_{iiB} (dg_{b}/dr)_{idir} -
1148 : ! (dg_{a}/dr)_{idir} (d(r) - R_{b})_{iiB} g_{b}
1149 : scale = 1.0_dp
1150 512067753 : current_env%rs_buf(igrid_level)%r(:, :, :) = 0.0_dp
1151 : CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), &
1152 : la_min(iset), lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
1153 : ra, rab, scale, jpab_b, na1 - 1, nb1 - 1, &
1154 : radius=radius, &
1155 : ga_gb_function=adbmdab_func, &
1156 20574 : rsgrid=current_env%rs_buf(igrid_level))
1157 : CALL collocate_gauge_ortho(rsgrid=current_env%rs_buf(igrid_level), &
1158 : rsbuf=rs_current(igrid_level), &
1159 : rsgauge=rs_gauge(iiiB, igrid_level), &
1160 : cube_info=cube_info(igrid_level), radius=radius, &
1161 : zeta=zeta(ipgf, iset), zetb=zetb(jpgf, jset), &
1162 20574 : ra=ra, rab=rab, ir=iiiB)
1163 :
1164 : ! here the decontracted mat_jp_riii{ab} is multiplied by
1165 : ! f_{ab} = -g_{a} (d(r) - R_{b})_{iiB} (dg_{b}/dr)_{idir} +
1166 : ! (dg_{a}/dr)_{idir} (d(r) - R_{b})_{iiB} g_{b}
1167 20574 : scale = -1.0_dp
1168 512067753 : current_env%rs_buf(igrid_level)%r(:, :, :) = 0.0_dp
1169 : CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), &
1170 : la_min(iset), lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
1171 : ra, rab, scale, jpab_c, na1 - 1, nb1 - 1, &
1172 : radius=radius, &
1173 : ga_gb_function=adbmdab_func, &
1174 20574 : rsgrid=current_env%rs_buf(igrid_level))
1175 : CALL collocate_gauge_ortho(rsgrid=current_env%rs_buf(igrid_level), &
1176 : rsbuf=rs_current(igrid_level), &
1177 : rsgauge=rs_gauge(iiB, igrid_level), &
1178 : cube_info=cube_info(igrid_level), radius=radius, &
1179 : zeta=zeta(ipgf, iset), zetb=zetb(jpgf, jset), &
1180 20574 : ra=ra, rab=rab, ir=iiB)
1181 : ELSE
1182 : ! here the decontracted mat_jp_rii{ab} is multiplied by
1183 : ! f_{ab} = g_{a} (r - R_{b})_{iiB} (dg_{b}/dr)_{idir} -
1184 : ! (dg_{a}/dr)_{idir} (r - R_{b})_{iiB} g_{b}
1185 : scale = 1.0_dp
1186 : CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), &
1187 : la_min(iset), lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
1188 : ra, rab, scale, jpab_b, na1 - 1, nb1 - 1, &
1189 : rs_current(igrid_level), &
1190 : radius=radius, &
1191 133488 : ga_gb_function=encode_ardbmdarb_func(idir=idir, ir=iiiB))
1192 : ! here the decontracted mat_jp_riii{ab} is multiplied by
1193 : ! f_{ab} = -g_{a} (r - R_{b})_{iiB} (dg_{b}/dr)_{idir} +
1194 : ! (dg_{a}/dr)_{idir} (r - R_{b})_{iiB} g_{b}
1195 133488 : scale = -1.0_dp
1196 : CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), &
1197 : la_min(iset), lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
1198 : ra, rab, scale, jpab_c, na1 - 1, nb1 - 1, &
1199 : rs_current(igrid_level), &
1200 : radius=radius, &
1201 133488 : ga_gb_function=encode_ardbmdarb_func(idir=idir, ir=iiB))
1202 : END IF
1203 :
1204 : END DO loop_tasks
1205 : !
1206 : ! Scale the density with the gauge rho * ( r - d(r) ) if needed
1207 2286 : IF (do_igaim) THEN
1208 1764 : DO igrid_level = 1, gridlevel_info%ngrid_levels
1209 : CALL rs_grid_mult_and_add(rs_current(igrid_level), rs_rho(igrid_level), &
1210 1764 : rs_gauge(idir2, igrid_level), 1.0_dp)
1211 : END DO
1212 : END IF
1213 : ! *** Release work storage ***
1214 :
1215 2286 : IF (distributed_rs_grids) THEN
1216 0 : CALL dbcsr_deallocate_matrix(deltajp_a(1)%matrix)
1217 0 : CALL dbcsr_deallocate_matrix(deltajp_b(1)%matrix)
1218 0 : CALL dbcsr_deallocate_matrix(deltajp_c(1)%matrix)
1219 0 : IF (do_igaim) CALL dbcsr_deallocate_matrix(deltajp_d(1)%matrix)
1220 : END IF
1221 2286 : DEALLOCATE (deltajp_a, deltajp_b, deltajp_c, deltajp_d)
1222 :
1223 2286 : DEALLOCATE (jpabt_a, jpabt_b, jpabt_c, jpabt_d, workt, tasks)
1224 :
1225 2286 : IF (ASSOCIATED(atom_pair_send)) DEALLOCATE (atom_pair_send)
1226 2286 : IF (ASSOCIATED(atom_pair_recv)) DEALLOCATE (atom_pair_recv)
1227 :
1228 2286 : CALL density_rs2pw(pw_env, rs_current, current_rs, current_gs)
1229 11394 : DO i = 1, SIZE(rs_current)
1230 11394 : CALL rs_grid_release(rs_current(i))
1231 : END DO
1232 :
1233 11394 : DO i = 1, SIZE(rs_rho)
1234 11394 : IF (rs_descs(i)%rs_desc%distributed .AND. .NOT. my_retain_rsgrid) THEN
1235 0 : CALL rs_grid_release(rs_rho(i))
1236 : END IF
1237 : END DO
1238 :
1239 : ! Free the array of grids (grids themselves are released in density_rs2pw)
1240 2286 : DEALLOCATE (rs_current)
1241 :
1242 2286 : CALL timestop(handle)
1243 :
1244 6858 : END SUBROUTINE calculate_jrho_resp
1245 :
1246 : ! **************************************************************************************************
1247 : !> \brief ...
1248 : !> \param idir ...
1249 : !> \param ir ...
1250 : !> \return ...
1251 : ! **************************************************************************************************
1252 266976 : FUNCTION encode_ardbmdarb_func(idir, ir) RESULT(func)
1253 : INTEGER, INTENT(IN) :: idir, ir
1254 : INTEGER :: func
1255 :
1256 266976 : CPASSERT(1 <= idir .AND. idir <= 3 .AND. 1 <= ir .AND. ir <= 3)
1257 266976 : SELECT CASE (10*idir + ir)
1258 : CASE (11)
1259 30426 : func = GRID_FUNC_ARDBmDARB_XX
1260 : CASE (12)
1261 30426 : func = GRID_FUNC_ARDBmDARB_XY
1262 : CASE (13)
1263 30426 : func = GRID_FUNC_ARDBmDARB_XZ
1264 : CASE (21)
1265 30426 : func = GRID_FUNC_ARDBmDARB_YX
1266 : CASE (22)
1267 28140 : func = GRID_FUNC_ARDBmDARB_YY
1268 : CASE (23)
1269 30426 : func = GRID_FUNC_ARDBmDARB_YZ
1270 : CASE (31)
1271 30426 : func = GRID_FUNC_ARDBmDARB_ZX
1272 : CASE (32)
1273 30426 : func = GRID_FUNC_ARDBmDARB_ZY
1274 : CASE (33)
1275 28140 : func = GRID_FUNC_ARDBmDARB_ZZ
1276 : CASE DEFAULT
1277 266976 : CPABORT("invalid idir or iiiB")
1278 : END SELECT
1279 266976 : END FUNCTION encode_ardbmdarb_func
1280 :
1281 : ! **************************************************************************************************
1282 : !> \brief ...
1283 : !> \param rsgrid ...
1284 : !> \param rsbuf ...
1285 : !> \param rsgauge ...
1286 : !> \param cube_info ...
1287 : !> \param radius ...
1288 : !> \param ra ...
1289 : !> \param rab ...
1290 : !> \param zeta ...
1291 : !> \param zetb ...
1292 : !> \param ir ...
1293 : ! **************************************************************************************************
1294 41148 : SUBROUTINE collocate_gauge_ortho(rsgrid, rsbuf, rsgauge, cube_info, radius, ra, rab, zeta, zetb, ir)
1295 : TYPE(realspace_grid_type) :: rsgrid, rsbuf, rsgauge
1296 : TYPE(cube_info_type), INTENT(IN) :: cube_info
1297 : REAL(KIND=dp), INTENT(IN) :: radius
1298 : REAL(KIND=dp), DIMENSION(3), INTENT(IN) :: ra, rab
1299 : REAL(KIND=dp), INTENT(IN) :: zeta, zetb
1300 : INTEGER, INTENT(IN) :: ir
1301 :
1302 : INTEGER :: cmax, i, ig, igmax, igmin, j, j2, jg, &
1303 : jg2, jgmin, k, k2, kg, kg2, kgmin, &
1304 : length, offset, sci, start
1305 41148 : INTEGER, ALLOCATABLE, DIMENSION(:, :) :: map
1306 : INTEGER, DIMENSION(3) :: cubecenter, lb_cube, ng, ub_cube
1307 41148 : INTEGER, DIMENSION(:), POINTER :: sphere_bounds
1308 : REAL(KIND=dp) :: f, point(3, 4), res(4), x, y, y2, z, z2, &
1309 : zetp
1310 : REAL(KIND=dp), DIMENSION(3) :: dr, rap, rb, rbp, roffset, rp
1311 41148 : REAL(kind=dp), DIMENSION(:, :, :), POINTER :: gauge, grid, grid_buf
1312 :
1313 0 : CPASSERT(rsgrid%desc%orthorhombic)
1314 41148 : NULLIFY (sphere_bounds)
1315 :
1316 41148 : grid => rsgrid%r(:, :, :)
1317 41148 : grid_buf => rsbuf%r(:, :, :)
1318 41148 : gauge => rsgauge%r(:, :, :)
1319 :
1320 : ! *** center of gaussians and their product
1321 41148 : zetp = zeta + zetb
1322 41148 : f = zetb/zetp
1323 164592 : rap(:) = f*rab(:)
1324 164592 : rbp(:) = rap(:) - rab(:)
1325 164592 : rp(:) = ra(:) + rap(:)
1326 164592 : rb(:) = ra(:) + rab(:)
1327 :
1328 : ! *** properties of the grid ***
1329 164592 : ng(:) = rsgrid%desc%npts(:)
1330 41148 : dr(1) = rsgrid%desc%dh(1, 1)
1331 41148 : dr(2) = rsgrid%desc%dh(2, 2)
1332 41148 : dr(3) = rsgrid%desc%dh(3, 3)
1333 :
1334 : ! *** get the sub grid properties for the given radius ***
1335 41148 : CALL return_cube(cube_info, radius, lb_cube, ub_cube, sphere_bounds)
1336 164592 : cmax = MAXVAL(ub_cube)
1337 :
1338 : ! *** position of the gaussian product
1339 : !
1340 : ! this is the actual definition of the position on the grid
1341 : ! i.e. a point rp(:) gets here grid coordinates
1342 : ! MODULO(rp(:)/dr(:),ng(:))+1
1343 : ! hence (0.0,0.0,0.0) in real space is rsgrid%lb on the rsgrid ((1,1,1) on grid)
1344 : !
1345 164592 : ALLOCATE (map(-cmax:cmax, 3))
1346 3221964 : map(:, :) = -1
1347 41148 : CALL compute_cube_center(cubecenter, rsgrid%desc, zeta, zetb, ra, rab)
1348 164592 : roffset(:) = rp(:) - REAL(cubecenter(:), dp)*dr(:)
1349 :
1350 : ! *** a mapping so that the ig corresponds to the right grid point
1351 164592 : DO i = 1, 3
1352 164592 : IF (rsgrid%desc%perd(i) == 1) THEN
1353 123444 : start = lb_cube(i)
1354 123354 : DO
1355 246798 : offset = MODULO(cubecenter(i) + start, ng(i)) + 1 - start
1356 246798 : length = MIN(ub_cube(i), ng(i) - offset) - start
1357 3180726 : DO ig = start, start + length
1358 3180726 : map(ig, i) = ig + offset
1359 : END DO
1360 246798 : IF (start + length >= ub_cube(i)) EXIT
1361 123354 : start = start + length + 1
1362 : END DO
1363 : ELSE
1364 : ! this takes partial grid + border regions into account
1365 0 : offset = MODULO(cubecenter(i) + lb_cube(i) + rsgrid%desc%lb(i) - rsgrid%lb_local(i), ng(i)) + 1 - lb_cube(i)
1366 : ! check for out of bounds
1367 0 : IF (ub_cube(i) + offset > UBOUND(grid, i) .OR. lb_cube(i) + offset < LBOUND(grid, i)) THEN
1368 0 : CPABORT("Cube bound out of grid bounds")
1369 : END IF
1370 0 : DO ig = lb_cube(i), ub_cube(i)
1371 0 : map(ig, i) = ig + offset
1372 : END DO
1373 : END IF
1374 : END DO
1375 :
1376 : ! *** actually loop over the grid
1377 41148 : sci = 1
1378 41148 : kgmin = sphere_bounds(sci)
1379 41148 : sci = sci + 1
1380 530136 : DO kg = kgmin, 0
1381 488988 : kg2 = 1 - kg
1382 488988 : k = map(kg, 3)
1383 488988 : k2 = map(kg2, 3)
1384 488988 : jgmin = sphere_bounds(sci)
1385 488988 : sci = sci + 1
1386 488988 : z = (REAL(kg, dp) + REAL(cubecenter(3), dp))*dr(3)
1387 488988 : z2 = (REAL(kg2, dp) + REAL(cubecenter(3), dp))*dr(3)
1388 5604174 : DO jg = jgmin, 0
1389 5074038 : jg2 = 1 - jg
1390 5074038 : j = map(jg, 2)
1391 5074038 : j2 = map(jg2, 2)
1392 5074038 : igmin = sphere_bounds(sci)
1393 5074038 : sci = sci + 1
1394 5074038 : igmax = 1 - igmin
1395 5074038 : y = (REAL(jg, dp) + REAL(cubecenter(2), dp))*dr(2)
1396 5074038 : y2 = (REAL(jg2, dp) + REAL(cubecenter(2), dp))*dr(2)
1397 118256958 : DO ig = igmin, igmax
1398 112693932 : i = map(ig, 1)
1399 112693932 : x = (REAL(ig, dp) + REAL(cubecenter(1), dp))*dr(1)
1400 112693932 : point(1, 1) = x; point(2, 1) = y; point(3, 1) = z
1401 112693932 : point(1, 2) = x; point(2, 2) = y2; point(3, 2) = z
1402 112693932 : point(1, 3) = x; point(2, 3) = y; point(3, 3) = z2
1403 112693932 : point(1, 4) = x; point(2, 4) = y2; point(3, 4) = z2
1404 : !
1405 112693932 : res(1) = (point(ir, 1) - rb(ir)) - gauge(i, j, k)
1406 112693932 : res(2) = (point(ir, 2) - rb(ir)) - gauge(i, j2, k)
1407 112693932 : res(3) = (point(ir, 3) - rb(ir)) - gauge(i, j, k2)
1408 112693932 : res(4) = (point(ir, 4) - rb(ir)) - gauge(i, j2, k2)
1409 : !
1410 112693932 : grid_buf(i, j, k) = grid_buf(i, j, k) + grid(i, j, k)*res(1)
1411 112693932 : grid_buf(i, j2, k) = grid_buf(i, j2, k) + grid(i, j2, k)*res(2)
1412 112693932 : grid_buf(i, j, k2) = grid_buf(i, j, k2) + grid(i, j, k2)*res(3)
1413 117767970 : grid_buf(i, j2, k2) = grid_buf(i, j2, k2) + grid(i, j2, k2)*res(4)
1414 : END DO
1415 : END DO
1416 : END DO
1417 82296 : END SUBROUTINE collocate_gauge_ortho
1418 :
1419 : ! **************************************************************************************************
1420 : !> \brief ...
1421 : !> \param current_env ...
1422 : !> \param qs_env ...
1423 : ! **************************************************************************************************
1424 28 : SUBROUTINE current_set_gauge(current_env, qs_env)
1425 : !
1426 : TYPE(current_env_type) :: current_env
1427 : TYPE(qs_environment_type), POINTER :: qs_env
1428 :
1429 : CHARACTER(LEN=*), PARAMETER :: routineN = 'current_set_gauge'
1430 :
1431 : INTEGER :: idir
1432 : REAL(dp) :: dbox(3)
1433 28 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: box_data
1434 : INTEGER :: handle, igrid_level, nbox(3), gauge
1435 28 : INTEGER, ALLOCATABLE, DIMENSION(:, :, :) :: box_ptr
1436 : TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
1437 28 : POINTER :: rs_descs
1438 : TYPE(pw_env_type), POINTER :: pw_env
1439 28 : TYPE(realspace_grid_type), DIMENSION(:, :), POINTER :: rs_gauge
1440 :
1441 28 : TYPE(box_type), DIMENSION(:, :, :), POINTER :: box
1442 : LOGICAL :: use_old_gauge_atom
1443 :
1444 28 : NULLIFY (rs_gauge, box)
1445 :
1446 28 : CALL timeset(routineN, handle)
1447 :
1448 : CALL get_current_env(current_env=current_env, &
1449 : use_old_gauge_atom=use_old_gauge_atom, &
1450 : rs_gauge=rs_gauge, &
1451 28 : gauge=gauge)
1452 :
1453 28 : IF (gauge == current_gauge_atom) THEN
1454 : CALL get_qs_env(qs_env=qs_env, &
1455 28 : pw_env=pw_env)
1456 : CALL pw_env_get(pw_env=pw_env, &
1457 28 : rs_descs=rs_descs)
1458 : !
1459 : ! box the atoms
1460 28 : IF (use_old_gauge_atom) THEN
1461 22 : CALL box_atoms(qs_env)
1462 : ELSE
1463 6 : CALL box_atoms_new(current_env, qs_env, box)
1464 : END IF
1465 : !
1466 : ! allocate and build the gauge
1467 136 : DO igrid_level = pw_env%gridlevel_info%ngrid_levels, 1, -1
1468 :
1469 432 : DO idir = 1, 3
1470 432 : CALL rs_grid_create(rs_gauge(idir, igrid_level), rs_descs(igrid_level)%rs_desc)
1471 : END DO
1472 :
1473 136 : IF (use_old_gauge_atom) THEN
1474 : CALL collocate_gauge(current_env, qs_env, &
1475 : rs_gauge(1, igrid_level), &
1476 : rs_gauge(2, igrid_level), &
1477 88 : rs_gauge(3, igrid_level))
1478 : ELSE
1479 : CALL collocate_gauge_new(current_env, qs_env, &
1480 : rs_gauge(1, igrid_level), &
1481 : rs_gauge(2, igrid_level), &
1482 : rs_gauge(3, igrid_level), &
1483 20 : box)
1484 : END IF
1485 : END DO
1486 : !
1487 : ! allocate the buf
1488 724 : ALLOCATE (current_env%rs_buf(pw_env%gridlevel_info%ngrid_levels))
1489 136 : DO igrid_level = 1, pw_env%gridlevel_info%ngrid_levels
1490 136 : CALL rs_grid_create(current_env%rs_buf(igrid_level), rs_descs(igrid_level)%rs_desc)
1491 : END DO
1492 : !
1493 28 : DEALLOCATE (box_ptr, box_data)
1494 28 : CALL deallocate_box(box)
1495 : END IF
1496 :
1497 56 : CALL timestop(handle)
1498 :
1499 : CONTAINS
1500 :
1501 : ! **************************************************************************************************
1502 : !> \brief ...
1503 : !> \param qs_env ...
1504 : ! **************************************************************************************************
1505 22 : SUBROUTINE box_atoms(qs_env)
1506 : TYPE(qs_environment_type), POINTER :: qs_env
1507 :
1508 : REAL(kind=dp), PARAMETER :: box_size_guess = 5.0_dp
1509 :
1510 : INTEGER :: i, iatom, ibox, ii, jbox, kbox, natms
1511 : REAL(dp) :: offset(3)
1512 22 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: ratom
1513 : TYPE(cell_type), POINTER :: cell
1514 22 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1515 22 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1516 :
1517 : CALL get_qs_env(qs_env=qs_env, &
1518 : qs_kind_set=qs_kind_set, &
1519 : cell=cell, &
1520 22 : particle_set=particle_set)
1521 :
1522 22 : natms = SIZE(particle_set, 1)
1523 66 : ALLOCATE (ratom(3, natms))
1524 : !
1525 : ! box the atoms
1526 22 : nbox(1) = CEILING(cell%hmat(1, 1)/box_size_guess)
1527 22 : nbox(2) = CEILING(cell%hmat(2, 2)/box_size_guess)
1528 22 : nbox(3) = CEILING(cell%hmat(3, 3)/box_size_guess)
1529 : !write(*,*) 'nbox',nbox
1530 22 : dbox(1) = cell%hmat(1, 1)/REAL(nbox(1), dp)
1531 22 : dbox(2) = cell%hmat(2, 2)/REAL(nbox(2), dp)
1532 22 : dbox(3) = cell%hmat(3, 3)/REAL(nbox(3), dp)
1533 : !write(*,*) 'dbox',dbox
1534 132 : ALLOCATE (box_ptr(0:nbox(1), 0:nbox(2) - 1, 0:nbox(3) - 1), box_data(3, natms))
1535 390 : box_data(:, :) = HUGE(0.0_dp)
1536 418 : box_ptr(:, :, :) = HUGE(0)
1537 : !
1538 22 : offset(1) = cell%hmat(1, 1)*0.5_dp
1539 22 : offset(2) = cell%hmat(2, 2)*0.5_dp
1540 22 : offset(3) = cell%hmat(3, 3)*0.5_dp
1541 114 : DO iatom = 1, natms
1542 390 : ratom(:, iatom) = pbc(particle_set(iatom)%r(:), cell) + offset(:)
1543 : END DO
1544 : !
1545 22 : i = 1
1546 66 : DO kbox = 0, nbox(3) - 1
1547 154 : DO jbox = 0, nbox(2) - 1
1548 88 : box_ptr(0, jbox, kbox) = i
1549 308 : DO ibox = 0, nbox(1) - 1
1550 : ii = 0
1551 912 : DO iatom = 1, natms
1552 : IF (INT(ratom(1, iatom)/dbox(1)) == ibox .AND. &
1553 736 : INT(ratom(2, iatom)/dbox(2)) == jbox .AND. &
1554 176 : INT(ratom(3, iatom)/dbox(3)) == kbox) THEN
1555 368 : box_data(:, i) = ratom(:, iatom) - offset(:)
1556 92 : i = i + 1
1557 92 : ii = ii + 1
1558 : END IF
1559 : END DO
1560 264 : box_ptr(ibox + 1, jbox, kbox) = box_ptr(ibox, jbox, kbox) + ii
1561 : END DO
1562 : END DO
1563 : END DO
1564 : !
1565 : IF (.FALSE.) THEN
1566 : DO kbox = 0, nbox(3) - 1
1567 : DO jbox = 0, nbox(2) - 1
1568 : DO ibox = 0, nbox(1) - 1
1569 : WRITE (*, *) 'box=', ibox, jbox, kbox
1570 : WRITE (*, *) 'nbr atom=', box_ptr(ibox + 1, jbox, kbox) - box_ptr(ibox, jbox, kbox)
1571 : DO iatom = box_ptr(ibox, jbox, kbox), box_ptr(ibox + 1, jbox, kbox) - 1
1572 : WRITE (*, *) 'iatom=', iatom
1573 : WRITE (*, '(A,3E14.6)') 'coor=', box_data(:, iatom)
1574 : END DO
1575 : END DO
1576 : END DO
1577 : END DO
1578 : END IF
1579 22 : DEALLOCATE (ratom)
1580 22 : END SUBROUTINE box_atoms
1581 :
1582 : ! **************************************************************************************************
1583 : !> \brief ...
1584 : !> \param current_env ...
1585 : !> \param qs_env ...
1586 : !> \param rs_grid_x ...
1587 : !> \param rs_grid_y ...
1588 : !> \param rs_grid_z ...
1589 : ! **************************************************************************************************
1590 88 : SUBROUTINE collocate_gauge(current_env, qs_env, rs_grid_x, rs_grid_y, rs_grid_z)
1591 : !
1592 : TYPE(current_env_type) :: current_env
1593 : TYPE(qs_environment_type), POINTER :: qs_env
1594 : TYPE(realspace_grid_type), INTENT(IN) :: rs_grid_x, rs_grid_y, rs_grid_z
1595 :
1596 : INTEGER :: i, iatom, ibeg, ibox, iend, imax, imin, &
1597 : j, jatom, jbox, jmax, jmin, k, kbox, &
1598 : kmax, kmin, lb(3), lb_local(3), natms, &
1599 : natms_local, ng(3)
1600 : REAL(KIND=dp) :: ab, buf_tmp, dist, dr(3), &
1601 : gauge_atom_radius, offset(3), pa, pb, &
1602 : point(3), pra(3), r(3), res(3), summe, &
1603 : tmp, x, y, z
1604 88 : REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: buf, nrm_atms_pnt
1605 88 : REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: atms_pnt, ratom
1606 88 : REAL(kind=dp), DIMENSION(:, :, :), POINTER :: grid_x, grid_y, grid_z
1607 : TYPE(cell_type), POINTER :: cell
1608 88 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1609 88 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1610 :
1611 : !
1612 :
1613 : CALL get_current_env(current_env=current_env, &
1614 88 : gauge_atom_radius=gauge_atom_radius)
1615 : !
1616 : CALL get_qs_env(qs_env=qs_env, &
1617 : qs_kind_set=qs_kind_set, &
1618 : cell=cell, &
1619 88 : particle_set=particle_set)
1620 : !
1621 88 : natms = SIZE(particle_set, 1)
1622 88 : dr(1) = rs_grid_x%desc%dh(1, 1)
1623 88 : dr(2) = rs_grid_x%desc%dh(2, 2)
1624 88 : dr(3) = rs_grid_x%desc%dh(3, 3)
1625 352 : lb(:) = rs_grid_x%desc%lb(:)
1626 352 : lb_local(:) = rs_grid_x%lb_local(:)
1627 88 : grid_x => rs_grid_x%r(:, :, :)
1628 88 : grid_y => rs_grid_y%r(:, :, :)
1629 88 : grid_z => rs_grid_z%r(:, :, :)
1630 352 : ng(:) = UBOUND(grid_x)
1631 88 : offset(1) = cell%hmat(1, 1)*0.5_dp
1632 88 : offset(2) = cell%hmat(2, 2)*0.5_dp
1633 88 : offset(3) = cell%hmat(3, 3)*0.5_dp
1634 616 : ALLOCATE (buf(natms), ratom(3, natms), atms_pnt(3, natms), nrm_atms_pnt(natms))
1635 : !
1636 : ! go over the grid
1637 1350 : DO k = 1, ng(3)
1638 26188 : DO j = 1, ng(2)
1639 618230 : DO i = 1, ng(1)
1640 : !
1641 592130 : point(3) = REAL(k - 1 + lb_local(3) - lb(3), dp)*dr(3)
1642 592130 : point(2) = REAL(j - 1 + lb_local(2) - lb(2), dp)*dr(2)
1643 592130 : point(1) = REAL(i - 1 + lb_local(1) - lb(1), dp)*dr(1)
1644 2368520 : point = pbc(point, cell)
1645 : !
1646 : ! run over the overlaping boxes
1647 592130 : natms_local = 0
1648 592130 : kmin = INT((point(3) + offset(3) - gauge_atom_radius)/dbox(3))
1649 592130 : kmax = INT((point(3) + offset(3) + gauge_atom_radius)/dbox(3))
1650 592130 : IF (kmax - kmin + 1 > nbox(3)) THEN
1651 527618 : kmin = 0
1652 527618 : kmax = nbox(3) - 1
1653 : END IF
1654 1735750 : DO kbox = kmin, kmax
1655 1143620 : jmin = INT((point(2) + offset(2) - gauge_atom_radius)/dbox(2))
1656 1143620 : jmax = INT((point(2) + offset(2) + gauge_atom_radius)/dbox(2))
1657 1143620 : IF (jmax - jmin + 1 > nbox(2)) THEN
1658 1055236 : jmin = 0
1659 1055236 : jmax = nbox(2) - 1
1660 : END IF
1661 3967326 : DO jbox = jmin, jmax
1662 2231576 : imin = INT((point(1) + offset(1) - gauge_atom_radius)/dbox(1))
1663 2231576 : imax = INT((point(1) + offset(1) + gauge_atom_radius)/dbox(1))
1664 2231576 : IF (imax - imin + 1 > nbox(1)) THEN
1665 2110472 : imin = 0
1666 2110472 : imax = nbox(1) - 1
1667 : END IF
1668 7762096 : DO ibox = imin, imax
1669 4386900 : ibeg = box_ptr(MODULO(ibox, nbox(1)), MODULO(jbox, nbox(2)), MODULO(kbox, nbox(3)))
1670 4386900 : iend = box_ptr(MODULO(ibox, nbox(1)) + 1, MODULO(jbox, nbox(2)), MODULO(kbox, nbox(3))) - 1
1671 9170920 : DO iatom = ibeg, iend
1672 20419552 : r(:) = pbc(box_data(:, iatom) - point(:), cell) + point(:)
1673 2552444 : dist = (r(1) - point(1))**2 + (r(2) - point(2))**2 + (r(3) - point(3))**2
1674 6939344 : IF (dist < gauge_atom_radius**2) THEN
1675 2505134 : natms_local = natms_local + 1
1676 10020536 : ratom(:, natms_local) = r(:)
1677 : !
1678 : ! compute the distance atoms-point
1679 2505134 : x = point(1) - r(1)
1680 2505134 : y = point(2) - r(2)
1681 2505134 : z = point(3) - r(3)
1682 2505134 : atms_pnt(1, natms_local) = x
1683 2505134 : atms_pnt(2, natms_local) = y
1684 2505134 : atms_pnt(3, natms_local) = z
1685 2505134 : nrm_atms_pnt(natms_local) = SQRT(x*x + y*y + z*z)
1686 : END IF
1687 : END DO
1688 : END DO
1689 : END DO
1690 : END DO
1691 : !
1692 616968 : IF (natms_local > 0) THEN
1693 : !
1694 : !
1695 3034004 : DO iatom = 1, natms_local
1696 2505134 : buf_tmp = 1.0_dp
1697 2505134 : pra(1) = atms_pnt(1, iatom)
1698 2505134 : pra(2) = atms_pnt(2, iatom)
1699 2505134 : pra(3) = atms_pnt(3, iatom)
1700 2505134 : pa = nrm_atms_pnt(iatom)
1701 15477460 : DO jatom = 1, natms_local
1702 12972326 : IF (iatom == jatom) CYCLE
1703 10467192 : pb = nrm_atms_pnt(jatom)
1704 10467192 : x = pra(1) - atms_pnt(1, jatom)
1705 10467192 : y = pra(2) - atms_pnt(2, jatom)
1706 10467192 : z = pra(3) - atms_pnt(3, jatom)
1707 10467192 : ab = SQRT(x*x + y*y + z*z)
1708 : !
1709 10467192 : tmp = (pa - pb)/ab
1710 10467192 : tmp = 0.5_dp*(3.0_dp - tmp*tmp)*tmp
1711 10467192 : tmp = 0.5_dp*(3.0_dp - tmp*tmp)*tmp
1712 10467192 : tmp = 0.5_dp*(3.0_dp - tmp*tmp)*tmp
1713 15477460 : buf_tmp = buf_tmp*0.5_dp*(1.0_dp - tmp)
1714 : END DO
1715 3034004 : buf(iatom) = buf_tmp
1716 : END DO
1717 : res(1) = 0.0_dp
1718 : res(2) = 0.0_dp
1719 : res(3) = 0.0_dp
1720 : summe = 0.0_dp
1721 3034004 : DO iatom = 1, natms_local
1722 2505134 : res(1) = res(1) + ratom(1, iatom)*buf(iatom)
1723 2505134 : res(2) = res(2) + ratom(2, iatom)*buf(iatom)
1724 2505134 : res(3) = res(3) + ratom(3, iatom)*buf(iatom)
1725 3034004 : summe = summe + buf(iatom)
1726 : END DO
1727 528870 : res(1) = res(1)/summe
1728 528870 : res(2) = res(2)/summe
1729 528870 : res(3) = res(3)/summe
1730 528870 : grid_x(i, j, k) = point(1) - res(1)
1731 528870 : grid_y(i, j, k) = point(2) - res(2)
1732 528870 : grid_z(i, j, k) = point(3) - res(3)
1733 : ELSE
1734 63260 : grid_x(i, j, k) = 0.0_dp
1735 63260 : grid_y(i, j, k) = 0.0_dp
1736 63260 : grid_z(i, j, k) = 0.0_dp
1737 : END IF
1738 : END DO
1739 : END DO
1740 : END DO
1741 :
1742 88 : DEALLOCATE (buf, ratom, atms_pnt, nrm_atms_pnt)
1743 :
1744 88 : END SUBROUTINE collocate_gauge
1745 :
1746 : ! **************************************************************************************************
1747 : !> \brief ...
1748 : !> \param current_env ...
1749 : !> \param qs_env ...
1750 : !> \param box ...
1751 : ! **************************************************************************************************
1752 6 : SUBROUTINE box_atoms_new(current_env, qs_env, box)
1753 : TYPE(current_env_type) :: current_env
1754 : TYPE(qs_environment_type), POINTER :: qs_env
1755 : TYPE(box_type), DIMENSION(:, :, :), POINTER :: box
1756 :
1757 : CHARACTER(LEN=*), PARAMETER :: routineN = 'box_atoms_new'
1758 :
1759 : INTEGER :: handle, i, iatom, ibeg, ibox, iend, &
1760 : ifind, ii, imax, imin, j, jatom, jbox, &
1761 : jmax, jmin, k, kbox, kmax, kmin, &
1762 : natms, natms_local
1763 : REAL(dp) :: gauge_atom_radius, offset(3), scale
1764 6 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: ratom
1765 6 : REAL(dp), DIMENSION(:, :), POINTER :: r_ptr
1766 : REAL(kind=dp) :: box_center(3), box_center_wrap(3), &
1767 : box_size_guess, r(3)
1768 : TYPE(cell_type), POINTER :: cell
1769 6 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1770 6 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1771 :
1772 6 : CALL timeset(routineN, handle)
1773 :
1774 : CALL get_qs_env(qs_env=qs_env, &
1775 : qs_kind_set=qs_kind_set, &
1776 : cell=cell, &
1777 6 : particle_set=particle_set)
1778 :
1779 : CALL get_current_env(current_env=current_env, &
1780 6 : gauge_atom_radius=gauge_atom_radius)
1781 :
1782 6 : scale = 2.0_dp
1783 :
1784 6 : box_size_guess = gauge_atom_radius/scale
1785 :
1786 6 : natms = SIZE(particle_set, 1)
1787 18 : ALLOCATE (ratom(3, natms))
1788 :
1789 : !
1790 : ! box the atoms
1791 6 : nbox(1) = CEILING(cell%hmat(1, 1)/box_size_guess)
1792 6 : nbox(2) = CEILING(cell%hmat(2, 2)/box_size_guess)
1793 6 : nbox(3) = CEILING(cell%hmat(3, 3)/box_size_guess)
1794 6 : dbox(1) = cell%hmat(1, 1)/REAL(nbox(1), dp)
1795 6 : dbox(2) = cell%hmat(2, 2)/REAL(nbox(2), dp)
1796 6 : dbox(3) = cell%hmat(3, 3)/REAL(nbox(3), dp)
1797 36 : ALLOCATE (box_ptr(0:nbox(1), 0:nbox(2) - 1, 0:nbox(3) - 1), box_data(3, natms))
1798 62 : box_data(:, :) = HUGE(0.0_dp)
1799 27054 : box_ptr(:, :, :) = HUGE(0)
1800 : !
1801 6 : offset(1) = cell%hmat(1, 1)*0.5_dp
1802 6 : offset(2) = cell%hmat(2, 2)*0.5_dp
1803 6 : offset(3) = cell%hmat(3, 3)*0.5_dp
1804 20 : DO iatom = 1, natms
1805 20 : ratom(:, iatom) = pbc(particle_set(iatom)%r(:), cell)
1806 : END DO
1807 : !
1808 6 : i = 1
1809 88 : DO kbox = 0, nbox(3) - 1
1810 1430 : DO jbox = 0, nbox(2) - 1
1811 1342 : box_ptr(0, jbox, kbox) = i
1812 25706 : DO ibox = 0, nbox(1) - 1
1813 24282 : ii = 0
1814 88846 : DO iatom = 1, natms
1815 : IF (MODULO(FLOOR(ratom(1, iatom)/dbox(1)), nbox(1)) == ibox .AND. &
1816 64564 : MODULO(FLOOR(ratom(2, iatom)/dbox(2)), nbox(2)) == jbox .AND. &
1817 24282 : MODULO(FLOOR(ratom(3, iatom)/dbox(3)), nbox(3)) == kbox) THEN
1818 56 : box_data(:, i) = ratom(:, iatom)
1819 14 : i = i + 1
1820 14 : ii = ii + 1
1821 : END IF
1822 : END DO
1823 25624 : box_ptr(ibox + 1, jbox, kbox) = box_ptr(ibox, jbox, kbox) + ii
1824 : END DO
1825 : END DO
1826 : END DO
1827 : !
1828 : IF (.FALSE.) THEN
1829 : DO kbox = 0, nbox(3) - 1
1830 : DO jbox = 0, nbox(2) - 1
1831 : DO ibox = 0, nbox(1) - 1
1832 : IF (box_ptr(ibox + 1, jbox, kbox) - box_ptr(ibox, jbox, kbox) > 0) THEN
1833 : WRITE (*, *) 'box=', ibox, jbox, kbox
1834 : WRITE (*, *) 'nbr atom=', box_ptr(ibox + 1, jbox, kbox) - box_ptr(ibox, jbox, kbox)
1835 : DO iatom = box_ptr(ibox, jbox, kbox), box_ptr(ibox + 1, jbox, kbox) - 1
1836 : WRITE (*, '(A,I3,3E14.6)') 'coor=', iatom, box_data(:, iatom)
1837 : END DO
1838 : END IF
1839 : END DO
1840 : END DO
1841 : END DO
1842 : END IF
1843 : !
1844 6 : NULLIFY (box)
1845 25736 : ALLOCATE (box(0:nbox(1) - 1, 0:nbox(2) - 1, 0:nbox(3) - 1))
1846 : !
1847 : ! build the list
1848 88 : DO k = 0, nbox(3) - 1
1849 1430 : DO j = 0, nbox(2) - 1
1850 25706 : DO i = 0, nbox(1) - 1
1851 : !
1852 24282 : box_center(1) = (REAL(i, dp) + 0.5_dp)*dbox(1)
1853 24282 : box_center(2) = (REAL(j, dp) + 0.5_dp)*dbox(2)
1854 24282 : box_center(3) = (REAL(k, dp) + 0.5_dp)*dbox(3)
1855 24282 : box_center_wrap = pbc(box_center, cell)
1856 : !
1857 : ! find the atoms that are in the overlaping boxes
1858 24282 : natms_local = 0
1859 24282 : kmin = FLOOR((box_center(3) - gauge_atom_radius)/dbox(3))
1860 24282 : kmax = FLOOR((box_center(3) + gauge_atom_radius)/dbox(3))
1861 24282 : IF (kmax - kmin + 1 > nbox(3)) THEN
1862 0 : kmin = 0
1863 0 : kmax = nbox(3) - 1
1864 : END IF
1865 145692 : DO kbox = kmin, kmax
1866 121410 : jmin = FLOOR((box_center(2) - gauge_atom_radius)/dbox(2))
1867 121410 : jmax = FLOOR((box_center(2) + gauge_atom_radius)/dbox(2))
1868 121410 : IF (jmax - jmin + 1 > nbox(2)) THEN
1869 450 : jmin = 0
1870 450 : jmax = nbox(2) - 1
1871 : END IF
1872 751842 : DO jbox = jmin, jmax
1873 606150 : imin = FLOOR((box_center(1) - gauge_atom_radius)/dbox(1))
1874 606150 : imax = FLOOR((box_center(1) + gauge_atom_radius)/dbox(1))
1875 606150 : IF (imax - imin + 1 > nbox(1)) THEN
1876 1350 : imin = 0
1877 1350 : imax = nbox(1) - 1
1878 : END IF
1879 3755610 : DO ibox = imin, imax
1880 3028050 : ibeg = box_ptr(MODULO(ibox, nbox(1)), MODULO(jbox, nbox(2)), MODULO(kbox, nbox(3)))
1881 3028050 : iend = box_ptr(MODULO(ibox, nbox(1)) + 1, MODULO(jbox, nbox(2)), MODULO(kbox, nbox(3))) - 1
1882 3635630 : DO iatom = ibeg, iend
1883 5720 : r = pbc(box_center_wrap(:) - box_data(:, iatom), cell)
1884 : IF (ABS(r(1)) <= (scale + 0.5_dp)*dbox(1) .AND. &
1885 1430 : ABS(r(2)) <= (scale + 0.5_dp)*dbox(2) .AND. &
1886 3028050 : ABS(r(3)) <= (scale + 0.5_dp)*dbox(3)) THEN
1887 1430 : natms_local = natms_local + 1
1888 5720 : ratom(:, natms_local) = box_data(:, iatom)
1889 : END IF
1890 : END DO
1891 : END DO ! box
1892 : END DO
1893 : END DO
1894 : !
1895 : ! set the list
1896 24282 : box(i, j, k)%n = natms_local
1897 24282 : NULLIFY (box(i, j, k)%r)
1898 25624 : IF (natms_local > 0) THEN
1899 3840 : ALLOCATE (box(i, j, k)%r(3, natms_local))
1900 1280 : r_ptr => box(i, j, k)%r
1901 1280 : CALL dcopy(3*natms_local, ratom(1, 1), 1, r_ptr(1, 1), 1)
1902 : END IF
1903 : END DO ! list
1904 : END DO
1905 : END DO
1906 :
1907 : IF (.FALSE.) THEN
1908 : DO k = 0, nbox(3) - 1
1909 : DO j = 0, nbox(2) - 1
1910 : DO i = 0, nbox(1) - 1
1911 : IF (box(i, j, k)%n > 0) THEN
1912 : WRITE (*, *)
1913 : WRITE (*, *) 'box=', i, j, k
1914 : box_center(1) = (REAL(i, dp) + 0.5_dp)*dbox(1)
1915 : box_center(2) = (REAL(j, dp) + 0.5_dp)*dbox(2)
1916 : box_center(3) = (REAL(k, dp) + 0.5_dp)*dbox(3)
1917 : box_center = pbc(box_center, cell)
1918 : WRITE (*, '(A,3E14.6)') 'box_center=', box_center
1919 : WRITE (*, *) 'nbr atom=', box(i, j, k)%n
1920 : r_ptr => box(i, j, k)%r
1921 : DO iatom = 1, box(i, j, k)%n
1922 : WRITE (*, '(A,I3,3E14.6)') 'coor=', iatom, r_ptr(:, iatom)
1923 : r(:) = pbc(box_center(:) - r_ptr(:, iatom), cell)
1924 : IF (ABS(r(1)) > (scale + 0.5_dp)*dbox(1) .OR. &
1925 : ABS(r(2)) > (scale + 0.5_dp)*dbox(2) .OR. &
1926 : ABS(r(3)) > (scale + 0.5_dp)*dbox(3)) THEN
1927 : WRITE (*, *) 'error too many atoms'
1928 : WRITE (*, *) 'dist=', ABS(r(:))
1929 : WRITE (*, *) 'large_dist=', (scale + 0.5_dp)*dbox
1930 : CPABORT("Some atoms are too far from box center")
1931 : END IF
1932 : END DO
1933 : END IF
1934 : END DO ! list
1935 : END DO
1936 : END DO
1937 : END IF
1938 :
1939 : IF (.TRUE.) THEN
1940 88 : DO k = 0, nbox(3) - 1
1941 1430 : DO j = 0, nbox(2) - 1
1942 25706 : DO i = 0, nbox(1) - 1
1943 24282 : box_center(1) = (REAL(i, dp) + 0.5_dp)*dbox(1)
1944 24282 : box_center(2) = (REAL(j, dp) + 0.5_dp)*dbox(2)
1945 24282 : box_center(3) = (REAL(k, dp) + 0.5_dp)*dbox(3)
1946 97128 : box_center = pbc(box_center, cell)
1947 24282 : r_ptr => box(i, j, k)%r
1948 90188 : DO iatom = 1, natms
1949 258256 : r(:) = pbc(box_center(:) - ratom(:, iatom), cell)
1950 64564 : ifind = 0
1951 68174 : DO jatom = 1, box(i, j, k)%n
1952 79004 : IF (SUM(ABS(ratom(:, iatom) - r_ptr(:, jatom))) < 1E-10_dp) ifind = 1
1953 : END DO
1954 :
1955 88846 : IF (ifind == 0) THEN
1956 : ! SQRT(DOT_PRODUCT(r, r)) < gauge_atom_radius
1957 252536 : IF (DOT_PRODUCT(r, r) < (gauge_atom_radius*gauge_atom_radius)) THEN
1958 0 : WRITE (*, *) 'error atom too close'
1959 0 : WRITE (*, *) 'iatom', iatom
1960 0 : WRITE (*, *) 'box_center', box_center
1961 0 : WRITE (*, *) 'ratom', ratom(:, iatom)
1962 0 : WRITE (*, *) 'gauge_atom_radius', gauge_atom_radius
1963 0 : CPABORT("Some atoms are too close within gauge_atom_radius")
1964 : END IF
1965 : END IF
1966 : END DO
1967 : END DO ! list
1968 : END DO
1969 : END DO
1970 : END IF
1971 :
1972 6 : DEALLOCATE (ratom)
1973 :
1974 6 : CALL timestop(handle)
1975 :
1976 12 : END SUBROUTINE box_atoms_new
1977 :
1978 : ! **************************************************************************************************
1979 : !> \brief ...
1980 : !> \param current_env ...
1981 : !> \param qs_env ...
1982 : !> \param rs_grid_x ...
1983 : !> \param rs_grid_y ...
1984 : !> \param rs_grid_z ...
1985 : !> \param box ...
1986 : ! **************************************************************************************************
1987 20 : SUBROUTINE collocate_gauge_new(current_env, qs_env, rs_grid_x, rs_grid_y, rs_grid_z, box)
1988 : !
1989 : TYPE(current_env_type) :: current_env
1990 : TYPE(qs_environment_type), POINTER :: qs_env
1991 : TYPE(realspace_grid_type), INTENT(IN) :: rs_grid_x, rs_grid_y, rs_grid_z
1992 : TYPE(box_type), DIMENSION(:, :, :), POINTER :: box
1993 :
1994 : CHARACTER(LEN=*), PARAMETER :: routineN = 'collocate_gauge_new'
1995 :
1996 : INTEGER :: box_end(3), box_start(3), delta_lb(3), grid_end(3), grid_start(3), handle, i, &
1997 : iatom, ib, ibox, j, jatom, jb, jbox, k, kb, kbox, lb(3), lb_local(3), natms, &
1998 : natms_local0, natms_local1, ng(3)
1999 : INTEGER(KIND=int_8) :: box_lower(3), box_upper(3), &
2000 : grid_lower(3), grid_upper(3), npts(3)
2001 20 : REAL(dp), DIMENSION(:, :), POINTER :: r_ptr
2002 : REAL(KIND=dp) :: ab, box_center(3), buf_tmp, dist, dr(3), &
2003 : gauge_atom_radius, offset(3), pa, pb, &
2004 : point(3), pra(3), r(3), res(3), summe, &
2005 : tmp, x, y, z
2006 20 : REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: buf, nrm_atms_pnt
2007 20 : REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: atms_pnt, ratom
2008 20 : REAL(kind=dp), DIMENSION(:, :, :), POINTER :: grid_x, grid_y, grid_z
2009 : TYPE(cell_type), POINTER :: cell
2010 20 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2011 20 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2012 :
2013 20 : CALL timeset(routineN, handle)
2014 :
2015 : !
2016 : CALL get_current_env(current_env=current_env, &
2017 20 : gauge_atom_radius=gauge_atom_radius)
2018 : !
2019 : CALL get_qs_env(qs_env=qs_env, &
2020 : qs_kind_set=qs_kind_set, &
2021 : cell=cell, &
2022 20 : particle_set=particle_set)
2023 : !
2024 20 : natms = SIZE(particle_set, 1)
2025 20 : dr(1) = rs_grid_x%desc%dh(1, 1)
2026 20 : dr(2) = rs_grid_x%desc%dh(2, 2)
2027 20 : dr(3) = rs_grid_x%desc%dh(3, 3)
2028 80 : lb(:) = rs_grid_x%desc%lb(:)
2029 80 : lb_local(:) = rs_grid_x%lb_local(:)
2030 20 : grid_x => rs_grid_x%r(:, :, :)
2031 20 : grid_y => rs_grid_y%r(:, :, :)
2032 20 : grid_z => rs_grid_z%r(:, :, :)
2033 80 : ng(:) = UBOUND(grid_x)
2034 80 : npts(:) = INT(rs_grid_x%desc%npts(:), KIND=int_8)
2035 80 : delta_lb(:) = lb_local(:) - lb(:)
2036 20 : offset(1) = cell%hmat(1, 1)*0.5_dp
2037 20 : offset(2) = cell%hmat(2, 2)*0.5_dp
2038 20 : offset(3) = cell%hmat(3, 3)*0.5_dp
2039 140 : ALLOCATE (buf(natms), ratom(3, natms), atms_pnt(3, natms), nrm_atms_pnt(natms))
2040 : !
2041 : ! Both the grid and the boxes partition the same cell. Cancel the cell length:
2042 : ! g*dr >= b*dbox is equivalent to g*nbox >= b*npts.
2043 : ! For a positive divisor d, floor(a/d) = (a - MODULO(a,d))/d,
2044 : ! including negative indices in the grid's halo. Use 64-bit products.
2045 80 : grid_lower = INT(delta_lb, KIND=int_8)*nbox
2046 80 : grid_upper = (INT(ng, KIND=int_8) - 1_int_8 + delta_lb)*nbox
2047 80 : box_start = INT((grid_lower - MODULO(grid_lower, npts))/npts)
2048 80 : box_end = INT((grid_upper - MODULO(grid_upper, npts))/npts)
2049 : !
2050 : ! go over the box-list
2051 314 : DO kb = box_start(3), box_end(3)
2052 5148 : DO jb = box_start(2), box_end(2)
2053 89870 : DO ib = box_start(1), box_end(1)
2054 84742 : ibox = MODULO(ib, nbox(1))
2055 84742 : jbox = MODULO(jb, nbox(2))
2056 84742 : kbox = MODULO(kb, nbox(3))
2057 : !
2058 : ! The existing box intervals include both endpoints. Compute ceil(b*npts/nbox)
2059 : ! and floor((b+1)*npts/nbox) exactly, then clip to this rank's local grid.
2060 : ! ceil(a/d) = (a + MODULO(-a,d))/d also handles negative box indices.
2061 338968 : box_lower = INT([ib, jb, kb], KIND=int_8)*npts
2062 338968 : box_upper = (INT([ib, jb, kb], KIND=int_8) + 1_int_8)*npts
2063 338968 : grid_start = INT((box_lower + MODULO(-box_lower, INT(nbox, KIND=int_8)))/nbox)
2064 338968 : grid_end = INT((box_upper - MODULO(box_upper, INT(nbox, KIND=int_8)))/nbox)
2065 338968 : grid_start = MAX(grid_start, delta_lb) - delta_lb + 1
2066 338968 : grid_end = MIN(grid_end, ng - 1 + delta_lb) - delta_lb + 1
2067 : !
2068 : ! Check the box boundaries in the same exact integer coordinates.
2069 338968 : grid_lower = (INT(grid_start, KIND=int_8) - 1_int_8 + delta_lb)*nbox
2070 338968 : grid_upper = (INT(grid_end, KIND=int_8) - 1_int_8 + delta_lb)*nbox
2071 338968 : CPASSERT(ALL(grid_lower >= box_lower))
2072 338968 : CPASSERT(ALL(grid_upper <= box_upper))
2073 : !
2074 : ! the center of the box
2075 84742 : box_center(1) = (REAL(ibox, dp) + 0.5_dp)*dbox(1)
2076 84742 : box_center(2) = (REAL(jbox, dp) + 0.5_dp)*dbox(2)
2077 84742 : box_center(3) = (REAL(kbox, dp) + 0.5_dp)*dbox(3)
2078 : !
2079 : ! find the atoms that are in the overlaping boxes
2080 84742 : natms_local0 = box(ibox, jbox, kbox)%n
2081 84742 : r_ptr => box(ibox, jbox, kbox)%r
2082 : !
2083 : ! go over the grid inside the box
2084 89576 : IF (natms_local0 > 0) THEN
2085 : !
2086 : ! here there are some atoms...
2087 10132 : DO k = grid_start(3), grid_end(3)
2088 32420 : DO j = grid_start(2), grid_end(2)
2089 159542 : DO i = grid_start(1), grid_end(1)
2090 130750 : point(1) = REAL(i - 1 + delta_lb(1), dp)*dr(1)
2091 130750 : point(2) = REAL(j - 1 + delta_lb(2), dp)*dr(2)
2092 130750 : point(3) = REAL(k - 1 + delta_lb(3), dp)*dr(3)
2093 523000 : point = pbc(point, cell)
2094 : !
2095 : ! compute atom-point distances
2096 130750 : natms_local1 = 0
2097 372536 : DO iatom = 1, natms_local0
2098 1934288 : r(:) = pbc(r_ptr(:, iatom) - point(:), cell) + point(:) !needed?
2099 241786 : dist = (r(1) - point(1))**2 + (r(2) - point(2))**2 + (r(3) - point(3))**2
2100 372536 : IF (dist < gauge_atom_radius**2) THEN
2101 154830 : natms_local1 = natms_local1 + 1
2102 619320 : ratom(:, natms_local1) = r(:)
2103 : !
2104 : ! compute the distance atoms-point
2105 154830 : x = point(1) - r(1)
2106 154830 : y = point(2) - r(2)
2107 154830 : z = point(3) - r(3)
2108 154830 : atms_pnt(1, natms_local1) = x
2109 154830 : atms_pnt(2, natms_local1) = y
2110 154830 : atms_pnt(3, natms_local1) = z
2111 154830 : nrm_atms_pnt(natms_local1) = SQRT(x*x + y*y + z*z)
2112 : END IF
2113 : END DO
2114 : !
2115 : !
2116 153038 : IF (natms_local1 > 0) THEN
2117 : !
2118 : ! build the step
2119 240028 : DO iatom = 1, natms_local1
2120 154830 : buf_tmp = 1.0_dp
2121 154830 : pra(1) = atms_pnt(1, iatom)
2122 154830 : pra(2) = atms_pnt(2, iatom)
2123 154830 : pra(3) = atms_pnt(3, iatom)
2124 154830 : pa = nrm_atms_pnt(iatom)
2125 448924 : DO jatom = 1, natms_local1
2126 294094 : IF (iatom == jatom) CYCLE
2127 139264 : pb = nrm_atms_pnt(jatom)
2128 139264 : x = pra(1) - atms_pnt(1, jatom)
2129 139264 : y = pra(2) - atms_pnt(2, jatom)
2130 139264 : z = pra(3) - atms_pnt(3, jatom)
2131 139264 : ab = SQRT(x*x + y*y + z*z)
2132 : !
2133 139264 : tmp = (pa - pb)/ab
2134 139264 : tmp = 0.5_dp*(3.0_dp - tmp*tmp)*tmp
2135 139264 : tmp = 0.5_dp*(3.0_dp - tmp*tmp)*tmp
2136 139264 : tmp = 0.5_dp*(3.0_dp - tmp*tmp)*tmp
2137 448924 : buf_tmp = buf_tmp*0.5_dp*(1.0_dp - tmp)
2138 : END DO
2139 240028 : buf(iatom) = buf_tmp
2140 : END DO
2141 : res(1) = 0.0_dp
2142 : res(2) = 0.0_dp
2143 : res(3) = 0.0_dp
2144 : summe = 0.0_dp
2145 240028 : DO iatom = 1, natms_local1
2146 154830 : res(1) = res(1) + ratom(1, iatom)*buf(iatom)
2147 154830 : res(2) = res(2) + ratom(2, iatom)*buf(iatom)
2148 154830 : res(3) = res(3) + ratom(3, iatom)*buf(iatom)
2149 240028 : summe = summe + buf(iatom)
2150 : END DO
2151 85198 : res(1) = res(1)/summe
2152 85198 : res(2) = res(2)/summe
2153 85198 : res(3) = res(3)/summe
2154 85198 : grid_x(i, j, k) = point(1) - res(1)
2155 85198 : grid_y(i, j, k) = point(2) - res(2)
2156 85198 : grid_z(i, j, k) = point(3) - res(3)
2157 : ELSE
2158 45552 : grid_x(i, j, k) = 0.0_dp
2159 45552 : grid_y(i, j, k) = 0.0_dp
2160 45552 : grid_z(i, j, k) = 0.0_dp
2161 : END IF
2162 : END DO ! grid
2163 : END DO
2164 : END DO
2165 : !
2166 : ELSE
2167 : !
2168 : ! here there is no atom
2169 192148 : DO k = grid_start(3), grid_end(3)
2170 399546 : DO j = grid_start(2), grid_end(2)
2171 803654 : DO i = grid_start(1), grid_end(1)
2172 485222 : grid_x(i, j, k) = 0.0_dp
2173 485222 : grid_y(i, j, k) = 0.0_dp
2174 692620 : grid_z(i, j, k) = 0.0_dp
2175 : END DO ! grid
2176 : END DO
2177 : END DO
2178 : !
2179 : END IF
2180 : !
2181 : END DO ! list
2182 : END DO
2183 : END DO
2184 :
2185 20 : DEALLOCATE (buf, ratom, atms_pnt, nrm_atms_pnt)
2186 :
2187 20 : CALL timestop(handle)
2188 :
2189 20 : END SUBROUTINE collocate_gauge_new
2190 :
2191 : ! **************************************************************************************************
2192 : !> \brief ...
2193 : !> \param box ...
2194 : ! **************************************************************************************************
2195 28 : SUBROUTINE deallocate_box(box)
2196 : TYPE(box_type), DIMENSION(:, :, :), POINTER :: box
2197 :
2198 : INTEGER :: i, j, k
2199 :
2200 28 : IF (ASSOCIATED(box)) THEN
2201 100 : DO k = LBOUND(box, 3), UBOUND(box, 3)
2202 1594 : DO j = LBOUND(box, 2), UBOUND(box, 2)
2203 28390 : DO i = LBOUND(box, 1), UBOUND(box, 1)
2204 25624 : IF (ASSOCIATED(box(i, j, k)%r)) THEN
2205 1280 : DEALLOCATE (box(i, j, k)%r)
2206 : END IF
2207 : END DO
2208 : END DO
2209 : END DO
2210 6 : DEALLOCATE (box)
2211 : END IF
2212 28 : END SUBROUTINE deallocate_box
2213 : END SUBROUTINE current_set_gauge
2214 :
2215 : ! **************************************************************************************************
2216 : !> \brief ...
2217 : !> \param current_env ...
2218 : !> \param qs_env ...
2219 : !> \param iB ...
2220 : ! **************************************************************************************************
2221 492 : SUBROUTINE current_build_chi(current_env, qs_env, iB)
2222 : !
2223 : TYPE(current_env_type) :: current_env
2224 : TYPE(qs_environment_type), POINTER :: qs_env
2225 : INTEGER, INTENT(IN) :: iB
2226 :
2227 492 : IF (current_env%full) THEN
2228 396 : CALL current_build_chi_many_centers(current_env, qs_env, iB)
2229 96 : ELSE IF (current_env%nbr_center(1) > 1) THEN
2230 0 : CALL current_build_chi_many_centers(current_env, qs_env, iB)
2231 : ELSE
2232 96 : CALL current_build_chi_one_center(current_env, qs_env, iB)
2233 : END IF
2234 :
2235 492 : END SUBROUTINE current_build_chi
2236 :
2237 : ! **************************************************************************************************
2238 : !> \brief ...
2239 : !> \param current_env ...
2240 : !> \param qs_env ...
2241 : !> \param iB ...
2242 : ! **************************************************************************************************
2243 396 : SUBROUTINE current_build_chi_many_centers(current_env, qs_env, iB)
2244 : !
2245 : TYPE(current_env_type) :: current_env
2246 : TYPE(qs_environment_type), POINTER :: qs_env
2247 : INTEGER, INTENT(IN) :: iB
2248 :
2249 : CHARACTER(LEN=*), PARAMETER :: routineN = 'current_build_chi_many_centers'
2250 :
2251 : CHARACTER(LEN=default_string_length) :: basis_type
2252 : INTEGER :: handle, icenter, idir, idir2, ii, iiB, iii, iiiB, ispin, istate, j, jstate, &
2253 : max_states, nao, natom, nbr_center(2), nmo, nspins, nstate_loc, nstates(2), output_unit
2254 396 : INTEGER, ALLOCATABLE, DIMENSION(:) :: first_sgf, last_sgf
2255 396 : INTEGER, DIMENSION(:), POINTER :: row_blk_sizes
2256 : LOGICAL :: chi_pbc, gapw
2257 : REAL(dp) :: chi(3), chi_tmp, contrib, contrib2, &
2258 : dk(3), int_current(3), &
2259 : int_current_tmp, maxocc
2260 : TYPE(cell_type), POINTER :: cell
2261 396 : TYPE(cp_2d_i_p_type), DIMENSION(:), POINTER :: center_list
2262 396 : TYPE(cp_2d_r_p_type), DIMENSION(:), POINTER :: centers_set
2263 : TYPE(cp_fm_struct_type), POINTER :: tmp_fm_struct
2264 : TYPE(cp_fm_type) :: psi0, psi_D, psi_p1, psi_p2, psi_rxp
2265 4356 : TYPE(cp_fm_type), DIMENSION(3) :: p_rxp, r_p1, r_p2
2266 36036 : TYPE(cp_fm_type), DIMENSION(9, 3) :: rr_p1, rr_p2, rr_rxp
2267 396 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: psi0_order
2268 396 : TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: psi1_D, psi1_p, psi1_rxp
2269 : TYPE(cp_fm_type), POINTER :: mo_coeff
2270 : TYPE(cp_logger_type), POINTER :: logger
2271 : TYPE(dbcsr_distribution_type), POINTER :: dbcsr_dist
2272 396 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: op_mom_ao, op_p_ao
2273 396 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: op_mom_der_ao
2274 : TYPE(dft_control_type), POINTER :: dft_control
2275 396 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
2276 : TYPE(mp_para_env_type), POINTER :: para_env
2277 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
2278 396 : POINTER :: sab_all, sab_orb
2279 396 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2280 396 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2281 :
2282 : !
2283 :
2284 396 : CALL timeset(routineN, handle)
2285 : !
2286 396 : NULLIFY (dft_control, mos, para_env, mo_coeff, op_mom_ao, &
2287 396 : op_mom_der_ao, center_list, centers_set, &
2288 396 : op_p_ao, psi1_p, psi1_rxp, psi1_D, &
2289 396 : cell, particle_set, qs_kind_set)
2290 :
2291 396 : logger => cp_get_default_logger()
2292 396 : output_unit = cp_logger_get_default_io_unit(logger)
2293 :
2294 : CALL get_qs_env(qs_env=qs_env, &
2295 : dft_control=dft_control, &
2296 : mos=mos, &
2297 : para_env=para_env, &
2298 : cell=cell, &
2299 : dbcsr_dist=dbcsr_dist, &
2300 : particle_set=particle_set, &
2301 : qs_kind_set=qs_kind_set, &
2302 : sab_all=sab_all, &
2303 396 : sab_orb=sab_orb)
2304 :
2305 396 : nspins = dft_control%nspins
2306 396 : gapw = dft_control%qs_control%gapw
2307 396 : basis_type = "ORB"
2308 396 : IF (gapw) basis_type = "ORB_SOFT"
2309 :
2310 : CALL get_current_env(current_env=current_env, &
2311 : chi_pbc=chi_pbc, &
2312 : nao=nao, &
2313 : nbr_center=nbr_center, &
2314 : center_list=center_list, &
2315 : centers_set=centers_set, &
2316 : psi1_p=psi1_p, &
2317 : psi1_rxp=psi1_rxp, &
2318 : psi1_D=psi1_D, &
2319 : nstates=nstates, &
2320 396 : psi0_order=psi0_order)
2321 : !
2322 : ! get max nbr of states per center
2323 396 : max_states = 0
2324 978 : DO ispin = 1, nspins
2325 4428 : DO icenter = 1, nbr_center(ispin)
2326 : max_states = MAX(max_states, center_list(ispin)%array(1, icenter + 1)&
2327 4032 : & - center_list(ispin)%array(1, icenter))
2328 : END DO
2329 : END DO
2330 : !
2331 : ! Allocate sparse matrices for dipole, quadrupole and their derivatives => 9x3
2332 : ! Remember the derivatives are antisymmetric
2333 396 : CALL dbcsr_allocate_matrix_set(op_mom_ao, 9)
2334 396 : CALL dbcsr_allocate_matrix_set(op_mom_der_ao, 9, 3)
2335 : !
2336 : ! prepare for allocation
2337 396 : natom = SIZE(particle_set, 1)
2338 1188 : ALLOCATE (first_sgf(natom))
2339 792 : ALLOCATE (last_sgf(natom))
2340 : CALL get_particle_set(particle_set, qs_kind_set, &
2341 : first_sgf=first_sgf, &
2342 396 : last_sgf=last_sgf)
2343 792 : ALLOCATE (row_blk_sizes(natom))
2344 396 : CALL dbcsr_convert_offsets_to_sizes(first_sgf, row_blk_sizes, last_sgf)
2345 396 : DEALLOCATE (first_sgf)
2346 396 : DEALLOCATE (last_sgf)
2347 : !
2348 : !
2349 396 : ALLOCATE (op_mom_ao(1)%matrix)
2350 : CALL dbcsr_create(matrix=op_mom_ao(1)%matrix, &
2351 : name="op_mom", &
2352 : dist=dbcsr_dist, matrix_type=dbcsr_type_no_symmetry, &
2353 : row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
2354 396 : mutable_work=.TRUE.)
2355 396 : CALL cp_dbcsr_alloc_block_from_nbl(op_mom_ao(1)%matrix, sab_all)
2356 :
2357 1584 : DO idir2 = 1, 3
2358 1188 : ALLOCATE (op_mom_der_ao(1, idir2)%matrix)
2359 : CALL dbcsr_copy(op_mom_der_ao(1, idir2)%matrix, op_mom_ao(1)%matrix, &
2360 1584 : "op_mom_der_ao"//"-"//TRIM(ADJUSTL(cp_to_string(idir2))))
2361 : END DO
2362 :
2363 3564 : DO idir = 2, SIZE(op_mom_ao, 1)
2364 3168 : ALLOCATE (op_mom_ao(idir)%matrix)
2365 : CALL dbcsr_copy(op_mom_ao(idir)%matrix, op_mom_ao(1)%matrix, &
2366 3168 : "op_mom_ao"//"-"//TRIM(ADJUSTL(cp_to_string(idir))))
2367 13068 : DO idir2 = 1, 3
2368 9504 : ALLOCATE (op_mom_der_ao(idir, idir2)%matrix)
2369 : CALL dbcsr_copy(op_mom_der_ao(idir, idir2)%matrix, op_mom_ao(1)%matrix, &
2370 12672 : "op_mom_der_ao"//"-"//TRIM(ADJUSTL(cp_to_string(idir*idir2))))
2371 : END DO
2372 : END DO
2373 : !
2374 396 : CALL dbcsr_allocate_matrix_set(op_p_ao, 3)
2375 396 : ALLOCATE (op_p_ao(1)%matrix)
2376 : CALL dbcsr_create(matrix=op_p_ao(1)%matrix, &
2377 : name="op_p_ao", &
2378 : dist=dbcsr_dist, matrix_type=dbcsr_type_antisymmetric, &
2379 : row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
2380 396 : mutable_work=.TRUE.)
2381 396 : CALL cp_dbcsr_alloc_block_from_nbl(op_p_ao(1)%matrix, sab_orb)
2382 :
2383 1188 : DO idir = 2, 3
2384 792 : ALLOCATE (op_p_ao(idir)%matrix)
2385 : CALL dbcsr_copy(op_p_ao(idir)%matrix, op_p_ao(1)%matrix, &
2386 1188 : "op_p_ao"//"-"//TRIM(ADJUSTL(cp_to_string(idir))))
2387 : END DO
2388 : !
2389 : !
2390 396 : DEALLOCATE (row_blk_sizes)
2391 : !
2392 : !
2393 : ! Allocate full matrices for only one vector
2394 396 : mo_coeff => psi0_order(1)
2395 396 : NULLIFY (tmp_fm_struct)
2396 : CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nao, &
2397 : ncol_global=max_states, para_env=para_env, &
2398 396 : context=mo_coeff%matrix_struct%context)
2399 396 : CALL cp_fm_create(psi0, tmp_fm_struct)
2400 396 : CALL cp_fm_create(psi_D, tmp_fm_struct)
2401 396 : CALL cp_fm_create(psi_rxp, tmp_fm_struct)
2402 396 : CALL cp_fm_create(psi_p1, tmp_fm_struct)
2403 396 : CALL cp_fm_create(psi_p2, tmp_fm_struct)
2404 396 : CALL cp_fm_struct_release(tmp_fm_struct)
2405 : !
2406 : CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nao, &
2407 : ncol_global=max_states, para_env=para_env, &
2408 396 : context=mo_coeff%matrix_struct%context)
2409 1584 : DO idir = 1, 3
2410 1188 : CALL cp_fm_create(p_rxp(idir), tmp_fm_struct, set_zero=.TRUE.)
2411 1188 : CALL cp_fm_create(r_p1(idir), tmp_fm_struct, set_zero=.TRUE.)
2412 1188 : CALL cp_fm_create(r_p2(idir), tmp_fm_struct, set_zero=.TRUE.)
2413 12276 : DO idir2 = 1, 9
2414 10692 : CALL cp_fm_create(rr_rxp(idir2, idir), tmp_fm_struct, set_zero=.TRUE.)
2415 10692 : CALL cp_fm_create(rr_p1(idir2, idir), tmp_fm_struct, set_zero=.TRUE.)
2416 11880 : CALL cp_fm_create(rr_p2(idir2, idir), tmp_fm_struct, set_zero=.TRUE.)
2417 : END DO
2418 : END DO
2419 396 : CALL cp_fm_struct_release(tmp_fm_struct)
2420 : !
2421 : !
2422 : !
2423 : ! recompute the linear momentum matrices
2424 396 : CALL build_lin_mom_matrix(qs_env, op_p_ao)
2425 : !
2426 : !
2427 : ! get iiB and iiiB
2428 396 : CALL set_vecp(iB, iiB, iiiB)
2429 978 : DO ispin = 1, nspins
2430 : !
2431 : ! get ground state MOS
2432 582 : nmo = nstates(ispin)
2433 582 : mo_coeff => psi0_order(ispin)
2434 582 : CALL get_mo_set(mo_set=mos(ispin), maxocc=maxocc)
2435 : !
2436 : ! Initialize the temporary vector chi
2437 582 : chi = 0.0_dp
2438 : int_current = 0.0_dp
2439 : !
2440 : ! Start loop over the occupied states
2441 4032 : DO icenter = 1, nbr_center(ispin)
2442 : !
2443 : ! Get the Wannier center of the istate-th ground state orbital
2444 13800 : dk(1:3) = centers_set(ispin)%array(1:3, icenter)
2445 : !
2446 : ! Compute the multipole integrals for the state istate,
2447 : ! using as reference center the corresponding Wannier center
2448 34500 : DO idir = 1, 9
2449 31050 : CALL dbcsr_set(op_mom_ao(idir)%matrix, 0.0_dp)
2450 127650 : DO idir2 = 1, 3
2451 124200 : CALL dbcsr_set(op_mom_der_ao(idir, idir2)%matrix, 0.0_dp)
2452 : END DO
2453 : END DO
2454 : CALL build_local_moments_der_matrix(qs_env, op_mom_der_ao, 2, 2, ref_point=dk, &
2455 : moments=op_mom_ao, basis_type=basis_type, &
2456 3450 : minimum_image=.FALSE., ordered=.TRUE.)
2457 : !
2458 : ! collecte the states that belong to a given center
2459 3450 : CALL cp_fm_set_all(psi0, 0.0_dp)
2460 3450 : CALL cp_fm_set_all(psi_rxp, 0.0_dp)
2461 3450 : CALL cp_fm_set_all(psi_D, 0.0_dp)
2462 3450 : CALL cp_fm_set_all(psi_p1, 0.0_dp)
2463 3450 : CALL cp_fm_set_all(psi_p2, 0.0_dp)
2464 3450 : nstate_loc = center_list(ispin)%array(1, icenter + 1) - center_list(ispin)%array(1, icenter)
2465 3450 : jstate = 1
2466 7278 : DO j = center_list(ispin)%array(1, icenter), center_list(ispin)%array(1, icenter + 1) - 1
2467 3828 : istate = center_list(ispin)%array(2, j)
2468 : !
2469 : ! block the states that belong to this center
2470 3828 : CALL cp_fm_to_fm(mo_coeff, psi0, 1, istate, jstate)
2471 : !
2472 3828 : CALL cp_fm_to_fm(psi1_rxp(ispin, iB), psi_rxp, 1, istate, jstate)
2473 3828 : IF (current_env%full) CALL cp_fm_to_fm(psi1_D(ispin, iB), psi_D, 1, istate, jstate)
2474 : !
2475 : ! psi1_p_iiB_istate and psi1_p_iiiB_istate
2476 3828 : CALL cp_fm_to_fm(psi1_p(ispin, iiB), psi_p1, 1, istate, jstate)
2477 3828 : CALL cp_fm_to_fm(psi1_p(ispin, iiiB), psi_p2, 1, istate, jstate)
2478 : !
2479 7278 : jstate = jstate + 1
2480 : END DO ! istate
2481 : !
2482 : ! scale the ordered mos
2483 3450 : IF (current_env%full) CALL cp_fm_scale_and_add(1.0_dp, psi_rxp, -1.0_dp, psi_D)
2484 : !
2485 13800 : DO idir = 1, 3
2486 10350 : CALL set_vecp(idir, ii, iii)
2487 : CALL cp_dbcsr_sm_fm_multiply(op_p_ao(idir)%matrix, psi_rxp, &
2488 10350 : p_rxp(idir), ncol=nstate_loc, alpha=1.e0_dp)
2489 10350 : IF (iiiB == iii .OR. iiiB == ii) THEN
2490 : CALL cp_dbcsr_sm_fm_multiply(op_mom_ao(idir)%matrix, psi_p1, &
2491 6900 : r_p1(idir), ncol=nstate_loc, alpha=1.e0_dp)
2492 : END IF
2493 10350 : IF (iiB == iii .OR. iiB == ii) THEN
2494 : CALL cp_dbcsr_sm_fm_multiply(op_mom_ao(idir)%matrix, psi_p2, &
2495 6900 : r_p2(idir), ncol=nstate_loc, alpha=1.e0_dp)
2496 : END IF
2497 117300 : DO idir2 = 1, 9
2498 93150 : IF (idir2 == ii .OR. idir2 == iii) THEN
2499 : CALL cp_dbcsr_sm_fm_multiply(op_mom_der_ao(idir2, idir)%matrix, psi_rxp, &
2500 20700 : rr_rxp(idir2, idir), ncol=nstate_loc, alpha=1.e0_dp)
2501 : END IF
2502 : !
2503 93150 : IF (idir2 == ind_m2(ii, iiiB) .OR. idir2 == ind_m2(iii, iiiB) .OR. idir2 == iiiB) THEN
2504 : CALL cp_dbcsr_sm_fm_multiply(op_mom_der_ao(idir2, idir)%matrix, psi_p1, &
2505 31050 : rr_p1(idir2, idir), ncol=nstate_loc, alpha=1.e0_dp)
2506 : END IF
2507 : !
2508 103500 : IF (idir2 == ind_m2(ii, iiB) .OR. idir2 == ind_m2(iii, iiB) .OR. idir2 == iiB) THEN
2509 : CALL cp_dbcsr_sm_fm_multiply(op_mom_der_ao(idir2, idir)%matrix, psi_p2, &
2510 31050 : rr_p2(idir2, idir), ncol=nstate_loc, alpha=1.e0_dp)
2511 : END IF
2512 : END DO
2513 : END DO
2514 : !
2515 : ! Multuply left and right by the appropriate coefficients and sum into the
2516 : ! correct component of the chi tensor using the appropriate multiplicative factor
2517 : ! (don't forget the occupation number)
2518 : ! Loop over the cartesian components of the tensor
2519 : ! The loop over the components of the external field is external, thereby
2520 : ! only one column of the chi tensor is computed here
2521 14382 : DO idir = 1, 3
2522 10350 : chi_tmp = 0.0_dp
2523 10350 : int_current_tmp = 0.0_dp
2524 : !
2525 : ! get ii and iii
2526 10350 : CALL set_vecp(idir, ii, iii)
2527 : !
2528 : ! term: 2[C0| (r-dk)_ii |d_iii(C1(rxp-D))]-2[C0| (r-dk)_iii |d_ii(C1(rxp-D))]
2529 : ! the factor 2 should be already included in the matrix elements
2530 : contrib = 0.0_dp
2531 10350 : CALL cp_fm_trace(psi0, rr_rxp(ii, iii), contrib)
2532 10350 : chi_tmp = chi_tmp + 2.0_dp*contrib
2533 : !
2534 : contrib = 0.0_dp
2535 10350 : CALL cp_fm_trace(psi0, rr_rxp(iii, ii), contrib)
2536 10350 : chi_tmp = chi_tmp - 2.0_dp*contrib
2537 : !
2538 : ! correction: dk_ii*2[C0| d_iii(C1(rxp-D))] - dk_iii*2[C0| d_ii(C1(rxp-D))]
2539 : ! factor 2 not included in the matrix elements
2540 : contrib = 0.0_dp
2541 10350 : CALL cp_fm_trace(psi0, p_rxp(iii), contrib)
2542 10350 : IF (.NOT. chi_pbc) chi_tmp = chi_tmp + 2.0_dp*dk(ii)*contrib
2543 10350 : int_current_tmp = int_current_tmp + 2.0_dp*contrib
2544 : !
2545 : contrib2 = 0.0_dp
2546 10350 : CALL cp_fm_trace(psi0, p_rxp(ii), contrib2)
2547 10350 : IF (.NOT. chi_pbc) chi_tmp = chi_tmp - 2.0_dp*dk(iii)*contrib2
2548 : !
2549 : ! term: -2[C0| (r-dk)_ii (r-dk)_iiB | d_iii(C1(piiiB))] \
2550 : ! +2[C0| (r-dk)_iii (r-dk)_iiB | d_ii(C1(piiiB))]
2551 : ! the factor 2 should be already included in the matrix elements
2552 : contrib = 0.0_dp
2553 10350 : idir2 = ind_m2(ii, iiB)
2554 10350 : CALL cp_fm_trace(psi0, rr_p2(idir2, iii), contrib)
2555 10350 : chi_tmp = chi_tmp - 2.0_dp*contrib
2556 : contrib2 = 0.0_dp
2557 10350 : IF (iiB == iii) THEN
2558 3450 : CALL cp_fm_trace(psi0, r_p2(ii), contrib2)
2559 3450 : chi_tmp = chi_tmp - contrib2
2560 : END IF
2561 : !
2562 : contrib = 0.0_dp
2563 10350 : idir2 = ind_m2(iii, iiB)
2564 10350 : CALL cp_fm_trace(psi0, rr_p2(idir2, ii), contrib)
2565 10350 : chi_tmp = chi_tmp + 2.0_dp*contrib
2566 : contrib2 = 0.0_dp
2567 10350 : IF (iiB == ii) THEN
2568 3450 : CALL cp_fm_trace(psi0, r_p2(iii), contrib2)
2569 3450 : chi_tmp = chi_tmp + contrib2
2570 : END IF
2571 : !
2572 : ! correction: -dk_ii * 2[C0|(r-dk)_iiB | d_iii(C1(piiiB))] \
2573 : ! +dk_iii * 2[C0|(r-dk)_iiB | d_ii(C1(piiiB))]
2574 : ! the factor 2 should be already included in the matrix elements
2575 : ! no additional correction terms because of the orthogonality between C0 and C1
2576 : contrib = 0.0_dp
2577 10350 : CALL cp_fm_trace(psi0, rr_p2(iiB, iii), contrib)
2578 10350 : IF (.NOT. chi_pbc) chi_tmp = chi_tmp - 2.0_dp*dk(ii)*contrib
2579 10350 : int_current_tmp = int_current_tmp - 2.0_dp*contrib
2580 : !
2581 : contrib2 = 0.0_dp
2582 10350 : CALL cp_fm_trace(psi0, rr_p2(iiB, ii), contrib2)
2583 10350 : IF (.NOT. chi_pbc) chi_tmp = chi_tmp + 2.0_dp*dk(iii)*contrib2
2584 : !
2585 : ! term: +2[C0| (r-dk)_ii (r-dk)_iiiB | d_iii(C1(piiB))] \
2586 : ! -2[C0| (r-dk)_iii (r-dk)_iiiB | d_ii(C1(piiB))]
2587 : ! the factor 2 should be already included in the matrix elements
2588 : contrib = 0.0_dp
2589 10350 : idir2 = ind_m2(ii, iiiB)
2590 10350 : CALL cp_fm_trace(psi0, rr_p1(idir2, iii), contrib)
2591 10350 : chi_tmp = chi_tmp + 2.0_dp*contrib
2592 : contrib2 = 0.0_dp
2593 10350 : IF (iiiB == iii) THEN
2594 3450 : CALL cp_fm_trace(psi0, r_p1(ii), contrib2)
2595 3450 : chi_tmp = chi_tmp + contrib2
2596 : END IF
2597 : !
2598 : contrib = 0.0_dp
2599 10350 : idir2 = ind_m2(iii, iiiB)
2600 10350 : CALL cp_fm_trace(psi0, rr_p1(idir2, ii), contrib)
2601 10350 : chi_tmp = chi_tmp - 2.0_dp*contrib
2602 : contrib2 = 0.0_dp
2603 10350 : IF (iiiB == ii) THEN
2604 3450 : CALL cp_fm_trace(psi0, r_p1(iii), contrib2)
2605 3450 : chi_tmp = chi_tmp - contrib2
2606 : END IF
2607 : !
2608 : ! correction: +dk_ii * 2[C0|(r-dk)_iiiB | d_iii(C1(piiB))] +\
2609 : ! -dk_iii * 2[C0|(r-dk)_iiiB | d_ii(C1(piiB))]
2610 : ! the factor 2 should be already included in the matrix elements
2611 : contrib = 0.0_dp
2612 10350 : CALL cp_fm_trace(psi0, rr_p1(iiiB, iii), contrib)
2613 10350 : IF (.NOT. chi_pbc) chi_tmp = chi_tmp + 2.0_dp*dk(ii)*contrib
2614 10350 : int_current_tmp = int_current_tmp + 2.0_dp*contrib
2615 : !
2616 : contrib2 = 0.0_dp
2617 10350 : CALL cp_fm_trace(psi0, rr_p1(iiiB, ii), contrib2)
2618 10350 : IF (.NOT. chi_pbc) chi_tmp = chi_tmp - 2.0_dp*dk(iii)*contrib2
2619 : !
2620 : ! accumulate
2621 10350 : chi(idir) = chi(idir) + maxocc*chi_tmp
2622 106950 : int_current(iii) = int_current(iii) + int_current_tmp
2623 : END DO ! idir
2624 :
2625 : END DO ! icenter
2626 : !
2627 3306 : DO idir = 1, 3
2628 : current_env%chi_tensor(idir, iB, ispin) = current_env%chi_tensor(idir, iB, ispin) + &
2629 1746 : chi(idir)
2630 582 : IF (output_unit > 0) THEN
2631 : !WRITE(output_unit,'(A,E12.6)') ' chi_'//ACHAR(119+idir)//ACHAR(119+iB)//&
2632 : ! & ' = ',chi(idir)
2633 : !WRITE(output_unit,'(A,E12.6)') ' analytic \int j_'//ACHAR(119+idir)//ACHAR(119+iB)//&
2634 : ! & '(r) d^3r = ',int_current(idir)
2635 : END IF
2636 : END DO
2637 : !
2638 : END DO ! ispin
2639 : !
2640 : ! deallocate the sparse matrices
2641 396 : CALL dbcsr_deallocate_matrix_set(op_mom_ao)
2642 396 : CALL dbcsr_deallocate_matrix_set(op_mom_der_ao)
2643 396 : CALL dbcsr_deallocate_matrix_set(op_p_ao)
2644 :
2645 396 : CALL cp_fm_release(psi0)
2646 396 : CALL cp_fm_release(psi_rxp)
2647 396 : CALL cp_fm_release(psi_D)
2648 396 : CALL cp_fm_release(psi_p1)
2649 396 : CALL cp_fm_release(psi_p2)
2650 1584 : DO idir = 1, 3
2651 1188 : CALL cp_fm_release(p_rxp(idir))
2652 1188 : CALL cp_fm_release(r_p1(idir))
2653 1188 : CALL cp_fm_release(r_p2(idir))
2654 12276 : DO idir2 = 1, 9
2655 10692 : CALL cp_fm_release(rr_rxp(idir2, idir))
2656 10692 : CALL cp_fm_release(rr_p1(idir2, idir))
2657 11880 : CALL cp_fm_release(rr_p2(idir2, idir))
2658 : END DO
2659 : END DO
2660 :
2661 396 : CALL timestop(handle)
2662 :
2663 2376 : END SUBROUTINE current_build_chi_many_centers
2664 :
2665 : ! **************************************************************************************************
2666 : !> \brief ...
2667 : !> \param current_env ...
2668 : !> \param qs_env ...
2669 : !> \param iB ...
2670 : ! **************************************************************************************************
2671 96 : SUBROUTINE current_build_chi_one_center(current_env, qs_env, iB)
2672 : !
2673 : TYPE(current_env_type) :: current_env
2674 : TYPE(qs_environment_type), POINTER :: qs_env
2675 : INTEGER, INTENT(IN) :: iB
2676 :
2677 : CHARACTER(LEN=*), PARAMETER :: routineN = 'current_build_chi_one_center'
2678 :
2679 : CHARACTER(LEN=default_string_length) :: basis_type
2680 : INTEGER :: handle, idir, idir2, iiB, iiiB, ispin, jdir, jjdir, kdir, max_states, nao, natom, &
2681 : nbr_center(2), nmo, nspins, nstates(2), output_unit
2682 : INTEGER, ALLOCATABLE, DIMENSION(:) :: first_sgf, last_sgf
2683 96 : INTEGER, DIMENSION(:), POINTER :: row_blk_sizes
2684 : LOGICAL :: chi_pbc, gapw
2685 : REAL(dp) :: chi(3), contrib, dk(3), int_current(3), &
2686 : maxocc
2687 : TYPE(cell_type), POINTER :: cell
2688 96 : TYPE(cp_2d_i_p_type), DIMENSION(:), POINTER :: center_list
2689 96 : TYPE(cp_2d_r_p_type), DIMENSION(:), POINTER :: centers_set
2690 : TYPE(cp_fm_type) :: buf
2691 96 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: psi0_order
2692 96 : TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: psi1_p, psi1_rxp
2693 : TYPE(cp_fm_type), POINTER :: mo_coeff
2694 : TYPE(cp_logger_type), POINTER :: logger
2695 : TYPE(dbcsr_distribution_type), POINTER :: dbcsr_dist
2696 96 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: op_mom_ao, op_p_ao
2697 96 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: op_mom_der_ao
2698 : TYPE(dft_control_type), POINTER :: dft_control
2699 96 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
2700 : TYPE(mp_para_env_type), POINTER :: para_env
2701 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
2702 96 : POINTER :: sab_all, sab_orb
2703 96 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2704 96 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2705 :
2706 : !
2707 :
2708 96 : CALL timeset(routineN, handle)
2709 : !
2710 96 : NULLIFY (dft_control, mos, para_env, mo_coeff, op_mom_ao, &
2711 96 : op_mom_der_ao, center_list, centers_set, &
2712 96 : op_p_ao, psi1_p, psi1_rxp, cell, psi0_order)
2713 :
2714 96 : logger => cp_get_default_logger()
2715 96 : output_unit = cp_logger_get_default_io_unit(logger)
2716 :
2717 : CALL get_qs_env(qs_env=qs_env, &
2718 : dft_control=dft_control, &
2719 : mos=mos, &
2720 : para_env=para_env, &
2721 : cell=cell, &
2722 : particle_set=particle_set, &
2723 : qs_kind_set=qs_kind_set, &
2724 : sab_all=sab_all, &
2725 : sab_orb=sab_orb, &
2726 96 : dbcsr_dist=dbcsr_dist)
2727 :
2728 96 : nspins = dft_control%nspins
2729 96 : gapw = dft_control%qs_control%gapw
2730 96 : basis_type = "ORB"
2731 96 : IF (gapw) basis_type = "ORB_SOFT"
2732 :
2733 : CALL get_current_env(current_env=current_env, &
2734 : chi_pbc=chi_pbc, &
2735 : nao=nao, &
2736 : nbr_center=nbr_center, &
2737 : center_list=center_list, &
2738 : centers_set=centers_set, &
2739 : psi1_p=psi1_p, &
2740 : psi1_rxp=psi1_rxp, &
2741 : nstates=nstates, &
2742 96 : psi0_order=psi0_order)
2743 : !
2744 228 : max_states = MAXVAL(nstates(1:nspins))
2745 : !
2746 : ! Allocate sparse matrices for dipole, quadrupole and their derivatives => 9x3
2747 : ! Remember the derivatives are antisymmetric
2748 96 : CALL dbcsr_allocate_matrix_set(op_mom_ao, 9)
2749 96 : CALL dbcsr_allocate_matrix_set(op_mom_der_ao, 9, 3)
2750 : !
2751 : ! prepare for allocation
2752 96 : natom = SIZE(particle_set, 1)
2753 288 : ALLOCATE (first_sgf(natom))
2754 192 : ALLOCATE (last_sgf(natom))
2755 : CALL get_particle_set(particle_set, qs_kind_set, &
2756 : first_sgf=first_sgf, &
2757 96 : last_sgf=last_sgf)
2758 192 : ALLOCATE (row_blk_sizes(natom))
2759 96 : CALL dbcsr_convert_offsets_to_sizes(first_sgf, row_blk_sizes, last_sgf)
2760 96 : DEALLOCATE (first_sgf)
2761 96 : DEALLOCATE (last_sgf)
2762 : !
2763 : !
2764 96 : ALLOCATE (op_mom_ao(1)%matrix)
2765 : CALL dbcsr_create(matrix=op_mom_ao(1)%matrix, &
2766 : name="op_mom", &
2767 : dist=dbcsr_dist, matrix_type=dbcsr_type_no_symmetry, &
2768 : row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
2769 96 : mutable_work=.TRUE.)
2770 96 : CALL cp_dbcsr_alloc_block_from_nbl(op_mom_ao(1)%matrix, sab_all)
2771 :
2772 384 : DO idir2 = 1, 3
2773 288 : ALLOCATE (op_mom_der_ao(1, idir2)%matrix)
2774 : CALL dbcsr_copy(op_mom_der_ao(1, idir2)%matrix, op_mom_ao(1)%matrix, &
2775 384 : "op_mom_der_ao"//"-"//TRIM(ADJUSTL(cp_to_string(idir2))))
2776 : END DO
2777 :
2778 864 : DO idir = 2, SIZE(op_mom_ao, 1)
2779 768 : ALLOCATE (op_mom_ao(idir)%matrix)
2780 : CALL dbcsr_copy(op_mom_ao(idir)%matrix, op_mom_ao(1)%matrix, &
2781 768 : "op_mom_ao"//"-"//TRIM(ADJUSTL(cp_to_string(idir))))
2782 3168 : DO idir2 = 1, 3
2783 2304 : ALLOCATE (op_mom_der_ao(idir, idir2)%matrix)
2784 : CALL dbcsr_copy(op_mom_der_ao(idir, idir2)%matrix, op_mom_ao(1)%matrix, &
2785 3072 : "op_mom_der_ao"//"-"//TRIM(ADJUSTL(cp_to_string(idir*idir2))))
2786 : END DO
2787 : END DO
2788 : !
2789 96 : CALL dbcsr_allocate_matrix_set(op_p_ao, 3)
2790 96 : ALLOCATE (op_p_ao(1)%matrix)
2791 : CALL dbcsr_create(matrix=op_p_ao(1)%matrix, &
2792 : name="op_p_ao", &
2793 : dist=dbcsr_dist, matrix_type=dbcsr_type_antisymmetric, &
2794 : row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
2795 96 : mutable_work=.TRUE.)
2796 96 : CALL cp_dbcsr_alloc_block_from_nbl(op_p_ao(1)%matrix, sab_orb)
2797 :
2798 288 : DO idir = 2, 3
2799 192 : ALLOCATE (op_p_ao(idir)%matrix)
2800 : CALL dbcsr_copy(op_p_ao(idir)%matrix, op_p_ao(1)%matrix, &
2801 288 : "op_p_ao"//"-"//TRIM(ADJUSTL(cp_to_string(idir))))
2802 : END DO
2803 : !
2804 : !
2805 96 : DEALLOCATE (row_blk_sizes)
2806 : !
2807 : ! recompute the linear momentum matrices
2808 96 : CALL build_lin_mom_matrix(qs_env, op_p_ao)
2809 : !
2810 : !
2811 : ! get iiB and iiiB
2812 96 : CALL set_vecp(iB, iiB, iiiB)
2813 228 : DO ispin = 1, nspins
2814 : !
2815 132 : CPASSERT(nbr_center(ispin) == 1)
2816 : !
2817 : ! get ground state MOS
2818 132 : nmo = nstates(ispin)
2819 132 : mo_coeff => psi0_order(ispin)
2820 132 : CALL get_mo_set(mo_set=mos(ispin), maxocc=maxocc)
2821 : !
2822 : ! Create buffer matrix
2823 132 : CALL cp_fm_create(buf, mo_coeff%matrix_struct)
2824 : !
2825 : ! Initialize the temporary vector chi
2826 132 : chi = 0.0_dp
2827 : int_current = 0.0_dp
2828 : !
2829 : !
2830 : ! Get the Wannier center of the istate-th ground state orbital
2831 528 : dk(1:3) = centers_set(ispin)%array(1:3, 1)
2832 : !
2833 : ! Compute the multipole integrals for the state istate,
2834 : ! using as reference center the corresponding Wannier center
2835 1320 : DO idir = 1, 9
2836 1188 : CALL dbcsr_set(op_mom_ao(idir)%matrix, 0.0_dp)
2837 4884 : DO idir2 = 1, 3
2838 4752 : CALL dbcsr_set(op_mom_der_ao(idir, idir2)%matrix, 0.0_dp)
2839 : END DO
2840 : END DO
2841 : CALL build_local_moments_der_matrix(qs_env, op_mom_der_ao, 2, 2, ref_point=dk, &
2842 : moments=op_mom_ao, basis_type=basis_type, &
2843 132 : minimum_image=.FALSE., ordered=.TRUE.)
2844 : !
2845 : !
2846 : ! Multuply left and right by the appropriate coefficients and sum into the
2847 : ! correct component of the chi tensor using the appropriate multiplicative factor
2848 : ! (don't forget the occupation number)
2849 : ! Loop over the cartesian components of the tensor
2850 : ! The loop over the components of the external field is external, thereby
2851 : ! only one column of the chi tensor is computed here
2852 528 : DO idir = 1, 3
2853 : !
2854 : !
2855 : !
2856 : ! term: dk_ii*2[C0| d_iii(C1(rxp-D))] - dk_iii*2[C0| d_ii(C1(rxp-D))]
2857 396 : IF (.NOT. chi_pbc) THEN
2858 : CALL cp_dbcsr_sm_fm_multiply(op_p_ao(idir)%matrix, mo_coeff, &
2859 396 : buf, ncol=nmo, alpha=1.e0_dp)
2860 1584 : DO jdir = 1, 3
2861 5148 : DO kdir = 1, 3
2862 3564 : IF (Levi_Civita(kdir, jdir, idir) == 0.0_dp) CYCLE
2863 792 : CALL cp_fm_trace(buf, psi1_rxp(ispin, iB), contrib)
2864 4752 : chi(kdir) = chi(kdir) - Levi_Civita(kdir, jdir, idir)*2.0_dp*dk(jdir)*contrib
2865 : END DO
2866 : END DO
2867 : END IF
2868 : !
2869 : !
2870 : !
2871 : ! term: 2[C0| (r-dk)_ii |d_iii(C1(rxp-D))]-2[C0| (r-dk)_iii |d_ii(C1(rxp-D))]
2872 : ! and
2873 : ! term: -dk_ii * 2[C0|(r-dk)_iiB | d_iii(C1(piiiB))] +
2874 : ! +dk_iii * 2[C0|(r-dk)_iiB | d_ii(C1(piiiB))]
2875 : ! and
2876 : ! term: +dk_ii * 2[C0|(r-dk)_iiiB | d_iii(C1(piiB))] +
2877 : ! -dk_iii * 2[C0|(r-dk)_iiiB | d_ii(C1(piiB))]
2878 1584 : DO jdir = 1, 3
2879 : CALL cp_dbcsr_sm_fm_multiply(op_mom_der_ao(jdir, idir)%matrix, mo_coeff, &
2880 1188 : buf, ncol=nmo, alpha=1.e0_dp)
2881 4752 : DO kdir = 1, 3
2882 3564 : IF (Levi_Civita(kdir, jdir, idir) == 0.0_dp) CYCLE
2883 792 : CALL cp_fm_trace(buf, psi1_rxp(ispin, iB), contrib)
2884 4752 : chi(kdir) = chi(kdir) - Levi_Civita(kdir, jdir, idir)*2.0_dp*contrib
2885 : END DO
2886 : !
2887 1584 : IF (.NOT. chi_pbc) THEN
2888 1188 : IF (jdir == iiB) THEN
2889 1584 : DO jjdir = 1, 3
2890 5148 : DO kdir = 1, 3
2891 3564 : IF (Levi_Civita(kdir, jjdir, idir) == 0.0_dp) CYCLE
2892 792 : CALL cp_fm_trace(buf, psi1_p(ispin, iiiB), contrib)
2893 4752 : chi(kdir) = chi(kdir) + Levi_Civita(kdir, jjdir, idir)*2.0_dp*dk(jjdir)*contrib
2894 : END DO
2895 : END DO
2896 : END IF
2897 : !
2898 1188 : IF (jdir == iiiB) THEN
2899 1584 : DO jjdir = 1, 3
2900 5148 : DO kdir = 1, 3
2901 3564 : IF (Levi_Civita(kdir, jjdir, idir) == 0.0_dp) CYCLE
2902 792 : CALL cp_fm_trace(buf, psi1_p(ispin, iiB), contrib)
2903 4752 : chi(kdir) = chi(kdir) - Levi_Civita(kdir, jjdir, idir)*2.0_dp*dk(jjdir)*contrib
2904 : END DO
2905 : END DO
2906 : END IF
2907 : END IF
2908 : END DO
2909 : !
2910 : !
2911 : !
2912 : ! term1: -2[C0| (r-dk)_ii (r-dk)_iiB | d_iii(C1(piiiB))] +
2913 : ! +2[C0| (r-dk)_iii (r-dk)_iiB | d_ii(C1(piiiB))]
2914 : ! and
2915 : ! term1: +2[C0| (r-dk)_ii (r-dk)_iiiB | d_iii(C1(piiB))] +
2916 : ! -2[C0| (r-dk)_iii (r-dk)_iiiB | d_ii(C1(piiB))]
2917 : ! HERE THERE IS ONE EXTRA MULTIPLY
2918 1584 : DO jdir = 1, 3
2919 : CALL cp_dbcsr_sm_fm_multiply(op_mom_der_ao(ind_m2(jdir, iiB), idir)%matrix, mo_coeff, &
2920 1188 : buf, ncol=nmo, alpha=1.e0_dp)
2921 4752 : DO kdir = 1, 3
2922 3564 : IF (Levi_Civita(kdir, jdir, idir) == 0.0_dp) CYCLE
2923 792 : CALL cp_fm_trace(buf, psi1_p(ispin, iiiB), contrib)
2924 4752 : chi(kdir) = chi(kdir) + Levi_Civita(kdir, jdir, idir)*2.0_dp*contrib
2925 : END DO
2926 : !
2927 : CALL cp_dbcsr_sm_fm_multiply(op_mom_der_ao(ind_m2(jdir, iiiB), idir)%matrix, mo_coeff, &
2928 1188 : buf, ncol=nmo, alpha=1.e0_dp)
2929 5148 : DO kdir = 1, 3
2930 3564 : IF (Levi_Civita(kdir, jdir, idir) == 0.0_dp) CYCLE
2931 792 : CALL cp_fm_trace(buf, psi1_p(ispin, iiB), contrib)
2932 4752 : chi(kdir) = chi(kdir) - Levi_Civita(kdir, jdir, idir)*2.0_dp*contrib
2933 : END DO
2934 : END DO
2935 : !
2936 : !
2937 : !
2938 : ! term2: -2[C0| (r-dk)_ii (r-dk)_iiB | d_iii(C1(piiiB))] +
2939 : ! +2[C0| (r-dk)_iii (r-dk)_iiB | d_ii(C1(piiiB))]
2940 : ! and
2941 : ! term2: +2[C0| (r-dk)_ii (r-dk)_iiiB | d_iii(C1(piiB))] +
2942 : ! -2[C0| (r-dk)_iii (r-dk)_iiiB | d_ii(C1(piiB))]
2943 : CALL cp_dbcsr_sm_fm_multiply(op_mom_ao(idir)%matrix, mo_coeff, &
2944 396 : buf, ncol=nmo, alpha=1.e0_dp)
2945 1584 : DO jdir = 1, 3
2946 5148 : DO kdir = 1, 3
2947 3564 : IF (Levi_Civita(kdir, idir, jdir) == 0.0_dp) CYCLE
2948 1980 : IF (iiB == jdir) THEN
2949 264 : CALL cp_fm_trace(buf, psi1_p(ispin, iiiB), contrib)
2950 264 : chi(kdir) = chi(kdir) + Levi_Civita(kdir, idir, jdir)*contrib
2951 : END IF
2952 : END DO
2953 : END DO
2954 : !
2955 1716 : DO jdir = 1, 3
2956 5148 : DO kdir = 1, 3
2957 3564 : IF (Levi_Civita(kdir, idir, jdir) == 0.0_dp) CYCLE
2958 1980 : IF (iiiB == jdir) THEN
2959 264 : CALL cp_fm_trace(buf, psi1_p(ispin, iiB), contrib)
2960 264 : chi(kdir) = chi(kdir) - Levi_Civita(kdir, idir, jdir)*contrib
2961 : END IF
2962 : !
2963 : END DO
2964 : END DO
2965 : !
2966 : !
2967 : !
2968 : !
2969 : END DO ! idir
2970 : !
2971 528 : DO idir = 1, 3
2972 : current_env%chi_tensor(idir, iB, ispin) = current_env%chi_tensor(idir, iB, ispin) + &
2973 396 : maxocc*chi(idir)
2974 132 : IF (output_unit > 0) THEN
2975 : !WRITE(output_unit,'(A,E12.6)') ' chi_'//ACHAR(119+idir)//ACHAR(119+iB)//&
2976 : ! & ' = ',maxocc * chi(idir)
2977 : END IF
2978 : END DO
2979 : !
2980 360 : CALL cp_fm_release(buf)
2981 : END DO ! ispin
2982 : !
2983 : ! deallocate the sparse matrices
2984 96 : CALL dbcsr_deallocate_matrix_set(op_mom_ao)
2985 96 : CALL dbcsr_deallocate_matrix_set(op_mom_der_ao)
2986 96 : CALL dbcsr_deallocate_matrix_set(op_p_ao)
2987 :
2988 96 : CALL timestop(handle)
2989 :
2990 192 : END SUBROUTINE current_build_chi_one_center
2991 :
2992 0 : END MODULE qs_linres_current
|