module GBL
  !sikinote http://slpr.sakura.ne.jp/qp/
  !Author : sikino
  !Date   : 2016/03/18 (yyyy/mm/dd)
  !       : 2016/03/20
  !       : 2016/07/23
  !       : 2016/07/25
  !       : 2016/08/06
  implicit none
  !Constant of system
  double precision::m,g,a,eta,rho,temperature,pressure,moisture
  character(48)::omgdecay
 
  !Example parameter
  ! 1, tol=1d-10, eps=1d-9
  !           => very exact, slow computing speed  
  ! 2, tol=1d-6, eps=1d-6
  !           => enough computation practically.
 
  !Accuracy of rungekutta(tol must be constant)
  !         1d-2 < tol   : Rouph condition, computing speed is fast.
  ! 1d-10 <  tol < 1d-2  :               Intermediate
  ! 1d-12 < tol  < 1d-10 : Exact condition, computing speed is slow.
  ! tol < 1d-12          : Not reccomended, Maybe cannot computing due to machine epsilon.
  double precision,parameter::tol=1d-10
  !Conversence epsilon at rootfinding method
  !         1d0 < eps : Rouph condition, computing speed is fast.
  ! 1d-10 < eps < 1d0 :               Intermediate
  !  eps  < 1d-10     : Exact condition, computing speed is slow.
  !                      or cannot converge less than 1d-10.
  double precision,parameter::eps=1d-7
end module GBL
!================================
function rho_humid(T,P,M)
  ! T : temperature [degree]
  ! P : pressure    [Pa] ( 1 atm = 101325 Pa )
  ! M : moisture    [no-dimension]
  implicit none
  double precision,intent(in)::T,P,M
  double precision::rho_humid,et,rhoair
 
  et=6.1078d0*10d0**(7.5d0*T/(T+237.3d0)) ! et[hPa]
  et=100d0*et
  et=M*et
  !write(6,*)"et[Pa]",et
  rhoair=0.0034856447d0*P/(T+273.15d0-0.670d0)
  rho_humid=rhoair*(1d0-0.378d0*et/P)
 
  return
end function rho_humid
function eta_air(T)
  ! T : temperature [degree]
  implicit none
  double precision::T,eta_air
 
  eta_air=1.487d-6*((T+273.15d0)**1.5d0)/((T+273.15d0)+117d0)
  return
end function eta_air
module RKmod
  !sikinote http://slpr.sakura.ne.jp/qp/
  !developer => sikino
  !date => 2015/07/13
  implicit none
  !For Butcher table
  integer,private::s
  double precision,private,allocatable::a(:,:),b1(:),b2(:),c(:),Rc(:)
  !-----------------------------
