Skip to content

Commit c93c9a1

Browse files
Fix bugs + align with softening etc
1 parent 3670d6f commit c93c9a1

1 file changed

Lines changed: 20 additions & 74 deletions

File tree

src/gravity/octree.h

Lines changed: 20 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ struct Octree {
146146
}
147147
};
148148

149+
149150
inline void bhAccel(Octree* node,
150151
const Particle& p,
151152
real theta,
@@ -162,20 +163,26 @@ inline void bhAccel(Octree* node,
162163

163164
constexpr real G = real(1.0);
164165

165-
// Adaptive softening
166-
real eps = nextSoftening(node->size, node->m, dist);
167-
166+
// Geometric separation
168167
real dx = node->cx - p.x;
169168
real dy = node->cy - p.y;
170169
real dz = node->cz - p.z;
171170

172-
real r2_soft = dx * dx + dy * dy + dz * dz + eps * eps;
173-
real dist = std::sqrt(r2_soft);
171+
// Physical distance (unsmoothed)
172+
real r2 = dx*dx + dy*dy + dz*dz;
173+
real dist = std::sqrt(r2 + real(1e-20)); // tiny floor to avoid NaN
174+
175+
// Adaptive softening (returns epsilon)
176+
real eps = nextSoftening(node->size, node->m, dist);
177+
178+
// Softened distance for force
179+
real r2_soft = r2 + eps*eps;
180+
real dist_soft = std::sqrt(r2_soft);
174181

175-
// BH acceptance criterion
182+
// BH acceptance criterion (use geometric distance)
176183
if (node->leaf || (node->size / dist) < theta) {
177-
// Monopole
178-
real invDist = real(1.0) / dist;
184+
// Monopole term with softened distance
185+
real invDist = real(1.0) / dist_soft;
179186
real invDist2 = invDist * invDist;
180187
real invDist3 = invDist * invDist2;
181188

@@ -185,13 +192,13 @@ inline void bhAccel(Octree* node,
185192
real ay_m = dy * fac;
186193
real az_m = dz * fac;
187194

188-
// Quadrupole (use non-softened r^2 for shape; still approximate)
195+
// Quadrupole: use geometric r (no softening) for shape
189196
real rx = dx;
190197
real ry = dy;
191198
real rz = dz;
192-
real r2 = rx * rx + ry * ry + rz * rz + real(1e-12); // avoid zero
193-
real r = std::sqrt(r2);
194-
real invr = real(1.0) / r;
199+
real r2_q = rx*rx + ry*ry + rz*rz + real(1e-12); // avoid zero
200+
real r_q = std::sqrt(r2_q);
201+
real invr = real(1.0) / r_q;
195202
real invr2 = invr * invr;
196203
real invr3 = invr * invr2;
197204
real invr5 = invr3 * invr2;
@@ -233,65 +240,4 @@ inline void bhAccel(Octree* node,
233240
bhAccel(node->child[i], p, theta, ax, ay, az);
234241
}
235242
}
236-
}
237-
238-
239-
struct BarnesHut {
240-
real theta;
241-
real root_x, root_y, root_z;
242-
real root_size;
243-
Octree* root = nullptr;
244-
245-
BarnesHut(real theta_,
246-
real cx,
247-
real cy,
248-
real cz,
249-
real halfSize)
250-
: theta(theta_)
251-
, root_x(cx)
252-
, root_y(cy)
253-
, root_z(cz)
254-
, root_size(halfSize) {}
255-
256-
~BarnesHut() {
257-
delete root;
258-
}
259-
260-
// Build tree from particles (positions must already be set).
261-
void build(std::vector<Particle>& particles) {
262-
delete root;
263-
root = new Octree(root_x, root_y, root_z, root_size);
264-
265-
for (auto& p : particles) {
266-
root->insert(&p);
267-
}
268-
root->computeMass();
269-
}
270-
271-
// Compute self-gravity accelerations in-place on particles.
272-
273-
void evalSelfGravity(std::vector<Particle>& particles) const {
274-
if (!root) return;
275-
276-
for (auto& p : particles) {
277-
real ax = 0;
278-
real ay = 0;
279-
real az = 0;
280-
bhAccel(root, p, theta, ax, ay, az);
281-
282-
p.ax = ax;
283-
p.ay = ay;
284-
p.az = az;
285-
}
286-
}
287-
288-
289-
void evalAtPoint(const Particle& probe,
290-
real& ax,
291-
real& ay,
292-
real& az) const {
293-
ax = ay = az = 0;
294-
if (!root) return;
295-
bhAccel(root, probe, theta, ax, ay, az);
296-
}
297-
};
243+
}

0 commit comments

Comments
 (0)