I am trying to solve a system of three differential equations simultaneously

14 visualizzazioni (ultimi 30 giorni)
I am attempting to sovle three differental equations simultaneously. The end goal is to plot the trajectory of (R2, R1) on an x,y plot.
Equation 1: dR1/dt = k1(a1*Rw - R1)
Equation 2: dR2/dt = k2(a2*Rw - R2)
Equation 3: (Xw*dRw)/dt = (Rwin-Rw)*u - (X1(dR1))/dt - (X2(dR2))/dt
ideally I would like to generate code to solve these three equations to where I could define the variables as needed but if this helps,
u=0:1
R1=6
R2=5.5
Rw=-0.5
a1=1.001
a2=0.9998
X1=X2 (these are mole fractions)
K1/K2 = 5 (these are rate constants)
Xw = 0.01 to 0.999 with steps of 0.01, 0.1, 0.2, 0.333, 0.5, 0.666, 0.8, 0.999
Atttached is the original paper for the equations and the way I would like to graph them for reference. The three ways I want to graph the data are "Closed" system, "Buffered" system, and Open System.
Thank you!! If this question belongs somwhere else please let me know.
  1 Commento
Sam Chak
Sam Chak il 20 Mar 2024
Can you rearrange the equations to this form?
appears to rise linearly. What is rate of change of when expressed in the form of as a function of time?

Accedi per commentare.

Risposta accettata

Star Strider
Star Strider il 20 Mar 2024
It ‘sort of’ has an analytic solution (if you want to let it run for a while, and then can make sense of that result), however if you want a numeric result from it, provide values for the variables and integrate it numerically —
syms R1(t) R2(t) Rw(t) k1 k2 X1 X2 u Rwin Xw a1 a2 R10 R20 Rw0 Y
dR1 = diff(R1);
dR2 = diff(R2);
dRw = diff(Rw);
Equation1 = dR1 == k1*(a1*Rw - R1)
Equation1(t) = 
Equation2 = dR2 == k2*(a2*Rw - R2)
Equation2(t) = 
Equation3 = (Xw*dRw) == (Rwin-Rw)*u - (X1*(dR1)) - (X2*(dR2))
Equation3(t) = 
% S = dsolve(Equation1, Equation2, Equation3, R1(0)==R10, R2(0)==R20, Rw(0)==Rw0);
% R1 = S.R1
% Rw = S.R2
% Rw = S.Rw
[VF,Subs] = odeToVectorField(Equation1, Equation2, Equation3)
VF = 
Subs = 
DifEqns = matlabFunction(VF, 'Vars',{t, Y, k1, k2, X1, X2, u, Rwin, Xw, a1, a2}) % Use This Result With The Numeric ODE Integrator Of Your Choice
DifEqns = function_handle with value:
@(t,Y,k1,k2,X1,X2,u,Rwin,Xw,a1,a2)[k2.*(a2.*Y(3)-Y(1));k1.*(a1.*Y(3)-Y(2));(Rwin.*u-u.*Y(3)+X1.*k1.*Y(2)+X2.*k2.*Y(1)-X1.*a1.*k1.*Y(3)-X2.*a2.*k2.*Y(3))./Xw]
.
  6 Commenti
Erin Summerlin-Donofrio
Erin Summerlin-Donofrio il 20 Mar 2024
Modificato: Erin Summerlin-Donofrio il 20 Mar 2024
Thank you!!!
I do have a couple of questions if you don't mind.
Is this syntax choosing the second value for u? also for Xw in the above code. My apologies, for Xw I meant very close to zero, not zero. As in the above question I'd like to vary u and Xw (from 0.005 to 0.9999, for example).
u=[0 1];
u = u(2);
And this is used to call R1 as Y1, etc?
R2 = Y(:,1);
R1 = Y(:,2);
Rw = Y(:,3);
Thank you!
Star Strider
Star Strider il 20 Mar 2024
My pleasure!
The order of the differential equations is: [R2 R1 Rw], so the initial conditions must match that order. That means:
Y0 = [5.5; 6.0; 0];
To vary ‘u’ and ‘Xw’ it will be necessary to run the code separately for each combination of them. Since each are (1x2) vectors, running the code 4 times, once with each combination. You can do this in two nested loops. If there are more than 2 values for each, the code will have to be run for each combination. Again, nested loops.
for k1 = 1:numel(u)
for k2 = 1:numel(Xw)
[t{k1,k2}, Y{k1,k2}] = ode45(@(t, Y) DifEqns(t, Y, k1, k2, X1, X2, u(k1), Rwin, Xw(k2), a1, a2), t, Y0);
end
end
This creates cell arrays for ‘t’ and ‘Y’ and saves them for each run.
To then get ‘Y’ for the second value of ‘u’ and the first value of ‘Xw’ the addressing would be:
Y21 = Y{2,1};
If you want them all to have the same row lengths, define:
t = linspace(0, 1000, N);
where ‘N’ can be any reasonable number (500, 1000, 1500 ...). That may make it easier to work with them, and it only requires one reference toto the time vector.
This:
R2 = Y(:,1);
R1 = Y(:,2);
Rw = Y(:,3);
or, keeping with the ongoing example:
R2 = Y21(:,1);
R1 = Y21(:,2);
Rw = Y21(:,3);
selects the varioous values from the ‘Y’ matrix so you can plot them individually. That is easier than having to refer to each column each time you need to use it.
.