contains
  subroutine rk_preparation(method)
    !set Butcher table
    implicit none
    character(*)::method
    if(trim(method).eq."rk4")then
       s=4
       allocate(a(1:s,1:s),b1(1:s),c(1:s))
       a=0d0; b1=0d0; c=0d0
       c(1:4)=(/0d0, 0.5d0, 0.5d0, 1d0/)
       a(1,1:4)=(/0d0,0d0,0d0,0d0/)
       a(2,1:4)=(/0.5d0,0d0,0d0,0d0/)
       a(3,1:4)=(/0d0,0.5d0,0d0,0d0/)
       a(4,1:4)=(/0d0,0d0,1d0,0d0/)
       b1(1:4)=(/1d0/6d0, 1d0/3d0, 1d0/3d0, 1d0/6d0/)
    elseif(trim(method).eq."rkf45")then
       s=6
       allocate(a(1:s,1:s),b1(1:s),b2(1:s),c(1:s),Rc(1:s))
       a=0d0; b1=0d0; b2=0d0; c=0d0; Rc=0d0
       c(1:6)=(/0d0, 0.25d0, 3d0/8d0, 12d0/13d0, 1d0, 0.5d0/)
       a(1:6,1:6)=0d0
       a(1,1:6)=(/0d0, 0d0, 0d0, 0d0, 0d0, 0d0/)
       a(2,1:6)=(/0.25d0, 0d0, 0d0, 0d0, 0d0, 0d0/)
       a(3,1:6)=(/0.09375d0, 0.28125d0, 0d0, 0d0, 0d0, 0d0/)
       a(4,1:6)=(/1932d0/2197d0, -7200d0/2197d0, 7296d0/2197d0, 0d0, 0d0, 0d0/)
       a(5,1:6)=(/439d0/216d0, -8d0, 3680d0/513d0, -845d0/4104d0, 0d0, 0d0/)
       a(6,1:6)=(/-8d0/27d0, 2d0, -3544d0/2565d0, 1859d0/4104d0, -11d0/40d0, 0d0/)
       b2(1:6)=(/16d0/135d0, 0d0, 6656d0/12825d0, 28561d0/56430d0, -9d0/50d0, 2d0/55d0/)
       b1(1:6)=(/25d0/216d0, 0d0, 1408d0/2565d0, 2197d0/4104d0, -0.2d0, 0d0/)  
       Rc(1:6)=(/1d0/360d0,0d0,-128d0/4275d0,-2197d0/75240d0,1d0/50d0,2d0/55d0/)
    else
       write(6,*)"program stop at rk_preparation"
       stop
    end if
    return
  end subroutine rk_preparation
  !------------------------------
  subroutine rk_deallocation(method)
    implicit none
    character(*)::method
    if(trim(method).eq."rk4")then
       deallocate(a,b1,c)
    elseif(trim(method).eq."rkf45")then
       deallocate(a,b1,b2,c,Rc)
    else
       write(6,*)"program stop at rk_deallocation"
       stop
    end if
    return
  end subroutine rk_deallocation
  !-------------------
  subroutine rkf451(func,N,x,h,y,xbound,info,tol,ik)
   
    !------------
    !info = -2  (Failed. calclation range has already over.)
    !     = -1  (Failed.
    !             h becomes too small. change tol or check condition of func.)
    !     =  0  (Success. running now)
    !     =  1  (Success. x reach xbound normally)
    !------------
    implicit none
    interface
       function func(iN,ix,iy,is,iik)
         implicit none
         integer,intent(in)::iN,is,iik
         double precision,intent(in)::ix,iy(1:iN)
         double precision::func
       end function func
    end interface
    integer,intent(in)::N,ik
    double precision,intent(in)::xbound
    double precision,intent(in)::tol
    double precision,intent(inout)::x,h,y(1:N)
    integer,intent(inout)::info
    double precision,parameter::hmin=1d-14,hmax=1.d0
    integer::i,j,FLAG
    double precision::R,delta,tx,tmp(1:N),K(1:s,1:N),Sy,err
    if(abs(h).ge.hmax)then
       if(h.le.0d0)then
          h=-hmax
       else
          h=hmax
       endif
    endif
    FLAG=1
    if(abs(x-xbound).le.1d-15)then
       info=1
       FLAG=0
    else
       if(abs(h).le.1d-15)then
          write(6,*)"maybe overflow or underflow, please change tol."
          write(6,'(A)')"====Err info===="
          write(6,'(A,e17.9e3)')"x    --> ",x
          write(6,'(A,e17.9e3)')"h    --> ",h
          do i=1,N
             write(6,'(A,i0,A,e17.9e3)')"y(",i,") --> ",y(i)
          enddo
          write(6,'(A)')"================"
          info=-1
          FLAG=0
          stop
       endif
       if(h.le.0d0.and.xbound-x.ge.0d0)then
          info=-2
          FLAG=0
       elseif(h.gt.0d0.and.xbound-x.le.0d0)then
          info=-2
          FLAG=0
       endif
    endif
    do while(FLAG.eq.1)
       tx=x
       do j=1,s
          tx=x+c(j)*h
          tmp(1:N)=y(1:N)
          do i=1,j-1
             tmp(1:N)=tmp(1:N)+K(i,1:N)*a(j,i)
          enddo
          do i=1,N
             K(j,i)=h*func(N,tx,tmp,i,ik)
          enddo
       enddo
       !step 4
       R=0d0
       do i=1,N
          R=R+(Rc(1)*K(1,i)+Rc(3)*K(3,i)+Rc(4)*K(4,i)+Rc(5)*K(5,i)+Rc(6)*K(6,i))**2d0
       enddo
       R=abs(dsqrt(R)/h)
       Sy=0d0
       do i=1,N
          Sy=Sy+(y(i)*y(i))
       enddo
       Sy=dsqrt(Sy)
       if(Sy.ge.1d0)then
          err=tol*Sy
       else
          err=tol
       endif
       !step 5
       if(R.le.err)then
          x=x+h  
          do i=1,s
             y(1:N)=y(1:N)+b1(i)*K(i,1:N)
          enddo
          FLAG=0
       endif
       !step 6
       !  Avoid zero deviding.
       if(R.ge.1d-20)then
          delta=(err/(2d0*R))**0.25d0
       else
          delta=4d0
       endif
       !step 7
       if(delta.le.0.1d0)then
          !function changes dramatically.
          h=0.1d0*h
       elseif(delta.ge.4d0)then
          !function changes loosely.
          h=4d0*h
       else
          !function changes moderately.
          h=delta*h
       endif
       !step 8
       if(abs(h).ge.hmax)then
          if(h.le.0d0)then
             h=-hmax
          else
             h=hmax
          endif
       endif
       !step 9
       if(abs(xbound-x).le.abs(h))then
          h=xbound-x
          if(abs(h).le.hmin)then
             info=1
             FLAG=0
          endif
       end if
    enddo
    return
  end subroutine rkf451
  subroutine rkf451_e(func,x,y,xbound,info,tol,ik)
    !sikinote
    !  propagate from y(x) to y(xbound) without interval
    !
    !  info = -1 : h < hmin. Maybe path the singular point.
    !       =  1 : x reach xbound.
    !
    implicit none
    interface
       function func(iN,ix,iy,is,iik)
         implicit none
         integer,intent(in)::iN,is,iik
         double precision,intent(in)::ix,iy(1:iN)
         double precision::func
       end function func
    end interface
    integer::N,ik
    double precision,intent(in)::xbound,tol
    double precision,intent(inout)::x,y(:)
    integer,intent(inout)::info
    double precision,parameter::hmin=1d-14,hmax=1.d0
    integer::i,j,FLAG,key,disc
    double precision::R,delta,tx,Sy,err,h,h0
    double precision,allocatable::tmp(:),K(:,:)
    disc=0
    key=0
    h0=999d0
    N=size(y,1)
    allocate(tmp(1:N),K(1:s,1:N))
    tmp=0d0; K=0d0  
   
    h=xbound-x   
    if(abs(h).ge.hmax)then
       if(h.le.0d0)then
          h=-hmax
       else
          h=hmax
       endif
    endif
    FLAG=1
    if(abs(x-xbound).le.hmin*0.1d0)then
       info=1
       FLAG=0
    endif
    do while(FLAG.eq.1)
       tx=x
       do j=1,s
          tx=x+c(j)*h
          tmp(1:N)=y(1:N)
          do i=1,j-1
             tmp(1:N)=tmp(1:N)+K(i,1:N)*a(j,i)
          enddo
          do i=1,N
             K(j,i)=h*func(N,tx,tmp,i,ik)
          enddo
       enddo
       !step 4
       R=0d0
       do i=1,N
          R=R+(Rc(1)*K(1,i)+Rc(3)*K(3,i)+Rc(4)*K(4,i)+Rc(5)*K(5,i)+Rc(6)*K(6,i))**2d0
       enddo
       R=abs(dsqrt(R)/h)
       Sy=0d0
       do i=1,N
          Sy=Sy+(y(i)*y(i))
       enddo
       Sy=dsqrt(Sy)
       if(Sy.ge.1d0)then
          err=tol*Sy
       else
          err=tol
       endif
       !step 5
       if(R.le.err.or.key.eq.1)then
          x=x+h
          do i=1,s
             y(1:N)=y(1:N)+b1(i)*K(i,1:N)
          enddo
          key=0
       endif
       !step 6
       !  Avoid zero deviding.
       if(R.ge.1d-20)then
          delta=(err/(2d0*R))**0.25d0
       else
          delta=4d0
       endif
       !step 7
       if(delta.le.0.1d0)then
          !function changes dramatically.
          h=0.1d0*h
       elseif(delta.ge.4d0)then
          !function changes loosely.
          h=4d0*h
       else
          !function changes moderately.
          h=delta*h
       endif
       !step 8
       if(abs(h).ge.hmax)then
          h=sign(1d0,h)*hmax
       elseif(abs(h).lt.hmin)then
          h=sign(1d0,h)*hmin
          key=1
          disc=1
       endif
       
       !step 9
       if(abs(xbound-x).le.abs(h))then
          h=xbound-x
          if(abs(h).le.hmin)then
             info=1
             FLAG=0
          endif
       end if
    enddo
   
    if(disc.eq.1)then
       info=-1
    endif
       
    deallocate(tmp,K)
    return
  end subroutine rkf451_e
