66 type(projector_matrix_t),
allocatable,
public :: projector_matrices(:)
67 integer,
public :: nprojector_matrices
68 logical,
public :: apply_projector_matrices
69 logical,
public :: has_non_local_potential
70 integer :: full_projection_size
71 integer,
public :: max_npoints
72 integer,
public :: total_points
74 logical :: projector_mix
75 complex(real64),
allocatable,
public :: projector_phases(:, :, :, :)
76 integer,
allocatable,
public :: projector_to_atom(:)
78 integer,
allocatable :: regions(:)
79 integer,
public :: nphase
84 type(accel_mem_t) :: buff_offsets
85 type(accel_mem_t) :: buff_matrices
86 type(accel_mem_t) :: buff_maps
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),
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(:)
145 class(nonlocal_pseudopotential_t),
intent(inout) :: this
149 this%apply_projector_matrices = .false.
150 this%has_non_local_potential = .false.
151 this%nprojector_matrices = 0
153 this%projector_self_overlap = .false.
167 integer :: imat, iatom
172 if (.not.
allocated(this%projector_matrices) .or. this%nprojector_matrices == 0)
then
177 assert(
allocated(this%projector_to_atom))
178 assert(
size(this%projector_matrices) >= this%nprojector_matrices)
179 assert(
size(this%projector_to_atom) >= this%nprojector_matrices)
181 do imat = 1, this%nprojector_matrices
182 pmat => this%projector_matrices(imat)
183 iatom = this%projector_to_atom(imat)
185 assert(iatom >= 1 .and. iatom <= epot%natoms)
186 assert(
allocated(epot%proj))
187 assert(
allocated(epot%proj(iatom)%sphere%map))
188 assert(
allocated(epot%proj(iatom)%sphere%rel_x))
190 pmat%map => epot%proj(iatom)%sphere%map
191 pmat%position => epot%proj(iatom)%sphere%rel_x
207 if (
allocated(this%projector_matrices))
then
221 do iproj = 1, this%nprojector_matrices
224 safe_deallocate_a(this%regions)
225 safe_deallocate_a(this%projector_matrices)
226 safe_deallocate_a(this%projector_phases)
227 safe_deallocate_a(this%projector_to_atom)
242 class(
space_t),
intent(in) :: space
243 class(
mesh_t),
intent(in) :: mesh
244 type(
epot_t),
target,
intent(in) :: epot
246 integer :: iatom, iproj, ll, lmax, lloc, mm, ic, jc
247 integer :: nmat, imat, ip, iorder
248 integer :: nregion, jatom, katom, iregion
249 integer,
allocatable :: order(:), head(:), region_count(:)
250 logical,
allocatable :: atom_counted(:)
264 safe_allocate(order(1:epot%natoms))
265 safe_allocate(head(1:epot%natoms + 1))
266 safe_allocate(region_count(1:epot%natoms))
267 safe_allocate(atom_counted(1:epot%natoms))
269 this%projector_self_overlap = .false.
270 atom_counted = .false.
276 nregion = nregion + 1
277 assert(nregion <= epot%natoms)
279 region_count(nregion) = 0
281 do iatom = 1, epot%natoms
282 if (atom_counted(iatom)) cycle
287 assert(
associated(epot%proj(iatom)%sphere%mesh))
288 do jatom = 1, region_count(nregion)
289 katom = order(head(nregion) + jatom - 1)
291 overlap =
submesh_overlap(epot%proj(iatom)%sphere, epot%proj(katom)%sphere, space)
296 if (.not. overlap)
then
299 region_count(nregion) = region_count(nregion) + 1
300 order(head(nregion) - 1 + region_count(nregion)) = iatom
301 atom_counted(iatom) = .
true.
306 head(nregion + 1) = head(nregion) + region_count(nregion)
308 if (all(atom_counted))
exit
311 safe_deallocate_a(atom_counted)
312 safe_deallocate_a(region_count)
319 do iregion = 1, nregion
320 do iatom = head(iregion), head(iregion + 1) - 1
322 do jatom = head(iregion), iatom - 1
324 assert(.not.
submesh_overlap(epot%proj(order(iatom))%sphere, epot%proj(order(jatom))%sphere, space))
335 this%nprojector_matrices = 0
336 this%apply_projector_matrices = .false.
337 this%has_non_local_potential = .false.
338 this%nregions = nregion
341 do iorder = 1, epot%natoms
342 iatom = order(iorder)
345 this%has_non_local_potential = .
true.
350 do iorder = 1, epot%natoms
351 iatom = order(iorder)
354 this%nprojector_matrices = this%nprojector_matrices + 1
355 this%apply_projector_matrices = .
true.
360 if (mesh%use_curvilinear) this%apply_projector_matrices = .false.
362 if (.not. this%apply_projector_matrices)
then
363 safe_deallocate_a(order)
364 safe_deallocate_a(head)
371 safe_allocate(this%projector_matrices(1:this%nprojector_matrices))
372 safe_allocate(this%regions(1:this%nprojector_matrices + 1))
373 safe_allocate(this%projector_to_atom(1:epot%natoms))
375 this%full_projection_size = 0
376 this%regions(this%nregions + 1) = this%nprojector_matrices + 1
378 this%projector_mix = .false.
381 do iregion = 1, this%nregions
382 this%regions(iregion) = iproj + 1
383 do iorder = head(iregion), head(iregion + 1) - 1
385 iatom = order(iorder)
391 pmat => this%projector_matrices(iproj)
393 this%projector_to_atom(iproj) = iatom
395 lmax = epot%proj(iatom)%lmax
396 lloc = epot%proj(iatom)%lloc
403 if (ll == lloc) cycle
405 nmat = nmat + epot%proj(iatom)%kb_p(ll, mm)%n_c
415 if (ll == lloc) cycle
417 kb_p => epot%proj(iatom)%kb_p(ll, mm)
419 call lalg_copy(pmat%npoints, kb_p%p(:, ic), pmat%dprojectors(:, imat))
420 pmat%scal(imat) = kb_p%e(ic)*mesh%vol_pp(1)
426 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
430 this%projector_mix = .
true.
435 if (ll == lloc) cycle
455 if (ll == lloc) cycle
457 hgh_p => epot%proj(iatom)%hgh_p(ll, mm)
464 pmat%zmix(imat - 1 + ic, imat - 1 + jc, 1) = hgh_p%h(ic, jc) +
m_half*mm*hgh_p%k(ic, jc)
465 pmat%zmix(imat - 1 + ic, imat - 1 + jc, 2) = hgh_p%h(ic, jc) -
m_half*mm*hgh_p%k(ic, jc)
468 pmat%zmix(imat - 1 + ic, imat + 3 - 1 + jc, 3) =
m_half*hgh_p%k(ic, jc) * &
469 sqrt(real(ll*(ll+1)-mm*(mm+1), real64))
473 pmat%zmix(imat - 1 + ic, imat - 3 - 1 + jc, 4) =
m_half*hgh_p%k(ic, jc) * &
474 sqrt(real(ll*(ll+1)-mm*(mm-1), real64))
481 pmat%dmix(imat - 1 + ic, imat - 1 + jc) = hgh_p%h(ic, jc)
488 call lalg_copy(pmat%npoints, hgh_p%zp(:, ic), pmat%zprojectors(:, imat))
490 call lalg_copy(pmat%npoints, hgh_p%dp(:, ic), pmat%dprojectors(:, imat))
492 pmat%scal(imat) = mesh%volume_element
499 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
504 this%projector_mix = .
true.
508 if (lloc /= 0) nmat = nmat + epot%proj(iatom)%kb_p(1, 1)%n_c
511 if (ll == lloc) cycle
513 nmat = nmat + epot%proj(iatom)%rkb_p(ll, mm)%n_c
518 has_mix_matrix = .
true., is_cmplx = .
true.)
525 kb_p => epot%proj(iatom)%kb_p(1, 1)
528 pmat%zmix(ic, ic, 1:2) = kb_p%e(ic)
529 do ip = 1, pmat%npoints
530 pmat%zprojectors(ip, ic) = kb_p%p(ip, ic)
532 pmat%scal(ic) = mesh%volume_element
539 if (ll == lloc) cycle
541 rkb_p => epot%proj(iatom)%rkb_p(ll, mm)
544 do ic = 0, rkb_p%n_c/2-1
545 pmat%zmix(imat + ic*2, imat + ic*2, 1) = rkb_p%f(ic*2+1, 1, 1)
546 pmat%zmix(imat + ic*2, imat + ic*2, 2) = rkb_p%f(ic*2+1, 2, 2)
548 pmat%zmix(imat + ic*2+1, imat + ic*2+1, 1) = rkb_p%f(ic*2+2, 1, 1)
549 pmat%zmix(imat + ic*2+1, imat + ic*2+1, 2) = rkb_p%f(ic*2+2, 2, 2)
552 pmat%zmix(imat + ic*2+rkb_p%n_c, imat + ic*2, 4) = rkb_p%f(ic*2+1, 2, 1)
553 pmat%zmix(imat + ic*2+1+rkb_p%n_c, imat + ic*2+1, 4) = rkb_p%f(ic*2+2, 2, 1)
557 pmat%zmix(imat + ic*2-rkb_p%n_c, imat + ic*2, 3) = rkb_p%f(ic*2+1, 1, 2)
558 pmat%zmix(imat + ic*2+1-rkb_p%n_c, imat + ic*2+1, 3) = rkb_p%f(ic*2+2, 1, 2)
563 call lalg_copy(pmat%npoints, rkb_p%ket(:, ic, 1, 1), pmat%zprojectors(:, imat))
564 pmat%scal(imat) = mesh%volume_element
572 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
578 pmat%map => epot%proj(iatom)%sphere%map
579 pmat%position => epot%proj(iatom)%sphere%rel_x
581 pmat%regions = epot%proj(iatom)%sphere%regions
583 this%full_projection_size = this%full_projection_size + pmat%nprojs
588 if (mesh%parallel_in_domains)
then
589 call mesh%mpi_grp%allreduce_inplace(this%projector_self_overlap, 1, mpi_logical, mpi_lor)
592 safe_deallocate_a(order)
593 safe_deallocate_a(head)
595 this%total_points = 0
598 do imat = 1, this%nprojector_matrices
599 pmat => this%projector_matrices(imat)
601 this%max_npoints = max(this%max_npoints, pmat%npoints)
602 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
603 this%total_points = this%total_points + pmat%npoints
619 class(
space_t),
intent(in) :: space
620 class(
mesh_t),
intent(in) :: mesh
631 if (.not.
allocated(this%projector_matrices) .or. this%nprojector_matrices <= 0)
then
666 class(
space_t),
intent(in) :: space
667 class(
mesh_t),
intent(in) :: mesh
669 integer,
parameter :: OFFSET_SIZE = 6
670 integer,
parameter :: POINTS = 1, projs = 2, matrix = 3, map = 4, scal = 5, mix = 6
671 integer :: imat, matrix_size, scal_size
672 integer :: ip, is, ii, ipos, mix_offset
673 integer,
allocatable :: cnt(:), invmap(:, :), invmap2(:), pos(:)
674 integer,
allocatable :: offsets(:, :)
679 assert(
allocated(this%projector_matrices))
680 assert(this%nprojector_matrices > 0)
682 safe_allocate(offsets(1:offset_size, 1:this%nprojector_matrices))
683 safe_allocate(cnt(1:mesh%np))
688 this%total_points = 0
693 do imat = 1, this%nprojector_matrices
694 pmat => this%projector_matrices(imat)
696 this%max_npoints = max(this%max_npoints, pmat%npoints)
697 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
699 offsets(points, imat) = pmat%npoints
700 offsets(projs, imat) = pmat%nprojs
702 offsets(matrix, imat) = matrix_size
703 matrix_size = matrix_size + pmat%npoints*pmat%nprojs
705 offsets(map, imat) = this%total_points
706 this%total_points = this%total_points + pmat%npoints
708 offsets(scal, imat) = scal_size
709 scal_size = scal_size + pmat%nprojs
711 offsets(mix, imat) = mix_offset
712 if (
allocated(pmat%dmix))
then
713 mix_offset = mix_offset + pmat%nprojs**2
714 else if (
allocated(pmat%zmix))
then
715 mix_offset = mix_offset + 4*pmat%nprojs**2
717 offsets(mix, imat) = -1
720 do is = 1, pmat%npoints
722 cnt(ip) = cnt(ip) + 1
726 safe_allocate(invmap(1:max(maxval(cnt), 1), 1:mesh%np))
727 safe_allocate(invmap2(1:max(maxval(cnt)*mesh%np, 1)))
728 safe_allocate(pos(1:mesh%np + 1))
732 do imat = 1, this%nprojector_matrices
733 pmat => this%projector_matrices(imat)
734 do is = 1, pmat%npoints
736 cnt(ip) = cnt(ip) + 1
737 invmap(cnt(ip), ip) = ii
747 invmap2(ipos) = invmap(ii, ip)
752 if (this%projector_matrices(1)%is_cmplx)
then
761 if (mix_offset > 0)
then
762 if (
allocated(this%projector_matrices(1)%zmix))
then
769 do imat = 1, this%nprojector_matrices
770 pmat => this%projector_matrices(imat)
771 if (pmat%npoints > 0)
then
772 if (pmat%is_cmplx)
then
773 call accel_write_buffer(this%buff_matrices, pmat%npoints, pmat%nprojs, pmat%zprojectors, &
774 offset = offsets(matrix, imat))
776 call accel_write_buffer(this%buff_matrices, pmat%npoints, pmat%nprojs, pmat%dprojectors, &
777 offset = offsets(matrix, imat))
779 call accel_write_buffer(this%buff_maps, pmat%npoints, pmat%map, offset = offsets(map, imat))
781 offset = 3*offsets(map, imat))
783 call accel_write_buffer(this%buff_scals, pmat%nprojs, pmat%scal, offset = offsets(scal, imat))
784 if (offsets(mix, imat) /= -1)
then
785 if (
allocated(pmat%zmix))
then
786 call accel_write_buffer(this%buff_mix, pmat%nprojs, pmat%nprojs, 4, pmat%zmix, offset = offsets(mix, imat))
788 call accel_write_buffer(this%buff_mix, pmat%nprojs, pmat%nprojs, pmat%dmix, offset = offsets(mix, imat))
794 call accel_write_buffer(this%buff_offsets, offset_size, this%nprojector_matrices, offsets)
802 safe_deallocate_a(offsets)
803 safe_deallocate_a(cnt)
804 safe_deallocate_a(invmap)
805 safe_deallocate_a(invmap2)
806 safe_deallocate_a(pos)
816 integer :: ik, imat, iphase, nphase, offset, npoints
820 if (.not.
allocated(this%projector_phases))
then
825 nphase =
size(this%projector_phases, 2)
829 this%total_points*nphase*
size(this%projector_phases, 4))
832 do ik = lbound(this%projector_phases, 4), ubound(this%projector_phases, 4)
833 do imat = 1, this%nprojector_matrices
834 npoints = this%projector_matrices(imat)%npoints
835 do iphase = 1, nphase
836 if (npoints > 0)
then
837 call accel_write_buffer(this%buff_projector_phases, npoints, this%projector_phases(1:, iphase, imat, ik), &
838 offset = offset, async=.
true.)
840 offset = offset + npoints
852 logical pure function nonlocal_pseudopotential_self_overlap(this) result(projector_self_overlap)
855 projector_self_overlap = this%projector_self_overlap
860#include "nonlocal_pseudopotential_inc.F90"
863#include "complex.F90"
864#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
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
integer, parameter, public fully_relativistic_zora
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), public type_float
type(type_t), public type_cmplx
type(type_t), public type_integer
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....