28  use, 
intrinsic :: iso_fortran_env
 
   67    class(perturbation_t), 
pointer :: pert => null()
 
   68    class(perturbation_t), 
pointer :: pert2 => null()
 
   70    real(real64), 
allocatable :: eff_mass_inv(:,:,:,:)
 
   72    real(real64), 
allocatable :: velocity(:,:,:)
 
   74    type(lr_t), 
allocatable :: lr(:,:)
 
   78    type(lr_t), 
allocatable :: lr2(:,:,:)
 
   82    integer :: occ_solution_method
 
   83    real(real64)   :: degen_thres
 
   91    class(*),        
intent(inout) :: system
 
   92    logical,         
intent(in)    :: from_scratch
 
   98      message(1) = 
"CalculationMode = kdotp not implemented for multi-system calculations" 
  109    type(electrons_t),   
intent(inout) :: sys
 
  110    logical,             
intent(in)    :: fromScratch
 
  112    type(kdotp_t)           :: kdotp_vars
 
  113    type(sternheimer_t)     :: sh, sh2
 
  114    logical                 :: calc_eff_mass, calc_2nd_order, complex_response
 
  116    integer              :: idir, idir2, ierr, pdim, ispin
 
  117    character(len=100)   :: str_tmp
 
  118    real(real64)         :: errornorm
 
  119    type(restart_t)      :: restart_load, restart_dump
 
  121    class(perturbation_t), 
pointer :: pert2  
 
  125    call messages_experimental(
"k.p perturbation and calculation of effective masses", namespace=sys%namespace)
 
  127    if (sys%hm%pcm%run_pcm) 
then 
  142    if (sys%kpoints%use_symmetries) 
then 
  143      call messages_experimental(
"KPoints symmetries with CalculationMode = kdotp", namespace=sys%namespace)
 
  146    pdim = sys%space%periodic_dim
 
  148    if (.not. sys%space%is_periodic()) 
then 
  149      message(1) = 
"k.p perturbation cannot be used for a finite system." 
  154    safe_allocate(kdotp_vars%lr(1, 1:pdim))
 
  158    if (calc_2nd_order) 
then 
  161      call kdotp_vars%pert2%setup_dir(1) 
 
  162      safe_allocate(kdotp_vars%lr2(1, 1:pdim, 1:pdim))
 
  170        is_complex = complex_response)
 
  173      message(1) = 
"A previous gs calculation is required." 
  189    message(1) = 
'Info: Setting up Hamiltonian for linear response.' 
  191    call v_ks_h_setup(sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st, sys%ks, sys%hm)
 
  194      message(1) = 
'Info: Using real wavefunctions.' 
  196      message(1) = 
'Info: Using complex wavefunctions.' 
  205    safe_allocate(kdotp_vars%velocity(1:pdim, 1:sys%st%nst, 1:sys%st%nik))
 
  206    call calc_band_velocity(sys%namespace, sys%space, sys%gr, sys%st, sys%hm, kdotp_vars%pert, &
 
  207      kdotp_vars%velocity(:,:,:))
 
  214    safe_deallocate_a(kdotp_vars%velocity)
 
  218    call sternheimer_init(sh, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc, sys%mc, complex_response, &
 
  219      set_ham_var = 0, set_occ_response = (kdotp_vars%occ_solution_method == 0), &
 
  220      set_last_occ_response = (kdotp_vars%occ_solution_method == 0), occ_response_by_sternheimer = .
true.)
 
  222    if (calc_2nd_order) 
then 
  223      call sternheimer_init(sh2, sys%namespace, sys%space, sys%gr, sys%st, sys%hm, sys%ks%xc, sys%mc, complex_response, &
 
  224        set_ham_var = 0, set_occ_response = .false., set_last_occ_response = .false.)
 
  228      call lr_init(kdotp_vars%lr(1, idir))
 
  229      call lr_allocate(kdotp_vars%lr(1, idir), sys%st, sys%gr)
 
  231      if (calc_2nd_order) 
then 
  232        do idir2 = idir, pdim
 
  233          call lr_init(kdotp_vars%lr2(1, idir, idir2))
 
  234          call lr_allocate(kdotp_vars%lr2(1, idir, idir2), sys%st, sys%gr)
 
  239      if (.not. fromscratch) 
then 
  242        if (ierr == 0) 
call states_elec_load(restart_load, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
 
  243          ierr, lr=kdotp_vars%lr(1, idir))
 
  247          message(1) = 
"Unable to read response wavefunctions from '"//trim(
wfs_tag_sigma(sys%namespace, str_tmp, 1))//
"'." 
  251        if (calc_2nd_order) 
then 
  252          do idir2 = idir, pdim
 
  256              call states_elec_load(restart_load, sys%namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
 
  257                ierr, lr=kdotp_vars%lr2(1, idir, idir2))
 
  262              message(1) = 