end module RKmod
!--------------------
subroutine seeklm(xa,xb,za,zb,nodes,poles,r0,v0,omg0,u0,ik)
  !nodes --> number of nodes
  !poles --> number of local maximam/minimam
  !
  !nodes=0
  !              
  !              
  !    x--------------------------------
  !      \_______  
  !               \______
  !                      \
  !                      orbit of bullet
  !
  !nodes=1
  !   za_____________xa
  !               __/\_                
  !      ________/     \_  
  !     /                \  
  !    x------------------\------------
  !                        \
  !                         \
  !                          \
  !                             \orbit of bullet
  !
  !nodes=2
  !
  !  zb________________ xb                
  !                    /\
  !          xa      /    \  
  !    x-----------/--------\------------
  !      \        /          \
  !        \    /             \
  !  za______\/                \
  !                             \orbit of bullet
  !
  use RKmod
  use GBL
  implicit none
  integer,intent(in)::ik
  double precision,intent(in)::omg0(1:3),r0(1:3),v0(1:3),u0(1:3)
  double precision,intent(out)::xa,xb,za,zb
  integer,intent(out)::nodes,poles
  integer::i,j,info
  integer,parameter::N=12
  double precision::vz0,vz1,vz2,t0,t1,t2,ta,tb,tbef,rz0,rz1
  double precision::x(1:N),tt,th,tx(1:N),bt,bh,bx(1:N)
  double precision::t,h,xbound,rkfd
  external::rkfd
 
  x(1:3)=r0(1:3)
  x(4:6)=v0(1:3)
  x(7:9)=omg0(1:3)
  x(10:12)=u0(1:3)
 
  xbound=10d0
  i=1; t=0d0; h=1d-1; info=0
  info=0; nodes=0; poles=0
 
  xa=0d0; xb=0d0; za=0d0; zb=0d0
 
  call rk_preparation("rkf45")
  do while(info.eq.0)
     tt=t; th=h; tx=x
     rz0=x(3); vz0=x(6); t0=t  
     call rkf451(rkfd,size(x),t,h,x,xbound,info,tol,ik)
     rz1=x(3); vz1=x(6); t1=t
     if(vz0*vz1.lt.0.d0)then
        bt=tt; bh=th; bx=tx
        t0=bt; t2=0.5d0*(2d0*bt+th); t1=bt+th
        do j=1,60
           tt=bt; th=bh; tx=bx
           th=t2-bt
           call rkf451(rkfd,size(tx),tt,th,tx,xbound,info,tol,ik)
           vz2=tx(6)
           if(vz2*vz0.ge.0.d0)then
              t2=t2+0.5d0*(t1-t2)
           else
              tbef=t2
              t2=t2-0.5d0*(t1-t2)
              t1=tbef
           endif
           if(abs(t1-t2)/t1.lt.1d-10)then
              if(poles.eq.0)then
                 ta=t2; xa=tx(1); za=tx(3)
              else
                 tb=t2; xb=tx(1); zb=tx(3)
              endif
              exit
           endif
        enddo
        poles=poles+1
     endif
     if((rz0-r0(3))*(rz1-r0(3)).lt.0d0)then
        nodes=nodes+1
     endif
     
     if(x(3).lt.0d0)then
        info=1
     endif
     i=i+1
  enddo
  call rk_deallocation("rkf45")
 
  return
end subroutine seeklm
subroutine seekzeroin(xa,xb,nodes,r0,v0,omg0,u0,ik)
  !nodes --> number of nodes
  !
  !nodes=0
  !              
  !              
  !    x--------------------------------
  !      \_______  
  !               \______
  !                      \
  !                      orbit of bullet
  !
  !nodes=1
  !
  !               __/\_                
  !      ________/     \_  
  !     /                \ xa
  !    x------------------\------------
  !                        \
  !                         \
  !                          \
  !                             \orbit of bullet
  !
  !nodes=2
  !
  !
  !                    /\
  !              xa  /    \  xb
  !    x-----------/--------\------------
  !      \        /          \
  !        \    /             \
  !          \/                \
  !                             \orbit of bullet
  !
  use RKmod
  use GBL
  implicit none
  integer,intent(in)::ik
  double precision,intent(in)::omg0(1:3),r0(1:3),v0(1:3),u0(1:3)
  double precision,intent(out)::xa,xb
  integer,intent(out)::nodes
 
  integer::i,j,info
  integer,parameter::N=12
  double precision::rz0,rz1,rz2,t0,t1,t2,ta,tb,tbef,rzini
  double precision::x(1:N),tt,th,tx(1:N),bt,bh,bx(1:N)
  double precision::t,h,xbound,rkfd
  external::rkfd
  rzini=r0(3)
  x(1:3)=r0(1:3)
  x(4:6)=v0(1:3)
  x(7:9)=omg0(1:3)
  x(10:12)=u0(1:3)
  xbound=10d0
  i=1; t=0d0; h=1d-1; info=0
  info=0; nodes=0
 
  xa=0d0; xb=0d0
 
  call rk_preparation("rkf45")
  !-----1step-----
  call rkf451(rkfd,size(x),t,h,x,xbound,info,tol,ik)
  !----------------
  do while(info.eq.0)
     tt=t; th=h; tx=x
     rz0=x(3); t0=t  
     call rkf451(rkfd,size(x),t,h,x,xbound,info,tol,ik)
     rz1=x(3); t1=t
     
     if(rz0-rzini.lt.0.d0.neqv.rz1-rzini.lt.0.d0)then
        bt=tt; bh=th; bx=tx
        t0=bt; t2=0.5d0*(2d0*bt+th); t1=bt+th
        do j=1,60
           tt=bt; th=bh; tx=bx
           th=t2-bt
           call rkf451(rkfd,size(tx),tt,th,tx,xbound,info,tol,ik)
           rz2=tx(3)
           if(rz2-rzini.lt.0.d0.eqv.rz0-rzini.lt.0.d0)then
              t2=t2+0.5d0*(t1-t2)
           else
              tbef=t2
              t2=t2-0.5d0*(t1-t2)
              t1=tbef
           endif
           if(abs(t1-t2)/t1.lt.1d-10)then
              if(nodes.eq.0)then
                 ta=t2; xa=tx(1)
              else
                 tb=t2; xb=tx(1)
              endif
              nodes=nodes+1
              exit
           endif
        enddo
     endif
     if(x(3).lt.0d0)then
        info=1
     endif
     i=i+1
  enddo
  call rk_deallocation("rkf45")
 
  return
