Wie man Dirichlet-Randbedingungen effizient in globalen Finite-Elemente-Steifheitsmatrizen mit geringer Dichte implementiert

9

Ich frage mich, wie Dirichlet-Randbedingungen in globalen Finite-Elemente-Matrizen mit geringer Dichte tatsächlich effizient implementiert werden. Nehmen wir zum Beispiel an, unsere globale Finite-Elemente-Matrix war:

K.=[520- -102410001632- -1037000203]]und rechter Vektorb=[b1b2b3b4b5]]

dann eine Dirichlet-Bedingung auf den ersten Knoten anzuwenden ( ), würden wir die erste Zeile auf Null setzen, eine 1 bei und die erste Spalte von der rechten Seite subtrahieren. Zum Beispiel würde unser System werden: K 11 K = [ 1 0 0 0 0 0 4 1 0 0 0 1 6 3 2 0 0 3 7 0 0 0 2 0 3 ]x1=cK.11

K.=[1000004100016320037000203]]und rechter Vektorb=[cb2- -2×cb3- -0×cb4+1×cb5- -0×c]]

Theoretisch ist das alles gut und schön, aber wenn unsere K-Matrix im komprimierten Zeilenformat (CRS) gespeichert ist, wird das Verschieben der Spalten auf die rechte Seite für große Systeme teuer (wobei viele Knoten Dirichlet sind). Eine Alternative wäre, die Spalten, die einer Dirichlet-Bedingung entsprechen, nicht nach rechts zu verschieben, dh unser System würde zu:

K.=[100002410001632- -1037000203]]und rechter Vektorb=[cb2b3b4b5]]

Dies hat jedoch den großen Nachteil, dass das System nicht mehr symmetrisch ist und wir daher keinen vorkonditionierten konjugierten Gradienten (oder andere symmetrische Löser) mehr verwenden können. Eine interessante Lösung, auf die ich gestoßen bin, ist die "Methode der großen Zahlen", die ich in dem Buch "Programmieren endlicher Elemente in Java" von Gennadiy Nikishkov gefunden habe. Diese Methode nutzt die Tatsache, dass die doppelte Genauigkeit nur etwa 16 Stellen Genauigkeit enthält. Anstatt eine 1 in die Position , platzieren wir eine große Zahl. Zum Beispiel wird unser System: K.11

K.=[1.0e6420- -102410001632- -1037000203]]und rechter Vektorb=[c×1.0e64b2b3b4b5]]

Die Vorteile dieser Methode sind, dass sie die Symmetrie der Matrix beibehält und gleichzeitig für spärliche Speicherformate sehr effizient ist. Meine Fragen lauten dann wie folgt:

Wie werden Dirichlet-Randbedingungen typischerweise in Finite-Elemente-Codes für Wärme / Flüssigkeiten implementiert? Verwenden Menschen normalerweise die Methode der großen Anzahl oder tun sie etwas anderes? Gibt es einen Nachteil bei der Methode der großen Zahlen, die jemand sehen kann? Ich gehe davon aus, dass es wahrscheinlich eine effiziente Standardmethode gibt, die in den meisten kommerziellen und nichtkommerziellen Codes verwendet wird, um dieses Problem zu lösen (natürlich erwarte ich nicht, dass die Leute das gesamte Innenleben jedes kommerziellen Finite-Elemente-Lösers kennen, aber dieses Problem scheint grundlegend zu sein genug, dass wahrscheinlich jemand an solchen Projekten gearbeitet hat und Anleitung geben könnte).

