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) :: buff_point_to_mat
92 type(accel_mem_t) :: buff_proj_to_mat
93 type(accel_mem_t),
public :: buff_projector_phases
94 type(accel_mem_t),
pointer,
public :: buff_bra_phasepsi => null()
95 type(accel_mem_t),
pointer,
public :: buff_bra_projection_temp => null()
96 type(accel_mem_t) :: buff_mix
97 logical :: projector_self_overlap
98 real(real64),
pointer,
public :: spin(:,:,:) => null()
136 real(real64),
allocatable :: dprojection(:, :)
137 complex(real64),
allocatable :: zprojection(:, :)
138 type(accel_mem_t) :: buff_projection
139 type(accel_mem_t) :: buff_spin_to_phase
140 integer :: cuda_stream_projection_DtH
149 class(nonlocal_pseudopotential_t),
intent(inout) :: this
153 this%apply_projector_matrices = .false.
154 this%has_non_local_potential = .false.
155 this%nprojector_matrices = 0
157 this%projector_self_overlap = .false.
171 integer :: imat, iatom
177 nullify(this%buff_bra_phasepsi)
178 nullify(this%buff_bra_projection_temp)
179 safe_allocate(this%buff_bra_phasepsi)
180 safe_allocate(this%buff_bra_projection_temp)
182 if (.not.
allocated(this%projector_matrices) .or. this%nprojector_matrices == 0)
then
187 assert(
allocated(this%projector_to_atom))
188 assert(
size(this%projector_matrices) >= this%nprojector_matrices)
189 assert(
size(this%projector_to_atom) >= this%nprojector_matrices)
191 do imat = 1, this%nprojector_matrices
192 pmat => this%projector_matrices(imat)
193 iatom = this%projector_to_atom(imat)
195 assert(iatom >= 1 .and. iatom <= epot%natoms)
196 assert(
allocated(epot%proj))
197 assert(
allocated(epot%proj(iatom)%sphere%map))
198 assert(
allocated(epot%proj(iatom)%sphere%rel_x))
200 pmat%map => epot%proj(iatom)%sphere%map
201 pmat%position => epot%proj(iatom)%sphere%rel_x
218 if (
allocated(this%projector_matrices))
then
235 do iproj = 1, this%nprojector_matrices
238 safe_deallocate_a(this%regions)
239 safe_deallocate_a(this%projector_matrices)
240 safe_deallocate_a(this%projector_phases)
241 safe_deallocate_a(this%projector_to_atom)
244 if (
associated(this%buff_bra_phasepsi))
then
247 if (
associated(this%buff_bra_projection_temp))
then
250 safe_deallocate_p(this%buff_bra_phasepsi)
251 safe_deallocate_p(this%buff_bra_projection_temp)
265 class(
space_t),
intent(in) :: space
266 class(
mesh_t),
intent(in) :: mesh
267 type(
epot_t),
target,
intent(in) :: epot
269 integer :: iatom, iproj, ll, lmax, lloc, mm, ic, jc
270 integer :: nmat, imat, ip, iorder
271 integer :: nregion, jatom, katom, iregion
272 integer,
allocatable :: order(:),
head(:), region_count(:)
273 logical,
allocatable :: atom_counted(:)
287 safe_allocate(order(1:epot%natoms))
288 safe_allocate(
head(1:epot%natoms + 1))
289 safe_allocate(region_count(1:epot%natoms))
290 safe_allocate(atom_counted(1:epot%natoms))
292 this%projector_self_overlap = .false.
293 atom_counted = .false.
299 nregion = nregion + 1
300 assert(nregion <= epot%natoms)
302 region_count(nregion) = 0
304 do iatom = 1, epot%natoms
305 if (atom_counted(iatom)) cycle
310 assert(
associated(epot%proj(iatom)%sphere%mesh))
311 do jatom = 1, region_count(nregion)
312 katom = order(
head(nregion) + jatom - 1)
314 overlap =
submesh_overlap(epot%proj(iatom)%sphere, epot%proj(katom)%sphere, space)
319 if (.not. overlap)
then
322 region_count(nregion) = region_count(nregion) + 1
323 order(
head(nregion) - 1 + region_count(nregion)) = iatom
324 atom_counted(iatom) = .
true.
329 head(nregion + 1) =
head(nregion) + region_count(nregion)
331 if (all(atom_counted))
exit
334 safe_deallocate_a(atom_counted)
335 safe_deallocate_a(region_count)
342 do iregion = 1, nregion
343 do iatom =
head(iregion),
head(iregion + 1) - 1
345 do jatom =
head(iregion), iatom - 1
347 assert(.not.
submesh_overlap(epot%proj(order(iatom))%sphere, epot%proj(order(jatom))%sphere, space))
359 safe_allocate(this%buff_bra_phasepsi)
360 safe_allocate(this%buff_bra_projection_temp)
363 this%nprojector_matrices = 0
364 this%apply_projector_matrices = .false.
365 this%has_non_local_potential = .false.
366 this%nregions = nregion
369 do iorder = 1, epot%natoms
370 iatom = order(iorder)
373 this%has_non_local_potential = .
true.
378 do iorder = 1, epot%natoms
379 iatom = order(iorder)
382 this%nprojector_matrices = this%nprojector_matrices + 1
383 this%apply_projector_matrices = .
true.
388 if (mesh%use_curvilinear) this%apply_projector_matrices = .false.
390 if (.not. this%apply_projector_matrices)
then
391 safe_deallocate_a(order)
392 safe_deallocate_a(
head)
399 safe_allocate(this%projector_matrices(1:this%nprojector_matrices))
400 safe_allocate(this%regions(1:this%nregions + 1))
401 safe_allocate(this%projector_to_atom(1:epot%natoms))
403 this%full_projection_size = 0
404 this%regions(this%nregions + 1) = this%nprojector_matrices + 1
406 this%projector_mix = .false.
409 do iregion = 1, this%nregions
410 this%regions(iregion) = iproj + 1
411 do iorder =
head(iregion),
head(iregion + 1) - 1
413 iatom = order(iorder)
419 pmat => this%projector_matrices(iproj)
421 this%projector_to_atom(iproj) = iatom
423 lmax = epot%proj(iatom)%lmax
424 lloc = epot%proj(iatom)%lloc
431 if (ll == lloc) cycle
433 nmat = nmat + epot%proj(iatom)%kb_p(ll, mm)%n_c
443 if (ll == lloc) cycle
445 kb_p => epot%proj(iatom)%kb_p(ll, mm)
447 call lalg_copy(pmat%npoints, kb_p%p(:, ic), pmat%dprojectors(:, imat))
448 pmat%scal(imat) = kb_p%e(ic)*mesh%vol_pp(1)
454 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
458 this%projector_mix = .
true.
463 if (ll == lloc) cycle
470 has_mix_matrix = .
true., is_cmplx = (epot%proj_reltype ==
spin_orbit))
483 if (ll == lloc) cycle
485 hgh_p => epot%proj(iatom)%hgh_p(ll, mm)
492 pmat%zmix(imat - 1 + ic, imat - 1 + jc, 1) = hgh_p%h(ic, jc) +
m_half*mm*hgh_p%k(ic, jc)
493 pmat%zmix(imat - 1 + ic, imat - 1 + jc, 2) = hgh_p%h(ic, jc) -
m_half*mm*hgh_p%k(ic, jc)
496 pmat%zmix(imat - 1 + ic, imat + 3 - 1 + jc, 3) =
m_half*hgh_p%k(ic, jc) * &
497 sqrt(real(ll*(ll+1)-mm*(mm+1), real64))
501 pmat%zmix(imat - 1 + ic, imat - 3 - 1 + jc, 4) =
m_half*hgh_p%k(ic, jc) * &
502 sqrt(real(ll*(ll+1)-mm*(mm-1), real64))
509 pmat%dmix(imat - 1 + ic, imat - 1 + jc) = hgh_p%h(ic, jc)
516 call lalg_copy(pmat%npoints, hgh_p%zp(:, ic), pmat%zprojectors(:, imat))
518 call lalg_copy(pmat%npoints, hgh_p%dp(:, ic), pmat%dprojectors(:, imat))
520 pmat%scal(imat) = mesh%volume_element
527 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
532 this%projector_mix = .
true.
536 if (lloc /= 0) nmat = nmat + epot%proj(iatom)%kb_p(1, 1)%n_c
539 if (ll == lloc) cycle
541 nmat = nmat + epot%proj(iatom)%rkb_p(ll, mm)%n_c
546 has_mix_matrix = .
true., is_cmplx = .
true.)
553 kb_p => epot%proj(iatom)%kb_p(1, 1)
556 pmat%zmix(ic, ic, 1:2) = kb_p%e(ic)
557 do ip = 1, pmat%npoints
558 pmat%zprojectors(ip, ic) = kb_p%p(ip, ic)
560 pmat%scal(ic) = mesh%volume_element
567 if (ll == lloc) cycle
569 rkb_p => epot%proj(iatom)%rkb_p(ll, mm)
572 do ic = 0, rkb_p%n_c/2-1
573 pmat%zmix(imat + ic*2, imat + ic*2, 1) = rkb_p%f(ic*2+1, 1, 1)
574 pmat%zmix(imat + ic*2, imat + ic*2, 2) = rkb_p%f(ic*2+1, 2, 2)
576 pmat%zmix(imat + ic*2+1, imat + ic*2+1, 1) = rkb_p%f(ic*2+2, 1, 1)
577 pmat%zmix(imat + ic*2+1, imat + ic*2+1, 2) = rkb_p%f(ic*2+2, 2, 2)
580 pmat%zmix(imat + ic*2+rkb_p%n_c, imat + ic*2, 4) = rkb_p%f(ic*2+1, 2, 1)
581 pmat%zmix(imat + ic*2+1+rkb_p%n_c, imat + ic*2+1, 4) = rkb_p%f(ic*2+2, 2, 1)
585 pmat%zmix(imat + ic*2-rkb_p%n_c, imat + ic*2, 3) = rkb_p%f(ic*2+1, 1, 2)
586 pmat%zmix(imat + ic*2+1-rkb_p%n_c, imat + ic*2+1, 3) = rkb_p%f(ic*2+2, 1, 2)
591 call lalg_copy(pmat%npoints, rkb_p%ket(:, ic, 1, 1), pmat%zprojectors(:, imat))
592 pmat%scal(imat) = mesh%volume_element
600 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
606 pmat%map => epot%proj(iatom)%sphere%map
607 pmat%position => epot%proj(iatom)%sphere%rel_x
609 pmat%regions = epot%proj(iatom)%sphere%regions
611 this%full_projection_size = this%full_projection_size + pmat%nprojs
616 if (mesh%parallel_in_domains)
then
617 call mesh%mpi_grp%allreduce_inplace(this%projector_self_overlap, 1, mpi_logical, mpi_lor)
620 safe_deallocate_a(order)
621 safe_deallocate_a(
head)
623 this%total_points = 0
626 do imat = 1, this%nprojector_matrices
627 pmat => this%projector_matrices(imat)
629 this%max_npoints = max(this%max_npoints, pmat%npoints)
630 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
631 this%total_points = this%total_points + pmat%npoints
647 class(
space_t),
intent(in) :: space
648 class(
mesh_t),
intent(in) :: mesh
659 if (.not.
allocated(this%projector_matrices) .or. this%nprojector_matrices <= 0)
then
697 class(
space_t),
intent(in) :: space
698 class(
mesh_t),
intent(in) :: mesh
700 integer,
parameter :: OFFSET_SIZE = 6
701 integer,
parameter :: POINTS = 1, projs = 2, matrix = 3, map = 4, scal = 5, mix = 6
702 integer :: imat, matrix_size, scal_size
703 integer :: ip, is, ii, ipos, mix_offset
704 integer,
allocatable :: cnt(:), invmap(:, :), invmap2(:), pos(:)
705 integer,
allocatable :: invmap_mat(:, :), invmap_mat2(:)
706 integer,
allocatable :: offsets(:, :), point_to_mat(:), proj_to_mat(:)
711 assert(
allocated(this%projector_matrices))
712 assert(this%nprojector_matrices > 0)
714 safe_allocate(offsets(1:offset_size, 1:this%nprojector_matrices))
715 safe_allocate(cnt(1:mesh%np))
720 this%total_points = 0
725 do imat = 1, this%nprojector_matrices
726 pmat => this%projector_matrices(imat)
728 this%max_npoints = max(this%max_npoints, pmat%npoints)
729 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
731 offsets(points, imat) = pmat%npoints
732 offsets(projs, imat) = pmat%nprojs
734 offsets(matrix, imat) = matrix_size
735 matrix_size = matrix_size + pmat%npoints*pmat%nprojs
737 offsets(map, imat) = this%total_points
738 this%total_points = this%total_points + pmat%npoints
740 offsets(scal, imat) = scal_size
741 scal_size = scal_size + pmat%nprojs
743 offsets(mix, imat) = mix_offset
744 if (
allocated(pmat%dmix))
then
745 mix_offset = mix_offset + pmat%nprojs**2
746 else if (
allocated(pmat%zmix))
then
747 mix_offset = mix_offset + 4*pmat%nprojs**2
749 offsets(mix, imat) = -1
752 do is = 1, pmat%npoints
754 cnt(ip) = cnt(ip) + 1
758 safe_allocate(invmap(1:max(maxval(cnt), 1), 1:mesh%np))
759 safe_allocate(invmap2(1:max(maxval(cnt)*mesh%np, 1)))
760 safe_allocate(invmap_mat(1:max(maxval(cnt), 1), 1:mesh%np))
761 safe_allocate(invmap_mat2(1:max(maxval(cnt)*mesh%np, 1)))
762 safe_allocate(pos(1:mesh%np + 1))
766 do imat = 1, this%nprojector_matrices
767 pmat => this%projector_matrices(imat)
768 do is = 1, pmat%npoints
770 cnt(ip) = cnt(ip) + 1
771 invmap(cnt(ip), ip) = ii
772 invmap_mat(cnt(ip), ip) = imat - 1
782 invmap2(ipos) = invmap(ii, ip)
783 invmap_mat2(ipos) = invmap_mat(ii, ip)
788 if (this%projector_matrices(1)%is_cmplx)
then
797 if (mix_offset > 0)
then
798 if (
allocated(this%projector_matrices(1)%zmix))
then
805 do imat = 1, this%nprojector_matrices
806 pmat => this%projector_matrices(imat)
807 if (pmat%npoints > 0)
then
808 if (pmat%is_cmplx)
then
809 call accel_write_buffer(this%buff_matrices, pmat%npoints, pmat%nprojs, pmat%zprojectors, &
810 offset = offsets(matrix, imat))
812 call accel_write_buffer(this%buff_matrices, pmat%npoints, pmat%nprojs, pmat%dprojectors, &
813 offset = offsets(matrix, imat))
815 call accel_write_buffer(this%buff_maps, pmat%npoints, pmat%map, offset = offsets(map, imat))
817 offset = 3*offsets(map, imat))
819 call accel_write_buffer(this%buff_scals, pmat%nprojs, pmat%scal, offset = offsets(scal, imat))
820 if (offsets(mix, imat) /= -1)
then
821 if (
allocated(pmat%zmix))
then
822 call accel_write_buffer(this%buff_mix, pmat%nprojs, pmat%nprojs, 4, pmat%zmix, offset = offsets(mix, imat))
824 call accel_write_buffer(this%buff_mix, pmat%nprojs, pmat%nprojs, pmat%dmix, offset = offsets(mix, imat))
830 call accel_write_buffer(this%buff_offsets, offset_size, this%nprojector_matrices, offsets)
842 safe_allocate(point_to_mat(1:max(this%total_points, 1)))
843 safe_allocate(proj_to_mat(1:max(scal_size, 1)))
844 do imat = 1, this%nprojector_matrices
845 pmat => this%projector_matrices(imat)
846 point_to_mat(offsets(map, imat) + 1:offsets(map, imat) + pmat%npoints) = imat - 1
847 proj_to_mat(offsets(scal, imat) + 1:offsets(scal, imat) + pmat%nprojs) = imat - 1
855 safe_deallocate_a(offsets)
856 safe_deallocate_a(point_to_mat)
857 safe_deallocate_a(proj_to_mat)
858 safe_deallocate_a(cnt)
859 safe_deallocate_a(invmap)
860 safe_deallocate_a(invmap2)
861 safe_deallocate_a(invmap_mat)
862 safe_deallocate_a(invmap_mat2)
863 safe_deallocate_a(pos)
873 integer :: ik, imat, iphase, nphase, offset, npoints
877 if (.not.
allocated(this%projector_phases))
then
882 nphase =
size(this%projector_phases, 2)
886 this%total_points*nphase*
size(this%projector_phases, 4))
889 do ik = lbound(this%projector_phases, 4), ubound(this%projector_phases, 4)
890 do imat = 1, this%nprojector_matrices
891 npoints = this%projector_matrices(imat)%npoints
892 do iphase = 1, nphase
893 if (npoints > 0)
then
894 call accel_write_buffer(this%buff_projector_phases, npoints, this%projector_phases(1:, iphase, imat, ik), &
895 offset = offset, async=.
true.)
897 offset = offset + npoints
909 logical pure function nonlocal_pseudopotential_self_overlap(this) result(projector_self_overlap)
912 projector_self_overlap = this%projector_self_overlap
917#include "nonlocal_pseudopotential_inc.F90"
920#include "complex.F90"
921#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.
logical pure function, public accel_buffer_is_allocated(this)
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....