細川・林・石田・長谷部 2019...

62
プログラミング演習II 細川・林・石田・長谷部 2019 2Q

Upload: others

Post on 27-Jan-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

プログラミング演習II細川・林・石田・長谷部 2019 2Q

Page 2: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

本演習の内容と目的

以下の内容を講義・演習する • 質点の運動に関するシミュレーション • 拡散方程式の数値解法 • 移流方程式の数値解法 • 有限要素法

目的 • 物理現象を数値計算するための基礎知識を理解し • 数値計算のためのプログラム開発能力を修得する

Page 3: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

講義日程

A(火曜)班

6/11 質点運動

6/18 質点運動

6/25 拡散方程式

7/2  拡散方程式

7/9  移流方程式

7/16 移流方程式

7/23 有限要素法

B(水曜)班

6/12 質点運動

6/19 質点運動

6/24 拡散方程式

7/3   拡散方程式

7/10 移流方程式

7/17 移流方程式

7/24 有限要素法

Page 4: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

質点の運動

Page 5: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

重力による質点の落下

dv(t)

dt= g

x

x = 0

g

Z t2

t1

dv(t)

dtdt =

Z t2

t1

gdt

v(t2) = v(t1) + g(t2 � t1)

時間経過後の質点の速度を知りたいなら、運動方程式を積分すればよい

t

vv(t)

t1 t2

g(t2 � t1)

Page 6: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

空気抵抗がある場合

v(t2) = v(t1) + g(t2 � t1)

を、未来の速度 = 今の速度 + 加速度x経過時間 と捉えよう

t

v

t1 t2

VT

空気抵抗により加速度が時間的に変化(速度に依存)する問題にも使える?

g

dv

dt= g � �

mv(t)

ϒ:空気抵抗の係数終端速度

v(t) =mg

⇣1� e�

�m t

Page 7: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

少し先の未来を知り、繰り返す

t

v

v(t)

t1 t2

VT

経過時間を細切れにして、少し先の未来の速度を求め、それを繰り返してずっと先の未来を知ることはできるのではないか?

g

�t�t�t

v(t+�t) = v(t) +hg � �

mv(t)

i�t

時間刻み幅(time step size)

同じ計算を何度もする。。。コンピュータを使う!

差分式(differential equation)

Page 8: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

プログラミングの前に。。。:無次元化

式を無次元化しておく。

v(t+�t) = v(t) +hg � �

mv(t)

i�t

とおく

(以下ではチルダは省略)

mgv(t+�t) =

mgv(t) +

1� �

mgv(t)

���t

m

v =�v

mgf�t =

��t

m

v(t+ f�t) = v(t) +�1� v(t)

� f�t

t =�t

m

Page 9: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

プログラミングの前に。。。:時間刻み幅の設定

無次元化した厳密解(exact solution)(チルダ省略)

t

v(t) = 1� e�t

v

1� e�t = 0.63t = 1

t = 1

1� e�t = 0.63

のとき

  は時定数よりも小さくないと、 速度の変化を再現できないと考えられる

時定数 (time constant)

⌧ = 1

�t �t = 0.1を試す

Page 10: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

Xcode (1)

コレ

新規プロジェクトの作成

Page 11: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

Xcode (2)

mac OS > Command Line Tool

コレ

注:XcodeのVer.によって多少見え方が違います

Page 12: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

Xcode (3)

Language: C++

Product name: 01FallingParticle

Location: デスクトップに講義用フォルダを作成して入れる ファイル名・ディレクトリ名は半角英数が無難!!!!

Page 13: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

Xcode (4)

実行・書出ファイルが同じディレクトリに出るようにする

XcodeメニューのPreferences…からLocationsタブ選択、Derived DataをRelativeにする

コレ

コレと

Page 14: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

とりあえずmain.cppをBuild&Run(1)この中のBuild

  Succeededと出ればOK(2)Run

(3)下のConsoleからHelloが来ればOK

Page 15: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

#include <iostream>

int main(int argc, const char * argv[]) { // insert code here... std::cout << "Hello, World!\n";

return 0; }

main.cppの編集

不要なので消す

#include <iostream>

int main(int argc, const char * argv[]) { double v0 = 0.0; double dt = 0.1;

double v = v0; return 0; }

代わりにこれを入れる

�t = 0.1v0 = 0 v(0) = v0

Page 16: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

#include <iostream>

int main(int argc, const char * argv[]) { double v0 = 0.0; double dt = 0.1;

double v = v0; std::cout << "v: " << v << std::endl;

return 0; }

