67    real(real64)                                  :: rashba_coupling
 
   68    type(nl_operator_t),      
pointer,     
public :: kinetic
 
   69    real(real64),             
allocatable, 
public :: potential(:, :)
 
   70    real(real64),             
allocatable, 
public :: Impotential(:, :)
 
   71    real(real64),             
allocatable, 
public :: uniform_magnetic_field(:)
 
   73    real(real64),             
allocatable, 
public :: magnetic_field(:, :)
 
   75    real(real64),             
allocatable, 
public :: zeeman_pot(:, :)
 
   76    real(real64),             
allocatable, 
public :: uniform_vector_potential(:)
 
   80    real(real64),             
allocatable, 
public :: vector_potential(:, :)
 
   81    type(accel_mem_t)                             :: potential_accel
 
   82    type(accel_mem_t)                             :: impotential_accel
 
   83    type(accel_mem_t),                     
public :: vtau_accel
 
  116  integer, 
parameter, 
public ::          &
 
  117    TERM_ALL                 = huge(1),  &
 
  127  integer, 
parameter, 
public ::            &
 
  128    FIELD_POTENTIAL                = 1,    &
 
  140    class(hamiltonian_elec_base_t), 
intent(inout) :: this
 
  141    integer,                  
intent(in)    :: nspin
 
  142    real(real64),             
intent(in)    :: mass
 
  143    real(real64),             
intent(in)    :: rashba_coupling
 
  149    this%rashba_coupling = rashba_coupling
 
  165      if (
allocated(this%Impotential)) 
then 
  170    safe_deallocate_a(this%potential)
 
  171    safe_deallocate_a(this%Impotential)
 
  172    safe_deallocate_a(this%vector_potential)
 
  173    safe_deallocate_a(this%uniform_vector_potential)
 
  174    safe_deallocate_a(this%uniform_magnetic_field)
 
  175    safe_deallocate_a(this%magnetic_field)
 
  176    safe_deallocate_a(this%zeeman_pot)
 
  188    integer,                       
intent(in)    :: np
 
  192    push_sub(hamiltonian_elec_clear)
 
  194    if (
allocated(this%potential)) 
then 
  195      do ispin = 1, this%nspin
 
  198          this%potential(ip, ispin) = 
m_zero 
  203    if (
allocated(this%Impotential)) 
then 
  204      do ispin = 1, this%nspin
 
  207          this%Impotential(ip, ispin) = 
m_zero 
  212    if (
allocated(this%uniform_vector_potential)) 
then 
  213      this%uniform_vector_potential = 
m_zero 
  216    if (
allocated(this%vector_potential)) 
then 
  217      this%vector_potential = 
m_zero 
  220    if (
allocated(this%uniform_magnetic_field)) 
then 
  221      this%uniform_magnetic_field = 
m_zero 
  224    if (
allocated(this%magnetic_field)) 
then 
  225      this%magnetic_field = 
m_zero 
  228    if (
allocated(this%zeeman_pot)) 
then 
  232    pop_sub(hamiltonian_elec_clear)
 
  241    class(
mesh_t),            
intent(in)    :: mesh
 
  242    integer,                  
intent(in)    :: field
 
  243    logical,                  
intent(in)    :: complex_potential
 
  249    if (
bitand(field_potential, field) /= 0) 
then 
  250      if (.not. 
allocated(this%potential)) 
then 
  251        safe_allocate(this%potential(1:mesh%np, 1:this%nspin))
 
  252        do ispin = 1, this%nspin
 
  255            this%potential(ip, ispin) = 
m_zero 
  258        if (complex_potential) 
then 
  259          safe_allocate(this%Impotential(1:mesh%np, 1:this%nspin))
 
  260          do ispin = 1, this%nspin
 
  263              this%Impotential(ip, ispin) = 
m_zero 
  270          if (complex_potential) 
then 
  279      if (.not. 
allocated(this%uniform_vector_potential)) 
then 
  280        safe_allocate(this%uniform_vector_potential(1:mesh%box%dim))
 
  281        this%uniform_vector_potential = 
m_zero 
  286      if (.not. 
allocated(this%vector_potential)) 
then 
  287        safe_allocate(this%vector_potential(1:mesh%box%dim, 1:mesh%np))
 
  288        this%vector_potential = 
m_zero 
  293      if (.not. 
allocated(this%uniform_magnetic_field)) 
then 
  294        safe_allocate(this%uniform_magnetic_field(1:max(mesh%box%dim, 3)))
 
  295        this%uniform_magnetic_field = 
m_zero 
  301      if (.not. 
allocated(this%magnetic_field)) 
then 
  302        safe_allocate(this%magnetic_field(1:mesh%np, 1:max(mesh%box%dim, 3)))
 
  303        this%magnetic_field = 
