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

subroutine Param__Cell__setup(move)
  use ac_misc_module
  use ac_mpi_module
  implicit none

  integer, intent(in) :: move

  real(8) :: Kcutoff

  integer :: i, j
  real(8) :: L(3)
  real(8) :: Rg(3)
  real(8) :: a, b, c
  real(8) :: Rcmax
  integer :: Namax, Nbmax, Ncmax, Nmax
  integer :: na, nb, nc

  logical :: allinside, anyintersected

  Param%Cell%V   = dot_product( Param%Cell%La, Position__oprod( Param%Cell%Lb , Param%Cell%Lc ) )
  Param%Cell%dKa = Position__oprod( Param%Cell%Lb, Param%Cell%Lc) * (2.d0*M_PI/Param%Cell%V)
  Param%Cell%dKb = Position__oprod( Param%Cell%Lc, Param%Cell%La) * (2.d0*M_PI/Param%Cell%V)
  Param%Cell%dKc = Position__oprod( Param%Cell%La, Param%Cell%Lb) * (2.d0*M_PI/Param%Cell%V)

  if( Param%Cell%V < 0.d0 ) then
     Param%Cell%V = -Param%Cell%V
  end if

  Param%Cell%dKa1 = sqrt(dot_product(Param%Cell%dKa,Param%Cell%dKa))
  Param%Cell%dKb1 = sqrt(dot_product(Param%Cell%dKb,Param%Cell%dKb))
  Param%Cell%dKc1 = sqrt(dot_product(Param%Cell%dKc,Param%Cell%dKc))

  Kcutoff = sqrt(2.d0*Param%SCF%Ecutoff)

  call Param__Cell__findAppNumber(Param%Cell%Na,int(ceiling(2.d0*Kcutoff/Param%Cell%dKa1)))
  call Param__Cell__findAppNumber(Param%Cell%Nb,int(ceiling(2.d0*Kcutoff/Param%Cell%dKb1)))
  call Param__Cell__findAppNumber(Param%Cell%Nc,int(ceiling(2.d0*Kcutoff/Param%Cell%dKc1)))

  Param%Cell%dLa = Param%Cell%La*(1.d0/dble(Param%Cell%Na))
  Param%Cell%dLb = Param%Cell%Lb*(1.d0/dble(Param%Cell%Nb))
  Param%Cell%dLc = Param%Cell%Lc*(1.d0/dble(Param%Cell%Nc))

  Param%Cell%dV  = Param%Cell%V    &
       *(1.d0/dble(Param%Cell%Na)) &
       *(1.d0/dble(Param%Cell%Nb)) &
       *(1.d0/dble(Param%Cell%Nc))

  if( Param%Option%mx ) then
     Rg = 0.d0
     do i=1, Param%Data%natom
        Rg = Rg + Param%Data%vatom(i)%Ro
     end do
     Rg = Rg*(1.d0/Param%Data%natom)

     Param%Cell%Lo = Rg                           &
          - ( Param%Cell%La-Param%Cell%dLa        &
          + Param%Cell%Lb-Param%Cell%dLb          &
          + Param%Cell%Lc-Param%Cell%dLc )*0.5d0
  else
     Param%Cell%Lo = ( Param%Cell%dLa + Param%Cell%dLb + Param%Cell%dLc ) * 0.5d0
  end if

  if( Param%Data%natom == 0 ) then
     open(unit=16,file=Param%Option%file_ac_tempout,position='append')
     write(16,'(a)') '      ++++++ Error!: no atoms are located.'
     close(16)
     stop
  end if

  if( move == 0 ) then
     allinside=.true.
     if( Param%Option%cluster ) then
        do i=1, Param%Data%natom
           if( .not. Param__Cell__inside( &
                Param%Data%vatom(i)%Ro, Param%Data%vatom(i)%Rc ) ) then
              allinside=.false.
              exit
           end if
        end do

        if( .not. allinside ) then
           open(unit=16,file=Param%Option%file_ac_tempout,position='append')
           write(16,'(a,a)') '      ++++++ Error!: not all atoms are located inside the central unit cell.'
           close(16)
           stop
        end if

     else
        do i=1, Param%Data%natom
           L = Param%Data%vatom(i)%Ro

           a = 0.5d0*M_1_PI*( sum(Param%Cell%dKa(:)*L(:)) )
           b = 0.5d0*M_1_PI*( sum(Param%Cell%dKb(:)*L(:)) )
           c = 0.5d0*M_1_PI*( sum(Param%Cell%dKc(:)*L(:)) )

           if( a < 0.d0 .or. a >= 1.d0 ) then
              Param%Data%vatom(i)%Ro = &
                   Param%Data%vatom(i)%Ro - Param%Cell%La*dble(floor(a))
              allinside=.false.
           end if

           if( b < 0.d0 .or. b >= 1.d0 ) then
              Param%Data%vatom(i)%Ro = &
                   Param%Data%vatom(i)%Ro - Param%Cell%Lb*dble(floor(b))
              allinside=.false.
           end if
           if( c < 0.d0 .or. c >= 1.d0 ) then
              Param%Data%vatom(i)%Ro = &
                   Param%Data%vatom(i)%Ro - Param%Cell%Lc*dble(floor(c))
              allinside=.false.
           end if
        end do

        if( .not. allinside ) then
           Param%Option%atom_move = .true. 
        end if
     end if
  end if

  if( Param%Option%cluster ) then
     Param%Cell%nL    = 1

     allocate( Param%Cell%vL(3,0:0) )
     Param%Cell%vL(:,0) = 0.d0

     allocate( Param%Cell%vLna(0:0) )
     Param%Cell%vLna(0) = 0
     allocate( Param%Cell%vLnb(0:0) )
     Param%Cell%vLnb(0) = 0
     allocate( Param%Cell%vLnc(0:0) )
     Param%Cell%vLnc(0) = 0

     return
  end if

  Rcmax=0.d0
  do i=1, Param%Data%natom
     if( Rcmax < Param%Data%vatom(i)%Rc ) Rcmax = Param%Data%vatom(i)%Rc
  end do

  Namax = int(2.d0*Rcmax/sqrt(dot_product(Param%Cell%La,Param%Cell%La)))+1
  Nbmax = int(2.d0*Rcmax/sqrt(dot_product(Param%Cell%Lb,Param%Cell%Lb)))+1
  Ncmax = int(2.d0*Rcmax/sqrt(dot_product(Param%Cell%Lc,Param%Cell%Lc)))+1
  Nmax  = (2*Namax+1)*(2*Nbmax+1)*(2*Ncmax+1)

  allocate( Param%Cell%vL(3,1-Nmax:Nmax-1) )
  allocate( Param%Cell%vLna(1-Nmax:Nmax-1) )
  allocate( Param%Cell%vLnb(1-Nmax:Nmax-1) )
  allocate( Param%Cell%vLnc(1-Nmax:Nmax-1) )

  Param%Cell%nL=0
  do nc=0, +Ncmax
     do nb=-Nbmax, +Nbmax
        if( nc==0 .and. nb<0 ) cycle
        do na=-Namax, +Namax
           if( nc==0 .and. nb==0 .and. na<0 ) cycle

           call Param__Cell__L(L,na,nb,nc)
           anyintersected = .false.

           if( Param%Option%indirect_overlap ) then
              anyintersected = .true.
           end if

           paoloop: do i=1, Param%Data%natom
              do j=1, Param%Data%natom
                 if( Param__Cell__intersect( &
                      Param%Data%vatom(i)%Ro, Param%Data%vatom(i)%Rc,&
                      Param%Data%vatom(j)%Ro+L, Param%Data%vatom(j)%Rc ) ) then
                    anyintersected = .true.
                    exit paoloop
                 end if

              end do
           end do paoloop

           if( anyintersected ) then
              Param%Cell%vL  (:,Param%Cell%nL) = L(:)
              Param%Cell%vLna(Param%Cell%nL) = na*Param%Cell%Na
              Param%Cell%vLnb(Param%Cell%nL) = nb*Param%Cell%Nb
              Param%Cell%vLnc(Param%Cell%nL) = nc*Param%Cell%Nc

              Param%Cell%vL  (:,-Param%Cell%nL) = (-1.d0)*L(:)
              Param%Cell%vLna(-Param%Cell%nL) = (-1)*na*Param%Cell%Na
              Param%Cell%vLnb(-Param%Cell%nL) = (-1)*nb*Param%Cell%Nb
              Param%Cell%vLnc(-Param%Cell%nL) = (-1)*nc*Param%Cell%Nc

              Param%Cell%nL = Param%Cell%nL + 1 
           end if
        end do
     end do
  end do

  return
end subroutine Param__Cell__setup

subroutine Param__SCF__setup
  use ac_misc_module
  implicit none

  integer        :: ika, ikb, ikc
  real(8) :: vK(3)
  integer        :: l, k
  real(8) :: temp

  allocate(Param%SCF%vK(3,Param%SCF%Nka*Param%SCF%Nkb*Param%SCF%Nkc) )

  allocate(Param%SCF%i_vK(Param%SCF%Nka*Param%SCF%Nkb*Param%SCF%Nkc) )

  Param%SCF%nK=0
  do ika=1, Param%SCF%Nka
     do ikb=1, Param%SCF%Nkb
        do ikc=1, Param%SCF%Nkc
           vK = Param%Cell%dKa*( 0.5d0*dble(2*ika-1)/Param%SCF%Nka - 0.5d0 ) &
                + Param%Cell%dKb*( 0.5d0*dble(2*ikb-1)/Param%SCF%Nkb - 0.5d0 ) &
                + Param%Cell%dKc*( 0.5d0*dble(2*ikc-1)/Param%SCF%Nkc - 0.5d0 )

           Param%SCF%nK = Param%SCF%nK + 1 
           Param%SCF%vK(:,Param%SCF%nK) = vK(:)
        end do
     end do
  end do

  if( .not. Param%Option%spin_orbit ) then
     do k=1, Param%SCF%nK
        Param%SCF%i_vK(k)=-100
     end do
     do k=1, Param%SCF%nK
        if( Param%SCF%i_vK(k) /= -100 ) then
           cycle
        end if
        Param%SCF%i_vK(k)=-1
        vK=Param%SCF%vK(:,k)
        temp=sqrt(dot_product(vK,vK))
        if( temp < 1.d-14 ) then
           cycle
        end if
        do l=k+1, Param%SCF%nK
           vK=Param%SCF%vK(:,k)+Param%SCF%vK(:,l)
           temp=sqrt(dot_product(vK,vK))
           if( temp < 1.d-14 ) then
              Param%SCF%i_vK(k)=-2
              Param%SCF%i_vK(l)=k
              exit
           end if
        end do
     end do
  else
     do k=1, Param%SCF%nK
        Param%SCF%i_vK(k)=-1
     end do
  end if

  allocate( Param%SCF%vbloch(Param%SCF%nK,0:Param%Cell%nL-1) )
  do l=0, Param%Cell%nL-1
     do k=1, Param%SCF%nK
        Param%SCF%vbloch(k,l) = polar( (-1.0d0) * dot_product(Param%SCF%vK(:,k),Param%Cell%vL(:,l)) )
     end do
  end do

  return
