Electron Hamiltonian class
The electronic Hamiltonian is derived from the abstract Hamiltonian.
type, extends(hamiltonian_abst_t) :: hamiltonian_elec_t
! Components are public by default
!> The Hamiltonian must know what are the "dimensions" of the spaces,
!! in order to be able to operate on the states.
type(space_t), private :: space
type(states_elec_dim_t) :: d
type(hamiltonian_elec_base_t) :: hm_base
type(energy_t), allocatable :: energy
type(absorbing_boundaries_t) :: abs_boundaries !< absorbing boundaries
FLOAT, allocatable :: vhartree(:) !< Hartree potential
FLOAT, allocatable :: vxc(:,:) !< XC potential
FLOAT, allocatable :: vhxc(:,:) !< XC potential + Hartree potential + Berry potential
FLOAT, allocatable :: vtau(:,:) !< Derivative of e_XC w.r.t. tau
FLOAT, allocatable :: vberry(:,:) !< Berry phase potential from external e_field
type(derivatives_t), pointer, private :: der !< pointer to derivatives
type(ions_t), pointer :: ions
FLOAT :: exx_coef !< how much of EXX to mix
type(poisson_t) :: psolver !< Poisson solver
!> The self-induced vector potential and magnetic field
logical :: self_induced_magnetic
FLOAT, allocatable :: a_ind(:, :)
FLOAT, allocatable :: b_ind(:, :)
integer :: theory_level !< copied from sys%ks
type(xc_t), pointer :: xc !< pointer to xc object
type(xc_photons_t), pointer :: xc_photons !< pointer to the xc_photons object
type(epot_t) :: ep !< handles the external potential
type(pcm_t) :: pcm !< handles pcm variables
!> absorbing boundaries
logical, private :: adjoint
!> Mass of the particle (in most cases, mass = 1, electron mass)
FLOAT, private :: mass
!> There may be an "inhomogeneous", "source", or "forcing" term (useful for the OCT formalism)
logical, private :: inh_term
type(states_elec_t) :: inh_st
!> There may also be a exchange-like term, similar to the one necessary for time-dependent
!! Hartree Fock, also useful only for the OCT equations
type(oct_exchange_t) :: oct_exchange
type(scissor_t) :: scissor
FLOAT :: current_time
logical, private :: is_applied_packed !< This is initialized by the StatesPack variable.
!> For the DFT+U
type(lda_u_t) :: lda_u
integer :: lda_u_level
logical, public :: time_zero
type(exchange_operator_t), public :: exxop
type(kpoints_t), pointer, public :: kpoints => null()
type(partner_list_t) :: external_potentials !< List with all the external potentials
FLOAT, allocatable, public :: v_ext_pot(:) !< the potential comming from external potentials
FLOAT, allocatable, public :: v_static(:) !< static scalar potential
type(ion_electron_local_potential_t) :: v_ie_loc !< Ion-electron local potential interaction
type(nlcc_t) :: nlcc !< Ion-electron NLCC interaction
type(magnetic_constrain_t) :: magnetic_constrain
!> The possible kick
type(kick_t) :: kick
!> Maxwell-electrons coupling information
type(mxll_coupling_t) :: mxll
type(zora_t), pointer :: zora
contains
procedure :: update => hamiltonian_elec_update
procedure :: apply_packed => hamiltonian_elec_apply_packed
procedure :: update_span => hamiltonian_elec_span
procedure :: dapply => dhamiltonian_elec_apply
procedure :: zapply => zhamiltonian_elec_apply
procedure :: dmagnus_apply => dhamiltonian_elec_magnus_apply
procedure :: zmagnus_apply => zhamiltonian_elec_magnus_apply
procedure :: is_hermitian => hamiltonian_elec_hermitian
procedure :: set_mass => hamiltonian_elec_set_mass
end type hamiltonian_elec_t
It contains the ‘physical’ quantities, such as
- information about the dimensionality,
- the contributions to the potential,
- a pointer to the ions,
- electronic mass,
- etc.
and an instance of hamiltonian_elec_base_t
, which bundles some lower level variables.
The separation of quantities into these two classes is mostly historic, and currently has no deeper systematics.
type hamiltonian_elec_base_t
private
integer :: nspin !< number of spin channels
FLOAT :: mass !< Needed to compute the magnetic terms, if the mass is not one.
FLOAT :: rashba_coupling !< Rashba coupling strength
type(nl_operator_t), pointer, public :: kinetic !< kinetic energy operator
type(projector_matrix_t), allocatable, public :: projector_matrices(:) !< projectors
FLOAT, allocatable, public :: potential(:, :) !< real scalar potential
FLOAT, allocatable, public :: Impotential(:, :) !< imaginary scalar potential
FLOAT, allocatable, public :: uniform_magnetic_field(:) !< uniform magnetic field
!! (assumed to be in Gaussian units)
FLOAT, allocatable, public :: magnetic_field(:, :) !< non-uniform magnetic field
!! (assumed to be in Gaussian units)
FLOAT, allocatable, public :: zeeman_pot(:, :)
FLOAT, allocatable, public :: uniform_vector_potential(:) !< @brief a uniform vector potential
!!
!! in some cases, absorbed in the vector_potential
!! i.e. the non-uniform vector potential
FLOAT, allocatable, public :: vector_potential(:, :) !< general (non-uniform) vector potential
integer, public :: nprojector_matrices !< number of projector matrices
logical, public :: apply_projector_matrices !< flag whether to apply projection matrices
logical, public :: has_non_local_potential !< flag whether non-local potential exists
integer :: full_projection_size
integer, public :: max_npoints
integer, public :: total_points
integer :: max_nprojs
logical :: projector_mix
CMPLX, allocatable, public :: projector_phases(:, :, :, :)
integer, allocatable, public :: projector_to_atom(:)
integer, public :: nphase !< @brief number of phases:
!!
!! * 0 for finite systems without magnetic fields
!! * 1 for periodic systems or magnetic fields
!! * 3 for spiral boundary conditions
integer :: nregions !< number of non-overlapping regions
integer, allocatable :: regions(:) !< list of atomd in each region.
type(accel_mem_t) :: potential_accel
type(accel_mem_t) :: impotential_accel
type(accel_mem_t), public :: vtau_accel
type(accel_mem_t) :: buff_offsets
type(accel_mem_t) :: buff_matrices
type(accel_mem_t) :: buff_maps
type(accel_mem_t) :: buff_scals
type(accel_mem_t) :: buff_position
type(accel_mem_t) :: buff_pos
type(accel_mem_t) :: buff_invmap
type(accel_mem_t), public :: buff_projector_phases
type(accel_mem_t) :: buff_mix
CMPLX, allocatable, public :: phase(:, :) !< phase factor:
!! (1:gr%np_part, hm%d%kpt%start:hm%d%kpt%end);
!! set in hamiltonian_elec_oct_m::hamiltonian_elec_init()
CMPLX, allocatable, public :: phase_corr(:,:) !< phase correction:
!! (gr%np+1:gr%np_part, hm%d%kpt%start:hm%d%kpt%end);
!! set in hamiltonian_elec_oct_m::hamiltonian_elec_init()
CMPLX, allocatable, public :: phase_spiral(:,:) !< phase for spiral boundaruy conditions:
!! (1:gr%np_part-sp, 1:2);
!! set in hamiltonian_elec_oct_m::hamiltonian_elec_init()
type(accel_mem_t), public :: buff_phase
type(accel_mem_t), public :: buff_phase_spiral
type(accel_mem_t), public :: buff_phase_corr
integer, public :: buff_phase_qn_start
logical :: projector_self_overlap !< if .true. some projectors overlap with themselves
FLOAT, pointer, public :: spin(:,:,:)
contains
procedure :: init => hamiltonian_elec_base_init
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_init
procedure :: end => hamiltonian_elec_base_end
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_end
procedure :: clear => hamiltonian_elec_base_clear
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_clear
procedure :: update => hamiltonian_elec_base_update
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_update
procedure :: allocate_field => hamiltonian_elec_base_allocate
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_allocate
procedure :: accel_copy_pot => hamiltonian_elec_base_accel_copy_pot
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_accel_copy_pot
procedure :: destroy_proj => hamiltonian_elec_base_destroy_proj
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_destroy_proj
procedure :: build_proj => hamiltonian_elec_base_build_proj
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_build_proj
procedure :: has_magnetic => hamiltonian_elec_base_has_magnetic
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_has_magnetic
procedure :: has_zeeman => hamiltonian_elec_base_has_zeeman
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_has_zeeman
procedure :: has_vector_potential => hamiltonian_elec_base_has_vector_potential
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_has_vector_potential
procedure :: has_projector_self_overlap => hamiltonian_elec_base_projector_self_overlap
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_projector_self_overlap
procedure :: set_phase_corr => hamiltonian_elec_base_set_phase_corr
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_set_phase_corr
procedure :: unset_phase_corr => hamiltonian_elec_base_unset_phase_corr
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_unset_phase_corr
procedure :: apply_phase => hamiltonian_elec_base_phase
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_phase
procedure :: apply_phase_spiral => hamiltonian_elec_base_phase_spiral
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_phase_spiral
procedure :: calc_rashba => hamiltonian_elec_base_rashba
!< @copydoc hamiltonian_elec_base_oct_m::hamiltonian_elec_base_rashba
procedure :: dcalc_magnetic => dhamiltonian_elec_base_magnetic
!< @copydoc hamiltonian_elec_base_oct_m::dhamiltonian_elec_base_magnetic
procedure :: zcalc_magnetic => zhamiltonian_elec_base_magnetic
!< @copydoc hamiltonian_elec_base_oct_m::zhamiltonian_elec_base_magnetic
procedure :: dcalc_local => dhamiltonian_elec_base_local
!< @copydoc hamiltonian_elec_base_oct_m::dhamiltonian_elec_base_local
procedure :: zcalc_local => zhamiltonian_elec_base_local
!< @copydoc hamiltonian_elec_base_oct_m::zhamiltonian_elec_base_local
procedure :: dnlocal_start => dhamiltonian_elec_base_nlocal_start
!< @copydoc hamiltonian_elec_base_oct_m::dhamiltonian_elec_base_nlocal_start
procedure :: znlocal_start => zhamiltonian_elec_base_nlocal_start
!< @copydoc hamiltonian_elec_base_oct_m::zhamiltonian_elec_base_nlocal_start
procedure :: dnlocal_finish => dhamiltonian_elec_base_nlocal_finish
!< @copydoc hamiltonian_elec_base_oct_m::dhamiltonian_elec_base_nlocal_finish
procedure :: znlocal_finish => zhamiltonian_elec_base_nlocal_finish
!< @copydoc hamiltonian_elec_base_oct_m::zhamiltonian_elec_base_nlocal_finish
procedure :: dnlocal_force => dhamiltonian_elec_base_nlocal_force
!< @copydoc hamiltonian_elec_base_oct_m::dhamiltonian_elec_base_nlocal_force
procedure :: znlocal_force => zhamiltonian_elec_base_nlocal_force
!< @copydoc hamiltonian_elec_base_oct_m::zhamiltonian_elec_base_nlocal_force
procedure :: dnlocal_position_commutator => dhamiltonian_elec_base_nlocal_position_commutator
!< @copydoc hamiltonian_elec_base_oct_m::dhamiltonian_elec_base_nlocal_position_commutator
procedure :: znlocal_position_commutator => zhamiltonian_elec_base_nlocal_position_commutator
!< @copydoc hamiltonian_elec_base_oct_m::zhamiltonian_elec_base_nlocal_position_commutator
procedure :: dr_vn_local => dhamiltonian_elec_base_r_vnlocal
!< @copydoc hamiltonian_elec_base_oct_m::dhamiltonian_elec_base_r_vnlocal
procedure :: zr_vn_local => zhamiltonian_elec_base_r_vnlocal
!< @copydoc hamiltonian_elec_base_oct_m::zhamiltonian_elec_base_r_vnlocal
end type hamiltonian_elec_base_t
The method for application of the Hamiltonian, is implemented as a wrapper routine, which checks the compatibility of the supplied wave functions, and then calls the batched version of the routine.
This batched routine now takes care of the actual application of the various terms of the Hamiltonian. The different terms to be applied
can be selected using the optional terms
argument.
The Hamiltonian is only allowed to modify the wave functions. The reason why also the initial state psib
has intent(INOUT)
is that the Hamiltonian can pack the wave functions, if requested.