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

  implicit none
  integer :: num_atom,num_atom_kind,num_unit(3)
  integer :: neighbor_x_max,neighbor_y_max,neighbor_z_max
  integer :: kx_max,ky_max
  integer :: kz_max,iteration_max
  real(8) :: unit_block(3,3),eps
  real(8) :: cp,v_lr
  character(50) :: p_or_f,sgf_method,ham_model
  integer, pointer :: atom_orbital(:),atom_num(:),atom_electron(:)
  integer, pointer :: atom_kindn(:),pair_num(:,:)
  real(8), pointer :: ra(:,:),atom_mass(:)
  character(4), pointer :: atom_kind(:),atom_sign(:)

  integer, pointer :: omega_par(:),omega_par_num(:)
  complex(8), pointer :: omega(:)
  integer :: num_gra_te,iw_max

  real(8), pointer :: dos(:,:,:)

  integer :: mat_max_eigen
  real(8), pointer :: ev_mat(:,:,:,:,:,:)

  integer :: l_or_r
  character(50) :: calc_type_c
  character(50) :: dos_on_off
  character(50) :: eigen_s_as

  integer :: num_h00(2),num_h01(2),num_h10(2),num_s00,num_s01,num_s10
  real(8) :: ele_num_temp
  complex(8), pointer :: h00(:,:),h01(:,:),h10(:,:)
  complex(8), pointer :: s00(:),s01(:),s10(:)
  integer, pointer :: l1_h00(:,:),l1_h01(:,:),l1_h10(:,:)
  integer, pointer :: l1_s00(:),l1_s01(:),l1_s10(:)
  integer, pointer :: l2_h00(:,:),l2_h01(:,:),l2_h10(:,:)
  integer, pointer :: l2_s00(:),l2_s01(:),l2_s10(:)

  integer :: spin_switch_temp

  integer :: lr_switch

contains

  subroutine alo_condition(num_atom_kind,num_atom)

    implicit none
    integer, intent(in) :: num_atom_kind,num_atom
    integer :: ier

    allocate(atom_sign(num_atom_kind),atom_num(num_atom_kind)                    &
         ,atom_mass(num_atom_kind),atom_electron(num_atom_kind)               &
         ,atom_orbital(num_atom_kind),ra(num_atom,3)                          &
         ,atom_kind(num_atom),atom_kindn(num_atom),stat=ier)
    if( ier /= 0 ) then
       write(6,*) 'error allocate: alo_condition 1'
       stop
    end if

    if( ham_model == 'gsp' ) then
       allocate(pair_num(num_atom,num_atom),stat=ier)
       if( ier /= 0 ) then
          write(6,*) 'error allocate: alo_condition 2'
          stop
       end if
    end if

    return
  end subroutine alo_condition

  subroutine unset_condition

    implicit none
    integer :: ier

    deallocate(atom_sign,atom_num,atom_mass,atom_electron                        &
         ,atom_orbital,ra,atom_kind,atom_kindn,stat=ier)
    if( ier /= 0 ) then
       write(6,*) 'error deallocate: unset_condition 1'
       stop
    end if

    if( ham_model == 'gsp' ) then
       deallocate(pair_num,stat=ier)
       if( ier /= 0 ) then
          write(6,*) 'error allocate: unset_condition 2'
          stop
       end if
    end if

    return
  end subroutine unset_condition

  subroutine alo_condition_omega(i_w_num,om_block_num)

    implicit none
    integer,intent(in) :: i_w_num,om_block_num
    integer :: ier

    iw_max=i_w_num

    allocate(omega_par(om_block_num),omega_par_num(om_block_num),omega(iw_max)   &
         ,stat=ier)
    if( ier /= 0 ) then
       write(6,*) 'error allocate: alo_condition_omega'
       stop
    end if

    return
  end subroutine alo_condition_omega

  subroutine unset_condition_omega

    implicit none
    integer :: ier

    deallocate(omega_par,omega,omega_par_num,stat=ier)
    if( ier /= 0 ) then
       write(6,*) 'error deallocate: unset_condition_omega'
       stop
    end if

    return
  end subroutine unset_condition_omega

  subroutine alo_condition_dos(kt_num)

    implicit none
    integer, intent(in) :: kt_num
    integer :: ier

    allocate(dos(omega_par_num(num_gra_te),spin_switch_temp,kt_num)              &
         ,ev_mat(mat_max_eigen,kz_max,ky_max,kx_max,spin_switch_temp,kt_num)  &
         ,stat=ier)
    if( ier /= 0 ) then
       write(6,*) 'error allocate: alo_condition_dos'
       stop
    end if

    dos=0.d0
    ev_mat=0.d0

    return
  end subroutine alo_condition_dos

  subroutine unset_condition_dos

    implicit none
    integer :: ier

    deallocate(dos,ev_mat,stat=ier)
    if( ier /= 0 ) then
       write(6,*) 'error deallocate: unset_condition_dos'
       stop
    end if

    return
  end subroutine unset_condition_dos

  subroutine alo_condition_hami_temp

    implicit none
    integer :: ier,num_h00_temp,num_h01_temp,num_h10_temp

    num_h00_temp=num_h00(1)
    if( num_h00_temp < num_h00(2) ) then
       num_h00_temp=num_h00(2)
    end if
    num_h01_temp=num_h01(1)
    if( num_h01_temp < num_h01(2) ) then
       num_h01_temp=num_h01(2)
    end if
    num_h10_temp=num_h10(1)
    if( num_h10_temp < num_h10(2) ) then
       num_h10_temp=num_h10(2)
    end if

    allocate(h00(spin_switch_temp,num_h00_temp+1)                                &
         ,h01(spin_switch_temp,num_h01_temp+1)                                &
         ,h10(spin_switch_temp,num_h10_temp+1)                                &
         ,s00(num_s00+1),s01(num_s01+1),s10(num_s10+1)                        &
         ,l1_h00(spin_switch_temp,num_h00_temp+1)                             &
         ,l1_h01(spin_switch_temp,num_h01_temp+1)                             &
         ,l1_h10(spin_switch_temp,num_h10_temp+1)                             &
         ,l1_s00(num_s00+1),l1_s01(num_s01+1),l1_s10(num_s10+1)               &
         ,l2_h00(spin_switch_temp,num_h00_temp+1)                             &
         ,l2_h01(spin_switch_temp,num_h01_temp+1)                             &
         ,l2_h10(spin_switch_temp,num_h10_temp+1)                             &
         ,l2_s00(num_s00+1),l2_s01(num_s01+1),l2_s10(num_s10+1)               &
         ,stat=ier)
    if( ier /= 0 ) then
       write(6,*) 'error allocate: alo_condition_hami_temp'
       stop
    end if

    return
  end subroutine alo_condition_hami_temp

  subroutine unset_condition_hami_temp

    implicit none
    integer :: ier

    deallocate(h00,h01,h10,s00,s01,s10                                           &
         ,l1_h00,l1_h01,l1_h10,l1_s00,l1_s01,l1_s10                         &
         ,l2_h00,l2_h01,l2_h10,l2_s00,l2_s01,l2_s10,stat=ier)
    if( ier /= 0 ) then
       write(6,*) 'error deallocate: unset_condition_hami_temp'
       stop
    end if

    return
  end subroutine unset_condition_hami_temp
end module condition