James
quelle
2
Haben Sie Beweise dafür, dass dies Sie erheblich verlangsamt?
Bill Barth
@ BillBarth Ja, obwohl es immer die Möglichkeit gibt, dass ich etwas ineffizient mache. Gennadily selbst schreibt, dass die explizite Methode für vollständige 2D-Arrays zwar einfach ist, "aber es nicht immer einfach ist, auf Matrixzeilen und -spalten zuzugreifen, wenn eine Matrix im kompakten Format vorliegt." Dies deutet darauf hin, dass die effiziente Implementierung der expliziten Methode möglicherweise schwieriger ist. Da mein Code gerade geschrieben wird, kann die explizite Methode mehr Zeit in Anspruch nehmen als die eigentliche Lösung.
James
1
Machen Sie es wie Wolfgang sagt und wenden Sie Randbedingungen auf Elementmatrizen an, bevor Sie zusammensetzen.
Bill Barth
@ BillBarth Ja, ich denke ich werde das tun. Seine Videos sind unglaublich! Ich habe ihm gerade einen Kommentar / eine Frage hinterlassen, ob Sie die globalen Matrizen bei jedem Zeitschritt neu zusammensetzen müssen. Danach denke ich, dass ich seine Antwort akzeptieren werde.
James

Antworten:

11

In deal.II ( http://www.dealii.org - Haftungsausschluss: Ich bin einer der Hauptautoren dieser Bibliothek) eliminieren wir ganze Zeilen und Spalten, und es ist insgesamt nicht zu teuer. Der Trick besteht darin, die Tatsache zu verwenden, dass das Sparsity-Muster normalerweise symmetrisch ist, sodass Sie wissen, in welche Zeilen Sie schauen müssen, wenn Sie eine ganze Spalte entfernen.

Meiner Ansicht nach besteht der bessere Ansatz darin, diese Zeilen und Spalten in den Zellenmatrizen zu entfernen, bevor sie der globalen Matrix hinzugefügt werden. Dort arbeiten Sie mit Vollmatrizen, sodass alles effizient ist.

Ich habe noch nie von dem Ansatz mit großen Zahlen gehört und würde ihn nicht verwenden, da er sicherlich zu schrecklich schlecht konditionierten Problemen führen wird.

Als Referenz werden die Algorithmen, die wir in deal.II verwenden, konzeptionell in den Vorlesungen 21.6 und 21.65 unter http://www.math.colostate.edu/~bangerth/videos.html beschrieben . Sie stimmen genau mit Ihrer Beschreibung überein.

Wolfgang Bangerth
quelle
2
Bei einem zeitabhängigen Problem (z. B. der Wärmegleichung) setzen Sie die globale Matrix bei jedem Zeitschritt neu zusammen? Der Grund, den ich frage, ist, dass Sie im Fall von Dirichlet-Bedingungen ungleich Null Informationen aus der ursprünglichen globalen Matrix benötigen, wenn Sie die rechte Seite ändern. Wenn Sie diese Spalten jedoch während des vorherigen Zeitschritts auf Null gesetzt haben, gehen diese Informationen verloren (es sei denn, Sie speichern sie in zusätzlichen Arrays). Dies wäre kein Problem, wenn die globale Matrix bei jedem Zeitschritt neu zusammengestellt würde. Dies ist jedoch das, was ich in Betracht ziehe und was ohnehin getan werden müsste, wenn ein adaptives Netz verwendet wird.
James
1
Das hängt von der Anwendung ab. Alle "großen" Codes lösen nichtlineare zeitabhängige Probleme, und für diese ist klar, dass Sie auf die eine oder andere Weise neu zusammenbauen müssen. Bei linearen Codes können Sie einfach die Originalmatrix speichern und sie in jedem Zeitschritt an eine andere Stelle kopieren, Randbedingungen anwenden und diese dann im Solver verwenden. Dies erfordert nur mehr Speicher, ist aber ansonsten billig.
Wolfgang Bangerth
1
Ah, ich sehe, das habe ich vermutet. Ich werde implementieren, wie Sie vorgeschlagen haben. Ok das ist für deine Hilfe. Diese Deallii-Tutorial-Videos sind übrigens wirklich gut!
James
2

Null BCs sind einfach. Für BCs ungleich Null können Sie auch Lagrange-Multiplikatoren verwenden. ZB siehe hier . Ein Vorteil von LMs besteht darin, dass Sie eine beliebige Einschränkungsgleichung verwenden können, obwohl das System unbestimmt ist und Sie einen geeigneten Löser benötigen.

stali
quelle