21
D-MATH Numerische Methoden FS 2021 Dr. Vasile Gradinaru Serie 5 Abgabedatum: Di. 13.04. / Mi. 14.04, in den ¨ Ubungsgruppen Koordinatoren: Bei Fragen zu den ¨ Ubungen kontaktieren Sie bitte • Francesca Bartolucci [email protected] • Luc Grosheintz [email protected] Webpage: http://metaphor.ethz.ch/x/2021/fs/401-1662-10L 1. Kernaufgabe: Das N -K¨ orper Problem Wir betrachten N orper im dreidimensionalen Raum. Ihre Dynamik unterliegt einzig der Gravitation, beschrieben durch das Newtonsche Gesetz. Jeder K¨ orper K i hat eine Position q i R 3 und einen Impuls p i R 3 sowie eine Masse m i . Zur einfachen Behandlung der N orper fassen wir deren Positionen q i und Impulse p i in Vektoren zusammen: q := [q 1 | ... |q N ] T R 3N p := [p 1 | ... |p N ] T R 3N . Die Hamilton-Funktion H(q ,p ) lautet dann: H ( q ,p ) = 1 2 N i=1 1 m i p i T p i - G 1i<jN m i m j q j - q i Aus dieser Funktion erh¨ alt man die Bewegungsgleichungen durch partielles ableiten: ∂q ∂t =: ˙ q = H ∂p ∂p ∂t =: ˙ p = - H ∂q . Wir finden hier also: ˙ q k = H ∂p k = ∂p k 1 2 N i=1 1 m i p i T p i = 1 m k p k und: ˙ p k = - H ∂q k = ∂q k G N i=1 N j=i+1 m i m j q j - q i = G N i=1 i=k m i m k q i - q k 3 ( q i - q k ) . Schliesslich fasst man noch die Positionen q und Impulse p in einen einzigen grossen Vektor y := [q |p ] T zusammen. Bitte wenden!

Serie 5 - metaphor

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Serie 5 - metaphor

D-MATH Numerische Methoden FS 2021Dr. Vasile Gradinaru

Serie 5

Abgabedatum: Di. 13.04. / Mi. 14.04, in den Ubungsgruppen

Koordinatoren: Bei Fragen zu den Ubungen kontaktieren Sie bitte

• Francesca Bartolucci [email protected]

• Luc Grosheintz [email protected]

Webpage: http://metaphor.ethz.ch/x/2021/fs/401-1662-10L

1. Kernaufgabe: Das N-Korper Problem

Wir betrachten N Korper im dreidimensionalen Raum. Ihre Dynamik unterliegt einzig derGravitation, beschrieben durch das Newtonsche Gesetz. Jeder Korper Ki hat eine Positionqi ∈ R3 und einen Impuls pi ∈ R3 sowie eine Masse mi. Zur einfachen Behandlung der NKorper fassen wir deren Positionen qi und Impulse pi in Vektoren zusammen:

q := [q1| . . . |qN ]T ∈ R3N

p := [p1| . . . |pN ]T ∈ R3N .

Die Hamilton-Funktion H(q, p) lautet dann:

H(q, p)

= 12

N∑i=1

1mi

piTpi −G

∑1≤i<j≤N

mimj

‖qj − qi‖

Aus dieser Funktion erhalt man die Bewegungsgleichungen durch partielles ableiten:

∂q

∂t=: q = ∂H

∂p

∂p

∂t=: p = −∂H

∂q.

Wir finden hier also:

qk = ∂H∂pk

= ∂

∂pk

12

N∑i=1

1mi

piTpi = 1

mkpk

und:

pk = − ∂H∂qk

= ∂

∂qkG

N∑i=1

N∑j=i+1

mimj

‖qj − qi‖= G

N∑i=1i6=k

mimk

‖qi − qk‖3(qi − qk

).

Schliesslich fasst man noch die Positionen q und Impulse p in einen einzigen grossen Vektory := [q|p]T zusammen.

Bitte wenden!

Page 2: Serie 5 - metaphor

Aus obiger Herleitung bekommt man ein System von gekoppelten Differentialgleichungen ersterOrdnung:

y(t) =[q(t)p(t)

]=[

∂H∂p

−∂H∂q

]= f

(t, y)

mit f : R+ × R6N → R6N welches wir nun mit den Polygonzugverfahren aus der Vorlesunglosen wollen.

a) Implementieren Sie, z.B. mithilfe fruherer Aufgaben, das explizite und implizite Eulerver-fahren, die implizite Mittelpunktsregel und das Velocity-Verlet.

b) Implementieren Sie mithilfe obiger Formeln die Funktion f(y) korrekt fur N Korper.Hinweis: Benutzen Sie das Python Template nbody.py

Solution:Siehe 1

c) Implementieren Sie eine mit dem velocity-Verlet Verfahren kompatible Version der rechtenSeite. Achten Sie dabei auf die Verwendung korrekter Input-Werte.Solution:Siehe 2

d) Testen Sie die Implementation am Zweikorperproblem mit folgenden Anfangswerten. Mas-sen: m1 = 500, m2 = 1, Positionen: q1 = 0, q2 = (2, 0, 0), Impulse: p1 = 0, p2 =(0,√

Gm12 , 0) und G = 1. Das Ende der Simulation sei bei T = 3 und es sollen 5000

Zeitschritte gemacht werden. Plotten Sie die Bahnen der Korper in der x-y Ebene. Ver-gleichen Sie die benotigten Rechenzeiten der verschiedenen Methoden.Solution:In Abbildung 1 sehen Sie die Trajektorien der vier Loser. Auch hier sehen sie wieder denEffekt der Energieerhaltung oder eben fehlende Energieerhaltung.