end subroutine Param__SCF__setup

subroutine Param__Band__setup
  use ac_misc_module
  implicit none

  integer :: i, j, k
  real(8) :: V
  real(8) :: f

  if( Param%Band%fname == "" ) then
     allocate( Param%Band%vK(3,1:1) )
     Param%Band%vK(:,1) = 0.d0
     Param%Band%nK    = 1
     return
  end if

  if( dot_product( Param%Band%La,Param%Band%La ) == 0.0d0 ) then
     V = Param%Cell%V
     Param%Band%dKa = Param%Cell%dKa
     Param%Band%dKb = Param%Cell%dKb
     Param%Band%dKc = Param%Cell%dKc
  else
     V = dot_product( Param%Band%La, Position__oprod( Param%Band%Lb, Param%Band%Lc) )
     Param%Band%dKa = Position__oprod( Param%Band%Lb, Param%Band%Lc) * (2*M_PI/V)
     Param%Band%dKb = Position__oprod( Param%Band%Lc, Param%Band%La) * (2*M_PI/V)
     Param%Band%dKc = Position__oprod( Param%Band%La, Param%Band%Lb) * (2*M_PI/V)
  end if

  do i=1, Param%Band%nKpath
     Param%Band%vKpath(i)%ks = &
          Param%Band%dKa*Param%Band%vKpath(i)%ks(1) &
          + Param%Band%dKb*Param%Band%vKpath(i)%ks(2) &
          + Param%Band%dKc*Param%Band%vKpath(i)%ks(3)
     Param%Band%vKpath(i)%ke = &
          Param%Band%dKa*Param%Band%vKpath(i)%ke(1) &
          + Param%Band%dKb*Param%Band%vKpath(i)%ke(2) &
          + Param%Band%dKc*Param%Band%vKpath(i)%ke(3)
  end do

  Param%Band%nK = 0
  do i=1, Param%Band%nKpath
     Param%Band%nK = Param%Band%nK + Param%Band%vKpath(i)%mesh
  end do
  allocate( Param%Band%vK(3,Param%Band%nK) )

  k=0
  do i=1, Param%Band%nKpath
     if( Param%Band%vKpath(i)%mesh == 1 ) then
        k = k + 1
        Param%Band%vK(:,k) = Param%Band%vKpath(i)%ks
        cycle
     end if

     do j=1, Param%Band%vKpath(i)%mesh
        f = dble(j-1)/dble(Param%Band%vKpath(i)%mesh-1)
        k = k + 1
        Param%Band%vK(:,k) = Param%Band%vKpath(i)%ks*(1.d0-f) + Param%Band%vKpath(i)%ke*(f)
     end do
  end do

  return
end subroutine Param__Band__setup

subroutine Param__DOS__setup
  use ac_misc_module
  use ac_mpi_module
  implicit none

  if( Param%DOS%fname == "" ) then
     return
  end if

  if( Param%DOS%Nka == 0 .and. Param%DOS%Nkb == 0 .and. Param%DOS%Nkc == 0 ) then
     Param%DOS%Nka = Param%SCF%Nka
     Param%DOS%Nkb = Param%SCF%Nkb
     Param%DOS%Nkc = Param%SCF%Nkc
  end if

  Param%DOS%nK = Param%DOS%Nka * Param%DOS%Nkb * Param%DOS%Nkc
  Param%DOS%dE = (Param%DOS%Emax - Param%DOS%Emin)/(Param%DOS%Ne-1)

  if( MPI%root ) then
     if( Param%DOS%method == "tetrahedron" .and. Param%DOS%nK == 1 ) then
        open(unit=16,file=Param%Option%file_ac_tempout,position='append')
        write(16,'(a)') '      ++++++ Error!: Insufficient Dos.Kgrid for method tetrahedron.'
        close(16)
        stop
     end if
  end if

  return
end subroutine Param__DOS__setup

subroutine Param__MO__setup
  use ac_misc_module
  implicit none

  integer :: i
  real(8) :: V

  if( Param%MO%fbase == "" ) then
     return
  end if

  if( dot_product(Param%MO%La,Param%MO%La) == 0.0d0 ) then
     V = Param%Cell%V
     Param%MO%dKa = Param%Cell%dKa
     Param%MO%dKb = Param%Cell%dKb
     Param%MO%dKc = Param%Cell%dKc
  else
     V = dot_product( Param%MO%La, Position__oprod( Param%MO%Lb, Param%MO%Lc) )
     Param%MO%dKa = Position__oprod( Param%MO%Lb, Param%MO%Lc) * (2*M_PI/V)
     Param%MO%dKb = Position__oprod( Param%MO%Lc, Param%MO%La) * (2*M_PI/V)
     Param%MO%dKc = Position__oprod( Param%MO%La, Param%MO%Lb) * (2*M_PI/V)
  end if

  if( Param%MO%band_min == 0 .and. Param%MO%band_max == 0 ) then
     if( Param%MO%method == "band_num" ) then
        Param%MO%band_min = 1
        Param%MO%band_max = 5
     else if( Param%MO%method == "ho_lumo" ) then
        Param%MO%band_min = -5
        Param%MO%band_max = +5
     end if
  end if

  do i=1, Param%MO%nK
     Param%MO%vK(:,i) = Param%MO%dKa * Param%MO%vK(1,i) + Param%MO%dKb * Param%MO%vK(2,i) + Param%MO%dKc * Param%MO%vK(3,i)
  end do

  return
end subroutine Param__MO__setup

subroutine Param__Cell__getRange( range, Ro, Rc )
  use ac_misc_module
  implicit none

  integer, intent(out)       :: range(6)
  real(8), intent(in) :: Ro(3)
  real(8), intent(in)        :: Rc

  real(8) :: L(3)

  L = Ro - Param%Cell%Lo

  range(1) = int(floor  (0.5d0*M_1_PI*( sum(Param%Cell%dKa(:)*L(:)) - Param%Cell%dKa1*Rc )*Param%Cell%Na))+1
  range(2) = int(ceiling(0.5d0*M_1_PI*( sum(Param%Cell%dKa(:)*L(:)) + Param%Cell%dKa1*Rc )*Param%Cell%Na))+1
  range(3) = int(floor  (0.5d0*M_1_PI*( sum(Param%Cell%dKb(:)*L(:)) - Param%Cell%dKb1*Rc )*Param%Cell%Nb))+1
  range(4) = int(ceiling(0.5d0*M_1_PI*( sum(Param%Cell%dKb(:)*L(:)) + Param%Cell%dKb1*Rc )*Param%Cell%Nb))+1
  range(5) = int(floor  (0.5d0*M_1_PI*( sum(Param%Cell%dKc(:)*L(:)) - Param%Cell%dKc1*Rc )*Param%Cell%Nc))+1
  range(6) = int(ceiling(0.5d0*M_1_PI*( sum(Param%Cell%dKc(:)*L(:)) + Param%Cell%dKc1*Rc )*Param%Cell%Nc))+1

  return
end subroutine Param__Cell__getRange

subroutine Param__Data__setup
  use ac_misc_module
  implicit none

  integer :: i, a, n, npao, nvps
  type(Element_type), pointer :: elem


  call SphericalBessel__setup( Param%Integral1D%Nr, Param%Integral1D%Nk, Param%Integral1D%Ecutoff )

  do i=1, Param%Data%nelem
     call Element__setup( Param%Data%velem(i) )
  end do

  Param%Data%Ne = 0.d0
  do a=1, Param%Data%natom
     Param%Data%Ne = Param%Data%Ne + Param%Data%vatom(a)%Q
  end do
  if( Param%Data%Ne_extra /= 0.0d0 ) then
     Param%Data%Ne = Param%Data%Ne + Param%Data%Ne_extra
  end if

  if( .not. Param%Option%spin_polar ) then
     Param%Data%g = 2.d0
  else
     Param%Data%g = 1.d0
  end if

  if( Param%Data%Ne == 1.d0 ) Param%Data%g = 1.d0

  Param%Data%npao=0
  Param%Data%nvps=0
  allocate( Param%Data%vnpao(Param%Data%natom) )
  allocate( Param%Data%vipao(Param%Data%natom) )
  do a=1, Param%Data%natom
     elem => Param__Data__getElement( Param%Data%vatom(a)%name )

     npao = Element__getNumberOfPAO(elem)
     nvps = Element__getNumberOfVPS(elem)

     Param%Data%vipao(a) = Param%Data%npao + 1
     Param%Data%vnpao(a) = npao
     Param%Data%npao = Param%Data%npao + npao
     Param%Data%nvps = Param%Data%nvps + nvps
  end do

  return
end subroutine Param__Data__setup

subroutine Param__Option__show
  use ac_misc_module
  implicit none

  integer :: i

  write(16,*)
  write(16,*) '========================= file  name ========================='
  write(16,*)


  do i=1, Param%Data%nelem
     write(16,904) trim(Param%Data%velem_file(i,1))                           &
          ,trim(Param%Data%velem_file(i,2))
904  format(' /input/ file name -     PAO  ',a2,': ',a)
     write(16,905) trim(Param%Data%velem_file(i,1))                           &
          ,trim(Param%Data%velem_file(i,4))
905  format(' /input/ file name -     VPS  ',a2,': ',a)
  end do

  write(16,*)

  if( Param%Option%fname_rhoscf_in /= "" ) then
     write(16,900) trim(Param%Option%fname_rhoscf_in)
900  format(' /input/ file name -     density: ',a)
  end if

  if( Param%Option%fname_matrices_in /= "" ) then
     write(16,903) trim(Param%Option%fname_matrices_in)
903  format(' /input/ file name - hamiltonian: ',a)
  end if

  write(16,*)

  write(16,920) trim(Param%Option%fname_rhoscf)
920 format('/output/ file name -     density: ',a)
  write(16,923) trim(Param%Option%fname_rhoval)
923 format('/output/ file name -       Diso : ',a)
  write(16,924) trim(Param%Option%fname_rhopcc)
924 format('/output/ file name -       Dpcc : ',a)

  write(16,*)

  write(16,930) trim(Param%Option%fname_vtot)
930 format('/output/ file name -       Vtot : ',a)

  write(16,926) trim(Param%Option%fname_vhar)
926 format('/output/ file name -         Vh : ',a)

  write(16,927) trim(Param%Option%fname_vexc)
927 format('/output/ file name -        Vxc : ',a)

  write(16,925) trim(Param%Option%fname_vext)
