Phase functions

Phase functions are specified through their reduced Legendre moments \(\chi_\ell\) (Phase-function treatment). The zeroth moment is the normalisation and must be \(1\); allocate() sets it for you. The per-layer array phase_function_moments[l] holds \(2M\) moments (or \(2M+1\) when delta-M is enabled).

Built-in helpers

Each helper takes an optional layer index; -1 (the default) applies to all layers.

C++ / JAX

Effect

setIsotropic() / set_isotropic()

\(\chi_0 = 1\), all higher moments zero.

setRayleigh() / set_rayleigh()

\(\chi_2 = 0.1\), others zero.

setHenyeyGreenstein(g) / set_henyey_greenstein(g)

\(\chi_\ell = g^\ell\).

setDoubleHenyeyGreenstein(f, g1, g2) / set_double_henyey_greenstein(f, g1, g2)

\(\chi_\ell = f\,g_1^\ell + (1-f)\,g_2^\ell\).

cfg.setHenyeyGreenstein(0.7);       // all layers, g = 0.7
cfg.setRayleigh(0);                 // layer 0 only
cfg.setDoubleHenyeyGreenstein(0.9, 0.8, -0.5, 3);  // layer 3

Arbitrary phase functions

Fill the moment array directly. Only supply as many moments as you have; the rest stay zero:

// Custom expansion for layer l
for (int k = 0; k < n_moments; ++k)
  cfg.phase_function_moments[l][k] = chi[k];
import numpy as np
cfg.phase_function_moments[l] = np.array(chi)   # length up to 2*M (+1)

Warning

Keep \(\chi_0 = 1\). If you plan to use delta-M scaling, provide the \(2M\)-th moment as well (index 2*num_quadrature), since it defines the truncation fraction \(f\) (Using delta-M scaling).