sph_kernels module

Provides classes representing SPH kernels to smooth particles onto the pixel grid.

class martini.sph_kernels.AdaptiveKernel(*args: tuple, **kwargs: dict)[source]

Bases: object

Pre-configured adaptive kernels have been implemented in v2.0.3.

See the SPH Kernels page in the documentation for details. You most likely want to use WendlandC2Kernel(), WendlandC6Kernel(), CubicSplineKernel() or QuarticSplineKernel() where you previously used AdaptiveKernel(...).

Parameters:
  • *args (any) – Any arguments, this class just raises an exception on attempted use.

  • **kwargs (any) – Any keyword arguemnts; this class just raises an exception on attempted use.

class martini.sph_kernels.CubicSplineKernel[source]

Bases: _AdaptiveKernel

Implementation of the cubic spline (M4) kernel integral.

The cubic spline is the ‘classic’ SPH kernel. The exact integral is usually too slow to be practical; the implementation here approximates the kernel amplitude as constant across the pixel, which converges to within 1% of the exact integral provided the SPH smoothing lengths are at least 1.16 pixels in size.

The cubic spline kernel is here defined as:

\[\begin{split}W(q) = \frac{8}{\pi}\begin{cases} (1 - 6q^2(1 - \frac{q}{2})) &{\rm for}\;0 \leq q < \frac{1}{2}\\ 2(1 - q)^3 &{\rm for}\;\frac{1}{2} \leq q < 1\\ 0 &{\rm for}\;q \geq 1 \end{cases}\end{split}\]

This class falls back to the DiracDeltaKernel and GaussianKernel when the approximation used for the surface integral of the cubic spline kernel is not accurate to within better than 1%. To strictly use the cubic spline kernel, use _CubicSplineKernel instead.

eval_kernel(r: ndarray | Annotated[Quantity, Unit('arcsec')], h: ndarray | Annotated[Quantity, Unit('arcsec')]) Quantity | ndarray

Evaluate the kernel, handling array casting and rescaling.

Parameters:
Returns:

Kernel value at position(s) r.

Return type:

ndarray

kernel(q: ndarray) ndarray[source]

Evaluate the kernel function of the cubic spline kernel.

The cubic spline kernel is here defined as:

\[\begin{split}W(q) = \frac{8}{\pi}\begin{cases} (1 - 6q^2(1 - \frac{q}{2})) &{\rm for}\;0 \leq q < \frac{1}{2}\\ 2(1 - q)^3 &{\rm for}\;\frac{1}{2} \leq q < 1\\ 0 &{\rm for}\;q \geq 1 \end{cases}\end{split}\]
Parameters:

q (ndarray) – Dimensionless distance parameter.

Returns:

Kernel value at positions q.

Return type:

ndarray

class martini.sph_kernels.DiracDeltaKernel(size_in_fwhm: float = 1.0)[source]

Bases: _BaseSPHKernel

Implementation of a Dirac-delta kernel integral.

The Dirac-delta kernel is here defined as:

\[\begin{split}W(q) = \begin{cases} \infty &{\rm for}\;q = 0\\ 0 &{\rm for}\;q > 0 \end{cases}\end{split}\]
Parameters:

size_in_fwhm (float) – In principle the width of a Dirac-delta kernel is 0, but this would lead to no particles contributing to any pixels. Ideally this would be set to approximately the size of the pixel, but setting it to the smoothing length (1.0) is acceptable given the validation condition.

eval_kernel(r: ndarray | Annotated[Quantity, Unit('arcsec')], h: ndarray | Annotated[Quantity, Unit('arcsec')]) Quantity | ndarray

Evaluate the kernel, handling array casting and rescaling.

Parameters:
  • r (ndarray or Quantity) – Distance parameter, same units (if applicable) as h.

  • h (ndarray or Quantity) – Smoothing scale parameter (FWHM), same units (if applicable) as r.

Returns:

Kernel value at position(s) r.

Return type:

ndarray

kernel(q: ndarray) ndarray[source]

Evaluate the kernel function.

The Dirac-delta kernel is here defined as:

\[\begin{split}W(q) = \begin{cases} \infty &{\rm for}\;q = 0\\ 0 &{\rm for}\;q > 0 \end{cases}\end{split}\]
Parameters:

q (ndarray) – Dimensionless distance parameter.

Returns:

Kernel value at positions q.

Return type:

ndarray

class martini.sph_kernels.GaussianKernel(truncate: float = 3.0)[source]

Bases: _AdaptiveKernel