925 format('/output/ file name -       Vext : ',a)

  write(16,*)

  write(16,933) trim(Param%Option%fname_matrices)
933 format('/output/ file name - hamiltonian: ',a)

  write(16,*)

  if( Param%Band%fname /= "" ) then
     if( .not. Param%Option%spin_polar ) then
        write(16,940) trim(Param%Band%fname)
940     format('/output/ file name -       BAND : ',a)
     else
        write(16,943) trim(Param%Band%fname),trim(Param%Band%fname1)
943     format('/output/ file name -       BAND : ',a,' & ',a)
     end if
  end if
  if( Param%DOS%fname /= "" ) then
     write(16,941) trim(Param%DOS%fname)
941  format('/output/ file name -        DOS : ',a)
  end if
  if( Param%MO%fbase /= "" ) then
     write(16,942) trim(Param%MO%fbase)
942  format('/output/ file name -         MO : ',a)
  end if

  write(16,*)
  write(16,*) '--------------------- file name for NEGF ---------------------'
  write(16,*)

  write(16,953) trim(Param%Option%fname_ascot_vd)
953 format('  /output/ file name -        vd: ',a)
  write(16,954) trim(Param%Option%fname_ascot_in)
954 format('  /output/ file name - condition: ',a)
  write(16,950) trim(Param%Option%fname_accel_c)
950 format('  /output/ file name -    junc_h: ',a)

  return
end subroutine Param__Option__show

subroutine Param__SCF__show
  use ac_misc_module
  use ac_mpi_module
  implicit none
  character(10) :: chara_temp

  write(16,*)

  write(16,921) Param%SCF%exc_type
921 format('                        Vxc type: ',a)

  if( Param%Option%projection ) then
     chara_temp='on'
  else
     chara_temp='off'
  end if
  write(16,951) chara_temp
951 format('                 Vloc projection: ',a)

  write(16,922) Param%SCF%Te*AU_TO_KELVIN
922 format('         electric temperature[K]: ',f10.4)
  write(16,923) Param%SCF%Ecutoff
923 format('  real space energy cutoff[a.u.]: ',f10.4)

  write(16,925) Param%SCF%Nka, Param%SCF%Nkb, Param%SCF%Nkc
925 format('                        K points: (',i3,',',i3,',',i3,')')

  write(16,*)
  if( Param%Option%spin_polar ) then
     chara_temp='on'
  else
     chara_temp='off'
  end if
  write(16,924) chara_temp
924 format('               spin polarization: ',a)
  if( Param%Option%spin_orbit ) then
     chara_temp='on'
  else
     chara_temp='off'
  end if
  write(16,950) chara_temp
950 format('             spin orbit coupling: ',a)

  if( Param%Option%cluster ) then
     chara_temp='on'
  else
     chara_temp='off'
  end if
  write(16,928) chara_temp
928 format('                         cluster: ',a)

  write(16,*) 
  write(16,912) Param%SCF%cri_type
912 format('                        scf diff: ',a)
  write(16,913) Param%SCF%criterion
913 format('          scf convergence [a.u.]: ',e10.5)
  write(16,914) Param%SCF%iter_max
914 format('         max number of iteration: ' ,i10)

  write(16,915) Param%SCF%mix_type
915 format('                   mixing method: ',a10)
  write(16,935) Param%SCF%mix_target
935 format('                          target: ',a)
  if( Param%SCF%mix_type == "Pulay" ) then
     write(16,917) Param%SCF%mix_history
917  format('            Pulay-  mixing steps: ',i10)
     write(16,926) Param%SCF%mix_start
926  format('            Pulay- starting step: ',i10)
  end if
  if( Param%SCF%mix_type /= "Simple" ) then
     write(16,916) Param%SCF%mix_weight
916  format('                   mixing weight: ',f10.4)
  end if
  if( Param%SCF%mix_type /= "Anderson" ) then
     write(16,958) Param%SCF%mix_weight_s
958  format('          mixing weight (simple): ',f10.4)
  end if

  write(16,*)
  write(16,927) trim(Param%Option%saveat)
927 format('                        output at: ',a)

  write(16,*)
  write(16,*) '===========            force calculation            =========='
  write(16,*)
  if( Param%Option%optimize ) then
     if( Param%SCF%opt_iter_max > 0 ) then
        chara_temp='optimize'
        write(16,942) chara_temp
        write(16,945) Param%Option%optimize_method
        write(16,943) Param%SCF%force_criterion
        write(16,944) Param%SCF%opt_iter_max
     else
        chara_temp='on'
        write(16,942) chara_temp
     end if
  else
     chara_temp='off'
     write(16,942) chara_temp
  end if
942 format('               force calculation: ',a)
943 format('    opt force convergence [a.u.]: ',e10.5)
944 format('   max_num of optimization iter.: ' ,i10)
945 format('                          method: ',a)


  write(16,*)
  write(16,*) '=========== one-dimensional integration calculation =========='
  write(16,*)
  write(16,918) Param%Integral1D%Nr
918 format('          real space grid points: ',i10)
  write(16,919) Param%Integral1D%Nk
919 format('          reciprocal grid points: ',i10)
  write(16,920) Param%Integral1D%Ecutoff
920 format('             energy cutoff [a.u]: ',e10.5)


  if( MPI%num_sc_work2space >= -1.d0 ) then
     write(16,*)
     write(16,*) '===========              for ScaLapack              =========='
     write(16,*)
     write(16,953) MPI%num_sc_work2space
953  format('               num_sc_work2space: ',f10.2)
     write(16,952) MPI%num_check_sc
952  format('                    num_check_sc: ',i10)
  end if

  return
end subroutine Param__SCF__show

subroutine Param__Band__show
  use ac_misc_module
  implicit none

  type(Element_type), pointer :: elem
  integer :: i,a,n

  if( Param%Band%fname == "" ) return

  i=0

  write(16,*)
  write(16,*) '====================== Band calculation ======================'
  write(16,*)
  write(16,910) Param%Band%num_band
910 format('                show band number: ',i10)

  if( Param%Band%num_band == 0 ) then
     Param%Data%Ne=0.d0
     do a=1, Param%Data%natom
        Param%Data%Ne = Param%Data%Ne + Param%Data%vatom(a)%Q
     end do
     Param%Band%num_band=Param%Data%Ne
     if( Param%Option%spin_orbit ) then
        Param%Band%num_band=Param%Band%num_band+5
     else
        !!            Param%Band%num_band=Param%Data%Ne/2+imod(Param%Band%num_band,2)+5
        Param%Band%num_band=Param%Data%Ne/2+mod(Param%Band%num_band,2)+5
     end if
     i=1
  end if

  Base%npao=0
  do a=1, Param%Data%natom
     elem => Param__Data__getElement( Param%Data%vatom(a)%name )
     do n=1, elem%npao
        Base%npao = Base%npao + 2*(elem%vpao(n)%l) + 1
     end do
  end do
  if( Param%Band%num_band > Base%npao ) then
     Param%Band%num_band=Base%npao
     i=1
  end if

  if( i == 1 )then
     write(16,912) Param%Band%num_band
912  format('                               => ',i10,' !! (def)')
  end if

  write(16,911) Param%Band%nK
911 format('                  total K points: ',i10)

  return
end subroutine Param__Band__show

subroutine Param__DOS__show
  use ac_misc_module
  implicit none

  if( Param%DOS%fname == "" ) return

  write(16,*)
  write(16,*) '================ Density of states calculation ==============='
  write(16,*)
  write(16,912) Param%DOS%method
912 format('                          method: ',a)
  write(16,925) Param%DOS%Nka, Param%DOS%Nkb, Param%DOS%Nkc
925 format('                        K points: (',i3,',',i3,',',i3,')')

  write(16,*)
  write(16,911) Param%DOS%Emin*AU_TO_EV, Param%DOS%Emax*AU_TO_EV
911 format('                energy range[eV]: ',e12.5,' -> ',e12.5)
  write(16,910) Param%DOS%Ne
910 format('                     energy grid: ',i10)
  if( Param%DOS%method == 'gaussian' ) then
     write(16,914) Param%DOS%GB*AU_TO_EV
914  format('         gaussian broadening[eV]: ',e12.5)
  end if

  return
end subroutine Param__DOS__show

subroutine Param__MO__show
  use ac_misc_module
  implicit none

  if( Param%MO%fbase == "" ) return

  write(16,*)
  write(16,*) '================ Molecular orbital calculation ==============='
  write(16,*)
  write(16,912) Param%MO%method
912 format('        band range specification: ',a)
  write(16,911) Param%MO%band_min, Param%MO%band_max
911 format('               output band range: ',i10,' -> ',i10)
  write(16,913) Param%MO%nK
913 format('                  total K points: ',i10)

  return
end subroutine Param__MO__show

subroutine Param__Data__show
  use ac_misc_module
  implicit none
  integer :: a, n, napao, ll
  character(10) :: chara_temp
  integer, allocatable :: vnpao_temp(:)
  type(Element_type), pointer :: elem

  write(16,*)
  write(16,*)
  write(16,*) '--------------------------------------------------------------'
  write(16,*) '------------   PAO bases and Pseudo-potentials:'
  write(16,*) '--------------------------------------------------------------'
  write(16,950) trim(Param%Data%element_type)
950 format('                    element type: 'a)
  write(16,*)

  do a=1, Param%Data%nelem

     if( Param%Data%velem(a)%pcc ) then
        chara_temp='on'
     else
        chara_temp='off'
     end if

     if((Param%Data%element_type=='ciao_ls') &
          .and.(.not. Param%Option%spin_orbit) &
          .and.(Param%Data%velem(a)%dirac)) then
        ll=1
     else
        ll=0
     end if
     write(16,940) a,Param%Data%velem(a)%name,Param%Data%velem(a)%npao      &
          ,Param%Data%velem(a)%nVnon-ll,chara_temp
940  format('  (',i3,') name: ',a2,' ,PAO:',i2,' ,VPS:',i2,' ,PCC:',a4)

     write(16,941) '       PAO (l,Rc) ='
941  format(a,$)
     do n=1, Param%Data%velem(a)%npao
        write(16,942) ' ('
942     format(a,$)
        write(16,943) Param%Data%velem(a)%vpao(n)%l, Param%Data%velem(a)%vpao(n)%Rc
943     format(i1,1x,f4.2,$)
        write(16,944) ')'
944     format(a,$)
     end do
     write(16,*)

     write(16,945) '     VPS (l,E,Rc) ='
945  format(a,$)
     if( Param%Data%velem(a)%nVnon-ll == 0 ) then
        write(16,946) ' none'
