(git:ba1d7ca)
Loading...
Searching...
No Matches
qs_diis.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Apply the direct inversion in the iterative subspace (DIIS) of Pulay
10!> in the framework of an SCF iteration for convergence acceleration
11!> \par Literature
12!> - P. Pulay, Chem. Phys. Lett. 73, 393 (1980)
13!> - P. Pulay, J. Comput. Chem. 3, 556 (1982)
14!> \par History
15!> - Changed to BLACS matrix usage (08.06.2001,MK)
16!> - rewritten to include LSD (1st attempt) (01.2003, Joost VandeVondele)
17!> - DIIS for ROKS (05.04.06,MK)
18!> - DIIS for k-points (04.2023, Augustin Bussy)
19!> \author Matthias Krack (28.06.2000)
20! **************************************************************************************************
21MODULE qs_diis
24 USE cp_cfm_types, ONLY: cp_cfm_create,&
31 USE cp_dbcsr_api, ONLY: &
34 USE cp_dbcsr_contrib, ONLY: dbcsr_dot,&
43 USE cp_fm_types, ONLY: cp_fm_create,&
57 USE kinds, ONLY: default_string_length,&
58 dp
59 USE mathlib, ONLY: diag_complex,&
68 USE qs_mo_types, ONLY: get_mo_set,&
70 USE string_utilities, ONLY: compress
71#include "./base/base_uses.f90"
72
73 IMPLICIT NONE
74
75 PRIVATE
76
77 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_diis'
78
79 ! Public subroutines
80
81 PUBLIC :: qs_diis_b_clear, &
84 PUBLIC :: qs_diis_b_clear_sparse, &
87 PUBLIC :: qs_diis_b_clear_kp, &
93
94CONTAINS
95
96! **************************************************************************************************
97!> \brief Allocates an SCF DIIS buffer
98!> \param diis_buffer the buffer to create
99!> \param nbuffer ...
100!> \par History
101!> 02.2003 created [fawzi]
102!> \author fawzi
103! **************************************************************************************************
104 SUBROUTINE qs_diis_b_create(diis_buffer, nbuffer)
105
106 TYPE(qs_diis_buffer_type), INTENT(OUT) :: diis_buffer
107 INTEGER, INTENT(in) :: nbuffer
108
109 CHARACTER(len=*), PARAMETER :: routinen = 'qs_diis_b_create'
110
111 INTEGER :: handle
112
113! -------------------------------------------------------------------------
114
115 CALL timeset(routinen, handle)
116
117 NULLIFY (diis_buffer%b_matrix)
118 NULLIFY (diis_buffer%error)
119 NULLIFY (diis_buffer%param)
120 diis_buffer%nbuffer = nbuffer
121 diis_buffer%ncall = 0
122
123 CALL timestop(handle)
124
125 END SUBROUTINE qs_diis_b_create
126
127! **************************************************************************************************
128!> \brief Allocate and initialize a DIIS buffer for nao*nao parameter
129!> variables and with a buffer size of nbuffer.
130!> \param diis_buffer the buffer to initialize
131!> \param matrix_struct the structure for the matrix of the buffer
132!> \param nspin ...
133!> \param scf_section ...
134!> \par History
135!> - Creation (07.05.2001, Matthias Krack)
136!> - Changed to BLACS matrix usage (08.06.2001,MK)
137!> - DIIS for ROKS (05.04.06,MK)
138!> \author Matthias Krack
139!> \note
140!> check to allocate matrixes only when needed, using a linked list?
141! **************************************************************************************************
142 SUBROUTINE qs_diis_b_check_i_alloc(diis_buffer, matrix_struct, nspin, &
143 scf_section)
144
145 TYPE(qs_diis_buffer_type), INTENT(INOUT) :: diis_buffer
146 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
147 INTEGER, INTENT(IN) :: nspin
148 TYPE(section_vals_type), POINTER :: scf_section
149
150 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_diis_b_check_i_alloc'
151
152 INTEGER :: handle, ibuffer, ispin, nbuffer, &
153 output_unit
154 TYPE(cp_logger_type), POINTER :: logger
155
156! -------------------------------------------------------------------------
157
158 CALL timeset(routinen, handle)
159
160 logger => cp_get_default_logger()
161
162 nbuffer = diis_buffer%nbuffer
163
164 IF (.NOT. ASSOCIATED(diis_buffer%error)) THEN
165 ALLOCATE (diis_buffer%error(nbuffer, nspin))
166
167 DO ispin = 1, nspin
168 DO ibuffer = 1, nbuffer
169 CALL cp_fm_create(diis_buffer%error(ibuffer, ispin), &
170 name="qs_diis_b%error("// &
171 trim(adjustl(cp_to_string(ibuffer)))//","// &
172 trim(adjustl(cp_to_string(ibuffer)))//")", &
173 matrix_struct=matrix_struct)
174 END DO
175 END DO
176 END IF
177
178 IF (.NOT. ASSOCIATED(diis_buffer%param)) THEN
179 ALLOCATE (diis_buffer%param(nbuffer, nspin))
180
181 DO ispin = 1, nspin
182 DO ibuffer = 1, nbuffer
183 CALL cp_fm_create(diis_buffer%param(ibuffer, ispin), &
184 name="qs_diis_b%param("// &
185 trim(adjustl(cp_to_string(ibuffer)))//","// &
186 trim(adjustl(cp_to_string(ibuffer)))//")", &
187 matrix_struct=matrix_struct)
188 END DO
189 END DO
190 END IF
191
192 IF (.NOT. ASSOCIATED(diis_buffer%b_matrix)) THEN
193 ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
194 diis_buffer%b_matrix = 0.0_dp
195 output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIIS_INFO", &
196 extension=".scfLog")
197 IF (output_unit > 0) THEN
198 WRITE (unit=output_unit, fmt="(/,T9,A)") &
199 "DIIS | The SCF DIIS buffer was allocated and initialized"
200 END IF
201 CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
202 "PRINT%DIIS_INFO")
203 END IF
204
205 CALL timestop(handle)
206
207 END SUBROUTINE qs_diis_b_check_i_alloc
208
209! **************************************************************************************************
210!> \brief Update the SCF DIIS buffer, and if appropriate does a diis step.
211!> \param diis_buffer ...
212!> \param mo_array ...
213!> \param kc ...
214!> \param sc ...
215!> \param delta ...
216!> \param error_max ...
217!> \param diis_step ...
218!> \param eps_diis ...
219!> \param nmixing ...
220!> \param s_matrix ...
221!> \param scf_section ...
222!> \param roks ...
223!> \par History
224!> - Creation (07.05.2001, Matthias Krack)
225!> - Changed to BLACS matrix usage (08.06.2001, MK)
226!> - 03.2003 rewamped [fawzi]
227!> - Adapted for high-spin ROKS (08.04.06,MK)
228!> \author Matthias Krack
229! **************************************************************************************************
230 SUBROUTINE qs_diis_b_step(diis_buffer, mo_array, kc, sc, delta, error_max, &
231 diis_step, eps_diis, nmixing, s_matrix, scf_section, roks)
232
233 TYPE(qs_diis_buffer_type), POINTER :: diis_buffer
234 TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mo_array
235 TYPE(cp_fm_type), DIMENSION(:), POINTER :: kc
236 TYPE(cp_fm_type), INTENT(IN) :: sc
237 REAL(kind=dp), INTENT(IN) :: delta
238 REAL(kind=dp), INTENT(OUT) :: error_max
239 LOGICAL, INTENT(OUT) :: diis_step
240 REAL(kind=dp), INTENT(IN) :: eps_diis
241 INTEGER, INTENT(IN), OPTIONAL :: nmixing
242 TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
243 POINTER :: s_matrix
244 TYPE(section_vals_type), POINTER :: scf_section
245 LOGICAL, INTENT(IN), OPTIONAL :: roks
246
247 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_diis_b_step'
248 REAL(kind=dp), PARAMETER :: eigenvalue_threshold = 1.0e-12_dp
249
250 CHARACTER(LEN=2*default_string_length) :: message
251 INTEGER :: handle, homo, ib, imo, ispin, jb, &
252 my_nmixing, nao, nb, nb1, nmo, nspin, &
253 output_unit
254 LOGICAL :: eigenvectors_discarded, my_roks
255 REAL(kind=dp) :: maxocc, tmp
256 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: ev, occ
257 REAL(kind=dp), DIMENSION(:), POINTER :: occa, occb
258 REAL(kind=dp), DIMENSION(:, :), POINTER :: a, b
259 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
260 TYPE(cp_fm_type), POINTER :: c, new_errors, old_errors, parameters
261 TYPE(cp_logger_type), POINTER :: logger
262
263! -------------------------------------------------------------------------
264
265 CALL timeset(routinen, handle)
266
267 nspin = SIZE(mo_array)
268 diis_step = .false.
269
270 IF (PRESENT(roks)) THEN
271 my_roks = .true.
272 nspin = 1
273 ELSE
274 my_roks = .false.
275 END IF
276
277 my_nmixing = 2
278 IF (PRESENT(nmixing)) my_nmixing = nmixing
279
280 NULLIFY (c, new_errors, old_errors, parameters, matrix_struct, a, b, occa, occb)
281 logger => cp_get_default_logger()
282
283 ! Quick return, if no DIIS is requested
284
285 IF (diis_buffer%nbuffer < 1) THEN
286 CALL timestop(handle)
287 RETURN
288 END IF
289
290 CALL cp_fm_get_info(kc(1), &
291 matrix_struct=matrix_struct)
292 CALL qs_diis_b_check_i_alloc(diis_buffer, &
293 matrix_struct=matrix_struct, &
294 nspin=nspin, &
295 scf_section=scf_section)
296
297 error_max = 0.0_dp
298
299 ib = modulo(diis_buffer%ncall, diis_buffer%nbuffer) + 1
300 diis_buffer%ncall = diis_buffer%ncall + 1
301 nb = min(diis_buffer%ncall, diis_buffer%nbuffer)
302
303 DO ispin = 1, nspin
304
305 CALL get_mo_set(mo_set=mo_array(ispin), &
306 nao=nao, &
307 nmo=nmo, &
308 homo=homo, &
309 mo_coeff=c, &
310 occupation_numbers=occa, &
311 maxocc=maxocc)
312
313 new_errors => diis_buffer%error(ib, ispin)
314 parameters => diis_buffer%param(ib, ispin)
315
316 ! Copy the Kohn-Sham matrix K to the DIIS buffer
317
318 CALL cp_fm_to_fm(kc(ispin), parameters)
319
320 IF (my_roks) THEN
321
322 ALLOCATE (occ(nmo))
323
324 CALL get_mo_set(mo_set=mo_array(2), &
325 occupation_numbers=occb)
326
327 DO imo = 1, nmo
328 occ(imo) = sqrt(occa(imo) + occb(imo))
329 END DO
330
331 CALL cp_fm_to_fm(c, sc)
332 CALL cp_fm_column_scale(sc, occ(1:homo))
333
334 ! KC <- K*C
335 CALL cp_fm_symm("L", "U", nao, homo, 1.0_dp, parameters, sc, 0.0_dp, kc(ispin))
336
337 IF (PRESENT(s_matrix)) THEN
338 CALL copy_dbcsr_to_fm(s_matrix(1)%matrix, new_errors)
339 ! SC <- S*C
340 CALL cp_fm_symm("L", "U", nao, homo, 1.0_dp, new_errors, c, 0.0_dp, sc)
341 CALL cp_fm_column_scale(sc, occ(1:homo))
342 END IF
343
344 ! new_errors <- KC*(SC)^T - (SC)*(KC)^T = K*P*S - S*P*K
345 ! or for an orthogonal basis
346 ! new_errors <- KC*C^T - C*(KC)^T = K*P - P*K with S = I
347 CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, sc, kc(ispin), 0.0_dp, new_errors)
348 CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, kc(ispin), sc, -1.0_dp, new_errors)
349
350 DEALLOCATE (occ)
351
352 ELSE
353
354 ! KC <- K*C
355 CALL cp_fm_symm("L", "U", nao, homo, maxocc, parameters, c, 0.0_dp, kc(ispin))
356
357 IF (PRESENT(s_matrix)) THEN
358 ! I guess that this copy can be avoided for LSD
359 CALL copy_dbcsr_to_fm(s_matrix(1)%matrix, new_errors)
360 ! sc <- S*C
361 CALL cp_fm_symm("L", "U", nao, homo, 2.0_dp, new_errors, c, 0.0_dp, sc)
362 ! new_errors <- KC*(SC)^T - (SC)*(KC)^T = K*P*S - S*P*K
363 CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, sc, kc(ispin), 0.0_dp, new_errors)
364 CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, kc(ispin), sc, -1.0_dp, new_errors)
365 ELSE
366 ! new_errors <- KC*(C)^T - C*(KC)^T = K*P - P*K
367 CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, c, kc(ispin), 0.0_dp, new_errors)
368 CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, kc(ispin), c, -1.0_dp, new_errors)
369 END IF
370
371 END IF
372
373 CALL cp_fm_maxabsval(new_errors, tmp)
374 error_max = max(error_max, tmp)
375
376 END DO
377
378 ! Check, if a DIIS step is appropriate
379
380 diis_step = ((diis_buffer%ncall >= my_nmixing) .AND. (delta < eps_diis))
381
382 output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIIS_INFO", &
383 extension=".scfLog")
384 IF (output_unit > 0) THEN
385 WRITE (unit=output_unit, fmt="(/,T9,A,I4,/,(T9,A,ES12.3))") &
386 "DIIS | Current SCF DIIS buffer size: ", nb, &
387 "DIIS | Maximum SCF DIIS error vector element:", error_max, &
388 "DIIS | Current SCF convergence: ", delta, &
389 "DIIS | Threshold value for a DIIS step: ", eps_diis
390 IF (error_max < eps_diis) THEN
391 WRITE (unit=output_unit, fmt="(T9,A)") &
392 "DIIS | => The SCF DIIS buffer will be updated"
393 ELSE
394 WRITE (unit=output_unit, fmt="(T9,A)") &
395 "DIIS | => No update of the SCF DIIS buffer"
396 END IF
397 IF (diis_step .AND. (error_max < eps_diis)) THEN
398 WRITE (unit=output_unit, fmt="(T9,A,/)") &
399 "DIIS | => A SCF DIIS step will be performed"
400 ELSE
401 WRITE (unit=output_unit, fmt="(T9,A,/)") &
402 "DIIS | => No SCF DIIS step will be performed"
403 END IF
404 END IF
405
406 ! Update the SCF DIIS buffer
407
408 IF (error_max < eps_diis) THEN
409
410 b => diis_buffer%b_matrix
411
412 DO jb = 1, nb
413 b(jb, ib) = 0.0_dp
414 DO ispin = 1, nspin
415 old_errors => diis_buffer%error(jb, ispin)
416 new_errors => diis_buffer%error(ib, ispin)
417 CALL cp_fm_trace(old_errors, new_errors, tmp)
418 b(jb, ib) = b(jb, ib) + tmp
419 END DO
420 b(ib, jb) = b(jb, ib)
421 END DO
422
423 ELSE
424
425 diis_step = .false.
426
427 END IF
428
429 ! Perform DIIS step
430
431 IF (diis_step) THEN
432
433 nb1 = nb + 1
434
435 ALLOCATE (a(nb1, nb1))
436 ALLOCATE (b(nb1, nb1))
437 ALLOCATE (ev(nb1))
438
439 ! Set up the linear DIIS equation system
440
441 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
442
443 b(1:nb, nb1) = -1.0_dp
444 b(nb1, 1:nb) = -1.0_dp
445 b(nb1, nb1) = 0.0_dp
446
447 ! Solve the linear DIIS equation system
448
449 ev(1:nb1) = 0.0_dp
450 CALL diamat_all(b(1:nb1, 1:nb1), ev(1:nb1))
451
452 a(1:nb1, 1:nb1) = b(1:nb1, 1:nb1)
453
454 eigenvectors_discarded = .false.
455
456 DO jb = 1, nb1
457 IF (abs(ev(jb)) < eigenvalue_threshold) THEN
458 IF (output_unit > 0) THEN
459 IF (.NOT. eigenvectors_discarded) THEN
460 WRITE (unit=output_unit, fmt="(T9,A)") &
461 "DIIS | Checking eigenvalues of the DIIS error matrix"
462 END IF
463 WRITE (unit=message, fmt="(T9,A,I6,A,ES10.1,A,ES10.1)") &
464 "DIIS | Eigenvalue ", jb, " = ", ev(jb), " is smaller than "// &
465 "threshold ", eigenvalue_threshold
466 CALL compress(message)
467 WRITE (unit=output_unit, fmt="(T9,A)") trim(message)
468 eigenvectors_discarded = .true.
469 END IF
470 a(1:nb1, jb) = 0.0_dp
471 ELSE
472 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
473 END IF
474 END DO
475
476 IF ((output_unit > 0) .AND. eigenvectors_discarded) THEN
477 WRITE (unit=output_unit, fmt="(T9,A,/)") &
478 "DIIS | The corresponding eigenvectors were discarded"
479 END IF
480
481 ev(1:nb) = matmul(a(1:nb, 1:nb1), b(nb1, 1:nb1))
482
483 ! Update Kohn-Sham matrix
484
485 DO ispin = 1, nspin
486 CALL cp_fm_set_all(kc(ispin), 0.0_dp)
487 DO jb = 1, nb
488 parameters => diis_buffer%param(jb, ispin)
489 CALL cp_fm_scale_and_add(1.0_dp, kc(ispin), -ev(jb), parameters)
490 END DO
491 END DO
492
493 DEALLOCATE (a)
494 DEALLOCATE (b)
495 DEALLOCATE (ev)
496
497 ELSE
498
499 DO ispin = 1, nspin
500 parameters => diis_buffer%param(ib, ispin)
501 CALL cp_fm_to_fm(parameters, kc(ispin))
502 END DO
503
504 END IF
505
506 CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
507 "PRINT%DIIS_INFO")
508
509 CALL timestop(handle)
510
511 END SUBROUTINE qs_diis_b_step
512
513! **************************************************************************************************
514!> \brief clears the buffer
515!> \param diis_buffer the buffer to clear
516!> \par History
517!> 02.2003 created [fawzi]
518!> \author fawzi
519! **************************************************************************************************
520 PURE SUBROUTINE qs_diis_b_clear(diis_buffer)
521
522 TYPE(qs_diis_buffer_type), INTENT(INOUT) :: diis_buffer
523
524 diis_buffer%ncall = 0
525
526 END SUBROUTINE qs_diis_b_clear
527
528! **************************************************************************************************
529!> \brief Update the SCF DIIS buffer in linear scaling SCF (LS-SCF),
530!> and if appropriate does a diis step.
531!> \param diis_buffer ...
532!> \param qs_env ...
533!> \param ls_scf_env ...
534!> \param unit_nr ...
535!> \param iscf ...
536!> \param diis_step ...
537!> \param eps_diis ...
538!> \param nmixing ...
539!> \param s_matrix ...
540!> \param threshold ...
541!> \par History
542!> - Adapted for LS-SCF (10-11-14) from qs_diis_b_step
543!> \author Fredy W. Aquino
544! **************************************************************************************************
545
546 SUBROUTINE qs_diis_b_step_4lscf(diis_buffer, qs_env, ls_scf_env, unit_nr, iscf, &
547 diis_step, eps_diis, nmixing, s_matrix, threshold)
548! Note.- Input: ls_scf_env%matrix_p(ispin) , Density Matrix
549! matrix_ks (from qs_env) , Kohn-Sham Matrix (IN/OUT)
550
551 TYPE(qs_diis_buffer_type_sparse), POINTER :: diis_buffer
552 TYPE(qs_environment_type), POINTER :: qs_env
553 TYPE(ls_scf_env_type) :: ls_scf_env
554 INTEGER, INTENT(IN) :: unit_nr, iscf
555 LOGICAL, INTENT(OUT) :: diis_step
556 REAL(kind=dp), INTENT(IN) :: eps_diis
557 INTEGER, INTENT(IN), OPTIONAL :: nmixing
558 TYPE(dbcsr_type), OPTIONAL :: s_matrix
559 REAL(kind=dp), INTENT(IN) :: threshold
560
561 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_diis_b_step_4lscf'
562 REAL(kind=dp), PARAMETER :: eigenvalue_threshold = 1.0e-12_dp
563
564 INTEGER :: handle, ib, ispin, jb, my_nmixing, nb, &
565 nb1, nspin
566 REAL(kind=dp) :: error_max, tmp
567 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: ev
568 REAL(kind=dp), DIMENSION(:, :), POINTER :: a, b
569 TYPE(cp_logger_type), POINTER :: logger
570 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks
571 TYPE(dbcsr_type) :: matrix_kserr_t, matrix_tmp
572 TYPE(dbcsr_type), POINTER :: new_errors, old_errors, parameters
573 TYPE(mp_para_env_type), POINTER :: para_env
574
575 CALL timeset(routinen, handle)
576 IF (ls_scf_env%do_pao) THEN
577 cpabort("LS_SCF%LS_DIIS not compatible with PAO")
578 END IF
579 nspin = ls_scf_env%nspins
580 diis_step = .false.
581 my_nmixing = 2
582 IF (PRESENT(nmixing)) my_nmixing = nmixing
583 NULLIFY (new_errors, old_errors, parameters, a, b)
584 logger => cp_get_default_logger()
585 ! Quick return, if no DIIS is requested
586 IF (diis_buffer%nbuffer < 1) THEN
587 CALL timestop(handle)
588 RETURN
589 END IF
590
591! Getting current Kohn-Sham matrix from qs_env
592 CALL get_qs_env(qs_env, &
593 para_env=para_env, &
594 matrix_ks=matrix_ks)
595 CALL qs_diis_b_check_i_alloc_sparse( &
596 diis_buffer, &
597 ls_scf_env, &
598 nspin)
599 error_max = 0.0_dp
600
601 ib = modulo(diis_buffer%ncall, diis_buffer%nbuffer) + 1
602 diis_buffer%ncall = diis_buffer%ncall + 1
603 nb = min(diis_buffer%ncall, diis_buffer%nbuffer)
604! Create scratch arrays
605 CALL dbcsr_create(matrix_tmp, &
606 template=ls_scf_env%matrix_ks(1), &
607 matrix_type='N')
608 CALL dbcsr_set(matrix_tmp, 0.0_dp) ! reset matrix
609 CALL dbcsr_create(matrix_kserr_t, &
610 template=ls_scf_env%matrix_ks(1), &
611 matrix_type='N')
612 CALL dbcsr_set(matrix_kserr_t, 0.0_dp) ! reset matrix
613
614 DO ispin = 1, nspin ! ------ Loop-ispin----START
615
616 new_errors => diis_buffer%error(ib, ispin)%matrix
617 parameters => diis_buffer%param(ib, ispin)%matrix
618 ! Copy the Kohn-Sham matrix K to the DIIS buffer
619 CALL dbcsr_copy(parameters, & ! out
620 matrix_ks(ispin)%matrix) ! in
621
622 IF (PRESENT(s_matrix)) THEN ! if-s_matrix ---------- START
623! Calculate Kohn-Sham error (non-orthogonal)= K*P*S-(K*P*S)^T
624! matrix_tmp = P*S
625 CALL dbcsr_multiply("N", "N", &
626 1.0_dp, ls_scf_env%matrix_p(ispin), &
627 s_matrix, &
628 0.0_dp, matrix_tmp, &
629 filter_eps=threshold)
630! new_errors= K*P*S
631 CALL dbcsr_multiply("N", "N", &
632 1.0_dp, matrix_ks(ispin)%matrix, &
633 matrix_tmp, &
634 0.0_dp, new_errors, &
635 filter_eps=threshold)
636! matrix_KSerr_t= transpose(K*P*S)
637 CALL dbcsr_transposed(matrix_kserr_t, &
638 new_errors)
639! new_errors=K*P*S-transpose(K*P*S)
640 CALL dbcsr_add(new_errors, &
641 matrix_kserr_t, &
642 1.0_dp, -1.0_dp)
643 ELSE ! if-s_matrix ---------- MID
644! Calculate Kohn-Sham error (orthogonal)= K*P - P*K
645! new_errors=K*P
646 CALL dbcsr_multiply("N", "N", &
647 1.0_dp, matrix_ks(ispin)%matrix, &
648 ls_scf_env%matrix_p(ispin), &
649 0.0_dp, new_errors, &
650 filter_eps=threshold)
651! matrix_KSerr_t= transpose(K*P)
652 CALL dbcsr_transposed(matrix_kserr_t, &
653 new_errors)
654! new_errors=K*P-transpose(K*P)
655 CALL dbcsr_add(new_errors, &
656 matrix_kserr_t, &
657 1.0_dp, -1.0_dp)
658 END IF ! if-s_matrix ---------- END
659
660 tmp = dbcsr_maxabs(new_errors)
661 error_max = max(error_max, tmp)
662
663 END DO ! ------ Loop-ispin----END
664
665 ! Check, if a DIIS step is appropriate
666
667 diis_step = (diis_buffer%ncall >= my_nmixing)
668
669 IF (unit_nr > 0) THEN
670 WRITE (unit_nr, '(A29,I3,A3,4(I3,A1))') &
671 "DIIS: (ncall,nbuffer,ib,nb)=(", iscf, ")=(", &
672 diis_buffer%ncall, ",", diis_buffer%nbuffer, ",", ib, ",", nb, ")"
673 WRITE (unit_nr, '(A57,I3,A3,L1,A1,F10.8,A1,F4.2,A1,L1,A1)') &
674 "DIIS: (diis_step,error_max,eps_diis,error_max<eps_diis)=(", &
675 iscf, ")=(", diis_step, ",", error_max, ",", eps_diis, ",", &
676 (error_max < eps_diis), ")"
677 WRITE (unit_nr, '(A75)') &
678 "DIIS: diis_step=T : Perform DIIS error_max<eps_diis=T : Update DIIS buffer"
679 END IF
680
681 ! Update the SCF DIIS buffer
682 IF (error_max < eps_diis) THEN
683 b => diis_buffer%b_matrix
684 DO jb = 1, nb
685 b(jb, ib) = 0.0_dp
686 DO ispin = 1, nspin
687 old_errors => diis_buffer%error(jb, ispin)%matrix
688 new_errors => diis_buffer%error(ib, ispin)%matrix
689 CALL dbcsr_dot(old_errors, &
690 new_errors, &
691 tmp) ! out : < f_i | f_j >
692 b(jb, ib) = b(jb, ib) + tmp
693 END DO ! end-loop-ispin
694 b(ib, jb) = b(jb, ib)
695 END DO ! end-loop-jb
696 ELSE
697 diis_step = .false.
698 END IF
699
700 ! Perform DIIS step
701 IF (diis_step) THEN
702 nb1 = nb + 1
703 ALLOCATE (a(nb1, nb1))
704 ALLOCATE (b(nb1, nb1))
705 ALLOCATE (ev(nb1))
706 ! Set up the linear DIIS equation system
707 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
708 b(1:nb, nb1) = -1.0_dp
709 b(nb1, 1:nb) = -1.0_dp
710 b(nb1, nb1) = 0.0_dp
711 ! Solve the linear DIIS equation system
712 CALL diamat_all(b(1:nb1, 1:nb1), ev(1:nb1))
713 a(1:nb1, 1:nb1) = b(1:nb1, 1:nb1)
714 DO jb = 1, nb1
715 IF (abs(ev(jb)) < eigenvalue_threshold) THEN
716 a(1:nb1, jb) = 0.0_dp
717 ELSE
718 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
719 END IF
720 END DO ! end-loop-jb
721
722 ev(1:nb) = matmul(a(1:nb, 1:nb1), b(nb1, 1:nb1))
723
724 ! Update Kohn-Sham matrix
725 IF (iscf >= ls_scf_env%iter_ini_diis) THEN ! if-iscf-to-updateKS------ START
726
727 IF (unit_nr > 0) THEN
728 WRITE (unit_nr, '(A40,I3)') 'DIIS: Updating Kohn-Sham matrix at iscf=', iscf
729 END IF
730
731 DO ispin = 1, nspin
732 CALL dbcsr_set(matrix_ks(ispin)%matrix, & ! reset matrix
733 0.0_dp)
734 DO jb = 1, nb
735 parameters => diis_buffer%param(jb, ispin)%matrix
736 CALL dbcsr_add(matrix_ks(ispin)%matrix, parameters, &
737 1.0_dp, -ev(jb))
738 END DO ! end-loop-jb
739 END DO ! end-loop-ispin
740 END IF ! if-iscf-to-updateKS------ END
741
742 DEALLOCATE (a)
743 DEALLOCATE (b)
744 DEALLOCATE (ev)
745
746 ELSE
747 DO ispin = 1, nspin
748 parameters => diis_buffer%param(ib, ispin)%matrix
749 CALL dbcsr_copy(parameters, & ! out
750 matrix_ks(ispin)%matrix) ! in
751 END DO ! end-loop-ispin
752 END IF
753 CALL dbcsr_release(matrix_tmp)
754 CALL dbcsr_release(matrix_kserr_t)
755 CALL timestop(handle)
756
757 END SUBROUTINE qs_diis_b_step_4lscf
758
759! **************************************************************************************************
760!> \brief Allocate and initialize a DIIS buffer with a buffer size of nbuffer.
761!> \param diis_buffer the buffer to initialize
762!> \param ls_scf_env ...
763!> \param nspin ...
764!> \par History
765!> - Adapted from qs_diis_b_check_i_alloc for sparse matrices and
766!> used in LS-SCF module (ls_scf_main) (10-11-14)
767!> \author Fredy W. Aquino
768!> \note
769!> check to allocate matrices only when needed
770! **************************************************************************************************
771
772 SUBROUTINE qs_diis_b_check_i_alloc_sparse(diis_buffer, ls_scf_env, &
773 nspin)
774
775 TYPE(qs_diis_buffer_type_sparse), INTENT(INOUT) :: diis_buffer
776 TYPE(ls_scf_env_type) :: ls_scf_env
777 INTEGER, INTENT(IN) :: nspin
778
779 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_diis_b_check_i_alloc_sparse'
780
781 INTEGER :: handle, ibuffer, ispin, nbuffer
782 TYPE(cp_logger_type), POINTER :: logger
783
784! -------------------------------------------------------------------------
785
786 CALL timeset(routinen, handle)
787
788 logger => cp_get_default_logger()
789
790 nbuffer = diis_buffer%nbuffer
791
792 IF (.NOT. ASSOCIATED(diis_buffer%error)) THEN
793 ALLOCATE (diis_buffer%error(nbuffer, nspin))
794
795 DO ispin = 1, nspin
796 DO ibuffer = 1, nbuffer
797 ALLOCATE (diis_buffer%error(ibuffer, ispin)%matrix)
798
799 CALL dbcsr_create(diis_buffer%error(ibuffer, ispin)%matrix, &
800 template=ls_scf_env%matrix_ks(1), &
801 matrix_type='N')
802 END DO
803 END DO
804 END IF
805
806 IF (.NOT. ASSOCIATED(diis_buffer%param)) THEN
807 ALLOCATE (diis_buffer%param(nbuffer, nspin))
808
809 DO ispin = 1, nspin
810 DO ibuffer = 1, nbuffer
811 ALLOCATE (diis_buffer%param(ibuffer, ispin)%matrix)
812 CALL dbcsr_create(diis_buffer%param(ibuffer, ispin)%matrix, &
813 template=ls_scf_env%matrix_ks(1), &
814 matrix_type='N')
815 END DO
816 END DO
817 END IF
818
819 IF (.NOT. ASSOCIATED(diis_buffer%b_matrix)) THEN
820 ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
821
822 diis_buffer%b_matrix = 0.0_dp
823 END IF
824
825 CALL timestop(handle)
826
827 END SUBROUTINE qs_diis_b_check_i_alloc_sparse
828
829! **************************************************************************************************
830!> \brief clears the DIIS buffer in LS-SCF calculation
831!> \param diis_buffer the buffer to clear
832!> \par History
833!> 10-11-14 created [FA] modified from qs_diis_b_clear
834!> \author Fredy W. Aquino
835! **************************************************************************************************
836
837 PURE SUBROUTINE qs_diis_b_clear_sparse(diis_buffer)
838
839 TYPE(qs_diis_buffer_type_sparse), INTENT(INOUT) :: diis_buffer
840
841 diis_buffer%ncall = 0
842
843 END SUBROUTINE qs_diis_b_clear_sparse
844
845! **************************************************************************************************
846!> \brief Allocates an SCF DIIS buffer for LS-SCF calculation
847!> \param diis_buffer the buffer to create
848!> \param nbuffer ...
849!> \par History
850!> 10-11-14 created [FA] modified from qs_diis_b_create
851!> \author Fredy W. Aquino
852! **************************************************************************************************
853 PURE SUBROUTINE qs_diis_b_create_sparse(diis_buffer, nbuffer)
854
855 TYPE(qs_diis_buffer_type_sparse), INTENT(OUT) :: diis_buffer
856 INTEGER, INTENT(in) :: nbuffer
857
858 NULLIFY (diis_buffer%b_matrix)
859 NULLIFY (diis_buffer%error)
860 NULLIFY (diis_buffer%param)
861 diis_buffer%nbuffer = nbuffer
862 diis_buffer%ncall = 0
863
864 END SUBROUTINE qs_diis_b_create_sparse
865
866! **************************************************************************************************
867!> \brief Allocates an SCF DIIS buffer for k-points
868!> \param diis_buffer the buffer to create
869!> \param nbuffer ...
870! **************************************************************************************************
871 SUBROUTINE qs_diis_b_create_kp(diis_buffer, nbuffer)
872
873 TYPE(qs_diis_buffer_type_kp), INTENT(OUT) :: diis_buffer
874 INTEGER, INTENT(in) :: nbuffer
875
876 NULLIFY (diis_buffer%b_matrix)
877 NULLIFY (diis_buffer%error)
878 NULLIFY (diis_buffer%param)
879 NULLIFY (diis_buffer%smat)
880 diis_buffer%nbuffer = nbuffer
881 diis_buffer%ncall = 0
882
883 END SUBROUTINE qs_diis_b_create_kp
884
885! **************************************************************************************************
886!> \brief Allocate and initialize a DIIS buffer for nao*nao parameter
887!> variables and with a buffer size of nbuffer, in the k-point case
888!> \param diis_buffer the buffer to initialize
889!> \param matrix_struct the structure for the matrix of the buffer note: this is in the kp subgroup
890!> \param nspin ...
891!> \param nkp ...
892!> \param scf_section ...
893! **************************************************************************************************
894 SUBROUTINE qs_diis_b_check_i_alloc_kp(diis_buffer, matrix_struct, nspin, nkp, scf_section)
895
896 TYPE(qs_diis_buffer_type_kp), INTENT(INOUT) :: diis_buffer
897 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
898 INTEGER, INTENT(IN) :: nspin, nkp
899 TYPE(section_vals_type), POINTER :: scf_section
900
901 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_diis_b_check_i_alloc_kp'
902
903 INTEGER :: handle, ibuffer, ikp, ispin, nbuffer, &
904 output_unit
905 TYPE(cp_logger_type), POINTER :: logger
906
907! -------------------------------------------------------------------------
908
909 CALL timeset(routinen, handle)
910
911 logger => cp_get_default_logger()
912
913 nbuffer = diis_buffer%nbuffer
914
915 IF (.NOT. ASSOCIATED(diis_buffer%error)) THEN
916 ALLOCATE (diis_buffer%error(nbuffer, nspin, nkp))
917
918 DO ikp = 1, nkp
919 DO ispin = 1, nspin
920 DO ibuffer = 1, nbuffer
921 CALL cp_cfm_create(diis_buffer%error(ibuffer, ispin, ikp), &
922 name="qs_diis_b%error("// &
923 trim(adjustl(cp_to_string(ibuffer)))//","// &
924 trim(adjustl(cp_to_string(ibuffer)))//")", &
925 matrix_struct=matrix_struct)
926 END DO
927 END DO
928 END DO
929 END IF
930
931 IF (.NOT. ASSOCIATED(diis_buffer%param)) THEN
932 ALLOCATE (diis_buffer%param(nbuffer, nspin, nkp))
933
934 DO ikp = 1, nkp
935 DO ispin = 1, nspin
936 DO ibuffer = 1, nbuffer
937 CALL cp_cfm_create(diis_buffer%param(ibuffer, ispin, ikp), &
938 name="qs_diis_b%param("// &
939 trim(adjustl(cp_to_string(ibuffer)))//","// &
940 trim(adjustl(cp_to_string(ibuffer)))//")", &
941 matrix_struct=matrix_struct)
942 END DO
943 END DO
944 END DO
945 END IF
946
947 IF (.NOT. ASSOCIATED(diis_buffer%smat)) THEN
948 ALLOCATE (diis_buffer%smat(nkp))
949 DO ikp = 1, nkp
950 CALL cp_cfm_create(diis_buffer%smat(ikp), &
951 name="kp_cfm_smat("// &
952 trim(adjustl(cp_to_string(ibuffer)))//","// &
953 trim(adjustl(cp_to_string(ibuffer)))//")", &
954 matrix_struct=matrix_struct)
955 END DO
956 END IF
957
958 IF (.NOT. ASSOCIATED(diis_buffer%b_matrix)) THEN
959 ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
960 diis_buffer%b_matrix = 0.0_dp
961 output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIIS_INFO", &
962 extension=".scfLog")
963 IF (output_unit > 0) THEN
964 WRITE (unit=output_unit, fmt="(/,T9,A)") &
965 "DIIS | The SCF DIIS buffer was allocated and initialized"
966 END IF
967 CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
968 "PRINT%DIIS_INFO")
969 END IF
970
971 CALL timestop(handle)
972
973 END SUBROUTINE qs_diis_b_check_i_alloc_kp
974
975! **************************************************************************************************
976!> \brief clears the buffer
977!> \param diis_buffer the buffer to clear
978! **************************************************************************************************
979 PURE SUBROUTINE qs_diis_b_clear_kp(diis_buffer)
980
981 TYPE(qs_diis_buffer_type_kp), INTENT(INOUT) :: diis_buffer
982
983 diis_buffer%ncall = 0
984
985 END SUBROUTINE qs_diis_b_clear_kp
986
987! **************************************************************************************************
988!> \brief Update info about the current buffer step ib and the current number of buffers nb
989!> \param diis_buffer ...
990!> \param ib ...
991!> \param nb ...
992! **************************************************************************************************
993 SUBROUTINE qs_diis_b_info_kp(diis_buffer, ib, nb)
994 TYPE(qs_diis_buffer_type_kp), POINTER :: diis_buffer
995 INTEGER, INTENT(OUT) :: ib, nb
996
997 ib = modulo(diis_buffer%ncall, diis_buffer%nbuffer) + 1
998 diis_buffer%ncall = diis_buffer%ncall + 1
999 nb = min(diis_buffer%ncall, diis_buffer%nbuffer)
1000
1001 END SUBROUTINE qs_diis_b_info_kp
1002
1003! **************************************************************************************************
1004!> \brief Calculate and store the error for a given k-point
1005!> \param diis_buffer ...
1006!> \param ib ...
1007!> \param mos ...
1008!> \param kc ...
1009!> \param sc ...
1010!> \param ispin ...
1011!> \param ikp ...
1012!> \param nkp_local ...
1013!> \param scf_section ...
1014!> \param real_wfn ...
1015!> \note We assume that we always have an overlap matrix.
1016!> TODO: do we need to pass the kp weight for the back Fourier transform?
1017! **************************************************************************************************
1018 SUBROUTINE qs_diis_b_calc_err_kp(diis_buffer, ib, mos, kc, sc, ispin, ikp, nkp_local, scf_section, &
1019 real_wfn)
1020 TYPE(qs_diis_buffer_type_kp), POINTER :: diis_buffer
1021 INTEGER, INTENT(IN) :: ib
1022 TYPE(mo_set_type), DIMENSION(:, :), POINTER :: mos
1023 TYPE(cp_cfm_type), INTENT(INOUT) :: kc, sc
1024 INTEGER, INTENT(IN) :: ispin, ikp, nkp_local
1025 TYPE(section_vals_type), POINTER :: scf_section
1026 LOGICAL, INTENT(IN), OPTIONAL :: real_wfn
1027
1028 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_diis_b_calc_err_kp'
1029
1030 INTEGER :: handle, homo, nao, nmo, nspin
1031 LOGICAL :: my_real_wfn
1032 REAL(dp) :: maxocc
1033 TYPE(cp_cfm_type) :: cmos
1034 TYPE(cp_cfm_type), POINTER :: new_errors, parameters, smat
1035 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
1036 TYPE(cp_fm_type), POINTER :: imos, rmos
1037
1038 NULLIFY (matrix_struct, imos, rmos, parameters, new_errors, smat)
1039
1040 CALL timeset(routinen, handle)
1041 my_real_wfn = .false.
1042 IF (PRESENT(real_wfn)) my_real_wfn = real_wfn
1043
1044 !Calculate the error for this given k-point, store the KS matrix as well as the ovlp matrix
1045 !All of this happens within the kp subgroups
1046
1047 ! Quick return, if no DIIS is requested
1048 IF (diis_buffer%nbuffer < 1) THEN
1049 CALL timestop(handle)
1050 RETURN
1051 END IF
1052 nspin = SIZE(mos, 2)
1053
1054 CALL cp_cfm_get_info(kc, matrix_struct=matrix_struct)
1055 CALL qs_diis_b_check_i_alloc_kp(diis_buffer, &
1056 matrix_struct=matrix_struct, &
1057 nspin=nspin, nkp=nkp_local, &
1058 scf_section=scf_section)
1059
1060 !We calculate: e(ikp) = F(ikp)*P(ikp)*S(ikp) - S(ikp)*P(ikp)*F(ikp)
1061 CALL get_mo_set(mos(1, ispin), nao=nao, nmo=nmo, homo=homo, mo_coeff=rmos, maxocc=maxocc)
1062 NULLIFY (matrix_struct)
1063 CALL cp_fm_get_info(rmos, matrix_struct=matrix_struct)
1064 CALL cp_cfm_create(cmos, matrix_struct)
1065 IF (my_real_wfn) THEN
1066 CALL cp_cfm_scale_and_add_fm(cmplx(0.0_dp, kind=dp), cmos, &
1067 cmplx(1.0_dp, kind=dp), rmos)
1068 ELSE
1069 CALL get_mo_set(mos(2, ispin), mo_coeff=imos)
1070 CALL cp_fm_to_cfm(rmos, imos, cmos)
1071 END IF
1072
1073 new_errors => diis_buffer%error(ib, ispin, ikp)
1074 parameters => diis_buffer%param(ib, ispin, ikp)
1075 smat => diis_buffer%smat(ikp)
1076
1077 !copy the KS and overlap matrices to the DIIS buffer
1078 CALL cp_cfm_to_cfm(kc, parameters)
1079 CALL cp_cfm_to_cfm(sc, smat)
1080
1081 ! KC <- K*C
1082 CALL parallel_gemm("N", "N", nao, homo, nao, cmplx(maxocc, kind=dp), parameters, cmos, (0.0_dp, 0.0_dp), kc)
1083 ! SC <- S*C
1084 CALL parallel_gemm("N", "N", nao, homo, nao, (2.0_dp, 0.0_dp), smat, cmos, (0.0_dp, 0.0_dp), sc)
1085
1086 ! new_errors <- KC*(SC)^T - (SC)*(KC)^T = K*P*S - S*P*K
1087 CALL parallel_gemm("N", "T", nao, nao, homo, (1.0_dp, 0.0_dp), sc, kc, (0.0_dp, 0.0_dp), new_errors)
1088 CALL parallel_gemm("N", "T", nao, nao, homo, (1.0_dp, 0.0_dp), kc, sc, (-1.0_dp, 0.0_dp), new_errors)
1089
1090 !clean-up
1091 CALL cp_cfm_release(cmos)
1092
1093 CALL timestop(handle)
1094
1095 END SUBROUTINE qs_diis_b_calc_err_kp
1096
1097! **************************************************************************************************
1098!> \brief Update the SCF DIIS buffer, and if appropriate does a diis step, for k-points
1099!> \param diis_buffer ...
1100!> \param coeffs ...
1101!> \param ib ...
1102!> \param nb ...
1103!> \param delta ...
1104!> \param error_max ...
1105!> \param diis_step ...
1106!> \param eps_diis ...
1107!> \param nspin ...
1108!> \param nkp ...
1109!> \param nkp_local ...
1110!> \param nmixing ...
1111!> \param scf_section ...
1112!> \param para_env_inter_kp communicator connecting the k-point groups
1113! **************************************************************************************************
1114 SUBROUTINE qs_diis_b_step_kp(diis_buffer, coeffs, ib, nb, delta, error_max, diis_step, eps_diis, &
1115 nspin, nkp, nkp_local, nmixing, scf_section, para_env_inter_kp)
1116
1117 TYPE(qs_diis_buffer_type_kp), POINTER :: diis_buffer
1118 COMPLEX(KIND=dp), DIMENSION(:), INTENT(INOUT) :: coeffs
1119 INTEGER, INTENT(IN) :: ib, nb
1120 REAL(kind=dp), INTENT(IN) :: delta
1121 REAL(kind=dp), INTENT(OUT) :: error_max
1122 LOGICAL, INTENT(OUT) :: diis_step
1123 REAL(kind=dp), INTENT(IN) :: eps_diis
1124 INTEGER, INTENT(IN) :: nspin, nkp, nkp_local
1125 INTEGER, INTENT(IN), OPTIONAL :: nmixing
1126 TYPE(section_vals_type), POINTER :: scf_section
1127 TYPE(mp_para_env_type), POINTER :: para_env_inter_kp
1128
1129 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_diis_b_step_kp'
1130 REAL(kind=dp), PARAMETER :: eigenvalue_threshold = 1.0e-12_dp
1131
1132 CHARACTER(LEN=2*default_string_length) :: message
1133 COMPLEX(KIND=dp) :: tmp
1134 COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: a, b
1135 INTEGER :: handle, ikp, ispin, jb, my_nmixing, nb1, &
1136 output_unit
1137 LOGICAL :: eigenvectors_discarded
1138 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: ev
1139 TYPE(cp_cfm_type) :: old_errors
1140 TYPE(cp_cfm_type), POINTER :: new_errors
1141 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
1142 TYPE(cp_fm_type) :: ierr, rerr
1143 TYPE(cp_logger_type), POINTER :: logger
1144
1145 NULLIFY (matrix_struct, new_errors, logger)
1146
1147 CALL timeset(routinen, handle)
1148
1149 diis_step = .false.
1150
1151 my_nmixing = 2
1152 IF (PRESENT(nmixing)) my_nmixing = nmixing
1153
1154 logger => cp_get_default_logger()
1155
1156 ! Quick return, if no DIIS is requested
1157 IF (diis_buffer%nbuffer < 1) THEN
1158 CALL timestop(handle)
1159 RETURN
1160 END IF
1161
1162 ! Check, if a DIIS step is appropriate
1163 diis_step = ((diis_buffer%ncall >= my_nmixing) .AND. (delta < eps_diis))
1164
1165 ! Calculate the DIIS buffer, and update it if max_error < eps_diis
1166 CALL cp_cfm_get_info(diis_buffer%error(ib, 1, 1), matrix_struct=matrix_struct)
1167 CALL cp_fm_create(ierr, matrix_struct)
1168 CALL cp_fm_create(rerr, matrix_struct)
1169 CALL cp_cfm_create(old_errors, matrix_struct)
1170 ALLOCATE (b(nb, nb))
1171 b = 0.0_dp
1172 DO jb = 1, nb
1173 DO ikp = 1, nkp_local
1174 DO ispin = 1, nspin
1175 new_errors => diis_buffer%error(ib, ispin, ikp)
1176 CALL cp_cfm_to_fm(diis_buffer%error(jb, ispin, ikp), rerr, ierr)
1177 CALL cp_fm_scale(-1.0_dp, ierr)
1178 CALL cp_fm_to_cfm(rerr, ierr, old_errors)
1179 CALL cp_cfm_trace(old_errors, new_errors, tmp)
1180 b(jb, ib) = b(jb, ib) + 1.0_dp/real(nkp, dp)*tmp
1181 END DO
1182 END DO
1183 b(ib, jb) = conjg(b(jb, ib))
1184 END DO
1185 CALL cp_fm_release(ierr)
1186 CALL cp_fm_release(rerr)
1187 CALL cp_cfm_release(old_errors)
1188 ! cp_cfm_trace has already reduced each trace over the ranks of its
1189 ! k-point group. Reduce the group contributions only once, over the
1190 ! communicator that connects the k-point groups.
1191 CALL para_env_inter_kp%sum(b)
1192
1193 error_max = sqrt(real(b(ib, ib))**2 + aimag(b(ib, ib))**2)
1194
1195 output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIIS_INFO", &
1196 extension=".scfLog")
1197 IF (output_unit > 0) THEN
1198 WRITE (unit=output_unit, fmt="(/,T9,A,I4,/,(T9,A,ES12.3))") &
1199 "DIIS | Current SCF DIIS buffer size: ", nb, &
1200 "DIIS | Maximum SCF DIIS error at last step: ", error_max, &
1201 "DIIS | Current SCF convergence: ", delta, &
1202 "DIIS | Threshold value for a DIIS step: ", eps_diis
1203 IF (error_max < eps_diis) THEN
1204 WRITE (unit=output_unit, fmt="(T9,A)") &
1205 "DIIS | => The SCF DIIS buffer will be updated"
1206 ELSE
1207 WRITE (unit=output_unit, fmt="(T9,A)") &
1208 "DIIS | => No update of the SCF DIIS buffer"
1209 END IF
1210 IF (diis_step .AND. (error_max < eps_diis)) THEN
1211 WRITE (unit=output_unit, fmt="(T9,A,/)") &
1212 "DIIS | => A SCF DIIS step will be performed"
1213 ELSE
1214 WRITE (unit=output_unit, fmt="(T9,A,/)") &
1215 "DIIS | => No SCF DIIS step will be performed"
1216 END IF
1217 END IF
1218
1219 ! Update the SCF DIIS buffer
1220 IF (error_max < eps_diis) THEN
1221 DO jb = 1, nb
1222 diis_buffer%b_matrix(ib, jb) = b(ib, jb)
1223 diis_buffer%b_matrix(jb, ib) = b(jb, ib)
1224 END DO
1225 ELSE
1226
1227 diis_step = .false.
1228 END IF
1229 DEALLOCATE (b)
1230
1231 ! Perform DIIS step
1232 IF (diis_step) THEN
1233
1234 nb1 = nb + 1
1235
1236 ALLOCATE (a(nb1, nb1))
1237 ALLOCATE (b(nb1, nb1))
1238 ALLOCATE (ev(nb1))
1239
1240 ! Set up the linear DIIS equation system
1241 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
1242
1243 b(1:nb, nb1) = -1.0_dp
1244 b(nb1, 1:nb) = -1.0_dp
1245 b(nb1, nb1) = 0.0_dp
1246
1247 ! Solve the linear DIIS equation system
1248 ev(1:nb1) = 0.0_dp !eigenvalues
1249 a(1:nb1, 1:nb1) = 0.0_dp !eigenvectors
1250 CALL diag_complex(b(1:nb1, 1:nb1), a(1:nb1, 1:nb1), ev(1:nb1))
1251 b(1:nb1, 1:nb1) = a(1:nb1, 1:nb1)
1252
1253 eigenvectors_discarded = .false.
1254
1255 DO jb = 1, nb1
1256 IF (abs(ev(jb)) < eigenvalue_threshold) THEN
1257 IF (output_unit > 0) THEN
1258 IF (.NOT. eigenvectors_discarded) THEN
1259 WRITE (unit=output_unit, fmt="(T9,A)") &
1260 "DIIS | Checking eigenvalues of the DIIS error matrix"
1261 END IF
1262 WRITE (unit=message, fmt="(T9,A,I6,A,ES10.1,A,ES10.1)") &
1263 "DIIS | Eigenvalue ", jb, " = ", ev(jb), " is smaller than "// &
1264 "threshold ", eigenvalue_threshold
1265 CALL compress(message)
1266 WRITE (unit=output_unit, fmt="(T9,A)") trim(message)
1267 eigenvectors_discarded = .true.
1268 END IF
1269 a(1:nb1, jb) = 0.0_dp
1270 ELSE
1271 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
1272 END IF
1273 END DO
1274
1275 IF ((output_unit > 0) .AND. eigenvectors_discarded) THEN
1276 WRITE (unit=output_unit, fmt="(T9,A,/)") &
1277 "DIIS | The corresponding eigenvectors were discarded"
1278 END IF
1279
1280 coeffs(1:nb) = -matmul(a(1:nb, 1:nb1), conjg(b(nb1, 1:nb1)))
1281 ELSE
1282
1283 coeffs(:) = 0.0_dp
1284 coeffs(ib) = 1.0_dp
1285 END IF
1286
1287 CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
1288 "PRINT%DIIS_INFO")
1289
1290 CALL timestop(handle)
1291
1292 END SUBROUTINE qs_diis_b_step_kp
1293END MODULE qs_diis
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_scale_and_add_fm(alpha, matrix_a, beta, matrix_b)
Scale and add two BLACS matrices (a = alpha*a + beta*b). where b is a real matrix (adapted from cp_cf...
subroutine, public cp_cfm_trace(matrix_a, matrix_b, trace)
Returns the trace of matrix_a^T matrix_b, i.e sum_{i,j}(matrix_a(i,j)*matrix_b(i,j)) .
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_fm_to_cfm(msourcer, msourcei, mtarget)
Construct a complex full matrix by taking its real and imaginary parts from two separate real-value f...
subroutine, public cp_cfm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, matrix_struct, para_env)
Returns information about a full matrix.
subroutine, public cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
subroutine, public dbcsr_transposed(transposed, normal, shallow_data_copy, transpose_distribution, use_distribution)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
real(dp) function, public dbcsr_maxabs(matrix)
Compute the maxabs norm of a dbcsr matrix.
subroutine, public dbcsr_dot(matrix_a, matrix_b, trace)
Computes the dot product of two matrices, also known as the trace of their matrix product.
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_column_scale(matrixa, scaling)
scales column i of matrix a with scaling(i)
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
subroutine, public cp_fm_scale(alpha, matrix_a)
scales a matrix matrix_a = alpha * matrix_b
subroutine, public cp_fm_symm(side, uplo, m, n, alpha, matrix_a, matrix_b, beta, matrix_c)
computes matrix_c = beta * matrix_c + alpha * matrix_a * matrix_b computes matrix_c = beta * matrix_c...
represent the structure of a full matrix
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_maxabsval(matrix, a_max, ir_max, ic_max)
find the maximum absolute value of the matrix element maxval(abs(matrix))
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
Types needed for a linear scaling quickstep SCF run based on the density matrix.
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
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
subroutine, public diag_complex(matrix, eigenvectors, eigenvalues)
Diagonalizes a local complex Hermitian matrix using LAPACK. Based on cp_cfm_heevd.
Definition mathlib.F:1878
subroutine, public diamat_all(a, eigval, dac)
Diagonalize the symmetric n by n matrix a using the LAPACK library. Only the upper triangle of matrix...
Definition mathlib.F:381
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes
buffer for the diis of the scf
Apply the direct inversion in the iterative subspace (DIIS) of Pulay in the framework of an SCF itera...
Definition qs_diis.F:21
subroutine, public qs_diis_b_info_kp(diis_buffer, ib, nb)
Update info about the current buffer step ib and the current number of buffers nb.
Definition qs_diis.F:994
pure subroutine, public qs_diis_b_create_sparse(diis_buffer, nbuffer)
Allocates an SCF DIIS buffer for LS-SCF calculation.
Definition qs_diis.F:854
pure subroutine, public qs_diis_b_clear(diis_buffer)
clears the buffer
Definition qs_diis.F:521
subroutine, public qs_diis_b_step_kp(diis_buffer, coeffs, ib, nb, delta, error_max, diis_step, eps_diis, nspin, nkp, nkp_local, nmixing, scf_section, para_env_inter_kp)
Update the SCF DIIS buffer, and if appropriate does a diis step, for k-points.
Definition qs_diis.F:1116
subroutine, public qs_diis_b_create(diis_buffer, nbuffer)
Allocates an SCF DIIS buffer.
Definition qs_diis.F:105
subroutine, public qs_diis_b_step_4lscf(diis_buffer, qs_env, ls_scf_env, unit_nr, iscf, diis_step, eps_diis, nmixing, s_matrix, threshold)
Update the SCF DIIS buffer in linear scaling SCF (LS-SCF), and if appropriate does a diis step.
Definition qs_diis.F:548
subroutine, public qs_diis_b_create_kp(diis_buffer, nbuffer)
Allocates an SCF DIIS buffer for k-points.
Definition qs_diis.F:872
subroutine, public qs_diis_b_step(diis_buffer, mo_array, kc, sc, delta, error_max, diis_step, eps_diis, nmixing, s_matrix, scf_section, roks)
Update the SCF DIIS buffer, and if appropriate does a diis step.
Definition qs_diis.F:232
pure subroutine, public qs_diis_b_clear_sparse(diis_buffer)
clears the DIIS buffer in LS-SCF calculation
Definition qs_diis.F:838
pure subroutine, public qs_diis_b_clear_kp(diis_buffer)
clears the buffer
Definition qs_diis.F:980
subroutine, public qs_diis_b_check_i_alloc_kp(diis_buffer, matrix_struct, nspin, nkp, scf_section)
Allocate and initialize a DIIS buffer for nao*nao parameter variables and with a buffer size of nbuff...
Definition qs_diis.F:895
subroutine, public qs_diis_b_calc_err_kp(diis_buffer, ib, mos, kc, sc, ispin, ikp, nkp_local, scf_section, real_wfn)
Calculate and store the error for a given k-point.
Definition qs_diis.F:1020
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, mimic, 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, sab_cneo, 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, matrix_vhxc, 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, xcint_weights, 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, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
Utilities for string manipulations.
subroutine, public compress(string, full)
Eliminate multiple space characters in a string. If full is .TRUE., then all spaces are eliminated.
Represent a complex full matrix.
keeps the information about the structure of a full matrix
represent a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment
build arrau of pointers to diis buffers in the k-point (complex full matrices) case
build array of pointers to diis buffers for sparse matrix case
keeps a buffer with the previous values of s,p,k