27 use,
intrinsic :: iso_fortran_env
79 integer :: calculation_mode
81 logical :: unitary_transform
87 type(states_elec_t) :: adiabatic_st
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
107 type(restart_t) :: restart_load
116 call states_elec_load(restart_load, namespace, space, adiabatic_st, gr, hm%kpoints, &
117 ierr, label =
': Adiabatic states')
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
132 integer :: cols_t1t2_block
153 if (
parse_block(namespace,
'TDDMPropagation_2Times', blk) == 0)
then
155 if (cols_t1t2_block == 2)
then
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),
'] ', &
166 message(1) =
"Input: TDDMPropagation_2Times block must have 2 columns."
183 call parse_variable(namespace,
'TDDMPropagationBasis', option__tddmpropagationbasis__adiabatic, this%basis)
197 call parse_variable(namespace,
'TDDMUnitaryTransformFix', .false., this%unitary_transform)
201 message(1) =
"Warning: TDDMPropagation requires a number of empty states."
202 message(2) =
" Add ExtraStates and rerun."
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."
210 if (st%d%ispin ==
spinors)
then
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
224 type(
grid_t),
intent(in) :: gr
225 type(
ions_t),
intent(in) :: ions
229 type(
v_ks_t),
intent(inout) :: ks
230 integer,
intent(in) :: iter
231 real(real64),
intent(in) :: dt
233 logical,
optional,
intent(in) :: update_energy
235 real(real64),
parameter :: ZERO = 1.0e-10_real64
237 real(real64) :: population(3), leak
239 logical :: update_energy_
240 complex(real64),
allocatable :: resd(:, :, :), rho_mat(:, :), conj_psi_phi(:, :)
246 call hm%update(gr, namespace, space, ext_partners, time=iter * dt)
248 if (dmp%basis == option__tddmpropagationbasis__adiabatic)
then
249 call eigensolver_init(eigens, namespace, gr, dmp%adiabatic_st, hm, mc, space)
251 call eigens%run(namespace, gr, dmp%adiabatic_st, hm, space, ext_partners, iter)
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))
259 population = 0.0_real64
261 do ik = st%d%kpt%start, st%d%kpt%end
262 population(1) = population(1) + sum(st%occ(:, ik) * st%kweights(ik))
275 call dissipation(dmp,dmp%adiabatic_st, st, ik, dt, rho_mat)
277 call update_st(dmp, ik, gr, resd, st, rho_mat)
280 population(3) = population(3) + sum(st%occ(:, ik))*st%kweights(ik)
283 safe_deallocate_a(resd)
284 safe_deallocate_a(rho_mat)
285 safe_deallocate_a(conj_psi_phi)
287 call st%d%kpt%mpi_grp%allreduce_inplace(population, 3, mpi_double_precision, mpi_sum)
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'
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
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_)
305 if (dmp%basis == option__tddmpropagationbasis__adiabatic)
then
320 integer,
intent(in) :: ik
322 type(
grid_t),
intent(in) :: gr
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(:, :)
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))
339 overlap(jst, jst) =
zmf_dotp(gr, st%d%dim, psij, psij, reduce = .false.)
340 do ist = jst + 1, st%nst
342 overlap(ist, jst) =
zmf_dotp(gr, st%d%dim, psii, psij, reduce = .false.)
346 call gr%allreduce(overlap)
349 safe_deallocate_a(psii)
350 safe_deallocate_a(psij)
354 rho_mat(ist, jst) = overlap(ist, 1) * overlap(1, jst) * st%occ(1, ik)
356 rho_mat(ist, jst) = rho_mat(ist, jst) + overlap(ist, lst) * overlap(lst, jst) * st%occ(lst, ik)
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
371 safe_deallocate_a(overlap)
372 safe_deallocate_a(rho_mat)
390 integer,
intent(in) :: ik
392 type(
grid_t),
intent(in) :: gr
393 complex(real64),
intent(out) :: conj_psi_phi(:, :)
394 complex(real64),
intent(out) :: resd(:, :, :)
397 complex(real64),
allocatable :: psi(:, :), phi(:, :)
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)
407 safe_allocate(psi(1:gr%np, 1:st%d%dim))
408 safe_allocate(phi(1:gr%np, 1:st%d%dim))
414 conj_psi_phi(ist, jst) =
zmf_dotp(gr, st%d%dim, phi, psi, reduce = .false.)
417 call gr%allreduce(conj_psi_phi(:, 1:st%nst))
423 call lalg_axpy(gr%np, st%d%dim, -conj_psi_phi(jst, ist), phi, resd(:, :, jst))
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.)
433 call gr%allreduce(conj_psi_phi(:, 1+st%nst:2*st%nst))
435 safe_deallocate_a(psi)
436 safe_deallocate_a(phi)
451 integer,
intent(in) :: ik
453 complex(real64),
intent(in) :: conj_psi_phi(:, :)
454 complex(real64),
intent(out) :: rho_mat(:, :)
456 integer :: ist, jst, lst
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)
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)
469 rho_mat(ist, jst) = rho_mat(ist, jst) + conj_psi_phi(lst, ist) * conjg(conj_psi_phi(lst, jst)) * st%occ(lst, ik)
485 integer,
intent(in) :: ik
487 complex(real64),
intent(in) :: rho_mat(:, :)
488 real(real64),
intent(inout) :: pop
491 real(real64) :: qtot_basis
495 assert(ubound(rho_mat, dim = 1) == 2*st%nst)
496 assert(ubound(rho_mat, dim = 2) == 2*st%nst)
500 qtot_basis = qtot_basis + real(rho_mat(ist, ist), real64)
502 pop = pop + qtot_basis * st%kweights(ik)
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(:, :, :)
521 complex(real64),
intent(inout) :: rho_mat(:, :)
523 real(real64),
parameter :: ZERO = 1.0e-12_real64
524 real(real64) :: occ(1:2*st%nst)
526 complex(real64),
allocatable :: phii(:, :), phij(:, :)
527 complex(real64),
allocatable :: overlap(:, :)
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)
537 safe_allocate(overlap(1:2*st%nst, 1:2*st%nst))
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
545 safe_allocate(phii(1:gr%np, 1:st%d%dim))
546 safe_allocate(phij(1:gr%np, 1:st%d%dim))
549 if (jst <= st%nst)
then
552 phij = resd(:, :, jst-st%nst)
554 overlap(jst, jst) =
zmf_dotp(gr, st%d%dim, phij, phij, reduce = .false.)
556 do ist = jst + 1, 2*st%nst
557 if (ist <= st%nst)
then
560 phii = resd(:, :, ist-st%nst)
563 overlap(ist, jst) =
zmf_dotp(gr, st%d%dim, phii, phij, reduce = .false.)
568 call gr%allreduce(overlap)
570 safe_deallocate_a(phii)
571 safe_deallocate_a(phij)
575 safe_deallocate_a(overlap)
577 if (dmp%unitary_transform)
then
580 call update_wfc_occ(dmp%adiabatic_st, ik, st, gr, resd, rho_mat, occ)
592 subroutine update_wfc_occ(adiabatic_st, ik, st, gr, resd, rho_mat, occ)
594 integer,
intent(in) :: ik
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)
602 complex(real64),
allocatable :: psi(:, :), phij(:, :)
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)
612 safe_allocate(psi(1:gr%np, 1:st%d%dim))
613 safe_allocate(phij(1:gr%np, 1:st%d%dim))
620 call lalg_axpy(gr%np, st%d%dim, rho_mat(jst, ist+st%nst), phij, psi)
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)
630 st%occ(1:st%nst, ik) = occ(1+st%nst:2*st%nst)
632 safe_deallocate_a(psi)
633 safe_deallocate_a(phij)
665 integer,
intent(in) :: ik
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)
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(:, :)
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)
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))
700 call lalg_axpy(gr%np, st%d%dim, rho_mat(jst, ist), phi, psi_tilde)
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)
709 overlap_procrus(ist, jst) =
zmf_dotp(gr, st%d%dim, psi_tilde, psi, reduce = .false.)
712 call gr%allreduce(overlap_procrus)
715 uproj = matmul(uu(:,1:st%nst), vt)
717 safe_deallocate_a(overlap_procrus)
718 safe_deallocate_a(uu)
719 safe_deallocate_a(vt)
726 if (occ(jst) > zero)
then
727 uji = uproj(jst, ist)*
sqrt(occ(jst))
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)
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)
740 call lalg_axpy(gr%np, st%d%dim, uproj(jst, ist)*rho_mat(lst, jst), phi, psi)
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)
749 norm =
zmf_nrm2(gr, st%d%dim, psi_tilde, reduce = .
true.)**2
750 st%occ(ist, ik) = norm
753 safe_deallocate_a(psi)
754 safe_deallocate_a(psi_tilde)
755 safe_deallocate_a(phi)
756 safe_deallocate_a(uproj)
775 type(
dmp_t),
intent(in) :: dmp
778 integer,
intent(in) :: ik
779 real(real64),
intent(in) :: dt
780 complex(real64),
intent(inout) :: nn(:,:)
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
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))
794 t2 = dmp%t(2)*
sqrt(real(st%nik, real64)*st%nst/2)
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
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
810 trace_before_dissipation = 0.0_real64
812 trace_before_dissipation = trace_before_dissipation + real(nn(a, a))
821 nn_current(a,b) = nn_current(a,b) + dmatrix(a,b,c,d) * nn(c,d)
829 nn(a,b) = nn(a,b) + (nn_current(a,b)*dt)/
factorial(i)
836 trace_after_dissipation = 0.0_real64
838 trace_after_dissipation =trace_after_dissipation + real(nn(a, a))
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)
847 safe_deallocate_a(nn_current)
848 safe_deallocate_a(dmatrix)
constant times a vector plus a vector
This module implements common operations on batches of mesh functions.
type(debug_t), save, public debug
This module implements a calculator for the density and defines related functions.
subroutine, public density_calc(st, gr, density, istin)
Computes the density from the orbitals in st.
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
complex(real64), parameter, public m_z0
real(real64), parameter, public m_half
real(real64), parameter, public m_one
real(real64), parameter, public m_min_occ
Minimal occupation that is considered to be non-zero.
This module implements the underlying real-space grid.
This module defines classes and functions for interaction partners.
This module contains interfaces for LAPACK routines.
This module is intended to contain "only mathematical" functions and procedures.
recursive integer function, public factorial(n)
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.
subroutine, public messages_not_implemented(feature, namespace)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_input_error(namespace, var, details, row, column)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
This module handles the communicators for the various parallelization strategies.
this module contains the low-level part of the output system
integer function, public parse_block(namespace, name, blk, check_varinfo_)
integer, parameter, public restart_gs
subroutine, public restart_init(restart, namespace, data_type, type, mc, ierr, mesh, dir, exact)
Initializes a restart object.
integer, parameter, public restart_type_load
subroutine, public restart_end(restart)
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.
character(len=20) pure function, public units_abbrev(this)
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)
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.
Stores all communicators and groups.
The states_elec_t class contains all electronic wave functions.