946     format(a,$)
     end if
     do n=1, Param%Data%velem(a)%nVnon
        if((Param%Data%element_type=='ciao_ls') &
             .and.(.not. Param%Option%spin_orbit) &
             .and.(Param%Data%velem(a)%dirac) &
             .and.(Param%Data%velem(a)%vVnon(n,1)%l==Param%Data%velem(a)%Vloc%l)) then
           cycle
        end if
        write(16,947) ' ('
947     format(a,$)
        write(16,948) &
             Param%Data%velem(a)%vVnon(n,1)%l, &
             Param%Data%velem(a)%vVnon(n,1)%Q, &
             Param%Data%velem(a)%vVnon(n,1)%Rc
948     format(i1,1x,e8.2,1x,f4.2,$)
        write(16,949) ')'
949     format(a,$)
     end do
     write(16,*)

  end do

  write(16,*) '--------------------------------------------------------------'
  write(16,*)
  write(16,*) '--------------------------------------------------------------'
  write(16,*) '------------   Unit cell:'
  write(16,*) '--------------------------------------------------------------'

  write(16,*) '   real space unit vectors[a.u.]'
  write(16,923) Param%Cell%La(:)
923 format('                               A: ',f9.4,' ',f9.4,' ',f9.4)
  write(16,924) Param%Cell%Lb(:)
924 format('                               B: ',f9.4,' ',f9.4,' ',f9.4)
  write(16,925) Param%Cell%Lc(:)
925 format('                               C: ',f9.4,' ',f9.4,' ',f9.4)

  write(16,*)
  write(16,921) Param%Cell%V
921 format('          unit cell volume[a.u.]: ',e10.4)
  write(16,*)

  write(16,*) '   reciprocal space unit vectors'
  write(16,926) Param%Cell%dKa(:)
926 format('                             dKa: ',f9.4,' ',f9.4,' ',f9.4)
  write(16,927) Param%Cell%dKb(:)
927 format('                             dKb: ',f9.4,' ',f9.4,' ',f9.4)
  write(16,928) Param%Cell%dKc(:)
928 format('                             dKc: ',f9.4,' ',f9.4,' ',f9.4)

  write(16,*)

  write(16,920) Param%Cell%Na, Param%Cell%Nb, Param%Cell%Nc
920 format('          real space grid points: (',i4,',',i4,',',i4,')')
  write(16,922) Param%Cell%nL
922 format('    total neighboring unit cells: ',i10)

  allocate( vnpao_temp(Param%Data%natom) )

  Param%Data%Ne=0.d0
  do a=1, Param%Data%natom
     Param%Data%Ne = Param%Data%Ne + Param%Data%vatom(a)%Q
  end do
  Base%npao=0
  do a=1, Param%Data%natom
     napao = 0
     elem => Param__Data__getElement( Param%Data%vatom(a)%name )
     do n=1, elem%npao
        napao = napao + 2*(elem%vpao(n)%l) + 1
     end do
     vnpao_temp(a) = napao
     Base%npao = Base%npao + napao
  end do

  write(16,*) '--------------------------------------------------------------'
  write(16,*)
  write(16,*) '--------------------------------------------------------------'
  write(16,*) '------------   Atoms:'
  write(16,*) '--------------------------------------------------------------'
  if( Param%Option%atom_move ) then
     write(16,*) ' !Warning!: some atoms are moved inside the central unit cell.'
     write(16,*)
  end if

  write(16,932) Base%npao
932 format('                 total PAO bases: ',i10)
  write(16,930) Param%Data%natom
930 format('                     total atoms: ',i10)
  write(16,931) Param%Data%Ne
931 format('                 total electrons: ',f10.4)

  write(16,*)

  write(16,*) ' atom   Q         Rc       PAO    Ro'
  do a=1, Param%Data%natom
     if( Param%Data%vatom(a)%optimize .and. Param%SCF%opt_iter_max /= 0 ) then
        chara_temp='free'
     else
        chara_temp='fixed'
     end if
     write(16,933) a,Param%Data%vatom(a)%name, Param%Data%vatom(a)%Q,       &
          Param%Data%vatom(a)%Rc,vnpao_temp(a),                      &
          Param%Data%vatom(a)%Ro(:),        &
          chara_temp
933  format(i4,'  ',a2,f9.4,f9.4,i5,'  ',f9.4,f9.4,f9.4,'  ',a5)
  end do

  write(16,*) '--------------------------------------------------------------'
  write(16,*)

  deallocate( vnpao_temp )

  return
end subroutine Param__Data__show

subroutine Param__deallocate
  use ac_misc_module
  implicit none

  integer :: a

  if( associated(Param%Cell%vL) ) deallocate( Param%Cell%vL )
  if( associated(Param%Cell%vLna) ) deallocate( Param%Cell%vLna )
  if( associated(Param%Cell%vLnb) ) deallocate( Param%Cell%vLnb )
  if( associated(Param%Cell%vLnc) ) deallocate( Param%Cell%vLnc )
  if( associated(Param%SCF%vbloch) )   deallocate( Param%SCF%vbloch )
  if( associated(Param%SCF%vK) )   deallocate( Param%SCF%vK )
  if( associated(Param%SCF%i_vK) )   deallocate( Param%SCF%i_vK )

  if( associated(Param%Band%vKpath) ) deallocate( Param%Band%vKpath )
  if( associated(Param%Band%vK) ) deallocate( Param%Band%vK )

  if( associated(Param%MO%vK) ) deallocate( Param%MO%vK )

  do a=1, Param%Data%nelem
     call Element__deallocate( Param%Data%velem(a) )
  end do
  do a=1, Param%Data%natom
     call Atom__deallocate( Param%Data%vatom(a) )
  end do

  if( associated(Param%Data%velem) ) deallocate( Param%Data%velem )
  if( associated(Param%Data%vatom) ) deallocate( Param%Data%vatom )
  if( associated(Param%Data%vnpao) ) deallocate( Param%Data%vnpao )
  if( associated(Param%Data%vipao) ) deallocate( Param%Data%vipao )

  if( associated(Param%Data%velem_file) ) deallocate( Param%Data%velem_file )

  call SphericalBessel__deallocate

  return
end subroutine Param__deallocate

subroutine Param__read( fname )
  use ac_misc_module
  use ac_mpi_module
  implicit none

  character(len=*) fname

  integer        :: iunit
  logical        :: ex
  character(256) :: buf
  character(32)  :: tag

  integer        :: i, j
  real(8)  :: MOL_TO_AU, CEL_TO_AU
  character(16)  :: name
  character(64)  :: name_pao, mode, name_vps, mode2
  character(256) :: fname_pao, fname_vps
  character(16)  :: str

  real(8) :: R(3)
  real(8) :: ks(3), ke(3)
  integer        :: mesh
  type(Element_type), pointer :: elem

  logical        :: internal_coordinate = .false.
  real(8)        :: Qu, Qd
  logical        :: optimize
  character(256) :: dummy

  integer        :: is_opt=0
  real(8) :: mass = 0.0d0

  open(unit=16,file=Param%Option%file_ac_tempout,position='append')
  write(16,*) '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'
  write(16,999) fname
  write(16,*)
999 format(' +++++++++++ start: read file:: ',a15)
  close(16)

  inquire(file=fname,exist=ex)
  if( .not. ex ) then
     open(unit=16,file=Param%Option%file_ac_tempout,position='append')
     write(16,'(a,a)') '      ++++++ Error!: can not open file', trim(fname)
     close(16)
     stop
  end if
  iunit=1
  open(iunit, file=fname)

  MOL_TO_AU = AA_TO_AU
  CEL_TO_AU = AA_TO_AU

  do 
     read(iunit, '(a)', end=100) buf
     if( uncomment(buf) ) cycle
     read(buf,*) tag

     select case(tag)

     case('general{')
        do
           read(iunit, '(a)', end=100) buf
           if( uncomment(buf) ) cycle
           read(buf,*) tag

           select case(tag)
           case('system_name')
              read(buf,*) tag, Param%name
           case('dft__negf')
              cycle
           case('model_type')
              cycle
           case('calc_type')
              cycle
           case('read_SF_file')
              cycle
           case('output_G&T')
              cycle
           case('output_G')
              cycle
           case('output_T')
              cycle
           case('output_H')
              cycle
           case('band_calc_type')
              cycle

           case('}general')
              exit

           case default
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a,a,a)') '??? broken ??? //general{} has an unknown tag ', trim(tag), '// => stop'
              close(16)
              go to 1111

           end select
        end do
     case('}general')
        open(unit=16,file=Param%Option%file_ac_tempout,position='append')
        write(16,'(a)') '??? broken ??? //general{}// => stop'
        close(16)
        go to 1111


     case('accuracy{')
        do 
           read(iunit, '(a)', end=100) buf
           if( uncomment(buf) ) cycle
           read(buf,*) tag

           select case(tag)
           case('energy_cutoff')
              read(buf,*,end=1001) tag, Param%SCF%Ecutoff, str
              Param%SCF%Ecutoff = Param%SCF%Ecutoff * TO_AU(str)
              goto 1002
1001          continue
              Param%SCF%Ecutoff = Param%SCF%Ecutoff * RY_TO_AU
1002          continue

           case('temperature')
              read(buf,*,end=1011) tag, Param%SCF%Te, str
              Param%SCF%Te = Param%SCF%Te * TO_AU(str)
              goto 1012
1011          continue
              Param%SCF%Te = Param%SCF%Te * KELVIN_TO_AU
1012          continue

           case('scf_criterion_type')
              read(buf,*) tag, str
              select case(str)
              case('fermi')
                 Param%SCF%cri_type = 'fermi'
              case('orbital')
                 Param%SCF%cri_type = 'orbital'
              case('total')
                 Param%SCF%cri_type = 'total'
              case('density')
                 Param%SCF%cri_type = 'density'
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //accuracy/scf_criterion_type// => stop'
                 close(16)
                 go to 1111
              end select

           case('scf_convergence')
              read(buf,*,end=1021) tag, Param%SCF%criterion, str
              Param%SCF%criterion = Param%SCF%criterion * TO_AU(str)
              goto 1022
1021          continue
              Param%SCF%criterion = Param%SCF%criterion
