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