Matlab,保护法的整合

时间:2013-01-10 17:58:48

标签: matlab numerical-methods conservation-laws

我想知道是否有成熟的强大库或类似FEX的软件包来处理matlab中的标量守恒定律(比如1D)。

我目前正在处理一维非线性,非局部,守恒定律,一阶方案的扩散误差正在扼杀我,而且很多物理学都被遗漏了。因此,我想知道是否已经存在一些强大的工具,以避免自己编写一些代码(理想情况下,类似于boost::odeint,用于C ++中与方案无关的高阶ODE集成)。

任何帮助表示感谢。

编辑:对于缺乏清晰度表示道歉。这里的守恒定律是指形式为

的一般的hyberbolic偏导数方程
 u_t(t,x) + F_x(t,x) = 0

其中u=u(t,x)是一个密集的守恒变量(比如标量,1D,例如质量密度,能量密度......),而F = F(t,x)是它的通量。因此,我对汉密尔顿系统特征(能量,电流......)的保护特性并不感兴趣(感谢@headmyshoulder的评论)。

我引用boost::odeint来概述一个强大的通用库来解决数学问题(ODE的集成)。因此,我正在寻找一些实现Godunov类型方法的包等等。

1 个答案:

答案 0 :(得分:3)

我目前正致力于冲击 - 湍流模拟的新方法,并在MATLAB中进行大量的代码测试/验证。不幸的是,我还没有找到一个能够做你所希望的通用库,但基本的Godunov或MUSCL代码实现起来相对简单。本文对一些有用的方法有很好的概述:
[1] Kurganov,Alexander和Eitan Tadmor(2000),非线性守恒定律和对流 - 扩散方程的新的高分辨率中心方案, J.比较。 Phys。,160,214-282。 PDF

以下是该论文的一些例子,用于解决非粘性Burgers方程的周期域上的1D等间距网格。这些方法很容易推广到方程组,耗散(粘性)系统和更高维度,如[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));

方法

Nessyahu-Tadmor计划:

A nd 订单方案

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 );

此方法计算x j + 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

Kurganov-Tadmor计划

[1]的Kurganov-Tadmor方案比NT方案有几个优点,包括较低的数值耗散和半离散形式,允许使用您选择的任何时间积分方法。使用与上述相同的空间离散化,可以将其表示为du / dt =(stuff)的ODE。该ODE的右侧可以通过函数计算:

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);

此函数还依赖于知道F(u)的雅可比行列式的谱半径(上面代码中的rhodF)。对于无粘性汉堡,这只是

function rho = rhodF(u)
dFdu=abs(u);

KT计划的主要计划可能是:

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