From 58ca7c09935eebcb95178ae6d79a191c8c8a6829 Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Mon, 21 Jul 2025 21:19:49 -0400 Subject: [PATCH 01/19] sphinx-quickstart --- docs/Makefile | 20 ++++++++++++++++++++ docs/make.bat | 35 +++++++++++++++++++++++++++++++++++ docs/source/conf.py | 28 ++++++++++++++++++++++++++++ docs/source/index.rst | 17 +++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 docs/Makefile create mode 100644 docs/make.bat create mode 100644 docs/source/conf.py create mode 100644 docs/source/index.rst diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..d0c3cbf1 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 00000000..747ffb7b --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..c51df65a --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,28 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'XLB' +copyright = '2025, Medyan Naser' +author = 'Medyan Naser' +release = '0.1' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [] + +templates_path = ['_templates'] +exclude_patterns = [] + + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'alabaster' +html_static_path = ['_static'] diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..b51f2801 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,17 @@ +.. XLB documentation master file, created by + sphinx-quickstart on Mon Jul 21 21:16:57 2025. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +XLB documentation +================= + +Add your content using ``reStructuredText`` syntax. See the +`reStructuredText `_ +documentation for details. + + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + From a6de29a76a50e82f7767dc628f55ce1e9b52eb96 Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Mon, 21 Jul 2025 21:55:35 -0400 Subject: [PATCH 02/19] Add basic functionality to the web page --- docs/source/conf.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index c51df65a..04cb7eac 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -14,7 +14,12 @@ # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration -extensions = [] +extensions = [ + "myst_parser", # for Markdown support + "sphinx.ext.autodoc", # for docstrings + "sphinx.ext.napoleon", # for Google-style/Numpy-style docstrings + "sphinx_book_theme", +] templates_path = ['_templates'] exclude_patterns = [] @@ -24,5 +29,19 @@ # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_theme = 'alabaster' html_static_path = ['_static'] + +html_theme = "sphinx_book_theme" +html_theme_options = { + "repository_url": "https://github.com/Autodesk/XLB.git", + "use_repository_button": True, + "use_edit_page_button": True, + "use_issues_button": True, + "use_fullscreen_button": True, +} + +extensions.append("myst_parser") +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', +} From d4908e0c2cc040568a0961b6aacdbdc59d6f54a3 Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Tue, 22 Jul 2025 20:31:27 -0400 Subject: [PATCH 03/19] Divide the docs into sub pages --- docs/source/api_reference.md | 3 + docs/source/conf.py | 4 ++ docs/source/contributing.md | 43 ++++++++++++++ docs/source/examples.md | 40 +++++++++++++ docs/source/getting_started.md | 15 +++++ docs/source/index.md | 105 +++++++++++++++++++++++++++++++++ docs/source/index.rst | 17 ------ docs/source/tutorials.md | 3 + 8 files changed, 213 insertions(+), 17 deletions(-) create mode 100644 docs/source/api_reference.md create mode 100644 docs/source/contributing.md create mode 100644 docs/source/examples.md create mode 100644 docs/source/getting_started.md create mode 100644 docs/source/index.md delete mode 100644 docs/source/index.rst create mode 100644 docs/source/tutorials.md diff --git a/docs/source/api_reference.md b/docs/source/api_reference.md new file mode 100644 index 00000000..2d50374b --- /dev/null +++ b/docs/source/api_reference.md @@ -0,0 +1,3 @@ +# API Reference + +TODO \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index 04cb7eac..6e9a889a 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -38,6 +38,8 @@ "use_edit_page_button": True, "use_issues_button": True, "use_fullscreen_button": True, + "navigation_with_keys": True, + "show_navbar_depth": 2, } extensions.append("myst_parser") @@ -45,3 +47,5 @@ '.rst': 'restructuredtext', '.md': 'markdown', } + +root_doc = 'index' diff --git a/docs/source/contributing.md b/docs/source/contributing.md new file mode 100644 index 00000000..33a6bbf0 --- /dev/null +++ b/docs/source/contributing.md @@ -0,0 +1,43 @@ +# Contributing + +## Roadmap + +### Work in Progress (WIP) +*Note: Some of the work-in-progress features can be found in the branches of the XLB repository. For contributions to these features, please reach out.* + + - 🌐 **Grid Refinement:** Implementing adaptive mesh refinement techniques for enhanced simulation accuracy. + + - πŸ’Ύ **Out-of-Core Computations:** Enabling simulations that exceed available GPU memory, suitable for CPU+GPU coherent memory models such as NVIDIA's Grace Superchips (coming soon). + + +- ⚑ **Multi-GPU Acceleration using [Neon](https://github.com/Autodesk/Neon) + Warp:** Using Neon's data structure for improved scaling. + +- πŸ—œοΈ **GPU Accelerated Lossless Compression and Decompression**: Implementing high-performance lossless compression and decompression techniques for larger-scale simulations and improved performance. + +- 🌑️ **Fluid-Thermal Simulation Capabilities:** Incorporating heat transfer and thermal effects into fluid simulations. + +- 🎯 **Adjoint-based Shape and Topology Optimization:** Implementing gradient-based optimization techniques for design optimization. + +- 🧠 **Machine Learning Accelerated Simulations:** Leveraging machine learning to speed up simulations and improve accuracy. + +- πŸ“‰ **Reduced Order Modeling using Machine Learning:** Developing data-driven reduced-order models for efficient and accurate simulations. + + +### Wishlist +*Contributions to these features are welcome. Please submit PRs for the Wishlist items.* + +- 🌊 **Free Surface Flows:** Simulating flows with free surfaces, such as water waves and droplets. + +- πŸ“‘ **Electromagnetic Wave Propagation:** Simulating the propagation of electromagnetic waves. + +- πŸ›©οΈ **Supersonic Flows:** Simulating supersonic flows. + +- 🌊🧱 **Fluid-Solid Interaction:** Modeling the interaction between fluids and solid objects. + +- 🧩 **Multiphase Flow Simulation:** Simulating flows with multiple immiscible fluids. + +- πŸ”₯ **Combustion:** Simulating combustion processes and reactive flows. + +- πŸͺ¨ **Particle Flows and Discrete Element Method:** Incorporating particle-based methods for granular and particulate flows. + +- πŸ”§ **Better Geometry Processing Pipelines:** Improving the handling and preprocessing of complex geometries for simulations. \ No newline at end of file diff --git a/docs/source/examples.md b/docs/source/examples.md new file mode 100644 index 00000000..a7924d01 --- /dev/null +++ b/docs/source/examples.md @@ -0,0 +1,40 @@ +# Examples + + +

+ +

+

+ On GPU in-situ rendering using PhantomGaze library (no I/O). Flow over a NACA airfoil using KBC Lattice Boltzmann Simulation with ~10 million cells. +

+ + +

+ +

+

+ DrivAer model in a wind-tunnel using KBC Lattice Boltzmann Simulation with approx. 317 million cells +

+ +

+ +

+

+ Airflow in to, out of, and within a building (~400 million cells) +

+ +

+ +

+

+The stages of a fluid density field from an initial state to the emergence of the "XLB" pattern through deep learning optimization at timestep 200 (see paper for details) +

+ +
+ +

+ +

+

+ Lid-driven Cavity flow at Re=100,000 (~25 million cells) +

diff --git a/docs/source/getting_started.md b/docs/source/getting_started.md new file mode 100644 index 00000000..9ac7c0aa --- /dev/null +++ b/docs/source/getting_started.md @@ -0,0 +1,15 @@ +# Getting Started +To get started with XLB, you can install it using pip: +```bash +pip install xlb +``` + +To install the latest development version from source: + +```bash +pip install git+https://github.com/Autodesk/XLB.git +``` + +The changelog for the releases can be found [here](https://github.com/Autodesk/XLB/blob/main/CHANGELOG.md). + +For examples to get you started please refer to the [examples](https://github.com/Autodesk/XLB/tree/main/examples) folder. diff --git a/docs/source/index.md b/docs/source/index.md new file mode 100644 index 00000000..273ea98c --- /dev/null +++ b/docs/source/index.md @@ -0,0 +1,105 @@ +[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +[![GitHub star chart](https://img.shields.io/github/stars/Autodesk/XLB?style=social)](https://star-history.com/#Autodesk/XLB) +

+ +

+ +# XLB: A Differentiable Massively Parallel Lattice Boltzmann Library in Python for Physics-Based Machine Learning + +πŸŽ‰ **Exciting News!** πŸŽ‰ XLB version 0.2.0 has been released, featuring a complete rewrite of the library and introducing support for the NVIDIA Warp backend! +XLB can now be installed via pip: `pip install xlb`. + +XLB is a fully differentiable 2D/3D Lattice Boltzmann Method (LBM) library that leverages hardware acceleration. It supports [JAX](https://github.com/google/jax) and [NVIDIA Warp](https://github.com/NVIDIA/warp) backends, and is specifically designed to solve fluid dynamics problems in a computationally efficient and differentiable manner. Its unique combination of features positions it as an exceptionally suitable tool for applications in physics-based machine learning. With the new Warp backend, XLB now offers state-of-the-art performance for even faster simulations. + +## Accompanying Paper + +Please refer to the [accompanying paper](https://doi.org/10.1016/j.cpc.2024.109187) for benchmarks, validation, and more details about the library. + +## Citing XLB + +If you use XLB in your research, please cite the following paper: + +``` +@article{ataei2024xlb, + title={{XLB}: A differentiable massively parallel lattice {Boltzmann} library in {Python}}, + author={Ataei, Mohammadmehdi and Salehipour, Hesam}, + journal={Computer Physics Communications}, + volume={300}, + pages={109187}, + year={2024}, + publisher={Elsevier} +} +``` + +## Key Features +- **Multiple Backend Support:** XLB now includes support for multiple backends including JAX and NVIDIA Warp, providing *state-of-the-art* performance for lattice Boltzmann simulations. Currently, only single GPU is supported for the Warp backend. +- **Integration with JAX Ecosystem:** The library can be easily integrated with JAX's robust ecosystem of machine learning libraries such as [Flax](https://github.com/google/flax), [Haiku](https://github.com/deepmind/dm-haiku), [Optax](https://github.com/deepmind/optax), and many more. +- **Differentiable LBM Kernels:** XLB provides differentiable LBM kernels that can be used in differentiable physics and deep learning applications. +- **Scalability:** XLB is capable of scaling on distributed multi-GPU systems using the JAX backend, enabling the execution of large-scale simulations on hundreds of GPUs with billions of cells. +- **Support for Various LBM Boundary Conditions and Kernels:** XLB supports several LBM boundary conditions and collision kernels. +- **User-Friendly Interface:** Written entirely in Python, XLB emphasizes a highly accessible interface that allows users to extend the library with ease and quickly set up and run new simulations. +- **Leverages JAX Array and Shardmap:** The library incorporates the new JAX array unified array type and JAX shardmap, providing users with a numpy-like interface. This allows users to focus solely on the semantics, leaving performance optimizations to the compiler. +- **Platform Versatility:** The same XLB code can be executed on a variety of platforms including multi-core CPUs, single or multi-GPU systems, TPUs, and it also supports distributed runs on multi-GPU systems or TPU Pod slices. +- **Visualization:** XLB provides a variety of visualization options including in-situ on GPU rendering using [PhantomGaze](https://github.com/loliverhennigh/PhantomGaze). + + +## Capabilities + +### LBM + +- BGK collision model (Standard LBM collision model) +- KBC collision model (unconditionally stable for flows with high Reynolds number) + +### Machine Learning + +- Easy integration with JAX's ecosystem of machine learning libraries +- Differentiable LBM kernels +- Differentiable boundary conditions + +### Lattice Models + +- D2Q9 +- D3Q19 +- D3Q27 (Must be used for KBC simulation runs) + +### Compute Capabilities +- Single GPU support for the Warp backend with state-of-the-art performance +- Distributed Multi-GPU support using the JAX backend +- Mixed-Precision support (store vs compute) +- Out-of-core support (coming soon) + +### Output + +- Binary and ASCII VTK output (based on PyVista library) +- In-situ rendering using [PhantomGaze](https://github.com/loliverhennigh/PhantomGaze) library +- [Orbax](https://github.com/google/orbax)-based distributed asynchronous checkpointing +- Image Output +- 3D mesh voxelizer using trimesh + +### Boundary conditions + +- **Equilibrium BC:** In this boundary condition, the fluid populations are assumed to be in at equilibrium. Can be used to set prescribed velocity or pressure. + +- **Full-Way Bounceback BC:** In this boundary condition, the velocity of the fluid populations is reflected back to the fluid side of the boundary, resulting in zero fluid velocity at the boundary. + +- **Half-Way Bounceback BC:** Similar to the Full-Way Bounceback BC, in this boundary condition, the velocity of the fluid populations is partially reflected back to the fluid side of the boundary, resulting in a non-zero fluid velocity at the boundary. + +- **Do Nothing BC:** In this boundary condition, the fluid populations are allowed to pass through the boundary without any reflection or modification. + +- **Zouhe BC:** This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. +- **Regularized BC:** This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. This BC is more stable than Zouhe BC, but computationally more expensive. +- **Extrapolation Outflow BC:** A type of outflow boundary condition that uses extrapolation to avoid strong wave reflections. + +- **Interpolated Bounceback BC:** Interpolated bounce-back boundary condition for representing curved boundaries. + + + +```{toctree} +:maxdepth: 2 +:caption: Contentsxs + +getting_started.md +tutorials.md +api_reference.md +contributing.md +examples.md \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst deleted file mode 100644 index b51f2801..00000000 --- a/docs/source/index.rst +++ /dev/null @@ -1,17 +0,0 @@ -.. XLB documentation master file, created by - sphinx-quickstart on Mon Jul 21 21:16:57 2025. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -XLB documentation -================= - -Add your content using ``reStructuredText`` syntax. See the -`reStructuredText `_ -documentation for details. - - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - diff --git a/docs/source/tutorials.md b/docs/source/tutorials.md new file mode 100644 index 00000000..ed8ec410 --- /dev/null +++ b/docs/source/tutorials.md @@ -0,0 +1,3 @@ +# Tutorials + +For examples to get you started please refer to the [examples](https://github.com/Autodesk/XLB/tree/main/examples) folder. \ No newline at end of file From 4d37a0ce8ec9cbbeaa2341590c3d1f8e44429382 Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Tue, 22 Jul 2025 21:37:53 -0400 Subject: [PATCH 04/19] Add logo and style sheet --- docs/source/_static/logo-transparent.png | Bin 0 -> 107210 bytes docs/source/_static/style.css | 4 + docs/source/conf.py | 30 +++-- docs/source/examples.md | 9 +- docs/source/getting_started.md | 15 --- docs/source/index.md | 105 ----------------- docs/source/index.rst | 141 +++++++++++++++++++++++ docs/source/installation.md | 36 ++++++ 8 files changed, 212 insertions(+), 128 deletions(-) create mode 100644 docs/source/_static/logo-transparent.png create mode 100644 docs/source/_static/style.css delete mode 100644 docs/source/getting_started.md delete mode 100644 docs/source/index.md create mode 100644 docs/source/index.rst create mode 100644 docs/source/installation.md diff --git a/docs/source/_static/logo-transparent.png b/docs/source/_static/logo-transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..27c8568114e725080fac17ed4c6a75dbb4a3e37c GIT binary patch literal 107210 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 literal 0 HcmV?d00001 diff --git a/docs/source/_static/style.css b/docs/source/_static/style.css new file mode 100644 index 00000000..4dd5b906 --- /dev/null +++ b/docs/source/_static/style.css @@ -0,0 +1,4 @@ +.bd-main .bd-content .bd-article-container { + max-width: none !important; + width: 100% !important; +} \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index 6e9a889a..39c7eff3 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -32,16 +32,27 @@ html_static_path = ['_static'] html_theme = "sphinx_book_theme" +# html_theme_options = { +# "repository_url": "https://github.com/Autodesk/XLB.git", +# "use_repository_button": True, +# "use_edit_page_button": True, +# "use_issues_button": True, +# "use_fullscreen_button": True, +# "navigation_with_keys": True, +# "show_navbar_depth": 2, +# } + html_theme_options = { - "repository_url": "https://github.com/Autodesk/XLB.git", - "use_repository_button": True, - "use_edit_page_button": True, - "use_issues_button": True, - "use_fullscreen_button": True, - "navigation_with_keys": True, - "show_navbar_depth": 2, + 'show_toc_level': 2, + 'repository_url': 'https://github.com/Autodesk/XLB.git', + 'use_repository_button': True, # add a "link to repository" button + 'navigation_with_keys': False, + 'article_header_start': ['toggle-primary-sidebar.html', 'breadcrumbs'], } +html_logo = '_static/logo-transparent.png' + + extensions.append("myst_parser") source_suffix = { '.rst': 'restructuredtext', @@ -49,3 +60,8 @@ } root_doc = 'index' + +html_static_path = ['_static'] + +def setup(app): + app.add_css_file('style.css') \ No newline at end of file diff --git a/docs/source/examples.md b/docs/source/examples.md index a7924d01..ef73d458 100644 --- a/docs/source/examples.md +++ b/docs/source/examples.md @@ -1,5 +1,12 @@ # Examples +

+ Wind Turbine Simulation +

+

+ Simulation of a wind turbine based on the immersed boundary method. +

+

@@ -37,4 +44,4 @@ The stages of a fluid density field from an initial state to the emergence of th

Lid-driven Cavity flow at Re=100,000 (~25 million cells) -

+

\ No newline at end of file diff --git a/docs/source/getting_started.md b/docs/source/getting_started.md deleted file mode 100644 index 9ac7c0aa..00000000 --- a/docs/source/getting_started.md +++ /dev/null @@ -1,15 +0,0 @@ -# Getting Started -To get started with XLB, you can install it using pip: -```bash -pip install xlb -``` - -To install the latest development version from source: - -```bash -pip install git+https://github.com/Autodesk/XLB.git -``` - -The changelog for the releases can be found [here](https://github.com/Autodesk/XLB/blob/main/CHANGELOG.md). - -For examples to get you started please refer to the [examples](https://github.com/Autodesk/XLB/tree/main/examples) folder. diff --git a/docs/source/index.md b/docs/source/index.md deleted file mode 100644 index 273ea98c..00000000 --- a/docs/source/index.md +++ /dev/null @@ -1,105 +0,0 @@ -[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) -[![GitHub star chart](https://img.shields.io/github/stars/Autodesk/XLB?style=social)](https://star-history.com/#Autodesk/XLB) -

- -

- -# XLB: A Differentiable Massively Parallel Lattice Boltzmann Library in Python for Physics-Based Machine Learning - -πŸŽ‰ **Exciting News!** πŸŽ‰ XLB version 0.2.0 has been released, featuring a complete rewrite of the library and introducing support for the NVIDIA Warp backend! -XLB can now be installed via pip: `pip install xlb`. - -XLB is a fully differentiable 2D/3D Lattice Boltzmann Method (LBM) library that leverages hardware acceleration. It supports [JAX](https://github.com/google/jax) and [NVIDIA Warp](https://github.com/NVIDIA/warp) backends, and is specifically designed to solve fluid dynamics problems in a computationally efficient and differentiable manner. Its unique combination of features positions it as an exceptionally suitable tool for applications in physics-based machine learning. With the new Warp backend, XLB now offers state-of-the-art performance for even faster simulations. - -## Accompanying Paper - -Please refer to the [accompanying paper](https://doi.org/10.1016/j.cpc.2024.109187) for benchmarks, validation, and more details about the library. - -## Citing XLB - -If you use XLB in your research, please cite the following paper: - -``` -@article{ataei2024xlb, - title={{XLB}: A differentiable massively parallel lattice {Boltzmann} library in {Python}}, - author={Ataei, Mohammadmehdi and Salehipour, Hesam}, - journal={Computer Physics Communications}, - volume={300}, - pages={109187}, - year={2024}, - publisher={Elsevier} -} -``` - -## Key Features -- **Multiple Backend Support:** XLB now includes support for multiple backends including JAX and NVIDIA Warp, providing *state-of-the-art* performance for lattice Boltzmann simulations. Currently, only single GPU is supported for the Warp backend. -- **Integration with JAX Ecosystem:** The library can be easily integrated with JAX's robust ecosystem of machine learning libraries such as [Flax](https://github.com/google/flax), [Haiku](https://github.com/deepmind/dm-haiku), [Optax](https://github.com/deepmind/optax), and many more. -- **Differentiable LBM Kernels:** XLB provides differentiable LBM kernels that can be used in differentiable physics and deep learning applications. -- **Scalability:** XLB is capable of scaling on distributed multi-GPU systems using the JAX backend, enabling the execution of large-scale simulations on hundreds of GPUs with billions of cells. -- **Support for Various LBM Boundary Conditions and Kernels:** XLB supports several LBM boundary conditions and collision kernels. -- **User-Friendly Interface:** Written entirely in Python, XLB emphasizes a highly accessible interface that allows users to extend the library with ease and quickly set up and run new simulations. -- **Leverages JAX Array and Shardmap:** The library incorporates the new JAX array unified array type and JAX shardmap, providing users with a numpy-like interface. This allows users to focus solely on the semantics, leaving performance optimizations to the compiler. -- **Platform Versatility:** The same XLB code can be executed on a variety of platforms including multi-core CPUs, single or multi-GPU systems, TPUs, and it also supports distributed runs on multi-GPU systems or TPU Pod slices. -- **Visualization:** XLB provides a variety of visualization options including in-situ on GPU rendering using [PhantomGaze](https://github.com/loliverhennigh/PhantomGaze). - - -## Capabilities - -### LBM - -- BGK collision model (Standard LBM collision model) -- KBC collision model (unconditionally stable for flows with high Reynolds number) - -### Machine Learning - -- Easy integration with JAX's ecosystem of machine learning libraries -- Differentiable LBM kernels -- Differentiable boundary conditions - -### Lattice Models - -- D2Q9 -- D3Q19 -- D3Q27 (Must be used for KBC simulation runs) - -### Compute Capabilities -- Single GPU support for the Warp backend with state-of-the-art performance -- Distributed Multi-GPU support using the JAX backend -- Mixed-Precision support (store vs compute) -- Out-of-core support (coming soon) - -### Output - -- Binary and ASCII VTK output (based on PyVista library) -- In-situ rendering using [PhantomGaze](https://github.com/loliverhennigh/PhantomGaze) library -- [Orbax](https://github.com/google/orbax)-based distributed asynchronous checkpointing -- Image Output -- 3D mesh voxelizer using trimesh - -### Boundary conditions - -- **Equilibrium BC:** In this boundary condition, the fluid populations are assumed to be in at equilibrium. Can be used to set prescribed velocity or pressure. - -- **Full-Way Bounceback BC:** In this boundary condition, the velocity of the fluid populations is reflected back to the fluid side of the boundary, resulting in zero fluid velocity at the boundary. - -- **Half-Way Bounceback BC:** Similar to the Full-Way Bounceback BC, in this boundary condition, the velocity of the fluid populations is partially reflected back to the fluid side of the boundary, resulting in a non-zero fluid velocity at the boundary. - -- **Do Nothing BC:** In this boundary condition, the fluid populations are allowed to pass through the boundary without any reflection or modification. - -- **Zouhe BC:** This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. -- **Regularized BC:** This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. This BC is more stable than Zouhe BC, but computationally more expensive. -- **Extrapolation Outflow BC:** A type of outflow boundary condition that uses extrapolation to avoid strong wave reflections. - -- **Interpolated Bounceback BC:** Interpolated bounce-back boundary condition for representing curved boundaries. - - - -```{toctree} -:maxdepth: 2 -:caption: Contentsxs - -getting_started.md -tutorials.md -api_reference.md -contributing.md -examples.md \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..3fd02031 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,141 @@ +.. image:: https://img.shields.io/badge/License-Apache_2.0-blue.svg + :target: https://opensource.org/licenses/Apache-2.0 + :align: left + +.. image:: https://img.shields.io/github/stars/Autodesk/XLB?style=social + :target: https://star-history.com/#Autodesk/XLB + :align: left + +.. raw:: html + +

+ +

