TABLE OF CONTENTS


ABINIT/m_kg [ Modules ]

[ Top ] [ Modules ]

NAME

 m_kg

FUNCTION

  Low-level functions to operate of G-vectors.

COPYRIGHT

  Copyright (C) 2008-2024 ABINIT group (DCA, XG, GMR, MT, DRH, AR)
  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

16 #if defined HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19 
20 #include "abi_common.h"
21 
22 MODULE m_kg
23 
24  use defs_basis
25  use m_errors
26  use m_abicore
27  use m_errors
28  use m_xmpi
29  use m_dtset
30 
31  use defs_abitypes, only : MPI_type
32  use m_fftcore,     only : kpgsph, bound
33  use m_mpinfo,      only : proc_distrb_cycle
34  use m_time,        only : timab
35 
36  implicit none
37 
38  private

ABINIT/mkkin_metdqdq [ Functions ]

[ Top ] [ Functions ]

NAME

 mkkin_metdqdq

FUNCTION

 Compute elements of the second q-gradient of the metric
 kinetic energy operator in reciprocal
 space at given k point wrt cartesian q components.

INPUTS

  effmass=effective mass for electrons (1. in common case)
  gprimd(3,3)=reciprocal space dimensional primitive translations
  idir= strain perturbation direction
  kg(3,npw) = integer coordinates of planewaves in basis sphere.
  kpt(3)    = reduced coordinates of k point
  npw       = number of plane waves at kpt.
  qdir      = direction of the first q-gradient

OUTPUT

  dqdqkinpw(npw)=d/deps(istr) ( (1/2)*(2 pi)**2 * (k+G)**2 )

NOTES

  **Since the 2nd derivative w.r.t q-vector is calculated along cartesian
    directions, the 1/twopi**2 factor (that in the rest of the code is applied
    in the reduced to cartesian derivative conversion process) is here
    explicictly included in the formulas.

  **Notice that idir=1-9, in contrast to the strain perturbation (idir=1-6),
    because this term is not symmetric w.r.t permutations of the two strain
    indices.

  **A -i factor has been factorized out in all the contributions of the second
    q-gradient of the metric Hamiltonian. This is lately included in the contribution
    of the corresponing term (T4) to the flexoelectric tensor in dfpt_flexoout.F90

SOURCE

1218 subroutine mkkin_metdqdq(dqdqkinpw,effmass,gprimd,idir,kg,kpt,npw,qdir)
1219 
1220 !Arguments -------------------------------
1221 !scalars
1222  integer,intent(in) :: idir,npw,qdir
1223  real(dp),intent(in) :: effmass
1224 !arrays
1225  integer,intent(in) :: kg(3,npw)
1226  real(dp),intent(in) :: gprimd(3,3),kpt(3)
1227  real(dp),intent(out) :: dqdqkinpw(npw)
1228 
1229 !Local variables -------------------------
1230 !scalars
1231  integer :: beta,delta,gamma,ig,ka,kb
1232  real(dp) :: delbd,delbg,deldg
1233  real(dp) :: dkinetic,gpk1,gpk2,gpk3,htpi
1234  real(dp) :: gpkc(3)
1235 !arrays
1236  integer,save :: idx(18)=(/1,1,2,2,3,3,3,2,3,1,2,1,2,3,1,3,1,2/)
1237 
1238 ! *********************************************************************
1239 
1240 !htpi is (1/2) (2 Pi):
1241  htpi=0.5_dp*two_pi
1242 
1243  ka=idx(2*idir-1);kb=idx(2*idir)
1244 
1245 !For easier formula implementation
1246  beta=ka
1247  delta=kb
1248  gamma=qdir
1249 
1250 !Kronecker deltas
1251  delbd=0.0_dp; delbg=0.0_dp; deldg=0.0_dp
1252  if (beta==delta) delbd=1.0_dp
1253  if (beta==gamma) delbg=1.0_dp
1254  if (delta==gamma) deldg=1.0_dp
1255 
1256  do ig=1,npw
1257    gpk1=dble(kg(1,ig))+kpt(1)
1258    gpk2=dble(kg(2,ig))+kpt(2)
1259    gpk3=dble(kg(3,ig))+kpt(3)
1260 
1261 !  Obtain G in cartesian coordinates
1262    gpkc(1)=gprimd(1,1)*gpk1+gprimd(1,2)*gpk2+gprimd(1,3)*gpk3
1263    gpkc(2)=gprimd(2,1)*gpk1+gprimd(2,2)*gpk2+gprimd(2,3)*gpk3
1264    gpkc(3)=gprimd(3,1)*gpk1+gprimd(3,2)*gpk2+gprimd(3,3)*gpk3
1265 
1266    dkinetic=htpi*(2.0_dp*deldg*gpkc(beta)+delbg*gpkc(delta)+ &
1267  & delbd*gpkc(gamma))
1268 
1269    dqdqkinpw(ig)=dkinetic/effmass
1270  end do
1271 
1272 end subroutine mkkin_metdqdq

ABINIT/mkpwind_k [ Functions ]

[ Top ] [ Functions ]

NAME

 mkpwind_k

FUNCTION

 Make plane wave index at k point for basis at second k point,
 needed to compute overlaps $\langle u_{k,n}|u_{k+b,n}\rangle$
 as appear in Berry phase derived quantities

INPUTS

 dk(3)=real vector difference of ket kpt - bra kpt
 dtset <type(dataset_type)>=all input variables in this dataset
 fnkpt=number of kpts in full BZ
 fkptns=kpts in full BZ
 gmet(3,3)=metric in reciprocal space
 indkk_f2ibz(fnkpt,6)=information on folding from FBZ to IBZ (see initberry or initorbmag)
 ikpt=index of bra k pt in FBZ
 ikpt1=index of neighbour ket k pt in FBZ
 mpi_enreg=information about MPI parallelization
 npwarr(dtset%nkpt)=npw at each kpt
 symrec(3,3,nsym) = symmetries in reciprocal space in terms of
   reciprocal space primitive translations

OUTPUT

 pwind_k1(dtset%mpw)=output index of ikpt1 basis states refered to ikpt

SIDE EFFECTS

TODO

NOTES

SOURCE

 986 subroutine mkpwind_k(dk,dtset,fnkpt,fkptns,gmet,indkk_f2ibz,ikpt,ikpt1,&
 987 & mpi_enreg,npwarr,pwind_k1,symrec)
 988 
 989   !Arguments ------------------------------------
 990   !scalars
 991   integer,intent(in) :: fnkpt,ikpt,ikpt1
 992   type(dataset_type),intent(in) :: dtset
 993   type(MPI_type), intent(inout) :: mpi_enreg
 994 
 995   !arrays
 996   integer,intent(in) :: indkk_f2ibz(fnkpt,6)
 997   integer,intent(in) :: npwarr(dtset%nkpt)
 998   integer,intent(in) :: symrec(3,3,dtset%nsym)
 999   integer,intent(out) :: pwind_k1(dtset%mpw)
