応用物理学セミナーA 先進工学部
武藤恭之
工学院大学
基礎・教養教育部門
1 Linux の基礎
1.1 歴史
Linux とは、1991年にヘルシンキ大学の学生であった Linus Torvalds氏によって開 発が始められた、オペレーティングシステム(OS)の総称である。誰でも開発が可能な
「オープンソース」の形で提供され、様々な人によって開発が進められてきた。Linuxに は様々な種類(ディストリビューション)があり、その上で動くソフトウェアも様々なも のがある。安定なシステムとして定評があり、科学計算・システム開発など、様々な分野 で広く使われている。
Linuxは、基本的にコマンドラインで操作することが多く(最近はGUIも普及してき
たが)、初めは敷居が高いが、コマンドを覚えると非常に使いやすい。
1.2 ディレクトリ構造
Linuxは、ディレクトリ構造のもとに設計されている。ディレクトリは、Windowsで
「フォルダ」と呼ぶものと同じで、様々なファイルを入れておくための入れ物のようなも のである。入れ物の中にさらに入れ物が入っていることもある。
Linuxのおおもとのディレクトリは「/」という名前がついた「ルートディレクトリ」で
ある。この下に、様々なファイルが格納されている。一つの計算機をたくさんの人数で使 うことができるように、それぞれのユーザーごとのファイルが「/home/username」とい うディレクトリの中に入るようになっている。ただし、usernameは使用者ごとに異なっ ている。実際に使う場合には、この「/home/username」以下のディレクトリの中に自分 でファイルやディレクトリを作りながら作業をしていく。
2 操作手順
2.1 ログインの仕方
まず手始めに、ログインをしてみよう。情報センターの端末から、大学の教育用システ ムにログインする。
端末の画面で「Putty」と呼ばれるソフトを立ち上げ、ホスト名に:
urban.ccs.kogakuin.ac.jp
と、ポート番号「22」を指定し、接続する。設定の画面で「変換」を開き、文字コードを
「EUC-JP」にしておくと、日本語が文字化けしなくて良い(かも)。
IDとパスワードを聞かれるので、情報センターのIDとパスワードを入力し、ログイン する。
2.2 自分の居るディレクトリを確認する
Linuxを使うに当たっては、自分が今どのディレクトリに居て、どのファイルを操作し
ているかを常に把握していなければならない。そこで、自分の今いるディレクトリを確認 するコマンドが:
pwd
というコマンドである。まず、ログインしたら、「pwd」と入力してエンターキーを押して みよう。通常
/home/usename
というような出力が得られるはずである。この出力が、自分が現在居るディレクトリを 表す。
2.3 今日使うファイルの取得
何かブラウザを立ち上げて:
http://www.ns.kogakuin.ac.jp/~ft13389/seminarA/
にアクセスすると、「hello.c」というファイルと「seminarA_muto.tar.gz」というファ イルがあるのが分かるだろう。これらが、今日の演習で使用するファイルである。
Puttyの画面で、今居る場所が:
/home/username
であることを確認する。その場所に居なければ:
cd ~
と入力する。その上で
wget http://www.ns.kogakuin.ac.jp/~ft13389/seminarA/hello.c
wget http://www.ns.kogakuin.ac.jp/~ft13389/seminarA/seminarA_muto.tar.gz と入力する。こうすると、現在居るディレクトリに、上記の二つのファイルがコピーさ れる。
2.4 ディレクトリの中身を見る
今居るディレクトリの中身を確認するには:
ls
と入力する。
ちゃんと「hello.c」と「seminarA_muto.tar.gz」がダウンロード出来ているかを確 認しよう。
2.5 ディレクトリを作成する
様々な作業を行う際は、ディレクトリを分けて行って、色々なファイルが混ざらないよ うにするのが良い。そこで、今日の作業のためのディレクトリを作る。今居るディレクト リの直下に、「seminarA」というディレクトリを作るには:
mkdir seminarA と入力する。
2.6 ファイルのコピーと移動
先ほどダウンロードした二つのファイルを、作業用のディレクトリに移そう:
cp hello.c seminarA/
と入力すると、「hello.c」が、「seminarA」にコピーされる。
また:
mv seminarA_muto.tar.gz seminarA/
と入力すると、「seminarA_muto.tar.gz」を、「seminarA」に移動させることができる。
この二つのコマンドを打ったら、「ls」で、ディレクトリの中身を確認してみよう。
「hello.c」のみが残っているはずである。
2.7 ファイルを削除する
「hello.c」は、作業用のディレクトリの中で使うので、今居るディレクトリには必要
が無い。そこで、このファイルを削除しておく:
rm hello.c
と入力すると、ファイルを削除できる。
注意:「rm」コマンドは、Windowsのように「ゴミ箱」にファイルを移すことなく、
直接ファイルをシステムから削除してしまう。いったんファイルを削除すると、元には戻 せないので、細心の注意が必要である。重要なファイルを消してしまうと、システムその ものが止まってしまう可能性がある。
2.8 ディレクトリを移動する
次に、居る場所を、作業用のディレクトリに移ろう。
cd seminarA
と入力すると、ディレクトリを移ることができる。
この後、「pwd」を入力し、現在の場所を確認した上で、「ls」を入力してディレクトリ の中のファイルを確認しよう。先ほどのコピー・移動がうまくいっていれば、「hello.c」 と「seminarA_muto.tar.gz」が見えるはずである。
2.9 テキストファイルの中身を確認する
テキストファイルの中に何が書かれているかを簡単に確認する方法がいくつかある。こ こでは、「hello.c」の中身を確認してみよう。
less hello.c
と入力すると、「hello.c」の中身が表示される。プログラムらしき何かであることが分 かるだろう。
その後 q
を入力すると、もとの状態に戻る。
2.10 プログラムをコンパイルして実行する
「hello.c」は、C言語で書かれたプログラムである。これを実行するためには、一度、
「コンパイル」という手続きを踏み、実行ファイル(アプリケーションあるいはソフトウェ ア)を作ってから、その実行ファイルを実行させる。
プログラムのコンパイルには、「コンパイラ」と呼ばれるソフトを使う。コンパイラは
「人間が読み書きできるプログラムを、コンピュータが認識できるソフトの形に作り直す」
ことをするソフトである。
世の中には様々なプログラムがあるが、ここではインテル社の作っているインテルコン
パイラを使ってみよう。
icc -o hello.out hello.c
と入力して、コンパイルをしてみよう。このコマンドは、「hello.cというコードを、icc を使ってコンパイルしhello.outという実行ファイルを作れ」という意味である。icc のオプションの一つである、-oの後に続く文字列で、実行ファイルの名前を指定する。そ して、スペースを空けて、もとのコードのファイル名を入力する。
コンパイル終了後、「ls」を入力してディレクトリの中身を確認すると、「hello.out」 が出来ているのが分かるだろう。
この実行ファイルを動かすには:
./hello.out
と入力する。はじめの「ドットスラッシュ」を忘れないこと。プログラムを実行すると hello, world
と表示されるだろう。
注:Linux上で使える無料のコンパイラとしては、gccが代表的であり、幅広く使われて
いる。gccもiccも、基本的なオプションは同じであり:
gcc -o hello.out hello.c とすれば、gccでコンパイルされたものを作ることがで きる。
2.11 hello.c の内容
hello.cは、「『hello, world』という文字列を画面(標準出力)に表示して終了する」と いうプログラムである。実際に中身を見ると
#include<stdio.h>
int main(void) {
printf("hello, world\n");
return 0;
}
というプログラムである。
1行目の「#include<stdio.h>」は、C言語を書く上でのオマジナイのようなもので、
ここでは触れない。
2行目に「int main(void)」と書かれており、そこから中カッコ{}で挟まれた二行 が続いている。ここが、このプログラムのメインの働きをする部分である。
4行目の「printf("hello, world\n");」が、「hello, world」という文字列を出力す る命令である。「printf」が、標準出力に表示をするための命令で、カッコの中の、ダブ ルクオーテ―ション””で囲まれた文字列を出力する。ただし、“”の最後の「\n」は、改 行を表す(ので、出力では見えない)。
2.12 ファイルを編集する
さて、「hello.c」を編集して、好きな文字列を表示させてみよう。ファイルを編集す
るには、「エディタ」と呼ばれる種類のソフト(Windowsでのメモ帳のようなソフト)が 必要になる。Linuxで使えるエディタとして、ここではemacsを使う。
emacs -nw hello.c
と入力して、emacsを立ち上げ、「hello.c」を開こう。
次に、キーボードの上下キーを使い、カーソルを編集したい「hello, world\n」の部 分まで持っていこう。ここで、「hello, world」の部分を好きな文字列に編集する。マウス は使えないので注意すること。
文字列を編集すると、右下の部分に「**」という記号が出現する。この記号は、「ファ イルがまだセーブされていない」ということを意味している。そこで:
Ctrlキーを押したまま「x」と「s」を順に押す
という入力を行う。これで、ファイルがセーブされる。
入力とセーブを繰り返し、希望の文字列を入力し終えたら:Ctrlキーを押したまま「x」 と「c」を順に押す
という入力を行う。これで、emacsは終了し、コマンドの入力画面に戻る。
できたプログラムをコンパイルして実行してみよう。
注:本当は、viと呼ばれるソフトを使いこなせるとより良い。
3 微分方程式の数値計算
物理では、様々な問題が微分方程式の形で定式化されており、世の中の現象を予測する ために、これらの方程式を数値的に解くということがよく行われる。
ここでは、「微分方程式を数値的に解く」とはどのようなことかの雰囲気を味わっても らうために、簡単な運動方程式を解く。
具体的な問題として、単振動の問題 md2x
dt2 =−kx (1)
を解くことを考える。一年生の物理学の授業で習ったように、この解は
x(t) =Acos(ωt) +Bsin(ωt) (2)
で与えられ、ω =√
k/mが角振動数である。また、AとBは初期条件で決まる定数であ りt = 0に位置がx0、速度がv0 であったならば、A =x0 およびB = v0/ω となる。ま た、運動エネルギーK = 1
2mv2 と位置エネルギーU = 1
2kx2 の和(全力学的エネルギー E)は運動を通して一定であり、その値は
E = 1
2mv02+ 1
2kx20 (3)
である。
3.1 オイラー法による数値計算
初期条件を決まれば、微分方程式の解は一通りに決まる。コンピュータに微分方程式を 解かせるとは、与えられた初期条件のもと、その後の時間発展を数値的に求めるというこ とである。
しかし、コンピュータは、「微分」といった連続的な量を扱うことはできない。そこで、
コンピュータに解けるように、もとの微分方程式を「離散化」し、近似的な方程式を解か せるということをする。微分方程式を数値的に解く上で重要なのは
• うまく問題を差分化する
• 離散化による誤差がどの程度あるかをきっちりと見積もる
という点に尽きる。出てきた解が本当の解をどれだけうまく表現しているかを、何らかの 方法で見積もらなければならない。
まず、式(1)を少し変形し、二つの連立一階微分方程式の形に書き直す:
dx
dt =vx (4)
dvx
dt =−ω2x (5)
実際に数値計算をするのは、この二つの一階微分方程式の組み合わせである。
最も単純な離散化の方法は、微分を次のように簡単な差分で置き替えることである:
dx
dt → x(tn+1)−x(tn)
∆t +O(∆t2) (6)
ここで、tn は、差分化した時刻を表す。t = t0 から始まり、∆tごとに、t1 = t0+ ∆t, t2 = t0 + 2∆t, · · · と、その後の時刻における物体の位置を求めていく。この差分化に よって、式(4)と式(5)を書き直すと
x(tn+1)−x(tn)
∆t =vx(tn) (7)
vx(tn+1)−vx(tn)
∆t =−ω2x(tn) (8)
となるから、時刻t=tn+1での物体の位置と速度は、その直前のt=tn での値を用いて x(tn+1) =x(tn) +vx(tn)∆t (9) vx(tn+1) =vx(tn)−ω2x(tn)∆t (10) と求められることが分かる。この式(9)と式 (10)を用い、t = t0 での位置と速度を初期 条件として、その後の時刻における位置と速度を求めていく方法をオイラー法といい、こ の方法における精度は1次であるという。
3.2 オイラー法による単振動の問題の数値計算
3.2.1 ファイルの展開
ディレクトリ「seminarA」に居ることを確認し、「ls」を入力して、ディレクトリの中 に「seminarA_muto.tar.gz」があることを確認する。これは、zipのように、いくつか のファイルをまとめて一つの圧縮ファイルにしているものである。これを展開するため に:
tar xvzf seminarA_muto.tar.gz
と入力する。再び「ls」をすると、「harmonic_oscillator」というディレクトリが出来 ている。
cd harmonic_oscillator
でこのディレクトリに移り、「ls」をすると、いくつかのファイルがあることが分かるだ ろう。
3.2.2 コードのコンパイルと実行
ディレクトリ「harmonic_oscillator」の中で、特に重要なファイルは以下の二つで ある:
main.c · · · コード本体
test.par · · · 入力パラメータ用ファイル
なにはともあれ、コードを走らせてみよう。まず、以下のようにコマンドを入力し、コ ンパイルを行う:
icc -o main.out main.c -lm
これで、実行ファイル「main.out」が出来ている。最後の「-lm」は、数学関数を使うた めのオマジナイ。
この「main.out」は、入力のパラメータファイルと、出力のファイルが必要であり、次
のようなコマンドで実行する:
./main.out (パラメータファイル名) (出力ファイル名)
たとえば、パラメータのファイルが「test.par」で、出力のファイル名が「test.txt」 であるならば:
./main.out test.par test.txtと入力する。このコマンドを実行してから「ls」をす ると、test.txtができているのが分かるだろう。
3.2.3 パラメータファイルの書式
test.parの中身を:
less test.par
で見てみると、次のように、「変数名」と「その数値」が、タブ文字で区切られて入力され ていることがわかる・
MASS 1.0
SPRING 1.0
EXTERN_FORCE_AMP 0.0 EXTERN_FORCE_FREQ 0.0
X0 1.0 Y0 0.0 DXDT0 0.0 DYDT0 0.0
DT 0.03 TINI 0.0 TFIN 30.0
INTEGRATE_ORDER 1
DT_OUT 0.1
今のところ、理解しておく必要があるパラメータは、以下の通り:
• MASS· · · 質点の質量
• SPRING · · · ばね定数
• X0· · · x方向の位置の初期条件
• DXDT0 · · · x方向の速度の初期条件
• DT離散化する時間の刻み幅
• INTEGRATE_ORDER · · · 離散化の次数(オイラー法なら1)
また、コードはxy面の二次元で解けるようになっているが、当面は1次元(x方向)し か使わない。
3.2.4 出力ファイルの書式
出力ファイルの中身を:less test.txt で確認すると、たくさんの数値が、スペース で区切られて並んでいることが分かるだろう。
一行目に、それぞれの列が何を表しているかが書かれており:
• 1行目: 時刻
• 2行目: x座標
• 3行目: y座標
• 4行目: x方向の速度vx
• 5行目: y方向の速度vy
• 6行目: 運動エネルギー
• 7行目: ポテンシャルエネルギー
• 8行目: 全エネルギー を表している。
3.2.5 出力ファイルのグラフ化
計算ができたら、数値データをグラフに表し、物体の運動の様子を見てみよう。Linux 上で全てグラフまで作成することが可能だが、演習室の環境の都合上、データを手元に落
として、Excelを使ってグラフを作ることにする。
まず、WinSCP を用いて、データを手もとに落とすための準備をする。WinSCPを起
動し、ホスト名に:urban.ccs.kogakuin.ac.jpを入力する。次に、ポート番号が「22」 となっていることを確認し、ユーザー名に情報センターのIDを入れ、いったん「保存」
しておく。
次に、「保存したセッション」から、先ほど保存したプロファイルを選んで、ログイン をする。パスワードを聞かれるので、情報センターのパスワードを入力する。
向かって左側が自分のパソコンを表し、右側が接続先の情報センターのシステムを表し ている。ディレクトリは、それぞれの画面の上に表示されている。右の画面で、先ほど計 算して結果のファイルが置かれたディレクトリに移る。また、左の画面で、自分の手もと のパソコンの適当なディレクトリを選んでおく。
右の画面からデータのファイルを選び、左の画面にドラッグ&ドロップをすると、ファ イルがコピーされる。
コピーされたファイルをExcelで開く。Excelを立ち上げてファイルを開く時、「すべ てのファイル」を選んでおかないと、表示がされない(かもしれない)ので、気を付ける こと。
その後、データのファイル形式として、「カンマやタブなどの区切り文字によってフィー ルドごとに区切られたデータ」を選び、区切り文字として「スペース」を選択する。する と、先ほどのデータがExcelに読み込まれるので、これをもとにグラフを作成する。グラ フの作成の仕方は、「情報処理入門」などで習っているはず…?
【課題:基本】 今のデータに基づき、x座標とtの関係を表すグラフを作成せよ
【課題:基本】 今のデータに基づき、全エネルギーとtの関係を表すグラフを作成せよ この結果を見ると:
• 本当は単振動をするはずなのに、振幅がどんどん大きくなっている
• 全エネルギーが保存するはずなのに、どんどん大きくなっている ことがわかる。
今回のパラメータでは:
• 質点の質量: 1
• ばね定数: 1
• 初期の(x方向の)位置:1
• 初期の(x方向の)速度:0 なので、時刻tにおける位置は
x(t) = cos(t) (11)
と表され、全エネルギーは0.5となっているはずである。
【課題:基本】 数値的に求まった解と本当の解のずれが、何パーセントになっているか を計算し、時間を横軸に取ったグラフとして表せ。
【課題:基本】 数値的に求まった全エネルギーと本当の値のずれが、何パーセントに なっているかを計算し、時間を横軸に取ったグラフとして表せ。
3.2.6 差分化のパラメータによる誤差の変化
より精度よく計算するにはどうすれば良いだろうか。数値計算の誤差は、式(6)の差分 化による誤差に起因している。この誤差を減らせば良いはずだから、より小さなDTの値 を設定すれば良いだろう。そこで、パラメータファイルを書き替え、DTの値を変えよう。
例えば、DTの値として、0.01を設定してみる。そのためには、test.parのDTの行を DT 0.01
というように変更すれば良い。こうしたうえで:
./main.out test.par test_DT001.txt のようにしてプログラムを実行する。この時:
• 出力のファイル名を、以前のものと変えておくことを忘れないこと。そうでない と、元のデータが上書きされる。
• どの出力ファイルがどのパラメータに対応するかを、何らかの形できちんとメモし ておくこと。ファイルが多くなってくると、ドンドン手に負えなくなってくる。
特に、上記の二点目は注意を怠るとすぐにデータが散らかって手に負えなくなる。パラ メータファイル自体を新しく作って出力のファイル名と対応付ける、出力のファイル名を 工夫してパラメータを分かりやすくする、別途ノートに記録をする、などの工夫が必要で ある。数値計算も、計算機を使用した「実験」であるので、方法や結果をまとめた「実験 ノート」を作成しておくことを強く推奨する。
【課題:基本】 DTを0.01に設定した場合について:
• 時刻tと位置xの関係を表すグラフ
• 時刻tと全エネルギーEの関係を表すグラフ
• 時刻tと位置xの誤差との間の関係を表すグラフ
• 時刻tと全エネルギーEの誤差との間の関係を表すグラフ の4種類を作成せよ。
【課題:標準】 さらにDTを変化させた計算を行い、時刻t = 30におけるエネルギーの 誤差が、DTによってどう変化するかを求めよ。この結果を、横軸をDT、縦軸をエネル ギーの誤差に取ったグラフとして表せ。
【課題:応用】 エネルギーの誤差がDTの何乗に比例するかを計算せよ。(ヒント:Excel の場合、いったん対数に直してから線形近似をすると…)
3.2.7 高精度の差分化
式(6)は、∆t2 の誤差を含む差分化の方法である。これを工夫することで、∆tのより 高次まで正しい手法を得ることができる。
詳細は省略するが、x(t)に関する微分方程式 dx
dt =v(x, t) (12)
を、以下のようにして求める方法は、2次Runge-Kutta法と呼ばれる:
k1 = ∆tv(xn, tn) (13)
k2 = ∆tv(xn+k1/2, tn+ ∆t/2) (14)
xn+1 =xn+k2 (15)
ここに、xn は、x(tn)の意味であり、tn+1 =tn+ ∆tである。
今回のコードでは、この2次のRunge-Kutta法を用いた計算も出来るようになってい る。パラメータファイルの中で、INTEGRATE_ORDER 2とすることで、2次Runge-Kutta 法で計算するようになる。
【課題:標準】 DTの値を揃えた上で、INTEGRATE_ORDERを1に設定した場合(オイ ラー法)と、2に設定した場合(2次Runge-Kutta法)の解の誤差を比較せよ。
3.3 未知の問題についての数値計算
これまでのようなテスト計算を重ねることで、どのような設定で計算すべきかという雰 囲気をつかむことができる。その設定が分かれば、未知の問題に取り組んでいくことがで きる。
未知の問題とは、例えば:
• 初期条件の設定を変えた計算
• 長時間の計算
• 異なる種類の力が入った計算 などである。
今回のコードでは、パラメータファイルの書き替えで、初期条件を変えた計算を行うこ とが可能である。具体的には、X0, Y0, DXDT0, DYDT0の値を変えれば良い。また、TINI (初期時刻) とTFIN (終了時刻)を変更することで、長時間の計算が可能である。コードの 組み方を工夫し、やりたい計算に応用が効きやすいようにしていくことが重要である。
また、今回のコードでは、強制力がかかっている場合の(1次元)運動をパラメータ ファイルの書き替えのみで計算できるようにしてある。具体的には:
md2x
dt2 =−kx+F0sin(βt) (16) という形の運動方程式(右辺第二項が強制力)について、F0 の値はEXTERN_FORCE_AMP の値を、β の値はEXTERN_FORCE_FREQの値を変更することで計算ができる。ただし、こ れらはそれぞれx方向の力としてしかかからないようになっているので注意すること。
さらに、コードそのものを書き替えることで、異なる力を自分で入れて計算することが できる。main.cの最後の方にある、force_x, force_y が、与えられた位置・速度・時 刻において物体にかかる力を計算する関数である。ここを書きかえることで、惑星の運動 なども計算することが可能になる。
なお、力を変更した場合、ポテンシャルエネルギーの表式も変わることに注意しよ う。今回のコードで用いている手法では、ポテンシャルエネルギーの表式は求める位 置・速度への影響は無いが、エネルギー保存則などを議論する場合には必要になる。
potential_energyが、与えられた位置におけるポテンシャルエネルギーを計算する関 数で、これもmain.cの中に含まれている。
【課題:発展】 パラメータの変更やコードの書き替えを行い、自由に問題を設定して議論 せよ。