Hauptseite des Projekts
**[[ss16:Physiksimulation|Physiksimulation]]/[[ss16:Physiksimulation_Doc_Main|Dokumentation]]/[[ss16:Physiksimulation_doc_components|Komponenten]]/** =====Cython-Teil===== ====Programmstruktur==== {{ :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)// 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 Die Methoden //add()// und //modify()// der //Schnittstelle// bekommen ein PyCObject übergeben, um die Lesbarkeit des Codes zu erhöhen.\\ ====setup.py==== 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. from distutils.core import setup from Cython.Build import cythonize from Cython.Distutils import build_ext from distutils.extension import Extension setup(cmdclass={'build_ext':build_ext}, ext_modules = [Extension("PyCInterface", ["PyCInterface.pyx","interface.cpp", "simulation.cpp", "universe.cpp", "auswertung.cpp", "object.cpp", "vector3d.cpp"], language="c++", extra_compile_args=["-std=c++11"], extra_link_args=["-std=c++11"])] ) **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: from PyCInterface import * interface = Schnittstelle() obj = PyCObject() obj.x = ... obj.y = ... ... interface.add (obj) interface.run(70000) 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.