1000   real(dp),intent(in) :: dk(3),fkptns(3,fnkpt),gmet(3,3)
1001 
1002   !Local variables -------------------------
1003   !scalars
1004   integer :: exchn2n3d,idum1,ikg1,ikpti,ikpt1i,ipw,istwf_k,isym,isym1,jpw,npw_k,npw_k1
1005   real(dp) :: ecut_eff
1006 
1007   !arrays
1008   integer,allocatable :: kg_k(:,:),kg1_k(:,:)
1009   real(dp) :: dg(3),dum33(3,3),kpt(3),kpt1(3),iadum(3),iadum1(3)
1010 
1011   ! ***********************************************************************
1012 
1013   ikpti = indkk_f2ibz(ikpt,1)
1014   ikpt1i = indkk_f2ibz(ikpt1,1)
1015 
1016 
1017   ecut_eff = dtset%ecut*(dtset%dilatmx)**2
1018   exchn2n3d = 0 ; istwf_k = 1 ; ikg1 = 0
1019 
1020   ! Build basis sphere of plane waves for the k-point
1021   ! we avoid using the global kg data because of difficulties in parallel-ism
1022   ABI_MALLOC(kg_k,(3,dtset%mpw))
1023   kg_k(:,:) = 0
1024   kpt(:) = dtset%kptns(:,ikpti)
1025   call kpgsph(ecut_eff,exchn2n3d,gmet,ikg1,ikpt,istwf_k,kg_k,kpt,1,mpi_enreg,dtset%mpw,npw_k)
1026 
1027   ! Build basis sphere of plane waves for the nearest neighbour of the k-point
1028   ABI_MALLOC(kg1_k,(3,dtset%mpw))
1029   kg1_k(:,:) = 0
1030   kpt1(:) = dtset%kptns(:,ikpt1i)
1031   call kpgsph(ecut_eff,exchn2n3d,gmet,ikg1,ikpt,istwf_k,kg1_k,kpt1,1,mpi_enreg,dtset%mpw,npw_k1)
1032 
1033   !        Deal with symmetry transformations
1034   !
1035 
1036   !        bra k-point k(b) and IBZ k-point kIBZ(b) related by
1037   !        k(b) = alpha(b) S(b)^t kIBZ(b) + G(b)
1038   !        where alpha(b), S(b) and G(b) are given by indkk_f2ibz
1039   !
1040   !        For the ket k-point:
1041   !        k(k) = alpha(k) S(k)^t kIBZ(k) + G(k) - GBZ(k)
1042   !        where GBZ(k) takes k(k) to the BZ
1043   !
1044 
1045   isym  = indkk_f2ibz(ikpt,2)
1046   isym1 = indkk_f2ibz(ikpt1,2)
1047 
1048   !        Construct transformed G vector that enters the matching condition:
1049   !        alpha(k) S(k)^{t,-1} ( -G(b) - GBZ(k) + G(k) )
1050 
1051   dg(:) = -indkk_f2ibz(ikpt,3:5) &
1052        & - nint(-fkptns(:,ikpt) - dk(:) - tol10 + fkptns(:,ikpt1)) &
1053        & + indkk_f2ibz(ikpt1,3:5)
1054 
1055   iadum(:) = MATMUL(TRANSPOSE(dtset%symrel(:,:,isym1)),dg(:))
1056 
1057   dg(:) = iadum(:)
1058 
1059   !        Construct S(k)^{t,-1} S(b)^{t}
1060 
1061   dum33(:,:) = MATMUL(TRANSPOSE(dtset%symrel(:,:,isym1)),symrec(:,:,isym))
1062 
1063   !        Construct alpha(k) alpha(b)
1064 
1065   pwind_k1(:) = 0
1066   npw_k = npwarr(ikpti)
1067   do ipw = 1, npw_k
1068 
1069      !          NOTE: the bra G vector is taken for the sym-related IBZ k point,
1070      !          not for the FBZ k point
1071 
1072      ! original code from initberry
1073      ! iadum(:) = kg(:,kgindex(ikpti) + ipw)
1074 
1075      iadum(:) = kg_k(:,ipw)
1076 
1077      !          to determine r.l.v. matchings, we transformed the bra vector
1078      !          Rotation
1079      iadum1(:)=0
1080      do idum1=1,3
1081         iadum1(:)=iadum1(:)+dum33(:,idum1)*iadum(idum1)
1082      end do
1083      iadum(:)=iadum1(:)
1084      iadum(:) = iadum(:) + dg(:)
1085 
1086      do jpw = 1, npw_k1
1087         iadum1(1:3) = kg1_k(1:3,jpw)
1088         if ( (iadum(1) == iadum1(1)).and. &
1089              &     (iadum(2) == iadum1(2)).and. &
1090              &     (iadum(3) == iadum1(3)) ) then
1091            pwind_k1(ipw) = jpw
1092            exit
1093         end if
1094      end do
1095   end do
1096 
1097   ABI_FREE(kg_k)
1098   ABI_FREE(kg1_k)
1099 
1100 end subroutine mkpwind_k

m_kg/getcut [ Functions ]

[ Top ] [ m_kg ] [ Functions ]

NAME

 getcut

FUNCTION

 For input kpt, fft box dim ngfft(1:3), recip space metric gmet, and kinetic energy cutoff ecut, COMPUTES:

 if iboxcut==0:
   gsqcut: cut-off on G^2 for "large sphere" of radius double that
            of the basis sphere corresponding to ecut
   boxcut: where boxcut == gcut(box)/gcut(sphere).
                 boxcut >=2 for no aliasing.
                 boxcut < 1 is wrong and halts subroutine.
 if iboxcut==1:
   gsqcut: cut-off on G^2 for "large sphere" containing the whole fft box
   boxcut: no meaning (zero)

INPUTS

 ecut=kinetic energy cutoff for planewave sphere (hartree)
 gmet(3,3)=reciprocal space metric (bohr^-2)
 iboxcut=0: compute gsqcut and boxcut with boxcut>=1
         1: compute gsqcut for boxcut=1 (sphere_cutoff=box_cutoff)
 iout=unit number for output file
 kpt(3)=input k vector (reduced coordinates--in terms of reciprocal lattice primitive translations)
 ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft

OUTPUT

 boxcut=defined above (dimensionless), ratio of basis sphere
  diameter to fft box length (smallest value)
 gsqcut=Fourier cutoff on G^2 for "large sphere" of radius double
  that of the basis sphere--appropriate for charge density rho(G),
  Hartree potential, and pseudopotentials

NOTES

 2*gcut arises from rho(g)=sum g prime (psi(g primt)*psi(g prime+g))
               where psi(g) is only nonzero for |g| <= gcut).
 ecut (currently in hartree) is proportional to gcut(sphere)**2.

SOURCE

 96 subroutine getcut(boxcut, ecut, gmet, gsqcut, iboxcut, iout, kpt, ngfft)
 97 
 98 !Arguments ------------------------------------
 99 !scalars