main.cpp: 値の確認

これを入れる

Build, Runし、Consoleに”v: 0.0”がでればOK

標準出力

Cではprintf関数を使いますが、C++ではstd::coutを使います。

std::coutに<<で続けて出力したい文字列や変数を書いていくだけで簡単。

std::endlは改行命令です(end of line)

stdはstandardの略です。とりあえず気にしない。

Page 17: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

#include <iostream> int main(int argc, const char * argv[]) {

double v0 = 0.0; double dt = 0.1;

double v = v0; std::cout << "v: " << v << std::endl; v = v + (1.0 - v)*dt; std::cout << "v: " << v << std::endl;

return 0; }

数値計算を始める!

早速、未来の速度を知る手続きを始める

これを入れる

Build, Runし、vの変化を確認せよ!

Page 18: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

#include <iostream> int main(int argc, const char * argv[]) {

double v0 = 0.0; double dt = 0.1;

double v = v0; int stepEnd = 100; int step = 0; std::cout << "v: " << v << std::endl; while(step < stepEnd){ v += (1.0 - v)*dt; step++; std::cout << "v(" << dt*(double)step << ") = " << v << std::endl;

} return 0; }

もっと先まで計算する

変更箇所

Build, Runし、vの変化を確認せよ!

(注:これは1行です)

指定した回数だけ計算させる

step = step + 1v += ! v = v +

t = �t⇥ step

Page 19: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

gnuplot用データ出力まずはスペース区切りで値のみ出力するように変更

#include <iostream>

int main(int argc, const char * argv[]) { double v0 = 0.0; double dt = 0.1;

double v = v0; int stepEnd = 100; int step = 0;

std::cout << dt*(double)step << " " << v << std::endl; while(step < stepEnd){

v += (1.0 - v)*dt; step++;

std::cout << dt*(double)step << " " << v << std::endl; }

return 0; }

Page 20: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

gnuplot用データ出力:Terminalで実行

Terminalを起動

cd (change directory)で実行ファイルの場所まで移動

(1)cd と打ったあと、

(2)ファインダーから”Debug”

フォルダをdrag & drop

(3)Enterして、pwdで現ディレクトリを確認

(……/Debug/になっているはず)

Page 21: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

gnuplot用データ出力:Terminalで実行

Terminal内で実行する

$./01FallingParticle

Terminal内で実行し、結果をファイルに出力する

$./01FallingParticle > data.txt

ファイルができていることと内容を確認する

Page 22: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【参考】UnixコマンドTerminalで使うコマンド【この講義で使うもの】

pwd:現ディレクトリのフルパスを表示(print working directory)

cd: ディレクトリの移動(change directory)

ls: 現作業ディレクトリ内のファイル一覧を表示

相対パス

./ 現作業ディレクトリの意味

../ 現作業ディレクトリのひとつ上のディレクトリを指す

例えば、 cd ../ はひとつ上のディレクトリに移動 【他の基本コマンド】

cp: ファイルコピー(cp data.txt data_copy.txtとか)

mv: ファイルの移動、ファイル名変更(mv data.txt ../)とか

rm: ファイル消去

Page 23: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

gnuplot

Terminalからgnuplotを起動(ディレクトリを変えずに)

$gnuplot

gnuplotが起動したらデータファイルから描画

>set xlabel “t” >set ylabel “v” >plot “data.txt” title ‘v’

Page 24: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

gnuplot:理論解との比較(定性的)

理論解を重ねてプロット

>plot “data.txt” title ‘v’, 1-exp(-x)

期待通り!(でもちょっとずれてる?)

Page 25: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

gnuplot:結果の保存

PDFで描画結果を保存できます。File > Save as

Page 26: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

誤差の評価 ・ここからまたXcodeで

数学ライブラリの読み込み(exp使用のため)

画面出力の関数化と誤差評価

t = 1までに変更Output関数で出力

e(t) =

����v(t)� vex(t)

vex(t)

����

#include <iostream> #include <cmath>

double Output(double t, double v, bool display){ double vExact = 1.0 - exp(-t); double error = (v - vExact)/vExact; if(vExact == 0.0) error = 0.0; if(display == true) std::cout << t << ": " << v << ", " << vExact << ", " << error << std::endl; return fabs(error); };