e) Als nachstes wollen wir ein Dreikorperproblem betrachten. Im Allgemeinen ist das Drei-korperproblem nicht analytisch losbar. Untersuchen Sie numerisch die Dynamik mit dengegebenen Anfangswerten. Massen: m1 = m2 = m3 = 1. Positionen und Impulse:

q1 = (0.97000436,−0.24308753, 0) p1 = (0.46620368, 0.43236573, 0)q2 = (−0.97000436, 0.24308753, 0) p2 = (0.46620368, 0.43236573, 0)q3 = (0, 0, 0) p3 = (−0.93240737,−0.86473146, 0) .

Auch hier nehmen wir G = 1. Das Ende der Simulation sei T = 2 simuliert und es sollen1000 Zeitschritte mit dem velocity-Verlet impliziten Mittelpunktsregel gemacht werden.Plotten Sie die Bahnen der drei Korper in der x-y Ebene.1

Solution:Die Losung wird in Abbildung 2 gezeigt.

f) Abschliessend wollen wir die Bahnen der Planeten2 des ausseren Sonnensystems untersu-chen. Dazu integrieren wir ihre Bewegungsgleichungen ausgehend von konkreten Anfangs-werten. Diese Werte sind im Python Template zur Aufgabe notiert und alle Einheiten sind

1Dieses sehr spezielle Bewegungsmuster ist als figure-eight pattern bekannt und detailliert beschrieben im PaperA remarkable periodic solution of the three-body problem in the case of equal masses von Alain Chenciner undRichard Montgomery, zu finden unter http://arxiv.org/abs/math/0011268

2Pluto ist offiziell zwar kein Planet mehr, wir wollen ihn hier dennoch berucksichtigen.

Siehe nachstes Blatt!

Page 3: Serie 5 - metaphor

−2 −1 0 1 2

−2

−1

0

1

2

−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0−2.0

−1.5

−1.0

−0.5

0.0

0.5

1.0

1.5

2.0

−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0

−2.0

−1.5

−1.0

−0.5

0.0

0.5

1.0

1.5

2.0

−2.0 −1.5 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0

−2.0

−1.5

−1.0

−0.5

0.0

0.5

1.0

1.5

2.0

Abbildung 1: Trajekorien des Zweikorperproblems.

im astronomischen Einheitensystem (Langen in A.U., Massen relativ zur Sonne und Zeitin Tagen). Hier nehmen wir G = 2.95912208286 · 10−4. Mit jeder Methode sollen 2000Zeitschritte gemacht werden. Die Simulation soll bis T = 20000 laufen. Plotten Sie diePlanetenbahnen in der x-y Ebene. (Die Berechnung mit den impliziten Methoden dauerteine Weile.)Solution:Die Planetenbahnen sehen Sie in Abbildung 3.

Solution:

Listing 1: Python-Skript zur Kernaufgabe 11 # -*- coding: utf -8 -*-

3 import numpy as npimport scipy.optimize

5

7def integrate(method , rhs , y0, T, N):

9 y = np.empty((N + 1,) + y0.shape)

11 t0, dt = 0.0, T / Ny[0, ...] = y0

13 f o r i in range (0, N):y[i + 1, ...] = method(rhs , y[i, ...], t0 + i * dt, dt)

15

Bitte wenden!

Page 4: Serie 5 - metaphor

−1.0 −0.5 0.0 0.5 1.0−0.4

−0.3

−0.2

−0.1

0.0

0.1

0.2

0.3

0.4

−1.0 −0.5 0.0 0.5 1.0

−0.3

−0.2

−0.1

0.0

0.1

0.2

0.3

−1.0 −0.5 0.0 0.5 1.0

−0.3

−0.2

−0.1

0.0

0.1

0.2

0.3

−1.0 −0.5 0.0 0.5 1.0

−0.3

−0.2

−0.1

0.0

0.1

0.2

0.3

Abbildung 2: Trajekorien des Dreikorperproblems.

t = np.arange(N + 1) * dt17 return t, y

19def explicit_euler_step(rhs , y0, t0, dt):

21 return y0 + dt * rhs(t0, y0)

23def explicit_euler(rhs , y0, T, N):

25 return integrate(explicit_euler_step , rhs , y0, T, N)

27def implicit_euler_step(rhs , y0, t0, dt):

29 # Das implizite Eulerverfahren ist# y1 = y0 + dt * rhs(t+dt, y1)

31 # Wir mussen diese gleichung nach y1 auflosen.F = lambda y1: y1 - (y0 + dt * rhs(t0 + dt, y1))

33initial_guess = explicit_euler_step(rhs , y0, t0, dt)

35 return scipy.optimize.fsolve(F, initial_guess)

37def implicit_euler(rhs , y0, T, N):

39 return integrate(implicit_euler_step , rhs , y0, T, N)

41def implicit_mid_point_step(rhs , y0, t0, dt):

43 # Die implizite Mittelpunktsregel ist# y1 = y0 + dt*rhs(t+0.5*dt, 0.5*(y0 + y1))

45 F = lambda y1: y1 - (y0 + dt * rhs(t0 + 0.5 * dt, 0.5 * (y0 + y1)))

Siehe nachstes Blatt!

Page 5: Serie 5 - metaphor

−20 −10 0 10 20 30 40

−30

−20

−10

0

10

20

(a) Explizite Eulerregel

−20 −10 0 10 20 30

−30

−20

−10

0

10

20