100  integer,intent(in) :: iboxcut,iout
101  real(dp),intent(in) :: ecut
102  real(dp),intent(out) :: boxcut,gsqcut
103 !arrays
104  integer,intent(in) :: ngfft(18)
105  real(dp),intent(in) :: gmet(3,3),kpt(3)
106 
107 !Local variables-------------------------------
108 !scalars
109  integer :: plane
110  real(dp) :: boxsq,cutrad,ecut_pw,effcut,largesq,sphsq
111  character(len=1000) :: msg
112 !arrays
113  integer :: gbound(3)
114 
115 ! *************************************************************************
116 
117  ! This is to treat the case in which ecut has not been initialized e.g. for wavelet computations.
118  ! The default for ecut is -1.0 , allowed only for wavelets calculations
119  ecut_pw=ecut
120  if(ecut<-tol8)ecut_pw=ten
121 
122  !gcut(box)**2=boxsq; gcut(sphere)**2=sphsq
123  !get min. d**2 to boundary of fft box:
124  !(gmet sets dimensions: bohr**-2)
125  !ecut(sphere)=0.5*(2 pi)**2 * sphsq:
126  call bound(largesq,boxsq,gbound,gmet,kpt,ngfft,plane)
127  effcut=0.5_dp * (two_pi)**2 * boxsq
128  sphsq=2._dp*ecut_pw/two_pi**2
129 
130  if (iboxcut/=0) then
131    boxcut=10._dp
132    gsqcut=(largesq/sphsq)*(2.0_dp*ecut)/two_pi**2
133 
134    write(msg, '(a,a,3f8.4,a,3i4,a,a,f11.3,a,a)' ) ch10,&
135    ' getcut: wavevector=',kpt,'  ngfft=',ngfft(1:3),ch10,&
136    '         ecut(hartree)=',ecut_pw+tol8,ch10,'=> whole FFT box selected'
137    if(iout/=std_out) call wrtout(iout,msg)
138    call wrtout(std_out,msg)
139  else
140 
141   ! Get G^2 cutoff for sphere of double radius of basis sphere
142   ! for selecting G s for rho(G), V_Hartree(G), and V_psp(G)--
143   ! cut off at fft box boundary or double basis sphere radius, whichever
144   ! is smaller.  If boxcut were 2, then relation would be
145   ! $ecut_eff = (1/2) * (2 Pi Gsmall)^2 and gsqcut=4*Gsmall^2$.
146    boxcut = sqrt(boxsq/sphsq)
147    cutrad = min(2.0_dp,boxcut)
148    gsqcut = (cutrad**2)*(2.0_dp*ecut_pw)/two_pi**2
149 
150    if(ecut>-tol8)then
151 
152      write(msg, '(a,a,3f8.4,a,3i4,a,a,f11.3,3x,a,f10.5)' ) ch10,&
153      ' getcut: wavevector=',kpt,'  ngfft=',ngfft(1:3),ch10,&
154      '         ecut(hartree)=',ecut+tol8,'=> boxcut(ratio)=',boxcut+tol8
155      if(iout/=std_out) call wrtout(iout,msg)
156      call wrtout(std_out,msg)
157 
158      if (boxcut<1.0_dp) then
159        write(msg, '(9a,f12.6,6a)' )&
160        'Choice of acell, ngfft, and ecut',ch10,&
161        '===> basis sphere extends BEYOND fft box !',ch10,&
162        'Recall that boxcut=Gcut(box)/Gcut(sphere)  must be > 1.',ch10,&
163        'Action: try larger ngfft or smaller ecut.',ch10,&
164        'Note that ecut=effcut/boxcut**2 and effcut=',effcut+tol8,ch10,&
165        'This situation might happen when optimizing the cell parameters.',ch10,&
166        'Your starting geometry might be crazy.',ch10,&
167        'See https://wiki.abinit.org/doku.php?id=howto:troubleshooting#incorrect_initial_geometry .'
168        if(iout/=std_out) call wrtout(iout,msg)
169        ABI_ERROR(msg)
170      end if
171 
172      if (boxcut>2.2_dp) then
173        write(msg, '(a,a,a,a,a,a,a,a,a,a,a,f12.6,a,a)' ) ch10,&
174        ' getcut : COMMENT -',ch10,&
175        '  Note that boxcut > 2.2 ; recall that',' boxcut=Gcut(box)/Gcut(sphere) = 2',ch10,&
176        '  is sufficient for exact treatment of convolution.',ch10,&
177        '  Such a large boxcut is a waste : you could raise ecut',ch10,&
178        '  e.g. ecut=',effcut*0.25_dp+tol8,' Hartrees makes boxcut=2',ch10
179        if(iout/=std_out) call wrtout(iout,msg)
180        call wrtout(std_out,msg)
181      end if
182 
183      if (boxcut<1.5_dp) then
184        write(msg, '(15a)' ) ch10,&
185        ' getcut : WARNING -',ch10,&
186        '  Note that boxcut < 1.5; this usually means',ch10,&
187        '  that the forces are being fairly strongly affected by',' the smallness of the fft box.',ch10,&
188        '  Be sure to test with larger ngfft(1:3) values.',ch10,&
189        '  This situation might happen when optimizing the cell parameters.',ch10,&
190        '  Your starting geometry might be crazy.',ch10,&
191        '  See https://wiki.abinit.org/doku.php?id=howto:troubleshooting#incorrect_initial_geometry .'
192        if(iout/=std_out) call wrtout(iout,msg)
193        call wrtout(std_out,msg)
194      end if
195 
196    end if
197 
198  end if  ! iboxcut
199 
200 end subroutine getcut

m_kg/getmpw [ Functions ]

[ Top ] [ m_kg ] [ Functions ]

NAME

 getmpw

FUNCTION

 From input ecut, combined with ucvol and gmet, compute recommended mpw
 mpw is the maximum number of plane-waves in the wave-function basis
 for one processor of the WF group

INPUTS

 ecut=plane-wave cutoff energy in Hartrees
 exchn2n3d=if n1, n2 and n3 are exchanged
 gmet(3,3)=reciprocal space metric (bohr**-2).
 istwfk(nkpt)=input option parameter that describes the storage of wfs
 kptns(3,nkpt)=real(dp) array for k points (normalisation is already taken into account)
 mpi_enreg=information about MPI parallelization
 nkpt=integer number of k points in the calculation

OUTPUT

 mpw=maximal number of plane waves over all k points of the processor
  (for one processor of the WF group)

SOURCE

