Source code for astronomix._spatial_operators._differencing

"""
High-order finite-difference operators on interface-defined fields.

Provides the 6th-order interface-to-centre derivative used by the
finite-difference (constrained-transport) backend and the magnetic-field
divergence built from it.
"""

# general
from functools import partial

# jax
import jax
import jax.numpy as jnp

# astronomix functions
from astronomix._stencil_operations._stencil_operations import _shift


[docs] @partial(jax.jit, static_argnames=["axis"]) def finite_difference_int6(f_int, axis): """ High-order FD derivative, assumed f defined at interfaces, and the i-th index corresponds to the i+1/2 interface. The finite difference formula is: df/dx at i = c1 * (f_{i+1/2} - f_{i-1/2}) + c2 * (f_{i+3/2} - f_{i-3/2}) + c3 * (f_{i+5/2} - f_{i-5/2}) Note that the i+1/2 interface corresponds to index i in the array. 6th order: c1 = 75/64, c2 = -25/384, c3 = 3/640 4th order: c1 = 9/8, c2 = -1/24, c3 = 0 """ c1, c2, c3 = 75.0 / 64.0, -25.0 / 384.0, 3.0 / 640.0 return ( c1 * (f_int - _shift(f_int, 1, axis=axis)) + c2 * (_shift(f_int, -1, axis=axis) - _shift(f_int, 2, axis=axis)) + c3 * (_shift(f_int, -2, axis=axis) - _shift(f_int, 3, axis=axis)) )
@jax.jit def _interface_field_divergence(bx_int, by_int, bz_int, grid_spacing): """ Compute the divergence of the magnetic field defined at interfaces using finite difference. Args: bx_int: Magnetic field in x-direction at x interfaces. by_int: Magnetic field in y-direction at y interfaces. bz_int: Magnetic field in z-direction at z interfaces. grid_spacing: Grid spacing (assumed uniform in all directions). Returns: Divergence of the magnetic field at cell centers. """ d_bx_dx = finite_difference_int6(bx_int, axis=0) / grid_spacing d_by_dy = finite_difference_int6(by_int, axis=1) / grid_spacing d_bz_dz = finite_difference_int6(bz_int, axis=2) / grid_spacing div_b = d_bx_dx + d_by_dy + d_bz_dz return div_b