(b) Implizite Eulerregel

−20 −10 0 10 20 30 40

−30

−20

−10

0

10

20

(c) Implizite Mittelpunktsregel

−20 −10 0 10 20 30 40

−30

−20

−10

0

10

20

(d) Velocity Verlet

Abbildung 3: Planetenbahnen berechnet mit den verschiedenen Verfahren. (Abweichende Plotsmoglich, da die Nullstellensuche mit fsolve im hochdimensionalen Raum schlecht funktioniert.)

47 initial_guess = explicit_euler_step(rhs , y0, t0, dt)return scipy.optimize.fsolve(F, initial_guess)

49

51 def implicit_mid_point(rhs , y0, T, N):return integrate(implicit_mid_point_step , rhs , y0, T, N)

53

55 def velocity_verlet_step(rhs , xv0 , t0, dt):xv0 = xv0.reshape((2, -1))

57 xv1 = np.empty_like(xv0)x0, x1 = xv0[0, :], xv1[0, :]

59 v0, v1 = xv0[1, :], xv1[1, :]

61 x1[:] = x0 + dt * v0 + 0.5 * dt ** 2 * rhs(t0, x0)v1[:] = v0 + 0.5 * dt * (rhs(t0, x0) + rhs(t0 + dt, x1))

63return xv1.reshape(-1)

65

67 def velocity_verlet(rhs , y0, T, N):return integrate(velocity_verlet_step , rhs , y0, T, N)

Bitte wenden!

Page 6: Serie 5 - metaphor

Listing 2: Python-Skript zur Kernaufgabe 1# -*- coding: utf -8 -*-

2 import timeimport numpy as np

4 import matplotlib.pyplot as plt

6 from ode_solvers import explicit_euler , implicit_eulerfrom ode_solvers import implicit_mid_point , velocity_verlet

8def nbody_pdot(t, q, m, G):

10 """ Berechnet die zeitliche Ableitung des Impluses im N-Korper Problem.

12 t : Aktuelle Zeit , wird nicht gebraucht.

14 q : 2D-Array , (n_bodies , 3). Ort jedes der N Korper. Entlang der erstenAchse sind die verschiedenen Korper , entlang der zweiten die drei

16 ortlichen Dimensionen.

18 m : 1D Array. Masse jedes Objekts.

20 G : Gravitationskonstante."""

22 dpdt = np.empty_like(q)

24 n_bodies = q.shape[0]f o r k in range (n_bodies):

26 dq = q - q[k, :]

28 norm3 = np.linalg.norm(dq, axis=1) ** 3norm3 = norm3.reshape((-1, 1))

30 mimk = m * m[k]

32 # ‘ + 1e-200‘ verhindert eine Division durch Null. Jedoch ist ‘1e-200‘# zu klein um irgendeinen physikalisch korrekten Wert zu verandern.

34 tmp = mimk * dq / (norm3 + 1e-200)dpdt[k, :] = G * (np.sum(tmp[:k, :], axis=0) + np.sum(tmp[k + 1 :, :], ↘

· · · axis=0))36

return dpdt38

40 def nbody_rhs(t, y, m, G):"""Rechte Seite des N-Korperproblems.

42t : Aktuelle Zeit.

44 y : 1D Array der approximativen Losung der ODE. Die Elemente von‘y‘ sind so arrangiert , dass

46 y.reshape((2, -1, 3))auf der ersten Achse indiziert man den Ort bzw. den Impuls; auf der ↘

· · · zweiten48 Achse sind die verschiedenen Korper; und auf der dritten Achse

indiziert man die 3 ortlichen Koordinaten.50

m : Massen der Objekte.52 G : Gravitationskonstante.

"""54 y = y.reshape((2, -1, 3))

q, p = y[0, ...], y[1, ...]56 m = m.reshape((-1, 1))

58 dydt = np.empty_like(y)dydt[0, ...] = 1.0 / m * p

60 dydt[1, ...] = nbody_pdot(t, q, m, G)

Siehe nachstes Blatt!

Page 7: Serie 5 - metaphor

62 return dydt.reshape(-1)

64def nbody_verlet_rhs(t, q, m, G):

66 """ Zeitliche Ableitung der Geschwindigkeit des N-Korperproblems.

68 t : Aktuelle Zeit.q : 1D Array des approximativen Ortes der Teilchen. Diese sind so arrangiert ,↘

· · · dass70 q.reshape((-1, 3))

die verschiedenen Teilchen auf der ersten Achse hat und die 372 Koordinaten auf der zweiten Achse.

m : Masses der Teilchen.74 G : Gravitationskonstante.

"""76 q = q.reshape((-1, 3))

m = m.reshape((-1, 1))78 return np.reshape(nbody_pdot(t, q, m, G) / m, -1)

80

82def plot_orbits(y, filename):

84 """Erstellt einen Plot der Bahnen aller Teilchen.

86 y : 4D-Array. Approximative Losung des N-Korperproblems.Achse 0: Zeitschritte

88 Achse 1: Ort und Implus/Geschwindigkeit.Achse 2: Verschiedene Teilchen.

90 Achse 3: Raumdimensionen.

92 filename : Name der Datei unterdem der Plot gespeichert wird , ohne Endung."""

94 f o r k in range (y.shape[2]):plt.plot(y[:, 0, k, 0], y[:, 0, k, 1])

96plt.savefig(filename + ".png")

98 plt.savefig(filename + ".eps")plt.show()

100

