LCOV - code coverage report
Current view: top level - src/65_paw - m_paw_mkrho.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 71.8 % 284 204
Test Date: 2026-11-09 11:14:24 Functions: 100.0 % 2 2
Branches: 56.7 % 457 259

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_paw_mkrho
       2                 :             : !! NAME
       3                 :             : !!  m_paw_mkrho
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  This module contains routines used to compute PAW density on the real space fine grid.
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !! Copyright (C) 2018-2026 ABINIT group (MT, JWZ)
      10                 :             : !! This file is distributed under the terms of the
      11                 :             : !! GNU General Public License, see ~abinit/COPYING
      12                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      13                 :             : !!
      14                 :             : !! SOURCE
      15                 :             : 
      16                 :             : #if defined HAVE_CONFIG_H
      17                 :             : #include "config.h"
      18                 :             : #endif
      19                 :             : 
      20                 :             : #include "abi_common.h"
      21                 :             : 
      22                 :             : MODULE m_paw_mkrho
      23                 :             : 
      24                 :             :  use defs_basis
      25                 :             :  use m_abicore
      26                 :             :  use m_errors
      27                 :             :  use m_xmpi
      28                 :             :  use m_extfpmd
      29                 :             : 
      30                 :             :  use defs_abitypes,      only : MPI_type
      31                 :             :  use m_time,             only : timab
      32                 :             :  use m_pawang,           only : pawang_type
      33                 :             :  use m_pawrad,           only : pawrad_type,pawrad_deducer0
      34                 :             :  use m_pawtab,           only : pawtab_type,pawtab_get_lsize
      35                 :             :  use m_paw_sphharm,      only : initylmr
      36                 :             :  use m_pawfgrtab,        only : pawfgrtab_type,pawfgrtab_init,pawfgrtab_free
      37                 :             :  use m_pawrhoij,         only : pawrhoij_type,pawrhoij_copy,pawrhoij_free_unpacked, &
      38                 :             : &                               pawrhoij_nullify,pawrhoij_free,pawrhoij_symrhoij
      39                 :             :  use m_pawfgr,           only : pawfgr_type
      40                 :             :  use m_paw_nhat,         only : pawmknhat,nhatgrid
      41                 :             :  use m_paral_atom,       only : get_my_atmtab,free_my_atmtab
      42                 :             :  use m_fourier_interpol, only : transgrid
      43                 :             : 
      44                 :             :  use m_sort,             only : sort_dp
      45                 :             :  use m_splines,          only : spline,splint
      46                 :             :  use m_io_tools,         only : open_file
      47                 :             :  use m_geometry,         only : xred2xcart
      48                 :             :  use m_pptools,          only : printxsf
      49                 :             :  use m_fft,              only : fourdp
      50                 :             : 
      51                 :             :  implicit none
      52                 :             : 
      53                 :             :  private
      54                 :             : 
      55                 :             : !public procedures.
      56                 :             :  public :: pawmkrho ! Build PAW electronic density on fine grid, including compensation charge density
      57                 :             :  public :: denfgr   ! Build complete PAW electronic density on fine grid, including on-site contributions
      58                 :             : 
      59                 :             : CONTAINS  !========================================================================================
      60                 :             : !!***
      61                 :             : 
      62                 :             : !----------------------------------------------------------------------
      63                 :             : 
      64                 :             : !!****f* m_paw_mkrho/pawmkrho
      65                 :             : !! NAME
      66                 :             : !! pawmkrho
      67                 :             : !!
      68                 :             : !! FUNCTION
      69                 :             : !! PAW only:
      70                 :             : !! Build total pseudo (compensated) density (\tild_rho + \hat_rho)
      71                 :             : !! Build compensation charge density (\hat_rho)
      72                 :             : !! Build occupation matrix (packed storage)
      73                 :             : !!
      74                 :             : !! INPUTS
      75                 :             : !!  compute_rhor_rhog: if 1: set the computation of rhor and rhog in addition to the compensating charge.
      76                 :             : !!                     if 0: compute only the compensating charge
      77                 :             : !!  cplex: if 1, real space 1-order functions on FFT grid are REAL, if 2, COMPLEX
      78                 :             : !!         1 for GS calculations
      79                 :             : !!  extfpmd <type(extfpmd_type)>=--optional--extended first-principles molecular dynamics type
      80                 :             : !!  gprimd(3,3)=dimensional primitive translations for reciprocal space(bohr^-1).
      81                 :             : !!  indsym(4,nsym,natom)=indirect indexing array for atom labels
      82                 :             : !!  ipert=index of perturbation if pawrhoij is a pertubed rhoij
      83                 :             : !!        no meaning for ground-state calculations (should be 0)
      84                 :             : !!  idir=direction of atomic displacement (in case of atomic displ. perturb.)
      85                 :             : !!  mpi_enreg=information about MPI parallelization
      86                 :             : !!  my_natom=number of atoms treated by current processor
      87                 :             : !!  natom=number of atoms in cell
      88                 :             : !!  nspden=number of spin-density components
      89                 :             : !!  nsym=number of symmetry elements in space group
      90                 :             : !!  ntypat=number of types of atoms in unit cell.
      91                 :             : !!  paral_kgb=option for (kpt,g vectors,bands) parallelism
      92                 :             : !!  pawang <type(pawang_type)>=angular mesh discretization and related data
      93                 :             : !!  pawang_sym <type(pawang_type)>=angular data used for symmetrization
      94                 :             : !!                                 optional parameter only needed for RF calculations
      95                 :             : !!  pawfgr <type(paw_fgr_type)>=fine rectangular grid parameters
      96                 :             : !!  pawfgrtab(natom) <type(pawfgrtab_type)>=atomic data given on fine rectangular grid
      97                 :             : !!  pawprtvol=control print volume and debugging output for PAW
      98                 :             : !!  pawrhoij0(natom) <type(pawrhoij_type)>= GS paw rhoij occupancies and related data (used only if ipert>0)
      99                 :             : !!                                          optional parameter only needed for RF calculations
     100                 :             : !!  pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
     101                 :             : !!  qphon(3)=wavevector of the phonon (RF only)
     102                 :             : !!  rhopsg(2,pawfgr%nfftc)= pseudo density given on the coarse grid in reciprocal space
     103                 :             : !!  rhopsr(pawfgr%nfftc,nspden)= pseudo density given on the coarse grid in real space
     104                 :             : !!  rprimd(3,3)=real space primitive translations.
     105                 :             : !!  symafm(nsym)=(anti)ferromagnetic part of symmetry operations
     106                 :             : !!  symrec(3,3,nsym)=symmetries of group in terms of operations on
     107                 :             : !!                   reciprocal space primitive translations
     108                 :             : !!  typat(natom)=type for each atom
     109                 :             : !!  ucvol=volume of the unit cell
     110                 :             : !!  xred(3,natom)= reduced atomic coordinates
     111                 :             : !!
     112                 :             : !! OUTPUT
     113                 :             : !!  compch_fft=compensation charge inside spheres integrated over fine fft grid
     114                 :             : !!  pawnhat(pawfgr%nfft,nspden)=compensation charge density on fine rectangular grid (optional argument)
     115                 :             : !!  rhog(2,pawfgr%nfft)= compensated pseudo density given on the fine grid in reciprocal space
     116                 :             : !!                       This output is optional
     117                 :             : !!  rhor(pawfgr%nfft,nspden)= compensated pseudo density given on the fine grid in real space
     118                 :             : !!
     119                 :             : !! SIDE EFFECTS
     120                 :             : !!  pawrhoij(my_natom)= PAW occupancies
     121                 :             : !!                   At input : values at previous step  in packed storage (pawrhoij()%rhoijp)
     122                 :             : !!                   At output: values (symmetrized)     in packed storage (pawrhoij()%rhoijp)
     123                 :             : !!  pawrhoij_unsym(:)= unsymmetrized PAW occupancies
     124                 :             : !!                   At input : values (unsymmetrized) in unpacked storage (pawrhoij()%rhoij_)
     125                 :             : !!                   At output: values in unpacked storage (pawrhoij()%rhoij_) are destroyed
     126                 :             : !!
     127                 :             : !! NOTES
     128                 :             : !!  pawrhoij and pawrhoij_unsym can be identical (refer to the same pawrhoij datastructure).
     129                 :             : !!  They should be different only if pawrhoij is distributed over atomic sites
     130                 :             : !!  (in that case pawrhoij_unsym should not be distributed over atomic sites).
     131                 :             : !!
     132                 :             : !! SOURCE
     133                 :             : 
     134                 :       45716 : subroutine pawmkrho(compute_rhor_rhog,compch_fft,cplex,gprimd,idir,indsym,ipert,mpi_enreg,&
     135                 :       22858 : &          my_natom,natom,nspden,nsym,ntypat,paral_kgb,pawang,pawfgr,pawfgrtab,pawprtvol,&
     136   [ -  +  -  + ]:       45716 : &          pawrhoij,pawrhoij_unsym,&
     137                 :       45716 : &          pawtab,qphon,rhopsg,rhopsr,rhor,rprimd,symafm,symrec,typat,ucvol,usewvl,xred,&
     138   [ -  +  -  -  :       28515 : &          pawang_sym,pawnhat,pawnhatgr,pawrhoij0,rhog,extfpmd) ! optional arguments
                   -  - ]
     139                 :             : 
     140                 :             : !Arguments ------------------------------------
     141                 :             : !scalars
     142                 :             :  integer,intent(in) :: compute_rhor_rhog,cplex,idir,ipert,my_natom,natom,nspden,nsym,ntypat,paral_kgb,pawprtvol
     143                 :             :  integer,intent(in) :: usewvl
     144                 :             :  real(dp),intent(in) :: ucvol
     145                 :             :  real(dp),intent(out) :: compch_fft
     146                 :             :  type(MPI_type),intent(in) :: mpi_enreg
     147                 :             :  type(pawang_type),intent(in) :: pawang
     148                 :             :  type(pawang_type),intent(in),optional :: pawang_sym
     149                 :             :  type(pawfgr_type),intent(in) :: pawfgr
     150                 :             :  type(extfpmd_type),intent(in),pointer,optional :: extfpmd
     151                 :             : !arrays
     152                 :             :  integer,intent(in) :: indsym(4,nsym,natom)
     153                 :             :  integer,intent(in) :: symafm(nsym),symrec(3,3,nsym),typat(natom)
     154                 :             :  real(dp),intent(in) :: gprimd(3,3),qphon(3),rprimd(3,3),xred(3,natom)
     155                 :             :  real(dp),intent(inout),target,optional :: pawnhat(cplex*pawfgr%nfft,nspden) !vz_i
     156                 :             :  real(dp),intent(inout),target,optional :: pawnhatgr(:,:,:) !vz_i
     157                 :             :  real(dp),intent(inout) :: rhor(cplex*pawfgr%nfft,nspden*compute_rhor_rhog)
     158                 :             :  real(dp),intent(out),optional :: rhog(2,pawfgr%nfft*compute_rhor_rhog)
     159                 :             :  real(dp),intent(inout) :: rhopsg(2,pawfgr%nfftc*compute_rhor_rhog),rhopsr(cplex*pawfgr%nfftc,nspden*compute_rhor_rhog)
     160                 :             :  type(pawfgrtab_type),intent(inout) :: pawfgrtab(my_natom)
     161                 :             :  type(pawrhoij_type),intent(inout),target :: pawrhoij(:)
     162                 :             :  type(pawrhoij_type),intent(inout) :: pawrhoij_unsym(:)
     163                 :             :  type(pawrhoij_type),intent(in),target,optional :: pawrhoij0(my_natom)
     164                 :             :  type(pawtab_type),intent(in) :: pawtab(ntypat)
     165                 :             : 
     166                 :             : !Local variables-------------------------------
     167                 :             : !scalars
     168                 :             :  integer :: choice,ider,izero,option
     169                 :             :  character(len=500) :: msg
     170                 :             : !arrays
     171                 :             :  real(dp) :: tsec(2)
     172                 :             :  real(dp),target :: rhodum(0,0,0)
     173                 :       22858 :  real(dp),pointer :: pawnhat_ptr(:,:)
     174                 :       22858 :  real(dp),pointer :: pawnhatgr_ptr(:,:,:)
     175                 :       22858 :  type(pawrhoij_type),pointer :: pawrhoij_ptr(:),pawrhoij0_ptr(:)
     176                 :             : 
     177                 :             : ! ***********************************************************************
     178                 :             : 
     179                 :             :  DBG_ENTER("COLL")
     180                 :             : 
     181                 :       22858 :  call timab(556,1,tsec)
     182                 :             : 
     183                 :             : !Compatibility tests
     184         [ +  - ]:       22858 :  if (size(pawrhoij_unsym)>0) then
     185         [ -  + ]:       22858 :    if (pawrhoij_unsym(1)%use_rhoij_==0) then
     186                 :           0 :      msg='  rhoij_ field must be allocated in pawrhoij_unsym !'
     187                 :           0 :      ABI_BUG(msg)
     188                 :             :    end if
     189                 :             :  end if
     190   [ +  +  -  + ]:       22858 :  if (ipert>0.and.(.not.present(pawrhoij0))) then
     191                 :           0 :    msg='  pawrhoij0 must be present when ipert>0 !'
     192                 :           0 :    ABI_BUG(msg)
     193                 :             :  end if
     194                 :             : 
     195                 :             : !Symetrize PAW occupation matrix and store it in packed storage
     196                 :       22858 :  call timab(557,1,tsec)
     197                 :       22858 :  option=1;choice=1
     198         [ +  + ]:       22858 :  if (present(pawang_sym)) then
     199                 :             :    call pawrhoij_symrhoij(pawrhoij,pawrhoij_unsym,choice,gprimd,indsym,ipert,&
     200                 :             : &       natom,nsym,ntypat,option,pawang_sym,pawprtvol,pawtab,rprimd,symafm,&
     201                 :             : &       symrec,typat,comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab,&
     202                 :        5772 : &       qphon=qphon)
     203                 :             :  else
     204                 :             :    call pawrhoij_symrhoij(pawrhoij,pawrhoij_unsym,choice,gprimd,indsym,ipert,&
     205                 :             : &       natom,nsym,ntypat,option,pawang,pawprtvol,pawtab,rprimd,symafm,&
     206                 :             : &       symrec,typat,comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab,&
     207                 :       17086 : &       qphon=qphon)
     208                 :             :  end if
     209                 :       22858 :  call pawrhoij_free_unpacked(pawrhoij_unsym)
     210                 :       22858 :  call timab(557,2,tsec)
     211                 :             : 
     212                 :             : !In somes cases (parallelism), has to distribute the PAW occupation matrix
     213   [ +  +  -  + ]:       22858 :  if (size(pawrhoij)==natom.and.(my_natom/=natom)) then
     214   [ #  #  #  #  :           0 :    ABI_MALLOC(pawrhoij_ptr,(my_natom))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     215                 :           0 :    call pawrhoij_nullify(pawrhoij_ptr)
     216                 :             :    call pawrhoij_copy(pawrhoij,pawrhoij_ptr,&
     217                 :             : &   mpi_atmtab=mpi_enreg%my_atmtab,comm_atom=mpi_enreg%comm_atom, &
     218                 :           0 : &   keep_cplex=.false.,keep_qphase=.false.,keep_itypat=.false.,keep_nspden=.false.)
     219                 :             :  else
     220                 :       22858 :    pawrhoij_ptr=>pawrhoij
     221                 :             :  end if
     222                 :             : 
     223                 :             : !Compute compensation charge density
     224                 :       22858 :  ider=0;izero=0
     225         [ +  + ]:       22858 :  if (present(pawnhat)) then
     226                 :       22760 :    pawnhat_ptr => pawnhat
     227                 :             :  else
     228   [ -  +  +  -  :         392 :    ABI_MALLOC(pawnhat_ptr,(pawfgr%nfft,nspden))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     229                 :             :  end if
     230         [ -  + ]:       22858 :  if (present(pawnhatgr)) then
     231                 :           0 :    pawnhatgr_ptr => pawnhatgr
     232                 :             :  else
     233                 :       22858 :    pawnhatgr_ptr => rhodum
     234                 :             :  end if
     235         [ +  + ]:       22858 :  if (present(pawrhoij0)) then
     236                 :        5657 :    pawrhoij0_ptr => pawrhoij0
     237                 :             :  else
     238                 :       17201 :    pawrhoij0_ptr => pawrhoij_ptr
     239                 :             :  end if
     240                 :             : 
     241                 :             :  call pawmknhat(compch_fft,cplex,ider,idir,ipert,izero,gprimd,my_natom,natom,&
     242                 :             : & pawfgr%nfft,pawfgr%ngfft,ider,nspden,ntypat,pawang,pawfgrtab,&
     243                 :             : & pawnhatgr_ptr,pawnhat_ptr,pawrhoij_ptr,pawrhoij0_ptr,pawtab,qphon,rprimd,ucvol,usewvl,xred,&
     244                 :             : & comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab,&
     245                 :             : & comm_fft=mpi_enreg%comm_fft,paral_kgb=paral_kgb,me_g0=mpi_enreg%me_g0,&
     246   [ -  +  -  +  :       22858 : & distribfft=mpi_enreg%distribfft,mpi_comm_wvl=mpi_enreg%comm_wvl)
             -  +  -  + ]
     247                 :             : 
     248         [ +  + ]:       22858 :  if (compute_rhor_rhog/=0) then
     249                 :             : !  Transfer pseudo density from coarse grid to fine grid
     250         [ +  - ]:       22738 :    if(usewvl==0) then
     251                 :       22738 :      call transgrid(cplex,mpi_enreg,nspden,+1,1,0,paral_kgb,pawfgr,rhopsg,rhodum,rhopsr,rhor)
     252                 :             :    end if
     253                 :             : 
     254                 :             : !  Add pseudo density and compensation charge density (on fine grid)
     255   [ +  +  +  + ]:   983414779 :    rhor(:,:)=rhor(:,:)+pawnhat_ptr(:,:)
     256                 :             : 
     257                 :             : !  Add extfpmd electrons contributions to density on fine grid.
     258         [ +  + ]:       22738 :    if(present(extfpmd)) then
     259         [ +  + ]:       15511 :      if(associated(extfpmd)) then
     260   [ -  +  -  - ]:          90 :        if(extfpmd%version==10.and.allocated(extfpmd%nelectarr)) then
     261   [ #  #  #  # ]:           0 :          rhor(:,:)=rhor(:,:)+extfpmd%nelectarr(:,:)/ucvol/nspden
     262                 :             :        else
     263   [ +  +  +  + ]:      993332 :          rhor(:,:)=rhor(:,:)+extfpmd%nelect/ucvol/nspden
     264                 :             :        end if
     265                 :             :      end if
     266                 :             :    end if
     267                 :             : 
     268                 :             : !  Compute compensated pseudo density in reciprocal space
     269         [ +  + ]:       22738 :    if (present(rhog)) then
     270                 :       19773 :      call fourdp(cplex,rhog,rhor(:,1),-1,mpi_enreg,pawfgr%nfft,1,pawfgr%ngfft,0)
     271                 :             :    end if
     272                 :             :  end if
     273                 :             : 
     274                 :             : !Free temporary memory spaces
     275         [ +  + ]:       22858 :  if (.not.present(pawnhat)) then
     276         [ -  + ]:          98 :    ABI_FREE(pawnhat_ptr)
     277                 :             :  end if
     278   [ +  +  -  + ]:       22858 :  if (size(pawrhoij)==natom.and.(my_natom/=natom)) then
     279                 :           0 :    call pawrhoij_free(pawrhoij_ptr)
     280         [ #  # ]:           0 :    ABI_FREE(pawrhoij_ptr)
     281                 :             :  end if
     282                 :             :  nullify(pawnhat_ptr)
     283                 :             :  nullify(pawnhatgr_ptr)
     284                 :       22858 :  nullify(pawrhoij_ptr)
     285                 :             : 
     286                 :       22858 :  call timab(556,2,tsec)
     287                 :             : 
     288                 :             :  DBG_EXIT("COLL")
     289                 :             : 
     290   [ +  +  +  + ]:       68574 : end subroutine pawmkrho
     291                 :             : !!***
     292                 :             : 
     293                 :             : !----------------------------------------------------------------------
     294                 :             : 
     295                 :             : !!****f* m_paw_mkrho/denfgr
     296                 :             : !! NAME
     297                 :             : !! denfgr
     298                 :             : !!
     299                 :             : !! FUNCTION
     300                 :             : !!  Construct complete electron density on fine grid, by removing nhat
     301                 :             : !!  and adding PAW corrections
     302                 :             : !!
     303                 :             : !! INPUTS
     304                 :             : !!   atindx1(natom)=index table for atoms, inverse of atindx (see gstate.f)
     305                 :             : !!   gmet(3,3)=reciprocal space metric tensor in bohr**-2.
     306                 :             : !!   mpi_atmtab(:)=--optional-- indexes of the atoms treated by current proc
     307                 :             : !!   comm_atom=--optional-- MPI communicator over atoms
     308                 :             : !!   my_natom=number of atoms treated by current processor
     309                 :             : !!   natom= number of atoms in cell
     310                 :             : !!   nattyp(ntypat)= # atoms of each type.
     311                 :             : !!   ngfft(18)=contain all needed information about 3D FFT (see NOTES at beginning of scfcv)
     312                 :             : !!   nhat(pawfgr%nfft,nspden)= compensation charge density used in PAW
     313                 :             : !!   nspinor=Number of spinor components
     314                 :             : !!   nsppol=Number of independent spin components.
     315                 :             : !!   nspden= number of spin densities
     316                 :             : !!   ntypat= number of types of atoms in the cell
     317                 :             : !!   pawfgr <type(pawfgr_type)>= data about the fine grid
     318                 :             : !!   pawrad(ntypat) <type(pawrad_type)>= radial mesh data for each type of atom
     319                 :             : !!   pawrhoij(natom) <type(pawrhoij_type)>= rho_ij data for each atom
     320                 :             : !!   pawtab(ntypat) <type(pawtab_type)>= PAW functions around each type of atom
     321                 :             : !!   rhor(pawfgr%nfft,nspden)= input density ($\tilde{n}+\hat{n}$ in PAW case)
     322                 :             : !!   rprimd(3,3)=dimensional primitive translations for real space (bohr)
     323                 :             : !!   typat(natom)= list of atom types
     324                 :             : !!   ucvol=unit cell volume (bohr**3)
     325                 :             : !!   xred(3,natom)=reduced dimensionless atomic coordinates
     326                 :             : !!
     327                 :             : !! OUTPUT
     328                 :             : !! rhor_paw(pawfgr%nfft,nspden)= full electron density on the fine grid
     329                 :             : !!
     330                 :             : !! NOTES
     331                 :             : !!   In PAW calculations, the valence density present in rhor includes the
     332                 :             : !!   compensation charge density $\hat{n}$, and also doesn't include the on-site
     333                 :             : !!   PAW contributions. For post-processing and proper visualization it is necessary
     334                 :             : !!   to use the full electronic density, which is what this subroutine constructs.
     335                 :             : !!   Specifically, it removes $\hat{n}$ from rhor, and also computes the on-site PAW
     336                 :             : !!   terms. This is nothing other than the proper PAW treatment of the density
     337                 :             : !!   operator $|\mathbf{r}\rangle\langle\mathbf{r}|$, and yields the formula
     338                 :             : !!   $$\tilde{n}+\sum_{ij}\rho_ij\left[\varphi_i(\mathbf{r})\varphi_j(\mathbf{r})-
     339                 :             : !!   \tilde{\varphi}_i(\mathbf{r})\tilde{\varphi}_j(\mathbf{r})\right]$$
     340                 :             : !!   Notice that this formula is expressed on the fine grid, and requires
     341                 :             : !!   interpolating the PAW radial functions onto this grid, as well as calling
     342                 :             : !!   initylmr in order to get the angular functions on the grid points.
     343                 :             : !!
     344                 :             : !! SOURCE
     345                 :             : 
     346                 :           4 :  subroutine denfgr(atindx1,gmet,spaceComm_in,my_natom,natom,nattyp,ngfft,nhat,nspinor,nsppol,nspden,ntypat, &
     347                 :           4 : & pawfgr,pawrad,pawrhoij,pawtab,prtvol,rhor,rhor_paw,rhor_n_one,rhor_nt_one,rprimd,typat,ucvol,xred,&
     348   [ +  +  -  +  :           2 : & abs_n_tilde_nt_diff,znucl,mpi_atmtab,comm_atom) ! Optional arguments
                   -  - ]
     349                 :             : 
     350                 :             : !Arguments ------------------------------------
     351                 :             : !scalars
     352                 :             :  integer,intent(in) :: my_natom,natom,nspden,ntypat,prtvol,nsppol,nspinor
     353                 :             :  integer,optional,intent(in) :: comm_atom
     354                 :             :  real(dp),intent(in) :: ucvol
     355                 :             :  type(pawfgr_type),intent(in) :: pawfgr
     356                 :             : !arrays
     357                 :             :  integer,intent(in) :: spaceComm_in
     358                 :             :  integer,intent(in) :: atindx1(natom),nattyp(ntypat),ngfft(18),typat(natom)
     359                 :             :  integer,optional,target,intent(in) :: mpi_atmtab(:)
     360                 :             :  real(dp),intent(in) :: gmet(3,3),nhat(pawfgr%nfft,nspden)
     361                 :             :  real(dp),intent(in) :: rhor(pawfgr%nfft,nspden),rprimd(3,3)
     362                 :             :  real(dp),intent(inout) :: xred(3,natom)
     363                 :             :  real(dp),intent(out) :: rhor_paw(pawfgr%nfft,nspden)
     364                 :             :  real(dp),intent(out) :: rhor_n_one(pawfgr%nfft,nspden)
     365                 :             :  real(dp),intent(out) :: rhor_nt_one(pawfgr%nfft,nspden)
     366                 :             :  real(dp),optional,intent(out) :: abs_n_tilde_nt_diff(nspden)
     367                 :             :  real(dp),optional,intent(in) :: znucl(ntypat)
     368                 :             :  type(pawrad_type),intent(in) :: pawrad(ntypat)
     369                 :             :  type(pawrhoij_type),intent(in) :: pawrhoij(my_natom)
     370                 :             :  type(pawtab_type),target,intent(in) :: pawtab(ntypat)
     371                 :             : 
     372                 :             : !Local variables-------------------------------
     373                 :             : !scalars
     374                 :             :  integer,parameter :: master=0
     375                 :             :  integer :: delta,iatom,ierr,ifgd,ifftsph,inl,inrm,ipsang,irhoij
     376                 :             :  integer :: ispden,itypat,il,im,ilm,iln,ilmn
     377                 :             :  integer :: jl,jlm,jln,jm,j0lmn,jlmn
     378                 :             :  integer :: klmn,my_comm_atom,my_start_indx,my_end_indx
     379                 :             :  integer :: nfgd,nnl,normchoice,nprocs,optcut,optgr0,optgr1,optgr2
     380                 :             :  integer :: optrad,option,my_rank,remainder,tmp_unt
     381                 :             :  real(dp) :: phj,phi,rR,tphj,tphi,ybcbeg,ybcend
     382                 :             :  logical :: my_atmtab_allocated,paral_atom
     383                 :             :  character(len=500) :: message
     384                 :             : !arrays
     385                 :           4 :  integer,allocatable :: l_size_atm(:),nrm_ifftsph(:)
     386                 :           2 :  integer,contiguous, pointer :: indlmn(:,:)
     387                 :           2 :  integer,pointer :: my_atmtab(:)
     388                 :             :  real(dp) :: ylmgr(3,3,0)
     389                 :           4 :  real(dp) :: yvals(4),xcart(3,natom)
     390                 :           4 :  real(dp),allocatable :: diag(:),nrm(:),phigrd(:,:),tphigrd(:,:),ylm(:,:),ypp(:)
     391                 :           2 :  real(dp),allocatable :: phi_at_zero(:),tphi_at_zero(:)
     392                 :           2 :  real(dp),allocatable :: rhor_tmp(:,:),tot_rhor(:)
     393                 :             :  character(len=fnlen) :: xsf_fname
     394   [ +  +  +  +  :          50 :  type(pawfgrtab_type) :: local_pawfgrtab(my_natom)
          +  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
     395                 :             : 
     396                 :             : ! ************************************************************************
     397                 :             : 
     398                 :             :  DBG_ENTER("COLL")
     399                 :             : 
     400         [ +  - ]:           2 :  if (my_natom>0) then
     401         [ -  + ]:           2 :    ABI_CHECK(pawrhoij(1)%qphase==1,'denfgr not supposed to be called with qphase/=1!')
     402                 :             :  end if
     403                 :             : 
     404                 :             : !Set up parallelism over atoms (compatible only with band-FFT parallelism)
     405   [ +  +  +  - ]:           2 :  paral_atom=(present(comm_atom).and.(my_natom/=natom))
     406         [ -  + ]:           2 :  nullify(my_atmtab);if (present(mpi_atmtab)) my_atmtab => mpi_atmtab
     407         [ +  + ]:           2 :  my_comm_atom=xmpi_comm_self;if (present(comm_atom)) my_comm_atom=comm_atom
     408                 :             :  call get_my_atmtab(my_comm_atom,my_atmtab,my_atmtab_allocated,paral_atom,natom,&
     409                 :           2 : & my_natom_ref=my_natom)
     410                 :             : 
     411                 :             : !MG: FIXME It won't work if atom-parallelism is used
     412                 :             : !but even the loop over atoms below should be rewritten in this case.
     413                 :             : 
     414                 :             : !use a local copy of pawfgrtab to make sure we use the correction in the paw spheres
     415                 :             : !the usual pawfgrtab uses r_shape which may not be the same as r_paw
     416         [ +  - ]:           2 :  if (my_natom>0) then
     417         [ -  + ]:           2 :    if (paral_atom) then
     418                 :           0 :      call pawtab_get_lsize(pawtab,l_size_atm,my_natom,typat,mpi_atmtab=my_atmtab)
     419                 :             :      call pawfgrtab_init(local_pawfgrtab,pawrhoij(1)%qphase,l_size_atm,nspden,typat,&
     420                 :           0 : &     mpi_atmtab=my_atmtab,comm_atom=my_comm_atom)
     421                 :             :    else
     422                 :           2 :      call pawtab_get_lsize(pawtab,l_size_atm,my_natom,typat)
     423                 :           2 :      call pawfgrtab_init(local_pawfgrtab,pawrhoij(1)%qphase,l_size_atm,nspden,typat)
     424                 :             :    end if
     425         [ -  + ]:           2 :    ABI_FREE(l_size_atm)
     426                 :             :  end if
     427                 :             : 
     428                 :             : !Note: call to nhatgrid: comm_fft not used because FFT parallelism
     429                 :             : !is done manually below
     430                 :           2 :  optcut = 1 ! use rpaw to construct local_pawfgrtab
     431                 :           2 :  optgr0 = 0; optgr1 = 0; optgr2 = 0 ! dont need gY terms locally
     432                 :           2 :  optrad = 1 ! do store r-R
     433         [ -  + ]:           2 :  if (paral_atom) then
     434                 :             :    call nhatgrid(atindx1,gmet,my_natom,natom,nattyp,ngfft,ntypat,&
     435                 :             : &   optcut,optgr0,optgr1,optgr2,optrad,local_pawfgrtab,pawtab,rprimd,typat,ucvol,xred,&
     436                 :           0 : &   comm_atom=my_comm_atom,mpi_atmtab=my_atmtab)
     437                 :             :  else
     438                 :             :    call nhatgrid(atindx1,gmet,my_natom,natom,nattyp,ngfft,ntypat,&
     439                 :           2 : &   optcut,optgr0,optgr1,optgr2,optrad,local_pawfgrtab,pawtab,rprimd,typat,ucvol,xred)
     440                 :             :  end if
     441                 :             : !now local_pawfgrtab is ready to use
     442                 :             : 
     443                 :             : !Initialise output arrays.
     444   [ +  +  +  +  :      208907 :  rhor_paw=zero; rhor_n_one=zero; rhor_nt_one=zero
          +  +  +  +  +  
                +  +  + ]
     445                 :             : 
     446                 :             : !Initialise and check parallell execution
     447                 :           2 :  my_rank = xmpi_comm_rank(spaceComm_in)
     448                 :           2 :  nprocs = xmpi_comm_size(spaceComm_in)
     449                 :             : 
     450                 :             : 
     451                 :             : !loop over atoms in cell
     452         [ +  + ]:           6 :  do iatom = 1, my_natom
     453                 :           4 :    itypat = pawrhoij(iatom)%itypat
     454                 :           4 :    indlmn => pawtab(itypat)%indlmn
     455                 :           4 :    nfgd = local_pawfgrtab(iatom)%nfgd ! number of points in the fine grid for this PAW sphere
     456                 :           4 :    nnl = pawtab(itypat)%basis_size ! number of nl elements in PAW basis
     457                 :             : 
     458                 :             : !  Division of fine grid points among processors
     459         [ +  - ]:           4 :    if (nprocs==1) then ! Make sure everything runs with one proc
     460                 :           4 :      write(message,'(a)') '  In denfgr - number of processors:     1'
     461                 :           4 :      call wrtout(std_out,message,'COLL')
     462                 :           4 :      write(message,'(a)') '  Calculation of PAW density done in serial'
     463                 :           4 :      call wrtout(std_out,message,'COLL')
     464                 :           4 :      write(message,'(a,I6)') '  Number of fine grid points:',nfgd
     465                 :           4 :      call wrtout(std_out,message,'COLL')
     466                 :           4 :      my_start_indx = 1
     467                 :           4 :      my_end_indx = nfgd
     468                 :             :    else ! Divide up the fine grid points among the processors
     469                 :           0 :      write(message,'(a,I4)') '  In denfgr - number of processors: ',nprocs
     470                 :           0 :      call wrtout(std_out,message,'COLL')
     471                 :           0 :      write(message,'(a)') '  Calculation of PAW density done in parallel'
     472                 :           0 :      call wrtout(std_out,message,'COLL')
     473                 :           0 :      write(message,'(a,I6)') '  Number of fine grid points:',nfgd
     474                 :           0 :      call wrtout(std_out,message,'COLL')
     475                 :             : !    Divide the fine grid points among the processors
     476         [ #  # ]:           0 :      delta = int(floor(real(nfgd)/real(nprocs)))
     477                 :           0 :      remainder = nfgd-nprocs*delta
     478                 :           0 :      my_start_indx = 1+my_rank*delta
     479                 :           0 :      my_end_indx = (my_rank+1)*delta
     480                 :             : !    Divide the remainder points among the processors
     481                 :             : !    by shuffling indices
     482         [ #  # ]:           0 :      if ((my_rank+1)>remainder) then
     483                 :           0 :        my_start_indx = my_start_indx + remainder
     484                 :           0 :        my_end_indx = my_end_indx + remainder
     485                 :             :      else
     486                 :           0 :        my_start_indx = my_start_indx + my_rank
     487                 :           0 :        my_end_indx = my_end_indx + my_rank + 1
     488                 :             :      end if
     489         [ #  # ]:           0 :      if (prtvol>9) then
     490                 :           0 :        write(message,'(a,I6)') '  My index Starts at: ',my_start_indx
     491                 :           0 :        call wrtout(std_out,message,'PERS')
     492                 :           0 :        write(message,'(a,I6)') '             Ends at: ',my_end_indx
     493                 :           0 :        call wrtout(std_out,message,'PERS')
     494                 :           0 :        write(message,'(a,I6)') '               # pts: ',my_end_indx+1-my_start_indx
     495                 :           0 :        call wrtout(std_out,message,'PERS')
     496                 :             :      end if
     497                 :             :    end if
     498                 :             : 
     499                 :           4 :    write(message,'(a,I3,a,I3)') '  Entered loop for atom: ',iatom,' of:',natom
     500                 :           4 :    call wrtout(std_out,message,'PERS')
     501                 :             : 
     502                 :             : !  obtain |r-R| values on fine grid
     503   [ -  +  +  -  :          12 :    ABI_MALLOC(nrm,(nfgd))
          +  -  +  -  -  
                +  -  + ]
     504         [ +  + ]:        6852 :    do ifgd=1, nfgd
     505         [ +  + ]:       27396 :      nrm(ifgd) = sqrt(dot_product(local_pawfgrtab(iatom)%rfgd(:,ifgd),local_pawfgrtab(iatom)%rfgd(:,ifgd)))
     506                 :             :    end do ! these are the |r-R| values
     507                 :             : 
     508                 :             : !  compute Ylm for each r-R vector.
     509                 :             : !  ----
     510                 :           4 :    ipsang = 1 + (pawtab(itypat)%l_size - 1)/2 ! recall l_size=2*l_max+1
     511   [ -  +  +  -  :          16 :    ABI_MALLOC(ylm,(ipsang*ipsang,nfgd))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     512                 :           4 :    option = 1 ! compute Ylm(r-R) for vectors
     513                 :           4 :    normchoice = 1 ! use computed norms of input vectors
     514                 :           4 :    call initylmr(ipsang,normchoice,nfgd,nrm,option,local_pawfgrtab(iatom)%rfgd,ylm,ylmgr)
     515                 :             : 
     516                 :             : !  in order to do spline fits, the |r-R| data must be sorted
     517                 :             : !  ----
     518   [ -  +  +  -  :          12 :    ABI_MALLOC(nrm_ifftsph,(nfgd))
          +  -  +  -  -  
                +  -  + ]
     519         [ +  + ]:        6852 :    nrm_ifftsph(:) = local_pawfgrtab(iatom)%ifftsph(:) ! copy of indices of points, to be rearranged by sort_dp
     520                 :           4 :    call sort_dp(nfgd,nrm,nrm_ifftsph,tol8) ! sort the nrm points, keeping track of which goes where
     521                 :             : 
     522                 :             : !  now make spline fits of phi and tphi  onto the fine grid around the atom
     523                 :             : !  ----
     524   [ -  +  +  -  :          16 :    ABI_MALLOC(phigrd,(nfgd,nnl))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     525   [ -  +  +  -  :          12 :    ABI_MALLOC(tphigrd,(nfgd,nnl))
          -  +  +  -  -  
                +  -  + ]
     526   [ -  +  +  -  :          12 :    ABI_MALLOC(phi_at_zero,(nnl))
          +  -  +  -  -  
                +  -  + ]
     527   [ -  +  +  -  :           8 :    ABI_MALLOC(tphi_at_zero,(nnl))
             -  +  -  + ]
     528   [ -  +  +  -  :          12 :    ABI_MALLOC(ypp,(pawtab(itypat)%mesh_size))
          +  -  +  -  -  
                +  -  + ]
     529   [ -  +  +  -  :           8 :    ABI_MALLOC(diag,(pawtab(itypat)%mesh_size))
             -  +  -  + ]
     530                 :             : 
     531         [ +  + ]:          20 :    do inl = 1, nnl
     532                 :             : 
     533                 :             : !    spline phi onto points
     534   [ +  +  +  + ]:       19856 :      ypp(:) = zero; diag(:) = zero; ybcbeg = zero; ybcend = zero;
     535                 :          16 :      call spline(pawrad(itypat)%rad,pawtab(itypat)%phi(:,inl),pawtab(itypat)%mesh_size,ybcbeg,ybcend,ypp)
     536                 :          16 :      call splint(pawtab(itypat)%mesh_size,pawrad(itypat)%rad,pawtab(itypat)%phi(:,inl),ypp,nfgd,nrm,phigrd(:,inl))
     537                 :             : 
     538                 :             : !    next splint tphi onto points
     539   [ +  +  +  + ]:       19856 :      ypp(:) = zero; diag(:) = zero; ybcbeg = zero; ybcend = zero;
     540                 :          16 :      call spline(pawrad(itypat)%rad,pawtab(itypat)%tphi(:,inl),pawtab(itypat)%mesh_size,ybcbeg,ybcend,ypp)
     541                 :          16 :      call splint(pawtab(itypat)%mesh_size,pawrad(itypat)%rad,pawtab(itypat)%tphi(:,inl),ypp,nfgd,nrm,tphigrd(:,inl))
     542                 :             : 
     543                 :             : !    Find out the value of the basis function at zero using extrapolation
     544                 :          16 :      yvals = zero
     545                 :             : !    Extrapolate only if this is an s-state (l=0)
     546         [ +  + ]:          16 :      if (indlmn(1,inl)==0) then
     547         [ +  + ]:          32 :        yvals(2:4) = pawtab(itypat)%phi(2:4,inl)/pawrad(itypat)%rad(2:4)
     548                 :           8 :        call pawrad_deducer0(yvals,4,pawrad(itypat))
     549                 :           8 :        write(std_out,*) 'phi_at_zero: ',yvals(1),' from:',yvals(2:4)
     550                 :             :      end if
     551                 :          16 :      phi_at_zero(inl) = yvals(1)
     552                 :             : 
     553                 :          16 :      yvals = zero
     554                 :             : !    Extrapolate only if this is an s-state (l=0)
     555         [ +  + ]:          16 :      if (indlmn(1,inl)==0) then
     556         [ +  + ]:          32 :        yvals(2:4) = pawtab(itypat)%tphi(2:4,inl)/pawrad(itypat)%rad(2:4)
     557                 :           8 :        call pawrad_deducer0(yvals,4,pawrad(itypat))
     558                 :           8 :        write(std_out,*) 'tphi_at_zero: ',yvals(1),' from:',yvals(2:4)
     559                 :             :      end if
     560                 :          20 :      tphi_at_zero(inl) = yvals(1)
     561                 :             : 
     562                 :             :    end do ! end loop over nnl basis functions
     563         [ -  + ]:           4 :    ABI_FREE(ypp)
     564         [ -  + ]:           4 :    ABI_FREE(diag)
     565                 :             : 
     566                 :             : !  loop over basis elements for this atom
     567                 :             : !  because we have to store things like <phi|r'><r'|phi>-<tphi|r'><r'|tphi> at each point of the
     568                 :             : !  fine grid, there is no integration, and hence no simplifications of the Y_lm's. That's why
     569                 :             : !  we have to loop through the basis elements in exhaustive detail, rather than just a loop over
     570                 :             : !  lmn2_size or something comparable.
     571                 :             : !  ----
     572         [ -  + ]:           4 :    if (prtvol>9) then
     573                 :           0 :      write(message,'(a,I3)') '  Entering j-loop over basis elements for atom:',iatom
     574                 :           0 :      call wrtout(std_out,message,'PERS')
     575                 :             :    end if
     576                 :             : 
     577         [ +  + ]:          36 :    do jlmn=1,pawtab(itypat)%lmn_size
     578                 :             : 
     579         [ -  + ]:          32 :      if (prtvol>9) then
     580                 :           0 :        write(message,'(2(a,I3))') '  Element:',jlmn,' of:',pawtab(itypat)%lmn_size
     581                 :           0 :        call wrtout(std_out,message,'PERS')
     582                 :             :      end if
     583                 :             : 
     584                 :          32 :      jl=indlmn(1,jlmn)
     585                 :          32 :      jm=indlmn(2,jlmn)
     586                 :          32 :      jlm=indlmn(4,jlmn)
     587                 :          32 :      jln=indlmn(5,jlmn)
     588                 :          32 :      j0lmn=jlmn*(jlmn-1)/2
     589                 :             : 
     590         [ -  + ]:          32 :      if (prtvol>9) then
     591                 :           0 :        write(message,'(a,I3)') '  Entering i-loop for j:',jlmn
     592                 :           0 :        call wrtout(std_out,message,'PERS')
     593                 :             :      end if
     594                 :             : 
     595         [ +  + ]:         180 :      do ilmn=1,jlmn
     596                 :             : 
     597         [ -  + ]:         144 :        if (prtvol>9) then
     598                 :           0 :          write(message,'(2(a,I3))') '    Element:',ilmn,' of:',jlmn
     599                 :           0 :          call wrtout(std_out,message,'PERS')
     600                 :             :        end if
     601                 :             : 
     602                 :         144 :        il=indlmn(1,ilmn)
     603                 :         144 :        im=indlmn(2,ilmn)
     604                 :         144 :        iln=indlmn(5,ilmn)
     605                 :         144 :        ilm=indlmn(4,ilmn)
     606                 :         144 :        klmn=j0lmn+ilmn
     607                 :             : 
     608         [ -  + ]:         144 :        if (prtvol>9) then
     609                 :           0 :          write(message,'(a)') '    Entering loop over nonzero elems of rhoij'
     610                 :           0 :          call wrtout(std_out,message,'PERS')
     611                 :             :        end if
     612                 :             : 
     613                 :             : !      Loop over non-zero elements of rhoij
     614         [ +  + ]:        1904 :        do irhoij=1,pawrhoij(iatom)%nrhoijsel
     615         [ +  + ]:        1872 :          if (klmn==pawrhoij(iatom)%rhoijselect(irhoij)) then ! rho_ij /= 0 for this klmn
     616                 :             : 
     617         [ +  + ]:       82224 :            do ifgd=my_start_indx, my_end_indx ! loop over fine grid points in current PAW sphere
     618                 :       82176 :              ifftsph = local_pawfgrtab(iatom)%ifftsph(ifgd) ! index of the point on the grid
     619                 :             : 
     620                 :             : !            have to retrieve the spline point to use since these were sorted
     621         [ +  - ]:   113671320 :              do inrm=1, nfgd
     622         [ +  + ]:   113671320 :                if(nrm_ifftsph(inrm) == ifftsph) exit ! have found nrm point corresponding to nfgd point
     623                 :             :              end do ! now inrm is the index of the sorted nrm vector to use
     624                 :             : 
     625                 :             : !            avoid division by zero
     626         [ +  + ]:       82176 :              if(nrm(inrm) > zero) then
     627                 :       82140 :                rR = nrm(inrm) ! value of |r-R| in the following
     628                 :             : !              recall that <r|phi>=u(r)*Slm(r^)/r
     629                 :       82140 :                phj  = phigrd(inrm,jln)*ylm(jlm,ifgd)/rR
     630                 :       82140 :                phi  = phigrd(inrm,iln)*ylm(ilm,ifgd)/rR
     631                 :       82140 :                tphj = tphigrd(inrm,jln)*ylm(jlm,ifgd)/rR
     632                 :       82140 :                tphi = tphigrd(inrm,iln)*ylm(ilm,ifgd)/rR
     633                 :             :              else
     634                 :             : !              use precalculated <r|phi>=u(r)*Slm(r^)/r at r=0
     635                 :          36 :                phj  = phi_at_zero(jln)*ylm(jlm,ifgd)
     636                 :          36 :                phi  = phi_at_zero(iln)*ylm(ilm,ifgd)
     637                 :          36 :                tphj = tphi_at_zero(jln)*ylm(jlm,ifgd)
     638                 :          36 :                tphi = tphi_at_zero(iln)*ylm(ilm,ifgd)
     639                 :             :              end if ! check if |r-R| = 0
     640                 :             : 
     641         [ +  + ]:      237720 :              do ispden=1,nspden
     642         [ +  - ]:      237672 :                if (pawrhoij(iatom)%cplex_rhoij == 1) then
     643                 :             :                  rhor_paw(ifftsph,ispden) = rhor_paw(ifftsph,ispden) + &
     644                 :      155496 : &                 pawtab(itypat)%dltij(klmn)*pawrhoij(iatom)%rhoijp(irhoij,ispden)*(phj*phi - tphj*tphi)
     645                 :             : 
     646                 :             :                  rhor_n_one(ifftsph,ispden) = rhor_n_one(ifftsph,ispden) + &
     647                 :      155496 : &                 pawtab(itypat)%dltij(klmn)*pawrhoij(iatom)%rhoijp(irhoij,ispden)*phj*phi
     648                 :             : 
     649                 :             :                  rhor_nt_one(ifftsph,ispden) = rhor_nt_one(ifftsph,ispden) + &
     650                 :      155496 : &                 pawtab(itypat)%dltij(klmn)*pawrhoij(iatom)%rhoijp(irhoij,ispden)*tphj*tphi
     651                 :             :                else
     652                 :             :                  rhor_paw(ifftsph,ispden) = rhor_paw(ifftsph,ispden) + &
     653                 :           0 : &                 pawtab(itypat)%dltij(klmn)*pawrhoij(iatom)%rhoijp(2*irhoij-1,ispden)*(phj*phi - tphj*tphi)
     654                 :             : 
     655                 :             :                  rhor_n_one(ifftsph,ispden) = rhor_n_one(ifftsph,ispden) + &
     656                 :           0 : &                 pawtab(itypat)%dltij(klmn)*pawrhoij(iatom)%rhoijp(2*irhoij-1,ispden)*phj*phi
     657                 :             : 
     658                 :             :                  rhor_nt_one(ifftsph,ispden) = rhor_nt_one(ifftsph,ispden) + &
     659                 :           0 : &                 pawtab(itypat)%dltij(klmn)*pawrhoij(iatom)%rhoijp(2*irhoij-1,ispden)*tphj*tphi
     660                 :             :                end if ! end check on cplex rhoij
     661                 :             : 
     662                 :             :              end do ! end loop over nsdpen
     663                 :             :            end do ! end loop over nfgd
     664                 :             :          end if ! end selection on rhoij /= 0
     665                 :             :        end do ! end loop over non-zero rhoij
     666                 :             :      end do ! end loop over ilmn atomic basis states
     667                 :             :    end do ! end loop over jlmn atomic basis states
     668                 :             : 
     669         [ -  + ]:           4 :    ABI_FREE(nrm)
     670         [ -  + ]:           4 :    ABI_FREE(nrm_ifftsph)
     671         [ -  + ]:           4 :    ABI_FREE(phigrd)
     672         [ -  + ]:           4 :    ABI_FREE(tphigrd)
     673         [ -  + ]:           4 :    ABI_FREE(ylm)
     674         [ -  + ]:           4 :    ABI_FREE(phi_at_zero)
     675         [ -  + ]:           6 :    ABI_FREE(tphi_at_zero)
     676                 :             :  end do     ! Loop on atoms
     677                 :             : 
     678                 :             : !MPI sum on each node the different contributions to the PAW densities.
     679                 :           2 :  call xmpi_sum(rhor_paw,spaceComm_in,ierr)
     680                 :           2 :  call xmpi_sum(rhor_n_one,spaceComm_in,ierr)
     681                 :           2 :  call xmpi_sum(rhor_nt_one,spaceComm_in,ierr)
     682         [ -  + ]:           2 :  if (paral_atom) then
     683                 :           0 :    call xmpi_sum(rhor_paw,my_comm_atom,ierr)
     684                 :           0 :    call xmpi_sum(rhor_n_one,my_comm_atom,ierr)
     685                 :           0 :    call xmpi_sum(rhor_nt_one,my_comm_atom,ierr)
     686                 :             :  end if
     687                 :             : 
     688                 :           2 :  call wrtout(std_out,' *** Partial contributions to PAW rhor summed ***','PERS')
     689                 :           2 :  call xmpi_barrier(spaceComm_in)
     690                 :             : 
     691                 :             : !Add the plane-wave contribution \tilde{n} and remove \hat{n}
     692                 :             : !BE careful here since the storage mode of rhoij and rhor is different.
     693                 :           4 :  select case (nspinor)
     694                 :             :  case (1)
     695         [ +  + ]:           2 :    if (nsppol==1)  then
     696   [ +  +  +  + ]:        4098 :      rhor_paw = rhor_paw + rhor - nhat
     697                 :             :    else  ! Spin-polarised case: rhor_paw contains rhor_paw(spin_up,spin_down) but we need rhor_paw(total,spin_up)
     698   [ -  +  +  -  :           3 :      ABI_MALLOC(tot_rhor,(pawfgr%nfft))
          +  -  +  -  -  
                +  -  + ]
     699                 :             : !
     700                 :             : !      AE rhor
     701   [ +  +  +  + ]:       98305 :      tot_rhor(:) = SUM(rhor_paw,DIM=2)
     702         [ +  + ]:       32769 :      rhor_paw(:,2) = rhor_paw(:,1)
     703         [ +  + ]:       32769 :      rhor_paw(:,1) = tot_rhor
     704   [ +  +  +  + ]:       65539 :      rhor_paw = rhor_paw + rhor - nhat
     705                 :             : !
     706                 :             : !      onsite AE rhor
     707   [ +  +  +  + ]:       98305 :      tot_rhor(:) = SUM(rhor_n_one,DIM=2)
     708         [ +  + ]:       32769 :      rhor_n_one(:,2) = rhor_n_one(:,1)
     709         [ +  + ]:       32769 :      rhor_n_one(:,1) = tot_rhor
     710                 :             : !
     711                 :             : !      onsite PS rhor
     712   [ +  +  +  + ]:       98305 :      tot_rhor(:) = SUM(rhor_nt_one,DIM=2)
     713         [ +  + ]:       32769 :      rhor_nt_one(:,2) = rhor_nt_one(:,1)
     714         [ +  + ]:       32769 :      rhor_nt_one(:,1) = tot_rhor
     715                 :             : 
     716         [ -  + ]:           1 :      ABI_FREE(tot_rhor)
     717                 :             :    end if
     718                 :             : 
     719                 :             :  case (2)
     720                 :             : !    * if nspden==4, rhor contains (n^11, n^22, Re[n^12], Im[n^12].
     721                 :             : !    Storage mode for rhoij is different, See pawaccrhoij.
     722                 :           0 :    ABI_ERROR("nspinor 2 not coded")
     723                 :             :  case default
     724                 :           0 :    write(message,'(a,i0)')" Wrong value for nspinor=",nspinor
     725      [ +  -  - ]:           2 :    ABI_ERROR(message)
     726                 :             :  end select
     727                 :             : 
     728                 :             : !if (prtvol>9) then ! Check normalisation
     729                 :             : !write(message,'(a,F8.4)') '  PAWDEN - NORM OF DENSITY: ',SUM(rhor_paw(:,1))*ucvol/PRODUCT(pawfgr%ngfft(1:3))
     730                 :             : !call wrtout(std_out,message,'COLL')
     731                 :             : !end if
     732                 :             : 
     733         [ -  + ]:           2 :  if (present(abs_n_tilde_nt_diff).AND.present(znucl)) then
     734   [ #  #  #  #  :           0 :    ABI_MALLOC(rhor_tmp,(pawfgr%nfft,nspden))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     735         [ #  # ]:           0 :    do ispden=1,nspden
     736         [ #  # ]:           0 :      rhor_tmp(:,ispden) = zero
     737         [ #  # ]:           0 :      do iatom=1,my_natom
     738         [ #  # ]:           0 :        do ifgd=1,local_pawfgrtab(iatom)%nfgd ! loop over fine grid points in current PAW sphere
     739                 :           0 :          ifftsph = local_pawfgrtab(iatom)%ifftsph(ifgd) ! index of the point on the grid
     740                 :             :          rhor_tmp(ifftsph,ispden) = rhor(ifftsph,ispden) - nhat(ifftsph,ispden) &
     741                 :           0 : &         - rhor_nt_one(ifftsph,ispden)
     742                 :             :        end do !ifgd
     743                 :             :      end do ! iatom
     744                 :             :    end do ! ispden
     745         [ #  # ]:           0 :    if (paral_atom) then
     746                 :           0 :      call xmpi_sum(rhor_tmp,my_comm_atom,ierr)
     747                 :             :    end if
     748                 :             : 
     749         [ #  # ]:           0 :    if (my_rank==master) then
     750         [ #  # ]:           0 :      do ispden=1,nspden
     751                 :             : !      Write to xsf file
     752                 :           0 :        call xred2xcart(natom,rprimd,xcart,xred)
     753                 :           0 :        write(xsf_fname,'(a,I0,a)') 'N_tilde_onsite_diff_sp',ispden,'.xsf'
     754         [ #  # ]:           0 :        if (open_file(xsf_fname,message, unit=tmp_unt,status='unknown',form='formatted') /= 0) then
     755                 :           0 :          ABI_ERROR(message)
     756                 :             :        end if
     757                 :             :        call printxsf(ngfft(1),ngfft(2),ngfft(3),rhor_tmp(:,ispden),rprimd,&
     758                 :           0 : &       (/zero,zero,zero/),natom,ntypat,typat,xcart,znucl,tmp_unt,0)
     759                 :           0 :        close(tmp_unt)
     760         [ #  # ]:           0 :        abs_n_tilde_nt_diff(ispden) = SUM(ABS(rhor_tmp(:,ispden)))/pawfgr%nfft
     761                 :           0 :        write(message,'(4(a),F16.9,2(a,I0),a)') ch10,'  Wrote xsf file with \tilde{n}-\tilde{n}^1.',ch10,&
     762                 :           0 : &       '  Value of norm |\tilde{n}-\tilde{n}^1|:',&
     763                 :           0 : &       abs_n_tilde_nt_diff(ispden),' spin: ',ispden,' of ',nspden,ch10
     764                 :           0 :        call wrtout(std_out,message,'COLL')
     765                 :             :      end do
     766                 :             :    end if
     767         [ #  # ]:           0 :    ABI_FREE(rhor_tmp)
     768                 :             : 
     769                 :             :  else if ((present(abs_n_tilde_nt_diff).AND.(.NOT.present(znucl))) &
     770         [ -  + ]:           2 : &   .OR.(.NOT.present(abs_n_tilde_nt_diff).AND.(present(znucl)))) then
     771                 :           0 :    write(message,'(a)') ' Both abs_n_tilde_nt_diff *and* znucl must be passed',ch10,&
     772                 :           0 : &   'to denfgr for |\tilde{n}-\tilde{n}^1| norm evaluation.'
     773                 :           0 :    ABI_ERROR(message)
     774                 :             :  end if
     775                 :             : 
     776                 :           2 :  call pawfgrtab_free(local_pawfgrtab)
     777                 :             : 
     778                 :             : !Destroy atom table used for parallelism
     779                 :           2 :  call free_my_atmtab(my_atmtab,my_atmtab_allocated)
     780                 :             : 
     781                 :           2 :  call xmpi_barrier(spaceComm_in)
     782                 :             : 
     783                 :             :  DBG_EXIT("COLL")
     784                 :             : 
     785   [ -  +  -  + ]:           8 :  end subroutine denfgr
     786                 :             : !!***
     787                 :             : 
     788                 :             : !----------------------------------------------------------------------
     789                 :             : 
     790                 :             : END MODULE m_paw_mkrho
     791                 :             : !!***
        

Generated by: LCOV version 2.3-1