00001 module m_dos
00002 implicit none
00003 contains
00004
00005 subroutine calculate_dos(NWF,NTK,nkb1,nkb2,nkb3,electron_number,threshold_transfer,delt,delw,b1,b2,b3,SK0,EIG,VKS)
00006 implicit none
00007 integer,intent(in)::NWF,NTK,nkb1,nkb2,nkb3
00008 real(8),intent(in)::electron_number
00009 real(8),intent(in)::threshold_transfer
00010 real(8),intent(in)::b1(3),b2(3),b3(3)
00011 real(8),intent(in)::SK0(3,NTK)
00012 real(8),intent(in)::EIG(NWF,NTK)
00013 real(8),intent(in)::delt
00014 real(8),intent(in)::delw
00015
00016 complex(8),intent(in)::VKS(NWF,NWF,NTK)
00017 real(8),allocatable::pdos(:,:)
00018 real(8)::flg_pdos
00019
00020 real(8),parameter::dmna=1.0d-3
00021 real(8),parameter::dmnr=1.0d-3
00022
00023 real(8)::emax
00024 real(8)::emin
00025 integer::ndosgrd
00026 real(8)::FermiEnergy
00027 real(8),allocatable::dosgrd(:)
00028 real(8),allocatable::dos(:)
00029 real(8),allocatable::efline(:)
00030
00031
00032
00033 call est_ndosgrd(NWF,NTK,EIG(1,1),delw,emin,emax,ndosgrd)
00034 allocate(dosgrd(ndosgrd));dosgrd=0.0d0
00035 call make_dosgrd(emin,delw,ndosgrd,dosgrd(1))
00036
00037
00038
00039 allocate(dos(ndosgrd));dos=0.0d0
00040 call calc_dos(NWF,NTK,nkb1,nkb2,nkb3,ndosgrd,dosgrd(1),EIG(1,1),SK0(1,1),delt,dmnr,dmna,b1(1),b2(1),b3(1),dos(1))
00041
00042
00043
00044 flg_pdos=maxval(abs(VKS))
00045 if(flg_pdos/=0.0d0)then
00046 write(6,'(a40,f15.8,a)')'flg_pdos/=0.0:',flg_pdos,': PDOS calculate:'
00047 allocate(pdos(ndosgrd,NWF));pdos=0.0d0
00048 call calc_pdos(NWF,NTK,nkb1,nkb2,nkb3,ndosgrd,dosgrd(1),EIG(1,1),VKS(1,1,1),SK0(1,1),delt,dmnr,dmna,b1(1),b2(1),b3(1),pdos(1,1))
00049 endif
00050
00051
00052
00053 call est_ef(ndosgrd,delw,electron_number,dosgrd(1),dos(1),FermiEnergy)
00054 allocate(efline(ndosgrd));efline=0.0d0
00055 call make_efline(ndosgrd,FermiEnergy,delw,dosgrd(1),dos(1),efline(1))
00056
00057
00058
00059 call wrt_dos(threshold_transfer,ndosgrd,dosgrd(1),dos(1),efline(1))
00060
00061
00062
00063 if(flg_pdos/=0.0d0)then
00064 call wrt_pdos(NWF,ndosgrd,dosgrd(1),pdos(1,1),efline(1))
00065 endif
00066
00067 return
00068 end subroutine
00069
00070 subroutine est_ndosgrd(NTB,NTK,E_EIG,deltw,emin,emax,ndosgrd)
00071 implicit none
00072 integer,intent(in)::NTB,NTK
00073 real(8),intent(in)::E_EIG(NTB,NTK)
00074 real(8),intent(in)::deltw
00075 real(8),intent(out)::emax,emin
00076 integer,intent(out)::ndosgrd
00077 real(8)::diff
00078 real(8),parameter::au=27.21151d0
00079
00080 emax=maxval(E_EIG)
00081 emin=minval(E_EIG)
00082 diff=emax-emin
00083
00084
00085
00086 ndosgrd=int(2.0d0*diff/deltw)+1
00087 emax=emax+0.5d0*diff
00088 emin=emin-0.5d0*diff
00089
00090 write(6,*)
00091 write(6,'(a50)')'GRID DATA FOR DOS:'
00092 write(6,'(a50,f15.7)')'emin(eV):',emin*au
00093 write(6,'(a50,f15.7)')'emax(eV):',emax*au
00094 write(6,'(a50,f15.7)')'deltw(eV):',deltw*au
00095 write(6,'(a50,i15)')'ndosgrd:',ndosgrd
00096 write(6,*)
00097 return
00098 end subroutine
00099
00100 subroutine make_dosgrd(emin,deltw,ndosgrd,dosgrd)
00101 implicit none
00102 real(8),intent(in)::emin,deltw
00103 integer,intent(in)::ndosgrd
00104 real(8),intent(out)::dosgrd(ndosgrd)
00105 integer::ie
00106
00107 dosgrd=0.0d0
00108 do ie=1,ndosgrd
00109 dosgrd(ie)=emin+dble(ie)*deltw
00110 enddo
00111 return
00112 end subroutine
00113
00114 subroutine est_ef(ndosgrd,deltw,electron_number,dosgrd,dos,FermiEnergy)
00115 implicit none
00116 integer,intent(in)::ndosgrd
00117 real(8),intent(in)::deltw,electron_number
00118 real(8),intent(in)::dosgrd(ndosgrd)
00119 real(8),intent(in)::dos(ndosgrd)
00120 real(8),intent(out)::FermiEnergy
00121 real(8)::SUM_REAL
00122 integer::ie
00123 real(8),parameter::au=27.21151d0
00124
00125 SUM_REAL=0.0d0
00126 do ie=1,ndosgrd-1
00127
00128
00129
00130
00131 SUM_REAL=SUM_REAL+deltw*(dos(ie)+dos(ie+1))/2.0d0
00132 enddo
00133 write(6,'(a50,f15.7)')'SUM of DOS:',SUM_REAL
00134
00135 SUM_REAL=0.0d0
00136 do ie=1,ndosgrd-1
00137 if(SUM_REAL>=electron_number)goto 3000
00138
00139
00140
00141
00142 SUM_REAL=SUM_REAL+deltw*(dos(ie)+dos(ie+1))/2.0d0
00143 enddo
00144 3000 FermiEnergy=dosgrd(ie)
00145 write(6,'(a50,f15.7)')'electron_number:',SUM_REAL
00146 write(6,'(a50,f15.7)')'FermiEnergy:',dosgrd(ie)*au
00147 return
00148 end subroutine
00149
00150 subroutine make_efline(ndosgrd,FermiEnergy,deltw,dosgrd,dos,efline)
00151 implicit none
00152 integer,intent(in)::ndosgrd
00153 real(8),intent(in)::FermiEnergy,deltw
00154 real(8),intent(in)::dosgrd(ndosgrd)
00155 real(8),intent(in)::dos(ndosgrd)
00156 real(8),intent(out)::efline(ndosgrd)
00157 real(8)::diff,diff_old,dosmax,N0ttr
00158 integer::ie,ief
00159 real(8)::SUM_REAL
00160 real(8),parameter::au=27.21151d0
00161
00162
00163
00164 diff_old=1.0d0
00165 do ie=1,ndosgrd
00166 diff=dabs(dosgrd(ie)-FermiEnergy)
00167 if(diff_old>diff) then
00168 ief=ie
00169 diff_old=diff
00170 endif
00171 enddo
00172 dosmax=1.2d0*maxval(abs(dos(:)))/au
00173 dosmax=dble(nint(dosmax*10.0d0))/10.0d0
00174 do ie=1,ndosgrd
00175 if(ie<=ief) then
00176 efline(ie)=dosmax
00177 else
00178 efline(ie)=0.0d0
00179 endif
00180 enddo
00181
00182
00183
00184 SUM_REAL=0.0d0
00185 do ie=1,ndosgrd-1
00186
00187
00188
00189
00190 SUM_REAL=SUM_REAL+deltw*(dos(ie)+dos(ie+1))/2.0d0
00191
00192 enddo
00193 write(6,*)
00194 write(6,'(a50,f15.7)')'Integral dos(w) dw:',SUM_REAL
00195 N0ttr=dos(ief)/2.0d0
00196 write(6,'(a50,f15.7)')'N(0) in au per calc cell:',N0ttr
00197 write(6,'(a50,f15.7)')'N(0) in eV per calc cell:',N0ttr/au
00198 write(6,*)
00199 return
00200 end subroutine
00201
00202 subroutine wrt_dos(threshold_transfer,ndosgrd,dosgrd,dos,efline)
00203 implicit none
00204 integer,intent(in)::ndosgrd
00205 real(8),intent(in)::dosgrd(ndosgrd)
00206 real(8),intent(in)::dos(ndosgrd)
00207 real(8),intent(in)::efline(ndosgrd)
00208 real(8),intent(in)::threshold_transfer
00209 integer::ie
00210 real(8),parameter::au=27.21151d0
00211
00212
00213
00214 OPEN(300,file='./dat.dos-total')
00215 rewind(300)
00216 write(300,'(a,x,f10.5)')'#Energy cutoff for transfer (eV):',threshold_transfer*au
00217 do ie=1,ndosgrd
00218 write(300,'(3f15.10)') dosgrd(ie)*au,dos(ie)/au,efline(ie)
00219 enddo
00220 close(300)
00221 return
00222 end subroutine
00223
00224 subroutine wrt_pdos(NTB,ndosgrd,dosgrd,pdos,efline)
00225 implicit none
00226 integer,intent(in)::NTB
00227 integer,intent(in)::ndosgrd
00228 real(8),intent(in)::dosgrd(ndosgrd)
00229 real(8),intent(in)::pdos(ndosgrd,NTB)
00230 real(8),intent(in)::efline(ndosgrd)
00231 character(99)::filename
00232 integer::ie,ib
00233 real(8),parameter::au=27.21151d0
00234
00235
00236
00237 do ib=1,NTB
00238 write(filename,'("./dat.dos-",i3.3)')ib
00239 OPEN(400,FILE=TRIM(filename))
00240 rewind(400)
00241 do ie=1,ndosgrd
00242 write(400,'(3f15.10)') dosgrd(ie)*au,pdos(ie,ib)/au,efline(ie)
00243 enddo
00244 close(400)
00245 enddo
00246 return
00247 end subroutine wrt_pdos
00248
00249 subroutine calc_dos(NTB,NTK,nkb1,nkb2,nkb3,ndosgrd,dosgrd,E_EIG,SK0,delt,dmnr,dmna,b1,b2,b3,dos)
00250 use m_tetrahedron
00251 implicit none
00252 integer,intent(in)::NTB,NTK,nkb1,nkb2,nkb3,ndosgrd
00253 real(8),intent(in)::dosgrd(ndosgrd)
00254 real(8),intent(in)::E_EIG(NTB,NTK)
00255 real(8),intent(in)::SK0(3,NTK)
00256 real(8),intent(in)::delt,dmnr,dmna
00257 real(8),intent(in)::b1(3),b2(3),b3(3)
00258 real(8),intent(out)::dos(ndosgrd)
00259
00260 integer::index_kpt(nkb1,nkb2,nkb3)
00261 integer::imt1(4*nkb1*nkb2*nkb3*6)
00262 integer::ie,jb,ik,ikb1,ikb2,ikb3
00263 integer::iomp,omp_get_thread_num
00264 real(8)::SUM_REAL
00265 complex(8)::fk_1D(NTK)
00266 complex(8)::fk_3D(nkb1,nkb2,nkb3)
00267 complex(8)::gk_1D(NTK)
00268 complex(8)::gk_3D(nkb1,nkb2,nkb3)
00269 complex(8)::xo(nkb1,nkb2,nkb3)
00270 complex(8)::xow(ndosgrd,nkb1,nkb2,nkb3)
00271 real(8),parameter::pi=dacos(-1.0d0)
00272 real(8),parameter::au=27.21151d0
00273
00274 call make_index_kpt(NTK,nkb1,nkb2,nkb3,SK0(1,1),index_kpt(1,1,1))
00275 call ttrhdrn_mkidx(nkb1,nkb2,nkb3,imt1(1),b1(1),b2(1),b3(1))
00276 xow=0.0d0
00277
00278
00279
00280 do ie=1,ndosgrd
00281 do jb=1,NTB
00282 fk_1D=0.0d0
00283 gk_1D=0.0d0
00284 do ik=1,NTK
00285 fk_1D(ik)=1.0d0
00286 gk_1D(ik)=cmplx(dosgrd(ie)-E_EIG(jb,ik),-delt)
00287 enddo
00288 fk_3D=0.0d0
00289 gk_3D=0.0d0
00290 do ikb3=1,nkb3
00291 do ikb2=1,nkb2
00292 do ikb1=1,nkb1
00293 ik=index_kpt(ikb1,ikb2,ikb3)
00294 fk_3D(ikb1,ikb2,ikb3)=fk_1D(ik)
00295 gk_3D(ikb1,ikb2,ikb3)=gk_1D(ik)
00296 enddo
00297 enddo
00298 enddo
00299 xo=0.0d0
00300 call ttrhdrn_simple(dmna,dmnr,nkb1,nkb2,nkb3,imt1(1),&
00301 fk_3D(1,1,1),gk_3D(1,1,1),xo(1,1,1))
00302 xow(ie,:,:,:)=xow(ie,:,:,:)+xo(:,:,:)
00303 enddo
00304 iomp=omp_get_thread_num()
00305
00306
00307
00308 enddo
00309
00310
00311 dos=0.0d0
00312 do ie=1,ndosgrd
00313 SUM_REAL=0.0d0
00314 do ikb3=1,nkb3
00315 do ikb2=1,nkb2
00316 do ikb1=1,nkb1
00317 SUM_REAL=SUM_REAL+dabs(dimag(xow(ie,ikb1,ikb2,ikb3)))/pi
00318 enddo
00319 enddo
00320 enddo
00321 dos(ie)=2.0d0*SUM_REAL/dble(NTK)
00322 enddo
00323
00324 return
00325 end subroutine
00326
00327 subroutine calc_pdos(NTB,NTK,nkb1,nkb2,nkb3,ndosgrd,dosgrd,E_EIG,VKS,SK0,delt,dmnr,dmna,b1,b2,b3,pdos)
00328 use m_tetrahedron
00329 implicit none
00330 integer,intent(in)::NTB,NTK,nkb1,nkb2,nkb3,ndosgrd
00331 real(8),intent(in)::dosgrd(ndosgrd)
00332 real(8),intent(in)::E_EIG(NTB,NTK)
00333 real(8),intent(in)::SK0(3,NTK)
00334 real(8),intent(in)::delt,dmnr,dmna
00335 real(8),intent(in)::b1(3),b2(3),b3(3)
00336
00337 complex(8),intent(in)::VKS(NTB,NTB,NTK)
00338 complex(8)::pxow(ndosgrd,NTB,nkb1,nkb2,nkb3)
00339 real(8),intent(out)::pdos(ndosgrd,NTB)
00340
00341 integer::index_kpt(nkb1,nkb2,nkb3)
00342 integer::imt1(4*nkb1*nkb2*nkb3*6)
00343 integer::ie,ib,jb,ik,ikb1,ikb2,ikb3
00344 integer::iomp,omp_get_thread_num
00345 real(8)::SUM_REAL
00346 complex(8)::fk_1D(NTK)
00347 complex(8)::fk_3D(nkb1,nkb2,nkb3)
00348 complex(8)::gk_1D(NTK)
00349 complex(8)::gk_3D(nkb1,nkb2,nkb3)
00350 complex(8)::xo(nkb1,nkb2,nkb3)
00351 real(8),parameter::pi=dacos(-1.0d0)
00352 real(8),parameter::au=27.21151d0
00353
00354 call make_index_kpt(NTK,nkb1,nkb2,nkb3,SK0(1,1),index_kpt(1,1,1))
00355 call ttrhdrn_mkidx(nkb1,nkb2,nkb3,imt1(1),b1(1),b2(1),b3(1))
00356 pxow=0.0d0
00357
00358
00359
00360 do ie=1,ndosgrd
00361 do jb=1,NTB
00362 fk_1D=0.0d0
00363 gk_1D=0.0d0
00364 do ik=1,NTK
00365 fk_1D(ik)=1.0d0
00366 gk_1D(ik)=cmplx(dosgrd(ie)-E_EIG(jb,ik),-delt)
00367 enddo
00368 fk_3D=0.0d0
00369 gk_3D=0.0d0
00370 do ikb3=1,nkb3
00371 do ikb2=1,nkb2
00372 do ikb1=1,nkb1
00373 ik=index_kpt(ikb1,ikb2,ikb3)
00374 fk_3D(ikb1,ikb2,ikb3)=fk_1D(ik)
00375 gk_3D(ikb1,ikb2,ikb3)=gk_1D(ik)
00376 enddo
00377 enddo
00378 enddo
00379 xo=0.0d0
00380 call ttrhdrn_simple(dmna,dmnr,nkb1,nkb2,nkb3,imt1(1),&
00381 fk_3D(1,1,1),gk_3D(1,1,1),xo(1,1,1))
00382 pxow(ie,jb,:,:,:)=xo(:,:,:)
00383 enddo
00384 iomp=omp_get_thread_num()
00385
00386 enddo
00387
00388
00389 pdos=0.0d0
00390 do ie=1,ndosgrd
00391 do ib=1,NTB
00392 SUM_REAL=0.0d0
00393 do jb=1,NTB
00394 do ikb3=1,nkb3
00395 do ikb2=1,nkb2
00396 do ikb1=1,nkb1
00397 ik=index_kpt(ikb1,ikb2,ikb3)
00398 SUM_REAL=SUM_REAL+(abs(VKS(jb,ib,ik))**2)*dabs(dimag(pxow(ie,jb,ikb1,ikb2,ikb3)))/pi
00399 enddo
00400 enddo
00401 enddo
00402 enddo
00403 pdos(ie,ib)=2.0d0*SUM_REAL/dble(NTK)
00404 enddo
00405 enddo
00406
00407 return
00408 end subroutine calc_pdos
00409
00410 SUBROUTINE make_index_kpt(NTK,nkb1,nkb2,nkb3,SK0,index_kpt)
00411 implicit none
00412 integer::NTK,nkb1,nkb2,nkb3
00413 real(8)::SK0(3,NTK)
00414 integer::ik,ix,iy,iz
00415 real(8)::x,y,z
00416 integer::index_kpt(nkb1,nkb2,nkb3)
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 do ik=1,NTK
00452 x=SK0(1,ik)*dble(nkb1)
00453 y=SK0(2,ik)*dble(nkb2)
00454 z=SK0(3,ik)*dble(nkb3)
00455 x=x+(dble(nkb1)-dble(mod(nkb1,2)))/2.0d0
00456 y=y+(dble(nkb2)-dble(mod(nkb2,2)))/2.0d0
00457 z=z+(dble(nkb3)-dble(mod(nkb3,2)))/2.0d0
00458 ix=idnint(x)+mod(nkb1,2)
00459 iy=idnint(y)+mod(nkb2,2)
00460 iz=idnint(z)+mod(nkb3,2)
00461 index_kpt(ix,iy,iz)=ik
00462 enddo
00463
00464 RETURN
00465 END subroutine
00466
00467 end module m_dos