"Unable to read response wavefunctions from '"//trim(
wfs_tag_sigma(sys%namespace, str_tmp, 1))//
"'." 
  271    message(1) = 
"Info: Calculating k.p linear response of ground-state wavefunctions." 
  273    kdotp_vars%converged = .
true.
 
  277      write(
message(1), 
'(3a)') 
'Info: Calculating response for the ', 
index2axis(idir), &
 
  280      call kdotp_vars%pert%setup_dir(idir)
 
  283        call dsternheimer_solve(sh, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%mc, &
 
  284          kdotp_vars%lr(1:1, idir), 1, 
m_zero, kdotp_vars%pert, restart_dump, 
"", 
kdotp_wfs_tag(idir), &
 
  285          have_restart_rho = .false.)
 
  286        if (kdotp_vars%occ_solution_method == 1) 
then 
  287          call dkdotp_add_occ(sys%namespace, sys%space, sys%gr, sys%st, sys%hm, kdotp_vars%pert, &
 
  288            kdotp_vars%lr(1, idir), kdotp_vars%degen_thres)
 
  291        call zsternheimer_solve(sh, sys%namespace, sys%space, sys%gr, sys%kpoints, sys%st, sys%hm, sys%mc, &
 
  292          kdotp_vars%lr(1:1, idir), 1, 
m_zi * kdotp_vars%eta, kdotp_vars%pert, restart_dump, 
"", &
 
  294        if (kdotp_vars%occ_solution_method == 1) 
then 
  295          call zkdotp_add_occ(sys%namespace, sys%space, sys%gr, sys%st, sys%hm, kdotp_vars%pert, &
 
  296            kdotp_vars%lr(1, idir), kdotp_vars%degen_thres)
 
  304        call doutput_lr(sys%outp, sys%namespace, sys%space, 
kdotp_dir, sys%st, sys%gr, kdotp_vars%lr(1, idir), idir, 1, &
 
  307        do ispin = 1, sys%st%d%nspin
 
  308          errornorm = 
hypot(errornorm, 
dmf_nrm2(sys%gr, kdotp_vars%lr(1, idir)%ddl_rho(:, ispin)))
 
  311        call zoutput_lr(sys%outp, sys%namespace, sys%space, 
kdotp_dir, sys%st, sys%gr, kdotp_vars%lr(1, idir), idir, 1, &
 
  314        do ispin = 1, sys%st%d%nspin
 
  315          errornorm = 
hypot(errornorm, 
zmf_nrm2(sys%gr, kdotp_vars%lr(1, idir)%zdl_rho(:, ispin)))
 
  319      write(
message(1),
'(a,g13.6)') 
"Norm of relative density variation = ", errornorm / sys%st%qtot
 
  322      if (calc_2nd_order) 
then 
  324        do idir2 = idir, pdim
 
  325          write(
message(1), 
'(3a)') 
'Info: Calculating second-order response in the ', 
index2axis(idir2), &
 
  329          call pert2%setup_dir(idir2)
 
  333              sys%mc, kdotp_vars%lr(1:1, idir), kdotp_vars%lr(1:1, idir2), &
 
  335              kdotp_vars%lr2(1:1, idir, idir2), kdotp_vars%pert2, restart_dump, 
"", 
kdotp_wfs_tag(idir, idir2), &
 
  336              have_restart_rho = .false., have_exact_freq = .
true.)
 
  339              sys%mc, kdotp_vars%lr(1:1, idir), kdotp_vars%lr(1:1, idir2), &
 
  340              1, 
m_zi * kdotp_vars%eta, 
m_zi * kdotp_vars%eta, kdotp_vars%pert, pert2, &
 
  341              kdotp_vars%lr2(1:1, idir, idir2), kdotp_vars%pert2, restart_dump, 
"", 
kdotp_wfs_tag(idir, idir2), &
 
  342              have_restart_rho = .false., have_exact_freq = .
true.)
 
  352    if (calc_eff_mass) 
then 
  353      message(1) = 
"Info: Calculating effective masses." 
  356      safe_allocate(kdotp_vars%eff_mass_inv(1:pdim, 1:pdim, 1:sys%st%nst, 1:sys%st%nik))
 
  357      kdotp_vars%eff_mass_inv(:,:,:,:) = 
m_zero 
  361        call dcalc_eff_mass_inv(sys%namespace, sys%space, sys%gr, sys%st, sys%hm, kdotp_vars%lr, &
 
  362          kdotp_vars%pert, kdotp_vars%eff_mass_inv, kdotp_vars%degen_thres)
 
  364        call zcalc_eff_mass_inv(sys%namespace, sys%space, sys%gr, sys%st, sys%hm, kdotp_vars%lr, &
 
  365          kdotp_vars%pert, kdotp_vars%eff_mass_inv, kdotp_vars%degen_thres)
 
  369      call kdotp_write_eff_mass(sys%st, sys%kpoints, kdotp_vars, sys%namespace, sys%space%periodic_dim)
 
  371      safe_deallocate_a(kdotp_vars%eff_mass_inv)
 
  378      if (calc_2nd_order) 
then 
  379        do idir2 = idir, pdim
 
  380          call lr_dealloc(kdotp_vars%lr2(1, idir, idir2))
 
  388    deallocate(kdotp_vars%pert)
 
  389    safe_deallocate_a(kdotp_vars%lr)
 
  391    if (calc_2nd_order) 
then 
  393      safe_deallocate_p(pert2)
 
  394      deallocate(kdotp_vars%pert2)
 
  395      safe_deallocate_a(kdotp_vars%lr2)
 
  428      call parse_variable(sys%namespace, 
'KdotPOccupiedSolutionMethod', 0, kdotp_vars%occ_solution_method)
 
  431          namespace=sys%namespace)
 
  443        kdotp_vars%degen_thres)
 
  467      call parse_variable(sys%namespace, 
'KdotPCalculateEffectiveMasses', .
true., calc_eff_mass)
 
  478      call parse_variable(sys%namespace, 
'KdotPCalcSecondOrder', .false., calc_2nd_order)
 
  489      call kdotp_vars%pert%info()
 
  493      if (kdotp_vars%occ_solution_method == 0) 
