! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !
! @@                                                                @@ !
! @@       PROGRAM  ASCOT 2014.440 (ver.4.53)                       @@ !
! @@     "Abinitio Simulation Code for Quantum Transport"           @@ !
! @@                                                                @@ !
! @@                                                                @@ !
! @@  AUTHOR(S): Hisashi KONDO (Univ. Tokyo)                        @@ !
! @@             Naoki WATANABE (Mizuho I.R.)                       @@ !
! @@             Nobutaka NISHIKAWA (Mizuho I.R.)                   @@ !
! @@                                                09/May/2014     @@ !
! @@                                                                @@ !
! @@  Contact address: Phase System Consortium                      @@ !
! @@                                                                @@ !
! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !

subroutine cal_gf_se_c_scf(descCC,descCL,descLL,descCR,descRR,ispin,kt)

  use scf_negf
  use condition_ini
  use hamiltonian_sgf
  use hamiltonian_c
  use gf_se_c
  use constant
  use ac_mpi_module
  use mod_mpi
  use hamiltonian_e

  implicit none
  type(MPI_MatDesc), intent(in) :: descCC, descCL, descLL, descCR, descRR
  integer, intent(in) :: ispin,kt
  integer :: iw_do,i1_do,i2_do,i3_do,icou,i_w_st 
  integer :: px,py,qx,qy
  complex(8) :: w,w_weight

  real(8) :: st1,st2,stdel,tot_t

  integer :: i, j

  open(unit=16,file=file_tempout,position='append')
  write(16,*) '         ------------ spin:',ispin,'------------'
  close(16)

  cdens(:,:,ispin) = 0.d0
  edens(:,:,ispin) = 0.d0

  tot_t=0.d0

  if( ispin == 1 ) then
     i_w_st=MPI%rankE
  else
     i_w_st=MPI%rankE-mod(i_total_omega,MPI%sizeE)
     if( i_w_st < 0 ) then
        i_w_st=i_w_st+MPI%sizeE
     end if
  end if

  do iw_do=1+i_w_st,i_total_omega,MPI%sizeE

     !!if(MPI%root) write(*,*) 'iw_do',iw_do,1+i_w_st,i_total_omega,MPI%sizeE

     open(unit=60,file=file_sf_scf(ispin,kt,iw_do,MPI%rank2))
     write(60,995) m_mat_max_c,i_total_omega
     close(60)

     w=omega_scf(iw_do)
     w_weight=omega_weight_scf(iw_do)


     call myclock(st1)

     open(unit=16,file=file_tempout,position='append')
     open(unit=60,file=file_sf_scf(ispin,kt,iw_do,MPI%rank2),position='append')

     write(60,997) w,w_weight,ispin
     close(60)
     do px=1,kx_max_ll                                           
        do py=1,ky_max_ll                                         
           call selfenergy_l(descCC,descCL,descLL,w,iw_do,px,py,ispin,kt)
           icou=0
           do j=descCC%scol,descCC%ecol
              do i=1,descCC%nrow
                 if( se_l_mat_per(i,j,px,py) /= dcmplx(0.d0,0.d0) ) then 
                    icou=icou+1
                 end if
              end do
           end do
           open(unit=60,file=file_sf_scf(ispin,kt,iw_do,MPI%rank2),position='append')
           write(60,*) icou
           do j=descCC%scol,descCC%ecol
              do i=1,descCC%nrow
                 if( se_l_mat_per(i,j,px,py) /= dcmplx(0.d0,0.d0) ) then 
                    write(60,999) i,j,se_l_mat_per(i,j,px,py) 
                 end if
              end do
           end do
           close(60)

        end do
     end do
     close(16)

     call myclock(st2)
     stdel=st2-st1
     tot_t=tot_t+stdel

     call myclock(st1)

     open(unit=16,file=file_tempout,position='append')
     open(unit=60,file=file_sf_scf(ispin,kt,iw_do,MPI%rank2),position='append')
     write(60,998) w,w_weight,ispin
     close(60)
     do qx=1,kx_max_rr                                           
        do qy=1,ky_max_rr                                         
           call selfenergy_r(descCC,descCR,descRR,w,iw_do,qx,qy,ispin,kt)
           icou=0
           do j=descCC%scol,descCC%ecol
              do i=1,descCC%nrow
                 if( se_r_mat_per(i,j,qx,qy) /= dcmplx(0.d0,0.d0) ) then 
                    icou=icou+1
                 end if
              end do
           end do
           open(unit=60,file=file_sf_scf(ispin,kt,iw_do,MPI%rank2),position='append')
           write(60,*) icou
           do j=descCC%scol,descCC%ecol
              do i=1,descCC%nrow
                 if( se_r_mat_per(i,j,qx,qy) /= dcmplx(0.d0,0.d0) ) then 
                    write(60,999) i,j,se_r_mat_per(i,j,qx,qy) 
                 end if
              end do
           end do
           close(60)

        end do
     end do
     close(16)

     call myclock(st2)
     stdel=st2-st1
     tot_t=tot_t+stdel

     call myclock(st1)

     open(unit=16,file=file_tempout,position='append')
     do px=1,kx_max_ll                                           
        do py=1,ky_max_ll                                         
           do qx=1,kx_max_rr                                       
              do qy=1,ky_max_rr                                     
                 call green_function_scf(descCC,w,w_weight,iw_do,px,py,qx,qy,ispin)
              end do
           end do
        end do
     end do
     close(16)

     call myclock(st2)
     stdel=st2-st1
     tot_t=tot_t+stdel


  end do

  call myclock(st1)
  call calc_edm(descCC,ispin)
  call myclock(st2)
  stdel=st2-st1
  tot_t=tot_t+stdel

  open(unit=16,file=file_tempout,position='append')
  write(16,*) '                t=',tot_t
  close(16)


