{"id":31772052,"url":"https://github.com/maroba/bhut","last_synced_at":"2025-10-10T03:55:24.198Z","repository":{"id":312402931,"uuid":"1047367145","full_name":"maroba/bhut","owner":"maroba","description":"A high-performance Barnes-Hut N-body accelerator that is array-agnostic, supporting both NumPy and Dask arrays for distributed computation.","archived":false,"fork":false,"pushed_at":"2025-08-30T10:40:10.000Z","size":1886,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-30T12:07:36.640Z","etag":null,"topics":["dask","gravitation","physics","python","scientific-computing"],"latest_commit_sha":null,"homepage":"https://maroba.github.io/bhut/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/maroba.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-30T09:00:46.000Z","updated_at":"2025-08-30T10:48:04.000Z","dependencies_parsed_at":"2025-08-30T12:07:45.742Z","dependency_job_id":"5a2f7e06-77e5-452c-b93e-128d04547f96","html_url":"https://github.com/maroba/bhut","commit_stats":null,"previous_names":["maroba/bhut"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/maroba/bhut","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maroba%2Fbhut","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maroba%2Fbhut/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maroba%2Fbhut/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maroba%2Fbhut/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maroba","download_url":"https://codeload.github.com/maroba/bhut/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maroba%2Fbhut/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002601,"owners_count":26083426,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dask","gravitation","physics","python","scientific-computing"],"created_at":"2025-10-10T03:55:17.526Z","updated_at":"2025-10-10T03:55:24.193Z","avatar_url":"https://github.com/maroba.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bhut\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/maroba/bhut/raw/main/docs/assets/logo.png\" alt=\"bhut logo\" width=\"200\"/\u003e\n\u003c/div\u003e\n\nA high-performance Barnes-Hut N-body accelerator in Python that is array-agnostic, supporting both NumPy and Dask arrays for distributed computation.\n\n[![CI](https://github.com/maroba/bhut/workflows/CI/badge.svg)](https://github.com/maroba/bhut/actions)\n[![PyPI](https://img.shields.io/pypi/v/bhut.svg)](https://pypi.org/project/bhut/)\n[![Python](https://img.shields.io/pypi/pyversions/bhut.svg)](https://pypi.org/project/bhut/)\n\n## Documentation\n\nFull documentation is available at:\n\n**https://maroba.github.io/bhut/**\n\n## Installation\n\n```bash\npip install bhut\n```\n\nFor acceleration features and optional dependencies:\n```bash\npip install bhut[accel]\npip install 'dask[array]'  # For distributed computation\npip install numba         # For JIT acceleration (recommended)\n```\n\n## Quick Start\n\n### Functional API\n\n```python\nimport numpy as np\nimport bhut\n\n# Generate random N-body system\nN = 10000\npositions = np.random.randn(N, 3)\nmasses = np.ones(N)\n\n# Compute gravitational accelerations using Barnes-Hut algorithm\naccelerations = bhut.accelerations(\n    positions, masses, \n    theta=0.5,        # Opening angle criterion\n    softening=0.01,   # Gravitational softening\n    G=1.0            # Gravitational constant\n)\n\nprint(f\"Acceleration shape: {accelerations.shape}\")  # (10000, 3)\n```\n\n### Object-Oriented API\n\n```python\nimport numpy as np\nfrom bhut import Tree\n\n# Create and build tree\npositions = np.random.randn(1000, 3)\nmasses = np.ones(1000)\n\ntree = Tree(positions, masses, leaf_size=32)\ntree.build()\n\n# Query accelerations for same particles\nself_accel = tree.accelerations(theta=0.5, softening=0.01)\n\n# Query accelerations at different target positions\ntargets = np.random.randn(500, 3)\ntarget_accel = tree.accelerations(targets, theta=0.5, softening=0.01)\n\n# Efficient tree updates for time evolution\nnew_positions = positions + 0.1 * np.random.randn(1000, 3)\n\n# Refit: fast update when particles move but topology is similar\ntree.refit(new_positions)\naccel_refit = tree.accelerations(theta=0.5, softening=0.01)\n\n# Rebuild: complete reconstruction when topology changes significantly\ntree.rebuild(new_positions, new_masses=masses * 1.1)\naccel_rebuild = tree.accelerations(theta=0.5, softening=0.01)\n```\n\n### Distributed Computing with Dask\n\n```python\nimport numpy as np\nimport dask.array as da\nimport bhut\n\n# Create large dataset distributed across chunks\nN = 1_000_000\npositions_np = np.random.randn(N, 3).astype(np.float64)\nmasses_np = np.ones(N, dtype=np.float64)\n\n# Convert to Dask arrays with chunking\npositions_da = da.from_array(positions_np, chunks=(100_000, 3))\nmasses_da = da.from_array(masses_np, chunks=(100_000,))\n\n# Compute accelerations in parallel (auto-detects Dask backend)\naccelerations_da = bhut.accelerations(positions_da, masses_da, theta=0.5)\n\n# Result preserves chunking structure for efficient downstream processing\nprint(f\"Input chunks: {positions_da.chunks}\")\nprint(f\"Output chunks: {accelerations_da.chunks}\")\n\n# Compute final result when needed\nresult = accelerations_da.compute()\n```\n\n### Numba JIT Acceleration\n\nFor maximum performance with NumPy arrays, install Numba for automatic JIT compilation:\n\n```python\nimport numpy as np\nimport bhut\n\n# Numba automatically detected and used if available\npositions = np.random.randn(10000, 3)\nmasses = np.ones(10000)\n\n# First call includes compilation overhead (~1s)\naccel1 = bhut.accelerations(positions, masses, theta=0.5)\n\n# Subsequent calls use cached compiled code (~27x faster)\naccel2 = bhut.accelerations(positions, masses, theta=0.5)\n```\n\n**Performance comparison (10,000 particles):**\n- **Without Numba**: ~4.5 seconds (pure Python)\n- **With Numba**: ~0.16 seconds after compilation (~27x speedup)\n- **Memory**: No additional memory overhead\n- **Compatibility**: Falls back gracefully when Numba unavailable\n\n**When Numba is used:**\n- Automatically detected when `import numba` succeeds\n- Only accelerates compute-intensive leaf node interactions\n- Pure Python fallback always available\n- Works with NumPy arrays (Dask arrays use pure Python)\n\n```python\n# Check if Numba acceleration is active\nfrom bhut.traverse.bh import HAVE_NUMBA\nprint(f\"Numba acceleration: {'✓ Available' if HAVE_NUMBA else '✗ Not available'}\")\n```\n\n## Features\n\n- **High Performance**: O(N log N) tree construction, O(M log N) force evaluation\n- **Numba Acceleration**: Optional JIT compilation for ~27x speedup in particle interactions\n- **Array-Agnostic**: Seamless support for NumPy and Dask arrays\n- **Distributed**: Built-in Dask integration for large-scale computation\n- **Accurate**: Configurable Barnes-Hut approximation with error control\n- **Efficient Updates**: Tree refit/rebuild for time-stepping simulations\n\n## Parameter Tuning Guide\n\n### Opening Angle (`theta`)\n\nControls the accuracy-performance tradeoff:\n\n## Parameter Tuning Guide\n\n### Opening Angle (`theta`)\n\nControls the accuracy-performance tradeoff:\n\n```python\n# High accuracy, slow computation\naccel_accurate = bhut.accelerations(pos, masses, theta=0.1)\n\n# Balanced (recommended for most applications)\naccel_balanced = bhut.accelerations(pos, masses, theta=0.5)\n\n# Fast approximation, lower accuracy\naccel_fast = bhut.accelerations(pos, masses, theta=1.0)\n\n# Direct summation (exact but O(N²))\naccel_exact = bhut.accelerations(pos, masses, theta=0.0)\n```\n\n**Guidelines:**\n- `theta = 0.0`: Exact O(N²) calculation (small systems only)\n- `theta = 0.1-0.3`: High accuracy for precision-critical applications\n- `theta = 0.5`: Good balance for most scientific simulations\n- `theta = 0.7-1.0`: Fast approximation for large-scale surveys\n- `theta \u003e 1.0`: Very approximate, mainly for prototyping\n\n### Leaf Size (`leaf_size`)\n\nControls tree granularity and performance:\n\n```python\n# Fine-grained tree (more memory, potentially faster for large queries)\ntree_fine = Tree(pos, masses, leaf_size=16)\ntree_fine.build()\n\n# Balanced (recommended default)\ntree_balanced = Tree(pos, masses, leaf_size=32)\ntree_balanced.build()\n\n# Coarse-grained tree (less memory, faster construction)\ntree_coarse = Tree(pos, masses, leaf_size=64)\ntree_coarse.build()\n```\n\n**Guidelines:**\n- `leaf_size = 8-16`: Best for systems with many small query sets\n- `leaf_size = 32`: Recommended default for most applications\n- `leaf_size = 64-128`: Better for large query sets or memory-constrained systems\n- `leaf_size \u003e 128`: May degrade performance due to increased direct summation\n\n### Performance Optimization\n\n#### Tree Refit vs Rebuild\n\nFor time-stepping simulations:\n\n```python\ntree = Tree(positions, masses)\ntree.build()\n\nfor timestep in range(num_steps):\n    # Compute forces\n    accel = tree.accelerations(theta=0.5, softening=0.01)\n    \n    # Update positions\n    positions += velocity * dt + 0.5 * accel * dt**2\n    velocity += accel * dt\n    \n    # Decide whether to refit or rebuild\n    if should_refit_vs_rebuild(tree, positions):\n        tree.refit(positions)  # Fast: O(N), preserves tree structure\n    else:\n        tree.rebuild(positions)  # Slower: O(N log N), rebuilds from scratch\n```\n\n#### Chunking Strategy for Dask\n\n```python\n# Good chunking: ~100K-1M particles per chunk\npositions_da = da.from_array(positions, chunks=(500_000, 3))\n\n# Avoid: too small chunks (overhead dominates)\npositions_bad = da.from_array(positions, chunks=(1_000, 3))\n\n# Avoid: too large chunks (memory issues, poor parallelization)\npositions_bad = da.from_array(positions, chunks=(10_000_000, 3))\n```\n\n## Performance Characteristics\n\n| System Size | Construction Time | Memory Usage | Recommended θ | Numba Speedup |\n|-------------|------------------|--------------|---------------|---------------|\n| N \u003c 10³     | \u003c 1ms            | \u003c 1MB        | 0.0 (exact)   | ~2x           |\n| N ~ 10⁴     | ~ 10ms           | ~ 10MB       | 0.3           | ~10x          |\n| N ~ 10⁵     | ~ 100ms          | ~ 100MB      | 0.5           | ~27x          |\n| N ~ 10⁶     | ~ 1s             | ~ 1GB        | 0.5           | ~27x          |\n| N \u003e 10⁶     | Use Dask         | Distributed  | 0.7           | N/A*          |\n\n*Dask arrays use pure Python (Numba optimizations planned for future releases)\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## Citation\n\nIf you use bhut in your research, please cite:\n\n```bibtex\n@software{bhut,\n  title={bhut: A Barnes-Hut N-body Accelerator},\n  author={Matthias Baer},\n  url={https://github.com/your-org/bhut},\n  year={2025}\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaroba%2Fbhut","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaroba%2Fbhut","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaroba%2Fbhut/lists"}