Метод «прыжковой лягушки» очень эффективен и стабилен, и хорошо работает для любой динамической системы частиц / полей, включая плазму. Для гравитации это просто. Вот все, что вы делаете для одной итерации на одной планете (проблема с одним телом, одна планета вокруг неподвижного солнца):
public void Push()
{
Position += Gravity.dT * Velocity;
Velocity += Gravity.dT * GravityAccelerationVector(Position);
}
Где "Gravity.dT" - это постоянный временной шаг в произвольной мере. Я использую System.Windows.Vector, но подойдет любой пользовательский класс Vector, если он поддерживает базовое умножение и сложение. Хитрость заключается в том, что Position и Velocity не совпадают, что очень часто встречается в большинстве методов интеграции. Скорее, они поражены. Позиция на итерации N обновляется на основе Скорости от итерации N - 1/2, но затем Скорость на итерации N + 1/2 обновляется на основе Позиции на итерации N.
Версия N-body выглядит следующим образом:
public static void PushPlanets(Planet[] planets)
{
// Position Push at iteration N + 0:
foreach(var p in planets)
p.Position += Gravity.dT * p.Velocity; // Velocity from N - 1/2
// Velocity Push at iteration N + 1/2:
foreach (var p in planets)
{
Vector TotalGravity = new Vector(0,0);
foreach (var pN in planets)
{
if (pN == p) continue;
TotalGravity += pN.Mass * p.Mass * GravityAccelerationVector(p.Position - pN.Position);
}
TotalGravity += Sun.Mass * p.Mass * GravityAccelerationVector(p.Position); // Solar acceleration
p.Velocity += Gravity.dT * TotalGravity;
}
Где
public static Vector GravityAccelerationVector(Vector position)
{
return Vector.Multiply(-G / position.LengthSquared / position.Length, position);
}
N-тело только сложнее, потому что вместо одного гравитационного источника их несколько. Формат кода тот же, однако: положение каждой планеты сдвигается скоростью N-1/2, затем мы вычисляем общее ускорение силы тяжести на каждой планете на основе новых позиций, а затем мы увеличиваем скорость каждой планеты на это общее ускорение .
Другие методы, даже методы высокого порядка , часто нестабильны, потому что они линейно проецируют следующий шаг, основываясь на скорости положения и одновременно. Это всегда приведет к ошибкам в добавлении энергии в систему, и орбиты будут постепенно двигаться все дальше и дальше наружу. Другие методы могут компенсировать эту естественную ошибку и удалить энергию из системы. В общем, нужно энергетически нейтральное решение. Метод прыжковой лягушки будет постепенно ошибаться в терминах фазы орбит, но не в общей энергии.