227 subroutine getmpw(ecut,exchn2n3d,gmet,istwfk,kptns,mpi_enreg,mpw,nkpt)
228 
229 !Arguments ------------------------------------
230 !scalars
231  integer,intent(in) :: exchn2n3d,nkpt
232  integer,intent(out) :: mpw
233  real(dp),intent(in) :: ecut
234  type(MPI_type),intent(inout) :: mpi_enreg
235 !arrays
236  integer,intent(in) :: istwfk(nkpt)
237  real(dp),intent(in) :: gmet(3,3),kptns(3,nkpt)
238 
239 !Local variables-------------------------------
240 !scalars
241  integer :: ikpt,istwf_k,npw
242 ! integer :: npwwrk,pad=50
243 ! real(dp) :: scale=1.3_dp
244  character(len=500) :: msg
245 !arrays
246  integer,allocatable :: kg(:,:)
247  real(dp) :: kpoint(3)
248 
249 ! *************************************************************************
250 
251 !An upper bound for mpw, might be obtained as follows
252 !the average number of plane-waves in the cutoff sphere is
253 !npwave = (2*ecut)**(3/2) * ucvol / (6*pi**2)
254 !the upper bound is calculated as
255 !npwwrk = int(scale * npwave) + pad
256 !rescale so an upper bound
257 !npwave=nint(ucvol*(2.0_dp*ecut)**1.5_dp/(6.0_dp*pi**2))
258 !npwwrk=nint(dble(npwave)*scale)+pad
259 
260  ABI_MALLOC(kg,(3,100))
261 
262 !set mpw to zero, as needed for only counting in kpgsph
263  mpw = 0
264 
265 !Might be parallelized over k points ? !
266  do ikpt = 1,nkpt
267 !  Do computation of G sphere, returning npw
268    kpoint(:)=kptns(:,ikpt)
269    istwf_k=istwfk(ikpt)
270    call kpgsph(ecut,exchn2n3d,gmet,0,ikpt,istwf_k,kg,kpoint,0,mpi_enreg,0,npw)
271    mpw = max(npw,mpw)
272  end do
273 
274  write(msg,'(a,i0)') ' getmpw: optimal value of mpw= ',mpw
275  call wrtout(std_out,msg)
276 
277  ABI_FREE(kg)
278 
279 end subroutine getmpw

m_kg/getph [ Functions ]

[ Top ] [ m_kg ] [ Functions ]

NAME

 getph

FUNCTION

 Compute three factors of one-dimensional structure factor phase
 for input atomic coordinates, for all planewaves which fit in fft box.
 The storage of these atomic factors is made according to the
 values provided by the index table atindx. This will save time in nonlop.

INPUTS

  atindx(natom)=index table for atoms (see gstate.f)
  natom=number of atoms in cell.
  n1,n2,n3=dimensions of fft box (ngfft(3)).
  xred(3,natom)=reduced atomic coordinates.

OUTPUT

  ph1d(2,(2*n1+1)*natom+(2*n2+1)*natom+(2*n3+1)*natom)=exp(2Pi i G.xred) for
   integer vector G with components ranging from -nj <= G <= nj.
   Real and imag given in usual Fortran convention.

SOURCE

708 subroutine getph(atindx, natom, n1, n2, n3, ph1d, xred)
709 
710 !Arguments ------------------------------------
711 !scalars
712  integer,intent(in) :: n1,n2,n3,natom
713 !arrays
714  integer,intent(in) :: atindx(natom)
715  real(dp),intent(in) :: xred(3,natom)
716  real(dp),intent(out) :: ph1d(:,:)
717 
718 !Local variables-------------------------------
719 !scalars
720  integer,parameter :: im=2,re=1
721  integer :: i1,i2,i3,ia,ii,ph1d_size1,ph1d_size2,ph1d_sizemin
722  !character(len=500) :: msg
723  real(dp) :: arg
724 
725 ! *************************************************************************
726 
727  ph1d_size1=size(ph1d,1); ph1d_size2=size(ph1d,2)
728  ph1d_sizemin = (2*n1+1+2*n2+1+2*n3+1)*natom
729  if (ph1d_size1 /= 2 .or. ph1d_size2 < ph1d_sizemin) then
730    ABI_BUG('Wrong ph1d sizes!')
731  end if
732 
733  do ia=1,natom
734 
735    ! Store the phase factor of atom number ia in place atindx(ia)
736    i1=(atindx(ia)-1)*(2*n1+1)
737    i2=(atindx(ia)-1)*(2*n2+1)+natom*(2*n1+1)
738    i3=(atindx(ia)-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1)
739 
740    do ii=1,2*n1+1
741      arg=two_pi*dble(ii-1-n1)*xred(1,ia)
742      ph1d(re,ii+i1)=dcos(arg)
743      ph1d(im,ii+i1)=dsin(arg)
744    end do
745 
746    do ii=1,2*n2+1
747      arg=two_pi*dble(ii-1-n2)*xred(2,ia)
748      ph1d(re,ii+i2)=dcos(arg)
749      ph1d(im,ii+i2)=dsin(arg)
750    end do
751 
752    do ii=1,2*n3+1
753      arg=two_pi*dble(ii-1-n3)*xred(3,ia)
754      ph1d(re,ii+i3)=dcos(arg)
755      ph1d(im,ii+i3)=dsin(arg)
756    end do
757 
758  end do
759 
760  ! This to avoid uninitialized ph1d values
761  if (ph1d_sizemin < ph1d_size2) ph1d(:,ph1d_sizemin+1:ph1d_size2)=zero
762 
763 end subroutine getph

m_kg/kpgio [ Functions ]

[ Top ] [ m_kg ] [ Functions ]

NAME

 kpgio

FUNCTION

 Do initialization of kg data.

INPUTS

  ecut=kinetic energy planewave cutoff (hartree)
  exchn2n3d=if 1, n2 and n3 are exchanged
  gmet(3,3)=reciprocal space metric (bohr^-2)
  istwfk(nkpt)=input option parameter that describes the storage of wfs
  kptns(3,nkpt)=reduced coords of k points
  mkmem =number of k points treated by this node.
  character(len=4) : mode_paral=either 'COLL' or 'PERS', tells whether
   the loop over k points must be done by all processors or not,
   in case of parallel execution.
  mpi_enreg=information about MPI parallelization
  mpw=maximum number of planewaves as dimensioned in calling routine
  nband(nkpt*nsppol)=number of bands at each k point
  nkpt=number of k points
  nsppol=1 for unpolarized, 2 for polarized

OUTPUT

  npwarr(nkpt)=array holding npw for each k point, taking into account
   the effect of istwfk, and the spreading over processors
  npwtot(nkpt)=array holding the total number of plane waves for each k point,
  kg(3,mpw*mkmem)=dimensionless coords of G vecs in basis sphere at k point

NOTES

 Note that in case of band parallelism, the number of spin-up
 and spin-down bands must be equal at each k points

SOURCE

