Octopus
density.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2010 M. Marques, A. Castro, A. Rubio, G. Bertsch, 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
26!
27module density_oct_m
28 use accel_oct_m
29 use batch_oct_m
31 use iso_c_binding
32 use comm_oct_m
33 use debug_oct_m
36 use epot_oct_m
37 use global_oct_m
38 use grid_oct_m
39 use, intrinsic :: iso_fortran_env
42 use math_oct_m
43 use mesh_oct_m
46 use mpi_oct_m
50 use parser_oct_m
51 use phase_oct_m
55 use ps_oct_m, only: proj_uspp
56 use smear_oct_m
57 use space_oct_m
61 use types_oct_m
63
64 implicit none
65
66 private
67
68 public :: &
81
84 private
85 real(real64), contiguous, pointer :: density(:, :)
86 ! !! dimensions (1:np, 1:d%nspin)
87 type(states_elec_t), pointer :: st => null()
88 type(grid_t), pointer :: gr => null()
89 type(epot_t), pointer :: ep => null()
90 type(nonlocal_pseudopotential_t), pointer :: vnl => null()
91 type(phase_t), pointer :: phase => null()
92 type(accel_mem_t) :: buff_density
93 integer(int64) :: pnp
94 logical :: packed
95 end type density_calc_t
96
97contains
98
103 !
104 subroutine density_calc_init(this, st, gr, density, ep, vnl, phase)
105 type(density_calc_t), intent(out) :: this
106 type(states_elec_t), target, intent(in) :: st
107 type(grid_t), target, intent(in) :: gr
108 real(real64), contiguous, target, intent(out) :: density(:, :)
109 type(epot_t), optional, target, intent(in) :: ep
110 type(nonlocal_pseudopotential_t), optional, target, intent(in) :: vnl
111 type(phase_t), optional, target, intent(in) :: phase
112
113 integer :: ip, ispin
114 logical :: correct_size
115
116 push_sub(density_calc_init)
117
118 this%st => st
119 this%gr => gr
120 nullify(this%ep)
121 nullify(this%vnl)
122 nullify(this%phase)
123
124 if (st%requires_generalized_overlap) then
125 if (.not. present(ep) .or. .not. present(vnl)) then
126 call messages_not_implemented("density calculation with ultrasoft/PAW augmentation density")
127 end if
128 this%ep => ep
129 this%vnl => vnl
130 if (present(phase)) this%phase => phase
131 end if
132
133 this%density => density
134 !$omp parallel private(ip)
135 do ispin = 1, st%d%nspin
136 !$omp do
137 do ip = 1, gr%np
138 this%density(ip, ispin) = m_zero
139 end do
140 !$omp end do nowait
141 end do
142 !$omp end parallel
143
144 this%packed = .false.
145
146 correct_size = ubound(this%density, dim = 1) == this%gr%np .or. &
147 ubound(this%density, dim = 1) == this%gr%np_part
148 assert(correct_size)
149
150 pop_sub(density_calc_init)
151 end subroutine density_calc_init
152
153 ! ---------------------------------------------------
155 !
156 subroutine density_calc_pack(this, async)
157 type(density_calc_t), intent(inout) :: this
158 logical, optional, intent(in) :: async
159
160 push_sub(density_calc_pack)
161
162 this%packed = .true.
163 this%pnp = accel_padded_size(this%gr%np)
164 call accel_create_buffer(this%buff_density, accel_mem_read_write, type_float, this%pnp*this%st%d%nspin)
165
166 ! set to zero
167 call accel_set_buffer_to_zero(this%buff_density, type_float, this%pnp*this%st%d%nspin, async=async)
168
169 pop_sub(density_calc_pack)
170 end subroutine density_calc_pack
171
172 ! ---------------------------------------------------
177 subroutine density_calc_state(this, psib, istin)
178 type(density_calc_t), intent(inout) :: this
179 type(wfs_elec_t), intent(in) :: psib
180 integer, intent(in) :: istin
182 integer :: ist, ip, ispin, istin_, bsize, gsize
183 complex(real64) :: term, psi1, psi2
184 real(real64), allocatable :: weight(:)
185 type(accel_mem_t) :: buff_weight
186 type(accel_kernel_t), pointer :: kernel
188 push_sub(density_calc_state)
189 call profiling_in("CALC_STATE_DENSITY")
190
191 ispin = this%st%d%get_spin_index(psib%ik)
192
193 istin_= 0
194
195 safe_allocate(weight(1:psib%nst))
196 do ist = 1, psib%nst
197 weight(ist) = this%st%kweights(psib%ik)*this%st%occ(psib%ist(ist), psib%ik)
198 if (psib%ist(ist) == istin) istin_ = ist
199 end do
200
201 assert(istin_ > 0)
202
203 if (abs(weight(istin_)) <= m_epsilon) then
204 call profiling_out("CALC_STATE_DENSITY")
205 pop_sub(density_calc_state)
206 return
207 end if
208
209 !fix ist for the remaining code
210 ist = istin_
211
212
213 select case (psib%status())
214 case (batch_not_packed)
215 select case (this%st%d%ispin)
217 if (states_are_real(this%st)) then
218 !$omp parallel do simd schedule(static)
219 do ip = 1, this%gr%np
220 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff(ip, 1, ist)**2
221 end do
222 else
223 !$omp parallel do schedule(static)
224 do ip = 1, this%gr%np
225 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
226 real(conjg(psib%zff(ip, 1, ist))*psib%zff(ip, 1, ist), real64)
227 end do
228 end if
229 case (spinors)
230 !$omp parallel do schedule(static) private(psi1, psi2, term)
231 do ip = 1, this%gr%np
232 psi1 = psib%zff(ip, 1, ist)
233 psi2 = psib%zff(ip, 2, ist)
234 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
235 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
236 term = weight(ist)*psi1*conjg(psi2)
237 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
238 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
239 end do
240 end select
241
242 case (batch_packed)
243
244 select case (this%st%d%ispin)
246 if (states_are_real(this%st)) then
247 !$omp parallel do schedule(static)
248 do ip = 1, this%gr%np
249 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff_pack(ist, ip)**2
250 end do
251 else
252
253 !$omp parallel do schedule(static)
254 do ip = 1, this%gr%np
255 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
256 real(conjg(psib%zff_pack(ist, ip))*psib%zff_pack(ist, ip), real64)
257 end do
258 end if
259 case (spinors)
260 assert(mod(psib%nst_linear, 2) == 0)
261 !$omp parallel do schedule(static) private(psi1, psi2, term)
262 do ip = 1, this%gr%np
263 psi1 = psib%zff_pack(2*ist - 1, ip)
264 psi2 = psib%zff_pack(2*ist, ip)
265 term = weight(ist)*psi1*conjg(psi2)
266
267 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
268 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
269 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
270 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
271 end do
272 end select
273
275 if (.not. this%packed) call density_calc_pack(this, async=.true.)
276
277 call accel_create_buffer(buff_weight, accel_mem_read_only, type_float, psib%nst)
278 call accel_write_buffer(buff_weight, psib%nst, weight, async=.true.)
279
280 select case (this%st%d%ispin)
282 if (states_are_real(this%st)) then
283 kernel => kernel_density_real
284 else
285 kernel => kernel_density_complex
286 end if
287
288 call accel_set_kernel_arg(kernel, 0, psib%nst)
289 call accel_set_kernel_arg(kernel, 1, this%gr%np)
290 call accel_set_kernel_arg(kernel, 2, int(this%pnp*(ispin - 1), int32))
291 call accel_set_kernel_arg(kernel, 3, buff_weight)
292 call accel_set_kernel_arg(kernel, 4, psib%ff_device)
293 call accel_set_kernel_arg(kernel, 5, int(log2(psib%pack_size(1)), int32))
294 call accel_set_kernel_arg(kernel, 6, this%buff_density)
295
296 case (spinors)
297 kernel => kernel_density_spinors
298
299 call accel_set_kernel_arg(kernel, 0, psib%nst)
300 call accel_set_kernel_arg(kernel, 1, this%gr%np)
301 call accel_set_kernel_arg(kernel, 2, int(this%pnp, int32))
302 call accel_set_kernel_arg(kernel, 3, buff_weight)
303 call accel_set_kernel_arg(kernel, 4, psib%ff_device)
304 call accel_set_kernel_arg(kernel, 5, int(log2(psib%pack_size(1)), int32))
305 call accel_set_kernel_arg(kernel, 6, this%buff_density)
306 end select
307
308 ! Compute the grid
309 bsize = accel_kernel_block_size(kernel)
310 call accel_grid_size(this%gr%np, bsize, gsize)
311
312 call accel_kernel_run(kernel, (/gsize/), (/bsize/))
313
314 call accel_finish()
315 call accel_free_buffer(buff_weight)
316 end select
317
318 if (this%st%requires_generalized_overlap) then
319 call density_calc_accumulate_uspp(this, psib, ispin, weight)
320 end if
321
322 safe_deallocate_a(weight)
323
324 call profiling_out("CALC_STATE_DENSITY")
325
326 pop_sub(density_calc_state)
327 end subroutine density_calc_state
328
329 ! ---------------------------------------------------
331 !
332 subroutine density_calc_accumulate(this, psib, async)
333 type(density_calc_t), intent(inout) :: this
334 type(wfs_elec_t), intent(in) :: psib
335 logical, optional, intent(in) :: async
336
337 integer :: ist, ip, ispin, bsize, gsize
338 complex(real64) :: term, psi1, psi2
339 real(real64), allocatable :: weight(:)
340 type(accel_mem_t) :: buff_weight
341 type(accel_kernel_t), pointer :: kernel
342
344 call profiling_in("CALC_DENSITY")
345
346 ispin = this%st%d%get_spin_index(psib%ik)
347
348 safe_allocate(weight(1:psib%nst))
349 do ist = 1, psib%nst
350 weight(ist) = this%st%kweights(psib%ik)*this%st%occ(psib%ist(ist), psib%ik)
351 end do
352
353 select case (psib%status())
354 case (batch_not_packed)
355 select case (this%st%d%ispin)
357 if (states_are_real(this%st)) then
358 do ist = 1, psib%nst
359 if (abs(weight(ist)) <= m_epsilon) cycle
360 !$omp parallel do simd schedule(static)
361 do ip = 1, this%gr%np
362 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff(ip, 1, ist)**2
363 end do
364 end do
365 else
366 do ist = 1, psib%nst
367 if (abs(weight(ist)) <= m_epsilon) cycle
368 !$omp parallel do schedule(static)
369 do ip = 1, this%gr%np
370 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
371 real(conjg(psib%zff(ip, 1, ist))*psib%zff(ip, 1, ist), real64)
372 end do
373 end do
374 end if
375 case (spinors)
376 do ist = 1, psib%nst
377 if (abs(weight(ist)) <= m_epsilon) cycle
378 !$omp parallel do schedule(static) private(psi1, psi2, term)
379 do ip = 1, this%gr%np
380 psi1 = psib%zff(ip, 1, ist)
381 psi2 = psib%zff(ip, 2, ist)
382 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
383 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
384 term = weight(ist)*psi1*conjg(psi2)
385 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
386 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
387 end do
388 end do
389 end select
390
391 case (batch_packed)
392
393 select case (this%st%d%ispin)
395 if (states_are_real(this%st)) then
396 !$omp parallel do schedule(static) private(ist)
397 do ip = 1, this%gr%np
398 do ist = 1, psib%nst
399 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff_pack(ist, ip)**2
400 end do
401 end do
402 else
403 !$omp parallel do schedule(static) private(ist)
404 do ip = 1, this%gr%np
405 do ist = 1, psib%nst
406 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
407 real(conjg(psib%zff_pack(ist, ip))*psib%zff_pack(ist, ip), real64)
408 end do
409 end do
410 end if
411 case (spinors)
412 assert(mod(psib%nst_linear, 2) == 0)
413 !$omp parallel do schedule(static) private(ist, psi1, psi2, term)
414 do ip = 1, this%gr%np
415 do ist = 1, psib%nst
416 psi1 = psib%zff_pack(2*ist - 1, ip)
417 psi2 = psib%zff_pack(2*ist, ip)
418 term = weight(ist)*psi1*conjg(psi2)
419
420 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
421 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
422 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
423 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
424 end do
425 end do
426 end select
427
429 if (.not. this%packed) call density_calc_pack(this)
430
431 call accel_create_buffer(buff_weight, accel_mem_read_only, type_float, psib%nst)
432 call accel_write_buffer(buff_weight, psib%nst, weight, async=.true.)
433
434 select case (this%st%d%ispin)
436 if (states_are_real(this%st)) then
437 kernel => kernel_density_real
438 else
439 kernel => kernel_density_complex
440 end if
441
442 call accel_set_kernel_arg(kernel, 0, psib%nst)
443 call accel_set_kernel_arg(kernel, 1, this%gr%np)
444 call accel_set_kernel_arg(kernel, 2, int(this%pnp, int32)*(ispin - 1))
445 call accel_set_kernel_arg(kernel, 3, buff_weight)
446 call accel_set_kernel_arg(kernel, 4, psib%ff_device)
447 call accel_set_kernel_arg(kernel, 5, int(log2(psib%pack_size(1)), int32))
448 call accel_set_kernel_arg(kernel, 6, this%buff_density)
449
450 case (spinors)
451 kernel => kernel_density_spinors
452
453 call accel_set_kernel_arg(kernel, 0, psib%nst)
454 call accel_set_kernel_arg(kernel, 1, this%gr%np)
455 call accel_set_kernel_arg(kernel, 2, int(this%pnp, int32))
456 call accel_set_kernel_arg(kernel, 3, buff_weight)
457 call accel_set_kernel_arg(kernel, 4, psib%ff_device)
458 call accel_set_kernel_arg(kernel, 5, int(log2(psib%pack_size(1)), int32))
459 call accel_set_kernel_arg(kernel, 6, this%buff_density)
460 end select
461
462 ! Compute the grid
463 bsize = accel_kernel_block_size(kernel)
464 call accel_grid_size(this%gr%np, bsize, gsize)
465
466 call accel_kernel_run(kernel, (/gsize/), (/bsize/))
467
468 call accel_free_buffer(buff_weight)
469
470 if(.not. optional_default(async, .false.)) call accel_finish()
471
472 end select
473
474 ! Ultrasoft/PAW augmentation density: n(r) += sum_ij Q_ij(r) <psi|beta_i><beta_j|psi>.
475 ! This must be done on the batch path used by the SCF (density_calc), not only in
476 ! density_calc_state, otherwise the augmentation charge is silently dropped.
477 if (this%st%requires_generalized_overlap) then
478 call density_calc_accumulate_uspp(this, psib, ispin, weight)
479 end if
480
481 safe_deallocate_a(weight)
482
483
484 if (this%st%d%ispin /= spinors) then
485 if (states_are_real(this%st)) then
486 ! 1 add (1), 2 mult (1)
487 call profiling_count_operations(psib%nst*this%gr%np*(1 + 2))
488 else
489 ! 1 add (2), 1 complex mult (6), 1 real-complex mult (2)
490 call profiling_count_operations(psib%nst*this%gr%np*(2 + 6 + 2))
491 end if
492 else
493 ! 4 add (2), 3 complex mult (6), 3 real-complex mult (2)
494 call profiling_count_operations(psib%nst*this%gr%np*(4*2 + 3*6 + 3*2))
495 end if
496
497 call profiling_out("CALC_DENSITY")
498
500 end subroutine density_calc_accumulate
501
502 ! ---------------------------------------------------
504 subroutine density_calc_accumulate_uspp(this, psib, ispin, weight)
505 type(density_calc_t), intent(inout) :: this
506 type(wfs_elec_t), intent(in) :: psib
507 integer, intent(in) :: ispin
508 real(real64), intent(in) :: weight(:)
509
510 integer :: imat, iatom, iproj, jproj, ltot, mtot, is, ip, pair_index, lm, np, lmaxq
511 real(real64) :: coeff, val, cval
512 real(real64), allocatable :: beta_density(:, :, :)
513 real(real64), allocatable :: acc(:)
514 type(projector_matrix_t), pointer :: pmat
515 type(projector_t), pointer :: proj
516 type(wfs_elec_t) :: phased_psib
517 logical :: do_phase
518
519 push_sub_with_profile(density_calc_accumulate_uspp)
520
521 assert(associated(this%ep))
522 assert(associated(this%vnl))
523 assert(this%st%d%ispin /= spinors)
524 assert(this%st%d%dim == 1)
525 assert(.not. this%gr%use_curvilinear)
526 assert(this%vnl%apply_projector_matrices)
527
528 if (psib%status() == batch_device_packed) then
529 call messages_not_implemented("USPP augmentation density for accelerator batches")
530 end if
531
532 ! The projections <beta|psi> that build the augmentation density matrix must
533 ! include the Bloch phase exp(ik.r) at k /= 0, exactly as in the Hamiltonian and
534 ! overlap apply.
535 do_phase = .false.
536 if (associated(this%phase)) do_phase = this%phase%is_allocated()
537
538 if (states_are_real(this%st)) then
539 call dnonlocal_pseudopotential_density_matrix(this%vnl, this%gr, this%st%d, .false., psib, weight, beta_density)
540 else if (do_phase .and. .not. psib%has_phase) then
541 call psib%copy_to(phased_psib)
542 call this%phase%apply_to(this%gr, this%gr%np, .false., phased_psib, src = psib)
543 phased_psib%has_phase = .true.
544 call znonlocal_pseudopotential_density_matrix(this%vnl, this%gr, this%st%d, .false., phased_psib, weight, beta_density)
545 call phased_psib%end()
546 else
547 call znonlocal_pseudopotential_density_matrix(this%vnl, this%gr, this%st%d, .false., psib, weight, beta_density)
548 end if
549
550 do imat = 1, this%vnl%nprojector_matrices
551 pmat => this%vnl%projector_matrices(imat)
552 iatom = this%vnl%projector_to_atom(imat)
553 proj => this%ep%proj(iatom)
554
555 assert(projector_is(proj, proj_uspp))
556 assert(allocated(proj%uspp_qfunc))
557 assert(proj%uspp_qfunc_nbeta > 0)
558 assert(proj%uspp_qfunc_lmax >= 0)
559
560 np = pmat%npoints
561 lmaxq = proj%uspp_qfunc_lmax
562
563 ! Real spherical harmonics Y_LM at the sphere points depend only on the (fixed)
564 ! sphere geometry. By default they are computed once and cached in the projector
565 ! matrix (shared with nonlocal_pseudopotential_update_dij; reset when projectors
566 ! rebuild); with USPPSaveMemory the cache is freed at the end of the call.
567 ! Index lm = L*(L+1) + M + 1, L = 0..lmaxq, M = -L..L.
568 if (.not. allocated(pmat%uspp_ylm)) then
569 safe_allocate(pmat%uspp_ylm(1:np, 1:(lmaxq + 1)**2))
570 do ltot = 0, lmaxq
571 do mtot = -ltot, ltot
572 lm = ltot*(ltot + 1) + mtot + 1
573 do is = 1, np
574 call ylmr_real(pmat%position(1:3, is), ltot, mtot, pmat%uspp_ylm(is, lm))
575 end do
576 end do
577 end do
578 end if
579
580 safe_allocate(acc(1:np))
581 acc(1:np) = m_zero
582 do iproj = 1, pmat%nprojs
583 assert(pmat%beta_index(iproj) >= 1 .and. pmat%beta_index(iproj) <= proj%uspp_qfunc_nbeta)
584 do jproj = 1, pmat%nprojs
585 assert(pmat%beta_index(jproj) >= 1 .and. pmat%beta_index(jproj) <= proj%uspp_qfunc_nbeta)
586 val = beta_density(iproj, jproj, imat)
587 if (abs(val) <= m_epsilon) cycle
588
589 pair_index = (pmat%beta_index(iproj) - 1)*proj%uspp_qfunc_nbeta + pmat%beta_index(jproj)
590
591 ! Gaunt coefficients depend only on the angular momenta, so hoist them out
592 ! of the grid-point loop. The remaining inner loop over sphere points is
593 ! contiguous and branch-free (a zero Q_ij^L simply contributes zero).
594 do ltot = 0, lmaxq
595 do mtot = -ltot, ltot
596 coeff = real_gaunt(pmat%l(iproj), pmat%m(iproj), pmat%l(jproj), pmat%m(jproj), ltot, mtot)
597 if (abs(coeff) <= 1.0e-12_real64) cycle
598 cval = val*coeff
599 lm = ltot*(ltot + 1) + mtot + 1
600 !$omp simd
601 do is = 1, np
602 acc(is) = acc(is) + cval*pmat%uspp_ylm(is, lm)*proj%uspp_qfunc(is, pair_index, ltot)
603 end do
604 end do
605 end do
606 end do
607 end do
608
609 ! Scatter the accumulated augmentation density onto the mesh (once per atom).
610 do is = 1, np
611 ip = pmat%map(is)
612 this%density(ip, ispin) = this%density(ip, ispin) + acc(is)
613 end do
614
615 safe_deallocate_a(acc)
616 ! With USPPSaveMemory we do not retain the Y_LM cache between calls.
617 if (this%vnl%uspp_save_memory) then
618 safe_deallocate_a(pmat%uspp_ylm)
619 end if
620 end do
621
622 safe_deallocate_a(beta_density)
623
624 pop_sub_with_profile(density_calc_accumulate_uspp)
625 end subroutine density_calc_accumulate_uspp
626
627 ! ---------------------------------------------------
633 !
634 subroutine density_calc_end(this, allreduce, symmetrize, buff_density)
635 type(density_calc_t), intent(inout) :: this
636 logical, optional, intent(in) :: allreduce
637 logical, optional, intent(in) :: symmetrize
638 type(accel_mem_t), optional, intent(inout) :: buff_density
639
640 integer :: ispin, ip
641 real(real64), allocatable :: tmpdensity(:)
642 logical :: was_packed
643
644 logical:: allreduce_local, symmetrize_local
645
646 push_sub(density_calc_end)
647
648 call profiling_in("CALC_DENSITY_END")
649
650 allreduce_local = (this%st%parallel_in_states .or. this%st%d%kpt%parallel) .and. optional_default(allreduce, .true.)
651 symmetrize_local = this%st%symmetrize_density .and. optional_default(symmetrize, .true.)
652
653 was_packed = this%packed ! Save before modifying
654 if (this%packed) then
655 this%packed = .false.
656
657 safe_allocate(tmpdensity(1:this%gr%np))
658
659 ! the density is in device memory
660 do ispin = 1, this%st%d%nspin
661 call accel_read_buffer(this%buff_density, int(this%gr%np, int64), tmpdensity, offset = (ispin - 1)*this%pnp)
662
663 !$omp parallel do simd
664 do ip = 1, this%gr%np
665 this%density(ip, ispin) = this%density(ip, ispin) + tmpdensity(ip)
666 end do
667 end do
668
669 safe_deallocate_a(tmpdensity)
670
671 ! If buff_density is not needed, free the GPU buffer now
672 if (.not. present(buff_density)) then
673 call accel_free_buffer(this%buff_density)
674 end if
675 end if
676
677 ! reduce over states and k-points
678 if (allreduce_local) then
679 call profiling_in("DENSITY_REDUCE")
680 call comm_allreduce(this%st%st_kpt_mpi_grp, this%density, dim = (/this%gr%np, this%st%d%nspin/))
681 call profiling_out("DENSITY_REDUCE")
682 end if
683
684 if (symmetrize_local) then
685 do ispin = 1, this%st%d%nspin
686 call dgrid_symmetrize_scalar_field(this%gr, this%density(:, ispin))
687 end do
688 end if
689
690 if (present(buff_density) .and. was_packed) then
691 if (allreduce_local .or. symmetrize_local) then
692 do ispin = 1, this%st%d%nspin
693 call accel_write_buffer(this%buff_density, int(this%gr%np, int64), &
694 this%density(1:this%gr%np, ispin), &
695 offset=int((ispin - 1)*this%pnp, int64))
696 end do
697 end if
698
699 ! Free any previously stored buffer before overwriting
700 if (buff_density%allocated) call accel_free_buffer(buff_density)
701
702 call accel_move_buffer(this%buff_density, buff_density)
703 end if
704
705 call profiling_out("CALC_DENSITY_END")
706
707 pop_sub(density_calc_end)
708 end subroutine density_calc_end
709
710
711 ! ---------------------------------------------------------
716 !
717 subroutine density_calc(st, gr, density, istin, ep, vnl, phase)
718 type(states_elec_t), intent(inout) :: st
719 type(grid_t), intent(in) :: gr
720 real(real64), contiguous, intent(out) :: density(:, :)
721 integer, optional, intent(in) :: istin
722 type(epot_t), optional, target, intent(in) :: ep
723 type(nonlocal_pseudopotential_t), optional, target, intent(in) :: vnl
724 type(phase_t), optional, target, intent(in) :: phase
725
726 integer :: ik, ib
727 type(density_calc_t) :: dens_calc
728
729 push_sub(density_calc)
730
731 assert(ubound(density, dim = 1) == gr%np .or. ubound(density, dim = 1) == gr%np_part)
732
733 if (st%requires_generalized_overlap .and. present(istin)) then
734 call messages_not_implemented("state-resolved density with ultrasoft/PAW augmentation density")
735 end if
736
737 call density_calc_init(dens_calc, st, gr, density, ep, vnl, phase)
738
739 if (.not. present(istin)) then
740 ! ordinary density accumulate
741 do ik = st%d%kpt%start, st%d%kpt%end
742 do ib = st%group%block_start, st%group%block_end
743 call density_calc_accumulate(dens_calc, st%group%psib(ib, ik), async=.true.)
744 end do
745 end do
746 call accel_finish()
747 else
748 ! state-resolved density
749 do ik = st%d%kpt%start, st%d%kpt%end
750 do ib = st%group%block_start, st%group%block_end
751 if (st%group%psib(ib, ik)%ist(1) <= istin .and. st%group%psib(ib, ik)%ist(st%group%psib(ib, ik)%nst) >= istin) then
752 call density_calc_state(dens_calc, st%group%psib(ib, ik), istin)
753 end if
754 end do
755 end do
756 end if
757
758 call density_calc_end(dens_calc, allreduce = .not. present(istin), buff_density = st%buff_density)
759
760 pop_sub(density_calc)
761 end subroutine density_calc
762
763 ! ---------------------------------------------------------
765 subroutine states_elec_freeze_orbitals(st, namespace, space, gr, mc, kpoints, n, family_is_mgga)
766 type(states_elec_t), intent(inout) :: st
767 type(namespace_t), intent(in) :: namespace
768 class(space_t), intent(in) :: space
769 type(grid_t), intent(in) :: gr
770 type(multicomm_t), intent(in) :: mc
771 type(kpoints_t), intent(in) :: kpoints
772 integer, intent(in) :: n
773 logical, intent(in) :: family_is_mgga
774
775 integer :: ist, ik, ib, nblock
776 integer :: nodeto, nodefr
777 type(states_elec_t) :: staux
778 complex(real64), allocatable :: psi(:, :, :), rec_buffer(:,:)
779 type(wfs_elec_t) :: psib
780 type(density_calc_t) :: dens_calc
781
783
784 if (st%requires_generalized_overlap) then
785 call messages_not_implemented("frozen-orbital density with ultrasoft/PAW augmentation density")
786 end if
787
788 if (n >= st%nst) then
789 write(message(1),'(a)') 'Attempting to freeze a number of orbitals which is larger or equal to'
790 write(message(2),'(a)') 'the total number. The program has to stop.'
791 call messages_fatal(2, namespace=namespace)
792 end if
793
794 assert(states_are_complex(st))
795
796 if (.not. allocated(st%frozen_rho)) then
797 safe_allocate(st%frozen_rho(1:gr%np, 1:st%d%nspin))
798 end if
799
800 call density_calc_init(dens_calc, st, gr, st%frozen_rho)
801
802 do ik = st%d%kpt%start, st%d%kpt%end
803 if (n < st%st_start) cycle
804
805 do ib = st%group%block_start, st%group%block_end
806 !We can use the full batch
807 if (states_elec_block_max(st, ib) <= n) then
808
809 call density_calc_accumulate(dens_calc, st%group%psib(ib, ik))
810 if (states_elec_block_max(st, ib) == n) exit
811
812 else !Here we only use a part of this batch
813
814 nblock = n - states_elec_block_min(st, ib) + 1
815
816 safe_allocate(psi(1:gr%np, 1:st%d%dim, 1:nblock))
817
818 do ist = 1, nblock
819 call states_elec_get_state(st, gr, states_elec_block_min(st, ib) + ist - 1, ik, psi(:, :, ist))
820 end do
821
822 call wfs_elec_init(psib, st%d%dim, states_elec_block_min(st, ib), n, psi, ik)
823 call density_calc_accumulate(dens_calc, psib)
824 call psib%end()
825 safe_deallocate_a(psi)
826
827 exit
828
829 end if
830
831 end do
832 end do
833
834 call density_calc_end(dens_calc)
835
836 if (family_is_mgga) then
837 if (.not. allocated(st%frozen_tau)) then
838 safe_allocate(st%frozen_tau(1:gr%np, 1:st%d%nspin))
839 end if
840 if (.not. allocated(st%frozen_gdens)) then
841 safe_allocate(st%frozen_gdens(1:gr%np, 1:space%dim, 1:st%d%nspin))
842 end if
843 if (.not. allocated(st%frozen_ldens)) then
844 safe_allocate(st%frozen_ldens(1:gr%np, 1:st%d%nspin))
845 end if
846
847 call states_elec_calc_quantities(gr, st, kpoints, .true., kinetic_energy_density = st%frozen_tau, &
848 density_gradient = st%frozen_gdens, density_laplacian = st%frozen_ldens, st_end = n)
849 end if
850
851
852 call states_elec_copy(staux, st)
853
854 call states_elec_freeze_redistribute_states(st, namespace, gr, mc, n)
855
856 safe_allocate(psi(1:gr%np, 1:st%d%dim, 1))
857 safe_allocate(rec_buffer(1:gr%np, 1:st%d%dim))
859 do ik = st%d%kpt%start, st%d%kpt%end
860 ! loop over all frozen states
861 do ist = 1, st%nst
862 ! new distribution: frozen states
863 nodeto = st%node(ist)
864 ! old distribution: full states
865 nodefr = staux%node(ist+n)
866
867 if (st%mpi_grp%rank == nodeto .and. st%mpi_grp%rank == nodefr) then
868 ! do a simple copy on the same rank, also for serial version
869 call states_elec_get_state(staux, gr, ist+n, ik, psi(:, :, 1))
870 call states_elec_set_state(st, gr, ist, ik, psi(:, :, 1))
871 else
872 ! we can use blocking send/recv calls here because we always have different ranks
873 if (st%mpi_grp%rank == nodefr) then
874 call states_elec_get_state(staux, gr, ist+n, ik, psi(:, :, 1))
875 call st%mpi_grp%send(psi(1, 1, 1), gr%np*st%d%dim, mpi_double_complex, nodeto, ist)
876 end if
877 if (st%mpi_grp%rank == nodeto) then
878 call st%mpi_grp%recv(rec_buffer(1, 1), gr%np*st%d%dim, mpi_double_complex, nodefr, ist)
879 call states_elec_set_state(st, gr, ist, ik, rec_buffer(:, :))
880 end if
881 end if
882 end do
883 end do
884
885 safe_deallocate_a(psi)
886 safe_deallocate_a(rec_buffer)
887
888 do ik = 1, st%nik
889 do ist = 1, st%nst
890 st%occ(ist, ik) = staux%occ(n+ist, ik)
891 st%eigenval(ist, ik) = staux%eigenval(n+ist, ik)
892 end do
893 end do
894
895 call states_elec_end(staux)
897 end subroutine states_elec_freeze_orbitals
898
899 ! ---------------------------------------------------------
900 subroutine states_elec_freeze_redistribute_states(st, namespace, mesh, mc, nn)
901 type(states_elec_t), intent(inout) :: st
902 type(namespace_t), intent(in) :: namespace
903 class(mesh_t), intent(in) :: mesh
904 type(multicomm_t), intent(in) :: mc
905 integer, intent(in) :: nn
906
908
909 st%nst = st%nst - nn
910
912 call states_elec_distribute_nodes(st, namespace, mc)
913 call states_elec_allocate_wfns(st, mesh, type_cmplx, packed=.true.)
914
915 safe_deallocate_a(st%eigenval)
916 safe_allocate(st%eigenval(1:st%nst, 1:st%nik))
917 st%eigenval = huge(st%eigenval)
918
919 safe_deallocate_a(st%occ)
920 safe_allocate(st%occ (1:st%nst, 1:st%nik))
921 st%occ = m_zero
922
923
926
927 ! ---------------------------------------------------------
928 subroutine states_elec_freeze_adjust_qtot(st)
929 type(states_elec_t), intent(inout) :: st
930
931 integer :: ik, ist
932
934
935 ! Change the smearing method by fixing the occupations to
936 ! that of the ground-state such that the unfrozen states inherit
937 ! those values.
938 st%smear%method = smear_fixed_occ
939
940 ! Set total charge
941 st%qtot = m_zero
942 do ik = st%d%kpt%start, st%d%kpt%end
943 do ist = st%st_start, st%st_end
944 st%qtot = st%qtot + st%occ(ist, ik) * st%kweights(ik)
945 end do
946 end do
947
948 if (st%parallel_in_states .or. st%d%kpt%parallel) then
949 call comm_allreduce(st%st_kpt_mpi_grp, st%qtot)
950 end if
951
952
954 end subroutine states_elec_freeze_adjust_qtot
955
956
957 ! ---------------------------------------------------------
966 !
967 subroutine states_elec_total_density(st, mesh, total_rho)
968 type(states_elec_t), intent(in) :: st
969 class(mesh_t), intent(in) :: mesh
970 real(real64), contiguous, intent(out) :: total_rho(:,:)
971
972 integer :: is
973
975
976 call lalg_copy(mesh%np, st%d%nspin, st%rho, total_rho)
977
978 if (allocated(st%rho_core)) then
979 do is = 1, st%d%spin_channels
980 call lalg_axpy(mesh%np, m_one/st%d%spin_channels, st%rho_core, total_rho(:, is))
981 end do
982 end if
983
984 ! Add, if it exists, the frozen density from the inner orbitals.
985 if (allocated(st%frozen_rho)) then
986 call lalg_axpy(mesh%np, st%d%nspin, m_one, st%frozen_rho, total_rho)
987 end if
988
990 end subroutine states_elec_total_density
991
992 ! ---------------------------------------------------------
995 subroutine states_elec_sync_buff_density(st, mesh)
996 type(states_elec_t), intent(inout) :: st
997 class(mesh_t), intent(in) :: mesh
998
999 integer :: is
1000 integer(int64) :: pnp
1001
1003
1004 if (accel_is_enabled() .and. st%buff_density%allocated) then
1005 pnp = accel_padded_size(mesh%np)
1006 do is = 1, st%d%nspin
1007 call accel_write_buffer(st%buff_density, int(mesh%np, int64), st%rho(1:mesh%np, is), &
1008 offset = (is - 1)*pnp)
1009 end do
1010 end if
1011
1013 end subroutine states_elec_sync_buff_density
1014
1015#include "undef.F90"
1016#include "real.F90"
1017#include "density_inc.F90"
1018
1019#include "undef.F90"
1020#include "complex.F90"
1021#include "density_inc.F90"
1022
1023end module density_oct_m
1024
1025
1026!! Local Variables:
1027!! mode: f90
1028!! coding: utf-8
1029!! End:
constant times a vector plus a vector
Definition: lalg_basic.F90:192
Copies a vector x, to a vector y.
Definition: lalg_basic.F90:218
type(accel_kernel_t), target, save, public kernel_density_real
Definition: accel.F90:270
integer function, public accel_kernel_block_size(kernel)
Definition: accel.F90:1215
subroutine, public accel_free_buffer(this, async)
Definition: accel.F90:988
subroutine, public accel_finish()
Definition: accel.F90:1125
subroutine, public accel_move_buffer(buffer_from, buffer_to)
Move the buffer memory from the first buffer to the second.
Definition: accel.F90:1031
type(accel_kernel_t), target, save, public kernel_density_spinors
Definition: accel.F90:272
integer, parameter, public accel_mem_read_write
Definition: accel.F90:183
pure logical function, public accel_is_enabled()
Definition: accel.F90:412
type(accel_kernel_t), target, save, public kernel_density_complex
Definition: accel.F90:271
integer, parameter, public accel_mem_read_only
Definition: accel.F90:183
This module implements batches of mesh functions.
Definition: batch.F90:133
integer, parameter, public batch_not_packed
functions are stored in CPU memory, unpacked order
Definition: batch.F90:309
integer, parameter, public batch_device_packed
functions are stored in device memory in packed order
Definition: batch.F90:309
integer, parameter, public batch_packed
functions are stored in CPU memory, in transposed (packed) order
Definition: batch.F90:309
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:116
This module implements a calculator for the density and defines related functions.
Definition: density.F90:120
subroutine density_calc_state(this, psib, istin)
Calculate contribution to the density from state istin.
Definition: density.F90:271
subroutine, public density_calc_accumulate(this, psib, async)
Accumulate weighted orbital densities for a batch psib.
Definition: density.F90:426
subroutine, public states_elec_freeze_adjust_qtot(st)
Definition: density.F90:1022
subroutine, public states_elec_freeze_redistribute_states(st, namespace, mesh, mc, nn)
Definition: density.F90:994
subroutine, public density_calc(st, gr, density, istin, ep, vnl, phase)
Computes the density from the orbitals in st.
Definition: density.F90:811
subroutine density_calc_pack(this, async)
prepare the density calculator for GPU use
Definition: density.F90:250
subroutine, public states_elec_sync_buff_density(st, mesh)
Synchronize the GPU density buffer with the host density strho.
Definition: density.F90:1089
subroutine, public ddensity_accumulate_grad(space, mesh, st, psib, grad_psib, grad_rho)
Accumulate within a batch.
Definition: density.F90:1179
subroutine, public zdensity_accumulate_grad(space, mesh, st, psib, grad_psib, grad_rho)
Accumulate within a batch.
Definition: density.F90:1369
subroutine density_calc_accumulate_uspp(this, psib, ispin, weight)
Accumulate the real-space USPP augmentation density for one wavefunction batch.
Definition: density.F90:598
subroutine, public states_elec_total_density(st, mesh, total_rho)
This routine calculates the total electronic density.
Definition: density.F90:1061
subroutine, public density_calc_end(this, allreduce, symmetrize, buff_density)
Finalize the density calculation.
Definition: density.F90:728
subroutine, public states_elec_freeze_orbitals(st, namespace, space, gr, mc, kpoints, n, family_is_mgga)
Calculate partial density for frozen orbitals.
Definition: density.F90:859
subroutine, public density_calc_init(this, st, gr, density, ep, vnl, phase)
initialize the density calculator
Definition: density.F90:198
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
integer, parameter, public unpolarized
Parameters...
integer, parameter, public spinors
integer, parameter, public spin_polarized
real(real64), parameter, public m_zero
Definition: global.F90:198
real(real64), parameter, public m_epsilon
Definition: global.F90:214
real(real64), parameter, public m_one
Definition: global.F90:199
This module implements the underlying real-space grid.
Definition: grid.F90:117
subroutine, public dgrid_symmetrize_scalar_field(gr, field, suppress_warning)
Definition: grid.F90:680
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
subroutine, public ylmr_real(xx, li, mi, ylm)
This is a Numerical Recipes-based subroutine computes real spherical harmonics ylm at position (x,...
Definition: math.F90:384
real(real64) function, public real_gaunt(l1, m1, l2, m2, l3, m3)
Real Gaunt coefficient , by quadrature.
Definition: math.F90:533
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1066
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:408
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:145
subroutine, public znonlocal_pseudopotential_density_matrix(this, mesh, std, spiral_bnd, psib, weight, beta_density)
Accumulate occupation-weighted beta-projector density matrices for USPP density.
subroutine, public dnonlocal_pseudopotential_density_matrix(this, mesh, std, spiral_bnd, psib, weight, beta_density)
Accumulate occupation-weighted beta-projector density matrices for USPP density.
/* To use the profiling module, call profiling_in and profiling_out with the label of the region as a...
Definition: profiling.F90:143
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:693
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:625
logical elemental function, public projector_is(p, type)
Definition: projector.F90:215
Definition: ps.F90:114
integer, parameter, public proj_uspp
Definition: ps.F90:171
integer, parameter, public smear_fixed_occ
Definition: smear.F90:174
pure logical function, public states_are_complex(st)
pure logical function, public states_are_real(st)
This module handles spin dimensions of the states and the k-point distribution.
integer pure function, public states_elec_block_max(st, ib)
return index of last state in block ib
subroutine, public states_elec_distribute_nodes(st, namespace, mc)
Distribute states over the processes for states parallelization.
subroutine, public states_elec_calc_quantities(gr, st, kpoints, nlcc, kinetic_energy_density, paramagnetic_current, density_gradient, density_laplacian, gi_kinetic_energy_density, st_end)
calculated selected quantities
subroutine, public states_elec_end(st)
finalize the states_elec_t object
subroutine, public states_elec_deallocate_wfns(st)
Deallocates the KS wavefunctions defined within a states_elec_t structure.
subroutine, public states_elec_allocate_wfns(st, mesh, wfs_type, skip, packed)
Allocates the KS wavefunctions defined within a states_elec_t structure.
subroutine, public states_elec_copy(stout, stin, exclude_wfns, exclude_eigenval, special, dest_type, copy_data)
make a (selective) copy of a states_elec_t object
integer pure function, public states_elec_block_min(st, ib)
return index of first state in block ib
type(type_t), parameter, public type_cmplx
Definition: types.F90:135
type(type_t), parameter, public type_float
Definition: types.F90:134
The calculator object.
Definition: density.F90:176
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:169
Describes mesh distribution to nodes.
Definition: mesh.F90:186
Stores all communicators and groups.
Definition: multicomm.F90:206
A container for the phase.
Definition: phase.F90:179
A set of projectors defined on a submesh.
The projector data type is intended to hold the local and non-local parts of the pseudopotentials....
Definition: projector.F90:179
The states_elec_t class contains all electronic wave functions.
batches of electronic states
Definition: wfs_elec.F90:141
int true(void)