33 use,
intrinsic :: iso_fortran_env
67 integer :: calculation_mode
69 logical :: unitary_transform
70 type(states_elec_t) :: adiabatic_st
73 type(restart_t) :: restart_dump
75 real(real64) :: tmodel(2)
76 real(real64),
allocatable :: occ_gs(:, :)
78 real(real64) :: uniform(2)
80 character(len=256) :: epw_file
82 integer :: istart, iend, wnst
85 real(real64) :: astep(3)
87 integer,
allocatable :: kmap(:)
88 type(mpi_grp_t) :: intranode_grp, internode_grp
90 type(MPI_Win) :: window_trans_rate
98 real(real32),
pointer,
volatile :: ave_trans(:)
103 subroutine dmp_init(this, namespace, st, space, hm)
104 class(dmp_t),
intent(inout) :: this
105 type(namespace_t),
intent(in) :: namespace
106 type(states_elec_t),
intent(in) :: st
107 class(space_t),
intent(in) :: space
108 type(hamiltonian_elec_t),
intent(in) :: hm
111 integer :: ncols, nempty
112 real(real64) :: nempty_percent
127 call parse_variable(namespace,
'TDDMPropagationBasis', option__tddmpropagationbasis__adiabatic, this%basis)
141 call parse_variable(namespace,
'TDDMOrthogonal', .false., this%othn)
152 call parse_variable(namespace,
'TDDMUnitaryTransformFix', .
true., this%unitary_transform)
170 if (
parse_block(namespace,
'TDDMPropagation_uniform_decay', blk) == 0)
then
171 if (this%strategy /= -1)
then
172 message(1) =
"Multiple dissipation strategies are not allowed."
182 message(1) =
"Info: TDDMPropagation uniform decay approximation:"
183 write(
message(2),
'(a, f0.2, 1x, 2a, F0.2, 1x, 2a)')
' [lifetime, temperature] = [', &
187 message(1) =
"Input: TDDMPropagation_uniform_decay block must have 2 columns."
203 if (
parse_block(namespace,
'TDDMPropagation_2Times', blk) == 0)
then
204 if (this%strategy /= -1)
then
205 message(1) =
"Multiple dissipation strategies are not allowed."
215 message(1) =
"Info: TDDMPropagation 2-times approximation:"
216 write(
message(2),
'(a, f12.6, a, f12.6, a,a)') &
217 ' [t1, t2] = [', this%tmodel(1) ,
', ', this%tmodel(2),
'] ', &
221 message(1) =
"Input: TDDMPropagation_2Times block must have 2 columns."
225 if (.not. this%othn)
then
227 message(1) =
"Overriding input: TDDMOrthogonal set to yes for TDDMPropagation_2Times."
242 call parse_variable(namespace,
'TDDMPropagation_from_epw',
'-', this%epw_file)
243 if (trim(this%epw_file) /=
'-')
then
245 write(
message(1),
'(a)')
'Only Monkhorst-Pack k-point meshes are supported in the EPW-DMPropagation strategy.'
248 if (hm%kpoints%reduced%nshifts /= 1)
then
249 write(
message(1),
'(a)')
'Multiple Monkhorst-Pack shifts are not supported in the EPW-DMPropagation strategy.'
252 if (space%dim /= 3)
then
253 write(
message(1),
'(a)')
'Only 3D systems are supported in the EPW-DMPropagation strategy.'
257 if (this%strategy /= -1)
then
258 message(1) =
"Multiple dissipation strategies are not allowed."
262 write(
message(1),
'(a, a)')
"Info: TDDMPropagation transition rates from file: ", trim(this%epw_file)
279 if (this%strategy == 3)
then
281 if (.NOT. (this%istart > 0))
then
282 write(
message(1),
'(a)')
'EPWBandLowest must be specified when TDDMPropagation_from_epw is enabled.'
289 if (this%calculation_mode == option__tddmpropagation__collision_integral .and. this%strategy /= 3)
then
290 message(1) =
"Warning: TDDMPropagation_from_epw is required for collision integral."
291 message(2) =
" Add TDDMPropagation_from_epw and rerun."
297 if (nempty == 0 .and. nempty_percent <
m_epsilon)
then
298 message(1) =
"Warning: TDDMPropagation requires a number of empty states."
299 message(2) =
" Add ExtraStates and rerun."
303 if (st%parallel_in_states)
then
304 message(1) =
"Warning: TDDMPropagation does not support parallel states."
305 message(2) =
" Remove ParallelStates and rerun."
319 type(
dmp_t),
intent(inout) :: dmp
322 type(
grid_t),
intent(in) :: gr
323 type(
ions_t),
intent(in) :: ions
327 logical,
intent(in) :: from_scratch
338 if (from_scratch .or. dmp%basis == option__tddmpropagationbasis__groundstate)
then
345 call states_elec_load(restart_load, namespace, space, dmp%adiabatic_st, gr, hm%kpoints, ierr, label =
": DM-basis")
347 message(1) =
'Unable to read DM-basis wavefunctions.'
351 call restart_load%end()
354 if (dmp%strategy == 2)
then
355 safe_allocate(dmp%occ_gs(1:st%nst, 1:st%nik))
356 dmp%occ_gs = dmp%adiabatic_st%occ
363 if (dmp%basis == option__tddmpropagationbasis__adiabatic)
then
371 type(
mpi_grp_t),
intent(in) :: system_grp
372 type(
dmp_t),
intent(inout) :: dmp
376 if (dmp%basis == option__tddmpropagationbasis__adiabatic)
then
377 call dmp%restart_dump%end()
384 safe_deallocate_a(dmp%occ_gs)
390 subroutine dm_propagation_run(dmp, namespace, space, gr, ions, st, mc, hm, ks, iter, dt, ext_partners, update_energy)
391 type(
dmp_t),
intent(inout) :: dmp
394 type(
grid_t),
intent(in) :: gr
395 type(
ions_t),
intent(in) :: ions
399 type(
v_ks_t),
intent(inout) :: ks
400 integer,
intent(in) :: iter
401 real(real64),
intent(in) :: dt
403 logical,
optional,
intent(in) :: update_energy
405 real(real64),
parameter :: ZERO = 1.0e-15_real64
407 real(real64) :: nrm2_tdks(st%nst, st%nik), population(3), leak
409 logical :: update_energy_
410 complex(real64),
allocatable :: rho_mat_k(:, :, :)
412 complex(real64),
allocatable :: overlap_ad_ks(:, :, :), overlap_resd_ks(:, :, :)
413 integer,
allocatable :: nresd_k(:)
419 call hm%update(gr, namespace, space, ext_partners, time=iter * dt)
420 if (dmp%basis == option__tddmpropagationbasis__adiabatic)
then
421 call eigensolver_init(eigens, namespace, gr, dmp%adiabatic_st, hm, mc, space)
423 call eigens%run(namespace, gr, dmp%adiabatic_st, hm, space, ext_partners, iter)
426 safe_allocate(overlap_ad_ks(1:st%nst, 1:st%nst, st%d%kpt%start:st%d%kpt%end))
427 safe_allocate(overlap_resd_ks(1:st%nst, 1:st%nst, st%d%kpt%start:st%d%kpt%end))
428 safe_allocate(rho_mat_k(2*st%nst, 2*st%nst, st%d%kpt%start:st%d%kpt%end))
429 safe_allocate(nresd_k(st%d%kpt%start:st%d%kpt%end))
431 population = 0.0_real64
437 do ik = st%d%kpt%start, st%d%kpt%end
442 overlap_ad_ks(:, :, ik) = conjg(overlap_ad_ks(:, :, ik))
448 call construct_residuals(gr, namespace, dmp%adiabatic_st, st, ik, dmp%othn, overlap_ad_ks(:, :, ik), &
449 nrm2_tdks(:, ik), nresd_k(ik), overlap_resd_ks(:, :, ik), resd_st)
452 call construct_density_matrix(nresd_k(ik), ik, st, overlap_ad_ks(:, :, ik), overlap_resd_ks(:, :, ik), rho_mat_k(:, :, ik))
456 call broadcast_occupation(dmp%adiabatic_st%occ, dmp%adiabatic_st%d%kpt, dmp%adiabatic_st%nst, st%parallel_in_states)
459 call dissipation(hm, st, namespace, nresd_k, dt, dmp, rho_mat_k)
461 do ik = st%d%kpt%start, st%d%kpt%end
463 call update_st(dmp, ik, gr, namespace, nresd_k(ik), overlap_ad_ks(:, :, ik), overlap_resd_ks(:, :, ik), nrm2_tdks(:, ik), &
464 resd_st, st, rho_mat_k(:, :, ik), population(3))
469 safe_deallocate_a(overlap_ad_ks)
470 safe_deallocate_a(overlap_resd_ks)
474 safe_deallocate_a(rho_mat_k)
475 safe_deallocate_a(nresd_k)
477 call st%d%kpt%mpi_grp%allreduce_inplace(population, 3, mpi_double_precision, mpi_sum)
479 write(
message(1),
'(a,E21.14,a,E21.14,a,E21.14,a)')
'DMPopulation: ', population(1), &
480 ' (', population(2),
' in basis ) before damping; ', population(3),
' after damping'
483 leak = population(1) - population(3)
484 if (abs(leak) > zero)
then
485 write(
message(1),
'(a,E15.8,a,I8)')
'Leakage: ', leak,
'(after damping) at time step', iter
488 dmp%adiabatic_st%qtot = population(1)
493 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, calc_eigenval = update_energy_, &
494 time = abs(iter * dt), calc_energy = update_energy_)
496 if (dmp%basis == option__tddmpropagationbasis__adiabatic)
then
507 integer,
intent(in) :: ik
509 type(
grid_t),
intent(in) :: gr
510 real(real64),
intent(out) :: nrm2(:)
511 real(real64),
intent(inout) :: pop
513 integer :: ib, i_minst, i_maxst
517 assert(pop >= 0.0_real64)
518 assert(
size(nrm2) == st%nst)
520 do ib = st%group%block_start, st%group%block_end
523 call mesh_batch_nrm2(gr, st%group%psib(ib, ik), nrm2(i_minst:i_maxst), reduce = .false.)
525 nrm2(1:st%nst) = nrm2(1:st%nst)**2
526 if (gr%parallel_in_domains)
then
527 call gr%allreduce(nrm2, dim = st%nst)
530 pop = pop + sum(st%occ(1:st%nst, ik)* nrm2(1:st%nst)) * st%kweights(ik)
539 integer,
intent(in) :: ik
542 complex(real64),
intent(in) :: overlap(:, :)
543 real(real64),
intent(inout) :: pop
549 assert(ubound(overlap, dim = 1) == ad_st%nst)
550 assert(ubound(overlap, dim = 2) == st%nst)
553 ad_st%occ(1:ad_st%nst, ik) = 0.0_real64
555 do ist = 1, ad_st%nst
556 ad_st%occ(ist, ik) = ad_st%occ(ist, ik) + &
557 (real(overlap(ist, jst))**2 + aimag(overlap(ist, jst))**2) * st%occ(jst, ik)
561 pop = pop + sum(ad_st%occ(:, ik)) * ad_st%kweights(ik)
582 subroutine construct_residuals(gr, namespace, ad_st, st, ik, othn, overlap_ad_ks, nrm2_tdks, nresd, overlap_resd_ks, resd)
583 type(
grid_t),
intent(in) :: gr
587 integer,
intent(in) :: ik
588 logical,
intent(in) :: othn
589 complex(real64),
intent(in) :: overlap_ad_ks(:, :)
590 real(real64),
intent(in) :: nrm2_tdks(:)
591 integer,
intent(out) :: nresd
592 complex(real64),
intent(out) :: overlap_resd_ks(:, :)
595 integer :: ib, j, i_minst, i_maxst
596 complex(real64),
allocatable :: d_j(:, :), ss(:)
597 real(real64),
parameter :: small_rho = 1.0e-14_real64
598 real(real64),
parameter :: small_resd = 1.0e-7_real64
599 real(real64) :: nrm_dj, nrm2_dj
603 assert(ubound(overlap_ad_ks, dim = 1) == ad_st%nst)
604 assert(ubound(overlap_ad_ks, dim = 2) == st%nst)
605 assert(ubound(overlap_resd_ks, dim = 1) == resd%nst)
606 assert(ubound(overlap_resd_ks, dim = 2) == st%nst)
608 safe_allocate(d_j(1:gr%np, st%d%dim))
616 do ib = ad_st%group%block_start, ad_st%group%block_end
620 ad_st%group%psib(ib, ik), d_j)
629 overlap_resd_ks = conjg(overlap_resd_ks)
634 safe_allocate(ss(1:st%nst))
640 nrm2_dj = nrm2_tdks(j) - sum(real(overlap_ad_ks(:, j))**2) - sum(aimag(overlap_ad_ks(:, j))**2)
641 if (nrm2_dj > small_rho)
then
644 nrm_dj =
sqrt(nrm2_dj)
649 do ib = ad_st%group%block_start, ad_st%group%block_end
653 ad_st%group%psib(ib, ik), d_j)
662 if (nrm_dj > small_resd)
then
670 do ib = st%group%block_start, st%group%block_end
673 call zmesh_batch_mf_dotp(gr, st%group%psib(ib, ik), d_j, ss(i_minst:i_maxst), reduce = .false., nst = i_maxst-i_minst+1)
676 overlap_resd_ks(nresd, 1:st%nst) = conjg(ss(1:st%nst))
680 overlap_resd_ks(nresd+1:resd%nst, :) =
m_z0
681 if (gr%parallel_in_domains)
then
682 call gr%allreduce(overlap_resd_ks)
685 safe_deallocate_a(ss)
689 safe_deallocate_a(d_j)
711 integer,
intent(in) :: nresd
712 integer,
intent(in) :: ik
714 complex(real64),
intent(in) :: overlap_ad_ks(:, :)
715 complex(real64),
intent(in) :: overlap_resd_ks(:, :)
716 complex(real64),
intent(out) :: rho_mat(:, :)
718 integer :: ist, jst, lst
719 real(real64) :: sqrt_f
720 complex(real64),
allocatable :: s_ad_scaled(:, :), s_resd_scaled(:, :)
724 assert(ubound(overlap_ad_ks, dim = 1) == st%nst)
725 assert(ubound(overlap_ad_ks, dim = 2) == st%nst)
726 assert(ubound(overlap_resd_ks, dim = 1) == st%nst)
727 assert(ubound(overlap_resd_ks, dim = 2) == st%nst)
728 assert(ubound(rho_mat, dim = 1) == 2*st%nst)
729 assert(ubound(rho_mat, dim = 2) == 2*st%nst)
731 safe_allocate(s_ad_scaled(st%nst, st%nst))
733 safe_allocate(s_resd_scaled(nresd, st%nst))
741 sqrt_f =
sqrt(st%occ(lst, ik))
742 s_ad_scaled(1:st%nst, lst) = overlap_ad_ks(1:st%nst, lst) * sqrt_f
744 s_resd_scaled(1:nresd, lst) = overlap_resd_ks(1:nresd, lst) * sqrt_f
749 call blas_herk(
'U',
'N', st%nst, st%nst, 1.0_real64, s_ad_scaled(1,1), st%nst, 0.0_real64, rho_mat(1, 1), 2*st%nst)
752 call blas_herk(
'U',
'N', nresd, st%nst, 1.0_real64, s_resd_scaled(1,1), nresd, 0.0_real64, &
753 rho_mat(st%nst + 1, st%nst + 1), 2*st%nst)
755 call blas_gemm(
'N',
'C', st%nst, nresd, st%nst,
m_z1, s_ad_scaled(1,1), st%nst, s_resd_scaled(1,1), &
756 nresd,
m_z0, rho_mat(1, st%nst + 1), 2*st%nst)
763 rho_mat(jst, ist) = conjg(rho_mat(ist, jst))
768 rho_mat(ist + st%nst, jst) = conjg(rho_mat(jst, ist + st%nst))
777 rho_mat(jst + st%nst, ist + st%nst) = conjg(rho_mat(ist + st%nst, jst + st%nst))
782 safe_deallocate_a(s_ad_scaled)
784 safe_deallocate_a(s_resd_scaled)
791 real(real64),
intent(inout) :: occ(:, :)
793 integer,
intent(in) :: nst
794 logical,
intent(in) :: parstate
797 integer,
allocatable :: rdispls(:), recvcnts(:)
798 real(real64),
allocatable :: sendbuffer(:, :)
802 assert(ubound(occ, dim = 1) == nst)
803 assert(ubound(occ, dim = 2) == kpt%nglobal)
804 assert(.not. parstate)
806 if (kpt%parallel)
then
807 safe_allocate(recvcnts(1:kpt%mpi_grp%size))
808 safe_allocate(rdispls(1:kpt%mpi_grp%size))
809 safe_allocate(sendbuffer(1:nst, kpt%nlocal))
811 incount = nst * kpt%nlocal
812 recvcnts(:) = nst * kpt%num(:)
813 sendbuffer(1:nst, 1:kpt%nlocal) = occ(:, kpt%start:kpt%end)
817 call kpt%mpi_grp%allgatherv(sendbuffer, incount, mpi_double_precision, &
818 occ, recvcnts, rdispls, mpi_double_precision)
820 safe_deallocate_a(sendbuffer)
821 safe_deallocate_a(recvcnts)
822 safe_deallocate_a(rdispls)
844 subroutine dissipation(hm, st, namespace, nresd_k, dt, dmp, rho_mat_k)
848 integer,
intent(in) :: nresd_k(:)
849 real(real64),
intent(in) :: dt
850 type(
dmp_t),
intent(inout) :: dmp
851 complex(real64),
intent(inout) :: rho_mat_k(:, :, :)
855 assert(ubound(nresd_k, dim = 1) == dmp%adiabatic_st%d%kpt%nlocal)
856 assert(ubound(rho_mat_k, dim = 1) == 2*dmp%adiabatic_st%nst)
857 assert(ubound(rho_mat_k, dim = 2) == 2*dmp%adiabatic_st%nst)
858 assert(ubound(rho_mat_k, dim = 3) == dmp%adiabatic_st%d%kpt%nlocal)
860 if (dmp%calculation_mode == option__tddmpropagation__master_equation)
then
861 select case (dmp%strategy)
867 call lindblad_from_epw(dmp, hm, st%d%kpt, st%system_grp, namespace, nresd_k, dt, rho_mat_k)
869 else if (dmp%calculation_mode == option__tddmpropagation__collision_integral)
then
870 call collision_from_epw(dmp, hm, st%d%kpt, st%system_grp, namespace, nresd_k, dt, rho_mat_k)
882 type(
dmp_t),
intent(in) :: dmp
884 integer,
intent(in) :: nresd_k(:)
885 real(real64),
intent(in) :: dt
886 complex(real64),
intent(inout) :: rho_mat_k(:, :, :)
888 real(real64) :: coeff
889 real(real64),
allocatable :: rtrans(:, :)
890 complex(real64),
allocatable :: rho_in(:, :), rho_out(:, :), rho_res(:, :), rho_tmp(:, :)
891 integer :: iorder, nst, ik, ik_, nresd
892 integer,
parameter :: norder = 4
896 nst = dmp%adiabatic_st%nst
899 safe_allocate(rtrans(1:nst, 1:nst))
900 safe_allocate(rho_in(1:2*nst, 1:2*nst))
901 safe_allocate(rho_out(1:2*nst, 1:2*nst))
902 safe_allocate(rho_res(1:2*nst, 1:2*nst))
904 do ik = kpt%start, kpt%end
905 ik_ = ik - kpt%start + 1
911 rho_in(1:2*nst, 1:2*nst) = rho_mat_k(1:2*nst, 1:2*nst, ik_)
914 do iorder = 1, norder-1
918 coeff = coeff * dt / iorder
919 rho_res = rho_res + coeff * rho_out
922 call move_alloc(rho_in, rho_tmp)
923 call move_alloc(rho_out, rho_in)
924 call move_alloc(rho_tmp, rho_out)
928 coeff = coeff * dt / norder
929 rho_res = rho_res + coeff * rho_out
931 rho_mat_k(1:2*nst, 1:2*nst, ik_) = rho_mat_k(1:2*nst, 1:2*nst, ik_) + rho_res
934 safe_deallocate_a(rho_in)
935 safe_deallocate_a(rho_out)
936 safe_deallocate_a(rtrans)
937 safe_deallocate_a(rho_res)
948 real(real64),
intent(in) :: uniform(:)
950 integer,
intent(in) :: ik
951 real(real64),
intent(out) :: rtrans(:, :)
953 integer :: ist, jst, nst
954 real(real64) :: rate_character, omega, inv_omega, nph, delta_e
955 real(real64),
parameter :: small_e = 0.002_real64/(
m_two*
p_ry), large_e = 0.5_real64/(
m_two*
p_ry)
956 real(real64) :: unocc_ist, unocc_jst
961 assert(ubound(rtrans, dim = 1) == nst)
962 assert(ubound(rtrans, dim = 2) == nst)
964 rate_character = 1 / uniform(1)
966 inv_omega = 1.0_real64 / max(omega, 1.0e-12_real64)
971 unocc_ist = 1.0_real64 - ad_st%occ(ist, ik) / ad_st%smear%el_per_state
973 do jst = ist + 1, nst
974 delta_e = ad_st%eigenval(jst, ik) - ad_st%eigenval(ist, ik)
975 if (delta_e < small_e) cycle
977 if (delta_e < large_e)
then
978 nph = 1.0_real64/(
exp(delta_e*inv_omega) - 1.0_real64)
982 unocc_jst = 1.0_real64 - ad_st%occ(jst, ik) / ad_st%smear%el_per_state
984 rtrans(ist, jst) = merge(rate_character * unocc_ist * (nph + 1),
m_zero, unocc_ist >
m_zero)
985 rtrans(jst, ist) = merge(rate_character * unocc_jst * nph,
m_zero, unocc_jst >
m_zero)
999 integer,
intent(in) :: nst
1000 integer,
intent(in) :: nresd
1001 real(real64),
intent(in) :: rtrans(:, :)
1002 complex(real64),
intent(in) :: den_mat(:, :)
1003 complex(real64),
intent(out) :: l_mat(:, :)
1005 integer :: ist, jst, lst
1009 assert(ubound(rtrans, dim = 1) == nst)
1010 assert(ubound(rtrans, dim = 2) == nst)
1011 assert(ubound(den_mat, dim = 1) == 2*nst)
1012 assert(ubound(den_mat, dim = 2) == 2*nst)
1013 assert(ubound(l_mat, dim = 1) == 2*nst)
1014 assert(ubound(l_mat, dim = 2) == 2*nst)
1020 if (ist == jst) cycle
1021 do lst = 1, nst + nresd
1022 l_mat(ist, lst) = l_mat(ist, lst) -
m_half * rtrans(jst, ist) * den_mat(ist, lst)
1023 l_mat(lst, ist) = l_mat(lst, ist) -
m_half * rtrans(jst, ist) * den_mat(lst, ist)
1025 l_mat(jst, jst) = l_mat(jst, jst) + rtrans(jst, ist) * den_mat(ist, ist)
1041 type(
dmp_t),
intent(in) :: dmp
1043 integer,
intent(in) :: nresd_k(:)
1044 real(real64),
intent(in) :: dt
1045 complex(real64),
intent(inout) :: rho_mat_k(:, :, :)
1047 real(real64) :: decay_T1, decay_T2
1048 integer :: ist, jst, nst, ik, ik_, nresd
1052 nst = dmp%adiabatic_st%nst
1054 decay_t1 =
exp(-dt / dmp%tmodel(1))
1055 decay_t2 =
exp(-dt / dmp%tmodel(2))
1057 do ik = kpt%start, kpt%end
1058 ik_ = ik - kpt%start + 1
1059 nresd = nresd_k(ik_)
1062 rho_mat_k(ist, ist, ik_) = dmp%occ_gs(ist, ik_) + (rho_mat_k(ist, ist, ik_) - dmp%occ_gs(ist, ik_)) * decay_t1
1064 do ist = nst + 1, nst + nresd
1065 rho_mat_k(ist, ist, ik_) = rho_mat_k(ist, ist, ik_) * decay_t1
1067 do ist = 1, nst + nresd
1068 do jst = ist + 1, nst + nresd
1069 rho_mat_k(jst, ist, ik_) = rho_mat_k(jst, ist, ik_) * decay_t2
1070 rho_mat_k(ist, jst, ik_) = conjg(rho_mat_k(jst, ist, ik_))
1081 subroutine lindblad_from_epw(dmp, hm, kpt, system_grp, namespace, nresd_k, dt, rho_mat_k)
1082 type(
dmp_t),
intent(inout) :: dmp
1085 type(
mpi_grp_t),
intent(in) :: system_grp
1087 integer,
intent(in) :: nresd_k(:)
1088 real(real64),
intent(in) :: dt
1089 complex(real64),
intent(inout) :: rho_mat_k(:, :, :)
1091 real(real64) :: coeff
1092 real(real64),
allocatable :: rho_diag(:, :)
1093 complex(real64),
allocatable :: rho_in(:, :, :), rho_out(:, :, :), rho_tmp(:, :, :)
1094 integer,
parameter :: norder = 4
1095 integer :: ist, iorder, ik, nst, ik_, nik
1099 nst = dmp%adiabatic_st%nst
1100 nik = dmp%adiabatic_st%nik
1102 call dmp%update_trans_rate(hm, system_grp, namespace)
1105 safe_allocate_source_a(rho_diag, dmp%adiabatic_st%occ)
1108 safe_allocate_source(rho_in, rho_mat_k)
1109 safe_allocate(rho_out(1:2*nst, 1:2*nst, 1:kpt%nlocal))
1113 do iorder = 1, norder - 1
1115 coeff = coeff * dt / iorder
1117 do ik = kpt%start, kpt%end
1118 ik_ = ik - kpt%start + 1
1120 call lindblad_operator_epw(dmp, ik, hm%kpoints%nik_skip, nresd_k(ik_), rho_diag, rho_in(:, :, ik_), rho_out(:, :, ik_))
1122 call lalg_axpy(2*nst, 2*nst, coeff, rho_out(:, :, ik_), rho_mat_k(:, :, ik_))
1126 do ik = kpt%start, kpt%end
1127 ik_ = ik - kpt%start + 1
1129 rho_diag(ist, ik) = real(rho_out(ist, ist, ik_))
1137 call move_alloc(rho_in, rho_tmp)
1138 call move_alloc(rho_out, rho_in)
1139 call move_alloc(rho_tmp, rho_out)
1143 coeff = coeff * dt / norder
1145 do ik = kpt%start, kpt%end
1146 ik_ = ik - kpt%start + 1
1148 call lindblad_operator_epw(dmp, ik, hm%kpoints%nik_skip, nresd_k(ik_), rho_diag, rho_in(:, :, ik_), rho_out(:, :, ik_))
1150 call lalg_axpy(2*nst, 2*nst, coeff, rho_out(:, :, ik_), rho_mat_k(:, :, ik_))
1154 safe_deallocate_a(rho_in)
1155 safe_deallocate_a(rho_out)
1156 safe_deallocate_a(rho_diag)
1170 subroutine collision_from_epw(dmp, hm, kpt, system_grp, namespace, nresd_k, dt, rho_mat_k)
1171 type(
dmp_t),
intent(inout) :: dmp
1174 type(
mpi_grp_t),
intent(in) :: system_grp
1176 integer,
intent(in) :: nresd_k(:)
1177 real(real64),
intent(in) :: dt
1178 complex(real64),
intent(inout) :: rho_mat_k(:, :, :)
1180 real(real64) :: gam, gam_in, gam_out
1181 real(real64),
allocatable :: gam_bnd(:)
1182 real(real64),
parameter :: gthresh = 1.0e-8_real64
1183 integer :: ist, jst, ik, nst, nresd, ik_, nik_skip
1187 nst = dmp%adiabatic_st%nst
1188 nik_skip = hm%kpoints%nik_skip
1190 safe_allocate(gam_bnd(2*nst))
1192 call dmp%update_trans_rate(hm, system_grp, namespace)
1195 do ik = kpt%start, kpt%end
1196 ik_ = ik - kpt%start + 1
1197 nresd = nresd_k(ik_)
1200 gam_bnd = 0.0_real64
1201 do ist = dmp%istart, dmp%iend
1202 call lifetime(dmp, ik, ist, nik_skip, gam_bnd(ist))
1205 do ist = 1, nst + nresd
1206 do jst = ist + 1, nst + nresd
1207 gam = -(gam_bnd(ist) + gam_bnd(jst)) / 2.0_real64
1210 rho_mat_k(jst, ist, ik_) = rho_mat_k(jst, ist, ik_) *
exp(gam * dt)
1211 rho_mat_k(ist, jst, ik_) = conjg(rho_mat_k(jst, ist, ik_))
1217 do ik = kpt%start, kpt%end
1218 ik_ = ik - kpt%start + 1
1219 do ist = dmp%istart, dmp%iend
1220 call get_gamma(dmp, ik, ist, nik_skip, gam_in, gam_out)
1221 if (gam_out * dt > gthresh)
then
1222 rho_mat_k(ist, ist, ik_) = rho_mat_k(ist, ist, ik_) *
exp(-gam_out * dt) &
1223 + (gam_in / gam_out) * (1.0_real64 -
exp(-gam_out * dt))
1226 rho_mat_k(ist, ist, ik_) = rho_mat_k(ist, ist, ik_) * (1.0_real64 - gam_out * dt) + gam_in * dt
1231 safe_deallocate_a(gam_bnd)
1238 class(
dmp_t),
intent(inout) :: this
1240 type(
mpi_grp_t),
intent(in) :: system_grp
1245 push_sub_with_profile(dmp_propagation_update_trans_rate)
1249 if (ia /= this%ia)
then
1254 pop_sub_with_profile(dmp_propagation_update_trans_rate)
1261 type(
ions_t),
intent(in) :: ions
1263 type(
mpi_grp_t),
intent(in) :: system_grp
1264 type(
dmp_t),
intent(inout) :: dmp
1266 integer :: ierr, iostat, idim, idir, iqq, totq
1267 integer :: epw_nk(3), oct_nk(3)
1268 real(real64) :: oct_s(3), at(3,3)
1273 if (system_grp%is_root())
then
1274 open(newunit=dmp%iunit, file=trim(dmp%epw_file), form=
'unformatted',
access=
'stream', status=
'old', &
1275 action=
'read', iostat=iostat)
1276 if (iostat /= 0)
then
1278 write(
message(1),
'(a,a)')
'Error opening file: ', trim(dmp%epw_file)
1282 read(dmp%iunit, iostat=ierr) iqq, totq, dmp%wnst, epw_nk(1:3), at, oct_nk(1:3), oct_s(1:3), dmp%astep(1:3), dmp%na(1:3)
1284 write(
message(1),
'(a,a)')
'Error reading header from: ', trim(dmp%epw_file)
1290 call system_grp%bcast(dmp%wnst, 1, mpi_integer, 0)
1291 call system_grp%bcast(at, 9, mpi_double_precision, 0)
1292 call system_grp%bcast(oct_s, 3, mpi_double_precision, 0)
1293 call system_grp%bcast(dmp%astep, 3, mpi_double_precision, 0)
1294 call system_grp%bcast(dmp%na, 3, mpi_integer, 0)
1295 call system_grp%bcast(epw_nk, 3, mpi_integer, 0)
1296 call system_grp%bcast(oct_nk, 3, mpi_integer, 0)
1298 dmp%iend = dmp%istart + dmp%wnst - 1
1300 if (any(oct_nk /= hm%kpoints%nik_axis))
then
1301 write(
message(1),
'(a, a)')
'Inconsistent k-point mesh in KPointsGrid and ', trim(dmp%epw_file)
1304 if (any(abs(oct_s - hm%kpoints%full%shifts(:, 1)) >
m_epsilon))
then
1305 write(
message(1),
'(a, a)')
'Inconsistent k-point mesh shifts in KPointsGrid and ', trim(dmp%epw_file)
1309 write(
message(1),
'(3(a,i0), a)')
'Info: Averaged transition rates obtained from a ', epw_nk(1),
' x ', &
1310 epw_nk(2),
' x ', epw_nk(3),
' EPW k-point mesh'
1312 write(
message(1),
'(a, i0, a, i0)')
'Info: Damping band ', dmp%istart,
' - ', dmp%iend
1314 write(
message(1),
'(a)')
' EPW Lattice Vectors [1/alat]'
1316 write(
message(1+idim),
'(3f12.6)') (at(idir, idim), idir = 1, 3)
1319 if (any(abs(at - ions%latt%rlattice_primitive) >
m_epsilon))
then
1320 write(
message(1),
'(a)')
'Lattice settings are not fully consistent with those in EPW'
1330 dmp%num = int(product(oct_nk), kind=int64)**2 * int(dmp%wnst, kind=int64)**2
1333 call create_intranode_communicator(system_grp, dmp%intranode_grp, dmp%internode_grp)
1335 call slmpi_create_shared_memory_window(dmp%num, dmp%intranode_grp, dmp%window_trans_rate, ave_trans)
1337 safe_allocate(ave_trans(1:dmp%num))
1345 integer,
intent(in) :: ia
1346 type(
mpi_grp_t),
intent(in) :: system_grp
1348 type(
dmp_t),
intent(inout) :: dmp
1350 integer(int64),
parameter :: header_bytes = 168
1351 integer(int64),
parameter :: epw_bytes = 4
1352 integer(int64) :: offset
1357 if (system_grp%is_root())
then
1359 offset = header_bytes + int(ia - 1, kind=int64) * dmp%num * epw_bytes + 1_int64
1360 read(dmp%iunit, pos=offset, iostat=ierr) ave_trans
1362 write(
message(1),
'(a,a)')
'Error reading transition rates from: ', trim(dmp%epw_file)
1369 if (dmp%intranode_grp%rank == 0)
then
1370 call smpi_grp_bcast(dmp%internode_grp, ave_trans(1), dmp%num, mpi_real, 0)
1372 call lmpi_sync_shared_memory_window(dmp%window_trans_rate, dmp%intranode_grp)
1382 type(
mpi_grp_t),
intent(in) :: system_grp
1383 type(
dmp_t),
intent(inout) :: dmp
1387 safe_deallocate_a(dmp%kmap)
1389 if (system_grp%is_root())
then
1394 call lmpi_destroy_shared_memory_window(dmp%window_trans_rate)
1397 safe_deallocate_p(ave_trans)
1408 type(
dmp_t),
intent(inout) :: dmp
1410 integer :: ik, idx, nik, nik_mp
1412 real(real64) :: kred(3), kidx(3)
1413 real(real64),
parameter :: tol = 1.0d-10
1417 nik = dmp%adiabatic_st%nik
1418 nik_mp = nik - kpoints%nik_skip
1419 safe_allocate(dmp%kmap(nik))
1422 dmp%kmap = nik_mp + 1
1426 kred = kpoints%get_point(ik, .false.)
1427 kidx = (kred + 0.5_real64) * real(kpoints%nik_axis, kind=real64) - kpoints%full%shifts(:, 1)
1430 if (ik <= nik_mp)
then
1431 if (any(abs(kidx - nint(kidx)) > tol))
then
1432 write(
message(1),
'(a)')
'K-point mesh is not compatible with EPW input'
1438 kidx_ = modulo(nint(kidx), kpoints%nik_axis)
1440 idx = kidx_(1) * kpoints%nik_axis(2) * kpoints%nik_axis(3) + kidx_(2) * kpoints%nik_axis(3) + &
1447 assert(all(dmp%kmap <= nik_mp))
1454 type(
dmp_t),
intent(in) :: dmp
1458 real(real64) :: ared(3), approx(3)
1459 integer :: apoint_idx(3)
1460 integer :: aidx, idim
1465 if (
allocated(hm%hm_base%uniform_vector_potential))
then
1471 if (dmp%astep(idim) >
m_zero)
then
1472 apoint_idx(idim) = nint(ared(idim) / dmp%astep(idim))
1473 approx(idim) = apoint_idx(idim) * dmp%astep(idim)
1475 apoint_idx(idim) = 0
1476 approx(idim) = 0.0_real64
1479 if (any(abs(apoint_idx) > dmp%na))
then
1480 write(
message(1),
'(a, 3F8.3)')
'Vector potential exceeds mesh range: ', ared
1482 where (apoint_idx < -dmp%na)
1483 apoint_idx = -dmp%na
1485 where (apoint_idx > dmp%na)
1494 aidx = (apoint_idx(1) + dmp%na(1)) * (2 * dmp%na(2) + 1) * (2 * dmp%na(3) + 1) + &
1495 (apoint_idx(2) + dmp%na(2)) * (2 * dmp%na(3) + 1) + &
1496 (apoint_idx(3) + dmp%na(3)) + 1
1498 write(
message(1),
'(a, x, 3F7.3)')
'Approximated vector field damping grid:', approx
1508 function get_trans_rate(dmp, nik_mp, jbnd, ibnd, k, kq, p_block)
result(res)
1509 type(
dmp_t),
intent(in) :: dmp
1510 integer,
intent(in) :: nik_mp
1511 integer,
intent(in) :: jbnd
1512 integer,
intent(in) :: ibnd
1513 integer,
intent(in) :: k
1514 integer,
intent(in) :: kq
1515 logical,
optional,
intent(in) :: p_block
1517 real(real64) :: unocc, res
1519 integer(int64) :: idx
1528 idx = int(kq_-1, kind=int64) * int(nik_mp, kind=int64) * int(dmp%wnst, kind=int64)**2 + &
1529 int((k_-1) * dmp%wnst**2, kind=int64) + &
1530 int((ibnd-dmp%istart)*dmp%wnst + (jbnd-dmp%istart) + 1, kind=int64)
1532 assert(idx >= 1 .and. idx <= dmp%num)
1534 res = real(ave_trans(idx), kind=real64)
1537 unocc = 1.0_real64 - dmp%adiabatic_st%occ(jbnd, kq) / dmp%adiabatic_st%smear%el_per_state
1538 res = res * max(unocc, 0.0_real64)
1552 type(
dmp_t),
intent(in) :: dmp
1553 integer,
intent(in) :: ik
1554 integer,
intent(in) :: nik_skip
1555 integer,
intent(in) :: nresd
1556 real(real64),
intent(in) :: rho_diag(:, :)
1557 complex(real64),
intent(in) :: den_mat(:, :)
1558 complex(real64),
intent(out) :: l_mat(:, :)
1560 integer :: lst, nst, nik_mp, ikq, ibnd, jbnd
1564 nst = dmp%adiabatic_st%nst
1565 nik_mp = dmp%adiabatic_st%nik - nik_skip
1567 assert(ubound(rho_diag, dim = 1) == nst)
1568 assert(ubound(rho_diag, dim = 2) == dmp%adiabatic_st%nik)
1569 assert(ubound(den_mat, dim = 1) == 2*nst)
1570 assert(ubound(den_mat, dim = 2) == 2*nst)
1571 assert(ubound(l_mat, dim = 1) == 2*nst)
1572 assert(ubound(l_mat, dim = 2) == 2*nst)
1579 do jbnd = dmp%istart, dmp%iend
1580 do ibnd = dmp%istart, dmp%iend
1583 do lst = 1, nst + nresd
1584 l_mat(ibnd, lst) = l_mat(ibnd, lst) -
m_half * tr * den_mat(ibnd, lst)
1585 l_mat(lst, ibnd) = l_mat(lst, ibnd) -
m_half * tr * den_mat(lst, ibnd)
1587 l_mat(ibnd, ibnd) = l_mat(ibnd, ibnd) +
get_trans_rate(dmp, nik_mp, ibnd, jbnd, ikq, ik, p_block=.
true.) &
1588 * rho_diag(jbnd, ikq)
1601 subroutine lifetime(dmp, ik, ibnd, nik_skip, gam)
1602 type(
dmp_t),
intent(in) :: dmp
1603 integer,
intent(in) :: ik
1604 integer,
intent(in) :: ibnd
1605 integer,
intent(in) :: nik_skip
1606 real(real64),
intent(out) :: gam
1608 integer :: nik_mp, ikq, jbnd
1612 assert(ibnd >= dmp%istart .and. ibnd <= dmp%iend)
1613 nik_mp = dmp%adiabatic_st%nik - nik_skip
1619 do jbnd = dmp%istart, dmp%iend
1622 tr =
get_trans_rate(dmp, nik_mp, ibnd, jbnd, ikq, ik, p_block=.false.)
1623 gam = gam + tr * dmp%adiabatic_st%occ(jbnd, ikq) / dmp%adiabatic_st%smear%el_per_state
1641 subroutine get_gamma(dmp, ik, ibnd, nik_skip, gam_in, gam_out)
1642 type(
dmp_t),
intent(in) :: dmp
1643 integer,
intent(in) :: ik
1644 integer,
intent(in) :: ibnd
1645 integer,
intent(in) :: nik_skip
1646 real(real64),
intent(out) :: gam_in
1647 real(real64),
intent(out) :: gam_out
1649 integer :: nik_mp, ikq, jbnd
1653 assert(ibnd >= dmp%istart .and. ibnd <= dmp%iend)
1654 nik_mp = dmp%adiabatic_st%nik - nik_skip
1659 gam_out = 0.0_real64
1661 do jbnd = dmp%istart, dmp%iend
1663 gam_out = gam_out + tr
1665 gam_in = gam_in + tr * dmp%adiabatic_st%occ(jbnd, ikq)
1688 subroutine update_st(dmp, ik, gr, namespace, nresd, overlap_ad_ks, overlap_resd_ks, nrm2_tdks, resd, st, rho_mat, pop)
1689 type(
dmp_t),
intent(inout) :: dmp
1690 integer,
intent(in) :: ik
1691 type(
grid_t),
intent(in) :: gr
1693 integer,
intent(in) :: nresd
1694 complex(real64),
intent(in) :: overlap_ad_ks(:, :)
1695 complex(real64),
intent(in) :: overlap_resd_ks(:, :)
1696 real(real64),
intent(in) :: nrm2_tdks(:)
1699 complex(real64),
intent(inout) :: rho_mat(:, :)
1700 real(real64),
intent(inout) :: pop
1702 real(real64),
allocatable :: occ(:)
1703 complex(real64),
allocatable :: overlap(:, :), overlap_ad_resd(:, :)
1704 integer :: ist, jst, nst
1708 nst = dmp%adiabatic_st%nst
1710 assert(ubound(overlap_ad_ks, dim = 1) == nst)
1711 assert(ubound(overlap_ad_ks, dim = 2) == nst)
1712 assert(ubound(overlap_resd_ks, dim = 1) == nst)
1713 assert(ubound(overlap_resd_ks, dim = 2) == nst)
1714 assert(ubound(rho_mat, dim = 1) == 2*nst)
1715 assert(ubound(rho_mat, dim = 2) == 2*nst)
1718 safe_allocate(occ(1:nst+nresd))
1723 assert(nresd == nst)
1726 safe_allocate(overlap(1:2*nst, 1:2*nst))
1727 safe_allocate(overlap_ad_resd(1:nst, 1:nst))
1732 overlap(ist, ist) =
m_one
1739 overlap(ist, jst + nst) = conjg(overlap_ad_resd(ist, jst))
1745 overlap(nst+1:nst+nresd, nst+1:nst+nresd) = overlap_resd_ks(1:nresd, 1:nresd)
1746 call blas_gemm(
'T',
'N', nresd, nresd, nst, -
m_z1, overlap_ad_resd(1, 1), nst, overlap_ad_ks(1, 1), nst, &
1747 m_z1, overlap(nst+1, nst+1), 2*nst)
1752 safe_deallocate_a(overlap_ad_resd)
1753 safe_deallocate_a(overlap)
1757 if (dmp%unitary_transform)
then
1759 nrm2_tdks, occ, rho_mat, st, pop)
1761 call update_wfc_occ(ik, dmp%adiabatic_st, resd, gr, nresd, occ, rho_mat, st, pop)
1764 safe_deallocate_a(occ)
1776 subroutine update_wfc_occ(ik, ad_st, resd, gr, nresd, occ, v_mat, st, pop)
1777 integer,
intent(in) :: ik
1780 type(
grid_t),
intent(in) :: gr
1781 integer,
intent(in) :: nresd
1782 real(real64),
intent(in) :: occ(:)
1783 complex(real64),
intent(in) :: v_mat(:, :)
1785 real(real64),
intent(inout) :: pop
1787 complex(real64),
allocatable :: psi_j(:, :)
1788 integer :: j, ib, i_minst, i_maxst, nst
1793 assert(ubound(v_mat, dim = 1) == 2*nst)
1794 assert(ubound(v_mat, dim = 2) == 2*nst)
1796 safe_allocate(psi_j(1:gr%np, st%d%dim))
1798 do j = nst+nresd, nst+1, -1
1799 psi_j = (0.0_real64, 0.0_real64)
1800 do ib = ad_st%group%block_start, ad_st%group%block_end
1804 ad_st%group%psib(ib, ik), psi_j)
1806 do ib = resd%group%block_start, resd%group%block_end
1809 if (i_minst > nresd) cycle
1811 resd%group%psib(ib, ik), psi_j, nst=i_maxst-i_minst+1)
1818 st%occ(1:nst, ik) = occ(nst+nresd:nresd+1:-1)
1819 pop = pop + sum(st%occ(1:nst, ik)) * st%kweights(ik)
1821 safe_deallocate_a(psi_j)
1841 nrm2_tdks, occ_tilde, v_mat, st, pop)
1842 integer,
intent(in) :: ik
1845 type(
grid_t),
intent(in) :: gr
1846 integer,
intent(in) :: nresd
1847 complex(real64),
intent(in) :: overlap_ad_ks(:, :)
1848 complex(real64),
intent(in) :: overlap_resd_ks(:, :)
1849 real(real64),
intent(in) :: nrm2_tdks(:)
1850 real(real64),
intent(in) :: occ_tilde(:)
1851 complex(real64),
intent(inout) :: v_mat(:, :)
1853 real(real64),
intent(inout) :: pop
1855 integer :: ist, jst, ib, i_minst, i_maxst, nst
1856 complex(real64),
allocatable :: overlap_procrus(:, :), uproj(:, :), utrans(:, :)
1857 complex(real64),
allocatable :: uu(:, :), vt(:, :)
1858 complex(real64),
allocatable :: psi(:, :)
1859 real(real64),
parameter :: small_occ = 5.0e-15_real64
1860 real(real64) :: sg_values(1:st%nst), rocc_tilde(1:st%nst+nresd), rocc(1:st%nst)
1861 real(real64) :: qtot_transform, nrm2, occ
1866 assert(ubound(overlap_ad_ks, dim = 1) == ad_st%nst)
1867 assert(ubound(overlap_ad_ks, dim = 2) == nst)
1868 assert(ubound(overlap_resd_ks, dim = 1) == resd%nst)
1869 assert(ubound(overlap_resd_ks, dim = 2) == nst)
1870 assert(ubound(v_mat, dim = 1) == 2*nst)
1871 assert(ubound(v_mat, dim = 2) == 2*nst)
1874 rocc_tilde(1:nst+nresd) =
sqrt(max(occ_tilde(1:nst+nresd), small_occ))
1875 rocc(1:nst) =
sqrt(max(st%occ(1:nst, ik), small_occ))
1877 safe_allocate(overlap_procrus(1:nst+nresd, 1:nst))
1882 call blas_gemm(
'C',
'N', nst+nresd, nst, nst,
m_z1, v_mat(1, 1), 2*nst, overlap_ad_ks(1, 1), nst, &
1883 m_z0, overlap_procrus(1, 1), nst+nresd)
1884 call blas_gemm(
'C',
'N', nst+nresd, nst, nresd,
m_z1, v_mat(1+nst, 1), 2*nst, overlap_resd_ks(1, 1), nst, &
1885 m_z1, overlap_procrus(1, 1), nst+nresd)
1887 do ist = 1, nst+nresd
1888 overlap_procrus(ist, jst) = overlap_procrus(ist, jst) * rocc_tilde(ist) * rocc(jst)
1892 safe_allocate(uproj(1:nst+nresd, 1:nst))
1893 safe_allocate(uu(1:nst+nresd, 1:nst+nresd))
1894 safe_allocate(vt(1:nst, 1:nst))
1897 uproj = matmul(uu(:,1:nst), vt)
1899 safe_deallocate_a(overlap_procrus)
1900 safe_deallocate_a(vt)
1901 safe_deallocate_a(uu)
1903 safe_allocate(utrans(1:nst+nresd, 1:nst))
1906 do ist = 1, nst+nresd
1907 call blas_scal(nst+nresd, cmplx(rocc_tilde(ist), 0.0, real64), v_mat(1, ist), 1)
1910 call blas_gemm(
'N',
'N', nst+nresd, nst, nst+nresd,
m_z1, v_mat(1, 1), 2*nst, uproj(1, 1), nst+nresd, &
1911 m_z0, utrans(1, 1), nst+nresd)
1913 safe_deallocate_a(uproj)
1914 safe_allocate(psi(1:gr%np, st%d%dim))
1917 qtot_transform = 0.0_real64
1919 psi = (0.0_real64, 0.0_real64)
1920 do ib = ad_st%group%block_start, ad_st%group%block_end
1924 ad_st%group%psib(ib, ik), psi)
1926 do ib = resd%group%block_start, resd%group%block_end
1929 if (i_minst > nresd) cycle
1931 resd%group%psib(ib, ik), psi, nst=i_maxst-i_minst+1)
1933 nrm2 = real(
zmf_dotp(gr, st%d%dim, psi, psi, reduce = .
true.), real64)
1934 qtot_transform = qtot_transform + nrm2
1935 occ = nrm2 / nrm2_tdks(jst)
1936 st%occ(jst, ik) = occ
1941 pop = pop + qtot_transform * st%kweights(ik)
1943 safe_deallocate_a(utrans)
1944 safe_deallocate_a(psi)
1952 integer,
intent(in) :: n
1953 complex(real64),
intent(in) :: mat(:, :)
1954 real(real64),
parameter :: tol = 1.0e-14_real64
1956 assert(ubound(mat, dim=1) == n)
1957 assert(ubound(mat, dim=2) == n)
1959 is_hermitian = maxval(abs(mat - transpose(conjg(mat)))) <= tol
1963 subroutine slmpi_create_shared_memory_window(number_of_elements, intranode_grp, window, array)
1965 integer(int64),
intent(in) :: number_of_elements
1966 type(
mpi_grp_t),
intent(in) :: intranode_grp
1967 type(mpi_win),
intent(out) :: window
1968 real(real32),
pointer,
intent(out) :: array(:)
1971 integer(kind=MPI_ADDRESS_KIND) :: window_size
1972 integer :: disp_unit
1977 if (intranode_grp%rank == 0)
then
1978 window_size = number_of_elements * 4_mpi_address_kind
1980 window_size = 0_mpi_address_kind
1982 assert(number_of_elements * 4 < huge(0_mpi_address_kind))
1983 assert(window_size >= 0)
1985 call mpi_win_allocate_shared(window_size, disp_unit, mpi_info_null, &
1986 intranode_grp%comm, ptr, window)
1988 if (intranode_grp%rank /= 0)
then
1989 call mpi_win_shared_query(window, 0, window_size, disp_unit, ptr)
1992 call c_f_pointer(ptr, array, [number_of_elements])
1995 call mpi_win_lock_all(mpi_mode_nocheck, window)
1997 end subroutine slmpi_create_shared_memory_window
1999 subroutine smpi_grp_bcast(mpi_grp, buf, cnt, sendtype, root)
2002 real(real32),
target,
intent(inout) :: buf
2003 integer(int64),
intent(in) :: cnt
2004 type(mpi_datatype),
intent(in) :: sendtype
2005 integer,
intent(in) :: root
2007 integer :: rounds, iround, size
2008 integer(int64) :: offset
2009 real(real32),
pointer :: bufptr(:)
2013 call mpi_debug_in(mpi_grp%comm, c_mpi_bcast)
2016 call c_f_pointer(c_loc(buf), bufptr, [cnt])
2017 rounds = int(cnt/huge(0_int32), int32)
2018 do iround = 1, rounds
2019 offset = int(huge(0_int32), int64) * (iround - 1) + 1
2020 call mpi_bcast(bufptr(offset), huge(0_int32), sendtype, root, mpi_grp%comm)
2023 offset = int(huge(0_int32), int64) * rounds + 1
2024 size = int(mod(cnt, int(huge(0_int32),int64)), int32)
2025 call mpi_bcast(bufptr(offset),
size, sendtype, root, mpi_grp%comm)
2027 call mpi_debug_out(mpi_grp%comm, c_mpi_bcast)
2029 end subroutine smpi_grp_bcast
int access(const char *__name, int __type) __attribute__((__nothrow__
--------------— gemm ---------------— performs one of the matrix-matrix operations
--------------— syrk, herk ---------------— performs one of the symmetric rank k operations
--------------— scal ---------------— Scales a vector by a constant.
constant times a vector plus a vector
scales a vector by a constant
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
double exp(double __x) __attribute__((__nothrow__
This module implements common operations on batches of mesh functions.
subroutine, public zbatch_axpy_function(np, aa, xx, psi, nst)
This routine performs a set of axpy operations for each function x of a batch (xx),...
This module contains interfaces for BLAS routines You should not use these routines directly....
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 lifetime(dmp, ik, ibnd, nik_skip, gam)
Calculate the total scattering rate (inverse lifetime) for a given state.
subroutine iopar_close_trans_rate(system_grp, dmp)
Finalize transition rate resources.
subroutine lindblad_from_epw(dmp, hm, kpt, system_grp, namespace, nresd_k, dt, rho_mat_k)
Evolve the density matrix under EPW-derived Lindblad dissipation.
subroutine lindblad_uniform(dmp, kpt, nresd_k, dt, rho_mat_k)
Evolve the density matrix in time under uniform dissipation.
subroutine, public dm_propagation_init_run(dmp, namespace, space, gr, ions, st, hm, mc, from_scratch)
Initialise the adiabatic states prior to running TD propagation.
subroutine lindblad_operator_uniform(nst, nresd, rtrans, den_mat, l_mat)
Calculate the Lindblad dissipator matrix for uniform decay.
integer function get_vector_field_index(dmp, hm, namespace)
Get the flattened 1D index of the current vector potential on the discrete EPW vector field grid.
real(real64) function get_trans_rate(dmp, nik_mp, jbnd, ibnd, k, kq, p_block)
Get transition rate from state (k, ibnd) to (kq, jbnd).
subroutine lindblad_operator_epw(dmp, ik, nik_skip, nresd, rho_diag, den_mat, l_mat)
Calculate the Lindblad dissipator matrix using EPW electron-phonon scattering rates.
subroutine, public dm_end_run(system_grp, dmp)
logical function is_hermitian(n, mat)
Check if a matrix is Hermitian.
subroutine iopar_read_trans_rate(ia, system_grp, namespace, dmp)
Read in transition rates to the shared memory window and then broadcast via internode communicator.
subroutine dmp_init(this, namespace, st, space, hm)
Initialise an instance of density matrix dissipation.
subroutine build_epw_kmap(namespace, kpoints, dmp)
Map internal k-point indices to the 1D EPW Monkhorst-Pack grid and verify mesh compatibility.
subroutine collision_from_epw(dmp, hm, kpt, system_grp, namespace, nresd_k, dt, rho_mat_k)
Evolve the density matrix subject to the electron-phonon collision integral.
subroutine broadcast_occupation(occ, kpt, nst, parstate)
subroutine total_population(ik, st, gr, nrm2, pop)
Calculate total population.
subroutine update_wfc_occ_procrustes(ik, ad_st, resd, gr, nresd, overlap_ad_ks, overlap_resd_ks, nrm2_tdks, occ_tilde, v_mat, st, pop)
Update states using Procrustes transformation to ensure time continuity.
subroutine get_gamma(dmp, ik, ibnd, nik_skip, gam_in, gam_out)
Calculate in/out scattering rates (Gamma) for a specific state (ik, ibnd).
subroutine update_wfc_occ(ik, ad_st, resd, gr, nresd, occ, v_mat, st, pop)
Update states directly from diagonalization (no Procrustes).
subroutine construct_residuals(gr, namespace, ad_st, st, ik, othn, overlap_ad_ks, nrm2_tdks, nresd, overlap_resd_ks, resd)
Construct the residual basis and its overlap with TDKS wavefunctions.
subroutine, public dm_propagation_run(dmp, namespace, space, gr, ions, st, mc, hm, ks, iter, dt, ext_partners, update_energy)
Density matrix propagation.
subroutine dm_propagation_update_trans_rate(this, hm, system_grp, namespace)
Read and update the EPW transition matrix only when the vector field index changes.
subroutine transition_rate_uniform(uniform, ad_st, ik, rtrans)
Calculate state transition rates assuming uniform electron-phonon coupling.
subroutine construct_density_matrix(nresd, ik, st, overlap_ad_ks, overlap_resd_ks, rho_mat)
Construct the full density matrix in the adiabatic and residual basis.
subroutine lindblad_2times(dmp, kpt, nresd_k, dt, rho_mat_k)
Evolve the density matrix using the phenomenological two-time (T1/T2) relaxation model.
subroutine iopar_open_trans_rate(namespace, ions, hm, system_grp, dmp)
Read in metadata of transition rates, build intra/inter communicators and shared memory window.
subroutine dissipation(hm, st, namespace, nresd_k, dt, dmp, rho_mat_k)
Evolve the density matrix in time under dissipation.
subroutine update_st(dmp, ik, gr, namespace, nresd, overlap_ad_ks, overlap_resd_ks, nrm2_tdks, resd, st, rho_mat, pop)
Diagonalize the density matrix to update occupations and wavefunctions.
subroutine population_in_adiabatic(ik, ad_st, st, overlap, pop)
Calculate number of electrons in the adiabatic basis.
subroutine, public eigensolver_init(eigens, namespace, gr, st, hm, mc, space, deactivate_oracle)
subroutine, public eigensolver_end(eigens)
integer, parameter, public spin_polarized
real(real64), parameter, public m_two
real(real64), parameter, public m_zero
real(real64), parameter, public p_ry
logical pure function, public not_in_openmp()
complex(real64), parameter, public m_z0
real(real64), parameter, public m_epsilon
complex(real64), parameter, public m_z1
real(real64), parameter, public m_half
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
This module defines classes and functions for interaction partners.
integer, parameter, public kpoints_monkh_pack
subroutine, public kpoints_to_reduced(latt, kin, kout)
This module defines functions over batches of mesh functions.
subroutine, public mesh_batch_nrm2(mesh, aa, nrm2, reduce)
Calculate the norms (norm2, not the square!) of a batch of mesh functions.
subroutine, public zmesh_batch_mf_dotp(mesh, aa, psi, dot, reduce, nst)
calculate the dot products between a batch and a vector of mesh functions
This module defines various routines, operating on mesh functions.
subroutine, public messages_not_implemented(feature, namespace)
subroutine, public messages_warning(no_lines, all_nodes, 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 contains some common usage patterns of MPI routines.
type(mpi_comm), parameter, public mpi_comm_undefined
used to indicate a communicator has not been initialized
This module handles the communicators for the various parallelization strategies.
integer function, public parse_block(namespace, name, blk, check_varinfo_)
integer, parameter, public restart_dm
integer, parameter, public restart_gs
integer, parameter, public restart_type_dump
integer, parameter, public restart_type_load
subroutine, public zstates_elec_calc_projections(st, gs_st, namespace, mesh, ik, proj, gs_nst)
This routine computes the projection between two set of states.
subroutine, public zstates_elec_orthogonalize_single_batch(st, mesh, nst, iqn, phi, normalize, mask, overlap, norm, Theta_fi, beta_ij, against_all)
orthogonalize a single wave function against a set of states
integer pure function, public states_elec_block_max(st, ib)
return index of last state in block ib
subroutine, public states_elec_end(st)
finalize the states_elec_t object
subroutine, public states_elec_copy(stout, stin, exclude_wfns, exclude_eigenval, special)
make a (selective) copy of a states_elec_t object
integer pure function, public states_elec_block_min(st, ib)
return index of first state in block ib
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_t), public unit_kelvin
For converting energies into temperatures.
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)
Distribution of N instances over mpi_grpsize processes, for the local rank mpi_grprank....
Extension of space that contains the knowledge of the spin dimension.
Description of the grid, containing information on derivatives, stencil, and symmetries.
This is defined even when running serial.
Stores all communicators and groups.
The states_elec_t class contains all electronic wave functions.