! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !
! @@                                                                @@ !
! @@       PROGRAM  ASCOT 2014.440 (ver.4.40)                       @@ !
! @@     "Abinitio Simulation Code for Quantum Transport"           @@ !
! @@                                                                @@ !
! @@                                                                @@ !
! @@  AUTHOR(S): Hisashi KONDO (Univ. Tokyo)                        @@ !
! @@                                                09/May/2014     @@ !
! @@                                                                @@ !
! @@  Contact address: Phase System Consortium                      @@ !
! @@                                                                @@ !
! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !

module mod_mpi

  implicit none
  integer :: nprocs,myrank,ierr
  character(50) :: file_tempout
  character(50), pointer :: file_sf_scf(:,:,:)
  character(50), pointer :: file_sf_tr(:,:)

contains
  subroutine alo_mod_sftr(kt,file_selfenergy)

    implicit none
    integer, intent(in) :: kt
    character(50), intent(in) :: file_selfenergy
    character(1) :: character_temp(4),character_temk(4),a(10)
    character(50) :: filename_temp
    character(60) :: filename_com
    integer :: i1,i2,k1,i_temp1,i_temp2,ier

    if( file_selfenergy == 'none' ) then
       filename_temp='sel.data'
       filename_temp=adjustr(filename_temp)
    else
       filename_temp=adjustr(file_selfenergy)
    end if

    allocate(file_sf_tr(kt,nprocs),stat=ier)
    if( ier /= 0 ) then
       write(6,*) 'error allocate: lo_mod_sftr'
       stop
    end if

    a(1)='0'
    a(2)='1'
    a(3)='2'
    a(4)='3'
    a(5)='4'
    a(6)='5'
    a(7)='6'
    a(8)='7'
    a(9)='8'
    a(10)='9'

    do k1=1,kt
       i_temp1=k1
       do i2=1,4
          i_temp2=i_temp1/(10**(4-i2))
          character_temk(i2)=a(i_temp2+1)
          i_temp1=i_temp1-(10**(4-i2))*i_temp2
       end do
       do i1=1,nprocs
          i_temp1=i1
          do i2=1,4
             i_temp2=i_temp1/(10**(4-i2))
             character_temp(i2)=a(i_temp2+1)
             i_temp1=i_temp1-(10**(4-i2))*i_temp2
          end do
          filename_com=filename_temp//'_'//character_temk(1)//character_temk(2)    &
               //character_temk(3)//character_temk(4)    &
               //'_'//character_temp(1)//character_temp(2)    &
               //character_temp(3)//character_temp(4)
          file_sf_tr(k1,i1)=adjustl(filename_com)
       end do
    end do

    return
  end subroutine alo_mod_sftr

  subroutine dealo_mod_sftr

    implicit none
    integer :: ier

    deallocate(file_sf_tr,stat=ier)
    if( ier /= 0 ) then
       write(6,*) 'error allocate: delo_mod_sftr'
       stop
    end if

    return
  end subroutine dealo_mod_sftr

  subroutine alo_tempout

    implicit none
    character(1) :: character_temp(4),a(10)
    integer :: i2,i_temp1,i_temp2

    a(1)='0'
    a(2)='1'
    a(3)='2'
    a(4)='3'
    a(5)='4'
    a(6)='5'
    a(7)='6'
    a(8)='7'
    a(9)='8'
    a(10)='9'

    i_temp1=myrank+1
    do i2=1,4
       i_temp2=i_temp1/(10**(4-i2))
       character_temp(i2)=a(i_temp2+1)
       i_temp1=i_temp1-(10**(4-i2))*i_temp2
    end do
    file_tempout='g.output'//'_'//character_temp(1)//character_temp(2)           &
         //character_temp(3)//character_temp(4)

    return
  end subroutine alo_tempout

  subroutine alo_mod_mpi(iw,ispin,kt,file_selfenergy_scf)

    implicit none
    integer, intent(in) :: iw,ispin,kt
    character(50), intent(in) :: file_selfenergy_scf
    character(1) :: character_temp(4),character_temk(4),a(10)
    character(50) :: filename_temp
    character(60) :: filename_com
    integer :: i1,i2,i3,k1,i_temp1,i_temp2,ier

    if( file_selfenergy_scf == 'none' ) then
       filename_temp='sel.in'
       filename_temp=adjustr(filename_temp)
    else
       filename_temp=adjustr(file_selfenergy_scf)
    end if

    allocate(file_sf_scf(ispin,kt,iw),stat=ier)
    if( ier /= 0 ) then
       write(6,*) 'error allocate: alo_mod_mpi'
       stop
    end if

    a(1)='0'
    a(2)='1'
    a(3)='2'
    a(4)='3'
    a(5)='4'
    a(6)='5'
    a(7)='6'
    a(8)='7'
    a(9)='8'
    a(10)='9'

    do i3=1,ispin
       do k1=1,kt
          i_temp1=k1
          do i2=1,4
             i_temp2=i_temp1/(10**(4-i2))
             character_temk(i2)=a(i_temp2+1)
             i_temp1=i_temp1-(10**(4-i2))*i_temp2
          end do
          do i1=1,iw
             i_temp1=i1
             do i2=1,4
                i_temp2=i_temp1/(10**(4-i2))
                character_temp(i2)=a(i_temp2+1)
                i_temp1=i_temp1-(10**(4-i2))*i_temp2
             end do
             if( i3 == 1 ) then
                character_temp(1)='1'
             else
                character_temp(1)='2'
             end if
             filename_com=filename_temp//'_'//character_temk(1)//character_temk(2)  &
                  //character_temk(3)//character_temk(4)  &
                  //'_'//character_temp(1)//character_temp(2)  &
                  //character_temp(3)//character_temp(4)
             file_sf_scf(i3,k1,i1)=adjustl(filename_com)
          end do
       end do
    end do

    return
  end subroutine alo_mod_mpi

  subroutine dealo_mod_mpi

    implicit none
    integer :: ier

    deallocate(file_sf_scf,stat=ier)
    if( ier /= 0 ) then
       write(6,*) 'error allocate: dealo_mod_mpi'
       stop
    end if

    return
  end subroutine dealo_mod_mpi
end module mod_mpi
