Вы можете попробовать использовать решатель граничных значений 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 ;
![enter image description here](https://i.stack.imgur.com/lrgeX.jpg)
с использованием аналогичного решателя 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()
![enter image description here](https://i.stack.imgur.com/sNRbx.png)
, кажется, показывает правильное поведение. Прямая интеграция с использованием этих параметров с другим методом интеграции подтверждает правильность решения
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()