Source code for astronomix._spatial_operators._interpolate

"""
High-order interpolation between cell centres and cell faces.

Provides the 4th-order centre-to-face and 6th-order face-to-centre
interpolations, plus the point-value to cell-average correction used to retain
high-order accuracy in dimensionally split settings.
"""

# 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 interp_center_to_face(arr, axis): """ Interpolate to x-interfaces using 4th order f_{i+1/2} = (-f_{i-1} + 9f_{i} + 9f_{i+1} - f_{i+2}) / 16 The i-th array index in the output corresponds to the i+1/2 interface. """ return ( -_shift(arr, 1, axis=axis) + 9 * arr + 9 * _shift(arr, -1, axis=axis) - _shift(arr, -2, axis=axis) ) / 16.0
[docs] @partial(jax.jit, static_argnames=["axis"]) def interp_face_to_center(f_int, axis): """ 6th order interpolation from face to center. """ return ( 3 * _shift(f_int, 3, axis=axis) - 25 * _shift(f_int, 2, axis=axis) + 150 * _shift(f_int, 1, axis=axis) + 150 * f_int - 25 * _shift(f_int, -1, axis=axis) + 3 * _shift(f_int, -2, axis=axis) ) / 256.0
[docs] @partial(jax.jit, static_argnames=["axisA", "axisB"]) def point_values_to_averages(q, axisA, axisB): """ For point values q, we can approximate the cell-averaged values Q based on interpolation as Q_i = q_i + Δx^2/24 q''(x_i) - ... For point values, the second derivative can be approximated q''(x_i) = (q_{i+1} - 2 q_i + q_{i-1}) / Δx^2 Here we apply this in two dimensions. Compare Buchmüller and Helzel 2014, Eq. 12, 13. Such smoothing can be used to retain high-order accuracy in dimensionally split settings. """ smooth_x = ( _shift(q, 1, axis=axisA) - 2 * q + _shift(q, -1, axis=axisA) ) / 24.0 smooth_y = ( _shift(q, 1, axis=axisB) - 2 * q + _shift(q, -1, axis=axisB) ) / 24.0 return q + smooth_x + smooth_y
[docs] @partial(jax.jit, static_argnames=["axisA"]) def point_values_to_averages_single_axis(q, axisA): """ Single axis version of point_values_to_averages. """ smooth = ( _shift(q, 1, axis=axisA) - 2 * q + _shift(q, -1, axis=axisA) ) / 24.0 return q + smooth