Google ClassroomGoogle Classroom
GeoGebraGeoGebra Classroom

模造1(重力とエネルギー)

このページはマス旅の一部です。 今回は「重力とエネルギー」のシミュレーションをしよう。 geogebraのテキストでは上付きドット記号が使えないので(')を使って時間微分の1階分を表すことにします。微分df/dtはf'で、d^2f/dt^2はf''とかきます。

1.解析解と数値計算解

課題1:「高さHtのビルの屋上から鉛直に初速度v0で玉を投げ上げる。 そのときの玉の運動を、横軸を時間t、たて軸を位置yとして連続的に打点する。 重力加速度はg=9.81。」 運動方程式はF=ma=mv'=mx''(2階の微分方程式)だから、 自由落下の場合はF=mg=mv'=my''となるね。 <解析解を利用する> 玉の位置y、速度v、加速度は上向きを+とします。 y,vはtの関数として解析的に書ける。 速度v=g(t)=v0-g*t vグラフは上底v0,下底v0+g*t,高さtの台形となるので、面積は (v0+v0-g*t)t*1/2=v0*t-1/2g*t^2 yの初期値Htとたすと、y=Ht+v0*t-1/2g*t^2 このyの式はHt,v0全部載せ だから、これで曲線y=f(t)が完成。あとは、geogebraで作れるね。 <オイラー法を利用する> 時間ごとの変化に着目すると、 加速度が速度の瞬間増分(微分)だから、v'=g 速度が距離の瞬間増分(微分)だから、y'=v 時間増分th=0.1などとする。 初項v0, 公差 -g*th の等差数列になるから、リストvsができる。 v0, v0 -g*th, v0 -g*th*2,.... 初項Ht, 階差vi*th の階差数列になるから、リストysができる。 Ht, Ht+v1*th, Ht+v1*th+v2*th, Ht+v1*th+v2*th+v3*th ....... リストのi番目はHt+(v1+v2+...+v_{i-1})*th <geogebraのコード> g=9.81 th=0.1 rev_th=1/0.1 Ht=Slider(0, 10,1) #オブジェクトを画面に固定しましょう。 v0=Slider(-10, 10,1) #オブジェクトを画面に固定しましょう。 t=Slider(0, 5, 0.1)  #設定>上級>アニメーション>増加(51段階表示で連続表示) #ここから解析解 f(x)=Ht + v0 * x-1/2 g * x^2 ex=If(f(t)>0,f(t),0) P=(t,ex)) #地上で玉は止まる。 #ここからオイラー法 N=60*rev_th vs=Sequence(v0 -g*th*k,k,0,N) #階差部分を等差数列の部分和によってつくる。番号のズレ補正のため、初項を0にする。 vith = Join({0},Sequence(Sum(Take(vs,1,k)) *th , k,1,N-1)) ys=Sequence(Ht+Element(vith , k), k, 1,N) idx = t * rev_th + 1  # (1..51)のレンジの離散量 ele=Element(ys,idx) eu=If(ele>0,ele,0) Q=(t, eu) #オイラー法の玉の動き #Pの正確な動きと、Qの近似的な動きを比べてみよう。 thが0.1荒いので誤差が拡大してしまってますね。 thを細やかにすると点Pと点Qのズレは縮小するでしょう。 v0=0にすると自由落下になり、v0<0にすると鉛直投げ下しになります。

鉛直投げ上げの解析解とオイラー法

2.NSolveODEを使おう

<NSolveODEで課題1を解く> geogebraにはルンゲ=クッタ法を内蔵した数値解を求める関数NSolveODEがあります。 それを使ってみよう。 距離の微分y'=v 速度の微分v'=-g(上向きが正) 解きたいの微分はy',v'で そのy,vの初期値はy=Ht, v=v0です。 調べる範囲はさっきは指定しませんでしたが、12秒もいりません。t=10で十分です。 そこで、次の6行を入れます。 #定数 g=9.81 #初期値 Ht=Slider(0, 10,1) v0=Slider(-10, 10,1) #微分方程式 y'(t, y, v) = v v'(t, y, v) = -g #情報をまとめて投げるt=0からt=10まで調べる。t=0のときの初期値が`{ }の中。 NSolveODE({y', v'}, 0, {Ht, v0}, 10) エンターすると、 一瞬で、y=f(t),v=g(t)の2関数を数値的に解明してくれます。 yのグラフを選んで、オブジェクト上の点を取ると、Aになります。 Aの設定を上級>アニメーション>速度0.3、表示条件y(A)、表示>値にすると、 yのグラフにそって玉が地面まで移動して消えます。上級>アニメーション>増加にしないと、 点がもとに戻ってしまいますね。

鉛直投げ上げの微分方程式を数値的に解く

<課題2:課題1に空気抵抗を追加する> 空気抵抗があると加速度が-kvだけ変化して、a=-g-kvになるのです。 だから、微分方程式は、y'=vとv'=-g-kvの連立方程式になりますね。 空気抵抗のある落下運動をシミュレーションしようとすると大変なことになります。 それは、解析解ではv’変数分離法で積分でやってもvが指数関数になるので、 yは指数関数の積分になり、面倒な式になるからです。 オイラー法でもgeogebraで離散的にリスト処理でやろうとすると、 v自体が等差数列ではなくなるので、プログラミングが不可能ではないでしょうが、超面倒なのです。 もちろん、python,javascriptでwhile文を使えばできるでしょうが、大掛かりです。 でも、大丈夫! ルンゲ=クッタ法を内蔵した数値解を求める関数NSolveODEがgeogebraにはあります。 空気抵抗係数k=0.15という条件を追加して調べてみよう。 #定数 g=9.81 k=Slider(0,5,0.05) #追加最初はk=0.15にしましょうか。 #初期値 Ht=Slider(0, 10,1) v0=Slider(-10, 10,1) y'(t,y,v) = v #この次の1行を変えるだけです。 v'(t,y,v) = -g - k*v NSolveODE({y', v'}, 0, {Ht, v0}, 10) k=0にすると、抵抗ゼロ、 kを上げていくと重力がキャンセルされて、 等速運動になるという 面白い現象がシミュレーションできます。 すごいぞ、geogebra!

鉛直投げ上げと空気抵抗