102 def measure_runtime(function , *args , **kwargs):"""Naive measurement of the runtime of a function.

104This idea of only measuring once , only works for rather slow

106 functions. Anything above 0.1 seconds should be safe.

108 Naturally , there are still sources of error , e.g., the current CPU load. Ifyou’re running other expensive tasks in parallel the runtime could be off.

110Examples:

112# fx = f(x)

114 t_run , fx = measure_runtime(f, x)

116 # fx = f(x, foo=42.0)t_run , fx = measure_runtime(f, x, foo=42.0)

118# a, b = f(x)

120 t_run , (a, b) = measure_runtime(f, x)"""

122t0 = time.perf_counter()

124 fx = function(*args , **kwargs)t1 = time.perf_counter()

Bitte wenden!

Page 8: Serie 5 - metaphor

126return t1 - t0, fx

128

130 def nbody_simulation(y0, m, T, N, G, figure_basename):n_bodies = m.size

132all_methods = [explicit_euler , implicit_euler , implicit_mid_point]

134 rhs = lambda t, y: nbody_rhs(t, y, m, G)all_labels = ["explicit_euler", "implicit_euler", "implicit_mid_point"]

136f o r method , label in z i p (all_methods , all_labels):

138 runtime , (t, y) = measure_runtime(method , rhs , y0.reshape(-1), T, N)plot_orbits(y.reshape((-1, 2, n_bodies , 3)), figure_basename + "_" + ↘

· · · label)140

p r i n t ("{:s} took {:e}s". format(label , runtime))142

# Velocity -Verlet benotigt (q,v) als Startwerte.144 y0[1, :, :] /= m

146 rhs = lambda t, y: nbody_verlet_rhs(t, y, m, G)runtime , (t, y) = measure_runtime(velocity_verlet , rhs , y0.reshape(-1), T, N)

148 plot_orbits(y.reshape((-1, 2, n_bodies , 3)), figure_basename + "_verlet")p r i n t ("{:s} took {:e}s". format("verlet", runtime))

150

152 def ex3_c():n_bodies = 2

154 m = np.array([500, 1]).reshape((-1, 1))G = 1.0

156y0 = np.zeros((2, n_bodies , 3))

158 y0[0, 1, 0] = 2.0y0[1, 1, 1] = np.sqrt(0.5 * G * m[0])

160T, N = 3.0, 5000

162nbody_simulation(y0, m, T, N, G, "two_body")

164

166

168 def three_body_ic():n_bodies = 3

170 m = np.array([1.0, 1.0, 1.0])

172 y0 = np.zeros((2, n_bodies , 3))

174 y0[0, 0, :] = np.array ([0.97000436 , -0.24308753, 0.0])y0[1, 0, :] = np.array ([0.46620368 , 0.43236573 , 0.0])

176y0[0, 1, :] = -y0[0, 0, :]

178 y0[1, 1, :] = y0[1, 0, :]

180 y0[0, 2, :] = 0.0y0[1, 2, :] = np.array ([-0.93240737, -0.86473146, 0.0])

182return m, y0

184

186 def planet_ic():msun = 1.00000597682

188 qsun = np.array([0, 0, 0])vsun = np.array([0, 0, 0])

Siehe nachstes Blatt!

Page 9: Serie 5 - metaphor

190mj = 0.00095486104043

192 qj = np.array([-3.5023653, -3.8169847, -1.5507963])vj = np.array ([0.00565429 , -0.00412490, -0.00190589])

194ms = 0.000285583733151

196 qs = np.array ([9.0755314 , -3.0458353, -1.6483708])vs = np.array ([0.00168318 , 0.00483525 , 0.00192462])

198mu = 0.0000437273164546

200 qu = np.array ([8.3101420 , -16.2901086, -7.2521278])vu = np.array ([0.00354178 , 0.00137102 , 0.00055029])

202mn = 0.0000517759138449

204 qn = np.array ([11.4707666 , -25.7294829, -10.8169456])vn = np.array ([0.00288930 , 0.00114527 , 0.00039677])

206mp = 7.692307692307693e-09

208 qp = np.array([-15.5387357, -25.2225594, -3.1902382])vp = np.array ([0.00276725 , -0.00170702, -0.00136504])

210masses = np.array([msun , mj, ms, mu, mn, mp]).reshape((-1, 1))

212n_bodies = 6

214 y0 = np.empty((2, n_bodies , 3))f o r k, q0 in enumerate([qsun , qj, qs, qu, qn, qp]):

216 y0[0, k, :] = q0

218 f o r k, (m, v0) in enumerate( z i p (masses , [vsun , vj, vs, vu, vn, vp])):y0[1, k, :] = m * v0

220return masses , y0

222

224 def ex3_d():G, T, N = 1.0, 5.0, 10000

226 m, y0 = three_body_ic()

228 nbody_simulation(y0, m, T, N, G, "eight")

230def ex3_e():

232 m, y0 = planet_ic()shape = y0.shape

234G = 2.95912208286e-4

236 T, N = 20000, 2000

238 nbody_simulation(y0, m, T, N, G, "solar_system")

240i f __name__ == "__main__":

242 ex3_c()ex3_d()

244 ex3_e()

2. Simples Splittingverfahren

Die folgende ODE beschreibt die Drehung und das gleichzeitige Schrumpfen eines Vektors inR2.

Bitte wenden!

Page 10: Serie 5 - metaphor

d

dty = dR

dt·R−1 · y + b y (1)

mit b = −0.1 und der Rotationsmatrix

R(t) =(

cos θt − sin θtsin θt cos θt.

)(2)

a) Identifizieren Sie die Rotations- und Streckungsterme in der ODE. Splitten Sie die ODEin die zwei Terme.

