(git:374b731)
Loading...
Searching...
No Matches
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
24 USE cp_cfm_types, ONLY: cp_cfm_create,&
38 USE cp_fm_types, ONLY: &
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
54 USE kinds, ONLY: dp
55 USE mathconstants, ONLY: twopi
57 USE orbital_pointers, ONLY: coset
74 USE qs_mo_types, ONLY: get_mo_set,&
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
95CONTAINS
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 !
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 !
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
1253END MODULE qs_linres_op
1254
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.
subroutine, public cp_cfm_create(matrix, matrix_struct, name)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
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.
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...
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
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
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...
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
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...
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_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,...
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
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 ...
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.
real(kind=dp), parameter, public one
real(kind=dp), parameter, public twopi
real(kind=dp), parameter, public zero
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.
subroutine, public build_efg_matrix(qs_env, matrix_efg, rc)
Calculation of the electric field gradient matrix over Cartesian Gaussian functions.
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.
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...
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...
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.
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)
...
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)
...
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)
...
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.
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)
...
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.
subroutine, public build_pso_matrix(qs_env, matrix_so, rc)
Calculation of the paramagnetic spin orbit matrix over Cartesian Gaussian functions.
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
represent a pointer to a 2d array
represent a pointer to a 2d array
Represent a complex full matrix.
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
Provides all information about a quickstep kind.
General settings for linear response calculations.