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 nmr_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 : !> \par History
19 : !> created 07-2005 [MI]
20 : !> \author MI
21 : ! **************************************************************************************************
22 : MODULE qs_linres_current_utils
23 : USE atomic_kind_types, ONLY: atomic_kind_type
24 : USE cell_types, ONLY: cell_type,&
25 : pbc
26 : USE cp_array_utils, ONLY: cp_2d_i_p_type,&
27 : cp_2d_r_p_type
28 : USE cp_control_types, ONLY: dft_control_type
29 : USE cp_dbcsr_api, ONLY: dbcsr_convert_offsets_to_sizes,&
30 : dbcsr_copy,&
31 : dbcsr_create,&
32 : dbcsr_distribution_type,&
33 : dbcsr_p_type,&
34 : dbcsr_set,&
35 : dbcsr_type_antisymmetric
36 : USE cp_dbcsr_cp2k_link, ONLY: cp_dbcsr_alloc_block_from_nbl
37 : USE cp_dbcsr_operations, ONLY: cp_dbcsr_sm_fm_multiply,&
38 : dbcsr_allocate_matrix_set,&
39 : dbcsr_deallocate_matrix_set
40 : USE cp_fm_basic_linalg, ONLY: cp_fm_column_scale,&
41 : cp_fm_scale_and_add
42 : USE cp_fm_struct, ONLY: cp_fm_struct_create,&
43 : cp_fm_struct_release,&
44 : cp_fm_struct_type
45 : USE cp_fm_types, ONLY: cp_fm_create,&
46 : cp_fm_release,&
47 : cp_fm_set_all,&
48 : cp_fm_to_fm,&
49 : cp_fm_type
50 : USE cp_log_handling, ONLY: cp_get_default_logger,&
51 : cp_logger_type,&
52 : cp_to_string
53 : USE cp_output_handling, ONLY: cp_p_file,&
54 : cp_print_key_finished_output,&
55 : cp_print_key_should_output,&
56 : cp_print_key_unit_nr
57 : USE input_constants, ONLY: current_gauge_atom,&
58 : current_gauge_r,&
59 : current_gauge_r_and_step_func,&
60 : current_orb_center_atom,&
61 : current_orb_center_box,&
62 : current_orb_center_common,&
63 : current_orb_center_wannier,&
64 : ot_precond_full_all
65 : USE input_section_types, ONLY: section_get_lval,&
66 : section_vals_get_subs_vals,&
67 : section_vals_type,&
68 : section_vals_val_get
69 : USE kinds, ONLY: default_path_length,&
70 : dp
71 : USE memory_utilities, ONLY: reallocate
72 : USE message_passing, ONLY: mp_para_env_type
73 : USE particle_methods, ONLY: get_particle_set
74 : USE particle_types, ONLY: particle_type
75 : USE pw_env_types, ONLY: pw_env_get,&
76 : pw_env_type
77 : USE pw_methods, ONLY: pw_zero
78 : USE pw_pool_types, ONLY: pw_pool_type
79 : USE pw_types, ONLY: pw_c1d_gs_type,&
80 : pw_r3d_rs_type
81 : USE qs_environment_types, ONLY: get_qs_env,&
82 : qs_environment_type
83 : USE qs_kind_types, ONLY: qs_kind_type
84 : USE qs_linres_methods, ONLY: linres_read_restart,&
85 : linres_solver,&
86 : linres_write_restart
87 : USE qs_linres_op, ONLY: set_vecp
88 : USE qs_linres_types, ONLY: current_env_type,&
89 : deallocate_jrho_atom_set,&
90 : get_current_env,&
91 : init_jrho_atom_set,&
92 : jrho_atom_type,&
93 : linres_control_type,&
94 : set_current_env
95 : USE qs_loc_methods, ONLY: qs_print_cubes
96 : USE qs_loc_types, ONLY: get_qs_loc_env,&
97 : localized_wfn_control_type,&
98 : qs_loc_env_type
99 : USE qs_matrix_pools, ONLY: qs_matrix_pools_type
100 : USE qs_mo_types, ONLY: get_mo_set,&
101 : mo_set_type
102 : USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
103 : USE qs_operators_ao, ONLY: build_lin_mom_matrix
104 : USE qs_p_env_types, ONLY: qs_p_env_type
105 : USE qs_rho_types, ONLY: qs_rho_clear,&
106 : qs_rho_create,&
107 : qs_rho_set
108 : USE realspace_grid_types, ONLY: rs_grid_release
109 : USE scf_control_types, ONLY: scf_control_type
110 : #include "./base/base_uses.f90"
111 :
112 : IMPLICIT NONE
113 :
114 : PRIVATE
115 : PUBLIC :: current_response, current_env_cleanup, current_env_init
116 :
117 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_linres_current_utils'
118 :
119 : CONTAINS
120 :
121 : ! **************************************************************************************************
122 : !> \brief ...
123 : !> \param current_env ...
124 : !> \param p_env ...
125 : !> \param qs_env ...
126 : ! **************************************************************************************************
127 174 : SUBROUTINE current_response(current_env, p_env, qs_env)
128 : !
129 : TYPE(current_env_type) :: current_env
130 : TYPE(qs_p_env_type) :: p_env
131 : TYPE(qs_environment_type), POINTER :: qs_env
132 :
133 : CHARACTER(LEN=*), PARAMETER :: routineN = 'current_response'
134 :
135 : CHARACTER(LEN=default_path_length) :: my_pos
136 : INTEGER :: first_center, handle, i, icenter, idir, ii, iii, ispin, ist_true, istate, j, &
137 : jcenter, jstate, max_nbr_center, max_states, nao, natom, nbr_center(2), ncubes, nmo, &
138 : nspins, nstates(2), output_unit
139 174 : INTEGER, ALLOCATABLE, DIMENSION(:) :: first_sgf, last_sgf
140 174 : INTEGER, DIMENSION(:), POINTER :: list_cubes, row_blk_sizes
141 174 : INTEGER, DIMENSION(:, :, :), POINTER :: statetrueindex
142 : LOGICAL :: append_cube, should_stop
143 : REAL(dp) :: dk(3), dkl(3), dl(3)
144 174 : REAL(dp), ALLOCATABLE, DIMENSION(:) :: dkl_vec_ii, dkl_vec_iii
145 174 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: vecbuf_dklxp0
146 : TYPE(cell_type), POINTER :: cell
147 174 : TYPE(cp_2d_i_p_type), DIMENSION(:), POINTER :: center_list
148 174 : TYPE(cp_2d_r_p_type), DIMENSION(:), POINTER :: centers_set
149 : TYPE(cp_fm_struct_type), POINTER :: tmp_fm_struct
150 174 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_work_ii, fm_work_iii, h1_psi0, psi1
151 174 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: hpsi0_ptr, psi0_order
152 174 : TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: p_psi0, psi1_D, psi1_p, psi1_rxp, &
153 174 : rxp_psi0
154 : TYPE(cp_fm_type), POINTER :: mo_coeff
155 : TYPE(cp_logger_type), POINTER :: logger
156 : TYPE(dbcsr_distribution_type), POINTER :: dbcsr_dist
157 174 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: op_p_ao
158 : TYPE(dft_control_type), POINTER :: dft_control
159 : TYPE(linres_control_type), POINTER :: linres_control
160 : TYPE(mp_para_env_type), POINTER :: para_env
161 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
162 174 : POINTER :: sab_orb
163 174 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
164 174 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
165 : TYPE(qs_matrix_pools_type), POINTER :: mpools
166 : TYPE(section_vals_type), POINTER :: current_section, lr_section, print_key
167 :
168 174 : CALL timeset(routineN, handle)
169 : !
170 174 : NULLIFY (cell, dft_control, linres_control, lr_section, current_section, &
171 174 : logger, mpools, mo_coeff, para_env, &
172 174 : tmp_fm_struct, &
173 174 : list_cubes, statetrueindex, centers_set, center_list, psi1_p, psi1_rxp, psi1_D, &
174 174 : p_psi0, rxp_psi0, psi0_order, op_p_ao, sab_orb, particle_set)
175 :
176 174 : logger => cp_get_default_logger()
177 174 : lr_section => section_vals_get_subs_vals(qs_env%input, "PROPERTIES%LINRES")
178 : current_section => section_vals_get_subs_vals(qs_env%input, &
179 174 : "PROPERTIES%LINRES%CURRENT")
180 :
181 : output_unit = cp_print_key_unit_nr(logger, lr_section, "PRINT%PROGRAM_RUN_INFO", &
182 174 : extension=".linresLog")
183 174 : IF (output_unit > 0) THEN
184 : WRITE (UNIT=output_unit, FMT="(T10,A,/)") &
185 87 : "*** Self consistent optimization of the response wavefunctions ***"
186 : END IF
187 :
188 : CALL get_qs_env(qs_env=qs_env, &
189 : dft_control=dft_control, &
190 : mpools=mpools, cell=cell, &
191 : linres_control=linres_control, &
192 : sab_orb=sab_orb, &
193 : particle_set=particle_set, &
194 : qs_kind_set=qs_kind_set, &
195 : dbcsr_dist=dbcsr_dist, &
196 174 : para_env=para_env)
197 :
198 174 : nspins = dft_control%nspins
199 :
200 : CALL get_current_env(current_env=current_env, &
201 : nao=nao, &
202 : nstates=nstates, &
203 : centers_set=centers_set, &
204 : nbr_center=nbr_center, &
205 : center_list=center_list, &
206 : list_cubes=list_cubes, &
207 : statetrueindex=statetrueindex, &
208 : psi1_p=psi1_p, &
209 : psi1_rxp=psi1_rxp, &
210 : psi1_D=psi1_D, &
211 : p_psi0=p_psi0, &
212 : rxp_psi0=rxp_psi0, &
213 174 : psi0_order=psi0_order)
214 : !
215 : ! allocate the vectors
216 174 : IF (current_env%full) THEN
217 980 : ALLOCATE (psi1(nspins), h1_psi0(nspins))
218 348 : DO ispin = 1, nspins
219 206 : mo_coeff => psi0_order(ispin)
220 206 : NULLIFY (tmp_fm_struct)
221 : CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nao, &
222 : ncol_global=nstates(ispin), &
223 206 : context=mo_coeff%matrix_struct%context)
224 206 : CALL cp_fm_create(psi1(ispin), tmp_fm_struct)
225 206 : CALL cp_fm_create(h1_psi0(ispin), tmp_fm_struct)
226 348 : CALL cp_fm_struct_release(tmp_fm_struct)
227 : END DO
228 : !
229 : ! prepare for allocation
230 142 : natom = SIZE(particle_set, 1)
231 426 : ALLOCATE (first_sgf(natom))
232 284 : ALLOCATE (last_sgf(natom))
233 : CALL get_particle_set(particle_set, qs_kind_set, &
234 : first_sgf=first_sgf, &
235 142 : last_sgf=last_sgf)
236 284 : ALLOCATE (row_blk_sizes(natom))
237 142 : CALL dbcsr_convert_offsets_to_sizes(first_sgf, row_blk_sizes, last_sgf)
238 142 : DEALLOCATE (first_sgf, last_sgf)
239 : !
240 : ! rebuild the linear momentum matrices
241 142 : CALL dbcsr_allocate_matrix_set(op_p_ao, 3)
242 142 : ALLOCATE (op_p_ao(1)%matrix)
243 : CALL dbcsr_create(matrix=op_p_ao(1)%matrix, &
244 : name="OP_P", &
245 : dist=dbcsr_dist, matrix_type=dbcsr_type_antisymmetric, &
246 : row_blk_size=row_blk_sizes, col_blk_size=row_blk_sizes, &
247 142 : nze=0, mutable_work=.TRUE.)
248 142 : CALL cp_dbcsr_alloc_block_from_nbl(op_p_ao(1)%matrix, sab_orb)
249 : !
250 : !
251 142 : DEALLOCATE (row_blk_sizes)
252 : !
253 : !
254 142 : CALL dbcsr_set(op_p_ao(1)%matrix, 0.0_dp)
255 426 : DO idir = 2, 3
256 284 : ALLOCATE (op_p_ao(idir)%matrix)
257 : CALL dbcsr_copy(op_p_ao(idir)%matrix, op_p_ao(1)%matrix, &
258 284 : "current_env%op_p_ao"//"-"//TRIM(ADJUSTL(cp_to_string(idir))))
259 426 : CALL dbcsr_set(op_p_ao(idir)%matrix, 0.0_dp)
260 : END DO
261 : !
262 : !CALL p_xyz_ao(op_p_ao,qs_env,minimum_image=.FALSE.)
263 142 : CALL build_lin_mom_matrix(qs_env, op_p_ao)
264 : !
265 : END IF
266 : !
267 : ! set response to zero
268 : !
269 696 : DO idir = 1, 3
270 1446 : DO ispin = 1, nspins
271 750 : CALL cp_fm_set_all(psi1_p(ispin, idir), 0.0_dp)
272 750 : CALL cp_fm_set_all(psi1_rxp(ispin, idir), 0.0_dp)
273 1272 : IF (current_env%full) CALL cp_fm_set_all(psi1_D(ispin, idir), 0.0_dp)
274 : END DO
275 : END DO
276 : !
277 : !
278 : !
279 : ! load restart file
280 : !
281 174 : first_center = 0
282 174 : IF (linres_control%linres_restart) THEN
283 24 : DO idir = 1, 3
284 : ! operator p
285 18 : CALL linres_read_restart(qs_env, lr_section, psi1_p(:, idir), idir, "nmr_p")
286 : ! operator rxp
287 24 : CALL linres_read_restart(qs_env, lr_section, psi1_rxp(:, idir), idir, "nmr_rxp")
288 : END DO
289 : END IF
290 : !
291 : !
292 : !
293 : !
294 174 : should_stop = .FALSE.
295 174 : current_env%all_pert_op_done = .FALSE.
296 : ! operator p
297 696 : DO idir = 1, 3
298 522 : IF (should_stop) EXIT
299 522 : IF (output_unit > 0) THEN
300 261 : WRITE (output_unit, "(T10,A)") "Response to the perturbation operator P_"//ACHAR(idir + 119)
301 : END IF
302 : !
303 : ! Initial guess for psi1
304 522 : hpsi0_ptr => p_psi0(:, idir)
305 : !
306 : !
307 522 : linres_control%converged = .FALSE.
308 522 : CALL linres_solver(p_env, qs_env, psi1_p(:, idir), hpsi0_ptr, psi0_order, output_unit, should_stop)
309 : !
310 : !
311 : ! print response functions
312 522 : IF (BTEST(cp_print_key_should_output(logger%iter_info, current_section,&
313 : & "PRINT%RESPONSE_FUNCTION_CUBES"), cp_p_file)) THEN
314 0 : ncubes = SIZE(list_cubes, 1)
315 0 : print_key => section_vals_get_subs_vals(current_section, "PRINT%RESPONSE_FUNCTION_CUBES")
316 0 : append_cube = section_get_lval(current_section, "PRINT%RESPONSE_FUNCTION_CUBES%APPEND")
317 0 : my_pos = "REWIND"
318 0 : IF (append_cube) THEN
319 0 : my_pos = "APPEND"
320 : END IF
321 : !
322 :
323 0 : DO ispin = 1, nspins
324 : CALL qs_print_cubes(qs_env, psi1_p(ispin, idir), ncubes, list_cubes, &
325 : centers_set(ispin)%array, print_key, 'psi1_p', &
326 0 : idir=idir, ispin=ispin, file_position=my_pos)
327 : END DO ! ispin
328 : END IF ! print response functions
329 : !
330 : ! write restart file
331 696 : CALL linres_write_restart(qs_env, lr_section, psi1_p(:, idir), idir, "nmr_p")
332 : END DO ! idir
333 : !
334 : ! operator rxp
335 696 : DO idir = 1, 3
336 522 : IF (should_stop) EXIT
337 522 : IF (output_unit > 0) THEN
338 261 : WRITE (output_unit, "(T10,A)") "Response to the perturbation operator L_"//ACHAR(idir + 119)
339 : END IF
340 : !
341 : ! Initial guess for psi1
342 522 : hpsi0_ptr => rxp_psi0(:, idir)
343 : !
344 : !
345 522 : linres_control%converged = .FALSE.
346 522 : CALL linres_solver(p_env, qs_env, psi1_rxp(:, idir), hpsi0_ptr, psi0_order, output_unit, should_stop)
347 : !
348 : ! print response functions
349 522 : IF (BTEST(cp_print_key_should_output(logger%iter_info, current_section,&
350 : & "PRINT%RESPONSE_FUNCTION_CUBES"), cp_p_file)) THEN
351 0 : ncubes = SIZE(list_cubes, 1)
352 0 : print_key => section_vals_get_subs_vals(current_section, "PRINT%RESPONSE_FUNCTION_CUBES")
353 :
354 0 : DO ispin = 1, nspins
355 : CALL qs_print_cubes(qs_env, psi1_rxp(ispin, idir), ncubes, list_cubes, &
356 : centers_set(ispin)%array, print_key, 'psi1_rxp', &
357 0 : idir=idir, ispin=ispin, file_position=my_pos)
358 : END DO ! ispin
359 : END IF ! print response functions
360 : !
361 : ! write restart file
362 696 : CALL linres_write_restart(qs_env, lr_section, psi1_rxp(:, idir), idir, "nmr_rxp")
363 : END DO ! idir
364 174 : IF (.NOT. should_stop) current_env%all_pert_op_done = .TRUE.
365 : !
366 : ! operator D
367 174 : IF (current_env%full) THEN
368 142 : current_env%all_pert_op_done = .FALSE.
369 : !
370 : !
371 348 : DO ispin = 1, nspins
372 348 : CALL cp_fm_set_all(psi1(ispin), 0.0_dp)
373 : END DO
374 : !
375 : ! The correction is state depedent a loop over the states is necessary
376 348 : max_nbr_center = MAXVAL(nbr_center(1:nspins))
377 348 : max_states = MAXVAL(nstates(1:nspins))
378 : !
379 0 : ALLOCATE (vecbuf_dklxp0(1, nao), fm_work_ii(nspins), fm_work_iii(nspins), &
380 1690 : dkl_vec_ii(max_states), dkl_vec_iii(max_states))
381 142 : vecbuf_dklxp0(1, nao) = 0.0_dp
382 : !
383 348 : DO ispin = 1, nspins
384 206 : nmo = nstates(ispin)
385 206 : mo_coeff => psi0_order(ispin)
386 206 : NULLIFY (tmp_fm_struct)
387 : CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nao, &
388 : ncol_global=nmo, para_env=para_env, &
389 206 : context=mo_coeff%matrix_struct%context)
390 :
391 206 : CALL cp_fm_create(fm_work_ii(ispin), tmp_fm_struct)
392 206 : CALL cp_fm_set_all(fm_work_ii(ispin), 0.0_dp)
393 206 : CALL cp_fm_create(fm_work_iii(ispin), tmp_fm_struct)
394 206 : CALL cp_fm_set_all(fm_work_iii(ispin), 0.0_dp)
395 348 : CALL cp_fm_struct_release(tmp_fm_struct)
396 : END DO ! ispin
397 : !
398 568 : DO idir = 1, 3
399 426 : IF (should_stop) EXIT
400 1044 : DO ispin = 1, nspins
401 1044 : CALL cp_fm_set_all(psi1_D(ispin, idir), 0.0_dp)
402 : END DO
403 426 : first_center = 0
404 426 : IF (linres_control%linres_restart) THEN
405 18 : CALL linres_read_restart(qs_env, lr_section, psi1_D(:, idir), idir, "nmr_dxp-", ind=first_center)
406 : END IF
407 426 : IF (first_center > 0) THEN
408 6 : IF (output_unit > 0) THEN
409 : WRITE (output_unit, "(T10,A,I4,A)")&
410 3 : & "Response to the perturbation operators (dk-dl)xp up to state ", &
411 6 : first_center, " have been read from restart"
412 : END IF
413 : END IF
414 : !
415 : ! here we run over the max number of states, then we need
416 : ! to be careful with overflow while doing uks calculations.
417 2886 : DO icenter = 1, max_nbr_center
418 : !
419 2460 : IF (should_stop) EXIT
420 2460 : IF (icenter > first_center) THEN
421 2436 : IF (output_unit > 0) THEN
422 : WRITE (output_unit, "(T10,A,I4,A)")&
423 1218 : & "Response to the perturbation operator (dk-dl)xp for -state- ", &
424 2436 : icenter, " in dir. "//ACHAR(idir + 119)
425 : END IF
426 : !
427 6306 : DO ispin = 1, nspins
428 3870 : nmo = nstates(ispin)
429 3870 : mo_coeff => psi0_order(ispin)
430 : !
431 : ! take care that no overflow can occur for uks
432 3870 : IF (icenter .GT. nbr_center(ispin)) THEN
433 : !
434 : ! set h1_psi0 and psi1 to zero to avoid problems in linres_scf
435 276 : CALL cp_fm_set_all(h1_psi0(ispin), 0.0_dp)
436 276 : CALL cp_fm_set_all(psi1(ispin), 0.0_dp)
437 276 : CYCLE
438 : END IF
439 : !
440 30702 : dkl_vec_ii(:) = 0.0_dp
441 30702 : dkl_vec_iii(:) = 0.0_dp
442 : !
443 3594 : ist_true = statetrueindex(idir, icenter, ispin)
444 : !
445 : ! the initial guess is the previous set of psi1, just optimized
446 3594 : CALL set_vecp(idir, ii, iii)
447 14376 : dk(1:3) = centers_set(ispin)%array(1:3, ist_true)
448 : !
449 27612 : DO jcenter = 1, nbr_center(ispin)
450 96072 : dl(1:3) = centers_set(ispin)%array(1:3, jcenter)
451 24018 : dkl = pbc(dl, dk, cell)
452 52962 : DO j = center_list(ispin)%array(1, jcenter), center_list(ispin)%array(1, jcenter + 1) - 1
453 25350 : jstate = center_list(ispin)%array(2, j)
454 25350 : dkl_vec_ii(jstate) = dkl(ii)
455 49368 : dkl_vec_iii(jstate) = dkl(iii)
456 : END DO
457 : END DO
458 : !
459 : ! First term
460 : ! Rescale the ground state orbitals by (dk-dl)_ii
461 3594 : CALL cp_fm_to_fm(mo_coeff, fm_work_ii(ispin))
462 3594 : CALL cp_fm_column_scale(fm_work_ii(ispin), dkl_vec_ii(1:nmo))
463 : !
464 : ! Apply the p_iii operator
465 : ! fm_work_iii = -p_iii * (dk-dl)_ii * C0
466 : CALL cp_dbcsr_sm_fm_multiply(op_p_ao(iii)%matrix, fm_work_ii(ispin), &
467 3594 : fm_work_iii(ispin), ncol=nmo, alpha=-1.0_dp)
468 : !
469 : ! Copy in h1_psi0
470 : ! h1_psi0_i = fm_work_iii
471 3594 : CALL cp_fm_to_fm(fm_work_iii(ispin), h1_psi0(ispin))
472 : !
473 : ! Second term
474 : ! Rescale the ground state orbitals by (dk-dl)_iii
475 3594 : CALL cp_fm_to_fm(mo_coeff, fm_work_iii(ispin))
476 3594 : CALL cp_fm_column_scale(fm_work_iii(ispin), dkl_vec_iii(1:nmo))
477 : !
478 : ! Apply the p_ii operator
479 : ! fm_work_ii = -p_ii * (dk-dl)_iii * C0
480 : CALL cp_dbcsr_sm_fm_multiply(op_p_ao(ii)%matrix, fm_work_iii(ispin), &
481 3594 : fm_work_ii(ispin), ncol=nmo, alpha=-1.0_dp)
482 : !
483 : ! Copy in h1_psi0
484 : ! h1_psi0_i = fm_work_iii - fm_work_ii
485 : CALL cp_fm_scale_and_add(1.0_dp, h1_psi0(ispin),&
486 9624 : & -1.0_dp, fm_work_ii(ispin))
487 : END DO
488 :
489 : !
490 : ! Optimize the response wavefunctions
491 2436 : CALL linres_solver(p_env, qs_env, psi1, h1_psi0, psi0_order, output_unit, should_stop)
492 : !
493 2436 : IF (output_unit > 0) THEN
494 : WRITE (output_unit, "(T10,A,/)")&
495 1218 : & "Store the psi1 vector for the calculation of the response current density "
496 : END IF
497 : !
498 6306 : DO ispin = 1, nspins
499 : !
500 : ! take care that no overflow can occur for uks
501 3870 : IF (icenter .GT. nbr_center(ispin)) CYCLE
502 : !
503 : ! need to reset those guys
504 3594 : ist_true = statetrueindex(idir, icenter, ispin)
505 7566 : DO i = center_list(ispin)%array(1, ist_true), center_list(ispin)%array(1, ist_true + 1) - 1
506 3972 : istate = center_list(ispin)%array(2, i)
507 : !
508 : ! the optimized wfns are copied in the fm
509 7566 : CALL cp_fm_to_fm(psi1(ispin), psi1_D(ispin, idir), 1, istate, istate)
510 : END DO
511 6306 : current_env%full_done(idir*ispin, icenter) = .TRUE.
512 : END DO ! ispin
513 : !
514 : ELSE
515 48 : DO ispin = 1, nspins
516 48 : current_env%full_done(idir*ispin, icenter) = .TRUE.
517 : END DO ! ispin
518 : END IF
519 2886 : CALL linres_write_restart(qs_env, lr_section, psi1_D(:, idir), idir, "nmr_dxp-", ind=icenter)
520 :
521 : END DO ! center
522 : !
523 : ! print response functions
524 426 : IF (BTEST(cp_print_key_should_output(logger%iter_info, current_section,&
525 142 : & "PRINT%RESPONSE_FUNCTION_CUBES"), cp_p_file)) THEN
526 0 : ncubes = SIZE(list_cubes, 1)
527 0 : print_key => section_vals_get_subs_vals(current_section, "PRINT%RESPONSE_FUNCTION_CUBES")
528 0 : DO ispin = 1, nspins
529 : CALL qs_print_cubes(qs_env, psi1_D(ispin, idir), &
530 : ncubes, list_cubes, centers_set(ispin)%array, print_key, 'psi1_D', &
531 0 : idir=idir, ispin=ispin, file_position=my_pos)
532 : END DO
533 : END IF ! print response functions
534 : !
535 : END DO ! idir
536 142 : IF (.NOT. should_stop) current_env%all_pert_op_done = .TRUE.
537 : !
538 : ! clean up
539 142 : CALL cp_fm_release(fm_work_ii)
540 142 : CALL cp_fm_release(fm_work_iii)
541 142 : DEALLOCATE (dkl_vec_ii, dkl_vec_iii, vecbuf_dklxp0)
542 :
543 : END IF
544 : !
545 : ! clean up
546 174 : IF (current_env%full) THEN
547 142 : CALL dbcsr_deallocate_matrix_set(op_p_ao)
548 142 : CALL cp_fm_release(psi1)
549 142 : CALL cp_fm_release(h1_psi0)
550 : END IF
551 : !
552 : CALL cp_print_key_finished_output(output_unit, logger, lr_section,&
553 174 : & "PRINT%PROGRAM_RUN_INFO")
554 : !
555 174 : CALL timestop(handle)
556 : !
557 348 : END SUBROUTINE current_response
558 :
559 : ! **************************************************************************************************
560 :
561 : ! **************************************************************************************************
562 : !> \brief ...
563 : !> \param current_env ...
564 : !> \param qs_env ...
565 : ! **************************************************************************************************
566 174 : SUBROUTINE current_env_init(current_env, qs_env)
567 : !
568 : TYPE(current_env_type) :: current_env
569 : TYPE(qs_environment_type), POINTER :: qs_env
570 :
571 : CHARACTER(LEN=*), PARAMETER :: routineN = 'current_env_init'
572 :
573 : INTEGER :: handle, homo, i, iao, iatom, ibox, icenter, icount, idir, ii, ini, ir, is, ispin, &
574 : istate, istate2, istate_next, ix, iy, iz, j, jstate, k, max_nbr_center, max_states, n, &
575 : n_rep, nao, natom, nbr_box, ncubes, nmo, nspins, nstate, nstate_list(2), output_unit
576 174 : INTEGER, ALLOCATABLE, DIMENSION(:) :: buff, first_sgf, last_sgf
577 174 : INTEGER, ALLOCATABLE, DIMENSION(:, :) :: state_list
578 174 : INTEGER, DIMENSION(:), POINTER :: bounds, list, nbox, &
579 174 : selected_states_on_atom_list
580 : LOGICAL :: force_no_full, gapw, is0, &
581 : uniform_occupation
582 174 : LOGICAL, ALLOCATABLE, DIMENSION(:, :) :: state_done
583 : REAL(dp) :: center(3), center2(3), dist, mdist, &
584 : r(3), rab(3)
585 174 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: rbuff
586 174 : REAL(dp), DIMENSION(:), POINTER :: common_center
587 174 : REAL(dp), DIMENSION(:, :), POINTER :: center_array
588 174 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
589 : TYPE(cell_type), POINTER :: cell
590 : TYPE(cp_fm_struct_type), POINTER :: tmp_fm_struct
591 : TYPE(cp_fm_type), POINTER :: mo_coeff
592 : TYPE(cp_logger_type), POINTER :: logger
593 : TYPE(dft_control_type), POINTER :: dft_control
594 174 : TYPE(jrho_atom_type), DIMENSION(:), POINTER :: jrho1_atom_set
595 : TYPE(linres_control_type), POINTER :: linres_control
596 : TYPE(localized_wfn_control_type), POINTER :: localized_wfn_control
597 174 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
598 : TYPE(mp_para_env_type), POINTER :: para_env
599 174 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
600 174 : TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
601 : TYPE(pw_env_type), POINTER :: pw_env
602 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
603 174 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
604 174 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
605 : TYPE(qs_loc_env_type), POINTER :: qs_loc_env
606 : TYPE(qs_matrix_pools_type), POINTER :: mpools
607 : TYPE(scf_control_type), POINTER :: scf_control
608 : TYPE(section_vals_type), POINTER :: current_section, lr_section
609 :
610 174 : CALL timeset(routineN, handle)
611 :
612 174 : NULLIFY (atomic_kind_set, qs_kind_set, cell, dft_control, linres_control, scf_control, &
613 174 : logger, mos, mpools, current_section, particle_set, mo_coeff, &
614 174 : auxbas_pw_pool, pw_env, jrho1_atom_set, common_center, tmp_fm_struct, &
615 174 : para_env, qs_loc_env, localized_wfn_control, rho_g, rho_r)
616 : !
617 : !
618 : CALL get_qs_env(qs_env=qs_env, &
619 : atomic_kind_set=atomic_kind_set, &
620 : qs_kind_set=qs_kind_set, &
621 : cell=cell, &
622 : dft_control=dft_control, &
623 : linres_control=linres_control, &
624 : mos=mos, &
625 : mpools=mpools, &
626 : particle_set=particle_set, &
627 : pw_env=pw_env, &
628 : scf_control=scf_control, &
629 174 : para_env=para_env)
630 : !
631 174 : gapw = dft_control%qs_control%gapw
632 174 : nspins = dft_control%nspins
633 174 : natom = SIZE(particle_set, 1)
634 174 : CALL get_mo_set(mo_set=mos(1), nao=nao)
635 : !
636 174 : max_states = 0
637 424 : DO ispin = 1, nspins
638 250 : CALL get_mo_set(mo_set=mos(ispin), nmo=nmo)
639 424 : max_states = MAX(max_states, nmo)
640 : END DO
641 : !
642 : !
643 : !
644 : ! some checks
645 424 : DO ispin = 1, nspins
646 : CALL get_mo_set(mo_set=mos(ispin), nmo=nmo, homo=homo, &
647 250 : uniform_occupation=uniform_occupation)
648 : !
649 : ! check that homo=nmo
650 250 : IF (nmo .NE. homo) CPABORT("nmo != homo")
651 : !
652 : ! check that the nbr of localized states is equal to the nbr of states
653 : ! nmoloc = SIZE(linres_control%localized_wfn_control%centers_set(ispin)%array,2)
654 : ! IF (nmoloc.NE.nmo) CALL cp_abort(__LOCATION__,&
655 : ! "The nbr of localized functions "//&
656 : ! & "is not equal to the nbr of states.")
657 : !
658 : ! check that the occupation is uniform
659 674 : IF (.NOT. uniform_occupation) CPABORT("nmo != homo")
660 : END DO
661 : !
662 : !
663 174 : logger => cp_get_default_logger()
664 174 : lr_section => section_vals_get_subs_vals(qs_env%input, "PROPERTIES%LINRES")
665 : output_unit = cp_print_key_unit_nr(logger, lr_section, "PRINT%PROGRAM_RUN_INFO", &
666 174 : extension=".linresLog")
667 :
668 174 : IF (output_unit > 0) THEN
669 87 : WRITE (output_unit, "(/,T20,A,/)") "*** Start current Calculation ***"
670 87 : WRITE (output_unit, "(T10,A,/)") "Inizialization of the current environment"
671 : END IF
672 :
673 174 : CALL current_env_cleanup(current_env)
674 174 : current_env%gauge_init = .FALSE.
675 4698 : current_env%chi_tensor(:, :, :) = 0.0_dp
676 4698 : current_env%chi_tensor_loc(:, :, :) = 0.0_dp
677 174 : current_env%nao = nao
678 174 : current_env%full = .TRUE.
679 174 : current_env%do_selected_states = .FALSE.
680 : !
681 : ! If current_density or full_nmr different allocations are required
682 174 : current_section => section_vals_get_subs_vals(qs_env%input, "PROPERTIES%LINRES%CURRENT")
683 : !
684 : ! Select the gauge
685 174 : CALL section_vals_val_get(current_section, "GAUGE", i_val=current_env%gauge)
686 178 : SELECT CASE (current_env%gauge)
687 : CASE (current_gauge_r)
688 4 : current_env%gauge_name = "R"
689 : CASE (current_gauge_r_and_step_func)
690 142 : current_env%gauge_name = "R_AND_STEP_FUNCTION"
691 : CASE (current_gauge_atom)
692 28 : current_env%gauge_name = "ATOM"
693 : CASE DEFAULT
694 174 : CPABORT("Unknown gauge, try again...")
695 : END SELECT
696 : !
697 : ! maximal radius to build the atom gauge
698 : CALL section_vals_val_get(current_section, "GAUGE_ATOM_RADIUS", &
699 174 : r_val=current_env%gauge_atom_radius)
700 : ! use old gauge atom
701 : CALL section_vals_val_get(current_section, "USE_OLD_GAUGE_ATOM", &
702 174 : l_val=current_env%use_old_gauge_atom)
703 : ! chi for pbc
704 174 : CALL section_vals_val_get(current_section, "CHI_PBC", l_val=current_env%chi_pbc)
705 : !
706 : ! use old gauge atom
707 : CALL section_vals_val_get(current_section, "USE_OLD_GAUGE_ATOM", &
708 174 : l_val=current_env%use_old_gauge_atom)
709 : !
710 : ! chi for pbc
711 174 : CALL section_vals_val_get(current_section, "CHI_PBC", l_val=current_env%chi_pbc)
712 : !
713 : ! which center for the orbitals shall we use
714 174 : CALL section_vals_val_get(current_section, "ORBITAL_CENTER", i_val=current_env%orb_center)
715 300 : SELECT CASE (current_env%orb_center)
716 : CASE (current_orb_center_wannier)
717 : !
718 126 : current_env%orb_center_name = "WANNIER"
719 : CASE (current_orb_center_common)
720 : !
721 32 : current_env%orb_center_name = "COMMON"
722 32 : current_env%full = .FALSE.
723 : !
724 : ! Is there a user specified common_center?
725 32 : CALL section_vals_val_get(current_section, "COMMON_CENTER", r_vals=common_center)
726 : CASE (current_orb_center_atom)
727 : !
728 10 : current_env%orb_center_name = "ATOM"
729 : CASE (current_orb_center_box)
730 : !
731 6 : current_env%orb_center_name = "BOX"
732 : !
733 : ! Is there a user specified nbox?
734 6 : CALL section_vals_val_get(current_section, "NBOX", i_vals=nbox)
735 : CASE DEFAULT
736 174 : CPABORT("Unknown orbital center, try again...")
737 : END SELECT
738 :
739 174 : CALL section_vals_val_get(current_section, "FORCE_NO_FULL", l_val=force_no_full)
740 174 : IF (force_no_full) current_env%full = .FALSE.
741 : !
742 : ! Check if restat also psi0 should be restarted
743 : !IF(current_env%restart_current .AND. scf_control%density_guess/=restart_guess)THEN
744 : ! CPABORT("restart_nmr requires density_guess=restart")
745 : !ENDIF
746 : !
747 : ! check that the psi0 are localized and you have all the centers
748 174 : CPASSERT(linres_control%localized_psi0)
749 174 : IF (output_unit > 0) THEN
750 : WRITE (output_unit, '(A)') &
751 87 : ' To get CURRENT parameters within PBC you need localized zero order orbitals '
752 : END IF
753 174 : qs_loc_env => linres_control%qs_loc_env
754 174 : CALL get_qs_loc_env(qs_loc_env, localized_wfn_control=localized_wfn_control)
755 : !
756 : !
757 : ALLOCATE (current_env%centers_set(nspins), current_env%center_list(nspins), &
758 1718 : state_list(max_states, nspins))
759 2196 : state_list(:, :) = HUGE(0)
760 522 : nstate_list(:) = HUGE(0)
761 : !
762 : !
763 : !
764 : ! if qmmm is selected change the definition of the center of the box 0 -> L/2
765 174 : IF (current_env%do_qmmm) THEN
766 12 : DO ispin = 1, nspins
767 42 : DO istate = 1, SIZE(localized_wfn_control%centers_set(ispin)%array, 2)
768 : ! just to be sure...
769 30 : r(:) = pbc(localized_wfn_control%centers_set(ispin)%array(:, istate), cell)
770 30 : IF (r(1) .LT. 0.0_dp) THEN
771 : localized_wfn_control%centers_set(ispin)%array(1, istate) = &
772 6 : r(1) + cell%hmat(1, 1)
773 : END IF
774 30 : IF (r(2) .LT. 0.0_dp) THEN
775 : localized_wfn_control%centers_set(ispin)%array(2, istate) = &
776 24 : r(2) + cell%hmat(2, 2)
777 : END IF
778 36 : IF (r(3) .LT. 0.0_dp) THEN
779 : localized_wfn_control%centers_set(ispin)%array(3, istate) = &
780 6 : r(3) + cell%hmat(3, 3)
781 : END IF
782 : END DO
783 : END DO
784 : END IF
785 : !
786 : !
787 : !
788 : ! if the user has requested to compute the response for a subset of the states
789 : ! we collect them here. it requies the states to be localized!
790 : CALL section_vals_val_get(current_section, "SELECTED_STATES_ATOM_RADIUS", &
791 174 : r_val=current_env%selected_states_atom_radius)
792 174 : CALL section_vals_val_get(current_section, "SELECTED_STATES_ON_ATOM_LIST", n_rep_val=n_rep)
793 : !
794 174 : current_env%do_selected_states = n_rep .GT. 0
795 : !
796 : ! for the moment selected states doesnt work with the preconditioner FULL_ALL
797 174 : IF (linres_control%preconditioner_type .EQ. ot_precond_full_all .AND. current_env%do_selected_states) &
798 0 : CPABORT("Selected states doesnt work with the preconditioner FULL_ALL")
799 : !
800 : !
801 174 : NULLIFY (current_env%selected_states_on_atom_list)
802 174 : n = 0
803 182 : DO ir = 1, n_rep
804 8 : NULLIFY (list)
805 : CALL section_vals_val_get(current_section, "SELECTED_STATES_ON_ATOM_LIST", &
806 8 : i_rep_val=ir, i_vals=list)
807 182 : IF (ASSOCIATED(list)) THEN
808 8 : CALL reallocate(current_env%selected_states_on_atom_list, 1, n + SIZE(list))
809 32 : DO ini = 1, SIZE(list)
810 32 : current_env%selected_states_on_atom_list(ini + n) = list(ini)
811 : END DO
812 8 : n = n + SIZE(list)
813 : END IF
814 : END DO
815 : !
816 : ! build the subset
817 174 : IF (current_env%do_selected_states) THEN
818 8 : selected_states_on_atom_list => current_env%selected_states_on_atom_list
819 20 : DO ispin = 1, nspins
820 12 : center_array => localized_wfn_control%centers_set(ispin)%array
821 12 : nstate = 0
822 184 : DO istate = 1, SIZE(center_array, 2)
823 436 : DO i = 1, SIZE(selected_states_on_atom_list, 1)
824 364 : iatom = selected_states_on_atom_list(i)
825 1456 : r(:) = pbc(center_array(1:3, istate) - particle_set(iatom)%r(:), cell)
826 : ! SQRT(DOT_PRODUCT(r, r)) .LE. current_env%selected_states_atom_radius
827 1456 : IF ((DOT_PRODUCT(r, r)) .LE. (current_env%selected_states_atom_radius &
828 : *current_env%selected_states_atom_radius)) &
829 60 : THEN
830 : !
831 : ! add the state to the list
832 112 : nstate = nstate + 1
833 112 : state_list(nstate, ispin) = istate
834 112 : EXIT
835 : END IF
836 : END DO
837 : END DO
838 20 : nstate_list(ispin) = nstate
839 : END DO
840 : ELSE
841 404 : DO ispin = 1, nspins
842 238 : center_array => localized_wfn_control%centers_set(ispin)%array
843 238 : nstate = 0
844 1724 : DO istate = 1, SIZE(center_array, 2)
845 1486 : nstate = nstate + 1
846 1724 : state_list(nstate, ispin) = istate
847 : END DO
848 404 : nstate_list(ispin) = nstate
849 : END DO
850 : END IF
851 : !
852 : !
853 : !
854 : ! clustering the states
855 424 : DO ispin = 1, nspins
856 250 : nstate = nstate_list(ispin)
857 250 : current_env%nstates(ispin) = nstate
858 : !
859 : ALLOCATE (current_env%center_list(ispin)%array(2, nstate + 1), &
860 1250 : current_env%centers_set(ispin)%array(3, nstate))
861 5794 : current_env%center_list(ispin)%array(:, :) = HUGE(0)
862 6642 : current_env%centers_set(ispin)%array(:, :) = HUGE(0.0_dp)
863 : !
864 250 : center_array => localized_wfn_control%centers_set(ispin)%array
865 : !
866 : ! point to the psi0 centers
867 174 : SELECT CASE (current_env%orb_center)
868 : CASE (current_orb_center_wannier)
869 : !
870 : ! use the wannier center as -center-
871 180 : current_env%nbr_center(ispin) = nstate
872 1284 : DO is = 1, nstate
873 1104 : istate = state_list(is, ispin)
874 4416 : current_env%centers_set(ispin)%array(1:3, is) = center_array(1:3, istate)
875 1104 : current_env%center_list(ispin)%array(1, is) = is
876 1284 : current_env%center_list(ispin)%array(2, is) = istate
877 : END DO
878 180 : current_env%center_list(ispin)%array(1, nstate + 1) = nstate + 1
879 : !
880 : CASE (current_orb_center_common)
881 : !
882 : ! use a common -center-
883 176 : current_env%centers_set(ispin)%array(:, 1) = common_center(:)
884 44 : current_env%nbr_center(ispin) = 1
885 44 : current_env%center_list(ispin)%array(1, 1) = 1
886 44 : current_env%center_list(ispin)%array(1, 2) = nstate + 1
887 310 : DO is = 1, nstate
888 266 : istate = state_list(is, ispin)
889 310 : current_env%center_list(ispin)%array(2, is) = istate
890 : END DO
891 : !
892 : CASE (current_orb_center_atom)
893 : !
894 : ! use the atom as -center-
895 48 : ALLOCATE (buff(nstate_list(ispin)))
896 158 : buff(:) = 0
897 : !
898 158 : DO is = 1, nstate
899 142 : istate = state_list(is, ispin)
900 142 : mdist = HUGE(0.0_dp)
901 712 : DO iatom = 1, natom
902 554 : r = pbc(particle_set(iatom)%r(:), cell)
903 554 : rab = pbc(r, center_array(1:3, istate), cell)
904 554 : dist = SQRT(rab(1)**2 + rab(2)**2 + rab(3)**2)
905 696 : IF (dist .LT. mdist) THEN
906 322 : buff(is) = iatom
907 322 : mdist = dist
908 : END IF
909 : END DO
910 : END DO
911 : !
912 16 : i = 0
913 16 : ii = 1
914 16 : current_env%center_list(ispin)%array(1, 1) = 1
915 76 : DO iatom = 1, natom
916 60 : j = 0
917 60 : is0 = .TRUE.
918 614 : DO is = 1, nstate
919 554 : istate = state_list(is, ispin)
920 614 : IF (buff(is) .EQ. iatom) THEN
921 142 : j = j + 1
922 142 : i = i + 1
923 142 : is0 = .FALSE.
924 142 : current_env%center_list(ispin)%array(2, i) = istate
925 : END IF
926 : END DO
927 76 : IF (.NOT. is0) THEN
928 48 : IF (output_unit > 0) THEN
929 24 : WRITE (output_unit, '(T2,A,I6,A,I6)') 'clustering ', j, ' center(s) on atom ', iatom
930 : END IF
931 : current_env%center_list(ispin)%array(1, ii + 1) = &
932 48 : current_env%center_list(ispin)%array(1, ii) + j
933 : current_env%centers_set(ispin)%array(:, ii) = &
934 192 : pbc(particle_set(iatom)%r, cell)
935 48 : ii = ii + 1
936 : END IF
937 : END DO
938 16 : current_env%nbr_center(ispin) = ii - 1
939 : !
940 16 : DEALLOCATE (buff)
941 : CASE (current_orb_center_box)
942 : !
943 : ! use boxes as -center-
944 10 : nbr_box = nbox(1)*nbox(2)*nbox(3)
945 50 : ALLOCATE (rbuff(3, nbr_box), buff(nstate))
946 3546 : rbuff(:, :) = HUGE(0.0_dp)
947 96 : buff(:) = 0
948 : !
949 10 : ibox = 1
950 54 : DO iz = 1, nbox(3)
951 250 : DO iy = 1, nbox(2)
952 1124 : DO ix = 1, nbox(1)
953 884 : rbuff(1, ibox) = cell%hmat(1, 1)*((REAL(ix, dp) - 0.5_dp)/REAL(nbox(1), dp) - 0.5_dp)
954 884 : rbuff(2, ibox) = cell%hmat(2, 2)*((REAL(iy, dp) - 0.5_dp)/REAL(nbox(2), dp) - 0.5_dp)
955 884 : rbuff(3, ibox) = cell%hmat(3, 3)*((REAL(iz, dp) - 0.5_dp)/REAL(nbox(3), dp) - 0.5_dp)
956 1080 : ibox = ibox + 1
957 : END DO
958 : END DO
959 : END DO
960 : !
961 96 : DO is = 1, nstate
962 86 : istate = state_list(is, ispin)
963 86 : mdist = HUGE(0.0_dp)
964 8406 : DO ibox = 1, nbr_box
965 8310 : rab(:) = pbc(rbuff(:, ibox), center_array(1:3, istate), cell)
966 8310 : dist = SQRT(rab(1)**2 + rab(2)**2 + rab(3)**2)
967 8396 : IF (dist .LT. mdist) THEN
968 650 : buff(is) = ibox
969 650 : mdist = dist
970 : END IF
971 : END DO
972 : END DO
973 : !
974 10 : i = 0
975 10 : ii = 1
976 10 : current_env%center_list(ispin)%array(1, 1) = 1
977 894 : DO ibox = 1, nbr_box
978 884 : j = 0
979 884 : is0 = .TRUE.
980 9194 : DO is = 1, nstate
981 8310 : istate = state_list(is, ispin)
982 9194 : IF (buff(is) .EQ. ibox) THEN
983 86 : j = j + 1
984 86 : i = i + 1
985 86 : is0 = .FALSE.
986 86 : current_env%center_list(ispin)%array(2, i) = istate
987 : END IF
988 : END DO
989 894 : IF (.NOT. is0) THEN
990 54 : IF (output_unit > 0) THEN
991 27 : WRITE (output_unit, '(T2,A,I6,A,I6)') 'clustering ', j, ' center(s) on box ', ibox
992 : END IF
993 : current_env%center_list(ispin)%array(1, ii + 1) = &
994 54 : current_env%center_list(ispin)%array(1, ii) + j
995 216 : current_env%centers_set(ispin)%array(:, ii) = rbuff(:, ibox)
996 : ii = ii + 1
997 : END IF
998 : END DO
999 10 : current_env%nbr_center(ispin) = ii - 1
1000 : !
1001 10 : DEALLOCATE (buff, rbuff)
1002 : CASE DEFAULT
1003 250 : CPABORT("Unknown orbital center, try again...")
1004 : END SELECT
1005 : END DO
1006 : !
1007 : !
1008 : !
1009 : ! block the states for each center
1010 772 : ALLOCATE (current_env%psi0_order(nspins))
1011 424 : DO ispin = 1, nspins
1012 250 : CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff)
1013 250 : NULLIFY (tmp_fm_struct)
1014 : CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nao, &
1015 : ncol_global=nstate_list(ispin), para_env=para_env, &
1016 250 : context=mo_coeff%matrix_struct%context)
1017 250 : CALL cp_fm_create(current_env%psi0_order(ispin), tmp_fm_struct)
1018 250 : CALL cp_fm_struct_release(tmp_fm_struct)
1019 424 : CALL cp_fm_set_all(current_env%psi0_order(ispin), 0.0_dp)
1020 : END DO
1021 : !
1022 : !
1023 424 : DO ispin = 1, nspins
1024 250 : CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff)
1025 250 : jstate = 0
1026 1674 : DO icenter = 1, current_env%nbr_center(ispin)
1027 2848 : DO i = current_env%center_list(ispin)%array(1, icenter), &
1028 1500 : current_env%center_list(ispin)%array(1, icenter + 1) - 1
1029 : !
1030 1598 : istate = current_env%center_list(ispin)%array(2, i)
1031 1598 : jstate = jstate + 1
1032 : !
1033 2848 : IF (current_env%do_selected_states) THEN ! this should be removed. always reorder the states
1034 : ! the blocking works (so far) with all the precond except FULL_ALL
1035 : ! the center_list(ispin)%array(2,i) array is obsolete then
1036 112 : current_env%center_list(ispin)%array(2, i) = jstate
1037 112 : CALL cp_fm_to_fm(mo_coeff, current_env%psi0_order(ispin), 1, istate, jstate)
1038 : ELSE
1039 : ! for the moment we just copy them
1040 1486 : CALL cp_fm_to_fm(mo_coeff, current_env%psi0_order(ispin), 1, istate, istate)
1041 : END IF
1042 : END DO
1043 : END DO
1044 : END DO
1045 : !
1046 : !
1047 : !
1048 : !
1049 174 : IF (current_env%do_qmmm .AND.&
1050 : & (current_env%orb_center .EQ. current_orb_center_wannier .OR. &
1051 : current_env%orb_center .EQ. current_orb_center_atom .OR. &
1052 : current_env%orb_center .EQ. current_orb_center_box)) THEN
1053 4 : IF (output_unit > 0) THEN
1054 2 : WRITE (output_unit, *) 'WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING '
1055 2 : WRITE (output_unit, *) 'orbital center shifted to match the '
1056 2 : WRITE (output_unit, *) 'center of the box (L/2 L/2 L/2) (superdirty...)'
1057 2 : WRITE (output_unit, *) 'WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING '
1058 : END IF
1059 8 : DO ispin = 1, nspins
1060 24 : DO istate = 1, current_env%nbr_center(ispin)
1061 16 : IF (current_env%centers_set(ispin)%array(1, istate) .LE. 0.0_dp) THEN
1062 : current_env%centers_set(ispin)%array(1, istate) = &
1063 0 : current_env%centers_set(ispin)%array(1, istate) + cell%hmat(1, 1)
1064 : END IF
1065 16 : IF (current_env%centers_set(ispin)%array(2, istate) .LE. 0.0_dp) THEN
1066 : current_env%centers_set(ispin)%array(2, istate) = &
1067 0 : current_env%centers_set(ispin)%array(2, istate) + cell%hmat(2, 2)
1068 : END IF
1069 20 : IF (current_env%centers_set(ispin)%array(3, istate) .LE. 0.0_dp) THEN
1070 : current_env%centers_set(ispin)%array(3, istate) = &
1071 0 : current_env%centers_set(ispin)%array(3, istate) + cell%hmat(3, 3)
1072 : END IF
1073 : END DO
1074 : END DO
1075 : ! printing
1076 8 : DO ispin = 1, nspins
1077 178 : IF (output_unit > 0) THEN
1078 2 : WRITE (output_unit, '(/,T2,A,I2)') "WANNIER CENTERS for spin ", ispin
1079 2 : WRITE (output_unit, '(/,T18,A)') "--------------- Shifted Centers --------------- "
1080 10 : DO istate = 1, current_env%nbr_center(ispin)
1081 : WRITE (output_unit, '(T5,A,I6,3F12.6)') &
1082 34 : 'state ', istate, current_env%centers_set(ispin)%array(1:3, istate)
1083 : END DO
1084 : END IF
1085 : END DO
1086 : END IF
1087 : !
1088 : !
1089 : !
1090 : ! reorder the center dependent responses
1091 424 : max_nbr_center = MAXVAL(current_env%nbr_center(1:nspins))
1092 174 : current_env%nao = nao
1093 696 : ALLOCATE (current_env%statetrueindex(3, max_nbr_center, nspins))
1094 5792 : current_env%statetrueindex(:, :, :) = 0
1095 : IF (.TRUE.) THEN
1096 522 : ALLOCATE (state_done(3, max_nbr_center))
1097 424 : DO ispin = 1, nspins
1098 5618 : state_done(:, :) = .FALSE.
1099 250 : current_env%statetrueindex(1, 1, ispin) = 1
1100 250 : center(1) = current_env%centers_set(ispin)%array(1, 1)
1101 250 : center(2) = current_env%centers_set(ispin)%array(2, 1)
1102 250 : center(3) = current_env%centers_set(ispin)%array(3, 1)
1103 250 : state_done(1, 1) = .TRUE.
1104 250 : icount = 1
1105 250 : CALL get_mo_set(mo_set=mos(ispin), nmo=nmo)
1106 : !
1107 1174 : DO idir = 1, 3
1108 750 : ini = 1
1109 750 : IF (idir == 1) ini = 2
1110 4250 : DO istate = ini, current_env%nbr_center(ispin)
1111 3500 : mdist = HUGE(0.0_dp)
1112 : !
1113 26496 : DO istate2 = 1, current_env%nbr_center(ispin)
1114 26496 : IF (.NOT. state_done(idir, istate2)) THEN
1115 12748 : center2(1) = current_env%centers_set(ispin)%array(1, istate2)
1116 12748 : center2(2) = current_env%centers_set(ispin)%array(2, istate2)
1117 12748 : center2(3) = current_env%centers_set(ispin)%array(3, istate2)
1118 : !
1119 12748 : rab = pbc(center, center2, cell)
1120 12748 : CALL set_vecp(idir, j, k)
1121 12748 : dist = SQRT(rab(j)*rab(j) + rab(k)*rab(k))
1122 : !
1123 12748 : IF (dist .LT. mdist) THEN
1124 6818 : mdist = dist
1125 6818 : istate_next = istate2
1126 : END IF
1127 : END IF
1128 : END DO ! istate2
1129 : !
1130 3500 : icount = icount + 1
1131 3500 : state_done(idir, istate_next) = .TRUE.
1132 3500 : current_env%statetrueindex(idir, icount, ispin) = istate_next
1133 3500 : center(1) = current_env%centers_set(ispin)%array(1, istate_next)
1134 3500 : center(2) = current_env%centers_set(ispin)%array(2, istate_next)
1135 4250 : center(3) = current_env%centers_set(ispin)%array(3, istate_next)
1136 : END DO ! istate
1137 1000 : icount = 0
1138 : END DO ! idir
1139 : END DO
1140 174 : DEALLOCATE (state_done)
1141 : ELSE
1142 : DO ispin = 1, nspins
1143 : DO icenter = 1, current_env%nbr_center(ispin)
1144 : current_env%statetrueindex(:, icenter, ispin) = icenter
1145 : END DO
1146 : END DO
1147 : END IF
1148 : !
1149 : !
1150 174 : IF (output_unit > 0) THEN
1151 87 : WRITE (output_unit, "(T2,A,T60,A)") "CURRENT| Gauge used", &
1152 507 : REPEAT(' ', 20 - LEN_TRIM(current_env%gauge_name))//TRIM(current_env%gauge_name)
1153 87 : WRITE (output_unit, "(T2,A,T79,L1)") "CURRENT| Use old gauge code", current_env%use_old_gauge_atom
1154 87 : WRITE (output_unit, "(T2,A,T79,L1)") "CURRENT| Compute chi for PBC calculation", current_env%chi_pbc
1155 87 : IF (current_env%gauge .EQ. current_gauge_atom) THEN
1156 14 : WRITE (output_unit, "(T2,A,T68,E12.6)") "CURRENT| Radius for building the gauge", &
1157 28 : current_env%gauge_atom_radius
1158 : END IF
1159 87 : WRITE (output_unit, "(T2,A,T60,A)") "CURRENT| Orbital center used", &
1160 1348 : REPEAT(' ', 20 - LEN_TRIM(current_env%orb_center_name))//TRIM(current_env%orb_center_name)
1161 87 : IF (current_env%orb_center .EQ. current_orb_center_common) THEN
1162 16 : WRITE (output_unit, "(T2,A,T50,3F10.6)") "CURRENT| Common center", common_center(1:3)
1163 71 : ELSEIF (current_env%orb_center .EQ. current_orb_center_box) THEN
1164 3 : WRITE (output_unit, "(T2,A,T60,3I5)") "CURRENT| Nbr boxes in each direction", nbox(1:3)
1165 : END IF
1166 : !
1167 212 : DO ispin = 1, nspins
1168 125 : CALL get_mo_set(mo_set=mos(ispin), nmo=nmo)
1169 125 : WRITE (output_unit, '(T2,A,I6,A,I6,A,I2)') 'CURRENT| Compute', &
1170 125 : nstate_list(ispin), ' selected response functions out of', &
1171 250 : nmo, ' for spin ', ispin
1172 : !
1173 125 : WRITE (output_unit, '(T2,A,I6,A,I2)') 'CURRENT| There is a total of ', &
1174 462 : current_env%nbr_center(ispin), ' (clustered) center(s) for spin ', ispin
1175 : END DO
1176 : END IF
1177 :
1178 174 : IF (BTEST(cp_print_key_should_output(logger%iter_info, current_section,&
1179 : & "PRINT%RESPONSE_FUNCTION_CUBES"), cp_p_file)) THEN
1180 :
1181 0 : NULLIFY (bounds, list)
1182 0 : ncubes = 0
1183 : CALL section_vals_val_get(current_section,&
1184 : & "PRINT%RESPONSE_FUNCTION_CUBES%CUBES_LU_BOUNDS", &
1185 0 : i_vals=bounds)
1186 0 : ncubes = bounds(2) - bounds(1) + 1
1187 0 : IF (ncubes > 0) THEN
1188 0 : ALLOCATE (current_env%list_cubes(ncubes))
1189 0 : DO ir = 1, ncubes
1190 0 : current_env%list_cubes(ir) = bounds(1) + (ir - 1)
1191 : END DO
1192 : END IF
1193 0 : IF (.NOT. ASSOCIATED(current_env%list_cubes)) THEN
1194 : CALL section_vals_val_get(current_section, "PRINT%RESPONSE_FUNCTION_CUBES%CUBES_LIST", &
1195 0 : n_rep_val=n_rep)
1196 0 : ncubes = 0
1197 0 : DO ir = 1, n_rep
1198 0 : NULLIFY (list)
1199 : CALL section_vals_val_get(current_section, "PRINT%RESPONSE_FUNCTION_CUBES%CUBES_LIST", &
1200 0 : i_rep_val=ir, i_vals=list)
1201 0 : IF (ASSOCIATED(list)) THEN
1202 0 : CALL reallocate(current_env%list_cubes, 1, ncubes + SIZE(list))
1203 0 : DO ini = 1, SIZE(list)
1204 0 : current_env%list_cubes(ini + ncubes) = list(ini)
1205 : END DO
1206 0 : ncubes = ncubes + SIZE(list)
1207 : END IF
1208 : END DO ! ir
1209 : END IF
1210 0 : IF (.NOT. ASSOCIATED(current_env%list_cubes)) THEN
1211 0 : ALLOCATE (current_env%list_cubes(max_states))
1212 0 : DO ir = 1, max_states
1213 0 : current_env%list_cubes(ir) = ir
1214 : END DO
1215 : END IF
1216 : END IF
1217 174 : IF (BTEST(cp_print_key_should_output(logger%iter_info, current_section,&
1218 : & "PRINT%CURRENT_CUBES"), cp_p_file)) THEN
1219 : END IF
1220 :
1221 : ! for the chemical shift we need 6 psi1, i.e. 6 optimization procedures
1222 : ! They become 9 if full nmr is calculated, i.e. with the correction term too
1223 : ! All of them are required at the end of the optimization procedure
1224 : ! if the current density and the induced field have to be calculated
1225 : ! If instead only the shift is needed, only one psi1 should be enough, providing
1226 : ! that after every optimization the corresponding shift contribution is calculated
1227 : ! prepare the psi1
1228 : !
1229 : ! for the rxp we cannot calculate it a priori because it is in facts (r-dk)xp
1230 : ! where dk is the center of the orbital it is applied to. We would need nstate operators
1231 : ! What we can store is (r-dk)xp|psi0k> for each k, which is a full matrix only
1232 : ! Therefore we prepare here the full matrix p_psi0 and rxp_psi0
1233 : ! We also need a temporary sparse matrix where to store the integrals during the calculation
1234 : ALLOCATE (current_env%p_psi0(nspins, 3), current_env%rxp_psi0(nspins, 3), &
1235 6132 : current_env%psi1_p(nspins, 3), current_env%psi1_rxp(nspins, 3))
1236 174 : IF (current_env%full) THEN
1237 1328 : ALLOCATE (current_env%psi1_D(nspins, 3))
1238 : END IF
1239 424 : DO ispin = 1, nspins
1240 250 : mo_coeff => current_env%psi0_order(ispin)
1241 250 : NULLIFY (tmp_fm_struct)
1242 : CALL cp_fm_struct_create(tmp_fm_struct, nrow_global=nao, &
1243 : ncol_global=current_env%nstates(ispin), &
1244 250 : context=mo_coeff%matrix_struct%context)
1245 1000 : DO idir = 1, 3
1246 750 : CALL cp_fm_create(current_env%psi1_p(ispin, idir), tmp_fm_struct)
1247 750 : CALL cp_fm_create(current_env%psi1_rxp(ispin, idir), tmp_fm_struct)
1248 750 : CALL cp_fm_create(current_env%p_psi0(ispin, idir), tmp_fm_struct)
1249 750 : CALL cp_fm_create(current_env%rxp_psi0(ispin, idir), tmp_fm_struct)
1250 1000 : IF (current_env%full) THEN
1251 618 : CALL cp_fm_create(current_env%psi1_D(ispin, idir), tmp_fm_struct)
1252 : END IF
1253 : END DO
1254 424 : CALL cp_fm_struct_release(tmp_fm_struct)
1255 : END DO
1256 : !
1257 : ! If the current density on the grid needs to be stored
1258 174 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
1259 696 : ALLOCATE (current_env%jrho1_set(3))
1260 696 : DO idir = 1, 3
1261 522 : NULLIFY (rho_r, rho_g)
1262 4110 : ALLOCATE (rho_r(nspins), rho_g(nspins))
1263 1272 : DO ispin = 1, nspins
1264 750 : CALL auxbas_pw_pool%create_pw(rho_r(ispin))
1265 750 : CALL pw_zero(rho_r(ispin))
1266 750 : CALL auxbas_pw_pool%create_pw(rho_g(ispin))
1267 1272 : CALL pw_zero(rho_g(ispin))
1268 : END DO
1269 522 : NULLIFY (current_env%jrho1_set(idir)%rho)
1270 522 : ALLOCATE (current_env%jrho1_set(idir)%rho)
1271 522 : CALL qs_rho_create(current_env%jrho1_set(idir)%rho)
1272 : CALL qs_rho_set(current_env%jrho1_set(idir)%rho, &
1273 696 : rho_r=rho_r, rho_g=rho_g)
1274 : END DO
1275 : !
1276 : ! Initialize local current density if GAPW calculation
1277 174 : IF (gapw) THEN
1278 96 : CALL init_jrho_atom_set(jrho1_atom_set, atomic_kind_set, nspins)
1279 96 : CALL set_current_env(current_env=current_env, jrho1_atom_set=jrho1_atom_set)
1280 : END IF
1281 : !
1282 : ALLOCATE (current_env%basisfun_center(3, current_env%nao), &
1283 1044 : first_sgf(natom), last_sgf(natom))
1284 15886 : current_env%basisfun_center = 0.0_dp
1285 : CALL get_particle_set(particle_set, qs_kind_set, &
1286 : first_sgf=first_sgf, &
1287 174 : last_sgf=last_sgf)
1288 : !Build 3 arrays where for each contracted basis function
1289 : !the x y and z coordinates of the center are given
1290 710 : DO iatom = 1, natom
1291 4638 : DO iao = first_sgf(iatom), last_sgf(iatom)
1292 16248 : DO idir = 1, 3
1293 15712 : current_env%basisfun_center(idir, iao) = particle_set(iatom)%r(idir)
1294 : END DO
1295 : END DO
1296 : END DO
1297 :
1298 174 : DEALLOCATE (first_sgf, last_sgf, state_list)
1299 :
1300 1218 : current_env%simple_done(1:6) = .FALSE.
1301 :
1302 696 : ALLOCATE (current_env%full_done(3*nspins, max_nbr_center))
1303 5052 : current_env%full_done = .FALSE.
1304 : !
1305 : ! allocate pointer for the gauge
1306 5900 : ALLOCATE (current_env%rs_gauge(3, pw_env%gridlevel_info%ngrid_levels))
1307 :
1308 174 : CALL cp_print_key_finished_output(output_unit, logger, lr_section, "PRINT%PROGRAM_RUN_INFO")
1309 174 : CALL timestop(handle)
1310 :
1311 870 : END SUBROUTINE current_env_init
1312 :
1313 : ! **************************************************************************************************
1314 : !> \brief ...
1315 : !> \param current_env ...
1316 : ! **************************************************************************************************
1317 348 : SUBROUTINE current_env_cleanup(current_env)
1318 :
1319 : TYPE(current_env_type) :: current_env
1320 :
1321 : INTEGER :: i, idir, ispin
1322 :
1323 348 : CALL cp_fm_release(current_env%psi0_order)
1324 : !
1325 : !psi1_p
1326 348 : CALL cp_fm_release(current_env%psi1_p)
1327 : !
1328 : !psi1_rxp
1329 348 : CALL cp_fm_release(current_env%psi1_rxp)
1330 : !
1331 : !psi1_D
1332 348 : CALL cp_fm_release(current_env%psi1_D)
1333 : !
1334 : !p_psi0
1335 348 : CALL cp_fm_release(current_env%p_psi0)
1336 : !
1337 : !rxp_psi0
1338 348 : CALL cp_fm_release(current_env%rxp_psi0)
1339 : !
1340 348 : IF (ASSOCIATED(current_env%centers_set)) THEN
1341 424 : DO ispin = 1, SIZE(current_env%centers_set, 1)
1342 424 : DEALLOCATE (current_env%centers_set(ispin)%array)
1343 : END DO
1344 174 : DEALLOCATE (current_env%centers_set)
1345 : END IF
1346 :
1347 348 : IF (ASSOCIATED(current_env%center_list)) THEN
1348 424 : DO ispin = 1, SIZE(current_env%center_list, 1)
1349 424 : DEALLOCATE (current_env%center_list(ispin)%array)
1350 : END DO
1351 174 : DEALLOCATE (current_env%center_list)
1352 : END IF
1353 :
1354 348 : IF (ASSOCIATED(current_env%list_cubes)) THEN
1355 0 : DEALLOCATE (current_env%list_cubes)
1356 : END IF
1357 : ! Current density on the grid
1358 348 : IF (ASSOCIATED(current_env%jrho1_set)) THEN
1359 696 : DO idir = 1, 3
1360 522 : CALL qs_rho_clear(current_env%jrho1_set(idir)%rho)
1361 696 : DEALLOCATE (current_env%jrho1_set(idir)%rho)
1362 : END DO
1363 174 : DEALLOCATE (current_env%jrho1_set)
1364 : END IF
1365 : !
1366 : ! Local current density, atom by atom (only gapw)
1367 348 : IF (ASSOCIATED(current_env%jrho1_atom_set)) THEN
1368 96 : CALL deallocate_jrho_atom_set(current_env%jrho1_atom_set)
1369 : END IF
1370 :
1371 : !fullnmr_done
1372 348 : IF (ASSOCIATED(current_env%full_done)) THEN
1373 174 : DEALLOCATE (current_env%full_done)
1374 : END IF
1375 348 : IF (ASSOCIATED(current_env%basisfun_center)) THEN
1376 174 : DEALLOCATE (current_env%basisfun_center)
1377 : END IF
1378 348 : IF (ASSOCIATED(current_env%statetrueindex)) THEN
1379 174 : DEALLOCATE (current_env%statetrueindex)
1380 : END IF
1381 348 : IF (ASSOCIATED(current_env%selected_states_on_atom_list)) THEN
1382 8 : DEALLOCATE (current_env%selected_states_on_atom_list)
1383 : END IF
1384 : ! give back the gauge
1385 348 : IF (ASSOCIATED(current_env%rs_gauge)) THEN
1386 696 : DO idir = 1, 3
1387 2772 : DO i = 1, SIZE(current_env%rs_gauge, 2)
1388 2598 : CALL rs_grid_release(current_env%rs_gauge(idir, i))
1389 : END DO
1390 : END DO
1391 174 : DEALLOCATE (current_env%rs_gauge)
1392 : END IF
1393 :
1394 : ! give back the buf
1395 348 : IF (ASSOCIATED(current_env%rs_buf)) THEN
1396 136 : DO i = 1, SIZE(current_env%rs_buf)
1397 136 : CALL rs_grid_release(current_env%rs_buf(i))
1398 : END DO
1399 28 : DEALLOCATE (current_env%rs_buf)
1400 : END IF
1401 :
1402 348 : END SUBROUTINE current_env_cleanup
1403 :
1404 : END MODULE qs_linres_current_utils
|