Octopus
nonlocal_pseudopotential.F90
Go to the documentation of this file.
1!! Copyright (C) 2009 X. Andrade
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
22 use accel_oct_m
24 use batch_oct_m
26 use blas_oct_m
27 use debug_oct_m
29 use epot_oct_m
30 use global_oct_m
35 use math_oct_m
36 use mesh_oct_m
38 use mpi_oct_m
42 use ps_oct_m
44 use space_oct_m
48 use types_oct_m
50
51 implicit none
52
53 private
54
55 public :: &
60
64 private
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
72 integer :: max_nprojs
73 logical :: projector_mix
74 complex(real64), allocatable, public :: projector_phases(:, :, :, :)
75 integer, allocatable, public :: projector_to_atom(:)
76 integer :: nregions
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()
99 contains
100
101 procedure :: init => nonlocal_pseudopotential_init
102
103 procedure :: build => nonlocal_pseudopotential_build_proj
104
105 procedure :: end => nonlocal_pseudopotential_destroy_proj
106
107 procedure :: has_self_overlap => nonlocal_pseudopotential_self_overlap
108
109 procedure :: dstart => dnonlocal_pseudopotential_start
110
111 procedure :: zstart => znonlocal_pseudopotential_start
112
113 procedure :: dfinish => dnonlocal_pseudopotential_finish
114
115 procedure :: zfinish => znonlocal_pseudopotential_finish
117 procedure :: dforce => dnonlocal_pseudopotential_force
118
119 procedure :: zforce => znonlocal_pseudopotential_force
120
121 procedure :: dposition_commutator => dnonlocal_pseudopotential_position_commutator
122
123 procedure :: zposition_commutator => znonlocal_pseudopotential_position_commutator
124
125 procedure :: dr_vn_local => dnonlocal_pseudopotential_r_vnlocal
126
127 procedure :: zr_vn_local => znonlocal_pseudopotential_r_vnlocal
128
130
131
133 !
134 type projection_t
135 private
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
141 end type projection_t
142
143contains
144
145 ! ---------------------------------------------------------
148 subroutine nonlocal_pseudopotential_init(this)
149 class(nonlocal_pseudopotential_t), intent(inout) :: this
150
152
153 this%apply_projector_matrices = .false.
154 this%has_non_local_potential = .false.
155 this%nprojector_matrices = 0
156
157 this%projector_self_overlap = .false.
162 ! ---------------------------------------------------------
168 class(nonlocal_pseudopotential_t), target, intent(inout) :: this
169 type(epot_t), target, intent(in) :: epot
171 integer :: imat, iatom
172 type(projector_matrix_t), pointer :: pmat
175
176 ! After the assignment these still point to the buffers of the source: drop them, do not free them
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
184 return
185 end if
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)
194
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))
199
200 pmat%map => epot%proj(iatom)%sphere%map
201 pmat%position => epot%proj(iatom)%sphere%rel_x
202 end do
203
207
209 !--------------------------------------------------------
212 class(nonlocal_pseudopotential_t), intent(inout) :: this
213
214 integer :: iproj
215
217
218 if (allocated(this%projector_matrices)) then
219
221 call accel_free_buffer(this%buff_offsets)
222 call accel_free_buffer(this%buff_matrices)
223 call accel_free_buffer(this%buff_maps)
224 call accel_free_buffer(this%buff_scals)
225 call accel_free_buffer(this%buff_position)
226 call accel_free_buffer(this%buff_pos)
227 call accel_free_buffer(this%buff_invmap)
228 call accel_free_buffer(this%buff_invmap_mat)
229 call accel_free_buffer(this%buff_point_to_mat)
230 call accel_free_buffer(this%buff_proj_to_mat)
231 if (this%projector_mix) call accel_free_buffer(this%buff_mix)
232 if (allocated(this%projector_phases)) call accel_free_buffer(this%buff_projector_phases)
233 end if
235 do iproj = 1, this%nprojector_matrices
236 call projector_matrix_deallocate(this%projector_matrices(iproj))
237 end do
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)
242 end if
244 if (associated(this%buff_bra_phasepsi)) then
245 if (accel_buffer_is_allocated(this%buff_bra_phasepsi)) call accel_free_buffer(this%buff_bra_phasepsi)
246 end if
247 if (associated(this%buff_bra_projection_temp)) then
248 if (accel_buffer_is_allocated(this%buff_bra_projection_temp)) call accel_free_buffer(this%buff_bra_projection_temp)
249 end if
250 safe_deallocate_p(this%buff_bra_phasepsi)
251 safe_deallocate_p(this%buff_bra_projection_temp)
252
255
256 !-----------------------------------------------------------------
263 subroutine nonlocal_pseudopotential_build_proj(this, space, mesh, epot)
264 class(nonlocal_pseudopotential_t), target, intent(inout) :: this
265 class(space_t), intent(in) :: space
266 class(mesh_t), intent(in) :: mesh
267 type(epot_t), target, intent(in) :: epot
268
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(:)
274 logical :: overlap
275 type(projector_matrix_t), pointer :: pmat
276 type(kb_projector_t), pointer :: kb_p
277 type(rkb_projector_t), pointer :: rkb_p
278 type(hgh_projector_t), pointer :: hgh_p
279
281
282 call profiling_in("ATOM_COLORING")
283
284 ! this is most likely a very inefficient algorithm, O(natom**2) or
285 ! O(natom**3), probably it should be replaced by something better.
286
287 safe_allocate(order(1:epot%natoms)) ! order(iregion) = ?
288 safe_allocate(head(1:epot%natoms + 1)) ! head(iregion) points to the first atom in region iregion
289 safe_allocate(region_count(1:epot%natoms)) ! region_count(iregion): number of atoms in that region
290 safe_allocate(atom_counted(1:epot%natoms))
291
292 this%projector_self_overlap = .false.
293 atom_counted = .false.
294 order = -1
295
296 head(1) = 1
297 nregion = 0
298 do
299 nregion = nregion + 1
300 assert(nregion <= epot%natoms)
301
302 region_count(nregion) = 0
303
304 do iatom = 1, epot%natoms
305 if (atom_counted(iatom)) cycle
307 overlap = .false.
308
309 if (.not. projector_is(epot%proj(iatom), proj_none)) then
310 assert(associated(epot%proj(iatom)%sphere%mesh))
311 do jatom = 1, region_count(nregion)
312 katom = order(head(nregion) + jatom - 1)
313 if (projector_is(epot%proj(katom), proj_none)) cycle
314 overlap = submesh_overlap(epot%proj(iatom)%sphere, epot%proj(katom)%sphere, space)
315 if (overlap) exit
316 end do
317 end if
318
319 if (.not. overlap) then
320 ! iatom did not overlap with any previously counted atoms:
321 ! iatom will be added to the current region
322 region_count(nregion) = region_count(nregion) + 1
323 order(head(nregion) - 1 + region_count(nregion)) = iatom
324 atom_counted(iatom) = .true.
325 end if
326
327 end do
328
329 head(nregion + 1) = head(nregion) + region_count(nregion)
330
331 if (all(atom_counted)) exit
332 end do
333
334 safe_deallocate_a(atom_counted)
335 safe_deallocate_a(region_count)
336
337 call messages_write('The atoms can be separated in ')
338 call messages_write(nregion)
339 call messages_write(' non-overlapping groups.')
340 call messages_info(debug_only=.true.)
341
342 do iregion = 1, nregion
343 do iatom = head(iregion), head(iregion + 1) - 1
344 if (.not. projector_is(epot%proj(order(iatom)), proj_kb)) cycle
345 do jatom = head(iregion), iatom - 1
346 if (.not. projector_is(epot%proj(order(jatom)), proj_kb)) cycle
347 assert(.not. submesh_overlap(epot%proj(order(iatom))%sphere, epot%proj(order(jatom))%sphere, space))
348 end do
349 end do
350 end do
351
352 call profiling_out("ATOM_COLORING")
353
354 ! deallocate previous projectors
355 call this%end()
356
357 ! The two bra scratch buffers. They are pointers so that
358 ! X(nonlocal_pseudopotential_start), whose `this` is intent(in), can fill them.
359 safe_allocate(this%buff_bra_phasepsi)
360 safe_allocate(this%buff_bra_projection_temp)
361
362 ! count projectors
363 this%nprojector_matrices = 0
364 this%apply_projector_matrices = .false.
365 this%has_non_local_potential = .false.
366 this%nregions = nregion
367
368 !We determine if we have only local potential or not.
369 do iorder = 1, epot%natoms
370 iatom = order(iorder)
371
372 if (.not. projector_is_null(epot%proj(iatom))) then
373 this%has_non_local_potential = .true.
374 exit
375 end if
376 end do
377
378 do iorder = 1, epot%natoms
379 iatom = order(iorder)
380
381 if (.not. projector_is_null(epot%proj(iatom))) then
382 this%nprojector_matrices = this%nprojector_matrices + 1
383 this%apply_projector_matrices = .true.
384 end if
385 end do
386
387 ! This is currently the only not supported case
388 if (mesh%use_curvilinear) this%apply_projector_matrices = .false.
389
390 if (.not. this%apply_projector_matrices) then
391 safe_deallocate_a(order)
392 safe_deallocate_a(head)
393
395 return
396 end if
397
398
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))
402
403 this%full_projection_size = 0
404 this%regions(this%nregions + 1) = this%nprojector_matrices + 1
405
406 this%projector_mix = .false.
407
408 iproj = 0
409 do iregion = 1, this%nregions
410 this%regions(iregion) = iproj + 1
411 do iorder = head(iregion), head(iregion + 1) - 1
412
413 iatom = order(iorder)
414
415 if (projector_is(epot%proj(iatom), proj_none)) cycle
416
417 iproj = iproj + 1
418
419 pmat => this%projector_matrices(iproj)
420
421 this%projector_to_atom(iproj) = iatom
422
423 lmax = epot%proj(iatom)%lmax
424 lloc = epot%proj(iatom)%lloc
425
426 if (projector_is(epot%proj(iatom), proj_kb)) then
427
428 ! count the number of projectors for this matrix
429 nmat = 0
430 do ll = 0, lmax
431 if (ll == lloc) cycle
432 do mm = -ll, ll
433 nmat = nmat + epot%proj(iatom)%kb_p(ll, mm)%n_c
434 end do
435 end do
436
437 call projector_matrix_allocate(pmat, nmat, epot%proj(iatom)%sphere, has_mix_matrix = .false.)
438
439 ! generate the matrix
440 pmat%dprojectors = m_zero
441 imat = 1
442 do ll = 0, lmax
443 if (ll == lloc) cycle
444 do mm = -ll, ll
445 kb_p => epot%proj(iatom)%kb_p(ll, mm)
446 do ic = 1, kb_p%n_c
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)
449 imat = imat + 1
450 end do
451 end do
452 end do
453
454 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
455
456 else if (projector_is(epot%proj(iatom), proj_hgh)) then
457
458 this%projector_mix = .true.
459
460 ! count the number of projectors for this matrix
461 nmat = 0
462 do ll = 0, lmax
463 if (ll == lloc) cycle
464 do mm = -ll, ll
465 nmat = nmat + 3
466 end do
467 end do
468
469 call projector_matrix_allocate(pmat, nmat, epot%proj(iatom)%sphere, &
470 has_mix_matrix = .true., is_cmplx = (epot%proj_reltype == spin_orbit))
471
472 ! generate the matrix
473 if (epot%proj_reltype == spin_orbit) then
474 pmat%zprojectors = m_zero
475 pmat%zmix = m_zero
476 else
477 pmat%dprojectors = m_zero
478 pmat%dmix = m_zero
479 end if
480
481 imat = 1
482 do ll = 0, lmax
483 if (ll == lloc) cycle
484 do mm = -ll, ll
485 hgh_p => epot%proj(iatom)%hgh_p(ll, mm)
486
487 ! HGH pseudos mix different components, so we need to
488 ! generate a matrix that mixes the projections
489 if (epot%proj_reltype == spin_orbit) then
490 do ic = 1, 3
491 do jc = 1, 3
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)
494
495 if (mm < ll) then
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))
498 end if
499
500 if (-mm < ll) then
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))
503 end if
504 end do
505 end do
506 else
507 do ic = 1, 3
508 do jc = 1, 3
509 pmat%dmix(imat - 1 + ic, imat - 1 + jc) = hgh_p%h(ic, jc)
510 end do
511 end do
512 end if
513
514 do ic = 1, 3
515 if (epot%proj_reltype == spin_orbit) then
516 call lalg_copy(pmat%npoints, hgh_p%zp(:, ic), pmat%zprojectors(:, imat))
517 else
518 call lalg_copy(pmat%npoints, hgh_p%dp(:, ic), pmat%dprojectors(:, imat))
519 end if
520 pmat%scal(imat) = mesh%volume_element
521 imat = imat + 1
522 end do
523
524 end do
525 end do
526
527 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
528
529 else if (projector_is(epot%proj(iatom), proj_rkb)) then
530 assert(epot%proj_reltype == spin_orbit)
531
532 this%projector_mix = .true.
533
534 ! count the number of projectors for this matrix
535 nmat = 0
536 if (lloc /= 0) nmat = nmat + epot%proj(iatom)%kb_p(1, 1)%n_c
537
538 do ll = 1, lmax
539 if (ll == lloc) cycle
540 do mm = -ll, ll
541 nmat = nmat + epot%proj(iatom)%rkb_p(ll, mm)%n_c
542 end do
543 end do
544
545 call projector_matrix_allocate(pmat, nmat, epot%proj(iatom)%sphere, &
546 has_mix_matrix = .true., is_cmplx = .true.)
547
548 pmat%zprojectors = m_zero
549 pmat%zmix = m_zero
550
551 imat = 1
552 if (lloc /= 0) then
553 kb_p => epot%proj(iatom)%kb_p(1, 1)
554
555 do ic = 1, kb_p%n_c
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)
559 end do
560 pmat%scal(ic) = mesh%volume_element
561 end do
562 imat = kb_p%n_c + 1
563 nullify(kb_p)
564 end if
565
566 do ll = 1, lmax
567 if (ll == lloc) cycle
568 do mm = -ll, ll
569 rkb_p => epot%proj(iatom)%rkb_p(ll, mm)
570
571 ! See rkb_projector.F90 for understanding the indices
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)
575
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)
578
579 if (mm < ll) then
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)
582 end if
583
584 if (-mm < ll) then
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)
587 end if
588 end do
589
590 do ic = 1, rkb_p%n_c
591 call lalg_copy(pmat%npoints, rkb_p%ket(:, ic, 1, 1), pmat%zprojectors(:, imat))
592 pmat%scal(imat) = mesh%volume_element
593 imat = imat + 1
594 end do
595 end do
596
597 nullify(rkb_p)
598 end do
599
600 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
601
602 else
603 cycle
604 end if
605
606 pmat%map => epot%proj(iatom)%sphere%map
607 pmat%position => epot%proj(iatom)%sphere%rel_x
608
609 pmat%regions = epot%proj(iatom)%sphere%regions
610
611 this%full_projection_size = this%full_projection_size + pmat%nprojs
612
613 end do
614 end do
615
616 if (mesh%parallel_in_domains) then
617 call mesh%mpi_grp%allreduce_inplace(this%projector_self_overlap, 1, mpi_logical, mpi_lor)
618 end if
619
620 safe_deallocate_a(order)
621 safe_deallocate_a(head)
622
623 this%total_points = 0
624 this%max_npoints = 0
625 this%max_nprojs = 0
626 do imat = 1, this%nprojector_matrices
627 pmat => this%projector_matrices(imat)
628
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
632 end do
633
634 if (accel_is_enabled()) then
637 end if
638
640
642
643 ! ----------------------------------------------------------------------------------
645 subroutine nonlocal_pseudopotential_accel_rebuild(this, space, mesh)
646 class(nonlocal_pseudopotential_t), target, intent(inout) :: this
647 class(space_t), intent(in) :: space
648 class(mesh_t), intent(in) :: mesh
649
651
652 if (.not. accel_is_enabled()) then
654 return
655 end if
656
658
659 if (.not. allocated(this%projector_matrices) .or. this%nprojector_matrices <= 0) then
661 return
662 end if
663
666
669
670 ! ----------------------------------------------------------------------------------
673 class(nonlocal_pseudopotential_t), intent(inout) :: this
674
676
677 call accel_detach_buffer(this%buff_offsets)
678 call accel_detach_buffer(this%buff_matrices)
679 call accel_detach_buffer(this%buff_maps)
680 call accel_detach_buffer(this%buff_scals)
681 call accel_detach_buffer(this%buff_position)
682 call accel_detach_buffer(this%buff_pos)
683 call accel_detach_buffer(this%buff_invmap)
684 call accel_detach_buffer(this%buff_invmap_mat)
685 call accel_detach_buffer(this%buff_point_to_mat)
686 call accel_detach_buffer(this%buff_proj_to_mat)
687 call accel_detach_buffer(this%buff_projector_phases)
688 call accel_detach_buffer(this%buff_mix)
689
692
693 ! ----------------------------------------------------------------------------------
695 subroutine nonlocal_pseudopotential_build_accel_buffers(this, space, mesh)
696 class(nonlocal_pseudopotential_t), target, intent(inout) :: this
697 class(space_t), intent(in) :: space
698 class(mesh_t), intent(in) :: mesh
699
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(:)
707 type(projector_matrix_t), pointer :: pmat
708
710
711 assert(allocated(this%projector_matrices))
712 assert(this%nprojector_matrices > 0)
713
714 safe_allocate(offsets(1:offset_size, 1:this%nprojector_matrices))
715 safe_allocate(cnt(1:mesh%np))
716
717 cnt = 0
718
719 matrix_size = 0
720 this%total_points = 0
721 scal_size = 0
722 this%max_npoints = 0
723 this%max_nprojs = 0
724 mix_offset = 0
725 do imat = 1, this%nprojector_matrices
726 pmat => this%projector_matrices(imat)
727
728 this%max_npoints = max(this%max_npoints, pmat%npoints)
729 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
730
731 offsets(points, imat) = pmat%npoints
732 offsets(projs, imat) = pmat%nprojs
733
734 offsets(matrix, imat) = matrix_size
735 matrix_size = matrix_size + pmat%npoints*pmat%nprojs
736
737 offsets(map, imat) = this%total_points
738 this%total_points = this%total_points + pmat%npoints
739
740 offsets(scal, imat) = scal_size
741 scal_size = scal_size + pmat%nprojs
742
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
748 else
749 offsets(mix, imat) = -1
750 end if
751
752 do is = 1, pmat%npoints
753 ip = pmat%map(is)
754 cnt(ip) = cnt(ip) + 1
755 end do
756 end do
757
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))
763
764 cnt = 0
765 ii = 0
766 do imat = 1, this%nprojector_matrices
767 pmat => this%projector_matrices(imat)
768 do is = 1, pmat%npoints
769 ip = pmat%map(is)
770 cnt(ip) = cnt(ip) + 1
771 invmap(cnt(ip), ip) = ii
772 invmap_mat(cnt(ip), ip) = imat - 1
773 ii = ii + 1
774 end do
775 end do
776
777 ipos = 0
778 pos(1) = 0
779 do ip = 1, mesh%np
780 do ii = 1, cnt(ip)
781 ipos = ipos + 1
782 invmap2(ipos) = invmap(ii, ip)
783 invmap_mat2(ipos) = invmap_mat(ii, ip)
784 end do
785 pos(ip + 1) = ipos
786 end do
787
788 if (this%projector_matrices(1)%is_cmplx) then
789 call accel_create_buffer(this%buff_matrices, accel_mem_read_only, type_cmplx, matrix_size)
790 else
791 call accel_create_buffer(this%buff_matrices, accel_mem_read_only, type_float, matrix_size)
792 end if
793 call accel_create_buffer(this%buff_maps, accel_mem_read_only, type_integer, this%total_points)
794 call accel_create_buffer(this%buff_position, accel_mem_read_only, type_float, 3*this%total_points)
795 call accel_create_buffer(this%buff_scals, accel_mem_read_only, type_float, scal_size)
796
797 if (mix_offset > 0) then
798 if (allocated(this%projector_matrices(1)%zmix)) then
799 call accel_create_buffer(this%buff_mix, accel_mem_read_only, type_cmplx, mix_offset)
800 else
801 call accel_create_buffer(this%buff_mix, accel_mem_read_only, type_float, mix_offset)
802 end if
803 end if
804
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))
811 else
812 call accel_write_buffer(this%buff_matrices, pmat%npoints, pmat%nprojs, pmat%dprojectors, &
813 offset = offsets(matrix, imat))
814 end if
815 call accel_write_buffer(this%buff_maps, pmat%npoints, pmat%map, offset = offsets(map, imat))
816 call accel_write_buffer(this%buff_position, space%dim, pmat%npoints, pmat%position, &
817 offset = 3*offsets(map, imat))
818 end if
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))
823 else
824 call accel_write_buffer(this%buff_mix, pmat%nprojs, pmat%nprojs, pmat%dmix, offset = offsets(mix, imat))
825 end if
826 end if
827 end do
828
829 call accel_create_buffer(this%buff_offsets, accel_mem_read_only, type_integer, offset_size*this%nprojector_matrices)
830 call accel_write_buffer(this%buff_offsets, offset_size, this%nprojector_matrices, offsets)
831
832 call accel_create_buffer(this%buff_pos, accel_mem_read_only, type_integer, mesh%np + 1)
833 call accel_write_buffer(this%buff_pos, mesh%np + 1, pos)
834
835 call accel_create_buffer(this%buff_invmap, accel_mem_read_only, type_integer, ipos)
836 call accel_write_buffer(this%buff_invmap, ipos, invmap2)
837
838 call accel_create_buffer(this%buff_invmap_mat, accel_mem_read_only, type_integer, ipos)
839 call accel_write_buffer(this%buff_invmap_mat, ipos, invmap_mat2)
840
841 ! 0-based matrix index of every packed projector point and every projector
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
848 end do
849
850 call accel_create_buffer(this%buff_point_to_mat, accel_mem_read_only, type_integer, this%total_points)
851 call accel_write_buffer(this%buff_point_to_mat, this%total_points, point_to_mat)
852 call accel_create_buffer(this%buff_proj_to_mat, accel_mem_read_only, type_integer, scal_size)
853 call accel_write_buffer(this%buff_proj_to_mat, scal_size, proj_to_mat)
854
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)
864
867
868 ! ----------------------------------------------------------------------------------
871 class(nonlocal_pseudopotential_t), intent(inout) :: this
872
873 integer :: ik, imat, iphase, nphase, offset, npoints
874
876
877 if (.not. allocated(this%projector_phases)) then
879 return
880 end if
881
882 nphase = size(this%projector_phases, 2)
883 this%nphase = nphase
884
885 call accel_create_buffer(this%buff_projector_phases, accel_mem_read_only, type_cmplx, &
886 this%total_points*nphase*size(this%projector_phases, 4))
887
888 offset = 0
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.)
896 end if
897 offset = offset + npoints
898 end do
899 end do
900 end do
901 call accel_finish()
902
905
906 ! ----------------------------------------------------------------------------------
908 !
909 logical pure function nonlocal_pseudopotential_self_overlap(this) result(projector_self_overlap)
910 class(nonlocal_pseudopotential_t), intent(in) :: this
911
912 projector_self_overlap = this%projector_self_overlap
914
915#include "undef.F90"
916#include "real.F90"
917#include "nonlocal_pseudopotential_inc.F90"
918
919#include "undef.F90"
920#include "complex.F90"
921#include "nonlocal_pseudopotential_inc.F90"
922
924
925!! Local Variables:
926!! mode: f90
927!! coding: utf-8
928!! End:
Copies a vector x, to a vector y.
Definition: lalg_basic.F90:188
double sqrt(double __x) __attribute__((__nothrow__
subroutine, public accel_free_buffer(this, async)
Definition: accel.F90:945
subroutine, public accel_finish()
Definition: accel.F90:1082
subroutine, public accel_detach_buffer(this)
Clear a buffer handle without freeing device memory.
Definition: accel.F90:1014
logical pure function, public accel_buffer_is_allocated(this)
Definition: accel.F90:1074
pure logical function, public accel_is_enabled()
Definition: accel.F90:376
integer, parameter, public accel_mem_read_only
Definition: accel.F90:185
type(accel_kernel_t), pointer head
Definition: accel.F90:370
This module implements batches of mesh functions.
Definition: batch.F90:135
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:118
This module contains interfaces for BLAS routines You should not use these routines directly....
Definition: blas.F90:120
integer, parameter, public spin_orbit
Definition: epot.F90:168
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public m_half
Definition: global.F90:206
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
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.
Definition: profiling.F90:631
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:554
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)
Definition: projector.F90:211
logical elemental function, public projector_is_null(p)
Definition: projector.F90:204
Definition: ps.F90:116
integer, parameter, public proj_hgh
Definition: ps.F90:171
integer, parameter, public proj_rkb
Definition: ps.F90:171
integer, parameter, public proj_none
Definition: ps.F90:171
integer, parameter, public proj_kb
Definition: ps.F90:171
This module handles spin dimensions of the states and the k-point distribution.
logical function, public submesh_overlap(sm1, sm2, space)
Definition: submesh.F90:705
type(type_t), parameter, public type_cmplx
Definition: types.F90:136
type(type_t), parameter, public type_integer
Definition: types.F90:137
type(type_t), parameter, public type_float
Definition: types.F90:135
Describes mesh distribution to nodes.
Definition: mesh.F90:187
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....
int true(void)