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
248 integer(int64),
dimension(2) :: np, gsize, bsize
249 integer(int64) :: ip_inner_global
250 real(real64) :: kpoint(space%dim)
251 real(real64),
allocatable :: x_global(:,:), kpt_vec_pot(:,:)
252 type(
accel_mem_t) :: buff_vec_pot, buff_x_global, buff_x
254 real(real64) :: tmp_sum
256 if (.not.
allocated(uniform_vector_potential))
return
261 if (.not.
allocated(phase%phase))
then
262 safe_allocate(phase%phase(1:mesh%np_part, kpt%start:kpt%end))
265 mesh%np_part*kpt%nlocal)
269 if (.not.
allocated(phase%phase_corr))
then
270 safe_allocate(phase%phase_corr(mesh%np+1:mesh%np_part, kpt%start:kpt%end))
273 (mesh%np_part - mesh%np)*kpt%nlocal)
282 if (mesh%parallel_in_domains) sp = mesh%np + mesh%pv%np_ghost
284 safe_allocate(x_global(1:space%dim,(sp + 1):mesh%np_part))
287 do ip = sp + 1, mesh%np_part
291 x_global(:,ip) =
mesh_x_global(mesh, ip_inner_global) - mesh%x(1:space%dim, ip)
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(mesh%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.)
350 np = (/mesh%np_part, kpt%nlocal/)
357 call accel_read_buffer(phase%buff_phase_corr, mesh%np_part - mesh%np, kpt%nlocal, phase%phase_corr)
362 safe_deallocate_a(kpt_vec_pot)
365 safe_deallocate_a(x_global)
373 class(
phase_t),
intent(inout) :: phase
386 safe_deallocate_a(phase%phase)
387 safe_deallocate_a(phase%phase_corr)
388 safe_deallocate_a(phase%phase_spiral)
396 class(
phase_t),
intent(inout) :: phase
397 class(
mesh_t),
intent(in) :: mesh
409 phase%buff_phase_qn_start = kpt%start
415 if (
allocated(phase%phase))
then
416 assert(
size(phase%phase, 1) == mesh%np_part)
417 nlocal = ubound(phase%phase, dim=2) - lbound(phase%phase, dim=2) + 1
422 if (
allocated(phase%phase_corr))
then
423 assert(
size(phase%phase_corr, 1) == mesh%np_part - mesh%np)
424 nlocal = ubound(phase%phase_corr, dim=2) - lbound(phase%phase_corr, dim=2) + 1
426 size(phase%phase_corr, 1)*nlocal)
427 call accel_write_buffer(phase%buff_phase_corr,
size(phase%phase_corr, 1), nlocal, phase%phase_corr)
430 if (
allocated(phase%phase_spiral))
then
432 size(phase%phase_spiral, 1)*
size(phase%phase_spiral, 2))
434 size(phase%phase_spiral, 2), phase%phase_spiral)
444 class(
phase_t),
intent(in) :: phase
445 class(
mesh_t),
intent(in) :: mesh
447 logical,
optional,
intent(in) :: async
450 logical :: phase_correction
455 phase_correction = phase%is_allocated()
459 if (phase_correction)
then
460 call phase%apply_to(mesh, mesh%np, .false., psib, async=async)
470 class(
phase_t),
intent(in) :: phase
471 class(
mesh_t),
intent(in) :: mesh
473 logical,
optional,
intent(in) :: async
475 logical :: phase_correction
480 phase_correction = phase%is_allocated()
484 if (phase_correction)
then
485 call phase%apply_to(mesh, mesh%np, .
true., psib, async=async)
495 class(
phase_t),
intent(in) :: this
496 class(
mesh_t),
intent(in) :: mesh
497 integer,
intent(in) :: np
498 logical,
intent(in) :: conjugate
499 type(
wfs_elec_t),
target,
intent(inout) :: psib
500 type(
wfs_elec_t),
optional,
target,
intent(in) :: src
501 logical,
optional,
intent(in) :: async
503 integer :: ip, ii, sp
505 complex(real64) :: phase
506 integer(int64),
dimension(3) :: gsizes, bsizes
514 assert(np <= mesh%np_part)
516 assert(psib%ik >= lbound(this%phase, dim=2))
517 assert(psib%ik <= ubound(this%phase, dim=2))
520 if (
present(src)) src_ => src
522 assert(src_%has_phase .eqv. conjugate)
523 assert(src_%ik == psib%ik)
527 sp = min(np, mesh%np)
528 if (np > mesh%np .and. mesh%parallel_in_domains) sp = mesh%np + mesh%pv%np_ghost
530 select case (psib%status())
537 do ip = 1, min(mesh%np, np)
538 phase = conjg(this%phase(ip, psib%ik))
540 do ii = 1, psib%nst_linear
541 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
549 phase = conjg(this%phase(ip, psib%ik))
551 do ii = 1, psib%nst_linear
552 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
561 do ip = 1, min(mesh%np, np)
562 phase = this%phase(ip, psib%ik)
564 do ii = 1, psib%nst_linear
565 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
573 phase = this%phase(ip, psib%ik)
575 do ii = 1, psib%nst_linear
576 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
588 do ii = 1, psib%nst_linear
590 do ip = 1, min(mesh%np, np)
591 psib%zff_linear(ip, ii) = conjg(this%phase(ip, psib%ik))*src_%zff_linear(ip, ii)
598 psib%zff_linear(ip, ii) = conjg(this%phase(ip, psib%ik))*src_%zff_linear(ip, ii)
606 do ii = 1, psib%nst_linear
608 do ip = 1, min(mesh%np, np)
609 psib%zff_linear(ip, ii) = this%phase(ip, psib%ik)*src_%zff_linear(ip, ii)
616 psib%zff_linear(ip, ii) = this%phase(ip, psib%ik)*src_%zff_linear(ip, ii)
650 psib%has_phase = .not. conjugate
663 class(
phase_t),
intent(in) :: this
664 complex(real64),
intent(inout) :: psi(:, :)
665 integer,
intent(in) :: np
666 integer,
intent(in) :: dim
667 integer,
intent(in) :: ik
668 logical,
intent(in) :: conjugate
674 assert(ik >= lbound(this%phase, dim=2))
675 assert(ik <= ubound(this%phase, dim=2))
684 psi(ip, idim) = conjg(this%phase(ip, ik))*psi(ip, idim)
693 psi(ip, idim) = this%phase(ip, ik)*psi(ip, idim)
709 class(
phase_t),
intent(in) :: this
713 integer :: ip, ii, sp
714 integer,
allocatable :: spin_label(:)
716 integer(int64) :: bsize
717 integer(int64),
dimension(2) :: np, gsizes, bsizes
724 assert(der%boundaries%spiral)
728 if (der%mesh%parallel_in_domains) sp = der%mesh%np + der%mesh%pv%np_ghost
731 select case (psib%status())
735 do ip = sp + 1, der%mesh%np_part
736 do ii = 1, psib%nst_linear, 2
737 if (this%spin(3,psib%linear_to_ist(ii), psib%ik)>0)
then
738 psib%zff_pack(ii+1, ip) = psib%zff_pack(ii+1, ip)*this%phase_spiral(ip-sp, 1)
740 psib%zff_pack(ii, ip) = psib%zff_pack(ii, ip)*this%phase_spiral(ip-sp, 2)
749 do ii = 1, psib%nst_linear, 2
750 if (this%spin(3,psib%linear_to_ist(ii), psib%ik)>0)
then
752 do ip = sp + 1, der%mesh%np_part
753 psib%zff_linear(ip, ii+1) = psib%zff_linear(ip, ii+1)*this%phase_spiral(ip-sp, 1)
758 do ip = sp + 1, der%mesh%np_part
759 psib%zff_linear(ip, ii) = psib%zff_linear(ip, ii)*this%phase_spiral(ip-sp, 2)
775 safe_allocate(spin_label(1:psib%nst_linear))
777 do ii = 1, psib%nst_linear, 2
778 if (this%spin(3, psib%linear_to_ist(ii), psib%ik) > 0) spin_label(ii)=1
796 np = (/psib%pack_size(1)/2_int64, int(der%mesh%np_part - sp, int64)/)
797 bsizes = (/psib%pack_size(1)/2, 2*bsize/)
806 safe_deallocate_a(spin_label)
816 logical pure function phase_is_allocated(this)
817 class(
phase_t),
intent(in) :: this
819 phase_is_allocated =
allocated(this%phase)
830 class(
phase_t),
intent(in) :: phase
831 type(grid_t),
intent(in) :: gr
832 type(distributed_t),
intent(in) :: kpt
833 type(wfs_elec_t),
intent(in) :: psib
834 type(wfs_elec_t),
intent(out) :: psib_with_phase
836 integer :: k_offset, n_boundary_points
840 call psib%copy_to(psib_with_phase)
841 if (phase%is_allocated())
then
842 call phase%apply_to(gr, gr%np, conjugate = .false., psib = psib_with_phase, src = psib, async=.
true.)
845 k_offset = psib%ik - kpt%start
846 n_boundary_points = int(gr%np_part - gr%np)
847 call boundaries_set(gr%der%boundaries, gr, psib_with_phase, phase_correction = phase%phase_corr(:, psib%ik), &
848 buff_phase_corr = phase%buff_phase_corr, offset=k_offset*n_boundary_points, async=.
true.)
850 call psib%copy_data_to(gr%np, psib_with_phase)
851 call boundaries_set(gr%der%boundaries, gr, psib_with_phase)
854 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__
integer function, public accel_kernel_block_size(kernel)
subroutine, public accel_free_buffer(this, async)
subroutine, public accel_kernel_start_call(this, file_name, kernel_name, flags)
subroutine, public accel_finish()
subroutine, public accel_detach_buffer(this)
Clear a buffer handle without freeing device memory.
integer, parameter, public accel_mem_read_write
type(accel_kernel_t), target, save, public kernel_phase_spiral
pure logical function, public accel_is_enabled()
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, public phase_accel_rebuild(phase, mesh, kpt)
Rebuild phase accelerator buffers after an intrinsic copy.
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), parameter, public type_cmplx
type(type_t), parameter, public type_integer
type(type_t), parameter, public type_float
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