! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !
! @@                                                                @@ !
! @@       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 trans(descCC,w,iw_do,px,py,qx,qy,ispin,kt)

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

  implicit none

  type(MPI_MatDesc), intent(in) :: descCC
  integer, intent(in) :: iw_do
  integer, intent(in) :: px,py,qx,qy,ispin,kt
  complex(8), intent(in) :: w

  integer :: i1_do,i2_do,ier
  complex(8), allocatable :: amat_temp5(:,:),amat_temp6(:,:)
  complex(8), allocatable :: bmat_temp5(:,:),bmat_temp6(:,:)
  complex(8), parameter :: CI = (0.0d0, 1.0d0)
  character(50) :: nfile_strans

  integer :: i, j
  complex(8) :: trace



  if( iw_do > iw_max_gs ) then
     go to 100
  end if

  call alo_hami_c3(descCC)
  if( ham_model_ini == 'input' .or. ham_model_ini == 'scf_accel' ) then
     if( ham_model_ini == 'input' ) then
        call set_hami_c_cc_input(descCC,ispin)
     else
        call set_hami_c_cc_scf(descCC,ispin)
     end if
  else
     call set_hami_c_cc(descCC,px,py,qx,qy)
  end if

  allocate(amat_temp6(descCC%nrow, descCC%scol:descCC%ecol),stat=ier)
  allocate(bmat_temp6(descCC%nrow, descCC%scol:descCC%ecol),stat=ier)
  if( ier /= 0 ) then
     write(6,*) 'error allocate: trans 1'
     stop
  end if

  amat_temp6(:,:) = w*scc_mat(:,:) - hcc_mat(:,:)

  call unset_hami_c31

  bmat_temp6(:,:) = se_l_mat_per(:,:,px,py) + se_r_mat_per(:,:,qx,qy) 

  bmat_temp6(:,:) = amat_temp6(:,:) - bmat_temp6(:,:) 

  call MPI__ZGETRI_ASCOT( descCC, bmat_temp6 )

  call MPI__ZGEMM_ASCOT( 'N', 'N', descCC, &
       C1, bmat_temp6, scc_mat, C0, amat_temp6 )

  call unset_hami_c32

  call MPI__ZLATRA_ASCOT( descCC, amat_temp6, trace )
  call cal_print_text2(iw_do,trace,ispin,kt)

100 continue

  do i1_do=1,MPI%sizeE
     call MPI_BARRIER(mpi_comm_world,MPI%info)
     if( iw_do > iw_max_gs ) then
        cycle
     end if
     if( i1_do == MPI%rankE+1 ) then
        if( iw_do /= 1 ) then
           if( spin_switch_cc /= 2 ) then
              if( switch_out_gf /= 'off' ) then
                 nfile_strans='gfc'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=50,file=nfile_strans,position='append')
              end if
              if( switch_out_tr == 'all' ) then
                 nfile_strans='ftg'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=46,file=nfile_strans,position='append')
              end if
           else
              if( switch_out_gf /= 'off' ) then
                 nfile_strans='gfc_up'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=50,file=nfile_strans,position='append')
                 nfile_strans='gfc_do'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=52,file=nfile_strans,position='append')
              end if
              if( switch_out_tr == 'all' ) then
                 nfile_strans='ftg_up'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=46,file=nfile_strans,position='append')
                 nfile_strans='ftg_do'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=47,file=nfile_strans,position='append')
              end if
           end if
        else
           if( spin_switch_cc /= 2 ) then
              if( switch_out_gf /= 'off' ) then
                 nfile_strans='gfc'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=50,file=nfile_strans)
              end if
              if( switch_out_tr == 'all' ) then
                 nfile_strans='ftg'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=46,file=nfile_strans)
              end if
           else
              if( switch_out_gf /= 'off' ) then
                 nfile_strans='gfc_up'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=50,file=nfile_strans)
                 nfile_strans='gfc_do'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=52,file=nfile_strans)
              end if
              if( switch_out_tr == 'all' ) then
                 nfile_strans='ftg_up'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=46,file=nfile_strans)
                 nfile_strans='ftg_do'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=47,file=nfile_strans)
              end if
           end if
        end if
        call print_site_sel(descCC,w,amat_temp6,bmat_temp6,ispin)
        if( spin_switch_cc /= 2 ) then
           if( switch_out_gf /= 'off' ) then
              close(50)
           end if
           if( switch_out_tr == 'all' ) then
              close(46)
           end if
        else
           if( switch_out_gf /= 'off' ) then
              close(50)
              close(52)
           end if
           if( switch_out_tr == 'all' ) then
              close(46)
              close(47)
           end if
        end if
     end if
  end do

  if( iw_do > iw_max_gs ) then
     go to 110
  end if

  allocate(amat_temp5(descCC%nrow, descCC%scol:descCC%ecol),stat=ier)
  allocate(bmat_temp5(descCC%nrow, descCC%scol:descCC%ecol),stat=ier)
  if( ier /= 0 ) then
     write(6,*) 'error allocate: trans 3'
     stop
  end if


  amat_temp5(:,:) = +se_r_mat_per(:,:,qx,qy) 
  bmat_temp5(:,:) = -se_r_mat_per(:,:,qx,qy) 

  call MPI__ZTRANC_ASCOT( descCC, C1, amat_temp5, C1, bmat_temp5 )

  amat_temp5(:,:) = amat_temp5(:,:) * CI


  call MPI__ZGEMM_ASCOT( 'N', 'C', descCC, &
       C1, amat_temp5, bmat_temp6,C0, amat_temp6 )

  amat_temp5(:,:) = +se_l_mat_per(:,:,qx,qy) 
  bmat_temp5(:,:) = -se_l_mat_per(:,:,qx,qy) 

  call MPI__ZTRANC_ASCOT( descCC, C1, amat_temp5, C1, bmat_temp5 )

  amat_temp5(:,:) = amat_temp5(:,:) * CI

  call MPI__ZGEMM_ASCOT( 'N', 'N', descCC, &
       C1, amat_temp5, bmat_temp6, C0, bmat_temp5 )
  call MPI__ZGEMM_ASCOT( 'N', 'N', descCC, &
       C1, bmat_temp5, amat_temp6,C0, amat_temp5 )

  call MPI__ZLATRA_ASCOT( descCC, amat_temp5, trace )

  call cal_print_text3(iw_do,trace,ispin,kt)