b) Losen Sie die beiden ODEs, welche Sie durch das Splitting erhalten haben, analytisch.Hinweis: Die beiden Terme haben eine klare geometrische Bedeutung. Nutzen Sie dies ausum analytische Losungen zu finden.

c) Implementieren Sie das Strang-Splittingverfahren und integrieren Sie die ODE mit demStartwert y = (1, 0) bis t = 100.Hinweis: Implementieren Sie autonome Losungsoperatoren.

Hinweis: Verwenden Sie das Template simple splitting.py.

Solution:

a) Die Rotations- und Streckunfsterme in der ODE lauten{ddty = dR

dt R−1y

y(0) = y0{ddty = by

y(0) = y0

b) Die analytische Loesungen lauteny(t) = R(t)y0

y(t) = y0ebt

c) Betrachte die zwei Operatoren φ∆trot and φ∆t

str, die jeweils die zugehorige ODE losen. DasStrang-Splitting lautet dann

y(tn+1) = φ∆t/2rot φ∆

strφ∆t/2rot y(tn)

Listing 3: Python-Skript zu Aufgabe 21 # coding: utf -8

3 import numpy as npimport matplotlib.pyplot as plt

5 import scipy.integrate

7 # Wir wollen# dy/dt = A(t) y + b*y

9 # mittels Splitting losen. Dabei ist A eine Rotationsmatrix und b

Siehe nachstes Blatt!

Page 11: Serie 5 - metaphor

0.75 0.50 0.25 0.00 0.25 0.50 0.75 1.000.6

0.4

0.2

0.0

0.2

0.4

0.6

0.8

Abbildung 4: Aufgabe 1: Simples Splittingverfahren

# eine reelle Zahl.11

# Die Losung ist also eine Komposition von Rotation13 # und Streckung von y.

15 b = -0.1theta = 0.25 * np.pi

17

19 def rhs(t, y):return np.dot(dRdt(t), np.dot(invR(t), y)) + b * y

21

23 def R(t):angle = theta * t

25 A = np.array([[np.cos(angle), -np.sin(angle)], [np.sin(angle), np.cos(angle)↘

· · · ]])return A

27

29 def invR(t):return R(-t)

31

33 def dRdt(t):angle = theta * t

35 A = theta * np.array([[-np.sin(angle), -np.cos(angle)], [np.cos(angle), -np.sin(angle)]]

37 )

39 return A

41def rotate(y, dt):

43 angle = theta * dt

Bitte wenden!

Page 12: Serie 5 - metaphor

A = R(dt)45

return np.dot(A, y)47

49 def Phi_rot(y, dt):"""Exakter Losungsoperator der Rotationsterme in der ODE."""

51return rotate(y, dt)

53

55 def Phi_stretch(y, dt):"""Exakter Losungsoperator der Zerfallsterme in der ODE."""

57return np.array(y * np.exp(b * dt))

59

61 def integrate(method , y0, t_end , n_steps):"""Fuhrt wiedeholt Zeitschritte des Verfahrens ‘method ‘ aus.

63Input:

65 method : Einschrittverfahren mit Signatur ‘(y[i,:], t, dt)‘."""

67t, dt = np.linspace(0, t_end , n_steps + 1, retstep=True)

69 y = np.empty((n_steps + 1,) + y0.shape)y[0, ...] = y0

71f o r i in range (n_steps):

73 y[i + 1, ...] = method(y[i, ...], dt)

75 return t, y

77def strang_splitting_step(Phi_a , Phi_b , y0, dt):

79 y_a = Phi_a(y0, 0.5 * dt)y_ba = Phi_b(y_a , dt)

81 y_aba = Phi_a(y_ba , 0.5 * dt)

83 return y_aba

85def strang_splitting(Phi_a , Phi_b , y0, t_end , n_steps):

87 method = lambda y, dt: strang_splitting_step(Phi_a , Phi_b , y, dt)

89 return integrate(method , y0, t_end , n_steps)

91

93def reference_solution(rhs , t_end , y0, n_steps):

95 # Wir wollen die Losung an folgenden Punktent_eval = np.linspace(0.0, t_end , n_steps)

97soln = scipy.integrate.solve_ivp(rhs , (0, t_end), y0, t_eval=t_eval)

99 return soln.t, soln.y.transpose()

101i f __name__ == "__main__":

103 y0 = np.array([1.0, 0.0])t_end = 100.0

105 n_steps = 1000

107 t, y = strang_splitting(Phi_rot , Phi_stretch , y0, t_end , n_steps)

Siehe nachstes Blatt!

Page 13: Serie 5 - metaphor

109 t_ref , y_ref = reference_solution(rhs , t_end , y0, n_steps)

111 plt.plot(y[:, 0], y[:, 1])plt.plot(y_ref[:, 0], y_ref[:, 1])

113 plt.savefig("spiral.pdf")plt.show()

3. Teilchen im Gravitationsfeld einer Punktmasse

Bewegungsgleichungen konnen oft als Hamiltonisches System

q = ∇p ·H(p, q) (3)p = −∇q ·H(p, q) (4)

geschrieben werden. Fur ein Teilchen im Gravitationsfeld der Sonne gilt

H = 1/2m ‖p‖2 + U(q)

wobei

U(q) = U(q) = −GMq

.

Wir setzen G = M = m = 1.

a) Leiten Sie die Bewegungsgleichungen eines Teilchens in im Gravitationsfeld einer Punkt-masse her. Verwenden Sie die Newtonschen Gesetze. Vergewissern Sie sich, dass (3) mitder von Ihnen hergeleiteten ODE ubereinstimmt.

