(git:e7e05ae)
qs_mom_methods.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 methods for deltaSCF calculations
10 ! **************************************************************************************************
12  USE bibliography, ONLY: barca2018,&
13  gilbert2008,&
14  cite_reference
15  USE cp_blacs_env, ONLY: cp_blacs_env_type
20  cp_fm_struct_type
21  USE cp_fm_types, ONLY: cp_fm_create,&
24  cp_fm_to_fm,&
25  cp_fm_type,&
28  USE dbcsr_api, ONLY: dbcsr_p_type
29  USE input_constants, ONLY: momproj_norm,&
30  momproj_sum,&
31  momtype_imom,&
33  USE input_section_types, ONLY: section_vals_type
34  USE kinds, ONLY: dp
35  USE parallel_gemm_api, ONLY: parallel_gemm
36  USE qs_density_matrices, ONLY: calculate_density_matrix
37  USE qs_mo_types, ONLY: get_mo_set,&
38  mo_set_type,&
41  USE qs_scf_types, ONLY: qs_scf_env_type
42  USE scf_control_types, ONLY: scf_control_type
44  USE util, ONLY: sort,&
45  sort_unique
46 #include "./base/base_uses.f90"
47 
48  IMPLICIT NONE
49 
50  PRIVATE
51 
52  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_mom_methods'
53 
54  PUBLIC :: do_mom_guess, do_mom_diag
55  PRIVATE :: mom_is_unique_orbital_indices, mom_reoccupy_orbitals
56 
57 CONTAINS
58 
59 ! **************************************************************************************************
60 !> \brief check that every molecular orbital index appears only once in each
61 !> (de-)occupation list supplied by user. Check that all the indices
62 !> are positive integers and abort if it is not the case.
63 !> \param iarr list of molecular orbital indices to be checked
64 !> \return .true. if all the elements are unique or the list contains
65 !> exactly one 0 element (meaning no excitation)
66 !> \par History
67 !> 01.2016 created [Sergey Chulkov]
68 ! **************************************************************************************************
69  FUNCTION mom_is_unique_orbital_indices(iarr) RESULT(is_unique)
70  INTEGER, DIMENSION(:), POINTER :: iarr
71  LOGICAL :: is_unique
72 
73  CHARACTER(len=*), PARAMETER :: routineN = 'mom_is_unique_orbital_indices'
74 
75  INTEGER :: handle, norbs
76  INTEGER, DIMENSION(:), POINTER :: tmp_iarr
77 
78  CALL timeset(routinen, handle)
79 
80  cpassert(ASSOCIATED(iarr))
81  norbs = SIZE(iarr)
82 
83  IF (norbs > 0) THEN
84  ALLOCATE (tmp_iarr(norbs))
85 
86  tmp_iarr(:) = iarr(:)
87  CALL sort_unique(tmp_iarr, is_unique)
88 
89  ! Ensure that all orbital indices are positive integers.
90  ! A special value '0' means 'disabled keyword',
91  ! it must appear once to be interpreted in such a way
92  IF (tmp_iarr(1) < 0 .OR. (tmp_iarr(1) == 0 .AND. norbs > 1)) &
93  cpabort("MOM: all molecular orbital indices must be positive integer numbers")
94 
95  DEALLOCATE (tmp_iarr)
96  END IF
97 
98  is_unique = .true.
99 
100  CALL timestop(handle)
101 
102  END FUNCTION mom_is_unique_orbital_indices
103 
104 ! **************************************************************************************************
105 !> \brief swap occupation numbers between molecular orbitals
106 !> from occupation and de-occupation lists
107 !> \param mo_set set of molecular orbitals
108 !> \param deocc_orb_set list of de-occupied orbital indices
109 !> \param occ_orb_set list of newly occupied orbital indices
110 !> \param spin spin component of the molecular orbitals;
111 !> to be used for diagnostic messages
112 !> \par History
113 !> 01.2016 created [Sergey Chulkov]
114 ! **************************************************************************************************
115  SUBROUTINE mom_reoccupy_orbitals(mo_set, deocc_orb_set, occ_orb_set, spin)
116  TYPE(mo_set_type), INTENT(INOUT) :: mo_set
117  INTEGER, DIMENSION(:), POINTER :: deocc_orb_set, occ_orb_set
118  CHARACTER(len=*), INTENT(in) :: spin
119 
120  CHARACTER(len=*), PARAMETER :: routineN = 'mom_reoccupy_orbitals'
121 
122  CHARACTER(len=10) :: str_iorb, str_norbs
123  CHARACTER(len=3) :: str_prefix
124  INTEGER :: handle, homo, iorb, lfomo, nao, nmo, &
125  norbs
126  REAL(kind=dp) :: maxocc
127  REAL(kind=dp), DIMENSION(:), POINTER :: occ_nums
128 
129  CALL timeset(routinen, handle)
130 
131  ! MOM electron excitation should preserve both the number of electrons and
132  ! multiplicity of the electronic system thus ensuring the following constraint :
133  ! norbs = SIZE(deocc_orb_set) == SIZE(occ_orb_set)
134  norbs = SIZE(deocc_orb_set)
135 
136  ! the following assertion should never raise an exception
137  cpassert(SIZE(deocc_orb_set) == SIZE(occ_orb_set))
138 
139  ! MOM does not follow aufbau principle producing non-uniformly occupied orbitals
140  CALL set_mo_set(mo_set=mo_set, uniform_occupation=.false.)
141 
142  IF (deocc_orb_set(1) /= 0 .AND. occ_orb_set(1) /= 0) THEN
143  CALL get_mo_set(mo_set=mo_set, maxocc=maxocc, &
144  nao=nao, nmo=nmo, occupation_numbers=occ_nums)
145 
146  IF (deocc_orb_set(norbs) > nao .OR. occ_orb_set(norbs) > nao) THEN
147  ! STOP: one of the molecular orbital index exceeds the number of atomic basis functions available
148  CALL integer_to_string(nao, str_norbs)
149 
150  IF (deocc_orb_set(norbs) >= occ_orb_set(norbs)) THEN
151  iorb = deocc_orb_set(norbs)
152  str_prefix = 'de-'
153  ELSE
154  iorb = occ_orb_set(norbs)
155  str_prefix = ''
156  END IF
157  CALL integer_to_string(iorb, str_iorb)
158 
159  CALL cp_abort(__location__, "Unable to "//trim(str_prefix)//"occupy "// &
160  trim(spin)//" orbital No. "//trim(str_iorb)// &
161  " since its index exceeds the number of atomic orbital functions available ("// &
162  trim(str_norbs)//"). Please consider using a larger basis set.")
163  END IF
164 
165  IF (deocc_orb_set(norbs) > nmo .OR. occ_orb_set(norbs) > nmo) THEN
166  ! STOP: one of the molecular orbital index exceeds the number of constructed molecular orbitals
167  IF (deocc_orb_set(norbs) >= occ_orb_set(norbs)) THEN
168  iorb = deocc_orb_set(norbs)
169  ELSE
170  iorb = occ_orb_set(norbs)
171  END IF
172 
173  IF (iorb - nmo > 1) THEN
174  CALL integer_to_string(iorb - nmo, str_iorb)
175  str_prefix = 's'
176  ELSE
177  str_iorb = 'an'
178  str_prefix = ''
179  END IF
180 
181  CALL integer_to_string(nmo, str_norbs)
182 
183  CALL cp_abort(__location__, "The number of molecular orbitals ("//trim(str_norbs)// &
184  ") is not enough to perform MOM calculation. Please add "// &
185  trim(str_iorb)//" extra orbital"//trim(str_prefix)// &
186  " using the ADDED_MOS keyword in the SCF section of your input file.")
187  END IF
188 
189  DO iorb = 1, norbs
190  ! swap occupation numbers between two adjoint molecular orbitals
191  IF (occ_nums(deocc_orb_set(iorb)) <= 0.0_dp) THEN
192  CALL integer_to_string(deocc_orb_set(iorb), str_iorb)
193 
194  CALL cp_abort(__location__, "The "//trim(spin)//" orbital No. "// &
195  trim(str_iorb)//" is not occupied thus it cannot be deoccupied.")
196  END IF
197 
198  IF (occ_nums(occ_orb_set(iorb)) > 0.0_dp) THEN
199  CALL integer_to_string(occ_orb_set(iorb), str_iorb)
200 
201  CALL cp_abort(__location__, "The "//trim(spin)//" orbital No. "// &
202  trim(str_iorb)//" is already occupied thus it cannot be reoccupied.")
203  END IF
204 
205  occ_nums(occ_orb_set(iorb)) = occ_nums(deocc_orb_set(iorb))
206  occ_nums(deocc_orb_set(iorb)) = 0.0_dp
207  END DO
208 
209  ! locate the lowest non-maxocc occupied orbital
210  DO lfomo = 1, nmo
211  IF (occ_nums(lfomo) /= maxocc) EXIT
212  END DO
213 
214  ! locate the highest occupied orbital
215  DO homo = nmo, 1, -1
216  IF (occ_nums(homo) > 0.0_dp) EXIT
217  END DO
218 
219  CALL set_mo_set(mo_set=mo_set, homo=homo, lfomo=lfomo)
220 
221  ELSE IF (deocc_orb_set(1) /= 0 .OR. occ_orb_set(1) /= 0) THEN
222  CALL cp_abort(__location__, &
223  "Incorrect multiplicity of the MOM reference electronic state")
224  END IF
225 
226  CALL timestop(handle)
227 
228  END SUBROUTINE mom_reoccupy_orbitals
229 
230 ! **************************************************************************************************
231 !> \brief initial guess for the maximum overlap method
232 !> \param nspins number of spin components
233 !> \param mos array of molecular orbitals
234 !> \param scf_control SCF control variables
235 !> \param p_rmpv density matrix to be computed
236 !> \par History
237 !> * 01.2016 created [Sergey Chulkov]
238 ! **************************************************************************************************
239  SUBROUTINE do_mom_guess(nspins, mos, scf_control, p_rmpv)
240  INTEGER, INTENT(in) :: nspins
241  TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
242  TYPE(scf_control_type), POINTER :: scf_control
243  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: p_rmpv
244 
245  CHARACTER(len=*), PARAMETER :: routinen = 'do_mom_guess'
246 
247  CHARACTER(len=10) :: str_iter
248  INTEGER :: handle, ispin, scf_iter
249  LOGICAL :: is_mo
250  REAL(kind=dp) :: maxa
251  TYPE(cp_fm_type), POINTER :: mo_coeff
252 
253  CALL timeset(routinen, handle)
254 
255  ! we are about to initialise the maximum overlap method,
256  ! so cite the relevant reference first
257  IF (scf_control%diagonalization%mom_type == momtype_mom) THEN
258  CALL cite_reference(gilbert2008)
259  ELSE IF (scf_control%diagonalization%mom_type == momtype_imom) THEN
260  CALL cite_reference(barca2018)
261  END IF
262 
263  ! ensure we do not have duplicated orbital indices
264  IF (.NOT. &
265  (mom_is_unique_orbital_indices(scf_control%diagonalization%mom_deoccA) .AND. &
266  mom_is_unique_orbital_indices(scf_control%diagonalization%mom_deoccB) .AND. &
267  mom_is_unique_orbital_indices(scf_control%diagonalization%mom_occA) .AND. &
268  mom_is_unique_orbital_indices(scf_control%diagonalization%mom_occB))) &
269  CALL cp_abort(__location__, &
270  "Duplicate orbital indices were found in the MOM section")
271 
272  ! ignore beta orbitals for spin-unpolarized calculations
273  IF (nspins == 1 .AND. (scf_control%diagonalization%mom_deoccB(1) /= 0 &
274  .OR. scf_control%diagonalization%mom_occB(1) /= 0)) THEN
275 
276  CALL cp_warn(__location__, "Maximum overlap method will"// &
277  " ignore beta orbitals since neither UKS nor ROKS calculation is performed")
278  END IF
279 
280  ! compute the change in multiplicity and number of electrons
281  IF (SIZE(scf_control%diagonalization%mom_deoccA) /= &
282  SIZE(scf_control%diagonalization%mom_occA) .OR. &
283  (nspins > 1 .AND. &
284  SIZE(scf_control%diagonalization%mom_deoccB) /= &
285  SIZE(scf_control%diagonalization%mom_occB))) THEN
286 
287  CALL cp_abort(__location__, "Incorrect multiplicity of the MOM reference"// &
288  " electronic state or inconsistent number of electrons")
289  END IF
290 
291  is_mo = .false.
292  ! by default activate MOM at the second SCF iteration as the
293  ! 'old' molecular orbitals are unavailable from the very beginning
294  scf_iter = 2
295  ! check if the molecular orbitals are actually there
296  ! by finding at least one MO coefficient > 0
297  DO ispin = 1, nspins
298  CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff)
299  CALL cp_fm_maxabsval(mo_coeff, maxa)
300  ! is_mo |= maxa > 0.0_dp
301  IF (maxa > 0.0_dp) THEN
302  is_mo = .true.
303  ! we already have the molecular orbitals (e.g. from a restart file);
304  ! activate MOM immediately if the input keyword START_ITER is not given
305  scf_iter = 1
306  EXIT
307  END IF
308  END DO
309 
310  ! proceed alpha orbitals
311  IF (nspins >= 1) &
312  CALL mom_reoccupy_orbitals(mos(1), &
313  scf_control%diagonalization%mom_deoccA, &
314  scf_control%diagonalization%mom_occA, 'alpha')
315 
316  ! proceed beta orbitals (if any)
317  IF (nspins >= 2) &
318  CALL mom_reoccupy_orbitals(mos(2), &
319  scf_control%diagonalization%mom_deoccB, &
320  scf_control%diagonalization%mom_occB, 'beta')
321 
322  ! recompute the density matrix if the molecular orbitals are here;
323  ! otherwise do nothing to prevent zeroing out the density matrix
324  ! obtained from atomic guess
325  IF (is_mo) THEN
326  DO ispin = 1, nspins
327  CALL calculate_density_matrix(mos(ispin), p_rmpv(ispin)%matrix)
328  END DO
329  END IF
330 
331  ! adjust the start SCF iteration number if needed
332  IF (scf_control%diagonalization%mom_start < scf_iter) THEN
333  IF (scf_control%diagonalization%mom_start > 0) THEN
334  ! inappropriate iteration number has been provided through the input file;
335  ! fix it and issue a warning message
336  CALL integer_to_string(scf_iter, str_iter)
337  CALL cp_warn(__location__, &
338  "The maximum overlap method will be activated at the SCF iteration No. "// &
339  trim(str_iter)//" due to the SCF guess method used.")
340  END IF
341  scf_control%diagonalization%mom_start = scf_iter
342  ELSE IF (scf_control%diagonalization%mom_start > scf_iter .AND. &
343  (scf_control%diagonalization%mom_occA(1) > 0 .OR. scf_control%diagonalization%mom_occB(1) > 0)) THEN
344  ! the keyword START_ITER has been provided for an excited state calculation, ignore it
345  CALL integer_to_string(scf_iter, str_iter)
346  CALL cp_warn(__location__, &
347  "The maximum overlap method will be activated at the SCF iteration No. "// &
348  trim(str_iter)//" because an excited state calculation has been requested")
349  scf_control%diagonalization%mom_start = scf_iter
350  END IF
351 
352  ! MOM is now initialised properly
353  scf_control%diagonalization%mom_didguess = .true.
354 
355  CALL timestop(handle)
356 
357  END SUBROUTINE do_mom_guess
358 
359 ! **************************************************************************************************
360 !> \brief do an SCF iteration, then compute occupation numbers of the new
361 !> molecular orbitals according to their overlap with the previous ones
362 !> \param scf_env SCF environment information
363 !> \param mos array of molecular orbitals
364 !> \param matrix_ks sparse Kohn-Sham matrix
365 !> \param matrix_s sparse overlap matrix
366 !> \param scf_control SCF control variables
367 !> \param scf_section SCF input section
368 !> \param diis_step have we done a DIIS step
369 !> \par History
370 !> * 07.2014 created [Matt Watkins]
371 !> * 01.2016 release version [Sergey Chulkov]
372 !> * 03.2018 initial maximum overlap method [Sergey Chulkov]
373 ! **************************************************************************************************
374  SUBROUTINE do_mom_diag(scf_env, mos, matrix_ks, matrix_s, scf_control, scf_section, diis_step)
375  TYPE(qs_scf_env_type), POINTER :: scf_env
376  TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
377  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
378  TYPE(scf_control_type), POINTER :: scf_control
379  TYPE(section_vals_type), POINTER :: scf_section
380  LOGICAL, INTENT(INOUT) :: diis_step
381 
382  CHARACTER(len=*), PARAMETER :: routinen = 'do_mom_diag'
383 
384  INTEGER :: handle, homo, iproj, ispin, lfomo, nao, &
385  nmo, nspins
386  INTEGER, ALLOCATABLE, DIMENSION(:) :: inds
387  REAL(kind=dp) :: maxocc
388  REAL(kind=dp), DIMENSION(:), POINTER :: occ_nums, proj, tmp_occ_nums
389  TYPE(cp_blacs_env_type), POINTER :: blacs_env
390  TYPE(cp_fm_struct_type), POINTER :: ao_mo_fmstruct, mo_mo_fmstruct
391  TYPE(cp_fm_type), POINTER :: mo_coeff, mo_coeff_ref, overlap, svec
392 
393  CALL timeset(routinen, handle)
394 
395  IF (.NOT. scf_control%diagonalization%mom_didguess) &
396  CALL cp_abort(__location__, &
397  "The current implementation of the maximum overlap method is incompatible with the initial SCF guess")
398 
399  ! number of spins == dft_control%nspins
400  nspins = SIZE(matrix_ks)
401 
402  ! copy old molecular orbitals
403  IF (scf_env%iter_count >= scf_control%diagonalization%mom_start) THEN
404  IF (.NOT. ASSOCIATED(scf_env%mom_ref_mo_coeff)) THEN
405  ALLOCATE (scf_env%mom_ref_mo_coeff(nspins))
406  DO ispin = 1, nspins
407  NULLIFY (ao_mo_fmstruct)
408  CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, occupation_numbers=occ_nums)
409  CALL cp_fm_get_info(mo_coeff, matrix_struct=ao_mo_fmstruct)
410  CALL cp_fm_create(scf_env%mom_ref_mo_coeff(ispin), ao_mo_fmstruct)
411 
412  ! Initial Maximum Overlap Method: keep initial molecular orbitals
413  IF (scf_control%diagonalization%mom_type == momtype_imom) THEN
414  CALL cp_fm_to_fm(mo_coeff, scf_env%mom_ref_mo_coeff(ispin))
415  CALL cp_fm_column_scale(scf_env%mom_ref_mo_coeff(ispin), occ_nums)
416  END IF
417  END DO
418  END IF
419 
420  ! allocate the molecular orbitals overlap matrix
421  IF (.NOT. ASSOCIATED(scf_env%mom_overlap)) THEN
422  ALLOCATE (scf_env%mom_overlap(nspins))
423  DO ispin = 1, nspins
424  NULLIFY (blacs_env, mo_mo_fmstruct)
425  CALL get_mo_set(mo_set=mos(ispin), nmo=nmo, mo_coeff=mo_coeff)
426  CALL cp_fm_get_info(mo_coeff, context=blacs_env)
427  CALL cp_fm_struct_create(mo_mo_fmstruct, nrow_global=nmo, ncol_global=nmo, context=blacs_env)
428  CALL cp_fm_create(scf_env%mom_overlap(ispin), mo_mo_fmstruct)
429  CALL cp_fm_struct_release(mo_mo_fmstruct)
430  END DO
431  END IF
432 
433  ! allocate a matrix to store the product S * mo_coeff
434  IF (.NOT. ASSOCIATED(scf_env%mom_s_mo_coeff)) THEN
435  ALLOCATE (scf_env%mom_s_mo_coeff(nspins))
436  DO ispin = 1, nspins
437  NULLIFY (ao_mo_fmstruct)
438  CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff)
439  CALL cp_fm_get_info(mo_coeff, matrix_struct=ao_mo_fmstruct)
440  CALL cp_fm_create(scf_env%mom_s_mo_coeff(ispin), ao_mo_fmstruct)
441  END DO
442  END IF
443 
444  ! Original Maximum Overlap Method: keep orbitals from the previous SCF iteration
445  IF (scf_control%diagonalization%mom_type == momtype_mom) THEN
446  DO ispin = 1, nspins
447  CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, occupation_numbers=occ_nums)
448  CALL cp_fm_to_fm(mo_coeff, scf_env%mom_ref_mo_coeff(ispin))
449  CALL cp_fm_column_scale(scf_env%mom_ref_mo_coeff(ispin), occ_nums)
450  END DO
451  END IF
452  END IF
453 
454  ! solve the eigenproblem
455  CALL general_eigenproblem(scf_env, mos, matrix_ks, matrix_s, scf_control, scf_section, diis_step)
456 
457  IF (scf_env%iter_count >= scf_control%diagonalization%mom_start) THEN
458  DO ispin = 1, nspins
459 
460  ! TO DO: sparse-matrix variant; check if use_mo_coeff_b is set, and if yes use mo_coeff_b instead
461  CALL get_mo_set(mo_set=mos(ispin), maxocc=maxocc, mo_coeff=mo_coeff, &
462  nao=nao, nmo=nmo, occupation_numbers=occ_nums)
463 
464  mo_coeff_ref => scf_env%mom_ref_mo_coeff(ispin)
465  overlap => scf_env%mom_overlap(ispin)
466  svec => scf_env%mom_s_mo_coeff(ispin)
467 
468  ! svec = S * C(new)
469  CALL cp_dbcsr_sm_fm_multiply(matrix_s(1)%matrix, mo_coeff, svec, nmo)
470 
471  ! overlap = C(reference occupied)^T * S * C(new)
472  CALL parallel_gemm('T', 'N', nmo, nmo, nao, 1.0_dp, mo_coeff_ref, svec, 0.0_dp, overlap)
473 
474  ALLOCATE (proj(nmo))
475  ALLOCATE (inds(nmo))
476  ALLOCATE (tmp_occ_nums(nmo))
477 
478  ! project the new molecular orbitals into the space of the reference occupied orbitals
479  SELECT CASE (scf_control%diagonalization%mom_proj_formula)
480  CASE (momproj_sum)
481  ! proj_j = abs( \sum_i overlap(i, j) )
482  CALL cp_fm_vectorssum(overlap, proj)
483 
484  DO iproj = 1, nmo
485  proj(iproj) = abs(proj(iproj))
486  END DO
487 
488  CASE (momproj_norm)
489  ! proj_j = (\sum_i overlap(i, j)**2) ** 0.5
490  CALL cp_fm_vectorsnorm(overlap, proj)
491 
492  CASE DEFAULT
493  cpabort("Unimplemented projection formula")
494  END SELECT
495 
496  tmp_occ_nums(:) = occ_nums(:)
497  ! sort occupation numbers in ascending order
498  CALL sort(tmp_occ_nums, nmo, inds)
499  ! sort overlap projection in ascending order
500  CALL sort(proj, nmo, inds)
501 
502  ! reorder occupation numbers according to overlap projections
503  DO iproj = 1, nmo
504  occ_nums(inds(iproj)) = tmp_occ_nums(iproj)
505  END DO
506 
507  DEALLOCATE (tmp_occ_nums)
508  DEALLOCATE (inds)
509  DEALLOCATE (proj)
510 
511  ! locate the lowest non-fully occupied orbital
512  DO lfomo = 1, nmo
513  IF (occ_nums(lfomo) /= maxocc) EXIT
514  END DO
515 
516  ! locate the highest occupied orbital
517  DO homo = nmo, 1, -1
518  IF (occ_nums(homo) > 0.0_dp) EXIT
519  END DO
520 
521  CALL set_mo_set(mo_set=mos(ispin), homo=homo, lfomo=lfomo)
522  END DO
523  END IF
524 
525  ! recompute density matrix
526  DO ispin = 1, nspins
527  CALL calculate_density_matrix(mos(ispin), scf_env%p_mix_new(ispin, 1)%matrix)
528  END DO
529 
530  CALL timestop(handle)
531 
532  END SUBROUTINE do_mom_diag
533 
534 END MODULE qs_mom_methods
collects all references to literature in CP2K as new algorithms / method are included from literature...
Definition: bibliography.F:28
integer, save, public barca2018
Definition: bibliography.F:43
integer, save, public gilbert2008
Definition: bibliography.F:43
methods related to the blacs parallel environment
Definition: cp_blacs_env.F:15
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm 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)
represent the structure of a full matrix
Definition: cp_fm_struct.F:14
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
Definition: cp_fm_struct.F:125
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
Definition: cp_fm_struct.F:320
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
Definition: cp_fm_types.F:1016
subroutine, public cp_fm_vectorssum(matrix, sum_array, dir)
summing up all the elements along the matrix's i-th index or
Definition: cp_fm_types.F:1252
subroutine, public cp_fm_vectorsnorm(matrix, norm_array)
find the inorm of each column norm_{j}= sqrt( \sum_{i} A_{ij}*A_{ij} )
Definition: cp_fm_types.F:1207
subroutine, public cp_fm_maxabsval(matrix, a_max, ir_max, ic_max)
find the maximum absolute value of the matrix element maxval(abs(matrix))
Definition: cp_fm_types.F:1064
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
Definition: cp_fm_types.F:167
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public momproj_norm
integer, parameter, public momtype_mom
integer, parameter, public momproj_sum
integer, parameter, public momtype_imom
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
basic linear algebra operations for full matrixes
collects routines that calculate density matrices
Definition and initialisation of the mo data type.
Definition: qs_mo_types.F:22
subroutine, public set_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, uniform_occupation, kTS, mu, flexible_electron_count)
Set the components of a MO set data structure.
Definition: qs_mo_types.F:452
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.
Definition: qs_mo_types.F:397
methods for deltaSCF calculations
subroutine, public do_mom_diag(scf_env, mos, matrix_ks, matrix_s, scf_control, scf_section, diis_step)
do an SCF iteration, then compute occupation numbers of the new molecular orbitals according to their...
subroutine, public do_mom_guess(nspins, mos, scf_control, p_rmpv)
initial guess for the maximum overlap method
Different diagonalization schemes that can be used for the iterative solution of the eigenvalue probl...
subroutine, public general_eigenproblem(scf_env, mos, matrix_ks, matrix_s, scf_control, scf_section, diis_step)
the inner loop of scf, specific to diagonalization with S matrix basically, in goes the ks matrix out...
module that contains the definitions of the scf types
Definition: qs_scf_types.F:14
parameters that control an scf iteration
Utilities for string manipulations.
subroutine, public integer_to_string(inumber, string)
Converts an integer number to a string. The WRITE statement will return an error message,...
All kind of helpful little routines.
Definition: util.F:14