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.)