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 global_oct_m
37 use grid_oct_m
38 use, intrinsic :: iso_fortran_env
41 use math_oct_m
42 use mesh_oct_m
45 use mpi_oct_m
48 use parser_oct_m
50 use smear_oct_m
51 use space_oct_m
55 use types_oct_m
57
58 implicit none
59
60 private
61
62 public :: &
74
77 private
78 real(real64), contiguous, pointer :: density(:, :)
79 ! !! dimensions (1:np, 1:d%nspin)
80 type(states_elec_t), pointer :: st
81 type(grid_t), pointer :: gr
82 type(accel_mem_t) :: buff_density
83 integer(int64) :: pnp
84 logical :: packed
85 end type density_calc_t
86
87contains
88
93 !
94 subroutine density_calc_init(this, st, gr, density)
95 type(density_calc_t), intent(out) :: this
96 type(states_elec_t), target, intent(in) :: st
97 type(grid_t), target, intent(in) :: gr
98 real(real64), contiguous, target, intent(out) :: density(:, :)
99
100 integer :: ip, ispin
101 logical :: correct_size
102
103 push_sub(density_calc_init)
104
105 this%st => st
106 this%gr => gr
107
108 this%density => density
109 !$omp parallel private(ip)
110 do ispin = 1, st%d%nspin
111 !$omp do
112 do ip = 1, gr%np
113 this%density(ip, ispin) = m_zero
114 end do
115 !$omp end do nowait
116 end do
117 !$omp end parallel
118
119 this%packed = .false.
120
121 correct_size = ubound(this%density, dim = 1) == this%gr%np .or. &
122 ubound(this%density, dim = 1) == this%gr%np_part
123 assert(correct_size)
124
125 pop_sub(density_calc_init)
126 end subroutine density_calc_init
127
128 ! ---------------------------------------------------
130 !
131 subroutine density_calc_pack(this, async)
132 type(density_calc_t), intent(inout) :: this
133 logical, optional, intent(in) :: async
134
135 push_sub(density_calc_pack)
136
137 this%packed = .true.
138 this%pnp = accel_padded_size(this%gr%np)
139 call accel_create_buffer(this%buff_density, accel_mem_read_write, type_float, this%pnp*this%st%d%nspin)
140
141 ! set to zero
142 call accel_set_buffer_to_zero(this%buff_density, type_float, this%pnp*this%st%d%nspin, async=async)
143
144 pop_sub(density_calc_pack)
145 end subroutine density_calc_pack
146
147 ! ---------------------------------------------------
151 !
152 subroutine density_calc_state(this, psib, istin)
153 type(density_calc_t), intent(inout) :: this
154 type(wfs_elec_t), intent(in) :: psib
155 integer, intent(in) :: istin
156
157 integer :: ist, ip, ispin, istin_, bsize, gsize
158 complex(real64) :: term, psi1, psi2
159 real(real64), allocatable :: weight(:)
160 type(accel_mem_t) :: buff_weight
161 type(accel_kernel_t), pointer :: kernel
162
163 push_sub(density_calc_state)
164 call profiling_in("CALC_STATE_DENSITY")
165
166 ispin = this%st%d%get_spin_index(psib%ik)
167
168 istin_= 0
169
170 safe_allocate(weight(1:psib%nst))
171 do ist = 1, psib%nst
172 weight(ist) = this%st%kweights(psib%ik)*this%st%occ(psib%ist(ist), psib%ik)
173 if (psib%ist(ist) == istin) istin_ = ist
174 end do
176 assert(istin_ > 0)
178 if (abs(weight(istin_)) <= m_epsilon) then
179 call profiling_out("CALC_STATE_DENSITY")
180 pop_sub(density_calc_state)
181 return
182 end if
183
184 !fix ist for the remaining code
185 ist = istin_
186
187
188 select case (psib%status())
190 select case (this%st%d%ispin)
192 if (states_are_real(this%st)) then
193 !$omp parallel do simd schedule(static)
194 do ip = 1, this%gr%np
195 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff(ip, 1, ist)**2
196 end do
197 else
198 !$omp parallel do schedule(static)
199 do ip = 1, this%gr%np
200 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
201 real(conjg(psib%zff(ip, 1, ist))*psib%zff(ip, 1, ist), real64)
202 end do
203 end if
204 case (spinors)
205 !$omp parallel do schedule(static) private(psi1, psi2, term)
206 do ip = 1, this%gr%np
207 psi1 = psib%zff(ip, 1, ist)
208 psi2 = psib%zff(ip, 2, ist)
209 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
210 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
211 term = weight(ist)*psi1*conjg(psi2)
212 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
213 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
214 end do
215 end select
216
217 case (batch_packed)
218
219 select case (this%st%d%ispin)
221 if (states_are_real(this%st)) then
222 !$omp parallel do schedule(static)
223 do ip = 1, this%gr%np
224 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff_pack(ist, ip)**2
225 end do
226 else
227
228 !$omp parallel do schedule(static)
229 do ip = 1, this%gr%np
230 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
231 real(conjg(psib%zff_pack(ist, ip))*psib%zff_pack(ist, ip), real64)
232 end do
233 end if
234 case (spinors)
235 assert(mod(psib%nst_linear, 2) == 0)
236 !$omp parallel do schedule(static) private(psi1, psi2, term)
237 do ip = 1, this%gr%np
238 psi1 = psib%zff_pack(2*ist - 1, ip)
239 psi2 = psib%zff_pack(2*ist, ip)
240 term = weight(ist)*psi1*conjg(psi2)
241
242 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
243 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
244 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
245 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
246 end do
247 end select
248
250 if (.not. this%packed) call density_calc_pack(this, async=.true.)
251
252 call accel_create_buffer(buff_weight, accel_mem_read_only, type_float, psib%nst)
253 call accel_write_buffer(buff_weight, psib%nst, weight, async=.true.)
254
255 select case (this%st%d%ispin)
257 if (states_are_real(this%st)) then
258 kernel => kernel_density_real
259 else
260 kernel => kernel_density_complex
261 end if
262
263 call accel_set_kernel_arg(kernel, 0, psib%nst)
264 call accel_set_kernel_arg(kernel, 1, this%gr%np)
265 call accel_set_kernel_arg(kernel, 2, int(this%pnp*(ispin - 1), int32))
266 call accel_set_kernel_arg(kernel, 3, buff_weight)
267 call accel_set_kernel_arg(kernel, 4, psib%ff_device)
268 call accel_set_kernel_arg(kernel, 5, int(log2(psib%pack_size(1)), int32))
269 call accel_set_kernel_arg(kernel, 6, this%buff_density)
270
271 case (spinors)
272 kernel => kernel_density_spinors
273
274 call accel_set_kernel_arg(kernel, 0, psib%nst)
275 call accel_set_kernel_arg(kernel, 1, this%gr%np)
276 call accel_set_kernel_arg(kernel, 2, int(this%pnp, int32))
277 call accel_set_kernel_arg(kernel, 3, buff_weight)
278 call accel_set_kernel_arg(kernel, 4, psib%ff_device)
279 call accel_set_kernel_arg(kernel, 5, int(log2(psib%pack_size(1)), int32))
280 call accel_set_kernel_arg(kernel, 6, this%buff_density)
281 end select
282
283 ! Compute the grid
284 bsize = accel_kernel_block_size(kernel)
285 call accel_grid_size(this%gr%np, bsize, gsize)
286
287 call accel_kernel_run(kernel, (/gsize/), (/bsize/))
288
289 call accel_finish()
290 call accel_free_buffer(buff_weight)
291 end select
292
293 safe_deallocate_a(weight)
294
295 call profiling_out("CALC_STATE_DENSITY")
296
297 pop_sub(density_calc_state)
298 end subroutine density_calc_state
299
300 ! ---------------------------------------------------
302 !
303 subroutine density_calc_accumulate(this, psib, async)
304 type(density_calc_t), intent(inout) :: this
305 type(wfs_elec_t), intent(in) :: psib
306 logical, optional, intent(in) :: async
307
308 integer :: ist, ip, ispin, bsize, gsize
309 complex(real64) :: term, psi1, psi2
310 real(real64), allocatable :: weight(:)
311 type(accel_mem_t) :: buff_weight
312 type(accel_kernel_t), pointer :: kernel
313
315 call profiling_in("CALC_DENSITY")
316
317 ispin = this%st%d%get_spin_index(psib%ik)
318
319 safe_allocate(weight(1:psib%nst))
320 do ist = 1, psib%nst
321 weight(ist) = this%st%kweights(psib%ik)*this%st%occ(psib%ist(ist), psib%ik)
322 end do
323
324 select case (psib%status())
325 case (batch_not_packed)
326 select case (this%st%d%ispin)
328 if (states_are_real(this%st)) then
329 do ist = 1, psib%nst
330 if (abs(weight(ist)) <= m_epsilon) cycle
331 !$omp parallel do simd schedule(static)
332 do ip = 1, this%gr%np
333 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff(ip, 1, ist)**2
334 end do
335 end do
336 else
337 do ist = 1, psib%nst
338 if (abs(weight(ist)) <= m_epsilon) cycle
339 !$omp parallel do schedule(static)
340 do ip = 1, this%gr%np
341 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
342 real(conjg(psib%zff(ip, 1, ist))*psib%zff(ip, 1, ist), real64)
343 end do
344 end do
345 end if
346 case (spinors)
347 do ist = 1, psib%nst
348 if (abs(weight(ist)) <= m_epsilon) cycle
349 !$omp parallel do schedule(static) private(psi1, psi2, term)
350 do ip = 1, this%gr%np
351 psi1 = psib%zff(ip, 1, ist)
352 psi2 = psib%zff(ip, 2, ist)
353 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
354 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
355 term = weight(ist)*psi1*conjg(psi2)
356 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
357 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
358 end do
359 end do
360 end select
361
362 case (batch_packed)
363
364 select case (this%st%d%ispin)
366 if (states_are_real(this%st)) then
367 !$omp parallel do schedule(static) private(ist)
368 do ip = 1, this%gr%np
369 do ist = 1, psib%nst
370 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff_pack(ist, ip)**2
371 end do
372 end do
373 else
374 !$omp parallel do schedule(static) private(ist)
375 do ip = 1, this%gr%np
376 do ist = 1, psib%nst
377 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
378 real(conjg(psib%zff_pack(ist, ip))*psib%zff_pack(ist, ip), real64)
379 end do
380 end do
381 end if
382 case (spinors)
383 assert(mod(psib%nst_linear, 2) == 0)
384 !$omp parallel do schedule(static) private(ist, psi1, psi2, term)
385 do ip = 1, this%gr%np
386 do ist = 1, psib%nst
387 psi1 = psib%zff_pack(2*ist - 1, ip)
388 psi2 = psib%zff_pack(2*ist, ip)
389 term = weight(ist)*psi1*conjg(psi2)
390
391 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
392 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
393 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
394 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
395 end do
396 end do
397 end select
400 if (.not. this%packed) call density_calc_pack(this)
401
402 call accel_create_buffer(buff_weight, accel_mem_read_only, type_float, psib%nst)
403 call accel_write_buffer(buff_weight, psib%nst, weight, async=.true.)
404
405 select case (this%st%d%ispin)
407 if (states_are_real(this%st)) then
408 kernel => kernel_density_real
409 else
410 kernel => kernel_density_complex
411 end if
412
413 call accel_set_kernel_arg(kernel, 0, psib%nst)
414 call accel_set_kernel_arg(kernel, 1, this%gr%np)
415 call accel_set_kernel_arg(kernel, 2, int(this%pnp, int32)*(ispin - 1))
416 call accel_set_kernel_arg(kernel, 3, buff_weight)
417 call accel_set_kernel_arg(kernel, 4, psib%ff_device)
418 call accel_set_kernel_arg(kernel, 5, int(log2(psib%pack_size(1)), int32))
419 call accel_set_kernel_arg(kernel, 6, this%buff_density)
420
421 case (spinors)
422 kernel => kernel_density_spinors
423
424 call accel_set_kernel_arg(kernel, 0, psib%nst)
425 call accel_set_kernel_arg(kernel, 1, this%gr%np)
426 call accel_set_kernel_arg(kernel, 2, int(this%pnp, int32))
427 call accel_set_kernel_arg(kernel, 3, buff_weight)
428 call accel_set_kernel_arg(kernel, 4, psib%ff_device)
429 call accel_set_kernel_arg(kernel, 5, int(log2(psib%pack_size(1)), int32))
430 call accel_set_kernel_arg(kernel, 6, this%buff_density)
431 end select
432
433 ! Compute the grid
434 bsize = accel_kernel_block_size(kernel)
435 call accel_grid_size(this%gr%np, bsize, gsize)
436
437 call accel_kernel_run(kernel, (/gsize/), (/bsize/))
438
439 call accel_free_buffer(buff_weight)
440
441 if(.not. optional_default(async, .false.)) call accel_finish()
442
443 end select
444
445 safe_deallocate_a(weight)
446
447
448 if (this%st%d%ispin /= spinors) then
449 if (states_are_real(this%st)) then
450 ! 1 add (1), 2 mult (1)
451 call profiling_count_operations(psib%nst*this%gr%np*(1 + 2))
452 else
453 ! 1 add (2), 1 complex mult (6), 1 real-complex mult (2)
454 call profiling_count_operations(psib%nst*this%gr%np*(2 + 6 + 2))
455 end if
456 else
457 ! 4 add (2), 3 complex mult (6), 3 real-complex mult (2)
458 call profiling_count_operations(psib%nst*this%gr%np*(4*2 + 3*6 + 3*2))
459 end if
460
461 call profiling_out("CALC_DENSITY")
462
464 end subroutine density_calc_accumulate
465
466 ! ---------------------------------------------------
471 !
472 subroutine density_calc_end(this, allreduce, symmetrize)
473 type(density_calc_t), intent(inout) :: this
474 logical, optional, intent(in) :: allreduce
475 logical, optional, intent(in) :: symmetrize
476
477 integer :: ispin, ip
478 real(real64), allocatable :: tmpdensity(:)
479
480 push_sub(density_calc_end)
481
482 if (this%packed) then
483 safe_allocate(tmpdensity(1:this%gr%np))
484
485 ! the density is in device memory
486 do ispin = 1, this%st%d%nspin
487 call accel_read_buffer(this%buff_density, int(this%gr%np, int64), tmpdensity, offset = (ispin - 1)*this%pnp)
488
489 !$omp parallel do simd
490 do ip = 1, this%gr%np
491 this%density(ip, ispin) = this%density(ip, ispin) + tmpdensity(ip)
492 end do
493 end do
494
495 this%packed = .false.
496 call accel_free_buffer(this%buff_density)
497 safe_deallocate_a(tmpdensity)
498 end if
499
500 ! reduce over states and k-points
501 if ((this%st%parallel_in_states .or. this%st%d%kpt%parallel) .and. optional_default(allreduce, .true.)) then
502 call profiling_in("DENSITY_REDUCE")
503 call comm_allreduce(this%st%st_kpt_mpi_grp, this%density, dim = (/this%gr%np, this%st%d%nspin/))
504 call profiling_out("DENSITY_REDUCE")
505 end if
506
507 if (this%st%symmetrize_density .and. optional_default(symmetrize, .true.)) then
508 do ispin = 1, this%st%d%nspin
509 call dgrid_symmetrize_scalar_field(this%gr, this%density(:, ispin))
510 end do
511 end if
512
513 pop_sub(density_calc_end)
514 end subroutine density_calc_end
515
516
517 ! ---------------------------------------------------------
522 !
523 subroutine density_calc(st, gr, density, istin)
524 type(states_elec_t), intent(in) :: st
525 type(grid_t), intent(in) :: gr
526 real(real64), contiguous,intent(out) :: density(:, :)
527 integer, optional, intent(in) :: istin
528
529 integer :: ik, ib
530 type(density_calc_t) :: dens_calc
531
532 push_sub(density_calc)
533
534 assert(ubound(density, dim = 1) == gr%np .or. ubound(density, dim = 1) == gr%np_part)
535
536 call density_calc_init(dens_calc, st, gr, density)
537
538 if (.not. present(istin)) then
539 ! ordinary density accumulate
540 do ik = st%d%kpt%start, st%d%kpt%end
541 do ib = st%group%block_start, st%group%block_end
542 call density_calc_accumulate(dens_calc, st%group%psib(ib, ik), async=.true.)
543 end do
544 end do
545 call accel_finish()
546 else
547 ! state-resolved density
548 do ik = st%d%kpt%start, st%d%kpt%end
549 do ib = st%group%block_start, st%group%block_end
550 if (st%group%psib(ib, ik)%ist(1) <= istin .and. st%group%psib(ib, ik)%ist(st%group%psib(ib, ik)%nst) >= istin) then
551 call density_calc_state(dens_calc, st%group%psib(ib, ik), istin)
552 end if
553 end do
554 end do
555
556 end if
557
558
559 call density_calc_end(dens_calc, allreduce = .not. present(istin))
560
561 pop_sub(density_calc)
562 end subroutine density_calc
563
564 ! ---------------------------------------------------------
566 subroutine states_elec_freeze_orbitals(st, namespace, space, gr, mc, kpoints, n, family_is_mgga)
567 type(states_elec_t), intent(inout) :: st
568 type(namespace_t), intent(in) :: namespace
569 class(space_t), intent(in) :: space
570 type(grid_t), intent(in) :: gr
571 type(multicomm_t), intent(in) :: mc
572 type(kpoints_t), intent(in) :: kpoints
573 integer, intent(in) :: n
574 logical, intent(in) :: family_is_mgga
575
576 integer :: ist, ik, ib, nblock
577 integer :: nodeto, nodefr
578 type(states_elec_t) :: staux
579 complex(real64), allocatable :: psi(:, :, :), rec_buffer(:,:)
580 type(wfs_elec_t) :: psib
581 type(density_calc_t) :: dens_calc
582
584
585 if (n >= st%nst) then
586 write(message(1),'(a)') 'Attempting to freeze a number of orbitals which is larger or equal to'
587 write(message(2),'(a)') 'the total number. The program has to stop.'
588 call messages_fatal(2, namespace=namespace)
589 end if
590
591 assert(states_are_complex(st))
592
593 if (.not. allocated(st%frozen_rho)) then
594 safe_allocate(st%frozen_rho(1:gr%np, 1:st%d%nspin))
595 end if
596
597 call density_calc_init(dens_calc, st, gr, st%frozen_rho)
598
599 do ik = st%d%kpt%start, st%d%kpt%end
600 if (n < st%st_start) cycle
601
602 do ib = st%group%block_start, st%group%block_end
603 !We can use the full batch
604 if (states_elec_block_max(st, ib) <= n) then
605
606 call density_calc_accumulate(dens_calc, st%group%psib(ib, ik))
607 if (states_elec_block_max(st, ib) == n) exit
608
609 else !Here we only use a part of this batch
610
611 nblock = n - states_elec_block_min(st, ib) + 1
612
613 safe_allocate(psi(1:gr%np, 1:st%d%dim, 1:nblock))
614
615 do ist = 1, nblock
616 call states_elec_get_state(st, gr, states_elec_block_min(st, ib) + ist - 1, ik, psi(:, :, ist))
617 end do
619 call wfs_elec_init(psib, st%d%dim, states_elec_block_min(st, ib), n, psi, ik)
620 call density_calc_accumulate(dens_calc, psib)
621 call psib%end()
622 safe_deallocate_a(psi)
623
624 exit
625
626 end if
627
628 end do
629 end do
630
631 call density_calc_end(dens_calc)
632
633 if (family_is_mgga) then
634 if (.not. allocated(st%frozen_tau)) then
635 safe_allocate(st%frozen_tau(1:gr%np, 1:st%d%nspin))
636 end if
637 if (.not. allocated(st%frozen_gdens)) then
638 safe_allocate(st%frozen_gdens(1:gr%np, 1:space%dim, 1:st%d%nspin))
639 end if
640 if (.not. allocated(st%frozen_ldens)) then
641 safe_allocate(st%frozen_ldens(1:gr%np, 1:st%d%nspin))
642 end if
643
644 call states_elec_calc_quantities(gr, st, kpoints, .true., kinetic_energy_density = st%frozen_tau, &
645 density_gradient = st%frozen_gdens, density_laplacian = st%frozen_ldens, st_end = n)
646 end if
647
648
649 call states_elec_copy(staux, st)
650
651 call states_elec_freeze_redistribute_states(st, namespace, gr, mc, n)
652
653 safe_allocate(psi(1:gr%np, 1:st%d%dim, 1))
654 safe_allocate(rec_buffer(1:gr%np, 1:st%d%dim))
655
656 do ik = st%d%kpt%start, st%d%kpt%end
657 ! loop over all frozen states
658 do ist = 1, st%nst
659 ! new distribution: frozen states
660 nodeto = st%node(ist)
661 ! old distribution: full states
662 nodefr = staux%node(ist+n)
663
664 if (st%mpi_grp%rank == nodeto .and. st%mpi_grp%rank == nodefr) then
665 ! do a simple copy on the same rank, also for serial version
666 call states_elec_get_state(staux, gr, ist+n, ik, psi(:, :, 1))
667 call states_elec_set_state(st, gr, ist, ik, psi(:, :, 1))
668 else
669 ! we can use blocking send/recv calls here because we always have different ranks
670 if (st%mpi_grp%rank == nodefr) then
671 call states_elec_get_state(staux, gr, ist+n, ik, psi(:, :, 1))
672 call st%mpi_grp%send(psi(1, 1, 1), gr%np*st%d%dim, mpi_double_complex, nodeto, ist)
673 end if
674 if (st%mpi_grp%rank == nodeto) then
675 call st%mpi_grp%recv(rec_buffer(1, 1), gr%np*st%d%dim, mpi_double_complex, nodefr, ist)
676 call states_elec_set_state(st, gr, ist, ik, rec_buffer(:, :))
677 end if
678 end if
679 end do
680 end do
681
682 safe_deallocate_a(psi)
683 safe_deallocate_a(rec_buffer)
684
685 do ik = 1, st%nik
686 do ist = 1, st%nst
687 st%occ(ist, ik) = staux%occ(n+ist, ik)
688 st%eigenval(ist, ik) = staux%eigenval(n+ist, ik)
689 end do
690 end do
691
692 call states_elec_end(staux)
694 end subroutine states_elec_freeze_orbitals
695
696 ! ---------------------------------------------------------
697 subroutine states_elec_freeze_redistribute_states(st, namespace, mesh, mc, nn)
698 type(states_elec_t), intent(inout) :: st
699 type(namespace_t), intent(in) :: namespace
700 class(mesh_t), intent(in) :: mesh
701 type(multicomm_t), intent(in) :: mc
702 integer, intent(in) :: nn
703
705
706 st%nst = st%nst - nn
707
709 call states_elec_distribute_nodes(st, namespace, mc)
710 call states_elec_allocate_wfns(st, mesh, type_cmplx, packed=.true.)
711
712 safe_deallocate_a(st%eigenval)
713 safe_allocate(st%eigenval(1:st%nst, 1:st%nik))
714 st%eigenval = huge(st%eigenval)
715
716 safe_deallocate_a(st%occ)
717 safe_allocate(st%occ (1:st%nst, 1:st%nik))
718 st%occ = m_zero
719
720
723
724 ! ---------------------------------------------------------
725 subroutine states_elec_freeze_adjust_qtot(st)
726 type(states_elec_t), intent(inout) :: st
727
728 integer :: ik, ist
729
731
732 ! Change the smearing method by fixing the occupations to
733 ! that of the ground-state such that the unfrozen states inherit
734 ! those values.
735 st%smear%method = smear_fixed_occ
736
737 ! Set total charge
738 st%qtot = m_zero
739 do ik = st%d%kpt%start, st%d%kpt%end
740 do ist = st%st_start, st%st_end
741 st%qtot = st%qtot + st%occ(ist, ik) * st%kweights(ik)
742 end do
743 end do
744
745 if (st%parallel_in_states .or. st%d%kpt%parallel) then
746 call comm_allreduce(st%st_kpt_mpi_grp, st%qtot)
747 end if
748
749
751 end subroutine states_elec_freeze_adjust_qtot
752
753
754 ! ---------------------------------------------------------
763 !
764 subroutine states_elec_total_density(st, mesh, total_rho)
765 type(states_elec_t), intent(in) :: st
766 class(mesh_t), intent(in) :: mesh
767 real(real64), contiguous, intent(out) :: total_rho(:,:)
768
769 integer :: is
770
772
773 call lalg_copy(mesh%np, st%d%nspin, st%rho, total_rho)
774
775 if (allocated(st%rho_core)) then
776 do is = 1, st%d%spin_channels
777 call lalg_axpy(mesh%np, m_one/st%d%spin_channels, st%rho_core, total_rho(:, is))
778 end do
779 end if
780
781 ! Add, if it exists, the frozen density from the inner orbitals.
782 if (allocated(st%frozen_rho)) then
783 call lalg_axpy(mesh%np, st%d%nspin, m_one, st%frozen_rho, total_rho)
784 end if
785
787 end subroutine states_elec_total_density
788
789#include "undef.F90"
790#include "real.F90"
791#include "density_inc.F90"
793#include "undef.F90"
794#include "complex.F90"
795#include "density_inc.F90"
796
797end module density_oct_m
798
799
800!! Local Variables:
801!! mode: f90
802!! coding: utf-8
803!! End:
constant times a vector plus a vector
Definition: lalg_basic.F90:173
Copies a vector x, to a vector y.
Definition: lalg_basic.F90:188
type(accel_kernel_t), target, save, public kernel_density_real
Definition: accel.F90:271
integer function, public accel_kernel_block_size(kernel)
Definition: accel.F90:1188
subroutine, public accel_free_buffer(this, async)
Definition: accel.F90:1005
subroutine, public accel_finish()
Definition: accel.F90:1098
type(accel_kernel_t), target, save, public kernel_density_spinors
Definition: accel.F90:273
integer, parameter, public accel_mem_read_write
Definition: accel.F90:185
type(accel_kernel_t), target, save, public kernel_density_complex
Definition: accel.F90:272
integer, parameter, public accel_mem_read_only
Definition: accel.F90:185
This module implements batches of mesh functions.
Definition: batch.F90:135
integer, parameter, public batch_not_packed
functions are stored in CPU memory, unpacked order
Definition: batch.F90:286
integer, parameter, public batch_device_packed
functions are stored in device memory in packed order
Definition: batch.F90:286
integer, parameter, public batch_packed
functions are stored in CPU memory, in transposed (packed) order
Definition: batch.F90:286
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:118
This module implements a calculator for the density and defines related functions.
Definition: density.F90:122
subroutine, public density_calc_end(this, allreduce, symmetrize)
Finalize the density calculation.
Definition: density.F90:568
subroutine density_calc_state(this, psib, istin)
Calculate contribution to the density from state istin.
Definition: density.F90:248
subroutine, public density_calc_accumulate(this, psib, async)
Accumulate weighted orbital densities for a batch psib.
Definition: density.F90:399
subroutine, public states_elec_freeze_adjust_qtot(st)
Definition: density.F90:821
subroutine, public states_elec_freeze_redistribute_states(st, namespace, mesh, mc, nn)
Definition: density.F90:793
subroutine, public density_calc_init(this, st, gr, density)
initialize the density calculator
Definition: density.F90:190
subroutine density_calc_pack(this, async)
prepare the density calculator for GPU use
Definition: density.F90:227
subroutine, public ddensity_accumulate_grad(space, mesh, st, psib, grad_psib, grad_rho)
Accumulate within a batch.
Definition: density.F90:955
subroutine, public zdensity_accumulate_grad(space, mesh, st, psib, grad_psib, grad_rho)
Accumulate within a batch.
Definition: density.F90:1144
subroutine, public states_elec_total_density(st, mesh, total_rho)
This routine calculates the total electronic density.
Definition: density.F90:860
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:662
subroutine, public density_calc(st, gr, density, istin)
Computes the density from the orbitals in st.
Definition: density.F90:619
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:200
real(real64), parameter, public m_epsilon
Definition: global.F90:216
real(real64), parameter, public m_one
Definition: global.F90:201
This module implements the underlying real-space grid.
Definition: grid.F90:119
subroutine, public dgrid_symmetrize_scalar_field(gr, field, suppress_warning)
Definition: grid.F90:672
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
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
integer, parameter, public smear_fixed_occ
Definition: smear.F90:176
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)
@Brief. 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)
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), public type_float
Definition: types.F90:135
type(type_t), public type_cmplx
Definition: types.F90:136
The calculator object.
Definition: density.F90:171
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:171
Describes mesh distribution to nodes.
Definition: mesh.F90:187
Stores all communicators and groups.
Definition: multicomm.F90:208
The states_elec_t class contains all electronic wave functions.
batches of electronic states
Definition: wfs_elec.F90:141
int true(void)