int main(int argc, const char * argv[]) { double v0 = 0.0; double dt = 0.1; double v = v0; int stepEnd = 10; int step = 0; Output(dt*(double)step, v, true); while(step < stepEnd){ v += (1.0 - v)*dt; step++; Output(dt*(double)step, v, true); } return 0; }

Page 27: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

gnuplotを計算中に呼び出す

計算結果をファイルに入れてからgnuplotで描画するのは手間

pipeという機能を使って、計算しながらgnuplotを使う

計算を実行している端末(のプロセス)から

gnuplotを起動するための端末(子プロセス)を作るイメージ

Page 28: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

GnuplotInterfaceの利用

GnuplotInterface.h & .cpp:pipe関連の命令を記述したプログラム

www2.kobe-u.ac.jp/~hayashiダウンロード

にファイルを移動(main.cppと同じところ)

/01FallingParticle/01FallingParticle/

ファイルを2つとも ここにdrag & drop

Page 29: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

利用するための手続き in main.cpp

#include <iostream> #include <cmath> #include “GnuplotInterface.h"

double Output(double t, double v, bool display){...}

int main(int argc, const char * argv[]) { GnuplotInterface* gnuplot = new GnuplotInterface(); double v0 = 0.0; double dt = 0.1; double v = v0; int stepEnd = 10; int step = 0; Output(dt*(double)step, v, true); while(step < stepEnd){ v += (1.0 - v)*dt; step++; Output(dt*(double)step, v, true); } delete gnuplot; return 0; }

読み込み

利用開始の手続き

利用終了の手続き

(gnuplotに情報を流す仲介役)

同プロジェクト内にあるheaderファイルを読む場合 #include “” (<>ではない)

Page 30: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

結果の描画

軸ラベルの設定

‘-’はデータ待ち受け開始の意味

データを投入

eはデータ待ち受け終了

#include <iostream> #include <cmath> #include "GnuplotInterface.h"

double Output(double t, double v, bool display){...};

int main(int argc, const char * argv[]) { GnuplotInterface* gnuplot = new GnuplotInterface(); gnuplot->SetAxisLabel("x", "t"); gnuplot->SetAxisLabel("y", "v"); double v0 = 0.0; double dt = 0.1; double v = v0; int stepEnd = 10; int step = 0; Output(dt*(double)step, v, true); gnuplot->Injection("plot '-' title 'predicted', 1-exp(-x) \n"); gnuplot->Injection(dt*(double)step, v); while(step < stepEnd){ v += (1.0 - v)*dt; step++; Output(dt*(double)step, v, true); gnuplot->Injection(dt*(double)step, v); } gnuplot->Injection("e\n"); delete gnuplot; return 0; }

注:’はPDFからのcopy&pasteだと化ける可能性あります

+ キーshift 7

Page 31: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【課題】(1)誤差の分析I・(2)差分式の再検討

  を小さくすれば、予測の精度が上がるのではないだろうか?�t• dt = 0.1 • dt = 0.01 • dt = 0.001

dt と stepEndを変更して、

の場合のt = 1における誤差を比較・誤差とdtの関係を検討する!

(1)誤差の分析

横軸に dt 、縦軸に t=1における誤差 をとり、gnuplotで描画すること。

(2)差分式の再検討

ここは      としてもよいのではないか?v(t+�t)

その差分式を用いて計算し、dt = 0.1での誤差を前回と比較する。右辺の速度を      に変え、この速度で解き直し、差分式を得る。

【新規プロジェクト:01FallingParticleImplicit】

x1, y1 x2, y2 x3, y3

v(t+�t)

結果を    のようにテキストファイルに貼り、Terminalで起動したgnuplotで読み込む(plot “data.txt”)。set logscale xで軸を対数にする。(yも)

v(t+�t) = v(t) + (1� v(t))�t

Page 32: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【課題】(1)誤差の分析I

(1)誤差の分析

�t1

1/10

1/10

Page 33: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【課題】(2)差分式の再検討

(2)差分式の再検討【新規プロジェクト:01FallingParticleImplicit】

#include <iostream> #include <cmath> #include "GnuplotInterface.h"

void Output(double t, double v, bool display){...};

int main(int argc, const char * argv[]) { ... while(step < stepEnd){ v = (v + dt)/(1.0 + dt); step++; Output(dt*(double)step, v, true); gnuplot->Injection(dt*(double)step, v); } ... }

1行変えるだけ!

v(t+�t) =v(t) +�t

1 +�t

Page 34: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【課題】(2)差分式の再検討

(2)差分式の再検討

v(t+�t) = v(t) + (1� v(t))�t

