62 type(projector_matrix_t),
allocatable,
public :: projector_matrices(:)
63 integer,
public :: nprojector_matrices
64 logical,
public :: apply_projector_matrices
65 logical,
public :: has_non_local_potential
66 integer :: full_projection_size
67 integer,
public :: max_npoints
68 integer,
public :: total_points
70 logical :: projector_mix
71 complex(real64),
allocatable,
public :: projector_phases(:, :, :, :)
72 integer,
allocatable,
public :: projector_to_atom(:)
74 integer,
allocatable :: regions(:)
75 integer,
public :: nphase
80 type(accel_mem_t) :: buff_offsets
81 type(accel_mem_t) :: buff_matrices
82 type(accel_mem_t) :: buff_maps
83 type(accel_mem_t) :: buff_scals
84 type(accel_mem_t) :: buff_position
85 type(accel_mem_t) :: buff_pos
86 type(accel_mem_t) :: buff_invmap
87 type(accel_mem_t),
public :: buff_projector_phases
88 type(accel_mem_t) :: buff_mix
89 logical :: projector_self_overlap
90 real(real64),
pointer,
public :: spin(:,:,:) => null()
127 real(real64),
allocatable :: dprojection(:, :)
128 complex(real64),
allocatable :: zprojection(:, :)
129 type(accel_mem_t) :: buff_projection
130 type(accel_mem_t) :: buff_spin_to_phase
139 class(nonlocal_pseudopotential_t),
intent(inout) :: this
143 this%apply_projector_matrices = .false.
144 this%has_non_local_potential = .false.
145 this%nprojector_matrices = 0
147 this%projector_self_overlap = .false.
162 if (
allocated(this%projector_matrices))
then
176 do iproj = 1, this%nprojector_matrices
179 safe_deallocate_a(this%regions)
180 safe_deallocate_a(this%projector_matrices)
181 safe_deallocate_a(this%projector_phases)
182 safe_deallocate_a(this%projector_to_atom)
197 class(
space_t),
intent(in) :: space
199 type(
epot_t),
target,
intent(in) :: epot
201 integer :: iatom, iproj, ll, lmax, lloc, mm, ic, jc
202 integer :: nmat, imat, ip, iorder
203 integer :: nregion, jatom, katom, iregion
204 integer,
allocatable :: order(:),
head(:), region_count(:)
205 logical,
allocatable :: atom_counted(:)
219 safe_allocate(order(1:epot%natoms))
220 safe_allocate(
head(1:epot%natoms + 1))
221 safe_allocate(region_count(1:epot%natoms))
222 safe_allocate(atom_counted(1:epot%natoms))
224 this%projector_self_overlap = .false.
225 atom_counted = .false.
231 nregion = nregion + 1
232 assert(nregion <= epot%natoms)
234 region_count(nregion) = 0
236 do iatom = 1, epot%natoms
237 if (atom_counted(iatom)) cycle
242 assert(
associated(epot%proj(iatom)%sphere%mesh))
243 do jatom = 1, region_count(nregion)
244 katom = order(
head(nregion) + jatom - 1)
246 overlap =
submesh_overlap(epot%proj(iatom)%sphere, epot%proj(katom)%sphere, space)
251 if (.not. overlap)
then
254 region_count(nregion) = region_count(nregion) + 1
255 order(
head(nregion) - 1 + region_count(nregion)) = iatom
256 atom_counted(iatom) = .
true.
261 head(nregion + 1) =
head(nregion) + region_count(nregion)
263 if (all(atom_counted))
exit
266 safe_deallocate_a(atom_counted)
267 safe_deallocate_a(region_count)
276 do iregion = 1, nregion
277 do iatom =
head(iregion),
head(iregion + 1) - 1
279 do jatom =
head(iregion), iatom - 1
281 assert(.not.
submesh_overlap(epot%proj(order(iatom))%sphere, epot%proj(order(jatom))%sphere, space))
292 this%nprojector_matrices = 0
293 this%apply_projector_matrices = .false.
294 this%has_non_local_potential = .false.
295 this%nregions = nregion
298 do iorder = 1, epot%natoms
299 iatom = order(iorder)
302 this%has_non_local_potential = .
true.
307 do iorder = 1, epot%natoms
308 iatom = order(iorder)
311 this%nprojector_matrices = this%nprojector_matrices + 1
312 this%apply_projector_matrices = .
true.
315 this%apply_projector_matrices = .false.
321 if (mesh%use_curvilinear) this%apply_projector_matrices = .false.
323 if (.not. this%apply_projector_matrices)
then
324 safe_deallocate_a(order)
325 safe_deallocate_a(
head)
332 safe_allocate(this%projector_matrices(1:this%nprojector_matrices))
333 safe_allocate(this%regions(1:this%nprojector_matrices + 1))
334 safe_allocate(this%projector_to_atom(1:epot%natoms))
336 this%full_projection_size = 0
337 this%regions(this%nregions + 1) = this%nprojector_matrices + 1
339 this%projector_mix = .false.
342 do iregion = 1, this%nregions
343 this%regions(iregion) = iproj + 1
344 do iorder =
head(iregion),
head(iregion + 1) - 1
346 iatom = order(iorder)
352 pmat => this%projector_matrices(iproj)
354 this%projector_to_atom(iproj) = iatom
356 lmax = epot%proj(iatom)%lmax
357 lloc = epot%proj(iatom)%lloc
364 if (ll == lloc) cycle
366 nmat = nmat + epot%proj(iatom)%kb_p(ll, mm)%n_c
376 if (ll == lloc) cycle
378 kb_p => epot%proj(iatom)%kb_p(ll, mm)
380 do ip = 1, pmat%npoints
381 pmat%dprojectors(ip, imat) = kb_p%p(ip, ic)
383 pmat%scal(imat) = kb_p%e(ic)*mesh%vol_pp(1)
389 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
393 this%projector_mix = .
true.
398 if (ll == lloc) cycle
418 if (ll == lloc) cycle
420 hgh_p => epot%proj(iatom)%hgh_p(ll, mm)
427 pmat%zmix(imat - 1 + ic, imat - 1 + jc, 1) = hgh_p%h(ic, jc) +
m_half*mm*hgh_p%k(ic, jc)
428 pmat%zmix(imat - 1 + ic, imat - 1 + jc, 2) = hgh_p%h(ic, jc) -
m_half*mm*hgh_p%k(ic, jc)
431 pmat%zmix(imat - 1 + ic, imat + 3 - 1 + jc, 3) =
m_half*hgh_p%k(ic, jc) * &
432 sqrt(real(ll*(ll+1)-mm*(mm+1), real64))
436 pmat%zmix(imat - 1 + ic, imat - 3 - 1 + jc, 4) =
m_half*hgh_p%k(ic, jc) * &
437 sqrt(real(ll*(ll+1)-mm*(mm-1), real64))
444 pmat%dmix(imat - 1 + ic, imat - 1 + jc) = hgh_p%h(ic, jc)
451 do ip = 1, pmat%npoints
452 pmat%zprojectors(ip, imat) = hgh_p%zp(ip, ic)
455 do ip = 1, pmat%npoints
456 pmat%dprojectors(ip, imat) = hgh_p%dp(ip, ic)
459 pmat%scal(imat) = mesh%volume_element
466 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
471 this%projector_mix = .
true.
475 if (lloc /= 0) nmat = nmat + epot%proj(iatom)%kb_p(1, 1)%n_c
478 if (ll == lloc) cycle
480 nmat = nmat + epot%proj(iatom)%rkb_p(ll, mm)%n_c
485 has_mix_matrix = .
true., is_cmplx = .
true.)
492 kb_p => epot%proj(iatom)%kb_p(1, 1)
495 pmat%zmix(ic, ic, 1:2) = kb_p%e(ic)
496 do ip = 1, pmat%npoints
497 pmat%zprojectors(ip, ic) = kb_p%p(ip, ic)
499 pmat%scal(ic) = mesh%volume_element
506 if (ll == lloc) cycle
508 rkb_p => epot%proj(iatom)%rkb_p(ll, mm)
511 do ic = 0, rkb_p%n_c/2-1
512 pmat%zmix(imat + ic*2, imat + ic*2, 1) = rkb_p%f(ic*2+1, 1, 1)
513 pmat%zmix(imat + ic*2, imat + ic*2, 2) = rkb_p%f(ic*2+1, 2, 2)
515 pmat%zmix(imat + ic*2+1, imat + ic*2+1, 1) = rkb_p%f(ic*2+2, 1, 1)
516 pmat%zmix(imat + ic*2+1, imat + ic*2+1, 2) = rkb_p%f(ic*2+2, 2, 2)
519 pmat%zmix(imat + ic*2+rkb_p%n_c, imat + ic*2, 4) = rkb_p%f(ic*2+1, 2, 1)
520 pmat%zmix(imat + ic*2+1+rkb_p%n_c, imat + ic*2+1, 4) = rkb_p%f(ic*2+2, 2, 1)
524 pmat%zmix(imat + ic*2-rkb_p%n_c, imat + ic*2, 3) = rkb_p%f(ic*2+1, 1, 2)
525 pmat%zmix(imat + ic*2+1-rkb_p%n_c, imat + ic*2+1, 3) = rkb_p%f(ic*2+2, 1, 2)
530 do ip = 1, pmat%npoints
531 pmat%zprojectors(ip, imat) = rkb_p%ket(ip, ic, 1, 1)
533 pmat%scal(imat) = mesh%volume_element
541 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
547 pmat%map => epot%proj(iatom)%sphere%map
548 pmat%position => epot%proj(iatom)%sphere%rel_x
550 pmat%regions = epot%proj(iatom)%sphere%regions
552 this%full_projection_size = this%full_projection_size + pmat%nprojs
557 if (mesh%parallel_in_domains)
then
558 call mesh%mpi_grp%allreduce_inplace(this%projector_self_overlap, 1, mpi_logical, mpi_lor)
561 safe_deallocate_a(order)
562 safe_deallocate_a(
head)
564 this%total_points = 0
567 do imat = 1, this%nprojector_matrices
568 pmat => this%projector_matrices(imat)
570 this%max_npoints = max(this%max_npoints, pmat%npoints)
571 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
572 this%total_points = this%total_points + pmat%npoints
583 integer :: matrix_size, scal_size
584 integer,
allocatable :: cnt(:), invmap(:, :), invmap2(:), pos(:)
585 integer,
allocatable :: offsets(:, :)
586 integer,
parameter :: OFFSET_SIZE = 6
587 integer,
parameter :: POINTS = 1, projs = 2, matrix = 3, map = 4, scal = 5, mix = 6
588 integer :: ip, is, ii, ipos, mix_offset
592 safe_allocate(offsets(1:offset_size, 1:this%nprojector_matrices))
593 safe_allocate(cnt(1:mesh%np))
612 this%total_points = 0
617 do imat = 1, this%nprojector_matrices
618 pmat => this%projector_matrices(imat)
620 this%max_npoints = max(this%max_npoints, pmat%npoints)
621 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
623 offsets(points, imat) = pmat%npoints
624 offsets(projs, imat) = pmat%nprojs
626 offsets(matrix, imat) = matrix_size
627 matrix_size = matrix_size + pmat%npoints*pmat%nprojs
629 offsets(map, imat) = this%total_points
630 this%total_points = this%total_points + pmat%npoints
632 offsets(scal, imat) = scal_size
633 scal_size = scal_size + pmat%nprojs
635 offsets(mix, imat) = mix_offset
636 if (
allocated(pmat%dmix))
then
637 mix_offset = mix_offset + pmat%nprojs**2
638 else if (
allocated(pmat%zmix))
then
639 mix_offset = mix_offset + 4 * pmat%nprojs**2
641 offsets(mix, imat) = -1
644 do is = 1, pmat%npoints
646 cnt(ip) = cnt(ip) + 1
650 safe_allocate(invmap(1:max(maxval(cnt), 1), 1:mesh%np))
651 safe_allocate(invmap2(1:max(maxval(cnt)*mesh%np, 1)))
652 safe_allocate(pos(1:mesh%np + 1))
656 do imat = 1, this%nprojector_matrices
657 pmat => this%projector_matrices(imat)
658 do is = 1, pmat%npoints
660 cnt(ip) = cnt(ip) + 1
661 invmap(cnt(ip), ip) = ii
671 invmap2(ipos) = invmap(ii, ip)
677 if (this%projector_matrices(1)%is_cmplx)
then
686 if (mix_offset > 0)
then
687 if (
allocated(this%projector_matrices(1)%zmix))
then
695 do imat = 1, this%nprojector_matrices
696 pmat => this%projector_matrices(imat)
698 if (pmat%npoints > 0)
then
699 if (pmat%is_cmplx)
then
700 call accel_write_buffer(this%buff_matrices, pmat%nprojs*pmat%npoints, pmat%zprojectors, offset = offsets(matrix, imat))
702 call accel_write_buffer(this%buff_matrices, pmat%nprojs*pmat%npoints, pmat%dprojectors, offset = offsets(matrix, imat))
704 call accel_write_buffer(this%buff_maps, pmat%npoints, pmat%map, offset = offsets(map, imat))
705 call accel_write_buffer(this%buff_position, 3*pmat%npoints, pmat%position, offset = 3*offsets(map, imat))
707 call accel_write_buffer(this%buff_scals, pmat%nprojs, pmat%scal, offset = offsets(scal, imat))
708 if (offsets(mix, imat) /= -1)
then
709 if (
allocated(pmat%zmix))
then
710 call accel_write_buffer(this%buff_mix, 4*pmat%nprojs**2, pmat%zmix, offset = offsets(mix, imat))
712 call accel_write_buffer(this%buff_mix, pmat%nprojs**2, pmat%dmix, offset = offsets(mix, imat))
719 call accel_write_buffer(this%buff_offsets, offset_size*this%nprojector_matrices, offsets)
728 safe_deallocate_a(offsets)
729 safe_deallocate_a(cnt)
730 safe_deallocate_a(invmap)
731 safe_deallocate_a(invmap2)
732 safe_deallocate_a(pos)
742 logical pure function nonlocal_pseudopotential_self_overlap(this) result(projector_self_overlap)
745 projector_self_overlap = this%projector_self_overlap
750#include "nonlocal_pseudopotential_inc.F90"
753#include "complex.F90"
754#include "nonlocal_pseudopotential_inc.F90"
double sqrt(double __x) __attribute__((__nothrow__
subroutine, public accel_release_buffer(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....
type(debug_t), save, public debug
integer, parameter, public norel
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, verbose_limit, stress, all_nodes, namespace)
subroutine nonlocal_pseudopotential_destroy_proj(this)
Destroy the data of nonlocal_pseudopotential_t.
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 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 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_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....