/* Das n-Körperproblem in drei Dimensionen
 * n gravitativ wirkende Körper bewegen sich durch ihre gegenseitige Newtonsche Anziehungskraft
 * Berechnung der Lösung eines Systems von 2*3*n Differentialgleichungen erster Ordnung
 * mittels Runge-Kutta Ordnung vier Methode
 * Verfahren zur Loesung der DGL ist in einer abstrakten Basisklasse ausgelagert
 * Berechnung der Lösung innerhalb einer Methode (Klassenfunktion) Runge-Kutta-Verfahren
 * Überschreibung der virtuellen Funktion der Bewegungsgleichungen in der abgeleiteten Klasse (Subklasse) 'nBody'
 * Zeitentwicklung der fuer unterschiedliche t-Werte in [a,b]
 * Unterklasse 'nBody'
 * Konstruktor 1: 'nBody'(Grav.Konstante G, Massenvektor der Körper, Anfangszeit a, Endzeit b, Anzahl der Punkte N, Anfangswerte u_init)
 * Konstruktor 2: Elliptische Lagrangesche homografischen Lösungen (Exzentrizität exz in [0,1])
 *                'nBody'(Anfangszeit a, Endzeit b, Anzahl der Punkte N, Exzentrizität exz)
 * Ausgabe zum Plotten in Datei
 */

#include "N-BodyProblem.hpp" // Header-Datei des n-Körperproblem in drei Dimensionen
#include <iostream>          // Standard Input- und Output Bibliothek in C, z.B. fprintf(...)
#include <vector>            // Vector-Container der Standardbibliothek
using namespace std;         // Benutze den Namensraum std

// Hauptfunktion
int main(){
    double a = 0;                               // Untergrenze des Zeit-Intervalls
    double b = 12.4;                            // Obergrenze des Intervalls
    int N = 100000;                             // Anzahl der Punkte

    FILE *ausgabe;                              // Deklaration eines Files fuer die Ausgabedatei
    ausgabe = fopen("N-BodyProblem.dat", "w+"); // Ergebnisse werden in die Datei 'N-BodyProblem.dat' geschrieben

    // Anfangswerte für die 'Figur Acht' (Orte und Geschwindigkeiten der drei Körper in drei Dimensionen)
//    vector<double> u_init {0.97000436,-0.24308753,0.0,-0.97000436,0.24308753,0.0,0.0,0.0,0.0,
//        0.46620368,0.43236573,0.0,0.46620368,0.43236573,0.0,-0.93240737,-0.86473146,0.0};
//    nBody L = nBody(1,{1,1,1},a,b,N,u_init); // Konstruktor 1 bilded eine Instanz der Klasse nBody

    // Anfangswerte für die Elliptische Lagrangesche homografischen Lösungen (Exzentrizität exz=0.7)
    nBody L = nBody(a,b,N,0.7);           // Konstruktor 2 bilded eine Instanz der Klasse nBody
    L.solve();                            // Methode des Runge-Kutta-Verfahrens ausführen

    fprintf(ausgabe, "# 0: Index i \n# 1: t-Wert \n# 2:x_1 \n# 3:vx_1 \n# 4:y_1 \n# 5:vy_1 \n# 6:z_1 ... \n"); // Beschreibung der ausgegebenen Groessen
    for(size_t i=0; i  < L.t.size(); i += 10){                        // for-Schleife über die Zeitgitterpunkte (nur jeden 10-ten Wert ausgeben)
        fprintf(ausgabe, "%3ld %19.15f ",i,L.t[i]);                   // Ausgabe Index und Zeit
        for(unsigned j=0; j  < 2*3*L.n; ++j){                         // for-Schleife zur Ausgabe der Orte und Geschw. der n-Körper
            fprintf(ausgabe, "%19.15f %19.15f ",L.r(i)[j],L.v(i)[j]); // Ausgabe xyz-Werte und Geschwindigkeiten der Körper
        }                                                             // Ende der for-Schleife; n-Körper
        fprintf(ausgabe, "\n");                                       // Neue Zeile
    }                                                                 // Ende der for-Schleife; Zeitgitterpunkte
} // Ende der Hauptfunktion
