65 type(projector_matrix_t),
allocatable,
public :: projector_matrices(:)
66 integer,
public :: nprojector_matrices
67 logical,
public :: apply_projector_matrices
68 logical,
public :: has_non_local_potential
69 integer :: full_projection_size
70 integer,
public :: max_npoints
71 integer,
public :: total_points
73 logical :: projector_mix
74 complex(real64),
allocatable,
public :: projector_phases(:, :, :, :)
75 integer,
allocatable,
public :: projector_to_atom(:)
77 integer,
allocatable :: regions(:)
78 integer,
public :: nphase
83 type(accel_mem_t) :: buff_offsets
84 type(accel_mem_t) :: buff_matrices
85 type(accel_mem_t) :: buff_maps
86 type(accel_mem_t) :: buff_scals
87 type(accel_mem_t) :: buff_position
88 type(accel_mem_t) :: buff_pos
89 type(accel_mem_t) :: buff_invmap
90 type(accel_mem_t) :: buff_invmap_mat
91 type(accel_mem_t),
public :: buff_projector_phases
92 type(accel_mem_t) :: buff_mix
93 logical :: projector_self_overlap
94 real(real64),
pointer,
public :: spin(:,:,:) => null()
131 real(real64),
allocatable :: dprojection(:, :)
132 complex(real64),
allocatable :: zprojection(:, :)
133 type(accel_mem_t) :: buff_projection
134 type(accel_mem_t) :: buff_spin_to_phase
135 type(accel_mem_t),
allocatable :: buff_phasepsi(:)
136 type(accel_mem_t),
allocatable :: buff_projection_temp(:)
137 integer :: cuda_stream_projection_DtH
146 class(nonlocal_pseudopotential_t),
intent(inout) :: this
150 this%apply_projector_matrices = .false.
151 this%has_non_local_potential = .false.
152 this%nprojector_matrices = 0
154 this%projector_self_overlap = .false.
168 integer :: imat, iatom
173 if (.not.
allocated(this%projector_matrices) .or. this%nprojector_matrices == 0)
then
178 assert(
allocated(this%projector_to_atom))
179 assert(
size(this%projector_matrices) >= this%nprojector_matrices)
180 assert(
size(this%projector_to_atom) >= this%nprojector_matrices)
182 do imat = 1, this%nprojector_matrices
183 pmat => this%projector_matrices(imat)
184 iatom = this%projector_to_atom(imat)
186 assert(iatom >= 1 .and. iatom <= epot%natoms)
187 assert(
allocated(epot%proj))
188 assert(
allocated(epot%proj(iatom)%sphere%map))
189 assert(
allocated(epot%proj(iatom)%sphere%rel_x))
191 pmat%map => epot%proj(iatom)%sphere%map
192 pmat%position => epot%proj(iatom)%sphere%rel_x
208 if (
allocated(this%projector_matrices))
then
220 if (
allocated(this%projector_phases))
call accel_free_buffer(this%buff_projector_phases)
223 do iproj = 1, this%nprojector_matrices
226 safe_deallocate_a(this%regions)
227 safe_deallocate_a(this%projector_matrices)
228 safe_deallocate_a(this%projector_phases)
229 safe_deallocate_a(this%projector_to_atom)
244 class(
space_t),
intent(in) :: space
245 class(
mesh_t),
intent(in) :: mesh
246 type(
epot_t),
target,
intent(in) :: epot
248 integer :: iatom, iproj, ll, lmax, lloc, mm, ic, jc
249 integer :: nmat, imat, ip, iorder
250 integer :: nregion, jatom, katom, iregion
251 integer,
allocatable :: order(:),
head(:), region_count(:)
252 logical,
allocatable :: atom_counted(:)
266 safe_allocate(order(1:epot%natoms))
267 safe_allocate(
head(1:epot%natoms + 1))
268 safe_allocate(region_count(1:epot%natoms))
269 safe_allocate(atom_counted(1:epot%natoms))
271 this%projector_self_overlap = .false.
272 atom_counted = .false.
278 nregion = nregion + 1
279 assert(nregion <= epot%natoms)
281 region_count(nregion) = 0
283 do iatom = 1, epot%natoms
284 if (atom_counted(iatom)) cycle
289 assert(
associated(epot%proj(iatom)%sphere%mesh))
290 do jatom = 1, region_count(nregion)
291 katom = order(
head(nregion) + jatom - 1)
293 overlap =
submesh_overlap(epot%proj(iatom)%sphere, epot%proj(katom)%sphere, space)
298 if (.not. overlap)
then
301 region_count(nregion) = region_count(nregion) + 1
302 order(
head(nregion) - 1 + region_count(nregion)) = iatom
303 atom_counted(iatom) = .
true.
308 head(nregion + 1) =
head(nregion) + region_count(nregion)
310 if (all(atom_counted))
exit
313 safe_deallocate_a(atom_counted)
314 safe_deallocate_a(region_count)
321 do iregion = 1, nregion
322 do iatom =
head(iregion),
head(iregion + 1) - 1
324 do jatom =
head(iregion), iatom - 1
326 assert(.not.
submesh_overlap(epot%proj(order(iatom))%sphere, epot%proj(order(jatom))%sphere, space))
337 this%nprojector_matrices = 0
338 this%apply_projector_matrices = .false.
339 this%has_non_local_potential = .false.
340 this%nregions = nregion
343 do iorder = 1, epot%natoms
344 iatom = order(iorder)
347 this%has_non_local_potential = .
true.
352 do iorder = 1, epot%natoms
353 iatom = order(iorder)
356 this%nprojector_matrices = this%nprojector_matrices + 1
357 this%apply_projector_matrices = .
true.
362 if (mesh%use_curvilinear) this%apply_projector_matrices = .false.
364 if (.not. this%apply_projector_matrices)
then
365 safe_deallocate_a(order)
366 safe_deallocate_a(
head)
373 safe_allocate(this%projector_matrices(1:this%nprojector_matrices))
374 safe_allocate(this%regions(1:this%nregions + 1))
375 safe_allocate(this%projector_to_atom(1:epot%natoms))
377 this%full_projection_size = 0
378 this%regions(this%nregions + 1) = this%nprojector_matrices + 1
380 this%projector_mix = .false.
383 do iregion = 1, this%nregions
384 this%regions(iregion) = iproj + 1
385 do iorder =
head(iregion),
head(iregion + 1) - 1
387 iatom = order(iorder)
393 pmat => this%projector_matrices(iproj)
395 this%projector_to_atom(iproj) = iatom
397 lmax = epot%proj(iatom)%lmax
398 lloc = epot%proj(iatom)%lloc
405 if (ll == lloc) cycle
407 nmat = nmat + epot%proj(iatom)%kb_p(ll, mm)%n_c
417 if (ll == lloc) cycle
419 kb_p => epot%proj(iatom)%kb_p(ll, mm)
421 call lalg_copy(pmat%npoints, kb_p%p(:, ic), pmat%dprojectors(:, imat))
422 pmat%scal(imat) = kb_p%e(ic)*mesh%vol_pp(1)
428 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
432 this%projector_mix = .
true.
437 if (ll == lloc) cycle
444 has_mix_matrix = .
true., is_cmplx = (epot%proj_reltype ==
spin_orbit))
457 if (ll == lloc) cycle
459 hgh_p => epot%proj(iatom)%hgh_p(ll, mm)
466 pmat%zmix(imat - 1 + ic, imat - 1 + jc, 1) = hgh_p%h(ic, jc) +
m_half*mm*hgh_p%k(ic, jc)
467 pmat%zmix(imat - 1 + ic, imat - 1 + jc, 2) = hgh_p%h(ic, jc) -
m_half*mm*hgh_p%k(ic, jc)
470 pmat%zmix(imat - 1 + ic, imat + 3 - 1 + jc, 3) =
m_half*hgh_p%k(ic, jc) * &
471 sqrt(real(ll*(ll+1)-mm*(mm+1), real64))
475 pmat%zmix(imat - 1 + ic, imat - 3 - 1 + jc, 4) =
m_half*hgh_p%k(ic, jc) * &
476 sqrt(real(ll*(ll+1)-mm*(mm-1), real64))
483 pmat%dmix(imat - 1 + ic, imat - 1 + jc) = hgh_p%h(ic, jc)
490 call lalg_copy(pmat%npoints, hgh_p%zp(:, ic), pmat%zprojectors(:, imat))
492 call lalg_copy(pmat%npoints, hgh_p%dp(:, ic), pmat%dprojectors(:, imat))
494 pmat%scal(imat) = mesh%volume_element
501 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
506 this%projector_mix = .
true.
510 if (lloc /= 0) nmat = nmat + epot%proj(iatom)%kb_p(1, 1)%n_c
513 if (ll == lloc) cycle
515 nmat = nmat + epot%proj(iatom)%rkb_p(ll, mm)%n_c
520 has_mix_matrix = .
true., is_cmplx = .
true.)
527 kb_p => epot%proj(iatom)%kb_p(1, 1)
530 pmat%zmix(ic, ic, 1:2) = kb_p%e(ic)
531 do ip = 1, pmat%npoints
532 pmat%zprojectors(ip, ic) = kb_p%p(ip, ic)
534 pmat%scal(ic) = mesh%volume_element
541 if (ll == lloc) cycle
543 rkb_p => epot%proj(iatom)%rkb_p(ll, mm)
546 do ic = 0, rkb_p%n_c/2-1
547 pmat%zmix(imat + ic*2, imat + ic*2, 1) = rkb_p%f(ic*2+1, 1, 1)
548 pmat%zmix(imat + ic*2, imat + ic*2, 2) = rkb_p%f(ic*2+1, 2, 2)
550 pmat%zmix(imat + ic*2+1, imat + ic*2+1, 1) = rkb_p%f(ic*2+2, 1, 1)
551 pmat%zmix(imat + ic*2+1, imat + ic*2+1, 2) = rkb_p%f(ic*2+2, 2, 2)
554 pmat%zmix(imat + ic*2+rkb_p%n_c, imat + ic*2, 4) = rkb_p%f(ic*2+1, 2, 1)
555 pmat%zmix(imat + ic*2+1+rkb_p%n_c, imat + ic*2+1, 4) = rkb_p%f(ic*2+2, 2, 1)
559 pmat%zmix(imat + ic*2-rkb_p%n_c, imat + ic*2, 3) = rkb_p%f(ic*2+1, 1, 2)
560 pmat%zmix(imat + ic*2+1-rkb_p%n_c, imat + ic*2+1, 3) = rkb_p%f(ic*2+2, 1, 2)
565 call lalg_copy(pmat%npoints, rkb_p%ket(:, ic, 1, 1), pmat%zprojectors(:, imat))
566 pmat%scal(imat) = mesh%volume_element
574 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
580 pmat%map => epot%proj(iatom)%sphere%map
581 pmat%position => epot%proj(iatom)%sphere%rel_x
583 pmat%regions = epot%proj(iatom)%sphere%regions
585 this%full_projection_size = this%full_projection_size + pmat%nprojs
590 if (mesh%parallel_in_domains)
then
591 call mesh%mpi_grp%allreduce_inplace(this%projector_self_overlap, 1, mpi_logical, mpi_lor)
594 safe_deallocate_a(order)
595 safe_deallocate_a(
head)
597 this%total_points = 0
600 do imat = 1, this%nprojector_matrices
601 pmat => this%projector_matrices(imat)
603 this%max_npoints = max(this%max_npoints, pmat%npoints)
604 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
605 this%total_points = this%total_points + pmat%npoints
621 class(
space_t),
intent(in) :: space
622 class(
mesh_t),
intent(in) :: mesh
633 if (.not.
allocated(this%projector_matrices) .or. this%nprojector_matrices <= 0)
then
669 class(
space_t),
intent(in) :: space
670 class(
mesh_t),
intent(in) :: mesh
672 integer,
parameter :: OFFSET_SIZE = 6
673 integer,
parameter :: POINTS = 1, projs = 2, matrix = 3, map = 4, scal = 5, mix = 6
674 integer :: imat, matrix_size, scal_size
675 integer :: ip, is, ii, ipos, mix_offset
676 integer,
allocatable :: cnt(:), invmap(:, :), invmap2(:), pos(:)
677 integer,
allocatable :: invmap_mat(:, :), invmap_mat2(:)
678 integer,
allocatable :: offsets(:, :)
683 assert(
allocated(this%projector_matrices))
684 assert(this%nprojector_matrices > 0)
686 safe_allocate(offsets(1:offset_size, 1:this%nprojector_matrices))
687 safe_allocate(cnt(1:mesh%np))
692 this%total_points = 0
697 do imat = 1, this%nprojector_matrices
698 pmat => this%projector_matrices(imat)
700 this%max_npoints = max(this%max_npoints, pmat%npoints)
701 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
703 offsets(points, imat) = pmat%npoints
704 offsets(projs, imat) = pmat%nprojs
706 offsets(matrix, imat) = matrix_size
707 matrix_size = matrix_size + pmat%npoints*pmat%nprojs
709 offsets(map, imat) = this%total_points
710 this%total_points = this%total_points + pmat%npoints
712 offsets(scal, imat) = scal_size
713 scal_size = scal_size + pmat%nprojs
715 offsets(mix, imat) = mix_offset
716 if (
allocated(pmat%dmix))
then
717 mix_offset = mix_offset + pmat%nprojs**2
718 else if (
allocated(pmat%zmix))
then
719 mix_offset = mix_offset + 4*pmat%nprojs**2
721 offsets(mix, imat) = -1
724 do is = 1, pmat%npoints
726 cnt(ip) = cnt(ip) + 1
730 safe_allocate(invmap(1:max(maxval(cnt), 1), 1:mesh%np))
731 safe_allocate(invmap2(1:max(maxval(cnt)*mesh%np, 1)))
732 safe_allocate(invmap_mat(1:max(maxval(cnt), 1), 1:mesh%np))
733 safe_allocate(invmap_mat2(1:max(maxval(cnt)*mesh%np, 1)))
734 safe_allocate(pos(1:mesh%np + 1))
738 do imat = 1, this%nprojector_matrices
739 pmat => this%projector_matrices(imat)
740 do is = 1, pmat%npoints
742 cnt(ip) = cnt(ip) + 1
743 invmap(cnt(ip), ip) = ii
744 invmap_mat(cnt(ip), ip) = imat - 1
754 invmap2(ipos) = invmap(ii, ip)
755 invmap_mat2(ipos) = invmap_mat(ii, ip)
760 if (this%projector_matrices(1)%is_cmplx)
then
769 if (mix_offset > 0)
then
770 if (
allocated(this%projector_matrices(1)%zmix))
then
777 do imat = 1, this%nprojector_matrices
778 pmat => this%projector_matrices(imat)
779 if (pmat%npoints > 0)
then
780 if (pmat%is_cmplx)
then
781 call accel_write_buffer(this%buff_matrices, pmat%npoints, pmat%nprojs, pmat%zprojectors, &
782 offset = offsets(matrix, imat))
784 call accel_write_buffer(this%buff_matrices, pmat%npoints, pmat%nprojs, pmat%dprojectors, &
785 offset = offsets(matrix, imat))
787 call accel_write_buffer(this%buff_maps, pmat%npoints, pmat%map, offset = offsets(map, imat))
789 offset = 3*offsets(map, imat))
791 call accel_write_buffer(this%buff_scals, pmat%nprojs, pmat%scal, offset = offsets(scal, imat))
792 if (offsets(mix, imat) /= -1)
then
793 if (
allocated(pmat%zmix))
then
794 call accel_write_buffer(this%buff_mix, pmat%nprojs, pmat%nprojs, 4, pmat%zmix, offset = offsets(mix, imat))
796 call accel_write_buffer(this%buff_mix, pmat%nprojs, pmat%nprojs, pmat%dmix, offset = offsets(mix, imat))
802 call accel_write_buffer(this%buff_offsets, offset_size, this%nprojector_matrices, offsets)
813 safe_deallocate_a(offsets)
814 safe_deallocate_a(cnt)
815 safe_deallocate_a(invmap)
816 safe_deallocate_a(invmap2)
817 safe_deallocate_a(invmap_mat)
818 safe_deallocate_a(invmap_mat2)
819 safe_deallocate_a(pos)
829 integer :: ik, imat, iphase, nphase, offset, npoints
833 if (.not.
allocated(this%projector_phases))
then
838 nphase =
size(this%projector_phases, 2)
842 this%total_points*nphase*
size(this%projector_phases, 4))
845 do ik = lbound(this%projector_phases, 4), ubound(this%projector_phases, 4)
846 do imat = 1, this%nprojector_matrices
847 npoints = this%projector_matrices(imat)%npoints
848 do iphase = 1, nphase
849 if (npoints > 0)
then
850 call accel_write_buffer(this%buff_projector_phases, npoints, this%projector_phases(1:, iphase, imat, ik), &
851 offset = offset, async=.
true.)
853 offset = offset + npoints
865 logical pure function nonlocal_pseudopotential_self_overlap(this) result(projector_self_overlap)
868 projector_self_overlap = this%projector_self_overlap
873#include "nonlocal_pseudopotential_inc.F90"
876#include "complex.F90"
877#include "nonlocal_pseudopotential_inc.F90"
Copies a vector x, to a vector y.
double sqrt(double __x) __attribute__((__nothrow__
subroutine, public accel_free_buffer(this, async)
subroutine, public accel_finish()
subroutine, public accel_detach_buffer(this)
Clear a buffer handle without freeing device memory.
pure logical function, public accel_is_enabled()
integer, parameter, public accel_mem_read_only
type(accel_kernel_t), pointer head
This module implements batches of mesh functions.
This module implements common operations on batches of mesh functions.
This module contains interfaces for BLAS routines You should not use these routines directly....
integer, parameter, public spin_orbit
real(real64), parameter, public m_zero
real(real64), parameter, public m_half
This module is intended to contain "only mathematical" functions and procedures.
This module defines the meshes, which are used in Octopus.
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
subroutine nonlocal_pseudopotential_destroy_proj(this)
Destroy the data of nonlocal_pseudopotential_t.
subroutine nonlocal_pseudopotential_detach_accel_buffers(this)
Clear copied accelerator handles so they do not alias source buffers.
subroutine dnonlocal_pseudopotential_force(this, mesh, st, spiral_bnd, iqn, ndim, psi1b, psi2b, force)
calculate contribution to forces, from non-local potentials
subroutine znonlocal_pseudopotential_position_commutator(this, mesh, std, spiral_bnd, psib, commpsib, async)
apply the commutator between the non-local potential and the position to the wave functions.
subroutine znonlocal_pseudopotential_force(this, mesh, st, spiral_bnd, iqn, ndim, psi1b, psi2b, force)
calculate contribution to forces, from non-local potentials
subroutine dnonlocal_pseudopotential_start(this, mesh, std, spiral_bnd, psib, projection, async)
Start application of non-local potentials (stored in the Hamiltonian) to the wave functions.
subroutine dnonlocal_pseudopotential_finish(this, mesh, spiral_bnd, std, projection, vpsib)
finish the application of non-local potentials.
subroutine, public nonlocal_pseudopotential_accel_rebuild(this, space, mesh)
Rebuild accelerator buffers after an intrinsic copy.
subroutine dnonlocal_pseudopotential_position_commutator(this, mesh, std, spiral_bnd, psib, commpsib, async)
apply the commutator between the non-local potential and the position to the wave functions.
subroutine, public nonlocal_pseudopotential_rebind_projectors(this, epot)
Rebind projector matrix pointers (map, position) to a target epot.
subroutine nonlocal_pseudopotential_build_accel_buffers(this, space, mesh)
Build accelerator buffers for projectors from host-side projector matrices.
subroutine znonlocal_pseudopotential_r_vnlocal(this, mesh, std, spiral_bnd, psib, commpsib)
Accumulates to commpsib the result of x V_{nl} | psib >
logical pure function nonlocal_pseudopotential_self_overlap(this)
Returns .true. if the Hamiltonian contains projectors, which overlap with themself.
subroutine nonlocal_pseudopotential_init(this)
initialize the nonlocal_pseudopotential_t object
subroutine dnonlocal_pseudopotential_r_vnlocal(this, mesh, std, spiral_bnd, psib, commpsib)
Accumulates to commpsib the result of x V_{nl} | psib >
subroutine znonlocal_pseudopotential_start(this, mesh, std, spiral_bnd, psib, projection, async)
Start application of non-local potentials (stored in the Hamiltonian) to the wave functions.
subroutine nonlocal_pseudopotential_build_projector_phase_accel_buffer(this)
Rebuild projector phase accelerator buffer from host-side projector phases.
subroutine nonlocal_pseudopotential_build_proj(this, space, mesh, epot)
build the projectors for the application of pseudo-potentials
subroutine znonlocal_pseudopotential_finish(this, mesh, spiral_bnd, std, projection, vpsib)
finish the application of non-local potentials.
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.
subroutine, public projector_matrix_deallocate(this)
subroutine, public projector_matrix_allocate(this, nprojs, sphere, has_mix_matrix, is_cmplx)
logical elemental function, public projector_is(p, type)
logical elemental function, public projector_is_null(p)
integer, parameter, public proj_hgh
integer, parameter, public proj_rkb
integer, parameter, public proj_none
integer, parameter, public proj_kb
This module handles spin dimensions of the states and the k-point distribution.
logical function, public submesh_overlap(sm1, sm2, space)
type(type_t), parameter, public type_cmplx
type(type_t), parameter, public type_integer
type(type_t), parameter, public type_float
Describes mesh distribution to nodes.
nonlocal part of the pseudopotential
Class for projections of wave functions.
A set of projectors defined on a submesh.
The rkb_projector data type holds the KB projectors build with total angular momentum eigenfunctions....