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
    type(ks_potential_t) :: ks_pot !< Kohn-Sham potentials (Hartree, xc, vtau)
    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 => null()
  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
  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.