Matlab,守恒定律的积分

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,例如质量密度

我想知道在matlab中是否有可靠的库或类似FEX的包来处理标量守恒定律(比如1D)

我目前正在处理一维非线性、非局部守恒定律,一阶格式的扩散误差正在折磨我,而且还遗漏了很多物理知识。因此,我想知道是否已经有了一些健壮的工具来避免自己编写一些代码(理想情况下,类似于C++中的模式无关的高阶ODE集成)

谢谢你的帮助

编辑:对不够清晰表示歉意。这里对于守恒定律,我指的是形式为

 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的东西吗?