TABLE OF CONTENTS


ABINIT/pawsushat [ Functions ]

[ Top ] [ Functions ]

NAME

 pawsushat

FUNCTION

 PAW only, for susceptibility matrix:
 Compute contribution to the product of two wavefunctions (exchange charge density)
 from hat (compensation charge) density (in reciprocal space and eventually in real space):
    sushat_{ij,R}(g)=Sum_{L}[Q^L_ijR(g)]

COPYRIGHT

 Copyright (C) 1998-2018 ABINIT group (MT)
 This file is distributed under the terms of the
 GNU General Public License, see ~abinit/COPYING
 or http://www.gnu.org/copyleft/gpl.txt .
 For the initials of contributors, see ~abinit/doc/developers/contributors.txt.

INPUTS

  atindx(natom)=index table for atoms, inverse of atindx
  cprj_k(natom,nspinor*nband_k)= wave functions projected with non-local projectors:
                                 cprj_k=<p_i|Cnk> where p_i is a non-local projector.
                                 WARNING: cprj(iatom,:) ARE SORTED BY ATOM TYPE !!!
  distribfft<type(distribfft_type)>=--optional-- contains infos related to FFT parallelism
  gbound_diel(2*mgfftdiel+8,2)=G sphere boundary for small FFT sphere.
  gylmg_diel(npwdiel,lmax_diel**2,ntypat)= -PAW only- Fourier transform of g_l(r).Y_ml(r) shape functions
  iband1,iband2= indices of the bands concerned with
  ispinor1,ispinor2= indices of spinorial components concerned with
  istwf_k=input option parameter that describes the storage of wfs
  kg_diel(3,npwdiel)=reduced planewave coordinates for the dielectric matrix.
  lmax_diel=1+max. value of l angular momentum used for dielectric matrix
  me_g0=--optional-- 1 if the current process treat the g=0 plane-wave (only needed when comm_fft is present)
  mgfftdiel=maximum size of 1D FFTs, for the computation of the dielectric matrix
  mpi_atmtab(:)=--optional-- indexes of the atoms treated by current proc
  comm_atom=--optional-- MPI communicator over atoms
  comm_fft=--optional-- MPI communicator over FT components
  natom=number of atoms in cell
  nband=number of bands at this k point for that spin polarization
  ndiel4,ndiel5,ndiel6= FFT dimensions, modified to avoid cache trashing
  nfftdiel=number of FFT grid points for the small (diel) grid
  ngfftdiel(18)=contain all needed information about 3D FFT, for dielectric matrix
  nspinor=number of spinorial components of the wavefunctions
  ntypat=number of types of atoms in unit cell.
  optreal=0 if WF product has to be output in reciprocal space
          1 if WF product has to be output in real space
  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
  pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
  ph3d_diel(2,npwdiel,natom*usepaw)=3-dim structure factors, for each atom and plane wave, for dielectric matrix
  typat(natom)=type (integer) for each atom

SIDE EFFECTS

  === if optreal=0
  wfprod(2,npwdiel)=PAW contrib. to product of two wavefunctions (iband1,iband2):
                    is added (in reciprocal space)
  === if optreal=1
  wfraug(2,ndiel4,ndiel5,ndiel6)=PAW contrib. to product of two wavefunctions (iband1,iband2)
                                 is added (in real space)

PARENTS

      susk,suskmm

CHILDREN

      destroy_distribfft,fourwf,free_my_atmtab,get_my_atmtab
      init_distribfft_seq,initmpi_seq,set_mpi_enreg_fft,unset_mpi_enreg_fft
      xmpi_sum

