前提・実現したいこと
Pythonでxの値を増やしながら、それに対応する高さを求めるコードを書いています。
前提としてxは0.1から0.05刻みで0.55まで増やします。そしてそれに対応する水の量をwaterとしています。流れとしては初期値xの値を増やしながら(最初に入っている水の量)、その時々の速度をルンゲクッタで求めるというものです。(本当に知りたいのは_vi[-1]とsum(_vi)なのですが...。)
まずxの初期値(動かしたいもの)
i = 0.10 di = 0.05 _xi = [] while i <= 0.55 : xi = i _xi.append(xi) print(xi) i += di
初期値xに対応する水の量
i = 0.10 di = 0.05 _water = [] while i <= 0.55 : water = S1 * rho * (0.60 - i ) _water.append(water) print(water) i += di
発生している問題・エラーメッセージ
実行してエラーが出ることはないのですが、リストの中に何も入っていない状況になるので思ったように動いていないのだと思います。
該当のソースコード
ルンゲクッタを行うために以下を定義しておきます。
# dx / dt を計算して返す関数 def dxdt(x): result = SS * math.sqrt((2.0/rho)*(P0*((X0/x)**gm) - PA)) return result
#dv/dtを計算して返す関数 def dvdt(x): u_square = (2.0/rho)*(P0*((X0/x)**gm) - PA) result = (rho*S2*u_square)/(M0 + rho*(L-x)*S1) - g return result ``` 以下のコードではiに対するviが知るためのコードなのですが、実行してもリストに値が返ってきません。 ``` _water = [] while i <= 0.55: t = 0 v = 0 x = i #xの初期値 dt = 0.000001 di = 0.05 water = S1*rho*(0.60 - i) #xiは上で出ている。それぞれのiに対応している。 _water.append(water) _t=[] _x=[] _v=[] _u=[] while x <= 0.60: #境界面が0.60以下の位置にあるとき #ルンゲクッタで時間tでの水の座標を求める。 k1 = dxdt(x)*dt; k2 = dxdt((x+k1/2.0))*dt; k3 = dxdt((x+k2/2.0))*dt; k4 = dxdt((x+k3))*dt; k = (k1 + 2.0*(k2 + k3 )+ k4)/6.0; #噴出する水の速度 viを求めるのに必要です。 u = math.sqrt((2/rho)*(P0*((i/x)**gm) - PA)); # m/s #ルンゲクッタで速度を求める。 k1v = dvdti(x)*dt; k2v = dvdti((x+k1v/2.0))*dt; k3v = dvdti((x +k2v/2.0))*dt; k4v = dvdti((x +k3v))*dt; kv = (k1v + 2.0*(k2v + k3v) *k4v)/6.0; #配列へ _t.append(t) _x.append(x) _u.append(u) _v.append(v) t += dt; x += k; v += kv; i += di; ``` ``` import math import numpy as np import matplotlib.pyplot as plt ``` 文字の意味です。 ``` pi = math.pi S1 = pi*(0.08/2)**2 #ペットボトルの断面積 m^2 S2 = pi*(0.02/2)**2 #噴出口の断面積 m^2 SS = (0.02/ 0.08)**2 # 断面積の比 S1/S2 L = 0.60 # ペットボトルの長さ m rho = 1000.0 # 水の密度 kg/m^3 atm = 101325 # atm → N/m^3 P0 = 4.0*atm # ペットボトル内部の圧力 N/m^2 PA = 1.0*atm # 大気圧 N/m^2 X0 = 0.48 # 水と空気の境界面 水の量 m gm = 7/5 # Cp/Cv 気体の比熱比 dt = 0.000001 #時間幅 sec g = 9.8 #重力加速度 m/sec^2 M0 = 0.12 # ロケットの質量(水抜き) kg ``` 追記(訂正) リストxiの中には要素が10個あるのでjを0から10まで増やしながら対応する_v[-1]とsum(_v)を返してもらうコードを書きました。これをどうにかしたいと思っています。 ``` j = 0 dj = 1 _t=[] _x=[] _vf=[] _vsum = [] _u=[] while j <= 9 : t = 0 v = 0 x = _xi[j]#xの初期値 これを変えていきたい。 dt = 0.000001 while x <= 0.60: #境界面がL以下の位置にあるとき これを超えると水が完全に切れたことに #ルンゲクッタで時間tでの水の座標を求める。 k1 = dxdt(x)*dt; k2 = dxdt((x+k1/2.0))*dt; k3 = dxdt((x+k2/2.0))*dt; k4 = dxdt((x+k3))*dt; k = (k1 + 2.0*(k2 + k3 )+ k4)/6.0; u = math.sqrt((2/rho)*(P0*((i/x)**gm) - PA)); # m/s #ルンゲクッタで速度を求める。 k1v = dvdt(x)*dt; k2v = dvdt((x+k1v/2.0))*dt; k3v = dvdt((x +k2v/2.0))*dt; k4v = dvdt((x +k3v))*dt; kv = (k1v + 2.0*(k2v + k3v) *k4v)/6.0; vf = _v[-1] #最終速度 vsum = sum(_v) #vの和 #配列へ _t.append(t) _x.append(x) _u.append(u) _v.append(v) _vf.append(vf) _vsum.append(vsum) t += dt; x += k; v += kv; Hi = sum(_vi)*dt + (_vi[-1])**2/2/g #最高到達点を求める式 _Hi.append(Hi) j += dj; ``` こういうエラーが出てきてしまいます。 ```ここに言語を入力 IndexErrorTraceback (most recent call last) <ipython-input-17-14b49cbf9f76> in <module>() 35 kv = (k1v + 2.0*(k2v + k3v) *k4v)/6.0; 36 ---> 37 vf = _v[-1] #最終速度 38 vsum = sum(_v) #vの和 39 IndexError: list index out of range ``` ### 試したこと 上のコードを作成してiを増やしながらそれに対応する速度を求めようとしました。 しかし速度は恐らく時間によるものなので求めるのは難しい気がしています。 時間と速度の関係を知りたいのではなく、最終的にはiに対する_vi[-1](水がなくなったときの速度)とsum(_vi)(これが分かれば水がなくなったときの到達点が分かります。)なので今はそれを返してくれるコードを書いています。 上記のコードでは実行してもリストの中には何も入っていません。 どうしてこうなっているのか私には理解できないので、その理由を教えていただきたいです。 またviを求めるのではなくvi[-1]とsum(_vi)を求めたいのでヒントがあれば教えてください(チャレンジ中です) ### 補足情報(FW/ツールのバージョンなど) 問題はペットボトルロケットの水の量に対する最高到達点を求めようというものです。 ペットボトルロケットを真上に発射すると水が入っている状態ではルンゲクッタで速度を求めることが出来ますが、水がなくなるとその時の速度を初速度とする投げ上げ運動に変わります。 最高到達点は、水が切れた時の速度と到達点が分かれば求めることが出来ます。 つまり、最初の座標xを変えながら速度と到達点を返してくれるコードを書くことを目的としています。 この問題に至るまでに時間と速度の関係等を求める問題があったのですが(水の量は固定されていた)、この問題は時間は関係なく今度は初期値(最初にどれくらい水が入っているのか)を変える必要があり頭が混乱しています。 力技で自分で水の量を毎回変えながら最高到達点を求めてグラフを描くことには成功したのですが... ヒントをいただけたら幸いです。よろしくお願いいたします。
あなたの回答
tips
プレビュー