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)
274 do iregion = 1, nregion
275 do iatom =
head(iregion),
head(iregion + 1) - 1
277 do jatom =
head(iregion), iatom - 1
279 assert(.not.
submesh_overlap(epot%proj(order(iatom))%sphere, epot%proj(order(jatom))%sphere, space))
290 this%nprojector_matrices = 0
291 this%apply_projector_matrices = .false.
292 this%has_non_local_potential = .false.
293 this%nregions = nregion
296 do iorder = 1, epot%natoms
297 iatom = order(iorder)
300 this%has_non_local_potential = .
true.
305 do iorder = 1, epot%natoms
306 iatom = order(iorder)
309 this%nprojector_matrices = this%nprojector_matrices + 1
310 this%apply_projector_matrices = .
true.
313 this%apply_projector_matrices = .false.
319 if (mesh%use_curvilinear) this%apply_projector_matrices = .false.
321 if (.not. this%apply_projector_matrices)
then
322 safe_deallocate_a(order)
323 safe_deallocate_a(
head)
330 safe_allocate(this%projector_matrices(1:this%nprojector_matrices))
331 safe_allocate(this%regions(1:this%nprojector_matrices + 1))
332 safe_allocate(this%projector_to_atom(1:epot%natoms))
334 this%full_projection_size = 0
335 this%regions(this%nregions + 1) = this%nprojector_matrices + 1
337 this%projector_mix = .false.
340 do iregion = 1, this%nregions
341 this%regions(iregion) = iproj + 1
342 do iorder =
head(iregion),
head(iregion + 1) - 1
344 iatom = order(iorder)
350 pmat => this%projector_matrices(iproj)
352 this%projector_to_atom(iproj) = iatom
354 lmax = epot%proj(iatom)%lmax
355 lloc = epot%proj(iatom)%lloc
362 if (ll == lloc) cycle
364 nmat = nmat + epot%proj(iatom)%kb_p(ll, mm)%n_c
374 if (ll == lloc) cycle
376 kb_p => epot%proj(iatom)%kb_p(ll, mm)
378 do ip = 1, pmat%npoints
379 pmat%dprojectors(ip, imat) = kb_p%p(ip, ic)
381 pmat%scal(imat) = kb_p%e(ic)*mesh%vol_pp(1)
387 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
391 this%projector_mix = .
true.
396 if (ll == lloc) cycle
416 if (ll == lloc) cycle
418 hgh_p => epot%proj(iatom)%hgh_p(ll, mm)
425 pmat%zmix(imat - 1 + ic, imat - 1 + jc, 1) = hgh_p%h(ic, jc) +
m_half*mm*hgh_p%k(ic, jc)
426 pmat%zmix(imat - 1 + ic, imat - 1 + jc, 2) = hgh_p%h(ic, jc) -
m_half*mm*hgh_p%k(ic, jc)
429 pmat%zmix(imat - 1 + ic, imat + 3 - 1 + jc, 3) =
m_half*hgh_p%k(ic, jc) * &
430 sqrt(real(ll*(ll+1)-mm*(mm+1), real64))
434 pmat%zmix(imat - 1 + ic, imat - 3 - 1 + jc, 4) =
m_half*hgh_p%k(ic, jc) * &
435 sqrt(real(ll*(ll+1)-mm*(mm-1), real64))
442 pmat%dmix(imat - 1 + ic, imat - 1 + jc) = hgh_p%h(ic, jc)
449 do ip = 1, pmat%npoints
450 pmat%zprojectors(ip, imat) = hgh_p%zp(ip, ic)
453 do ip = 1, pmat%npoints
454 pmat%dprojectors(ip, imat) = hgh_p%dp(ip, ic)
457 pmat%scal(imat) = mesh%volume_element
464 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
469 this%projector_mix = .
true.
473 if (lloc /= 0) nmat = nmat + epot%proj(iatom)%kb_p(1, 1)%n_c
476 if (ll == lloc) cycle
478 nmat = nmat + epot%proj(iatom)%rkb_p(ll, mm)%n_c
483 has_mix_matrix = .
true., is_cmplx = .
true.)
490 kb_p => epot%proj(iatom)%kb_p(1, 1)
493 pmat%zmix(ic, ic, 1:2) = kb_p%e(ic)
494 do ip = 1, pmat%npoints
495 pmat%zprojectors(ip, ic) = kb_p%p(ip, ic)
497 pmat%scal(ic) = mesh%volume_element
504 if (ll == lloc) cycle
506 rkb_p => epot%proj(iatom)%rkb_p(ll, mm)
509 do ic = 0, rkb_p%n_c/2-1
510 pmat%zmix(imat + ic*2, imat + ic*2, 1) = rkb_p%f(ic*2+1, 1, 1)
511 pmat%zmix(imat + ic*2, imat + ic*2, 2) = rkb_p%f(ic*2+1, 2, 2)
513 pmat%zmix(imat + ic*2+1, imat + ic*2+1, 1) = rkb_p%f(ic*2+2, 1, 1)
514 pmat%zmix(imat + ic*2+1, imat + ic*2+1, 2) = rkb_p%f(ic*2+2, 2, 2)
517 pmat%zmix(imat + ic*2+rkb_p%n_c, imat + ic*2, 4) = rkb_p%f(ic*2+1, 2, 1)
518 pmat%zmix(imat + ic*2+1+rkb_p%n_c, imat + ic*2+1, 4) = rkb_p%f(ic*2+2, 2, 1)
522 pmat%zmix(imat + ic*2-rkb_p%n_c, imat + ic*2, 3) = rkb_p%f(ic*2+1, 1, 2)
523 pmat%zmix(imat + ic*2+1-rkb_p%n_c, imat + ic*2+1, 3) = rkb_p%f(ic*2+2, 1, 2)
528 do ip = 1, pmat%npoints
529 pmat%zprojectors(ip, imat) = rkb_p%ket(ip, ic, 1, 1)
531 pmat%scal(imat) = mesh%volume_element
539 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
545 pmat%map => epot%proj(iatom)%sphere%map
546 pmat%position => epot%proj(iatom)%sphere%rel_x
548 pmat%regions = epot%proj(iatom)%sphere%regions
550 this%full_projection_size = this%full_projection_size + pmat%nprojs
555 if (mesh%parallel_in_domains)
then
556 call mesh%mpi_grp%allreduce_inplace(this%projector_self_overlap, 1, mpi_logical, mpi_lor)
559 safe_deallocate_a(order)
560 safe_deallocate_a(
head)
562 this%total_points = 0
565 do imat = 1, this%nprojector_matrices
566 pmat => this%projector_matrices(imat)
568 this%max_npoints = max(this%max_npoints, pmat%npoints)
569 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
570 this%total_points = this%total_points + pmat%npoints
581 integer :: matrix_size, scal_size
582 integer,
allocatable :: cnt(:), invmap(:, :), invmap2(:), pos(:)
583 integer,
allocatable :: offsets(:, :)
584 integer,
parameter :: OFFSET_SIZE = 6
585 integer,
parameter :: POINTS = 1, projs = 2, matrix = 3, map = 4, scal = 5, mix = 6
586 integer :: ip, is, ii, ipos, mix_offset
590 safe_allocate(offsets(1:offset_size, 1:this%nprojector_matrices))
591 safe_allocate(cnt(1:mesh%np))
610 this%total_points = 0
615 do imat = 1, this%nprojector_matrices
616 pmat => this%projector_matrices(imat)
618 this%max_npoints = max(this%max_npoints, pmat%npoints)
619 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
621 offsets(points, imat) = pmat%npoints
622 offsets(projs, imat) = pmat%nprojs
624 offsets(matrix, imat) = matrix_size
625 matrix_size = matrix_size + pmat%npoints*pmat%nprojs
627 offsets(map, imat) = this%total_points
628 this%total_points = this%total_points + pmat%npoints
630 offsets(scal, imat) = scal_size
631 scal_size = scal_size + pmat%nprojs
633 offsets(mix, imat) = mix_offset
634 if (
allocated(pmat%dmix))
then
635 mix_offset = mix_offset + pmat%nprojs**2
636 else if (
allocated(pmat%zmix))
then
637 mix_offset = mix_offset + 4 * pmat%nprojs**2
639 offsets(mix, imat) = -1
642 do is = 1, pmat%npoints
644 cnt(ip) = cnt(ip) + 1
648 safe_allocate(invmap(1:max(maxval(cnt), 1), 1:mesh%np))
649 safe_allocate(invmap2(1:max(maxval(cnt)*mesh%np, 1)))
650 safe_allocate(pos(1:mesh%np + 1))
654 do imat = 1, this%nprojector_matrices
655 pmat => this%projector_matrices(imat)
656 do is = 1, pmat%npoints
658 cnt(ip) = cnt(ip) + 1
659 invmap(cnt(ip), ip) = ii
669 invmap2(ipos) = invmap(ii, ip)
675 if (this%projector_matrices(1)%is_cmplx)
then
684 if (mix_offset > 0)
then
685 if (
allocated(this%projector_matrices(1)%zmix))
then
693 do imat = 1, this%nprojector_matrices
694 pmat => this%projector_matrices(imat)
696 if (pmat%npoints > 0)
then
697 if (pmat%is_cmplx)
then
698 call accel_write_buffer(this%buff_matrices, pmat%nprojs*pmat%npoints, pmat%zprojectors, offset = offsets(matrix, imat))
700 call accel_write_buffer(this%buff_matrices, pmat%nprojs*pmat%npoints, pmat%dprojectors, offset = offsets(matrix, imat))
702 call accel_write_buffer(this%buff_maps, pmat%npoints, pmat%map, offset = offsets(map, imat))
703 call accel_write_buffer(this%buff_position, 3*pmat%npoints, pmat%position, offset = 3*offsets(map, imat))
705 call accel_write_buffer(this%buff_scals, pmat%nprojs, pmat%scal, offset = offsets(scal, imat))
706 if (offsets(mix, imat) /= -1)
then
707 if (
allocated(pmat%zmix))
then
708 call accel_write_buffer(this%buff_mix, 4*pmat%nprojs**2, pmat%zmix, offset = offsets(mix, imat))
710 call accel_write_buffer(this%buff_mix, pmat%nprojs**2, pmat%dmix, offset = offsets(mix, imat))
717 call accel_write_buffer(this%buff_offsets, offset_size*this%nprojector_matrices, offsets)
726 safe_deallocate_a(offsets)
727 safe_deallocate_a(cnt)
728 safe_deallocate_a(invmap)
729 safe_deallocate_a(invmap2)
730 safe_deallocate_a(pos)
740 logical pure function nonlocal_pseudopotential_self_overlap(this) result(projector_self_overlap)
743 projector_self_overlap = this%projector_self_overlap
748#include "nonlocal_pseudopotential_inc.F90"
751#include "complex.F90"
752#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....
integer, parameter, public norel
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 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....