Upload
carsyn
View
51
Download
8
Embed Size (px)
DESCRIPTION
ODE. Ordinary Differential Equations. 一阶常微分方程的初值问题: 节点: x 1
Citation preview
Ordinary Differential Equations
ODE
• 一阶常微分方程的初值问题:
• 节点: x1<x2< … <xn
• 步长 为常数
00 )(
),(
yxy
yxfdx
dy
1 ii xxh
• 一 欧拉方法(折线法) yi+1=yi+h f(xi,yi) (i =0,1, …, n-1)
优点:计算简单。 缺点:一阶精度。• 二 改进的欧拉方法
)(2
1),(
),(
1
1
cpi
piic
iiip
yyy
yxhfyy
yxhfyy
• 改进的欧拉公式可改写为
它每一步计算 f(x,y) 两次,截断误差为 O(h3)
),(
),(
)(2
12
1
211
hkyhxfk
yxfk
kkh
yy
ii
ii
ii
ydt
dy
10,1)0( ty
tey 精确解:
function [t,y] = Heun(ode,tspan,h,y0)t = (tspan(1):h:tspan(end))';n = length(t);y = y0*ones(n,1);for i=2:n k1 = feval(ode,t(i-1),y(i-1)); k2 = feval(ode,t(i),y(i-1)+h*k1); y(i) = y(i-1)+h*(k1+k2)/2;end
• 三 龙格—库塔法 (Runge-Kutta)
欧拉公式可改写为
它每一步计算 f (xi,yi) 一次,截断误差为 O(h2)
),(1
11
ii
ii
yxfk
hkyy
• 标准四阶龙格—库塔公式
每一步计算 f (x, y) 四次,截断误差为 O(h5)
),(
)2
,2
(
)2
,2
(
),(
)22(6
34
23
12
1
43211
hkyhxfk
kh
yh
xfk
kh
yh
xfk
yxfk
kkkkh
yy
ii
ii
ii
ii
ii0
1/2 1/2
1/2 0 1/2
1 0 0 1
1/6 2/6 2/6 1/6
.)()),(),(,()(
;)()),(),(,()('
'
bvxvxuxgxv
auxvxuxfxu
43211
43211
226
226
cccch
vv
kkkkh
uu
ii
ii
),,(
),,(
)2
1,
2
1,
2(
)2
1,
2
1,
2(
)2
1,
2
1,
2(
)2
1,
2
1,
2(
),,(
),,(
334
334
223
223
112
112
1
1
hcvhkuhxgc
hcvhkuhxfk
hcvhkuh
xgc
hcvhkuh
xfk
hcvhkuh
xgc
hcvhkuh
xfk
vuxgc
vuxfk
iii
iii
iii
iii
iii
iii
iii
iii
对于两个分量的一阶常微分方程组
用经典 4 阶 Runge-Kutta 法求解的格式为
,1
1
n
jjjii kbhyy
.,,3,2,
),,(
),,(
1
1
1
1
1
njac
kahyhcxfk
yxfk
j
mjmj
j
mmjmijij
ii
n 级显式 Runge-Kutta 方法的一般计算格式:
其中
.1,,3,2),51623(12 211 Nifffh
yy iiiii
.1,,4,3),9375955(24 3211 Niffffh
yy iiiiii
.1,,3,2),5199(24 2111 Niffffh
yy iiiiii
Adams 外插公式( Adams-Bashforth 公式)是一类 k+1 步 k+1 阶显式方法三步法( k=2) ,
四步法( k=3) ,
Adams 内插公式( Adams-Moulton 公式)是一类 k+1 步 k+2 阶隐式方法三步法( k=2) ,
Adams 预估 -校正方法( Adams-Bashforth-Moulton 公式)一般取四步外插法与三步内插法结合。
#include <stdio.h>#include <stdlib.h>#include <math.h>#define TRUE 1main() {int nstep_pr, j, k;float h, hh, k1, k2, k3, k4, t_old, t_limit, t_mid, t_new, t_pr, y, ya, yn;double fun(); printf( "\n Fourth-Order Runge-Kutta Scheme \n" ); while(TRUE){ printf( "Interval of t for printing ?\n" ); scanf( "%f", &t_pr ); printf( "Number of steps in one printing interval?\n" ); scanf( "%d", &nstep_pr ); printf( "Maximum t?\n" ); scanf( "%f", &t_limit ); y = 1.0; /* Setting the initial value of the solution */ h = t_pr/nstep_pr; printf( "h=%g \n", h ); t_new = 0; /* Time is initialized. */ hh = h/2; printf( "--------------------------------------\n" ); printf( " t y\n" ); printf( "--------------------------------------\n" ); printf( " %12.5f %15.6e \n", t_new, y );
do{ for( j = 1; j <= nstep_pr; j++ ){ t_old = t_new; t_new = t_new + h; yn = y; t_mid = t_old + hh; yn = y; k1 = h*fun( yn, t_old ); ya = yn + k1/2; k2 = h*fun( ya, t_mid ); ya = yn + k2/2; k3 = h*fun( ya, t_mid ); ya = yn + k3 ; k4 = h*fun( ya, t_new ); y = yn + (k1 + k2*2 + k3*2 + k4)/6; } printf( " %12.5f %15.6e \n", t_new, y ); } while( t_new <= t_limit ); printf( "--------------------------------------\n" ); printf( " Maximum t limit exceeded \n" ); printf( "Type 1 to continue, or 0 to stop.\n" ); scanf( "%d", &k ); if( k != 1 ) exit(0); }}
double fun(y, t)float y, t;{float fun_v; fun_v = -y; return( fun_v );}
四 误差的控制 我们常用事后估计法来估计误差,即从 xi
出发,用两种办法计算 y(xi+1) 的近似值。记 为从 xi 出发以 h 为步长得到的 y(xi+1) 的近似值,记 为从 xi 出发以 h/2 为步长跨两步得到的 y(xi+1) 的近似值。设给定精度为 ε 。如果不等式
成立,则 即为 y(xi+1) 的满足精度要求的近似值。
)(1
hiy
)2/(1
hiy
)(1
)2/(1
hi
hi yy
)2/(1
hiy
自适应:使用 2个不同的 h。如果一个大的 h和一个小的 h得到的解相同,那么减小 h就没有意义了;相反如果两个解差别大,可以假设大 h值得到的解是不精确的。使用相同的 h值, 2种不同的算法。如果低精度算法与高精度算法的结果相同,则没有必要减小 h。
Ode23 非刚性 , 单步法 , 二三阶 Runge-Kutta,精度低Ode45非刚性 , 单步法 , 四五阶 Runge-Kutta,精度较高 ,最常用Ode113非刚性 , 多步法 , 采用可变阶 (1-13)Adams PECE 算法 , 精度可高可低Ode15s 刚性 , 多步法 ,采用 Gear’s (或 BDF)算法 , 精度中等 . 如果 ode45很慢 , 系统可能是刚性的 ,可试此法Ode23s 刚性 , 单步法 , 采用 2阶 Rosenbrock法 , 精度较低 , 可解决 ode15s 效果不好的刚性方程 .Ode23t 适度刚性 , 采用梯形法则 ,适用于轻微刚性系统 ,给出的解无数值衰减 .Ode23tb 刚性 , TR-BDF2, 即 R-K的第一级用梯形法则 ,第二级用 Gear 法 . 精度较低 , 对于误差允许范围比较差的情况 ,比 ode15s好 .
Matlab 函数
Matlab’s ode23(Bogacki, Shampine)
).9865(72
),,(
),432(9
),4
3,
4
3(
),2
1,
2(
),,(
43211
14
3211
23
12
1
kkkkh
e
yhxfk
kkkh
yy
hkyh
xfk
hkyh
xfk
yxfk
n
nn
nn
nn
nn
nn
Runge-Kutta-Fehlberg方法 (RKF45)
).40
11
4104
1859
2565
35442
27
8,
2(
),4104
845
513
36808
216
439,(
),32
7296
2197
7200
2197
1932,
13
12(
),32
9
32
3,
8
3(
),4
1,
4(
),,(
543216
43215
3214
213
12
1
hkhkhkhkhkyh
xfk
hkhkhkhkyhxfk
hkhkhkyh
xfk
hkhkyh
xfk
hkyh
xfk
yxfk
nn
nn
nn
nn
nn
nn
4阶 Runge-Kutta近似
hkhkhkhkyz nn 54311 5
1
4104
2197
2565
1408
216
25
5阶 Runge-Kutta近似
hkhkhkhkhkyy nn 654311 55
2
50
9
56430
28561
12825
6656
135
16
局部误差估计 11 nn zy
Matlab’s ode45 is a variation of RKF45
0)1( 2 xxxx
xx
xx
2
1
12212
21
)1( xxxx
xx
Van der Pol:
function xdot = vdpol(t,x)xdot(1) = x(2);xdot(2) = -(x(1)^2 -1)*x(2) -x(1);xdot = xdot'; % VDPOL must return a column vector.
% xdot = [x(2); -(x(1)^2 -1)*x(2) -x(1)]; % xdot = [0 , 1; -1 ,-(x(1)^2 -1)] *x;
t0 = 0;tf = 20;x0 = [0; 0.25]; [t,x] = ode45(@vdpol,[t0,tf],x0);plot(t,x);figure(101)plot(x(:,1),x(:,2));
Lorenz吸引子
function xdot = lorenz(t,x)xdot = [ -8/3, 0, x(2); 0, -10, 10;
-x(2), 28, -1]*x;x0 = [0,0,eps]';[t,x] = ode23('lorenz',[0,100],x0);plot3(x(:,1),x(:,2),x(:,3));plot(x(:,1),x(:,2));
function yp = examstiff(t,y)yp = [-2, 1; 998, -998]*y + [2*sin(t);999*(cos(t)-sin(t))];
y0 = [2;3];tic,[t,y] = ode113('examstiff',[0,10],y0);toctic,[t,y] = ode45('examstiff',[0,10],y0);toctic,[t,y] = ode23('examstiff',[0,10],y0);toctic,[t,y] = ode23s('examstiff',[0,10],y0);toctic,[t,y] = ode15s('examstiff',[0,10],y0);toctic,[t,y] = ode23t('examstiff',[0,10],y0);toctic,[t,y] = ode23tb('examstiff',[0,10],y0);toc
)sin(cos999
sin2
998998
12'
'
xx
x
v
u
v
u
3
2
)0(
)0(
v
u
刚性方程
向后差分方法( Gear’s method)隐式 Runge-Kutta法
function f = weissinger(t,y,yp)f = t*y^2*yp^3 - y^3*yp^2 + t*(t^2+1)*yp - t^2*y;
t0 = 1;y0 = sqrt(3/2);yp0= 0; % guess[y0,yp0] = decic(@weissinger,t0,y0,1,yp0,0); % 求出自洽初值。保持 y0 不变[t,y] = ode15i(@weissinger,[1,10],y0,yp0);ytrue = sqrt(t.^2+0.5);plot(t,ytrue,t,y,'o')
),(),( ' ytfyytM
0),,( ' yytf
0)1()()( 2'22'33'2 ytyttyyyty
线性隐式 ODE:
完全隐式 ODE(Matlab7):
Weissinger方程 :
2/3 5.0)( 2 tty初值为 时 , 解析解为
function yp = ddefun(t,y,Z)yp = zeros(2,1);% define lags=[1,3]yp(1) = Z(1,2)^2 + Z(2,1)^2;yp(2) = y(1) + Z(2,1);
function y = ddehist(t)y = zeros(2,1);y(1) = 1;y(2) = t-2;
lags = [1,3];sol = dde23(@ddefun,lags,@ddehist,[0,1]);hold on;plot(sol.x,sol.y(1,:),'b-');plot(sol.x,sol.y(2,:),'r-');
))(,),(),(,()( 1'
ktytytytfty
)1()(
)1()3(
21'2
22
21
'1
tytyy
tytyy
)0(,2)(
1)(
2
1
ttty
ty
延迟微分方程
Sol = dde23(ddefun,lags,ddehist,tspan)
初值 :
)(,)(
;),()()( '''
byay
bxaxryxqyxpy
,,
),()(2
)(2
10
11
2
11
N
jjjjj
jjjj
yy
xryxqh
yyxp
h
yyy
,2
1 jj ph
a
,2 2jj qhb
,2
1 jj ph
c
,,
;,,2,1,
10
211
N
jjjjjjj
yy
Njrhycybya
有限差分法二阶线性边值问题
差分离散:
).( jj xrr
),( jj xpp
),( jj xqq
bvp4c
.0)(,)(
),()()('11
1'1
"1
ayay
xryxqyxpy
.1)(,0)(
,)()('22
2'2
"2
ayay
yxqyxpy
).()(
)()()( 2
2
11 ty
by
bytyty
线性边值问题的打靶法:二阶线性边值问题 (11)的可以通过求解下面两个初值问题获得。
原来边值问题的解可以表示为:
非线性边值问题的打靶法
(IVP1)
(IVP2)
符号计算
y = dsolve('D2y = -a^2*y','x') % 求通解y = dsolve('D2y = -a^2*y','y(0)=1','Dy(pi/a)=0','x')[x,y] = dsolve('Dx=4x-2y','Dy=2x-y','t')
1 u
0u
4
1),(
22 yxyxu
Pdetool求解区域 ,定义边界 ,网格划分 ,计算 ,画图 , 保存文件求解
边条
解析解
演示求解过程
fauuc )(
fauuct
ud
)(
fauuct
ud
)(2
2
duauuc )(
2222121222121
1212111212111
)()(
)()(
fuauaucuc
fuauaucuc
02 pu
0 u
Stokes 问题
Q1-P0有限元离散
0,1 vu
0,0 vu
0
0
v
u
0
0
v
u
uuuu 2
Re
1
pt
0 u
Navier-Stokes 问题
MAC差分离散
X
Y
0 0.5 10
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
Re=500
Frame 001 10 Jul 2004 Frame 001 10 Jul 2004
X
Y
0 0.5 10
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
Re=2000
Frame 001 10 Jun 2004 Frame 001 10 Jun 2004
x
y
0 1 2 3 4 5 6 70
0.5
1
1.5
2
2.5
3
2-D BACKSTEP FLOWUpwind+Possion Equation,t=15s
x
y
0 1 2 3 4 5 6 70
1
2
3
2-D Back Step FlowSOLA t=0.5s
x
y
0 1 20
0.2
0.4
0.6
0.8
1
0
y
G
x
F
t
Q
sE
v
uQ
upE
uv
pu
u
F
s
2
vpE
pv
uv
v
G
s
2物理问题的控制方程:
前台阶流( A Mach 3 Wind Tunnel with a Step)模拟放置在风洞中的前台阶流动。风洞尺寸:宽 1.0 ,长 3.0 ,台阶高 0.2 ,放置在距风洞左边界 0.6 个单位长度处。
0
x
F
t
Q
sE
uQ
upE
pu
u
F
s )(
2
Sod问题Sod问题是在激波管中充以两种介质,维持一定的压力差,用隔膜分开;当
隔膜突然破裂后,形成间断面,研究其时间发展情况。Euler方程组:
A picture is worth a thousand words. - Anonymous
Make it right before you make it faster.- Brain W. Kernighan, P. J. Plauger,
The Elements of Programming Style(1978)