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