2016-09-22 1 views
1

私は2dの原始惑星系のディスクのシミュレーションを書いていますが、今ではもっとも時間がかかるコードは重力の引力を計算することです。これは私が現在使っているコードです。n体の重力誘引アルゴリズムを最適化する

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 in

double rT = Math.sqrt(rX*rX+rY*rY); 

が最大の原因だと思っていますが、私はそれを取り除くことさえできるのかどうかは分かりません。

コンパイル準備のコードは、あなたがポイントのペアごとに二回計算しているhttps://github.com/quietsamurai98/2D-Accretion-Simulation/tree/Trails-png

+0

Javaは、O(log n)の複雑さが速いsqrt関数に対してスマートパワーアルゴリズムを使用します。それはホメオゲノス領域(ほこり...)のための粒子の代わりにセクタを使用すると考えられている遅延 – Rishi

+0

の理由ではありませんか?それはオブジェクトの量をかなり粗くする必要がありますが、精度は少し下がりますが、離散的な統合は現実とは遠く離れていることに気がついたら...少し伸びた精度はそれほど大きな影響を与えるべきではありません。ブースのアプローチで数回繰り返しても結果を比較する必要があるかどうかを確認するには、+/-同じにする必要があります。 – Spektre

答えて

1

で見つけることができます。 これを試してください。

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); 
      } 
     } 
    } 
} 
+0

これは間違いなく助けになりました! – quietsamurai98

0

クワッドツリー(または3次元のオクト)を使用することもできます。次に、同じセル内の各ボディからの重力を計算し、その後、すべての外部セルについて、セル内の質量の合計を計算し、その質量でそのセルの中心から重力を計算します。これで精度は落ちますが、バランスのとれたクワッドツリーと非常に多くのN-Bodyがかなりリアルに見えます。 https://en.wikipedia.org/wiki/Barnes%E2%80%93Hut_simulation

関連する問題