+ +XLB: A Differentiable Massively Parallel Lattice Boltzmann Library in Python for Physics-Based Machine Learning +=============================================================================================================== + +.. raw:: html + + + + + + + +πŸŽ‰ **Exciting News!** πŸŽ‰ +XLB version 0.2.0 has been released, featuring a complete rewrite of the library and introducing support for the NVIDIA Warp backend! +XLB can now be installed via pip: `pip install xlb`. + +XLB is a fully differentiable 2D/3D Lattice Boltzmann Method (LBM) library that leverages hardware acceleration. +XLB supports `JAX `_ and `NVIDIA Warp `_ backends, +and is specifically designed to solve fluid dynamics problems in a computationally efficient and differentiable manner. +Its unique combination of features positions it as an exceptionally suitable tool for applications in physics-based machine learning. +With the new Warp backend, XLB now offers state-of-the-art performance for even faster simulations. + +Accompanying Paper +------------------ + +Please refer to the `accompanying paper `_ for benchmarks, validation, and more details. + +Citing XLB +---------- + +If you use XLB in your research, please cite: + +.. code-block:: bibtex + + @article{ataei2024xlb, + title={{XLB}: A differentiable massively parallel lattice {Boltzmann} library in {Python}}, + author={Ataei, Mohammadmehdi and Salehipour, Hesam}, + journal={Computer Physics Communications}, + volume={300}, + pages={109187}, + year={2024}, + publisher={Elsevier} + } + +Key Features +============ + +- **Multiple Backend Support:** XLB now includes support for multiple backends including JAX and NVIDIA Warp, providing *state-of-the-art* performance for lattice Boltzmann simulations. Currently, only single GPU is supported for the Warp backend. +- **Integration with JAX Ecosystem:** The library can be easily integrated with JAX's robust ecosystem of machine learning libraries such as `Flax `_, `Haiku `_, `Optax `_, and many more. +- **Differentiable LBM Kernels:** XLB provides differentiable LBM kernels that can be used in differentiable physics and deep learning applications. +- **Scalability:** XLB is capable of scaling on distributed multi-GPU systems using the JAX backend, enabling the execution of large-scale simulations on hundreds of GPUs with billions of cells. +- **Support for Various LBM Boundary Conditions and Kernels:** XLB supports several LBM boundary conditions and collision kernels. +- **User-Friendly Interface:** Written entirely in Python, XLB emphasizes a highly accessible interface that allows users to extend the library with ease and quickly set up and run new simulations. +- **Leverages JAX Array and Shardmap:** The library incorporates the new JAX array unified array type and JAX shardmap, providing users with a numpy-like interface. This allows users to focus solely on the semantics, leaving performance optimizations to the compiler. +- **Platform Versatility:** The same XLB code can be executed on a variety of platforms including multi-core CPUs, single or multi-GPU systems, TPUs, and it also supports distributed runs on multi-GPU systems or TPU Pod slices. +- **Visualization:** XLB provides a variety of visualization options including in-situ on GPU rendering using `PhantomGaze `_. + +Capabilities +============ + +LBM +--- + +- BGK collision model (Standard LBM collision model) +- KBC collision model (unconditionally stable for flows with high Reynolds number) + +Machine Learning +---------------- + +- Easy integration with JAX's ecosystem of machine learning libraries +- Differentiable LBM kernels +- Differentiable boundary conditions + +Lattice Models +-------------- + +- D2Q9 +- D3Q19 +- D3Q27 (Must be used for KBC simulation runs) + +Compute Capabilities +-------------------- + +- Single GPU support for the Warp backend with state-of-the-art performance +- Distributed Multi-GPU support using the JAX backend +- Mixed-Precision support (store vs compute) +- Out-of-core support (coming soon) + +Output +------ + +- Binary and ASCII VTK output (based on PyVista library) +- In-situ rendering using `PhantomGaze `_ library +- `Orbax `_-based distributed asynchronous checkpointing +- Image Output +- 3D mesh voxelizer using trimesh + +Boundary Conditions +------------------- + +- **Equilibrium BC:** In this boundary condition, the fluid populations are assumed to be at equilibrium. Can be used to set prescribed velocity or pressure. +- **Full-Way Bounceback BC:** The velocity of the fluid populations is reflected back to the fluid side of the boundary, resulting in zero fluid velocity at the boundary. +- **Half-Way Bounceback BC:** The velocity of the fluid populations is partially reflected back, resulting in a non-zero fluid velocity at the boundary. +- **Do Nothing BC:** The fluid populations are allowed to pass through the boundary without any reflection or modification. +- **Zouhe BC:** Used to impose a prescribed velocity or pressure profile at the boundary. +- **Regularized BC:** More stable than Zouhe BC, but computationally more expensive. +- **Extrapolation Outflow BC:** A type of outflow boundary condition that uses extrapolation to avoid strong wave reflections. +- **Interpolated Bounceback BC:** Interpolated bounce-back boundary condition for representing curved boundaries. + + +.. toctree:: + :hidden: + :maxdepth: 2 + :caption: Contents + + installation.md + tutorials.md + api_reference.md + contributing.md + examples.md diff --git a/docs/source/installation.md b/docs/source/installation.md new file mode 100644 index 00000000..6158a423 --- /dev/null +++ b/docs/source/installation.md @@ -0,0 +1,36 @@ +# Installation + +## Getting Startedd +To get started with XLB, you can install it using pip. There are different installation options depending on your hardware and needs: + +### Basic Installation (CPU-only) +```bash +pip install xlb +``` + +### Installation with CUDA support (for NVIDIA GPUs) +This installation is for the JAX backend with CUDA support: +```bash +pip install "xlb[cuda]" +``` + +### Installation with TPU support +This installation is for the JAX backend with TPU support: +```bash +pip install "xlb[tpu]" +``` + +### Notes: +- For Mac users: Use the basic CPU installation command as JAX's GPU support is not available on MacOS +- The NVIDIA Warp backend is included in all installation options and supports CUDA automatically when available +- The installation options for CUDA and TPU only affect the JAX backend + +To install the latest development version from source: + +```bash +pip install git+https://github.com/Autodesk/XLB.git +``` + +The changelog for the releases can be found [here](https://github.com/Autodesk/XLB/blob/main/CHANGELOG.md). + +For examples to get you started please refer to the [examples](https://github.com/Autodesk/XLB/tree/main/examples) folder. \ No newline at end of file From 0180c7d0ed7f826c3cdc1f84343693ee51916d34 Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Wed, 23 Jul 2025 08:02:36 -0400 Subject: [PATCH 05/19] Add API reference page --- docs/source/api_reference.md | 217 ++++++++++++++++++++++++++++++++++- 1 file changed, 215 insertions(+), 2 deletions(-) diff --git a/docs/source/api_reference.md b/docs/source/api_reference.md index 2d50374b..4da7eaca 100644 --- a/docs/source/api_reference.md +++ b/docs/source/api_reference.md @@ -1,3 +1,216 @@ -# API Reference +# XLB API Reference -TODO \ No newline at end of file +XLB is a flexible and performant lattice Boltzmann fluid solver built for multi-backend (JAX and Warp) simulation. This reference provides a structured overview of how to use the API, based on working code examples. + +--- + + +## Overview + +XLB is structured around a modular design: + +- **Velocity Sets:** e.g., `D2Q9`, `D3Q19`, `D3Q27` +- **Compute Backends:** `JAX`, `WARP` +- **Precision Policies:** Controls floating point behavior (`FP32FP32`, `FP64FP64`, etc.) +- **Grid Factory:** Creates simulation domains +- **Operators:** Include steppers, boundary conditions, macroscopic quantity extractors +- **Distribute:** JAX multi-GPU or distributed computing support + +--- + +## Simulation Pipeline + +### 1. Initialization + +```python +import xlb +from xlb.compute_backend import ComputeBackend +from xlb.precision_policy import PrecisionPolicy + +backend = ComputeBackend.JAX # or ComputeBackend.WARP +precision = PrecisionPolicy.FP32FP32 +velocity_set = xlb.velocity_set.D3Q19( + precision_policy=precision, + compute_backend=backend, +) + +xlb.init( + velocity_set=velocity_set, + default_backend=backend, + default_precision_policy=precision, +) +``` +--- + +### 2. Grid Creation +```python +from xlb.grid import grid_factory + +grid_shape = (64, 64, 64) +grid = grid_factory(grid_shape, compute_backend=backend) +``` + +### 3. Boundary Indexing +```python +box = grid.bounding_box_indices(remove_edges=True) + +inlet = box["left"] +outlet = box["right"] +walls = [box["top"][i] + box["bottom"][i] for i in range(velocity_set.d)] +``` +Use numpy.unique() or list comprehensions to merge sets. + +### 4. Boundary Conditions + +From xlb.operator.boundary_condition, supported boundary conditions include: +FullwayBounceBackBC +HalfwayBounceBackBC +RegularizedBC +ExtrapolationOutflowBC + +**Defining a Dynamic Velocity Profile** +```python +@wp.func +def profile(index: wp.vec3i): + return wp.vec(0.05, 0.0, 0.0, length=1) + +bc_inlet = RegularizedBC("velocity", profile=profile, indices=inlet) +``` +**Defining a Static Velocity** +```python +bc_wall = RegularizedBC("velocity", prescribed_value=(0.0, 0.0, 0.0), indices=walls) +``` +Combine: +```python +boundary_conditions = [bc_wall, bc_inlet, bc_outlet] +``` + + +### 5. Stepper Setup + +from xlb.operator.stepper import IncompressibleNavierStokesStepper +```python +stepper = IncompressibleNavierStokesStepper( + grid=grid, + boundary_conditions=boundary_conditions, + collision_type="BGK", # or "KBC" + force_vector=force_vector, # Optional +) +``` + +### 6. Field Preparation +```python +f_0, f_1, bc_mask, missing_mask = stepper.prepare_fields() + +from xlb.helper import initialize_eq + +f_0 = initialize_eq( + f_0, grid, velocity_set, precision, backend, u=initial_velocity +) +``` + +### 7. Running the Simulation +```python +for step in range(num_steps): + f_0, f_1 = stepper(f_0, f_1, bc_mask, missing_mask, omega, step) + f_0, f_1 = f_1, f_0 # Swap buffers + + if step % post_process_interval == 0: + post_process(step, f_0) +``` + +### 8. Post-Processing +```python +from xlb.operator.macroscopic import Macroscopic + +macro = Macroscopic( + compute_backend=backend, + precision_policy=precision, + velocity_set=velocity_set +) +rho, u = macro(f_current) +``` +Saving fields: +```python +from xlb.utils import save_image, save_fields_vtk + +save_image(u[0][:, mid_y, :], timestep=step) +save_fields_vtk({"u_x": u[0], "rho": rho[0]}, timestep=step) +``` + +## Distributing Computation +```python +from xlb.distribute import distribute + +stepper = IncompressibleNavierStokesStepper(...) +stepper = distribute(stepper, grid, velocity_set) +``` +⚠️ Note: Distributed mode requires ComputeBackend.JAX. Warp is not supported. + +## Supported Velocity Sets + +| Velocity Set | Dimensions | Use Case | +|--------------|------------|-----------------| +| D2Q9 | 2D | Benchmark cases | +| D3Q19 | 3D | General use | +| D3Q27 | 3D | High accuracy | + +**Create a velocity set:** + +```python +velocity_set = xlb.velocity_set.D3Q27(precision_policy, compute_backend) +``` + +## Backends and Precision Policies + +### Compute Backends + +- `ComputeBackend.JAX`: JAX-based backend (CPU/GPU) +- `ComputeBackend.WARP`: CUDA-accelerated backend via NVIDIA Warp + +### Precision Policies + +| Policy | Compute | Storage | +|-----------|---------|---------| +| FP32FP32 | float32 | float32 | +| FP64FP64 | float64 | float64 | + +> Use these based on hardware support and performance needs. + + +## Utilities + +- `save_image(field_slice, timestep)` + Saves 2D PNG slices of a field. + +- `save_fields_vtk(fields, timestep)` + Outputs full 3D VTK data. + +- `initialize_eq(...)` + Initializes distributions using macroscopic profiles. + +- `wp.to_jax(warp_array)` + Converts a Warp array to a JAX ndarray. + +- `vonKarman_loglaw_wall(yplus)` + Returns the analytical log-law velocity profile for wall-bounded flows. + +--- + +## Appendix: Example Presets + +### Lid-Driven Cavity + +- Uses `D2Q9` +- Regularized boundary condition for inlet +- Supports distributed setup + +### Channel Flow + +- Uses external forcing via `force_vector` +- Includes log-law analysis and DNS reference data + +### Obstacle Flow + +- Demonstrates bounce-back boundary condition on an internal obstacle +- Shows custom mask creation for complex geometries From 178e97dc1f9af732deaa817674f6bbc0f00cd772 Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Wed, 23 Jul 2025 16:43:25 -0400 Subject: [PATCH 06/19] Add yml file for ReadTheDocs --- .readthedocs.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .readthedocs.yml diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 00000000..c996ba23 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,13 @@ +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +# python: +# install: +# - requirements: docs/requirements.txt # or just requirements.txt if it's in root + +sphinx: + configuration: docs/source/conf.py # or conf.py if it's in root From 2d8c35c66c053246f77e60ce2a2c397060b9c68f Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Wed, 23 Jul 2025 16:49:32 -0400 Subject: [PATCH 07/19] Add requirements.txt --- .readthedocs.yml | 6 +++--- docs/requirements.txt | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 docs/requirements.txt diff --git a/.readthedocs.yml b/.readthedocs.yml index c996ba23..e0eec521 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -5,9 +5,9 @@ build: tools: python: "3.11" -# python: -# install: -# - requirements: docs/requirements.txt # or just requirements.txt if it's in root +python: + install: + - requirements: docs/requirements.txt # or just requirements.txt if it's in root sphinx: configuration: docs/source/conf.py # or conf.py if it's in root diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..00281ca0 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +sphinx +myst-parser \ No newline at end of file From 5b2c1ac2c82b3ed20f17da42457ab5dcc88295b9 Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Wed, 23 Jul 2025 16:51:25 -0400 Subject: [PATCH 08/19] Add to the requirements --- docs/requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 00281ca0..1e4e8314 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,2 +1,3 @@ sphinx -myst-parser \ No newline at end of file +myst-parser +sphinx_book_theme \ No newline at end of file From 38fb75e7b74c5b1905ee2aa054eafc33a3f896a1 Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Thu, 24 Jul 2025 20:59:18 -0400 Subject: [PATCH 09/19] switch to MKDocs --- docs/Makefile | 20 -- docs/{source => }/api_reference.md | 0 .../_static => assets}/logo-transparent.png | Bin docs/{source => }/contributing.md | 0 docs/{source => }/examples.md | 0 docs/index.md | 206 ++++++------------ docs/index2.md | 193 ++++++++++++++++ docs/{source => }/installation.md | 0 docs/make.bat | 35 --- docs/mkdocs.yml | 12 + docs/requirements.txt | 3 - docs/source/_static/style.css | 4 - docs/source/conf.py | 67 ------ docs/source/index.rst | 141 ------------ docs/{source => }/tutorials.md | 0 mkdocs.yml | 11 +- 16 files changed, 282 insertions(+), 410 deletions(-) delete mode 100644 docs/Makefile rename docs/{source => }/api_reference.md (100%) rename docs/{source/_static => assets}/logo-transparent.png (100%) rename docs/{source => }/contributing.md (100%) rename docs/{source => }/examples.md (100%) create mode 100644 docs/index2.md rename docs/{source => }/installation.md (100%) delete mode 100644 docs/make.bat create mode 100644 docs/mkdocs.yml delete mode 100644 docs/requirements.txt delete mode 100644 docs/source/_static/style.css delete mode 100644 docs/source/conf.py delete mode 100644 docs/source/index.rst rename docs/{source => }/tutorials.md (100%) diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index d0c3cbf1..00000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = source -BUILDDIR = build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/source/api_reference.md b/docs/api_reference.md similarity index 100% rename from docs/source/api_reference.md rename to docs/api_reference.md diff --git a/docs/source/_static/logo-transparent.png b/docs/assets/logo-transparent.png similarity index 100% rename from docs/source/_static/logo-transparent.png rename to docs/assets/logo-transparent.png diff --git a/docs/source/contributing.md b/docs/contributing.md similarity index 100% rename from docs/source/contributing.md rename to docs/contributing.md diff --git a/docs/source/examples.md b/docs/examples.md similarity index 100% rename from docs/source/examples.md rename to docs/examples.md diff --git a/docs/index.md b/docs/index.md index 5a74c0d1..c420328a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,41 +1,50 @@ -[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) -[![GitHub star chart](https://img.shields.io/github/stars/Autodesk/XLB?style=social)](https://star-history.com/#Autodesk/XLB) +![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg) +[![GitHub Stars](https://img.shields.io/github/stars/Autodesk/XLB?style=social)](https://star-history.com/#Autodesk/XLB) +

- + XLB Logo

# XLB: A Differentiable Massively Parallel Lattice Boltzmann Library in Python for Physics-Based Machine Learning -πŸŽ‰ **Exciting News!** πŸŽ‰ XLB version 0.2.0 has been released, featuring a complete rewrite of the library and introducing support for the NVIDIA Warp backend! -XLB can now be installed via pip: `pip install xlb`. + -XLB is a fully differentiable 2D/3D Lattice Boltzmann Method (LBM) library that leverages hardware acceleration. It supports [JAX](https://github.com/google/jax) and [NVIDIA Warp](https://github.com/NVIDIA/warp) backends, and is specifically designed to solve fluid dynamics problems in a computationally efficient and differentiable manner. Its unique combination of features positions it as an exceptionally suitable tool for applications in physics-based machine learning. With the new Warp backend, XLB now offers state-of-the-art performance for even faster simulations. +πŸŽ‰ **Exciting News!** +XLB version 0.2.0 has been released, featuring a complete rewrite of the library and introducing support for the NVIDIA Warp backend! +XLB can now be installed via pip: -## Getting Started -To get started with XLB, you can install it using pip: ```bash pip install xlb ``` -To install the latest development version from source: - -```bash -pip install git+https://github.com/Autodesk/XLB.git -``` +# XLB: Differentiable Lattice Boltzmann Library -The changelog for the releases can be found [here](https://github.com/Autodesk/XLB/blob/main/CHANGELOG.md). +**XLB** is a fully differentiable 2D/3D Lattice Boltzmann Method (LBM) library that leverages hardware acceleration. +XLB supports [JAX](https://github.com/google/jax) and [NVIDIA Warp](https://github.com/NVIDIA/warp) backends, +and is specifically designed to solve fluid dynamics problems in a computationally efficient and differentiable manner. +Its unique combination of features positions it as an exceptionally suitable tool for applications in physics-based machine learning. +With the new Warp backend, XLB now offers state-of-the-art performance for even faster simulations. -For examples to get you started please refer to the [examples](https://github.com/Autodesk/XLB/tree/main/examples) folder. +--- ## Accompanying Paper -Please refer to the [accompanying paper](https://doi.org/10.1016/j.cpc.2024.109187) for benchmarks, validation, and more details about the library. +Please refer to the [accompanying paper](https://doi.org/10.1016/j.cpc.2024.109187) for benchmarks, validation, and more details. + +--- ## Citing XLB -If you use XLB in your research, please cite the following paper: +If you use XLB in your research, please cite: -``` +```bibtex @article{ataei2024xlb, title={{XLB}: A differentiable massively parallel lattice {Boltzmann} library in {Python}}, author={Ataei, Mohammadmehdi and Salehipour, Hesam}, @@ -47,7 +56,8 @@ If you use XLB in your research, please cite the following paper: } ``` -## Key Features +# Key Features + - **Multiple Backend Support:** XLB now includes support for multiple backends including JAX and NVIDIA Warp, providing *state-of-the-art* performance for lattice Boltzmann simulations. Currently, only single GPU is supported for the Warp backend. - **Integration with JAX Ecosystem:** The library can be easily integrated with JAX's robust ecosystem of machine learning libraries such as [Flax](https://github.com/google/flax), [Haiku](https://github.com/deepmind/dm-haiku), [Optax](https://github.com/deepmind/optax), and many more. - **Differentiable LBM Kernels:** XLB provides differentiable LBM kernels that can be used in differentiable physics and deep learning applications. @@ -58,134 +68,56 @@ If you use XLB in your research, please cite the following paper: - **Platform Versatility:** The same XLB code can be executed on a variety of platforms including multi-core CPUs, single or multi-GPU systems, TPUs, and it also supports distributed runs on multi-GPU systems or TPU Pod slices. - **Visualization:** XLB provides a variety of visualization options including in-situ on GPU rendering using [PhantomGaze](https://github.com/loliverhennigh/PhantomGaze). -## Showcase - - -

- -

-

- On GPU in-situ rendering using PhantomGaze library (no I/O). Flow over a NACA airfoil using KBC Lattice Boltzmann Simulation with ~10 million cells. -

- - -

- -

-

- DrivAer model in a wind-tunnel using KBC Lattice Boltzmann Simulation with approx. 317 million cells -

- -

- -

-

- Airflow in to, out of, and within a building (~400 million cells) -

- -

- -

-

-The stages of a fluid density field from an initial state to the emergence of the "XLB" pattern through deep learning optimization at timestep 200 (see paper for details) -

- -
- -

- -

-

- Lid-driven Cavity flow at Re=100,000 (~25 million cells) -

- -## Capabilities - -### LBM - -- BGK collision model (Standard LBM collision model) -- KBC collision model (unconditionally stable for flows with high Reynolds number) - -### Machine Learning - -- Easy integration with JAX's ecosystem of machine learning libraries -- Differentiable LBM kernels -- Differentiable boundary conditions - -### Lattice Models - -- D2Q9 -- D3Q19 -- D3Q27 (Must be used for KBC simulation runs) - -### Compute Capabilities -- Single GPU support for the Warp backend with state-of-the-art performance -- Distributed Multi-GPU support using the JAX backend -- Mixed-Precision support (store vs compute) -- Out-of-core support (coming soon) - -### Output - -- Binary and ASCII VTK output (based on PyVista library) -- In-situ rendering using [PhantomGaze](https://github.com/loliverhennigh/PhantomGaze) library -- [Orbax](https://github.com/google/orbax)-based distributed asynchronous checkpointing -- Image Output -- 3D mesh voxelizer using trimesh - -### Boundary conditions - -- **Equilibrium BC:** In this boundary condition, the fluid populations are assumed to be in at equilibrium. Can be used to set prescribed velocity or pressure. - -- **Full-Way Bounceback BC:** In this boundary condition, the velocity of the fluid populations is reflected back to the fluid side of the boundary, resulting in zero fluid velocity at the boundary. - -- **Half-Way Bounceback BC:** Similar to the Full-Way Bounceback BC, in this boundary condition, the velocity of the fluid populations is partially reflected back to the fluid side of the boundary, resulting in a non-zero fluid velocity at the boundary. - -- **Do Nothing BC:** In this boundary condition, the fluid populations are allowed to pass through the boundary without any reflection or modification. - -- **Zouhe BC:** This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. -- **Regularized BC:** This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. This BC is more stable than Zouhe BC, but computationally more expensive. -- **Extrapolation Outflow BC:** A type of outflow boundary condition that uses extrapolation to avoid strong wave reflections. - -- **Interpolated Bounceback BC:** Interpolated bounce-back boundary condition for representing curved boundaries. - -## Roadmap - -### Work in Progress (WIP) -*Note: Some of the work-in-progress features can be found in the branches of the XLB repository. For contributions to these features, please reach out.* - - - 🌐 **Grid Refinement:** Implementing adaptive mesh refinement techniques for enhanced simulation accuracy. - - - πŸ’Ύ **Out-of-Core Computations:** Enabling simulations that exceed available GPU memory, suitable for CPU+GPU coherent memory models such as NVIDIA's Grace Superchips (coming soon). - - -- ⚑ **Multi-GPU Acceleration using [Neon](https://github.com/Autodesk/Neon) + Warp:** Using Neon's data structure for improved scaling. - -- πŸ—œοΈ **GPU Accelerated Lossless Compression and Decompression**: Implementing high-performance lossless compression and decompression techniques for larger-scale simulations and improved performance. - -- 🌑️ **Fluid-Thermal Simulation Capabilities:** Incorporating heat transfer and thermal effects into fluid simulations. +# Capabilities -- 🎯 **Adjoint-based Shape and Topology Optimization:** Implementing gradient-based optimization techniques for design optimization. +## LBM -- 🧠 **Machine Learning Accelerated Simulations:** Leveraging machine learning to speed up simulations and improve accuracy. +- **BGK collision model** – Standard LBM collision model +- **KBC collision model** – Unconditionally stable for flows with high Reynolds number -- πŸ“‰ **Reduced Order Modeling using Machine Learning:** Developing data-driven reduced-order models for efficient and accurate simulations. +## Machine Learning +- Easy integration with JAX's ecosystem of machine learning libraries +- Differentiable LBM kernels +- Differentiable boundary conditions -### Wishlist -*Contributions to these features are welcome. Please submit PRs for the Wishlist items.* +## Lattice Models -- 🌊 **Free Surface Flows:** Simulating flows with free surfaces, such as water waves and droplets. +- D2Q9 +- D3Q19 +- D3Q27 *(Must be used for KBC simulation runs)* -- πŸ“‘ **Electromagnetic Wave Propagation:** Simulating the propagation of electromagnetic waves. +## Compute Capabilities -- πŸ›©οΈ **Supersonic Flows:** Simulating supersonic flows. +- Single GPU support for the Warp backend with state-of-the-art performance +- Distributed Multi-GPU support using the JAX backend +- Mixed-Precision support (store vs compute) +- Out-of-core support *(coming soon)* -- 🌊🧱 **Fluid-Solid Interaction:** Modeling the interaction between fluids and solid objects. +## Output -- 🧩 **Multiphase Flow Simulation:** Simulating flows with multiple immiscible fluids. +- Binary and ASCII VTK output (based on PyVista library) +- In-situ rendering using [PhantomGaze](https://github.com/loliverhennigh/PhantomGaze) library +- [Orbax](https://github.com/google/orbax)-based distributed asynchronous checkpointing +- Image Output +- 3D mesh voxelizer using `trimesh` -- πŸ”₯ **Combustion:** Simulating combustion processes and reactive flows. +## Boundary Conditions -- πŸͺ¨ **Particle Flows and Discrete Element Method:** Incorporating particle-based methods for granular and particulate flows. +- **Equilibrium BC:** In this boundary condition, the fluid populations are assumed to be at equilibrium. Can be used to set prescribed velocity or pressure. +- **Full-Way Bounceback BC:** The velocity of the fluid populations is reflected back to the fluid side of the boundary, resulting in zero fluid velocity at the boundary. +- **Half-Way Bounceback BC:** The velocity of the fluid populations is partially reflected back, resulting in a non-zero fluid velocity at the boundary. +- **Do Nothing BC:** The fluid populations are allowed to pass through the boundary without any reflection or modification. +- **Zouhe BC:** Used to impose a prescribed velocity or pressure profile at the boundary. +- **Regularized BC:** More stable than Zouhe BC, but computationally more expensive. +- **Extrapolation Outflow BC:** A type of outflow boundary condition that uses extrapolation to avoid strong wave reflections. +- **Interpolated Bounceback BC:** Interpolated bounce-back boundary condition for representing curved boundaries. -- πŸ”§ **Better Geometry Processing Pipelines:** Improving the handling and preprocessing of complex geometries for simulations. + diff --git a/docs/index2.md b/docs/index2.md new file mode 100644 index 00000000..2f77faf9 --- /dev/null +++ b/docs/index2.md @@ -0,0 +1,193 @@ +[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +[![GitHub star chart](https://img.shields.io/github/stars/Autodesk/XLB?style=social)](https://star-history.com/#Autodesk/XLB) +

