我正在尝试绘制以下等式(让我们称之为“等式1”):
这是我正在测试的代码:
clear all;
xl=0; xr=1; % x domain [xl,xr]
J = 10; % J: number of division for x
dx = (xr-xl) / J; % dx: mesh size
tf = 0.1; % final simulation time
Nt = 60; % Nt: number of time steps
dt = tf/Nt/4;
x = xl : dx : xr; % generate the grid point
u_ex = zeros(J+1,Nt);
for n = 1:Nt
t = n*dt; % current time
for j=1:J+1
xj = xl + (j-1)*dx;
suma = zeros(100 , 1);
for k= 1:100
suma(k) = 4/(((2*k-1)^2) *pi*pi);
suma(k) = suma(k) * exp(-((2*k-1)^2) *pi*pi*t) * cos(2*k-1)*pi*xj;
end
m = sum(suma);
u_ex(j, n)= 0.5 - m;
end
end
tt = dt : dt : Nt*dt;
figure(1)
surf(x,tt, u_ex'); % 3-D surface plot
xlabel('x')
ylabel('t')
zlabel('u')
问题是我得到的只是一个平坦的表面:
方程式1被假设为以下具有边界值的抛物型偏微分方程的解:
在得到数值解之后,它应该是这样的:
此图在边界x = 0和x = 1处获得正确的值。等式1的图在边界处没有这些值。
我完整的.m代码(绘制数值解和方程1)是:
clear all; % clear all variables in memory
xl=0; xr=1; % x domain [xl,xr]
J = 10; % J: number of division for x
dx = (xr-xl) / J; % dx: mesh size
tf = 0.1; % final simulation time
Nt = 60; % Nt: number of time steps
dt = tf/Nt/4;
mu = dt/(dx)^2;
if mu > 0.5 % make sure dt satisy stability condition
error('mu should < 0.5!')
end
% Evaluate the initial conditions
x = xl : dx : xr; % generate the grid point
% store the solution at all grid points for all time steps
u = zeros(J+1,Nt);
u_ex = zeros(J+1,Nt);
% Find the approximate solution at each time step
for n = 1:Nt
t = n*dt; % current time
% boundary condition at left side
gl = 0;
% boundary condition at right side
gr = 0;
for j=2:J
if n==1 % first time step
u(j,n) = j;
else % interior nodes
u(j,n)=u(j,n-1) + mu*(u(j+1,n-1) - 2*u(j,n-1) + u(j-1,n-1));
end
end
u(1,n) = gl; % the left-end point
u(J+1,n) = gr; % the right-end point
% calculate the analytic solution
for j=1:J+1
xj = xl + (j-1)*dx;
suma = zeros(100 , 1);
for k= 1:100
suma(k) = 4/(((2*k-1)^2) *pi*pi);
suma(k) = suma(k) * exp(-((2*k-1)^2) *pi*pi*t) * cos(2*k-1)*pi*xj;
end
m = sum(suma);
u_ex(j, n)= 0.5 - m;
end
end
% Plot the results
tt = dt : dt : Nt*dt;
figure(1)
colormap(gray); % draw gray figure
surf(x,tt, u'); % 3-D surface plot
xlabel('x')
ylabel('t')
zlabel('u')
title('Numerical solution of 1-D parabolic equation')
figure(2)
surf(x,tt, u_ex'); % 3-D surface plot
xlabel('x')
ylabel('t')
zlabel('u')
title('Analytic solution of 1-D parabolic equation')
maxerr=max(max(abs(u-u_ex))),
该代码摘自陈义东,李吉春,第2章,练习3中的“使用MATLAB的计算偏微分方程”。
简而言之:我不是在询问微分方程或边界问题,我想知道的是:为什么在绘制公式1时得到平坦的表面?我错过了一个括号吗? 我不想使用symsum函数,因为它永远不会停止脚本执行,我想学习如何使用symsum绘制公式1。
我用Matlab R2008b和Octave 4.2.1测试了这段代码。我得到了相同的结果(即使for loop
中{1000}和50000项与k
变量相加,也是如此。
修改<!/强> 谢谢,史蒂夫!
我在余弦附近错过了几个括号,正确的代码是:
clear all; % clear all variables in memory
xl=0; xr=1; % x domain [xl,xr]
J = 10; % J: number of division for x
dx = (xr-xl) / J; % dx: mesh size
tf = 0.1; % final simulation time
Nt = 60; % Nt: number of time steps
dt = tf/Nt/4;
mu = dt/(dx)^2;
if mu > 0.5 % make sure dt satisy stability condition
error('mu should < 0.5!')
end
% Evaluate the initial conditions
x = xl : dx : xr; % generate the grid point
% store the solution at all grid points for all time steps
u = zeros(J+1,Nt);
u_ex = zeros(J+1,Nt);
% Find the approximate solution at each time step
for n = 1:Nt
t = n*dt; % current time
% boundary condition at left side
gl = 0;
% boundary condition at right side
gr = 0;
for j=2:J
if n==1 % first time step
u(j,n) = j;
else % interior nodes
u(j,n)=u(j,n-1) + mu*(u(j+1,n-1) - 2*u(j,n-1) + u(j-1,n-1));
end
end
u(1,n) = gl; % the left-end point
u(J+1,n) = gr; % the right-end point
% calculate the analytic solution
for j=1:J+1
xj = xl + (j-1)*dx;
suma = zeros(1000 , 1);
for k= 1:1000
suma(k) = 4/(((2*k-1)^2) *pi*pi);
suma(k) *= exp(-((2*k-1)^2) *pi*pi*t) * cos((2*k-1)*pi*xj);
end
m = sum(suma);
u_ex(j, n)= 0.5 - m;
end
end
% Plot the results
tt = dt : dt : Nt*dt;
figure(1)
colormap(gray); % draw gray figure
surf(x,tt, u'); % 3-D surface plot
xlabel('x')
ylabel('t')
zlabel('u')
title('Numerical solution of 1-D parabolic equation')
figure(2)
surf(x,tt, u_ex'); % 3-D surface plot
xlabel('x')
ylabel('t')
zlabel('u')
title('Analytic solution of 1-D parabolic equation')
现在我的等式1看起来好多了:
史蒂夫在指出我的数字解决方案可能是错误时也是对的。我没有注意到边界值是我的函数的导数,而不是函数的实际值。我会问老师这件事。
EDIT2! 好,我知道了。要计算边界处的导数,您必须在同一本书中使用提示2.21:
% hint 2.21 given by the book
% it is better to calculate the boundary values after calculating the inner points inside the for j = 1:m loop because you will need them:
u(1, n) = u(2, n) - dx * gl; % the left-end point
u(J+1,n) = u(J, n) + dx * gr; % the right-end point
现在我的数值解决方案看起来像我的解析解决方案:D
Matlab R2008b无法识别Octave所做的*=
运算符。我没有在其他版本的Matlab中测试这个运算符,因为我太穷了。