使用 MATLAB 的 pdepe 的(非)耦合 PDE 的奇怪错误结果,时间加倍
Strange wrong result for (un)coupled PDEs using MATLAB's pdepe, time is doubled
我正在尝试使用 pdpe 求解 1d 中的两个耦合反应扩散方程,即
$\partial_t u_1 = \nabla^2 u_1 + 2k(-u_1^2+u_2)$
$\partial_t u_2 = \nabla^2 u_1 + k(u_1^2-u_2)$
解在 $x\in[0,1]$ 域中,初始条件是两个以 $x=1/2$ 为中心的相同高斯分布。边界条件对两个分量都是吸收的,即 $u_1(0)=u_2(0)=u_1(1)=u_2(1)=0$。
pdepe给了我一个解决方案,没有提示任何错误。但是,我认为解决方案一定是错误的,因为当我将耦合设置为零时,即 $k=0$(并且如果我将其设置得非常小,比如 $k=0.001$),解决方案并不重合用简单扩散方程的解
$\partial_t u = \nabla^2 u$
从 pdepe 本身获得。
奇怪的是,耦合设置为零的 "coupled" 案例中的解 $u_1(t)=u_2(t)$ 以及非耦合案例的解如果我们设置 $t'=2t$,则通过构造 $u(t')$ 重合,也就是说,"coupled" 情况的解的演化速度是非耦合情况的解的两倍。
这是一个最小的工作示例:
偶联案例
function [xmesh,tspan,sol] = coupled(k) %argument is the coupling k
std=0.001; %width of initial gaussian
center=1/2; %center of gaussian
xmesh=linspace(0,1,10000);
tspan=linspace(0,1,1000);
sol = pdepe(0,@pdefun,@icfun,@bcfun,xmesh,tspan);
function [c,f,s] = pdefun(x,t,u,dudx)
c=ones(2,1);
f=zeros(2,1);
f(1) = dudx(1);
f(2) = dudx(2);
s=zeros(2,1);
s(1) = 2*k*(u(2)-u(1)^2);
s(2) = k*(u(1)^2-u(2));
end
function u0 = icfun(x)
u0=ones(2,1);
u0(1) = exp(-(x-center)^2/(2*std^2))/(sqrt(2*pi)*std);
u0(2) = exp(-(x-center)^2/(2*std^2))/(sqrt(2*pi)*std);
end
function [pL,qL,pR,qR] = bcfun(xL,uL,xR,uR,t)
pL=zeros(2,1);
pL(1) = uL(1);
pL(2) = uL(2);
pR=zeros(2,1);
pR(1) = uR(1);
pR(2) = uR(2);
qL = [0 0;0 0];
qR = [0 0;0 0];
end
end
非耦合案例
function [xmesh,tspan,sol] = uncoupled()
std=0.001; %width of initial gaussian
center=1/2; %center of gaussian
xmesh=linspace(0,1,10000);
tspan=linspace(0,1,1000);
sol = pdepe(0,@pdefun,@icfun,@bcfun,xmesh,tspan);
function [c,f,s] = pdefun(x,t,u,dudx)
c=1;
f = dudx;
s=0;
end
function u0 = icfun(x)
u0=exp(-(x-center)^2/(2*std^2))/(sqrt(2*pi)*std);
end
function [pL,qL,pR,qR] = bcfun(xL,uL,xR,uR,t)
pL=uL;
pR=uR;
qL = 0;
qR = 0;
end
end
现在,假设我们 运行
[xmesh,tspan,soluncoupled] = uncoupled();
[xmesh,tspan,solcoupled] = coupled(0); %coupling k=0, i.e. uncoupled solutions
可以通过绘制任何时间索引 $it$ 的解来直接检查,即使它们应该相同,每个函数给出的解也不相同,例如
hold all
plot(xmesh,soluncoupled(it+1,:),'b')
plot(xmesh,solcoupled(it+1,:,1),'r')
plot(xmesh,solcoupled(it+1,:,2),'g')
另一方面,如果我们将非耦合解的时间加倍,则解是相同的
hold all
plot(xmesh,soluncoupled(2*it+1,:),'b')
plot(xmesh,solcoupled(it+1,:,1),'r')
plot(xmesh,solcoupled(it+1,:,2),'g')
情况$k=0$不是奇异的,可以将$k$设置得小但有限,与情况$k=0$的偏差最小,即解仍然快一倍作为非耦合解决方案。
我真的不明白这是怎么回事。我需要处理耦合情况,但如果 $k\to 0$ 时它没有给出正确的限制,我显然不相信结果。我不明白我可能在哪里犯错。会不会是bug?
我正在尝试使用 pdpe 求解 1d 中的两个耦合反应扩散方程,即
$\partial_t u_1 = \nabla^2 u_1 + 2k(-u_1^2+u_2)$
$\partial_t u_2 = \nabla^2 u_1 + k(u_1^2-u_2)$
解在 $x\in[0,1]$ 域中,初始条件是两个以 $x=1/2$ 为中心的相同高斯分布。边界条件对两个分量都是吸收的,即 $u_1(0)=u_2(0)=u_1(1)=u_2(1)=0$。
pdepe给了我一个解决方案,没有提示任何错误。但是,我认为解决方案一定是错误的,因为当我将耦合设置为零时,即 $k=0$(并且如果我将其设置得非常小,比如 $k=0.001$),解决方案并不重合用简单扩散方程的解
$\partial_t u = \nabla^2 u$
从 pdepe 本身获得。
奇怪的是,耦合设置为零的 "coupled" 案例中的解 $u_1(t)=u_2(t)$ 以及非耦合案例的解如果我们设置 $t'=2t$,则通过构造 $u(t')$ 重合,也就是说,"coupled" 情况的解的演化速度是非耦合情况的解的两倍。
这是一个最小的工作示例:
偶联案例
function [xmesh,tspan,sol] = coupled(k) %argument is the coupling k
std=0.001; %width of initial gaussian
center=1/2; %center of gaussian
xmesh=linspace(0,1,10000);
tspan=linspace(0,1,1000);
sol = pdepe(0,@pdefun,@icfun,@bcfun,xmesh,tspan);
function [c,f,s] = pdefun(x,t,u,dudx)
c=ones(2,1);
f=zeros(2,1);
f(1) = dudx(1);
f(2) = dudx(2);
s=zeros(2,1);
s(1) = 2*k*(u(2)-u(1)^2);
s(2) = k*(u(1)^2-u(2));
end
function u0 = icfun(x)
u0=ones(2,1);
u0(1) = exp(-(x-center)^2/(2*std^2))/(sqrt(2*pi)*std);
u0(2) = exp(-(x-center)^2/(2*std^2))/(sqrt(2*pi)*std);
end
function [pL,qL,pR,qR] = bcfun(xL,uL,xR,uR,t)
pL=zeros(2,1);
pL(1) = uL(1);
pL(2) = uL(2);
pR=zeros(2,1);
pR(1) = uR(1);
pR(2) = uR(2);
qL = [0 0;0 0];
qR = [0 0;0 0];
end
end
非耦合案例
function [xmesh,tspan,sol] = uncoupled()
std=0.001; %width of initial gaussian
center=1/2; %center of gaussian
xmesh=linspace(0,1,10000);
tspan=linspace(0,1,1000);
sol = pdepe(0,@pdefun,@icfun,@bcfun,xmesh,tspan);
function [c,f,s] = pdefun(x,t,u,dudx)
c=1;
f = dudx;
s=0;
end
function u0 = icfun(x)
u0=exp(-(x-center)^2/(2*std^2))/(sqrt(2*pi)*std);
end
function [pL,qL,pR,qR] = bcfun(xL,uL,xR,uR,t)
pL=uL;
pR=uR;
qL = 0;
qR = 0;
end
end
现在,假设我们 运行
[xmesh,tspan,soluncoupled] = uncoupled();
[xmesh,tspan,solcoupled] = coupled(0); %coupling k=0, i.e. uncoupled solutions
可以通过绘制任何时间索引 $it$ 的解来直接检查,即使它们应该相同,每个函数给出的解也不相同,例如
hold all
plot(xmesh,soluncoupled(it+1,:),'b')
plot(xmesh,solcoupled(it+1,:,1),'r')
plot(xmesh,solcoupled(it+1,:,2),'g')
另一方面,如果我们将非耦合解的时间加倍,则解是相同的
hold all
plot(xmesh,soluncoupled(2*it+1,:),'b')
plot(xmesh,solcoupled(it+1,:,1),'r')
plot(xmesh,solcoupled(it+1,:,2),'g')
情况$k=0$不是奇异的,可以将$k$设置得小但有限,与情况$k=0$的偏差最小,即解仍然快一倍作为非耦合解决方案。
我真的不明白这是怎么回事。我需要处理耦合情况,但如果 $k\to 0$ 时它没有给出正确的限制,我显然不相信结果。我不明白我可能在哪里犯错。会不会是bug?