148 Ecuat¸ii diferent¸iale în MATLAB Ecuat¸ia a fost scrisă ca un sistem de două ecuat¸ii de ordinul I, deci g(t,y) = y1. Codul pentru g(t,y) este function [gstop,isterminal,direction] = g(t,y) gstop = y(1); isterminal = 1; direction = 0; Primul argument de ies¸ire, gstop, este valoarea pe care dorim s-o anulăm. Dacă al doilea argument de ies¸ire, isterminal, are valoarea 1, rezolvitorul va termina execut¸ia dacă gstop este zero. Dacă isterminal = 0, evenimentul este înregistrat s¸i rezolvarea continuă. direction poate fi -1, 1 sau 0, după cum zeroul se atinge dacă funct¸ia este descrescătoare, crescătoare sau nemonotonă. Calculul s¸i reprezentarea traiectoriei se poate face cu function falling_body(y0) opts = odeset(’events’,@g); [t,y,tfinal] = ode45(@f,[0,Inf],y0,opts); tfinal plot(t,y(:,1),’-’,[0,tfinal],[1,0],’o’) axis([-0.1, tfinal+0.1, -0.1, max(y(:,1)+0.1)]); xlabel t ylabel y title(’Corp in cadere’) text(tfinal-0.8, 0, [’tfinal = ’ num2str(tfinal)]) Pentru valoarea init¸ială y0=[1; 0] se obt¸ine >> falling_body([1;0]) tfinal = 1.65745691995813 s¸i graficul din figura 6.10. Detect¸ia evenimentelor este utilă în probleme ce presupun fenomene periodice. Problema celor două corpuri este un exemplu bun. Ea descrie orbita unui corp asupra căruia act¸ionează fort¸a gravitat¸ională a unui corp mult mai greu. Utilizând coordonate carteziene, u(t) s¸i v(t) cu originea în corpul mai greu, ecuat¸iile sunt: u ′′ (t) = − u(t) r(t) 3 v ′′ (t) = − v(t) r(t) 3, unde r(t) = u(t) 2 +v(t) 2 . Întreaga rezolvare este cont¸inută într-un singur fis¸ier de tip funct¸ie, orbit.m (sursa MATLAB 6.3). Parametrul de intrare, reltol, este
6.5. Tratarea evenimentelor 149 y 1 0.8 0.6 0.4 0.2 0 Corp in cadere tfinal = 1.6575 0 0.2 0.4 0.6 0.8 t 1 1.2 1.4 1.6 Figura 6.10: Traiectoria unui corp în cădere Sursa MATLAB 6.3 Problema celor două corpuri function orbit(reltol) y0 = [1; 0; 0; 0.3]; opts = odeset(’events’, @gstop,’RelTol’,reltol); [t,y,te,ye] = ode45(@twobody,[0,2*pi], y0, opts, y0); tfinal = te(end) yfinal = ye(end,1:2) plot(y(:,1),y(:,2),’-’,0,0,’ro’) axis([-0.1 1.05 -0.35 0.35]) %---------function ydot = twobody(t,y,y0) r = sqrt(y(1)ˆ2 + y(2)ˆ2); ydot = [y(3); y(4); -y(1)/rˆ3; -y(2)/rˆ3]; %-------function [val,isterm,dir] = gstop(t,y,y0) d = y(1:2)-y0(1:2); v = y(3:4); val = d’*v; isterm = 1; dir = 1;