+ +

+ +# XLB: A Differentiable Massively Parallel Lattice Boltzmann Library in Python for Physics-Based Machine Learning + +πŸŽ‰ **Exciting News!** πŸŽ‰ XLB version 0.2.0 has been released, featuring a complete rewrite of the library and introducing support for the NVIDIA Warp backend! +XLB can now be installed via pip: `pip install xlb`. + +XLB is a fully differentiable 2D/3D Lattice Boltzmann Method (LBM) library that leverages hardware acceleration. It supports [JAX](https://github.com/google/jax) and [NVIDIA Warp](https://github.com/NVIDIA/warp) backends, and is specifically designed to solve fluid dynamics problems in a computationally efficient and differentiable manner. Its unique combination of features positions it as an exceptionally suitable tool for applications in physics-based machine learning. With the new Warp backend, XLB now offers state-of-the-art performance for even faster simulations. + +## Getting Started +To get started with XLB, you can install it using pip: +```bash +pip install xlb +``` + +To install the latest development version from source: + +```bash +pip install git+https://github.com/Autodesk/XLB.git +``` + +The changelog for the releases can be found [here](https://github.com/Autodesk/XLB/blob/main/CHANGELOG.md). + +For examples to get you started please refer to the [examples](https://github.com/Autodesk/XLB/tree/main/examples) folder. + +## Accompanying Paper + +Please refer to the [accompanying paper](https://doi.org/10.1016/j.cpc.2024.109187) for benchmarks, validation, and more details about the library. + +## Citing XLB + +If you use XLB in your research, please cite the following paper: + +``` +@article{ataei2024xlb, + title={{XLB}: A differentiable massively parallel lattice {Boltzmann} library in {Python}}, + author={Ataei, Mohammadmehdi and Salehipour, Hesam}, + journal={Computer Physics Communications}, + volume={300}, + pages={109187}, + year={2024}, + publisher={Elsevier} +} +``` + +## Key Features +- **Multiple Backend Support:** XLB now includes support for multiple backends including JAX and NVIDIA Warp, providing *state-of-the-art* performance for lattice Boltzmann simulations. Currently, only single GPU is supported for the Warp backend. +- **Integration with JAX Ecosystem:** The library can be easily integrated with JAX's robust ecosystem of machine learning libraries such as [Flax](https://github.com/google/flax), [Haiku](https://github.com/deepmind/dm-haiku), [Optax](https://github.com/deepmind/optax), and many more. +- **Differentiable LBM Kernels:** XLB provides differentiable LBM kernels that can be used in differentiable physics and deep learning applications. +- **Scalability:** XLB is capable of scaling on distributed multi-GPU systems using the JAX backend, enabling the execution of large-scale simulations on hundreds of GPUs with billions of cells. +- **Support for Various LBM Boundary Conditions and Kernels:** XLB supports several LBM boundary conditions and collision kernels. +- **User-Friendly Interface:** Written entirely in Python, XLB emphasizes a highly accessible interface that allows users to extend the library with ease and quickly set up and run new simulations. +- **Leverages JAX Array and Shardmap:** The library incorporates the new JAX array unified array type and JAX shardmap, providing users with a numpy-like interface. This allows users to focus solely on the semantics, leaving performance optimizations to the compiler. +- **Platform Versatility:** The same XLB code can be executed on a variety of platforms including multi-core CPUs, single or multi-GPU systems, TPUs, and it also supports distributed runs on multi-GPU systems or TPU Pod slices. +- **Visualization:** XLB provides a variety of visualization options including in-situ on GPU rendering using [PhantomGaze](https://github.com/loliverhennigh/PhantomGaze). + +## Showcase + + +

+ +

+

+ On GPU in-situ rendering using PhantomGaze library (no I/O). Flow over a NACA airfoil using KBC Lattice Boltzmann Simulation with ~10 million cells. +

+ + +

+ +

+

+ DrivAer model in a wind-tunnel using KBC Lattice Boltzmann Simulation with approx. 317 million cells +

+ +

+ +

+

+ Airflow in to, out of, and within a building (~400 million cells) +

+ +

+ +

+

+The stages of a fluid density field from an initial state to the emergence of the "XLB" pattern through deep learning optimization at timestep 200 (see paper for details) +

+ +
+ +

+ +

+

+ Lid-driven Cavity flow at Re=100,000 (~25 million cells) +

+ +## Capabilities + +### LBM + +- BGK collision model (Standard LBM collision model) +- KBC collision model (unconditionally stable for flows with high Reynolds number) + +### Machine Learning + +- Easy integration with JAX's ecosystem of machine learning libraries +- Differentiable LBM kernels +- Differentiable boundary conditions + +### Lattice Models + +- D2Q9 +- D3Q19 +- D3Q27 (Must be used for KBC simulation runs) + +### Compute Capabilities +- Single GPU support for the Warp backend with state-of-the-art performance +- Distributed Multi-GPU support using the JAX backend +- Mixed-Precision support (store vs compute) +- Out-of-core support (coming soon) + +### Output + +- Binary and ASCII VTK output (based on PyVista library) +- In-situ rendering using [PhantomGaze](https://github.com/loliverhennigh/PhantomGaze) library +- [Orbax](https://github.com/google/orbax)-based distributed asynchronous checkpointing +- Image Output +- 3D mesh voxelizer using trimesh + +### Boundary conditions + +- **Equilibrium BC:** In this boundary condition, the fluid populations are assumed to be in at equilibrium. Can be used to set prescribed velocity or pressure. + +- **Full-Way Bounceback BC:** In this boundary condition, the velocity of the fluid populations is reflected back to the fluid side of the boundary, resulting in zero fluid velocity at the boundary. + +- **Half-Way Bounceback BC:** Similar to the Full-Way Bounceback BC, in this boundary condition, the velocity of the fluid populations is partially reflected back to the fluid side of the boundary, resulting in a non-zero fluid velocity at the boundary. + +- **Do Nothing BC:** In this boundary condition, the fluid populations are allowed to pass through the boundary without any reflection or modification. + +- **Zouhe BC:** This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. +- **Regularized BC:** This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. This BC is more stable than Zouhe BC, but computationally more expensive. +- **Extrapolation Outflow BC:** A type of outflow boundary condition that uses extrapolation to avoid strong wave reflections. + +- **Interpolated Bounceback BC:** Interpolated bounce-back boundary condition for representing curved boundaries. + +## Roadmap + +### Work in Progress (WIP) +*Note: Some of the work-in-progress features can be found in the branches of the XLB repository. For contributions to these features, please reach out.* + + - 🌐 **Grid Refinement:** Implementing adaptive mesh refinement techniques for enhanced simulation accuracy. + + - πŸ’Ύ **Out-of-Core Computations:** Enabling simulations that exceed available GPU memory, suitable for CPU+GPU coherent memory models such as NVIDIA's Grace Superchips (coming soon). + + +- ⚑ **Multi-GPU Acceleration using [Neon](https://github.com/Autodesk/Neon) + Warp:** Using Neon's data structure for improved scaling. + +- πŸ—œοΈ **GPU Accelerated Lossless Compression and Decompression**: Implementing high-performance lossless compression and decompression techniques for larger-scale simulations and improved performance. + +- 🌑️ **Fluid-Thermal Simulation Capabilities:** Incorporating heat transfer and thermal effects into fluid simulations. + +- 🎯 **Adjoint-based Shape and Topology Optimization:** Implementing gradient-based optimization techniques for design optimization. + +- 🧠 **Machine Learning Accelerated Simulations:** Leveraging machine learning to speed up simulations and improve accuracy. + +- πŸ“‰ **Reduced Order Modeling using Machine Learning:** Developing data-driven reduced-order models for efficient and accurate simulations. + + +### Wishlist +*Contributions to these features are welcome. Please submit PRs for the Wishlist items.* + +- 🌊 **Free Surface Flows:** Simulating flows with free surfaces, such as water waves and droplets. + +- πŸ“‘ **Electromagnetic Wave Propagation:** Simulating the propagation of electromagnetic waves. + +- πŸ›©οΈ **Supersonic Flows:** Simulating supersonic flows. + +- 🌊🧱 **Fluid-Solid Interaction:** Modeling the interaction between fluids and solid objects. + +- 🧩 **Multiphase Flow Simulation:** Simulating flows with multiple immiscible fluids. + +- πŸ”₯ **Combustion:** Simulating combustion processes and reactive flows. + +- πŸͺ¨ **Particle Flows and Discrete Element Method:** Incorporating particle-based methods for granular and particulate flows. + +- πŸ”§ **Better Geometry Processing Pipelines:** Improving the handling and preprocessing of complex geometries for simulations. + +This is not wanted \ No newline at end of file diff --git a/docs/source/installation.md b/docs/installation.md similarity index 100% rename from docs/source/installation.md rename to docs/installation.md diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 747ffb7b..00000000 --- a/docs/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=source -set BUILDDIR=build - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -if "%1" == "" goto help - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml new file mode 100644 index 00000000..883adb1f --- /dev/null +++ b/docs/mkdocs.yml @@ -0,0 +1,12 @@ +site_name: XLB Documentation + +theme: + name: material # Optional but looks great + +nav: + - Home: index.md + - API Reference: api_reference.md + - Examples: examples.md + - Velocity Sets: velocity_sets.md + - Backend and Precision: backends_precision.md + - Utilities: utilities.md \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index 1e4e8314..00000000 --- a/docs/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -sphinx -myst-parser -sphinx_book_theme \ No newline at end of file diff --git a/docs/source/_static/style.css b/docs/source/_static/style.css deleted file mode 100644 index 4dd5b906..00000000 --- a/docs/source/_static/style.css +++ /dev/null @@ -1,4 +0,0 @@ -.bd-main .bd-content .bd-article-container { - max-width: none !important; - width: 100% !important; -} \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py deleted file mode 100644 index 39c7eff3..00000000 --- a/docs/source/conf.py +++ /dev/null @@ -1,67 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# For the full list of built-in configuration values, see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Project information ----------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information - -project = 'XLB' -copyright = '2025, Medyan Naser' -author = 'Medyan Naser' -release = '0.1' - -# -- General configuration --------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration - -extensions = [ - "myst_parser", # for Markdown support - "sphinx.ext.autodoc", # for docstrings - "sphinx.ext.napoleon", # for Google-style/Numpy-style docstrings - "sphinx_book_theme", -] - -templates_path = ['_templates'] -exclude_patterns = [] - - - -# -- Options for HTML output ------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output - -html_static_path = ['_static'] - -html_theme = "sphinx_book_theme" -# html_theme_options = { -# "repository_url": "https://github.com/Autodesk/XLB.git", -# "use_repository_button": True, -# "use_edit_page_button": True, -# "use_issues_button": True, -# "use_fullscreen_button": True, -# "navigation_with_keys": True, -# "show_navbar_depth": 2, -# } - -html_theme_options = { - 'show_toc_level': 2, - 'repository_url': 'https://github.com/Autodesk/XLB.git', - 'use_repository_button': True, # add a "link to repository" button - 'navigation_with_keys': False, - 'article_header_start': ['toggle-primary-sidebar.html', 'breadcrumbs'], -} - -html_logo = '_static/logo-transparent.png' - - -extensions.append("myst_parser") -source_suffix = { - '.rst': 'restructuredtext', - '.md': 'markdown', -} - -root_doc = 'index' - -html_static_path = ['_static'] - -def setup(app): - app.add_css_file('style.css') \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst deleted file mode 100644 index 3fd02031..00000000 --- a/docs/source/index.rst +++ /dev/null @@ -1,141 +0,0 @@ -.. image:: https://img.shields.io/badge/License-Apache_2.0-blue.svg - :target: https://opensource.org/licenses/Apache-2.0 - :align: left - -.. image:: https://img.shields.io/github/stars/Autodesk/XLB?style=social - :target: https://star-history.com/#Autodesk/XLB - :align: left - -.. raw:: html - -

- -

- -XLB: A Differentiable Massively Parallel Lattice Boltzmann Library in Python for Physics-Based Machine Learning -=============================================================================================================== - -.. raw:: html - - - - - - - -πŸŽ‰ **Exciting News!** πŸŽ‰ -XLB version 0.2.0 has been released, featuring a complete rewrite of the library and introducing support for the NVIDIA Warp backend! -XLB can now be installed via pip: `pip install xlb`. - -XLB is a fully differentiable 2D/3D Lattice Boltzmann Method (LBM) library that leverages hardware acceleration. -XLB supports `JAX `_ and `NVIDIA Warp `_ backends, -and is specifically designed to solve fluid dynamics problems in a computationally efficient and differentiable manner. -Its unique combination of features positions it as an exceptionally suitable tool for applications in physics-based machine learning. -With the new Warp backend, XLB now offers state-of-the-art performance for even faster simulations. - -Accompanying Paper ------------------- - -Please refer to the `accompanying paper `_ for benchmarks, validation, and more details. - -Citing XLB ----------- - -If you use XLB in your research, please cite: - -.. code-block:: bibtex - - @article{ataei2024xlb, - title={{XLB}: A differentiable massively parallel lattice {Boltzmann} library in {Python}}, - author={Ataei, Mohammadmehdi and Salehipour, Hesam}, - journal={Computer Physics Communications}, - volume={300}, - pages={109187}, - year={2024}, - publisher={Elsevier} - } - -Key Features -============ - -- **Multiple Backend Support:** XLB now includes support for multiple backends including JAX and NVIDIA Warp, providing *state-of-the-art* performance for lattice Boltzmann simulations. Currently, only single GPU is supported for the Warp backend. -- **Integration with JAX Ecosystem:** The library can be easily integrated with JAX's robust ecosystem of machine learning libraries such as `Flax `_, `Haiku `_, `Optax `_, and many more. -- **Differentiable LBM Kernels:** XLB provides differentiable LBM kernels that can be used in differentiable physics and deep learning applications. -- **Scalability:** XLB is capable of scaling on distributed multi-GPU systems using the JAX backend, enabling the execution of large-scale simulations on hundreds of GPUs with billions of cells. -- **Support for Various LBM Boundary Conditions and Kernels:** XLB supports several LBM boundary conditions and collision kernels. -- **User-Friendly Interface:** Written entirely in Python, XLB emphasizes a highly accessible interface that allows users to extend the library with ease and quickly set up and run new simulations. -- **Leverages JAX Array and Shardmap:** The library incorporates the new JAX array unified array type and JAX shardmap, providing users with a numpy-like interface. This allows users to focus solely on the semantics, leaving performance optimizations to the compiler. -- **Platform Versatility:** The same XLB code can be executed on a variety of platforms including multi-core CPUs, single or multi-GPU systems, TPUs, and it also supports distributed runs on multi-GPU systems or TPU Pod slices. -- **Visualization:** XLB provides a variety of visualization options including in-situ on GPU rendering using `PhantomGaze `_. - -Capabilities -============ - -LBM ---- - -- BGK collision model (Standard LBM collision model) -- KBC collision model (unconditionally stable for flows with high Reynolds number) - -Machine Learning ----------------- - -- Easy integration with JAX's ecosystem of machine learning libraries -- Differentiable LBM kernels -- Differentiable boundary conditions - -Lattice Models --------------- - -- D2Q9 -- D3Q19 -- D3Q27 (Must be used for KBC simulation runs) - -Compute Capabilities --------------------- - -- Single GPU support for the Warp backend with state-of-the-art performance -- Distributed Multi-GPU support using the JAX backend -- Mixed-Precision support (store vs compute) -- Out-of-core support (coming soon) - -Output ------- - -- Binary and ASCII VTK output (based on PyVista library) -- In-situ rendering using `PhantomGaze `_ library -- `Orbax `_-based distributed asynchronous checkpointing -- Image Output -- 3D mesh voxelizer using trimesh - -Boundary Conditions -------------------- - -- **Equilibrium BC:** In this boundary condition, the fluid populations are assumed to be at equilibrium. Can be used to set prescribed velocity or pressure. -- **Full-Way Bounceback BC:** The velocity of the fluid populations is reflected back to the fluid side of the boundary, resulting in zero fluid velocity at the boundary. -- **Half-Way Bounceback BC:** The velocity of the fluid populations is partially reflected back, resulting in a non-zero fluid velocity at the boundary. -- **Do Nothing BC:** The fluid populations are allowed to pass through the boundary without any reflection or modification. -- **Zouhe BC:** Used to impose a prescribed velocity or pressure profile at the boundary. -- **Regularized BC:** More stable than Zouhe BC, but computationally more expensive. -- **Extrapolation Outflow BC:** A type of outflow boundary condition that uses extrapolation to avoid strong wave reflections. -- **Interpolated Bounceback BC:** Interpolated bounce-back boundary condition for representing curved boundaries. - - -.. toctree:: - :hidden: - :maxdepth: 2 - :caption: Contents - - installation.md - tutorials.md - api_reference.md - contributing.md - examples.md diff --git a/docs/source/tutorials.md b/docs/tutorials.md similarity index 100% rename from docs/source/tutorials.md rename to docs/tutorials.md diff --git a/mkdocs.yml b/mkdocs.yml index 70af7180..bd9ec520 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -43,9 +43,9 @@ theme: name: material features: - header.autohide - logo: assets/logo.svg + logo: assets/logo-transparent.png # Favicon - favicon: assets/logo.svg + favicon: assets/logo-transparent.png # Directory containing theme customizations # custom_dir: theme_customizations/ font: @@ -147,4 +147,9 @@ extra_javascript: - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js nav: - - XLB's home: index.md \ No newline at end of file + - XLB's home: index.md + - Installation: installation.md + - API Reference: api_reference.md + - Examples: examples.md + - Contributing: contributing.md + - Tutorails: tutorials.md \ No newline at end of file From 73c5e88c2bbc3dfe68769ba92f5ce5f80ad180f7 Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Thu, 24 Jul 2025 21:41:10 -0400 Subject: [PATCH 10/19] Add missing sections --- docs/index.md | 120 ++++++++++++++++++------------------------- docs/installation.md | 2 +- 2 files changed, 52 insertions(+), 70 deletions(-) diff --git a/docs/index.md b/docs/index.md index c420328a..8446c2db 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,50 +1,41 @@ -![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg) -[![GitHub Stars](https://img.shields.io/github/stars/Autodesk/XLB?style=social)](https://star-history.com/#Autodesk/XLB) - +[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +[![GitHub star chart](https://img.shields.io/github/stars/Autodesk/XLB?style=social)](https://star-history.com/#Autodesk/XLB)

- XLB Logo +