end subroutine seekzeroin
subroutine detwy(energy,r,vy,omgx,omgz,u,zeroinx,exwy,exvz,ik)
  implicit none
  integer,intent(in)::ik
  double precision,intent(in)::energy,zeroinx
  double precision,intent(in)::r(1:3),omgx,omgz,u(1:3),vy
  double precision,intent(out)::exwy,exvz 
  integer::Nr,count,Nsplit
  double precision,parameter::pi=dacos(-1d0)
  double precision,allocatable::rd(:)
  double precision::ad,bd,wycond
  external::wycond
 
  ad=-800d0*2d0*pi; bd=2d0*pi; Nsplit=25; Nr=1
  allocate(rd(1:Nr))
  rd(1:Nr)=0d0
  count=0
  call rootfindingw(wycond,energy,r,vy,omgx,omgz,u,zeroinx,ad,bd,Nsplit,Nr,rd,exvz,count,"bisection",1)
  exwy=rd(1)
  if(ik.eq.0)then  
     ad=exwy-5d0*2d0*pi; bd=exwy+5d0*2d0*pi; Nsplit=1; Nr=1
     rd(1:Nr)=0d0
     count=0
     call rootfindingw(wycond,energy,r,vy,omgx,omgz,u,zeroinx,ad,bd,Nsplit,Nr,rd,exvz,count,"false_position",0)
     exwy=rd(1)
  endif
  deallocate(rd)
  return
end subroutine detwy
!--------------------------
function wycond(energy,r,vy,omgx,omgy,omgz,u,zeroinx,exvz,ik)
  use GBL, only:m
  implicit none
  integer,intent(in)::ik
  double precision,intent(in)::energy,r(1:3),u(1:3),vy,omgx,omgy,omgz,zeroinx
  double precision,intent(out)::exvz
  integer::nodes
  double precision::zeroinx1,zeroinx2,wycond,v(1:3),omg(1:3)
 
  omg(1)=omgx; omg(2)=omgy; omg(3)=omgz
  call detvz(energy,r,vy,omg,u,exvz,ik)
  v(1)=dsqrt((2d0*energy/m)-exvz**2-vy**2)
  v(2)=vy
  v(3)=exvz
  call seekzeroin(zeroinx1,zeroinx2,nodes,r,v,omg,u,ik)
  if(zeroinx2.ge.1d-10)then
     wycond=zeroinx2-zeroinx
  else
     wycond=2d0*zeroinx
  endif
     
  return
end function wycond
!------------------------------
subroutine detwy2(energy,r,vy,omgx,omgz,u,udh,exwy,exvz,ik)  
  implicit none
  integer,intent(in)::ik
  double precision,intent(in)::energy,udh,r(1:3),omgx,omgz,u(1:3),vy
  double precision,intent(out)::exwy,exvz
  integer::Nr,count,Nsplit
  double precision,parameter::pi=dacos(-1d0)
  double precision,allocatable::rd(:)
  double precision::ad,bd,wycond2
  external::wycond2
 
  ad=-1000d0*2d0*pi; bd=2d0*pi; Nsplit=25; Nr=1
  allocate(rd(1:Nr))
  rd(1:Nr)=0d0
  count=0 
  call rootfindingw(wycond2,energy,r,vy,omgx,omgz,u,udh,ad,bd,Nsplit,Nr,rd,exvz,count,"bisection",1)
  exwy=rd(1)
  if(ik.eq.0)then
     ad=exwy-5d0*2d0*pi; bd=exwy+5d0*2d0*pi; Nsplit=1; Nr=1
     count=0; rd(1:Nr)=0d0
     call rootfindingw(wycond2,energy,r,vy,omgx,omgz,u,udh,ad,bd,Nsplit,Nr,rd,exvz,count,"false_position",0)
     exwy=rd(1)
  endif
  deallocate(rd) 
  return
end subroutine detwy2
!--------------------------
function wycond2(energy,r,vy,omgx,omgy,omgz,u,udh,exvz,ik)
  use GBL, only:m
  implicit none
  integer,intent(in)::ik
  double precision,intent(in)::energy,r(1:3),u(1:3),vy,omgx,omgy,omgz,udh
  double precision,intent(out)::exvz
  integer::nodes,poles
  double precision::xa,xb,za,zb,z0,wycond2,v(1:3),omg(1:3)
 
  omg(1)=omgx; omg(2)=omgy; omg(3)=omgz
  call detvz(energy,r,vy,omg,u,exvz,ik)
  v(1)=dsqrt((2d0*energy/m)-exvz**2-vy**2)
  v(2)=vy
  v(3)=exvz
 
  z0=r(3)
  call seeklm(xa,xb,za,zb,nodes,poles,r,v,omg,u,ik)
  if(poles.eq.0.or.za.lt.0d0)then
     wycond2=10d0
  elseif(poles.eq.1)then
     wycond2=za-z0
  elseif(poles.eq.2)then
     wycond2=zb-za
  else
     write(6,*)"unknown,poles-->",poles
     stop
  endif
  wycond2=wycond2-udh
 
  return
end function wycond2
!-------------------------
subroutine detvz(energy,r,vy,omg,u,exvz,ik)  
  implicit none
  integer,intent(in)::ik
  double precision,intent(in)::energy
  double precision,intent(in)::r(1:3),omg(1:3),u(1:3),vy
  integer::Nr,count,Nsplit
  double precision,intent(out)::exvz
 
  double precision,allocatable::rd(:)
  double precision::ad,bd,vzcond
  external::vzcond
 
  ad=-30d0; bd=1d0; Nsplit=80; Nr=1
  allocate(rd(1:Nr))
  rd(1:Nr)=0d0
  count=0
  call vzroot(vzcond,energy,r,vy,omg,u,ad,bd,Nsplit,Nr,rd,count,ik)
  exvz=rd(1)
 
  return
end subroutine detvz
!------------------------
function vzcond(energy,r,vy,vz,omg,u,ik)
  use GBL, only:m
  implicit none
  integer,intent(in)::ik
  double precision,intent(in)::energy,r(1:3),vy,vz,omg(1:3),u(1:3)
  double precision::vzcond,v(1:3)
  integer::nodes,poles
  double precision::xa,xb,za,zb,z0
 
  v(1)=dsqrt((2d0*energy/m)-vz**2-vy**2)
  v(2)=vy
  v(3)=vz
  z0=r(3)
  call seeklm(xa,xb,za,zb,nodes,poles,r,v,omg,u,ik)
  if(poles.eq.0)then
     vzcond=-z0-1d0
  elseif(poles.eq.1)then
     vzcond=za-z0
  elseif(poles.eq.2)then
     vzcond=za+zb-2d0*z0
  else
     write(6,*)"unknown,poles-->",poles
     stop
  endif
 
  return