995 format(i10,i10)
997 format(d28.19,d28.19,d28.19,d28.19,i5                                        &
       ,'    ** left  *******************************')
998 format(d28.19,d28.19,d28.19,d28.19,i5                                        &
       ,'    ** right *******************************')
999 format(i10,i10,d28.19,d28.19)

  return
end subroutine cal_gf_se_c_scf

subroutine cal_gf_se_read_scf(descCC,ispin,kt)

  use scf_negf
  use condition_ini
  use hamiltonian_sgf
  use hamiltonian_c
  use gf_se_c
  use constant
  use ac_mpi_module
  use mod_mpi

  implicit none
  type(MPI_MatDesc) :: descCC
  integer, intent(in) :: ispin,kt
  integer :: iw_do,i1_do,i2_do,i3_do,icou,i_total_omega_tt,i_w_st 
  integer :: px,py,qx,qy
  integer :: m_mat_max_read,itemp
  real(8) :: temp1,temp2,temp3,temp4
  complex(8) :: w,w_weight,w1

  real(8) :: st1,st2,stdel,tot_t
  integer :: i, j

  open(unit=16,file=file_tempout,position='append')
  write(16,*) '         ------------ spin:',ispin,'------------'
  close(16)

  cdens(:,:,ispin) = 0.d0
  edens(:,:,ispin) = 0.d0

  tot_t=0.d0

  if( ispin == 1 ) then
     i_w_st=MPI%rankE
  else
     i_w_st=MPI%rankE-mod(i_total_omega,MPI%sizeE)
     if( i_w_st < 0 ) then
        i_w_st=i_w_st+MPI%sizeE
     end if
  end if

  do iw_do=1+i_w_st,i_total_omega,MPI%sizeE

     !!if(MPI%root) write(*,*) 'iw_do',iw_do,1+i_w_st,i_total_omega,MPI%sizeE

     open(unit=60,file=file_sf_scf(ispin,kt,iw_do,MPI%rank2))

     read(60,*) m_mat_max_read,i_total_omega_tt

     if( i_total_omega /= i_total_omega_tt ) then
        close(60)
        open(unit=16,file=file_tempout,position='append')
        write(16,*) 'error- (i_total_omega /= i_total_omega_t)',iw_do
        write(16,*) '                 re-cal.'
        close(16)
        stop
     end if

     itemp=m_mat_max_c-m_mat_max_read

     do px=1,kx_max_ll
        do py=1,ky_max_ll
           se_l_mat_per(:,:,px,py) = dcmplx(0.d0,0.d0) 
        end do
     end do

     read(60,996) temp1,temp2,temp3,temp4
     w=dcmplx(temp1,temp2)
     w_weight=dcmplx(temp3,temp4)

     do px=1,kx_max_ll
        do py=1,ky_max_ll
           read(60,*) icou
           do i3_do=1,icou
              read(60,999) i,j,temp1,temp2
              se_l_mat_per(i,j,px,py) = dcmplx(temp1,temp2) 
           end do
        end do
     end do

     do qx=1,kx_max_rr
        do qy=1,ky_max_rr
           se_r_mat_per(:,:,qx,qy) = dcmplx(0.d0,0.d0) 
        end do
     end do

     read(60,996) temp1,temp2,temp3,temp4
     w1=dcmplx(temp1,temp2)
     if( w /= w1 ) then
        write(6,*) 'error--A  w /= w1', w, w1
        stop
     end if
     do qx=1,kx_max_rr
        do qy=1,ky_max_rr
           read(60,*) icou
           do i3_do=1,icou
              read(60,999) i,j,temp1,temp2
              se_r_mat_per(itemp+i,itemp+j,qx,qy) = dcmplx(temp1,temp2) 
           end do
        end do
     end do
     close(60)

     call myclock(st1)

     open(unit=16,file=file_tempout,position='append')
     do px=1,kx_max_ll
        do py=1,ky_max_ll
           do qx=1,kx_max_rr
              do qy=1,ky_max_rr
                 call green_function_scf(descCC,w,w_weight,iw_do,px,py,qx,qy,ispin)
              end do
           end do
        end do
     end do
     close(16)

     call myclock(st2)
     stdel=st2-st1
     tot_t=tot_t+stdel

  end do

  call myclock(st1)
  call calc_edm(descCC,ispin)
  call myclock(st2)
  stdel=st2-st1
  tot_t=tot_t+stdel



  open(unit=16,file=file_tempout,position='append')
  write(16,*) '                t=',tot_t
  close(16)