m_zero 
  304        safe_allocate(this%zeeman_pot(1:mesh%np, 1:this%nspin))
 
  322    class(
mesh_t),                  
intent(in)    :: mesh
 
  323    real(real64),                   
intent(in)    :: gyromagnetic_ratio
 
  324    integer,                        
intent(in)    :: ispin
 
  326    real(real64) :: b_norm2, cc
 
  331    if (
allocated(this%uniform_vector_potential) .and. 
allocated(this%vector_potential)) 
then 
  333      do idir = 1, mesh%box%dim
 
  336          this%vector_potential(idir, ip) = &
 
  337            this%vector_potential(idir, ip) + this%uniform_vector_potential(idir)
 
  340      safe_deallocate_a(this%uniform_vector_potential)
 
  344    if (.not. 
allocated(this%magnetic_field)) 
then 
  357    if (
allocated(this%uniform_magnetic_field) ) 
then 
  362          this%magnetic_field(ip, idir) = this%magnetic_field(ip, idir) + this%uniform_magnetic_field(idir)
 
  373        b_norm2 = norm2(this%magnetic_field(ip, 1:max(mesh%box%dim, 3)))
 
  374        this%zeeman_pot(ip, 1) =   cc*b_norm2
 
  375        this%zeeman_pot(ip, 2) = - cc*b_norm2
 
  381        this%zeeman_pot(ip, 1) =  cc*this%magnetic_field(ip, 3)
 
  382        this%zeeman_pot(ip, 2) = - cc*this%magnetic_field(ip, 3)
 
  383        this%zeeman_pot(ip, 3) =   cc*this%magnetic_field(ip, 1)
 
  384        this%zeeman_pot(ip, 4) = - cc*this%magnetic_field(ip, 2)
 
  387    safe_deallocate_a(this%uniform_magnetic_field)
 
  398    class(
mesh_t),            
intent(in)    :: mesh
 
  399    real(real64), 
optional,          
intent(in)    :: vtau(:,:)
 
  401    integer :: offset, ispin
 
  407      do ispin = 1, this%nspin
 
  408        call accel_write_buffer(this%potential_accel, mesh%np, this%potential(:, ispin), offset = offset)
 
  409        if(
present(vtau)) 
then 
  412        if(
allocated(this%Impotential)) 
then 
  413          call accel_write_buffer(this%impotential_accel, mesh%np, this%Impotential(:, ispin), offset = offset)
 
  425  logical pure function hamiltonian_elec_base_has_magnetic(this) result(has_magnetic)
 
  428    has_magnetic = 
allocated(this%vector_potential) &
 
  429      .or. 
allocated(this%uniform_magnetic_field)
 
  436  logical pure function hamiltonian_elec_base_has_zeeman(this) result(has_zeeman)
 
  439    has_zeeman = 
allocated(this%zeeman_pot)
 
  446  logical pure function hamiltonian_elec_base_has_vector_potential(this) result(has_vector_potential)
 
  449    has_vector_potential = 
allocated(this%vector_potential) &
 
  450      .or. 
allocated(this%uniform_vector_potential)
 
  457    class(mesh_t),                  
intent(in)    :: mesh
 
  458    type(derivatives_t),            
intent(in)    :: der
 
  459    type(states_elec_dim_t),        
intent(in)    :: std
 
  460    type(wfs_elec_t), 
target,       
intent(in)    :: psib
 
  461    type(wfs_elec_t), 
target,       
intent(inout) :: vpsib
 
  463    integer :: ist, idim, ip
 
  464    complex(real64), 
allocatable :: psi(:, :), vpsi(:, :), grad(:, :, :)
 
  468    if (abs(this%rashba_coupling) < m_epsilon) 
then 
  472    assert(std%ispin == spinors)
 
  473    assert(mesh%box%dim == 2)
 
  474    assert(psib%type() == type_cmplx)
 
  475    assert(vpsib%type() == type_cmplx)
 
  477    safe_allocate(psi(1:mesh%np_part, 1:std%dim))
 
  478    safe_allocate(vpsi(1:mesh%np, 1:std%dim))
 
  479    safe_allocate(grad(1:mesh%np, 1:mesh%box%dim, 1:std%dim))
 
  482      call batch_get_state(psib, ist, mesh%np_part, psi)
 
  483      call batch_get_state(vpsib, ist, mesh%np, vpsi)
 
  486        call zderivatives_grad(der, psi(:, idim), grad(:, :, idim), ghost_update = .false., set_bc = .false.)
 
  489      if (
allocated(this%vector_potential)) 
then 
  491          vpsi(ip, 1) = vpsi(ip, 1) - &
 
  492            (this%rashba_coupling) * (this%vector_potential(2, ip) + m_zi * this%vector_potential(1, ip)) * psi(ip, 2)
 
  493          vpsi(ip, 2) = vpsi(ip, 2) - &
 
  494            (this%rashba_coupling) * (this%vector_potential(2, ip) - m_zi * this%vector_potential(1, ip)) * psi(ip, 1)
 
  499        vpsi(ip, 1) = vpsi(ip, 1) - &
 
  500          this%rashba_coupling*( grad(ip, 1, 2) - m_zi*grad(ip, 2, 2))
 
  501        vpsi(ip, 2) = vpsi(ip, 2) + &
 
  502          this%rashba_coupling*( grad(ip, 1, 1) + m_zi*grad(ip, 2, 1))
 
  505      call batch_set_state(vpsib, ist, mesh%np, vpsi)
 
  508    safe_deallocate_a(grad)
 
  509    safe_deallocate_a(vpsi)
 
  510    safe_deallocate_a(psi)
 
  517#include "hamiltonian_elec_base_inc.F90" 
  520#include "complex.F90" 
  521#include "hamiltonian_elec_base_inc.F90" 