v(t+�t) =v(t) +�t

1 +�t

Page 35: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

誤差の検討

誤差が   に比例していることが分かった。その原因は?�t1

テイラー展開により、

v(t+�t) = v(t) + (1� v(t))�t差分式                   に代入

元の微分方程式にはない項。主要項は  に比例 差分式はこの余計な項がある方程式を解いている!

�t1

この方法は一次精度(1st-order accuracy)である。

v(t+�t) = v(t) +1

1!

dv

dt

����t

�t+1

2!

d2v

dt2

����t

�t2 +O(�t

3)

v(t) +1

1!

dv

dt

����t

�t+1

2!

d2v

dt2

����t

�t2 +O(�t

3) = v(t) + (1� v(t))�t

dv

dt

����t

= 1� v(t) +

� 1

2!

d2v

dt2

����t

�t1 +O(�t

2)

Page 36: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【課題】(3)誤差の分析II

差分式

についても同様に誤差のオーダを調べる。

v(t+�t) =v(t) +�t

1 +�t

Page 37: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

時間の表記法

t = n�t

これまでのプログラムでもすでに見たように、時間は

と書けるので、時間を表すには何回目の計算時点か(つまりn)を示せば十分。そこでこれ以降は

vn+1 = v(t+�t)

vn = v(t)

にように上付添字で時間を表すことにする(n乗ではないので注意)。

Page 38: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

差分式の分類

一般に、       に対して、df

dt= g(f)

と右辺を既知の値で評価するものを陽解法(explicit scheme)という。

一方、未知の値を使うものは陰解法(implicit scheme)という。

【課題】前の2つの方法を陽解法か陰解法に分類する。

fn+1 � fn

�t= g(fn±k, fn) (k > 0)

fn+1 � fn

�t= g(fn�k, fn) (k > 0)

Page 39: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

二次精度の方法

陽解法

の誤差はともに   に比例していたが、誤差の主要項の符号は逆

両者を組み合わせることでうまく誤差を低減できないか?

vn+1 = vn + (1� vn)�t

vn+1 = vn + (1� vn+1)�t

陰解法

�t1

Crank-Nicolson法 fn+1 � fn

�t=

g(fn+1) + g(fn)

2

Page 40: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

Crank-Nicolson法

vn+1 � vn

�t=

1

2

⇥(1� vn+1) + (1� vn)

vn+1 =vn +

�1� 1

2vn��t

1 + �t2

#include <iostream> #include <cmath> #include "GnuplotInterface.h"

void Output(double t, double v, bool display){...};

int main(int argc, const char * argv[]) { ... while(step < stepEnd){ v = (v + (1.0 - v*0.5)*dt)/(1.0 + dt*0.5); step++; Output(dt*(double)step, v, true); gnuplot->Injection(dt*(double)step, v); } ... }

Page 41: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【課題】Crank-Nicolson法の精度

かなり改善されている!

【課題】Crank-Nicolson法が二次精度であることをテイラー展開で示す!

Page 42: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

Adams-Bashforth法・Runge-Kutta法

Crank-Nicolson法は未来の値を使うので陰解法。 二次精度の陽解法は?

fn+1 � fn

�t=

3g(fn)� g(fn�1)

2

f (1) � fn

�t/2= g(fn)

fn+1 � fn

�t= g(f (1))

Adams-Bashforth法

Runge-Kutta法(多段階法)

注:最初のステップは古い値が分からないので、次のRunge-Kuttaなどを使う

1回目の計算で中間段階の速度を求める もう一度計算し、速度を更新する

Page 43: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【課題】二次精度陽解法の精度検証

【課題】Adams-Bashforth法を質点の落下問題に適用し、差分法を得る。

【課題】Adams-Bashforth法を用いて質点の速度変化を計算し、二次精度であることを検証する。

【課題】Runge-Kutta法を質点の落下問題に適用し、差分法を得る。

【課題】Runge-Kutta法を用いて質点の速度変化を計算し、二次精度であることを検証する。

(進んだ問題:テイラー展開を用いて両者が二次精度であることを示す)

Page 44: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【課題】二次精度陽解法の精度検証

Page 45: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【課題】二次精度陽解法の精度検証

�t1

�t2

Page 46: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【課題】数値安定性(Numerical stability)

  は時定数よりも小さくないと、 速度の変化を再現できないと考えられる�t �t = 0.1

を試す

これまで、

としてきたが、時定数と同程度、さらには時定数よりも大きい時間刻み幅を使うと何がおきるだろう?