# XLB: A Differentiable Massively Parallel Lattice Boltzmann Library in Python for Physics-Based Machine Learning - +πŸŽ‰ **Exciting News!** πŸŽ‰ XLB version 0.2.0 has been released, featuring a complete rewrite of the library and introducing support for the NVIDIA Warp backend! +XLB can now be installed via pip: `pip install xlb`. -πŸŽ‰ **Exciting News!** -XLB version 0.2.0 has been released, featuring a complete rewrite of the library and introducing support for the NVIDIA Warp backend! -XLB can now be installed via pip: +XLB is a fully differentiable 2D/3D Lattice Boltzmann Method (LBM) library that leverages hardware acceleration. It supports [JAX](https://github.com/google/jax) and [NVIDIA Warp](https://github.com/NVIDIA/warp) backends, and is specifically designed to solve fluid dynamics problems in a computationally efficient and differentiable manner. Its unique combination of features positions it as an exceptionally suitable tool for applications in physics-based machine learning. With the new Warp backend, XLB now offers state-of-the-art performance for even faster simulations. +## Getting Started +To get started with XLB, you can install it using pip: ```bash pip install xlb ``` -# XLB: Differentiable Lattice Boltzmann Library +To install the latest development version from source: -**XLB** is a fully differentiable 2D/3D Lattice Boltzmann Method (LBM) library that leverages hardware acceleration. -XLB supports [JAX](https://github.com/google/jax) and [NVIDIA Warp](https://github.com/NVIDIA/warp) backends, -and is specifically designed to solve fluid dynamics problems in a computationally efficient and differentiable manner. -Its unique combination of features positions it as an exceptionally suitable tool for applications in physics-based machine learning. -With the new Warp backend, XLB now offers state-of-the-art performance for even faster simulations. +```bash +pip install git+https://github.com/Autodesk/XLB.git +``` ---- +The changelog for the releases can be found [here](https://github.com/Autodesk/XLB/blob/main/CHANGELOG.md). -## Accompanying Paper +For examples to get you started please refer to the [examples](https://github.com/Autodesk/XLB/tree/main/examples) folder. -Please refer to the [accompanying paper](https://doi.org/10.1016/j.cpc.2024.109187) for benchmarks, validation, and more details. +## Accompanying Paper ---- +Please refer to the [accompanying paper](https://doi.org/10.1016/j.cpc.2024.109187) for benchmarks, validation, and more details about the library. ## Citing XLB -If you use XLB in your research, please cite: +If you use XLB in your research, please cite the following paper: -```bibtex +``` @article{ataei2024xlb, title={{XLB}: A differentiable massively parallel lattice {Boltzmann} library in {Python}}, author={Ataei, Mohammadmehdi and Salehipour, Hesam}, @@ -56,7 +47,7 @@ If you use XLB in your research, please cite: } ``` -# Key Features +## Key Features - **Multiple Backend Support:** XLB now includes support for multiple backends including JAX and NVIDIA Warp, providing *state-of-the-art* performance for lattice Boltzmann simulations. Currently, only single GPU is supported for the Warp backend. - **Integration with JAX Ecosystem:** The library can be easily integrated with JAX's robust ecosystem of machine learning libraries such as [Flax](https://github.com/google/flax), [Haiku](https://github.com/deepmind/dm-haiku), [Optax](https://github.com/deepmind/optax), and many more. @@ -68,56 +59,47 @@ If you use XLB in your research, please cite: - **Platform Versatility:** The same XLB code can be executed on a variety of platforms including multi-core CPUs, single or multi-GPU systems, TPUs, and it also supports distributed runs on multi-GPU systems or TPU Pod slices. - **Visualization:** XLB provides a variety of visualization options including in-situ on GPU rendering using [PhantomGaze](https://github.com/loliverhennigh/PhantomGaze). -# Capabilities - -## LBM +## Capabilities -- **BGK collision model** – Standard LBM collision model -- **KBC collision model** – Unconditionally stable for flows with high Reynolds number +### LBM -## Machine Learning +- BGK collision model (Standard LBM collision model) +- KBC collision model (unconditionally stable for flows with high Reynolds number) -- Easy integration with JAX's ecosystem of machine learning libraries -- Differentiable LBM kernels -- Differentiable boundary conditions +### Machine Learning -## Lattice Models +- Easy integration with JAX's ecosystem of machine learning libraries +- Differentiable LBM kernels +- Differentiable boundary conditions -- D2Q9 -- D3Q19 -- D3Q27 *(Must be used for KBC simulation runs)* +### Lattice Models -## Compute Capabilities +- D2Q9 +- D3Q19 +- D3Q27 (Must be used for KBC simulation runs) -- Single GPU support for the Warp backend with state-of-the-art performance -- Distributed Multi-GPU support using the JAX backend -- Mixed-Precision support (store vs compute) -- Out-of-core support *(coming soon)* +### Compute Capabilities +- Single GPU support for the Warp backend with state-of-the-art performance +- Distributed Multi-GPU support using the JAX backend +- Mixed-Precision support (store vs compute) +- Out-of-core support (coming soon) -## Output +### Output -- Binary and ASCII VTK output (based on PyVista library) -- In-situ rendering using [PhantomGaze](https://github.com/loliverhennigh/PhantomGaze) library -- [Orbax](https://github.com/google/orbax)-based distributed asynchronous checkpointing -- Image Output -- 3D mesh voxelizer using `trimesh` +- Binary and ASCII VTK output (based on PyVista library) +- In-situ rendering using [PhantomGaze](https://github.com/loliverhennigh/PhantomGaze) library +- [Orbax](https://github.com/google/orbax)-based distributed asynchronous checkpointing +- Image Output +- 3D mesh voxelizer using trimesh -## Boundary Conditions +### Boundary conditions -- **Equilibrium BC:** In this boundary condition, the fluid populations are assumed to be at equilibrium. Can be used to set prescribed velocity or pressure. -- **Full-Way Bounceback BC:** The velocity of the fluid populations is reflected back to the fluid side of the boundary, resulting in zero fluid velocity at the boundary. -- **Half-Way Bounceback BC:** The velocity of the fluid populations is partially reflected back, resulting in a non-zero fluid velocity at the boundary. -- **Do Nothing BC:** The fluid populations are allowed to pass through the boundary without any reflection or modification. -- **Zouhe BC:** Used to impose a prescribed velocity or pressure profile at the boundary. -- **Regularized BC:** More stable than Zouhe BC, but computationally more expensive. -- **Extrapolation Outflow BC:** A type of outflow boundary condition that uses extrapolation to avoid strong wave reflections. -- **Interpolated Bounceback BC:** Interpolated bounce-back boundary condition for representing curved boundaries. +- **Equilibrium BC:** In this boundary condition, the fluid populations are assumed to be in at equilibrium. Can be used to set prescribed velocity or pressure. +- **Full-Way Bounceback BC:** In this boundary condition, the velocity of the fluid populations is reflected back to the fluid side of the boundary, resulting in zero fluid velocity at the boundary. +- **Half-Way Bounceback BC:** Similar to the Full-Way Bounceback BC, in this boundary condition, the velocity of the fluid populations is partially reflected back to the fluid side of the boundary, resulting in a non-zero fluid velocity at the boundary. +- **Do Nothing BC:** In this boundary condition, the fluid populations are allowed to pass through the boundary without any reflection or modification. +- **Zouhe BC:** This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. +- **Regularized BC:** This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. This BC is more stable than Zouhe BC, but computationally more expensive. +- **Extrapolation Outflow BC:** A type of outflow boundary condition that uses extrapolation to avoid strong wave reflections. +- **Interpolated Bounceback BC:** Interpolated bounce-back boundary condition for representing curved boundaries. - diff --git a/docs/installation.md b/docs/installation.md index 6158a423..0a43568f 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,6 +1,6 @@ # Installation -## Getting Startedd +## Getting Started To get started with XLB, you can install it using pip. There are different installation options depending on your hardware and needs: ### Basic Installation (CPU-only) From 9cbaf220c475fca10e046b28089c821f7e3e75dc Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Sun, 27 Jul 2025 18:26:09 -0400 Subject: [PATCH 11/19] Add constants page --- docs/constants.md | 109 ++++++++++++++++++++++++++++++++++++++++++++++ docs/operator.md | 62 ++++++++++++++++++++++++++ mkdocs.yml | 15 ++++--- 3 files changed, 181 insertions(+), 5 deletions(-) create mode 100644 docs/constants.md create mode 100644 docs/operator.md diff --git a/docs/constants.md b/docs/constants.md new file mode 100644 index 00000000..933e4e05 --- /dev/null +++ b/docs/constants.md @@ -0,0 +1,109 @@ +# πŸ“˜ Constants and Enums + +This page documents the core enums and configuration constants used throughout the codebase. These constants define important fixed values such as compute backends, grid strategies, physics models, and precision policies used in simulations. + + + +## πŸ”§ Compute Backends + +Defined in compute_backend.py + +```python +class ComputeBackend(Enum): + JAX = auto() + WARP = auto() +``` +Description: + +Specifies the available compute engines: + +- **JAX**: Uses JAX for GPU/TPU accelerated computation. +- **WARP**: Uses NVIDIA Warp for GPU-based simulation. + +## 🧱 Grid Backends + +Defined in grid_backend.py +```python +class GridBackend(Enum): + JAX = auto() + WARP = auto() + OOC = auto() +``` + +Description: + +Represents the grid computation backend: + +- **JAX, WARP** (same as above) +- **OOC**: Out-of-core grid handling (e.g., large datasets or disk-based grids). + +## 🌊 Physics Types + +Defined in physics_type.py +```python +class PhysicsType(Enum): + NSE = auto() # Navier-Stokes Equations + ADE = auto() # Advection-Diffusion Equations +``` + +Description: + +Defines the physical equations the system can solve: + +- **NSE**: Fluid dynamics using Navier-Stokes. +- **ADE**: Transport processes using Advection-Diffusion. + + +## 🎯 Precision Enum + +Defined in precision_policy.py +```python +class Precision(Enum): + FP64, FP32, FP16, UINT8, BOOL +``` + +Description: + +Represents data precision levels. Each precision level maps to both JAX and WARP data types via properties: + +- Precision.wp_dtype β†’ Warp data type +- Precision.jax_dtype β†’ JAX data type + + + +## βš™οΈ PrecisionPolicy Enum + +```python +class PrecisionPolicy(Enum): + FP64FP64, FP64FP32, FP64FP16, FP32FP32, FP32FP16 +``` + +Description: + +Controls how data is computed vs stored: + +- **FP64FP32** means compute in float64, store in float32 +Utility methods: +- **.compute_precision**: Returns compute-side precision +- **.store_precision**: Returns storage-side precision +- **.cast_to_compute_jax(array)**: Casts to compute dtype +- **.cast_to_store_jax(array)**: Casts to store dtype + + + +## βš™οΈ Default Configuration + +Defined in default_config.py + +```python +@dataclass +class DefaultConfig: + velocity_set + default_backend + default_precision_policy +``` +Set globally using: +```python +init(velocity_set, backend, precision_policy) +``` +This is used to initialize system-wide simulation behavior based on chosen backends and numerical settings. \ No newline at end of file diff --git a/docs/operator.md b/docs/operator.md new file mode 100644 index 00000000..0be2f30b --- /dev/null +++ b/docs/operator.md @@ -0,0 +1,62 @@ +# Operator + +Base class for all operators, including collision, streaming, equilibrium, etc. +Responsible for handling compute backends like JAX and NVIDIA Warp. + +## Overview + +The `Operator` class acts as the foundational interface for all lattice Boltzmann operators in XLB. It manages backend selection and provides a unified API to call backend-specific implementations transparently. It also facilitates registering backend implementations and handles precision policies and compute types. + +## Usage + +```python +from xlb.operator import Operator +from xlb.compute_backend import ComputeBackend +from xlb.precision_policy import PrecisionPolicy + +op = Operator( + velocity_set=None, # or specify velocity set + precision_policy=PrecisionPolicy.FP32FP32, + compute_backend=ComputeBackend.JAX, +) + +# Call the operator (calls backend-specific implementation) +result = op(some_input_data) +``` + +## Constructor + +```python +Operator( + velocity_set=None, + precision_policy=None, + compute_backend=None +) +``` + +- velocity_set: (optional) Velocity set used by the operator; defaults to global config. +- precision_policy: (optional) Precision policy for compute and storage. +- compute_backend: (optional) Backend to run on (e.g., JAX or Warp). + +Raises `ValueError` if the specified backend is unsupported. + +## Methods and Properties + +`register_backend(backend_name)` +Decorator to register backend implementations for subclasses. + +`__call__(*args, callback=None, **kwargs)` +Calls the appropriate backend method, matching the subclass and backend, and passes args/kwargs. +- callback (optional): Callable to be called with the result. + +`supported_compute_backend` +Returns a list of supported backend keys registered for this operator. + +`backend` +Returns the actual backend module (jax.numpy or warp), depending on the current backend. + +`compute_dtype` +Returns the compute data type (e.g., float32, float64) according to the precision policy and backend. + +`store_dtype` +Returns the storage data type according to the precision policy and backend. \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index bd9ec520..4f051059 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -41,6 +41,7 @@ site_description: 'Documentation for project XLB' theme: # Name of the theme name: material + highlight_theme: default features: - header.autohide logo: assets/logo-transparent.png @@ -76,8 +77,6 @@ markdown_extensions: - admonition - codehilite - smarty - - pymdownx.superfences - - pymdownx.highlight - markdown.extensions.attr_list - markdown.extensions.def_list - markdown.extensions.fenced_code @@ -87,15 +86,15 @@ markdown_extensions: - pymdownx.arithmatex: generic: true - attr_list - - pymdownx.superfences - pymdownx.highlight: use_pygments: true linenums: true anchor_linenums: true linenums_style: table - pymdownx.snippets - - pymdownx.highlight - pymdownx.inlinehilite + - pymdownx.superfences + - toc # MkDocs supports plugins written in Python to extend the functionality of the site # This parameter contains a list of the MkDocs plugins to add to the site @@ -152,4 +151,10 @@ nav: - API Reference: api_reference.md - Examples: examples.md - Contributing: contributing.md - - Tutorails: tutorials.md \ No newline at end of file + - Tutorails: tutorials.md + - Operator: operator.md + - Constants: constants.md + # - BC: BC.md + # - streaming_and_collision: streaming_and_collision.md + # - grid: grid.md + # - common steps: common_steps.md \ No newline at end of file From fafdde3b35dffe4c6fbab32d03d340b23337db48 Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Tue, 29 Jul 2025 20:04:13 -0400 Subject: [PATCH 12/19] Add docs page for Grid --- docs/common_steps.md | 55 ++++++++++++++++++++++++++++++++ docs/grid.md | 75 ++++++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 4 +-- 3 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 docs/common_steps.md create mode 100644 docs/grid.md diff --git a/docs/common_steps.md b/docs/common_steps.md new file mode 100644 index 00000000..6b514fa1 --- /dev/null +++ b/docs/common_steps.md @@ -0,0 +1,55 @@ +# πŸ” Common Flow / Required Steps Across All Examples + +## **Step 1: Import and Configure Environment** +- Import `xlb` components. +- Define backend (`WARP` or `JAX`) and precision policy. +- Choose appropriate `velocity_set` based on simulation type (2D or 3D). + +## **Step 2: Initialize XLB** +```python +xlb.init(velocity_set, default_backend, default_precision_policy) +``` + +## **Step 3: Define the Simulation Grid** +```python +grid = grid_factory(grid_shape, compute_backend) +``` + +## **Step 4: Define Boundary Indices** +```python +box = grid.bounding_box_indices() +walls = ... +``` + +## **Step 5: Setup Boundary Conditions** +```python +bc_wall = FullwayBounceBackBC(...) +bc_inlet = RegularizedBC(...) +boundary_conditions = [bc_wall, bc_inlet, ...] +``` + +## **Step 6: Setup Stepper** +```python +stepper = IncompressibleNavierStokesStepper(grid, boundary_conditions, ...) +f_0, f_1, bc_mask, missing_mask = stepper.prepare_fields() +``` + +## **Step 7 (Optional): Initialize Fields** +```python +f_0 = initialize_eq(f_0, grid, velocity_set, precision_policy, compute_backend, u=u_init) +``` + +## **Step 8: Post-processing Setup** +```python +Instantiate Macroscopic. +Write custom post_process functions. +``` + +## **Step 9: Run Simulation Loop** +```python +for step in range(num_steps): + f_0, f_1 = stepper(f_0, f_1, bc_mask, missing_mask, omega, step) + f_0, f_1 = f_1, f_0 # Swap buffers + if step % interval == 0: + post_process(...) +``` \ No newline at end of file diff --git a/docs/grid.md b/docs/grid.md new file mode 100644 index 00000000..407c2ee5 --- /dev/null +++ b/docs/grid.md @@ -0,0 +1,75 @@ +# Grid + +The `xlb.grid` module provides utilities to define and manage structured grids for Lattice Boltzmann (LBM) simulations. A grid defines the spatial layout of your simulation domain and is tightly integrated with the selected compute backend (JAX or Warp). + +## Quick start + +```python +from xlb.grid import grid_factory +from xlb.compute_backend import ComputeBackend +import xlb + +# (Usually already done once in your program) +xlb.init(...) + +# Create a 3D grid on Warp +grid = grid_factory((256, 128, 128), compute_backend=ComputeBackend.WARP) + +# Create a distribution field with cardinality = velocity_set.d +f = grid.create_field(cardinality=19) # e.g., D3Q19 + +# Get boundary indices to build BCs +faces = grid.bounding_box_indices(remove_edges=True) +left, right = faces["left"], faces["right"] + +``` + +## **Parameters** + +- `shape: Tuple[int, ...]` β€” `(nx, ny)` for 2D or `(nx, ny, nz)` for 3D. +- `compute_backend: ComputeBackend` β€” `ComputeBackend.JAX` or `ComputeBackend.WARP`. + +## **Attributes** + +- `grid.shape` : The full domain shape you passed in. +- `grid.dim` : 2 or 3, inferred from `shape`. + +## **Functions** + +- `grid_factory(shape, compute_backend=None)` : Returns a `JaxGrid` or `WarpGrid` based on the backend. + +- `grid.bounding_box_indices(remove_edges: bool = False) -> dict[str, list[list[int]]]`: + - Returns integer indices for each boundary face. + - Keys for 2D: `bottom`, `top`, `left`, `right` + - Keys for 3D: `bottom`, `top`, `left`, `right`, `front`, `back` + - `remove_edges=True` : removes edge/corner nodes (useful to avoid double-applying BCs). + +Example +```python +faces = grid.bounding_box_indices(remove_edges=True) +inlet = faces["left"] +outlet = faces["right"] +walls = (faces["bottom"][0] + faces["top"][0]) # merge faces per-dimension +``` + + +- `grid.create_field(cardinality: int, dtype: Precision = None, fill_value: float = None) -> array`: + - Creates a field over the grid for storing simulation data. + - `cardinality`: number of values per grid cell + - 1 β†’ scalar field (e.g., density, pressure) + - 2/3 β†’ vector field (e.g., velocity components) + - `dtype`: precision (FP32, FP64, FP16, BOOL). Defaults to config. + - `BOOL` is only supported with **JaxGrid** + - `fill_value`: initialize with constant; defaults to 0. + + + +## **JAX-specific:** `JaxGrid` +`JaxGrid` is designed for multi-device setups. + + +## **Warp-specific:** `WarpGrid` +`WarpGrid` targets single GPU with NVIDIA Warp. + +- For 2D grids, a singleton `z` dimension is automatically added to keep kernels consistent. + diff --git a/mkdocs.yml b/mkdocs.yml index 4f051059..a6a7b048 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -156,5 +156,5 @@ nav: - Constants: constants.md # - BC: BC.md # - streaming_and_collision: streaming_and_collision.md - # - grid: grid.md - # - common steps: common_steps.md \ No newline at end of file + - grid: grid.md + - common steps: common_steps.md \ No newline at end of file From 62761747c53e422aef211d46049dad50122d03dd Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Tue, 29 Jul 2025 20:53:15 -0400 Subject: [PATCH 13/19] Add docs page for Boundary Conditions --- docs/BC.md | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 12 ++-- 2 files changed, 181 insertions(+), 6 deletions(-) create mode 100644 docs/BC.md diff --git a/docs/BC.md b/docs/BC.md new file mode 100644 index 00000000..efd5b577 --- /dev/null +++ b/docs/BC.md @@ -0,0 +1,175 @@ +# BoundaryCondition (Base Class) + +The `BoundaryCondition` class is the base class for implementing all boundary conditions in Lattice Boltzmann Method (LBM) simulations. +It extends the generic `Operator` class and provides the foundational structure for applying boundary logic in different simulation stages. + +## πŸ“Œ Purpose + +In LBM simulations, boundary conditions (BCs) define how the simulation behaves at domain edges β€” walls, inlets, outlets, etc. +`BoundaryCondition` provides: + +- A uniform interface for implementing BCs +- GPU/TPU-compatible kernels using **JAX** or **Warp** +- Support for auxiliary data (e.g., prescribed velocities) +- Integration with velocity sets, precision policy, and compute backends + + + +## 🧩 Key Parameters + +| Argument | Description | +|--------------------|---------------------------------------------------------------------| +| `implementation_step` | When the BC is applied: `COLLISION` or `STREAMING` | +| `velocity_set` | Type of LBM velocity set (optional, uses default if not provided) | +| `precision_policy` | Controls numerical precision (optional) | +| `compute_backend` | Either `JAX` or `WARP` (optional) | +| `indices` | Grid indices where the BC applies | +| `mesh_vertices` | Optional mesh information for mesh-aware BCs | + + + + + + + +--- + +## 🚧 **Boundary Condition Subclasses** + +## 1. DoNothingBC + +The `DoNothingBC` class implements no operation boundary condition that effectively skips streaming step at boundary nodes, leaving distributions unchanged. + +- **Step:** Streaming +- **Backend:** JAX, Warp +- **Notes:** Useful for test cases or special boundary handling. + +--- + +## 2. EquilibriumBC + +The `EquilibriumBC` class implements a boundary condition that enforces the distribution functions to be at their equilibrium state for prescribed density and velocity values. + +- **Step:** Streaming +- **Backend:** JAX, Warp +- **Notes:** Constructor requires macroscopic density (`rho`) and velocity (`u`) values + +--- + +## 3. ExtrapolationOutflowBC + +The `ExtrapolationOutflowBC` class implements an extrapolation-based outflow boundary condition to reduce wave reflections at simulation domain exits. + +- **Step:** Streaming +- **Backend:** JAX, Warp +- **Notes:** + +--- + +## 4. FullwayBounceBackBC + +The `FullwayBounceBackBC` class implements the classic full bounce-back boundary condition, reflecting distribution functions at boundaries. + +- **Step:** Collision +- **Backend:** JAX, Warp +- **Notes:** Enforces no-slip wall conditions by reversing particle distributions at the boundary during the collision step. + +--- + +## 5. GradsApproximationBC + +The `GradsApproximationBC` class implements boundary conditions using Grad’s approximation to reconstruct missing distribution functions based on macroscopic moments. + +- **Step:** Streaming +- **Backend:** Warp +- **Notes:** Requires 3D velocity sets (not implemented in 2D) +--- + +## 6. HalfwayBounceBackBC + +The `HalfwayBounceBackBC` class implements the halfway bounce-back boundary condition, a popular variant of the bounce-back method used in LBM simulations. + +- **Step:** Streaming +- **Backend:** JAX, Warp +- **Notes:** Enforces no-slip conditions by reflecting distribution functions halfway between fluid and boundary nodes, improving accuracy over fullway bounce-back. +--- + +## 7. ZouHeBC + +The `ZouHeBC` class implements the classical Zou-He boundary condition for prescribed velocity or pressure boundaries using non-equilibrium bounce-back. + +- **Step:** Streaming +- **Backend:** JAX, Warp +- **Notes:** Supports only normal velocity components (only one non-zero velocity element allowed) + + +--- + +## 8. RegularizedBC + +The `RegularizedBC` class extends the `ZouHeBC` to implement a regularized boundary condition incorporating a non-equilibrium bounce-back with additional second-moment corrections. + +- **Step:** Streaming +- **Backend:** JAX, Warp +- **Notes:** + +--- + +## Summary Table of Boundary Conditions + +| BC Class | Purpose | Implementation Step | Supports Auxiliary Data | Backend Support | +|------------------------|------------------------------------------------------|---------------------|------------------------|-----------------------| +| `DoNothingBC` | Leaves boundary distributions unchanged (no-op) | STREAMING | No |JAX, Warp | +| `EquilibriumBC` | Prescribe equilibrium populations | STREAMING | No | JAX, Warp | +| `ExtrapolationOutflowBC`| Smooth outflow via extrapolation | STREAMING | Yes | JAX, Warp | +| `FullwayBounceBackBC` | Classic bounce-back (no-slip) | COLLISION | No | JAX, Warp | +| `GradsApproximationBC` | Approximate missing populations via Grad's method | STREAMING | No | Warp only | +| `HalfwayBounceBackBC` | Halfway bounce-back for no-slip walls | STREAMING | No | JAX, Warp | +| `ZouHeBC` | Classical Zou-He velocity/pressure BC with non-equilibrium bounce-back | STREAMING | Yes |JAX, Warp | +| `RegularizedBC` | Non-equilibrium bounce-back with second moment regularization | STREAMING | No | JAX, Warp | diff --git a/mkdocs.yml b/mkdocs.yml index a6a7b048..e4b67dda 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -148,13 +148,13 @@ extra_javascript: nav: - XLB's home: index.md - Installation: installation.md - - API Reference: api_reference.md - - Examples: examples.md - - Contributing: contributing.md - Tutorails: tutorials.md - Operator: operator.md - Constants: constants.md - # - BC: BC.md + - Boundary Condition: BC.md + - Grid: grid.md + - Common Steps: common_steps.md # - streaming_and_collision: streaming_and_collision.md - - grid: grid.md - - common steps: common_steps.md \ No newline at end of file + # - API Reference: api_reference.md + - Examples: examples.md + - Contributing: contributing.md \ No newline at end of file From 681e2b42445e7efbdb8c99e3aab9839bcf638985 Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Tue, 29 Jul 2025 22:20:26 -0400 Subject: [PATCH 14/19] Add docs page for macroscopic, stream, and collision --- docs/macroscopic.md | 33 +++++++++ docs/stepper.md | 56 +++++++++++++++ docs/streaming_and_collision.md | 117 ++++++++++++++++++++++++++++++++ mkdocs.yml | 6 +- 4 files changed, 210 insertions(+), 2 deletions(-) create mode 100644 docs/macroscopic.md create mode 100644 docs/stepper.md create mode 100644 docs/streaming_and_collision.md diff --git a/docs/macroscopic.md b/docs/macroscopic.md new file mode 100644 index 00000000..2aaaeb75 --- /dev/null +++ b/docs/macroscopic.md @@ -0,0 +1,33 @@ +# Moments in LBM + +In the Lattice Boltzmann Method (LBM), the fluid is represented not directly by macroscopic variables (density, velocity, pressure) but by a set of distribution functions f. + +These distribution functions describe the probability of particles moving in certain discrete directions on the lattice. + +Computes fluid density (`ρ`) and velocity (`u`) from the distribution field `f`. + +## Methods + +`macroscopic(f) -> (rho, u)` + +- overview: compute macroscopic fields from the distribution. + +*Parameters* + +- `f`: distribution field created with grid.create_field(velocity_set.d) + +*Returns* + +- rho: scalar density field, shape (1, *grid.shape) +- u: velocity vector field, shape (dim, *grid.shape) + +Example: + +```python +from xlb.operator.macroscopic.macroscopic import Macroscopic + +# Assume f is a distribution field on the grid +macroscopic = Macroscopic(velocity_set=my_velocity_set) + +rho, u = macroscopic(f) +``` \ No newline at end of file diff --git a/docs/stepper.md b/docs/stepper.md new file mode 100644 index 00000000..f22320a3 --- /dev/null +++ b/docs/stepper.md @@ -0,0 +1,56 @@ +# Stepper + +The `Stepper` orchestrates the time-stepping of Lattice Boltzmann simulations. +It ties together streaming, collision, macroscopic updates, and boundary conditions. + +A stepper advances the simulation forward by one time step. It orchestrates the sequence of operations: + +1. **Streaming** β†’ particles move along lattice directions. +2. **Boundary conditions** β†’ enforce walls, inlets, outlets, etc. +3. **Macroscopic update** β†’ compute density (ρ) and velocity (u). +4. **Equilibrium calculation** β†’ build the equilibrium distribution (f_eq). +5. **Collision** β†’ relax distributions toward equilibrium. + + +## IncompressibleNavierStokesStepper +A ready-to-use stepper for solving the incompressible Navier–Stokes equations with LBM. + +**Functions** + +`prepare_fields(initializer=None) -> (f0, f1, bc_mask, missing_mask)` + +- Allocates and initializes the distribution fields and boundary condition masks. +- `initializer`: optional operator for custom initialization (otherwise uses default equilibrium with ρ=1, u=0). + +Returns: + +- `f0`: distribution field at the start of the step +- `f1`: buffer for the next step (double-buffering) +- `bc_mask`: IDs indicating which boundary condition applies at each node +- `missing_mask`: marks which populations are missing at boundary nodes + +**Constructor** +```python +IncompressibleNavierStokesStepper( + grid, + boundary_conditions=[], + collision_type="BGK", + forcing_scheme="exact_difference", + force_vector=None, +) +``` + +**Example** +```python +# Create a 3D grid +grid = grid_factory((64, 64, 64), compute_backend=ComputeBackend.JAX) + +# Create stepper with BGK collision +stepper = IncompressibleNavierStokesStepper(grid, boundary_conditions=my_bcs) + +# Prepare fields +f0, f1, bc_mask, missing_mask = stepper.prepare_fields() + +# Advance one step +f0, f1 = stepper(f0, f1, bc_mask, missing_mask, omega=1.0, timestep=0) +``` \ No newline at end of file diff --git a/docs/streaming_and_collision.md b/docs/streaming_and_collision.md new file mode 100644 index 00000000..a4a919ce --- /dev/null +++ b/docs/streaming_and_collision.md @@ -0,0 +1,117 @@ +# πŸ”„ StreamingOperator & CollisionOperator + +In Lattice Boltzmann Method (LBM) simulations, the two core steps are **Streaming** and **Collision**. These operations define how distribution functions move across the grid and how they interact locally. + +The following operators abstract these steps: + +- `Stream`: handles propagation (pull-based streaming) +- `Collision`: handles local distribution interactions (e.g., BGK) + +--- + +## πŸš€ Stream (Base Class) + +The `Stream` operator performs the **streaming step** by pulling values from neighboring grid points, depending on the velocity set. + +### πŸ“Œ Purpose + +- Implements the **pull scheme** of LBM streaming. +- Ensures support for both 2D and 3D simulations. +- Compatible with **JAX** and **Warp** backends. + +### 🧩 Key Properties + +| Property | Description | +|------------------------|-----------------------------------------------------------| +| `implementation_step` | `STREAMING` | +| `backend_support` | JAX and Warp | +| `supports_auxiliary_data` | ❌ No | + +### βš™οΈ JAX Implementation + +```python +@jit +def jax_implementation(self, f): + def _streaming_jax_i(f, c): + return jnp.roll(f, (c[0], c[1]), axis=(0, 1)) # for 2D + + return vmap(_streaming_jax_i, in_axes=(0, 0), out_axes=0)(f, jnp.array(self.velocity_set.c).T) +``` + +This uses jax.numpy.roll to shift distributions in each velocity direction. + +## βš™οΈ Warp Implementation + +```python +@wp.kernel +def kernel(f_0, f_1): + index = wp.vec3i(i, j, k) + _f = functional(f_0, index) + f_1[...] = _f +``` +Warp handles periodic boundary corrections and shift indexing manually within the kernel for 3D arrays. + +## πŸ’₯ Collision (Base Class) + +The `Collision` operator defines how particles interact locally after streaming, typically by relaxing towards equilibrium. + +### πŸ“Œ Purpose + +- Base class for implementing collision models. +- Uses distribution function `f`, equilibrium `feq`, and local properties (`rho`, `u`, etc.). +- Meant to be subclassed (e.g., for `BGK`). + +## 🧩 Key Properties + +| Property | Description | +|------------------------|----------------------------------| +| `implementation_step` | `COLLISION` | +| `backend_support` | JAX and Warp | +| `supports_auxiliary_data` | βœ… Yes (e.g., `omega`) | + +## πŸ§ͺ BGK: A Subclass of Collision + +**BGK** (Bhatnagar–Gross–Krook) is a common collision model where the post-collision distribution is calculated by relaxing toward equilibrium. + +### βš™οΈ JAX Implementation + +```python +@jit +def jax_implementation(self, f, feq, rho, u, omega): + fneq = f - feq + return f - self.compute_dtype(omega) * fneq +``` + + +### βš™οΈ Warp Implementation + +```python +@wp.func +def functional(f, feq, rho, u, omega): + fneq = f - feq + return f - dtype(omega) * fneq +``` +The Warp kernel loads and stores distribution values per node and performs the same BGK operation element-wise. + +### πŸ›  Backend Support Summary + +| Operator | JAX Support | Warp Support | Streaming | Collision | Supports Aux Data | +|------------|-------------|--------------|-----------|-----------|------------------------| +| Stream | βœ… Yes | βœ… Yes | βœ… Yes | ❌ No | ❌ No | +| Collision | βœ… Yes | βœ… Yes | ❌ No | βœ… Yes | βœ… Yes | +| BGK | βœ… Yes | βœ… Yes | ❌ No | βœ… Yes | βœ… Yes (omega) | +| ForcedCollision | βœ… Yes | βœ… Yes | ❌ No | βœ… Yes | βœ… Yes (force vector) | +| KBC | βœ… Yes | βœ… Yes | ❌ No | βœ… Yes | βœ… Yes | + +--- + +### πŸ—‚ Registry + +All operator subclasses are registered via the Operator base class using decorators: + +```python +@Operator.register_backend(ComputeBackend.JAX) +def jax_implementation(...) +``` + +This allows dynamic backend dispatch at runtime. \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index e4b67dda..fed38522 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -148,13 +148,15 @@ extra_javascript: nav: - XLB's home: index.md - Installation: installation.md - - Tutorails: tutorials.md + # - Tutorails: tutorials.md - Operator: operator.md - Constants: constants.md - Boundary Condition: BC.md - Grid: grid.md + - Macroscopic: macroscopic.md + - Stepper: stepper.md - Common Steps: common_steps.md - # - streaming_and_collision: streaming_and_collision.md + - Streaming and Collision: streaming_and_collision.md # - API Reference: api_reference.md - Examples: examples.md - Contributing: contributing.md \ No newline at end of file From 496f0682df99fb30e350d581a9e1bee3560d8a37 Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Thu, 31 Jul 2025 18:58:15 -0400 Subject: [PATCH 15/19] structure the mkdocs pages --- docs/BC.md | 95 ++++++++++----------------------------------------- docs/index.md | 12 ------- mkdocs.yml | 19 ++++++----- 3 files changed, 28 insertions(+), 98 deletions(-) diff --git a/docs/BC.md b/docs/BC.md index efd5b577..fe749e09 100644 --- a/docs/BC.md +++ b/docs/BC.md @@ -82,84 +82,25 @@ This BC effectively does nothing to the boundary values β€” useful for debugging ## 🚧 **Boundary Condition Subclasses** -## 1. DoNothingBC +1. **DoNothingBC**: +In this boundary condition, the fluid populations are allowed to pass through the boundary without any reflection or modification. Useful for test cases or special boundary handling. +2. **EquilibriumBC**: +In this boundary condition, the fluid populations are assumed to be in at equilibrium. Constructor has optional macroscopic density (`rho`) and velocity (`u`) values +3. **FullwayBounceBackBC**: +In this boundary condition, the velocity of the fluid populations is reflected back to the fluid side of the boundary, resulting in zero fluid velocity at the boundary. Enforces no-slip wall conditions by reversing particle distributions at the boundary during the collision step. +4. **HalfwayBounceBackBC**: +Similar to the `FullwayBounceBackBC`, in this boundary condition, the velocity of the fluid populations is partially reflected back to the fluid side of the boundary, resulting in a non-zero fluid velocity at the boundary. Enforces no-slip conditions by reflecting distribution functions halfway between fluid and boundary nodes, improving accuracy over fullway bounce-back. +5. **ZouHeBC**: +This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. Supports only normal velocity components (only one non-zero velocity element allowed) +6. **RegularizedBC**: +This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. This BC is more stable than `ZouHeBC`, but computationally more expensive. +7. **ExtrapolationOutflowBC**: +A type of outflow boundary condition that uses extrapolation to avoid strong wave reflections. +8. **GradsApproximationBC**: +Interpolated bounce-back boundary condition for representing curved boundaries. Requires 3D velocity sets (not implemented in 2D) -The `DoNothingBC` class implements no operation boundary condition that effectively skips streaming step at boundary nodes, leaving distributions unchanged. -- **Step:** Streaming -- **Backend:** JAX, Warp -- **Notes:** Useful for test cases or special boundary handling. ---- - -## 2. EquilibriumBC - -The `EquilibriumBC` class implements a boundary condition that enforces the distribution functions to be at their equilibrium state for prescribed density and velocity values. - -- **Step:** Streaming -- **Backend:** JAX, Warp -- **Notes:** Constructor requires macroscopic density (`rho`) and velocity (`u`) values - ---- - -## 3. ExtrapolationOutflowBC - -The `ExtrapolationOutflowBC` class implements an extrapolation-based outflow boundary condition to reduce wave reflections at simulation domain exits. - -- **Step:** Streaming -- **Backend:** JAX, Warp -- **Notes:** - ---- - -## 4. FullwayBounceBackBC - -The `FullwayBounceBackBC` class implements the classic full bounce-back boundary condition, reflecting distribution functions at boundaries. - -- **Step:** Collision -- **Backend:** JAX, Warp -- **Notes:** Enforces no-slip wall conditions by reversing particle distributions at the boundary during the collision step. - ---- - -## 5. GradsApproximationBC - -The `GradsApproximationBC` class implements boundary conditions using Grad’s approximation to reconstruct missing distribution functions based on macroscopic moments. - -- **Step:** Streaming -- **Backend:** Warp -- **Notes:** Requires 3D velocity sets (not implemented in 2D) ---- - -## 6. HalfwayBounceBackBC - -The `HalfwayBounceBackBC` class implements the halfway bounce-back boundary condition, a popular variant of the bounce-back method used in LBM simulations. - -- **Step:** Streaming -- **Backend:** JAX, Warp -- **Notes:** Enforces no-slip conditions by reflecting distribution functions halfway between fluid and boundary nodes, improving accuracy over fullway bounce-back. ---- - -## 7. ZouHeBC - -The `ZouHeBC` class implements the classical Zou-He boundary condition for prescribed velocity or pressure boundaries using non-equilibrium bounce-back. - -- **Step:** Streaming -- **Backend:** JAX, Warp -- **Notes:** Supports only normal velocity components (only one non-zero velocity element allowed) - - ---- - -## 8. RegularizedBC - -The `RegularizedBC` class extends the `ZouHeBC` to implement a regularized boundary condition incorporating a non-equilibrium bounce-back with additional second-moment corrections. - -- **Step:** Streaming -- **Backend:** JAX, Warp -- **Notes:** - ---- ## Summary Table of Boundary Conditions @@ -167,9 +108,9 @@ The `RegularizedBC` class extends the `ZouHeBC` to implement a regularized bound |------------------------|------------------------------------------------------|---------------------|------------------------|-----------------------| | `DoNothingBC` | Leaves boundary distributions unchanged (no-op) | STREAMING | No |JAX, Warp | | `EquilibriumBC` | Prescribe equilibrium populations | STREAMING | No | JAX, Warp | -| `ExtrapolationOutflowBC`| Smooth outflow via extrapolation | STREAMING | Yes | JAX, Warp | | `FullwayBounceBackBC` | Classic bounce-back (no-slip) | COLLISION | No | JAX, Warp | -| `GradsApproximationBC` | Approximate missing populations via Grad's method | STREAMING | No | Warp only | | `HalfwayBounceBackBC` | Halfway bounce-back for no-slip walls | STREAMING | No | JAX, Warp | | `ZouHeBC` | Classical Zou-He velocity/pressure BC with non-equilibrium bounce-back | STREAMING | Yes |JAX, Warp | | `RegularizedBC` | Non-equilibrium bounce-back with second moment regularization | STREAMING | No | JAX, Warp | +| `ExtrapolationOutflowBC`| Smooth outflow via extrapolation | STREAMING | Yes | JAX, Warp | +| `GradsApproximationBC` | Approximate missing populations via Grad's method | STREAMING | No | Warp only | diff --git a/docs/index.md b/docs/index.md index 8446c2db..88ea7aed 100644 --- a/docs/index.md +++ b/docs/index.md @@ -91,15 +91,3 @@ If you use XLB in your research, please cite the following paper: - [Orbax](https://github.com/google/orbax)-based distributed asynchronous checkpointing - Image Output - 3D mesh voxelizer using trimesh - -### Boundary conditions - -- **Equilibrium BC:** In this boundary condition, the fluid populations are assumed to be in at equilibrium. Can be used to set prescribed velocity or pressure. -- **Full-Way Bounceback BC:** In this boundary condition, the velocity of the fluid populations is reflected back to the fluid side of the boundary, resulting in zero fluid velocity at the boundary. -- **Half-Way Bounceback BC:** Similar to the Full-Way Bounceback BC, in this boundary condition, the velocity of the fluid populations is partially reflected back to the fluid side of the boundary, resulting in a non-zero fluid velocity at the boundary. -- **Do Nothing BC:** In this boundary condition, the fluid populations are allowed to pass through the boundary without any reflection or modification. -- **Zouhe BC:** This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. -- **Regularized BC:** This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. This BC is more stable than Zouhe BC, but computationally more expensive. -- **Extrapolation Outflow BC:** A type of outflow boundary condition that uses extrapolation to avoid strong wave reflections. -- **Interpolated Bounceback BC:** Interpolated bounce-back boundary condition for representing curved boundaries. - diff --git a/mkdocs.yml b/mkdocs.yml index fed38522..0e32ffef 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -149,14 +149,15 @@ nav: - XLB's home: index.md - Installation: installation.md # - Tutorails: tutorials.md - - Operator: operator.md - - Constants: constants.md - - Boundary Condition: BC.md - - Grid: grid.md - - Macroscopic: macroscopic.md - - Stepper: stepper.md - - Common Steps: common_steps.md - - Streaming and Collision: streaming_and_collision.md - # - API Reference: api_reference.md + - API & Modules: + - Common Steps: common_steps.md + - Constants: constants.md + - Grid: grid.md + - Operator: operator.md + - Boundary Condition: BC.md + - Macroscopic: macroscopic.md + - Stepper: stepper.md + - Streaming and Collision: streaming_and_collision.md + # - API Reference: api_reference.md - Examples: examples.md - Contributing: contributing.md \ No newline at end of file From d387c869382d1a9c81ecfb585860479a7e653c3c Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Mon, 4 Aug 2025 09:52:51 -0400 Subject: [PATCH 16/19] Add doc pages equilibrium, distribution and force --- docs/distribution.md | 100 +++++++++++++++++++++++++++++++++++++++++++ docs/equilibrium.md | 35 +++++++++++++++ docs/force.md | 67 +++++++++++++++++++++++++++++ docs/operator.md | 28 +++++++++++- docs/velocity_set.md | 46 ++++++++++++++++++++ mkdocs.yml | 6 ++- 6 files changed, 279 insertions(+), 3 deletions(-) create mode 100644 docs/distribution.md create mode 100644 docs/equilibrium.md create mode 100644 docs/force.md create mode 100644 docs/velocity_set.md diff --git a/docs/distribution.md b/docs/distribution.md new file mode 100644 index 00000000..45e141d3 --- /dev/null +++ b/docs/distribution.md @@ -0,0 +1,100 @@ +# Distribution + +The `distribution` module provides tools for distributing **lattice Boltzmann operators** across multiple devices (e.g., GPUs or TPUs) using [JAX sharding](https://jax.readthedocs.io/en/latest/notebooks/Distributed_arrays_and_automatic_parallelization.html). +This enables simulations to run in parallel while ensuring correct **halo communication** between device partitions. + +--- + +## Overview + +In lattice Boltzmann methods (LBM), each lattice site’s distribution function depends on its neighbors. +When running on multiple devices, the domain is split (sharded) across them, requiring **data exchange at the boundaries** after each step. + +The `distribution` module handles: + +- **Sharding operators** across devices. +- **Exchanging boundary (halo) data** between devices. +- Supporting stepper operators (like `IncompressibleNavierStokesStepper`) with or without boundary conditions. + +--- + +## Functions + +### `distribute_operator` + +```python +distribute_operator(operator, grid, velocity_set, num_results=1, ops="permute") +``` +Wraps an operator to run in distributed fashion. + +## Parameters + +- **operator** (`Operator`) + The LBM operator (e.g., collision, streaming). + +- **grid** + Grid definition with device mesh info (`grid.global_mesh`, `grid.shape`, `grid.nDevices`). + +- **velocity_set** + Velocity set defining the LBM stencil (e.g., D2Q9, D3Q19). + +- **num_results** (`int`, default=`1`) + Number of results returned by the operator. + +- **ops** (`str`, default=`"permute"`) + Communication scheme. Currently supports `"permute"` for halo exchange. + +--- + +## Details + +- Uses **`shard_map`** to parallelize across devices. +- Applies **halo communication** via `jax.lax.ppermute`: + - Sends right-edge values to the left neighbor. + - Sends left-edge values to the right neighbor. +- Returns a **JIT-compiled distributed operator**. + +--- + +### `distribute` + +```python +distribute(operator, grid, velocity_set, num_results=1, ops="permute") + +``` + +## Description + +Decides how to distribute an operator or stepper. + +--- + +## Parameters + +Same as **`distribute_operator`**. + +--- + +## Special Case: `IncompressibleNavierStokesStepper` + +- Checks if boundary conditions require **post-streaming updates**: + - If **yes** β†’ only the `.stream` operator is distributed. + - If **no** β†’ the entire stepper is distributed. + +--- + +## Example + +```python +from xlb.operator.stepper import IncompressibleNavierStokesStepper +from xlb.distribution import distribute + +# Create stepper +stepper = IncompressibleNavierStokesStepper(...) + +# Distribute across devices +distributed_stepper = distribute(stepper, grid, velocity_set) + +# Run simulation +state = distributed_stepper(state) +``` diff --git a/docs/equilibrium.md b/docs/equilibrium.md new file mode 100644 index 00000000..d4d95ae4 --- /dev/null +++ b/docs/equilibrium.md @@ -0,0 +1,35 @@ +# Equilibrium + +Equilibrium operators define the **target distribution functions** in the Lattice Boltzmann Method (LBM). +They represent the state towards which the fluid relaxes during the **collision step** and are essential for computing correct fluid behavior. + +--- + +## Overview + +- In LBM, particles are represented by discrete distributions along predefined velocity directions. +- After collisions, these distributions relax toward an **equilibrium distribution**. +- The chosen equilibrium model determines how density and velocity fields map to these distributions. + +The equilibrium distribution ensures that: + +- Mass and momentum are conserved. +- Macroscopic fluid quantities (like density and velocity) are correctly reproduced. + +--- + +## QuadraticEquilibrium + +The **QuadraticEquilibrium** is the default and most widely used equilibrium model in LBM. + +- **Mathematical Basis**: + Approximates the Maxwell–Boltzmann distribution using a second-order Hermite polynomial expansion. +- **Inputs**: + - **Density (ρ):** scalar field + - **Velocity (u):** vector field (2D or 3D depending on lattice) +- **Outputs**: + - **Equilibrium distribution functions (feq):** one per velocity direction in the velocity set + +This model ensures correct recovery of the **Navier–Stokes equations** for incompressible flows. + +--- \ No newline at end of file diff --git a/docs/force.md b/docs/force.md new file mode 100644 index 00000000..63d7661f --- /dev/null +++ b/docs/force.md @@ -0,0 +1,67 @@ +# Force + +The **Force** module provides operators for handling forces in Lattice Boltzmann Method (LBM) simulations. +These operators cover both **adding external forces to the fluid** and **computing the forces exerted by the fluid on solid boundaries**. + +--- + +## Overview + +Forces in LBM simulations can act in two distinct ways: + +- **Body forces**: External effects applied to the fluid domain (e.g., gravity, acceleration, electromagnetic forces). +- **Boundary forces**: Hydrodynamic forces exerted by the fluid on immersed solid objects (e.g., drag or lift). + +XLB provides two operators to handle these cases: + +| Operator | Purpose | +|---------------------|-------------------------------------------------------------------------| +| **ExactDifference** | Adds body forces to the fluid using the Exact Difference Method (EDM). | +| **MomentumTransfer** | Computes the force exerted by the fluid on boundaries via momentum exchange. | + +Both operators support **JAX** and **Warp** compute backends. + +--- + +## ExactDifference + +The **Exact Difference** operator incorporates external body forces into the fluid dynamics without breaking stability or conservation. +It uses the *Exact Difference Method (EDM)* introduced by Kupershtokh (2004), which is a stable and widely used approach in LBM. + +- **Purpose**: Apply external forces uniformly to the fluid domain. +- **Use cases**: Gravity-driven flows, accelerated channel flows, magnetohydrodynamics. +- **Method**: + - Computes the difference between equilibrium distributions with and without a velocity shift caused by the force. + - Corrects the post-collision distribution functions by adding this difference. +- **Notes**: + - Currently limited to constant force vectors (not spatially varying fields). + - Works seamlessly with the chosen velocity set (e.g., D2Q9, D3Q19, D3Q27). + +--- + +## MomentumTransfer + +The **Momentum Transfer** operator measures the hydrodynamic force exerted by the fluid on solid boundaries. +It implements the *momentum exchange method*, introduced by Ladd (1994) and extended by Mei et al. (2002) for curved boundaries. + +- **Purpose**: Compute forces such as drag, lift, or pressure exerted on immersed boundaries. +- **Use cases**: Flow around cylinders, aerodynamic lift, sedimentation of particles, boundary stress analysis. +- **Method**: + - Uses the post-collision distributions and applies boundary conditions. + - Identifies boundary nodes and their missing directions. + - Computes the exchanged momentum between the fluid and the solid at each node. +- **Notes**: + - Should be applied **after boundary conditions** are imposed. + - Compatible with advanced no-slip schemes (e.g., Bouzidi) for curved geometries. + - Returns either a field of forces (JAX) or the net force (Warp). + +--- + +## Summary + +- **ExactDifference** β†’ Drives the fluid using external body forces (e.g., gravity, acceleration). +- **MomentumTransfer** β†’ Measures hydrodynamic forces acting on immersed solid geometries. + +Together, they enable both **forcing the fluid** and **analyzing boundary interactions**, making them essential for advanced LBM simulations. + +--- diff --git a/docs/operator.md b/docs/operator.md index 0be2f30b..70dbdf8b 100644 --- a/docs/operator.md +++ b/docs/operator.md @@ -59,4 +59,30 @@ Returns the actual backend module (jax.numpy or warp), depending on the current Returns the compute data type (e.g., float32, float64) according to the precision policy and backend. `store_dtype` -Returns the storage data type according to the precision policy and backend. \ No newline at end of file +Returns the storage data type according to the precision policy and backend. + +--- + +## Precision Caster + +The **PrecisionCaster** is a utility operator for converting lattice Boltzmann data between different numeric precisions. + +### Overview + +Precision plays an important role in balancing **accuracy** and **performance** during simulations. +For example, some steps may require high precision (`float64`) for stability, while others can run efficiently in lower precision (`float32`). + +The `PrecisionCaster` operator handles this conversion seamlessly for both supported backends. + +### Features + +- Converts distribution functions between precisions (e.g., FP32 β†’ FP64). +- Available for **JAX** and **Warp** backends. +- Works transparently with any chosen velocity set (e.g., D2Q9, D3Q19, D3Q27). +- Can be used before or after key operators to ensure data is in the desired format. + +### Use Cases + +- **Performance optimization**: Run most of the simulation in FP32 for speed, while critical calculations use FP64. +- **Mixed-precision workflows**: Adapt precision dynamically depending on stability needs. +- **GPU acceleration**: Exploit lower-precision compute on GPUs while preserving accuracy where needed. diff --git a/docs/velocity_set.md b/docs/velocity_set.md new file mode 100644 index 00000000..24d20e2a --- /dev/null +++ b/docs/velocity_set.md @@ -0,0 +1,46 @@ +# Velocity Sets + +In the Lattice Boltzmann Method (LBM), a **velocity set** defines the discrete directions in which particle distributions propagate on the lattice at each time step. These discrete velocities approximate the continuous fluid velocity space and are fundamental to accurately simulating fluid flow. + +Each velocity set specifies: +- The **dimension** (2D or 3D) of the lattice. +- The **number of discrete velocities (Q)** per lattice node. +- The **velocity vectors** representing allowed particle movement directions. +- The **weights** associated with each velocity, ensuring correct macroscopic behavior. + +--- + +## Base Class: `VelocitySet` + +All velocity sets inherit from the `VelocitySet` base class, which manages: +- The dimension and number of velocities. +- The velocity vectors and their weights. +- Backend compatibility for accelerated computation (JAX or WARP). + +Users typically instantiate predefined velocity sets rather than the base class directly. + +--- + +## What Do These Velocities Represent? + +Each velocity vector corresponds to a possible direction a fluid particle can move from a lattice node during streaming. For example, in a 2D lattice: + +- A zero vector (rest particle) means the particle stays at the node. +- Unit vectors along coordinate axes represent movement to neighboring nodes (up, down, left, right). +- Diagonal vectors represent movement to diagonal neighbors. + +The collection of these vectors must satisfy mathematical conditions to recover the Navier–Stokes equations correctly at the macroscopic scale, which govern fluid dynamics. + +The associated weights define the relative probability or influence of particles moving in each direction, balancing isotropy and stability. + +--- + +## Predefined Velocity Sets + +| Class | Dimension | Velocities (Q) | Description | +|---------|-----------|----------------|------------------------------------| +| `D2Q9` | 2D | 9 | Rest + 4 axis-aligned + 4 diagonal directions; standard for 2D flow simulations. | +| `D3Q19` | 3D | 19 | Combines rest, axis-aligned, and select diagonal directions for efficient 3D flows. | +| `D3Q27` | 3D | 27 | Full cubic lattice with all combinations of [-1,0,1] in 3D; higher isotropy and accuracy. | + +--- \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 0e32ffef..1b2fb3b2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -148,16 +148,18 @@ extra_javascript: nav: - XLB's home: index.md - Installation: installation.md - # - Tutorails: tutorials.md - API & Modules: - Common Steps: common_steps.md - Constants: constants.md + - Velocity set: velocity_set.md - Grid: grid.md - Operator: operator.md + - Distribution: distribution.md - Boundary Condition: BC.md - Macroscopic: macroscopic.md - Stepper: stepper.md - Streaming and Collision: streaming_and_collision.md - # - API Reference: api_reference.md + - Force: force.md + - Equilibrium: equilibrium.md - Examples: examples.md - Contributing: contributing.md \ No newline at end of file From f77df1a75b2c8b8dcbe4569ea746ba37b2083a00 Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Mon, 4 Aug 2025 19:04:36 -0400 Subject: [PATCH 17/19] restructure the docs --- docs/{ => api}/BC.md | 0 docs/api/constants.md | 137 ++++++++++++++++ docs/{ => api}/distribution.md | 0 docs/{ => api}/equilibrium.md | 0 docs/{ => api}/force.md | 0 docs/api/grid.md | 90 +++++++++++ docs/{ => api}/macroscopic.md | 0 docs/{ => api}/operator.md | 0 docs/{ => api}/stepper.md | 0 docs/{ => api}/streaming_and_collision.md | 0 docs/api/velocity_set.md | 77 +++++++++ docs/constants.md | 109 ------------- docs/grid.md | 75 --------- docs/guide/concepts.md | 73 +++++++++ docs/guide/getting_started.md | 186 ++++++++++++++++++++++ docs/{ => guide}/installation.md | 0 docs/guide/introduction.md | 57 +++++++ docs/quickstart.md | 0 docs/velocity_set.md | 46 ------ mkdocs.yml | 67 ++++++-- 20 files changed, 670 insertions(+), 247 deletions(-) rename docs/{ => api}/BC.md (100%) create mode 100644 docs/api/constants.md rename docs/{ => api}/distribution.md (100%) rename docs/{ => api}/equilibrium.md (100%) rename docs/{ => api}/force.md (100%) create mode 100644 docs/api/grid.md rename docs/{ => api}/macroscopic.md (100%) rename docs/{ => api}/operator.md (100%) rename docs/{ => api}/stepper.md (100%) rename docs/{ => api}/streaming_and_collision.md (100%) create mode 100644 docs/api/velocity_set.md delete mode 100644 docs/constants.md delete mode 100644 docs/grid.md create mode 100644 docs/guide/concepts.md create mode 100644 docs/guide/getting_started.md rename docs/{ => guide}/installation.md (100%) create mode 100644 docs/guide/introduction.md create mode 100644 docs/quickstart.md delete mode 100644 docs/velocity_set.md diff --git a/docs/BC.md b/docs/api/BC.md similarity index 100% rename from docs/BC.md rename to docs/api/BC.md diff --git a/docs/api/constants.md b/docs/api/constants.md new file mode 100644 index 00000000..81d9cd51 --- /dev/null +++ b/docs/api/constants.md @@ -0,0 +1,137 @@ +# Constants and Enums + +This page provides a reference for the core enumerations (`Enum`) and configuration objects that govern the behavior of XLB simulations. These objects are used to specify settings like the computational backend, numerical precision, and the physics model to be solved. + +--- + +## ComputeBackend + +Defined in `compute_backend.py` + +```python +class ComputeBackend(Enum): + JAX = auto() + WARP = auto() +``` + +**Description:** + +An `Enum` specifying the primary computational engine for executing simulation kernels. + +- **`JAX`**: Use the [JAX](https://github.com/google/jax) framework for computation, enabling execution on CPUs, GPUs, and TPUs. +- **`WARP`**: Use the [NVIDIA Warp](https://github.com/NVIDIA/warp) framework for high-performance GPU simulation kernels. + +--- + +## GridBackend + +Defined in `grid_backend.py` + +```python +class GridBackend(Enum): + JAX = auto() + WARP = auto() + OOC = auto() +``` + +**Description:** + +An `Enum` defining the backend for grid creation and data management. + +- **`JAX`**, **`WARP`**: The grid data resides in memory on the respective compute device. +- **`OOC`**: Handles simulations where the grid data is too large to fit into memory and must be processed "out-of-core" from disk. + +--- + +## PhysicsType + +Defined in `physics_type.py` + +```python +class PhysicsType(Enum): + NSE = auto() # Navier-Stokes Equations + ADE = auto() # Advection-Diffusion Equations +``` + +**Description:** + +An `Enum` used to select the set of physical equations to be solved by the stepper. + +- **`NSE`**: Simulates fluid dynamics governed by the incompressible Navier-Stokes equations. +- **`ADE`**: Simulates transport phenomena governed by the Advection-Diffusion equation. + +--- + +## Precision + +Defined in `precision_policy.py` + +```python +class Precision(Enum): + FP64 = auto() + FP32 = auto() + FP16 = auto() + UINT8 = auto() + BOOL = auto() +``` + +**Description:** + +An `Enum` representing fundamental data precision levels. Each member provides properties to get the corresponding data type in the target compute backend: + +- **`.wp_dtype`**: The equivalent `warp` data type (e.g., `wp.float32`). +- **`.jax_dtype`**: The equivalent `jax.numpy` data type (e.g., `jnp.float32`). + +--- + +## PrecisionPolicy + +Defined in `precision_policy.py` + +```python +class PrecisionPolicy(Enum): + FP64FP64 = auto() + FP64FP32 = auto() + FP64FP16 = auto() + FP32FP32 = auto() + FP32FP16 = auto() +``` + +**Description:** + +An `Enum` that defines a policy for balancing numerical accuracy and memory usage. It specifies a precision for computation and a (potentially different) precision for storage. + +For example, `FP64FP32` specifies that calculations should be performed in high-precision `float64`, but the results are stored in memory-efficient `float32`. + +**Utility Properties & Methods:** +- **`.compute_precision`**: Returns the `Precision` enum for computation. +- **`.store_precision`**: Returns the `Precision` enum for storage. +- **`.cast_to_compute_jax(array)`**: Casts a JAX array to the policy's compute precision. +- **`.cast_to_store_jax(array)`**: Casts a JAX array to the policy's store precision. + +--- + +## DefaultConfig + +Defined in `default_config.py` + +```python +@dataclass +class DefaultConfig: + velocity_set + default_backend + default_precision_policy +``` + +A `dataclass` that holds the global configuration for a simulation session. + +An instance of this configuration is set globally using the `xlb.init()` function at the beginning of a script. This ensures that all subsequently created XLB components are aware of the chosen backend, velocity set, and precision policy. + +```python +# The xlb.init() function sets the global DefaultConfig instance +xlb.init( + velocity_set=D2Q9(...), + default_backend=ComputeBackend.JAX, + default_precision_policy=PrecisionPolicy.FP32FP32 +) +``` \ No newline at end of file diff --git a/docs/distribution.md b/docs/api/distribution.md similarity index 100% rename from docs/distribution.md rename to docs/api/distribution.md diff --git a/docs/equilibrium.md b/docs/api/equilibrium.md similarity index 100% rename from docs/equilibrium.md rename to docs/api/equilibrium.md diff --git a/docs/force.md b/docs/api/force.md similarity index 100% rename from docs/force.md rename to docs/api/force.md diff --git a/docs/api/grid.md b/docs/api/grid.md new file mode 100644 index 00000000..cccce31a --- /dev/null +++ b/docs/api/grid.md @@ -0,0 +1,90 @@ +# Grid + +The `xlb.grid` module provides the fundamental tools for defining and managing the structured, Cartesian grids used in Lattice Boltzmann simulations. A `Grid` object represents the spatial layout of your simulation domain and is the first component you typically create when setting up a simulation. + +It is tightly integrated with the selected compute backend, ensuring that all data structures are allocated on the correct device (e.g., a JAX device or an NVIDIA GPU for Warp). + +--- + +## Creating a Grid + +The primary way to create a grid is with the `grid_factory` function. This function automatically returns the correct grid object (`JaxGrid` or `WarpGrid`) based on the selected compute backend. + +```python +from xlb.grid import grid_factory +from xlb.compute_backend import ComputeBackend +import xlb + +# Assuming xlb.init() has been called with a default backend... + +# Create a 2D grid for the JAX backend +grid_2d = grid_factory(shape=(500, 500), compute_backend=ComputeBackend.JAX) + +# Create a 3D grid for the Warp backend +grid_3d = grid_factory(shape=(256, 128, 128), compute_backend=ComputeBackend.WARP) +``` + +### `grid_factory(shape, compute_backend)` +- **`shape: Tuple[int, ...]`**: A tuple defining the grid dimensions. For example, `(nx, ny)` for 2D or `(nx, ny, nz)` for 3D. +- **`compute_backend: ComputeBackend`**: The backend to use (`ComputeBackend.JAX` or `ComputeBackend.WARP`). If not provided, it defaults to the backend set in `xlb.init()`. + + +--- + +## Using a Grid Instance + +Once you have a `grid` object, you can use its attributes and methods to define boundary regions and create data fields for your simulation. + +### Attributes + +- **`grid.shape`**: The full domain shape passed during creation (e.g., `(256, 128, 128)`). +- **`grid.dim`**: The number of spatial dimensions, inferred from the shape (2 for 2D, 3 for 3D). + +### Methods + +#### `grid.bounding_box_indices()` + +This is a crucial helper method for defining boundary conditions. It returns a dictionary containing the integer coordinates for each face of the grid's bounding box. + +```python +faces = grid_2d.bounding_box_indices(remove_edges=True) + +# faces is a dictionary with keys: 'bottom', 'top', 'left', 'right' +inlet_indices = faces["left"] +outlet_indices = faces["right"] + +# Combine multiple faces to define all stationary walls +wall_indices = faces["bottom"] + faces["top"] +``` + +- **`remove_edges: bool = False`**: If set to `True`, the corner/edge nodes where faces meet are excluded. This is highly recommended to prevent applying conflicting boundary conditions to the same node (e.g., treating a corner as both a "left" wall and a "bottom" wall). + +#### `grid.create_field()` + +This method allocates a data array (a "field") on the grid, using the appropriate backend (e.g., `jax.numpy` array or `warp` array). This is used to create storage for all simulation data, such as the particle distribution functions ($f_i$) or macroscopic quantities ($\rho, \vec{u}$). + +```python +# Create a field to store the D2Q9 particle distribution functions (f_i) +# Cardinality is 9 because there are 9 velocities in D2Q9. +f = grid_2d.create_field(cardinality=9) + +# Create a scalar field for density (rho) +rho = grid_2d.create_field(cardinality=1) + +# Create a 2D vector field for velocity (u) +u = grid_2d.create_field(cardinality=2) +``` + +- **`cardinality: int`**: The number of data values to store at each grid node. For a scalar field like density, `cardinality=1`. For a vector field like 2D velocity, `cardinality=2`. For the LBM particle populations $f_i$, `cardinality` is equal to $q$, the number of discrete velocities in your `VelocitySet`. +- **`dtype: Precision = None`**: The numerical precision for the field data (e.g., `Precision.FP32`). Defaults to the global precision policy. `Precision.BOOL` is only supported by `JaxGrid`. +- **`fill_value: float = None`**: An optional value to initialize all elements of the array. Defaults to `0`. + +--- + +## Backend-Specific Details + +### `JaxGrid` +The `JaxGrid` object is designed to be compatible with JAX's features, including multi-device parallelization via sharding. + +### `WarpGrid` +The `WarpGrid` is optimized for single-GPU execution with NVIDIA Warp. For 2D grids, it automatically adds a singleton `z` dimension (e.g., a `(500, 500)` shape becomes a `(500, 500, 1)` array). This is done to maintain consistency, allowing the same Warp kernels to be used for both 2D and 3D simulations. \ No newline at end of file diff --git a/docs/macroscopic.md b/docs/api/macroscopic.md similarity index 100% rename from docs/macroscopic.md rename to docs/api/macroscopic.md diff --git a/docs/operator.md b/docs/api/operator.md similarity index 100% rename from docs/operator.md rename to docs/api/operator.md diff --git a/docs/stepper.md b/docs/api/stepper.md similarity index 100% rename from docs/stepper.md rename to docs/api/stepper.md diff --git a/docs/streaming_and_collision.md b/docs/api/streaming_and_collision.md similarity index 100% rename from docs/streaming_and_collision.md rename to docs/api/streaming_and_collision.md diff --git a/docs/api/velocity_set.md b/docs/api/velocity_set.md new file mode 100644 index 00000000..464f8cee --- /dev/null +++ b/docs/api/velocity_set.md @@ -0,0 +1,77 @@ +# Velocity Sets + +In the Lattice Boltzmann Method (LBM), a **velocity set** defines the discrete directions in which particle populations propagate on the lattice each time step. These sets, often denoted as $D_dQ_q$ (e.g., D2Q9 for 2 dimensions, 9 velocities), are fundamental to the simulation's accuracy and stability. + +Each velocity set provides the essential components for the streaming step and equilibrium calculations: + +- **Dimension ($d$)**: The spatial dimension of the simulation (2D or 3D). +- **Number of Velocities ($q$)**: The quantity of discrete velocity vectors at each lattice node. +- **Velocity Vectors ($e_i$)**: The set of vectors representing allowed directions of particle movement. +- **Weights ($w_i$)**: The scalar weights associated with each velocity vector, crucial for correctly recovering macroscopic fluid behavior. + +--- + +## The `VelocitySet` Class + +All velocity set objects in XLB, such as `D2Q9` or `D3Q19`, are instances of a class that inherits from a common `VelocitySet` base. This object is a critical part of the initial simulation setup. + +An instance of a velocity set class provides access to its core properties and is configured for the chosen compute backend (e.g., JAX or WARP). It is typically created once and passed to `xlb.init()` at the beginning of a script. + +### Usage Example + +```python +import xlb +from xlb.compute_backend import ComputeBackend +from xlb.precision_policy import PrecisionPolicy + +# 1. Choose and instantiate a velocity set for a 2D simulation +# This configures it for a specific backend and precision. +velocity_set_2d = xlb.velocity_set.D2Q9( + compute_backend=ComputeBackend.JAX, + precision_policy=PrecisionPolicy.FP32FP32 +) + +# 2. Pass the instantiated object during initialization +xlb.init( + velocity_set=velocity_set_2d, + # ... other config options +) + +# 3. You can now access its properties if needed +print(f"Dimension: {velocity_set_2d.d}") # Output: 2 +print(f"Num Velocities: {velocity_set_2d.q}") # Output: 9 +``` + +--- + +## Conceptual Model: Vectors and Weights + +The velocity vectors $e_i$ represent the exact paths particles can take from one lattice node to another in a single time step. The collection of these vectors must satisfy specific mathematical symmetry (isotropy) conditions to ensure that the simulated fluid behaves like a real fluid. + +For the standard `D2Q9` set, the 9 vectors correspond to: +- One "rest" particle (zero vector) that stays at the node. +- Four particles moving to the nearest neighbors along the coordinate axes. +- Four particles moving to the diagonal neighbors. + +Visually, the vectors point from the center node (4) to the surrounding nodes: +``` + (8) \ (1) / (2) + \ | / + (7)---(0)---(3) + / | \ + (6) / (5) \ (4) +``` + +The corresponding weights $w_i$ define the contribution of each particle population to the macroscopic density and momentum. They are carefully chosen values that ensure the LBM simulation correctly recovers the Navier-Stokes equations. For `D2Q9`, rest particles have the highest weight, followed by axis-aligned particles, and then diagonal particles. + +--- + +## Predefined Velocity Sets + +XLB provides several standard, pre-validated velocity sets suitable for a range of physics problems. + +| Class | Dimension | Velocities (q) | Description | +| :--- | :--- | :--- | :--- | +| **`D2Q9`** | 2D | 9 | Standard for 2D flows. Includes a rest particle, 4 axis-aligned directions, and 4 diagonal directions. Provides a good balance of accuracy and efficiency. | +| **`D3Q19`**| 3D | 19 | An efficient choice for 3D flows. Includes a rest particle, 6 axis-aligned directions, and 12 diagonal directions to the faces of the two surrounding cubes. | +| **`D3Q27`**| 3D | 27 | A more comprehensive 3D model. Includes all 27 vectors in a 3x3x3 cube around the node. Offers higher isotropy and accuracy at a greater computational cost. | \ No newline at end of file diff --git a/docs/constants.md b/docs/constants.md deleted file mode 100644 index 933e4e05..00000000 --- a/docs/constants.md +++ /dev/null @@ -1,109 +0,0 @@ -# πŸ“˜ Constants and Enums - -This page documents the core enums and configuration constants used throughout the codebase. These constants define important fixed values such as compute backends, grid strategies, physics models, and precision policies used in simulations. - - - -## πŸ”§ Compute Backends - -Defined in compute_backend.py - -```python -class ComputeBackend(Enum): - JAX = auto() - WARP = auto() -``` -Description: - -Specifies the available compute engines: - -- **JAX**: Uses JAX for GPU/TPU accelerated computation. -- **WARP**: Uses NVIDIA Warp for GPU-based simulation. - -## 🧱 Grid Backends - -Defined in grid_backend.py -```python -class GridBackend(Enum): - JAX = auto() - WARP = auto() - OOC = auto() -``` - -Description: - -Represents the grid computation backend: - -- **JAX, WARP** (same as above) -- **OOC**: Out-of-core grid handling (e.g., large datasets or disk-based grids). - -## 🌊 Physics Types - -Defined in physics_type.py -```python -class PhysicsType(Enum): - NSE = auto() # Navier-Stokes Equations - ADE = auto() # Advection-Diffusion Equations -``` - -Description: - -Defines the physical equations the system can solve: - -- **NSE**: Fluid dynamics using Navier-Stokes. -- **ADE**: Transport processes using Advection-Diffusion. - - -## 🎯 Precision Enum - -Defined in precision_policy.py -```python -class Precision(Enum): - FP64, FP32, FP16, UINT8, BOOL -``` - -Description: - -Represents data precision levels. Each precision level maps to both JAX and WARP data types via properties: - -- Precision.wp_dtype β†’ Warp data type -- Precision.jax_dtype β†’ JAX data type - - - -## βš™οΈ PrecisionPolicy Enum - -```python -class PrecisionPolicy(Enum): - FP64FP64, FP64FP32, FP64FP16, FP32FP32, FP32FP16 -``` - -Description: - -Controls how data is computed vs stored: - -- **FP64FP32** means compute in float64, store in float32 -Utility methods: -- **.compute_precision**: Returns compute-side precision -- **.store_precision**: Returns storage-side precision -- **.cast_to_compute_jax(array)**: Casts to compute dtype -- **.cast_to_store_jax(array)**: Casts to store dtype - - - -## βš™οΈ Default Configuration - -Defined in default_config.py - -```python -@dataclass -class DefaultConfig: - velocity_set - default_backend - default_precision_policy -``` -Set globally using: -```python -init(velocity_set, backend, precision_policy) -``` -This is used to initialize system-wide simulation behavior based on chosen backends and numerical settings. \ No newline at end of file diff --git a/docs/grid.md b/docs/grid.md deleted file mode 100644 index 407c2ee5..00000000 --- a/docs/grid.md +++ /dev/null @@ -1,75 +0,0 @@ -# Grid - -The `xlb.grid` module provides utilities to define and manage structured grids for Lattice Boltzmann (LBM) simulations. A grid defines the spatial layout of your simulation domain and is tightly integrated with the selected compute backend (JAX or Warp). - -## Quick start - -```python -from xlb.grid import grid_factory -from xlb.compute_backend import ComputeBackend -import xlb - -# (Usually already done once in your program) -xlb.init(...) - -# Create a 3D grid on Warp -grid = grid_factory((256, 128, 128), compute_backend=ComputeBackend.WARP) - -# Create a distribution field with cardinality = velocity_set.d -f = grid.create_field(cardinality=19) # e.g., D3Q19 - -# Get boundary indices to build BCs -faces = grid.bounding_box_indices(remove_edges=True) -left, right = faces["left"], faces["right"] - -``` - -## **Parameters** - -- `shape: Tuple[int, ...]` β€” `(nx, ny)` for 2D or `(nx, ny, nz)` for 3D. -- `compute_backend: ComputeBackend` β€” `ComputeBackend.JAX` or `ComputeBackend.WARP`. - -## **Attributes** - -- `grid.shape` : The full domain shape you passed in. -- `grid.dim` : 2 or 3, inferred from `shape`. - -## **Functions** - -- `grid_factory(shape, compute_backend=None)` : Returns a `JaxGrid` or `WarpGrid` based on the backend. - -- `grid.bounding_box_indices(remove_edges: bool = False) -> dict[str, list[list[int]]]`: - - Returns integer indices for each boundary face. - - Keys for 2D: `bottom`, `top`, `left`, `right` - - Keys for 3D: `bottom`, `top`, `left`, `right`, `front`, `back` - - `remove_edges=True` : removes edge/corner nodes (useful to avoid double-applying BCs). - -Example -```python -faces = grid.bounding_box_indices(remove_edges=True) -inlet = faces["left"] -outlet = faces["right"] -walls = (faces["bottom"][0] + faces["top"][0]) # merge faces per-dimension -``` - - -- `grid.create_field(cardinality: int, dtype: Precision = None, fill_value: float = None) -> array`: - - Creates a field over the grid for storing simulation data. - - `cardinality`: number of values per grid cell - - 1 β†’ scalar field (e.g., density, pressure) - - 2/3 β†’ vector field (e.g., velocity components) - - `dtype`: precision (FP32, FP64, FP16, BOOL). Defaults to config. - - `BOOL` is only supported with **JaxGrid** - - `fill_value`: initialize with constant; defaults to 0. - - - -## **JAX-specific:** `JaxGrid` -`JaxGrid` is designed for multi-device setups. - - -## **Warp-specific:** `WarpGrid` -`WarpGrid` targets single GPU with NVIDIA Warp. - -- For 2D grids, a singleton `z` dimension is automatically added to keep kernels consistent. - diff --git a/docs/guide/concepts.md b/docs/guide/concepts.md new file mode 100644 index 00000000..3ed1d2aa --- /dev/null +++ b/docs/guide/concepts.md @@ -0,0 +1,73 @@ +# Core Concepts in XLB + +In the [Introduction](./introduction.md), we covered the basic theory of the Lattice Boltzmann Method (LBM). Now, let's explore how that theory is translated into the practical software components you will use to build every XLB simulation. + +Understanding these core concepts is the key to unlocking the full power and flexibility of the library. Each concept is represented by one or more Python objects that serve as the building blocks of your simulation. + +--- + +## The Grid and Velocity Set + +The foundation of any LBM simulation is the lattice itself. In XLB, this is defined by two components: + +* **`Grid`**: This object represents the discrete simulation domain. It holds the shape of your computational grid (e.g., 500x500) and provides helpful methods for identifying regions, such as the boundaries of the domain using `grid.bounding_box_indices()`. It represents the collection of all spatial nodes $\vec{x}$. + +* **`Velocity Set`**: This defines the mesoscopic "pathways" particles can take on the lattice. It specifies the set of discrete velocity vectors $\vec{e}_i$ and their corresponding weights $w_i$. The choice of velocity set depends on the physics you want to simulate and the dimensionality of your problem. Common choices include: + * **`D2Q9`**: For 2D simulations (D_imension=2, Q_uantity-of-velocities=9). + * **`D3Q19`** or **`D3Q27`**: For 3D simulations. + +Together, the `Grid` and `Velocity Set` establish the space-time arena where your simulation will unfold. + +*For more details, see the API Reference for [`Grid`](../api/grid.md) and [`Velocity Set`](../api/velocity_set.md).* + +## The Distribution Function ($f_i$) + +The central data structure in an XLB simulation is the **Distribution Function**. This is a large array that stores the value of the particle population $f_i(\vec{x}, t)$ for every discrete velocity $i$ at every node $\vec{x}$ on the grid. + +While it is the most important piece of data, you will rarely modify it directly. Instead, the `Stepper` object (see below) reads from and writes to the distribution function arrays during the collision and streaming steps. All the complex fluid behavior emerges from the evolution of this single data structure. + +*For more details, see the API Reference for [`Distribution`](../api/distribution.md).* + +## Boundary Conditions + +A fluid simulation is often defined by its interactions with the boundaries of the domain. In XLB, these interactions are defined by a list of `BoundaryCondition` objects. Each object targets a specific set of grid nodes and enforces a physical rule. + +XLB provides several common boundary conditions out of the box. + +Defining the correct boundary conditions is one of the most critical steps in setting up a valid simulation. + +*For more details, see the API Reference for [`Boundary Condition`](../api/bc.md) and our [How-to Guides](./how-to-bc.md).* + +## The Stepper + +The `Stepper` is the engine of your simulation. It is the object that orchestrates the core LBM algorithm and advances the simulation forward in time. When you call the stepper in your main loop, it performs a complete time step, which involves: + +1. **Collision**: Applying the collision model (e.g., BGK) to every node on the grid. This relaxes the distribution functions $f_i$ towards their local equilibrium $f_i^{eq}$. +2. **Boundary Conditions**: Applying the logic from all the `BoundaryCondition` objects you have defined. +3. **Streaming**: Propagating the post-collision particle populations $f_i^*$ to their neighboring nodes along their velocity vectors $\vec{e}_i$. + +The `IncompressibleNavierStokesStepper` is the primary stepper used for most standard fluid dynamics problems. + +*For more details, see the API Reference for [`Stepper`](../api/stepper.md) and [`Streaming and Collision`](../api/streaming_and_collision.md).* + +## Macroscopic Variables ($\rho, \vec{u}$) + +While the LBM simulation operates on the mesoscopic distribution functions $f_i$, the results we are interested in are usually macroscopic quantities like fluid density $\rho$ and velocity $\vec{u}$. + +The process of calculating these from $f_i$ is called "taking moments." XLB provides a `Macroscopic` computer for this exact purpose. You provide it with the current distribution function, and it returns the macroscopic fields by computing the sums over the discrete velocities: + +* **Density:** $\rho = \sum_i f_i$ +* **Momentum:** $\rho\vec{u} = \sum_i f_i \vec{e}_i$ + +This calculation is typically done in the post-processing stage of your simulation loop to analyze and visualize the results. + +*For more details, see the API Reference for [`Macroscopic`](../api/macroscopic.md).* + +## Compute Backends and Precision + +A key feature of XLB is its ability to run the same simulation code on different high-performance backends. This is configured globally via `xlb.init()`. + +* **`ComputeBackend`**: This tells XLB which engine to use for all numerical computations (e.g., `JAX` for CPU/GPU/TPU or `WARP` for high-performance NVIDIA GPU kernels). +* **`PrecisionPolicy`**: This controls the numerical precision (e.g., 32-bit `FP32` or 64-bit `FP64` floats) used for the simulation, allowing you to balance performance with accuracy. + +This design allows you to write your physics code once and seamlessly switch the underlying computation engine to best suit your hardware. \ No newline at end of file diff --git a/docs/guide/getting_started.md b/docs/guide/getting_started.md new file mode 100644 index 00000000..2ebad918 --- /dev/null +++ b/docs/guide/getting_started.md @@ -0,0 +1,186 @@ +# Getting Started: Your First Simulation + +Welcome to XLB! This guide will walk you through every step of creating and running your first 2D fluid simulation: the classic **Lid-Driven Cavity**. + +By the end of this tutorial, you will understand the workflow to simulate fluid in a box with a moving top lid and know how the results are generated. + +## The Goal: Lid-Driven Cavity + +We will simulate a square cavity filled with a fluid. The bottom and side walls are stationary, while the top wall (the "lid") moves at a constant horizontal velocity. This motion drags the fluid, creating a large vortex inside the cavity. + + +--- + +### Step 1: Imports and Initial Configuration + +First, we need to import the necessary components from the `xlb` library and other utilities. We also define our simulation's core configuration: + +* **`ComputeBackend`**: We choose the engine that will perform the calculations. `WARP` is a great choice for high performance on NVIDIA GPUs. +* **`PrecisionPolicy`**: We define the numerical precision for our calculations (e.g., 32-bit floats). +* **`velocity_set`**: We choose the set of discrete velocities for our lattice. For 2D simulations, `D2Q9` is the standard choice. + +```python +import xlb +from xlb.compute_backend import ComputeBackend +from xlb.precision_policy import PrecisionPolicy +from xlb.grid import grid_factory +from xlb.operator.stepper import IncompressibleNavierStokesStepper +from xlb.operator.boundary_condition import HalfwayBounceBackBC, EquilibriumBC +from xlb.operator.macroscopic import Macroscopic +from xlb.utils import save_image + +import jax.numpy as jnp +import numpy as np +import warp as wp +``` + +### Step 2: Define Simulation Parameters + +Next, we set the physical and numerical parameters for our simulation in the script. + +* **Grid Shape**: We'll use a 500x500 grid. +* **Reynolds Number (`Re`)**: A dimensionless number that characterizes the flow. Higher `Re` means more turbulent-like flow. +* **Lid Velocity (`u_lid`)**: The speed of the top wall. +* **Relaxation Parameter (`omega`)**: This parameter, related to the fluid's viscosity, controls the rate at which particle distributions relax to equilibrium during the collision step. It is calculated from the Reynolds number. Its value is typically between 0 and 2. + +```python +# --- Simulation Parameters --- +GRID_SHAPE = (500, 500) +REYNOLDS_NUMBER = 200.0 +LID_VELOCITY = 0.05 +NUM_STEPS = 10000 + +# --- Derived Parameters --- +# Calculate fluid viscosity from Reynolds number +viscosity = LID_VELOCITY * (GRID_SHAPE[0] - 1) / REYNOLDS_NUMBER +# Calculate the relaxation parameter omega from viscosity +omega = 1.0 / (3.0 * viscosity + 0.5) +``` + +### Step 3: Initialize XLB and Create the Grid + +With our configuration ready, we initialize the XLB environment and create our simulation grid. + +* `xlb.init()`: This crucial step sets up the global environment with our chosen backend and precision. +* `grid_factory()`: This function creates a `Grid` object, which is a representation of our simulation domain. + +```python +# --- Setup XLB Environment --- +compute_backend = ComputeBackend.WARP +precision_policy = PrecisionPolicy.FP32FP32 +velocity_set = xlb.velocity_set.D2Q9(precision_policy=precision_policy, compute_backend=compute_backend) + +# Initialize XLB +xlb.init( + velocity_set=velocity_set, + default_backend=compute_backend, + default_precision_policy=precision_policy, +) + +# Create the simulation grid +grid = grid_factory(GRID_SHAPE, compute_backend=compute_backend) +``` + +### Step 4: Define Boundary Regions + +We need to tell XLB where the walls and the moving lid are. The `grid` object has a helper method, `bounding_box_indices()`, to easily get the indices of the domain's edges, which we then assign to named regions like `lid` and `walls`. + +```python +# --- Define Boundary Indices --- +# Get all boundary indices +box = grid.bounding_box_indices() +# Get boundary indices without the corners +box_no_edge = grid.bounding_box_indices(remove_edges=True) + +# Assign regions +lid = box_no_edge["top"] +walls = [box["bottom"][i] + box["left"][i] + box["right"][i] for i in range(velocity_set.d)] +# Flatten the list of wall indices +walls = np.unique(np.array(walls), axis=-1).tolist() +``` + +### Step 5: Setup Boundary Conditions + +Now we associate a physical behavior with each boundary region by creating instances of boundary condition classes. + +* **`EquilibriumBC`**: We use this for the lid. It forces the fluid at the lid's location to have a specific density $\rho$ and velocity $\vec{u}$. This effectively "drags" the fluid. +* **`HalfwayBounceBackBC`**: This is a standard no-slip wall condition. It simulates a solid, stationary wall by bouncing particles back in the direction they came from. + +```python +# --- Create Boundary Conditions --- +bc_lid = EquilibriumBC(rho=1.0, u=(LID_VELOCITY, 0.0), indices=lid) +bc_walls = HalfwayBounceBackBC(indices=walls) + +boundary_conditions = [bc_walls, bc_lid] +``` + +### Step 6: Setup the Stepper + +The `Stepper` is the engine of the simulation. It orchestrates the collision and streaming steps. We create an `IncompressibleNavierStokesStepper` and use its `prepare_fields()` method to initialize the distribution function arrays (`f_0` and `f_1`) and boundary masks. + +`f_0` and `f_1` are two buffers that hold the entire state of the simulation. We use two to swap between them at each time step. + +```python +# --- Setup the Simulation Stepper --- +stepper = IncompressibleNavierStokesStepper( + grid=grid, + boundary_conditions=boundary_conditions, + collision_type="BGK", +) + +# Prepare the fields (distribution functions f_0, f_1 and masks) +f_0, f_1, bc_mask, missing_mask = stepper.prepare_fields() +``` + +### Step 7: The Simulation Loop + +This is where the magic happens! A `for` loop runs the simulation for a specified number of steps. In each iteration of the loop, the script performs these actions: +1. Calls the `stepper` to perform one full time step (collision and streaming). This updates the `f_1` buffer based on the current state in the `f_0` buffer. +2. **Swaps the buffers**: The script then swaps `f_0` and `f_1` so that the newly computed state becomes the input for the next step. +3. Periodically runs post-processing logic to calculate macroscopic variables like velocity and save the results as an image. + +```python +# --- Run the Simulation --- +print("Starting simulation...") +for step in range(NUM_STEPS): + # Perform one simulation step + f_0, f_1 = stepper(f_0, f_1, bc_mask, missing_mask, omega, step) + + # Swap the distribution function buffers + f_0, f_1 = f_1, f_0 + + # --- Post-processing (every 1000 steps) --- + if step % 1000 == 0 or step == NUM_STEPS - 1: + print(f"Processing step {step}...") + + # We use a JAX-backend Macroscopic computer for post-processing + # First, convert the Warp tensor to a JAX array if needed + if compute_backend == ComputeBackend.WARP: + f_current = wp.to_jax(f_0)[..., 0] # Drop the z-dim added by Warp for 2D + else: + f_current = f_0 + + # Create a Macroscopic computer on the fly + macro_computer = Macroscopic( + compute_backend=ComputeBackend.JAX, + precision_policy=precision_policy, + velocity_set=xlb.velocity_set.D2Q9(precision_policy=precision_policy, compute_backend=ComputeBackend.JAX), + ) + + # Calculate density and velocity + rho, u = macro_computer(f_current) + + # Calculate velocity magnitude for visualization + u_magnitude = jnp.sqrt(u[0]**2 + u[1]**2) + + # Save the velocity magnitude field as an image + save_image(u_magnitude, timestep=step, prefix="lid_driven_cavity") + print(f"Saved image for step {step}.") + +print("Simulation finished!") +``` + +## Next Steps + +Congratulations! You now understand the workflow for configuring and running a fluid simulation with XLB. +* To understand the details of the classes and functions we discussed, dive into the [**API Reference**](../api/constants.md). \ No newline at end of file diff --git a/docs/installation.md b/docs/guide/installation.md similarity index 100% rename from docs/installation.md rename to docs/guide/installation.md diff --git a/docs/guide/introduction.md b/docs/guide/introduction.md new file mode 100644 index 00000000..3872e1c8 --- /dev/null +++ b/docs/guide/introduction.md @@ -0,0 +1,57 @@ +# Introduction to XLB + +Welcome to XLB! This page will introduce you to the core concepts of the library, the numerical method it's based on, and the general philosophy behind its design. + +## What is XLB? + +XLB is a modern, high-performance library for computational fluid dynamics (CFD) based on the **Lattice Boltzmann Method (LBM)**. It is written in Python and designed with two primary goals in mind: + +1. **Ease of Use:** XLB provides a high-level, object-oriented API that makes setting up complex fluid simulations intuitive and straightforward. The goal is to let you focus on the physics of your problem, not on boilerplate code. +2. **Flexibility and Performance:** While being easy to use, XLB is built for serious research. It is designed to be easily extendable with new physical models, and it leverages modern numerical backends (like JAX or Numba) to achieve performance comparable to compiled languages, all from within the comfort of Python. + +It is an ideal tool for students learning CFD, researchers prototyping new models, and anyone who needs a powerful and flexible fluid simulation toolkit. + +## A Brief Primer on the Lattice Boltzmann Method + +To understand how to use XLB, it's helpful to understand the basics of the Lattice Boltzmann Method. Unlike traditional CFD solvers that directly discretize the macroscopic Navier-Stokes equations, LBM is a **mesoscopic method**. It simulates fluid flow by modeling the collective behavior of fluid particles. + +The core variable in LBM is the **particle distribution function**, denoted as $f_i(\vec{x}, t)$. This function represents the population of particles at a lattice node $\vec{x}$ at time $t$, moving with a discrete velocity $\vec{e}_i$. The collection of these discrete velocities (e.g., 9 in 2D for the D2Q9 model) forms a `Velocity Set`. + +The entire LBM algorithm elegantly evolves these particle populations through two simple steps in each time iteration: + +1. **Collision:** At each lattice node, the particle populations interact with each other. This interaction, or "collision," causes the distribution functions $f_i$ to relax towards a local **equilibrium distribution**, $f_i^{eq}$. This equilibrium state is a function of the macroscopic fluid properties like density ($\rho$) and velocity ($\vec{u}$), which are calculated directly from the particle distributions. The most common collision model is the Bhatnagar-Gross-Krook (BGK) operator, which simplifies this process to: + + $$f_i^* = f_i - \frac{1}{\tau} (f_i - f_i^{eq})$$ + + where $f_i^*$ is the post-collision state and $\tau$ is the relaxation time, which controls the fluid's viscosity. + +2. **Streaming:** After collision, the particle populations propagate, or "stream," to their nearest neighbors in the direction of their velocity $\vec{e}_i$. + + $$f_i(\vec{x} + \vec{e}_i \Delta t, t + \Delta t) = f_i^*(\vec{x}, t)$$ + +By repeating these two simple, local steps, the complex, non-linear behavior of fluid flow described by the Navier-Stokes equations emerges automatically. + +Finally, the macroscopic fluid variables are recovered at any point by taking moments of the distribution functions: +* **Density:** $\rho = \sum_i f_i$ +* **Momentum:** $\rho\vec{u} = \sum_i f_i \vec{e}_i$ + +## The XLB Philosophy: Mapping Concepts to Code + +XLB is designed to make its code structure directly reflect the concepts of the LBM. When you build a simulation, you are essentially assembling Python objects that represent each part of the method. + +* **The Lattice (`Grid`, `Velocity Set`):** You first define the simulation domain by creating a `Grid` object and choosing a `Velocity Set` (e.g., D2Q9 for 2D simulations). + +* **The Physics (`Equilibrium`, `Collision`, `Stream`):** The "rules" of the simulation are encapsulated in objects. The mathematical form of the equilibrium distribution $f_i^{eq}$ is handled by the `Equilibrium` module, the collision process is defined by an `Collision`, and the stepper process is defined by a `Stream`. + +* **Boundaries and Forces (`BoundaryCondition`, `Force`):** Physical boundaries (like walls) and body forces (like gravity) are not part of the core LBM algorithm but are added as distinct `BoundaryCondition` and `Force` objects that interact with the particle distributions at specific nodes. + +* **The Engine (`Stepper`):** The main simulation loop, which repeatedly calls the collision and streaming steps, is controlled by a `Stepper` object. You initialize it with your setup and tell it how many steps to run. + +* **The Results (`Macroscopic`):** To get useful data out of your simulation, you use functions from the `Macroscopic` module to compute density, velocity, and other quantities from the `Distribution` object. + +## Next Steps + +Now that you have a conceptual overview, you're ready to get started! + +* **Installation:** If you haven't already, head to the [**Installation**](./installation.md) page. +* **Dive into Code:** The best way to learn is by doing. Follow our [**Getting Started: Your First Simulation**](./getting_started.md) tutorial to build and run a simple simulation from scratch. \ No newline at end of file diff --git a/docs/quickstart.md b/docs/quickstart.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/velocity_set.md b/docs/velocity_set.md deleted file mode 100644 index 24d20e2a..00000000 --- a/docs/velocity_set.md +++ /dev/null @@ -1,46 +0,0 @@ -# Velocity Sets - -In the Lattice Boltzmann Method (LBM), a **velocity set** defines the discrete directions in which particle distributions propagate on the lattice at each time step. These discrete velocities approximate the continuous fluid velocity space and are fundamental to accurately simulating fluid flow. - -Each velocity set specifies: -- The **dimension** (2D or 3D) of the lattice. -- The **number of discrete velocities (Q)** per lattice node. -- The **velocity vectors** representing allowed particle movement directions. -- The **weights** associated with each velocity, ensuring correct macroscopic behavior. - ---- - -## Base Class: `VelocitySet` - -All velocity sets inherit from the `VelocitySet` base class, which manages: -- The dimension and number of velocities. -- The velocity vectors and their weights. -- Backend compatibility for accelerated computation (JAX or WARP). - -Users typically instantiate predefined velocity sets rather than the base class directly. - ---- - -## What Do These Velocities Represent? - -Each velocity vector corresponds to a possible direction a fluid particle can move from a lattice node during streaming. For example, in a 2D lattice: - -- A zero vector (rest particle) means the particle stays at the node. -- Unit vectors along coordinate axes represent movement to neighboring nodes (up, down, left, right). -- Diagonal vectors represent movement to diagonal neighbors. - -The collection of these vectors must satisfy mathematical conditions to recover the Navier–Stokes equations correctly at the macroscopic scale, which govern fluid dynamics. - -The associated weights define the relative probability or influence of particles moving in each direction, balancing isotropy and stability. - ---- - -## Predefined Velocity Sets - -| Class | Dimension | Velocities (Q) | Description | -|---------|-----------|----------------|------------------------------------| -| `D2Q9` | 2D | 9 | Rest + 4 axis-aligned + 4 diagonal directions; standard for 2D flow simulations. | -| `D3Q19` | 3D | 19 | Combines rest, axis-aligned, and select diagonal directions for efficient 3D flows. | -| `D3Q27` | 3D | 27 | Full cubic lattice with all combinations of [-1,0,1] in 3D; higher isotropy and accuracy. | - ---- \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 1b2fb3b2..eb732cc9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -145,21 +145,54 @@ extra_javascript: - https://polyfill.io/v3/polyfill.min.js?features=es6 - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js +# nav: +# - XLB's home: index.md +# - Installation: installation.md +# - API & Modules: +# - Common Steps: common_steps.md +# - Constants: constants.md +# - Velocity set: velocity_set.md +# - Grid: grid.md +# - Operator: operator.md +# - Distribution: distribution.md +# - Boundary Condition: BC.md +# - Macroscopic: macroscopic.md +# - Stepper: stepper.md +# - Streaming and Collision: streaming_and_collision.md +# - Force: force.md +# - Equilibrium: equilibrium.md +# - Examples: examples.md +# - Contributing: contributing.md + + nav: - - XLB's home: index.md - - Installation: installation.md - - API & Modules: - - Common Steps: common_steps.md - - Constants: constants.md - - Velocity set: velocity_set.md - - Grid: grid.md - - Operator: operator.md - - Distribution: distribution.md - - Boundary Condition: BC.md - - Macroscopic: macroscopic.md - - Stepper: stepper.md - - Streaming and Collision: streaming_and_collision.md - - Force: force.md - - Equilibrium: equilibrium.md - - Examples: examples.md - - Contributing: contributing.md \ No newline at end of file + - 'Home': 'index.md' + - 'User Guide': + - 'Introduction': 'guide/introduction.md' + - 'Installation': 'guide/installation.md' + - 'Getting Started': 'guide/getting_started.md' + - 'Core Concepts': 'guide/concepts.md' + # - 'How-to Guides': + # - 'Set up Boundary Conditions': 'guides/how-to-bc.md' + # - 'Implement a Forcing Scheme': 'guides/how-to-force.md' + # - 'Advanced Guides': + # - 'Parallel Simulations with JAX': 'advanced/parallelism.md' + - 'API Reference': + - 'Simulation Setup': + - 'Constants': 'api/constants.md' + - 'Velocity Set': 'api/velocity_set.md' + - 'Grid': 'api/grid.md' + - 'LBM Kernel': + - 'Equilibrium': 'api/equilibrium.md' + - 'Operator': 'api/operator.md' + - 'Streaming and Collision': 'api/streaming_and_collision.md' + - 'Physics & Numerics': + - 'Boundary Condition': 'api/BC.md' + - 'Force': 'api/force.md' + - 'Simulation Control': + - 'Stepper': 'api/stepper.md' + - 'Macroscopic Variables': 'api/macroscopic.md' + - 'Distributed Computing': + - 'Distribution': 'api/distribution.md' + - 'Examples': examples.md + - 'Contributing': 'contributing.md' \ No newline at end of file From 5c1df831949e0a4f40ebb8a3a3d8db1473440a9a Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Mon, 4 Aug 2025 21:43:40 -0400 Subject: [PATCH 18/19] modify operator and collision doc page --- docs/api/operator.md | 112 ++++++++++++---------------- docs/api/streaming_and_collision.md | 112 +++++++++------------------- mkdocs.yml | 23 +----- 3 files changed, 85 insertions(+), 162 deletions(-) diff --git a/docs/api/operator.md b/docs/api/operator.md index 70dbdf8b..91b9283f 100644 --- a/docs/api/operator.md +++ b/docs/api/operator.md @@ -1,88 +1,72 @@ -# Operator +# The Operator Concept -Base class for all operators, including collision, streaming, equilibrium, etc. -Responsible for handling compute backends like JAX and NVIDIA Warp. +In XLB, an **Operator** is a fundamental building block that performs a single, well-defined action within a simulation. Think of operators as the "verbs" of the Lattice Boltzmann Method. Any distinct step in the algorithm, such as collision, streaming, or calculating equilibrium, is encapsulated within its own callable operator object. -## Overview - -The `Operator` class acts as the foundational interface for all lattice Boltzmann operators in XLB. It manages backend selection and provides a unified API to call backend-specific implementations transparently. It also facilitates registering backend implementations and handles precision policies and compute types. - -## Usage - -```python -from xlb.operator import Operator -from xlb.compute_backend import ComputeBackend -from xlb.precision_policy import PrecisionPolicy - -op = Operator( - velocity_set=None, # or specify velocity set - precision_policy=PrecisionPolicy.FP32FP32, - compute_backend=ComputeBackend.JAX, -) - -# Call the operator (calls backend-specific implementation) -result = op(some_input_data) -``` - -## Constructor +--- -```python -Operator( - velocity_set=None, - precision_policy=None, - compute_backend=None -) -``` +## Common Features (The Operator Base Class) -- velocity_set: (optional) Velocity set used by the operator; defaults to global config. -- precision_policy: (optional) Precision policy for compute and storage. -- compute_backend: (optional) Backend to run on (e.g., JAX or Warp). +The `Operator` base class provides a unified interface and a set of shared features for all operators in XLB. This ensures that every part of the simulation behaves consistently, regardless of its specific function. When you use any operator in XLB, you can rely on the following features: -Raises `ValueError` if the specified backend is unsupported. +#### 1. Backend Management +Every operator is aware of the compute backend (`JAX` or `Warp`). When an operator is called, it automatically dispatches the execution to the correct, highly optimized backend implementation without any extra effort from the user. -## Methods and Properties +#### 2. Precision Policy Awareness +Operators automatically respect the globally or locally defined `PrecisionPolicy`. They handle the data types for computation (`.compute_dtype`) and storage (`.store_dtype`) transparently, helping to balance performance and numerical accuracy. -`register_backend(backend_name)` -Decorator to register backend implementations for subclasses. +#### 3. Standardized Calling Convention +All operators are **callable** (using `()`). This provides a clean, functional API that makes it simple to compose operators and build a custom simulation loop. -`__call__(*args, callback=None, **kwargs)` -Calls the appropriate backend method, matching the subclass and backend, and passes args/kwargs. -- callback (optional): Callable to be called with the result. +### Conceptual Usage -`supported_compute_backend` -Returns a list of supported backend keys registered for this operator. +While you rarely instantiate the base `Operator` directly, all its subclasses follow the same pattern of creation and use. You first instantiate a specific operator (e.g., for BGK collision), configuring it with a velocity set and policies. Then, you call that instance with the required data to perform its action. -`backend` -Returns the actual backend module (jax.numpy or warp), depending on the current backend. +```python +from xlb.operator.collision import BGKCollision # A concrete operator subclass +from xlb.precision_policy import PrecisionPolicy +from xlb.compute_backend import ComputeBackend -`compute_dtype` -Returns the compute data type (e.g., float32, float64) according to the precision policy and backend. +# Instantiate a specific operator (e.g., for BGK collision) +collision_op = BGKCollision( + velocity_set=my_velocity_set, + precision_policy=PrecisionPolicy.FP32FP32, + compute_backend=ComputeBackend.JAX +) -`store_dtype` -Returns the storage data type according to the precision policy and backend. +# Call the operator with the required data +# It automatically runs the JAX implementation in FP32. +f_post_collision = collision_op(f_pre_collision, omega=1.8) +``` --- -## Precision Caster +## Utility Operator: `PrecisionCaster` -The **PrecisionCaster** is a utility operator for converting lattice Boltzmann data between different numeric precisions. +The `PrecisionCaster` is a prime example of a simple yet powerful utility operator provided by XLB. Its sole purpose is to convert the numerical precision of simulation data fields. ### Overview -Precision plays an important role in balancing **accuracy** and **performance** during simulations. -For example, some steps may require high precision (`float64`) for stability, while others can run efficiently in lower precision (`float32`). +Precision plays an important role in balancing **accuracy** and **performance**. Some simulation steps may require high precision (`float64`) for stability, while many others can run much faster in lower precision (`float32`), especially on GPUs. The `PrecisionCaster` handles this conversion seamlessly. -The `PrecisionCaster` operator handles this conversion seamlessly for both supported backends. +### Use Cases -### Features +- **Performance Optimization**: Run the bulk of a simulation in `FP32` for speed, but cast data to `FP64` before critical calculations. +- **Mixed-Precision Workflows**: Adapt precision dynamically based on runtime stability needs. +- **Memory Management**: Store data in a lower precision to reduce memory footprint, casting to a higher precision only when needed for computation. -- Converts distribution functions between precisions (e.g., FP32 β†’ FP64). -- Available for **JAX** and **Warp** backends. -- Works transparently with any chosen velocity set (e.g., D2Q9, D3Q19, D3Q27). -- Can be used before or after key operators to ensure data is in the desired format. +### Usage +To use the `PrecisionCaster`, you create an instance configured with the *target* precision policy you want to convert to. You then apply this operator to a data field, and it will return a new field with the converted precision. -### Use Cases +```python +from xlb.operator import PrecisionCaster -- **Performance optimization**: Run most of the simulation in FP32 for speed, while critical calculations use FP64. -- **Mixed-precision workflows**: Adapt precision dynamically depending on stability needs. -- **GPU acceleration**: Exploit lower-precision compute on GPUs while preserving accuracy where needed. +# Assume 'f_low_precision' is a field with FP32 data +# Create a caster to convert data to a higher precision (FP64) +caster_to_fp64 = PrecisionCaster( + velocity_set=my_velocity_set, + precision_policy=PrecisionPolicy.FP64FP64 # Target policy +) + +# Apply the operator to cast the field +f_high_precision = caster_to_fp64(f_low_precision) +``` diff --git a/docs/api/streaming_and_collision.md b/docs/api/streaming_and_collision.md index a4a919ce..8367e793 100644 --- a/docs/api/streaming_and_collision.md +++ b/docs/api/streaming_and_collision.md @@ -1,4 +1,4 @@ -# πŸ”„ StreamingOperator & CollisionOperator +# StreamingOperator & CollisionOperator In Lattice Boltzmann Method (LBM) simulations, the two core steps are **Streaming** and **Collision**. These operations define how distribution functions move across the grid and how they interact locally. @@ -9,109 +9,67 @@ The following operators abstract these steps: --- -## πŸš€ Stream (Base Class) +## Stream (Base Class) The `Stream` operator performs the **streaming step** by pulling values from neighboring grid points, depending on the velocity set. -### πŸ“Œ Purpose +### Purpose - Implements the **pull scheme** of LBM streaming. - Ensures support for both 2D and 3D simulations. -- Compatible with **JAX** and **Warp** backends. -### 🧩 Key Properties -| Property | Description | -|------------------------|-----------------------------------------------------------| -| `implementation_step` | `STREAMING` | -| `backend_support` | JAX and Warp | -| `supports_auxiliary_data` | ❌ No | - -### βš™οΈ JAX Implementation - -```python -@jit -def jax_implementation(self, f): - def _streaming_jax_i(f, c): - return jnp.roll(f, (c[0], c[1]), axis=(0, 1)) # for 2D - - return vmap(_streaming_jax_i, in_axes=(0, 0), out_axes=0)(f, jnp.array(self.velocity_set.c).T) -``` - -This uses jax.numpy.roll to shift distributions in each velocity direction. - -## βš™οΈ Warp Implementation - -```python -@wp.kernel -def kernel(f_0, f_1): - index = wp.vec3i(i, j, k) - _f = functional(f_0, index) - f_1[...] = _f -``` -Warp handles periodic boundary corrections and shift indexing manually within the kernel for 3D arrays. - -## πŸ’₯ Collision (Base Class) +## Collision (Base Class) The `Collision` operator defines how particles interact locally after streaming, typically by relaxing towards equilibrium. -### πŸ“Œ Purpose +### Purpose - Base class for implementing collision models. - Uses distribution function `f`, equilibrium `feq`, and local properties (`rho`, `u`, etc.). - Meant to be subclassed (e.g., for `BGK`). -## 🧩 Key Properties +## BGK (Bhatnagar–Gross–Krook) -| Property | Description | -|------------------------|----------------------------------| -| `implementation_step` | `COLLISION` | -| `backend_support` | JAX and Warp | -| `supports_auxiliary_data` | βœ… Yes (e.g., `omega`) | +- **Concept**: BGK is a common collision model where the post-collision distribution is calculated by relaxing toward equilibrium at a single relaxation rate. +- **When to use**: + - Standard fluid simulations. + - Good balance of performance and accuracy. -## πŸ§ͺ BGK: A Subclass of Collision +--- -**BGK** (Bhatnagar–Gross–Krook) is a common collision model where the post-collision distribution is calculated by relaxing toward equilibrium. +### ForcedCollision -### βš™οΈ JAX Implementation +- **Concept**: Extends BGK by including external forces (such as gravity, pressure gradients, or body accelerations). +- **When to use**: + - Flows influenced by external fields. + - Problems where force-driven effects are important. -```python -@jit -def jax_implementation(self, f, feq, rho, u, omega): - fneq = f - feq - return f - self.compute_dtype(omega) * fneq -``` +--- +### KBC (Karlin–BΓΆsch–Chikatamarla) -### βš™οΈ Warp Implementation +- **Concept**: A more advanced model that improves numerical stability and accuracy, especially for high Reynolds number flows. +- **When to use**: + - Simulations at high Reynolds numbers. + - Turbulent or under-resolved flows where BGK may become unstable. -```python -@wp.func -def functional(f, feq, rho, u, omega): - fneq = f - feq - return f - dtype(omega) * fneq -``` -The Warp kernel loads and stores distribution values per node and performs the same BGK operation element-wise. +--- -### πŸ›  Backend Support Summary +## Summary of Support -| Operator | JAX Support | Warp Support | Streaming | Collision | Supports Aux Data | -|------------|-------------|--------------|-----------|-----------|------------------------| -| Stream | βœ… Yes | βœ… Yes | βœ… Yes | ❌ No | ❌ No | -| Collision | βœ… Yes | βœ… Yes | ❌ No | βœ… Yes | βœ… Yes | -| BGK | βœ… Yes | βœ… Yes | ❌ No | βœ… Yes | βœ… Yes (omega) | -| ForcedCollision | βœ… Yes | βœ… Yes | ❌ No | βœ… Yes | βœ… Yes (force vector) | -| KBC | βœ… Yes | βœ… Yes | ❌ No | βœ… Yes | βœ… Yes | +| Operator | JAX Support | Warp Support | Typical Use Case | +|-----------------|-------------|--------------|------------------------------------------| +| Stream | Yes | Yes | Particle propagation | +| BGK | Yes | Yes | Standard fluid simulations | +| ForcedCollision | Yes | Yes | Flows with external forces | +| KBC | Yes | Yes | High Reynolds number / turbulent flows | --- -### πŸ—‚ Registry - -All operator subclasses are registered via the Operator base class using decorators: - -```python -@Operator.register_backend(ComputeBackend.JAX) -def jax_implementation(...) -``` +## Choosing the Right Operator -This allows dynamic backend dispatch at runtime. \ No newline at end of file +- Start with **BGK** for most general-purpose LBM simulations. +- Use **ForcedCollision** if external forces significantly affect your system. +- Switch to **KBC** if you need more stability at high Reynolds numbers or for turbulent flows. +- The **Stream** operator is always required to handle propagation. diff --git a/mkdocs.yml b/mkdocs.yml index eb732cc9..a09ea359 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -145,25 +145,6 @@ extra_javascript: - https://polyfill.io/v3/polyfill.min.js?features=es6 - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js -# nav: -# - XLB's home: index.md -# - Installation: installation.md -# - API & Modules: -# - Common Steps: common_steps.md -# - Constants: constants.md -# - Velocity set: velocity_set.md -# - Grid: grid.md -# - Operator: operator.md -# - Distribution: distribution.md -# - Boundary Condition: BC.md -# - Macroscopic: macroscopic.md -# - Stepper: stepper.md -# - Streaming and Collision: streaming_and_collision.md -# - Force: force.md -# - Equilibrium: equilibrium.md -# - Examples: examples.md -# - Contributing: contributing.md - nav: - 'Home': 'index.md' @@ -183,8 +164,8 @@ nav: - 'Velocity Set': 'api/velocity_set.md' - 'Grid': 'api/grid.md' - 'LBM Kernel': - - 'Equilibrium': 'api/equilibrium.md' - 'Operator': 'api/operator.md' + - 'Equilibrium': 'api/equilibrium.md' - 'Streaming and Collision': 'api/streaming_and_collision.md' - 'Physics & Numerics': - 'Boundary Condition': 'api/BC.md' @@ -195,4 +176,4 @@ nav: - 'Distributed Computing': - 'Distribution': 'api/distribution.md' - 'Examples': examples.md - - 'Contributing': 'contributing.md' \ No newline at end of file + - 'Contributing': 'contributing.md' From d00c2f66c74e704ffe7c8ddb23f671266537e6a5 Mon Sep 17 00:00:00 2001 From: Medyan Naser Date: Wed, 6 Aug 2025 20:43:16 -0400 Subject: [PATCH 19/19] remove unused files --- docs/api_reference.md | 216 ------------------------------------------ docs/index2.md | 193 ------------------------------------- docs/quickstart.md | 0 docs/tutorials.md | 3 - 4 files changed, 412 deletions(-) delete mode 100644 docs/api_reference.md delete mode 100644 docs/index2.md delete mode 100644 docs/quickstart.md delete mode 100644 docs/tutorials.md diff --git a/docs/api_reference.md b/docs/api_reference.md deleted file mode 100644 index 4da7eaca..00000000 --- a/docs/api_reference.md +++ /dev/null @@ -1,216 +0,0 @@ -# XLB API Reference - -XLB is a flexible and performant lattice Boltzmann fluid solver built for multi-backend (JAX and Warp) simulation. This reference provides a structured overview of how to use the API, based on working code examples. - ---- - - -## Overview - -XLB is structured around a modular design: - -- **Velocity Sets:** e.g., `D2Q9`, `D3Q19`, `D3Q27` -- **Compute Backends:** `JAX`, `WARP` -- **Precision Policies:** Controls floating point behavior (`FP32FP32`, `FP64FP64`, etc.) -- **Grid Factory:** Creates simulation domains -- **Operators:** Include steppers, boundary conditions, macroscopic quantity extractors -- **Distribute:** JAX multi-GPU or distributed computing support - ---- - -## Simulation Pipeline - -### 1. Initialization - -```python -import xlb -from xlb.compute_backend import ComputeBackend -from xlb.precision_policy import PrecisionPolicy - -backend = ComputeBackend.JAX # or ComputeBackend.WARP -precision = PrecisionPolicy.FP32FP32 -velocity_set = xlb.velocity_set.D3Q19( - precision_policy=precision, - compute_backend=backend, -) - -xlb.init( - velocity_set=velocity_set, - default_backend=backend, - default_precision_policy=precision, -) -``` ---- - -### 2. Grid Creation -```python -from xlb.grid import grid_factory - -grid_shape = (64, 64, 64) -grid = grid_factory(grid_shape, compute_backend=backend) -``` - -### 3. Boundary Indexing -```python -box = grid.bounding_box_indices(remove_edges=True) - -inlet = box["left"] -outlet = box["right"] -walls = [box["top"][i] + box["bottom"][i] for i in range(velocity_set.d)] -``` -Use numpy.unique() or list comprehensions to merge sets. - -### 4. Boundary Conditions - -From xlb.operator.boundary_condition, supported boundary conditions include: -FullwayBounceBackBC -HalfwayBounceBackBC -RegularizedBC -ExtrapolationOutflowBC - -**Defining a Dynamic Velocity Profile** -```python -@wp.func -def profile(index: wp.vec3i): - return wp.vec(0.05, 0.0, 0.0, length=1) - -bc_inlet = RegularizedBC("velocity", profile=profile, indices=inlet) -``` -**Defining a Static Velocity** -```python -bc_wall = RegularizedBC("velocity", prescribed_value=(0.0, 0.0, 0.0), indices=walls) -``` -Combine: -```python -boundary_conditions = [bc_wall, bc_inlet, bc_outlet] -``` - - -### 5. Stepper Setup - -from xlb.operator.stepper import IncompressibleNavierStokesStepper -```python -stepper = IncompressibleNavierStokesStepper( - grid=grid, - boundary_conditions=boundary_conditions, - collision_type="BGK", # or "KBC" - force_vector=force_vector, # Optional -) -``` - -### 6. Field Preparation -```python -f_0, f_1, bc_mask, missing_mask = stepper.prepare_fields() - -from xlb.helper import initialize_eq - -f_0 = initialize_eq( - f_0, grid, velocity_set, precision, backend, u=initial_velocity -) -``` - -### 7. Running the Simulation -```python -for step in range(num_steps): - f_0, f_1 = stepper(f_0, f_1, bc_mask, missing_mask, omega, step) - f_0, f_1 = f_1, f_0 # Swap buffers - - if step % post_process_interval == 0: - post_process(step, f_0) -``` - -### 8. Post-Processing -```python -from xlb.operator.macroscopic import Macroscopic - -macro = Macroscopic( - compute_backend=backend, - precision_policy=precision, - velocity_set=velocity_set -) -rho, u = macro(f_current) -``` -Saving fields: -```python -from xlb.utils import save_image, save_fields_vtk - -save_image(u[0][:, mid_y, :], timestep=step) -save_fields_vtk({"u_x": u[0], "rho": rho[0]}, timestep=step) -``` - -## Distributing Computation -```python -from xlb.distribute import distribute - -stepper = IncompressibleNavierStokesStepper(...) -stepper = distribute(stepper, grid, velocity_set) -``` -⚠️ Note: Distributed mode requires ComputeBackend.JAX. Warp is not supported. - -## Supported Velocity Sets - -| Velocity Set | Dimensions | Use Case | -|--------------|------------|-----------------| -| D2Q9 | 2D | Benchmark cases | -| D3Q19 | 3D | General use | -| D3Q27 | 3D | High accuracy | - -**Create a velocity set:** - -```python -velocity_set = xlb.velocity_set.D3Q27(precision_policy, compute_backend) -``` - -## Backends and Precision Policies - -### Compute Backends - -- `ComputeBackend.JAX`: JAX-based backend (CPU/GPU) -- `ComputeBackend.WARP`: CUDA-accelerated backend via NVIDIA Warp - -### Precision Policies - -| Policy | Compute | Storage | -|-----------|---------|---------| -| FP32FP32 | float32 | float32 | -| FP64FP64 | float64 | float64 | - -> Use these based on hardware support and performance needs. - - -## Utilities - -- `save_image(field_slice, timestep)` - Saves 2D PNG slices of a field. - -- `save_fields_vtk(fields, timestep)` - Outputs full 3D VTK data. - -- `initialize_eq(...)` - Initializes distributions using macroscopic profiles. - -- `wp.to_jax(warp_array)` - Converts a Warp array to a JAX ndarray. - -- `vonKarman_loglaw_wall(yplus)` - Returns the analytical log-law velocity profile for wall-bounded flows. - ---- - -## Appendix: Example Presets - -### Lid-Driven Cavity - -- Uses `D2Q9` -- Regularized boundary condition for inlet -- Supports distributed setup - -### Channel Flow - -- Uses external forcing via `force_vector` -- Includes log-law analysis and DNS reference data - -### Obstacle Flow - -- Demonstrates bounce-back boundary condition on an internal obstacle -- Shows custom mask creation for complex geometries diff --git a/docs/index2.md b/docs/index2.md deleted file mode 100644 index 2f77faf9..00000000 --- a/docs/index2.md +++ /dev/null @@ -1,193 +0,0 @@ -[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) -[![GitHub star chart](https://img.shields.io/github/stars/Autodesk/XLB?style=social)](https://star-history.com/#Autodesk/XLB) -

