优化 n 体引力吸引算法
Optimizing an n-body gravitational attraction algorithm
我正在编写 2d 原行星盘的模拟,现在,最耗时的代码是计算引力。这是我目前使用的代码。
for(int i=0; i<particleCount; i++){
if(boolArray[i]){ //boolArray is linked with particleArray, false means the linked particle has collided with another particle and no longer exists
double iX = particleArray[i].getXPosition();
double iY = particleArray[i].getYPosition();
double iM = particleArray[i].getMass();
for(int j=0; j<particleCount; j++){
if(i!=j&&boolArray[j]){
double rX = iX-particleArray[j].getXPosition();
double rY = iY-particleArray[j].getYPosition();
double rT = Math.sqrt(rX*rX+rY*rY);
double rF = rT*rT*rT;
double fT = -constantGravity*iM*particleArray[j].getMass()/rF;
particleArray[i].updateForce(rX*fT, rY*fT);
}
}
}
}
有人知道如何加快速度吗?我认为
中的 sqrt
double rT = Math.sqrt(rX*rX+rY*rY);
是最大的罪魁祸首,但我不确定我是否能摆脱它。
可以在 https://github.com/quietsamurai98/2D-Accretion-Simulation/tree/Trails-png
找到编译就绪代码
您正在为每对点计算两次。
试试这个。
for (int i = 0; i < particleCount; i++) {
if (boolArray[i]) { // boolArray is linked with particleArray, false
// means the linked particle has collided with
// another particle and no longer exists
double iX = particleArray[i].getXPosition();
double iY = particleArray[i].getYPosition();
double iM = particleArray[i].getMass();
for (int j = i + 1; j < particleCount; j++) {
if (boolArray[j]) {
double rX = iX - particleArray[j].getXPosition();
double rY = iY - particleArray[j].getYPosition();
double rT = Math.sqrt(rX * rX + rY * rY);
double rF = rT * rT * rT;
double fT = -constantGravity * iM * particleArray[j].getMass() / rF;
particleArray[i].updateForce(rX * fT, rY * fT);
particleArray[j].updateForce(-rX * fT, -rY * fT);
}
}
}
}
您也可以使用四叉树(或 3d 的八叉树)。然后计算来自同一单元内每个物体的重力,然后为每个外部单元计算单元内质量的总和,并计算来自具有所述质量的单元中心的重力。这将失去精度,但具有良好平衡的四叉树和大量 N-Bodies 看起来非常逼真。 https://en.wikipedia.org/wiki/Barnes%E2%80%93Hut_simulation
我正在编写 2d 原行星盘的模拟,现在,最耗时的代码是计算引力。这是我目前使用的代码。
for(int i=0; i<particleCount; i++){
if(boolArray[i]){ //boolArray is linked with particleArray, false means the linked particle has collided with another particle and no longer exists
double iX = particleArray[i].getXPosition();
double iY = particleArray[i].getYPosition();
double iM = particleArray[i].getMass();
for(int j=0; j<particleCount; j++){
if(i!=j&&boolArray[j]){
double rX = iX-particleArray[j].getXPosition();
double rY = iY-particleArray[j].getYPosition();
double rT = Math.sqrt(rX*rX+rY*rY);
double rF = rT*rT*rT;
double fT = -constantGravity*iM*particleArray[j].getMass()/rF;
particleArray[i].updateForce(rX*fT, rY*fT);
}
}
}
}
有人知道如何加快速度吗?我认为
中的 sqrtdouble rT = Math.sqrt(rX*rX+rY*rY);
是最大的罪魁祸首,但我不确定我是否能摆脱它。
可以在 https://github.com/quietsamurai98/2D-Accretion-Simulation/tree/Trails-png
找到编译就绪代码您正在为每对点计算两次。 试试这个。
for (int i = 0; i < particleCount; i++) {
if (boolArray[i]) { // boolArray is linked with particleArray, false
// means the linked particle has collided with
// another particle and no longer exists
double iX = particleArray[i].getXPosition();
double iY = particleArray[i].getYPosition();
double iM = particleArray[i].getMass();
for (int j = i + 1; j < particleCount; j++) {
if (boolArray[j]) {
double rX = iX - particleArray[j].getXPosition();
double rY = iY - particleArray[j].getYPosition();
double rT = Math.sqrt(rX * rX + rY * rY);
double rF = rT * rT * rT;
double fT = -constantGravity * iM * particleArray[j].getMass() / rF;
particleArray[i].updateForce(rX * fT, rY * fT);
particleArray[j].updateForce(-rX * fT, -rY * fT);
}
}
}
}
您也可以使用四叉树(或 3d 的八叉树)。然后计算来自同一单元内每个物体的重力,然后为每个外部单元计算单元内质量的总和,并计算来自具有所述质量的单元中心的重力。这将失去精度,但具有良好平衡的四叉树和大量 N-Bodies 看起来非常逼真。 https://en.wikipedia.org/wiki/Barnes%E2%80%93Hut_simulation