27  use, 
intrinsic :: iso_fortran_env
 
   56    class(mesh_t),       
pointer     :: mesh
 
   57    type(atom_t),        
pointer     :: atom(:)
 
   58    real(real64),        
pointer     :: pos(:,:)
 
   60    type(lattice_vectors_t), 
pointer :: latt
 
   61    real(real64),        
allocatable :: total_density(:)
 
   62    real(real64),        
allocatable :: free_volume(:)
 
   63    real(real64),        
allocatable :: free_vol_r3(:,:)
 
   65    type(namespace_t)                :: namespace
 
   68  real(real64), 
parameter, 
public :: TOL_HIRSHFELD = 1e-9_real64
 
   72  subroutine hirshfeld_init(this, mesh, namespace, space, latt, atom, natoms, pos, nspin)
 
   73    type(hirshfeld_t),           
intent(out)   :: this
 
   74    class(mesh_t),       
target, 
intent(in)    :: mesh
 
   75    type(namespace_t),           
intent(in)    :: namespace
 
   76    class(space_t),              
intent(in)    :: space
 
   77    type(lattice_vectors_t), 
target, 
intent(in):: latt
 
   78    type(atom_t), 
target,        
intent(in)    :: atom(:)
 
   79    integer,                     
intent(in)    :: natoms
 
   80    real(real64), 
target,        
intent(in)    :: pos(1:space%dim,1:natoms)
 
   81    integer,                     
intent(in)    :: nspin
 
   83    integer :: iatom, ip, isp
 
   84    real(real64) :: rr, atom_pos(space%dim), rmax, den
 
   85    real(real64), 
allocatable :: atom_density(:, :)
 
   86    type(ps_t), 
pointer :: ps
 
   87    type(lattice_iterator_t) :: latt_iter
 
   99    this%namespace = namespace
 
  101    safe_allocate(this%total_density(1:mesh%np))
 
  102    safe_allocate(this%free_volume(1:natoms))
 
  103    safe_allocate(this%free_vol_r3(1:mesh%np, 1:natoms))
 
  104    safe_allocate(atom_density(1:mesh%np, 1:nspin))
 
  109      this%total_density(ip) = 
m_zero 
  115        this%free_vol_r3(ip, iatom) = 
m_zero 
  122      select type(spec=>atom(iatom)%species)
 
  131        rmax = max(rmax, ps%density(isp)%x_threshold)
 
  135      do icell = 1, latt_iter%n_cells
 
  136        atom_pos = pos(:, iatom) + latt_iter%get(icell)
 
  143          rr = norm2(mesh%x(ip, :) - atom_pos)
 
  144          den = sum(atom_density(ip, 1:nspin))
 
  146          this%total_density(ip) = this%total_density(ip) + den
 
  147          this%free_vol_r3(ip, iatom) = this%free_vol_r3(ip, iatom) + den*rr**3
 
  150      this%free_volume(iatom) = 
dmf_integrate(this%mesh, this%free_vol_r3(:, iatom), reduce = .false.)
 
  153    if (this%mesh%parallel_in_domains) 
then 
  154      call this%mesh%allreduce(this%free_volume)
 
  157    safe_deallocate_a(atom_density)
 
  171    safe_deallocate_a(this%total_density)
 
  172    safe_deallocate_a(this%free_volume)
 
  173    safe_deallocate_a(this%free_vol_r3)
 
  187    class(
space_t),            
intent(in)    :: space
 
  188    integer,                   
intent(in)    :: iatom
 
  189    real(real64),              
intent(in)    :: density(:, :)
 
  190    real(real64),              
intent(out)   :: charge
 
  193    real(real64) :: dens_ip
 
  194    real(real64), 
allocatable :: atom_density(:, :), hirshfeld_density(:)
 
  200    assert(
allocated(this%total_density))
 
  202    safe_allocate(atom_density(1:this%mesh%np, 1:this%nspin))
 
  203    safe_allocate(hirshfeld_density(1:this%mesh%np))
 
  206      this%pos(:, iatom), this%mesh, this%nspin, atom_density)
 
  209    do ip = 1, this%mesh%np
 
  210      dens_ip = sum(atom_density(ip, 1:this%nspin))
 
  211      if (abs(dens_ip) > tol_hirshfeld) 