subroutine, public accel_release_buffer(this)
 
pure logical function, public accel_is_enabled()
 
integer, parameter, public accel_mem_read_only
 
This module implements batches of mesh functions.
 
This module implements common operations on batches of mesh functions.
 
This module contains interfaces for BLAS routines You should not use these routines directly....
 
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
 
integer, parameter, public spinors
 
integer, parameter, public spin_polarized
 
real(real64), parameter, public m_zero
 
real(real64), parameter, public m_half
 
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
 
subroutine dhamiltonian_elec_base_magnetic(this, mesh, der, std, ep, ispin, psib, vpsib)
apply magnetic terms form the Hamiltonian to the wave functions
 
logical pure function hamiltonian_elec_base_has_vector_potential(this)
return .true. of the Hamiltonian contains any vector potential
 
subroutine, public dhamiltonian_elec_base_local_sub(potential, mesh, std, ispin, psib, vpsib, Impotential, potential_accel, impotential_accel, async)
apply a local potential to a set of states
 
subroutine hamiltonian_elec_base_update_magnetic_terms(this, mesh, gyromagnetic_ratio, ispin)
update the magnetic terms of the hamiltonian_elec_base_t.
 
integer, parameter, public term_local_external
 
subroutine hamiltonian_elec_base_rashba(this, mesh, der, std, psib, vpsib)
 
subroutine dhamiltonian_elec_base_local(this, mesh, std, ispin, psib, vpsib, async)
apply the local potential (stored in the hamiltonian) to the states
 
integer, parameter, public field_uniform_magnetic_field
 
subroutine hamiltonian_elec_base_allocate(this, mesh, field, complex_potential)
This function ensures that the corresponding field is allocated.
 
integer, parameter, public field_uniform_vector_potential
 
integer, parameter, public field_vector_potential
 
subroutine hamiltonian_elec_base_clear(this, np)
This functions sets to zero all fields that are currently allocated.
 
logical pure function hamiltonian_elec_base_has_magnetic(this)
return .true. if the Hamiltonian contains any magnetic field
 
subroutine hamiltonian_elec_base_end(this)
Finalizer for hamiltonian_elec_base_t.
 
integer, parameter, public term_mgga
 
integer, parameter, public term_others
 
subroutine zhamiltonian_elec_base_magnetic(this, mesh, der, std, ep, ispin, psib, vpsib)
apply magnetic terms form the Hamiltonian to the wave functions
 
integer, parameter, public term_non_local_potential
 
integer, parameter, public term_rdmft_occ
 
integer, parameter, public term_kinetic
 
subroutine zhamiltonian_elec_base_local(this, mesh, std, ispin, psib, vpsib, async)
apply the local potential (stored in the hamiltonian) to the states
 
logical pure function hamiltonian_elec_base_has_zeeman(this)
return .true. of the Hamiltonian contains a zeeman term
 
integer, parameter, public field_magnetic_field
 
subroutine, public zhamiltonian_elec_base_local_sub(potential, mesh, std, ispin, psib, vpsib, Impotential, potential_accel, impotential_accel, async)
apply a local potential to a set of states
 
subroutine hamiltonian_elec_base_init(this, nspin, mass, rashba_coupling)
initialize the hamiltonian_elec_base_t object
 
subroutine hamiltonian_elec_base_accel_copy_pot(this, mesh, vtau)
copy the potential to the acceleration device buffer
 
integer, parameter, public term_dft_u
 
integer, parameter, public term_local_potential
 
This module is intended to contain "only mathematical" functions and procedures.
 
This module defines the meshes, which are used in Octopus.
 
This module defines non-local operators.
 
This module handles spin dimensions of the states and the k-point distribution.
 
type(type_t), public type_float
 
The basic Hamiltonian for electronic system.
 
Describes mesh distribution to nodes.