86 complex(real64),
allocatable :: phase(:, :)
89 complex(real64),
public,
allocatable :: phase_corr(:,:)
92 complex(real64),
allocatable :: phase_spiral(:,:)
95 type(accel_mem_t) :: buff_phase
96 type(accel_mem_t) :: buff_phase_spiral
97 type(accel_mem_t),
public :: buff_phase_corr
98 integer :: buff_phase_qn_start
99 real(real64),
public,
pointer :: spin(:,:,:) => null()
125 class(phase_t),
intent(inout) :: phase
126 type(grid_t),
intent(in) :: gr
127 type(distributed_t),
intent(in) :: kpt
128 type(kpoints_t),
intent(in) :: kpoints
129 type(states_elec_dim_t),
intent(in) :: d
130 type(space_t),
intent(in) :: space
132 integer :: ip, ik, sp
133 integer(int64) :: ip_inner_global
134 real(real64) :: kpoint(space%dim), x_global(space%dim)
141 phase%buff_phase_qn_start = kpt%start
143 if(kpoints%gamma_only())
then
148 safe_allocate(phase%phase(1:gr%np_part, kpt%start:kpt%end))
149 safe_allocate(phase%phase_corr(gr%np+1:gr%np_part, kpt%start:kpt%end))
151 do ik = kpt%start, kpt%end
153 do ip = gr%np + 1, gr%np_part
154 phase%phase_corr(ip, ik) =
m_one
160 if (gr%der%boundaries%spiralBC)
then
162 if (gr%parallel_in_domains) sp = gr%np + gr%pv%np_ghost
168 safe_allocate(phase%phase_spiral(1:gr%np_part-sp, 1:2))
171 do ip = sp + 1, gr%np_part
175 phase%phase_spiral(ip-sp, 1) = &
176 exp(
m_zi * sum((gr%x(ip, 1:space%dim)-x_global(1:space%dim)) * gr%der%boundaries%spiral_q(1:space%dim)))
177 phase%phase_spiral(ip-sp, 2) = &
178 exp(-
m_zi * sum((gr%x(ip, 1:space%dim)-x_global(1:space%dim)) * gr%der%boundaries%spiral_q(1:space%dim)))
183 call accel_write_buffer(phase%buff_phase_spiral, gr%np_part-sp, 2, phase%phase_spiral)
188 kpoint(1:space%dim) =
m_zero
191 if (gr%parallel_in_domains) sp = gr%np + gr%pv%np_ghost
193 do ik = kpt%start, kpt%end
194 kpoint(1:space%dim) = kpoints%get_point(d%get_kpoint_index(ik))
197 do ip = 1, gr%np_part
198 phase%phase(ip, ik) =
exp(-
m_zi * sum(gr%x(ip, 1:space%dim) * kpoint(1:space%dim)))
204 do ip = sp + 1, gr%np_part
210 phase%phase_corr(ip, ik) = phase%phase(ip, ik)* &
211 exp(
m_zi * sum(x_global(1:space%dim) * kpoint(1:space%dim)))
221 call accel_write_buffer(phase%buff_phase_corr, gr%np_part - gr%np, kpt%nlocal, phase%phase_corr)
229 subroutine phase_update_phases(phase, mesh, kpt, kpoints, d, space, uniform_vector_potential)
230 class(
phase_t),
intent(inout) :: phase
231 class(
mesh_t),
intent(in) :: mesh
235 type(
space_t),
intent(in) :: space
236 real(real64),
allocatable,
intent(in) :: uniform_vector_potential(:)
238 integer :: ik, ip, sp, wgsize
239 integer(int64) :: ip_inner_global
240 real(real64) :: kpoint(space%dim)
241 real(real64),
allocatable :: x_global(:,:), kpt_vec_pot(:,:)
242 type(
accel_mem_t) :: buff_vec_pot, buff_x_global, buff_x
245 if (.not.
allocated(uniform_vector_potential))
return
250 if (.not.
allocated(phase%phase))
then
251 safe_allocate(phase%phase(1:mesh%np_part, kpt%start:kpt%end))
254 mesh%np_part*kpt%nlocal)
258 if (.not.
allocated(phase%phase_corr))
then
259 safe_allocate(phase%phase_corr(mesh%np+1:mesh%np_part, kpt%start:kpt%end))
262 (mesh%np_part - mesh%np)*kpt%nlocal)
271 if (mesh%parallel_in_domains) sp = mesh%np + mesh%pv%np_ghost
273 safe_allocate(x_global(1:space%dim,(sp + 1):mesh%np_part))
275 do ip = sp + 1, mesh%np_part
280 x_global(:,ip) =
mesh_x_global(mesh, ip_inner_global) - mesh%x(ip, 1:space%dim)
285 do ik = kpt%start, kpt%end
286 kpoint(1:space%dim) = kpoints%get_point(d%get_kpoint_index(ik))
288 kpoint(1:space%dim) = kpoint(1:space%dim) + uniform_vector_potential(1:space%dim)
291 do ip = 1, mesh%np_part
292 phase%phase(ip, ik) =
exp(cmplx(
m_zero, -sum(mesh%x(ip, 1:space%dim)*kpoint(1:space%dim)), real64))
297 do ip = sp + 1, mesh%np_part
298 phase%phase_corr(ip, ik) =
exp(cmplx(
m_zero, sum(x_global(1:space%dim, ip) * kpoint(1:space%dim)), real64))
307 safe_allocate(kpt_vec_pot(1:space%dim,kpt%start:kpt%end))
308 do ik = kpt%start, kpt%end
309 kpoint(1:space%dim) = kpoints%get_point(d%get_kpoint_index(ik))
310 kpt_vec_pot(1:space%dim, ik) = kpoint(1:space%dim) + uniform_vector_potential(1:space%dim)
319 call accel_write_buffer(buff_x_global, space%dim, mesh%np_part-sp, x_global(1:space%dim,(sp + 1):mesh%np_part), async=.
true.)
340 call accel_read_buffer(phase%buff_phase_corr, mesh%np_part - mesh%np, kpt%nlocal, phase%phase_corr)
345 safe_deallocate_a(kpt_vec_pot)
348 safe_deallocate_a(x_global)
356 class(
phase_t),
intent(inout) :: phase
369 safe_deallocate_a(phase%phase)
370 safe_deallocate_a(phase%phase_corr)
371 safe_deallocate_a(phase%phase_spiral)
380 class(
phase_t),
intent(in) :: phase
381 class(
mesh_t),
intent(in) :: mesh
383 logical,
optional,
intent(in) :: async
386 logical :: phase_correction
391 phase_correction = phase%is_allocated()
395 if (phase_correction)
then
396 call phase%apply_to(mesh, mesh%np, .false., psib, async=async)
406 class(
phase_t),
intent(in) :: phase
407 class(
mesh_t),
intent(in) :: mesh
409 logical,
optional,
intent(in) :: async
411 logical :: phase_correction
416 phase_correction = phase%is_allocated()
420 if (phase_correction)
then
421 call phase%apply_to(mesh, mesh%np, .
true., psib, async=async)
431 class(
phase_t),
intent(in) :: this
432 class(
mesh_t),
intent(in) :: mesh
433 integer,
intent(in) :: np
434 logical,
intent(in) :: conjugate
435 type(
wfs_elec_t),
target,
intent(inout) :: psib
436 type(
wfs_elec_t),
optional,
target,
intent(in) :: src
437 logical,
optional,
intent(in) :: async
439 integer :: ip, ii, sp
441 complex(real64) :: phase
442 integer(int64) :: wgsize, dim2, dim3
450 assert(np <= mesh%np_part)
452 assert(psib%ik >= lbound(this%phase, dim=2))
453 assert(psib%ik <= ubound(this%phase, dim=2))
456 if (
present(src)) src_ => src
458 assert(src_%has_phase .eqv. conjugate)
459 assert(src_%ik == psib%ik)
463 sp = min(np, mesh%np)
464 if (np > mesh%np .and. mesh%parallel_in_domains) sp = mesh%np + mesh%pv%np_ghost
466 select case (psib%status())
473 do ip = 1, min(mesh%np, np)
474 phase = conjg(this%phase(ip, psib%ik))
476 do ii = 1, psib%nst_linear
477 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
485 phase = conjg(this%phase(ip, psib%ik))
487 do ii = 1, psib%nst_linear
488 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
497 do ip = 1, min(mesh%np, np)
498 phase = this%phase(ip, psib%ik)
500 do ii = 1, psib%nst_linear
501 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
509 phase = this%phase(ip, psib%ik)
511 do ii = 1, psib%nst_linear
512 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
524 do ii = 1, psib%nst_linear
526 do ip = 1, min(mesh%np, np)
527 psib%zff_linear(ip, ii) = conjg(this%phase(ip, psib%ik))*src_%zff_linear(ip, ii)
534 psib%zff_linear(ip, ii) = conjg(this%phase(ip, psib%ik))*src_%zff_linear(ip, ii)
542 do ii = 1, psib%nst_linear
544 do ip = 1, min(mesh%np, np)
545 psib%zff_linear(ip, ii) = this%phase(ip, psib%ik)*src_%zff_linear(ip, ii)
552 psib%zff_linear(ip, ii) = this%phase(ip, psib%ik)*src_%zff_linear(ip, ii)
583 call accel_kernel_run(ker_phase, (/psib%pack_size(1), dim2, dim3/), (/psib%pack_size(1), wgsize, 1_int64/))
588 psib%has_phase = .not. conjugate
601 class(
phase_t),
intent(in) :: this
602 complex(real64),
intent(inout) :: psi(:, :)
603 integer,
intent(in) :: np
604 integer,
intent(in) :: dim
605 integer,
intent(in) :: ik
606 logical,
intent(in) :: conjugate
612 assert(ik >= lbound(this%phase, dim=2))
613 assert(ik <= ubound(this%phase, dim=2))
622 psi(ip, idim) = conjg(this%phase(ip, ik))*psi(ip, idim)
631 psi(ip, idim) = this%phase(ip, ik)*psi(ip, idim)
647 class(
phase_t),
intent(in) :: this
651 integer :: ip, ii, sp
652 integer,
allocatable :: spin_label(:)
654 integer(int64) :: wgsize
661 assert(der%boundaries%spiral)
665 if (der%mesh%parallel_in_domains) sp = der%mesh%np + der%mesh%pv%np_ghost
668 select case (psib%status())
672 do ip = sp + 1, der%mesh%np_part
673 do ii = 1, psib%nst_linear, 2
674 if (this%spin(3,psib%linear_to_ist(ii), psib%ik)>0)
then
675 psib%zff_pack(ii+1, ip) = psib%zff_pack(ii+1, ip)*this%phase_spiral(ip-sp, 1)
677 psib%zff_pack(ii, ip) = psib%zff_pack(ii, ip)*this%phase_spiral(ip-sp, 2)
686 do ii = 1, psib%nst_linear, 2
687 if (this%spin(3,psib%linear_to_ist(ii), psib%ik)>0)
then
689 do ip = sp + 1, der%mesh%np_part
690 psib%zff_linear(ip, ii+1) = psib%zff_linear(ip, ii+1)*this%phase_spiral(ip-sp, 1)
695 do ip = sp + 1, der%mesh%np_part
696 psib%zff_linear(ip, ii) = psib%zff_linear(ip, ii)*this%phase_spiral(ip-sp, 2)
712 safe_allocate(spin_label(1:psib%nst_linear))
714 do ii = 1, psib%nst_linear, 2
715 if (this%spin(3, psib%linear_to_ist(ii), psib%ik) > 0) spin_label(ii)=1
734 (/psib%pack_size(1)/2,
pad(der%mesh%np_part - sp, 2*wgsize)/), &
735 (/psib%pack_size(1)/2, 2*wgsize/))
741 safe_deallocate_a(spin_label)
751 logical pure function phase_is_allocated(this)
752 class(
phase_t),
intent(in) :: this
754 phase_is_allocated =
allocated(this%phase)
double exp(double __x) __attribute__((__nothrow__
subroutine, public accel_kernel_start_call(this, file_name, kernel_name, flags)
subroutine, public accel_finish()
integer, parameter, public accel_mem_read_write
integer pure function, public accel_max_size_per_dim(dim)
type(accel_kernel_t), target, save, public kernel_phase_spiral
subroutine, public accel_release_buffer(this, async)
pure logical function, public accel_is_enabled()
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_not_packed
functions are stored in CPU memory, unpacked order
integer, parameter, public batch_device_packed
functions are stored in device memory in packed order
integer, parameter, public batch_packed
functions are stored in CPU memory, in transposed (packed) order
This module implements common operations on batches of mesh functions.
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
real(real64), parameter, public m_zero
complex(real64), parameter, public m_zi
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
This module is intended to contain "only mathematical" functions and procedures.
This module defines the meshes, which are used in Octopus.
integer(int64) function, public mesh_periodic_point(mesh, space, ip)
This function returns the point inside the grid corresponding to a boundary point when PBCs are used....
real(real64) function, dimension(1:mesh%box%dim), public mesh_x_global(mesh, ipg)
subroutine phase_phase_spiral(this, der, psib)
apply spiral phase
subroutine phase_unset_phase_corr(phase, mesh, psib, async)
unset the phase correction (if necessary)
subroutine phase_init_phases(phase, gr, kpt, kpoints, d, space)
Initiliaze the phase arrays and copy to GPU the data.
subroutine phase_end(phase)
Releases the memory of the phase object.
subroutine phase_update_phases(phase, mesh, kpt, kpoints, d, space, uniform_vector_potential)
Update the phases.
logical pure function phase_is_allocated(this)
subroutine phase_apply_batch(this, mesh, np, conjugate, psib, src, async)
apply (remove) the phase to the wave functions before (after) applying the Hamiltonian
subroutine phase_set_phase_corr(phase, mesh, psib, async)
set the phase correction (if necessary)
subroutine phase_apply_mf(this, psi, np, dim, ik, conjugate)
apply (or remove) the phase to a wave function psi
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.
This module handles spin dimensions of the states and the k-point distribution.
type(type_t), public type_float
type(type_t), public type_cmplx
type(type_t), public type_integer
class representing derivatives
Distribution of N instances over mpi_grpsize processes, for the local rank mpi_grprank....
Describes mesh distribution to nodes.
A container for the phase.
class for organizing spins and k-points
batches of electronic states