偏微分方程数值解—ADI格式求解二维抛物型方程

偏微分的第4次实验,主要内容为二维抛物型方程的ADI格式求解。不足之处望读者多多指正。

实验内容

使用ADI格式求解以下问题:
∂ u ∂ t − ( ∂ 2 u ∂ x 2 + ∂ 2 u ∂ y 2 ) = − 3 2 e 1 2 ( x + y ) − t , 0 < x , y < 1 , 0 < t ⩽ 1 \frac{\partial u}{\partial t}-\left(\frac{\partial^{2} u}{\partial x^{2}}+\frac{\partial^{2} u}{\partial y^{2}}\right)=-\frac{3}{2} e^{\frac{1}{2}(x+y)-t}, \quad 0<x, y<1, \quad 0<t \leqslant 1 tu(x22u+y22u)=23e21(x+y)t,0<x,y<1,0<t1
u ( x , y , 0 ) = e 1 2 ( x + y ) , 0 < x , y < 1 u(x, y, 0)=e^{\frac{1}{2}(x+y)}, \quad 0<x, y<1 u(x,y,0)=e21(x+y),0<x,y<1
u ( 0 , y , t ) = e 1 2 y − t , u ( 1 , y , t ) = e 1 2 ( 1 + y ) − t , 0 ⩽ y ⩽ 1 , 0 ⩽ t ⩽ 1 u(0, y, t)=e^{\frac{1}{2} y-t}, \quad u(1, y, t)=e^{\frac{1}{2}(1+y)-t}, \quad 0 \leqslant y \leqslant 1, \quad 0 \leqslant t \leqslant 1 u(0,y,t)=e21yt,u(1,y,t)=e21(1+y)t,0y1,0t1
u ( x , 0 , t ) = e 1 2 x − t , u ( x , 1 , t ) = e 1 2 ( 1 + x ) − t , 0 < x < 1 , 0 ⩽ t ⩽ 1 u(x, 0, t)=e^{\frac{1}{2} x-t}, \quad u(x, 1, t)=e^{\frac{1}{2}(1+x)-t}, \quad 0<x<1, \quad 0 \leqslant t \leqslant 1 u(x,0,t)=e21xt,u(x,1,t)=e21(1+x)t,0<x<1,0t1
该问题的精确解为: u ( x , y , t ) = e 1 2 ( x + y ) − t u(x, y, t)=e^{\frac{1}{2}(x+y)-t} u(x,y,t)=e21(x+y)t

算法原理(偷懒贴图)

在这里插入图片描述

从第K层过渡到K+1/2层

在这里插入图片描述
在这里插入图片描述

从第K+1/2过渡到第K+1层

在这里插入图片描述

在这里插入图片描述

算法实现思想

结合上述算法思想,实现思路如下:
(1)分别给出空间区间数M,与时间间隔数N,得到空间步长h与时间步长c;
(2)构建矩阵A1、A2、A3、A4,令k=1;
(3)判断k是否等于N+1,若相等执行步骤(4)、(5),反之执行步骤(6);
(4)构建U(k)、F(k+1/2)并求解出中间层U(k+1/2);
(5)构建F(k+1),求解U(K+1),将求解结果写入三维数组U3,k=k+1,并返回步骤(3);
(6)输出U3,程序结束。

Matlab实现

ADI格式实现尝试

function U3 = ADI(M,N,h,c,x,y,t)
%***************************************************************
% 求解二维抛物型奇次方程 ut=uxx+uyy;
% 0≤x≤1 ,0≤y≤1 , 0≤t≤T;
% 该问题的定解: u(x,y,t)=exp( 1/2(x+y)-t);
% 初值条件: u(x,y,0)=exp( 1/2(x+y) );
% 边值条件: u(0,y,t)=exp( 1/2*(y)-t ); u(1,y,t)=exp( 1/2*(1+y)-t );
%  u(x,0,t)=exp( 1/2*x-t ); u(x,1,t)=exp( 1/2*(x+1)-t );
%***************************************************************
r=c./h^2;  
%构造B1
bb1=zeros(1,M-1);                          %给主对角线位置赋值.
for i=1:M-1
    bb1(i)=1+r;
end
B1=diag(bb1); 
%构造C1
cc1=zeros(1,M-1);                          %给主对角线位置赋值.
for i=1:M-1
    cc1(i)=-r./2;
