Previous | ToC | Next |
ここからが実習本番です。準備は大変だったかもしれませんが、実際に研究に
使われているパッケージですので、役に立つこともあると思います。
この実習では、
Cold Collapse とは、「冷たい」、つまり、粒子の速度分散等が系のサイズを
支えるだけの大きさがない粒子分布を作って、そこから時間発展をさせるとど
んなことが起こるか、という問題です。もちろん、宇宙でそのままのことが起
こるわけではないのですが、 現在のビッグバンモデルでは、例えば銀河といっ
た現在ある構造は、一様な宇宙膨張から重力ゆらぎが成長していって、膨張か
ら外れて収縮に移ってできるわけです。大雑把な理解としては、膨張から収縮
に移る、ということはどこかで最大膨張になったところがあり、そこではその
中の粒子は全部止まっているわけですから、 Cold Collapse というのはそう
いう状態のモデルであると考えることができます。
もっとも、現在の CDM 宇宙論では、小さいスケールの構造が先にできるので、
銀河系のような大きなサイズのものが一気に Cold Collapse でできるわけで
はありませんが、それでも Cold Collapse で何が起きるか、ということを理
解しておくことは宇宙における構造形成を理解する基本といえます。
能書きはさておき、まず初期条件を作ってみます。
nemo の中に役に立ちそうなプログラムはあるかをみます。nemo のプログラム
でモデルを作るものは大体 mk なんとかという名前なので、ls してみると、、、
並べかえには snapsort というプログラムが使えます。どんなオプションがあ
るかは、ヘルプオプションや man ページで確認して下さい。
ここでは、 PGPLOT に簡易なユーザーインターフェースをつけた wip という
プログラムでグラフを書き、そのためのデータは snapprint の出力を awkで
加工してみます。
人が作ったプログラムだから、自分が作ったものよりは信用できますが、
だからといってチェックしないで使ってはいけません。これは、プログ
ラムが間違っている可能性は(それまでに沢山の人が使っているものでも)必
ずあるし、また、プログラムが正しくても自分の使いかたが間違ってい
ることもある、というかこちらは良くある、からです。
さて、時間積分です。今回は、 hackcode1_qp という、 nemo に初めか
らはいっているプログラムを使ってみることにします。これは、
Barnes-Hut ツリーアルゴリズムで有名な Barnes 本人が1985年頃に書い
たものです。この、nemo というパッケージ自体が、その頃にプリンスト
ン高等研究所にいた Piet Hut, Josh Barnes と、現在も開発、メンテナ
ンスを 続けている Peter Teuben の3人が共同で始めたもので、構造化
されたバイナリファイルや、引数で数式を与えるとコンパイルして自分
自身にリンクする、といった仕掛けの最初の実装は Barnes によるもの
です。
と、これは余談ですが、 gadget とか、もっと速いコードを使ってもよ
いですが、今日の実習ではそこまではしないで、ユーザーインターフェー
スが簡単で安全に使える hackcode1_qp を使うことにします。例によっ
て help をみてみます。
試しに、入力、出力だけを指定して、あとはデフォルトでやってみましょ
う。
画面に一杯出力がでますが、なんだかわからないかもしれません。最後
の数行は
ウインドウをスクロールして上のほうに戻ると、最初のほうの出力は
理論的には、hackcode1 で使っている leap frog 公式では、エネルギー
の誤差は時間ステップの2乗に比例します。なので、これは大体正しい振
る舞いといえます。
結果を snapplot や glnemo で見てみます。
もうちょっとがんばって、ムービーを作ってみましょう。glnemo で、ア
ニメーションのアイコン(左のメニューの一番下)を押すと、アニメーショ
ンのメニューがでます。ここでまず、 Recording/Playing の「O」を押すとアニ
メーションの実行記録が始まります。そこで、左側の play ボタンを押
し、表示が終わる数フレーム前に(ここが極めて重要)
Recording/Playing の「X」を押します。
それが済んだら、入力スナップショットを巻き戻し(play の3角ボタンの下の
巻き戻しっぽいアイコン)、アニメーションのメニューウインドウのほうの
play の「>」ボタンを押して、
警告ウインドウがでたもので、以下の Rendering を実行すると、何故か X が
固まります。大変危険ですのでここは十分に注意して下さい。
上手くいったら、 Rendaring のメニューに移動して、スナップショットを巻
き戻した上で、「Start」をクリックします。そうすると、どこかに
(デフォルトは /tmp/render/frame.xxxxx.png, xxxxx は連番)フレーム毎の
png ファイルができます。これを、例えば animation gif に変換するなら、ファイルができているディレクトリで
さて、さっきは、エネルギーの最終の値をチェックしましたが、これだけでは
普通は十分ではありません。最後の値は良くても、途中でデタラメな値になっ
ていることもあるからです。これをチェックするためには、時間変化のグラフ
を作る必要があります。
hackcode1_qp は、出力のスナップショットファイルの中に、エネルギーや他
の色々な情報を埋め込んでいます。これは
wip でグラフを書いた例が図 21です。結構駄
目ですね。
エネルギー誤差が大きいのは、タイムステップが大き過ぎるせいではあります
が、初期条件が「一様」という特別なものであるためでもあります。
密度一様な球のコラプスは、密度一様なまま進む、という特徴があります。実
際の計算では粒子数が有限なので1点にはあつまらないですが、原理的には1点
に集まってしまうわけで、そうするとどんなにタイムステップを短くしても上
手くいきません。そういう、破綻する場合の積分方法の話も講義では少し触れ
たかもしれませんが、実習ではそこまで高度なことはしません。
逆にいうと、密度が一様でなければ、そこまでひどいことは起きないわけです。
密度一様でなくて、半径の-1乗にしてみます。
少しありえないほど細長いですが、楕円銀河のように見えないこともないもの
が出来ているはずです。エネルギーエラーも、ずっと小さくなっていること
が確認できます。
エネルギーエラーを計算する awk のスクリプトを少し変えると、ビリアル比
T/U が計算できます。この場合にビリアル比のグラフを出す、というのが最初
の課題、ということにします。 Energy の行で、 4 個めが T, 5個めが U な
ので、 $3 の代わりに $4/$5 をプリントさせればよいわけです。
さて、タイムステップをどんどん小さくしていくと、エネルギーエラーは小さ
くなりますが、ある程度以下にはならないことがわかります。それはなぜか、
また、さらに小さくするにはどうすればよいか、を調べるのは発展課題としま
す。
前に、初期条件をチェックするには累積質量分布を使いましたが、「どのよう
な銀河ができたのか」といった物理的な性質を見るのには累積分布はあまり
便利ではありません。なので、半径方向の空間密度分布を書いてみます。
nemo には radprof というプログラムがあるのですが、動作が気に喰わないと
いうか今一つ使えないので、snapprint の出力から書いてみることにします。
前に書いたように、どうしてもN体では粒子数によるゆらぎがあります。ここでは粒子
128 個毎に、その2つの粒子にはさまれた球殼の平均密度を、2つの粒子の半径
の平均の半径での密度とします。
式で書いたほうがわかりやすいですね。粒子が半径順に並んでいて、半径が
で質量が とすると、粒子 にはさまれた範囲の密度を
グラフは、この場合には
4. N 体シミュレーション実習
といったことができるようになる、ということを目標にします。
4.1. Cold Collapse
4.1.1. 前置き
4.1.2. 初期条件の作成とその検証
%ls $NEMOBIN/mk*
/home/makino/work/nemo_cvs/bin/mkbaredisk
/home/makino/work/nemo_cvs/bin/mkconfig
/home/makino/work/nemo_cvs/bin/mkcube
/home/makino/work/nemo_cvs/bin/mkdisk
/home/makino/work/nemo_cvs/bin/mkexpdisk
/home/makino/work/nemo_cvs/bin/mkexphot
/home/makino/work/nemo_cvs/bin/mkflowdisk
/home/makino/work/nemo_cvs/bin/mkhom
/home/makino/work/nemo_cvs/bin/mkhomsph
/home/makino/work/nemo_cvs/bin/mkkd95
/home/makino/work/nemo_cvs/bin/mknemo
/home/makino/work/nemo_cvs/bin/mkommod
/home/makino/work/nemo_cvs/bin/mkop73
/home/makino/work/nemo_cvs/bin/mkorbit
/home/makino/work/nemo_cvs/bin/mkpdoc
/home/makino/work/nemo_cvs/bin/mkplummer
/home/makino/work/nemo_cvs/bin/mkpolytrope
/home/makino/work/nemo_cvs/bin/mksphere
/home/makino/work/nemo_cvs/bin/mkspiral
/home/makino/work/nemo_cvs/bin/mktestdisk
やたら沢山あります。ディスクっぽいものが多いですが、ここでは mkhomsph
というのを使ってみます。
%mkhomsph help=
mkhomsph out=??? nbody=2048 rmin=0 rmax=1.2 2t/w=0.0 vmax=0 power=0 seed=0 zerocm=t headline= VERSION=1.4b
%mkhomsph test4k 4096
%glnemo test4k
という感じで、どんなものができるかみてましょう。
%snapsort test4k test4k.sort rank=r
で、半径方向に並べかえてくれます。次に、「半径方向の累積質量分布」を作っ
て、これを半径をグラフにしてみたい、ということになります。
%snapprint test4k.sort options=r,m | awk '{macc += $2; print macc, $0}' > tab.out
ruby や perl を使ってもよいですが、こういう使い方なら awk が簡単です。
ここでは、ソートした test4k.sort から、粒子の位置の半径と質量が1行に
なった出力を作り、それを awk で処理します。 awk でやっていることは
macc という変数に 1行の2つめの数 ($2) を加算し、加算した macc と読み込
んだ行全体を出力する (print macc, $0) というものです。 {} でくくった中
を1行毎に実行する、というのが awk の基本動作で、さらに '' でくくってい
るのはこれ全体をシェルに解釈させないで awk に渡すためです。 tab.out が
どんなファイルかみてみましょう。
% head tab.out
0.000244141 0.0480947 0.000244141
0.000488282 0.0717042 0.000244141
0.000732423 0.120009 0.000244141
0.000976564 0.137944 0.000244141
0.00122071 0.154036 0.000244141
0.00146485 0.157324 0.000244141
0.00170899 0.163142 0.000244141
0.00195313 0.163527 0.000244141
0.00219727 0.164162 0.000244141
0.00244141 0.164364 0.000244141
こんな感じ(2列目の距離の数字は乱数の初期値によって違うはず) で、最初の
ほうでは距離の数字が小さく
% tail tab.out
0.997804 1.21369 0.000244141
0.998048 1.2137 0.000244141
0.998293 1.21397 0.000244141
0.998537 1.2148 0.000244141
0.998781 1.21576 0.000244141
0.999025 1.21585 0.000244141
0.999269 1.21661 0.000244141
0.999513 1.21795 0.000244141
0.999757 1.21842 0.000244141
1 1.2211 0.000244141
最後のほうでは大きくなっていればもっともらしいです。グラフは
%wip
Could not open user's WIP initialization file.
Setting up default device [/XWINDOW]
Welcome to WIP Version: 2.3 22jan98
WIP> device /xs
WIP> data tab.out
WIP> xcol 2
WIP> ycol 1
WIP> limit
WIP> box
WIP> conn
こんな感じでコマンドをいれると図 20 の
ようなグラフがでるはずです。なお、 wip は end で終了します。
%snapprint test4k.sort options=r,m | awk '{macc += $2; rs=$1/1.2; print macc, $0, rs*rs*rs}' > tab.out
wip
Could not open user's WIP initialization file.
Setting up default device [/XWINDOW]
Welcome to WIP Version: 2.3 22jan98
WIP> device /xw
WIP> data tab.out
WIP> xcol 2
WIP> ycol 1
WIP> era
WIP> limit
WIP> box
WIP> conn
WIP> ycol 4
WIP> color 2
WIP> conn
WIP> end
が4列目のデータになっているはずなので、それを ycol 4 で
y軸方向のデータとして読み、 color 2 で赤に変えてプロットしています。
グラフは載せませんが、ちゃんとあっていることを各自確認して下さい。
4.1.3. 時間積分
%hackcode1_qp help=
hackcode1_qp in= out= restart= continue= save= nbody=128 seed=123 cencon=false freq=32.0 eps=0.05 tol=1.0 fcells=1.0 options=mass,phase tstop=2.0 freqout=4.0 minor_freqout=32.0 debug=false VERSION=1.4
色々謎なパラメータがあるので、 man hackcode1_qp 、、、あれ、そん
なの知らない、とでますね。 man hackcode1 でマニュアルを見ることが
できます。 qp がつくと4重極モーメントを使って、より正確に力を計算
するものになっています。
%hackcode1_qp test4k test4k.outsnap
4.1.4. エネルギー誤差のチェック
tnow T+U T/U nttot nbavg ncavg cputime
2.000 -0.4579 -0.7211 796020 39 155 0.13
cm pos 0.0007 -0.0011 -0.0015
cm vel 0.0026 -0.0014 -0.0037
particle data written
という感じのはずです。(細かい数字は違います) tnow は時刻、 T+U は
系のトータルエネルギー、 T/U は運動エネルギー T とポテンシャルエ
ネルギー U の比、いわゆるビリアル比です。力学平衡の状態ならこれは
-0.5 です。その次の3つの数字はツリーコードでの計算量を示していて、
1ステップで粒子への力を計算した回数、1粒子への、粒子からの力の数
の平均、1粒子への、ツリーノードからの力の数の平均、となっています。
その下の cm pos, cm vel は、系全体の重心の位置と速度です。大体0で
すが少し動いているのがわかります。
Hack code
nbody freq eps tol
4096 32.00 0.0500 1.0000
options: mass,phase
tnow T+U T/U nttot nbavg ncavg cputime
0.000 -0.4983 -0.0000 425175 17 86 0.00
cm pos -0.0000 -0.0000 0.0000
cm vel 0.0000 0.0000 0.0000
particle data written
tnow T+U T/U nttot nbavg ncavg cputime
0.031 -0.4983 -0.0003 424385 17 86 0.01
cm pos -0.0000 0.0000 -0.0000
cm vel -0.0000 0.0000 -0.0000
というような感じだと思います。freq はタイムステップの逆数、 eps
は重力ソフトニングの値、 tol はツリーコードの opening angle で、
小さくすると精度は上がりますが計算量も増えます。ここでエネルギー
である T+U の値を比べると、 -0.4983 だったのが -0.4579 になって、
大きく変わってしまっています。これでは駄目そうな感じがするので、
タイムステップを小さくしてみましょう。
%hackcode1_qp test4k test4k.outsnap freq=128
Hack code
nbody freq eps tol
4096 128.00 0.0500 1.0000
options: mass,phase
### Fatal error [hackcode1_qp]: stropen: file "test4k.outsnap" already exists
nemo のプログラムは、出力ファイルがすでにあったらアボートするよう
になっています。
%rm test4k.outsnap ; hackcode1_qp test4k test4k.outsnap freq=128
tnow T+U T/U nttot nbavg ncavg cputime
2.000 -0.5006 -0.7081 780717 38 151 0.92
cm pos 0.0012 -0.0003 -0.0008
cm vel 0.0038 0.0004 -0.0020
freq=128 を指定して、タイムステップをデフォルトの 1/4 にしてみた
結果です。劇的にエネルギー保存が改善されているのがわかります。最
初のでは 10% 程度だったものが、 0.5% 程度になっています。
4.1.5. アニメーション
%snapplot test4k.outsnap
%glnemo test4k.outsnap
どちらも、パラパラ漫画ふうですが、出力間隔が大き過ぎて気分がでま
せん。間隔を変えるオプションは freqout なので、これも指定してもう
一度実行してみます。
%rm test4k.outsnap ; hackcode1_qp test4k test4k.outsnap freq=128 freqout=32
今度は snapplot 等でもう少し気分がでると思います。
を確認して下さい。警告ウインドウがでてしまったら、 Recording からやり
直して下さい。
%convert *.png anim.gif
でOKです。gif アニメは、ブラウザで見ることもできますが、何が起こってい
るか、の物理を直観的に理解するためには、1コマずつ進めるとか、逆に戻る
とかが簡単にできるツールが必須です。結構、なかなか適当なものがありませ
ん。 gif アニメの表示には xanim が便利ですが、開発が止まって 10年ほど
たつこともあり Cygwin や Linux の最近のディストリビューションにははいっ
ていません。 Gnome があれば、GImageView はあまり便利ではないですが一応
それらしいことができます。Windows でも Explorer で沢山の画像ファイルを
見る、というのが簡単な方法のような気がします。
4.1.6. エネルギー誤差の時間変化グラフを作る
%tsf test4k.outsnap
で見ることができます。最後のほうの出力が
set SnapShot
set Parameters
int Nobj 4096
double Time 2.00000
tes
set Particles
int CoordSystem 66306
double Mass[4096] 0.000244141 0.000244141 0.000244141 0.000244141
0.000244141 0.000244141 0.000244141 0.000244141 0.000244141
0.000244141 0.000244141 0.000244141 0.000244141 0.000244141
0.000244141 0.000244141 0.000244141 0.000244141 0.000244141
. . .
double PhaseSpace[4096][2][3] 0.153245 0.0136813 -0.205303 1.79778
-0.760285 -0.378773 -0.454063 0.919896 -0.552425 -0.704771
1.34618 -1.00689 -0.983543 -0.662581 -0.412249 -1.66848 -1.23127
-0.691078 0.153962 0.0313744 -0.0690967 1.43265 -0.379112
. . .
tes
set Diagnostics
double Energy[3] -0.500630 1.21438 -1.71501
double KETensor[3][3] 0.377060 0.0249498 -0.0361606 0.0249498
0.380638 -0.0253557 -0.0361606 -0.0253557 0.456682
double PETensor[3][3] -0.413097 0.0255456 0.0248519 0.0249459
-0.417775 0.0157845 0.0236208 0.0148032 -0.599691
double AMTensor[3][3] 0.00000 -0.000262578 0.000150161 0.000262578
0.00000 -0.000102650 -0.000150161 0.000102650 0.00000
double CMPhaseSpace[2][3] 0.00120219 -0.000280852 -0.000787409
0.00384288 0.000367961 -0.00195136
double cputime 0.778333
tes
tes
ですから、
をプロットすればよさそうです。また awk を使うことにすると
%tsf test4k.outsnap | awk '/Time/{t=$3}/Energy/{print t, $3}' > tab.out
です。 /Time/{t=$3}は、入力行が正規表現 /Time/ と一致したら、括弧内を
実行、で、 Time という文字列w含む行の3個めの文字列(区切りはスペース)を
t という変数に代入、/Energy/{print t, $3} は同様に Energy を含む行にき
たら、 t の値と 3個めの文字列をプリント、となります。
4.1.7. 初期条件を変えてみる
%mkhomsph test4kb 4096 power=1
これも、累積質量分布がちゃんと出来ていることを確認しましょう。
% hackcode1_qp test4kb test4kb.outsnap freq=128 freqout=32 tstop=10
で少し長い計算をして glnemo でアニメーションを作ったりしてみましょう。
4.1.8. 密度分布を書く
{
m+= $2
if ( NR % 128 == 0){
r1 = $1
print (r1+r0)/2, m/(r1*r1*r1-r0*r0*r0)*0.2387
m=0
r0=r1
}
}
awk には、
といった特性があるので、割合簡潔に処理を表現できているのがわかります。
なお、 awk なんていう大昔の言語は嫌だ、もうちょっと現代的なものがよい、
という向きには、例えば Ruby を使うなら
r0=m=0
while s=gets()
a=s.chomp.split
m+= a[1].to_f
if ( $. % 128 == 0)
r1 = a[0].to_f
print (r1+r0)/2, " ",m/(r1*r1*r1-r0*r0*r0)*0.2387, "\n"
m=0
r0=r1
end
end
という感じですが、これでは awk に比べて面倒なだけでメリットはありませ
ん。どちらの場合でも
%snapprint test4k.sort options=r,m | awk -f density.awk > tab.out
とか
%snapprint test4k.sort options=r,m | awk -f density.rb > tab.out
とかすれば、それらしいデータがでているはずです。(もちろん、上のコードを
そういう名前でファイルにセーブする必要があります) 前と同様にグラフを書
いてみましょう。折角 ruby を使うのでもう少し気の効いたことをするなら、
プログラムを2行ばかり変更して
r0=m=0
open("|snapprint #{ARGV[0]} options=r,m"){|io|
while s= io.gets()
a=s.chomp.split
m+= a[1].to_f
if ( $. % 128 == 0)
r1 = a[0].to_f
print (r1+r0)/2, " ",m/(r1*r1*r1-r0*r0*r0)*0.2387, "\n"
m=0
r0=r1
end
end
}
として見る、といったこともできます。この場合は、 ruby プログラムの中で
snapprint #{ARGV[0]} options=r,m を実行して、その出力を io.gets() で読
む、というふうにしています。こうしておくと、
%ruby density2.rb test4k.sort
という形で実行できるので、沢山のファイルについて密度分布を書く、と
いった場合にやりやすいし、後になってこのプログラムの使いかたをすっかり
忘れた時にも、 snapprint をどう使ったかは書いてあるので安全です。
まあ、ヘルプとか、色々つけておくとあとで助かるのですが、世間で普通に使
われている方法は面倒であまり使いやすくないように思います。プリンストン
高等研究所の Piet Hut (Barnes-Hut ツリーコードの Hut) と牧野が少し前に
「コマンドラインオプションのパーザはどうあるべきか」だけで本一冊分くら
いの原 稿を書いたことがあるので、そういうのに興味がある人は読んで見ると
得ることがあるかもしれません。
%wip
Could not open user's WIP initialization file.
Setting up default device [/XWINDOW]
Welcome to WIP Version: 2.3 22jan98
WIP> device /xw
WIP> data tab.out
WIP> xcol 1
WIP> ycol 2
WIP> limit
WIP> era
WIP> box
WIP> conn
という感じで書けると思います。これを、シミュレーションの最後のスナップ
ショットに適用してみましょう。最後のスナップショットに snapsort とかを
適用するには、最後のスナップショットを切り出すコマンドを使うのが便利で
す。
%snaptrim test4kb.outsnap - times=10 | snapsort - - rank=r |\
? snapprint - options=r,m | ruby density.rb > tab.out
### nemo Debug Info: r m
### nemo Debug Info: time = 10 npart = 1 ndiag = 1 outputing particles
4.1.9. 提出課題
なお、提出用のファイルを作るには、画面のスクリーンショットとかでもいけ
なくはないですが、例えば TeX の場合 ps ファイルを作るのが便利です。
WIP の場合、
%wip
Could not open user's WIP initialization file.
Setting up default device [/XWINDOW]
Welcome to WIP Version: 2.3 22jan98
WIP> device xxx.ps/vcps
と、device コマンドで出力を ps ファイル(この場合、名前が xxx.ps) にす
ることができます。この後で
WIP> viewport 0.2 0.9 0.3 0.8
を実行すると大体正方形のグラフになるはずです。
Previous | ToC | Next |