資料請求番号:SH43 SH44 TS41
大学や会社で研究開発活動をしていると、微分方程式における様々なパラメータが変化すると解曲線はどのように変化するのかをストレスなく確認したいという場面があると思います。
また、パラメータを求める実験を行う際には、ターゲットとしている微分方程式がパラメータによってどのように変動するのかを予め知っておけば、実験計画をスムーズに立てられると思います。
今回は、微分方程式のパラメータの変化が解曲線にどのような影響を与えるのかを理解するためのアニメーションの作成方法をまとめたいと思います。
今回作成したいアニメーションは以下の通りです。こちらは振動現象の微分方程式
をルンゲ・クッタ法で解いた曲線で、「γ=0.1の粘性によって減衰してしまうところ、どのくらいの強制振動F0を与えると振動を安定に続けることができるのか」を考察しています。
※こちらのページは振動に関する上記の微分方程式をルンゲクッタ法で解くプログラムがあることを前提にしています。ルンゲクッタ法のプログラムは以下の記事で解説しています。 /* –vibration formula rk-method ——– */ Sub rkvib() ‘Calculate properties ‘Constants ‘Initial Condition ‘Runge-kutta roop For i = 0 To ((ed – init) / h) j = 6 + i / h2 Cells(1, 6) = i If i Mod h2 = 0 Then Cells(j, 6) = t End If kx(1) = h * F1(t, x, v) t = nt Next i End Sub Function F1(ByVal t As Double, ByVal x As Double, ByVal v As Double) As Double Function F2(ByVal t As Double, ByVal x As Double, ByVal v As Double) As Double /* –vibration formula rk-method End——– */ なんでそんなケンカ腰なのよ!?イライラしてるからってワタシに当たらないでちょうだい!! まぁ、確かにないけど。ワタシはプログラム書くことが仕事だら?一応微分方程式を解くプログラムは書けるけど、その微分方程式の中身はよく分かんない~なんてよくあることだし? ああ。 これを0.1ずつ変動させながら、繰り返しグラフを描画させられる方法なら知ってるわよ。 おおっ、ってことは、いちいち0.1ずつ変化させてルンゲクッタループしなくてもええってこと? まぁね。1回アニメーション見て、気になったパラメータで刻み幅を小さくするなり、他のパラメータ考察するなりすれば、効率よさそうじゃない? せやな!教えてくれよ! お腹すいたな~。今日、テンイチ行きたいな~ ・・・しょうがねぇな。ええよ。行こう。 やった! それで、今回やりたいことっていうのは、例えばF0を0.5から4まで動かしたときの解曲線の挙動が見たいっていう目的なら、 せやな。 なら、基本形として、C7セルにあるF0の値を代入しては計算させてプロットさせての繰り返しになるわね。 /* –vibration constant simulation——– */ For force = 0.5 To 1 Step 0.1 /* –Rose curve Realtime plot ——End– */ このApplication.Run “rkvib”ってのは・・・ルンゲクッタループか? /* –vibration formula rk-method ——– */ Sub rkvib() ‘Calculate properties ‘Constants ‘Initial Condition ‘Runge-kutta roop For i = 0 To ((ed – init) / h) j = 6 + i / h2 Cells(1, 6) = i If i Mod h2 = 0 Then Cells(j, 6) = t End If kx(1) = h * F1(t, x, v) t = nt Next i End Sub Function F1(ByVal t As Double, ByVal x As Double, ByVal v As Double) As Double Function F2(ByVal t As Double, ByVal x As Double, ByVal v As Double) As Double /* –vibration formula rk-method End——– */ そうそう!0.5でルンゲクッタループ回して、Step0.1だから次は0.6で回して・・ってこと。 ほう。繰り返しの制御変数に整数型以外も使えるのか。便利やな。 まぁ、一応、テストとして、とりあえず1までにしてやってみたら? わかった。 ・・・・。 数字が変化するだけで、リアルタイムでグラフが変化せんのやけど。 まぁまぁ待って待って。 で? それで一旦制御をOSに返しますっていう命令を書かなきゃいけないの。それがDo Events関数。 /* –vibration constant simulation——– */ For force = 0.5 To 1 Step 0.1 /* –Rose curve Realtime plot ——End– */ /* –vibration formula rk-method ——– */ Sub rkvib() ‘Calculate properties ‘Constants ‘Initial Condition ‘Runge-kutta roop For i = 0 To ((ed – init) / h) j = 6 + i / h2 Cells(1, 6) = i If i Mod h2 = 0 Then Cells(j, 6) = t End If kx(1) = h * F1(t, x, v) t = nt Next i End Sub Function F1(ByVal t As Double, ByVal x As Double, ByVal v As Double) As Double Function F2(ByVal t As Double, ByVal x As Double, ByVal v As Double) As Double /* –vibration formula rk-method End——– */ おおっ!グラフがうごきよった!!最初からこれ教えろよ~(笑) でしょ?スゴイでしょ?そしたら、F0 = 4までまわしてごらん? これでF0=3がちょうどいいってことがわかるし、F0 = 2.1~2.2で重ね合わせ特有の不安定な振動がなくなるのもわかるたいね! いやぁ~。よかよか!ありがとう! じゃ、テンイチ行きましょ! はいはい・・・。
[blogcard url=”https://shimaphoto03.com/program/rk-vib/”]
※VBAソースコード 振動
Public omega0, gamma, force, omega As Double
Dim x0, v0, init, ed, h, h2, kx(4), kv(4) As Double
Dim i, j As Integer
init = Cells(1, 3)
ed = Cells(2, 3)
h = Cells(3, 3)
h2 = Cells(4, 3)
omega0 = Cells(5, 3)
gamma = Cells(6, 3)
force = Cells(7, 3)
omega = Cells(8, 3)
x0 = Cells(4, 7)
v0 = Cells(4, 8)
x = x0
v = v0
t = init
Cells(2, 6) = j – 6
Cells(j, 7) = x
Cells(j, 8) = v
kv(1) = h * F2(t, x, v)
kx(2) = h * F1(t + h / 2, x + kx(1) / 2, v + kv(1) / 2)
kv(2) = h * F2(t + h / 2, x + kx(1) / 2, v + kv(1) / 2)
kx(3) = h * F1(t + h / 2, x + kx(2) / 2, v + kv(2) / 2)
kv(3) = h * F2(t + h / 2, x + kx(2) / 2, v + kv(2) / 2)
kx(4) = h * F1(t + h, x + kx(3), v + kv(3))
kv(4) = h * F2(t + h, x + kx(3), v + kv(3))
nx = x + (kx(1) + 2 * kx(2) + 2 * kx(3) + kx(4)) / 6
nv = v + (kv(1) + 2 * kv(2) + 2 * kv(3) + kv(4)) / 6
nt = t + h
x = nx
v = nv
F1 = v
End Function
F2 = -omega0 ^ 2 * x – 2 * gamma * v + force * Cos(omega * t)
End Function
はじめに
ただね、例えば・・・この微分方程式のF0ってパラメータあるでしょ?説明
0.5でルンゲクッタループ回して、グラフ見て、0.6でルンゲクッタループ回して・・・を続けて4までたどり着くようにすればいいのよね。
Cells(7, 3) = force
Application.Run “rkvib”
Next force
Public omega0, gamma, force, omega As Double
Dim x0, v0, init, ed, h, h2, kx(4), kv(4) As Double
Dim i, j As Integer
init = Cells(1, 3)
ed = Cells(2, 3)
h = Cells(3, 3)
h2 = Cells(4, 3)
omega0 = Cells(5, 3)
gamma = Cells(6, 3)
force = Cells(7, 3)
omega = Cells(8, 3)
x0 = Cells(4, 7)
v0 = Cells(4, 8)
x = x0
v = v0
t = init
Cells(2, 6) = j – 6
Cells(j, 7) = x
Cells(j, 8) = v
kv(1) = h * F2(t, x, v)
kx(2) = h * F1(t + h / 2, x + kx(1) / 2, v + kv(1) / 2)
kv(2) = h * F2(t + h / 2, x + kx(1) / 2, v + kv(1) / 2)
kx(3) = h * F1(t + h / 2, x + kx(2) / 2, v + kv(2) / 2)
kv(3) = h * F2(t + h / 2, x + kx(2) / 2, v + kv(2) / 2)
kx(4) = h * F1(t + h, x + kx(3), v + kv(3))
kv(4) = h * F2(t + h, x + kx(3), v + kv(3))
nx = x + (kx(1) + 2 * kx(2) + 2 * kx(3) + kx(4)) / 6
nv = v + (kv(1) + 2 * kv(2) + 2 * kv(3) + kv(4)) / 6
nt = t + h
x = nx
v = nv
F1 = v
End Function
F2 = -omega0 ^ 2 * x – 2 * gamma * v + force * Cos(omega * t)
End Function
もうテンイチ行かんぞ!!
あのね、VBAのプログラム回している間はExcelの制御を完全にVBAに渡している状態になるの。
だから、時間のかかるマクロを回している間はExcelがフリーズしたみたいな感じになるのよね。
これを入れてやってみなよ。制御がOSに返ったらグラフを描くことができるから。完成形(サンプルプログラム)
Cells(7, 3) = force
Application.Run “rkvib”
DoEvents: DoEvents: DoEvents
Next force
※Sub rkvib()
Public omega0, gamma, force, omega As Double
Dim x0, v0, init, ed, h, h2, kx(4), kv(4) As Double
Dim i, j As Integer
init = Cells(1, 3)
ed = Cells(2, 3)
h = Cells(3, 3)
h2 = Cells(4, 3)
omega0 = Cells(5, 3)
gamma = Cells(6, 3)
force = Cells(7, 3)
omega = Cells(8, 3)
x0 = Cells(4, 7)
v0 = Cells(4, 8)
x = x0
v = v0
t = init
Cells(2, 6) = j – 6
Cells(j, 7) = x
Cells(j, 8) = v
kv(1) = h * F2(t, x, v)
kx(2) = h * F1(t + h / 2, x + kx(1) / 2, v + kv(1) / 2)
kv(2) = h * F2(t + h / 2, x + kx(1) / 2, v + kv(1) / 2)
kx(3) = h * F1(t + h / 2, x + kx(2) / 2, v + kv(2) / 2)
kv(3) = h * F2(t + h / 2, x + kx(2) / 2, v + kv(2) / 2)
kx(4) = h * F1(t + h, x + kx(3), v + kv(3))
kv(4) = h * F2(t + h, x + kx(3), v + kv(3))
nx = x + (kx(1) + 2 * kx(2) + 2 * kx(3) + kx(4)) / 6
nv = v + (kv(1) + 2 * kv(2) + 2 * kv(3) + kv(4)) / 6
nt = t + h
x = nx
v = nv
F1 = v
End Function
F2 = -omega0 ^ 2 * x – 2 * gamma * v + force * Cos(omega * t)
End Function
View Comments
こんにちは、
貴殿のサイト読ましてもらっています。
とても詳しくわかりやすく説明されていて、VBA初心者の私にとってはとても学びやすいです。
ところで、以下のコードなんですが、これをどこに書けば最後の動画のようになるのでしょうか?
rkvib内のどこかなのかモジュール(Module1 やModule2)内に導入すればいいのでしょうか?
For force = 0.5 To 1 Step 0.1
Cells(7, 3) = force
Application.Run “rkvib”
DoEvents: DoEvents: DoEvents
Next force
こんにちは。
質問の回答ですが、同一モジュール内にrkvibとは別の新しいSubプロシージャを作成して
For force = 0.5 To 1 Step 0.1
Cells(7, 3) = force
Application.Run “rkvib”
DoEvents: DoEvents: DoEvents
Next force
の構文を書けばよろしいかと思います。