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), public :: buff_projector_phases
92 type(accel_mem_t) :: buff_mix
93 logical :: projector_self_overlap
94 real(real64), pointer, public :: spin(:,:,:) => null()
95 contains
96
97 procedure :: init => nonlocal_pseudopotential_init
98
99 procedure :: build => nonlocal_pseudopotential_build_proj
100
101 procedure :: end => nonlocal_pseudopotential_destroy_proj
102
103 procedure :: has_self_overlap => nonlocal_pseudopotential_self_overlap
104
105 procedure :: dstart => dnonlocal_pseudopotential_start
106
107 procedure :: zstart => znonlocal_pseudopotential_start
108
109 procedure :: dfinish => dnonlocal_pseudopotential_finish
110
111 procedure :: zfinish => znonlocal_pseudopotential_finish
112
113 procedure :: dforce => dnonlocal_pseudopotential_force
114
115 procedure :: zforce => znonlocal_pseudopotential_force
117 procedure :: dposition_commutator => dnonlocal_pseudopotential_position_commutator
118
119 procedure :: zposition_commutator => znonlocal_pseudopotential_position_commutator
120
121 procedure :: dr_vn_local => dnonlocal_pseudopotential_r_vnlocal
122
123 procedure :: zr_vn_local => znonlocal_pseudopotential_r_vnlocal
124
126
128 !
129 type projection_t
130 private
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(:)
137 integer :: cuda_stream_projection_DtH
138 end type projection_t
139
140contains
141
142 ! ---------------------------------------------------------
145 subroutine nonlocal_pseudopotential_init(this)
146 class(nonlocal_pseudopotential_t), intent(inout) :: this
147
149
150 this%apply_projector_matrices = .false.
151 this%has_non_local_potential = .false.
152 this%nprojector_matrices = 0
153
154 this%projector_self_overlap = .false.
155
157 end subroutine nonlocal_pseudopotential_init
159 ! ---------------------------------------------------------
165 class(nonlocal_pseudopotential_t), target, intent(inout) :: this
166 type(epot_t), target, intent(in) :: epot
168 integer :: imat, iatom
169 type(projector_matrix_t), pointer :: pmat
173 if (.not. allocated(this%projector_matrices) .or. this%nprojector_matrices == 0) then
175 return
176 end if
177
178 assert(allocated(this%projector_to_atom))
179 assert(size(this%projector_matrices) >= this%nprojector_matrices)
180 assert(size(this%projector_to_atom) >= this%nprojector_matrices)
182 do imat = 1, this%nprojector_matrices
183 pmat => this%projector_matrices(imat)
184 iatom = this%projector_to_atom(imat)
186 assert(iatom >= 1 .and. iatom <= epot%natoms)
187 assert(allocated(epot%proj))
188 assert(allocated(epot%proj(iatom)%sphere%map))
189 assert(allocated(epot%proj(iatom)%sphere%rel_x))
190
191 pmat%map => epot%proj(iatom)%sphere%map
192 pmat%position => epot%proj(iatom)%sphere%rel_x
193 end do
197
199 !--------------------------------------------------------
202 class(nonlocal_pseudopotential_t), intent(inout) :: this
203
204 integer :: iproj
205
207
208 if (allocated(this%projector_matrices)) then
209
211 call accel_free_buffer(this%buff_offsets)
212 call accel_free_buffer(this%buff_matrices)
213 call accel_free_buffer(this%buff_maps)
214 call accel_free_buffer(this%buff_scals)
215 call accel_free_buffer(this%buff_position)
216 call accel_free_buffer(this%buff_pos)
217 call accel_free_buffer(this%buff_invmap)
218 call accel_free_buffer(this%buff_invmap_mat)
219 if (this%projector_mix) call accel_free_buffer(this%buff_mix)
220 if (allocated(this%projector_phases)) call accel_free_buffer(this%buff_projector_phases)
221 end if
222
223 do iproj = 1, this%nprojector_matrices
224 call projector_matrix_deallocate(this%projector_matrices(iproj))
225 end do
226 safe_deallocate_a(this%regions)
227 safe_deallocate_a(this%projector_matrices)
228 safe_deallocate_a(this%projector_phases)
229 safe_deallocate_a(this%projector_to_atom)
230 end if
234
235 !-----------------------------------------------------------------
241 !
242 subroutine nonlocal_pseudopotential_build_proj(this, space, mesh, epot)
243 class(nonlocal_pseudopotential_t), target, intent(inout) :: this
244 class(space_t), intent(in) :: space
245 class(mesh_t), intent(in) :: mesh
246 type(epot_t), target, intent(in) :: epot
247
248 integer :: iatom, iproj, ll, lmax, lloc, mm, ic, jc
249 integer :: nmat, imat, ip, iorder
250 integer :: nregion, jatom, katom, iregion
251 integer, allocatable :: order(:), head(:), region_count(:)
252 logical, allocatable :: atom_counted(:)
253 logical :: overlap
254 type(projector_matrix_t), pointer :: pmat
255 type(kb_projector_t), pointer :: kb_p
256 type(rkb_projector_t), pointer :: rkb_p
257 type(hgh_projector_t), pointer :: hgh_p
258
260
261 call profiling_in("ATOM_COLORING")
262
263 ! this is most likely a very inefficient algorithm, O(natom**2) or
264 ! O(natom**3), probably it should be replaced by something better.
265
266 safe_allocate(order(1:epot%natoms)) ! order(iregion) = ?
267 safe_allocate(head(1:epot%natoms + 1)) ! head(iregion) points to the first atom in region iregion
268 safe_allocate(region_count(1:epot%natoms)) ! region_count(iregion): number of atoms in that region
269 safe_allocate(atom_counted(1:epot%natoms))
270
271 this%projector_self_overlap = .false.
272 atom_counted = .false.
273 order = -1
274
275 head(1) = 1
276 nregion = 0
277 do
278 nregion = nregion + 1
279 assert(nregion <= epot%natoms)
280
281 region_count(nregion) = 0
282
283 do iatom = 1, epot%natoms
284 if (atom_counted(iatom)) cycle
285
286 overlap = .false.
287
288 if (.not. projector_is(epot%proj(iatom), proj_none)) then
289 assert(associated(epot%proj(iatom)%sphere%mesh))
290 do jatom = 1, region_count(nregion)
291 katom = order(head(nregion) + jatom - 1)
292 if (projector_is(epot%proj(katom), proj_none)) cycle
293 overlap = submesh_overlap(epot%proj(iatom)%sphere, epot%proj(katom)%sphere, space)
294 if (overlap) exit
295 end do
296 end if
297
298 if (.not. overlap) then
299 ! iatom did not overlap with any previously counted atoms:
300 ! iatom will be added to the current region
301 region_count(nregion) = region_count(nregion) + 1
302 order(head(nregion) - 1 + region_count(nregion)) = iatom
303 atom_counted(iatom) = .true.
304 end if
305
306 end do
307
308 head(nregion + 1) = head(nregion) + region_count(nregion)
309
310 if (all(atom_counted)) exit
311 end do
312
313 safe_deallocate_a(atom_counted)
314 safe_deallocate_a(region_count)
315
316 call messages_write('The atoms can be separated in ')
317 call messages_write(nregion)
318 call messages_write(' non-overlapping groups.')
319 call messages_info(debug_only=.true.)
320
321 do iregion = 1, nregion
322 do iatom = head(iregion), head(iregion + 1) - 1
323 if (.not. projector_is(epot%proj(order(iatom)), proj_kb)) cycle
324 do jatom = head(iregion), iatom - 1
325 if (.not. projector_is(epot%proj(order(jatom)), proj_kb)) cycle
326 assert(.not. submesh_overlap(epot%proj(order(iatom))%sphere, epot%proj(order(jatom))%sphere, space))
327 end do
328 end do
329 end do
330
331 call profiling_out("ATOM_COLORING")
332
333 ! deallocate previous projectors
334 call this%end()
335
336 ! count projectors
337 this%nprojector_matrices = 0
338 this%apply_projector_matrices = .false.
339 this%has_non_local_potential = .false.
340 this%nregions = nregion
341
342 !We determine if we have only local potential or not.
343 do iorder = 1, epot%natoms
344 iatom = order(iorder)
345
346 if (.not. projector_is_null(epot%proj(iatom))) then
347 this%has_non_local_potential = .true.
348 exit
349 end if
350 end do
351
352 do iorder = 1, epot%natoms
353 iatom = order(iorder)
354
355 if (.not. projector_is_null(epot%proj(iatom))) then
356 this%nprojector_matrices = this%nprojector_matrices + 1
357 this%apply_projector_matrices = .true.
358 end if
359 end do
360
361 ! This is currently the only not supported case
362 if (mesh%use_curvilinear) this%apply_projector_matrices = .false.
363
364 if (.not. this%apply_projector_matrices) then
365 safe_deallocate_a(order)
366 safe_deallocate_a(head)
367
369 return
370 end if
371
372
373 safe_allocate(this%projector_matrices(1:this%nprojector_matrices))
374 safe_allocate(this%regions(1:this%nregions + 1))
375 safe_allocate(this%projector_to_atom(1:epot%natoms))
376
377 this%full_projection_size = 0
378 this%regions(this%nregions + 1) = this%nprojector_matrices + 1
379
380 this%projector_mix = .false.
381
382 iproj = 0
383 do iregion = 1, this%nregions
384 this%regions(iregion) = iproj + 1
385 do iorder = head(iregion), head(iregion + 1) - 1
386
387 iatom = order(iorder)
388
389 if (projector_is(epot%proj(iatom), proj_none)) cycle
390
391 iproj = iproj + 1
392
393 pmat => this%projector_matrices(iproj)
394
395 this%projector_to_atom(iproj) = iatom
396
397 lmax = epot%proj(iatom)%lmax
398 lloc = epot%proj(iatom)%lloc
399
400 if (projector_is(epot%proj(iatom), proj_kb)) then
401
402 ! count the number of projectors for this matrix
403 nmat = 0
404 do ll = 0, lmax
405 if (ll == lloc) cycle
406 do mm = -ll, ll
407 nmat = nmat + epot%proj(iatom)%kb_p(ll, mm)%n_c
408 end do
409 end do
410
411 call projector_matrix_allocate(pmat, nmat, epot%proj(iatom)%sphere, has_mix_matrix = .false.)
412
413 ! generate the matrix
414 pmat%dprojectors = m_zero
415 imat = 1
416 do ll = 0, lmax
417 if (ll == lloc) cycle
418 do mm = -ll, ll
419 kb_p => epot%proj(iatom)%kb_p(ll, mm)
420 do ic = 1, kb_p%n_c
421 call lalg_copy(pmat%npoints, kb_p%p(:, ic), pmat%dprojectors(:, imat))
422 pmat%scal(imat) = kb_p%e(ic)*mesh%vol_pp(1)
423 imat = imat + 1
424 end do
425 end do
426 end do
427
428 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
429
430 else if (projector_is(epot%proj(iatom), proj_hgh)) then
431
432 this%projector_mix = .true.
433
434 ! count the number of projectors for this matrix
435 nmat = 0
436 do ll = 0, lmax
437 if (ll == lloc) cycle
438 do mm = -ll, ll
439 nmat = nmat + 3
440 end do
441 end do
442
443 call projector_matrix_allocate(pmat, nmat, epot%proj(iatom)%sphere, &
444 has_mix_matrix = .true., is_cmplx = (epot%proj_reltype == spin_orbit))
445
446 ! generate the matrix
447 if (epot%proj_reltype == spin_orbit) then
448 pmat%zprojectors = m_zero
449 pmat%zmix = m_zero
450 else
451 pmat%dprojectors = m_zero
452 pmat%dmix = m_zero
453 end if
454
455 imat = 1
456 do ll = 0, lmax
457 if (ll == lloc) cycle
458 do mm = -ll, ll
459 hgh_p => epot%proj(iatom)%hgh_p(ll, mm)
460
461 ! HGH pseudos mix different components, so we need to
462 ! generate a matrix that mixes the projections
463 if (epot%proj_reltype == spin_orbit) then
464 do ic = 1, 3
465 do jc = 1, 3
466 pmat%zmix(imat - 1 + ic, imat - 1 + jc, 1) = hgh_p%h(ic, jc) + m_half*mm*hgh_p%k(ic, jc)
467 pmat%zmix(imat - 1 + ic, imat - 1 + jc, 2) = hgh_p%h(ic, jc) - m_half*mm*hgh_p%k(ic, jc)
468
469 if (mm < ll) then
470 pmat%zmix(imat - 1 + ic, imat + 3 - 1 + jc, 3) = m_half*hgh_p%k(ic, jc) * &
471 sqrt(real(ll*(ll+1)-mm*(mm+1), real64))
472 end if
473
474 if (-mm < ll) then
475 pmat%zmix(imat - 1 + ic, imat - 3 - 1 + jc, 4) = m_half*hgh_p%k(ic, jc) * &
476 sqrt(real(ll*(ll+1)-mm*(mm-1), real64))
477 end if
478 end do
479 end do
480 else
481 do ic = 1, 3
482 do jc = 1, 3
483 pmat%dmix(imat - 1 + ic, imat - 1 + jc) = hgh_p%h(ic, jc)
484 end do
485 end do
486 end if
487
488 do ic = 1, 3
489 if (epot%proj_reltype == spin_orbit) then
490 call lalg_copy(pmat%npoints, hgh_p%zp(:, ic), pmat%zprojectors(:, imat))
491 else
492 call lalg_copy(pmat%npoints, hgh_p%dp(:, ic), pmat%dprojectors(:, imat))
493 end if
494 pmat%scal(imat) = mesh%volume_element
495 imat = imat + 1
496 end do
497
498 end do
499 end do
500
501 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
502
503 else if (projector_is(epot%proj(iatom), proj_rkb)) then
504 assert(epot%proj_reltype == spin_orbit)
505
506 this%projector_mix = .true.
507
508 ! count the number of projectors for this matrix
509 nmat = 0
510 if (lloc /= 0) nmat = nmat + epot%proj(iatom)%kb_p(1, 1)%n_c
511
512 do ll = 1, lmax
513 if (ll == lloc) cycle
514 do mm = -ll, ll
515 nmat = nmat + epot%proj(iatom)%rkb_p(ll, mm)%n_c
516 end do
517 end do
518
519 call projector_matrix_allocate(pmat, nmat, epot%proj(iatom)%sphere, &
520 has_mix_matrix = .true., is_cmplx = .true.)
521
522 pmat%zprojectors = m_zero
523 pmat%zmix = m_zero
524
525 imat = 1
526 if (lloc /= 0) then
527 kb_p => epot%proj(iatom)%kb_p(1, 1)
528
529 do ic = 1, kb_p%n_c
530 pmat%zmix(ic, ic, 1:2) = kb_p%e(ic)
531 do ip = 1, pmat%npoints
532 pmat%zprojectors(ip, ic) = kb_p%p(ip, ic)
533 end do
534 pmat%scal(ic) = mesh%volume_element
535 end do
536 imat = kb_p%n_c + 1
537 nullify(kb_p)
538 end if
539
540 do ll = 1, lmax
541 if (ll == lloc) cycle
542 do mm = -ll, ll
543 rkb_p => epot%proj(iatom)%rkb_p(ll, mm)
544
545 ! See rkb_projector.F90 for understanding the indices
546 do ic = 0, rkb_p%n_c/2-1
547 pmat%zmix(imat + ic*2, imat + ic*2, 1) = rkb_p%f(ic*2+1, 1, 1)
548 pmat%zmix(imat + ic*2, imat + ic*2, 2) = rkb_p%f(ic*2+1, 2, 2)
549
550 pmat%zmix(imat + ic*2+1, imat + ic*2+1, 1) = rkb_p%f(ic*2+2, 1, 1)
551 pmat%zmix(imat + ic*2+1, imat + ic*2+1, 2) = rkb_p%f(ic*2+2, 2, 2)
552
553 if (mm < ll) then
554 pmat%zmix(imat + ic*2+rkb_p%n_c, imat + ic*2, 4) = rkb_p%f(ic*2+1, 2, 1)
555 pmat%zmix(imat + ic*2+1+rkb_p%n_c, imat + ic*2+1, 4) = rkb_p%f(ic*2+2, 2, 1)
556 end if
557
558 if (-mm < ll) then
559 pmat%zmix(imat + ic*2-rkb_p%n_c, imat + ic*2, 3) = rkb_p%f(ic*2+1, 1, 2)
560 pmat%zmix(imat + ic*2+1-rkb_p%n_c, imat + ic*2+1, 3) = rkb_p%f(ic*2+2, 1, 2)
561 end if
562 end do
563
564 do ic = 1, rkb_p%n_c
565 call lalg_copy(pmat%npoints, rkb_p%ket(:, ic, 1, 1), pmat%zprojectors(:, imat))
566 pmat%scal(imat) = mesh%volume_element
567 imat = imat + 1
568 end do
569 end do
570
571 nullify(rkb_p)
572 end do
573
574 this%projector_self_overlap = this%projector_self_overlap .or. epot%proj(iatom)%sphere%overlap
575
576 else
577 cycle
578 end if
579
580 pmat%map => epot%proj(iatom)%sphere%map
581 pmat%position => epot%proj(iatom)%sphere%rel_x
582
583 pmat%regions = epot%proj(iatom)%sphere%regions
584
585 this%full_projection_size = this%full_projection_size + pmat%nprojs
586
587 end do
588 end do
589
590 if (mesh%parallel_in_domains) then
591 call mesh%mpi_grp%allreduce_inplace(this%projector_self_overlap, 1, mpi_logical, mpi_lor)
592 end if
593
594 safe_deallocate_a(order)
595 safe_deallocate_a(head)
596
597 this%total_points = 0
598 this%max_npoints = 0
599 this%max_nprojs = 0
600 do imat = 1, this%nprojector_matrices
601 pmat => this%projector_matrices(imat)
602
603 this%max_npoints = max(this%max_npoints, pmat%npoints)
604 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
605 this%total_points = this%total_points + pmat%npoints
606 end do
607
608 if (accel_is_enabled()) then
611 end if
612
614
616
617 ! ----------------------------------------------------------------------------------
619 subroutine nonlocal_pseudopotential_accel_rebuild(this, space, mesh)
620 class(nonlocal_pseudopotential_t), target, intent(inout) :: this
621 class(space_t), intent(in) :: space
622 class(mesh_t), intent(in) :: mesh
623
625
626 if (.not. accel_is_enabled()) then
628 return
629 end if
630
632
633 if (.not. allocated(this%projector_matrices) .or. this%nprojector_matrices <= 0) then
635 return
636 end if
637
640
643
644 ! ----------------------------------------------------------------------------------
647 class(nonlocal_pseudopotential_t), intent(inout) :: this
648
650
651 call accel_detach_buffer(this%buff_offsets)
652 call accel_detach_buffer(this%buff_matrices)
653 call accel_detach_buffer(this%buff_maps)
654 call accel_detach_buffer(this%buff_scals)
655 call accel_detach_buffer(this%buff_position)
656 call accel_detach_buffer(this%buff_pos)
657 call accel_detach_buffer(this%buff_invmap)
658 call accel_detach_buffer(this%buff_invmap_mat)
659 call accel_detach_buffer(this%buff_projector_phases)
660 call accel_detach_buffer(this%buff_mix)
661
664
665 ! ----------------------------------------------------------------------------------
667 subroutine nonlocal_pseudopotential_build_accel_buffers(this, space, mesh)
668 class(nonlocal_pseudopotential_t), target, intent(inout) :: this
669 class(space_t), intent(in) :: space
670 class(mesh_t), intent(in) :: mesh
671
672 integer, parameter :: OFFSET_SIZE = 6
673 integer, parameter :: POINTS = 1, projs = 2, matrix = 3, map = 4, scal = 5, mix = 6
674 integer :: imat, matrix_size, scal_size
675 integer :: ip, is, ii, ipos, mix_offset
676 integer, allocatable :: cnt(:), invmap(:, :), invmap2(:), pos(:)
677 integer, allocatable :: invmap_mat(:, :), invmap_mat2(:)
678 integer, allocatable :: offsets(:, :)
679 type(projector_matrix_t), pointer :: pmat
680
682
683 assert(allocated(this%projector_matrices))
684 assert(this%nprojector_matrices > 0)
685
686 safe_allocate(offsets(1:offset_size, 1:this%nprojector_matrices))
687 safe_allocate(cnt(1:mesh%np))
688
689 cnt = 0
690
691 matrix_size = 0
692 this%total_points = 0
693 scal_size = 0
694 this%max_npoints = 0
695 this%max_nprojs = 0
696 mix_offset = 0
697 do imat = 1, this%nprojector_matrices
698 pmat => this%projector_matrices(imat)
699
700 this%max_npoints = max(this%max_npoints, pmat%npoints)
701 this%max_nprojs = max(this%max_nprojs, pmat%nprojs)
702
703 offsets(points, imat) = pmat%npoints
704 offsets(projs, imat) = pmat%nprojs
705
706 offsets(matrix, imat) = matrix_size
707 matrix_size = matrix_size + pmat%npoints*pmat%nprojs
708
709 offsets(map, imat) = this%total_points
710 this%total_points = this%total_points + pmat%npoints
711
712 offsets(scal, imat) = scal_size
713 scal_size = scal_size + pmat%nprojs
715 offsets(mix, imat) = mix_offset
716 if (allocated(pmat%dmix)) then
717 mix_offset = mix_offset + pmat%nprojs**2
718 else if (allocated(pmat%zmix)) then
719 mix_offset = mix_offset + 4*pmat%nprojs**2
720 else
721 offsets(mix, imat) = -1
722 end if
723
724 do is = 1, pmat%npoints
725 ip = pmat%map(is)
726 cnt(ip) = cnt(ip) + 1
727 end do
728 end do
729
730 safe_allocate(invmap(1:max(maxval(cnt), 1), 1:mesh%np))
731 safe_allocate(invmap2(1:max(maxval(cnt)*mesh%np, 1)))
732 safe_allocate(invmap_mat(1:max(maxval(cnt), 1), 1:mesh%np))
733 safe_allocate(invmap_mat2(1:max(maxval(cnt)*mesh%np, 1)))
734 safe_allocate(pos(1:mesh%np + 1))
735
736 cnt = 0
737 ii = 0
738 do imat = 1, this%nprojector_matrices
739 pmat => this%projector_matrices(imat)
740 do is = 1, pmat%npoints
741 ip = pmat%map(is)
742 cnt(ip) = cnt(ip) + 1
743 invmap(cnt(ip), ip) = ii
744 invmap_mat(cnt(ip), ip) = imat - 1
745 ii = ii + 1
746 end do
747 end do
748
749 ipos = 0
750 pos(1) = 0
751 do ip = 1, mesh%np
752 do ii = 1, cnt(ip)
753 ipos = ipos + 1
754 invmap2(ipos) = invmap(ii, ip)
755 invmap_mat2(ipos) = invmap_mat(ii, ip)
756 end do
757 pos(ip + 1) = ipos
758 end do
759
760 if (this%projector_matrices(1)%is_cmplx) then
761 call accel_create_buffer(this%buff_matrices, accel_mem_read_only, type_cmplx, matrix_size)
762 else
763 call accel_create_buffer(this%buff_matrices, accel_mem_read_only, type_float, matrix_size)
764 end if
765 call accel_create_buffer(this%buff_maps, accel_mem_read_only, type_integer, this%total_points)
766 call accel_create_buffer(this%buff_position, accel_mem_read_only, type_float, 3*this%total_points)
767 call accel_create_buffer(this%buff_scals, accel_mem_read_only, type_float, scal_size)
768
769 if (mix_offset > 0) then
770 if (allocated(this%projector_matrices(1)%zmix)) then
771 call accel_create_buffer(this%buff_mix, accel_mem_read_only, type_cmplx, mix_offset)
772 else
773 call accel_create_buffer(this%buff_mix, accel_mem_read_only, type_float, mix_offset)
774 end if
775 end if
776
777 do imat = 1, this%nprojector_matrices
778 pmat => this%projector_matrices(imat)
779 if (pmat%npoints > 0) then
780 if (pmat%is_cmplx) then
781 call accel_write_buffer(this%buff_matrices, pmat%npoints, pmat%nprojs, pmat%zprojectors, &
782 offset = offsets(matrix, imat))
783 else
784 call accel_write_buffer(this%buff_matrices, pmat%npoints, pmat%nprojs, pmat%dprojectors, &
785 offset = offsets(matrix, imat))
786 end if
787 call accel_write_buffer(this%buff_maps, pmat%npoints, pmat%map, offset = offsets(map, imat))
788 call accel_write_buffer(this%buff_position, space%dim, pmat%npoints, pmat%position, &
789 offset = 3*offsets(map, imat))
790 end if
791 call accel_write_buffer(this%buff_scals, pmat%nprojs, pmat%scal, offset = offsets(scal, imat))
792 if (offsets(mix, imat) /= -1) then
793 if (allocated(pmat%zmix)) then
794 call accel_write_buffer(this%buff_mix, pmat%nprojs, pmat%nprojs, 4, pmat%zmix, offset = offsets(mix, imat))
795 else
796 call accel_write_buffer(this%buff_mix, pmat%nprojs, pmat%nprojs, pmat%dmix, offset = offsets(mix, imat))
797 end if
798 end if
799 end do
800
801 call accel_create_buffer(this%buff_offsets, accel_mem_read_only, type_integer, offset_size*this%nprojector_matrices)
802 call accel_write_buffer(this%buff_offsets, offset_size, this%nprojector_matrices, offsets)
803
804 call accel_create_buffer(this%buff_pos, accel_mem_read_only, type_integer, mesh%np + 1)
805 call accel_write_buffer(this%buff_pos, mesh%np + 1, pos)
806
807 call accel_create_buffer(this%buff_invmap, accel_mem_read_only, type_integer, ipos)
808 call accel_write_buffer(this%buff_invmap, ipos, invmap2)
809
810 call accel_create_buffer(this%buff_invmap_mat, accel_mem_read_only, type_integer, ipos)
811 call accel_write_buffer(this%buff_invmap_mat, ipos, invmap_mat2)
812
813 safe_deallocate_a(offsets)
814 safe_deallocate_a(cnt)
815 safe_deallocate_a(invmap)
816 safe_deallocate_a(invmap2)
817 safe_deallocate_a(invmap_mat)
818 safe_deallocate_a(invmap_mat2)
819 safe_deallocate_a(pos)
820
823
824 ! ----------------------------------------------------------------------------------
827 class(nonlocal_pseudopotential_t), intent(inout) :: this
828
829 integer :: ik, imat, iphase, nphase, offset, npoints
830
832
833 if (.not. allocated(this%projector_phases)) then
835 return
836 end if
837
838 nphase = size(this%projector_phases, 2)
839 this%nphase = nphase
840
841 call accel_create_buffer(this%buff_projector_phases, accel_mem_read_only, type_cmplx, &
842 this%total_points*nphase*size(this%projector_phases, 4))
843
844 offset = 0
845 do ik = lbound(this%projector_phases, 4), ubound(this%projector_phases, 4)
846 do imat = 1, this%nprojector_matrices
847 npoints = this%projector_matrices(imat)%npoints
848 do iphase = 1, nphase
849 if (npoints > 0) then
850 call accel_write_buffer(this%buff_projector_phases, npoints, this%projector_phases(1:, iphase, imat, ik), &
851 offset = offset, async=.true.)
852 end if
853 offset = offset + npoints
854 end do
855 end do
856 end do
857 call accel_finish()
858
861
862 ! ----------------------------------------------------------------------------------
864 !
865 logical pure function nonlocal_pseudopotential_self_overlap(this) result(projector_self_overlap)
866 class(nonlocal_pseudopotential_t), intent(in) :: this
867
868 projector_self_overlap = this%projector_self_overlap
870
871#include "undef.F90"
872#include "real.F90"
873#include "nonlocal_pseudopotential_inc.F90"
874
875#include "undef.F90"
876#include "complex.F90"
877#include "nonlocal_pseudopotential_inc.F90"
878
880
881!! Local Variables:
882!! mode: f90
883!! coding: utf-8
884!! 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:941
subroutine, public accel_finish()
Definition: accel.F90:1059
subroutine, public accel_detach_buffer(this)
Clear a buffer handle without freeing device memory.
Definition: accel.F90:1010
pure logical function, public accel_is_enabled()
Definition: accel.F90:372
integer, parameter, public accel_mem_read_only
Definition: accel.F90:185
type(accel_kernel_t), pointer head
Definition: accel.F90:366
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)