(git:0d88fc2)
Loading...
Searching...
No Matches
qs_mo_types.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Definition and initialisation of the mo data type.
10!> \par History
11!> - adapted to the new QS environment data structure (02.04.2002,MK)
12!> - set_mo_occupation added (17.04.02,MK)
13!> - correct_mo_eigenvalues added (18.04.02,MK)
14!> - calculate_density_matrix moved from qs_scf to here (22.04.02,MK)
15!> - mo_set_p_type added (23.04.02,MK)
16!> - PRIVATE attribute set for TYPE mo_set_type (23.04.02,MK)
17!> - started conversion to LSD (1.2003, Joost VandeVondele)
18!> - set_mo_occupation moved to qs_mo_occupation (11.12.14 MI)
19!> - correct_mo_eigenvalues moved to qs_scf_methods (03.2016, Sergey Chulkov)
20!> \author Matthias Krack (09.05.2001,MK)
21! **************************************************************************************************
23
24 USE cp_dbcsr_api, ONLY: dbcsr_copy,&
32 USE cp_fm_types, ONLY: cp_fm_create,&
38 USE kinds, ONLY: dp
39#include "./base/base_uses.f90"
40
41 IMPLICIT NONE
42
43 PRIVATE
44
45 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_mo_types'
46
48 ! The actual MO coefficients as a matrix
49 TYPE(cp_fm_type), POINTER :: mo_coeff => null()
50 TYPE(dbcsr_type), POINTER :: mo_coeff_b => null()
51 ! we are using the dbcsr mo_coeff_b
52 LOGICAL :: use_mo_coeff_b = .false.
53 ! Number of molecular orbitals (# cols in mo_coeff)
54 INTEGER :: nmo = -1
55 ! Number of atomic orbitals (# rows in mo_coeff)
56 INTEGER :: nao = -1
57 ! MO occupation numbers and MO eigenvalues (if eigenstates)
58 REAL(kind=dp), DIMENSION(:), POINTER :: eigenvalues => null(), &
59 occupation_numbers => null()
60 ! Maximum allowed occupation number of an MO, i.e.
61 ! 1 for spin unrestricted (polarized) and 2 for spin restricted
62 REAL(kind=dp) :: maxocc = -1
63 ! Number of electrons (taking occupations into account)
64 INTEGER :: nelectron = -1
65 REAL(kind=dp) :: n_el_f = -1.0_dp
66 ! Highest orbital with non-zero occupation
67 INTEGER :: homo = -1
68 ! lowest non maxocc occupied orbital (e.g. fractional or zero)
69 INTEGER :: lfomo = -1
70 ! True, if all allocated MOs have the same occupation number.
71 ! This is not the case for fractional occupations or for added MOs
72 ! with zero occupation.
73 LOGICAL :: uniform_occupation = .false.
74 ! The entropic energy contribution
75 REAL(kind=dp) :: kts = -1.0_dp
76 ! Fermi energy level
77 REAL(kind=dp) :: mu = 0.0_dp
78 ! Threshold value for multiplicity change
79 REAL(kind=dp) :: flexible_electron_count = -1.0_dp
80 END TYPE mo_set_type
81
83 TYPE(mo_set_type), POINTER :: mo_set => null()
84 END TYPE mo_set_p_type
85
86 PUBLIC :: mo_set_p_type, &
88
89 PUBLIC :: allocate_mo_set, &
92 get_mo_set, &
98
99CONTAINS
100
101! **************************************************************************************************
102!> \brief reassign an already allocated mo_set
103!> \param mo_set_new ...
104!> \param mo_set_old ...
105!> \date 2019-05-16
106!> \par History
107!> \author Soumya Ghosh
108! **************************************************************************************************
109 SUBROUTINE reassign_allocated_mos(mo_set_new, mo_set_old)
110 TYPE(mo_set_type), INTENT(INOUT) :: mo_set_new, mo_set_old
111
112 INTEGER :: nmo
113
114 mo_set_new%maxocc = mo_set_old%maxocc
115 mo_set_new%nelectron = mo_set_old%nelectron
116 mo_set_new%n_el_f = mo_set_old%n_el_f
117 mo_set_new%nao = mo_set_old%nao
118 mo_set_new%nmo = mo_set_old%nmo
119 mo_set_new%homo = mo_set_old%homo
120 mo_set_new%lfomo = mo_set_old%lfomo
121 mo_set_new%uniform_occupation = mo_set_old%uniform_occupation
122 mo_set_new%kTS = mo_set_old%kTS
123 mo_set_new%mu = mo_set_old%mu
124 mo_set_new%flexible_electron_count = mo_set_old%flexible_electron_count
125
126 nmo = mo_set_new%nmo
127
128 CALL cp_fm_to_fm(mo_set_old%mo_coeff, mo_set_new%mo_coeff)
129
130 !IF (ASSOCIATED(mo_set_old%mo_coeff_b)) THEN
131 ! CALL dbcsr_copy(mo_set_new%mo_coeff_b, mo_set_old%mo_coeff_b)
132 !END IF
133 !mo_set_new%use_mo_coeff_b = mo_set_old%use_mo_coeff_b
134
135 mo_set_new%eigenvalues = mo_set_old%eigenvalues
136
137 mo_set_new%occupation_numbers = mo_set_old%occupation_numbers
138
139 END SUBROUTINE reassign_allocated_mos
140
141! **************************************************************************************************
142!> \brief allocate a new mo_set, and copy the old data
143!> \param mo_set_new ...
144!> \param mo_set_old ...
145!> \date 2009-7-19
146!> \par History
147!> \author Joost VandeVondele
148! **************************************************************************************************
149 SUBROUTINE duplicate_mo_set(mo_set_new, mo_set_old)
150 TYPE(mo_set_type), INTENT(OUT) :: mo_set_new
151 TYPE(mo_set_type), INTENT(IN) :: mo_set_old
152
153 INTEGER :: nmo
154
155 mo_set_new%maxocc = mo_set_old%maxocc
156 mo_set_new%nelectron = mo_set_old%nelectron
157 mo_set_new%n_el_f = mo_set_old%n_el_f
158 mo_set_new%nao = mo_set_old%nao
159 mo_set_new%nmo = mo_set_old%nmo
160 mo_set_new%homo = mo_set_old%homo
161 mo_set_new%lfomo = mo_set_old%lfomo
162 mo_set_new%uniform_occupation = mo_set_old%uniform_occupation
163 mo_set_new%kTS = mo_set_old%kTS
164 mo_set_new%mu = mo_set_old%mu
165 mo_set_new%flexible_electron_count = mo_set_old%flexible_electron_count
166
167 nmo = mo_set_new%nmo
168
169 NULLIFY (mo_set_new%mo_coeff)
170 ALLOCATE (mo_set_new%mo_coeff)
171 CALL cp_fm_create(mo_set_new%mo_coeff, mo_set_old%mo_coeff%matrix_struct)
172 CALL cp_fm_to_fm(mo_set_old%mo_coeff, mo_set_new%mo_coeff)
173
174 NULLIFY (mo_set_new%mo_coeff_b)
175 IF (ASSOCIATED(mo_set_old%mo_coeff_b)) THEN
176 CALL dbcsr_init_p(mo_set_new%mo_coeff_b)
177 CALL dbcsr_copy(mo_set_new%mo_coeff_b, mo_set_old%mo_coeff_b)
178 END IF
179 mo_set_new%use_mo_coeff_b = mo_set_old%use_mo_coeff_b
180
181 ALLOCATE (mo_set_new%eigenvalues(nmo))
182 mo_set_new%eigenvalues = mo_set_old%eigenvalues
183
184 ALLOCATE (mo_set_new%occupation_numbers(nmo))
185 mo_set_new%occupation_numbers = mo_set_old%occupation_numbers
186
187 END SUBROUTINE duplicate_mo_set
188
189! **************************************************************************************************
190!> \brief Allocates a mo set and partially initializes it (nao,nmo,nelectron,
191!> and flexible_electron_count are valid).
192!> For the full initialization you need to call init_mo_set
193!> \param mo_set the mo_set to allocate
194!> \param nao number of atom orbitals
195!> \param nmo number of molecular orbitals
196!> \param nelectron number of electrons
197!> \param n_el_f ...
198!> \param maxocc maximum occupation of an orbital (LDA: 2, LSD:1)
199!> \param flexible_electron_count the number of electrons can be changed
200!> \date 15.05.2001
201!> \par History
202!> 11.2002 splitted initialization in two phases [fawzi]
203!> \author Matthias Krack
204! **************************************************************************************************
205 SUBROUTINE allocate_mo_set(mo_set, nao, nmo, nelectron, n_el_f, maxocc, &
206 flexible_electron_count)
207
208 TYPE(mo_set_type), INTENT(INOUT) :: mo_set
209 INTEGER, INTENT(IN) :: nao, nmo, nelectron
210 REAL(kind=dp), INTENT(IN) :: n_el_f, maxocc, flexible_electron_count
211
212 mo_set%maxocc = maxocc
213 mo_set%nelectron = nelectron
214 mo_set%n_el_f = n_el_f
215 mo_set%nao = nao
216 mo_set%nmo = nmo
217 mo_set%homo = 0
218 mo_set%lfomo = 0
219 mo_set%uniform_occupation = .true.
220 mo_set%kTS = 0.0_dp
221 mo_set%mu = 0.0_dp
222 mo_set%flexible_electron_count = flexible_electron_count
223
224 NULLIFY (mo_set%eigenvalues)
225 NULLIFY (mo_set%occupation_numbers)
226 NULLIFY (mo_set%mo_coeff)
227 NULLIFY (mo_set%mo_coeff_b)
228 mo_set%use_mo_coeff_b = .false.
229
230 END SUBROUTINE allocate_mo_set
231
232! **************************************************************************************************
233!> \brief initializes an allocated mo_set.
234!> eigenvalues, mo_coeff, occupation_numbers are valid only
235!> after this call.
236!> \param mo_set the mo_set to initialize
237!> \param fm_pool a pool out which you initialize the mo_set
238!> \param fm_ref a reference matrix from which you initialize the mo_set
239!> \param fm_struct ...
240!> \param name ...
241!> \param counter ...
242!> \par History
243!> 11.2002 revamped [fawzi]
244!> \author Fawzi Mohamed
245! **************************************************************************************************
246 SUBROUTINE init_mo_set(mo_set, fm_pool, fm_ref, fm_struct, name, counter)
247
248 TYPE(mo_set_type), INTENT(INOUT) :: mo_set
249 TYPE(cp_fm_pool_type), INTENT(IN), OPTIONAL :: fm_pool
250 TYPE(cp_fm_type), INTENT(IN), OPTIONAL :: fm_ref
251 TYPE(cp_fm_struct_type), OPTIONAL, POINTER :: fm_struct
252 CHARACTER(LEN=*), INTENT(in) :: name
253 INTEGER, INTENT(INOUT), OPTIONAL :: counter
254
255 INTEGER :: na, nao, nb, nmo, nomo
256
257 cpassert(.NOT. ASSOCIATED(mo_set%eigenvalues))
258 cpassert(.NOT. ASSOCIATED(mo_set%occupation_numbers))
259 cpassert(.NOT. ASSOCIATED(mo_set%mo_coeff))
260 mark_used(counter)
261 cpassert(PRESENT(fm_pool) .NEQV. (PRESENT(fm_ref) .NEQV. PRESENT(fm_struct)))
262 NULLIFY (mo_set%mo_coeff)
263 IF (PRESENT(fm_pool)) THEN
264 ALLOCATE (mo_set%mo_coeff)
265 CALL fm_pool_create_fm(fm_pool, mo_set%mo_coeff, name=name)
266 ELSE IF (PRESENT(fm_ref)) THEN
267 ALLOCATE (mo_set%mo_coeff)
268 CALL cp_fm_create(mo_set%mo_coeff, fm_ref%matrix_struct, name=name)
269 ELSE IF (PRESENT(fm_struct)) THEN
270 ALLOCATE (mo_set%mo_coeff)
271 cpassert(ASSOCIATED(fm_struct))
272 CALL cp_fm_create(mo_set%mo_coeff, fm_struct, name=name)
273 END IF
274 CALL cp_fm_set_all(mo_set%mo_coeff, 0.0_dp)
275 CALL cp_fm_get_info(mo_set%mo_coeff, nrow_global=nao, ncol_global=nmo)
276
277 cpassert(nao >= mo_set%nao)
278 cpassert(nmo >= mo_set%nmo)
279
280 ALLOCATE (mo_set%eigenvalues(nmo))
281 mo_set%eigenvalues(:) = 0.0_dp
282
283 ALLOCATE (mo_set%occupation_numbers(nmo))
284 ! Initialize MO occupations
285 mo_set%occupation_numbers(:) = 0.0_dp
286 ! Quick return, if no electrons are available
287 IF (mo_set%nelectron == 0) THEN
288 RETURN
289 END IF
290
291 IF (modulo(mo_set%nelectron, int(mo_set%maxocc)) == 0) THEN
292 nomo = nint(mo_set%nelectron/mo_set%maxocc)
293 mo_set%occupation_numbers(1:nomo) = mo_set%maxocc
294 ELSE
295 nomo = int(mo_set%nelectron/mo_set%maxocc) + 1
296 ! Initialize MO occupations
297 mo_set%occupation_numbers(1:nomo - 1) = mo_set%maxocc
298 mo_set%occupation_numbers(nomo - ((na - nb)/2):nomo) = 1
299 END IF
300
301 cpassert(nmo >= nomo)
302 cpassert((SIZE(mo_set%occupation_numbers) == nmo))
303
304 mo_set%homo = nomo
305 mo_set%lfomo = nomo + 1
306 mo_set%mu = mo_set%eigenvalues(nomo)
307
308 END SUBROUTINE init_mo_set
309
310! **************************************************************************************************
311!> \brief make the beta orbitals explicitly equal to the alpha orbitals
312!> effectively copying the orbital data
313!> \param mo_array ...
314!> \param convert_dbcsr ...
315!> \par History
316!> 10.2004 created [Joost VandeVondele]
317! **************************************************************************************************
318 SUBROUTINE mo_set_restrict(mo_array, convert_dbcsr)
319 TYPE(mo_set_type), DIMENSION(2), INTENT(IN) :: mo_array
320 LOGICAL, INTENT(in), OPTIONAL :: convert_dbcsr
321
322 CHARACTER(LEN=*), PARAMETER :: routinen = 'mo_set_restrict'
323
324 INTEGER :: handle
325 LOGICAL :: my_convert_dbcsr
326
327 CALL timeset(routinen, handle)
328
329 my_convert_dbcsr = .false.
330 IF (PRESENT(convert_dbcsr)) my_convert_dbcsr = convert_dbcsr
331
332 cpassert(mo_array(1)%nmo >= mo_array(2)%nmo)
333
334 ! first nmo_beta orbitals are copied from alpha to beta
335 IF (my_convert_dbcsr) THEN !fm->dbcsr
336 CALL dbcsr_copy_columns_hack(mo_array(2)%mo_coeff_b, mo_array(1)%mo_coeff_b, & !fm->dbcsr
337 mo_array(2)%nmo, 1, 1, & !fm->dbcsr
338 para_env=mo_array(1)%mo_coeff%matrix_struct%para_env, & !fm->dbcsr
339 blacs_env=mo_array(1)%mo_coeff%matrix_struct%context) !fm->dbcsr
340 ELSE !fm->dbcsr
341 CALL cp_fm_to_fm(mo_array(1)%mo_coeff, mo_array(2)%mo_coeff, mo_array(2)%nmo)
342 END IF
343
344 CALL timestop(handle)
345
346 END SUBROUTINE mo_set_restrict
347
348! **************************************************************************************************
349!> \brief Deallocate a wavefunction data structure.
350!> \param mo_set ...
351!> \date 15.05.2001
352!> \author MK
353!> \version 1.0
354! **************************************************************************************************
355 SUBROUTINE deallocate_mo_set(mo_set)
356
357 TYPE(mo_set_type), INTENT(INOUT) :: mo_set
358
359 IF (ASSOCIATED(mo_set%eigenvalues)) THEN
360 DEALLOCATE (mo_set%eigenvalues)
361 NULLIFY (mo_set%eigenvalues)
362 END IF
363 IF (ASSOCIATED(mo_set%occupation_numbers)) THEN
364 DEALLOCATE (mo_set%occupation_numbers)
365 NULLIFY (mo_set%occupation_numbers)
366 END IF
367 IF (ASSOCIATED(mo_set%mo_coeff)) THEN
368 CALL cp_fm_release(mo_set%mo_coeff)
369 DEALLOCATE (mo_set%mo_coeff)
370 NULLIFY (mo_set%mo_coeff)
371 END IF
372 IF (ASSOCIATED(mo_set%mo_coeff_b)) CALL dbcsr_release_p(mo_set%mo_coeff_b)
373
374 END SUBROUTINE deallocate_mo_set
375
376! **************************************************************************************************
377!> \brief Get the components of a MO set data structure.
378!> \param mo_set ...
379!> \param maxocc ...
380!> \param homo ...
381!> \param lfomo ...
382!> \param nao ...
383!> \param nelectron ...
384!> \param n_el_f ...
385!> \param nmo ...
386!> \param eigenvalues ...
387!> \param occupation_numbers ...
388!> \param mo_coeff ...
389!> \param mo_coeff_b ...
390!> \param uniform_occupation ...
391!> \param kTS ...
392!> \param mu ...
393!> \param flexible_electron_count ...
394!> \date 22.04.2002
395!> \author MK
396!> \version 1.0
397! **************************************************************************************************
398 SUBROUTINE get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, &
399 eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, &
400 uniform_occupation, kTS, mu, flexible_electron_count)
401
402 TYPE(mo_set_type), INTENT(IN) :: mo_set
403 REAL(kind=dp), INTENT(OUT), OPTIONAL :: maxocc
404 INTEGER, INTENT(OUT), OPTIONAL :: homo, lfomo, nao, nelectron
405 REAL(kind=dp), INTENT(OUT), OPTIONAL :: n_el_f
406 INTEGER, INTENT(OUT), OPTIONAL :: nmo
407 REAL(kind=dp), DIMENSION(:), OPTIONAL, POINTER :: eigenvalues, occupation_numbers
408 TYPE(cp_fm_type), OPTIONAL, POINTER :: mo_coeff
409 TYPE(dbcsr_type), OPTIONAL, POINTER :: mo_coeff_b
410 LOGICAL, INTENT(OUT), OPTIONAL :: uniform_occupation
411 REAL(kind=dp), INTENT(OUT), OPTIONAL :: kts, mu, flexible_electron_count
412
413 IF (PRESENT(maxocc)) maxocc = mo_set%maxocc
414 IF (PRESENT(homo)) homo = mo_set%homo
415 IF (PRESENT(lfomo)) lfomo = mo_set%lfomo
416 IF (PRESENT(nao)) nao = mo_set%nao
417 IF (PRESENT(nelectron)) nelectron = mo_set%nelectron
418 IF (PRESENT(n_el_f)) n_el_f = mo_set%n_el_f
419 IF (PRESENT(nmo)) nmo = mo_set%nmo
420 IF (PRESENT(eigenvalues)) eigenvalues => mo_set%eigenvalues
421 IF (PRESENT(occupation_numbers)) THEN
422 occupation_numbers => mo_set%occupation_numbers
423 END IF
424 IF (PRESENT(mo_coeff)) mo_coeff => mo_set%mo_coeff
425 IF (PRESENT(mo_coeff_b)) mo_coeff_b => mo_set%mo_coeff_b
426 IF (PRESENT(uniform_occupation)) uniform_occupation = mo_set%uniform_occupation
427 IF (PRESENT(kts)) kts = mo_set%kTS
428 IF (PRESENT(mu)) mu = mo_set%mu
429 IF (PRESENT(flexible_electron_count)) flexible_electron_count = mo_set%flexible_electron_count
430
431 END SUBROUTINE get_mo_set
432
433! **************************************************************************************************
434!> \brief Set the components of a MO set data structure.
435!> \param mo_set ...
436!> \param maxocc ...
437!> \param homo ...
438!> \param lfomo ...
439!> \param nao ...
440!> \param nelectron ...
441!> \param n_el_f ...
442!> \param nmo ...
443!> \param eigenvalues ...
444!> \param occupation_numbers ...
445!> \param uniform_occupation ...
446!> \param kTS ...
447!> \param mu ...
448!> \param flexible_electron_count ...
449!> \date 22.04.2002
450!> \author MK
451!> \version 1.0
452! **************************************************************************************************
453 SUBROUTINE set_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, &
454 eigenvalues, occupation_numbers, uniform_occupation, &
455 kTS, mu, flexible_electron_count)
456
457 TYPE(mo_set_type), INTENT(INOUT) :: mo_set
458 REAL(kind=dp), INTENT(IN), OPTIONAL :: maxocc
459 INTEGER, INTENT(IN), OPTIONAL :: homo, lfomo, nao, nelectron
460 REAL(kind=dp), INTENT(IN), OPTIONAL :: n_el_f
461 INTEGER, INTENT(IN), OPTIONAL :: nmo
462 REAL(kind=dp), DIMENSION(:), OPTIONAL, POINTER :: eigenvalues, occupation_numbers
463 LOGICAL, INTENT(IN), OPTIONAL :: uniform_occupation
464 REAL(kind=dp), INTENT(IN), OPTIONAL :: kts, mu, flexible_electron_count
465
466 IF (PRESENT(maxocc)) mo_set%maxocc = maxocc
467 IF (PRESENT(homo)) mo_set%homo = homo
468 IF (PRESENT(lfomo)) mo_set%lfomo = lfomo
469 IF (PRESENT(nao)) mo_set%nao = nao
470 IF (PRESENT(nelectron)) mo_set%nelectron = nelectron
471 IF (PRESENT(n_el_f)) mo_set%n_el_f = n_el_f
472 IF (PRESENT(nmo)) mo_set%nmo = nmo
473 IF (PRESENT(eigenvalues)) THEN
474 IF (ASSOCIATED(mo_set%eigenvalues)) THEN
475 DEALLOCATE (mo_set%eigenvalues)
476 END IF
477 mo_set%eigenvalues => eigenvalues
478 END IF
479 IF (PRESENT(occupation_numbers)) THEN
480 IF (ASSOCIATED(mo_set%occupation_numbers)) THEN
481 DEALLOCATE (mo_set%occupation_numbers)
482 END IF
483 mo_set%occupation_numbers => occupation_numbers
484 END IF
485 IF (PRESENT(uniform_occupation)) mo_set%uniform_occupation = uniform_occupation
486 IF (PRESENT(kts)) mo_set%kTS = kts
487 IF (PRESENT(mu)) mo_set%mu = mu
488 IF (PRESENT(flexible_electron_count)) mo_set%flexible_electron_count = flexible_electron_count
489
490 END SUBROUTINE set_mo_set
491
492! **************************************************************************************************
493!> \brief Check if the set of MOs in mo_set specifed by the MO index range [first_mo,last_mo]
494!> an integer occupation within a tolerance.
495!> \param mo_set :: MO set for which the uniform occupation will be checked
496!> \param first_mo :: Index of first MO for the checked MO range
497!> \param last_mo :: Index of last MO for the checked MO range
498!> \param occupation :: Requested uniform MO occupation with the MO range
499!> \param tolerance :: Requested numerical tolerance for an integer occupation
500!> \return has_uniform_occupation :: boolean, true if an integer occupation is found otherwise false
501!> \par History
502!> 04.08.2021 Created (MK)
503!> \author Matthias Krack (MK)
504!> \version 1.0
505! **************************************************************************************************
506 FUNCTION has_uniform_occupation(mo_set, first_mo, last_mo, occupation, tolerance)
507
508 TYPE(mo_set_type), INTENT(IN) :: mo_set
509 INTEGER, INTENT(IN), OPTIONAL :: first_mo, last_mo
510 REAL(kind=dp), INTENT(IN), OPTIONAL :: occupation, tolerance
511 LOGICAL :: has_uniform_occupation
512
513 INTEGER :: my_first_mo, my_last_mo
514 REAL(kind=dp) :: my_occupation, my_tolerance
515
516 has_uniform_occupation = .false.
517
518 IF (PRESENT(first_mo)) THEN
519 cpassert(first_mo >= lbound(mo_set%eigenvalues, 1))
520 my_first_mo = first_mo
521 ELSE
522 my_first_mo = lbound(mo_set%eigenvalues, 1)
523 END IF
524
525 IF (PRESENT(last_mo)) THEN
526 cpassert(last_mo <= ubound(mo_set%eigenvalues, 1))
527 my_last_mo = last_mo
528 ELSE
529 my_last_mo = ubound(mo_set%eigenvalues, 1)
530 END IF
531
532 IF (PRESENT(occupation)) THEN
533 my_occupation = occupation
534 ELSE
535 my_occupation = mo_set%maxocc
536 END IF
537
538 IF (PRESENT(tolerance)) THEN
539 my_tolerance = tolerance
540 ELSE
541 my_tolerance = epsilon(0.0_dp)
542 END IF
543
544 has_uniform_occupation = all(abs(mo_set%occupation_numbers(my_first_mo:my_last_mo) - my_occupation) < my_tolerance)
545
546 END FUNCTION has_uniform_occupation
547
548END MODULE qs_mo_types
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
subroutine, public dbcsr_release_p(matrix)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_init_p(matrix)
...
DBCSR operations in CP2K.
subroutine, public dbcsr_copy_columns_hack(matrix_b, matrix_a, ncol, source_start, target_start, para_env, blacs_env)
hack for dbcsr_copy_columns
pool for for elements that are retained and released
subroutine, public fm_pool_create_fm(pool, element, name)
returns an element, allocating it if none is in the pool
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_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
subroutine, public duplicate_mo_set(mo_set_new, mo_set_old)
allocate a new mo_set, and copy the old data
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.
subroutine, public init_mo_set(mo_set, fm_pool, fm_ref, fm_struct, name, counter)
initializes an allocated mo_set. eigenvalues, mo_coeff, occupation_numbers are valid only after this ...
subroutine, public allocate_mo_set(mo_set, nao, nmo, nelectron, n_el_f, maxocc, flexible_electron_count)
Allocates a mo set and partially initializes it (nao,nmo,nelectron, and flexible_electron_count are v...
subroutine, public mo_set_restrict(mo_array, convert_dbcsr)
make the beta orbitals explicitly equal to the alpha orbitals effectively copying the orbital data
subroutine, public deallocate_mo_set(mo_set)
Deallocate a wavefunction data structure.
logical function, public has_uniform_occupation(mo_set, first_mo, last_mo, occupation, tolerance)
Check if the set of MOs in mo_set specifed by the MO index range [first_mo,last_mo] an integer occupa...
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.
subroutine, public reassign_allocated_mos(mo_set_new, mo_set_old)
reassign an already allocated mo_set
represent a pool of elements with the same structure
keeps the information about the structure of a full matrix
represent a full matrix