Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| lehrkraefte:snr:informatik:glf4-23:wellengleichung [2024/05/15 14:48] – [1-dimensional: Simulation einer schwingenden Saite] Olaf Schnürer | lehrkraefte:snr:informatik:glf4-23:wellengleichung [2024/05/15 14:51] (current) – Olaf Schnürer | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ~~NOTOC~~ | ||
| + | |||
| + | Falls numpy etc. auf Schulrechnern nicht verfügbar: | ||
| + | |||
| + | https:// | ||
| + | |||
| + | |||
| + | ====== Wellengleichung ====== | ||
| + | |||
| + | (alle Programme recht rasch erstellt, geht sicher eleganter...) Die Mathematik und Formeln für die Iteration sind hier noch nicht dokumentiert (bisher an Tafel erklärt). Wellengleichung $u_{tt}=\Delta u$ bzw. $v=u_t$ und $v_t=\Delta u$. | ||
| + | |||
| + | |||
| + | {{: | ||
| + | |||
| + | {{: | ||
| + | |||
| + | ===== 1-dimensional: | ||
| + | |||
| + | === Lernen, wie man den Graphen einer Funktion zeichnet (function plot) === | ||
| + | |||
| + | <hidden Bitte Programm ausklappen> | ||
| + | <code graphen-zeichnen.py> | ||
| + | import numpy as np | ||
| + | from matplotlib import pyplot as plt | ||
| + | from matplotlib import colormaps | ||
| + | import matplotlib.animation as animation | ||
| + | from matplotlib.animation import FuncAnimation | ||
| + | |||
| + | # maximale x-Koordinate. | ||
| + | n = 40 | ||
| + | |||
| + | # Gezeichnet werden soll die folgende Funktion f. | ||
| + | # Bitte damit herumspielen. | ||
| + | def f(x): | ||
| + | return 100 * np.sin(x * 3 * np.pi / n) | ||
| + | |||
| + | # Die Liste u wird die Funktionswerte von f an allen ganzzahligen Argumenten zwischen 0 und n-1 enthalten. | ||
| + | # Zuerst wird sie initialisiert (alle Einträge Null). | ||
| + | u = np.zeros(n) | ||
| + | # Dann werden die Funktionswerte von f berechnet. | ||
| + | for x in range(n): | ||
| + | u[x] = f(x) | ||
| + | |||
| + | fig, ax = plt.subplots() | ||
| + | # Ausdehnung der y-Achse. | ||
| + | ax.set(xlim=(0, | ||
| + | |||
| + | # Die Plot-Funktion benötigt zu jedem y-Wert den zugehörigen x-Wert. | ||
| + | # Der folgende Befehl erstellt eine Liste aller ganzan Zahlen von 0 bis n-1. | ||
| + | x_werte = np.linspace(0, | ||
| + | |||
| + | ax.plot(x_werte, | ||
| + | plt.show() | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | === Lernen, wie man den Graphen einer zeitabhängigen Funktion animiert zeichnet === | ||
| + | |||
| + | <hidden Bitte Programm ausklappen> | ||
| + | <code animation-eines-zeitabhaengigen-graphen.py> | ||
| + | import numpy as np | ||
| + | from matplotlib import pyplot as plt | ||
| + | from matplotlib import colormaps | ||
| + | import matplotlib.animation as animation | ||
| + | from matplotlib.animation import FuncAnimation | ||
| + | |||
| + | # maximale x-Koordinate. | ||
| + | n = 40 | ||
| + | iterationen = 1000 | ||
| + | geschwindigkeit = 20 # je höher, desto schneller | ||
| + | |||
| + | # In der folgenden Funktion ist i die Iterationsvariable = die Zeit. | ||
| + | # Zur Zeit i soll die Funktion f(i, ?) gezeigt werden. | ||
| + | # Bitte damit herumspielen. | ||
| + | def f(i, x): | ||
| + | return i * x / n | ||
| + | |||
| + | # u enthält die Funktionswerte zu allen Zeiten i und Orten x. | ||
| + | # Initialisierung. | ||
| + | u = np.zeros((iterationen + 1, n)) | ||
| + | # Berechnung der Werte. | ||
| + | for i in range(1, iterationen + 1): | ||
| + | for x_werte in range(1, n): | ||
| + | u[i, x_werte] = f(i, x_werte) | ||
| + | |||
| + | fig, ax = plt.subplots() | ||
| + | x_werte = np.linspace(0, | ||
| + | |||
| + | def animate(i): | ||
| + | ax.cla() | ||
| + | ax.set(xlim=(0, | ||
| + | ax.plot(x_werte, | ||
| + | |||
| + | anim = FuncAnimation(fig, | ||
| + | # anim = FuncAnimation(fig, | ||
| + | |||
| + | plt.show() | ||
| + | </ | ||
| + | |||
| + | |||
| + | === Schwingende Saite simulieren === | ||
| + | |||
| + | <hidden Bitte Programm ausklappen> | ||
| + | <code schwingende-saite.py> | ||
| + | import numpy as np | ||
| + | from matplotlib import pyplot as plt | ||
| + | from matplotlib import colormaps | ||
| + | import matplotlib.animation as animation | ||
| + | from matplotlib.animation import FuncAnimation | ||
| + | |||
| + | # Grösse des quadratischen Feldes | ||
| + | n = 40 | ||
| + | iterationen = 1000 | ||
| + | geschwindigkeit = 20 # je höher, desto schneller | ||
| + | |||
| + | delta_t = 0.01 | ||
| + | |||
| + | # Auslenkungen u und Geschwindigkeiten v auf Null setzen für alle Zeiten und $x$-Werte. | ||
| + | u = np.zeros((iterationen + 1, n)) | ||
| + | v = np.zeros((iterationen + 1, n)) | ||
| + | |||
| + | # Randwerte | ||
| + | for i in range(iterationen): | ||
| + | # Die schwingende Saite ist am Rand befestigt: | ||
| + | # Auslenkung am Rand ist zu jedem Zeitupunkt Null. | ||
| + | u[i, 0] = 0 | ||
| + | u[i, n - 1] = 0 | ||
| + | # Geschwindigkeit am Rand ist zu jedem Zeitpunkt Null. | ||
| + | v[i, 0] = 0 | ||
| + | v[i, n - 1] = 0 | ||
| + | print(" | ||
| + | |||
| + | def f(x): | ||
| + | return np.sin(3 * np.pi * x) | ||
| + | # Aufgabe: Statt dieser Sinusfunktion nimm andere Funktionen auf dem Intervall [0, 1]. | ||
| + | # Empfehlung: Die Randwerte (also die Werte bei 0 und 1) sollten Null sein. | ||
| + | # Die Funktion sollte Werte im Intervall [-1, 1] annehmen. | ||
| + | # Vorschläge: | ||
| + | |||
| + | # Startwerte zur Zeit t=0: | ||
| + | for x_werte in range(n): | ||
| + | # Auslenkung zur Zeit t=0 an der Stelle x: | ||
| + | u[0, x_werte] = 100 * f(x_werte / (n - 1)) | ||
| + | # Geschwindigkeit zur Zeit t=0 an der Stelle x: | ||
| + | v[0, x_werte] = 0 | ||
| + | print(" | ||
| + | |||
| + | # Start der Simulation | ||
| + | for i in range(1, iterationen + 1): | ||
| + | if i % 100 == 0: | ||
| + | print(f" | ||
| + | for x_werte in range(1, n - 1): | ||
| + | v[i, x_werte] = v[i - 1, x_werte] + 0.05 | ||
| + | u[i, x_werte] = u[i - 1, x_werte] + v[i - 1, x_werte] * delta_t | ||
| + | |||
| + | fig, ax = plt.subplots() | ||
| + | x_werte = np.linspace(0, | ||
| + | |||
| + | def animate(i): | ||
| + | ax.cla() | ||
| + | ax.set(xlim=(0, | ||
| + | ax.plot(x_werte, | ||
| + | |||
| + | anim = FuncAnimation(fig, | ||
| + | |||
| + | plt.show() | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | ==== Wikipedia dazu ==== | ||
| + | |||
| + | https:// | ||
| + | |||
| + | ===== 2-dimensional: | ||
| + | |||
| + | |||
| + | === Lernen, wie man eine Fläche zeichnet (surface plot) === | ||
| + | |||
| + | <hidden Bitte Programm ausklappen> | ||
| + | <code suface-plot.py> | ||
| + | import numpy as np | ||
| + | from matplotlib import pyplot as plt | ||
| + | from matplotlib import colormaps | ||
| + | import matplotlib.animation as animation | ||
| + | from matplotlib.animation import FuncAnimation | ||
| + | |||
| + | # Grösse des quadratischen Feldes | ||
| + | n = 40 | ||
| + | |||
| + | u = np.zeros((n, | ||
| + | |||
| + | def f(z, s): | ||
| + | return np.sin(np.pi * z) * np.sin(2 * np.pi * s) | ||
| + | |||
| + | for z in range(1, n - 1): | ||
| + | for s in range(1, n - 1): | ||
| + | u[z, s] = 100 * f(z / (n-1), s/(n-1)) | ||
| + | |||
| + | (z, s) = np.meshgrid(np.arange(n), | ||
| + | fig = plt.figure() | ||
| + | koordinatensystem = fig.add_subplot(projection = ' | ||
| + | koordinatensystem.set_zlim(-100, | ||
| + | plot = koordinatensystem.plot_surface(z, | ||
| + | # fig.colorbar(plot, | ||
| + | fig.colorbar(plot, | ||
| + | |||
| + | |||
| + | plt.show() | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | === Simulation einer schwingenden Trommel === | ||
| + | |||
| + | <hidden Bitte Programm ausklappen> | ||
| + | <code trommel.py> | ||
| + | import numpy as np | ||
| + | from matplotlib import pyplot as plt | ||
| + | from matplotlib import colormaps | ||
| + | import matplotlib.animation as animation | ||
| + | from matplotlib.animation import FuncAnimation | ||
| + | |||
| + | # Grösse des quadratischen Feldes | ||
| + | n = 40 | ||
| + | # iterationen = 2600 | ||
| + | iterationen = 1000 | ||
| + | |||
| + | delta_t = 0.02 | ||
| + | |||
| + | geschwindigkeit = 40 | ||
| + | |||
| + | u = np.zeros((iterationen + 1, n, n)) | ||
| + | v = np.zeros((iterationen + 1, n, n)) | ||
| + | |||
| + | # Randwerte | ||
| + | for i in range(iterationen): | ||
| + | for s in range(n): | ||
| + | u[i, 0, s] = 0 | ||
| + | u[i, n - 1, s] = 0 | ||
| + | v[i, 0, s] = 0 | ||
| + | v[i, n - 1, s] = 0 | ||
| + | for z in range(n): | ||
| + | u[i, z, 0] = 0 | ||
| + | u[i, z, n - 1] = 0 | ||
| + | v[i, z, 0] = 0 | ||
| + | v[i, z, n - 1] = 0 | ||
| + | print(" | ||
| + | |||
| + | def f(z, s): | ||
| + | return np.sin(np.pi * z) * np.sin(2 * np.pi * s) | ||
| + | |||
| + | # Startwerte | ||
| + | for z in range(n): | ||
| + | for s in range(n): | ||
| + | u[0, z, s] = 100 * f(z / (n -1), s / (n - 1)) | ||
| + | v[0, z, s] = 0 | ||
| + | print(" | ||
| + | |||
| + | # Start der Simulation | ||
| + | for i in range(1, iterationen + 1): | ||
| + | if i % 100 == 0: | ||
| + | print(f" | ||
| + | for z in range(1, n - 1): | ||
| + | for s in range(1, n - 1): | ||
| + | v[i, z, s] = v[i - 1, z, s] + 0.05 | ||
| + | u[i, z, s] = u[i - 1, z, s] + v[i - 1, z, s] * delta_t | ||
| + | |||
| + | |||
| + | (z, s) = np.meshgrid(np.arange(n), | ||
| + | fig = plt.figure() | ||
| + | koordinatensystem = fig.add_subplot(projection = ' | ||
| + | koordinatensystem.set_zlim(0, | ||
| + | plot = koordinatensystem.plot_surface(z, | ||
| + | # fig.colorbar(plot, | ||
| + | fig.colorbar(plot, | ||
| + | |||
| + | def animiere(i): | ||
| + | j = i * geschwindigkeit | ||
| + | if i % 10 == 0: | ||
| + | print(f' | ||
| + | koordinatensystem.cla() | ||
| + | plt.title(f" | ||
| + | plt.xlabel(" | ||
| + | plt.ylabel(" | ||
| + | koordinatensystem.set_zlim(-100, | ||
| + | plot = koordinatensystem.plot_surface(z, | ||
| + | return fig | ||
| + | |||
| + | |||
| + | anim = animation.FuncAnimation(fig, | ||
| + | anim.save(" | ||
| + | |||
| + | plt.show() | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | === Simulation === | ||
| + | |||
| + | Die beim Simulieren nötige Formel findet sich hier: | ||
| + | |||
| + | < | ||
| + | # Start der Simulation | ||
| + | for i in range(1, iterationen + 1): | ||
| + | if i % 100 == 0: | ||
| + | print(f" | ||
| + | for z in range(1, n - 1): | ||
| + | for s in range(1, n - 1): | ||
| + | v[i, z, s] = v[i - 1, z, s] + ((u[i - 1, z - 1, s] - 2 * u[i - 1, z, s] + u[i - 1, z + 1, s]) + (u[i - 1, z, s - 1] - 2 * u[i - 1, z, s] + u[i - 1, z, s + 1])) * delta_t | ||
| + | u[i, z, s] = u[i - 1, z, s] + v[i - 1, z, s] * delta_t | ||
| + | </ | ||