InterENO#

class fridom.framework.grid.cartesian.eno_interpolation.InterENO(order: int = 5, method: Literal['pointwise', 'cell_average'] = 'pointwise')[source]#

Bases: InterpolationModule

ENO interpolation module.

Description#

Let’s consider a field :math: f(x) which cell averages are known at the grid points :math: x_{i+1/2} and we want to interpolate the field at the grid points :math: x_{i+1}:

                                      Interpolate here
                                            v
  | x_{i-1-1/2} |  x_{i-1/2}  |  x_{i+1/2}  | x_{i+1+1/2} | x_{i+2+1/2} |
  ^             ^             ^             ^             ^             ^
x_{i-2}      x_{i-1}        x_{i}        x_{i+1}      x_{i+2}         x_{i+3}

For this, we first select a stencil of size :math: n+1 that contains the grid points :math: x_{i-1/2} and :math: x_{i+1/2} based on the smoothness of the field. For this we need to store the store the start grid point of the stencil, for more details see the compute_start_of_stencil method.

Once the stencil is selected, we interpolate the field either pointwise (for finite difference methods) or cell average (for finite volume methods) using polynomial interpolation.

Parameters#

orderint, optional

The order of the ENO interpolation. Default is 5.

methodstr, optional

The method of interpolation. Can be either “pointwise” or “cell_average”. Default is “pointwise”. “pointwise” for finite difference methods. It will treat the function values as pointwise values. “cell_average” for finite volume methods. It will treat the function values as cell averages and construct a polynomial which cell averages are equal to the cell averages of the field at the grid points.

References#

[1] Shu, Chi-Wang. „Essentially Non-Oscillatory and Weighted Essentially Non-Oscillatory Schemes for Hyperbolic Conservation Laws“. In Advanced Numerical Approximation of Nonlinear Hyperbolic Equations: Lectures given at the 2nd Session of the Centro Internazionale Matematico Estivo (C.I.M.E.) Held in Cetraro, Italy, June 23–28, 1997

__init__(order: int = 5, method: Literal['pointwise', 'cell_average'] = 'pointwise') None[source]#

Methods

__init__([order, method])

compute_polynomial_coefficients_cell_average(...)

Polynomial coefficients for the ENO interpolation for cell averages.

compute_polynomial_coefficients_pointwise(...)

Polynomial coefficients for the ENO interpolation for pointwise values.

compute_start_of_stencil(f, axis, destination)

Compute the start of the stencil for the ENO interpolation.

disable()

Disable the module.

enable()

Enable the module.

interpolate(f, destination)

Interpolate the field to the destination position.

is_enabled()

Whether the module is enabled or not.

reset()

Stop and start the module.

setup(mset[, setup_mode])

Set the module up.

start()

Start the module.

stop()

Stop the module.

update(mz)

Update the model state.

Attributes

diff_module

The differentiation module to be used by this module.

grid

The grid of the model settings.

info

Return a dictionary with information about the time stepper.

interp_module

The interpolation module to be used by this module.

is_setup

Whether the module is set up.

mset

The model settings.

name

required_halo

The required halo points for this module.

name = 'ENO Interpolation'#
compute_polynomial_coefficients_pointwise(stencil_size: int) ndarray[source]#

Polynomial coefficients for the ENO interpolation for pointwise values.

Parameters#

stencil_sizeint

The size of the stencil.

Returns#

np.ndarray

The polynomial coefficients for the ENO interpolation.

Description#

We consider a stencil of size \(n+1\) with grid positions \(x_{i+1/2}\). For a function \(f(x)\) we have the function values at the grid points \(x_{i+1/2}\):

 |    x_{1/2}    |   x_{1+1/2}   |   x_{2+1/2}   |
x_0             x_1             x_2             x_3
      f_{1/2}        f_{1+1/2}       f_{2+1/2}

We search for a polynomial \(p(x)\) of order \(n\) such that the function value is equal to \(f_{i+1/2}\) at the grid points:

\[p(x_{i+1/2}) = f_{i+1/2}\]