end
C1=diag(cc1); 
%***************************************************************
%构造A1
aa1=blkdiag(kron(eye(M-1),B1));             %创建主对角矩阵块
mid=mat2cell(aa1,(M-1)*ones(1,M-1),(M-1)*ones(1,M-1));
mid(find(diag(ones(1,M-2),1)==1))={
    
    C1};     %创建上对角矩阵块
mid(find(diag(ones(1,M-2),-1)==1))={
    
    C1};    %创建下对角矩阵块
A1=cell2mat(mid);                        
%***************************************************************
%构造B2
bb1=zeros(1,M-2);                     
for i=1:M-2                            %-1,1对角线位置赋值.
    bb1(i)=r./2;
end
bb2=zeros(1,M-1);                          %给主对角线位置赋值.
for i=1:M-1
    bb2(i)=1-r;
end
B2=diag(bb1,-1)+diag(bb2)+diag(bb1,1);    
%***************************************************************
%构造A2
aa2=blkdiag(kron(eye(M-1),B2));           %创建主对角矩阵块
mid=mat2cell(aa2,(M-1)*ones(1,M-1),(M-1)*ones(1,M-1));
A2=cell2mat(mid);                        
%***************************************************************
%构造B3
bb4=zeros(1,M-2);                     
for i=1:M-2                            %-1,1对角线位置赋值.
    bb4(i)=-r./2;
end
bb5=zeros(1,M-1);                       %给主对角线位置赋值.
for i=1:M-1
    bb5(i)=1+r;
end
B3=diag(bb4,-1)+diag(bb5)+diag(bb4,1);    
%***************************************************************
%构造A3
aa3=blkdiag(kron(eye(M-1),B3));           %创建主对角矩阵块
mid=mat2cell(aa3,(M-1)*ones(1,M-1),(M-1)*ones(1,M-1));
A3=cell2mat(mid);        
%***************************************************************
%构造B4
bb6=zeros(1,M-1);                          %给主对角线位置赋值.
for i=1:M-1
    bb6(i)=1-r;
end
B4=diag(bb6);
%***************************************************************
%构造C4
cc=zeros(1,M-1);                          %给主对角线位置赋值.
for i=1:M-1
    cc(i)=r./2;
end
C4=diag(cc);
%***************************************************************
%构造A4
aa4=blkdiag(kron(eye(M-1),B4));             %创建主对角矩阵块
mid=mat2cell(aa4,(M-1)*ones(1,M-1),(M-1)*ones(1,M-1));
mid(find(diag(ones(1,M-2),1)==1))={
    
    C4};     %创建上对角矩阵块
mid(find(diag(ones(1,M-2),-1)==1))={
    
    C4};    %创建下对角矩阵块
A4=cell2mat(mid);
%***************************************************************
%Fk+1/2, 先构造f1
ff1=zeros(1,M-2);                     
for i=1:M-2                            %-1,1对角线位置赋值.
    ff1(i)=r./4;
end
ff2=zeros(1,M-1);                        %给主对角线位置赋值.
for i=1:M-1
    ff2(i)=(1-r)./2;
end
f1=diag(ff1,-1)+diag(ff2)+diag(ff1,1);    
%***************************************************************
%再构造f2
ff1=zeros(1,M-2);                     
for i=1:M-2                            %-1,1对角线位置赋值.
    ff1(i)=-r./4;
end
ff2=zeros(1,M-1);                          %给主对角线位置赋值.
for i=1:M-1
    ff2(i)=(1+r)./2;
end
f2=diag(ff1,-1)+diag(ff2)+diag(ff1,1);    
%***************************************************************
U0=zeros((M-1)*(M-1),1);
count1=1;%记录第0层总个数
% 初值条件如下,给第0层赋值
for i=1:M-1    %不包括边界值
    for j=1:M-1
       U0(count1,1)=exp(0.5*(x(i+1)+y(j+1))-t(1));
       count1=count1+1;
    end
