(git:f2099e5)
Loading...
Searching...
No Matches
floquet_types.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 Environment type holding the work and accumulation arrays of the Floquet-Bloch
10!> band-structure calculation (floquet_main), plus the derived sizes.
11!> \par History
12!> \author Shridhar Shanbhag (27.01.2026)
13! **************************************************************************************************
15 USE kinds, ONLY: dp
17#include "./base/base_uses.f90"
18
19 IMPLICIT NONE
20
21 PRIVATE
22
23 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'floquet_types'
24
25 PUBLIC :: floquet_env_type, &
30
31! **************************************************************************************************
32!> \brief Work and accumulation arrays for one Floquet-Bloch band-structure run, plus the derived
33!> sizes. The per-(k-point,spin) buffers are overwritten each iteration; the all_* arrays
34!> accumulate the results over all DOS k-points and spins.
35!> \param max_f_index Floquet truncation index M
36!> \param n_f_size size of the truncated Floquet Hamiltonian, n_mo*(1 + 2*M)
37!> \param n_E number of points on the DOS energy grid
38!> \param nkp_only_bs number of band-structure k-points (the k-points the Floquet loop runs over)
39!> \param n_mo number of active bands used by the Floquet calculation (the MAX_NMO band window,
40!> or the full molecular-orbital count when MAX_NMO <= 0); all work/output arrays are sized
41!> with this
42!> \param n_mo_full total number of molecular orbitals (full band count before windowing)
43!> \param n_lo lowest full-band index of the active window, per spin (n_spin)
44!> \param n_hi highest full-band index of the active window, per spin (n_spin)
45!> \param n_spin number of spin channels
46!> \param eigenvalues Floquet eigenvalues for the current (k-point,spin) (n_f_size)
47!> \param w0 central-sector weights (n_f_size)
48!> \param wE outermost-sector weights (n_f_size)
49!> \param a_k spectral function A(k,E) on the energy grid (n_E)
50!> \param quasi_energies quasi-energies (n_mo)
51!> \param m0_energies m=0 band energies (n_mo)
52!> \param m0_weights central-sector weight of each m=0 band (n_mo)
53!> \param e_k_kp_spin band energies for the current (k-point,spin) (n_mo)
54!> \param p_k_kp_spin momentum matrix elements for the current (k-point,spin) (3, n_mo, n_mo)
55!> \param all_quasi_energies quasi-energies for every (band, spin, bs k-point) (n_mo, n_spin, nkp_only_bs)
56!> \param all_a_k spectral function for every (energy, spin, bs k-point) (n_E, n_spin, nkp_only_bs)
57!> \param all_m0_energies m=0 band energies for every (band, spin, bs k-point) (n_mo, n_spin, nkp_only_bs)
58!> \param all_m0_weights central-sector weights for every (band, spin, bs k-point) (n_mo, n_spin, nkp_only_bs)
59! **************************************************************************************************
61 INTEGER :: max_f_index = -1, &
62 n_f_size = -1, &
63 n_e = -1, &
64 nkp_only_bs = -1, &
65 n_mo = -1, &
66 n_mo_full = -1, &
67 n_spin = -1
68 INTEGER, ALLOCATABLE, DIMENSION(:) :: n_lo, n_hi
69 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues, w0, we, a_k, &
70 quasi_energies, m0_energies, &
71 m0_weights, e_k_kp_spin
72 COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: p_k_kp_spin
73 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: all_quasi_energies, all_a_k, &
74 all_m0_energies, all_m0_weights
75 END TYPE floquet_env_type
76
77CONTAINS
78
79! **************************************************************************************************
80!> \brief Number of active bands used by the Floquet calculation: the MAX_NMO band window closest
81!> to the VBM, clamped to the full molecular-orbital count, or the full count when MAX_NMO <= 0.
82!> \param bs_env ...
83!> \return the active band count
84! **************************************************************************************************
85 FUNCTION floquet_active_band_count(bs_env) RESULT(n_active)
86 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
87 INTEGER :: n_active
88
89 IF (bs_env%max_nmo_floquet <= 0 .OR. bs_env%max_nmo_floquet >= bs_env%n_ao) THEN
90 n_active = bs_env%n_ao
91 ELSE
92 n_active = bs_env%max_nmo_floquet
93 END IF
94
95 END FUNCTION floquet_active_band_count
96
97! **************************************************************************************************
98!> \brief Full-band index bounds [n_lo, n_hi] of the active window for one spin, selecting the
99!> MAX_NMO Kohn-Sham eigenstates closest to the VBM. Mirrors the HOMO-centred windowing of
100!> qs_moment_kpoints (qs_moments.F), with a final reclamp so the window holds exactly
101!> floquet_active_band_count(bs_env) states regardless of the per-spin HOMO index.
102!> \param bs_env ...
103!> \param ispin spin channel
104!> \param n_lo lowest full-band index of the window
105!> \param n_hi highest full-band index of the window
106! **************************************************************************************************
107 SUBROUTINE floquet_band_window(bs_env, ispin, n_lo, n_hi)
108 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
109 INTEGER, INTENT(IN) :: ispin
110 INTEGER, INTENT(OUT) :: n_lo, n_hi
111
112 INTEGER :: homo, max_nmo, n_mo_full
113
114 n_mo_full = bs_env%n_ao
115 max_nmo = bs_env%max_nmo_floquet
116
117 IF (max_nmo <= 0 .OR. max_nmo >= n_mo_full) THEN
118 n_lo = 1
119 n_hi = n_mo_full
120 ELSE
121 homo = bs_env%n_occ(ispin)
122 n_lo = max(1, homo - (max_nmo - 1)/2)
123 n_hi = min(n_mo_full, n_lo + max_nmo - 1)
124 ! reclamp so the window holds exactly max_nmo states (keeps the fixed-size buffers valid
125 ! when n_occ(1) /= n_occ(2)); a no-op away from the band edges
126 n_lo = max(1, n_hi - max_nmo + 1)
127 END IF
128
129 END SUBROUTINE floquet_band_window
130
131! **************************************************************************************************
132!> \brief Set the derived sizes from bs_env and allocate all work and accumulation arrays.
133!> \param floquet_env ...
134!> \param bs_env ...
135! **************************************************************************************************
136 SUBROUTINE floquet_env_create(floquet_env, bs_env)
137 TYPE(floquet_env_type), INTENT(OUT) :: floquet_env
138 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
139
140 CHARACTER(LEN=*), PARAMETER :: routinen = 'floquet_env_create'
141
142 INTEGER :: handle, ispin, n_mo, ne, nf, nk, ns
143
144 CALL timeset(routinen, handle)
145
146 floquet_env%n_spin = bs_env%n_spin
147 floquet_env%n_mo_full = bs_env%n_ao
148 ! n_mo is the active band count (the MAX_NMO window, or the full count when MAX_NMO <= 0);
149 ! every work/output array below is sized with it
150 floquet_env%n_mo = floquet_active_band_count(bs_env)
151 floquet_env%max_f_index = bs_env%max_floquet_index
152 floquet_env%n_f_size = floquet_env%n_mo*(1 + 2*floquet_env%max_f_index)
153 floquet_env%n_E = nint(2*bs_env%energy_window_floquet/bs_env%energy_step_floquet)
154 floquet_env%nkp_only_bs = bs_env%nkp_only_bs
155
156 ! Per-spin full-band index bounds of the active window (used to slice the full-band data)
157 ALLOCATE (floquet_env%n_lo(floquet_env%n_spin), floquet_env%n_hi(floquet_env%n_spin))
158 DO ispin = 1, floquet_env%n_spin
159 CALL floquet_band_window(bs_env, ispin, floquet_env%n_lo(ispin), floquet_env%n_hi(ispin))
160 END DO
161
162 n_mo = floquet_env%n_mo
163 nf = floquet_env%n_f_size
164 ne = floquet_env%n_E
165 ns = floquet_env%n_spin
166 nk = floquet_env%nkp_only_bs
167
168 ! per-(k-point,spin) work buffers
169 ALLOCATE (floquet_env%eigenvalues(nf), floquet_env%w0(nf), floquet_env%wE(nf))
170 ALLOCATE (floquet_env%a_k(ne))
171 ALLOCATE (floquet_env%quasi_energies(n_mo), floquet_env%m0_energies(n_mo), &
172 floquet_env%m0_weights(n_mo))
173 ALLOCATE (floquet_env%e_k_kp_spin(n_mo), floquet_env%p_k_kp_spin(3, n_mo, n_mo))
174
175 ! per-(spin,k-point) accumulation arrays, filled once by the owning subgroup source and
176 ! summed across the global communicator after the k-point loop
177 ALLOCATE (floquet_env%all_quasi_energies(n_mo, ns, nk), source=0.0_dp)
178 ALLOCATE (floquet_env%all_a_k(ne, ns, nk), source=0.0_dp)
179 ALLOCATE (floquet_env%all_m0_energies(n_mo, ns, nk), source=0.0_dp)
180 ALLOCATE (floquet_env%all_m0_weights(n_mo, ns, nk), source=0.0_dp)
181
182 CALL timestop(handle)
183
184 END SUBROUTINE floquet_env_create
185
186! **************************************************************************************************
187!> \brief Deallocate all arrays held by floquet_env.
188!> \param floquet_env ...
189! **************************************************************************************************
190 SUBROUTINE floquet_env_release(floquet_env)
191 TYPE(floquet_env_type), INTENT(INOUT) :: floquet_env
192
193 CHARACTER(LEN=*), PARAMETER :: routinen = 'floquet_env_release'
194
195 INTEGER :: handle
196
197 CALL timeset(routinen, handle)
198
199 IF (ALLOCATED(floquet_env%n_lo)) DEALLOCATE (floquet_env%n_lo)
200 IF (ALLOCATED(floquet_env%n_hi)) DEALLOCATE (floquet_env%n_hi)
201 IF (ALLOCATED(floquet_env%eigenvalues)) DEALLOCATE (floquet_env%eigenvalues)
202 IF (ALLOCATED(floquet_env%w0)) DEALLOCATE (floquet_env%w0)
203 IF (ALLOCATED(floquet_env%wE)) DEALLOCATE (floquet_env%wE)
204 IF (ALLOCATED(floquet_env%a_k)) DEALLOCATE (floquet_env%a_k)
205 IF (ALLOCATED(floquet_env%quasi_energies)) DEALLOCATE (floquet_env%quasi_energies)
206 IF (ALLOCATED(floquet_env%m0_energies)) DEALLOCATE (floquet_env%m0_energies)
207 IF (ALLOCATED(floquet_env%m0_weights)) DEALLOCATE (floquet_env%m0_weights)
208 IF (ALLOCATED(floquet_env%e_k_kp_spin)) DEALLOCATE (floquet_env%e_k_kp_spin)
209 IF (ALLOCATED(floquet_env%p_k_kp_spin)) DEALLOCATE (floquet_env%p_k_kp_spin)
210 IF (ALLOCATED(floquet_env%all_quasi_energies)) DEALLOCATE (floquet_env%all_quasi_energies)
211 IF (ALLOCATED(floquet_env%all_a_k)) DEALLOCATE (floquet_env%all_a_k)
212 IF (ALLOCATED(floquet_env%all_m0_energies)) DEALLOCATE (floquet_env%all_m0_energies)
213 IF (ALLOCATED(floquet_env%all_m0_weights)) DEALLOCATE (floquet_env%all_m0_weights)
214
215 CALL timestop(handle)
216
217 END SUBROUTINE floquet_env_release
218
219END MODULE floquet_types
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.
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,...
subroutine, public floquet_env_release(floquet_env)
Deallocate all arrays held by floquet_env.
subroutine, public floquet_band_window(bs_env, ispin, n_lo, n_hi)
Full-band index bounds [n_lo, n_hi] of the active window for one spin, selecting the MAX_NMO Kohn-Sha...
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Work and accumulation arrays for one Floquet-Bloch band-structure run, plus the derived sizes....