00001 MODULE m_frmsf
00002
00003 IMPLICIT NONE
00004
00005 CONTAINS
00006
00007
00008 SUBROUTINE wrt_frmsf(NWF,dense,Na1,Na2,Na3,nkb1,nkb2,nkb3,a1,a2,a3,b1,b2,b3,FermiEnergy,H_MAT_R)
00009
00010
00011
00012 IMPLICIT NONE
00013
00014 integer,intent(in) :: NWF
00015 integer,intent(in) :: dense(3)
00016
00017 INTEGER,INTENT(IN) :: Na1, Na2, Na3, nkb1, nkb2, nkb3
00018 REAL(8),INTENT(IN) :: a1(3), a2(3), a3(3), b1(3), b2(3), b3(3), FermiEnergy
00019
00020
00021 COMPLEX(8),INTENT(IN) :: H_MAT_R(NWF,NWF,-Na1:Na1,-Na2:Na2,-Na3:Na3)
00022
00023
00024 INTEGER :: ik, i1, i2, i3, ib, jb, fo = 21, nk, i1min, i2min, i3min
00025 REAL(8) :: kvec(3,PRODUCT(dense(1:3))), phase, tpi=2.0d0*acos(-1.0d0),
00026
00027 & Ek(NWF,PRODUCT(dense(1:3))), proj(NWF,NWF,PRODUCT(dense(1:3)))
00028
00029 real(8),allocatable :: WEIGHT_R(:,:,:)
00030
00031
00032 COMPLEX(8) :: Hk(NWF,NWF), phase_factor, ci=CMPLX(0.0d0,1.0d0)
00033 CHARACTER(256) :: fname
00034
00035 WRITE(*,*) "Wannnier-interpolated Fermi surface"
00036
00037 WRITE(*,*) " Dense grid : ", dense(1:3)
00038
00039 nk = PRODUCT(dense(1:3))
00040
00041 ik = 0
00042 DO i1 = 1, dense(1)
00043 DO i2 = 1, dense(2)
00044 DO i3 = 1, dense(3)
00045 ik = ik + 1
00046 kvec(1:3,ik) = DBLE((/i1, i2, i3/) - 1) / DBLE(dense(1:3))
00047 END DO
00048 END DO
00049 END DO
00050
00051 allocate(WEIGHT_R(-Na1:Na1,-Na2:Na2,-Na3:Na3)); WEIGHT_R=1.0d0
00052
00053
00054
00055
00056
00057
00058
00059 Ek(1:NWF, 1:nk) = 0.0d0
00060
00061
00062 DO ik = 1, nk
00063 Hk(1:NWF,1:NWF) = 0.0d0
00064 DO ib = 1, NWF
00065 DO jb = 1, NWF
00066 DO i1 = -Na1, Na1
00067 DO i2 = -Na2, Na2
00068 DO i3 = -Na3, Na3
00069
00070
00071 CALL search_Rmin(i1,i2,i3,nkb1,nkb2,nkb3, &
00072 & a1,a2,a3,i1min,i2min,i3min)
00073 phase = tpi * DOT_PRODUCT(kvec(1:3,ik), DBLE((/i1min, i2min, i3min/)))
00074
00075 phase_factor = EXP(ci * phase) * WEIGHT_R(i1,i2,i3)
00076 Hk(jb,ib) = Hk(jb,ib) &
00077 & + H_MAT_R(jb,ib,i1,i2,i3) * phase_factor
00078 END DO
00079 END DO
00080 END DO
00081 END DO
00082 END DO
00083
00084
00085 CALL diagV(NWF,Hk(1:NWF,1:NWF),Ek(1:NWF,ik))
00086
00087
00088 proj(1:NWF,1:NWF,ik) = DBLE(CONJG(Hk(1:NWF,1:NWF)) * Hk(1:NWF,1:NWF))
00089
00090 END DO
00091
00092
00093
00094
00095
00096 WRITE(fname,'(a)')"./dat.frmsf"
00097 OPEN(fo,FILE=TRIM(fname))
00098 rewind(fo)
00099 WRITE(fo,*) dense(1:3)
00100 WRITE(fo,*) 1
00101 WRITE(fo,*) NWF
00102 WRITE(fo,*) REAL(b1(1:3))
00103 WRITE(fo,*) REAL(b2(1:3))
00104 WRITE(fo,*) REAL(b3(1:3))
00105 DO ib=1,NWF
00106 DO ik=1,nk
00107 WRITE(fo,*) REAL(Ek(ib,ik)-FermiEnergy)
00108 ENDDO
00109 ENDDO
00110 DO ib=1,NWF
00111 DO ik=1,nk
00112 WRITE(fo,*) REAL(ib)
00113 ENDDO
00114 ENDDO
00115 CLOSE(fo)
00116
00117 WRITE(*,*) TRIM(fname)," finish"
00118
00119
00120
00121 DO ib = 1, NWF
00122
00123
00124 WRITE(fname,'(a,i3.3,a)')"./dat.orb-",ib,".frmsf"
00125 OPEN(fo,FILE=TRIM(fname))
00126 WRITE(fo,*) dense(1:3)
00127 WRITE(fo,*) 1
00128 WRITE(fo,*) NWF
00129 WRITE(fo,*) REAL(b1(1:3))
00130 WRITE(fo,*) REAL(b2(1:3))
00131 WRITE(fo,*) REAL(b3(1:3))
00132 DO jb = 1, NWF
00133 DO ik = 1, nk
00134 WRITE(fo,*) REAL(Ek(jb,ik) - FermiEnergy)
00135 END DO
00136 END DO
00137 DO jb = 1, NWF
00138 DO ik = 1, nk
00139 WRITE(fo,*) REAL(proj(ib,jb,ik))
00140 END DO
00141 END DO
00142 CLOSE(fo)
00143
00144 WRITE(*,*) TRIM(fname), " for orbital ", ib
00145
00146 END DO
00147
00148
00149 END SUBROUTINE wrt_frmsf
00150
00151 subroutine search_Rmin(i,j,k,nkb1,nkb2,nkb3,a1,a2,a3,imin,jmin,kmin)
00152 implicit none
00153 integer::i,j,k,nkb1,nkb2,nkb3
00154 integer::imin,jmin,kmin
00155 real(8)::a1(3),a2(3),a3(3)
00156 integer::nmin,mmin,lmin
00157 integer::n,m,l
00158 real(8)::R_pos(3),R_abs,R_min,R_bfr
00159 R_pos(:)=dble(i)*a1(:)+dble(j)*a2(:)+dble(k)*a3(:)
00160 nmin=0;mmin=0;lmin=0
00161 R_bfr=dsqrt(R_pos(1)**2+R_pos(2)**2+R_pos(3)**2)
00162 R_min=R_bfr
00163 do n=-3,3
00164 do m=-3,3
00165 do l=-3,3
00166 R_pos(:)=dble(i+n*nkb1)*a1(:)+dble(j+m*nkb2)*a2(:)+dble(k+l*nkb3)*a3(:)
00167 R_abs=dsqrt(R_pos(1)**2+R_pos(2)**2+R_pos(3)**2)
00168 if(R_min>R_abs)then
00169 R_min=R_abs
00170 nmin=n
00171 mmin=m
00172 lmin=l
00173 endif
00174 enddo
00175 enddo
00176 enddo
00177 imin=i+nmin*nkb1
00178 jmin=j+mmin*nkb2
00179 kmin=k+lmin*nkb3
00180 return
00181
00182 end subroutine search_Rmin
00183
00184 subroutine diagV(nm,mat,eig)
00185 implicit none
00186 integer,intent(in)::nm
00187 complex(8),intent(inout)::mat(nm,nm)
00188 real(8),intent(out)::eig(nm)
00189 integer::LWORK,LRWORK,LIWORK
00190 integer,allocatable::iwork_zheevd(:)
00191 real(8),allocatable::rwork_zheevd(:)
00192 complex(8),allocatable::work_zheevd(:)
00193 integer::ind
00194 real(8)::eps
00195
00196 LWORK= 2*nm+nm**2
00197 LRWORK=1+12*nm+3*nm**2
00198 LIWORK=3+10*nm
00199 allocate(work_zheevd(LWORK));work_zheevd(:)=0.0d0
00200 allocate(rwork_zheevd(LRWORK));rwork_zheevd(:)=0.0d0
00201 allocate(iwork_zheevd(LIWORK));iwork_zheevd(:)=0
00202 eps=1.0d-18
00203 ind=0
00204
00205 call zheevd("V","U",nm,mat,nm,eig,work_zheevd,LWORK,rwork_zheevd,LRWORK,iwork_zheevd,LIWORK,ind)
00206
00207 if(ind/=0)then
00208 write(6,*)'ind=',ind
00209 stop
00210 endif
00211
00212 deallocate(work_zheevd,rwork_zheevd,iwork_zheevd)
00213 return
00214 end subroutine diagV
00215
00216 END MODULE m_frmsf