m_dmx.f90

Go to the documentation of this file.
00001 module m_dmx 
00002   implicit none
00003 contains
00004   !
00005   subroutine calculate_dmx(NTB,NTK,NWF,nkb1,nkb2,nkb3,Na1,Na2,Na3,FermiEnergy,a1,a2,a3,b1,b2,b3,SK0,EIG,UNT)
00006     implicit none 
00007     integer,intent(in)::NTB,NWF,NTK,nkb1,nkb2,nkb3,Na1,Na2,Na3 
00008     real(8),intent(in)::FermiEnergy 
00009     real(8),intent(in)::a1(3),a2(3),a3(3)
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(NTB,NTK)
00013     complex(8),intent(in)::UNT(NTB,NWF,NTK) 
00014     !
00015     integer,allocatable::lat_num_a1(:),lat_num_a2(:),lat_num_a3(:) 
00016     real(8),allocatable::WEIGHT_R(:,:,:) 
00017     real(8),allocatable::xow(:,:,:,:)
00018     complex(8),allocatable::pf(:,:,:,:) 
00019     complex(8),allocatable::dmx(:,:,:,:,:) 
00020     integer::NR 
00021     integer,parameter::flg_weight=1 
00022     !
00023     !1. lat_num_a%
00024     !
00025     NR=(2*Na1+1)*(2*Na2+1)*(2*Na3+1) 
00026     allocate(lat_num_a1(NR)); lat_num_a1=0  
00027     allocate(lat_num_a2(NR)); lat_num_a2=0  
00028     allocate(lat_num_a3(NR)); lat_num_a3=0  
00029     call make_lat_num(Na1,Na2,Na3,NR,lat_num_a1(1),lat_num_a2(1),lat_num_a3(1)) 
00030     !
00031     !2. xow(ib,ik) 
00032     !
00033     allocate(xow(NTB,nkb1,nkb2,nkb3)); xow=0.0d0 
00034     call make_xow(nkb1,nkb2,nkb3,NTB,NTK,FermiEnergy,b1(1),b2(1),b3(1),SK0(1,1),EIG(1,1),xow(1,1,1,1)) 
00035     !
00036     !3. WEIGHT_R
00037     !
00038     allocate(WEIGHT_R(-Na1:Na1,-Na2:Na2,-Na3:Na3)); WEIGHT_R=1.0d0
00039     call make_WEIGHT_R(nkb1,nkb2,nkb3,Na1,Na2,Na3,NTK,flg_weight,WEIGHT_R(-Na1,-Na2,-Na3)) 
00040     !
00041     !4. phase factor
00042     !
00043     allocate(pf(-Na1:Na1,-Na2:Na2,-Na3:Na3,NTK)); pf=0.0d0 
00044     call make_pf(Na1,Na2,Na3,nkb1,nkb2,nkb3,NTK,a1(1),a2(1),a3(1),SK0(1,1),pf(-Na1,-Na2,-Na3,1)) 
00045     !
00046     !5. density matrix 
00047     !
00048     allocate(dmx(NWF,NWF,-Na1:Na1,-Na2:Na2,-Na3:Na3)); dmx=0.0d0   
00049     call make_dmx(Na1,Na2,Na3,NR,NTB,NTK,NWF,nkb1,nkb2,nkb3,lat_num_a1(1),lat_num_a2(1),lat_num_a3(1),&
00050     SK0(1,1),UNT(1,1,1),xow(1,1,1,1),pf(-Na1,-Na2,-Na3,1),WEIGHT_R(-Na1,-Na2,-Na3),dmx(1,1,-Na1,-Na2,-Na3)) 
00051     !
00052     !6. write density matrix
00053     call wrt_model_dr(NWF,Na1,Na2,Na3,dmx(1,1,-Na1,-Na2,-Na3))
00054     ! 
00055     deallocate(WEIGHT_R,pf,xow,lat_num_a1,lat_num_a2,lat_num_a3,dmx) 
00056     !
00057     return 
00058   end subroutine calculate_dmx 
00059 
00060   subroutine make_lat_num(Na1,Na2,Na3,NR,lat_num_a1,lat_num_a2,lat_num_a3) 
00061     implicit none
00062     integer,intent(in)::Na1,Na2,Na3,NR 
00063     integer,intent(out)::lat_num_a1(NR)
00064     integer,intent(out)::lat_num_a2(NR)
00065     integer,intent(out)::lat_num_a3(NR)
00066     integer::ia1,ia2,ia3,iR 
00067     !
00068     do ia1=-Na1,Na1
00069      do ia2=-Na2,Na2
00070       do ia3=-Na3,Na3
00071        iR=(ia3+Na3+1)+(ia2+Na2)*(2*Na3+1)+(ia1+Na1)*(2*Na3+1)*(2*Na2+1) 
00072        lat_num_a1(iR)=ia1
00073        lat_num_a2(iR)=ia2
00074        lat_num_a3(iR)=ia3 
00075       enddo
00076      enddo
00077     enddo 
00078     !
00079     return 
00080   end subroutine make_lat_num 
00081 
00082   subroutine make_xow(nkb1,nkb2,nkb3,NTB,NTK,FermiEnergy,b1,b2,b3,SK0,E_EIG,xow) 
00083     use m_tetrainteg
00084     implicit none 
00085     integer,intent(in)::nkb1,nkb2,nkb3,NTB,NTK
00086     real(8),intent(in)::FermiEnergy 
00087     real(8),intent(in)::b1(3),b2(3),b3(3)
00088     real(8),intent(in)::SK0(3,NTK) 
00089     real(8),intent(in)::E_EIG(NTB,NTK) 
00090     real(8),intent(out)::xow(NTB,nkb1,nkb2,nkb3) 
00091     !
00092     integer::index_kpt(nkb1,nkb2,nkb3) 
00093     integer::imt1(4*nkb1*nkb2*nkb3*6)  
00094     complex(8)::fk_3D(nkb1,nkb2,nkb3) 
00095     complex(8)::gk_1D(NTK)
00096     complex(8)::gk_3D(nkb1,nkb2,nkb3)
00097     complex(8)::xo(nkb1,nkb2,nkb3)  
00098     complex(8)::ca1(4)
00099     complex(8)::omega(1)  
00100     integer::ib,ikb1,ikb2,ikb3,ik 
00101     real(8)::SUM_REAL 
00102     real(8),parameter::au=27.21151d0
00103     !real(8),parameter::delt=0.005d0/au!Greens function delt in au 
00104     real(8),parameter::delt=0.01d0/au!Greens function delt in au 
00105     real(8),parameter::dmna=1.0d-3!Ttrhdrn parameter dmna in au 
00106     real(8),parameter::dmnr=1.0d-3!Ttrhdrn parameter dmnr in au 
00107     real(8),parameter::pi=dacos(-1.0d0)
00108     !
00109     index_kpt=0 
00110     call make_index_kpt(NTK,nkb1,nkb2,nkb3,SK0(1,1),index_kpt(1,1,1)) 
00111     !
00112     imt1=0 
00113     call ttritg_mkidx(nkb1,nkb2,nkb3,imt1(1),b1(1),b2(1),b3(1)) 
00114     !
00115     omega(1)=cmplx(FermiEnergy,0.0d0)
00116     !
00117     !   !$OMP PARALLEL PRIVATE(ik,ib,gk_1D,fk_3D,gk_3D,ikb3,ikb2,ikb1,xo,ca1) 
00118     !   !$OMP DO 
00119     do ib=1,NTB
00120      do ik=1,NTK 
00121       gk_1D(ik)=cmplx(-E_EIG(ib,ik),-delt) 
00122      enddo 
00123      gk_3D=0.0d0 
00124      do ikb3=1,nkb3
00125       do ikb2=1,nkb2
00126        do ikb1=1,nkb1 
00127         ik=index_kpt(ikb1,ikb2,ikb3)
00128         gk_3D(ikb1,ikb2,ikb3)=gk_1D(ik) 
00129        enddo
00130       enddo
00131      enddo 
00132      fk_3D=1.0d0 
00133      xo=0.0d0 
00134      ca1=0.0d0 
00135      call ttritg_sum(dmna,dmnr,nkb1,nkb2,nkb3,imt1(1),fk_3D(1,1,1),gk_3D(1,1,1),1,omega(1),ca1(1),xo(1,1,1)) 
00136      xow(ib,:,:,:)=dabs(dimag(xo(:,:,:)))/pi  
00137     enddo!ib 
00138     !    !$OMP END DO 
00139     !    !$OMP END PARALLEL 
00140     !
00141     SUM_REAL=0.0d0 
00142     do ikb3=1,nkb3
00143      do ikb2=1,nkb2
00144       do ikb1=1,nkb1
00145        do ib=1,NTB 
00146         SUM_REAL=SUM_REAL+xow(ib,ikb1,ikb2,ikb3)  
00147        enddo 
00148       enddo 
00149      enddo 
00150     enddo 
00151     write(6,'(a40)')'+++ m_dmx: make_xow +++' 
00152     write(6,'(a40,f15.8)')'(2/N)sum_{a,k}f(a,k)',2.0d0*SUM_REAL/dble(NTK) !2 is spin   
00153     write(6,*) 
00154     return 
00155   end subroutine make_xow 
00156 
00157   subroutine make_index_kpt(NTK,nkb1,nkb2,nkb3,SK0,index_kpt)      
00158     implicit none 
00159     integer,intent(in)::NTK,nkb1,nkb2,nkb3
00160     real(8),intent(in)::SK0(3,NTK)  
00161     integer,intent(out)::index_kpt(nkb1,nkb2,nkb3)    
00162     integer::ik,ix,iy,iz
00163     real(8)::x,y,z
00164     ! 
00165     !if(MOD(NTK,2)/=0)then 
00166     ! !write(6,*)'i am in make_index for odd'
00167     ! do ik=1,NTK 
00168     !  x=SK0(1,ik)*dble(nkb1) 
00169     !  y=SK0(2,ik)*dble(nkb2)
00170     !  z=SK0(3,ik)*dble(nkb3)  
00171     !  x=x+(dble(nkb1)-1.0d0)/2.0d0 
00172     !  y=y+(dble(nkb2)-1.0d0)/2.0d0
00173     !  z=z+(dble(nkb3)-1.0d0)/2.0d0 
00174     !  ix=idnint(x)+1
00175     !  iy=idnint(y)+1
00176     !  iz=idnint(z)+1
00177     !  index_kpt(ix,iy,iz)=ik
00178     ! enddo 
00179     !else!20170316 
00180     ! !write(6,*)'i am in make_index for even'
00181     ! do ik=1,NTK 
00182     !  x=SK0(1,ik)*dble(nkb1) 
00183     !  y=SK0(2,ik)*dble(nkb2)
00184     !  z=SK0(3,ik)*dble(nkb3)  
00185     !  x=x+dble(nkb1)/2.0d0 
00186     !  y=y+dble(nkb2)/2.0d0
00187     !  z=z+dble(nkb3)/2.0d0 
00188     !  ix=idnint(x)
00189     !  iy=idnint(y)
00190     !  iz=idnint(z)
00191     !  index_kpt(ix,iy,iz)=ik
00192     ! enddo 
00193     !endif 
00194     !--
00195     !
00196     !20190520 Kazuma Nakamura
00197     !
00198     do ik=1,NTK 
00199      x=SK0(1,ik)*dble(nkb1) 
00200      y=SK0(2,ik)*dble(nkb2)
00201      z=SK0(3,ik)*dble(nkb3)  
00202      x=x+(dble(nkb1)-dble(mod(nkb1,2)))/2.0d0 
00203      y=y+(dble(nkb2)-dble(mod(nkb2,2)))/2.0d0 
00204      z=z+(dble(nkb3)-dble(mod(nkb3,2)))/2.0d0 
00205      ix=idnint(x)+mod(nkb1,2)
00206      iy=idnint(y)+mod(nkb2,2)
00207      iz=idnint(z)+mod(nkb3,2)
00208      index_kpt(ix,iy,iz)=ik
00209     enddo 
00210     ! 
00211     return 
00212   end subroutine  
00213 
00214   subroutine make_WEIGHT_R(nkb1,nkb2,nkb3,Na1,Na2,Na3,NTK,flg_weight,WEIGHT_R) 
00215     implicit none 
00216     integer,intent(in)::nkb1,nkb2,nkb3,Na1,Na2,Na3,NTK,flg_weight  
00217     real(8),intent(out)::WEIGHT_R(-Na1:Na1,-Na2:Na2,-Na3:Na3)
00218     integer::ia1,ia2,ia3
00219     real(8)::SUM_REAL 
00220     real(8),parameter::dlt_eps=1.0d-6 
00221     !
00222     if(flg_weight.eq.1)then
00223      write(6,'(a40)')'WEIGHT CALCULATED' 
00224      SUM_REAL=0.0d0 
00225      do ia1=-Na1,Na1
00226       do ia2=-Na2,Na2
00227        do ia3=-Na3,Na3
00228         if(abs(ia1)==Na1.and.mod(nkb1,2)==0.and.Na1/=0) WEIGHT_R(ia1,ia2,ia3)=WEIGHT_R(ia1,ia2,ia3)*0.5d0 
00229         if(abs(ia2)==Na2.and.mod(nkb2,2)==0.and.Na2/=0) WEIGHT_R(ia1,ia2,ia3)=WEIGHT_R(ia1,ia2,ia3)*0.5d0 
00230         if(abs(ia3)==Na3.and.mod(nkb3,2)==0.and.Na3/=0) WEIGHT_R(ia1,ia2,ia3)=WEIGHT_R(ia1,ia2,ia3)*0.5d0 
00231         SUM_REAL=SUM_REAL+WEIGHT_R(ia1,ia2,ia3)
00232        enddo!ia3
00233       enddo!ia2
00234      enddo!ia1
00235      write(6,'(a40,f15.8,i8)')'SUM_WEIGHT,NTK',SUM_REAL,NTK  
00236      if(abs(SUM_REAL-dble(NTK))>dlt_eps)then 
00237       stop 'SUM_WEIGHT/=NTK'
00238      endif 
00239     else
00240      write(6,'(a40)')'WEIGHT NOT CALCULATED' 
00241     endif 
00242     !
00243     return 
00244   end subroutine make_WEIGHT_R 
00245 
00246   subroutine make_pf(Na1,Na2,Na3,nkb1,nkb2,nkb3,NTK,a1,a2,a3,SK0,pf) 
00247     implicit none 
00248     integer,intent(in)::Na1,Na2,Na3,nkb1,nkb2,nkb3,NTK 
00249     real(8),intent(in)::a1(3),a2(3),a3(3) 
00250     real(8),intent(in)::SK0(3,NTK) 
00251     complex(8),intent(out)::pf(-Na1:Na1,-Na2:Na2,-Na3:Na3,NTK)   
00252     integer::ia1,ia2,ia3,ik 
00253     integer::ia1min,ia2min,ia3min 
00254     real(8)::PHASE 
00255     complex(8),parameter::ci=(0.0D0,1.0D0) 
00256     real(8),parameter::tpi=2.0d0*dacos(-1.0d0)
00257     !
00258     do ik=1,NTK 
00259      do ia3=-Na3,Na3 
00260       do ia2=-Na2,Na2 
00261        do ia1=-Na1,Na1 
00262         call search_Rmin(ia1,ia2,ia3,nkb1,nkb2,nkb3,a1(1),a2(1),a3(1),ia1min,ia2min,ia3min)
00263         PHASE=tpi*(SK0(1,ik)*DBLE(ia1min)+SK0(2,ik)*DBLE(ia2min)+SK0(3,ik)*DBLE(ia3min))           
00264         pf(ia1,ia2,ia3,ik)=EXP(-ci*PHASE) !notice minus sign
00265        enddo!ia1 
00266       enddo!ia2 
00267      enddo!ia3 
00268     enddo!ik  
00269     !
00270     return 
00271   end subroutine make_pf 
00272 
00273   subroutine search_Rmin(i,j,k,nkb1,nkb2,nkb3,a1,a2,a3,imin,jmin,kmin)
00274     implicit none
00275     integer,intent(in)::i,j,k,nkb1,nkb2,nkb3
00276     real(8),intent(in)::a1(3),a2(3),a3(3) 
00277     integer,intent(out)::imin,jmin,kmin
00278     integer::nmin,mmin,lmin
00279     integer::n,m,l 
00280     real(8)::R_pos(3),R_abs,R_min,R_bfr
00281     R_pos(:)=dble(i)*a1(:)+dble(j)*a2(:)+dble(k)*a3(:)
00282     nmin=0;mmin=0;lmin=0
00283     R_bfr=dsqrt(R_pos(1)**2+R_pos(2)**2+R_pos(3)**2) 
00284     R_min=R_bfr 
00285     do n=-3,3
00286      do m=-3,3
00287       do l=-3,3
00288        R_pos(:)=dble(i+n*nkb1)*a1(:)+dble(j+m*nkb2)*a2(:)+dble(k+l*nkb3)*a3(:)
00289        R_abs=dsqrt(R_pos(1)**2+R_pos(2)**2+R_pos(3)**2) 
00290        if(R_min>R_abs)then 
00291         R_min=R_abs
00292         nmin=n
00293         mmin=m
00294         lmin=l
00295        endif 
00296       enddo
00297      enddo
00298     enddo
00299     imin=i+nmin*nkb1
00300     jmin=j+mmin*nkb2
00301     kmin=k+lmin*nkb3
00302     return
00303   end subroutine search_Rmin
00304   
00305   subroutine make_dmx(Na1,Na2,Na3,NR,NTB,NTK,NWF,nkb1,nkb2,nkb3,lat_num_a1,lat_num_a2,lat_num_a3,SK0,UNT,xow,pf,WEIGHT_R,dmx) 
00306     implicit none
00307     integer,intent(in)::Na1,Na2,Na3,NR,NTB,NTK,NWF,nkb1,nkb2,nkb3   
00308     integer,intent(in)::lat_num_a1(NR),lat_num_a2(NR),lat_num_a3(NR)
00309     real(8),intent(in)::SK0(3,NTK) 
00310     real(8),intent(in)::WEIGHT_R(-Na1:Na1,-Na2:Na2,-Na3:Na3)
00311     real(8),intent(in)::xow(NTB,nkb1,nkb2,nkb3) 
00312     complex(8),intent(in)::UNT(NTB,NWF,NTK) 
00313     complex(8),intent(in)::pf(-Na1:Na1,-Na2:Na2,-Na3:Na3,NTK) 
00314     complex(8),intent(out)::dmx(NWF,NWF,-Na1:Na1,-Na2:Na2,-Na3:Na3) 
00315     integer::iR,ia1,ia2,ia3,iw,jw,ib,ikb1,ikb2,ikb3,ik 
00316     integer::index_kpt(nkb1,nkb2,nkb3) 
00317     real(8)::DMX_REAL 
00318     complex(8)::SUM_CMPX,DMX_CMPX
00319     !
00320     index_kpt=0 
00321     call make_index_kpt(NTK,nkb1,nkb2,nkb3,SK0(1,1),index_kpt(1,1,1)) 
00322     !
00323     !write(6,*) 
00324     !write(6,'(a40)')'+++ m_dmx: UNT check +++' 
00325     !do iw=1,NWF
00326     ! SUM_CMPX=0.0d0 
00327     ! do ib=1,NTB 
00328     !  do ikb1=1,nkb1
00329     !   do ikb2=1,nkb2
00330     !    do ikb3=1,nkb3 
00331     !     ik=index_kpt(ikb1,ikb2,ikb3)
00332     !     write(6,'(a,i8,2f15.8)')'pf000ik',ik,pf(0,0,0,ik)  
00333     !     SUM_CMPX=SUM_CMPX+CONJG(UNT(ib,iw,ik))*UNT(ib,iw,ik)*pf(0,0,0,ik)*WEIGHT_R(0,0,0)*xow(ib,ikb1,ikb2,ikb3) 
00334     !    enddo
00335     !   enddo
00336     !  enddo
00337     ! enddo 
00338     ! write(6,'(a40,i8,x,2f15.10)')'(2/N)sum_{a,k}|<ak|i0>|^2',iw,2.0d0*SUM_CMPX/dble(NTK)  
00339     !enddo 
00340     !
00341     dmx=0.0d0 
00342     do iR=1,NR 
00343      ia1=lat_num_a1(iR)
00344      ia2=lat_num_a2(iR)
00345      ia3=lat_num_a3(iR)
00346      !write(6,'(3i5,f15.8)')ia1,ia2,ia3,WEIGHT_R(ia1,ia2,ia3) 
00347      do iw=1,NWF
00348       do jw=1,NWF 
00349        SUM_CMPX=0.0d0 
00350        do ib=1,NTB 
00351         do ikb1=1,nkb1
00352          do ikb2=1,nkb2
00353           do ikb3=1,nkb3 
00354            ik=index_kpt(ikb1,ikb2,ikb3)
00355            SUM_CMPX&
00356           =SUM_CMPX&
00357           +CONJG(UNT(ib,iw,ik))*UNT(ib,jw,ik)*xow(ib,ikb1,ikb2,ikb3)*pf(ia1,ia2,ia3,ik)*WEIGHT_R(ia1,ia2,ia3)  
00358           enddo!ikb1
00359          enddo!ikb2
00360         enddo!ikb3
00361        enddo!ib  
00362        dmx(iw,jw,ia1,ia2,ia3)=2.0d0*SUM_CMPX/dble(NTK) !2 is spin   
00363       enddo!jw 
00364      enddo!iw 
00365     enddo!iR 
00366     ! 
00367     !impose sum rule
00368     !
00369     SUM_CMPX=0.0d0 
00370     do iw=1,NWF
00371      SUM_CMPX=SUM_CMPX+dmx(iw,iw,0,0,0) 
00372     enddo 
00373     write(6,*) 
00374     write(6,'(a40)')'+++ m_dmx: Tr(DMX) +++' 
00375     DMX_REAL=dble(nint(dble(SUM_CMPX))) 
00376     DMX_CMPX=cmplx(DMX_REAL,0.0d0)    
00377     write(6,'(a40,2f15.10)')'before correction',SUM_CMPX 
00378     write(6,'(a40,2f15.10)')'after  correction',DMX_CMPX 
00379     do iw=1,NWF
00380      dmx(iw,iw,0,0,0)=dmx(iw,iw,0,0,0)*(DMX_CMPX/SUM_CMPX) 
00381     enddo 
00382     !
00383     return 
00384   end subroutine make_dmx 
00385 
00386   subroutine wrt_model_dr(NWF,Na1,Na2,Na3,DR) 
00387     implicit none 
00388     integer,intent(in)::NWF,Na1,Na2,Na3 
00389     complex(8),intent(in)::DR(NWF,NWF,-Na1:Na1,-Na2:Na2,-Na3:Na3)
00390     integer::N_element 
00391     integer::ia1,ia2,ia3,ib,jb,i 
00392     integer,allocatable::unit_vec(:)!unit_vec(N_element) 
00393     real(8),parameter::au=27.21151d0
00394     !
00395     N_element=(2*Na1+1)*(2*Na2+1)*(2*Na3+1)  
00396     !
00397     !OPEN(307,W,FILE='zvo_dr.dat') 
00398     !
00399     OPEN(307,FILE='./dir-model/zvo_dr.dat') 
00400     write(307,'(a)')'wannier90 format for vmcdry.out or HPhi -sdry'
00401     write(307,'(i10)') NWF 
00402     write(307,'(i10)') N_element
00403     !
00404     allocate(unit_vec(N_element)); unit_vec=1
00405     write(307,'(15i5)')(unit_vec(i),i=1,N_element) 
00406     deallocate(unit_vec) 
00407     !
00408     do ia1=-Na1,Na1
00409      do ia2=-Na2,Na2
00410       do ia3=-Na3,Na3 
00411        do ib=1,NWF 
00412         do jb=1,NWF 
00413          write(307,'(i5,i5,i5,i5,i5,2f15.10)') ia1,ia2,ia3,ib,jb,DR(ib,jb,ia1,ia2,ia3) 
00414         enddo!jb
00415        enddo!ib
00416       enddo!ia3
00417      enddo!ia2
00418     enddo!ia1 
00419     return
00420     !
00421   end subroutine wrt_model_dr 
00422   !
00423 end module m_dmx 

Generated on 17 Nov 2020 for respack by  doxygen 1.6.1