Help with odes and two different reactions
Show older comments
๐๐ถ๐ด/๐๐ก = ๐1๐ด = โ๐๐ด๐ถ๐ด๐ถ๐ต ( 9 ) The first two have the same rate constant
๐๐ถ๐ต/๐๐ก = ๐1๐ต = ๐1๐ด = โ๐๐ด๐ถ๐ด๐ถ๐ต ( 10 )
d๐ถ๐/๐๐ก = ๐2๐ = โ๐๐๐ถ๐ ( 11 )
A + B โ C + ยฝ D (gas)
S โ 3 D (gas) + misc liquids and solids
These are the two reactions, do I have to do two seperate odes because of the different reactions (and rate constants)? Or is there a way to work out all the differentials in the same ode with initial concentrations known?
If any of my code is needed to answer the question let me know.
Thanks
1 Comment
Torsten
on 14 Jan 2022
Look at the second example (Solve Stiff ODE) to see how you can solve all three ODEs in one call to the integrator.
Answers (1)
HWIK
on 14 Jan 2022
Just write a function for the ODEs and feed it to the solver:
function out = name_your_function(tspan, inputs)
%Get your inputs and assign them to variables:
%(keep the same order as in your initial conditions!)
ca = inputs(1);
cb = inputs(2);
cs = inputs(3);
%Define your relationships:
%choose your values of k1 & k2:
k1 = ;
k2 = ;
%Reaction rates:
r1 = k1*ca*cb;
r2 = k2*cs;
%Define your ODEs:
dca = -r1;
dcb = -r1;
dcs = -r2;
%Assign your ourput:
out = [dca; dcb; dcs];
end
Solve over a given time span and for whatever initial conditions you have, using whatever solver seems to suit your system best.
33 Comments
Tom Goodland
on 14 Jan 2022
HWIK
on 14 Jan 2022
What I wrote is just the function, to solve it you just define what time range you want to plot over and define your initial conditions, which you then feed to the ode solver:
tspan = [0 200]; %just as an example
initial_conditions = [3 2 1]; %its the values of the variables you are solving for at t=0
%there must be as many inputs to the initial conditions as variables solved
%Solve your ODE function (I picked ode45 in this case,could be another):
[t , y] = ode45(@name_your_function, tspan initial_conditions);
%output t is your time range, and y an array with all your variables where:
ca = y(:,1);
cb = y(:,2); %and so on, you can then plot(t, ca)
If you want to solve for pressure and temperature you will have to add those in the code of the function I added before in a similar way as I did with the rate laws
Torsten
on 14 Jan 2022
tspan = [0 200]; %just as an example
initial_conditions = [4.3 5.1 3]; %its the values of the variables you are solving for at t=0
%there must be as many inputs to the initial conditions as variables solved
%Solve your ODE function (I picked ode45 in this case,could be another):
[t,y] = ode15s(@(t,y)name_your_function(t,y(1),y(2),y(3)), tspan, initial_conditions);
%output t is your time range, and y an array with all your variables where:
ca = y(:,1);
cb = y(:,2);
cs = y(:,3);
plot(t,[ca,cb,cs]);
function out = name_your_function(tspan,ca,cb,cs);
%Get your inputs and assign them to variables:
%(keep the same order as in your initial conditions!)
%Define your relationships:
k_0_1 = 4E14;
k_0_2 = 1E84;
Ea1 = 128000;
Ea2 = 800000;
R_gas = 8.314;
%choose your values of k1 & k2:
k1 = k_0_1*exp(-Ea1/(R_gas*422));
k2 = k_0_2*exp(-Ea2/(R_gas*422));
%Reaction rates:
r1 = k1*ca*cb;
r2 = k2*cs;
%Define your ODEs:
dca = -r1;
dcb = -r1;
dcs = -r2;
%Assign your ourput:
out = [dca; dcb; dcs];
end
HWIK
on 14 Jan 2022
When assigning variables in your ode function dont assign them to a constant, use the format I followed in the code I gave, assign them to the input of the function, if not the ode solver will be solving for the same thing all the time.
When you are calling the function in the solver use @ before
Tom Goodland
on 14 Jan 2022
Tom Goodland
on 15 Jan 2022
HWIK
on 15 Jan 2022
As long as what you put in your question are elementary reactions, dcD/dt = r1/2 + 3*r2
Tom Goodland
on 15 Jan 2022
HWIK
on 15 Jan 2022
follow the same structure as the current one, just add temperature and pressure to the input and output variables, and define their relationships. For the conditionals in the pressure use an if statement.
Tom Goodland
on 15 Jan 2022
HWIK
on 15 Jan 2022
Just add the expressions for dP and dT in the function you are adding to the ode solver, you only need one function, and then just update the output: out = [dca ; dcb;... ; dP; dT].
Similarly add the inputs in the same order: P = inputs(5); T = inputs(6)
Torsten
on 15 Jan 2022
If it worked with three, it will also work with five :-)
Tom Goodland
on 15 Jan 2022
Torsten
on 15 Jan 2022
function main
tspan = [0 200]; %just as an example
initial_conditions = [4.3 5.1 3 0 4.4 422]; %its the values of the variables you are solving for at t=0
%there must be as many inputs to the initial conditions as variables solved
%Solve your ODE function (I picked ode45 in this case,could be another):
[t,y] = ode15s(@(t,y)fun(t,y(1),y(2),y(3),y(4),y(5),y(6)), tspan, initial_conditions);
%output t is your time range, and y an array with all your variables where:
ca = y(:,1);
cb = y(:,2);
cs = y(:,3);
cd = y(:,4);
P = y(:,5);
T_2 = y(:,6);
figure(1)
plot(t,[ca,cb,cs,cd])
figure(2)
plot(t,P)
figure(3)
plot(t,T_2)
end
function out = fun(tspan,ca,cb,cs,cd,P,T_2)
%Get your inputs and assign them to variables:
%(keep the same order as in your initial conditions!)
%Define your relationships:
k_0_1 = 4E14;
k_0_2 = 1E84;
Ea1 = 128000;
Ea2 = 800000;
R_gas = 8.314;
V0 = 4000;% L
VH = 5000;
Cv1 = 3360; % mol / h * atm
Cv2 = 53600; % mol / h * atm
Hr1 = -45400; % J / mol
Hr2 = -3.2E5;
Ta = 373;
UA = 0;
NCp = 1.26E7; % J / K
%choose your values of k1 & k2:
k1 = k_0_1*exp(-Ea1/(R_gas*T_2));
k2 = k_0_2*exp(-Ea2/(R_gas*T_2));
%Reaction rates:
r1 = k1*ca*cb;
r2 = k2*cs;
%Fd
Fd = (-0.5*r1-3*r2)*V0;
%
if Fd < 11.4 % mol / h
Fvent = Fd;
else
if P < 28.2 % atm
Fvent = (P - 1)*Cv1;
else
Fvent = (P - 1)*(Cv1 + Cv2);
end
end
%Define your ODEs:
dca = -r1;
dcb = -r1;
dcs = -r2;
dcd = r1/2 + 3*r2;
dp = (Fd - Fvent)*((R_gas*T_2)/VH);
dT = (V0*(r1*Hr1 + r2*Hr2) - UA*(T_2 - Ta))/NCp;
%Assign your ourput:
out = [dca; dcb; dcs; dcd;dp;dT];
end
Check whether Fvent is calculated correctly.
HWIK
on 15 Jan 2022
Use semicolons in your out variable in the function, it must be a column vector.
In the solver you have one input for your initial conditions, therefore your thorsten function must too, and extract those variables at the begining of the function from the array you input it (just like I put in the initial answer...).
You are missing a * in the dT variable after the UA.
Also, do not define the variables you are trying to solve as constants, like you did for T_2, or else it will remain as a constant.
Tom Goodland
on 15 Jan 2022
Tom Goodland
on 15 Jan 2022
Tom Goodland
on 15 Jan 2022
Torsten
on 15 Jan 2022
Ua = 0, Hr1, Hr2 are both negative, r1 and r2 are positive, so dT/dt < 0.
r2s is positive, but becomes smaller with time: from 2.8e-15 to 5.3e-27 (so all appr. 0).
But you should learn to debug by yourself. Just remove the semicolon after the variable you want to see, run the code and look at the values printed to the command window.
Tom Goodland
on 16 Jan 2022
Tom Goodland
on 16 Jan 2022
Torsten
on 16 Jan 2022
For another part I have to do these plots all again for: where the cooling water is turned on (UA = 2.77E6 J/(h K)) once the temperature in the reactor reaches 455 K. How would I calculate the initial conditions for this, is there something on matlab to choose 455K and find the CA, CB, CS, and CD values corresponding on the graphs?
Define an event for the integrator if T reaches 455 K.
dp = (Fd - Fvent)*((R_gas*T_2)/VH) in the code so would I be right in saying that as temperature increases the pressure should aswell due to T_2 being multuplied by R_gas in the equation.
Only if Fd > Fvent
Tom Goodland
on 16 Jan 2022
No, it's the solution vector [ca,cb,cs,...] at the time when the event occured.
You will have to call odeXY with these values as start values for a new period of integration and with the equation for dT/dt changed. Hand a flag to odefun which contains the number of the integration period and which serves you to set up the dT/dt equation correctly:
function dydt = odefun(t,ca,cb,cs,cd,P,T_2,flag)
...
if flag==1
dT = ...;
elseif flag ==2
dT = ...;
end
Tom Goodland
on 16 Jan 2022
Tom Goodland
on 16 Jan 2022
Torsten
on 17 Jan 2022
This is a rough guideline.
If errors pop up, first make an attempt to correct them on your own, please.
function main
tspan = [0 200]; %just as an example
initial_conditions = [4.3 5.1 3 0 4.4 422]; %its the values of the variables you are solving for at t=0
options = odeset('Events',@myEventsFcn);
iflag = 1;
[t1,y1,te,ye,ie] = ode15s(@(t,y)fun(t,y(1),y(2),y(3),y(4),y(5),y(6),iflag), tspan, initial_conditions,options);
iflag = 2;
[t2,y2] = ode15s(@(t,y)fun(t,y(1),y(2),y(3),y(4),y(5),y(6),iflag), [te tspan(end)], ye);
t = [t1;te;t2];
y = [y1;ye;y2];
%output t is your time range, and y an array with all your variables where:
ca = y(:,1);
cb = y(:,2);
cs = y(:,3);
cd = y(:,4);
P = y(:,5);
T_2 = y(:,6);
figure(1)
plot(t,[ca,cb,cs,cd])
figure(2)
plot(t,P)
figure(3)
plot(t,T_2)
end
function [value,isterminal,direction] = myEventsFcn(t,y)
value = y(6) - 455; % The value that we want to be zero
isterminal = 1; % Halt integration
direction = 0; % The zero can be approached from either direction
end
function out = fun(tspan,ca,cb,cs,cd,P,T_2,iflag)
%Get your inputs and assign them to variables:
%(keep the same order as in your initial conditions!)
%Define your relationships:
k_0_1 = 4E14;
k_0_2 = 1E84;
Ea1 = 128000;
Ea2 = 800000;
R_gas = 8.314;
V0 = 4000;% L
VH = 5000;
Cv1 = 3360; % mol / h * atm
Cv2 = 53600; % mol / h * atm
Hr1 = -45400; % J / mol
Hr2 = -3.2E5;
Ta = 373;
if iflag == 1
UA = 0;
elseif iflag == 2
UA = 2.77E6;
end
NCp = 1.26E7; % J / K
%choose your values of k1 & k2:
k1 = k_0_1*exp(-Ea1/(R_gas*T_2));
k2 = k_0_2*exp(-Ea2/(R_gas*T_2));
%Reaction rates:
r1 = k1*ca*cb;
r2 = k2*cs;
%Fd
Fd = (-0.5*r1-3*r2)*V0;
%
if Fd < 11.4 % mol / h
Fvent = Fd;
else
if P < 28.2 % atm
Fvent = (P - 1)*Cv1;
else
Fvent = (P - 1)*(Cv1 + Cv2);
end
end
%Define your ODEs:
dca = -r1;
dcb = -r1;
dcs = -r2;
dcd = r1/2 + 3*r2;
dp = (Fd - Fvent)*((R_gas*T_2)/VH);
dT = (V0*(r1*Hr1 + r2*Hr2) - UA*(T_2 - Ta))/NCp;
%Assign your ourput:
out = [dca; dcb; dcs; dcd;dp;dT];
end
Tom Goodland
on 17 Jan 2022
Tom Goodland
on 17 Jan 2022
Tom Goodland
on 17 Jan 2022
Torsten
on 18 Jan 2022
You mean something like this ?
function main
tspan = [0 10]; %just as an example
initial_conditions = [4.3 5.1 3 0 4.4 422]; %its the values of the variables you are solving for at t=0
%there must be as many inputs to the initial conditions as variables solved
%Solve your ODE function (I picked ode45 in this case,could be another):
Tstop_left = 450.0;
Tstop_right = 495.0;
Tstop = (Tstop_left + Tstop_right)/2.0;
while Tstop_right - Tstop_left >= 0.1
options = odeset('RelTol',1e-8,'AbsTol',1e-8,'Events',@(t,y)myEventsFcn(t,y,Tstop));
iflag = 1;
[t1,y1,te,ye,ie] = ode15s(@(t,y)fun(t,y(1),y(2),y(3),y(4),y(5),y(6),iflag), tspan, initial_conditions,options);
iflag = 2;
options = odeset('RelTol',1e-8,'AbsTol',1e-8,'InitialStep',1e-8);
[t2,y2] = ode15s(@(t,y)fun(t,y(1),y(2),y(3),y(4),y(5),y(6),iflag), [te tspan(end)], ye, options);
Tmax = max(y2(:,6))
if Tmax > 500
Tstop_left = Tstop_left;
Tstop_right = Tstop;
Tstop = (Tstop_left + Tstop_right)/2;
else
Tstop_left = Tstop;
Tstop_right = Tstop_right;
Tstop = (Tstop_left + Tstop_right)/2;
end
end
Tstop
t = [t1;te;t2];
y = [y1;ye;y2];
%output t is your time range, and y an array with all your variables where:
ca = y(:,1);
cb = y(:,2);
cs = y(:,3);
cd = y(:,4);
P = y(:,5);
T_2 = y(:,6);
figure(1)
plot(t,[ca,cb,cs,cd])
figure(2)
plot(t,P)
figure(3)
plot(t,T_2)
end
function [value,isterminal,direction] = myEventsFcn(t,y,Tstop)
value = y(6) - Tstop; % The value that we want to be zero
isterminal = 1; % Halt integration
direction = 0; % The zero can be approached from either direction
end
function out = fun(tspan,ca,cb,cs,cd,P,T_2,iflag)
%Get your inputs and assign them to variables:
%(keep the same order as in your initial conditions!)
%Define your relationships:
k_0_1 = 4E14;
k_0_2 = 1E84;
Ea1 = 128000;
Ea2 = 800000;
R_gas = 8.314;
V0 = 4000;% L
VH = 5000;
Cv1 = 3360; % mol / h * atm
Cv2 = 53600; % mol / h * atm
Hr1 = -45400; % J / mol
Hr2 = -3.2E5;
Ta = 373;
if iflag == 1
UA = 0;
elseif iflag == 2
UA = 2.77E6;
end
NCp = 1.26E7; % J / K
%choose your values of k1 & k2:
k1 = k_0_1*exp(-Ea1/(R_gas*T_2));
k2 = k_0_2*exp(-Ea2/(R_gas*T_2));
%Reaction rates:
r1 = k1*ca*cb;
r2 = k2*cs;
%Fd
Fd = (-0.5*r1-3*r2)*V0;
%
if Fd < 11.4 % mol / h
Fvent = Fd;
else
if P < 28.2 % atm
Fvent = (P - 1)*Cv1;
else
Fvent = (P - 1)*(Cv1 + Cv2);
end
end
%Define your ODEs:
dca = -r1;
dcb = -r1;
dcs = -r2;
dcd = r1/2 + 3*r2;
dp = (Fd - Fvent)*((R_gas*T_2)/VH);
dT = (V0*(r1*-Hr1 + r2*-Hr2) - UA*(T_2 - Ta))/NCp;
%Assign your ourput:
out = [dca; dcb; dcs; dcd;dp;dT];
end
Categories
Find more on Ordinary Differential Equations in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!