b) Spalten Sie den Hamiltonian in zwei Teile T (p) und V (q). Welchen physikalischen Grossenensprechen T und V ?

c) Schreiben Sie die beiden ODEs, welche durch das Splitting entstehen, auf und losen Siebeide analytisch.

d) Implementieren Sie Strang-Splitting oder eines der vielen Splittingverfahren aus Code 2.4.9im Skript, die Parameter finden Sie auch in splitting parameters.py.

e) Integrieren Sie (3) mit Startwert p(0) = (0, 1), q(0) = (1, 0) bis zur Zeit t = 50.Plotten Sie q2-q1, p-q sowie H − t, T − t und V − t. Die letzten drei Grossen plotten Sieam besten in einem Plot.• Versuchen Sie andere Startwerte.• Untersuchen Sie das Langzeitverhalten.• Probieren Sie auch ganz kleine Schrittweiten aus.

Solution:Wir beginnen mit dem Hamiltonian ohne Reibung und ohne externe Kraft:

H = p2

2 + V (q) .

Daraus konnen wir mit den Hamiltongleichungen ein System erster Ordnung herleiten:

q = ∂

∂pH = p

p = − ∂

∂qH = −∇V (q)

Bitte wenden!

Page 14: Serie 5 - metaphor

oder aquivalent:q +∇V (q) = 0

mit V (q) = g cos(q) und somit ∇V (q) = −g sin(q). Fassen wir die Variablen im Vektor Y =(q, p)T zusammen, so ergibt sich ein Splitting aus:

Y =(qp

)=(

p−∇V (q)

)=(p0

)︸︷︷︸

Φa

+(

0−∇V (q)

)︸ ︷︷ ︸

Φb

.

Nun konnen wir in die Bewegungsgleichung (3.) Reibungsterme einbauen:

q + µq +∇V (q) = 0 .

Hieraus konnen wir folgendes Gleichungssystem formen:

Y =(qp

)=(pq

)=(

p−µq −∇V (q)

)=(

p−µp−∇V (q)

)Fuer das Splitting ergeben sich dann mehrere aquivalente Moeglichkeiten:

=(p0

)︸︷︷︸

Φa

+(

0−µp−∇V (q)

)︸ ︷︷ ︸

Φb

=(

p−µp

)︸ ︷︷ ︸

Φ′a

+(

0−V (q)

)︸ ︷︷ ︸

Φ′b

Fugen wir eine externe Kraft F (t) zu (3.) hinzu, so ergibt sich:

q +∇V (q) = F (t) .

Hieraus konnen wir wiederum ein Gleichungssystem ableiten:

Y =(qp

)=(pq

)=(

p−∇V (q) + F (t)

)Da nun aber die Variable t auf der rechten Seite auftaucht, mussen wir diese explizit behandeln:qpt

=

p−∇V (q) + F (t)

1

Fuer das Splitting gibt es auch hier mehrere Moeglichkeiten:

=

p01

︸ ︷︷ ︸

Φa

+

0−∇V (q) + F (t)

0

︸ ︷︷ ︸

Φb

=

p00

︸ ︷︷ ︸

Φ′a

+

0−∇V (q) + F (t)

1

︸ ︷︷ ︸

Φ′b

=

pF (t)

0

︸ ︷︷ ︸

Φ′′a

+

0−∇V (q)

1

︸ ︷︷ ︸

Φ′′b

= . . .

Haben wir Reibung und externe Kraft, so mussen wir beide Teile kombinieren. Ausgehend vonder Gleichung:

q + µq +∇V (q) = F (t) .erhalten wir:qp

t

=

pqt

=

pF (t)−∇V (q)− µq

1

=

pF (t)−∇V (q)− µp

1

Siehe nachstes Blatt!

Page 15: Serie 5 - metaphor

und daraus beispielsweise folgende Splittings:

=

p−µp

1

︸ ︷︷ ︸

Φa

+

0F (t)−∇V (q)

0

︸ ︷︷ ︸

Φb

=

p01

︸ ︷︷ ︸

Φ′a

+

0F (t)−∇V (q)− µp

0

︸ ︷︷ ︸

Φ′b

= . . .

Die jeweiligen Propagatoren Φa und Φb ergeben sich aus der Integration nach τ von 0 bis h mitentsprechenden Anfangswerten q0, p0 und t0. Beispielsweise:

Φa = ∂Φa∂τ

=

p01

Φa = Φ0a +

∫ h

0

∂Φa∂τ

dτ =

∫ h

0 pdτ∫ h0 0dτ∫ h0 1dτ

= Φ0a +

q0 + p0hp0

t0 + h

und

Φb = ∂Φb∂τ

=

0F (t)−∇V (q)− µp

0

Φb = Φ0b +

∫ h

0

∂Φb∂τ

dτ = Φ0b +

∫ h

0 0dτ∫ h0 F (t)−∇V (q)− µpdτ∫ h

0 0dτ

=

q0

p0 +∫ h

0 F (t0)−∇V (q0)− µpdτt0

=

