Octopus
kdotp.F90
Go to the documentation of this file.
1!!! Copyright (C) 2008-2010 David Strubbe
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
21module kdotp_oct_m
22 use debug_oct_m
23 use global_oct_m
24 use grid_oct_m
25 use output_oct_m
27 use io_oct_m
28 use, intrinsic :: iso_fortran_env
34 use mesh_oct_m
37 use mpi_oct_m
40 use parser_oct_m
46 use smear_oct_m
53 use unit_oct_m
55 use utils_oct_m
56 use v_ks_oct_m
57
58 implicit none
59
60 private
61
62 public :: &
65
66 type kdotp_t
67 private
68 class(perturbation_t), pointer :: pert => null()
69 class(perturbation_t), pointer :: pert2 => null()
70
71 real(real64), allocatable :: eff_mass_inv(:,:,:,:)
73 real(real64), allocatable :: velocity(:,:,:)
74
75 type(lr_t), allocatable :: lr(:,:)
78
79 type(lr_t), allocatable :: lr2(:,:,:)
81
82 logical :: converged
83 integer :: occ_solution_method
84 real(real64) :: degen_thres
85 real(real64) :: eta
86 end type kdotp_t
87
88contains
89
90 ! ---------------------------------------------------------
91 subroutine kdotp_lr_run(system, from_scratch)
92 class(*), intent(inout) :: system
93 logical, intent(in) :: from_scratch
94
95 push_sub(kdotp_lr_run)
96
97 select type (system)
98 class is (multisystem_basic_t)
99 message(1) = "CalculationMode = kdotp not implemented for multi-system calculations"
100 call messages_fatal(1, namespace=system%namespace)
101 type is (electrons_t)
102 call kdotp_lr_run_legacy(system, from_scratch)
103 end select
104
105 pop_sub(kdotp_lr_run)
106 end subroutine kdotp_lr_run
107
108 ! ---------------------------------------------------------
109 subroutine kdotp_lr_run_legacy(sys, fromScratch)
110 type(electrons_t), intent(inout) :: sys
111 logical, intent(in) :: fromScratch
112
113 type(kdotp_t) :: kdotp_vars
114 type(sternheimer_t) :: sh, sh2
115 logical :: calc_eff_mass, calc_2nd_order, complex_response
116
117 integer :: idir, idir2, ierr, pdim, ispin
118 character(len=100) :: str_tmp
119 real(real64) :: errornorm
120 type(restart_t) :: restart_load, restart_dump
121
122 class(perturbation_t), pointer :: pert2 ! for the second direction in second-order kdotp
123
124 push_sub(kdotp_lr_run_legacy)
125
126 call messages_experimental("k.p perturbation and calculation of effective masses", namespace=sys%namespace)
127
128 if (sys%hm%pcm%run_pcm) then
129 call messages_not_implemented("PCM for CalculationMode /= gs or td", namespace=sys%namespace)
130 end if
131
132 !TODO: This test belongs to the pert.F90 file, in the case of the velocity operator not been defined
133 ! from the Hamiltonian
134 ! In this case, there are other terms missing (MGGA, DFT+U for instance).
135 if (sys%hm%theory_level == hartree_fock) then
136 call messages_not_implemented('Commutator of Fock operator', namespace=sys%namespace)
137 end if
138 if (sys%hm%theory_level == generalized_kohn_sham_dft) then
139 call messages_not_implemented('k.p with generalized Kohn-Sham DFT', namespace=sys%namespace)
140 end if
141
142
143 if (sys%kpoints%use_symmetries) then
144 call messages_experimental("KPoints symmetries with CalculationMode = kdotp", namespace=sys%namespace)
145 end if
146
147 pdim = sys%space%periodic_dim
148
149 if (.not. sys%space%is_periodic()) then
150 message(1) = "k.p perturbation cannot be used for a finite system."
151 call messages_fatal(1, namespace=sys%namespace)
152 end if
153
154 kdotp_vars%pert => perturbation_kdotp_t(sys%namespace, sys%ions)
155 safe_allocate(kdotp_vars%lr(1, 1:pdim))
156
157 call parse_input()
158
159 if (calc_2nd_order) then
160 kdotp_vars%pert2 => perturbation_none_t(sys%namespace)
161 pert2 => perturbation_kdotp_t(sys%namespace, sys%ions)
162 call kdotp_vars%pert2%setup_dir(1) ! direction is irrelevant
163 safe_allocate(kdotp_vars%lr2(1, 1:pdim, 1:pdim))
164 end if
165
166 !Read ground-state wavefunctions
167 complex_response = (abs(kdotp_vars%eta) > m_epsilon) .or. states_are_complex(sys%st)
168 call restart_init(restart_load, sys%namespace, restart_gs, restart_type_load, sys%mc, ierr, mesh=sys%gr, exact=.true.)
169 if (ierr == 0) then
170 call states_elec_look_and_load(restart_load, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
171 is_complex = complex_response)
172 call restart_end(restart_load)
173 else
174 message(1) = "A previous gs calculation is required."
175 call messages_fatal(1, namespace=sys%namespace)
176 end if
178 ! Use of ForceComplex will make this true after states_elec_look_and_load even if it was not before.
179 ! Otherwise, this line is a tautology.
180 complex_response = states_are_complex(sys%st)
181
182 ! Start restart. Note: we are going to use the same directory to read and write.
183 ! Therefore, restart_dump must be initialized first to make sure the directory
184 ! exists when we initialize restart_load.
185 call restart_init(restart_dump, sys%namespace, restart_kdotp, restart_type_dump, sys%mc, ierr, mesh=sys%gr)
186 ! no problem if this fails
187 call restart_init(restart_load, sys%namespace, restart_kdotp, restart_type_load, sys%mc, ierr, mesh=sys%gr)
188
189 ! setup Hamiltonian
190 message(1) = 'Info: Setting up Hamiltonian for linear response.'
191 call messages_info(1, namespace=sys%namespace)
192 call v_ks_h_setup(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, sys%hm)
193
194 if (states_are_real(sys%st)) then
195 message(1) = 'Info: Using real wavefunctions.'
196 else
197 message(1) = 'Info: Using complex wavefunctions.'
198 end if
199 call messages_info(1, namespace=sys%namespace)
200
201 ! Band velocities
202 message(1) = 'Calculating band velocities.'
203 call messages_info(1, namespace=sys%namespace)
204
205 ! Compute band velocities
206 safe_allocate(kdotp_vars%velocity(1:pdim, 1:sys%st%nst, 1:sys%st%nik))
207 call calc_band_velocity(sys%namespace, sys%space, sys%gr, sys%st, sys%hm, kdotp_vars%pert, &
208 kdotp_vars%velocity(:,:,:))
209
210 ! Output of the band velocities
211 if (mpi_grp_is_root(mpi_world)) then
212 call io_mkdir(kdotp_dir, sys%namespace) ! data output
213 call kdotp_write_band_velocity(sys%st, pdim, kdotp_vars%velocity(:,:,:), sys%namespace)
214 end if
215 safe_deallocate_a(kdotp_vars%velocity)
216
217
218 call sternheimer_obsolete_variables(sys%namespace, 'KdotP_', 'KdotP')
219 call sternheimer_init(sh, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc, sys%mc, complex_response, &
220 set_ham_var = 0, set_occ_response = (kdotp_vars%occ_solution_method == 0), &
221 set_last_occ_response = (kdotp_vars%occ_solution_method == 0), occ_response_by_sternheimer = .true.)
222 ! ham_var_set = 0 results in HamiltonianVariation = V_ext_only
223 if (calc_2nd_order) then
224 call sternheimer_init(sh2, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc, sys%mc, complex_response, &
225 set_ham_var = 0, set_occ_response = .false., set_last_occ_response = .false.)
226 end if
227
228 do idir = 1, pdim
229 call lr_init(kdotp_vars%lr(1, idir))
230 call lr_allocate(kdotp_vars%lr(1, idir), sys%st, sys%gr)
231
232 if (calc_2nd_order) then
233 do idir2 = idir, pdim
234 call lr_init(kdotp_vars%lr2(1, idir, idir2))
235 call lr_allocate(kdotp_vars%lr2(1, idir, idir2), sys%st, sys%gr)
236 end do
237 end if
238
239 ! load wavefunctions
240 if (.not. fromscratch) then
241 str_tmp = kdotp_wfs_tag(idir)
242 call restart_open_dir(restart_load, wfs_tag_sigma(sys%namespace, str_tmp, 1), ierr)
243 if (ierr == 0) call states_elec_load(restart_load, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
244 ierr, lr=kdotp_vars%lr(1, idir))
245 call restart_close_dir(restart_load)
246
247 if (ierr /= 0) then
248 message(1) = "Unable to read response wavefunctions from '"//trim(wfs_tag_sigma(sys%namespace, str_tmp, 1))//"'."
249 call messages_warning(1, namespace=sys%namespace)
250 end if
251
252 if (calc_2nd_order) then
253 do idir2 = idir, pdim
254 str_tmp = kdotp_wfs_tag(idir, idir2)
255 call restart_open_dir(restart_load, wfs_tag_sigma(sys%namespace, str_tmp, 1), ierr)
256 if (ierr == 0) then
257 call states_elec_load(restart_load, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
258 ierr, lr=kdotp_vars%lr2(1, idir, idir2))
259 end if
260 call restart_close_dir(restart_load)
261
262 if (ierr /= 0) then
263 message(1) = "Unable to read response wavefunctions from '"//trim(wfs_tag_sigma(sys%namespace, str_tmp, 1))//"'."
264 call messages_warning(1, namespace=sys%namespace)
265 end if
266 end do
267 end if
268 end if
269 end do
270
271 call info()
272 message(1) = "Info: Calculating k.p linear response of ground-state wavefunctions."
273 call messages_info(1, namespace=sys%namespace)
274 kdotp_vars%converged = .true.
275
276 ! solve the Sternheimer equation
277 do idir = 1, pdim
278 write(message(1), '(3a)') 'Info: Calculating response for the ', index2axis(idir), &
279 '-direction.'
280 call messages_info(1, namespace=sys%namespace)
281 call kdotp_vars%pert%setup_dir(idir)
282
283 if (states_are_real(sys%st)) then
284 call dsternheimer_solve(sh, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%mc, &
285 kdotp_vars%lr(1:1, idir), 1, m_zero, kdotp_vars%pert, restart_dump, "", kdotp_wfs_tag(idir), &
286 have_restart_rho = .false.)
287 if (kdotp_vars%occ_solution_method == 1) then
288 call dkdotp_add_occ(sys%namespace, sys%space, sys%gr, sys%st, sys%hm, kdotp_vars%pert, &
289 kdotp_vars%lr(1, idir), kdotp_vars%degen_thres)
290 end if
291 else
292 call zsternheimer_solve(sh, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%mc, &
293 kdotp_vars%lr(1:1, idir), 1, m_zi * kdotp_vars%eta, kdotp_vars%pert, restart_dump, "", &
294 kdotp_wfs_tag(idir), have_restart_rho = .false.)
295 if (kdotp_vars%occ_solution_method == 1) then
296 call zkdotp_add_occ(sys%namespace, sys%space, sys%gr, sys%st, sys%hm, kdotp_vars%pert, &
297 kdotp_vars%lr(1, idir), kdotp_vars%degen_thres)
298 end if
299 end if
300
301 kdotp_vars%converged = kdotp_vars%converged .and. sternheimer_has_converged(sh)
302
303 errornorm = m_zero
304 if (states_are_real(sys%st)) then
305 call doutput_lr(sys%outp, sys%namespace, sys%space, kdotp_dir, sys%st, sys%gr, kdotp_vars%lr(1, idir), idir, 1, &
306 sys%ions, units_out%force)
307
308 do ispin = 1, sys%st%d%nspin
309 errornorm = hypot(errornorm, dmf_nrm2(sys%gr, kdotp_vars%lr(1, idir)%ddl_rho(:, ispin)))
310 end do
311 else
312 call zoutput_lr(sys%outp, sys%namespace, sys%space, kdotp_dir, sys%st, sys%gr, kdotp_vars%lr(1, idir), idir, 1, &
313 sys%ions, units_out%force)
314
315 do ispin = 1, sys%st%d%nspin
316 errornorm = hypot(errornorm, zmf_nrm2(sys%gr, kdotp_vars%lr(1, idir)%zdl_rho(:, ispin)))
317 end do
318 end if
319
320 write(message(1),'(a,g13.6)') "Norm of relative density variation = ", errornorm / sys%st%qtot
321 call messages_info(1, namespace=sys%namespace)
322
323 if (calc_2nd_order) then
324 ! by equality of mixed partial derivatives, kdotp_vars%lr2(idir, idir2) = kdotp_vars%lr2(idir2, idir)
325 do idir2 = idir, pdim
326 write(message(1), '(3a)') 'Info: Calculating second-order response in the ', index2axis(idir2), &
327 '-direction.'
328 call messages_info(1, namespace=sys%namespace)
329
330 call pert2%setup_dir(idir2)
331
332 if (states_are_real(sys%st)) then
333 call dsternheimer_solve_order2(sh, sh, sh2, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, &
334 sys%mc, kdotp_vars%lr(1:1, idir), kdotp_vars%lr(1:1, idir2), &
335 1, m_zero, m_zero, kdotp_vars%pert, pert2, &
336 kdotp_vars%lr2(1:1, idir, idir2), kdotp_vars%pert2, restart_dump, "", kdotp_wfs_tag(idir, idir2), &
337 have_restart_rho = .false., have_exact_freq = .true.)
338 else
339 call zsternheimer_solve_order2(sh, sh, sh2, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, &
340 sys%mc, kdotp_vars%lr(1:1, idir), kdotp_vars%lr(1:1, idir2), &
341 1, m_zi * kdotp_vars%eta, m_zi * kdotp_vars%eta, kdotp_vars%pert, pert2, &
342 kdotp_vars%lr2(1:1, idir, idir2), kdotp_vars%pert2, restart_dump, "", kdotp_wfs_tag(idir, idir2), &
343 have_restart_rho = .false., have_exact_freq = .true.)
344 end if
345
346 end do
347 message(1) = ""
348 call messages_info(1, namespace=sys%namespace)
349 end if
350 end do ! idir
351
352 ! calculate effective masses
353 if (calc_eff_mass) then
354 message(1) = "Info: Calculating effective masses."
355 call messages_info(1, namespace=sys%namespace)
356
357 safe_allocate(kdotp_vars%eff_mass_inv(1:pdim, 1:pdim, 1:sys%st%nst, 1:sys%st%nik))
358 kdotp_vars%eff_mass_inv(:,:,:,:) = m_zero
359
360
361 if (states_are_real(sys%st)) then
362 call dcalc_eff_mass_inv(sys%namespace, sys%space, sys%gr, sys%st, sys%hm, kdotp_vars%lr, &
363 kdotp_vars%pert, kdotp_vars%eff_mass_inv, kdotp_vars%degen_thres)
364 else
365 call zcalc_eff_mass_inv(sys%namespace, sys%space, sys%gr, sys%st, sys%hm, kdotp_vars%lr, &
366 kdotp_vars%pert, kdotp_vars%eff_mass_inv, kdotp_vars%degen_thres)
367 end if
368
369 call kdotp_write_degeneracies(sys%st, kdotp_vars%degen_thres, sys%namespace)
370 call kdotp_write_eff_mass(sys%st, sys%kpoints, kdotp_vars, sys%namespace, sys%space%periodic_dim)
371
372 safe_deallocate_a(kdotp_vars%eff_mass_inv)
373 end if
374
375 ! clean up some things
376 do idir = 1, pdim
377 call lr_dealloc(kdotp_vars%lr(1, idir))
378
379 if (calc_2nd_order) then
380 do idir2 = idir, pdim
381 call lr_dealloc(kdotp_vars%lr2(1, idir, idir2))
382 end do
383 end if
384 end do
385
386 call restart_end(restart_load)
387 call restart_end(restart_dump)
388 call sternheimer_end(sh)
389 deallocate(kdotp_vars%pert)
390 safe_deallocate_a(kdotp_vars%lr)
391
392 if (calc_2nd_order) then
393 call sternheimer_end(sh2)
394 safe_deallocate_p(pert2)
395 deallocate(kdotp_vars%pert2)
396 safe_deallocate_a(kdotp_vars%lr2)
397 end if
398
399 call states_elec_deallocate_wfns(sys%st)
400
401 pop_sub(kdotp_lr_run_legacy)
402
403 contains
404
405 ! ---------------------------------------------------------
406
407 subroutine parse_input()
408
410
411 !%Variable KdotPOccupiedSolutionMethod
412 !%Type integer
413 !%Default sternheimer_eqn
414 !%Section Linear Response::KdotP
415 !%Description
416 !% Method of calculating the contribution of the projection of the
417 !% linear-response wavefunctions in the occupied subspace.
418 !%Option sternheimer_eqn 0
419 !% The Sternheimer equation is solved including the occupied subspace,
420 !% to get the full linear-response wavefunctions.
421 !%Option sum_over_states 1
422 !% The Sternheimer equation is solved only in the unoccupied subspace,
423 !% and a sum-over-states perturbation-theory expression is used to
424 !% evaluate the contributions in the occupied subspace.
425 !%End
426
427 call messages_obsolete_variable(sys%namespace, 'KdotP_OccupiedSolutionMethod', 'KdotPOccupiedSolutionMethod')
428
429 call parse_variable(sys%namespace, 'KdotPOccupiedSolutionMethod', 0, kdotp_vars%occ_solution_method)
430 if (kdotp_vars%occ_solution_method == 1 .and. .not. smear_is_semiconducting(sys%st%smear)) then
431 call messages_not_implemented('KdotPOccupiedSolutionMethod = sum_over_states for non-semiconducting smearing', &
432 namespace=sys%namespace)
433 end if
434
435 !%Variable DegeneracyThreshold
436 !%Type float
437 !%Default 1e-5
438 !%Section States
439 !%Description
440 !% States with energy <math>E_i</math> and <math>E_j</math> will be considered degenerate
441 !% if <math> \left| E_i - E_j \right| < </math><tt>DegeneracyThreshold</tt>.
442 !%End
443 call parse_variable(sys%namespace, 'DegeneracyThreshold', units_from_atomic(units_inp%energy, 1e-5_real64), &
444 kdotp_vars%degen_thres)
445 kdotp_vars%degen_thres = units_to_atomic(units_inp%energy, kdotp_vars%degen_thres)
446
447 !%Variable KdotPEta
448 !%Type float
449 !%Default 0.0
450 !%Section Linear Response::KdotP
451 !%Description
452 !% Imaginary frequency added to Sternheimer equation which may improve convergence.
453 !% Not recommended.
454 !%End
455 call messages_obsolete_variable(sys%namespace, 'KdotP_Eta', 'KdotPEta')
456 call parse_variable(sys%namespace, 'KdotPEta', m_zero, kdotp_vars%eta)
457 kdotp_vars%eta = units_to_atomic(units_inp%energy, kdotp_vars%eta)
458
459 !%Variable KdotPCalculateEffectiveMasses
460 !%Type logical
461 !%Default true
462 !%Section Linear Response::KdotP
463 !%Description
464 !% If true, uses <tt>kdotp</tt> perturbations of ground-state wavefunctions
465 !% to calculate effective masses. It is not correct for degenerate states.
466 !%End
467 call messages_obsolete_variable(sys%namespace, 'KdotP_CalculateEffectiveMasses', 'KdotPCalculateEffectiveMasses')
468 call parse_variable(sys%namespace, 'KdotPCalculateEffectiveMasses', .true., calc_eff_mass)
469
470 !%Variable KdotPCalcSecondOrder
471 !%Type logical
472 !%Default false
473 !%Section Linear Response::KdotP
474 !%Description
475 !% If true, calculates second-order response of wavefunctions as well as first-order response.
476 !% Note that the second derivative of the Hamiltonian is NOT included in this calculation.
477 !% This is needed for a subsequent run in <tt>CalculationMode = em_resp</tt> with <tt>EMHyperpol</tt>.
478 !%End
479 call parse_variable(sys%namespace, 'KdotPCalcSecondOrder', .false., calc_2nd_order)
480
482
483 end subroutine parse_input
484
485 ! ---------------------------------------------------------
486 subroutine info()
487
488 push_sub(kdotp_lr_run_legacy.info)
489
490 call kdotp_vars%pert%info()
491
492 call messages_print_with_emphasis(msg='k.p perturbation theory', namespace=sys%namespace)
493
494 if (kdotp_vars%occ_solution_method == 0) then
495 message(1) = 'Occupied solution method: Sternheimer equation.'
496 else
497 message(1) = 'Occupied solution method: sum over states.'
498 end if
499
500 call messages_info(1, namespace=sys%namespace)
501
502 call messages_print_with_emphasis(namespace=sys%namespace)
503
505
506 end subroutine info
507
508 end subroutine kdotp_lr_run_legacy
509
510 ! ---------------------------------------------------------
511 subroutine kdotp_write_band_velocity(st, periodic_dim, velocity, namespace)
512 type(states_elec_t), intent(inout) :: st
513 integer, intent(in) :: periodic_dim
514 real(real64), intent(in) :: velocity(:,:,:)
515 type(namespace_t), intent(inout) :: namespace
516
517 character(len=80) :: filename, tmp
518 integer :: iunit, ik, ist, ik2, ispin, idir
519
520 if (.not. mpi_grp_is_root(mpi_world)) return ! only first node outputs
521
523
524 write(filename, '(a)') kdotp_dir//'velocity'
525 iunit = io_open(trim(filename), namespace, action='write')
526 write(iunit,'(a)') '# Band velocities'
527
528 do ik = 1, st%nik
529 ispin = st%d%get_spin_index(ik)
530 ik2 = st%d%get_kpoint_index(ik)
531 tmp = int2str(ik2)
532
533 write(iunit,'(a,i1,a,a)') '# spin = ', ispin, ', k-point = ', trim(tmp)
534
535 write(iunit,'(a)',advance='no') '# state energy '
536 do idir = 1, periodic_dim
537 write(iunit,'(3a)',advance='no') 'vg(', trim(index2axis(idir)), ') '
538 end do
539 write(iunit,'(a)')
540
541 write(iunit,'(3a)',advance='no') '# [', trim(units_abbrev(units_out%energy)), '] '
542 do idir = 1, periodic_dim
543 write(iunit,'(3a)',advance='no') '[', trim(units_abbrev(units_out%velocity)), '] '
544 end do
545 write(iunit,'(a)')
546
547 do ist = 1, st%nst
548 write(iunit,'(i5,f12.5,3f12.5)') ist, units_from_atomic(units_out%energy, st%eigenval(ist, ik)), &
549 velocity(1:periodic_dim, ist, ik)
550 end do
551 end do
552
553 call io_close(iunit)
555 end subroutine kdotp_write_band_velocity
556
557 ! ---------------------------------------------------------
558 subroutine kdotp_write_eff_mass(st, kpoints, kdotp_vars, namespace, periodic_dim)
559 type(states_elec_t), intent(inout) :: st
560 type(kpoints_t), intent(in) :: kpoints
561 type(kdotp_t), intent(inout) :: kdotp_vars
562 type(namespace_t), intent(in) :: namespace
563 integer, intent(in) :: periodic_dim
564
565 character(len=80) :: filename, tmp
566 integer :: iunit, ik, ist, ik2, ispin
567
568 if (.not. mpi_grp_is_root(mpi_world)) return ! only first node outputs
569
570 push_sub(kdotp_write_eff_mass)
571
572 do ik = 1, st%nik
573 ispin = st%d%get_spin_index(ik)
574 ik2 = st%d%get_kpoint_index(ik)
575
576 tmp = int2str(ik2)
577 write(filename, '(3a, i1)') kdotp_dir//'kpoint_', trim(tmp), '_', ispin
578 iunit = io_open(trim(filename), namespace, action='write')
580 write(iunit,'(a, i10)') '# spin index = ', ispin
581 write(iunit,'(a, i10)') '# k-point index = ', ik2
582 write(iunit,'(a, 99f12.8)') '# k-point coordinates = ', kpoints%get_point(ik2)
583 if (.not. kdotp_vars%converged) write(iunit, '(a)') "# WARNING: not converged"
584
585 write(iunit,'(a)')
586 write(iunit,'(a)') '# Inverse effective-mass tensors'
587 do ist = 1, st%nst
588 write(iunit,'(a)')
589 tmp = int2str(ist)
590 write(iunit,'(a, a, a, f12.8, a, a)') 'State #', trim(tmp), ', Energy = ', &
591 units_from_atomic(units_out%energy, st%eigenval(ist, ik)), ' ', units_abbrev(units_out%energy)
592 call output_tensor(kdotp_vars%eff_mass_inv(:, :, ist, ik), periodic_dim, unit_one, iunit=iunit)
593 end do
594
595 write(iunit,'(a)')
596 write(iunit,'(a)') '# Effective-mass tensors'
597 do ist = 1, st%nst
598 write(iunit,'(a)')
599 tmp = int2str(ist)
600 write(iunit,'(a, a, a, f12.8, a, a)') 'State #', trim(tmp), ', Energy = ', &
601 units_from_atomic(units_out%energy, st%eigenval(ist, ik)), ' ', units_abbrev(units_out%energy)
602 call lalg_inverse(periodic_dim, kdotp_vars%eff_mass_inv(:, :, ist, ik), 'dir')
603 call output_tensor(kdotp_vars%eff_mass_inv(:, :, ist, ik), periodic_dim, unit_one, iunit=iunit)
604 end do
605
606 call io_close(iunit)
607 end do
608
609 pop_sub(kdotp_write_eff_mass)
610 end subroutine kdotp_write_eff_mass
611
612 ! ---------------------------------------------------------
613 subroutine kdotp_write_degeneracies(st, threshold, namespace)
614 type(states_elec_t), intent(inout) :: st
615 real(real64), intent(in) :: threshold
616 type(namespace_t), intent(in) :: namespace
617
618 character(len=80) :: tmp
619 integer :: ik, ist, ist2, ik2, ispin
620
621 if (.not. mpi_grp_is_root(mpi_world)) return ! only first node outputs
622
624
625 call messages_print_with_emphasis(msg='Degenerate subspaces', namespace=namespace)
626
627 do ik = 1, st%nik
628 ispin = st%d%get_spin_index(ik)
629 ik2 = st%d%get_kpoint_index(ik)
630
631 tmp = int2str(ik2)
632 write(message(1), '(3a, i1)') 'k-point ', trim(tmp), ', spin ', ispin
633 call messages_info(1, namespace=namespace)
634
635 ist = 1
636 do while (ist <= st%nst)
637 ! test for degeneracies
638 write(message(1),'(a)') '===='
639 tmp = int2str(ist)
640 write(message(2),'(a, a, a, f12.8, a, a)') 'State #', trim(tmp), ', Energy = ', &
641 units_from_atomic(units_out%energy, st%eigenval(ist, ik)), ' ', units_abbrev(units_out%energy)
642 call messages_info(2, namespace=namespace)
643
644 ist2 = ist + 1
645 do while (ist2 <= st%nst .and. &
646 abs(st%eigenval(min(ist2, st%nst), ik) - st%eigenval(ist, ik)) < threshold)
647 tmp = int2str(ist2)
648 write(message(1),'(a, a, a, f12.8, a, a)') 'State #', trim(tmp), ', Energy = ', &
649 units_from_atomic(units_out%energy, st%eigenval(ist2, ik)), ' ', units_abbrev(units_out%energy)
650 call messages_info(1, namespace=namespace)
651 ist2 = ist2 + 1
652 end do
653
654 ist = ist2
655 end do
656
657 write(message(1),'()')
658 call messages_info(1, namespace=namespace)
659 end do
660
661 message(1) = "Velocities and effective masses are not correct within degenerate subspaces."
662 call messages_warning(1, namespace=namespace)
663
665 end subroutine kdotp_write_degeneracies
666
667 ! ---------------------------------------------------------
668 character(len=12) pure function int2str(ii) result(str)
669 integer, intent(in) :: ii
670
671 write(str, '(i11)') ii
672 str = trim(adjustl(str))
673
674 end function int2str
675
676end module kdotp_oct_m
677
678!! Local Variables:
679!! mode: f90
680!! coding: utf-8
681!! End:
subroutine parse_input()
Definition: em_resp.F90:819
double hypot(double __x, double __y) __attribute__((__nothrow__
real(real64), parameter, public m_zero
Definition: global.F90:188
character(len= *), parameter, public kdotp_dir
Definition: global.F90:255
complex(real64), parameter, public m_zi
Definition: global.F90:202
real(real64), parameter, public m_epsilon
Definition: global.F90:204
This module implements the underlying real-space grid.
Definition: grid.F90:117
Definition: io.F90:114
subroutine, public io_close(iunit, grp)
Definition: io.F90:418
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:311
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:352
subroutine, public calc_band_velocity(namespace, space, gr, st, hm, pert, velocity)
Computes the k-point and band-resolved velocity.
Definition: kdotp_calc.F90:174
subroutine, public dkdotp_add_occ(namespace, space, gr, st, hm, pert, kdotp_lr, degen_thres)
add projection onto occupied states, by sum over states
Definition: kdotp_calc.F90:400
subroutine, public zkdotp_add_occ(namespace, space, gr, st, hm, pert, kdotp_lr, degen_thres)
add projection onto occupied states, by sum over states
Definition: kdotp_calc.F90:639
subroutine, public dcalc_eff_mass_inv(namespace, space, gr, st, hm, lr, pert, eff_mass_inv, degen_thres)
Computes the effective mass tensor.
Definition: kdotp_calc.F90:302
character(len=100) function, public kdotp_wfs_tag(dir, dir2)
Definition: kdotp_calc.F90:152
subroutine, public zcalc_eff_mass_inv(namespace, space, gr, st, hm, lr, pert, eff_mass_inv, degen_thres)
Computes the effective mass tensor.
Definition: kdotp_calc.F90:541
subroutine kdotp_write_band_velocity(st, periodic_dim, velocity, namespace)
Definition: kdotp.F90:605
subroutine kdotp_lr_run_legacy(sys, fromScratch)
Definition: kdotp.F90:203
subroutine kdotp_write_eff_mass(st, kpoints, kdotp_vars, namespace, periodic_dim)
Definition: kdotp.F90:652
subroutine kdotp_write_degeneracies(st, threshold, namespace)
Definition: kdotp.F90:707
subroutine, public kdotp_lr_run(system, from_scratch)
Definition: kdotp.F90:185
character(len=12) pure function, public int2str(ii)
Definition: kdotp.F90:762
A module to handle KS potential, without the external potential.
integer, parameter, public hartree_fock
integer, parameter, public generalized_kohn_sham_dft
subroutine, public lr_allocate(lr, st, mesh, allocate_rho)
subroutine, public lr_init(lr)
subroutine, public lr_dealloc(lr)
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:920
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1113
character(len=512), private msg
Definition: messages.F90:165
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:537
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1045
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:414
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1085
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:616
logical function mpi_grp_is_root(grp)
Is the current MPI process of grpcomm, root.
Definition: mpi.F90:430
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:266
This module implements the basic mulsisystem class, a container system for other systems.
this module contains the output system
Definition: output.F90:115
subroutine, public zoutput_lr(outp, namespace, space, dir, st, mesh, lr, idir, isigma, ions, pert_unit)
Definition: output.F90:2609
subroutine, public doutput_lr(outp, namespace, space, dir, st, mesh, lr, idir, isigma, ions, pert_unit)
Definition: output.F90:2878
integer, parameter, public restart_kdotp
Definition: restart.F90:200
integer, parameter, public restart_gs
Definition: restart.F90:200
type(restart_data_t), dimension(restart_n_data_types) info
Definition: restart.F90:256
subroutine, public restart_init(restart, namespace, data_type, type, mc, ierr, mesh, dir, exact)
Initializes a restart object.
Definition: restart.F90:516
integer, parameter, public restart_type_dump
Definition: restart.F90:245
subroutine, public restart_open_dir(restart, dirname, ierr)
Change the restart directory to dirname, where "dirname" is a subdirectory of the base restart direct...
Definition: restart.F90:772
integer, parameter, public restart_type_load
Definition: restart.F90:245
subroutine, public restart_end(restart)
Definition: restart.F90:722
subroutine, public restart_close_dir(restart)
Change back to the base directory. To be called after restart_open_dir.
Definition: restart.F90:806
logical pure function, public smear_is_semiconducting(this)
Definition: smear.F90:833
pure logical function, public states_are_complex(st)
pure logical function, public states_are_real(st)
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public states_elec_deallocate_wfns(st)
Deallocates the KS wavefunctions defined within a states_elec_t structure.
This module handles reading and writing restart information for the states_elec_t.
subroutine, public states_elec_look_and_load(restart, namespace, space, st, mesh, kpoints, is_complex, packed)
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...
subroutine, public dsternheimer_solve(this, namespace, space, gr, kpoints, st, hm, mc, lr, nsigma, omega, perturbation, restart, rho_tag, wfs_tag, idir, have_restart_rho, have_exact_freq)
This routine calculates the first-order variations of the wavefunctions for an applied perturbation.
logical function, public sternheimer_has_converged(this)
character(len=100) function, public wfs_tag_sigma(namespace, base_name, isigma)
subroutine, public dsternheimer_solve_order2(sh1, sh2, sh_2ndorder, namespace, space, gr, kpoints, st, hm, mc, lr1, lr2, nsigma, omega1, omega2, pert1, pert2, lr_2ndorder, pert_2ndorder, restart, rho_tag, wfs_tag, have_restart_rho, have_exact_freq, give_pert1psi2, give_dl_eig1)
subroutine, public zsternheimer_solve_order2(sh1, sh2, sh_2ndorder, namespace, space, gr, kpoints, st, hm, mc, lr1, lr2, nsigma, omega1, omega2, pert1, pert2, lr_2ndorder, pert_2ndorder, restart, rho_tag, wfs_tag, have_restart_rho, have_exact_freq, give_pert1psi2, give_dl_eig1)
subroutine, public sternheimer_init(this, namespace, space, gr, st, hm, xc, mc, wfs_are_cplx, set_ham_var, set_occ_response, set_last_occ_response, occ_response_by_sternheimer)
subroutine, public zsternheimer_solve(this, namespace, space, gr, kpoints, st, hm, mc, lr, nsigma, omega, perturbation, restart, rho_tag, wfs_tag, idir, have_restart_rho, have_exact_freq)
This routine calculates the first-order variations of the wavefunctions for an applied perturbation.
subroutine, public sternheimer_end(this)
subroutine, public sternheimer_obsolete_variables(namespace, old_prefix, new_prefix)
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:132
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:223
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
type(unit_system_t), public units_inp
the units systems for reading and writing
type(unit_t), public unit_one
some special units required for particular quantities
This module is intended to contain simple general-purpose utility functions and procedures.
Definition: utils.F90:118
subroutine, public output_tensor(tensor, ndim, unit, write_average, iunit, namespace)
Definition: utils.F90:242
character pure function, public index2axis(idir)
Definition: utils.F90:202
subroutine, public v_ks_h_setup(namespace, space, gr, ions, ext_partners, st, ks, hm, calc_eigenval, calc_current)
Definition: v_ks.F90:677
Class describing the electron system.
Definition: electrons.F90:218
Container class for lists of system_oct_m::system_t.
The states_elec_t class contains all electronic wave functions.
int true(void)