1022          continue

           case('num_max_iteration')
              read(buf,*) tag, Param%SCF%iter_max

           case('ksampling{')
              do
                 read(iunit, '(a)', end=100) buf
                 if( uncomment(buf) ) cycle
                 read(buf,*) tag

                 select case(tag)
                 case('method')
                    read(buf,*) tag, str
                    select case(str)
                    case("gamma")
                       Param%SCF%Nka=1
                       Param%SCF%Nkb=1
                       Param%SCF%Nkc=1
                    case("mesh")
                       read(iunit,'(a)') buf
                       read(iunit,'(a)') buf
                       read(buf,*) Param%SCF%Nka, Param%SCF%Nkb, Param%SCF%Nkc
                       read(iunit,'(a)') buf
                    case default
                       open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                       write(16,'(a)') '??? broken ??? //accuracy/ksampling/method//'
                       close(16)
                    end select

                 case('}ksampling')
                    exit

                 case default
                    open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                    write(16,'(a,a,a)') '??? broken ??? //accuracy/ksampling{} has an unknown tag ', trim(tag), '// => stop'
                    close(16)
                    go to 1111


                 end select
              end do

           case('}ksampling')
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a)') '??? broken ??? //accuracy/ksampling{}// => stop'
              close(16)
              go to 1111


           case('xctype')
              read(buf,*) tag, str
              select case(str)
              case('ldapz81')
                 Param%SCF%exc_type = 'PZ81'
              case('ldapw91')
                 Param%SCF%exc_type = 'PW91'
              case('ggapbe')
                 Param%SCF%exc_type = 'PBE'
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //accuracy/xctype// => stop'
                 close(16)
                 go to 1111
              end select


           case('element_data_path_vps')
              read(buf,*) tag, Param%Data%path_vps
              if( Param%Data%path_vps == "" ) then
                 Param%Data%path_vps = "."
              end if

           case('element_data_path_pao')
              read(buf,*) tag, Param%Data%path_pao
              if( Param%Data%path_pao == "" ) then
                 Param%Data%path_pao = "."
              end if

           case('element_type')
              read(buf,*) tag, str
              select case(str)
              case('ciao')
                 Param%Data%element_type = "ciao"
              case('ciao_ls')
                 Param%Data%element_type = "ciao_ls"
              case('adpack')
                 Param%Data%element_type = "adpack"
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //accuracy/element_type// => stop'
                 close(16)
                 go to 1111
              end select

           case('num_element')
              read(buf,*) tag, Param%Data%nelem

           case('element_list{')
              if( Param%Data%nelem <= 0 ) then
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //accuracy/num_element// => stop'
                 close(16)
                 goto 1111
              end if

              allocate( Param%Data%velem(Param%Data%nelem))
              allocate( Param%Data%velem_file(Param%Data%nelem,5))

              do i=1, Param%Data%nelem
                 read(iunit, '(a)') buf

                 read(buf,*,end=1115) name, name_pao, name_vps, mode, dummy, mass
                 mode2 = ""
                 goto 1114
1115             continue
                 read(buf,*,end=1112) name, name_pao, name_vps, mode, mode2
                 goto 1114
1112             continue
                 read(buf,*,end=1113) name, name_pao, name_vps, mode
                 mode2 = ""
                 goto 1114
1113             continue
                 mode  = ""
                 mode2 = ""
                 goto 1114
1114             continue

                 fname_pao = trim(Param%Data%path_pao) // "/" // trim(name_pao)
                 fname_vps = trim(Param%Data%path_vps) // "/" // trim(name_vps)

                 Param%Data%velem_file(i,1)=name
                 Param%Data%velem_file(i,2)=fname_pao
                 Param%Data%velem_file(i,3)=mode
                 Param%Data%velem_file(i,4)=fname_vps
                 Param%Data%velem_file(i,5)=mode2

                 select case(Param%Data%element_type)
                 case('ciao')
                    call Element__readPAO_ciao  ( Param%Data%velem(i), name, fname_pao, mode, mode2 )
                    call Element__readVPS_ciao  ( Param%Data%velem(i), name, fname_vps )
                 case('ciao_ls')
                    call Element__readPAO_ciao  ( Param%Data%velem(i), name, fname_pao, mode, mode2 )
                    call Element__readVPS_ciao_ls( Param%Data%velem(i), name, fname_vps )
                 case('adpack')
                    call Element__readPAO_adpack( Param%Data%velem(i), name, fname_pao, mode, mode2 )
                    call Element__readVPS_adpack( Param%Data%velem(i), name, fname_vps )
                 end select

                 Param%Data%velem(i)%mass = mass * ATOM_MASS_TO_AU
              end do
              read(iunit, '(a)') buf

           case('}element_list')
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a)') '??? broken ??? //accuracy/element_list{}// => stop'
              close(16)
              go to 1111

           case('opt_switch','calc_force')
              read(buf,*) tag, str
              select case(str)
              case('opt','Opt','OPT')
                 Param%Option%optimize = .true.
                 is_opt=0
              case('on','On','ON')
                 Param%Option%optimize = .true.
                 is_opt=1
              case('off','Off','OFF')
                 Param%Option%optimize = .false.
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //accuracy/opt_switch{}// => stop'
                 close(16)
                 go to 1111
              end select

           case('opt_method')
              read(buf,*) tag, str
              select case(str)
              case('cg','CG','Cg','conjgate gradient')
                 Param%Option%optimize_method = "cg"
              case('sd','SDf','Sd','steepest descent')
                 Param%Option%optimize_method = "sd"
              case('diis','DIIS','gdiis','GDIIS','gDIIS','pulay','Pulay')
                 Param%Option%optimize_method = "diis"
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //accuracy/opt_method// => stop'
                 close(16)
                 go to 1111
              end select

           case('force_convergence','opt_force_convergence')
              read(buf,*,end=1051) tag, Param%SCF%force_criterion, str
              Param%SCF%force_criterion = Param%SCF%force_criterion * TO_AU(str)
              goto 1052
1051          continue
              Param%SCF%force_criterion = Param%SCF%force_criterion
1052          continue

           case('opt_num_max_iteration')
              read(buf,*) tag, Param%SCF%opt_iter_max

           case('projection')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%Option%projection = .true.

              case('off','Off','OFF')
                 Param%Option%projection = .false.
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //accuracy/projection// => stop'
                 close(16)
                 go to 1111
              end select

           case('}accuracy')
              exit

           case default
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a,a,a)') '??? broken ??? //accuracy{} has an unknown tag ', trim(tag), '// => stop'
              close(16)
              go to 1111

           end select

        end do

     case('structure{')
        do 
           read(iunit, '(a)', end=100) buf
           if( uncomment(buf) ) cycle
           read(buf,*) tag

           select case(tag)

           case('spin_polarization')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%Option%spin_polar = .true.
                 if( .not. Param%Option%spin_orbit ) then
                    Param%Option%nspin = 2
                 end if
              case('off','Off','OFF')
                 if( .not. Param%Option%spin_orbit ) then
                    Param%Option%spin_polar = .false.
                    Param%Option%nspin = 1
                 else
                    open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                    write(16,'(a)') '??? SO ??? //structure/spin_polarization// -> ON'
                    close(16)
                 end if
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //structure/spin_polarization// => stop'
                 close(16)
                 go to 1111
              end select

           case('spin_orbit_coupling')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 if( Param%Option%nspin == 1 ) then
                    open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                    write(16,'(a)') '??? SP ??? //structure/spin_polarization// -> ON'
                    close(16)
                 end if
                 Param%Option%spin_orbit = .true.
                 Param%Option%spin_polar = .true.
                 Param%Option%nspin  = 4
              case('off','Off','OFF')
                 Param%Option%spin_orbit = .false.
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //structure/spin_orbit_coupling// => stop'
                 close(16)
                 go to 1111
              end select

           case('sw_cluster')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%Option%cluster = .true.
              case('off','Off','OFF')
                 Param%Option%cluster = .false.
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //structure/sw_cluster// => stop'
                 close(16)
                 go to 1111
              end select

           case('unit_cell{')
              do
                 read(iunit, '(a)', end=100) buf
                 if( uncomment(buf) ) cycle
                 read(buf,*) tag

                 select case(tag)
                 case('unit')
                    read(buf,*) tag, str
                    CEL_TO_AU = TO_AU(str)

                 case('vector{')
                    read(iunit,'(a)') buf
                    read(buf,*) Param%Cell%La(:)

                    read(iunit,'(a)') buf
                    read(buf,*) Param%Cell%Lb(:)

                    read(iunit,'(a)') buf
                    read(buf,*) Param%Cell%Lc(:)

                    Param%Cell%La = Param%Cell%La * CEL_TO_AU
                    Param%Cell%Lb = Param%Cell%Lb * CEL_TO_AU
                    Param%Cell%Lc = Param%Cell%Lc * CEL_TO_AU
                    read(iunit,'(a)') buf

                 case('}vector')
                    open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                    write(16,'(a)') '??? broken ??? //structure/cell/vector{}// => stop'
                    close(16)
                    go to 1111

                 case('}unit_cell')
                    exit

                 case default
                    open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                    write(16,'(a,a,a)') '??? broken ??? //structure/cell{} has an unknown tag ', trim(tag), '// => stop'
                    close(16)
                    go to 1111

                 end select
              end do

           case('}unit_cell')
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a)') '??? broken ??? //structure/cell{}// => stop'
              close(16)
              go to 1111

           case('atom_list{')
              Param%Data%Ne_extra = 0.0d0

              do
                 read(iunit, '(a)', end=100) buf
                 if( uncomment(buf) ) cycle
                 read(buf,*) tag

                 select case(tag)
                 case('num_atom')
                    read(buf,*) tag, Param%Data%natom
                 case('num_left_atom')
                    read(buf,*) tag, Param%Data%natom_left
                 case('num_right_atom')
                    read(buf,*) tag, Param%Data%natom_right
                 case('unit')
                    read(buf,*) tag, str
                    MOL_TO_AU = TO_AU(str)

                 case('coordinate_system')
                    read(buf,*) tag, str
                    select case(str)
                    case('internal')
                       internal_coordinate = .true.
                    case('cartesian')
                       internal_coordinate = .false.
                    case default
                       open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                       write(16,'(a)') '??? broken ??? //structure/atom_list/coordinate_system// => stop'
                       close(16)
                       go to 1111
                    end select

                 case('extra_charge')
                    read(buf,*) tag, Param%Data%Ne_extra

                 case('atoms{')
                    if( Param%Data%natom <= 0 ) then
                       open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                       write(16,'(a)') '??? broken ??? //structure/atom_list/num_atom// => stop'
                       close(16)
                       go to 1111
                    end if

                    allocate( Param%Data%vatom(Param%Data%natom))
                    do i=1, Param%Data%natom
                       read(iunit,'(a)') buf
                       read(buf,*,end=1081) dummy, name, R(:), Qu, Qd, str
                       if( dummy == dummy ) then
                       endif
                       goto 1082
1081                   continue
                       read(buf,*) dummy, name, R(:), Qu, Qd
                       str = "free"