- -

- -# XLB: A Differentiable Massively Parallel Lattice Boltzmann Library in Python for Physics-Based Machine Learning - -πŸŽ‰ **Exciting News!** πŸŽ‰ XLB version 0.2.0 has been released, featuring a complete rewrite of the library and introducing support for the NVIDIA Warp backend! -XLB can now be installed via pip: `pip install xlb`. - -XLB is a fully differentiable 2D/3D Lattice Boltzmann Method (LBM) library that leverages hardware acceleration. It supports [JAX](https://github.com/google/jax) and [NVIDIA Warp](https://github.com/NVIDIA/warp) backends, and is specifically designed to solve fluid dynamics problems in a computationally efficient and differentiable manner. Its unique combination of features positions it as an exceptionally suitable tool for applications in physics-based machine learning. With the new Warp backend, XLB now offers state-of-the-art performance for even faster simulations. - -## Getting Started -To get started with XLB, you can install it using pip: -```bash -pip install xlb -``` - -To install the latest development version from source: - -```bash -pip install git+https://github.com/Autodesk/XLB.git -``` - -The changelog for the releases can be found [here](https://github.com/Autodesk/XLB/blob/main/CHANGELOG.md). - -For examples to get you started please refer to the [examples](https://github.com/Autodesk/XLB/tree/main/examples) folder. - -## Accompanying Paper - -Please refer to the [accompanying paper](https://doi.org/10.1016/j.cpc.2024.109187) for benchmarks, validation, and more details about the library. - -## Citing XLB - -If you use XLB in your research, please cite the following paper: - -``` -@article{ataei2024xlb, - title={{XLB}: A differentiable massively parallel lattice {Boltzmann} library in {Python}}, - author={Ataei, Mohammadmehdi and Salehipour, Hesam}, - journal={Computer Physics Communications}, - volume={300}, - pages={109187}, - year={2024}, - publisher={Elsevier} -} -``` - -## Key Features -- **Multiple Backend Support:** XLB now includes support for multiple backends including JAX and NVIDIA Warp, providing *state-of-the-art* performance for lattice Boltzmann simulations. Currently, only single GPU is supported for the Warp backend. -- **Integration with JAX Ecosystem:** The library can be easily integrated with JAX's robust ecosystem of machine learning libraries such as [Flax](https://github.com/google/flax), [Haiku](https://github.com/deepmind/dm-haiku), [Optax](https://github.com/deepmind/optax), and many more. -- **Differentiable LBM Kernels:** XLB provides differentiable LBM kernels that can be used in differentiable physics and deep learning applications. -- **Scalability:** XLB is capable of scaling on distributed multi-GPU systems using the JAX backend, enabling the execution of large-scale simulations on hundreds of GPUs with billions of cells. -- **Support for Various LBM Boundary Conditions and Kernels:** XLB supports several LBM boundary conditions and collision kernels. -- **User-Friendly Interface:** Written entirely in Python, XLB emphasizes a highly accessible interface that allows users to extend the library with ease and quickly set up and run new simulations. -- **Leverages JAX Array and Shardmap:** The library incorporates the new JAX array unified array type and JAX shardmap, providing users with a numpy-like interface. This allows users to focus solely on the semantics, leaving performance optimizations to the compiler. -- **Platform Versatility:** The same XLB code can be executed on a variety of platforms including multi-core CPUs, single or multi-GPU systems, TPUs, and it also supports distributed runs on multi-GPU systems or TPU Pod slices. -- **Visualization:** XLB provides a variety of visualization options including in-situ on GPU rendering using [PhantomGaze](https://github.com/loliverhennigh/PhantomGaze). - -## Showcase - - -

