Second order ODE - Error in using ODE45?

조회 수: 2 (최근 30일)
Jennifer Yang
Jennifer Yang 2018년 6월 17일
댓글: Walter Roberson 2018년 6월 17일
Hello, I'm trying to solve the second order differential equation (Fick's second law) with a reaction term (which is a function of C_L) in MATLAB.
I created one script setting up my equations (odefcn.m) and another script to call to call odefcn (solodefcn.m).
function dC_Ldx=odefcn(x,C_L)
dC_Ldx = zeros(2,1);
syms N_r N_R N_r2 N_rR N_pR N_R2 R_L C_L
%Diffusion coefficient
D_ij= 1*10^-6;
%Rate constants
k_1 = 0.00193;
k_2 = 0.00255;
k_3 = 4.09;
d_1 = 0.007;
d_2 = 3.95*10^-5;
d_3 = 2.26;
%Equilibrium constants
K_1 = 3.63;
K_2 = 0.0155;
K_3 = 0.553;
K_4 = 9.01;
%K_5 = 0.077;
%K_6 = 0.000818;
K_i = 0.139;
%
N_T = 1.7;
N_r = (-(1+(C_L./K_2))+sqrt((1+(C_L./K_2)).^2-((4.*((2./K_4).*(1+(C_L./K_2).*(1+(1./K_i).*(1+(C_L./K_3)))))).*N_T)))./...
((4./K_4).*(1+(C_L./K_2).*(1+(1./K_i).*(1+(C_L./K_3)))));
N_R = (C_L./K_1).*N_r;
N_r2 = (1./K_4).*(N_r).^2;
N_rR = (C_L./(2.*K_2.*K_4)).*(N_r).^2;
N_pR = (C_L./(2.*K_2.*K_4.*K_i)).*(N_r).^2;
N_R2 = ((C_L.^2)./(K_2.*K_3.*K_4.*K_i)).*(N_r).^2;
R_L = ((2.*d_1.*(N_T-N_r-N_r2-N_rR-N_pR-N_R2))-(2.*k_1.*C_L.*N_r))+...
((2.*d_2.*(N_T-N_r-N_R-N_r2-N_pR-N_R2)))-((k_2.*C_L.*(N_T-N_r-N_R-N_rR-N_pR-N_R2)))+...
(d_3.*(N_T-N_r-N_R-N_r2-N_rR-N_pR))-(2.*k_3.*C_L.*(N_T-N_r-N_R-N_r2-N_rR-N_R2));
R_L = vectorize(R_L);
dC_Ldx(1) = C_L(2);
dC_Ldx(2) = -R_L/D_ij;
and (solodefcn.m)
clear all; close all; clc;
x0=0;
xf=100;
C_L0 = [1 0];
[x,C_L] = ode45(@odefcn, [x0,xf], C_L0);
plot(x,C_L(:,1),x,C_L(:,2))
I keep on getting the errors:
Error using symengine (line 58) Index exceeds matrix dimensions.
Error in sym/subsref (line 696) B = mupadmex('symobj::subsref',A.s,inds{:});
Error in odefcn (line 45) dC_Ldx(1) = C_L(2);
Error in odearguments (line 87) f0 = feval(ode,t0,y0,args{:}); % ODE15I sets args{1} to yp0.
Error in ode45 (line 113) [neq, tspan, ntspan, next, t0, tfinal, tdir, y0, f0, odeArgs, odeFcn, ...
Error in solodefcn (line 6) [x,C_L] = ode45(@odefcn, [x0,xf], C_L0);
and am unsure what I am doing wrong.
Am I setting up my second order differential equation incorrectly? I would appreciate any help I can get. Thank you!

답변 (1개)

Walter Roberson
Walter Roberson 2018년 6월 17일
Your declaration
syms N_r N_R N_r2 N_rR N_pR N_R2 R_L C_L
is overriding the C_L parameter name you are using . When you
syms C_L
that is the same as
C_L = sym('C_L')
so C_L ends up being a symbolic scalar, not something of length 2.
But even if you were preserving it correctly, what you are passing in is C_L(:,2) which is a scalar itself, so it would not have two elements inside ode function
  댓글 수: 6
Jennifer Yang
Jennifer Yang 2018년 6월 17일
Sorry. I'm still a bit confused. Is this for the original code where I had
dC_Ldx(2)=-R_L/D_ij
or for the situation where I had
dC_Ldx(2) = ((51.*C_L.*(((2000.*C_L)./31 + (((2000.*C_L)./31 + 1).^2 - (160000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./1643 - 80./53).^(1./2) - 1)./((800000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./27931 + 400./901) + (1146198855342281490208.*C_L.*((2000.*C_L)./31 + (((2000.*C_L)./31 + 1).^2 - (160000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./1643 - 80./53).^(1./2) - 1).^2)./(39069471042761828759.*((800000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./27931 + 400./901).^2) + (576460752303423488.*C_L.^2.*((2000.*C_L)./31 + (((2000.*C_L)./31 + 1).^2 - (160000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./1643 - 80./53).^(1./2) - 1).^2)./(6188225981639695.*((800000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./27931 + 400./901).^2) + (100.*C_L.*((2000.*C_L)./31 + (((2000.*C_L)./31 + 1).^2 - (160000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./1643 - 80./53).^(1./2) - 1))./(363.*((800000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./27931 + 400./901)) - 17./10))./20000 - (10487338329099335857321.*((2000.*C_L)./31 + (((2000.*C_L)./31 + 1).^2 - (160000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./1643 - 80./53).^(1./2) - 1))./(4611686018427387904000.*((800000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./27931 + 400./901)) + (409.*C_L.*(((2000.*C_L)./31 + (((2000.*C_L)./31 + 1).^2 - (160000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./1643 - 80./53).^(1./2) - 1)./((800000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./27931 + 400./901) + (100.*((2000.*C_L)./31 + (((2000.*C_L)./31 + 1).^2 - (160000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./1643 - 80./53).^(1./2) - 1).^2)./(901.*((800000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./27931 + 400./901).^2) + (100000.*C_L.*((2000.*C_L)./31 + (((2000.*C_L)./31 + 1).^2 - (160000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./1643 - 80./53).^(1./2) - 1).^2)./(27931.*((800000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./27931 + 400./901).^2) + (576460752303423488.*C_L.^2.*((2000.*C_L)./31 + (((2000.*C_L)./31 + 1).^2 - (160000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./1643 - 80./53).^(1./2) - 1).^2)./(6188225981639695.*((800000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./27931 + 400./901).^2) + (100.*C_L.*((2000.*C_L)./31 + (((2000.*C_L)./31 + 1).^2 - (160000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./1643 - 80./53).^(1./2) - 1))./(363.*((800000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./27931 + 400./901)) - 17./10))./50 - (10487338329099335857321.*((2000.*C_L)./31 + (((2000.*C_L)./31 + 1).^2 - (160000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./1643 - 80./53).^(1./2) - 1).^2)./(41551291026030765015040.*((800000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./27931 + 400./901).^2) - (333636569133360832851632851.*C_L.*((2000.*C_L)./31 + (((2000.*C_L)./31 + 1).^2 - (160000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./1643 - 80./53).^(1./2) - 1).^2)./(5000892293473514081152000.*((800000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./27931 + 400./901).^2) - (64927927453439194281.*C_L.^2.*((2000.*C_L)./31 + (((2000.*C_L)./31 + 1).^2 - (160000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./1643 - 80./53).^(1./2) - 1).^2)./(49505807853117560000.*((800000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./27931 + 400./901).^2) - (6554620466871470812811417.*C_L.*((2000.*C_L)./31 + (((2000.*C_L)./31 + 1).^2 - (160000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./1643 - 80./53).^(1./2) - 1))./(10462762654307136307200000.*((800000.*C_L.*((1000000.*C_L)./76867 + 1139./139))./27931 + 400./901)) + 178284751594688709574457./46116860184273879040000)./D_ij;
So what is the C = C_L(1); and L=C_L(2); supposed to do? Is this supposed to replace or fix the mismatch vector length for dC_Ldx(1) and dC_Ldx(2)?
You also mentioned to write the code in terms of C and L. I only really have everything in terms of C_L. So I'm not too sure what you mean.
Walter Roberson
Walter Roberson 2018년 6월 17일
Hmmm, I think,
function dC_Ldx=odefcn(x, C_L_derivs)
C_L = C_L_derivs(1);
....
dC_Ldx(1) = C_L_derivs(1);
dC_Ldx(2) = -R_L/D_ij;

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Numeric Solvers에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by