SOURCE

 70 #if defined HAVE_CONFIG_H
 71 #include "config.h"
 72 #endif
 73 
 74 #include "abi_common.h"
 75 
 76 subroutine pawsushat(atindx,cprj_k,gbound_diel,gylmg_diel,iband1,iband2,ispinor1,ispinor2,istwf_k,kg_diel,&
 77 &                    lmax_diel,mgfftdiel,natom,nband,ndiel4,ndiel5,ndiel6,&
 78 &                    ngfftdiel,npwdiel,nspinor,ntypat,optreal,&
 79 &                    pawang,pawtab,ph3d_diel,typat,wfprod,wfraug, &
 80 &                    mpi_atmtab,comm_atom,comm_fft,me_g0,paral_kgb,distribfft) ! optional arguments (parallelism)
 81 
 82  use defs_basis
 83  use defs_abitypes
 84  use m_profiling_abi
 85  use m_distribfft
 86  use m_errors
 87  use m_xmpi, only : xmpi_comm_self,xmpi_sum
 88 
 89  use m_pawang,     only : pawang_type
 90  use m_pawtab,     only : pawtab_type
 91  use m_pawcprj,    only : pawcprj_type
 92  use m_paral_atom, only : get_my_atmtab, free_my_atmtab
 93  use m_mpinfo,     only : set_mpi_enreg_fft, unset_mpi_enreg_fft
 94 
 95 !This section has been created automatically by the script Abilint (TD).
 96 !Do not modify the following lines by hand.
 97 #undef ABI_FUNC
 98 #define ABI_FUNC 'pawsushat'
 99  use interfaces_51_manage_mpi
