Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
地球惑星内部物理学演習B 資料7
114
VII. 常微分方程式と高精度解法 16.ローレンツのカオス 現象を記述する方程式が決定論的で計算可能な場合でも未来が予測できないことがある。このことを最初に示したのがローレンツによるカオスのモデルである。このような現象は非線型な場合に起こりうる。
16.1 熱対流とローレンツの方程式 エドワード・ローレンツはカオスを発見した気象学者として知られる。ローレンツは大気の対流運動の単純化したモデルを考え,対流の時間変動が次の3つの式で表されるとした。
(16.1)
(16.2)
(16.3) これらの式は対流の速度や温度をフーリエ級数で表し,低次のモードだけを考えることにより得られる。ここで, X(t): 流線関数の基本モード Y(t): 温度の基本モード Z(t): 温度の第1次高調波モード s: プラントル数(大きいほど粘性の影響が強い) g: レイリー数(大きいほど浮力が強い) b: 対流の水平波長 に相当すると考えることができる。
(16.4)
(16.5)
(16.6)
dX t( )dt
= −σ X t( )+σY t( )
dY t( )dt
= −X t( )Z t( )+ γ X t( )−Y t( )
dZ t( )dt
= −X t( )Y t( )− bZ t( )
X ∞( ) = Y ∞( ) = Z ∞( ) = 0
X± ,Y± ,Z±( ) = ±C,±C,γ −1( )
C = b γ −1( )
地球惑星内部物理学演習B 資料7
115
ローレンツの式はgによって次のような3種類の解を持つ。 (1) g < 1のとき: 対流が停止する
(16.7)
(2) 1 < g < gT (=24.7368 )のとき: 対流が定常状態となる。
(16.8)
(16.9)
(3) g > gTのとき: 対流がカオスになる。解は定常解の周りで振動する。
このとき,定常解をアトラクターと呼ぶ。
ここでは,2つのことに注目する。まず,gの違いにより解が異なった様相をしめすことが数値計算で得られるのかという点である。もう1つは初期値をわずかに変化させるとどのようになるかという点である。
17.常微分方程式の数値解法 ローレンツの式は非線型であるため,定常状態のような特別の場合を除いて解析的に解くことができない。そのため,初期条件を与えて,時間発展問題としてコンピュータを使用して数値的に解くことになる。 17.1 オイラー法による解法 偏微分方程式の時と同様,3つの常微分方程式の微分を前進差分
(17.1) で置き換える。ここで,nはタイムステップ番号である。すなわち,
(17.2)
(17.3)
(17.4) である。ベクトル式で書くと,
X ∞( ) = Y ∞( ) = Z ∞( ) = 0
X± ,Y± ,Z±( ) = ±C,±C,γ −1( )
C = b γ −1( )
dfdt
= f n+1 − f n
Δt
Xn+1 − Xn
Δt= −σ Xn +σY n
Y n+1 −Y n
Δt= −XnZn + γ Xn −Y n
Zn+1 −Y n
Δt= −XnY n + bZn
地球惑星内部物理学演習B 資料7
116
(17.5) と表すことができる。ただし,
(17.6)
(17.7)
である。この時間微分は1次の前進差分であるから,この方法はオイラー法である。ローレンツの式は1階常微分方程式であるから,初期における X, Y, Zの値を与えることにより,時間進行により解くことができる。 17.2 予測子・修正子法:2次ルンゲ・クッタ法 オイラー法は1次精度と打ち切り誤差が大きいので,より高次の打ち切り誤差を持つ方法が望ましい。ところで(16.1)~(16.3)の右辺は非線型であり,陰解法を使用しても連立1次方程式とはならない。このため,陰解法で解くには反復法が必要になってしまい,計算の効率が悪い。そこで,未来の予測値を作ってそこから時間微分係数の値を計算し直し,これを用いて時間を進める方法が用いられる。つまり,行きつ戻りつ計算するのである。このような方法は予測子・修正子法 (predictor-corrector method)とよばれる。 予測子ステップはオイラー法で計算する。導関数
(17.11)
より,未来の予測値
(17.12)
を計算する。このあと,これを予測子として,未来の値から計算される勾配
(17.13)
を計算した後,未来の値は,修正子ステップ
X n+1 − X n
Δt= F X n( )
X n =Xn
Y n
Z n
⎡
⎣
⎢⎢⎢
⎤
⎦
⎥⎥⎥
F X n( ) =−σ Xn +σY n
−XnZn + γ Xn −Y n
−XnY n + bZn
⎡
⎣
⎢⎢⎢
⎤
⎦
⎥⎥⎥
k1 = F X n( )
!X n+1 = X n + Δtk1
k2 = F !Xn+1( )
地球惑星内部物理学演習B 資料7
117
(17.14) から計算される。すなわち,
(17.15) と計算したことになる。つまり,クランク・ニコルソン法の陰的な項の代わりに予測子から計算した導関数を用いていることになる。この方法はクランク・ニコルソン法と同様,2次の打ち切り誤差を持つ。 17.3 4次ルンゲ・クッタ法 1つのタイムステップの途中も使って修正を加えるとより高次の打ち切り誤差を持つ方法を作ることができる。このような方法をルンゲ・クッタ法 (Runge-Kutta method)
とよぶ。予測子・修正子法は2次の精度を持つルンゲ・クッタ法ということができる。連立常微分方程式を解くのに最もよく用いられる4次ルンゲ・クッタ法では,途中,現在のステップの導関数を1回,中間ステップの導関数を2回,未来のステップの導関数を1回用いる。現在ステップの導関数
(17.21)
より中間ステップの予測子を求める。
(17.22) これを用いて,さらに中間ステップの導関数を計算し,
(17.23)
(17.24)
のように中間ステップの値を計算し直す。これから未来のステップの予測子を求める。
(17.25)
(17.26)
未来ステップの予測子から,未来側の導関数
X n+1 = X n + Δt2k1 + k2( )
X n+1 = X n + Δt2F X n( )+ F !X n+1( )⎡⎣ ⎤⎦
k1 = F X n( )
!X n+1 2 = X n + Δt2k1
k2 = F !Xn+1 2( )
X̂ n+1 2 = X n + Δt2k2
k3 = F X̂ n+1 2( )⌢X n+1 = X n + Δtk3
地球惑星内部物理学演習B 資料7
118
(17.27)
を求める。導関数に重みをつけて平均し,未来の値を下式のように計算する。
(17.28) ここで,導関数の重みの割合 1, 4 (= 2 + 2), 1がシンプソン法と同じになっている。ここでは,ルンゲ・クッタ法を利用して,ローレンツの式を解くことにする。 問題VII-1 (1) ローレンツの式を解くプログラムをコンパイルして実行せよ。 (2) gの値を変えると,上記のような3種類の解が得られることを示せ。 (3) カオスとなるような条件のとき,初期値を極端に大きくしたらどのような解が得られるか調べよ。
(4) カオスとなるような条件のとき,初期値を 0.01程度変化させて実行するとどのようになるか調べよ。
(5) (3)(4)はどのような意味を持つか考察せよ。
図17.1 X(t)と Z(t)をプロット
k4 = F⌢X n+1( )
X n+1 = X n + Δt6k1 + 2k2 + 2k3 + k4( )
地球惑星内部物理学演習B 資料7
119
問題7-1 ローレンツ方程式のルンゲ・クッタ法による解法プログラム
ローレンツ方程式をルンゲ・クッタ法により解くプログラムである。プログラムはメインルー
チン lo_main.f90,サブルーチン lo_cal_RHS.f90,モジュールプログラム lo_mod_para_l.f90
の3つからなる。パラメータの設定はデータファイル lo_para.datにある。コンパイルはモジ
ュールファイルを先に作っておく必要があるので,
f95–clo_mod_para_l.f90
f95–clo_main.f90lo_cal_RHS.f90
f95–olo.outlo*.o
のように行うこと。プログラムは
https://home.hiroshima-u.ac.jp/nakakuki/Lectures/enshu/lorenz_rk.tar
からダウンロード可能である。
メインプログラム lo_main.f
!
!****LorenzChaosmodel****
!
programlorenzrk
usemod_para_l
implicitnone
character(60)::apara
real(8)::dt,t
integer::nt,it,nft,i
real(8),allocatable::X(:),Y(:),Z(:)
real(8)::X_o(3),X_m(3),X_f(3)
real(8)::k1(3),k2(3),k3(3),k4(3)
地球惑星内部物理学演習B 資料7
120
open(10,file='lo_para.dat',status='old')
!****readparameters****
read(10,*)
read(10,*)apara
read(10,*)sig
write(6,*)apara
write(6,*)sig
read(10,*)apara
read(10,*)gamm
write(6,*)apara
write(6,*)gamm
read(10,*)apara
read(10,*)b
write(6,*)apara
write(6,*)b
read(10,*)apara
read(10,*)dt
write(6,*)apara
write(6,*)dt
read(10,*)apara
read(10,*)nt
write(6,*)apara
write(6,*)nt
read(10,*)apara
read(10,*)nft
write(6,*)apara
地球惑星内部物理学演習B 資料7
121
write(6,*)nft
!****SetdimensionofX,Y,Z****
allocate(X(0:nt),Y(0:nt),Z(0:nt))
!****Initalcondition****
it=0
t=0.0d0
read(10,*)apara
read(10,*)X(0)
write(6,*)apara
write(6,*)X(0)
read(10,*)apara
read(10,*)Y(0)
write(6,*)apara
write(6,*)Y(0)
read(10,*)apara
read(10,*)Z(0)
write(6,*)apara
write(6,*)Z(0)
!****openoutputfileandwriteinitalcondition****
open(20,file='lorenz1.dat')
write(20,*)it,t,X(0),Y(0),Z(0)
!****Timemarchingloop********************************************************
地球惑星内部物理学演習B 資料7
122
doit=1,nt
i=it-1
t=dfloat(it)*dt
!Runge-Kuttamethod
X_o(1)=X(i)
X_o(2)=Y(i)
X_o(3)=Z(i)
callcal_RHS(X_o,k1)
X_m(:)=X_o(:)+0.5d0*dt*k1(:)
callcal_RHS(X_m,k2)
X_m(:)=X_o(:)+0.5d0*dt*k2(:)
callcal_RHS(X_m,k3)
X_f(:)=X_o(:)+dt*k3(:)
callcal_RHS(X_f,k4)
X_f(:)=X_o(:)+dt/6.0d0*(k1(:)+2.0d0*k2(:)+2.0d0*k3(:)+k4(:))
X(i+1)=X_f(1)
Y(i+1)=X_f(2)
Z(i+1)=X_f(3)
!****writeresultsineachnftsteps****
if(mod(it,nft)==0)write(20,*)it,t,X(it),Y(it),Z(it)
enddo
地球惑星内部物理学演習B 資料7
123
!****EndofTimemarchingloop**************************************************
close(10)
close(20)
stop
endprogramlorenzrk
ローレンツ方程式をルンゲ・クッタ法により解くプログラムで,sやgなどの物理パラメータの
宣言をモジュール,導関数,すなわち,右辺の計算をサブルーチンとしている。
usemod_para_l:モジュール mod_para_lを呼び出す。モジュール内で宣言された変数はグロー
バル変数として扱われる。モジュールをコンパイルすると lo_mod_para_1.mod というファイル
と lo_mod_para_1.oの両方ができる。lo_mod_para_1.modファイルは他の Fortran90 ファイルを
コンパイルするときに必要になるので,モジュールプログラムは先にコンパイルしなければな
らない。lo_mod_para_1.oは実行形式ファイルを作るときに使用される。
サブルーチンプログラム lo_cal_RHS.f
!
!calculateRHSofLorenzEquation
!
subroutinecal_RHS(X,k)
usemod_para_l
implicitnone
real(8)::X(3),k(3)
!CalculateRHS
k(1)=-sig*X(1)+sig*X(2)
地球惑星内部物理学演習B 資料7
124
k(2)=-X(1)*X(3)+gamm*X(1)-X(2)
k(3)=X(1)*X(2)-b*X(3)
return
endsubroutinecal_RHS
ローレンツ方程式の右辺を計算する。モジュールが use により呼び出されている。
モジュールプログラム lo_mod_para_l.f
!
!Definitionofparameters
!
modulemod_para_l
implicitnone
real(8)::sig,gamm,b
endmodulemod_para_l
共通の物理パラメータを格納するを変数を宣言している。モジュールで宣言された変数はグロ
ーバル変数として扱われる。サブルーチンが多く,サブルーチン間にまたがって使用される変
数が多数あるときには便利な機能である。
パラメータファイル lo_para.dat
#****ParametersforLorenzmodelcalculation****
'#(1)Sigma(Prandtlnumber)'
10.0d0
'#(2)Gamma(Rayleighnumber):criticalvalue=24.7368'
25.0d0
'#(3)b(wavelength)'
地球惑星内部物理学演習B 資料7
125
2.666666666666666667d0
'#(4)dt(Timestepincrement)'
2.0d-3
'#(5)nt(Numberoftimesteps)'
50000
'#(6)nft(Time-stepintervalwritingresults)'
10
'#(7)X(0)(initialvalueofX)'
10.0d0
'#(8)Y(0)(initialvalueofY)'
15.0d0
'#(9)Z(0)(initialvalueofZ)'
30.0d0
物理パラメータの値や初期値などを与える。gの値や初期値を変化させたいときには,値を変更
する。このファイルの値を変更した場合でも再コンパイルは必要ない。