GPU-fähige Quadraturregeln
Quadraturregeln in Dune bestehen aus einem std::vector<Dune::QuadraturePoint>
(oder etwas, dass sich ähnlich wie ein std::vector
verhält. Ein QuadraturePoint
besteht aus einem Gewicht und einer Position. Je nach GeometrieType/Shape (z.B. Quadrat vs. Dreieck) und je nach maximaler Polynom-Ordnung der zu integrierenden Funktion benötigt man unterschiedliche Quadraturregeln. Wie man an eine Dune-Quadraturregel kommt sieht man ganz gut in quadrature.hh.
Für das Rechnen auf der GPU müssen die Quadraturregeln in ein Format kopiert werden mit dem die GPU umgehen kann. Die Klasse QuadraturePoint
sollte funktionieren, der std::vector
der die Quadraturpunkte zu einer Regel zusammenfasst wird nicht funktionieren. Eine Möglichkeit wäre etwas wie:
struct GPUQuadratureRule {
Dune::QuadraturePoint *data;
std::size_t size;
};
- Für das Testen auf der CPU können die Daten einfach ein einem
std::vector<...> qr
gespeichert werden, und dieGPUQuadratureRule
kann mit{ qr.data(), qr.size() }
initialisiert werden. - Für das spätere Rechnen auf der GPU müßte entsprechend Speicher vom Executor allokiert werden und die Daten da rein kopiert werden, die GPU-Addresse des Speichers würde dann in
GPUQuadratureRule::data
landen.
Dann sollte im lokalen Operator jacobian_apply_volume()
so geändert werden daß es diese custom Quadraturregel verwendet. Ob ihr dabei die Quadraturregel so baut daß ihr die direkt in der range-based for
Loop verwenden könnt, oder ob ihr die Loop so umbaut daß die mit der neuen Datenstruktur klar kommt ist dabei erstmal egal.
Für dieses Issue sollte der Geometrietyp und die Quadraturordnung hardkodiert werden um es überschaubar zu halten. Den Geometrietyp bekommt Ihr mit Dune::GeometryTypes::cube(2)
(Würfel der Dimension 2, a.k.a Quadrat/Quadrilateral), siehe https://dune-project.org/doxygen/master/namespaceDune_1_1GeometryTypes.html. Um an die verwendete Quadraturordnung ranzukommen könnt ihr vorrübergehend mal ein std::cout << order << std::endl;
in jacobian_apply_volume()
einbauen.
Dann solltet Ihr genau eine Quadraturordnung bekommen, mit der Ihr die GPUQuadratureRule
in gridoperator.hh
in nonlinear_jacobian_apply()
erstellen könnt.
Es bleibt die Frage wie die GPUQuadratureRule
in jacobian_apply_volume()
reinkommt -- für dieses Issue würde ich die einfach als zusätzliche Parameter übergeben.
Offene Fragen, in nachfolgenden Tasks zu lösen:
- Hardcodierter GeometryTyp der Quadraturregel (low Priority, ist schon an anderen Stellen implizit als Quadrilateral angenommen)
- Hardkodierte Quadraturordnung
- Wie genau kommt die Funktionen im LocalOperator (
jacobian_volume_apply()
etc.) an die Quadraturregel