38 use,
intrinsic :: iso_fortran_env
78 real(real64),
pointer :: density(:, :)
79 type(states_elec_t),
pointer :: st
80 type(grid_t),
pointer :: gr
81 type(accel_mem_t) :: buff_density
94 type(density_calc_t),
intent(out) :: this
95 type(states_elec_t),
target,
intent(in) :: st
96 type(grid_t),
target,
intent(in) :: gr
97 real(real64),
target,
intent(out) :: density(:, :)
100 logical :: correct_size
107 this%density => density
109 do ispin = 1, st%d%nspin
112 this%density(ip, ispin) =
m_zero
118 this%packed = .false.
120 correct_size = ubound(this%density, dim = 1) == this%gr%np .or. &
121 ubound(this%density, dim = 1) == this%gr%np_part
131 type(density_calc_t),
intent(inout) :: this
132 logical,
optional,
intent(in) :: async
152 type(density_calc_t),
intent(inout) :: this
153 type(wfs_elec_t),
intent(in) :: psib
154 integer,
intent(in) :: istin
156 integer :: ist, ip, ispin, istin_, wgsize
157 complex(real64) :: term, psi1, psi2
158 real(real64),
allocatable :: weight(:)
159 type(accel_mem_t) :: buff_weight
160 type(accel_kernel_t),
pointer :: kernel
165 ispin = this%st%d%get_spin_index(psib%ik)
169 safe_allocate(weight(1:psib%nst))
171 weight(ist) = this%st%kweights(psib%ik)*this%st%occ(psib%ist(ist), psib%ik)
172 if (psib%ist(ist) == istin) istin_ = ist
184 select case (psib%status())
186 select case (this%st%d%ispin)
190 do ip = 1, this%gr%np
191 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff(ip, 1, ist)**2
195 do ip = 1, this%gr%np
196 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
197 real(conjg(psib%zff(ip, 1, ist))*psib%zff(ip, 1, ist), real64)
202 do ip = 1, this%gr%np
203 psi1 = psib%zff(ip, 1, ist)
204 psi2 = psib%zff(ip, 2, ist)
205 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
206 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
207 term = weight(ist)*psi1*conjg(psi2)
208 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
209 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
215 select case (this%st%d%ispin)
219 do ip = 1, this%gr%np
220 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff_pack(ist, ip)**2
225 do ip = 1, this%gr%np
226 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
227 real(conjg(psib%zff_pack(ist, ip))*psib%zff_pack(ist, ip), real64)
231 assert(mod(psib%nst_linear, 2) == 0)
233 do ip = 1, this%gr%np
234 psi1 = psib%zff_pack(2*ist - 1, ip)
235 psi2 = psib%zff_pack(2*ist, ip)
236 term = weight(ist)*psi1*conjg(psi2)
238 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
239 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
240 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
241 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
251 select case (this%st%d%ispin)
287 safe_deallocate_a(weight)
300 logical,
optional,
intent(in) :: async
302 integer :: ist, ip, ispin, wgsize
303 complex(real64) :: term, psi1, psi2
304 real(real64),
allocatable :: weight(:)
311 ispin = this%st%d%get_spin_index(psib%ik)
313 safe_allocate(weight(1:psib%nst))
315 weight(ist) = this%st%kweights(psib%ik)*this%st%occ(psib%ist(ist), psib%ik)
318 select case (psib%status())
320 select case (this%st%d%ispin)
326 do ip = 1, this%gr%np
327 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff(ip, 1, ist)**2
334 do ip = 1, this%gr%np
335 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
336 real(conjg(psib%zff(ip, 1, ist))*psib%zff(ip, 1, ist), real64)
344 do ip = 1, this%gr%np
345 psi1 = psib%zff(ip, 1, ist)
346 psi2 = psib%zff(ip, 2, ist)
347 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
348 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
349 term = weight(ist)*psi1*conjg(psi2)
350 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
351 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
358 select case (this%st%d%ispin)
362 do ip = 1, this%gr%np
364 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff_pack(ist, ip)**2
369 do ip = 1, this%gr%np
371 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
372 real(conjg(psib%zff_pack(ist, ip))*psib%zff_pack(ist, ip), real64)
377 assert(mod(psib%nst_linear, 2) == 0)
379 do ip = 1, this%gr%np
381 psi1 = psib%zff_pack(2*ist - 1, ip)
382 psi2 = psib%zff_pack(2*ist, ip)
383 term = weight(ist)*psi1*conjg(psi2)
385 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
386 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
387 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
388 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
399 select case (this%st%d%ispin)
437 safe_deallocate_a(weight)
440 if (this%st%d%ispin /=
spinors)
then
466 logical,
optional,
intent(in) :: allreduce
467 logical,
optional,
intent(in) :: symmetrize
470 real(real64),
allocatable :: tmpdensity(:)
474 if (this%packed)
then
475 safe_allocate(tmpdensity(1:this%gr%np))
478 do ispin = 1, this%st%d%nspin
479 call accel_read_buffer(this%buff_density, int(this%gr%np, int64), tmpdensity, offset = (ispin - 1)*this%pnp)
482 do ip = 1, this%gr%np
483 this%density(ip, ispin) = this%density(ip, ispin) + tmpdensity(ip)
487 this%packed = .false.
489 safe_deallocate_a(tmpdensity)
493 if ((this%st%parallel_in_states .or. this%st%d%kpt%parallel) .and.
optional_default(allreduce, .
true.))
then
495 call comm_allreduce(this%st%st_kpt_mpi_grp, this%density, dim = (/this%gr%np, this%st%d%nspin/))
500 do ispin = 1, this%st%d%nspin
517 type(
grid_t),
intent(in) :: gr
518 real(real64),
intent(out) :: density(:, :)
519 integer,
optional,
intent(in) :: istin
526 assert(ubound(density, dim = 1) == gr%np .or. ubound(density, dim = 1) == gr%np_part)
530 if (.not.
present(istin))
then
532 do ik = st%d%kpt%start, st%d%kpt%end
533 do ib = st%group%block_start, st%group%block_end
540 do ik = st%d%kpt%start, st%d%kpt%end
541 do ib = st%group%block_start, st%group%block_end
542 if (st%group%psib(ib, ik)%ist(1) <= istin .and. st%group%psib(ib, ik)%ist(st%group%psib(ib, ik)%nst) >= istin)
then
561 class(
space_t),
intent(in) :: space
562 type(
grid_t),
intent(in) :: gr
565 integer,
intent(in) :: n
566 logical,
intent(in) :: family_is_mgga
568 integer :: ist, ik, ib, nblock
569 integer :: nodeto, nodefr
571 complex(real64),
allocatable :: psi(:, :, :), rec_buffer(:,:)
577 if (n >= st%nst)
then
578 write(
message(1),
'(a)')
'Attempting to freeze a number of orbitals which is larger or equal to'
579 write(
message(2),
'(a)')
'the total number. The program has to stop.'
585 if (.not.
allocated(st%frozen_rho))
then
586 safe_allocate(st%frozen_rho(1:gr%np, 1:st%d%nspin))
591 do ik = st%d%kpt%start, st%d%kpt%end
592 if (n < st%st_start) cycle
594 do ib = st%group%block_start, st%group%block_end
605 safe_allocate(psi(1:gr%np, 1:st%d%dim, 1:nblock))
614 safe_deallocate_a(psi)
625 if (family_is_mgga)
then
626 if (.not.
allocated(st%frozen_tau))
then
627 safe_allocate(st%frozen_tau(1:gr%np, 1:st%d%nspin))
629 if (.not.
allocated(st%frozen_gdens))
then
630 safe_allocate(st%frozen_gdens(1:gr%np, 1:space%dim, 1:st%d%nspin))
632 if (.not.
allocated(st%frozen_ldens))
then
633 safe_allocate(st%frozen_ldens(1:gr%np, 1:st%d%nspin))
637 density_gradient = st%frozen_gdens, density_laplacian = st%frozen_ldens, st_end = n)
645 safe_allocate(psi(1:gr%np, 1:st%d%dim, 1))
646 safe_allocate(rec_buffer(1:gr%np, 1:st%d%dim))
648 do ik = st%d%kpt%start, st%d%kpt%end
652 nodeto = st%node(ist)
654 nodefr = staux%node(ist+n)
656 if (st%mpi_grp%rank == nodeto .and. st%mpi_grp%rank == nodefr)
then
662 if (st%mpi_grp%rank == nodefr)
then
664 call st%mpi_grp%send(psi(1, 1, 1), gr%np*st%d%dim, mpi_double_complex, nodeto, ist)
666 if (st%mpi_grp%rank == nodeto)
then
667 call st%mpi_grp%recv(rec_buffer(1, 1), gr%np*st%d%dim, mpi_double_complex, nodefr, ist)
674 safe_deallocate_a(psi)
675 safe_deallocate_a(rec_buffer)
679 st%occ(ist, ik) = staux%occ(n+ist, ik)
680 st%eigenval(ist, ik) = staux%eigenval(n+ist, ik)
692 class(
mesh_t),
intent(in) :: mesh
694 integer,
intent(in) :: nn
704 safe_deallocate_a(st%eigenval)
705 safe_allocate(st%eigenval(1:st%nst, 1:st%nik))
706 st%eigenval = huge(st%eigenval)
708 safe_deallocate_a(st%occ)
709 safe_allocate(st%occ (1:st%nst, 1:st%nik))
731 do ik = st%d%kpt%start, st%d%kpt%end
732 do ist = st%st_start, st%st_end
733 st%qtot = st%qtot + st%occ(ist, ik) * st%kweights(ik)
737 if (st%parallel_in_states .or. st%d%kpt%parallel)
then
758 class(
mesh_t),
intent(in) :: mesh
759 real(real64),
contiguous,
intent(out) :: total_rho(:,:)
765 call lalg_copy(mesh%np, st%d%nspin, st%rho, total_rho)
767 if (
allocated(st%rho_core))
then
768 do is = 1, st%d%spin_channels
769 call lalg_axpy(mesh%np,
m_one/st%d%spin_channels, st%rho_core, total_rho(:, is))
774 if (
allocated(st%frozen_rho))
then
775 call lalg_axpy(mesh%np, st%d%nspin,
m_one, st%frozen_rho, total_rho)
783#include "density_inc.F90"
786#include "complex.F90"
787#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
subroutine, public accel_finish()
type(accel_kernel_t), target, save, public kernel_density_spinors
integer, parameter, public accel_mem_read_write
subroutine, public accel_release_buffer(this)
type(accel_kernel_t), target, save, public kernel_density_complex
integer function, public accel_kernel_workgroup_size(kernel)
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