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:
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 ]
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:
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:
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).
Antworten:
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.
quelle
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.
quelle