471 subroutine kpgio(ecut,exchn2n3d,gmet,istwfk,kg,kptns,mkmem,nband,nkpt,&
472 & mode_paral,mpi_enreg,mpw,npwarr,npwtot,nsppol)
473 
474 !Arguments ------------------------------------
475 !scalars
476  integer,intent(in) :: exchn2n3d,mkmem,mpw,nkpt,nsppol
477  real(dp),intent(in) :: ecut
478  character(len=4),intent(in) :: mode_paral
479  type(MPI_type),intent(inout) :: mpi_enreg
480 !arrays
481  integer,intent(in) :: istwfk(nkpt),nband(nkpt*nsppol)
482  integer,intent(out) :: kg(3,mpw*mkmem),npwarr(nkpt),npwtot(nkpt)
483  real(dp),intent(in) :: gmet(3,3),kptns(3,nkpt)
484 
485 !Local variables-------------------------------
486 !scalars
487  integer :: ierr,ikg,ikpt,istwf_k,me,nband_down,nband_k,npw1
488  logical :: test_npw
489  character(len=500) :: msg
490 !arrays
491  real(dp) :: kpoint(3)
492 
493 ! *************************************************************************
494 
495 !Define me
496  me=mpi_enreg%me_kpt
497 
498  if((mpi_enreg%paralbd==1) .and. (mode_paral=='PERS')) then
499    if(nsppol==2)then
500      do ikpt=1,nkpt
501        nband_k=nband(ikpt)
502        nband_down=nband(ikpt+nkpt)
503        if(nband_k/=nband_down)then
504          write(msg,'(a,a,a,a,a,a,a,a,i4,a,i4,a,a,a,i4,a,a,a)')ch10,&
505          ' kpgio : ERROR -',ch10,&
506          '  Band parallel case, one must have same number',ch10,&
507          '  of spin up and spin down bands, but input is :',ch10,&
508          '  nband(up)=',nband_k,', nband(down)=',nband_down,',',ch10,&
509          '  for ikpt=',ikpt,'.',ch10,&
510          '  Action: correct nband in your input file.'
511 !        MG: Tests v3(10,11,17) and v6(67) fail if this test is enabled
512 !        call wrtout(std_out,msg,mode_paral)
513        end if
514      end do
515    end if
516  end if
517  npwarr(:)=0
518  npwtot(:)=0
519 
520  kg=0
521  ikg=0
522 !Find (k+G) sphere for each k.
523 
524  do ikpt=1,nkpt
525 
526    nband_k = nband(ikpt)
527 
528    if(mode_paral=='PERS')then
529      if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,-1,me)) cycle
530    end if
531 
532    kpoint(:)=kptns(:,ikpt)
533    istwf_k=istwfk(ikpt)
534    call kpgsph(ecut,exchn2n3d,gmet,ikg,ikpt,istwf_k,kg,kpoint,mkmem,mpi_enreg,mpw,npw1)
535 
536    test_npw=.true.
537    if (xmpi_paral==1)then
538      if (mode_paral=='PERS')then
539        test_npw=(minval(mpi_enreg%proc_distrb(ikpt,1:nband_k,1:nsppol))==me)
540      end if
541    end if
542    if (test_npw) npwarr(ikpt)=npw1
543 
544 !  Make sure npw < nband never happens:
545 !  if (npw1<nband(ikpt)) then
546 !  write(msg, '(a,a,a,a,i5,a,3f8.4,a,a,i10,a,i10,a,a,a,a)' )ch10,&
547 !  &   ' kpgio : ERROR -',ch10,&
548 !  &   '  At k point number',ikpt,' k=',(kptns(ierr,ikpt),ierr=1,3),ch10,&
549 !  &   '  npw=',npw1,' < nband=',nband(ikpt),ch10,&
550 !  &   '  Indicates not enough planewaves for desired number of bands.',ch10,&
551 !  &   '  Action: change either ecut or nband in input file.'
552 !  ABI_ERROR(msg)
553 !  end if
554 
555 !  Find boundary of G sphere for efficient zero padding,
556 !    Shift to next section of each array kg
557    ikg=ikg+npw1
558  end do !  End of the loop over k points
559 
560 ! TODO: this fails on some platforms if nproc > nkpt
561  if(mode_paral == 'PERS') then
562    call xmpi_sum(npwarr,mpi_enreg%comm_kpt,ierr)
563  end if
564 
565  !if (mpi_enreg%nproc>1) call wrtout(std_out,' kpgio: loop on k-points done in parallel','COLL')
566 
567 !XG030513 MPIWF : now, one should sum npwarr over all processors
568 !of the WF group, to get npwtot (to be spread on all procs of the WF group
569  npwtot(:)=npwarr(:)
570 
571 !Taking into account istwfk
572  do ikpt=1,nkpt
573    if(istwfk(ikpt)>1)then
574      if(istwfk(ikpt)==2)then
575        npwtot(ikpt)=2*npwtot(ikpt)-1
576      else
577        npwtot(ikpt)=2*npwtot(ikpt)
578      end if
579    end if
580  end do
581 
582 end subroutine kpgio

m_kg/kpgstr [ Functions ]

[ Top ] [ m_kg ] [ Functions ]

NAME

 kpgstr

FUNCTION

 Compute elements of the derivative the kinetic energy operator in reciprocal
 space at given k point wrt a single cartesian strain component

INPUTS

  ecut=cut-off energy for plane wave basis sphere (Ha)
  ecutsm=smearing energy for plane wave kinetic energy (Ha)
  effmass_free=effective mass for electrons (1. in common case)
  gmet(3,3) = reciprocal lattice metric tensor (Bohr**-2)
  gprimd(3,3)=reciprocal space dimensional primitive translations
  istr=1,...6 specifies cartesian strain component 11,22,33,32,31,21
  kg(3,npw) = integer coordinates of planewaves in basis sphere.
  kpt(3)    = reduced coordinates of k point
  npw       = number of plane waves at kpt.

OUTPUT

  dkinpw(npw)=d/deps(istr) ( (1/2)*(2 pi)**2 * (k+G)**2 )

NOTES

  Src_6response/kpg3.f

SOURCE

793 subroutine kpgstr(dkinpw,ecut,ecutsm,effmass_free,gmet,gprimd,istr,kg,kpt,npw)
794 
795 !Arguments -------------------------------
796 !scalars
797  integer,intent(in) :: istr,npw
798  real(dp),intent(in) :: ecut,ecutsm,effmass_free
799 !arrays
800  integer,intent(in) :: kg(3,npw)
801  real(dp),intent(in) :: gmet(3,3),gprimd(3,3),kpt(3)
802  real(dp),intent(out) :: dkinpw(npw)
803 
804 !Local variables -------------------------
805 !scalars
806  integer :: ig,ii,ka,kb
807  real(dp) :: dfsm,dkinetic,dkpg2,ecutsm_inv,fsm,gpk1,gpk2,gpk3,htpisq
808 ! real(dp) :: d2fsm ! used in commented section below
809  real(dp) :: kpg2,xx
810  character(len=500) :: msg
811 !arrays
812  integer,save :: idx(12)=(/1,1,2,2,3,3,3,2,3,1,2,1/)
813  real(dp) :: dgmetds(3,3)
814 
815 ! *********************************************************************
816 
817 !htpisq is (1/2) (2 Pi) **2:
818  htpisq=0.5_dp*(two_pi)**2
819 
820  ecutsm_inv=0.0_dp
821  if(ecutsm>1.0d-20)ecutsm_inv=1/ecutsm
822 
823 !Compute derivative of metric tensor wrt strain component istr
824  if(istr<1 .or. istr>6)then
825    write(msg, '(a,i10,a,a,a)' )&
826    'Input istr=',istr,' not allowed.',ch10,&
827    'Possible values are 1,2,3,4,5,6 only.'
828    ABI_BUG(msg)
829  end if
830 
831  ka=idx(2*istr-1);kb=idx(2*istr)
832  do ii = 1,3
833    dgmetds(:,ii)=-(gprimd(ka,:)*gprimd(kb,ii)+gprimd(kb,:)*gprimd(ka,ii))
834  end do
835 !For historical reasons:
836  dgmetds(:,:)=0.5_dp*dgmetds(:,:)
837 
838  do ig=1,npw
839    gpk1=dble(kg(1,ig))+kpt(1)
840    gpk2=dble(kg(2,ig))+kpt(2)
841    gpk3=dble(kg(3,ig))+kpt(3)
842    kpg2=htpisq*&
843 &   ( gmet(1,1)*gpk1**2+         &
844 &   gmet(2,2)*gpk2**2+         &
845 &   gmet(3,3)*gpk3**2          &
846 &   +2.0_dp*(gpk1*gmet(1,2)*gpk2+  &
847 &   gpk1*gmet(1,3)*gpk3+  &
848 &   gpk2*gmet(2,3)*gpk3 )  )
849    dkpg2=htpisq*2.0_dp*&
850 &   (gpk1*(dgmetds(1,1)*gpk1+dgmetds(1,2)*gpk2+dgmetds(1,3)*gpk3)+  &
851 &   gpk2*(dgmetds(2,1)*gpk1+dgmetds(2,2)*gpk2+dgmetds(2,3)*gpk3)+  &
852 &   gpk3*(dgmetds(3,1)*gpk1+dgmetds(3,2)*gpk2+dgmetds(3,3)*gpk3) )
853    dkinetic=dkpg2
854    if(kpg2>ecut-ecutsm)then
855      if(kpg2>ecut-tol12)then
856 !      The wavefunction has been filtered : no derivative
857        dkinetic=0.0_dp
858      else
859        xx=(ecut-kpg2)*ecutsm_inv
860 !      This kinetic cutoff smoothing function and its xx derivatives
861 !      were produced with Mathematica and the fortran code has been
862 !      numerically checked against Mathematica.
863        fsm=1.0_dp/(xx**2*(3+xx*(1+xx*(-6+3*xx))))
864        dfsm=-3.0_dp*(-1+xx)**2*xx*(2+5*xx)*fsm**2
865 !      d2fsm=6.0_dp*xx**2*(9+xx*(8+xx*(-52+xx*(-3+xx*(137+xx*&
866 !      &                        (-144+45*xx))))))*fsm**3
867        dkinetic=dkpg2*(fsm-ecutsm_inv*kpg2*dfsm)
868      end if
869    end if
870    dkinpw(ig)=dkinetic/effmass_free
871  end do
872 
873 end subroutine kpgstr

m_kg/mkkin [ Functions ]

[ Top ] [ m_kg ] [ Functions ]

NAME

 mkkin

FUNCTION

 compute elements of kinetic energy operator in reciprocal space at a given k point

INPUTS

  ecut=cut-off energy for plane wave basis sphere (Ha)
  ecutsm=smearing energy for plane wave kinetic energy (Ha)
  effmass_free=effective mass for electrons (1. in common case)
  gmet(3,3)=reciprocal lattice metric tensor ($\textrm{Bohr}^{-2}$)
  idir1 = 1st direction of the derivative (if 1 <= idir1 <= 3, not used otherwise)
  idir2 = 2st direction of the derivative (if 1 <= idir1,idir2 <= 3, not used otherwise))
  kg(3,npw)=integer coordinates of planewaves in basis sphere.
  kpt(3)=reduced coordinates of k point
  npw=number of plane waves at kpt.

