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_sphere_weights
87 type(accel_mem_t) :: buff_scals
88 type(accel_mem_t) :: buff_position
89 type(accel_mem_t) :: buff_pos
90 type(accel_mem_t) :: buff_invmap
91 type(accel_mem_t) :: buff_invmap_mat
92 type(accel_mem_t) :: buff_point_to_mat
93 type(accel_mem_t) :: buff_proj_to_mat
94 type(accel_mem_t),
public :: buff_projector_phases
95 type(accel_mem_t),
pointer,
public :: buff_bra_phasepsi => null()
96 type(accel_mem_t),
pointer,
public :: buff_bra_projection_temp => null()
97 type(accel_mem_t) :: buff_mix
98 logical :: projector_self_overlap
99 real(real64),
pointer,
public :: spin(:,:,:) => null()
137 real(real64),
allocatable :: dprojection(:, :)
138 complex(real64),
allocatable :: zprojection(:, :)
139 type(accel_mem_t) :: buff_projection
140 type(accel_mem_t) :: buff_spin_to_phase
141 integer :: cuda_stream_projection_DtH
150 class(nonlocal_pseudopotential_t),
intent(inout) :: this
154 this%apply_projector_matrices = .false.
155 this%has_non_local_potential = .false.
156 this%nprojector_matrices = 0
158 this%projector_self_overlap = .false.
172 integer :: imat, iatom
178 nullify(this%buff_bra_phasepsi)
179 nullify(this%buff_bra_projection_temp)
180 safe_allocate(this%buff_bra_phasepsi)
181 safe_allocate(this%buff_bra_projection_temp)
183 if (.not.
allocated(this%projector_matrices) .or. this%nprojector_matrices == 0)
then
188 assert(
allocated(this%projector_to_atom))
189 assert(
size(this%projector_matrices) >= this%nprojector_matrices)
190 assert(
size(this%projector_to_atom) >= this%nprojector_matrices)
192 do imat = 1, this%nprojector_matrices
193 pmat => this%projector_matrices(imat)
194 iatom = this%projector_to_atom(imat)
196 assert(iatom >= 1 .and. iatom <= epot%natoms)
197 assert(
allocated(epot%proj))
198 assert(
allocated(epot%proj(iatom)%sphere%map))
199 assert(
allocated(epot%proj(iatom)%sphere%rel_x))
201 pmat%map => epot%proj(iatom)%sphere%map
202 pmat%position => epot%proj(iatom)%sphere%rel_x
219 if (
allocated(this%projector_matrices))
then
237 do iproj = 1, this%nprojector_matrices
240 safe_deallocate_a(this%regions)
241 safe_deallocate_a(this%projector_matrices)
242 safe_deallocate_a(this%projector_phases)
243 safe_deallocate_a(this%projector_to_atom)
246 if (
associated(this%buff_bra_phasepsi))
then
249 if (
associated(this%buff_bra_projection_temp))
then
252 safe_deallocate_p(this%buff_bra_phasepsi)
253 safe_deallocate_p(this%buff_bra_projection_temp)
267 class(
space_t),
intent(in) :: space
268 class(
mesh_t),
intent(in) :: mesh
269 type(
epot_t),
target,
intent(in) :: epot
271 integer :: iatom, iproj, ll, lmax, lloc, mm, ic, jc
272 integer :: nmat, imat, ip, iorder
273 integer :: nregion, jatom, katom, iregion
274 integer,
allocatable :: order(:), head(:), region_count(:)
275 logical,
allocatable :: atom_counted(:)
289 safe_allocate(order(1:epot%natoms))
290 safe_allocate(head(1:epot%natoms + 1))
291 safe_allocate(region_count(1:epot%natoms))
292 safe_allocate(atom_counted(1:epot%natoms))
294 this%projector_self_overlap = .false.
295 atom_counted = .false.
301 nregion = nregion + 1
302 assert(nregion <= epot%natoms)
304 region_count(nregion) = 0
306 do iatom = 1, epot%natoms
307 if (atom_counted(iatom)) cycle
312 assert(
associated(epot%proj(iatom)%sphere%mesh))
313 do jatom = 1, region_count(nregion)
314 katom = order(head(nregion) + jatom - 1)
316 overlap =
submesh_overlap(epot%proj(iatom)%sphere, epot%proj(katom)%sphere, space)
321 if (.not. overlap)
then
324 region_count(nregion) = region_count(nregion) + 1
325 order(head(nregion) - 1 + region_count(nregion)) = iatom
326 atom_counted(iatom) = .
true.
331 head(nregion + 1) = head(nregion) + region_count(nregion)
333 if (all(atom_counted))
exit
336 safe_deallocate_a(atom_counted)
337 safe_deallocate_a(region_count)
344 do iregion = 1, nregion
345 do iatom = head(iregion), head(iregion + 1) - 1
347 do jatom = head(iregion), iatom - 1
349 assert(.not.
submesh_overlap(epot%proj(order(iatom))%sphere, epot%proj(order(jatom))%sphere, space))
361 safe_allocate(this%buff_bra_phasepsi)
362 safe_allocate(this%buff_bra_projection_temp)
365 this%nprojector_matrices = 0
366 this%apply_projector_matrices = .false.
367 this%has_non_local_potential = .false.
368 this%nregions = nregion
371 do iorder = 1, epot%natoms
372 iatom = order(iorder)
375 this%has_non_local_potential = .
true.
380 do iorder = 1, epot%natoms
381 iatom = order(iorder)
384 this%nprojector_matrices = this%nprojector_matrices + 1
385 this%apply_projector_matrices = .
true.
390 if (mesh%use_curvilinear) this%apply_projector_matrices = .false.
392 if (.not. this%apply_projector_matrices)
then
393 safe_deallocate_a(order)
394 safe_deallocate_a(head)
401 safe_allocate(this%projector_matrices(1:this%nprojector_matrices))
402 safe_allocate(this%regions(1:this%nregions + 1))
403 safe_allocate(this%projector_to_atom(1:epot%natoms))
405 this%full_projection_size = 0
406 this%regions(this%nregions + 1) = this%nprojector_matrices + 1
408 this%projector_mix = .false.
411 do iregion = 1, this%nregions
412 this%regions(iregion) = iproj + 1
413 do iorder = head(iregion), head(iregion + 1) - 1
415 iatom = order(iorder)
421 pmat => this%projector_matrices(iproj)
423 this%projector_to_atom(iproj) = iatom
425 lmax = epot%proj(iatom)%lmax
426 lloc = epot%proj(iatom)%lloc
433 if (ll == lloc) cycle
435 nmat = nmat + epot%proj(iatom)%kb_p(ll, mm)%n_c
445 if (ll == lloc) cycle
447 kb_p => epot%proj(iatom)%kb_p(ll, mm)
449 call lalg_copy(pmat%npoints, kb_p%p(:, ic), pmat%dprojectors(:, imat))
452 pmat%scal(imat) = kb_p%e(ic)*mesh%volume_element
458 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
462 this%projector_mix = .
true.
467 if (ll == lloc) cycle
474 has_mix_matrix = .
true., is_cmplx = (epot%proj_reltype ==
spin_orbit))
487 if (ll == lloc) cycle
489 hgh_p => epot%proj(iatom)%hgh_p(ll, mm)
496 pmat%zmix(imat - 1 + ic, imat - 1 + jc, 1) = hgh_p%h(ic, jc) +
m_half*mm*hgh_p%k(ic, jc)
497 pmat%zmix(imat - 1 + ic, imat - 1 + jc, 2) = hgh_p%h(ic, jc) -
m_half*mm*hgh_p%k(ic, jc)
500 pmat%zmix(imat - 1 + ic, imat + 3 - 1 + jc, 3) =
m_half*hgh_p%k(ic, jc) * &
501 sqrt(real(ll*(ll+1)-mm*(mm+1), real64))
505 pmat%zmix(imat - 1 + ic, imat - 3 - 1 + jc, 4) =
m_half*hgh_p%k(ic, jc) * &
506 sqrt(real(ll*(ll+1)-mm*(mm-1), real64))
513 pmat%dmix(imat - 1 + ic, imat - 1 + jc) = hgh_p%h(ic, jc)
520 call lalg_copy(pmat%npoints, hgh_p%zp(:, ic), pmat%zprojectors(:, imat))
522 call lalg_copy(pmat%npoints, hgh_p%dp(:, ic), pmat%dprojectors(:, imat))
524 pmat%scal(imat) = mesh%volume_element
531 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
536 this%projector_mix = .
true.
540 if (lloc /= 0) nmat = nmat + epot%proj(iatom)%kb_p(1, 1)%n_c
543 if (ll == lloc) cycle
545 nmat = nmat + epot%proj(iatom)%rkb_p(ll, mm)%n_c
550 has_mix_matrix = .
true., is_cmplx = .
true.)
557 kb_p => epot%proj(iatom)%kb_p(1, 1)
560 pmat%zmix(ic, ic, 1:2) = kb_p%e(ic)
561 do ip = 1, pmat%npoints
562 pmat%zprojectors(ip, ic) = kb_p%p(ip, ic)
564 pmat%scal(ic) = mesh%volume_element
571 if (ll == lloc) cycle
573 rkb_p => epot%proj(iatom)%rkb_p(ll, mm)
576 do ic = 0, rkb_p%n_c/2-1
577 pmat%zmix(imat + ic*2, imat + ic*2, 1) = rkb_p%f(ic*2+1, 1, 1)
578 pmat%zmix(imat + ic*2, imat + ic*2, 2) = rkb_p%f(ic*2+1, 2, 2)
580 pmat%zmix(imat + ic*2+1, imat + ic*2+1, 1) = rkb_p%f(ic*2+2, 1, 1)
581 pmat%zmix(imat + ic*2+1, imat + ic*2+1, 2) = rkb_p%f(ic*2+2, 2, 2)
584 pmat%zmix(imat + ic*2+rkb_p%n_c, imat + ic*2, 4) = rkb_p%f(ic*2+1, 2, 1)
585 pmat%zmix(imat + ic*2+1+rkb_p%n_c, imat + ic*2+1, 4) = rkb_p%f(ic*2+2, 2, 1)
589 pmat%zmix(imat + ic*2-rkb_p%n_c, imat + ic*2, 3) = rkb_p%f(ic*2+1, 1, 2)
590 pmat%zmix(imat + ic*2+1-rkb_p%n_c, imat + ic*2+1, 3) = rkb_p%f(ic*2+2, 1, 2)
595 call lalg_copy(pmat%npoints, rkb_p%ket(:, ic, 1, 1), pmat%zprojectors(:, imat))
596 pmat%scal(imat) = mesh%volume_element
604 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
610 pmat%map => epot%proj(iatom)%sphere%map
611 pmat%position => epot%proj(iatom)%sphere%rel_x
613 pmat%regions = epot%proj(iatom)%sphere%regions
615 this%full_projection_size = this%full_projection_size + pmat%nprojs
618 if (mesh%use_vol_pp)
then
619 safe_allocate(pmat%sphere_weights(1:max(pmat%npoints, 1)))
620 do ip = 1, pmat%npoints
621 pmat%sphere_weights(ip) = mesh%vol_pp(pmat%map(ip))
628 if (mesh%parallel_in_domains)
then
629 call mesh%mpi_grp%allreduce_inplace(this%projector_self_overlap, 1, mpi_logical, mpi_lor)
632 safe_deallocate_a(order)
633 safe_deallocate_a(head)
635 this%total_points = 0
638 do imat = 1, this%nprojector_matrices
639 pmat => this%projector_matrices(imat)
641 this%max_npoints = max(this%max_npoints, pmat%npoints)
642 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
643 this%total_points = this%total_points + pmat%npoints
659 class(
space_t),
intent(in) :: space
660 class(
mesh_t),
intent(in) :: mesh
671 if (.not.
allocated(this%projector_matrices) .or. this%nprojector_matrices <= 0)
then
709 class(
space_t),
intent(in) :: space
710 class(
mesh_t),
intent(in) :: mesh
712 integer,
parameter :: OFFSET_SIZE = 6
713 integer,
parameter :: POINTS = 1, projs = 2, matrix = 3, map = 4, scal = 5, mix = 6
714 integer :: imat, matrix_size, scal_size
715 integer :: ip, is, ii, ipos, mix_offset
716 integer,
allocatable :: cnt(:), invmap(:, :), invmap2(:), pos(:)
717 integer,
allocatable :: invmap_mat(:, :), invmap_mat2(:)
718 integer,
allocatable :: offsets(:, :), point_to_mat(:), proj_to_mat(:)
723 assert(
allocated(this%projector_matrices))
724 assert(this%nprojector_matrices > 0)
726 safe_allocate(offsets(1:offset_size, 1:this%nprojector_matrices))
727 safe_allocate(cnt(1:mesh%np))
732 this%total_points = 0
737 do imat = 1, this%nprojector_matrices
738 pmat => this%projector_matrices(imat)
740 this%max_npoints = max(this%max_npoints, pmat%npoints)
741 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
743 offsets(points, imat) = pmat%npoints
744 offsets(projs, imat) = pmat%nprojs
746 offsets(matrix, imat) = matrix_size
747 matrix_size = matrix_size + pmat%npoints*pmat%nprojs
749 offsets(map, imat) = this%total_points
750 this%total_points = this%total_points + pmat%npoints
752 offsets(scal, imat) = scal_size
753 scal_size = scal_size + pmat%nprojs
755 offsets(mix, imat) = mix_offset
756 if (
allocated(pmat%dmix))
then
757 mix_offset = mix_offset + pmat%nprojs**2
758 else if (
allocated(pmat%zmix))
then
759 mix_offset = mix_offset + 4*pmat%nprojs**2
761 offsets(mix, imat) = -1
764 do is = 1, pmat%npoints
766 cnt(ip) = cnt(ip) + 1
770 safe_allocate(invmap(1:max(maxval(cnt), 1), 1:mesh%np))
771 safe_allocate(invmap2(1:max(maxval(cnt)*mesh%np, 1)))
772 safe_allocate(invmap_mat(1:max(maxval(cnt), 1), 1:mesh%np))
773 safe_allocate(invmap_mat2(1:max(maxval(cnt)*mesh%np, 1)))
774 safe_allocate(pos(1:mesh%np + 1))
778 do imat = 1, this%nprojector_matrices
779 pmat => this%projector_matrices(imat)
780 do is = 1, pmat%npoints
782 cnt(ip) = cnt(ip) + 1
783 invmap(cnt(ip), ip) = ii
784 invmap_mat(cnt(ip), ip) = imat - 1
794 invmap2(ipos) = invmap(ii, ip)
795 invmap_mat2(ipos) = invmap_mat(ii, ip)
800 if (this%projector_matrices(1)%is_cmplx)
then
806 if (mesh%use_vol_pp)
then
812 if (mix_offset > 0)
then
813 if (
allocated(this%projector_matrices(1)%zmix))
then
820 do imat = 1, this%nprojector_matrices
821 pmat => this%projector_matrices(imat)
822 if (pmat%npoints > 0)
then
823 if (pmat%is_cmplx)
then
824 call accel_write_buffer(this%buff_matrices, pmat%npoints, pmat%nprojs, pmat%zprojectors, &
825 offset = offsets(matrix, imat))
827 call accel_write_buffer(this%buff_matrices, pmat%npoints, pmat%nprojs, pmat%dprojectors, &
828 offset = offsets(matrix, imat))
830 call accel_write_buffer(this%buff_maps, pmat%npoints, pmat%map, offset = offsets(map, imat))
831 if (mesh%use_vol_pp)
then
832 call accel_write_buffer(this%buff_sphere_weights, pmat%npoints, pmat%sphere_weights, &
833 offset = offsets(map, imat))
836 offset = 3*offsets(map, imat))
838 call accel_write_buffer(this%buff_scals, pmat%nprojs, pmat%scal, offset = offsets(scal, imat))
839 if (offsets(mix, imat) /= -1)
then
840 if (
allocated(pmat%zmix))
then
841 call accel_write_buffer(this%buff_mix, pmat%nprojs, pmat%nprojs, 4, pmat%zmix, offset = offsets(mix, imat))
843 call accel_write_buffer(this%buff_mix, pmat%nprojs, pmat%nprojs, pmat%dmix, offset = offsets(mix, imat))
849 call accel_write_buffer(this%buff_offsets, offset_size, this%nprojector_matrices, offsets)
861 safe_allocate(point_to_mat(1:max(this%total_points, 1)))
862 safe_allocate(proj_to_mat(1:max(scal_size, 1)))
863 do imat = 1, this%nprojector_matrices
864 pmat => this%projector_matrices(imat)
865 point_to_mat(offsets(map, imat) + 1:offsets(map, imat) + pmat%npoints) = imat - 1
866 proj_to_mat(offsets(scal, imat) + 1:offsets(scal, imat) + pmat%nprojs) = imat - 1
874 safe_deallocate_a(offsets)
875 safe_deallocate_a(point_to_mat)
876 safe_deallocate_a(proj_to_mat)
877 safe_deallocate_a(cnt)
878 safe_deallocate_a(invmap)
879 safe_deallocate_a(invmap2)
880 safe_deallocate_a(invmap_mat)
881 safe_deallocate_a(invmap_mat2)
882 safe_deallocate_a(pos)
892 integer :: ik, imat, iphase, nphase, offset, npoints
896 if (.not.
allocated(this%projector_phases))
then
901 nphase =
size(this%projector_phases, 2)
905 this%total_points*nphase*
size(this%projector_phases, 4))
908 do ik = lbound(this%projector_phases, 4), ubound(this%projector_phases, 4)
909 do imat = 1, this%nprojector_matrices
910 npoints = this%projector_matrices(imat)%npoints
911 do iphase = 1, nphase
912 if (npoints > 0)
then
913 call accel_write_buffer(this%buff_projector_phases, npoints, this%projector_phases(1:, iphase, imat, ik), &
914 offset = offset, async=.
true.)
916 offset = offset + npoints
928 logical pure function nonlocal_pseudopotential_self_overlap(this) result(projector_self_overlap)
931 projector_self_overlap = this%projector_self_overlap
936#include "nonlocal_pseudopotential_inc.F90"
939#include "complex.F90"
940#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
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....