Reputation: 35
I'm writing a simulation of a 2d protoplanetary disk, and right now, the most time consuming bit of code is calculating the gravitational attraction. This is the code I'm currently using.
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);
}
}
}
}
Does anybody have any ideas on how to speed it up? I think the sqrt in
double rT = Math.sqrt(rX*rX+rY*rY);
is the biggest culprit, but I'm not sure if I could even get rid of it.
The compile-ready code can be found at https://github.com/quietsamurai98/2D-Accretion-Simulation/tree/Trails-png
Upvotes: 1
Views: 204
Reputation: 56
You can also use quad-trees(or octrees for 3d). You then calculate the force of gravity from each body within the same cell and then for every outside cell calculate the sum of the masses within the cell and calculate the force of gravity from the center of that cell with said mass. This will lose precision but with a well balanced quad tree and very large number of N-Bodies will look pretty realistic. https://en.wikipedia.org/wiki/Barnes%E2%80%93Hut_simulation
Upvotes: 1
Reputation:
You are calculating twice for each pair of point. Try this.
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);
}
}
}
}
Upvotes: 1