then 
  212        hirshfeld_density(ip) = sum(density(ip, 1:this%nspin))*dens_ip/this%total_density(ip)
 
  214        hirshfeld_density(ip) = 0.0_real64
 
  220    safe_deallocate_a(atom_density)
 
  221    safe_deallocate_a(hirshfeld_density)
 
  232    integer,                   
intent(in)    :: iatom
 
  233    real(real64),              
intent(in)    :: density(:, :)
 
  234    real(real64),              
intent(out)   :: volume_ratio
 
  237    real(real64), 
allocatable :: hirshfeld_density(:)
 
  244    assert(
allocated(this%total_density))
 
  246    safe_allocate(hirshfeld_density(1:this%mesh%np))
 
  249    do ip = 1, this%mesh%np
 
  250      if (this%total_density(ip) > tol_hirshfeld) 
then 
  251        hirshfeld_density(ip) = this%free_vol_r3(ip, iatom)*sum(density(ip, 1:this%nspin))/this%total_density(ip)
 
  253        hirshfeld_density(ip) = 0.0_real64
 
  257    volume_ratio = 
dmf_integrate(this%mesh, hirshfeld_density)/this%free_volume(iatom)
 
  259    safe_deallocate_a(hirshfeld_density)
 
  270    integer,                   
intent(in)    :: iatom
 
  271    real(real64),              
intent(out)   :: ddensity(:)
 
  274    real(real64), 
allocatable :: atom_density(:, :)
 
  280    safe_allocate(atom_density(1:this%mesh%np, 1:this%nspin))
 
  283    do ip = 1, this%mesh%np
 
  284      if (abs(this%total_density(ip)) > tol_hirshfeld) 
then 
  285        ddensity(ip) = this%free_vol_r3(ip, iatom)/(this%total_density(ip)*this%free_volume(iatom))
 
  291    safe_deallocate_a(atom_density)
 
  302    class(
space_t),            
intent(in)    :: space
 
  303    integer,                   
intent(in)    :: iatom
 
  304    integer,                   
intent(in)    :: jatom
 
  305    real(real64),              
intent(in)    :: density(:, :)
 
  306    real(real64), 
contiguous,         
intent(out)   :: dposition(:)
 
  308    integer :: ip, idir, icell, jcell, isp
 
  309    real(real64) :: atom_dens, atom_der,rri, rri2, rrj, tdensity, rij, rmax_isqu, rmax_jsqu
 
  310    real(real64) :: pos_i(space%dim), pos_j(space%dim), rmax_i, rmax_j
 
  311    real(real64), 
allocatable :: grad(:, :), atom_density(:, :), atom_derivative(:, :)
 
  313    type(
ps_t), 
pointer :: ps_i, ps_j
 
  314    real(real64) :: tmp, xxi(space%dim), xxj(space%dim)
 
  316    real(real64) :: tol_spacing
 
  320    tol_spacing = maxval(this%mesh%spacing(1:space%dim))
 
  324    dposition(1:space%dim) = 
m_zero 
  326    select type(spec=> this%atom(iatom)%species)
 
  332    select type(spec=> this%atom(jatom)%species)
 
  341    do isp = 1, this%nspin
 
  342      rmax_i = max(rmax_i, ps_i%density(isp)%x_threshold)
 
  343      rmax_j = max(rmax_j, ps_j%density_der(isp)%x_threshold)
 
  346    rmax_isqu = rmax_i**2
 
  347    rmax_jsqu = rmax_j**2
 
  349    safe_allocate(grad(1:this%mesh%np, 1:space%dim))
 
  350    grad(1:this%mesh%np, 1:space%dim) = 
