<p align="center">
<img src="https://github.com/James-Wirth/nullgeo/releases/download/assets/kerr_starfield_hdr.png" alt="Kerr black hole" width="800">
</p>
## nullgeo
This is a general relativistic ray tracing library written in Rust.
Currently, we have implemented the Minkowski, Schwarzschild, Reissner–Nordström, Kerr, and the Ellis wormhole spacetimes.
All quantities are in geometrized units ($G = c = 1$), and we have adopted the signature $(-,+,+,+)$.
## Installation
### CLI
```
cargo install nullgeo-cli
```
### Library
```toml
[dependencies]
nullgeo = "0.2"
```
## Example Usage (with CLI)
A scene can be defined with a TOML file (see below). To render the scene, run:
```
nullgeo render scene.toml
```
### e.g. Kerr black hole, $a = 0.9M$, with accretion disk
```toml
[metric]
kind = "kerr"
mass = 1.0
spin = 0.9
[camera]
position = [-85.0, 0.0, 9.0]
fov_deg = 24.0
width = 640
height = 360
supersample = 3
supersample_max = 4
[disk]
r_out = 18.0
t_in = 10000.0
optical_depth = 2.5
aspect_ratio = 0.05
[sky]
checker_deg = 15.0
[[output]]
path = "kerr_output.png"
kind = "beauty"
exposure = 4.0
tone = "aces"
```
### Trace a single ray (for debugging)
```
nullgeo propagate --metric kerr --spin 0.9 --pos=-20,0,5 --dir=1,0,0 --out ray.csv
```
creates a file `ray.csv` containing $(\lambda, t, x, y, z, H)$.
## Theory
### Hamiltonian Formulation
The Hamiltonian for photons is
```math
H(x, p) = \tfrac{1}{2}\, g^{\mu\nu}(x)\, p_{\mu} p_{\nu}
```
subject to the null constraint $H = 0$. Hamilton's equations give the trajectory
```math
\dot{x}^{\mu} = \frac{\partial H}{\partial p_{\mu}} = g^{\mu\nu} p_{\nu} \qquad\qquad \dot{p}_{\mu} = -\frac{\partial H}{\partial x^{\mu}} = -\tfrac{1}{2} \partial_{\mu} g^{\rho\sigma} p_{\rho} p_{\sigma}
```
where the dot denotes differentiation with respect to an affine parameter $\lambda$.
### Pinhole Camera and the Local Orthonormal Frame
A local tetrad $\lbrace e_a{}^{\mu} \rbrace$ is constructed at the camera's position. The timelike basis vector is the observer's 4-velocity, $e_0{}^{\mu} = u^{\mu}$. A static observer has $u \propto \partial_t$. A set of spatial basis vectors $e_i{}^{\mu}$ can be obtained by Gram-Schmidt orthogonalization (w.r.t $g$) of three seed vectors projected into the subspace orthgonal to $u$ via the projector $h = g + u \otimes u$.
A photon with spatial direction $\mathbf{n}$ and energy $E$ has four-momentum components $p^a = E(1, n^{i})$ *in the tetrad basis*. In coordinate basis (i.e. w.r.t. the $dx^{\mu}$ for covectors or w.r.t. the $\partial_{\mu}$ for vectors), the coordinate components follow from $p_{\mu} = g_{\mu\nu} e_{a}{}^{\nu} p^{a}$.
## License
MIT or Apache-2.0