绘制具有无穷和的

时间:2017-03-17 16:03:32

标签: matlab plot octave

我正在尝试绘制以下等式(让我们称之为“等式1”):

equation 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')

问题是我得到的只是一个平坦的表面:

enter image description here

方程式1被假设为以下具有边界值的抛物型偏微分方程的解:

enter image description here

在得到数值解之后,它应该是这样的:

enter image description here

此图在边界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看起来好多了:

much better

史蒂夫在指出我的数字解决方案可能是错误时也是对的。我没有注意到边界值是我的函数的导数,而不是函数的实际值。我会问老师这件事。

EDIT2! 好,我知道了。要计算边界处的导数,您必须在同一本书中使用提示2.21:

enter image description here

% 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中测试这个运算符,因为我太穷了。

Yvon:我认为解析解公式来自傅立叶扩展的真实部分,但是作者并不知道他们是如何得到它的。

0 个答案:

没有答案