38 use,
intrinsic :: iso_fortran_env
78 real(real64),
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),
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_, wgsize
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
185 select case (psib%status())
187 select case (this%st%d%ispin)
191 do ip = 1, this%gr%np
192 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff(ip, 1, ist)**2
196 do ip = 1, this%gr%np
197 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
198 real(conjg(psib%zff(ip, 1, ist))*psib%zff(ip, 1, ist), real64)
203 do ip = 1, this%gr%np
204 psi1 = psib%zff(ip, 1, ist)
205 psi2 = psib%zff(ip, 2, ist)
206 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
207 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
208 term = weight(ist)*psi1*conjg(psi2)
209 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
210 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
216 select case (this%st%d%ispin)
220 do ip = 1, this%gr%np
221 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff_pack(ist, ip)**2
226 do ip = 1, this%gr%np
227 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
228 real(conjg(psib%zff_pack(ist, ip))*psib%zff_pack(ist, ip), real64)
232 assert(mod(psib%nst_linear, 2) == 0)
234 do ip = 1, this%gr%np
235 psi1 = psib%zff_pack(2*ist - 1, ip)
236 psi2 = psib%zff_pack(2*ist, ip)
237 term = weight(ist)*psi1*conjg(psi2)
239 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
240 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
241 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
242 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
252 select case (this%st%d%ispin)
288 safe_deallocate_a(weight)
301 logical,
optional,
intent(in) :: async
303 integer :: ist, ip, ispin, wgsize
304 complex(real64) :: term, psi1, psi2
305 real(real64),
allocatable :: weight(:)
312 ispin = this%st%d%get_spin_index(psib%ik)
314 safe_allocate(weight(1:psib%nst))
316 weight(ist) = this%st%kweights(psib%ik)*this%st%occ(psib%ist(ist), psib%ik)
319 select case (psib%status())
321 select case (this%st%d%ispin)
327 do ip = 1, this%gr%np
328 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff(ip, 1, ist)**2
335 do ip = 1, this%gr%np
336 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
337 real(conjg(psib%zff(ip, 1, ist))*psib%zff(ip, 1, ist), real64)
345 do ip = 1, this%gr%np
346 psi1 = psib%zff(ip, 1, ist)
347 psi2 = psib%zff(ip, 2, ist)
348 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
349 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
350 term = weight(ist)*psi1*conjg(psi2)
351 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
352 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
359 select case (this%st%d%ispin)
363 do ip = 1, this%gr%np
365 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff_pack(ist, ip)**2
370 do ip = 1, this%gr%np
372 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
373 real(conjg(psib%zff_pack(ist, ip))*psib%zff_pack(ist, ip), real64)
378 assert(mod(psib%nst_linear, 2) == 0)
380 do ip = 1, this%gr%np
382 psi1 = psib%zff_pack(2*ist - 1, ip)
383 psi2 = psib%zff_pack(2*ist, ip)
384 term = weight(ist)*psi1*conjg(psi2)
386 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
387 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
388 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
389 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
400 select case (this%st%d%ispin)
438 safe_deallocate_a(weight)
441 if (this%st%d%ispin /=
spinors)
then
467 logical,
optional,
intent(in) :: allreduce
468 logical,
optional,
intent(in) :: symmetrize
471 real(real64),
allocatable :: tmpdensity(:)
475 if (this%packed)
then
476 safe_allocate(tmpdensity(1:this%gr%np))
479 do ispin = 1, this%st%d%nspin
480 call accel_read_buffer(this%buff_density, int(this%gr%np, int64), tmpdensity, offset = (ispin - 1)*this%pnp)
483 do ip = 1, this%gr%np
484 this%density(ip, ispin) = this%density(ip, ispin) + tmpdensity(ip)
488 this%packed = .false.
490 safe_deallocate_a(tmpdensity)
494 if ((this%st%parallel_in_states .or. this%st%d%kpt%parallel) .and.
optional_default(allreduce, .
true.))
then
496 call comm_allreduce(this%st%st_kpt_mpi_grp, this%density, dim = (/this%gr%np, this%st%d%nspin/))
501 do ispin = 1, this%st%d%nspin
518 type(
grid_t),
intent(in) :: gr
519 real(real64),
intent(out) :: density(:, :)
520 integer,
optional,
intent(in) :: istin
527 assert(ubound(density, dim = 1) == gr%np .or. ubound(density, dim = 1) == gr%np_part)
531 if (.not.
present(istin))
then
533 do ik = st%d%kpt%start, st%d%kpt%end
534 do ib = st%group%block_start, st%group%block_end
541 do ik = st%d%kpt%start, st%d%kpt%end
542 do ib = st%group%block_start, st%group%block_end
543 if (st%group%psib(ib, ik)%ist(1) <= istin .and. st%group%psib(ib, ik)%ist(st%group%psib(ib, ik)%nst) >= istin)
then
562 class(
space_t),
intent(in) :: space
563 type(
grid_t),
intent(in) :: gr
566 integer,
intent(in) :: n
567 logical,
intent(in) :: family_is_mgga
569 integer :: ist, ik, ib, nblock
570 integer :: nodeto, nodefr
572 complex(real64),
allocatable :: psi(:, :, :), rec_buffer(:,:)
578 if (n >= st%nst)
then
579 write(
message(1),
'(a)')
'Attempting to freeze a number of orbitals which is larger or equal to'
580 write(
message(2),
'(a)')
'the total number. The program has to stop.'
586 if (.not.
allocated(st%frozen_rho))
then
587 safe_allocate(st%frozen_rho(1:gr%np, 1:st%d%nspin))
592 do ik = st%d%kpt%start, st%d%kpt%end
593 if (n < st%st_start) cycle
595 do ib = st%group%block_start, st%group%block_end
606 safe_allocate(psi(1:gr%np, 1:st%d%dim, 1:nblock))
615 safe_deallocate_a(psi)
626 if (family_is_mgga)
then
627 if (.not.
allocated(st%frozen_tau))
then
628 safe_allocate(st%frozen_tau(1:gr%np, 1:st%d%nspin))
630 if (.not.
allocated(st%frozen_gdens))
then
631 safe_allocate(st%frozen_gdens(1:gr%np, 1:space%dim, 1:st%d%nspin))
633 if (.not.
allocated(st%frozen_ldens))
then
634 safe_allocate(st%frozen_ldens(1:gr%np, 1:st%d%nspin))
638 density_gradient = st%frozen_gdens, density_laplacian = st%frozen_ldens, st_end = n)
646 safe_allocate(psi(1:gr%np, 1:st%d%dim, 1))
647 safe_allocate(rec_buffer(1:gr%np, 1:st%d%dim))
649 do ik = st%d%kpt%start, st%d%kpt%end
653 nodeto = st%node(ist)
655 nodefr = staux%node(ist+n)
657 if (st%mpi_grp%rank == nodeto .and. st%mpi_grp%rank == nodefr)
then
663 if (st%mpi_grp%rank == nodefr)
then
665 call st%mpi_grp%send(psi(1, 1, 1), gr%np*st%d%dim, mpi_double_complex, nodeto, ist)
667 if (st%mpi_grp%rank == nodeto)
then
668 call st%mpi_grp%recv(rec_buffer(1, 1), gr%np*st%d%dim, mpi_double_complex, nodefr, ist)
675 safe_deallocate_a(psi)
676 safe_deallocate_a(rec_buffer)
680 st%occ(ist, ik) = staux%occ(n+ist, ik)
681 st%eigenval(ist, ik) = staux%eigenval(n+ist, ik)
693 class(
mesh_t),
intent(in) :: mesh
695 integer,
intent(in) :: nn
705 safe_deallocate_a(st%eigenval)
706 safe_allocate(st%eigenval(1:st%nst, 1:st%nik))
707 st%eigenval = huge(st%eigenval)
709 safe_deallocate_a(st%occ)
710 safe_allocate(st%occ (1:st%nst, 1:st%nik))
732 do ik = st%d%kpt%start, st%d%kpt%end
733 do ist = st%st_start, st%st_end
734 st%qtot = st%qtot + st%occ(ist, ik) * st%kweights(ik)
738 if (st%parallel_in_states .or. st%d%kpt%parallel)
then
759 class(
mesh_t),
intent(in) :: mesh
760 real(real64),
contiguous,
intent(out) :: total_rho(:,:)
766 call lalg_copy(mesh%np, st%d%nspin, st%rho, total_rho)
768 if (
allocated(st%rho_core))
then
769 do is = 1, st%d%spin_channels
770 call lalg_axpy(mesh%np,
m_one/st%d%spin_channels, st%rho_core, total_rho(:, is))
775 if (
allocated(st%frozen_rho))
then
776 call lalg_axpy(mesh%np, st%d%nspin,
m_one, st%frozen_rho, total_rho)
784#include "density_inc.F90"
787#include "complex.F90"
788#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