Accedi per commentare.

Più risposte (2)

Sam Chak
Sam Chak il 20 Mar 2024
Modificato: Sam Chak il 21 Mar 2024
The third differential equation can be rearranged conveniently, allowing all three state equations to be incorporated into the 'odeModel()' function, which can be called by the ode45 solver. The remaining task is to ensure the correct input of parameters. Here is a code snippet for reference. You may need to design the flow signal u (also known as the manipulated variable) to achieve the desired output responses in , , and .
Edit: The code has been updated with the provided parameters and has been slightly modified using a 'for-loop' method to simulate the dynamical system iteratively for various values of the parameter , following similar approach demonstrated in Criss et al. (1987).
%% Settings
tspan = [0, 10]; % simulation time
R0 = [6.0; 5.5; -0.5]; % initial values of R1, R2, Rw
Xw = [0.01, 0.1, 0.2, 1/3, 0.5, 2/3, 0.8, 0.999]; % 8 elements in Xw
i = 1; % for placing text position
a = 1; % for placing text position
b = 60; % for placing text position
%% Call ode45 to solve odeModel for different values of Xw
for j = 1:numel(Xw) % looping 8 times
hold on, % hold current figure
[t, R] = ode45(@(t, R) odeModel(t, R, Xw(j)), tspan, R0);
plot(R(:,2), R(:,1)) % plot R1 (y-axis) vs. R2 (x-axis)
Ra = R(:,2); % for placing text position
Rb = R(:,1); % for placing text position
text(Rb(-i*a+b), Ra(-i*a+b), "Xw="+string(Xw(j)), 'FontSize', 8)
i = i + 1; % for placing text position
end
axis([2 6.5 1.5 6.5])
grid on, xlabel('R_{2}(t)'), ylabel('R_{1}(t)')
title('Mineral–Water Oxygen Isotope Exchange')
%% Dynamics of Mineral–Water Oxygen Isotope Exchange
function dRdt = odeModel(~, R, Xw)
% definitions
R1 = R(1);
R2 = R(2);
Rw = R(3);
% parameters
k1 = 5;
k2 = 1;
a1 = 1.001;
a2 = 0.9988;
Rwin=-0.5;
X1 = 0.5;
X2 = 0.5;
u = 0;
% state equations
dR1 = k1*(a1*Rw - R1);
dR2 = k2*(a2*Rw - R2);
dRw = ((Rwin - Rw)*u - X1*dR1 - X2*dR2)/Xw;
% derivative vector
dRdt= [dR1;
dR2;
dRw];
end
  16 Commenti
Erin Summerlin-Donofrio
Erin Summerlin-Donofrio il 8 Mag 2024
THANK YOU!!
Being able to plot it in 3D is actually really useful for what I'm trying to model and visualize!
Once again I SO appreciate all of your time and effort!!

Accedi per commentare.


Sam Chak
Sam Chak il 3 Mag 2024
This is merely a test. From the perspective of a first-order system, the variable u serves as an inverse of the time constant. Consequently, when the influx of water u is very large, the time constant of system is very small, and the state 'Rw' rapidly converges to the desired reference 'Rwin', nearly instantaneously, as if 'Rw' were constant irrespective of its initial condition.
Here is a demo:.
tspan = [0 10];
R0 = [4; 3; 2];
[t, R] = ode45(@(t, R) odefun(t, R, 1, 1, 1, 1, 1, 1000, 1, 1, 1), tspan, R0);
plot(t, R), grid on, xlabel('t'), legend('R_1', 'R_2', 'R_w', 'fontsize', 14)
%% Buffer System
function dRdt = odefun(t, R, a1, a2, k1, k2, Rwin, u, X1, X2, Xw)
dRdt = zeros(3, 1);
Rw = R(3);
dRdt(1) = - k1*(R(1) - a1*Rw); % k1 exponential rate response of R1(t) --> a1*Rw if Rw is bounded
dRdt(2) = - k2*(R(2) - a2*Rw); % k2 exponential rate response of R2(t) --> a2*Rw if Rw is bounded
dRdt(3) = (- u*(R(3) - Rwin) - X2*(- k2*(R(2) - a2*Rw)) - X1*(- k1*(R(1) - a1*Rw)))/Xw;
end

Community Treasure Hunt

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

Start Hunting!

Translated by