q0{(

p0 + 1µ (∇V (q0)− F (t0))

)e−µh − 1

µ (∇V (q0)− F (t0)) µ 6= 0p0 + F (t0)h−∇V (q0)h µ = 0

t0

Listing 4: Python-Skript zu Aufgabe 3

1 # coding: utf -8

3 import numpy as npimport numpy.linalg

5import matplotlib.pyplot as plt

7from splitting_parameters import splitting_parameters

9

11 def integrate(method , y0, t_end , n_steps):"""Fuhrt wiedeholt Zeitschritte des Verfahrens ‘method ‘ aus.

13Input:

15 method : Einschrittverfahren mit Signatur ‘(y[i,:], t, dt)‘."""

17t, dt = np.linspace(0, t_end , n_steps + 1, retstep=True)

19 y = np.empty((n_steps + 1,) + y0.shape)y[0, ...] = y0

21f o r i in range (n_steps):

23 y[i + 1, ...] = method(y[i, ...], dt)

Bitte wenden!

Page 16: Serie 5 - metaphor

25 return t, y

27G = 1.0

29 M = 1.0

31def U(r):

33 return -G * M / r

35def dUdr(r):

37 return G * M / r ** 2

39def T(p):

41 return 0.5 * np.sum(p ** 2, axis=-1)

43def V(q):

45 return U(np.linalg.norm(q, axis=-1))

47def H(q, p):

49 return T(p) + V(q)

51def gradT(p):

53 return p

55def gradV(q):

57 r = np.linalg.norm(q)return dUdr(r) * q / r

59

61 def PhiT(y, dt):q, p = y[0, :], y[1, :]

63y1 = np.empty_like(y)

65 y1[0, :] = q + dt * gradT(p)y1[1, :] = p

67return y1

69

71 def PhiV(y, dt):q, p = y[0, :], y[1, :]

73y1 = np.empty_like(y)

75 y1[0, :] = qy1[1, :] = p - dt * gradV(q)

77return y1

79

81 def splitting_method_step(PhiA , PhiB , y, dt, method):a, b = splitting_parameters(method)

83f o r ai, bi in z i p (a, b):

85 y = PhiB(PhiA(y, ai * dt), bi * dt)

87 return y

Siehe nachstes Blatt!

Page 17: Serie 5 - metaphor

89def splitting_method(PhiA , PhiB , y0, t_end , n_steps , method):

91 step = lambda y, dt: splitting_method_step(PhiA , PhiB , y, dt, method)return integrate(step , y0, t_end , n_steps)

93

95 q = np.array([1.0, 0.0])p = np.array([0.0, 1.2])

97y = np.empty((2, p.size))

99 y[0, :] = qy[1, :] = p

101t_end = 50.0

103 n_steps = 5000

105 t, y = splitting_method(PhiV , PhiT , y, t_end , n_steps , method="KL6")

107 plt.plot(y[:, 0, 0], y[:, 0, 1])plt.axis("equal")

109 plt.savefig("2_trajectory.pdf")

111 plt.figure()plt.plot(t, H(y[:, 0, :], y[:, 1, :]), label="H")

113 plt.plot(t, V(y[:, 1, :]), label="V")plt.plot(t, T(y[:, 0, :]), label="T")

115 plt.legend(loc="best")plt.savefig("2_energy.pdf")

117

119 plt.show()

4. Kernaufgabe: Pendel mit Reibung und externer Kraft

Wir betrachten das mathematische Pendel, welches durch folgende Gleichung (l = g = 1)beschrieben ist:

ϕ+ µϕ+ g

lsinϕ = F (t) (5)

mit externer Kraft:

F (t) = A sin(ωt) (6)

mit Frequenz ω = 1.3, Amplitude A = 1 und Reibung µ = 0 bzw. µ = 0.1 . Verwenden Sie dieAnfangswerte ϕ(0) = π

3 und ϕ(0) = 0.

a) Losen Sie (5) mit Runge-Kutta, z.B. via scipy.integrate.solve ivp.

b) Losen Sie (5) mit den Splitting-Verfahren SS, PRKS6, Y61, KL8.Hinweis: Sie finden die Parameter der verschiedenen Splittingverfahren in splitting parameters.py.

c) Plotten Sie die Auslenkung ϕ(t) und die Trajektorien im Phasenraum ϕ(t), ϕ(t).

Hinweis: Verwenden Sie das Template pendulum.py.

Solution:

Bitte wenden!

Page 18: Serie 5 - metaphor

0 25 50 75 100 125 150 175 200

20

15

10

5

0

Auslenkungrk45Version 1Version 2

(a) Auslenkung ϕ(t), µ = 0

0 25 50 75 100 125 150 175 200

2

1

0

1

2

Auslenkungrk45Version 1Version 2

(b) Auslenkung ϕ(t), µ = 0.1

20 15 10 5 03

2

1

0

1

2

Phasenraumrk45Version 1Version 2

(c) Phasenraumplot, µ = 0

2 1 0 1 2

2

1

0

1

2

Phasenraumrk45Version 1Version 2

(d) Phasenraumplot, µ = 0.1

Abbildung 5: Aufgabe 3: Pendel mit Reibung und externer Kraft

Listing 5: Python-Skript zu Kernaufgabe 4,label=list:pendulum1 # coding: utf -8

3 import numpy as npimport matplotlib.pyplot as plt

5 import scipy.integratefrom splitting_parameters import splitting_parameters

7

9 def integrate(method , y0, t_end , n_steps):t, dt = np.linspace(0, t_end , n_steps + 1, retstep=True)

11 y = np.empty((n_steps + 1,) + y0.shape)y[0, ...] = y0

13f o r i in range (n_steps):

15 y[i + 1, ...] = method(y[i, ...], dt)

17 return t, y

19def plot_angle(t, all_y , all_labels):

21 """Plottet den Winkel als Funktion der Zeit.

23 t: Zeitpunkte an denen die Losung approximiert wurde.all_y: Eine Liste aller Losungen die geplottet werden sollen.

25 all_labels: Eine Liste der Labels der entsprechenden Approximationen."""

