Matlab,守恒定律的积分
我想知道在matlab中是否有可靠的库或类似FEX的包来处理标量守恒定律(比如1D) 我目前正在处理一维非线性、非局部守恒定律,一阶格式的扩散误差正在折磨我,而且还遗漏了很多物理知识。因此,我想知道是否已经有了一些健壮的工具来避免自己编写一些代码(理想情况下,类似于C++中的模式无关的高阶ODE集成) 谢谢你的帮助 编辑:对不够清晰表示歉意。这里对于守恒定律,我指的是形式为Matlab,守恒定律的积分,matlab,numerical-methods,conservation-laws,Matlab,Numerical Methods,Conservation Laws,我想知道在matlab中是否有可靠的库或类似FEX的包来处理标量守恒定律(比如1D) 我目前正在处理一维非线性、非局部守恒定律,一阶格式的扩散误差正在折磨我,而且还遗漏了很多物理知识。因此,我想知道是否已经有了一些健壮的工具来避免自己编写一些代码(理想情况下,类似于C++中的模式无关的高阶ODE集成) 谢谢你的帮助 编辑:对不够清晰表示歉意。这里对于守恒定律,我指的是形式为 u_t(t,x) + F_x(t,x) = 0 其中,u=u(t,x)是一个密集守恒变量(比如标量,1D,例如质量密度
u_t(t,x) + F_x(t,x) = 0
其中,u=u(t,x)
是一个密集守恒变量(比如标量,1D,例如质量密度,能量密度,…),而F=F(t,x)
是它的通量。因此,我对哈密顿系统的守恒性质(能量,电流…)不感兴趣(感谢@headmyshoulder的评论)
我引用了
boost::odeint
作为一个健壮的通用库的概念参考,该库解决了一个数学问题(ODE的集成)。因此,我正在寻找一些实现Godunov类型方法等的软件包。我目前正在研究冲击湍流模拟的新方法,并在MATLAB中进行大量代码测试/验证。不幸的是,我还没有找到一个通用的库来实现您希望的功能,但是一个基本的Godunov或MUSCL代码相对来说实现起来比较简单。本文对一些有用的方法有一个很好的概述:[1] Kurganov,Alexander和Eitan Tadmor(2000),非线性守恒定律和对流扩散方程的新的高分辨率中心格式,J.Comp。物理,160214-282 下面是那篇文章中的几个例子,用于在周期域上求解无粘Burgers方程的一维等间距网格。这些方法很容易推广到方程组、耗散(粘性)系统和高维系统,如[1]所述。这些方法依赖于以下功能: 通量项:
function f = flux(u)
%flux term for Burgers equation: F(u) = u^2/2;
f = u.^2/2;
Minmod功能:
function m = minmod(a,b)
%minmod function:
m = (sign(a)+sign(b))/2.*min(abs(a),abs(b));
function RHS = KTrhs(dx,u)
%%% Kurganov-Tadmor scheme
ux = minmod((u-circshift(u,[0 1]))/dx,(circshift(u,[0 -1])-u)/dx);
uplus = u-dx/2*ux;
uminus = circshift(u+dx/2*ux,[0 1]);
a = max(abs(rhodF(uminus)),abs(rhodF(uplus)));
RHS = -( flux(circshift(uplus,[0 -1]))+flux(circshift(uminus,[0 -1])) ...
-flux(uplus)-flux(uminus) )/(2*dx) ...
+( circshift(a,[0 -1]).*(circshift(uplus,[0 -1])-circshift(uminus,[0 -1])) ...
-a.*(uplus-uminus) )/(2*dx);
方法
Nessyahu-Tadmor方案:
二阶方案
function unew = step_u(dx,dt,u)
%%% Nessyahu-Tadmor scheme
ux = minmod((u-circshift(u,[0 1]))/dx,(circshift(u,[0 -1])-u)/dx);
f = flux(u);
fx = minmod((f-circshift(f,[0 1]))/dx,(circshift(f,[0 -1])-f)/dx);
umid = u-dt/2*fx;
fmid = flux(umid);
unew = (u + circshift(u,[0 -1]))/2 + (dx)/8*(ux-circshift(ux,[0 -1])) ...
-dt/dx*( circshift(fmid,[0 -1])-fmid );
该方法在xj+1/2网格点处计算新的u值,因此它还需要在每一步进行网格移动。主要功能应类似于:
clear all
% Set up grid
nx = 256;
xmin=0; xmax=2*pi;
x=linspace(xmin,xmax,nx);
dx = x(2)-x(1);
%initialize
u = exp(-4*(x-pi*1/2).^2)-exp(-4*(x-pi*3/2).^2);
%CFL number:
CFL = 0.25;
t = 0;
dt = CFL*dx/max(abs(u(:)));
while (t<2)
u = step_u(dx,dt,u);
x=x+dx/2;
% handle grid shifts
if x(end)>=xmax+dx
x(end)=0;
x=circshift(x,[0 1]);
u=circshift(u,[0 1]);
end
t = t+dt;
%plot
figure(1)
clf
plot(x,u,'k')
title(sprintf('time, t = %1.2f',t))
if ~exist('YY','var')
YY=ylim;
end
axis([xmin xmax YY])
drawnow
end
clear all
nx = 256;
xmin=0; xmax=2*pi;
x=linspace(xmin,xmax,nx);
dx = x(2)-x(1);
%initialize
u = exp(-4*(x-pi*1/2).^2)-exp(-4*(x-pi*3/2).^2);
%CFL number:
CFL = 0.25;
t = 0;
dt = CFL*dx/max(abs(u(:)));
while (t<3)
% 4th order Runge-Kutta time stepping
k1 = KTrhs(dx,u);
k2 = KTrhs(dx,u+dt/2*k1);
k3 = KTrhs(dx,u+dt/2*k2);
k4 = KTrhs(dx,u+dt*k3);
u = u+dt/6*(k1+2*k2+2*k3+k4);
t = t+dt;
%plot
figure(1)
clf
plot(x,u,'k')
title(sprintf('time, t = %1.2f',t))
if ~exist('YY','var')
YY=ylim;
end
axis([xmin xmax YY])
drawnow
end
该函数还依赖于知道F(u)的雅可比矩阵的光谱半径(上述代码中的rhodF
)。对于无粘性汉堡来说,这只是
function rho = rhodF(u)
dFdu=abs(u);
KT计划的主要计划可能是:
clear all
% Set up grid
nx = 256;
xmin=0; xmax=2*pi;
x=linspace(xmin,xmax,nx);
dx = x(2)-x(1);
%initialize
u = exp(-4*(x-pi*1/2).^2)-exp(-4*(x-pi*3/2).^2);
%CFL number:
CFL = 0.25;
t = 0;
dt = CFL*dx/max(abs(u(:)));
while (t<2)
u = step_u(dx,dt,u);
x=x+dx/2;
% handle grid shifts
if x(end)>=xmax+dx
x(end)=0;
x=circshift(x,[0 1]);
u=circshift(u,[0 1]);
end
t = t+dt;
%plot
figure(1)
clf
plot(x,u,'k')
title(sprintf('time, t = %1.2f',t))
if ~exist('YY','var')
YY=ylim;
end
axis([xmin xmax YY])
drawnow
end
clear all
nx = 256;
xmin=0; xmax=2*pi;
x=linspace(xmin,xmax,nx);
dx = x(2)-x(1);
%initialize
u = exp(-4*(x-pi*1/2).^2)-exp(-4*(x-pi*3/2).^2);
%CFL number:
CFL = 0.25;
t = 0;
dt = CFL*dx/max(abs(u(:)));
while (t<3)
% 4th order Runge-Kutta time stepping
k1 = KTrhs(dx,u);
k2 = KTrhs(dx,u+dt/2*k1);
k3 = KTrhs(dx,u+dt/2*k2);
k4 = KTrhs(dx,u+dt*k3);
u = u+dt/6*(k1+2*k2+2*k3+k4);
t = t+dt;
%plot
figure(1)
clf
plot(x,u,'k')
title(sprintf('time, t = %1.2f',t))
if ~exist('YY','var')
YY=ylim;
end
axis([xmin xmax YY])
drawnow
end
全部清除
nx=256;
xmin=0;xmax=2*pi;
x=linspace(xmin,xmax,nx);
dx=x(2)-x(1);
%初始化
u=exp(-4*(x-pi*1/2)。^2)-exp(-4*(x-pi*3/2)。^2);
%CFL编号:
CFL=0.25;
t=0;
dt=CFL*dx/max(abs(u)());
虽然(todeint有辛Runge-Kutta步进器。也许这对你很有用。它们至少在平均值和相空间体积上节约了能量。我还不清楚你指的是什么样的守恒定律。如果u是守恒的,你的ODE F_x=0。@headmyshoulder,我进一步改进了这个问题,谢谢你的评论。b我指的是一种等式。你考虑过类似openFOAM的东西吗?