慣性振動の図示
これはなに
地獄の前期を終えて夏休みに入ったのでぼちぼちfortranとか総観気象学入門とかの進捗を生んでいるのですが、AtCoderの提出コードのように自分が書いたコードがすぐ見れないのがネックでした。そこでこのブログを思い出したのでなんかやったらちょこちょこ書いていきたいと思います。発見したことを発信するというよりは自分の備忘録として使いたいので、そんなに濃い内容はないかと思いますが生暖かい目で見てくれれば幸いです。
今回は慣性振動をfortranとgnuplotで図示したのでそれについて書いていきます。地衡風が生じる理由として「どんな方向にものをぶん投げてもコリオリ力で(北半球なら)進行方向の右に曲げられて、そのうち定常状態に落ち着いて地衡風になるよね」っていうよくある説明が厳密には正確じゃないな~ってことが分かると思います。
本題
出発点はおなじみ運動方程式です。空気塊の速度成分をとすれば
で与えられます。ただし摩擦項は速度の大きさに比例するとしました。(厳密にはです。)
ここで気圧傾度力は時間・空間的に一定として
とすれば見慣れた一階連立常微分方程式になるので
とおいてやれば
になります。これを初期条件の下で解いて
を得ます。これをいい感じに積分すれば変位になるので、初期条件のもとで積分して
となります(ただし)。微分方程式の問題集に出てきそう。
解が得られたので、後はfortranでコードを書いて解の様子を出力し、gnuplotで書くだけです。ソースコードは以下のようになりました。
module globals !初期条件や定数を格納するモジュール real(8),parameter :: pi=3.141592653589793d0 complex(8) :: G=(-1.0d0,1.0d0),W=(1.3d0,3.0d0) real(8),parameter :: f=0.7d0,gm=0.1d0 end module globals module subporog !地衡風・地上風成分を出力するモジュール use globals implicit none contains subroutine geo(t,n) integer :: i,n,fo=12 real(8) t,dt,nt complex(8) :: gt,gma=(gm,f) dt=t/dble(n) open(fo,file='geostrophic(frictional)') do i=0,n nt=dble(i)*dt gt=G*nt/gma write(fo,*)real(gt),aimag(gt) enddo close(fo) end subroutine geo end module subporog program main !メイン部分 use globals use subporog implicit none real(8) t,dt,nt integer :: n,i,fo=11 complex(8) :: ft,gma = (gm,f) write(*,*)"input parameter t'(0<t<t')" read(*,*)t write(*,*)"input step n(integer)" read(*,*)n dt=t/dble(n) open(fo,file="f=07(frictional).d") do i=0,n nt=dble(i)*dt ft=(W-G/gma)*(1.0d0-exp(-gma*nt))/gma+G*nt/gma write(fo,*)real(ft),aimag(ft) enddo close(fo) call geo(t,n) end program main
fortranは複素数型が定義されているんですね。メチャメチャ便利です。
パラメーターを、はじめにぶん投げる方向を、気圧傾度力の方向をとして図示したものが以下になります。ステップ数は2000にしました。
摩擦に引きずられて地上風が地衡風の左側にズレていることや、十分時間が過ぎた後では摩擦を考慮したほうは地上風に近づいている一方、摩擦を無視した方ではいつまで経っても振動しているのが見えますね。風が地上風に落ち着くには摩擦の効果がデカいというのがよくわかります。
地上風は等圧線と概ね30度くらいで交わるって言われてるのでパラメーターの初期値を適当に設定しすぎた感は否めませんが、fortranに慣れ親しむのが目的だったのでこれで良しとします。暇な人居たらいい感じにパラメーター設定してみてください。
最後に
fortranは神。息をするように扱える様になりたいです。