プログラム




以下のサンプルプログラムでは、容器は実際のペットボトルに近い、半径4.5cm、長さ25cm、質量60gの円柱とします。
また、噴出口の半径を1.0cmとし、ペットボトルは出口に近付くにつれて断面が狭くなるような形をしているので、
実際の1/2の有効断面積を用います。

  program main
  implicit none
  
  integer(kind=4),parameter:: neq=3         !解く方程式の数
  integer(kind=4),parameter:: nmax=10000
  
  real(kind=8),parameter:: eps=1.0d-10
  
  external ex2,ex1
  common S,S1,P0,PA,M0,L,H,RHO,x0,g,M    !ex1,ex2と共通の変数

  real(kind=8),dimension(neq):: y0,yn
  real(kind=8) t0,tn,dt
  real(kind=8) S,S1,P0,PA,M0,L,H,RHO,T_0       !新たな変数の定義
  real(kind=8) x0,v,P,F,M,A,g,E,W,T            !新たな変数の定義
  
  real(kind=8),dimension(neq,12):: work
  
  integer(kind=4) ierr,i,n
  
  character(len=12) fname1,fname2    !ファイル名
  
  
  write(*,'(a,$)') 'filename1 ?'         !ファイル名の入力
  read(*,*) fname1

  write(*,'(a,$)') 'filename2 ?'
  read(*,*) fname2
  
  open(9,file=fname1)
  open(10,file=fname2)
  
  n=0
  t0=0.0d0
  dt=0.01d0
 
  S=0.00031/2.                
  S1=0.0064
  P0=200000
  PA=100000                     !初期条件などの入力(MKS単位系)
  M0=0.06                       
  L=0.25
  x0=0.2
  H=1.4
  RHO=1000
  T_0=300
  g=9.8
  
  y0(1) = x0               !ペットボトル内の水面の位置
  y0(2) = 0                !ペットボトルの速度
  y0(3) = 0.               !ペットボトルの高さ
  
  V=sqrt(2.*(P0-PA)/RHO)    !(1)式
  F=RHO*S*V*V               !(6)式
  M=M0+RHO*S1*(L-X0)        !(7)式
  A=F/M-g                   !(8)式
  E=(P0-PA)*S*V             ! 噴出する水の運動エネルギー
  W=PA*S*V                  ! 水が大気を押しのける仕事率
  
  write(9,'(i5,1x,f7.3,10d23.15)') n,t0,x0,V,P0,F,M,A,T_0,E,W
  write(10,'(i5,1x,f7.3,3d23.15)') n,t0,y0(2),y0(3)

 do n=1,nmax
     if (M0 < M) then        !水を噴出中      
        tn=t0+dt
        call runge(neq,ex2,t0,tn,y0,yn,eps,ierr,work)
        t0=tn
        do i=1,neq
           y0(i)=yn(i)
        end do
        
        P=P0*(X0/y0(1))**H      !(3)式
        V=sqrt(2.*(P-PA)/RHO)   !(1)式
        F=RHO*S*V*V             !(6)式
        M=M0+RHO*S1*(L-y0(1))   !(7)式
        A=F/M-g                 !(8)式
        T=T_0*(X0/y0(1))**(H-1.)!(4)式
        E=(P-PA)*S*V            ! 噴出する水の運動エネルギー
        W=PA*S*V                ! 水が大気を押しのける仕事率

        write(9,'(i5,1x,f7.3,10d23.15)') n,t0,y0(1),V,P,F,M,A,T,E,W
        write(10,'(i5,1x,f7.3,3d23.15)') n,t0,y0(2),y0(3)     
        
     else                   !水を出し切った後
        tn=t0+dt
        call runge(neq,ex1,t0,tn,y0,yn,eps,ierr,work)
        t0=tn
        do i=1,neq
           y0(i)=yn(i)
        end do
        
        write(10,'(i5,1x,f7.3,4d23.15)') n,t0,y0(2),y0(3)     
     end if
        
     if(y0(3)<0.)exit   !地上に戻ったら計算終了
  end do
  
  
  close(9)
  close(10)
  
end program main

real(kind=8) function ex2(i,t,y)     !水を噴出中
  implicit none
  
  integer(kind=4),parameter:: neq=3  !解く方程式の数
  
  common S,S1,P0,PA,M0,L,H,RHO,x0,g,M  !mainと共通の変数
  integer(kind=4) i
  real(kind=8) t
  real(kind=8),dimension(neq):: y
  real(kind=8) S,S1,P0,PA,M0,L,H,RHO,x0,g,M  !変数の定義
       
  if ((L-y(1))<0.) y(1)=L         !水を最後に噴出したら水の位置はX=L
  if (i==1) then
     ex2= S/S1*sqrt(2./RHO*(P0*(X0/y(1))**H-PA))  !(5)式
  else if (i==2) then
     ex2= 2.*S*(P0*(X0/y(1))**H-PA)/(M0+RHO*S1*(L-y(1)))-g  ! (8)式
  else if (i==3) then
     ex2 = y(2)                      !(9)式
  else
     ex2=0.0d0
  end if
  
  return
end function ex2


real(kind=8) function ex1(i,t,y)    !水を出し切った後
  implicit none
  
  integer(kind=4),parameter:: neq=3  !解く方程式の数
  
   common S,S1,P0,PA,M0,L,H,RHO,x0,g,M  !mainと共通の変数
  integer(kind=4) i
  real(kind=8) t
  real(kind=8),dimension(neq):: y
  real(kind=8)  S,S1,P0,PA,M0,L,H,RHO,x0,g,M   !変数の定義
  
     if (i==1) then
        ex1=0.     
     else if (i==2) then
        ex1= -g
     else if (i==3) then
        ex1 = y(2)
     else
        ex1=0.0d0
     end if
  
     return
end function ex1




プログラム中では、y(1)→ x、y(2)→ V、y(3)→ X に対応しています。
このプログラムのソースコードは~yamashir/wrocket/xrunge1.f90,xrunge2.f90(図2用)からコピーできます。

計算結果