(git:6344619)
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
60 USE mathlib, ONLY: diag_complex,&
69 USE qs_mo_types, ONLY: get_mo_set,&
71 USE string_utilities, ONLY: compress
72#include "./base/base_uses.f90"
73
74 IMPLICIT NONE
75
76 PRIVATE
77
78 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_diis'
79
80 ! Public subroutines
81
82 PUBLIC :: qs_diis_b_clear, &
85 PUBLIC :: qs_diis_b_clear_sparse, &
88 PUBLIC :: qs_diis_b_clear_kp, &
94
95CONTAINS
96
97! **************************************************************************************************
98!> \brief Allocates an SCF DIIS buffer
99!> \param diis_buffer the buffer to create
100!> \param nbuffer ...
101!> \par History
102!> 02.2003 created [fawzi]
103!> \author fawzi
104! **************************************************************************************************
105 SUBROUTINE qs_diis_b_create(diis_buffer, nbuffer)
106
107 TYPE(qs_diis_buffer_type), INTENT(OUT) :: diis_buffer
108 INTEGER, INTENT(in) :: nbuffer
109
110 CHARACTER(len=*), PARAMETER :: routinen = 'qs_diis_b_create'
111
112 INTEGER :: handle
113
114! -------------------------------------------------------------------------
115
116 CALL timeset(routinen, handle)
117
118 NULLIFY (diis_buffer%b_matrix)
119 NULLIFY (diis_buffer%error)
120 NULLIFY (diis_buffer%param)
121 diis_buffer%nbuffer = nbuffer
122 diis_buffer%ncall = 0
123
124 CALL timestop(handle)
125
126 END SUBROUTINE qs_diis_b_create
127
128! **************************************************************************************************
129!> \brief Allocate and initialize a DIIS buffer for nao*nao parameter
130!> variables and with a buffer size of nbuffer.
131!> \param diis_buffer the buffer to initialize
132!> \param matrix_struct the structure for the matrix of the buffer
133!> \param nspin ...
134!> \param scf_section ...
135!> \par History
136!> - Creation (07.05.2001, Matthias Krack)
137!> - Changed to BLACS matrix usage (08.06.2001,MK)
138!> - DIIS for ROKS (05.04.06,MK)
139!> \author Matthias Krack
140!> \note
141!> check to allocate matrixes only when needed, using a linked list?
142! **************************************************************************************************
143 SUBROUTINE qs_diis_b_check_i_alloc(diis_buffer, matrix_struct, nspin, &
144 scf_section)
145
146 TYPE(qs_diis_buffer_type), INTENT(INOUT) :: diis_buffer
147 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
148 INTEGER, INTENT(IN) :: nspin
149 TYPE(section_vals_type), POINTER :: scf_section
150
151 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_diis_b_check_i_alloc'
152
153 INTEGER :: handle, ibuffer, ispin, nbuffer, &
154 output_unit
155 TYPE(cp_logger_type), POINTER :: logger
156
157! -------------------------------------------------------------------------
158
159 CALL timeset(routinen, handle)
160
161 logger => cp_get_default_logger()
162
163 nbuffer = diis_buffer%nbuffer
164
165 IF (.NOT. ASSOCIATED(diis_buffer%error)) THEN
166 ALLOCATE (diis_buffer%error(nbuffer, nspin))
167
168 DO ispin = 1, nspin
169 DO ibuffer = 1, nbuffer
170 CALL cp_fm_create(diis_buffer%error(ibuffer, ispin), &
171 name="qs_diis_b%error("// &
172 trim(adjustl(cp_to_string(ibuffer)))//","// &
173 trim(adjustl(cp_to_string(ibuffer)))//")", &
174 matrix_struct=matrix_struct)
175 END DO
176 END DO
177 END IF
178
179 IF (.NOT. ASSOCIATED(diis_buffer%param)) THEN
180 ALLOCATE (diis_buffer%param(nbuffer, nspin))
181
182 DO ispin = 1, nspin
183 DO ibuffer = 1, nbuffer
184 CALL cp_fm_create(diis_buffer%param(ibuffer, ispin), &
185 name="qs_diis_b%param("// &
186 trim(adjustl(cp_to_string(ibuffer)))//","// &
187 trim(adjustl(cp_to_string(ibuffer)))//")", &
188 matrix_struct=matrix_struct)
189 END DO
190 END DO
191 END IF
192
193 IF (.NOT. ASSOCIATED(diis_buffer%b_matrix)) THEN
194 ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
195 diis_buffer%b_matrix = 0.0_dp
196 output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIIS_INFO", &
197 extension=".scfLog")
198 IF (output_unit > 0) THEN
199 WRITE (unit=output_unit, fmt="(/,T9,A)") &
200 "DIIS | The SCF DIIS buffer was allocated and initialized"
201 END IF
202 CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
203 "PRINT%DIIS_INFO")
204 END IF
205
206 CALL timestop(handle)
207
208 END SUBROUTINE qs_diis_b_check_i_alloc
209
210! **************************************************************************************************
211!> \brief Update the SCF DIIS buffer, and if appropriate does a diis step.
212!> \param diis_buffer ...
213!> \param mo_array ...
214!> \param kc ...
215!> \param sc ...
216!> \param delta ...
217!> \param error_max ...
218!> \param diis_step ...
219!> \param eps_diis ...
220!> \param nmixing ...
221!> \param s_matrix ...
222!> \param scf_section ...
223!> \param roks ...
224!> \par History
225!> - Creation (07.05.2001, Matthias Krack)
226!> - Changed to BLACS matrix usage (08.06.2001, MK)
227!> - 03.2003 rewamped [fawzi]
228!> - Adapted for high-spin ROKS (08.04.06,MK)
229!> \author Matthias Krack
230! **************************************************************************************************
231 SUBROUTINE qs_diis_b_step(diis_buffer, mo_array, kc, sc, delta, error_max, &
232 diis_step, eps_diis, nmixing, s_matrix, scf_section, roks)
233
234 TYPE(qs_diis_buffer_type), POINTER :: diis_buffer
235 TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mo_array
236 TYPE(cp_fm_type), DIMENSION(:), POINTER :: kc
237 TYPE(cp_fm_type), INTENT(IN) :: sc
238 REAL(kind=dp), INTENT(IN) :: delta
239 REAL(kind=dp), INTENT(OUT) :: error_max
240 LOGICAL, INTENT(OUT) :: diis_step
241 REAL(kind=dp), INTENT(IN) :: eps_diis
242 INTEGER, INTENT(IN), OPTIONAL :: nmixing
243 TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
244 POINTER :: s_matrix
245 TYPE(section_vals_type), POINTER :: scf_section
246 LOGICAL, INTENT(IN), OPTIONAL :: roks
247
248 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_diis_b_step'
249 REAL(kind=dp), PARAMETER :: eigenvalue_threshold = 1.0e-12_dp
250
251 CHARACTER(LEN=2*default_string_length) :: message
252 INTEGER :: handle, homo, ib, imo, ispin, jb, &
253 my_nmixing, nao, nb, nb1, nmo, nspin, &
254 output_unit
255 LOGICAL :: eigenvectors_discarded, my_roks
256 REAL(kind=dp) :: maxocc, tmp
257 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: ev, occ, traces
258 REAL(kind=dp), DIMENSION(:), POINTER :: occa, occb
259 REAL(kind=dp), DIMENSION(:, :), POINTER :: a, b
260 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
261 TYPE(cp_fm_type), POINTER :: c, new_errors, parameters
262 TYPE(cp_logger_type), POINTER :: logger
263
264! -------------------------------------------------------------------------
265
266 CALL timeset(routinen, handle)
267
268 nspin = SIZE(mo_array)
269 diis_step = .false.
270
271 IF (PRESENT(roks)) THEN
272 my_roks = .true.
273 nspin = 1
274 ELSE
275 my_roks = .false.
276 END IF
277
278 my_nmixing = 2
279 IF (PRESENT(nmixing)) my_nmixing = nmixing
280
281 NULLIFY (c, new_errors, parameters, matrix_struct, a, b, occa, occb)
282 logger => cp_get_default_logger()
283
284 ! Quick return, if no DIIS is requested
285
286 IF (diis_buffer%nbuffer < 1) THEN
287 CALL timestop(handle)
288 RETURN
289 END IF
290
291 CALL cp_fm_get_info(kc(1), &
292 matrix_struct=matrix_struct)
293 CALL qs_diis_b_check_i_alloc(diis_buffer, &
294 matrix_struct=matrix_struct, &
295 nspin=nspin, &
296 scf_section=scf_section)
297
298 error_max = 0.0_dp
299
300 ib = modulo(diis_buffer%ncall, diis_buffer%nbuffer) + 1
301 diis_buffer%ncall = diis_buffer%ncall + 1
302 nb = min(diis_buffer%ncall, diis_buffer%nbuffer)
303
304 IF (PRESENT(s_matrix)) THEN
305 IF (.NOT. ALLOCATED(diis_buffer%overlap_copy_plan)) ALLOCATE (diis_buffer%overlap_copy_plan)
306 END IF
307
308 DO ispin = 1, nspin
309
310 CALL get_mo_set(mo_set=mo_array(ispin), &
311 nao=nao, &
312 nmo=nmo, &
313 homo=homo, &
314 mo_coeff=c, &
315 occupation_numbers=occa, &
316 maxocc=maxocc)
317
318 new_errors => diis_buffer%error(ib, ispin)
319 parameters => diis_buffer%param(ib, ispin)
320
321 ! Copy the Kohn-Sham matrix K to the DIIS buffer
322
323 CALL cp_fm_to_fm(kc(ispin), parameters)
324
325 IF (my_roks) THEN
326
327 ALLOCATE (occ(nmo))
328
329 CALL get_mo_set(mo_set=mo_array(2), &
330 occupation_numbers=occb)
331
332 DO imo = 1, nmo
333 occ(imo) = sqrt(occa(imo) + occb(imo))
334 END DO
335
336 CALL cp_fm_to_fm(c, sc)
337 CALL cp_fm_column_scale(sc, occ(1:homo))
338
339 ! KC <- K*C
340 CALL cp_fm_symm("L", "U", nao, homo, 1.0_dp, parameters, sc, 0.0_dp, kc(ispin))
341
342 IF (PRESENT(s_matrix)) THEN
343 CALL copy_dbcsr_to_fm(s_matrix(1)%matrix, new_errors, diis_buffer%overlap_copy_plan, check_plan=.true.)
344 ! SC <- S*C
345 CALL cp_fm_symm("L", "U", nao, homo, 1.0_dp, new_errors, c, 0.0_dp, sc)
346 CALL cp_fm_column_scale(sc, occ(1:homo))
347 END IF
348
349 ! new_errors <- KC*(SC)^T - (SC)*(KC)^T = K*P*S - S*P*K
350 ! or for an orthogonal basis
351 ! new_errors <- KC*C^T - C*(KC)^T = K*P - P*K with S = I
352 CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, sc, kc(ispin), 0.0_dp, new_errors)
353 CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, kc(ispin), sc, -1.0_dp, new_errors)
354
355 DEALLOCATE (occ)
356
357 ELSE
358
359 ! KC <- K*C
360 CALL cp_fm_symm("L", "U", nao, homo, maxocc, parameters, c, 0.0_dp, kc(ispin))
361
362 IF (PRESENT(s_matrix)) THEN
363 ! I guess that this copy can be avoided for LSD
364 CALL copy_dbcsr_to_fm(s_matrix(1)%matrix, new_errors, diis_buffer%overlap_copy_plan, check_plan=.true.)
365 ! sc <- S*C
366 CALL cp_fm_symm("L", "U", nao, homo, 2.0_dp, new_errors, c, 0.0_dp, sc)
367 ! new_errors <- KC*(SC)^T - (SC)*(KC)^T = K*P*S - S*P*K
368 CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, sc, kc(ispin), 0.0_dp, new_errors)
369 CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, kc(ispin), sc, -1.0_dp, new_errors)
370 ELSE
371 ! new_errors <- KC*(C)^T - C*(KC)^T = K*P - P*K
372 CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, c, kc(ispin), 0.0_dp, new_errors)
373 CALL parallel_gemm("N", "T", nao, nao, homo, 1.0_dp, kc(ispin), c, -1.0_dp, new_errors)
374 END IF
375
376 END IF
377
378 CALL cp_fm_maxabsval(new_errors, tmp)
379 error_max = max(error_max, tmp)
380
381 END DO
382
383 ! Check, if a DIIS step is appropriate
384
385 diis_step = ((diis_buffer%ncall >= my_nmixing) .AND. (delta < eps_diis))
386
387 output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIIS_INFO", &
388 extension=".scfLog")
389 IF (output_unit > 0) THEN
390 WRITE (unit=output_unit, fmt="(/,T9,A,I4,/,(T9,A,ES12.3))") &
391 "DIIS | Current SCF DIIS buffer size: ", nb, &
392 "DIIS | Maximum SCF DIIS error vector element:", error_max, &
393 "DIIS | Current SCF convergence: ", delta, &
394 "DIIS | Threshold value for a DIIS step: ", eps_diis
395 IF (error_max < eps_diis) THEN
396 WRITE (unit=output_unit, fmt="(T9,A)") &
397 "DIIS | => The SCF DIIS buffer will be updated"
398 ELSE
399 WRITE (unit=output_unit, fmt="(T9,A)") &
400 "DIIS | => No update of the SCF DIIS buffer"
401 END IF
402 IF (diis_step .AND. (error_max < eps_diis)) THEN
403 WRITE (unit=output_unit, fmt="(T9,A,/)") &
404 "DIIS | => A SCF DIIS step will be performed"
405 ELSE
406 WRITE (unit=output_unit, fmt="(T9,A,/)") &
407 "DIIS | => No SCF DIIS step will be performed"
408 END IF
409 END IF
410
411 ! Update the SCF DIIS buffer
412
413 IF (error_max < eps_diis) THEN
414
415 b => diis_buffer%b_matrix
416
417 ALLOCATE (traces(nb))
418 b(1:nb, ib) = 0.0_dp
419 ! Batch history traces, but avoid starting OpenMP for a single entry.
420 DO ispin = 1, nspin
421 IF (nb == 1) THEN
422 CALL cp_fm_trace(diis_buffer%error(1, ispin), diis_buffer%error(ib, ispin), traces(1))
423 ELSE
424 CALL cp_fm_trace(diis_buffer%error(1:nb, ispin), diis_buffer%error(ib, ispin), traces)
425 END IF
426 b(1:nb, ib) = b(1:nb, ib) + traces(:)
427 END DO
428 DEALLOCATE (traces)
429
430 DO jb = 1, nb
431 b(ib, jb) = b(jb, ib)
432 END DO
433
434 ELSE
435
436 diis_step = .false.
437
438 END IF
439
440 ! Perform DIIS step
441
442 IF (diis_step) THEN
443
444 nb1 = nb + 1
445
446 ALLOCATE (a(nb1, nb1))
447 ALLOCATE (b(nb1, nb1))
448 ALLOCATE (ev(nb1))
449
450 ! Set up the linear DIIS equation system
451
452 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
453
454 b(1:nb, nb1) = -1.0_dp
455 b(nb1, 1:nb) = -1.0_dp
456 b(nb1, nb1) = 0.0_dp
457
458 ! Solve the linear DIIS equation system
459
460 ev(1:nb1) = 0.0_dp
461 CALL diamat_all(b(1:nb1, 1:nb1), ev(1:nb1))
462
463 a(1:nb1, 1:nb1) = b(1:nb1, 1:nb1)
464
465 eigenvectors_discarded = .false.
466
467 DO jb = 1, nb1
468 IF (abs(ev(jb)) < eigenvalue_threshold) THEN
469 IF (output_unit > 0) THEN
470 IF (.NOT. eigenvectors_discarded) THEN
471 WRITE (unit=output_unit, fmt="(T9,A)") &
472 "DIIS | Checking eigenvalues of the DIIS error matrix"
473 END IF
474 WRITE (unit=message, fmt="(T9,A,I6,A,ES10.1,A,ES10.1)") &
475 "DIIS | Eigenvalue ", jb, " = ", ev(jb), " is smaller than "// &
476 "threshold ", eigenvalue_threshold
477 CALL compress(message)
478 WRITE (unit=output_unit, fmt="(T9,A)") trim(message)
479 eigenvectors_discarded = .true.
480 END IF
481 a(1:nb1, jb) = 0.0_dp
482 ELSE
483 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
484 END IF
485 END DO
486
487 IF ((output_unit > 0) .AND. eigenvectors_discarded) THEN
488 WRITE (unit=output_unit, fmt="(T9,A,/)") &
489 "DIIS | The corresponding eigenvectors were discarded"
490 END IF
491
492 ev(1:nb) = matmul(a(1:nb, 1:nb1), b(nb1, 1:nb1))
493
494 ! Update Kohn-Sham matrix
495
496 DO ispin = 1, nspin
497 CALL cp_fm_set_all(kc(ispin), 0.0_dp)
498 DO jb = 1, nb
499 parameters => diis_buffer%param(jb, ispin)
500 CALL cp_fm_scale_and_add(1.0_dp, kc(ispin), -ev(jb), parameters)
501 END DO
502 END DO
503
504 DEALLOCATE (a)
505 DEALLOCATE (b)
506 DEALLOCATE (ev)
507
508 ELSE
509
510 DO ispin = 1, nspin
511 parameters => diis_buffer%param(ib, ispin)
512 CALL cp_fm_to_fm(parameters, kc(ispin))
513 END DO
514
515 END IF
516
517 CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
518 "PRINT%DIIS_INFO")
519
520 CALL timestop(handle)
521
522 END SUBROUTINE qs_diis_b_step
523
524! **************************************************************************************************
525!> \brief clears the buffer
526!> \param diis_buffer the buffer to clear
527!> \par History
528!> 02.2003 created [fawzi]
529!> \author fawzi
530! **************************************************************************************************
531 PURE SUBROUTINE qs_diis_b_clear(diis_buffer)
532
533 TYPE(qs_diis_buffer_type), INTENT(INOUT) :: diis_buffer
534
535 diis_buffer%ncall = 0
536
537 END SUBROUTINE qs_diis_b_clear
538
539! **************************************************************************************************
540!> \brief Update the SCF DIIS buffer in linear scaling SCF (LS-SCF),
541!> and if appropriate does a diis step.
542!> \param diis_buffer ...
543!> \param qs_env ...
544!> \param ls_scf_env ...
545!> \param unit_nr ...
546!> \param iscf ...
547!> \param diis_step ...
548!> \param eps_diis ...
549!> \param nmixing ...
550!> \param s_matrix ...
551!> \param threshold ...
552!> \par History
553!> - Adapted for LS-SCF (10-11-14) from qs_diis_b_step
554!> \author Fredy W. Aquino
555! **************************************************************************************************
556
557 SUBROUTINE qs_diis_b_step_4lscf(diis_buffer, qs_env, ls_scf_env, unit_nr, iscf, &
558 diis_step, eps_diis, nmixing, s_matrix, threshold)
559! Note.- Input: ls_scf_env%matrix_p(ispin) , Density Matrix
560! matrix_ks (from qs_env) , Kohn-Sham Matrix (IN/OUT)
561
562 TYPE(qs_diis_buffer_type_sparse), POINTER :: diis_buffer
563 TYPE(qs_environment_type), POINTER :: qs_env
564 TYPE(ls_scf_env_type) :: ls_scf_env
565 INTEGER, INTENT(IN) :: unit_nr, iscf
566 LOGICAL, INTENT(OUT) :: diis_step
567 REAL(kind=dp), INTENT(IN) :: eps_diis
568 INTEGER, INTENT(IN), OPTIONAL :: nmixing
569 TYPE(dbcsr_type), OPTIONAL :: s_matrix
570 REAL(kind=dp), INTENT(IN) :: threshold
571
572 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_diis_b_step_4lscf'
573 REAL(kind=dp), PARAMETER :: eigenvalue_threshold = 1.0e-12_dp
574
575 INTEGER :: handle, ib, ispin, jb, my_nmixing, nb, &
576 nb1, nspin
577 REAL(kind=dp) :: error_max, tmp
578 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: ev
579 REAL(kind=dp), DIMENSION(:, :), POINTER :: a, b
580 TYPE(cp_logger_type), POINTER :: logger
581 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks
582 TYPE(dbcsr_type) :: matrix_kserr_t, matrix_tmp
583 TYPE(dbcsr_type), POINTER :: new_errors, old_errors, parameters
584 TYPE(mp_para_env_type), POINTER :: para_env
585
586 CALL timeset(routinen, handle)
587 IF (ls_scf_env%do_pao) THEN
588 cpabort("LS_SCF%LS_DIIS not compatible with PAO")
589 END IF
590 nspin = ls_scf_env%nspins
591 diis_step = .false.
592 my_nmixing = 2
593 IF (PRESENT(nmixing)) my_nmixing = nmixing
594 NULLIFY (new_errors, old_errors, parameters, a, b)
595 logger => cp_get_default_logger()
596 ! Quick return, if no DIIS is requested
597 IF (diis_buffer%nbuffer < 1) THEN
598 CALL timestop(handle)
599 RETURN
600 END IF
601
602! Getting current Kohn-Sham matrix from qs_env
603 CALL get_qs_env(qs_env, &
604 para_env=para_env, &
605 matrix_ks=matrix_ks)
606 CALL qs_diis_b_check_i_alloc_sparse( &
607 diis_buffer, &
608 ls_scf_env, &
609 nspin)
610 error_max = 0.0_dp
611
612 ib = modulo(diis_buffer%ncall, diis_buffer%nbuffer) + 1
613 diis_buffer%ncall = diis_buffer%ncall + 1
614 nb = min(diis_buffer%ncall, diis_buffer%nbuffer)
615! Create scratch arrays
616 CALL dbcsr_create(matrix_tmp, &
617 template=ls_scf_env%matrix_ks(1), &
618 matrix_type='N')
619 CALL dbcsr_set(matrix_tmp, 0.0_dp) ! reset matrix
620 CALL dbcsr_create(matrix_kserr_t, &
621 template=ls_scf_env%matrix_ks(1), &
622 matrix_type='N')
623 CALL dbcsr_set(matrix_kserr_t, 0.0_dp) ! reset matrix
624
625 DO ispin = 1, nspin ! ------ Loop-ispin----START
626
627 new_errors => diis_buffer%error(ib, ispin)%matrix
628 parameters => diis_buffer%param(ib, ispin)%matrix
629 ! Copy the Kohn-Sham matrix K to the DIIS buffer
630 CALL dbcsr_copy(parameters, & ! out
631 matrix_ks(ispin)%matrix) ! in
632
633 IF (PRESENT(s_matrix)) THEN ! if-s_matrix ---------- START
634! Calculate Kohn-Sham error (non-orthogonal)= K*P*S-(K*P*S)^T
635! matrix_tmp = P*S
636 CALL dbcsr_multiply("N", "N", &
637 1.0_dp, ls_scf_env%matrix_p(ispin), &
638 s_matrix, &
639 0.0_dp, matrix_tmp, &
640 filter_eps=threshold)
641! new_errors= K*P*S
642 CALL dbcsr_multiply("N", "N", &
643 1.0_dp, matrix_ks(ispin)%matrix, &
644 matrix_tmp, &
645 0.0_dp, new_errors, &
646 filter_eps=threshold)
647! matrix_KSerr_t= transpose(K*P*S)
648 CALL dbcsr_transposed(matrix_kserr_t, &
649 new_errors)
650! new_errors=K*P*S-transpose(K*P*S)
651 CALL dbcsr_add(new_errors, &
652 matrix_kserr_t, &
653 1.0_dp, -1.0_dp)
654 ELSE ! if-s_matrix ---------- MID
655! Calculate Kohn-Sham error (orthogonal)= K*P - P*K
656! new_errors=K*P
657 CALL dbcsr_multiply("N", "N", &
658 1.0_dp, matrix_ks(ispin)%matrix, &
659 ls_scf_env%matrix_p(ispin), &
660 0.0_dp, new_errors, &
661 filter_eps=threshold)
662! matrix_KSerr_t= transpose(K*P)
663 CALL dbcsr_transposed(matrix_kserr_t, &
664 new_errors)
665! new_errors=K*P-transpose(K*P)
666 CALL dbcsr_add(new_errors, &
667 matrix_kserr_t, &
668 1.0_dp, -1.0_dp)
669 END IF ! if-s_matrix ---------- END
670
671 tmp = dbcsr_maxabs(new_errors)
672 error_max = max(error_max, tmp)
673
674 END DO ! ------ Loop-ispin----END
675
676 ! Check, if a DIIS step is appropriate
677
678 diis_step = (diis_buffer%ncall >= my_nmixing)
679
680 IF (unit_nr > 0) THEN
681 WRITE (unit_nr, '(A29,I3,A3,4(I3,A1))') &
682 "DIIS: (ncall,nbuffer,ib,nb)=(", iscf, ")=(", &
683 diis_buffer%ncall, ",", diis_buffer%nbuffer, ",", ib, ",", nb, ")"
684 WRITE (unit_nr, '(A57,I3,A3,L1,A1,F10.8,A1,F4.2,A1,L1,A1)') &
685 "DIIS: (diis_step,error_max,eps_diis,error_max<eps_diis)=(", &
686 iscf, ")=(", diis_step, ",", error_max, ",", eps_diis, ",", &
687 (error_max < eps_diis), ")"
688 WRITE (unit_nr, '(A75)') &
689 "DIIS: diis_step=T : Perform DIIS error_max<eps_diis=T : Update DIIS buffer"
690 END IF
691
692 ! Update the SCF DIIS buffer
693 IF (error_max < eps_diis) THEN
694 b => diis_buffer%b_matrix
695 DO jb = 1, nb
696 b(jb, ib) = 0.0_dp
697 DO ispin = 1, nspin
698 old_errors => diis_buffer%error(jb, ispin)%matrix
699 new_errors => diis_buffer%error(ib, ispin)%matrix
700 CALL dbcsr_dot(old_errors, &
701 new_errors, &
702 tmp) ! out : < f_i | f_j >
703 b(jb, ib) = b(jb, ib) + tmp
704 END DO ! end-loop-ispin
705 b(ib, jb) = b(jb, ib)
706 END DO ! end-loop-jb
707 ELSE
708 diis_step = .false.
709 END IF
710
711 ! Perform DIIS step
712 IF (diis_step) THEN
713 nb1 = nb + 1
714 ALLOCATE (a(nb1, nb1))
715 ALLOCATE (b(nb1, nb1))
716 ALLOCATE (ev(nb1))
717 ! Set up the linear DIIS equation system
718 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
719 b(1:nb, nb1) = -1.0_dp
720 b(nb1, 1:nb) = -1.0_dp
721 b(nb1, nb1) = 0.0_dp
722 ! Solve the linear DIIS equation system
723 CALL diamat_all(b(1:nb1, 1:nb1), ev(1:nb1))
724 a(1:nb1, 1:nb1) = b(1:nb1, 1:nb1)
725 DO jb = 1, nb1
726 IF (abs(ev(jb)) < eigenvalue_threshold) THEN
727 a(1:nb1, jb) = 0.0_dp
728 ELSE
729 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
730 END IF
731 END DO ! end-loop-jb
732
733 ev(1:nb) = matmul(a(1:nb, 1:nb1), b(nb1, 1:nb1))
734
735 ! Update Kohn-Sham matrix
736 IF (iscf >= ls_scf_env%iter_ini_diis) THEN ! if-iscf-to-updateKS------ START
737
738 IF (unit_nr > 0) THEN
739 WRITE (unit_nr, '(A40,I3)') 'DIIS: Updating Kohn-Sham matrix at iscf=', iscf
740 END IF
741
742 DO ispin = 1, nspin
743 CALL dbcsr_set(matrix_ks(ispin)%matrix, & ! reset matrix
744 0.0_dp)
745 DO jb = 1, nb
746 parameters => diis_buffer%param(jb, ispin)%matrix
747 CALL dbcsr_add(matrix_ks(ispin)%matrix, parameters, &
748 1.0_dp, -ev(jb))
749 END DO ! end-loop-jb
750 END DO ! end-loop-ispin
751 END IF ! if-iscf-to-updateKS------ END
752
753 DEALLOCATE (a)
754 DEALLOCATE (b)
755 DEALLOCATE (ev)
756
757 ELSE
758 DO ispin = 1, nspin
759 parameters => diis_buffer%param(ib, ispin)%matrix
760 CALL dbcsr_copy(parameters, & ! out
761 matrix_ks(ispin)%matrix) ! in
762 END DO ! end-loop-ispin
763 END IF
764 CALL dbcsr_release(matrix_tmp)
765 CALL dbcsr_release(matrix_kserr_t)
766 CALL timestop(handle)
767
768 END SUBROUTINE qs_diis_b_step_4lscf
769
770! **************************************************************************************************
771!> \brief Allocate and initialize a DIIS buffer with a buffer size of nbuffer.
772!> \param diis_buffer the buffer to initialize
773!> \param ls_scf_env ...
774!> \param nspin ...
775!> \par History
776!> - Adapted from qs_diis_b_check_i_alloc for sparse matrices and
777!> used in LS-SCF module (ls_scf_main) (10-11-14)
778!> \author Fredy W. Aquino
779!> \note
780!> check to allocate matrices only when needed
781! **************************************************************************************************
782
783 SUBROUTINE qs_diis_b_check_i_alloc_sparse(diis_buffer, ls_scf_env, &
784 nspin)
785
786 TYPE(qs_diis_buffer_type_sparse), INTENT(INOUT) :: diis_buffer
787 TYPE(ls_scf_env_type) :: ls_scf_env
788 INTEGER, INTENT(IN) :: nspin
789
790 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_diis_b_check_i_alloc_sparse'
791
792 INTEGER :: handle, ibuffer, ispin, nbuffer
793 TYPE(cp_logger_type), POINTER :: logger
794
795! -------------------------------------------------------------------------
796
797 CALL timeset(routinen, handle)
798
799 logger => cp_get_default_logger()
800
801 nbuffer = diis_buffer%nbuffer
802
803 IF (.NOT. ASSOCIATED(diis_buffer%error)) THEN
804 ALLOCATE (diis_buffer%error(nbuffer, nspin))
805
806 DO ispin = 1, nspin
807 DO ibuffer = 1, nbuffer
808 ALLOCATE (diis_buffer%error(ibuffer, ispin)%matrix)
809
810 CALL dbcsr_create(diis_buffer%error(ibuffer, ispin)%matrix, &
811 template=ls_scf_env%matrix_ks(1), &
812 matrix_type='N')
813 END DO
814 END DO
815 END IF
816
817 IF (.NOT. ASSOCIATED(diis_buffer%param)) THEN
818 ALLOCATE (diis_buffer%param(nbuffer, nspin))
819
820 DO ispin = 1, nspin
821 DO ibuffer = 1, nbuffer
822 ALLOCATE (diis_buffer%param(ibuffer, ispin)%matrix)
823 CALL dbcsr_create(diis_buffer%param(ibuffer, ispin)%matrix, &
824 template=ls_scf_env%matrix_ks(1), &
825 matrix_type='N')
826 END DO
827 END DO
828 END IF
829
830 IF (.NOT. ASSOCIATED(diis_buffer%b_matrix)) THEN
831 ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
832
833 diis_buffer%b_matrix = 0.0_dp
834 END IF
835
836 CALL timestop(handle)
837
838 END SUBROUTINE qs_diis_b_check_i_alloc_sparse
839
840! **************************************************************************************************
841!> \brief clears the DIIS buffer in LS-SCF calculation
842!> \param diis_buffer the buffer to clear
843!> \par History
844!> 10-11-14 created [FA] modified from qs_diis_b_clear
845!> \author Fredy W. Aquino
846! **************************************************************************************************
847
848 PURE SUBROUTINE qs_diis_b_clear_sparse(diis_buffer)
849
850 TYPE(qs_diis_buffer_type_sparse), INTENT(INOUT) :: diis_buffer
851
852 diis_buffer%ncall = 0
853
854 END SUBROUTINE qs_diis_b_clear_sparse
855
856! **************************************************************************************************
857!> \brief Allocates an SCF DIIS buffer for LS-SCF calculation
858!> \param diis_buffer the buffer to create
859!> \param nbuffer ...
860!> \par History
861!> 10-11-14 created [FA] modified from qs_diis_b_create
862!> \author Fredy W. Aquino
863! **************************************************************************************************
864 PURE SUBROUTINE qs_diis_b_create_sparse(diis_buffer, nbuffer)
865
866 TYPE(qs_diis_buffer_type_sparse), INTENT(OUT) :: diis_buffer
867 INTEGER, INTENT(in) :: nbuffer
868
869 NULLIFY (diis_buffer%b_matrix)
870 NULLIFY (diis_buffer%error)
871 NULLIFY (diis_buffer%param)
872 diis_buffer%nbuffer = nbuffer
873 diis_buffer%ncall = 0
874
875 END SUBROUTINE qs_diis_b_create_sparse
876
877! **************************************************************************************************
878!> \brief Allocates an SCF DIIS buffer for k-points
879!> \param diis_buffer the buffer to create
880!> \param nbuffer ...
881! **************************************************************************************************
882 SUBROUTINE qs_diis_b_create_kp(diis_buffer, nbuffer)
883
884 TYPE(qs_diis_buffer_type_kp), INTENT(OUT) :: diis_buffer
885 INTEGER, INTENT(in) :: nbuffer
886
887 NULLIFY (diis_buffer%b_matrix)
888 NULLIFY (diis_buffer%error)
889 NULLIFY (diis_buffer%param)
890 NULLIFY (diis_buffer%smat)
891 diis_buffer%nbuffer = nbuffer
892 diis_buffer%ncall = 0
893
894 END SUBROUTINE qs_diis_b_create_kp
895
896! **************************************************************************************************
897!> \brief Allocate and initialize a DIIS buffer for nao*nao parameter
898!> variables and with a buffer size of nbuffer, in the k-point case
899!> \param diis_buffer the buffer to initialize
900!> \param matrix_struct the structure for the matrix of the buffer note: this is in the kp subgroup
901!> \param nspin ...
902!> \param nkp ...
903!> \param scf_section ...
904! **************************************************************************************************
905 SUBROUTINE qs_diis_b_check_i_alloc_kp(diis_buffer, matrix_struct, nspin, nkp, scf_section)
906
907 TYPE(qs_diis_buffer_type_kp), INTENT(INOUT) :: diis_buffer
908 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
909 INTEGER, INTENT(IN) :: nspin, nkp
910 TYPE(section_vals_type), POINTER :: scf_section
911
912 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_diis_b_check_i_alloc_kp'
913
914 INTEGER :: handle, ibuffer, ikp, ispin, nbuffer, &
915 output_unit
916 TYPE(cp_logger_type), POINTER :: logger
917
918! -------------------------------------------------------------------------
919
920 CALL timeset(routinen, handle)
921
922 logger => cp_get_default_logger()
923
924 nbuffer = diis_buffer%nbuffer
925
926 IF (.NOT. ASSOCIATED(diis_buffer%error)) THEN
927 ALLOCATE (diis_buffer%error(nbuffer, nspin, nkp))
928
929 DO ikp = 1, nkp
930 DO ispin = 1, nspin
931 DO ibuffer = 1, nbuffer
932 CALL cp_cfm_create(diis_buffer%error(ibuffer, ispin, ikp), &
933 name="qs_diis_b%error("// &
934 trim(adjustl(cp_to_string(ibuffer)))//","// &
935 trim(adjustl(cp_to_string(ibuffer)))//")", &
936 matrix_struct=matrix_struct)
937 END DO
938 END DO
939 END DO
940 END IF
941
942 IF (.NOT. ASSOCIATED(diis_buffer%param)) THEN
943 ALLOCATE (diis_buffer%param(nbuffer, nspin, nkp))
944
945 DO ikp = 1, nkp
946 DO ispin = 1, nspin
947 DO ibuffer = 1, nbuffer
948 CALL cp_cfm_create(diis_buffer%param(ibuffer, ispin, ikp), &
949 name="qs_diis_b%param("// &
950 trim(adjustl(cp_to_string(ibuffer)))//","// &
951 trim(adjustl(cp_to_string(ibuffer)))//")", &
952 matrix_struct=matrix_struct)
953 END DO
954 END DO
955 END DO
956 END IF
957
958 IF (.NOT. ASSOCIATED(diis_buffer%smat)) THEN
959 ALLOCATE (diis_buffer%smat(nkp))
960 DO ikp = 1, nkp
961 CALL cp_cfm_create(diis_buffer%smat(ikp), &
962 name="kp_cfm_smat("//trim(cp_to_string(ikp))//")", &
963 matrix_struct=matrix_struct)
964 END DO
965 END IF
966
967 IF (.NOT. ASSOCIATED(diis_buffer%b_matrix)) THEN
968 ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
969 diis_buffer%b_matrix = 0.0_dp
970 output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIIS_INFO", &
971 extension=".scfLog")
972 IF (output_unit > 0) THEN
973 WRITE (unit=output_unit, fmt="(/,T9,A)") &
974 "DIIS | The SCF DIIS buffer was allocated and initialized"
975 END IF
976 CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
977 "PRINT%DIIS_INFO")
978 END IF
979
980 CALL timestop(handle)
981
982 END SUBROUTINE qs_diis_b_check_i_alloc_kp
983
984! **************************************************************************************************
985!> \brief clears the buffer
986!> \param diis_buffer the buffer to clear
987! **************************************************************************************************
988 PURE SUBROUTINE qs_diis_b_clear_kp(diis_buffer)
989
990 TYPE(qs_diis_buffer_type_kp), INTENT(INOUT) :: diis_buffer
991
992 diis_buffer%ncall = 0
993
994 END SUBROUTINE qs_diis_b_clear_kp
995
996! **************************************************************************************************
997!> \brief Update info about the current buffer step ib and the current number of buffers nb
998!> \param diis_buffer ...
999!> \param ib ...
1000!> \param nb ...
1001! **************************************************************************************************
1002 SUBROUTINE qs_diis_b_info_kp(diis_buffer, ib, nb)
1003 TYPE(qs_diis_buffer_type_kp), POINTER :: diis_buffer
1004 INTEGER, INTENT(OUT) :: ib, nb
1005
1006 ib = modulo(diis_buffer%ncall, diis_buffer%nbuffer) + 1
1007 diis_buffer%ncall = diis_buffer%ncall + 1
1008 nb = min(diis_buffer%ncall, diis_buffer%nbuffer)
1009
1010 END SUBROUTINE qs_diis_b_info_kp
1011
1012! **************************************************************************************************
1013!> \brief Calculate and store the error for a given k-point
1014!> \param diis_buffer ...
1015!> \param ib ...
1016!> \param mos ...
1017!> \param kc ...
1018!> \param sc ...
1019!> \param ispin ...
1020!> \param ikp ...
1021!> \param cmos caller-owned scratch; the controller preallocates it and the DIIS buffer
1022!> \param real_wfn ...
1023!> \param local use local GEMM on a one-rank k-point group
1024!> \param gemm_ctx private local GEMM context, unused for distributed groups
1025!> \note We assume that we always have an overlap matrix.
1026!> TODO: do we need to pass the kp weight for the back Fourier transform?
1027! **************************************************************************************************
1028 SUBROUTINE qs_diis_b_calc_err_kp(diis_buffer, ib, mos, kc, sc, ispin, ikp, cmos, real_wfn, local, gemm_ctx)
1029 TYPE(qs_diis_buffer_type_kp), POINTER :: diis_buffer
1030 INTEGER, INTENT(IN) :: ib
1031 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
1032 TYPE(cp_cfm_type), INTENT(INOUT) :: kc, sc
1033 INTEGER, INTENT(IN) :: ispin, ikp
1034 TYPE(cp_cfm_type), INTENT(INOUT) :: cmos
1035 LOGICAL, INTENT(IN), OPTIONAL :: real_wfn, local
1036 TYPE(local_gemm_ctxt_type), INTENT(INOUT) :: gemm_ctx
1037
1038 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_diis_b_calc_err_kp'
1039
1040 INTEGER :: handle, homo, nao
1041 LOGICAL :: my_real_wfn
1042 REAL(dp) :: maxocc
1043 TYPE(cp_cfm_type), POINTER :: new_errors, parameters, smat
1044 TYPE(cp_fm_type), POINTER :: rmos
1045
1046 NULLIFY (rmos, parameters, new_errors, smat)
1047
1048 CALL timeset(routinen, handle)
1049 my_real_wfn = .false.
1050 IF (PRESENT(real_wfn)) my_real_wfn = real_wfn
1051
1052 !Calculate the error for this given k-point, store the KS matrix as well as the ovlp matrix
1053 !All of this happens within the kp subgroups
1054
1055 ! Quick return, if no DIIS is requested
1056 IF (diis_buffer%nbuffer < 1) THEN
1057 CALL timestop(handle)
1058 RETURN
1059 END IF
1060 CALL get_mo_set(mos(ispin), nao=nao, homo=homo, maxocc=maxocc)
1061
1062 IF (my_real_wfn) THEN
1063 CALL get_mo_set(mos(ispin), mo_coeff=rmos)
1064 CALL cp_cfm_scale_and_add_fm(cmplx(0.0_dp, kind=dp), cmos, &
1065 cmplx(1.0_dp, kind=dp), rmos)
1066 ELSE
1067 CALL cp_cfm_to_cfm(mos(ispin)%cmo_coeff, cmos)
1068 END IF
1069
1070 new_errors => diis_buffer%error(ib, ispin, ikp)
1071 parameters => diis_buffer%param(ib, ispin, ikp)
1072 smat => diis_buffer%smat(ikp)
1073
1074 !copy the KS and overlap matrices to the DIIS buffer
1075 CALL cp_cfm_to_cfm(kc, parameters)
1076 CALL cp_cfm_to_cfm(sc, smat)
1077
1078 ! KC <- K*C; SC <- S*C. Retain the existing factor of two in SC.
1079 ! new_errors <- KC*(SC)^H - SC*(KC)^H.
1080 IF (local) THEN
1081 cpassert(product(parameters%matrix_struct%context%num_pe) == 1)
1082 cpassert(product(cmos%matrix_struct%context%num_pe) == 1)
1083 cpassert(product(kc%matrix_struct%context%num_pe) == 1)
1084 cpassert(product(smat%matrix_struct%context%num_pe) == 1)
1085 cpassert(product(sc%matrix_struct%context%num_pe) == 1)
1086 cpassert(product(new_errors%matrix_struct%context%num_pe) == 1)
1087 CALL gemm_ctx%gemm("N", "N", nao, homo, nao, cmplx(maxocc, kind=dp), &
1088 parameters%local_data, SIZE(parameters%local_data, 1), &
1089 cmos%local_data, SIZE(cmos%local_data, 1), (0.0_dp, 0.0_dp), &
1090 kc%local_data, SIZE(kc%local_data, 1))
1091 CALL gemm_ctx%gemm("N", "N", nao, homo, nao, (2.0_dp, 0.0_dp), &
1092 smat%local_data, SIZE(smat%local_data, 1), &
1093 cmos%local_data, SIZE(cmos%local_data, 1), (0.0_dp, 0.0_dp), &
1094 sc%local_data, SIZE(sc%local_data, 1))
1095 CALL gemm_ctx%gemm("N", "C", nao, nao, homo, (1.0_dp, 0.0_dp), &
1096 sc%local_data, SIZE(sc%local_data, 1), &
1097 kc%local_data, SIZE(kc%local_data, 1), (0.0_dp, 0.0_dp), &
1098 new_errors%local_data, SIZE(new_errors%local_data, 1))
1099 CALL gemm_ctx%gemm("N", "C", nao, nao, homo, (1.0_dp, 0.0_dp), &
1100 kc%local_data, SIZE(kc%local_data, 1), &
1101 sc%local_data, SIZE(sc%local_data, 1), (-1.0_dp, 0.0_dp), &
1102 new_errors%local_data, SIZE(new_errors%local_data, 1))
1103 ELSE
1104 CALL parallel_gemm("N", "N", nao, homo, nao, cmplx(maxocc, kind=dp), parameters, cmos, (0.0_dp, 0.0_dp), kc)
1105 CALL parallel_gemm("N", "N", nao, homo, nao, (2.0_dp, 0.0_dp), smat, cmos, (0.0_dp, 0.0_dp), sc)
1106 CALL parallel_gemm("N", "C", nao, nao, homo, (1.0_dp, 0.0_dp), sc, kc, (0.0_dp, 0.0_dp), new_errors)
1107 CALL parallel_gemm("N", "C", nao, nao, homo, (1.0_dp, 0.0_dp), kc, sc, (-1.0_dp, 0.0_dp), new_errors)
1108 END IF
1109
1110 CALL timestop(handle)
1111
1112 END SUBROUTINE qs_diis_b_calc_err_kp
1113
1114! **************************************************************************************************
1115!> \brief Update the SCF DIIS buffer, and if appropriate does a diis step, for k-points
1116!> \param diis_buffer ...
1117!> \param coeffs ...
1118!> \param ib ...
1119!> \param nb ...
1120!> \param delta ...
1121!> \param error_max ...
1122!> \param diis_step ...
1123!> \param eps_diis ...
1124!> \param nspin ...
1125!> \param nkp ...
1126!> \param nkp_local ...
1127!> \param nmixing ...
1128!> \param scf_section ...
1129!> \param para_env_inter_kp communicator connecting the k-point groups
1130! **************************************************************************************************
1131 SUBROUTINE qs_diis_b_step_kp(diis_buffer, coeffs, ib, nb, delta, error_max, diis_step, eps_diis, &
1132 nspin, nkp, nkp_local, nmixing, scf_section, para_env_inter_kp)
1133
1134 TYPE(qs_diis_buffer_type_kp), POINTER :: diis_buffer
1135 COMPLEX(KIND=dp), DIMENSION(:), INTENT(INOUT) :: coeffs
1136 INTEGER, INTENT(IN) :: ib, nb
1137 REAL(kind=dp), INTENT(IN) :: delta
1138 REAL(kind=dp), INTENT(OUT) :: error_max
1139 LOGICAL, INTENT(OUT) :: diis_step
1140 REAL(kind=dp), INTENT(IN) :: eps_diis
1141 INTEGER, INTENT(IN) :: nspin, nkp, nkp_local
1142 INTEGER, INTENT(IN), OPTIONAL :: nmixing
1143 TYPE(section_vals_type), POINTER :: scf_section
1144 TYPE(mp_para_env_type), POINTER :: para_env_inter_kp
1145
1146 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_diis_b_step_kp'
1147 REAL(kind=dp), PARAMETER :: eigenvalue_threshold = 1.0e-12_dp
1148
1149 CHARACTER(LEN=2*default_string_length) :: message
1150 COMPLEX(KIND=dp) :: tmp
1151 COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: a, b
1152 INTEGER :: handle, ikp, ispin, jb, my_nmixing, nb1, &
1153 output_unit
1154 LOGICAL :: eigenvectors_discarded
1155 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: ev
1156 TYPE(cp_cfm_type) :: old_errors
1157 TYPE(cp_cfm_type), POINTER :: new_errors
1158 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
1159 TYPE(cp_fm_type) :: ierr, rerr
1160 TYPE(cp_logger_type), POINTER :: logger
1161
1162 NULLIFY (matrix_struct, new_errors, logger)
1163
1164 CALL timeset(routinen, handle)
1165
1166 diis_step = .false.
1167
1168 my_nmixing = 2
1169 IF (PRESENT(nmixing)) my_nmixing = nmixing
1170
1171 logger => cp_get_default_logger()
1172
1173 ! Quick return, if no DIIS is requested
1174 IF (diis_buffer%nbuffer < 1) THEN
1175 CALL timestop(handle)
1176 RETURN
1177 END IF
1178
1179 ! Check, if a DIIS step is appropriate
1180 diis_step = ((diis_buffer%ncall >= my_nmixing) .AND. (delta < eps_diis))
1181
1182 ! Calculate the DIIS buffer, and update it if max_error < eps_diis
1183 CALL cp_cfm_get_info(diis_buffer%error(ib, 1, 1), matrix_struct=matrix_struct)
1184 CALL cp_fm_create(ierr, matrix_struct)
1185 CALL cp_fm_create(rerr, matrix_struct)
1186 CALL cp_cfm_create(old_errors, matrix_struct)
1187 ALLOCATE (b(nb, nb))
1188 b = 0.0_dp
1189 DO jb = 1, nb
1190 DO ikp = 1, nkp_local
1191 DO ispin = 1, nspin
1192 new_errors => diis_buffer%error(ib, ispin, ikp)
1193 CALL cp_cfm_to_fm(diis_buffer%error(jb, ispin, ikp), rerr, ierr)
1194 CALL cp_fm_scale(-1.0_dp, ierr)
1195 CALL cp_fm_to_cfm(rerr, ierr, old_errors)
1196 CALL cp_cfm_trace(old_errors, new_errors, tmp)
1197 b(jb, ib) = b(jb, ib) + 1.0_dp/real(nkp, dp)*tmp
1198 END DO
1199 END DO
1200 b(ib, jb) = conjg(b(jb, ib))
1201 END DO
1202 CALL cp_fm_release(ierr)
1203 CALL cp_fm_release(rerr)
1204 CALL cp_cfm_release(old_errors)
1205 ! cp_cfm_trace has already reduced each trace over the ranks of its
1206 ! k-point group. Reduce the group contributions only once, over the
1207 ! communicator that connects the k-point groups.
1208 CALL para_env_inter_kp%sum(b)
1209
1210 error_max = sqrt(real(b(ib, ib))**2 + aimag(b(ib, ib))**2)
1211
1212 output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIIS_INFO", &
1213 extension=".scfLog")
1214 IF (output_unit > 0) THEN
1215 WRITE (unit=output_unit, fmt="(/,T9,A,I4,/,(T9,A,ES12.3))") &
1216 "DIIS | Current SCF DIIS buffer size: ", nb, &
1217 "DIIS | Maximum SCF DIIS error at last step: ", error_max, &
1218 "DIIS | Current SCF convergence: ", delta, &
1219 "DIIS | Threshold value for a DIIS step: ", eps_diis
1220 IF (error_max < eps_diis) THEN
1221 WRITE (unit=output_unit, fmt="(T9,A)") &
1222 "DIIS | => The SCF DIIS buffer will be updated"
1223 ELSE
1224 WRITE (unit=output_unit, fmt="(T9,A)") &
1225 "DIIS | => No update of the SCF DIIS buffer"
1226 END IF
1227 IF (diis_step .AND. (error_max < eps_diis)) THEN
1228 WRITE (unit=output_unit, fmt="(T9,A,/)") &
1229 "DIIS | => A SCF DIIS step will be performed"
1230 ELSE
1231 WRITE (unit=output_unit, fmt="(T9,A,/)") &
1232 "DIIS | => No SCF DIIS step will be performed"
1233 END IF
1234 END IF
1235
1236 ! Update the SCF DIIS buffer
1237 IF (error_max < eps_diis) THEN
1238 DO jb = 1, nb
1239 diis_buffer%b_matrix(ib, jb) = b(ib, jb)
1240 diis_buffer%b_matrix(jb, ib) = b(jb, ib)
1241 END DO
1242 ELSE
1243
1244 diis_step = .false.
1245 END IF
1246 DEALLOCATE (b)
1247
1248 ! Perform DIIS step
1249 IF (diis_step) THEN
1250
1251 nb1 = nb + 1
1252
1253 ALLOCATE (a(nb1, nb1))
1254 ALLOCATE (b(nb1, nb1))
1255 ALLOCATE (ev(nb1))
1256
1257 ! Set up the linear DIIS equation system
1258 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
1259
1260 b(1:nb, nb1) = -1.0_dp
1261 b(nb1, 1:nb) = -1.0_dp
1262 b(nb1, nb1) = 0.0_dp
1263
1264 ! Solve the linear DIIS equation system
1265 ev(1:nb1) = 0.0_dp !eigenvalues
1266 a(1:nb1, 1:nb1) = 0.0_dp !eigenvectors
1267 CALL diag_complex(b(1:nb1, 1:nb1), a(1:nb1, 1:nb1), ev(1:nb1))
1268 b(1:nb1, 1:nb1) = a(1:nb1, 1:nb1)
1269
1270 eigenvectors_discarded = .false.
1271
1272 DO jb = 1, nb1
1273 IF (abs(ev(jb)) < eigenvalue_threshold) THEN
1274 IF (output_unit > 0) THEN
1275 IF (.NOT. eigenvectors_discarded) THEN
1276 WRITE (unit=output_unit, fmt="(T9,A)") &
1277 "DIIS | Checking eigenvalues of the DIIS error matrix"
1278 END IF
1279 WRITE (unit=message, fmt="(T9,A,I6,A,ES10.1,A,ES10.1)") &
1280 "DIIS | Eigenvalue ", jb, " = ", ev(jb), " is smaller than "// &
1281 "threshold ", eigenvalue_threshold
1282 CALL compress(message)
1283 WRITE (unit=output_unit, fmt="(T9,A)") trim(message)
1284 eigenvectors_discarded = .true.
1285 END IF
1286 a(1:nb1, jb) = 0.0_dp
1287 ELSE
1288 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
1289 END IF
1290 END DO
1291
1292 IF ((output_unit > 0) .AND. eigenvectors_discarded) THEN
1293 WRITE (unit=output_unit, fmt="(T9,A,/)") &
1294 "DIIS | The corresponding eigenvectors were discarded"
1295 END IF
1296
1297 coeffs(1:nb) = -matmul(a(1:nb, 1:nb1), conjg(b(nb1, 1:nb1)))
1298 ELSE
1299
1300 coeffs(:) = 0.0_dp
1301 coeffs(ib) = 1.0_dp
1302 END IF
1303
1304 CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
1305 "PRINT%DIIS_INFO")
1306
1307 CALL timestop(handle)
1308
1309 END SUBROUTINE qs_diis_b_step_kp
1310END 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, plan, check_plan)
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:1907
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:1003
pure subroutine, public qs_diis_b_create_sparse(diis_buffer, nbuffer)
Allocates an SCF DIIS buffer for LS-SCF calculation.
Definition qs_diis.F:865
subroutine, public qs_diis_b_calc_err_kp(diis_buffer, ib, mos, kc, sc, ispin, ikp, cmos, real_wfn, local, gemm_ctx)
Calculate and store the error for a given k-point.
Definition qs_diis.F:1029
pure subroutine, public qs_diis_b_clear(diis_buffer)
clears the buffer
Definition qs_diis.F:532
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:1133
subroutine, public qs_diis_b_create(diis_buffer, nbuffer)
Allocates an SCF DIIS buffer.
Definition qs_diis.F:106
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:559
subroutine, public qs_diis_b_create_kp(diis_buffer, nbuffer)
Allocates an SCF DIIS buffer for k-points.
Definition qs_diis.F:883
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:233
pure subroutine, public qs_diis_b_clear_sparse(diis_buffer)
clears the DIIS buffer in LS-SCF calculation
Definition qs_diis.F:849
pure subroutine, public qs_diis_b_clear_kp(diis_buffer)
clears the buffer
Definition qs_diis.F:989
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:906
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, cmo_coeff)
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