How can I make ODE15s interpolate a value from a given table on each time step?

3 views (last 30 days)
I am trying to solve a system of algebraic and differntial equations using ODE15s. This is not my problem though, I cannot seem to figure out how to impliment my experimental data, which I have in a matrix in terms of time, into my ODE solver. I would basically like for, on each time step, my Area of Valve(Av) in the ODE solver to interpolate to a matrix containing Valve area and time that I have measured.
So just for an example here's a much simplified version of my code:
Data = readmatrix(experimentdata)
Av = Data(:,8) %Table of Av values that I should note are too sporatic to be polyfit with any accuracy.
time = Data(:,1)
function out = myODE(t,y)
out(1) = ...
out(2) = ...
out(3) = Av*...
end
Basically because I can't get my Av value in terms of time to match with the time step in the ODE solver, I am getting tolerance errors from ODE15s and having discontinuities created. Any help is greatly appreciated.
Note: The code runs just fine given constant Av, only when given a vector does it fail.

Answers (2)

Walter Roberson
Walter Roberson on 8 Jul 2023
You can call interp1(), but you must use an interpolation method that is at least quartic (not linear).
If your situation is such that the arrays you are interpolating over can be said to outline a continuous path that should be assumed to curve through the data points, then interp1() with 'cubic' might work for you. If you are at time t between two entries t1 and t2 and it makes sense to "look ahead" to t2 to steer towards where you need to be at t2, then this method might work for you.
If your situation is such that the arrays give information about sudden events, then each time there is such an event, then you need to stop the ode*() call, adjust the boundary conditions, and then call the ode*() function again to pick up from the boundary. For example if the data in the arrays represent injections of chemicals, or represent bumps in a road, or represent bouncing off of something, then you cannot use interp1() in your ode function.

Star Strider
Star Strider on 8 Jul 2023
That depends on the problem that you want ode15s to solve. As a general rule, the approach is to include an interp1 call, and pass ‘Av’ and ‘time’ as additional arguments to ‘myODE’.
Example —
time = linspace(0, 5, 150).';
Av = (1 - exp(-0.5*time))*10;
[t,y] = ode15s(@(t,y)myODE(t,y,Av,time), [0 5], [0.1 0.2 0.3]);
figure
plot(t, y)
grid
xlabel('Time')
ylabel('Something')
function out = myODE(t, y, Av, time)
Avv = interp1(Av, time, t);
out = zeros(3,1);
out(1) = -100*y(1);
out(2) = y(2);
out(3) = Avv / y(3);
end
That may not be appropriate for all types of problems that ode15s can solve, however it will work for some of them.
.
  8 Comments
Torsten
Torsten on 9 Jul 2023
Edited: Torsten on 9 Jul 2023
The call to "interp1" should most probably be
Av = interp1(Timekept,Valvekept,t,'spline') ;
instead of
Av = interp1(Valvekept,Timekept,t,'spline') ;
shouldn't it ?
Star Strider
Star Strider on 9 Jul 2023
@Torsten — Thank you. I didn’t see that (but then I wasn’t looking for it).
That doesn’t affect my previous Comment, that remains the same.

Sign in to comment.

Categories

Find more on Numerical Integration and Differential Equations in Help Center and File Exchange

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!