end
%***************************************************************
%先求k+1/2层
k=1;%记录行数
FF1=zeros(M-1,1);
FF2=zeros(M-1,1);
uk=zeros(M-1,1);%u(0,j,k)|u(M,j,k)
uk1=zeros(M-1,1);%u(0,j,k+1)|u(M,j,k+1)
uk_1=zeros(M-1,1);%u(0,0/M,k)|u(M,0/M,k)
uk1_1=zeros(M-1,1);%u(0,0/M,k+1)|u(M,0/M,k+1)
F1=zeros((M-1)*(M-1),1);
while k~=N+1
%***************************************************************
%构造F(k+1/2)
%FF1
for i=1:M-1
    uk(i,1)=exp(0.5*(y(i+1)-t(k)));
    uk1(i,1)=exp(0.5*(y(i+1)-t(k+1)));
end
uk_1(1,1)=exp(1*t(k));
uk_1(M-1,1)=exp(0.5-t(k));
uk1_1(1,1)=exp(t(k+1));
uk1_1(M-1,1)=exp(0.5+t(k+1));
FF1=f1*uk+r./4*uk_1+f2*uk1-r./4*uk1_1;
%***************************************************************
%FF2
for i=1:M-1
    uk(i,1)=exp(0.5*(1+y(i+1)+t(k)));
    uk1(i,1)=exp(0.5*(1+y(i+1)+t(k+1)));
end
uk_1(1,1)=exp(0.5+t(k));
uk_1(M-1,1)=exp(1+t(k));
uk1_1(1,1)=exp(0.5+t(k+1));
uk1_1(M-1,1)=exp(1+t(k+1));
FF2=f1*uk+r./4*uk_1+f2*uk1-r./4*uk1_1;
% 在下面把FF1全部赋给F1即F(k+1/2)向量的前M-1for j=1:M-1    
 F1(j,1)=FF1(j,1);
end
% 在下面把FF2全部赋给F1即F(k+1/2)向量的最后的M-1项
pp=1;
for j=(M-1)*(M-2)+1:(M-1)*(M-1)
 F1(j,1)=FF2(pp,1);  %Fk+1/2
 pp=pp+1;
end
%***************************************************************
% 构造F(k)
F=zeros((M-1)*(M-1),1);%Fk
c=1;
for j=1:M-1
    F(c,1)=exp(0.5*(x(j+1)+t(k)));
    F(c+M-2,1)=exp(0.5*(1+x(j+1)+t(k)));
    c=c+M-1;
end
f=A2*U0+0.5.*r*F1+0.5.*r*F;
U1=A1\f;      %U1为第一阶段利用U(k)所求的U(k+1/2);
%***************************************************************
 
% 继续往下求解, 利用U(k+1/2)求的U(k+1), 此为第二阶段
% U(k+1/2)已存放到U1中, F(k+1/2)已存放到F1之中, 在第二阶段需要使用两者;
ff6=zeros((M-1)*(M-1),1); %Fk+1
% ff6为所需要的F(k+1);
c=1;
for j=1:M-1
    ff6(c,1)=exp(0.5*(x(j+1)+t(k+1)));
    ff6(c+M-2,1)=exp(0.5*(1+x(j+1)+t(k+1)));
    c=c+M-1;
end
FF=A4*U1+0.5*r*(ff6+F1);
U=A3\FF;
%***************************************************************
% U为所求的U(k+1)
U0=U; %U(k+1)作为下一次迭代的初值条件
U=reshape(U,M-1,M-1);
for i=2:M
    for j=2:M
       U3(i,j,k)=U(i-1,j-1); 
    end
end
for i=1:M+1
 U3(i,1,k)=exp(0.5*(x(i))-t(k+1));  %左边界
 U3(i,M+1,k)=exp(0.5*(1+x(i))-t(k+1)); %右边界
end
 
for i=1:M+1
 U3(1,i,k)=exp(0.5*(y(i)-t(k+1)));  %上边界
 U3(M+1,i,k)=exp(0.5*(1+y(i))-t(k+1)); %下边界
end
 
k=k+1;  %进入下一层
end


调用的主函数

主要实现:完成迭代矩阵U3与解析解矩阵U4的实现,主要实现图像拟合、与误差分析

求解结果(目标)

拟合图像

在这里插入图片描述

动态实现尝试

  • 这里的动态实现与实验的不一样,实现思路主要来自b站的网课
    在这里插入图片描述

实验总结

完成了matlab拟合与可视化的部分,误差分析并计算误差阶有待下篇文章完成。

参考

物理老师的热传导课

猜你喜欢

转载自blog.csdn.net/Zengmeng1998/article/details/109613175