各手法で時間刻み幅を大きくしたとき何が起きるか確かめる

Page 47: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

gnuplotで複数の計算結果を同時プロットしたい人へ(1/4)

例えば、陽解法の計算結果(時間と速度のデータ)と、陰解法の計算結果を同時にプロットしたい場合、

• 陽解法で計算し、結果をファイル”explicit.txt”に出力する。

• 陰解法で計算し、結果をファイル”implicit.txt”に出力する。 • 結果のファイルを同じ場所に置いておく。 • Terminalを開き、結果のファイルがある場所に移動する。

• gnuplotをTerminalで起動する。

• plot ‘explicit.txt’, ‘implicit’, 1-exp(-x) でグラフを描画する。

ファイルへの出力は、1回目に習ったTerminalで’ > ’を使って実行する方法で出来る。プログラムで出力する場合は次頁を参照。

Page 48: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

gnuplotで複数の計算結果を同時プロットしたい人へ(2/4)

std::ofstreamを使うと、C言語のfprintfみたいにファイルに書き込める。

int main(int argc, const char * argv[]) { std::ofstream output("data.txt"); ... output << dt*(double)step << " “ << v << " “ << std::endl; while(step < stepEnd){ ... step++;

output << dt*(double)step << " “ << v << " “ << std::endl; } ... return 0; }

ファイルを扱うための変数名(自分で決めていい)作成するファイル名(自分で決めていい)

std::coutのかわりに、自分で決めたofstreamの変数名を書く

(Terminalで’>’実行せずに、Xcodeでファイル出力まで完結できます)

Page 49: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

gnuplotで複数の計算結果を同時プロットしたい人へ(3/4)

以下、gnuplotまで含めてXcodeで完結したい人向け。

gnuplotでこの3列のデータから2つのプロットを作るには、

プログラムで陽解法と陰解法の結果をひとつのファイルにまとめて出力。(「時刻、陽解法結果、陰解法結果」を縦に並べたテキストファイル)

plot 'data.txt' using 1:2 title 'explicit', '' using 1:3 title 'implicit'

1,2列目のデータを使うという意味 前(‘data.txt’)のデータを使うという意味

一回の計算で陽解法と陰解法の計算結果を取り扱うので、vを配列で定義しておくと便利(Crank-Nicolsonとかを同じ方法で追加できる)。C言語と同じように配列を利用できるが、std::vector<型名>も便利。 std::vector<double> v {v0, v0}; output << dt*(double)step << " "; for(int i=0; i<v.size(); i++) output << v[i] << " "; output << std::endl;

double型ベクターの宣言・初期化例ベクターvの値をoutputに出力

Page 50: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

gnuplotで複数の計算結果を同時プロットしたい人へ(3/4)

...

double Output(double t, double v, bool display){...};

