|
10 | 10 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
11 | 11 |
|
12 | 12 | #pragma once |
| 13 | +#include "floatdef.h" |
13 | 14 | #include <cmath> |
| 15 | +#include <algorithm> |
14 | 16 |
|
15 | | -/* Softening for BarnesHut */ |
| 17 | +/** |
| 18 | + * @brief Softening for Barnes-Hut node interactions. |
| 19 | + * Note: nodeMass and dist are passed as individual reals from the SoA arrays. |
| 20 | + */ |
16 | 21 | inline real nextSoftening(real nodeSize, real nodeMass, real dist) { |
17 | | - // Base softening from node size |
18 | | - real eps_size = nodeSize * real(0.015); |
| 22 | + // std::pow(x, 1/3) or std::cbrt is slow. |
| 23 | + // In SoA loops, this is often the bottleneck. |
| 24 | + real eps_size = nodeSize * real(0.015); |
| 25 | + real eps_mass = std::cbrt(nodeMass) * real(0.002); |
19 | 26 |
|
20 | | - // Mass-based softening (physical radius proxy) |
21 | | - real eps_mass = std::cbrt(nodeMass) * real(0.002); |
| 27 | + // Distance taper: strong at r->0, fades smoothly |
| 28 | + real eps_taper = real(1.0) / (real(1.0) + dist * real(10.0)); |
22 | 29 |
|
23 | | - // Distance taper: strong at r→0, fades smoothly |
24 | | - real eps_taper = real(1.0) / (real(1.0) + dist * real(10.0)); |
| 30 | + // Combine |
| 31 | + real eps = (eps_size + eps_mass) * eps_taper; |
25 | 32 |
|
26 | | - // Combine |
27 | | - real eps = (eps_size + eps_mass) * eps_taper; |
28 | | - |
29 | | - // Minimum floor |
30 | | - const real eps_min = real(1e-4); |
31 | | - if (eps < eps_min) |
32 | | - eps = eps_min; |
33 | | - |
34 | | - return eps; |
| 33 | + // Minimum floor - using std::max is cleaner and easier for the compiler to optimize |
| 34 | + return std::max(eps, real(1e-4)); |
35 | 35 | } |
36 | 36 |
|
37 | | -/* Softening for Gravity kernel */ |
| 37 | +/** |
| 38 | + * @brief Softening for direct particle-particle gravity kernels. |
| 39 | + * ma and mb are the masses pulled from the ps.m[i] and ps.m[j] arrays. |
| 40 | + */ |
38 | 41 | inline real pairSoftening(real ma, real mb) { |
39 | | - // Physical radius proxy |
40 | | - real ea = std::cbrt(ma) * real(0.002); |
41 | | - real eb = std::cbrt(mb) * real(0.002); |
42 | | - |
43 | | - // Symmetric combination (quadrature) |
44 | | - real eps = std::sqrt(ea * ea + eb * eb); |
| 42 | + // Physical radius proxy |
| 43 | + real ea = std::cbrt(ma) * real(0.002); |
| 44 | + real eb = std::cbrt(mb) * real(0.002); |
45 | 45 |
|
46 | | - // Minimum floor |
47 | | - const real eps_min = real(1e-4); |
48 | | - if (eps < eps_min) |
49 | | - eps = eps_min; |
| 46 | + // Symmetric combination (quadrature) |
| 47 | + real epsSq = ea * ea + eb * eb; |
| 48 | + real eps = std::sqrt(epsSq); |
50 | 49 |
|
51 | | - return eps; // return epsilon |
| 50 | + // Minimum floor |
| 51 | + return std::max(eps, real(1e-4)); |
52 | 52 | } |
0 commit comments