110 continue

  do i1_do=1,MPI%sizeE
     call MPI_BARRIER( MPI_COMM_WORLD, MPI%info )
     if( iw_do > iw_max_gs ) then
        cycle
     end if
     if( i1_do == MPI%rankE+1 ) then
        if( iw_do /= 1 ) then
           if( spin_switch_cc /= 2 ) then
              if( switch_out_tr /= 'off' ) then
                 nfile_strans='tra'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=51,file=nfile_strans,position='append')
              end if
              if( switch_out_tr == 'all' ) then
                 nfile_strans='gam'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=48,file=nfile_strans,position='append')
              end if
              open(unit=55,file='sf_gf.dat',position='append')
           else
              if( switch_out_tr /= 'off' ) then
                 nfile_strans='tra_up'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=51,file=nfile_strans,position='append')
                 nfile_strans='tra_do'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=53,file=nfile_strans,position='append')
              end if
              if( switch_out_tr == 'all' ) then
                 nfile_strans='gam_up'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=48,file=nfile_strans,position='append')
                 nfile_strans='gam_do'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=49,file=nfile_strans,position='append')
              end if
              open(unit=55,file='sf_gf_up.dat',position='append')
              open(unit=56,file='sf_gf_do.dat',position='append')
           end if
           open(unit=57,file='em_gf.dat',position='append')
           open(unit=58,file='trans.dat',position='append')
        else
           if( spin_switch_cc /= 2 ) then
              if( switch_out_tr /= 'off' ) then
                 nfile_strans='tra'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=51,file=nfile_strans)
              end if
              if( kt /= 1 ) then
                 open(unit=55,file='sf_gf.dat',position='append')
              else
                 open(unit=55,file='sf_gf.dat')
              end if
              if( switch_out_tr == 'all' ) then
                 nfile_strans='gam'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=48,file=nfile_strans)
              end if
           else
              if( switch_out_tr /= 'off' ) then
                 nfile_strans='tra_up'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=51,file=nfile_strans)
                 nfile_strans='tra_do'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=53,file=nfile_strans)
              end if
              if( switch_out_tr == 'all' ) then
                 nfile_strans='gam_up'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=48,file=nfile_strans)
                 nfile_strans='gam_do'
                 call makefilename_strans(kt,nfile_strans)
                 open(unit=49,file=nfile_strans)
              end if
              if( kt /= 1 ) then
                 open(unit=55,file='sf_gf_up.dat',position='append')
                 open(unit=56,file='sf_gf_do.dat',position='append')
              else
                 open(unit=55,file='sf_gf_up.dat')
                 open(unit=56,file='sf_gf_do.dat')
              end if
           end if
           if( kt /= 1 ) then
              open(unit=57,file='em_gf.dat',position='append')
              open(unit=58,file='trans.dat',position='append')
           else
              open(unit=57,file='em_gf.dat')
              open(unit=58,file='trans.dat')
           end if
        end if
        call print_site_tra(descCC,w,amat_temp5,ispin)
        call print_text_t(w,iw_do,ispin,kt)
        if( spin_switch_cc /= 2 ) then
           if( switch_out_tr /= 'off' ) then
              close(51)
           end if
           close(55)
           close(57)
           close(58)
           if( switch_out_tr == 'all' ) then
              close(48)
           end if
        else
           if( switch_out_tr /= 'off' ) then
              close(51)
              close(53)
           end if
           close(55)
           close(56)
           close(57)
           close(58)
           if( switch_out_tr == 'all' ) then
              close(48)
              close(49)
           end if
        end if
     end if
  end do

  if( iw_do > iw_max_gs ) then
     go to 120
  end if

  deallocate(amat_temp5,amat_temp6,bmat_temp5,bmat_temp6,stat=ier)
  if( ier /= 0 ) then
     write(6,*) 'error deallocate: trans'
     stop
  end if

120 continue

  return
end subroutine trans

subroutine makefilename_strans(kt,nfile_strans)
  use ac_mpi_module
  implicit none

  integer, intent(in) :: kt
  character(50), intent(inout) :: nfile_strans

  character(60) :: filename_com

  write( filename_com,'("_k",i4.4,"_p",i4.4,".data")') kt, MPI%rank2  
  nfile_strans = adjustl(trim(nfile_strans)//filename_com)



  return
end subroutine makefilename_strans
