Bernhard
Registriertes Mitglied
"100 Punkte für den Kandidaten".x_n - Aktueller Ort
v_n - aktuelle Geschw.
a - Beschleunigung?
h - Schrittweite
n aktueller Zeitpunkt
n+1 nächster (zu berechnender) Zeitpunkt
Zuletzt bearbeitet:
"100 Punkte für den Kandidaten".x_n - Aktueller Ort
v_n - aktuelle Geschw.
a - Beschleunigung?
h - Schrittweite
n aktueller Zeitpunkt
n+1 nächster (zu berechnender) Zeitpunkt
Hallo Stefan,Ich habe da die Variablen x und v durcheinander gebracht. Richtig muss es heißen:
x_{n+1} = x_n + h * v_n + 0,5 * h^2 * a(x_n)
v_{n+1} = v_n + h * a(x_n + h/2 * v_n)
Die Beschleunigung muss bei diesem Verfahren pro Schritt, statt einmal, also zweimal berechnet werden und zwar an der Stelle x_n für den neuen Ort und an der Stelle x_n + h/2 * v_n für die neue Geschwindigkeit.
Hallo Stefan,Da ist mir gerade was aufgefallen. Ich glaube bei mir ist das so nicht implementiert, sondern folgendermaßen:
v_{n+1} = v_n + a(x_n)
x_{n+1} = x_n + v{n+1}
1. fehlt das h in den Gleichungen, was aber durch TconsSquare = h*h bereits weiter vorne eingerechnet ist (möglicherweise ist frühe quadrieren falsch)
2. benutze ich v(n+1) um x(n+1) zu berechnen was möglicherweise auch falsch ist.
Ich denke zuerst müssen wir die Fehler da ausräumen, die möglicherweise für die Abweichungen verantwortlich sind.
void Planet::GetNextPosition(double Tconst)
{
dx->x = Velocity->x;
dx->y = Velocity->y;
dx->z = Velocity->z;
// Neue Position
dx->Mul(Tconst);
pos->Add(dx);
// Neue Geschwindigkeit
Accel->Mul(Tconst);
Velocity->Add(Accel);
Accel->Reset();
}
void PSystem::DoStep()
{
steps++;
Planet *source;
Planet *target;
double dist;
for(source = sun; source != 0; source = source->next)
{
for(target = sun;target != 0;target = target->next)
{
if(source != target)
{
PVektor::Sub(tmp, target->pos, source->pos); // Beschleunigung berechnen
dist = tmp->Len();
tmp->Mul(target->mass/(dist*dist*dist));
source->Accel->Add(tmp); // Beschleunigung hinzufügen
}
}
}
for(source = sun; source != 0; source = source->next)
{
source->GetNextPosition( Tconst );
}
}
tmp->Velocity->x = vx;
tmp->Velocity->y = vy;
tmp->Velocity->z = vz;
Hallo Stefan,In dem von euch vorgeschlagenen HORIZONS Katalog(Danke nochmal, genau was ich gesucht habe) werden perfekterweise die Objekte als Position und Geschwindigkeit angegeben.
Hier als Beispiel die Erde, Koordinatenursprung ist die Sonne, Einheit ist AU:
JDCT
X Y Z <-- Position
VX VY VZ <-- Geschwindigkeit
LT RG RR LT = Lichtzeit(day); RG = Distance from Center(AU); RR = Range Rate(Änderungsrate von RG pro Tag (AU/day)
2455652.500000000 = A.D. 2011-Apr-01 00:00:00.0000 (CT)
-9.855554845305842E-01 -1.864518242419004E-01 1.975847807252305E-05 <-- Position
2.933461796767275E-03 -1.697932543422671E-02 2.779216797989756E-07 <-- Geschwindigkeit
5.793060517472141E-03 1.003037335417702E+00 2.739049035701513E-04
Man könnte die Massen der Planeten trivialerweise über die relativistische Massenformel m_rel = m / sqrt(1-v^2/c^2) berechnen, da wir uns ja im Schwerpunktsystem befinden. Ich frage mich schon des längeren, ob man damit näherungsweise die Periheldrehung simulieren kann. Ich muss mir aber erst mal überlegen, wie sich das innerhalb der Midpoint-Methode implementieren läßt. Mit Runge-Kutta könnte man auch noch eine Version basteln, aber die relativistischen Effekte finde ich erst mal spannender.Sicher gibt es irgendwelche linearen Approximationen für die ART Effekte, mal schauen.
Das kann ich noch nicht nachvollziehen. Gerechnet wird mit 31536000 Sekunden = 365 Tage. Addiert man zum 01.04.2011 diese 365 Tage bekommt man - wie im Programm - den 31.03.2012.Der Fehler der ungenügenden Genauigkeit habe ich vermutlich gefunden: die Zeitfunktion die noch aus C-Zeiten stammt, rechnet anscheinend mit der Systemzeitzone (also unsere), jedenfalls beträgt der Fehler genau 6h.
Ich komme deswegen eher auf die folgenden Werte:Berücksichtigt man die Abweichung, beträgt der absolute Fehler der Position nach einem Jahr:
X = 730 km
Y = 5900 km
Z = 1640 km
Hallo Stefan,Man könnte die Massen der Planeten trivialerweise über die relativistische Massenformel m_rel = m / sqrt(1-v^2/c^2) berechnen, da wir uns ja im Schwerpunktsystem befinden. Ich frage mich schon des längeren, ob man damit näherungsweise die Periheldrehung simulieren kann.
So leuchtet es ein.Daher ist man auf der sichereren Seite, wenn man immer erst die kleinen Zahlen miteinander addiert und in der Größenordnung wächst.
PHP:void PSystem::DoStep() { steps++; Planet *source; Planet *target; double dist; for(source = sun; source != 0; source = source->next) { for(target = sun;target != 0;target = target->next) { if(source != target) { PVektor::Sub(tmp, target->pos, source->pos); // Beschleunigung berechnen dist = tmp->Len(); tmp->Mul(target->mass/(dist*dist*dist)); source->Accel->Add(tmp); // Beschleunigung hinzufügen } } } for(source = sun; source != 0; source = source->next) { source->GetNextPosition( Tconst ); } }
void PSystem::DoStep()
{
steps++;
Planet *pI= sun;
Planet *pJ = sun->next;
double dist, dist3;
PVektor tmpI, tmpJ;
int iLen, i, j; //iLen mal bitte auf Anzahl Objekte setzen (wie gesagt, Code noch nicht angeschaut)!!!
for(i=0; i<iLen; i++)
{
for(j=i+1; j<iLen; j++)
{
PVektor::Sub(tmpI, pI->pos, pJ->pos);
PVektor::Sub(tmpJ, pI->pos, pJ->pos); //notwendig (doppelt gemoppelt), da Sub, Add usw. keine neue Instanz zurückgeben sondern die bestehende ändern (brauch aber zwei verschiedene Vektoren zum Ändern des jeweiligen Beschleunigungsanteils)
dist = tmpI->Len();
dist3 = dist*dist*dist;
tmpI->Mul(pJ->mass/dist3)
tmpJ->Mul(pI->mass/dist3)
pI->Accel->Sub(tmpI);
pJ->Accel->Add(tmpJ);
pJ=pJ->next;
}
pI=pI->next;
}
for(pI = sun; pI!= 0; pI=pI->next)
{
pI->GetNextPosition( Tconst );
}
}
Es ist recht merkwürdig das es "genau" 6 Std. sind. Aber ich mache mittlerweile die Zeitfunktion nichtmehr verantwortlich dafür.
Ich vermute irgendeinen Fehler in den Vorgaben von Horizons.
Das is es nicht. Ich habe das mit einem Kalender nachgeprüft und der 29.02.2012 wird in der Rechnung zu 100% berücksichtigt.Ich nehme sehr stark an, dass der 29.02.2012 nur anteilig mit seinen 6h in die Positionsbestimmung eingeflossen ist.
Am liebsten würde ich alles mal mit 100 Stellen Genauigkeit rechnen und nicht mit double.