3. 多くの Numerical Method の背景となる重要な数学式。 Fig. 6.2 x+h における異なる次数のテイラー展開。 A)0 次近似、 B) 1次近似、 C) 2次近似、 D) 3次近似。
4. Numerical model テイラー展開のある点で切り捨てを行って進行。 この切り捨てにより起こる誤差-> Numerical Error ある method が n 次精度( n 次で切り捨て)->最も大きな各ステップでの切り捨て誤差は h n+1 *何故 Numerical Error を気にするのか? ① エラーは無い方がいい。出来る限り精度の良い結果を得るため。 ② 解の安定性。誤差が打ち消し合う場合と増幅する場合がある。 Fig. 6.3 Numerical Error の例。 A) 始めは小さいが徐々に真値から外れてくる。 B) 近似値が振動する。振動により現実的にはありえない負の値を示すこともある (●)
5. 力学的な微分式の微分段階はタイムステップ ? t (一定でなくてもいい)を用いて Fig. 6.4 Numerical integration method の構成 テイラー式を用いた最も単純な update formula 。 O( ? t) : 切り捨てによる誤差 (i.e. for t =0.01, ? t 2 = 1e ?4 , ? t3=1e?6; whereas for t=1, ? t 2 = ? t n =1) 。 一次精度
6. Euler Integration の例: 単純な algal growth model 二次以降のテイラー級数を切り捨てるため、事実上 ? t の間速度が一定だと仮定->もしそういう場合でなければ精度はあまり良くない( Fig. 6.5A )。 対策としては ? t を小さくすることである。モデルの性質が本当に悪いと、何も変化しない位 ? t を小さくする必要があるかも
7. 積分法の良し悪しのポイント;精度、安定性、速さ、メモリ必要量 ① 精度 離散化誤差(各タイムステップで発生):テイラー展開の結果と比較することで見積もれる。高次の method はタイムステップが進むほど高精度になる。 ② 安定性 連続的な solution points 間における振動増加をもたらす可能性の大きさ。なるべく精度良く安定である方がいい。 ③ スピード 1) タイムステップの数と ? t の取り方、 2)t ~ t+ ? t での関数計算の数 ④ メモリ必要量 繰り返し積分が複雑になればなるほどメモリは多く必要になる。 ← 毎回のタイムステップで記憶しなければいけない情報量の多さ hard-to-integrate type of problems は’ stiff’ sets of equations と言われる。 ← 異なる固有のタイムスケールを持ってモデル化されたプロセスに起きる。 例; dynamics of bacterial population dynamics (time scale: hours~days) + a forcing with a seasonal or year-to-year variation (time scale: months~years) ← ほとんどのコンピュータは速いプロセスに合わせてで計算する
8. 数値解析において常微分方程式の近似解を求める一連の方法。最も良く用いられる 4 次の Runge-Kutta method は各タイムステップ ? t で 4 つの評価を行う。 次の値( C i +1 )は、現在の値( C i )に間隔( ? t )と推定された勾配の積を加えたものである。その勾配は次の 4 つの勾配の重み付け平均で求める。 4 次精度の方法、すなわち全体の切り捨て誤差が ? t 5 のオーダーになる ← ? t 一定
13. R model では信頼性と効率性を達成するようなステップサイズを自動的に選ぶ繰り返し積分法 (ode) が利用できる( pakage deSolve )。 より単純な繰り返し積分はスピードに関していくつか問題がある。もし高精度で安定な Euler or 4th order Runge-Kutta method で用いた ? t が出力区間と同じかより大きいとしたら、その method はおそらく良い選択である。 ← fixed time step method によって得られた結果が十分に高精度か確かめる前に ? t が十分に小さいかチェックしなくてはいけない。 <チェック項目> あるタイムステップでまずモデルを走らせる タイムステップを二倍にして二つの run 間での違いを検査する。 もし違いが顕著なら、有意に変化しなくなるまでタイムステップを半分にする。 もし違いが有意でないなら、有意に変化するまでタイムステップを二倍にする。 大事を取るため、十分な精度のタイムステップの半分を用いる。
14. 空間的一次元導関数の数値近似は有限の節目や layer の関数値を計算。 これらの微分には空間での位置の経過を慎重に追わなくてはいけない。特に、濃度、表層、フラックスや距離が ボックスの中心の値 なのか 境界の値 なのか。 Fig. 6.6 空間的導関数は空間定義域を grid cells や boxes の数で再分配することで近似する。位置 (x i ) はボックスの 中心 。 相対的距離はボックスの 中心間 の距離 ( ? x i,i+1 ) かボックスの 長さ ( ? x i, ? x i+1, ) 濃度や密度などは grid cell の 中心の値 フラックスはボックスの 境界 で定義される。
15. First step; flux-gradient form で一般的な反応輸送方程式を立てる。 (g は一次成長速度 ) 各ボックス i に関して Ci はボックス i における濃度、 ? x i はボックス i の厚さ、 Ai はボックス i の中心部表面積、 ? i はボックス i 周りのフラックス勾配を表す。 ボックス i におけるフラックス勾配は次のボックス (i, i+1) と前のボックス (i-1, i) の境界間の違いで定義される:
19. The backward differencing scheme 濃度が負にならず、安定。だが一次精度。-> Taylor 展開の二次以上の項を無視することで発生する 切り捨て誤差 ( numerical dispersion or numerical dissipation ) 実際の現象がシャープな勾配だとしても、なだらかな勾配になることがある。 例)非移動性で一定速度の個体数増加 Fig. 6.7 実際の局所的な分布が、 advection を含んだ growth model を行うと実線のようになだらかな分布を示す。
20. ① ほとんどの場合、移流と拡散項が混合しており、数値的分散 (numerical dispersion) はその他の分散に対してごく小さいと考えられる。このような場合、 the backward numerical scheme は十分な精度であると考えるかもしれない。 ② より複雑な numerical scheme を用いる 数値的分散は Taylor series を高次項まで用いることで抑えられるが、それらの手法は複雑であるため未だにいくつかの問題がある。参考として Gurney and Nisbet (1998) の本が挙げられる。 ③ 大きなボックスに対して特に起こるため、ボックス数を増やす。 しかし、ボックス数を増やせばコンピュータへの負担が大きくなるので限度はある。 ④ 濃度が負になる危険性を無視して centre differences を用いる。 これはある条件下では最善の解決策。空間軸に対して濃度が増加しない限り、負の濃度が算出されることがない。さらに数値的分散はかなり抑えられる。 例)堆積有機物濃度…堆積物の深度が深くなるほど減少する。 -> explicit way の堆積有機物モデルは移流を centre difference を用いて記述する。
21. 異なる scheme における数値的分散の効果を見る。 3 種類の scheme ① backward differences( ? =1) ② centred differences( ? =0.5) ③ a flexible scheme ( the Fiadeiro scheme ) ( ? =Peclet number の関数 ) 同じ大きさのボックスに対して、3つの scheme とも簡単のために一つの方程式でモデル化する。 Pe ( Peclet number); 分散過程における移流の相対的重要性を表す無次元数。
22. require(deSolve) まず deSolve を読み込む # general parameters times <- c(1/365,10/365,30/365,1/4,1/2,1) # y time at which output is required # General parameters for all runs DD <- 0.1 # cm2/y diffusion coefficient representing bioturbatin u <- 1 # cm/y advection = sedimentation rate init <- 1000 # n.cm-3 initial density in upper layers 上層の初期密度 outtime <- 6 # choose the output time point (as found in 'times') you want to see in the graphs # default outtime=6 will show distribution after 1.0 year # Function to calculate derivatives Lumin <-function(t,LUMIN,parameters) 関数 Lumin の定義 { with (as.list(c(LUMIN,parameters)), { FluxDiff <- -DD*diff(c(LUMIN[1],LUMIN,LUMIN[numboxes]))/delx 拡散フラックス FluxAdv <- u * (sigma * c(0,LUMIN) + (1-sigma) * 移流フラックス c(0,LUMIN[2:numboxes],LUMIN[numboxes])) 表層、中間、最深層にわける Flux <- FluxDiff + FluxAdv 拡散+移流 dLUMIN <- -diff(Flux)/delx Flux(i) – Flux(i-1) i=2-numbox list(dLUMIN ) 境界におけるフラックス }) }
23. # Function to run the model and produce output Modelfunc <- function(ltt,diffm,numboxes) 関数 Modelfunc の定義 { # complete set of parameters, depending on choices delx <- 3/numboxes # thickness of boxes in cm ? x :ボックス長 if (diffm=="back") sigma<-1 if (diffm==“cent”) sigma<-0.5 3パターンの解き方 if (diffm=="fiad") { if (DD>0) { Pe <- u * delx/DD sigma <- (1 + (1/tanh(Pe) - 1/Pe))/2 } if (DD==0) sigma <- 1 } pars<-as.list(c( 関数 Lumin の [parameters] numboxes = numboxes, delx = delx, sigma = sigma, DD = DD, u = u ))
24. # call 呼び出し state <- c(LUMIN=Ll) 初期値 out <- ode.band(y=state,times,func=Lumin,parms=pars,nspec=1 (the number of *species* (components) in the model) ) # store output Dl <- out[outtime,2:(numboxes+1)] # output Distance <- seq(from=delx/2, by=delx, length.out=numboxes) # distance of box centres from x=0 if (diffm=="back") ttext<-"Backward Differences“ if (diffm=="cent") ttext<-"Centered Differences" if (diffm=="fiad") ttext<-"Fiadeiro Scheme" if (ltt==1){ #numberbox =300 plot(Dl,Distance,xlim=c(0,max(Dl)),ylim=c(numboxes*delx,0),type="l", main=ttext,xlab="Tracer density",ylab="Depth (cm)") legend(200,2, legend=c("n=300","n=120","n=60","n=30","n=15"), lty=c(1,2,3,4,5),title="no. of boxes",pch=c(-1,-1,-1,-1,-1)) pch=type of symbol } if (ltt>1)lines(Dl,Distance,lty=ltt) #numberbox =120, 60, 30, 15 } ode.band(y, times, func, parms, nspec = NULL, bandup = nspec, banddown = nspec, method = "lsode", ...) Assumes a banded Jacobian matrix, but does not rearrange the state variables (in contrast to ode.1D). Suitable for 1-D models that include transport only between adjacent layers and that model only one species.
25. # Run model with number of different options windows() par (mfrow=c(1,3),oma=c(1,1,4,1),mar=c(5, 4, 4, 2)+0.1,mgp=c(3,1,0)) numboxlist <- c(300,120,60,30,15) for (diffm in c("back","cent","fiad")) { for (ltt in 1:5) { numboxes<-numboxlist[ltt] Modelfunc(ltt,diffm,numboxes) } } ttext<-paste("Luminophore distribution at t = ",round(times[outtime],2),"year") mtext(outer=TRUE,side=3,ttext,cex=2)
26. 小さい Pe : Centred diff. ( dispersion-donated )、大きい Pe : backward diff. ( advection-donated )に切り替わる。 3つの scheme による計算結果を比較。 Backward は数値的分散の効果を大きく反映。ボックス数を多くしても。 Centre ではボックス数が少ない場合に結果がずれる。しかし、これは初期条件の影響もある。ボックス数 30 と 300 では結果がそれほど変わらない。 The Fiadeiro scheme は centre differences より backward differences に近い( D が低い値なので、 Pe が大きい)。 Backward よりは僅かに良い結果。 dispersion coefficient が増加 又は advection が減少すれば the Feadeiro scheme は centre differences に近づくだろう。 最後に、この場合 centred differences は不安定性を示さなかった。
28. #----------------------# # the model equations: # #----------------------# model<-function(t,state,parameters){ 関数 model を定義 with(as.list(c(state,parameters)),{ # unpack the state variables, parameters dD <- -k1*E*D + k2*I dI <- k1*E*D - k2*I - k3*I*F dE <- -k1*E*D + k2*I + k3*I*F dF <- - k3*I*F dG <- k3*I*F list(c(dD,dI,dE,dF,dG)) # the output, packed as a list }) } #-----------------------# # the model parameters: # #-----------------------# parameters<-c(k1=0.01/24, # parameter values k2=0.1/24, k3=0.1/24)
29. #-------------------------# # the initial conditions: # 初期濃度 ( D, I, E, F, G) #-------------------------# state <-c(D=100, # state variable initial conditions I=10, E=1, F=1, G=0) #----------------------# # RUNNING the model: # #----------------------# times <-seq(0,300,0.5) # time: from 0 to 300 hours, steps of 0.5 hours # integrate the model require(deSolve) # package with the integration routine: out <-as.data.frame(ode(state,times,model,parameters)) #------------------------# # PLOTTING model output: # #------------------------# #windows() par(mfrow=c(2,2), oma=c(0,0,3,0)) # set number of plots (mfrow) and margin size (oma) plot (times,out$D,type="l",main="[D]",xlab="time, hours",ylab="mol/m3",lwd=2) plot (times,out$F,type="l",main="[F]",xlab="time, hours",ylab="mol/m3",lwd=2) plot (times,out$E,type="l",main="[E]",xlab="time, hours",ylab="mol/m3",lwd=2) plot (times,out$I,type="l",main="[I]",xlab="time, hours",ylab="mol/m3",lwd=2) mtext(outer=TRUE,side=3,"enzymatic reaction",cex=1.5) #plot (times,out$sum,type="l",col="red") ode(y, times, func, parms, method = c(“lsoda”, “lsode”, “lsodes”, “lsodar”, “vode”, “daspk”, "euler", "rk4", "ode23", "ode45"), ...)
30. Soetaert, K. and P.M.J. Herman. 2009. A practical guide to ecological modelling using R as a simulation platform. Springer. Output of the enzymatic reaction model