Skip to content

Commit f77df1a

Browse files
committed
restructure the docs
1 parent d387c86 commit f77df1a

20 files changed

Lines changed: 670 additions & 247 deletions
File renamed without changes.

docs/api/constants.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Constants and Enums
2+
3+
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.
4+
5+
---
6+
7+
## ComputeBackend
8+
9+
Defined in `compute_backend.py`
10+
11+
```python
12+
class ComputeBackend(Enum):
13+
JAX = auto()
14+
WARP = auto()
15+
```
16+
17+
**Description:**
18+
19+
An `Enum` specifying the primary computational engine for executing simulation kernels.
20+
21+
- **`JAX`**: Use the [JAX](https://github.com/google/jax) framework for computation, enabling execution on CPUs, GPUs, and TPUs.
22+
- **`WARP`**: Use the [NVIDIA Warp](https://github.com/NVIDIA/warp) framework for high-performance GPU simulation kernels.
23+
24+
---
25+
26+
## GridBackend
27+
28+
Defined in `grid_backend.py`
29+
30+
```python
31+
class GridBackend(Enum):
32+
JAX = auto()
33+
WARP = auto()
34+
OOC = auto()
35+
```
36+
37+
**Description:**
38+
39+
An `Enum` defining the backend for grid creation and data management.
40+
41+
- **`JAX`**, **`WARP`**: The grid data resides in memory on the respective compute device.
42+
- **`OOC`**: Handles simulations where the grid data is too large to fit into memory and must be processed "out-of-core" from disk.
43+
44+
---
45+
46+
## PhysicsType
47+
48+
Defined in `physics_type.py`
49+
50+
```python
51+
class PhysicsType(Enum):
52+
NSE = auto() # Navier-Stokes Equations
53+
ADE = auto() # Advection-Diffusion Equations
54+
```
55+
56+
**Description:**
57+
58+
An `Enum` used to select the set of physical equations to be solved by the stepper.
59+
60+
- **`NSE`**: Simulates fluid dynamics governed by the incompressible Navier-Stokes equations.
61+
- **`ADE`**: Simulates transport phenomena governed by the Advection-Diffusion equation.
62+
63+
---
64+
65+
## Precision
66+
67+
Defined in `precision_policy.py`
68+
69+
```python
70+
class Precision(Enum):
71+
FP64 = auto()
72+
FP32 = auto()
73+
FP16 = auto()
74+
UINT8 = auto()
75+
BOOL = auto()
76+
```
77+
78+
**Description:**
79+
80+
An `Enum` representing fundamental data precision levels. Each member provides properties to get the corresponding data type in the target compute backend:
81+
82+
- **`.wp_dtype`**: The equivalent `warp` data type (e.g., `wp.float32`).
83+
- **`.jax_dtype`**: The equivalent `jax.numpy` data type (e.g., `jnp.float32`).
84+
85+
---
86+
87+
## PrecisionPolicy
88+
89+
Defined in `precision_policy.py`
90+
91+
```python
92+
class PrecisionPolicy(Enum):
93+
FP64FP64 = auto()
94+
FP64FP32 = auto()
95+
FP64FP16 = auto()
96+
FP32FP32 = auto()
97+
FP32FP16 = auto()
98+
```
99+
100+
**Description:**
101+
102+
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.
103+
104+
For example, `FP64FP32` specifies that calculations should be performed in high-precision `float64`, but the results are stored in memory-efficient `float32`.
105+
106+
**Utility Properties & Methods:**
107+
- **`.compute_precision`**: Returns the `Precision` enum for computation.
108+
- **`.store_precision`**: Returns the `Precision` enum for storage.
109+
- **`.cast_to_compute_jax(array)`**: Casts a JAX array to the policy's compute precision.
110+
- **`.cast_to_store_jax(array)`**: Casts a JAX array to the policy's store precision.
111+
112+
---
113+
114+
## DefaultConfig
115+
116+
Defined in `default_config.py`
117+
118+
```python
119+
@dataclass
120+
class DefaultConfig:
121+
velocity_set
122+
default_backend
123+
default_precision_policy
124+
```
125+
126+
A `dataclass` that holds the global configuration for a simulation session.
127+
128+
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.
129+
130+
```python
131+
# The xlb.init() function sets the global DefaultConfig instance
132+
xlb.init(
133+
velocity_set=D2Q9(...),
134+
default_backend=ComputeBackend.JAX,
135+
default_precision_policy=PrecisionPolicy.FP32FP32
136+
)
137+
```
File renamed without changes.
File renamed without changes.
File renamed without changes.

docs/api/grid.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Grid
2+
3+
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.
4+
5+
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).
6+
7+
---
8+
9+
## Creating a Grid
10+
11+
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.
12+
13+
```python
14+
from xlb.grid import grid_factory
15+
from xlb.compute_backend import ComputeBackend
16+
import xlb
17+
18+
# Assuming xlb.init() has been called with a default backend...
19+
20+
# Create a 2D grid for the JAX backend
21+
grid_2d = grid_factory(shape=(500, 500), compute_backend=ComputeBackend.JAX)
22+
23+
# Create a 3D grid for the Warp backend
24+
grid_3d = grid_factory(shape=(256, 128, 128), compute_backend=ComputeBackend.WARP)
25+
```
26+
27+
### `grid_factory(shape, compute_backend)`
28+
- **`shape: Tuple[int, ...]`**: A tuple defining the grid dimensions. For example, `(nx, ny)` for 2D or `(nx, ny, nz)` for 3D.
29+
- **`compute_backend: ComputeBackend`**: The backend to use (`ComputeBackend.JAX` or `ComputeBackend.WARP`). If not provided, it defaults to the backend set in `xlb.init()`.
30+
31+
32+
---
33+
34+
## Using a Grid Instance
35+
36+
Once you have a `grid` object, you can use its attributes and methods to define boundary regions and create data fields for your simulation.
37+
38+
### Attributes
39+
40+
- **`grid.shape`**: The full domain shape passed during creation (e.g., `(256, 128, 128)`).
41+
- **`grid.dim`**: The number of spatial dimensions, inferred from the shape (2 for 2D, 3 for 3D).
42+
43+
### Methods
44+
45+
#### `grid.bounding_box_indices()`
46+
47+
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.
48+
49+
```python
50+
faces = grid_2d.bounding_box_indices(remove_edges=True)
51+
52+
# faces is a dictionary with keys: 'bottom', 'top', 'left', 'right'
53+
inlet_indices = faces["left"]
54+
outlet_indices = faces["right"]
55+
56+
# Combine multiple faces to define all stationary walls
57+
wall_indices = faces["bottom"] + faces["top"]
58+
```
59+
60+
- **`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).
61+
62+
#### `grid.create_field()`
63+
64+
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}$).
65+
66+
```python
67+
# Create a field to store the D2Q9 particle distribution functions (f_i)
68+
# Cardinality is 9 because there are 9 velocities in D2Q9.
69+
f = grid_2d.create_field(cardinality=9)
70+
71+
# Create a scalar field for density (rho)
72+
rho = grid_2d.create_field(cardinality=1)
73+
74+
# Create a 2D vector field for velocity (u)
75+
u = grid_2d.create_field(cardinality=2)
76+
```
77+
78+
- **`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`.
79+
- **`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`.
80+
- **`fill_value: float = None`**: An optional value to initialize all elements of the array. Defaults to `0`.
81+
82+
---
83+
84+
## Backend-Specific Details
85+
86+
### `JaxGrid`
87+
The `JaxGrid` object is designed to be compatible with JAX's features, including multi-device parallelization via sharding.
88+
89+
### `WarpGrid`
90+
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.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)