end function vzcond
!--------------------
subroutine vzroot(func,energy,r,vy,omg,u,ad,bd,Nsplit,Nr,rd,count,ik)
  !Developer : sikino
  use GBL
  implicit none
  interface
     function func(ienergy,ir,ivy,ivz,iomg,iu,iik)
       implicit none
       integer,intent(in)::iik
       double precision,intent(in)::ienergy,ir(1:3),ivy,ivz,iomg(1:3),iu(1:3)
       double precision::func
     end function func
  end interface
  integer,intent(in)::Nr,Nsplit,ik
  double precision,intent(in)::ad,bd,energy,r(1:3),vy,omg(1:3),u(1:3)
  integer,intent(out)::count
  double precision,intent(out)::rd(1:Nr)
 
  integer::N,i,j 
  double precision::h,hd,x0,x1,x2,y0,y1,y2,Dy0,tx1,ty1
  !ad < bd
  if(ad.ge.bd)then
     write(6,'(A,2e15.6e3)')"must be ad < bd, your ad,bd --> ",ad,bd
     write(6,'(A)')"program stop at rootfinding"
     stop
  end if
 
  N=Nsplit
  hd=abs(ad-bd)/dble(N)
  count=0
  x0=ad
  y0=func(energy,r,vy,x0,omg,u,ik)
  do i=1,N
     x1=x0+hd
     y1=func(energy,r,vy,x1,omg,u,ik)
     if(y0.lt.0.d0.neqv.y1.lt.0.d0)then
        tx1=x1
        ty1=y1
        
        !bisection rule
        do j=1,60
           x2=0.5d0*(x0+x1)
           y2=func(energy,r,vy,x2,omg,u,ik)
           if(y2.lt.0.d0.eqv.y0.lt.0.d0)then
              x0=x2
           else
              x1=x2
           endif
           if(abs((x1-x0)/x2).lt.eps)then
              if(y2.le.1d0)then
                 count=count+1
                 rd(count)=x2
                 exit
              endif
           endif
        enddo
        if(j.eq.61)write(6,*)"+--cannot convergence at root-finding method bs--+"
        
        if(count.ge.Nr)exit
        x1=tx1
        y1=ty1
     endif
     x0=x1
     y0=y1
  enddo
  return
end subroutine vzroot
subroutine rootfindingw(func,energy,r,vy, &
     omgx,omgz,u,zeroinx,ad,bd,Nsplit,Nr,rd,exvz,count,method,ik)
  !Date : 2015/07/28
  !Developer : sikino
  use GBL
  implicit none
  interface
     function func(ienergy,ir,ivy,iomgx,iomgy,iomgz,iu,izin,iexvz,iik)
       implicit none
       integer,intent(in)::iik
       double precision,intent(in)::ienergy,ir(1:3),ivy,iomgx,iomgy,iomgz,izin,iu(1:3)
       double precision,intent(out)::iexvz
       double precision::func
     end function func
  end interface
  integer,intent(in)::Nr,Nsplit,ik
  double precision,intent(in)::ad,bd,energy,r(1:3),vy,u(1:3)
  double precision,intent(in)::omgx,omgz,zeroinx
  integer,intent(out)::count
  double precision,intent(out)::rd(1:Nr),exvz
  double precision,parameter::pi=dacos(-1d0)
  character(*),intent(in)::method
 
  integer::N,i,j
               
  double precision::h,hd,x0,x1,x2,y0,y1,y2,Dy0,tx1,ty1
  !ad < bd
  if(ad.ge.bd)then
     write(6,'(A,2e15.6e3)')"must be ad < bd, your ad,bd --> ",ad,bd
     write(6,'(A)')"program stop at rootfinding"
     stop
  end if
  !Announsment
  write(6,'(A,A)')" ---- ",trim(method)
 
  N=Nsplit
  hd=abs(ad-bd)/dble(N)
  count=0
  x0=ad
  y0=func(energy,r,vy,omgx,x0,omgz,u,zeroinx,exvz,ik)
  do i=1,N
     x1=x0+hd
     y1=func(energy,r,vy,omgx,x1,omgz,u,zeroinx,exvz,ik)
     write(6,'(A,i0,A,i0,A,f14.8,A,f14.8)')" Sequence ",i," of ",N," : omgy/2pi ",x1/2d0/pi, " : zeroin ",y1
     if(y0.lt.0.d0.neqv.y1.lt.0.d0)then
        write(6,'(A)')"  +--- Root find, go to conversion phase --+  "
        tx1=x1
        ty1=y1
        if(trim(method).eq."bisection")then
           !bisection rule
           do j=1,60              
              x2=0.5d0*(x0+x1)
              y2=func(energy,r,vy,omgx,x2,omgz,u,zeroinx,exvz,ik)
              if(y2.lt.0.d0.eqv.y0.lt.0.d0)then
                 x0=x2
              else
                 x1=x2
              endif
              write(6,'(A,f16.8,A)')"Conversion => ",eps*abs(x2/(x1-x0))*100d0,"%"
              if(abs((x1-x0)/x2).lt.eps)then
                 !If y2 is large, y2 is singular point.  
                 if(y2.le.1d0)then
                    count=count+1
                    rd(count)=x2
                 endif
                 exit
              endif
           enddo
           if(j.eq.60)write(6,*)"+--cannot convergence at root-finding method bs--+"
        elseif(trim(method).eq."newton_raphson")then
           !Newton-Raphson method
           do j=1,10
              h=1.d-4
              y0=func(energy,r,vy,omgx,x0,omgz,u,zeroinx,exvz,ik)
              Dy0=(func(energy,r,vy,omgx,x0+h,omgz,u,zeroinx,exvz,ik)-y0)/h
              x2=x0-y0/Dy0
              if(abs((x0-x2)/x2).lt.eps)then
                 if(y0.le.1d0)then
                    count=count+1
                    rd(count)=x2
                 endif
                 exit
              endif
              x0=x2
           enddo
           if(j.eq.10)write(6,*)"+--cannot convergence at root-finding method nr--+"
        elseif(trim(method).eq."false_position")then
           !false position method
           if(abs(y1).gt.abs(y0))then
              do j=1,30
                 x2=x0-y0*(x1-x0)/(y1-y0)
                 write(6,'(A,f16.8,A)')"Conversion => ",eps*abs(x2/(x2-x0))*100d0,"%"
                 if(abs((x2-x0)/x2).lt.eps)then
                    if(y0.le.1d0)then
                       count=count+1
                       rd(count)=x2
                    end if
                    exit
                 endif
                 x0=x2
                 y0=func(energy,r,vy,omgx,x0,omgz,u,zeroinx,exvz,ik)
              enddo
           else
              do j=1,30
                 x2=x0-y0*(x1-x0)/(y1-y0)
                 write(6,'(A,f15.8,A)')"Conversion => ",eps*abs(x2/(x1-x2))*100d0,"%"
                 if(abs((x2-x1)/x2).lt.eps)then
                    if(y1.le.1d0)then
                       count=count+1
                       rd(count)=x2
                    endif
                    exit
                 endif
                 x1=x2
                 y1=func(energy,r,vy,omgx,x1,omgz,u,zeroinx,exvz,ik)
              enddo
           endif
           if(j.eq.30)write(6,*)"+--cannot convergence at root-finding method fp--+"
        else
           write(6,'(A,A)')"unknown type of method, your method--> ",trim(method)
           write(6,'(A,A)')"program stop"
           stop
        end if
        if(count.ge.Nr)exit
        x1=tx1
        y1=ty1
     endif
     x0=x1
     y0=y1
  enddo
  return
