! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ !
! @@                                                                @@ !
! @@       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 scf_main_negf_ac

  use scf_negf
  use fft
  use dft
  use condition_ini
  use hamiltonian_sgf
  use hamiltonian_c
  use hamiltonian_temp
  use gf_se_c
  use constant
  use ac_mpi_module
  use mod_mpi

  implicit none

  integer :: i_do,iter,cutene_vt_ok,ispin
  real(8) :: dif_max_rho
  real(8) :: st1,st2,stdel

  integer :: i_conv_ok,i_temp,ier,i1_do,i2_do,i3_do,kt,ic_spin

  real(8) :: qx_scf,qy_scf,qq_con
  type(MPI_MatDesc) :: descCC, descLL, descRR, descCR, descCL

  call MPI__setupMatDesc( descCC, m_mat_max_c,m_mat_max_c )
  call MPI__setupMatDesc( descLL, mat_max_ll, mat_max_ll )
  call MPI__setupMatDesc( descRR, mat_max_rr, mat_max_rr )
  call MPI__setupMatDesc( descCL, m_mat_max_c, mat_max_ll )
  call MPI__setupMatDesc( descCR, m_mat_max_c, mat_max_rr )

  if( ispin_pol_scf /= 2 ) then
     ic_spin=1
  else
     ic_spin=2
  end if

  call alo_mod_mpi(i_total_omega,ic_spin,kt_num,file_selfenergy_scf)

  call alo_scf_ham(descCC)

  call alo_ham_temp_ham(descCC,descLL,descRR)

  if( ft_switch == 'f_2_ft' .or. ft_switch == 'fft' .or. ft_switch == 'fftw' ) then
     call set_fft
  else
     call alo_dft(n_a,n_b,2)
  end if

  open(unit=16,file=file_tempout,position='append')
  write(16,*)
  write(16,*) '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'
  call myclock(st1)
  close(16)

  call alo_density_ini
  call fourier_pot

  if( restart_onoff /= 'on' ) then
     call iteration_ini
  end if

  call calc_charge_open

  open(unit=16,file=file_tempout,position='append')
  write(16,*) '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'
  call myclock(st2)
  stdel=st2-st1
  write(16,*) '                t=',stdel
  close(16)

  if( iter_conv > 10 .and. iter_conv < 20 ) then
     call DensityMatrix__update(dif_max_rho,0)
  else
     if( iter_conv > 20 .and. iter_conv < 30 ) then
        call Hamiltonian__calcD__ac2as
        call Density__update(dif_max_rho,0)
     end if
  end if

  call Density__deallocate2
  call Param__deallocate2

  !!call output_tmp
  !!if(MPI%root) then
  !!   write(*,*) 'time (negf scf) (sec)'
  !!   call output_time
  !!end if

  gra_onoff='off'
  cutene_vt_ok=0

  i_conv_ok=1

  open(unit=16,file=file_tempout,position='append')
  write(16,*)
  write(16,*) '**************************************************************'
  write(16,*) '************ start iteration:'
  write(16,*) '**************************************************************'
  close(16)

  do i_do=1,max_num_scf

     !!if(MPI%root) write(*,*) 'i_do', i_do

     open(unit=16,file=file_tempout,position='append')
     write(16,*)
     write(16,*) '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'
     write(16,*) '++++++++++++ iterations:',i_do
     write(16,*) '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'
     close(16)

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

     cutene_vt_ok=0
     iter=i_do

     call alo_density_2
     if( hartree_switch == 0 ) then
        call alo_use_scf_4
        call cal_vhart_easier
        call unset_use_scf_4
     else
        call cal_vhartree
     end if
     call unset_density_21

     call alo_use_scf_3(m_mat_max_c)
     call cal_vother(cutene_vt_ok)

     call cal_hamiltonian_accel
     call unset_use_scf_32

     call myclock(st2)
     stdel=st2-st1
     write(16,*) '                t=',stdel
     close(16)

     iter=i_do
     call alo_density_1(descCC)


     do kt=1,ka_scf*kb_scf
        if( ksw_po_kt_scf(kt) == 0 ) then
           cycle
        end if

        qx_scf=po_kt_scf(2,kt)
        qy_scf=po_kt_scf(3,kt)
        qq_con=dfloat(ksw_po_kt_scf(kt))

        open(unit=16,file=file_tempout,position='append')
        write(16,*) '         >>>>>>>>>>>>    k:',kt,'<<<<<<<<<<<<'
        close(16)

        call set_ham_temp_ham_l(descLL,qx_scf,qy_scf)
        call set_ham_temp_ham_r(descRR,qx_scf,qy_scf)
        call set_ham_scf_ham_c (descCC,descLL,descRR,qx_scf,qy_scf)

        do ispin=1,ic_spin
           if( file_selfenergy_onoff /= 'on' .and. i_do == 1 ) then
              call cal_gf_se_c_scf(descCC,descCL,descLL,descCR,descRR,ispin,kt)
           else
              call cal_gf_se_read_scf(descCC,ispin,kt)
           end if
           !!call cal_gf_se_c2_scf(descCC,descCL,descLL,descCR,descRR,ispin,kt)
        end do

        do ispin=1,ic_spin
           call MPI__Allreduce_MatrixE_ASCOT( descCC, cdens(:,:,ispin) )
           call MPI__Allreduce_MatrixE_ASCOT( descCC, edens(:,:,ispin) )
        end do

        call Hamiltonian__calcD__as2ac(descCC,qx_scf,qy_scf,qq_con,kt)
     end do


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

     call dens_atom2cell_lr(dif_max_rho,iter)
     call unset_density_1

     call myclock(st2)
     stdel=st2-st1
     write(16,*) '                t=',stdel

     if( (iter_conv == 1 .or. iter_conv > 10)                                   &
          .and. iter == 0 .and. cutene_vt_ok == 0 ) then
        write(16,*)
        write(16,*)                                                              &
             '**************************************************************'
        write(16,*) '************   end iterations:',i_do
        write(16,*)                                                              &
             '**************************************************************'
        i_conv_ok=0
     end if
100  continue

     close(16)

     if( i_conv_ok == 0 ) then
        exit
     end if

     !!if(MPI%root) then
     !!   write(*,*) 'time (negf scf) (sec)', i_do
     !!   call output_time
     !!end if

  end do

  if( force_calc_onoff == 'on' ) then
     call Force__calc__negf
  end if

  call unset_density_ini
  gra_onoff='on'

  call unset_scf_accel_parameter
  call dealo_ham_temp_ham

  if( ft_switch == 'f_2_ft' .or. ft_switch == 'fft' .or. ft_switch == 'fftw' ) then
     call unset_fft
  else
     call unset_dft
  end if

  call dealo_mod_mpi

  call Base__deallocate3

  call MPI__unsetMatDesc( descCC )
  call MPI__unsetMatDesc( descLL )
  call MPI__unsetMatDesc( descRR )
  call MPI__unsetMatDesc( descCL )
  call MPI__unsetMatDesc( descCR )

  return
end subroutine scf_main_negf_ac

subroutine scf_main_unset_negf

  use scf_negf

  implicit none

  call unset_scf_ham
  call unset_scf_accel_parameter1

  return
end subroutine scf_main_unset_negf
