TABLE OF CONTENTS
- m_paw_dfpt/dsdr_k_paw
- m_paw_dfpt/m_paw_dfpt
- m_paw_dfpt/pawdfptenergy
- m_paw_dfpt/pawgrnl
- pawgrnl/pawgrnl_convert
m_paw_dfpt/dsdr_k_paw [ Functions ]
[ Top ] [ m_paw_dfpt ] [ Functions ]
NAME
dsdr_k_paw
FUNCTION
compute on-site terms for forces and stresses for finite electric fields with PAW
INPUTS
cprj_k (pawcprj_type) :: cprj for occupied bands at point k cprj_kb :: cprj for occupied bands at point k+b dtefield :: structure referring to all efield and berry's phase variables kdir :: integer giving direction along which overlap is computed for ket kfor :: integer indicating whether to compute forward (1) or backward (2) along kpt string natom :: number of atoms in cell typat :: typat(natom) type of each atom
OUTPUT
SIDE EFFECTS
dsdr :: array of the on-site PAW parts of the derivatives with respect to atm positions and/or strains of the overlaps between Bloch states at points k and k+b, for the various pairs of bands
NOTES
This routine assumes that the cprj are not explicitly ordered by atom type.
SOURCE
2063 subroutine dsdr_k_paw(cprj_k,cprj_kb,dsdr,dtefield,kdir,kfor,mband,natom,ncpgr,typat) 2064 2065 !Arguments--------------------------- 2066 !scalars 2067 integer,intent(in) :: kdir,kfor,mband,natom,ncpgr 2068 character(len=500) :: message 2069 type(efield_type),intent(in) :: dtefield 2070 type(pawcprj_type),intent(in) :: cprj_k(natom,dtefield%nspinor*mband) 2071 type(pawcprj_type),intent(in) :: cprj_kb(natom,dtefield%nspinor*mband) 2072 2073 !arrays 2074 integer,intent(in) :: typat(natom) 2075 real(dp),intent(inout) :: dsdr(2,natom,ncpgr,dtefield%mband_occ,dtefield%mband_occ) 2076 2077 !Local variables--------------------------- 2078 !scalars 2079 integer :: iatom,iband,ibs,icpgr,ilmn,ispinor,itypat 2080 integer :: jband,jbs,jlmn,klmn,nspinor 2081 complex(dpc) :: cpk,cpkb,dcpk,dcpkb,cterm,paw_onsite 2082 2083 ! ************************************************************************* 2084 2085 !initialize dsdr 2086 dsdr(:,:,:,:,:) = zero 2087 2088 ! if 3 gradients we are in the ctocprj choice 2 case 2089 ! and the 3 gradients are due to the atomic displacements 2090 ! if 6 gradients we are in the ctocprj choice 3 case 2091 ! and the 6 gradients are due to the strains 2092 ! if 9 gradients we are in the ctocprj choice 23 case 2093 ! and the first six are due to strain, last three due to displacements 2094 if (ncpgr /= 3 .and. ncpgr /= 6 .and. ncpgr /= 9) then 2095 message = ' dsdr_k_paw called with ncpgr /= 3, 6, or 9 (no gradients) ' 2096 ABI_BUG(message) 2097 end if 2098 2099 nspinor = dtefield%nspinor 2100 2101 do iatom = 1, natom 2102 itypat = typat(iatom) 2103 2104 do ilmn=1,dtefield%lmn_size(itypat) 2105 do jlmn=1,dtefield%lmn_size(itypat) 2106 klmn=max(ilmn,jlmn)*(max(ilmn,jlmn)-1)/2 + min(ilmn,jlmn) 2107 paw_onsite = cmplx(dtefield%qijb_kk(1,klmn,iatom,kdir),& 2108 & dtefield%qijb_kk(2,klmn,iatom,kdir)) 2109 if (kfor > 1) paw_onsite = conjg(paw_onsite) 2110 do iband = 1, dtefield%mband_occ 2111 do jband = 1, dtefield%mband_occ 2112 do ispinor = 1, nspinor 2113 do icpgr = 1, ncpgr 2114 ibs = nspinor*(iband-1) + ispinor 2115 jbs = nspinor*(jband-1) + ispinor 2116 cpk=cmplx(cprj_k(iatom,ibs)%cp(1,ilmn),cprj_k(iatom,ibs)%cp(2,ilmn)) 2117 dcpk=cmplx(cprj_k(iatom,ibs)%dcp(1,icpgr,ilmn),cprj_k(iatom,ibs)%dcp(2,icpgr,ilmn)) 2118 cpkb=cmplx(cprj_kb(iatom,jbs)%cp(1,jlmn),cprj_kb(iatom,jbs)%cp(2,jlmn)) 2119 dcpkb=cmplx(cprj_kb(iatom,jbs)%dcp(1,icpgr,jlmn),cprj_kb(iatom,jbs)%dcp(2,icpgr,jlmn)) 2120 cterm=paw_onsite*(conjg(dcpk)*cpkb+conjg(cpk)*dcpkb) 2121 dsdr(1,iatom,icpgr,iband,jband) = dsdr(1,iatom,icpgr,iband,jband)+real(cterm) 2122 dsdr(2,iatom,icpgr,iband,jband) = dsdr(2,iatom,icpgr,iband,jband)+aimag(cterm) 2123 end do ! end loop over icpgr 2124 end do ! end loop over ispinor 2125 end do ! end loop over jband 2126 end do ! end loop over iband 2127 end do ! end loop over ilmn 2128 end do ! end loop over jlmn 2129 2130 end do ! end loop over atoms 2131 2132 end subroutine dsdr_k_paw
m_paw_dfpt/m_paw_dfpt [ Modules ]
NAME
m_paw_dfpt
FUNCTION
This module contains several routines related to the 1st and 2nd order derivatives (in the DFPT approach) of PAW on-site quantities.
COPYRIGHT
Copyright (C) 2018-2024 ABINIT group (MT,AM,FJ,JWZ) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt .
SOURCE
17 #if defined HAVE_CONFIG_H 18 #include "config.h" 19 #endif 20 21 #include "abi_common.h" 22 23 MODULE m_paw_dfpt 24 25 use defs_basis 26 use m_abicore 27 use m_xmpi 28 use m_errors 29 use m_time, only : timab 30 31 use defs_datatypes, only : pseudopotential_type 32 use m_pawang, only : pawang_type 33 use m_pawrad, only : pawrad_type 34 use m_pawtab, only : pawtab_type 35 use m_paw_an, only : paw_an_type 36 use m_paw_ij, only : paw_ij_type 37 use m_pawcprj, only : pawcprj_type 38 use m_pawdij, only : pawdijhartree,pawdiju_euijkl 39 use m_pawrhoij, only : pawrhoij_type,pawrhoij_free,pawrhoij_gather,pawrhoij_nullify 40 use m_pawfgrtab, only : pawfgrtab_type, pawfgrtab_free, pawfgrtab_nullify, pawfgrtab_gather 41 use m_paw_finegrid, only : pawgylm, pawrfgd_fft, pawexpiqr 42 use m_pawxc, only : pawxc_dfpt, pawxcm_dfpt 43 use m_paw_denpot, only : pawdensities,pawaccenergy,pawaccenergy_nospin 44 use m_paral_atom, only : get_my_atmtab,free_my_atmtab 45 use m_atm2fft, only : dfpt_atm2fft 46 use m_distribfft, only : distribfft_type,init_distribfft_seq,destroy_distribfft 47 use m_geometry, only : metric, stresssym 48 use m_efield, only : efield_type 49 50 implicit none 51 52 private 53 54 !public procedures. 55 public :: pawdfptenergy ! Compute Hartree+XC PAW on-site contrib. to a 1st or 2nd-order energy 56 public :: pawgrnl ! Compute derivatives of total energy due to NL terms (PAW Dij derivatives) 57 public :: dsdr_k_paw ! Compute PAW on-site terms for forces/stresses for finite electric fields 58 59 CONTAINS !========================================================================================
m_paw_dfpt/pawdfptenergy [ Functions ]
[ Top ] [ m_paw_dfpt ] [ Functions ]
NAME
pawdfptenergy
FUNCTION
This routine compute the Hartree+XC+U PAW on-site contributions to a 1st-order or 2nd-order energy. These contributions are equal to: E_onsite= Int{ VHxc[n1_a^(j1);nc^(j1)].n1_b^(j2) } -Int{ VHxc[tild_n1_a^(j1)+hat_n1_a^(j1);tild_n_c^(j1)].(tild_n1_b+n1_b)^(j2) } Some typical uses: A-Contribution to non-stationary expression of the 2nd-order total energy: In that case, n1_a^(1)[r]=n1^(j1)[r] and n1_b[r]=delta_n1^(j2)[r] where j1 and j2 are two given perturbations, and delta_n1^(j)[r] is the 1s-order density only due to change of WF overlap. See PRB 78, 035105 (2008) [[cite:Audouze2008]], Eq.(80). E_onsite= Int{ VHxc[n1^(j1);nc^(j1)].delta_n1^(j2) } -Int{ VHxc[tild_n1^(j1)+hat_n1^(j1);tild_n_c^(j1)].delta_(tild_n1+hat_n1)^(j2) } B-Contribution to first-order Fermi energy: In that case, n1_a^(1)[r]=n1^(j1)[r] and n1_b[r]=n1[r,EFermi] where j1 is the current perturbation, and n1[r,EFermi] is the density at Fermi level. E_onsite= Int{ VHxc[n1^(j1);nc^(j1)].n1[r,EFermi] } -Int{ VHxc[tild_n1^(j1)+hat_n1^(j1);tild_n_c^(j1)].(tild_n1+hat_n1)[r,EFermi] }
INPUTS
ipert1,ipert2=indexes of perturbations (j1) and (j2) if ipert2<=0, we compute a first-order energy if ipert2> 0, we compute a second-order energy ixc= choice of exchange-correlation scheme mpi_atmtab(:)=--optional-- indexes of the atoms treated by current proc comm_atom=--optional-- MPI communicator over atoms my_natom=number of atoms treated by current processor natom=total number of atoms in cell ntypat=number of types of atoms in unit cell. nzlmopt_a= For the n1_a density: if -1, compute all LM-moments of the density and use non-zero LM-moments if 0, compute all LM-moments of the density and use all LM-moments if +1, compute only non-zero LM-moments of the density (stored before) nzlmopt_b= For the n1_b density: if -1, compute all LM-moments of the density and use non-zero LM-moments if 0, compute all LM-moments of the density and use all LM-moments if +1, compute only non-zero LM-moments of the density (stored before) paw_an0(natom) <type(paw_an_type)>=paw arrays for 0th-order quantities given on angular mesh paw_an1(natom) <type(paw_an_type)>=paw arrays for 1st-order quantities given on angular mesh This corresponds to (j1) perturbation paw_ij1(natom) <type(paw_ij_type)>=paw arrays given on (i,j) channels This corresponds to (j1) perturbation pawang <type(pawang_type)>=paw angular mesh and related data pawprtvol=control print volume and debugging output for PAW pawrad(ntypat) <type(pawrad_type)>=paw radial mesh and related data pawrhoij_a(natom) <type(pawrhoij_type)>= paw rhoij 1st-order occupancies for the (j1) perturbation pawrhoij_b(natom) <type(pawrhoij_type)>= if ipert2> 0: paw rhoij 1st-order occupancies for the (j2) perturbation corrsponding to n1_b^(j2)[r] if ipert2<=0: paw rhoij occupancies corresponding to n1_b[r] pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data pawxcdev=Choice of XC development (0=no dev. (use of angular mesh) ; 1 or 2=dev. on moments) xclevel= XC functional level
OUTPUT
delta_energy(2)= real and imaginary parts of contributions to non-stationary expression for the second derivative of the total energy
SIDE EFFECTS
==== if paw_an1(:)%has_vxc<2, compute 1st-order XC potentials paw_an1(natom)%vxc1(cplex_a*mesh_size,:,nspden) =AE 1st-order XC potential Vxc^(j1) paw_an1(natom)%vxct1(cplex_a*mesh_size,:,nspden)=PS 1st-order XC potential tVxc^(j1) ==== if paw_ij1(:)%has_dijhartree<2, compute 1st-order Dij_hartree paw_ij1(natom)%dijhartree(cplex_a*lmn2_size)=Hartree contribution to Dij^(j1) ==== if paw_ij1(:)%has_dijU<2, compute 1st-order Dij_U paw_ij1(natom)%diju(cplex_a*lmn2_size)=DFT+U contribution to Dij^(j1)
SOURCE
139 subroutine pawdfptenergy(delta_energy,ipert1,ipert2,ixc,my_natom,natom,ntypat,nzlmopt_a,nzlmopt_b,& 140 & paw_an0,paw_an1,paw_ij1,pawang,pawprtvol,pawrad,pawrhoij_a,pawrhoij_b,& 141 & pawtab,pawxcdev,xclevel, & 142 & mpi_atmtab,comm_atom) ! optional arguments (parallelism) 143 144 !Arguments --------------------------------------------- 145 !scalars 146 integer,intent(in) :: ipert1,ipert2,ixc,my_natom,natom,ntypat,nzlmopt_a,nzlmopt_b 147 integer,intent(in) :: pawprtvol,pawxcdev,xclevel 148 integer,optional,intent(in) :: comm_atom 149 type(pawang_type),intent(in) :: pawang 150 !arrays 151 integer,optional,target,intent(in) :: mpi_atmtab(:) 152 real(dp),intent(out) :: delta_energy(2) 153 type(paw_an_type),intent(in) :: paw_an0(my_natom) 154 type(paw_an_type),intent(inout) :: paw_an1(my_natom) 155 type(paw_ij_type),intent(inout) :: paw_ij1(my_natom) 156 type(pawrad_type),intent(in) :: pawrad(ntypat) 157 type(pawrhoij_type),intent(in) :: pawrhoij_a(my_natom),pawrhoij_b(my_natom) 158 type(pawtab_type),intent(in) :: pawtab(ntypat) 159 160 !Local variables --------------------------------------- 161 !scalars 162 integer, parameter :: PAWU_ALGO_1=1,PAWU_ALGO_2=2 163 integer :: cplex_a,cplex_b,cplex_vxc1,iatom,iatom_tot,ierr,itypat,lm_size_a,lm_size_b,mesh_size 164 integer :: my_comm_atom,nspden,opt_compch,optexc,optvxc,pawu_algo,qphase_dijh1,qphase_diju1 165 integer :: usecore,usepawu,usetcore,usexcnhat 166 logical :: my_atmtab_allocated,non_magnetic_xc,paral_atom 167 real(dp) :: compch,eexc,eexc_im 168 character(len=500) :: msg 169 !arrays 170 integer,pointer :: my_atmtab(:) 171 logical,allocatable :: lmselect_a(:),lmselect_b(:),lmselect_tmp(:) 172 real(dp) :: delta_energy_h(2),delta_energy_u(2),delta_energy_xc(2),tsec(2) 173 real(dp),allocatable :: kxc_dum(:,:,:),nhat1(:,:,:),rho1(:,:,:),trho1(:,:,:) 174 175 ! ************************************************************************* 176 177 DBG_ENTER("COLL") 178 179 call timab(567,1,tsec) 180 181 if (.not.(ipert1==natom+1.or.ipert1==natom+10.or.ipert1==natom+11 & 182 & .or.ipert2==natom+1.or.ipert2==natom+10.or.ipert2==natom+11)) then 183 if((abs(nzlmopt_a)/=1.and.nzlmopt_a/=0).or.(abs(nzlmopt_b)/=1.and.nzlmopt_b/=0)) then 184 msg='invalid value for nzlmopt!' 185 ABI_BUG(msg) 186 end if 187 if (my_natom>0) then 188 if(paw_ij1(1)%has_dijhartree==0) then 189 msg='dijhartree must be allocated!' 190 ABI_BUG(msg) 191 end if 192 if (any(pawtab(1:ntypat)%usepawu/=0)) then 193 if(paw_ij1(1)%has_dijU==0) then 194 msg='dijU must be allocated!' 195 ABI_BUG(msg) 196 end if 197 end if 198 if(paw_an1(1)%has_vxc==0) then 199 msg='vxc1 and vxct1 must be allocated!' 200 ABI_BUG(msg) 201 end if 202 if(paw_an0(1)%has_kxc==0) then 203 msg='kxc1 must be allocated!' 204 ABI_BUG(msg) 205 end if 206 if ((ipert1<=natom.or.ipert1==natom+1.or.ipert1==natom+10.or.ipert1==natom+11).and.paw_an0(1)%has_kxc/=2) then 207 msg='XC kernels for ground state must be in memory!' 208 ABI_BUG(msg) 209 end if 210 if (paw_ij1(1)%qphase/=paw_an1(1)%cplex) then 211 msg='paw_ij1()%qphase and paw_an1()%cplex must be equal!' 212 ABI_BUG(msg) 213 end if 214 if (pawrhoij_a(1)%qphase<paw_an1(1)%cplex.or.pawrhoij_b(1)%qphase<paw_an1(1)%cplex) then 215 msg='pawrhoij()%qphase must be >=paw_an1()%cplex!' 216 ABI_BUG(msg) 217 end if 218 if (paw_ij1(1)%nspden/=paw_an1(1)%nspden) then 219 msg='paw_ij1()%nspden and paw_an1()%nspden must be equal!' 220 ABI_BUG(msg) 221 end if 222 if (pawrhoij_a(1)%nspden/=pawrhoij_b(1)%nspden) then 223 msg='pawrhoij_a()%nspden must =pawrhoij_b()%nspden !' 224 ABI_BUG(msg) 225 end if 226 end if 227 end if 228 229 !Set up parallelism over atoms 230 paral_atom=(present(comm_atom).and.(my_natom/=natom)) 231 nullify(my_atmtab);if (present(mpi_atmtab)) my_atmtab => mpi_atmtab 232 my_comm_atom=xmpi_comm_self;if (present(comm_atom)) my_comm_atom=comm_atom 233 call get_my_atmtab(my_comm_atom,my_atmtab,my_atmtab_allocated,paral_atom,natom,my_natom_ref=my_natom) 234 235 !Init contribution to 1st-order (or 2nd-order) energy 236 delta_energy(1:2)=zero 237 238 !For some perturbations, nothing else to do 239 if (ipert1==natom+1.or.ipert1==natom+10.or.ipert1==natom+11 .or. & 240 & ipert2==natom+1.or.ipert2==natom+10.or.ipert2==natom+11) return 241 242 !Various inits 243 opt_compch=0;optvxc=1;optexc=3 244 usecore=0;usetcore=0 ! This is true for phonons and Efield pert. 245 usexcnhat=maxval(pawtab(1:ntypat)%usexcnhat) 246 delta_energy_xc(1:2)=zero 247 delta_energy_h(1:2)=zero 248 delta_energy_u(1:2)=zero 249 250 !================ Loop on atomic sites ======================= 251 do iatom=1,my_natom 252 iatom_tot=iatom;if (paral_atom) iatom_tot=my_atmtab(iatom) 253 254 itypat=pawrhoij_a(iatom)%itypat 255 mesh_size=pawtab(itypat)%mesh_size 256 nspden=paw_an1(iatom)%nspden 257 cplex_a=pawrhoij_a(iatom)%qphase 258 cplex_b=pawrhoij_b(iatom)%qphase 259 cplex_vxc1=paw_an1(iatom)%cplex 260 qphase_dijh1=paw_ij1(iatom)%qphase 261 qphase_diju1=paw_ij1(iatom)%qphase 262 lm_size_a=paw_an1(iatom)%lm_size 263 if (ipert2<=0) lm_size_b=paw_an0(iatom)%lm_size 264 if (ipert2> 0) lm_size_b=paw_an1(iatom)%lm_size 265 usepawu=pawtab(itypat)%usepawu 266 pawu_algo=merge(PAWU_ALGO_1,PAWU_ALGO_2,ipert1<=0.and.ipert2<=0.and.usepawu>=0) 267 non_magnetic_xc=(mod(abs(usepawu),10)==4) 268 269 ! If Vxc potentials are not in memory, compute them 270 if (paw_an1(iatom)%has_vxc/=2) then 271 ABI_MALLOC(rho1 ,(cplex_a*mesh_size,lm_size_a,nspden)) 272 ABI_MALLOC(trho1,(cplex_a*mesh_size,lm_size_a,nspden)) 273 ABI_MALLOC(nhat1,(cplex_a*mesh_size,lm_size_a,nspden*usexcnhat)) 274 ABI_MALLOC(lmselect_a,(lm_size_a)) 275 lmselect_a(:)=paw_an1(iatom)%lmselect(:) 276 ABI_MALLOC(lmselect_tmp,(lm_size_a)) 277 lmselect_tmp(:)=.true. 278 if (nzlmopt_a==1) lmselect_tmp(:)=lmselect_a(:) 279 ! Compute on-site 1st-order densities 280 call pawdensities(compch,cplex_a,iatom_tot,lmselect_tmp,lmselect_a,& 281 & lm_size_a,nhat1,nspden,nzlmopt_a,opt_compch,1-usexcnhat,-1,0,pawang,pawprtvol,& 282 & pawrad(itypat),pawrhoij_a(iatom),pawtab(itypat),rho1,trho1) 283 ABI_FREE(lmselect_tmp) 284 ! Compute on-site 1st-order xc potentials 285 if (pawxcdev/=0) then 286 call pawxcm_dfpt(pawtab(itypat)%coredens,cplex_a,cplex_vxc1,eexc,ixc,paw_an0(iatom)%kxc1,& 287 & lm_size_a,lmselect_a,nhat1,paw_an0(iatom)%nkxc1,non_magnetic_xc,mesh_size,nspden,optvxc,& 288 & pawang,pawrad(itypat),rho1,usecore,0,& 289 & paw_an1(iatom)%vxc1,xclevel) 290 call pawxcm_dfpt(pawtab(itypat)%tcoredens(:,1),cplex_a,cplex_vxc1,eexc,ixc,paw_an0(iatom)%kxct1,& 291 & lm_size_a,lmselect_a,nhat1,paw_an0(iatom)%nkxc1,non_magnetic_xc,mesh_size,nspden,optvxc,& 292 & pawang,pawrad(itypat),trho1,usetcore,2*usexcnhat,& 293 & paw_an1(iatom)%vxct1,xclevel) 294 else 295 call pawxc_dfpt(pawtab(itypat)%coredens,cplex_a,cplex_vxc1,eexc,ixc,paw_an0(iatom)%kxc1,& 296 & lm_size_a,lmselect_a,nhat1,paw_an0(iatom)%nkxc1,non_magnetic_xc,mesh_size,nspden,optvxc,& 297 & pawang,pawrad(itypat),rho1,usecore,0,& 298 & paw_an0(iatom)%vxc1,paw_an1(iatom)%vxc1,xclevel) 299 call pawxc_dfpt(pawtab(itypat)%tcoredens(:,1),cplex_a,cplex_vxc1,eexc,ixc,paw_an0(iatom)%kxct1,& 300 & lm_size_a,lmselect_a,nhat1,paw_an0(iatom)%nkxc1,non_magnetic_xc,mesh_size,nspden,optvxc,& 301 & pawang,pawrad(itypat),trho1,usetcore,2*usexcnhat,& 302 & paw_an0(iatom)%vxct1,paw_an1(iatom)%vxct1,xclevel) 303 end if 304 305 paw_an1(iatom)%has_vxc=2 306 ABI_FREE(lmselect_a) 307 ABI_FREE(rho1) 308 ABI_FREE(trho1) 309 ABI_FREE(nhat1) 310 end if ! has_vxc 311 312 ! Compute contribution to 1st-order (or 2nd-order) energy from 1st-order XC potential 313 ABI_MALLOC(rho1 ,(cplex_b*mesh_size,lm_size_b,nspden)) 314 ABI_MALLOC(trho1,(cplex_b*mesh_size,lm_size_b,nspden)) 315 ABI_MALLOC(nhat1,(cplex_b*mesh_size,lm_size_b,nspden*usexcnhat)) 316 ABI_MALLOC(lmselect_b,(lm_size_b)) 317 if (ipert2<=0) lmselect_b(:)=paw_an0(iatom)%lmselect(:) 318 if (ipert2> 0) lmselect_b(:)=paw_an1(iatom)%lmselect(:) 319 ABI_MALLOC(lmselect_tmp,(lm_size_b)) 320 lmselect_tmp(:)=.true. 321 if (nzlmopt_b==1) lmselect_tmp(:)=lmselect_b(:) 322 ! Compute on-site 1st-order densities 323 call pawdensities(compch,cplex_b,iatom_tot,lmselect_tmp,lmselect_b,& 324 & lm_size_b,nhat1,nspden,nzlmopt_b,opt_compch,1-usexcnhat,-1,0,pawang,pawprtvol,& 325 & pawrad(itypat),pawrhoij_b(iatom),pawtab(itypat),rho1,trho1) 326 ABI_FREE(lmselect_tmp) 327 ! Compute contributions to 1st-order (or 2nd-order) energy 328 if (pawxcdev/=0) then 329 ABI_MALLOC(kxc_dum,(mesh_size,pawang%angl_size,0)) 330 call pawxcm_dfpt(pawtab(itypat)%coredens,cplex_b,cplex_vxc1,eexc,ixc,kxc_dum,& 331 & lm_size_b,lmselect_b,nhat1,0,non_magnetic_xc,mesh_size,nspden,optexc,pawang,pawrad(itypat),& 332 & rho1,usecore,0,paw_an1(iatom)%vxc1,xclevel,d2enxc_im=eexc_im) 333 delta_energy_xc(1)=delta_energy_xc(1)+eexc 334 delta_energy_xc(2)=delta_energy_xc(2)+eexc_im 335 call pawxcm_dfpt(pawtab(itypat)%tcoredens(:,1),& 336 & cplex_b,cplex_vxc1,eexc,ixc,kxc_dum,& 337 & lm_size_b,lmselect_b,nhat1,0,non_magnetic_xc,mesh_size,nspden,optexc,pawang,pawrad(itypat),& 338 & trho1,usetcore,2*usexcnhat,paw_an1(iatom)%vxct1,xclevel,& 339 & d2enxc_im=eexc_im) 340 ABI_FREE(kxc_dum) 341 delta_energy_xc(1)=delta_energy_xc(1)-eexc 342 delta_energy_xc(2)=delta_energy_xc(2)-eexc_im 343 else 344 ABI_MALLOC(kxc_dum,(mesh_size,lm_size_b,0)) 345 call pawxc_dfpt(pawtab(itypat)%coredens,cplex_b,cplex_vxc1,eexc,ixc,kxc_dum,& 346 & lm_size_b,lmselect_b,nhat1,0,non_magnetic_xc,mesh_size,nspden,optexc,pawang,pawrad(itypat),& 347 & rho1,usecore,0,paw_an0(iatom)%vxc1,paw_an1(iatom)%vxc1,xclevel,d2enxc_im=eexc_im) 348 delta_energy_xc(1)=delta_energy_xc(1)+eexc 349 delta_energy_xc(2)=delta_energy_xc(2)+eexc_im 350 call pawxc_dfpt(pawtab(itypat)%tcoredens(:,1),& 351 & cplex_b,cplex_vxc1,eexc,ixc,kxc_dum,& 352 & lm_size_b,lmselect_b,nhat1,0,non_magnetic_xc,mesh_size,nspden,optexc,pawang,pawrad(itypat),& 353 & trho1,usetcore,2*usexcnhat,paw_an0(iatom)%vxct1,paw_an1(iatom)%vxct1,xclevel,& 354 & d2enxc_im=eexc_im) 355 ABI_FREE(kxc_dum) 356 delta_energy_xc(1)=delta_energy_xc(1)-eexc 357 delta_energy_xc(2)=delta_energy_xc(2)-eexc_im 358 end if 359 ABI_FREE(lmselect_b) 360 ABI_FREE(rho1) 361 ABI_FREE(trho1) 362 ABI_FREE(nhat1) 363 364 ! If Dij_hartree are not in memory, compute them 365 if (paw_ij1(iatom)%has_dijhartree/=2) then 366 call pawdijhartree(paw_ij1(iatom)%dijhartree,qphase_dijh1,paw_ij1(iatom)%nspden,& 367 & pawrhoij_a(iatom),pawtab(itypat)) 368 paw_ij1(iatom)%has_dijhartree=2 369 end if 370 371 ! Compute contribution to 1st-order(or 2nd-order) energy from 1st-order Hartree potential 372 call pawaccenergy_nospin(delta_energy_h(1),pawrhoij_b(iatom),paw_ij1(iatom)%dijhartree, & 373 & 1,qphase_dijh1,pawtab(itypat),epaw_im=delta_energy_h(2)) 374 375 ! Compute contribution to 1st-order(or 2nd-order) energy from 1st-order PAW+U potential 376 if (usepawu/=0.and.pawu_algo==PAWU_ALGO_2) then 377 ! If DijU are not in memory, compute them 378 if (paw_ij1(iatom)%has_dijU/=2) then ! We force the recomputation of dijU in when cplex=2 to get diju_im 379 call pawdiju_euijkl(paw_ij1(iatom)%dijU,paw_ij1(iatom)%cplex_dij,qphase_diju1,& 380 & paw_ij1(iatom)%ndij,pawrhoij_a(iatom),pawtab(itypat)) 381 paw_ij1(iatom)%has_dijU=2 382 end if 383 ! Compute contribution to 1st-order(or 2nd-order) energy 384 call pawaccenergy(delta_energy_u(1),pawrhoij_b(iatom),paw_ij1(iatom)%dijU,paw_ij1(iatom)%cplex_dij, & 385 & qphase_diju1,paw_ij1(iatom)%ndij,pawtab(itypat),epaw_im=delta_energy_u(2)) 386 ! Add FLL double-counting contribution 387 if (ipert1==0) then ! If j1/=0, Dij^FLL^(j1)=0 because it is constant 388 call pawaccenergy_nospin(delta_energy_u(1),pawrhoij_b(iatom),pawtab(itypat)%euij_fll,1,1,& 389 & pawtab(itypat),epaw_im=delta_energy_u(2)) 390 end if 391 end if 392 393 ! ================ End loop on atomic sites ======================= 394 end do 395 396 !Final building of 1st-order (or 2nd-order) energy 397 delta_energy(1:2)=delta_energy_xc(1:2)+delta_energy_h(1:2)+delta_energy_u(1:2) 398 399 !Reduction in case of parallelism 400 if (paral_atom) then 401 call xmpi_sum(delta_energy,my_comm_atom,ierr) 402 end if 403 404 !Destroy atom table used for parallelism 405 call free_my_atmtab(my_atmtab,my_atmtab_allocated) 406 407 call timab(567,2,tsec) 408 409 DBG_EXIT("COLL") 410 411 end subroutine pawdfptenergy
m_paw_dfpt/pawgrnl [ Functions ]
[ Top ] [ m_paw_dfpt ] [ Functions ]
NAME
pawgrnl
FUNCTION
PAW: Add to GRadients of total energy due to non-local term of Hamiltonian the contribution due to Dij derivatives In particular, compute contribution to forces, stresses, dyn. matrix Remember: Vnl=Sum_ij[|p_i>Dij<p_j|]
INPUTS
atindx1(natom)=index table for atoms, inverse of atindx dimnhat=second dimension of array nhat (0 or # of spin components) distribfft<type(distribfft_type)>=--optional-- contains all the information related to the FFT parallelism and plane sharing dyfr_cplex=1 if dyfrnl is real, 2 if it is complex gsqcut=Fourier cutoff on G^2 for "large sphere" of radius double that of the basis sphere mgfft=maximum size of 1D FFTs me_g0=--optional-- 1 if the current process treat the g=0 plane-wave (only needed when comm_fft is present) mpi_atmtab(:)=--optional-- indexes of the atoms treated by current proc comm_atom=--optional-- MPI communicator over atoms comm_fft=--optional-- MPI communicator over FFT components (=mpi_comm_grid is not present) mpi_comm_grid=--optional-- MPI communicator over real space grid components (=comm_fft is not present) my_natom=number of atoms treated by current processor natom=total number of atoms in cell nattyp(ntypat)=array describing how many atoms of each type in cell nfft=(effective) number of FFT grid points (for this processor) ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft nhat(nfft,dimnhat)=compensation charge density on rectangular grid in real space nspden=number of spin-density components nsym=number of symmetries in space group ntypat=number of types of atoms optgr= 1 if gradients with respect to atomic position(s) have to be computed optgr2= 1 if 2nd gradients with respect to atomic position(s) have to be computed optstr= 1 if gradients with respect to strain(s) have to be computed optstr2= 1 if 2nd gradients with respect to strain(s) have to be computed paral_kgb=--optional-- 1 if "band-FFT" parallelism is activated (only needed when comm_fft is present) pawang <type(pawang_type)>=paw angular mesh and related data pawfgrtab(my_natom) <type(pawfgrtab_type)>=atomic data given on fine rectangular grid pawrhoij(my_natom) <type(pawrhoij_type)>= paw rhoij occupancies and related data pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data ph1d(2,3*(2*mgfft+1)*natom)=1-dim phase (structure factor) information psps <type(pseudopotential_type)>=variables related to pseudopotentials qphon(3)=wavevector of the phonon rprimd(3,3)=dimensional primitive translations in real space (bohr) symrec(3,3,nsym)=symmetries in reciprocal space, reduced coordinates typat(natom)=types of atoms ucvol=unit cell volume vtrial(nfft,nspden)= total local potential vxc(nfft,nspden)=XC potential xred(3,natom)=reduced dimensionless atomic coordinates
SIDE EFFECTS
At input, this terms contain contribution from non-local projectors derivatives At output, they are updated with the contribution of Dij derivatives ==== if optgr=1 ==== grnl(3*natom) =gradients of NL energy wrt atomic coordinates ==== if optstr=1 ==== nlstr(6) =gradients of NL energy wrt strains ==== if optgr2=1 ==== dyfrnl(dyfr_cplex,3,3,natom,natom) =2nd gradients of NL energy wrt atomic coordinates ==== if optstr=2 ==== eltfrnl(6+3*natom,6)=non-symmetrized non-local contribution to the elastic tensor
NOTES
In the case of parallelisation over atoms and calculation of dynamical matrix (optgr2=1) several data are gathered and no more distributed inside this routine.
SOURCE
486 subroutine pawgrnl(atindx1,dimnhat,dyfrnl,dyfr_cplex,eltfrnl,grnl,gsqcut,mgfft,my_natom,natom,& 487 & nattyp,nfft,ngfft,nhat,nlstr,nspden,nsym,ntypat,optgr,optgr2,optstr,optstr2,& 488 & pawang,pawfgrtab,pawrhoij,pawtab,ph1d,psps,qphon,rprimd,symrec,typat,ucvol,vtrial,vxc,xred,& 489 & mpi_atmtab,comm_atom,comm_fft,mpi_comm_grid,me_g0,paral_kgb,distribfft) ! optional arguments (parallelism) 490 491 !Arguments ------------------------------------ 492 !scalars 493 integer,intent(in) :: dimnhat,dyfr_cplex,mgfft,my_natom,natom,nfft,nspden,nsym,ntypat 494 integer,intent(in) :: optgr,optgr2,optstr,optstr2 495 integer,optional,intent(in) :: me_g0,comm_atom,comm_fft,mpi_comm_grid,paral_kgb 496 real(dp),intent(in) :: gsqcut,ucvol 497 type(distribfft_type),optional,target,intent(in) :: distribfft 498 type(pawang_type),intent(in) :: pawang 499 type(pseudopotential_type),intent(in) :: psps 500 !arrays 501 integer,intent(in) :: atindx1(natom),nattyp(ntypat),ngfft(18) 502 integer,intent(in) :: symrec(3,3,nsym),typat(natom) 503 integer,optional,target,intent(in) :: mpi_atmtab(:) 504 real(dp),intent(in) :: nhat(nfft,dimnhat),ph1d(2,3*(2*mgfft+1)*natom),qphon(3) 505 real(dp),intent(in) :: rprimd(3,3),vxc(nfft,nspden),xred(3,natom) 506 real(dp),intent(in),target :: vtrial(nfft,nspden) 507 real(dp),intent(inout) :: dyfrnl(dyfr_cplex,3,3,natom,natom*optgr2) 508 real(dp),intent(inout) :: eltfrnl(6+3*natom,6),grnl(3*natom*optgr) 509 real(dp),intent(inout) :: nlstr(6*optstr) 510 type(pawfgrtab_type),target,intent(inout) :: pawfgrtab(:) 511 type(pawrhoij_type),target,intent(inout) :: pawrhoij(:) 512 type(pawtab_type),intent(in) :: pawtab(ntypat) 513 514 !Local variables------------------------------- 515 !scalars 516 integer :: bufind,bufsiz,cplex,dimvtrial,eps_alpha,eps_beta,eps_gamma,eps_delta,iatm,iatom 517 integer :: iatom_pawfgrtab,iatom_pawrhoij,iatom_tot,iatshft,ic,idiag,idir,ier,ilm,indx,irhoij 518 integer :: isel,ishift_grhoij,ishift_gr,ishift2_gr,ishift_gr2,ishift_str,ishift_str2,ishift_str2is,ispden 519 integer :: ispvtr,itypat,jatom,jatom_tot,jatm,jc,jrhoij,jtypat,klm,klmn,klmn1,ll,lm_size 520 integer :: lm_sizej,lmax,lmin,lmn2_size,me_fft,mu,mua,mub,mushift,my_me_g0,my_comm_atom,my_comm_fft 521 integer :: my_comm_grid,my_paral_kgb,n1,n2,n3,nfftot,nfgd,nfgd_jatom 522 integer :: ngrad,ngrad_nondiag,ngradp,ngradp_nondiag,ngrhat,nsploop 523 integer :: opt1,opt2,opt3,qne0,usexcnhat 524 logical,parameter :: save_memory=.true. 525 logical :: has_phase,my_atmtab_allocated 526 logical :: paral_atom,paral_atom_pawfgrtab,paral_atom_pawrhoij,paral_grid 527 real(dp) :: dlt_tmp,fact_ucvol,grhat_x,hatstr_diag,rcut_jatom,ro,ro_d,ucvol_ 528 character(len=500) :: msg 529 type(distribfft_type),pointer :: my_distribfft 530 type(pawfgrtab_type),pointer :: pawfgrtab_iatom,pawfgrtab_jatom 531 type(pawrhoij_type),pointer :: pawrhoij_iatom,pawrhoij_jatom 532 !arrays 533 integer,parameter :: alpha(9)=(/1,2,3,3,3,2,2,1,1/),beta(9)=(/1,2,3,2,1,1,3,3,2/) 534 integer,parameter :: eps1(6)=(/1,2,3,2,3,1/),eps2(6)=(/1,2,3,3,1,2/) 535 integer,parameter :: mu9(9)=(/1,2,3,4,5,6,4,5,6/) 536 integer,allocatable :: atindx(:),atm_indx(:),mu4(:) 537 integer,allocatable,target :: ifftsph_tmp(:) 538 integer,ABI_CONTIGUOUS pointer :: ffti3_local(:),fftn3_distrib(:),ifft_jatom(:) 539 integer, pointer :: my_atmtab(:) 540 real(dp) :: gmet(3,3),gprimd(3,3),hatstr(6),rdum(1),rdum2(1),rmet(3,3),tmp(12) 541 real(dp) :: work1(dyfr_cplex,3,3),work2(dyfr_cplex,3,3) 542 real(dp),allocatable :: buf(:,:),buf1(:),dyfr(:,:,:,:,:),eltfr(:,:) 543 real(dp),allocatable :: grhat_tmp(:,:),grhat_tmp2(:,:),hatgr(:) 544 real(dp),allocatable :: prod(:,:),prodp(:,:),vloc(:),vpsp1_gr(:,:),vpsp1_str(:,:) 545 real(dp),allocatable,target :: rfgd_tmp(:,:) 546 real(dp),ABI_CONTIGUOUS pointer :: gylm_jatom(:,:),gylmgr_jatom(:,:,:),gylmgr2_jatom(:,:,:),expiqr_jatom(:,:) 547 real(dp),ABI_CONTIGUOUS pointer :: rfgd_jatom(:,:),vtrial_(:,:) 548 type(coeff2_type),allocatable :: prod_nondiag(:),prodp_nondiag(:) 549 type(pawfgrtab_type),pointer :: pawfgrtab_(:),pawfgrtab_tot(:) 550 type(pawrhoij_type),pointer :: pawrhoij_(:),pawrhoij_tot(:) 551 552 ! ************************************************************************* 553 554 DBG_ENTER("COLL") 555 556 !Compatibility tests 557 qne0=0;if (qphon(1)**2+qphon(2)**2+qphon(3)**2>=1.d-15) qne0=1 558 if (my_natom>0) then 559 if ((optgr2==1.or.optstr2==1).and.pawrhoij(1)%ngrhoij==0) then 560 msg='pawgrnl: inconsistency between variables optgr2/optstr2 and ngrhoij!' 561 ABI_BUG(msg) 562 end if 563 if (pawfgrtab(1)%rfgd_allocated==0) then 564 if ((optgr2==1.and.qne0==1).or.optstr2==1) then 565 msg='pawgrnl: pawfgrtab()%rfgd array must be allocated!' 566 ABI_BUG(msg) 567 end if 568 end if 569 if (pawrhoij(1)%qphase/=1) then 570 msg='pawgrnl: not supposed to be called with pawrhoij(:)%qphase=2!' 571 ABI_BUG(msg) 572 end if 573 end if 574 575 !---------------------------------------------------------------------- 576 !Parallelism setup 577 578 !Set up parallelism over atoms 579 paral_atom=(present(comm_atom).and.(my_natom/=natom)) 580 paral_atom_pawfgrtab=(size(pawfgrtab)/=natom) 581 paral_atom_pawrhoij=(size(pawrhoij)/=natom) 582 nullify(my_atmtab);if (present(mpi_atmtab)) my_atmtab => mpi_atmtab 583 my_comm_atom=xmpi_comm_self;if (present(comm_atom)) my_comm_atom=comm_atom 584 call get_my_atmtab(my_comm_atom,my_atmtab,my_atmtab_allocated,paral_atom,natom,my_natom_ref=my_natom) 585 if (paral_atom) then 586 ABI_MALLOC(atm_indx,(natom)) 587 atm_indx=-1 588 do iatom=1,my_natom 589 atm_indx(my_atmtab(iatom))=iatom 590 end do 591 end if 592 593 !Set up parallelism over real space grid and/or FFT 594 n1=ngfft(1);n2=ngfft(2);n3=ngfft(3);nfftot=n1*n2*n3 595 my_comm_grid=xmpi_comm_self;my_comm_fft=xmpi_comm_self;me_fft=0 596 my_me_g0=1;my_paral_kgb=0;paral_grid=.false.;nullify(my_distribfft) 597 if (present(mpi_comm_grid).or.present(comm_fft)) then 598 if (present(mpi_comm_grid)) my_comm_grid=mpi_comm_grid 599 if (present(comm_fft)) my_comm_fft=comm_fft 600 if (.not.present(mpi_comm_grid)) my_comm_grid=comm_fft 601 if (.not.present(comm_fft)) my_comm_fft=mpi_comm_grid 602 paral_grid=(xmpi_comm_size(my_comm_grid)>1) 603 me_fft=xmpi_comm_rank(my_comm_fft) 604 end if 605 if (optgr2==1.or.optstr2==1) then 606 if (present(comm_fft)) then 607 if ((.not.present(paral_kgb)).or.(.not.present(me_g0)).or.(.not.present(distribfft))) then 608 ABI_BUG(' Need paral_kgb, me_g0 and distribfft with comm_fft !') 609 end if 610 my_me_g0=me_g0;my_paral_kgb=paral_kgb 611 my_distribfft => distribfft 612 else 613 ABI_MALLOC(my_distribfft,) 614 call init_distribfft_seq(my_distribfft,'f',n2,n3,'fourdp') 615 end if 616 if (n2 == my_distribfft%n2_coarse) then 617 fftn3_distrib => my_distribfft%tab_fftdp3_distrib 618 ffti3_local => my_distribfft%tab_fftdp3_local 619 else 620 fftn3_distrib => my_distribfft%tab_fftdp3dg_distrib 621 ffti3_local => my_distribfft%tab_fftdp3dg_local 622 end if 623 else 624 nullify(my_distribfft,fftn3_distrib,ffti3_local) 625 end if 626 627 !---------------------------------------------------------------------- 628 !Initializations 629 630 !Compute different geometric tensors 631 !ucvol is not computed here but provided as input arg 632 call metric(gmet,gprimd,-1,rmet,rprimd,ucvol_) 633 fact_ucvol=ucvol/dble(nfftot) 634 635 !Retrieve local potential according to the use of nhat in XC 636 usexcnhat=maxval(pawtab(1:ntypat)%usexcnhat) 637 if (usexcnhat==0) then 638 ! dimvtrial=nspden 639 dimvtrial=1 640 ABI_MALLOC(vtrial_,(nfft,dimvtrial)) 641 !!!$OMP PARALLEL DO PRIVATE(ic) SHARED(nfft,vtrial,vtrial_,vxc) 642 do ic=1,nfft 643 vtrial_(ic,1:dimvtrial)=vtrial(ic,1:dimvtrial)-vxc(ic,1:dimvtrial) 644 end do 645 else 646 dimvtrial=nspden 647 vtrial_ => vtrial 648 end if 649 650 !Initializations and allocations 651 ngrhat=0;ngrad=0;ngradp=0;ngrad_nondiag=0;ngradp_nondiag=0 652 ishift_grhoij=0;ishift_gr=0;ishift_gr2=0;ishift_str=0;ishift_str2=0;ishift_str2is=0;ishift2_gr=0 653 cplex=1;if (qne0==1) cplex=2 654 if (optgr==1) then 655 ABI_MALLOC(hatgr,(3*natom)) 656 hatgr=zero 657 ngrad=ngrad+3 658 ngrhat=ngrhat+3 659 ishift_gr2=ishift_gr2+3 660 end if 661 if (optgr2==1) then 662 mu=min(dyfr_cplex,cplex) 663 ngrad =ngrad +9 664 ngradp=ngradp+3 665 ngrad_nondiag = ngrad_nondiag +9*mu 666 ngradp_nondiag= ngradp_nondiag+3*mu 667 ngrhat= ngrhat+9*mu 668 end if 669 if (optstr==1) then 670 hatstr=zero 671 ngrad=ngrad+6 672 ngrhat=ngrhat+6 673 ishift_gr=ishift_gr+6 674 ishift_gr2=ishift_gr2+6 675 ishift_str2=ishift_str2+6 676 ishift_str2is = ishift_str2is+6 677 end if 678 if (optstr2==1) then 679 ngrad =ngrad+6*(6+3) 680 ngradp=ngradp+(6+3) 681 ngrad_nondiag =ngrad_nondiag+6*(6+3) 682 ngradp_nondiag=ngradp_nondiag+3 683 ishift2_gr=ishift2_gr+3 684 ngrhat=ngrhat+6*(6+3) 685 ishift_gr=ishift_gr+(6+3) 686 ishift_gr2=ishift_gr2+6*(6+3) 687 ishift_str2is=ishift_str2is+36 688 ishift_grhoij = 6 689 end if 690 691 !DEBUG 692 ! write(6,*)' preparatory computations : usexcnhat, nspden, dimvtrial=',usexcnhat, nspden, dimvtrial 693 !ENDDEBUG 694 !nsploop=nspden;if (dimvtrial<nspden) nsploop=2 695 nsploop=nspden;if (dimvtrial<nspden .and. nspden==4) nsploop=1 696 if (optgr2/=1.and.optstr2/=1) then 697 ABI_MALLOC(grhat_tmp,(ngrhat,1)) 698 else 699 ABI_MALLOC(grhat_tmp,(ngrhat,natom)) 700 grhat_tmp=zero 701 ABI_MALLOC(prod_nondiag,(natom)) 702 ABI_MALLOC(prodp_nondiag,(natom)) 703 ABI_MALLOC(atindx,(natom)) 704 if(optgr2==1.or.optstr2==1)then 705 ABI_MALLOC(vpsp1_gr,(cplex*nfft,3)) 706 vpsp1_gr(:,:)= zero 707 end if 708 if (optgr2==1) then 709 ABI_MALLOC(dyfr,(dyfr_cplex,3,3,natom,natom)) 710 dyfr=zero 711 end if 712 if (optstr2==1) then 713 ABI_MALLOC(vpsp1_str,(cplex*nfft,6)) 714 ABI_MALLOC(grhat_tmp2,(18,natom)) 715 ABI_MALLOC(eltfr,(6+3*natom,6)) 716 eltfr=zero 717 end if 718 ABI_MALLOC(mu4,(4)) 719 atindx(:)=0 720 do iatom=1,natom 721 iatm=0 722 do while (atindx(iatom)==0.and.iatm<natom) 723 iatm=iatm+1;if (atindx1(iatm)==iatom) atindx(iatom)=iatm 724 end do 725 end do 726 end if 727 728 !The computation of dynamical matrix and elastic tensor requires the knowledge of 729 !g_l(r-R).Y_lm(r-R) and derivatives for all atoms 730 !Compute them here, except memory saving is activated 731 if ((.not.save_memory).and.(optgr2==1.or.optstr2==1)) then 732 do jatom=1,size(pawfgrtab) 733 jatom_tot=jatom;if (paral_atom_pawfgrtab) jatom_tot=my_atmtab(jatom) 734 pawfgrtab_jatom => pawfgrtab(jatom) 735 lm_sizej=pawfgrtab_jatom%l_size**2 736 opt1=0;opt2=0;opt3=0 737 if (pawfgrtab_jatom%gylm_allocated==0) then 738 if (allocated(pawfgrtab_jatom%gylm)) then 739 ABI_FREE(pawfgrtab_jatom%gylm) 740 end if 741 ABI_MALLOC(pawfgrtab_jatom%gylm,(pawfgrtab_jatom%nfgd,lm_sizej)) 742 pawfgrtab_jatom%gylm_allocated=2;opt1=1 743 end if 744 if (pawfgrtab_jatom%gylmgr_allocated==0) then 745 if (allocated(pawfgrtab_jatom%gylmgr)) then 746 ABI_FREE(pawfgrtab_jatom%gylmgr) 747 end if 748 ABI_MALLOC(pawfgrtab_jatom%gylmgr,(3,pawfgrtab_jatom%nfgd,lm_sizej)) 749 pawfgrtab_jatom%gylmgr_allocated=2;opt2=1 750 end if 751 if (opt1+opt2+opt3>0) then 752 call pawgylm(pawfgrtab_jatom%gylm,pawfgrtab_jatom%gylmgr,& 753 & pawfgrtab_jatom%gylmgr2,lm_sizej,pawfgrtab_jatom%nfgd,& 754 & opt1,opt2,opt3,pawtab(typat(jatom_tot)),pawfgrtab_jatom%rfgd) 755 end if 756 if (optgr2==1.and.qne0==1) then 757 if (pawfgrtab_jatom%expiqr_allocated==0) then 758 if (allocated(pawfgrtab_jatom%expiqr)) then 759 ABI_FREE(pawfgrtab_jatom%expiqr) 760 end if 761 pawfgrtab_jatom%expiqr_allocated=2 762 ABI_MALLOC(pawfgrtab_jatom%expiqr,(2,nfgd)) 763 call pawexpiqr(pawfgrtab_jatom%expiqr,gprimd,pawfgrtab_jatom%nfgd,& 764 & qphon,pawfgrtab_jatom%rfgd,xred(:,jatom_tot)) 765 end if 766 end if 767 end do 768 end if 769 770 !The computation of dynamical matrix and elastic tensor might require some communications 771 if ((optgr2==1.or.optstr2==1).and.paral_atom.and.paral_atom_pawfgrtab.and.(.not.save_memory)) then 772 ABI_MALLOC(pawfgrtab_tot,(natom)) 773 call pawfgrtab_nullify(pawfgrtab_tot) 774 call pawfgrtab_gather(pawfgrtab,pawfgrtab_tot,my_comm_atom,ier,mpi_atmtab=my_atmtab) 775 else 776 pawfgrtab_tot => pawfgrtab 777 end if 778 if ((optgr2==1.or.optstr2==1).and.paral_atom.and.paral_atom_pawrhoij) then 779 ABI_MALLOC(pawrhoij_tot,(natom)) 780 call pawrhoij_nullify(pawrhoij_tot) 781 call pawrhoij_gather(pawrhoij,pawrhoij_tot,-1,my_comm_atom, & 782 & with_rhoijres=.false.,with_rhoij_=.false.,with_lmnmix=.false.) 783 else 784 pawrhoij_tot => pawrhoij 785 end if 786 787 if (save_memory) then 788 pawfgrtab_ => pawfgrtab 789 pawrhoij_ => pawrhoij 790 else 791 pawfgrtab_ => pawfgrtab_tot 792 pawrhoij_ => pawrhoij_tot 793 end if 794 795 !---------------------------------------------------------------------- 796 !Loops over types and atoms 797 798 iatshft=0 799 do itypat=1,ntypat 800 801 lmn2_size=pawtab(itypat)%lmn2_size 802 lm_size=pawtab(itypat)%lcut_size**2 803 804 do iatm=iatshft+1,iatshft+nattyp(itypat) 805 806 iatom_tot=atindx1(iatm) 807 iatom=iatom_tot 808 if (paral_atom) then 809 if (save_memory.or.(optgr2/=1.and.optstr2/=1)) iatom=atm_indx(iatom_tot) 810 end if 811 812 if (iatom==-1) cycle 813 iatom_pawfgrtab=iatom_tot;if (paral_atom_pawfgrtab) iatom_pawfgrtab=iatom 814 iatom_pawrhoij =iatom_tot;if (paral_atom_pawrhoij) iatom_pawrhoij =iatom 815 pawfgrtab_iatom => pawfgrtab_(iatom_pawfgrtab) 816 pawrhoij_iatom => pawrhoij_(iatom_pawrhoij) 817 818 idiag=1;if (optgr2==1.or.optstr2==1) idiag=iatm 819 nfgd=pawfgrtab_iatom%nfgd 820 821 ABI_MALLOC(vloc,(nfgd)) 822 if (ngrad>0) then 823 ABI_MALLOC(prod,(ngrad,lm_size)) 824 end if 825 if (ngradp>0) then 826 ABI_MALLOC(prodp,(ngradp,lm_size)) 827 end if 828 if (ngrad_nondiag>0.and.ngradp_nondiag>0) then 829 do jatm=1,natom 830 jtypat=typat(atindx1(jatm)) 831 lm_sizej=pawtab(jtypat)%lcut_size**2 832 ABI_MALLOC(prod_nondiag(jatm)%value,(ngrad_nondiag,lm_sizej)) 833 ABI_MALLOC(prodp_nondiag(jatm)%value,(ngradp_nondiag,lm_sizej)) 834 prod_nondiag(jatm)%value=zero 835 prodp_nondiag(jatm)%value=zero 836 end do 837 end if 838 839 grhat_tmp=zero 840 if(optstr2==1) grhat_tmp2=zero 841 842 ! ------------------------------------------------------------------ 843 ! Compute some useful data 844 845 ! Eventually compute g_l(r).Y_lm(r) derivatives for the current atom (if not already done) 846 if ((optgr==1.or.optstr==1).and.(optgr2/=1).and.(optstr2/=1)) then 847 if (pawfgrtab_iatom%gylmgr_allocated==0) then 848 if (allocated(pawfgrtab_iatom%gylmgr)) then 849 ABI_FREE(pawfgrtab_iatom%gylmgr) 850 end if 851 ABI_MALLOC(pawfgrtab_iatom%gylmgr,(3,pawfgrtab_iatom%nfgd,lm_size)) 852 pawfgrtab_iatom%gylmgr_allocated=2 853 call pawgylm(rdum,pawfgrtab_iatom%gylmgr,rdum2,lm_size,pawfgrtab_iatom%nfgd,& 854 & 0,1,0,pawtab(itypat),pawfgrtab_iatom%rfgd) 855 end if 856 857 end if 858 if (optgr2==1.or.optstr2==1) then 859 opt1=0;opt2=0;opt3=0 860 if (pawfgrtab_iatom%gylm_allocated==0) then 861 if (allocated(pawfgrtab_iatom%gylm)) then 862 ABI_FREE(pawfgrtab_iatom%gylm) 863 end if 864 ABI_MALLOC(pawfgrtab_iatom%gylm,(pawfgrtab_iatom%nfgd,lm_size)) 865 pawfgrtab_iatom%gylm_allocated=2;opt1=1 866 end if 867 if (pawfgrtab_iatom%gylmgr_allocated==0) then 868 if (allocated(pawfgrtab_iatom%gylmgr)) then 869 ABI_FREE(pawfgrtab_iatom%gylmgr) 870 end if 871 ABI_MALLOC(pawfgrtab_iatom%gylmgr,(3,pawfgrtab_iatom%nfgd,lm_size)) 872 pawfgrtab_iatom%gylmgr_allocated=2;opt2=1 873 end if 874 if (pawfgrtab_iatom%gylmgr2_allocated==0) then 875 if (allocated(pawfgrtab_iatom%gylmgr2)) then 876 ABI_FREE(pawfgrtab_iatom%gylmgr2) 877 end if 878 ABI_MALLOC(pawfgrtab_iatom%gylmgr2,(6,pawfgrtab_iatom%nfgd,lm_size)) 879 pawfgrtab_iatom%gylmgr2_allocated=2;opt3=1 880 end if 881 if (opt1+opt2+opt3>0) then 882 call pawgylm(pawfgrtab_iatom%gylm,pawfgrtab_iatom%gylmgr,& 883 & pawfgrtab_iatom%gylmgr2,lm_size,pawfgrtab_iatom%nfgd,& 884 & opt1,opt2,opt3,pawtab(itypat),pawfgrtab_iatom%rfgd) 885 end if 886 end if 887 888 ! Eventually compute exp(-i.q.r) factors for the current atom (if not already done) 889 if (optgr2==1.and.qne0==1.and.(pawfgrtab_iatom%expiqr_allocated==0)) then 890 if (allocated(pawfgrtab_iatom%expiqr)) then 891 ABI_FREE(pawfgrtab_iatom%expiqr) 892 end if 893 ABI_MALLOC(pawfgrtab_iatom%expiqr,(2,nfgd)) 894 call pawexpiqr(pawfgrtab_iatom%expiqr,gprimd,nfgd,qphon,& 895 & pawfgrtab_iatom%rfgd,xred(:,iatom)) 896 pawfgrtab_iatom%expiqr_allocated=2 897 end if 898 has_phase=(optgr2==1.and.pawfgrtab_iatom%expiqr_allocated/=0) 899 900 ! Eventually compute 1st-order potential 901 if (optgr2==1.or.optstr2==1) then 902 call dfpt_atm2fft(atindx,cplex,gmet,gprimd,gsqcut,idir,iatom_tot,& 903 & mgfft,psps%mqgrid_vl,natom,3,nfft,ngfft,ntypat,ph1d,& 904 & psps%qgrid_vl,qphon,typat,ucvol,psps%usepaw,xred,psps,pawtab,atmvlocr1=vpsp1_gr,& 905 & vspl=psps%vlspl,comm_fft=my_comm_fft,me_g0=my_me_g0,& 906 & paral_kgb=my_paral_kgb,distribfft=my_distribfft) 907 if (cplex==1) then 908 do ic=1,nfft 909 tmp(1:3)=vpsp1_gr(ic,1:3) 910 do mu=1,3 911 vpsp1_gr(ic,mu)=-(gprimd(mu,1)*tmp(1)+gprimd(mu,2)*tmp(2)+gprimd(mu,3)*tmp(3)) 912 end do 913 end do 914 else ! cplex=2 915 do ic=1,nfft 916 jc=2*ic;tmp(1:3)=vpsp1_gr(jc-1,1:3);tmp(4:6)=vpsp1_gr(jc,1:3) 917 do mu=1,3 918 vpsp1_gr(jc-1,mu)=-(gprimd(mu,1)*tmp(1)+gprimd(mu,2)*tmp(2)+gprimd(mu,3)*tmp(3)) 919 vpsp1_gr(jc ,mu)=-(gprimd(mu,1)*tmp(4)+gprimd(mu,2)*tmp(5)+gprimd(mu,3)*tmp(6)) 920 end do 921 end do 922 end if 923 end if 924 if (optstr2==1) then 925 vpsp1_str(:,:) = zero 926 call dfpt_atm2fft(atindx,cplex,gmet,gprimd,gsqcut,idir,natom+3,& 927 & mgfft,psps%mqgrid_vl,natom,6,nfft,ngfft,ntypat,& 928 & ph1d,psps%qgrid_vl,qphon,typat,ucvol,psps%usepaw,xred,psps,pawtab,atmvlocr1=vpsp1_str,& 929 & vspl=psps%vlspl,comm_fft=my_comm_fft,me_g0=my_me_g0,& 930 & paral_kgb=my_paral_kgb,distribfft=my_distribfft) 931 end if 932 933 ! ------------------------------------------------------------------ 934 ! Loop over spin components 935 936 do ispden=1,nsploop 937 938 ! ----- Retrieve potential (subtle if nspden=4 ;-) 939 if (nspden/=4) then 940 ispvtr=min(dimvtrial,ispden) 941 do ic=1,nfgd 942 jc = pawfgrtab_iatom%ifftsph(ic) 943 vloc(ic)=vtrial_(jc,ispvtr) 944 end do 945 else 946 if (ispden==1) then 947 ispvtr=min(dimvtrial,2) 948 do ic=1,nfgd 949 jc=pawfgrtab_iatom%ifftsph(ic) 950 vloc(ic)=half*(vtrial_(jc,1)+vtrial_(jc,ispvtr)) 951 end do 952 else if (ispden==4) then 953 ispvtr=min(dimvtrial,2) 954 do ic=1,nfgd 955 jc=pawfgrtab_iatom%ifftsph(ic) 956 vloc(ic)=half*(vtrial_(jc,1)-vtrial_(jc,ispvtr)) 957 end do 958 else if (ispden==2) then 959 ispvtr=min(dimvtrial,3) 960 do ic=1,nfgd 961 jc=pawfgrtab_iatom%ifftsph(ic) 962 vloc(ic)=vtrial_(jc,ispvtr) 963 end do 964 else ! ispden=3 965 ispvtr=min(dimvtrial,4) 966 do ic=1,nfgd 967 jc=pawfgrtab_iatom%ifftsph(ic) 968 vloc(ic)=-vtrial_(jc,ispvtr) 969 end do 970 end if 971 end if 972 973 ! ----------------------------------------------------------------------- 974 ! ----- Compute projected scalars (integrals of vloc and Q_ij^hat) ------ 975 ! ----- and/or their derivatives ---------------------------------------- 976 977 if (ngrad>0) prod=zero 978 if (ngradp>0) prodp=zero 979 980 ! ==== Contribution to forces ==== 981 if (optgr==1) then 982 do ilm=1,lm_size 983 do ic=1,pawfgrtab_iatom%nfgd 984 do mu=1,3 985 prod(mu+ishift_gr,ilm)=prod(mu+ishift_gr,ilm)-& 986 & vloc(ic)*pawfgrtab_iatom%gylmgr(mu,ic,ilm) 987 end do 988 end do 989 end do 990 end if ! optgr 991 992 ! ==== Contribution to stresses ==== 993 if (optstr==1) then 994 do ilm=1,lm_size 995 do ic=1,pawfgrtab_iatom%nfgd 996 jc=pawfgrtab_iatom%ifftsph(ic) 997 do mu=1,6 998 mua=alpha(mu);mub=beta(mu) 999 prod(mu+ishift_str,ilm)=prod(mu+ishift_str,ilm) & 1000 & +half*vloc(ic)& 1001 & *(pawfgrtab_iatom%gylmgr(mua,ic,ilm)*pawfgrtab_iatom%rfgd(mub,ic)& 1002 & +pawfgrtab_iatom%gylmgr(mub,ic,ilm)*pawfgrtab_iatom%rfgd(mua,ic)) 1003 end do 1004 end do 1005 end do 1006 end if ! optstr 1007 !DEBUG 1008 ! write(6,*)' after loops on ilm, ic, mu : ispden,lm_size, pawfgrtab_iatom%nfgd=',ispden,lm_size, pawfgrtab_iatom%nfgd 1009 ! write(6,*)' after loops on ilm, ic, mu, writes ilm, prod(1+ishift_str,ilm:lm_size) when bigger than tol10 (ilm between 1 and lm_size)' 1010 ! do ilm=1, lm_size 1011 ! if( abs(prod(1+ishift_str,ilm))>tol6 )then 1012 ! write(6,*)ilm,prod(1+ishift_str,ilm) 1013 ! endif 1014 ! enddo 1015 !ENDDEBUG 1016 1017 ! ==== Diagonal contribution to frozen wf part of dyn. matrix ==== 1018 if (optgr2==1) then 1019 ! Diagonal contribution 1020 do ilm=1,lm_size 1021 do ic=1,pawfgrtab_iatom%nfgd 1022 do mu=1,9 1023 prod(ishift_gr2+mu,ilm)=prod(ishift_gr2+mu,ilm) & 1024 & +half*vloc(ic)*pawfgrtab_iatom%gylmgr2(mu9(mu),ic,ilm) 1025 end do 1026 do mu=1,3 1027 prodp(ishift_gr+mu,ilm)=prodp(ishift_gr+mu,ilm) & 1028 & -vloc(ic)*pawfgrtab_iatom%gylmgr(mu,ic,ilm) 1029 end do 1030 end do 1031 end do 1032 end if ! optgr2 1033 1034 ! ==== Diagonal contribution to elastic tensor ==== 1035 if (optstr2==1) then 1036 do ilm=1,lm_size 1037 do ic=1,pawfgrtab_iatom%nfgd 1038 mu=1 1039 jc=pawfgrtab_iatom%ifftsph(ic) 1040 do mua=1,6 1041 eps_alpha=eps1(mua);eps_beta=eps2(mua); 1042 do mub=1,6 1043 eps_gamma=eps1(mub);eps_delta=eps2(mub); 1044 mu4 = zero 1045 call pawgrnl_convert(mu4,eps_alpha,eps_beta,eps_gamma,eps_delta) 1046 ! v_loc*d2glylm 1047 prod(ishift_str2+mu,ilm)=prod(ishift_str2+mu,ilm) + half*half*vloc(ic)*( & 1048 & pawfgrtab_iatom%rfgd(eps_beta,ic)*pawfgrtab_iatom%rfgd(eps_gamma,ic)*& 1049 & pawfgrtab_iatom%gylmgr2(mu4(2),ic,ilm)& 1050 & +pawfgrtab_iatom%rfgd(eps_alpha,ic)*pawfgrtab_iatom%rfgd(eps_gamma,ic)*& 1051 pawfgrtab_iatom%gylmgr2(mu4(4),ic,ilm)& 1052 & +pawfgrtab_iatom%rfgd(eps_beta,ic) *pawfgrtab_iatom%rfgd(eps_delta,ic)*& 1053 pawfgrtab_iatom%gylmgr2(mu4(1),ic,ilm)& 1054 & +pawfgrtab_iatom%rfgd(eps_alpha,ic)*pawfgrtab_iatom%rfgd(eps_delta,ic)*& 1055 pawfgrtab_iatom%gylmgr2(mu4(3),ic,ilm)) 1056 if(eps_gamma==eps_beta)then 1057 prod(ishift_str2+mu,ilm)=prod(ishift_str2+mu,ilm) & 1058 & +half*half*vloc(ic)*(pawfgrtab_iatom%gylmgr(eps_delta,ic,ilm)*pawfgrtab_iatom%rfgd(eps_alpha,ic)) 1059 end if 1060 if(eps_gamma==eps_alpha)then 1061 prod(ishift_str2+mu,ilm)=prod(ishift_str2+mu,ilm) & 1062 & +half*half*vloc(ic)*(pawfgrtab_iatom%gylmgr(eps_delta,ic,ilm)*pawfgrtab_iatom%rfgd(eps_beta,ic)) 1063 end if 1064 if(eps_delta==eps_beta)then 1065 prod(ishift_str2+mu,ilm)=prod(ishift_str2+mu,ilm) & 1066 & +half*half*vloc(ic)*(pawfgrtab_iatom%gylmgr(eps_gamma,ic,ilm)*pawfgrtab_iatom%rfgd(eps_alpha,ic)) 1067 end if 1068 if(eps_delta==eps_alpha)then 1069 prod(ishift_str2+mu,ilm)=prod(ishift_str2+mu,ilm) & 1070 & +half*half*vloc(ic)*(pawfgrtab_iatom%gylmgr(eps_gamma,ic,ilm)*pawfgrtab_iatom%rfgd(eps_beta,ic)) 1071 end if 1072 ! d(vloc)/d(eps_gammadelta) * d(gylm)/d(eps_alphabeta) 1073 prod(ishift_str2+mu,ilm)=prod(ishift_str2+mu,ilm)& 1074 & +vpsp1_str(jc,mub)*half*(& 1075 & (pawfgrtab_iatom%gylmgr(eps_alpha,ic,ilm)*pawfgrtab_iatom%rfgd(eps_beta,ic)& 1076 & +pawfgrtab_iatom%gylmgr(eps_beta,ic,ilm) *pawfgrtab_iatom%rfgd(eps_alpha,ic))) 1077 ! d(vloc)/d(eps_alphabeta) * d(gylm)/d(eps_gammadelta) 1078 prod(ishift_str2+mu,ilm)=prod(ishift_str2+mu,ilm)& 1079 & +vpsp1_str(jc,mua)*half*(& 1080 & (pawfgrtab_iatom%gylmgr(eps_gamma,ic,ilm)*pawfgrtab_iatom%rfgd(eps_delta,ic)& 1081 & +pawfgrtab_iatom%gylmgr(eps_delta,ic,ilm)*pawfgrtab_iatom%rfgd(eps_gamma,ic))) 1082 ! delta_alphabeta * dv_loc/depsgammadelta * (gylm) 1083 if (mua<=3) then 1084 prod(ishift_str2+mu,ilm)=prod(ishift_str2+mu,ilm) & 1085 & +vpsp1_str(jc,mub)*pawfgrtab_iatom%gylm(ic,ilm) 1086 end if 1087 ! delta_gammadelta * dv_loc/depsalphabeta * (gylm) 1088 if (mub<=3) then 1089 prod(ishift_str2+mu,ilm)=prod(ishift_str2+mu,ilm) & 1090 & +vpsp1_str(jc,mua) * pawfgrtab_iatom%gylm(ic,ilm) 1091 end if 1092 ! delta_gammadelta * v_loc * d(gylm)/d(eps_alphabeta) 1093 if (mub<=3) then 1094 prod(ishift_str2+mu,ilm)=prod(ishift_str2+mu,ilm) & 1095 & +half*vloc(ic)& 1096 & *(pawfgrtab_iatom%gylmgr(eps_beta,ic,ilm)*pawfgrtab_iatom%rfgd(eps_alpha,ic)& 1097 & + pawfgrtab_iatom%gylmgr(eps_alpha,ic,ilm)*pawfgrtab_iatom%rfgd(eps_beta,ic)) 1098 end if 1099 ! delta_alphabeta * v_loc * d(gylm)/d(eps_gammadelta) 1100 if (mua<=3) then 1101 prod(ishift_str2+mu,ilm)=prod(ishift_str2+mu,ilm) & 1102 & +half*vloc(ic)& 1103 & *(pawfgrtab_iatom%gylmgr(eps_gamma,ic,ilm)*pawfgrtab_iatom%rfgd(eps_delta,ic)& 1104 & + pawfgrtab_iatom%gylmgr(eps_delta,ic,ilm)*pawfgrtab_iatom%rfgd(eps_gamma,ic)) 1105 end if 1106 ! delta_gammadelta delta_alphabeta * v_loc * (gylm) 1107 if (mua<=3.and.mub<=3) then 1108 prod(ishift_str2+mu,ilm)=prod(ishift_str2+mu,ilm) & 1109 & +vloc(ic)*pawfgrtab_iatom%gylm(ic,ilm) 1110 end if 1111 mu=mu+1 1112 end do !end loop mub 1113 end do !end loop mua 1114 ! vloc * d(gylm)/d(eps_alphabeta) 1115 do mu=1,6 1116 mua=alpha(mu);mub=beta(mu) 1117 prodp(ishift_str2+mu,ilm)=prodp(ishift_str2+mu,ilm)& 1118 & +half*vloc(ic)*& 1119 & (pawfgrtab_iatom%gylmgr(mua,ic,ilm)*pawfgrtab_iatom%rfgd(mub,ic)& 1120 & +pawfgrtab_iatom%gylmgr(mub,ic,ilm)*pawfgrtab_iatom%rfgd(mua,ic)) 1121 ! d(vloc)/d(eps_alphabeta or gammadelta) * gylm 1122 prodp(ishift_str2+mu,ilm)=prodp(ishift_str2+mu,ilm)& 1123 & +vpsp1_str(jc,mu)*pawfgrtab_iatom%gylm(ic,ilm) 1124 ! delta_alphabeta * vloc * gylm 1125 if (mu<=3) then 1126 prodp(ishift_str2+mu,ilm)=prodp(ishift_str2+mu,ilm)& 1127 & +vloc(ic)*pawfgrtab_iatom%gylm(ic,ilm) 1128 end if 1129 1130 ! INTERNAL STRAIN CONTRIBUTION: 1131 do idir=1,3 1132 ! v_loc*d2glylm/dR contribution: 1133 eps_alpha=alpha(mu);eps_beta=beta(mu); 1134 call pawgrnl_convert(mu4,eps_alpha,eps_beta,idir,idir) 1135 prod(ishift_str2is+(mu-1)*3+idir,ilm)=prod(ishift_str2is+(mu-1)*3+idir,ilm)& 1136 & -half*vloc(ic)& 1137 & *(pawfgrtab_iatom%gylmgr2(mu4(3),ic,ilm)*pawfgrtab_iatom%rfgd(eps_alpha,ic)& 1138 & +pawfgrtab_iatom%gylmgr2(mu4(1),ic,ilm)*pawfgrtab_iatom%rfgd(eps_beta,ic)) 1139 if (idir==eps_beta)then 1140 prod(ishift_str2is+(mu-1)*3+idir,ilm)=prod(ishift_str2is+(mu-1)*3+idir,ilm)& 1141 & -half*vloc(ic)*(pawfgrtab_iatom%gylmgr(eps_alpha,ic,ilm)) 1142 end if 1143 if (idir==eps_alpha)then 1144 prod(ishift_str2is+(mu-1)*3+idir,ilm)=prod(ishift_str2is+(mu-1)*3+idir,ilm)& 1145 & -half*vloc(ic)*(pawfgrtab_iatom%gylmgr(eps_beta,ic,ilm)) 1146 end if 1147 ! delta_gammadelta * v_loc * d(gylm)/dR 1148 if (mu<=3) then 1149 prod(ishift_str2is+(mu-1)*3+idir,ilm)=prod(ishift_str2is+(mu-1)*3+idir,ilm)-& 1150 vloc(ic)*pawfgrtab_iatom%gylmgr(idir,ic,ilm) 1151 end if 1152 ! dv_loc/deps_alph_beta * d(gylm)/dR 1153 prod(ishift_str2is+(mu-1)*3+idir,ilm)=prod(ishift_str2is+(mu-1)*3+idir,ilm)-& 1154 vpsp1_str(jc,mu)*pawfgrtab_iatom%gylmgr(idir,ic,ilm) 1155 end do 1156 end do 1157 do idir=1,3 1158 ! v_loc * d(gylm)/dR 1159 prodp(6+idir,ilm) = prodp(6+idir,ilm)-vloc(ic)*pawfgrtab_iatom%gylmgr(idir,ic,ilm) 1160 end do !end loop idir 1161 ! END INTERNAL STRAIN CONTRIBUTION 1162 1163 end do 1164 end do 1165 end if !optstr2 1166 1167 ! Off-diagonal contributions 1168 if (optgr2==1.or.optstr2==1) then 1169 do jatm=1,natom 1170 jatom_tot=atindx1(jatm);jtypat=typat(jatom_tot) 1171 jatom=jatom_tot;if (paral_atom.and.save_memory) jatom=atm_indx(jatom_tot) 1172 lm_sizej=pawtab(jtypat)%lcut_size**2 1173 1174 ! Retrieve data for the atom j 1175 if (save_memory.and.jatom/=iatom) then 1176 rcut_jatom=pawtab(jtypat)%rshp 1177 call pawrfgd_fft(ifftsph_tmp,gmet,n1,n2,n3,nfgd_jatom,rcut_jatom,rfgd_tmp,rprimd,& 1178 & ucvol,xred(:,jatom_tot),fft_distrib=fftn3_distrib,fft_index=ffti3_local,me_fft=me_fft) 1179 ifft_jatom => ifftsph_tmp ; rfgd_jatom => rfgd_tmp 1180 ABI_MALLOC(gylm_jatom,(nfgd_jatom,lm_sizej)) 1181 ABI_MALLOC(gylmgr_jatom,(3,nfgd_jatom,lm_sizej)) 1182 opt1=1;opt2=1;opt3=0;gylmgr2_jatom=>gylmgr_jatom 1183 call pawgylm(gylm_jatom,gylmgr_jatom,gylmgr2_jatom,lm_sizej,nfgd_jatom,& 1184 & opt1,opt2,opt3,pawtab(typat(jatom_tot)),rfgd_jatom) 1185 if (optgr2==1.and.qne0==1) then 1186 ABI_MALLOC(expiqr_jatom,(2,nfgd_jatom)) 1187 call pawexpiqr(expiqr_jatom,gprimd,nfgd_jatom,qphon,rfgd_jatom,xred(:,jatom_tot)) 1188 end if 1189 else 1190 pawfgrtab_jatom => pawfgrtab_tot(jatom) 1191 nfgd_jatom = pawfgrtab_jatom%nfgd 1192 ifft_jatom => pawfgrtab_jatom%ifftsph 1193 rfgd_jatom => pawfgrtab_jatom%rfgd 1194 gylm_jatom => pawfgrtab_jatom%gylm 1195 gylmgr_jatom => pawfgrtab_jatom%gylmgr 1196 gylmgr2_jatom => pawfgrtab_jatom%gylmgr2 1197 expiqr_jatom => pawfgrtab_jatom%expiqr 1198 end if 1199 1200 ! ==== Off-diagonal contribution to frozen wf part of dyn. matrix ==== 1201 if (optgr2==1) then 1202 mu = min(dyfr_cplex,cplex) 1203 prod_nondiag(jatm)%value(ishift_gr2+1:ishift_gr2+(9*mu),:) = zero 1204 prodp_nondiag(jatm)%value(ishift2_gr+1:ishift2_gr +(3*mu),:) = zero 1205 if (has_phase.or.cplex==2) then 1206 if (dyfr_cplex==1.or.cplex==1) then 1207 do ilm=1,lm_sizej 1208 do ic=1,nfgd_jatom 1209 jc=2*ifft_jatom(ic) 1210 tmp(1:3)=vpsp1_gr(jc-1,1:3)*expiqr_jatom(1,ic) & 1211 & -vpsp1_gr(jc ,1:3)*expiqr_jatom(2,ic) 1212 do mu=1,9 1213 mua=alpha(mu);mub=beta(mu) 1214 prod_nondiag(jatm)%value(ishift_gr2+mu,ilm)=prod_nondiag(jatm)%value(ishift_gr2+mu,ilm) & 1215 & +tmp(mua)*gylmgr_jatom(mub,ic,ilm) 1216 end do 1217 do mu=1,3 1218 prodp_nondiag(jatm)%value(ishift2_gr+mu,ilm)=prodp_nondiag(jatm)%value(ishift2_gr+mu,ilm) & 1219 & -tmp(mu)*gylm_jatom(ic,ilm) 1220 end do 1221 end do 1222 end do 1223 else 1224 do ilm=1,lm_sizej 1225 do ic=1,nfgd_jatom 1226 jc=2*ifft_jatom(ic) 1227 tmp(1:3)=vpsp1_gr(jc-1,1:3)*expiqr_jatom(1,ic) & 1228 & -vpsp1_gr(jc ,1:3)*expiqr_jatom(2,ic) 1229 tmp(4:6)=vpsp1_gr(jc-1,1:3)*expiqr_jatom(2,ic) & 1230 & +vpsp1_gr(jc ,1:3)*expiqr_jatom(1,ic) 1231 do mu=1,9 1232 mua=alpha(mu);mub=beta(mu) 1233 prod_nondiag(jatm)%value(ishift_gr2+mu,ilm)=prod_nondiag(jatm)%value(ishift_gr2+mu,ilm) & 1234 & +tmp(mua )*gylmgr_jatom(mub,ic,ilm) 1235 prod_nondiag(jatm)%value(ishift_gr2+9+mu,ilm)=prod_nondiag(jatm)%value(ishift_gr2+9+mu,ilm) & 1236 & +tmp(3+mua)*gylmgr_jatom(mub,ic,ilm) 1237 end do 1238 do mu=1,3 1239 prodp_nondiag(jatm)%value(ishift2_gr+mu,ilm)=prodp_nondiag(jatm)%value(ishift2_gr+mu,ilm) & 1240 & -tmp( mu)*gylm_jatom(ic,ilm) 1241 prodp_nondiag(jatm)%value(ishift2_gr+3+mu,ilm)=prodp_nondiag(jatm)%value(ishift2_gr+3+mu,ilm) & 1242 & -tmp(3+mu)*gylm_jatom(ic,ilm) 1243 end do 1244 end do 1245 end do 1246 end if 1247 else ! no phase 1248 do ilm=1,lm_sizej 1249 do ic=1,nfgd_jatom 1250 jc=ifft_jatom(ic) 1251 do mu=1,9 1252 mua=alpha(mu);mub=beta(mu) 1253 prod_nondiag(jatm)%value(ishift_gr2+mu,ilm)=prod_nondiag(jatm)%value(ishift_gr2+mu,ilm) & 1254 & +vpsp1_gr(jc,mua)*gylmgr_jatom(mub,ic,ilm) 1255 end do 1256 do mu=1,3 1257 prodp_nondiag(jatm)%value(ishift2_gr+mu,ilm)=prodp_nondiag(jatm)%value(ishift2_gr+mu,ilm) & 1258 & -vpsp1_gr(jc,mu)*gylm_jatom(ic,ilm) 1259 end do 1260 end do 1261 end do 1262 end if 1263 end if ! optgr2 1264 1265 ! ==== Off-diagonal contribution to elastic tensor ==== 1266 if (optstr2==1) then 1267 prod_nondiag(jatm)%value(ishift_str2is+1:ishift_str2is+18,:)=zero 1268 prodp_nondiag(jatm)%value(1:3,:)=zero 1269 do ilm=1,lm_sizej 1270 do ic=1,nfgd_jatom 1271 mu=1;jc=ifft_jatom(ic) 1272 ! INTERNAL STRAIN CONTRIBUTION: 1273 do mua=1,6 1274 eps_alpha=eps1(mua);eps_beta=eps2(mua); 1275 ! d(-vloc)/dR * d(gylm)/d(eps_gamma_delta) 1276 do idir=1,3 1277 prod_nondiag(jatm)%value(ishift_str2is+(mua-1)*3+idir,ilm)=& 1278 & prod_nondiag(jatm)%value(ishift_str2is+(mua-1)*3+idir,ilm)& 1279 & -vpsp1_gr(jc,idir)*half& 1280 & *(gylmgr_jatom(eps_alpha,ic,ilm) * rfgd_jatom(eps_beta ,ic)& 1281 & +gylmgr_jatom(eps_beta ,ic,ilm) * rfgd_jatom(eps_alpha,ic)) 1282 ! delta_alphabeta * d(-v_loc/dr) * gylm 1283 if (mua<=3) then 1284 prod_nondiag(jatm)%value(ishift_str2is+(mua-1)*3+idir,ilm)=& 1285 & prod_nondiag(jatm)%value(ishift_str2is+(mua-1)*3+idir,ilm)& 1286 & -vpsp1_gr(jc,idir)*gylm_jatom(ic,ilm) 1287 end if 1288 end do ! dir 1289 end do ! mua 1290 do idir=1,3 1291 ! d(-v_loc/dr) * gylm 1292 prodp_nondiag(jatm)%value(idir,ilm) = prodp_nondiag(jatm)%value(idir,ilm)& 1293 & -vpsp1_gr(jc,idir)*gylm_jatom(ic,ilm) 1294 end do !end loop idir 1295 ! END INTERNAL STRAIN CONTRIBUTION 1296 end do 1297 end do 1298 end if ! optstr2 1299 1300 ! Release temp memory allocated for atom j 1301 if (save_memory.and.jatom/=iatom) then 1302 ABI_FREE(ifftsph_tmp) 1303 ABI_FREE(rfgd_tmp) 1304 ABI_FREE(gylm_jatom) 1305 ABI_FREE(gylmgr_jatom) 1306 if (optgr2==1.and.qne0==1) then 1307 ABI_FREE(expiqr_jatom) 1308 end if 1309 end if 1310 1311 end do ! loop on atoms j 1312 end if ! optgr2 or optstr2 1313 1314 ! --- Apply scaling factor on integrals --- 1315 if (ngrad >0) prod (:,:)=prod (:,:)*fact_ucvol 1316 if (ngradp>0) prodp(:,:)=prodp(:,:)*fact_ucvol 1317 if (ngrad_nondiag>0) then 1318 do jatm=1,natom 1319 prod_nondiag(jatm)%value(:,:)=prod_nondiag(jatm)%value(:,:)*fact_ucvol 1320 end do 1321 end if 1322 if (ngradp_nondiag>0) then 1323 do jatm=1,natom 1324 prodp_nondiag(jatm)%value(:,:)=prodp_nondiag(jatm)%value(:,:)*fact_ucvol 1325 end do 1326 end if 1327 1328 ! --- Reduction in case of parallelization --- 1329 if (paral_grid) then 1330 if (ngrad>0) then 1331 call xmpi_sum(prod,my_comm_grid,ier) 1332 end if 1333 if (ngradp>0) then 1334 call xmpi_sum(prodp,my_comm_grid,ier) 1335 end if 1336 if (ngrad_nondiag>0.or.ngradp_nondiag>0) then 1337 bufsiz=0;bufind=0 1338 do jatm=1,natom 1339 jtypat=typat(atindx1(jatm)) 1340 bufsiz=bufsiz+pawtab(jtypat)%lcut_size**2 1341 end do 1342 ABI_MALLOC(buf,(ngrad_nondiag+ngradp_nondiag,bufsiz)) 1343 do jatm=1,natom 1344 jtypat=typat(atindx1(jatm)) 1345 lm_sizej=pawtab(jtypat)%lcut_size**2 1346 if (ngrad_nondiag> 0) buf(1:ngrad_nondiag,bufind+1:bufind+lm_sizej)= & 1347 & prod_nondiag(jatm)%value(:,:) 1348 if (ngradp_nondiag>0) buf(ngrad_nondiag+1:ngrad_nondiag+ngradp_nondiag, & 1349 & bufind+1:bufind+lm_sizej)=prodp_nondiag(jatm)%value(:,:) 1350 bufind=bufind+lm_sizej*(ngrad_nondiag+ngradp_nondiag) 1351 end do 1352 call xmpi_sum(buf,my_comm_grid,ier) 1353 bufind=0 1354 do jatm=1,natom 1355 jtypat=typat(atindx1(jatm)) 1356 lm_sizej=pawtab(jtypat)%lcut_size**2 1357 if (ngrad> 0) prod_nondiag(jatm)%value(:,:)= & 1358 & buf(1:ngrad_nondiag,bufind+1:bufind+lm_sizej) 1359 if (ngradp>0) prodp_nondiag(jatm)%value(:,:)= & 1360 & buf(ngrad_nondiag+1:ngrad_nondiag+ngradp_nondiag,bufind+1:bufind+lm_sizej) 1361 bufind=bufind+lm_sizej*(ngrad_nondiag+ngradp_nondiag) 1362 end do 1363 ABI_FREE(buf) 1364 end if 1365 end if 1366 1367 ! ---------------------------------------------------------------- 1368 ! Compute final sums (i.e. derivatives of Sum_ij[rho_ij.Intg{Qij.Vloc}] 1369 1370 ! ---- Compute terms common to all gradients 1371 jrhoij=1 1372 do irhoij=1,pawrhoij_iatom%nrhoijsel 1373 klmn=pawrhoij_iatom%rhoijselect(irhoij) 1374 klm =pawtab(itypat)%indklmn(1,klmn) 1375 lmin=pawtab(itypat)%indklmn(3,klmn) 1376 lmax=pawtab(itypat)%indklmn(4,klmn) 1377 ro =pawrhoij_iatom%rhoijp(jrhoij,ispden) 1378 ro_d=ro*pawtab(itypat)%dltij(klmn) 1379 do ll=lmin,lmax,2 1380 do ilm=ll**2+1,(ll+1)**2 1381 isel=pawang%gntselect(ilm,klm) 1382 if (isel>0) then 1383 grhat_x=ro_d*pawtab(itypat)%qijl(ilm,klmn) 1384 do mu=1,ngrad 1385 grhat_tmp(mu,idiag)=grhat_tmp(mu,idiag)+grhat_x*prod(mu,ilm) 1386 ! DEBUG 1387 ! if(mu==ishift_str+1 .and. & 1388 !& (abs(grhat_x*prod(mu,ilm))>tol6 .or. irhoij==1 ) )then 1389 ! write(6,'(a,5i4,3es16.6)')& 1390 !& 'mu,idiag,ilm,irhoij,ll, grhat_tmp(mu,idiag),grhat_x,prod(mu,ilm)=',& 1391 !& mu,idiag,ilm,irhoij,ll, grhat_tmp(mu,idiag),grhat_x,prod(mu,ilm) 1392 ! endif 1393 ! ENDDEBUG 1394 end do 1395 end if 1396 end do 1397 end do 1398 jrhoij=jrhoij+pawrhoij_iatom%cplex_rhoij 1399 end do 1400 1401 ! DEBUG 1402 ! write(6,*)' Accumulation of grhat_tmp : idiag,grhat_tmp(ishift_str+1,idiag),',idiag,grhat_tmp(ishift_str+1,idiag) 1403 ! ENDDEBUG 1404 1405 ! ---- Add additional (diagonal) terms for dynamical matrix 1406 ! ---- Terms including rhoij derivatives 1407 if (optgr2==1) then 1408 klmn1=1 1409 do klmn=1,lmn2_size 1410 klm =pawtab(itypat)%indklmn(1,klmn) 1411 lmin=pawtab(itypat)%indklmn(3,klmn) 1412 lmax=pawtab(itypat)%indklmn(4,klmn) 1413 dlt_tmp=pawtab(itypat)%dltij(klmn) 1414 do ll=lmin,lmax,2 1415 do ilm=ll**2+1,(ll+1)**2 1416 isel=pawang%gntselect(ilm,klm) 1417 if (isel>0) then 1418 ro_d= dlt_tmp*pawtab(itypat)%qijl(ilm,klmn) 1419 do mu=1,9 1420 mua=alpha(mu);mub=beta(mu) 1421 grhat_tmp(ishift_gr2+mu,idiag)=grhat_tmp(ishift_gr2+mu,idiag)& 1422 & +ro_d*pawrhoij_iatom%grhoij(ishift_grhoij+mua,klmn1,ispden)*prodp(mub+ishift_gr,ilm) 1423 end do 1424 end if 1425 end do 1426 end do 1427 klmn1=klmn1+pawrhoij_iatom%cplex_rhoij 1428 end do ! klmn 1429 end if ! optgr2 1430 1431 ! ---- Add additional (diagonal) terms for elastic tensor 1432 ! ---- Terms including rhoij derivatives 1433 if (optstr2==1)then 1434 klmn1=1 1435 do klmn=1,lmn2_size 1436 klm =pawtab(itypat)%indklmn(1,klmn) 1437 lmin=pawtab(itypat)%indklmn(3,klmn) 1438 lmax=pawtab(itypat)%indklmn(4,klmn) 1439 dlt_tmp=pawtab(itypat)%dltij(klmn) 1440 do ll=lmin,lmax,2 1441 do ilm=ll**2+1,(ll+1)**2 1442 isel=pawang%gntselect(ilm,klm) 1443 if (isel>0) then 1444 ro_d=dlt_tmp*pawtab(itypat)%qijl(ilm,klmn) 1445 mu=1 1446 do mua=1,6 1447 do mub=1,6 1448 grhat_tmp(ishift_str2+mu,iatm)= grhat_tmp(ishift_str2+mu,iatm)& 1449 & +ro_d*pawrhoij_iatom%grhoij(mub,klmn1,ispden)*prodp(mua,ilm) 1450 grhat_tmp(ishift_str2+mu,iatm)= grhat_tmp(ishift_str2+mu,iatm)& 1451 & +ro_d*pawrhoij_iatom%grhoij(mua,klmn1,ispden)*prodp(mub,ilm) 1452 mu=mu+1 1453 end do 1454 ! INTERNAL STRAIN CONTRIBUTION 1455 do idir=1,3 1456 grhat_tmp(ishift_str2is+(mua-1)*3+idir,iatm) = grhat_tmp(ishift_str2is+(mua-1)*3+idir,iatm)& 1457 & +ro_d*pawrhoij_iatom%grhoij(ishift_grhoij+idir,klmn1,ispden)*prodp(mua,ilm) 1458 grhat_tmp(ishift_str2is+(mua-1)*3+idir,iatm) = grhat_tmp(ishift_str2is+(mua-1)*3+idir,iatm)& 1459 & +ro_d*pawrhoij_iatom%grhoij(mua,klmn1,ispden)*prodp(6+idir,ilm) 1460 end do 1461 end do 1462 end if 1463 end do 1464 end do 1465 klmn1=klmn1+pawrhoij_iatom%cplex_rhoij 1466 end do 1467 end if ! optstr2 1468 1469 ! ---- Add off-diagonal additional contributions for second gradients 1470 if (optgr2==1.or.optstr2==1) then 1471 do jatm=1,natom 1472 jatom_tot=atindx1(jatm);jtypat=typat(jatom_tot) 1473 pawrhoij_jatom => pawrhoij_tot(jatom_tot) 1474 1475 ! ---- Dynamical matrix 1476 if (optgr2==1) then 1477 1478 ! Off-diagonal term including rhoij 1479 if (dyfr_cplex==1.or.cplex==1) then 1480 jrhoij=1 1481 do irhoij=1,pawrhoij_jatom%nrhoijsel 1482 klmn=pawrhoij_jatom%rhoijselect(irhoij) 1483 klm =pawtab(jtypat)%indklmn(1,klmn) 1484 lmin=pawtab(jtypat)%indklmn(3,klmn) 1485 lmax=pawtab(jtypat)%indklmn(4,klmn) 1486 ro =pawrhoij_jatom%rhoijp(jrhoij,ispden) 1487 ro_d=ro*pawtab(jtypat)%dltij(klmn) 1488 do ll=lmin,lmax,2 1489 do ilm=ll**2+1,(ll+1)**2 1490 isel=pawang%gntselect(ilm,klm) 1491 if (isel>0) then 1492 grhat_x=ro_d*pawtab(jtypat)%qijl(ilm,klmn) 1493 do mu=1,9 1494 grhat_tmp(ishift_gr2+mu,jatm)=grhat_tmp(ishift_gr2+mu,jatm) & 1495 & +grhat_x*prod_nondiag(jatm)%value(ishift_gr2+mu,ilm) 1496 end do 1497 end if 1498 end do 1499 end do 1500 jrhoij=jrhoij+pawrhoij_jatom%cplex_rhoij 1501 end do 1502 else 1503 jrhoij=1;mushift=ishift_gr2+9 1504 do irhoij=1,pawrhoij_jatom%nrhoijsel 1505 klmn=pawrhoij_jatom%rhoijselect(irhoij) 1506 klm =pawtab(jtypat)%indklmn(1,klmn) 1507 lmin=pawtab(jtypat)%indklmn(3,klmn) 1508 lmax=pawtab(jtypat)%indklmn(4,klmn) 1509 ro =pawrhoij_jatom%rhoijp(jrhoij,ispden) 1510 ro_d=ro*pawtab(jtypat)%dltij(klmn) 1511 do ll=lmin,lmax,2 1512 do ilm=ll**2+1,(ll+1)**2 1513 isel=pawang%gntselect(ilm,klm) 1514 if (isel>0) then 1515 grhat_x=ro_d*pawtab(jtypat)%qijl(ilm,klmn) 1516 do mu=1,9 1517 grhat_tmp(ishift_gr2+mu,jatm)=grhat_tmp(ishift_gr2+mu,jatm)& 1518 & +grhat_x*prod_nondiag(jatm)%value(ishift_gr2+mu,ilm) 1519 grhat_tmp(mushift+mu,jatm)=grhat_tmp(mushift+mu,jatm)& 1520 & +grhat_x*prod_nondiag(jatm)%value(ishift_gr2+9+mu,ilm) 1521 end do 1522 end if 1523 end do 1524 end do 1525 jrhoij=jrhoij+pawrhoij_jatom%cplex_rhoij 1526 end do 1527 end if 1528 1529 ! Off-diagonal term including rhoij derivative 1530 if (dyfr_cplex==1.or.cplex==1) then 1531 klmn1=1 1532 do klmn=1,pawrhoij_jatom%lmn2_size 1533 klm =pawtab(jtypat)%indklmn(1,klmn) 1534 lmin=pawtab(jtypat)%indklmn(3,klmn) 1535 lmax=pawtab(jtypat)%indklmn(4,klmn) 1536 dlt_tmp=pawtab(jtypat)%dltij(klmn) 1537 do ll=lmin,lmax,2 1538 do ilm=ll**2+1,(ll+1)**2 1539 isel=pawang%gntselect(ilm,klm) 1540 if (isel>0) then 1541 ro_d=dlt_tmp*pawtab(jtypat)%qijl(ilm,klmn) 1542 do mu=1,9 1543 mua=alpha(mu);mub=beta(mu) 1544 grhat_tmp(ishift_gr2+mu,jatm)=grhat_tmp(ishift_gr2+mu,jatm) & 1545 & +ro_d*pawrhoij_jatom%grhoij(ishift_grhoij+mua,klmn1,ispden) & 1546 & *prodp_nondiag(jatm)%value(ishift2_gr+mub,ilm) 1547 end do 1548 end if 1549 end do 1550 end do 1551 klmn1=klmn1+pawrhoij_jatom%cplex_rhoij 1552 end do ! klmn 1553 else ! ngradp_nondiag>=6 1554 klmn1=1;mushift=ishift_gr2+9 1555 do klmn=1,pawrhoij_jatom%lmn2_size 1556 klm =pawtab(jtypat)%indklmn(1,klmn) 1557 lmin=pawtab(jtypat)%indklmn(3,klmn) 1558 lmax=pawtab(jtypat)%indklmn(4,klmn) 1559 dlt_tmp=pawtab(jtypat)%dltij(klmn) 1560 do ll=lmin,lmax,2 1561 do ilm=ll**2+1,(ll+1)**2 1562 isel=pawang%gntselect(ilm,klm) 1563 if (isel>0) then 1564 ro_d=dlt_tmp*pawtab(jtypat)%qijl(ilm,klmn) 1565 do mu=1,9 1566 mua=alpha(mu);mub=beta(mu) 1567 grhat_tmp(ishift_gr2+mu,jatm)=grhat_tmp(ishift_gr2+mu,jatm) & 1568 & +ro_d*pawrhoij_jatom%grhoij(ishift_grhoij+mua,klmn1,ispden) & 1569 & *prodp_nondiag(jatm)%value(ishift2_gr+mub,ilm) 1570 grhat_tmp(mushift+mu,jatm)=grhat_tmp(mushift+mu,jatm) & 1571 & +ro_d*pawrhoij_jatom%grhoij(ishift_grhoij+mua,klmn1,ispden) & 1572 & *prodp_nondiag(jatm)%value(ishift2_gr+3+mub,ilm) 1573 end do 1574 end if 1575 end do 1576 end do 1577 klmn1=klmn1+pawrhoij_jatom%cplex_rhoij 1578 end do 1579 end if 1580 end if ! optgr2 1581 1582 ! ---- Elastic tensor 1583 if (optstr2==1)then 1584 1585 ! Off-diagonal term including rhoij 1586 jrhoij=1; 1587 do irhoij=1,pawrhoij_jatom%nrhoijsel 1588 klmn=pawrhoij_jatom%rhoijselect(irhoij) 1589 klm =pawtab(jtypat)%indklmn(1,klmn) 1590 lmin=pawtab(jtypat)%indklmn(3,klmn) 1591 lmax=pawtab(jtypat)%indklmn(4,klmn) 1592 ro =pawrhoij_jatom%rhoijp(jrhoij,ispden) 1593 ro_d=ro*pawtab(jtypat)%dltij(klmn) 1594 do ll=lmin,lmax,2 1595 do ilm=ll**2+1,(ll+1)**2 1596 isel=pawang%gntselect(ilm,klm) 1597 if (isel>0) then 1598 grhat_x=ro_d*pawtab(jtypat)%qijl(ilm,klmn) 1599 do mu=1,18 1600 grhat_tmp2(mu,jatm)=grhat_tmp2(mu,jatm) & 1601 & +grhat_x*prod_nondiag(jatm)%value(ishift_str2is+mu,ilm) 1602 end do 1603 end if 1604 end do 1605 end do 1606 jrhoij=jrhoij+pawrhoij_jatom%cplex_rhoij 1607 end do 1608 ! Off-diagonal term including rhoij derivative 1609 klmn1=1 1610 do klmn=1,pawrhoij_jatom%lmn2_size 1611 klm =pawtab(jtypat)%indklmn(1,klmn) 1612 lmin=pawtab(jtypat)%indklmn(3,klmn) 1613 lmax=pawtab(jtypat)%indklmn(4,klmn) 1614 dlt_tmp=pawtab(jtypat)%dltij(klmn) 1615 do ll=lmin,lmax,2 1616 do ilm=ll**2+1,(ll+1)**2 1617 isel=pawang%gntselect(ilm,klm) 1618 if (isel>0) then 1619 ro_d=dlt_tmp*pawtab(jtypat)%qijl(ilm,klmn) 1620 mu=1 1621 do mua=1,6 1622 do idir=1,3 1623 grhat_tmp2((mua-1)*3+idir,jatm) = grhat_tmp2((mua-1)*3+idir,jatm) & 1624 & +ro_d*pawrhoij_jatom%grhoij(mua,klmn1,ispden) & 1625 & *prodp_nondiag(jatm)%value(idir,ilm) 1626 end do 1627 end do 1628 end if 1629 end do 1630 end do 1631 klmn1=klmn1+pawrhoij_jatom%cplex_rhoij 1632 end do 1633 end if ! optstr2 1634 1635 end do ! jatm 1636 end if ! optgr2 or optstr2 1637 1638 ! ---------------------------------------------------------------- 1639 ! End of loop over spin components 1640 1641 end do ! ispden 1642 1643 ! Eventually free temporary space for g_l(r).Y_lm(r) factors 1644 if (pawfgrtab_iatom%gylm_allocated==2) then 1645 ABI_FREE(pawfgrtab_iatom%gylm) 1646 ABI_MALLOC(pawfgrtab_iatom%gylm,(0,0)) 1647 pawfgrtab_iatom%gylm_allocated=0 1648 end if 1649 if (pawfgrtab_iatom%gylmgr_allocated==2) then 1650 ABI_FREE(pawfgrtab_iatom%gylmgr) 1651 ABI_MALLOC(pawfgrtab_iatom%gylmgr,(0,0,0)) 1652 pawfgrtab_iatom%gylmgr_allocated=0 1653 end if 1654 if (pawfgrtab_iatom%gylmgr2_allocated==2) then 1655 ABI_FREE(pawfgrtab_iatom%gylmgr2) 1656 ABI_MALLOC(pawfgrtab_iatom%gylmgr2,(0,0,0)) 1657 pawfgrtab_iatom%gylmgr2_allocated=0 1658 end if 1659 if (pawfgrtab_iatom%expiqr_allocated==2) then 1660 ABI_FREE(pawfgrtab_iatom%expiqr) 1661 ABI_MALLOC(pawfgrtab_iatom%expiqr,(0,0)) 1662 pawfgrtab_iatom%expiqr_allocated=0 1663 end if 1664 1665 ! ---------------------------------------------------------------- 1666 ! Copy results in corresponding arrays 1667 1668 ! ==== Forces ==== 1669 ! Convert from cartesian to reduced coordinates 1670 if (optgr==1) then 1671 mushift=3*(iatm-1) 1672 tmp(1:3)=grhat_tmp(ishift_gr+1:ishift_gr+3,idiag) 1673 do mu=1,3 1674 hatgr(mu+mushift)=rprimd(1,mu)*tmp(1)+rprimd(2,mu)*tmp(2)+rprimd(3,mu)*tmp(3) 1675 end do 1676 end if 1677 1678 ! ==== Stresses ==== 1679 if (optstr==1) then 1680 ! This is contribution Eq.(41) of Torrent2008. 1681 !DEBUG 1682 ! write(6,*)' after loop on ispden,ishift_str,idiag,hatstr(1),grhat_tmp(ishift_str+1)',hatstr(1),grhat_tmp(ishift_str+1,idiag) 1683 !ENDDEBUG 1684 hatstr(1:6)=hatstr(1:6)+grhat_tmp(ishift_str+1:ishift_str+6,idiag) 1685 end if 1686 1687 ! ==== Frozen wf part of dyn. matrix ==== 1688 if (optgr2==1) then 1689 do jatm=1,natom 1690 do mu=1,9 1691 mua=alpha(mu);mub=beta(mu) 1692 dyfr(1,mub,mua,jatm,iatm)=grhat_tmp(ishift_gr2+mu,jatm) 1693 end do 1694 if (dyfr_cplex==2.and.cplex==2) then 1695 mushift=ishift_gr2+9 1696 do mu=1,9 1697 mua=alpha(mu);mub=beta(mu) 1698 dyfr(2,mub,mua,jatm,iatm)=grhat_tmp(mushift+mu,jatm) 1699 end do 1700 end if 1701 end do 1702 end if 1703 1704 ! ==== Elastic tensor ==== 1705 if (optstr2==1) then 1706 eltfr(1:6,1:6)=eltfr(1:6,1:6)+ & 1707 & reshape(grhat_tmp(ishift_str2+1:ishift_str2+36,iatm),(/6,6/)) 1708 ! Convert internal Strain in reduced coordinates 1709 do mua = 1,6 1710 tmp(1:3)=grhat_tmp(ishift_str2is+(mua-1)*3+1:ishift_str2is+(mua-1)*3+3,iatm) 1711 do idir=1,3 1712 eltfr(6+(iatm-1)*3+idir,mua)=eltfr(6+(iatm-1)*3+idir,mua)+ & 1713 & (rprimd(1,idir)*tmp(1)+rprimd(2,idir)*tmp(2)+rprimd(3,idir)*tmp(3)) 1714 end do 1715 do jatm=1,natom 1716 tmp(1:3)=grhat_tmp2((mua-1)*3+1:(mua-1)*3+3,jatm) 1717 do idir=1,3 1718 eltfr(6+(iatm-1)*3+idir,mua)=eltfr(6+(iatm-1)*3+idir,mua)+ & 1719 & (rprimd(1,idir)*tmp(1)+rprimd(2,idir)*tmp(2)+rprimd(3,idir)*tmp(3)) 1720 end do 1721 end do 1722 end do 1723 end if 1724 1725 ! ---------------------------------------------------------------- 1726 ! End loops on types and atoms 1727 1728 ABI_FREE(vloc) 1729 if (ngrad>0) then 1730 ABI_FREE(prod) 1731 end if 1732 if (ngradp>0) then 1733 ABI_FREE(prodp) 1734 end if 1735 if (optgr2==1.or.optstr2==1) then 1736 do jatm=1,natom 1737 ABI_FREE(prod_nondiag(jatm)%value) 1738 ABI_FREE(prodp_nondiag(jatm)%value) 1739 end do 1740 end if 1741 end do ! iatm 1742 iatshft=iatshft+nattyp(itypat) 1743 end do ! itypat 1744 1745 !DEBUG 1746 ! write(6,*)' before parallelization over atoms hatstr(1)',hatstr(1) 1747 !ENDDEBUG 1748 1749 !Reduction in case of parallelisation over atoms 1750 if (paral_atom) then 1751 bufsiz=3*natom*optgr+6*optstr 1752 if (save_memory) bufsiz=bufsiz+9*dyfr_cplex*natom**2*optgr2+6*(6+3*natom)*optstr2 1753 if (bufsiz>0) then 1754 ABI_MALLOC(buf1,(bufsiz)) 1755 if (optgr==1) buf1(1:3*natom)=hatgr(1:3*natom) 1756 indx=optgr*3*natom 1757 if (optstr==1) buf1(indx+1:indx+6)=hatstr(1:6) 1758 indx=indx+optstr*6 1759 if (save_memory) then 1760 if (optgr2==1) then 1761 buf1(indx+1:indx+9*dyfr_cplex*natom**2)= & 1762 & reshape(dyfr,(/9*dyfr_cplex*natom**2/)) 1763 indx=indx+9*dyfr_cplex*natom**2 1764 end if 1765 if (optstr2==1) then 1766 buf1(indx+1:indx+6*(6+3*natom))= & 1767 & reshape(eltfr,(/6*(6+3*natom)/)) 1768 indx=indx+6*(6+3*natom) 1769 end if 1770 end if 1771 call xmpi_sum(buf1,my_comm_atom,ier) 1772 if (optgr==1) hatgr(1:3*natom)=buf1(1:3*natom) 1773 indx=optgr*3*natom 1774 if (optstr==1) hatstr(1:6)=buf1(indx+1:indx+6) 1775 indx=indx+optstr*6 1776 if (save_memory) then 1777 if (optgr2==1) then 1778 dyfr(1:dyfr_cplex,1:3,1:3,1:natom,1:natom)= & 1779 & reshape(buf1(indx+1:indx+9*dyfr_cplex*natom**2),(/dyfr_cplex,3,3,natom,natom/)) 1780 indx=indx+9*dyfr_cplex*natom**2 1781 end if 1782 if (optstr2==1) then 1783 eltfr(1:6+3*natom,1:6)= & 1784 & reshape(buf1(indx+1:indx+6*(6+3*natom)),(/6+3*natom,6/)) 1785 indx=indx+6*(6+3*natom) 1786 end if 1787 end if 1788 ABI_FREE(buf1) 1789 end if 1790 end if 1791 1792 !Deallocate additional memory 1793 ABI_FREE(grhat_tmp) 1794 if (optgr2==1.or.optstr2==1) then 1795 ABI_FREE(mu4) 1796 ABI_FREE(atindx) 1797 if (optgr2==1.or.optstr2==1) then 1798 ABI_FREE(vpsp1_gr) 1799 end if 1800 if (optstr2==1) then 1801 ABI_FREE(grhat_tmp2) 1802 ABI_FREE(vpsp1_str) 1803 end if 1804 ABI_FREE(prod_nondiag) 1805 ABI_FREE(prodp_nondiag) 1806 if (.not.save_memory) then 1807 do jatom=1,size(pawfgrtab) 1808 pawfgrtab_jatom => pawfgrtab(jatom) 1809 if (pawfgrtab(jatom)%gylm_allocated==2) then 1810 ABI_FREE(pawfgrtab(jatom)%gylm) 1811 ABI_MALLOC(pawfgrtab(jatom)%gylm,(0,0)) 1812 pawfgrtab(jatom)%gylm_allocated=0 1813 end if 1814 if (pawfgrtab(jatom)%gylmgr_allocated==2) then 1815 ABI_FREE(pawfgrtab(jatom)%gylmgr) 1816 ABI_MALLOC(pawfgrtab(jatom)%gylmgr,(0,0,0)) 1817 pawfgrtab(jatom)%gylmgr_allocated=0 1818 end if 1819 if (pawfgrtab(jatom)%gylmgr2_allocated==2) then 1820 ABI_FREE(pawfgrtab(jatom)%gylmgr2) 1821 ABI_MALLOC(pawfgrtab(jatom)%gylmgr2,(0,0,0)) 1822 pawfgrtab(jatom)%gylmgr2_allocated=0 1823 end if 1824 if (pawfgrtab(jatom)%expiqr_allocated==2) then 1825 ABI_FREE(pawfgrtab(jatom)%expiqr) 1826 ABI_MALLOC(pawfgrtab(jatom)%expiqr,(0,0)) 1827 pawfgrtab(jatom)%expiqr_allocated=0 1828 end if 1829 end do 1830 end if 1831 if (paral_atom) then 1832 if ((.not.save_memory).and.paral_atom_pawfgrtab) then 1833 call pawfgrtab_free(pawfgrtab_tot) 1834 ABI_FREE(pawfgrtab_tot) 1835 end if 1836 if (paral_atom_pawrhoij) then 1837 call pawrhoij_free(pawrhoij_tot) 1838 ABI_FREE(pawrhoij_tot) 1839 end if 1840 end if 1841 end if 1842 1843 !---------------------------------------------------------------------- 1844 !Update non-local gradients 1845 1846 !===== Update forces ===== 1847 if (optgr==1) then 1848 grnl(1:3*natom)=grnl(1:3*natom)+hatgr(1:3*natom) 1849 ABI_FREE(hatgr) 1850 end if 1851 1852 !===== Convert stresses (add diag and off-diag contributions) ===== 1853 if (optstr==1) then 1854 1855 ! Has to compute int[nhat*vtrial]. See Eq.(40) in Torrent2008 . 1856 hatstr_diag=zero 1857 if (nspden==1.or.dimvtrial==1) then 1858 do ic=1,nfft 1859 hatstr_diag=hatstr_diag+vtrial_(ic,1)*nhat(ic,1) 1860 end do 1861 else if (nspden==2) then 1862 do ic=1,nfft 1863 hatstr_diag=hatstr_diag+vtrial_(ic,1)*nhat(ic,2)+vtrial_(ic,2)*(nhat(ic,1)-nhat(ic,2)) 1864 end do 1865 else if (nspden==4) then 1866 do ic=1,nfft 1867 hatstr_diag=hatstr_diag+half*(vtrial_(ic,1)*(nhat(ic,1)+nhat(ic,4)) & 1868 & +vtrial_(ic,2)*(nhat(ic,1)-nhat(ic,4))) & 1869 & +vtrial_(ic,3)*nhat(ic,2)-vtrial_(ic,4)*nhat(ic,3) 1870 end do 1871 end if 1872 hatstr_diag=hatstr_diag*fact_ucvol 1873 if (paral_grid) then 1874 call xmpi_sum(hatstr_diag,my_comm_grid,ier) 1875 end if 1876 1877 ! Convert hat contribution 1878 1879 !DEBUG 1880 ! write(6,*)' hatstr(1),hatstr_diag,nlstr(1)=',hatstr(1),hatstr_diag,nlstr(1) 1881 !ENDDEBUG 1882 1883 hatstr(1:3)=(hatstr(1:3)+hatstr_diag)/ucvol 1884 hatstr(4:6)= hatstr(4:6)/ucvol 1885 1886 ! Add to already computed NL contrib 1887 nlstr(1:6)=nlstr(1:6)+hatstr(1:6) 1888 1889 ! Apply symmetries 1890 call stresssym(gprimd,nsym,nlstr,symrec) 1891 end if 1892 1893 !===== Convert dynamical matrix (from cartesian to reduced coordinates) ===== 1894 if (optgr2==1) then 1895 do iatm=1,natom 1896 do jatm=1,natom 1897 do mua=1,3 1898 do mub=1,3 1899 work1(1,mua,mub)=dyfr(1,mub,mua,jatm,iatm)+dyfr(1,mua,mub,iatm,jatm) 1900 end do 1901 end do 1902 if (dyfr_cplex==2) then 1903 do mua=1,3 1904 do mub=1,3 1905 work1(2,mua,mub)=dyfr(2,mub,mua,jatm,iatm)-dyfr(2,mua,mub,iatm,jatm) 1906 end do 1907 end do 1908 end if 1909 do mu=1,3 1910 work2(:,:,mu)=rprimd(1,mu)*work1(:,:,1)+rprimd(2,mu)*work1(:,:,2)+rprimd(3,mu)*work1(:,:,3) 1911 end do 1912 do mub=1,3 1913 do mua=1,3 1914 dyfrnl(:,mua,mub,jatm,iatm)=dyfrnl(:,mua,mub,jatm,iatm) & ! Already contains NL projectors contribution 1915 & +rprimd(1,mua)*work2(:,1,mub) & 1916 & +rprimd(2,mua)*work2(:,2,mub) & 1917 & +rprimd(3,mua)*work2(:,3,mub) 1918 end do 1919 end do 1920 end do 1921 end do 1922 ABI_FREE(dyfr) 1923 end if 1924 1925 !===== Update elastic tensor ===== 1926 if (optstr2==1) then 1927 eltfrnl(1:6+3*natom,1:6)=eltfrnl(1:6+3*natom,1:6)+eltfr(1:6+3*natom,1:6) 1928 ABI_FREE(eltfr) 1929 end if 1930 1931 !---------------------------------------------------------------------- 1932 !End 1933 1934 !Destroy temporary space 1935 if (usexcnhat==0) then 1936 ABI_FREE(vtrial_) 1937 end if 1938 1939 !Destroy atom tables used for parallelism 1940 call free_my_atmtab(my_atmtab,my_atmtab_allocated) 1941 if (paral_atom) then 1942 ABI_FREE(atm_indx) 1943 end if 1944 1945 !Destroy FFT tables used for parallelism 1946 if ((optgr2==1.or.optstr2==1).and.(.not.present(comm_fft))) then 1947 call destroy_distribfft(my_distribfft) 1948 ABI_FREE(my_distribfft) 1949 end if 1950 1951 DBG_ENTER("COLL") 1952 1953 CONTAINS
pawgrnl/pawgrnl_convert [ Functions ]
[ Top ] [ pawgrnl ] [ Functions ]
NAME
pawgrnl_convert
FUNCTION
notation: Convert index of the elastic tensor: - voigt notation => 32 - normal notation => 3 3 2 2 - notation for gylmgr2 => 32 32 32 32 => 4 4 4
INPUTS
eps_alpha, eps_beta, eps_delta, eps_gamma
OUTPUT
mu4(4) = array with index for the second derivative of gylm
SIDE EFFECTS
mu4(4) = input : array with index for the second derivative of gylm output: the 4 indexes for the calculation of the second derivative of gylm
SOURCE
1979 subroutine pawgrnl_convert(mu4,eps_alpha,eps_beta,eps_gamma,eps_delta) 1980 1981 !Arguments ------------------------------------ 1982 !scalar 1983 integer,intent(in) :: eps_alpha,eps_beta 1984 integer,optional,intent(in) :: eps_gamma,eps_delta 1985 !array 1986 integer,intent(inout) :: mu4(4) 1987 1988 !Local variables------------------------------- 1989 integer :: eps1,eps2,i,j,k 1990 integer,allocatable :: mu_temp(:) 1991 1992 ! ************************************************************************* 1993 1994 ABI_MALLOC(mu_temp,(4)) 1995 if (present(eps_gamma).and.present(eps_delta)) then 1996 mu_temp(1)=eps_alpha 1997 mu_temp(2)=eps_beta 1998 mu_temp(3)=eps_gamma 1999 mu_temp(4)=eps_delta 2000 else 2001 mu_temp(1)=eps_alpha 2002 mu_temp(2)=eps_beta 2003 mu_temp(3)= 0 2004 mu_temp(4)= 0 2005 end if 2006 k=1 2007 do i=1,2 2008 eps1=mu_temp(i) 2009 do j=1,2 2010 eps2=mu_temp(2+j) 2011 if(eps1==eps2) then 2012 if(eps1==1) mu4(k)=1; 2013 if(eps1==2) mu4(k)=2; 2014 if(eps1==3) mu4(k)=3; 2015 else 2016 if((eps1==3.and.eps2==2).or.(eps1==2.and.eps2==3)) mu4(k)=4; 2017 if((eps1==3.and.eps2==1).or.(eps1==1.and.eps2==3)) mu4(k)=5; 2018 if((eps1==1.and.eps2==2).or.(eps1==2.and.eps2==1)) mu4(k)=6; 2019 end if 2020 k=k+1 2021 end do 2022 end do 2023 ABI_FREE(mu_temp) 2024 2025 end subroutine pawgrnl_convert 2026 ! ------------------------------------------------ 2027 2028 end subroutine pawgrnl