(git:98357aa)
Loading...
Searching...
No Matches
floquet_main.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Floquet-Bloch band-structure calculations: builds and diagonalises the
10!> truncated Floquet-Bloch Hamiltonian H_F(k) for each DOS k-point and writes the m=0
11!> band structure, the quasi-energies and the Floquet density of states.
12!> \par History
13!> \author Shridhar Shanbhag (27.01.2026)
14! **************************************************************************************************
18 USE cp_cfm_diag, ONLY: cp_cfm_heevd
19 USE cp_cfm_types, ONLY: cp_cfm_create,&
29 USE floquet_utils, ONLY: &
33 USE kinds, ONLY: dp
34 USE mathconstants, ONLY: z_zero
40#include "./base/base_uses.f90"
41
42 IMPLICIT NONE
43
44 PRIVATE
45
46 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'floquet_main'
47
48 PUBLIC :: floquet
49
50CONTAINS
51
52! **************************************************************************************************
53!> \brief Computes the Floquet-Bloch band structure, density of states and quasi-energies.
54!> \param qs_env ...
55!> \param bs_env ...
56! **************************************************************************************************
57 SUBROUTINE floquet(qs_env, bs_env)
58 TYPE(qs_environment_type), POINTER :: qs_env
59 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
60
61 CHARACTER(LEN=*), PARAMETER :: routinen = 'floquet'
62
63 COMPLEX(KIND=dp), ALLOCATABLE, &
64 DIMENSION(:, :, :, :, :) :: dipole
65 INTEGER :: handle, ikp, ispin, my_group, &
66 n_est_done, n_source_done, ngroups
67 INTEGER, ALLOCATABLE, DIMENSION(:) :: group_distribution
68 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: e_k
69 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :, :) :: de_dk
70 TYPE(cp_blacs_env_type), POINTER :: blacs_env_sub
71 TYPE(cp_cfm_type) :: cfm_eigenvectors, floquet_matrix
72 TYPE(cp_fm_struct_type), POINTER :: floquet_struct
73 TYPE(floquet_env_type) :: floquet_env
74 TYPE(mp_para_env_type), POINTER :: para_env, para_env_sub
75
76 CALL timeset(routinen, handle)
77
78 CALL get_qs_env(qs_env, para_env=para_env)
79
80 ! Floquet-Bloch theory: under a monochromatic electric field drive the Hamiltonian is periodic,
81 ! H(k,t) = H(k,t+T) with T = 2π/Ω, where Ω is the angular frequency of the drive.
82 ! By Floquet's theorem the solutions are:
83 ! ψ_αk(t) = e^(-i λ_αk t) Σ_m e^(-i m Ω t) |F^m_αk>, with quasi-energies λ_αk and
84 ! Fourier index m.
85 ! In order to obtain the solutions λ_αk, we start with the Floquet Hamiltonian defined as,
86 ! H_F(k,t) = H(k,t) - iħ d/dt.
87 ! Taking the Fourier transform, the solutions are obtained by diagonalizing the matrix H_F(k)
88 ! H_F(k) F_αk = λ_αk F_αk,
89 ! where H_F(k) is block-tridiagonal in the sector index m = -M..M (M = MAX_FLOQUET_INDEX)
90 ! and each block is nao×nao. We build and diagonalise H_F(k) per DOS k-point k and spin.
91 ! The matrix H_F(k) has size (nao*(2*MAX_FLOQUET_INDEX+1) x nao*(2*MAX_FLOQUET_INDEX+1)).
92
93 CALL write_floquet_header(bs_env)
94
95 CALL floquet_env_create(floquet_env, bs_env)
96
97 ! Equilibrium band data at every band-structure k-point k from H(k)C(k) = S(k)C(k)ε(k):
98 ! band energies ε_nk
99 ! k-derivatives ∇_k ε_nk = C_n(k)^† ∇_k H(k) C_n(k) - ε_nk C_n(k)^† ∇_k S(k) C_n(k)
100 ! dipoles d_nm(k) = <ψ_nk| r |ψ_mk>
101 ! Results are distributed across ranks (k-point ikp stored on rank MOD(ikp-1,num_pe)).
102 CALL compute_e_k_de_dk_dipole(qs_env, bs_env, e_k, de_dk, dipole)
103
104 ! Split the global communicator into Floquet subgroups (Hamiltonian distributed within each
105 ! subgroup, k-points distributed across subgroups) and create the subgroup BLACS context.
106 CALL make_floquet_subgroups(qs_env, bs_env, para_env_sub, blacs_env_sub, &
107 group_distribution, ngroups)
108
109 !get inside make_floquet_subroutine
110 my_group = group_distribution(para_env%mepos)
111
112 CALL cp_fm_struct_create(floquet_struct, context=blacs_env_sub, para_env=para_env_sub, &
113 nrow_global=floquet_env%n_f_size, ncol_global=floquet_env%n_f_size)
114 CALL cp_cfm_create(floquet_matrix, floquet_struct, set_zero=.true.)
115 CALL cp_cfm_create(cfm_eigenvectors, floquet_struct, set_zero=.true.)
116
117 n_source_done = 0
118
119 DO ikp = 1, floquet_env%nkp_only_bs
120 ! Only the subgroup that owns this k-point's data works on it
121 IF (group_distribution(mod(ikp - 1, para_env%num_pe)) /= my_group) cycle
122
123 DO ispin = 1, floquet_env%n_spin
124 ! Broadcast this k-point/spin's ε_nk, ∇_k ε_nk and d_nm(k) to every rank of the
125 ! owning subgroup (its owner rank holds them from the distributed precompute above).
126 CALL distribute_floquet_kp_data(para_env, para_env_sub, ispin, ikp, e_k, de_dk, &
127 dipole, floquet_env)
128
129 ! Assemble H_F(k) in Sambe space (blocks m,m' = -M..M, each nao×nao)
130 ! diagonal (H_F)^{m,m}_{nn'} = (ε_nk + m ħΩ) δ_{nn'}
131 ! off diagonal (H_F)^{m,m±1}_{nn'} = Σ_a p^a_{nn'}(k) (i E_a e^{±iφ_a})/(2Ω), a=x,y,z
132 ! with momentum p^a_{nn'}(k) = i d^a_{nn'}(k)(ε_nk - ε_n'k) + ∇_{k_a} ε_nk δ_{nn'}
133 ! and field E_a = |E| pol_a.
134 CALL build_floquet_matrix(bs_env, floquet_env, floquet_matrix)
135
136 ! Diagonalise H_F(k) F_αk = λ_αk F_αk -> quasi-energies λ_αk and eigenvector components
137 ! F^{n,m}_αk = <n,m|αk> (band index n, sector m).
138 CALL cp_cfm_set_all(cfm_eigenvectors, z_zero)
139 CALL cp_cfm_heevd(floquet_matrix, cfm_eigenvectors, floquet_env%eigenvalues)
140
141 ! Calculate sector weights,
142 ! w_αk^(m) = Σ_{n=1}^{nao} |<n,m|αk>|^2 (with Σ_m w_αk^(m) = 1).
143 ! Keep only the central weight w0_αk = w_αk^(0) and the outermost-rung weight
144 ! wE_αk = w_αk^(-M) + w_αk^(+M)
145 CALL floquet_sector_weights(floquet_env, cfm_eigenvectors)
146
147 ! Truncation check: the m=0-dominated states (w0_αk > 1/2) must leak negligibly onto the
148 ! outermost rungs, max_{α: w0_αk > 1/2} wE_αk ≤ EPS_FLOQUET, else M is too small.
149 CALL check_floquet_convergence(bs_env, floquet_env)
150
151 ! From λ_αk and w0_αk obtain, and store on the subgroup source for (ispin,ikp):
152 ! DOS:
153 ! A(k,E) = -(1/π) Im Tr_KS G^R_00(k,E) = -(1/π) Σ_α w0_αk Im[1/(E+iη-λ_αk)]
154 ! with G^R_00 = [(E+iη) - H_F(k)]^{-1}_{m=0,m=0}, η = broadening/2.
155 ! The central (m=0) block of the retarded Floquet Green's function gives the
156 ! physical, time-averaged spectral function / density of states; see
157 ! T. Oka and S. Kitamura, Annu. Rev. Condens. Matter Phys. 10, 387 (2019), and
158 ! N. Tsuji, T. Oka, and H. Aoki, Phys. Rev. B 78, 235124 (2008).
159 ! m=0 bands:
160 ! ε^{0}_ik = λ_{α(i)}k, with band i placed at the eigenvalue where the cumulative
161 ! m=0 weight Σ_{λ_αk<E} w0_αk first crosses i - 1/2.
162 ! We know that: Σ_α w0_αk = nao. So we choose the matrix eigenvalue such that:
163 ! N(ε) = Σ_{α : λ_αk ≤ ε} w0_αk first crosses i - 1/2 to find the m=0 band.
164 ! Quasi-energy:
165 ! ε̃_ik = ε^{0}_ik - mħΩ (choose m such that ε̃_ik is folded to (-ħΩ/2, ħΩ/2]).
166 CALL calculate_floquet_observables(bs_env, para_env_sub, ispin, ikp, floquet_env)
167 END DO
168
169 ! Rough live K-Point progress
170 IF (bs_env%unit_nr > 0) THEN
171 n_source_done = n_source_done + 1
172 n_est_done = min(n_source_done*ngroups, floquet_env%nkp_only_bs)
173 WRITE (bs_env%unit_nr, '(T2,A,I6,A,F6.1,A)') &
174 "FLOQUET PROGRESS | Estimated no. of k-points done: ", n_est_done, " (", &
175 100.0_dp*real(n_est_done, dp)/real(floquet_env%nkp_only_bs, dp), " %)"
176 END IF
177 END DO
178
179 ! Write the m=0 bands ε^{0}_ik, the quasi-energies ε̃_ik and the DOS A(k,E) in their
180 ! respective files
181 CALL write_floquet_results(bs_env, floquet_env)
182
183 DEALLOCATE (e_k, de_dk, dipole)
184 DEALLOCATE (group_distribution)
185 CALL floquet_env_release(floquet_env)
186 CALL cp_cfm_release(floquet_matrix)
187 CALL cp_cfm_release(cfm_eigenvectors)
188 CALL cp_fm_struct_release(floquet_struct)
189 CALL cp_blacs_env_release(blacs_env_sub)
190 CALL mp_para_env_release(para_env_sub)
191
192 CALL timestop(handle)
193
194 END SUBROUTINE floquet
195
196END MODULE floquet_main
methods related to the blacs parallel environment
subroutine, public cp_blacs_env_release(blacs_env)
releases the given blacs_env
used for collecting diagonalization schemes available for cp_cfm_type
Definition cp_cfm_diag.F:14
subroutine, public cp_cfm_heevd(matrix, eigenvectors, eigenvalues)
Perform a diagonalisation of a complex matrix.
Definition cp_cfm_diag.F:74
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_cfm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_set_all(matrix, alpha, beta)
Set all elements of the full matrix to alpha. Besides, set all diagonal matrix elements to beta (if g...
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
Floquet-Bloch band-structure calculations: builds and diagonalises the truncated Floquet-Bloch Hamilt...
subroutine, public floquet(qs_env, bs_env)
Computes the Floquet-Bloch band structure, density of states and quasi-energies.
Environment type holding the work and accumulation arrays of the Floquet-Bloch band-structure calcula...
subroutine, public floquet_env_create(floquet_env, bs_env)
Set the derived sizes from bs_env and allocate all work and accumulation arrays.
subroutine, public floquet_env_release(floquet_env)
Deallocate all arrays held by floquet_env.
Helper routines for the Floquet-Bloch band-structure calculation (floquet_main).
subroutine, public floquet_sector_weights(floquet_env, cfm_eigenvectors)
Central and boundary-sector weights of every Floquet eigenvector, stored into floquet_envw0 and floqu...
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 compute_e_k_de_dk_dipole(qs_env, bs_env, e_k, de_dk, dipole)
Precompute, on the global communicator, the band quantities needed to assemble the Floquet-Bloch Hami...
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 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 distribute_floquet_kp_data(para_env, para_env_sub, ispin, ikp, e_k, de_dk, dipole, floquet_env)
Make this k-point/spin's band data available to every rank of the owning subgroup.
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public z_zero
Interface to the message passing library MPI.
subroutine, public mp_para_env_release(para_env)
releases the para object (to be called when you don't want anymore the shared copy of this object)
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.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
Represent a complex full matrix.
keeps the information about the structure of a 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