# Should be easy but I keep getting errors. I want to input the array through a function that I already have generated through equations then plot it.

1 view (last 30 days)
Nikolaj Kloch on 5 Oct 2020
Edited: Stephen Cobeldick on 8 Oct 2020
%Initial Scipt with function at bottom
%I want to plug in the arays of kmat into the equations in combustion.m to use ode and save the results using the c1mat, c2mat, etc... I keep making more errors and am doing something frustrating. Any guidance would be very helpful!
A1=9200000;
A2=420000000;
A3=350000;
n1=0;
n2=5.3;
n3=7.65;
Ea1=108400;
Ea2=350000;
Ea3=525000;
R=82.057;
k1mat = zeros(1,29);
k2mat = zeros(1,29);
k3mat = zeros(1,29);
c1mat = zeros(1,29);
c2mat = zeros(1,29);
c3mat = zeros(1,29);
Tmat = 500:25:1200;
for i = 1:numel(Tmat)
T = Tmat(i)+25;
c1=(3.6*10^-04)*(1/R*T);
%c2=0
c3=(2.4*10^-04)*(1/R*T);
c4=0.0664*(1/R*T);
k1=(A1*T^(n1)*exp(-Ea1/(R*T)));
k2=(A2*T^(n2)*exp(-Ea2/(R*T)));
k3=(A3*T^(n3)*exp(-Ea3/(R*T)));
k1mat(i) = k1;
k2mat(i) = k2;
k3mat(i) = k3;
c1mat(i) = c1;
c3mat(i) = c3;
c4mat(i) = c4;
end
%{
c(1)=(NH4)2(SO4)
c(2)=NH3
c(3)=NO
c(4)=O2
row2 = kmat(2, :)
%}
kmat = [k1mat; k2mat; k3mat];
options=odeset('maxstep',0.01,'abstol',1e-16,'reltol',1e-4);
[t c]=ode45(@combustion, [0:0.0001:0.1],[c1mat c2mat c3mat c4mat],options,kmat);
figure(1)
plot(t,c(:,1),'b','LineWidth',1.5)
hold on;
plot(t,c(:,3),'r','LineWidth',1.5)
hold on;
plot(t,c(:,4),'g','LineWidth',1.5)
hold off;
xlabel('Time/s')
ylabel('Concentration')
legend ('A','B*','D*')
function dcdt= combustion(t,c,par)
%kmat(2, :)
dcdt(1,1)=-kmat(1, :)*c(1,1);
dcdt(2,1)=(2*kmat(1, :)*c(1,1))-(kmat(2, :)*c(2,1)*c(3,1))-(kmat(3, :)*c(2,1)*c(4,1));
dcdt(3,1)=(-kmat(2, :)*c(2,1)*c(3,1))+(kmat(3, :)*c(2,1)*c(4,1));

Kiran Felix Robert on 8 Oct 2020
Hi Nikolaj,
The error is because a MATLAB Function has a different workspace with respect to the base workspace. That is the variables which you have in your base workspace cannot be accessed inside the function. (Try adding breakpoints in the first blank line of the combustion function and check your workspace)
Since you have defined kmat in the base workspace and you are using it inside your combustion function you get an error. Please check the documentation for the ode45 function as you cannot pass arguments directly.
One possible work around is to define your kmat inside your combustion function. Or another (not advised) way is to declare your kmat as a global variable (you must declare it both outside and inside the function)
Refer Base and Function Workspaces , ode45 , global variable for more information.
Kiran Felix Robert

Stephen Cobeldick on 8 Oct 2020
Edited: Stephen Cobeldick on 8 Oct 2020
As the ode45 documentation explains here (with examples):
the correct solution is that you need to parameterize your function:
For example redefine the function so that kmat is an input argument:
function dcdt= combustion(t,c,kmat)
and then call it like this:
kmat = [..];
[t,c] = ode45(@(t,y)combustion(t,y,kmat), .. );