end subroutine rootfindingw
!---------------------------
function rkfd(N,t,x,s,ik)
  use GBL
  implicit none
  integer,intent(in)::N,s,ik
  double precision,intent(in)::t,x(1:N)
  double precision::r(1:3),v(1:3),relv(1:3),omg(1:3),u(1:3),nw,nv,I
  double precision::rkfd,gravity,vis1,vis2,mag,Nz,Nze
  double precision,parameter::pi=datan(1d0)*4d0
  external::gravity,vis1,vis2,mag,Nz,Nze
 
  r(1:3)=x(1:3)
  v(1:3)=x(4:6)
  omg(1:3)=x(7:9)
  u(1:3)=x(10:12)
  relv(1:3)=v(1:3)-u(1:3)
 
  rkfd=0.d0
  if(s.le.3)then
     ! Differential equation of position
     ! d {x,y,z}/dt = v{x,y,z}
     rkfd=v(s)
  elseif(s.le.6)then
     ! Differential equation of velocity
     ! d v_{x,y,z}/dt = F{x,y,z}
     rkfd=gravity(s-3,m,g,r)+vis1(s-3,relv,a,eta) &
          +vis2(s-3,relv,a,eta,rho)+mag(s-3,omg,relv,a,rho)
     rkfd=rkfd/m
  elseif(s.le.9)then
     ! Differential equation for omega
     ! d omega{x,y,z}/dt = N_{x,y,z}/I
     if(trim(omgdecay).eq."yes")then
        I=0.4d0*m*a*a
        nv=dsqrt(relv(1)**2+relv(2)**2+relv(3)**2)
        nw=dsqrt(omg(1)**2+omg(2)**2+omg(3)**2)
        if(nw.le.1d-13)then
           rkfd=0d0
        else
           if(ik.eq.0)then
              rkfd=(Nz(nv,a,eta,rho,nw)/I)*x(s)/nw
           else
              rkfd=(Nze(nv,a,eta,rho,nw)/I)*x(s)/nw
           end if
        endif
     else
        rkfd=0d0
     endif
  else
     ! Differential equation for wind
     ! d u{x,y,z}/dt = Fu_{x,y,z}
     rkfd=0d0
  endif
 
  return
end function rkfd
!-----------------------------
function gravity(dir,m,g,r)
  implicit none
  integer,intent(in)::dir
  double precision::gravity
  double precision,intent(in)::m,g,r(1:3)
 
  if(dir.eq.3)then
     gravity=-m*g
  else
     gravity=0.d0
  endif
 
  return
end function gravity
!-------------------------------
function c1(a,eta)
  implicit none
  double precision::c1
  double precision,intent(in)::eta,a
  double precision,parameter::pi=dacos(-1.d0)
  c1=6.d0*pi*eta*a
 
  return
end function c1
!------------------------------
function c2(nv,a,eta,rho)
  implicit none
  double precision,parameter::pi=dacos(-1.d0)
  double precision,intent(in)::nv,eta,a,rho
  double precision::Cd,Reynolds,c2
  external::Cd,Reynolds
  c2=0.5d0*Cd(Reynolds(nv,a,eta,rho))*rho*pi*a*a
 
  return
end function c2
!-----------------------------
function vis1(dir,v,a,eta)
  implicit none
  integer,intent(in)::dir
  double precision,intent(in)::v(1:3),a,eta
  double precision::vis1,norm,nv,c1
  external::c1
 
  nv=dsqrt(v(1)**2.d0+v(2)**2.d0+v(3)**2.d0)
  norm=c1(a,eta)*nv
 
  vis1=-norm*v(dir)/nv
 
  return
end function vis1
!-------------------------
function vis2(dir,v,a,eta,rho)
  implicit none
  integer,intent(in)::dir
  double precision,intent(in)::v(1:3),a,eta,rho
  double precision::vis2,norm,nv,c2
  external::c2
 
  nv=dsqrt(v(1)*v(1)+v(2)*v(2)+v(3)*v(3))
  norm=c2(nv,a,eta,rho)*nv*nv
 
  vis2=-norm*v(dir)/nv
 
  return
end function vis2
!--------------------------
function mag(dir,omg,v,a,rho)
  implicit none
  integer,intent(in)::dir
  double precision,intent(in)::omg(1:3),v(1:3),a,rho
  double precision,parameter::pi=dacos(-1.d0)
  double precision::mag,L(1:3),nomg,nv,nL,Cl
 
  nomg=dsqrt(omg(1)*omg(1)+omg(2)*omg(2)+omg(3)*omg(3))
  if(nomg.le.1.d-14)then
     mag=0.d0
     return
  endif
 
  nv=dsqrt(v(1)*v(1)+v(2)*v(2)+v(3)*v(3))
  L(1)=v(2)*omg(3)-v(3)*omg(2)
  L(2)=v(3)*omg(1)-v(1)*omg(3)
  L(3)=v(1)*omg(2)-v(2)*omg(1)
  nL=dsqrt(L(1)*L(1)+L(2)*L(2)+L(3)*L(3))
  if(nL.le.1.d-14)then
     mag=0.d0
     return
  endif
 
  ! for BB bullet
  Cl=0.12d0
  mag=-Cl*(4.d0/3.d0)*pi*(a**3d0)*2.d0*rho*nomg*nv*L(dir)/nL
 
  return
end function mag
!--------------------------
function Reynolds(nv,a,eta,rho)
  !Reynolds number
  ! nv : norm of velocity of object
  !  a : radius of object
  !eta : viscosity (not Kinetic viscosity)
  !rho : density of fluid
  implicit none
  double precision,intent(in)::nv,a,eta,rho
  double precision::keta,Reynolds
 
  !keta means Kinetic viscosity
  keta=eta/rho
 
  Reynolds=nv*2.d0*a/keta
 
  return
