|
| 1 | +```@meta |
| 2 | +CurrentModule = PhysicalTrees |
| 3 | +``` |
| 4 | + |
1 | 5 | # PhysicalTrees.jl |
2 | 6 |
|
3 | | -*Tools to construct distributed unitful trees* |
| 7 | +*Distributed octrees for N-body simulation* |
| 8 | + |
| 9 | +[PhysicalTrees.jl](https://github.com/JuliaAstroSim/PhysicalTrees.jl) |
| 10 | +is a package in the [JuliaAstroSim](https://github.com/JuliaAstroSim) |
| 11 | +ecosystem. It builds and queries space-partitioning **octrees** over |
| 12 | +particle data, in a way that is |
| 13 | + |
| 14 | +* **Unitful** — positions, smoothing lengths and box sizes carry their |
| 15 | + physical units (kpc, Myr, M⊙, …) end to end; unit errors are caught |
| 16 | + at the call site rather than producing silent nonsense. |
| 17 | +* **Distributed** — the build pipeline is split across multiple |
| 18 | + workers and the tree is rebuilt in place after data movement. |
| 19 | +* **Composable** — sits on top of [PhysicalParticles.jl](https://juliaastrosim.github.io/PhysicalParticles.jl/dev/) |
| 20 | + and re-exports its `PVector`, `Star`, `Massless`, `extent` and |
| 21 | + `datadimension`, so the rest of the ecosystem is one `using` away. |
| 22 | + |
| 23 | +## Why an octree? |
| 24 | + |
| 25 | +An N-body simulation needs to evaluate gravity (or SPH kernels) |
| 26 | +between every pair of nearby particles. A naïve double loop is |
| 27 | +``\mathcal O(N^2)``; an octree brings this down to ``\mathcal O(N\log N)`` |
| 28 | +by only descending into a node when the field it represents could |
| 29 | +materially contribute. |
| 30 | + |
| 31 | +## Package Features |
| 32 | + |
| 33 | +- Octree construction from raw `PVector`s, from |
| 34 | + `StructArray{<:AbstractParticle}`, and from unitless or unitful |
| 35 | + data. |
| 36 | +- Multi-worker tree construction via |
| 37 | + [`ParallelOperations`](https://github.com/JuliaAstroSim/ParallelOperations.jl). |
| 38 | +- Neighbor search: |
| 39 | + * [`ngb_treefind_variable`](@ref) / [`ngb_treefind_pairs`](@ref) — |
| 40 | + single-center cube / sphere search. |
| 41 | + * [`ngb_treefind_all`](@ref) / [`ngb_treefind_pairs_all`](@ref) — |
| 42 | + bulk neighbor list for every local particle (SPH density loop). |
| 43 | + * [`search_inbox_local`](@ref) / [`search_inradius_local`](@ref) / |
| 44 | + [`search_all_parallel`](@ref) — distributed variants that return |
| 45 | + per-task export flags so the caller can pull candidates from |
| 46 | + remote workers. |
| 47 | +- Periodic boundary conditions with a minimum-image convention |
| 48 | + (see [`ngb_periodic_diff`](@ref) and |
| 49 | + [`check_incube_periodic`](@ref)). |
| 50 | +- `update_node_len` — re-enlarges node `SideLength`s after particles |
| 51 | + have moved, equivalent to Gadget-2's |
| 52 | + `force_update_node_len_local`. |
| 53 | + |
| 54 | +## Quick start |
| 55 | + |
| 56 | +```julia |
| 57 | +using PhysicalParticles, PhysicalTrees, Unitful, UnitfulAstro |
| 58 | +using Distributed |
| 59 | +addprocs(2) |
| 60 | +@everywhere using PhysicalParticles, PhysicalTrees, UnitfulAstro |
| 61 | + |
| 62 | +# Six unitful particles in a (-1, 1)³ kpc cube |
| 63 | +pos = [PVector( 1.0, 1.0, 1.0, u"kpc"), |
| 64 | + PVector(-1.0, -1.0, -1.0, u"kpc"), |
| 65 | + PVector( 1.0, 0.0, -1.0, u"kpc"), |
| 66 | + PVector(-1.0, 0.0, 1.0, u"kpc"), |
| 67 | + PVector( 0.0, 0.0, -1.0, u"kpc"), |
| 68 | + PVector(-1.0, 0.0, 0.0, u"kpc")] |
4 | 69 |
|
5 | | -# Package Features |
| 70 | +particles = StructArray(Star(uAstro) for _ in 1:6) |
| 71 | +assign_particles(particles, :Pos, pos) |
6 | 72 |
|
7 | | -- Unitful |
8 | | -- Distributed |
9 | | -- User-friendly interface |
| 73 | +# Build the tree across workers 1 and 2 |
| 74 | +tree = octree(particles, pids = workers()) |
10 | 75 |
|
11 | | -# Manual Outline |
| 76 | +# Find particles inside a unit-radius cube around the origin |
| 77 | +ngb = ngb_treefind_variable(PVector(0.0, 0.0, 0.0, u"kpc"), 1.0u"kpc", tree) |
| 78 | + |
| 79 | +# Tear down on all workers when done |
| 80 | +unregister(tree) |
| 81 | +``` |
| 82 | + |
| 83 | +## Manual Outline |
12 | 84 |
|
13 | 85 | ```@contents |
14 | 86 | Pages = [ |
15 | 87 | "manual/guide.md", |
| 88 | + "manual/octree.md", |
16 | 89 | ] |
17 | | -``` |
| 90 | +``` |
| 91 | + |
| 92 | +## Library Reference |
| 93 | + |
| 94 | +```@contents |
| 95 | +Pages = [ |
| 96 | + "lib/Types.md", |
| 97 | + "lib/Methods.md", |
| 98 | +] |
| 99 | +``` |
| 100 | + |
| 101 | +## Package ecosystem |
| 102 | + |
| 103 | +- Basic data structure: [PhysicalParticles.jl](https://github.com/JuliaAstroSim/PhysicalParticles.jl) |
| 104 | +- File I/O: [AstroIO.jl](https://github.com/JuliaAstroSim/AstroIO.jl) |
| 105 | +- Initial Condition: [AstroIC.jl](https://github.com/JuliaAstroSim/AstroIC.jl) |
| 106 | +- Parallelism: [ParallelOperations.jl](https://github.com/JuliaAstroSim/ParallelOperations.jl) |
| 107 | +- Trees: [PhysicalTrees.jl](https://github.com/JuliaAstroSim/PhysicalTrees.jl) |
| 108 | +- Meshes: [PhysicalMeshes.jl](https://github.com/JuliaAstroSim/PhysicalMeshes.jl) |
| 109 | +- Plotting: [AstroPlot.jl](https://github.com/JuliaAstroSim/AstroPlot.jl) |
| 110 | +- [AstroNbodySim.jl](https://github.com/JuliaAstroSim/AstroNbodySim.jl) — gravitational N-body simulations, glue layer, and parallel runtime |
| 111 | +- Simulation of wave dark matter: [WaveDM.jl](https://github.com/JuliaAstroSim/WaveDM.jl) |
0 commit comments