Octopus
dm_propagation.F90
Go to the documentation of this file.
1!! Copyright (C) 2024 - 2025 S. Pal, Z. Nie, U. De Giovannini
2!! This program is free software; you can redistribute it and/or modify
3!! it under the terms of the GNU General Public License as published by
4!! the Free Software Foundation; either version 2, or (at your option)
5!! any later version.
6!!
7!! This program is distributed in the hope that it will be useful,
8!! but WITHOUT ANY WARRANTY; without even the implied warranty of
9!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10!! GNU General Public License for more details.
11!!
12!! You should have received a copy of the GNU General Public License
13!! along with this program; if not, write to the Free Software
14!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15!! 02110-1301, USA.
16!!
17
18#include "global.h"
19
21 use debug_oct_m
24 use global_oct_m
25 use grid_oct_m
27 use, intrinsic :: iso_fortran_env
29 use ions_oct_m
33 use math_oct_m
34 use mesh_oct_m
38 use mpi_oct_m
41 use parser_oct_m
44 use space_oct_m
47 use unit_oct_m
50 use lapack_oct_m
54 use v_ks_oct_m
59
60 implicit none
61
62 private
63
64 public :: &
65 dmp_t, &
68
77 type dmp_t
78
79 integer :: calculation_mode
80 integer :: basis
81 logical :: unitary_transform
82 real(real64) :: t(2)
83 ! Initialised from GS KS states, so included in this class so adiabatic_st can be returned
84 ! from td_init_run. Note, one could alternatively do in dm_propagation_run:
85 ! if(iter==1) call states_elec_copy(dmp%adiabatic_st, st, special=.true.)
86 ! as I am not sure if the restart calls are required.
87 type(states_elec_t) :: adiabatic_st
88 !
89 contains
90 procedure :: init => dmp_init
91 end type dmp_t
92
93
94contains
95
97 subroutine dm_propagation_init_run(adiabatic_st, namespace, space, gr, st, hm, mc)
98 type(states_elec_t), intent(inout) :: adiabatic_st
99 type(namespace_t), intent(in) :: namespace
100 type(electron_space_t), intent(in) :: space
101 type(grid_t), intent(in) :: gr
102 type(states_elec_t), intent(in) :: st
103 type(hamiltonian_elec_t), intent(in) :: hm
104 type(multicomm_t), intent(in) :: mc
105
106 integer :: ierr
107 type(restart_t) :: restart_load
108
110
111 ! By default, wavefunctions are copied. In principle, exclude_eigenval should be true.
112 ! But we need its allocation
113 call states_elec_copy(adiabatic_st, st, special=.true.)
114 call restart_init(restart_load, namespace, restart_gs, restart_type_load, mc, ierr, mesh=gr, exact =.true.)
115 if (ierr == 0) then
116 call states_elec_load(restart_load, namespace, space, adiabatic_st, gr, hm%kpoints, &
117 ierr, label = ': Adiabatic states')
118 end if
119 call restart_end(restart_load)
120
122
123 end subroutine dm_propagation_init_run
124
125
127 subroutine dmp_init(this, namespace, st)
128 class(dmp_t), intent(out) :: this
129 type(namespace_t), intent(in) :: namespace
130 type(states_elec_t), intent(in) :: st
131
132 integer :: cols_t1t2_block
133 type(block_t) :: blk
134
135 push_sub(dmp_init)
136
137 !%Variable TDDMPropagation_2Times
138 !%Type block
139 !%Section Time-Dependent
140 !%Description
141 !% Two times approximation for the jump operator in the master equation.
142 !%
143 !% <tt>%TDDMPropagation_2Times
144 !% <br>&nbsp;&nbsp; t1 | t2
145 !% <br>%</tt>
146 !%End
147
148 cols_t1t2_block = 0
149 !TODO: maybe define some more reasonable defaults
150 this%t(1) = m_zero
151 this%t(2) = m_one
152
153 if (parse_block(namespace, 'TDDMPropagation_2Times', blk) == 0) then
154 cols_t1t2_block = parse_block_cols(blk, 0)
155 if (cols_t1t2_block == 2) then
156 call parse_block_float(blk, 0, 0, this%t(1), units_inp%time)
157 call parse_block_float(blk, 0, 1, this%t(2), units_inp%time)
158 call parse_block_end(blk)
159
160 message(1) = "Info: TDDMPropagation 2-times approximation:"
161 write(message(2),'(a, f12.6, a, f12.6, a,a)') &
162 ' [t1, t2] = [', this%t(1) , ', ', this%t(2), '] ', &
163 trim(units_abbrev(units_out%time))
164 call messages_info(2, namespace=namespace)
165 else
166 message(1) = "Input: TDDMPropagation_2Times block must have 2 columns."
167 call messages_fatal(1, namespace=namespace)
168 end if
169 end if
171 !%Variable TDDMPropagationBasis
172 !%Type integer
173 !%Default Adiabatic
174 !%Section Time-Dependent
175 !%Description
176 !% Decides the basis set for the density matrix propagation.
177 !%Option Adiabatic 01
178 !% Istantaneous eigenstates of the Hamiltonian.
179 !%Option Groundstate 02
180 !% Eigenstates of the Hamiltonian at t=0.
181 !%End
182
183 call parse_variable(namespace, 'TDDMPropagationBasis', option__tddmpropagationbasis__adiabatic, this%basis)
184 if (.not. varinfo_valid_option('TDDMPropagationBasis', this%basis)) then
185 call messages_input_error(namespace, 'TDDMPropagationBasis')
186 endif
187 call messages_print_var_option('TDDMPropagationBasis', this%basis, namespace=namespace)
188
189 !%Variable TDDMUnitaryTransformFix
190 !%Type logical
191 !%Default no
192 !%Section Time-Dependent
193 !%Description
194 !% Applies an additional unitary transformation to the damped wavefunctions
195 !% to maximize their overlap with the reference wavefunctions before damping.
196 !%End
197 call parse_variable(namespace, 'TDDMUnitaryTransformFix', .false., this%unitary_transform)
198
199 !Sanity checks
200 if (all(st%occ >= m_min_occ)) then
201 message(1) = "Warning: TDDMPropagation requires a number of empty states."
202 message(2) = " Add ExtraStates and rerun."
203 call messages_fatal(2, namespace=namespace)
204 else if (st%parallel_in_states) then
205 message(1) = "Warning: TDDMPropagation does not support parallel states."
206 message(2) = " Remove ParallelStates and rerun."
207 call messages_fatal(2, namespace=namespace)
208 end if
209
210 if (st%d%ispin == spinors) then
211 call messages_not_implemented('TDDMPropagation with spinors', namespace=namespace)
212 end if
213
214 pop_sub(dmp_init)
215
216 end subroutine dmp_init
217
218
220 subroutine dm_propagation_run(dmp, namespace, space, gr, ions, st, mc, hm, ks, iter, dt, ext_partners, update_energy)
221 type(dmp_t), intent(inout) :: dmp
222 type(namespace_t), intent(in) :: namespace
223 type(electron_space_t), intent(in) :: space
224 type(grid_t), intent(in) :: gr
225 type(ions_t), intent(in) :: ions
226 type(states_elec_t), intent(inout) :: st
227 type(multicomm_t), intent(in) :: mc
228 type(hamiltonian_elec_t), intent(inout) :: hm
229 type(v_ks_t), intent(inout) :: ks
230 integer, intent(in) :: iter
231 real(real64), intent(in) :: dt
232 type(partner_list_t), intent(in) :: ext_partners
233 logical, optional,intent(in) :: update_energy
234
235 real(real64), parameter :: ZERO = 1.0e-10_real64
236 type(eigensolver_t) :: eigens
237 real(real64) :: population(3), leak
238 integer :: ik
239 logical :: update_energy_
240 complex(real64), allocatable :: resd(:, :, :), rho_mat(:, :), conj_psi_phi(:, :)
241
242 push_sub_with_profile(dm_propagation_run)
243
244 ! Update the hamiltonian. hm is updated after each td propagation.
245 ! But ions may move afterthen
246 call hm%update(gr, namespace, space, ext_partners, time=iter * dt)
247
248 if (dmp%basis == option__tddmpropagationbasis__adiabatic) then
249 call eigensolver_init(eigens, namespace, gr, dmp%adiabatic_st, hm, mc, space)
250 eigens%converged = 0
251 call eigens%run(namespace, gr, dmp%adiabatic_st, hm, space, ext_partners, iter)
252 end if
253
254 ! Compute everything
255 safe_allocate(resd(1:gr%np, 1:st%d%dim, 1:st%nst))
256 safe_allocate(rho_mat(1:2*st%nst, 1:2*st%nst))
257 safe_allocate(conj_psi_phi(1:st%nst, 1:2*st%nst)) ! (i, j) = <\phi, d_j | \psi_i >
258
259 population = 0.0_real64
260
261 do ik = st%d%kpt%start, st%d%kpt%end
262 population(1) = population(1) + sum(st%occ(:, ik) * st%kweights(ik))
263
264 if (debug%info) then
265 call orthogonality_check_ks(ik, st, gr)
266 end if
267
268 call construct_residuals(dmp%adiabatic_st, ik, st, gr, conj_psi_phi, resd)
269
270 call construct_density_matrix(ik, st, conj_psi_phi, rho_mat)
271
272 ! population before damping
273 call population_in_adiabatic(ik, st, rho_mat, population(2))
274
275 call dissipation(dmp,dmp%adiabatic_st, st, ik, dt, rho_mat)
276
277 call update_st(dmp, ik, gr, resd, st, rho_mat)
278
279 ! population after damping
280 population(3) = population(3) + sum(st%occ(:, ik))*st%kweights(ik)
281 end do
282
283 safe_deallocate_a(resd)
284 safe_deallocate_a(rho_mat)
285 safe_deallocate_a(conj_psi_phi)
286
287 call st%d%kpt%mpi_grp%allreduce_inplace(population, 3, mpi_double_precision, mpi_sum)
288
289 write(message(1), '(a,E15.8,a,E15.8,a,E15.8,a)') 'DMPopulation: ', population(1), &
290 ' (', population(2), ' in basis ) before damping; ', population(3), ' after damping'
291 call messages_info(1)
292
293 leak = population(1) - population(3)
294 if (abs(leak) > zero) then
295 write(message(1), '(a,E15.8,a,I8)') 'Leakage: ', leak, '(after damping) at time step', iter
296 call messages_info(1)
297 end if
298
299 ! renew hamiltonian
300 call density_calc(st, gr, st%rho)
301 update_energy_ = optional_default(update_energy, .true.)
302 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, calc_eigenval = update_energy_, &
303 time = abs(iter * dt), calc_energy = update_energy_)
304
305 if (dmp%basis == option__tddmpropagationbasis__adiabatic) then
306 call eigensolver_end(eigens)
307 end if
308
309 pop_sub_with_profile(dm_propagation_run)
310
311 end subroutine dm_propagation_run
312
319 subroutine orthogonality_check_ks(ik, st, gr)
320 integer, intent(in) :: ik
321 type(states_elec_t), intent(in) :: st
322 type(grid_t), intent(in) :: gr
323
324 integer :: ist, jst, lst
325 real(real64) :: dqtot
326 real(real64) :: occ(1:st%nst)
327 real(real64), parameter :: ZERO = 1.0e-12_real64
328 complex(real64), allocatable :: psii(:, :), psij(:, :), overlap(:, :), rho_mat(:, :)
329
330 push_sub(orthogonality_check_ks)
331
332 safe_allocate(psii(1:gr%np, 1:st%d%dim))
333 safe_allocate(psij(1:gr%np, 1:st%d%dim))
334 safe_allocate(overlap(1:st%nst, 1:st%nst))
335 safe_allocate(rho_mat(1:st%nst, 1:st%nst))
336
337 do jst = 1, st%nst
338 call states_elec_get_state(st, gr, jst, ik, psij)
339 overlap(jst, jst) = zmf_dotp(gr, st%d%dim, psij, psij, reduce = .false.)
340 do ist = jst + 1, st%nst
341 call states_elec_get_state(st, gr, ist, ik, psii)
342 overlap(ist, jst) = zmf_dotp(gr, st%d%dim, psii, psij, reduce = .false.)
343 end do
344 end do
345 call lower_triangular_to_hermitian(st%nst, overlap)
346 call gr%allreduce(overlap)
347
348
349 safe_deallocate_a(psii)
350 safe_deallocate_a(psij)
351
352 do jst = 1, st%nst
353 do ist = jst, st%nst
354 rho_mat(ist, jst) = overlap(ist, 1) * overlap(1, jst) * st%occ(1, ik)
355 do lst = 2, st%nst
356 rho_mat(ist, jst) = rho_mat(ist, jst) + overlap(ist, lst) * overlap(lst, jst) * st%occ(lst, ik)
357 end do
358 end do
359 end do
360 call lower_triangular_to_hermitian(st%nst, rho_mat)
361
362
363 call lalg_geneigensolve(st%nst, rho_mat, overlap, occ, preserve_mat=.false.)
364 dqtot = sum(st%occ(:, ik)) - sum(occ)
365 if (dqtot > zero) then
366 write(message(1),'(a,E12.5,a,i4)') 'TDKS wavefunctions is not fullly orthonormalized with ', dqtot, &
367 'electrons difference at ik= ', ik
368 call messages_info(1,all_nodes=.true.)
369 end if
370
371 safe_deallocate_a(overlap)
372 safe_deallocate_a(rho_mat)
373
375 end subroutine orthogonality_check_ks
376
388 subroutine construct_residuals(adiabatic_st, ik, st, gr, conj_psi_phi, resd)
389 type(states_elec_t), intent(in) :: adiabatic_st
390 integer, intent(in) :: ik
391 type(states_elec_t), intent(in) :: st
392 type(grid_t), intent(in) :: gr
393 complex(real64), intent(out) :: conj_psi_phi(:, :)
394 complex(real64), intent(out) :: resd(:, :, :)
395
396 integer :: ist, jst
397 complex(real64), allocatable :: psi(:, :), phi(:, :)
398
399 push_sub(construct_residuals)
400
401 assert(ubound(conj_psi_phi, dim = 1) == st%nst)
402 assert(ubound(conj_psi_phi, dim = 2) == 2*st%nst)
403 assert(ubound(resd, dim = 1) == gr%np)
404 assert(ubound(resd, dim = 2) == st%d%dim)
405 assert(ubound(resd, dim = 3) == st%nst)
406
407 safe_allocate(psi(1:gr%np, 1:st%d%dim))
408 safe_allocate(phi(1:gr%np, 1:st%d%dim))
409
410 do jst = 1, st%nst
411 call states_elec_get_state(adiabatic_st, gr, jst, ik, phi)
412 do ist = 1, st%nst
413 call states_elec_get_state(st, gr, ist, ik, psi)
414 conj_psi_phi(ist, jst) = zmf_dotp(gr, st%d%dim, phi, psi, reduce = .false.)
415 end do
416 end do
417 call gr%allreduce(conj_psi_phi(:, 1:st%nst))
418
419 do jst = 1, st%nst
420 call states_elec_get_state(st, gr, jst, ik, resd(:, :, jst))
421 do ist = 1, st%nst
422 call states_elec_get_state(adiabatic_st, gr, ist, ik, phi)
423 call lalg_axpy(gr%np, st%d%dim, -conj_psi_phi(jst, ist), phi, resd(:, :, jst))
424 end do
425 end do
426
427 do ist = 1, st%nst
428 call states_elec_get_state(st, gr, ist, ik, psi)
429 do jst = 1+st%nst, 2*st%nst
430 conj_psi_phi(ist, jst) = zmf_dotp(gr, st%d%dim, resd(:, :, jst-st%nst), psi, reduce = .false.)
431 end do
432 end do
433 call gr%allreduce(conj_psi_phi(:, 1+st%nst:2*st%nst))
434
435 safe_deallocate_a(psi)
436 safe_deallocate_a(phi)
437
438 pop_sub(construct_residuals)
439 end subroutine construct_residuals
440
450 subroutine construct_density_matrix(ik, st, conj_psi_phi, rho_mat)
451 integer, intent(in) :: ik
452 type(states_elec_t), intent(in) :: st
453 complex(real64), intent(in) :: conj_psi_phi(:, :)
454 complex(real64), intent(out) :: rho_mat(:, :)
455
456 integer :: ist, jst, lst
457
459
460 assert(ubound(conj_psi_phi, dim = 1) == st%nst)
461 assert(ubound(conj_psi_phi, dim = 2) == 2*st%nst)
462 assert(ubound(rho_mat, dim = 1) == 2*st%nst)
463 assert(ubound(rho_mat, dim = 2) == 2*st%nst)
464
465 do jst = 1, 2*st%nst
466 do ist = jst, 2*st%nst
467 rho_mat(ist, jst) = conj_psi_phi(1, ist) * conjg(conj_psi_phi(1, jst)) * st%occ(1, ik)
468 do lst = 2, st%nst
469 rho_mat(ist, jst) = rho_mat(ist, jst) + conj_psi_phi(lst, ist) * conjg(conj_psi_phi(lst, jst)) * st%occ(lst, ik)
470 end do
471 end do
472 end do
473 call lower_triangular_to_hermitian(2*st%nst, rho_mat)
474
476 end subroutine construct_density_matrix
477
484 subroutine population_in_adiabatic(ik, st, rho_mat, pop)
485 integer, intent(in) :: ik
486 type(states_elec_t), intent(in) :: st
487 complex(real64), intent(in) :: rho_mat(:, :)
488 real(real64),intent(inout) :: pop
489
490 integer :: ist
491 real(real64) :: qtot_basis
492
494
495 assert(ubound(rho_mat, dim = 1) == 2*st%nst)
496 assert(ubound(rho_mat, dim = 2) == 2*st%nst)
497
498 qtot_basis = m_zero
499 do ist = 1, st%nst
500 qtot_basis = qtot_basis + real(rho_mat(ist, ist), real64)
501 end do
502 pop = pop + qtot_basis * st%kweights(ik)
503
505 end subroutine population_in_adiabatic
506
515 subroutine update_st(dmp, ik, gr, resd, st, rho_mat)
516 type(dmp_t), intent(in) :: dmp
517 integer, intent(in) :: ik
518 type(grid_t), intent(in) :: gr
519 complex(real64), intent(in) :: resd(:, :, :)
520 type(states_elec_t), intent(inout) :: st
521 complex(real64), intent(inout) :: rho_mat(:, :)
522
523 real(real64), parameter :: ZERO = 1.0e-12_real64
524 real(real64) :: occ(1:2*st%nst)
525 integer :: ist, jst
526 complex(real64), allocatable :: phii(:, :), phij(:, :)
527 complex(real64), allocatable :: overlap(:, :)
528
529 push_sub(update_st)
530
531 assert(ubound(resd, dim = 1) == gr%np)
532 assert(ubound(resd, dim = 2) == st%d%dim)
533 assert(ubound(resd, dim = 3) == st%nst)
534 assert(ubound(rho_mat, dim = 1) == 2*st%nst)
535 assert(ubound(rho_mat, dim = 2) == 2*st%nst)
536
537 safe_allocate(overlap(1:2*st%nst, 1:2*st%nst))
538
539 if (maxval(abs(rho_mat - transpose(conjg(rho_mat)))) > zero) then
540 write(message(1),'(a,E12.5,a,i4)') "rho_mat is not Hermitian! Max deviation = ", &
541 maxval(abs(rho_mat - transpose(conjg(rho_mat)))), ' at ik= ', ik
542 call messages_fatal(1)
543 end if
544
545 safe_allocate(phii(1:gr%np, 1:st%d%dim))
546 safe_allocate(phij(1:gr%np, 1:st%d%dim))
547
548 do jst = 1, 2*st%nst
549 if (jst <= st%nst) then
550 call states_elec_get_state(dmp%adiabatic_st, gr, jst, ik, phij)
551 else
552 phij = resd(:, :, jst-st%nst)
553 end if
554 overlap(jst, jst) = zmf_dotp(gr, st%d%dim, phij, phij, reduce = .false.)
555
556 do ist = jst + 1, 2*st%nst
557 if (ist <= st%nst) then
558 call states_elec_get_state(dmp%adiabatic_st, gr, ist, ik, phii)
559 else
560 phii = resd(:, :, ist-st%nst)
561 end if
562
563 overlap(ist, jst) = zmf_dotp(gr, st%d%dim, phii, phij, reduce = .false.)
564
565 end do
566 end do
567 call lower_triangular_to_hermitian(2*st%nst, overlap)
568 call gr%allreduce(overlap)
569
570 safe_deallocate_a(phii)
571 safe_deallocate_a(phij)
572
573 call lalg_geneigensolve(2*st%nst, rho_mat, overlap, occ, preserve_mat=.false.)
574
575 safe_deallocate_a(overlap)
576
577 if (dmp%unitary_transform) then
578 call update_wfc_occ_procrustes(dmp%adiabatic_st, ik, st, gr, resd, rho_mat, occ)
579 else
580 call update_wfc_occ(dmp%adiabatic_st, ik, st, gr, resd, rho_mat, occ)
581 end if
582
583 pop_sub(update_st)
584 end subroutine update_st
585
592 subroutine update_wfc_occ(adiabatic_st, ik, st, gr, resd, rho_mat, occ)
593 type(states_elec_t), intent(in) :: adiabatic_st
594 integer, intent(in) :: ik
595 type(states_elec_t), intent(inout) :: st
596 type(grid_t), intent(in) :: gr
597 complex(real64), intent(in) :: resd(:, :, :)
598 complex(real64), intent(in) :: rho_mat(:, :)
599 real(real64), intent(in) :: occ(1:2*st%nst)
600
601 integer :: ist, jst
602 complex(real64), allocatable :: psi(:, :), phij(:, :)
603
604 push_sub(update_wfc_occ)
605
606 assert(ubound(resd, dim = 1) == gr%np)
607 assert(ubound(resd, dim = 2) == st%d%dim)
608 assert(ubound(resd, dim = 3) == st%nst)
609 assert(ubound(rho_mat, dim = 1) == 2*st%nst)
610 assert(ubound(rho_mat, dim = 2) == 2*st%nst)
611
612 safe_allocate(psi(1:gr%np, 1:st%d%dim))
613 safe_allocate(phij(1:gr%np, 1:st%d%dim))
614
615 ! update wave functions
616 do ist = 1, st%nst
617 psi = m_z0
618 do jst = 1, st%nst
619 call states_elec_get_state(adiabatic_st, gr, jst, ik, phij)
620 call lalg_axpy(gr%np, st%d%dim, rho_mat(jst, ist+st%nst), phij, psi)
621 end do
622 do jst = 1+st%nst, 2*st%nst
623 call lalg_axpy(gr%np, st%d%dim, rho_mat(jst, ist+st%nst), resd(:, :, jst-st%nst), psi)
624 end do
625 call zmf_normalize(gr, st%d%dim, psi)
626 call states_elec_set_state(st, gr, ist, ik, psi)
627 end do
628
629 ! update occupation
630 st%occ(1:st%nst, ik) = occ(1+st%nst:2*st%nst)
631
632 safe_deallocate_a(psi)
633 safe_deallocate_a(phij)
634
635 pop_sub(update_wfc_occ)
636 end subroutine update_wfc_occ
637
663 subroutine update_wfc_occ_procrustes(adiabatic_st, ik, st, gr, resd, rho_mat, occ)
664 type(states_elec_t), intent(in) :: adiabatic_st
665 integer, intent(in) :: ik
666 type(states_elec_t), intent(inout) :: st
667 type(grid_t), intent(in) :: gr
668 complex(real64), intent(in) :: resd(:, :, :)
669 complex(real64), intent(in) :: rho_mat(:, :)
670 real(real64), intent(in) :: occ(1:2*st%nst)
671
672 integer :: ist, jst, lst
673 complex(real64) :: uji
674 complex(real64), allocatable :: overlap_procrus(:, :), uproj(:, :)
675 complex(real64), allocatable :: uu(:, :), vt(:, :)
676 real(real64) :: sg_values(1:st%nst), norm
677 real(real64), parameter :: ZERO = 1.0e-12_real64
678 complex(real64), allocatable :: psi(:, :), psi_tilde(:, :), phi(:, :)
679
681
682 assert(ubound(resd, dim = 1) == gr%np)
683 assert(ubound(resd, dim = 2) == st%d%dim)
684 assert(ubound(resd, dim = 3) == st%nst)
685 assert(ubound(rho_mat, dim = 1) == 2*st%nst)
686 assert(ubound(rho_mat, dim = 2) == 2*st%nst)
687
688 safe_allocate(psi(1:gr%np, 1:st%d%dim))
689 safe_allocate(psi_tilde(1:gr%np, 1:st%d%dim))
690 safe_allocate(phi(1:gr%np, 1:st%d%dim))
691 safe_allocate(overlap_procrus(1:2*st%nst,1:st%nst))
692 safe_allocate(uproj(1:2*st%nst, 1:st%nst))
693 safe_allocate(uu(1:2*st%nst, 1:2*st%nst))
694 safe_allocate(vt(1:st%nst, 1:st%nst))
695
696 do ist = 1, 2*st%nst
697 psi_tilde = m_z0
698 do jst = 1, st%nst
699 call states_elec_get_state(adiabatic_st, gr, jst, ik, phi)
700 call lalg_axpy(gr%np, st%d%dim, rho_mat(jst, ist), phi, psi_tilde)
701 end do
702 do jst = 1+st%nst, 2*st%nst
703 call lalg_axpy(gr%np, st%d%dim, rho_mat(jst, ist), resd(:, :, jst-st%nst), psi_tilde)
704 end do
705 call zmf_normalize(gr, st%d%dim, psi_tilde)
706
707 do jst = 1, st%nst
708 call states_elec_get_state(st, gr, jst, ik, psi)
709 overlap_procrus(ist, jst) = zmf_dotp(gr, st%d%dim, psi_tilde, psi, reduce = .false.)
710 end do
711 end do
712 call gr%allreduce(overlap_procrus)
713
714 call lalg_singular_value_decomp(2*st%nst, st%nst, overlap_procrus, uu, vt, sg_values)
715 uproj = matmul(uu(:,1:st%nst), vt)
716
717 safe_deallocate_a(overlap_procrus)
718 safe_deallocate_a(uu)
719 safe_deallocate_a(vt)
720
721 ! update wavefunctions and occupation
722 do ist = 1, st%nst
723 psi = m_z0
724 psi_tilde = m_z0
725 do jst = 1, 2*st%nst
726 if (occ(jst) > zero) then
727 uji = uproj(jst, ist)*sqrt(occ(jst))
728 do lst = 1, st%nst
729 call states_elec_get_state(adiabatic_st, gr, lst, ik, phi)
730 call lalg_axpy(gr%np, st%d%dim, uproj(jst, ist)*rho_mat(lst, jst), phi, psi)
731 call lalg_axpy(gr%np, st%d%dim, uji*rho_mat(lst, jst), phi, psi_tilde)
732 end do
733 do lst = 1+st%nst, 2*st%nst
734 call lalg_axpy(gr%np, st%d%dim, uproj(jst, ist)*rho_mat(lst, jst), resd(:, :, lst-st%nst), psi)
735 call lalg_axpy(gr%np, st%d%dim, uji*rho_mat(lst, jst), resd(:, :, lst-st%nst), psi_tilde)
736 end do
737 else
738 do lst = 1, st%nst
739 call states_elec_get_state(adiabatic_st, gr, lst, ik, phi)
740 call lalg_axpy(gr%np, st%d%dim, uproj(jst, ist)*rho_mat(lst, jst), phi, psi)
741 end do
742 do lst = 1+st%nst, 2*st%nst
743 call lalg_axpy(gr%np, st%d%dim, uproj(jst, ist)*rho_mat(lst, jst), resd(:, :, lst-st%nst), psi)
744 end do
745 end if
746 end do
747 call zmf_normalize(gr, st%d%dim, psi)
748 call states_elec_set_state(st, gr, ist, ik, psi)
749 norm = zmf_nrm2(gr, st%d%dim, psi_tilde, reduce = .true.)**2
750 st%occ(ist, ik) = norm
751 end do
752
753 safe_deallocate_a(psi)
754 safe_deallocate_a(psi_tilde)
755 safe_deallocate_a(phi)
756 safe_deallocate_a(uproj)
757
759 end subroutine update_wfc_occ_procrustes
760
774 subroutine dissipation(dmp, bst, st, ik, dt, nn)
775 type(dmp_t), intent(in) :: dmp
776 type(states_elec_t), intent(in) :: bst
777 type(states_elec_t), intent(in) :: st
778 integer, intent(in) :: ik
779 real(real64), intent(in) :: dt
780 complex(real64), intent(inout) :: nn(:,:)
781
782 complex(real64), allocatable :: DMatrix(:,:,:,:), nn_current(:,:)
783 real(real64) :: trace_before_dissipation, trace_after_dissipation, difference
784 real(real64) :: tol = 1.0e-10_real64
785 complex(real64) :: gamma
786 integer :: i, a, b, c, d, m, n
787 integer, parameter :: order = 4
788 real(real64) :: t2
789
790 push_sub_with_profile(dissipation)
791 safe_allocate(nn_current(1:bst%nst, 1:bst%nst))
792 safe_allocate(dmatrix(1:bst%nst, 1:bst%nst, 1:bst%nst, 1:bst%nst))
793 ! t2 is same for all k-points
794 t2 = dmp%t(2)*sqrt(real(st%nik, real64)*st%nst/2)
795
796 dmatrix = m_z0
797 do m = bst%st_start, bst%st_end
798 gamma = bst%occ(m, ik)/t2
799 do n = bst%st_start, bst%st_end
800 if (m /= n) then
801 dmatrix(m, m, n, n) = dmatrix(m,m,n,n) + gamma
802 do a = bst%st_start, bst%st_end
803 dmatrix(a, n, a, n) = dmatrix(a, n, a, n) - m_half*gamma
804 dmatrix(n, a, n, a) = dmatrix(n, a, n, a) - m_half*gamma
805 end do ! a
806 end if
807 end do ! n
808 end do ! m
809
810 trace_before_dissipation = 0.0_real64
811 do a = 1, bst%nst
812 trace_before_dissipation = trace_before_dissipation + real(nn(a, a))
813 end do
814
815 do i = 1, order
816 nn_current = m_z0
817 do d= 1, bst%nst
818 do c= 1, bst%nst
819 do b= 1, bst%nst
820 do a = 1, bst%nst
821 nn_current(a,b) = nn_current(a,b) + dmatrix(a,b,c,d) * nn(c,d)
822 end do
823 end do
824 end do
825 end do
826 ! Add to output nn
827 do a = 1, bst%nst
828 do b = 1, bst%nst
829 nn(a,b) = nn(a,b) + (nn_current(a,b)*dt)/ factorial(i)
830 end do
831 end do
832 end do
833
834 call symmetrize_matrix(bst%nst, nn)
835
836 trace_after_dissipation = 0.0_real64
837 do a = 1, bst%nst
838 trace_after_dissipation =trace_after_dissipation + real(nn(a, a))
839 end do
840
841 difference = trace_after_dissipation - trace_before_dissipation
842 if (abs(difference) > tol) then
843 write(message(1), '(A, ES12.5)') "Trace difference is non-zero in multiply_dissipator! = ", abs(difference)
844 call messages_fatal(1)
845 end if
846
847 safe_deallocate_a(nn_current)
848 safe_deallocate_a(dmatrix)
849
850 pop_sub_with_profile(dissipation)
851
852 end subroutine dissipation
853
854end module dm_propagation_oct_m
constant times a vector plus a vector
Definition: lalg_basic.F90:171
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:116
type(debug_t), save, public debug
Definition: debug.F90:156
This module implements a calculator for the density and defines related functions.
Definition: density.F90:120
subroutine, public density_calc(st, gr, density, istin)
Computes the density from the orbitals in st.
Definition: density.F90:610
subroutine construct_residuals(adiabatic_st, ik, st, gr, conj_psi_phi, resd)
Construct the residual basis from the TDKS wavefunctions.
subroutine construct_density_matrix(ik, st, conj_psi_phi, rho_mat)
Construct the full density matrix in the adiabatic and residual basis.
subroutine, public dm_propagation_init_run(adiabatic_st, namespace, space, gr, st, hm, mc)
Initialise the adiabatic states prior to running TB propagation.
subroutine dissipation(dmp, bst, st, ik, dt, nn)
Apply dissipation to the density matrix This subroutine applies the dissipation operator to the densi...
subroutine dmp_init(this, namespace, st)
Initialise an instance of density matrix dissipation.
subroutine update_st(dmp, ik, gr, resd, st, rho_mat)
Diagonalize the density matrix and update the wavefunction and occupation.
subroutine population_in_adiabatic(ik, st, rho_mat, pop)
Calculate population in adiabatic basis.
subroutine update_wfc_occ(adiabatic_st, ik, st, gr, resd, rho_mat, occ)
Transform the wavefunctions into real-space basis The wavefunctions in real-space basis are given by:
subroutine, public dm_propagation_run(dmp, namespace, space, gr, ions, st, mc, hm, ks, iter, dt, ext_partners, update_energy)
Apply dissipation to a TD run via the Linblad formalism.
subroutine orthogonality_check_ks(ik, st, gr)
Check orthonality and electron number of TDKS wavefunctions We constructed the density matrix from th...
subroutine update_wfc_occ_procrustes(adiabatic_st, ik, st, gr, resd, rho_mat, occ)
Make TDKS wavefunctions continuous by maximizing their overlap.
subroutine, public eigensolver_init(eigens, namespace, gr, st, hm, mc, space, deactivate_oracle)
subroutine, public eigensolver_end(eigens)
integer, parameter, public spinors
real(real64), parameter, public m_zero
Definition: global.F90:188
complex(real64), parameter, public m_z0
Definition: global.F90:198
real(real64), parameter, public m_half
Definition: global.F90:194
real(real64), parameter, public m_one
Definition: global.F90:189
real(real64), parameter, public m_min_occ
Minimal occupation that is considered to be non-zero.
Definition: global.F90:211
This module implements the underlying real-space grid.
Definition: grid.F90:117
This module defines classes and functions for interaction partners.
This module contains interfaces for LAPACK routines.
Definition: lapack.F90:118
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
recursive integer function, public factorial(n)
Definition: math.F90:289
This module defines various routines, operating on mesh functions.
subroutine, public zmf_normalize(mesh, dim, psi, norm)
Normalize a mesh function psi.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1096
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:414
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:696
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:599
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:145
this module contains the low-level part of the output system
Definition: output_low.F90:115
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:618
integer, parameter, public restart_gs
Definition: restart.F90:200
subroutine, public restart_init(restart, namespace, data_type, type, mc, ierr, mesh, dir, exact)
Initializes a restart object.
Definition: restart.F90:517
integer, parameter, public restart_type_load
Definition: restart.F90:246
subroutine, public restart_end(restart)
Definition: restart.F90:723
subroutine, public states_elec_copy(stout, stin, exclude_wfns, exclude_eigenval, special)
make a (selective) copy of a states_elec_t object
This module provides routines for communicating states when using states parallelization.
This module handles reading and writing restart information for the states_elec_t.
subroutine, public states_elec_load(restart, namespace, space, st, mesh, kpoints, ierr, iter, lr, lowest_missing, label, verbose, skip)
returns in ierr: <0 => Fatal error, or nothing read =0 => read all wavefunctions >0 => could only rea...
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:132
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:223
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
type(unit_system_t), public units_inp
the units systems for reading and writing
subroutine, public v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, calc_eigenval, time, calc_energy, calc_current, force_semilocal)
Definition: v_ks.F90:738
Density matrix dissipation.
Extension of space that contains the knowledge of the spin dimension.
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:169
Stores all communicators and groups.
Definition: multicomm.F90:206
The states_elec_t class contains all electronic wave functions.
int true(void)