1082                   continue
                       select case(str)
                       case("free","optimize")
                          optimize = .true.
                       case("fix", "fixed")
                          optimize = .false.
                       case default
                          optimize = .true.
                       end select

                       if( internal_coordinate ) then
                          R = Param%Cell%La * R(1) + Param%Cell%Lb * R(2) + Param%Cell%Lc * R(3) + Param%Cell%Lo
                       else if( MOL_TO_AU /= 1.d0 ) then
                          R = R*MOL_TO_AU
                       end if

                       elem => Param__Data__getElement( name )

                       call Atom__set( Param%Data%vatom(i), name, R, &
                            elem%vpao(1)%Rc, -elem%Vloc%Q, elem%atomic_number, (Qu-Qd)/(Qu+Qd), optimize )
                    end do
                    read(iunit,'(a)') buf

                 case('}atoms')
                    open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                    write(16,'(a)') '??? broken ??? //structure/atom_list/atoms{}// => stop'
                    close(16)
                    go to 1111

                 case('}atom_list')
                    exit

                 case default
                    open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                    write(16,'(a,a,a)') '??? broken ??? //structure/atom_list{} has an unknown tag ', trim(tag), '// => stop'
                    close(16)
                    go to 1111


                 end select
              end do

           case('}atom_list')
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a)') '??? broken ??? //structure/atom_list{}// => stop'
              close(16)
              goto 1111

           case('}structure')
              exit

           case default
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a,a,a)') '??? broken ??? //structure{} has an unknown tag ', trim(tag), '// => stop'
              close(16)

              go to 1111

           end select
        end do


     case('charge_mixing{')
        do
           read(iunit, '(a)', end=100) buf
           if( uncomment(buf) ) cycle
           read(buf,*) tag

           select case(tag)

           case('mixing_methods','method','methods')
              read(buf,*) tag, str
              select case(str)
              case('simple','Simple')
                 Param%SCF%mix_type    = 'Simple'
                 Param%SCF%mix_start   = 0
                 Param%SCF%mix_history = 1
              case('pulay','Pulay','rmm-diis','Rmm-Diis','RMM-DIIS')
                 Param%SCF%mix_type = 'Pulay'
              case('Anderson','anderson')
                 Param%SCF%mix_type = 'Anderson'
                 Param%SCF%mix_start   = 0
                 Param%SCF%mix_history = 3
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //charge_mixing/mixing_methods// => stop'
                 close(16)
                 go to 1111
              end select

           case('target')
              read(buf,*) tag, str
              select case(str)
              case('density','Density')
                 Param%SCF%mix_target = 'density'
              case('density_matrix','Density_Matrix','matrix','Matrix','DM')
                 Param%SCF%mix_target = 'density_matrix'
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //charge_mixing/mixing_target// => stop'
                 close(16)
                 go to 1111
              end select


           case('mixing_weight','weight')
              read(buf,*) tag, Param%SCF%mix_weight

           case('mixing_weight_simple','weight_simple')
              read(buf,*) tag, Param%SCF%mix_weight_s

           case('pulay_start','rmmdiis_start','mix_start','mixing_start','start')
              read(buf,*) tag, Param%SCF%mix_start

           case('pulay_history','rmmdiis_history','mix_history','mixing_history','history')
              read(buf,*) tag, Param%SCF%mix_history

           case('}charge_mixing')
              exit

           case default
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a,a,a)') '??? broken ??? //charge_mixing{} has an unknown tag ', trim(tag), '// => stop'
              close(16)
              go to 1111

           end select
        end do

     case('}charge_mixing')
        open(unit=16,file=Param%Option%file_ac_tempout,position='append')
        write(16,'(a)') '??? broken ??? //charge_mixing{}// => stop'
        close(16)
        goto 1111

     case('file_in{')
        do
           read(iunit, '(a)', end=100) buf
           if( uncomment(buf) ) cycle
           read(buf,*) tag

           select case(tag)
           case('density_scf')
              read(buf,*) tag, Param%Option%fname_rhoscf_in

           case('matrices')
              read(buf,*) tag, Param%Option%fname_matrices_in

           case('}file_in')
              exit

           case default
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a,a,a)') '??? broken ??? //file_in{} has an unknown tag ', trim(tag), '// => stop'
              close(16)
              go to 1111
           end select
        end do

     case('}file_in')
        open(unit=16,file=Param%Option%file_ac_tempout,position='append')
        write(16,'(a)') '??? broken ??? //file_in{}// => stop'
        close(16)
        goto 1111



     case('file_out{')
        if( Param%name == "" ) then
           open(unit=16,file=Param%Option%file_ac_tempout,position='append')
           write(16,'(a)') '??? not given ??? //general/system_name// => stop'
           close(16)
           go to 1111
        end if

        do
           read(iunit, '(a)', end=100) buf
           if( uncomment(buf) ) cycle
           read(buf,*) tag

           select case(tag)
           case('save_at')
              read(buf,*) tag, str
              select case(str)
              case("never")
                 Param%Option%saveat = "never"
              case("everystep")
                 Param%Option%saveat = "everstep"
              case("finalstep")
                 Param%Option%saveat = "finalstep"
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //file_out/save_at// => stop'
                 close(16)
                 go to 1111
              end select

           case('field_format')
              read(buf,*) tag, str
              select case(str)
              case('cube')
                 Param%Option%field_format = ".cube"
              case('dx')
                 Param%Option%field_format = ".dx"
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //file_out/field_format// => stop'
                 close(16)
                 go to 1111
              end select

           case('density_scf')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%Option%fname_rhoscf   = trim(Param%name) // ".density.scf" // trim(Param%Option%field_format)
              case('off','Off','OFF')
                 Param%Option%fname_rhoscf   = ""
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //file_out/density_scf// => stop'
                 close(16)
                 go to 1111
              end select

           case('density_val')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%Option%fname_rhoval  = trim(Param%name) // ".density.val" // trim(Param%Option%field_format)
              case('off','Off','OFF')
                 Param%Option%fname_rhoval  = ""
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //file_out/density_val// => stop'
                 close(16)
                 go to 1111
              end select

           case('density_pcc')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%Option%fname_rhopcc  = trim(Param%name) // ".density.pcc" // trim(Param%Option%field_format)
              case('off','Off','OFF')
                 Param%Option%fname_rhopcc  = ""
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //file_out/density_pcc// => stop'
                 close(16)
                 go to 1111
              end select

           case('potential_ext')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%Option%fname_vext   = trim(Param%name) // ".potential.ext" // trim(Param%Option%field_format)
              case('off','Off','OFF')
                 Param%Option%fname_vext   = ""
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //file_out/potential_ext// => stop'
                 close(16)
                 go to 1111
              end select

           case('potential_har')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%Option%fname_vhar  = trim(Param%name) // ".potential.har" // trim(Param%Option%field_format)
              case('off','Off','OFF')
                 Param%Option%fname_vhar  = ""
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //file_out/potential_har// => stop'
                 close(16)
                 go to 1111
              end select

           case('potential_exc')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%Option%fname_vexc   = trim(Param%name) // ".potential.exc" // trim(Param%Option%field_format)
              case('off','Off','OFF')
                 Param%Option%fname_vexc   = ""
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //file_out/potential_exc// => stop'
                 close(16)
                 go to 1111

              end select

           case('potential_tot')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%Option%fname_vtot   = trim(Param%name) // ".potential.tot" // trim(Param%Option%field_format)
              case('off','Off','OFF')
                 Param%Option%fname_vtot   = ""
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //file_out/potential_tot// => stop'
                 close(16)
                 go to 1111
              end select

           case('matrices')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%Option%fname_matrices = trim(Param%name) // ".matrices.dat"
              case('off','Off','OFF')
                 Param%Option%fname_matrices = ""
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //file_out/matrices// => stop'
                 close(16)
                 go to 1111

              end select

           case('f_negf')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%Option%ascot_negf = .true.
                 Param%Option%fname_accel_c  = ""
                 Param%Option%fname_accel_r  = ""
                 Param%Option%fname_accel_l  = ""
                 Param%Option%fname_ascot_vd = trim(Param%name) // ".vd.data"
                 Param%Option%fname_ascot_in = trim(Param%name) // ".in.data"
              case('off','Off','OFF')
                 Param%Option%fname_accel_c  = ""
                 Param%Option%fname_accel_r  = ""
                 Param%Option%fname_accel_l  = ""
                 Param%Option%fname_ascot_vd = ""
                 Param%Option%fname_ascot_in = ""
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //file_out/f_negf// => stop'
                 close(16)
                 go to 1111
              end select

           case('gamma_matrix')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%Option%fname_accel_c  = trim(Param%name) // ".ascot_c.dat"
                 Param%Option%fname_accel_r  = ""
                 Param%Option%fname_accel_l  = ""
              case('off','Off','OFF')
                 Param%Option%fname_accel_c  = ""
                 Param%Option%fname_accel_r  = ""
                 Param%Option%fname_accel_l  = ""
              case default
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a)') '??? broken ??? //file_out/gamma_matrix// => stop'
                 close(16)
                 go to 1111
              end select

           case('}file_out')
              exit

           case default
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a,a,a)') '??? broken ??? //file_out{} has an unknown tag ', trim(tag), '// => stop'
              close(16)
              go to 1111


           end select
        end do

     case('}file_out')
        open(unit=16,file=Param%Option%file_ac_tempout,position='append')
        write(16,'(a)') '??? broken ??? //file_out{}// => stop'
        close(16)
        goto 1111


     case('atom_int{')
        do
           read(iunit, '(a)', end=100) buf
           if( uncomment(buf) ) cycle
           read(buf,*) tag

           select case(tag)
           case('num_k')
              read(buf,*) tag, Param%Integral1D%Nk

           case('num_r')
              read(buf,*) tag, Param%Integral1D%Nr

           case('energy_cutoff')
              read(buf,*,end=1031) tag, Param%Integral1D%Ecutoff, str
              Param%Integral1D%Ecutoff = Param%Integral1D%Ecutoff * TO_AU(str)
              goto 1032
1031          continue
              Param%Integral1D%Ecutoff = Param%Integral1D%Ecutoff * RY_TO_AU