Such a polynomial can be constructed using the lagrange interpolation polynomial \(\ell_i(x)\):

\[p(x) = \sum_{i=0}^{n} f_{i+1/2} \ell_i(x) \quad \text{with} \quad \ell_i(x) = \prod_{j=0, j \neq i}^{n} \frac{x - x_{j+1/2}}{x_{i+1/2} - x_{j+1/2}}\]

Hence, at the grid points \(x_k\), we have:

\[p(x_k) = \sum_{i=0}^{n} c_{ki} f_{i+1/2} \quad \text{with} \quad c_{ki} = \prod_{j=0, j \neq i}^{n} \frac{x_k - x_{j+1/2}}{x_{i+1/2} - x_{j+1/2}}\]

for a uniform grid with \(x_i = i \Delta x\), the coefficients \(c_{ki}\) can be computed as

\[c_{ki} = \prod_{j=0, j \neq i}^{n} \frac{k - j - 1/2}{i - j}\]
compute_polynomial_coefficients_cell_average(stencil_size: int) ndarray[source]#

Polynomial coefficients for the ENO interpolation for cell averages.

Parameters#

stencil_sizeint

The size of the stencil.

Returns#

np.ndarray

The polynomial coefficients for the ENO interpolation.

Description#

We follow Shu (1998) to compute reconstruction coefficients. For this, we consider a stencil of size \(n+1\) with grid positions \(x_i\). For a function \(f(x)\) cell averages are known at the grid points \(x_{i+1/2}\):

 |    x_{1/2}    |   x_{1+1/2}   |   x_{2+1/2}   |
x_0             x_1             x_2             x_3
      f_{1/2}        f_{1+1/2}       f_{2+1/2}

with the cell averages given by

\[f_{i+1/2} = \frac{1}{x_{i+1} - x_i} \int_{x_i}^{x_{i+1}} f(x) dx\]

We search for a polynomial \(p(x)\) of order \(n-1\) such that the cell averaged value is equal to \(f_{i+1/2}\) at the grid points:

\[f_{i+1/2} = \frac{1}{x_{i+1} - x_i} \int_{x_i}^{x_{i+1}} p(x) dx\]

We now evaluate the integral of \(f(x)\) at the positions \(x_i\):

\[F_i = F(x_i) = \int_{x_0}^{x_i} f(x) dx = F_0 + \sum_{m=0}^{i-1} f_{m+1/2} (x_{m+1} - x_m)\]

The integration constant \(F_0\) does not matter and can be set to zero (\(F_0 = 0\)). We now define the polynomial \(P(x)\) using the lagrange interpolation polynomial \(\ell_i(x)\):

\[P(x) = \sum_{i=0}^{n} F_i \ell_i(x) \quad \text{with} \quad \ell_i(x) = \prod_{j=0, j \neq i}^{n} \frac{x - x_j}{x_i - x_j}\]

This can be rewritten as

\[\begin{split}\begin{align*} P(x) &= \sum_{i=1}^{n} \sum_{m=0}^{i-1} f_{m+1/2} (x_{m+1} - x_m) \ell_i(x) \\ &= \sum_{i=0}^{n-1} f_{i+1/2} \sum_{m=i+1}^{n} (x_{i+1} - x_i) \ell_m(x) \end{align*}\end{split}\]

