(git:be2ee82)
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 = sqrt(dot_product(active_space_env%as_mix_r_buffer(ib, :), &
260 active_space_env%as_mix_r_buffer(ib, :)))
261
262 IF (nb == 1 .OR. res_norm < 1.e-14_dp) THEN
263 CALL active_space_direct_mix(p_old, p_solver, mixing_store%alpha, p_mixed)
264 ELSE
265 ALLOCATE (c(nb, nb))
266 ALLOCATE (c_inv(nb, nb))
267 ALLOCATE (alpha_c(nb))
268 ALLOCATE (p_diis(ndim))
269
270 c(:, :) = 0.0_dp
271 DO i = 1, nb
272 DO j = i, nb
273 c(j, i) = dot_product(active_space_env%as_mix_r_buffer(i, :), &
274 active_space_env%as_mix_r_buffer(j, :))
275 c(i, j) = c(j, i)
276 END DO
277 END DO
278
279 CALL invert_matrix(c, c_inv, inv_err, improve=.true.)
280 norm_c_inv = sum(c_inv)
281 IF (abs(norm_c_inv) < 1.e-14_dp) THEN
282 CALL active_space_direct_mix(p_old, p_solver, mixing_store%alpha, p_mixed)
283 ELSE
284 DO i = 1, nb
285 alpha_c(i) = sum(c_inv(:, i))/norm_c_inv
286 END DO
287
288 p_diis(:) = 0.0_dp
289 DO i = 1, nb
290 p_diis(:) = p_diis(:) + alpha_c(i)*(active_space_env%as_mix_x_buffer(i, :) + &
291 mixing_store%pulay_beta*active_space_env%as_mix_r_buffer(i, :))
292 END DO
293 IF (mixing_store%pulay_alpha > 0.0_dp) THEN
294 p_mixed = mixing_store%pulay_alpha*p_solver + &
295 (1.0_dp - mixing_store%pulay_alpha)*p_diis
296 ELSE
297 p_mixed = p_diis
298 END IF
299 END IF
300
301 DEALLOCATE (alpha_c)
302 DEALLOCATE (p_diis)
303 DEALLOCATE (c)
304 DEALLOCATE (c_inv)
305 END IF
306
307 active_space_env%as_mix_x_buffer(ibb, :) = p_mixed
308 mixing_store%iter_method = "Pulay"
309
310 END SUBROUTINE active_space_pulay_mixing
311
312! **************************************************************************************************
313!> \brief Apply original or modified Broyden mixing to the dense active-space density vector.
314!> \param active_space_env active space environment
315!> \param p_old current active-space density vector
316!> \param p_solver active-space density vector returned by the external solver
317!> \param p_mixed mixed active-space density vector
318!> \param modified use dynamic residual weights of modified Broyden
319! **************************************************************************************************
320 SUBROUTINE active_space_broyden_mixing(active_space_env, p_old, p_solver, p_mixed, modified)
321 TYPE(active_space_type), POINTER :: active_space_env
322 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: p_old, p_solver
323 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: p_mixed
324 LOGICAL, INTENT(IN) :: modified
325
326 INTEGER :: ib, j, k, nb, nbuffer, ndim
327 LOGICAL :: can_update
328 REAL(kind=dp) :: delta_norm, inv_err, res_norm, weight
329 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: c, g, p_res
330 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: a, b
331 TYPE(mixing_storage_type), POINTER :: mixing_store
332
333 ndim = SIZE(p_old)
334 CALL ensure_active_mixing_history(active_space_env, ndim)
335 mixing_store => active_space_env%as_mixing_store
336 nbuffer = mixing_store%nbuffer
337
338 ALLOCATE (p_res(ndim))
339 p_res(:) = p_solver(:) - p_old(:)
340 res_norm = sqrt(dot_product(p_res, p_res))
341
342 mixing_store%ncall = mixing_store%ncall + 1
343 IF (mixing_store%ncall == 1) THEN
344 CALL active_space_direct_mix(p_old, p_solver, mixing_store%alpha, p_mixed)
345 active_space_env%as_mix_x_old = p_old
346 active_space_env%as_mix_r_old = p_res
347 IF (modified) THEN
348 mixing_store%iter_method = "MBroy"
349 ELSE
350 mixing_store%iter_method = "Broy."
351 END IF
352 DEALLOCATE (p_res)
353 RETURN
354 END IF
355
356 nb = min(mixing_store%ncall - 1, nbuffer)
357 ib = modulo(mixing_store%ncall - 2, nbuffer) + 1
358
359 active_space_env%as_mix_r_buffer(ib, :) = p_res - active_space_env%as_mix_r_old
360 active_space_env%as_mix_x_buffer(ib, :) = p_old - active_space_env%as_mix_x_old
361 delta_norm = sqrt(dot_product(active_space_env%as_mix_r_buffer(ib, :), &
362 active_space_env%as_mix_r_buffer(ib, :)))
363 can_update = res_norm > 1.e-14_dp .AND. delta_norm > 1.e-14_dp
364
365 IF (can_update) THEN
366 active_space_env%as_mix_r_buffer(ib, :) = active_space_env%as_mix_r_buffer(ib, :)/delta_norm
367 active_space_env%as_mix_x_buffer(ib, :) = active_space_env%as_mix_x_buffer(ib, :)/delta_norm + &
368 mixing_store%alpha*active_space_env%as_mix_r_buffer(ib, :)
369
370 IF (modified) THEN
371 IF (res_norm > (mixing_store%wc/mixing_store%wmax)) THEN
372 active_space_env%as_mix_weight(ib) = mixing_store%wc/res_norm
373 ELSE
374 active_space_env%as_mix_weight(ib) = mixing_store%wmax
375 END IF
376 active_space_env%as_mix_weight(ib) = max(1.0_dp, active_space_env%as_mix_weight(ib))
377 END IF
378
379 ALLOCATE (a(nb, nb))
380 ALLOCATE (b(nb, nb))
381 ALLOCATE (c(nb))
382 ALLOCATE (g(nb))
383
384 a(:, :) = 0.0_dp
385 c(:) = 0.0_dp
386 DO j = 1, nb
387 DO k = j, nb
388 a(k, j) = dot_product(active_space_env%as_mix_r_buffer(j, :), &
389 active_space_env%as_mix_r_buffer(k, :))
390 a(j, k) = a(k, j)
391 END DO
392 END DO
393
394 DO j = 1, nb
395 c(j) = dot_product(active_space_env%as_mix_r_buffer(j, :), p_res)
396 IF (modified) THEN
397 c(j) = active_space_env%as_mix_weight(j)*c(j)
398 DO k = 1, nb
399 a(k, j) = active_space_env%as_mix_weight(k)* &
400 active_space_env%as_mix_weight(j)*a(k, j)
401 END DO
402 a(j, j) = mixing_store%broy_w0*mixing_store%broy_w0 + a(j, j)
403 ELSE
404 a(j, j) = mixing_store%broy_w0 + a(j, j)
405 END IF
406 END DO
407
408 CALL invert_matrix(a, b, inv_err)
409 g(:) = 0.0_dp
410 DO j = 1, nb
411 DO k = 1, nb
412 g(j) = g(j) + b(k, j)*c(k)
413 END DO
414 END DO
415
416 CALL active_space_direct_mix(p_old, p_solver, mixing_store%alpha, p_mixed)
417 DO j = 1, nb
418 weight = 1.0_dp
419 IF (modified) weight = active_space_env%as_mix_weight(j)
420 p_mixed = p_mixed - weight*g(j)*active_space_env%as_mix_x_buffer(j, :)
421 END DO
422
423 DEALLOCATE (a)
424 DEALLOCATE (b)
425 DEALLOCATE (c)
426 DEALLOCATE (g)
427 ELSE
428 active_space_env%as_mix_r_buffer(ib, :) = 0.0_dp
429 active_space_env%as_mix_x_buffer(ib, :) = 0.0_dp
430 CALL active_space_direct_mix(p_old, p_solver, mixing_store%alpha, p_mixed)
431 END IF
432
433 active_space_env%as_mix_x_old = p_old
434 active_space_env%as_mix_r_old = p_res
435 IF (modified) THEN
436 mixing_store%iter_method = "MBroy"
437 ELSE
438 mixing_store%iter_method = "Broy."
439 END IF
440
441 DEALLOCATE (p_res)
442
443 END SUBROUTINE active_space_broyden_mixing
444
445! **************************************************************************************************
446!> \brief Mix the dense active-space density vector.
447!> \param active_space_env active space environment
448!> \param p_old current active-space density vector
449!> \param p_solver active-space density vector returned by the external solver
450!> \param p_mixed mixed active-space density vector
451! **************************************************************************************************
452 SUBROUTINE mix_active_density_vector(active_space_env, p_old, p_solver, p_mixed)
453 TYPE(active_space_type), POINTER :: active_space_env
454 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: p_old, p_solver
455 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: p_mixed
456
457 INTEGER :: active_mix_iter
458 TYPE(mixing_storage_type), POINTER :: mixing_store
459
460 IF (active_space_env%as_mixing_method == no_mixing_nr .OR. &
461 .NOT. ASSOCIATED(active_space_env%as_mixing_store)) THEN
462 p_mixed = p_solver
463 RETURN
464 END IF
465
466 mixing_store => active_space_env%as_mixing_store
467 active_space_env%as_mixing_iter = active_space_env%as_mixing_iter + 1
468
469 IF (active_space_env%as_mixing_iter <= mixing_store%nskip_mixing) THEN
470 p_mixed = p_solver
471 mixing_store%iter_method = "NoMix"
472 RETURN
473 END IF
474
475 active_mix_iter = active_space_env%as_mixing_iter - mixing_store%nskip_mixing
476 IF (active_space_env%as_mixing_method == direct_mixing_nr .OR. &
477 active_mix_iter <= mixing_store%n_simple_mix) THEN
478 CALL active_space_direct_mix(p_old, p_solver, mixing_store%alpha, p_mixed)
479 mixing_store%iter_method = "P_Mix"
480 RETURN
481 END IF
482
483 SELECT CASE (active_space_env%as_mixing_method)
484 CASE (pulay_mixing_nr)
485 CALL active_space_pulay_mixing(active_space_env, p_old, p_solver, p_mixed)
486 CASE (broyden_mixing_nr)
487 CALL active_space_broyden_mixing(active_space_env, p_old, p_solver, p_mixed, .false.)
489 CALL active_space_broyden_mixing(active_space_env, p_old, p_solver, p_mixed, .true.)
490 CASE DEFAULT
491 cpabort("Unsupported ACTIVE_SPACE%MIXING%METHOD.")
492 END SELECT
493
494 END SUBROUTINE mix_active_density_vector
495
496! **************************************************************************************************
497!> \brief Update active space density matrix from Fortran arrays
498!> \param p_act_mo_a alpha density matrix in active space MO basis
499!> \param active_space_env active space environment
500!> \param p_act_mo_b beta density matrix in active space MO basis
501!> \author Vladimir Rybkin
502! **************************************************************************************************
503 SUBROUTINE update_active_density(p_act_mo_a, active_space_env, p_act_mo_b)
504 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: p_act_mo_a
505 TYPE(active_space_type), POINTER :: active_space_env
506 REAL(kind=dp), DIMENSION(:), INTENT(IN), OPTIONAL :: p_act_mo_b
507
508 INTEGER :: i1, i2, idx, ispin, m1, m2, nact2, &
509 nmo_active, nspins
510 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: p_mixed, p_old, p_solver
511 TYPE(cp_fm_type), POINTER :: p_active
512
513 nmo_active = active_space_env%nmo_active
514 nact2 = nmo_active*nmo_active
515 nspins = active_space_env%nspins
516 cpassert(SIZE(p_act_mo_a) == nact2)
517 IF (nspins == 2) THEN
518 IF (.NOT. PRESENT(p_act_mo_b)) cpabort("Missing beta active-space density.")
519 cpassert(SIZE(p_act_mo_b) == nact2)
520 END IF
521
522 ALLOCATE (p_mixed(nspins*nact2))
523 ALLOCATE (p_old(nspins*nact2))
524 ALLOCATE (p_solver(nspins*nact2))
525
526 p_solver(1:nact2) = p_act_mo_a
527 IF (nspins == 2) THEN
528 p_solver(nact2 + 1:2*nact2) = p_act_mo_b
529 END IF
530
531 idx = 0
532 DO ispin = 1, nspins
533 p_active => active_space_env%p_active(ispin)
534 DO i1 = 1, nmo_active
535 m1 = active_space_env%active_orbitals(i1, ispin)
536 DO i2 = 1, nmo_active
537 idx = idx + 1
538 m2 = active_space_env%active_orbitals(i2, ispin)
539 CALL cp_fm_get_element(p_active, m1, m2, p_old(idx))
540 END DO
541 END DO
542 END DO
543
544 CALL mix_active_density_vector(active_space_env, p_old, p_solver, p_mixed)
545
546 idx = 0
547 DO ispin = 1, nspins
548 p_active => active_space_env%p_active(ispin)
549 DO i1 = 1, nmo_active
550 m1 = active_space_env%active_orbitals(i1, ispin)
551 DO i2 = 1, nmo_active
552 idx = idx + 1
553 m2 = active_space_env%active_orbitals(i2, ispin)
554 CALL cp_fm_set_element(p_active, m1, m2, p_mixed(idx))
555 END DO
556 END DO
557 END DO
558
559 DEALLOCATE (p_mixed)
560 DEALLOCATE (p_old)
561 DEALLOCATE (p_solver)
562
563 END SUBROUTINE update_active_density
564
565END 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