~~NOTOC~~ Falls numpy etc. auf Schulrechnern nicht verfügbar: https://trinket.io/embed/python3/a5bd54189b ====== Wärmeleitungsgleichung simulieren ====== Die Mathematik und Formeln für die Iteration sind hier noch nicht dokumentiert (bisher an Tafel erklärt). Wärmeleitungsgleichung $u_{t}=\Delta u$. ===== Numpy und Matplotlib: einige Befehle kennenlernen (und eventuell Bibliotheken installieren) ===== import numpy as np from matplotlib import pyplot as plt # Zweidimensionale Tabelle (= zweidimensionales Array = zweidimensionale Matrix) mit Nullen als Einträgen erstellen. Beachte: # - erster Index Zeilennummer (also y-Koordinate), Indizes 0 bis 4=5-1; # - zweiter Index Spaltennummer (also x-Koordinate), Indizes von 0 bis 9=10-1. u = np.zeros((5, 10)) # Setze die Einträge an den Positionen (0, 0) und ((0, 19) auf 80. u[0, 0] = 80 u[0, 9] = 80 # Setze alle Einträge in der mittleren Zeile (Zeilennummer 2) auf 40. for j in range(10): u[2, j] = 40 # Ausgabe der Matrix print(u) plt.title(f"Have fun with numpy and matplotlib!") plt.xlabel("Spalten (zweite Indizes)") plt.ylabel(f"Zeilen (erste Indizes)") plt.pcolormesh(u, cmap=plt.cm.jet, vmin=0, vmax=100) plt.colorbar() plt.savefig("beispiel.png") plt.show() ===== Wärmeausbreitung (1-dimensional) in einem Stab simulieren ===== {{:lehrkraefte:snr:informatik:klasse-4:simulationen:stab-ort-zeit-diagramm.png?400|}} import numpy as np from matplotlib import pyplot as plt # Länge des Stabes n = 100 iterationen = 400 # alpha = Temperaturleitfähigkeit, siehe https://de.wikipedia.org/wiki/Temperaturleitf%C3%A4higkeit alpha = 1 delta_x = 1 # Die folgende Wahl des Zeitschritts delta_t = Δt sorgt dafür, dass die numerische Simulation stabil läuft (ohne Begründung). delta_t = (delta_x ** 2)/(4 * alpha) # Die folgende Konstante gamma hängt von delta_t ab und taucht dann in der Simulation auf. gamma = (alpha * delta_t) / (delta_x ** 2) # Zweidimensionale Tabelle (Array), erste Koordinate Iterationsnummer, zweite Koordinate Ort. u = np.zeros((iterationen + 1, n)) # Temperaturverteilung am Anfang u[0, 1] = 80 # Aufgabe: Eigene Temperaturverteilung am Anfang definieren! # Randwerte: Temperaturen an den Enden des Stabes (vorgegeben für alle Zeiten) for i in range(iterationen): u[i, 0] = 0 u[i, n - 1] = 0 # Start der Simulation for i in range(1, iterationen + 1): for x in range(1, n - 1): # Aufgabe: Die folgende Zeile so anpassen, dass die Temperaturentwicklung wie in der Aufgabenstellung erläutert verläuft. u[i, x] = u[i - 1, x - 1] # print(u) # Energie-/Wärme-Erhaltung (abgesehen von konstanten Randwerten) # print([sum(z) for z in u]) plt.title(f"Heatmap eines horizontalen Stabes\n Zeitschritt Δt = {delta_t} pro Iteration") plt.xlabel("x") plt.ylabel(f"Iterationen") plt.pcolormesh(u, cmap=plt.cm.jet, vmin=0, vmax=100) plt.colorbar() plt.savefig("stab-ort-zeit-diagramm.png") plt.show() ===== Beispiel zum Erstellen einer animierten gif-Datei (= kleiner Film) ===== 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 = 30 # Anzahl der Iterationen iterationen = 40 # Dreidimensionale Tabelle (Array), erste Koordinate Iterationsnummer (oft = Zeit), zweite Koordinate Zeile, dritte Koordinate Spalte. u = np.zeros((iterationen + 1, n, n)) # Temperaturverteilung am Anfang u[0, 5, 9] = 100 u[0, 5, 10] = 100 u[0, 5, n - 10] = 100 u[0, 5, n - 9] = 100 # Start der Simulation, i für Iterationsnummer, z für Zeilennummer, s für Spaltennummer for i in range(1, iterationen + 1): for z in range(1, n - 1): for s in range(1, n - 1): u[i, z, s] = (u[i - 1, z - 1, s - 1] + u[i - 1, z - 1, s + 1]) / 2 def animiere(i): print(i) plt.clf() plt.title(f"Heatmap, Iteration = {i}") plt.xlabel("s") plt.ylabel("z") plt.pcolormesh(u[i, :, :], cmap=plt.cm.jet, vmin=0, vmax=100) plt.colorbar() # plt.show() anim = animation.FuncAnimation(plt.figure(), animiere, interval=1, frames=iterationen, repeat=False) anim.save("ausbreitungsbeispiel.gif") ===== Wärmeausbreitung 2-dimensional, etwa in einem Zimmer mit beheizten Wänden und offenem Fenster ===== Zum Spass ist am Anfang noch eine Wärmeblase mitten im Raum... {{:lehrkraefte:snr:informatik:klasse-4:simulationen:waermeausbreitung-raum-mit-fenster.gif?400|}} 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 = 30 iterationen = 60 # alpha = Temperaturleitfähigkeit, siehe https://de.wikipedia.org/wiki/Temperaturleitf%C3%A4higkeit alpha = 2 delta_x = 1 delta_t = (delta_x ** 2)/(4 * alpha) gamma = (alpha * delta_t) / (delta_x ** 2) # Dreidimensionale Tabelle (Array), erste Koordinate Iterationsnummer, zweite Koordinate Zeile, dritte Koordinate Spalte. u = np.zeros((iterationen + 1, n, n)) # Randwerte: Temperaturen am Rand des Quadrates (vorgegeben für alle Zeiten) for i in range(iterationen): for s in range(n): u[i, 0, s] = 100 # Aufgabe: interessantere Randwerte vereinbaren! Etwa Raum mit offenem Fenster und Heizungen an den Wänden. # Anfangswerte # Aufgabe: Wer mag, definiert interessante Anfangswerte. u[0, n // 2, n // 2] = 100 # Start der Simulation for i in range(1, iterationen + 1): for z in range(1, n - 1): for s in range(1, n - 1): # Aufgabe: Wärmeausbreitungsformel anpassen! u[i, z, s] = u[i - 1, z - 1, s] def animiere(i): print(i) plt.clf() plt.title(f"Heatmap, Zeit t = {i * delta_t:.3f}") plt.xlabel("s") plt.ylabel("z") plt.pcolormesh(u[i, :, :], cmap=plt.cm.jet, vmin=0, vmax=100) plt.colorbar() # plt.show() anim = animation.FuncAnimation(plt.figure(), animiere, interval=1, frames=iterationen, repeat=False) anim.save("feld.gif")