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

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 mod_mpi

  implicit none
  include 'mpif.h'
  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), allocatable :: dens_temp1(:,:,:,:)
  real(8), allocatable :: dens_temp2(:,:,:,:)

  real(8) :: qx_scf,qy_scf,qq_con

  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(m_mat_max_c)
  call alo_ham_temp_ham(m_mat_max_c,mat_max_ll,mat_max_rr)

  if( ft_switch == 'f_2_ft' .or. ft_switch == 'fft' ) 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

  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

     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(m_mat_max_c)

     !                                +++++++++++++++++++++++++++++++++++++++++++++++++++

     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(qx_scf,qy_scf)
        call set_ham_temp_ham_r(qx_scf,qy_scf)
        call set_ham_scf_ham_c(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(ispin,kt)
           else
              call cal_gf_se_read_scf(ispin,kt)
           end if
        end do

        allocate(dens_temp1(4,ic_spin,m_mat_max_c,m_mat_max_c)                   &
             ,dens_temp2(4,ic_spin,m_mat_max_c,m_mat_max_c),stat=ier)
        if( ier /= 0 ) then
           write(6,*) 'error allocate: alo_density_temp'
           stop
        end if
        do i3_do=1,m_mat_max_c
           do i2_do=1,m_mat_max_c
              do i1_do=1,ic_spin
                 dens_temp1(1,i1_do,i2_do,i3_do)=dens(i1_do,i2_do,i3_do)
                 dens_temp1(2,i1_do,i2_do,i3_do)=dens2(i1_do,i2_do,i3_do)
                 dens_temp1(3,i1_do,i2_do,i3_do)=edens(i1_do,i2_do,i3_do)
                 dens_temp1(4,i1_do,i2_do,i3_do)=edens2(i1_do,i2_do,i3_do)
                 dens_temp2(1,i1_do,i2_do,i3_do)=0.d0
                 dens_temp2(2,i1_do,i2_do,i3_do)=0.d0
                 dens_temp2(3,i1_do,i2_do,i3_do)=0.d0
                 dens_temp2(4,i1_do,i2_do,i3_do)=0.d0
              end do
           end do
        end do
        i_temp=4*ic_spin*m_mat_max_c*m_mat_max_c
        call MPI_ALLREDUCE(dens_temp1,dens_temp2,i_temp,MPI_DOUBLE_PRECISION     &
             ,MPI_SUM,mpi_comm_world,ierr)
        do i3_do=1,m_mat_max_c
           do i2_do=1,m_mat_max_c
              do i1_do=1,ic_spin
                 dens(i1_do,i2_do,i3_do)=dens_temp2(1,i1_do,i2_do,i3_do)
                 dens2(i1_do,i2_do,i3_do)=dens_temp2(2,i1_do,i2_do,i3_do)
                 edens(i1_do,i2_do,i3_do)=dens_temp2(3,i1_do,i2_do,i3_do)
                 edens2(i1_do,i2_do,i3_do)=dens_temp2(4,i1_do,i2_do,i3_do)
              end do
           end do
        end do
        deallocate(dens_temp1,dens_temp2,stat=ier)
        if( ier /= 0 ) then
           write(6,*) 'error deallocate: alo_density_temp'
           stop
        end if

        call Hamiltonian__calcD__as2ac(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

  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'  ) then
     call unset_fft
  else
     call unset_dft
  end if

  call dealo_mod_mpi

  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