Implementation of a (truncated) Gaussian kernel integral.

Calculates the kernel integral over a pixel. The 3 integrals (along \(dx\), \(dy\), \(dz\)) are evaluated exactly, however the truncation is implemented approximately, erring on the side of integrating slightly further than the truncation radius.

The Gaussian kernel is here defined as:

\[\begin{split}W(q) = \begin{cases} (\sqrt{2\pi}\sigma)^{-3} \exp\left(-\frac{1}{2}\left(\frac{q}{\sigma}\right)^2\right) &{\rm for}\;0 \leq q < t\\ 0 &{\rm for}\;q > t \end{cases}\end{split}\]

with \(\sigma=(2\sqrt{2\log(2)})^{-1}\), s.t. FWHM = 1, and \(t\) being the truncation radius.

This class falls back to the DiracDeltaKernel and GaussianKernel (with large truncation) when the approximation used for the surface integral of the Gaussian kernel is not accurate to within better than 1%. To strictly use the Gaussian kernel, use _GaussianKernel instead.

Parameters:

truncate (float, optional) – Number of standard deviations at which to truncate kernel. Truncation radii <2 would lead to large errors and are not permitted.

eval_kernel(r: ndarray | Annotated[Quantity, Unit('arcsec')], h: ndarray | Annotated[Quantity, Unit('arcsec')]) Quantity | ndarray

Evaluate the kernel, handling array casting and rescaling.

Parameters:
Returns:

Kernel value at position(s) r.

Return type:

ndarray

kernel(q: ndarray) ndarray[source]

Evaluate the kernel function of the Gaussian kernel.

The Gaussian kernel is here defined as:

\[\begin{split}W(q) = \begin{cases} (\sqrt{2\pi}\sigma)^{-3} \exp\left(-\frac{1}{2}\left(\frac{q}{\sigma}\right)^2\right) &{\rm for}\;0 \leq q < t\\ 0 &{\rm for}\;q > t \end{cases}\end{split}\]

with \(\sigma=(2\sqrt{2\log(2)})^{-1}\), s.t. FWHM = 1, and \(t\) being the truncation radius.

Parameters:

q (ndarray) – Dimensionless distance parameter.

Returns:

Kernel value at positions q.

Return type:

ndarray

class martini.sph_kernels.QuarticSplineKernel[source]

Bases: _AdaptiveKernel

Implementation of the quartic spline kernel integral.

The quartic spline (M5) kernel is used in the SPHENIX scheme (e.g. in Colibre). The exact integral is usually too slow to be practical; the implementation here approximates the kernel amplitude as constant across the pixel, which converges to within 1% of the exact integral provided the SPH smoothing lengths are at least 1.2385 pixels in size.

The quartic spline kernel is here defined as:

\[\begin{split}W(q) = \frac{15625}{512\pi}\begin{cases} (1 - q)^4 - 5(\frac{3}{5} - q)^4 + 10(\frac{1}{5}-q)^4 &{\rm for}\;0 \leq q < \frac{1}{5}\\ (1 - q)^4 - 5(\frac{3}{5} - q)^4 &{\rm for}\;\frac{1}{5} \leq q < \frac{3}{5}\\ (1 - q)^4 &{\rm for}\;\frac{3}{5} \leq q < 1\\ 0 &{\rm for}\;q \geq 1 \end{cases}\end{split}\]

This class falls back to the DiracDeltaKernel and GaussianKernel when the approximation used for the surface integral of the quartic spline kernel is not accurate to within better than 1%. To strictly use the quartic spline kernel, use _QuarticSplineKernel instead.

eval_kernel(r: ndarray | Annotated[Quantity, Unit('arcsec')], h: ndarray | Annotated[Quantity, Unit('arcsec')]) Quantity | ndarray

Evaluate the kernel, handling array casting and rescaling.

Parameters:
Returns:

Kernel value at position(s) r.

Return type:

ndarray

kernel(q: ndarray) ndarray[source]

Evaluate the kernel function of the quartic spline kernel.

The quartic spline kernel is here defined as:

\[\begin{split}W(q) = \frac{15625}{512\pi}\begin{cases} (1 - q)^4 - 5(\frac{3}{5} - q)^4 + 10(\frac{1}{5}-q)^4 &{\rm for}\;0 \leq q < \frac{1}{5}\\ (1 - q)^4 - 5(\frac{3}{5} - q)^4 &{\rm for}\;\frac{1}{5} \leq q < \frac{3}{5}\\ (1 - q)^4 &{\rm for}\;\frac{3}{5} \leq q < 1\\ 0 &{\rm for}\;q \geq 1 \end{cases}\end{split}\]
Parameters:

