TABLE OF CONTENTS
ABINIT/mkdenpos [ Functions ]
NAME
mkdenpos
FUNCTION
Make a ground-state density positive everywhere : when the density (or spin-density) is smaller than xc_denpos, set it to the value of xc_denpos
COPYRIGHT
Copyright (C) 1998-2018 ABINIT group (DCA, XG, GMR) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
INPUTS
nfft=(effective) number of FFT grid points (for this processor) nspden=number of spin-density components (max. 2) option=0 if density rhonow is stored as (up,dn) 1 if density rhonow is stored as (up+dn,up) Active only when nspden=2 xc_denpos= lowest allowed density (usually for the computation of the XC functionals)
OUTPUT
(see side effects)
SIDE EFFECTS
Input/output iwarn=At input: iwarn=0 a warning will be printed when rho is negative iwarn>0 no warning will be printed out At output: iwarn is increased by 1 rhonow(nfft,nspden)=electron (spin)-density in real space, either on the unshifted grid (if ishift==0, then equal to rhor),or on the shifted grid
NOTES
At this stage, rhonow(:,1:nspden) contains the density in real space, on the unshifted or shifted grid. Now test for negative densities Note that, ignoring model core charge, as long as boxcut>=2 the shifted density is derivable from the square of a Fourier interpolated charge density => CANNOT go < 0. However, actually can go < 0 to within machine precision; do not print useless warnings in this case, just fix it. Fourier interpolated core charge can go < 0 due to Gibbs oscillations; could avoid this by recomputing the model core charge at the new real space grid points (future work).
PARENTS
bethe_salpeter,m_pawxc,mkcore_wvl,posdoppler,poslifetime,posratecore psolver_rhohxc,rhohxcpositron,rhotoxc,wvl_initro
CHILDREN
SOURCE
58 #if defined HAVE_CONFIG_H 59 #include "config.h" 60 #endif 61 62 #include "abi_common.h" 63 64 65 subroutine mkdenpos(iwarn,nfft,nspden,option,rhonow,xc_denpos) 66 67 use defs_basis 68 use m_profiling_abi 69 use m_errors 70 71 !This section has been created automatically by the script Abilint (TD). 72 !Do not modify the following lines by hand. 73 #undef ABI_FUNC 74 #define ABI_FUNC 'mkdenpos' 75 !End of the abilint section 76 77 implicit none 78 79 !Arguments ------------------------------------ 80 !scalars 81 integer,intent(in) :: nfft,nspden,option 82 integer,intent(inout) :: iwarn 83 real(dp),intent(in) :: xc_denpos 84 !arrays 85 real(dp),intent(inout) :: rhonow(nfft,nspden) 86 87 !Local variables------------------------------- 88 !scalars 89 integer :: ifft,ispden,numneg 90 real(dp) :: rhotmp,worst 91 character(len=500) :: message 92 !arrays 93 real(dp) :: rho(2) 94 95 ! ************************************************************************* 96 97 numneg=0 98 worst=zero 99 100 if(nspden==1)then 101 102 ! Non spin-polarized 103 !$OMP PARALLEL DO PRIVATE(ifft,rhotmp) REDUCTION(MIN:worst) REDUCTION(+:numneg) SHARED(nfft,rhonow) 104 do ifft=1,nfft 105 rhotmp=rhonow(ifft,1) 106 if(rhotmp<xc_denpos)then 107 if(rhotmp<-xc_denpos)then 108 ! This case is probably beyond machine precision considerations 109 worst=min(worst,rhotmp) 110 numneg=numneg+1 111 end if 112 rhonow(ifft,1)=xc_denpos 113 end if 114 end do 115 else if (nspden==2) then 116 117 ! Spin-polarized 118 119 ! rhonow is stored as (up,dn) 120 if (option==0) then 121 122 !$OMP PARALLEL DO PRIVATE(ifft,ispden,rho,rhotmp) REDUCTION(MIN:worst) REDUCTION(+:numneg) & 123 !$OMP&SHARED(nfft,nspden,rhonow) 124 do ifft=1,nfft 125 ! For polarized case, rho(1) is spin-up density, rho(2) is spin-down density 126 rho(1)=rhonow(ifft,1) 127 rho(2)=rhonow(ifft,2) 128 do ispden=1,nspden 129 if (rho(ispden)<xc_denpos) then 130 if (rho(ispden)<-xc_denpos) then 131 ! This case is probably beyond machine precision considerations 132 worst=min(worst,rho(ispden)) 133 numneg=numneg+1 134 end if 135 rhonow(ifft,ispden)=xc_denpos 136 end if 137 end do 138 end do 139 140 ! rhonow is stored as (up+dn,up) 141 else if (option==1) then 142 143 !$OMP PARALLEL DO PRIVATE(ifft,ispden,rho,rhotmp) & 144 !$OMP&REDUCTION(MIN:worst) REDUCTION(+:numneg) & 145 !$OMP&SHARED(nfft,nspden,rhonow) 146 do ifft=1,nfft 147 ! For polarized case, rho(1) is spin-up density, rho(2) is spin-down density 148 rho(1)=rhonow(ifft,2) 149 rho(2)=rhonow(ifft,1)-rho(1) 150 do ispden=1,nspden 151 if (rho(ispden)<xc_denpos) then 152 if (rho(ispden)<-xc_denpos) then 153 ! This case is probably beyond machine precision considerations 154 worst=min(worst,rho(ispden)) 155 numneg=numneg+1 156 end if 157 rho(ispden)=xc_denpos 158 rhonow(ifft,1)=rho(1)+rho(2) 159 rhonow(ifft,2)=rho(1) 160 end if 161 end do 162 end do 163 164 end if ! option 165 166 else 167 MSG_BUG('nspden>2 not allowed !') 168 end if ! End choice between non-spin polarized and spin-polarized. 169 170 if (numneg>0) then 171 if (iwarn==0) then 172 write(message,'(a,i0,a,a,a,es10.2,a,e10.2,a,a,a,a)')& 173 & 'Density went too small (lower than xc_denpos) at ',numneg,' points',ch10,& 174 & 'and was set to xc_denpos = ',xc_denpos,'. Lowest was ',worst,'.',ch10,& 175 & 'Likely due to too low boxcut or too low ecut for',' pseudopotential core charge.' 176 MSG_WARNING(message) 177 end if 178 iwarn=iwarn+1 179 end if 180 181 end subroutine mkdenpos