996 format(d28.19,d28.19,d28.19,d28.19)
999 format(i10,i10,d28.19,d28.19)

  return
end subroutine cal_gf_se_read_scf

subroutine cal_gf_se_c2_scf(descCC,descCL,descLL,descCR,descRR,ispin,kt)

  use scf_negf
  use condition_ini
  use hamiltonian_sgf
  use hamiltonian_c
  use gf_se_c
  use constant
  use ac_mpi_module
  use mod_mpi
  use hamiltonian_e

  implicit none
  type(MPI_MatDesc), intent(in) :: descCC, descCL, descLL, descCR, descRR
  integer, intent(in) :: ispin,kt
  integer :: iw_do,i1_do,i2_do,i3_do,icou,i_w_st 
  integer :: px,py,qx,qy
  complex(8) :: w,w_weight

  real(8) :: st1,st2,stdel,tot_t

  integer :: i, j

  open(unit=16,file=file_tempout,position='append')
  write(16,*) '         ------------ spin:',ispin,'------------'
  close(16)


  cdens(:,:,ispin) = 0.d0
  edens(:,:,ispin) = 0.d0

  tot_t=0.d0

  if( ispin == 1 ) then
     i_w_st=MPI%rankE
  else
     i_w_st=MPI%rankE-mod(i_total_omega,MPI%sizeE)
     if( i_w_st < 0 ) then
        i_w_st=i_w_st+MPI%sizeE
     end if
  end if

  do iw_do=1+i_w_st,i_total_omega,MPI%sizeE

     !!if(MPI%root) write(*,*) 'iw_do',iw_do,1+i_w_st,i_total_omega,MPI%sizeE


     w=omega_scf(iw_do)
     w_weight=omega_weight_scf(iw_do)


     call myclock(st1)

     open(unit=16,file=file_tempout,position='append')

     do px=1,kx_max_ll                                           
        do py=1,ky_max_ll                                         
           call selfenergy_l(descCC,descCL,descLL,w,iw_do,px,py,ispin,kt)

        end do
     end do
     close(16)

     call myclock(st2)
     stdel=st2-st1
     tot_t=tot_t+stdel

     call myclock(st1)

     open(unit=16,file=file_tempout,position='append')
     do qx=1,kx_max_rr                                           
        do qy=1,ky_max_rr                                         
           call selfenergy_r(descCC,descCR,descRR,w,iw_do,qx,qy,ispin,kt)

        end do
     end do
     close(16)

     call myclock(st2)
     stdel=st2-st1
     tot_t=tot_t+stdel

     call myclock(st1)

     open(unit=16,file=file_tempout,position='append')
     do px=1,kx_max_ll                                           
        do py=1,ky_max_ll                                         
           do qx=1,kx_max_rr                                       
              do qy=1,ky_max_rr                                     
                 call green_function_scf(descCC,w,w_weight,iw_do,px,py,qx,qy,ispin)
              end do
           end do
        end do
     end do
     close(16)

     call myclock(st2)
     stdel=st2-st1
     tot_t=tot_t+stdel


  end do

  call myclock(st1)
  call calc_edm(descCC,ispin)
  call myclock(st2)
  stdel=st2-st1
  tot_t=tot_t+stdel

  open(unit=16,file=file_tempout,position='append')
  write(16,*) '                t=',tot_t
  close(16)


995 format(i10,i10)
997 format(d28.19,d28.19,d28.19,d28.19,i5                                        &
       ,'    ** left  *******************************')
998 format(d28.19,d28.19,d28.19,d28.19,i5                                        &
       ,'    ** right *******************************')
999 format(i10,i10,d28.19,d28.19)

  return
end subroutine cal_gf_se_c2_scf
