kramann.info
© Guido Kramann

Login: Passwort:










6.2 Erstellen des Integrators als Runge-Kutta-Integrator

  • Die Implementierung eines Runge-Kutta-Integrators in C++ wurde bereits in Simulationstechnik und Informatik3 behandelt.
  • Die nachfolgende Umsetzung in Java unterscheidet sich kaum davon.
  • Im Hinblick auf eine Umsetzung als Java-Bean ist unbedingt ein leerer Konstruktor erforderlich. Dies gilt auch für alle anderen Klassen, die als Java-Bean umgesetzt werden sollen.
  • Außerdem gibt es eine Methode add(..), die es ermöglicht ein zu simulierendes Modell als Objekt-Referenz zu speichern. Diese Registrierung soll bei der Oberflächen-basierten Variante automatisiert werden.
  • Wieder gibt es eine vorgeschaltete Basisklasse (Integrator):
  • Erst nach der Registrierung des Modells ist der Integrator funktionstüchtig.
  • Beachten Sie auch die Kommentare in den Quellcodes.
package opti;
import java.awt.*; //package awt für die paint()-Methode nötig.
public class Integrator
{
    protected Simulationsmodell simulationsmodell = null;
    protected double[] yneu = null;
    /**
    Mit add(..) wird eine Referenz auf das zu integrierende Modell im 
    Integrator-Objekt gespeichert.
    */
    public void add(Simulationsmodell simulationsmodell)
    {
        this.simulationsmodell = simulationsmodell;
        yneu  = new double[simulationsmodell.getAnzahlGleichungen()];
    }
    /**
    Die Objekt-Methode zeitschritt(..) muss von erbenden Integrator-Klassen überschrieben werden.
    */
    double[] zeitschritt(double[] yalt,double t,double dt)
    {
        if(simulationsmodell==null)
            return null;
        return yneu;
    }
    /** Ein Integrator kann durch Überschreiben der Methode paint() in die Lage
    versetzt werden, seinen aktuellen Zustand grafisch darzustellen.<br/>
    Die Methode wird von der paint-Methode eines Canvas-Objekts her aufgerufen.
    */
    public void paint(Graphics2D g)
    {
    }     
}

Code 6.2-1: Basisklasse Integrator.java

package opti;
import java.awt.*; //package awt für die paint()-Methode nötig.
public class RungeKuttaIntegrator extends Integrator
{
    private double[] yhilf = null;
    private double[] k1=null,k2=null,k3=null,k4=null;
    private double[] k; //Hilfsreferenz, um Berechnungsergebnisse vom Modell zu speichern.
    public void add(Simulationsmodell simulationsmodell)
    {
        this.simulationsmodell = simulationsmodell;
        yneu  = new double[simulationsmodell.getAnzahlGleichungen()];
        yhilf = new double[simulationsmodell.getAnzahlGleichungen()];
        k1 = new double[simulationsmodell.getAnzahlGleichungen()]; 
        k2 = new double[simulationsmodell.getAnzahlGleichungen()]; 
        k3 = new double[simulationsmodell.getAnzahlGleichungen()]; 
        k4 = new double[simulationsmodell.getAnzahlGleichungen()];     
    }
    public double[] zeitschritt(double[] yalt,double t,double dt)
    {
        /**
        Erst nach der Registrierung des Modells mit add(..) ist der Integrator funktionstüchtig.
        */
        if(simulationsmodell==null)
            return null;
        k = simulationsmodell.berechneRechteSeite(yalt,t);
        for(int i=0;i<simulationsmodell.getAnzahlGleichungen();i++)
        {
            k1[i] = k[i];
            yhilf[i] = yalt[i] + 0.5*dt*k1[i];
        }                
        k = simulationsmodell.berechneRechteSeite(yhilf,t);
        for(int i=0;i<simulationsmodell.getAnzahlGleichungen();i++)
        {
            k2[i] = k[i];
            yhilf[i] = yalt[i] + 0.5*dt*k2[i];
        }                
        k = simulationsmodell.berechneRechteSeite(yhilf,t);
        for(int i=0;i<simulationsmodell.getAnzahlGleichungen();i++)
        {
            k3[i] = k[i];
            yhilf[i] = yalt[i] + dt*k3[i];
        }                
        k = simulationsmodell.berechneRechteSeite(yhilf,t);
        for(int i=0;i<simulationsmodell.getAnzahlGleichungen();i++)
        {
            k4[i] = k[i];
        }                
        for(int i=0;i<simulationsmodell.getAnzahlGleichungen();i++)
        {
            yneu[i] = yalt[i] + (dt/6.0)*(k1[i]+2.0*k2[i]+2.0*k3[i]+k4[i]);
        }                
        return yneu;
    }     
    /** paint(..) wird bei der Konsolenanwendung nicht verwendet.*/
    public void paint(Graphics2D g)
    {
    }
}

Code 6.2-2: Runge-Kutta-Integrator RungeKuttaIntegrator.java

  • Mit Hilfe der Klassen LinearerSchwinger und TestRungeKuttaIntegrator ist ein einfacher Test des Runge-Kutta-Integrators möglich.
  • Entpacken Sie das nachfolgende .zip-File.
  • Gehen Sie über die Konsole in den Ordner ruku.
  • Kompilieren Sie die Klassen mit javac opti/*.java
  • Starten Sie das Testprogramm mit java opti/TestRungeKuttaIntegrator
ruku.zip - Testen des Runge-Kutta-Integrators
  • Mit Hilfe der Klassen Antrieb und TestAntrieb kann die Regelstrecke getestet werden.
  • Benutzung wie oben.
antrieb.zip - Test der Regelstrecke Antrieb