Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ss16:physiksimulation_doc_cython

Hauptseite des Projekts

Physiksimulation/Dokumentation/Komponenten/

Cython-Teil

Programmstruktur

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.

ss16/physiksimulation_doc_cython.txt · Zuletzt geändert: 2016/08/14 22:11 von markumnus