43#include "./base/base_uses.f90"
49 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'floquet_utils'
54 INTEGER,
PARAMETER,
PRIVATE :: n_fm_work_copies = 8
75 SUBROUTINE build_off_diagonal_matrix(bs_env, p_k_kp_spin, off_diag_m)
76 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
77 COMPLEX(KIND=dp),
DIMENSION(:, :, :),
INTENT(IN) :: p_k_kp_spin
78 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(OUT) :: off_diag_m
80 CHARACTER(LEN=*),
PARAMETER :: routineN =
'build_off_diagonal_matrix'
82 COMPLEX(KIND=dp),
DIMENSION(3) :: efactor
83 INTEGER :: handle, i, i_dir, j, n_mo
84 REAL(KIND=
dp) :: amplitude, omega
85 REAL(KIND=
dp),
DIMENSION(3) :: e_vec, phi, polarisation
87 CALL timeset(routinen, handle)
91 n_mo =
SIZE(p_k_kp_spin, 2)
93 polarisation(:) = bs_env%floquet_polarisation(:)
94 IF (sqrt(sum(polarisation**2)) < epsilon(0.0_dp))
THEN
95 cpabort(
"Invalid (too small) polarisation vector specified for POLARISATION")
98 amplitude = bs_env%floquet_amplitude
99 e_vec(:) = amplitude*polarisation
100 phi(:) =
pi*bs_env%floquet_phi(:)
101 omega = bs_env%floquet_omega
105 efactor(i_dir) =
gaussi*e_vec(i_dir)*cmplx(cos(phi(i_dir)), sin(phi(i_dir)), kind=
dp)/(2*omega)
113 off_diag_m(i, j) = off_diag_m(i, j) + &
114 p_k_kp_spin(i_dir, i, j)*efactor(i_dir)
119 CALL timestop(handle)
121 END SUBROUTINE build_off_diagonal_matrix
130 SUBROUTINE build_diagonal_matrix(bs_env, e_k_kp_spin, f_index, diag_e)
131 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
132 REAL(KIND=
dp),
DIMENSION(:),
INTENT(IN) :: e_k_kp_spin
133 INTEGER,
INTENT(IN) :: f_index
134 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(OUT) :: diag_e
136 CHARACTER(LEN=*),
PARAMETER :: routineN =
'build_diagonal_matrix'
138 INTEGER :: handle, i, n_mo
139 REAL(KIND=
dp) :: omega
141 CALL timeset(routinen, handle)
144 n_mo =
SIZE(e_k_kp_spin)
145 omega = bs_env%floquet_omega
148 diag_e(i, i) = e_k_kp_spin(i) + f_index*omega
151 CALL timestop(handle)
153 END SUBROUTINE build_diagonal_matrix
167 CHARACTER(LEN=*),
PARAMETER :: routinen =
'build_floquet_matrix'
169 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: conj_off_diag_m, diag_e, off_diag_m
170 INTEGER :: f_index, handle, i, i_f, max_f_index, &
173 CALL timeset(routinen, handle)
175 n_mo = floquet_env%n_mo
176 max_f_index = floquet_env%max_f_index
177 n_fbands = 1 + 2*max_f_index
180 ALLOCATE (diag_e(n_mo, n_mo), source=
z_zero)
181 ALLOCATE (off_diag_m(n_mo, n_mo), source=
z_zero)
182 ALLOCATE (conj_off_diag_m(n_mo, n_mo), source=
z_zero)
184 CALL build_off_diagonal_matrix(bs_env, floquet_env%p_k_kp_spin, off_diag_m)
185 conj_off_diag_m(:, :) = conjg(transpose(off_diag_m(:, :)))
187 floquet_matrix%local_data(:, :) =
z_zero
189 i_f = 1 + (i - 1)*n_mo
190 f_index = i - max_f_index - 1
191 CALL build_diagonal_matrix(bs_env, floquet_env%e_k_kp_spin, f_index, diag_e)
198 DEALLOCATE (diag_e, off_diag_m, conj_off_diag_m)
200 CALL timestop(handle)
216 INTEGER,
INTENT(IN) :: ispin, ikp
217 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: e_k
218 COMPLEX(KIND=dp),
DIMENSION(:, :, :, :, :), &
222 CHARACTER(LEN=*),
PARAMETER :: routinen =
'distribute_floquet_kp_data'
224 INTEGER :: handle, loc_idx, local_src, nhi, nlo, &
227 CALL timeset(routinen, handle)
230 owner = mod(ikp - 1, para_env%num_pe)
233 IF (para_env%mepos == owner) local_src = para_env_sub%mepos
234 CALL para_env_sub%max(local_src)
240 IF (para_env%mepos == owner)
THEN
241 loc_idx = ceiling(real(ikp)/para_env%num_pe)
242 nlo = floquet_env%n_lo(ispin)
243 nhi = floquet_env%n_hi(ispin)
244 floquet_env%e_k_kp_spin(:) = e_k(ispin, loc_idx, nlo:nhi)
245 floquet_env%p_k_kp_spin(:, :, :) = p_k(ispin, loc_idx, :, nlo:nhi, nlo:nhi)
247 CALL para_env_sub%bcast(floquet_env%e_k_kp_spin, local_src)
248 CALL para_env_sub%bcast(floquet_env%p_k_kp_spin, local_src)
250 CALL timestop(handle)
265 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :), &
267 COMPLEX(KIND=dp),
ALLOCATABLE, &
268 DIMENSION(:, :, :, :, :),
INTENT(OUT) :: p_k
270 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_e_k_p_k'
272 INTEGER :: handle, ikp, nkp_only_bs, nkp_start
273 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: xkp_all
275 CALL timeset(routinen, handle)
279 nkp_start = bs_env%nkp_only_DOS
280 nkp_only_bs = bs_env%nkp_only_bs
283 ALLOCATE (xkp_all(3, nkp_only_bs))
284 DO ikp = 1, nkp_only_bs
285 xkp_all(:, ikp) = bs_env%kpoints_DOS%xkp(1:3, nkp_start + ikp)
295 CALL timestop(handle)
304 FUNCTION find_ranks_per_node(para_env)
RESULT(ranks_per_node)
306 INTEGER :: ranks_per_node
311 ranks_per_node = max(1, node_comm%num_pe)
312 CALL node_comm%free()
314 END FUNCTION find_ranks_per_node
322 FUNCTION floquet_determine_subgroup_size(qs_env, bs_env)
RESULT(group_size)
325 INTEGER :: group_size
327 CHARACTER(LEN=*),
PARAMETER :: routinen =
'floquet_determine_subgroup_size'
329 INTEGER :: g_load, g_mem, handle, n_f_size, &
330 nkp_only_bs, ranks_per_node, unit_nr
331 INTEGER(KIND=int_8) :: buffers, cached, memfree, memlikelyfree, &
332 memtotal, needed_bytes, slab, &
333 sreclaimable, usable_per_rank
334 REAL(kind=
dp) :: mem_fill_fraction
337 CALL timeset(routinen, handle)
341 unit_nr = bs_env%unit_nr
344 nkp_only_bs = bs_env%nkp_only_bs
345 mem_fill_fraction = bs_env%floquet_mem_fill_fraction
357 CALL m_memory_details(memtotal, memfree, buffers, cached, slab, sreclaimable, memlikelyfree)
358 ranks_per_node = find_ranks_per_node(para_env)
359 usable_per_rank = int(mem_fill_fraction*real(memfree,
dp),
int_8)/int(ranks_per_node,
int_8)
363 needed_bytes = 16_int_8*int(n_fm_work_copies,
int_8)*int(n_f_size,
int_8)**2
365 IF (usable_per_rank <= 0_int_8)
THEN
367 g_mem = para_env%num_pe
370 g_mem = int(min((needed_bytes + usable_per_rank - 1_int_8)/usable_per_rank, &
371 int(para_env%num_pe,
int_8)))
374 IF (g_mem > para_env%num_pe) cpwarn(
"Total Memory Likely Insufficient, process may be killed")
377 g_load = para_env%num_pe/max(nkp_only_bs, 1)
379 group_size = max(g_mem, g_load)
380 group_size = min(group_size, para_env%num_pe)
381 group_size = max(group_size, 1)
382 CALL para_env%max(group_size)
384 IF (unit_nr > 0)
THEN
385 WRITE (unit_nr,
'(T2,A)')
""
386 WRITE (unit_nr,
'(T2,A,T66,I15)')
"FLOQUET MEMORY | Detected MPI ranks per node:", ranks_per_node
387 WRITE (unit_nr,
'(T2,A,T66,I12,A)')
"FLOQUET MEMORY | Free memory per rank:", &
388 (memlikelyfree/int(ranks_per_node,
int_8))/1048576_int_8,
" MB"
389 WRITE (unit_nr,
'(T2,A,T66,I12,A)')
"FLOQUET MEMORY | Usable per rank (reserve applied):", &
390 usable_per_rank/1048576_int_8,
" MB"
391 WRITE (unit_nr,
'(T2,A,T66,I15)')
"FLOQUET MEMORY | Floquet copies needed:", n_fm_work_copies
392 WRITE (unit_nr,
'(T2,A,T66,I12,A)')
"FLOQUET MEMORY | Total Floquet working set:", &
393 needed_bytes/1048576_int_8,
" MB"
394 WRITE (unit_nr,
'(T2,A,T66,I12,A)')
"FLOQUET MEMORY | Floquet working set per rank:", &
395 (needed_bytes/int(max(group_size, 1),
int_8))/1048576_int_8,
" MB"
396 WRITE (unit_nr,
'(T2,A,T66,I15)')
"FLOQUET MEMORY | Memory floor (ranks/subgroup):", g_mem
397 WRITE (unit_nr,
'(T2,A,T66,I15)')
"FLOQUET MEMORY | K-point floor (ranks/subgroup):", g_load
398 WRITE (unit_nr,
'(T2,A,T66,I15)')
"FLOQUET MEMORY | Chosen MPI ranks per subgroup:", group_size
401 CALL timestop(handle)
402 END FUNCTION floquet_determine_subgroup_size
415 group_distribution, ngroups)
420 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(OUT) :: group_distribution
421 INTEGER,
INTENT(OUT) :: ngroups
423 CHARACTER(LEN=*),
PARAMETER :: routinen =
'make_floquet_subgroups'
425 INTEGER :: group_size, handle, n_spin, nkp_only_bs, &
429 CALL timeset(routinen, handle)
432 unit_nr = bs_env%unit_nr
433 nkp_only_bs = bs_env%nkp_only_bs
434 n_spin = bs_env%n_spin
438 group_size = floquet_determine_subgroup_size(qs_env, bs_env)
440 IF (nkp_only_bs < para_env%num_pe)
THEN
441 stride_kp = para_env%num_pe/group_size
445 ALLOCATE (group_distribution(0:para_env%num_pe - 1))
446 ALLOCATE (para_env_sub)
447 CALL para_env_sub%from_split(comm=para_env, ngroups=ngroups, &
448 group_distribution=group_distribution, &
449 subgroup_min_size=group_size, stride=stride_kp)
450 IF (unit_nr > 0)
THEN
451 WRITE (unit_nr,
'(T2,A,T66,I15)')
"FLOQUET MEMORY | Subgroup rank stride:", stride_kp
452 WRITE (unit_nr,
'(T2,A,T66,I15)')
"FLOQUET MEMORY | Number of subgroups:", ngroups
453 WRITE (unit_nr,
'(/,T2,A,I5,A,I1,A)')
"FLOQUET CALCULATIONS PROGRESS OUT OF", nkp_only_bs, &
454 " K-POINTS AND ", n_spin,
" SPINS"
457 NULLIFY (blacs_env_sub)
460 CALL timestop(handle)
472 TYPE(
cp_cfm_type),
INTENT(IN) :: floquet_eigenvectors
474 CHARACTER(LEN=*),
PARAMETER :: routinen =
'floquet_sector_weights'
476 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: v_block
477 INTEGER :: handle, max_f_index, n_f_size, n_mo
479 CALL timeset(routinen, handle)
481 n_mo = floquet_env%n_mo
482 max_f_index = floquet_env%max_f_index
483 n_f_size = floquet_env%n_f_size
485 ALLOCATE (v_block(n_mo, n_f_size))
489 floquet_env%w0(:) = sum(abs(v_block)**2, dim=1)
492 floquet_env%wE(:) = 0.0_dp
493 IF (max_f_index >= 1)
THEN
495 floquet_env%wE(:) = sum(abs(v_block)**2, dim=1)
498 floquet_env%wE(:) = floquet_env%wE(:) + sum(abs(v_block)**2, dim=1)
504 cpassert(abs(sum(floquet_env%w0) - real(n_mo,
dp)) < 1.0e-6_dp*real(n_mo,
dp))
506 CALL timestop(handle)
520 CHARACTER(LEN=*),
PARAMETER :: routinen =
'check_floquet_convergence'
522 CHARACTER(LEN=default_string_length) :: msg
524 REAL(kind=
dp) :: leak
527 CALL timeset(routinen, handle)
530 IF (bs_env%max_floquet_index < 1)
THEN
531 CALL timestop(handle)
537 IF (.NOT. any(floquet_env%w0 > 0.5_dp))
THEN
538 cpwarn(
"Floquet: no m=0-dominated state; cannot assess MAX_FLOQUET_INDEX convergence.")
539 CALL timestop(handle)
543 leak = maxval(floquet_env%wE, mask=(floquet_env%w0 > 0.5_dp))
545 IF (bs_env%eps_floquet > 0.0_dp .AND. leak > bs_env%eps_floquet)
THEN
546 WRITE (msg,
'(A,ES10.2E2,A,ES10.2E2)') &
547 "MAX_FLOQUET_INDEX is too small. Leak: ", leak,
"exceeds EPS_FLOQUET: ", bs_env%eps_floquet
551 CALL timestop(handle)
560 FUNCTION floquet_reference_energy(bs_env)
RESULT(mu)
564 IF (bs_env%do_gw .OR. &
566 mu = bs_env%band_edges_scf%VBM
567 ELSE IF (bs_env%n_spin == 1)
THEN
568 mu = bs_env%eigenval_scf_Gamma(bs_env%n_occ(1), 1)
570 mu = max(bs_env%eigenval_scf_Gamma(bs_env%n_occ(1), 1), &
571 bs_env%eigenval_scf_Gamma(bs_env%n_occ(2), 2))
574 END FUNCTION floquet_reference_energy
589 INTEGER,
INTENT(IN) :: ispin, ikp
592 CHARACTER(LEN=*),
PARAMETER :: routinen =
'calculate_floquet_observables'
594 INTEGER :: handle, i, i_e, j, n_e, n_f_size, n_mo
595 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: work
596 REAL(kind=
dp) :: broad, cum, e_min, energy, energy_step, &
597 mu, omega, target_level
599 CALL timeset(routinen, handle)
601 n_f_size = floquet_env%n_f_size
602 n_mo = floquet_env%n_mo
603 n_e = floquet_env%n_E
605 mu = floquet_reference_energy(bs_env)
606 omega = bs_env%floquet_omega
607 broad = bs_env%broadening_floquet
608 energy_step = bs_env%energy_step_floquet
609 e_min = mu - bs_env%energy_window_floquet
618 energy = e_min + i_e*energy_step
619 floquet_env%a_k(i_e) = -sum(floquet_env%w0(:)* &
621 floquet_env%eigenvalues(:))))/
pi
628 target_level = real(i,
dp) - 0.5_dp
629 DO WHILE (cum < target_level .AND. j < n_f_size)
631 cum = cum + floquet_env%w0(j)
633 floquet_env%m0_energies(i) = floquet_env%eigenvalues(j) - mu
634 floquet_env%m0_weights(i) = floquet_env%w0(j)
638 floquet_env%quasi_energies(:) = floquet_env%m0_energies &
639 - omega*real(ceiling(floquet_env%m0_energies/omega - 0.5_dp),
dp)
642 ALLOCATE (work(n_mo))
643 CALL sort(floquet_env%quasi_energies, n_mo, work)
648 IF (para_env_sub%is_source())
THEN
649 floquet_env%all_quasi_energies(:, ispin, ikp) = floquet_env%quasi_energies(:)
650 floquet_env%all_a_k(:, ispin, ikp) = floquet_env%a_k(:)
651 floquet_env%all_m0_energies(:, ispin, ikp) = floquet_env%m0_energies(:)
652 floquet_env%all_m0_weights(:, ispin, ikp) = floquet_env%m0_weights(:)
655 CALL timestop(handle)
666 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_floquet_header'
668 INTEGER :: handle, n_active, n_f_size, unit_nr
670 CALL timeset(routinen, handle)
672 unit_nr = bs_env%unit_nr
675 n_f_size = n_active*(1 + 2*bs_env%max_floquet_index)
677 IF (unit_nr > 0)
THEN
679 WRITE (unit_nr,
'(T2,A)')
' '
680 WRITE (unit_nr,
'(T2,A)') repeat(
'-', 79)
681 WRITE (unit_nr,
'(T2,A,A78)')
'-',
'-'
682 WRITE (unit_nr,
'(T2,A,A51,A27)')
'-',
'FLOQUET BANDSTRUCTURE CALCULATION',
'-'
683 WRITE (unit_nr,
'(T2,A,A78)')
'-',
'-'
684 WRITE (unit_nr,
'(T2,A)') repeat(
'-', 79)
685 WRITE (unit_nr,
'(T2,A)')
' '
687 WRITE (unit_nr,
'(T2,A,T37,A,T67,ES12.2E2)')
"FLOQUET PARAMETERS",
"Amplitude [V/m]:", &
689 WRITE (unit_nr,
'(T37,A,T67,F12.4)')
"Frequency [eV]:", bs_env%floquet_omega*
evolt
690 WRITE (unit_nr,
'(T37,A)') repeat(
"-", 44)
691 WRITE (unit_nr,
'(T37,A,T55,3F8.4)')
"Polarisation:", bs_env%floquet_polarisation(1:3)
692 WRITE (unit_nr,
'(T37,A,T55,3F8.4)')
"Phase offsets:",
pi*bs_env%floquet_phi(1:3)
693 WRITE (unit_nr,
'(T37,A)') repeat(
"-", 44)
694 WRITE (unit_nr,
'(T37,A,T67,I12)')
"Max Floquet index:", bs_env%max_floquet_index
695 WRITE (unit_nr,
'(T37,A,T67,I12)')
"Max KS states (MAX_NMO, 0=all):", bs_env%max_nmo_floquet
696 WRITE (unit_nr,
'(T37,A,T67,I12)')
"Active bands used (of total):", n_active
697 WRITE (unit_nr,
'(T37,A,T67,I12)')
"Total number of bands:", bs_env%n_ao
698 WRITE (unit_nr,
'(T37,A,T67,I12)')
"Floquet Hamiltonian Size:", n_f_size
699 WRITE (unit_nr,
'(T37,A)') repeat(
"-", 44)
700 WRITE (unit_nr,
'(T37,A,T67,F12.4)') &
701 "Energy window [eV]:", bs_env%energy_window_floquet*
evolt
702 WRITE (unit_nr,
'(T37,A,T67,F12.4)')
"Energy step [eV]:", bs_env%energy_step_floquet*
evolt
703 WRITE (unit_nr,
'(T37,A,T67,F12.4)')
"Broadening [eV]:", bs_env%broadening_floquet*
evolt
704 WRITE (unit_nr,
'(T37,A)') repeat(
"-", 44)
705 WRITE (unit_nr,
'(A)')
""
707 WRITE (unit_nr,
'(T2,A)') &
708 "We construct the Floquet-Bloch Hamiltonian and diagonalise it. Projecting the"
709 WRITE (unit_nr,
'(T2,A)') &
710 "eigenvectors onto the Floquet sectors gives the weights w = Σ_n |<n,m|α>|²,"
711 WRITE (unit_nr,
'(T2,A)') &
712 "from which all of the following are obtained."
713 WRITE (unit_nr,
'(A)')
""
714 WRITE (unit_nr,
'(T2,A)') &
715 "The m=0 bands are the eigenvectors with the largest central-sector weight; they"
716 WRITE (unit_nr,
'(T2,A)') &
717 "reduce to the equilibrium bands at zero field and are stored, with their"
718 WRITE (unit_nr,
'(T2,A)') &
719 " weights, in FLOQUET_BANDSTRUCTURE.bs"
720 WRITE (unit_nr,
'(A)')
""
721 WRITE (unit_nr,
'(T2,A)') &
722 "Folding those bands into the first Floquet Brillouin zone, relative to the VBM,"
723 WRITE (unit_nr,
'(T2,A)') &
724 "gives the quasi-energies stored in QUASI_ENERGIES.bs"
725 WRITE (unit_nr,
'(A)')
""
726 WRITE (unit_nr,
'(T2,A)') &
727 "The k-resolved density of states is obtained by computing the trace of"
728 WRITE (unit_nr,
'(T2,A)') &
729 "the retarded Green's function and stored in FLOQUET_DOS.out"
730 WRITE (unit_nr,
'(T2,A)') &
731 "DOS(ω,k) = -1/π*Im[Tr_KS(G^R(ω,k))]"
732 WRITE (unit_nr,
'(A)')
""
735 CALL timestop(handle)
749 CHARACTER(LEN=*),
PARAMETER :: routinen =
'write_floquet_results'
751 CHARACTER(LEN=default_string_length) :: fname
752 INTEGER :: bunit, handle, i, i_e, ikp_for_file, &
753 ispin, n_e, n_mo, n_spin, nkp_only_bs, &
754 nkp_start, qunit, wunit
755 REAL(kind=
dp) :: e_min, energy, energy_step, f_occ, kt, &
757 REAL(kind=
dp),
DIMENSION(3) :: xkp
759 CALL timeset(routinen, handle)
762 CALL bs_env%para_env%sum(floquet_env%all_quasi_energies)
763 CALL bs_env%para_env%sum(floquet_env%all_a_k)
764 CALL bs_env%para_env%sum(floquet_env%all_m0_energies)
765 CALL bs_env%para_env%sum(floquet_env%all_m0_weights)
767 IF (bs_env%para_env%is_source())
THEN
769 n_mo = floquet_env%n_mo
770 n_spin = floquet_env%n_spin
771 nkp_only_bs = floquet_env%nkp_only_bs
772 n_e = floquet_env%n_E
773 nkp_start = bs_env%nkp_only_DOS
776 mu = floquet_reference_energy(bs_env)
777 energy_step = bs_env%energy_step_floquet
778 e_min = mu - bs_env%energy_window_floquet
781 kt = bs_env%floquet_temperature/
kelvin
786 WRITE (fname,
"(2A)") trim(bs_env%floquet_bs_file),
".bs"
787 CALL open_file(trim(fname), unit_number=bunit, file_status=
"REPLACE", file_action=
"WRITE")
788 WRITE (bunit,
"(A)")
"# Floquet m=0 (central-sector) band structure"
789 WRITE (bunit,
"(A)")
"# (in units of eV, relative to the VBM, not folded)"
790 WRITE (bunit,
"(A)")
"# w = sum_n |<n,m=0|alpha>|^2 in [0,1]: w~1 clean m=0 replica,"
791 WRITE (bunit,
"(A)")
"# w~0.5 hybridised with a sideband (drive near resonance)"
792 WRITE (bunit,
"(A)")
"# The band column is the absolute Kohn-Sham band index; only the"
793 WRITE (bunit,
"(A)")
"# MAX_NMO band window closest to the VBM is reported (all bands if 0)."
796 WRITE (fname,
"(2A)") trim(bs_env%floquet_qe_file),
".bs"
797 CALL open_file(trim(fname), unit_number=qunit, file_status=
"REPLACE", file_action=
"WRITE")
798 WRITE (qunit,
"(A)")
"# Quasi-energies obtained by diagonalising the Floquet Hamiltonian"
799 WRITE (qunit,
"(A)")
"# (in units of eV, the m=0 bands relative to the VBM, folded to"
800 WRITE (qunit,
"(A)")
"# the first Floquet Brillouin zone -hbar*Omega/2 < e <= hbar*Omega/2)"
803 WRITE (fname,
"(2A)") trim(bs_env%floquet_dos_file),
".out"
804 CALL open_file(trim(fname), unit_number=wunit, file_status=
"REPLACE", file_action=
"WRITE")
805 WRITE (wunit,
"(A)")
"# Floquet Density of States: D(ω,k) = -1/π*Im[Tr_KS(G^R(ω,k))]"
807 DO ikp_for_file = 1, nkp_only_bs
808 xkp(1:3) = bs_env%kpoints_DOS%xkp(1:3, nkp_start + ikp_for_file)
812 WRITE (bunit,
"(A,I0,T10,A,I0,A,T24,3(1X,F14.8))") &
813 "# Spin ", ispin,
" Point ", ikp_for_file,
": ", xkp(1:3)
814 WRITE (bunit,
"(A)")
"# KS band Energy [eV] m=0 weight"
816 WRITE (bunit,
"(I8,F21.8,F17.5)") floquet_env%n_lo(ispin) - 1 + i, &
817 floquet_env%all_m0_energies(i, ispin, ikp_for_file)*
evolt, &
818 floquet_env%all_m0_weights(i, ispin, ikp_for_file)
822 WRITE (qunit,
"(A,I0,T10,A,I0,A,T24,3(1X,F14.8))") &
823 "# Spin ", ispin,
" Point ", ikp_for_file,
": ", xkp(1:3)
824 WRITE (qunit,
"(A)")
"# Floquet band Quasi-energy [eV]"
826 WRITE (qunit,
"(I8,F21.8)") i, &
827 floquet_env%all_quasi_energies(i, ispin, ikp_for_file)*
evolt
832 WRITE (wunit,
"(A,I0,T10,A,I0,A,T24,3(1X,F14.8))") &
833 "# Spin ", ispin,
" Point ", ikp_for_file,
": ", xkp(1:3)
834 IF (bs_env%floquet_temperature > 0.0_dp)
THEN
835 WRITE (wunit,
"(A)")
"#Energy-VBM (eV) A(ω,k) = DOS (1/eV) f*A = occupied DOS (1/eV)"
837 energy = e_min + i_e*energy_step
839 IF (x > 40.0_dp)
THEN
841 ELSE IF (x < -40.0_dp)
THEN
844 f_occ = 1.0_dp/(exp(x) + 1.0_dp)
846 WRITE (wunit,
"(2X,3G13.4)") (energy - mu)*
evolt, &
847 floquet_env%all_a_k(i_e, ispin, ikp_for_file)/
evolt, &
848 f_occ*floquet_env%all_a_k(i_e, ispin, ikp_for_file)/
evolt
851 WRITE (wunit,
"(A)")
"#Energy-VBM (eV) A(ω,k) = DOS (1/eV)"
853 energy = e_min + i_e*energy_step
854 WRITE (wunit,
"(2X,2G13.4)") (energy - mu)*
evolt, &
855 floquet_env%all_a_k(i_e, ispin, ikp_for_file)/
evolt
867 CALL timestop(handle)
methods related to the blacs parallel environment
subroutine, public cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
allocates and initializes a type that represent a blacs context
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
Extract a sub-matrix from the full matrix: op(target_m)(1:n_rows,1:n_cols) = fm(start_row:start_row+n...
subroutine, public cp_cfm_set_submatrix(matrix, new_values, start_row, start_col, n_rows, n_cols, alpha, beta, transpose)
Set a sub-matrix of the full matrix: matrix(start_row:start_row+n_rows,start_col:start_col+n_cols) = ...
Utility routines to open and close files. Tracking of preconnections.
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Environment type holding the work and accumulation arrays of the Floquet-Bloch band-structure calcula...
integer function, public floquet_active_band_count(bs_env)
Number of active bands used by the Floquet calculation: the MAX_NMO band window closest to the VBM,...
Helper routines for the Floquet-Bloch band-structure calculation (floquet_main).
subroutine, public check_floquet_convergence(bs_env, floquet_env)
Checks that MAX_FLOQUET_INDEX is large enough and the Floquet Hamiltonian was truncated far enough aw...
subroutine, public make_floquet_subgroups(qs_env, bs_env, para_env_sub, blacs_env_sub, group_distribution, ngroups)
Split the para_env into subgroups so that the Floquet Hamiltonian is distributed across the ranks of ...
subroutine, public write_floquet_header(bs_env)
Print the Floquet header with the input parameters and a short description of the output.
subroutine, public write_floquet_results(bs_env, floquet_env)
Sum the accumulated results across MPI ranks and write the m=0 band structure, the quasi-energies and...
subroutine, public build_floquet_matrix(bs_env, floquet_env, floquet_matrix)
Builds the Floquet-Bloch Hamiltonian H_F(k) for a single k-point and spin channel from the band data ...
subroutine, public distribute_floquet_kp_data(para_env, para_env_sub, ispin, ikp, e_k, p_k, floquet_env)
Make this k-point/spin's band data available to every rank of the owning subgroup.
subroutine, public compute_e_k_p_k(qs_env, bs_env, e_k, p_k)
Precompute, on the global communicator, the band quantities needed to assemble the Floquet-Bloch Hami...
subroutine, public calculate_floquet_observables(bs_env, para_env_sub, ispin, ikp, floquet_env)
Calculate all Floquet observables for one k-point and spin: the DOS (a_k), the m=0 bands,...
subroutine, public floquet_sector_weights(floquet_env, floquet_eigenvectors)
Central and boundary-sector weights of every Floquet eigenvector, stored into floquet_envw0 and floqu...
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
integer, parameter, public default_string_length
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_memory_details(memtotal, memfree, buffers, cached, slab, sreclaimable, memlikelyfree)
get more detailed memory info, all units are bytes. the only 'useful' option is MemLikelyFree which i...
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
complex(kind=dp), parameter, public z_one
complex(kind=dp), parameter, public gaussi
complex(kind=dp), parameter, public z_zero
Interface to the message passing library MPI.
type(mp_split_type), parameter, public mp_comm_split_type_shared
Definition of physical constants:
real(kind=dp), parameter, public a_bohr
real(kind=dp), parameter, public kelvin
real(kind=dp), parameter, public evolt
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Calculates the moment integrals <a|r^m|b> and <a|r x d/dr|b>.
subroutine, public qs_moment_kpoints_deep(qs_env, xkp, dipole, rcc, berry_c, momentum, energy, do_parallel)
Calculates the dipole moments, berry curvature, momentum and band energy for periodic systems for kpo...
All kind of helpful little routines.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
Represent a complex full matrix.
Work and accumulation arrays for one Floquet-Bloch band-structure run, plus the derived sizes....
stores all the informations relevant to an mpi environment