TABLE OF CONTENTS


ABINIT/make_efg_el [ Functions ]

[ Top ] [ Functions ]

NAME

 make_efg_el

FUNCTION

 compute the electric field gradient due to electron density

COPYRIGHT

 Copyright (C) 2005-2018 ABINIT group (JJ)
 This file is distributed under the terms of the
 GNU General Public License, see ~ABINIT/COPYING
 or http://www.gnu.org/copyleft/gpl.txt .

INPUTS

 mpi_enreg=information about MPI parallelization
 natom, number of atoms in unit cell
 nfft,ngfft(18), number of FFT points and details of FFT
 nspden, number of spin components
 nsym=number of symmetries in space group
 rhor(nfft,nspden), valence electron density, here $\tilde{n} + \hat{n}$
 rprimd(3,3), conversion from crystal coordinates to cartesian coordinates
 symrel(3,3,nsym)=symmetry operators in terms of action on primitive translations
 tnons(3,nsym) = nonsymmorphic translations
 xred(3,natom), location of atoms in crystal coordinates.

OUTPUT

 efg(3,3,natom), the 3x3 efg tensor at each atomic site due to rhor

NOTES

 This routine computes the electric field gradient, specifically the components
 $\partial^2 V/\partial x_\alpha \partial x_\beta$ of the potential generated by the valence
 electrons, at each atomic site in the unit cell. Key references: Kresse and Joubert, ``From
 ultrasoft pseudopotentials to the projector augmented wave method'', Phys. Rev. B. 59, 1758--1775 (1999),
 and Profeta, Mauri, and Pickard, ``Accurate first principles prediction of $^{17}$O NMR parameters in
 SiO$_2$: Assignment of the zeolite ferrierite spectrum'', J. Am. Chem. Soc. 125, 541--548 (2003). This
 routine computes the second derivatives of the potential generated by $\tilde{n}$ (see Kresse and Joubert
 for notation, Fourier-transforming the density, doing the sum in G space, and then transforming back at
 each atomic site. The final formula is
 \begin{displaymath}
 \frac{\partial^2 V}{\partial x_\alpha\partial x_\beta} = -4\pi^2\sum_G (G_\alpha G_\beta - \delta_{\alpha,\beta}G^2/3)
 \left(\frac{\tilde{n}(G)}{\pi G^2}\right)e^{2\pi i G\cdot R}
 \end{displaymath}

PARENTS

      calc_efg

CHILDREN

      fourdp,matpointsym,matr3inv,ptabs_fourdp,xmpi_sum,xred2xcart

SOURCE

 54 #if defined HAVE_CONFIG_H
 55 #include "config.h"
 56 #endif
 57 #include "abi_common.h"
 58 
 59 subroutine make_efg_el(efg,mpi_enreg,natom,nfft,ngfft,nspden,nsym,paral_kgb,rhor,rprimd,symrel,tnons,xred)
 60 
 61  use defs_basis
 62  use defs_abitypes
 63  use m_profiling_abi
 64 
 65  use m_geometry, only : xred2xcart
 66  use m_mpinfo,   only : ptabs_fourdp
 67  use m_xmpi,     only : xmpi_sum
 68 
 69 !This section has been created automatically by the script Abilint (TD).
 70 !Do not modify the following lines by hand.
 71 #undef ABI_FUNC
 72 #define ABI_FUNC 'make_efg_el'
 73  use interfaces_32_util
 74  use interfaces_45_geomoptim
 75  use interfaces_53_ffts
 76 !End of the abilint section
 77 
 78  implicit none
 79 
 80 !Arguments ------------------------------------
 81 !scalars
 82  integer,intent(in) :: natom,nfft,nspden,nsym,paral_kgb
 83  type(MPI_type),intent(in) :: mpi_enreg
 84 !arrays
 85  integer,intent(in) :: ngfft(18),symrel(3,3,nsym)
 86  real(dp),intent(in) :: rhor(nfft,nspden),rprimd(3,3),tnons(3,nsym),xred(3,natom)
 87  real(dp),intent(out) :: efg(3,3,natom)
 88 
 89 !Local variables-------------------------------
 90 !scalars
 91  integer :: cplex,fftdir,fofg_index,iatom,i1,i2,i2_local,i23,i3,id1,id2,id3
 92  integer :: ierr,ig,ig2,ig3,ii,ii1,ing,jj
 93  integer :: me_fft,n1,n2,n3,nproc_fft,tim_fourdp
 94  real(dp) :: cph,derivs,phase,sph,trace
 95 ! type(MPI_type) :: mpi_enreg_seq
 96 !arrays
 97  integer :: id(3)
 98  integer, ABI_CONTIGUOUS pointer :: fftn2_distrib(:),ffti2_local(:)
 99  integer, ABI_CONTIGUOUS pointer :: fftn3_distrib(:),ffti3_local(:)
100  real(dp) :: gprimd(3,3),gred(3),gvec(3),ratom(3)
101  real(dp),allocatable :: fofg(:,:),fofr(:),gq(:,:),xcart(:,:)
102 
103 ! ************************************************************************
104 
105 !DEBUG
106 !write(std_out,*)' make_efg_el : enter'
107 !ENDDEBUG
108 
109  ABI_ALLOCATE(fofg,(2,nfft))
110  ABI_ALLOCATE(fofr,(nfft))
111  ABI_ALLOCATE(xcart,(3,natom))
112 
113  efg(:,:,:) = zero
114  call xred2xcart(natom,rprimd,xcart,xred) ! get atomic locations in cartesian coords
115  call matr3inv(rprimd,gprimd)
116 
117  tim_fourdp = 0 ! timing code, not using
118  fftdir = -1 ! FT from R to G
119  cplex = 1 ! fofr is real
120 !here we are only interested in the total charge density including nhat, which is rhor(:,1)
121 !regardless of the value of nspden. This may change in the future depending on
122 !developments with noncollinear magnetization and so forth. Such a change will
123 !require an additional loop over nspden.
124 !Multiply by -1 to convert the electron particle density to the charge density
125  fofr(:) = -rhor(:,1)
126 
127  ! Get the distrib associated with this fft_grid  See hartre.F90 for another example where
128  ! this is done
129  n1=ngfft(1); n2=ngfft(2); n3=ngfft(3)
130  nproc_fft = mpi_enreg%nproc_fft; me_fft = mpi_enreg%me_fft
131  call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local)
132 
133  call fourdp(cplex,fofg,fofr,fftdir,mpi_enreg,nfft,ngfft,paral_kgb,tim_fourdp) ! construct charge density in G space
134 
135  ! the following loops over G vectors has been copied from hartre.F90 in order to be compatible with
136  ! possible FFT parallelism
137 
138  ! In order to speed the routine, precompute the components of g
139  ! Also check if the booked space was large enough...
140  ABI_ALLOCATE(gq,(3,max(n1,n2,n3)))
141  do ii=1,3
142    id(ii)=ngfft(ii)/2+2
143    do ing=1,ngfft(ii)
144      ig=ing-(ing/id(ii))*ngfft(ii)-1
145      gq(ii,ing)=ig
146    end do
147  end do
148  id1=n1/2+2;id2=n2/2+2;id3=n3/2+2
149 
150  ! Triple loop on each dimension
151  do i3=1,n3
152    ig3=i3-(i3/id3)*n3-1
153    gred(3) = gq(3,i3)
154 
155    do i2=1,n2
156      ig2=i2-(i2/id2)*n2-1
157      if (fftn2_distrib(i2) == me_fft) then
158 
159        gred(2) = gq(2,i2)
160        i2_local = ffti2_local(i2)
161        i23=n1*(i2_local-1 +(n2/nproc_fft)*(i3-1))
162        ! Do the test that eliminates the Gamma point outside of the inner loop
163        ii1=1
164        if(i23==0 .and. ig2==0 .and. ig3==0) ii1=2
165 
166        ! Final inner loop on the first dimension (note the lower limit)
167        do i1=ii1,n1
168 !         gs=gs2+ gq(1,i1)*(gq(1,i1)*gmet(1,1)+gqg2p3)
169          gred(1) = gq(1,i1)
170          gvec(1:3) = MATMUL(gprimd,gred)
171          fofg_index=i1+i23
172          trace = dot_product(gvec,gvec)
173          do ii = 1, 3 ! sum over components of efg tensor
174            do jj = 1, 3 ! sum over components of efg tensor
175              derivs = gvec(ii)*gvec(jj) ! This term is $G_\alpha G_\beta$
176              if (ii == jj) derivs = derivs - trace/three
177              do iatom = 1, natom ! sum over atoms in unit cell
178                ratom(:) = xcart(:,iatom) ! extract location of atom iatom
179                phase = two_pi*dot_product(gvec,ratom) ! argument of $e^{2\pi i G\cdot R}$
180                cph = cos(phase)
181                sph = sin(phase)
182                efg(ii,jj,iatom) = efg(ii,jj,iatom) - &
183 &               four_pi*derivs*(fofg(1,fofg_index)*cph-fofg(2,fofg_index)*sph)/trace ! real part of efg tensor
184              end do ! end loop over atoms in cell
185            end do ! end loop over jj in V_ij
186          end do ! end loop over ii in V_ij
187        end do ! End loop on i1
188      end if
189    end do ! End loop on i2
190  end do ! End loop on i3
191 
192  call xmpi_sum(efg,mpi_enreg%comm_fft,ierr)
193 
194 ! symmetrize tensor at each atomic site using point symmetry operations
195  do iatom = 1, natom
196    call matpointsym(iatom,efg(:,:,iatom),natom,nsym,rprimd,symrel,tnons,xred)
197  end do
198 
199  ABI_DEALLOCATE(fofg)
200  ABI_DEALLOCATE(fofr)
201  ABI_DEALLOCATE(xcart)
202  ABI_DEALLOCATE(gq)
203 
204 !DEBUG
205 !write(std_out,*)' make_efg_el : exit '
206 !stop
207 !ENDDEBUG
208 
209 end subroutine make_efg_el