27 fig = plt.figure(figsize=(20, 10))plt.title("Auslenkung")

29f o r y, label in z i p (all_y , all_labels):

31 plt.plot(t, y[:, 0], label=label)

Siehe nachstes Blatt!

Page 19: Serie 5 - metaphor

33 plt.grid()plt.legend()

35 return fig

37def plot_phasespace(all_y , all_labels):

39 """Plottet

41 all_y: Eine Liste aller Losungen die geplottet werden sollen.all_labels: Eine Liste der Labels der entsprechenden Approximationen.

43 """fig = plt.figure(figsize=(20, 10))

45 plt.title("Phasenraum")

47 f o r y, label in z i p (all_y , all_labels):plt.plot(y[:, 0], y[:, 1], label=label)

49plt.grid()

51 plt.legend()

53 return fig

55# konstanten furs problem

57 g = 1l = 1

59 mu = 0omega = 1.3

61 A = 1

63def F(t):

65 return A * np.sin(omega * t)

67# Rechte Seite zur Kontrolle mit einem Referenzloser

69 def rhs(t, y):"""

71 y: 2d-array y[0] = winkel , y[1] = winkelgeschwindigkeit"""

73 ret = np.empty(2)ret[0] = y[1]

75 ret[1] = -mu * y[1] - g / l * np.sin(y[0]) + F(t)return ret

77

79 # Eine Moglichkeit zu Splitten:def Phi_A(y, dt):

81 """y = 3er vektor mit eintragen winkel , winkelgeschw , zeit

83 """ret = np.empty(3)

85 ret[0] = y[0] + dt * y[1]ret[1] = y[1]

87 ret[2] = y[2] + dtreturn ret

89

91 def Phi_B(y, dt):ret = np.empty(3)

93 ret[0] = y[0]ret[2] = y[2]

95 i f mu != 0:b = (g / l * np.sin(y[0]) - F(y[2])) / mu

Bitte wenden!

Page 20: Serie 5 - metaphor

97 ret[1] = (y[1] + b) * np.exp(-mu * dt) - be l s e :

99 ret[1] = y[1] + dt * (-np.sin(y[0]) + F(y[2]))return ret

101

103 # eine andere Variante:def Phi_A2(y, dt):

105 ret = np.empty(3)i f mu == 0:

107 ret[0] = y[0] + dt * y[1]ret[1] = y[1]

109 e l s e :ret[0] = y[0] + y[1] / mu * (1 - np.exp(-mu * dt))

111 ret[1] = y[1] * np.exp(-mu * dt)ret[2] = y[2] + dt

113 return ret

115def Phi_B2(y, dt):

117 ret = np.empty(3)ret[0] = y[0]

119 ret[1] = y[1] + dt * (F(y[2]) - g / l * np.sin(y[0]))ret[2] = y[2]

121 return ret

123def splitting_step(a, b, Phi_a , Phi_b , y0, dt):

125 f o r a_i , b_i in z i p (a, b):y0 = Phi_a(y0, a_i * dt)

127 y0 = Phi_b(y0, b_i * dt)

129 return y0

131def splitting(splitting_method , Phi_a , Phi_b , y0, t_end , n_steps):

133 a, b = splitting_parameters(splitting_method)method = lambda y, dt: splitting_step(a, b, Phi_a , Phi_b , y, dt)

135return integrate(method , y0, t_end , n_steps)

137

139 def rk45(rhs , t_end , y0, n_steps):t_eval = np.linspace(0.0, t_end , n_steps + 1)

141 soln = scipy.integrate.solve_ivp(rhs , (0.0, t_end), y0, t_eval=t_eval , atol=1e-12, rtol=1e-12, method="↘

· · · RK45"143 )

145 return soln.t, soln.y.transpose()

147i f __name__ == "__main__":

149 t_end = 200.0n_steps = 5000

151f o r mu in [0.0, 0.1]:

153 y0 = np.array([np.pi / 3, 0])t_rk45 , y_rk45 = rk45(rhs , t_end , y0, n_steps)

155y0 = np.append(y0, 0)

157 methods = ["SS", "PRKS6", "Y61", "KL8"]all_y = [y_rk45]

159 f o r m in methods:_, y = splitting(m, Phi_A2 , Phi_B2 , y0, t_end , n_steps)

Siehe nachstes Blatt!

Page 21: Serie 5 - metaphor

161 all_y.append(y)

163 fig = plot_angle(t_rk45 , all_y , ["rk45"] + methods)fig = plot_phasespace(all_y , ["rk45"] + methods)

165t, y1 = splitting("KL8", Phi_A , Phi_B , y0, t_end , n_steps)

167 t, y2 = splitting("KL8", Phi_A2 , Phi_B2 , y0, t_end , n_steps)

169 fig = plot_angle(t, [y_rk45 , y1, y2], ["rk45", "Version 1", "Version 2"])plt.savefig("auslenkung_mu" + ("0_0" i f mu == 0.0 e l s e "0_1") + ".png")

171 plt.savefig("auslenkung_mu" + ("0_0" i f mu == 0.0 e l s e "0_1") + ".pdf")

173 fig = plot_phasespace([y_rk45 , y1, y2], ["rk45", "Version 1", "Version 2"↘

· · · ])plt.savefig("phasenraum_mu" + ("0_0" i f mu == 0.0 e l s e "0_1") + ".png")

175 plt.savefig("phasenraum_mu" + ("0_0" i f mu == 0.0 e l s e "0_1") + ".pdf")plt.show()