1032          continue

           case('}atom_int')
              exit

           case default
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a,a,a)') '??? broken ??? //atom_int{} has an unknown tag ', trim(tag), '// => stop'
              close(16)
              go to 1111


           end select
        end do

     case('}atom_int')
        open(unit=16,file=Param%Option%file_ac_tempout,position='append')
        write(16,'(a)') '??? broken ??? //atom_int{}// => stop'
        close(16)
        goto 1111


     case('mpi_condition{')
        do
           read(iunit, '(a)', end=100) buf
           if( uncomment(buf) ) cycle
           read(buf,*) tag

           select case(tag)
           case('num_sc_work2space')
              read(buf,*) tag, MPI%num_sc_work2space
              if( MPI%num_sc_work2space < -1.d0 ) then
                 open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                 write(16,'(a,a,a)') '??? change ??? //mpi_condition/num_sc_work2space// => -1'
                 close(16)
                 MPI%num_sc_work2space=-1.d0
              end if

           case('num_check_sc')
              read(buf,*) tag, MPI%num_check_sc

           case('}mpi_condition')
              exit

           case default
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a,a,a)') '??? broken ??? //mpi_condition{} has an unknown tag ', trim(tag), '// => stop'
              close(16)
              go to 1111

           end select
        end do

     case('}mpi_condition')
        open(unit=16,file=Param%Option%file_ac_tempout,position='append')
        write(16,'(a)') '??? broken ??? //mpi_condition{}// => stop'
        close(16)
        goto 1111

     case('postprocessing{','Postprocessing{')
        if( Param%name == "" ) then
           open(unit=16,file=Param%Option%file_ac_tempout,position='append')
           write(16,'(a)') '??? broken ??? //general/system_name// => stop'
           close(16)
           go to 1111
        end if

        do
           read(iunit, '(a)', end=100) buf
           if( uncomment(buf) ) cycle
           read(buf,*) tag

           select case(tag)
           case('band{')
              do
                 read(iunit, '(a)', end=100) buf
                 if( uncomment(buf) ) cycle
                 read(buf,*) tag

                 select case(tag)
                 case('sw_band')
                    read(buf,*) tag, str
                    select case(str)
                    case('on','On','ON')
                       Param%Band%fname = trim(Param%name) // ".band.dat"
                    case('off','Off','OFF')
                       Param%Band%fname = ""
                    case default
                       open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                       write(16,'(a)') '??? broken ??? //post/band/sw_band// => stop'
                       close(16)
                       go to 1111
                    end select

                 case('num_show_band')
                    read(buf,*) tag, Param%Band%num_band

                 case('unit_cell{')
                    do
                       read(iunit, '(a)', end=100) buf
                       if( uncomment(buf) ) cycle
                       read(buf,*) tag

                       select case(tag)
                       case('unit')
                          read(buf,*) tag, str
                          CEL_TO_AU = TO_AU(str)

                       case('vector{')
                          read(iunit,'(a)') buf
                          read(buf,*) Param%Band%La(:)

                          read(iunit,'(a)') buf
                          read(buf,*) Param%Band%Lb(:)

                          read(iunit,'(a)') buf
                          read(buf,*) Param%Band%Lc(:)

                          Param%Band%La = Param%Band%La * CEL_TO_AU
                          Param%Band%Lb = Param%Band%Lb * CEL_TO_AU
                          Param%Band%Lc = Param%Band%Lc * CEL_TO_AU

                          read(iunit,'(a)') buf

                       case('}vector')
                          open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                          write(16,'(a)') '??? broken ??? //post/band/cell/vector{}// => stop'
                          close(16)
                          goto 1111

                       case('}unit_cell')
                          exit

                       case default
                          open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                          write(16,'(a,a,a)') '??? broken ??? //post/band/cell{} has an unknown tag ', trim(tag), '// => stop'
                          close(16)
                          go to 1111

                       end select
                    end do

                 case('}unit_cell')
                    open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                    write(16,'(a)') '??? broken ??? //post/band/cell{}// => stop'
                    close(16)
                    goto 1111

                 case('num_band_path')
                    read(buf,*) tag, Param%Band%nKpath
                    if( Param%Band%nKpath == 0 ) then
                       Param%Band%fname = ""
                    end if

                 case('band_path{')
                    if( Param%Band%nKpath<=0 ) then
                       open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                       write(16,'(a)') '??? broken ??? //post/band/num_band_path// => stop'
                       close(16)
                       goto 1111
                    end if

                    allocate( Param%Band%vKpath(Param%Band%nKpath) )
                    do i=1, Param%Band%nKpath
                       read(iunit,'(a)') buf
                       read(buf,*) ks(:), ke(:), mesh

                       Param%Band%vKpath(i)%ks = ks
                       Param%Band%vKpath(i)%ke = ke
                       Param%Band%vKpath(i)%mesh = mesh
                    end do
                    read(iunit,'(a)') buf

                 case('}band')
                    exit

                 case default
                    open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                    write(16,'(a,a,a)') '??? broken ??? //post/band{} has an unknown tag ', trim(tag), '// => stop'
                    close(16)
                    goto 1111

                 end select
              end do

           case('}band')
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a)') '??? broken ??? //post/band{}// => stop'
              close(16)
              goto 1111


           case('dos{')
              do
                 read(iunit, '(a)', end=100) buf
                 if( uncomment(buf) ) cycle
                 read(buf,*) tag

                 select case(tag)
                 case('sw_dos')
                    read(buf,*) tag, str
                    select case(str)
                    case('on','On','ON')
                       Param%DOS%fname = trim(Param%name) // ".dos.dat"
                    case('off','Off','OFF')
                       Param%DOS%fname = ""
                    case default
                       open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                       write(16,'(a)') '??? broken ??? //post/dos/sw_dos// => stop'
                       close(16)
                       go to 1111
                    end select

                 case('method')
                    read(buf,*) tag, str
                    select case(str)
                    case('boxes','histogram')
                       Param%DOS%method = 'histogram'
                    case('gaussian')
                       Param%DOS%method = 'gaussian'
                    case('tetrahedron')
                       Param%DOS%method = 'tetrahedron'
                    case default 
                       open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                       write(16,'(a)') '??? broken ??? //post/dos/method// => stop'
                       close(16)
                       go to 1111
                    end select

                 case('gaussian_broadening')
                    read(buf,*,end=1043) tag, Param%DOS%GB, str
                    Param%DOS%GB = Param%DOS%GB * TO_AU(str)
                    goto 1044
1043                continue
                    Param%DOS%GB = Param%DOS%GB * EV_TO_AU
1044                continue

                 case('e_range{')
                    do
                       read(iunit, '(a)', end=100) buf
                       if( uncomment(buf) ) cycle
                       read(buf,*) tag
                       if( tag == "}e_range" ) exit

                       read(buf,*,end=1041) Param%DOS%Ne, Param%DOS%Emin, Param%DOS%Emax, str
                       Param%DOS%Emin = Param%DOS%Emin * TO_AU(str)
                       Param%DOS%Emax = Param%DOS%Emax * TO_AU(str)
                       goto 1042
1041                   continue
                       Param%DOS%Emin = Param%DOS%Emin * EV_TO_AU
                       Param%DOS%Emax = Param%DOS%Emax * EV_TO_AU
1042                   continue
                    end do

                 case('ksampling{')
                    do
                       read(iunit, '(a)', end=100) buf
                       if( uncomment(buf) ) cycle
                       read(buf,*) tag
                       if( tag == "}ksampling" ) exit
                       read(buf,*) Param%DOS%Nka, Param%DOS%Nkb, Param%DOS%Nkc
                    end do

                 case('}dos')
                    exit

                 case default
                    open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                    write(16,'(a,a,a)') '??? broken ??? //post/dos{} has an unknown tag ', trim(tag), '// => stop'
                    close(16)
                    go to 1111

                 end select
              end do

           case('}dos')
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a)') '??? broken ??? //post/dos{}// => stop'
              close(16)
              goto 1111



           case('mo{')
              do
                 read(iunit, '(a)', end=100) buf
                 if( uncomment(buf) ) cycle
                 read(buf,*) tag

                 select case(tag)
                 case('sw_mo')
                    read(buf,*) tag, str
                    select case(str)
                    case('on','On','ON')
                       Param%MO%fbase = trim(Param%name) // ".mo"
                    case('off','Off','OFF')
                       Param%MO%fbase = ""
                    case default
                       open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                       write(16,'(a)') '??? broken ??? //post/mo/sw_mo// => stop'
                       close(16)
                       go to 1111
                    end select

                 case('m_bandnum')
                    read(buf,*) tag, str
                    select case(str)
                    case('band_num','bandnum')
                       Param%MO%method = 'band_num'
                    case('ho_lumo','homolumo')
                       Param%MO%method = 'ho_lumo'
                    case default 
                       open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                       write(16,'(a)') '??? broken ??? //post/mo/method// => stop'
                       close(16) 
                       go to 1111
                    end select

                 case('band_range{')
                    do
                       read(iunit, '(a)', end=100) buf
                       if( uncomment(buf) ) cycle
                       read(buf,*) tag
                       if( tag == "}band_range" ) exit
                       read(buf,*) Param%MO%band_min, Param%MO%band_max
                    end do


                 case('unit_cell{')
                    do
                       read(iunit, '(a)', end=100) buf
                       if( uncomment(buf) ) cycle
                       read(buf,*) tag

                       select case(tag)
                       case('unit')
                          read(buf,*) tag, str
                          CEL_TO_AU = TO_AU(str)

                       case('vector{')
                          read(iunit,'(a)') buf
                          read(buf,*) Param%MO%La(:)

                          read(iunit,'(a)') buf
                          read(buf,*) Param%MO%Lb(:)

                          read(iunit,'(a)') buf
                          read(buf,*) Param%MO%Lc(:)

                          Param%MO%La = Param%MO%La * CEL_TO_AU
                          Param%MO%Lb = Param%MO%Lb * CEL_TO_AU
                          Param%MO%Lc = Param%MO%Lc * CEL_TO_AU

                          read(iunit,'(a)') buf

                       case('}vector')
                          open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                          write(16,'(a)') '??? broken ??? //post/mo/cell/vector{}// => stop'
                          close(16)
                          goto 1111

                       case('}unit_cell')
                          exit

                       case default
                          open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                          write(16,'(a,a,a)') '??? broken ??? //post/mo/cell{} has an unknown tag ', trim(tag), '// => stop'
                          close(16) 
                          go to 1111


                       end select
                    end do

                 case('}unit_cell')
                    open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                    write(16,'(a)') '??? broken ??? //post/mo/cell{}// => stop'
                    close(16) 
                    goto 1111

                 case('num_k_points')
                    read(buf,*) tag, Param%MO%nK
                    allocate( Param%MO%vK(3,Param%MO%nK) )

                 case('k_points{')
                    if( .not. associated(Param%MO%vK) ) then
                       open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                       write(16,'(a)') '??? broken ??? //post/mo/num_k_points// => stop'
                       close(16) 
                       go to 1111
                    end if

                    do i=1, Param%MO%nK
                       read(iunit,'(a)') buf
                       read(buf,*) Param%MO%vK(:,i)
                    end do
                    read(iunit,'(a)') buf

                 case('}mo')
                    exit

                 case default
                    open(unit=16,file=Param%Option%file_ac_tempout,position='append')
                    write(16,'(a,a,a)') '??? broken ??? //post/mo{} has an unknown tag ', trim(tag), '// => stop'
                    close(16) 
                    go to 1111

                 end select
              end do

           case('}mo')
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a)') '??? broken ??? //post/mo{}// => stop'
              close(16) 
              goto 1111


           case('}postprocessing','}Postprocessing')
              exit

           case default
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a,a,a)') '??? broken ??? //post{} has an unknown tag ', trim(tag), '// => stop'
              close(16) 
              go to 1111

           end select
        end do

        ! phonon
     case('phonon{','Phonon{')
        Param%Option%phonon = .true.
        do
           read(iunit, '(a)', end=100) buf
           if( uncomment(buf) ) cycle
           read(buf,*) tag

           select case(tag)
           case('displacement')
              read(buf,*) tag, Param%phonon%displacement

           case('output_force_constant_matrix')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%phonon%output_force_constant_matrix = .true.
              case('off','Off','OFF')
                 Param%phonon%output_force_constant_matrix = .false.
              end select

           case('output_dynamical_matrix')
              read(buf,*) tag, str
              select case(str)
              case('on','On','ON')
                 Param%phonon%output_dynamical_matrix = .true.
              case('off','Off','OFF')
                 Param%phonon%output_dynamical_matrix = .false.
              end select

           case('}phonon')
              exit

           case default
              open(unit=16,file=Param%Option%file_ac_tempout,position='append')
              write(16,'(a,a,a)') '??? broken ??? //phonon{} has an unknown tag ', trim(tag), '// => stop'
              close(16)
              go to 1111

           end select
        end do

     end select
  end do