OUTPUT

  kinpw(npw)=(modified) kinetic energy (or derivative) for each plane wave (Hartree)

NOTES

 Usually, the kinetic energy expression is $(1/2) (2 \pi)^2 (k+G)^2 $
 However, the present implementation allows for a modification
 of this kinetic energy, in order to obtain smooth total energy
 curves with respect to the cut-off energy or the cell size and shape.
 Thus the usual expression is kept if it is lower then ecut-ecutsm,
 zero is returned beyond ecut, and in between, the kinetic
 energy is DIVIDED by a smearing factor (to make it infinite at the
 cut-off energy). The smearing factor is $x^2 (3-2x)$, where
 x = (ecut- unmodified energy)/ecutsm.
 This smearing factor is also used to derived a modified kinetic
 contribution to stress, in another routine (forstrnps.f)

 Also, in order to break slightly the symmetry between axes, that causes
 sometimes a degeneracy of eigenvalues and do not allow to obtain
 the same results on different machines, there is a modification
 by one part over 1.0e12 of the metric tensor elements (1,1) and (3,3)

SOURCE

323 subroutine mkkin (ecut,ecutsm,effmass_free,gmet,kg,kinpw,kpt,npw,idir1,idir2)
324 
325 !Arguments ------------------------------------
326 !scalars
327  integer,intent(in) :: npw
328  integer,intent(in) :: idir1,idir2
329  real(dp),intent(in) :: ecut,ecutsm,effmass_free
330 !arrays
331  integer,intent(in) :: kg(3,npw)
332  real(dp),intent(in) :: gmet(3,3),kpt(3)
333  real(dp),intent(out) :: kinpw(npw)
334 
335 !Local variables-------------------------------
336 !scalars
337  integer :: ig,order
338  real(dp),parameter :: break_symm=1.0d-11
339  real(dp) :: ecutsm_inv,fsm,gpk1,gpk2,gpk3,htpisq,kinetic,kpg2,dkpg2,xx
340  real(dp) :: d1kpg2,d2kpg2,ddfsm, dfsm
341 !arrays
342  real(dp) :: gmet_break(3,3) !, tsec(2)
343 
344 ! *************************************************************************
345 
346  ! htpisq is (1/2) (2 Pi) **2:
347  htpisq=0.5_dp*(two_pi)**2
348 
349  ecutsm_inv=0.0_dp
350  if(ecutsm>1.0d-20)ecutsm_inv=1/ecutsm
351 
352  gmet_break(:,:)=gmet(:,:)
353  gmet_break(1,1)=(1.0_dp+break_symm)*gmet(1,1)
354  gmet_break(3,3)=(1.0_dp-break_symm)*gmet(3,3)
355 
356  order=0 ! Compute the kinetic operator
357  if (idir1>0.and.idir1<4) then
358    order=1 ! Compute the 1st derivative of the kinetic operator
359    if (idir2>0.and.idir2<4) then
360      order=2 ! Compute the 2nd derivative of the kinetic operator
361    end if
362  end if
363 
364 !$OMP PARALLEL DO PRIVATE(dkpg2,d1kpg2,d2kpg2,gpk1,gpk2,gpk3,ig,kinetic,kpg2,xx,fsm,dfsm,ddfsm) &
365 !$OMP SHARED(kinpw,ecut,ecutsm,ecutsm_inv) &
366 !$OMP SHARED(gmet_break,htpisq,idir1,idir2,kg,kpt,npw)
367  do ig=1,npw
368    gpk1=dble(kg(1,ig))+kpt(1)
369    gpk2=dble(kg(2,ig))+kpt(2)
370    gpk3=dble(kg(3,ig))+kpt(3)
371    kpg2=htpisq*&
372 &   ( gmet_break(1,1)*gpk1**2+         &
373 &   gmet_break(2,2)*gpk2**2+         &
374 &   gmet_break(3,3)*gpk3**2          &
375 &   +2.0_dp*(gpk1*gmet_break(1,2)*gpk2+  &
376 &   gpk1*gmet_break(1,3)*gpk3+  &
377 &   gpk2*gmet_break(2,3)*gpk3 )  )
378    select case (order)
379    case(0)
380      kinetic=kpg2
381    case(1)
382      dkpg2=htpisq*2.0_dp*&
383 &     (gmet_break(idir1,1)*gpk1+gmet_break(idir1,2)*gpk2+gmet_break(idir1,3)*gpk3)
384      kinetic=dkpg2
385    case(2)
386      dkpg2=htpisq*2.0_dp*gmet_break(idir1,idir2)
387      kinetic=dkpg2
388    end select
389    if(kpg2>ecut-ecutsm)then
390      if(kpg2>ecut-tol12)then
391        if(order==0) then
392 !        Will filter the wavefunction, based on this value, in cgwf.f, getghc.f and precon.f
393          kinetic=huge(zero)*1.d-10
394        else
395 !        The wavefunction has been filtered : no derivative
396          kinetic=0
397        end if
398      else
399        if(order==0) then
400          xx=max( (ecut-kpg2)*ecutsm_inv , 1.0d-20)
401        else
402          xx=(ecut-kpg2)*ecutsm_inv
403        end if
404        if(order==2) then
405          d1kpg2=htpisq*2.0_dp*&
406 &         (gmet_break(idir1,1)*gpk1+gmet_break(idir1,2)*gpk2+gmet_break(idir1,3)*gpk3)
407          d2kpg2=htpisq*2.0_dp*&
408 &         (gmet_break(idir2,1)*gpk1+gmet_break(idir2,2)*gpk2+gmet_break(idir2,3)*gpk3)
409        end if
410 !      This kinetic cutoff smoothing function and its xx derivatives
411 !      were produced with Mathematica and the fortran code has been
412 !      numerically checked against Mathematica.
413        fsm=1.0_dp/(xx**2*(3+xx*(1+xx*(-6+3*xx))))
414        if(order>0) dfsm=-3.0_dp*(-1+xx)**2*xx*(2+5*xx)*fsm**2
415        if(order>1) ddfsm=6.0_dp*xx**2*(9+xx*(8+xx*(-52+xx*(-3+xx*(137+xx*(-144+45*xx))))))*fsm**3
416        select case (order)
417        case(0)
418          kinetic=kpg2*fsm
419        case(1)
420          kinetic=dkpg2*(fsm-ecutsm_inv*kpg2*dfsm)
421        case(2)
422          kinetic=dkpg2*fsm&
423 &         -2.0_dp*d1kpg2*dfsm*ecutsm_inv*d2kpg2&
424 &         +kpg2*ddfsm*(ecutsm_inv**2)*d1kpg2*d2kpg2&
425 &         -kpg2*dfsm*ecutsm_inv*dkpg2
426        end select
427      end if
428    end if
429    kinpw(ig)=kinetic/effmass_free
430  end do
431 !$OMP END PARALLEL DO
432 
433 end subroutine mkkin

