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
115 integer,
parameter,
public :: &
116 TERM_ALL = huge(1), &
126 integer,
parameter,
public :: &
127 FIELD_POTENTIAL = 1, &
139 class(hamiltonian_elec_base_t),
intent(inout) :: this
140 integer,
intent(in) :: nspin
141 real(real64),
intent(in) :: mass
142 real(real64),
intent(in) :: rashba_coupling
148 this%rashba_coupling = rashba_coupling
157 class(hamiltonian_elec_base_t),
intent(inout) :: this
163 if (
allocated(this%Impotential))
then
168 safe_deallocate_a(this%potential)
169 safe_deallocate_a(this%Impotential)
170 safe_deallocate_a(this%vector_potential)
171 safe_deallocate_a(this%uniform_vector_potential)
172 safe_deallocate_a(this%uniform_magnetic_field)
173 safe_deallocate_a(this%magnetic_field)
174 safe_deallocate_a(this%zeeman_pot)
186 integer,
intent(in) :: np
190 push_sub(hamiltonian_elec_clear)
192 if (
allocated(this%potential))
then
193 do ispin = 1, this%nspin
201 if (
allocated(this%Impotential))
then
202 do ispin = 1, this%nspin
205 this%Impotential(ip, ispin) =
m_zero
210 if (
allocated(this%uniform_vector_potential))
then
211 this%uniform_vector_potential =
m_zero
214 if (
allocated(this%vector_potential))
then
215 this%vector_potential =
m_zero
218 if (
allocated(this%uniform_magnetic_field))
then
222 if (
allocated(this%magnetic_field))
then
223 this%magnetic_field =
m_zero
226 if (
allocated(this%zeeman_pot))
then
230 pop_sub(hamiltonian_elec_clear)
239 class(
mesh_t),
intent(in) :: mesh
240 integer,
intent(in) :: field
241 logical,
intent(in) :: complex_potential
247 if (
bitand(field_potential, field) /= 0)
then
248 if (.not.
allocated(this%potential))
then
249 safe_allocate(this%potential(1:mesh%np, 1:this%nspin))
250 do ispin = 1, this%nspin
253 this%potential(ip, ispin) =
m_zero
256 if (complex_potential)
then
257 safe_allocate(this%Impotential(1:mesh%np, 1:this%nspin))
258 do ispin = 1, this%nspin
261 this%Impotential(ip, ispin) =
m_zero
267 if (complex_potential)
then
276 if (.not.
allocated(this%uniform_vector_potential))
then
277 safe_allocate(this%uniform_vector_potential(1:mesh%box%dim))
278 this%uniform_vector_potential =
m_zero
283 if (.not.
allocated(this%vector_potential))
then
284 safe_allocate(this%vector_potential(1:mesh%box%dim, 1:mesh%np))
285 this%vector_potential =
m_zero
290 if (.not.
allocated(this%uniform_magnetic_field))
then
291 safe_allocate(this%uniform_magnetic_field(1:max(mesh%box%dim, 3)))
292 this%uniform_magnetic_field =
m_zero
298 if (.not.
allocated(this%magnetic_field))
then
299 safe_allocate(this%magnetic_field(1:mesh%np, 1:max(mesh%box%dim, 3)))
300 this%magnetic_field =
m_zero
301 safe_allocate(this%zeeman_pot(1:mesh%np, 1:this%nspin))
319 class(
mesh_t),
intent(in) :: mesh
320 real(real64),
intent(in) :: gyromagnetic_ratio
321 integer,
intent(in) :: ispin
323 real(real64) :: b_norm2, cc
328 if (
allocated(this%uniform_vector_potential) .and.
allocated(this%vector_potential))
then
330 do idir = 1, mesh%box%dim
333 this%vector_potential(idir, ip) = &
334 this%vector_potential(idir, ip) + this%uniform_vector_potential(idir)
337 safe_deallocate_a(this%uniform_vector_potential)
341 if (.not.
allocated(this%magnetic_field))
then
354 if (
allocated(this%uniform_magnetic_field) )
then
359 this%magnetic_field(ip, idir) = this%magnetic_field(ip, idir) + this%uniform_magnetic_field(idir)
370 b_norm2 = norm2(this%magnetic_field(ip, 1:max(mesh%box%dim, 3)))
371 this%zeeman_pot(ip, 1) = cc*b_norm2
372 this%zeeman_pot(ip, 2) = - cc*b_norm2
378 this%zeeman_pot(ip, 1) = cc*this%magnetic_field(ip, 3)
379 this%zeeman_pot(ip, 2) = - cc*this%magnetic_field(ip, 3)
380 this%zeeman_pot(ip, 3) = cc*this%magnetic_field(ip, 1)
381 this%zeeman_pot(ip, 4) = - cc*this%magnetic_field(ip, 2)
384 safe_deallocate_a(this%uniform_magnetic_field)
395 class(
mesh_t),
intent(in) :: mesh
397 integer :: offset, ispin
403 do ispin = 1, this%nspin
404 call accel_write_buffer(this%potential_accel, mesh%np, this%potential(:, ispin), offset = offset)
405 if(
allocated(this%Impotential))
then
406 call accel_write_buffer(this%impotential_accel, mesh%np, this%Impotential(:, ispin), offset = offset)
418 logical pure function hamiltonian_elec_base_has_magnetic(this) result(has_magnetic)
421 has_magnetic =
allocated(this%vector_potential) &
422 .or.
allocated(this%uniform_magnetic_field)
429 logical pure function hamiltonian_elec_base_has_zeeman(this) result(has_zeeman)
432 has_zeeman =
allocated(this%zeeman_pot)
439 logical pure function hamiltonian_elec_base_has_vector_potential(this) result(has_vector_potential)
442 has_vector_potential =
allocated(this%vector_potential) &
443 .or.
allocated(this%uniform_vector_potential)
450 class(mesh_t),
intent(in) :: mesh
451 type(derivatives_t),
intent(in) :: der
452 type(states_elec_dim_t),
intent(in) :: std
453 type(wfs_elec_t),
target,
intent(in) :: psib
454 type(wfs_elec_t),
target,
intent(inout) :: vpsib
456 integer :: ist, idim, ip
457 complex(real64),
allocatable :: psi(:, :), vpsi(:, :), grad(:, :, :)
461 if (abs(this%rashba_coupling) < m_epsilon)
then
465 assert(std%ispin == spinors)
466 assert(mesh%box%dim == 2)
467 assert(psib%type() == type_cmplx)
468 assert(vpsib%type() == type_cmplx)
470 safe_allocate(psi(1:mesh%np_part, 1:std%dim))
471 safe_allocate(vpsi(1:mesh%np, 1:std%dim))
472 safe_allocate(grad(1:mesh%np, 1:mesh%box%dim, 1:std%dim))
475 call batch_get_state(psib, ist, mesh%np_part, psi)
476 call batch_get_state(vpsib, ist, mesh%np, vpsi)
479 call zderivatives_grad(der, psi(:, idim), grad(:, :, idim), ghost_update = .false., set_bc = .false.)
482 if (
allocated(this%vector_potential))
then
484 vpsi(ip, 1) = vpsi(ip, 1) - &
485 (this%rashba_coupling) * cmplx(this%vector_potential(2, ip), this%vector_potential(1, ip), real64) * psi(ip, 2)
486 vpsi(ip, 2) = vpsi(ip, 2) - &
487 (this%rashba_coupling) * cmplx(this%vector_potential(2, ip), -this%vector_potential(1, ip), real64) * psi(ip, 1)
492 vpsi(ip, 1) = vpsi(ip, 1) - &
493 this%rashba_coupling*( grad(ip, 1, 2) - m_zi*grad(ip, 2, 2))
494 vpsi(ip, 2) = vpsi(ip, 2) + &
495 this%rashba_coupling*( grad(ip, 1, 1) + m_zi*grad(ip, 2, 1))
498 call batch_set_state(vpsib, ist, mesh%np, vpsi)
501 safe_deallocate_a(grad)
502 safe_deallocate_a(vpsi)
503 safe_deallocate_a(psi)
510#include "hamiltonian_elec_base_inc.F90"
513#include "complex.F90"
514#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 hamiltonian_elec_base_accel_copy_pot(this, mesh)
copy the potential to the acceleration device buffer
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
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.