プログラムな日常>ウェブプログラム作品集>
実用的な陽解法の基本
(useful contrivances in explicit simulations)
(reset and) move <--> stop
θ0(initial)
A(interval)

【陽解法について】

シミュレーションの手法である陽解法について検索すると、簡単ではあるが「精度、安定性、計算能率が悪い」方法とする解説が多いが、 私は陽解法の効果的な事例に多く出会っているので、陽解法のために残念に思っている。

そもそも何が陽解法かということから論じるべきかも知れない。 例えば、既存のある サイト(国立天文台) を信じるなら、時間微分的変量 E と、その時間積分(例えば加速度に対する速度、あるいは速度に対する位置)Q とが存在する場合、次の2つの場合

  1. Qn, En → Qn+1
  2. Qn-1, En → Qn+1
は、どちらも陽解法と呼ぶことができるようだ(ここで添え字は時間軸上の序列)。 この内、1は問題外としても、2を適切に行えば、定性的にも精度的にも申し分ない方法を多くの場合に提供可能だ。

今、バネ定数 k のバネ(片端は固定)に支えられた質量 M の一次元振動を考える(上下には動かず、左右にのみ動く)。


位置を r (安定点をゼロ)、その速度を v 、加速度を a とする。関係式は、

   r = v dt
   a = -(k/M) r
   v = a dt

差分化すると、

   rn = rn-2 + 2 Δt vn-1
   an = -(k/M) rn
   vn+1 = vn-1 + 2 Δt an

番号の付け方は、例えば n を偶数とし、r と a については偶数番のみ、v については、奇数番のみを有効とする。 そうでない系列(r と a について奇数番、v について偶数番)を並行させても良いが、両系列の微妙な不一致のため、細かな振動が残るように見えてしまうことがある。 過去の 記事 でこれを並行させたときには、(両系列に連携がある)連続体だったので同じ問題は起こらなかった (と言うか、ずれがあれば振動が残るのが当然という条件だった)。

添え字が連番ではない上の式が気持ち悪いという向きには、次のように書くこともできる。

   rn = rn-1 + Δt wn-1
   an = -(k/M) rn
   wn = wn-1 + Δt an

ここで、wn は、vn+0.5 とも読み替えるべきものである。 wn-1 は、vn-0.5 と読み替えられる。 これらの式で Δt は例えば、これらの式の rn から rn+1 までの時間間隔に相当する。

このような陽解法で求められる周期運動は安定であり、そのことには明確な理由がある。 各変数の因果関係は下の図のように要約されるが、ここで、過去から未来に向かっている赤い矢印のみ反転させ、 (過去から未来でなく)未来から過去に向かう逆計算が正確にできる。 現象は時間に対して対称なので、たとえば振動現象は、未来、過去のどちらの方向にも、増大も減少もせず維持される。 ただし、この事例ではそうであるとしても、順方向も含め、簡単に計算できるかどうかは、実は場合によるかも知れない。



【ウェブプログラムについて】

今回のウェブプログラムは、支点、質量、(縮まない)竿から成る振子である。

   θn = θn-1 + Δθn-0.5
   Δθn+0.5 = Δθn-0.5 - A sin(θn)
   A = G Δt2/R

「move」のチェックを外した状態で第一のスクロールバーを動かすと、初期状態を設定できる。 第二のスクロールバーで、時間の荒さを変えられる。 初期速度はゼロ( Δθ0.5 = - A sin(θ0)/2 )としているので、正確な計算では頂点を越えることはないはずだが、初期位置が高く時間間隔が荒い場合、(誤差により)越えてしまうこともある。 ただし、越えるような条件でないときは、長時間になっても越えず、また、振動が広がることも止むこともなく、ある意味、安定である。