int main(int argc, const char * argv[]) { std::ofstream output("data.txt"); GnuplotInterface* gnuplot = new GnuplotInterface(); gnuplot->SetAxisLabel("x", “t"); gnuplot->SetAxisLabel("y", "v"); double v0 = 0.0; double dt = 0.1; std::vector<double> v {v0, v0}; int stepEnd = 10; int step = 0; output << dt*(double)step << " "; for(int i=0; i<v.size(); i++) output << v[i] << " "; output << std::endl; while(step < stepEnd){ for(int i=0; i<v.size(); i++){ switch (i) { case 0: v[i] += (1.0 - v[i])*dt; break; case 1: v[i] = (v[i] + dt)/(1.0 + dt); break; default: break; } } step++; output << dt*(double)step << " "; for(int i=0; i<v.size(); i++) output << v[i] << " "; output << std::endl; } gnuplot->Injection("set key left top\n"); gnuplot->Injection("plot 'data.txt' using 1:2 title 'explicit', '' using 1:3 title 'implicit', 1-exp(-x)\n"); for(int i=0; i<v.size(); i++) std::cout << Output(dt*(double)step, v[i], false) << ", "; delete gnuplot; return 0; }

switchで陽解法と陰解法を分岐

ofstreamでファイル出力準備

std::vectorで配列準備

ファイル出力

ファイル出力

gnuplot

Page 51: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

2階線形常微分方程式:振動問題

バネに繋がれた質点とみなせる物体の振動問題を考える

md2x

dt2= �kxx自然長での位置

F = �kxフックの法則 (k > 0)

物体の位置  を計算するには  の時間に関する2階微分に対する差分を考える?これまでに学んだ1階微分の差分解法でどうすれば?

x x

Page 52: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

連立1階線形常微分方程式として捉える

dx

dt= v

このように書いてみると、未知数   の連立1階常微分方程式。 1階なので、それぞれの式には既に修得した方法が使える!

x, v

dv

dt= �!2x ! =

rk

m

Page 53: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

一次精度の陽解法を適用

dx

dt= v

dv

dt= �!2x

xn+1 � xn

�t= vn xn+1 = xn + vn�t

vn+1 � vn

�t= �!2xn vn+1 = vn � !2xn�t

プログラム開発のポイント • 変数はxとvの2つ必要 • 1ステップの計算で2つの変数をアップデート

Page 54: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

問題設定と時間刻み幅の検討x(0) = x0 = 1

v(0) = v0 = 0

! = 1

x(t) = cos(!t)

v(t) = �! sin(!t)

(この際単位は気にしないでいきましょう。。)

T

周期       の    に対してせめて10ステップはとろうT/4

�t =T

4⇥ 1

10

T/4

T = 2⇡/!

Page 55: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

一次精度の陽解法によるプログラムを開発#include <iostream> #include <cmath> #include "GnuplotInterface.h"

int main(int argc, const char * argv[]) { GnuplotInterface* gnuplot = new GnuplotInterface(); gnuplot->SetAxisLabel("x", "t"); gnuplot->SetAxisLabel("y", "x"); double x0 = 1.0; double v0 = 0.0; double omega = 1.0; double omega2= omega*omega; double x = x0; double v = v0; double T = 2.0*M_PI/omega; double dt = (T/4.0)*0.1; gnuplot->SetGraphRange("x", 0.0, T); int stepEnd = (int)(T/dt) + 1; int step = 0; gnuplot->Injection("set key left bottom\n"); gnuplot->Injection("plot '-' title 'predicted x', cos(x), 0 \n"); gnuplot->Injection(dt*(double)step, x); while(step < stepEnd){ double xtmp = x + v*dt; double vtmp = v - omega2*x*dt; x = xtmp; v = vtmp; step++; gnuplot->Injection(dt*(double)step, x); } gnuplot->Injection("e\n"); delete gnuplot; return 0; }

x0 v0!

!2

�t =T

4⇥ 1

10

xn+1 = xn + vn�t

vn+1 = vn � !2xn�t

【新規プロジェクト:02OscillatingBody】

T = 2⇡/!

Page 56: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【課題】一次精度の陽解法による結果(x)と課題

【課題】周期の数倍程度計算すると結果はどうか、確認する雰囲気はでているけれども、だんだん振幅が大きくなっているような?

【課題】dtを1/10に小さくして1周期分の計算をしてみるとどうか、確認する

Page 57: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

一次精度の陽解法による結果(v)

速度が時間経過とともに大きくなっている(エネルギが保存されていない)

Page 58: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【課題】二次精度のRunge-Kutta法を適用

dx

dt= v

dv

dt= �!2x

【課題】Runge-Kutta法のプログラムを作成し計算する!

x(1) � xn

�t/2= vn

v(1) � vn

�t/2= �!2xn vn+1 � vn

�t= �!2x(1)

xn+1 � xn

�t= v(1)

Step 1 Step 2

Page 59: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

二次精度Runge-Kutta法による計算結果

かなり改善されている!

教訓:一次精度・二次精度のどちらにすべきかは精度・安定性・開発時間・計算時間を天秤にかけて適切に判断する必要あり。

Page 60: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【自由課題】四次精度のRunge-Kutta法を適用

f (1) = fn +�t

2gn

f (2) = fn +�t

2g(1)

f (3) = fn +�tg(2)

fn+1 = fn +�t

6(gn + 2g(1) + 2g(2) + g(3))

20周期計算でもこれだけ合います。

手間がかかるだけあって。。

Page 61: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

【課題】一次精度の陰解法を適用

dx

dt= v

dv

dt= �!2x

xn+1 � xn

�t= vn+1

vn+1 � vn

�t= �!2xn+1

お互いの未知量が入っている。。。どうする?!

【課題】陰解法の計算式を検討する!

【課題】陰解法のプログラムを作成し計算する!

Page 62: 細川・林・石田・長谷部 2019 2Qhayashi/handout/programmingII2019...本演習の内容と目的 以下の内容を講義・演習する • 質点の運動に関するシミュレーション

一次精度の陰解法による結果(x)