In Kapitel 8 entstand die exakte Bedingung des Kontinuums: In jedem Punkt muss die räumliche Änderung der Spannung die innere Last ausgleichen — eine partielle Differentialgleichung. Das ist die starke Form: Gleichgewicht buchstäblich überall, und sie verlangt von der Lösung eine zweite Ableitung. Dieses Kapitel formt dieselbe Bedingung so um, dass sie nur noch erste Ableitungen verlangt: die schwache Form. Sie fordert Gleichgewicht nicht punktweise, sondern „im gewichteten Mittel“, geprüft mit Testfunktionen — und weil sie weniger Glätte verlangt, verträgt sie geknickte Lösungen und lässt sich, auf endlich viele Ansatzfunktionen eingeschränkt, in ein lineares Gleichungssystem\(K\,u = f\) verwandeln — der Bogen zurück zu Kapitel 5, jetzt fürs Kontinuum. Am Kapitelende schließt Teil III.
Lernziele
Nach diesem Kapitel kannst du
den Unterschied zwischen „in jedem Punkt exakt“ (starke Form) und „im gewichteten Mittel gegen jede zulässige Testfunktion“ (schwache Form) in Worten erklären und benennen, dass „schwach“ für eine geringere Glätteanforderung steht,
eine Testfunktion als „Fühler“ deuten, mit dem man das Gleichgewicht abfragt, und das Prinzip der virtuellen Arbeit anschaulich nachvollziehen,
erklären, warum die schwache Form nur erste Ableitungen braucht und damit für stückweise lineare Ansätze passt,
benennen, wie die schwache Form durch Einschränkung auf endlich viele Ansatzfunktionen wieder zu K·u = f wird — der Kreis zurück zu Kapitel 4 und 5.
Bevor das Kapitel beginnt, steht sein Rechenwerk: der schematische Modellstab mit seinen vier Größen, die exakte Lösung als Prüfstein, das fertige System \(K\,u = f\), die beiden Arbeitsintegrale und die Fühler-Rechnung. Es ist reines Python ohne Bibliotheken und eingeklappt — wer wissen will, woher ein Name im Kapitel kommt, klappt es auf und findet ihn. Es rechnet, gibt aber nichts aus: Keine Zahl nimmt einer Vorhersage etwas vorweg.
Das Rechenwerk dieses Kapitels — zum Nachlesen aufklappen
# Reine Python-Werkbank (keine Bibliotheken): der interne Rechenkern dieses# Kapitels. Er darf rechnen, nimmt aber keiner Vorhersage etwas vorweg; die# sichtbaren Prüfblöcke weiter unten kommen erst nach Frage, Vorhersage,# Darstellung, Deutung und Formel. Numerisch gleich# gehalten mit js/kap09_schwache_form.js (getrennte Implementierungen,# die gegeneinander geprüft werden).import mathdef komma(x, stellen=2):"""Deutsche Kommadarstellung mit Endnullen-Trimmung; Minuszeichen −.""" s =f"{x:.{stellen}f}"if"."in s: s = s.rstrip("0").rstrip(".")return s.replace("-", "−").replace(".", ",")def komma_sig(x, n=3):"""Deutsche Darstellung mit n signifikanten Stellen (ohne e-Notation); echte Rundungsreste (< 10⁻¹²) werden als 0 gezeigt, sonst NIE nullgeschnappt."""ifabs(x) <1e-12:return"0" s =f"{x:.{n}g}"if"e"in s or"E"in s: s =f"{x:.12f}".rstrip("0").rstrip(".")return s.replace("-", "−").replace(".", ",")# --- Schematischer Modellstab (OHNE Einheit): fest bei x = 0, freies rechtes# Ende bei x = L, konstante innere Last b (Volumenkraft). Querschnittsfläche A# symbolisch, hier A = 1 (Rechnung je Einheitsquerschnitt). Mit Hooke# σ = E·du/dx (Kapitel 6) und dem Schnittkraftgesetz N = E·A·du/dx lautet die# starke Form −(E·A·u')' = A·b. Die exakte Lösung ist bekannt (A kürzt sich# heraus) — KEINE Kanon-/Referenzzahlen, keine Ferse.LAENGE =1.0# Länge L des Modellstabs (schematisch, ohne Einheit)E_MODUL =1.0# E-Modul E (schematisch, ohne Einheit)QUERSCHNITT =1.0# Querschnittsfläche A = 1 (Rechnung je Einheitsquerschnitt)LAST_B =1.0# konstante innere Last b (schematisch, ohne Einheit)FUEHLER_HALBBREITE =0.18# halbe Breite der Zelt-Testfunktion (schematisch)def exakte_verschiebung(x):"""Exakte (starke) Lösung: −(E·A·u')' = A·b, u(0) = 0, u'(L) = 0. Ergebnis u(x) = (b/E)·(L·x − x²/2) — A kürzt sich heraus."""return (LAST_B / E_MODUL) * (LAENGE * x - x * x /2.0)def exakte_dehnung(x):"""Exakte Dehnung du/dx = (b/E)·(L − x); am freien Ende (x = L) null."""return (LAST_B / E_MODUL) * (LAENGE - x)def system_matrix(n):"""Das FERTIGE globale System K der schwachen Form mit n stückweise linearen Ansätzen (Tridiagonalgestalt, direkt aufgestellt). Einträge E·A/h. WIE dieses System Element für Element entsteht (lokale Matrizen, Assemblierung), zeigt Kapitel 10 — hier zählt nur, DASS ein K·u = f entsteht. Freie Knoten 1..n (Knoten 0 ist fest)."""ifint(n) != n or n <1:raiseValueError(f"Zahl der Elemente n muss ganzzahlig ≥ 1 sein: {n}") n =int(n) h = LAENGE / n k = E_MODUL * QUERSCHNITT / h K = [[0.0] * n for _ inrange(n)]for i inrange(n): K[i][i] =2.0* k if i < n -1else k # freier Endknoten: nur kif i >0: K[i][i -1] =-kif i < n -1: K[i][i +1] =-kreturn Kdef last_vektor(n):"""Der Lastvektor f aus der konstanten inneren Last b (gewichtete Mittel der Zelt-Ansätze): innere Knoten A·b·h, der freie Endknoten A·b·h/2."""ifint(n) != n or n <1:raiseValueError(f"Zahl der Elemente n muss ganzzahlig ≥ 1 sein: {n}") n =int(n) h = LAENGE / n f = [QUERSCHNITT * LAST_B * h] * n f[n -1] = QUERSCHNITT * LAST_B * h /2.0# freier Endknoten: halbe Lastreturn fdef loese_system(K, f):"""Gauß-Elimination ohne Pivotsuche (K symmetrisch, dominant) — dasselbe Verfahren wie in Kapitel 5, hier für das kleine System der schwachen Form.""" n =len(f) a = [zeile[:] for zeile in K] b = f[:]for s inrange(n): p = a[s][s]if p ==0.0:raiseValueError("Pivot ist null — System nicht lösbar")for r inrange(s +1, n): faktor = a[r][s] / pif faktor !=0.0:for c inrange(s, n): a[r][c] -= faktor * a[s][c] b[r] -= faktor * b[s] x = [0.0] * nfor r inrange(n -1, -1, -1): summe = b[r]for c inrange(r +1, n): summe -= a[r][c] * x[c] x[r] = summe / a[r][r]return xdef galerkin_knoten(n):"""Die Knotenwerte der schwachen Näherung: K·u = f lösen; Knoten 0 fest (0).""" x = loese_system(system_matrix(n), last_vektor(n))return [0.0] + xdef _feld_aus_knoten(u, n, x):"""Stückweise lineare Interpolation der Knotenwerte an der Stelle x.""" h = LAENGE / nif x <=0.0:return u[0]if x >= LAENGE:return u[n] i =int(x / h)if i >= n: i = n -1 t = (x - i * h) / hreturn u[i] * (1.0- t) + u[i +1] * tdef galerkin_feld(n, x):"""Die schwache Näherungslösung (Polygonzug durch die Knotenwerte) bei x."""return _feld_aus_knoten(galerkin_knoten(n), n, x)def _mess_stellen(n):"""Knoten und Elementmitten — an ihnen liegt das Maximum des Abstands je Element (linear: Mitte; Treppe: Knoten).""" h = LAENGE / n stellen = [i * h for i inrange(n +1)] stellen += [(i +0.5) * h for i inrange(n)]return stellendef konvergenz_fehler(n):"""Größter Abstand |schwach − stark| (an Knoten und Elementmitten ausgewertet, dort liegt das Maximum). Fällt in genau diesem 1D-Sonderfall wie h².""" u = galerkin_knoten(n)returnmax(abs(_feld_aus_knoten(u, n, x) - exakte_verschiebung(x))for x in _mess_stellen(n))def knoten_fehler(n):"""Größter Abstand AN den Knoten. In diesem 1D-Sonderfall (konstanter Koeffizient, exakte Lastintegration) ~ 0 (Knoten-Exaktheit).""" u = galerkin_knoten(n) h = LAENGE / nreturnmax(abs(u[i] - exakte_verschiebung(i * h)) for i inrange(n +1))def ansatz_feld(n, art, x):"""Wie ein Ansatz das Verschiebungsfeld DARSTELLT (reiner Darstellungsversuch, keine gerechnete FEM-Lösung): „konstant“ = Treppe (ein Wert je Element, Wert in der Elementmitte), „linear“ = Polygonzug der schwachen Näherung (Zelt-Ansätze).""" h = LAENGE / n xx =min(max(x, 0.0), LAENGE) i =int(xx / h)if i >= n: i = n -1if art =="konstant":return exakte_verschiebung((i +0.5) * h)if art =="linear":return _feld_aus_knoten(galerkin_knoten(n), n, xx)raiseValueError(f"Ansatz muss 'konstant' oder 'linear' sein: {art}")def ansatz_fehler(n, art):"""Größter Abstand des Ansatzes von der exakten Lösung (Knoten + Elementmitten)."""returnmax(abs(ansatz_feld(n, art, x) - exakte_verschiebung(x))for x in _mess_stellen(n))def ansatz_innere_dehnung(n, art):"""Betragsgrößte Dehnung du/dx INNERHALB eines Elements: „konstant“ → 0 (flache Stufen tragen keine Dehnung), „linear“ → nicht null (jedes Element trägt eine konstante Dehnung)."""if art =="konstant":return0.0if art =="linear": u = galerkin_knoten(n) h = LAENGE / nreturnmax(abs((u[i +1] - u[i]) / h) for i inrange(n))raiseValueError(f"Ansatz muss 'konstant' oder 'linear' sein: {art}")STOERUNG_VON, STOERUNG_BIS =0.1, 0.4# Träger der örtlichen Störungdef mittelpunktsumme(funktion, von, bis, teile=2000):"""Fläche unter einer Kurve als Mittelpunktsumme (Verfahren aus Kapitel 7)."""ifint(teile) != teile or teile <1:raiseValueError(f"Zahl der Teile muss ganzzahlig ≥ 1 sein: {teile}") h = (bis - von) / teilereturn h *sum(funktion(von + (k +0.5) * h) for k inrange(int(teile)))def innere_arbeit(v_strich, teile=2000):"""Arbeit der inneren Spannungen bei der gedachten Verschiebung v: das Integral über E·A·u'·v', mit u der exakten Lösung."""return mittelpunktsumme(lambda x: E_MODUL * QUERSCHNITT * exakte_dehnung(x) * v_strich(x),0.0, LAENGE, teile)def aeussere_arbeit(v, teile=2000):"""Arbeit der äußeren Last bei der gedachten Verschiebung v: das Integral über A·b·v."""return mittelpunktsumme(lambda x: QUERSCHNITT * LAST_B * v(x), 0.0, LAENGE, teile)def stoerung(x):"""Örtliche Störung des Feldes: eine Beule, die NUR zwischen 0,1 und 0,4 sitzt und außerhalb exakt null ist (am festen Ende ohnehin null)."""if x <= STOERUNG_VON or x >= STOERUNG_BIS:return0.0return math.sin(math.pi * (x - STOERUNG_VON)/ (STOERUNG_BIS - STOERUNG_VON))def kandidat_verschiebung(amp, x):"""Kandidatenfeld für die Fühler-Animation: exakte Lösung plus abklingende örtliche Beule. Bei amp = 0 ist es die Lösung selbst."""return exakte_verschiebung(x) + amp * stoerung(x)def fuehler(x, mitte, halbbreite=FUEHLER_HALBBREITE):"""Zelt-Testfunktion (Fühler): 1 in der Mitte, linear auf 0 an den Rändern."""ifnot halbbreite >0:raiseValueError(f"Halbbreite muss positiv sein: {halbbreite}") d =abs(x - mitte)returnmax(0.0, 1.0- d / halbbreite)def gewichtete_abweichung(amp, mitte, halbbreite=FUEHLER_HALBBREITE):"""Gewichtete Gleichgewichtsabweichung des Kandidatenfeldes, abgefragt mit dem Zelt-Fühler an der Stelle mitte: die schwache Residuen-Größe ∫ E·A·w'·v' dx − ∫ A·b·v dx (freies Ende, v(0) = 0). Der Fühler muss GANZ im Gebiet liegen — ungültige (randnahe) Zentren werden abgelehnt. Bei amp = 0 (exakte Lösung) ist die Abweichung NULL."""ifnot halbbreite >0:raiseValueError(f"Halbbreite muss positiv sein: {halbbreite}")if mitte - halbbreite <-1e-12or mitte + halbbreite > LAENGE +1e-12:raiseValueError(f"Fühler nicht ganz im Gebiet (nur innere Zelte): {mitte}")def w(x):return kandidat_verschiebung(amp, x) innere = E_MODUL * QUERSCHNITT * (2.0* w(mitte) - w(mitte - halbbreite) - w(mitte + halbbreite)) / halbbreite last = QUERSCHNITT * LAST_B * halbbreitereturn innere - last
Dazu kommen die Zeichenwerkzeuge der Kapitelbilder: die echte Fersenkontur, die Orientierung, der Maßstab — und zwei fertige Bildfunktionen aus dem Kapitelmodul programme/kap09/zeichnungen.py, die weiter unten die Knotenpunkte auf die Parabel und die Konvergenzgerade auftragen. Auch diese Zelle ist eingeklappt; sie trägt keinen Gedanken, nur Bildmechanik.
Die Zeichenwerkzeuge der Kapitelbilder
# --- Nur Zeichenhilfen (numpy/matplotlib): Kontur, Orientierung, Achsen. Diese# Zelle wird vom Gleichheitstest übersprungen (sie importiert numpy/matplotlib).import jsonimport pathlibimport sysimport numpy as npimport matplotlib.pyplot as pltfrom matplotlib.ticker import FuncFormatterfrom matplotlib.path import Path as MplPathfrom matplotlib.patches import PathPatch, FancyArrow# Zeichenmechanik der Werkbank-Bilder (Muster 3): der Lehrgedanke bleibt in den# sichtbaren Zellen, das Matplotlib-Beiwerk liegt in programme/kap09.sys.path.insert(0, str(pathlib.Path("programme/kap09").resolve()))from zeichnungen import (zeichne_knoten_auf_parabel, zeichne_konvergenz_ordnung2)# Echte Kalkaneus-Kontur (48 Punkte, 66 × 42,06 mm), aus der JSON-Datei; niemals# das zugrunde liegende Bild selbst (nur die extrahierte Form ist frei). Die# Ferse-Bilder dieses Kapitels sind KONZEPT-SKIZZEN mit echter Kontur, aber# OHNE Feldwerte — gerechnete Spannungs- und Verschiebungsfelder zeigt das Buch# ab Kapitel 11._kontur = json.loads( pathlib.Path("../geometrie/kalkaneus_kontur.json").read_text())KONTUR = np.array(_kontur["punkte"]) *1000.0# m -> mm_PFAD = MplPath(KONTUR)def de_achse(ax):"""Achsen-Tickbeschriftung auf deutsche Kommas umstellen."""def deutsch(wert, _pos):return komma_sig(wert, 3) f = FuncFormatter(deutsch) ax.xaxis.set_major_formatter(f) ax.yaxis.set_major_formatter(f)def kontur_und_orientierung(ax):"""Fersenschnitt füllen und mit Orientierung (hinten/vorn/oben) versehen.""" ax.fill(KONTUR[:, 0], KONTUR[:, 1], color="#f0e2d0", ec="#a9825f", lw=1.6, zorder=1) ax.text(46, 9, "Fersenbein", fontsize=8, color="#8a6a4a", ha="center", zorder=2) ax.text(-13, 47, "hinten (Ferse)", fontsize=9, color="#666") ax.text(46, 47, "vorn (Zehen)", fontsize=9, color="#666")def orientierung_extra(ax):"""„oben ↑“-Pfeil und 10-mm-Maßstabsbalken (P2-Bildregel).""" ax.annotate("oben", xy=(-11, 40), xytext=(-11, 26), fontsize=9, color="#444", ha="center", arrowprops=dict(arrowstyle="->", color="#444", lw=1.4)) ax.plot([54, 64], [-2, -2], color="#333", lw=2.4, solid_capstyle="butt") ax.plot([54, 54], [-3.2, -0.8], color="#333", lw=1.2) ax.plot([64, 64], [-3.2, -0.8], color="#333", lw=1.2) ax.text(59, -5.4, "10 mm", ha="center", fontsize=8, color="#333")def kontur_clip(ax):"""Clip-Pfad aus der Kontur: Formen werden am Rand beschnitten.""" clip = PathPatch(MplPath(np.vstack([KONTUR, KONTUR[:1]])), transform=ax.transData, fc="none", ec="none") ax.add_patch(clip)return clipdef clip_kuenstler(kuenstler, clip):"""set_clip_path auf ein einzelnes oder mehrere matplotlib-Objekte anwenden."""for k in (kuenstler ifisinstance(kuenstler, (list, tuple)) else [kuenstler]):if k isnotNone: k.set_clip_path(clip)
9.1 Der Aufhänger: der Prüfer misst nicht jeden Punkt
Eine Ingenieurin nimmt eine Brücke ab. Sie misst nicht die Durchbiegung an unendlich vielen Stellen; sie fährt Testlasten über das Tragwerk und schaut, ob sich alles ausgleicht. Die schwache Form prüft das Gleichgewicht genauso: nicht Punkt für Punkt, sondern gegen Testfunktionen, gewichtet gemittelt. Was sie dabei gewinnt, ist nicht weniger Prüfung — gefordert wird sie weiterhin gegen jede zulässige Testfunktion —, sondern weniger Anspruch an die Lösung: Sie braucht nur noch erste Ableitungen. Warum das die Tür zum Rechner öffnet, zeigt dieses Kapitel an demselben Zugstab, an dem Kapitel 8 die Gleichung aufgestellt hat — und den man von Hand nachrechnen kann.
9.2 Drei Stufen: stark, schwach, diskret
Der Weg zur FEM führt über drei Stufen, die man auseinanderhalten muss.
Starke Form. Genau die Gleichung, die Kapitel 8 am Zugstab aufgestellt hat, \(-(E\,A\,u')' = A\,b\), gilt in jedem Punkt. Sie verlangt eine zweite Ableitung der Verschiebung: einmal wird abgeleitet, um aus der Verschiebung die Dehnung zu machen, ein zweites Mal für die Bilanz.
Kontinuierliche schwache Form. Man multipliziert die Gleichung mit einer Testfunktion\(v\) und integriert; nach partieller Integration steht dort nur noch \(\int E\,A\,u'\,v' = \int A\,b\,v\). Diese Bedingung muss für alle zulässigen Testfunktionen \(v\) gelten (weiterhin unendlich viele), aber sie verlangt nur noch erste Ableitungen. Genau das meint „schwach“: geringere Glätteanforderung — nicht weniger Bedingungen.
Diskrete Galerkin-Form. Jetzt schränkt man Lösung und Testfunktionen auf einen endlichen Raum ein — stückweise lineare Zelte über wenigen Knoten. Aus den unendlich vielen Bedingungen werden endlich viele, und daraus wird \(K\,u = f\).
Abbildung 9.1 stellt die ersten beiden Stufen untereinander; die dritte folgt weiter unten am Regler.
Code
import numpy as npimport matplotlib.pyplot as pltfig, (axo, axu) = plt.subplots(2, 1, figsize=(4.8, 6.9))# Oben: starke Form — Punktraster „an jedem Punkt = 0“, am Rand beschnitten.kontur_und_orientierung(axo)orientierung_extra(axo)clip_o = kontur_clip(axo)for x in np.arange(2, 66, 3.2):for y in np.arange(2, 42, 3.2):if _PFAD.contains_point((x, y)): pkt, = axo.plot(x, y, ".", color="#5b6b7a", ms=3.2, zorder=3) clip_kuenstler(pkt, clip_o)axo.set_title("starke Form: „= 0 an JEDEM Punkt“", fontsize=10, color="#333")axo.set_xlim(-16, 70); axo.set_ylim(-8, 52)axo.set_aspect("equal"); axo.axis("off")# Unten: schwache Form — schematische Zelt-Testfunktionen, am Rand geclippt.kontur_und_orientierung(axu)orientierung_extra(axu)clip_u = kontur_clip(axu)for xm, hoehe in [(26, 12), (32, 12), (38, 12)]: linie, = axu.plot([xm -3, xm, xm +3], [16, 16+ hoehe, 16], color="#2a7d2a", lw=1.8, zorder=4) pkt, = axu.plot(xm, 16+ hoehe, "o", color="#2a7d2a", ms=4, zorder=5) clip_kuenstler([linie, pkt], clip_u)axu.set_title("schwache Form: „= 0 im Mittel gegen JEDE zulässige Testfunktion“", fontsize=10, color="#2a7d2a")axu.set_xlim(-16, 70); axu.set_ylim(-8, 52)axu.set_aspect("equal"); axu.axis("off")plt.tight_layout()plt.show()
Abbildung 9.1: Konzept-Skizze (echte Kalkaneus-Kontur, KEINE Feldwerte), untereinander. Oben die starke Form: Gleichgewicht an jedem einzelnen Punkt (Punktraster, am Rand beschnitten). Unten die kontinuierliche schwache Form: geprüft im gewichteten Mittel gegen jede zulässige Testfunktion (schematische Zelte). Beide fordern unendlich viele Bedingungen — der Unterschied ist die geringere Glätteanforderung unten, nicht eine endliche Anzahl. Die endliche Einschränkung (Galerkin) ist ein dritter, späterer Schritt. Sagittalschnitt, x nach vorn, y nach oben.
Deutung. Oben steht eine punktweise Forderung, die eine zweite Ableitung verlangt. Unten steht dieselbe Physik als Mittelwert gegen Testfunktionen — mit nur ersten Ableitungen. Beide sind zunächst unendlich viele Bedingungen; die endliche, rechenbare Fassung entsteht erst, wenn man die Testfunktionen auf wenige Zelte einschränkt (weiter unten). Warum das nicht ungenauer, sondern lösbarer ist, klärt der Rest des Kapitels am Zugstab.
9.3 Derselbe Stab, jetzt mit freiem Ende
Gerechnet wird am Zugstab aus Kapitel 8: links fest eingespannt, \(u(0) = 0\), im ganzen Stab die konstante innere Last \(b\), und die Gleichung unverändert \(-(E\,A\,u')' = A\,b\). Eine einzige Angabe ändert sich, und zwar am rechten Ende. Kapitel 8 hat dort mit der Kraft \(F\) gezogen, also \(E\,A\,u'(L) = F\); hier zieht niemand, also ist \(F = 0\) und damit \(u'(L) = 0\) — das freie Ende. Das ist der einfachste Fall, den dieser Stab hergibt, und genau deshalb steht er hier: An ihm lässt sich jede Behauptung dieses Kapitels von Hand nachprüfen. Seine vier Größen \(E\), \(A\), \(L\) und \(b\) stehen alle auf eins und tragen keine Einheit; Kapitel 8 rechnet mit anderen Zahlen (\(E = 2\), \(F = 1{,}2\)), dieselbe Bauart. Für diesen Fall ist die exakte Lösung bekannt (die Fläche \(A\) kürzt sich heraus):
Die Dehnung ist am eingespannten Ende am größten und am freien Ende null. Diese exakte Kurve ist der Prüfstein für die schwache Näherung. Tabelle 9.1 belegt sie an sechs Stellen (sie verrät keine Vorhersage — die exakte Lösung ist die starke Referenz, nicht die noch offene schwache Näherung):
Tabelle 9.1: Die exakte (starke) Lösung des schematischen Modellstabs, ausgewertet an sechs Stellen. Alle Größen ohne Einheit: L = 1, E = 1, A = 1, b = 1.
Ort \(x\)
exakte Verschiebung \(u(x)\)
exakte Dehnung \(\mathrm{d}u/\mathrm{d}x\)
0
0
1
0,2
0,18
0,8
0,4
0,32
0,6
0,6
0,42
0,4
0,8
0,48
0,2
1
0,5
0
Deutung. Die Verschiebung wächst vom festen Ende (0) bis zum freien Ende auf den größten Wert \(b\,L^2/(2E) = 0{,}5\); die Dehnung fällt geradlinig von \(b\,L/E\) am festen Ende auf null am freien Ende. Das ist die starke Lösung — die Referenz, gegen die wir die schwache Näherung halten.
9.4 Der Fühler: das Gleichgewicht abtasten
Die schwache Form entsteht in zwei Schritten. Erstens: die Gleichgewichtsbedingung \(-(E\,A\,u')' = A\,b\) nicht für sich stehen lassen, sondern mit einer Testfunktion \(v\) — dem „Fühler“ — multiplizieren und über den Stab aufintegrieren (das Integral aus Kapitel 7):
Ein einzelner Fühler prüft das Gleichgewicht nicht mehr punktweise, sondern gewichtet gemittelt über den Bereich, den er berührt — und nur über ihn. Abbildung 9.2 zeigt drei solche Fühler über dem Stab, jeden an einer anderen Stelle. Ihre Form ist ein Zelt: in der Mitte eins, an den Rändern null. Im Studium heißt ein solches Zelt eine Hutfunktion; dieses Buch bleibt beim Zelt.
Code
import numpy as npimport matplotlib.pyplot as pltfig, (axs, axf) = plt.subplots(2, 1, figsize=(7.0, 4.8), gridspec_kw={"height_ratios": [0.55, 1]})# Oben: der Stab mit Einspannung, freiem Ende und innerer Last.axs.add_patch(plt.Rectangle((0, -0.16), 1, 0.32, fc="#f0e2d0", ec="#a9825f", lw=1.6))axs.plot([0, 0], [-0.30, 0.30], color="#333", lw=2.4)for y in np.linspace(-0.30, 0.24, 7): axs.plot([-0.05, 0.0], [y, y +0.06], color="#333", lw=1.0)for xp in np.linspace(0.08, 0.86, 8): axs.annotate("", xy=(xp +0.06, 0.0), xytext=(xp, 0.0), arrowprops=dict(arrowstyle="->", color="#7a2b8a", lw=1.2))axs.text(0.5, 0.36, "innere Last b", ha="center", fontsize=9, color="#7a2b8a")axs.text(0.0, -0.48, "fest: u(0) = 0", ha="center", fontsize=9, color="#333")axs.text(1.0, -0.48, "frei: u′(1) = 0", ha="center", fontsize=9, color="#333")axs.set_xlim(-0.10, 1.10); axs.set_ylim(-0.70, 0.56); axs.axis("off")# Unten: drei Zelt-Fühler und die Stücke, die sie berühren.for i, (mitte, farbe) inenumerate(zip([0.25, 0.50, 0.75], ["#2a7d2a", "#b3541e", "#7a2b8a"])): links, rechts = mitte - FUEHLER_HALBBREITE, mitte + FUEHLER_HALBBREITE axf.plot([links, mitte, rechts], [0, 1, 0], color=farbe, lw=2.2) axf.fill([links, mitte, rechts], [0, 1, 0], color=farbe, alpha=0.12)# Die drei Balken auf eigenen Höhen, sonst sehen sie aus wie ein Balken. axf.plot([links, rechts], [-0.22-0.10* i] *2, color=farbe, lw=5, solid_capstyle="butt") axf.text(mitte, 1.07, "Fühler bei "+ komma(mitte, 2), ha="center", fontsize=9, color=farbe)axf.plot([0, 1], [0, 0], color="#333", lw=1.2)for k inrange(6): axf.plot([k /5, k /5], [0, -0.05], color="#333", lw=1.0) axf.text(k /5, -0.13, komma(k /5, 1), ha="center", fontsize=9, color="#555")axf.text(0.5, -0.58, "darunter: das Stück Stab, das jeder Fühler berührt", ha="center", fontsize=9, color="#555")axf.set_xlim(-0.10, 1.10); axf.set_ylim(-0.70, 1.28); axf.axis("off")plt.tight_layout()plt.show()
Abbildung 9.2: Drei Zelt-Testfunktionen („Fühler“) über dem Modellstab, untereinander. Oben der Stab selbst: links die feste Einspannung, rechts das freie Ende, dazwischen die innere Last b (violette Pfeile). Unten die drei Fühler an den Stellen 0,25, 0,50 und 0,75 — jeder eins in seiner Mitte, null an seinen Rändern. Die drei farbigen Balken darunter — je einer auf eigener Höhe — zeigen das Stück Stab, das der jeweilige Fühler berührt: Nur dort fragt er das Gleichgewicht ab, außerhalb zählt für ihn nichts. Schematisch, ohne Einheit.
Deutung. Der Fühler gewichtet: Wo er hoch ist, zählt das Gleichgewicht stark, zu den Rändern hin immer weniger, außerhalb seines Stücks gar nicht. Deshalb prüft ein einzelner Fühler immer nur eine Region — erst alle Fühler zusammen prüfen den ganzen Stab. Was so ein Fühler physikalisch bedeutet, sagt der nächste Abschnitt.
9.5 Virtuelle Arbeit: der Fühler ist eine gedachte Verschiebung
Der zweite Schritt gibt dem Fühler eine Bedeutung. Deutet man die Testfunktion \(v\) als eine gedachte, kleine Verschiebung des Körpers — eine, die man nicht wirklich ausführt, sondern nur zur Prüfung annimmt —, dann ist das Integral gerade die Arbeit, welche die Kräfte bei dieser gedachten Verschiebung leisten. Dahinter steht die virtuelle Arbeit: Bei jeder gedachten Verschiebung heben sich innere und äußere Arbeit auf. Das ist nur eine andere Sprache für dieselbe Gleichgewichtsbedingung, und es macht die schwache Form zu einer Variationsformulierung — nicht „Kraftbilanz in jedem Punkt“, sondern „Arbeitsbilanz für jede gedachte Verschiebung“.
Das lässt sich am Modellstab nachrechnen, statt es zu glauben. Nimm als gedachte Verschiebung die einfachste zulässige Funktion, \(v(x) = x\): Sie ist am festen Ende null — mehr verlangt die Einspannung nicht — und wächst nach rechts gleichmäßig an. Die innere Arbeit ist dann die Fläche unter \(E\,A\,u'\,v'\), die äußere die Fläche unter \(A\,b\,v\); beide entstehen als Fläche unter der Kurve nach dem Rezept aus Kapitel 7. Abbildung 9.3 legt sie übereinander, und die Zeile darunter wiederholt die Probe für zwei weitere gedachte Verschiebungen.
Code
import matplotlib.pyplot as pltdef v_linear(x):return xdef v_linear_strich(x):return1.0xs_bild = [k /200.0for k inrange(201)]arbeit_innen = innere_arbeit(v_linear_strich)arbeit_aussen = aeussere_arbeit(v_linear)fig, (axo, axu) = plt.subplots(2, 1, figsize=(7.0, 5.8), sharex=True)axo.plot(xs_bild, [exakte_verschiebung(x) for x in xs_bild], color="#9aa0a6", lw=2.6, label="exakte Lösung u(x)")axo.plot(xs_bild, [v_linear(x) for x in xs_bild], color="#2a7d2a", lw=2.6, label="gedachte Verschiebung v(x) = x")axo.set_ylabel("Verschiebung (ohne Einheit)")axo.legend(fontsize=9, loc="upper left")axo.grid(alpha=0.3)de_achse(axo)axu.fill_between(xs_bild, [E_MODUL * QUERSCHNITT * exakte_dehnung(x) * v_linear_strich(x)for x in xs_bild], color="#b3541e", alpha=0.35)axu.fill_between(xs_bild, [QUERSCHNITT * LAST_B * v_linear(x) for x in xs_bild], color="#7a2b8a", alpha=0.35)axu.annotate("innere Arbeit E·A·u′·v′\nFläche "+ komma(arbeit_innen, 3), xy=(0.22, 0.62), xytext=(0.26, 0.90), fontsize=9, color="#8a3d12", arrowprops=dict(arrowstyle="->", color="#8a3d12"))axu.annotate("äußere Arbeit A·b·v\nFläche "+ komma(arbeit_aussen, 3), xy=(0.82, 0.42), xytext=(0.60, 0.90), fontsize=9, color="#7a2b8a", arrowprops=dict(arrowstyle="->", color="#7a2b8a"))axu.set_xlabel("Ort x auf dem Stab (ohne Einheit)")axu.set_ylabel("Arbeit je Länge (ohne Einheit)")axu.grid(alpha=0.3)de_achse(axu)plt.tight_layout()plt.show()for name, v, v_strich in [("v(x) = x", v_linear, v_linear_strich), ("v(x) = x²", lambda x: x * x, lambda x: 2.0* x), ("v(x) = x·(2 − x)", lambda x: x * (2.0- x),lambda x: 2.0-2.0* x)]:print(f"{name:18s} innere Arbeit {komma(innere_arbeit(v_strich), 3):>6s}"f" äußere Arbeit {komma(aeussere_arbeit(v), 3):>6s}")
Abbildung 9.3: Virtuelle Arbeit am Modellstab, untereinander. Oben die gedachte Verschiebung v(x) = x (grün) und, zum Vergleich, die exakte Lösung u(x) (grau) — v ist frei gewählt und nicht die Lösung. Unten die beiden Arbeiten als Flächen über dem Stab: orange die innere Arbeit E·A·u′·v′, die nach rechts abfällt, violett die äußere Arbeit A·b·v, die nach rechts ansteigt. Die beiden Dreiecke sind spiegelbildlich und flächengleich. Alle Größen schematisch, ohne Einheit.
v(x) = x innere Arbeit 0,5 äußere Arbeit 0,5
v(x) = x² innere Arbeit 0,333 äußere Arbeit 0,333
v(x) = x·(2 − x) innere Arbeit 0,667 äußere Arbeit 0,667
Deutung unter der Ausgabe. Die beiden Flächen sind spiegelbildliche Dreiecke mit demselben Inhalt: Bei der gedachten Verschiebung \(v(x) = x\) leisten die inneren Spannungen genau so viel Arbeit wie die äußere Last, je \(0{,}5\). Die Zeile darunter wiederholt die Probe für zwei krummere gedachte Verschiebungen — je \(0{,}333\) und je \(0{,}667\) —, und sie ginge für jede zulässige Funktion so aus. Das ist das Prinzip der virtuellen Arbeit, an unserem Stab nachgerechnet: Weil die beiden Arbeiten sich für jede gedachte Verschiebung ausgleichen, sagt „die Arbeitsbilanz stimmt“ dasselbe wie „das Gleichgewicht stimmt“.
9.6 Partielle Integration: die Ableitung wandert
Noch steckt im Integral die zweite Ableitung (über \((E\,A\,u')'\)). Das ist der entscheidende Haken: Eine zweite Ableitung setzt voraus, dass die Lösung überall glatt gekrümmt ist — geknickte, stückweise gerade Lösungen hätten sie gar nicht. Hier hilft die partielle Integration: Sie lässt eine Ableitung von \(u\) auf den Fühler \(v\) hinüberwandern. Sie ist das einzige Rechengesetz, das dieses Kapitel von außen holt, und sie fällt nicht vom Himmel — der Kasten rechnet sie in zwei Zeilen vor.
HinweisWoher die partielle Integration kommt
Für zwei Funktionen ist die Steigung ihres Produkts \((u\,v)' = u'\,v + u\,v'\): Man leitet erst die eine ab und lässt die andere stehen, dann umgekehrt, und addiert beides. Integriert man diese Gleichung von \(0\) bis \(L\), steht links der Unterschied der Produktwerte an den beiden Enden, \([\,u\,v\,]_0^L\), rechts die Summe zweier Flächen. Stellt man um, wandert eine Ableitung von der einen Funktion auf die andere:
Mehr steckt nicht dahinter. In der Formel gleich darunter spielt \(E\,A\,u'\) die Rolle, die hier \(u\) hat — deshalb steht dort am Rand \([\,E\,A\,u'\,v\,]_0^L\).
\[
\underbrace{\int_0^L -(E\,A\,u')'\,v\,\mathrm{d}x}_{\text{zweite Ableitung von }u}
\;=\;
\underbrace{\int_0^L E\,A\,u'\,v'\,\mathrm{d}x}_{\text{je eine erste Ableitung}}
\;-\;\Big[\,E\,A\,u'\,v\,\Big]_0^L .
\]
Nach dem Wandern trägt jede Seite nur noch erste Ableitungen — von \(u\)und von \(v\). Abbildung 9.4 macht das Wandern und den Randterm sichtbar.
Code
import numpy as npimport matplotlib.pyplot as pltfrom matplotlib.patches import FancyArrowfig, ax = plt.subplots(figsize=(8.2, 3.6))ax.text(0.15, 0.66, r"$\int -(E\,A\,u')'\,v\,dx$", fontsize=15, ha="center")ax.text(0.15, 0.42, "zweite Ableitung\nliegt ganz auf u", fontsize=9, ha="center", color="#555")ax.add_patch(FancyArrow(0.32, 0.6, 0.15, 0, width=0.012, head_width=0.06, length_includes_head=True, color="#7a2b8a"))ax.text(0.395, 0.72, "eine Ableitung\nwandert auf v", fontsize=9, ha="center", color="#7a2b8a")ax.text(0.65, 0.66, r"$\int E\,A\,u'\,v'\,dx \;-\;[\,E\,A\,u'\,v\,]_0^L$", fontsize=15, ha="center")ax.text(0.62, 0.42, "je eine erste Ableitung", fontsize=9, ha="center", color="#2a7d2a")ax.annotate("Randterm:\nhier tritt die Endkraft ein\n(Sehne, Faszie — Kapitel 12)", xy=(0.88, 0.6), xytext=(0.74, 0.06), fontsize=9, color="#b3541e", arrowprops=dict(arrowstyle="->", color="#b3541e"))ax.set_xlim(0, 1); ax.set_ylim(0, 1); ax.axis("off")plt.tight_layout()plt.show()
Abbildung 9.4: Schematische Skizze (keine Zahlen): Die partielle Integration lässt eine Ableitung von der Spannung (u’, links) auf die Testfunktion (v, rechts) wandern (violetter Pfeil). Danach steht auf jeder Seite nur noch eine erste Ableitung — u’·v’. Am Rand bleibt der Term E·A·u’·v übrig (rechts): Genau dort tritt eine vorgegebene Endkraft E·A·u’ (etwa der durch die Achillessehne eingeleitete Zug) auf natürliche Weise ein. Rein schematisch, kein Maßstab.
Deutung. Zwei Dinge sind gewonnen. Erstens braucht die Bedingung jetzt nur noch erste Ableitungen — sie verträgt geknickte, stückweise lineare Lösungen, die eine zweite Ableitung nicht hätten. Genau das macht sie für Dreiecksnetze tauglich. Zweitens fällt der Randterm\([E\,A\,u'\,v]_0^L\) von selbst an, und zwar an genau den beiden Stellen, für die Kapitel 8 die zwei Arten von Randbedingung aufgezählt hat: Wo der Ort vorgegeben ist, ist der Fühler null und der Term verschwindet; wo die Kraft vorgegeben ist, steht in \(E\,A\,u'\) gerade diese Kraft. Die zweite Art muss man also nicht eigens einbauen — sie fällt aus der Umformung heraus.
Das ist zugleich die Stelle, an der die Ferse in diese Rechnung eintritt. Am Modellstab ist das rechte Ende frei, der Randterm also null; zieht dort aber wirklich jemand, so steht in ihm eine wirkliche Kraft — an der Ferse der Zug der Achillessehne, im Zahlenanhang mit \(3{,}5 \cdot \text{KG} = 2576\) N verzeichnet (Anhang A). Dieser eine Term ist der Platz, an dem eine solche Zahl in die Gleichung kommt. Kapitel 12 setzt sie dort ein, dann allerdings als Kraft je Fläche, die erst über die Randfläche aufsummiert wieder eine Kraft ergibt.
Für unseren Stab verschwindet der Randterm an beiden Enden, und es bleibt die schwache Form
\[
\int_0^L E\,A\,u'\,v'\,\mathrm{d}x \;=\; \int_0^L A\,b\,v\,\mathrm{d}x
\qquad\text{für jede zulässige Testfunktion } v \text{ mit } v(0) = 0 .
\]
9.7 Der Fühler tastet ab
Jetzt sehen wir die schwache Form in Bewegung. Ein Zelt-Fühler wandert über die inneren Positionen des Stabs; an jeder zeigt ein Balken die gewichtete Gleichgewichtsabweichung — die linke minus die rechte Seite der schwachen Form für das gerade gezeigte Feld. Das gezeigte Feld ist die Lösung mit einer örtlichen Beule: Zwischen \(x = 0{,}1\) und \(x = 0{,}4\) ist es nach oben gedrückt, überall sonst stimmt es genau. Die Animation lässt die Beule abklingen.
WichtigVorhersage-Punkt
Bevor du abspielst: Das Feld ist nur im linken Drittel gestört, als Ganzes also falsch. Schlägt der Fühler deshalb an allen inneren Positionen aus — oder nur an manchen? Lege dich fest.
Deutung. Nur die Fühler, die die Beule berühren, schlagen aus. Steht der Fühler weit rechts, liegt sein Zelt vollständig außerhalb der Beule; er zeigt exakt null, obwohl das Feld als Ganzes falsch ist. Das ist die Arbeitsweise der schwachen Form: Jeder Fühler prüft die Region, die er berührt, und erst alle Fühler zusammen prüfen den ganzen Stab — deshalb genügt es nie, dass ein Fühler null zeigt. Klingt die Beule ab, gehen auch die ausgeschlagenen Balken gegen null, und sobald das Feld die Lösung ist, zeigt keiner mehr etwas an. Die Balkenhöhe ist aus dem gezeichneten Feld und der Fühlerstelle berechnet, nicht aus einem Steuerparameter; der Fühler ist nur zur Darstellung in der Höhe skaliert (gerechnet wird mit Spitzenwert eins).
9.8 Mehr Testfunktionen, näher an der Lösung
Jetzt die dritte Stufe: die diskrete Galerkin-Form. Man sucht die Lösung nicht mehr unter allen denkbaren Feldern, sondern nur unter den stückweise linearen. Der Stab wird in \(n\) Stücke geteilt; dazu gehören \(n\) Testfunktionen: \(n-1\) ganze Zelte im Inneren und ein halbes Zelt am freien Ende (bei \(n = 1\) gibt es nur dieses halbe). Je mehr Stücke, desto feiner die Näherung.
WichtigVorhersage-Punkt
Bevor du schiebst: Der Regler erhöht die Zahl der Testfunktionen (wenige → viele). Nähert sich die schwache Lösung der starken für die gezeigten \(n\) immer weiter an, oder erkennst du eine Grenze, ab der nichts mehr besser wird? Lege dich fest.
Deutung. Für die gezeigten \(n = 1 \dots 16\) bringen mehr Testfunktionen die schwache Lösung der starken immer näher; eine Grenze, ab der nichts mehr besser würde, zeigt sich hier nicht. Und überraschend: An den Knoten stimmen beide schon bei ganz wenigen Zelten exakt überein — das ist eine Besonderheit genau dieses 1D-Sonderfalls (konstanter Koeffizient, exakt integrierte Last), keine allgemeine Eigenschaft der FEM. Nur zwischen den Knoten bleibt ein Abstand, und der schrumpft mit jeder Verfeinerung.
In diesem Schritt steckt eine Entscheidung, die man leicht übersieht: Die Testfunktionen kommen aus demselben Vorrat wie die Lösung — dieselben Zelte, einmal als Ansatzfunktion für \(u\), einmal als Testfunktion \(v\). Diese Wahl heißt Galerkin-Verfahren, und sie hat eine sichtbare Folge. In \(\int E\,A\,u'\,v'\,\mathrm{d}x\) stehen \(u\) und \(v\) gleichberechtigt: Vertauscht man beide, steht dasselbe da. Was Zelt \(i\) gegen Zelt \(j\) beiträgt, ist deshalb derselbe Wert wie der von Zelt \(j\) gegen Zelt \(i\) — es entsteht dieselbe Symmetrie der Matrix wie in Kapitel 4, dort noch damit begründet, dass eine Feder auf beide Enden gleich zieht, hier aus der Bauform des Integrals. Kapitel 10 findet sie an jeder einzelnen Elementmatrix wieder.
Wodurch die schwache Form „lösbarer“ wird, sieht man, wenn man die Zelte in die schwache Gleichung einsetzt: Aus den Integralen wird ein kleines lineares Gleichungssystem\(K\,u = f\) — genau die Bauform aus Kapitel 5. Für \(n = 2\) (freie Knoten bei \(x = 0{,}5\) und \(x = 1\)) lautet das fertige System mit unserem schematischen Stab; der Block darunter löst es mit Gauß-Elimination und trägt die zwei gerechneten Knotenwerte auf die exakte Parabel auf (Abbildung 9.5):
Das Galerkin-System für n = 2 lösen und gegen die Parabel halten
n =2K = system_matrix(n) # das fertige globale System (Aufbau: Kapitel 10)f = last_vektor(n)u = loese_system(K, f) # Gauß-Elimination wie in Kapitel 5print(f"K · u = f für n = {n} (freie Knoten x = 0,5 und x = 1):\n")print(f" [ {komma(K[0][0], 2):>5s}{komma(K[0][1], 2):>5s} ] [ u₁ ] [ {komma(f[0], 3)} ]")print(f" [ {komma(K[1][0], 2):>5s}{komma(K[1][1], 2):>5s} ] [ u₂ ] = [ {komma(f[1], 3)} ]")zeichne_knoten_auf_parabel(exakte_verschiebung, LAENGE, [0.5, 1.0], u)
K · u = f für n = 2 (freie Knoten x = 0,5 und x = 1):
[ 4 −2 ] [ u₁ ] [ 0,5 ]
[ −2 2 ] [ u₂ ] = [ 0,25 ]
Abbildung 9.5: Die exakte Lösung u(x) des schematischen Stabs ist eine Parabel (graue Kurve); die zwei mit Gauß-Elimination gerechneten Galerkin-Knotenwerte (n = 2, grüne Punkte bei x = 0,5 und x = 1) liegen ohne erkennbaren Abstand genau auf ihr. Das ist die Besonderheit dieses 1D-Sonderfalls (konstanter Koeffizient, exakt integrierte Last), keine allgemeine FEM-Eigenschaft. Werte schematisch (Modellstab ohne Einheit).
Deutung unter der Ausgabe. Das ist ein symmetrisches \(2\times 2\)-System wie in Kapitel 5, mit Gauß-Elimination gelöst — und seine zwei Knotenwerte \(0{,}375\) und \(0{,}5\) liegen in Abbildung 9.5 ohne den kleinsten Abstand genau auf der exakten Parabel. Wie dieses \(K\) aus den einzelnen Elementen zusammengebaut wird (lokale Elementmatrizen, Assemblierung), ist Stoff von Kapitel 10; hier zählt nur, dass aus der schwachen Form ein \(K\,u = f\) wird. Wie schnell der Abstand zwischen den Knoten schrumpft, trägt der nächste Block doppelt-logarithmisch über der Zahl der Testfunktionen auf; Abbildung 9.6 macht die Konvergenzordnung zur ablesbaren Steigung:
Den Abstand zur starken Lösung über wachsendem n sammeln
ns = [1, 2, 4, 8, 16]fehler = []for n in ns: fehler.append(konvergenz_fehler(n))zeichne_konvergenz_ordnung2(ns, fehler)print(f"feinster Abstand bei n = {ns[-1]}: {komma_sig(fehler[-1], 3)} "f"(an den Knoten {komma_sig(knoten_fehler(ns[-1]), 2)})")
Abbildung 9.6: Der größte Abstand zwischen schwacher und starker Lösung über der Zahl der Testfunktionen n, doppelt-logarithmisch. Die Datenpunkte (orange) laufen parallel zur gestrichelten Referenzgeraden der Steigung −2: Die Konvergenz hat Ordnung zwei. An den Knoten selbst bleibt der Abstand praktisch null (Kontrollwert unter dem Bild) — hier wird nur der Abstand ZWISCHEN den Knoten gezeigt. Werte schematisch (Modellstab ohne Einheit).
feinster Abstand bei n = 16: 0,000488 (an den Knoten 0)
Deutung unter der Ausgabe. Im doppelt-logarithmischen Bild wird der größte Abstand zur Geraden parallel zur Referenz der Steigung −2 — die Folge der Näherungen \(u_h\) konvergiert in diesem Sonderfall mit Ordnung zwei gegen die starke Lösung. An den Knoten bleibt der Abstand durchweg praktisch null (nur Rundungsrauschen; der Kontrollwert unter dem Bild). Die Aussage „für glatte Probleme dieselbe Lösung“ ist damit nicht behauptet, sondern gerechnet — hier für \(n = 1 \dots 16\): an den Knoten exakt, dazwischen mit Ordnung zwei gegen null.
Ordnung zwei ist das, was ein stückweise linearer Ansatz an einem glatten eindimensionalen Problem hergibt — der bestmögliche Fall. Das Ablesen bleibt dasselbe wie in Kapitel 7: Steigung im doppelt-logarithmischen Bild. Kapitel 13 wiederholt diese Messung am Fersenmodell und findet dort eine kleinere Ordnung; woran das liegt, prüft es dort. Wer die beiden Zahlen später nebeneinanderlegt, hat an diesem Stab den Vergleichsmaßstab.
WarnungWeniger verlangen, mehr bekommen
Vermutung:„Abschwächen heißt schlampiger rechnen — das Ergebnis wird ungenauer.“
Warum sie naheliegt: „Schwach“ klingt nach „weniger genau“, und wer eine Bedingung von „überall punktweise“ auf „im Mittel“ lockert, scheint etwas aufzugeben.
Was stattdessen gilt: Abgeschwächt wird nicht die Genauigkeit, sondern die Glätteanforderung: nur noch erste statt zweiter Ableitungen. Dadurch werden geknickte, stückweise lineare Lösungen zulässig, die eine punktweise zweite Ableitung gar nicht besäßen — und genau die lassen sich rechnen. Für das glatte Stab-Problem liefert die schwache Näherung an den Knoten sogar die exakte Lösung und konvergiert dazwischen mit Ordnung zwei (die beiden Bilder oben zeigen beides). Weniger Glätte zu verlangen hat hier nichts gekostet und die Tür zum Rechner geöffnet.
9.9 Konstant oder linear — warum erste Ableitungen den Ansatz bestimmen
Die schwache Form braucht von der Lösung nur die erste Ableitung — die aber muss es geben. Das entscheidet, welche Ansätze taugen. Der Umschalter vergleicht, wie gut zwei Ansatztypen das Verschiebungsfeld darstellen können: ein stückweise konstanter (Treppe, ein Wert je Element) und ein stückweise linearer (Zelt, geknickter Polygonzug). Es geht hier ausdrücklich um die Darstellbarkeit, nicht um eine gerechnete Lösung.
WichtigVorhersage-Punkt
Bevor du umschaltest:Kann ein geknickter linearer Ansatz das gedehnte Stabfeld besser darstellen als konstante Stufen, oder ist er nur teurer? Lege dich fest.
Deutung. Der lineare Ansatz stellt das gedehnte Feld deutlich besser dar. Der konstante Ansatz ist eine Treppe: Innerhalb jeder Stufe ist die Dehnung \(\mathrm{d}u/\mathrm{d}x\) null — er trägt in keinem Element eine Dehnung. Und ein global stetiger konstanter Ansatz, der zusätzlich \(u(0) = 0\) erfüllt, wäre überall null, also nutzlos; unstetige Treppen wiederum liegen außerhalb des konformen Ansatzraums dieses Kapitels (deshalb ist die Treppe hier nur ein Darstellungsversuch, keine gerechnete Lösung). Der lineare Ansatz gibt jedem Element eine konstante, von null verschiedene Dehnung und folgt der Kurve. Genau deshalb ist der stückweise lineare Ansatz der einfachste, der zur schwachen Form passt: Sie integriert \(u'\,v'\), und ein brauchbarer Ansatz muss eine erste Ableitung haben, die nicht überall null ist — das ist die Antwort auf die Vorhersagefrage.
9.10 Und in der Ebene?
Alles bisher Gezeigte war eindimensional: ein Stab, eine Richtung, ein Strich als Rand. In der Ebene ändert sich an diesem Weg nichts Grundsätzliches, nur die Buchhaltung wird länger. Aus dem Produkt \(u'\,v'\) wird eine Summe über die drei Verformungsanteile aus Kapitel 6 — \(\varepsilon_{xx}\), \(\varepsilon_{yy}\) und die Gleitung \(\gamma_{xy}\) —, mit der 3×3-Materialtabelle \(C\) dazwischen. Aus dem Stabstück wird ein Dreieck, aus dem Zelt über einem Intervall ein Zelt über allen Dreiecken, die an einem Knoten hängen, und aus dem Randterm an zwei Endpunkten ein Integral über eine Randlinie. Testen, partiell integrieren, auf endlich viele Zelte einschränken: dieselben drei Handgriffe. Genau diese Übersetzung nimmt Kapitel 10 vor.
9.11 Der Kreis schließt sich
Abbildung 9.7 fasst die drei Stufen zusammen: Aus der starken Form wird durch Testen und partielle Integration die kontinuierliche schwache Form (für alle zulässigen Testfunktionen); schränkt man auf endlich viele Ansatzfunktionen ein, entsteht die diskrete Galerkin-Form und daraus \(K\,u = f\) — das lineare Gleichungssystem aus Kapitel 5, jetzt fürs Kontinuum.
Abbildung 9.7: Der Bogen von Teil III als schematisches Flussdiagramm (keine Ferse-Darstellung): starke Form (jeder Punkt, Kapitel 8) → kontinuierliche schwache Form (∀ zulässige Testfunktion, dieses Kapitel) → diskrete Galerkin-Form mit endlich vielen Ansatzfunktionen (Kapitel 10) → K·u = f, das lineare Gleichungssystem aus Kapitel 5. Der Kreis schließt sich: dieselbe Bauform wie am Federmodell, jetzt fürs Kontinuum.
Deutung. Der Weg ist geschlossen: Die punktweise Gleichgewichtsbedingung aus Kapitel 8 wird abgeschwächt (dieses Kapitel), die abgeschwächte Form nimmt endlich viele Ansatzfunktionen auf (Kapitel 10), und heraus fällt wieder ein \(K\,u = f\) wie am Zwei-Feder-System aus Kapitel 4 und 5. Aus einer Differentialgleichung über unendlich vielen Punkten ist ein endliches Gleichungssystem geworden — das ist die Tür, welche die schwache Form aufstößt.
9.12 Teil III abgeschlossen — die Studiums-Tabelle
Damit schließt Teil III. Die Studiums-Tabelle im Vorwort hat für diesen Teil vier Zeilen vorgesehen. Abgehakt wird nur, was der Teil wirklich geliefert hat: die Steigung und die Fläche als Ableitung und Integral in Kapitel 7, die hingeschriebene Feldgleichung in Kapitel 8, die schwache Form in diesem Kapitel.
Im Buch als …
Im Studium heißt es …
eingelöst
Steigung einer Messkurve
Ableitung, Differentialquotient
Kapitel 7 ✓
Fläche unter der Belastungskurve
Integral
Kapitel 7 ✓
Gleichgewicht in jedem Punkt
partielle Differentialgleichung
Kapitel 8 ✓
„die Gleichung abschwächen“
schwache Form, Variationsformulierung
Kapitel 9 ✓
Teil IV baut darauf auf: Aus dem Körper wird ein Netz, die Ansatzfunktionen sitzen auf Dreiecken, und aus der schwachen Form wird die konkrete Steifigkeitsmatrix.
Editierbare Zelle. Der folgende Block ist zum Selbstprobieren da, und er antwortet mit einem Bild: Die graue Kurve ist die exakte Lösung, die farbigen Polygonzüge sind die schwachen Näherungen für die Zahlen in elementzahlen, die Punkte ihre Knotenwerte. Trag andere Zahlen ein und führe die Zelle aus — je mehr Testfunktionen, desto enger schmiegt sich der Polygonzug an die Parabel, während die Knotenpunkte schon bei wenigen Elementen genau auf ihr sitzen.
Deutung. Schon \(n = 1\) trifft den Endwert \(0{,}5\) exakt — der erste Polygonzug endet genau auf der Parabel —, und mit mehr Testfunktionen bleibt der Abstand an den Knoten praktisch null, während sich der Zug dazwischen anschmiegt. Das ist dieselbe Knoten-Exaktheit dieses 1D-Sonderfalls wie am Regler, hier zum Selbst-Ausprobieren, ohne dass für das Verständnis eine Zeile Python nötig wäre.
Übungen
Ü 9.1 (Verstehen). Erkläre in zwei, drei Sätzen den Unterschied zwischen der kontinuierlichen schwachen Form und ihrer diskreten Galerkin-Fassung. Warum ist „schwach“ keine Aussage über die Zahl der Bedingungen?
HinweisMusterlösung zu Ü 9.1
Die kontinuierliche schwache Form fordert die gemittelte Gleichgewichtsbedingung gegen jede zulässige Testfunktion — das sind weiterhin unendlich viele Bedingungen. „Schwach“ bezieht sich allein auf die geringere Glätteanforderung: Nach der partiellen Integration reichen erste statt zweiter Ableitungen. Erst die diskrete Galerkin-Fassung schränkt Lösung und Testfunktionen auf einen endlichen Raum (stückweise lineare Zelte) ein; dadurch werden aus den unendlich vielen Bedingungen endlich viele, und es entsteht ein lösbares \(K\,u = f\). Endlich wird also die Diskretisierung, nicht die schwache Form selbst.
Ü 9.2 (Verändern). Öffne den Testfunktions-Regler und protokolliere den größten Abstand zwischen schwacher und starker Lösung für \(n = 2, 4, 8\). Sage vorher, ob er sich bei jeder Verdopplung halbiert. Was beobachtest du, und was passiert an den Knoten?
HinweisMusterlösung zu Ü 9.2
Der größte Abstand viertelt sich bei jeder Verdopplung, nicht halbiert (Ordnung zwei) — Abbildung 9.6 zeigt das als Gerade der Steigung −2. An den Knoten ist der Abstand durchweg praktisch null: In genau diesem 1D-Sonderfall (konstanter Koeffizient, exakt integrierte Last) ist die stückweise lineare schwache Form an den Knoten exakt, nur zwischen ihnen bleibt der schnell schrumpfende Abstand. Doppelt so viele Testfunktionen bringen viermal so genau — mehr, als die naheliegende Vorhersage „halbiert“ erwartet. (Eine allgemeine Konvergenzstudie folgt in Kapitel 13; die Knoten-Exaktheit gilt nicht für beliebige Probleme.)
Ü 9.3 (Übertragen). Begründe, warum die schwache Form die Endkräfte am Rand (den durch Achillessehne bzw. Plantarfaszie eingeleiteten Zug) „geschenkt“ mitliefert. Beziehe dich auf die partielle Integration.
HinweisMusterlösung zu Ü 9.3
Bei der partiellen Integration wandert eine Ableitung von der Spannung auf die Testfunktion, und dabei fällt der Randterm \([E\,A\,u'\,v]_0^L\) an. Am eingespannten Ende ist die Testfunktion null (dort ist die Verschiebung vorgeschrieben), sodass dieser Anteil wegfällt; am belasteten Ende steht in \(E\,A\,u'\) gerade die vorgegebene Endkraft. Sie taucht also nicht als Zusatzannahme auf, sondern entsteht auf natürliche Weise aus der Umformung — man muss sie nur einsetzen. Für den Stab hier ist das freie Ende lastfrei, der Randterm also null; sobald an Sehne oder Faszie eine Kraft zieht, trägt derselbe Randterm sie in die schwache Form ein (Kapitel 12).
Roter Faden
Wo kam das schon vor, wo kommt es wieder?Zurück: Die schwache Form nutzt das Integral aus Kapitel 7 (Mitteln über das Gebiet) und schwächt die partielle Differentialgleichung aus Kapitel 8 ab; am Ende steht wieder das \(K\,u = f\) aus Kapitel 5. In der Studiums-Tabelle im Vorwort steht dafür die Zeile „die Gleichung abschwächen → schwache Form, Variationsformulierung“ — mit diesem Kapitel ist Teil III eingelöst. Vor: Kapitel 10 setzt die stückweise linearen Ansätze konkret auf Dreiecke und baut die Steifigkeitsmatrix Element für Element zusammen; die natürlichen Randterme werden in Kapitel 12 zu Bodenreaktion, Achillessehnenzug und Faszienzug, und Kapitel 13 misst die Konvergenzordnung noch einmal an der Ferse. Die schwache Form ist zugleich der Boden, auf dem der Rechner hinter den Reglern arbeitet: Sein FEM-Paket diskretisiert genau diese Form.
Was dieses Kapitel NICHT tut
Es entwickelt keine Funktionalanalysis (keine Sobolev-Räume, keine Normen als Theorie), beweist weder Existenz noch Eindeutigkeit einer Lösung, baut keine konkreten Elementmatrizen zusammen (Kapitel 10) und wählt keine Quadratur. Die partielle Integration erscheint nur eindimensional; der Randterm wird gezeigt, seine Ausgestaltung zu echten Randlasten ist Kapitel 12. Der Modellstab ist schematisch und einheitenfrei: Seine Zahlen belegen die Konvergenzaussage dieses eindimensionalen Sonderfalls und sonst nichts. Der Umschalter „konstant/linear“ ist ein Darstellungsversuch, keine gerechnete Lösung, und die beiden Fersenbilder sind Konzept-Skizzen mit echter Kontur, aber ohne Feldwerte — gerechnete Felder zeigt das Buch ab Kapitel 11.