kramann.info
© Guido Kramann

Login: Passwort:










kramann.info
© Guido Kramann

Login: Passwort:




Übung 10 - Prozedurales Programm in objektorientierte Form bringen

Ein Frohes Neues Jahr!
  • In der letzten Vorlesung vor Weihnachten wurde das folgende Simulationsprogramm entwickelt:
#include<iostream>
using namespace std;
int main()
{
    double x=1.0;
    double v=0.0;
    double xneu=1.0;
    double vneu=0.0;
    double dt=0.1;
    double t=0.0;
    for(int i=0;i<1000;i++)
    {
        cout<<t<<" "<<x<<" "<<v<<endl;
        vneu = (-x-0.5*v)*dt+v;
        xneu = (       v)*dt+x;
        x = xneu;
        v = vneu;
        t=t+dt;
    }
}

Code 0-1: Simulationsprogramm aus der Vorlesung vom 16.12.2009.

  • Wie in der Vorlesung dargestellt wurde, wird hier ein Differentialgelichungssystem numerisch integriert, das einem linearen Schwinger entspricht.
  • Das Verfahren zur Integration ist das so genannte Euler-Verfahren.
  • Das Differentialgleichungssystem wird benutzt, um die aktuelle Steigung an einer Stelle zu bestimmen.
  • Der alte Wert plus die aktuelle Steigung mal Δt ergibt den Wert zum Zeitpunkt t+Δt:

f(t+Δt) = f(t)+ (df(t)/dt)*Δt

  • Da das Differentialgleichungssystem aus zwei Gleichungen besteht, muß das Verfahren auch für beide Gleichungen angewendet werden.
  • Die eine Gleichung liefert die Steigung der Geschwindigkeit an einer bestimmten Stelle [x,v].
  • Die andere Gleichung liefert die Steigung des Weges an einer bestimmten Stelle [x,v]:

dv(x,v)/dt = -x-0.5*v

dx(x,v)/dt = v

  • Diese beiden Gleichungen, die die aktuelle Steigung bestimmen sind das Modell, das simuliert wird.
  • Das ganze andere drum herum ist die numerische Integration, auch Simulation genannt.

Aufgabe 1

  • Spalten Sie das obige prozedurale Programm in zwei Klassen auf:
  • Die eine Klasse soll das Modell enthalten.
  • Die zweite soll das Integrationsverfahren repräsentieren.
  • Hintergrund: Diese Aufspaltung soll es ermöglichen, auch andere Modelle mit dem Integrationsverfahren zu berechnen, oder dieses Modell mit einem anderen Integrationsverfahren, indem man dann nur jeweils eine der beiden Klassen durch etwas Neues ersetzt.
  • Diese Übung soll die Grundlage für ein Simulationsprogramm mit GUI bilden, mit dem diese Vorlesung abschließen wird.

Hilfestellungen:

  • Modell-Klasse:
  • Die Modellklasse soll lediglich eine Funktion enthalten, die die aktuelle Steigung zurückliefert.
  • Sinnvollerweise liefert sie einen Zeiger auf ein Array, das die beiden Steigungswerte beinhaltet.
  • Übergabeparameter dieser Funktion ist natürlich ein Array, das das aktuelle x und v enthält.
  • Da nicht jedes Modell aus genau zwei Gleichungen besteht, sollte der Übergabeparameter ein Array sein und nicht zwei getrennte double-Werte.
  • Aus dem gleichen Grund macht es Sinn, eine weitere Funktion zu definieren, die die Anzahl der Modellgleichungen zurückgibt.
  • Dies dient dazu, dass der Integrator "weiß", für wieviele Gleichungen der nächste Integrationsschritt ausgeführt werden soll.
  • Integrator-Klasse:
  • Hier bieten sich unterschiedliche Möglichkeiten an.
  • Man könnte alles, was jetzt in der main-Methode passiert, in die Integratorklasse verlegen.
  • Dies ist die aufwändigere Variante.
  • Einfacher wird es, wenn man die Schleife für die Integrationsschritte in der main-Methode beläßt.
  • In diesem Fall führt eine Funktion in dem Integrator-Objekt nur einen Integrationsschritt aus.
  • Beim Erzeugen eines Integrator-Objektes sollte ein Zeiger auf ein Modell übergeben werden, welches dann in der Integrationsfunktion benutzt wird.
  • D.h. es wird ein Modell-Objekt in dem Integrator-Objekt registriert, um zu vereinbaren, für welches Modell die Integrationsschritte durchgeführt werden sollen.
  • Ebenso beim Erzeugen des Integrator-Objektes sollte die Schrittweite Δt vereinbart werden.
  • Die eigentliche Integrationsfunktion führt dann immer nur einen Integrationsschritt durch (ein Schritt in der Schleife der main-Methode).
  • Ihr wird als Übergabeparameter nur der aktuelle Wert für [x(t),v(t)] als double-Array übergeben.
  • Die Funktion liefert dann einen Zeiger auf in double-Array zurück, das [x(t+Δt),v(t+Δt)] enthält.

Vorgehen:

  • Zeichnen Sie zunächst ein UML-Klassendiagramm Ihres Lösungskonzeptes und besprechen es untereinander und nötigenfalls mit Ihrem Dozenten.
  • Setzen Sie dann erst Ihre Idee in ein C++-Programm um.
  • Testen Sie Ihr Programm, indem Sie bei gleichen Anfangsbedingungen und gleicher Schrittweite Δt Ihre Ausgabe mit der des prozeduralen Programms vergleichen.

Aufgabe 2

  • Nachfolgend ist dem Euler-Integrations-Verfahren das wesentlich bessere Runge-Kutta-Integrations-Verfahren gegenüber gestellt.
  • Schreiben Sie eine neue Integratorklasse, die das Runge-Kutta-Verfahren verwendet und testen Sie dieses.
  • Um das Austauschen von Integrator-Klassen und Modellklassen zu vereinfachen, bietet es sich an, Abstrakte Klassen für beide einzuführen. Machen Sie das.
Allgemeines Modell mit Euler-Verfahren integtriert.

Bild 0-1: Allgemeines Modell mit Euler-Verfahren integtriert.

Allgemeines Modell mit Runge-Kutta-Verfahren integtriert.

Bild 0-2: Allgemeines Modell mit Runge-Kutta-Verfahren integtriert.