LLLLLL林 2024-05-29 23:44 采纳率: 0%
浏览 4

matlab求解微分方程,请大家帮纠错

求解微分方程-Uxx-Uyy+Ux+20yUy+U=f,我已经写出了代码,但误差太大,始终检查不出错误。
思路是:fish2d是用来求解-Uxx-Uyy=f类型的快速泊松方程求解器,因此方程化为-Uxx-Uyy=f-Ux-20yUy-U。用初值u0=0代入右端来迭代,每次求解时调用fish2d函数。真解已知,根据真解求出了右端项f。

以下为代码(其实是matlab):

  1. 主函数
clc,clear,close all
a=0;
b=1;
c=0;
d=1;
N1=31;
N2=31;
h1=(b-a)/N1;
h2=(d-c)/N2;
x=a+[1:N1-1]*h1;
y=c+[1:N2-1]*h2;
[X,Y]=meshgrid(x,y);

%准备矩阵
e1=ones(N1-1,1);
e2=ones(N2-1,1);
e3=ones((N1-1)*(N2-1),1);
I1=spdiags(e1,0,N1-1,N1-1);
I2=spdiags(e2,0,N2-1,N2-1);
I=spdiags(e3,0,(N1-1)*(N2-1),(N1-1)*(N2-1));
K3=spdiags([-e1,e1],[-1,1],N1-1,N1-1);
K4=spdiags([-e2,e2],[-1,1],N2-1,N2-1);

%A、B、C、D用以生成系数矩阵
C=kron(K3,I2);
C=C/(2*h1);     %u_x系数矩阵
D=kron(I1,K4);
D=D/(2*h2);     %u_y系数矩阵
for i=1:N2-1
    k=i;
    while k<=(N1-1)*(N2-1)
        D(:,k)=D(:,k)*20*y(i);  %a2(x,y)=20y。将矩阵每一列*20*所在列数
        k=k+(N2-1);
    end
end

%右端项f,代入真解解出
f=zeros(N1-1,N2-1);
for i=1:N1-1
    for j=1:N2-1
        f(i,j)=20*y(j)*(10*x(i)*y(j)*exp(x(i)^(9/2))*(x(i)- 1) + 10*x(i)*exp(x(i)^(9/2))*(x(i)- 1)*(y(j) - 1)) - 20*x(i)*exp(x(i)^(9/2))*(x(i)- 1)...
               - 20*y(j)*exp(x(i)^(9/2))*(y(j) - 1) + 10*x(i)*y(j)*exp(x(i)^(9/2))*(y(j)- 1) + 10*y(j)*exp(x(i)^(9/2))*(x(i)- 1)*(y(j)- 1)...
               - 90*x(i)^(9/2)*y(j)*exp(x(i)^(9/2))*(y(j) - 1) + 10*x(i)*y(j)*exp(x(i)^(9/2))*(x(i)- 1)*(y(j) - 1) - (405*x(i)^8*y(j)*exp(x(i)^(9/2))...
               *(x(i)-1)*(y(j)-1))/2-(495*x(i)^(7/2)*y(j)*exp(x(i)^(9/2))*(x(i)- 1)*(y(j)-1))/2+ 45*x(i)^(9/2)*y(j)*exp(x(i)^(9/2))*(x(i)- 1)*(y(j) - 1);
    end