100 continue

  close(iunit)

  if( is_opt == 0 ) then
     if( Param%SCF%opt_iter_max == 0 ) then
        open(unit=16,file=Param%Option%file_ac_tempout,position='append')
        write(16,'(a)') '??? to ??? //accuracy/calc_force{}// :: opt -> ON'
        close(16)
     end if
  else
     Param%SCF%opt_iter_max=0
  end if
  if( Param%SCF%mix_weight_s < 0.d0 ) then
     Param%SCF%mix_weight_s=Param%SCF%mix_weight
     open(unit=16,file=Param%Option%file_ac_tempout,position='append')
     write(16,'(a)') '??? to ??? //charge_mixing/mixing_weight_simple{}// :: -> mixing_weight'
     close(16)
  end if
  if( Param%Option%nspin == 0 ) then
     Param%Option%nspin = 1
  end if
  if( Param%Option%nspin == 2 .and. Param%Band%fname /="" ) then
     Param%Band%fname = trim(Param%name) // ".band_u.dat"
     Param%Band%fname1 = trim(Param%name) // ".band_d.dat"
  end if

  return

1111 continue

  close(iunit)
  stop

end subroutine Param__read

subroutine Param__setup(move)
  use ac_misc_module
  implicit none
  integer, intent(in) :: move

  call Param__Cell__setup(move)
  call Param__SCF__setup
  call Param__Band__setup
  call Param__DOS__setup
  call Param__MO__setup
  call Param__Data__setup

  return
end subroutine Param__setup

subroutine Param__show
  use ac_misc_module
  implicit none

  open(unit=16,file=Param%Option%file_ac_tempout,position='append')
  write(16,*)
  write(16,*)
  write(16,*) '********************** **************** **********************'
  write(16,*) '*                 input  condition  !  dft  !                *'
  write(16,*) '********************** **************** **********************'
  write(16,*)

  call Param__SCF__show
  call Param__Band__show
  call Param__DOS__show
  call Param__MO__show
  call Param__Option__show
  call Param__Data__show

  write(16,*) '++++++++++++  end : read file'
  write(16,*) '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'
  write(16,*)
  close(16)

  return
end subroutine Param__show

subroutine Param__Cell__R( R, ia, ib, ic )
  use ac_misc_module

  implicit none
  integer, intent(in) :: ia, ib, ic
  real(8), intent(out) :: R(3)

  R =  Param%Cell%Lo + Param%Cell%dLa*dble(ia-1) &
       + Param%Cell%dLb*dble(ib-1) + Param%Cell%dLc*dble(ic-1)

  return
end subroutine Param__Cell__R

subroutine Param__Cell__L(L,na,nb,nc)
  use ac_misc_module

  implicit none
  integer, intent(in) :: na, nb, nc
  real(8), intent(out) :: L(3)

  L = Param%Cell%La*dble(na) + Param%Cell%Lb*dble(nb) &
       + Param%Cell%Lc*dble(nc)

  return
end subroutine Param__Cell__L

subroutine Param__Cell__K(K,ika,ikb,ikc)
  use ac_misc_module

  implicit none
  integer, intent(in) :: ika, ikb, ikc
  real(8), intent(out) :: K(3)

  K = 0.d0

  if( 2*ika-2 < Param%Cell%Na ) then
     K = K + Param%Cell%dKa*dble(ika-1)
  else
     K = K - Param%Cell%dKa*dble(Param%Cell%Na+1-ika)
  end if

  if( 2*ikb-2 < Param%Cell%Nb ) then
     K = K + Param%Cell%dKb*dble(ikb-1)
  else
     K = K - Param%Cell%dKb*dble(Param%Cell%Nb+1-ikb)
  end if

  if( 2*ikc-2 < Param%Cell%Nc ) then
     K = K + Param%Cell%dKc*dble(ikc-1)
  else
     K = K - Param%Cell%dKc*dble(Param%Cell%Nc+1-ikc)
  end if

  return
end subroutine Param__Cell__K

subroutine Param__DOS__binIndex(i,E)
  use ac_misc_module

  implicit none
  real(8), intent(in) :: E
  integer, intent(out) :: i

  i = int((E - Param%DOS%Emin + Param%DOS%dE/2)/Param%DOS%dE) + 1

  return
end subroutine Param__DOS__binIndex

subroutine Param__DOS__binEnergy(E,i)
  use ac_misc_module

  implicit none
  integer, intent(in) :: i
  real(8), intent(out) :: E

  E = Param%DOS%Emin + Param%DOS%dE*(i-1)

  return
end subroutine Param__DOS__binEnergy

subroutine Param__DOS__K(K,ika,ikb,ikc)
  use ac_misc_module

  implicit none
  integer, intent(in) :: ika, ikb, ikc
  real(8), intent(out) :: K(3)

  K = Param%Cell%dKa*( 0.5d0*dble(2*ika-1)/Param%DOS%Nka - 0.5d0 ) &
       + Param%Cell%dKb*( 0.5d0*dble(2*ikb-1)/Param%DOS%Nkb - 0.5d0 ) &
       + Param%Cell%dKc*( 0.5d0*dble(2*ikc-1)/Param%DOS%Nkc - 0.5d0 )

  return
end subroutine Param__DOS__K

subroutine Param__Cell__findAppNumber(n,no_in)
  use ac_misc_module

  implicit none
  integer, intent(out) :: n
  integer, intent(in) :: no_in
  integer :: a,no,dn
  logical :: found

  no=no_in

  if( Param%Option%mx ) then
     dn = 1
  else
     dn = 2
     if( mod(no,2) == 1 ) no = no+1
  end if

  do n=no, 2*no-1, dn
     a=n
     found=.false.

     do 
        if( mod(a,5) == 0 ) then
           a = a/5
           cycle
        end if
        if( mod(a,3) == 0 ) then
           a = a/3
           cycle
        end if
        if( mod(a,2) == 0 ) then
           a = a/2
           cycle
        end if
        if( a==1 ) then
           found=.true.
           exit
        else
           found=.false.
           exit
        end if
     end do

     if( found ) then
        return
     end if
  end do

  n = 0

  return
end subroutine Param__Cell__findAppNumber

subroutine Param__readdata_ASCOT
  use ac_misc_module

  implicit none
  integer       :: i,n,i_c
  character(5)   :: chara_temp
  type(Element_type), pointer :: elem

  open(unit=90,file=Param%Option%fname_ascot_in)

  write(90,900) Param%name
900 format(a15,'    system_name')

  write(90,*)
  write(90,905) Param%Data%element_type,Param%SCF%exc_type,Param%Option%nspin-1
905 format(a15,a15,i5,'    element_type, exc_type, spin')

  write(90,913) Param%SCF%Te, Param%SCF%Ecutoff
913 format(d28.18,d28.18,'    temperature,   energy_cutoff')

  write(90,*)
  write(90,912) Param%SCF%Nka, Param%SCF%Nkb, Param%SCF%Nkc
912 format(i10,i10,i10,'    ksampling')

  write(90,*)
  write(90,911) Param%Integral1D%Nk, Param%Integral1D%Nr, Param%Integral1D%Ecutoff
911 format(i10,i10,d28.18,'    Integral1D')

  if( Param%Option%projection ) then
     chara_temp='on'
  else
     chara_temp='off'
  end if

  write(90,*)
  write(90,*) Param%Data%nelem,'      ',trim(chara_temp),'    num_element'
  do i=1, Param%Data%nelem
     write(90,901) trim(Param%Data%velem_file(i,1))     &
          ,trim(Param%Data%velem_file(i,2))     &
          ,trim(Param%Data%velem_file(i,3))     &
          ,trim(Param%Data%velem_file(i,4))     &
          ,trim(Param%Data%velem_file(i,5))
901  format(a,'  "',a,'"  "',a,'"   "',a,'"   "',a,'"    element_list')
  end do

  write(90,*)
  write(90,904)Param%Cell%La(:)
  write(90,904)Param%Cell%Lb(:)
  write(90,904)Param%Cell%Lc(:)
904 format(d28.18,d28.18,d28.18)

  write(90,*)
  write(90,902) Param%Data%natom, Param%Data%natom_left, Param%Data%natom_right
902 format(i10,i10,i10,'    num_atom:: c, l, r')
  do i=1, Param%Data%natom
     elem => Param__Data__getElement( Param%Data%vatom(i)%name )
     i_c=0
     do n=1, elem%npao
        i_c = i_c + 2*(elem%vpao(n)%l) + 1
     end do
     write(90,903) i, Param%Data%vatom(i)%name, &
          Param%Data%vatom(i)%Ro(:),   &
          Param%Data%vatom(i)%polarization,i_c, Param%Data%vatom(i)%Q
903  format(i5,'   ',a5,d28.18,d28.18,d28.18,d28.18,i10,d28.18)
  end do

  close(90)

  return
end subroutine Param__readdata_ASCOT

subroutine Param__Structure__show
  use ac_misc_module
  use ac_mpi_module

  implicit none
  integer :: a
  integer, allocatable :: vnpao_temp(:)
  type(Element_type), pointer :: elem

  if( MPI%root ) then
     open(unit=60,file='structure.dat')
     write(60,*) '--------------------------------------------------------------'
     write(60,*) '------------   Atoms:'
     write(60,*) '--------------------------------------------------------------'

     write(60,*) ' atom   Q         Ro'
     do a=1, Param%Data%natom
        write(60,933) a,Param%Data%vatom(a)%name,                              &
             Param%Data%vatom(a)%Ro*AU_TO_AA, Param%Data%vatom(a)%Q
     end do

     write(60,*) '--------------------------------------------------------------'
     write(60,*)
     close(60)
  end if

933 format(i4,'  ',a2,3f20.15,f9.4)
932 format(i4,'  ',a2,3f15.10,f9.4)

  return
end subroutine Param__Structure__show
