(git:374b731)
Loading...
Searching...
No Matches
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! **************************************************************************************************
14 USE dbcsr_api, ONLY: dbcsr_copy,&
15 dbcsr_get_info,&
16 dbcsr_p_type,&
17 dbcsr_type
19 USE kinds, ONLY: default_string_length,&
20 dp
21 USE kpoint_types, ONLY: kpoint_type
35 USE qs_ks_types, ONLY: qs_ks_did_change,&
39 USE qs_mo_types, ONLY: mo_set_type
41 USE qs_ot_scf, ONLY: ot_scf_destroy,&
45 USE qs_rho_types, ONLY: qs_rho_get,&
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
80CONTAINS
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, &
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
724END 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.
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...
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.
subroutine, public outer_loop_gradient(qs_env, scf_env)
computes the gradient wrt to the outer loop variables
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...
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...
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
integer, parameter, public ot_diag_method_nr
integer, parameter, public filter_matrix_diag_method_nr
integer, parameter, public block_davidson_diag_method_nr
integer, parameter, public ot_method_nr
integer, parameter, public special_diag_method_nr
integer, parameter, public block_krylov_diag_method_nr
integer, parameter, public general_diag_method_nr
parameters that control an scf iteration
Contains information about kpoints.
stores all the informations relevant to an mpi environment
calculation environment to calculate the ks matrix, holds all the needed vars. assumes that the core ...
keeps the density in various representations, keeping track of which ones are valid.
contains the parameters needed by a scf run