gpt4 book ai didi

java - Runge-Kutta N-Body 实现不起作用

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:57:46 25 4
gpt4 key购买 nike

我已经按照本文所述用 Java 实现了 Runge-Kutta 4 算法。 http://spiff.rit.edu/richmond/nbody/OrbitRungeKutta4.pdf

然而,运动是不稳定的。即使只有两个 body ,也没有周期性运动。

protected void integrateRK4(double time) {

final double H = time;
final double HO2 = H/2;
final double HO6 = H/6;

Vector2[] currentVelocities = new Vector2[objects.length];
Vector2[] currentPositions = new Vector2[objects.length];
Vector2[] vk1 = new Vector2[objects.length];
Vector2[] vk2 = new Vector2[objects.length];
Vector2[] vk3 = new Vector2[objects.length];
Vector2[] vk4 = new Vector2[objects.length];
Vector2[] rk1 = new Vector2[objects.length];
Vector2[] rk2 = new Vector2[objects.length];
Vector2[] rk3 = new Vector2[objects.length];
Vector2[] rk4 = new Vector2[objects.length];


for (int i=0; i<objects.length; i++) {
currentVelocities[i] = objects[i].velocity().clone();
currentPositions[i] = objects[i].position().clone();
}

vk1 = computeAccelerations(objects);
for (int i=0; i<objects.length; i++) {
rk1[i] = currentVelocities[i].clone();
}

for (int i=0; i<objects.length; i++) {
objects[i].setPosition(Vectors2.add(currentPositions[i], Vectors2.prod(rk1[i], HO2)));
}
vk2 = computeAccelerations(objects);

for (int i=0; i<objects.length; i++) {
rk2[i] = Vectors2.prod(vk1[i], HO2);
}


for (int i=0; i<objects.length; i++) {
objects[i].setPosition(Vectors2.add(currentPositions[i], Vectors2.prod(rk2[i], HO2)));
}
vk3 = computeAccelerations(objects);

for (int i=0; i<objects.length; i++) {
rk3[i] = Vectors2.prod(vk2[i], HO2);
}


for (int i=0; i<objects.length; i++) {
objects[i].setPosition(Vectors2.add(currentPositions[i], Vectors2.prod(rk3[i], H)));
}
vk4 = computeAccelerations(objects);

for (int i=0; i<objects.length; i++) {
rk4[i] = Vectors2.prod(vk3[i], H);
}


for (int i=0; i<objects.length; i++) {
objects[i].setVelocity(Vectors2.add(currentVelocities[i], Vectors2.prod(Vectors2.add(vk1[i], Vectors2.prod(vk2[i], 2), Vectors2.prod(vk3[i], 2), vk4[i]), HO6)));
objects[i].setPosition(Vectors2.add(currentPositions[i], Vectors2.prod(Vectors2.add(rk1[i], Vectors2.prod(rk2[i], 2), Vectors2.prod(rk3[i], 2), rk4[i]), HO6)));
}
}

我的实现不知何故不正确吗?

注意:

Vectors2 是我自己实现的 Vectors,它是大小为 2 的一阶张量。
所有静态方法 Vectors2.* 都返回 vector 的副本。
所有在 Vector2 实例上调用的非静态方法都会修改 vector ,同样适用于 objects[i].addVelocity()objects[i].addPosition()

Vectors2.add(Vector2... vectors2) 进行逐元素加法。
Vectors2.prod(Vector2... vectors2) 执行逐元素乘法。
Vectors2.prod(Vector2 vector2, double c) 执行逐元素乘法。

computeAccelerations(PointBody[] objects) 返回加速度 vector 数组。
变量 objects 是类 NBodyIntegrator 的一个属性,这些函数是其中的一部分。它是一个 PointBody[] 数组。

为了确保这不是其他错误,我通过删除 k2、k3 和 k4 将 RK4 算法缩减为显式欧拉算法。这一个按预期工作。

protected void integrateRK1(double time) {
final double H = time;
final double HO2 = H/2;

Vector2[] currentVelocities = new Vector2[objects.length];
Vector2[] currentPositions = new Vector2[objects.length];
Vector2[] vk1;
Vector2[] rk1 = new Vector2[objects.length];


for (int i=0; i<objects.length; i++) {
currentVelocities[i] = objects[i].velocity().clone();
currentPositions[i] = objects[i].position().clone();
}


vk1 = computeAccelerations(objects);
for (int i=0; i<objects.length; i++) {
rk1[i] = currentVelocities[i].clone();
}


for (int i=0; i<objects.length; i++) {
objects[i].setVelocity(Vectors2.add(currentVelocities[i], Vectors2.prod(Vectors2.add(vk1[i]), H)));
objects[i].setPosition(Vectors2.add(currentPositions[i], Vectors2.prod(Vectors2.add(rk1[i]), H)));
}
}

最佳答案

你在设置

rk1 = v0
pos2 = pos0 + rk1*h/2
vk2 = acc(pos2)

这是正确的。但是然后你继续

rk2 = vk1*h/2

它应该在哪里

rk2 = v0 + vk1*h/2

等等。当然那么累积位置更新也是错误的。

关于java - Runge-Kutta N-Body 实现不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42848155/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com