MATLAB 使用 ode45 为波函数设置动画会引发公差错误
MATLAB using ode45 to animate wave function throws tolerance error
我正在 MATLAB 中制作波函数的动画。到目前为止,我还没有接触到动画的一部分,因为我的 ode45 抛出了一个错误。我为此使用了 de Korteweg-de Vries 方程
(可以在这里找到:https://en.wikipedia.org/wiki/Korteweg%E2%80%93de_Vries_equation)。
现在我的代码如下:
function[t, N, u] = wave(u0, L, T, S, N)
%First we create a vector t which stores the time entries, a vector x which
%stores the location entries and an h which is the location step size for
%the Korteweg-De Vries function.
time = linspace(0,T,S);
x = linspace(-L,L,N);
h = x(2)-x(1);
U0=u0(x);
options=odeset('RelTol',1e-13,'AbsTol',1e-13);
[t,u] = ode45(@kdv,time,U0,options);
function dudt = kdv(t,u)
d2udx2 = ([u(N)-2*u(1)+u(2); diff(u,2); u(N-1)-2*u(N)+u(1)] ./ h^2);
total = d2udx2 + 3.*u.^2;
diff_total = diff(total);
diff_total = [diff_total(end); diff_total(1:end)];
dudt = -[diff_total(2)-diff_total(N-1); diff(diff_total,2); diff_total(N-1)+diff_total(2)] ./ (2*h);
end
end
现在,当我设置 f=@(x)(2/2).*(1./cosh(sqrt(2).*x./2).^2)
,然后使用 [t,N,u]=wave(f, 20, 10, 200, 200);
调用函数时,出现以下错误:
Warning: Failure at t=6.520003e-02. Unable to meet integration tolerances without reducing the step size below the
smallest value allowed (2.220446e-16) at time t.
In ode45 (line 360)
In wave (line 23)
此外,返回的 t
和 u
的大小分别为 16x1
和 16x200
,但我认为它们会扩展为 200x1
和 200x200
如果没有出现警告。
任何有关如何解决此问题的提示都将不胜感激。
你做的太多了,中间的构建步骤diff_total
是多余的
d2udx2
因此 total
构造正确。您可以将第一个构造缩短为
d2udx2 = diff([u(N); u; u(1) ], 2)./h^2`;
下一步构造diff_total
与dudt
中的差异构造是多余的。 diff_total
构造缺少 h
的除法,由于某些未知原因,您在 dudt
.
中间有差阶 2
外部 x
微分最好通过卷积完成,以获得中心差商,就像在外部元素中一样,
dudt = -conv([ total(N); total; total(1)], [1; 0; -1], 'valid')/(2*h)
总的来说就是求导过程
function dudt = kdv(t,u,h)
d2udx2 = diff([u(end); u; u(1) ], 2)./h^2;
total = d2udx2 + 3*u.^2;
dudt = -conv( [ total(end); total; total(1)], [1; 0; -1], 'valid')./(2*h);
end
其中(N=80
)产生了解决方案
这是一个以 c=2
.
速度传播的孤子波
我正在 MATLAB 中制作波函数的动画。到目前为止,我还没有接触到动画的一部分,因为我的 ode45 抛出了一个错误。我为此使用了 de Korteweg-de Vries 方程 (可以在这里找到:https://en.wikipedia.org/wiki/Korteweg%E2%80%93de_Vries_equation)。
现在我的代码如下:
function[t, N, u] = wave(u0, L, T, S, N)
%First we create a vector t which stores the time entries, a vector x which
%stores the location entries and an h which is the location step size for
%the Korteweg-De Vries function.
time = linspace(0,T,S);
x = linspace(-L,L,N);
h = x(2)-x(1);
U0=u0(x);
options=odeset('RelTol',1e-13,'AbsTol',1e-13);
[t,u] = ode45(@kdv,time,U0,options);
function dudt = kdv(t,u)
d2udx2 = ([u(N)-2*u(1)+u(2); diff(u,2); u(N-1)-2*u(N)+u(1)] ./ h^2);
total = d2udx2 + 3.*u.^2;
diff_total = diff(total);
diff_total = [diff_total(end); diff_total(1:end)];
dudt = -[diff_total(2)-diff_total(N-1); diff(diff_total,2); diff_total(N-1)+diff_total(2)] ./ (2*h);
end
end
现在,当我设置 f=@(x)(2/2).*(1./cosh(sqrt(2).*x./2).^2)
,然后使用 [t,N,u]=wave(f, 20, 10, 200, 200);
调用函数时,出现以下错误:
Warning: Failure at t=6.520003e-02. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (2.220446e-16) at time t. In ode45 (line 360) In wave (line 23)
此外,返回的 t
和 u
的大小分别为 16x1
和 16x200
,但我认为它们会扩展为 200x1
和 200x200
如果没有出现警告。
任何有关如何解决此问题的提示都将不胜感激。
你做的太多了,中间的构建步骤diff_total
是多余的
d2udx2
因此total
构造正确。您可以将第一个构造缩短为d2udx2 = diff([u(N); u; u(1) ], 2)./h^2`;
下一步构造
diff_total
与dudt
中的差异构造是多余的。diff_total
构造缺少h
的除法,由于某些未知原因,您在dudt
. 中间有差阶 2
外部
x
微分最好通过卷积完成,以获得中心差商,就像在外部元素中一样,dudt = -conv([ total(N); total; total(1)], [1; 0; -1], 'valid')/(2*h)
总的来说就是求导过程
function dudt = kdv(t,u,h)
d2udx2 = diff([u(end); u; u(1) ], 2)./h^2;
total = d2udx2 + 3*u.^2;
dudt = -conv( [ total(end); total; total(1)], [1; 0; -1], 'valid')./(2*h);
end
其中(N=80
)产生了解决方案
这是一个以 c=2
.