1 Der Träger im Feuer
Stell dir ein Bürogeschoss vor, kurz nach Feierabend. Unter der massiven Betondecke spannt sich ein Stahlträger von Wand zu Wand, einen Meter lang, eine Handbreit hoch. Sein linkes Ende steckt tief im Auflager der kühlen Außenwand, die es bei rund 20 °C festhält. Und dann, eines Abends, bricht unter seinem rechten Ende ein Feuer aus — ein Papierstapel, ein Regal, ein schwelender Verteilerkasten. Heiße Brandgase lecken von unten an den Träger. Die Wärme kriecht ins Metall: Zuerst wird nur das rechte Ende heiß — bei einem heftigen Brand beginnt es sogar dunkelrot zu glühen —, und Stunde um Stunde schiebt sich die Hitze weiter nach links, dem kalten Auflager entgegen. Weil die Flammen den Träger von unten heizen, die Betondecke ihn aber von oben kühl hält, steht über seine Höhe ein Temperaturgefälle — und darunter beginnt er sich zu krümmen, leise, aber unaufhaltsam, wie ein Bimetallstreifen im Toaster.
Jetzt die Frage, um die es in diesem ganzen Buch geht: Woher weiß ein Computer, wie warm der Träger in der Mitte ist — dort, wo niemand ein Thermometer hält? Und woher kennt er die Verbiegung, bevor überhaupt jemand den Träger eingebaut und das Feuer entfacht hat?
Die kurze Antwort passt in einen Satz: Er zerlegt den Träger in viele kleine Stücke, stellt für jedes Stück eine einfache Beziehung auf und löst alle gemeinsam. Diese Stücke heißen finite Elemente — endliche, handliche Elemente statt des unendlich fein verschmierten echten Materials. Der ganze Rest des Buches macht nichts anderes, als diesen einen Satz mit Leben zu füllen.
Code
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(figsize=(8.5, 3.6))
# Betondecke oben als schraffiertes Band
ax.add_patch(plt.Rectangle((-0.05, 0.11), 1.15, 0.06, hatch="....",
facecolor="lightgray", edgecolor="black", lw=1.0,
zorder=2))
ax.text(0.5, 0.145, "Betondecke", ha="center", va="center", fontsize=9,
zorder=3)
# Der Träger als waagerechtes Band mit Temperaturverlauf (kalt links -> heiss rechts)
verlauf = np.linspace(0.0, 1.0, 256).reshape(1, -1) ** 2.2
ax.imshow(verlauf, extent=(0.0, 1.0, -0.05, 0.05), aspect="auto",
cmap="inferno", vmin=0.0, vmax=1.0, zorder=1)
ax.add_patch(plt.Rectangle((0.0, -0.05), 1.0, 0.10, fill=False,
edgecolor="black", lw=1.5, zorder=3))
# Auflager links (kühle Außenwand) als Schraffur
ax.add_patch(plt.Rectangle((-0.07, -0.13), 0.07, 0.26, hatch="///",
facecolor="lightsteelblue", edgecolor="black",
zorder=2))
ax.text(-0.035, -0.17, "kühles\nAuflager\n20 °C", ha="center", va="top",
fontsize=9, clip_on=False)
# Brandherd rechts unten als Flammen-Dreiecke
for mitte in (0.84, 0.93, 1.02):
ax.fill([mitte - 0.035, mitte, mitte + 0.035], [-0.20, -0.06, -0.20],
color="orangered", zorder=2)
ax.text(0.93, -0.23, "Brandherd", ha="center", va="top", color="orangered",
fontsize=10)
# Die Frage in der Mitte
ax.annotate("wie warm\nist es hier?", xy=(0.5, 0.0), xytext=(0.5, 0.24),
ha="center", va="bottom", fontsize=10, zorder=4,
arrowprops=dict(arrowstyle="->", color="black"))
ax.set_xlim(-0.22, 1.22)
ax.set_ylim(-0.30, 0.30)
ax.set_yticks([])
ax.set_xlabel("Ort entlang des Trägers (0 = kaltes Auflager, 1 m = Brandherd)")
ax.set_title("Ein Träger, ein Feuer — und eine Frage")
plt.tight_layout()
plt.show()
Was man hier sieht: die Szene, die uns fünfzehn Kapitel lang begleitet. Der Farbverlauf ist kein Schmuck, sondern die eigentliche Unbekannte — die Temperatur an jedem Ort, so wie eine Wärmebildkamera sie sähe. Am linken Ende kennen wir sie (das Auflager hält 20 °C), am rechten gibt der Brandherd sie vor; dazwischen soll der Computer sie ausrechnen. Genau dieselbe Szene taucht in jedem Kapitel wieder auf, nur jedes Mal mit etwas mehr geöffneter Motorhaube.
Echte Stahlträger haben fast nie einen vollen rechteckigen Querschnitt. Sie sind I-Profile (im Querschnitt wie ein liegendes H): zwei breite Gurte oben und unten, dazwischen ein dünner Steg. Das spart Stahl, ohne viel Tragfähigkeit zu verlieren. Für dieses Buch nehmen wir stattdessen einen massiven Rechteckquerschnitt, 0,1 m × 0,1 m. Das ist eine bewusste Vereinfachung: Sie hält die Geometrie und alle Rechnungen sauber, ohne dass am Kern der Methode etwas verloren ginge. Der Weg vom Rechteck zum echten Profil ist danach nur noch Formsache — dieselbe FEM, nur mit einer verwickelteren Form.
Lernziele
Nach diesem Kapitel kannst du …
- … in eigenen Worten erklären, was eine Simulation ist und warum man die Wirklichkeit dafür in kleine Stücke zerlegt,
- … an drei Beispielen benennen, wo die Finite-Elemente-Methode heute steckt (Fahrzeugbau, Elektronik, Brandschutz),
- … die fünf Bausteine jeder FEM-Rechnung aufzählen — Geometrie und Netz, Physik, Randbedingungen, Gleichungssystem, Löser,
- … am Finale-Programm vorhersagen, was ein feineres Netz oder heißere Brandgase qualitativ ändern — und es ausprobieren.
Vermutung: „Der Computer löst die Wärmegleichung exakt — er ist ja ein Computer, und Computer rechnen genau.”
Warum sie naheliegt: Ein Taschenrechner liefert \(7 \times 8 = 56\) auf Knopfdruck und ohne Fehler. Warum sollte er bei einem heißen Träger plötzlich nur schätzen?
Was stattdessen stimmt: Der Computer löst gar nicht das echte Problem, sondern ein Ersatzproblem aus endlich vielen Zahlen — den Temperaturen an einigen ausgewählten Punkten. Zwischen diesen Punkten rät er (auf sehr kluge Weise). Die ganze Kunst der Methode besteht darin, das Ersatzproblem so zu bauen, dass es der Wirklichkeit nahekommt. „Finite Elemente” ist genau der Name für diese Kunst. Dass ein Ersatzproblem trotzdem verblüffend genau sein kann — und woran man das erkennt — ist eines der wichtigsten Themen des Buches (Kapitel 12).
Der Titel dieses Kapitels ist mit Bedacht gewählt, aber er darf nicht missverstanden werden. Stahl verbrennt nicht wie Holz oder Papier, und er schmilzt auch nicht so bald: Baustahl wird erst bei rund 1500 °C flüssig. Was ihm im Brand gefährlich wird, setzt lange vor dem Schmelzen ein und ganz unauffällig — er verliert seine Festigkeit. Schon bei etwa 600 °C trägt Stahl nur noch ungefähr die Hälfte der Last, die er bei Zimmertemperatur aushält (CEN (Europäisches Komitee für Normung) 2005). Ein Träger versagt im Brand also nicht, weil er wegschmilzt, sondern weil er weich wird und unter seiner Last nachgibt.
Sichtbar wird die Hitze am Glühen. Erhitzt man Stahl im Dunkeln, beginnt er ab etwa 550 °C matt zu leuchten, und die Farbe verrät die Temperatur:
| Farbe | ungefähre Temperatur |
|---|---|
| beginnende Dunkelrotglut | ~550 °C |
| Kirschrot | ~800 °C |
| Hellrot bis Orange | ~1000 °C |
| Gelb | ~1200 °C |
| Weiß, dann flüssig | ~1500 °C |
Deshalb sprechen wir vom „glühenden” Träger nur dort, wo er es wirklich tut — jenseits von rund 550 °C. Und deshalb umhüllt man tragende Stahlteile im Bauwerk mit Brandschutzplatten oder dämmenden Anstrichen: Sie verzögern das Aufheizen, sodass der Träger im Ernstfall lange genug kühl und damit tragfähig bleibt. Genau diese Frage — wie lange hält der Träger? — treibt das ganze Buch an.
1.1 Das Finale zum Anfassen
Bevor wir irgendetwas erklären, darfst du mit dem fertigen Ergebnis spielen. Das folgende Programm ist im Kern dasselbe, das am Ende des Buches steht (Kapitel 15) — nur dass dort die Motorhaube offen ist und du jede Zeile kennst. Hier ist es eine Blackbox mit drei Reglern: wie heiß die Brandgase sind, wie fein der Träger zerlegt wird und wie lange das Feuer schon brennt.
Zuerst schauen wir dem Vorgang beim Ablaufen zu. Die folgende Darstellung rechnet die Minuten durch: Man sieht die Wärme vom Brandherd (rechts) ins kühl gehaltene Metall wandern und den Träger sich dabei krümmen (die Verbiegung ist stark überhöht dargestellt, sonst sähe man sie kaum).
Code
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import PolyCollection
from matplotlib.animation import FuncAnimation
from IPython.display import HTML
# Dieselbe 2D-Rechnung wie in der Blackbox weiter unten (NumPy-Kurzfassung
# des Finale-Programms aus Kapitel 15), hier mit einer Momentaufnahme je
# Zeitschritt fuer den Film.
laenge, hoehe, tiefe = 1.0, 0.1, 0.1
leitfaehigkeit, dichte, kapazitaet = 50.0, 7850.0, 460.0
e_modul, querkontraktion, ausdehnung = 210e9, 0.30, 12e-6
uebergang, luft, brandherd_ab, brandgas = 25.0, 20.0, 0.5, 500.0
nx, ny = 16, 4
minuten_gesamt, schritte = 30.0, 40
xs = np.linspace(0.0, laenge, nx + 1)
ys = np.linspace(0.0, hoehe, ny + 1)
gx, gy = np.meshgrid(xs, ys)
kn2 = np.column_stack([gx.ravel(), gy.ravel()])
tri2 = []
for zeile in range(ny):
for spalte in range(nx):
e = zeile * (nx + 1) + spalte
tri2.append((e, e + 1, e + nx + 2))
tri2.append((e, e + nx + 2, e + nx + 1))
tri2 = np.array(tri2)
def zelt2(p):
x, y = p[:, 0], p[:, 1]
b = np.array([y[1] - y[2], y[2] - y[0], y[0] - y[1]])
c = np.array([x[2] - x[1], x[0] - x[2], x[1] - x[0]])
a2 = x[0] * b[0] + x[1] * b[1] + x[2] * b[2]
return b / a2, c / a2, a2 / 2.0
n2 = len(kn2)
K2 = np.zeros((n2, n2))
Cap2 = np.zeros(n2)
for d in tri2:
b, c, A = zelt2(kn2[d])
K2[np.ix_(d, d)] += leitfaehigkeit * tiefe * A * (np.outer(b, b)
+ np.outer(c, c))
Cap2[d] += dichte * kapazitaet * tiefe * A / 3.0
unten2 = np.arange(nx + 1)
oben2 = ny * (nx + 1) + np.arange(nx + 1)
links2 = np.arange(ny + 1) * (nx + 1)
rechts2 = links2 + nx
sx, sy = laenge / nx * tiefe, hoehe / ny * tiefe
def stuecke2(anzahl, stueck):
w = np.full(anzahl, stueck)
w[0] = w[-1] = stueck / 2.0
return w
Rdiag2 = np.zeros(n2)
Rlast2 = np.zeros(n2)
for kante, fl, umg in [
(oben2, stuecke2(nx + 1, sx), np.full(nx + 1, luft)),
(rechts2, stuecke2(ny + 1, sy), np.full(ny + 1, brandgas)),
(unten2, stuecke2(nx + 1, sx),
np.where(kn2[unten2, 0] >= brandherd_ab, brandgas, luft))]:
Rdiag2[kante] += uebergang * fl
Rlast2[kante] += uebergang * fl * umg
fest2 = np.zeros(n2, dtype=bool)
fest2[links2] = True
frei2 = ~fest2
dt2 = minuten_gesamt * 60.0 / schritte
S2 = K2.copy()
S2[np.arange(n2), np.arange(n2)] += Cap2 / dt2 + Rdiag2
S2ff = S2[np.ix_(frei2, frei2)]
S2fc = S2[np.ix_(frei2, fest2)]
T2 = np.full(n2, luft)
frames_T = [T2.copy()]
for s in range(schritte):
rhs = Cap2 / dt2 * T2 + Rlast2
T2[frei2] = np.linalg.solve(S2ff, rhs[frei2] - S2fc @ T2[fest2])
frames_T.append(T2.copy())
# Mechanik: Steifigkeit einmal, thermische Kraefte je Momentaufnahme.
fkt = e_modul / (1.0 - querkontraktion**2)
Cm = fkt * np.array([[1.0, querkontraktion, 0.0],
[querkontraktion, 1.0, 0.0],
[0.0, 0.0, (1.0 - querkontraktion) / 2.0]])
Kg2 = np.zeros((2 * n2, 2 * n2))
bt_liste, dof_liste, flaechen_liste = [], [], []
for d in tri2:
b, c, A = zelt2(kn2[d])
B = np.zeros((3, 6))
B[0, 0::2] = b
B[1, 1::2] = c
B[2, 0::2] = c
B[2, 1::2] = b
dof = np.empty(6, dtype=int)
dof[0::2] = 2 * d
dof[1::2] = 2 * d + 1
Kg2[np.ix_(dof, dof)] += B.T @ Cm @ B * tiefe * A
bt_liste.append(B)
dof_liste.append(dof)
flaechen_liste.append(A)
festd2 = np.zeros(2 * n2, dtype=bool)
lk2 = np.where(np.isclose(kn2[:, 0], 0.0))[0]
festd2[2 * lk2] = True
festd2[2 * lk2 + 1] = True
freid2 = ~festd2
Kg2ff = Kg2[np.ix_(freid2, freid2)]
def mech2(T):
f = np.zeros(2 * n2)
for B, dof, A, d in zip(bt_liste, dof_liste, flaechen_liste, tri2):
dT = T[d].mean() - luft
eps0 = np.array([ausdehnung * dT, ausdehnung * dT, 0.0])
f[dof] += B.T @ (Cm @ eps0) * tiefe * A
u = np.zeros(2 * n2)
u[freid2] = np.linalg.solve(Kg2ff, f[freid2])
return u
frames_u = [mech2(T) for T in frames_T]
ueber2 = 0.3 * hoehe / max(np.abs(u).max() for u in frames_u)
tmax2 = frames_T[-1].max()
fig, ax = plt.subplots(figsize=(8.5, 3.2))
polys = PolyCollection([], cmap="inferno", edgecolors="white",
linewidths=0.3)
polys.set_clim(luft, tmax2)
ax.add_collection(polys)
ax.add_patch(plt.Rectangle((0.0, 0.0), laenge, hoehe, fill=False,
edgecolor="0.4", ls="--", lw=1.0))
ax.add_patch(plt.Rectangle((-0.05, -0.05), 0.05, hoehe + 0.10, hatch="///",
facecolor="lightsteelblue", edgecolor="black"))
ax.add_patch(plt.Rectangle((-0.05, hoehe + 0.025), laenge + 0.10, 0.028,
facecolor="0.82", edgecolor="0.5"))
for flamme in (0.60, 0.75, 0.90):
ax.fill([flamme - 0.04, flamme, flamme + 0.04],
[-0.075, -0.018, -0.075], color="orangered")
titel = ax.text(0.5, hoehe + 0.065, "", ha="center", fontsize=11)
ax.text(0.0, -0.093, "Verformung %.0f-fach überhöht" % ueber2,
fontsize=9, color="gray")
ax.set_xlim(-0.08, laenge + 0.08)
ax.set_ylim(-0.10, hoehe + 0.10)
ax.set_aspect("equal")
ax.set_yticks([])
ax.set_xlabel("Ort entlang des Trägers (m)")
fig.colorbar(polys, ax=ax, pad=0.02, shrink=0.8, label="Temperatur (°C)")
def zeichne(k):
u = frames_u[k]
vx = kn2[:, 0] + ueber2 * u[0::2]
vy = kn2[:, 1] + ueber2 * u[1::2]
polys.set_verts([np.column_stack([vx[d], vy[d]]) for d in tri2])
polys.set_array(frames_T[k][tri2].mean(axis=1))
titel.set_text("nach %4.1f Minuten" % (k * dt2 / 60.0))
return polys, titel
ani = FuncAnimation(fig, zeichne, frames=len(frames_T), interval=180,
blit=False)
plt.close(fig)
HTML(ani.to_jshtml())Was man sieht: Nach wenigen Minuten ist erst die äußerste rechte Ecke warm, der ganze Rest liegt noch kalt im Auflager. Stahl leitet Wärme nämlich eher zäh — und so reicht die spürbare Hitze selbst nach einer halben Stunde erst gut eine Handbreit, rund 16 cm, in den Träger hinein. Die Wärme kriecht. Die Verbiegung folgt ihr auf dem Fuß: Nur wo es heiß ist, krümmt sich das Metall. Beides zusammen — die kriechende Wärme und die daraus folgende Verformung — ist das Ziel des Buches.
Und nun die Blackbox selbst. In der HTML-Fassung läuft der folgende Code direkt in deinem Browser — und zwar keine vereinfachte Vorschau, sondern die echte Rechnung des großen Finales (Kapitel 15) in kompakter Form: Der Träger ist eine Fläche aus kleinen Dreiecken, die Brandgase wärmen ihn von unten rechts, die Betondecke kühlt ihn von oben, und aus dem Temperaturfeld folgt die Verformung. Ändere oben die drei Werte, drücke auf Ausführen und schau, was passiert — den „Maschinenraum” darunter musst du jetzt noch nicht verstehen, den öffnet das Buch Kapitel für Kapitel.
Zur Vorhersage von eben: Heißere Brandgase geben im gleichen Takt mehr Durchbiegung — genauer: Die Verformung wächst hier proportional zur Übertemperatur der Brandgase, also zu ihrem Abstand von den 20 °C des kalten Auflagers. Verdoppelst du diesen Abstand, verdoppelt sich auch die Verbiegung. Das ist kein Zufall und keine Selbstverständlichkeit; warum es so ist (und wann es nicht mehr stimmt), klärt sich erst in Kapitel 13. Fürs Erste zählt nur: Du hast einen Regler bewegt und eine Wirkung gesehen. Genau dieses Ausprobieren ist der rote Faden.
Diese Blackbox ist keine Attrappe: Sie rechnet die volle 2D-Finite-Elemente-Kette des großen Finales (Kapitel 15) — Wärmeleitung über die Fläche, Brandgase und Betondecke als Wärmeübergang am Rand, und daraus die Verformung. Weil die Flammen den Träger von unten heizen und die Decke ihn von oben kühl hält, ist seine Unterseite wärmer als seine Oberseite; die warme Unterseite dehnt sich stärker, und der Träger wölbt sich nach oben — wie ein Bimetallstreifen. Das ist genau die Physik, die die Kapitel 13 und 14 entwickeln.
Zwei Dinge sind trotzdem ehrlich zu sagen. Erstens rechnet der Maschinenraum hier mit dem fertigen Rechenpaket NumPy — als flinkem Rechenknecht für deinen Browser. Verstehen kann man daran nichts; darum baut das Buch dieselbe Maschine Kapitel für Kapitel in reinem Python nach, bis du in Kapitel 15 jede Zeile kennst. Zweitens bleibt es eine grobe Rechnung auf einem kleinen Netz — wie fein das Netz sein muss, damit man den Zahlen trauen darf, ist die Kernfrage von Kapitel 12.
1.2 Was ist eigentlich eine Simulation?
Eine Simulation lässt ein Stück Wirklichkeit im Rechner ablaufen, bevor (oder ohne dass) es in echt passiert. Das Kunststück dabei ist immer dasselbe und besteht aus drei Schritten:
- Zerlegen. Die Wirklichkeit ist unendlich fein — jeder noch so kleine Punkt des Trägers hat seine eigene Temperatur. Damit kann ein Rechner nicht umgehen; er kennt nur endlich viele Zahlen. Also teilen wir den Träger in eine überschaubare Zahl kleiner Stücke und merken uns die Temperatur nur an deren Ecken, den Knoten.
- Lokal rechnen. Für ein einzelnes kleines Stück ist die Physik einfach: Wärme fließt von warm nach kalt, und wie viel, hängt nur von den paar Nachbarknoten ab. Diese einfache lokale Beziehung schreibt man für jedes Stück getrennt auf — immer nach demselben Bauplan.
- Zusammensetzen. Die vielen kleinen lokalen Beziehungen teilen sich ihre Knoten und ergeben zusammengefügt ein großes Gleichungssystem. Löst man es, kennt man die Temperatur an allen Knoten auf einen Schlag.
Diese Denkweise ist nicht neu und nicht auf Träger beschränkt. Eine Wettervorhersage arbeitet genauso: Sie legt ein Gitter über die Landkarte, kennt für jede Gitterzelle Temperatur, Druck und Wind, und rechnet für jede Zelle aus, was ihre Nachbarn ihr im nächsten Zeitschritt zuschieben. Kein Meteorologe löst die Wirklichkeit „exakt” — er löst ein Ersatzproblem auf einem Gitter. Feineres Gitter, schärfere Vorhersage; gröberes Gitter, schnellere Rechnung. Genau dieser Kompromiss begegnet uns beim Träger wieder.
Code
import matplotlib.pyplot as plt
fig, achsen = plt.subplots(3, 1, figsize=(8.0, 4.6))
# (a) ein Stück
ax = achsen[0]
ax.add_patch(plt.Rectangle((0, 0), 1.0, 0.2, facecolor="whitesmoke",
edgecolor="black", lw=1.5))
ax.set_title("1 Stück", loc="left", fontsize=10)
# (b) vier Stücke
ax = achsen[1]
for k in range(4):
ax.add_patch(plt.Rectangle((k * 0.25, 0), 0.25, 0.2,
facecolor="whitesmoke", edgecolor="black",
lw=1.2))
ax.set_title("4 Stücke", loc="left", fontsize=10)
# (c) 64 Dreiecke: 16 Spalten x 2 Reihen Rechtecke, je diagonal geteilt
ax = achsen[2]
spalten, reihen = 16, 2
for i in range(spalten):
for j in range(reihen):
x0, y0 = i * (1.0 / spalten), j * (0.2 / reihen)
x1, y1 = x0 + 1.0 / spalten, y0 + 0.2 / reihen
ax.plot([x0, x1, x1, x0, x0], [y0, y0, y1, y1, y0], color="black",
lw=0.6)
ax.plot([x0, x1], [y0, y1], color="black", lw=0.6)
ax.set_title("64 Dreiecke", loc="left", fontsize=10)
for ax in achsen:
ax.set_xlim(-0.03, 1.03)
ax.set_ylim(-0.05, 0.25)
ax.set_aspect("equal")
ax.axis("off")
plt.tight_layout()
plt.show()
Was man hier sieht: Ein einziges Stück kann den Temperaturverlauf nicht abbilden — es kennt ja nur seine Ecken. Mit vier Stücken erahnt man die Kurve schon, mit vielen Dreiecken schmiegt sich das Netz eng an die Wirklichkeit. Das ist die zentrale Stellschraube jeder Simulation, und du hast sie eben am Regler „NETZ” selbst bedient.
Dass ein feineres Netz die Lösung glatter und näher an der Wirklichkeit macht, sieht man am Temperaturprofil unseres Trägers unmittelbar:
Code
import numpy as np
import matplotlib.pyplot as plt
leit = 50.0 / (7850.0 * 460.0)
def profil(zahl):
dx = 1.0 / (zahl - 1)
dt = 0.4 * dx * dx / (2.0 * leit)
schritte = int(1800.0 / dt) + 1
dt = 1800.0 / schritte
faktor = leit * dt / (dx * dx)
T = np.full(zahl, 20.0)
T[-1] = 500.0
for s in range(schritte):
T[1:-1] = T[1:-1] + faktor * (T[2:] - 2.0 * T[1:-1] + T[:-2])
return np.linspace(0.0, 1.0, zahl), T
fig, achsen = plt.subplots(1, 3, figsize=(9.0, 3.0), sharey=True)
for ax, (zahl, name) in zip(achsen, [(11, "grob"), (26, "mittel"),
(51, "fein")]):
x, T = profil(zahl)
ax.plot(x, T, "o-", ms=4, color="tab:red")
ax.set_title("%s (%d Knoten)" % (name, zahl), fontsize=10)
ax.set_xlabel("Ort (m)")
ax.grid(True, alpha=0.3)
achsen[0].set_ylabel("Temperatur (°C)")
plt.tight_layout()
plt.show()
Was man hier sieht: Alle drei Kurven erzählen dieselbe Geschichte — rechts heiß, links kalt —, aber das grobe Netz zeichnet sie mit wenigen groben Ecken, das feine mit einer glatten Linie. Weil Stahl die Wärme nur zäh weiterreicht, drängt sich der ganze Anstieg im rechten Viertel zusammen; genau dort trennt sich grob von fein. Für ein erstes Gefühl reicht grob; wer der Zahl in der Mitte trauen will, braucht fein. Wann „fein genug” erreicht ist, ist eine eigene Kunst (Kapitel 12).
1.3 Wo die finiten Elemente überall stecken
Der Träger im Feuer ist ein Lehrbeispiel — aber die Methode dahinter ist eine der meistgenutzten Rechentechniken der Ingenieurwelt. Drei Beispiele:
Das Auto. Wenn ein neues Automodell in den Crashtest geht, ist der teuerste Teil längst gelaufen — im Rechner. Seit den 1990er Jahren ist die Crash-Simulation Industriestandard: Ein komplettes Fahrzeugmodell besteht heute aus mehreren Millionen finiten Elementen, bei Spitzenmodellen sind es rund zehn Millionen, und ein Aufprall wird in winzigen Zeitschritten durchgerechnet. So sieht man, wo sich die Karosserie falten muss, damit die Insassen geschützt bleiben — bevor das erste Blech gebogen ist.
Das Handy. Warum überlebt das eine Gehäuse den Sturz auf den Gehweg und das andere nicht? Bevor ein Smartphone gebaut wird, lässt man es im Rechner tausendfach fallen. Aus verschiedenen Höhen, auf verschiedene Ecken, nach genormten Falltests: Die Simulation zeigt, wo im Glas die Spannung sich staut und wo eine Platine reißt. Ein paar Zehntelmillimeter mehr Rahmen an der richtigen Stelle — im Rechner gefunden, nicht im Reklamationslager.
Der Brandschutz. Genau unsere Szene ist ein eigener Ingenieurberuf. Bevor ein Stahltragwerk gebaut wird, muss jemand nachweisen, dass es im Brandfall lange genug steht, damit alle Menschen hinauskommen und die Feuerwehr löschen kann. Dieser Brandschutznachweis — oft mit finiten Elementen gerechnet — verfolgt, wie schnell sich die Träger erwärmen und wann sie ihre Tragfähigkeit verlieren. Das Ergebnis steckt in Kürzeln, die man an jeder Baustelle findet: R30, R60, R90 stehen für Widerstand (englisch resistance) über 30, 60 oder 90 Minuten. Ein Träger der Klasse R90 muss unter Last und Feuer mindestens anderthalb Stunden durchhalten. Ob eine Beplankung dick genug für R90 ist oder nicht, entscheidet oft genau so eine Rechnung, wie wir sie in diesem Buch aufbauen.
Allen dreien ist gemeinsam: Ein reales Objekt wird in finite Elemente zerlegt, für jedes Element gilt eine einfache Physik, und aus den vielen kleinen Beziehungen wird ein großes Gleichungssystem, das der Computer löst. Wer diesen Kern am Träger verstanden hat, versteht ihn überall.
1.4 Die fünf Bausteine und die Landkarte des Buches
Jede FEM-Rechnung — ob Träger, Auto oder Brücke — steht auf denselben fünf Bausteinen:
- Geometrie und Netz — die Form des Objekts und ihre Zerlegung in Elemente.
- Physik — das Naturgesetz, das in jedem Element gilt (bei uns: die Wärmeleitung, später die Verformung).
- Randbedingungen — was am Rand vorgegeben ist (links das kühle Auflager mit 20 °C, rechts die heißen Brandgase).
- Gleichungssystem — die vielen lokalen Beziehungen, zu einem großen System zusammengesetzt.
- Löser — das Verfahren, das dieses Gleichungssystem knackt.
Diese fünf Bausteine sind zugleich die Landkarte des Buches: Jedes kommende Kapitel füllt einen von ihnen mit Leben. Abbildung 1.6 zeigt, welches Kapitel welchen Baustein liefert.
Code
import matplotlib.pyplot as plt
bausteine = [
("Geometrie\n& Netz", "Kap. 10–11"),
("Physik", "Kap. 5, 6, 9"),
("Rand-\nbedingungen", "Kap. 8"),
("Gleichungs-\nsystem", "Kap. 3, 7"),
("Löser", "Kap. 4"),
]
farben = ["#cfe8f3", "#ffe0b3", "#ffd6d6", "#d9f0d3", "#e6dcf0"]
fig, ax = plt.subplots(figsize=(9.0, 3.0))
breite, luecke = 1.5, 0.4
for k, ((name, kapitel), farbe) in enumerate(zip(bausteine, farben)):
x0 = k * (breite + luecke)
ax.add_patch(plt.Rectangle((x0, 0), breite, 1.0, facecolor=farbe,
edgecolor="black", lw=1.3))
ax.text(x0 + breite / 2, 0.62, name, ha="center", va="center",
fontsize=10, weight="bold")
ax.text(x0 + breite / 2, 0.22, kapitel, ha="center", va="center",
fontsize=9)
if k < len(bausteine) - 1:
ax.annotate("", xy=(x0 + breite + luecke, 0.5),
xytext=(x0 + breite, 0.5),
arrowprops=dict(arrowstyle="-|>", color="black", lw=1.3))
ax.text((len(bausteine) * (breite + luecke) - luecke) / 2, 1.45,
"Python-Grundlagen: Kap. 2 · Verformung: Kap. 13–14 · "
"Prüfen & Vertrauen: Kap. 12 · das Finale: Kap. 15",
ha="center", va="center", fontsize=9, style="italic")
ax.set_xlim(-0.2, len(bausteine) * (breite + luecke) - luecke + 0.2)
ax.set_ylim(-0.2, 1.7)
ax.axis("off")
plt.tight_layout()
plt.show()
Was man hier sieht: die Reiseroute. Von links nach rechts entsteht eine FEM-Rechnung; von Kapitel zu Kapitel füllen wir die Kästen. Auffällig: Der Baustein „Gleichungssystem” kommt schon in Kapitel 3 — lange vor der Physik. Das ist Absicht. Wir bauen die komplette FEM-Maschinerie zuerst an einer Kette aus Federn, wo reine Schulalgebra genügt, und lassen die schwierigere Physik erst später einziehen.
Ein einziger Ausblick auf die Physik sei erlaubt, mehr Formel kommt in diesem Kapitel nicht vor. Das Naturgesetz hinter dem wandernden Farbband heißt Fouriersches Gesetz und sagt schlicht, wie stark die Wärme fließt:
\[ \text{Wärmestrom} \;=\; -\,\lambda \cdot (\text{Temperaturgefälle}). \]
Das \(\lambda\) ist die Wärmeleitfähigkeit (bei unserem Stahl \(50\ \mathrm{W/(m\,K)}\)), das Gefälle misst, wie schnell sich die Temperatur mit dem Ort ändert. Fällt die Temperatur zum Beispiel um \(280\ \mathrm{K}\) über den ganzen Meter — von 300 °C am beflammten Ende auf 20 °C am Auflager —, so ist das Gefälle \(280\ \mathrm{K/m}\) und der Wärmestrom \(50 \cdot 280 = 14\,000\ \mathrm{W/m^2}\), also 14 Kilowatt pro Quadratmeter. Durch die Querschnittsfläche unseres Trägers (\(0{,}01\ \mathrm{m^2}\)) fließen damit rund \(140\ \mathrm{W}\). Das Minuszeichen sagt nur: Die Wärme fließt bergab, vom Heißen zum Kalten. Diesen einen Satz zu einer vollständigen Träger-Rechnung auszubauen, ist die Aufgabe von Kapitel 5 bis Kapitel 9.
1.5 Woher die Methode kommt
Die Finite-Elemente-Methode ist keine Erfindung des Computerzeitalters allein, sondern eine Antwort auf ein sehr konkretes Problem: den Flugzeugflügel der 1950er Jahre. Schnellere, dünnere Tragflächen ließen sich mit den Formeln der klassischen Statik nicht mehr zuverlässig berechnen — ihre Form war zu unregelmäßig. Ingenieure bei Boeing und an der Universität Berkeley, unter ihnen M. J. Turner und Ray Clough, kamen Mitte der 1950er auf denselben Gedanken wie wir eben: Zerlege den komplizierten Flügel in viele kleine, einfache Dreiecke, für die man rechnen kann, und setze das Ganze wieder zusammen (Turner u. a. 1956). Den Namen „finite element” prägte Clough wenig später (Clough 1960).
Aus dieser Not entstanden fast alle Begriffe, die uns begegnen werden — Steifigkeit, Element, Assemblierung. Warum sie gerade so heißen und wie aus der Idee eine Methode wurde, erzählt Kapitel 3 ausführlich. Für jetzt genügt: Die Methode wurde erfunden, weil jemand ein reales Ding ausrechnen musste, das zu kompliziert für eine einzige Formel war. Genau davor stehen wir mit dem Träger im Feuer.
Roter Faden
Dieses Kapitel hat die Reise nur gezeigt, nicht angetreten. Alles, was du hier als Blackbox erlebt hast, wird geöffnet: Das Netz und seine Elemente bauen wir ab Kapitel 3 und in der Fläche ab Kapitel 10; die Physik der Wärme kommt in Kapitel 5 bis Kapitel 9; die Randbedingungen — das kühle Auflager und die Brandgase — bekommen in Kapitel 8 ihren Auftritt; das Gleichungssystem und sein Löser sind das Thema von Kapitel 3 und Kapitel 4; und warum sich der Träger überhaupt verbiegt, klärt sich in Kapitel 13 und Kapitel 14. Im Finale (Kapitel 15) steht dann genau dieses Programm wieder vor dir — mit offener Motorhaube.
Übungen
Ü 1.1 (Verstehen). Ordne die fünf Bausteine einer Brückensimulation zu: Was ist hier jeweils (a) die Geometrie und das Netz, (b) die Physik, (c) die Randbedingungen, (d) das Gleichungssystem, (e) der Löser? Beantworte es in eigenen Worten, ohne Rechner.
Eine mögliche Zuordnung: (a) Geometrie und Netz — die Form der Brücke (Träger, Pfeiler, Fahrbahn), zerlegt in viele kleine Elemente; (b) Physik — die Gesetze der Statik, die in jedem Element Kräfte und Verformung verknüpfen; (c) Randbedingungen — die Brücke ist an den Pfeilern im Boden verankert (dort keine Bewegung), und obendrauf drücken Verkehr und Wind; (d) Gleichungssystem — alle lokalen Kraft-Verformungs- Beziehungen zusammengesetzt; (e) Löser — das Rechenverfahren, das ausrechnet, wie stark sich jeder Knoten verschiebt. Dieselben fünf Bausteine wie beim Träger, nur größer.
Ü 1.2 (Verändern). Führe in der Blackbox oben zwei Experimente durch und notiere jeweils deine Beobachtung. (a) Lass NETZ und ZEIT fest und stelle die Brandgase nacheinander auf 300, 500 und 800 °C. Wie ändern sich die Mittentemperatur und die Hebung der Spitze? (b) Lass die Brandgase und ZEIT fest und schalte NETZ von “grob” über “mittel” auf “fein”. Ändert sich die Hebung stark? Und die Temperaturkurven?
(a) Mit heißeren Brandgasen steigen beide Werte, und zwar im gleichen Takt: Verdoppelt man die Übertemperatur der Brandgase (also den Abstand zu 20 °C), verdoppeln sich auch Mittentemperatur-Anstieg und Hebung. Von 300 auf 800 °C wächst die Hebung von rund 0,09 auf rund 0,24 mm — auf knapp das Dreifache, genau wie die Übertemperatur von 280 auf 780 K. Das liegt daran, dass in dieser Rechnung alles linear von der Temperatur abhängt — eine bewusste Vereinfachung, deren Grenzen Kapitel 13 bespricht.
(b) Überraschung: Die Hebung wächst beim Verfeinern deutlich — von rund 0,07 mm (“grob”) über 0,15 mm (“mittel”) auf 0,20 mm (“fein”). Das Netz ist also kein harmloser Schönheitsregler, sondern verändert das Ergebnis: Grobe Dreiecksnetze sind bei Biegung zu steif und nähern sich der wahren Verformung von unten. Auch die Temperaturkurven werden feiner gezeichnet, ändern sich aber kaum noch — die Wärme ist gutmütiger als die Verformung. Welche Zahl man am Ende glauben darf und wie man das prüft, ist so wichtig, dass ihr Kapitel 12 ganz gewidmet ist (und Kapitel 14 erklärt die zu steifen Dreiecke).
Ü 1.3 (Übertragen). Denk dir ein eigenes Simulationsproblem aus deinem Alltag aus — eine Bratpfanne auf der Herdplatte, das Eis in einem Getränk, die Wärmedämmung einer Hauswand. Zerlege es in die fünf Bausteine: Was ist die Geometrie, was die Physik, was sind die Randbedingungen? Du musst nichts ausrechnen, nur benennen.
Geometrie und Netz: die Pfanne (Boden und Griff), zerlegt in kleine Stücke. Physik: Wärmeleitung im Metall, wie beim Träger. Randbedingungen: Der Boden liegt auf der heißen Herdplatte (dort eine hohe Temperatur vorgegeben), das Griffende hängt in der Zimmerluft. Gleichungssystem und Löser: wie gehabt — alle lokalen Beziehungen zusammensetzen und lösen. Ergebnis: wie warm der Griff wird, ohne ihn anzufassen. Es ist im Kern dieselbe Rechnung wie beim Träger im Feuer.
Das Kleingedruckte
Dieses Kapitel hat bewusst mehr versprochen als bewiesen. Das Finale-Programm ist eine Vorschau: Sein Wärmeteil rechnet echt, aber grob; sein Biege-Teil schätzt die Verformung mit einer stark vereinfachten Formel, die nur ein Gefühl vermitteln soll. Auch die Annahme über den Temperaturunterschied zwischen Unter- und Oberseite und die lineare Kopplung von Wärme und Verformung sind Näherungen, die wir erst ab Kapitel 13 durch die echte Rechnung ersetzen. Ebenso ist der massive Rechteckquerschnitt eine Vereinfachung gegenüber dem echten I-Profil, und wir behandeln alle Materialkennwerte als temperaturunabhängig — obwohl Stahl in Wahrheit mit steigender Hitze weicher wird, wie der Kasten weiter oben schon andeutet. Nichts davon musst du jetzt glauben — du sollst es am Ende des Buches selbst herleiten und einordnen können. Bis dahin gilt die einfachste aller Regeln: erst ausprobieren, dann verstehen.