Numerische Lösung des mathematischen Pendels mit ...
Numerische Lösung des mathematischen Pendels mit ...
Numerische Lösung des mathematischen Pendels mit ...
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
<strong>Numerische</strong> <strong>Lösung</strong> <strong>des</strong> <strong>mathematischen</strong><br />
<strong>Pendels</strong> <strong>mit</strong> verschiedenen Verfahren<br />
Geneviève Grunert (171756)<br />
Paul Ebermann (165588)<br />
2. September 2003<br />
Zusammenfassung<br />
Die Differentialgleichung <strong>des</strong> <strong>mathematischen</strong> <strong>Pendels</strong> wird <strong>mit</strong><br />
dem expliziten Euler-Verfahren und der impliziten Mittelpunktsregel<br />
gelöst und die Ergebnisse <strong>mit</strong> der exakten <strong>Lösung</strong> verglichen.<br />
Es zeigt sich, dass beim expliziten Euler-Verfahren ein ” Energiegewinn“<br />
vorliegt, während die Mittelpunktsregel dieses Problem nicht<br />
hat.
Inhaltsverzeichnis<br />
Aufgabenstellung 2<br />
Physikalische Interpretation der Aufgabenstellung 3<br />
Exakte <strong>Lösung</strong> 4<br />
Analyse der Differentialgleichung . . . . . . . . . . . . . . . . . . . 4<br />
Näherungslösung für kleine Winkel . . . . . . . . . . . . . . . . . . 5<br />
Allgemeiner <strong>Lösung</strong>sansatz . . . . . . . . . . . . . . . . . . . . . . 5<br />
Periodendauer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />
Verfahrensbeschreibung 7<br />
Allgemeines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7<br />
Explizites Eulerverfahren . . . . . . . . . . . . . . . . . . . . . . . 7<br />
Implizite Mittelpunktsregel . . . . . . . . . . . . . . . . . . . . . . 7<br />
Automomer Fall . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />
Einzelschritte per Newton . . . . . . . . . . . . . . . . . . . . 8<br />
Einzelschritte nach Banach . . . . . . . . . . . . . . . . . . . 8<br />
Implementation 9<br />
Rahmenwerk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />
Verfahren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />
Weitere Klassen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18<br />
Exakte <strong>Lösung</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19<br />
Graphen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22<br />
Ergebnisse 23<br />
<strong>Lösung</strong>en . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />
Beobachtung der Hamiltonfunktion und Erklärung . . . . . . . . . 29<br />
Quellenangaben 32<br />
1
Aufgabenstellung – Aufgabe 20<br />
Die Gleichungen<br />
˙p = − sinq<br />
˙q = p<br />
beschreiben die Bewegung <strong>des</strong> <strong>mathematischen</strong> <strong>Pendels</strong> (<strong>mit</strong> der Ortskoordinate<br />
q := x und p := ˙x).<br />
Die Hamiltonfunktion<br />
H(p,q) := 1<br />
2 p2 − cos q<br />
beschreibt die Gesamtenergie <strong>des</strong> Systems. Integrieren Sie das System <strong>mit</strong><br />
• dem expliziten Eulerverfahren und<br />
• der impliziten Mittelpunktsregel<br />
<strong>mit</strong> konstanter Schrittweite auf einem hinreichend großen Zeitintervall.<br />
Überprüfen Sie die numerischen Werte der Hamiltonfunktion für beide Verfahren<br />
und erklären Sie das beobachtete Verhalten.<br />
Stellen Sie die numerischen <strong>Lösung</strong>en, die exakte <strong>Lösung</strong> und die Differenzen<br />
geeignet graphisch dar.<br />
2
Physikalische Interpretation der Aufgabenstellung<br />
Bei unserem <strong>mathematischen</strong> Pendel ist x = q die aktuelle Auslenkung <strong>des</strong><br />
<strong>Pendels</strong> (als Winkel im Bogenmaß) und p = ˙x die aktuelle Winkelgeschwindigkeit.<br />
l<br />
m<br />
q<br />
Ftang<br />
Fgrav<br />
Abbildung 1: Das mathematische Pendel<br />
Bei einer Fadenlänge l und einer Masse m sowie der Fallbeschleunigung<br />
g ergibt sich bei Auslenkungswinkel q und Winkelgeschwindigkeit p eine<br />
absolute Auslenkung von l · sin q, eine tangentiale Geschwindigkeit von l · p.<br />
Es wirkt eine Gravitations-Kraft von Fgrav = m · g auf das Massestück, die<br />
sich in einen tangentialen sowie einen radialen Bestandteil aufspaltet. Dabei<br />
ist<br />
Frad = F · cos q<br />
= m · g · cos q<br />
(der radiale Anteil wird vom Faden aufgefangen) und<br />
Ftang = −F · sin q<br />
= −m · g · sin q<br />
Wegen der Newtonschen Gleichung F = m·a haben wir also eine tangentiale<br />
Beschleunigung von<br />
atang = −g · sinq<br />
3
Da für die tangentiale Beschleunigung aber auch atang = l · ˙p gilt, ergibt<br />
sich schließlich<br />
˙p = − g<br />
l<br />
· sin q<br />
Die Masse m geht in die Gleichung gar nicht ein. Normiert man nun Zeit-<br />
gerade eins ergibt, so erhält man die Gleichung<br />
und Wegeinheiten so, dass g<br />
l<br />
˙p = − sin q.<br />
Da p aber auch die Ableitung von q ist, erhalten wir durch diese Überlegungen<br />
unser Differentialgleichungssystem<br />
Exakte <strong>Lösung</strong><br />
˙p = − sinq<br />
˙q = p.<br />
Analyse der Differentialgleichung<br />
Unsere Differentialgleichung ist eine autonome gewöhnliche Differentialgleichung<br />
der Form<br />
x ′ (t) = f(x(t)).<br />
Bei uns ist hier<br />
f : R 2 → R 2<br />
f(p,q) = (− sin q,p)<br />
Dabei ist f überall stetig differenzierbar <strong>mit</strong><br />
f ′ (p,q) =<br />
� �<br />
0 − cos(q)<br />
1 0<br />
Offensichtlich ist �f ′ (p,q)� 1 = �f ′ (p,q)� ∞ = 1, die Funktion f also global<br />
lipschitzstetig <strong>mit</strong> Lipschitzkonstante 1 (bezüglich dieser Normen).<br />
Das Differentialgleichungssystem erster Ordnung<br />
˙p = − sinq<br />
˙q = p<br />
lässt sich in eine Differentialgleichung zweiter Ordnung umschreiben, wobei<br />
q := x und p := ˙x gesetzt werden (wie in der Interpretation gesehen). Die<br />
Differentialgleichung<br />
¨x = − sinx<br />
hat natürlich die triviale <strong>Lösung</strong> x = 0. Da diese <strong>Lösung</strong> nicht besonders<br />
interessant ist, versuchen wir andere zu finden.<br />
4
Näherungslösung für kleine Winkel<br />
Für kleine Winkel q geht die Differentialgleichung durch die Näherung<br />
sin x ≈ x über in die Differentialgleichung<br />
¨x = −x.<br />
Dies ist eine homogene Differentialgleichung <strong>mit</strong> konstanten Koeffizienten.<br />
Man kann sie also lösen, und die allgemeine reelle <strong>Lösung</strong> ist<br />
x(t) = c1 · sin t + c2 · cos t,<br />
wobei für die Konstanten gilt: c1 = ˙x(0), c2 = x(0). Natürlich kann man die<br />
Konstanten bestimmen, sobald man irgendwelche Anfangswerte hat. Nur<br />
wenn man die Anfangswerte bei t = 0 gegeben hat, so lassen sie sich besonders<br />
leicht ablesen.<br />
Allgemeiner <strong>Lösung</strong>sansatz<br />
Die Differentialgleichung lässt sich umschreiben zu:<br />
�<br />
d 1<br />
dt 2 ˙x2 �<br />
− cos x = 0.<br />
Da<strong>mit</strong> ist 1<br />
2 · ˙x2 − cos x = E eine Konstante. Diese gibt die gesamt Energie<br />
<strong>des</strong> <strong>Pendels</strong> an. Für die exakte <strong>Lösung</strong> ist da<strong>mit</strong> die Hamiltonfunktion<br />
H(p,q) := 1<br />
2 p2 − cos q<br />
konstant. Hat man Anfangswerte gegeben, so ist die Konstante durch diese<br />
bestimmt. Eine <strong>Lösung</strong> der Differentialgleichung löst also in einer Umgebung<br />
J eines Anfangswertes t0, in der die Ableitung nicht Null ist, eine der<br />
Differentialgleichungen<br />
˙x = � 2(E + cos x) oder ˙x = − � 2(E + cos x),<br />
abhängig vom Vorzeichen von ˙x(t0). Beide sind Differentialgleichungen <strong>mit</strong><br />
getrennten Variablen. Nehmen wir an, dass die Ableitung positiv ist. Da<strong>mit</strong><br />
ergibt sich als <strong>Lösung</strong>sansatz:<br />
� x(t)<br />
x(t0)<br />
dξ<br />
� 2(E + cos ξ) =<br />
Dieses Integral ist nicht geschlossen lösbar. Die exakte <strong>Lösung</strong> ist also die<br />
Umkehrfunktion zu<br />
t = H(x) = t0 +<br />
� x(t)<br />
x(t0)<br />
5<br />
� t<br />
t0<br />
dt.<br />
dξ<br />
� 2(E + cos ξ) .
Setzt man t0 = 0 und bestimmt E dadurch, daß man man einen Wert q0 für<br />
x(t) einsetzt, an dem die Ableitung verschwindet, so ist E = − cos q0. Dann<br />
erhält man für H die Form<br />
H(x) =<br />
� x(t)<br />
x(0)<br />
dξ<br />
� 2(− cos q0 + cos ξ) .<br />
Die lokale <strong>Lösung</strong> kann periodisch auf ganz R fortgesetzt werden (siehe [1]).<br />
Die Umkehrfunktion dieses elliptischen Integrals erster Gattung heißt Jacobische<br />
Amplitudenfunktion.<br />
Periodendauer<br />
Als Periode ergibt sich<br />
2 ξ<br />
Setzt man cos ξ = 1 − 2sin 2<br />
elliptischen Integrals<br />
� q0 dξ<br />
T = 4 √ .<br />
0 cos ξ − cos q0<br />
� π<br />
2<br />
T = 4<br />
0<br />
ein, so ergibt sich die Standardform eines<br />
dξ<br />
�<br />
2 q0 1 − sin 2 · sin2 .<br />
ξ<br />
Dies kann man in einer Reihe entwickeln. Denn es gilt:<br />
1<br />
�<br />
2 q0 1 − sin 2 · sin2 =<br />
ξ<br />
∞�<br />
(−1) n ·<br />
n=0<br />
� − 1<br />
2<br />
n<br />
�<br />
2n q0<br />
· sin<br />
2 · sin2n ξ<br />
Diese Reihe kann man gliedweise integrieren, da sie absolut konvergiert.<br />
Dann ergibt sich schließlich<br />
� � �2 1 2 q0<br />
T = 2π · 1 + · sin<br />
2 2 +<br />
� � �<br />
2<br />
1 · 3 4 q0<br />
· sin + · · · .<br />
2 · 4 2<br />
6
Verfahrensbeschreibung<br />
Allgemeines<br />
Wir betrachten hier allgemein die gewöhnliche Differentialgleichung <strong>mit</strong> Anfangswertproblem<br />
x ′ (t) = f(x(t),t), x(t0) = x0,<br />
sowie den Spezialfall einer autonomen gewöhnlichen Differentialgleichung,<br />
x ′ (t) = f(x(t)), x(t0) = x0.<br />
(In unserem Fall <strong>des</strong> <strong>mathematischen</strong> <strong>Pendels</strong> haben wir es ja <strong>mit</strong> einer<br />
autonomen Gleichung zu tun.)<br />
Unsere Verfahren bestimmen nun für ein Intervall [t0,tN] eine (endliche)<br />
Folge {xi} N<br />
i=0 von Näherungswerten der Funktionswerte der exakten<br />
<strong>Lösung</strong> {x(ti)} N<br />
i=0 , wobei wir hier die äquidistanten Stützstellen<br />
, betrachten.<br />
ti = ti−1 + h = t0 + h · i, h = tN −t0<br />
N<br />
Explizites Eulerverfahren<br />
Das explizite Eulerverfahren gehört zur Klasse der k-Schritt-Verfahren, es<br />
ist nämlich das einzige explizite 1-Schritt-Verfahren. Die Verfahrensformel<br />
ist allgemein<br />
xl+1 = xl + h · f(xl,tl)<br />
und im autonomen Fall<br />
Implizite Mittelpunktsregel<br />
xl+1 = xl + h · f(xl). (1)<br />
Die implizite Mittelpunktsregel gehört nicht zur Klasse der in der Vorlesung<br />
behandelten k-Schrittverfahren, ist aber de facto auch ein 1-Schritt-<br />
Verfahren, da für jeden Schritt nur das Ergebnis <strong>des</strong> vorherigen Schrittes<br />
notwendig ist, keine früheren Schritte.<br />
Die Verfahrensformel ist hier<br />
�<br />
xl + xl+1<br />
xl+1 = xl + h · f ,<br />
2<br />
tl<br />
�<br />
+ tl+1<br />
2<br />
Offensichtlich ist das kein explizites Verfahren, da die Funktion am Mittelpunkt<br />
zwischen dem (schon bekannten) xl und (noch zu bestimmenden)<br />
xl+1 ausgewertet wird (ebenfalls <strong>mit</strong> Mittelpunkt der Parameter-Werte).<br />
7
Automomer Fall<br />
Da wir es in unserem Fall <strong>mit</strong> einer autonomen Differentialgleichung zu tun<br />
haben, vereinfachen sich die Formeln etwas. Die implizite Mittelpunktsregel<br />
wird zu<br />
� �<br />
xl + xl+1<br />
xl+1 = xl + h · f<br />
(2)<br />
2<br />
Da wir es <strong>mit</strong> einem impliziten Verfahren zu tun haben, können wir nicht<br />
die Ergebnisse xl+1 der Einzelschritte nicht einfach hinschreiben, sondern<br />
müssen die Gleichung (2) numerisch lösen. Dafür bieten sich zwei Varianten<br />
an.<br />
Einzelschritte per Newton<br />
Da sich unsere Funktion f leicht differenzieren lässt, könnten wir das Newtonverfahren<br />
verwenden.<br />
Mit g(y) := xl − y + h · f �xl+y �<br />
müssten wir also eine Nullstelle von g<br />
2<br />
finden. Hierbei könnten wir y0 := xl als Startwert nehmen, und verwendeten<br />
dann die normale Newtoniteration<br />
yj+1 = yj + zj, wobei zj <strong>Lösung</strong> von g ′ (yj) · zj = −f(yj).<br />
Auch eine Variante <strong>des</strong> Newtonverfahrens, wie ein Sekantenverfahren, wäre<br />
denkbar.<br />
Einzelschritte nach Banach<br />
Eine einfachere Variante ist eine Fixpunkt-Iteration nach Banach: Wir betrachten<br />
die Funktion<br />
k : R n → R n<br />
� �<br />
xl + y<br />
k(y) := xl + h · f<br />
2<br />
Offensichtlich ist jeder Fixpunkt dieser Funktion eine <strong>Lösung</strong> für (2) und<br />
umgekehrt.<br />
Da unser f lipschitzstetig war, ist dies ebenso für k der Fall. Für h < 2<br />
ist k kontraktierend, und die Iteration<br />
yi+1 := k(yi)<br />
� �<br />
xl + yi<br />
= xl + h · f<br />
2<br />
konvergiert (bei beliebigem Startwert) gegen den einzigen Fixpunkt (also<br />
xl+1).<br />
In unserem Programm wurde die Banach-Iteration verwendet, die zwar<br />
langsamer ist, aber leichter implementierbar (man muss keine Inverse einer<br />
Matrix bestimmen, das Ableiten kann man sich auch sparen).<br />
8
Implementation<br />
Wir haben uns für die <strong>Lösung</strong> autonomer Differentialgleichungen <strong>mit</strong> verschiedenen<br />
1-Schritt-Verfahren ein Framework erstellt.<br />
Rahmenwerk<br />
Ein Verfahren muss jeweils das Interface Verfahren implementieren.<br />
101 package semesterarbeit.programme;<br />
102<br />
103 /**<br />
104 * Ein 1-Schritt-Verfahren zur <strong>Lösung</strong> von Autonomen<br />
105 * Differentialgleichungen.<br />
106 *<br />
107 * @author Paul Ebermann, Geneviève Grunert<br />
108 * @version 1.0<br />
109 */<br />
110 public interface Verfahren<br />
111 {<br />
112<br />
113 /**<br />
114 * Setzt die Schrittweite fest.<br />
115 */<br />
116 public void setSchrittweite(double h);<br />
117<br />
118 /**<br />
119 * Setzt die Funktion der Differentialgleichung fest.<br />
120 */<br />
121 public void setDGL(AutonomeDGL f);<br />
122<br />
123 /**<br />
124 * Berechnet aus einem alten Wert einen neuen nach<br />
125 * der Verfahrensgleichung.<br />
126 * @param x der alte reelle Wertevektor<br />
127 * @return der neue relle Vektor, der sich aus der<br />
128 * Verfahrensvorschrift ergibt.<br />
129 */<br />
130 public double[] verfahrensSchritt(double[] x);<br />
131<br />
132 } // Verfahren<br />
Eine zu lösende Differentialgleichung (ohne Anfangswert) dagegen hat<br />
das Interface AutonomeDGL zu implementieren – das ist ein Subinterface von<br />
RHochNFunktion.<br />
9
201 package semesterarbeit.programme;<br />
202<br />
203 /**<br />
204 * Eine Funktion R^n --> R^n.<br />
205 * In anderer Betrachtungsweise ein Vektorfeld<br />
206 * auf dem R^n.<br />
207 *<br />
208 * @author Geneviève Grunert, Paul Ebermann<br />
209 * @version PPS 1.1.5<br />
210 */<br />
211 public interface RHochNFunktion<br />
212 {<br />
213<br />
214 /**<br />
215 * Berechnet den Wert <strong>des</strong> Vektorfel<strong>des</strong><br />
216 * an der angegebenen Stelle.<br />
217 *<br />
218 * @param x ein reller Vektor, möglichst im<br />
219 * Definitionsbereich der Funktion<br />
220 * @return der Funktionwert an der Stelle x<br />
221 */<br />
222 public double[] berechne(double[] x);<br />
223<br />
224 }// RHochNFunktion<br />
301 package semesterarbeit.programme;<br />
302<br />
303 /**<br />
304 * Diese Schnittstelle modelliert eine<br />
305 * autonome Differentialgleichung. Dies ist eine<br />
306 * Differentialgleichung der Form<br />
307 *<br />
308 * x’(t) = f(x(t)),<br />
309 *<br />
310 * wobei wir nur differenzierbare Funktionen<br />
311 * f : R^n --> R^n<br />
312 * betrachten. Diese Schnittstelle stellt die Funktion<br />
313 * f (vererbt von {@link RHochNFunktion})<br />
314 * und deren Ableitung Df zur Verfügung.<br />
315 *<br />
316 * Man kann eine solche Differentialgleichung z.B. als<br />
317 * differenzierbares Vektorfeld auffassen, die <strong>Lösung</strong>en<br />
318 * sind dann Flüsse <strong>des</strong> Vektorfel<strong>des</strong>.<br />
319 *<br />
10
320 * @author Paul Ebermann, Geneviève Grunert<br />
321 * @version PPS 1.1.5<br />
322 */<br />
323 interface AutonomeDGL extends RHochNFunktion<br />
324 {<br />
325<br />
326 /**<br />
327 * Die ableitung()-Methode stellt<br />
328 * das Differential <strong>des</strong> Vektorfel<strong>des</strong> zur Verfügung.<br />
329 *<br />
330 * (Dies ist hilfreich, um etwa das Newton-Verfahren<br />
331 * anwenden zu können ...)<br />
332 */<br />
333 public double[][] ableitung(double[] x);<br />
334 }<br />
335<br />
Außerdem kann man noch verschiedene Ausgabeeinheiten benutzen - um<br />
etwa daraus eine Animation zu erstellen oder eine Grafik. Wir nutzen das,<br />
um einmal die Auslenkung und einmal die Werte der Hamilton-Funktion<br />
auszugeben.<br />
401 package semesterarbeit.programme;<br />
402<br />
403 /**<br />
404 * Ausgabe - Schnittstelle, welche von<br />
405 * {@link Verfahrensanwender#berechneMit} verwendet wird,<br />
406 * um die Ergebnisse eines Verfahrens auszugeben.<br />
407 *<br />
408 * Eine Implementation dieser Schnittstelle bekommt<br />
409 * jeden Zwischenwert durch Aufruf der output-Methode<br />
410 * gemeldet. Was sie da<strong>mit</strong> anfängt, ist Privatsache ...<br />
411 */<br />
412 public interface Ausgabe<br />
413 {<br />
414<br />
415 /**<br />
416 * Gibt einen Datensatz aus.<br />
417 *<br />
418 * @param t der Zeitpunkt<br />
419 * @param xVonT der Funktionswert zu diesem Zeitpunkt.<br />
420 */<br />
421 public void output(double t, double[] xVonT);<br />
422<br />
11
423 /**<br />
424 * Beendet die Ausgabe.<br />
425 */<br />
426 public void close();<br />
427<br />
428 }// Ausgabe<br />
Den Kern unseres Systems bildet die Klasse Verfahrensanwender.<br />
Sie löst eine Anfangswertaufgabe (bestehend aus Problem, Anfangswert,<br />
Schrittweite und Intervall) <strong>mit</strong> einem gegebenen Verfahren und gibt Ergebnisse<br />
an eine Ausgabeeinheit. Alle diese Parameter können unabhängig<br />
voneinander gewählt werden.<br />
501 package semesterarbeit.programme;<br />
502<br />
503 /**<br />
504 * Verfahrensanwender - wendet Verfahren auf ein Problem an<br />
505 * und sorgt für eine Ausgabe der Ergebnisse.<br />
506 *<br />
507 * Im Konstruktor wird Problem, Intervall<br />
508 * und Schrittweite angegeben, danach kann mehrfach <strong>mit</strong><br />
509 * verschiedenen Verfahren und Ausgabeeinheiten eine <strong>Lösung</strong><br />
510 * berechnet werden.<br />
511 *<br />
512 * @author Paul Ebermann, Geneviève Grunert<br />
513 * @version 1.0<br />
514 */<br />
515 public class Verfahrensanwender {<br />
516<br />
517 /**<br />
518 * Die Differentialgleichung<br />
519 */<br />
520 private final AutonomeDGL dgl;<br />
521 /**<br />
522 * Der Anfangswert<br />
523 */<br />
524 private final double[] anfang;<br />
525 /**<br />
526 * Das Problem soll im Intervall [0, zeit] gelöst<br />
527 * werden.<br />
528 */<br />
529 private final double zeit;<br />
530 /**<br />
531 * Die Schrittweite.<br />
12
532 */<br />
533 private final double h;<br />
534<br />
535 /**<br />
536 * Dieser Konstruktor erstellt einen Verfahrensanwender<br />
537 * für ein gegebenes Anfangswertproblem, Intervall und<br />
538 * Schrittweite.<br />
539 */<br />
540 public Verfahrensanwender(AutonomeDGL dgl,<br />
541 double[] anfangswert,<br />
542 double zeitdauer,<br />
543 double schrittweite)<br />
544 {<br />
545 this. dgl = dgl;<br />
546 this.anfang = anfangswert;<br />
547 this.zeit = zeitdauer;<br />
548 this.h = schrittweite;<br />
549 }<br />
550<br />
551 /**<br />
552 * Berechnet eine <strong>Lösung</strong> (bzw. eine Approximation<br />
553 * an eine solche) <strong>mit</strong>tels <strong>des</strong> gewählten Verfahrens<br />
554 * und gibt die <strong>Lösung</strong> an die gewählte Ausgabeeinheit<br />
555 * aus.<br />
556 *<br />
557 * Es wird dem Verfahren <strong>mit</strong>geteilt, um welche<br />
558 * Differentialgleichung es sich handelt, sowie welche<br />
559 * Schrittweite verwendet werden soll.<br />
560 *<br />
561 * Dann wird wiederholt die verfahrensSchritt()-Methode<br />
562 * <strong>des</strong> Verfahrens ausgeführt, als Parameter jeweils<br />
563 * das Ergebnis <strong>des</strong> vorherigen Schrittes (am Anfang<br />
564 * der Anfangswert).<br />
565 *<br />
566 * Nach jedem Verfahrens-Schritt (und vor dem ersten)<br />
567 * wird die aktuelle Zeit sowie das Ergebniss <strong>des</strong><br />
568 * Schrittes an die output()-Methode der<br />
569 * Ausgabe-Einheit übergeben.<br />
570 * Am Ende wird noch deren close()-Methode aufgerufen.<br />
571 */<br />
572 void berechneMit(Verfahren verf, Ausgabe ausgabe)<br />
573 {<br />
574 verf.setDGL(dgl);<br />
575 verf.setSchrittweite(h);<br />
13
576 double[] werte = anfang;<br />
577<br />
578 // Anfangswert ausgeben<br />
579 ausgabe.output(0, werte);<br />
580<br />
581 for (double t = 0; t < zeit; t += h)<br />
582 {<br />
583 // Einen Schritt ausführen ...<br />
584 werte = verf.verfahrensSchritt(werte);<br />
585<br />
586 // Ergebnis ausgeben<br />
587 ausgabe.output(t+h, werte);<br />
588 }<br />
589<br />
590 // Abschluss der Ausgabe<br />
591 ausgabe.close();<br />
592 }<br />
593<br />
594 }<br />
Durch diese Konstruktion ist unser Rahmenwerk flexibel einsetzbar. Man<br />
kann sowohl die Differentialgleichung als auch die Verfahren austauschen,<br />
gleiches gilt für die Ausgabeeinheiten.<br />
Verfahren<br />
Die Klasse Eulerverfahren implementiert das explizite Eulerverfahren.<br />
601 package semesterarbeit.programme;<br />
602<br />
603 /**<br />
604 * Implementation <strong>des</strong> expliziten Eulerverfahrens.<br />
605 *<br />
606 * Die Methoden sind im Interface {@link Verfahren}<br />
607 * spezifiziert (und ansonsten ist auch der Name<br />
608 * recht aussagekräftig).<br />
609 *<br />
610 * @author Geneviève Grunert, Paul Ebermann<br />
611 * @version 1.0<br />
612 */<br />
613 public class Eulerverfahren implements Verfahren<br />
614 {<br />
615<br />
616 private double h;<br />
617 private AutonomeDGL f;<br />
14
618<br />
619 public void setSchrittweite(double h)<br />
620 {<br />
621 this.h = h;<br />
622 }<br />
623<br />
624 public void setDGL(AutonomeDGL dgl)<br />
625 {<br />
626 this.f = dgl;<br />
627 }<br />
628<br />
629 /**<br />
630 * Verfahrensvorschrift:<br />
631 *<br />
632 * x_(l+1) = x_l + h * f(x_l)<br />
633 */<br />
634 public double [] verfahrensSchritt(double[] a)<br />
635 {<br />
636 // f(x_l)<br />
637 double[] ergF = f.berechne(a);<br />
638<br />
639 // x_l + h * f(x_l)<br />
640 return VektorTools.plus(a,<br />
641 VektorTools.mal(h, ergF));<br />
642 }<br />
643<br />
644 }<br />
Die Klasse MittelpunktBanach implementiert die Mittelpunktsregel über<br />
eine Banach-Fixpunkt-Iteration.<br />
701 package semesterarbeit.programme;<br />
702<br />
703 /**<br />
704 * Implizite Mittelpunktsregel <strong>mit</strong>tels<br />
705 * Banach-Iteration.<br />
706 *<br />
707 * Die Methoden sind in {@link Verfahren} beschrieben.<br />
708 *<br />
709 * @author Geneviève Grunert, Paul Ebermann<br />
710 */<br />
711 public class MittelpunktBanach implements Verfahren<br />
712 {<br />
713<br />
714 private double h;<br />
15
715 private AutonomeDGL dgl;<br />
716 private BanachIteration banach;<br />
717<br />
718 public void setSchrittweite(double d)<br />
719 {<br />
720 this.h = d;<br />
721 this.banach = new BanachIteration(0.000001*d);<br />
722 }<br />
723<br />
724 public void setDGL(AutonomeDGL autonomeDGL)<br />
725 {<br />
726 this.dgl = autonomeDGL;<br />
727 }<br />
728<br />
729 public double[] verfahrensSchritt(final double[] alt)<br />
730 {<br />
731 // Funktion erstellen, deren Fixpunkt<br />
732 // zu finden ist.<br />
733 RHochNFunktion k = new RHochNFunktion() {<br />
734 public double[] berechne(double[] y)<br />
735 {<br />
736 // fMitte = f( (alt+y)/2 )<br />
737 double[] fMitte =<br />
738 dgl.berechne(VektorTools.<strong>mit</strong>telwert<br />
739 (alt, y));<br />
740<br />
741 // k(y) := alt + h * fMitte<br />
742 return<br />
743 VektorTools.plus<br />
744 ( alt,<br />
745 VektorTools.mal(h, fMitte)<br />
746 );<br />
747 }<br />
748 };<br />
749 // Banachverfahren auf k ansetzen<br />
750 return banach.findeFixpunkt(k, alt);<br />
751 }<br />
752<br />
753 }<br />
Die Banach-Fixpunkt-Iteration wird dabei durch die Klasse<br />
BanachIteration übernommen.<br />
801 package semesterarbeit.programme;<br />
802<br />
16
803 /**<br />
804 * Das Fixpunktverfahren nach Banach.<br />
805 *<br />
806 * @author Geneviève Grunert, Paul Ebermann<br />
807 */<br />
808 public class BanachIteration<br />
809 {<br />
810<br />
811 final double epsilon;<br />
812<br />
813 /**<br />
814 * @param epsilon Eine Iteration wird abgebrochen,<br />
815 * sobald der Fixpunkt (bezüglich oo-Norm) besser<br />
816 * als epsilon approximiert ist (für diese<br />
817 * Abschätzung wird die Kontraktivität der<br />
818 * Abbildung benötigt).<br />
819 */<br />
820 public BanachIteration(double epsilon)<br />
821 {<br />
822 this.epsilon = epsilon;<br />
823 }<br />
824<br />
825<br />
826 /**<br />
827 * Er<strong>mit</strong>telt einen Fixpunkt durch Banach-Iteration.<br />
828 * Da<strong>mit</strong> das konvergiert, sollte die Abbildung<br />
829 * kontraktierend (d.h. Lipschitzkonstante < 1)<br />
830 * sein.<br />
831 *<br />
832 * @param f die Funktion, deren Fixpunkt gefunden<br />
833 * werden soll<br />
834 * @param startwert der Startwert der Iteration<br />
835 * @return eine Approximation <strong>des</strong> Fixpunktes<br />
836 */<br />
837 public double[] findeFixpunkt(RHochNFunktion f,<br />
838 double[] startwert)<br />
839 {<br />
840 double[] alt;<br />
841 double[] neu = startwert;<br />
842 do<br />
843 {<br />
844 alt = neu;<br />
845 neu = f.berechne(alt);<br />
846 } while(abstandGrößer(alt, neu));<br />
17
847 return neu;<br />
848 }<br />
849<br />
850 /**<br />
851 * Testet, ob der Abstand zweier reeller Vektoren<br />
852 * bezüglich der oo-Norm größer als epsilon ist.<br />
853 * @param a ein reeller Vektor<br />
854 * @param b ein weiterer reeller Vektor<br />
855 * @return wahr oder falsch<br />
856 */<br />
857 private boolean abstandGrößer(double[] a, double[] b)<br />
858 {<br />
859 for (int i = 0; i < a.length; i++)<br />
860 {<br />
861 if (Math.abs(a[i] - b[i]) > epsilon)<br />
862 {<br />
863 return true;<br />
864 }<br />
865 }<br />
866 return false;<br />
867 }<br />
868<br />
869 }<br />
Weitere Klassen<br />
Wir brauchen natürlich noch unsere Differentialgleichung, da<strong>mit</strong> das Programm<br />
weiß, was gelöst werden soll:<br />
901 package semesterarbeit.programme;<br />
902<br />
903 /**<br />
904 * Die Differentialgleichung eines <strong>mathematischen</strong><br />
905 * (Faden-)<strong>Pendels</strong> im einfachsten Fall.<br />
906 *<br />
907 * p’ = - sin q<br />
908 * q’ = p<br />
909 *<br />
910 * @author Geneviève Grunert, Paul Ebermann<br />
911 */<br />
912 public class PendelGleichung<br />
913 implements AutonomeDGL {<br />
914<br />
915 /**<br />
18
916 * Die Funktion der Pendel-Gleichung.<br />
917 *<br />
918 * f(p, q) = ( - sin(q), p)<br />
919 *<br />
920 */<br />
921 public double[] berechne(double[] x)<br />
922 {<br />
923 return new double[]{ - Math.sin(x[1]), x[0] };<br />
924 }<br />
925<br />
926<br />
927 /**<br />
928 * Die Ableitung der Pendel-Gleichung.<br />
929 *<br />
930 * Das ist die Matrix<br />
931 *<br />
932 * f’(p,q) = ( 0 -cos(q) )<br />
933 * ( 1 0 ).<br />
934 */<br />
935 public double[][] ableitung(double[] x)<br />
936 {<br />
937 return new double[][]<br />
938 {<br />
939 { 0, - Math.cos(x[1]) },<br />
940 { 1, 0},<br />
941 };<br />
942 }<br />
943<br />
944<br />
945 } // PendelGleichung<br />
Weiterhin gibt es 2 Ausgabe-Klassen, um Zeit-Auslenkung bzw. Zeit-<br />
Hamilton in Dateien zu schreiben und eine Beispiel-Klasse, um alles zusammenzuführen<br />
(es wird ein spezielles Anfangswertproblem und Intervall<br />
gewählt, und <strong>mit</strong> verschiedenen Schrittweiten und Verfahren gelöst). Diese<br />
Klassen nehmen wir jetzt nicht im Quelltext auf, da die Implementation<br />
kanonisch ist (und nichts <strong>mit</strong> dem eigentlichen Problem zu tun hat).<br />
Exakte <strong>Lösung</strong><br />
Die exakte <strong>Lösung</strong> sowie die Differenzen der exakten <strong>Lösung</strong> zu unseren<br />
Näherungslösungen haben wir von Mathematica berechnen lassen. Hier die<br />
Eingabedaten:<br />
1 (***********************************************<br />
19
2 ( Mathematica-Eingabedatei, um die exakte<br />
3 ( <strong>Lösung</strong> der Pendelgleichung sowie die<br />
4 ( Differenzen der exakten <strong>Lösung</strong> zu unseren<br />
5 ( Näherungslösungen zu bestimmen.<br />
6 (<br />
7 ( Anwendung per<br />
8 (<br />
9 ( math < mathinput.m<br />
10 (<br />
11 ***********************************************)<br />
12<br />
13 (*********** Anfangswert *********************)<br />
14<br />
15 phi0 := 0.3<br />
16<br />
17 (************ die exakte <strong>Lösung</strong> ****************)<br />
18<br />
19 kappa := 1/Sin[phi0/2]<br />
20 f[t_] := Re[2 JacobiAmplitude[t/kappa +<br />
21 EllipticF[phi0/2, kappa^2],<br />
22 kappa^2]]<br />
23 (*** Re[] ist notwendig, weil sonst immer *)<br />
24 (*** ein (kleiner) imaginärer Anteil entsteht, *)<br />
25 (*** wo<strong>mit</strong> unser Plot-Programm nicht klarkommt. *)<br />
26<br />
27 (*** Das Intervall (<strong>mit</strong> Schrittweite 0.5) *)<br />
28<br />
29 r := Range[0, 60, 0.5]<br />
30<br />
31 (********** Ausgabe der exakten <strong>Lösung</strong>en **********)<br />
32<br />
33 (** Verzeichnis wechseln ****)<br />
34<br />
35 SetDirectory["plots"];<br />
36<br />
37 g[t_] := {t, f[t]}<br />
38 SetAttributes[g, Listable]<br />
39 Export["exakt2.plot", N[g[r]], "List"]<br />
40<br />
41 (*** Jetzt noch der Hamilton-Operator davon - *)<br />
42 (*** der ist natürlich konstant. *)<br />
43<br />
44 h[t_] := {t, - Cos[phi0] }<br />
45 SetAttributes[h, Listable]<br />
20
46 Export["hamExakt.plot", N[h[r]], "List"]<br />
47<br />
48 (*** Jetzt wollen wir noch die exakte <strong>Lösung</strong> *)<br />
49 (*** <strong>mit</strong> den Näherungen vergleichen. *)<br />
50<br />
51 (** Unsere Differenz-Funktion *)<br />
52 d[t_, x_] := { t, x - f[t] }<br />
53<br />
54 dateien := FileNames[{"euler*.plot", "banach*.plot"}]<br />
55<br />
56 (*** Jetzt eine Schleife über alle Dateien ... *)<br />
57 Do[<br />
58<br />
59 name = dateien[[i]];<br />
60 liste = Import[name, "List"];<br />
61<br />
62 (* Das ist jetzt eine Liste <strong>mit</strong> abwechselnd<br />
63 Zeit und Näherung dazu *)<br />
64<br />
65 liste = Partition[liste, 2];<br />
66<br />
67 (* Jetzt haben wir eine Liste aus<br />
68 zweielementigen Listen, jeweils Zeit und<br />
69 Näherung *)<br />
70<br />
71 (*** Ersetze die Einzel-Listen (Tiefe: 1)<br />
72 durch eine Anwendung von d. *)<br />
73 liste = Apply[d, liste, {1}];<br />
74<br />
75 (* Jetzt haben wir eine Liste aus<br />
76 zweielementigen Listen, jeweils Zeit<br />
77 und Differenz *)<br />
78<br />
79 (* Beim Dateinamen wird einfach vorne<br />
80 ein D angehängt. **)<br />
81<br />
82 Export["D" name, liste, "List"]<br />
83<br />
84 (* Das ganze machen wir für alle i<br />
85 von 1 bis Anzahl der Dateien. *)<br />
86<br />
87 , {i, Length[dateien] }]<br />
88<br />
89 (* Wieder zurückwechseln *)<br />
21
90<br />
91 ResetDirectory[];<br />
92<br />
93 (*<br />
94 *** Local Variables:<br />
95 *** mode: fundamental<br />
96 *** End:<br />
97 *)<br />
Graphen<br />
Die Ausgabe der Graphen (sowohl der exakten <strong>Lösung</strong> als auch der numerischen)<br />
erfolgte jeweils als Wertetabelle und wurde in dieses Dokument<br />
<strong>mit</strong>tels <strong>des</strong> PSTricks-\fileplot-Befehls eingebunden.<br />
Das komplette Dokument kann <strong>mit</strong> dem createPS-Skript aus den Quelltexten<br />
erstellt werden (zumin<strong>des</strong>t auf den Computern im Mathe-Pool).<br />
22
Ergebnisse<br />
<strong>Lösung</strong>en<br />
In den folgenden Bildern ist jeweils ein Plot der p-Werte der exakten <strong>Lösung</strong><br />
(dünn gepunktet), der <strong>Lösung</strong> <strong>des</strong> impliziten Mittelpunktverfahrens (durchgezogen)<br />
und der <strong>Lösung</strong> <strong>des</strong> expliziten Eulerverfahrens 1 (gestrichelt) zu<br />
sehen, jeweils <strong>mit</strong> Startwert q(0) = 0.3, p(0) = 0 im Intervall [0,60] (auf der<br />
t-Achse sind also die Einteilungen <strong>mit</strong> 10 zu multiplizieren).<br />
1<br />
0<br />
−1<br />
−2<br />
1 2 3 4 5 6<br />
Abbildung 2: <strong>Lösung</strong>en <strong>mit</strong> h = 0.1<br />
Die Schrittweiten variieren zwischen den Bildern, wir fangen an <strong>mit</strong><br />
Schrittweite h = 0.1 (Abbildung 2). Man erkennt, dass die <strong>Lösung</strong> nach<br />
Mittelpunktsregel auch auf langen Intervallen gut <strong>mit</strong> der exakten <strong>Lösung</strong><br />
übereinstimmt, während das explizite Eulerverfahren sowohl eine wachsende<br />
Amplitude als auch eine wachsende Periodendauer aufweist.<br />
Abbildung 3 zeigt die Differenzen 〈Verfahrenslösung〉−〈exakte <strong>Lösung</strong>〉.<br />
Betrachten wir die gleichen Verfahren bei h = 0.05 (Abbildung 4).<br />
Bei der Mittelpunktsregel ist kein Unterschied zu bemerken, während das<br />
explizite Eulerverfahren sich deutlich verbessert. Dies erkennt man auch gut,<br />
wenn man sich die Differenzen zur exakten <strong>Lösung</strong> ansieht (Abbildung 5).<br />
Betrachten wir das Eulerverfahren <strong>mit</strong> noch einmal kleinerer Schrittweite<br />
h = 0.01 (Abbildung 6, Differenz in Abbildung 7), dann erkennt man, dass<br />
1 Im folgenden wird nur noch ” Mittelpunktsregel“ und ” Eulerverfahren“ verwendet, das<br />
Wort ” implizit“ bzw. ” explizit“ sei hier implizit enthalten.<br />
23
1<br />
0<br />
−1<br />
−2<br />
1<br />
0<br />
−1<br />
−2<br />
1 2 3 4 5 6<br />
Abbildung 3: Differenzen bei h = 0.1<br />
1 2 3 4 5 6<br />
Abbildung 4: <strong>Lösung</strong>en bei h = 0.05<br />
24
1<br />
0<br />
−1<br />
−2<br />
1<br />
0<br />
−1<br />
−2<br />
1 2 3 4 5 6<br />
Abbildung 5: Differenzen bei h = 0.05<br />
1 2 3 4 5 6<br />
Abbildung 6: Euler bei h = 0.01<br />
25
1<br />
0<br />
−1<br />
−2<br />
1 2 3 4 5 6<br />
Abbildung 7: Euler-Differenz bei h = 0.01<br />
es um einiges besser wird.<br />
Vergrößern wir dagegen die Schrittweite auf h = 0.2, so gerät Euler völlig<br />
außer Kontrolle (es gibt einen ” Überschlag“), während unsere Mittelpunktsregel<br />
sich friedlich verhält (Abbildung 8).<br />
Bei noch größeren Schrittweiten (Abbildung 10, durchgezogen: h = 0.5,<br />
gestrichelt: h = 0.8) merkt man allerdings auch der Mittelpunktsregel an,<br />
dass sie nur Näherungen berechnet - die <strong>Lösung</strong>en geraten etwas aus dem<br />
Takt, die Periodendauer vergrößert sich. Die Differenzen (Abbildung 11)<br />
übersteigen in der Amplitude die der Original-Funktion. Dagegen bleibt die<br />
Amplitude der <strong>Lösung</strong>en im richtigen Bereich.<br />
26
1<br />
0<br />
−1<br />
−2<br />
1<br />
0<br />
−1<br />
−2<br />
1 2 3 4 5 6<br />
Abbildung 8: <strong>Lösung</strong>en bei h = 0.2<br />
1 2 3 4 5 6<br />
Abbildung 9: Differenzen bei h = 0.2<br />
27
1<br />
0<br />
−1<br />
−2<br />
1<br />
0<br />
−1<br />
−2<br />
1 2 3 4 5 6<br />
Abbildung 10: Mittelpunktsregel bei h = 0.5 und 0.8<br />
1 2 3 4 5 6<br />
Abbildung 11: Differenzen der Mittelpunktsregel bei h = 0.5 und 0.8<br />
28
Beobachtung der Hamiltonfunktion und Erklärung<br />
Schauen wir uns nun das Verhalten <strong>des</strong> Hamilton-Operators für die <strong>Lösung</strong>en<br />
an. Da dieser (physikalisch betrachtet) gerade die Energie <strong>des</strong> Systems<br />
ausdrückt, muss er (wegen dem Energieerhaltungssatz) konstant bleiben.<br />
Dies wurde ja auch beim Herleiten der exakten <strong>Lösung</strong> aus der Differentialgleichung<br />
hergeleitet.<br />
1<br />
0<br />
−1<br />
−2<br />
1 2 3 4 5 6<br />
Abbildung 12: Hamilton-Funktion bei h = 0.1<br />
Betrachten wir nun unseren ” Standardfall“ <strong>mit</strong> h = 0.1, und betrachten<br />
dafür den Hamilton-Operator, so können wir folgen<strong>des</strong> beobachten:<br />
Die recht gute Näherung durch die implizite Mittelpunktsregel gibt den<br />
physikalischen Sachverhalt richtig wieder. Setzt man die Näherung in die<br />
Hamiltonfunktion ein, so erhält man auch hier eine konstante Funktion.<br />
Aber die Näherung durch das explizite Eulerverfahren ist sehr schlecht. Das<br />
erkennt man schon, wenn man die Energie betrachtet. Denn setzt man die<br />
<strong>Lösung</strong> <strong>des</strong> expliziten Eulerverfahrens in die Hamiltonfunktion ein, so gewinnt<br />
man im Laufe der Zeit Energie, was physikalisch unmöglich ist. Der<br />
Energiegewinn resultiert daraus, dass beim expliziten Eulerverfahren die<br />
Amplitude <strong>des</strong> <strong>Pendels</strong> vergrößert wird.<br />
Bei kleineren Schrittweiten verringert sich dieser Effekt, bei größeren<br />
verstärkt er sich, wie in den weiteren Abbildungen zu sehen ist. Das Mittelpunktsverfahren<br />
dagegen erhält bei jeder Schrittweite die richtige Energie.<br />
29
1<br />
0<br />
−1<br />
−2<br />
1<br />
0<br />
−1<br />
−2<br />
1 2 3 4 5 6<br />
Abbildung 13: Hamilton-Funktion bei h = 0.05<br />
1 2 3 4 5 6<br />
Abbildung 14: Hamilton-Funktion für Euler bei h = 0.01<br />
30
1<br />
0<br />
−1<br />
−2<br />
1<br />
0<br />
−1<br />
−2<br />
1 2 3 4 5 6<br />
Abbildung 15: Hamilton-Funktion bei h = 0.2<br />
1 2 3 4 5 6<br />
Abbildung 16: Hamilton-Funktion für Mittelpunktsverfahren bei h = 0.5<br />
und h = 0.8<br />
31
Quellenangaben<br />
[1] Konrad Königsberger:<br />
Analysis 1, Springer-Lehrbuch,<br />
Springer-Verlag, 3. Auflage 1995. (Seiten 230, 295ff )<br />
[2] Physikalisches Institut der Universität Basel:<br />
Versuchsbeschreibung für das Anfängerpraktikum<br />
http://www.unibas.ch/phys-ap/vers08/anl08.htm<br />
[3] Hendrik van Hees:<br />
de.sci.physik-FAQ – Klassische Mechanik<br />
http://theory.gsi.de/~vanhees/faq-pdf/mech.pdf (Seiten 59ff )<br />
[4] Knut Petras:<br />
Vorlesungsskript – Numerik gewöhnlicher Differentialgleichungen<br />
http://www-public.tu-bs.de:8080/~petras/lva/dgl00/vorl.ps<br />
(Seite 33)<br />
32