TABLE OF CONTENTS
ABINIT/prcref_PMA [ Functions ]
NAME
prcref_PMA
FUNCTION
Compute preconditioned residual potential (or density) and forces. iprcel, densfor_pred and iprcfc govern the choice of the preconditioner. Three tasks are done : 1) Preconditioning of the forces (residual has already been included) using the approximate force constant matrix. Get proposed change of atomic positions. 2) Precondition the residual, get first part of proposed trial potential change. 3) PAW only: precondition the rhoij residuals (simple preconditionning) 4) Take into account the proposed change of atomic positions to modify the proposed trial potential change. NOTE This routine is almost similar to prcref.F90 which is employed in case of density mixing. Yet it has undergone strong changes simultaneously from two different sources at the same time which resulted in a splitting.
COPYRIGHT
Copyright (C) 1998-2018 ABINIT group (DCA,XG,MT) 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
atindx(natom)=index table for atoms (see gstate.f) dielar(7)=input parameters for dielectric matrix: diecut,dielng,diemac,diemix,diegap,dielam,diemixmag. dielstrt=number of the step at which the dielectric preconditioning begins. dtset <type(dataset_type)>=all input variables in this dataset | intxc=control xc quadrature | densfor_pred= not yet used here | iprcel= governs the preconditioning of the potential residual | 0 => simple model dielectric matrix, described by the | parameters dielng, diemac, diemix and diemixmag contained in dielar. | between 21 and 39 => until istep=dielstart, same as iprcel=0, then uses | the RPA dielectric matrix (routine dielmt) | between 41 and 49 => uses the RPA dielectric matrix (routine dielmt). | between 51 and 59 => uses the RPA dielectric matrix (routine dieltcel). | between 61 and 69 => uses the electronic dielectric matr (routine dieltcel). | between 71 and 79 => uses the real-space preconditioner based on Kerker prc (prcrskerkerN) | between 81 and 99 => reserved for futur version of the real-space preconditioner | between 141 and 169 -> same as between 41 and 69 but with a different periodicity: modulo(iprcel modulo (10)) | iprcfc= governs the preconditioning of the forces | 0 => hessian is the identity matrix | 1 => hessian is 0.5 times the identity matrix | 2 => hessian is 0.25 times the identity matrix | ixc=exchange-correlation choice parameter. | natom=number of atoms | nspden=number of spin-density components | occopt=option for occupancies | prtvol=control print volume and debugging | typat(natom)=integer type for each atom in cell fcart(3,natom)=cartesian forces (hartree/bohr) ffttomix(nfft*(1-nfftprc/nfft))=Index of the points of the FFT (fine) grid on the grid used for mixing (coarse) gmet(3,3)=metrix tensor in G space in Bohr**-2. gsqcut=cutoff on (k+G)^2 (bohr^-2) istep= number of the step in the SCF cycle kg_diel(3,npwdiel)=reduced planewave coordinates for the dielectric matrix. mgfft=maximum size of 1D FFTs moved_atm_inside= if 1, then the preconditioned forces as well as the preconditioned potential residual must be computed; otherwise, compute only the preconditioned potential residual. mpi_enreg=information about MPI parallelization my_natom=number of atoms treated by current processor nattyp(ntypat)=number of atoms of each type in cell. nfft=number of fft grid points nfftprc=size of FFT grid on which the potential residual will be preconditionned ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft ngfftprc(18)=contain all needed information about 3D FFT for the grid corresponding to nfftprc nkxc=second dimension of the array kxc, see rhotoxc.f for a description npawmix=-PAW only- number of spherical part elements to be mixed npwdiel=number of planewaves for dielectric matrix ntypat=number of types of atoms in cell. n1xccc=dimension of xccc1d ; 0 if no XC core correction is used optreal=1 if residual potential is is REAL space, 2 if it is in RECIPROCAL SPACE optres=0: the array vresid contains a potential residual 1: the array vresid contains a density residual pawrhoij(my_natom) <type(pawrhoij_type)>= paw rhoij occupancies and related data Use here rhoij residuals (and gradients) psps <type(pseudopotential_type)>=variables related to pseudopotentials rhog(2,nfft)=array for electron density in reciprocal space rhor(nfft,nspden)=array for electron density in electrons/bohr**3. rprimd(3,3)=dimensional primitive translations in real space (bohr) susmat(2,npwdiel,nspden,npwdiel,nspden)= the susceptibility (or density-density response) matrix in reciprocal space vresid(optreal*nfftprc,nspden)=residual potential vxc(nfft,nspden)=exchange-correlation potential (hartree) vhartr(nfft)=array for holding Hartree potential vlspl(mqgrid,2,ntypat)=q^2 v(q) spline for each type of atom. vpsp(nfft)=array for holding local psp xred(3,natom)=reduced dimensionless atomic coordinates etotal pawtab
OUTPUT
dtn_pc(3,natom)=preconditioned change of atomic position, in reduced coordinates vrespc(optreal*nfftprc,nspden)=preconditioned residual of the potential ==== if psps%usepaw==1 rhoijrespc(npawmix)= preconditionned rhoij residuals at output SIDE EFFECT dielinv(2,npwdiel,nspden,npwdiel,nspden)= inverse of the dielectric matrix in rec. space kxc(nfft,nkxc)=exchange-correlation kernel, needed if the electronic dielectric matrix is computed ===== if densfor_pred==3 .and. moved_atm_inside==1 ===== ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phases
PARENTS
newvtr
CHILDREN
atm2fft,dielmt,dieltcel,fourdp,fresid,getph,hartre indirect_parallel_fourier,kgindex,mean_fftr,metric,mkcore,mklocl moddiel,prcrskerker1,prcrskerker2,rhotoxc,testsusmat,xcart2xred xcdata_init,xmpi_sum,zerosym
SOURCE
130 #if defined HAVE_CONFIG_H 131 #include "config.h" 132 #endif 133 134 #include "abi_common.h" 135 136 subroutine prcref_PMA(atindx,dielar,dielinv,& 137 & dielstrt,dtn_pc,dtset,fcart,ffttomix,gmet,gsqcut,& 138 & istep,kg_diel,kxc,& 139 & mgfft,moved_atm_inside,mpi_enreg,my_natom,& 140 & nattyp,nfft,nfftprc,ngfft,ngfftprc,nkxc,npawmix,npwdiel,ntypat,n1xccc,& 141 & optreal,optres,pawrhoij,ph1d,psps,rhog, rhoijrespc,rhor,rprimd,& 142 & susmat,vhartr,vpsp,vresid,vrespc,vxc,xred,& 143 & etotal,pawtab,wvl) 144 145 use defs_basis 146 use defs_datatypes 147 use defs_abitypes 148 use defs_wvltypes 149 use m_errors 150 use m_profiling_abi 151 use m_xmpi 152 use m_cgtools 153 use m_xcdata 154 155 use m_geometry, only : xcart2xred, metric 156 use m_pawtab, only : pawtab_type 157 use m_pawrhoij, only : pawrhoij_type 158 use m_fft, only : zerosym 159 use m_kg, only : getph 160 use m_dtset, only : testsusmat 161 162 !This section has been created automatically by the script Abilint (TD). 163 !Do not modify the following lines by hand. 164 #undef ABI_FUNC 165 #define ABI_FUNC 'prcref_PMA' 166 use interfaces_52_fft_mpi_noabirule 167 use interfaces_53_ffts 168 use interfaces_56_xc 169 use interfaces_64_psp 170 use interfaces_67_common 171 use interfaces_68_rsprc, except_this_one => prcref_PMA 172 !End of the abilint section 173 174 implicit none 175 176 !Arguments------------------------------- 177 !variables used for tfvw 178 !scalars 179 integer,intent(in) :: dielstrt,istep,mgfft,moved_atm_inside,my_natom,n1xccc 180 integer,intent(in) :: nfft,nfftprc,nkxc,npawmix,npwdiel,ntypat 181 integer,intent(in) :: optreal,optres 182 real(dp),intent(in) :: etotal,gsqcut 183 type(MPI_type),intent(in) :: mpi_enreg 184 type(dataset_type),intent(in) :: dtset 185 type(pseudopotential_type),intent(in) :: psps 186 type(wvl_data), intent(inout) :: wvl 187 !arrays 188 integer,intent(in) :: atindx(dtset%natom),ffttomix(nfft*(1-nfftprc/nfft)) 189 integer,intent(in) :: kg_diel(3,npwdiel),nattyp(ntypat),ngfft(18),ngfftprc(18) 190 real(dp),intent(in) :: dielar(7),fcart(3,dtset%natom) 191 real(dp),intent(in) :: rhog(2,nfft) 192 real(dp),intent(in) :: rhor(nfft,dtset%nspden),rprimd(3,3) 193 real(dp),intent(in) :: susmat(2,npwdiel,dtset%nspden,npwdiel,dtset%nspden) 194 real(dp),intent(in) :: vhartr(nfft),vresid(nfftprc*optreal,dtset%nspden) 195 real(dp),intent(in) :: vxc(nfft,dtset%nspden) 196 real(dp),intent(inout) :: dielinv(2,npwdiel,dtset%nspden,npwdiel,dtset%nspden) 197 real(dp),intent(inout) :: gmet(3,3),kxc(nfft,nkxc) 198 real(dp),intent(inout) :: ph1d(2,3*(2*mgfft+1)*dtset%natom),vpsp(nfft) 199 real(dp),intent(inout) :: xred(3,dtset%natom) 200 real(dp),intent(out) :: dtn_pc(3,dtset%natom),rhoijrespc(npawmix) 201 real(dp),intent(out) :: vrespc(nfftprc*optreal,dtset%nspden) 202 type(pawrhoij_type),intent(inout) :: pawrhoij(my_natom*psps%usepaw) 203 type(pawtab_type),intent(in) :: pawtab(ntypat*psps%usepaw) 204 205 !Local variables------------------------------- 206 !scalars 207 integer :: coredens_method,cplex,dielop,iatom,ier,ifft,ii,index,ipw1 208 integer :: ipw2,ispden,klmn,kmix,n1,n2,n3,n3xccc,nfftot,nk3xc,optatm 209 integer :: optdyfr,opteltfr,optgr,option,optn,optn2,optstr,optv,vloc_method 210 real(dp) :: ai,ar,diemix,diemixmag,eei,enxc 211 real(dp) :: mixfac 212 real(dp) :: mixfac_eff,mixfacmag,ucvol,vxcavg 213 logical :: computediel 214 logical :: non_magnetic_xc 215 character(len=500) :: message 216 type(xcdata_type) :: xcdata 217 !arrays 218 integer :: qprtrb(3) 219 integer,allocatable :: indpw_prc(:) 220 real(dp) :: dummy6(6),gprimd(3,3),qphon(3),rmet(3,3),strsxc(6) 221 real(dp) :: vmean(dtset%nspden),vprtrb(2) 222 real(dp),allocatable :: dummy_in(:) 223 real(dp) :: dummy_out1(0),dummy_out2(0),dummy_out3(0),dummy_out4(0),dummy_out5(0),dummy_out6(0),dummy_out7(0) 224 real(dp),allocatable :: dyfrlo_indx(:,:,:),dyfrx2(:,:,:) 225 real(dp),allocatable :: fcart_pc(:,:),gresid(:,:),grtn_indx(:,:) 226 real(dp),allocatable :: grxc(:,:),grxc_indx(:,:),rhog_wk(:,:) 227 real(dp),allocatable :: rhor_wk(:,:),rhor_wk0(:,:),vhartr_wk(:),vpsp_wk(:) 228 real(dp),allocatable :: vres_diel(:,:),vxc_wk(:,:),work(:),work1(:,:),work2(:) 229 real(dp),allocatable :: work3(:,:),xccc3d(:),xred_wk(:,:) 230 logical,allocatable :: mask(:) 231 232 ! ************************************************************************* 233 234 if(optres==1)then 235 MSG_ERROR('density mixing (optres=1) not admitted!') 236 end if 237 238 !Compute different geometric tensor, as well as ucvol, from rprimd 239 call metric(gmet,gprimd,-1,rmet,rprimd,ucvol) 240 241 ! Initialise non_magnetic_xc for rhohxc 242 non_magnetic_xc=(dtset%usepawu==4).or.(dtset%usepawu==14) 243 244 !1) Eventually take care of the forces 245 246 if(moved_atm_inside==1)then 247 ABI_ALLOCATE(fcart_pc,(3,dtset%natom)) 248 249 if(dtset%iprcfc==0)then 250 fcart_pc(:,:)=fcart(:,:) 251 else 252 fcart_pc(:,:)= (two**dtset%iprcfc) * fcart(:,:) 253 end if 254 255 ! Compute preconditioned delta xred from preconditioned fcart and rprimd 256 call xcart2xred(dtset%natom,rprimd,fcart_pc,dtn_pc) 257 258 ABI_DEALLOCATE(fcart_pc) 259 end if 260 261 !####################################################################### 262 263 !2) Take care of the potential residual 264 265 !Compute the residuals corresponding to the solution 266 !of an approximate realspace dielectric function according 267 !to X. Gonze PRB vol54 nb7 p4383 (1996) 268 if(dtset%iprcel>=71.and.dtset%iprcel<=79) then 269 if (nfft==nfftprc) then 270 if (dtset%iprcel<=78) then 271 call prcrskerker1(dtset,mpi_enreg,nfft,dtset%nspden,ngfft,dielar,etotal, & 272 & gprimd,vresid,vrespc,rhor(:,1)) 273 else 274 call prcrskerker2(dtset,nfft,dtset%nspden,ngfft,dielar,gprimd,rprimd, & 275 & vresid,vrespc,dtset%natom,xred,mpi_enreg,ucvol) 276 end if 277 else 278 ! If preconditionning has to be done on a coarse grid, 279 ! has to transfer several arrays 280 ABI_ALLOCATE(work1,(nfftprc,dtset%nspden)) 281 ABI_ALLOCATE(work3,(nfftprc,dtset%nspden)) 282 ABI_ALLOCATE(work,(2*nfftprc)) 283 do ispden=1,dtset%nspden 284 work(:)=vresid(:,ispden) 285 call fourdp(1,work,work1(:,ispden),+1,mpi_enreg,nfftprc,ngfftprc,dtset%paral_kgb,0) 286 end do 287 ABI_DEALLOCATE(work) 288 if (dtset%iprcel<=78) then 289 ABI_ALLOCATE(rhog_wk,(2,nfftprc)) 290 rhog_wk(:,:)=zero 291 if (mpi_enreg%nproc_fft>1.and. mpi_enreg%paral_kgb==1) then 292 nfftot=PRODUCT(ngfft(1:3)) 293 call indirect_parallel_Fourier(ffttomix,rhog_wk,mpi_enreg,ngfftprc,& 294 & ngfft,nfftprc,nfft,dtset%paral_kgb,rhog,nfftot) 295 else 296 do ii=1,nfft 297 if (ffttomix(ii)>0) rhog_wk(:,ffttomix(ii))=rhog(:,ii) 298 end do 299 end if 300 call zerosym(rhog_wk,2,ngfftprc(1),ngfftprc(2),ngfftprc(3),& 301 & comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft) 302 ABI_ALLOCATE(work,(nfftprc)) 303 call fourdp(1,rhog_wk,work,+1,mpi_enreg,nfftprc,ngfftprc,dtset%paral_kgb,0) 304 call prcrskerker1(dtset,mpi_enreg,nfftprc,dtset%nspden,ngfftprc,dielar,etotal, & 305 & gprimd,work1,work3,work) 306 ABI_DEALLOCATE(work) 307 else 308 call prcrskerker2(dtset,nfftprc,dtset%nspden,ngfftprc,dielar,gprimd,rprimd, & 309 & work1,work3,dtset%natom,xred,mpi_enreg,ucvol) 310 end if 311 do ispden=1,dtset%nspden 312 call fourdp(1,vrespc(:,ispden),work3(:,ispden),-1,mpi_enreg,nfftprc,ngfftprc,dtset%paral_kgb,0) 313 end do 314 ABI_DEALLOCATE(work1) 315 ABI_DEALLOCATE(work3) 316 end if 317 318 else 319 320 if(dtset%iprcel==0 .or. (dtset%iprcel<40.and.istep<dielstrt) )then 321 cplex=optreal 322 qphon(:)=zero 323 ! Simple scalar multiplication, or model dielectric function 324 call moddiel(cplex,dielar,mpi_enreg,nfftprc,ngfftprc,dtset%nspden,optreal,optres,dtset%paral_kgb,qphon,rprimd,vresid,vrespc) 325 326 ! Use the inverse dielectric matrix in a small G sphere 327 else if( (istep>=dielstrt .and. dtset%iprcel>=21) .or. modulo(dtset%iprcel,100)>=41 )then 328 329 ! Wnith dielop=1, the matrices will be computed when istep=dielstrt 330 ! With dielop=2, the matrices will be computed when istep=dielstrt and 1 331 dielop=1 332 if(modulo(dtset%iprcel,100)>=41)dielop=2 333 call testsusmat(computediel,dielop,dielstrt,dtset,istep) !test if the matrix is to be computed 334 if(computediel) then 335 ! Compute the inverse dielectric matrix from the susceptibility matrix 336 ! There are two routines for the RPA matrix, while for the electronic 337 ! dielectric matrix, only dieltcel will do the work 338 if(modulo(dtset%iprcel,100)<=49)then 339 call dielmt(dielinv,gmet,kg_diel,& 340 & npwdiel,dtset%nspden,dtset%occopt,dtset%prtvol,susmat) 341 else 342 option=1 343 if(modulo(dtset%iprcel,100)>=61)option=2 344 call dieltcel(dielinv,gmet,kg_diel,kxc,& 345 & nfft,ngfft,nkxc,npwdiel,dtset%nspden,dtset%occopt,option,dtset%paral_kgb,dtset%prtvol,susmat) 346 end if 347 end if 348 349 ABI_ALLOCATE(work1,(2,nfftprc)) 350 ABI_ALLOCATE(work2,(optreal*nfftprc)) 351 352 ! Presently, one uses the inverse of the RPA dielectric matrix, 353 ! for which spin must be averaged. 354 355 ! Do fft from real space (work2) to G space (work1) 356 if (optreal==1) then 357 work2(:)=vresid(:,1) 358 ! Must average over spins if needed. 359 if(dtset%nspden/=1)work2(:)=(work2(:)+vresid(:,2))*half 360 call fourdp(1,work1,work2,-1,mpi_enreg,nfftprc,ngfftprc,dtset%paral_kgb,0) 361 else 362 work1(:,:)=reshape(vresid(:,1),(/2,nfftprc/)) 363 if (dtset%nspden/=1) work1(:,:)=(work1(:,:)+reshape(vresid(:,2),(/2,nfftprc/)))*half 364 end if 365 366 ! Multiply by restricted inverse of dielectric matrix. 367 ! Must first copy relevant elements of work1 to a npwdiel-dimensioned array, 368 ! then zero work1, operate with the dielinv matrix, and store in work1. 369 370 ABI_ALLOCATE(vres_diel,(2,npwdiel)) 371 ABI_ALLOCATE(indpw_prc,(npwdiel)) 372 ABI_ALLOCATE(mask,(npwdiel)) 373 mask(:)=.true. 374 call kgindex(indpw_prc,kg_diel,mask,mpi_enreg,ngfftprc,npwdiel) 375 do ipw1=1,npwdiel 376 if(mask(ipw1)) then 377 vres_diel(1,ipw1)=work1(1,indpw_prc(ipw1)) 378 vres_diel(2,ipw1)=work1(2,indpw_prc(ipw1)) 379 end if 380 end do 381 382 work1(:,:)=zero 383 do ipw1=1,npwdiel 384 ar=zero ; ai=zero 385 386 ! Use inverse of dielectric matrix (potential mixing) 387 do ipw2=1,npwdiel 388 if(mask(ipw2))then 389 ar=ar+dielinv(1,ipw1,1,ipw2,1)*vres_diel(1,ipw2) & 390 & -dielinv(2,ipw1,1,ipw2,1)*vres_diel(2,ipw2) 391 ai=ai+dielinv(2,ipw1,1,ipw2,1)*vres_diel(1,ipw2) & 392 & +dielinv(1,ipw1,1,ipw2,1)*vres_diel(2,ipw2) 393 end if 394 end do 395 ! Must be careful not to count the diagonal 1 twice : it is added later, 396 ! so must be subtracted now. 397 call xmpi_sum(ar,mpi_enreg%comm_fft,ier) 398 call xmpi_sum(ai,mpi_enreg%comm_fft,ier) 399 if(mask(ipw1)) then 400 work1(1,indpw_prc(ipw1))=ar-vres_diel(1,ipw1) 401 work1(2,indpw_prc(ipw1))=ai-vres_diel(2,ipw1) 402 end if !mask(ipw1) 403 end do ! ipw1 404 ABI_DEALLOCATE(vres_diel) 405 ABI_DEALLOCATE(indpw_prc) 406 ABI_DEALLOCATE(mask) 407 408 ! Fourier transform 409 if (optreal==1) then 410 call fourdp(1,work1,work2,1,mpi_enreg,nfftprc,ngfftprc,dtset%paral_kgb,0) 411 else 412 work2(:)=reshape(work1(:,:),(/nfftprc*2/)) 413 end if 414 415 ! Add to get the preconditioned vresid, must be careful about spins. 416 if(dtset%iprcel>=30)then 417 diemix=dielar(4);diemixmag=abs(dielar(7)) 418 vrespc(:,1)=diemix*(vresid(:,1)+work2(:)) 419 if(dtset%nspden/=1)vrespc(:,2)=diemixmag*(vresid(:,2)+work2(:)) 420 if(dtset%nspden==4)vrespc(:,3:4)=diemixmag*vresid(:,3:4) 421 else 422 vrespc(:,1)=vresid(:,1)+work2(:) 423 if(dtset%nspden/=1)vrespc(:,2)=vresid(:,2)+work2(:) 424 if(dtset%nspden==4)vrespc(:,3:4)=vresid(:,3:4) 425 end if 426 427 ABI_DEALLOCATE(work1) 428 ABI_DEALLOCATE(work2) 429 430 ! Other choice ? 431 else 432 write(message, '(a,i0,a,a,a,a)' )& 433 & 'From the calling routine, iprcel= ',dtset%iprcel,ch10,& 434 & 'The only allowed values are 0 or larger than 20.',ch10,& 435 & 'Action: correct your input file.' 436 MSG_ERROR(message) 437 end if 438 end if 439 !####################################################################### 440 441 !3) PAW only : precondition the rhoij quantities (augmentation 442 !occupancies) residuals. Use a simple preconditionning 443 !with the same mixing factor as the model dielectric function. 444 445 if (psps%usepaw==1.and.my_natom>0) then 446 if (istep>=dielstrt.and.dtset%iprcel>=21.and.dtset%iprcel<30) then 447 mixfac=one;mixfacmag=one 448 else 449 mixfac=dielar(4);mixfacmag=abs(dielar(7)) 450 end if 451 if (pawrhoij(1)%cplex==1) then 452 index=0 453 do iatom=1,my_natom 454 do ispden=1,pawrhoij(iatom)%nspden 455 mixfac_eff=mixfac;if (ispden>1) mixfac_eff=mixfacmag 456 do kmix=1,pawrhoij(iatom)%lmnmix_sz 457 index=index+1;klmn=pawrhoij(iatom)%kpawmix(kmix) 458 rhoijrespc(index)=mixfac_eff*pawrhoij(iatom)%rhoijres(klmn,ispden) 459 end do 460 end do 461 end do 462 else 463 index=-1 464 do iatom=1,my_natom 465 do ispden=1,pawrhoij(iatom)%nspden 466 mixfac_eff=mixfac;if (ispden>1) mixfac_eff=mixfacmag 467 do kmix=1,pawrhoij(iatom)%lmnmix_sz 468 index=index+2;klmn=2*pawrhoij(iatom)%kpawmix(kmix)-1 469 rhoijrespc(index:index+1)=mixfac_eff*pawrhoij(iatom)%rhoijres(klmn:klmn+1,ispden) 470 end do 471 end do 472 end do 473 end if 474 end if 475 !####################################################################### 476 477 !4) Take care of the change of atomic positions 478 !Note : this part is very demanding on memory... 479 !however, since this algorithm is still in development, 480 !it was NOT included in the estimation provided by memory.f 481 if(abs(dtset%densfor_pred)==3 .and. moved_atm_inside==1)then 482 483 ! Not yet compatible with resid given in reciprocal space 484 if (optreal/=1) then 485 write(message, '(5a)' )& 486 & 'From the calling routine, densfor_pred=3',ch10,& 487 & 'You cannot use residuals in reciprocal space.',ch10,& 488 & 'Action: correct your input file.' 489 MSG_ERROR(message) 490 end if 491 492 ! Not compatible with non-collinear magnetism 493 if(dtset%nspden==4)then 494 MSG_ERROR('densfor_pred=3 does not work for nspden=4!') 495 end if 496 497 n1=ngfft(1) ; n2=ngfft(2) ; n3=ngfft(3) 498 nfftot=PRODUCT(ngfft(1:3)) 499 500 ! First subtract the current local, hartree and exchange correlation potentials 501 do ispden=1,min(dtset%nspden,2) 502 vrespc(:,ispden)=vrespc(:,ispden)-vpsp(:)-vhartr(:)-vxc(:,ispden) 503 end do 504 if (dtset%nspden==4) then 505 do ispden=3,4 506 vrespc(:,ispden)=vrespc(:,ispden)-vxc(:,ispden) 507 end do 508 end if 509 510 ! Compute the modified density, in rhor_wk 511 option=2 512 ABI_ALLOCATE(gresid,(3,dtset%natom)) 513 ABI_ALLOCATE(grxc,(3,dtset%natom)) 514 ABI_ALLOCATE(rhor_wk,(nfft,dtset%nspden)) 515 ABI_ALLOCATE(rhor_wk0,(nfft,dtset%nspden)) 516 ABI_ALLOCATE(xred_wk,(3,dtset%natom)) 517 xred_wk(:,:)=xred(:,:)+dtn_pc(:,:) 518 519 call fresid(dtset,gresid,mpi_enreg,nfft,ngfft,& 520 & ntypat,option,pawtab,rhor,rprimd,& 521 & ucvol,rhor_wk,xred_wk,xred,psps%znuclpsp) 522 523 ! Compute up+down rhog_wk(G) by fft 524 ABI_ALLOCATE(work,(nfft)) 525 ABI_ALLOCATE(rhog_wk,(2,nfft)) 526 work(:)=rhor_wk(:,1) 527 call fourdp(1,rhog_wk,work,-1,mpi_enreg,nfft,ngfft,dtset%paral_kgb,0) 528 ABI_DEALLOCATE(work) 529 530 ! Compute structure factor phases for new atomic pos: 531 call getph(atindx,dtset%natom,n1,n2,n3,ph1d,xred_wk) 532 533 ! Compute local ionic pseudopotential vpsp: 534 ! and core electron density xccc3d, if needed. 535 n3xccc=0;if (n1xccc/=0) n3xccc=nfft 536 ABI_ALLOCATE(xccc3d,(n3xccc)) 537 ABI_ALLOCATE(vpsp_wk,(nfft)) 538 vprtrb(1:2)=zero 539 540 ! Determine by which method the local ionic potential and/or 541 ! the pseudo core charge density have to be computed 542 ! Local ionic potential: 543 ! Method 1: PAW 544 ! Method 2: Norm-conserving PP, icoulomb>0, wavelets 545 vloc_method=1;if (psps%usepaw==0) vloc_method=2 546 if (dtset%icoulomb>0) vloc_method=2 547 if (psps%usewvl==1) vloc_method=2 548 ! Pseudo core charge density: 549 ! Method 1: PAW, nc_xccc_gspace 550 ! Method 2: Norm-conserving PP, wavelets 551 coredens_method=1;if (psps%usepaw==0) coredens_method=2 552 if (psps%nc_xccc_gspace==1) coredens_method=1 553 if (psps%nc_xccc_gspace==0) coredens_method=2 554 if (psps%usewvl==1) coredens_method=2 555 556 ! Local ionic potential and/or pseudo core charge by method 1 557 if (vloc_method==1.or.coredens_method==1) then 558 optv=0;if (vloc_method==1) optv=1 559 optn=0;if (coredens_method==1) optn=n3xccc/nfft 560 optatm=1;optdyfr=0;opteltfr=0;optgr=0;optstr=0;optn2=1 561 ! Note: atindx1 should be passed to atm2fft (instead of atindx) but it is unused... 562 call atm2fft(atindx,xccc3d,vpsp,dummy_out1,dummy_out2,dummy_out3,dummy_in,gmet,& 563 & gprimd,dummy_out4,dummy_out5,gsqcut,mgfft,psps%mqgrid_vl,dtset%natom,nattyp,& 564 & nfft,ngfft,ntypat,optatm,optdyfr,opteltfr,optgr,optn,optn2,optstr,optv,& 565 & psps,pawtab,ph1d,psps%qgrid_vl,qprtrb,dummy_in,dummy_out6,dummy_out7,ucvol,& 566 & psps%usepaw,dummy_in,dummy_in,dummy_in,vprtrb,psps%vlspl,& 567 & comm_fft=mpi_enreg%comm_fft,me_g0=mpi_enreg%me_g0,& 568 & paral_kgb=mpi_enreg%paral_kgb,distribfft=mpi_enreg%distribfft) 569 end if 570 571 ! Local ionic potential by method 2 572 if (vloc_method==2) then 573 option=1 574 ABI_ALLOCATE(dyfrlo_indx,(3,3,dtset%natom)) 575 ABI_ALLOCATE(grtn_indx,(3,dtset%natom)) 576 call mklocl(dtset,dyfrlo_indx,eei,gmet,gprimd,grtn_indx,gsqcut,dummy6,& 577 & mgfft,mpi_enreg,dtset%natom,nattyp,nfft,ngfft,dtset%nspden,& 578 & ntypat,option,pawtab,ph1d,psps,qprtrb,rhog_wk,rhor_wk,rprimd,& 579 & ucvol,vprtrb,vpsp_wk,wvl%descr,wvl%den,xred) 580 ABI_DEALLOCATE(dyfrlo_indx) 581 ABI_DEALLOCATE(grtn_indx) 582 end if 583 584 ! Pseudo core electron density by method 2 585 if (coredens_method==2.and.n1xccc/=0) then 586 option=1 587 ABI_ALLOCATE(dyfrx2,(3,3,dtset%natom)) 588 ABI_ALLOCATE(grxc_indx,(3,dtset%natom)) 589 call mkcore(dummy6,dyfrx2,grxc_indx,mpi_enreg,dtset%natom,nfft,dtset%nspden,ntypat,& 590 & n1,n1xccc,n2,n3,option,rprimd,dtset%typat,ucvol,vxc,psps%xcccrc,& 591 & psps%xccc1d,xccc3d,xred_wk) 592 ABI_DEALLOCATE(dyfrx2) 593 ABI_DEALLOCATE(grxc_indx) 594 end if 595 596 ! Compute Hartree+xc potentials 597 ABI_ALLOCATE(vxc_wk,(nfft,dtset%nspden)) 598 ABI_ALLOCATE(vhartr_wk,(nfft)) 599 option=1 600 601 call hartre(1,gsqcut,psps%usepaw,mpi_enreg,nfft,ngfft,dtset%paral_kgb,rhog_wk,rprimd,vhartr_wk) 602 603 ! Prepare the call to rhotoxc 604 call xcdata_init(xcdata,dtset=dtset) 605 nk3xc=1 606 ABI_ALLOCATE(work,(0)) 607 call rhotoxc(enxc,kxc,mpi_enreg,nfft,ngfft,& 608 & work,0,work,0,nkxc,nk3xc,non_magnetic_xc,n3xccc,option,dtset%paral_kgb,rhor_wk,rprimd,strsxc,1,& 609 & vxc_wk,vxcavg,xccc3d,xcdata,vhartr=vhartr_wk) 610 ABI_DEALLOCATE(work) 611 ABI_DEALLOCATE(xccc3d) 612 613 ! Sum all contributions 614 do ispden=1,min(dtset%nspden,2) 615 do ifft=1,nfft 616 vrespc(ifft,ispden)=vrespc(ifft,ispden)+vpsp_wk(ifft)+vhartr_wk(ifft)+vxc_wk(ifft,ispden) 617 end do 618 end do 619 if (dtset%nspden==4) then 620 do ispden=3,4 621 do ifft=1,nfft 622 vrespc(ifft,ispden)=vrespc(ifft,ispden)+vxc_wk(ifft,ispden) 623 end do 624 end do 625 end if 626 call mean_fftr(vrespc,vmean,nfft,nfftot,dtset%nspden,mpi_comm_sphgrid=mpi_enreg%comm_fft) 627 if(dtset%nspden==2) then 628 vmean(1)=half*(vmean(1)+vmean(2)) 629 vmean(2)=vmean(1) 630 end if 631 do ispden=1,dtset%nspden 632 vrespc(:,ispden)=vrespc(:,ispden)-vmean(ispden) 633 end do 634 ABI_DEALLOCATE(gresid) 635 ABI_DEALLOCATE(grxc) 636 ABI_DEALLOCATE(rhog_wk) 637 ABI_DEALLOCATE(rhor_wk) 638 ABI_DEALLOCATE(rhor_wk0) 639 ABI_DEALLOCATE(xred_wk) 640 ABI_DEALLOCATE(vhartr_wk) 641 ABI_DEALLOCATE(vpsp_wk) 642 ABI_DEALLOCATE(vxc_wk) 643 644 end if 645 646 end subroutine prcref_PMA