Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Solving four ordinary dif equations simultaneously using ode45 matlab

  1. Nov 29, 2006 #1
    I am trying to replicate an example problem that was found in an "into to combustion book"....... And of course, yes it is for school. Unfortunately there is no matlab class offered but, they expect us to know it.... I tried the example in matlab help found under the ode45 and couldnt even get this to run. I thought if i could get it to run, I would use this as a model for the problem i am working on.......... Solving four equations simultanously

    Example problem code:
    -----------------------------------------------------------
    function dy = rigid(t,y)

    dy = zeros(3,1);

    dy(1) = y(2) * y(3);

    dy(2) = -y(1) * y(3);

    dy(3) = -0.51 * y(1) * y(2);

    options = odeset('RelTol', 1e-4, 'AbsTol', [1e-4 1e-4 1e-5]);

    [T,Y] = ode45(@rigid, [0 12], [0 1 1], options);

    plot(T,Y(:,1),'-',T,Y(:,2),'-.',T,Y(:3),'.');
    -----------------------------------------------------------

    This Code Shows an error in the "dy(1) = y(2) * y(3);" line.

    The equations i really need to solve for are as follows
    -----------------------------------------------------------
    dF/dt = -4.7316(10^8) * (F^0.1) * (O^1.65) * exp(-15098/T)
    F(0) = .023918

    dO/dt = 16 * (dF/dt)
    O(0) = .382681

    dP/dt = -17 * (dF/dt)
    P(0) = 0

    dT/dt = -3715.19* (dF/dt)
    T(0) = 753
    -----------------------------------------------------------

    Any Help would greatly be appreceated, its due monday...
    and it seems everything else is.
    Thanks,
    Jack
     
  2. jcsd
  3. Nov 30, 2006 #2
    For the ode solvers in matlab, you need two pieces. If you have the equation
    dy/dt = f(t,y)
    you need to create a matlab function which evalutes f(t,y) when given y and t, and then you need a separate piece which calls ode45, and ode45 takes in as an argument the function name of f(t,y). Your function rigid(t,y) is what evaluates f(t,y), but then you need to pass that as an argument to ode45. So what you have
    should be broken up into two separate things. First you need the function
    Code (Text):
    function dy = rigid(t,y)

    dy = zeros(3,1);

    dy(1) = y(2) * y(3);

    dy(2) = -y(1) * y(3);

    dy(3) = -0.51 * y(1) * y(2);
    saved as rigid.m, and then you need another file which contains
    Code (Text):
     options = odeset('RelTol', 1e-4, 'AbsTol', [1e-4 1e-4 1e-5]);

    [T,Y] = ode45(@rigid, [0 12], [0 1 1], options);

    plot(T,Y(:,1),'-',T,Y(:,2),'-.',T,Y(:,3),'.');
    Run this second file and it will declare the options you want, it will call matlab's ode solver which in turn will call your function rigid, and then it will plot the results. Also, you have a type in your original thing in the last line plot(....), you need a comma between the colon and three.
     
  4. Nov 30, 2006 #3
    Thanks, I will give that a try LeBrad
     
  5. Dec 1, 2006 #4
    I was able to get the problem to work, know i am trying to use it as a model for solving the poblem below. For some reason I get an error in the first line of the second function expression. I do agree something is wrong there, it's just matlab help is not helping, Any thoughts or suggestions?
    Jack

    %problem solving for
    % dF/dt = -4.7316*(10^8)* (F^0.1)*(O^1.65)*exp(-15098/T)
    % F(0) = .023918
    %
    % dO/dt = 16 * dF/dt
    % O(0) = .382681
    %
    % dP/dt = -17 * dF/dt
    % P(0) = 0
    %
    % dT/dt = -3715.19 * dF/dt
    % T(0) = 753
    %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %Begin myodee.m
    function myodee
    [t,y] = ode45(@rigid, [0 3.100], [.023918 0.38261 0 753]);
    %t= the scaler time
    %y= the colum vector
    %ode45 is the solver
    %@rigid is the function handle calling function below
    %[0 3.100] is the time to be evaluated from t0 to tf
    %[.023918....etc] is the initial conditions
    odeprint(t,y);
    %odeprint to print results on screen
    %plot(t,y(:,1),'-',t,y(:,2),'-.',t,y(:,3),'.'); in case to plot


    function (t,[dF,dO,dP,dT]) = rigid ([F O P T])
    %[dF,dO,dP,dT] = returns outputs to y
    %rigid(t,[F,O,P,T]) accepts the inputs (initial conditions)
    dF = -4.7316*(10^8)*(F^0.1)*(Ox^1.65)* exp(-15098/T);
    dO = 16 * dF;
    dP = -17 * dF;
    dT = -3715.9 * dF;
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %Problem Modelled after

    %Begin myode.m
    %function myode % Added this line
    % Moved these three lines up to the top of the file
    %options = odeset('RelTol', 1e-4, 'AbsTol', [1e-4 1e-4 1e-5]);
    %[T,Y] = ode45(@rigid, [0 12], [0 1 1], options);
    %plot(T,Y(:,1),'-',T,Y(:,2),'-.',T,Y(:,3),'.');

    %function dy = rigid(t,y)
    %dy = zeros(3,1);
    %dy(1) = y(2) * y(3);
    %dy(2) = -y(1) * y(3);
    %dy(3) = -0.51 * y(1) * y(2);
     
  6. Dec 1, 2006 #5
    I made some changes that should make it work for you.
    Code (Text):
    function myodee
    tspan = [0 3.1]; y0 = [.023918; 0.38261; 0; 753];
    [t,y] = ode45(@rigid,tspan,y0);
    %t= the scaler time
    %y= the colum vector
    %ode45 is the solver
    %@rigid is the function handle calling function below
    %[0 3.100] is the time to be evaluated from t0 to tf
    %[.023918....etc] is the initial conditions
    odeprint(t,y);
    %odeprint to print results on screen
    plot(t,y(:,1),'-',t,y(:,2),'-.',t,y(:,3),'.'); %in case to plot


    function dy = rigid(t,y)
    %[dF,dO,dP,dT] = returns outputs to y
    %rigid(t,[F,O,P,T]) accepts the inputs (initial conditions)
    F = y(1);
    Ox = y(2);
    P = y(3);
    T = y(4);
    dF = -4.7316*(10^8)*(F^0.1)*(Ox^1.65)* exp(-15098/T);
    dO = 16 * dF;
    dP = -17 * dF;
    dT = -3715.9 * dF;
    dy = [dF; dO; dP; dT];
    A couple things to note here.

    First, the odefunc rigid which you pass to ode45 should take in two vectors (t and y) and return one vector (dy). If you try to pass the vector as [a b c d] in the function definition (first line of the function)
    function (t,[dF,dO,dP,dT]) = rigid (t,[F O P T])
    , it will just confuse matlab, so just pass it as y,
    function dy = rigid(t,y)
    and then pull it apart in the next line like
    a = y(1);
    b = y(2);
    ...
    Similarly, define dy = [da db dc dd] and then return the vector dy.

    It is, however, ok to write
    [t,y] = ode45(@rigid, [0 3.100], [.023918 0.38261 0 753]);
    when you are calling a function. But it just makes things confusing so I defined tspan and y0.

    And you can't have spaces between a function name and it's argument, e.g.
    rigid (a,b) should be rigid(a,b).

    Let me know if this doesn't work for you or if something I changed isn't clear.
     
  7. Dec 1, 2006 #6
    Thank You very much, I will give it a try............. and report back
    Thanks again
    Jack
     
  8. Dec 2, 2006 #7
    Wow, I tried it and i worked, I just had a few more q's

    1. how do increase the significant digets that are printed out on the screen by the odeprint function?

    2. I changed the time scale to (0 to 3.1 ms), The question I had is between 3 and 3.1 ms there is a major /defining it as a "stiff" problem. How can I focus in on this area without initial conditions? I already added this code below to increase the precision.

    options = odeset('RelTol',1e-6,'AbsTol',[1e-6 1e-6 1e-6 1e-6]);

    Thanks for all your help.

    Jack
     
  9. Dec 3, 2006 #8
    add 'format long' somewhere near the top of your first function.

    Are you saying you only want to look at y(t) between t=3ms and t=3.1ms? If that's what you want, you need to know the initial condition y(3ms). If you want, you could run ode45 twice, once on t=[0,3ms], and then again from t=[3ms,3.1ms] using the final value from the first run as the intial condition for the second part.

    If you just want smaller time steps near 3ms, you can define the time discretization for ode45. When tspan is [0,3.1] as it is now, ode45 picks how to discretize it, but if you define tspan = [0:0.01:3.1] it will chop up the time into into 0.01 size pieces. If you want to go from 0 to 3.1 but you want to go slower from 1 to 2, you can define
    tspan = [[0:0.1:1], [1:0.001:2], [2:0.1:3.1]]
    Then you have timesteps of 0.1 from 1 to 2, timesteps of 0.001 from 1 to 2, and timesteps of 0.1 from 2 to 3.1. So you can do something like that to alter the timestep size in important regions.
     
  10. Dec 3, 2006 #9
    LeBrad,
    That sounds like it will help, I will have to give it a try tommorow
    Jack
     
  11. Jun 24, 2009 #10
    I have a doubt....I want to pass additional parameters in ode 45 ......how can i do it...!!!! Pllz reply...!!!
     
  12. Sep 13, 2011 #11
    Suppose my function F itself is a function of O or P or T....Then how to code it...???
    Please help me asap....
     
  13. Sep 13, 2011 #12
    Suppose my function F itself is a function of O or P or T....Then how to code it...???
    Please help me asap....
     
  14. Jan 31, 2012 #13
    Hi,I am trying to solve a system of differential equations consisting 3 equations with 3 variables.one of the given eqations is of second order. I converted it to first order.everything was ok compare to the first example here given. but unfortunately I found many errors.
    would you please help me to solve it.........
    here are the matlab codes.........

    function dx=test(r,x)
    dx=zeros(4,1);
    dx(1)=(1/(6*r))*(-exp(2*x(1))*(1+k*x(3)^2)+3-r^2*k*x(4)^2);
    dx(2)=(1/(2*r))*(((3+k*x(3)^2)-exp(-2*x(1))*k*r^2*x(4)^2)*1/3*exp(-2*x(1))-1);
    dx(4)=exp(2*x(1))*(exp(-2*x(1))*x(4)*r^2*(dx(1)-dx(2)-2/r)+2*x(3));

    I saved namely test.m file
    then I wrote another script file as follows......

    k=1;
    x0=[0 -1 0 1];
    [r,x]=ode45('test',[0 10],x0);
    plot(r,x(:,1))




    here the reply from the matlab....

    ??? Undefined function or variable 'k'.

    Error in ==> test at 3
    dx(1)=(1/(6*r))*(-exp(2*x(1))*(1+k*x(3)^2)+3-r^2*k*x(4)^2);

    Error in ==> odearguments at 109
    f0 = feval(ode,t0,y0,args{:}); % ODE15I sets args{1} to yp0.

    Error in ==> ode45 at 173
    [neq, tspan, ntspan, next, t0, tfinal, tdir, y0, f0, odeArgs, odeFcn, ...

    Error in ==> solve at 3
    [r,x]=ode45('test',[0 10],x0);

    >>

    please help me to solve it!!!!
    thanks
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?



Similar Discussions: Solving four ordinary dif equations simultaneously using ode45 matlab
Loading...