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.