100  use interfaces_53_ffts
101 !End of the abilint section
102 
103  implicit none
104 
105 !Arguments ---------------------------------------------
106 !scalars
107  integer,intent(in) :: iband1,iband2,ispinor1,ispinor2,istwf_k,lmax_diel,mgfftdiel
108  integer,intent(in) :: natom,nband,ndiel4,ndiel5,ndiel6,npwdiel,nspinor
109  integer,intent(in) :: ntypat,optreal
110  integer,optional,intent(in) :: me_g0,comm_atom,comm_fft,paral_kgb
111  type(distribfft_type),optional,intent(in),target :: distribfft
112  type(pawang_type),intent(in) :: pawang
113 !arrays
114  integer,intent(in) :: atindx(natom),gbound_diel(2*mgfftdiel+8,2)
115  integer,intent(in) :: kg_diel(3,npwdiel),ngfftdiel(18),typat(natom)
116  integer,optional,target,intent(in) :: mpi_atmtab(:)
117  real(dp),intent(in) :: gylmg_diel(npwdiel,lmax_diel**2,ntypat)
118  real(dp),intent(in) :: ph3d_diel(2,npwdiel,natom)
119  real(dp),intent(inout) :: wfprod(2,npwdiel*(1-optreal))
120  real(dp),intent(inout) :: wfraug(2,ndiel4,ndiel5,ndiel6*optreal)
121  type(pawcprj_type),intent(in) :: cprj_k(natom,nspinor*nband)
122  type(pawtab_type),intent(in) :: pawtab(ntypat)
123 
124 !Local variables ---------------------------------------
125 !scalars
126  integer :: cplex,iatm,iatom,iatom_tot,ibsp1,ibsp2,ierr,il,ilmn,ils,ilslm,ipw
127  integer :: itypat,j0lmn,jlmn,klm,klmn,lmax,lmin,mm,my_comm_atom,my_comm_fft,my_natom,paral_kgb_fft,tim_fourwf
128  real(dp) :: phil1,phil2,sgn,weight_dum,wf1,wf2
129  logical :: my_atmtab_allocated,parity,paral_atom
130  type(distribfft_type),pointer :: my_distribfft
131  type(mpi_type) :: mpi_enreg_fft
132 !arrays
133  integer,pointer :: my_atmtab(:)
134  real(dp) :: ro(2),ro_ql(2)
135  real(dp),allocatable :: dummy(:,:),wfprod_paw(:,:),wfraug_paw(:,:,:,:)
136 
137 ! *************************************************************************
138 
139  DBG_ENTER("COLL")
140 
141  if (present(comm_fft)) then
142    if ((.not.present(paral_kgb)).or.(.not.present(me_g0))) then
143      MSG_BUG('Need paral_kgb and me_g0 with comm_fft !')
144    end if
145  end if
146 
147 !Set up parallelism over atoms
148  paral_atom=(present(comm_atom).and.(my_natom/=natom))
149  nullify(my_atmtab);if (present(mpi_atmtab)) my_atmtab => mpi_atmtab
150  my_comm_atom=xmpi_comm_self;if (present(comm_atom)) my_comm_atom=comm_atom
151  call get_my_atmtab(my_comm_atom,my_atmtab,my_atmtab_allocated,paral_atom,natom)
152  my_natom=natom;if (paral_atom) my_natom=size(my_atmtab)
153 
154  cplex=1;if (istwf_k>1) cplex=2
155  ABI_ALLOCATE(wfprod_paw,(2,npwdiel))
156  wfprod_paw(:,:)=zero
157  ibsp1=(iband1-1)*nspinor+ispinor1
158  ibsp2=(iband2-1)*nspinor+ispinor2
159 
160 !------------------------------------------------------------------------
161 !----- Loop over atoms
162 !------------------------------------------------------------------------
163  do iatom=1,my_natom
164    iatom_tot=iatom;if (paral_atom) iatom_tot=my_atmtab(iatom)
165    iatm=atindx(iatom_tot)
166    itypat=typat(iatom_tot)
167 
168 !  ------------------------------------------------------------------------
169 !  ----- Loop over ij channels (basis components)
170 !  ------------------------------------------------------------------------
171    do jlmn=1,pawtab(itypat)%lmn_size
172      j0lmn=jlmn*(jlmn-1)/2
173      do ilmn=1,jlmn
174        klmn=j0lmn+ilmn
175        klm =pawtab(itypat)%indklmn(1,klmn)
176        lmin=pawtab(itypat)%indklmn(3,klmn)
177        lmax=pawtab(itypat)%indklmn(4,klmn)
178 
179        ro(1)=cprj_k(iatm,ibsp1)%cp(1,ilmn)*cprj_k(iatm,ibsp2)%cp(1,jlmn)
180        if (cplex==2) then
181          ro(1)=ro(1)+cprj_k(iatm,ibsp1)%cp(2,ilmn)*cprj_k(iatm,ibsp2)%cp(2,jlmn)
182          ro(2)=cprj_k(iatm,ibsp1)%cp(2,ilmn)*cprj_k(iatm,ibsp2)%cp(1,jlmn) &
183 &         -cprj_k(iatm,ibsp1)%cp(1,ilmn)*cprj_k(iatm,ibsp2)%cp(2,jlmn)
184        end if
185        ro(1:cplex)=ro(1:cplex)*pawtab(itypat)%dltij(klmn)
186 
187        do ils=lmin,lmax,2
188          il=mod(ils,4);parity=(mod(il,2)==0)
189          sgn=one;if (il>1) sgn=-one
190 
191          do mm=-ils,ils
192            ilslm=ils*ils+ils+mm+1
193            if (pawang%gntselect(ilslm,klm)>0) then
194 
195              ro_ql(1:cplex)=pawtab(itypat)%qijl(ilslm,klmn)*ro(1:cplex)
196 
197 !            Compute: Sum_{ijR} [ cpi* cpj qij^l (-i)^l g_l(g) S_lm(g) ]
198 
199              if (cplex==1) then
200                if (parity) then
201                  do ipw=1,npwdiel
202                    phil1= sgn*ph3d_diel(1,ipw,iatm)     ! (i)^l.exp(i.g.R)
203                    phil2= sgn*ph3d_diel(2,ipw,iatm)
204                    wf1= phil1*ro_ql(1)                  ! cpi* cpj qij^l (-i)^l.exp(-i.g.R)
205                    wf2=-phil2*ro_ql(1)
206                    wfprod_paw(1,ipw)=wfprod_paw(1,ipw)+wf1*gylmg_diel(ipw,ilslm,itypat)
207                    wfprod_paw(2,ipw)=wfprod_paw(2,ipw)+wf2*gylmg_diel(ipw,ilslm,itypat)
208                  end do
209                else
210                  do ipw=1,npwdiel
211                    phil1=-sgn*ph3d_diel(2,ipw,iatm)  ! (i)^l.exp(i.g.R)
212                    phil2= sgn*ph3d_diel(1,ipw,iatm)
213                    wf1= phil1*ro_ql(1)               ! cpi* cpj qij^l (-i)^l.exp(-i.g.R)
214                    wf2=-phil2*ro_ql(1)
215                    wfprod_paw(1,ipw)=wfprod_paw(1,ipw)+wf1*gylmg_diel(ipw,ilslm,itypat)
216                    wfprod_paw(2,ipw)=wfprod_paw(2,ipw)+wf2*gylmg_diel(ipw,ilslm,itypat)
217                  end do
218                end if
219 
220              else
221 
222                if (parity) then
223                  do ipw=1,npwdiel
224                    phil1= sgn*ph3d_diel(1,ipw,iatm)     ! (i)^l.exp(i.g.R)
225                    phil2= sgn*ph3d_diel(2,ipw,iatm)
226                    wf1=phil1*ro_ql(1)+phil2*ro_ql(2)    ! cpi* cpj qij^l (-i)^l.exp(-i.g.R)
227                    wf2=phil1*ro_ql(2)-phil2*ro_ql(1)
228                    wfprod_paw(1,ipw)=wfprod_paw(1,ipw)+wf1*gylmg_diel(ipw,ilslm,itypat)
229                    wfprod_paw(2,ipw)=wfprod_paw(2,ipw)+wf2*gylmg_diel(ipw,ilslm,itypat)
230                  end do
231                else
232                  do ipw=1,npwdiel
233                    phil1=-sgn*ph3d_diel(2,ipw,iatm)     ! (i)^l.exp(i.g.R)
234                    phil2= sgn*ph3d_diel(1,ipw,iatm)
235                    wf1=phil1*ro_ql(1)+phil2*ro_ql(2)    ! cpi* cpj qij^l (-i)^l.exp(-i.g.R)
236                    wf2=phil1*ro_ql(2)-phil2*ro_ql(1)
237                    wfprod_paw(1,ipw)=wfprod_paw(1,ipw)+wf1*gylmg_diel(ipw,ilslm,itypat)
238                    wfprod_paw(2,ipw)=wfprod_paw(2,ipw)+wf2*gylmg_diel(ipw,ilslm,itypat)
239                  end do
240                end if
241 
242              end if
243            end if
244          end do
245        end do
246 
247 !      ----- End loop over ij channels
248      end do
249    end do
250 
251 !  ----- End loop over atoms
252  end do
253 
254 !Reduction in case of parallelism over atoms
255  if (paral_atom) then
256    call xmpi_sum(wfprod_paw,my_comm_atom,ierr)
257  end if
258 
259  if (optreal==0) then
260 
261 !  === Output in reciprocal space
262    wfprod(:,:)=wfprod(:,:)+wfprod_paw(:,:)
263 
264  else
265 !  === Output in reciprocal space
266    tim_fourwf=17;weight_dum=0
267 !  Create fake mpi_enreg to wrap fourdp
268    if (present(distribfft)) then
269      my_distribfft => distribfft
270    else
271      ABI_DATATYPE_ALLOCATE(my_distribfft,)
272      call init_distribfft_seq(my_distribfft,'c',ngfftdiel(2),ngfftdiel(3),'fourwf')
273    end if
274    call initmpi_seq(mpi_enreg_fft)
275    ABI_DATATYPE_DEALLOCATE(mpi_enreg_fft%distribfft)
276    if (present(comm_fft)) then
277      call set_mpi_enreg_fft(mpi_enreg_fft,comm_fft,my_distribfft,me_g0,paral_kgb)
278      my_comm_fft=comm_fft;paral_kgb_fft=paral_kgb
279    else
280      my_comm_fft=xmpi_comm_self;paral_kgb_fft=0;
281      mpi_enreg_fft%distribfft => my_distribfft
282    end if
283 !  do FFT
284    ABI_ALLOCATE(wfraug_paw,(2,ndiel4,ndiel5,ndiel6))
285    call fourwf(1,dummy,wfprod_paw,dummy,wfraug_paw,gbound_diel,gbound_diel,&
286 &   istwf_k,kg_diel,kg_diel,mgfftdiel,mpi_enreg_fft,1,ngfftdiel,1,npwdiel,&
287 &   ndiel4,ndiel5,ndiel6,0,paral_kgb_fft,tim_fourwf,weight_dum,weight_dum)
288    wfraug(:,:,:,:)=wfraug(:,:,:,:)+wfraug_paw(:,:,:,:)
289    ABI_DEALLOCATE(wfraug_paw)
290    call unset_mpi_enreg_fft(mpi_enreg_fft)
291    if (.not.present(distribfft)) then
292      call destroy_distribfft(my_distribfft)
293      ABI_DATATYPE_DEALLOCATE(my_distribfft)
294    end if
295  end if
296 
297  ABI_DEALLOCATE(wfprod_paw)
298 
299 !Destroy atom table used for parallelism
300  call free_my_atmtab(my_atmtab,my_atmtab_allocated)
301 
302  DBG_EXIT("COLL")
303 
304 end subroutine pawsushat