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_, 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
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)
290 safe_deallocate_a(weight)
303 logical,
optional,
intent(in) :: async
305 integer :: ist, ip, ispin, bsize, gsize
306 complex(real64) :: term, psi1, psi2
307 real(real64),
allocatable :: weight(:)
314 ispin = this%st%d%get_spin_index(psib%ik)
316 safe_allocate(weight(1:psib%nst))
318 weight(ist) = this%st%kweights(psib%ik)*this%st%occ(psib%ist(ist), psib%ik)
321 select case (psib%status())
323 select case (this%st%d%ispin)
329 do ip = 1, this%gr%np
330 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff(ip, 1, ist)**2
337 do ip = 1, this%gr%np
338 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
339 real(conjg(psib%zff(ip, 1, ist))*psib%zff(ip, 1, ist), real64)
347 do ip = 1, this%gr%np
348 psi1 = psib%zff(ip, 1, ist)
349 psi2 = psib%zff(ip, 2, ist)
350 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
351 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
352 term = weight(ist)*psi1*conjg(psi2)
353 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
354 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
361 select case (this%st%d%ispin)
365 do ip = 1, this%gr%np
367 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)*psib%dff_pack(ist, ip)**2
372 do ip = 1, this%gr%np
374 this%density(ip, ispin) = this%density(ip, ispin) + weight(ist)* &
375 real(conjg(psib%zff_pack(ist, ip))*psib%zff_pack(ist, ip), real64)
380 assert(mod(psib%nst_linear, 2) == 0)
382 do ip = 1, this%gr%np
384 psi1 = psib%zff_pack(2*ist - 1, ip)
385 psi2 = psib%zff_pack(2*ist, ip)
386 term = weight(ist)*psi1*conjg(psi2)
388 this%density(ip, 1) = this%density(ip, 1) + weight(ist)*real(conjg(psi1)*psi1, real64)
389 this%density(ip, 2) = this%density(ip, 2) + weight(ist)*real(conjg(psi2)*psi2, real64)
390 this%density(ip, 3) = this%density(ip, 3) + real(term, real64)
391 this%density(ip, 4) = this%density(ip, 4) + aimag(term)
402 select case (this%st%d%ispin)
442 safe_deallocate_a(weight)
445 if (this%st%d%ispin /=
spinors)
then
471 logical,
optional,
intent(in) :: allreduce
472 logical,
optional,
intent(in) :: symmetrize
475 real(real64),
allocatable :: tmpdensity(:)
479 if (this%packed)
then
480 safe_allocate(tmpdensity(1:this%gr%np))
483 do ispin = 1, this%st%d%nspin
484 call accel_read_buffer(this%buff_density, int(this%gr%np, int64), tmpdensity, offset = (ispin - 1)*this%pnp)
487 do ip = 1, this%gr%np
488 this%density(ip, ispin) = this%density(ip, ispin) + tmpdensity(ip)
492 this%packed = .false.
494 safe_deallocate_a(tmpdensity)
498 if ((this%st%parallel_in_states .or. this%st%d%kpt%parallel) .and.
optional_default(allreduce, .
true.))
then
500 call comm_allreduce(this%st%st_kpt_mpi_grp, this%density, dim = (/this%gr%np, this%st%d%nspin/))
505 do ispin = 1, this%st%d%nspin
522 type(
grid_t),
intent(in) :: gr
523 real(real64),
intent(out) :: density(:, :)
524 integer,
optional,
intent(in) :: istin
531 assert(ubound(density, dim = 1) == gr%np .or. ubound(density, dim = 1) == gr%np_part)
535 if (.not.
present(istin))
then
537 do ik = st%d%kpt%start, st%d%kpt%end
538 do ib = st%group%block_start, st%group%block_end
545 do ik = st%d%kpt%start, st%d%kpt%end
546 do ib = st%group%block_start, st%group%block_end
547 if (st%group%psib(ib, ik)%ist(1) <= istin .and. st%group%psib(ib, ik)%ist(st%group%psib(ib, ik)%nst) >= istin)
then
566 class(
space_t),
intent(in) :: space
567 type(
grid_t),
intent(in) :: gr
570 integer,
intent(in) :: n
571 logical,
intent(in) :: family_is_mgga
573 integer :: ist, ik, ib, nblock
574 integer :: nodeto, nodefr
576 complex(real64),
allocatable :: psi(:, :, :), rec_buffer(:,:)
582 if (n >= st%nst)
then
583 write(
message(1),
'(a)')
'Attempting to freeze a number of orbitals which is larger or equal to'
584 write(
message(2),
'(a)')
'the total number. The program has to stop.'
590 if (.not.
allocated(st%frozen_rho))
then
591 safe_allocate(st%frozen_rho(1:gr%np, 1:st%d%nspin))
596 do ik = st%d%kpt%start, st%d%kpt%end
597 if (n < st%st_start) cycle
599 do ib = st%group%block_start, st%group%block_end
610 safe_allocate(psi(1:gr%np, 1:st%d%dim, 1:nblock))
619 safe_deallocate_a(psi)
630 if (family_is_mgga)
then
631 if (.not.
allocated(st%frozen_tau))
then
632 safe_allocate(st%frozen_tau(1:gr%np, 1:st%d%nspin))
634 if (.not.
allocated(st%frozen_gdens))
then
635 safe_allocate(st%frozen_gdens(1:gr%np, 1:space%dim, 1:st%d%nspin))
637 if (.not.
allocated(st%frozen_ldens))
then
638 safe_allocate(st%frozen_ldens(1:gr%np, 1:st%d%nspin))
642 density_gradient = st%frozen_gdens, density_laplacian = st%frozen_ldens, st_end = n)
650 safe_allocate(psi(1:gr%np, 1:st%d%dim, 1))
651 safe_allocate(rec_buffer(1:gr%np, 1:st%d%dim))
653 do ik = st%d%kpt%start, st%d%kpt%end
657 nodeto = st%node(ist)
659 nodefr = staux%node(ist+n)
661 if (st%mpi_grp%rank == nodeto .and. st%mpi_grp%rank == nodefr)
then
667 if (st%mpi_grp%rank == nodefr)
then
669 call st%mpi_grp%send(psi(1, 1, 1), gr%np*st%d%dim, mpi_double_complex, nodeto, ist)
671 if (st%mpi_grp%rank == nodeto)
then
672 call st%mpi_grp%recv(rec_buffer(1, 1), gr%np*st%d%dim, mpi_double_complex, nodefr, ist)
679 safe_deallocate_a(psi)
680 safe_deallocate_a(rec_buffer)
684 st%occ(ist, ik) = staux%occ(n+ist, ik)
685 st%eigenval(ist, ik) = staux%eigenval(n+ist, ik)
697 class(
mesh_t),
intent(in) :: mesh
699 integer,
intent(in) :: nn
709 safe_deallocate_a(st%eigenval)
710 safe_allocate(st%eigenval(1:st%nst, 1:st%nik))
711 st%eigenval = huge(st%eigenval)
713 safe_deallocate_a(st%occ)
714 safe_allocate(st%occ (1:st%nst, 1:st%nik))
736 do ik = st%d%kpt%start, st%d%kpt%end
737 do ist = st%st_start, st%st_end
738 st%qtot = st%qtot + st%occ(ist, ik) * st%kweights(ik)
742 if (st%parallel_in_states .or. st%d%kpt%parallel)
then
763 class(
mesh_t),
intent(in) :: mesh
764 real(real64),
contiguous,
intent(out) :: total_rho(:,:)
770 call lalg_copy(mesh%np, st%d%nspin, st%rho, total_rho)
772 if (
allocated(st%rho_core))
then
773 do is = 1, st%d%spin_channels
774 call lalg_axpy(mesh%np,
m_one/st%d%spin_channels, st%rho_core, total_rho(:, is))
779 if (
allocated(st%frozen_rho))
then
780 call lalg_axpy(mesh%np, st%d%nspin,
m_one, st%frozen_rho, total_rho)
788#include "density_inc.F90"
791#include "complex.F90"
792#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