Prof. Dr. R. Kessler, C:\ro\Si5\Matlab\DGLn\Solver_Vergleich_Pendel.doc, S. 1/1 Homepage: http://www.home.hs-karlsruhe.de/~kero1/ Vergleich mehrerer Solver beim Pendel großer Amplitude Download: http://www.home.hs-karlsruhe.de/%7ekero1/solververgleich/solvpend.zip Bei Google-Suche analytische numerische Lösung DGL War eine der Fundstellen http://iamserver.fms.uni-rostock.de/studium/woernle/technische%2mechanik/numerik.pdf Darin wird als Beispiel das Physikalische Pendel ( Länge l, Masse m, alf, gschwindigkeit w=dalf/dt ) behandelt, also das System der zwei DGLn dalf/dt = w; dw/dt = - g/l * sin(alf). In dem Intenet-Fund wird dies DGL-System mit zwei Matlab-Dateien berechnet, einmal mit Euler, einmal mit ode45. Diese Matlab-Texte kann man aus dem gefundenen PDF-Text mit Maustechnik markieren und kopieren. Daraus wurden zwei eigene Matlab-Dateien erzeugt. Dabei wurden statt der Funktionen (function) im Internet- Fund m-dateien verwendet. Dadurch ist man sehr viel flexibler bei der Parametereingabe. Zusätzlich wurden noch zwei weitere Solver ausprobiert: Mit Simulink der solver ode 45 (mit extern gewählten Parametern reltol und abstol) und mit Matlab der Tephys-Algorithmus (vgl. die unten eingefügte Matlab-Datei). Zum Genauigkeits-Vergleich der eingesamt 4 Solver wurden die berechneten Kurven in die gleiche Figur geplottet. Zunächst einige Aufrufe, danach die Dateien: bild 3, m=.5, l=.3, x1=-179.9, x2=, deltat=.2, relto=1e-11, abstol=1e-11 2-2 2 1-1 5 1 15 2 25-2 5 1 15 2 25 Der clear;m=.5;l=.3;tend=25;x1=-179.9;x2=;bild=2;pendel45k;pause;deltat=.2;reltol=1e-12;abstol=1e-12;pendelk1 Das obere Teilbild zeigt den Pendelwinkel (in Grad) als Funktion der Zeit. Man sieht, dass die blaue Kurve (Euler) schon beim ersten Maximum nach oben verschwindet, also ist die Euler-Methode sehr ungenau. Nicht viel besser ist die Matlab-Methode mit ode45 (schwarze Punkte). Die roten Punkte sind die mit Simulink berechneten Kurven (ode 45, mit reltol=1e-12, abstol=1e-12). Die mit Tephys-Methode berechneten Kurven sind als durchgezogene dicke schwarze Kurven dargestellt. Man erkennt, dass diese dicken schwarzen Kurven (Tephys) bei diesem Aufruf exakt auf den Kurven der roten Punkte (Simulink) liegen. Die Betrachtung mit Zoom würde diese Behauptung betätigen. Beim nächsten Aufruf wurden die Toleranzen für Simulink gröber eingestellt:
Prof. Dr. R. Kessler, C:\ro\Si5\Matlab\DGLn\Solver_Vergleich_Pendel.doc, S. 2/2 bild 4, m=.5, l=.3, x1=-179.9, x2=, deltat=.2, relto=1e-7, abstol=1e-7 2-2 2 1-1 5 1 15 2 25-2 5 1 15 2 25 clear;m=.5;l=.3;tend=25;x1=-179.9;x2=;bild=4;pendel45k;pause;deltat=.2;reltol=1e-8;abstol=1e-8;pendelk1 Man erkennt, dass jetzt die roten Punkte (Simulink) schon nicht mehr exakt auf den dicken schwarzen Kurven (Tephys) liegen. Also rechnet hier Simulink ungenauer als Tephys! Beim nächsten Aufruf wurden die Simulink-Toleranzen noch gröber eingestellt: 2 bild 5, m=.5, l=.3, x1=-179.9, x2=, deltat=.2, relto=1e-6, abstol=1e-6-2 2 1-1 5 1 15 2 25-2 5 1 15 2 25 clear;m=.5;l=.3;tend=25;x1=-179.9;x2=;bild=5;pendel45k;pause;deltat=.2;reltol=1e-7;abstol=1e-7;pendelk1 Man erkennt, dass infolge der hier gewählten Toleranzen (rtol=1e-7 und abstol=1e-7) die Simulink-Kurven deutlich ungenauer sind als die (dick schwarzen) Tephys-Kurven bild 7, m=.5, l=.3, x1=-179.9, x2=, deltat=.2, relto=.1, abstol=.1 2-2 2 1-1 5 1 15 2 25-2 5 1 15 2 25 clear;m=.5;l=.3;tend=25;x1=-179.9;x2=;bild=7;pendel45k;pause;deltat=.2;reltol=1e-5;abstol=1e-5;pendelk1
Prof. Dr. R. Kessler, C:\ro\Si5\Matlab\DGLn\Solver_Vergleich_Pendel.doc, S. 3/3 Hier sind die Toleranzen für Simulink noch schlechter gewählt: reltol=1e-5, abstol=1e-5. Folglich weichen die Simulink-Kurven (rote Punkte) sehr stark von den (genaueren!) schwarzen Tephys-Kurven ab. Anschließend die Dateien: Datei pensim.mdl, ode45, reltol abstol tsim 1/s om 1/s alf Start x2 Start x1*bogen -g/l * sin(u) % ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Hinweis: Die nachfolgenden Matlab-Dateien mögen etwas verwirrend erscheinen. Das liegt daran, dass sie aus den Dateien des Internet-Fundes entstanden sind. Teilweise wurde die Formulierung der Fundstellen beibehalten, zumindest als Kommentare. %Datei Pendel45k.m (statt function). % clear;m=.5;l=.3;tend=5;x1=45;x2=;bild=1; %function Pendel45 % Einfachpendel / Integration mit Runge-Kutta 4. Ordnung (ODE45) % Beispiel von Uni Rostock, gespeichert in c:\ro\si5\matlab\dgln\ % http://iamserver.fms.uni-rostock.de/studium/woernle/technische%2mechanik/numerik.pdf %clear all %global m g l d % Parameter für die private Funktion ableitung: Bogen = pi/18; Grad = 1/Bogen; % Umrechnungen % g=9.81; % Masse, Erdbeschleunigung %l =.3; % Pendellänge % Steht im Aufruf t = ; % Anfangszeit, Endzeit; kein deltat, da Schrittweitensteuerung %x1 = 45; % Anfangswinkel in Grad % Steht im Aufruf %x2 = ; % Anfangswinkelgeschwindigkeit % Steht im Aufruf %------- Aufruf des Integrators [t,x] = ode45(@ableitung, [t, tend], [x1*bogen, x2] ); % Darstellung der Lösung figure(bild); clf; subplot(2,1,1); plot (t,x(:,1)*grad,'.k');grid on; ylabel(''); subplot(2,1,2); plot (t,x(:,2),'.k'); grid on; xlabel(''); ylabel(''); % Die nachfolgenden Funktion wurde getrennt gespeichert als ableitung.m %***************** function ableitung.m ******** %function ableit = ableitung(t,x) % Funktion, in der die Ableitungen berechnet werden (freie Schwingungen) %global m g l d % Parameter %x1d = x(2) ; %x2d = - g/l*sin(x(1)) ; %ableit = [x1d; x2d]; % +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %Datei pendelk1.m
Prof. Dr. R. Kessler, C:\ro\Si5\Matlab\DGLn\Solver_Vergleich_Pendel.doc, S. 4/4 % clear; deltat=.1; bild=1; % Statt function einfache m-datei, dadurch leichter Parametervorgabe %function Pendel % Einfachpendel / Integration mit Euler explizit % Beispiel von Uni Rostock, gespeichert in c:\ro\si5\matlab\dgln\ % http://iamserver.fms.uni-rostock.de/studium/woernle/technische%2mechanik/numerik.pdf %clear all %global deltat format compact; Bogen = pi/18; Grad = 1/Bogen; % Umrechnungen %m =.5; % Steht im Aufruf g=9.81; % Masse, Erdbeschleunigung %l =.3; % Pendellänge % Steht im Aufruf t = ; %tend = 5;% Anfangszeit, % Steht im Aufruf %deltat =.1 ; % Zeitschrittweite % Steht im Aufruf %x1 = 45; % Anfangswinkel in Grad % Steht im Aufruf %x2 = ; % Anfangswinkelgeschwindigkeit % Steht im Aufruf x1 = x1*bogen; x2 = x2; % Umrechnen in Bogenmass % Speicherfelder initialisieren %t_val = [ ]; x1_val = [ ]; x2_val = [ ]; % diese Methode stand im Internet-Fund. Sie verbraucht sehr viel Zeit!! % Plotwerte deklarieren: Diese Methode geht sehr viel schneller!! Np=floor(tend/deltat); tpe=zeros(np,1); x1pe=tpe; x2pe=tpe; k=; for t = t : deltat : tend % Schleife über Zeitschritte % Abspeichern % t_val = [t_val t ]; x1_val = [x1_val x1*grad ]; x2_val = [x2_val x2 ]; % Auch hier meine Methode des Speicherns: k=k+1; tpe(k)=t; x1pe(k)=x1*grad; x2pe(k)=x2; % Berechnung der rechten ODE-Seite (freie Schwingungen) x1d = x2 ; x2d = - g/l*sin(x1) ; % Neue Zeit und Werte x1 = x1 + deltat*x1d ; x2 = x2 + deltat*x2d ; end; % Ende Schleife über Zeitschritte toc % Darstellung der Lösung figure(bild); subplot(2,1,1);hold on; %plot (t_val,x1_val,'b'); grid on;ylabel(''); plot (tpe,x1pe,'b'); grid on;ylabel(''); S1=['bild ',num2str(bild)]; S2=[', m=',num2str(m)];s3=[', l=',num2str(l)]; S4=[', x1=',num2str(x1)]; S5=[', x2=',num2str(x2)];s6=[', deltat=',num2str(deltat)]; S7=[', relto=',num2str(reltol)];s8=[', abstol=',num2str(abstol)]; tit=[s1,s2,s3,s4,s5,s6,s7,s8]; title(tit); axis ([,tend,-3,3]); subplot(2,1,2); hold on;%plot (t_val,x2_val,'b'); grid on; plot (tpe,x2pe,'b'); axis ([,tend,-2,2]); % ++++++++++++++++++++ jetzt Simulink ++++++++ disp('jetzt Simulink: rote Punkte');pause sim('pendsim'); subplot(2,1,1);hold on; plot(tsim,alf*grad,'.m'); subplot(2,1,2);hold on; plot(tsim,om,'.m'); disp('jetzt Tephys(schwarz)');pause
Prof. Dr. R. Kessler, C:\ro\Si5\Matlab\DGLn\Solver_Vergleich_Pendel.doc, S. 5/5 %++++++++++++++++++ Tephys-Methode:++++++++++++++++++++++++++++++ % Plotwerte deklarieren: Np=floor(tend/deltat); tp=zeros(np,1); x1p=tp; x2p=tp; %Startwerte: x1 = x1*bogen; x2=; k=;t=; while t < tend, k=k+1; tp(k)=t; x1p(k)=x1*grad; x2p(k)=x2; x1=x1+x2*deltat; x2=x2+(-g/l *sin(x1))*deltat; t=t+deltat; end; toc set(,'defaultlinelinewidth',1.5); % dicke Kurven subplot(2,1,1);hold on; plot(tp,x1p,'k'); subplot(2,1,2);hold on; plot(tp,x2p,'k'); set(,'defaultlinelinewidth',1); % dünnen Kurven %title(['']); % Ende der Datei pendelk1.m %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Eine neuere Version Matlab-Datei: Enthält den wichtige Hinweis, vor dem ersten Aufruf pend45 aufzurufen, sonst Fehlermeldung Demonstriert die riesige Rechenzeit bei der alten Speichermethode,tEuler(sec)= 3.6885 2-2 2 bild 3, l=.3, x1=-179.9, x2=, deltat=.2, relto=1e-11, abstol=1e-11 5 1 15 2 25-2 5 1 15 2 25 clear;l=.3;tend=25;x1=-179.9;x2=;bild=3;pendel45k;pause;deltat=.2;reltol=1e-12;abstol=1e-12;alt=1;pendelk2 Man erkennt im ylabel des oberen Teilbildes die Rechenzeit teuler = 3.68 sec %Datei pendelk2.m % mit wahlweise der alten Speichermethode (alt=1,wie im Internet-Fund) %oder der neuen Methode (alt=), Siehe Tabelle Rechenzeit in dieser Matlab-Datei %clear;l=.3;tend=25;x1=-179.9;x2=;bild=2;pendel45k;pause;deltat=.8;reltol=1e-12;abstol=1e-12;alt=1;pendelk2 %+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ % Wichtig: Bevor man dies zum ersten mal aufruft, vorher Pendel45 % aufrufen, sonst folgende Fehler-Meldung %??? Error using ==> funfun\private\odearguments % Solving ABLEITUNG requires an initial condition vector of length 1. %+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %clear;l=.3;tend=25;x1=-179.9;x2=;bild=2;deltat=.1;reltol=1e-12;abstol=1e- 12;alt=;pendelk2 % clear; deltat=.1; bild=1;
Prof. Dr. R. Kessler, C:\ro\Si5\Matlab\DGLn\Solver_Vergleich_Pendel.doc, S. 6/6 % Statt function einfache m-datei, dadurch leichter Parametervorgabe %function Pendel % Einfachpendel / Integration mit Euler explizit % Beispiel von Uni Rostock, gespeichert in c:\ro\si5\matlab\dgln\ % http://iamserver.fms.uni-rostock.de/studium/woernle/technische%2mechanik/numerik.pdf %clear all %global deltat format compact; Bogen = pi/18; Grad = 1/Bogen; % Umrechnungen %m =.5; g=9.81; % Masse, Erdbeschleunigung %l =.3; % Pendellänge t = ; %tend = 5;% Anfangszeit, %deltat =.1 ; % Zeitschrittweite %x1 = 45; % Anfangswinkel in Grad %x2 = ; % Anfangswinkelgeschwindigkeit x1 = x1*bogen; x2 = x2; % Umrechnen in Bogenmass % Speicherfelder initialisieren if alt>,t_val = [ ]; x1_val = [ ]; x2_val = [ ];end; %alte Speichermethode % Plotwerte deklarieren: if alt==,np=floor(tend/deltat); tpe=zeros(np,1); x1pe=tpe; x2pe=tpe;end; %neue Speichermethode k=; for t = t : deltat : tend % Schleife über Zeitschritte % Abspeichern if alt> t_val= [t_val t ]; x1_val= [x1_val x1*grad ];x2_val= [x2_val x2 ]; end; % Meine Methode des Speicherns: if alt==,k=k+1; tpe(k)=t; x1pe(k)=x1*grad; x2pe(k)=x2; end; % Berechnung der rechten ODE-Seite (freie Schwingungen) x1d = x2 ; x2d = - g/l*sin(x1) ; % Neue Zeit und Werte x1 = x1 + deltat*x1d ; x2 = x2 + deltat*x2d ; end; % Ende Schleife über Zeitschritte teuler=toc % Darstellung der Lösung figure(bild); subplot(2,1,1);hold on; if alt > plot (t_val,x1_val,'b'); grid on; end; % Die Rechenzeit teuler bei der "alten" Speichermethode steigt % gewaltig an mit kleiner werdender Schrittweite deltat: % deltat teuler(alt=1) teuler(alt=) %.32.19.37 %.16.5.67 %.8.21.13 %.4.85.26 %.2 3.56.54 %.1 17.8.11 %.5 72.7.22 if alt==, plot (tpe,x1pe,'b');end; grid on; ylabel([',teuler(sec)= ',num2str(teuler)]); S1=['bild ',num2str(bild)]; S3=[', l=',num2str(l)]; S4=[', x1=',num2str(x1)];s5=[', x2=',num2str(x2)];s6=[', deltat=',num2str(deltat)]; S7=[', relto=',num2str(reltol)];s8=[', abstol=',num2str(abstol)]; tit=[s1,s3,s4,s5,s6,s7,s8]; title(tit); axis ([,tend,-3,3]);
Prof. Dr. R. Kessler, C:\ro\Si5\Matlab\DGLn\Solver_Vergleich_Pendel.doc, S. 7/7 subplot(2,1,2); hold on; if alt >, plot (t_val,x2_val,'b');end; if alt ==, plot (tpe,x2pe,'b');end; grid on; axis ([,tend,-2,2]); % ++++++++++++++++++++ jetzt Simulink ++++++++ disp('das war Euler(blau),jetzt Simulink: rote Punkte');pause %+++++++++++++ jetzt Simulink ++++++++++++++++++++++++++++ sim('pendsim'); subplot(2,1,1);hold on; plot(tsim,alf*grad,'.m'); subplot(2,1,2);hold on; plot(tsim,om,'.m'); disp('das blaue war Euler, jetzt Tephys(schwarz)');pause %++++++++++++++++++ meine Methode:++++++++++++++++++++++++++++++ % Plotwerte deklarieren: Np=floor(tend/deltat); tp=zeros(np,1); x1p=tp; x2p=tp; %Startwerte: %x1=x1; x1 = x1*bogen; x2=; k=;t=; while t < tend, k=k+1; tp(k)=t; x1p(k)=x1*grad; x2p(k)=x2; x1=x1+x2*deltat; x2=x2+(-g/l *sin(x1))*deltat; t=t+deltat; end; toc set(,'defaultlinelinewidth',1.5); % dicke Kurven subplot(2,1,1);hold on; plot(tp,x1p,'k'); subplot(2,1,2);hold on; plot(tp,x2p,'k'); set(,'defaultlinelinewidth',1); % dünnen Kurven Title(['']); % Ende der Datei pendelk2.m