(git:852b9a4)
Loading...
Searching...
No Matches
qs_active_space_mixing.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 Dense density mixing for active-space embedding.
10! **************************************************************************************************
19 USE kinds, ONLY: dp
20 USE mathlib, ONLY: invert_matrix
22 USE qs_density_mixing_types, ONLY: &
26#include "./base/base_uses.f90"
27
28 IMPLICIT NONE
29 PRIVATE
30
33 PUBLIC :: update_active_density
34
35CONTAINS
36
37! **************************************************************************************************
38!> \brief Initialize the density mixer used in the self-consistent active-space embedding loop.
39!> \param active_space_env active space environment
40!> \param as_input ACTIVE_SPACE input section
41! **************************************************************************************************
42 SUBROUTINE initialize_active_space_mixing(active_space_env, as_input)
43 TYPE(active_space_type), POINTER :: active_space_env
44 TYPE(section_vals_type), POINTER :: as_input
45
46 LOGICAL :: do_mixing, legacy_alpha_explicit, &
47 mixing_alpha_explicit, mixing_explicit
48 REAL(kind=dp) :: legacy_alpha
49 TYPE(section_vals_type), POINTER :: mixing_section
50
51 NULLIFY (mixing_section)
52
53 CALL section_vals_val_get(as_input, "ALPHA", r_val=legacy_alpha, &
54 explicit=legacy_alpha_explicit)
55 IF (legacy_alpha < 0.0_dp .OR. legacy_alpha > 1.0_dp) THEN
56 cpabort("Specify an active-space damping factor between 0 and 1.")
57 END IF
58
59 mixing_section => section_vals_get_subs_vals(as_input, "MIXING")
60 CALL section_vals_get(mixing_section, explicit=mixing_explicit)
61 CALL section_vals_val_get(mixing_section, "_SECTION_PARAMETERS_", l_val=do_mixing)
62
63 active_space_env%as_mixing_dim = 0
64 active_space_env%as_mixing_iter = 0
65
66 IF (.NOT. do_mixing) THEN
67 active_space_env%as_mixing_method = no_mixing_nr
68 active_space_env%alpha = 1.0_dp
69 RETURN
70 END IF
71
72 CALL section_vals_val_get(mixing_section, "METHOD", &
73 i_val=active_space_env%as_mixing_method)
74
75 SELECT CASE (active_space_env%as_mixing_method)
76 CASE (no_mixing_nr)
77 active_space_env%alpha = 1.0_dp
78 RETURN
80 CONTINUE
81 CASE (gspace_mixing_nr)
82 CALL cp_abort(__location__, &
83 "ACTIVE_SPACE%MIXING%METHOD KERKER_MIXING is not supported. "// &
84 "The active-space density lives in the active MO subspace, "// &
85 "not in G-space.")
87 cpabort("ACTIVE_SPACE%MIXING%METHOD MULTISECANT_MIXING is not yet supported.")
88 CASE DEFAULT
89 cpabort("Unknown ACTIVE_SPACE%MIXING%METHOD.")
90 END SELECT
91
92 IF (ASSOCIATED(active_space_env%as_mixing_store)) THEN
93 cpabort("Active-space mixing storage already initialized.")
94 END IF
95 ALLOCATE (active_space_env%as_mixing_store)
96 CALL mixing_storage_create(active_space_env%as_mixing_store, mixing_section, &
97 active_space_env%as_mixing_method, ecut=0.0_dp)
98
99 CALL section_vals_val_get(mixing_section, "ALPHA", explicit=mixing_alpha_explicit)
100 IF ((legacy_alpha_explicit .AND. (.NOT. mixing_alpha_explicit)) .OR. &
101 ((.NOT. mixing_explicit) .AND. (.NOT. mixing_alpha_explicit))) THEN
102 active_space_env%as_mixing_store%alpha = legacy_alpha
103 END IF
104 IF (active_space_env%as_mixing_store%alpha < 0.0_dp .OR. &
105 active_space_env%as_mixing_store%alpha > 1.0_dp) THEN
106 cpabort("Specify an active-space mixing ALPHA between 0 and 1.")
107 END IF
108 IF (active_space_env%as_mixing_store%nbuffer < 1 .AND. &
109 active_space_env%as_mixing_method /= direct_mixing_nr) THEN
110 cpabort("ACTIVE_SPACE%MIXING%NBUFFER has to be positive.")
111 END IF
112
113 active_space_env%alpha = active_space_env%as_mixing_store%alpha
114
115 END SUBROUTINE initialize_active_space_mixing
116
117! **************************************************************************************************
118!> \brief Return the current active-space mixer label for iteration output.
119!> \param active_space_env active space environment
120!> \return short mixer label
121! **************************************************************************************************
122 FUNCTION active_space_mixing_label(active_space_env) RESULT(label)
123 TYPE(active_space_type), POINTER :: active_space_env
124 CHARACTER(len=15) :: label
125
126 SELECT CASE (active_space_env%as_mixing_method)
127 CASE (direct_mixing_nr)
128 label = "P_Mix"
129 CASE (pulay_mixing_nr)
130 label = "Pulay"
131 CASE (broyden_mixing_nr)
132 label = "Broy."
134 label = "MBroy"
135 CASE DEFAULT
136 label = "NoMix"
137 END SELECT
138 IF (ASSOCIATED(active_space_env%as_mixing_store)) THEN
139 IF (active_space_env%as_mixing_iter > 0 .AND. &
140 len_trim(active_space_env%as_mixing_store%iter_method) > 0) THEN
141 label = active_space_env%as_mixing_store%iter_method
142 END IF
143 END IF
144
145 END FUNCTION active_space_mixing_label
146
147! **************************************************************************************************
148!> \brief Release dense active-space mixing history buffers.
149!> \param active_space_env active space environment
150! **************************************************************************************************
151 SUBROUTINE release_active_mixing_history(active_space_env)
152 TYPE(active_space_type), POINTER :: active_space_env
153
154 IF (ASSOCIATED(active_space_env%as_mix_r_old)) THEN
155 DEALLOCATE (active_space_env%as_mix_r_old)
156 END IF
157 IF (ASSOCIATED(active_space_env%as_mix_weight)) THEN
158 DEALLOCATE (active_space_env%as_mix_weight)
159 END IF
160 IF (ASSOCIATED(active_space_env%as_mix_x_old)) THEN
161 DEALLOCATE (active_space_env%as_mix_x_old)
162 END IF
163 IF (ASSOCIATED(active_space_env%as_mix_r_buffer)) THEN
164 DEALLOCATE (active_space_env%as_mix_r_buffer)
165 END IF
166 IF (ASSOCIATED(active_space_env%as_mix_x_buffer)) THEN
167 DEALLOCATE (active_space_env%as_mix_x_buffer)
168 END IF
169 active_space_env%as_mixing_dim = 0
170
171 END SUBROUTINE release_active_mixing_history
172
173! **************************************************************************************************
174!> \brief Ensure dense active-space mixing history buffers are allocated.
175!> \param active_space_env active space environment
176!> \param ndim length of the flattened density vector
177! **************************************************************************************************
178 SUBROUTINE ensure_active_mixing_history(active_space_env, ndim)
179 TYPE(active_space_type), POINTER :: active_space_env
180 INTEGER, INTENT(IN) :: ndim
181
182 INTEGER :: nbuffer
183 TYPE(mixing_storage_type), POINTER :: mixing_store
184
185 IF (.NOT. ASSOCIATED(active_space_env%as_mixing_store)) RETURN
186 IF (active_space_env%as_mixing_method == direct_mixing_nr) RETURN
187
188 mixing_store => active_space_env%as_mixing_store
189 nbuffer = mixing_store%nbuffer
190 IF (nbuffer < 1) cpabort("ACTIVE_SPACE%MIXING%NBUFFER has to be positive.")
191
192 IF (active_space_env%as_mixing_dim == ndim .AND. &
193 ASSOCIATED(active_space_env%as_mix_r_buffer)) RETURN
194
195 CALL release_active_mixing_history(active_space_env)
196
197 active_space_env%as_mixing_dim = ndim
198 ALLOCATE (active_space_env%as_mix_r_old(ndim))
199 ALLOCATE (active_space_env%as_mix_weight(nbuffer))
200 ALLOCATE (active_space_env%as_mix_x_old(ndim))
201 ALLOCATE (active_space_env%as_mix_r_buffer(nbuffer, ndim))
202 ALLOCATE (active_space_env%as_mix_x_buffer(nbuffer, ndim))
203
204 active_space_env%as_mix_r_old = 0.0_dp
205 active_space_env%as_mix_weight = 1.0_dp
206 active_space_env%as_mix_x_old = 0.0_dp
207 active_space_env%as_mix_r_buffer = 0.0_dp
208 active_space_env%as_mix_x_buffer = 0.0_dp
209 mixing_store%ncall = 0
210
211 END SUBROUTINE ensure_active_mixing_history
212
213! **************************************************************************************************
214!> \brief Apply a direct dense active-space density mix.
215!> \param p_old current active-space density vector
216!> \param p_solver active-space density vector returned by the external solver
217!> \param alpha mixing damping
218!> \param p_mixed mixed active-space density vector
219! **************************************************************************************************
220 SUBROUTINE active_space_direct_mix(p_old, p_solver, alpha, p_mixed)
221 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: p_old, p_solver
222 REAL(kind=dp), INTENT(IN) :: alpha
223 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: p_mixed
224
225 p_mixed = p_old + alpha*(p_solver - p_old)
226
227 END SUBROUTINE active_space_direct_mix
228
229! **************************************************************************************************
230!> \brief Apply Pulay mixing to the dense active-space density vector.
231!> \param active_space_env active space environment
232!> \param p_old current active-space density vector
233!> \param p_solver active-space density vector returned by the external solver
234!> \param p_mixed mixed active-space density vector
235! **************************************************************************************************
236 SUBROUTINE active_space_pulay_mixing(active_space_env, p_old, p_solver, p_mixed)
237 TYPE(active_space_type), POINTER :: active_space_env
238 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: p_old, p_solver
239 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: p_mixed
240
241 INTEGER :: i, ib, ibb, j, nb, nbuffer, ndim
242 REAL(kind=dp) :: inv_err, norm_c_inv, res_norm
243 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: alpha_c, p_diis
244 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: c, c_inv
245 TYPE(mixing_storage_type), POINTER :: mixing_store
246
247 ndim = SIZE(p_old)
248 CALL ensure_active_mixing_history(active_space_env, ndim)
249 mixing_store => active_space_env%as_mixing_store
250 nbuffer = mixing_store%nbuffer
251
252 ib = modulo(mixing_store%ncall, nbuffer) + 1
253 mixing_store%ncall = mixing_store%ncall + 1
254 nb = min(mixing_store%ncall, nbuffer)
255 ibb = modulo(mixing_store%ncall, nbuffer) + 1
256
257 active_space_env%as_mix_x_buffer(ib, :) = p_old
258 active_space_env%as_mix_r_buffer(ib, :) = p_solver - p_old
259 res_norm = norm2(active_space_env%as_mix_r_buffer(ib, :))
260
261 IF (nb == 1 .OR. res_norm < 1.e-14_dp) THEN
262 CALL active_space_direct_mix(p_old, p_solver, mixing_store%alpha, p_mixed)
263 ELSE
264 ALLOCATE (c(nb, nb))
265 ALLOCATE (c_inv(nb, nb))
266 ALLOCATE (alpha_c(nb))
267 ALLOCATE (p_diis(ndim))
268
269 c(:, :) = 0.0_dp
270 DO i = 1, nb
271 DO j = i, nb
272 c(j, i) = dot_product(active_space_env%as_mix_r_buffer(i, :), &
273 active_space_env%as_mix_r_buffer(j, :))
274 c(i, j) = c(j, i)
275 END DO
276 END DO
277
278 CALL invert_matrix(c, c_inv, inv_err, improve=.true.)
279 norm_c_inv = sum(c_inv)
280 IF (abs(norm_c_inv) < 1.e-14_dp) THEN
281 CALL active_space_direct_mix(p_old, p_solver, mixing_store%alpha, p_mixed)
282 ELSE
283 DO i = 1, nb
284 alpha_c(i) = sum(c_inv(:, i))/norm_c_inv
285 END DO
286
287 p_diis(:) = 0.0_dp
288 DO i = 1, nb
289 p_diis(:) = p_diis(:) + alpha_c(i)*(active_space_env%as_mix_x_buffer(i, :) + &
290 mixing_store%pulay_beta*active_space_env%as_mix_r_buffer(i, :))
291 END DO
292 IF (mixing_store%pulay_alpha > 0.0_dp) THEN
293 p_mixed = mixing_store%pulay_alpha*p_solver + &
294 (1.0_dp - mixing_store%pulay_alpha)*p_diis
295 ELSE
296 p_mixed = p_diis
297 END IF
298 END IF
299
300 DEALLOCATE (alpha_c)
301 DEALLOCATE (p_diis)
302 DEALLOCATE (c)
303 DEALLOCATE (c_inv)
304 END IF
305
306 active_space_env%as_mix_x_buffer(ibb, :) = p_mixed
307 mixing_store%iter_method = "Pulay"
308
309 END SUBROUTINE active_space_pulay_mixing
310
311! **************************************************************************************************
312!> \brief Apply original or modified Broyden mixing to the dense active-space density vector.
313!> \param active_space_env active space environment
314!> \param p_old current active-space density vector
315!> \param p_solver active-space density vector returned by the external solver
316!> \param p_mixed mixed active-space density vector
317!> \param modified use dynamic residual weights of modified Broyden
318! **************************************************************************************************
319 SUBROUTINE active_space_broyden_mixing(active_space_env, p_old, p_solver, p_mixed, modified)
320 TYPE(active_space_type), POINTER :: active_space_env
321 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: p_old, p_solver
322 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: p_mixed
323 LOGICAL, INTENT(IN) :: modified
324
325 INTEGER :: ib, j, k, nb, nbuffer, ndim
326 LOGICAL :: can_update
327 REAL(kind=dp) :: delta_norm, inv_err, res_norm, weight
328 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: c, g, p_res
329 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: a, b
330 TYPE(mixing_storage_type), POINTER :: mixing_store
331
332 ndim = SIZE(p_old)
333 CALL ensure_active_mixing_history(active_space_env, ndim)
334 mixing_store => active_space_env%as_mixing_store
335 nbuffer = mixing_store%nbuffer
336
337 ALLOCATE (p_res(ndim))
338 p_res(:) = p_solver(:) - p_old(:)
339 res_norm = norm2(p_res)
340
341 mixing_store%ncall = mixing_store%ncall + 1
342 IF (mixing_store%ncall == 1) THEN
343 CALL active_space_direct_mix(p_old, p_solver, mixing_store%alpha, p_mixed)
344 active_space_env%as_mix_x_old = p_old
345 active_space_env%as_mix_r_old = p_res
346 IF (modified) THEN
347 mixing_store%iter_method = "MBroy"
348 ELSE
349 mixing_store%iter_method = "Broy."
350 END IF
351 DEALLOCATE (p_res)
352 RETURN
353 END IF
354
355 nb = min(mixing_store%ncall - 1, nbuffer)
356 ib = modulo(mixing_store%ncall - 2, nbuffer) + 1
357
358 active_space_env%as_mix_r_buffer(ib, :) = p_res - active_space_env%as_mix_r_old
359 active_space_env%as_mix_x_buffer(ib, :) = p_old - active_space_env%as_mix_x_old
360 delta_norm = norm2(active_space_env%as_mix_r_buffer(ib, :))
361 can_update = res_norm > 1.e-14_dp .AND. delta_norm > 1.e-14_dp
362
363 IF (can_update) THEN
364 active_space_env%as_mix_r_buffer(ib, :) = active_space_env%as_mix_r_buffer(ib, :)/delta_norm
365 active_space_env%as_mix_x_buffer(ib, :) = active_space_env%as_mix_x_buffer(ib, :)/delta_norm + &
366 mixing_store%alpha*active_space_env%as_mix_r_buffer(ib, :)
367
368 IF (modified) THEN
369 IF (res_norm > (mixing_store%wc/mixing_store%wmax)) THEN
370 active_space_env%as_mix_weight(ib) = mixing_store%wc/res_norm
371 ELSE
372 active_space_env%as_mix_weight(ib) = mixing_store%wmax
373 END IF
374 active_space_env%as_mix_weight(ib) = max(1.0_dp, active_space_env%as_mix_weight(ib))
375 END IF
376
377 ALLOCATE (a(nb, nb))
378 ALLOCATE (b(nb, nb))
379 ALLOCATE (c(nb))
380 ALLOCATE (g(nb))
381
382 a(:, :) = 0.0_dp
383 c(:) = 0.0_dp
384 DO j = 1, nb
385 DO k = j, nb
386 a(k, j) = dot_product(active_space_env%as_mix_r_buffer(j, :), &
387 active_space_env%as_mix_r_buffer(k, :))
388 a(j, k) = a(k, j)
389 END DO
390 END DO
391
392 DO j = 1, nb
393 c(j) = dot_product(active_space_env%as_mix_r_buffer(j, :), p_res)
394 IF (modified) THEN
395 c(j) = active_space_env%as_mix_weight(j)*c(j)
396 DO k = 1, nb
397 a(k, j) = active_space_env%as_mix_weight(k)* &
398 active_space_env%as_mix_weight(j)*a(k, j)
399 END DO
400 a(j, j) = mixing_store%broy_w0*mixing_store%broy_w0 + a(j, j)
401 ELSE
402 a(j, j) = mixing_store%broy_w0 + a(j, j)
403 END IF
404 END DO
405
406 CALL invert_matrix(a, b, inv_err)
407 g(:) = 0.0_dp
408 DO j = 1, nb
409 DO k = 1, nb
410 g(j) = g(j) + b(k, j)*c(k)
411 END DO
412 END DO
413
414 CALL active_space_direct_mix(p_old, p_solver, mixing_store%alpha, p_mixed)
415 DO j = 1, nb
416 weight = 1.0_dp
417 IF (modified) weight = active_space_env%as_mix_weight(j)
418 p_mixed = p_mixed - weight*g(j)*active_space_env%as_mix_x_buffer(j, :)
419 END DO
420
421 DEALLOCATE (a)
422 DEALLOCATE (b)
423 DEALLOCATE (c)
424 DEALLOCATE (g)
425 ELSE
426 active_space_env%as_mix_r_buffer(ib, :) = 0.0_dp
427 active_space_env%as_mix_x_buffer(ib, :) = 0.0_dp
428 CALL active_space_direct_mix(p_old, p_solver, mixing_store%alpha, p_mixed)
429 END IF
430
431 active_space_env%as_mix_x_old = p_old
432 active_space_env%as_mix_r_old = p_res
433 IF (modified) THEN
434 mixing_store%iter_method = "MBroy"
435 ELSE
436 mixing_store%iter_method = "Broy."
437 END IF
438
439 DEALLOCATE (p_res)
440
441 END SUBROUTINE active_space_broyden_mixing
442
443! **************************************************************************************************
444!> \brief Mix the dense active-space density vector.
445!> \param active_space_env active space environment
446!> \param p_old current active-space density vector
447!> \param p_solver active-space density vector returned by the external solver
448!> \param p_mixed mixed active-space density vector
449! **************************************************************************************************
450 SUBROUTINE mix_active_density_vector(active_space_env, p_old, p_solver, p_mixed)
451 TYPE(active_space_type), POINTER :: active_space_env
452 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: p_old, p_solver
453 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: p_mixed
454
455 INTEGER :: active_mix_iter
456 TYPE(mixing_storage_type), POINTER :: mixing_store
457
458 IF (active_space_env%as_mixing_method == no_mixing_nr .OR. &
459 .NOT. ASSOCIATED(active_space_env%as_mixing_store)) THEN
460 p_mixed = p_solver
461 RETURN
462 END IF
463
464 mixing_store => active_space_env%as_mixing_store
465 active_space_env%as_mixing_iter = active_space_env%as_mixing_iter + 1
466
467 IF (active_space_env%as_mixing_iter <= mixing_store%nskip_mixing) THEN
468 p_mixed = p_solver
469 mixing_store%iter_method = "NoMix"
470 RETURN
471 END IF
472
473 active_mix_iter = active_space_env%as_mixing_iter - mixing_store%nskip_mixing
474 IF (active_space_env%as_mixing_method == direct_mixing_nr .OR. &
475 active_mix_iter <= mixing_store%n_simple_mix) THEN
476 CALL active_space_direct_mix(p_old, p_solver, mixing_store%alpha, p_mixed)
477 mixing_store%iter_method = "P_Mix"
478 RETURN
479 END IF
480
481 SELECT CASE (active_space_env%as_mixing_method)
482 CASE (pulay_mixing_nr)
483 CALL active_space_pulay_mixing(active_space_env, p_old, p_solver, p_mixed)
484 CASE (broyden_mixing_nr)
485 CALL active_space_broyden_mixing(active_space_env, p_old, p_solver, p_mixed, .false.)
487 CALL active_space_broyden_mixing(active_space_env, p_old, p_solver, p_mixed, .true.)
488 CASE DEFAULT
489 cpabort("Unsupported ACTIVE_SPACE%MIXING%METHOD.")
490 END SELECT
491
492 END SUBROUTINE mix_active_density_vector
493
494! **************************************************************************************************
495!> \brief Update active space density matrix from Fortran arrays
496!> \param p_act_mo_a alpha density matrix in active space MO basis
497!> \param active_space_env active space environment
498!> \param p_act_mo_b beta density matrix in active space MO basis
499!> \author Vladimir Rybkin
500! **************************************************************************************************
501 SUBROUTINE update_active_density(p_act_mo_a, active_space_env, p_act_mo_b)
502 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: p_act_mo_a
503 TYPE(active_space_type), POINTER :: active_space_env
504 REAL(kind=dp), DIMENSION(:), INTENT(IN), OPTIONAL :: p_act_mo_b
505
506 INTEGER :: i1, i2, idx, ispin, m1, m2, nact2, &
507 nmo_active, nspins
508 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: p_mixed, p_old, p_solver
509 TYPE(cp_fm_type), POINTER :: p_active
510
511 nmo_active = active_space_env%nmo_active
512 nact2 = nmo_active*nmo_active
513 nspins = active_space_env%nspins
514 cpassert(SIZE(p_act_mo_a) == nact2)
515 IF (nspins == 2) THEN
516 IF (.NOT. PRESENT(p_act_mo_b)) cpabort("Missing beta active-space density.")
517 cpassert(SIZE(p_act_mo_b) == nact2)
518 END IF
519
520 ALLOCATE (p_mixed(nspins*nact2))
521 ALLOCATE (p_old(nspins*nact2))
522 ALLOCATE (p_solver(nspins*nact2))
523
524 p_solver(1:nact2) = p_act_mo_a
525 IF (nspins == 2) THEN
526 p_solver(nact2 + 1:2*nact2) = p_act_mo_b
527 END IF
528
529 idx = 0
530 DO ispin = 1, nspins
531 p_active => active_space_env%p_active(ispin)
532 DO i1 = 1, nmo_active
533 m1 = active_space_env%active_orbitals(i1, ispin)
534 DO i2 = 1, nmo_active
535 idx = idx + 1
536 m2 = active_space_env%active_orbitals(i2, ispin)
537 CALL cp_fm_get_element(p_active, m1, m2, p_old(idx))
538 END DO
539 END DO
540 END DO
541
542 CALL mix_active_density_vector(active_space_env, p_old, p_solver, p_mixed)
543
544 idx = 0
545 DO ispin = 1, nspins
546 p_active => active_space_env%p_active(ispin)
547 DO i1 = 1, nmo_active
548 m1 = active_space_env%active_orbitals(i1, ispin)
549 DO i2 = 1, nmo_active
550 idx = idx + 1
551 m2 = active_space_env%active_orbitals(i2, ispin)
552 CALL cp_fm_set_element(p_active, m1, m2, p_mixed(idx))
553 END DO
554 END DO
555 END DO
556
557 DEALLOCATE (p_mixed)
558 DEALLOCATE (p_old)
559 DEALLOCATE (p_solver)
560
561 END SUBROUTINE update_active_density
562
563END MODULE qs_active_space_mixing
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
static GRID_HOST_DEVICE int idx(const orbital a)
Return coset index of given orbital angular momentum.
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_get_element(matrix, irow_global, icol_global, alpha, local)
returns an element of a fm this value is valid on every cpu using this call is expensive
subroutine, public cp_fm_set_element(matrix, irow_global, icol_global, alpha)
sets an element of a matrix
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
Dense density mixing for active-space embedding.
character(len=15) function, public active_space_mixing_label(active_space_env)
Return the current active-space mixer label for iteration output.
subroutine, public update_active_density(p_act_mo_a, active_space_env, p_act_mo_b)
Update active space density matrix from Fortran arrays.
subroutine, public initialize_active_space_mixing(active_space_env, as_input)
Initialize the density mixer used in the self-consistent active-space embedding loop.
The types needed for the calculation of active space Hamiltonians.
module that contains the definitions of the scf types
integer, parameter, public broyden_mixing_nr
integer, parameter, public modified_broyden_mixing_nr
integer, parameter, public no_mixing_nr
integer, parameter, public direct_mixing_nr
integer, parameter, public multisecant_mixing_nr
integer, parameter, public pulay_mixing_nr
subroutine, public mixing_storage_create(mixing_store, mixing_section, mixing_method, ecut)
creates a mixing_storage
integer, parameter, public gspace_mixing_nr
represent a full matrix