(git:d3d49ac)
Loading...
Searching...
No Matches
qs_linres_current.F
Go to the documentation of this file.
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! **************************************************************************************************
22 USE cell_types, ONLY: cell_type,&
23 pbc
27 USE cp_dbcsr_api, ONLY: &
28 dbcsr_convert_offsets_to_sizes, dbcsr_copy, dbcsr_create, dbcsr_deallocate_matrix, &
30 dbcsr_set, dbcsr_type, dbcsr_type_antisymmetric, dbcsr_type_no_symmetry
41 USE cp_fm_types, ONLY: cp_fm_create,&
50 USE cp_output_handling, ONLY: cp_p_file,&
59 USE grid_api, ONLY: &
70 USE kinds, ONLY: default_path_length,&
72 dp
73 USE mathconstants, ONLY: twopi
76 USE orbital_pointers, ONLY: ncoset
80 USE pw_env_types, ONLY: pw_env_get,&
82 USE pw_methods, ONLY: pw_axpy,&
84 pw_scale,&
87 USE pw_types, ONLY: pw_c1d_gs_type,&
91 USE qs_kind_types, ONLY: get_qs_kind,&
97 USE qs_linres_op, ONLY: fac_vecp,&
99 ind_m2,&
100 set_vecp,&
105 USE qs_mo_types, ONLY: get_mo_set,&
115 USE qs_rho_types, ONLY: qs_rho_get
116 USE qs_subsys_types, ONLY: qs_subsys_get,&
132#include "./base/base_uses.f90"
133
134 IMPLICIT NONE
135
136 PRIVATE
137
138 ! *** Public subroutines ***
140
141 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_linres_current'
142
143 TYPE box_type
144 INTEGER :: n = -1
145 REAL(dp), POINTER, DIMENSION(:, :) :: r => null()
146 END TYPE box_type
147 REAL(dp), DIMENSION(3, 3, 3), PARAMETER :: levi_civita = reshape([ &
148 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, &
149 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, &
150 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])
151
152CONTAINS
153
154! **************************************************************************************************
155!> \brief First calculate the density matrixes, for each component of the current
156!> they are 3 because of the r dependent terms
157!> Next it collocates on the grid to have J(r)
158!> In the GAPW case one need to collocate on the PW grid only the soft part
159!> while the rest goes on Lebedev grids
160!> The contributions to the shift and to the susceptibility will be
161!> calculated separately and added only at the end
162!> The calculation of the shift tensor is performed on the position of the atoms
163!> and on other selected points in real space summing up the contributions
164!> from the PW grid current density and the local densities
165!> Spline interpolation is used
166!> \param current_env ...
167!> \param qs_env ...
168!> \param iB ...
169!> \author MI
170!> \note
171!> The susceptibility is needed to compute the G=0 term of the shift
172!> in reciprocal space. \chi_{ij} = \int (r x Jj)_i
173!> (where Jj id the current density generated by the field in direction j)
174!> To calculate the susceptibility on the PW grids it is necessary to apply
175!> the position operator yet another time.
176!> This cannot be done on directly on the full J(r) because it is not localized
177!> Therefore it is done state by state (see linres_nmr_shift)
178! **************************************************************************************************
179 SUBROUTINE current_build_current(current_env, qs_env, iB)
180 !
181 TYPE(current_env_type) :: current_env
182 TYPE(qs_environment_type), POINTER :: qs_env
183 INTEGER, INTENT(IN) :: ib
184
185 CHARACTER(LEN=*), PARAMETER :: routinen = 'current_build_current'
186
187 CHARACTER(LEN=default_path_length) :: ext, filename, my_pos
188 INTEGER :: handle, idir, iib, iiib, ispin, istate, &
189 j, jstate, nao, natom, nmo, nspins, &
190 nstates(2), output_unit, unit_nr
191 INTEGER, ALLOCATABLE, DIMENSION(:) :: first_sgf, last_sgf
192 INTEGER, DIMENSION(:), POINTER :: row_blk_sizes
193 LOGICAL :: append_cube, gapw, mpi_io
194 REAL(dp) :: dk(3), jrho_tot_g(3, 3), &
195 jrho_tot_r(3, 3), maxocc, scale_fac
196 REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: ddk
197 REAL(dp), EXTERNAL :: ddot
198 TYPE(cell_type), POINTER :: cell
199 TYPE(cp_2d_i_p_type), DIMENSION(:), POINTER :: center_list
200 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: p_psi1, psi1
201 TYPE(cp_fm_type), DIMENSION(:), POINTER :: psi0_order
202 TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: psi1_d, psi1_p, psi1_rxp
203 TYPE(cp_fm_type), POINTER :: mo_coeff
204 TYPE(cp_logger_type), POINTER :: logger
205 TYPE(dbcsr_distribution_type), POINTER :: dbcsr_dist
206 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: density_matrix0, density_matrix_a, &
207 density_matrix_ii, density_matrix_iii
208 TYPE(dft_control_type), POINTER :: dft_control
209 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
210 TYPE(mp_para_env_type), POINTER :: para_env
211 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
212 POINTER :: sab_all
213 TYPE(particle_list_type), POINTER :: particles
214 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
215 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: jrho1_g
216 TYPE(pw_env_type), POINTER :: pw_env
217 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
218 TYPE(pw_r3d_rs_type) :: wf_r
219 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: jrho1_r
220 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
221 TYPE(qs_matrix_pools_type), POINTER :: mpools
222 TYPE(qs_subsys_type), POINTER :: subsys
223 TYPE(realspace_grid_desc_type), POINTER :: auxbas_rs_desc
224 TYPE(section_vals_type), POINTER :: current_section
225
226 CALL timeset(routinen, handle)
227 !
228 NULLIFY (logger, current_section, density_matrix0, density_matrix_a, &
229 density_matrix_ii, density_matrix_iii, cell, dft_control, mos, &
230 particle_set, pw_env, auxbas_rs_desc, auxbas_pw_pool, &
231 para_env, center_list, mo_coeff, jrho1_r, jrho1_g, &
232 psi1_p, psi1_d, psi1_rxp, sab_all, qs_kind_set)
233
234 logger => cp_get_default_logger()
235 output_unit = cp_logger_get_default_io_unit(logger)
236 !
237 !
238 CALL get_current_env(current_env=current_env, &
239 center_list=center_list, &
240 psi1_rxp=psi1_rxp, &
241 psi1_d=psi1_d, &
242 psi1_p=psi1_p, &
243 psi0_order=psi0_order, &
244 nstates=nstates, &
245 nao=nao)
246 !
247 !
248 CALL get_qs_env(qs_env=qs_env, &
249 cell=cell, &
250 dft_control=dft_control, &
251 mos=mos, &
252 mpools=mpools, &
253 pw_env=pw_env, &
254 para_env=para_env, &
255 subsys=subsys, &
256 sab_all=sab_all, &
257 particle_set=particle_set, &
258 qs_kind_set=qs_kind_set, &
259 dbcsr_dist=dbcsr_dist)
260
261 CALL qs_subsys_get(subsys, particles=particles)
262
263 gapw = dft_control%qs_control%gapw
264 nspins = dft_control%nspins
265 natom = SIZE(particle_set, 1)
266 !
267 ! allocate temporary arrays
268 ALLOCATE (psi1(nspins), p_psi1(nspins))
269 DO ispin = 1, nspins
270 CALL cp_fm_create(psi1(ispin), psi0_order(ispin)%matrix_struct)
271 CALL cp_fm_create(p_psi1(ispin), psi0_order(ispin)%matrix_struct)
272 CALL cp_fm_set_all(psi1(ispin), 0.0_dp)
273 CALL cp_fm_set_all(p_psi1(ispin), 0.0_dp)
274 END DO
275 !
276 !
277 CALL dbcsr_allocate_matrix_set(density_matrix0, nspins)
278 CALL dbcsr_allocate_matrix_set(density_matrix_a, nspins)
279 CALL dbcsr_allocate_matrix_set(density_matrix_ii, nspins)
280 CALL dbcsr_allocate_matrix_set(density_matrix_iii, nspins)
281 !
282 ! prepare for allocation
283 ALLOCATE (first_sgf(natom))
284 ALLOCATE (last_sgf(natom))
285 CALL get_particle_set(particle_set, qs_kind_set, &
286 first_sgf=first_sgf, &
287 last_sgf=last_sgf)
288 ALLOCATE (row_blk_sizes(natom))
289 CALL dbcsr_convert_offsets_to_sizes(first_sgf, row_blk_sizes, last_sgf)
290 DEALLOCATE (first_sgf)
291 DEALLOCATE (last_sgf)
292 !
293 !
294 DO ispin = 1, nspins
295 !
296 !density_matrix0
297 ALLOCATE (density_matrix0(ispin)%matrix)
298 CALL dbcsr_create(matrix=density_matrix0(ispin)%matrix, &
299 name="density_matrix0", &
300 dist=dbcsr_dist, matrix_type=dbcsr_type_no_symmetry, &
301 row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
302 mutable_work=.true.)
303 CALL cp_dbcsr_alloc_block_from_nbl(density_matrix0(ispin)%matrix, sab_all)
304 !
305 !density_matrix_a
306 ALLOCATE (density_matrix_a(ispin)%matrix)
307 CALL dbcsr_copy(density_matrix_a(ispin)%matrix, density_matrix0(ispin)%matrix, &
308 name="density_matrix_a")
309 !
310 !density_matrix_ii
311 ALLOCATE (density_matrix_ii(ispin)%matrix)
312 CALL dbcsr_copy(density_matrix_ii(ispin)%matrix, density_matrix0(ispin)%matrix, &
313 name="density_matrix_ii")
314 !
315 !density_matrix_iii
316 ALLOCATE (density_matrix_iii(ispin)%matrix)
317 CALL dbcsr_copy(density_matrix_iii(ispin)%matrix, density_matrix0(ispin)%matrix, &
318 name="density_matrix_iii")
319 END DO
320 !
321 DEALLOCATE (row_blk_sizes)
322 !
323 !
324 current_section => section_vals_get_subs_vals(qs_env%input, "PROPERTIES%LINRES%CURRENT")
325 !
326 !
327 jrho_tot_g = 0.0_dp
328 jrho_tot_r = 0.0_dp
329 !
330 ! Lets go!
331 CALL set_vecp(ib, iib, iiib)
332 DO ispin = 1, nspins
333 nmo = nstates(ispin)
334 mo_coeff => psi0_order(ispin)
335 !maxocc = max_occ(ispin)
336 !
337 CALL get_mo_set(mo_set=mos(ispin), maxocc=maxocc)
338 !
339 !
340 ! Build the first density matrix
341 CALL dbcsr_set(density_matrix0(ispin)%matrix, 0.0_dp)
342 CALL cp_dbcsr_plus_fm_fm_t(sparse_matrix=density_matrix0(ispin)%matrix, &
343 matrix_v=mo_coeff, matrix_g=mo_coeff, &
344 ncol=nmo, alpha=maxocc)
345 !
346 ! Allocate buffer vectors
347 ALLOCATE (ddk(3, nmo))
348 !
349 ! Construct the 3 density matrices for the field in direction iB
350 !
351 ! First the full matrix psi_a_iB
352 associate(psi_a_ib => psi1(ispin), psi_buf => p_psi1(ispin))
353 CALL cp_fm_set_all(psi_a_ib, 0.0_dp)
354 CALL cp_fm_set_all(psi_buf, 0.0_dp)
355 ! psi_a_iB = - (R_\nu-dk)_ii psi1_piiiB + (R_\nu-dk)_iii psi1_piiB
356 !
357 ! contributions from the response psi1_p_ii and psi1_p_iii
358 DO istate = 1, current_env%nbr_center(ispin)
359 dk(1:3) = current_env%centers_set(ispin)%array(1:3, istate)
360 !
361 ! Copy the vector in the full matrix psi1
362 !nstate_loc = center_list(ispin)%array(1,icenter+1)-center_list(ispin)%array(1,icenter)
363 DO j = center_list(ispin)%array(1, istate), center_list(ispin)%array(1, istate + 1) - 1
364 jstate = center_list(ispin)%array(2, j)
365 CALL cp_fm_to_fm(psi1_p(ispin, iib), psi_a_ib, 1, jstate, jstate)
366 CALL cp_fm_to_fm(psi1_p(ispin, iiib), psi_buf, 1, jstate, jstate)
367 ddk(:, jstate) = dk(1:3)
368 END DO
369 END DO ! istate
370 CALL fm_scale_by_pbc_ac(psi_a_ib, current_env%basisfun_center, ddk, cell, iiib)
371 CALL fm_scale_by_pbc_ac(psi_buf, current_env%basisfun_center, ddk, cell, iib)
372 CALL cp_fm_scale_and_add(-1.0_dp, psi_a_ib, 1.0_dp, psi_buf)
373 !
374 !psi_a_iB = psi_a_iB + psi1_rxp
375 !
376 ! contribution from the response psi1_rxp
377 CALL cp_fm_scale_and_add(-1.0_dp, psi_a_ib, 1.0_dp, psi1_rxp(ispin, ib))
378 !
379 !psi_a_iB = psi_a_iB - psi1_D
380 IF (current_env%full) THEN
381 !
382 ! contribution from the response psi1_D
383 CALL cp_fm_scale_and_add(1.0_dp, psi_a_ib, -1.0_dp, psi1_d(ispin, ib))
384 END IF
385 !
386 ! Multiply by the occupation number for the density matrix
387 !
388 ! Build the first density matrix
389 CALL dbcsr_set(density_matrix_a(ispin)%matrix, 0.0_dp)
390 CALL cp_dbcsr_plus_fm_fm_t(sparse_matrix=density_matrix_a(ispin)%matrix, &
391 matrix_v=mo_coeff, matrix_g=psi_a_ib, &
392 ncol=nmo, alpha=maxocc)
393 END associate
394 !
395 ! Build the second density matrix
396 CALL dbcsr_set(density_matrix_iii(ispin)%matrix, 0.0_dp)
397 CALL cp_dbcsr_plus_fm_fm_t(sparse_matrix=density_matrix_iii(ispin)%matrix, &
398 matrix_v=mo_coeff, matrix_g=psi1_p(ispin, iiib), &
399 ncol=nmo, alpha=maxocc)
400 !
401 ! Build the third density matrix
402 CALL dbcsr_set(density_matrix_ii(ispin)%matrix, 0.0_dp)
403 CALL cp_dbcsr_plus_fm_fm_t(sparse_matrix=density_matrix_ii(ispin)%matrix, &
404 matrix_v=mo_coeff, matrix_g=psi1_p(ispin, iib), &
405 ncol=nmo, alpha=maxocc)
406 DO idir = 1, 3
407 !
408 ! Calculate the current density on the pw grid (only soft if GAPW)
409 ! idir is the cartesian component of the response current density
410 ! generated by the magnetic field pointing in cartesian direction iB
411 ! Use the qs_rho_type already used for rho during the scf
412 CALL qs_rho_get(current_env%jrho1_set(idir)%rho, rho_r=jrho1_r)
413 CALL qs_rho_get(current_env%jrho1_set(idir)%rho, rho_g=jrho1_g)
414 associate(jrho_rspace => jrho1_r(ispin), jrho_gspace => jrho1_g(ispin))
415 CALL pw_zero(jrho_rspace)
416 CALL pw_zero(jrho_gspace)
417 CALL calculate_jrho_resp(density_matrix0(ispin)%matrix, &
418 density_matrix_a(ispin)%matrix, &
419 density_matrix_ii(ispin)%matrix, &
420 density_matrix_iii(ispin)%matrix, &
421 ib, idir, jrho_rspace, jrho_gspace, qs_env, &
422 current_env, gapw)
423
424 scale_fac = cell%deth/twopi
425 CALL pw_scale(jrho_rspace, scale_fac)
426 CALL pw_scale(jrho_gspace, scale_fac)
427
428 jrho_tot_g(idir, ib) = pw_integrate_function(jrho_gspace, isign=-1)
429 jrho_tot_r(idir, ib) = pw_integrate_function(jrho_rspace, isign=-1)
430 END associate
431
432 IF (output_unit > 0) THEN
433 WRITE (output_unit, '(T2,2(A,E24.16))') 'Integrated j_'&
434 &//achar(idir + 119)//achar(ib + 119)//'(r): G-space=', &
435 jrho_tot_g(idir, ib), ' R-space=', jrho_tot_r(idir, ib)
436 END IF
437 !
438 END DO ! idir
439 !
440 ! Deallocate buffer vectors
441 DEALLOCATE (ddk)
442 !
443 END DO ! ispin
444
445 IF (gapw) THEN
446 DO idir = 1, 3
447 !
448 ! compute the atomic response current densities on the spherical grids
449 ! First the sparse matrices are multiplied by the expansion coefficients
450 ! this is the equivalent of the CPC for the charge density
451 CALL calculate_jrho_atom_coeff(qs_env, current_env, &
452 density_matrix0, &
453 density_matrix_a, &
454 density_matrix_ii, &
455 density_matrix_iii, &
456 ib, idir)
457 !
458 ! Then the radial parts are computed on the local radial grid, atom by atom
459 ! 8 functions are computed for each atom, per grid point
460 ! and per LM angular momentum. The multiplication by the Clebsh-Gordon
461 ! coefficients or they correspondent for the derivatives, is also done here
462 CALL calculate_jrho_atom_rad(qs_env, current_env, idir)
463 !
464 ! The current on the atomic grids
465 CALL calculate_jrho_atom(current_env, qs_env, ib, idir)
466 END DO ! idir
467 END IF
468 !
469 ! Cube files
470 IF (btest(cp_print_key_should_output(logger%iter_info, current_section,&
471 & "PRINT%CURRENT_CUBES"), cp_p_file)) THEN
472 append_cube = section_get_lval(current_section, "PRINT%CURRENT_CUBES%APPEND")
473 my_pos = "REWIND"
474 IF (append_cube) THEN
475 my_pos = "APPEND"
476 END IF
477 !
478 CALL pw_env_get(pw_env, auxbas_rs_desc=auxbas_rs_desc, &
479 auxbas_pw_pool=auxbas_pw_pool)
480 !
481 CALL auxbas_pw_pool%create_pw(wf_r)
482 !
483 DO idir = 1, 3
484 CALL pw_zero(wf_r)
485 CALL qs_rho_get(current_env%jrho1_set(idir)%rho, rho_r=jrho1_r)
486 DO ispin = 1, nspins
487 CALL pw_axpy(jrho1_r(ispin), wf_r, 1.0_dp)
488 END DO
489 !
490 IF (gapw) THEN
491 ! Add the local hard and soft contributions
492 ! This can be done atom by atom by a spline extrapolation of the values
493 ! on the spherical grid to the grid points.
494 cpabort("GAPW needs to be finalized")
495 END IF
496 filename = "jresp"
497 mpi_io = .true.
498 WRITE (ext, '(a2,I1,a2,I1,a5)') "iB", ib, "_d", idir, ".cube"
499 WRITE (ext, '(a2,a1,a2,a1,a5)') "iB", achar(ib + 119), "_d", achar(idir + 119), ".cube"
500 unit_nr = cp_print_key_unit_nr(logger, current_section, "PRINT%CURRENT_CUBES", &
501 extension=trim(ext), middle_name=trim(filename), &
502 log_filename=.false., file_position=my_pos, &
503 mpi_io=mpi_io)
504
505 CALL cp_pw_to_cube(wf_r, unit_nr, "RESPONSE CURRENT DENSITY ", &
506 particles=particles, &
507 stride=section_get_ivals(current_section, "PRINT%CURRENT_CUBES%STRIDE"), &
508 mpi_io=mpi_io)
509 CALL cp_print_key_finished_output(unit_nr, logger, current_section,&
510 & "PRINT%CURRENT_CUBES", mpi_io=mpi_io)
511 END DO
512 !
513 CALL auxbas_pw_pool%give_back_pw(wf_r)
514 END IF ! current cube
515 !
516 ! Integrated current response checksum
517 IF (output_unit > 0) THEN
518 WRITE (output_unit, '(T2,A,E24.16)') 'CheckSum R-integrated j=', &
519 sqrt(ddot(9, jrho_tot_r(1, 1), 1, jrho_tot_r(1, 1), 1))
520 END IF
521 !
522 !
523 ! Dellocate grids for the calculation of jrho and the shift
524 CALL cp_fm_release(psi1)
525 CALL cp_fm_release(p_psi1)
526
527 CALL dbcsr_deallocate_matrix_set(density_matrix0)
528 CALL dbcsr_deallocate_matrix_set(density_matrix_a)
529 CALL dbcsr_deallocate_matrix_set(density_matrix_ii)
530 CALL dbcsr_deallocate_matrix_set(density_matrix_iii)
531 !
532 ! Finalize
533 CALL timestop(handle)
534 !
535 END SUBROUTINE current_build_current
536
537! **************************************************************************************************
538!> \brief Calculation of the idir component of the response current density
539!> in the presence of a constant magnetic field in direction iB
540!> the current density is collocated on the pw grid in real space
541!> \param mat_d0 ...
542!> \param mat_jp ...
543!> \param mat_jp_rii ...
544!> \param mat_jp_riii ...
545!> \param iB ...
546!> \param idir ...
547!> \param current_rs ...
548!> \param current_gs ...
549!> \param qs_env ...
550!> \param current_env ...
551!> \param soft_valid ...
552!> \param retain_rsgrid ...
553!> \note
554!> The collocate is done in three parts, one for each density matrix
555!> In all cases the density matrices and therefore the collocation
556!> are not symmetric, that means that all the pairs (ab and ba) have
557!> to be considered separately
558!>
559!> mat_jp_{\mu\nu} is multiplied by
560!> f_{\mu\nu} = \phi_{\mu} (d\phi_{\nu}/dr)_{idir} -
561!> (d\phi_{\mu}/dr)_{idir} \phi_{\nu}
562!>
563!> mat_jp_rii_{\mu\nu} is multiplied by
564!> f_{\mu\nu} = \phi_{\mu} (r - R_{\nu})_{iiiB} (d\phi_{\nu}/dr)_{idir} -
565!> (d\phi_{\mu}/dr)_{idir} (r - R_{\nu})_{iiiB} \phi_{\nu} +
566!> \phi_{\mu} \phi_{\nu} (last term only if iiiB=idir)
567!>
568!> mat_jp_riii_{\mu\nu} is multiplied by
569!> (be careful: change in sign with respect to previous)
570!> f_{\mu\nu} = -\phi_{\mu} (r - R_{\nu})_{iiB} (d\phi_{\nu}/dr)_{idir} +
571!> (d\phi_{\mu}/dr)_{idir} (r - R_{\nu})_{iiB} \phi_{\nu} -
572!> \phi_{\mu} \phi_{\nu} (last term only if iiB=idir)
573!>
574!> All the terms sum up to the same grid
575! **************************************************************************************************
576 SUBROUTINE calculate_jrho_resp(mat_d0, mat_jp, mat_jp_rii, mat_jp_riii, iB, idir, &
577 current_rs, current_gs, qs_env, current_env, soft_valid, retain_rsgrid)
578
579 TYPE(dbcsr_type), POINTER :: mat_d0, mat_jp, mat_jp_rii, mat_jp_riii
580 INTEGER, INTENT(IN) :: ib, idir
581 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: current_rs
582 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: current_gs
583 TYPE(qs_environment_type), POINTER :: qs_env
584 TYPE(current_env_type) :: current_env
585 LOGICAL, INTENT(IN), OPTIONAL :: soft_valid, retain_rsgrid
586
587 CHARACTER(LEN=*), PARAMETER :: routinen = 'calculate_jrho_resp'
588 INTEGER, PARAMETER :: max_tasks = 2000
589
590 CHARACTER(LEN=default_string_length) :: basis_type
591 INTEGER :: adbmdab_func, bcol, brow, cindex, curr_tasks, handle, i, iatom, iatom_old, idir2, &
592 igrid_level, iib, iiib, ikind, ikind_old, ipgf, iset, iset_old, itask, ithread, jatom, &
593 jatom_old, jkind, jkind_old, jpgf, jset, jset_old, maxco, maxpgf, maxset, maxsgf, &
594 maxsgf_set, na1, na2, natom, nb1, nb2, ncoa, ncob, nimages, nkind, nseta, nsetb, ntasks, &
595 nthread, sgfa, sgfb
596 INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min, npgfa, &
597 npgfb, nsgfa, nsgfb
598 INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
599 LOGICAL :: atom_pair_changed, den_found, &
600 den_found_a, distributed_rs_grids, &
601 do_igaim, my_retain_rsgrid, my_soft
602 REAL(dp), DIMENSION(:, :, :), POINTER :: my_current, my_gauge, my_rho
603 REAL(kind=dp) :: eps_rho_rspace, f, kind_radius_a, &
604 kind_radius_b, lxo2, lyo2, lzo2, &
605 prefactor, radius, scale, scale2, zetp
606 REAL(kind=dp), DIMENSION(3) :: ra, rab, rb, rp
607 REAL(kind=dp), DIMENSION(:), POINTER :: set_radius_a, set_radius_b
608 REAL(kind=dp), DIMENSION(:, :), POINTER :: jp_block_a, jp_block_b, jp_block_c, jp_block_d, &
609 jpab_a, jpab_b, jpab_c, jpab_d, rpgfa, rpgfb, sphi_a, sphi_b, work, zeta, zetb
610 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: jpabt_a, jpabt_b, jpabt_c, jpabt_d, workt
611 TYPE(atom_pair_type), DIMENSION(:), POINTER :: atom_pair_recv, atom_pair_send
612 TYPE(cell_type), POINTER :: cell
613 TYPE(cube_info_type), DIMENSION(:), POINTER :: cube_info
614 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: deltajp_a, deltajp_b, deltajp_c, &
615 deltajp_d
616 TYPE(dbcsr_type), POINTER :: mat_a, mat_b, mat_c, mat_d
617 TYPE(dft_control_type), POINTER :: dft_control
618 TYPE(gridlevel_info_type), POINTER :: gridlevel_info
619 TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list
620 TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b, orb_basis_set
621 TYPE(mp_para_env_type), POINTER :: para_env
622 TYPE(neighbor_list_iterator_p_type), &
623 DIMENSION(:), POINTER :: nl_iterator
624 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
625 POINTER :: sab_orb
626 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
627 TYPE(pw_env_type), POINTER :: pw_env
628 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
629 TYPE(qs_kind_type), POINTER :: qs_kind
630 TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
631 POINTER :: rs_descs
632 TYPE(realspace_grid_type), DIMENSION(:), POINTER :: rs_current, rs_rho
633 TYPE(realspace_grid_type), DIMENSION(:, :), &
634 POINTER :: rs_gauge
635 TYPE(task_type), DIMENSION(:), POINTER :: tasks
636
637 NULLIFY (qs_kind, cell, dft_control, orb_basis_set, rs_rho, &
638 qs_kind_set, sab_orb, particle_set, rs_current, pw_env, &
639 rs_descs, para_env, set_radius_a, set_radius_b, la_max, la_min, &
640 lb_max, lb_min, npgfa, npgfb, nsgfa, nsgfb, rpgfa, rpgfb, &
641 sphi_a, sphi_b, zeta, zetb, first_sgfa, first_sgfb, tasks, &
642 workt, mat_a, mat_b, mat_c, mat_d, rs_gauge)
643 NULLIFY (deltajp_a, deltajp_b, deltajp_c, deltajp_d)
644 NULLIFY (jp_block_a, jp_block_b, jp_block_c, jp_block_d)
645 NULLIFY (jpabt_a, jpabt_b, jpabt_c, jpabt_d)
646 NULLIFY (atom_pair_send, atom_pair_recv)
647
648 CALL timeset(routinen, handle)
649
650 !
651 ! Set pointers for the different gauge
652 ! If do_igaim is False the current_env is never needed
653 do_igaim = current_env%gauge == current_gauge_atom
654
655 mat_a => mat_jp
656 mat_b => mat_jp_rii
657 mat_c => mat_jp_riii
658 IF (do_igaim) mat_d => mat_d0
659
660 my_retain_rsgrid = .false.
661 IF (PRESENT(retain_rsgrid)) my_retain_rsgrid = retain_rsgrid
662
663 CALL get_qs_env(qs_env=qs_env, &
664 qs_kind_set=qs_kind_set, &
665 cell=cell, &
666 dft_control=dft_control, &
667 particle_set=particle_set, &
668 sab_all=sab_orb, &
669 para_env=para_env, &
670 pw_env=pw_env)
671
672 IF (do_igaim) CALL get_current_env(current_env=current_env, rs_gauge=rs_gauge)
673
674 ! Component of appearing in the vector product rxp, iiB and iiiB
675 CALL set_vecp(ib, iib, iiib)
676 !
677 !
678 scale2 = 0.0_dp
679 idir2 = 1
680 IF (idir /= ib) THEN
681 CALL set_vecp_rev(idir, ib, idir2)
682 scale2 = fac_vecp(idir, ib, idir2)
683 END IF
684 !
685 ! *** assign from pw_env
686 gridlevel_info => pw_env%gridlevel_info
687 cube_info => pw_env%cube_info
688
689 ! Check that the neighbor list with all the pairs is associated
690 cpassert(ASSOCIATED(sab_orb))
691 ! *** set up the pw multi-grids
692 cpassert(ASSOCIATED(pw_env))
693 CALL pw_env_get(pw_env, rs_descs=rs_descs, rs_grids=rs_rho)
694
695 distributed_rs_grids = .false.
696 DO igrid_level = 1, gridlevel_info%ngrid_levels
697 IF (.NOT. all(rs_descs(igrid_level)%rs_desc%perd == 1)) THEN
698 distributed_rs_grids = .true.
699 END IF
700 END DO
701 eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
702 nthread = 1
703
704 ! *** Allocate work storage ***
705 CALL get_qs_kind_set(qs_kind_set=qs_kind_set, &
706 maxco=maxco, &
707 maxsgf=maxsgf, &
708 maxsgf_set=maxsgf_set)
709
710 lxo2 = sqrt(sum(cell%hmat(:, 1)**2))/2.0_dp
711 lyo2 = sqrt(sum(cell%hmat(:, 2)**2))/2.0_dp
712 lzo2 = sqrt(sum(cell%hmat(:, 3)**2))/2.0_dp
713
714 my_soft = .false.
715 IF (PRESENT(soft_valid)) my_soft = soft_valid
716 IF (my_soft) THEN
717 basis_type = "ORB_SOFT"
718 ELSE
719 basis_type = "ORB"
720 END IF
721
722 nkind = SIZE(qs_kind_set)
723
724 CALL reallocate(jpabt_a, 1, maxco, 1, maxco, 0, nthread - 1)
725 CALL reallocate(jpabt_b, 1, maxco, 1, maxco, 0, nthread - 1)
726 CALL reallocate(jpabt_c, 1, maxco, 1, maxco, 0, nthread - 1)
727 CALL reallocate(jpabt_d, 1, maxco, 1, maxco, 0, nthread - 1)
728 CALL reallocate(workt, 1, maxco, 1, maxsgf_set, 0, nthread - 1)
729 CALL reallocate_tasks(tasks, max_tasks)
730
731 ntasks = 0
732 curr_tasks = SIZE(tasks)
733
734 ! get maximum numbers
735 natom = SIZE(particle_set)
736 maxset = 0
737 maxpgf = 0
738
739 ! hard code matrix index (no kpoints)
740 nimages = dft_control%nimages
741 cpassert(nimages == 1)
742 cindex = 1
743
744 DO ikind = 1, nkind
745 qs_kind => qs_kind_set(ikind)
746
747 CALL get_qs_kind(qs_kind=qs_kind, basis_set=orb_basis_set)
748
749 IF (.NOT. ASSOCIATED(orb_basis_set)) cycle
750
751 CALL get_gto_basis_set(gto_basis_set=orb_basis_set, npgf=npgfa, nset=nseta)
752 maxset = max(nseta, maxset)
753 maxpgf = max(maxval(npgfa), maxpgf)
754 END DO
755
756 ! *** Initialize working density matrix ***
757
758 ! distributed rs grids require a matrix that will be changed (distribute_tasks)
759 ! whereas this is not the case for replicated grids
760 ALLOCATE (deltajp_a(1), deltajp_b(1), deltajp_c(1), deltajp_d(1))
761 IF (distributed_rs_grids) THEN
762 ALLOCATE (deltajp_a(1)%matrix, deltajp_b(1)%matrix, deltajp_c(1)%matrix)
763 IF (do_igaim) THEN
764 ALLOCATE (deltajp_d(1)%matrix)
765 END IF
766
767 CALL dbcsr_create(deltajp_a(1)%matrix, template=mat_a, name='deltajp_a')
768 CALL dbcsr_create(deltajp_b(1)%matrix, template=mat_a, name='deltajp_b')
769 CALL dbcsr_create(deltajp_c(1)%matrix, template=mat_a, name='deltajp_c')
770 IF (do_igaim) CALL dbcsr_create(deltajp_d(1)%matrix, template=mat_a, name='deltajp_d')
771 ELSE
772 deltajp_a(1)%matrix => mat_a !mat_jp
773 deltajp_b(1)%matrix => mat_b !mat_jp_rii
774 deltajp_c(1)%matrix => mat_c !mat_jp_riii
775 IF (do_igaim) deltajp_d(1)%matrix => mat_d !mat_d0
776 END IF
777
778 ALLOCATE (basis_set_list(nkind))
779 DO ikind = 1, nkind
780 qs_kind => qs_kind_set(ikind)
781 CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set_a, basis_type=basis_type)
782 IF (ASSOCIATED(basis_set_a)) THEN
783 basis_set_list(ikind)%gto_basis_set => basis_set_a
784 ELSE
785 NULLIFY (basis_set_list(ikind)%gto_basis_set)
786 END IF
787 END DO
788 CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
789 DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
790 CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, iatom=iatom, jatom=jatom, r=rab)
791 basis_set_a => basis_set_list(ikind)%gto_basis_set
792 IF (.NOT. ASSOCIATED(basis_set_a)) cycle
793 basis_set_b => basis_set_list(jkind)%gto_basis_set
794 IF (.NOT. ASSOCIATED(basis_set_b)) cycle
795 ra(:) = pbc(particle_set(iatom)%r, cell)
796 ! basis ikind
797 first_sgfa => basis_set_a%first_sgf
798 la_max => basis_set_a%lmax
799 la_min => basis_set_a%lmin
800 npgfa => basis_set_a%npgf
801 nseta = basis_set_a%nset
802 nsgfa => basis_set_a%nsgf_set
803 rpgfa => basis_set_a%pgf_radius
804 set_radius_a => basis_set_a%set_radius
805 kind_radius_a = basis_set_a%kind_radius
806 sphi_a => basis_set_a%sphi
807 zeta => basis_set_a%zet
808 ! basis jkind
809 first_sgfb => basis_set_b%first_sgf
810 lb_max => basis_set_b%lmax
811 lb_min => basis_set_b%lmin
812 npgfb => basis_set_b%npgf
813 nsetb = basis_set_b%nset
814 nsgfb => basis_set_b%nsgf_set
815 rpgfb => basis_set_b%pgf_radius
816 set_radius_b => basis_set_b%set_radius
817 kind_radius_b = basis_set_b%kind_radius
818 sphi_b => basis_set_b%sphi
819 zetb => basis_set_b%zet
820
821 IF (abs(rab(1)) > lxo2 .OR. abs(rab(2)) > lyo2 .OR. abs(rab(3)) > lzo2) THEN
822 cycle
823 END IF
824
825 brow = iatom
826 bcol = jatom
827
828 CALL dbcsr_get_block_p(matrix=mat_a, row=brow, col=bcol, &
829 block=jp_block_a, found=den_found_a)
830 CALL dbcsr_get_block_p(matrix=mat_b, row=brow, col=bcol, &
831 block=jp_block_b, found=den_found)
832 CALL dbcsr_get_block_p(matrix=mat_c, row=brow, col=bcol, &
833 block=jp_block_c, found=den_found)
834 IF (do_igaim) CALL dbcsr_get_block_p(matrix=mat_d, row=brow, col=bcol, &
835 block=jp_block_d, found=den_found)
836
837 IF (.NOT. ASSOCIATED(jp_block_a)) cycle
838
839 IF (distributed_rs_grids) THEN
840 CALL dbcsr_put_block(deltajp_a(1)%matrix, brow, bcol, jp_block_a)
841 CALL dbcsr_put_block(deltajp_b(1)%matrix, brow, bcol, jp_block_b)
842 CALL dbcsr_put_block(deltajp_c(1)%matrix, brow, bcol, jp_block_c)
843 IF (do_igaim) THEN
844 CALL dbcsr_put_block(deltajp_d(1)%matrix, brow, bcol, jp_block_d)
845 END IF
846 END IF
847
848 CALL task_list_inner_loop(tasks, ntasks, curr_tasks, rs_descs, &
849 dft_control, cube_info, gridlevel_info, cindex, &
850 iatom, jatom, rpgfa, rpgfb, zeta, zetb, kind_radius_b, &
851 set_radius_a, set_radius_b, ra, rab, &
852 la_max, la_min, lb_max, lb_min, npgfa, npgfb, nseta, nsetb)
853
854 END DO
855 CALL neighbor_list_iterator_release(nl_iterator)
856
857 DEALLOCATE (basis_set_list)
858
859 IF (distributed_rs_grids) THEN
860 CALL dbcsr_finalize(deltajp_a(1)%matrix)
861 CALL dbcsr_finalize(deltajp_b(1)%matrix)
862 CALL dbcsr_finalize(deltajp_c(1)%matrix)
863 IF (do_igaim) CALL dbcsr_finalize(deltajp_d(1)%matrix)
864 END IF
865
866 ! sorts / redistributes the task list
867 CALL distribute_tasks(rs_descs=rs_descs, ntasks=ntasks, natoms=natom, tasks=tasks, &
868 atom_pair_send=atom_pair_send, atom_pair_recv=atom_pair_recv, &
869 symmetric=.false., reorder_rs_grid_ranks=.true., &
870 skip_load_balance_distributed=.false.)
871
872 ALLOCATE (rs_current(gridlevel_info%ngrid_levels))
873
874 DO igrid_level = 1, gridlevel_info%ngrid_levels
875 ! Here we need to reallocate the distributed rs_grids, which may have been reordered
876 ! by distribute_tasks
877 IF (rs_descs(igrid_level)%rs_desc%distributed .AND. .NOT. my_retain_rsgrid) THEN
878 CALL rs_grid_release(rs_rho(igrid_level))
879 CALL rs_grid_create(rs_rho(igrid_level), rs_descs(igrid_level)%rs_desc)
880 END IF
881 CALL rs_grid_zero(rs_rho(igrid_level))
882 CALL rs_grid_create(rs_current(igrid_level), rs_descs(igrid_level)%rs_desc)
883 CALL rs_grid_zero(rs_current(igrid_level))
884 END DO
885
886 !
887 ! we need to build the gauge here
888 IF (.NOT. current_env%gauge_init .AND. do_igaim) THEN
889 CALL current_set_gauge(current_env, qs_env)
890 current_env%gauge_init = .true.
891 END IF
892 !
893 ! for any case double check the bounds !
894 IF (do_igaim) THEN
895 DO igrid_level = 1, gridlevel_info%ngrid_levels
896 my_rho => rs_rho(igrid_level)%r
897 my_current => rs_current(igrid_level)%r
898 IF (lbound(my_rho, 3) /= lbound(my_current, 3) .OR. &
899 lbound(my_rho, 2) /= lbound(my_current, 2) .OR. &
900 lbound(my_rho, 1) /= lbound(my_current, 1) .OR. &
901 ubound(my_rho, 3) /= ubound(my_current, 3) .OR. &
902 ubound(my_rho, 2) /= ubound(my_current, 2) .OR. &
903 ubound(my_rho, 1) /= ubound(my_current, 1)) THEN
904 WRITE (*, *) 'LBOUND(my_rho,3),LBOUND(my_current,3)', lbound(my_rho, 3), lbound(my_current, 3)
905 WRITE (*, *) 'LBOUND(my_rho,2),LBOUND(my_current,2)', lbound(my_rho, 2), lbound(my_current, 2)
906 WRITE (*, *) 'LBOUND(my_rho,1),LBOUND(my_current,1)', lbound(my_rho, 1), lbound(my_current, 1)
907 WRITE (*, *) 'UBOUND(my_rho,3),UBOUND(my_current,3)', ubound(my_rho, 3), ubound(my_current, 3)
908 WRITE (*, *) 'UBOUND(my_rho,2),UBOUND(my_current,2)', ubound(my_rho, 2), ubound(my_current, 2)
909 WRITE (*, *) 'UBOUND(my_rho,1),UBOUND(my_current,1)', ubound(my_rho, 1), ubound(my_current, 1)
910 cpabort("Bug")
911 END IF
912
913 my_gauge => rs_gauge(1, igrid_level)%r
914 IF (lbound(my_rho, 3) /= lbound(my_gauge, 3) .OR. &
915 lbound(my_rho, 2) /= lbound(my_gauge, 2) .OR. &
916 lbound(my_rho, 1) /= lbound(my_gauge, 1) .OR. &
917 ubound(my_rho, 3) /= ubound(my_gauge, 3) .OR. &
918 ubound(my_rho, 2) /= ubound(my_gauge, 2) .OR. &
919 ubound(my_rho, 1) /= ubound(my_gauge, 1)) THEN
920 WRITE (*, *) 'LBOUND(my_rho,3),LBOUND(my_gauge,3)', lbound(my_rho, 3), lbound(my_gauge, 3)
921 WRITE (*, *) 'LBOUND(my_rho,2),LBOUND(my_gauge,2)', lbound(my_rho, 2), lbound(my_gauge, 2)
922 WRITE (*, *) 'LBOUND(my_rho,1),LBOUND(my_gauge,1)', lbound(my_rho, 1), lbound(my_gauge, 1)
923 WRITE (*, *) 'UBOUND(my_rho,3),UbOUND(my_gauge,3)', ubound(my_rho, 3), ubound(my_gauge, 3)
924 WRITE (*, *) 'UBOUND(my_rho,2),UBOUND(my_gauge,2)', ubound(my_rho, 2), ubound(my_gauge, 2)
925 WRITE (*, *) 'UBOUND(my_rho,1),UBOUND(my_gauge,1)', ubound(my_rho, 1), ubound(my_gauge, 1)
926 cpabort("Bug")
927 END IF
928 END DO
929 END IF
930 !
931 !-------------------------------------------------------------
932
933 IF (distributed_rs_grids) THEN
934 CALL rs_distribute_matrix(rs_descs=rs_descs, pmats=deltajp_a, &
935 atom_pair_send=atom_pair_send, atom_pair_recv=atom_pair_recv, &
936 nimages=nimages, scatter=.true.)
937 CALL rs_distribute_matrix(rs_descs=rs_descs, pmats=deltajp_b, &
938 atom_pair_send=atom_pair_send, atom_pair_recv=atom_pair_recv, &
939 nimages=nimages, scatter=.true.)
940 CALL rs_distribute_matrix(rs_descs=rs_descs, pmats=deltajp_c, &
941 atom_pair_send=atom_pair_send, atom_pair_recv=atom_pair_recv, &
942 nimages=nimages, scatter=.true.)
943 IF (do_igaim) CALL rs_distribute_matrix(rs_descs=rs_descs, pmats=deltajp_d, &
944 atom_pair_send=atom_pair_send, atom_pair_recv=atom_pair_recv, &
945 nimages=nimages, scatter=.true.)
946 END IF
947
948 ithread = 0
949 jpab_a => jpabt_a(:, :, ithread)
950 jpab_b => jpabt_b(:, :, ithread)
951 jpab_c => jpabt_c(:, :, ithread)
952 IF (do_igaim) jpab_d => jpabt_d(:, :, ithread)
953 work => workt(:, :, ithread)
954
955 iatom_old = -1; jatom_old = -1; iset_old = -1; jset_old = -1
956 ikind_old = -1; jkind_old = -1
957
958 loop_tasks: DO itask = 1, ntasks
959 igrid_level = tasks(itask)%grid_level
960 cindex = tasks(itask)%image
961 iatom = tasks(itask)%iatom
962 jatom = tasks(itask)%jatom
963 iset = tasks(itask)%iset
964 jset = tasks(itask)%jset
965 ipgf = tasks(itask)%ipgf
966 jpgf = tasks(itask)%jpgf
967
968 ! apparently generalised collocation not implemented correctly yet
969 cpassert(tasks(itask)%dist_type /= 2)
970
971 IF (iatom /= iatom_old .OR. jatom /= jatom_old) THEN
972
973 ikind = particle_set(iatom)%atomic_kind%kind_number
974 jkind = particle_set(jatom)%atomic_kind%kind_number
975
976 IF (iatom /= iatom_old) ra(:) = pbc(particle_set(iatom)%r, cell)
977
978 brow = iatom
979 bcol = jatom
980
981 IF (ikind /= ikind_old) THEN
982 CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, &
983 basis_type=basis_type)
984
985 CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
986 first_sgf=first_sgfa, &
987 lmax=la_max, &
988 lmin=la_min, &
989 npgf=npgfa, &
990 nset=nseta, &
991 nsgf_set=nsgfa, &
992 pgf_radius=rpgfa, &
993 set_radius=set_radius_a, &
994 sphi=sphi_a, &
995 zet=zeta)
996 END IF
997
998 IF (jkind /= jkind_old) THEN
999
1000 CALL get_qs_kind(qs_kind_set(jkind), &
1001 basis_set=orb_basis_set, basis_type=basis_type)
1002
1003 CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
1004 first_sgf=first_sgfb, &
1005 kind_radius=kind_radius_b, &
1006 lmax=lb_max, &
1007 lmin=lb_min, &
1008 npgf=npgfb, &
1009 nset=nsetb, &
1010 nsgf_set=nsgfb, &
1011 pgf_radius=rpgfb, &
1012 set_radius=set_radius_b, &
1013 sphi=sphi_b, &
1014 zet=zetb)
1015
1016 END IF
1017
1018 CALL dbcsr_get_block_p(matrix=deltajp_a(1)%matrix, row=brow, col=bcol, &
1019 block=jp_block_a, found=den_found)
1020 CALL dbcsr_get_block_p(matrix=deltajp_b(1)%matrix, row=brow, col=bcol, &
1021 block=jp_block_b, found=den_found)
1022 CALL dbcsr_get_block_p(matrix=deltajp_c(1)%matrix, row=brow, col=bcol, &
1023 block=jp_block_c, found=den_found)
1024 IF (do_igaim) CALL dbcsr_get_block_p(matrix=deltajp_d(1)%matrix, row=brow, col=bcol, &
1025 block=jp_block_d, found=den_found)
1026
1027 IF (.NOT. ASSOCIATED(jp_block_a)) THEN
1028 cpabort("p_block not associated in deltap")
1029 END IF
1030
1031 iatom_old = iatom
1032 jatom_old = jatom
1033 ikind_old = ikind
1034 jkind_old = jkind
1035
1036 atom_pair_changed = .true.
1037
1038 ELSE
1039
1040 atom_pair_changed = .false.
1041
1042 END IF
1043
1044 IF (atom_pair_changed .OR. iset_old /= iset .OR. jset_old /= jset) THEN
1045
1046 ncoa = npgfa(iset)*ncoset(la_max(iset))
1047 sgfa = first_sgfa(1, iset)
1048 ncob = npgfb(jset)*ncoset(lb_max(jset))
1049 sgfb = first_sgfb(1, jset)
1050 ! Decontraction step for the selected blocks of the 3 density matrices
1051
1052 CALL dgemm("N", "N", ncoa, nsgfb(jset), nsgfa(iset), &
1053 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
1054 jp_block_a(sgfa, sgfb), SIZE(jp_block_a, 1), &
1055 0.0_dp, work(1, 1), maxco)
1056 CALL dgemm("N", "T", ncoa, ncob, nsgfb(jset), &
1057 1.0_dp, work(1, 1), maxco, &
1058 sphi_b(1, sgfb), SIZE(sphi_b, 1), &
1059 0.0_dp, jpab_a(1, 1), maxco)
1060
1061 CALL dgemm("N", "N", ncoa, nsgfb(jset), nsgfa(iset), &
1062 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
1063 jp_block_b(sgfa, sgfb), SIZE(jp_block_b, 1), &
1064 0.0_dp, work(1, 1), maxco)
1065 CALL dgemm("N", "T", ncoa, ncob, nsgfb(jset), &
1066 1.0_dp, work(1, 1), maxco, &
1067 sphi_b(1, sgfb), SIZE(sphi_b, 1), &
1068 0.0_dp, jpab_b(1, 1), maxco)
1069
1070 CALL dgemm("N", "N", ncoa, nsgfb(jset), nsgfa(iset), &
1071 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
1072 jp_block_c(sgfa, sgfb), SIZE(jp_block_c, 1), &
1073 0.0_dp, work(1, 1), maxco)
1074 CALL dgemm("N", "T", ncoa, ncob, nsgfb(jset), &
1075 1.0_dp, work(1, 1), maxco, &
1076 sphi_b(1, sgfb), SIZE(sphi_b, 1), &
1077 0.0_dp, jpab_c(1, 1), maxco)
1078
1079 IF (do_igaim) THEN
1080 CALL dgemm("N", "N", ncoa, nsgfb(jset), nsgfa(iset), &
1081 1.0_dp, sphi_a(1, sgfa), SIZE(sphi_a, 1), &
1082 jp_block_d(sgfa, sgfb), SIZE(jp_block_d, 1), &
1083 0.0_dp, work(1, 1), maxco)
1084 CALL dgemm("N", "T", ncoa, ncob, nsgfb(jset), &
1085 1.0_dp, work(1, 1), maxco, &
1086 sphi_b(1, sgfb), SIZE(sphi_b, 1), &
1087 0.0_dp, jpab_d(1, 1), maxco)
1088 END IF
1089
1090 iset_old = iset
1091 jset_old = jset
1092
1093 END IF
1094
1095 SELECT CASE (idir)
1096 CASE (1)
1097 adbmdab_func = grid_func_adbmdab_x
1098 CASE (2)
1099 adbmdab_func = grid_func_adbmdab_y
1100 CASE (3)
1101 adbmdab_func = grid_func_adbmdab_z
1102 CASE DEFAULT
1103 cpabort("invalid idir")
1104 END SELECT
1105
1106 rab(:) = tasks(itask)%rab
1107 rb(:) = ra(:) + rab(:)
1108 zetp = zeta(ipgf, iset) + zetb(jpgf, jset)
1109 f = zetb(jpgf, jset)/zetp
1110 prefactor = exp(-zeta(ipgf, iset)*f*dot_product(rab, rab))
1111 rp(:) = ra(:) + f*rab(:)
1112
1113 na1 = (ipgf - 1)*ncoset(la_max(iset)) + 1
1114 na2 = ipgf*ncoset(la_max(iset))
1115 nb1 = (jpgf - 1)*ncoset(lb_max(jset)) + 1
1116 nb2 = jpgf*ncoset(lb_max(jset))
1117
1118 ! Four calls to the general collocate density, to multply the correct function
1119 ! to each density matrix
1120
1121 !
1122 ! here the decontracted mat_jp_{ab} is multiplied by
1123 ! f_{ab} = g_{a} (dg_{b}/dr)_{idir} - (dg_{a}/dr)_{idir} g_{b}
1124 scale = 1.0_dp
1125 radius = exp_radius_very_extended(la_min=la_min(iset), la_max=la_max(iset), &
1126 lb_min=lb_min(jset), lb_max=lb_max(jset), &
1127 ra=ra, rb=rb, rp=rp, zetp=zetp, eps=eps_rho_rspace, &
1128 prefactor=prefactor, cutoff=1.0_dp)
1129
1130 CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), &
1131 la_min(iset), lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
1132 ra, rab, scale, jpab_a, na1 - 1, nb1 - 1, &
1133 rs_current(igrid_level), &
1134 radius=radius, ga_gb_function=adbmdab_func)
1135 IF (do_igaim) THEN
1136 ! here the decontracted mat_jb_{ab} is multiplied by
1137 ! f_{ab} = g_{a} * g_{b} ! THIS GOES OUTSIDE THE LOOP !
1138 IF (scale2 /= 0.0_dp) THEN
1139 CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), &
1140 la_min(iset), lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
1141 ra, rab, scale2, jpab_d, na1 - 1, nb1 - 1, &
1142 rs_rho(igrid_level), &
1143 radius=radius, ga_gb_function=grid_func_ab)
1144 END IF !rm
1145 ! here the decontracted mat_jp_rii{ab} is multiplied by
1146 ! f_{ab} = g_{a} (d(r) - R_{b})_{iiB} (dg_{b}/dr)_{idir} -
1147 ! (dg_{a}/dr)_{idir} (d(r) - R_{b})_{iiB} g_{b}
1148 scale = 1.0_dp
1149 current_env%rs_buf(igrid_level)%r(:, :, :) = 0.0_dp
1150 CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), &
1151 la_min(iset), lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
1152 ra, rab, scale, jpab_b, na1 - 1, nb1 - 1, &
1153 radius=radius, &
1154 ga_gb_function=adbmdab_func, &
1155 rsgrid=current_env%rs_buf(igrid_level))
1156 CALL collocate_gauge_ortho(rsgrid=current_env%rs_buf(igrid_level), &
1157 rsbuf=rs_current(igrid_level), &
1158 rsgauge=rs_gauge(iiib, igrid_level), &
1159 cube_info=cube_info(igrid_level), radius=radius, &
1160 zeta=zeta(ipgf, iset), zetb=zetb(jpgf, jset), &
1161 ra=ra, rab=rab, ir=iiib)
1162
1163 ! here the decontracted mat_jp_riii{ab} is multiplied by
1164 ! f_{ab} = -g_{a} (d(r) - R_{b})_{iiB} (dg_{b}/dr)_{idir} +
1165 ! (dg_{a}/dr)_{idir} (d(r) - R_{b})_{iiB} g_{b}
1166 scale = -1.0_dp
1167 current_env%rs_buf(igrid_level)%r(:, :, :) = 0.0_dp
1168 CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), &
1169 la_min(iset), lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
1170 ra, rab, scale, jpab_c, na1 - 1, nb1 - 1, &
1171 radius=radius, &
1172 ga_gb_function=adbmdab_func, &
1173 rsgrid=current_env%rs_buf(igrid_level))
1174 CALL collocate_gauge_ortho(rsgrid=current_env%rs_buf(igrid_level), &
1175 rsbuf=rs_current(igrid_level), &
1176 rsgauge=rs_gauge(iib, igrid_level), &
1177 cube_info=cube_info(igrid_level), radius=radius, &
1178 zeta=zeta(ipgf, iset), zetb=zetb(jpgf, jset), &
1179 ra=ra, rab=rab, ir=iib)
1180 ELSE
1181 ! here the decontracted mat_jp_rii{ab} is multiplied by
1182 ! f_{ab} = g_{a} (r - R_{b})_{iiB} (dg_{b}/dr)_{idir} -
1183 ! (dg_{a}/dr)_{idir} (r - R_{b})_{iiB} g_{b}
1184 scale = 1.0_dp
1185 CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), &
1186 la_min(iset), lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
1187 ra, rab, scale, jpab_b, na1 - 1, nb1 - 1, &
1188 rs_current(igrid_level), &
1189 radius=radius, &
1190 ga_gb_function=encode_ardbmdarb_func(idir=idir, ir=iiib))
1191 ! here the decontracted mat_jp_riii{ab} is multiplied by
1192 ! f_{ab} = -g_{a} (r - R_{b})_{iiB} (dg_{b}/dr)_{idir} +
1193 ! (dg_{a}/dr)_{idir} (r - R_{b})_{iiB} g_{b}
1194 scale = -1.0_dp
1195 CALL collocate_pgf_product(la_max(iset), zeta(ipgf, iset), &
1196 la_min(iset), lb_max(jset), zetb(jpgf, jset), lb_min(jset), &
1197 ra, rab, scale, jpab_c, na1 - 1, nb1 - 1, &
1198 rs_current(igrid_level), &
1199 radius=radius, &
1200 ga_gb_function=encode_ardbmdarb_func(idir=idir, ir=iib))
1201 END IF
1202
1203 END DO loop_tasks
1204 !
1205 ! Scale the density with the gauge rho * ( r - d(r) ) if needed
1206 IF (do_igaim) THEN
1207 DO igrid_level = 1, gridlevel_info%ngrid_levels
1208 CALL rs_grid_mult_and_add(rs_current(igrid_level), rs_rho(igrid_level), &
1209 rs_gauge(idir2, igrid_level), 1.0_dp)
1210 END DO
1211 END IF
1212 ! *** Release work storage ***
1213
1214 IF (distributed_rs_grids) THEN
1215 CALL dbcsr_deallocate_matrix(deltajp_a(1)%matrix)
1216 CALL dbcsr_deallocate_matrix(deltajp_b(1)%matrix)
1217 CALL dbcsr_deallocate_matrix(deltajp_c(1)%matrix)
1218 IF (do_igaim) CALL dbcsr_deallocate_matrix(deltajp_d(1)%matrix)
1219 END IF
1220 DEALLOCATE (deltajp_a, deltajp_b, deltajp_c, deltajp_d)
1221
1222 DEALLOCATE (jpabt_a, jpabt_b, jpabt_c, jpabt_d, workt, tasks)
1223
1224 IF (ASSOCIATED(atom_pair_send)) DEALLOCATE (atom_pair_send)
1225 IF (ASSOCIATED(atom_pair_recv)) DEALLOCATE (atom_pair_recv)
1226
1227 CALL density_rs2pw(pw_env, rs_current, current_rs, current_gs)
1228 DO i = 1, SIZE(rs_current)
1229 CALL rs_grid_release(rs_current(i))
1230 END DO
1231
1232 DO i = 1, SIZE(rs_rho)
1233 IF (rs_descs(i)%rs_desc%distributed .AND. .NOT. my_retain_rsgrid) THEN
1234 CALL rs_grid_release(rs_rho(i))
1235 END IF
1236 END DO
1237
1238 ! Free the array of grids (grids themselves are released in density_rs2pw)
1239 DEALLOCATE (rs_current)
1240
1241 CALL timestop(handle)
1242
1243 END SUBROUTINE calculate_jrho_resp
1244
1245! **************************************************************************************************
1246!> \brief ...
1247!> \param idir ...
1248!> \param ir ...
1249!> \return ...
1250! **************************************************************************************************
1251 FUNCTION encode_ardbmdarb_func(idir, ir) RESULT(func)
1252 INTEGER, INTENT(IN) :: idir, ir
1253 INTEGER :: func
1254
1255 cpassert(1 <= idir .AND. idir <= 3 .AND. 1 <= ir .AND. ir <= 3)
1256 SELECT CASE (10*idir + ir)
1257 CASE (11)
1258 func = grid_func_ardbmdarb_xx
1259 CASE (12)
1260 func = grid_func_ardbmdarb_xy
1261 CASE (13)
1262 func = grid_func_ardbmdarb_xz
1263 CASE (21)
1264 func = grid_func_ardbmdarb_yx
1265 CASE (22)
1266 func = grid_func_ardbmdarb_yy
1267 CASE (23)
1268 func = grid_func_ardbmdarb_yz
1269 CASE (31)
1270 func = grid_func_ardbmdarb_zx
1271 CASE (32)
1272 func = grid_func_ardbmdarb_zy
1273 CASE (33)
1274 func = grid_func_ardbmdarb_zz
1275 CASE DEFAULT
1276 cpabort("invalid idir or iiiB")
1277 END SELECT
1278 END FUNCTION encode_ardbmdarb_func
1279
1280! **************************************************************************************************
1281!> \brief ...
1282!> \param rsgrid ...
1283!> \param rsbuf ...
1284!> \param rsgauge ...
1285!> \param cube_info ...
1286!> \param radius ...
1287!> \param ra ...
1288!> \param rab ...
1289!> \param zeta ...
1290!> \param zetb ...
1291!> \param ir ...
1292! **************************************************************************************************
1293 SUBROUTINE collocate_gauge_ortho(rsgrid, rsbuf, rsgauge, cube_info, radius, ra, rab, zeta, zetb, ir)
1294 TYPE(realspace_grid_type) :: rsgrid, rsbuf, rsgauge
1295 TYPE(cube_info_type), INTENT(IN) :: cube_info
1296 REAL(kind=dp), INTENT(IN) :: radius
1297 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: ra, rab
1298 REAL(kind=dp), INTENT(IN) :: zeta, zetb
1299 INTEGER, INTENT(IN) :: ir
1300
1301 INTEGER :: cmax, i, ig, igmax, igmin, j, j2, jg, &
1302 jg2, jgmin, k, k2, kg, kg2, kgmin, &
1303 length, offset, sci, start
1304 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: map
1305 INTEGER, DIMENSION(3) :: cubecenter, lb_cube, ng, ub_cube
1306 INTEGER, DIMENSION(:), POINTER :: sphere_bounds
1307 REAL(kind=dp) :: f, point(3, 4), res(4), x, y, y2, z, z2, &
1308 zetp
1309 REAL(kind=dp), DIMENSION(3) :: dr, rap, rb, rbp, roffset, rp
1310 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: gauge, grid, grid_buf
1311
1312 cpassert(rsgrid%desc%orthorhombic)
1313 NULLIFY (sphere_bounds)
1314
1315 grid => rsgrid%r(:, :, :)
1316 grid_buf => rsbuf%r(:, :, :)
1317 gauge => rsgauge%r(:, :, :)
1318
1319 ! *** center of gaussians and their product
1320 zetp = zeta + zetb
1321 f = zetb/zetp
1322 rap(:) = f*rab(:)
1323 rbp(:) = rap(:) - rab(:)
1324 rp(:) = ra(:) + rap(:)
1325 rb(:) = ra(:) + rab(:)
1326
1327 ! *** properties of the grid ***
1328 ng(:) = rsgrid%desc%npts(:)
1329 dr(1) = rsgrid%desc%dh(1, 1)
1330 dr(2) = rsgrid%desc%dh(2, 2)
1331 dr(3) = rsgrid%desc%dh(3, 3)
1332
1333 ! *** get the sub grid properties for the given radius ***
1334 CALL return_cube(cube_info, radius, lb_cube, ub_cube, sphere_bounds)
1335 cmax = maxval(ub_cube)
1336
1337 ! *** position of the gaussian product
1338 !
1339 ! this is the actual definition of the position on the grid
1340 ! i.e. a point rp(:) gets here grid coordinates
1341 ! MODULO(rp(:)/dr(:),ng(:))+1
1342 ! hence (0.0,0.0,0.0) in real space is rsgrid%lb on the rsgrid ((1,1,1) on grid)
1343 !
1344 ALLOCATE (map(-cmax:cmax, 3))
1345 map(:, :) = -1
1346 CALL compute_cube_center(cubecenter, rsgrid%desc, zeta, zetb, ra, rab)
1347 roffset(:) = rp(:) - real(cubecenter(:), dp)*dr(:)
1348
1349 ! *** a mapping so that the ig corresponds to the right grid point
1350 DO i = 1, 3
1351 IF (rsgrid%desc%perd(i) == 1) THEN
1352 start = lb_cube(i)
1353 DO
1354 offset = modulo(cubecenter(i) + start, ng(i)) + 1 - start
1355 length = min(ub_cube(i), ng(i) - offset) - start
1356 DO ig = start, start + length
1357 map(ig, i) = ig + offset
1358 END DO
1359 IF (start + length >= ub_cube(i)) EXIT
1360 start = start + length + 1
1361 END DO
1362 ELSE
1363 ! this takes partial grid + border regions into account
1364 offset = modulo(cubecenter(i) + lb_cube(i) + rsgrid%desc%lb(i) - rsgrid%lb_local(i), ng(i)) + 1 - lb_cube(i)
1365 ! check for out of bounds
1366 IF (ub_cube(i) + offset > ubound(grid, i) .OR. lb_cube(i) + offset < lbound(grid, i)) THEN
1367 cpabort("Cube bound out of grid bounds")
1368 END IF
1369 DO ig = lb_cube(i), ub_cube(i)
1370 map(ig, i) = ig + offset
1371 END DO
1372 END IF
1373 END DO
1374
1375 ! *** actually loop over the grid
1376 sci = 1
1377 kgmin = sphere_bounds(sci)
1378 sci = sci + 1
1379 DO kg = kgmin, 0
1380 kg2 = 1 - kg
1381 k = map(kg, 3)
1382 k2 = map(kg2, 3)
1383 jgmin = sphere_bounds(sci)
1384 sci = sci + 1
1385 z = (real(kg, dp) + real(cubecenter(3), dp))*dr(3)
1386 z2 = (real(kg2, dp) + real(cubecenter(3), dp))*dr(3)
1387 DO jg = jgmin, 0
1388 jg2 = 1 - jg
1389 j = map(jg, 2)
1390 j2 = map(jg2, 2)
1391 igmin = sphere_bounds(sci)
1392 sci = sci + 1
1393 igmax = 1 - igmin
1394 y = (real(jg, dp) + real(cubecenter(2), dp))*dr(2)
1395 y2 = (real(jg2, dp) + real(cubecenter(2), dp))*dr(2)
1396 DO ig = igmin, igmax
1397 i = map(ig, 1)
1398 x = (real(ig, dp) + real(cubecenter(1), dp))*dr(1)
1399 point(1, 1) = x; point(2, 1) = y; point(3, 1) = z
1400 point(1, 2) = x; point(2, 2) = y2; point(3, 2) = z
1401 point(1, 3) = x; point(2, 3) = y; point(3, 3) = z2
1402 point(1, 4) = x; point(2, 4) = y2; point(3, 4) = z2
1403 !
1404 res(1) = (point(ir, 1) - rb(ir)) - gauge(i, j, k)
1405 res(2) = (point(ir, 2) - rb(ir)) - gauge(i, j2, k)
1406 res(3) = (point(ir, 3) - rb(ir)) - gauge(i, j, k2)
1407 res(4) = (point(ir, 4) - rb(ir)) - gauge(i, j2, k2)
1408 !
1409 grid_buf(i, j, k) = grid_buf(i, j, k) + grid(i, j, k)*res(1)
1410 grid_buf(i, j2, k) = grid_buf(i, j2, k) + grid(i, j2, k)*res(2)
1411 grid_buf(i, j, k2) = grid_buf(i, j, k2) + grid(i, j, k2)*res(3)
1412 grid_buf(i, j2, k2) = grid_buf(i, j2, k2) + grid(i, j2, k2)*res(4)
1413 END DO
1414 END DO
1415 END DO
1416 END SUBROUTINE collocate_gauge_ortho
1417
1418! **************************************************************************************************
1419!> \brief ...
1420!> \param current_env ...
1421!> \param qs_env ...
1422! **************************************************************************************************
1423 SUBROUTINE current_set_gauge(current_env, qs_env)
1424 !
1425 TYPE(current_env_type) :: current_env
1426 TYPE(qs_environment_type), POINTER :: qs_env
1427
1428 CHARACTER(LEN=*), PARAMETER :: routinen = 'current_set_gauge'
1429
1430 INTEGER :: idir
1431 REAL(dp) :: dbox(3)
1432 REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: box_data
1433 INTEGER :: handle, igrid_level, nbox(3), gauge
1434 INTEGER, ALLOCATABLE, DIMENSION(:, :, :) :: box_ptr
1435 TYPE(realspace_grid_desc_p_type), DIMENSION(:), &
1436 POINTER :: rs_descs
1437 TYPE(pw_env_type), POINTER :: pw_env
1438 TYPE(realspace_grid_type), DIMENSION(:, :), POINTER :: rs_gauge
1439
1440 TYPE(box_type), DIMENSION(:, :, :), POINTER :: box
1441 LOGICAL :: use_old_gauge_atom
1442
1443 NULLIFY (rs_gauge, box)
1444
1445 CALL timeset(routinen, handle)
1446
1447 CALL get_current_env(current_env=current_env, &
1448 use_old_gauge_atom=use_old_gauge_atom, &
1449 rs_gauge=rs_gauge, &
1450 gauge=gauge)
1451
1452 IF (gauge == current_gauge_atom) THEN
1453 CALL get_qs_env(qs_env=qs_env, &
1454 pw_env=pw_env)
1455 CALL pw_env_get(pw_env=pw_env, &
1456 rs_descs=rs_descs)
1457 !
1458 ! box the atoms
1459 IF (use_old_gauge_atom) THEN
1460 CALL box_atoms(qs_env)
1461 ELSE
1462 CALL box_atoms_new(current_env, qs_env, box)
1463 END IF
1464 !
1465 ! allocate and build the gauge
1466 DO igrid_level = pw_env%gridlevel_info%ngrid_levels, 1, -1
1467
1468 DO idir = 1, 3
1469 CALL rs_grid_create(rs_gauge(idir, igrid_level), rs_descs(igrid_level)%rs_desc)
1470 END DO
1471
1472 IF (use_old_gauge_atom) THEN
1473 CALL collocate_gauge(current_env, qs_env, &
1474 rs_gauge(1, igrid_level), &
1475 rs_gauge(2, igrid_level), &
1476 rs_gauge(3, igrid_level))
1477 ELSE
1478 CALL collocate_gauge_new(current_env, qs_env, &
1479 rs_gauge(1, igrid_level), &
1480 rs_gauge(2, igrid_level), &
1481 rs_gauge(3, igrid_level), &
1482 box)
1483 END IF
1484 END DO
1485 !
1486 ! allocate the buf
1487 ALLOCATE (current_env%rs_buf(pw_env%gridlevel_info%ngrid_levels))
1488 DO igrid_level = 1, pw_env%gridlevel_info%ngrid_levels
1489 CALL rs_grid_create(current_env%rs_buf(igrid_level), rs_descs(igrid_level)%rs_desc)
1490 END DO
1491 !
1492 DEALLOCATE (box_ptr, box_data)
1493 CALL deallocate_box(box)
1494 END IF
1495
1496 CALL timestop(handle)
1497
1498 CONTAINS
1499
1500! **************************************************************************************************
1501!> \brief ...
1502!> \param qs_env ...
1503! **************************************************************************************************
1504 SUBROUTINE box_atoms(qs_env)
1505 TYPE(qs_environment_type), POINTER :: qs_env
1506
1507 REAL(kind=dp), PARAMETER :: box_size_guess = 5.0_dp
1508
1509 INTEGER :: i, iatom, ibox, ii, jbox, kbox, natms
1510 REAL(dp) :: offset(3)
1511 REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: ratom
1512 TYPE(cell_type), POINTER :: cell
1513 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1514 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1515
1516 CALL get_qs_env(qs_env=qs_env, &
1517 qs_kind_set=qs_kind_set, &
1518 cell=cell, &
1519 particle_set=particle_set)
1520
1521 natms = SIZE(particle_set, 1)
1522 ALLOCATE (ratom(3, natms))
1523 !
1524 ! box the atoms
1525 nbox(1) = ceiling(cell%hmat(1, 1)/box_size_guess)
1526 nbox(2) = ceiling(cell%hmat(2, 2)/box_size_guess)
1527 nbox(3) = ceiling(cell%hmat(3, 3)/box_size_guess)
1528 !write(*,*) 'nbox',nbox
1529 dbox(1) = cell%hmat(1, 1)/real(nbox(1), dp)
1530 dbox(2) = cell%hmat(2, 2)/real(nbox(2), dp)
1531 dbox(3) = cell%hmat(3, 3)/real(nbox(3), dp)
1532 !write(*,*) 'dbox',dbox
1533 ALLOCATE (box_ptr(0:nbox(1), 0:nbox(2) - 1, 0:nbox(3) - 1), box_data(3, natms))
1534 box_data(:, :) = huge(0.0_dp)
1535 box_ptr(:, :, :) = huge(0)
1536 !
1537 offset(1) = cell%hmat(1, 1)*0.5_dp
1538 offset(2) = cell%hmat(2, 2)*0.5_dp
1539 offset(3) = cell%hmat(3, 3)*0.5_dp
1540 DO iatom = 1, natms
1541 ratom(:, iatom) = pbc(particle_set(iatom)%r(:), cell) + offset(:)
1542 END DO
1543 !
1544 i = 1
1545 DO kbox = 0, nbox(3) - 1
1546 DO jbox = 0, nbox(2) - 1
1547 box_ptr(0, jbox, kbox) = i
1548 DO ibox = 0, nbox(1) - 1
1549 ii = 0
1550 DO iatom = 1, natms
1551 IF (int(ratom(1, iatom)/dbox(1)) == ibox .AND. &
1552 int(ratom(2, iatom)/dbox(2)) == jbox .AND. &
1553 int(ratom(3, iatom)/dbox(3)) == kbox) THEN
1554 box_data(:, i) = ratom(:, iatom) - offset(:)
1555 i = i + 1
1556 ii = ii + 1
1557 END IF
1558 END DO
1559 box_ptr(ibox + 1, jbox, kbox) = box_ptr(ibox, jbox, kbox) + ii
1560 END DO
1561 END DO
1562 END DO
1563 !
1564 IF (.false.) THEN
1565 DO kbox = 0, nbox(3) - 1
1566 DO jbox = 0, nbox(2) - 1
1567 DO ibox = 0, nbox(1) - 1
1568 WRITE (*, *) 'box=', ibox, jbox, kbox
1569 WRITE (*, *) 'nbr atom=', box_ptr(ibox + 1, jbox, kbox) - box_ptr(ibox, jbox, kbox)
1570 DO iatom = box_ptr(ibox, jbox, kbox), box_ptr(ibox + 1, jbox, kbox) - 1
1571 WRITE (*, *) 'iatom=', iatom
1572 WRITE (*, '(A,3E14.6)') 'coor=', box_data(:, iatom)
1573 END DO
1574 END DO
1575 END DO
1576 END DO
1577 END IF
1578 DEALLOCATE (ratom)
1579 END SUBROUTINE box_atoms
1580
1581! **************************************************************************************************
1582!> \brief ...
1583!> \param current_env ...
1584!> \param qs_env ...
1585!> \param rs_grid_x ...
1586!> \param rs_grid_y ...
1587!> \param rs_grid_z ...
1588! **************************************************************************************************
1589 SUBROUTINE collocate_gauge(current_env, qs_env, rs_grid_x, rs_grid_y, rs_grid_z)
1590 !
1591 TYPE(current_env_type) :: current_env
1592 TYPE(qs_environment_type), POINTER :: qs_env
1593 TYPE(realspace_grid_type), INTENT(IN) :: rs_grid_x, rs_grid_y, rs_grid_z
1594
1595 INTEGER :: i, iatom, ibeg, ibox, iend, imax, imin, &
1596 j, jatom, jbox, jmax, jmin, k, kbox, &
1597 kmax, kmin, lb(3), lb_local(3), natms, &
1598 natms_local, ng(3)
1599 REAL(kind=dp) :: ab, buf_tmp, dist, dr(3), &
1600 gauge_atom_radius, offset(3), pa, pb, &
1601 point(3), pra(3), r(3), res(3), summe, &
1602 tmp, x, y, z
1603 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: buf, nrm_atms_pnt
1604 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: atms_pnt, ratom
1605 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: grid_x, grid_y, grid_z
1606 TYPE(cell_type), POINTER :: cell
1607 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1608 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1609
1610!
1611
1612 CALL get_current_env(current_env=current_env, &
1613 gauge_atom_radius=gauge_atom_radius)
1614 !
1615 CALL get_qs_env(qs_env=qs_env, &
1616 qs_kind_set=qs_kind_set, &
1617 cell=cell, &
1618 particle_set=particle_set)
1619 !
1620 natms = SIZE(particle_set, 1)
1621 dr(1) = rs_grid_x%desc%dh(1, 1)
1622 dr(2) = rs_grid_x%desc%dh(2, 2)
1623 dr(3) = rs_grid_x%desc%dh(3, 3)
1624 lb(:) = rs_grid_x%desc%lb(:)
1625 lb_local(:) = rs_grid_x%lb_local(:)
1626 grid_x => rs_grid_x%r(:, :, :)
1627 grid_y => rs_grid_y%r(:, :, :)
1628 grid_z => rs_grid_z%r(:, :, :)
1629 ng(:) = ubound(grid_x)
1630 offset(1) = cell%hmat(1, 1)*0.5_dp
1631 offset(2) = cell%hmat(2, 2)*0.5_dp
1632 offset(3) = cell%hmat(3, 3)*0.5_dp
1633 ALLOCATE (buf(natms), ratom(3, natms), atms_pnt(3, natms), nrm_atms_pnt(natms))
1634 !
1635 ! go over the grid
1636 DO k = 1, ng(3)
1637 DO j = 1, ng(2)
1638 DO i = 1, ng(1)
1639 !
1640 point(3) = real(k - 1 + lb_local(3) - lb(3), dp)*dr(3)
1641 point(2) = real(j - 1 + lb_local(2) - lb(2), dp)*dr(2)
1642 point(1) = real(i - 1 + lb_local(1) - lb(1), dp)*dr(1)
1643 point = pbc(point, cell)
1644 !
1645 ! run over the overlaping boxes
1646 natms_local = 0
1647 kmin = int((point(3) + offset(3) - gauge_atom_radius)/dbox(3))
1648 kmax = int((point(3) + offset(3) + gauge_atom_radius)/dbox(3))
1649 IF (kmax - kmin + 1 > nbox(3)) THEN
1650 kmin = 0
1651 kmax = nbox(3) - 1
1652 END IF
1653 DO kbox = kmin, kmax
1654 jmin = int((point(2) + offset(2) - gauge_atom_radius)/dbox(2))
1655 jmax = int((point(2) + offset(2) + gauge_atom_radius)/dbox(2))
1656 IF (jmax - jmin + 1 > nbox(2)) THEN
1657 jmin = 0
1658 jmax = nbox(2) - 1
1659 END IF
1660 DO jbox = jmin, jmax
1661 imin = int((point(1) + offset(1) - gauge_atom_radius)/dbox(1))
1662 imax = int((point(1) + offset(1) + gauge_atom_radius)/dbox(1))
1663 IF (imax - imin + 1 > nbox(1)) THEN
1664 imin = 0
1665 imax = nbox(1) - 1
1666 END IF
1667 DO ibox = imin, imax
1668 ibeg = box_ptr(modulo(ibox, nbox(1)), modulo(jbox, nbox(2)), modulo(kbox, nbox(3)))
1669 iend = box_ptr(modulo(ibox, nbox(1)) + 1, modulo(jbox, nbox(2)), modulo(kbox, nbox(3))) - 1
1670 DO iatom = ibeg, iend
1671 r(:) = pbc(box_data(:, iatom) - point(:), cell) + point(:)
1672 dist = (r(1) - point(1))**2 + (r(2) - point(2))**2 + (r(3) - point(3))**2
1673 IF (dist < gauge_atom_radius**2) THEN
1674 natms_local = natms_local + 1
1675 ratom(:, natms_local) = r(:)
1676 !
1677 ! compute the distance atoms-point
1678 x = point(1) - r(1)
1679 y = point(2) - r(2)
1680 z = point(3) - r(3)
1681 atms_pnt(1, natms_local) = x
1682 atms_pnt(2, natms_local) = y
1683 atms_pnt(3, natms_local) = z
1684 nrm_atms_pnt(natms_local) = sqrt(x*x + y*y + z*z)
1685 END IF
1686 END DO
1687 END DO
1688 END DO
1689 END DO
1690 !
1691 IF (natms_local > 0) THEN
1692 !
1693 !
1694 DO iatom = 1, natms_local
1695 buf_tmp = 1.0_dp
1696 pra(1) = atms_pnt(1, iatom)
1697 pra(2) = atms_pnt(2, iatom)
1698 pra(3) = atms_pnt(3, iatom)
1699 pa = nrm_atms_pnt(iatom)
1700 DO jatom = 1, natms_local
1701 IF (iatom == jatom) cycle
1702 pb = nrm_atms_pnt(jatom)
1703 x = pra(1) - atms_pnt(1, jatom)
1704 y = pra(2) - atms_pnt(2, jatom)
1705 z = pra(3) - atms_pnt(3, jatom)
1706 ab = sqrt(x*x + y*y + z*z)
1707 !
1708 tmp = (pa - pb)/ab
1709 tmp = 0.5_dp*(3.0_dp - tmp*tmp)*tmp
1710 tmp = 0.5_dp*(3.0_dp - tmp*tmp)*tmp
1711 tmp = 0.5_dp*(3.0_dp - tmp*tmp)*tmp
1712 buf_tmp = buf_tmp*0.5_dp*(1.0_dp - tmp)
1713 END DO
1714 buf(iatom) = buf_tmp
1715 END DO
1716 res(1) = 0.0_dp
1717 res(2) = 0.0_dp
1718 res(3) = 0.0_dp
1719 summe = 0.0_dp
1720 DO iatom = 1, natms_local
1721 res(1) = res(1) + ratom(1, iatom)*buf(iatom)
1722 res(2) = res(2) + ratom(2, iatom)*buf(iatom)
1723 res(3) = res(3) + ratom(3, iatom)*buf(iatom)
1724 summe = summe + buf(iatom)
1725 END DO
1726 res(1) = res(1)/summe
1727 res(2) = res(2)/summe
1728 res(3) = res(3)/summe
1729 grid_x(i, j, k) = point(1) - res(1)
1730 grid_y(i, j, k) = point(2) - res(2)
1731 grid_z(i, j, k) = point(3) - res(3)
1732 ELSE
1733 grid_x(i, j, k) = 0.0_dp
1734 grid_y(i, j, k) = 0.0_dp
1735 grid_z(i, j, k) = 0.0_dp
1736 END IF
1737 END DO
1738 END DO
1739 END DO
1740
1741 DEALLOCATE (buf, ratom, atms_pnt, nrm_atms_pnt)
1742
1743 END SUBROUTINE collocate_gauge
1744
1745! **************************************************************************************************
1746!> \brief ...
1747!> \param current_env ...
1748!> \param qs_env ...
1749!> \param box ...
1750! **************************************************************************************************
1751 SUBROUTINE box_atoms_new(current_env, qs_env, box)
1752 TYPE(current_env_type) :: current_env
1753 TYPE(qs_environment_type), POINTER :: qs_env
1754 TYPE(box_type), DIMENSION(:, :, :), POINTER :: box
1755
1756 CHARACTER(LEN=*), PARAMETER :: routinen = 'box_atoms_new'
1757
1758 INTEGER :: handle, i, iatom, ibeg, ibox, iend, &
1759 ifind, ii, imax, imin, j, jatom, jbox, &
1760 jmax, jmin, k, kbox, kmax, kmin, &
1761 natms, natms_local
1762 REAL(dp) :: gauge_atom_radius, offset(3), scale
1763 REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: ratom
1764 REAL(dp), DIMENSION(:, :), POINTER :: r_ptr
1765 REAL(kind=dp) :: box_center(3), box_center_wrap(3), &
1766 box_size_guess, r(3)
1767 TYPE(cell_type), POINTER :: cell
1768 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1769 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1770
1771 CALL timeset(routinen, handle)
1772
1773 CALL get_qs_env(qs_env=qs_env, &
1774 qs_kind_set=qs_kind_set, &
1775 cell=cell, &
1776 particle_set=particle_set)
1777
1778 CALL get_current_env(current_env=current_env, &
1779 gauge_atom_radius=gauge_atom_radius)
1780
1781 scale = 2.0_dp
1782
1783 box_size_guess = gauge_atom_radius/scale
1784
1785 natms = SIZE(particle_set, 1)
1786 ALLOCATE (ratom(3, natms))
1787
1788 !
1789 ! box the atoms
1790 nbox(1) = ceiling(cell%hmat(1, 1)/box_size_guess)
1791 nbox(2) = ceiling(cell%hmat(2, 2)/box_size_guess)
1792 nbox(3) = ceiling(cell%hmat(3, 3)/box_size_guess)
1793 dbox(1) = cell%hmat(1, 1)/real(nbox(1), dp)
1794 dbox(2) = cell%hmat(2, 2)/real(nbox(2), dp)
1795 dbox(3) = cell%hmat(3, 3)/real(nbox(3), dp)
1796 ALLOCATE (box_ptr(0:nbox(1), 0:nbox(2) - 1, 0:nbox(3) - 1), box_data(3, natms))
1797 box_data(:, :) = huge(0.0_dp)
1798 box_ptr(:, :, :) = huge(0)
1799 !
1800 offset(1) = cell%hmat(1, 1)*0.5_dp
1801 offset(2) = cell%hmat(2, 2)*0.5_dp
1802 offset(3) = cell%hmat(3, 3)*0.5_dp
1803 DO iatom = 1, natms
1804 ratom(:, iatom) = pbc(particle_set(iatom)%r(:), cell)
1805 END DO
1806 !
1807 i = 1
1808 DO kbox = 0, nbox(3) - 1
1809 DO jbox = 0, nbox(2) - 1
1810 box_ptr(0, jbox, kbox) = i
1811 DO ibox = 0, nbox(1) - 1
1812 ii = 0
1813 DO iatom = 1, natms
1814 IF (modulo(floor(ratom(1, iatom)/dbox(1)), nbox(1)) == ibox .AND. &
1815 modulo(floor(ratom(2, iatom)/dbox(2)), nbox(2)) == jbox .AND. &
1816 modulo(floor(ratom(3, iatom)/dbox(3)), nbox(3)) == kbox) THEN
1817 box_data(:, i) = ratom(:, iatom)
1818 i = i + 1
1819 ii = ii + 1
1820 END IF
1821 END DO
1822 box_ptr(ibox + 1, jbox, kbox) = box_ptr(ibox, jbox, kbox) + ii
1823 END DO
1824 END DO
1825 END DO
1826 !
1827 IF (.false.) THEN
1828 DO kbox = 0, nbox(3) - 1
1829 DO jbox = 0, nbox(2) - 1
1830 DO ibox = 0, nbox(1) - 1
1831 IF (box_ptr(ibox + 1, jbox, kbox) - box_ptr(ibox, jbox, kbox) > 0) THEN
1832 WRITE (*, *) 'box=', ibox, jbox, kbox
1833 WRITE (*, *) 'nbr atom=', box_ptr(ibox + 1, jbox, kbox) - box_ptr(ibox, jbox, kbox)
1834 DO iatom = box_ptr(ibox, jbox, kbox), box_ptr(ibox + 1, jbox, kbox) - 1
1835 WRITE (*, '(A,I3,3E14.6)') 'coor=', iatom, box_data(:, iatom)
1836 END DO
1837 END IF
1838 END DO
1839 END DO
1840 END DO
1841 END IF
1842 !
1843 NULLIFY (box)
1844 ALLOCATE (box(0:nbox(1) - 1, 0:nbox(2) - 1, 0:nbox(3) - 1))
1845 !
1846 ! build the list
1847 DO k = 0, nbox(3) - 1
1848 DO j = 0, nbox(2) - 1
1849 DO i = 0, nbox(1) - 1
1850 !
1851 box_center(1) = (real(i, dp) + 0.5_dp)*dbox(1)
1852 box_center(2) = (real(j, dp) + 0.5_dp)*dbox(2)
1853 box_center(3) = (real(k, dp) + 0.5_dp)*dbox(3)
1854 box_center_wrap = pbc(box_center, cell)
1855 !
1856 ! find the atoms that are in the overlaping boxes
1857 natms_local = 0
1858 kmin = floor((box_center(3) - gauge_atom_radius)/dbox(3))
1859 kmax = floor((box_center(3) + gauge_atom_radius)/dbox(3))
1860 IF (kmax - kmin + 1 > nbox(3)) THEN
1861 kmin = 0
1862 kmax = nbox(3) - 1
1863 END IF
1864 DO kbox = kmin, kmax
1865 jmin = floor((box_center(2) - gauge_atom_radius)/dbox(2))
1866 jmax = floor((box_center(2) + gauge_atom_radius)/dbox(2))
1867 IF (jmax - jmin + 1 > nbox(2)) THEN
1868 jmin = 0
1869 jmax = nbox(2) - 1
1870 END IF
1871 DO jbox = jmin, jmax
1872 imin = floor((box_center(1) - gauge_atom_radius)/dbox(1))
1873 imax = floor((box_center(1) + gauge_atom_radius)/dbox(1))
1874 IF (imax - imin + 1 > nbox(1)) THEN
1875 imin = 0
1876 imax = nbox(1) - 1
1877 END IF
1878 DO ibox = imin, imax
1879 ibeg = box_ptr(modulo(ibox, nbox(1)), modulo(jbox, nbox(2)), modulo(kbox, nbox(3)))
1880 iend = box_ptr(modulo(ibox, nbox(1)) + 1, modulo(jbox, nbox(2)), modulo(kbox, nbox(3))) - 1
1881 DO iatom = ibeg, iend
1882 r = pbc(box_center_wrap(:) - box_data(:, iatom), cell)
1883 IF (abs(r(1)) <= (scale + 0.5_dp)*dbox(1) .AND. &
1884 abs(r(2)) <= (scale + 0.5_dp)*dbox(2) .AND. &
1885 abs(r(3)) <= (scale + 0.5_dp)*dbox(3)) THEN
1886 natms_local = natms_local + 1
1887 ratom(:, natms_local) = box_data(:, iatom)
1888 END IF
1889 END DO
1890 END DO ! box
1891 END DO
1892 END DO
1893 !
1894 ! set the list
1895 box(i, j, k)%n = natms_local
1896 NULLIFY (box(i, j, k)%r)
1897 IF (natms_local > 0) THEN
1898 ALLOCATE (box(i, j, k)%r(3, natms_local))
1899 r_ptr => box(i, j, k)%r
1900 CALL dcopy(3*natms_local, ratom(1, 1), 1, r_ptr(1, 1), 1)
1901 END IF
1902 END DO ! list
1903 END DO
1904 END DO
1905
1906 IF (.false.) THEN
1907 DO k = 0, nbox(3) - 1
1908 DO j = 0, nbox(2) - 1
1909 DO i = 0, nbox(1) - 1
1910 IF (box(i, j, k)%n > 0) THEN
1911 WRITE (*, *)
1912 WRITE (*, *) 'box=', i, j, k
1913 box_center(1) = (real(i, dp) + 0.5_dp)*dbox(1)
1914 box_center(2) = (real(j, dp) + 0.5_dp)*dbox(2)
1915 box_center(3) = (real(k, dp) + 0.5_dp)*dbox(3)
1916 box_center = pbc(box_center, cell)
1917 WRITE (*, '(A,3E14.6)') 'box_center=', box_center
1918 WRITE (*, *) 'nbr atom=', box(i, j, k)%n
1919 r_ptr => box(i, j, k)%r
1920 DO iatom = 1, box(i, j, k)%n
1921 WRITE (*, '(A,I3,3E14.6)') 'coor=', iatom, r_ptr(:, iatom)
1922 r(:) = pbc(box_center(:) - r_ptr(:, iatom), cell)
1923 IF (abs(r(1)) > (scale + 0.5_dp)*dbox(1) .OR. &
1924 abs(r(2)) > (scale + 0.5_dp)*dbox(2) .OR. &
1925 abs(r(3)) > (scale + 0.5_dp)*dbox(3)) THEN
1926 WRITE (*, *) 'error too many atoms'
1927 WRITE (*, *) 'dist=', abs(r(:))
1928 WRITE (*, *) 'large_dist=', (scale + 0.5_dp)*dbox
1929 cpabort("Some atoms are too far from box center")
1930 END IF
1931 END DO
1932 END IF
1933 END DO ! list
1934 END DO
1935 END DO
1936 END IF
1937
1938 IF (.true.) THEN
1939 DO k = 0, nbox(3) - 1
1940 DO j = 0, nbox(2) - 1
1941 DO i = 0, nbox(1) - 1
1942 box_center(1) = (real(i, dp) + 0.5_dp)*dbox(1)
1943 box_center(2) = (real(j, dp) + 0.5_dp)*dbox(2)
1944 box_center(3) = (real(k, dp) + 0.5_dp)*dbox(3)
1945 box_center = pbc(box_center, cell)
1946 r_ptr => box(i, j, k)%r
1947 DO iatom = 1, natms
1948 r(:) = pbc(box_center(:) - ratom(:, iatom), cell)
1949 ifind = 0
1950 DO jatom = 1, box(i, j, k)%n
1951 IF (sum(abs(ratom(:, iatom) - r_ptr(:, jatom))) < 1e-10_dp) ifind = 1
1952 END DO
1953
1954 IF (ifind == 0) THEN
1955 ! SQRT(DOT_PRODUCT(r, r)) < gauge_atom_radius
1956 IF (dot_product(r, r) < (gauge_atom_radius*gauge_atom_radius)) THEN
1957 WRITE (*, *) 'error atom too close'
1958 WRITE (*, *) 'iatom', iatom
1959 WRITE (*, *) 'box_center', box_center
1960 WRITE (*, *) 'ratom', ratom(:, iatom)
1961 WRITE (*, *) 'gauge_atom_radius', gauge_atom_radius
1962 cpabort("Some atoms are too close within gauge_atom_radius")
1963 END IF
1964 END IF
1965 END DO
1966 END DO ! list
1967 END DO
1968 END DO
1969 END IF
1970
1971 DEALLOCATE (ratom)
1972
1973 CALL timestop(handle)
1974
1975 END SUBROUTINE box_atoms_new
1976
1977! **************************************************************************************************
1978!> \brief ...
1979!> \param current_env ...
1980!> \param qs_env ...
1981!> \param rs_grid_x ...
1982!> \param rs_grid_y ...
1983!> \param rs_grid_z ...
1984!> \param box ...
1985! **************************************************************************************************
1986 SUBROUTINE collocate_gauge_new(current_env, qs_env, rs_grid_x, rs_grid_y, rs_grid_z, box)
1987 !
1988 TYPE(current_env_type) :: current_env
1989 TYPE(qs_environment_type), POINTER :: qs_env
1990 TYPE(realspace_grid_type), INTENT(IN) :: rs_grid_x, rs_grid_y, rs_grid_z
1991 TYPE(box_type), DIMENSION(:, :, :), POINTER :: box
1992
1993 CHARACTER(LEN=*), PARAMETER :: routinen = 'collocate_gauge_new'
1994
1995 INTEGER :: delta_lb(3), handle, i, iatom, ib, ibe, ibox, ibs, ie, is, j, jatom, jb, jbe, &
1996 jbox, jbs, je, js, k, kb, kbe, kbox, kbs, ke, ks, lb(3), lb_local(3), natms, &
1997 natms_local0, natms_local1, ng(3)
1998 REAL(dp), DIMENSION(:, :), POINTER :: r_ptr
1999 REAL(kind=dp) :: ab, box_center(3), buf_tmp, dist, dr(3), &
2000 gauge_atom_radius, offset(3), pa, pb, &
2001 point(3), pra(3), r(3), res(3), summe, &
2002 tmp, x, y, z
2003 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: buf, nrm_atms_pnt
2004 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: atms_pnt, ratom
2005 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: grid_x, grid_y, grid_z
2006 TYPE(cell_type), POINTER :: cell
2007 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2008 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2009
2010 CALL timeset(routinen, handle)
2011
2012!
2013 CALL get_current_env(current_env=current_env, &
2014 gauge_atom_radius=gauge_atom_radius)
2015 !
2016 CALL get_qs_env(qs_env=qs_env, &
2017 qs_kind_set=qs_kind_set, &
2018 cell=cell, &
2019 particle_set=particle_set)
2020 !
2021 natms = SIZE(particle_set, 1)
2022 dr(1) = rs_grid_x%desc%dh(1, 1)
2023 dr(2) = rs_grid_x%desc%dh(2, 2)
2024 dr(3) = rs_grid_x%desc%dh(3, 3)
2025 lb(:) = rs_grid_x%desc%lb(:)
2026 lb_local(:) = rs_grid_x%lb_local(:)
2027 grid_x => rs_grid_x%r(:, :, :)
2028 grid_y => rs_grid_y%r(:, :, :)
2029 grid_z => rs_grid_z%r(:, :, :)
2030 ng(:) = ubound(grid_x)
2031 delta_lb(:) = lb_local(:) - lb(:)
2032 offset(1) = cell%hmat(1, 1)*0.5_dp
2033 offset(2) = cell%hmat(2, 2)*0.5_dp
2034 offset(3) = cell%hmat(3, 3)*0.5_dp
2035 ALLOCATE (buf(natms), ratom(3, natms), atms_pnt(3, natms), nrm_atms_pnt(natms))
2036 !
2037 ! find the boxes that match the grid
2038 ibs = floor(real(delta_lb(1), dp)*dr(1)/dbox(1))
2039 ibe = floor(real(ng(1) - 1 + delta_lb(1), dp)*dr(1)/dbox(1))
2040 jbs = floor(real(delta_lb(2), dp)*dr(2)/dbox(2))
2041 jbe = floor(real(ng(2) - 1 + delta_lb(2), dp)*dr(2)/dbox(2))
2042 kbs = floor(real(delta_lb(3), dp)*dr(3)/dbox(3))
2043 kbe = floor(real(ng(3) - 1 + delta_lb(3), dp)*dr(3)/dbox(3))
2044 !
2045 ! go over the box-list
2046 DO kb = kbs, kbe
2047 DO jb = jbs, jbe
2048 DO ib = ibs, ibe
2049 ibox = modulo(ib, nbox(1))
2050 jbox = modulo(jb, nbox(2))
2051 kbox = modulo(kb, nbox(3))
2052 !
2053 is = max(ceiling(real(ib, dp)*dbox(1)/dr(1)), delta_lb(1)) - delta_lb(1) + 1
2054 ie = min(floor(real(ib + 1, dp)*dbox(1)/dr(1)), ng(1) - 1 + delta_lb(1)) - delta_lb(1) + 1
2055 js = max(ceiling(real(jb, dp)*dbox(2)/dr(2)), delta_lb(2)) - delta_lb(2) + 1
2056 je = min(floor(real(jb + 1, dp)*dbox(2)/dr(2)), ng(2) - 1 + delta_lb(2)) - delta_lb(2) + 1
2057 ks = max(ceiling(real(kb, dp)*dbox(3)/dr(3)), delta_lb(3)) - delta_lb(3) + 1
2058 ke = min(floor(real(kb + 1, dp)*dbox(3)/dr(3)), ng(3) - 1 + delta_lb(3)) - delta_lb(3) + 1
2059 !
2060 ! sanity checks
2061 IF (.true.) THEN
2062 IF (real(ks - 1 + delta_lb(3), dp)*dr(3) < real(kb, dp)*dbox(3) .OR. &
2063 REAL(ke - 1 + delta_lb(3), dp)*dr(3) > REAL(kb + 1, dp)*dbox(3)) then
2064 WRITE (*, *) 'box_k', real(kb, dp)*dbox(3), real(kb + 1, dp)*dbox(3)
2065 WRITE (*, *) 'point_k', real(ks - 1 + delta_lb(3), dp)*dr(3), real(ke - 1 + delta_lb(3), dp)*dr(3)
2066 WRITE (*, *) 'ibox', ibox, 'jbox', jbox, 'kbox', kbox
2067 WRITE (*, *) 'is,ie', is, ie, ' js,je', js, je, ' ks,ke', ks, ke
2068 WRITE (*, *) 'ibs,ibe', ibs, ibe, ' jbs,jbe', jbs, jbe, ' kbs,kbe', kbs, kbe
2069 cpabort("we stop_k")
2070 END IF
2071 IF (real(js - 1 + delta_lb(2), dp)*dr(2) < real(jb, dp)*dbox(2) .OR. &
2072 REAL(je - 1 + delta_lb(2), dp)*dr(2) > REAL(jb + 1, dp)*dbox(2)) then
2073 WRITE (*, *) 'box_j', real(jb, dp)*dbox(2), real(jb + 1, dp)*dbox(2)
2074 WRITE (*, *) 'point_j', real(js - 1 + delta_lb(2), dp)*dr(2), real(je - 1 + delta_lb(2), dp)*dr(2)
2075 WRITE (*, *) 'is,ie', is, ie, ' js,je', js, je, ' ks,ke', ks, ke
2076 WRITE (*, *) 'ibs,ibe', ibs, ibe, ' jbs,jbe', jbs, jbe, ' kbs,kbe', kbs, kbe
2077 cpabort("we stop_j")
2078 END IF
2079 IF (real(is - 1 + delta_lb(1), dp)*dr(1) < real(ib, dp)*dbox(1) .OR. &
2080 REAL(ie - 1 + delta_lb(1), dp)*dr(1) > REAL(ib + 1, dp)*dbox(1)) then
2081 WRITE (*, *) 'box_i', real(ib, dp)*dbox(1), real(ib + 1, dp)*dbox(1)
2082 WRITE (*, *) 'point_i', real(is - 1 + delta_lb(1), dp)*dr(1), real(ie - 1 + delta_lb(1), dp)*dr(1)
2083 WRITE (*, *) 'is,ie', is, ie, ' js,je', js, je, ' ks,ke', ks, ke
2084 WRITE (*, *) 'ibs,ibe', ibs, ibe, ' jbs,jbe', jbs, jbe, ' kbs,kbe', kbs, kbe
2085 cpabort("we stop_i")
2086 END IF
2087 END IF
2088 !
2089 ! the center of the box
2090 box_center(1) = (real(ibox, dp) + 0.5_dp)*dbox(1)
2091 box_center(2) = (real(jbox, dp) + 0.5_dp)*dbox(2)
2092 box_center(3) = (real(kbox, dp) + 0.5_dp)*dbox(3)
2093 !
2094 ! find the atoms that are in the overlaping boxes
2095 natms_local0 = box(ibox, jbox, kbox)%n
2096 r_ptr => box(ibox, jbox, kbox)%r
2097 !
2098 ! go over the grid inside the box
2099 IF (natms_local0 > 0) THEN
2100 !
2101 ! here there are some atoms...
2102 DO k = ks, ke
2103 DO j = js, je
2104 DO i = is, ie
2105 point(1) = real(i - 1 + delta_lb(1), dp)*dr(1)
2106 point(2) = real(j - 1 + delta_lb(2), dp)*dr(2)
2107 point(3) = real(k - 1 + delta_lb(3), dp)*dr(3)
2108 point = pbc(point, cell)
2109 !
2110 ! compute atom-point distances
2111 natms_local1 = 0
2112 DO iatom = 1, natms_local0
2113 r(:) = pbc(r_ptr(:, iatom) - point(:), cell) + point(:) !needed?
2114 dist = (r(1) - point(1))**2 + (r(2) - point(2))**2 + (r(3) - point(3))**2
2115 IF (dist < gauge_atom_radius**2) THEN
2116 natms_local1 = natms_local1 + 1
2117 ratom(:, natms_local1) = r(:)
2118 !
2119 ! compute the distance atoms-point
2120 x = point(1) - r(1)
2121 y = point(2) - r(2)
2122 z = point(3) - r(3)
2123 atms_pnt(1, natms_local1) = x
2124 atms_pnt(2, natms_local1) = y
2125 atms_pnt(3, natms_local1) = z
2126 nrm_atms_pnt(natms_local1) = sqrt(x*x + y*y + z*z)
2127 END IF
2128 END DO
2129 !
2130 !
2131 IF (natms_local1 > 0) THEN
2132 !
2133 ! build the step
2134 DO iatom = 1, natms_local1
2135 buf_tmp = 1.0_dp
2136 pra(1) = atms_pnt(1, iatom)
2137 pra(2) = atms_pnt(2, iatom)
2138 pra(3) = atms_pnt(3, iatom)
2139 pa = nrm_atms_pnt(iatom)
2140 DO jatom = 1, natms_local1
2141 IF (iatom == jatom) cycle
2142 pb = nrm_atms_pnt(jatom)
2143 x = pra(1) - atms_pnt(1, jatom)
2144 y = pra(2) - atms_pnt(2, jatom)
2145 z = pra(3) - atms_pnt(3, jatom)
2146 ab = sqrt(x*x + y*y + z*z)
2147 !
2148 tmp = (pa - pb)/ab
2149 tmp = 0.5_dp*(3.0_dp - tmp*tmp)*tmp
2150 tmp = 0.5_dp*(3.0_dp - tmp*tmp)*tmp
2151 tmp = 0.5_dp*(3.0_dp - tmp*tmp)*tmp
2152 buf_tmp = buf_tmp*0.5_dp*(1.0_dp - tmp)
2153 END DO
2154 buf(iatom) = buf_tmp
2155 END DO
2156 res(1) = 0.0_dp
2157 res(2) = 0.0_dp
2158 res(3) = 0.0_dp
2159 summe = 0.0_dp
2160 DO iatom = 1, natms_local1
2161 res(1) = res(1) + ratom(1, iatom)*buf(iatom)
2162 res(2) = res(2) + ratom(2, iatom)*buf(iatom)
2163 res(3) = res(3) + ratom(3, iatom)*buf(iatom)
2164 summe = summe + buf(iatom)
2165 END DO
2166 res(1) = res(1)/summe
2167 res(2) = res(2)/summe
2168 res(3) = res(3)/summe
2169 grid_x(i, j, k) = point(1) - res(1)
2170 grid_y(i, j, k) = point(2) - res(2)
2171 grid_z(i, j, k) = point(3) - res(3)
2172 ELSE
2173 grid_x(i, j, k) = 0.0_dp
2174 grid_y(i, j, k) = 0.0_dp
2175 grid_z(i, j, k) = 0.0_dp
2176 END IF
2177 END DO ! grid
2178 END DO
2179 END DO
2180 !
2181 ELSE
2182 !
2183 ! here there is no atom
2184 DO k = ks, ke
2185 DO j = js, je
2186 DO i = is, ie
2187 grid_x(i, j, k) = 0.0_dp
2188 grid_y(i, j, k) = 0.0_dp
2189 grid_z(i, j, k) = 0.0_dp
2190 END DO ! grid
2191 END DO
2192 END DO
2193 !
2194 END IF
2195 !
2196 END DO ! list
2197 END DO
2198 END DO
2199
2200 DEALLOCATE (buf, ratom, atms_pnt, nrm_atms_pnt)
2201
2202 CALL timestop(handle)
2203
2204 END SUBROUTINE collocate_gauge_new
2205
2206! **************************************************************************************************
2207!> \brief ...
2208!> \param box ...
2209! **************************************************************************************************
2210 SUBROUTINE deallocate_box(box)
2211 TYPE(box_type), DIMENSION(:, :, :), POINTER :: box
2212
2213 INTEGER :: i, j, k
2214
2215 IF (ASSOCIATED(box)) THEN
2216 DO k = lbound(box, 3), ubound(box, 3)
2217 DO j = lbound(box, 2), ubound(box, 2)
2218 DO i = lbound(box, 1), ubound(box, 1)
2219 IF (ASSOCIATED(box(i, j, k)%r)) THEN
2220 DEALLOCATE (box(i, j, k)%r)
2221 END IF
2222 END DO
2223 END DO
2224 END DO
2225 DEALLOCATE (box)
2226 END IF
2227 END SUBROUTINE deallocate_box
2228 END SUBROUTINE current_set_gauge
2229
2230! **************************************************************************************************
2231!> \brief ...
2232!> \param current_env ...
2233!> \param qs_env ...
2234!> \param iB ...
2235! **************************************************************************************************
2236 SUBROUTINE current_build_chi(current_env, qs_env, iB)
2237 !
2238 TYPE(current_env_type) :: current_env
2239 TYPE(qs_environment_type), POINTER :: qs_env
2240 INTEGER, INTENT(IN) :: ib
2241
2242 IF (current_env%full) THEN
2243 CALL current_build_chi_many_centers(current_env, qs_env, ib)
2244 ELSE IF (current_env%nbr_center(1) > 1) THEN
2245 CALL current_build_chi_many_centers(current_env, qs_env, ib)
2246 ELSE
2247 CALL current_build_chi_one_center(current_env, qs_env, ib)
2248 END IF
2249
2250 END SUBROUTINE current_build_chi
2251
2252! **************************************************************************************************
2253!> \brief ...
2254!> \param current_env ...
2255!> \param qs_env ...
2256!> \param iB ...
2257! **************************************************************************************************
2258 SUBROUTINE current_build_chi_many_centers(current_env, qs_env, iB)
2259 !
2260 TYPE(current_env_type) :: current_env
2261 TYPE(qs_environment_type), POINTER :: qs_env
2262 INTEGER, INTENT(IN) :: ib
2263
2264 CHARACTER(LEN=*), PARAMETER :: routinen = 'current_build_chi_many_centers'
2265
2266 INTEGER :: handle, icenter, idir, idir2, ii, iib, iii, iiib, ispin, istate, j, jstate, &
2267 max_states, nao, natom, nbr_center(2), nmo, nspins, nstate_loc, nstates(2), output_unit
2268 INTEGER, ALLOCATABLE, DIMENSION(:) :: first_sgf, last_sgf
2269 INTEGER, DIMENSION(:), POINTER :: row_blk_sizes
2270 LOGICAL :: chi_pbc, gapw
2271 REAL(dp) :: chi(3), chi_tmp, contrib, contrib2, &
2272 dk(3), int_current(3), &
2273 int_current_tmp, maxocc
2274 TYPE(cell_type), POINTER :: cell
2275 TYPE(cp_2d_i_p_type), DIMENSION(:), POINTER :: center_list
2276 TYPE(cp_2d_r_p_type), DIMENSION(:), POINTER :: centers_set
2277 TYPE(cp_fm_struct_type), POINTER :: tmp_fm_struct
2278 TYPE(cp_fm_type) :: psi0, psi_d, psi_p1, psi_p2, psi_rxp
2279 TYPE(cp_fm_type), DIMENSION(3) :: p_rxp, r_p1, r_p2
2280 TYPE(cp_fm_type), DIMENSION(9, 3) :: rr_p1, rr_p2, rr_rxp
2281 TYPE(cp_fm_type), DIMENSION(:), POINTER :: psi0_order
2282 TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: psi1_d, psi1_p, psi1_rxp
2283 TYPE(cp_fm_type), POINTER :: mo_coeff
2284 TYPE(cp_logger_type), POINTER :: logger
2285 TYPE(dbcsr_distribution_type), POINTER :: dbcsr_dist
2286 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: op_mom_ao, op_p_ao
2287 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: op_mom_der_ao
2288 TYPE(dft_control_type), POINTER :: dft_control
2289 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
2290 TYPE(mp_para_env_type), POINTER :: para_env
2291 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
2292 POINTER :: sab_all, sab_orb
2293 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2294 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2295
2296!
2297
2298 CALL timeset(routinen, handle)
2299 !
2300 NULLIFY (dft_control, mos, para_env, mo_coeff, op_mom_ao, &
2301 op_mom_der_ao, center_list, centers_set, &
2302 op_p_ao, psi1_p, psi1_rxp, psi1_d, &
2303 cell, particle_set, qs_kind_set)
2304
2305 logger => cp_get_default_logger()
2306 output_unit = cp_logger_get_default_io_unit(logger)
2307
2308 CALL get_qs_env(qs_env=qs_env, &
2309 dft_control=dft_control, &
2310 mos=mos, &
2311 para_env=para_env, &
2312 cell=cell, &
2313 dbcsr_dist=dbcsr_dist, &
2314 particle_set=particle_set, &
2315 qs_kind_set=qs_kind_set, &
2316 sab_all=sab_all, &
2317 sab_orb=sab_orb)
2318
2319 nspins = dft_control%nspins
2320 gapw = dft_control%qs_control%gapw
2321
2322 CALL get_current_env(current_env=current_env, &
2323 chi_pbc=chi_pbc, &
2324 nao=nao, &
2325 nbr_center=nbr_center, &
2326 center_list=center_list, &
2327 centers_set=centers_set, &
2328 psi1_p=psi1_p, &
2329 psi1_rxp=psi1_rxp, &
2330 psi1_d=psi1_d, &
2331 nstates=nstates, &
2332 psi0_order=psi0_order)
2333 !
2334 ! get max nbr of states per center
2335 max_states = 0
2336 DO ispin = 1, nspins
2337 DO icenter = 1, nbr_center(ispin)
2338 max_states = max(max_states, center_list(ispin)%array(1, icenter + 1)&
2339 & - center_list(ispin)%array(1, icenter))
2340 END DO
2341 END DO
2342 !
2343 ! Allocate sparse matrices for dipole, quadrupole and their derivatives => 9x3
2344 ! Remember the derivatives are antisymmetric
2345 CALL dbcsr_allocate_matrix_set(op_mom_ao, 9)
2346 CALL dbcsr_allocate_matrix_set(op_mom_der_ao, 9, 3)
2347 !
2348 ! prepare for allocation
2349 natom = SIZE(particle_set, 1)
2350 ALLOCATE (first_sgf(natom))
2351 ALLOCATE (last_sgf(natom))
2352 CALL get_particle_set(particle_set, qs_kind_set, &
2353 first_sgf=first_sgf, &
2354 last_sgf=last_sgf)
2355 ALLOCATE (row_blk_sizes(natom))
2356 CALL dbcsr_convert_offsets_to_sizes(first_sgf, row_blk_sizes, last_sgf)
2357 DEALLOCATE (first_sgf)
2358 DEALLOCATE (last_sgf)
2359 !
2360 !
2361 ALLOCATE (op_mom_ao(1)%matrix)
2362 CALL dbcsr_create(matrix=op_mom_ao(1)%matrix, &
2363 name="op_mom", &
2364 dist=dbcsr_dist, matrix_type=dbcsr_type_no_symmetry, &
2365 row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
2366 mutable_work=.true.)
2367 CALL cp_dbcsr_alloc_block_from_nbl(op_mom_ao(1)%matrix, sab_all)
2368
2369 DO idir2 = 1, 3
2370 ALLOCATE (op_mom_der_ao(1, idir2)%matrix)
2371 CALL dbcsr_copy(op_mom_der_ao(1, idir2)%matrix, op_mom_ao(1)%matrix, &
2372 "op_mom_der_ao"//"-"//trim(adjustl(cp_to_string(idir2))))
2373 END DO
2374
2375 DO idir = 2, SIZE(op_mom_ao, 1)
2376 ALLOCATE (op_mom_ao(idir)%matrix)
2377 CALL dbcsr_copy(op_mom_ao(idir)%matrix, op_mom_ao(1)%matrix, &
2378 "op_mom_ao"//"-"//trim(adjustl(cp_to_string(idir))))
2379 DO idir2 = 1, 3
2380 ALLOCATE (op_mom_der_ao(idir, idir2)%matrix)
2381 CALL dbcsr_copy(op_mom_der_ao(idir, idir2)%matrix, op_mom_ao(1)%matrix, &
2382 "op_mom_der_ao"//"-"//trim(adjustl(cp_to_string(idir*idir2))))
2383 END DO
2384 END DO
2385 !
2386 CALL dbcsr_allocate_matrix_set(op_p_ao, 3)
2387 ALLOCATE (op_p_ao(1)%matrix)
2388 CALL dbcsr_create(matrix=op_p_ao(1)%matrix, &
2389 name="op_p_ao", &
2390 dist=dbcsr_dist, matrix_type=dbcsr_type_antisymmetric, &
2391 row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
2392 mutable_work=.true.)
2393 CALL cp_dbcsr_alloc_block_from_nbl(op_p_ao(1)%matrix, sab_orb)
2394
2395 DO idir = 2, 3
2396 ALLOCATE (op_p_ao(idir)%matrix)
2397 CALL dbcsr_copy(op_p_ao(idir)%matrix, op_p_ao(1)%matrix, &
2398 "op_p_ao"//"-"//trim(adjustl(cp_to_string(idir))))
2399 END DO
2400 !
2401 !
2402 DEALLOCATE (row_blk_sizes)
2403 !
2404 !
2405 ! Allocate full matrices for only one vector
2406 mo_coeff => psi0_order(1)
2407 NULLIFY (tmp_fm_struct)
2408 CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nao, &
2409 ncol_global=max_states, para_env=para_env, &
2410 context=mo_coeff%matrix_struct%context)
2411 CALL cp_fm_create(psi0, tmp_fm_struct)
2412 CALL cp_fm_create(psi_d, tmp_fm_struct)
2413 CALL cp_fm_create(psi_rxp, tmp_fm_struct)
2414 CALL cp_fm_create(psi_p1, tmp_fm_struct)
2415 CALL cp_fm_create(psi_p2, tmp_fm_struct)
2416 CALL cp_fm_struct_release(tmp_fm_struct)
2417 !
2418 CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nao, &
2419 ncol_global=max_states, para_env=para_env, &
2420 context=mo_coeff%matrix_struct%context)
2421 DO idir = 1, 3
2422 CALL cp_fm_create(p_rxp(idir), tmp_fm_struct, set_zero=.true.)
2423 CALL cp_fm_create(r_p1(idir), tmp_fm_struct, set_zero=.true.)
2424 CALL cp_fm_create(r_p2(idir), tmp_fm_struct, set_zero=.true.)
2425 DO idir2 = 1, 9
2426 CALL cp_fm_create(rr_rxp(idir2, idir), tmp_fm_struct, set_zero=.true.)
2427 CALL cp_fm_create(rr_p1(idir2, idir), tmp_fm_struct, set_zero=.true.)
2428 CALL cp_fm_create(rr_p2(idir2, idir), tmp_fm_struct, set_zero=.true.)
2429 END DO
2430 END DO
2431 CALL cp_fm_struct_release(tmp_fm_struct)
2432 !
2433 !
2434 !
2435 ! recompute the linear momentum matrices
2436 CALL build_lin_mom_matrix(qs_env, op_p_ao)
2437 !CALL p_xyz_ao(op_p_ao,qs_env,minimum_image=.FALSE.)
2438 !
2439 !
2440 ! get iiB and iiiB
2441 CALL set_vecp(ib, iib, iiib)
2442 DO ispin = 1, nspins
2443 !
2444 ! get ground state MOS
2445 nmo = nstates(ispin)
2446 mo_coeff => psi0_order(ispin)
2447 CALL get_mo_set(mo_set=mos(ispin), maxocc=maxocc)
2448 !
2449 ! Initialize the temporary vector chi
2450 chi = 0.0_dp
2451 int_current = 0.0_dp
2452 !
2453 ! Start loop over the occupied states
2454 DO icenter = 1, nbr_center(ispin)
2455 !
2456 ! Get the Wannier center of the istate-th ground state orbital
2457 dk(1:3) = centers_set(ispin)%array(1:3, icenter)
2458 !
2459 ! Compute the multipole integrals for the state istate,
2460 ! using as reference center the corresponding Wannier center
2461 DO idir = 1, 9
2462 CALL dbcsr_set(op_mom_ao(idir)%matrix, 0.0_dp)
2463 DO idir2 = 1, 3
2464 CALL dbcsr_set(op_mom_der_ao(idir, idir2)%matrix, 0.0_dp)
2465 END DO
2466 END DO
2467 CALL rrc_xyz_der_ao(op_mom_ao, op_mom_der_ao, qs_env, dk, order=2, &
2468 minimum_image=.false., soft=gapw)
2469 !
2470 ! collecte the states that belong to a given center
2471 CALL cp_fm_set_all(psi0, 0.0_dp)
2472 CALL cp_fm_set_all(psi_rxp, 0.0_dp)
2473 CALL cp_fm_set_all(psi_d, 0.0_dp)
2474 CALL cp_fm_set_all(psi_p1, 0.0_dp)
2475 CALL cp_fm_set_all(psi_p2, 0.0_dp)
2476 nstate_loc = center_list(ispin)%array(1, icenter + 1) - center_list(ispin)%array(1, icenter)
2477 jstate = 1
2478 DO j = center_list(ispin)%array(1, icenter), center_list(ispin)%array(1, icenter + 1) - 1
2479 istate = center_list(ispin)%array(2, j)
2480 !
2481 ! block the states that belong to this center
2482 CALL cp_fm_to_fm(mo_coeff, psi0, 1, istate, jstate)
2483 !
2484 CALL cp_fm_to_fm(psi1_rxp(ispin, ib), psi_rxp, 1, istate, jstate)
2485 IF (current_env%full) CALL cp_fm_to_fm(psi1_d(ispin, ib), psi_d, 1, istate, jstate)
2486 !
2487 ! psi1_p_iiB_istate and psi1_p_iiiB_istate
2488 CALL cp_fm_to_fm(psi1_p(ispin, iib), psi_p1, 1, istate, jstate)
2489 CALL cp_fm_to_fm(psi1_p(ispin, iiib), psi_p2, 1, istate, jstate)
2490 !
2491 jstate = jstate + 1
2492 END DO ! istate
2493 !
2494 ! scale the ordered mos
2495 IF (current_env%full) CALL cp_fm_scale_and_add(1.0_dp, psi_rxp, -1.0_dp, psi_d)
2496 !
2497 DO idir = 1, 3
2498 CALL set_vecp(idir, ii, iii)
2499 CALL cp_dbcsr_sm_fm_multiply(op_p_ao(idir)%matrix, psi_rxp, &
2500 p_rxp(idir), ncol=nstate_loc, alpha=1.e0_dp)
2501 IF (iiib == iii .OR. iiib == ii) THEN
2502 CALL cp_dbcsr_sm_fm_multiply(op_mom_ao(idir)%matrix, psi_p1, &
2503 r_p1(idir), ncol=nstate_loc, alpha=1.e0_dp)
2504 END IF
2505 IF (iib == iii .OR. iib == ii) THEN
2506 CALL cp_dbcsr_sm_fm_multiply(op_mom_ao(idir)%matrix, psi_p2, &
2507 r_p2(idir), ncol=nstate_loc, alpha=1.e0_dp)
2508 END IF
2509 DO idir2 = 1, 9
2510 IF (idir2 == ii .OR. idir2 == iii) THEN
2511 CALL cp_dbcsr_sm_fm_multiply(op_mom_der_ao(idir2, idir)%matrix, psi_rxp, &
2512 rr_rxp(idir2, idir), ncol=nstate_loc, alpha=1.e0_dp)
2513 END IF
2514 !
2515 IF (idir2 == ind_m2(ii, iiib) .OR. idir2 == ind_m2(iii, iiib) .OR. idir2 == iiib) THEN
2516 CALL cp_dbcsr_sm_fm_multiply(op_mom_der_ao(idir2, idir)%matrix, psi_p1, &
2517 rr_p1(idir2, idir), ncol=nstate_loc, alpha=1.e0_dp)
2518 END IF
2519 !
2520 IF (idir2 == ind_m2(ii, iib) .OR. idir2 == ind_m2(iii, iib) .OR. idir2 == iib) THEN
2521 CALL cp_dbcsr_sm_fm_multiply(op_mom_der_ao(idir2, idir)%matrix, psi_p2, &
2522 rr_p2(idir2, idir), ncol=nstate_loc, alpha=1.e0_dp)
2523 END IF
2524 END DO
2525 END DO
2526 !
2527 ! Multuply left and right by the appropriate coefficients and sum into the
2528 ! correct component of the chi tensor using the appropriate multiplicative factor
2529 ! (don't forget the occupation number)
2530 ! Loop over the cartesian components of the tensor
2531 ! The loop over the components of the external field is external, thereby
2532 ! only one column of the chi tensor is computed here
2533 DO idir = 1, 3
2534 chi_tmp = 0.0_dp
2535 int_current_tmp = 0.0_dp
2536 !
2537 ! get ii and iii
2538 CALL set_vecp(idir, ii, iii)
2539 !
2540 ! term: 2[C0| (r-dk)_ii |d_iii(C1(rxp-D))]-2[C0| (r-dk)_iii |d_ii(C1(rxp-D))]
2541 ! the factor 2 should be already included in the matrix elements
2542 contrib = 0.0_dp
2543 CALL cp_fm_trace(psi0, rr_rxp(ii, iii), contrib)
2544 chi_tmp = chi_tmp + 2.0_dp*contrib
2545 !
2546 contrib = 0.0_dp
2547 CALL cp_fm_trace(psi0, rr_rxp(iii, ii), contrib)
2548 chi_tmp = chi_tmp - 2.0_dp*contrib
2549 !
2550 ! correction: dk_ii*2[C0| d_iii(C1(rxp-D))] - dk_iii*2[C0| d_ii(C1(rxp-D))]
2551 ! factor 2 not included in the matrix elements
2552 contrib = 0.0_dp
2553 CALL cp_fm_trace(psi0, p_rxp(iii), contrib)
2554 IF (.NOT. chi_pbc) chi_tmp = chi_tmp + 2.0_dp*dk(ii)*contrib
2555 int_current_tmp = int_current_tmp + 2.0_dp*contrib
2556 !
2557 contrib2 = 0.0_dp
2558 CALL cp_fm_trace(psi0, p_rxp(ii), contrib2)
2559 IF (.NOT. chi_pbc) chi_tmp = chi_tmp - 2.0_dp*dk(iii)*contrib2
2560 !
2561 ! term: -2[C0| (r-dk)_ii (r-dk)_iiB | d_iii(C1(piiiB))] \
2562 ! +2[C0| (r-dk)_iii (r-dk)_iiB | d_ii(C1(piiiB))]
2563 ! the factor 2 should be already included in the matrix elements
2564 contrib = 0.0_dp
2565 idir2 = ind_m2(ii, iib)
2566 CALL cp_fm_trace(psi0, rr_p2(idir2, iii), contrib)
2567 chi_tmp = chi_tmp - 2.0_dp*contrib
2568 contrib2 = 0.0_dp
2569 IF (iib == iii) THEN
2570 CALL cp_fm_trace(psi0, r_p2(ii), contrib2)
2571 chi_tmp = chi_tmp - contrib2
2572 END IF
2573 !
2574 contrib = 0.0_dp
2575 idir2 = ind_m2(iii, iib)
2576 CALL cp_fm_trace(psi0, rr_p2(idir2, ii), contrib)
2577 chi_tmp = chi_tmp + 2.0_dp*contrib
2578 contrib2 = 0.0_dp
2579 IF (iib == ii) THEN
2580 CALL cp_fm_trace(psi0, r_p2(iii), contrib2)
2581 chi_tmp = chi_tmp + contrib2
2582 END IF
2583 !
2584 ! correction: -dk_ii * 2[C0|(r-dk)_iiB | d_iii(C1(piiiB))] \
2585 ! +dk_iii * 2[C0|(r-dk)_iiB | d_ii(C1(piiiB))]
2586 ! the factor 2 should be already included in the matrix elements
2587 ! no additional correction terms because of the orthogonality between C0 and C1
2588 contrib = 0.0_dp
2589 CALL cp_fm_trace(psi0, rr_p2(iib, iii), contrib)
2590 IF (.NOT. chi_pbc) chi_tmp = chi_tmp - 2.0_dp*dk(ii)*contrib
2591 int_current_tmp = int_current_tmp - 2.0_dp*contrib
2592 !
2593 contrib2 = 0.0_dp
2594 CALL cp_fm_trace(psi0, rr_p2(iib, ii), contrib2)
2595 IF (.NOT. chi_pbc) chi_tmp = chi_tmp + 2.0_dp*dk(iii)*contrib2
2596 !
2597 ! term: +2[C0| (r-dk)_ii (r-dk)_iiiB | d_iii(C1(piiB))] \
2598 ! -2[C0| (r-dk)_iii (r-dk)_iiiB | d_ii(C1(piiB))]
2599 ! the factor 2 should be already included in the matrix elements
2600 contrib = 0.0_dp
2601 idir2 = ind_m2(ii, iiib)
2602 CALL cp_fm_trace(psi0, rr_p1(idir2, iii), contrib)
2603 chi_tmp = chi_tmp + 2.0_dp*contrib
2604 contrib2 = 0.0_dp
2605 IF (iiib == iii) THEN
2606 CALL cp_fm_trace(psi0, r_p1(ii), contrib2)
2607 chi_tmp = chi_tmp + contrib2
2608 END IF
2609 !
2610 contrib = 0.0_dp
2611 idir2 = ind_m2(iii, iiib)
2612 CALL cp_fm_trace(psi0, rr_p1(idir2, ii), contrib)
2613 chi_tmp = chi_tmp - 2.0_dp*contrib
2614 contrib2 = 0.0_dp
2615 IF (iiib == ii) THEN
2616 CALL cp_fm_trace(psi0, r_p1(iii), contrib2)
2617 chi_tmp = chi_tmp - contrib2
2618 END IF
2619 !
2620 ! correction: +dk_ii * 2[C0|(r-dk)_iiiB | d_iii(C1(piiB))] +\
2621 ! -dk_iii * 2[C0|(r-dk)_iiiB | d_ii(C1(piiB))]
2622 ! the factor 2 should be already included in the matrix elements
2623 contrib = 0.0_dp
2624 CALL cp_fm_trace(psi0, rr_p1(iiib, iii), contrib)
2625 IF (.NOT. chi_pbc) chi_tmp = chi_tmp + 2.0_dp*dk(ii)*contrib
2626 int_current_tmp = int_current_tmp + 2.0_dp*contrib
2627 !
2628 contrib2 = 0.0_dp
2629 CALL cp_fm_trace(psi0, rr_p1(iiib, ii), contrib2)
2630 IF (.NOT. chi_pbc) chi_tmp = chi_tmp - 2.0_dp*dk(iii)*contrib2
2631 !
2632 ! accumulate
2633 chi(idir) = chi(idir) + maxocc*chi_tmp
2634 int_current(iii) = int_current(iii) + int_current_tmp
2635 END DO ! idir
2636
2637 END DO ! icenter
2638 !
2639 DO idir = 1, 3
2640 current_env%chi_tensor(idir, ib, ispin) = current_env%chi_tensor(idir, ib, ispin) + &
2641 chi(idir)
2642 IF (output_unit > 0) THEN
2643 !WRITE(output_unit,'(A,E12.6)') ' chi_'//ACHAR(119+idir)//ACHAR(119+iB)//&
2644 ! & ' = ',chi(idir)
2645 !WRITE(output_unit,'(A,E12.6)') ' analytic \int j_'//ACHAR(119+idir)//ACHAR(119+iB)//&
2646 ! & '(r) d^3r = ',int_current(idir)
2647 END IF
2648 END DO
2649 !
2650 END DO ! ispin
2651 !
2652 ! deallocate the sparse matrices
2653 CALL dbcsr_deallocate_matrix_set(op_mom_ao)
2654 CALL dbcsr_deallocate_matrix_set(op_mom_der_ao)
2655 CALL dbcsr_deallocate_matrix_set(op_p_ao)
2656
2657 CALL cp_fm_release(psi0)
2658 CALL cp_fm_release(psi_rxp)
2659 CALL cp_fm_release(psi_d)
2660 CALL cp_fm_release(psi_p1)
2661 CALL cp_fm_release(psi_p2)
2662 DO idir = 1, 3
2663 CALL cp_fm_release(p_rxp(idir))
2664 CALL cp_fm_release(r_p1(idir))
2665 CALL cp_fm_release(r_p2(idir))
2666 DO idir2 = 1, 9
2667 CALL cp_fm_release(rr_rxp(idir2, idir))
2668 CALL cp_fm_release(rr_p1(idir2, idir))
2669 CALL cp_fm_release(rr_p2(idir2, idir))
2670 END DO
2671 END DO
2672
2673 CALL timestop(handle)
2674
2675 END SUBROUTINE current_build_chi_many_centers
2676
2677! **************************************************************************************************
2678!> \brief ...
2679!> \param current_env ...
2680!> \param qs_env ...
2681!> \param iB ...
2682! **************************************************************************************************
2683 SUBROUTINE current_build_chi_one_center(current_env, qs_env, iB)
2684 !
2685 TYPE(current_env_type) :: current_env
2686 TYPE(qs_environment_type), POINTER :: qs_env
2687 INTEGER, INTENT(IN) :: ib
2688
2689 CHARACTER(LEN=*), PARAMETER :: routinen = 'current_build_chi_one_center'
2690
2691 INTEGER :: handle, idir, idir2, iib, iiib, ispin, jdir, jjdir, kdir, max_states, nao, natom, &
2692 nbr_center(2), nmo, nspins, nstates(2), output_unit
2693 INTEGER, ALLOCATABLE, DIMENSION(:) :: first_sgf, last_sgf
2694 INTEGER, DIMENSION(:), POINTER :: row_blk_sizes
2695 LOGICAL :: chi_pbc, gapw
2696 REAL(dp) :: chi(3), contrib, dk(3), int_current(3), &
2697 maxocc
2698 TYPE(cell_type), POINTER :: cell
2699 TYPE(cp_2d_i_p_type), DIMENSION(:), POINTER :: center_list
2700 TYPE(cp_2d_r_p_type), DIMENSION(:), POINTER :: centers_set
2701 TYPE(cp_fm_type) :: buf
2702 TYPE(cp_fm_type), DIMENSION(:), POINTER :: psi0_order
2703 TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: psi1_p, psi1_rxp
2704 TYPE(cp_fm_type), POINTER :: mo_coeff
2705 TYPE(cp_logger_type), POINTER :: logger
2706 TYPE(dbcsr_distribution_type), POINTER :: dbcsr_dist
2707 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: op_mom_ao, op_p_ao
2708 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: op_mom_der_ao
2709 TYPE(dft_control_type), POINTER :: dft_control
2710 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
2711 TYPE(mp_para_env_type), POINTER :: para_env
2712 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
2713 POINTER :: sab_all, sab_orb
2714 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2715 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2716
2717!
2718
2719 CALL timeset(routinen, handle)
2720 !
2721 NULLIFY (dft_control, mos, para_env, mo_coeff, op_mom_ao, &
2722 op_mom_der_ao, center_list, centers_set, &
2723 op_p_ao, psi1_p, psi1_rxp, cell, psi0_order)
2724
2725 logger => cp_get_default_logger()
2726 output_unit = cp_logger_get_default_io_unit(logger)
2727
2728 CALL get_qs_env(qs_env=qs_env, &
2729 dft_control=dft_control, &
2730 mos=mos, &
2731 para_env=para_env, &
2732 cell=cell, &
2733 particle_set=particle_set, &
2734 qs_kind_set=qs_kind_set, &
2735 sab_all=sab_all, &
2736 sab_orb=sab_orb, &
2737 dbcsr_dist=dbcsr_dist)
2738
2739 nspins = dft_control%nspins
2740 gapw = dft_control%qs_control%gapw
2741
2742 CALL get_current_env(current_env=current_env, &
2743 chi_pbc=chi_pbc, &
2744 nao=nao, &
2745 nbr_center=nbr_center, &
2746 center_list=center_list, &
2747 centers_set=centers_set, &
2748 psi1_p=psi1_p, &
2749 psi1_rxp=psi1_rxp, &
2750 nstates=nstates, &
2751 psi0_order=psi0_order)
2752 !
2753 max_states = maxval(nstates(1:nspins))
2754 !
2755 ! Allocate sparse matrices for dipole, quadrupole and their derivatives => 9x3
2756 ! Remember the derivatives are antisymmetric
2757 CALL dbcsr_allocate_matrix_set(op_mom_ao, 9)
2758 CALL dbcsr_allocate_matrix_set(op_mom_der_ao, 9, 3)
2759 !
2760 ! prepare for allocation
2761 natom = SIZE(particle_set, 1)
2762 ALLOCATE (first_sgf(natom))
2763 ALLOCATE (last_sgf(natom))
2764 CALL get_particle_set(particle_set, qs_kind_set, &
2765 first_sgf=first_sgf, &
2766 last_sgf=last_sgf)
2767 ALLOCATE (row_blk_sizes(natom))
2768 CALL dbcsr_convert_offsets_to_sizes(first_sgf, row_blk_sizes, last_sgf)
2769 DEALLOCATE (first_sgf)
2770 DEALLOCATE (last_sgf)
2771 !
2772 !
2773 ALLOCATE (op_mom_ao(1)%matrix)
2774 CALL dbcsr_create(matrix=op_mom_ao(1)%matrix, &
2775 name="op_mom", &
2776 dist=dbcsr_dist, matrix_type=dbcsr_type_no_symmetry, &
2777 row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
2778 mutable_work=.true.)
2779 CALL cp_dbcsr_alloc_block_from_nbl(op_mom_ao(1)%matrix, sab_all)
2780
2781 DO idir2 = 1, 3
2782 ALLOCATE (op_mom_der_ao(1, idir2)%matrix)
2783 CALL dbcsr_copy(op_mom_der_ao(1, idir2)%matrix, op_mom_ao(1)%matrix, &
2784 "op_mom_der_ao"//"-"//trim(adjustl(cp_to_string(idir2))))
2785 END DO
2786
2787 DO idir = 2, SIZE(op_mom_ao, 1)
2788 ALLOCATE (op_mom_ao(idir)%matrix)
2789 CALL dbcsr_copy(op_mom_ao(idir)%matrix, op_mom_ao(1)%matrix, &
2790 "op_mom_ao"//"-"//trim(adjustl(cp_to_string(idir))))
2791 DO idir2 = 1, 3
2792 ALLOCATE (op_mom_der_ao(idir, idir2)%matrix)
2793 CALL dbcsr_copy(op_mom_der_ao(idir, idir2)%matrix, op_mom_ao(1)%matrix, &
2794 "op_mom_der_ao"//"-"//trim(adjustl(cp_to_string(idir*idir2))))
2795 END DO
2796 END DO
2797 !
2798 CALL dbcsr_allocate_matrix_set(op_p_ao, 3)
2799 ALLOCATE (op_p_ao(1)%matrix)
2800 CALL dbcsr_create(matrix=op_p_ao(1)%matrix, &
2801 name="op_p_ao", &
2802 dist=dbcsr_dist, matrix_type=dbcsr_type_antisymmetric, &
2803 row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
2804 mutable_work=.true.)
2805 CALL cp_dbcsr_alloc_block_from_nbl(op_p_ao(1)%matrix, sab_orb)
2806
2807 DO idir = 2, 3
2808 ALLOCATE (op_p_ao(idir)%matrix)
2809 CALL dbcsr_copy(op_p_ao(idir)%matrix, op_p_ao(1)%matrix, &
2810 "op_p_ao"//"-"//trim(adjustl(cp_to_string(idir))))
2811 END DO
2812 !
2813 !
2814 DEALLOCATE (row_blk_sizes)
2815 !
2816 ! recompute the linear momentum matrices
2817 CALL build_lin_mom_matrix(qs_env, op_p_ao)
2818 !CALL p_xyz_ao(op_p_ao,qs_env,minimum_image=.FALSE.)
2819 !
2820 !
2821 ! get iiB and iiiB
2822 CALL set_vecp(ib, iib, iiib)
2823 DO ispin = 1, nspins
2824 !
2825 cpassert(nbr_center(ispin) == 1)
2826 !
2827 ! get ground state MOS
2828 nmo = nstates(ispin)
2829 mo_coeff => psi0_order(ispin)
2830 CALL get_mo_set(mo_set=mos(ispin), maxocc=maxocc)
2831 !
2832 ! Create buffer matrix
2833 CALL cp_fm_create(buf, mo_coeff%matrix_struct)
2834 !
2835 ! Initialize the temporary vector chi
2836 chi = 0.0_dp
2837 int_current = 0.0_dp
2838 !
2839 !
2840 ! Get the Wannier center of the istate-th ground state orbital
2841 dk(1:3) = centers_set(ispin)%array(1:3, 1)
2842 !
2843 ! Compute the multipole integrals for the state istate,
2844 ! using as reference center the corresponding Wannier center
2845 DO idir = 1, 9
2846 CALL dbcsr_set(op_mom_ao(idir)%matrix, 0.0_dp)
2847 DO idir2 = 1, 3
2848 CALL dbcsr_set(op_mom_der_ao(idir, idir2)%matrix, 0.0_dp)
2849 END DO
2850 END DO
2851 CALL rrc_xyz_der_ao(op_mom_ao, op_mom_der_ao, qs_env, dk, order=2, &
2852 minimum_image=.false., soft=gapw)
2853 !
2854 !
2855 ! Multuply left and right by the appropriate coefficients and sum into the
2856 ! correct component of the chi tensor using the appropriate multiplicative factor
2857 ! (don't forget the occupation number)
2858 ! Loop over the cartesian components of the tensor
2859 ! The loop over the components of the external field is external, thereby
2860 ! only one column of the chi tensor is computed here
2861 DO idir = 1, 3
2862 !
2863 !
2864 !
2865 ! term: dk_ii*2[C0| d_iii(C1(rxp-D))] - dk_iii*2[C0| d_ii(C1(rxp-D))]
2866 IF (.NOT. chi_pbc) THEN
2867 CALL cp_dbcsr_sm_fm_multiply(op_p_ao(idir)%matrix, mo_coeff, &
2868 buf, ncol=nmo, alpha=1.e0_dp)
2869 DO jdir = 1, 3
2870 DO kdir = 1, 3
2871 IF (levi_civita(kdir, jdir, idir) == 0.0_dp) cycle
2872 CALL cp_fm_trace(buf, psi1_rxp(ispin, ib), contrib)
2873 chi(kdir) = chi(kdir) - levi_civita(kdir, jdir, idir)*2.0_dp*dk(jdir)*contrib
2874 END DO
2875 END DO
2876 END IF
2877 !
2878 !
2879 !
2880 ! term: 2[C0| (r-dk)_ii |d_iii(C1(rxp-D))]-2[C0| (r-dk)_iii |d_ii(C1(rxp-D))]
2881 ! and
2882 ! term: -dk_ii * 2[C0|(r-dk)_iiB | d_iii(C1(piiiB))] +
2883 ! +dk_iii * 2[C0|(r-dk)_iiB | d_ii(C1(piiiB))]
2884 ! and
2885 ! term: +dk_ii * 2[C0|(r-dk)_iiiB | d_iii(C1(piiB))] +
2886 ! -dk_iii * 2[C0|(r-dk)_iiiB | d_ii(C1(piiB))]
2887 DO jdir = 1, 3
2888 CALL cp_dbcsr_sm_fm_multiply(op_mom_der_ao(jdir, idir)%matrix, mo_coeff, &
2889 buf, ncol=nmo, alpha=1.e0_dp)
2890 DO kdir = 1, 3
2891 IF (levi_civita(kdir, jdir, idir) == 0.0_dp) cycle
2892 CALL cp_fm_trace(buf, psi1_rxp(ispin, ib), contrib)
2893 chi(kdir) = chi(kdir) - levi_civita(kdir, jdir, idir)*2.0_dp*contrib
2894 END DO
2895 !
2896 IF (.NOT. chi_pbc) THEN
2897 IF (jdir == iib) THEN
2898 DO jjdir = 1, 3
2899 DO kdir = 1, 3
2900 IF (levi_civita(kdir, jjdir, idir) == 0.0_dp) cycle
2901 CALL cp_fm_trace(buf, psi1_p(ispin, iiib), contrib)
2902 chi(kdir) = chi(kdir) + levi_civita(kdir, jjdir, idir)*2.0_dp*dk(jjdir)*contrib
2903 END DO
2904 END DO
2905 END IF
2906 !
2907 IF (jdir == iiib) THEN
2908 DO jjdir = 1, 3
2909 DO kdir = 1, 3
2910 IF (levi_civita(kdir, jjdir, idir) == 0.0_dp) cycle
2911 CALL cp_fm_trace(buf, psi1_p(ispin, iib), contrib)
2912 chi(kdir) = chi(kdir) - levi_civita(kdir, jjdir, idir)*2.0_dp*dk(jjdir)*contrib
2913 END DO
2914 END DO
2915 END IF
2916 END IF
2917 END DO
2918 !
2919 !
2920 !
2921 ! term1: -2[C0| (r-dk)_ii (r-dk)_iiB | d_iii(C1(piiiB))] +
2922 ! +2[C0| (r-dk)_iii (r-dk)_iiB | d_ii(C1(piiiB))]
2923 ! and
2924 ! term1: +2[C0| (r-dk)_ii (r-dk)_iiiB | d_iii(C1(piiB))] +
2925 ! -2[C0| (r-dk)_iii (r-dk)_iiiB | d_ii(C1(piiB))]
2926 ! HERE THERE IS ONE EXTRA MULTIPLY
2927 DO jdir = 1, 3
2928 CALL cp_dbcsr_sm_fm_multiply(op_mom_der_ao(ind_m2(jdir, iib), idir)%matrix, mo_coeff, &
2929 buf, ncol=nmo, alpha=1.e0_dp)
2930 DO kdir = 1, 3
2931 IF (levi_civita(kdir, jdir, idir) == 0.0_dp) cycle
2932 CALL cp_fm_trace(buf, psi1_p(ispin, iiib), contrib)
2933 chi(kdir) = chi(kdir) + levi_civita(kdir, jdir, idir)*2.0_dp*contrib
2934 END DO
2935 !
2936 CALL cp_dbcsr_sm_fm_multiply(op_mom_der_ao(ind_m2(jdir, iiib), idir)%matrix, mo_coeff, &
2937 buf, ncol=nmo, alpha=1.e0_dp)
2938 DO kdir = 1, 3
2939 IF (levi_civita(kdir, jdir, idir) == 0.0_dp) cycle
2940 CALL cp_fm_trace(buf, psi1_p(ispin, iib), contrib)
2941 chi(kdir) = chi(kdir) - levi_civita(kdir, jdir, idir)*2.0_dp*contrib
2942 END DO
2943 END DO
2944 !
2945 !
2946 !
2947 ! term2: -2[C0| (r-dk)_ii (r-dk)_iiB | d_iii(C1(piiiB))] +
2948 ! +2[C0| (r-dk)_iii (r-dk)_iiB | d_ii(C1(piiiB))]
2949 ! and
2950 ! term2: +2[C0| (r-dk)_ii (r-dk)_iiiB | d_iii(C1(piiB))] +
2951 ! -2[C0| (r-dk)_iii (r-dk)_iiiB | d_ii(C1(piiB))]
2952 CALL cp_dbcsr_sm_fm_multiply(op_mom_ao(idir)%matrix, mo_coeff, &
2953 buf, ncol=nmo, alpha=1.e0_dp)
2954 DO jdir = 1, 3
2955 DO kdir = 1, 3
2956 IF (levi_civita(kdir, idir, jdir) == 0.0_dp) cycle
2957 IF (iib == jdir) THEN
2958 CALL cp_fm_trace(buf, psi1_p(ispin, iiib), contrib)
2959 chi(kdir) = chi(kdir) + levi_civita(kdir, idir, jdir)*contrib
2960 END IF
2961 END DO
2962 END DO
2963 !
2964 DO jdir = 1, 3
2965 DO kdir = 1, 3
2966 IF (levi_civita(kdir, idir, jdir) == 0.0_dp) cycle
2967 IF (iiib == jdir) THEN
2968 CALL cp_fm_trace(buf, psi1_p(ispin, iib), contrib)
2969 chi(kdir) = chi(kdir) - levi_civita(kdir, idir, jdir)*contrib
2970 END IF
2971 !
2972 END DO
2973 END DO
2974 !
2975 !
2976 !
2977 !
2978 END DO ! idir
2979 !
2980 DO idir = 1, 3
2981 current_env%chi_tensor(idir, ib, ispin) = current_env%chi_tensor(idir, ib, ispin) + &
2982 maxocc*chi(idir)
2983 IF (output_unit > 0) THEN
2984 !WRITE(output_unit,'(A,E12.6)') ' chi_'//ACHAR(119+idir)//ACHAR(119+iB)//&
2985 ! & ' = ',maxocc * chi(idir)
2986 END IF
2987 END DO
2988 !
2989 CALL cp_fm_release(buf)
2990 END DO ! ispin
2991 !
2992 ! deallocate the sparse matrices
2993 CALL dbcsr_deallocate_matrix_set(op_mom_ao)
2994 CALL dbcsr_deallocate_matrix_set(op_mom_der_ao)
2995 CALL dbcsr_deallocate_matrix_set(op_p_ao)
2996
2997 CALL timestop(handle)
2998
2999 END SUBROUTINE current_build_chi_one_center
3000
3001END MODULE qs_linres_current
static int imax(int x, int y)
Returns the larger of two given integers (missing from the C standard)
static int imin(int x, int y)
Returns the smaller of the two integers (missing from the C standard).
Definition dbm_miniapp.c:36
static GRID_HOST_DEVICE int ncoset(const int l)
Number of Cartesian orbitals up to given angular momentum quantum.
Definition grid_common.h:81
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
All kind of helpful little routines.
Definition ao_util.F:14
real(kind=dp) function, public exp_radius_very_extended(la_min, la_max, lb_min, lb_max, pab, o1, o2, ra, rb, rp, zetp, eps, prefactor, cutoff, epsabs)
computes the radius of the Gaussian outside of which it is smaller than eps
Definition ao_util.F:209
subroutine, public get_gto_basis_set(gto_basis_set, name, aliases, norm_type, kind_radius, ncgf, nset, nsgf, cgf_symbol, sgf_symbol, norm_cgf, set_radius, lmax, lmin, lx, ly, lz, m, ncgf_set, npgf, nsgf_set, nshell, cphi, pgf_radius, sphi, scon, zet, first_cgf, first_sgf, l, last_cgf, last_sgf, n, gcc, maxco, maxl, maxpgf, maxsgf_set, maxshell, maxso, nco_sum, npgf_sum, nshell_sum, maxder, short_kind_radius, npgf_seg_sum, ccon)
...
Handles all functions related to the CELL.
Definition cell_types.F:15
various utilities that regard array of different kinds: output, allocation,... maybe it is not a good...
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_deallocate_matrix(matrix)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_get_block_p(matrix, row, col, block, found, row_size, col_size)
...
subroutine, public dbcsr_finalize(matrix)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_put_block(matrix, row, col, block, summation)
...
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
subroutine, public cp_dbcsr_plus_fm_fm_t(sparse_matrix, matrix_v, matrix_g, ncol, alpha, keep_sparsity, symmetry_mode)
performs the multiplication sparse_matrix+dense_mat*dens_mat^T if matrix_g is not explicitly given,...
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
integer, parameter, public cp_p_file
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
A wrapper around pw_to_cube() which accepts particle_list_type.
subroutine, public cp_pw_to_cube(pw, unit_nr, title, particles, zeff, stride, max_file_size_mb, zero_tails, silent, mpi_io)
...
for a given dr()/dh(r) this will provide the bounds to be used if one wants to go over a sphere-subre...
Definition cube_utils.F:18
subroutine, public compute_cube_center(cube_center, rs_desc, zeta, zetb, ra, rab)
unifies the computation of the cube center, so that differences in implementation,...
Definition cube_utils.F:68
subroutine, public return_cube(info, radius, lb_cube, ub_cube, sphere_bounds)
...
Definition cube_utils.F:140
Fortran API for the grid package, which is written in C.
Definition grid_api.F:12
integer, parameter, public grid_func_adbmdab_z
Definition grid_api.F:31
integer, parameter, public grid_func_adbmdab_y
Definition grid_api.F:30
integer, parameter, public grid_func_ardbmdarb_yx
Definition grid_api.F:35
integer, parameter, public grid_func_ardbmdarb_zz
Definition grid_api.F:40
integer, parameter, public grid_func_ardbmdarb_xy
Definition grid_api.F:33
integer, parameter, public grid_func_ardbmdarb_zx
Definition grid_api.F:38
integer, parameter, public grid_func_ardbmdarb_xx
Definition grid_api.F:32
integer, parameter, public grid_func_ardbmdarb_yz
Definition grid_api.F:37
integer, parameter, public grid_func_ab
Definition grid_api.F:27
integer, parameter, public grid_func_ardbmdarb_yy
Definition grid_api.F:36
integer, parameter, public grid_func_adbmdab_x
Definition grid_api.F:29
subroutine, public collocate_pgf_product(la_max, zeta, la_min, lb_max, zetb, lb_min, ra, rab, scale, pab, o1, o2, rsgrid, ga_gb_function, radius, use_subpatch, subpatch_pattern)
low level collocation of primitive gaussian functions
Definition grid_api.F:116
integer, parameter, public grid_func_ardbmdarb_zy
Definition grid_api.F:39
integer, parameter, public grid_func_ardbmdarb_xz
Definition grid_api.F:34
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public current_gauge_atom
objects that represent the structure of input sections and the data contained in an input section
integer function, dimension(:), pointer, public section_get_ivals(section_vals, keyword_name)
...
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
logical function, public section_get_lval(section_vals, keyword_name)
...
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
integer, parameter, public default_path_length
Definition kinds.F:58
Definition of mathematical constants and functions.
real(kind=dp), parameter, public twopi
Utility routines for the memory handling.
Interface to the message passing library MPI.
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public ncoset
represent a simple array based list of the given type
Define methods related to particle_type.
subroutine, public get_particle_set(particle_set, qs_kind_set, first_sgf, last_sgf, nsgf, nmao, basis, ncgf)
Get the components of a particle set.
Define the data structure for the particle information.
container for various plainwaves related things
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, hund_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, proj_shell_charge, lr_atom, do_mtlr, u_j_loop, ao_coef, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
subroutine, public get_qs_kind_set(qs_kind_set, all_potential_present, tnadd_potential_present, gth_potential_present, sgp_potential_present, paw_atom_present, dft_plus_u_atom_present, maxcgf, maxsgf, maxco, maxco_proj, maxgtops, maxlgto, maxlprj, maxnset, maxsgf_set, ncgf, npgf, nset, nsgf, nshell, maxpol, maxlppl, maxlppnl, maxppnl, nelectron, maxder, max_ngrid_rad, max_sph_harm, maxg_iso_not0, lmax_rho0, basis_rcut, do_mtlr_present, basis_type, total_zeff_corr, npgf_seg, cneo_potential_present, nkind_q, natom_q)
Get attributes of an atomic kind set.
given the response wavefunctions obtained by the application of the (rxp), p, and ((dk-dl)xp) operato...
subroutine, public calculate_jrho_atom(current_env, qs_env, ib, idir)
...
subroutine, public calculate_jrho_atom_coeff(qs_env, current_env, mat_d0, mat_jp, mat_jp_rii, mat_jp_riii, ib, idir)
Calculate the expansion coefficients for the atomic terms of the current densitiy in GAPW.
subroutine, public calculate_jrho_atom_rad(qs_env, current_env, idir)
...
given the response wavefunctions obtained by the application of the (rxp), p, and ((dk-dl)xp) operato...
subroutine, public current_build_current(current_env, qs_env, ib)
First calculate the density matrixes, for each component of the current they are 3 because of the r d...
real(dp), dimension(3, 3, 3), parameter levi_civita
subroutine, public calculate_jrho_resp(mat_d0, mat_jp, mat_jp_rii, mat_jp_riii, ib, idir, current_rs, current_gs, qs_env, current_env, soft_valid, retain_rsgrid)
Calculation of the idir component of the response current density in the presence of a constant magne...
subroutine, public current_build_chi(current_env, qs_env, ib)
...
Calculate the operators p rxp and D needed in the optimization of the different contribution of the f...
integer function, public ind_m2(ii, iii)
...
subroutine, public set_vecp(i1, i2, i3)
...
real(dp) function, public fac_vecp(a, b, c)
...
subroutine, public fm_scale_by_pbc_ac(matrix, ra, rc, cell, ixyz)
scale a matrix as a_ij = a_ij * pbc(rc(:,j),ra(:,i))(ixyz)
subroutine, public set_vecp_rev(i1, i2, i3)
...
Type definitiona for linear response calculations.
subroutine, public get_current_env(current_env, simple_done, simple_converged, full_done, nao, nstates, gauge, list_cubes, statetrueindex, gauge_name, basisfun_center, nbr_center, center_list, centers_set, psi1_p, psi1_rxp, psi1_d, p_psi0, rxp_psi0, jrho1_atom_set, jrho1_set, chi_tensor, chi_tensor_loc, gauge_atom_radius, rs_gauge, use_old_gauge_atom, chi_pbc, psi0_order)
...
wrapper for the pools of matrixes
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
Define the neighbor list data types and the corresponding functionality.
subroutine, public neighbor_list_iterator_create(iterator_set, nl, search, nthread)
Neighbor list iterator functions.
subroutine, public neighbor_list_iterator_release(iterator_set)
...
integer function, public neighbor_list_iterate(iterator_set, mepos)
...
subroutine, public get_iterator_info(iterator_set, mepos, ikind, jkind, nkind, ilist, nlist, inode, nnode, iatom, jatom, r, cell)
...
subroutine, public rrc_xyz_der_ao(op, op_der, qs_env, rc, order, minimum_image, soft)
Calculation of the multipole operators integrals and of its derivatives of the type [\mu | op | d(\nu...
subroutine, public build_lin_mom_matrix(qs_env, matrix)
Calculation of the linear momentum matrix <mu|∂|nu> over Cartesian Gaussian functions.
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
types that represent a quickstep subsys
subroutine, public qs_subsys_get(subsys, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell, energy, force, qs_kind_set, cp_subsys, nelectron_total, nelectron_spin)
...
subroutine, public rs_grid_create(rs, desc)
...
subroutine, public rs_grid_mult_and_add(rs1, rs2, rs3, scalar)
rs1(i) = rs1(i) + rs2(i)*rs3(i)
subroutine, public rs_grid_release(rs_grid)
releases the given rs grid (see doc/ReferenceCounting.html)
subroutine, public rs_grid_zero(rs)
Initialize grid to zero.
Transfers densities from PW to RS grids and potentials from PW to RS.
subroutine, public density_rs2pw(pw_env, rs_rho, rho, rho_gspace)
given partial densities on the realspace multigrids, computes the full density on the plane wave grid...
generate the tasks lists used by collocate and integrate routines
subroutine, public rs_distribute_matrix(rs_descs, pmats, atom_pair_send, atom_pair_recv, nimages, scatter, hmats)
redistributes the matrix so that it can be used in realspace operations i.e. according to the task li...
subroutine, public distribute_tasks(rs_descs, ntasks, natoms, tasks, atom_pair_send, atom_pair_recv, symmetric, reorder_rs_grid_ranks, skip_load_balance_distributed)
Assembles tasks to be performed on local grid.
subroutine, public task_list_inner_loop(tasks, ntasks, curr_tasks, rs_descs, dft_control, cube_info, gridlevel_info, cindex, iatom, jatom, rpgfa, rpgfb, zeta, zetb, kind_radius_b, set_radius_a, set_radius_b, ra, rab, la_max, la_min, lb_max, lb_min, npgfa, npgfb, nseta, nsetb)
...
types for task lists
subroutine, public reallocate_tasks(tasks, new_size)
Grow an array of tasks while preserving the existing entries.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
represent a pointer to a 2d array
represent a pointer to a 2d array
keeps the information about the structure of a full matrix
represent a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment
contained for different pw related things
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Provides all information about a quickstep kind.
container for the pools of matrixes used by qs