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(phase_t) :: phase
type(energy_t), allocatable :: energy
type(absorbing_boundaries_t) :: abs_boundaries !< absorbing boundaries
real(real64), allocatable :: vhartree(:) !< Hartree potential
real(real64), allocatable :: vxc(:,:) !< XC potential
real(real64), allocatable :: vhxc(:,:) !< XC potential + Hartree potential + Berry potential
real(real64), allocatable :: vtau(:,:) !< Derivative of e_XC w.r.t. tau
real(real64), allocatable :: vberry(:,:) !< Berry phase potential from external e_field
type(derivatives_t), pointer, private :: der !< pointer to derivatives
type(nonlocal_pseudopotential_t) :: vnl !< Nonlocal part of the pseudopotential
type(ions_t), pointer :: ions
real(real64) :: 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
real(real64), allocatable :: a_ind(:, :)
real(real64), 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)
real(real64), 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
real(real64) :: 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
real(real64), allocatable, public :: v_ext_pot(:) !< the potential comming from external potentials
real(real64), 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
real(real64) :: mass !< Needed to compute the magnetic terms, if the mass is not one.
real(real64) :: rashba_coupling !< Rashba coupling strength
type(nl_operator_t), pointer, public :: kinetic !< kinetic energy operator
real(real64), allocatable, public :: potential(:, :) !< real scalar potential
real(real64), allocatable, public :: Impotential(:, :) !< imaginary scalar potential
real(real64), allocatable, public :: uniform_magnetic_field(:) !< uniform magnetic field
!! (assumed to be in Gaussian units)
real(real64), allocatable, public :: magnetic_field(:, :) !< non-uniform magnetic field
!! (assumed to be in Gaussian units)
real(real64), allocatable, public :: zeeman_pot(:, :)
real(real64), 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
real(real64), allocatable, public :: vector_potential(:, :) !< general (non-uniform) vector potential
type(accel_mem_t) :: potential_accel
type(accel_mem_t) :: impotential_accel
type(accel_mem_t), public :: vtau_accel
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_magnetic_terms => hamiltonian_elec_base_update_magnetic_terms
!< @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 :: 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 :: 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
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.