38 use,
intrinsic :: iso_fortran_env
78 real(real64),
contiguous,
pointer :: density(:, :)
80 type(states_elec_t),
pointer :: st
81 type(grid_t),
pointer :: gr
82 type(accel_mem_t) :: buff_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(:, :)
101 logical :: correct_size
108 this%density => density
110 do ispin = 1, st%d%nspin
113 this%density(ip, ispin) =
m_zero
119 this%packed = .false.
121 correct_size = ubound(this%density, dim = 1) == this%gr%np .or. &
122 ubound(this%density, dim = 1) == this%gr%np_part
132 type(density_calc_t),
intent(inout) :: this
133 logical,
optional,
intent(in) :: async
153 type(density_calc_t),
intent(inout) :: this
154 type(wfs_elec_t),
intent(in) :: psib
155 integer,
intent(in) :: istin
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
166 ispin = this%st%d%get_spin_index(psib%ik)
170 safe_allocate(weight(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
188 select case (psib%status())
190 select case (this%st%d%ispin)
194 do ip = 1, this%gr%np
195 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff(ip, 1, ist)**2
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)
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)
219 select case (this%st%d%ispin)
223 do ip = 1, this%gr%np
224 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff_pack(ist, ip)**2
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)
235 assert(mod(psib%nst_linear, 2) == 0)
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)
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)
255 select case (this%st%d%ispin)
293 safe_deallocate_a(weight)
306 logical,
optional,
intent(in) :: async
308 integer :: ist, ip, ispin, bsize, gsize
309 complex(real64) :: term, psi1, psi2
310 real(real64),
allocatable :: weight(:)
317 ispin = this%st%d%get_spin_index(psib%ik)
319 safe_allocate(weight(1:psib%nst))
321 weight(ist) = this%st%kweights(psib%ik)*this%st%occ(psib%ist(ist), psib%ik)
324 select case (psib%status())
326 select case (this%st%d%ispin)
332 do ip = 1, this%gr%np
333 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff(ip, 1, ist)**2
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)
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)
364 select case (this%st%d%ispin)
368 do ip = 1, this%gr%np
370 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff_pack(ist, ip)**2
375 do ip = 1, this%gr%np
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)
383 assert(mod(psib%nst_linear, 2) == 0)
385 do ip = 1, this%gr%np
387 psi1 = psib%zff_pack(2*ist - 1, ip)
388 psi2 = psib%zff_pack(2*ist, ip)
389 term = weight(ist)*psi1*conjg(psi2)
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)
405 select case (this%st%d%ispin)
445 safe_deallocate_a(weight)
448 if (this%st%d%ispin /=
spinors)
then
474 logical,
optional,
intent(in) :: allreduce
475 logical,
optional,
intent(in) :: symmetrize
478 real(real64),
allocatable :: tmpdensity(:)
482 if (this%packed)
then
483 safe_allocate(tmpdensity(1:this%gr%np))
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)
490 do ip = 1, this%gr%np
491 this%density(ip, ispin) = this%density(ip, ispin) + tmpdensity(ip)
495 this%packed = .false.
497 safe_deallocate_a(tmpdensity)
501 if ((this%st%parallel_in_states .or. this%st%d%kpt%parallel) .and.
optional_default(allreduce, .
true.))
then
503 call comm_allreduce(this%st%st_kpt_mpi_grp, this%density, dim = (/this%gr%np, this%st%d%nspin/))
508 do ispin = 1, this%st%d%nspin
525 type(
grid_t),
intent(in) :: gr
526 real(real64),
contiguous,
intent(out) :: density(:, :)
527 integer,
optional,
intent(in) :: istin
534 assert(ubound(density, dim = 1) == gr%np .or. ubound(density, dim = 1) == gr%np_part)
538 if (.not.
present(istin))
then
540 do ik = st%d%kpt%start, st%d%kpt%end
541 do ib = st%group%block_start, st%group%block_end
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
569 class(
space_t),
intent(in) :: space
570 type(
grid_t),
intent(in) :: gr
573 integer,
intent(in) :: n
574 logical,
intent(in) :: family_is_mgga
576 integer :: ist, ik, ib, nblock
577 integer :: nodeto, nodefr
579 complex(real64),
allocatable :: psi(:, :, :), rec_buffer(:,:)
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.'
593 if (.not.
allocated(st%frozen_rho))
then
594 safe_allocate(st%frozen_rho(1:gr%np, 1:st%d%nspin))
599 do ik = st%d%kpt%start, st%d%kpt%end
600 if (n < st%st_start) cycle
602 do ib = st%group%block_start, st%group%block_end
613 safe_allocate(psi(1:gr%np, 1:st%d%dim, 1:nblock))
622 safe_deallocate_a(psi)
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))
637 if (.not.
allocated(st%frozen_gdens))
then
638 safe_allocate(st%frozen_gdens(1:gr%np, 1:space%dim, 1:st%d%nspin))
640 if (.not.
allocated(st%frozen_ldens))
then
641 safe_allocate(st%frozen_ldens(1:gr%np, 1:st%d%nspin))
645 density_gradient = st%frozen_gdens, density_laplacian = st%frozen_ldens, st_end = n)
653 safe_allocate(psi(1:gr%np, 1:st%d%dim, 1))
654 safe_allocate(rec_buffer(1:gr%np, 1:st%d%dim))
656 do ik = st%d%kpt%start, st%d%kpt%end
660 nodeto = st%node(ist)
662 nodefr = staux%node(ist+n)
664 if (st%mpi_grp%rank == nodeto .and. st%mpi_grp%rank == nodefr)
then
670 if (st%mpi_grp%rank == nodefr)
then
672 call st%mpi_grp%send(psi(1, 1, 1), gr%np*st%d%dim, mpi_double_complex, nodeto, ist)
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)
682 safe_deallocate_a(psi)
683 safe_deallocate_a(rec_buffer)
687 st%occ(ist, ik) = staux%occ(n+ist, ik)
688 st%eigenval(ist, ik) = staux%eigenval(n+ist, ik)
700 class(
mesh_t),
intent(in) :: mesh
702 integer,
intent(in) :: nn
712 safe_deallocate_a(st%eigenval)
713 safe_allocate(st%eigenval(1:st%nst, 1:st%nik))
714 st%eigenval = huge(st%eigenval)
716 safe_deallocate_a(st%occ)
717 safe_allocate(st%occ (1:st%nst, 1:st%nik))
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)
745 if (st%parallel_in_states .or. st%d%kpt%parallel)
then
766 class(
mesh_t),
intent(in) :: mesh
767 real(real64),
contiguous,
intent(out) :: total_rho(:,:)
773 call lalg_copy(mesh%np, st%d%nspin, st%rho, total_rho)
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))
782 if (
allocated(st%frozen_rho))
then
783 call lalg_axpy(mesh%np, st%d%nspin,
m_one, st%frozen_rho, total_rho)
791#include "density_inc.F90"
794#include "complex.F90"
795#include "density_inc.F90"
constant times a vector plus a vector
Copies a vector x, to a vector y.
type(accel_kernel_t), target, save, public kernel_density_real
integer function, public accel_kernel_block_size(kernel)
subroutine, public accel_free_buffer(this, async)
subroutine, public accel_finish()
type(accel_kernel_t), target, save, public kernel_density_spinors
integer, parameter, public accel_mem_read_write
type(accel_kernel_t), target, save, public kernel_density_complex
integer, parameter, public accel_mem_read_only
This module implements batches of mesh functions.
integer, parameter, public batch_not_packed
functions are stored in CPU memory, unpacked order
integer, parameter, public batch_device_packed
functions are stored in device memory in packed order
integer, parameter, public batch_packed
functions are stored in CPU memory, in transposed (packed) order
This module implements common operations on batches of mesh functions.
This module implements a calculator for the density and defines related functions.
subroutine, public density_calc_end(this, allreduce, symmetrize)
Finalize the density calculation.
subroutine density_calc_state(this, psib, istin)
Calculate contribution to the density from state istin.
subroutine, public density_calc_accumulate(this, psib, async)
Accumulate weighted orbital densities for a batch psib.
subroutine, public states_elec_freeze_adjust_qtot(st)
subroutine, public states_elec_freeze_redistribute_states(st, namespace, mesh, mc, nn)
subroutine, public density_calc_init(this, st, gr, density)
initialize the density calculator
subroutine density_calc_pack(this, async)
prepare the density calculator for GPU use
subroutine, public ddensity_accumulate_grad(space, mesh, st, psib, grad_psib, grad_rho)
Accumulate within a batch.
subroutine, public zdensity_accumulate_grad(space, mesh, st, psib, grad_psib, grad_rho)
Accumulate within a batch.
subroutine, public states_elec_total_density(st, mesh, total_rho)
This routine calculates the total electronic density.
subroutine, public states_elec_freeze_orbitals(st, namespace, space, gr, mc, kpoints, n, family_is_mgga)
Calculate partial density for frozen orbitals.
subroutine, public density_calc(st, gr, density, istin)
Computes the density from the orbitals in st.
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
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
subroutine, public dgrid_symmetrize_scalar_field(gr, field, suppress_warning)
This module is intended to contain "only mathematical" functions and procedures.
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
This module handles the communicators for the various parallelization strategies.
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
integer, parameter, public smear_fixed_occ
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
type(type_t), public type_cmplx
Description of the grid, containing information on derivatives, stencil, and symmetries.
Describes mesh distribution to nodes.
Stores all communicators and groups.
The states_elec_t class contains all electronic wave functions.
batches of electronic states