Warum geht es unter linux und nicht unter windows??



  • Hi, bin gerade am verzweifeln, da ich eine Hausarbeit anfertigen muss und es zuhause leider nie funktioniert zu kompelieren... ien einfaches Programm wei hello world funktionert tadelos, aber folgender code leider nicht. Unter linux in der Uni klappt es imemer ohne Probleme, könnte jemand einmal ausprobieren oder mir evtl sogar sagen warum es nicht klappt ?? es kommt imemr die standard windows fehlermeldung "Programm funktioniert nicht mehr"

    Ist leider etwas lang, soll einen Springenden Ball simulieren, die mit einem Federpotential aneinander gekoppelt sind :

    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    #include<fstream>
    #include<math.h>
    
    using namespace std;
    void initialize();                                                  //Anfangswerte für x,v,m,time
    void force();                                                       //Berechnen der Kraefte/Energie als Funktion der x,v, etc
    void integrate_euler(double dt);                                    //Integrieren der Bewegungsgleichung mit Euler-Verfahren
    void integrate_velocity1(double dt);                                //Integrieren der Bewegungsgleichung mit Velocity-Verfahren
    void integrate_velocity2(double dt);                                //Integrieren der Bewegungsgleichung mit Velocity-Verfahren
    void sample(double DT, ofstream& ausgabe1, ofstream& ausgabe2);     //Berechnung verschiedener Observablen und Ausschreiben
    
    double laenge (double w1, double w2, double w3) // Länge im 3-dimensionalen Raum berechnen.
    {
        double strecke;
        strecke = sqrt(pow(w1,2)+pow(w2,2)+pow(w3,2));
        return strecke;
    }
    
    //-------------------------------------------------------- Variablen einführen-----------------------------------------------
    const int np = 2;                     // Anzahl Bälle
    double G,k;
    double zeit;
    int spruenge, koll;
    double t_sprung;
    double x[np][3];                //Koordinaten (3 Raumdimensionen)
    double v[np][3];                //Geschwindigkeit insgesamt
    double cache[np][3];            //Zwischenspeicher
    double m[np];                   //Massen
    double f[np][3];                //Kraefte auf Teilchen (3 Raumdimensionen)
    double f2[np][3];               //Kraefte auf Teilchen (3 Raumdimensionen) durch Feder
    double ke1,pe1,ke2,pe2;         //kinetische und potentielle Energien
    double t;                       //Zeit
    double Ballradius;               //Radius der Bälle
    
    //-------------------------------------------------Main----------------------------------------------------------------------
    int main(int argc , char* argv[])
    {
    
        //Einlesen der Integrations-Parameter
        const int NMAX =atoi(argv[1]); //Anzahl an Iterationen
        const double DT=atof(argv[2]); //Zeitschritt
    
        //Energien der Algorithmen
        double energy_e[np][NMAX], energy_v[np][NMAX];
    
        //Anfangswerte für x,v,m,zeit,G,K,spruenge,t_sprung,t
        initialize();
    
        //Integriere nmax mal und schreibe Ergebnisse aus
        force();
        ofstream out1; out1.open("Trajektorie1_e.txt",ios::out);  //Trajektorie unteres Teilchen
        ofstream out2; out2.open("Trajektorie2_e.txt",ios::out);  //Trajektorie oberes Teilchen
        ofstream phase; phase.open("Phasenraum_e.txt",ios::out);  //Pahsenraum
        ofstream details; details.open("zDetails.txt", ios::out); //Details
    
        //Euler
        for(int i=1;i<=NMAX;i++)
        {
            force();
            integrate_euler(DT);
            t+=DT;
            //Energie-Euler
            out1 << ke1 + pe1 << " ";
            out2 << ke2 + pe2 << " ";
            energy_e[0][i] = ke1+ke2+pe1+pe2;
            sample(DT, out1, out2);
            phase << x[1][2]-x[0][2]<< " "<< x[0][2]+x[1][2]<<endl;
    
        }
        cout <<"Anzahl der Sprünge : "<<spruenge<<"\nGesamtzeit :"<<t<<endl;
        details << "Gesamtzeit : \t\t\t\t\t" << t<<"s\nZeitschritt von :\t\t\t\t"<< DT<<"s\nFederkonstante : \t\t\t\t"<<k<< "\n\nEuler\nAnzahl Bodenkontakte : \t\t\t\t"<< spruenge << "\nKollisionen der Bälle : \t\t\t"<< koll<<endl;
    
        out1.close();
        out2.close();
        phase.close();
        //Velocity-Verlet Verfahren
        cout << "\n_______________________________________________________________\nVelocity-Verlet Verfahren\n_______________________________________________________________"<<endl;
        initialize();
        ofstream out21; out21.open("Trajektorie1_v.txt",ios::out);  //Trajektorie unteres Teilchen
        ofstream out22; out22.open("Trajektorie2_v.txt",ios::out);  //Trajektorie oberes Teilchen
        ofstream phase2; phase2.open("Phasenraum_v.txt",ios::out);  //Pahsenraum
    
        for(int i=1;i<=NMAX;i++)
        {
            force();
            integrate_velocity1(DT);
            force();
            integrate_velocity2(DT);
            t+=DT;
            //Energie-Velocity-Verlet
            out21 << ke1 + pe1 << " " ;
            out22 << ke2 + pe2 << " ";
            energy_v[0][i] = ke1+ke2+pe1+pe2;
            sample(DT, out21, out22);
            phase2 << x[1][2]-x[0][2]<< " "<< x[0][2]+x[1][2]<<endl;
        }
        details << "\n\nVelocity-Verlet\nAnzahl Bodenkontakte : \t\t\t\t"<< spruenge << "\nKollisionen der Bälle : \t\t\t"<< koll<<endl;
        cout <<"Anzahl der Sprünge : "<<spruenge<<"\nGesamtzeit :"<<t<< " Energiedifferenz Verlet : " << energy_v[0][NMAX-1]<< "-"<<energy_v[0][1] << "= "<< energy_v[0][NMAX-1]-energy_v[0][1] << "\nEnergiedifferenz Euler : " << energy_e[0][NMAX-1] << "-" <<energy_e[0][1]<< "= "<<energy_e[0][NMAX-1] -energy_e[0][1]<<endl;
        details << "\n\nEnergiedifferenz Velocity-Verlet Verfahren : \t" << energy_v[0][NMAX-1]-energy_v[0][1]<< "\nEnergiedifferenz Euler Verfahren : \t\t" << energy_e[0][NMAX-1] -energy_e[0][1] <<endl;
        out21.close();
        out22.close();
        phase2.close();
        details.close();
    
    }
    //-----------------------------------------------Initialize----------------------------------------------------------------
    void initialize()
    {
    
        //Startwerte
        Ballradius = 0.00005;
        t = 0;
        G = 1;
        k = 35;
        zeit = 0;
        spruenge = 0;
        t_sprung = 0;
        koll = 0;
        double cache[np][3];
    
        //erstes Teilchen
        m[0] = 1;
        x[0][0] =     0;      /* x-Richtung*/           v[0][0] = 0;
        x[0][1] =     0;      /* y-Richtung*/           v[0][1] = 0;
        x[0][2] =     10;     /* z-Richtung*/           v[0][2] = 0;
    
        //zweites Teilchen
        m[1] = 1;
        x[1][0] =     0;      /* x-Richtung*/           v[1][0] = 0;
        x[1][1] =     0;      /* y-Richtung*/           v[1][1] = 0;
        x[1][2] =     11;     /* z-Richtung*/           v[1][2] = 0;
    
    }
    
    //-------------------------------------------------Force---------------------------------------------------------------------
    void force()
    {
        // Schwerkraft
        for (int i =0; i<np;i++)
        {
            f[i][0] = 0;
            f[i][1] = 0;
            f[i][2] = -G*m[i]-v[i][2];
        }
    
        // Kraft durch Feder
        f2[0][2] = -k*(x[0][2]-x[1][2]+1);
        f2[1][2] = k*(x[0][2]-x[1][2]+1);
        cout << f2[0][2] << " " << f2[1][2] << endl;
    
        //Energien
        ke1 = 0.5*m[0]*pow(laenge(v[0][0],v[0][1],v[0][2]),2);
        pe1 = m[0]*G*x[0][2];
        cout <<" Kin : "<< ke1 << "Pot: "<< pe1 << " Gesamt : " << pe1+ke1 << endl;
    
        ke2 = 0.5*m[1]*pow(laenge(v[1][0],v[1][1],v[1][2]),2);
        pe2 = m[1]*G*x[1][2];
        cout << " Kin : "<< ke2 << "Pot : "<< pe2<< " Gesamt : " << pe2+ke2 <<endl;
    
    }
    //---------------------------------------------------Integrate--------------------------------------------------------------
    
    void integrate_euler(double dt)  //Euler-Algorithmus
    {
        zeit += dt;
        t_sprung += dt;
    
        //Teilche Kollision
        if ((x[1][2]-x[0][2])<Ballradius)
        {
            cache[1][2]=v[1][2] ;
            v[1][2]= v[0][2];
            v[0][2]= cache[1][2];
            koll++;
        }
        for (int i =0; i<np;i++)
        {
            //Bodenkontakt
            if (x[i][2] <= 0)
            {
                v[i][2] = -v[i][2];
                x[i][2] = 0;
                spruenge += 1;
                t_sprung = 0;
            }
    
            //Integration
            for (int j=0;j<3; j++)
            {
                v[i][j] = v[i][j] + dt*f[i][j];
                v[i][j] = v[i][j] + dt*f2[i][j];
                x[i][j] = x[i][j] + dt*v[i][j];
            }
        }
    }
    void integrate_velocity1(double dt)  //Velocity-Algorithmus1
    {
    
        zeit += dt;
        t_sprung += dt;
        //Teilche Kollision
        if ((x[1][2]-x[0][2])<Ballradius)
        {
            cache[1][2]=v[1][2] ;
            v[1][2]= v[0][2];
            v[0][2]= cache[1][2];
            koll++;
        }
        for (int i =0; i<np;i++)
        {
            //Bodenkontakt
            if (x[i][2] < 0)
            {
                v[i][2] = -v[i][2];
                x[i][2] = 0;
                spruenge += 1;
                t_sprung = 0;
            }
    
            for (int j=0;j<3; j++)
            {
                cache[i][j] = v[i][j] + dt/2*f[i][j];
                cache[i][j] = cache[i][j] + dt/2*f2[i][j];
                x[i][j] = x[i][j] + dt*cache[i][j];
            }
        }
    }
    void integrate_velocity2(double dt)  //Velocity-Algorithmus2
    {
    
        for (int i =0; i<np;i++)
        {
            for (int j=0;j<3; j++)
            {
                v[i][j] = cache[i][j] + dt/2*f[i][j];
                v[i][j] = v[i][j] + dt/2*f2[i][j];
            }
        }
    }
    //---------------------------------------------Ausgabe-------------------------------------------------------------------
    
    void sample(double DT, ofstream& ausgabe1, ofstream& ausgabe2)
    {
        ausgabe1 << t<<" "<<x[0][2]<< endl;
        cout << spruenge <<". Sprung, Sprungzeit : "<<t_sprung<<" Kollisionen : "<<koll <<endl;
        ausgabe2 <<t<<" "<<x[1][2]<<endl;
    }
    


  • Sry, hatte die Startargumente unter Windows vergessen... unter Linux kam immer eine geeignite Fehlermeldung. War etwas überreizt, da ich QT 3 mal neuinstalliert habe 😃

    Aber habe trotzdem noch eine Frage, weis nicht ob ich hier Richtig bin, aber ist mein Integrationsverfahren Richtig ? Ich verliere nämlich Energie relativ schnell, was ja eigtl nicht Sein sollte....

    Die Kraft wird so berechnet :

    void force()
    {
        // Schwerkraft
        for (int i =0; i<np;i++)
        {
            f[i][0] = 0;
            f[i][1] = 0;
            f[i][2] = -G*m[i]-v[i][2];
        }
    
        // Kraft durch Feder
        f2[0][2] = -k*(x[0][2]-x[1][2]+1);
        f2[1][2] = k*(x[0][2]-x[1][2]+1);
        cout << f2[0][2] << " " << f2[1][2] << endl;
    

    und integriert wird dann so :

    void integrate_euler(double dt)  //Euler-Algorithmus
    {
    
        for (int i =0; i<np;i++)
        {
            //Bodenkontakt
            if (x[i][2] <= 0)
            {
                v[i][2] = -v[i][2];
                x[i][2] = 0;
                spruenge += 1;
                t_sprung = 0;
            }
    
            //Integration
            for (int j=0;j<3; j++)
            {
                v[i][j] = v[i][j] + dt*f[i][j];
                v[i][j] = v[i][j] + dt*f2[i][j];
                x[i][j] = x[i][j] + dt*v[i][j];
            }
        }
    }
    


  • Zeile 45 und daraus resultierend Zeile 49.

    Bei einem Array

    int x[N];
    

    muss N immer konstant sein. Das heisst zur Compilezeit konstant, nicht irgendwann zur Laufzeit konstant.

    Und dein NMAX wird beim Start des Programms aus den Argumenten der Kommandozeile ausgewertet (Laufzeit), konstant gesagt und als Arraygröße genutzt. Das geht nicht.
    Der GCC hat da eine Erweiterung (VLA heisst die glaube ich), dass der das schluckt.

    Nimm statt

    double energy_e[np][NMAX];
    // und
    double ernergy_v[np][NMAX];
    

    lieber

    std::vector<std::vector<double>> energy_e(np, std::vector<double>(NMAX));
    // und
    std::vector<std::vector<double>> energy_v(np, std::vector<double>(NMAX));
    

    Ist sicherer.

    (Und irgendwo hast du einen Laufzeitfehler, ich vermute du hälst Arraygrenzen nicht ein, aber ich gucke deinen Code nicht durch, weil nicht schön.)


Log in to reply