(git:97501a3)
Loading...
Searching...
No Matches
mp2_cphf.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Routines to calculate CPHF like update and solve Z-vector equation
10!> for MP2 gradients (only GPW)
11!> \par History
12!> 11.2013 created [Mauro Del Ben]
13! **************************************************************************************************
16 USE admm_types, ONLY: admm_type,&
18 USE cell_types, ONLY: cell_type
21 USE cp_dbcsr_api, ONLY: dbcsr_add,&
36 USE cp_fm_types, ONLY: cp_fm_create,&
48 USE hfx_exx, ONLY: add_exx_to_rhs
50 USE hfx_types, ONLY: alloc_containers,&
64 USE kinds, ONLY: dp
66 USE machine, ONLY: m_flush,&
68 USE mathconstants, ONLY: fourpi
70 USE mp2_types, ONLY: mp2_type,&
73 USE pw_env_types, ONLY: pw_env_get,&
75 USE pw_methods, ONLY: pw_axpy,&
76 pw_copy,&
77 pw_derive,&
79 pw_scale,&
85 USE pw_types, ONLY: pw_c1d_gs_type,&
101 USE qs_integrate_potential, ONLY: integrate_v_core_rspace,&
102 integrate_v_rspace
104 USE qs_ks_types, ONLY: qs_ks_env_type,&
107 USE qs_mo_types, ONLY: get_mo_set,&
115 USE qs_p_env_types, ONLY: p_env_release,&
117 USE qs_rho_types, ONLY: qs_rho_get,&
120 USE virial_types, ONLY: virial_type,&
122
123!$ USE OMP_LIB, ONLY: omp_get_max_threads, omp_get_thread_num, omp_get_num_threads
124
125#include "./base/base_uses.f90"
126
127 IMPLICIT NONE
128
129 PRIVATE
130
131 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'mp2_cphf'
132 LOGICAL, PARAMETER, PRIVATE :: debug_forces = .true.
133
135
136CONTAINS
137
138! **************************************************************************************************
139!> \brief Solve Z-vector equations necessary for the calculation of the MP2
140!> gradients, in order to be consistent here the parameters for the
141!> calculation of the CPHF like updats have to be exactly equal to the
142!> SCF case
143!> \param qs_env ...
144!> \param mp2_env ...
145!> \param para_env ...
146!> \param dft_control ...
147!> \param mo_coeff ...
148!> \param homo ...
149!> \param Eigenval ...
150!> \param unit_nr ...
151!> \author Mauro Del Ben, Vladimir Rybkin
152! **************************************************************************************************
153 SUBROUTINE solve_z_vector_eq(qs_env, mp2_env, para_env, dft_control, &
154 mo_coeff, homo, Eigenval, unit_nr)
155 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
156 TYPE(mp2_type), INTENT(INOUT) :: mp2_env
157 TYPE(mp_para_env_type), INTENT(IN), POINTER :: para_env
158 TYPE(dft_control_type), INTENT(IN), POINTER :: dft_control
159 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff
160 INTEGER, DIMENSION(:), INTENT(IN) :: homo
161 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: eigenval
162 INTEGER, INTENT(IN) :: unit_nr
163
164 CHARACTER(LEN=*), PARAMETER :: routinen = 'solve_z_vector_eq'
165
166 INTEGER :: bin, handle, handle2, i, i_global, i_thread, iib, irep, ispin, j_global, jjb, &
167 my_bin_size, n_rep_hf, n_threads, nao, ncol_local, nmo, nrow_local, nspins, transf_type_in
168 INTEGER, ALLOCATABLE, DIMENSION(:) :: virtual
169 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
170 LOGICAL :: alpha_beta, do_dynamic_load_balancing, &
171 do_exx, do_hfx, restore_p_screen
172 REAL(kind=dp) :: focc
173 TYPE(cp_blacs_env_type), POINTER :: blacs_env
174 TYPE(cp_fm_struct_type), POINTER :: fm_struct_tmp
175 TYPE(cp_fm_type) :: fm_back, fm_g_mu_nu, fm_mo_mo
176 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: l_jb, mo_coeff_o, mo_coeff_v, p_ia, &
177 p_mo, w_mo
178 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_p_mp2, &
179 matrix_p_mp2_admm, matrix_s, p_mu_nu, &
180 rho1_ao, rho_ao, rho_ao_aux_fit
181 TYPE(hfx_container_type), DIMENSION(:), POINTER :: integral_containers
182 TYPE(hfx_container_type), POINTER :: maxval_container
183 TYPE(hfx_type), POINTER :: actual_x_data
184 TYPE(linres_control_type), POINTER :: linres_control
185 TYPE(qs_ks_env_type), POINTER :: ks_env
186 TYPE(qs_p_env_type), POINTER :: p_env
187 TYPE(qs_rho_type), POINTER :: rho, rho_aux_fit
188 TYPE(section_vals_type), POINTER :: hfx_section, hfx_sections, input
189
190 CALL timeset(routinen, handle)
191
192 ! start collecting stuff
193 CALL cp_fm_get_info(mo_coeff(1), nrow_global=nao, ncol_global=nmo)
194 cpassert(SIZE(eigenval, 1) == nmo)
195 cpassert(nao >= nmo)
196 NULLIFY (input, matrix_s, blacs_env, rho, &
197 matrix_p_mp2, matrix_p_mp2_admm, matrix_ks)
198 CALL get_qs_env(qs_env, &
199 ks_env=ks_env, &
200 input=input, &
201 matrix_s=matrix_s, &
202 matrix_ks=matrix_ks, &
203 matrix_p_mp2=matrix_p_mp2, &
204 matrix_p_mp2_admm=matrix_p_mp2_admm, &
205 blacs_env=blacs_env, &
206 rho=rho)
207
208 CALL qs_rho_get(rho, rho_ao=rho_ao)
209
210 ! Get number of relevant spin states
211 nspins = dft_control%nspins
212 alpha_beta = (nspins == 2)
213
214 CALL move_alloc(mp2_env%ri_grad%P_mo, p_mo)
215 CALL move_alloc(mp2_env%ri_grad%W_mo, w_mo)
216 CALL move_alloc(mp2_env%ri_grad%L_jb, l_jb)
217
218 ALLOCATE (virtual(nspins))
219 virtual(:) = nmo - homo(:)
220
221 NULLIFY (p_mu_nu)
222 CALL dbcsr_allocate_matrix_set(p_mu_nu, nspins)
223 DO ispin = 1, nspins
224 ALLOCATE (p_mu_nu(ispin)%matrix)
225 CALL dbcsr_copy(p_mu_nu(ispin)%matrix, rho_ao(1)%matrix, name="P_mu_nu")
226 CALL dbcsr_set(p_mu_nu(ispin)%matrix, 0.0_dp)
227 END DO
228
229 NULLIFY (fm_struct_tmp)
230 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=blacs_env, &
231 nrow_global=nao, ncol_global=nao)
232 CALL cp_fm_create(fm_g_mu_nu, fm_struct_tmp, name="G_mu_nu")
233 CALL cp_fm_create(fm_back, fm_struct_tmp, name="fm_back")
234 CALL cp_fm_struct_release(fm_struct_tmp)
235 CALL cp_fm_set_all(fm_g_mu_nu, 0.0_dp)
236 CALL cp_fm_set_all(fm_back, 0.0_dp)
237
238 ALLOCATE (mo_coeff_o(nspins), mo_coeff_v(nspins))
239 DO ispin = 1, nspins
240 NULLIFY (fm_struct_tmp)
241 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=blacs_env, &
242 nrow_global=nao, ncol_global=homo(ispin))
243 CALL cp_fm_create(mo_coeff_o(ispin), fm_struct_tmp, name="mo_coeff_o")
244 CALL cp_fm_struct_release(fm_struct_tmp)
245 CALL cp_fm_set_all(mo_coeff_o(ispin), 0.0_dp)
246 CALL cp_fm_to_fm_submat(msource=mo_coeff(ispin), mtarget=mo_coeff_o(ispin), &
247 nrow=nao, ncol=homo(ispin), &
248 s_firstrow=1, s_firstcol=1, &
249 t_firstrow=1, t_firstcol=1)
250
251 NULLIFY (fm_struct_tmp)
252 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=blacs_env, &
253 nrow_global=nao, ncol_global=virtual(ispin))
254 CALL cp_fm_create(mo_coeff_v(ispin), fm_struct_tmp, name="mo_coeff_v")
255 CALL cp_fm_struct_release(fm_struct_tmp)
256 CALL cp_fm_set_all(mo_coeff_v(ispin), 0.0_dp)
257 CALL cp_fm_to_fm_submat(msource=mo_coeff(ispin), mtarget=mo_coeff_v(ispin), &
258 nrow=nao, ncol=virtual(ispin), &
259 s_firstrow=1, s_firstcol=homo(ispin) + 1, &
260 t_firstrow=1, t_firstcol=1)
261 END DO
262
263 ! hfx section
264 NULLIFY (hfx_sections)
265 hfx_sections => section_vals_get_subs_vals(input, "DFT%XC%HF")
266 CALL section_vals_get(hfx_sections, explicit=do_hfx, n_repetition=n_rep_hf)
267 IF (do_hfx) THEN
268 ! here we check if we have to reallocate the HFX container
269 IF (mp2_env%ri_grad%free_hfx_buffer .AND. (.NOT. qs_env%x_data(1, 1)%do_hfx_ri)) THEN
270 CALL timeset(routinen//"_alloc_hfx", handle2)
271 n_threads = 1
272!$ n_threads = omp_get_max_threads()
273
274 DO irep = 1, n_rep_hf
275 DO i_thread = 0, n_threads - 1
276 actual_x_data => qs_env%x_data(irep, i_thread + 1)
277
278 do_dynamic_load_balancing = .true.
279 IF (n_threads == 1 .OR. actual_x_data%memory_parameter%do_disk_storage) do_dynamic_load_balancing = .false.
280
281 IF (do_dynamic_load_balancing) THEN
282 my_bin_size = SIZE(actual_x_data%distribution_energy)
283 ELSE
284 my_bin_size = 1
285 END IF
286
287 IF (.NOT. actual_x_data%memory_parameter%do_all_on_the_fly) THEN
288 CALL alloc_containers(actual_x_data%store_ints, my_bin_size)
289
290 DO bin = 1, my_bin_size
291 maxval_container => actual_x_data%store_ints%maxval_container(bin)
292 integral_containers => actual_x_data%store_ints%integral_containers(:, bin)
293 CALL hfx_init_container(maxval_container, actual_x_data%memory_parameter%actual_memory_usage, .false.)
294 DO i = 1, 64
295 CALL hfx_init_container(integral_containers(i), &
296 actual_x_data%memory_parameter%actual_memory_usage, .false.)
297 END DO
298 END DO
299 END IF
300 END DO
301 END DO
302 CALL timestop(handle2)
303 END IF
304
305 ! set up parameters for P_screening
306 restore_p_screen = qs_env%x_data(1, 1)%screening_parameter%do_initial_p_screening
307 IF (qs_env%x_data(1, 1)%screening_parameter%do_initial_p_screening) THEN
308 IF (mp2_env%ri_grad%free_hfx_buffer) THEN
309 mp2_env%p_screen = .false.
310 ELSE
311 mp2_env%p_screen = .true.
312 END IF
313 END IF
314 END IF
315
316 ! Add exx part for RPA
317 do_exx = .false.
318 IF (qs_env%mp2_env%method == ri_rpa_method_gpw) THEN
319 hfx_section => section_vals_get_subs_vals(qs_env%input, "DFT%XC%WF_CORRELATION%RI_RPA%HF")
320 CALL section_vals_get(hfx_section, explicit=do_exx)
321 END IF
322 IF (do_exx) THEN
323 CALL add_exx_to_rhs(rhs=p_mu_nu, &
324 qs_env=qs_env, &
325 ext_hfx_section=hfx_section, &
326 x_data=mp2_env%ri_rpa%x_data, &
327 recalc_integrals=.false., &
328 do_admm=mp2_env%ri_rpa%do_admm, &
329 do_exx=do_exx, &
330 reuse_hfx=mp2_env%ri_rpa%reuse_hfx)
331
332 focc = 1.0_dp
333 IF (nspins == 1) focc = 2.0_dp
334 !focc = 0.0_dp
335 DO ispin = 1, nspins
336 CALL dbcsr_add(p_mu_nu(ispin)%matrix, matrix_ks(ispin)%matrix, 1.0_dp, -1.0_dp)
337 CALL copy_dbcsr_to_fm(matrix=p_mu_nu(ispin)%matrix, fm=fm_g_mu_nu)
338 CALL parallel_gemm("N", "N", nao, homo(ispin), nao, 1.0_dp, &
339 fm_g_mu_nu, mo_coeff_o(ispin), 0.0_dp, fm_back)
340 CALL parallel_gemm("T", "N", homo(ispin), virtual(ispin), nao, focc, &
341 fm_back, mo_coeff_v(ispin), 1.0_dp, l_jb(ispin))
342 CALL parallel_gemm("T", "N", homo(ispin), homo(ispin), nao, -focc, &
343 fm_back, mo_coeff_o(ispin), 1.0_dp, w_mo(ispin))
344 END DO
345 END IF
346
347 ! Prepare arrays for linres code
348 NULLIFY (linres_control)
349 ALLOCATE (linres_control)
350 linres_control%do_kernel = .true.
351 linres_control%lr_triplet = .false.
352 linres_control%linres_restart = .false.
353 linres_control%max_iter = mp2_env%ri_grad%cphf_max_num_iter
354 linres_control%eps = mp2_env%ri_grad%cphf_eps_conv
355 linres_control%eps_filter = mp2_env%mp2_gpw%eps_filter
356 linres_control%restart_every = 50
357 linres_control%preconditioner_type = ot_precond_full_all
358 linres_control%energy_gap = 0.02_dp
359
360 NULLIFY (p_env)
361 ALLOCATE (p_env)
362 CALL p_env_create(p_env, qs_env, p1_option=p_mu_nu, orthogonal_orbitals=.true., linres_control=linres_control)
363 CALL set_qs_env(qs_env, linres_control=linres_control)
364 CALL p_env_psi0_changed(p_env, qs_env)
365 p_env%new_preconditioner = .true.
366 CALL p_env_check_i_alloc(p_env, qs_env)
367 mp2_env%ri_grad%p_env => p_env
368
369 ! update Lagrangian with the CPHF like update, occ-occ block, first call (recompute hfx integrals if needed)
370 transf_type_in = 1
371 ! In alpha-beta case, L_bj_alpha has Coulomb and XC alpha-alpha part
372 ! and (only) Coulomb alpha-beta part and vice versa.
373
374 ! Complete in closed shell case, alpha-alpha (Coulomb and XC)
375 ! part of L_bj(alpha) for open shell
376
377 CALL cphf_like_update(qs_env, mo_coeff_o, mo_coeff_v, eigenval, p_env, &
378 p_mo, fm_g_mu_nu, fm_back, transf_type_in, l_jb, &
379 recalc_hfx_integrals=(.NOT. do_exx .AND. mp2_env%ri_grad%free_hfx_buffer) &
380 .OR. (do_exx .AND. .NOT. mp2_env%ri_rpa%reuse_hfx))
381
382 ! at this point Lagrangian is completed ready to solve the Z-vector equations
383 ! P_ia will contain the solution of these equations
384 ALLOCATE (p_ia(nspins))
385 DO ispin = 1, nspins
386 NULLIFY (fm_struct_tmp)
387 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=blacs_env, &
388 nrow_global=homo(ispin), ncol_global=virtual(ispin))
389 CALL cp_fm_create(p_ia(ispin), fm_struct_tmp, name="P_ia")
390 CALL cp_fm_struct_release(fm_struct_tmp)
391 CALL cp_fm_set_all(p_ia(ispin), 0.0_dp)
392 END DO
393
394 CALL solve_z_vector_eq_low(qs_env, mp2_env, unit_nr, &
395 mo_coeff_o, mo_coeff_v, eigenval, p_env, &
396 l_jb, fm_g_mu_nu, fm_back, p_ia)
397
398 ! release fm stuff
399 CALL cp_fm_release(fm_g_mu_nu)
400 CALL cp_fm_release(l_jb)
401 CALL cp_fm_release(mo_coeff_o)
402 CALL cp_fm_release(mo_coeff_v)
403
404 CALL cp_fm_create(fm_mo_mo, p_mo(1)%matrix_struct)
405
406 DO ispin = 1, nspins
407 ! update the MP2-MO density matrix with the occ-virt block
408 CALL cp_fm_to_fm_submat(msource=p_ia(ispin), mtarget=p_mo(ispin), &
409 nrow=homo(ispin), ncol=virtual(ispin), &
410 s_firstrow=1, s_firstcol=1, &
411 t_firstrow=1, t_firstcol=homo(ispin) + 1)
412 ! transpose P_MO matrix (easy way to symmetrize)
413 CALL cp_fm_set_all(fm_mo_mo, 0.0_dp)
414 ! P_mo now is ready
415 CALL cp_fm_uplo_to_full(matrix=p_mo(ispin), work=fm_mo_mo)
416 END DO
417 CALL cp_fm_release(p_ia)
418 CALL cp_fm_release(fm_mo_mo)
419
420 ! do the final update to the energy weighted matrix W_MO
421 DO ispin = 1, nspins
422 CALL cp_fm_get_info(matrix=w_mo(ispin), &
423 nrow_local=nrow_local, &
424 ncol_local=ncol_local, &
425 row_indices=row_indices, &
426 col_indices=col_indices)
427 DO jjb = 1, ncol_local
428 j_global = col_indices(jjb)
429 IF (j_global <= homo(ispin)) THEN
430 DO iib = 1, nrow_local
431 i_global = row_indices(iib)
432 w_mo(ispin)%local_data(iib, jjb) = w_mo(ispin)%local_data(iib, jjb) &
433 - p_mo(ispin)%local_data(iib, jjb)*eigenval(j_global, ispin)
434 IF (i_global == j_global .AND. nspins == 1) w_mo(ispin)%local_data(iib, jjb) = &
435 w_mo(ispin)%local_data(iib, jjb) - 2.0_dp*eigenval(j_global, ispin)
436 IF (i_global == j_global .AND. nspins == 2) w_mo(ispin)%local_data(iib, jjb) = &
437 w_mo(ispin)%local_data(iib, jjb) - eigenval(j_global, ispin)
438 END DO
439 ELSE
440 DO iib = 1, nrow_local
441 i_global = row_indices(iib)
442 IF (i_global <= homo(ispin)) THEN
443 ! virt-occ
444 w_mo(ispin)%local_data(iib, jjb) = w_mo(ispin)%local_data(iib, jjb) &
445 - p_mo(ispin)%local_data(iib, jjb)*eigenval(i_global, ispin)
446 ELSE
447 ! virt-virt
448 w_mo(ispin)%local_data(iib, jjb) = w_mo(ispin)%local_data(iib, jjb) &
449 - p_mo(ispin)%local_data(iib, jjb)*eigenval(j_global, ispin)
450 END IF
451 END DO
452 END IF
453 END DO
454 END DO
455
456 ! create the MP2 energy weighted density matrix
457 NULLIFY (p_env%w1)
458 CALL dbcsr_allocate_matrix_set(p_env%w1, 1)
459 ALLOCATE (p_env%w1(1)%matrix)
460 CALL dbcsr_copy(p_env%w1(1)%matrix, matrix_s(1)%matrix, &
461 name="W MATRIX MP2")
462 CALL dbcsr_set(p_env%w1(1)%matrix, 0.0_dp)
463
464 ! backtnsform the collected parts of the energy-weighted density matrix into AO basis
465 DO ispin = 1, nspins
466 CALL parallel_gemm('N', 'N', nao, nmo, nmo, 1.0_dp, &
467 mo_coeff(ispin), w_mo(ispin), 0.0_dp, fm_back)
468 CALL cp_dbcsr_plus_fm_fm_t(p_env%w1(1)%matrix, fm_back, mo_coeff(ispin), nmo, 1.0_dp, .true., 1)
469 END DO
470 CALL cp_fm_release(w_mo)
471
472 CALL qs_rho_get(p_env%rho1, rho_ao=rho1_ao)
473
474 DO ispin = 1, nspins
475 CALL dbcsr_set(p_env%p1(ispin)%matrix, 0.0_dp)
476
477 CALL parallel_gemm('N', 'N', nao, nmo, nmo, 1.0_dp, &
478 mo_coeff(ispin), p_mo(ispin), 0.0_dp, fm_back)
479 CALL cp_dbcsr_plus_fm_fm_t(p_env%p1(ispin)%matrix, fm_back, mo_coeff(ispin), nmo, 1.0_dp, .true.)
480
481 CALL dbcsr_copy(rho1_ao(ispin)%matrix, p_env%p1(ispin)%matrix)
482 END DO
483 CALL cp_fm_release(p_mo)
484 CALL cp_fm_release(fm_back)
485
486 CALL p_env_update_rho(p_env, qs_env)
487
488 ! create mp2 DBCSR density
489 CALL dbcsr_allocate_matrix_set(matrix_p_mp2, nspins)
490 DO ispin = 1, nspins
491 ALLOCATE (matrix_p_mp2(ispin)%matrix)
492 CALL dbcsr_copy(matrix_p_mp2(ispin)%matrix, p_env%p1(ispin)%matrix, &
493 name="P MATRIX MP2")
494 END DO
495
496 IF (dft_control%do_admm) THEN
497 CALL get_admm_env(qs_env%admm_env, rho_aux_fit=rho_aux_fit)
498 CALL qs_rho_get(rho_aux_fit, rho_ao=rho_ao_aux_fit)
499
500 ! create mp2 DBCSR density in auxiliary basis
501 CALL dbcsr_allocate_matrix_set(matrix_p_mp2_admm, nspins)
502 DO ispin = 1, nspins
503 ALLOCATE (matrix_p_mp2_admm(ispin)%matrix)
504 CALL dbcsr_copy(matrix_p_mp2_admm(ispin)%matrix, p_env%p1_admm(ispin)%matrix, &
505 name="P MATRIX MP2 ADMM")
506 END DO
507 END IF
508
509 CALL set_ks_env(ks_env, matrix_p_mp2=matrix_p_mp2, matrix_p_mp2_admm=matrix_p_mp2_admm)
510
511 ! We will need one more hfx calculation for HF gradient part
512 mp2_env%not_last_hfx = .false.
513 mp2_env%p_screen = restore_p_screen
514
515 CALL timestop(handle)
516
517 END SUBROUTINE solve_z_vector_eq
518
519! **************************************************************************************************
520!> \brief Here we performe the CPHF like update using GPW,
521!> transf_type_in defines the type of transformation for the matrix in input
522!> transf_type_in = 1 -> occ-occ back transformation
523!> transf_type_in = 2 -> virt-virt back transformation
524!> transf_type_in = 3 -> occ-virt back transformation including the
525!> eigenvalues energy differences for the diagonal elements
526!> \param qs_env ...
527!> \param mo_coeff_o ...
528!> \param mo_coeff_v ...
529!> \param Eigenval ...
530!> \param p_env ...
531!> \param fm_mo ...
532!> \param fm_ao ...
533!> \param fm_back ...
534!> \param transf_type_in ...
535!> \param fm_mo_out ...
536!> \param recalc_hfx_integrals ...
537!> \author Mauro Del Ben, Vladimir Rybkin
538! **************************************************************************************************
539 SUBROUTINE cphf_like_update(qs_env, mo_coeff_o, mo_coeff_v, Eigenval, p_env, &
540 fm_mo, fm_ao, fm_back, transf_type_in, &
541 fm_mo_out, recalc_hfx_integrals)
542 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
543 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff_o, mo_coeff_v
544 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: eigenval
545 TYPE(qs_p_env_type) :: p_env
546 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fm_mo
547 TYPE(cp_fm_type), INTENT(INOUT) :: fm_ao
548 TYPE(cp_fm_type), INTENT(IN) :: fm_back
549 INTEGER, INTENT(IN) :: transf_type_in
550 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fm_mo_out
551 LOGICAL, INTENT(IN), OPTIONAL :: recalc_hfx_integrals
552
553 CHARACTER(LEN=*), PARAMETER :: routinen = 'cphf_like_update'
554
555 INTEGER :: handle, homo, i_global, iib, ispin, &
556 j_global, jjb, nao, ncol_local, &
557 nrow_local, nspins, virtual
558 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
559 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rho1_ao
560
561 CALL timeset(routinen, handle)
562
563 nspins = SIZE(eigenval, 2)
564
565 CALL qs_rho_get(p_env%rho1, rho_ao=rho1_ao)
566
567 ! Determine the first-order density matrices in AO basis
568 DO ispin = 1, nspins
569 CALL dbcsr_set(p_env%p1(ispin)%matrix, 0.0_dp)
570
571 CALL cp_fm_get_info(mo_coeff_o(ispin), nrow_global=nao, ncol_global=homo)
572 CALL cp_fm_get_info(mo_coeff_v(ispin), nrow_global=nao, ncol_global=virtual)
573
574 associate(mat_in => fm_mo(ispin))
575
576 ! perform back transformation
577 SELECT CASE (transf_type_in)
578 CASE (1)
579 ! occ-occ block
580 CALL parallel_gemm('N', 'N', nao, homo, homo, 1.0_dp, &
581 mo_coeff_o(ispin), mat_in, 0.0_dp, fm_back)
582 CALL cp_dbcsr_plus_fm_fm_t(p_env%p1(ispin)%matrix, fm_back, mo_coeff_o(ispin), homo, 1.0_dp, .true.)
583 ! virt-virt block
584 CALL parallel_gemm('N', 'N', nao, virtual, virtual, 1.0_dp, &
585 mo_coeff_v(ispin), mat_in, 0.0_dp, fm_back, &
586 b_first_col=homo + 1, &
587 b_first_row=homo + 1)
588 CALL cp_dbcsr_plus_fm_fm_t(p_env%p1(ispin)%matrix, fm_back, mo_coeff_v(ispin), virtual, 1.0_dp, .true.)
589
590 CASE (3)
591 ! virt-occ blocks
592 CALL parallel_gemm('N', 'N', nao, virtual, homo, 1.0_dp, &
593 mo_coeff_o(ispin), mat_in, 0.0_dp, fm_back)
594 CALL cp_dbcsr_plus_fm_fm_t(p_env%p1(ispin)%matrix, fm_back, mo_coeff_v(ispin), virtual, 1.0_dp, .true.)
595 ! and symmetrize (here again multiply instead of transposing)
596 CALL parallel_gemm('N', 'T', nao, homo, virtual, 1.0_dp, &
597 mo_coeff_v(ispin), mat_in, 0.0_dp, fm_back)
598 CALL cp_dbcsr_plus_fm_fm_t(p_env%p1(ispin)%matrix, fm_back, mo_coeff_o(ispin), homo, 1.0_dp, .true.)
599
600 CASE DEFAULT
601 ! nothing
602 END SELECT
603 END associate
604
605 CALL dbcsr_copy(rho1_ao(ispin)%matrix, p_env%p1(ispin)%matrix)
606 END DO
607
608 CALL p_env_update_rho(p_env, qs_env)
609
610 CALL apply_2nd_order_kernel(qs_env, p_env, recalc_hfx_integrals)
611
612 DO ispin = 1, nspins
613 CALL cp_fm_get_info(mo_coeff_o(ispin), nrow_global=nao, ncol_global=homo)
614 CALL cp_fm_get_info(mo_coeff_v(ispin), nrow_global=nao, ncol_global=virtual)
615
616 IF (transf_type_in == 3) THEN
617
618 ! scale for the orbital energy differences for the diagonal elements
619 CALL cp_fm_get_info(matrix=fm_mo_out(ispin), &
620 nrow_local=nrow_local, &
621 ncol_local=ncol_local, &
622 row_indices=row_indices, &
623 col_indices=col_indices)
624 DO jjb = 1, ncol_local
625 j_global = col_indices(jjb)
626 DO iib = 1, nrow_local
627 i_global = row_indices(iib)
628 fm_mo_out(ispin)%local_data(iib, jjb) = fm_mo(ispin)%local_data(iib, jjb)* &
629 (eigenval(j_global + homo, ispin) - eigenval(i_global, ispin))
630 END DO
631 END DO
632 END IF
633
634 ! copy back to fm
635 CALL cp_fm_set_all(fm_ao, 0.0_dp)
636 CALL copy_dbcsr_to_fm(matrix=p_env%kpp1(ispin)%matrix, fm=fm_ao)
637 CALL cp_fm_set_all(fm_back, 0.0_dp)
638 CALL cp_fm_uplo_to_full(fm_ao, fm_back)
639
640 associate(mat_out => fm_mo_out(ispin))
641
642 ! transform to MO basis, here we always sum the result into the input matrix
643
644 ! occ-virt block
645 CALL parallel_gemm('T', 'N', homo, nao, nao, 1.0_dp, &
646 mo_coeff_o(ispin), fm_ao, 0.0_dp, fm_back)
647 CALL parallel_gemm('N', 'N', homo, virtual, nao, 1.0_dp, &
648 fm_back, mo_coeff_v(ispin), 1.0_dp, mat_out)
649 END associate
650 END DO
651
652 CALL timestop(handle)
653
654 END SUBROUTINE cphf_like_update
655
656! **************************************************************************************************
657!> \brief Low level subroutine for the iterative solution of a large
658!> system of linear equation
659!> \param qs_env ...
660!> \param mp2_env ...
661!> \param unit_nr ...
662!> \param mo_coeff_o ...
663!> \param mo_coeff_v ...
664!> \param Eigenval ...
665!> \param p_env ...
666!> \param L_jb ...
667!> \param fm_G_mu_nu ...
668!> \param fm_back ...
669!> \param P_ia ...
670!> \author Mauro Del Ben, Vladimir Rybkin
671! **************************************************************************************************
672 SUBROUTINE solve_z_vector_eq_low(qs_env, mp2_env, unit_nr, &
673 mo_coeff_o, mo_coeff_v, Eigenval, p_env, &
674 L_jb, fm_G_mu_nu, fm_back, P_ia)
675 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
676 TYPE(mp2_type), INTENT(IN) :: mp2_env
677 INTEGER, INTENT(IN) :: unit_nr
678 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff_o, mo_coeff_v
679 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: eigenval
680 TYPE(qs_p_env_type), INTENT(IN), POINTER :: p_env
681 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: l_jb
682 TYPE(cp_fm_type), INTENT(INOUT) :: fm_g_mu_nu
683 TYPE(cp_fm_type), INTENT(IN) :: fm_back
684 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: p_ia
685
686 CHARACTER(LEN=*), PARAMETER :: routinen = 'solve_z_vector_eq_low'
687
688 INTEGER :: handle, i_global, iib, ispin, j_global, &
689 jjb, ncol_local, nmo, nrow_local, &
690 nspins, virtual
691 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
692 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: precond
693
694 CALL timeset(routinen, handle)
695
696 nmo = SIZE(eigenval, 1)
697 nspins = SIZE(eigenval, 2)
698
699 ! Pople method
700 ! change sign to L_jb
701 DO ispin = 1, nspins
702 l_jb(ispin)%local_data(:, :) = -l_jb(ispin)%local_data(:, :)
703 END DO
704
705 ! create fm structure
706 ALLOCATE (precond(nspins))
707 DO ispin = 1, nspins
708 ! create preconditioner (for now only orbital energy differences)
709 CALL cp_fm_create(precond(ispin), p_ia(ispin)%matrix_struct, name="precond")
710 CALL cp_fm_set_all(precond(ispin), 1.0_dp)
711 CALL cp_fm_get_info(matrix=precond(ispin), &
712 nrow_local=nrow_local, &
713 ncol_local=ncol_local, &
714 row_indices=row_indices, &
715 col_indices=col_indices, &
716 ncol_global=virtual)
717 DO jjb = 1, ncol_local
718 j_global = col_indices(jjb)
719 DO iib = 1, nrow_local
720 i_global = row_indices(iib)
721 precond(ispin)%local_data(iib, jjb) = 1.0_dp/(eigenval(j_global + nmo - virtual, ispin) - eigenval(i_global, ispin))
722 END DO
723 END DO
724 END DO
725
726 SELECT CASE (mp2_env%ri_grad%z_solver_method)
727 CASE (z_solver_pople)
728 CALL solve_z_vector_pople(qs_env, mp2_env, unit_nr, &
729 mo_coeff_o, mo_coeff_v, eigenval, p_env, &
730 l_jb, fm_g_mu_nu, fm_back, p_ia, precond)
731 CASE (z_solver_cg, z_solver_richardson, z_solver_sd)
732 CALL solve_z_vector_cg(qs_env, mp2_env, unit_nr, &
733 mo_coeff_o, mo_coeff_v, eigenval, p_env, &
734 l_jb, fm_g_mu_nu, fm_back, p_ia, precond)
735 CASE DEFAULT
736 cpabort("Unknown solver")
737 END SELECT
738
739 CALL cp_fm_release(precond)
740
741 CALL timestop(handle)
742
743 END SUBROUTINE solve_z_vector_eq_low
744
745! **************************************************************************************************
746!> \brief ...
747!> \param qs_env ...
748!> \param mp2_env ...
749!> \param unit_nr ...
750!> \param mo_coeff_o ...
751!> \param mo_coeff_v ...
752!> \param Eigenval ...
753!> \param p_env ...
754!> \param L_jb ...
755!> \param fm_G_mu_nu ...
756!> \param fm_back ...
757!> \param P_ia ...
758!> \param precond ...
759! **************************************************************************************************
760 SUBROUTINE solve_z_vector_pople(qs_env, mp2_env, unit_nr, &
761 mo_coeff_o, mo_coeff_v, Eigenval, p_env, &
762 L_jb, fm_G_mu_nu, fm_back, P_ia, precond)
763 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
764 TYPE(mp2_type), INTENT(IN) :: mp2_env
765 INTEGER, INTENT(IN) :: unit_nr
766 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff_o, mo_coeff_v
767 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: eigenval
768 TYPE(qs_p_env_type), INTENT(IN), POINTER :: p_env
769 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: l_jb
770 TYPE(cp_fm_type), INTENT(INOUT) :: fm_g_mu_nu
771 TYPE(cp_fm_type), INTENT(IN) :: fm_back
772 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: p_ia, precond
773
774 CHARACTER(LEN=*), PARAMETER :: routinen = 'solve_z_vector_pople'
775
776 INTEGER :: cycle_counter, handle, iib, iiter, &
777 ispin, max_num_iter, nspins, &
778 transf_type_in
779 LOGICAL :: converged
780 REAL(kind=dp) :: conv, eps_conv, scale_cphf, t1, t2
781 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: proj_bi_xj, temp_vals, x_norm, xi_b
782 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: a_small, b_small, xi_axi
783 TYPE(cp_fm_struct_p_type), ALLOCATABLE, &
784 DIMENSION(:) :: fm_struct_tmp
785 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: b_i, residual
786 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: ax, xn
787
788 CALL timeset(routinen, handle)
789
790 nspins = SIZE(eigenval, 2)
791
792 eps_conv = mp2_env%ri_grad%cphf_eps_conv
793
794 IF (accurate_dot_product_spin(l_jb, l_jb) >= (eps_conv*eps_conv)) THEN
795
796 max_num_iter = mp2_env%ri_grad%cphf_max_num_iter
797 scale_cphf = mp2_env%ri_grad%scale_step_size
798
799 ! set the transformation type (equal for all methods all updates)
800 transf_type_in = 3
801
802 ! set convergence flag
803 converged = .false.
804
805 ALLOCATE (fm_struct_tmp(nspins), b_i(nspins), residual(nspins))
806 DO ispin = 1, nspins
807 fm_struct_tmp(ispin)%struct => p_ia(ispin)%matrix_struct
808
809 CALL cp_fm_create(b_i(ispin), fm_struct_tmp(ispin)%struct, name="b_i")
810 CALL cp_fm_set_all(b_i(ispin), 0.0_dp)
811 b_i(ispin)%local_data(:, :) = precond(ispin)%local_data(:, :)*l_jb(ispin)%local_data(:, :)
812
813 ! create the residual vector (r), we check convergence on the norm of
814 ! this vector r=(Ax-b)
815 CALL cp_fm_create(residual(ispin), fm_struct_tmp(ispin)%struct, name="residual")
816 CALL cp_fm_set_all(residual(ispin), 0.0_dp)
817 END DO
818
819 IF (unit_nr > 0) THEN
820 WRITE (unit_nr, *)
821 WRITE (unit_nr, '(T3,A)') "MP2_CPHF| Iterative solution of Z-Vector equations (Pople's method)"
822 WRITE (unit_nr, '(T3,A,T45,ES8.1)') 'MP2_CPHF| Convergence threshold:', eps_conv
823 WRITE (unit_nr, '(T3,A,T45,I8)') 'MP2_CPHF| Maximum number of iterations: ', max_num_iter
824 WRITE (unit_nr, '(T3,A,T45,ES8.1)') 'MP2_CPHF| Scaling of initial guess: ', scale_cphf
825 WRITE (unit_nr, '(T4,A)') repeat("-", 40)
826 WRITE (unit_nr, '(T4,A,T15,A,T33,A)') 'Step', 'Time', 'Convergence'
827 WRITE (unit_nr, '(T4,A)') repeat("-", 40)
828 END IF
829
830 ALLOCATE (xn(nspins, max_num_iter))
831 ALLOCATE (ax(nspins, max_num_iter))
832 ALLOCATE (x_norm(max_num_iter))
833 ALLOCATE (xi_b(max_num_iter))
834 ALLOCATE (xi_axi(max_num_iter, 0:max_num_iter))
835 x_norm = 0.0_dp
836 xi_b = 0.0_dp
837 xi_axi = 0.0_dp
838
839 cycle_counter = 0
840 DO iiter = 1, max_num_iter
841 cycle_counter = cycle_counter + 1
842
843 t1 = m_walltime()
844
845 ! create and update x_i (orthogonalization with previous vectors)
846 DO ispin = 1, nspins
847 CALL cp_fm_create(xn(ispin, iiter), fm_struct_tmp(ispin)%struct, name="xi")
848 CALL cp_fm_set_all(xn(ispin, iiter), 0.0_dp)
849 END DO
850
851 ALLOCATE (proj_bi_xj(iiter - 1))
852 proj_bi_xj = 0.0_dp
853 ! first compute the projection of the actual b_i into all previous x_i
854 ! already scaled with the norm of each x_i
855 DO iib = 1, iiter - 1
856 proj_bi_xj(iib) = proj_bi_xj(iib) + accurate_dot_product_spin(b_i, xn(:, iib))/x_norm(iib)
857 END DO
858
859 ! update actual x_i
860 DO ispin = 1, nspins
861 xn(ispin, iiter)%local_data(:, :) = scale_cphf*b_i(ispin)%local_data(:, :)
862 DO iib = 1, iiter - 1
863 xn(ispin, iiter)%local_data(:, :) = xn(ispin, iiter)%local_data(:, :) - &
864 xn(ispin, iib)%local_data(:, :)*proj_bi_xj(iib)
865 END DO
866 END DO
867 DEALLOCATE (proj_bi_xj)
868
869 ! create Ax(iiter) that will store the matrix vector product for this cycle
870 DO ispin = 1, nspins
871 CALL cp_fm_create(ax(ispin, iiter), fm_struct_tmp(ispin)%struct, name="Ai")
872 CALL cp_fm_set_all(ax(ispin, iiter), 0.0_dp)
873 END DO
874
875 CALL cphf_like_update(qs_env, mo_coeff_o, &
876 mo_coeff_v, eigenval, p_env, &
877 xn(:, iiter), fm_g_mu_nu, fm_back, transf_type_in, &
878 ax(:, iiter))
879
880 ! in order to reduce the number of parallel sums here we
881 ! cluster all necessary scalar products into a single vector
882 ! temp_vals contains:
883 ! 1:iiter -> <Ax_i|x_j>
884 ! iiter+1 -> <x_i|b>
885 ! iiter+2 -> <x_i|x_i>
886
887 ALLOCATE (temp_vals(iiter + 2))
888 temp_vals = 0.0_dp
889 ! <Ax_i|x_j>
890 DO iib = 1, iiter
891 temp_vals(iib) = temp_vals(iib) + accurate_dot_product_spin(ax(:, iiter), xn(:, iib))
892 END DO
893 ! <x_i|b>
894 temp_vals(iiter + 1) = temp_vals(iiter + 1) + accurate_dot_product_spin(xn(:, iiter), l_jb)
895 ! norm
896 temp_vals(iiter + 2) = temp_vals(iiter + 2) + accurate_dot_product_spin(xn(:, iiter), xn(:, iiter))
897 ! update <Ax_i|x_j>, <x_i|b> and norm <x_i|x_i>
898 xi_axi(iiter, 1:iiter) = temp_vals(1:iiter)
899 xi_axi(1:iiter, iiter) = temp_vals(1:iiter)
900 xi_b(iiter) = temp_vals(iiter + 1)
901 x_norm(iiter) = temp_vals(iiter + 2)
902 DEALLOCATE (temp_vals)
903
904 ! solve reduced system
905 IF (ALLOCATED(a_small)) DEALLOCATE (a_small)
906 IF (ALLOCATED(b_small)) DEALLOCATE (b_small)
907 ALLOCATE (a_small(iiter, iiter))
908 ALLOCATE (b_small(iiter, 1))
909 a_small(1:iiter, 1:iiter) = xi_axi(1:iiter, 1:iiter)
910 b_small(1:iiter, 1) = xi_b(1:iiter)
911
912 CALL solve_system(matrix=a_small, mysize=iiter, eigenvectors=b_small)
913
914 ! check for convergence
915 DO ispin = 1, nspins
916 CALL cp_fm_set_all(residual(ispin), 0.0_dp)
917 DO iib = 1, iiter
918 residual(ispin)%local_data(:, :) = &
919 residual(ispin)%local_data(:, :) + &
920 b_small(iib, 1)*ax(ispin, iib)%local_data(:, :)
921 END DO
922
923 residual(ispin)%local_data(:, :) = &
924 residual(ispin)%local_data(:, :) - &
925 l_jb(ispin)%local_data(:, :)
926 END DO
927
928 conv = sqrt(accurate_dot_product_spin(residual, residual))
929
930 t2 = m_walltime()
931
932 IF (unit_nr > 0) THEN
933 WRITE (unit_nr, '(T3,I5,T13,F6.1,11X,F14.8)') iiter, t2 - t1, conv
934 CALL m_flush(unit_nr)
935 END IF
936
937 IF (conv <= eps_conv) THEN
938 converged = .true.
939 EXIT
940 END IF
941
942 ! update b_i for the next round
943 DO ispin = 1, nspins
944 b_i(ispin)%local_data(:, :) = b_i(ispin)%local_data(:, :) &
945 + precond(ispin)%local_data(:, :) &
946 *ax(ispin, iiter)%local_data(:, :)
947 END DO
948
949 scale_cphf = 1.0_dp
950
951 END DO
952
953 IF (unit_nr > 0) THEN
954 WRITE (unit_nr, '(T4,A)') repeat("-", 40)
955 IF (converged) THEN
956 WRITE (unit_nr, '(T3,A,I5,A)') 'Z-Vector equations converged in', cycle_counter, ' steps'
957 ELSE
958 WRITE (unit_nr, '(T3,A,I5,A)') 'Z-Vector equations NOT converged in', cycle_counter, ' steps'
959 END IF
960 END IF
961
962 ! store solution into P_ia
963 DO iiter = 1, cycle_counter
964 DO ispin = 1, nspins
965 p_ia(ispin)%local_data(:, :) = p_ia(ispin)%local_data(:, :) + &
966 b_small(iiter, 1)*xn(ispin, iiter)%local_data(:, :)
967 END DO
968 END DO
969
970 ! Release arrays
971 DEALLOCATE (x_norm)
972 DEALLOCATE (xi_b)
973 DEALLOCATE (xi_axi)
974
975 CALL cp_fm_release(b_i)
976 CALL cp_fm_release(residual)
977 CALL cp_fm_release(ax)
978 CALL cp_fm_release(xn)
979
980 ELSE
981 IF (unit_nr > 0) THEN
982 WRITE (unit_nr, '(T4,A)') repeat("-", 40)
983 WRITE (unit_nr, '(T3,A)') 'Residual smaller than EPS_CONV. Skip solution of Z-vector equation.'
984 END IF
985 END IF
986
987 CALL timestop(handle)
988
989 END SUBROUTINE solve_z_vector_pople
990
991! **************************************************************************************************
992!> \brief ...
993!> \param qs_env ...
994!> \param mp2_env ...
995!> \param unit_nr ...
996!> \param mo_coeff_o ...
997!> \param mo_coeff_v ...
998!> \param Eigenval ...
999!> \param p_env ...
1000!> \param L_jb ...
1001!> \param fm_G_mu_nu ...
1002!> \param fm_back ...
1003!> \param P_ia ...
1004!> \param precond ...
1005! **************************************************************************************************
1006 SUBROUTINE solve_z_vector_cg(qs_env, mp2_env, unit_nr, &
1007 mo_coeff_o, mo_coeff_v, Eigenval, p_env, &
1008 L_jb, fm_G_mu_nu, fm_back, P_ia, precond)
1009 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
1010 TYPE(mp2_type), INTENT(IN) :: mp2_env
1011 INTEGER, INTENT(IN) :: unit_nr
1012 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff_o, mo_coeff_v
1013 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: eigenval
1014 TYPE(qs_p_env_type), INTENT(IN), POINTER :: p_env
1015 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: l_jb
1016 TYPE(cp_fm_type), INTENT(INOUT) :: fm_g_mu_nu
1017 TYPE(cp_fm_type), INTENT(IN) :: fm_back
1018 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: p_ia, precond
1019
1020 CHARACTER(LEN=*), PARAMETER :: routinen = 'solve_z_vector_cg'
1021
1022 INTEGER :: cycles_passed, handle, iiter, ispin, max_num_iter, nspins, restart_counter, &
1023 restart_every, transf_type_in, z_solver_method
1024 LOGICAL :: converged, do_restart
1025 REAL(kind=dp) :: eps_conv, norm_residual, norm_residual_old, &
1026 residual_dot_diff_search_vec_new, residual_dot_diff_search_vec_old, &
1027 residual_dot_search_vec, residual_new_dot_diff_search_vec_old, scale_result, &
1028 scale_search, scale_step_size, search_vec_dot_a_search_vec, t1, t2
1029 TYPE(cp_fm_struct_p_type), ALLOCATABLE, &
1030 DIMENSION(:) :: fm_struct_tmp
1031 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: a_dot_search_vector, diff_search_vector, &
1032 residual, search_vector
1033
1034 CALL timeset(routinen, handle)
1035
1036 max_num_iter = mp2_env%ri_grad%cphf_max_num_iter
1037 eps_conv = mp2_env%ri_grad%cphf_eps_conv
1038 z_solver_method = mp2_env%ri_grad%z_solver_method
1039 restart_every = mp2_env%ri_grad%cphf_restart
1040 scale_step_size = mp2_env%ri_grad%scale_step_size
1041 transf_type_in = 3
1042 nspins = SIZE(eigenval, 2)
1043
1044 IF (unit_nr > 0) THEN
1045 WRITE (unit_nr, *)
1046 SELECT CASE (z_solver_method)
1047 CASE (z_solver_cg)
1048 IF (mp2_env%ri_grad%polak_ribiere) THEN
1049 WRITE (unit_nr, '(T3,A)') 'MP2_CPHF| Iterative solution of Z-Vector equations (CG with Polak-Ribiere step)'
1050 ELSE
1051 WRITE (unit_nr, '(T3,A)') 'MP2_CPHF| Iterative solution of Z-Vector equations (CG with Fletcher-Reeves step)'
1052 END IF
1053 CASE (z_solver_richardson)
1054 WRITE (unit_nr, '(T3,A)') 'MP2_CPHF| Iterative solution of Z-Vector equations (Richardson method)'
1055 CASE (z_solver_sd)
1056 WRITE (unit_nr, '(T3,A)') 'MP2_CPHF| Iterative solution of Z-Vector equations (Steepest Descent method)'
1057 CASE DEFAULT
1058 cpabort("Unknown solver")
1059 END SELECT
1060 WRITE (unit_nr, '(T3,A,T45,ES8.1)') 'MP2_CPHF| Convergence threshold:', eps_conv
1061 WRITE (unit_nr, '(T3,A,T45,I8)') 'MP2_CPHF| Maximum number of iterations: ', max_num_iter
1062 WRITE (unit_nr, '(T3,A,T45,I8)') 'MP2_CPHF| Number of steps for restart: ', restart_every
1063 WRITE (unit_nr, '(T3, A)') 'MP2_CPHF| Restart after no decrease'
1064 WRITE (unit_nr, '(T3,A,T45,ES8.1)') 'MP2_CPHF| Scaling factor of each step: ', scale_step_size
1065 WRITE (unit_nr, '(T4,A)') repeat("-", 40)
1066 WRITE (unit_nr, '(T4,A,T13,A,T28,A,T43,A)') 'Step', 'Restart', 'Time', 'Convergence'
1067 WRITE (unit_nr, '(T4,A)') repeat("-", 40)
1068 END IF
1069
1070 ALLOCATE (fm_struct_tmp(nspins), residual(nspins), diff_search_vector(nspins), &
1071 search_vector(nspins), a_dot_search_vector(nspins))
1072 DO ispin = 1, nspins
1073 fm_struct_tmp(ispin)%struct => p_ia(ispin)%matrix_struct
1074
1075 CALL cp_fm_create(residual(ispin), fm_struct_tmp(ispin)%struct, name="residual")
1076 CALL cp_fm_set_all(residual(ispin), 0.0_dp)
1077
1078 CALL cp_fm_create(diff_search_vector(ispin), fm_struct_tmp(ispin)%struct, name="difference search vector")
1079 CALL cp_fm_set_all(diff_search_vector(ispin), 0.0_dp)
1080
1081 CALL cp_fm_create(search_vector(ispin), fm_struct_tmp(ispin)%struct, name="search vector")
1082 CALL cp_fm_set_all(search_vector(ispin), 0.0_dp)
1083
1084 CALL cp_fm_create(a_dot_search_vector(ispin), fm_struct_tmp(ispin)%struct, name="A times search vector")
1085 CALL cp_fm_set_all(a_dot_search_vector(ispin), 0.0_dp)
1086 END DO
1087
1088 converged = .false.
1089 cycles_passed = max_num_iter
1090 ! By that, we enforce the setup of the matrices
1091 do_restart = .true.
1092
1093 t1 = m_walltime()
1094
1095 DO iiter = 1, max_num_iter
1096
1097 ! During the first iteration, P_ia=0 such that the application of the 2nd order matrix is zero
1098 IF (do_restart) THEN
1099 ! We do not consider the first step to be a restart
1100 ! Do not recalculate residual if it is already enforced to save FLOPs
1101 IF (.NOT. mp2_env%ri_grad%recalc_residual .OR. (iiter == 1)) THEN
1102 IF (iiter > 1) THEN
1103 CALL cphf_like_update(qs_env, mo_coeff_o, &
1104 mo_coeff_v, eigenval, p_env, &
1105 p_ia, fm_g_mu_nu, fm_back, transf_type_in, &
1106 residual)
1107 ELSE
1108 do_restart = .false.
1109
1110 DO ispin = 1, nspins
1111 CALL cp_fm_set_all(residual(ispin), 0.0_dp)
1112 END DO
1113 END IF
1114
1115 DO ispin = 1, nspins
1116 residual(ispin)%local_data(:, :) = l_jb(ispin)%local_data(:, :) &
1117 - residual(ispin)%local_data(:, :)
1118 END DO
1119 END IF
1120
1121 DO ispin = 1, nspins
1122 diff_search_vector(ispin)%local_data(:, :) = &
1123 precond(ispin)%local_data(:, :)*residual(ispin)%local_data(:, :)
1124 search_vector(ispin)%local_data(:, :) = diff_search_vector(ispin)%local_data(:, :)
1125 END DO
1126
1127 restart_counter = 1
1128 END IF
1129
1130 norm_residual_old = sqrt(accurate_dot_product_spin(residual, residual))
1131
1132 residual_dot_diff_search_vec_old = accurate_dot_product_spin(residual, diff_search_vector)
1133
1134 CALL cphf_like_update(qs_env, mo_coeff_o, &
1135 mo_coeff_v, eigenval, p_env, &
1136 search_vector, fm_g_mu_nu, fm_back, transf_type_in, &
1137 a_dot_search_vector)
1138
1139 IF (z_solver_method /= z_solver_richardson) THEN
1140 search_vec_dot_a_search_vec = accurate_dot_product_spin(search_vector, a_dot_search_vector)
1141
1142 IF (z_solver_method == z_solver_cg) THEN
1143 scale_result = residual_dot_diff_search_vec_old/search_vec_dot_a_search_vec
1144 ELSE
1145 residual_dot_search_vec = accurate_dot_product_spin(residual, search_vector)
1146 scale_result = residual_dot_search_vec/search_vec_dot_a_search_vec
1147 END IF
1148
1149 scale_result = scale_result*scale_step_size
1150
1151 ELSE
1152
1153 scale_result = scale_step_size
1154
1155 END IF
1156
1157 DO ispin = 1, nspins
1158 p_ia(ispin)%local_data(:, :) = p_ia(ispin)%local_data(:, :) &
1159 + scale_result*search_vector(ispin)%local_data(:, :)
1160 END DO
1161
1162 IF (.NOT. mp2_env%ri_grad%recalc_residual) THEN
1163
1164 DO ispin = 1, nspins
1165 residual(ispin)%local_data(:, :) = residual(ispin)%local_data(:, :) &
1166 - scale_result*a_dot_search_vector(ispin)%local_data(:, :)
1167 END DO
1168 ELSE
1169 CALL cphf_like_update(qs_env, mo_coeff_o, &
1170 mo_coeff_v, eigenval, p_env, &
1171 p_ia, fm_g_mu_nu, fm_back, transf_type_in, &
1172 residual)
1173
1174 DO ispin = 1, nspins
1175 residual(ispin)%local_data(:, :) = l_jb(ispin)%local_data(:, :) - residual(ispin)%local_data(:, :)
1176 END DO
1177 END IF
1178
1179 norm_residual = sqrt(accurate_dot_product_spin(residual, residual))
1180
1181 t2 = m_walltime()
1182
1183 IF (unit_nr > 0) THEN
1184 WRITE (unit_nr, '(T3,I4,T16,L1,T26,F6.1,8X,F14.8)') iiter, do_restart, t2 - t1, norm_residual
1185 CALL m_flush(unit_nr)
1186 END IF
1187
1188 IF (norm_residual <= eps_conv) THEN
1189 converged = .true.
1190 cycles_passed = iiter
1191 EXIT
1192 END IF
1193
1194 t1 = m_walltime()
1195
1196 IF (z_solver_method == z_solver_richardson) THEN
1197 DO ispin = 1, nspins
1198 search_vector(ispin)%local_data(:, :) = &
1199 scale_step_size*precond(ispin)%local_data(:, :)*residual(ispin)%local_data(:, :)
1200 END DO
1201 ELSE IF (z_solver_method == z_solver_sd) THEN
1202 DO ispin = 1, nspins
1203 search_vector(ispin)%local_data(:, :) = &
1204 precond(ispin)%local_data(:, :)*residual(ispin)%local_data(:, :)
1205 END DO
1206 ELSE
1207 IF (mp2_env%ri_grad%polak_ribiere) &
1208 residual_new_dot_diff_search_vec_old = accurate_dot_product_spin(residual, diff_search_vector)
1209
1210 DO ispin = 1, nspins
1211 diff_search_vector(ispin)%local_data(:, :) = &
1212 precond(ispin)%local_data(:, :)*residual(ispin)%local_data(:, :)
1213 END DO
1214
1215 residual_dot_diff_search_vec_new = accurate_dot_product_spin(residual, diff_search_vector)
1216
1217 scale_search = residual_dot_diff_search_vec_new/residual_dot_diff_search_vec_old
1218 IF (mp2_env%ri_grad%polak_ribiere) scale_search = &
1219 scale_search - residual_new_dot_diff_search_vec_old/residual_dot_diff_search_vec_old
1220
1221 DO ispin = 1, nspins
1222 search_vector(ispin)%local_data(:, :) = scale_search*search_vector(ispin)%local_data(:, :) &
1223 + diff_search_vector(ispin)%local_data(:, :)
1224 END DO
1225
1226 ! Make new to old
1227 residual_dot_diff_search_vec_old = residual_dot_diff_search_vec_new
1228 END IF
1229
1230 ! Check whether the residual decrease or restart is enforced and ask for restart
1231 do_restart = (norm_residual >= norm_residual_old .OR. (mod(restart_counter, restart_every) == 0))
1232
1233 restart_counter = restart_counter + 1
1234 norm_residual_old = norm_residual
1235
1236 END DO
1237
1238 IF (unit_nr > 0) THEN
1239 WRITE (unit_nr, '(T4,A)') repeat("-", 40)
1240 IF (converged) THEN
1241 WRITE (unit_nr, '(T3,A,I5,A)') 'Z-Vector equations converged in', cycles_passed, ' steps'
1242 ELSE
1243 WRITE (unit_nr, '(T3,A,I5,A)') 'Z-Vector equations NOT converged in', max_num_iter, ' steps'
1244 END IF
1245 END IF
1246
1247 DEALLOCATE (fm_struct_tmp)
1248 CALL cp_fm_release(residual)
1249 CALL cp_fm_release(diff_search_vector)
1250 CALL cp_fm_release(search_vector)
1251 CALL cp_fm_release(a_dot_search_vector)
1252
1253 CALL timestop(handle)
1254
1255 END SUBROUTINE solve_z_vector_cg
1256
1257! **************************************************************************************************
1258!> \brief ...
1259!> \param matrix1 ...
1260!> \param matrix2 ...
1261!> \return ...
1262! **************************************************************************************************
1263 FUNCTION accurate_dot_product_spin(matrix1, matrix2) RESULT(dotproduct)
1264 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: matrix1, matrix2
1265 REAL(kind=dp) :: dotproduct
1266
1267 INTEGER :: ispin
1268
1269 dotproduct = 0.0_dp
1270 DO ispin = 1, SIZE(matrix1)
1271 dotproduct = dotproduct + accurate_dot_product(matrix1(ispin)%local_data, matrix2(ispin)%local_data)
1272 END DO
1273 CALL matrix1(1)%matrix_struct%para_env%sum(dotproduct)
1274
1275 END FUNCTION accurate_dot_product_spin
1276
1277! **************************************************************************************************
1278!> \brief ...
1279!> \param qs_env ...
1280! **************************************************************************************************
1281 SUBROUTINE update_mp2_forces(qs_env)
1282 TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
1283
1284 CHARACTER(LEN=*), PARAMETER :: routinen = 'update_mp2_forces'
1285
1286 INTEGER :: alpha, beta, handle, idir, iounit, &
1287 ispin, nimages, nocc, nspins
1288 INTEGER, DIMENSION(3) :: comp
1289 LOGICAL :: do_exx, do_hfx, use_virial
1290 REAL(kind=dp) :: e_dummy, e_hartree, e_xc, ehartree, exc
1291 REAL(kind=dp), DIMENSION(3) :: deb
1292 REAL(kind=dp), DIMENSION(3, 3) :: h_stress, pv_virial
1293 TYPE(admm_type), POINTER :: admm_env
1294 TYPE(cell_type), POINTER :: cell
1295 TYPE(cp_logger_type), POINTER :: logger
1296 TYPE(dbcsr_p_type), ALLOCATABLE, DIMENSION(:), &
1297 TARGET :: matrix_ks_aux
1298 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_p_mp2, &
1299 matrix_p_mp2_admm, matrix_s, rho1, &
1300 rho_ao, rho_ao_aux, scrm
1301 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_p, rho_ao_kp, scrm_kp
1302 TYPE(dft_control_type), POINTER :: dft_control
1303 TYPE(hfx_type), DIMENSION(:, :), POINTER :: x_data
1304 TYPE(linres_control_type), POINTER :: linres_control
1305 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
1306 TYPE(mp_para_env_type), POINTER :: para_env
1307 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1308 POINTER :: sab_orb
1309 TYPE(pw_c1d_gs_type) :: pot_g, rho_tot_g, temp_pw_g
1310 TYPE(pw_c1d_gs_type), ALLOCATABLE, DIMENSION(:) :: dvg
1311 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g, rho_mp2_g
1312 TYPE(pw_c1d_gs_type), POINTER :: rho_core
1313 TYPE(pw_env_type), POINTER :: pw_env
1314 TYPE(pw_poisson_type), POINTER :: poisson_env
1315 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1316 TYPE(pw_r3d_rs_type) :: pot_r, vh_rspace, vhxc_rspace
1317 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_mp2_r, rho_mp2_r_aux, rho_r, &
1318 tau_mp2_r, vadmm_rspace, vtau_rspace, &
1319 vxc_rspace
1320 TYPE(qs_dispersion_type), POINTER :: dispersion_env
1321 TYPE(qs_energy_type), POINTER :: energy
1322 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
1323 TYPE(qs_ks_env_type), POINTER :: ks_env
1324 TYPE(qs_p_env_type), POINTER :: p_env
1325 TYPE(qs_rho_type), POINTER :: rho, rho_aux
1326 TYPE(section_vals_type), POINTER :: hfx_section, hfx_sections, input, &
1327 xc_section
1328 TYPE(task_list_type), POINTER :: task_list_aux_fit
1329 TYPE(virial_type), POINTER :: virial
1330
1331 CALL timeset(routinen, handle)
1332
1333 NULLIFY (input, pw_env, matrix_s, rho, energy, force, virial, &
1334 matrix_p_mp2, matrix_p_mp2_admm, matrix_ks, rho_core)
1335 CALL get_qs_env(qs_env, &
1336 ks_env=ks_env, &
1337 dft_control=dft_control, &
1338 pw_env=pw_env, &
1339 input=input, &
1340 mos=mos, &
1341 para_env=para_env, &
1342 matrix_s=matrix_s, &
1343 matrix_ks=matrix_ks, &
1344 matrix_p_mp2=matrix_p_mp2, &
1345 matrix_p_mp2_admm=matrix_p_mp2_admm, &
1346 rho=rho, &
1347 cell=cell, &
1348 force=force, &
1349 virial=virial, &
1350 sab_orb=sab_orb, &
1351 energy=energy, &
1352 rho_core=rho_core, &
1353 x_data=x_data)
1354
1355 logger => cp_get_default_logger()
1356 iounit = cp_print_key_unit_nr(logger, input, "DFT%XC%WF_CORRELATION%PRINT", &
1357 extension=".mp2Log")
1358
1359 do_exx = .false.
1360 IF (qs_env%mp2_env%method == ri_rpa_method_gpw) THEN
1361 hfx_section => section_vals_get_subs_vals(qs_env%input, "DFT%XC%WF_CORRELATION%RI_RPA%HF")
1362 CALL section_vals_get(hfx_section, explicit=do_exx)
1363 END IF
1364
1365 nimages = dft_control%nimages
1366 cpassert(nimages == 1)
1367
1368 p_env => qs_env%mp2_env%ri_grad%p_env
1369
1370 CALL qs_rho_get(rho, rho_ao=rho_ao, rho_ao_kp=rho_ao_kp, rho_r=rho_r, rho_g=rho_g)
1371 nspins = SIZE(rho_ao)
1372
1373 ! check if we have to calculate the virial
1374 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
1375 IF (use_virial) virial%pv_calculate = .true.
1376
1377 CALL zero_qs_force(force)
1378 IF (use_virial) CALL zero_virial(virial, .false.)
1379
1380 DO ispin = 1, nspins
1381 CALL dbcsr_add(rho_ao(ispin)%matrix, matrix_p_mp2(ispin)%matrix, 1.0_dp, 1.0_dp)
1382 END DO
1383
1384 ! kinetic energy
1385 NULLIFY (scrm_kp)
1386 matrix_p(1:nspins, 1:1) => rho_ao(1:nspins)
1387 CALL kinetic_energy_matrix(qs_env, matrixkp_t=scrm_kp, matrix_p=matrix_p, &
1388 calculate_forces=.true., &
1389 debug_forces=debug_forces, debug_stress=debug_forces)
1390 CALL dbcsr_deallocate_matrix_set(scrm_kp)
1391
1392 scrm_kp(1:nspins, 1:1) => matrix_ks(1:nspins)
1393 CALL core_matrices(qs_env, scrm_kp, rho_ao_kp, .true., 1, &
1394 debug_forces=debug_forces, debug_stress=debug_forces)
1395
1396 ! Get the different components of the KS potential
1397 NULLIFY (vxc_rspace, vtau_rspace, vadmm_rspace)
1398 IF (use_virial) THEN
1399 h_stress = 0.0_dp
1400 CALL ks_ref_potential(qs_env, vh_rspace, vxc_rspace, vtau_rspace, vadmm_rspace, ehartree, exc, h_stress)
1401 ! Update virial
1402 virial%pv_ehartree = virial%pv_ehartree + h_stress/real(para_env%num_pe, dp)
1403 virial%pv_virial = virial%pv_virial + h_stress/real(para_env%num_pe, dp)
1404 IF (.NOT. do_exx) THEN
1405 virial%pv_exc = virial%pv_exc - virial%pv_xc
1406 virial%pv_virial = virial%pv_virial - virial%pv_xc
1407 ELSE
1408 virial%pv_xc = 0.0_dp
1409 END IF
1410 IF (debug_forces) THEN
1411 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: xc ", third_tr(h_stress)
1412 CALL para_env%sum(virial%pv_xc(1, 1))
1413 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: Corr xc ", third_tr(virial%pv_xc)
1414 END IF
1415 ELSE
1416 CALL ks_ref_potential(qs_env, vh_rspace, vxc_rspace, vtau_rspace, vadmm_rspace, ehartree, exc)
1417 END IF
1418
1419 ! Vhxc
1420 CALL get_qs_env(qs_env, pw_env=pw_env)
1421 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
1422 poisson_env=poisson_env)
1423 CALL auxbas_pw_pool%create_pw(vhxc_rspace)
1424 IF (use_virial) h_stress = virial%pv_virial
1425 IF (debug_forces) THEN
1426 deb(1:3) = force(1)%rho_elec(1:3, 1)
1427 IF (use_virial) e_dummy = third_tr(h_stress)
1428 END IF
1429 IF (do_exx) THEN
1430 DO ispin = 1, nspins
1431 CALL pw_transfer(vh_rspace, vhxc_rspace)
1432 CALL dbcsr_add(rho_ao(ispin)%matrix, matrix_p_mp2(ispin)%matrix, 1.0_dp, -1.0_dp)
1433 CALL integrate_v_rspace(v_rspace=vhxc_rspace, &
1434 hmat=matrix_ks(ispin), pmat=rho_ao(ispin), &
1435 qs_env=qs_env, calculate_forces=.true.)
1436 CALL dbcsr_add(rho_ao(ispin)%matrix, matrix_p_mp2(ispin)%matrix, 1.0_dp, 1.0_dp)
1437 CALL pw_axpy(vxc_rspace(ispin), vhxc_rspace)
1438 CALL integrate_v_rspace(v_rspace=vhxc_rspace, &
1439 hmat=matrix_ks(ispin), pmat=matrix_p_mp2(ispin), &
1440 qs_env=qs_env, calculate_forces=.true.)
1441 IF (ASSOCIATED(vtau_rspace)) THEN
1442 CALL integrate_v_rspace(v_rspace=vtau_rspace(ispin), &
1443 hmat=matrix_ks(ispin), pmat=matrix_p_mp2(ispin), &
1444 qs_env=qs_env, calculate_forces=.true., compute_tau=.true.)
1445 END IF
1446 END DO
1447 ELSE
1448 DO ispin = 1, nspins
1449 CALL pw_transfer(vh_rspace, vhxc_rspace)
1450 CALL pw_axpy(vxc_rspace(ispin), vhxc_rspace)
1451 CALL integrate_v_rspace(v_rspace=vhxc_rspace, &
1452 hmat=matrix_ks(ispin), pmat=rho_ao(ispin), &
1453 qs_env=qs_env, calculate_forces=.true.)
1454 IF (ASSOCIATED(vtau_rspace)) THEN
1455 CALL integrate_v_rspace(v_rspace=vtau_rspace(ispin), &
1456 hmat=matrix_ks(ispin), pmat=rho_ao(ispin), &
1457 qs_env=qs_env, calculate_forces=.true., compute_tau=.true.)
1458 END IF
1459 END DO
1460 END IF
1461 IF (debug_forces) THEN
1462 deb(1:3) = force(1)%rho_elec(1:3, 1) - deb(1:3)
1463 CALL para_env%sum(deb)
1464 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: P*dVhxc ", deb
1465 IF (use_virial) THEN
1466 e_dummy = third_tr(virial%pv_virial) - e_dummy
1467 CALL para_env%sum(e_dummy)
1468 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: Vhxc ", e_dummy
1469 END IF
1470 END IF
1471 IF (use_virial) THEN
1472 h_stress = virial%pv_virial - h_stress
1473 virial%pv_ehartree = virial%pv_ehartree + h_stress
1474
1475 CALL qs_rho_get(p_env%rho1, rho_r=rho_mp2_r, tau_r=tau_mp2_r)
1476 e_xc = 0.0_dp
1477 DO ispin = 1, nspins
1478 ! The potentials have been scaled in ks_ref_potential, but for pw_integral_ab, we need the unscaled potentials
1479 CALL pw_scale(vxc_rspace(ispin), 1.0_dp/vxc_rspace(ispin)%pw_grid%dvol)
1480 e_xc = e_xc + pw_integral_ab(rho_mp2_r(ispin), vxc_rspace(ispin))
1481 IF (ASSOCIATED(vtau_rspace)) CALL pw_scale(vtau_rspace(ispin), 1.0_dp/vtau_rspace(ispin)%pw_grid%dvol)
1482 IF (ASSOCIATED(vtau_rspace)) e_xc = e_xc + pw_integral_ab(tau_mp2_r(ispin), vtau_rspace(ispin))
1483 END DO
1484 IF (debug_forces .AND. iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG VIRIAL:: vxc*d1 ", e_xc
1485 DO alpha = 1, 3
1486 virial%pv_exc(alpha, alpha) = virial%pv_exc(alpha, alpha) - e_xc/real(para_env%num_pe, dp)
1487 virial%pv_virial(alpha, alpha) = virial%pv_virial(alpha, alpha) - e_xc/real(para_env%num_pe, dp)
1488 END DO
1489 END IF
1490 DO ispin = 1, nspins
1491 CALL auxbas_pw_pool%give_back_pw(vxc_rspace(ispin))
1492 IF (ASSOCIATED(vtau_rspace)) THEN
1493 CALL auxbas_pw_pool%give_back_pw(vtau_rspace(ispin))
1494 END IF
1495 END DO
1496 DEALLOCATE (vxc_rspace)
1497 CALL auxbas_pw_pool%give_back_pw(vhxc_rspace)
1498 IF (ASSOCIATED(vtau_rspace)) DEALLOCATE (vtau_rspace)
1499
1500 DO ispin = 1, nspins
1501 CALL dbcsr_add(rho_ao(ispin)%matrix, matrix_p_mp2(ispin)%matrix, 1.0_dp, -1.0_dp)
1502 END DO
1503
1504 ! pw stuff
1505 NULLIFY (poisson_env, auxbas_pw_pool)
1506 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
1507 poisson_env=poisson_env)
1508
1509 ! get some of the grids ready
1510 CALL auxbas_pw_pool%create_pw(pot_r)
1511 CALL auxbas_pw_pool%create_pw(pot_g)
1512 CALL auxbas_pw_pool%create_pw(rho_tot_g)
1513
1514 CALL pw_zero(rho_tot_g)
1515
1516 CALL qs_rho_get(p_env%rho1, rho_r=rho_mp2_r, rho_g=rho_mp2_g)
1517 DO ispin = 1, nspins
1518 CALL pw_axpy(rho_mp2_g(ispin), rho_tot_g)
1519 END DO
1520
1521 IF (use_virial) THEN
1522 ALLOCATE (dvg(3))
1523 DO idir = 1, 3
1524 CALL auxbas_pw_pool%create_pw(dvg(idir))
1525 END DO
1526 CALL pw_poisson_solve(poisson_env, rho_tot_g, vhartree=pot_g, dvhartree=dvg)
1527 ELSE
1528 CALL pw_poisson_solve(poisson_env, rho_tot_g, vhartree=pot_g)
1529 END IF
1530
1531 CALL pw_transfer(pot_g, pot_r)
1532 CALL pw_scale(pot_r, pot_r%pw_grid%dvol)
1533 CALL pw_axpy(pot_r, vh_rspace)
1534
1535 ! calculate core forces
1536 CALL integrate_v_core_rspace(vh_rspace, qs_env)
1537 IF (debug_forces) THEN
1538 deb(:) = force(1)%rho_core(:, 1)
1539 CALL para_env%sum(deb)
1540 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: core ", deb
1541 IF (use_virial) THEN
1542 e_dummy = third_tr(virial%pv_virial) - e_dummy
1543 CALL para_env%sum(e_dummy)
1544 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: core ", e_dummy
1545 END IF
1546 END IF
1547 CALL auxbas_pw_pool%give_back_pw(vh_rspace)
1548
1549 IF (use_virial) THEN
1550 ! update virial if necessary with the volume term
1551 ! first create pw auxiliary stuff
1552 CALL auxbas_pw_pool%create_pw(temp_pw_g)
1553
1554 ! make a copy of the MP2 density in G space
1555 CALL pw_copy(rho_tot_g, temp_pw_g)
1556
1557 ! calculate total SCF density and potential
1558 CALL pw_copy(rho_g(1), rho_tot_g)
1559 IF (nspins == 2) CALL pw_axpy(rho_g(2), rho_tot_g)
1560 CALL pw_axpy(rho_core, rho_tot_g)
1561 CALL pw_poisson_solve(poisson_env, rho_tot_g, vhartree=pot_g)
1562
1563 ! finally update virial with the volume contribution
1564 e_hartree = pw_integral_ab(temp_pw_g, pot_g)
1565 IF (debug_forces .AND. iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: vh1*d0 ", e_hartree
1566
1567 h_stress = 0.0_dp
1568 DO alpha = 1, 3
1569 comp = 0
1570 comp(alpha) = 1
1571 CALL pw_copy(pot_g, rho_tot_g)
1572 CALL pw_derive(rho_tot_g, comp)
1573 h_stress(alpha, alpha) = -e_hartree
1574 DO beta = alpha, 3
1575 h_stress(alpha, beta) = h_stress(alpha, beta) &
1576 - 2.0_dp*pw_integral_ab(rho_tot_g, dvg(beta))/fourpi
1577 h_stress(beta, alpha) = h_stress(alpha, beta)
1578 END DO
1579 END DO
1580 IF (debug_forces .AND. iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: Hartree ", third_tr(h_stress)
1581
1582 ! free stuff
1583 CALL auxbas_pw_pool%give_back_pw(temp_pw_g)
1584 DO idir = 1, 3
1585 CALL auxbas_pw_pool%give_back_pw(dvg(idir))
1586 END DO
1587 DEALLOCATE (dvg)
1588
1589 virial%pv_ehartree = virial%pv_ehartree + h_stress/real(para_env%num_pe, dp)
1590 virial%pv_virial = virial%pv_virial + h_stress/real(para_env%num_pe, dp)
1591
1592 END IF
1593
1594 DO ispin = 1, nspins
1595 CALL dbcsr_set(p_env%kpp1(ispin)%matrix, 0.0_dp)
1596 IF (dft_control%do_admm) CALL dbcsr_set(p_env%kpp1_admm(ispin)%matrix, 0.0_dp)
1597 END DO
1598
1599 CALL get_qs_env(qs_env=qs_env, linres_control=linres_control)
1600
1601 IF (dft_control%do_admm) THEN
1602 CALL get_qs_env(qs_env, admm_env=admm_env)
1603 xc_section => admm_env%xc_section_primary
1604 ELSE
1605 xc_section => section_vals_get_subs_vals(input, "DFT%XC")
1606 END IF
1607
1608 IF (use_virial) THEN
1609 h_stress = 0.0_dp
1610 pv_virial = virial%pv_virial
1611 END IF
1612 IF (debug_forces) THEN
1613 deb = force(1)%rho_elec(1:3, 1)
1614 IF (use_virial) e_dummy = third_tr(pv_virial)
1615 END IF
1616 CALL apply_2nd_order_kernel(qs_env, p_env, .false., .true., use_virial, h_stress)
1617 IF (use_virial) THEN
1618 virial%pv_ehartree = virial%pv_ehartree + (virial%pv_virial - pv_virial)
1619 IF (debug_forces) THEN
1620 e_dummy = third_tr(virial%pv_virial - pv_virial)
1621 CALL para_env%sum(e_dummy)
1622 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: Kh ", e_dummy
1623 END IF
1624 virial%pv_exc = virial%pv_exc + h_stress
1625 virial%pv_virial = virial%pv_virial + h_stress
1626 IF (debug_forces) THEN
1627 e_dummy = third_tr(h_stress)
1628 CALL para_env%sum(e_dummy)
1629 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: Kxc ", e_dummy
1630 END IF
1631 END IF
1632 IF (debug_forces) THEN
1633 deb(:) = force(1)%rho_elec(:, 1) - deb
1634 CALL para_env%sum(deb)
1635 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: P0*Khxc ", deb
1636 IF (use_virial) THEN
1637 e_dummy = third_tr(virial%pv_virial) - e_dummy
1638 CALL para_env%sum(e_dummy)
1639 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: Khxc ", e_dummy
1640 END IF
1641 END IF
1642
1643 ! hfx section
1644 NULLIFY (hfx_sections)
1645 hfx_sections => section_vals_get_subs_vals(input, "DFT%XC%HF")
1646 CALL section_vals_get(hfx_sections, explicit=do_hfx)
1647 IF (do_hfx) THEN
1648 IF (do_exx) THEN
1649 IF (dft_control%do_admm) THEN
1650 CALL get_admm_env(qs_env%admm_env, rho_aux_fit=rho_aux)
1651 CALL qs_rho_get(rho_aux, rho_ao=rho_ao_aux, rho_ao_kp=rho_ao_kp)
1652 rho1 => p_env%p1_admm
1653 ELSE
1654 rho1 => p_env%p1
1655 END IF
1656 ELSE
1657 IF (dft_control%do_admm) THEN
1658 CALL get_admm_env(qs_env%admm_env, rho_aux_fit=rho_aux)
1659 CALL qs_rho_get(rho_aux, rho_ao=rho_ao_aux, rho_ao_kp=rho_ao_kp)
1660 DO ispin = 1, nspins
1661 CALL dbcsr_add(rho_ao_aux(ispin)%matrix, p_env%p1_admm(ispin)%matrix, 1.0_dp, 1.0_dp)
1662 END DO
1663 rho1 => p_env%p1_admm
1664 ELSE
1665 DO ispin = 1, nspins
1666 CALL dbcsr_add(rho_ao(ispin)%matrix, p_env%p1(ispin)%matrix, 1.0_dp, 1.0_dp)
1667 END DO
1668 rho1 => p_env%p1
1669 END IF
1670 END IF
1671
1672 IF (x_data(1, 1)%do_hfx_ri) THEN
1673
1674 CALL hfx_ri_update_forces(qs_env, x_data(1, 1)%ri_data, nspins, &
1675 x_data(1, 1)%general_parameter%fraction, &
1676 rho_ao=rho_ao_kp, rho_ao_resp=rho1, &
1677 use_virial=use_virial, resp_only=do_exx)
1678
1679 ELSE
1680 CALL derivatives_four_center(qs_env, rho_ao_kp, rho1, hfx_sections, para_env, &
1681 1, use_virial, resp_only=do_exx)
1682 END IF
1683
1684 IF (use_virial) THEN
1685 virial%pv_exx = virial%pv_exx - virial%pv_fock_4c
1686 virial%pv_virial = virial%pv_virial - virial%pv_fock_4c
1687 END IF
1688 IF (debug_forces) THEN
1689 deb(1:3) = force(1)%fock_4c(1:3, 1) - deb(1:3)
1690 CALL para_env%sum(deb)
1691 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: P*hfx ", deb
1692 IF (use_virial) THEN
1693 e_dummy = third_tr(virial%pv_fock_4c)
1694 CALL para_env%sum(e_dummy)
1695 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: hfx ", e_dummy
1696 END IF
1697 END IF
1698
1699 IF (.NOT. do_exx) THEN
1700 IF (dft_control%do_admm) THEN
1701 CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
1702 DO ispin = 1, nspins
1703 CALL dbcsr_add(rho_ao_aux(ispin)%matrix, p_env%p1_admm(ispin)%matrix, 1.0_dp, -1.0_dp)
1704 END DO
1705 ELSE
1706 DO ispin = 1, nspins
1707 CALL dbcsr_add(rho_ao(ispin)%matrix, p_env%p1(ispin)%matrix, 1.0_dp, -1.0_dp)
1708 END DO
1709 END IF
1710 END IF
1711
1712 IF (dft_control%do_admm) THEN
1713 IF (debug_forces) THEN
1714 deb = force(1)%overlap_admm(1:3, 1)
1715 IF (use_virial) e_dummy = third_tr(virial%pv_virial)
1716 END IF
1717 ! The 2nd order kernel contains a factor of two in apply_xc_admm_ao which we don't need for the projection derivatives
1718 IF (nspins == 1) CALL dbcsr_scale(p_env%kpp1_admm(1)%matrix, 0.5_dp)
1719 CALL admm_projection_derivative(qs_env, p_env%kpp1_admm, rho_ao)
1720 IF (debug_forces) THEN
1721 deb(:) = force(1)%overlap_admm(:, 1) - deb
1722 CALL para_env%sum(deb)
1723 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: P*KADMM*dS'", deb
1724 IF (use_virial) THEN
1725 e_dummy = third_tr(virial%pv_virial) - e_dummy
1726 CALL para_env%sum(e_dummy)
1727 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: KADMM*S' ", e_dummy
1728 END IF
1729 END IF
1730
1731 ALLOCATE (matrix_ks_aux(nspins))
1732 DO ispin = 1, nspins
1733 NULLIFY (matrix_ks_aux(ispin)%matrix)
1734 ALLOCATE (matrix_ks_aux(ispin)%matrix)
1735 CALL dbcsr_copy(matrix_ks_aux(ispin)%matrix, p_env%kpp1_admm(ispin)%matrix)
1736 CALL dbcsr_set(matrix_ks_aux(ispin)%matrix, 0.0_dp)
1737 END DO
1738
1739 ! Calculate kernel
1740 CALL tddft_hfx_matrix(matrix_ks_aux, rho_ao_aux, qs_env, .false.)
1741
1742 IF (qs_env%admm_env%aux_exch_func /= do_admm_aux_exch_func_none) THEN
1743 CALL get_qs_env(qs_env, ks_env=ks_env)
1744 CALL get_admm_env(qs_env%admm_env, task_list_aux_fit=task_list_aux_fit)
1745
1746 DO ispin = 1, nspins
1747 CALL dbcsr_add(rho_ao_aux(ispin)%matrix, p_env%p1_admm(ispin)%matrix, 1.0_dp, 1.0_dp)
1748 END DO
1749
1750 IF (use_virial) THEN
1751 CALL qs_rho_get(p_env%rho1_admm, rho_r=rho_mp2_r_aux)
1752 e_xc = 0.0_dp
1753 DO ispin = 1, nspins
1754 e_xc = e_xc + pw_integral_ab(rho_mp2_r_aux(ispin), vadmm_rspace(ispin))
1755 END DO
1756
1757 e_xc = -e_xc/vadmm_rspace(1)%pw_grid%dvol/real(para_env%num_pe, dp)
1758
1759 ! Update the virial
1760 DO alpha = 1, 3
1761 virial%pv_exc(alpha, alpha) = virial%pv_exc(alpha, alpha) + e_xc
1762 virial%pv_virial(alpha, alpha) = virial%pv_virial(alpha, alpha) + e_xc
1763 END DO
1764 IF (debug_forces) THEN
1765 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: P1*VADMM ", e_xc
1766 END IF
1767 END IF
1768
1769 IF (use_virial) h_stress = virial%pv_virial
1770 IF (debug_forces) THEN
1771 deb = force(1)%rho_elec(1:3, 1)
1772 IF (use_virial) e_dummy = third_tr(virial%pv_virial)
1773 END IF
1774 DO ispin = 1, nspins
1775 IF (do_exx) THEN
1776 CALL integrate_v_rspace(v_rspace=vadmm_rspace(ispin), hmat=matrix_ks_aux(ispin), qs_env=qs_env, &
1777 calculate_forces=.true., basis_type="AUX_FIT", &
1778 task_list_external=task_list_aux_fit, pmat=matrix_p_mp2_admm(ispin))
1779 ELSE
1780 CALL integrate_v_rspace(v_rspace=vadmm_rspace(ispin), hmat=matrix_ks_aux(ispin), qs_env=qs_env, &
1781 calculate_forces=.true., basis_type="AUX_FIT", &
1782 task_list_external=task_list_aux_fit, pmat=rho_ao_aux(ispin))
1783 END IF
1784 CALL auxbas_pw_pool%give_back_pw(vadmm_rspace(ispin))
1785 END DO
1786 IF (use_virial) virial%pv_ehartree = virial%pv_ehartree + (virial%pv_virial - h_stress)
1787 DEALLOCATE (vadmm_rspace)
1788 IF (debug_forces) THEN
1789 deb(:) = force(1)%rho_elec(:, 1) - deb
1790 CALL para_env%sum(deb)
1791 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: P*VADMM' ", deb
1792 IF (use_virial) THEN
1793 e_dummy = third_tr(virial%pv_virial) - e_dummy
1794 CALL para_env%sum(e_dummy)
1795 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: VADMM' ", e_dummy
1796 END IF
1797 END IF
1798
1799 DO ispin = 1, nspins
1800 CALL dbcsr_add(rho_ao_aux(ispin)%matrix, p_env%p1_admm(ispin)%matrix, 1.0_dp, -1.0_dp)
1801 END DO
1802
1803 END IF
1804
1805 DO ispin = 1, nspins
1806 CALL dbcsr_add(rho_ao(ispin)%matrix, p_env%p1(ispin)%matrix, 1.0_dp, 1.0_dp)
1807 END DO
1808
1809 IF (debug_forces) THEN
1810 deb = force(1)%overlap_admm(1:3, 1)
1811 IF (use_virial) e_dummy = third_tr(virial%pv_virial)
1812 END IF
1813 ! Add the second half of the projector deriatives contracting the first order density matrix with the fockian in the auxiliary basis
1814 IF (do_exx) THEN
1815 CALL admm_projection_derivative(qs_env, matrix_ks_aux, matrix_p_mp2)
1816 ELSE
1817 CALL admm_projection_derivative(qs_env, matrix_ks_aux, rho_ao)
1818 END IF
1819 IF (debug_forces) THEN
1820 deb(:) = force(1)%overlap_admm(:, 1) - deb
1821 CALL para_env%sum(deb)
1822 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: P*VADMM*dS'", deb
1823 IF (use_virial) THEN
1824 e_dummy = third_tr(virial%pv_virial) - e_dummy
1825 CALL para_env%sum(e_dummy)
1826 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: VADMM*S' ", e_dummy
1827 END IF
1828 END IF
1829
1830 DO ispin = 1, nspins
1831 CALL dbcsr_add(rho_ao(ispin)%matrix, p_env%p1(ispin)%matrix, 1.0_dp, -1.0_dp)
1832 END DO
1833
1834 DO ispin = 1, nspins
1835 CALL dbcsr_release(matrix_ks_aux(ispin)%matrix)
1836 DEALLOCATE (matrix_ks_aux(ispin)%matrix)
1837 END DO
1838 DEALLOCATE (matrix_ks_aux)
1839 END IF
1840 END IF
1841
1842 CALL dbcsr_scale(p_env%w1(1)%matrix, -1.0_dp)
1843
1844 ! Finish matrix_w_mp2 with occ-occ block
1845 DO ispin = 1, nspins
1846 CALL get_mo_set(mo_set=mos(ispin), homo=nocc, nmo=alpha)
1847 CALL calculate_whz_matrix(mos(ispin)%mo_coeff, p_env%kpp1(ispin)%matrix, &
1848 p_env%w1(1)%matrix, 1.0_dp, nocc)
1849 END DO
1850
1851 IF (debug_forces .AND. use_virial) e_dummy = third_tr(virial%pv_virial)
1852
1853 NULLIFY (scrm)
1854 CALL build_overlap_matrix(ks_env, matrix_s=scrm, &
1855 matrix_name="OVERLAP MATRIX", &
1856 basis_type_a="ORB", basis_type_b="ORB", &
1857 sab_nl=sab_orb, calculate_forces=.true., &
1858 matrix_p=p_env%w1(1)%matrix)
1859 CALL dbcsr_deallocate_matrix_set(scrm)
1860
1861 IF (debug_forces) THEN
1862 deb = force(1)%overlap(1:3, 1)
1863 CALL para_env%sum(deb)
1864 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: W*dS ", deb
1865 IF (use_virial) THEN
1866 e_dummy = third_tr(virial%pv_virial) - e_dummy
1867 CALL para_env%sum(e_dummy)
1868 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: S ", e_dummy
1869 END IF
1870 END IF
1871
1872 CALL auxbas_pw_pool%give_back_pw(pot_r)
1873 CALL auxbas_pw_pool%give_back_pw(pot_g)
1874 CALL auxbas_pw_pool%give_back_pw(rho_tot_g)
1875
1876 ! Release linres stuff
1877 CALL p_env_release(p_env)
1878 DEALLOCATE (p_env)
1879 NULLIFY (qs_env%mp2_env%ri_grad%p_env)
1880
1881 CALL sum_qs_force(force, qs_env%mp2_env%ri_grad%mp2_force)
1882 CALL deallocate_qs_force(qs_env%mp2_env%ri_grad%mp2_force)
1883
1884 IF (use_virial) THEN
1885 virial%pv_mp2 = qs_env%mp2_env%ri_grad%mp2_virial
1886 virial%pv_virial = virial%pv_virial + qs_env%mp2_env%ri_grad%mp2_virial
1887 IF (debug_forces) THEN
1888 e_dummy = third_tr(virial%pv_mp2)
1889 CALL para_env%sum(e_dummy)
1890 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,F16.8)") "DEBUG VIRIAL:: MP2nonsep ", e_dummy
1891 END IF
1892 END IF
1893 ! Rewind the change from the beginning
1894 IF (use_virial) virial%pv_calculate = .false.
1895
1896 ! Add the dispersion forces and virials
1897 CALL get_qs_env(qs_env, dispersion_env=dispersion_env)
1898 CALL calculate_dispersion_pairpot(qs_env, dispersion_env, e_dummy, .true.)
1899
1900 CALL cp_print_key_finished_output(iounit, logger, input, &
1901 "DFT%XC%WF_CORRELATION%PRINT")
1902
1903 CALL timestop(handle)
1904
1905 END SUBROUTINE update_mp2_forces
1906
1907! **************************************************************************************************
1908!> \brief Calculates the third of the trace of a 3x3 matrix, for debugging purposes
1909!> \param matrix ...
1910!> \return ...
1911! **************************************************************************************************
1912 PURE FUNCTION third_tr(matrix)
1913 REAL(kind=dp), DIMENSION(3, 3), INTENT(IN) :: matrix
1914 REAL(kind=dp) :: third_tr
1915
1916 third_tr = (matrix(1, 1) + matrix(2, 2) + matrix(3, 3))/3.0_dp
1917
1918 END FUNCTION third_tr
1919
1920END MODULE mp2_cphf
Contains ADMM methods which require molecular orbitals.
subroutine, public admm_projection_derivative(qs_env, matrix_hz, matrix_pz, fval)
Calculate derivatives terms from overlap matrices.
Types and set/get functions for auxiliary density matrix methods.
Definition admm_types.F:15
subroutine, public get_admm_env(admm_env, mo_derivs_aux_fit, mos_aux_fit, sab_aux_fit, sab_aux_fit_asymm, sab_aux_fit_vs_orb, matrix_s_aux_fit, matrix_s_aux_fit_kp, matrix_s_aux_fit_vs_orb, matrix_s_aux_fit_vs_orb_kp, task_list_aux_fit, matrix_ks_aux_fit, matrix_ks_aux_fit_kp, matrix_ks_aux_fit_im, matrix_ks_aux_fit_dft, matrix_ks_aux_fit_hfx, matrix_ks_aux_fit_dft_kp, matrix_ks_aux_fit_hfx_kp, rho_aux_fit, rho_aux_fit_buffer, admm_dm)
Get routine for the ADMM env.
Definition admm_types.F:593
Handles all functions related to the CELL.
Definition cell_types.F:15
methods related to the blacs parallel environment
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public cp_dbcsr_plus_fm_fm_t(sparse_matrix, matrix_v, matrix_g, ncol, alpha, keep_sparsity, symmetry_mode)
performs the multiplication sparse_matrix+dense_mat*dens_mat^T if matrix_g is not explicitly given,...
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_uplo_to_full(matrix, work, uplo)
given a triangular matrix according to uplo, computes the corresponding full matrix
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_to_fm_submat(msource, mtarget, nrow, ncol, s_firstrow, s_firstcol, t_firstrow, t_firstcol)
copy just a part ot the matrix
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
Utilities for hfx and admm methods.
subroutine, public tddft_hfx_matrix(matrix_ks, rho_ao, qs_env, update_energy, recalc_integrals, external_hfx_sections, external_x_data, external_para_env)
Add the hfx contributions to the Hamiltonian.
Routines to calculate derivatives with respect to basis function origin.
subroutine, public derivatives_four_center(qs_env, rho_ao, rho_ao_resp, hfx_section, para_env, irep, use_virial, adiabatic_rescale_factor, resp_only, external_x_data)
computes four center derivatives for a full basis set and updates the forcesfock_4c arrays....
Routines to calculate EXX in RPA and energy correction methods.
Definition hfx_exx.F:16
subroutine, public add_exx_to_rhs(rhs, qs_env, ext_hfx_section, x_data, recalc_integrals, do_admm, do_ec, do_exx, reuse_hfx)
Add the EXX contribution to the RHS of the Z-vector equation, namely the HF Hamiltonian.
Definition hfx_exx.F:325
RI-methods for HFX.
Definition hfx_ri.F:12
subroutine, public hfx_ri_update_forces(qs_env, ri_data, nspins, hf_fraction, rho_ao, rho_ao_resp, mos, use_virial, resp_only, rescale_factor)
the general routine that calls the relevant force code
Definition hfx_ri.F:3044
Types and set/get functions for HFX.
Definition hfx_types.F:15
subroutine, public hfx_init_container(container, memory_usage, do_disk_storage)
This routine deletes all list entries in a container in order to deallocate the memory.
Definition hfx_types.F:2527
subroutine, public alloc_containers(data, bin_size)
...
Definition hfx_types.F:2910
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public z_solver_pople
integer, parameter, public z_solver_cg
integer, parameter, public ri_rpa_method_gpw
integer, parameter, public do_admm_aux_exch_func_none
integer, parameter, public z_solver_sd
integer, parameter, public z_solver_richardson
integer, parameter, public ot_precond_full_all
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
sums arrays of real/complex numbers with much reduced round-off as compared to a naive implementation...
Definition kahan_sum.F:29
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Provides interfaces to LAPACK routines for factorisation and linear system solving.
subroutine, public solve_system(matrix, mysize, eigenvectors)
...
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition machine.F:131
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition machine.F:148
Definition of mathematical constants and functions.
real(kind=dp), parameter, public fourpi
Interface to the message passing library MPI.
Routines to calculate CPHF like update and solve Z-vector equation for MP2 gradients (only GPW)
Definition mp2_cphf.F:14
subroutine, public solve_z_vector_eq(qs_env, mp2_env, para_env, dft_control, mo_coeff, homo, eigenval, unit_nr)
Solve Z-vector equations necessary for the calculation of the MP2 gradients, in order to be consisten...
Definition mp2_cphf.F:155
subroutine, public update_mp2_forces(qs_env)
...
Definition mp2_cphf.F:1282
Types needed for MP2 calculations.
Definition mp2_types.F:14
basic linear algebra operations for full matrixes
container for various plainwaves related things
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
subroutine, public pw_derive(pw, n)
Calculate the derivative of a plane wave vector.
functions related to the poisson solver on regular grids
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Routines to calculate 2nd order kernels from a given response density in ao basis linear response scf...
subroutine, public apply_2nd_order_kernel(qs_env, p_env, recalc_hfx_integrals, calc_forces, calc_virial, virial)
Calculate a second order kernel (DFT, HF, ADMM correction) for a given density.
Calculation of the core Hamiltonian integral matrix <a|H|b> over Cartesian Gaussian-type functions.
subroutine, public kinetic_energy_matrix(qs_env, matrixkp_t, matrix_t, matrix_p, matrix_name, calculate_forces, nderivative, sab_orb, eps_filter, basis_type, debug_forces, debug_stress)
Calculate kinetic energy matrix and possible relativistic correction.
subroutine, public core_matrices(qs_env, matrix_h, matrix_p, calculate_forces, nder, ec_env, dcdr_env, ec_env_matrices, basis_type, debug_forces, debug_stress, atcore)
...
collects routines that calculate density matrices
subroutine, public calculate_whz_matrix(c0vec, hzm, w_matrix, focc, nocc)
Calculate the Wz matrix from the MO eigenvectors, MO eigenvalues, and the MO occupation numbers....
Calculation of dispersion using pair potentials.
subroutine, public calculate_dispersion_pairpot(qs_env, dispersion_env, energy, calculate_forces, atevdw)
...
Definition of disperson types for DFT calculations.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
subroutine, public set_qs_env(qs_env, super_cell, mos, qmmm, qmmm_periodic, ewald_env, ewald_pw, mpools, rho_external, external_vxc, mask, scf_control, rel_control, qs_charges, ks_env, ks_qmmm_env, wf_history, scf_env, active_space, input, oce, rho_atom_set, rho0_atom_set, rho0_mpole, run_rtp, rtp, rhoz_set, rhoz_tot, ecoul_1c, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, efield, linres_control, xas_env, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, ls_scf_env, do_transport, transport_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, harris_env, gcp_env, mp2_env, bs_env, kg_env, force, kpoints, wanniercentres, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Set the QUICKSTEP environment.
subroutine, public sum_qs_force(qs_force_out, qs_force_in)
Sum up two qs_force entities qs_force_out = qs_force_out + qs_force_in.
subroutine, public deallocate_qs_force(qs_force)
Deallocate a Quickstep force data structure.
subroutine, public zero_qs_force(qs_force)
Initialize a Quickstep force data structure.
Integrate single or product functions over a potential on a RS grid.
Calculate the KS reference potentials.
subroutine, public ks_ref_potential(qs_env, vh_rspace, vxc_rspace, vtau_rspace, vadmm_rspace, ehartree, exc, h_stress)
calculate the Kohn-Sham reference potential
subroutine, public set_ks_env(ks_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, complex_ks, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, kinetic, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_ks_im_kp, vppl, rho_core, rho_nlcc, rho_nlcc_g, vee, neighbor_list_id, kpoints, sab_orb, sab_all, sac_ae, sac_ppl, sac_lri, sap_ppnl, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_vdw, sab_scp, sab_almo, sab_kp, sab_kp_nosym, task_list, task_list_soft, subsys, dft_control, dbcsr_dist, distribution_2d, pw_env, para_env, blacs_env)
...
Type definitiona for linear response calculations.
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
Define the neighbor list data types and the corresponding functionality.
Calculation of overlap matrix, its derivatives and forces.
Definition qs_overlap.F:19
subroutine, public build_overlap_matrix(ks_env, matrix_s, matrixkp_s, matrix_name, nderivative, basis_type_a, basis_type_b, sab_nl, calculate_forces, matrix_p, matrixkp_p)
Calculation of the overlap matrix over Cartesian Gaussian functions.
Definition qs_overlap.F:120
Utility functions for the perturbation calculations.
subroutine, public p_env_psi0_changed(p_env, qs_env)
To be called after the value of psi0 has changed. Recalculates the quantities S_psi0 and m_epsilon.
subroutine, public p_env_create(p_env, qs_env, p1_option, p1_admm_option, orthogonal_orbitals, linres_control)
allocates and initializes the perturbation environment (no setup)
subroutine, public p_env_update_rho(p_env, qs_env)
...
subroutine, public p_env_check_i_alloc(p_env, qs_env)
checks that the intenal storage is allocated, and allocs it if needed
basis types for the calculation of the perturbation of density theory.
subroutine, public p_env_release(p_env)
relases the given p_env (see doc/ReferenceCounting.html)
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
types for task lists
subroutine, public zero_virial(virial, reset)
...
stores some data used in wavefunction fitting
Definition admm_types.F:120
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
represent a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores some data used in construction of Kohn-Sham matrix
Definition hfx_types.F:510
stores all the informations relevant to an mpi environment
contained for different pw related things
environment for the poisson solver
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
calculation environment to calculate the ks matrix, holds all the needed vars. assumes that the core ...
General settings for linear response calculations.
Represent a qs system that is perturbed. Can calculate the linear operator and the rhs of the system ...
keeps the density in various representations, keeping track of which ones are valid.