end function Reynolds
!---------------------------
function Cd(Re)
  !From
  !http://www.chem.mtu.edu/~fmorriso/DataCorrelationForSphereDrag2013.pdf
  !Drag coefficient Cd,
  !Cd depend on Reynolds number,Re.
  !Fource of Drug,D is written by
  !     1
  ! D= ---Cd*rho*pi*a**2*|V|**2
  !     2
  !        ^ This Cd!
  implicit none
  double precision,intent(in)::Re
  double precision::Cd,c1,c2,c3,c4
 
  c1=24.d0/Re
  c2=Re/5.d0
  c2=2.6d0*c2/(1.d0+c2**(1.52d0))
  c3=Re/263000d0
  c3=0.411d0*c3**(-7.94d0)/(1.d0+c3**(-8d0))
  c4=Re**0.8d0/461000d0
 
  Cd=c1+c2+c3+c4
 
  return
end function Cd
!----------------------------
function Nz(nv,a,eta,rho,omg)
  !Moment of omg direction
  implicit none
  double precision,intent(in)::nv,a,eta,rho,omg
  double precision::Nz,Cf,Fintegral
  external::Cf,Fintegral
 
  Nz=0.5d0*rho*Cf(nv,a,eta,rho)*a**3
  Nz=Nz*Fintegral(nv,a,omg)
 
  return
end function Nz
function Nze(nv,a,eta,rho,omg)
  implicit none
  double precision,intent(in)::nv,a,eta,rho,omg
  double precision::Nze,Cf,Fintegral
  double precision,parameter::pi=atan(1d0)*4d0
  external::Cf,Fintegral
  double precision::pc,tc,vu,vd,t
  pc=pi/5.32065d0 ! magic phi
  tc=pi/3.60475d0 ! magic theta
  
  vu= nv*sin(pc)-a*omg*sin(tc)
  vd=-nv*sin(pc)-a*omg*sin(tc)
  Nze=-0.5d0*rho*Cf(nv,a,eta,rho)
  Nze=Nze*(4d0*pi*a**2)*a*0.5d0
  Nze=-Nze*(abs(vu)*vu+abs(vd)*vd)
  
  return
end function Nze
!-------------------
function Cf(nv,a,eta,rho)
  implicit none
  ! nv : norm of velocity of object
  !  a : radius of object
  !eta : viscosity (not Kinetic viscosity)
  !rho : density of fluid
  double precision,intent(in)::nv,a,eta,rho
  double precision::Reynolds,Cf
  external::Reynolds
  ! Laminar flow
  Cf=1.328d0/dsqrt(Reynolds(nv,a,eta,rho))
 
  ! Turbulent flow Re > 10^7
  !Cf=0.455d0/(log10(Reynolds(nv,a,eta,rho))**(2.58d0))
 
  return
end function Cf
!----------------------------------
function Fintegral(u,R,omega)
  ! 2016/07/23
  !   2pi     pi
  !  /       /
  !  | dphi  | |u*sin(phi)-R*omega*sin(theta)|*{u*sin(phi)-R*omega*sin(theta)}*sin^2(theta) d theta
  !  /       /
  !  0      0
  implicit none
  double precision,intent(in)::u,R,omega
  double precision,parameter::pi=datan(1.d0)*4d0
  double precision::Fintegral,s,Fphi,x(1:15),w(1:15)
  external::Fphi
  integer::i
  s=0d0
  call GaussKronrod15ab(0d0,pi,x,w)
  do i=1,15
     s=s+w(i)*Fphi(u,R,omega,x(i))
  enddo
  call GaussKronrod15ab(pi,2d0*pi,x,w)
  do i=1,15
     s=s+w(i)*Fphi(u,R,omega,x(i))
  enddo    
  Fintegral=s  
 
  return
end function Fintegral
!------------------------------
subroutine GaussKronrod15ab(a,b,x,w)
  !Gauss-Kronrod Quadrature Nodes and Weights
  !http://www.advanpix.com/2011/11/07/gauss-kronrod-quadrature-nodes-weights/
  implicit none
  double precision,intent(in)::a,b
  double precision,intent(out)::x(1:15),w(1:15)
 
  integer::i
  integer,parameter::N=15
 
  x=0d0; w=0d0
 
  x( 8) = 0d0
  x( 9) = 2.077849550078984676006894037732449d-1
  x(10) = 4.058451513773971669066064120769615d-1
  x(11) = 5.860872354676911302941448382587296d-1
  x(12) = 7.415311855993944398638647732807884d-1
  x(13) = 8.648644233597690727897127886409262d-1
  x(14) = 9.491079123427585245261896840478513d-1
  x(15) = 9.914553711208126392068546975263285d-1  
  do i=1,7
     x(i)=-x(N-i+1)
  enddo
 
  w( 8) = 2.094821410847278280129991748917143d-1
  w( 9) = 2.044329400752988924141619992346491d-1
  w(10) = 1.903505780647854099132564024210137d-1
  w(11) = 1.690047266392679028265834265985503d-1
  w(12) = 1.406532597155259187451895905102379d-1
  w(13) = 1.047900103222501838398763225415180d-1
  w(14) = 6.309209262997855329070066318920429d-2
  w(15) = 2.293532201052922496373200805896959d-2
  do i=1,7
     w(i)=w(N-i+1)
  enddo
 
  x=0.5d0*((b-a)*x+(a+b))
  w=0.5d0*(b-a)*w
 
  return
end subroutine GaussKronrod15ab
!----------------------------------------
function Fphi(u,R,omega,phi)
  ! using analysis solution.
  !
  !   pi
  !  /
  !  | |u*sin(phi)-R*omega*sin(theta)|*{u*sin(phi)-R*omega*sin(theta)}*sin^2(theta) d theta
  !  /
  !  0
  !
  implicit none
  double precision,intent(in)::u,R,omega,phi
  double precision,parameter::pi=dacos(-1d0)
  double precision::a,b,c,tp,Fphi,Rw
  a=(u/(R*omega))*sin(phi)
 
  if(a.le.0d0)then
     Fphi=-(0.5d0*a*a*pi-8d0*a/3d0+3d0*pi/8d0)
  elseif(a.ge.1d0)then
     Fphi=0.5d0*a*a*pi-8d0*a/3d0+3d0*pi/8d0
  elseif(a.gt.0d0.and.a.lt.1d0)then
     tp=asin(a)
     b=-a*a*pi*0.5d0-8d0*a/3d0-3d0*pi/8d0+(2d0*a*a+3d0/2d0)*tp
     c=-(a*a+1d0)*dsin(2d0*tp)+dsin(4d0*tp)/8d0+6d0*a*dcos(tp)-2d0*a*dcos(3d0*tp)/3d0
     Fphi=b+c
  else
     write(6,*)"undefined at Fphi, program stop",a
     stop
  endif
 
  Rw=R*omega
  Fphi=Fphi*Rw*abs(Rw)
  return
