@@ -93,24 +93,30 @@ struct Octree {
9393inline void bhAccel (Octree* node, const Particle& p, real theta,
9494 real& ax, real& ay, real& az)
9595{
96- if (!node || node->m == 0 ) return ;
96+ if (!node || node->m == 0 )
97+ return ;
98+
99+ // Skip self-force
100+ if (node->leaf && node->body == &p)
101+ return ;
97102
98103 constexpr real G = real (6.67430e-11 );
99- constexpr real eps = real (1e-6 );
104+
105+ // IMPORTANT: use a meaningful softening for your scale
106+ constexpr real eps = real (1e6 );
100107
101108 real dx = node->cx - p.x ;
102109 real dy = node->cy - p.y ;
103110 real dz = node->cz - p.z ;
104111
105- // same softening style as Gravity(): + eps^2
106112 real distSq = dx*dx + dy*dy + dz*dz + eps*eps;
107113 real dist = std::sqrt (distSq);
108114
109- // Barnes–Hut acceptance criterion
110- // node->size is half-width → full size = 2*size
111- if (node-> leaf || ( (node-> size * real ( 2 )) / dist ) < theta) {
115+ // Correct Barnes–Hut acceptance criterion
116+ if ( node->leaf || (node-> size / dist) < theta)
117+ {
112118 real invDist = real (1 ) / dist;
113- real invDist3 = invDist * invDist * invDist; // 1 / r^3
119+ real invDist3 = invDist * invDist * invDist;
114120
115121 real fac = G * node->m * invDist3;
116122
@@ -120,9 +126,8 @@ inline void bhAccel(Octree* node, const Particle& p, real theta,
120126 return ;
121127 }
122128
123- // Otherwise recurse into children
124- for (int i = 0 ; i < 8 ; i++) {
129+ // Recurse
130+ for (int i = 0 ; i < 8 ; i++)
125131 if (node->child [i])
126132 bhAccel (node->child [i], p, theta, ax, ay, az);
127- }
128- }
133+ }
0 commit comments