68 real(real64) :: rashba_coupling
69 type(nl_operator_t),
pointer,
public :: kinetic
70 real(real64),
allocatable,
public :: potential(:, :)
71 real(real64),
allocatable,
public :: Impotential(:, :)
72 real(real64),
allocatable,
public :: uniform_magnetic_field(:)
74 real(real64),
allocatable,
public :: magnetic_field(:, :)
76 real(real64),
allocatable,
public :: zeeman_pot(:, :)
77 real(real64),
allocatable,
public :: uniform_vector_potential(:)
81 real(real64),
allocatable,
public :: vector_potential(:, :)
82 type(accel_mem_t) :: potential_accel
83 type(accel_mem_t) :: impotential_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
158 class(hamiltonian_elec_base_t),
intent(inout) :: this
164 if (
allocated(this%Impotential))
then
169 safe_deallocate_a(this%potential)
170 safe_deallocate_a(this%Impotential)
171 safe_deallocate_a(this%vector_potential)
172 safe_deallocate_a(this%uniform_vector_potential)
173 safe_deallocate_a(this%uniform_magnetic_field)
174 safe_deallocate_a(this%magnetic_field)
175 safe_deallocate_a(this%zeeman_pot)
187 integer,
intent(in) :: np
191 push_sub(hamiltonian_elec_clear)
193 if (
allocated(this%potential))
then
194 do ispin = 1, this%nspin
202 if (
allocated(this%Impotential))
then
203 do ispin = 1, this%nspin
206 this%Impotential(ip, ispin) =
m_zero
211 if (
allocated(this%uniform_vector_potential))
then
212 this%uniform_vector_potential =
m_zero
215 if (
allocated(this%vector_potential))
then
216 this%vector_potential =
m_zero
219 if (
allocated(this%uniform_magnetic_field))
then
220 this%uniform_magnetic_field =
m_zero
223 if (
allocated(this%magnetic_field))
then
224 this%magnetic_field =
m_zero
227 if (
allocated(this%zeeman_pot))
then
231 pop_sub(hamiltonian_elec_clear)
240 class(
mesh_t),
intent(in) :: mesh
241 integer,
intent(in) :: field
242 logical,
intent(in) :: complex_potential
248 if (
bitand(field_potential, field) /= 0)
then
249 if (.not.
allocated(this%potential))
then
250 safe_allocate(this%potential(1:mesh%np, 1:this%nspin))
251 do ispin = 1, this%nspin
254 this%potential(ip, ispin) =
m_zero
257 if (complex_potential)
then
258 safe_allocate(this%Impotential(1:mesh%np, 1:this%nspin))
259 do ispin = 1, this%nspin
262 this%Impotential(ip, ispin) =
m_zero
268 if (complex_potential)
then
277 if (.not.
allocated(this%uniform_vector_potential))
then
278 safe_allocate(this%uniform_vector_potential(1:mesh%box%dim))
279 this%uniform_vector_potential =
m_zero
284 if (.not.
allocated(this%vector_potential))
then
285 safe_allocate(this%vector_potential(1:mesh%box%dim, 1:mesh%np))
286 this%vector_potential =
m_zero
291 if (.not.
allocated(this%uniform_magnetic_field))
then
292 safe_allocate(this%uniform_magnetic_field(1:max(mesh%box%dim, 3)))
293 this%uniform_magnetic_field =
m_zero
299 if (.not.
allocated(this%magnetic_field))
then
300 safe_allocate(this%magnetic_field(1:mesh%np, 1:max(mesh%box%dim, 3)))
301 this%magnetic_field =
m_zero
302 safe_allocate(this%zeeman_pot(1:mesh%np, 1:this%nspin))
320 class(
mesh_t),
intent(in) :: mesh
321 real(real64),
intent(in) :: gyromagnetic_ratio
322 integer,
intent(in) :: ispin
324 real(real64) :: b_norm2, cc
329 if (
allocated(this%uniform_vector_potential) .and.
allocated(this%vector_potential))
then
331 do idir = 1, mesh%box%dim
334 this%vector_potential(idir, ip) = &
335 this%vector_potential(idir, ip) + this%uniform_vector_potential(idir)
338 safe_deallocate_a(this%uniform_vector_potential)
342 if (.not.
allocated(this%magnetic_field))
then
355 if (
allocated(this%uniform_magnetic_field) )
then
360 this%magnetic_field(ip, idir) = this%magnetic_field(ip, idir) + this%uniform_magnetic_field(idir)
371 b_norm2 = norm2(this%magnetic_field(ip, 1:max(mesh%box%dim, 3)))
372 this%zeeman_pot(ip, 1) = cc*b_norm2
373 this%zeeman_pot(ip, 2) = - cc*b_norm2
379 this%zeeman_pot(ip, 1) = cc*this%magnetic_field(ip, 3)
380 this%zeeman_pot(ip, 2) = - cc*this%magnetic_field(ip, 3)
381 this%zeeman_pot(ip, 3) = cc*this%magnetic_field(ip, 1)
382 this%zeeman_pot(ip, 4) = - cc*this%magnetic_field(ip, 2)
385 safe_deallocate_a(this%uniform_magnetic_field)
396 class(
mesh_t),
intent(in) :: mesh
398 integer :: offset, ispin
404 do ispin = 1, this%nspin
405 call accel_write_buffer(this%potential_accel, mesh%np, this%potential(:, ispin), offset = offset)
406 if(
allocated(this%Impotential))
then
407 call accel_write_buffer(this%impotential_accel, mesh%np, this%Impotential(:, ispin), offset = offset)
420 class(
mesh_t),
intent(in) :: mesh
422 logical :: complex_potential
434 if (.not.
allocated(this%potential))
then
439 complex_potential =
allocated(this%Impotential)
443 if (complex_potential)
then
448 call this%accel_copy_pot(mesh)
456 logical pure function hamiltonian_elec_base_has_magnetic(this) result(has_magnetic)
459 has_magnetic =
allocated(this%vector_potential) &
460 .or.
allocated(this%uniform_magnetic_field)
467 logical pure function hamiltonian_elec_base_has_zeeman(this) result(has_zeeman)
470 has_zeeman =
allocated(this%zeeman_pot)
477 logical pure function hamiltonian_elec_base_has_vector_potential(this) result(has_vector_potential)
480 has_vector_potential =
allocated(this%vector_potential) &
481 .or.
allocated(this%uniform_vector_potential)
488 class(mesh_t),
intent(in) :: mesh
489 type(derivatives_t),
intent(in) :: der
490 type(states_elec_dim_t),
intent(in) :: std
491 type(wfs_elec_t),
target,
intent(in) :: psib
492 type(wfs_elec_t),
target,
intent(inout) :: vpsib
494 integer :: ist, idim, ip
495 complex(real64),
allocatable :: psi(:, :), vpsi(:, :), grad(:, :, :)
499 if (abs(this%rashba_coupling) < m_epsilon)
then
503 assert(std%ispin == spinors)
504 assert(mesh%box%dim == 2)
505 assert(psib%type() == type_cmplx)
506 assert(vpsib%type() == type_cmplx)
508 safe_allocate(psi(1:mesh%np_part, 1:std%dim))
509 safe_allocate(vpsi(1:mesh%np, 1:std%dim))
510 safe_allocate(grad(1:mesh%np, 1:mesh%box%dim, 1:std%dim))
513 call batch_get_state(psib, ist, mesh%np_part, psi)
514 call batch_get_state(vpsib, ist, mesh%np, vpsi)
517 call zderivatives_grad(der, psi(:, idim), grad(:, :, idim), ghost_update = .false., set_bc = .false.)
520 if (
allocated(this%vector_potential))
then
522 vpsi(ip, 1) = vpsi(ip, 1) - &
523 (this%rashba_coupling) * cmplx(this%vector_potential(2, ip), this%vector_potential(1, ip), real64) * psi(ip, 2)
524 vpsi(ip, 2) = vpsi(ip, 2) - &
525 (this%rashba_coupling) * cmplx(this%vector_potential(2, ip), -this%vector_potential(1, ip), real64) * psi(ip, 1)
530 vpsi(ip, 1) = vpsi(ip, 1) - &
531 this%rashba_coupling*( grad(ip, 1, 2) - m_zi*grad(ip, 2, 2))
532 vpsi(ip, 2) = vpsi(ip, 2) + &
533 this%rashba_coupling*( grad(ip, 1, 1) + m_zi*grad(ip, 2, 1))
536 call batch_set_state(vpsib, ist, mesh%np, vpsi)
539 safe_deallocate_a(grad)
540 safe_deallocate_a(vpsi)
541 safe_deallocate_a(psi)
548#include "hamiltonian_elec_base_inc.F90"
551#include "complex.F90"
552#include "hamiltonian_elec_base_inc.F90"
subroutine, public accel_free_buffer(this, async)
subroutine, public accel_detach_buffer(this)
Clear a buffer handle without freeing device memory.
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)
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 zhamiltonian_elec_base_magnetic(this, mesh, der, std, ispin, psib, vpsib)
apply magnetic terms form the Hamiltonian to the wave functions
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
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
subroutine dhamiltonian_elec_base_magnetic(this, mesh, der, std, ispin, psib, vpsib)
apply magnetic terms form the Hamiltonian to the wave functions
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, public hamiltonian_elec_base_accel_rebuild(this, mesh)
Rebuild accelerator buffers after an intrinsic copy.
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.