then 
  494        message(1) = 
'Occupied solution method: Sternheimer equation.' 
  496        message(1) = 
'Occupied solution method: sum over states.' 
  512    integer,             
intent(in)    :: periodic_dim
 
  513    real(real64),        
intent(in)    :: velocity(:,:,:)
 
  516    character(len=80) :: filename, tmp
 
  517    integer :: iunit, ik, ist, ik2, ispin, idir
 
  523    write(filename, 
'(a)') 
kdotp_dir//
'velocity' 
  524    iunit = 
io_open(trim(filename), namespace, action=
'write')
 
  525    write(iunit,
'(a)') 
'# Band velocities' 
  528      ispin = st%d%get_spin_index(ik)
 
  529      ik2 = st%d%get_kpoint_index(ik)
 
  532      write(iunit,
'(a,i1,a,a)') 
'# spin = ', ispin, 
', k-point = ', trim(tmp)
 
  534      write(iunit,
'(a)',advance=
'no') 
'# state    energy       ' 
  535      do idir = 1, periodic_dim
 
  536        write(iunit,
'(3a)',advance=
'no') 
'vg(', trim(
index2axis(idir)), 
')       ' 
  541      do idir = 1, periodic_dim
 
  548          velocity(1:periodic_dim, ist, ik)
 
  560    type(
kdotp_t),        
intent(inout) :: kdotp_vars
 
  562    integer,              
intent(in)    :: periodic_dim
 
  564    character(len=80) :: filename, tmp
 
  565    integer :: iunit, ik, ist, ik2, ispin
 
  572      ispin = st%d%get_spin_index(ik)
 
  573      ik2 = st%d%get_kpoint_index(ik)
 
  576      write(filename, 
'(3a, i1)') 
kdotp_dir//
'kpoint_', trim(tmp), 
'_', ispin
 
  577      iunit = 
io_open(trim(filename), namespace, action=
'write')
 
  579      write(iunit,
'(a, i10)')    
'# spin    index = ', ispin
 
  580      write(iunit,
'(a, i10)')    
'# k-point index = ', ik2
 
  581      write(iunit,
'(a, 99f12.8)') 
'# k-point coordinates = ', kpoints%get_point(ik2)
 
  582      if (.not. kdotp_vars%converged) 
write(iunit, 
'(a)') 
"# WARNING: not converged" 
  585      write(iunit,
'(a)') 
'# Inverse effective-mass tensors' 
  589        write(iunit,
'(a, a, a, f12.8, a, a)') 
'State #', trim(tmp), 
', Energy = ', &
 
  595      write(iunit,
'(a)') 
'# Effective-mass tensors' 
  599        write(iunit,
'(a, a, a, f12.8, a, a)') 
'State #', trim(tmp), 
', Energy = ', &
 
  601        call lalg_inverse(periodic_dim, kdotp_vars%eff_mass_inv(:, :, ist, ik), 
'dir')
 
  614    real(real64),        
