34 use,
intrinsic :: iso_fortran_env
64 logical :: include_diamag
76 integer,
parameter,
public :: &
77 CURRENT_GRADIENT = 1, &
84 type(current_t),
intent(out) :: this
85 type(namespace_t),
intent(in) :: namespace
124 call parse_variable(namespace,
'CalculateDiamagneticCurrent', .false., this%include_diamag)
132 type(states_elec_t),
intent(inout) :: st
133 type(derivatives_t),
intent(inout) :: der
134 integer,
intent(in) :: ik
135 integer,
intent(in) :: ib
136 type(wfs_elec_t),
intent(in) :: psib
137 class(wfs_elec_t),
intent(in) :: gpsib(:)
139 integer :: ist, idir, ii, ip, idim, wgsize
140 complex(real64),
allocatable :: psi(:, :), gpsi(:, :)
141 real(real64),
allocatable :: current_tmp(:, :)
142 complex(real64) :: c_tmp
144 real(real64),
allocatable :: weight(:)
145 type(accel_mem_t) :: buff_weight, buff_current
146 type(accel_kernel_t),
save :: kernel
148 safe_allocate(psi(1:der%mesh%np_part, 1:st%d%dim))
149 safe_allocate(gpsi(1:der%mesh%np_part, 1:st%d%dim))
156 ww = st%kweights(ik)*st%occ(ist, ik)
159 do idim = 1, st%d%dim
160 ii = st%group%psib(ib, ik)%inv_index((/ist, idim/))
165 if (st%d%ispin /=
spinors)
then
167 do ip = 1, der%mesh%np
168 st%current_kpt(ip, idir, ik) = st%current_kpt(ip, idir, ik) + ww*aimag(conjg(psi(ip, 1))*gpsi(ip, 1))
173 do ip = 1, der%mesh%np
174 st%current_para(ip, idir, 1) = st%current_para(ip, idir, 1) + ww*aimag(conjg(psi(ip, 1))*gpsi(ip, 1))
175 st%current_para(ip, idir, 2) = st%current_para(ip, idir, 2) + ww*aimag(conjg(psi(ip, 2))*gpsi(ip, 2))
176 c_tmp = -
m_half*
m_zi*(conjg(psi(ip, 2))*gpsi(ip, 1) - psi(ip, 1)*conjg(gpsi(ip, 2)))
177 st%current_para(ip, idir, 3) = st%current_para(ip, idir, 3) + ww*real(c_tmp, real64)
178 st%current_para(ip, idir, 4) = st%current_para(ip, idir, 4) + ww*aimag(c_tmp)
190 safe_allocate(weight(1:psib%nst))
192 weight(ist) = st%kweights(ik)*st%occ(psib%ist(ist), ik)
218 safe_allocate(current_tmp(1:der%mesh%np, 1:der%dim))
222 call lalg_axpy(der%mesh%np, der%dim,
m_one, current_tmp, st%current_kpt(:,:,ik))
224 safe_deallocate_a(current_tmp)
229 safe_deallocate_a(weight)
233 assert(psib%is_packed() .eqv. gpsib(1)%is_packed())
238 ww = st%kweights(ik)*st%occ(ist, ik)
241 if (psib%is_packed())
then
244 do ip = 1, der%mesh%np
245 st%current_kpt(ip, idir, ik) = st%current_kpt(ip, idir, ik) &
246 + ww*aimag(conjg(psib%zff_pack(ii, ip))*gpsib(idir)%zff_pack(ii, ip))
253 do ip = 1, der%mesh%np
254 st%current_kpt(ip, idir, ik) = st%current_kpt(ip, idir, ik) &
255 + ww*aimag(conjg(psib%zff(ip, 1, ii))*gpsib(idir)%zff(ip, 1, ii))
265 safe_deallocate_a(psi)
266 safe_deallocate_a(gpsi)
276 type(
grid_t),
intent(inout) :: gr
278 class(
space_t),
intent(in) :: space
286 st%current = st%current_para
288 if (this%include_diamag)
then
290 st%current = st%current + st%current_dia
306 integer :: ispin, idir, ip
313 if(
allocated(hm%hm_base%vector_potential))
then
314 do ispin = 1, st%d%nspin
317 do ip = 1, der%mesh%np
319 st%current_dia(ip, idir, ispin) = st%current_dia(ip, idir, ispin) + &
320 st%rho(ip, ispin)*hm%hm_base%vector_potential(idir, ip)
341 real(real64),
allocatable :: magnetization_density(:, :), curl_mag(:, :)
349 safe_allocate(magnetization_density(1:der%mesh%np_part, 1:der%dim))
350 safe_allocate(curl_mag(1:der%mesh%np_part, 1:der%dim))
357 do ip = 1, der%mesh%np
358 st%current_mag(ip, idir, 1) = st%current_mag(ip, idir, 1) +
m_half * curl_mag(ip, idir)
363 safe_deallocate_a(magnetization_density)
364 safe_deallocate_a(curl_mag)
378 type(
grid_t),
intent(inout) :: gr
380 class(
space_t),
intent(in) :: space
383 integer :: ik, ist, idir, idim, ip, ib, ii, ispin
384 complex(real64),
allocatable :: gpsi(:, :, :), psi(:, :), hpsi(:, :), rhpsi(:, :), rpsi(:, :), hrpsi(:, :)
385 type(
wfs_elec_t) :: hpsib, rhpsib, rpsib, hrpsib, epsib
388 complex(real64) :: c_tmp
394 assert(all(ubound(st%current_para) == (/gr%np_part, gr%der%dim, st%d%nspin/)))
395 assert(all(ubound(st%current_kpt) == (/gr%np, gr%der%dim, st%d%kpt%end/)))
396 assert(all(lbound(st%current_kpt) == (/1, 1, st%d%kpt%start/)))
398 safe_allocate(psi(1:gr%np_part, 1:st%d%dim))
399 safe_allocate(gpsi(1:gr%np, 1:gr%der%dim, 1:st%d%dim))
400 safe_allocate(hpsi(1:gr%np_part, 1:st%d%dim))
401 safe_allocate(rhpsi(1:gr%np_part, 1:st%d%dim))
402 safe_allocate(rpsi(1:gr%np_part, 1:st%d%dim))
403 safe_allocate(hrpsi(1:gr%np_part, 1:st%d%dim))
404 safe_allocate_type_array(
wfs_elec_t, commpsib, (1:gr%der%dim))
407 do ik = st%d%kpt%start, st%d%kpt%end
408 do idir = 1, gr%der%dim
411 st%current_kpt(ip, idir, ik) =
m_zero
416 do ispin = 1, st%d%nspin
417 do idir = 1, gr%der%dim
420 st%current_para(ip, idir, ispin) =
m_zero
427 select case (this%method)
431 do ik = st%d%kpt%start, st%d%kpt%end
432 ispin = st%d%get_spin_index(ik)
433 do ib = st%group%block_start, st%group%block_end
435 call st%group%psib(ib, ik)%do_pack(copy = .
true.)
437 call st%group%psib(ib, ik)%copy_to(hpsib)
438 call st%group%psib(ib, ik)%copy_to(rhpsib)
439 call st%group%psib(ib, ik)%copy_to(rpsib)
440 call st%group%psib(ib, ik)%copy_to(hrpsib)
445 do idir = 1, gr%der%dim
447 call batch_mul(gr%np, gr%x(:, idir), hpsib, rhpsib)
448 call batch_mul(gr%np_part, gr%x(:, idir), st%group%psib(ib, ik), rpsib)
453 ww = st%kweights(ik)*st%occ(ist, ik)
456 do idim = 1, st%d%dim
457 ii = st%group%psib(ib, ik)%inv_index((/ist, idim/))
463 if (st%d%ispin /=
spinors)
then
466 st%current_kpt(ip, idir, ik) = st%current_kpt(ip, idir, ik) &
467 - ww*aimag(conjg(psi(ip, 1))*hrpsi(ip, 1) - conjg(psi(ip, 1))*rhpsi(ip, 1))
473 st%current_para(ip, idir, 1) = st%current_para(ip, idir, 1) + &
474 ww*aimag(conjg(psi(ip, 1))*hrpsi(ip, 1) - conjg(psi(ip, 1))*rhpsi(ip, 1))
475 st%current_para(ip, idir, 2) = st%current_para(ip, idir, 2) + &
476 ww*aimag(conjg(psi(ip, 2))*hrpsi(ip, 2) - conjg(psi(ip, 2))*rhpsi(ip, 2))
477 c_tmp = -
m_half*
m_zi*(conjg(psi(ip, 2))*hrpsi(ip, 1) - conjg(psi(ip, 2))*rhpsi(ip, 1) &
478 -psi(ip, 1)*conjg(hrpsi(ip, 2)) - psi(ip, 1)*conjg(rhpsi(ip, 2)))
479 st%current_para(ip, idir, 3) = st%current_para(ip, idir, 3) + ww*real(c_tmp, real64)
480 st%current_para(ip, idir, 4) = st%current_para(ip, idir, 4) + ww*aimag(c_tmp)
489 call st%group%psib(ib, ik)%do_unpack(copy = .false.)
504 .and. hm%theory_level /=
rdmft &
505 .and. hm%vnl%apply_projector_matrices)
then
509 do ik = st%d%kpt%start, st%d%kpt%end
510 ispin = st%d%get_spin_index(ik)
511 do ib = st%group%block_start, st%group%block_end
519 call hm%vnl%zposition_commutator(gr, st%d, gr%der%boundaries%spiral, epsib, commpsib, async=.
true.)
521 call zlda_u_commute_r(hm%lda_u, gr, space, st%d, namespace, epsib, commpsib)
525 do idir = 1, gr%der%dim
526 call commpsib(idir)%end()
539 do ik = st%d%kpt%start, st%d%kpt%end
540 ispin = st%d%get_spin_index(ik)
541 do ist = st%st_start, st%st_end
543 ww = st%kweights(ik)*st%occ(ist, ik)
548 if (hm%phase%is_allocated())
then
549 call hm%phase%apply_to_single(psi, gr%np, st%d%dim, ik, .false.)
552 do idim = 1, st%d%dim
553 call boundaries_set(gr%der%boundaries, gr, psi(:, idim), phase_correction = hm%phase%phase_corr(:, ik), &
554 buff_phase_corr = hm%phase%buff_phase_corr, offset=int((ik-st%d%kpt%start)*(gr%np_part-gr%np)))
557 do idim = 1, st%d%dim
562 do idim = 1, st%d%dim
570 do idim = 1, st%d%dim
571 do idir = 1, gr%der%dim
574 gpsi(ip, idir, idim) = (
m_one+
m_two*hm%vtau(ip,ispin))*gpsi(ip, idir, idim)
583 gr%der%boundaries, ik, psi, gpsi)
585 if (hm%scissor%apply)
then
590 psi, gpsi, hm%phase%is_allocated())
596 if (st%d%ispin /=
spinors)
then
597 do idir = 1, gr%der%dim
600 st%current_kpt(ip, idir, ik) = st%current_kpt(ip, idir, ik) + &
601 ww*aimag(conjg(psi(ip, 1))*gpsi(ip, idir, 1))
606 do idir = 1, gr%der%dim
609 st%current_para(ip, idir, 1) = st%current_para(ip, idir, 1) + &
610 ww*aimag(conjg(psi(ip, 1))*gpsi(ip, idir, 1))
611 st%current_para(ip, idir, 2) = st%current_para(ip, idir, 2) + &
612 ww*aimag(conjg(psi(ip, 2))*gpsi(ip, idir, 2))
613 c_tmp = -
m_half*
m_zi*(conjg(psi(ip, 2))*gpsi(ip, idir, 1) - psi(ip, 1)*conjg(gpsi(ip, idir, 2)))
614 st%current_para(ip, idir, 3) = st%current_para(ip, idir, 3) + ww*real(c_tmp, real64)
615 st%current_para(ip, idir, 4) = st%current_para(ip, idir, 4) + ww*aimag(c_tmp)
632 if (st%d%ispin /=
spinors)
then
634 do ik = st%d%kpt%start, st%d%kpt%end
635 ispin = st%d%get_spin_index(ik)
636 call lalg_axpy(gr%np, gr%der%dim,
m_one, st%current_kpt(:, :, ik), st%current_para(:, :, ispin))
640 if (st%parallel_in_states .or. st%d%kpt%parallel)
then
641 call comm_allreduce(st%st_kpt_mpi_grp, st%current_para, dim = (/gr%np, gr%der%dim, st%d%nspin/))
644 if (st%symmetrize_density)
then
645 do ispin = 1, st%d%nspin
650 safe_deallocate_a(gpsi)
651 safe_deallocate_a(psi)
652 safe_deallocate_a(hpsi)
653 safe_deallocate_a(rhpsi)
654 safe_deallocate_a(rpsi)
655 safe_deallocate_a(hrpsi)
656 safe_deallocate_a(commpsib)
673 complex(real64),
intent(in) :: psi_i(:,:)
674 complex(real64),
intent(in) :: psi_j(:,:)
675 integer,
intent(in) :: ik
676 complex(real64),
intent(out) :: cmel(:,:)
678 integer :: idir, idim, ip, ispin
679 complex(real64),
allocatable :: gpsi_j(:, :, :), ppsi_j(:,:), gpsi_i(:, :, :), ppsi_i(:,:)
683 safe_allocate(gpsi_i(1:der%mesh%np, 1:der%dim, 1:hm%d%dim))
684 safe_allocate(ppsi_i(1:der%mesh%np_part,1:hm%d%dim))
685 safe_allocate(gpsi_j(1:der%mesh%np, 1:der%dim, 1:hm%d%dim))
686 safe_allocate(ppsi_j(1:der%mesh%np_part,1:hm%d%dim))
690 ispin = hm%d%get_spin_index(ik)
692 ppsi_i(1:der%mesh%np,:) = psi_i(1:der%mesh%np,:)
694 ppsi_j(1:der%mesh%np,:) = psi_j(1:der%mesh%np,:)
697 do idim = 1, hm%d%dim
702 if (hm%phase%is_allocated())
then
704 call hm%phase%apply_to_single(ppsi_i, der%mesh%np_part, hm%d%dim, ik, .false.)
705 call hm%phase%apply_to_single(ppsi_j, der%mesh%np_part, hm%d%dim, ik, .false.)
708 do idim = 1, hm%d%dim
709 call zderivatives_grad(der, ppsi_i(:, idim), gpsi_i(:, :, idim), set_bc = .false.)
710 call zderivatives_grad(der, ppsi_j(:, idim), gpsi_j(:, :, idim), set_bc = .false.)
716 do idim = 1, hm%d%dim
719 do ip = 1, der%mesh%np
720 gpsi_i(ip, idir, idim) = (
m_one+
m_two*hm%vtau(ip,ispin))*gpsi_i(ip, idir, idim)
721 gpsi_j(ip, idir, idim) = (
m_one+
m_two*hm%vtau(ip,ispin))*gpsi_j(ip, idir, idim)
729 der%boundaries, ik, ppsi_i, gpsi_i)
731 der%boundaries, ik, ppsi_j, gpsi_j)
733 if (hm%scissor%apply)
then
743 do idim = 1, hm%d%dim
745 cmel(idir,ispin) =
m_zi *
zmf_dotp(der%mesh, psi_i(:, idim), gpsi_j(:, idir,idim), reduce = .false.)
746 cmel(idir,ispin) = cmel(idir,ispin) -
m_zi *
zmf_dotp(der%mesh, gpsi_i(:, idir, idim), psi_j(:, idim), reduce = .false.)
751 if (der%mesh%parallel_in_domains)
call der%mesh%allreduce(cmel)
755 safe_deallocate_a(gpsi_i)
756 safe_deallocate_a(ppsi_i)
757 safe_deallocate_a(gpsi_j)
758 safe_deallocate_a(ppsi_j)
766 class(
space_t),
intent(in) :: space
770 real(real64),
intent(out) :: current(:, :, :)
772 integer :: ik, ist, idir, idim, ip, ispin, ndim
773 complex(real64),
allocatable :: gpsi(:, :, :), psi(:, :), g2psi(:, :, :, :)
774 complex(real64) :: tmp
778 assert(space%is_periodic())
779 assert(st%d%dim == 1)
783 safe_allocate(psi(1:der%mesh%np_part, 1:st%d%dim))
784 safe_allocate(gpsi(1:der%mesh%np_part, 1:ndim, 1:st%d%dim))
785 safe_allocate(g2psi(1:der%mesh%np, 1:ndim, 1:ndim, 1:st%d%dim))
787 do ip = 1, der%mesh%np
788 current(ip, 1:ndim, 1:st%d%nspin) = st%current(ip, 1:ndim, 1:st%d%nspin)*hm%ep%vpsl(ip)
792 do ik = st%d%kpt%start, st%d%kpt%end
793 ispin = st%d%get_spin_index(ik)
794 do ist = st%st_start, st%st_end
796 if (abs(st%kweights(ik)*st%occ(ist, ik)) <=
m_epsilon) cycle
799 do idim = 1, st%d%dim
803 if (hm%phase%is_allocated())
then
804 call hm%phase%apply_to_single(psi, der%mesh%np_part, st%d%dim, ik, conjugate = .false.)
807 do idim = 1, st%d%dim
811 if (hm%phase%is_allocated())
then
812 call hm%phase%apply_to_single(gpsi(:, idir, :), der%mesh%np, st%d%dim, ik, conjugate = .
true.)
815 do idim = 1, st%d%dim
819 if (hm%phase%is_allocated())
then
820 call hm%phase%apply_to_single(gpsi(:, idir, :), der%mesh%np_part, st%d%dim, ik, conjugate = .false.)
823 do idim = 1, st%d%dim
824 call zderivatives_grad(der, gpsi(:, idir, idim), g2psi(:, :, idir, idim), set_bc = .false.)
828 do ip = 1, der%mesh%np
831 tmp = sum(conjg(g2psi(ip, 1:ndim, idir, idim))*gpsi(ip, 1:ndim, idim)) - &
832 sum(conjg(gpsi(ip, 1:ndim, idim))*g2psi(ip, 1:ndim, idir, idim))
833 tmp = tmp - conjg(gpsi(ip, idir, idim))*sum(g2psi(ip, 1:ndim, 1:ndim, idim)) + &
834 sum(conjg(g2psi(ip, 1:ndim, 1:ndim, idim)))*gpsi(ip, idir, idim)
835 current(ip, idir, ispin) = current(ip, idir, ispin) + st%kweights(ik)*st%occ(ist, ik)*aimag(tmp)/8.0_real64
constant times a vector plus a vector
subroutine, public accel_kernel_start_call(this, file_name, kernel_name, flags)
subroutine, public accel_finish()
subroutine, public accel_release_buffer(this)
integer, parameter, public accel_mem_write_only
integer function, public accel_kernel_workgroup_size(kernel)
integer, parameter, public accel_mem_read_only
This module implements batches of mesh functions.
integer, parameter, public batch_device_packed
functions are stored in device memory in packed order
This module implements common operations on batches of mesh functions.
Module implementing boundary conditions in Octopus.
subroutine current_batch_accumulate(st, der, ik, ib, psib, gpsib)
subroutine current_calculate_dia_non_unif_vec_pot(der, hm, st)
Compute diamagnetic current density from non-uniform vector potential (the part coming from the unifo...
subroutine, public current_calculate_mag(der, st)
Compute magnetization current Note: due to the the numerical curl, the magnetization current could de...
integer, parameter, public current_hamiltonian
integer, parameter, public current_gradient_corr
subroutine, public current_heat_calculate(space, der, hm, st, current)
subroutine current_calculate_para(this, namespace, gr, hm, space, st)
Compute paramagnetic current density (including full diamagnetic term if method = Hamiltonian us used...
subroutine, public current_calculate_mel(der, hm, psi_i, psi_j, ik, cmel)
subroutine, public current_calculate(this, namespace, gr, hm, space, st)
Compute total electronic current density.
subroutine, public current_init(this, namespace)
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public dderivatives_curl(der, ff, op_ff, ghost_update, set_bc)
apply the curl operator to a vector of mesh functions
subroutine, public zderivatives_batch_grad(der, ffb, opffb, ghost_update, set_bc, to_cartesian, metric, factor)
apply the gradient to a batch of mesh functions
subroutine, public zderivatives_grad(der, ff, op_ff, ghost_update, set_bc, to_cartesian)
apply the gradient to a mesh function
integer, parameter, public unpolarized
Parameters...
integer, parameter, public spinors
subroutine, public zexchange_operator_commute_r(this, namespace, mesh, st_d, ik, psi, gpsi)
real(real64), parameter, public m_two
real(real64), parameter, public m_zero
complex(real64), parameter, public m_z0
complex(real64), parameter, public m_zi
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_half
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
subroutine, public dgrid_symmetrize_vector_field(gr, field, suppress_warning)
integer, parameter, public generalized_kohn_sham_dft
integer, parameter, public rdmft
subroutine, public zhamiltonian_elec_apply_batch(hm, namespace, mesh, psib, hpsib, terms, set_bc)
subroutine, public hamiltonian_elec_copy_and_set_phase(hm, gr, kpt, psib, psib_with_phase)
Copy a batch to another batch and apply the Bloch phase to it.
integer, parameter, public hartree_fock
subroutine, public zlda_u_commute_r(this, mesh, space, d, namespace, psib, gpsib)
This routine computes [r,V_lda+u] .
subroutine, public zlda_u_commute_r_single(this, mesh, space, d, namespace, ist, ik, psi, gpsi, has_phase)
subroutine, public magnetic_density(mesh, std, rho, md)
This module is intended to contain "only mathematical" functions and procedures.
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
subroutine, public messages_input_error(namespace, var, details, row, column)
subroutine, public messages_experimental(name, namespace)
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
subroutine, public zprojector_commute_r_allatoms_alldir(pj, ions, mesh, dim, bnd, ik, psi, cpsi)
This function calculates |cpsi> += [x, V_nl] |psi>
integer pure function, public states_elec_block_max(st, ib)
return index of last state in block ib
integer pure function, public states_elec_block_min(st, ib)
return index of first state in block ib
type(type_t), public type_float
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
This module defines the unit system, used for input and output.
logical pure function, public family_is_mgga_with_exc(xcs)
Is the xc function part of the mGGA family with an energy functional.
class representing derivatives
Description of the grid, containing information on derivatives, stencil, and symmetries.
The states_elec_t class contains all electronic wave functions.
batches of electronic states