q (ndarray) – Dimensionless distance parameter.

Returns:

Kernel value at positions q.

Return type:

ndarray

class martini.sph_kernels.WendlandC2Kernel[source]

Bases: _AdaptiveKernel

Implementation of the Wendland C2 kernel integral.

The Wendland C2 kernel is used in the EAGLE code and derivatives (not in Gadget/Gadget2!). The exact integral is usually too slow to be practical; the implementation here approximates the kernel amplitude as constant across the pixel, which converges to within 1% of the exact integral provided the SPH smoothing lengths are at least 1.51 pixels in size.

The WendlandC2 kernel is here defined as:

\[\begin{split}W(q) = \begin{cases} \frac{21}{2\pi}(1-q)^4(4q+1) &{\rm for}\;0 \leq q < 1\\ 0 &{\rm for}\;q \geq 1 \end{cases}\end{split}\]

This class falls back to the DiracDeltaKernel and GaussianKernel when the approximation used for the surface integral of the WendlandC2 kernel is not accurate to within better than 1%. To strictly use the WendlandC2 kernel, use _WendlandC2Kernel instead.

eval_kernel(r: ndarray | Annotated[Quantity, Unit('arcsec')], h: ndarray | Annotated[Quantity, Unit('arcsec')]) Quantity | ndarray

Evaluate the kernel, handling array casting and rescaling.

Parameters:
Returns:

Kernel value at position(s) r.

Return type:

ndarray

kernel(q: ndarray) ndarray[source]

Evaluate the kernel function of the WendlandC2 kernel.

The WendlandC2 kernel is here defined as:

\[\begin{split}W(q) = \begin{cases} \frac{21}{2\pi}(1-q)^4(4q+1) &{\rm for}\;0 \leq q < 1\\ 0 &{\rm for}\;q \geq 1 \end{cases}\end{split}\]
Parameters:

q (ndarray) – Dimensionless distance parameter.

Returns:

Kernel value at positions q.

Return type:

ndarray

class martini.sph_kernels.WendlandC6Kernel[source]

Bases: _AdaptiveKernel

Implementation of the Wendland C6 kernel integral.

The Wendland C6 kernel is used in the Magneticum code (not in Gadget/Gadget2!). The exact integral is usually too slow to be practical; the implementation here approximates the kernel amplitude as constant across the pixel, which converges to within 1% of the exact integral provided the SPH smoothing lengths are at least 1.29 pixels in size.

The WendlandC6 kernel is here defined as:

\[\begin{split}W(q) = \begin{cases} \frac{1365}{64 \pi} (1 - q)^8 (1 + 8q + 25q^2 + 32q^3) &{\rm for}\;0 \leq q < 1\\ 0 &{\rm for}\;q \geq 1 \end{cases}\end{split}\]

This class falls back to the DiracDeltaKernel and GaussianKernel when the approximation used for the surface integral of the WendlandC6 kernel is not accurate to within better than 1%. To strictly use the WendlandC6 kernel, use _WendlandC6Kernel instead.

eval_kernel(r: ndarray | Annotated[Quantity, Unit('arcsec')], h: ndarray | Annotated[Quantity, Unit('arcsec')]) Quantity | ndarray

Evaluate the kernel, handling array casting and rescaling.

Parameters:
Returns:

Kernel value at position(s) r.

Return type:

ndarray

kernel(q: ndarray) ndarray[source]

Evaluate the kernel function of the WendlandC6 kernel.

The WendlandC6 kernel is here defined as:

\[\begin{split}W(q) = \begin{cases} \frac{1365}{64 \pi} (1 - q)^8 (1 + 8q + 25q^2 + 32q^3) &{\rm for}\;0 \leq q < 1\\ 0 &{\rm for}\;q \geq 1 \end{cases}\end{split}\]
Parameters:

q (ndarray) – Dimensionless distance parameter.

Returns:

Kernel value at positions q.

Return type:

ndarray

martini.sph_kernels.find_fwhm(f: Callable[[ndarray], ndarray]) float[source]

Solve for the FWHM of the input function.

Intended for SPH kernels and therefore assumes maximum occurs at \(f(0)\) and symmetry around \(f(0)\).

Parameters:

f (callable) – Function for which to find the FWHM.

Returns:

FWHM of the input function.

Return type:

float