intent(in)    :: threshold
 
  617    character(len=80) :: tmp
 
  618    integer :: ik, ist, ist2, ik2, ispin
 
  627      ispin = st%d%get_spin_index(ik)
 
  628      ik2 = st%d%get_kpoint_index(ik)
 
  631      write(
message(1), 
'(3a, i1)') 
'k-point ', trim(tmp), 
', spin ', ispin
 
  635      do while (ist <= st%nst)
 
  639        write(
message(2),
'(a, a, a, f12.8, a, a)') 
'State #', trim(tmp), 
', Energy = ', &
 
  644        do while (ist2 <= st%nst .and. &
 
  645          abs(st%eigenval(min(ist2, st%nst), ik) - st%eigenval(ist, ik)) < threshold)
 
  647          write(
message(1),
'(a, a, a, f12.8, a, a)') 
'State #', trim(tmp), 
', Energy = ', &
 
  660    message(1) = 
"Velocities and effective masses are not correct within degenerate subspaces." 
  667  character(len=12) pure function int2str(ii) result(str)
 
  668    integer, 
intent(in) :: ii
 
  670    write(str, 
'(i11)') ii
 
  671    str = trim(adjustl(str))
 
double hypot(double __x, double __y) __attribute__((__nothrow__
 
real(real64), parameter, public m_zero
 
character(len= *), parameter, public kdotp_dir
 
complex(real64), parameter, public m_zi
 
real(real64), parameter, public m_epsilon
 
This module implements the underlying real-space grid.
 
integer, parameter, public generalized_kohn_sham_dft
 
integer, parameter, public hartree_fock
 
subroutine, public io_close(iunit, grp)
 
subroutine, public io_mkdir(fname, namespace, parents)
 
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
 
subroutine, public calc_band_velocity(namespace, space, gr, st, hm, pert, velocity)
Computes the k-point and band-resolved velocity.
 
subroutine, public dkdotp_add_occ(namespace, space, gr, st, hm, pert, kdotp_lr, degen_thres)
add projection onto occupied states, by sum over states
 
subroutine, public zkdotp_add_occ(namespace, space, gr, st, hm, pert, kdotp_lr, degen_thres)
add projection onto occupied states, by sum over states
 
subroutine, public dcalc_eff_mass_inv(namespace, space, gr, st, hm, lr, pert, eff_mass_inv, degen_thres)
Computes the effective mass tensor.
 
character(len=100) function, public kdotp_wfs_tag(dir, dir2)
 
subroutine, public zcalc_eff_mass_inv(namespace, space, gr, st, hm, lr, pert, eff_mass_inv, degen_thres)
Computes the effective mass tensor.
 
subroutine kdotp_write_band_velocity(st, periodic_dim, velocity, namespace)
 
subroutine kdotp_lr_run_legacy(sys, fromScratch)
 
subroutine kdotp_write_eff_mass(st, kpoints, kdotp_vars, namespace, periodic_dim)
 
subroutine kdotp_write_degeneracies(st, threshold, namespace)
 
subroutine, public kdotp_lr_run(system, from_scratch)
 
character(len=12) pure function, public int2str(ii)
 
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.
 
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
 
subroutine, public messages_not_implemented(feature, namespace)
 
character(len=512), private msg
 
subroutine, public messages_warning(no_lines, all_nodes, namespace)
 
subroutine, public messages_obsolete_variable(namespace, name, rep)
 
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
 
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
 
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
 
subroutine, public messages_experimental(name, namespace)
 
logical function mpi_grp_is_root(grp)
 
type(mpi_grp_t), public mpi_world
 
This module implements the basic mulsisystem class, a container system for other systems.
 
this module contains the output system
 
subroutine, public zoutput_lr(outp, namespace, space, dir, st, mesh, lr, idir, isigma, ions, pert_unit)
 
subroutine, public doutput_lr(outp, namespace, space, dir, st, mesh, lr, idir, isigma, ions, pert_unit)
 
integer, parameter, public restart_kdotp
 
integer, parameter, public restart_gs
 
type(restart_data_t), dimension(restart_n_data_types) info
 
subroutine, public restart_init(restart, namespace, data_type, type, mc, ierr, mesh, dir, exact)
Initializes a restart object.
 
integer, parameter, public restart_type_dump
 
subroutine, public restart_open_dir(restart, dirname, ierr)
Change the restart directory to dirname, where "dirname" is a subdirectory of the base restart direct...
 
integer, parameter, public restart_type_load
 
subroutine, public restart_end(restart)
 
subroutine, public restart_close_dir(restart)
Change back to the base directory. To be called after restart_open_dir.
 
logical pure function, public smear_is_semiconducting(this)
 
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.
 
character(len=20) pure function, public units_abbrev(this)
 
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.
 
subroutine, public output_tensor(tensor, ndim, unit, write_average, iunit, namespace)
 
character pure function, public index2axis(idir)
 
subroutine, public v_ks_h_setup(namespace, space, gr, ions, ext_partners, st, ks, hm, calc_eigenval, calc_current)
 
Class describing the electron system.
 
Container class for lists of system_oct_m::system_t.
 
The states_elec_t class contains all electronic wave functions.