(git:419edc0)
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-2025 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! **************************************************************************************************
12 USE cp_dbcsr_api, ONLY: dbcsr_copy,&
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,&
57 USE qs_scf_types, ONLY: &
64#include "./base/base_uses.f90"
65
66 IMPLICIT NONE
67
68 PRIVATE
69
70 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_scf_loop_utils'
71
72 PUBLIC :: qs_scf_set_loop_flags, &
76
77CONTAINS
78
79! **************************************************************************************************
80!> \brief computes properties for a given hamiltonian using the current wfn
81!> \param scf_env ...
82!> \param diis_step ...
83!> \param energy_only ...
84!> \param just_energy ...
85!> \param exit_inner_loop ...
86! **************************************************************************************************
87 SUBROUTINE qs_scf_set_loop_flags(scf_env, diis_step, &
88 energy_only, just_energy, exit_inner_loop)
89
90 TYPE(qs_scf_env_type), POINTER :: scf_env
91 LOGICAL :: diis_step, energy_only, just_energy, &
92 exit_inner_loop
93
94! Some flags needed to be set at the beginning of the loop
95
96 diis_step = .false.
97 energy_only = .false.
98 just_energy = .false.
99
100 ! SCF loop, optimisation of the wfn coefficients
101 ! qs_env%rho%rho_r and qs_env%rho%rho_g should be up to date here
102
103 scf_env%iter_count = 0
104 exit_inner_loop = .false.
105
106 END SUBROUTINE qs_scf_set_loop_flags
107
108! **************************************************************************************************
109!> \brief takes known energy and derivatives and produces new wfns
110!> and or density matrix
111!> \param qs_env ...
112!> \param scf_env ...
113!> \param scf_control ...
114!> \param scf_section ...
115!> \param diis_step ...
116!> \param energy_only ...
117! **************************************************************************************************
118 SUBROUTINE qs_scf_new_mos(qs_env, scf_env, scf_control, scf_section, diis_step, &
119 energy_only)
120 TYPE(qs_environment_type), POINTER :: qs_env
121 TYPE(qs_scf_env_type), POINTER :: scf_env
122 TYPE(scf_control_type), POINTER :: scf_control
123 TYPE(section_vals_type), POINTER :: scf_section
124 LOGICAL :: diis_step, energy_only
125
126 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_scf_new_mos'
127
128 INTEGER :: handle, ispin
129 LOGICAL :: has_unit_metric, skip_diag_sub
130 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
131 TYPE(dft_control_type), POINTER :: dft_control
132 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
133 TYPE(qs_energy_type), POINTER :: energy
134 TYPE(qs_ks_env_type), POINTER :: ks_env
135 TYPE(qs_rho_type), POINTER :: rho
136
137 CALL timeset(routinen, handle)
138
139 NULLIFY (energy, ks_env, matrix_ks, matrix_s, rho, mos, dft_control)
140
141 CALL get_qs_env(qs_env=qs_env, &
142 matrix_s=matrix_s, energy=energy, &
143 ks_env=ks_env, &
144 matrix_ks=matrix_ks, rho=rho, mos=mos, &
145 dft_control=dft_control, &
146 has_unit_metric=has_unit_metric)
147 scf_env%iter_param = 0.0_dp
148
149 ! transfer total_zeff_corr from qs_env to scf_env only if
150 ! correct_el_density_dip is switched on [SGh]
151 IF (dft_control%correct_el_density_dip) THEN
152 scf_env%sum_zeff_corr = qs_env%total_zeff_corr
153 IF (abs(qs_env%total_zeff_corr) > 0.0_dp) THEN
154 IF (scf_env%method /= general_diag_method_nr) THEN
155 CALL cp_abort(__location__, &
156 "Please use ALGORITHM STANDARD in "// &
157 "SCF%DIAGONALIZATION if "// &
158 "CORE_CORRECTION /= 0.0 and "// &
159 "SURFACE_DIPOLE_CORRECTION TRUE ")
160 ELSEIF (dft_control%roks) THEN
161 CALL cp_abort(__location__, &
162 "Combination of "// &
163 "CORE_CORRECTION /= 0.0 and "// &
164 "SURFACE_DIPOLE_CORRECTION TRUE "// &
165 "is not implemented with ROKS")
166 ELSEIF (scf_control%diagonalization%mom) THEN
167 CALL cp_abort(__location__, &
168 "Combination of "// &
169 "CORE_CORRECTION /= 0.0 and "// &
170 "SURFACE_DIPOLE_CORRECTION TRUE "// &
171 "is not implemented with SCF%MOM")
172 END IF
173 END IF
174 END IF
175
176 SELECT CASE (scf_env%method)
177 CASE DEFAULT
178 CALL cp_abort(__location__, &
179 "unknown scf method: "// &
180 cp_to_string(scf_env%method))
181
182 ! *************************************************************************
183 ! Filter matrix diagonalisation: ugly implementation at this point of time
184 ! *************************************************************************
186
187 IF (abs(qs_env%total_zeff_corr) > 0.0_dp) THEN
188 CALL cp_abort(__location__, &
189 "CORE_CORRECTION /= 0.0 plus SURFACE_DIPOLE_CORRECTION TRUE "// &
190 "requires SCF%DIAGONALIZATION: ALGORITHM STANDARD")
191 END IF
192 CALL fb_env_do_diag(scf_env%filter_matrix_env, qs_env, &
193 matrix_ks, matrix_s, scf_section, diis_step)
194
195 ! Diagonlization in non orthonormal case
197 IF (dft_control%roks) THEN
198 CALL do_roks_diag(scf_env, mos, matrix_ks, matrix_s, &
199 scf_control, scf_section, diis_step, &
200 has_unit_metric)
201 ELSE
202 IF (scf_control%diagonalization%mom) THEN
203 CALL do_mom_diag(scf_env, mos, matrix_ks, &
204 matrix_s, scf_control, scf_section, &
205 diis_step)
206 ELSE
207 CALL do_general_diag(scf_env, mos, matrix_ks, &
208 matrix_s, scf_control, scf_section, &
209 diis_step)
210 END IF
211 IF (scf_control%do_diag_sub) THEN
212 skip_diag_sub = (scf_env%subspace_env%eps_diag_sub > 0.0_dp) .AND. &
213 (scf_env%iter_count == 1 .OR. scf_env%iter_delta > scf_env%subspace_env%eps_diag_sub)
214 IF (.NOT. skip_diag_sub) THEN
215 CALL do_scf_diag_subspace(qs_env, scf_env, scf_env%subspace_env, mos, rho, &
216 ks_env, scf_section, scf_control)
217 END IF
218 END IF
219 END IF
220 ! Diagonlization in orthonormal case
222 IF (dft_control%roks) THEN
223 CALL do_roks_diag(scf_env, mos, matrix_ks, matrix_s, &
224 scf_control, scf_section, diis_step, &
225 has_unit_metric)
226 ELSE
227 CALL do_special_diag(scf_env, mos, matrix_ks, &
228 scf_control, scf_section, &
229 diis_step)
230 END IF
231 ! OT diagonalization
232 CASE (ot_diag_method_nr)
233 CALL do_ot_diag(scf_env, mos, matrix_ks, matrix_s, &
234 scf_control, scf_section, diis_step)
235 ! Block Krylov diagonlization
237 IF ((scf_env%krylov_space%eps_std_diag > 0.0_dp) .AND. &
238 (scf_env%iter_count == 1 .OR. scf_env%iter_delta > scf_env%krylov_space%eps_std_diag)) THEN
239 IF (scf_env%krylov_space%always_check_conv) THEN
240 CALL do_block_krylov_diag(scf_env, mos, matrix_ks, &
241 scf_control, scf_section, check_moconv_only=.true.)
242 END IF
243 CALL do_general_diag(scf_env, mos, matrix_ks, &
244 matrix_s, scf_control, scf_section, diis_step)
245 ELSE
246 CALL do_block_krylov_diag(scf_env, mos, matrix_ks, &
247 scf_control, scf_section)
248 END IF
249 IF (scf_control%do_diag_sub) THEN
250 skip_diag_sub = (scf_env%subspace_env%eps_diag_sub > 0.0_dp) .AND. &
251 (scf_env%iter_count == 1 .OR. scf_env%iter_delta > scf_env%subspace_env%eps_diag_sub)
252 IF (.NOT. skip_diag_sub) THEN
253 CALL do_scf_diag_subspace(qs_env, scf_env, scf_env%subspace_env, mos, rho, &
254 ks_env, scf_section, scf_control)
255 END IF
256 END IF
257 ! Block Davidson diagonlization
259 CALL do_block_davidson_diag(qs_env, scf_env, mos, matrix_ks, matrix_s, scf_control, &
260 scf_section, .false.)
261 ! OT without diagonlization. Needs special treatment for SCP runs
262 CASE (ot_method_nr)
263 CALL qs_scf_loop_do_ot(qs_env, scf_env, scf_control%smear, mos, rho, &
264 qs_env%mo_derivs, energy%total, &
265 matrix_s, energy_only=energy_only, has_unit_metric=has_unit_metric)
266 END SELECT
267
268 energy%kTS = 0.0_dp
269 energy%efermi = 0.0_dp
270 CALL get_qs_env(qs_env, mos=mos)
271 DO ispin = 1, SIZE(mos)
272 energy%kTS = energy%kTS + mos(ispin)%kTS
273 energy%efermi = energy%efermi + mos(ispin)%mu
274 END DO
275 energy%efermi = energy%efermi/real(SIZE(mos), kind=dp)
276
277 CALL timestop(handle)
278
279 END SUBROUTINE qs_scf_new_mos
280
281! **************************************************************************************************
282!> \brief Updates MOs and density matrix using diagonalization
283!> Kpoint code
284!> \param qs_env ...
285!> \param scf_env ...
286!> \param scf_control ...
287!> \param diis_step ...
288! **************************************************************************************************
289 SUBROUTINE qs_scf_new_mos_kp(qs_env, scf_env, scf_control, diis_step)
290 TYPE(qs_environment_type), POINTER :: qs_env
291 TYPE(qs_scf_env_type), POINTER :: scf_env
292 TYPE(scf_control_type), POINTER :: scf_control
293 LOGICAL :: diis_step
294
295 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_scf_new_mos_kp'
296
297 INTEGER :: handle, ispin
298 LOGICAL :: has_unit_metric
299 REAL(dp) :: diis_error
300 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks, matrix_s
301 TYPE(dft_control_type), POINTER :: dft_control
302 TYPE(kpoint_type), POINTER :: kpoints
303 TYPE(mo_set_type), DIMENSION(:, :), POINTER :: mos
304 TYPE(qs_energy_type), POINTER :: energy
305
306 CALL timeset(routinen, handle)
307
308 NULLIFY (dft_control, kpoints, matrix_ks, matrix_s)
309
310 CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, kpoints=kpoints)
311 scf_env%iter_param = 0.0_dp
312
313 IF (dft_control%roks) &
314 cpabort("KP code: ROKS method not available: ")
315
316 SELECT CASE (scf_env%method)
317 CASE DEFAULT
318 CALL cp_abort(__location__, &
319 "KP code: Unknown scf method: "// &
320 cp_to_string(scf_env%method))
322 ! Diagonlization in non orthonormal case
323 CALL get_qs_env(qs_env, matrix_ks_kp=matrix_ks, matrix_s_kp=matrix_s)
324 CALL do_general_diag_kp(matrix_ks, matrix_s, kpoints, scf_env, scf_control, .true., &
325 diis_step, diis_error, qs_env)
326 IF (diis_step) THEN
327 scf_env%iter_param = diis_error
328 scf_env%iter_method = "DIIS/Diag."
329 ELSE
330 IF (scf_env%mixing_method == 0) THEN
331 scf_env%iter_method = "NoMix/Diag."
332 ELSE IF (scf_env%mixing_method == 1) THEN
333 scf_env%iter_param = scf_env%p_mix_alpha
334 scf_env%iter_method = "P_Mix/Diag."
335 ELSEIF (scf_env%mixing_method > 1) THEN
336 scf_env%iter_param = scf_env%mixing_store%alpha
337 scf_env%iter_method = trim(scf_env%mixing_store%iter_method)//"/Diag."
338 END IF
339 END IF
341 CALL get_qs_env(qs_env=qs_env, has_unit_metric=has_unit_metric)
342 cpassert(has_unit_metric)
343 ! Diagonlization in orthonormal case
344 CALL cp_abort(__location__, &
345 "KP code: Scf method not available: "// &
346 cp_to_string(scf_env%method))
347 CASE (ot_diag_method_nr, &
351 CALL cp_abort(__location__, &
352 "KP code: Scf method not available: "// &
353 cp_to_string(scf_env%method))
354 CASE (smeagol_method_nr)
355 ! SMEAGOL interface
356 diis_step = .false.
357 IF (scf_env%mixing_method == 0) THEN
358 scf_env%iter_method = "NoMix/SMGL"
359 ELSE IF (scf_env%mixing_method == 1) THEN
360 scf_env%iter_param = scf_env%p_mix_alpha
361 scf_env%iter_method = "P_Mix/SMGL"
362 ELSE IF (scf_env%mixing_method > 1) THEN
363 scf_env%iter_param = scf_env%mixing_store%alpha
364 scf_env%iter_method = trim(scf_env%mixing_store%iter_method)//"/SMGL"
365 END IF
366 CALL run_smeagol_emtrans(qs_env, last=.false., iter=scf_env%iter_count, rho_ao_kp=scf_env%p_mix_new)
367 END SELECT
368
369 CALL get_qs_env(qs_env=qs_env, energy=energy)
370 energy%kTS = 0.0_dp
371 energy%efermi = 0.0_dp
372 mos => kpoints%kp_env(1)%kpoint_env%mos
373 DO ispin = 1, SIZE(mos, 2)
374 energy%kTS = energy%kTS + mos(1, ispin)%kTS
375 energy%efermi = energy%efermi + mos(1, ispin)%mu
376 END DO
377 energy%efermi = energy%efermi/real(SIZE(mos, 2), kind=dp)
378
379 CALL timestop(handle)
380
381 END SUBROUTINE qs_scf_new_mos_kp
382
383! **************************************************************************************************
384!> \brief the inner loop of scf, specific to using to the orbital transformation method
385!> basically, in goes the ks matrix out goes a new p matrix
386!> \param qs_env ...
387!> \param scf_env ...
388!> \param smear ...
389!> \param mos ...
390!> \param rho ...
391!> \param mo_derivs ...
392!> \param total_energy ...
393!> \param matrix_s ...
394!> \param energy_only ...
395!> \param has_unit_metric ...
396!> \par History
397!> 03.2006 created [Joost VandeVondele]
398!> 2013 moved from qs_scf [Florian Schiffmann]
399! **************************************************************************************************
400 SUBROUTINE qs_scf_loop_do_ot(qs_env, scf_env, smear, mos, rho, mo_derivs, total_energy, &
401 matrix_s, energy_only, has_unit_metric)
402
403 TYPE(qs_environment_type), POINTER :: qs_env
404 TYPE(qs_scf_env_type), POINTER :: scf_env
405 TYPE(smear_type), POINTER :: smear
406 TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
407 TYPE(qs_rho_type), POINTER :: rho
408 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mo_derivs
409 REAL(kind=dp), INTENT(IN) :: total_energy
410 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
411 LOGICAL, INTENT(INOUT) :: energy_only
412 LOGICAL, INTENT(IN) :: has_unit_metric
413
414 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_scf_loop_do_ot'
415
416 INTEGER :: handle, ispin
417 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rho_ao
418 TYPE(dbcsr_type), POINTER :: orthogonality_metric
419
420 CALL timeset(routinen, handle)
421 NULLIFY (rho_ao)
422
423 CALL qs_rho_get(rho, rho_ao=rho_ao)
424
425 IF (has_unit_metric) THEN
426 NULLIFY (orthogonality_metric)
427 ELSE
428 orthogonality_metric => matrix_s(1)%matrix
429 END IF
430
431 ! in case of LSD the first spin qs_ot_env will drive the minimization
432 ! in the case of a restricted calculation, it will make sure the spin orbitals are equal
433
434 CALL ot_scf_mini(mos, mo_derivs, smear, orthogonality_metric, &
435 total_energy, energy_only, scf_env%iter_delta, &
436 scf_env%qs_ot_env)
437
438 DO ispin = 1, SIZE(mos)
439 CALL set_mo_occupation(mo_set=mos(ispin), smear=smear)
440 END DO
441
442 DO ispin = 1, SIZE(mos)
443 CALL calculate_density_matrix(mos(ispin), &
444 rho_ao(ispin)%matrix, &
445 use_dbcsr=.true.)
446 END DO
447
448 scf_env%iter_method = scf_env%qs_ot_env(1)%OT_METHOD_FULL
449 scf_env%iter_param = scf_env%qs_ot_env(1)%ds_min
450 qs_env%broyden_adaptive_sigma = scf_env%qs_ot_env(1)%broyden_adaptive_sigma
451
452 CALL timestop(handle)
453
454 END SUBROUTINE qs_scf_loop_do_ot
455
456! **************************************************************************************************
457!> \brief Performs the requested density mixing if any needed
458!> \param scf_env Holds SCF environment information
459!> \param rho All data for the electron density
460!> \param para_env Parallel environment
461!> \param diis_step Did we do a DIIS step?
462! **************************************************************************************************
463 SUBROUTINE qs_scf_density_mixing(scf_env, rho, para_env, diis_step)
464 TYPE(qs_scf_env_type), POINTER :: scf_env
465 TYPE(qs_rho_type), POINTER :: rho
466 TYPE(mp_para_env_type), POINTER :: para_env
467 LOGICAL :: diis_step
468
469 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp
470
471 NULLIFY (rho_ao_kp)
472
473 CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
474
475 SELECT CASE (scf_env%mixing_method)
476 CASE (direct_mixing_nr)
477 CALL scf_env_density_mixing(scf_env%p_mix_new, &
478 scf_env%mixing_store, rho_ao_kp, para_env, scf_env%iter_delta, scf_env%iter_count, &
479 diis=diis_step)
482 ! Compute the difference p_out-p_in
483 CALL self_consistency_check(rho_ao_kp, scf_env%p_delta, para_env, scf_env%p_mix_new, &
484 delta=scf_env%iter_delta)
485 CASE (no_mixing_nr)
486 CASE DEFAULT
487 CALL cp_abort(__location__, &
488 "unknown scf mixing method: "// &
489 cp_to_string(scf_env%mixing_method))
490 END SELECT
491
492 END SUBROUTINE qs_scf_density_mixing
493
494! **************************************************************************************************
495!> \brief checks whether exit conditions for outer loop are satisfied
496!> \param qs_env ...
497!> \param scf_env ...
498!> \param scf_control ...
499!> \param should_stop ...
500!> \param outer_loop_converged ...
501!> \param exit_outer_loop ...
502! **************************************************************************************************
503 SUBROUTINE qs_scf_check_outer_exit(qs_env, scf_env, scf_control, should_stop, &
504 outer_loop_converged, exit_outer_loop)
505 TYPE(qs_environment_type), POINTER :: qs_env
506 TYPE(qs_scf_env_type), POINTER :: scf_env
507 TYPE(scf_control_type), POINTER :: scf_control
508 LOGICAL :: should_stop, outer_loop_converged, &
509 exit_outer_loop
510
511 REAL(kind=dp) :: outer_loop_eps
512
513 outer_loop_converged = .true.
514 IF (scf_control%outer_scf%have_scf) THEN
515 ! We have an outer SCF loop...
516 scf_env%outer_scf%iter_count = scf_env%outer_scf%iter_count + 1
517 outer_loop_converged = .false.
518
519 CALL outer_loop_gradient(qs_env, scf_env)
520 ! Multiple constraints: get largest deviation
521 outer_loop_eps = sqrt(maxval(scf_env%outer_scf%gradient(:, scf_env%outer_scf%iter_count)**2))
522
523 IF (outer_loop_eps < scf_control%outer_scf%eps_scf) outer_loop_converged = .true.
524 END IF
525
526 exit_outer_loop = should_stop .OR. outer_loop_converged .OR. &
527 scf_env%outer_scf%iter_count > scf_control%outer_scf%max_scf
528
529 END SUBROUTINE qs_scf_check_outer_exit
530
531! **************************************************************************************************
532!> \brief checks whether exit conditions for inner loop are satisfied
533!> \param qs_env ...
534!> \param scf_env ...
535!> \param scf_control ...
536!> \param should_stop ...
537!> \param just_energy ...
538!> \param exit_inner_loop ...
539!> \param inner_loop_converged ...
540!> \param output_unit ...
541! **************************************************************************************************
542 SUBROUTINE qs_scf_check_inner_exit(qs_env, scf_env, scf_control, should_stop, just_energy, &
543 exit_inner_loop, inner_loop_converged, output_unit)
544 TYPE(qs_environment_type), POINTER :: qs_env
545 TYPE(qs_scf_env_type), POINTER :: scf_env
546 TYPE(scf_control_type), POINTER :: scf_control
547 LOGICAL :: should_stop, just_energy, &
548 exit_inner_loop, inner_loop_converged
549 INTEGER :: output_unit
550
551 inner_loop_converged = .false.
552 exit_inner_loop = .false.
553
554 CALL external_control(should_stop, "SCF", target_time=qs_env%target_time, &
555 start_time=qs_env%start_time)
556 IF (scf_env%iter_delta < scf_control%eps_scf) THEN
557 IF (output_unit > 0) THEN
558 WRITE (unit=output_unit, fmt="(/,T3,A,I5,A/)") &
559 "*** SCF run converged in ", scf_env%iter_count, " steps ***"
560 END IF
561 inner_loop_converged = .true.
562 exit_inner_loop = .true.
563 ELSE IF (should_stop .OR. scf_env%iter_count >= scf_control%max_scf) THEN
564 inner_loop_converged = .false.
565 IF (just_energy) THEN
566 exit_inner_loop = .false.
567 ELSE
568 exit_inner_loop = .true.
569 IF (output_unit > 0) THEN
570 WRITE (unit=output_unit, fmt="(/,T3,A,I5,A/)") &
571 "Leaving inner SCF loop after reaching ", scf_env%iter_count, " steps."
572 END IF
573 END IF
574 END IF
575
576 END SUBROUTINE qs_scf_check_inner_exit
577
578! **************************************************************************************************
579!> \brief undoing density mixing. Important upon convergence
580!> \param scf_env ...
581!> \param rho ...
582!> \param dft_control ...
583!> \param para_env ...
584!> \param diis_step ...
585! **************************************************************************************************
586 SUBROUTINE qs_scf_undo_mixing(scf_env, rho, dft_control, para_env, diis_step)
587 TYPE(qs_scf_env_type), POINTER :: scf_env
588 TYPE(qs_rho_type), POINTER :: rho
589 TYPE(dft_control_type), POINTER :: dft_control
590 TYPE(mp_para_env_type), POINTER :: para_env
591 LOGICAL :: diis_step
592
593 CHARACTER(len=default_string_length) :: name
594 INTEGER :: ic, ispin, nc
595 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp
596
597 NULLIFY (rho_ao_kp)
598
599 IF (scf_env%mixing_method > 0) THEN
600 CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
601 nc = SIZE(scf_env%p_mix_new, 2)
602 SELECT CASE (scf_env%mixing_method)
603 CASE (direct_mixing_nr)
604 CALL scf_env_density_mixing(scf_env%p_mix_new, scf_env%mixing_store, &
605 rho_ao_kp, para_env, scf_env%iter_delta, &
606 scf_env%iter_count, diis=diis_step, &
607 invert=.true.)
608 DO ic = 1, nc
609 DO ispin = 1, dft_control%nspins
610 CALL dbcsr_get_info(rho_ao_kp(ispin, ic)%matrix, name=name) ! keep the name
611 CALL dbcsr_copy(rho_ao_kp(ispin, ic)%matrix, scf_env%p_mix_new(ispin, ic)%matrix, name=name)
612 END DO
613 END DO
616 DO ic = 1, nc
617 DO ispin = 1, dft_control%nspins
618 CALL dbcsr_get_info(rho_ao_kp(ispin, ic)%matrix, name=name) ! keep the name
619 CALL dbcsr_copy(rho_ao_kp(ispin, ic)%matrix, scf_env%p_mix_new(ispin, ic)%matrix, name=name)
620 END DO
621 END DO
622 END SELECT
623 END IF
624 END SUBROUTINE qs_scf_undo_mixing
625
626! **************************************************************************************************
627!> \brief Performs the updates rho (takes care of mixing as well)
628!> \param rho ...
629!> \param qs_env ...
630!> \param scf_env ...
631!> \param ks_env ...
632!> \param mix_rho ...
633! **************************************************************************************************
634 SUBROUTINE qs_scf_rho_update(rho, qs_env, scf_env, ks_env, mix_rho)
635 TYPE(qs_rho_type), POINTER :: rho
636 TYPE(qs_environment_type), POINTER :: qs_env
637 TYPE(qs_scf_env_type), POINTER :: scf_env
638 TYPE(qs_ks_env_type), POINTER :: ks_env
639 LOGICAL, INTENT(IN) :: mix_rho
640
641 TYPE(mp_para_env_type), POINTER :: para_env
642
643 NULLIFY (para_env)
644 CALL get_qs_env(qs_env, para_env=para_env)
645 ! ** update qs_env%rho
646 CALL qs_rho_update_rho(rho, qs_env=qs_env)
647 ! ** Density mixing through density matrix or on the reciprocal space grid (exclusive)
648 IF (mix_rho) THEN
649 CALL gspace_mixing(qs_env, scf_env%mixing_method, scf_env%mixing_store, rho, &
650 para_env, scf_env%iter_count)
651
652 END IF
653 CALL qs_ks_did_change(ks_env, rho_changed=.true.)
654
655 END SUBROUTINE qs_scf_rho_update
656
657! **************************************************************************************************
658!> \brief Performs the necessary steps before leaving innner scf loop
659!> \param scf_env ...
660!> \param qs_env ...
661!> \param diis_step ...
662!> \param output_unit ...
663! **************************************************************************************************
664 SUBROUTINE qs_scf_inner_finalize(scf_env, qs_env, diis_step, output_unit)
665 TYPE(qs_scf_env_type), POINTER :: scf_env
666 TYPE(qs_environment_type), POINTER :: qs_env
667 LOGICAL :: diis_step
668 INTEGER, INTENT(IN) :: output_unit
669
670 LOGICAL :: do_kpoints
671 TYPE(dft_control_type), POINTER :: dft_control
672 TYPE(mp_para_env_type), POINTER :: para_env
673 TYPE(qs_energy_type), POINTER :: energy
674 TYPE(qs_ks_env_type), POINTER :: ks_env
675 TYPE(qs_rho_type), POINTER :: rho
676
677 NULLIFY (energy, rho, dft_control, ks_env)
678
679 CALL get_qs_env(qs_env=qs_env, energy=energy, ks_env=ks_env, &
680 rho=rho, dft_control=dft_control, para_env=para_env, &
681 do_kpoints=do_kpoints)
682
683 CALL cleanup_scf_loop(scf_env)
684
685 ! now, print out energies and charges corresponding to the obtained wfn
686 ! (this actually is not 100% consistent at this point)!
687 CALL qs_scf_print_summary(output_unit, qs_env)
688
689 CALL qs_scf_undo_mixing(scf_env, rho, dft_control, para_env, diis_step)
690
691 ! *** update rspace rho since the mo changed
692 ! *** this might not always be needed (i.e. no post calculation / no forces )
693 ! *** but guarantees that rho and wfn are consistent at this point
694 CALL qs_scf_rho_update(rho, qs_env, scf_env, ks_env, mix_rho=.false.)
695
696 END SUBROUTINE qs_scf_inner_finalize
697
698! **************************************************************************************************
699!> \brief perform cleanup operations at the end of an scf loop
700!> \param scf_env ...
701!> \par History
702!> 03.2006 created [Joost VandeVondele]
703! **************************************************************************************************
704 SUBROUTINE cleanup_scf_loop(scf_env)
705 TYPE(qs_scf_env_type), INTENT(INOUT) :: scf_env
706
707 CHARACTER(len=*), PARAMETER :: routinen = 'cleanup_scf_loop'
708
709 INTEGER :: handle, ispin
710
711 CALL timeset(routinen, handle)
712
713 SELECT CASE (scf_env%method)
714 CASE (ot_method_nr)
715 DO ispin = 1, SIZE(scf_env%qs_ot_env)
716 CALL ot_scf_destroy(scf_env%qs_ot_env(ispin))
717 END DO
718 DEALLOCATE (scf_env%qs_ot_env)
719 CASE (ot_diag_method_nr)
720 !
722 !
724 !
726 !
728 !
729 CASE (smeagol_method_nr)
730 !
731 CASE DEFAULT
732 CALL cp_abort(__location__, &
733 "unknown scf method method:"// &
734 cp_to_string(scf_env%method))
735 END SELECT
736
737 CALL timestop(handle)
738
739 END SUBROUTINE cleanup_scf_loop
740
741END MODULE qs_scf_loop_utils
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
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_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)
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:129
subroutine, public ot_scf_destroy(qs_ot_env)
...
Definition qs_ot_scf.F:450
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_check_inner_exit(qs_env, scf_env, scf_control, should_stop, just_energy, exit_inner_loop, inner_loop_converged, output_unit)
checks whether exit conditions for inner loop are satisfied
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_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 smeagol_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
CP2K+SMEAGOL interface.
subroutine, public run_smeagol_emtrans(qs_env, last, iter, rho_ao_kp)
Run NEGF/SMEAGOL transport calculation.
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