end function Fphi
!---------------------------------
subroutine bullet_orbit(N,x0,Nt,time,filename,ik)
  !sikinote http://slpr.sakura.ne.jp/qp/
  !Author : sikino
  !Date   : 2016/03/18 (yyyy/mm/dd)
  !       : 2016/03/20
  use GBL
  use RKmod
  implicit none
  integer,intent(in)::ik,N,Nt
  double precision,intent(in)::x0(1:N),time(0:Nt)
  character(*),intent(in)::filename
  double precision,parameter::pi=datan(1d0)*4d0
  integer::info,i,j
  double precision::x(1:N),Ene,h,t,tbound,rkfd
  external::rkfd
  x=x0
  info=0
  t=time(0)
  open(22,file=trim(filename),status='replace')
  write(22,'(A,e12.5e1,A)')"# m:  ",m,"[kg]"
  write(22,'(A,f12.5,A)')"# g:  ",g,"[m s^{-2}]"
  write(22,'(A,e12.5e1,A)')"# a:  ",a,"[m]"
  write(22,'(A,f12.5,A)')"# temperature:  ",temperature,"[degree Celsius]"
  write(22,'(A,f12.5,A)')"# moisture:  ",moisture,"[no-dimension]"
  write(22,'(A,f12.5,A)')"# pressure:  ",pressure,"[Pa]"
  write(22,'(A,e12.5e1,A)')"# eta:",eta,"[kg m^{-1} s^{-1}]"
  write(22,'(A,f12.5,A)')"# rho:",rho,"[kg m^{-3}]"
  write(22,'(A,e12.5e1)')"# tol:",tol
  write(22,'(A,e12.5e1)')"# eps:",eps
  write(22,'(A,14A13)')"#","t[s]","x[m]","y[m]","z[m]","vx[m/s]","vy[m/s]","vz[m/s]" &
   ,"wx[rot/s]","wy[rot/s]","wz[rot/s]","windx[m/s]","windy[m/s]","windz[m/s]","Energy[J]"
  Ene=0.5d0*m*(x(4)**2+x(5)**2+x(6)**2)
  write(22,'(14f13.6)')t,(x(i),i=1,6),(x(i)/(2d0*pi),i=7,9),(x(i),i=10,12),Ene
 
  call rk_preparation("rkf45")
  do j=0,Nt-1
     t=time(j); tbound=time(j+1); h=tbound-t
     call rkf451_e(rkfd,t,x,tbound,info,tol,ik)
             
     Ene=0.5d0*m*(x(4)**2+x(5)**2+x(6)**2)
     write(22,'(14f13.6)')t,(x(i),i=1,6),(x(i)/(2d0*pi),i=7,9),(x(i),i=10,12),Ene
     !Stop calculation when bullet reach ground.
     if(x(3).lt.0d0)exit
  enddo
  call rk_deallocation("rkf45")
 
  close(22)
  write(6,'(A,e10.3)')"Reach ground at ",t
 
  return
end subroutine bullet_orbit
program main
  use GBL
  implicit none
  integer::i,N,Nt,ik
  double precision,allocatable::x(:),time(:),r(:),u(:)
  double precision,parameter::pi=datan(1d0)*4d0
  double precision::rx,ry,rz,vx,vy,vz,ux,uy,uz,omgx,omgy,omgz
  double precision::energy,zeroinx,updownz,stept,exvz,exwy,theta
  character(48)::outputfile,filename,search_zeroin,search_updown
  double precision::tbound
  double precision::rho_humid,eta_air
  double precision::r0(1:3),v0(1:3),omg0(1:3),u0(1:3)
  external::rho_humid,eta_air
  
  double precision::xa,xb,za,zb
  integer::nodes,poles
  real::t1,t0
  
  namelist /input/m,a,energy,g,temperature,pressure,moisture &
       ,omgdecay,search_zeroin,zeroinx,search_updown,updownz &
       ,theta,rx,ry,rz,vy,ux,uy,uz,omgx,omgy,omgz &
       ,stept,outputfile,ik
 
  open(10,file="./input")
  read(10,nml=input)
  close(10)
  write(*,nml=input)
  N=12
  eta=eta_air(temperature)
  rho=rho_humid(temperature,pressure,moisture)
 
  vx=dsqrt((2d0*energy/m)-vy**2)*dcos(pi*theta/180d0)
  vz=dsqrt((2d0*energy/m)-vy**2)*dsin(pi*theta/180d0)
  omgx=omgx*2*pi
  omgy=omgy*2*pi
  omgz=omgz*2*pi
  allocate(x(1:N))
  x(1)=rx;  x(4)=vx;  x(7)=omgx;  x(10)=ux
  x(2)=ry;  x(5)=vy;  x(8)=omgy;  x(11)=uy
  x(3)=rz;  x(6)=vz;  x(9)=omgz;  x(12)=uz
 
  tbound=100d0
  Nt=nint(tbound/stept)
  allocate(time(0:Nt)); time=0d0
  do i=0,Nt
     time(i)=dble(i)*stept
  enddo
  filename=trim(outputfile)//".txt"
  call bullet_orbit(N,x,Nt,time,filename,ik)
  
  call cpu_time(t0)
  if(trim(search_zeroin).eq."yes")then
     write(6,'(A)')"==============================="
     write(6,'(A,f10.5)')" search vz and wy by zeroin --> ", zeroinx
     allocate(r(1:3),u(1:3)); r(1:3)=x(1:3); u(1:3)=x(10:12)
     call detwy(energy,r,x(5),x(7),x(9),u,zeroinx,exwy,exvz,ik)
     write(6,*)exwy/(2d0*pi),exvz
     x(4)=dsqrt((2d0*energy/m)-exvz**2-vy**2)
     x(5)=vy
     x(6)=exvz
     x(8)=exwy
     filename=trim(outputfile)//"_opt.txt"
     call bullet_orbit(N,x,Nt,time,filename,ik)
     deallocate(r,u)
  endif
  if(trim(search_updown).eq."yes")then
     write(6,'(A)')"==============================="
     write(6,'(A,f10.5)')" search vz and wy by up-down height --> ", updownz
     allocate(r(1:3),u(1:3)); r(1:3)=x(1:3); u(1:3)=x(10:12)
     call detwy2(energy,r,x(5),x(7),x(9),u,updownz,exwy,exvz,ik)
     write(6,*)exwy/(2d0*pi),exvz
     x(4)=dsqrt((2d0*energy/m)-exvz**2-vy**2)
     x(5)=vy
     x(6)=exvz
     x(8)=exwy
     filename=trim(outputfile)//"_h.txt"
     call bullet_orbit(N,x,Nt,time,filename,ik)
     deallocate(r,u)
  endif
  call cpu_time(t1)
  write(6,'(f10.3,A)')(t1-t0),"[CPU sec]"
 
  stop
end program main