87 complex(real64),
allocatable :: phase(:, :)
90 complex(real64),
public,
allocatable :: phase_corr(:,:)
93 complex(real64),
allocatable :: phase_spiral(:,:)
96 type(accel_mem_t) :: buff_phase
97 type(accel_mem_t) :: buff_phase_spiral
98 type(accel_mem_t),
public :: buff_phase_corr
99 integer :: buff_phase_qn_start
100 real(real64),
public,
pointer :: spin(:,:,:) => null()
128 class(phase_t),
intent(inout) :: phase
129 class(mesh_t),
intent(in) :: gr
130 type(distributed_t),
intent(in) :: kpt
131 type(kpoints_t),
intent(in) :: kpoints
132 type(states_elec_dim_t),
intent(in) :: d
133 type(space_t),
intent(in) :: space
135 integer :: ip, ik, sp
136 integer(int64) :: ip_inner_global
137 real(real64) :: kpoint(space%dim), x_global(space%dim)
144 phase%buff_phase_qn_start = kpt%start
146 if(kpoints%gamma_only())
then
151 safe_allocate(phase%phase(1:gr%np_part, kpt%start:kpt%end))
152 safe_allocate(phase%phase_corr(gr%np+1:gr%np_part, kpt%start:kpt%end))
154 do ik = kpt%start, kpt%end
156 do ip = gr%np + 1, gr%np_part
157 phase%phase_corr(ip, ik) =
m_one
166 if (gr%der%boundaries%spiralBC)
then
168 if (gr%parallel_in_domains) sp = gr%np + gr%pv%np_ghost
174 safe_allocate(phase%phase_spiral(1:gr%np_part-sp, 1:2))
177 do ip = sp + 1, gr%np_part
181 phase%phase_spiral(ip-sp, 1) = &
182 exp(
m_zi * sum((gr%x(1:space%dim, ip)-x_global(1:space%dim)) * gr%der%boundaries%spiral_q(1:space%dim)))
183 phase%phase_spiral(ip-sp, 2) = &
184 exp(-
m_zi * sum((gr%x(1:space%dim, ip)-x_global(1:space%dim)) * gr%der%boundaries%spiral_q(1:space%dim)))
189 call accel_write_buffer(phase%buff_phase_spiral, gr%np_part-sp, 2, phase%phase_spiral)
200 if (gr%parallel_in_domains) sp = gr%np + gr%pv%np_ghost
203 do ik = kpt%start, kpt%end
204 kpoint(1:space%dim) = kpoints%get_point(d%get_kpoint_index(ik))
206 do ip = 1, gr%np_part
207 phase%phase(ip, ik) =
exp(-
m_zi * sum(gr%x(1:space%dim, ip) * kpoint(1:space%dim)))
213 do ip = sp + 1, gr%np_part
219 phase%phase_corr(ip, ik) = phase%phase(ip, ik)* &
220 exp(
m_zi * sum(x_global(1:space%dim) * kpoint(1:space%dim)))
230 call accel_write_buffer(phase%buff_phase_corr, gr%np_part - gr%np, kpt%nlocal, phase%phase_corr)
238 subroutine phase_update_phases(phase, mesh, kpt, kpoints, d, space, uniform_vector_potential)
239 class(
phase_t),
intent(inout) :: phase
240 class(
mesh_t),
intent(in) :: mesh
244 type(
space_t),
intent(in) :: space
245 real(real64),
allocatable,
intent(in) :: uniform_vector_potential(:)
247 integer :: ik, ip, sp, wgsize
248 integer(int64) :: ip_inner_global
249 real(real64) :: kpoint(space%dim)
250 real(real64),
allocatable :: x_global(:,:), kpt_vec_pot(:,:)
251 type(
accel_mem_t) :: buff_vec_pot, buff_x_global, buff_x
253 real(real64) :: tmp_sum
255 if (.not.
allocated(uniform_vector_potential))
return
260 if (.not.
allocated(phase%phase))
then
261 safe_allocate(phase%phase(1:mesh%np_part, kpt%start:kpt%end))
264 mesh%np_part*kpt%nlocal)
268 if (.not.
allocated(phase%phase_corr))
then
269 safe_allocate(phase%phase_corr(mesh%np+1:mesh%np_part, kpt%start:kpt%end))
272 (mesh%np_part - mesh%np)*kpt%nlocal)
281 if (mesh%parallel_in_domains) sp = mesh%np + mesh%pv%np_ghost
283 safe_allocate(x_global(1:space%dim,(sp + 1):mesh%np_part))
286 do ip = sp + 1, mesh%np_part
290 x_global(:,ip) =
mesh_x_global(mesh, ip_inner_global) - mesh%x(1:space%dim, ip)
296 do ik = kpt%start, kpt%end
297 kpoint(1:space%dim) = kpoints%get_point(d%get_kpoint_index(ik))
299 kpoint(1:space%dim) = kpoint(1:space%dim) + uniform_vector_potential(1:space%dim)
302 do ip = 1, mesh%np_part
303 tmp_sum = sum(mesh%x(1:space%dim, ip)*kpoint(1:space%dim))
304 phase%phase(ip, ik) = cmplx(
cos(tmp_sum), -
sin(tmp_sum), real64)
309 do ip = sp + 1, mesh%np_part
310 tmp_sum = sum(x_global(1:space%dim, ip)*kpoint(1:space%dim))
311 phase%phase_corr(ip, ik) = cmplx(
cos(tmp_sum),
sin(tmp_sum), real64)
320 safe_allocate(kpt_vec_pot(1:space%dim,kpt%start:kpt%end))
321 do ik = kpt%start, kpt%end
322 kpoint(1:space%dim) = kpoints%get_point(d%get_kpoint_index(ik))
323 kpt_vec_pot(1:space%dim, ik) = kpoint(1:space%dim) + uniform_vector_potential(1:space%dim)
332 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.)
353 call accel_read_buffer(phase%buff_phase_corr, mesh%np_part - mesh%np, kpt%nlocal, phase%phase_corr)
358 safe_deallocate_a(kpt_vec_pot)
361 safe_deallocate_a(x_global)
369 class(
phase_t),
intent(inout) :: phase
382 safe_deallocate_a(phase%phase)
383 safe_deallocate_a(phase%phase_corr)
384 safe_deallocate_a(phase%phase_spiral)
393 class(
phase_t),
intent(in) :: phase
394 class(
mesh_t),
intent(in) :: mesh
396 logical,
optional,
intent(in) :: async
399 logical :: phase_correction
404 phase_correction = phase%is_allocated()
408 if (phase_correction)
then
409 call phase%apply_to(mesh, mesh%np, .false., psib, async=async)
419 class(
phase_t),
intent(in) :: phase
420 class(
mesh_t),
intent(in) :: mesh
422 logical,
optional,
intent(in) :: async
424 logical :: phase_correction
429 phase_correction = phase%is_allocated()
433 if (phase_correction)
then
434 call phase%apply_to(mesh, mesh%np, .
true., psib, async=async)
444 class(
phase_t),
intent(in) :: this
445 class(
mesh_t),
intent(in) :: mesh
446 integer,
intent(in) :: np
447 logical,
intent(in) :: conjugate
448 type(
wfs_elec_t),
target,
intent(inout) :: psib
449 type(
wfs_elec_t),
optional,
target,
intent(in) :: src
450 logical,
optional,
intent(in) :: async
452 integer :: ip, ii, sp
454 complex(real64) :: phase
455 integer(int64) :: wgsize, dim2, dim3
463 assert(np <= mesh%np_part)
465 assert(psib%ik >= lbound(this%phase, dim=2))
466 assert(psib%ik <= ubound(this%phase, dim=2))
469 if (
present(src)) src_ => src
471 assert(src_%has_phase .eqv. conjugate)
472 assert(src_%ik == psib%ik)
476 sp = min(np, mesh%np)
477 if (np > mesh%np .and. mesh%parallel_in_domains) sp = mesh%np + mesh%pv%np_ghost
479 select case (psib%status())
486 do ip = 1, min(mesh%np, np)
487 phase = conjg(this%phase(ip, psib%ik))
489 do ii = 1, psib%nst_linear
490 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
498 phase = conjg(this%phase(ip, psib%ik))
500 do ii = 1, psib%nst_linear
501 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
510 do ip = 1, min(mesh%np, np)
511 phase = this%phase(ip, psib%ik)
513 do ii = 1, psib%nst_linear
514 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
522 phase = this%phase(ip, psib%ik)
524 do ii = 1, psib%nst_linear
525 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
537 do ii = 1, psib%nst_linear
539 do ip = 1, min(mesh%np, np)
540 psib%zff_linear(ip, ii) = conjg(this%phase(ip, psib%ik))*src_%zff_linear(ip, ii)
547 psib%zff_linear(ip, ii) = conjg(this%phase(ip, psib%ik))*src_%zff_linear(ip, ii)
555 do ii = 1, psib%nst_linear
557 do ip = 1, min(mesh%np, np)
558 psib%zff_linear(ip, ii) = this%phase(ip, psib%ik)*src_%zff_linear(ip, ii)
565 psib%zff_linear(ip, ii) = this%phase(ip, psib%ik)*src_%zff_linear(ip, ii)
596 call accel_kernel_run(ker_phase, (/psib%pack_size(1), dim2, dim3/), (/psib%pack_size(1), wgsize, 1_int64/))
601 psib%has_phase = .not. conjugate
614 class(
phase_t),
intent(in) :: this
615 complex(real64),
intent(inout) :: psi(:, :)
616 integer,
intent(in) :: np
617 integer,
intent(in) :: dim
618 integer,
intent(in) :: ik
619 logical,
intent(in) :: conjugate
625 assert(ik >= lbound(this%phase, dim=2))
626 assert(ik <= ubound(this%phase, dim=2))
635 psi(ip, idim) = conjg(this%phase(ip, ik))*psi(ip, idim)
644 psi(ip, idim) = this%phase(ip, ik)*psi(ip, idim)
660 class(
phase_t),
intent(in) :: this
664 integer :: ip, ii, sp
665 integer,
allocatable :: spin_label(:)
667 integer(int64) :: wgsize
674 assert(der%boundaries%spiral)
678 if (der%mesh%parallel_in_domains) sp = der%mesh%np + der%mesh%pv%np_ghost
681 select case (psib%status())
685 do ip = sp + 1, der%mesh%np_part
686 do ii = 1, psib%nst_linear, 2
687 if (this%spin(3,psib%linear_to_ist(ii), psib%ik)>0)
then
688 psib%zff_pack(ii+1, ip) = psib%zff_pack(ii+1, ip)*this%phase_spiral(ip-sp, 1)
690 psib%zff_pack(ii, ip) = psib%zff_pack(ii, ip)*this%phase_spiral(ip-sp, 2)
699 do ii = 1, psib%nst_linear, 2
700 if (this%spin(3,psib%linear_to_ist(ii), psib%ik)>0)
then
702 do ip = sp + 1, der%mesh%np_part
703 psib%zff_linear(ip, ii+1) = psib%zff_linear(ip, ii+1)*this%phase_spiral(ip-sp, 1)
708 do ip = sp + 1, der%mesh%np_part
709 psib%zff_linear(ip, ii) = psib%zff_linear(ip, ii)*this%phase_spiral(ip-sp, 2)
725 safe_allocate(spin_label(1:psib%nst_linear))
727 do ii = 1, psib%nst_linear, 2
728 if (this%spin(3, psib%linear_to_ist(ii), psib%ik) > 0) spin_label(ii)=1
747 (/psib%pack_size(1)/2,
pad(der%mesh%np_part - sp, 2*wgsize)/), &
748 (/psib%pack_size(1)/2, 2*wgsize/))
754 safe_deallocate_a(spin_label)
764 logical pure function phase_is_allocated(this)
765 class(
phase_t),
intent(in) :: this
767 phase_is_allocated =
allocated(this%phase)
778 class(
phase_t),
intent(in) :: phase
779 type(grid_t),
intent(in) :: gr
780 type(distributed_t),
intent(in) :: kpt
781 type(wfs_elec_t),
intent(in) :: psib
782 type(wfs_elec_t),
intent(out) :: psib_with_phase
784 integer :: k_offset, n_boundary_points
788 call psib%copy_to(psib_with_phase)
789 if (phase%is_allocated())
then
790 call phase%apply_to(gr, gr%np, conjugate = .false., psib = psib_with_phase, src = psib, async=.
true.)
793 k_offset = psib%ik - kpt%start
794 n_boundary_points = int(gr%np_part - gr%np)
795 call boundaries_set(gr%der%boundaries, gr, psib_with_phase, phase_correction = phase%phase_corr(:, psib%ik), &
796 buff_phase_corr = phase%buff_phase_corr, offset=k_offset*n_boundary_points, async=.
true.)
798 call psib%copy_data_to(gr%np, psib_with_phase)
799 call boundaries_set(gr%der%boundaries, gr, psib_with_phase)
802 call psib_with_phase%do_pack(copy = .
true.)
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.
Module implementing boundary conditions in Octopus.
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_copy_and_set_phase(phase, gr, kpt, psib, psib_with_phase)
Copy a batch to another batch and apply the Bloch phase to it.
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