(git:ccc2433)
qs_linres_op.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief Calculate the operators p rxp and D needed in the optimization
10 !> of the different contribution of the firs order response orbitals
11 !> in a epr calculation
12 !> \note
13 !> The interactions are considered only within the minimum image convention
14 !> \par History
15 !> created 07-2005 [MI]
16 !> \author MI
17 ! **************************************************************************************************
19  USE cell_types, ONLY: cell_type,&
20  pbc
21  USE cp_array_utils, ONLY: cp_2d_i_p_type,&
22  cp_2d_r_p_type
24  USE cp_cfm_types, ONLY: cp_cfm_create,&
28  cp_cfm_type
29  USE cp_control_types, ONLY: dft_control_type
37  cp_fm_struct_type
38  USE cp_fm_types, ONLY: &
40  cp_fm_set_all, cp_fm_set_submatrix, cp_fm_to_fm, cp_fm_type
42  cp_logger_type,&
43  cp_to_string
46  USE dbcsr_api, ONLY: &
47  dbcsr_checksum, dbcsr_convert_offsets_to_sizes, dbcsr_copy, dbcsr_create, &
48  dbcsr_deallocate_matrix, dbcsr_distribution_type, dbcsr_get_block_p, &
49  dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, dbcsr_iterator_start, &
50  dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_p_type, dbcsr_set, dbcsr_type, &
51  dbcsr_type_antisymmetric, dbcsr_type_no_symmetry
53  section_vals_type
54  USE kinds, ONLY: dp
55  USE mathconstants, ONLY: twopi
56  USE message_passing, ONLY: mp_para_env_type
57  USE orbital_pointers, ONLY: coset
58  USE parallel_gemm_api, ONLY: parallel_gemm
60  USE particle_types, ONLY: particle_type
62  USE qs_environment_types, ONLY: get_qs_env,&
63  qs_environment_type
65  USE qs_kind_types, ONLY: get_qs_kind_set,&
66  qs_kind_type
67  USE qs_linres_types, ONLY: current_env_type,&
69  get_issc_env,&
71  issc_env_type,&
72  linres_control_type,&
73  polar_env_type
74  USE qs_mo_types, ONLY: get_mo_set,&
75  mo_set_type
78  USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
83 #include "./base/base_uses.f90"
84 
85  IMPLICIT NONE
86 
87  PRIVATE
90 
91  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_linres_op'
92 
93 ! **************************************************************************************************
94 
95 CONTAINS
96 
97 ! **************************************************************************************************
98 !> \brief Calculate the first order hamiltonian applied to the ao
99 !> and then apply them to the ground state orbitals,
100 !> the h1_psi1 full matrices are then ready to solve the
101 !> non-homogeneous linear equations that give the psi1
102 !> linear response orbitals.
103 !> \param current_env ...
104 !> \param qs_env ...
105 !> \par History
106 !> 07.2005 created [MI]
107 !> \author MI
108 !> \note
109 !> For the operators rxp and D the h1 depends on the psi0 to which
110 !> is applied, or better the center of charge of the psi0 is
111 !> used to define the position operator
112 !> The centers of the orbitals result form the orbital localization procedure
113 !> that typically uses the berry phase operator to define the Wannier centers.
114 ! **************************************************************************************************
115  SUBROUTINE current_operators(current_env, qs_env)
116 
117  TYPE(current_env_type) :: current_env
118  TYPE(qs_environment_type), POINTER :: qs_env
119 
120  CHARACTER(LEN=*), PARAMETER :: routinen = 'current_operators'
121 
122  INTEGER :: handle, iao, icenter, idir, ii, iii, &
123  ispin, istate, j, nao, natom, &
124  nbr_center(2), nmo, nsgf, nspins, &
125  nstates(2), output_unit
126  INTEGER, ALLOCATABLE, DIMENSION(:) :: first_sgf, last_sgf
127  INTEGER, DIMENSION(:), POINTER :: row_blk_sizes
128  REAL(dp) :: chk(3), ck(3), ckdk(3), dk(3)
129  REAL(dp), DIMENSION(:, :), POINTER :: basisfun_center, vecbuf_c0
130  TYPE(cell_type), POINTER :: cell
131  TYPE(cp_2d_i_p_type), DIMENSION(:), POINTER :: center_list
132  TYPE(cp_2d_r_p_type), DIMENSION(3) :: vecbuf_rmdc0
133  TYPE(cp_2d_r_p_type), DIMENSION(:), POINTER :: centers_set
134  TYPE(cp_fm_struct_type), POINTER :: tmp_fm_struct
135  TYPE(cp_fm_type) :: fm_work1
136  TYPE(cp_fm_type), DIMENSION(3) :: fm_rmd_mos
137  TYPE(cp_fm_type), DIMENSION(:), POINTER :: psi0_order
138  TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: p_psi0, rxp_psi0
139  TYPE(cp_fm_type), POINTER :: mo_coeff
140  TYPE(cp_logger_type), POINTER :: logger
141  TYPE(dbcsr_distribution_type), POINTER :: dbcsr_dist
142  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: op_ao
143  TYPE(dft_control_type), POINTER :: dft_control
144  TYPE(linres_control_type), POINTER :: linres_control
145  TYPE(mp_para_env_type), POINTER :: para_env
146  TYPE(neighbor_list_set_p_type), DIMENSION(:), &
147  POINTER :: sab_all, sab_orb
148  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
149  TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
150  TYPE(section_vals_type), POINTER :: lr_section
151 
152  CALL timeset(routinen, handle)
153 
154  NULLIFY (qs_kind_set, cell, dft_control, linres_control, &
155  logger, particle_set, lr_section, &
156  basisfun_center, centers_set, center_list, p_psi0, &
157  rxp_psi0, vecbuf_c0, psi0_order, &
158  mo_coeff, op_ao, sab_all)
159 
160  logger => cp_get_default_logger()
161  lr_section => section_vals_get_subs_vals(qs_env%input, &
162  "PROPERTIES%LINRES")
163 
164  output_unit = cp_print_key_unit_nr(logger, lr_section, "PRINT%PROGRAM_RUN_INFO", &
165  extension=".linresLog")
166  IF (output_unit > 0) THEN
167  WRITE (output_unit, fmt="(T2,A,/)") &
168  "CURRENT| Calculation of the p and (r-d)xp operators applied to psi0"
169  END IF
170 
171  CALL get_qs_env(qs_env=qs_env, &
172  qs_kind_set=qs_kind_set, &
173  cell=cell, &
174  dft_control=dft_control, &
175  linres_control=linres_control, &
176  para_env=para_env, &
177  particle_set=particle_set, &
178  sab_all=sab_all, &
179  sab_orb=sab_orb, &
180  dbcsr_dist=dbcsr_dist)
181 
182  nspins = dft_control%nspins
183 
184  CALL get_current_env(current_env=current_env, nao=nao, centers_set=centers_set, &
185  center_list=center_list, basisfun_center=basisfun_center, &
186  nbr_center=nbr_center, p_psi0=p_psi0, rxp_psi0=rxp_psi0, &
187  psi0_order=psi0_order, &
188  nstates=nstates)
189 
190  ALLOCATE (vecbuf_c0(1, nao))
191  DO idir = 1, 3
192  NULLIFY (vecbuf_rmdc0(idir)%array)
193  ALLOCATE (vecbuf_rmdc0(idir)%array(1, nao))
194  END DO
195 
196  CALL get_qs_kind_set(qs_kind_set=qs_kind_set, nsgf=nsgf)
197 
198  natom = SIZE(particle_set, 1)
199  ALLOCATE (first_sgf(natom))
200  ALLOCATE (last_sgf(natom))
201 
202  CALL get_particle_set(particle_set, qs_kind_set, &
203  first_sgf=first_sgf, &
204  last_sgf=last_sgf)
205 
206  ! Calculate the (r - dk)xp operator applied to psi0k
207  ! One possible way to go is to use the distributive property of the vector product and calculatr
208  ! (r-c)xp + (c-d)xp
209  ! where c depends on the contracted functions and not on the states
210  ! d is the center of a specific state and a loop over states is needed
211  ! the second term can be added in a second moment as a correction
212  ! notice: (r-c) and p are operators, whereas (c-d) is a multiplicative factor
213 
214  ! !First term: operator matrix elements
215  ! CALL rmc_x_p_xyz_ao(op_rmd_ao,qs_env,minimum_image=.FALSE.)
216  !************************************************************
217  !
218  ! Since many psi0 vector can have the same center, depending on how the center is selected,
219  ! the (r - dk)xp operator matrix is computed Ncenter times,
220  ! where Ncenter is the total number of different centers
221  ! and each time it is multiplied by all the psi0 with center dk to get the rxp_psi0 matrix
222 
223  !
224  ! prepare for allocation
225  ALLOCATE (row_blk_sizes(natom))
226  CALL dbcsr_convert_offsets_to_sizes(first_sgf, row_blk_sizes, last_sgf)
227  !
228  !
229  CALL dbcsr_allocate_matrix_set(op_ao, 3)
230  ALLOCATE (op_ao(1)%matrix, op_ao(2)%matrix, op_ao(3)%matrix)
231 
232  CALL dbcsr_create(matrix=op_ao(1)%matrix, &
233  name="op_ao", &
234  dist=dbcsr_dist, matrix_type=dbcsr_type_no_symmetry, &
235  row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
236  nze=0, mutable_work=.true.)
237  CALL cp_dbcsr_alloc_block_from_nbl(op_ao(1)%matrix, sab_all)
238  CALL dbcsr_set(op_ao(1)%matrix, 0.0_dp)
239 
240  DO idir = 2, 3
241  CALL dbcsr_copy(op_ao(idir)%matrix, op_ao(1)%matrix, &
242  "op_ao"//"-"//trim(adjustl(cp_to_string(idir))))
243  CALL dbcsr_set(op_ao(idir)%matrix, 0.0_dp)
244  END DO
245 
246  chk(:) = 0.0_dp
247  DO ispin = 1, nspins
248  mo_coeff => psi0_order(ispin)
249  nmo = nstates(ispin)
250  CALL cp_fm_set_all(p_psi0(ispin, 1), 0.0_dp)
251  CALL cp_fm_set_all(p_psi0(ispin, 2), 0.0_dp)
252  CALL cp_fm_set_all(p_psi0(ispin, 3), 0.0_dp)
253  DO icenter = 1, nbr_center(ispin)
254  CALL dbcsr_set(op_ao(1)%matrix, 0.0_dp)
255  CALL dbcsr_set(op_ao(2)%matrix, 0.0_dp)
256  CALL dbcsr_set(op_ao(3)%matrix, 0.0_dp)
257  !CALL rmc_x_p_xyz_ao(op_ao,qs_env,minimum_image=.FALSE.,&
258  ! & wancen=centers_set(ispin)%array(1:3,icenter))
259  ! &
260  CALL build_ang_mom_matrix(qs_env, op_ao, centers_set(ispin)%array(1:3, icenter))
261  !
262  ! accumulate checksums
263  chk(1) = chk(1) + dbcsr_checksum(op_ao(1)%matrix)
264  chk(2) = chk(2) + dbcsr_checksum(op_ao(2)%matrix)
265  chk(3) = chk(3) + dbcsr_checksum(op_ao(3)%matrix)
266  DO idir = 1, 3
267  CALL cp_fm_set_all(rxp_psi0(ispin, idir), 0.0_dp)
268  CALL cp_dbcsr_sm_fm_multiply(op_ao(idir)%matrix, mo_coeff, &
269  rxp_psi0(ispin, idir), ncol=nmo, &
270  alpha=-1.0_dp)
271  DO j = center_list(ispin)%array(1, icenter), center_list(ispin)%array(1, icenter + 1) - 1
272  istate = center_list(ispin)%array(2, j)
273  ! the p_psi0 fm is used as temporary matrix to store the results for the psi0 centered in dk
274  CALL cp_fm_to_fm(rxp_psi0(ispin, idir), &
275  p_psi0(ispin, idir), 1, istate, istate)
276  END DO
277  END DO
278  END DO
279  CALL cp_fm_to_fm(p_psi0(ispin, 1), rxp_psi0(ispin, 1))
280  CALL cp_fm_to_fm(p_psi0(ispin, 2), rxp_psi0(ispin, 2))
281  CALL cp_fm_to_fm(p_psi0(ispin, 3), rxp_psi0(ispin, 3))
282  END DO
283  !
284  CALL dbcsr_deallocate_matrix_set(op_ao)
285  !
286  ! print checksums
287  IF (output_unit > 0) THEN
288  WRITE (output_unit, '(T2,A,E23.16)') 'CURRENT| current_operators: CheckSum L_x =', chk(1)
289  WRITE (output_unit, '(T2,A,E23.16)') 'CURRENT| current_operators: CheckSum L_y =', chk(2)
290  WRITE (output_unit, '(T2,A,E23.16)') 'CURRENT| current_operators: CheckSum L_z =', chk(3)
291  END IF
292  !
293  ! Calculate the px py pz operators
294  CALL dbcsr_allocate_matrix_set(op_ao, 3)
295  ALLOCATE (op_ao(1)%matrix, op_ao(2)%matrix, op_ao(3)%matrix)
296 
297  CALL dbcsr_create(matrix=op_ao(1)%matrix, &
298  name="op_ao", &
299  dist=dbcsr_dist, matrix_type=dbcsr_type_antisymmetric, &
300  row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
301  nze=0, mutable_work=.true.)
302  CALL cp_dbcsr_alloc_block_from_nbl(op_ao(1)%matrix, sab_orb)
303  CALL dbcsr_set(op_ao(1)%matrix, 0.0_dp)
304 
305  DO idir = 2, 3
306  CALL dbcsr_copy(op_ao(idir)%matrix, op_ao(1)%matrix, &
307  "op_ao"//"-"//trim(adjustl(cp_to_string(idir))))
308  CALL dbcsr_set(op_ao(idir)%matrix, 0.0_dp)
309  END DO
310  !
311  CALL build_lin_mom_matrix(qs_env, op_ao)
312  !CALL p_xyz_ao(op_ao,qs_env,minimum_image=.FALSE.)
313  !
314  ! print checksums
315  chk(1) = dbcsr_checksum(op_ao(1)%matrix)
316  chk(2) = dbcsr_checksum(op_ao(2)%matrix)
317  chk(3) = dbcsr_checksum(op_ao(3)%matrix)
318  IF (output_unit > 0) THEN
319  WRITE (output_unit, '(T2,A,E23.16)') 'CURRENT| current_operators: CheckSum P_x =', chk(1)
320  WRITE (output_unit, '(T2,A,E23.16)') 'CURRENT| current_operators: CheckSum P_y =', chk(2)
321  WRITE (output_unit, '(T2,A,E23.16)') 'CURRENT| current_operators: CheckSum P_z =', chk(3)
322  END IF
323  ! Apply the p operator to the psi0
324  DO idir = 1, 3
325  DO ispin = 1, nspins
326  mo_coeff => psi0_order(ispin)
327  nmo = nstates(ispin)
328  CALL cp_fm_set_all(p_psi0(ispin, idir), 0.0_dp)
329  CALL cp_dbcsr_sm_fm_multiply(op_ao(idir)%matrix, mo_coeff, &
330  p_psi0(ispin, idir), ncol=nmo, &
331  alpha=-1.0_dp)
332  END DO
333  END DO
334  !
335  CALL dbcsr_deallocate_matrix_set(op_ao)
336  !
337  CALL cp_print_key_finished_output(output_unit, logger, lr_section, &
338  "PRINT%PROGRAM_RUN_INFO")
339 
340 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
341  ! This part is not necessary with the present implementation
342  ! the angular momentum operator is computed directly for each dk independently
343  ! and multiplied by the proper psi0 (i.e. those centered in dk)
344  ! If Wannier centers are used, and no grouping of states with close centers is applied
345  ! the (r-dk)xp operator is computed Nstate times and each time applied to only one vector psi0
346  !
347  ! Apply the (r-c)xp operator to the psi0
348  !DO ispin = 1,nspins
349  ! CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nmo=nmo, homo=homo)
350  ! DO idir = 1,3
351  ! CALL cp_fm_set_all(rxp_psi0(ispin,idir),0.0_dp)
352  ! CALL cp_sm_fm_multiply(op_rmd_ao(idir)%matrix,mo_coeff,&
353  ! rxp_psi0(ispin,idir),ncol=nmo,alpha=-1.0_dp)
354  ! END DO
355  !END DO
356 
357  !Calculate the second term of the operator state by state
358  !!!! what follows is a way to avoid calculating the L matrix for each centers.
359  !!!! not tested
360  IF (.false.) THEN
361  DO ispin = 1, nspins
362  ! Allocate full matrices as working storage in the calculation
363  ! of the rxp operator matrix. 3 matrices for the 3 Cartesian direction
364  ! plus one to apply the momentum oprator to the modified mos fm
365  mo_coeff => psi0_order(ispin)
366  nmo = nstates(ispin)
367  NULLIFY (tmp_fm_struct)
368  CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nao, &
369  ncol_global=nmo, para_env=para_env, &
370  context=mo_coeff%matrix_struct%context)
371  DO idir = 1, 3
372  CALL cp_fm_create(fm_rmd_mos(idir), tmp_fm_struct)
373  END DO
374  CALL cp_fm_create(fm_work1, tmp_fm_struct)
375  CALL cp_fm_struct_release(tmp_fm_struct)
376 
377  ! This part should be done better, using the full matrix distribution
378  DO istate = 1, nmo
379  CALL cp_fm_get_submatrix(psi0_order(ispin), vecbuf_c0, 1, istate, nao, 1, &
380  transpose=.true.)
381  !center of the localized psi0 state istate
382  dk(1:3) = centers_set(ispin)%array(1:3, istate)
383  DO idir = 1, 3
384  ! This loop should be distributed over the processors
385  DO iao = 1, nao
386  ck(1:3) = basisfun_center(1:3, iao)
387  ckdk = pbc(dk, ck, cell)
388  vecbuf_rmdc0(idir)%array(1, iao) = vecbuf_c0(1, iao)*ckdk(idir)
389  END DO ! iao
390  CALL cp_fm_set_submatrix(fm_rmd_mos(idir), vecbuf_rmdc0(idir)%array, &
391  1, istate, nao, 1, transpose=.true.)
392  END DO ! idir
393  END DO ! istate
394 
395  DO idir = 1, 3
396  CALL set_vecp(idir, ii, iii)
397 
398  !Add the second term to the idir component
399  CALL cp_fm_set_all(fm_work1, 0.0_dp)
400  CALL cp_dbcsr_sm_fm_multiply(op_ao(iii)%matrix, fm_rmd_mos(ii), &
401  fm_work1, ncol=nmo, alpha=-1.0_dp)
402  CALL cp_fm_scale_and_add(1.0_dp, rxp_psi0(ispin, idir), &
403  1.0_dp, fm_work1)
404 
405  CALL cp_fm_set_all(fm_work1, 0.0_dp)
406  CALL cp_dbcsr_sm_fm_multiply(op_ao(ii)%matrix, fm_rmd_mos(iii), &
407  fm_work1, ncol=nmo, alpha=-1.0_dp)
408  CALL cp_fm_scale_and_add(1.0_dp, rxp_psi0(ispin, idir), &
409  -1.0_dp, fm_work1)
410 
411  END DO ! idir
412 
413  DO idir = 1, 3
414  CALL cp_fm_release(fm_rmd_mos(idir))
415  END DO
416  CALL cp_fm_release(fm_work1)
417 
418  END DO ! ispin
419  END IF
420 
421  DEALLOCATE (row_blk_sizes)
422 
423  DEALLOCATE (first_sgf, last_sgf)
424 
425  DEALLOCATE (vecbuf_c0)
426  DO idir = 1, 3
427  DEALLOCATE (vecbuf_rmdc0(idir)%array)
428  END DO
429 
430  CALL timestop(handle)
431 
432  END SUBROUTINE current_operators
433 
434 ! **************************************************************************************************
435 !> \brief ...
436 !> \param issc_env ...
437 !> \param qs_env ...
438 !> \param iatom ...
439 ! **************************************************************************************************
440  SUBROUTINE issc_operators(issc_env, qs_env, iatom)
441 
442  TYPE(issc_env_type) :: issc_env
443  TYPE(qs_environment_type), POINTER :: qs_env
444  INTEGER, INTENT(IN) :: iatom
445 
446  CHARACTER(LEN=*), PARAMETER :: routinen = 'issc_operators'
447 
448  INTEGER :: handle, idir, ispin, nmo, nspins, &
449  output_unit
450  LOGICAL :: do_dso, do_fc, do_pso, do_sd
451  REAL(dp) :: chk(20), r_i(3)
452  TYPE(cell_type), POINTER :: cell
453  TYPE(cp_fm_type), DIMENSION(:), POINTER :: fc_psi0
454  TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: dso_psi0, efg_psi0, pso_psi0
455  TYPE(cp_fm_type), POINTER :: mo_coeff
456  TYPE(cp_logger_type), POINTER :: logger
457  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_dso, matrix_efg, matrix_fc, &
458  matrix_pso
459  TYPE(dft_control_type), POINTER :: dft_control
460  TYPE(linres_control_type), POINTER :: linres_control
461  TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
462  TYPE(mp_para_env_type), POINTER :: para_env
463  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
464  TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
465  TYPE(section_vals_type), POINTER :: lr_section
466 
467  CALL timeset(routinen, handle)
468 
469  NULLIFY (matrix_fc, matrix_pso, matrix_efg)
470  NULLIFY (efg_psi0, pso_psi0, fc_psi0)
471 
472  logger => cp_get_default_logger()
473  lr_section => section_vals_get_subs_vals(qs_env%input, &
474  "PROPERTIES%LINRES")
475 
476  output_unit = cp_print_key_unit_nr(logger, lr_section, "PRINT%PROGRAM_RUN_INFO", &
477  extension=".linresLog")
478 
479  CALL get_qs_env(qs_env=qs_env, &
480  qs_kind_set=qs_kind_set, &
481  cell=cell, &
482  dft_control=dft_control, &
483  linres_control=linres_control, &
484  para_env=para_env, &
485  mos=mos, &
486  particle_set=particle_set)
487 
488  nspins = dft_control%nspins
489 
490  CALL get_issc_env(issc_env=issc_env, &
491  matrix_efg=matrix_efg, & !this is used only here alloc/dealloc here???
492  matrix_pso=matrix_pso, & !this is used only here alloc/dealloc here???
493  matrix_fc=matrix_fc, & !this is used only here alloc/dealloc here???
494  matrix_dso=matrix_dso, & !this is used only here alloc/dealloc here???
495  efg_psi0=efg_psi0, &
496  pso_psi0=pso_psi0, &
497  dso_psi0=dso_psi0, &
498  fc_psi0=fc_psi0, &
499  do_fc=do_fc, &
500  do_sd=do_sd, &
501  do_pso=do_pso, &
502  do_dso=do_dso)
503  !
504  !
505  r_i = particle_set(iatom)%r !pbc(particle_set(iatom)%r,cell)
506  !write(*,*) 'issc_operators iatom=',iatom,' r_i=',r_i
507  chk = 0.0_dp
508  !
509  !
510  !
511  ! Fermi contact integral
512  !IF(do_fc) THEN
513  IF (.true.) THEN ! for the moment we build it (regs)
514  CALL dbcsr_set(matrix_fc(1)%matrix, 0.0_dp)
515  CALL build_fermi_contact_matrix(qs_env, matrix_fc, r_i)
516 
517  chk(1) = dbcsr_checksum(matrix_fc(1)%matrix)
518 
519  IF (output_unit > 0) THEN
520  WRITE (output_unit, '(T2,A,E23.16)') 'ISSC| fermi_contact: CheckSum =', chk(1)
521  END IF
522  END IF
523  !
524  ! spin-orbit integral
525  !IF(do_pso) THEN
526  IF (.true.) THEN ! for the moment we build it (regs)
527  CALL dbcsr_set(matrix_pso(1)%matrix, 0.0_dp)
528  CALL dbcsr_set(matrix_pso(2)%matrix, 0.0_dp)
529  CALL dbcsr_set(matrix_pso(3)%matrix, 0.0_dp)
530  CALL build_pso_matrix(qs_env, matrix_pso, r_i)
531 
532  chk(2) = dbcsr_checksum(matrix_pso(1)%matrix)
533  chk(3) = dbcsr_checksum(matrix_pso(2)%matrix)
534  chk(4) = dbcsr_checksum(matrix_pso(3)%matrix)
535 
536  IF (output_unit > 0) THEN
537  WRITE (output_unit, '(T2,A,E23.16)') 'ISSC| pso_x: CheckSum =', chk(2)
538  WRITE (output_unit, '(T2,A,E23.16)') 'ISSC| pso_y: CheckSum =', chk(3)
539  WRITE (output_unit, '(T2,A,E23.16)') 'ISSC| pso_z: CheckSum =', chk(4)
540  END IF
541  END IF
542  !
543  ! electric field integral
544  !IF(do_sd) THEN
545  IF (.true.) THEN ! for the moment we build it (regs)
546  CALL dbcsr_set(matrix_efg(1)%matrix, 0.0_dp)
547  CALL dbcsr_set(matrix_efg(2)%matrix, 0.0_dp)
548  CALL dbcsr_set(matrix_efg(3)%matrix, 0.0_dp)
549  CALL dbcsr_set(matrix_efg(4)%matrix, 0.0_dp)
550  CALL dbcsr_set(matrix_efg(5)%matrix, 0.0_dp)
551  CALL dbcsr_set(matrix_efg(6)%matrix, 0.0_dp)
552  CALL build_efg_matrix(qs_env, matrix_efg, r_i)
553 
554  chk(5) = dbcsr_checksum(matrix_efg(1)%matrix)
555  chk(6) = dbcsr_checksum(matrix_efg(2)%matrix)
556  chk(7) = dbcsr_checksum(matrix_efg(3)%matrix)
557  chk(8) = dbcsr_checksum(matrix_efg(4)%matrix)
558  chk(9) = dbcsr_checksum(matrix_efg(5)%matrix)
559  chk(10) = dbcsr_checksum(matrix_efg(6)%matrix)
560 
561  IF (output_unit > 0) THEN
562  WRITE (output_unit, '(T2,A,E23.16)') 'ISSC| efg (3xx-rr)/3: CheckSum =', chk(5)
563  WRITE (output_unit, '(T2,A,E23.16)') 'ISSC| efg (3yy-rr)/3: CheckSum =', chk(6)
564  WRITE (output_unit, '(T2,A,E23.16)') 'ISSC| efg (3zz-rr)/3: CheckSum =', chk(7)
565  WRITE (output_unit, '(T2,A,E23.16)') 'ISSC| efg xy: CheckSum =', chk(8)
566  WRITE (output_unit, '(T2,A,E23.16)') 'ISSC| efg xz: CheckSum =', chk(9)
567  WRITE (output_unit, '(T2,A,E23.16)') 'ISSC| efg yz: CheckSum =', chk(10)
568  END IF
569  END IF
570  !
571  !
572  IF (output_unit > 0) THEN
573  WRITE (output_unit, '(T2,A,E23.16)') 'ISSC| all operator: CheckSum =', sum(chk(1:10))
574  END IF
575  !
576  !>>> debugging only here we build the dipole matrix... debugging the kernel...
577  IF (do_dso) THEN
578  CALL dbcsr_set(matrix_dso(1)%matrix, 0.0_dp)
579  CALL dbcsr_set(matrix_dso(2)%matrix, 0.0_dp)
580  CALL dbcsr_set(matrix_dso(3)%matrix, 0.0_dp)
581  CALL rrc_xyz_ao(matrix_dso, qs_env, (/0.0_dp, 0.0_dp, 0.0_dp/), 1)
582  END IF
583  !
584  ! multiply by the mos
585  DO ispin = 1, nspins
586  !
587  CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff)
588  CALL cp_fm_get_info(mo_coeff, ncol_global=nmo)
589  !
590  ! EFG
591  IF (do_sd) THEN
592  DO idir = 1, 6
593  CALL cp_dbcsr_sm_fm_multiply(matrix_efg(idir)%matrix, mo_coeff, &
594  efg_psi0(ispin, idir), ncol=nmo, &
595  alpha=1.0_dp)
596  END DO
597  END IF
598  !
599  ! PSO
600  IF (do_pso) THEN
601  DO idir = 1, 3
602  CALL cp_dbcsr_sm_fm_multiply(matrix_pso(idir)%matrix, mo_coeff, &
603  pso_psi0(ispin, idir), ncol=nmo, &
604  alpha=-1.0_dp)
605  END DO
606  END IF
607  !
608  ! FC
609  IF (do_fc) THEN
610  CALL cp_dbcsr_sm_fm_multiply(matrix_fc(1)%matrix, mo_coeff, &
611  fc_psi0(ispin), ncol=nmo, &
612  alpha=1.0_dp)
613  END IF
614  !
615  !>>> for debugging only
616  IF (do_dso) THEN
617  DO idir = 1, 3
618  CALL cp_dbcsr_sm_fm_multiply(matrix_dso(idir)%matrix, mo_coeff, &
619  dso_psi0(ispin, idir), ncol=nmo, &
620  alpha=-1.0_dp)
621  END DO
622  END IF
623  !<<< for debugging only
624  END DO
625 
626  CALL cp_print_key_finished_output(output_unit, logger, lr_section, &
627  "PRINT%PROGRAM_RUN_INFO")
628 
629  CALL timestop(handle)
630 
631  END SUBROUTINE issc_operators
632 
633 ! **************************************************************************************************
634 !> \brief Calculate the dipole operator in the AO basis and its derivative wrt to MOs
635 !>
636 !> \param qs_env ...
637 ! **************************************************************************************************
638  SUBROUTINE polar_operators(qs_env)
639 
640  TYPE(qs_environment_type), POINTER :: qs_env
641 
642  LOGICAL :: do_periodic
643  TYPE(dft_control_type), POINTER :: dft_control
644  TYPE(polar_env_type), POINTER :: polar_env
645 
646  CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, polar_env=polar_env)
647  CALL get_polar_env(polar_env=polar_env, do_periodic=do_periodic)
648  IF (dft_control%qs_control%dftb .OR. dft_control%qs_control%xtb) THEN
649  IF (do_periodic) THEN
650  CALL polar_tb_operators_berry(qs_env)
651  ELSE
652  CALL polar_tb_operators_local(qs_env)
653  END IF
654  ELSE
655  IF (do_periodic) THEN
656  CALL polar_operators_berry(qs_env)
657  ELSE
658  CALL polar_operators_local(qs_env)
659  END IF
660  END IF
661 
662  END SUBROUTINE polar_operators
663 
664 ! **************************************************************************************************
665 !> \brief Calculate the Berry phase operator in the AO basis and
666 !> then the derivative of the Berry phase operator with respect to
667 !> the ground state wave function (see paper Putrino et al., JCP, 13, 7102) for the AOs;
668 !> afterwards multiply with the ground state MO coefficients
669 !>
670 !> \param qs_env ...
671 !> \par History
672 !> 01.2013 created [SL]
673 !> 06.2018 polar_env integrated into qs_env (MK)
674 !> \author SL
675 ! **************************************************************************************************
676 
677  SUBROUTINE polar_operators_berry(qs_env)
678 
679  TYPE(qs_environment_type), POINTER :: qs_env
680 
681  CHARACTER(LEN=*), PARAMETER :: routinen = 'polar_operators_berry'
682  COMPLEX(KIND=dp), PARAMETER :: one = (1.0_dp, 0.0_dp), &
683  zero = (0.0_dp, 0.0_dp)
684 
685  COMPLEX(DP) :: zdet, zdeta
686  INTEGER :: handle, i, idim, ispin, nao, nmo, &
687  nspins, tmp_dim, z
688  LOGICAL :: do_raman
689  REAL(dp) :: kvec(3), maxocc
690  TYPE(cell_type), POINTER :: cell
691  TYPE(cp_cfm_type), ALLOCATABLE, DIMENSION(:) :: eigrmat
692  TYPE(cp_cfm_type), ALLOCATABLE, DIMENSION(:, :) :: inv_mat
693  TYPE(cp_fm_struct_type), POINTER :: tmp_fm_struct
694  TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: op_fm_set, opvec
695  TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :, :) :: inv_work
696  TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: dberry_psi0
697  TYPE(cp_fm_type), POINTER :: mo_coeff
698  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
699  TYPE(dbcsr_type), POINTER :: cosmat, sinmat
700  TYPE(dft_control_type), POINTER :: dft_control
701  TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
702  TYPE(mp_para_env_type), POINTER :: para_env
703  TYPE(polar_env_type), POINTER :: polar_env
704 
705  CALL timeset(routinen, handle)
706 
707  NULLIFY (dberry_psi0, sinmat, cosmat)
708  NULLIFY (polar_env)
709 
710  NULLIFY (cell, dft_control, mos, matrix_s)
711  CALL get_qs_env(qs_env=qs_env, &
712  cell=cell, &
713  dft_control=dft_control, &
714  para_env=para_env, &
715  polar_env=polar_env, &
716  mos=mos, &
717  matrix_s=matrix_s)
718 
719  nspins = dft_control%nspins
720 
721  CALL get_polar_env(polar_env=polar_env, &
722  do_raman=do_raman, &
723  dberry_psi0=dberry_psi0)
724  !SL calculate dipole berry phase
725  IF (do_raman) THEN
726 
727  DO i = 1, 3
728  DO ispin = 1, nspins
729  CALL cp_fm_set_all(dberry_psi0(i, ispin), 0.0_dp)
730  END DO
731  END DO
732 
733  ! initialize all work matrices needed
734  ALLOCATE (opvec(2, dft_control%nspins))
735  ALLOCATE (op_fm_set(2, dft_control%nspins))
736  ALLOCATE (eigrmat(dft_control%nspins))
737  ALLOCATE (inv_mat(3, dft_control%nspins))
738  ALLOCATE (inv_work(2, 3, dft_control%nspins))
739 
740  ! A bit to allocate for the wavefunction
741  DO ispin = 1, dft_control%nspins
742  NULLIFY (tmp_fm_struct, mo_coeff)
743  CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, nao=nao, nmo=nmo)
744  CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nmo, &
745  ncol_global=nmo, para_env=para_env, context=mo_coeff%matrix_struct%context)
746  DO i = 1, SIZE(op_fm_set, 1)
747  CALL cp_fm_create(opvec(i, ispin), mo_coeff%matrix_struct)
748  CALL cp_fm_create(op_fm_set(i, ispin), tmp_fm_struct)
749  END DO
750  CALL cp_cfm_create(eigrmat(ispin), op_fm_set(1, ispin)%matrix_struct)
751  CALL cp_fm_struct_release(tmp_fm_struct)
752  DO i = 1, 3
753  CALL cp_cfm_create(inv_mat(i, ispin), op_fm_set(1, ispin)%matrix_struct)
754  CALL cp_fm_create(inv_work(2, i, ispin), op_fm_set(2, ispin)%matrix_struct)
755  CALL cp_fm_create(inv_work(1, i, ispin), op_fm_set(1, ispin)%matrix_struct)
756  END DO
757  END DO
758 
759  NULLIFY (cosmat, sinmat)
760  ALLOCATE (cosmat, sinmat)
761  CALL dbcsr_copy(cosmat, matrix_s(1)%matrix, 'COS MOM')
762  CALL dbcsr_copy(sinmat, matrix_s(1)%matrix, 'SIN MOM')
763 
764  DO i = 1, 3
765  kvec(:) = twopi*cell%h_inv(i, :)
766  CALL dbcsr_set(cosmat, 0.0_dp)
767  CALL dbcsr_set(sinmat, 0.0_dp)
768  CALL build_berry_moment_matrix(qs_env, cosmat, sinmat, kvec)
769 
770  DO ispin = 1, dft_control%nspins ! spin
771  CALL get_mo_set(mo_set=mos(ispin), nao=nao, mo_coeff=mo_coeff, nmo=nmo)
772 
773  CALL cp_dbcsr_sm_fm_multiply(cosmat, mo_coeff, opvec(1, ispin), ncol=nmo)
774  CALL parallel_gemm("T", "N", nmo, nmo, nao, 1.0_dp, mo_coeff, opvec(1, ispin), 0.0_dp, &
775  op_fm_set(1, ispin))
776  CALL cp_dbcsr_sm_fm_multiply(sinmat, mo_coeff, opvec(2, ispin), ncol=nmo)
777  CALL parallel_gemm("T", "N", nmo, nmo, nao, 1.0_dp, mo_coeff, opvec(2, ispin), 0.0_dp, &
778  op_fm_set(2, ispin))
779 
780  END DO
781 
782  ! Second step invert C^T S_berry C
783  zdet = one
784  DO ispin = 1, dft_control%nspins
785  CALL cp_cfm_get_info(eigrmat(ispin), ncol_local=tmp_dim)
786  DO idim = 1, tmp_dim
787  eigrmat(ispin)%local_data(:, idim) = &
788  cmplx(op_fm_set(1, ispin)%local_data(:, idim), &
789  -op_fm_set(2, ispin)%local_data(:, idim), dp)
790  END DO
791  CALL cp_cfm_set_all(inv_mat(i, ispin), zero, one)
792  CALL cp_cfm_solve(eigrmat(ispin), inv_mat(i, ispin), zdeta)
793  END DO
794 
795  ! Compute the derivative and add the result to mo_derivatives
796  DO ispin = 1, dft_control%nspins
797  CALL cp_cfm_get_info(eigrmat(ispin), ncol_local=tmp_dim)
798  CALL get_mo_set(mo_set=mos(ispin), nao=nao, nmo=nmo, maxocc=maxocc)
799  DO z = 1, tmp_dim
800  inv_work(1, i, ispin)%local_data(:, z) = real(inv_mat(i, ispin)%local_data(:, z), dp)
801  inv_work(2, i, ispin)%local_data(:, z) = aimag(inv_mat(i, ispin)%local_data(:, z))
802  END DO
803  CALL parallel_gemm("N", "N", nao, nmo, nmo, -1.0_dp, opvec(1, ispin), inv_work(2, i, ispin), &
804  0.0_dp, dberry_psi0(i, ispin))
805  CALL parallel_gemm("N", "N", nao, nmo, nmo, 1.0_dp, opvec(2, ispin), inv_work(1, i, ispin), &
806  1.0_dp, dberry_psi0(i, ispin))
807  END DO
808  END DO !x/y/z-direction
809  !SL we omit here the multiplication with hmat (this scaling back done at the end of the response calc)
810 
811  DO ispin = 1, dft_control%nspins
812  CALL cp_cfm_release(eigrmat(ispin))
813  DO i = 1, 3
814  CALL cp_cfm_release(inv_mat(i, ispin))
815  END DO
816  END DO
817  DEALLOCATE (inv_mat)
818  DEALLOCATE (eigrmat)
819 
820  CALL cp_fm_release(inv_work)
821  CALL cp_fm_release(opvec)
822  CALL cp_fm_release(op_fm_set)
823 
824  CALL dbcsr_deallocate_matrix(cosmat)
825  CALL dbcsr_deallocate_matrix(sinmat)
826 
827  END IF ! do_raman
828 
829  CALL timestop(handle)
830 
831  END SUBROUTINE polar_operators_berry
832 
833 ! **************************************************************************************************
834 !> \brief Calculate the Berry phase operator in the AO basis and
835 !> then the derivative of the Berry phase operator with respect to
836 !> the ground state wave function (see paper Putrino et al., JCP, 13, 7102) for the AOs;
837 !> afterwards multiply with the ground state MO coefficients
838 !>
839 !> \param qs_env ...
840 !> \par History
841 !> 01.2013 created [SL]
842 !> 06.2018 polar_env integrated into qs_env (MK)
843 !> 08.2020 adapt for xTB/DFTB (JHU)
844 !> \author SL
845 ! **************************************************************************************************
846 
847  SUBROUTINE polar_tb_operators_berry(qs_env)
848 
849  TYPE(qs_environment_type), POINTER :: qs_env
850 
851  CHARACTER(LEN=*), PARAMETER :: routinen = 'polar_tb_operators_berry'
852 
853  COMPLEX(dp) :: zdeta
854  INTEGER :: blk, handle, i, icol, idir, irow, ispin, &
855  nmo, nspins
856  LOGICAL :: do_raman, found
857  REAL(dp) :: dd, fdir
858  REAL(dp), DIMENSION(3) :: kvec, ria, rib
859  REAL(dp), DIMENSION(3, 3) :: hmat
860  REAL(dp), DIMENSION(:, :), POINTER :: d_block, s_block
861  TYPE(cell_type), POINTER :: cell
862  TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: dberry_psi0
863  TYPE(cp_fm_type), POINTER :: mo_coeff
864  TYPE(dbcsr_iterator_type) :: iter
865  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: dipmat, matrix_s
866  TYPE(dft_control_type), POINTER :: dft_control
867  TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
868  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
869  TYPE(polar_env_type), POINTER :: polar_env
870 
871  CALL timeset(routinen, handle)
872 
873  CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, &
874  cell=cell, particle_set=particle_set, &
875  polar_env=polar_env, mos=mos, matrix_s=matrix_s)
876 
877  nspins = dft_control%nspins
878 
879  CALL get_polar_env(polar_env=polar_env, &
880  do_raman=do_raman, &
881  dberry_psi0=dberry_psi0)
882 
883  IF (do_raman) THEN
884 
885  ALLOCATE (dipmat(3))
886  DO i = 1, 3
887  ALLOCATE (dipmat(i)%matrix)
888  CALL dbcsr_copy(dipmat(i)%matrix, matrix_s(1)%matrix, 'dipole')
889  CALL dbcsr_set(dipmat(i)%matrix, 0.0_dp)
890  END DO
891 
892  hmat = cell%hmat(:, :)/twopi
893 
894  CALL dbcsr_iterator_start(iter, matrix_s(1)%matrix)
895  DO WHILE (dbcsr_iterator_blocks_left(iter))
896  NULLIFY (s_block, d_block)
897  CALL dbcsr_iterator_next_block(iter, irow, icol, s_block, blk)
898  ria = particle_set(irow)%r
899  rib = particle_set(icol)%r
900  DO idir = 1, 3
901  kvec(:) = twopi*cell%h_inv(idir, :)
902  dd = sum(kvec(:)*ria(:))
903  zdeta = cmplx(cos(dd), sin(dd), kind=dp)
904  fdir = aimag(log(zdeta))
905  dd = sum(kvec(:)*rib(:))
906  zdeta = cmplx(cos(dd), sin(dd), kind=dp)
907  fdir = fdir + aimag(log(zdeta))
908  CALL dbcsr_get_block_p(matrix=dipmat(idir)%matrix, &
909  row=irow, col=icol, block=d_block, found=found)
910  cpassert(found)
911  d_block = d_block + 0.5_dp*fdir*s_block
912  END DO
913  END DO
914  CALL dbcsr_iterator_stop(iter)
915 
916  ! Compute the derivative and add the result to mo_derivatives
917  DO ispin = 1, dft_control%nspins ! spin
918  CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, nmo=nmo)
919  DO i = 1, 3
920  CALL cp_dbcsr_sm_fm_multiply(dipmat(i)%matrix, mo_coeff, &
921  dberry_psi0(i, ispin), ncol=nmo)
922  END DO !x/y/z-direction
923  END DO
924 
925  DO i = 1, 3
926  CALL dbcsr_deallocate_matrix(dipmat(i)%matrix)
927  END DO
928  DEALLOCATE (dipmat)
929 
930  END IF ! do_raman
931 
932  CALL timestop(handle)
933  END SUBROUTINE polar_tb_operators_berry
934 
935 ! **************************************************************************************************
936 !> \brief Calculate the Berry phase operator in the AO basis and
937 !> then the derivative of the Berry phase operator with respect to
938 !> the ground state wave function (see paper Putrino et al., JCP, 13, 7102) for the AOs;
939 !> afterwards multiply with the ground state MO coefficients
940 !>
941 !> \param qs_env ...
942 !> \par History
943 !> 01.2013 created [SL]
944 !> 06.2018 polar_env integrated into qs_env (MK)
945 !> \author SL
946 ! **************************************************************************************************
947  SUBROUTINE polar_operators_local(qs_env)
948 
949  TYPE(qs_environment_type), POINTER :: qs_env
950 
951  CHARACTER(LEN=*), PARAMETER :: routinen = 'polar_operators_local'
952 
953  INTEGER :: handle, i, ispin, nmo, nspins
954  LOGICAL :: do_raman
955  TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: dberry_psi0
956  TYPE(cp_fm_type), POINTER :: mo_coeff
957  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: dipmat, matrix_s
958  TYPE(dft_control_type), POINTER :: dft_control
959  TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
960  TYPE(polar_env_type), POINTER :: polar_env
961 
962  CALL timeset(routinen, handle)
963 
964  CALL get_qs_env(qs_env=qs_env, &
965  dft_control=dft_control, &
966  polar_env=polar_env, &
967  mos=mos, &
968  matrix_s=matrix_s)
969 
970  nspins = dft_control%nspins
971 
972  CALL get_polar_env(polar_env=polar_env, &
973  do_raman=do_raman, &
974  dberry_psi0=dberry_psi0)
975 
976  !SL calculate dipole berry phase
977  IF (do_raman) THEN
978 
979  ALLOCATE (dipmat(3))
980  DO i = 1, 3
981  ALLOCATE (dipmat(i)%matrix)
982  CALL dbcsr_copy(dipmat(i)%matrix, matrix_s(1)%matrix, 'dipole')
983  CALL dbcsr_set(dipmat(i)%matrix, 0.0_dp)
984  END DO
985  CALL build_local_moment_matrix(qs_env, dipmat, 1)
986 
987  ! Compute the derivative and add the result to mo_derivatives
988  DO ispin = 1, dft_control%nspins ! spin
989  CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, nmo=nmo)
990  DO i = 1, 3
991  CALL cp_dbcsr_sm_fm_multiply(dipmat(i)%matrix, mo_coeff, &
992  dberry_psi0(i, ispin), ncol=nmo)
993  END DO !x/y/z-direction
994  END DO
995 
996  DO i = 1, 3
997  CALL dbcsr_deallocate_matrix(dipmat(i)%matrix)
998  END DO
999  DEALLOCATE (dipmat)
1000 
1001  END IF ! do_raman
1002 
1003  CALL timestop(handle)
1004 
1005  END SUBROUTINE polar_operators_local
1006 
1007 ! **************************************************************************************************
1008 !> \brief Calculate the local dipole operator in the AO basis
1009 !> afterwards multiply with the ground state MO coefficients
1010 !>
1011 !> \param qs_env ...
1012 !> \par History
1013 !> 01.2013 created [SL]
1014 !> 06.2018 polar_env integrated into qs_env (MK)
1015 !> 08.2020 TB version (JHU)
1016 !> \author SL
1017 ! **************************************************************************************************
1018  SUBROUTINE polar_tb_operators_local(qs_env)
1019 
1020  TYPE(qs_environment_type), POINTER :: qs_env
1021 
1022  CHARACTER(LEN=*), PARAMETER :: routinen = 'polar_tb_operators_local'
1023 
1024  INTEGER :: blk, handle, i, icol, irow, ispin, nmo, &
1025  nspins
1026  LOGICAL :: do_raman, found
1027  REAL(dp) :: fdir
1028  REAL(dp), DIMENSION(3) :: ria, rib
1029  REAL(dp), DIMENSION(:, :), POINTER :: d_block, s_block
1030  TYPE(cell_type), POINTER :: cell
1031  TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: dberry_psi0
1032  TYPE(cp_fm_type), POINTER :: mo_coeff
1033  TYPE(dbcsr_iterator_type) :: iter
1034  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: dipmat, matrix_s
1035  TYPE(dft_control_type), POINTER :: dft_control
1036  TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
1037  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1038  TYPE(polar_env_type), POINTER :: polar_env
1039 
1040  CALL timeset(routinen, handle)
1041 
1042  CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, &
1043  cell=cell, particle_set=particle_set, &
1044  polar_env=polar_env, mos=mos, matrix_s=matrix_s)
1045 
1046  nspins = dft_control%nspins
1047 
1048  CALL get_polar_env(polar_env=polar_env, &
1049  do_raman=do_raman, &
1050  dberry_psi0=dberry_psi0)
1051 
1052  IF (do_raman) THEN
1053 
1054  ALLOCATE (dipmat(3))
1055  DO i = 1, 3
1056  ALLOCATE (dipmat(i)%matrix)
1057  CALL dbcsr_copy(dipmat(i)%matrix, matrix_s(1)%matrix, 'dipole')
1058  END DO
1059 
1060  CALL dbcsr_iterator_start(iter, matrix_s(1)%matrix)
1061  DO WHILE (dbcsr_iterator_blocks_left(iter))
1062  NULLIFY (s_block, d_block)
1063  CALL dbcsr_iterator_next_block(iter, irow, icol, s_block, blk)
1064  ria = particle_set(irow)%r
1065  ria = pbc(ria, cell)
1066  rib = particle_set(icol)%r
1067  rib = pbc(rib, cell)
1068  DO i = 1, 3
1069  CALL dbcsr_get_block_p(matrix=dipmat(i)%matrix, &
1070  row=irow, col=icol, block=d_block, found=found)
1071  cpassert(found)
1072  fdir = 0.5_dp*(ria(i) + rib(i))
1073  d_block = s_block*fdir
1074  END DO
1075  END DO
1076  CALL dbcsr_iterator_stop(iter)
1077 
1078  ! Compute the derivative and add the result to mo_derivatives
1079  DO ispin = 1, dft_control%nspins ! spin
1080  CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, nmo=nmo)
1081  DO i = 1, 3
1082  CALL cp_dbcsr_sm_fm_multiply(dipmat(i)%matrix, mo_coeff, &
1083  dberry_psi0(i, ispin), ncol=nmo)
1084  END DO !x/y/z-direction
1085  END DO
1086 
1087  DO i = 1, 3
1088  CALL dbcsr_deallocate_matrix(dipmat(i)%matrix)
1089  END DO
1090  DEALLOCATE (dipmat)
1091 
1092  END IF ! do_raman
1093 
1094  CALL timestop(handle)
1095 
1096  END SUBROUTINE polar_tb_operators_local
1097 
1098 ! **************************************************************************************************
1099 !> \brief ...
1100 !> \param a ...
1101 !> \param b ...
1102 !> \param c ...
1103 !> \return ...
1104 ! **************************************************************************************************
1105  FUNCTION fac_vecp(a, b, c) RESULT(factor)
1106 
1107  INTEGER :: a, b, c
1108  REAL(dp) :: factor
1109 
1110  factor = 0.0_dp
1111 
1112  IF ((b .EQ. a + 1 .OR. b .EQ. a - 2) .AND. (c .EQ. b + 1 .OR. c .EQ. b - 2)) THEN
1113  factor = 1.0_dp
1114  ELSEIF ((b .EQ. a - 1 .OR. b .EQ. a + 2) .AND. (c .EQ. b - 1 .OR. c .EQ. b + 2)) THEN
1115  factor = -1.0_dp
1116  END IF
1117 
1118  END FUNCTION fac_vecp
1119 
1120 ! **************************************************************************************************
1121 !> \brief ...
1122 !> \param ii ...
1123 !> \param iii ...
1124 !> \return ...
1125 ! **************************************************************************************************
1126  FUNCTION ind_m2(ii, iii) RESULT(i)
1127 
1128  INTEGER :: ii, iii, i
1129 
1130  INTEGER :: l(3)
1131 
1132  i = 0
1133  l(1:3) = 0
1134  IF (ii == 0) THEN
1135  l(iii) = 1
1136  ELSEIF (iii == 0) THEN
1137  l(ii) = 1
1138  ELSEIF (ii == iii) THEN
1139  l(ii) = 2
1140  i = coset(l(1), l(2), l(3)) - 1
1141  ELSE
1142  l(ii) = 1
1143  l(iii) = 1
1144  END IF
1145  i = coset(l(1), l(2), l(3)) - 1
1146  END FUNCTION ind_m2
1147 
1148 ! **************************************************************************************************
1149 !> \brief ...
1150 !> \param i1 ...
1151 !> \param i2 ...
1152 !> \param i3 ...
1153 ! **************************************************************************************************
1154  SUBROUTINE set_vecp(i1, i2, i3)
1155 
1156  INTEGER, INTENT(IN) :: i1
1157  INTEGER, INTENT(OUT) :: i2, i3
1158 
1159  IF (i1 == 1) THEN
1160  i2 = 2
1161  i3 = 3
1162  ELSEIF (i1 == 2) THEN
1163  i2 = 3
1164  i3 = 1
1165  ELSEIF (i1 == 3) THEN
1166  i2 = 1
1167  i3 = 2
1168  ELSE
1169  END IF
1170 
1171  END SUBROUTINE set_vecp
1172 ! **************************************************************************************************
1173 !> \brief ...
1174 !> \param i1 ...
1175 !> \param i2 ...
1176 !> \param i3 ...
1177 ! **************************************************************************************************
1178  SUBROUTINE set_vecp_rev(i1, i2, i3)
1179 
1180  INTEGER, INTENT(IN) :: i1, i2
1181  INTEGER, INTENT(OUT) :: i3
1182 
1183  IF ((i1 + i2) == 3) THEN
1184  i3 = 3
1185  ELSEIF ((i1 + i2) == 4) THEN
1186  i3 = 2
1187  ELSEIF ((i1 + i2) == 5) THEN
1188  i3 = 1
1189  ELSE
1190  END IF
1191 
1192  END SUBROUTINE set_vecp_rev
1193 
1194 ! **************************************************************************************************
1195 !> \brief scale a matrix as a_ij = a_ij * pbc(rc(:,j),ra(:,i))(ixyz)
1196 !> \param matrix ...
1197 !> \param ra ...
1198 !> \param rc ...
1199 !> \param cell ...
1200 !> \param ixyz ...
1201 !> \author vw
1202 ! **************************************************************************************************
1203  SUBROUTINE fm_scale_by_pbc_ac(matrix, ra, rc, cell, ixyz)
1204  TYPE(cp_fm_type), INTENT(IN) :: matrix
1205  REAL(kind=dp), DIMENSION(:, :), INTENT(in) :: ra, rc
1206  TYPE(cell_type), POINTER :: cell
1207  INTEGER, INTENT(IN) :: ixyz
1208 
1209  CHARACTER(LEN=*), PARAMETER :: routinen = 'fm_scale_by_pbc_AC'
1210 
1211  INTEGER :: handle, icol_global, icol_local, irow_global, irow_local, m, mypcol, myprow, n, &
1212  ncol_block, ncol_global, ncol_local, npcol, nprow, nrow_block, nrow_global, nrow_local
1213  REAL(kind=dp) :: dist(3), rra(3), rrc(3)
1214  REAL(kind=dp), DIMENSION(:, :), POINTER :: a
1215 
1216  CALL timeset(routinen, handle)
1217 
1218  myprow = matrix%matrix_struct%context%mepos(1)
1219  mypcol = matrix%matrix_struct%context%mepos(2)
1220  nprow = matrix%matrix_struct%context%num_pe(1)
1221  npcol = matrix%matrix_struct%context%num_pe(2)
1222 
1223  nrow_block = matrix%matrix_struct%nrow_block
1224  ncol_block = matrix%matrix_struct%ncol_block
1225  nrow_global = matrix%matrix_struct%nrow_global
1226  ncol_global = matrix%matrix_struct%ncol_global
1227  nrow_local = matrix%matrix_struct%nrow_locals(myprow)
1228  ncol_local = matrix%matrix_struct%ncol_locals(mypcol)
1229 
1230  n = SIZE(rc, 2)
1231  m = SIZE(ra, 2)
1232 
1233  a => matrix%local_data
1234  DO icol_local = 1, ncol_local
1235  icol_global = cp_fm_indxl2g(icol_local, ncol_block, mypcol, &
1236  matrix%matrix_struct%first_p_pos(2), npcol)
1237  IF (icol_global .GT. n) cycle
1238  rrc = rc(:, icol_global)
1239  DO irow_local = 1, nrow_local
1240  irow_global = cp_fm_indxl2g(irow_local, nrow_block, myprow, &
1241  matrix%matrix_struct%first_p_pos(1), nprow)
1242  IF (irow_global .GT. m) cycle
1243  rra = ra(:, irow_global)
1244  dist = pbc(rrc, rra, cell)
1245  a(irow_local, icol_local) = a(irow_local, icol_local)*dist(ixyz)
1246  END DO
1247  END DO
1248 
1249  CALL timestop(handle)
1250 
1251  END SUBROUTINE fm_scale_by_pbc_ac
1252 
1253 END MODULE qs_linres_op
1254 
subroutine pbc(r, r_pbc, s, s_pbc, a, b, c, alpha, beta, gamma, debug, info, pbc0, h, hinv)
...
Definition: dumpdcd.F:1203
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...
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_solve(matrix_a, general_a, determinant)
Solve the system of linear equations A*b=A_general using LU decomposition. Pay attention that both ma...
Represents a complex full matrix distributed on many processors.
Definition: cp_cfm_types.F:12
subroutine, public cp_cfm_create(matrix, matrix_struct, name)
Creates a new full matrix with the given structure.
Definition: cp_cfm_types.F:121
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
Definition: cp_cfm_types.F:159
subroutine, public cp_cfm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, matrix_struct, para_env)
Returns information about a full matrix.
Definition: cp_cfm_types.F:607
subroutine, public cp_cfm_set_all(matrix, alpha, beta)
Set all elements of the full matrix to alpha. Besides, set all diagonal matrix elements to beta (if g...
Definition: cp_cfm_types.F:179
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
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
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
Definition: cp_fm_struct.F:14
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
Definition: cp_fm_struct.F:125
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
Definition: cp_fm_struct.F:320
represent a full matrix distributed on many processors
Definition: cp_fm_types.F:15
integer function, public cp_fm_indxl2g(INDXLOC, NB, IPROC, ISRCPROC, NPROCS)
wrapper to scalapack function INDXL2G that computes the global index of a distributed matrix entry po...
Definition: cp_fm_types.F:2585
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
Definition: cp_fm_types.F:1016
subroutine, public cp_fm_set_submatrix(fm, new_values, start_row, start_col, n_rows, n_cols, alpha, beta, transpose)
sets a submatrix of a full matrix fm(start_row:start_row+n_rows,start_col:start_col+n_cols) = alpha*o...
Definition: cp_fm_types.F:768
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
Definition: cp_fm_types.F:535
subroutine, public cp_fm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
Definition: cp_fm_types.F:901
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
Definition: cp_fm_types.F:167
various routines to log and control the output. The idea is that decisions about where to log should ...
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,...
objects that represent the structure of input sections and the data contained in an input section
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
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
Definition of mathematical constants and functions.
Definition: mathconstants.F:16
real(kind=dp), parameter, public twopi
Interface to the message passing library MPI.
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:, :, :), allocatable, public coset
basic linear algebra operations for full matrixes
Define methods related to particle_type.
subroutine, public get_particle_set(particle_set, qs_kind_set, first_sgf, last_sgf, nsgf, nmao, basis)
Get the components of a particle set.
Define the data structure for the particle information.
Distribution of the electric field gradient integral matrix.
Definition: qs_elec_field.F:13
subroutine, public build_efg_matrix(qs_env, matrix_efg, rc)
Calculation of the electric field gradient matrix over Cartesian Gaussian functions.
Definition: qs_elec_field.F:75
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_RI_aux_kp, matrix_s, matrix_s_RI_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, 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, rhs)
Get the QUICKSTEP environment.
Distribution of the Fermi contact integral matrix.
subroutine, public build_fermi_contact_matrix(qs_env, matrix_fc, rc)
Calculation of the Fermi contact matrix over Cartesian Gaussian functions.
Define the quickstep kind type and their sub types.
Definition: qs_kind_types.F:23
subroutine, public get_qs_kind_set(qs_kind_set, all_potential_present, tnadd_potential_present, gth_potential_present, sgp_potential_present, paw_atom_present, dft_plus_u_atom_present, maxcgf, maxsgf, maxco, maxco_proj, maxgtops, maxlgto, maxlprj, maxnset, maxsgf_set, ncgf, npgf, nset, nsgf, nshell, maxpol, maxlppl, maxlppnl, maxppnl, nelectron, maxder, max_ngrid_rad, max_sph_harm, maxg_iso_not0, lmax_rho0, basis_rcut, basis_type, total_zeff_corr)
Get attributes of an atomic kind set.
Calculate the operators p rxp and D needed in the optimization of the different contribution of the f...
Definition: qs_linres_op.F:18
integer function, public ind_m2(ii, iii)
...
subroutine, public current_operators(current_env, qs_env)
Calculate the first order hamiltonian applied to the ao and then apply them to the ground state orbit...
Definition: qs_linres_op.F:116
subroutine, public set_vecp(i1, i2, i3)
...
real(dp) function, public fac_vecp(a, b, c)
...
subroutine, public polar_operators(qs_env)
Calculate the dipole operator in the AO basis and its derivative wrt to MOs.
Definition: qs_linres_op.F:639
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)
...
subroutine, public issc_operators(issc_env, qs_env, iatom)
...
Definition: qs_linres_op.F:441
Type definitiona for linear response calculations.
subroutine, public get_issc_env(issc_env, issc_on_atom_list, issc_gapw_radius, issc_loc, do_fc, do_sd, do_pso, do_dso, issc, interpolate_issc, psi1_efg, psi1_pso, psi1_dso, psi1_fc, efg_psi0, pso_psi0, dso_psi0, fc_psi0, matrix_efg, matrix_pso, matrix_dso, matrix_fc)
...
subroutine, public get_polar_env(polar_env, do_raman, do_periodic, dBerry_psi0, polar, psi1_dBerry, run_stopped)
...
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)
...
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.
Definition: qs_mo_types.F:397
Calculates the moment integrals <a|r^m|b> and <a|r x d/dr|b>
Definition: qs_moments.F:14
subroutine, public build_local_moment_matrix(qs_env, moments, nmoments, ref_point, ref_points, basis_type)
...
Definition: qs_moments.F:558
subroutine, public build_berry_moment_matrix(qs_env, cosmat, sinmat, kvec, sab_orb_external, basis_type)
...
Definition: qs_moments.F:1336
Define the neighbor list data types and the corresponding functionality.
subroutine, public build_ang_mom_matrix(qs_env, matrix, rc)
Calculation of the angular momentum matrix over Cartesian Gaussian functions.
subroutine, public build_lin_mom_matrix(qs_env, matrix)
Calculation of the linear momentum matrix <mu|∂|nu> over Cartesian Gaussian functions.
subroutine, public rrc_xyz_ao(op, qs_env, rc, order, minimum_image, soft)
Calculation of the components of the dipole operator in the length form by taking the relative positi...
Distribution of the spin orbit integral matrix.
Definition: qs_spin_orbit.F:13
subroutine, public build_pso_matrix(qs_env, matrix_so, rc)
Calculation of the paramagnetic spin orbit matrix over Cartesian Gaussian functions.
Definition: qs_spin_orbit.F:74