87 complex(real64),
allocatable :: phase(:, :)
90 complex(real64),
public,
allocatable :: phase_corr(:,:)
93 complex(real64),
allocatable :: phase_k(:, :)
95 complex(real64),
allocatable :: phase_corr_k(:,:)
96 complex(real64),
allocatable :: vp_phase(:)
97 complex(real64),
allocatable :: vp_phase_corr(:)
98 complex(real64),
allocatable :: phase_spiral(:,:)
101 type(accel_mem_t) :: buff_phase
102 type(accel_mem_t) :: buff_phase_spiral
103 type(accel_mem_t),
public :: buff_phase_corr
104 integer :: buff_phase_qn_start
105 real(real64),
public,
pointer :: spin(:,:,:) => null()
133 class(phase_t),
intent(inout) :: phase
134 class(mesh_t),
intent(in) :: gr
135 type(distributed_t),
intent(in) :: kpt
136 type(kpoints_t),
intent(in) :: kpoints
137 type(states_elec_dim_t),
intent(in) :: d
138 type(space_t),
intent(in) :: space
140 integer :: ip, ik, sp
141 integer(int64) :: ip_inner_global
142 real(real64) :: kpoint(space%dim), x_global(space%dim)
149 phase%buff_phase_qn_start = kpt%start
151 if(kpoints%gamma_only())
then
156 safe_allocate(phase%phase(1:gr%np_part, kpt%start:kpt%end))
157 safe_allocate(phase%phase_corr(gr%np+1:gr%np_part, kpt%start:kpt%end))
159 do ik = kpt%start, kpt%end
161 do ip = gr%np + 1, gr%np_part
162 phase%phase_corr(ip, ik) =
m_one
171 if (gr%der%boundaries%spiralBC)
then
173 if (gr%parallel_in_domains) sp = gr%np + gr%pv%np_ghost
179 safe_allocate(phase%phase_spiral(1:gr%np_part-sp, 1:2))
182 do ip = sp + 1, gr%np_part
186 phase%phase_spiral(ip-sp, 1) = &
187 exp(
m_zi * sum((gr%x(1:space%dim, ip)-x_global(1:space%dim)) * gr%der%boundaries%spiral_q(1:space%dim)))
188 phase%phase_spiral(ip-sp, 2) = &
189 exp(-
m_zi * sum((gr%x(1:space%dim, ip)-x_global(1:space%dim)) * gr%der%boundaries%spiral_q(1:space%dim)))
194 call accel_write_buffer(phase%buff_phase_spiral, gr%np_part-sp, 2, phase%phase_spiral)
205 if (gr%parallel_in_domains) sp = gr%np + gr%pv%np_ghost
208 do ik = kpt%start, kpt%end
209 kpoint(1:space%dim) = kpoints%get_point(d%get_kpoint_index(ik))
211 do ip = 1, gr%np_part
212 phase%phase(ip, ik) =
exp(-
m_zi * sum(gr%x(1:space%dim, ip) * kpoint(1:space%dim)))
218 do ip = sp + 1, gr%np_part
224 phase%phase_corr(ip, ik) = phase%phase(ip, ik)* &
225 exp(
m_zi * sum(x_global(1:space%dim) * kpoint(1:space%dim)))
235 call accel_write_buffer(phase%buff_phase_corr, gr%np_part - gr%np, kpt%nlocal(), phase%phase_corr)
243 subroutine phase_update_phases(phase, mesh, kpt, kpoints, d, space, uniform_vector_potential)
244 class(
phase_t),
intent(inout) :: phase
245 class(
mesh_t),
intent(in) :: mesh
249 type(
space_t),
intent(in) :: space
250 real(real64),
allocatable,
intent(in) :: uniform_vector_potential(:)
252 integer :: ik, ip, sp
253 integer(int64),
dimension(2) :: np, gsize, bsize
254 integer(int64) :: ip_inner_global
255 real(real64) :: kpoint(space%dim)
256 real(real64),
allocatable :: x_global(:,:), kpt_vec_pot(:,:)
257 type(
accel_mem_t) :: buff_vec_pot, buff_x_global, buff_x
260 character(len=128) :: kernel_name
261 real(real64) :: tmp_sum
263 if (.not.
allocated(uniform_vector_potential))
return
268 if (.not.
allocated(phase%phase))
then
269 safe_allocate(phase%phase(1:mesh%np_part, kpt%start:kpt%end))
272 mesh%np_part*kpt%nlocal())
276 if (.not.
allocated(phase%phase_corr))
then
277 safe_allocate(phase%phase_corr(mesh%np+1:mesh%np_part, kpt%start:kpt%end))
280 (mesh%np_part - mesh%np)*kpt%nlocal())
289 if (mesh%parallel_in_domains) sp = mesh%np + mesh%pv%np_ghost
291 safe_allocate(x_global(1:space%dim,(sp + 1):mesh%np_part))
294 do ip = sp + 1, mesh%np_part
298 x_global(:,ip) =
mesh_x_global(mesh, ip_inner_global) - mesh%x(1:space%dim, ip)
306 if (.not.
allocated(phase%phase_k))
then
307 safe_allocate(phase%phase_k(1:mesh%np_part, kpt%start:kpt%end))
308 safe_allocate(phase%phase_corr_k(sp + 1:mesh%np_part, kpt%start:kpt%end))
309 safe_allocate(phase%vp_phase(1:mesh%np_part))
310 safe_allocate(phase%vp_phase_corr(sp + 1:mesh%np_part))
312 do ik = kpt%start, kpt%end
313 kpoint(1:space%dim) = kpoints%get_point(d%get_kpoint_index(ik))
315 do ip = 1, mesh%np_part
316 tmp_sum = sum(mesh%x(1:space%dim, ip)*kpoint(1:space%dim))
317 phase%phase_k(ip, ik) = cmplx(
cos(tmp_sum), -
sin(tmp_sum), real64)
321 do ip = sp + 1, mesh%np_part
322 tmp_sum = sum(x_global(1:space%dim, ip)*kpoint(1:space%dim))
323 phase%phase_corr_k(ip, ik) = cmplx(
cos(tmp_sum),
sin(tmp_sum), real64)
333 do ip = 1, mesh%np_part
334 tmp_sum = sum(mesh%x(1:space%dim, ip)*uniform_vector_potential(1:space%dim))
335 phase%vp_phase(ip) = cmplx(
cos(tmp_sum), -
sin(tmp_sum), real64)
339 do ip = sp + 1, mesh%np_part
340 tmp_sum = sum(x_global(1:space%dim, ip)*uniform_vector_potential(1:space%dim))
341 phase%vp_phase_corr(ip) = cmplx(
cos(tmp_sum),
sin(tmp_sum), real64)
346 do ik = kpt%start, kpt%end
348 do ip = 1, mesh%np_part
349 phase%phase(ip, ik) = phase%phase_k(ip, ik) * phase%vp_phase(ip)
353 do ip = sp + 1, mesh%np_part
354 phase%phase_corr(ip, ik) = phase%phase_corr_k(ip, ik) * phase%vp_phase_corr(ip)
363 safe_allocate(kpt_vec_pot(1:space%dim,kpt%start:kpt%end))
364 do ik = kpt%start, kpt%end
365 kpoint(1:space%dim) = kpoints%get_point(d%get_kpoint_index(ik))
366 kpt_vec_pot(1:space%dim, ik) = kpoint(1:space%dim) + uniform_vector_potential(1:space%dim)
375 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.)
377 write(kernel_name,
'(a,i1,a)')
'update_phases<double, Dim::D', space%dim,
'>'
378 kernel => kernels(space%dim)
393 np = (/mesh%np_part, kpt%nlocal()/)
400 call accel_read_buffer(phase%buff_phase_corr, mesh%np_part - mesh%np, kpt%nlocal(), phase%phase_corr)
405 safe_deallocate_a(kpt_vec_pot)
408 safe_deallocate_a(x_global)
416 class(
phase_t),
intent(inout) :: phase
429 safe_deallocate_a(phase%phase)
430 safe_deallocate_a(phase%phase_corr)
431 safe_deallocate_a(phase%phase_k)
432 safe_deallocate_a(phase%phase_corr_k)
433 safe_deallocate_a(phase%vp_phase)
434 safe_deallocate_a(phase%vp_phase_corr)
435 safe_deallocate_a(phase%phase_spiral)
443 class(
phase_t),
intent(inout) :: phase
444 class(
mesh_t),
intent(in) :: mesh
456 phase%buff_phase_qn_start = kpt%start
462 if (
allocated(phase%phase))
then
463 assert(
size(phase%phase, 1) == mesh%np_part)
464 nlocal = ubound(phase%phase, dim=2) - lbound(phase%phase, dim=2) + 1
469 if (
allocated(phase%phase_corr))
then
470 assert(
size(phase%phase_corr, 1) == mesh%np_part - mesh%np)
471 nlocal = ubound(phase%phase_corr, dim=2) - lbound(phase%phase_corr, dim=2) + 1
473 size(phase%phase_corr, 1)*nlocal)
474 call accel_write_buffer(phase%buff_phase_corr,
size(phase%phase_corr, 1), nlocal, phase%phase_corr)
477 if (
allocated(phase%phase_spiral))
then
479 size(phase%phase_spiral, 1)*
size(phase%phase_spiral, 2))
481 size(phase%phase_spiral, 2), phase%phase_spiral)
491 class(
phase_t),
intent(in) :: phase
492 class(
mesh_t),
intent(in) :: mesh
494 logical,
optional,
intent(in) :: async
497 logical :: phase_correction
502 phase_correction = phase%is_allocated()
506 if (phase_correction)
then
507 call phase%apply_to(mesh, mesh%np, .false., psib, async=async)
517 class(
phase_t),
intent(in) :: phase
518 class(
mesh_t),
intent(in) :: mesh
520 logical,
optional,
intent(in) :: async
522 logical :: phase_correction
527 phase_correction = phase%is_allocated()
531 if (phase_correction)
then
532 call phase%apply_to(mesh, mesh%np, .
true., psib, async=async)
542 class(
phase_t),
intent(in) :: this
543 class(
mesh_t),
intent(in) :: mesh
544 integer,
intent(in) :: np
545 logical,
intent(in) :: conjugate
546 type(
wfs_elec_t),
target,
intent(inout) :: psib
547 type(
wfs_elec_t),
optional,
target,
intent(in) :: src
548 logical,
optional,
intent(in) :: async
550 integer :: ip, ii, sp
552 complex(real64) :: phase
553 integer(int64),
dimension(3) :: gsizes, bsizes
561 assert(np <= mesh%np_part)
563 assert(psib%ik >= lbound(this%phase, dim=2))
564 assert(psib%ik <= ubound(this%phase, dim=2))
567 if (
present(src)) src_ => src
569 assert(src_%has_phase .eqv. conjugate)
570 assert(src_%ik == psib%ik)
574 sp = min(np, mesh%np)
575 if (np > mesh%np .and. mesh%parallel_in_domains) sp = mesh%np + mesh%pv%np_ghost
577 select case (psib%status())
584 do ip = 1, min(mesh%np, np)
585 phase = conjg(this%phase(ip, psib%ik))
587 do ii = 1, psib%nst_linear
588 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
596 phase = conjg(this%phase(ip, psib%ik))
598 do ii = 1, psib%nst_linear
599 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
608 do ip = 1, min(mesh%np, np)
609 phase = this%phase(ip, psib%ik)
611 do ii = 1, psib%nst_linear
612 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
620 phase = this%phase(ip, psib%ik)
622 do ii = 1, psib%nst_linear
623 psib%zff_pack(ii, ip) = phase*src_%zff_pack(ii, ip)
635 do ii = 1, psib%nst_linear
637 do ip = 1, min(mesh%np, np)
638 psib%zff_linear(ip, ii) = conjg(this%phase(ip, psib%ik))*src_%zff_linear(ip, ii)
645 psib%zff_linear(ip, ii) = conjg(this%phase(ip, psib%ik))*src_%zff_linear(ip, ii)
653 do ii = 1, psib%nst_linear
655 do ip = 1, min(mesh%np, np)
656 psib%zff_linear(ip, ii) = this%phase(ip, psib%ik)*src_%zff_linear(ip, ii)
663 psib%zff_linear(ip, ii) = this%phase(ip, psib%ik)*src_%zff_linear(ip, ii)
697 psib%has_phase = .not. conjugate
710 class(
phase_t),
intent(in) :: this
711 complex(real64),
intent(inout) :: psi(:, :)
712 integer,
intent(in) :: np
713 integer,
intent(in) :: dim
714 integer,
intent(in) :: ik
715 logical,
intent(in) :: conjugate
721 assert(ik >= lbound(this%phase, dim=2))
722 assert(ik <= ubound(this%phase, dim=2))
731 psi(ip, idim) = conjg(this%phase(ip, ik))*psi(ip, idim)
740 psi(ip, idim) = this%phase(ip, ik)*psi(ip, idim)
756 class(
phase_t),
intent(in) :: this
760 integer :: ip, ii, sp
761 integer,
allocatable :: spin_label(:)
763 integer(int64) :: bsize
764 integer(int64),
dimension(2) :: np, gsizes, bsizes
771 assert(der%boundaries%spiral)
775 if (der%mesh%parallel_in_domains) sp = der%mesh%np + der%mesh%pv%np_ghost
778 select case (psib%status())
782 do ip = sp + 1, der%mesh%np_part
783 do ii = 1, psib%nst_linear, 2
784 if (this%spin(3,psib%linear_to_ist(ii), psib%ik)>0)
then
785 psib%zff_pack(ii+1, ip) = psib%zff_pack(ii+1, ip)*this%phase_spiral(ip-sp, 1)
787 psib%zff_pack(ii, ip) = psib%zff_pack(ii, ip)*this%phase_spiral(ip-sp, 2)
796 do ii = 1, psib%nst_linear, 2
797 if (this%spin(3,psib%linear_to_ist(ii), psib%ik)>0)
then
799 do ip = sp + 1, der%mesh%np_part
800 psib%zff_linear(ip, ii+1) = psib%zff_linear(ip, ii+1)*this%phase_spiral(ip-sp, 1)
805 do ip = sp + 1, der%mesh%np_part
806 psib%zff_linear(ip, ii) = psib%zff_linear(ip, ii)*this%phase_spiral(ip-sp, 2)
822 safe_allocate(spin_label(1:psib%nst_linear))
824 do ii = 1, psib%nst_linear, 2
825 if (this%spin(3, psib%linear_to_ist(ii), psib%ik) > 0) spin_label(ii)=1
843 np = (/psib%pack_size(1)/2_int64, int(der%mesh%np_part - sp, int64)/)
844 bsizes = (/psib%pack_size(1)/2, 2*bsize/)
853 safe_deallocate_a(spin_label)
863 logical pure function phase_is_allocated(this)
864 class(
phase_t),
intent(in) :: this
866 phase_is_allocated =
allocated(this%phase)
877 class(
phase_t),
intent(in) :: phase
878 type(grid_t),
intent(in) :: gr
879 type(distributed_t),
intent(in) :: kpt
880 type(wfs_elec_t),
intent(in) :: psib
881 type(wfs_elec_t),
intent(out) :: psib_with_phase
883 integer :: k_offset, n_boundary_points
887 call psib%copy_to(psib_with_phase)
888 if (phase%is_allocated())
then
889 call phase%apply_to(gr, gr%np, conjugate = .false., psib = psib_with_phase, src = psib, async=.
true.)
892 k_offset = psib%ik - kpt%start
893 n_boundary_points = int(gr%np_part - gr%np)
894 call boundaries_set(gr%der%boundaries, gr, psib_with_phase, phase_correction = phase%phase_corr(:, psib%ik), &
895 buff_phase_corr = phase%buff_phase_corr, offset=k_offset*n_boundary_points, async=.
true.)
897 call psib%copy_data_to(gr%np, psib_with_phase)
898 call boundaries_set(gr%der%boundaries, gr, psib_with_phase)
901 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