Line data Source code
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 Chemical shift calculation by dfpt
10 : !> Initialization of the issc_env, creation of the special neighbor lists
11 : !> Perturbation Hamiltonians by application of the p and rxp oprtators to psi0
12 : !> Write output
13 : !> Deallocate everything
14 : !> \note
15 : !> The psi0 should be localized
16 : !> the Sebastiani method works within the assumption that the orbitals are
17 : !> completely contained in the simulation box
18 : ! **************************************************************************************************
19 : MODULE qs_linres_issc_utils
20 : USE atomic_kind_types, ONLY: atomic_kind_type,&
21 : get_atomic_kind
22 : USE cell_types, ONLY: cell_type,&
23 : pbc
24 : USE cp_control_types, ONLY: dft_control_type
25 : USE cp_dbcsr_api, ONLY: dbcsr_convert_offsets_to_sizes,&
26 : dbcsr_copy,&
27 : dbcsr_create,&
28 : dbcsr_distribution_type,&
29 : dbcsr_p_type,&
30 : dbcsr_set,&
31 : dbcsr_type_antisymmetric,&
32 : dbcsr_type_symmetric
33 : USE cp_dbcsr_cp2k_link, ONLY: cp_dbcsr_alloc_block_from_nbl
34 : USE cp_dbcsr_operations, ONLY: cp_dbcsr_sm_fm_multiply,&
35 : dbcsr_allocate_matrix_set,&
36 : dbcsr_deallocate_matrix_set
37 : USE cp_fm_basic_linalg, ONLY: cp_fm_frobenius_norm,&
38 : cp_fm_trace
39 : USE cp_fm_struct, ONLY: cp_fm_struct_create,&
40 : cp_fm_struct_release,&
41 : cp_fm_struct_type
42 : USE cp_fm_types, ONLY: cp_fm_create,&
43 : cp_fm_get_info,&
44 : cp_fm_release,&
45 : cp_fm_set_all,&
46 : cp_fm_to_fm,&
47 : cp_fm_type
48 : USE cp_log_handling, ONLY: cp_get_default_logger,&
49 : cp_logger_get_default_io_unit,&
50 : cp_logger_type
51 : USE cp_output_handling, ONLY: cp_p_file,&
52 : cp_print_key_finished_output,&
53 : cp_print_key_should_output,&
54 : cp_print_key_unit_nr
55 : USE input_section_types, ONLY: section_vals_get_subs_vals,&
56 : section_vals_type,&
57 : section_vals_val_get
58 : USE kinds, ONLY: default_string_length,&
59 : dp
60 : USE mathlib, ONLY: diamat_all
61 : USE memory_utilities, ONLY: reallocate
62 : USE message_passing, ONLY: mp_para_env_type
63 : USE particle_methods, ONLY: get_particle_set
64 : USE particle_types, ONLY: particle_type
65 : USE physcon, ONLY: a_fine,&
66 : e_mass,&
67 : hertz,&
68 : p_mass
69 : USE qs_elec_field, ONLY: build_efg_matrix
70 : USE qs_environment_types, ONLY: get_qs_env,&
71 : qs_environment_type
72 : USE qs_fermi_contact, ONLY: build_fermi_contact_matrix
73 : USE qs_kind_types, ONLY: qs_kind_type
74 : USE qs_linres_methods, ONLY: linres_solver
75 : USE qs_linres_types, ONLY: get_issc_env,&
76 : issc_env_type,&
77 : linres_control_type
78 : USE qs_matrix_pools, ONLY: qs_matrix_pools_type
79 : USE qs_mo_types, ONLY: get_mo_set,&
80 : mo_set_type
81 : USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
82 : USE qs_p_env_types, ONLY: qs_p_env_type
83 : USE qs_spin_orbit, ONLY: build_pso_matrix
84 : #include "./base/base_uses.f90"
85 :
86 : IMPLICIT NONE
87 :
88 : PRIVATE
89 : PUBLIC :: issc_env_cleanup, issc_env_init, issc_response, issc_issc, issc_print
90 :
91 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_linres_issc_utils'
92 :
93 : CONTAINS
94 :
95 : ! **************************************************************************************************
96 : !> \brief Initialize the issc environment
97 : !> \param issc_env ...
98 : !> \param p_env ...
99 : !> \param qs_env ...
100 : ! **************************************************************************************************
101 44 : SUBROUTINE issc_response(issc_env, p_env, qs_env)
102 : !
103 : TYPE(issc_env_type) :: issc_env
104 : TYPE(qs_p_env_type) :: p_env
105 : TYPE(qs_environment_type), POINTER :: qs_env
106 :
107 : CHARACTER(LEN=*), PARAMETER :: routineN = 'issc_response'
108 :
109 : INTEGER :: handle, idir, ijdir, ispin, jdir, nao, &
110 : nmo, nspins, output_unit
111 : LOGICAL :: do_dso, do_fc, do_pso, do_sd, should_stop
112 : REAL(dp) :: chk, fro
113 : TYPE(cp_fm_struct_type), POINTER :: tmp_fm_struct
114 44 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: h1_psi0, psi0_order, psi1
115 44 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: fc_psi0, psi1_fc
116 44 : TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: dso_psi0, efg_psi0, psi1_dso, psi1_efg, &
117 44 : psi1_pso, pso_psi0
118 : TYPE(cp_fm_type), POINTER :: mo_coeff
119 : TYPE(cp_logger_type), POINTER :: logger
120 : TYPE(dft_control_type), POINTER :: dft_control
121 : TYPE(linres_control_type), POINTER :: linres_control
122 44 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
123 : TYPE(mp_para_env_type), POINTER :: para_env
124 : TYPE(qs_matrix_pools_type), POINTER :: mpools
125 : TYPE(section_vals_type), POINTER :: issc_section, lr_section
126 :
127 44 : CALL timeset(routineN, handle)
128 : !
129 44 : NULLIFY (dft_control, linres_control, lr_section, issc_section)
130 44 : NULLIFY (logger, mpools, mo_coeff, para_env)
131 44 : NULLIFY (tmp_fm_struct, psi1_fc, psi1_efg, psi1_pso, pso_psi0, fc_psi0, efg_psi0)
132 :
133 44 : logger => cp_get_default_logger()
134 44 : lr_section => section_vals_get_subs_vals(qs_env%input, "PROPERTIES%LINRES")
135 : issc_section => section_vals_get_subs_vals(qs_env%input, &
136 44 : "PROPERTIES%LINRES%SPINSPIN")
137 :
138 : output_unit = cp_print_key_unit_nr(logger, lr_section, "PRINT%PROGRAM_RUN_INFO", &
139 44 : extension=".linresLog")
140 44 : IF (output_unit > 0) THEN
141 : WRITE (UNIT=output_unit, FMT="(T10,A,/)") &
142 22 : "*** Self consistent optimization of the response wavefunctions ***"
143 : END IF
144 :
145 : CALL get_qs_env(qs_env=qs_env, &
146 : dft_control=dft_control, &
147 : mpools=mpools, &
148 : linres_control=linres_control, &
149 : mos=mos, &
150 44 : para_env=para_env)
151 :
152 44 : nspins = dft_control%nspins
153 :
154 : CALL get_issc_env(issc_env=issc_env, &
155 : !list_cubes=list_cubes, &
156 : psi1_efg=psi1_efg, &
157 : psi1_pso=psi1_pso, &
158 : psi1_dso=psi1_dso, &
159 : psi1_fc=psi1_fc, &
160 : efg_psi0=efg_psi0, &
161 : pso_psi0=pso_psi0, &
162 : dso_psi0=dso_psi0, &
163 : fc_psi0=fc_psi0, &
164 : do_fc=do_fc, &
165 : do_sd=do_sd, &
166 : do_pso=do_pso, &
167 44 : do_dso=do_dso)
168 : !
169 : ! allocate the vectors
170 180 : ALLOCATE (psi0_order(nspins))
171 228 : ALLOCATE (psi1(nspins), h1_psi0(nspins))
172 92 : DO ispin = 1, nspins
173 48 : CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff)
174 48 : psi0_order(ispin) = mo_coeff
175 48 : CALL cp_fm_get_info(mo_coeff, ncol_global=nmo, nrow_global=nao)
176 48 : NULLIFY (tmp_fm_struct)
177 : CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nao, &
178 : ncol_global=nmo, &
179 48 : context=mo_coeff%matrix_struct%context)
180 48 : CALL cp_fm_create(psi1(ispin), tmp_fm_struct)
181 48 : CALL cp_fm_create(h1_psi0(ispin), tmp_fm_struct)
182 140 : CALL cp_fm_struct_release(tmp_fm_struct)
183 : END DO
184 44 : chk = 0.0_dp
185 44 : should_stop = .FALSE.
186 : !
187 : ! operator efg
188 44 : IF (do_sd) THEN
189 : ijdir = 0
190 0 : DO idir = 1, 3
191 0 : DO jdir = idir, 3
192 0 : ijdir = ijdir + 1
193 0 : DO ispin = 1, nspins
194 0 : CALL cp_fm_set_all(psi1_efg(ispin, ijdir), 0.0_dp)
195 : END DO
196 0 : IF (output_unit > 0) THEN
197 0 : WRITE (output_unit, "(T10,A)") "Response to the perturbation operator efg_"//ACHAR(idir + 119)//ACHAR(jdir + 119)
198 : END IF
199 : !
200 : !Initial guess for psi1
201 0 : DO ispin = 1, nspins
202 0 : CALL cp_fm_set_all(psi1(ispin), 0.0_dp)
203 : !CALL cp_fm_to_fm(p_psi0(ispin,ijdir)%matrix, psi1(ispin))
204 : !CALL cp_fm_scale(-1.0_dp,psi1(ispin))
205 : END DO
206 : !
207 : !DO scf cycle to optimize psi1
208 0 : DO ispin = 1, nspins
209 0 : CALL cp_fm_to_fm(efg_psi0(ispin, ijdir), h1_psi0(ispin))
210 : END DO
211 : !
212 : !
213 0 : linres_control%lr_triplet = .FALSE.
214 0 : linres_control%do_kernel = .FALSE.
215 0 : linres_control%converged = .FALSE.
216 0 : CALL linres_solver(p_env, qs_env, psi1, h1_psi0, psi0_order, output_unit, should_stop)
217 : !
218 : !
219 : ! copy the response
220 0 : DO ispin = 1, nspins
221 0 : CALL cp_fm_to_fm(psi1(ispin), psi1_efg(ispin, ijdir))
222 0 : fro = cp_fm_frobenius_norm(psi1(ispin))
223 0 : chk = chk + fro
224 : END DO
225 : !
226 : ! print response functions
227 : !IF(BTEST(cp_print_key_should_output(logger%iter_info,issc_section,&
228 : ! & "PRINT%RESPONSE_FUNCTION_CUBES"),cp_p_file)) THEN
229 : ! ncubes = SIZE(list_cubes,1)
230 : ! print_key => section_vals_get_subs_vals(issc_section,"PRINT%RESPONSE_FUNCTION_CUBES")
231 : ! DO ispin = 1,nspins
232 : ! CALL qs_print_cubes(qs_env,psi1(ispin),ncubes,list_cubes,&
233 : ! centers_set(ispin)%array,print_key,'psi1_efg',&
234 : ! idir=ijdir,ispin=ispin)
235 : ! ENDDO ! ispin
236 : !ENDIF ! print response functions
237 : !
238 : !
239 0 : IF (output_unit > 0) THEN
240 0 : WRITE (output_unit, "(T10,A)") "Write the resulting psi1 in restart file... not implemented yet"
241 : END IF
242 : !
243 : ! Write the result in the restart file
244 : END DO ! jdir
245 : END DO ! idir
246 : END IF
247 : !
248 : ! operator pso
249 44 : IF (do_pso) THEN
250 136 : DO idir = 1, 3
251 216 : DO ispin = 1, nspins
252 216 : CALL cp_fm_set_all(psi1_pso(ispin, idir), 0.0_dp)
253 : END DO
254 102 : IF (output_unit > 0) THEN
255 51 : WRITE (output_unit, "(T10,A)") "Response to the perturbation operator pso_"//ACHAR(idir + 119)
256 : END IF
257 : !
258 : !Initial guess for psi1
259 216 : DO ispin = 1, nspins
260 216 : CALL cp_fm_set_all(psi1(ispin), 0.0_dp)
261 : !CALL cp_fm_to_fm(rxp_psi0(ispin,idir)%matrix, psi1(ispin))
262 : !CALL cp_fm_scale(-1.0_dp,psi1(ispin))
263 : END DO
264 : !
265 : !DO scf cycle to optimize psi1
266 216 : DO ispin = 1, nspins
267 216 : CALL cp_fm_to_fm(pso_psi0(ispin, idir), h1_psi0(ispin))
268 : END DO
269 : !
270 : !
271 102 : linres_control%lr_triplet = .FALSE. ! we do singlet response
272 102 : linres_control%do_kernel = .FALSE. ! we do uncoupled response
273 102 : linres_control%converged = .FALSE.
274 102 : CALL linres_solver(p_env, qs_env, psi1, h1_psi0, psi0_order, output_unit, should_stop)
275 : !
276 : !
277 : ! copy the response
278 216 : DO ispin = 1, nspins
279 114 : CALL cp_fm_to_fm(psi1(ispin), psi1_pso(ispin, idir))
280 114 : fro = cp_fm_frobenius_norm(psi1(ispin))
281 216 : chk = chk + fro
282 : END DO
283 : !
284 : ! print response functions
285 : !IF(BTEST(cp_print_key_should_output(logger%iter_info,issc_section,&
286 : ! & "PRINT%RESPONSE_FUNCTION_CUBES"),cp_p_file)) THEN
287 : ! ncubes = SIZE(list_cubes,1)
288 : ! print_key => section_vals_get_subs_vals(issc_section,"PRINT%RESPONSE_FUNCTION_CUBES")
289 : ! DO ispin = 1,nspins
290 : ! CALL qs_print_cubes(qs_env,psi1(ispin),ncubes,list_cubes,&
291 : ! centers_set(ispin)%array,print_key,'psi1_pso',&
292 : ! idir=idir,ispin=ispin)
293 : ! ENDDO ! ispin
294 : !ENDIF ! print response functions
295 : !
296 : !
297 238 : IF (output_unit > 0) THEN
298 51 : WRITE (output_unit, "(T10,A)") "Write the resulting psi1 in restart file... not implemented yet"
299 : END IF
300 : !
301 : ! Write the result in the restart file
302 : END DO ! idir
303 : END IF
304 : !
305 : ! operator fc
306 44 : IF (do_fc) THEN
307 0 : DO ispin = 1, nspins
308 0 : CALL cp_fm_set_all(psi1_fc(ispin), 0.0_dp)
309 : END DO
310 0 : IF (output_unit > 0) THEN
311 0 : WRITE (output_unit, "(T10,A)") "Response to the perturbation operator fc"
312 : END IF
313 : !
314 : !Initial guess for psi1
315 0 : DO ispin = 1, nspins
316 0 : CALL cp_fm_set_all(psi1(ispin), 0.0_dp)
317 : !CALL cp_fm_to_fm(rxp_psi0(ispin,idir)%matrix, psi1(ispin))
318 : !CALL cp_fm_scale(-1.0_dp,psi1(ispin))
319 : END DO
320 : !
321 : !DO scf cycle to optimize psi1
322 0 : DO ispin = 1, nspins
323 0 : CALL cp_fm_to_fm(fc_psi0(ispin), h1_psi0(ispin))
324 : END DO
325 : !
326 : !
327 0 : linres_control%lr_triplet = .TRUE. ! we do triplet response
328 0 : linres_control%do_kernel = .TRUE. ! we do coupled response
329 0 : linres_control%converged = .FALSE.
330 0 : CALL linres_solver(p_env, qs_env, psi1, h1_psi0, psi0_order, output_unit, should_stop)
331 : !
332 : !
333 : ! copy the response
334 0 : DO ispin = 1, nspins
335 0 : CALL cp_fm_to_fm(psi1(ispin), psi1_fc(ispin))
336 0 : fro = cp_fm_frobenius_norm(psi1(ispin))
337 0 : chk = chk + fro
338 : END DO
339 : !
340 : ! print response functions
341 : !IF(BTEST(cp_print_key_should_output(logger%iter_info,issc_section,&
342 : ! & "PRINT%RESPONSE_FUNCTION_CUBES"),cp_p_file)) THEN
343 : ! ncubes = SIZE(list_cubes,1)
344 : ! print_key => section_vals_get_subs_vals(issc_section,"PRINT%RESPONSE_FUNCTION_CUBES")
345 : ! DO ispin = 1,nspins
346 : ! CALL qs_print_cubes(qs_env,psi1(ispin),ncubes,list_cubes,&
347 : ! centers_set(ispin)%array,print_key,'psi1_pso',&
348 : ! idir=idir,ispin=ispin)
349 : ! ENDDO ! ispin
350 : !ENDIF ! print response functions
351 : !
352 : !
353 0 : IF (output_unit > 0) THEN
354 0 : WRITE (output_unit, "(T10,A)") "Write the resulting psi1 in restart file... not implemented yet"
355 : END IF
356 : !
357 : ! Write the result in the restart file
358 : END IF
359 :
360 : !>>>> debugging only
361 : !
362 : ! here we have the operator r and compute the polarizability for debugging the kernel only
363 44 : IF (do_dso) THEN
364 8 : DO idir = 1, 3
365 12 : DO ispin = 1, nspins
366 12 : CALL cp_fm_set_all(psi1_dso(ispin, idir), 0.0_dp)
367 : END DO
368 6 : IF (output_unit > 0) THEN
369 3 : WRITE (output_unit, "(T10,A)") "Response to the perturbation operator r_"//ACHAR(idir + 119)
370 : END IF
371 : !
372 : !Initial guess for psi1
373 12 : DO ispin = 1, nspins
374 12 : CALL cp_fm_set_all(psi1(ispin), 0.0_dp)
375 : !CALL cp_fm_to_fm(rxp_psi0(ispin,idir)%matrix, psi1(ispin))
376 : !CALL cp_fm_scale(-1.0_dp,psi1(ispin))
377 : END DO
378 : !
379 : !DO scf cycle to optimize psi1
380 12 : DO ispin = 1, nspins
381 12 : CALL cp_fm_to_fm(dso_psi0(ispin, idir), h1_psi0(ispin))
382 : END DO
383 : !
384 : !
385 6 : linres_control%lr_triplet = .FALSE. ! we do singlet response
386 6 : linres_control%do_kernel = .TRUE. ! we do uncoupled response
387 6 : linres_control%converged = .FALSE.
388 6 : CALL linres_solver(p_env, qs_env, psi1, h1_psi0, psi0_order, output_unit, should_stop)
389 : !
390 : !
391 : ! copy the response
392 12 : DO ispin = 1, nspins
393 6 : CALL cp_fm_to_fm(psi1(ispin), psi1_dso(ispin, idir))
394 6 : fro = cp_fm_frobenius_norm(psi1(ispin))
395 12 : chk = chk + fro
396 : END DO
397 : !
398 : ! print response functions
399 : !IF(BTEST(cp_print_key_should_output(logger%iter_info,issc_section,&
400 : ! & "PRINT%RESPONSE_FUNCTION_CUBES"),cp_p_file)) THEN
401 : ! ncubes = SIZE(list_cubes,1)
402 : ! print_key => section_vals_get_subs_vals(issc_section,"PRINT%RESPONSE_FUNCTION_CUBES")
403 : ! DO ispin = 1,nspins
404 : ! CALL qs_print_cubes(qs_env,psi1(ispin),ncubes,list_cubes,&
405 : ! centers_set(ispin)%array,print_key,'psi1_pso',&
406 : ! idir=idir,ispin=ispin)
407 : ! ENDDO ! ispin
408 : !ENDIF ! print response functions
409 : !
410 : !
411 14 : IF (output_unit > 0) THEN
412 3 : WRITE (output_unit, "(T10,A)") "Write the resulting psi1 in restart file... not implemented yet"
413 : END IF
414 : !
415 : ! Write the result in the restart file
416 : END DO ! idir
417 : END IF
418 : !<<<< debugging only
419 :
420 : !
421 : !
422 : ! print the checksum
423 44 : IF (output_unit > 0) THEN
424 22 : WRITE (output_unit, '(T2,A,E23.16)') 'ISSC| response: CheckSum =', chk
425 : END IF
426 : !
427 : !
428 : ! clean up
429 44 : CALL cp_fm_release(psi1)
430 44 : CALL cp_fm_release(h1_psi0)
431 44 : DEALLOCATE (psi0_order)
432 : !
433 : CALL cp_print_key_finished_output(output_unit, logger, lr_section,&
434 44 : & "PRINT%PROGRAM_RUN_INFO")
435 : !
436 44 : CALL timestop(handle)
437 : !
438 88 : END SUBROUTINE issc_response
439 :
440 : ! **************************************************************************************************
441 : !> \brief ...
442 : !> \param issc_env ...
443 : !> \param qs_env ...
444 : !> \param iatom ...
445 : ! **************************************************************************************************
446 44 : SUBROUTINE issc_issc(issc_env, qs_env, iatom)
447 :
448 : TYPE(issc_env_type) :: issc_env
449 : TYPE(qs_environment_type), POINTER :: qs_env
450 : INTEGER, INTENT(IN) :: iatom
451 :
452 : CHARACTER(LEN=*), PARAMETER :: routineN = 'issc_issc'
453 :
454 : INTEGER :: handle, ispin, ixyz, jatom, jxyz, natom, &
455 : nmo, nspins
456 : LOGICAL :: do_dso, do_fc, do_pso, do_sd, gapw
457 : REAL(dp) :: buf, facdso, facfc, facpso, facsd, g, &
458 : issc_dso, issc_fc, issc_pso, issc_sd, &
459 : maxocc
460 : REAL(dp), DIMENSION(3) :: r_i, r_j
461 44 : REAL(dp), DIMENSION(:, :, :, :, :), POINTER :: issc
462 : TYPE(cell_type), POINTER :: cell
463 44 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: fc_psi0, psi1_fc
464 44 : TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: psi1_dso, psi1_efg, psi1_pso
465 : TYPE(cp_fm_type), POINTER :: mo_coeff
466 44 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_dso, matrix_efg, matrix_fc, &
467 44 : matrix_pso
468 : TYPE(dft_control_type), POINTER :: dft_control
469 44 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
470 44 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
471 : TYPE(section_vals_type), POINTER :: issc_section
472 :
473 44 : CALL timeset(routineN, handle)
474 :
475 44 : NULLIFY (cell, dft_control, particle_set, issc, psi1_fc, psi1_efg, psi1_pso)
476 44 : NULLIFY (matrix_efg, matrix_fc, matrix_pso, mos, mo_coeff, fc_psi0)
477 :
478 : CALL get_qs_env(qs_env=qs_env, &
479 : cell=cell, &
480 : dft_control=dft_control, &
481 : particle_set=particle_set, &
482 44 : mos=mos)
483 :
484 44 : gapw = dft_control%qs_control%gapw
485 44 : natom = SIZE(particle_set, 1)
486 44 : nspins = dft_control%nspins
487 :
488 : CALL get_issc_env(issc_env=issc_env, &
489 : matrix_efg=matrix_efg, &
490 : matrix_pso=matrix_pso, &
491 : matrix_fc=matrix_fc, &
492 : matrix_dso=matrix_dso, &
493 : psi1_fc=psi1_fc, &
494 : psi1_efg=psi1_efg, &
495 : psi1_pso=psi1_pso, &
496 : psi1_dso=psi1_dso, &
497 : fc_psi0=fc_psi0, &
498 : issc=issc, &
499 : do_fc=do_fc, &
500 : do_sd=do_sd, &
501 : do_pso=do_pso, &
502 44 : do_dso=do_dso)
503 :
504 44 : g = e_mass/(2.0_dp*p_mass)
505 44 : facfc = hertz*g**2*a_fine**4
506 44 : facpso = hertz*g**2*a_fine**4
507 44 : facsd = hertz*g**2*a_fine**4
508 44 : facdso = hertz*g**2*a_fine**4
509 :
510 : !
511 : !
512 : issc_section => section_vals_get_subs_vals(qs_env%input, &
513 44 : & "PROPERTIES%LINRES%SPINSPIN")
514 : !
515 : ! Initialize
516 92 : DO ispin = 1, nspins
517 48 : CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, maxocc=maxocc)
518 48 : CALL cp_fm_get_info(mo_coeff, ncol_global=nmo)
519 :
520 292 : DO jatom = 1, natom
521 800 : r_i = particle_set(iatom)%r
522 800 : r_j = particle_set(jatom)%r
523 800 : r_j = pbc(r_i, r_j, cell) + r_i
524 : !
525 : !
526 : !
527 : !write(*,*) 'iatom =',iatom,' r_i=',r_i
528 : !write(*,*) 'jatom =',jatom,' r_j=',r_j
529 : !
530 : ! FC term
531 : !
532 200 : IF (do_fc .AND. iatom .NE. jatom) THEN
533 : !
534 : ! build the integral for the jatom
535 0 : CALL dbcsr_set(matrix_fc(1)%matrix, 0.0_dp)
536 0 : CALL build_fermi_contact_matrix(qs_env, matrix_fc, r_j)
537 : CALL cp_dbcsr_sm_fm_multiply(matrix_fc(1)%matrix, mo_coeff, &
538 : fc_psi0(ispin), ncol=nmo,& ! fc_psi0 a buffer
539 0 : & alpha=1.0_dp)
540 :
541 0 : CALL cp_fm_trace(fc_psi0(ispin), mo_coeff, buf)
542 0 : WRITE (*, *) ' jatom', jatom, 'tr(P*fc)=', buf
543 :
544 0 : CALL cp_fm_trace(fc_psi0(ispin), psi1_fc(ispin), buf)
545 0 : issc_fc = 2.0_dp*2.0_dp*maxocc*facfc*buf
546 0 : issc(1, 1, iatom, jatom, 1) = issc(1, 1, iatom, jatom, 1) + issc_fc
547 0 : issc(2, 2, iatom, jatom, 1) = issc(2, 2, iatom, jatom, 1) + issc_fc
548 0 : issc(3, 3, iatom, jatom, 1) = issc(3, 3, iatom, jatom, 1) + issc_fc
549 : END IF
550 : !
551 : ! SD term
552 : !
553 200 : IF (do_sd .AND. iatom .NE. jatom) THEN
554 : !
555 : ! build the integral for the jatom
556 0 : CALL dbcsr_set(matrix_efg(1)%matrix, 0.0_dp)
557 0 : CALL dbcsr_set(matrix_efg(2)%matrix, 0.0_dp)
558 0 : CALL dbcsr_set(matrix_efg(3)%matrix, 0.0_dp)
559 0 : CALL dbcsr_set(matrix_efg(4)%matrix, 0.0_dp)
560 0 : CALL dbcsr_set(matrix_efg(5)%matrix, 0.0_dp)
561 0 : CALL dbcsr_set(matrix_efg(6)%matrix, 0.0_dp)
562 0 : CALL build_efg_matrix(qs_env, matrix_efg, r_j)
563 0 : DO ixyz = 1, 6
564 : CALL cp_dbcsr_sm_fm_multiply(matrix_efg(ixyz)%matrix, mo_coeff, &
565 : fc_psi0(ispin), ncol=nmo,& ! fc_psi0 a buffer
566 0 : & alpha=1.0_dp, beta=0.0_dp)
567 0 : CALL cp_fm_trace(fc_psi0(ispin), mo_coeff, buf)
568 0 : WRITE (*, *) ' jatom', jatom, ixyz, 'tr(P*efg)=', buf
569 0 : DO jxyz = 1, 6
570 0 : CALL cp_fm_trace(fc_psi0(ispin), psi1_efg(ispin, jxyz), buf)
571 0 : issc_sd = 2.0_dp*maxocc*facsd*buf
572 : !issc(ixyz,jxyz,iatom,jatom) = issc_sd
573 : !write(*,*) 'pso_',ixyz,jxyz,' iatom',iatom,'jatom',jatom,issc_pso
574 : END DO
575 : END DO
576 : END IF
577 : !
578 : ! PSO term
579 : !
580 200 : IF (do_pso .AND. iatom .NE. jatom) THEN
581 : !
582 : ! build the integral for the jatom
583 128 : CALL dbcsr_set(matrix_pso(1)%matrix, 0.0_dp)
584 128 : CALL dbcsr_set(matrix_pso(2)%matrix, 0.0_dp)
585 128 : CALL dbcsr_set(matrix_pso(3)%matrix, 0.0_dp)
586 128 : CALL build_pso_matrix(qs_env, matrix_pso, r_j)
587 512 : DO ixyz = 1, 3
588 : CALL cp_dbcsr_sm_fm_multiply(matrix_pso(ixyz)%matrix, mo_coeff, &
589 : fc_psi0(ispin), ncol=nmo,& ! fc_psi0 a buffer
590 384 : & alpha=1.0_dp, beta=0.0_dp)
591 1664 : DO jxyz = 1, 3
592 1152 : CALL cp_fm_trace(fc_psi0(ispin), psi1_pso(ispin, jxyz), buf)
593 1152 : issc_pso = -2.0_dp*maxocc*facpso*buf
594 1536 : issc(ixyz, jxyz, iatom, jatom, 3) = issc(ixyz, jxyz, iatom, jatom, 3) + issc_pso
595 : END DO
596 : END DO
597 : END IF
598 : !
599 : ! DSO term
600 : !
601 : !>>>>> for debugging we compute here the polarizability and NOT the DSO term!
602 248 : IF (do_dso .AND. iatom .EQ. natom .AND. jatom .EQ. natom) THEN
603 : !
604 : ! build the integral for the jatom
605 : !CALL dbcsr_set(matrix_dso(1)%matrix,0.0_dp)
606 : !CALL dbcsr_set(matrix_dso(2)%matrix,0.0_dp)
607 : !CALL dbcsr_set(matrix_dso(3)%matrix,0.0_dp)
608 : !CALL dbcsr_set(matrix_dso(4)%matrix,0.0_dp)
609 : !CALL dbcsr_set(matrix_dso(5)%matrix,0.0_dp)
610 : !CALL dbcsr_set(matrix_dso(6)%matrix,0.0_dp)
611 : !CALL build_dso_matrix(qs_env,matrix_dso,r_i,r_j)
612 : !DO ixyz = 1,6
613 : ! CALL cp_sm_fm_multiply(matrix_dso(ixyz)%matrix,mo_coeff,&
614 : ! & fc_psi0(ispin),ncol=nmo,& ! fc_psi0 a buffer
615 : ! & alpha=1.0_dp,beta=0.0_dp)
616 : ! CALL cp_fm_trace(fc_psi0(ispin),mo_coeff,buf)
617 : ! issc_dso = 2.0_dp * maxocc * facdso * buf
618 : ! issc(ixyz,jxyz,iatom,jatom,4) = issc_dso
619 : !ENDDO
620 : !CALL dbcsr_set(matrix_dso(1)%matrix,0.0_dp)
621 : !CALL dbcsr_set(matrix_dso(2)%matrix,0.0_dp)
622 : !CALL dbcsr_set(matrix_dso(3)%matrix,0.0_dp)
623 : !CALL rRc_xyz_ao(matrix_dso,qs_env,(/0.0_dp,0.0_dp,0.0_dp/),1)
624 8 : DO ixyz = 1, 3
625 : CALL cp_dbcsr_sm_fm_multiply(matrix_dso(ixyz)%matrix, mo_coeff, &
626 : fc_psi0(ispin), ncol=nmo,& ! fc_psi0 a buffer
627 6 : & alpha=1.0_dp, beta=0.0_dp)
628 26 : DO jxyz = 1, 3
629 18 : CALL cp_fm_trace(psi1_dso(ispin, jxyz), fc_psi0(ispin), buf)
630 : ! we save the polarizability for a checksum later on !
631 18 : issc_dso = 2.0_dp*maxocc*buf
632 24 : issc(ixyz, jxyz, iatom, jatom, 4) = issc(ixyz, jxyz, iatom, jatom, 4) + issc_dso
633 : END DO
634 : END DO
635 :
636 : END IF
637 : !
638 : END DO ! jatom
639 : END DO ! ispin
640 : !
641 : !
642 : ! Finalize
643 44 : CALL timestop(handle)
644 : !
645 44 : END SUBROUTINE issc_issc
646 :
647 : ! **************************************************************************************************
648 : !> \brief ...
649 : !> \param issc_env ...
650 : !> \param qs_env ...
651 : ! **************************************************************************************************
652 12 : SUBROUTINE issc_print(issc_env, qs_env)
653 : TYPE(issc_env_type) :: issc_env
654 : TYPE(qs_environment_type), POINTER :: qs_env
655 :
656 : CHARACTER(LEN=2) :: element_symbol_i, element_symbol_j
657 : CHARACTER(LEN=default_string_length) :: name_i, name_j, title
658 : INTEGER :: iatom, jatom, natom, output_unit, &
659 : unit_atoms
660 : LOGICAL :: do_dso, do_fc, do_pso, do_sd, gapw
661 : REAL(dp) :: eig(3), issc_iso_dso, issc_iso_fc, &
662 : issc_iso_pso, issc_iso_sd, &
663 : issc_iso_tot, issc_tmp(3, 3)
664 12 : REAL(dp), DIMENSION(:, :, :, :, :), POINTER :: issc
665 : REAL(dp), EXTERNAL :: DDOT
666 : TYPE(atomic_kind_type), POINTER :: atom_kind_i, atom_kind_j
667 : TYPE(cp_logger_type), POINTER :: logger
668 : TYPE(dft_control_type), POINTER :: dft_control
669 12 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
670 : TYPE(section_vals_type), POINTER :: issc_section
671 :
672 12 : NULLIFY (logger, particle_set, atom_kind_i, atom_kind_j, dft_control)
673 :
674 24 : logger => cp_get_default_logger()
675 12 : output_unit = cp_logger_get_default_io_unit(logger)
676 :
677 : issc_section => section_vals_get_subs_vals(qs_env%input, &
678 12 : "PROPERTIES%LINRES%SPINSPIN")
679 :
680 : CALL get_issc_env(issc_env=issc_env, &
681 : issc=issc, &
682 : do_fc=do_fc, &
683 : do_sd=do_sd, &
684 : do_pso=do_pso, &
685 12 : do_dso=do_dso)
686 : !
687 : CALL get_qs_env(qs_env=qs_env, &
688 : dft_control=dft_control, &
689 12 : particle_set=particle_set)
690 :
691 12 : natom = SIZE(particle_set, 1)
692 12 : gapw = dft_control%qs_control%gapw
693 :
694 : !
695 12 : IF (output_unit > 0) THEN
696 6 : WRITE (output_unit, '(T2,A,E14.6)') 'ISSC| CheckSum K =', &
697 42 : SQRT(DDOT(SIZE(issc), issc, 1, issc, 1))
698 : END IF
699 : !
700 12 : IF (BTEST(cp_print_key_should_output(logger%iter_info, issc_section, &
701 : "PRINT%K_MATRIX"), cp_p_file)) THEN
702 :
703 : unit_atoms = cp_print_key_unit_nr(logger, issc_section, "PRINT%K_MATRIX", &
704 12 : extension=".data", middle_name="K", log_filename=.FALSE.)
705 :
706 12 : IF (unit_atoms > 0) THEN
707 6 : WRITE (unit_atoms, *)
708 6 : WRITE (unit_atoms, *)
709 6 : WRITE (title, '(A)') "Indirect spin-spin coupling matrix"
710 6 : WRITE (unit_atoms, '(T2,A)') title
711 28 : DO iatom = 1, natom
712 22 : atom_kind_i => particle_set(iatom)%atomic_kind
713 22 : CALL get_atomic_kind(atom_kind_i, name=name_i, element_symbol=element_symbol_i)
714 124 : DO jatom = 1, natom
715 96 : atom_kind_j => particle_set(jatom)%atomic_kind
716 96 : CALL get_atomic_kind(atom_kind_j, name=name_j, element_symbol=element_symbol_j)
717 : !
718 96 : IF (iatom .EQ. jatom .AND. .NOT. do_dso) CYCLE
719 : !
720 : !
721 : ! FC
722 975 : issc_tmp(:, :) = issc(:, :, iatom, jatom, 1)
723 1875 : issc_tmp(:, :) = 0.5_dp*(issc_tmp(:, :) + TRANSPOSE(issc_tmp(:, :)))
724 75 : CALL diamat_all(issc_tmp, eig)
725 75 : issc_iso_fc = (eig(1) + eig(2) + eig(3))/3.0_dp
726 : !
727 : ! SD
728 975 : issc_tmp(:, :) = issc(:, :, iatom, jatom, 2)
729 1875 : issc_tmp(:, :) = 0.5_dp*(issc_tmp(:, :) + TRANSPOSE(issc_tmp(:, :)))
730 75 : CALL diamat_all(issc_tmp, eig)
731 75 : issc_iso_sd = (eig(1) + eig(2) + eig(3))/3.0_dp
732 : !
733 : ! PSO
734 975 : issc_tmp(:, :) = issc(:, :, iatom, jatom, 3)
735 1875 : issc_tmp(:, :) = 0.5_dp*(issc_tmp(:, :) + TRANSPOSE(issc_tmp(:, :)))
736 75 : CALL diamat_all(issc_tmp, eig)
737 75 : issc_iso_pso = (eig(1) + eig(2) + eig(3))/3.0_dp
738 : !
739 : ! DSO
740 975 : issc_tmp(:, :) = issc(:, :, iatom, jatom, 4)
741 1875 : issc_tmp(:, :) = 0.5_dp*(issc_tmp(:, :) + TRANSPOSE(issc_tmp(:, :)))
742 75 : CALL diamat_all(issc_tmp, eig)
743 75 : issc_iso_dso = (eig(1) + eig(2) + eig(3))/3.0_dp
744 : !
745 : ! TOT
746 75 : issc_iso_tot = issc_iso_fc + issc_iso_sd + issc_iso_dso + issc_iso_pso
747 : !
748 : !
749 75 : WRITE (unit_atoms, *)
750 75 : WRITE (unit_atoms, '(T2,2(A,I5,A,2X,A2))') 'Indirect spin-spin coupling between ', &
751 75 : iatom, TRIM(name_i), element_symbol_i, ' and ', &
752 150 : jatom, TRIM(name_j), element_symbol_j
753 : !
754 75 : IF (do_fc) WRITE (unit_atoms, '(T1,A,f12.4,A)') ' Isotropic FC contribution = ', issc_iso_fc, ' Hz'
755 75 : IF (do_sd) WRITE (unit_atoms, '(T1,A,f12.4,A)') ' Isotropic SD contribution = ', issc_iso_sd, ' Hz'
756 75 : IF (do_pso) WRITE (unit_atoms, '(T1,A,f12.4,A)') ' Isotropic PSO contribution = ', issc_iso_pso, ' Hz'
757 : !IF(do_dso) WRITE(unit_atoms,'(T1,A,f12.4,A)') ' Isotropic DSO contribution = ',issc_iso_dso,' Hz'
758 75 : IF (do_dso) WRITE (unit_atoms, '(T1,A,f12.4,A)') ' !!! POLARIZABILITY (for the moment) = ', issc_iso_dso, ' Hz'
759 97 : IF (.NOT. do_dso) WRITE (unit_atoms, '(T1,A,f12.4,A)') ' Isotropic coupling = ', issc_iso_tot, ' Hz'
760 : END DO
761 : END DO
762 : END IF
763 : CALL cp_print_key_finished_output(unit_atoms, logger, issc_section,&
764 12 : & "PRINT%K_MATRIX")
765 : END IF
766 : !
767 : !
768 12 : END SUBROUTINE issc_print
769 :
770 : ! **************************************************************************************************
771 : !> \brief Initialize the issc environment
772 : !> \param issc_env ...
773 : !> \param qs_env ...
774 : ! **************************************************************************************************
775 12 : SUBROUTINE issc_env_init(issc_env, qs_env)
776 : !
777 : TYPE(issc_env_type) :: issc_env
778 : TYPE(qs_environment_type), POINTER :: qs_env
779 :
780 : CHARACTER(LEN=*), PARAMETER :: routineN = 'issc_env_init'
781 :
782 : INTEGER :: handle, iatom, idir, ini, ir, ispin, &
783 : istat, m, n, n_rep, nao, natom, &
784 : nspins, output_unit
785 12 : INTEGER, ALLOCATABLE, DIMENSION(:) :: first_sgf, last_sgf
786 12 : INTEGER, DIMENSION(:), POINTER :: list, row_blk_sizes
787 : LOGICAL :: gapw
788 : TYPE(cp_fm_struct_type), POINTER :: tmp_fm_struct
789 : TYPE(cp_fm_type), POINTER :: mo_coeff
790 : TYPE(cp_logger_type), POINTER :: logger
791 : TYPE(dbcsr_distribution_type), POINTER :: dbcsr_dist
792 : TYPE(dft_control_type), POINTER :: dft_control
793 : TYPE(linres_control_type), POINTER :: linres_control
794 12 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
795 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
796 12 : POINTER :: sab_orb
797 12 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
798 12 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
799 : TYPE(section_vals_type), POINTER :: issc_section, lr_section
800 :
801 : !
802 :
803 12 : CALL timeset(routineN, handle)
804 :
805 12 : NULLIFY (linres_control)
806 12 : NULLIFY (logger, issc_section)
807 12 : NULLIFY (tmp_fm_struct)
808 12 : NULLIFY (particle_set, qs_kind_set)
809 12 : NULLIFY (sab_orb)
810 :
811 12 : logger => cp_get_default_logger()
812 12 : lr_section => section_vals_get_subs_vals(qs_env%input, "PROPERTIES%LINRES")
813 :
814 : output_unit = cp_print_key_unit_nr(logger, lr_section, "PRINT%PROGRAM_RUN_INFO", &
815 12 : extension=".linresLog")
816 :
817 12 : CALL issc_env_cleanup(issc_env)
818 :
819 12 : IF (output_unit > 0) THEN
820 6 : WRITE (output_unit, "(/,T20,A,/)") "*** Start indirect spin-spin coupling Calculation ***"
821 6 : WRITE (output_unit, "(T10,A,/)") "Inizialization of the ISSC environment"
822 : END IF
823 :
824 : issc_section => section_vals_get_subs_vals(qs_env%input, &
825 12 : & "PROPERTIES%LINRES%SPINSPIN")
826 : !CALL section_vals_val_get(nmr_section,"INTERPOLATE_SHIFT",l_val=nmr_env%interpolate_shift)
827 : !CALL section_vals_val_get(nmr_section,"SHIFT_GAPW_RADIUS",r_val=nmr_env%shift_gapw_radius)
828 :
829 : CALL get_qs_env(qs_env=qs_env, &
830 : dft_control=dft_control, &
831 : linres_control=linres_control, &
832 : mos=mos, &
833 : sab_orb=sab_orb, &
834 : particle_set=particle_set, &
835 : qs_kind_set=qs_kind_set, &
836 12 : dbcsr_dist=dbcsr_dist)
837 : !
838 : !
839 12 : gapw = dft_control%qs_control%gapw
840 12 : nspins = dft_control%nspins
841 12 : natom = SIZE(particle_set, 1)
842 : !
843 : ! check that the psi0 are localized and you have all the centers
844 12 : IF (.NOT. linres_control%localized_psi0) &
845 : CALL cp_warn(__LOCATION__, 'To get indirect spin-spin coupling parameters within '// &
846 0 : 'PBC you need to localize zero order orbitals')
847 : !
848 : !
849 : ! read terms need to be calculated
850 : ! FC
851 12 : CALL section_vals_val_get(issc_section, "DO_FC", l_val=issc_env%do_fc)
852 : ! SD
853 12 : CALL section_vals_val_get(issc_section, "DO_SD", l_val=issc_env%do_sd)
854 : ! PSO
855 12 : CALL section_vals_val_get(issc_section, "DO_PSO", l_val=issc_env%do_pso)
856 : ! DSO
857 12 : CALL section_vals_val_get(issc_section, "DO_DSO", l_val=issc_env%do_dso)
858 : !
859 : !
860 : ! read the list of atoms on which the issc need to be calculated
861 12 : CALL section_vals_val_get(issc_section, "ISSC_ON_ATOM_LIST", n_rep_val=n_rep)
862 : !
863 : !
864 12 : NULLIFY (issc_env%issc_on_atom_list)
865 12 : n = 0
866 16 : DO ir = 1, n_rep
867 4 : NULLIFY (list)
868 4 : CALL section_vals_val_get(issc_section, "ISSC_ON_ATOM_LIST", i_rep_val=ir, i_vals=list)
869 16 : IF (ASSOCIATED(list)) THEN
870 4 : CALL reallocate(issc_env%issc_on_atom_list, 1, n + SIZE(list))
871 14 : DO ini = 1, SIZE(list)
872 14 : issc_env%issc_on_atom_list(ini + n) = list(ini)
873 : END DO
874 4 : n = n + SIZE(list)
875 : END IF
876 : END DO
877 : !
878 12 : IF (.NOT. ASSOCIATED(issc_env%issc_on_atom_list)) THEN
879 30 : ALLOCATE (issc_env%issc_on_atom_list(natom), STAT=istat)
880 10 : CPASSERT(istat .EQ. 0)
881 44 : DO iatom = 1, natom
882 44 : issc_env%issc_on_atom_list(iatom) = iatom
883 : END DO
884 : END IF
885 12 : issc_env%issc_natms = SIZE(issc_env%issc_on_atom_list)
886 : !
887 : !
888 : ! Initialize the issc tensor
889 : ALLOCATE (issc_env%issc(3, 3, issc_env%issc_natms, issc_env%issc_natms, 4), &
890 : issc_env%issc_loc(3, 3, issc_env%issc_natms, issc_env%issc_natms, 4), &
891 84 : STAT=istat)
892 12 : CPASSERT(istat == 0)
893 10220 : issc_env%issc(:, :, :, :, :) = 0.0_dp
894 10220 : issc_env%issc_loc(:, :, :, :, :) = 0.0_dp
895 : !
896 : ! allocation
897 : ALLOCATE (issc_env%efg_psi0(nspins, 6), issc_env%pso_psi0(nspins, 3), issc_env%fc_psi0(nspins), &
898 : issc_env%psi1_efg(nspins, 6), issc_env%psi1_pso(nspins, 3), issc_env%psi1_fc(nspins), &
899 : issc_env%dso_psi0(nspins, 3), issc_env%psi1_dso(nspins, 3), &
900 796 : STAT=istat)
901 12 : CPASSERT(istat == 0)
902 26 : DO ispin = 1, nspins
903 : !mo_coeff => current_env%psi0_order(ispin)%matrix
904 14 : CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff)
905 14 : CALL cp_fm_get_info(mo_coeff, ncol_global=m, nrow_global=nao)
906 :
907 14 : NULLIFY (tmp_fm_struct)
908 : CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nao, &
909 : ncol_global=m, &
910 14 : context=mo_coeff%matrix_struct%context)
911 98 : DO idir = 1, 6
912 84 : CALL cp_fm_create(issc_env%psi1_efg(ispin, idir), tmp_fm_struct)
913 98 : CALL cp_fm_create(issc_env%efg_psi0(ispin, idir), tmp_fm_struct)
914 : END DO
915 56 : DO idir = 1, 3
916 42 : CALL cp_fm_create(issc_env%psi1_pso(ispin, idir), tmp_fm_struct)
917 42 : CALL cp_fm_create(issc_env%pso_psi0(ispin, idir), tmp_fm_struct)
918 42 : CALL cp_fm_create(issc_env%psi1_dso(ispin, idir), tmp_fm_struct)
919 56 : CALL cp_fm_create(issc_env%dso_psi0(ispin, idir), tmp_fm_struct)
920 : END DO
921 14 : CALL cp_fm_create(issc_env%psi1_fc(ispin), tmp_fm_struct)
922 14 : CALL cp_fm_create(issc_env%fc_psi0(ispin), tmp_fm_struct)
923 40 : CALL cp_fm_struct_release(tmp_fm_struct)
924 : END DO
925 : !
926 : ! prepare for allocation
927 36 : ALLOCATE (first_sgf(natom))
928 24 : ALLOCATE (last_sgf(natom))
929 : CALL get_particle_set(particle_set, qs_kind_set, &
930 : first_sgf=first_sgf, &
931 12 : last_sgf=last_sgf)
932 24 : ALLOCATE (row_blk_sizes(natom))
933 12 : CALL dbcsr_convert_offsets_to_sizes(first_sgf, row_blk_sizes, last_sgf)
934 12 : DEALLOCATE (first_sgf)
935 12 : DEALLOCATE (last_sgf)
936 :
937 : !
938 : ! efg, pso and fc operators
939 12 : CALL dbcsr_allocate_matrix_set(issc_env%matrix_efg, 6)
940 12 : ALLOCATE (issc_env%matrix_efg(1)%matrix)
941 : CALL dbcsr_create(matrix=issc_env%matrix_efg(1)%matrix, &
942 : name="efg (3xx-rr)/3", &
943 : dist=dbcsr_dist, matrix_type=dbcsr_type_symmetric, &
944 : row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
945 12 : nze=0, mutable_work=.TRUE.)
946 12 : CALL cp_dbcsr_alloc_block_from_nbl(issc_env%matrix_efg(1)%matrix, sab_orb)
947 :
948 : ALLOCATE (issc_env%matrix_efg(2)%matrix, &
949 : issc_env%matrix_efg(3)%matrix, issc_env%matrix_efg(4)%matrix, &
950 12 : issc_env%matrix_efg(5)%matrix, issc_env%matrix_efg(6)%matrix)
951 : CALL dbcsr_copy(issc_env%matrix_efg(2)%matrix, issc_env%matrix_efg(1)%matrix, &
952 12 : 'efg xy')
953 : CALL dbcsr_copy(issc_env%matrix_efg(3)%matrix, issc_env%matrix_efg(1)%matrix, &
954 12 : 'efg xz')
955 : CALL dbcsr_copy(issc_env%matrix_efg(4)%matrix, issc_env%matrix_efg(1)%matrix, &
956 12 : 'efg (3yy-rr)/3')
957 : CALL dbcsr_copy(issc_env%matrix_efg(5)%matrix, issc_env%matrix_efg(1)%matrix, &
958 12 : 'efg yz')
959 : CALL dbcsr_copy(issc_env%matrix_efg(6)%matrix, issc_env%matrix_efg(1)%matrix, &
960 12 : 'efg (3zz-rr)/3')
961 :
962 12 : CALL dbcsr_set(issc_env%matrix_efg(1)%matrix, 0.0_dp)
963 12 : CALL dbcsr_set(issc_env%matrix_efg(2)%matrix, 0.0_dp)
964 12 : CALL dbcsr_set(issc_env%matrix_efg(3)%matrix, 0.0_dp)
965 12 : CALL dbcsr_set(issc_env%matrix_efg(4)%matrix, 0.0_dp)
966 12 : CALL dbcsr_set(issc_env%matrix_efg(5)%matrix, 0.0_dp)
967 12 : CALL dbcsr_set(issc_env%matrix_efg(6)%matrix, 0.0_dp)
968 : !
969 : ! PSO
970 12 : CALL dbcsr_allocate_matrix_set(issc_env%matrix_pso, 3)
971 12 : ALLOCATE (issc_env%matrix_pso(1)%matrix)
972 : CALL dbcsr_create(matrix=issc_env%matrix_pso(1)%matrix, &
973 : name="pso x", &
974 : dist=dbcsr_dist, matrix_type=dbcsr_type_antisymmetric, &
975 : row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
976 12 : nze=0, mutable_work=.TRUE.)
977 12 : CALL cp_dbcsr_alloc_block_from_nbl(issc_env%matrix_pso(1)%matrix, sab_orb)
978 :
979 12 : ALLOCATE (issc_env%matrix_pso(2)%matrix, issc_env%matrix_pso(3)%matrix)
980 : CALL dbcsr_copy(issc_env%matrix_pso(2)%matrix, issc_env%matrix_pso(1)%matrix, &
981 12 : 'pso y')
982 : CALL dbcsr_copy(issc_env%matrix_pso(3)%matrix, issc_env%matrix_pso(1)%matrix, &
983 12 : 'pso z')
984 12 : CALL dbcsr_set(issc_env%matrix_pso(1)%matrix, 0.0_dp)
985 12 : CALL dbcsr_set(issc_env%matrix_pso(2)%matrix, 0.0_dp)
986 12 : CALL dbcsr_set(issc_env%matrix_pso(3)%matrix, 0.0_dp)
987 : !
988 : ! DSO
989 12 : CALL dbcsr_allocate_matrix_set(issc_env%matrix_dso, 3)
990 12 : ALLOCATE (issc_env%matrix_dso(1)%matrix, issc_env%matrix_dso(2)%matrix, issc_env%matrix_dso(3)%matrix)
991 : CALL dbcsr_copy(issc_env%matrix_dso(1)%matrix, issc_env%matrix_efg(1)%matrix, &
992 12 : 'dso x')
993 : CALL dbcsr_copy(issc_env%matrix_dso(2)%matrix, issc_env%matrix_efg(1)%matrix, &
994 12 : 'dso y')
995 : CALL dbcsr_copy(issc_env%matrix_dso(3)%matrix, issc_env%matrix_efg(1)%matrix, &
996 12 : 'dso z')
997 12 : CALL dbcsr_set(issc_env%matrix_dso(1)%matrix, 0.0_dp)
998 12 : CALL dbcsr_set(issc_env%matrix_dso(2)%matrix, 0.0_dp)
999 12 : CALL dbcsr_set(issc_env%matrix_dso(3)%matrix, 0.0_dp)
1000 : !
1001 : ! FC
1002 12 : CALL dbcsr_allocate_matrix_set(issc_env%matrix_fc, 1)
1003 12 : ALLOCATE (issc_env%matrix_fc(1)%matrix)
1004 : CALL dbcsr_copy(issc_env%matrix_fc(1)%matrix, issc_env%matrix_efg(1)%matrix, &
1005 12 : 'fc')
1006 12 : CALL dbcsr_set(issc_env%matrix_fc(1)%matrix, 0.0_dp)
1007 :
1008 12 : DEALLOCATE (row_blk_sizes)
1009 : !
1010 : ! Conversion factors
1011 12 : IF (output_unit > 0) THEN
1012 : WRITE (output_unit, "(T2,A,T60,I4,A)")&
1013 6 : & "ISSC| spin-spin coupling computed for ", issc_env%issc_natms, ' atoms'
1014 : END IF
1015 :
1016 : CALL cp_print_key_finished_output(output_unit, logger, lr_section,&
1017 12 : & "PRINT%PROGRAM_RUN_INFO")
1018 :
1019 12 : CALL timestop(handle)
1020 :
1021 24 : END SUBROUTINE issc_env_init
1022 :
1023 : ! **************************************************************************************************
1024 : !> \brief Deallocate the issc environment
1025 : !> \param issc_env ...
1026 : !> \par History
1027 : ! **************************************************************************************************
1028 24 : SUBROUTINE issc_env_cleanup(issc_env)
1029 :
1030 : TYPE(issc_env_type), INTENT(INOUT) :: issc_env
1031 :
1032 24 : IF (ASSOCIATED(issc_env%issc_on_atom_list)) THEN
1033 12 : DEALLOCATE (issc_env%issc_on_atom_list)
1034 : END IF
1035 24 : IF (ASSOCIATED(issc_env%issc)) THEN
1036 12 : DEALLOCATE (issc_env%issc)
1037 : END IF
1038 24 : IF (ASSOCIATED(issc_env%issc_loc)) THEN
1039 12 : DEALLOCATE (issc_env%issc_loc)
1040 : END IF
1041 : !
1042 : !efg_psi0
1043 24 : CALL cp_fm_release(issc_env%efg_psi0)
1044 : !
1045 : !pso_psi0
1046 24 : CALL cp_fm_release(issc_env%pso_psi0)
1047 : !
1048 : !dso_psi0
1049 24 : CALL cp_fm_release(issc_env%dso_psi0)
1050 : !
1051 : !fc_psi0
1052 24 : CALL cp_fm_release(issc_env%fc_psi0)
1053 : !
1054 : !psi1_efg
1055 24 : CALL cp_fm_release(issc_env%psi1_efg)
1056 : !
1057 : !psi1_pso
1058 24 : CALL cp_fm_release(issc_env%psi1_pso)
1059 : !
1060 : !psi1_dso
1061 24 : CALL cp_fm_release(issc_env%psi1_dso)
1062 : !
1063 : !psi1_fc
1064 24 : CALL cp_fm_release(issc_env%psi1_fc)
1065 : !
1066 : !matrix_efg
1067 24 : IF (ASSOCIATED(issc_env%matrix_efg)) THEN
1068 12 : CALL dbcsr_deallocate_matrix_set(issc_env%matrix_efg)
1069 : END IF
1070 : !
1071 : !matrix_pso
1072 24 : IF (ASSOCIATED(issc_env%matrix_pso)) THEN
1073 12 : CALL dbcsr_deallocate_matrix_set(issc_env%matrix_pso)
1074 : END IF
1075 : !
1076 : !matrix_dso
1077 24 : IF (ASSOCIATED(issc_env%matrix_dso)) THEN
1078 12 : CALL dbcsr_deallocate_matrix_set(issc_env%matrix_dso)
1079 : END IF
1080 : !
1081 : !matrix_fc
1082 24 : IF (ASSOCIATED(issc_env%matrix_fc)) THEN
1083 12 : CALL dbcsr_deallocate_matrix_set(issc_env%matrix_fc)
1084 : END IF
1085 :
1086 24 : END SUBROUTINE issc_env_cleanup
1087 :
1088 : END MODULE qs_linres_issc_utils
|