-1

I have a ODE solver works nice and smooth, but I need to plot all in one figure. Connect figure (1)+(3) and Figure (2)+(4), I have to set start and stop conditions, but it not work for me, I´m at a dead end. I´m trying set the end conditions by x_m with no results.

options = odeset('Events',@events);

[t,y] = ode45(@ph1,[0,w_max],[0,0], options);
figure(1),plot(t,y(:,1));

x_n = y(:,1);
v_n = y(:,2);
x_m = x_n(end);
v_m = v_n(end);
q = max (t);


 d_v1 =diff(y(:,2));    
%d_t1 = diff(t);
%a_c1 = d_v1./d_t1;
 t_c1 = t(1:end-1);
%t_h1 = d_t1./2;

figure (2)
plot((t_c1),d_v1,'r') 
set(gca,'FontName','Times New Roman CE')
title('Rychlost')
xlabel('\it t\rm [s]')
ylabel('\it v_n\rm [m*s^{-1}]')
hold on

[t,y] = ode45(@ph2,[0,w_max],[0,0], options);
figure(3),plot(t,(y(:,1)));

d_v =diff(y(:,2));     
%d_t = diff(t);
%a_c = d_v./d_t;
t_c = t(1:end-1);
%t_h = d_t./2;

figure(4),plot((t_c),(d_v), 'g' );

% d_v2 =diff(d_v);     
% d_t2 = diff(d_t);
% a_c2 = d_v2./(d_t2.*d_t2);
% t_c2 = t(1:end-2);

% figure(5),plot((t_c2),a_c2 , 'r');

function [value,isterminal,direction] = events(t,y)

global ch

value = y(1) - ch;  
isterminal = 1;        
direction = 0;        




function dx = ph1(tt,x)
global F1 c m_c Ff p w s ln f_t sig dstr Ren pn Fex Fzmax xz xn l Fz m_n

Fpp = F1 + c*x(1); 

 if pn<0
     pn=abs(pn);
 end

if x(1)<ln

    pn=spline(w,p,tt)-((2*sig)/dstr*Ren);    
    Fex=3.1416.*f_t.*pn.*(ln-x(1));
end

if x(1)<42e-5
     Fz = Fzmax*(1-(1/xz)*(x(1)+l));   
end

if x(1)>44e-3
    m_c=m_c-m_n;
end


dx=[x(2);((spline(w,p,tt)*s)-Fpp-Ff-Fex-Fz)./m_c];

 function dx=ph2(tt,x)

 global Fv Ft m_z g f Fzp alfa m_nbp c

        Ft=m_z*g*f;
        Fv = 2*f*(Fzp/cos(alfa));

        if x(1)>0.44

        m_z=m_z+m_nbp

        end

        dx = [x(2);((x(1)*c)-Ft-Fv)/m_z];
talonmies
  • 70,661
  • 34
  • 192
  • 269
user2401142
  • 9
  • 1
  • 4

2 Answers2

0

Okay let me say this first: I'm not sure I have an answer as I cant replicate your problem (your code doesnt run...) and for some reason I still can not comment. But I think I can help you.

I. It seems like you are solving two ODEs separately, but both times with the same time vecotr [0 w_max]. You could (and I'd advise that) put both ODEs into one function dx = diffeq(args) and simply make dx a row vector. The problem you might encounter, is that any ODE solver will use different time steps for different mathematical functions. Now you may be tempted to regulate that timestep with 'MaxStep' and 'MinStep', but don't do that. You'll loose speed and accuracy and every advantage of the ODE solvers in matlab compared to simple integrators. You should put the differential equations into the same function even if they are not logically connected at all. It's just easier for you to handle the data.

II. Once you solve both differential equations in the same function and therefore in the same run of ode45/ode23 whatever, they will have exactly the same time vector. Also, the solution vectors will have the same size. Comparing them should be an easy task then. However, I don't understand how you can't "connect" the figures. Because if you always plot with 'plot(x,y)' instead of 'plot(y)', which you do, they should be aligned perfectly. for example:

 figure

 plot(t1,y1)

 hold on

 plot(t2, y2)

You'll notice that I used 't1' and 't2' and you should do the same. In your current code, you're overwriting your first 't' with your second 't', bad for debugging.

III. Just another advice: You are doing stuff like

 x_n = y(:,1);

 v_n = y(:,2);

Instead, you could create a struct for indices and store the variable names in there. Then you never access the variables by number, but only by those indices. For example:

 ind.x_n = 1;

 ind.v_n = 2;

and later in the differential equation: dy(ind.x_n) = ... dy(ind.v_n) = ... it will help you a lot once you have more code and more states.

IV. This brings me to the last point. more states! The stuff you're doing with global variables is very, very bad! It will be almost impossible to debug and you'r code is slowed down. I used once ONE global variable in my diffeq and had a slow down of around 30%.

  • If you have variables, which you need to "survive" one time step, lets say you want to use your old 'F1' in the next step, then you should make a state out of it. This of course implies, that you can actually derive it. I don't know what you're simulating so I can't tell. Just try it!

  • If you have variables, which you only calculate during one time step and also need them only for that certain time step, there's really no need to make the variable global. It does only harm!

I hope that was not too much and that it helped you. If not, please provide a link to a git repository for example with executable code. This way it's just a guessing game...

Potaito
  • 1,181
  • 2
  • 10
  • 32
  • FYI, I don't think your first guess (I.) as to what poster is doing (or trying to do) is right. See [this question](http://stackoverflow.com/questions/16768447/matlab-ode-start-stop-conditions). The two ODEs cannot be simulated simultaneously because the initial conditions of the second depend on the terminating states of the first (via events). Of course the code here does't show that at all or make that clear. – horchler May 28 '13 at 18:52
  • And your discussion of global variables is spot on. There is no reason to be using them here. – horchler May 28 '13 at 18:54
  • @horchler As I've learned, there needs to be a reason to USE global variables, and not vice versa. Function in- and outputs should always work. Especially in this case, where the system is a harmonic oscillator, there are really better options. – Potaito May 28 '13 at 19:59
0

I use this:

yy=y(:,1);
tt=t;
figure(3),plot(t+tt(end),abs((y(end:-1:1,1))),tt,yy);

where (t,y) is from first ODE and (tt,yy) from second. Maybe can help for someone

user2401142
  • 9
  • 1
  • 4