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 class(mesh_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
163 if (gr%der%boundaries%spiralBC)
then
165 if (gr%parallel_in_domains) sp = gr%np + gr%pv%np_ghost
171 safe_allocate(phase%phase_spiral(1:gr%np_part-sp, 1:2))
174 do ip = sp + 1, gr%np_part
178 phase%phase_spiral(ip-sp, 1) = &
179 exp(
m_zi * sum((gr%x(ip, 1:space%dim)-x_global(1:space%dim)) * gr%der%boundaries%spiral_q(1:space%dim)))
180 phase%phase_spiral(ip-sp, 2) = &
181 exp(-
m_zi * sum((gr%x(ip, 1:space%dim)-x_global(1:space%dim)) * gr%der%boundaries%spiral_q(1:space%dim)))
186 call accel_write_buffer(phase%buff_phase_spiral, gr%np_part-sp, 2, phase%phase_spiral)
197 if (gr%parallel_in_domains) sp = gr%np + gr%pv%np_ghost
200 do ik = kpt%start, kpt%end
201 kpoint(1:space%dim) = kpoints%get_point(d%get_kpoint_index(ik))
203 do ip = 1, gr%np_part
204 phase%phase(ip, ik) =
exp(-
m_zi * sum(gr%x(ip, 1:space%dim) * kpoint(1:space%dim)))
210 do ip = sp + 1, gr%np_part
216 phase%phase_corr(ip, ik) = phase%phase(ip, ik)* &
217 exp(
m_zi * sum(x_global(1:space%dim) * kpoint(1:space%dim)))
227 call accel_write_buffer(phase%buff_phase_corr, gr%np_part - gr%np, kpt%nlocal, phase%phase_corr)
235 subroutine phase_update_phases(phase, mesh, kpt, kpoints, d, space, uniform_vector_potential)
236 class(
phase_t),
intent(inout) :: phase
237 class(
mesh_t),
intent(in) :: mesh
241 type(
space_t),
intent(in) :: space
242 real(real64),
allocatable,
intent(in) :: uniform_vector_potential(:)
244 integer :: ik, ip, sp, wgsize
245 integer(int64) :: ip_inner_global
246 real(real64) :: kpoint(space%dim)
247 real(real64),
allocatable :: x_global(:,:), kpt_vec_pot(:,:), x(:,:)
248 type(
accel_mem_t) :: buff_vec_pot, buff_x_global, buff_x
250 real(real64) :: tmp_sum
252 if (.not.
allocated(uniform_vector_potential))
return
257 if (.not.
allocated(phase%phase))
then
258 safe_allocate(phase%phase(1:mesh%np_part, kpt%start:kpt%end))
261 mesh%np_part*kpt%nlocal)
265 if (.not.
allocated(phase%phase_corr))
then
266 safe_allocate(phase%phase_corr(mesh%np+1:mesh%np_part, kpt%start:kpt%end))
269 (mesh%np_part - mesh%np)*kpt%nlocal)
278 if (mesh%parallel_in_domains) sp = mesh%np + mesh%pv%np_ghost
280 safe_allocate(x_global(1:space%dim,(sp + 1):mesh%np_part))
283 safe_allocate(x(1:space%dim, 1:mesh%np_part))
284 x = transpose(mesh%x)
287 do ip = sp + 1, mesh%np_part
291 x_global(:,ip) =
mesh_x_global(mesh, ip_inner_global) - mesh%x(ip, 1:space%dim)
297 do ik = kpt%start, kpt%end
298 kpoint(1:space%dim) = kpoints%get_point(d%get_kpoint_index(ik))
300 kpoint(1:space%dim) = kpoint(1:space%dim) + uniform_vector_potential(1:space%dim)
303 do ip = 1, mesh%np_part
304 tmp_sum = sum(x(1:space%dim, ip)*kpoint(1:space%dim))
305 phase%phase(ip, ik) = cmplx(
cos(tmp_sum), -
sin(tmp_sum), real64)
310 do ip = sp + 1, mesh%np_part
311 tmp_sum = sum(x_global(1:space%dim, ip)*kpoint(1:space%dim))
312 phase%phase_corr(ip, ik) = cmplx(
cos(tmp_sum),
sin(tmp_sum), real64)
321 safe_allocate(kpt_vec_pot(1:space%dim,kpt%start:kpt%end))
322 do ik = kpt%start, kpt%end
323 kpoint(1:space%dim) = kpoints%get_point(d%get_kpoint_index(ik))
324 kpt_vec_pot(1:space%dim, ik) = kpoint(1:space%dim) + uniform_vector_potential(1:space%dim)
333 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.)
354 call accel_read_buffer(phase%buff_phase_corr, mesh%np_part - mesh%np, kpt%nlocal, phase%phase_corr)
359 safe_deallocate_a(kpt_vec_pot)
362 safe_deallocate_a(x_global)
371 class(
phase_t),
intent(inout) :: phase
384 safe_deallocate_a(phase%phase)
385 safe_deallocate_a(phase%phase_corr)
386 safe_deallocate_a(phase%phase_spiral)
395 class(
phase_t),
intent(in) :: phase
396 class(
mesh_t),
intent(in) :: mesh
398 logical,
optional,
intent(in) :: async
401 logical :: phase_correction
406 phase_correction = phase%is_allocated()
410 if (phase_correction)
then
411 call phase%apply_to(mesh, mesh%np, .false., psib, async=async)
421 class(
phase_t),
intent(in) :: phase
422 class(
mesh_t),
intent(in) :: mesh
424 logical,
optional,
intent(in) :: async
426 logical :: phase_correction
431 phase_correction = phase%is_allocated()
435 if (phase_correction)
then
436 call phase%apply_to(mesh, mesh%np, .
true., psib, async=async)
446 class(
phase_t),
intent(in) :: this
447 class(
mesh_t),
intent(in) :: mesh
448 integer,
intent(in) :: np
449 logical,
intent(in) :: conjugate
450 type(
wfs_elec_t),
target,
intent(inout) :: psib
451 type(
wfs_elec_t),
optional,
target,
intent(in) :: src
452 logical,
optional,
intent(in) :: async
454 integer :: ip, ii, sp
456 complex(real64) :: phase
457 integer(int64) :: wgsize, dim2, dim3
465 assert(np <= mesh%np_part)
467 assert(psib%ik >= lbound(this%phase, dim=2))
468 assert(psib%ik <= ubound(this%phase, dim=2))
471 if (
present(src)) src_ => src
473 assert(src_%has_phase .eqv. conjugate)
474 assert(src_%ik == psib%ik)
478 sp = min(np, mesh%np)
479 if (np > mesh%np .and. mesh%parallel_in_domains) sp = mesh%np + mesh%pv%np_ghost
481 select case (psib%status())
488 do ip = 1, min(mesh%np, np)
489 phase = conjg(this%phase(ip, psib%ik))
491 do ii = 1, psib%nst_linear
492 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
500 phase = conjg(this%phase(ip, psib%ik))
502 do ii = 1, psib%nst_linear
503 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
512 do ip = 1, min(mesh%np, np)
513 phase = this%phase(ip, psib%ik)
515 do ii = 1, psib%nst_linear
516 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
524 phase = this%phase(ip, psib%ik)
526 do ii = 1, psib%nst_linear
527 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
539 do ii = 1, psib%nst_linear
541 do ip = 1, min(mesh%np, np)
542 psib%zff_linear(ip, ii) = conjg(this%phase(ip, psib%ik))*src_%zff_linear(ip, ii)
549 psib%zff_linear(ip, ii) = conjg(this%phase(ip, psib%ik))*src_%zff_linear(ip, ii)
557 do ii = 1, psib%nst_linear
559 do ip = 1, min(mesh%np, np)
560 psib%zff_linear(ip, ii) = this%phase(ip, psib%ik)*src_%zff_linear(ip, ii)
567 psib%zff_linear(ip, ii) = this%phase(ip, psib%ik)*src_%zff_linear(ip, ii)
598 call accel_kernel_run(ker_phase, (/psib%pack_size(1), dim2, dim3/), (/psib%pack_size(1), wgsize, 1_int64/))
603 psib%has_phase = .not. conjugate
616 class(
phase_t),
intent(in) :: this
617 complex(real64),
intent(inout) :: psi(:, :)
618 integer,
intent(in) :: np
619 integer,
intent(in) :: dim
620 integer,
intent(in) :: ik
621 logical,
intent(in) :: conjugate
627 assert(ik >= lbound(this%phase, dim=2))
628 assert(ik <= ubound(this%phase, dim=2))
637 psi(ip, idim) = conjg(this%phase(ip, ik))*psi(ip, idim)
646 psi(ip, idim) = this%phase(ip, ik)*psi(ip, idim)
662 class(
phase_t),
intent(in) :: this
666 integer :: ip, ii, sp
667 integer,
allocatable :: spin_label(:)
669 integer(int64) :: wgsize
676 assert(der%boundaries%spiral)
680 if (der%mesh%parallel_in_domains) sp = der%mesh%np + der%mesh%pv%np_ghost
683 select case (psib%status())
687 do ip = sp + 1, der%mesh%np_part
688 do ii = 1, psib%nst_linear, 2
689 if (this%spin(3,psib%linear_to_ist(ii), psib%ik)>0)
then
690 psib%zff_pack(ii+1, ip) = psib%zff_pack(ii+1, ip)*this%phase_spiral(ip-sp, 1)
692 psib%zff_pack(ii, ip) = psib%zff_pack(ii, ip)*this%phase_spiral(ip-sp, 2)
701 do ii = 1, psib%nst_linear, 2
702 if (this%spin(3,psib%linear_to_ist(ii), psib%ik)>0)
then
704 do ip = sp + 1, der%mesh%np_part
705 psib%zff_linear(ip, ii+1) = psib%zff_linear(ip, ii+1)*this%phase_spiral(ip-sp, 1)
710 do ip = sp + 1, der%mesh%np_part
711 psib%zff_linear(ip, ii) = psib%zff_linear(ip, ii)*this%phase_spiral(ip-sp, 2)
727 safe_allocate(spin_label(1:psib%nst_linear))
729 do ii = 1, psib%nst_linear, 2
730 if (this%spin(3, psib%linear_to_ist(ii), psib%ik) > 0) spin_label(ii)=1
749 (/psib%pack_size(1)/2,
pad(der%mesh%np_part - sp, 2*wgsize)/), &
750 (/psib%pack_size(1)/2, 2*wgsize/))
756 safe_deallocate_a(spin_label)
766 logical pure function phase_is_allocated(this)
767 class(
phase_t),
intent(in) :: this
769 phase_is_allocated =
allocated(this%phase)
double exp(double __x) __attribute__((__nothrow__
double sin(double __x) __attribute__((__nothrow__
double cos(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)
Given a global point index, this function returns the coordinates of the point.
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....
Description of the grid, containing information on derivatives, stencil, and symmetries.
Describes mesh distribution to nodes.
A container for the phase.
class for organizing spins and k-points
batches of electronic states