Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ss16:physiksimulation_doc_cython [2016/08/13 17:28] markumnus angelegt |
ss16:physiksimulation_doc_cython [2016/08/14 22:11] (aktuell) markumnus Überschrift verschönert |
||
---|---|---|---|
Zeile 3: | Zeile 3: | ||
</a></center></html> | </a></center></html> | ||
- | <- [[ss16:Physiksimulation_doc_components|zurück zur Liste der Komponenten]] | + | **[[ss16:Physiksimulation|Physiksimulation]]/[[ss16:Physiksimulation_Doc_Main|Dokumentation]]/[[ss16:Physiksimulation_doc_components|Komponenten]]/** |
- | + | =====Cython-Teil===== | |
- | =====Physiksimulation | Cython-Teil===== | + | |
====Programmstruktur==== | ====Programmstruktur==== | ||
{{ :ss16:physiksimulation_struktur2107.png?nolink |}} | {{ :ss16:physiksimulation_struktur2107.png?nolink |}} | ||
+ | |||
+ | |||
+ | ====PyCInterface.pyx==== | ||
+ | Diese Cython-Datei hat 2 Hauptfunktionen:\\ | ||
+ | 1. Sie redefiniert den Header für die C++-Klasse //Interface// neu, sodass man sie in Cython nutzen kann.\\ | ||
+ | 2. Sie definiert zwei Klassen, die Python versteht und nutzen kann. Diese stehen für die Schnittstelle zum C++-Teil und für Objekte, die im Hauptprogramm einfach modifiziert und dann an das Interface übergeben werden können.\\ | ||
+ | Der Code sieht wie folgt aus:\\ | ||
+ | //(leider gibt es kein Cython-Syntax Highlighting, weswegen wir hier das für Python genutzt haben)// | ||
+ | <code Python> | ||
+ | import pyximport | ||
+ | from libcpp.string cimport string | ||
+ | pyximport.install() | ||
+ | |||
+ | cdef extern from "interface.hpp": | ||
+ | cdef cppclass Interface: | ||
+ | Interface() except+; | ||
+ | Interface(double G) except+; | ||
+ | void add (string, double, double, double, double, double, double, double); | ||
+ | void modify (string, double, double, double, double, double, double, double); | ||
+ | void run (unsigned int); | ||
+ | string step (); | ||
+ | void setG (double) | ||
+ | void setDT (double) | ||
+ | |||
+ | cdef class Schnittstelle: | ||
+ | cdef Interface intfc | ||
+ | | ||
+ | def __cinit__ (self, double G = -1): | ||
+ | """ | ||
+ | Konstruktor fuer Cython-Klassen. | ||
+ | """ | ||
+ | print "Initializing..." | ||
+ | if G == -1: | ||
+ | self.intfc = Interface () # if no gravitational constant was given | ||
+ | else: | ||
+ | self.intfc = Interface (G) | ||
+ | | ||
+ | def add (self, o): | ||
+ | """ | ||
+ | Fuegt ein PyCObject dem Universe hinzu. | ||
+ | """ | ||
+ | self.intfc.add (o.name, o.x, o.y, o.z, o.vx, o.vy, o.vz, o.m) | ||
+ | | ||
+ | def modify (self, o): | ||
+ | """ | ||
+ | UEberschreibt ein Object. | ||
+ | """ | ||
+ | self.intfc.modify (o.name, o.x, o.y, o.z, o.vx, o.vy, o.vz, o.m) | ||
+ | | ||
+ | def run (self, unsigned int n): | ||
+ | """ | ||
+ | Laesst die Berechnungen n Schritte laufen und schreibt die Ergebnisse in eine Textdatei. | ||
+ | """ | ||
+ | self.intfc.run (n) | ||
+ | | ||
+ | def step (self): | ||
+ | """ | ||
+ | Fuehrt einen Berechnungsschritt aus und gibt einen String mit Positionsdaten zurueck. | ||
+ | """ | ||
+ | return self.intfc.step() | ||
+ | | ||
+ | def setG (self, double G): | ||
+ | """ | ||
+ | Setzt die Gravitationskonstante fuer die Berechnungen neu. | ||
+ | """ | ||
+ | self.intfc.setG (G) | ||
+ | | ||
+ | def setDT (self, double DT): | ||
+ | """ | ||
+ | Setzt die Genauigkeit bei den Berechnungen. Je kleiner der Betrag von DT, desto genauer, aber auch langsamer sind die Berechnungen. | ||
+ | """ | ||
+ | self.intfc.setDT (DT) | ||
+ | |||
+ | class PyCObject: | ||
+ | def __init__(self): | ||
+ | self.name = "" | ||
+ | self.color = (1,1,1) | ||
+ | self.x = 0 # Position | ||
+ | self.y = 0 | ||
+ | self.z = 0 | ||
+ | self.vx = 0 # Velocity | ||
+ | self.vy = 0 | ||
+ | self.vz = 0 | ||
+ | self.ax = 0 # Acceleration | ||
+ | self.ay = 0 | ||
+ | self.az = 0 | ||
+ | self.m = 0 # Mass | ||
+ | self.size = 0.1 | ||
+ | self.fixed = False | ||
+ | |||
+ | </code> | ||
+ | Die Methoden //add()// und //modify()// der //Schnittstelle// bekommen ein PyCObject übergeben, um die Lesbarkeit des Codes zu erhöhen.\\ | ||
====setup.py==== | ====setup.py==== | ||
- | Diese Datei kompiliert und linkt die C++-Teile und das PyCInterface.pyx zu einer PyCInterface.cpp- und einer PyCInterface.so-Datei. | + | Diese Datei kompiliert und linkt die C++-Teile und das PyCInterface.pyx zu einer PyCInterface.cpp- und einer PyCInterface.so-Datei. Letztere kann wie gewohnt in Python importiert werden. |
<code Python> | <code Python> | ||
from distutils.core import setup | from distutils.core import setup | ||
Zeile 29: | Zeile 120: | ||
</code> | </code> | ||
**Ausgeführt wird dieses Skript mit //%%python setup.py build_ext --inplace%%//**. | **Ausgeführt wird dieses Skript mit //%%python setup.py build_ext --inplace%%//**. | ||
+ | |||
+ | ====Benutzung==== | ||
+ | Den Cython-Teil kann man in Python dann zum Beispiel so benutzen: | ||
+ | <code Python> | ||
+ | from PyCInterface import * | ||
+ | |||
+ | interface = Schnittstelle() | ||
+ | |||
+ | obj = PyCObject() | ||
+ | obj.x = ... | ||
+ | obj.y = ... | ||
+ | ... | ||
+ | interface.add (obj) | ||
+ | interface.run(70000) | ||
+ | </code> | ||
+ | Man kann die Objekte also leicht in Python modifizieren und dem Interface hinzufügen. Mit dem Aufruf der //run()//-Methode erhält man die ganze Rechenkraft von C++ und hat so die Vorteile beider optimal kombiniert. |