m_kg/mkkpg [ Functions ]

[ Top ] [ m_kg ] [ Functions ]

NAME

 mkkpg

FUNCTION

 Compute all (k+G) vectors (dp, in reduced coordinates) for given k point,
 from integer coordinates of G vectors.
 Eventually compute related data.

INPUTS

  kg(3,npw)=integer coords of planewaves in basis sphere
  kpt(3)=k point in terms of recip. translations
  nkpg=second dimension of array kpg
  npw=number of plane waves in reciprocal space

OUTPUT

  kpg(npw,3)= (k+G) components
  === if nkpg==9 ===
    kpg(npw,4:9)= [(k+G)_a].[(k+G)_b] quantities

SOURCE

899 subroutine mkkpg(kg, kpg, kpt, nkpg, npw)
900 
901 !Arguments ------------------------------------
902 !scalars
903  integer,intent(in) :: nkpg,npw
904 !arrays
905  integer,intent(in) :: kg(3,npw)
906  real(dp),intent(in) :: kpt(3)
907  real(dp),intent(out) :: kpg(npw,nkpg)
908 
909 !Local variables-------------------------------
910 !scalars
911  integer :: ipw,mu,mua,mub
912  character(len=500) :: msg
913 !arrays
914  integer,parameter :: alpha(6)=(/1,2,3,3,3,2/),beta(6)=(/1,2,3,2,1,1/)
915 
916 ! *************************************************************************
917 
918  if (nkpg==0) return
919 
920  !-- Test nkpg --
921  if (nkpg/=3.and.nkpg/=9) then
922    write(msg, '(a,i0)' )' Bad value for nkpg !',nkpg
923    ABI_BUG(msg)
924  end if
925 
926  !-- Compute (k+G) --
927 !$OMP PARALLEL DO COLLAPSE(2) &
928 !$OMP PRIVATE(mu,ipw)
929  do ipw=1,npw
930    do mu=1,3
931      kpg(ipw,mu)=kpt(mu)+dble(kg(mu,ipw))
932    end do
933  end do
934 !$OMP END PARALLEL DO
935 
936  !-- Compute [(k+G)_a].[(k+G)_b] --
937  if (nkpg==9) then
938 !$OMP PARALLEL DO COLLAPSE(2) &
939 !$OMP PRIVATE(ipw,mu,mua,mub)
940    do ipw=1,npw
941      do mu=4,9
942        mua=alpha(mu-3);mub=beta(mu-3)
943        kpg(ipw,mu)=kpg(ipw,mua)*kpg(ipw,mub)
944      end do
945    end do
946 !$OMP END PARALLEL DO
947  end if
948 
949 end subroutine mkkpg

m_kg/mkkpgcart [ Functions ]

[ Top ] [ m_kg ] [ Functions ]

NAME

 mkkpgcart

FUNCTION

 Compute all (k+G) vectors (dp, in cartesian coordinates) for given k point,
 from integer coordinates of G vectors.

INPUTS

  gprimd(3,3)=dimensional reciprocal space primitive translations
  kg(3,npw)=integer coords of planewaves in basis sphere
  kpt(3)=k point in terms of recip. translations
  nkpg=second dimension of array kpg
  npw=number of plane waves in reciprocal space

OUTPUT

  kpg(npw,3)= (k+G) components

SOURCE