- -

-

- On GPU in-situ rendering using PhantomGaze library (no I/O). Flow over a NACA airfoil using KBC Lattice Boltzmann Simulation with ~10 million cells. -

- - -

- -

-

- DrivAer model in a wind-tunnel using KBC Lattice Boltzmann Simulation with approx. 317 million cells -

- -

- -

-

- Airflow in to, out of, and within a building (~400 million cells) -

- -

- -

-

-The stages of a fluid density field from an initial state to the emergence of the "XLB" pattern through deep learning optimization at timestep 200 (see paper for details) -

- -
- -

- -

-

- Lid-driven Cavity flow at Re=100,000 (~25 million cells) -

- -## Capabilities - -### LBM - -- BGK collision model (Standard LBM collision model) -- KBC collision model (unconditionally stable for flows with high Reynolds number) - -### Machine Learning - -- Easy integration with JAX's ecosystem of machine learning libraries -- Differentiable LBM kernels -- Differentiable boundary conditions - -### Lattice Models - -- D2Q9 -- D3Q19 -- D3Q27 (Must be used for KBC simulation runs) - -### Compute Capabilities -- Single GPU support for the Warp backend with state-of-the-art performance -- Distributed Multi-GPU support using the JAX backend -- Mixed-Precision support (store vs compute) -- Out-of-core support (coming soon) - -### Output - -- Binary and ASCII VTK output (based on PyVista library) -- In-situ rendering using [PhantomGaze](https://github.com/loliverhennigh/PhantomGaze) library -- [Orbax](https://github.com/google/orbax)-based distributed asynchronous checkpointing -- Image Output -- 3D mesh voxelizer using trimesh - -### Boundary conditions - -- **Equilibrium BC:** In this boundary condition, the fluid populations are assumed to be in at equilibrium. Can be used to set prescribed velocity or pressure. - -- **Full-Way Bounceback BC:** In this boundary condition, the velocity of the fluid populations is reflected back to the fluid side of the boundary, resulting in zero fluid velocity at the boundary. - -- **Half-Way Bounceback BC:** Similar to the Full-Way Bounceback BC, in this boundary condition, the velocity of the fluid populations is partially reflected back to the fluid side of the boundary, resulting in a non-zero fluid velocity at the boundary. - -- **Do Nothing BC:** In this boundary condition, the fluid populations are allowed to pass through the boundary without any reflection or modification. - -- **Zouhe BC:** This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. -- **Regularized BC:** This boundary condition is used to impose a prescribed velocity or pressure profile at the boundary. This BC is more stable than Zouhe BC, but computationally more expensive. -- **Extrapolation Outflow BC:** A type of outflow boundary condition that uses extrapolation to avoid strong wave reflections. - -- **Interpolated Bounceback BC:** Interpolated bounce-back boundary condition for representing curved boundaries. - -## Roadmap - -### Work in Progress (WIP) -*Note: Some of the work-in-progress features can be found in the branches of the XLB repository. For contributions to these features, please reach out.* - - - 🌐 **Grid Refinement:** Implementing adaptive mesh refinement techniques for enhanced simulation accuracy. - - - πŸ’Ύ **Out-of-Core Computations:** Enabling simulations that exceed available GPU memory, suitable for CPU+GPU coherent memory models such as NVIDIA's Grace Superchips (coming soon). - - -- ⚑ **Multi-GPU Acceleration using [Neon](https://github.com/Autodesk/Neon) + Warp:** Using Neon's data structure for improved scaling. - -- πŸ—œοΈ **GPU Accelerated Lossless Compression and Decompression**: Implementing high-performance lossless compression and decompression techniques for larger-scale simulations and improved performance. - -- 🌑️ **Fluid-Thermal Simulation Capabilities:** Incorporating heat transfer and thermal effects into fluid simulations. - -- 🎯 **Adjoint-based Shape and Topology Optimization:** Implementing gradient-based optimization techniques for design optimization. - -- 🧠 **Machine Learning Accelerated Simulations:** Leveraging machine learning to speed up simulations and improve accuracy. - -- πŸ“‰ **Reduced Order Modeling using Machine Learning:** Developing data-driven reduced-order models for efficient and accurate simulations. - - -### Wishlist -*Contributions to these features are welcome. Please submit PRs for the Wishlist items.* - -- 🌊 **Free Surface Flows:** Simulating flows with free surfaces, such as water waves and droplets. - -- πŸ“‘ **Electromagnetic Wave Propagation:** Simulating the propagation of electromagnetic waves. - -- πŸ›©οΈ **Supersonic Flows:** Simulating supersonic flows. - -- 🌊🧱 **Fluid-Solid Interaction:** Modeling the interaction between fluids and solid objects. - -- 🧩 **Multiphase Flow Simulation:** Simulating flows with multiple immiscible fluids. - -- πŸ”₯ **Combustion:** Simulating combustion processes and reactive flows. - -- πŸͺ¨ **Particle Flows and Discrete Element Method:** Incorporating particle-based methods for granular and particulate flows. - -- πŸ”§ **Better Geometry Processing Pipelines:** Improving the handling and preprocessing of complex geometries for simulations. - -This is not wanted \ No newline at end of file diff --git a/docs/quickstart.md b/docs/quickstart.md deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/tutorials.md b/docs/tutorials.md deleted file mode 100644 index ed8ec410..00000000 --- a/docs/tutorials.md +++ /dev/null @@ -1,3 +0,0 @@ -# Tutorials - -For examples to get you started please refer to the [examples](https://github.com/Autodesk/XLB/tree/main/examples) folder. \ No newline at end of file