(git:34ef472)
qs_scf_loop_utils.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 ! **************************************************************************************************
8 !> \brief Utility routines for qs_scf
9 ! **************************************************************************************************
11  USE cp_control_types, ONLY: dft_control_type
13  USE cp_log_handling, ONLY: cp_to_string
14  USE dbcsr_api, ONLY: dbcsr_copy,&
15  dbcsr_get_info,&
16  dbcsr_p_type,&
17  dbcsr_type
18  USE input_section_types, ONLY: section_vals_type
19  USE kinds, ONLY: default_string_length,&
20  dp
21  USE kpoint_types, ONLY: kpoint_type
22  USE message_passing, ONLY: mp_para_env_type
23  USE qs_density_matrices, ONLY: calculate_density_matrix
28  no_mixing_nr,&
30  USE qs_energy_types, ONLY: qs_energy_type
31  USE qs_environment_types, ONLY: get_qs_env,&
32  qs_environment_type
35  USE qs_ks_types, ONLY: qs_ks_did_change,&
36  qs_ks_env_type
38  USE qs_mo_occupation, ONLY: set_mo_occupation
39  USE qs_mo_types, ONLY: mo_set_type
40  USE qs_mom_methods, ONLY: do_mom_diag
41  USE qs_ot_scf, ONLY: ot_scf_destroy,&
45  USE qs_rho_types, ONLY: qs_rho_get,&
46  qs_rho_type
51  do_ot_diag,&
52  do_roks_diag,&
62  ot_method_nr,&
63  qs_scf_env_type,&
65  USE scf_control_types, ONLY: scf_control_type,&
66  smear_type
67 #include "./base/base_uses.f90"
68 
69  IMPLICIT NONE
70 
71  PRIVATE
72 
73  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_scf_loop_utils'
74 
75  PUBLIC :: qs_scf_set_loop_flags, &
79 
80 CONTAINS
81 
82 ! **************************************************************************************************
83 !> \brief computes properties for a given hamiltonian using the current wfn
84 !> \param scf_env ...
85 !> \param diis_step ...
86 !> \param energy_only ...
87 !> \param just_energy ...
88 !> \param exit_inner_loop ...
89 ! **************************************************************************************************
90  SUBROUTINE qs_scf_set_loop_flags(scf_env, diis_step, &
91  energy_only, just_energy, exit_inner_loop)
92 
93  TYPE(qs_scf_env_type), POINTER :: scf_env
94  LOGICAL :: diis_step, energy_only, just_energy, &
95  exit_inner_loop
96 
97 ! Some flags needed to be set at the beginning of the loop
98 
99  diis_step = .false.
100  energy_only = .false.
101  just_energy = .false.
102 
103  ! SCF loop, optimisation of the wfn coefficients
104  ! qs_env%rho%rho_r and qs_env%rho%rho_g should be up to date here
105 
106  scf_env%iter_count = 0
107  exit_inner_loop = .false.
108 
109  END SUBROUTINE qs_scf_set_loop_flags
110 
111 ! **************************************************************************************************
112 !> \brief takes known energy and derivatives and produces new wfns
113 !> and or density matrix
114 !> \param qs_env ...
115 !> \param scf_env ...
116 !> \param scf_control ...
117 !> \param scf_section ...
118 !> \param diis_step ...
119 !> \param energy_only ...
120 ! **************************************************************************************************
121  SUBROUTINE qs_scf_new_mos(qs_env, scf_env, scf_control, scf_section, diis_step, &
122  energy_only)
123  TYPE(qs_environment_type), POINTER :: qs_env
124  TYPE(qs_scf_env_type), POINTER :: scf_env
125  TYPE(scf_control_type), POINTER :: scf_control
126  TYPE(section_vals_type), POINTER :: scf_section
127  LOGICAL :: diis_step, energy_only
128 
129  CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_scf_new_mos'
130 
131  INTEGER :: handle, ispin
132  LOGICAL :: has_unit_metric, skip_diag_sub
133  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
134  TYPE(dft_control_type), POINTER :: dft_control
135  TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
136  TYPE(qs_energy_type), POINTER :: energy
137  TYPE(qs_ks_env_type), POINTER :: ks_env
138  TYPE(qs_rho_type), POINTER :: rho
139 
140  CALL timeset(routinen, handle)
141 
142  NULLIFY (energy, ks_env, matrix_ks, matrix_s, rho, mos, dft_control)
143 
144  CALL get_qs_env(qs_env=qs_env, &
145  matrix_s=matrix_s, energy=energy, &
146  ks_env=ks_env, &
147  matrix_ks=matrix_ks, rho=rho, mos=mos, &
148  dft_control=dft_control, &
149  has_unit_metric=has_unit_metric)
150  scf_env%iter_param = 0.0_dp
151 
152  ! transfer total_zeff_corr from qs_env to scf_env only if
153  ! correct_el_density_dip is switched on [SGh]
154  IF (dft_control%correct_el_density_dip) THEN
155  scf_env%sum_zeff_corr = qs_env%total_zeff_corr
156  IF (abs(qs_env%total_zeff_corr) > 0.0_dp) THEN
157  IF (scf_env%method /= general_diag_method_nr) THEN
158  CALL cp_abort(__location__, &
159  "Please use ALGORITHM STANDARD in "// &
160  "SCF%DIAGONALIZATION if "// &
161  "CORE_CORRECTION /= 0.0 and "// &
162  "SURFACE_DIPOLE_CORRECTION TRUE ")
163  ELSEIF (dft_control%roks) THEN
164  CALL cp_abort(__location__, &
165  "Combination of "// &
166  "CORE_CORRECTION /= 0.0 and "// &
167  "SURFACE_DIPOLE_CORRECTION TRUE "// &
168  "is not implemented with ROKS")
169  ELSEIF (scf_control%diagonalization%mom) THEN
170  CALL cp_abort(__location__, &
171  "Combination of "// &
172  "CORE_CORRECTION /= 0.0 and "// &
173  "SURFACE_DIPOLE_CORRECTION TRUE "// &
174  "is not implemented with SCF%MOM")
175  END IF
176  END IF
177  END IF
178 
179  SELECT CASE (scf_env%method)
180  CASE DEFAULT
181  CALL cp_abort(__location__, &
182  "unknown scf method: "// &
183  cp_to_string(scf_env%method))
184 
185  ! *************************************************************************
186  ! Filter matrix diagonalisation: ugly implementation at this point of time
187  ! *************************************************************************
189 
190  IF (abs(qs_env%total_zeff_corr) > 0.0_dp) THEN
191  CALL cp_abort(__location__, &
192  "CORE_CORRECTION /= 0.0 plus SURFACE_DIPOLE_CORRECTION TRUE "// &
193  "requires SCF%DIAGONALIZATION: ALGORITHM STANDARD")
194  END IF
195  CALL fb_env_do_diag(scf_env%filter_matrix_env, qs_env, &
196  matrix_ks, matrix_s, scf_section, diis_step)
197 
198  ! Diagonlization in non orthonormal case
200  IF (dft_control%roks) THEN
201  CALL do_roks_diag(scf_env, mos, matrix_ks, matrix_s, &
202  scf_control, scf_section, diis_step, &
203  has_unit_metric)
204  ELSE
205  IF (scf_control%diagonalization%mom) THEN
206  CALL do_mom_diag(scf_env, mos, matrix_ks, &
207  matrix_s, scf_control, scf_section, &
208  diis_step)
209  ELSE
210  CALL do_general_diag(scf_env, mos, matrix_ks, &
211  matrix_s, scf_control, scf_section, &
212  diis_step)
213  END IF
214  IF (scf_control%do_diag_sub) THEN
215  skip_diag_sub = (scf_env%subspace_env%eps_diag_sub > 0.0_dp) .AND. &
216  (scf_env%iter_count == 1 .OR. scf_env%iter_delta > scf_env%subspace_env%eps_diag_sub)
217  IF (.NOT. skip_diag_sub) THEN
218  CALL do_scf_diag_subspace(qs_env, scf_env, scf_env%subspace_env, mos, rho, &
219  ks_env, scf_section, scf_control)
220  END IF
221  END IF
222  END IF
223  ! Diagonlization in orthonormal case
225  IF (dft_control%roks) THEN
226  CALL do_roks_diag(scf_env, mos, matrix_ks, matrix_s, &
227  scf_control, scf_section, diis_step, &
228  has_unit_metric)
229  ELSE
230  CALL do_special_diag(scf_env, mos, matrix_ks, &
231  scf_control, scf_section, &
232  diis_step)
233  END IF
234  ! OT diagonlization
235  CASE (ot_diag_method_nr)
236  CALL do_ot_diag(scf_env, mos, matrix_ks, matrix_s, &
237  scf_control, scf_section, diis_step)
238  ! Block Krylov diagonlization
240  IF ((scf_env%krylov_space%eps_std_diag > 0.0_dp) .AND. &
241  (scf_env%iter_count == 1 .OR. scf_env%iter_delta > scf_env%krylov_space%eps_std_diag)) THEN
242  IF (scf_env%krylov_space%always_check_conv) THEN
243  CALL do_block_krylov_diag(scf_env, mos, matrix_ks, &
244  scf_control, scf_section, check_moconv_only=.true.)
245  END IF
246  CALL do_general_diag(scf_env, mos, matrix_ks, &
247  matrix_s, scf_control, scf_section, diis_step)
248  ELSE
249  CALL do_block_krylov_diag(scf_env, mos, matrix_ks, &
250  scf_control, scf_section)
251  END IF
252  IF (scf_control%do_diag_sub) THEN
253  skip_diag_sub = (scf_env%subspace_env%eps_diag_sub > 0.0_dp) .AND. &
254  (scf_env%iter_count == 1 .OR. scf_env%iter_delta > scf_env%subspace_env%eps_diag_sub)
255  IF (.NOT. skip_diag_sub) THEN
256  CALL do_scf_diag_subspace(qs_env, scf_env, scf_env%subspace_env, mos, rho, &
257  ks_env, scf_section, scf_control)
258  END IF
259  END IF
260  ! Block Davidson diagonlization
262  CALL do_block_davidson_diag(qs_env, scf_env, mos, matrix_ks, matrix_s, scf_control, &
263  scf_section, .false.)
264  ! OT without diagonlization. Needs special treatment for SCP runs
265  CASE (ot_method_nr)
266  CALL qs_scf_loop_do_ot(qs_env, scf_env, scf_control%smear, mos, rho, &
267  qs_env%mo_derivs, energy%total, &
268  matrix_s, energy_only=energy_only, has_unit_metric=has_unit_metric)
269  END SELECT
270 
271  energy%kTS = 0.0_dp
272  energy%efermi = 0.0_dp
273  CALL get_qs_env(qs_env, mos=mos)
274  DO ispin = 1, SIZE(mos)
275  energy%kTS = energy%kTS + mos(ispin)%kTS
276  energy%efermi = energy%efermi + mos(ispin)%mu
277  END DO
278  energy%efermi = energy%efermi/real(SIZE(mos), kind=dp)
279 
280  CALL timestop(handle)
281 
282  END SUBROUTINE qs_scf_new_mos
283 
284 ! **************************************************************************************************
285 !> \brief Updates MOs and density matrix using diagonalization
286 !> Kpoint code
287 !> \param qs_env ...
288 !> \param scf_env ...
289 !> \param scf_control ...
290 !> \param diis_step ...
291 ! **************************************************************************************************
292  SUBROUTINE qs_scf_new_mos_kp(qs_env, scf_env, scf_control, diis_step)
293  TYPE(qs_environment_type), POINTER :: qs_env
294  TYPE(qs_scf_env_type), POINTER :: scf_env
295  TYPE(scf_control_type), POINTER :: scf_control
296  LOGICAL :: diis_step
297 
298  CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_scf_new_mos_kp'
299 
300  INTEGER :: handle, ispin
301  LOGICAL :: has_unit_metric
302  REAL(dp) :: diis_error
303  TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks, matrix_s
304  TYPE(dft_control_type), POINTER :: dft_control
305  TYPE(kpoint_type), POINTER :: kpoints
306  TYPE(mo_set_type), DIMENSION(:, :), POINTER :: mos
307  TYPE(qs_energy_type), POINTER :: energy
308 
309  CALL timeset(routinen, handle)
310 
311  NULLIFY (dft_control, kpoints, matrix_ks, matrix_s)
312 
313  CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, kpoints=kpoints)
314  scf_env%iter_param = 0.0_dp
315 
316  IF (dft_control%roks) &
317  cpabort("KP code: ROKS method not available: ")
318 
319  SELECT CASE (scf_env%method)
320  CASE DEFAULT
321  CALL cp_abort(__location__, &
322  "KP code: Unknown scf method: "// &
323  cp_to_string(scf_env%method))
325  ! Diagonlization in non orthonormal case
326  CALL get_qs_env(qs_env, matrix_ks_kp=matrix_ks, matrix_s_kp=matrix_s)
327  CALL do_general_diag_kp(matrix_ks, matrix_s, kpoints, scf_env, scf_control, .true., &
328  diis_step, diis_error, qs_env)
329  IF (diis_step) THEN
330  scf_env%iter_param = diis_error
331  scf_env%iter_method = "DIIS/Diag."
332  ELSE
333  IF (scf_env%mixing_method == 0) THEN
334  scf_env%iter_method = "NoMix/Diag."
335  ELSE IF (scf_env%mixing_method == 1) THEN
336  scf_env%iter_param = scf_env%p_mix_alpha
337  scf_env%iter_method = "P_Mix/Diag."
338  ELSEIF (scf_env%mixing_method > 1) THEN
339  scf_env%iter_param = scf_env%mixing_store%alpha
340  scf_env%iter_method = trim(scf_env%mixing_store%iter_method)//"/Diag."
341  END IF
342  END IF
344  CALL get_qs_env(qs_env=qs_env, has_unit_metric=has_unit_metric)
345  cpassert(has_unit_metric)
346  ! Diagonlization in orthonormal case
347  CALL cp_abort(__location__, &
348  "KP code: Scf method not available: "// &
349  cp_to_string(scf_env%method))
350  CASE (ot_diag_method_nr, &
353  ot_method_nr)
354  CALL cp_abort(__location__, &
355  "KP code: Scf method not available: "// &
356  cp_to_string(scf_env%method))
357  END SELECT
358 
359  CALL get_qs_env(qs_env=qs_env, energy=energy)
360  energy%kTS = 0.0_dp
361  energy%efermi = 0.0_dp
362  mos => kpoints%kp_env(1)%kpoint_env%mos
363  DO ispin = 1, SIZE(mos, 2)
364  energy%kTS = energy%kTS + mos(1, ispin)%kTS
365  energy%efermi = energy%efermi + mos(1, ispin)%mu
366  END DO
367  energy%efermi = energy%efermi/real(SIZE(mos, 2), kind=dp)
368 
369  CALL timestop(handle)
370 
371  END SUBROUTINE qs_scf_new_mos_kp
372 
373 ! **************************************************************************************************
374 !> \brief the inner loop of scf, specific to using to the orbital transformation method
375 !> basically, in goes the ks matrix out goes a new p matrix
376 !> \param qs_env ...
377 !> \param scf_env ...
378 !> \param smear ...
379 !> \param mos ...
380 !> \param rho ...
381 !> \param mo_derivs ...
382 !> \param total_energy ...
383 !> \param matrix_s ...
384 !> \param energy_only ...
385 !> \param has_unit_metric ...
386 !> \par History
387 !> 03.2006 created [Joost VandeVondele]
388 !> 2013 moved from qs_scf [Florian Schiffmann]
389 ! **************************************************************************************************
390  SUBROUTINE qs_scf_loop_do_ot(qs_env, scf_env, smear, mos, rho, mo_derivs, total_energy, &
391  matrix_s, energy_only, has_unit_metric)
392 
393  TYPE(qs_environment_type), POINTER :: qs_env
394  TYPE(qs_scf_env_type), POINTER :: scf_env
395  TYPE(smear_type), POINTER :: smear
396  TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
397  TYPE(qs_rho_type), POINTER :: rho
398  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mo_derivs
399  REAL(kind=dp), INTENT(IN) :: total_energy
400  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
401  LOGICAL, INTENT(INOUT) :: energy_only
402  LOGICAL, INTENT(IN) :: has_unit_metric
403 
404  CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_scf_loop_do_ot'
405 
406  INTEGER :: handle, ispin
407  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rho_ao
408  TYPE(dbcsr_type), POINTER :: orthogonality_metric
409 
410  CALL timeset(routinen, handle)
411  NULLIFY (rho_ao)
412 
413  CALL qs_rho_get(rho, rho_ao=rho_ao)
414 
415  IF (has_unit_metric) THEN
416  NULLIFY (orthogonality_metric)
417  ELSE
418  orthogonality_metric => matrix_s(1)%matrix
419  END IF
420 
421  ! in case of LSD the first spin qs_ot_env will drive the minimization
422  ! in the case of a restricted calculation, it will make sure the spin orbitals are equal
423 
424  CALL ot_scf_mini(mos, mo_derivs, smear, orthogonality_metric, &
425  total_energy, energy_only, scf_env%iter_delta, &
426  scf_env%qs_ot_env)
427 
428  DO ispin = 1, SIZE(mos)
429  CALL set_mo_occupation(mo_set=mos(ispin), smear=smear)
430  END DO
431 
432  DO ispin = 1, SIZE(mos)
433  CALL calculate_density_matrix(mos(ispin), &
434  rho_ao(ispin)%matrix, &
435  use_dbcsr=.true.)
436  END DO
437 
438  scf_env%iter_method = scf_env%qs_ot_env(1)%OT_METHOD_FULL
439  scf_env%iter_param = scf_env%qs_ot_env(1)%ds_min
440  qs_env%broyden_adaptive_sigma = scf_env%qs_ot_env(1)%broyden_adaptive_sigma
441 
442  CALL timestop(handle)
443 
444  END SUBROUTINE qs_scf_loop_do_ot
445 
446 ! **************************************************************************************************
447 !> \brief Performs the requested density mixing if any needed
448 !> \param scf_env Holds SCF environment information
449 !> \param rho All data for the electron density
450 !> \param para_env Parallel environment
451 !> \param diis_step Did we do a DIIS step?
452 ! **************************************************************************************************
453  SUBROUTINE qs_scf_density_mixing(scf_env, rho, para_env, diis_step)
454  TYPE(qs_scf_env_type), POINTER :: scf_env
455  TYPE(qs_rho_type), POINTER :: rho
456  TYPE(mp_para_env_type), POINTER :: para_env
457  LOGICAL :: diis_step
458 
459  TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp
460 
461  NULLIFY (rho_ao_kp)
462 
463  CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
464 
465  SELECT CASE (scf_env%mixing_method)
466  CASE (direct_mixing_nr)
467  CALL scf_env_density_mixing(scf_env%p_mix_new, &
468  scf_env%mixing_store, rho_ao_kp, para_env, scf_env%iter_delta, scf_env%iter_count, &
469  diis=diis_step)
472  ! Compute the difference p_out-p_in
473  CALL self_consistency_check(rho_ao_kp, scf_env%p_delta, para_env, scf_env%p_mix_new, &
474  delta=scf_env%iter_delta)
475  CASE (no_mixing_nr)
476  CASE DEFAULT
477  CALL cp_abort(__location__, &
478  "unknown scf mixing method: "// &
479  cp_to_string(scf_env%mixing_method))
480  END SELECT
481 
482  END SUBROUTINE qs_scf_density_mixing
483 
484 ! **************************************************************************************************
485 !> \brief checks whether exit conditions for outer loop are satisfied
486 !> \param qs_env ...
487 !> \param scf_env ...
488 !> \param scf_control ...
489 !> \param should_stop ...
490 !> \param outer_loop_converged ...
491 !> \param exit_outer_loop ...
492 ! **************************************************************************************************
493  SUBROUTINE qs_scf_check_outer_exit(qs_env, scf_env, scf_control, should_stop, &
494  outer_loop_converged, exit_outer_loop)
495  TYPE(qs_environment_type), POINTER :: qs_env
496  TYPE(qs_scf_env_type), POINTER :: scf_env
497  TYPE(scf_control_type), POINTER :: scf_control
498  LOGICAL :: should_stop, outer_loop_converged, &
499  exit_outer_loop
500 
501  REAL(kind=dp) :: outer_loop_eps
502 
503  outer_loop_converged = .true.
504  IF (scf_control%outer_scf%have_scf) THEN
505  ! We have an outer SCF loop...
506  scf_env%outer_scf%iter_count = scf_env%outer_scf%iter_count + 1
507  outer_loop_converged = .false.
508 
509  CALL outer_loop_gradient(qs_env, scf_env)
510  ! Multiple constraints: get largest deviation
511  outer_loop_eps = sqrt(maxval(scf_env%outer_scf%gradient(:, scf_env%outer_scf%iter_count)**2))
512 
513  IF (outer_loop_eps < scf_control%outer_scf%eps_scf) outer_loop_converged = .true.
514  END IF
515 
516  exit_outer_loop = should_stop .OR. outer_loop_converged .OR. &
517  scf_env%outer_scf%iter_count > scf_control%outer_scf%max_scf
518 
519  END SUBROUTINE qs_scf_check_outer_exit
520 
521 ! **************************************************************************************************
522 !> \brief checks whether exit conditions for inner loop are satisfied
523 !> \param qs_env ...
524 !> \param scf_env ...
525 !> \param scf_control ...
526 !> \param should_stop ...
527 !> \param exit_inner_loop ...
528 !> \param inner_loop_converged ...
529 !> \param output_unit ...
530 ! **************************************************************************************************
531  SUBROUTINE qs_scf_check_inner_exit(qs_env, scf_env, scf_control, should_stop, &
532  exit_inner_loop, inner_loop_converged, output_unit)
533  TYPE(qs_environment_type), POINTER :: qs_env
534  TYPE(qs_scf_env_type), POINTER :: scf_env
535  TYPE(scf_control_type), POINTER :: scf_control
536  LOGICAL :: should_stop, exit_inner_loop, &
537  inner_loop_converged
538  INTEGER :: output_unit
539 
540  inner_loop_converged = .false.
541  exit_inner_loop = .false.
542 
543  CALL external_control(should_stop, "SCF", target_time=qs_env%target_time, &
544  start_time=qs_env%start_time)
545  IF (scf_env%iter_delta < scf_control%eps_scf) THEN
546  IF (output_unit > 0) THEN
547  WRITE (unit=output_unit, fmt="(/,T3,A,I5,A/)") &
548  "*** SCF run converged in ", scf_env%iter_count, " steps ***"
549  END IF
550  inner_loop_converged = .true.
551  exit_inner_loop = .true.
552  ELSE IF (should_stop .OR. scf_env%iter_count >= scf_control%max_scf) THEN
553  inner_loop_converged = .false.
554  exit_inner_loop = .true.
555  IF (output_unit > 0) THEN
556  WRITE (unit=output_unit, fmt="(/,T3,A,I5,A/)") &
557  "Leaving inner SCF loop after reaching ", scf_env%iter_count, " steps."
558  END IF
559  END IF
560 
561  END SUBROUTINE qs_scf_check_inner_exit
562 
563 ! **************************************************************************************************
564 !> \brief undoing density mixing. Important upon convergence
565 !> \param scf_env ...
566 !> \param rho ...
567 !> \param dft_control ...
568 !> \param para_env ...
569 !> \param diis_step ...
570 ! **************************************************************************************************
571  SUBROUTINE qs_scf_undo_mixing(scf_env, rho, dft_control, para_env, diis_step)
572  TYPE(qs_scf_env_type), POINTER :: scf_env
573  TYPE(qs_rho_type), POINTER :: rho
574  TYPE(dft_control_type), POINTER :: dft_control
575  TYPE(mp_para_env_type), POINTER :: para_env
576  LOGICAL :: diis_step
577 
578  CHARACTER(len=default_string_length) :: name
579  INTEGER :: ic, ispin, nc
580  TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp
581 
582  NULLIFY (rho_ao_kp)
583 
584  IF (scf_env%mixing_method > 0) THEN
585  CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
586  nc = SIZE(scf_env%p_mix_new, 2)
587  SELECT CASE (scf_env%mixing_method)
588  CASE (direct_mixing_nr)
589  CALL scf_env_density_mixing(scf_env%p_mix_new, scf_env%mixing_store, &
590  rho_ao_kp, para_env, scf_env%iter_delta, &
591  scf_env%iter_count, diis=diis_step, &
592  invert=.true.)
593  DO ic = 1, nc
594  DO ispin = 1, dft_control%nspins
595  CALL dbcsr_get_info(rho_ao_kp(ispin, ic)%matrix, name=name) ! keep the name
596  CALL dbcsr_copy(rho_ao_kp(ispin, ic)%matrix, scf_env%p_mix_new(ispin, ic)%matrix, name=name)
597  END DO
598  END DO
601  DO ic = 1, nc
602  DO ispin = 1, dft_control%nspins
603  CALL dbcsr_get_info(rho_ao_kp(ispin, ic)%matrix, name=name) ! keep the name
604  CALL dbcsr_copy(rho_ao_kp(ispin, ic)%matrix, scf_env%p_mix_new(ispin, ic)%matrix, name=name)
605  END DO
606  END DO
607  END SELECT
608  END IF
609  END SUBROUTINE qs_scf_undo_mixing
610 
611 ! **************************************************************************************************
612 !> \brief Performs the updates rho (takes care of mixing as well)
613 !> \param rho ...
614 !> \param qs_env ...
615 !> \param scf_env ...
616 !> \param ks_env ...
617 !> \param mix_rho ...
618 ! **************************************************************************************************
619  SUBROUTINE qs_scf_rho_update(rho, qs_env, scf_env, ks_env, mix_rho)
620  TYPE(qs_rho_type), POINTER :: rho
621  TYPE(qs_environment_type), POINTER :: qs_env
622  TYPE(qs_scf_env_type), POINTER :: scf_env
623  TYPE(qs_ks_env_type), POINTER :: ks_env
624  LOGICAL, INTENT(IN) :: mix_rho
625 
626  TYPE(mp_para_env_type), POINTER :: para_env
627 
628  NULLIFY (para_env)
629  CALL get_qs_env(qs_env, para_env=para_env)
630  ! ** update qs_env%rho
631  CALL qs_rho_update_rho(rho, qs_env=qs_env)
632  ! ** Density mixing through density matrix or on the reciprocal space grid (exclusive)
633  IF (mix_rho) THEN
634  CALL gspace_mixing(qs_env, scf_env%mixing_method, scf_env%mixing_store, rho, &
635  para_env, scf_env%iter_count)
636 
637  END IF
638  CALL qs_ks_did_change(ks_env, rho_changed=.true.)
639 
640  END SUBROUTINE qs_scf_rho_update
641 
642 ! **************************************************************************************************
643 !> \brief Performs the necessary steps before leaving innner scf loop
644 !> \param scf_env ...
645 !> \param qs_env ...
646 !> \param diis_step ...
647 !> \param output_unit ...
648 ! **************************************************************************************************
649  SUBROUTINE qs_scf_inner_finalize(scf_env, qs_env, diis_step, output_unit)
650  TYPE(qs_scf_env_type), POINTER :: scf_env
651  TYPE(qs_environment_type), POINTER :: qs_env
652  LOGICAL :: diis_step
653  INTEGER, INTENT(IN) :: output_unit
654 
655  LOGICAL :: do_kpoints
656  TYPE(dft_control_type), POINTER :: dft_control
657  TYPE(mp_para_env_type), POINTER :: para_env
658  TYPE(qs_energy_type), POINTER :: energy
659  TYPE(qs_ks_env_type), POINTER :: ks_env
660  TYPE(qs_rho_type), POINTER :: rho
661 
662  NULLIFY (energy, rho, dft_control, ks_env)
663 
664  CALL get_qs_env(qs_env=qs_env, energy=energy, ks_env=ks_env, &
665  rho=rho, dft_control=dft_control, para_env=para_env, &
666  do_kpoints=do_kpoints)
667 
668  CALL cleanup_scf_loop(scf_env)
669 
670  ! now, print out energies and charges corresponding to the obtained wfn
671  ! (this actually is not 100% consistent at this point)!
672  CALL qs_scf_print_summary(output_unit, qs_env)
673 
674  CALL qs_scf_undo_mixing(scf_env, rho, dft_control, para_env, diis_step)
675 
676  ! *** update rspace rho since the mo changed
677  ! *** this might not always be needed (i.e. no post calculation / no forces )
678  ! *** but guarantees that rho and wfn are consistent at this point
679  CALL qs_scf_rho_update(rho, qs_env, scf_env, ks_env, mix_rho=.false.)
680 
681  END SUBROUTINE qs_scf_inner_finalize
682 
683 ! **************************************************************************************************
684 !> \brief perform cleanup operations at the end of an scf loop
685 !> \param scf_env ...
686 !> \par History
687 !> 03.2006 created [Joost VandeVondele]
688 ! **************************************************************************************************
689  SUBROUTINE cleanup_scf_loop(scf_env)
690  TYPE(qs_scf_env_type), INTENT(INOUT) :: scf_env
691 
692  CHARACTER(len=*), PARAMETER :: routinen = 'cleanup_scf_loop'
693 
694  INTEGER :: handle, ispin
695 
696  CALL timeset(routinen, handle)
697 
698  SELECT CASE (scf_env%method)
699  CASE (ot_method_nr)
700  DO ispin = 1, SIZE(scf_env%qs_ot_env)
701  CALL ot_scf_destroy(scf_env%qs_ot_env(ispin))
702  END DO
703  DEALLOCATE (scf_env%qs_ot_env)
704  CASE (ot_diag_method_nr)
705  !
707  !
709  !
711  !
713  !
714  CASE DEFAULT
715  CALL cp_abort(__location__, &
716  "unknown scf method method:"// &
717  cp_to_string(scf_env%method))
718  END SELECT
719 
720  CALL timestop(handle)
721 
722  END SUBROUTINE cleanup_scf_loop
723 
724 END MODULE qs_scf_loop_utils
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
Routines to handle the external control of CP2K.
subroutine, public external_control(should_stop, flag, globenv, target_time, start_time, force_check)
External manipulations during a run : when the <PROJECT_NAME>.EXIT_$runtype command is sent the progr...
various routines to log and control the output. The idea is that decisions about where to log should ...
objects that represent the structure of input sections and the data contained in an input section
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
integer, parameter, public default_string_length
Definition: kinds.F:57
Types and basic routines needed for a kpoint calculation.
Definition: kpoint_types.F:15
Interface to the message passing library MPI.
collects routines that calculate density matrices
module that contains the definitions of the scf types
integer, parameter, public broyden_mixing_nr
integer, parameter, public no_mixing_nr
integer, parameter, public direct_mixing_nr
integer, parameter, public multisecant_mixing_nr
integer, parameter, public pulay_mixing_nr
integer, parameter, public gspace_mixing_nr
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_RI_aux_kp, matrix_s, matrix_s_RI_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, WannierCentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, rhs)
Get the QUICKSTEP environment.
subroutine, public fb_env_do_diag(fb_env, qs_env, matrix_ks, matrix_s, scf_section, diis_step)
Do filtered matrix method diagonalisation.
subroutine, public gspace_mixing(qs_env, mixing_method, mixing_store, rho, para_env, iter_count)
Driver for the g-space mixing, calls the proper routine given the requested method.
subroutine, public qs_ks_did_change(ks_env, s_mstruct_changed, rho_changed, potential_changed, full_reset)
tells that some of the things relevant to the ks calculation did change. has to be called when change...
Definition: qs_ks_types.F:919
subroutine, public self_consistency_check(rho_ao, p_delta, para_env, p_out, delta)
...
Set occupation of molecular orbitals.
Definition and initialisation of the mo data type.
Definition: qs_mo_types.F:22
methods for deltaSCF calculations
subroutine, public do_mom_diag(scf_env, mos, matrix_ks, matrix_s, scf_control, scf_section, diis_step)
do an SCF iteration, then compute occupation numbers of the new molecular orbitals according to their...
basic functionality for using ot in the scf routines.
Definition: qs_ot_scf.F:14
subroutine, public ot_scf_mini(mo_array, matrix_dedc, smear, matrix_s, energy, energy_only, delta, qs_ot_env)
...
Definition: qs_ot_scf.F:126
subroutine, public ot_scf_destroy(qs_ot_env)
...
Definition: qs_ot_scf.F:447
Routines for performing an outer scf loop.
Definition: qs_outer_scf.F:14
subroutine, public outer_loop_gradient(qs_env, scf_env)
computes the gradient wrt to the outer loop variables
Definition: qs_outer_scf.F:103
methods of the rho structure (defined in qs_rho_types)
subroutine, public qs_rho_update_rho(rho_struct, qs_env, rho_xc_external, local_rho_set, task_list_external, task_list_external_soft, pw_env_external, para_env_external)
updates rho_r and rho_g to the rhorho_ao. if use_kinetic_energy_density also computes tau_r and tau_g...
superstucture that hold various representations of the density and keeps track of which ones are vali...
Definition: qs_rho_types.F:18
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...
Definition: qs_rho_types.F:229
Different diagonalization schemes that can be used for the iterative solution of the eigenvalue probl...
subroutine, public do_ot_diag(scf_env, mos, matrix_ks, matrix_s, scf_control, scf_section, diis_step)
the inner loop of scf, specific to iterative diagonalization using OT with S matrix; basically,...
subroutine, public do_block_davidson_diag(qs_env, scf_env, mos, matrix_ks, matrix_s, scf_control, scf_section, check_moconv_only)
iterative diagonalization using the block davidson space approach
subroutine, public do_roks_diag(scf_env, mos, matrix_ks, matrix_s, scf_control, scf_section, diis_step, orthogonal_basis)
Solve a set restricted open Kohn-Sham (ROKS) equations based on the alpha and beta Kohn-Sham matrices...
subroutine, public do_general_diag_kp(matrix_ks, matrix_s, kpoints, scf_env, scf_control, update_p, diis_step, diis_error, qs_env)
Kpoint diagonalization routine Transforms matrices to kpoint, distributes kpoint groups,...
subroutine, public do_scf_diag_subspace(qs_env, scf_env, subspace_env, mos, rho, ks_env, scf_section, scf_control)
inner loop within MOS subspace, to refine occupation and density, before next diagonalization of the ...
subroutine, public do_block_krylov_diag(scf_env, mos, matrix_ks, scf_control, scf_section, check_moconv_only)
iterative diagonalization using the block Krylov-space approach
subroutine, public do_special_diag(scf_env, mos, matrix_ks, scf_control, scf_section, diis_step)
the inner loop of scf, specific to diagonalization without S matrix basically, in goes the ks matrix ...
subroutine, public do_general_diag(scf_env, mos, matrix_ks, matrix_s, scf_control, scf_section, diis_step)
...
Utility routines for qs_scf.
subroutine, public qs_scf_new_mos(qs_env, scf_env, scf_control, scf_section, diis_step, energy_only)
takes known energy and derivatives and produces new wfns and or density matrix
subroutine, public qs_scf_inner_finalize(scf_env, qs_env, diis_step, output_unit)
Performs the necessary steps before leaving innner scf loop.
subroutine, public qs_scf_check_inner_exit(qs_env, scf_env, scf_control, should_stop, exit_inner_loop, inner_loop_converged, output_unit)
checks whether exit conditions for inner loop are satisfied
subroutine, public qs_scf_set_loop_flags(scf_env, diis_step, energy_only, just_energy, exit_inner_loop)
computes properties for a given hamiltonian using the current wfn
subroutine, public qs_scf_rho_update(rho, qs_env, scf_env, ks_env, mix_rho)
Performs the updates rho (takes care of mixing as well)
subroutine, public qs_scf_new_mos_kp(qs_env, scf_env, scf_control, diis_step)
Updates MOs and density matrix using diagonalization Kpoint code.
subroutine, public qs_scf_check_outer_exit(qs_env, scf_env, scf_control, should_stop, outer_loop_converged, exit_outer_loop)
checks whether exit conditions for outer loop are satisfied
subroutine, public qs_scf_density_mixing(scf_env, rho, para_env, diis_step)
Performs the requested density mixing if any needed.
groups fairly general SCF methods, so that modules other than qs_scf can use them too split off from ...
subroutine, public scf_env_density_mixing(p_mix_new, mixing_store, rho_ao, para_env, iter_delta, iter_count, diis, invert)
perform (if requested) a density mixing
subroutine, public qs_scf_print_summary(output_unit, qs_env)
writes a summary of information after scf
module that contains the definitions of the scf types
Definition: qs_scf_types.F:14
integer, parameter, public ot_diag_method_nr
Definition: qs_scf_types.F:51
integer, parameter, public filter_matrix_diag_method_nr
Definition: qs_scf_types.F:51
integer, parameter, public block_davidson_diag_method_nr
Definition: qs_scf_types.F:51
integer, parameter, public ot_method_nr
Definition: qs_scf_types.F:51
integer, parameter, public special_diag_method_nr
Definition: qs_scf_types.F:51
integer, parameter, public block_krylov_diag_method_nr
Definition: qs_scf_types.F:51
integer, parameter, public general_diag_method_nr
Definition: qs_scf_types.F:51
parameters that control an scf iteration