【问题标题】:How can i estimate kinitic parameter of a steady-state reactor我如何估计稳态反应堆的动力学参数
【发布时间】:2018-11-06 22:39:16
【问题描述】:

我想求解一个参数未知的ODE系统k1,k2,k3

dC1/dx=-k1*C1
dC2/dx=k1*C1-k2*C2
dC3/dx=k2*C2-k3*C3

我有一组实验结果,C1,C2,C3 的值在x=0(入口点)和x=1(终点)。

我在x=0x=1 之间没有任何数据来使用像ode45()ode23() 这样的ODE 函数来解决它,然后使用优化函数。如何在 MATLAB 中解决这个问题?

【问题讨论】:

    标签: matlab optimization model curve-fitting ode


    【解决方案1】:

    您可以尝试使用边界值求解器bvp4c(或bvp5c)。可以满足的边界条件的数量是 ODE 的维数和未知参数的数量之和,因此您希望将参数固定为 6 个已知值的 6 个可能条件。也就是说,传递给求解器的函数是

    function dCdx = odesys(x,C,k)
        dCdx = zeros_like(C)
        dCdx(1) = -k(1)*C(1)
        dCdx(2) =  k(1)*C(1)-k(2)*C(2)
        dCdx(3) =  k(2)*C(2)-k(3)*C(3)
    
    function bc = boundary(C0, CT, k)
        bc = [ C0(1)-c01, C0(2)-c02, C0(3)-c03, CT(1)-cT1, CT(2)-cT2, CT(3)-cT3 ]
    

    作为初始猜测,您可以使用已知值之间的一些线性插值。


    关于提供边界值的修改系统

    dC1/dx=-k1*C1/(1+k1*C1) ; 
    dC2/dx=k1*C1/(1+k1*C1)-k2*C2 ; 
    dC3/dx=k2*C2-k3*C3 ; 
    

    在脚本中使用类似的 python 求解器(但将 x1 更改为 100

    c0A, c0B, c0C = 293.3 , 2.1414, 3.6884
    c1A, c1B, c1C = 208.09, 33.823, 78.561 
    x0, x1 = 0.0, 100.0
    
    def odesys(x,C,k):
        dCdx = zeros_like(C)
        dCdx[0] = -k[0]*C[0]/(1+k[0]*C[0]) ;
        dCdx[1] =  k[0]*C[0]/(1+k[0]*C[0])-k[1]*C[1]
        dCdx[2] =  k[1]*C[1]-k[2]*C[2]
        return dCdx
    
    def bc(C0, C1, k):
        return [ C0[0]-c0A, C0[1]-c0B, C0[2]-c0C, C1[0]-c1A, C1[1]-c1B, C1[2]-c1C ]
    
    x_init = linspace(x0,x1,21)
    s = (x_init-x0)/(x1-x0)
    C_init = [ c0A+s*(c1A-c0A), c0B+s*(c1B-c0B), c0C+s*(c1C-c0C)]
    
    k = [1.0e-2, 1.0, 1.0]
    
    res = solve_bvp(odesys, bc, x_init, C_init, k)
    print res.message, res.p
    

    它将参数[ k1, k2, k3]的结果打印为

    The algorithm converged to the desired accuracy. 
    [ 0.02319266  0.02248122 -0.00678455]
    

    第三个参数是非物理负数,暗示模型或某些参数不正确。此外,绘制解决方案:

    x_sol=np.linspace(x0,x1,301)    
    C_sol=res.sol(x_sol)
    for k in range(3): plt.subplot(1,3,k+1); plt.plot(x_sol, C_sol[k]); plt.grid()
    plt.show()
    

    似乎显示了正确的行为。使用这些参数与另一种积分方法进行前向积分可以确认解决方案的正确性

    C_int = odeint( lambda C,t: odesys(t,C,res.p), res.sol(0), x_sol)
    for k in range(3): plt.subplot(1,3,k+1); plt.plot(x_sol, C_int[:,k]); plt.grid()
    plt.show()
    

    【讨论】:

    • 非常感谢您的帮助。我正在尝试在 matlab 中应用您的方法。这种方法可以用于非线性微分方程吗?例如,如果我们有 dCdx=-k1*C1/(1+k1*c1) 而不是 dCdx=-k1*c1 这个函数是否可以应用???
    • 数据与这个方程不兼容。 C1 的斜率以 (-1,0] 为界,在区间 [0,1] 上减少小于 1。减少超过 85 是不可能的。如果区间达到 100,它可能会起作用。
    • 我不懂python。如何将此代码转换为 matlab 脚本??
    • 这些是实验数据,应该是正确的。我想为 kinitic 参数找到一个被动值。如果这些值变为负值,则没有任何意义。我们必须考虑参数的正向约束以获得真实值
    • 正如我所说,那么模型太死板或不完整。但要讨论这个问题,您需要就模型的内容提供更多输入。还可以制作一个更通用的适应度函数,它采用参数k 并返回端点到给定端点的距离之和。然后您可以使用通用优化求解器进行调用。
    【解决方案2】:

    这是一个由 3 个常微分方程组成的系统问题。在x=0x=1 处的C1C2C3 的值是初始条件。您可以使用dsolve 解析解决它。在我的示例中,我假设初始条件为C1(0)=1; C2(0)=1; C3(1)=1;。您可以根据自己的数据进行修改。

    syms C1(x) C2(x) C3(x) k1 k2 k3
    
    % Define the equations using == and represent differentiation using the diff function.
    ode1 = diff(C1) == -k1*C1;
    ode2 = diff(C2) == k1*C1-k2*C2;
    ode3 = diff(C3) == k2*C2-k3*C3;
    odes = [ode1; ode2; ode3]
    
    % Define the initial conditions using ==
    cond1 = C1(0) == 1;
    cond2 = C2(0) == 1;
    cond3 = C3(1) == 1;
    conds = [cond1; cond2; cond3];
    
    % dsolve function finds values for the constants that satisfy these conditions.
    [C1Sol(x) C2Sol(x) C3Sol(x)] = dsolve(odes, conds)
    

    输出

    odes(x) =
    
               D(C1)(x) == -k1*C1(x)
     D(C2)(x) == k1*C1(x) - k2*C2(x)
     D(C3)(x) == k2*C2(x) - k3*C3(x)
    
    
    C1Sol(x) =
    
    exp(-k1*x)
    
    
    C2Sol(x) =
    
    -(exp(-k1*x)*exp(-k2*x)*((k1^2*k2*exp(k2*x))/((k1 - k2)*(k1 - k3)) - (k2^2*exp(k1*x)*(2*k1 - k2))/((k1 - k2)*(k2 - k3)) - (k1*k2*k3*exp(k2*x))/((k1 - k2)*(k1 - k3)) + (k2*k3*exp(k1*x)*(2*k1 - k2))/((k1 - k2)*(k2 - k3))))/k2
    
    
    C3Sol(x) =
    
    -exp(-k1*x)*exp(-k2*x)*exp(-k3*x)*((k2*exp(k1*x)*exp(k3*x)*(2*k1 - k2))/((k1 - k2)*(k2 - k3)) - (k1*k2*exp(k2*x)*exp(k3*x))/((k1 - k2)*(k1 - k3)) + (exp(k1*x)*exp(k2*x)*exp(k3)*(k1*k2^2 - k1^2*k2 - k1*k3^2 + k1^2*k3 + k2*k3^2 - k2^2*k3 + k1*k2^2*exp(-k1) + k1*k2^2*exp(-k2) - 2*k1^2*k2*exp(-k2) - k2^2*k3*exp(-k2) - k1*k2*k3*exp(-k1) + 2*k1*k2*k3*exp(-k2)))/((k1 - k2)*(k1 - k3)*(k2 - k3)))
    

    【讨论】:

    • 非常感谢您的帮助。首先,我在入口和出口处的每种化合物都有 4 个数据,而不仅仅是一个。这仅适用于一项实验。其次,我需要一个数值解,因为我的方程会有更多的参数(这里我只放了 3 个未知数。
    猜你喜欢
    • 1970-01-01
    • 2021-07-02
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多