Line data Source code
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 Calculation of band structures
10 : !> \par History
11 : !> 2015.06 created [JGH]
12 : !> \author JGH
13 : ! **************************************************************************************************
14 : MODULE qs_band_structure
15 : USE cell_types, ONLY: cell_type
16 : USE cp_blacs_env, ONLY: cp_blacs_env_type
17 : USE cp_control_types, ONLY: dft_control_type
18 : USE cp_dbcsr_api, ONLY: dbcsr_p_type
19 : USE cp_files, ONLY: close_file,&
20 : open_file
21 : USE cp_log_handling, ONLY: cp_logger_get_default_io_unit
22 : USE cp_parser_methods, ONLY: read_float_object
23 : USE dft_plus_u, ONLY: lowdin_kp_prepare
24 : USE input_section_types, ONLY: section_vals_get,&
25 : section_vals_get_subs_vals,&
26 : section_vals_type,&
27 : section_vals_val_get
28 : USE kinds, ONLY: default_string_length,&
29 : dp,&
30 : max_line_length
31 : USE kpoint_methods, ONLY: kpoint_env_initialize,&
32 : kpoint_init_cell_index,&
33 : kpoint_initialize_mo_set,&
34 : kpoint_initialize_mos
35 : USE kpoint_types, ONLY: get_kpoint_info,&
36 : kpoint_create,&
37 : kpoint_env_type,&
38 : kpoint_release,&
39 : kpoint_sym_create,&
40 : kpoint_type
41 : USE machine, ONLY: m_walltime
42 : USE mathconstants, ONLY: twopi
43 : USE message_passing, ONLY: mp_para_env_type
44 : USE physcon, ONLY: angstrom,&
45 : evolt
46 : USE qs_environment_types, ONLY: get_qs_env,&
47 : qs_env_release,&
48 : qs_environment_type
49 : USE qs_gamma2kp, ONLY: create_kp_from_gamma
50 : USE qs_mo_types, ONLY: get_mo_set
51 : USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
52 : USE qs_scf_diagonalization, ONLY: diag_kp_smat,&
53 : do_general_diag_kp
54 : USE qs_scf_types, ONLY: qs_scf_env_type
55 : USE scf_control_types, ONLY: scf_control_type
56 : USE string_utilities, ONLY: uppercase
57 : #include "./base/base_uses.f90"
58 :
59 : IMPLICIT NONE
60 :
61 : PRIVATE
62 :
63 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_band_structure'
64 :
65 : PUBLIC :: calculate_band_structure, calculate_kp_orbitals, calculate_kpoints_for_bs
66 :
67 : ! **************************************************************************************************
68 :
69 : CONTAINS
70 :
71 : ! **************************************************************************************************
72 : !> \brief Main routine for band structure calculation
73 : !> \param qs_env ...
74 : !> \author JGH
75 : ! **************************************************************************************************
76 55830 : SUBROUTINE calculate_band_structure(qs_env)
77 : TYPE(qs_environment_type), POINTER :: qs_env
78 :
79 : LOGICAL :: do_kpoints, explicit
80 : TYPE(section_vals_type), POINTER :: bs_input
81 :
82 27915 : bs_input => section_vals_get_subs_vals(qs_env%input, "DFT%PRINT%BAND_STRUCTURE")
83 27915 : CALL section_vals_get(bs_input, explicit=explicit)
84 27915 : IF (explicit) THEN
85 14 : CALL get_qs_env(qs_env, do_kpoints=do_kpoints)
86 14 : IF (do_kpoints) THEN
87 6 : CALL do_calculate_band_structure(qs_env)
88 : ELSE
89 : BLOCK
90 : TYPE(qs_environment_type), POINTER :: qs_env_kp
91 8 : CALL create_kp_from_gamma(qs_env, qs_env_kp)
92 8 : CALL do_calculate_band_structure(qs_env_kp)
93 8 : CALL qs_env_release(qs_env_kp)
94 8 : DEALLOCATE (qs_env_kp)
95 : END BLOCK
96 : END IF
97 : END IF
98 :
99 27915 : END SUBROUTINE calculate_band_structure
100 :
101 : ! **************************************************************************************************
102 : !> \brief band structure calculation
103 : !> \param qs_env ...
104 : !> \author JGH
105 : ! **************************************************************************************************
106 28 : SUBROUTINE do_calculate_band_structure(qs_env)
107 : TYPE(qs_environment_type), POINTER :: qs_env
108 :
109 : CHARACTER(LEN=default_string_length) :: filename, ustr
110 : CHARACTER(LEN=default_string_length), &
111 14 : DIMENSION(:), POINTER :: spname, strptr
112 : CHARACTER(LEN=max_line_length) :: error_message
113 : INTEGER :: bs_data_unit, i, i_rep, ik, ikk, ikpgr, &
114 : imo, ip, ispin, n_ptr, n_rep, nadd, &
115 : nkp, nmo, npline, npoints, nspins, &
116 : unit_nr
117 : INTEGER, DIMENSION(2) :: kp_range
118 : LOGICAL :: explicit, io_default, my_kpgrp
119 : REAL(KIND=dp) :: t1, t2
120 : REAL(KIND=dp), DIMENSION(3) :: kpptr
121 : REAL(KIND=dp), DIMENSION(3, 3) :: cart_hmat
122 14 : REAL(KIND=dp), DIMENSION(:), POINTER :: eigenvalues, eigval, occnum, &
123 14 : occupation_numbers, wkp
124 14 : REAL(kind=dp), DIMENSION(:, :), POINTER :: kpgeneral, kspecial, xkp
125 : TYPE(cell_type), POINTER :: cell
126 : TYPE(dft_control_type), POINTER :: dft_control
127 : TYPE(kpoint_env_type), POINTER :: kp
128 : TYPE(kpoint_type), POINTER :: kpoint
129 : TYPE(mp_para_env_type), POINTER :: para_env
130 : TYPE(section_vals_type), POINTER :: bs_input, kpset
131 :
132 28 : bs_input => section_vals_get_subs_vals(qs_env%input, "DFT%PRINT%BAND_STRUCTURE")
133 14 : CALL section_vals_get(bs_input, explicit=explicit)
134 14 : IF (explicit) THEN
135 14 : CALL section_vals_val_get(bs_input, "FILE_NAME", c_val=filename)
136 14 : CALL section_vals_val_get(bs_input, "ADDED_MOS", i_val=nadd)
137 14 : unit_nr = cp_logger_get_default_io_unit()
138 14 : CALL get_qs_env(qs_env=qs_env, para_env=para_env)
139 14 : CALL get_qs_env(qs_env, cell=cell)
140 182 : cart_hmat(:, :) = cell%hmat(:, :)
141 14 : IF (cell%input_cell_canonicalized) cart_hmat(:, :) = cell%input_hmat(:, :)
142 14 : kpset => section_vals_get_subs_vals(bs_input, "KPOINT_SET")
143 14 : CALL section_vals_get(kpset, n_repetition=n_rep)
144 14 : IF (unit_nr > 0) THEN
145 7 : WRITE (unit_nr, FMT="(/,T2,A)") "KPOINTS| Band Structure Calculation"
146 7 : WRITE (unit_nr, FMT="(T2,A,T71,I10)") "KPOINTS| Number of k-point sets", n_rep
147 7 : IF (nadd /= 0) THEN
148 4 : WRITE (unit_nr, FMT="(T2,A,T71,I10)") "KPOINTS| Number of added MOs/bands", nadd
149 : END IF
150 : END IF
151 14 : IF (filename == "") THEN
152 : ! use standard output file
153 8 : bs_data_unit = unit_nr
154 8 : io_default = .TRUE.
155 : ELSE
156 6 : io_default = .FALSE.
157 6 : IF (para_env%is_source()) THEN
158 : CALL open_file(filename, unit_number=bs_data_unit, file_status="UNKNOWN", file_action="WRITE", &
159 3 : file_position="APPEND")
160 : ELSE
161 3 : bs_data_unit = -1
162 : END IF
163 : END IF
164 30 : DO i_rep = 1, n_rep
165 16 : t1 = m_walltime()
166 16 : CALL section_vals_val_get(kpset, "NPOINTS", i_rep_section=i_rep, i_val=npline)
167 16 : CALL section_vals_val_get(kpset, "UNITS", i_rep_section=i_rep, c_val=ustr)
168 16 : CALL uppercase(ustr)
169 16 : CALL section_vals_val_get(kpset, "SPECIAL_POINT", i_rep_section=i_rep, n_rep_val=n_ptr)
170 48 : ALLOCATE (kspecial(3, n_ptr))
171 48 : ALLOCATE (spname(n_ptr))
172 48 : DO ip = 1, n_ptr
173 32 : CALL section_vals_val_get(kpset, "SPECIAL_POINT", i_rep_section=i_rep, i_rep_val=ip, c_vals=strptr)
174 32 : IF (SIZE(strptr(:), 1) == 4) THEN
175 6 : spname(ip) = strptr(1)
176 24 : DO i = 1, 3
177 18 : CALL read_float_object(strptr(i + 1), kpptr(i), error_message)
178 24 : IF (LEN_TRIM(error_message) > 0) CPABORT(TRIM(error_message))
179 : END DO
180 26 : ELSE IF (SIZE(strptr(:), 1) == 3) THEN
181 26 : spname(ip) = "not specified"
182 104 : DO i = 1, 3
183 78 : CALL read_float_object(strptr(i), kpptr(i), error_message)
184 104 : IF (LEN_TRIM(error_message) > 0) CPABORT(TRIM(error_message))
185 : END DO
186 : ELSE
187 0 : CPABORT("Input SPECIAL_POINT invalid")
188 : END IF
189 16 : SELECT CASE (ustr)
190 : CASE ("B_VECTOR")
191 96 : kspecial(1:3, ip) = kpptr(1:3)
192 : CASE ("CART_ANGSTROM")
193 : kspecial(1:3, ip) = (kpptr(1)*cart_hmat(1, 1:3) + &
194 : kpptr(2)*cart_hmat(2, 1:3) + &
195 0 : kpptr(3)*cart_hmat(3, 1:3))/twopi*angstrom
196 : CASE ("CART_BOHR")
197 : kspecial(1:3, ip) = (kpptr(1)*cart_hmat(1, 1:3) + &
198 : kpptr(2)*cart_hmat(2, 1:3) + &
199 32 : kpptr(3)*cart_hmat(3, 1:3))/twopi
200 : CASE DEFAULT
201 32 : CPABORT("Unknown unit <"//TRIM(ustr)//"> specified for k-point definition")
202 : END SELECT
203 : END DO
204 16 : npoints = (n_ptr - 1)*npline + 1
205 16 : CPASSERT(npoints >= 1)
206 :
207 : ! Initialize environment and calculate MOs
208 48 : ALLOCATE (kpgeneral(3, npoints))
209 112 : kpgeneral(1:3, 1) = kspecial(1:3, 1)
210 16 : ikk = 1
211 32 : DO ik = 2, n_ptr
212 118 : DO ip = 1, npline
213 86 : ikk = ikk + 1
214 : kpgeneral(1:3, ikk) = kspecial(1:3, ik - 1) + &
215 : REAL(ip, KIND=dp)/REAL(npline, KIND=dp)* &
216 618 : (kspecial(1:3, ik) - kspecial(1:3, ik - 1))
217 : END DO
218 : END DO
219 16 : NULLIFY (kpoint)
220 16 : CALL calculate_kp_orbitals(qs_env, kpoint, "GENERAL", nadd, kpgeneral=kpgeneral)
221 16 : DEALLOCATE (kpgeneral)
222 :
223 16 : CALL get_qs_env(qs_env, dft_control=dft_control)
224 16 : nspins = dft_control%nspins
225 16 : kp => kpoint%kp_env(1)%kpoint_env
226 16 : CALL get_mo_set(kp%mos(1), nmo=nmo)
227 64 : ALLOCATE (eigval(nmo), occnum(nmo))
228 16 : CALL get_kpoint_info(kpoint, nkp=nkp, kp_range=kp_range, xkp=xkp, wkp=wkp)
229 :
230 16 : IF (unit_nr > 0) THEN
231 : WRITE (UNIT=unit_nr, FMT="(T2,A,I4,T71,I10)") &
232 8 : "KPOINTS| Number of k-points in set ", i_rep, npoints
233 : WRITE (UNIT=unit_nr, FMT="(T2,A)") &
234 8 : "KPOINTS| In units of b-vector [2pi/Bohr]"
235 24 : DO ip = 1, n_ptr
236 : WRITE (UNIT=unit_nr, FMT="(T2,A,I5,1X,A11,3(1X,F12.6))") &
237 72 : "KPOINTS| Special point ", ip, ADJUSTL(TRIM(spname(ip))), kspecial(1:3, ip)
238 : END DO
239 : END IF
240 16 : IF (bs_data_unit > 0 .AND. (bs_data_unit /= unit_nr)) THEN
241 : WRITE (UNIT=bs_data_unit, FMT="(4(A,I0),A)") &
242 4 : "# Set ", i_rep, ": ", n_ptr, " special points, ", npoints, " k-points, ", nmo, " bands"
243 13 : DO ip = 1, n_ptr
244 : WRITE (UNIT=bs_data_unit, FMT="(A,I0,T20,T24,3(1X,F14.8),2X,A)") &
245 40 : "# Special point ", ip, kspecial(1:3, ip), ADJUSTL(TRIM(spname(ip)))
246 : END DO
247 : END IF
248 :
249 118 : DO ik = 1, nkp
250 102 : my_kpgrp = (ik >= kp_range(1) .AND. ik <= kp_range(2))
251 220 : DO ispin = 1, nspins
252 102 : IF (my_kpgrp) THEN
253 52 : ikpgr = ik - kp_range(1) + 1
254 52 : kp => kpoint%kp_env(ikpgr)%kpoint_env
255 52 : CALL get_mo_set(kp%mos(ispin), eigenvalues=eigenvalues, occupation_numbers=occupation_numbers)
256 1980 : eigval(1:nmo) = eigenvalues(1:nmo)
257 1980 : occnum(1:nmo) = occupation_numbers(1:nmo)
258 : ELSE
259 870 : eigval(1:nmo) = 0.0_dp
260 870 : occnum(1:nmo) = 0.0_dp
261 : END IF
262 3670 : CALL kpoint%para_env_inter_kp%sum(eigval)
263 3670 : CALL kpoint%para_env_inter_kp%sum(occnum)
264 204 : IF (bs_data_unit > 0) THEN
265 : WRITE (UNIT=bs_data_unit, FMT="(A,I0,T15,A,I0,A,T24,3(1X,F14.8),3X,F14.8)") &
266 204 : "# Point ", ik, " Spin ", ispin, ":", xkp(1:3, ik), wkp(ik)
267 : WRITE (UNIT=bs_data_unit, FMT="(A)") &
268 51 : "# Band Energy [eV] Occupation"
269 943 : DO imo = 1, nmo
270 : WRITE (UNIT=bs_data_unit, FMT="(T2,I7,2(1X,F14.8))") &
271 943 : imo, eigval(imo)*evolt, occnum(imo)
272 : END DO
273 : END IF
274 : END DO
275 : END DO
276 :
277 16 : DEALLOCATE (kspecial, spname)
278 16 : DEALLOCATE (eigval, occnum)
279 16 : CALL kpoint_release(kpoint)
280 16 : t2 = m_walltime()
281 78 : IF (unit_nr > 0) THEN
282 8 : WRITE (UNIT=unit_nr, FMT="(T2,A,T67,F14.3)") "KPOINTS| Time for k-point line ", t2 - t1
283 : END IF
284 :
285 : END DO
286 :
287 : ! Close output files
288 14 : IF (.NOT. io_default) THEN
289 6 : IF (para_env%is_source()) CALL close_file(bs_data_unit)
290 : END IF
291 :
292 : END IF
293 :
294 14 : END SUBROUTINE do_calculate_band_structure
295 :
296 : ! **************************************************************************************************
297 : !> \brief diagonalize KS matrices at a set of kpoints
298 : !> \param qs_env ...
299 : !> \param kpoint ...
300 : !> \param scheme ...
301 : !> \param nadd ...
302 : !> \param mp_grid ...
303 : !> \param kpgeneral ...
304 : !> \param group_size_ext ...
305 : !> \param kp_shift ...
306 : !> \param gamma_centered ...
307 : !> \author JGH
308 : ! **************************************************************************************************
309 16 : SUBROUTINE calculate_kp_orbitals(qs_env, kpoint, scheme, nadd, mp_grid, kpgeneral, group_size_ext, &
310 : kp_shift, gamma_centered)
311 : TYPE(qs_environment_type), POINTER :: qs_env
312 : TYPE(kpoint_type), POINTER :: kpoint
313 : CHARACTER(LEN=*), INTENT(IN) :: scheme
314 : INTEGER, INTENT(IN) :: nadd
315 : INTEGER, DIMENSION(3), INTENT(IN), OPTIONAL :: mp_grid
316 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
317 : OPTIONAL :: kpgeneral
318 : INTEGER, INTENT(IN), OPTIONAL :: group_size_ext
319 : REAL(KIND=dp), DIMENSION(3), INTENT(IN), OPTIONAL :: kp_shift
320 : LOGICAL, INTENT(IN), OPTIONAL :: gamma_centered
321 :
322 : INTEGER :: ik
323 : LOGICAL :: diis_step
324 16 : REAL(dp), POINTER :: potential(:, :)
325 : TYPE(cp_blacs_env_type), POINTER :: blacs_env
326 16 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks, matrix_s
327 : TYPE(dft_control_type), POINTER :: dft_control
328 : TYPE(kpoint_type), POINTER :: scf_kpoints
329 : TYPE(mp_para_env_type), POINTER :: para_env
330 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
331 16 : POINTER :: sab_nl
332 : TYPE(qs_scf_env_type), POINTER :: scf_env
333 : TYPE(scf_control_type), POINTER :: scf_control
334 :
335 : CALL calculate_kpoints_for_bs(kpoint, scheme, group_size_ext, mp_grid, kpgeneral, &
336 16 : kp_shift, gamma_centered)
337 :
338 16 : CALL get_qs_env(qs_env=qs_env, para_env=para_env, blacs_env=blacs_env)
339 16 : CALL kpoint_env_initialize(kpoint, para_env, blacs_env)
340 :
341 16 : CALL kpoint_initialize_mos(kpoint, qs_env%mos, nadd)
342 16 : CALL kpoint_initialize_mo_set(kpoint)
343 :
344 16 : CALL get_qs_env(qs_env, sab_kp=sab_nl, dft_control=dft_control)
345 16 : CALL kpoint_init_cell_index(kpoint, sab_nl, para_env, dft_control%nimages)
346 :
347 : CALL get_qs_env(qs_env, matrix_ks_kp=matrix_ks, matrix_s_kp=matrix_s, &
348 16 : scf_env=scf_env, scf_control=scf_control, kpoints=scf_kpoints)
349 16 : NULLIFY (potential)
350 16 : IF (ASSOCIATED(scf_kpoints)) THEN
351 16 : IF (ALLOCATED(scf_kpoints%lowdin_v)) THEN
352 0 : IF (ANY(scf_kpoints%lowdin_v /= 0.0_dp)) potential => scf_kpoints%lowdin_v
353 : END IF
354 : END IF
355 16 : IF (ASSOCIATED(potential)) THEN
356 0 : CALL diag_kp_smat(matrix_s, kpoint, scf_env%scf_work1)
357 0 : DO ik = 1, SIZE(kpoint%kp_env)
358 0 : CALL lowdin_kp_prepare(kpoint%kp_env(ik)%kpoint_env, scf_kpoints%lowdin_orbitals, .FALSE.)
359 : END DO
360 : END IF
361 : CALL do_general_diag_kp(matrix_ks, matrix_s, kpoint, scf_env, scf_control, .FALSE., diis_step, &
362 16 : potential=potential)
363 :
364 16 : END SUBROUTINE calculate_kp_orbitals
365 :
366 : ! **************************************************************************************************
367 : !> \brief ...
368 : !> \param kpoint ...
369 : !> \param scheme ...
370 : !> \param group_size_ext ...
371 : !> \param mp_grid ...
372 : !> \param kpgeneral ...
373 : !> \param kp_shift ...
374 : !> \param gamma_centered ...
375 : ! **************************************************************************************************
376 48 : SUBROUTINE calculate_kpoints_for_bs(kpoint, scheme, group_size_ext, mp_grid, kpgeneral, &
377 : kp_shift, gamma_centered)
378 :
379 : TYPE(kpoint_type), POINTER :: kpoint
380 : CHARACTER(LEN=*), INTENT(IN) :: scheme
381 : INTEGER, INTENT(IN), OPTIONAL :: group_size_ext
382 : INTEGER, DIMENSION(3), INTENT(IN), OPTIONAL :: mp_grid
383 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
384 : OPTIONAL :: kpgeneral
385 : REAL(KIND=dp), DIMENSION(3), INTENT(IN), OPTIONAL :: kp_shift
386 : LOGICAL, INTENT(IN), OPTIONAL :: gamma_centered
387 :
388 : INTEGER :: i, idim, ix, iy, iz, npoints
389 : INTEGER, DIMENSION(3) :: ik
390 : LOGICAL :: gamma_mesh
391 : REAL(KIND=dp), DIMENSION(3) :: kpt_latt, shift
392 :
393 64 : CPASSERT(.NOT. ASSOCIATED(kpoint))
394 :
395 64 : CALL kpoint_create(kpoint)
396 :
397 64 : IF (PRESENT(kp_shift)) THEN
398 0 : shift = kp_shift
399 : ELSE
400 64 : shift = 0.0_dp
401 : END IF
402 64 : IF (PRESENT(gamma_centered)) THEN
403 0 : gamma_mesh = gamma_centered
404 : ELSE
405 : gamma_mesh = .FALSE.
406 : END IF
407 :
408 64 : kpoint%kp_scheme = scheme
409 64 : kpoint%symmetry = .FALSE.
410 64 : kpoint%verbose = .FALSE.
411 64 : kpoint%full_grid = .FALSE.
412 64 : kpoint%use_real_wfn = .FALSE.
413 64 : kpoint%gamma_centered = gamma_mesh
414 256 : kpoint%kp_shift = shift
415 64 : kpoint%eps_geo = 1.e-6_dp
416 64 : IF (PRESENT(group_size_ext)) THEN
417 48 : kpoint%parallel_group_size = group_size_ext
418 : ELSE
419 16 : kpoint%parallel_group_size = -1
420 : END IF
421 0 : SELECT CASE (scheme)
422 : CASE ("GAMMA")
423 0 : kpoint%nkp = 1
424 0 : ALLOCATE (kpoint%xkp(3, 1), kpoint%wkp(1))
425 0 : kpoint%xkp(1:3, 1) = 0.0_dp
426 0 : kpoint%wkp(1) = 1.0_dp
427 0 : kpoint%symmetry = .TRUE.
428 0 : ALLOCATE (kpoint%kp_sym(1))
429 0 : NULLIFY (kpoint%kp_sym(1)%kpoint_sym)
430 0 : CALL kpoint_sym_create(kpoint%kp_sym(1)%kpoint_sym)
431 : CASE ("MONKHORST-PACK", "MACDONALD")
432 16 : CPASSERT(PRESENT(mp_grid))
433 16 : npoints = mp_grid(1)*mp_grid(2)*mp_grid(3)
434 64 : kpoint%nkp_grid(1:3) = mp_grid(1:3)
435 16 : kpoint%full_grid = .TRUE.
436 16 : kpoint%nkp = npoints
437 80 : ALLOCATE (kpoint%xkp(3, npoints), kpoint%wkp(npoints))
438 32 : kpoint%wkp(:) = 1._dp/REAL(npoints, KIND=dp)
439 : i = 0
440 32 : DO ix = 1, mp_grid(1)
441 48 : DO iy = 1, mp_grid(2)
442 48 : DO iz = 1, mp_grid(3)
443 16 : i = i + 1
444 64 : ik = [ix, iy, iz]
445 64 : DO idim = 1, 3
446 64 : IF (gamma_mesh .AND. MOD(mp_grid(idim), 2) == 0) THEN
447 : kpt_latt(idim) = REAL(2*ik(idim) - mp_grid(idim), KIND=dp)/ &
448 0 : (2._dp*REAL(mp_grid(idim), KIND=dp))
449 : ELSE
450 : kpt_latt(idim) = REAL(2*ik(idim) - mp_grid(idim) - 1, KIND=dp)/ &
451 48 : (2._dp*REAL(mp_grid(idim), KIND=dp))
452 : END IF
453 : END DO
454 80 : kpoint%xkp(1:3, i) = kpt_latt(1:3) + shift(1:3)
455 : END DO
456 : END DO
457 : END DO
458 : ! default: no symmetry settings
459 64 : ALLOCATE (kpoint%kp_sym(kpoint%nkp))
460 32 : DO i = 1, kpoint%nkp
461 16 : NULLIFY (kpoint%kp_sym(i)%kpoint_sym)
462 32 : CALL kpoint_sym_create(kpoint%kp_sym(i)%kpoint_sym)
463 : END DO
464 : CASE ("GENERAL")
465 48 : CPASSERT(PRESENT(kpgeneral))
466 48 : npoints = SIZE(kpgeneral, 2)
467 48 : kpoint%nkp = npoints
468 240 : ALLOCATE (kpoint%xkp(3, npoints), kpoint%wkp(npoints))
469 390 : kpoint%wkp(:) = 1._dp/REAL(npoints, KIND=dp)
470 1416 : kpoint%xkp(1:3, 1:npoints) = kpgeneral(1:3, 1:npoints)
471 : ! default: no symmetry settings
472 486 : ALLOCATE (kpoint%kp_sym(kpoint%nkp))
473 390 : DO i = 1, kpoint%nkp
474 342 : NULLIFY (kpoint%kp_sym(i)%kpoint_sym)
475 390 : CALL kpoint_sym_create(kpoint%kp_sym(i)%kpoint_sym)
476 : END DO
477 : CASE DEFAULT
478 64 : CPABORT("Unknown kpoint scheme requested")
479 : END SELECT
480 :
481 64 : END SUBROUTINE calculate_kpoints_for_bs
482 :
483 : END MODULE qs_band_structure
|