34 use,
intrinsic :: iso_fortran_env
65 logical :: include_diamag
77 integer,
parameter,
public :: &
78 CURRENT_GRADIENT = 1, &
85 type(current_t),
intent(out) :: this
86 type(namespace_t),
intent(in) :: namespace
125 call parse_variable(namespace,
'CalculateDiamagneticCurrent', .false., this%include_diamag)
133 type(states_elec_t),
intent(inout) :: st
134 type(derivatives_t),
intent(inout) :: der
135 integer,
intent(in) :: ik
136 integer,
intent(in) :: ib
137 type(wfs_elec_t),
intent(in) :: psib
138 class(wfs_elec_t),
intent(in) :: gpsib(:)
140 integer :: ist, idir, ii, ip, idim, wgsize
141 complex(real64),
allocatable :: psi(:, :), gpsi(:, :)
142 real(real64),
allocatable :: current_tmp(:, :)
143 complex(real64) :: c_tmp
145 real(real64),
allocatable :: weight(:)
146 type(accel_mem_t) :: buff_weight, buff_current
147 type(accel_kernel_t),
save :: kernel
149 safe_allocate(psi(1:der%mesh%np_part, 1:st%d%dim))
150 safe_allocate(gpsi(1:der%mesh%np_part, 1:st%d%dim))
157 ww = st%kweights(ik)*st%occ(ist, ik)
160 do idim = 1, st%d%dim
161 ii = st%group%psib(ib, ik)%inv_index((/ist, idim/))
166 if (st%d%ispin /=
spinors)
then
168 do ip = 1, der%mesh%np
169 st%current_kpt(ip, idir, ik) = st%current_kpt(ip, idir, ik) + ww*aimag(conjg(psi(ip, 1))*gpsi(ip, 1))
174 do ip = 1, der%mesh%np
175 st%current_para(ip, idir, 1) = st%current_para(ip, idir, 1) + ww*aimag(conjg(psi(ip, 1))*gpsi(ip, 1))
176 st%current_para(ip, idir, 2) = st%current_para(ip, idir, 2) + ww*aimag(conjg(psi(ip, 2))*gpsi(ip, 2))
177 c_tmp = -
m_half*
m_zi*(conjg(psi(ip, 2))*gpsi(ip, 1) - psi(ip, 1)*conjg(gpsi(ip, 2)))
178 st%current_para(ip, idir, 3) = st%current_para(ip, idir, 3) + ww*real(c_tmp, real64)
179 st%current_para(ip, idir, 4) = st%current_para(ip, idir, 4) + ww*aimag(c_tmp)
191 safe_allocate(weight(1:psib%nst))
193 weight(ist) = st%kweights(ik)*st%occ(psib%ist(ist), ik)
219 safe_allocate(current_tmp(1:der%mesh%np, 1:der%dim))
223 call lalg_axpy(der%mesh%np, der%dim,
m_one, current_tmp, st%current_kpt(:,:,ik))
225 safe_deallocate_a(current_tmp)
230 safe_deallocate_a(weight)
234 assert(psib%is_packed() .eqv. gpsib(1)%is_packed())
239 ww = st%kweights(ik)*st%occ(ist, ik)
242 if (psib%is_packed())
then
245 do ip = 1, der%mesh%np
246 st%current_kpt(ip, idir, ik) = st%current_kpt(ip, idir, ik) &
247 + ww*aimag(conjg(psib%zff_pack(ii, ip))*gpsib(idir)%zff_pack(ii, ip))
254 do ip = 1, der%mesh%np
255 st%current_kpt(ip, idir, ik) = st%current_kpt(ip, idir, ik) &
256 + ww*aimag(conjg(psib%zff(ip, 1, ii))*gpsib(idir)%zff(ip, 1, ii))
266 safe_deallocate_a(psi)
267 safe_deallocate_a(gpsi)
277 type(
grid_t),
intent(inout) :: gr
279 class(
space_t),
intent(in) :: space
287 st%current = st%current_para
289 if (this%include_diamag)
then
291 st%current = st%current + st%current_dia
307 integer :: ispin, idir, ip
314 if(
allocated(hm%hm_base%vector_potential))
then
315 do ispin = 1, st%d%nspin
318 do ip = 1, der%mesh%np
320 st%current_dia(ip, idir, ispin) = st%current_dia(ip, idir, ispin) + &
321 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))
355 call lalg_axpy(der%mesh%np, der%dim,
m_half, curl_mag, st%current_mag(:, :, 1))
357 safe_deallocate_a(magnetization_density)
358 safe_deallocate_a(curl_mag)
372 type(
grid_t),
intent(inout) :: gr
374 class(
space_t),
intent(in) :: space
377 integer :: ik, ist, idir, idim, ip, ib, ii, ispin
378 complex(real64),
allocatable :: gpsi(:, :, :), psi(:, :), hpsi(:, :), rhpsi(:, :), rpsi(:, :), hrpsi(:, :)
379 type(
wfs_elec_t) :: hpsib, rhpsib, rpsib, hrpsib, epsib
382 complex(real64) :: c_tmp
388 assert(all(ubound(st%current_para) == (/gr%np_part, gr%der%dim, st%d%nspin/)))
389 assert(all(ubound(st%current_kpt) == (/gr%np, gr%der%dim, st%d%kpt%end/)))
390 assert(all(lbound(st%current_kpt) == (/1, 1, st%d%kpt%start/)))
392 safe_allocate(psi(1:gr%np_part, 1:st%d%dim))
393 safe_allocate(gpsi(1:gr%np, 1:gr%der%dim, 1:st%d%dim))
394 safe_allocate(hpsi(1:gr%np_part, 1:st%d%dim))
395 safe_allocate(rhpsi(1:gr%np_part, 1:st%d%dim))
396 safe_allocate(rpsi(1:gr%np_part, 1:st%d%dim))
397 safe_allocate(hrpsi(1:gr%np_part, 1:st%d%dim))
398 safe_allocate_type_array(
wfs_elec_t, commpsib, (1:gr%der%dim))
401 do ik = st%d%kpt%start, st%d%kpt%end
402 do idir = 1, gr%der%dim
405 st%current_kpt(ip, idir, ik) =
m_zero
410 do ispin = 1, st%d%nspin
411 do idir = 1, gr%der%dim
414 st%current_para(ip, idir, ispin) =
m_zero
421 select case (this%method)
425 do ik = st%d%kpt%start, st%d%kpt%end
426 ispin = st%d%get_spin_index(ik)
427 do ib = st%group%block_start, st%group%block_end
429 call st%group%psib(ib, ik)%do_pack(copy = .
true.)
431 call st%group%psib(ib, ik)%copy_to(hpsib)
432 call st%group%psib(ib, ik)%copy_to(rhpsib)
433 call st%group%psib(ib, ik)%copy_to(rpsib)
434 call st%group%psib(ib, ik)%copy_to(hrpsib)
439 do idir = 1, gr%der%dim
441 call batch_mul(gr%np, gr%x(:, idir), hpsib, rhpsib)
442 call batch_mul(gr%np_part, gr%x(:, idir), st%group%psib(ib, ik), rpsib)
447 ww = st%kweights(ik)*st%occ(ist, ik)
450 do idim = 1, st%d%dim
451 ii = st%group%psib(ib, ik)%inv_index((/ist, idim/))
457 if (st%d%ispin /=
spinors)
then
460 st%current_kpt(ip, idir, ik) = st%current_kpt(ip, idir, ik) &
461 - ww*aimag(conjg(psi(ip, 1))*hrpsi(ip, 1) - conjg(psi(ip, 1))*rhpsi(ip, 1))
467 st%current_para(ip, idir, 1) = st%current_para(ip, idir, 1) + &
468 ww*aimag(conjg(psi(ip, 1))*hrpsi(ip, 1) - conjg(psi(ip, 1))*rhpsi(ip, 1))
469 st%current_para(ip, idir, 2) = st%current_para(ip, idir, 2) + &
470 ww*aimag(conjg(psi(ip, 2))*hrpsi(ip, 2) - conjg(psi(ip, 2))*rhpsi(ip, 2))
471 c_tmp = -
m_half*
m_zi*(conjg(psi(ip, 2))*hrpsi(ip, 1) - conjg(psi(ip, 2))*rhpsi(ip, 1) &
472 -psi(ip, 1)*conjg(hrpsi(ip, 2)) - psi(ip, 1)*conjg(rhpsi(ip, 2)))
473 st%current_para(ip, idir, 3) = st%current_para(ip, idir, 3) + ww*real(c_tmp, real64)
474 st%current_para(ip, idir, 4) = st%current_para(ip, idir, 4) + ww*aimag(c_tmp)
483 call st%group%psib(ib, ik)%do_unpack(copy = .false.)
498 .and. hm%theory_level /=
rdmft &
499 .and. hm%vnl%apply_projector_matrices)
then
503 do ik = st%d%kpt%start, st%d%kpt%end
504 ispin = st%d%get_spin_index(ik)
505 do ib = st%group%block_start, st%group%block_end
513 call hm%vnl%zposition_commutator(gr, st%d, gr%der%boundaries%spiral, epsib, commpsib, async=.
true.)
515 call zlda_u_commute_r(hm%lda_u, gr, space, st%d, namespace, epsib, commpsib)
519 do idir = 1, gr%der%dim
520 call commpsib(idir)%end()
533 do ik = st%d%kpt%start, st%d%kpt%end
534 ispin = st%d%get_spin_index(ik)
535 do ist = st%st_start, st%st_end
537 ww = st%kweights(ik)*st%occ(ist, ik)
542 if (hm%phase%is_allocated())
then
543 call hm%phase%apply_to_single(psi, gr%np, st%d%dim, ik, .false.)
546 do idim = 1, st%d%dim
547 call boundaries_set(gr%der%boundaries, gr, psi(:, idim), phase_correction = hm%phase%phase_corr(:, ik), &
548 buff_phase_corr = hm%phase%buff_phase_corr, offset=int((ik-st%d%kpt%start)*(gr%np_part-gr%np)))
551 do idim = 1, st%d%dim
556 do idim = 1, st%d%dim
563 call hm%ks_pot%zcurrent_mass_renormalization(gpsi, gr%der%dim, st%d%dim, ispin)
567 gr%der%boundaries, ik, psi, gpsi)
569 if (hm%scissor%apply)
then
574 psi, gpsi, hm%phase%is_allocated())
580 if (st%d%ispin /=
spinors)
then
581 do idir = 1, gr%der%dim
584 st%current_kpt(ip, idir, ik) = st%current_kpt(ip, idir, ik) + &
585 ww*aimag(conjg(psi(ip, 1))*gpsi(ip, idir, 1))
590 do idir = 1, gr%der%dim
593 st%current_para(ip, idir, 1) = st%current_para(ip, idir, 1) + &
594 ww*aimag(conjg(psi(ip, 1))*gpsi(ip, idir, 1))
595 st%current_para(ip, idir, 2) = st%current_para(ip, idir, 2) + &
596 ww*aimag(conjg(psi(ip, 2))*gpsi(ip, idir, 2))
597 c_tmp = -
m_half*
m_zi*(conjg(psi(ip, 2))*gpsi(ip, idir, 1) - psi(ip, 1)*conjg(gpsi(ip, idir, 2)))
598 st%current_para(ip, idir, 3) = st%current_para(ip, idir, 3) + ww*real(c_tmp, real64)
599 st%current_para(ip, idir, 4) = st%current_para(ip, idir, 4) + ww*aimag(c_tmp)
616 if (st%d%ispin /=
spinors)
then
618 do ik = st%d%kpt%start, st%d%kpt%end
619 ispin = st%d%get_spin_index(ik)
620 call lalg_axpy(gr%np, gr%der%dim,
m_one, st%current_kpt(:, :, ik), st%current_para(:, :, ispin))
624 if (st%parallel_in_states .or. st%d%kpt%parallel)
then
625 call comm_allreduce(st%st_kpt_mpi_grp, st%current_para, dim = (/gr%np, gr%der%dim, st%d%nspin/))
628 if (st%symmetrize_density)
then
629 do ispin = 1, st%d%nspin
634 safe_deallocate_a(gpsi)
635 safe_deallocate_a(psi)
636 safe_deallocate_a(hpsi)
637 safe_deallocate_a(rhpsi)
638 safe_deallocate_a(rpsi)
639 safe_deallocate_a(hrpsi)
640 safe_deallocate_a(commpsib)
657 complex(real64),
intent(in) :: psi_i(:,:)
658 complex(real64),
intent(in) :: psi_j(:,:)
659 integer,
intent(in) :: ik
660 complex(real64),
intent(out) :: cmel(:,:)
662 integer :: idir, idim, ispin
663 complex(real64),
allocatable :: gpsi_j(:, :, :), ppsi_j(:,:), gpsi_i(:, :, :), ppsi_i(:,:)
667 safe_allocate(gpsi_i(1:der%mesh%np, 1:der%dim, 1:hm%d%dim))
668 safe_allocate(ppsi_i(1:der%mesh%np_part,1:hm%d%dim))
669 safe_allocate(gpsi_j(1:der%mesh%np, 1:der%dim, 1:hm%d%dim))
670 safe_allocate(ppsi_j(1:der%mesh%np_part,1:hm%d%dim))
674 ispin = hm%d%get_spin_index(ik)
676 ppsi_i(1:der%mesh%np,:) = psi_i(1:der%mesh%np,:)
678 ppsi_j(1:der%mesh%np,:) = psi_j(1:der%mesh%np,:)
681 do idim = 1, hm%d%dim
686 if (hm%phase%is_allocated())
then
688 call hm%phase%apply_to_single(ppsi_i, der%mesh%np_part, hm%d%dim, ik, .false.)
689 call hm%phase%apply_to_single(ppsi_j, der%mesh%np_part, hm%d%dim, ik, .false.)
692 do idim = 1, hm%d%dim
693 call zderivatives_grad(der, ppsi_i(:, idim), gpsi_i(:, :, idim), set_bc = .false.)
694 call zderivatives_grad(der, ppsi_j(:, idim), gpsi_j(:, :, idim), set_bc = .false.)
699 call hm%ks_pot%zcurrent_mass_renormalization(gpsi_i, der%dim, hm%d%dim, ispin)
700 call hm%ks_pot%zcurrent_mass_renormalization(gpsi_j, der%dim, hm%d%dim, ispin)
704 der%boundaries, ik, ppsi_i, gpsi_i)
706 der%boundaries, ik, ppsi_j, gpsi_j)
708 if (hm%scissor%apply)
then
716 do idim = 1, hm%d%dim
718 cmel(idir,ispin) =
m_zi *
zmf_dotp(der%mesh, psi_i(:, idim), gpsi_j(:, idir,idim), reduce = .false.)
719 cmel(idir,ispin) = cmel(idir,ispin) -
m_zi *
zmf_dotp(der%mesh, gpsi_i(:, idir, idim), psi_j(:, idim), reduce = .false.)
724 if (der%mesh%parallel_in_domains)
call der%mesh%allreduce(cmel)
728 safe_deallocate_a(gpsi_i)
729 safe_deallocate_a(ppsi_i)
730 safe_deallocate_a(gpsi_j)
731 safe_deallocate_a(ppsi_j)
739 class(
space_t),
intent(in) :: space
743 real(real64),
intent(out) :: current(:, :, :)
745 integer :: ik, ist, idir, idim, ip, ispin, ndim
746 complex(real64),
allocatable :: gpsi(:, :, :), psi(:, :), g2psi(:, :, :, :)
747 complex(real64) :: tmp
751 assert(space%is_periodic())
752 assert(st%d%dim == 1)
756 safe_allocate(psi(1:der%mesh%np_part, 1:st%d%dim))
757 safe_allocate(gpsi(1:der%mesh%np_part, 1:ndim, 1:st%d%dim))
758 safe_allocate(g2psi(1:der%mesh%np, 1:ndim, 1:ndim, 1:st%d%dim))
760 do ip = 1, der%mesh%np
761 current(ip, 1:ndim, 1:st%d%nspin) = st%current(ip, 1:ndim, 1:st%d%nspin)*hm%ep%vpsl(ip)
765 do ik = st%d%kpt%start, st%d%kpt%end
766 ispin = st%d%get_spin_index(ik)
767 do ist = st%st_start, st%st_end
769 if (abs(st%kweights(ik)*st%occ(ist, ik)) <=
m_epsilon) cycle
772 do idim = 1, st%d%dim
776 if (hm%phase%is_allocated())
then
777 call hm%phase%apply_to_single(psi, der%mesh%np_part, st%d%dim, ik, conjugate = .false.)
780 do idim = 1, st%d%dim
784 if (hm%phase%is_allocated())
then
785 call hm%phase%apply_to_single(gpsi(:, idir, :), der%mesh%np, st%d%dim, ik, conjugate = .
true.)
788 do idim = 1, st%d%dim
792 if (hm%phase%is_allocated())
then
793 call hm%phase%apply_to_single(gpsi(:, idir, :), der%mesh%np_part, st%d%dim, ik, conjugate = .false.)
796 do idim = 1, st%d%dim
797 call zderivatives_grad(der, gpsi(:, idir, idim), g2psi(:, :, idir, idim), set_bc = .false.)
801 do ip = 1, der%mesh%np
804 tmp = sum(conjg(g2psi(ip, 1:ndim, idir, idim))*gpsi(ip, 1:ndim, idim)) - &
805 sum(conjg(gpsi(ip, 1:ndim, idim))*g2psi(ip, 1:ndim, idir, idim))
806 tmp = tmp - conjg(gpsi(ip, idir, idim))*sum(g2psi(ip, 1:ndim, 1:ndim, idim)) + &
807 sum(conjg(g2psi(ip, 1:ndim, 1:ndim, idim)))*gpsi(ip, idir, idim)
808 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_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)
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.
A module to handle KS potential, without the external potential.
integer, parameter, public rdmft
integer, parameter, public hartree_fock
integer, parameter, public generalized_kohn_sham_dft
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.
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