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
219 this%uniform_magnetic_field =
m_zero
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)
419 class(
mesh_t),
intent(in) :: mesh
421 logical :: complex_potential
433 if (.not.
allocated(this%potential))
then
438 complex_potential =
allocated(this%Impotential)
442 if (complex_potential)
then
447 call this%accel_copy_pot(mesh)
455 logical pure function hamiltonian_elec_base_has_magnetic(this) result(has_magnetic)
458 has_magnetic =
allocated(this%vector_potential) &
459 .or.
allocated(this%uniform_magnetic_field) &
460 .or.
allocated(this%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), parameter, public type_float
The basic Hamiltonian for electronic system.
Describes mesh distribution to nodes.