Graphene Susceptibility Code
R. B. Laughlin
c makes susceptibility from graphene bands.
parameter(nq=300)
parameter(ne=1000)
dimension xx(ne)
emax=7.0
eps=0.0000001
pi=3.1415927
c determine energy increment.
x=ne
de=emax/x
c determine momentum increment.
x=nq
dq=4.0*pi/3.0/x
c calculate sin and cos once.
s=sqrt(3.0)/2.0
c=1.0/2.0
c open output file.
open(7,file="output.dat",status="new")
c loop over momentum transfers.
dq0=2.0*pi/3.0/4.0
do 8 iq=1,4
q0x=0.0
q0y=iq*dq0
c q0y=(iq+4)*dq0
c zero out accumulator.
do 1 i=1,ne
xx(i)=0.0
1 continue
c begin looping over brillouin zone.
do 4 j=1,nq
do 4 k=1,nq
qx=(j-0.5)*dq+(k-0.5)*dq*c
qy=(k-0.5)*dq*s
call bands(q0x,q0y,qx,qy,eq,e1,e2,p)
c order the gradients.
e1=abs(e1)+eps
e2=abs(e2)+eps
c calculate minimum and maximum energies
eq=eq-(e1+e2)*dq/2.0
im=eq/de-2.0
if(im.lt.1) im=1
ip=im+(e1+e2)*dq/de+4.0
if(ip.gt.ne) ip=ne
c loop over energies in this range.
do 3 i=im,ip
c for this energy calculate the bin edges.
em=(i-1.0)*de
ep=em+de
c now calculate two areas.
dq1=(em-eq)/e1
dq2=(em-eq)/e2
am=dq1*dq2
if(dq1.gt.dq) am=am-(dq1-dq)**2*dq2/dq1
if(dq2.gt.dq) am=am-(dq2-dq)**2*dq1/dq2
if((dq1*dq2).gt.((dq1+dq2)*dq)) am=2.0*dq**2
if(dq1.lt.0.0.or.dq2.lt.0.0) am=0.0
dq1=(ep-eq)/e1
dq2=(ep-eq)/e2
ap=dq1*dq2
if(dq1.gt.dq) ap=ap-(dq1-dq)**2*dq2/dq1
if(dq2.gt.dq) ap=ap-(dq2-dq)**2*dq1/dq2
if((dq1*dq2).gt.((dq1+dq2)*dq)) ap=2.0*dq**2
if(dq1.lt.0.0.or.dq2.lt.0.0) ap=0.0
c the relevant area is the difference of these.
xx(i)=xx(i)+abs(ap-am)*p
c end of loop on energy bins.
3 continue
c end of loop over momenta.
4 continue
c output results.
x=0.0
y=(3.0/4.0/pi)**2/2.0
do 5 i=1,ne
xx(i)=xx(i)*y
x=x+xx(i)
xx(i)=xx(i)/de
5 continue
write(*,*) x
c output result with hilbert transform.
do 7 i=1,ne
x=0.0
do 6 ii=1,ne
y=i+ii
x=x-xx(ii)/y
if(i.eq.ii) go to 6
y=i-ii
x=x+xx(ii)/y
6 continue
y=-xx(i)*pi
e=(i-0.5)*de
write(7,20) e,x,y
7 continue
write(7,21)
8 continue
20 format(f10.4,2e18.7)
21 format(1h )
stop
end
subroutine bands(q0x,q0y,qx,qy,e,e1,e2,p)
complex zm,zp,z1,z2,z3
a=sqrt(3.0)/2.0
b=1.0/2.0
c compute energy and wavefunction for lower band
z1=cexp(cmplx(0.0,qx*a+qy*b))
z2=cexp(cmplx(0.0,-qx*a+qy*b))
z3=cexp(cmplx(0.0,-qy))
zm=z1+z2+z3
em=cabs(zm)
em1=a*aimag(conjg(zm)*(z1-z2))/em
em2=a*aimag(conjg(zm)*(z1-z3))/em
c compute energy and wavefunction for upper band.
qpx=qx+q0x
qpy=qy+q0y
z1=cexp(cmplx(0.0,qpx*a+qpy*b))
z2=cexp(cmplx(0.0,-qpx*a+qpy*b))
z3=cexp(cmplx(0.0,-qpy))
zp=z1+z2+z3
ep=cabs(zp)
ep1=a*aimag(conjg(zp)*(z1-z2))/ep
ep2=a*aimag(conjg(zp)*(z1-z3))/ep
c compute matrix element
p=(1.0-real(conjg(zp)*zm)/em/ep)/2.0
c compute transition energy and gradient
e=em+ep
e1=em1+ep1
e2=em2+ep2
return
end