1124 subroutine mkkpgcart(gprimd,kg,kpgcar,kpt,nkpg,npw)
1125 
1126 !Arguments ------------------------------------
1127 !scalars
1128  integer,intent(in) :: nkpg,npw
1129 !arrays
1130  real(dp),intent(in) :: gprimd(3,3)
1131  integer,intent(in) :: kg(3,npw)
1132  real(dp),intent(in) :: kpt(3)
1133  real(dp),intent(out) :: kpgcar(npw,nkpg)
1134 
1135 !Local variables-------------------------------
1136 !scalars
1137  integer :: ipw,mu
1138  character(len=500) :: msg
1139 !arrays
1140  real(dp),allocatable :: kpg(:,:)
1141 
1142 ! *************************************************************************
1143 
1144  DBG_ENTER("COLL")
1145 
1146  if (nkpg==0) return
1147 
1148 !-- Test nkpg --
1149  if (nkpg/=3) then
1150    write(msg, '(a,i0)' )' Bad value for nkpg !',nkpg
1151    ABI_BUG(msg)
1152  end if
1153 
1154 !-- Compute (k+G) --
1155  ABI_MALLOC(kpg,(npw,nkpg))
1156 !$OMP PARALLEL DO COLLAPSE(2) &
1157 !$OMP PRIVATE(mu,ipw)
1158  do ipw=1,npw
1159    do mu=1,3
1160      kpg(ipw,mu)=kpt(mu)+dble(kg(mu,ipw))
1161    end do
1162  end do
1163 !$OMP END PARALLEL DO
1164 
1165 !$OMP PARALLEL DO &
1166 !$OMP PRIVATE(ipw)
1167  do ipw=1,npw
1168    kpgcar(ipw,1)=kpg(ipw,1)*gprimd(1,1)+kpg(ipw,2)*gprimd(1,2)+kpg(ipw,3)*gprimd(1,3)
1169    kpgcar(ipw,2)=kpg(ipw,1)*gprimd(2,1)+kpg(ipw,2)*gprimd(2,2)+kpg(ipw,3)*gprimd(2,3)
1170    kpgcar(ipw,3)=kpg(ipw,1)*gprimd(3,1)+kpg(ipw,2)*gprimd(3,2)+kpg(ipw,3)*gprimd(3,3)
1171  end do
1172 !$OMP END PARALLEL DO
1173  ABI_FREE(kpg)
1174 
1175  DBG_EXIT("COLL")
1176 
1177 end subroutine mkkpgcart

m_kg/ph1d3d [ Functions ]

[ Top ] [ m_kg ] [ Functions ]

NAME

 ph1d3d

FUNCTION

 Compute the three-dimensional phase factor $e^{i 2 \pi (k+G) cdot xred}$
 from the three one-dimensional factors, the k point coordinates,
 and the atom positions, for all planewaves which fit in the fft box.

INPUTS

  iatom, jatom= bounds of atom indices in ph1d for which ph3d has to be computed
  kg_k(3,npw_k)=reduced planewave coordinates.
  matblk= dimension of ph3d
  natom= dimension of ph1d
  npw=number of plane waves
  n1,n2,n3=dimensions of fft box (ngfft(3)).
  phkxred(2,natom)=phase factors exp(2 pi k.xred)
  ph1d(2,(2*n1+1)*natom+(2*n2+1)*natom+(2*n3+1)*natom)=exp(2Pi i G xred) for
   vectors (Gx,0,0), (0,Gy,0) and (0,0,Gz)
   with components ranging from -nj <= Gj <= nj

OUTPUT

  ph3d(2,npw_k,matblk)=$e^{2 i \pi (k+G) cdot xred}$ for vectors (Gx,Gy,Gz),
   and for atoms in the range iatom to jatom with respect to ph1d

SOURCE

612 subroutine ph1d3d(iatom, jatom, kg_k, matblk, natom, npw_k, n1, n2, n3, phkxred, ph1d, ph3d)
613 
614 !Arguments ------------------------------------
615 !scalars
616  integer,intent(in) :: iatom,jatom,matblk,n1,n2,n3,natom,npw_k
617 !arrays
618  integer,intent(in) :: kg_k(3,npw_k)
619  real(dp),intent(in) :: ph1d(2,(2*n1+1+2*n2+1+2*n3+1)*natom)
620  real(dp),intent(in) :: phkxred(2,natom)
621  real(dp),intent(out) :: ph3d(2,npw_k,matblk)
622 
623 !Local variables-------------------------------
624 !scalars
625  integer :: i1,ia,iatblk,ig,kg1,kg2,kg3,shift1,shift2,shift3
626  real(dp) :: ph12i,ph12r,ph1i,ph1r,ph2i,ph2r,ph3i,ph3r,phkxi,phkxr
627  character(len=500) :: msg
628 !arrays
629  real(dp),allocatable :: ph1kxred(:,:)
630 
631 ! *************************************************************************
632 
633  if(matblk-1 < jatom-iatom)then
634    write(msg,'(a,a,a,a,a,i0,a,a,i0,a,i0,a)')&
635    'Input natom-1 must be larger or equal to jatom-iatom,',ch10,&
636    'while their value is : ',ch10,&
637    'natom-1 = ',natom-1,ch10,&
638    'jatom=',jatom,', iatom=',iatom,'.'
639    ABI_BUG(msg)
640  end if
641 
642  ABI_MALLOC(ph1kxred,(2,-n1:n1))
643 
644  ! ia runs from iatom to jatom
645  do ia=iatom,jatom
646 
647    ! iatblk runs from 1 to matblk
648    iatblk=ia-iatom+1
649    shift1=1+n1+(ia-1)*(2*n1+1)
650    shift2=1+n2+(ia-1)*(2*n2+1)+natom*(2*n1+1)
651    shift3=1+n3+(ia-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1)
652    ! Compute product of phkxred by phase for the first component of G vector
653    phkxr=phkxred(1,ia)
654    phkxi=phkxred(2,ia)
655    do i1=-n1,n1
656      ph1kxred(1,i1)=ph1d(1,i1+shift1)*phkxr-ph1d(2,i1+shift1)*phkxi
657      ph1kxred(2,i1)=ph1d(2,i1+shift1)*phkxr+ph1d(1,i1+shift1)*phkxi
658    end do
659 
660    ! Compute tri-dimensional phase factor
661 !$OMP PARALLEL DO PRIVATE(ig,ph1r,ph1i,ph2r,ph2i,ph3r,ph3i,ph12r,ph12i,kg1,kg2,kg3)
662    do ig=1,npw_k
663      kg1=kg_k(1,ig)
664      kg2=kg_k(2,ig)+shift2
665      kg3=kg_k(3,ig)+shift3
666      ph1r=ph1kxred(1,kg1)
667      ph1i=ph1kxred(2,kg1)
668      ph2r=ph1d(1,kg2)
669      ph2i=ph1d(2,kg2)
670      ph3r=ph1d(1,kg3)
671      ph3i=ph1d(2,kg3)
672      ph12r=ph1r*ph2r-ph1i*ph2i
673      ph12i=ph1r*ph2i+ph1i*ph2r
674      ph3d(1,ig,iatblk)=ph12r*ph3r-ph12i*ph3i
675      ph3d(2,ig,iatblk)=ph12r*ph3i+ph12i*ph3r
676    end do
677 !$OMP END PARALLEL DO
678  end do
679 
680  ABI_FREE(ph1kxred)
681 
682 end subroutine ph1d3d