m_zero 
  351    safe_allocate(atom_derivative(1:this%mesh%np, 1:this%nspin))
 
  352    safe_allocate(atom_density(1:this%mesh%np, 1:this%nspin))
 
  355    do jcell = 1, latt_iter_j%n_cells
 
  357      pos_j = this%pos(:, jatom) + latt_iter_j%get(jcell)
 
  358      atom_derivative(1:this%mesh%np, 1:this%nspin) = 
m_zero 
  360        min(this%nspin, 2), atom_derivative(1:this%mesh%np, 1:this%nspin))
 
  363      do icell = 1, latt_iter_i%n_cells
 
  365        pos_i = pos_j + latt_iter_i%get(icell) + (this%pos(:, iatom) - this%pos(:, jatom))
 
  366        rij =  norm2(pos_i - pos_j)
 
  368        if (rij - (rmax_j+rmax_i) < tol_spacing) 
then 
  373            atom_density(1:this%mesh%np, 1:this%nspin))
 
  376          do ip = 1, this%mesh%np
 
  377            if (this%total_density(ip)< tol_hirshfeld) cycle
 
  379            xxi = this%mesh%x(ip, :) - pos_i
 
  381            if (rri2 - rmax_isqu > tol_spacing) cycle 
 
  383            xxj = this%mesh%x(ip, :) - pos_j
 
  385            if (rrj - rmax_jsqu > tol_spacing) cycle 
 
  390            tdensity = sum(density(ip, 1:this%nspin))
 
  391            atom_dens = sum(atom_density(ip, 1:this%nspin))
 
  392            atom_der = sum(atom_derivative(ip, 1:this%nspin))
 
  394            if (rrj > tol_hirshfeld) 
then 
  395              tmp = rri*rri2*atom_dens*tdensity/this%total_density(ip)**2
 
  396              do idir = 1, space%dim
 
  397                grad(ip, idir) = grad(ip, idir) - tmp*atom_der*xxj(idir)/rrj
 
  402            if (iatom == jatom .and. rij < tol_hirshfeld) 
then 
  403              grad(ip, :) = grad(ip, :) + (
m_three*rri*atom_dens + rri2*atom_der)*tdensity/this%total_density(ip)*xxi
 
  412    do idir = 1, space%dim
 
  413      dposition(idir) = 
dmf_integrate(this%mesh, grad(1:this%mesh%np, idir), reduce = .false.) &
 
  414        /this%free_volume(iatom)
 
  417    if (this%mesh%parallel_in_domains) 
then 
  418      call this%mesh%allreduce(dposition, dim = space%dim)
 
  421    safe_deallocate_a(atom_density)
 
  422    safe_deallocate_a(atom_derivative)
 
  423    safe_deallocate_a(grad)
 
double sqrt(double __x) __attribute__((__nothrow__
 
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
 
real(real64), parameter, public m_zero
 
real(real64), parameter, public m_three
 
subroutine, public hirshfeld_init(this, mesh, namespace, space, latt, atom, natoms, pos, nspin)
 
subroutine, public hirshfeld_charge(this, space, iatom, density, charge)
 
subroutine, public hirshfeld_end(this)
 
subroutine, public hirshfeld_density_derivative(this, iatom, ddensity)
 
subroutine, public hirshfeld_position_derivative(this, space, iatom, jatom, density, dposition)
 
subroutine, public hirshfeld_volume_ratio(this, iatom, density, volume_ratio)
 
This module defines various routines, operating on mesh functions.
 
real(real64) function, public dmf_integrate(mesh, ff, mask, reduce)
Integrate a function on the mesh.
 
This module defines the meshes, which are used in Octopus.
 
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.
 
subroutine, public species_atom_density_np(species, namespace, pos, mesh, spin_channels, rho)
 
subroutine, public species_atom_density_derivative_np(species, namespace, pos, mesh, spin_channels, drho)
 
subroutine, public species_atom_density(species, namespace, space, latt, pos, mesh, spin_channels, rho)
 
The following class implements a lattice iterator. It allows one to loop over all cells that are with...