quietsamurai98
quietsamurai98

Reputation: 35

Optimizing an n-body gravitational attraction algorithm

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

Answers (2)

py13579
py13579

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

user4910279
user4910279

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

Related Questions