Comments
Description
Transcript
7.栓をし忘れ浴槽に水(ルンゲ・クッタ法) 数年前のある中学校の入試
環境シミュレーション 7.栓をし忘れ浴槽に水(ルンゲ・クッタ法) 平方根に比例し,高さ h から落下する物体の落下速 「いまさら流体力学?」木田重雄著(丸善株式会社)より 度 2 gh と等しくなる. 数年前のある中学校の入試問題である.下図に示 す浴槽は蛇口から一定の割合で水を入れると 2 時間 で満杯になる.また,排水口は満杯の浴槽を空にす るのに 3 時間かかる.ある日,浴槽に水を張ろうと して,うっかり排水栓を閉じるのを忘れてしまった. 浴槽は蛇口を開いてから何時間で一杯になるだろ う? では,栓をし忘れて浴槽に水を張るという問題を 考えてみよう.先ず,浴槽の容積 V は 1 m 3 (底面積 S = 1 m 2 ,深さ h = 1 m)とする.問題の蛇口からは, 1 時間に浴槽全体の 2 分の 1 に相当する水が入るこ とから,単位時間あたりの給水量(給水流量) Qin は, 浴槽容積を給水の所用時間で割った 1 2 m 3 h とな る.この給水流量は一定である. 次に,満杯の浴槽を排水栓を抜いて空にする場合 を考えてみる.ある微小な時間 Δt の間に流れ出す 水の量は,「トリチェリの定理」から排出流量を − α h とおけば,両者の積 − α h Δt となる(ここで h は,その時点(時間 t )における浴槽の水深である). 注意:理論的に言えば,流速が 2 gh となることから,こ れに排出口の断面積をかけてやれば排出流量が求まるは ずであるが,現実には,縮脈といって,流れ出す水の断面 積が排出口の断面積より小さくなる現象が現れる.また, その小さくなる比率(縮脈率)も排水口の形状や粗度によ って一様でないことから,理論式はそのままでは使うこと ができない.ただ,排出流量が水深の平方根に比例すると いう事実だけは残る. 正解? 一方,これだけの水が流れ出した結果として減少 した浴槽の水深を Δh とおけば,減少した浴槽容積 は, Δh に底面積をかけて SΔh となる.この減少し た浴槽容積と排出された水の量は等しいはずであ る か ら , SΔh = −α h Δt . 式 を 変 形 す れ ば Δh Δt = − α h S .ここで Δt の極限 Δt → 0 を考えれ この問題の出題者はおそらく次のような解答を 受験生に期待していたのであろう. この蛇口からは 1 時間に浴槽全体の 2 分の 1 に相 当する水が入る.一方,排水口からは 1 時間につき 浴槽の 3 分の 1 に相当する水がでていく.したがっ て,蛇口と排水栓の両方を開くと 1 時間に浴槽の 1 2 − 1 3 = 1 6 に相当する水がたまっていく.したが ば,次の微分方程式が得られる.(ちなみに微分方程 式は上記のように,浴槽への水の出入り,すなわち水とい う物質のある系(浴槽)への収支から導き出されることか ら「物質収支式」とも呼ばれる.) って,浴槽は 6 時間で満杯になる.答え 6 時間. 一見これで良さそうに思われるが,この問題はそ う単純ではなかった.実はこの場合「浴槽はいつま .... でたっても一杯にならない」が正解である. dh α =− dt S 正解 h ここで上式は,変数分離法で解析的に解くことが できる. この問題を解く鍵は,排水口から流れ出す水の速 さにある.君たちもお風呂(浴槽)の水を抜いたこと があるだろうが,排水口から流れ出す水の速さは決 して一定ではない.浴槽が満杯に近いときは,流れ 出す水の速度は速く,空っぽに近くなるとそれにつ れて速度も遅くなっていく.なぜそうなるかの詳し い解説はしないが,結論だけをいうと,排出口にお ける水の流速 v は次式のようになる. dh α =− dt S h → - dh h = α S dt → -∫ h −1 2 dh = α S ∫ dt 満杯の浴槽をからにするのに排水栓を抜いてか ら 3 時間かかるという題意より,次のように α が求 まる. v = 2 gh 0 α H S − ∫ h −1 2 dh = 3 [ ] ∫ dt → − 2 h 0 0 H =1 = α S [t ] t =3 0 → 2 1 = 3 α 1 → α = 2 3 = 0.6666... [m 5 2 h] 上式は「トリチェリの定理」と呼ばれ,ここでの g は重力加速度, h は浴槽の水深である.つまり,水 深 h の浴槽から流れ出す水の速度は,浴槽の水深の 最後に,排水栓を閉じずに蛇口を開いた場合の時 - 37 - 環境シミュレーション 上式をもとに Excel で,水深 h に対して,その深 さの水を溜めるのに必要な時間 t をプロットしてみ たのが下図である. 間 t に対する浴槽の水深 h を考えてみよう.先ほど と同様に,ある微小な時間 Δt を考える.その間に流 れ出す水の量は − α h Δt ,また蛇口から流れ込む水 の量は,給水流量が Qin ( 0.5 m 3 h )より +Qin Δt .そ れら両者の結果としての,浴槽の水深の変化を Δh とおけば,変化した浴槽容積は, Δh に底面積をか けた SΔh となり,この変化した浴槽容積は,給水さ れた水の量から排出された水の量を引いた値は等 しいはずである:SΔh = Qin Δt − α h Δt .式を変形し, Δt の極限 Δt → 0 を考えれば, dh dh 1 2 = Qin − α h → 1 = − h dt dt 2 3 S この微分方程式をやはり変数分離法で解いてやる. dh → 1 2−2 3 h = dt → ∫ dh 1 2−2 3 h = ∫ dt 限大となる.つまりこの問題の場合は,浴槽の水は 水深 0.5625 m までは溜まるが,それ以上は時間が 無限に経過しても溜まらない.すなわち浴槽は永遠 に満杯とはならないのである. この場合は,さらに h = x と変数を置換してやる ことが必要になる.積分範囲は 0 ≤ h ≤ h に対して 0 ≤ x ≤ h .ここで h = x の辺々を微分すると この理由は簡単である.水を張りはじめてある水 深までは水の給水流量が排出流量を上回る ( dh dt = 1 2 − 2 3 h > 0 )ために,水は溜まっていく 1 dh 1 dh = dx → = dx → dh = 2 xdx 2 h 2 x これを元の微分方程式に代入して, dt = =( dh 1 2−2 3 h = 図が示すとおり,浴槽に水を張っていくために必 要時間は,浴槽の水深が 0.5 m を過ぎたあたりから 急 激 に 長 く な る . 理 論 的 に は , dh dt = 1 2 − 2 3 h = 0 となる h = 9 / 16 = 0.5625 で無 2 xdx 12 xdx 9 − 3(3 − 4 x ) dx = = 1 2 − 2 3 x 3 − 4x 3 − 4x 9 − 3)dx 3 − 4x が,水深が高くなるにつれて,給水流量が一定なの に対して排出流量が徐々に大きくなっていき,ある 水深( h = 0.5625 m )になった時点で,排出流量が給水 流量と等しくなり( dh dt = 1 2 − 2 3 h = 0 ),それ以 上の水が浴槽にたまらなくなるのである. ルンゲ・クッタ法によるシミュレーション では同じ問題(微分方程式 dh dt = 1 2 − 2 3 h ) 辺々をそれぞれ 0 ≤ t ≤ t と 0 ≤ x ≤ h の範囲で積分 すると,以下のようになる. h t を数値計算で解いてみる.ここでは差分法のひとつ であるルンゲ・クッタ法で解いてみよう.前の章で の少し触れたように,差分法としてはルンゲ・クッ タ法のほうがオイラー法よりも精度がよく,実際の コンピュータ・シミュレーションで利用されている 差分法のほとんどがルンゲ・クッタ法である. 9 ∫ dt = ∫ ( 3 − 4 x − 3)dx 0 0 h ⎡ 9 ⎤ ln(3 − 4 x) − 3 x ⎥ 0 = ⎢− ⎣ 4 ⎦0 9 9 = − ln(3 − 4 h ) − 3 h + ln(3) 4 4 9 3 ∴t = ln −3 h 4 3− 4 h [t ] t ただし解説としては,サンプルプログラム全般の 説明からはじめ,ルンゲ・クッタ法については,そ の後で説明する. サンプルプログラムの概要 下図がこの問題のために作成したサンプルプロ グラムの外見である. 残念ながら h(t ) = のように,時間 t の関数として の浴槽の水深 h を求めることはできないが,逆に水 深 h に対する(水深 h の水を溜めるのに必要な)時間 t は求めることができる. - 38 - 環境シミュレーション 次のような Sub プロシージャで定義されている. Option Explicit Dim qin, alpha As Double 'ルンゲ-クッタ法(Runge-Kutta Method) Sub Sub_RKM() Dim t, k1, k2, k3, k4 As Double Dim i As Long Dim h1, del_t, t_end As Double UserForm1.TextBox1 = 0.5 UserForm1.TextBox2 = 0.1 UserForm1.TextBox3 = 10 UserForm1.TextBox4 = 0.666 UserForm1.TextBox5 = 0 このプログラムでは,B8:C9 にある「シミュレー ション・スタート」というコマンドボタンを押すこ とで,シミュレーションが開始する.すると経過時 間 t が A6 に,その時点での浴槽の水深 h が B6 に, C6 には水槽の深さ 1 m から水深を引いた値が表示 され,その結果をうけて右の図の水色部分があたか も浴槽中の水のように上下する. UserForm1.Show qin = UserForm1.TextBox1 del_t = UserForm1.TextBox2 t_end = UserForm1.TextBox3 alpha = UserForm1.TextBox4 h1 = UserForm1.TextBox5 t=0 Cells(6, 1) = t Cells(6, 2) = h1 If MsgBox(Prompt:="Ready?", Buttons:=vbOKCancel) <> _ vbOK Then Exit Sub For i = 1 To t_end / del_t t = t + del_t k1 = dhdt(t, h1) k2 = dhdt(t + del_t / 2, h1 + del_t * k1 / 2) k3 = dhdt(t + del_t / 2, h1 + del_t * k2 / 2) k4 = dhdt(t + del_t, h1 + del_t * k3) h1 = h1 + del_t * (k1 + 2 * k2 + 2 * k3 + k4) / 6 Cells(6, 1) = t Cells(6, 2) = h1 ActiveSheet.Calculate If t > 0 And (h1 <= 0 Or h1 >= 1) Then Exit For Next i MsgBox ("シミュレーション終了") End Sub では実際,スタートボタンを押してみよう.する と上図のようなダイアログボックスが現れる. ここでは, Qin = 給水流量 Qin [ m 3 / h] ,del_t = 差分法のタイムステップ Δt [h] ,t_end = シミュレ ーションの終了時間[h],alpha = 排出流量の速度係 数 α [m 5 2 h] ,h(0) = 時間 t = 0 での水深 h(0) [m] Function dhdt(t As Double, h1 As Double) As Double If h1 < 0 Then h1 = 0 dhdt = qin - alpha * h1 ^ (1 / 2) End Function を設定するようになっている.なお,図中ボックス 内のそれぞれの値はデフォールトとして与えてい るものである.このようなダイアログボックスの作 成のしかたと,ダイアログボックスからの値を数値 計算へ取り込む方法については後述する. また,この「Sub_RKM」がマクロとしてサンプ ルプログラムの「シミュレーションスタート」ボタ ンにリンクされている.(コマンドボタンへのマク ロ登録はモンテカルロ法を参照) またこのプログラムでは,ダイアログボックスで パラメータを設定した後,シミュレーションの開始 前と終了後にそれぞれ下図のようなメッセージボ ックスを表示させるようにしている. ではプログラムの詳細をみていこう. プログラムの詳細 Option Explicit Dim qin, alpha As Double '上記は,給水流量(qin)と排出流量の速度係数 α の 2 変数を倍精 '度で宣言したものである.このようにモジュールの先頭でデ 'ータ型を宣言すると,モジュール内のすべてのプロシージャが '適用範囲となる.このような変数を「モジュールレベル変数」 'とよび,各プロシージャ内で宣言され,そのプロシージャ内だ 'けで有効なローカル変数と区別される. VBA プログラム では上記のようなサンプルプログラムを動かし ているプログラムを見てみよう.このプログラムは - 39 - 環境シミュレーション t = t + del_t 'ルンゲ-クッタ法(Runge-Kutta Method) 'i がカウントされる度に,シミュレーション・クロックを del_t 'だけ進めている. Sub Sub_RKM() 'この Sub...から End Sub までが「Sub_RKM」と名づけた Sub プ 'ロシージャである. k1 = dhdt(t, h1) k2 = dhdt(t + del_t / 2, h1 + del_t * k1 / 2) k3 = dhdt(t + del_t / 2, h1 + del_t * k2 / 2) k4 = dhdt(t + del_t, h1 + del_t * k3) h1 = h1 + del_t * (k1 + 2 * k2 + 2 * k3 + k4) / 6 Dim t, k1, k2, k3, k4 As Double Dim i As Long Dim h1, del_t, t_end As Double '上記 3 行は「Sub_RKM」内でのデータ型宣言部分である.ちな 'みに t はシミュレーション時間,k1,k2,k3,k4 はルンゲ・ 'クッタ法で使用する変数,i は For...Next ステートメントのた 'めのインデックス,h1 は浴槽の水深,del_t がタイムステップ, ' t_end がシミュレーションの終了時間を表している. UserForm1.TextBox1 = 0.5 UserForm1.TextBox2 = 0.1 UserForm1.TextBox3 = 10 UserForm1.TextBox4 = 0.666 UserForm1.TextBox5 = 0 'パラメータを設定するユーザフォーム 'にデフォールト値を入れるための行である.「UserForm1」とは 'そのダイアログボックスがその名称のユーザフォーム (後述 'する)に定義されていることを示す.また「TextBox(1,2, '3,...)」は,数値を代入する場所がダイアログボックスで何番 'めのテキストボックス(後述する)になるかを示している. 'まず変数 k1 では,シミュレーション時間 t とその時点での水深 'h1 の値を下で定義している Function プロシージャ「dhdt()」 'に手渡し,その時点の dh/dt の値を返り値として k1 に受け取る. '変数 k2 では,シミュレーション時間 t に del_t/2 を足した値 'と,さきほどの水深 h1 に del_t*k1/2 を足した値を「dhdt()」 'に手渡し,その時の dh/dt を返り値として k2 に受け取る. '同様に変数 k3 では,シミュレーション時間 t に del_t/2 を足 'した値と,水深 h1 に del_t*k2/2 を足した値を「dhdt()」に手渡 'し,その時の dh/dt を返り値として k3 に受け取る. '変数 k4 では,シミュレーション時間 t に del_t を足した '値と,水深 h1 に del_t*k3 を足した値を「dhdt()」に手渡し,そ 'の時の dh/dt を返り値として k4 に受け取る. '最後にルンゲ・クッタ法の仕上げとして,上記のようにして得 'られた変数 k1,k2,k3,k4 から,その平均を 1:2:2:1 の重み 'で求め,重み平均に del_t をかけた値を,そのシミュレーショ 'ンステップ内での h1 の変化量として,前ステップの h1 に加え, 'その結果を新たな h1 とする. Cells(6, 1) = t Cells(6, 2) = h1 UserForm1.Show '「UserForm1」に定義されたダイアログボックスを画面に表示 'せよと命令している. '更新された t と h1 を,シートのセル A6 と B6 にそれぞれ表示 'する. qin = UserForm1.TextBox1 del_t = UserForm1.TextBox2 t_end = UserForm1.TextBox3 alpha = UserForm1.TextBox4 h1 = UserForm1.TextBox5 ActiveSheet.Calculate 'ワークシート上のグラフを描き直す. If t > 0 And (h1 <= 0 Or h1 >= 1) Then Exit For 'ダイアログボックスに打ち込まれた数値をプログラム内のパ 'ラメータとして取り込む. 'もし(If)t が 0 より大きく(t>0),かつ h1 が 0 以下(h1<=0)(浴 '槽から水がなくなる)かあるいは(Or)h1 が 1 以上(h1>=1)(浴槽 'から水があふれるよう)であれば(Then),For...Next ステート 'メントを抜ける(Exit For). t=0 'シミュレーション・クロックを 0 に初期化する. Next i Cells(6, 1) = t Cells(6, 2) = h1 '次の i で For...Next ステートメントを繰り返す. MsgBox ("シミュレーション終了") '現在アクティブなシートのセル(6 行 1 列目つまり A6)に変数 t 'の値を,セル(6 行 2 列目つまり B6)に h1 の値を表示する. '「シミュレーション終了」のメッセージボックスを画面に表示させる. If MsgBox(Prompt:="Ready?", Buttons:=vbOKCancel) <> _ vbOK Then Exit Sub End Sub '「Sub_RKM」という Sub プロシージャの終わり. 'MsgBox(メッセージボックス)関数を続く()の条件で画面表示 'し,もし(If)それに対する回答が O.K.ボタン(vbOK)以外(<>) 'なら (Then),この Sub プロシージャを終了する.ちなみに ' MsgBox 関数の表示条件は Prompt 文が”Ready?”で,ボタンが '「O.K.」と「Cancel」である(先に示したメッセージボックスを見 'よ). Function dhdt(t As Double, h1 As Double) As Double '「dhdt」という Function プロシージャの定義開始 If h1 < 0 Then h1 = 0 'さて以下の For...Next ステートメントの中がこのプログラム 'の核心部,ルンゲ・クッタ法による微分方程式の数値計算であ 'る. 'もし(If)h1 が 0 より小さい(h1<0)場合(Then)は,h1 を 0 と置 'く. For i = 1 To t_end / del_t dhdt = qin - alpha * h1 ^ (1 / 2) '問題の微分方程式(dh/dt)の値を与えられた条件で計算して返 'す. '以下の Next 行までの計算を 1 から,シミュレーション時間 't_end をタイムステップ del_t で割った回数だけ繰り返す. - 40 - 環境シミュレーション End Function 選択する.カーソルが「+」字に変わるので,フ ォーム上でこれをドラッグして,コントロール の配置場所とサイズを確定する. ユーザフォームの作成方法 サンプルプログラムではシミュレーションをス タートさせると,下図のようなダイアログボックス (ユーザフォーム)が現れ,ここでさまざまなシミ ュレーション条件を設定変更できるようになって いた. コントロールボタンの内容 [ツールボックス]にはさまざまなタイプのコントロ ールボタンが用意されている.しかし,本授業で使 用する以下の 3 つのボタンのみである.ここでは, それらのボタンのみについて紹介し,それ以外のボ タンについては説明を省略する.興味のある者は, オンラインヘルプなどで調べてほしい. 以下,Excel VBA におけるダイアログボックス (ユーザフォーム)の作成方法を簡単に説明してお く. ユーザフォームの作成には先ず,[ユーザフォー ム]シートが必要である.新規にこのシートを挿入す るには[標準モジュール]と同様に,[Visual Basic Editor]の[挿入]から[ユーザフォーム]を選ぶ.する と下図のような新規の[ユーザフォーム]シートが現 れる.プロシージャと異なり,一つの[ユーザフォー ム]シートに定義できるダイアログボックスは一つ きりである. 1. [ラベル]:フォーム上に文字列を書き込むため のコントロール. 2. [テキストボックス]:文字列,数値などを入力 するためのコントロール.ちなみにここに入っ た値を VBA では,「UserForm1.TextBox1」の ように参照する. 3. [コマンドボタン]:マクロ実行のボタンコント ロール. [テキストボッ クス]で定義し た入力ボックス [ラベル]で書き込んだ文字列 上図のように[ユーザフォーム]シートで定義でき るダイアログボックスはユーザが自由に作成・編集 できることからユーザフォームと呼ばれ,VBA の 定義済みのダイアログボックス(例えば,MsgBox 関数によるメッセージボックスなど)と区別される. ちなみに 1 変数だけの入力を求めるのなら 「InputBox」コマンドが簡単で便利である. この画面では,ダイアログボックスのタイトルや サイズを変更したり,希望のボタン(正確にはコント ロールと呼ぶ)をボックス上に配置したりすること ができる. 1.タイトルの変更:ボックスのタイトルバーの見 出しを変更するためには,フォーム上部の文字 列(初期状態では「UserForm1」となっている) を選択して,新しい名前に書き換える. 2.サイズの変更:フォームの端をクリックすると, 「Ⅱ」印のハンドルと呼ばれるものが四隅と四 辺上に現れるので,これをフォームが適当な大 きさになるまでドラッグする. 3.コントロールの配置:[ツールボックス]からフ ォーム上に配置したいボタン(コントロール)を コマンドボタンの設定方法 1) [ツールボックス]から[コマンドボタン]を選択. 「+」カーソルをドラッグしてダイアログボック ス上に適当な大きさのコマンドボタンを作成す る. 2) ボタン上の文字列「CommandButton1」をクリ ックして,これを「OK」と書き換える.書き換 えたら,ダイアログボックスの他の場所をクリッ クして編集から抜ける. 3) 「OK」と書き換えたボタンを右クリックして, ドロップダウンメニューから[コードの表示]を選 択する.すると次のような Private Sub プロシー ジャが現われるので,間に「UserForm1.Hide」 を書き加え,「UserForm1」のアイコンをクリ ックして,元のダイアログボックスのデザイン画 面に戻る. Private Sub CommandButton1_Click() UserForm1.Hide End Sub - 41 - 環境シミュレーション ここで「UserForm1.Hide」は,同ボタンがクリ ックされたときに,UserForm1 を隠せ(Hide)と の意味である. k 1 = f (t j , Y j ), k 2 = f (t j + Δt Δt , Yj + k 2 ), k 4 = f (t j + Δt , Y j + Δtk 3 ) 2 2 1 1 {Y j +1 − Y j } = ( k 1 + 2 k 2 + 2 k 3 + k 4 ) 6 Δt k 3 = f (t j + シミュレーション演習 出来上がったプログラムによって,以下のような 数値実験を行ってみよう. ではなぜこのような差分方法(ルンゲ・クッタ法) がオイラー法よりすぐれた O (( Δ t ) 4 ) の(累積打切り) 誤差をもつのであろうか? 1.給水流量 Qin [ m 3 / h] の変更:ダイアログボック スで,排出流量速度係数 alpha = 0(排水口に栓 をした状態),時間 t = 0 での水深 h(0) = 0 とお いて,給水流量 Qin にいろいろな値を入れ,給 水流量によって浴槽が満杯になる時間がどの ように変わるかを見てみよう. 2.排出流量速度係数 α [m 52 Δt Δt , Yj + k1 ) 2 2 河川の自浄モデル dL / dt = − K L をもとに,ルン ゲ・クッタ法の局所打切り誤差が O (( Δ t ) 5 ) (すなわち 累積打切り誤差が O (( Δ t ) 4 ) )になることを示そう. まず,自浄モデルの解析解は L ( t ) = L ( 0 ) e − Kt であ るから,時間 t = t + Δ t におけるテイラー展開は以下 のようになる. h] の変更:ダイアロ グボックスで,給水流量 Qin = 0(給水がない状 態),時間 t = 0 での水深 h(0) = 1(浴槽が満杯の 状態)とおいて,排出流量速度係数 alpha にい ろいろな値を入れ,速度係数によって浴槽がか らになる時間がどのように変わるかを見てみ よう. L (t + Δt ) = L (t ) + + 3.栓をし忘れて浴槽に水を張りはじめた場合:デ フォールト値のままでシミュレーションを行 い,本当に浴槽がいつまでたっても一杯になら ないのか,浴槽の最高水位は理論値どおりかを 確認しよう. Δ t ( 1) ( Δt ) 2 (2) ( Δ t ) 3 ( 3) L (t ) + L (t ) + L (t ) 1! 2! 3! ( Δt ) 4 (4) L (t ) ⋅ ⋅ ⋅ 4! ここで, L(1) (t ) = − KL(0)e − Kt = − KL(t ) L( 2 ) (t ) = − KL(1) (t ) = K 2 L(t ) L( 3) (t ) = K 2 L(1) (t ) = − K 3 L(t ) 4.タイムステップ Δt [h] の変更:タイムステップ del_t をいろいろ変えてみて,シミュレーショ ンの実行速度への影響を見てみよう. L( 4 ) (t ) = − K 3 L(1) (t ) = K 4 L(t ) より Δt (Δt ) 2 (K 2 ) (− K ) + 1! 2! (Δt ) 4 (Δt ) 3 + ( K 4 ) ⋅ ⋅⋅) (− K 3 ) + 3! 4! L ( t + Δ t ) = L ( t )(1 + 参考書 「理工系の基礎数学-数値計算」高橋大輔著(岩波書 店) 次にルンゲ・クッタ法のアルゴリズムに従って演 算を行ってみる. ルンゲ・クッタ法 ここでルンゲ・クッタ法について説明する.ルン ゲ・クッタ法による差分方法は,オイラー法による 差分方法を 1 {Y j +1 − Y j } = f (t j , Y j ) Δt とおけば(ここで Y j はステップ j 時点での差分解; Y j +1 は次のステップ j+1 時点での差分解――すなわ ち求めたい解,f (t j , Y j ) は時間 t j での与えられた微 分方程式の微分係数),以下のように表すことができ る. - 42 - 環境シミュレーション f (t , L(t)) = − KL(t ) k1 = f (t , L(t)) = − KL(t ) Δt Δt Δt , L(t) + k1 ) = − K ( L(t) + k1 ) 2 2 2 Δt Δt (− KL(t )) k1 = − KL(t) − K = − KL(t) − K 2 2 Δt = (− K + K 2 ) L(t ) 2 Δt Δt Δt k3 = f (t + , L(t ) + k2 ) = − K ( L(t ) + k2 ) 2 2 2 Δt Δt Δt k2 = − KL(t ) − K (− K + K 2 ) L(t ) = − K L(t ) − K 2 2 2 2 t ( t ) Δ Δ ) L(t ) = (− K + K 2 − K3 2 4 k4 = f (t + Δt , L(t) + Δtk3) = − K ( L(t) + Δtk3 ) k2 = f (t + = − KL(t) − KΔtk3 (Δt )2 Δt ) L(t ) − K3 2 4 (Δt )2 (Δt )3 ) L(t ) = (− K + K 2 Δt − K 3 + K4 2 4 Δt Δt k1 = − K L( t ) 6 6 Δt ( Δt ) 2 2 Δt ) L(t ) k2 = ( − K + K2 6 3 6 2 Δt Δt ( Δt ) 2 ( Δt ) 3 + K2 − K3 ) L(t ) k3 = ( − K 6 3 6 12 = − KL(t) − KΔt (− K + K 2 ( Δt ) 2 ( Δt ) 3 ( Δt ) 4 Δt Δt + K2 − K3 + K4 ) L( t ) k4 = ( − K 6 6 6 12 24 Δt ( k1 + k2 + k3 + k4 ) L( t ) + 6 = L ( t )(1 + + (Δt ) 2 (Δt ) 3 Δt (− K ) + (K 2 ) + (− K 3 ) 1! 2! 3! (Δt ) 4 ( K 4 )) 4! となり,確かにルンゲ・クッタ法の局所打切り誤差 は O (( Δ t ) 5 ) となる. 別の角度からルンゲ・クッタ法の局所打切り誤差 が O (( Δ t ) 5 ) となることを示そう.下の表は,5 つの 関数 f ( t ) = t , t 2 , t 3 , t 4 , t 5 について, f (1) の値を,初 期値 t = 0 , Δ t = 1 で,3 つの差分(オイラー,ホイン, ルンゲ・クッタ)法で求めてみたものである. 表よりも,ルンゲ・クッタ法では f ( t ) = t ~ t 4 ま で誤差なく計算できるが, f ( t ) = t 5 より高次な関 数ではエラーが生じることがわかる.すなわちこの ことこそ,ルンゲ・クッタ法の局所打切り誤差が O (( Δ t ) 5 ) となることと同値である. - 43 - 環境シミュレーション オイラー,ホイン,ルンゲ・クッタの比較 f (t ) t t2 t3 t4 t5 f ′(t ) 1 2t 3t 2 4t 3 5t 4 0 + 1 ⋅ (1) = 1 0 + 1 ⋅ (2 ⋅ 0 ) = 0 0 + 1 ⋅ (3 ⋅ 0 2 ) = 0 0 + 1 ⋅ (4 ⋅ 0 3 ) = 0 0 + 1 ⋅ (5 ⋅ 0 4 ) = 0 オイラー ホイン 0 + 1⋅ 1 (1 + 1) = 1 2 ルンゲ・クッタ 0 + 1⋅ 1 { 6 1+1+ 4 ⋅ (1)} =1 0 + 1⋅ 0 + 1⋅ 0 + 1⋅ 0 + 1⋅ 1 ( 2 ⋅ 0 + 2 ⋅ 1) = 1 2 1 3 ( 3 ⋅ 0 + 3 ⋅ 1) = 2 2 1 4 ( 4 ⋅ 0 + 4 ⋅ 1) = 2 2 1 5 ( 4 ⋅ 0 + 5 ⋅ 1) = 2 2 0 + 1⋅ 1 { 6 2 ⋅ 0 + 2 ⋅1 + 0 + 1⋅ 1 { 6 3 ⋅ 0 2 + 3 ⋅1 2 + 0 + 1⋅ 1 { 6 4 ⋅ 0 3 + 4 ⋅13 + 1 { 6 4 5 ⋅ 0 + 5 ⋅1 4 + 1 4 ⋅ ( 2 ⋅ ( ) )} 2 =1 1 4 ⋅ ( 3 ⋅ ( ) 2 )} 2 =1 1 4 ⋅ ( 4 ⋅ ( ) 3 )} 2 =1 1 4 ⋅ ( 5 ⋅ ( ) 4 )} 2 100 = 96 0 + 1⋅ 最後に,Sub プロシージャを用いず,全てをワークシート上でシミュレーションするプログラム例を示し ておく. G3 =G2+$B$5/6*(H2+2*I2+2*J2+K2) H3 =$B$1-$B$2*G3^(1/2) I3 =$B$1-$B$2*(G3+$B$5*H3/2)^(1/2) J3 =$B$1-$B$2*(G3+$B$5*I3/2)^(1/2) K3 =$B$1-$B$2*(G3+$B$5*J3)^(1/2) - 44 -