By construction, the polynomial given by \(p(x) = P'(x)\) satisfies

\[\frac{1}{x_{i+1} - x_i} \int_{x_i}^{x_{i+1}} p(x) dx = \frac{1}{x_{i+1} - x_i} (P(x_{i+1}) - P(x_i)) = \frac{1}{x_{i+1} - x_i} (F_{i+1} - F_i) = f_{i+1/2}\]

which is the desired result. The reconstruction at the positions \(x_{k}\) are then given by

\[p(x_k) &= \sum_{i=0}^{n-1} c_{ki} f_{i+1/2} \quad \text{with} \quad c_{ki} = \sum_{m=i+1}^{n} (x_{i+1} - x_i) \left. \frac{d}{dx} \ell_m(x) \right|_{x=x_k}\]

The derivative of the lagrange polynomial is given by

\[\frac{d}{dx} \ell_m(x) = \sum_{j=0, j \neq m}^{n} \frac{1}{x_m - x_j} \prod_{r=0, r \neq m, j}^{n} \frac{x - x_r}{x_m - x_r}\]

The coefficients \(c_{ki}\) are then given by

\[c_{ki} = \sum_{m=i+1}^{n} \sum_{j=0, j \neq m}^{n} \frac{x_{m+1} - x_m}{x_m - x_j} \prod_{r=0, r \neq m, j}^{n} \frac{x_k - x_r}{x_m - x_r}\]

Or, on a uniform grid with \(x_i = i \Delta x\):

\[c_{ki} = \sum_{m=i+1}^{n} \sum_{j=0, j \neq m}^{n} \frac{1}{m - j} \prod_{r=0, r \neq m, j}^{n} \frac{k - r}{m - r}\]
interpolate(f: ScalarField, destination: Position) ScalarField[source]#

Interpolate the field to the destination position.

Parameters#

ffr.ScalarField

The field to interpolate.

destinationfr.grid.Position

The position to interpolate to.

Returns#

fr.ScalarField

The interpolated field.

compute_start_of_stencil(f: ScalarField, axis: int, destination: AxisPosition) None[source]#

Compute the start of the stencil for the ENO interpolation.

Description#

We start with a stencil of size 2 that contains function values \(f_i\) and \(f_{i+1}\) at the grid points \(x_{i}\) and \(x_{i+1}\), we want to interpolate to the grid point \(x_{i+1/2}\):

|    x_i    |  x_{i+1}  |
|    f_i    |  f_{i+1}  |
            ^
    Interpolate here

To do this, we want to increase the stencil size, so that it contains \(n+1\) grid points, where \(n\) is the aimed order of the interpolation. The selection of the stencil is based on the smoothness of the field, we will later explain how we decide whether to include the next or previous grid point. For now, we assume for example that our stencil also one grid point to the left and two grid points to the right, so that we have a stencil of size 5 (order 4):

| x_{i-1} |   x_i   |  x_{i+1}  | x_{i+2}  | x_{i+3} |
                    ^
            Interpolate here

This function returns for every grid point \(x_{i}\) a list of indices of the stencil for that grid point, e.g. for the above example, the stencil index list for \(x_{i}\) would be [i-1, i, i+1, i+2, i+3]. Furthermore, we return the index of the coefficients for the polynomial interpolation, which is for the grid point \(x_{i}\) in the above example 2 (0 would be to the left of \(x_{i-1}\), 1 would be at left of \(x_{i}\) and 2 would be at the right of \(x_{i}\)).

Choosing the stencil#

Let’s assume we have the following stencil of size 3:

Function f:          |  f_{i-1}  |    f_i    |  f_{i+1}  |
First derivative:             f'_{i-1}     f'_{i}
Second derivative:                 f''_{i-1}

As we can see, from this stencil, we can compute the first and second derivative of the function. To compute the third derivative, we either need to include the previous grid point \(f_{i-2}\) or the next grid point \(f_{i+2}\), from which we obtain the two derivatives \(f'''_{i-2}\) and \(f'''_{i}\). We can now compare the absolute values of the two derivatives and choose the one with the smaller absolute value, and include the corresponding grid point in the stencil, so for example if \(|f'''_{i-2}| < |f'''_{i}|\), we include the grid point \(x_{i-2}\) in the stencil and repeat the process until we have a stencil of size \(n+1\).

We define the derivative of the function as:

\[f^{(n)}_{i} = f^{(n-1)}_{i+1} - f^{(n-1)}_{i}\]

As we work with uniform grids, we do not need to divide by the grid size \(\Delta x\), as it is the same for all grid points.

Returns#

list[tuple[np.ndarray[int]]]

A list of indices of the stencil for every grid point.

np.ndarray[int]

The index of the coefficients for the polynomial interpolation.