end
f=reshape(f',(N1-1)*(N2-1),1);%reshape按列取值

% 求解
u0=zeros((N1-1)*(N2-1),1);
k=1;
while k<=2
    u1=fish2d(f-(C+D+I)*u0);
    u0=u1;
    k=k+1;
end
%画图
u1=reshape(u1,N2-1,N1-1);
mesh(X,Y,u1);
title('数值解');
figure
u_true=10*X.*Y.*(1-X).*(1-Y).*exp(X.^4.5);
mesh(X,Y,u_true);
title('真解');
figure
mesh(X,Y,u_true-u1);
title('误差');

2.fish2d函数

function u = fish2d(f)
% Poisson solver in 2D based on matlab fft
% square geometry, homogeneous Dirichlet boundary conditions
% requires uniform mesh (2^k-1)^2 interior nodes 
%
% C. T. Kelley, January 6, 1994
%
% This code comes with no guarantee or warranty of any kind.
%
% Solves - u_xx - u_yy = f
%
% Requires sintv.m and isintv.m
%
% function u = fish2d(f)
%
%
global fish_lal fish_ual ua;
n=length(f);
m=sqrt(n);
hh=.5/(m+1);
h2=(m+1)*(m+1);
e=ones(m,1);
%
% Don't compute eigenvalues, factor tridiagonal matrices
% or allocate space for the 2-D representation of the solution
% more than once. Note the use of global variables to store
% fish_ual, fish_lal, and ua.
%
if exist('fish_ual')==1
    [f1, f2]=size(fish_ual);
    m1=sqrt(f1);
else
    m1=m;
end
if (exist('fish_ual') == 0) | (m1 ~= m)
%
% allocate room for ua, the 2D representation of the solution
%
    ua=zeros(m,m);
%
% set up diagonal of system using eigenvalues of 1D operator
%
    x=1:m; x=pi*hh*x'; lam=sin(x); lam=h2*(2*ones(m,1) + 4*lam.*lam);
    en=h2*ones(n,1); fn=en; gn=en; dx=zeros(n,1);
    for i=1:m
        fn(i*m)=0;
        gn((i-1)*m+1)=0;
        dx((i-1)*m+1:i*m)=lam(i)*ones(m,1);
    end
    al=spdiags([-fn, dx, -gn], [-1,0,1], n,n);
%
% factor the tridiagonal matrix for solution in the x direction
%
    [fish_lal,fish_ual]=lu(al);
end
%
% Map f into a rectangular array.
% Take sine transform in y direction.
%
ua(:)=f;
ua=sintv(ua).';
%
% Solve in the x direction
%
ua(:)=fish_ual\(fish_lal\ua(:));
%
% Take inverse transform.
%
ua=isintv((ua.'));
%
% Map uz into a linear array.
%
u=ua(:);

function u=sintv(z)
% sine transform, assume that size(z)=[nx,ny]=[2^k-1,ny]
%
% C. T. Kelley, May 1994
%
% This code comes with no guarantee or warranty of any kind.
%
[nx,ny]=size(z);
ww=-4*fft([zeros(ny,1), z']',2*nx+2);
u=imag(ww(2:nx+1,:));

function u=isintv(z)
% inverse sine transform, assume that size(z)=[nx,ny]=[2^k-1,ny]
% 
% C. T. Kelley, May 1994
%
% This code comes with no guarantee or warranty of any kind.
%
[nx,ny]=size(z);
ww=ifft([zeros(ny,1), z']',2*nx+2);
u=imag(ww(2:nx+1,:));
  • 写回答

2条回答 默认 最新

  • 阿里嘎多学长 2024-05-29 23:44
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    在MATLAB中求解微分方程时,确保代码的准确性和效率至关重要。根据您提供的代码和问题描述,以下是一些可能需要检查和改进的地方:

    1. 矩阵构建

      • 您在构建系数矩阵C和D时使用了spdiags函数,这是正确的方法。但是,需要确保矩阵的大小和稀疏性是正确的,以及它们是否正确地代表了微分方程中的导数项。
      • 在构建D矩阵时,您使用了嵌套循环来乘以20*y(i)。这可能会引起性能问题,并且如果循环的终止条件不正确,可能会导致错误的矩阵值。建议使用MATLAB的向量化操作来提高效率和准确性。
    2. 右端项f的计算

      • 您提供的f的计算看起来相当复杂,需要确保所有的数学运算都是正确的。特别是,您需要验证真解是否正确地代入到了f的计算中。
    3. fish2d函数的正确性

      • fish2d函数用于求解泊松方程,它要求网格大小为(2^k-1)^2,这意味着N1和N2必须是2的幂次减1。如果N1和N2不满足这个条件,fish2d函数可能无法正常工作。
      • 函数中使用了全局变量,这可能会导致难以追踪的错误。建议使用函数的输入和输出参数来传递数据,避免使用全局变量。
    4. 迭代过程

      • 您使用了简单的迭代方法来更新解u1。需要确保迭代次数足够,并且每次迭代都正确地更新了解。
    5. 绘图和误差分析

      • 在绘图和误差分析部分,确保使用了正确的方法来计算误差,并且绘图准确地反映了数值解和真解之间的差异。
    6. 其他注意事项

      • 代码中使用了clc,clear,close all,这是MATLAB的命令,用于清除当前的命令窗口、变量和图形窗口。确保这是您想要的行为,因为它会清除所有之前的计算结果。
      • fish2d函数中,使用了lu分解来求解线性系统。确保矩阵是可分解的,并且lu分解是稳定的。
    7. 代码实现

      • 如果您需要进一步的帮助来实现或改进代码,请提供更多的信息或具体的问题。
    8. 参考资料

      • MATLAB官方文档:MATLAB Documentation
      • 数值分析和微分方程求解的相关书籍,如《数值分析》(Richard L. Burden, J. Douglas Faires)。

    最后,如果您需要更具体的帮助或代码审查,请提供更详细的信息或具体的问题。这样我可以更准确地为您提供帮助。

    评论 编辑记录

报告相同问题?

问题事件

  • 修改了问题 5月29日
  • 创建了问题 5月29日

悬赏问题

  • ¥100 python 调用 cgps 命令获取 实时位置信息
  • ¥15 两台交换机分别是trunk接口和access接口为何无法通信,通信过程是如何?
  • ¥15 C语言使用vscode编码错误
  • ¥15 用KSV5转成本时,如何不生成那笔中间凭证
  • ¥20 ensp怎么配置让PC1和PC2通讯上
  • ¥50 有没有适合匹配类似图中的运动规律的图像处理算法
  • ¥15 dnat基础问题,本机发出,别人返回的包,不能命中
  • ¥15 请各位帮我看看是哪里出了问题
  • ¥15 vs2019的js智能提示
  • ¥15 关于#开发语言#的问题:FDTD建模问题图中代码没有报错,但是模型却变透明了