(git:374b731)
Loading...
Searching...
No Matches
dm_ls_scf.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Routines for a linear scaling quickstep SCF run based on the density
10!> matrix
11!> \par History
12!> 2010.10 created [Joost VandeVondele]
13!> \author Joost VandeVondele
14! **************************************************************************************************
17 USE bibliography, ONLY: kolafa2004,&
18 kuhne2007,&
19 cite_reference
25 USE dbcsr_api, ONLY: &
26 dbcsr_add, dbcsr_binary_read, dbcsr_binary_write, dbcsr_checksum, dbcsr_copy, &
27 dbcsr_create, dbcsr_distribution_type, dbcsr_filter, dbcsr_get_info, dbcsr_get_occupation, &
28 dbcsr_multiply, dbcsr_p_type, dbcsr_release, dbcsr_scale, dbcsr_set, dbcsr_type, &
29 dbcsr_type_no_symmetry
40 USE dm_ls_scf_qs, ONLY: ls_scf_dm_to_ks,&
57 USE kinds, ONLY: default_path_length,&
59 dp
60 USE machine, ONLY: m_flush,&
62 USE mathlib, ONLY: binomial
87#include "./base/base_uses.f90"
88
89 IMPLICIT NONE
90
91 PRIVATE
92
93 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'dm_ls_scf'
94
96
97CONTAINS
98
99! **************************************************************************************************
100!> \brief perform an linear scaling scf procedure: entry point
101!>
102!> \param qs_env ...
103!> \par History
104!> 2010.10 created [Joost VandeVondele]
105!> \author Joost VandeVondele
106! **************************************************************************************************
107 SUBROUTINE ls_scf(qs_env)
108 TYPE(qs_environment_type), POINTER :: qs_env
109
110 CHARACTER(len=*), PARAMETER :: routinen = 'ls_scf'
111
112 INTEGER :: handle
113 LOGICAL :: pao_is_done
114 TYPE(ls_scf_env_type), POINTER :: ls_scf_env
115
116 CALL timeset(routinen, handle)
117 CALL get_qs_env(qs_env, ls_scf_env=ls_scf_env)
118 CALL pao_optimization_start(qs_env, ls_scf_env)
119
120 pao_is_done = .false.
121 DO WHILE (.NOT. pao_is_done)
122 CALL ls_scf_init_scf(qs_env, ls_scf_env)
123 CALL pao_update(qs_env, ls_scf_env, pao_is_done)
124 CALL ls_scf_main(qs_env, ls_scf_env)
125 CALL pao_post_scf(qs_env, ls_scf_env, pao_is_done)
126 CALL ls_scf_post(qs_env, ls_scf_env)
127 END DO
128
129 CALL pao_optimization_end(ls_scf_env)
130
131 CALL timestop(handle)
132
133 END SUBROUTINE ls_scf
134
135! **************************************************************************************************
136!> \brief initialization needed for scf
137!> \param qs_env ...
138!> \param ls_scf_env ...
139!> \par History
140!> 2010.10 created [Joost VandeVondele]
141!> \author Joost VandeVondele
142! **************************************************************************************************
143 SUBROUTINE ls_scf_init_scf(qs_env, ls_scf_env)
144 TYPE(qs_environment_type), POINTER :: qs_env
145 TYPE(ls_scf_env_type) :: ls_scf_env
146
147 CHARACTER(len=*), PARAMETER :: routinen = 'ls_scf_init_scf'
148
149 INTEGER :: handle, ispin, nspin, unit_nr
150 TYPE(cp_logger_type), POINTER :: logger
151 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s, matrix_w
152 TYPE(dft_control_type), POINTER :: dft_control
153 TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
154 TYPE(qs_ks_env_type), POINTER :: ks_env
155 TYPE(section_vals_type), POINTER :: input
156
157 CALL timeset(routinen, handle)
158
159 ! get a useful output_unit
160 logger => cp_get_default_logger()
161 IF (logger%para_env%is_source()) THEN
162 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
163 ELSE
164 unit_nr = -1
165 END IF
166
167 ! get basic quantities from the qs_env
168 CALL get_qs_env(qs_env, nelectron_total=ls_scf_env%nelectron_total, &
169 matrix_s=matrix_s, &
170 matrix_w=matrix_w, &
171 ks_env=ks_env, &
172 dft_control=dft_control, &
173 molecule_set=molecule_set, &
174 input=input, &
175 has_unit_metric=ls_scf_env%has_unit_metric, &
176 para_env=ls_scf_env%para_env, &
177 nelectron_spin=ls_scf_env%nelectron_spin)
178
179 ! needs forces ? There might be a better way to flag this
180 ls_scf_env%calculate_forces = ASSOCIATED(matrix_w)
181
182 ! some basic initialization of the QS side of things
183 CALL ls_scf_init_qs(qs_env)
184
185 ! create the matrix template for use in the ls procedures
186 CALL matrix_ls_create(matrix_ls=ls_scf_env%matrix_s, matrix_qs=matrix_s(1)%matrix, &
187 ls_mstruct=ls_scf_env%ls_mstruct)
188
189 nspin = ls_scf_env%nspins
190 IF (ALLOCATED(ls_scf_env%matrix_p)) THEN
191 DO ispin = 1, SIZE(ls_scf_env%matrix_p)
192 CALL dbcsr_release(ls_scf_env%matrix_p(ispin))
193 END DO
194 ELSE
195 ALLOCATE (ls_scf_env%matrix_p(nspin))
196 END IF
197
198 DO ispin = 1, nspin
199 CALL dbcsr_create(ls_scf_env%matrix_p(ispin), template=ls_scf_env%matrix_s, &
200 matrix_type=dbcsr_type_no_symmetry)
201 END DO
202
203 ALLOCATE (ls_scf_env%matrix_ks(nspin))
204 DO ispin = 1, nspin
205 CALL dbcsr_create(ls_scf_env%matrix_ks(ispin), template=ls_scf_env%matrix_s, &
206 matrix_type=dbcsr_type_no_symmetry)
207 END DO
208
209 ! set up matrix S, and needed functions of S
210 CALL ls_scf_init_matrix_s(matrix_s(1)%matrix, ls_scf_env)
211
212 ! get the initial guess for the SCF
213 CALL ls_scf_initial_guess(qs_env, ls_scf_env)
214
215 IF (ls_scf_env%do_rho_mixing) THEN
216 CALL rho_mixing_ls_init(qs_env, ls_scf_env)
217 END IF
218
219 IF (ls_scf_env%do_pexsi) THEN
220 CALL pexsi_init_scf(ks_env, ls_scf_env%pexsi, matrix_s(1)%matrix)
221 END IF
222
223 IF (qs_env%do_transport) THEN
224 CALL transport_initialize(ks_env, qs_env%transport_env, matrix_s(1)%matrix)
225 END IF
226
227 CALL timestop(handle)
228
229 END SUBROUTINE ls_scf_init_scf
230
231! **************************************************************************************************
232!> \brief deal with the scf initial guess
233!> \param qs_env ...
234!> \param ls_scf_env ...
235!> \par History
236!> 2012.11 created [Joost VandeVondele]
237!> \author Joost VandeVondele
238! **************************************************************************************************
239 SUBROUTINE ls_scf_initial_guess(qs_env, ls_scf_env)
240 TYPE(qs_environment_type), POINTER :: qs_env
241 TYPE(ls_scf_env_type) :: ls_scf_env
242
243 CHARACTER(len=*), PARAMETER :: routinen = 'ls_scf_initial_guess'
244 INTEGER, PARAMETER :: aspc_guess = 2, atomic_guess = 1, &
245 restart_guess = 3
246
247 CHARACTER(LEN=default_path_length) :: file_name, project_name
248 INTEGER :: handle, iaspc, initial_guess_type, &
249 ispin, istore, naspc, unit_nr
250 REAL(kind=dp) :: alpha, cs_pos
251 TYPE(cp_logger_type), POINTER :: logger
252 TYPE(dbcsr_distribution_type) :: dist
253 TYPE(dbcsr_type) :: matrix_tmp1
254
255 IF (ls_scf_env%do_pao) RETURN ! pao has its own initial guess
256
257 CALL timeset(routinen, handle)
258
259 ! get a useful output_unit
260 logger => cp_get_default_logger()
261 IF (logger%para_env%is_source()) THEN
262 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
263 ELSE
264 unit_nr = -1
265 END IF
266
267 IF (unit_nr > 0) WRITE (unit_nr, '()')
268 ! if there is no history go for the atomic guess, otherwise extrapolate the dm history
269 IF (ls_scf_env%scf_history%istore == 0) THEN
270 IF (ls_scf_env%restart_read) THEN
271 initial_guess_type = restart_guess
272 ELSE
273 initial_guess_type = atomic_guess
274 END IF
275 ELSE
276 initial_guess_type = aspc_guess
277 END IF
278
279 ! how to get the initial guess
280 SELECT CASE (initial_guess_type)
281 CASE (atomic_guess)
282 CALL ls_scf_qs_atomic_guess(qs_env, ls_scf_env%energy_init)
283 CASE (restart_guess)
284 project_name = logger%iter_info%project_name
285 DO ispin = 1, SIZE(ls_scf_env%matrix_p)
286 WRITE (file_name, '(A,I0,A)') trim(project_name)//"_LS_DM_SPIN_", ispin, "_RESTART.dm"
287 CALL dbcsr_get_info(ls_scf_env%matrix_p(1), distribution=dist)
288 CALL dbcsr_binary_read(file_name, distribution=dist, matrix_new=ls_scf_env%matrix_p(ispin))
289 cs_pos = dbcsr_checksum(ls_scf_env%matrix_p(ispin), pos=.true.)
290 IF (unit_nr > 0) THEN
291 WRITE (unit_nr, '(T2,A,E20.8)') "Read restart DM "//trim(file_name)//" with checksum: ", cs_pos
292 END IF
293 END DO
294
295 ! directly go to computing the corresponding energy and ks matrix
296 CALL ls_scf_dm_to_ks(qs_env, ls_scf_env, ls_scf_env%energy_init, iscf=0)
297 CASE (aspc_guess)
298 CALL cite_reference(kolafa2004)
299 CALL cite_reference(kuhne2007)
300 naspc = min(ls_scf_env%scf_history%istore, ls_scf_env%scf_history%nstore)
301 DO ispin = 1, SIZE(ls_scf_env%matrix_p)
302 ! actual extrapolation
303 CALL dbcsr_set(ls_scf_env%matrix_p(ispin), 0.0_dp)
304 DO iaspc = 1, naspc
305 alpha = (-1.0_dp)**(iaspc + 1)*real(iaspc, kind=dp)* &
306 binomial(2*naspc, naspc - iaspc)/binomial(2*naspc - 2, naspc - 1)
307 istore = mod(ls_scf_env%scf_history%istore - iaspc, ls_scf_env%scf_history%nstore) + 1
308 CALL dbcsr_add(ls_scf_env%matrix_p(ispin), ls_scf_env%scf_history%matrix(ispin, istore), 1.0_dp, alpha)
309 END DO
310 END DO
311 END SELECT
312
313 ! which cases need getting purified and non-orthogonal ?
314 SELECT CASE (initial_guess_type)
316 ! do nothing
317 CASE (aspc_guess)
318 ! purification can't be done on the pexsi matrix, which is not necessarily idempotent,
319 ! and not stored in an ortho basis form
320 IF (.NOT. (ls_scf_env%do_pexsi)) THEN
321 DO ispin = 1, SIZE(ls_scf_env%matrix_p)
322 ! linear combination of P's is not idempotent. A bit of McWeeny is needed to ensure it is again
323 IF (SIZE(ls_scf_env%matrix_p) == 1) CALL dbcsr_scale(ls_scf_env%matrix_p(ispin), 0.5_dp)
324 ! to ensure that noisy blocks do not build up during MD (in particular with curvy) filter that guess a bit more
325 CALL dbcsr_filter(ls_scf_env%matrix_p(ispin), ls_scf_env%eps_filter**(2.0_dp/3.0_dp))
326 CALL purify_mcweeny(ls_scf_env%matrix_p(ispin:ispin), ls_scf_env%eps_filter, 3)
327 IF (SIZE(ls_scf_env%matrix_p) == 1) CALL dbcsr_scale(ls_scf_env%matrix_p(ispin), 2.0_dp)
328
329 IF (ls_scf_env%use_s_sqrt) THEN
330 ! need to get P in the non-orthogonal basis if it was stored differently
331 CALL dbcsr_create(matrix_tmp1, template=ls_scf_env%matrix_s, &
332 matrix_type=dbcsr_type_no_symmetry)
333 CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s_sqrt_inv, ls_scf_env%matrix_p(ispin), &
334 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
335 CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_s_sqrt_inv, &
336 0.0_dp, ls_scf_env%matrix_p(ispin), &
337 filter_eps=ls_scf_env%eps_filter)
338 CALL dbcsr_release(matrix_tmp1)
339
340 IF (ls_scf_env%has_s_preconditioner) THEN
341 CALL apply_matrix_preconditioner(ls_scf_env%matrix_p(ispin), "forward", &
342 ls_scf_env%matrix_bs_sqrt, ls_scf_env%matrix_bs_sqrt_inv)
343 END IF
344 END IF
345 END DO
346 END IF
347
348 ! compute corresponding energy and ks matrix
349 CALL ls_scf_dm_to_ks(qs_env, ls_scf_env, ls_scf_env%energy_init, iscf=0)
350 END SELECT
351
352 IF (unit_nr > 0) THEN
353 WRITE (unit_nr, '(T2,A,F20.9)') "Energy with the initial guess:", ls_scf_env%energy_init
354 WRITE (unit_nr, '()')
355 END IF
356
357 CALL timestop(handle)
358
359 END SUBROUTINE ls_scf_initial_guess
360
361! **************************************************************************************************
362!> \brief store a history of matrices for later use in ls_scf_initial_guess
363!> \param ls_scf_env ...
364!> \par History
365!> 2012.11 created [Joost VandeVondele]
366!> \author Joost VandeVondele
367! **************************************************************************************************
368 SUBROUTINE ls_scf_store_result(ls_scf_env)
369 TYPE(ls_scf_env_type) :: ls_scf_env
370
371 CHARACTER(len=*), PARAMETER :: routinen = 'ls_scf_store_result'
372
373 CHARACTER(LEN=default_path_length) :: file_name, project_name
374 INTEGER :: handle, ispin, istore, unit_nr
375 REAL(kind=dp) :: cs_pos
376 TYPE(cp_logger_type), POINTER :: logger
377 TYPE(dbcsr_type) :: matrix_tmp1
378
379 CALL timeset(routinen, handle)
380
381 ! get a useful output_unit
382 logger => cp_get_default_logger()
383 IF (logger%para_env%is_source()) THEN
384 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
385 ELSE
386 unit_nr = -1
387 END IF
388
389 IF (ls_scf_env%restart_write) THEN
390 DO ispin = 1, SIZE(ls_scf_env%matrix_p)
391 project_name = logger%iter_info%project_name
392 WRITE (file_name, '(A,I0,A)') trim(project_name)//"_LS_DM_SPIN_", ispin, "_RESTART.dm"
393 cs_pos = dbcsr_checksum(ls_scf_env%matrix_p(ispin), pos=.true.)
394 IF (unit_nr > 0) THEN
395 WRITE (unit_nr, '(T2,A,E20.8)') "Writing restart DM "//trim(file_name)//" with checksum: ", cs_pos
396 END IF
397 IF (ls_scf_env%do_transport .OR. ls_scf_env%do_pexsi) THEN
398 IF (unit_nr > 0) THEN
399 WRITE (unit_nr, '(T6,A)') "The restart DM "//trim(file_name)//" has the sparsity of S, therefore,"
400 WRITE (unit_nr, '(T6,A)') "not compatible with methods that require a full DM! "
401 END IF
402 END IF
403 CALL dbcsr_binary_write(ls_scf_env%matrix_p(ispin), file_name)
404 END DO
405 END IF
406
407 IF (ls_scf_env%scf_history%nstore > 0) THEN
408 ls_scf_env%scf_history%istore = ls_scf_env%scf_history%istore + 1
409 DO ispin = 1, SIZE(ls_scf_env%matrix_p)
410 istore = mod(ls_scf_env%scf_history%istore - 1, ls_scf_env%scf_history%nstore) + 1
411 CALL dbcsr_copy(ls_scf_env%scf_history%matrix(ispin, istore), ls_scf_env%matrix_p(ispin))
412
413 ! if we have the sqrt around, we use it to go to the orthogonal basis
414 IF (ls_scf_env%use_s_sqrt) THEN
415 ! usually sqrt(S) * P * sqrt(S) should be available, or could be stored at least,
416 ! so that the next multiplications could be saved.
417 CALL dbcsr_create(matrix_tmp1, template=ls_scf_env%matrix_s, &
418 matrix_type=dbcsr_type_no_symmetry)
419
420 IF (ls_scf_env%has_s_preconditioner) THEN
421 CALL apply_matrix_preconditioner(ls_scf_env%scf_history%matrix(ispin, istore), "backward", &
422 ls_scf_env%matrix_bs_sqrt, ls_scf_env%matrix_bs_sqrt_inv)
423 END IF
424 CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s_sqrt, ls_scf_env%scf_history%matrix(ispin, istore), &
425 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
426 CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_s_sqrt, &
427 0.0_dp, ls_scf_env%scf_history%matrix(ispin, istore), &
428 filter_eps=ls_scf_env%eps_filter)
429 CALL dbcsr_release(matrix_tmp1)
430 END IF
431
432 END DO
433 END IF
434
435 CALL timestop(handle)
436
437 END SUBROUTINE ls_scf_store_result
438
439! **************************************************************************************************
440!> \brief Main SCF routine. Can we keep it clean ?
441!> \param qs_env ...
442!> \param ls_scf_env ...
443!> \par History
444!> 2010.10 created [Joost VandeVondele]
445!> \author Joost VandeVondele
446! **************************************************************************************************
447 SUBROUTINE ls_scf_main(qs_env, ls_scf_env)
448 TYPE(qs_environment_type), POINTER :: qs_env
449 TYPE(ls_scf_env_type) :: ls_scf_env
450
451 CHARACTER(len=*), PARAMETER :: routinen = 'ls_scf_main'
452
453 INTEGER :: handle, iscf, ispin, &
454 nelectron_spin_real, nmixing, nspin, &
455 unit_nr
456 LOGICAL :: check_convergence, diis_step, do_transport, extra_scf, maxscf_reached, &
457 scf_converged, should_stop, transm_maxscf_reached, transm_scf_converged
458 REAL(kind=dp) :: energy_diff, energy_new, energy_old, &
459 eps_diis, t1, t2
460 TYPE(cp_logger_type), POINTER :: logger
461 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
462 TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:) :: matrix_ks_deviation, matrix_mixing_old
463 TYPE(energy_correction_type), POINTER :: ec_env
464 TYPE(qs_diis_buffer_type_sparse), POINTER :: diis_buffer
465 TYPE(transport_env_type), POINTER :: transport_env
466
467 CALL timeset(routinen, handle)
468
469 ! get a useful output_unit
470 logger => cp_get_default_logger()
471 IF (logger%para_env%is_source()) THEN
472 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
473 ELSE
474 unit_nr = -1
475 END IF
476
477 nspin = ls_scf_env%nspins
478
479 ! old quantities, useful for mixing
480 ALLOCATE (matrix_mixing_old(nspin), matrix_ks_deviation(nspin))
481 DO ispin = 1, nspin
482 CALL dbcsr_create(matrix_mixing_old(ispin), template=ls_scf_env%matrix_ks(ispin))
483
484 CALL dbcsr_create(matrix_ks_deviation(ispin), template=ls_scf_env%matrix_ks(ispin))
485 CALL dbcsr_set(matrix_ks_deviation(ispin), 0.0_dp)
486 END DO
487 ls_scf_env%homo_spin(:) = 0.0_dp
488 ls_scf_env%lumo_spin(:) = 0.0_dp
489
490 transm_scf_converged = .false.
491 transm_maxscf_reached = .false.
492
493 energy_old = 0.0_dp
494 IF (ls_scf_env%scf_history%istore > 0) energy_old = ls_scf_env%energy_init
495 check_convergence = .true.
496 iscf = 0
497 IF (ls_scf_env%ls_diis) THEN
498 diis_step = .false.
499 eps_diis = ls_scf_env%eps_diis
500 nmixing = ls_scf_env%nmixing
501 NULLIFY (diis_buffer)
502 ALLOCATE (diis_buffer)
503 CALL qs_diis_b_create_sparse(diis_buffer, &
504 nbuffer=ls_scf_env%max_diis)
505 CALL qs_diis_b_clear_sparse(diis_buffer)
506 CALL get_qs_env(qs_env, matrix_s=matrix_s)
507 END IF
508
509 CALL get_qs_env(qs_env, transport_env=transport_env, do_transport=do_transport)
510
511 ! the real SCF loop
512 DO
513
514 ! check on max SCF or timing/exit
515 CALL external_control(should_stop, "SCF", start_time=qs_env%start_time, target_time=qs_env%target_time)
516 IF (do_transport) THEN
517 maxscf_reached = should_stop .OR. iscf >= ls_scf_env%max_scf
518 ! one extra scf step for post-processing in transmission calculations
519 IF (transport_env%params%method .EQ. transport_transmission) THEN
520 IF (transm_maxscf_reached) THEN
521 IF (unit_nr > 0) WRITE (unit_nr, '(T2,A)') "SCF not converged! "
522 EXIT
523 END IF
524 transm_maxscf_reached = maxscf_reached
525 ELSE
526 IF (maxscf_reached) THEN
527 IF (unit_nr > 0) WRITE (unit_nr, '(T2,A)') "SCF not converged! "
528 EXIT
529 END IF
530 END IF
531 ELSE
532 IF (should_stop .OR. iscf >= ls_scf_env%max_scf) THEN
533 IF (unit_nr > 0) WRITE (unit_nr, '(T2,A)') "SCF not converged! "
534 ! Skip Harris functional calculation if ground-state is NOT converged
535 IF (qs_env%energy_correction) THEN
536 CALL get_qs_env(qs_env, ec_env=ec_env)
537 IF (ec_env%skip_ec) ec_env%do_skip = .true.
538 END IF
539 EXIT
540 END IF
541 END IF
542
543 t1 = m_walltime()
544 iscf = iscf + 1
545
546 ! first get a copy of the current KS matrix
547 CALL get_qs_env(qs_env, matrix_ks=matrix_ks)
548 DO ispin = 1, nspin
549 CALL matrix_qs_to_ls(ls_scf_env%matrix_ks(ispin), matrix_ks(ispin)%matrix, &
550 ls_scf_env%ls_mstruct, covariant=.true.)
551 IF (ls_scf_env%has_s_preconditioner) THEN
552 CALL apply_matrix_preconditioner(ls_scf_env%matrix_ks(ispin), "forward", &
553 ls_scf_env%matrix_bs_sqrt, ls_scf_env%matrix_bs_sqrt_inv)
554 END IF
555 CALL dbcsr_filter(ls_scf_env%matrix_ks(ispin), ls_scf_env%eps_filter)
556 END DO
557 ! run curvy steps if required. Needs an idempotent DM (either perification or restart)
558 IF ((iscf > 1 .OR. ls_scf_env%scf_history%istore > 0) .AND. ls_scf_env%curvy_steps) THEN
559 CALL dm_ls_curvy_optimization(ls_scf_env, energy_old, check_convergence)
560 ELSE
561 ! turn the KS matrix in a density matrix
562 DO ispin = 1, nspin
563 IF (ls_scf_env%do_rho_mixing) THEN
564 CALL dbcsr_copy(matrix_mixing_old(ispin), ls_scf_env%matrix_ks(ispin))
565 ELSE
566 IF (iscf == 1) THEN
567 ! initialize the mixing matrix with the current state if needed
568 CALL dbcsr_copy(matrix_mixing_old(ispin), ls_scf_env%matrix_ks(ispin))
569 ELSE
570 IF (ls_scf_env%ls_diis) THEN ! ------- IF-DIIS+MIX--- START
571 IF (diis_step .AND. (iscf - 1) .GE. ls_scf_env%iter_ini_diis) THEN
572 IF (unit_nr > 0) THEN
573 WRITE (unit_nr, '(A61)') &
574 '*************************************************************'
575 WRITE (unit_nr, '(A50,2(I3,A1),L1,A1)') &
576 " Using DIIS mixed KS: (iscf,INI_DIIS,DIIS_STEP)=(", &
577 iscf, ",", ls_scf_env%iter_ini_diis, ",", diis_step, ")"
578 WRITE (unit_nr, '(A52)') &
579 " KS_nw= DIIS-Linear-Combination-Previous KS matrices"
580 WRITE (unit_nr, '(61A)') &
581 "*************************************************************"
582 END IF
583 CALL dbcsr_copy(matrix_mixing_old(ispin), & ! out
584 ls_scf_env%matrix_ks(ispin)) ! in
585 ELSE
586 IF (unit_nr > 0) THEN
587 WRITE (unit_nr, '(A57)') &
588 "*********************************************************"
589 WRITE (unit_nr, '(A23,F5.3,A25,I3)') &
590 " Using MIXING_FRACTION=", ls_scf_env%mixing_fraction, &
591 " to mix KS matrix: iscf=", iscf
592 WRITE (unit_nr, '(A7,F5.3,A6,F5.3,A7)') &
593 " KS_nw=", ls_scf_env%mixing_fraction, "*KS + ", &
594 1.0_dp - ls_scf_env%mixing_fraction, "*KS_old"
595 WRITE (unit_nr, '(A57)') &
596 "*********************************************************"
597 END IF
598 ! perform the mixing of ks matrices
599 CALL dbcsr_add(matrix_mixing_old(ispin), &
600 ls_scf_env%matrix_ks(ispin), &
601 1.0_dp - ls_scf_env%mixing_fraction, &
602 ls_scf_env%mixing_fraction)
603 END IF
604 ELSE ! otherwise
605 IF (unit_nr > 0) THEN
606 WRITE (unit_nr, '(A57)') &
607 "*********************************************************"
608 WRITE (unit_nr, '(A23,F5.3,A25,I3)') &
609 " Using MIXING_FRACTION=", ls_scf_env%mixing_fraction, &
610 " to mix KS matrix: iscf=", iscf
611 WRITE (unit_nr, '(A7,F5.3,A6,F5.3,A7)') &
612 " KS_nw=", ls_scf_env%mixing_fraction, "*KS + ", &
613 1.0_dp - ls_scf_env%mixing_fraction, "*KS_old"
614 WRITE (unit_nr, '(A57)') &
615 "*********************************************************"
616 END IF
617 ! perform the mixing of ks matrices
618 CALL dbcsr_add(matrix_mixing_old(ispin), &
619 ls_scf_env%matrix_ks(ispin), &
620 1.0_dp - ls_scf_env%mixing_fraction, &
621 ls_scf_env%mixing_fraction)
622 END IF ! ------- IF-DIIS+MIX--- END
623 END IF
624 END IF
625
626 ! compute the density matrix that matches it
627 ! we need the proper number of states
628 nelectron_spin_real = ls_scf_env%nelectron_spin(ispin)
629 IF (ls_scf_env%nspins == 1) nelectron_spin_real = nelectron_spin_real/2
630
631 IF (do_transport) THEN
632 IF (ls_scf_env%has_s_preconditioner) &
633 cpabort("NOT YET IMPLEMENTED with S preconditioner. ")
634 IF (ls_scf_env%ls_mstruct%cluster_type .NE. ls_cluster_atomic) &
635 cpabort("NOT YET IMPLEMENTED with molecular clustering. ")
636
637 extra_scf = maxscf_reached .OR. scf_converged
638 ! get the current Kohn-Sham matrix (ks) and return matrix_p evaluated using an external C routine
639 CALL external_scf_method(transport_env, ls_scf_env%matrix_s, matrix_mixing_old(ispin), &
640 ls_scf_env%matrix_p(ispin), nelectron_spin_real, ls_scf_env%natoms, &
641 energy_diff, iscf, extra_scf)
642
643 ELSE
644 SELECT CASE (ls_scf_env%purification_method)
645 CASE (ls_scf_sign)
646 CALL density_matrix_sign(ls_scf_env%matrix_p(ispin), ls_scf_env%mu_spin(ispin), ls_scf_env%fixed_mu, &
647 ls_scf_env%sign_method, ls_scf_env%sign_order, matrix_mixing_old(ispin), &
648 ls_scf_env%matrix_s, ls_scf_env%matrix_s_inv, nelectron_spin_real, &
649 ls_scf_env%eps_filter, ls_scf_env%sign_symmetric, ls_scf_env%submatrix_sign_method, &
650 ls_scf_env%matrix_s_sqrt_inv)
651 CASE (ls_scf_tc2)
652 CALL density_matrix_tc2(ls_scf_env%matrix_p(ispin), matrix_mixing_old(ispin), ls_scf_env%matrix_s_sqrt_inv, &
653 nelectron_spin_real, ls_scf_env%eps_filter, ls_scf_env%homo_spin(ispin), &
654 ls_scf_env%lumo_spin(ispin), non_monotonic=ls_scf_env%non_monotonic, &
655 eps_lanczos=ls_scf_env%eps_lanczos, max_iter_lanczos=ls_scf_env%max_iter_lanczos)
656 CASE (ls_scf_trs4)
657 CALL density_matrix_trs4(ls_scf_env%matrix_p(ispin), matrix_mixing_old(ispin), ls_scf_env%matrix_s_sqrt_inv, &
658 nelectron_spin_real, ls_scf_env%eps_filter, ls_scf_env%homo_spin(ispin), &
659 ls_scf_env%lumo_spin(ispin), ls_scf_env%mu_spin(ispin), &
660 dynamic_threshold=ls_scf_env%dynamic_threshold, &
661 matrix_ks_deviation=matrix_ks_deviation(ispin), &
662 eps_lanczos=ls_scf_env%eps_lanczos, max_iter_lanczos=ls_scf_env%max_iter_lanczos)
663 CASE (ls_scf_pexsi)
664 IF (ls_scf_env%has_s_preconditioner) &
665 cpabort("S preconditioning not implemented in combination with the PEXSI library. ")
666 IF (ls_scf_env%ls_mstruct%cluster_type .NE. ls_cluster_atomic) &
667 CALL cp_abort(__location__, &
668 "Molecular clustering not implemented in combination with the PEXSI library. ")
669 CALL density_matrix_pexsi(ls_scf_env%pexsi, ls_scf_env%matrix_p(ispin), ls_scf_env%pexsi%matrix_w(ispin), &
670 ls_scf_env%pexsi%kTS(ispin), matrix_mixing_old(ispin), ls_scf_env%matrix_s, &
671 nelectron_spin_real, ls_scf_env%mu_spin(ispin), iscf, ispin)
672 END SELECT
673 END IF
674
675 IF (ls_scf_env%has_s_preconditioner) THEN
676 CALL apply_matrix_preconditioner(ls_scf_env%matrix_p(ispin), "forward", &
677 ls_scf_env%matrix_bs_sqrt, ls_scf_env%matrix_bs_sqrt_inv)
678 END IF
679 CALL dbcsr_filter(ls_scf_env%matrix_p(ispin), ls_scf_env%eps_filter)
680
681 IF (ls_scf_env%nspins == 1) CALL dbcsr_scale(ls_scf_env%matrix_p(ispin), 2.0_dp)
682
683 END DO
684 END IF
685
686 ! compute the corresponding new energy KS matrix and new energy
687 CALL ls_scf_dm_to_ks(qs_env, ls_scf_env, energy_new, iscf)
688
689 IF (ls_scf_env%do_pexsi) THEN
690 CALL pexsi_to_qs(ls_scf_env, qs_env, kts=ls_scf_env%pexsi%kTS)
691 END IF
692
693 ! report current SCF loop
694 energy_diff = energy_new - energy_old
695 energy_old = energy_new
696
697 t2 = m_walltime()
698 IF (unit_nr > 0) THEN
699 WRITE (unit_nr, *)
700 WRITE (unit_nr, '(T2,A,I6,F20.9,F20.9,F12.6)') "SCF", iscf, energy_new, energy_diff, t2 - t1
701 WRITE (unit_nr, *)
702 CALL m_flush(unit_nr)
703 END IF
704
705 IF (do_transport) THEN
706 scf_converged = check_convergence .AND. abs(energy_diff) < ls_scf_env%eps_scf*ls_scf_env%nelectron_total
707 ! one extra scf step for post-processing in transmission calculations
708 IF (transport_env%params%method .EQ. transport_transmission) THEN
709 IF (transm_scf_converged) EXIT
710 transm_scf_converged = scf_converged
711 ELSE
712 IF (scf_converged) THEN
713 IF (unit_nr > 0) WRITE (unit_nr, '(/,T2,A,I5,A/)') "SCF run converged in ", iscf, " steps."
714 EXIT
715 END IF
716 END IF
717 ELSE
718 ! exit criterion on the energy only for the time being
719 IF (check_convergence .AND. abs(energy_diff) < ls_scf_env%eps_scf*ls_scf_env%nelectron_total) THEN
720 IF (unit_nr > 0) WRITE (unit_nr, '(/,T2,A,I5,A/)') "SCF run converged in ", iscf, " steps."
721 ! Skip Harris functional calculation if ground-state is NOT converged
722 IF (qs_env%energy_correction) THEN
723 CALL get_qs_env(qs_env, ec_env=ec_env)
724 IF (ec_env%skip_ec) ec_env%do_skip = .false.
725 END IF
726 EXIT
727 END IF
728 END IF
729
730 IF (ls_scf_env%ls_diis) THEN
731! diis_buffer, buffer with 1) Kohn-Sham history matrix,
732! 2) KS error history matrix (f=KPS-SPK),
733! 3) B matrix (for finding DIIS weighting coefficients)
734 CALL qs_diis_b_step_4lscf(diis_buffer, qs_env, ls_scf_env, unit_nr, &
735 iscf, diis_step, eps_diis, nmixing, matrix_s(1)%matrix, &
736 ls_scf_env%eps_filter)
737 END IF
738
739 IF (ls_scf_env%do_pexsi) THEN
740 CALL pexsi_set_convergence_tolerance(ls_scf_env%pexsi, energy_diff, &
741 ls_scf_env%eps_scf*ls_scf_env%nelectron_total, &
742 ! initialize in second scf step of first SCF cycle:
743 (iscf .EQ. 2) .AND. (ls_scf_env%scf_history%istore .EQ. 0), &
744 check_convergence)
745 END IF
746
747 END DO
748
749 ! free storage
750 IF (ls_scf_env%ls_diis) THEN
751 CALL qs_diis_b_release_sparse(diis_buffer)
752 DEALLOCATE (diis_buffer)
753 END IF
754 DO ispin = 1, nspin
755 CALL dbcsr_release(matrix_mixing_old(ispin))
756 CALL dbcsr_release(matrix_ks_deviation(ispin))
757 END DO
758 DEALLOCATE (matrix_mixing_old, matrix_ks_deviation)
759
760 CALL timestop(handle)
761
762 END SUBROUTINE ls_scf_main
763
764! **************************************************************************************************
765!> \brief after SCF we have a density matrix, and the self consistent KS matrix
766!> analyze its properties.
767!> \param qs_env ...
768!> \param ls_scf_env ...
769!> \par History
770!> 2010.10 created [Joost VandeVondele]
771!> \author Joost VandeVondele
772! **************************************************************************************************
773 SUBROUTINE ls_scf_post(qs_env, ls_scf_env)
774 TYPE(qs_environment_type), POINTER :: qs_env
775 TYPE(ls_scf_env_type) :: ls_scf_env
776
777 CHARACTER(len=*), PARAMETER :: routinen = 'ls_scf_post'
778
779 INTEGER :: handle, ispin, unit_nr
780 REAL(kind=dp) :: occ
781 TYPE(cp_logger_type), POINTER :: logger
782 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_w
783 TYPE(dft_control_type), POINTER :: dft_control
784
785 CALL timeset(routinen, handle)
786
787 CALL get_qs_env(qs_env, dft_control=dft_control)
788
789 ! get a useful output_unit
790 logger => cp_get_default_logger()
791 IF (logger%para_env%is_source()) THEN
792 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
793 ELSE
794 unit_nr = -1
795 END IF
796
797 ! store the matrix for a next scf run
798 IF (.NOT. ls_scf_env%do_pao) &
799 CALL ls_scf_store_result(ls_scf_env)
800
801 ! write homo and lumo energy and occupation (if not already part of the output)
802 IF (ls_scf_env%curvy_steps) THEN
803 CALL post_scf_homo_lumo(ls_scf_env)
804
805 ! always report P occ
806 IF (unit_nr > 0) WRITE (unit_nr, *) ""
807 DO ispin = 1, ls_scf_env%nspins
808 occ = dbcsr_get_occupation(ls_scf_env%matrix_p(ispin))
809 IF (unit_nr > 0) WRITE (unit_nr, '(T2,A,F20.12)') "Density matrix (P) occupation ", occ
810 END DO
811 END IF
812
813 ! compute the matrix_w if associated
814 IF (ls_scf_env%calculate_forces) THEN
815 CALL get_qs_env(qs_env, matrix_w=matrix_w)
816 cpassert(ASSOCIATED(matrix_w))
817 IF (ls_scf_env%do_pexsi) THEN
818 CALL pexsi_to_qs(ls_scf_env, qs_env, matrix_w=ls_scf_env%pexsi%matrix_w)
819 ELSE
820 CALL calculate_w_matrix_ls(matrix_w, ls_scf_env)
821 END IF
822 END IF
823
824 ! compute properties
825
826 IF (ls_scf_env%perform_mu_scan) CALL post_scf_mu_scan(ls_scf_env)
827
828 IF (ls_scf_env%report_all_sparsities) CALL post_scf_sparsities(ls_scf_env)
829
830 IF (dft_control%qs_control%dftb) THEN
831 CALL scf_post_calculation_tb(qs_env, "DFTB", .true.)
832 ELSE IF (dft_control%qs_control%xtb) THEN
833 CALL scf_post_calculation_tb(qs_env, "xTB", .true.)
834 ELSE
835 CALL write_mo_free_results(qs_env)
836 END IF
837
838 IF (ls_scf_env%chebyshev%compute_chebyshev) CALL compute_chebyshev(qs_env, ls_scf_env)
839
840 IF (.true.) CALL post_scf_experiment()
841
842 IF (dft_control%qs_control%dftb .OR. dft_control%qs_control%xtb) THEN
843 !
844 ELSE
845 CALL qs_scf_post_moments(qs_env%input, logger, qs_env, unit_nr)
846 END IF
847
848 ! clean up used data
849
850 CALL dbcsr_release(ls_scf_env%matrix_s)
851 CALL deallocate_curvy_data(ls_scf_env%curvy_data)
852
853 IF (ls_scf_env%has_s_preconditioner) THEN
854 CALL dbcsr_release(ls_scf_env%matrix_bs_sqrt)
855 CALL dbcsr_release(ls_scf_env%matrix_bs_sqrt_inv)
856 END IF
857
858 IF (ls_scf_env%needs_s_inv) THEN
859 CALL dbcsr_release(ls_scf_env%matrix_s_inv)
860 END IF
861
862 IF (ls_scf_env%use_s_sqrt) THEN
863 CALL dbcsr_release(ls_scf_env%matrix_s_sqrt)
864 CALL dbcsr_release(ls_scf_env%matrix_s_sqrt_inv)
865 END IF
866
867 DO ispin = 1, SIZE(ls_scf_env%matrix_ks)
868 CALL dbcsr_release(ls_scf_env%matrix_ks(ispin))
869 END DO
870 DEALLOCATE (ls_scf_env%matrix_ks)
871
872 IF (ls_scf_env%do_pexsi) &
873 CALL pexsi_finalize_scf(ls_scf_env%pexsi, ls_scf_env%mu_spin)
874
875 CALL timestop(handle)
876
877 END SUBROUTINE ls_scf_post
878
879! **************************************************************************************************
880!> \brief Compute the HOMO LUMO energies post SCF
881!> \param ls_scf_env ...
882!> \par History
883!> 2013.06 created [Joost VandeVondele]
884!> \author Joost VandeVondele
885! **************************************************************************************************
886 SUBROUTINE post_scf_homo_lumo(ls_scf_env)
887 TYPE(ls_scf_env_type) :: ls_scf_env
888
889 CHARACTER(len=*), PARAMETER :: routinen = 'post_scf_homo_lumo'
890
891 INTEGER :: handle, ispin, nspin, unit_nr
892 LOGICAL :: converged
893 REAL(kind=dp) :: eps_max, eps_min, homo, lumo
894 TYPE(cp_logger_type), POINTER :: logger
895 TYPE(dbcsr_type) :: matrix_k, matrix_p, matrix_tmp
896
897 CALL timeset(routinen, handle)
898
899 ! get a useful output_unit
900 logger => cp_get_default_logger()
901 IF (logger%para_env%is_source()) THEN
902 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
903 ELSE
904 unit_nr = -1
905 END IF
906
907 IF (unit_nr > 0) WRITE (unit_nr, '(T2,A)') ""
908
909 ! TODO: remove these limitations
910 cpassert(.NOT. ls_scf_env%has_s_preconditioner)
911 cpassert(ls_scf_env%use_s_sqrt)
912
913 nspin = ls_scf_env%nspins
914
915 CALL dbcsr_create(matrix_p, template=ls_scf_env%matrix_p(1), matrix_type=dbcsr_type_no_symmetry)
916
917 CALL dbcsr_create(matrix_k, template=ls_scf_env%matrix_p(1), matrix_type=dbcsr_type_no_symmetry)
918
919 CALL dbcsr_create(matrix_tmp, template=ls_scf_env%matrix_p(1), matrix_type=dbcsr_type_no_symmetry)
920
921 DO ispin = 1, nspin
922 ! ortho basis ks
923 CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s_sqrt_inv, ls_scf_env%matrix_ks(ispin), &
924 0.0_dp, matrix_tmp, filter_eps=ls_scf_env%eps_filter)
925 CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp, ls_scf_env%matrix_s_sqrt_inv, &
926 0.0_dp, matrix_k, filter_eps=ls_scf_env%eps_filter)
927
928 ! extremal eigenvalues ks
929 CALL arnoldi_extremal(matrix_k, eps_max, eps_min, max_iter=ls_scf_env%max_iter_lanczos, &
930 threshold=ls_scf_env%eps_lanczos, converged=converged)
931
932 ! ortho basis p
933 CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s_sqrt, ls_scf_env%matrix_p(ispin), &
934 0.0_dp, matrix_tmp, filter_eps=ls_scf_env%eps_filter)
935 CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp, ls_scf_env%matrix_s_sqrt, &
936 0.0_dp, matrix_p, filter_eps=ls_scf_env%eps_filter)
937 IF (nspin == 1) CALL dbcsr_scale(matrix_p, 0.5_dp)
938
939 ! go compute homo lumo
940 CALL compute_homo_lumo(matrix_k, matrix_p, eps_min, eps_max, ls_scf_env%eps_filter, &
941 ls_scf_env%max_iter_lanczos, ls_scf_env%eps_lanczos, homo, lumo, unit_nr)
942
943 END DO
944
945 CALL dbcsr_release(matrix_p)
946 CALL dbcsr_release(matrix_k)
947 CALL dbcsr_release(matrix_tmp)
948
949 CALL timestop(handle)
950
951 END SUBROUTINE post_scf_homo_lumo
952
953! **************************************************************************************************
954!> \brief Compute the density matrix for various values of the chemical potential
955!> \param ls_scf_env ...
956!> \par History
957!> 2010.10 created [Joost VandeVondele]
958!> \author Joost VandeVondele
959! **************************************************************************************************
960 SUBROUTINE post_scf_mu_scan(ls_scf_env)
961 TYPE(ls_scf_env_type) :: ls_scf_env
962
963 CHARACTER(len=*), PARAMETER :: routinen = 'post_scf_mu_scan'
964
965 INTEGER :: handle, imu, ispin, nelectron_spin_real, &
966 nmu, nspin, unit_nr
967 REAL(kind=dp) :: mu, t1, t2, trace
968 TYPE(cp_logger_type), POINTER :: logger
969 TYPE(dbcsr_type) :: matrix_p
970
971 CALL timeset(routinen, handle)
972
973 ! get a useful output_unit
974 logger => cp_get_default_logger()
975 IF (logger%para_env%is_source()) THEN
976 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
977 ELSE
978 unit_nr = -1
979 END IF
980
981 nspin = ls_scf_env%nspins
982
983 CALL dbcsr_create(matrix_p, template=ls_scf_env%matrix_p(1))
984
985 nmu = 10
986 DO imu = 0, nmu
987
988 t1 = m_walltime()
989
990 mu = -0.4_dp + imu*(0.1_dp + 0.4_dp)/nmu
991
992 IF (unit_nr > 0) WRITE (unit_nr, *) "------- starting with mu ", mu
993
994 DO ispin = 1, nspin
995 ! we need the proper number of states
996 nelectron_spin_real = ls_scf_env%nelectron_spin(ispin)
997 IF (ls_scf_env%nspins == 1) nelectron_spin_real = nelectron_spin_real/2
998
999 CALL density_matrix_sign_fixed_mu(matrix_p, trace, mu, ls_scf_env%sign_method, &
1000 ls_scf_env%sign_order, ls_scf_env%matrix_ks(ispin), &
1001 ls_scf_env%matrix_s, ls_scf_env%matrix_s_inv, &
1002 ls_scf_env%eps_filter, ls_scf_env%sign_symmetric, &
1003 ls_scf_env%submatrix_sign_method, ls_scf_env%matrix_s_sqrt_inv)
1004 END DO
1005
1006 t2 = m_walltime()
1007
1008 IF (unit_nr > 0) WRITE (unit_nr, *) " obtained ", mu, trace, t2 - t1
1009
1010 END DO
1011
1012 CALL dbcsr_release(matrix_p)
1013
1014 CALL timestop(handle)
1015
1016 END SUBROUTINE post_scf_mu_scan
1017
1018! **************************************************************************************************
1019!> \brief Report on the sparsities of various interesting matrices.
1020!>
1021!> \param ls_scf_env ...
1022!> \par History
1023!> 2010.10 created [Joost VandeVondele]
1024!> \author Joost VandeVondele
1025! **************************************************************************************************
1026 SUBROUTINE post_scf_sparsities(ls_scf_env)
1027 TYPE(ls_scf_env_type) :: ls_scf_env
1028
1029 CHARACTER(len=*), PARAMETER :: routinen = 'post_scf_sparsities'
1030
1031 CHARACTER(LEN=default_string_length) :: title
1032 INTEGER :: handle, ispin, nspin, unit_nr
1033 TYPE(cp_logger_type), POINTER :: logger
1034 TYPE(dbcsr_type) :: matrix_tmp1, matrix_tmp2
1035
1036 CALL timeset(routinen, handle)
1037
1038 ! get a useful output_unit
1039 logger => cp_get_default_logger()
1040 IF (logger%para_env%is_source()) THEN
1041 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
1042 ELSE
1043 unit_nr = -1
1044 END IF
1045
1046 nspin = ls_scf_env%nspins
1047
1048 IF (unit_nr > 0) THEN
1049 WRITE (unit_nr, '()')
1050 WRITE (unit_nr, '(T2,A,E17.3)') "Sparsity reports for eps_filter: ", ls_scf_env%eps_filter
1051 WRITE (unit_nr, '()')
1052 END IF
1053
1054 CALL report_matrix_sparsity(ls_scf_env%matrix_s, unit_nr, "overlap matrix (S)", &
1055 ls_scf_env%eps_filter)
1056
1057 DO ispin = 1, nspin
1058 WRITE (title, '(A,I3)') "Kohn-Sham matrix (H) for spin ", ispin
1059 CALL report_matrix_sparsity(ls_scf_env%matrix_ks(ispin), unit_nr, title, &
1060 ls_scf_env%eps_filter)
1061 END DO
1062
1063 CALL dbcsr_create(matrix_tmp1, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
1064 CALL dbcsr_create(matrix_tmp2, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
1065
1066 DO ispin = 1, nspin
1067 WRITE (title, '(A,I3)') "Density matrix (P) for spin ", ispin
1068 CALL report_matrix_sparsity(ls_scf_env%matrix_p(ispin), unit_nr, title, &
1069 ls_scf_env%eps_filter)
1070
1071 CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s, ls_scf_env%matrix_p(ispin), &
1072 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
1073
1074 WRITE (title, '(A,I3,A)') "S * P(", ispin, ")"
1075 CALL report_matrix_sparsity(matrix_tmp1, unit_nr, title, ls_scf_env%eps_filter)
1076
1077 CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_s, &
1078 0.0_dp, matrix_tmp2, filter_eps=ls_scf_env%eps_filter)
1079 WRITE (title, '(A,I3,A)') "S * P(", ispin, ") * S"
1080 CALL report_matrix_sparsity(matrix_tmp2, unit_nr, title, ls_scf_env%eps_filter)
1081 END DO
1082
1083 IF (ls_scf_env%needs_s_inv) THEN
1084 CALL report_matrix_sparsity(ls_scf_env%matrix_s_inv, unit_nr, "inv(S)", &
1085 ls_scf_env%eps_filter)
1086 DO ispin = 1, nspin
1087 CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s_inv, ls_scf_env%matrix_ks(ispin), &
1088 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
1089
1090 WRITE (title, '(A,I3,A)') "inv(S) * H(", ispin, ")"
1091 CALL report_matrix_sparsity(matrix_tmp1, unit_nr, title, ls_scf_env%eps_filter)
1092 END DO
1093 END IF
1094
1095 IF (ls_scf_env%use_s_sqrt) THEN
1096
1097 CALL report_matrix_sparsity(ls_scf_env%matrix_s_sqrt, unit_nr, "sqrt(S)", &
1098 ls_scf_env%eps_filter)
1099 CALL report_matrix_sparsity(ls_scf_env%matrix_s_sqrt_inv, unit_nr, "inv(sqrt(S))", &
1100 ls_scf_env%eps_filter)
1101
1102 DO ispin = 1, nspin
1103 CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s_sqrt_inv, ls_scf_env%matrix_ks(ispin), &
1104 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
1105 CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_s_sqrt_inv, &
1106 0.0_dp, matrix_tmp2, filter_eps=ls_scf_env%eps_filter)
1107 WRITE (title, '(A,I3,A)') "inv(sqrt(S)) * H(", ispin, ") * inv(sqrt(S))"
1108 CALL report_matrix_sparsity(matrix_tmp2, unit_nr, title, ls_scf_env%eps_filter)
1109 END DO
1110
1111 DO ispin = 1, nspin
1112 CALL dbcsr_multiply("N", "N", 1.0_dp, ls_scf_env%matrix_s_sqrt, ls_scf_env%matrix_p(ispin), &
1113 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
1114 CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_s_sqrt, &
1115 0.0_dp, matrix_tmp2, filter_eps=ls_scf_env%eps_filter)
1116 WRITE (title, '(A,I3,A)') "sqrt(S) * P(", ispin, ") * sqrt(S)"
1117 CALL report_matrix_sparsity(matrix_tmp2, unit_nr, title, ls_scf_env%eps_filter)
1118 END DO
1119
1120 END IF
1121
1122 CALL dbcsr_release(matrix_tmp1)
1123 CALL dbcsr_release(matrix_tmp2)
1124
1125 CALL timestop(handle)
1126
1127 END SUBROUTINE post_scf_sparsities
1128
1129! **************************************************************************************************
1130!> \brief Helper routine to report on the sparsity of a single matrix,
1131!> for several filtering values
1132!> \param matrix ...
1133!> \param unit_nr ...
1134!> \param title ...
1135!> \param eps ...
1136!> \par History
1137!> 2010.10 created [Joost VandeVondele]
1138!> \author Joost VandeVondele
1139! **************************************************************************************************
1140 SUBROUTINE report_matrix_sparsity(matrix, unit_nr, title, eps)
1141 TYPE(dbcsr_type) :: matrix
1142 INTEGER :: unit_nr
1143 CHARACTER(LEN=*) :: title
1144 REAL(kind=dp) :: eps
1145
1146 CHARACTER(len=*), PARAMETER :: routinen = 'report_matrix_sparsity'
1147
1148 INTEGER :: handle
1149 REAL(kind=dp) :: eps_local, occ
1150 TYPE(dbcsr_type) :: matrix_tmp
1151
1152 CALL timeset(routinen, handle)
1153 CALL dbcsr_create(matrix_tmp, template=matrix, name=trim(title))
1154 CALL dbcsr_copy(matrix_tmp, matrix, name=trim(title))
1155
1156 IF (unit_nr > 0) THEN
1157 WRITE (unit_nr, '(T2,A)') "Sparsity for : "//trim(title)
1158 END IF
1159
1160 eps_local = max(eps, 10e-14_dp)
1161 DO
1162 IF (eps_local > 1.1_dp) EXIT
1163 CALL dbcsr_filter(matrix_tmp, eps_local)
1164 occ = dbcsr_get_occupation(matrix_tmp)
1165 IF (unit_nr > 0) WRITE (unit_nr, '(T2,F16.12,A3,F16.12)') eps_local, " : ", occ
1166 eps_local = eps_local*10
1167 END DO
1168
1169 CALL dbcsr_release(matrix_tmp)
1170
1171 CALL timestop(handle)
1172
1173 END SUBROUTINE report_matrix_sparsity
1174
1175! **************************************************************************************************
1176!> \brief Compute matrix_w as needed for the forces
1177!> \param matrix_w ...
1178!> \param ls_scf_env ...
1179!> \par History
1180!> 2010.11 created [Joost VandeVondele]
1181!> \author Joost VandeVondele
1182! **************************************************************************************************
1183 SUBROUTINE calculate_w_matrix_ls(matrix_w, ls_scf_env)
1184 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_w
1185 TYPE(ls_scf_env_type) :: ls_scf_env
1186
1187 CHARACTER(len=*), PARAMETER :: routinen = 'calculate_w_matrix_ls'
1188
1189 INTEGER :: handle, ispin
1190 REAL(kind=dp) :: scaling
1191 TYPE(dbcsr_type) :: matrix_tmp1, matrix_tmp2, matrix_tmp3
1192
1193 CALL timeset(routinen, handle)
1194
1195 CALL dbcsr_create(matrix_tmp1, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
1196 CALL dbcsr_create(matrix_tmp2, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
1197 CALL dbcsr_create(matrix_tmp3, template=ls_scf_env%matrix_s, matrix_type=dbcsr_type_no_symmetry)
1198
1199 IF (ls_scf_env%nspins == 1) THEN
1200 scaling = 0.5_dp
1201 ELSE
1202 scaling = 1.0_dp
1203 END IF
1204
1205 DO ispin = 1, ls_scf_env%nspins
1206
1207 CALL dbcsr_copy(matrix_tmp3, ls_scf_env%matrix_ks(ispin))
1208 IF (ls_scf_env%has_s_preconditioner) THEN
1209 CALL apply_matrix_preconditioner(matrix_tmp3, "backward", &
1210 ls_scf_env%matrix_bs_sqrt, ls_scf_env%matrix_bs_sqrt_inv)
1211 END IF
1212 CALL dbcsr_filter(matrix_tmp3, ls_scf_env%eps_filter)
1213
1214 CALL dbcsr_multiply("N", "N", scaling, ls_scf_env%matrix_p(ispin), matrix_tmp3, &
1215 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
1216 CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_p(ispin), &
1217 0.0_dp, matrix_tmp2, filter_eps=ls_scf_env%eps_filter)
1218 CALL matrix_ls_to_qs(matrix_w(ispin)%matrix, matrix_tmp2, ls_scf_env%ls_mstruct, covariant=.false.)
1219 END DO
1220
1221 CALL dbcsr_release(matrix_tmp1)
1222 CALL dbcsr_release(matrix_tmp2)
1223 CALL dbcsr_release(matrix_tmp3)
1224
1225 CALL timestop(handle)
1226
1227 END SUBROUTINE calculate_w_matrix_ls
1228
1229! **************************************************************************************************
1230!> \brief a place for quick experiments
1231!> \par History
1232!> 2010.11 created [Joost VandeVondele]
1233!> \author Joost VandeVondele
1234! **************************************************************************************************
1235 SUBROUTINE post_scf_experiment()
1236
1237 CHARACTER(len=*), PARAMETER :: routinen = 'post_scf_experiment'
1238
1239 INTEGER :: handle, unit_nr
1240 TYPE(cp_logger_type), POINTER :: logger
1241
1242 CALL timeset(routinen, handle)
1243
1244 ! get a useful output_unit
1245 logger => cp_get_default_logger()
1246 IF (logger%para_env%is_source()) THEN
1247 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
1248 ELSE
1249 unit_nr = -1
1250 END IF
1251
1252 CALL timestop(handle)
1253 END SUBROUTINE post_scf_experiment
1254
1255END MODULE dm_ls_scf
arnoldi iteration using dbcsr
Definition arnoldi_api.F:15
subroutine, public arnoldi_extremal(matrix_a, max_ev, min_ev, converged, threshold, max_iter)
simple wrapper to estimate extremal eigenvalues with arnoldi, using the old lanczos interface this hi...
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public kuhne2007
integer, save, public kolafa2004
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
Routines to handle the external control of CP2K.
subroutine, public external_control(should_stop, flag, globenv, target_time, start_time, force_check)
External manipulations during a run : when the <PROJECT_NAME>.EXIT_$runtype command is sent the progr...
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
Routines using linear scaling chebyshev methods.
subroutine, public compute_chebyshev(qs_env, ls_scf_env)
compute properties based on chebyshev expansion
density matrix optimization using exponential transformations
subroutine, public dm_ls_curvy_optimization(ls_scf_env, energy, check_conv)
driver routine for Head-Gordon curvy step approach
subroutine, public deallocate_curvy_data(curvy_data)
...
lower level routines for linear scaling SCF
subroutine, public ls_scf_init_matrix_s(matrix_s, ls_scf_env)
initialize S matrix related properties (sqrt, inverse...) Might be factored-out since this seems comm...
subroutine, public density_matrix_sign_fixed_mu(matrix_p, trace, mu, sign_method, sign_order, matrix_ks, matrix_s, matrix_s_inv, threshold, sign_symmetric, submatrix_sign_method, matrix_s_sqrt_inv)
for a fixed mu, compute the corresponding density matrix and its trace
subroutine, public apply_matrix_preconditioner(matrix, direction, matrix_bs_sqrt, matrix_bs_sqrt_inv)
apply a preconditioner either forward (precondition) inv(sqrt(bs)) * A * inv(sqrt(bs)) backward (rest...
subroutine, public density_matrix_sign(matrix_p, mu, fixed_mu, sign_method, sign_order, matrix_ks, matrix_s, matrix_s_inv, nelectron, threshold, sign_symmetric, submatrix_sign_method, matrix_s_sqrt_inv)
compute the density matrix with a trace that is close to nelectron. take a mu as input,...
subroutine, public compute_homo_lumo(matrix_k, matrix_p, eps_min, eps_max, threshold, max_iter_lanczos, eps_lanczos, homo, lumo, unit_nr)
compute the homo and lumo given a KS matrix and a density matrix in the orthonormalized basis and the...
subroutine, public density_matrix_trs4(matrix_p, matrix_ks, matrix_s_sqrt_inv, nelectron, threshold, e_homo, e_lumo, e_mu, dynamic_threshold, matrix_ks_deviation, max_iter_lanczos, eps_lanczos, converged)
compute the density matrix using a trace-resetting algorithm
subroutine, public density_matrix_tc2(matrix_p, matrix_ks, matrix_s_sqrt_inv, nelectron, threshold, e_homo, e_lumo, non_monotonic, eps_lanczos, max_iter_lanczos)
compute the density matrix using a non monotonic trace conserving algorithm based on SIAM DOI....
Routines for a linear scaling quickstep SCF run based on the density matrix, with a focus on the inte...
subroutine, public matrix_ls_to_qs(matrix_qs, matrix_ls, ls_mstruct, covariant, keep_sparsity)
second link to QS, copy a LS matrix to QS matrix used to isolate QS style matrices from LS style will...
subroutine, public ls_scf_dm_to_ks(qs_env, ls_scf_env, energy_new, iscf)
use the density matrix in ls_scf_env to compute the new energy and KS matrix
subroutine, public rho_mixing_ls_init(qs_env, ls_scf_env)
Initialize g-space density mixing.
subroutine, public matrix_ls_create(matrix_ls, matrix_qs, ls_mstruct)
create a matrix for use (and as a template) in ls based on a qs template
subroutine, public matrix_qs_to_ls(matrix_ls, matrix_qs, ls_mstruct, covariant)
first link to QS, copy a QS matrix to LS matrix used to isolate QS style matrices from LS style will ...
subroutine, public ls_scf_init_qs(qs_env)
further required initialization of QS. Might be factored-out since this seems common code with the ot...
subroutine, public ls_scf_qs_atomic_guess(qs_env, energy)
get an atomic initial guess
Types needed for a linear scaling quickstep SCF run based on the density matrix.
Routines for a linear scaling quickstep SCF run based on the density matrix.
Definition dm_ls_scf.F:15
subroutine, public post_scf_sparsities(ls_scf_env)
Report on the sparsities of various interesting matrices.
Definition dm_ls_scf.F:1027
subroutine, public calculate_w_matrix_ls(matrix_w, ls_scf_env)
Compute matrix_w as needed for the forces.
Definition dm_ls_scf.F:1184
subroutine, public ls_scf(qs_env)
perform an linear scaling scf procedure: entry point
Definition dm_ls_scf.F:108
Types needed for a for a Energy Correction.
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public atomic_guess
integer, parameter, public ls_scf_pexsi
integer, parameter, public ls_scf_trs4
integer, parameter, public ls_scf_sign
integer, parameter, public ls_scf_tc2
integer, parameter, public transport_transmission
integer, parameter, public restart_guess
integer, parameter, public ls_cluster_atomic
objects that represent the structure of input sections and the data contained in an input section
Routines useful for iterative matrix calculations.
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
integer, parameter, public default_path_length
Definition kinds.F:58
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition machine.F:106
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition machine.F:123
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
elemental real(kind=dp) function, public binomial(n, k)
The binomial coefficient n over k for 0 <= k <= n is calculated, otherwise zero is returned.
Definition mathlib.F:205
Define the data structure for the molecule information.
Main module for the PAO method.
Definition pao_main.F:12
subroutine, public pao_post_scf(qs_env, ls_scf_env, pao_is_done)
Calculate PAO forces and store density matrix for future ASPC extrapolations.
Definition pao_main.F:316
subroutine, public pao_update(qs_env, ls_scf_env, pao_is_done)
Called after the SCF optimization, updates the PAO basis.
Definition pao_main.F:185
subroutine, public pao_optimization_end(ls_scf_env)
Finish a PAO optimization run.
Definition pao_main.F:345
subroutine, public pao_optimization_start(qs_env, ls_scf_env)
Start a PAO optimization run.
Definition pao_main.F:108
Methods using the PEXSI library to calculate the density matrix and related quantities using the Kohn...
subroutine, public pexsi_to_qs(ls_scf_env, qs_env, kts, matrix_w)
Pass energy weighted density matrix and entropic energy contribution to QS environment.
subroutine, public density_matrix_pexsi(pexsi_env, matrix_p, matrix_w, kts, matrix_ks, matrix_s, nelectron_exact, mu, iscf, ispin)
Calculate density matrix, energy-weighted density matrix and entropic energy contribution with the DF...
subroutine, public pexsi_finalize_scf(pexsi_env, mu_spin)
Deallocations and post-processing after SCF.
subroutine, public pexsi_init_scf(ks_env, pexsi_env, template_matrix)
Initializations needed before SCF.
subroutine, public pexsi_set_convergence_tolerance(pexsi_env, delta_scf, eps_scf, initialize, check_convergence)
Set PEXSI convergence tolerance (numElectronPEXSITolerance), adapted to the convergence error of the ...
buffer for the diis of the scf
subroutine, public qs_diis_b_release_sparse(diis_buffer)
releases the given diis buffer (see doc/ReferenceCounting.html)
Apply the direct inversion in the iterative subspace (DIIS) of Pulay in the framework of an SCF itera...
Definition qs_diis.F:21
pure subroutine, public qs_diis_b_create_sparse(diis_buffer, nbuffer)
Allocates an SCF DIIS buffer for LS-SCF calculation.
Definition qs_diis.F:847
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:544
pure subroutine, public qs_diis_b_clear_sparse(diis_buffer)
clears the DIIS buffer in LS-SCF calculation
Definition qs_diis.F:831
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_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, 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, rhs)
Get the QUICKSTEP environment.
Does all kind of post scf calculations for GPW/GAPW.
subroutine, public write_mo_free_results(qs_env)
Write QS results always available (if switched on through the print_keys) Can be called from ls_scf.
subroutine, public qs_scf_post_moments(input, logger, qs_env, output_unit)
Computes and prints electric moments.
Does all kind of post scf calculations for DFTB.
subroutine, public scf_post_calculation_tb(qs_env, tb_type, no_mos)
collects possible post - scf calculations and prints info / computes properties.
CP2K transport environment and related C-interoperable types.
routines for DFT+NEGF calculations (coupling with the quantum transport code OMEN)
Definition transport.F:19
subroutine, public external_scf_method(transport_env, matrix_s, matrix_ks, matrix_p, nelectron_spin, natoms, energy_diff, iscf, extra_scf)
SCF calcualtion with an externally evaluated density matrix.
Definition transport.F:369
subroutine, public transport_initialize(ks_env, transport_env, template_matrix)
initializes the transport environment
Definition transport.F:290
type of a logger, at the moment it contains just a print level starting at which level it should be l...
Contains information on the energy correction functional for KG.
build array of pointers to diis buffers for sparse matrix case
calculation environment to calculate the ks matrix, holds all the needed vars. assumes that the core ...