如何在Matlab中的bvp4c求解器中包含分段定义的函数

时间:2016-05-17 20:26:43

标签: matlab ode piecewise

我在使用带有分段定义函数的bvp4c时遇到了麻烦。 我测试了代码,当分段定义的函数是常量时,它工作正常。 问题是我在分段定义的函数不是常数的区域中得到了错误的结果(我确切知道)。

有关如何处理此问题的任何想法或建议?

由于

    function bvp4
    xlow=0;
    xhigh=0.30;
    solinit=bvpinit(linspace(xlow,xhigh,1000),[0 0]);
    sol = bvp4c(@bvp4ode,@bvp4bc,solinit);
    xint=[xlow:0.0001:xhigh];
    Sxint=deval(sol,xint);
    Sxint1=abs(sqrt(Sxint));
    xint=[xlow:0.0001:xhigh];
    plot(xint,Sxint1(1,:),'r')

    function dydx = bvp4ode(x,y)
    So=0.00125;
    s=1.5;
    dydx = [y(2);    
        ((G(x)+125*f(x)*y(1)*(1+1/s^2)^0.5-1000*9.81*So*H(x))/(1000*0.5*l(x)*(f(x)/8)^0.5)-y(2)*2*(-2/3*x+0.071+2/3*0.08)*(-2/3)*b(x))/H(x)/H(x)];


    function res = bvp4bc(ya,yb)
    res = [ya(1);        yb(1)];



    function fval = f(x)
if     (x >= 0) && (x <= 0.08)
    fval = 0.0187;
elseif  (x > 0.08) && (x <= 0.17)
    fval = 0.0298;
elseif  (x > 0.17) && (x <= 0.3)
    fval= 0.0408;
end


function Gval = G(xint)
if     (xint >= 0) && (xint <= 0.08)
    Gval = 0.1306;
elseif  (xint > 0.08) && (xint <= 0.17)
    Gval = 0.1306;
elseif  (xint > 0.17) && (xint <= 0.3)
    Gval = -0.0337;
end

function Hval = H(xint)
if     (xint >= 0) && (xint < 0.08)
    Hval = 0.071;
elseif  (xint >= 0.08) && (xint <= 0.17)
    Hval = -2/3*xint+(0.071+2/3*0.08);
elseif  (xint >0.17) && (xint <= 0.3)
     Hval = 0.011;
end

function bval = b(xint)
if     (xint >= 0) && (xint < 0.08)
    bval = 0;
elseif  (xint >= 0.08) && (xint <= 0.17)
    bval = 1;
elseif  (xint > 0.17) && (xint <= 0.3)
    bval= 0;
end


function lval = l(xint)
if     (xint >= 0) && (xint <= 0.08)
    lval = 0.067;
elseif  (xint > 0.08) && (xint <= 0.17)
    lval = 0.134;
elseif  (xint > 0.17) && (xint <= 0.3)
    lval= 1.165;
end

1 个答案:

答案 0 :(得分:0)

你突然跳起来不会让你那个脆弱的解决者感到惊讶。

任何订单p解算器都期望ODE函数至少p次连续可微分,以明智地适应网格点的网格。本地步长。任何偏差都会导致奇点附近的过度和可能的振荡适应,导致步长的计算时间过长或下溢。

我看到两种可能解决这个问题,使用事件(如果支持BVP)来切换模型/ ODE函数或使用提供的multipoint mechanism将积分间隔分成参数函数不变的部分。然后,您还可以使用简单数组作为参数,而不是使用多个分支的函数。