# Stencil¶

This submodule offers functions to work with stencils in expression an offset-list form.

inverse_direction(direction)

Returns inverse i.e. negative of given direction tuple

Example

```>>> inverse_direction((1, -1, 0))
(-1, 1, 0)
```
inverse_direction_string(direction)

Returns inverse of given direction string

is_valid(stencil, max_neighborhood=None)

Tests if a nested sequence is a valid stencil i.e. all the inner sequences have the same length. If max_neighborhood is specified, it is also verified that the stencil does not contain any direction components with absolute value greater than the maximal neighborhood.

Examples

```>>> is_valid([(1, 0), (1, 0, 0)])  # stencil entries have different length
False
>>> is_valid([(2, 0), (1, 0)])
True
>>> is_valid([(2, 0), (1, 0)], max_neighborhood=1)
False
>>> is_valid([(2, 0), (1, 0)], max_neighborhood=2)
True
```
is_symmetric(stencil)

Tests for every direction d, that -d is also in the stencil

Examples

```>>> is_symmetric([(1, 0), (0, 1)])
False
>>> is_symmetric([(1, 0), (-1, 0)])
True
```
have_same_entries(s1, s2)

Checks if two stencils are the same

Examples

```>>> stencil1 = [(1, 0), (-1, 0), (0, 1), (0, -1)]
>>> stencil2 = [(-1, 0), (0, -1), (1, 0), (0, 1)]
>>> stencil3 = [(-1, 0), (0, -1), (1, 0)]
>>> have_same_entries(stencil1, stencil2)
True
>>> have_same_entries(stencil1, stencil3)
False
```
coefficient_dict(expr)

Extracts coefficients in front of field accesses in a expression.

Expression may only access a single field at a single index.

Returns

center, coefficient dict, nonlinear part where center is the single field that is accessed in expression accessed at center and coefficient dict maps offsets to coefficients. The nonlinear part is everything that is not in the form of coefficient times field access.

Examples

```>>> import pystencils as ps
>>> f = ps.fields("f(3) : double[2D]")
>>> field, coeffs, nonlinear_part = coefficient_dict(2 * f[0, 1](1) + 3 * f[-1, 0](1) + 123)
>>> assert nonlinear_part == 123 and field == f(1)
>>> sorted(coeffs.items())
[((-1, 0), 3), ((0, 1), 2)]
```
coefficients(expr)

Returns two lists - one with accessed offsets and one with their coefficients.

Same restrictions as `coefficient_dict` apply. Expression must not have any nonlinear part

```>>> import pystencils as ps
>>> f = ps.fields("f(3) : double[2D]")
>>> coff = coefficients(2 * f[0, 1](1) + 3 * f[-1, 0](1))
```
coefficient_list(expr, matrix_form=False)

Returns stencil coefficients in the form of nested lists

Same restrictions as `coefficient_dict` apply. Expression must not have any nonlinear part

Examples

```>>> import pystencils as ps
>>> f = ps.fields("f: double[2D]")
>>> coefficient_list(2 * f[0, 1] + 3 * f[-1, 0])
[[0, 0, 0], [3, 0, 0], [0, 2, 0]]
>>> coefficient_list(2 * f[0, 1] + 3 * f[-1, 0], matrix_form=True)
Matrix([
[0, 2, 0],
[3, 0, 0],
[0, 0, 0]])
```
offset_component_to_direction_string(coordinate_id, value)

Translates numerical offset to string notation.

x offsets are labeled with east ‘E’ and ‘W’, y offsets with north ‘N’ and ‘S’ and z offsets with top ‘T’ and bottom ‘B’ If the absolute value of the offset is bigger than 1, this number is prefixed.

Parameters

Examples

```>>> offset_component_to_direction_string(0, 1)
'E'
>>> offset_component_to_direction_string(1, 2)
'2N'
```
Return type

`str`

offset_to_direction_string(offsets)

Translates numerical offset to string notation. For details see `offset_component_to_direction_string()` :type offsets: `Sequence`[`int`] :param offsets: 3-tuple with x,y,z offset

Examples

```>>> offset_to_direction_string([1, -1, 0])
'SE'
>>> offset_to_direction_string(([-3, 0, -2]))
'2B3W'
```
Return type

`str`

direction_string_to_offset(direction, dim=3)

Reverse mapping of `offset_to_direction_string()`

Parameters

Examples

```>>> direction_string_to_offset('NW', dim=3)
array([-1,  1,  0])
>>> direction_string_to_offset('NW', dim=2)
array([-1,  1])
>>> direction_string_to_offset(offset_to_direction_string((3,-2,1)))
array([ 3, -2,  1])
```
plot_2d(stencil, axes=None, figure=None, data=None, textsize='12', **kwargs)

Creates a matplotlib 2D plot of the stencil

Parameters
• stencil – sequence of directions

• axes – optional matplotlib axes

• figure – optional matplotlib figure

• data – data to annotate the directions with, if none given, the indices are used

• textsize – size of annotation text

plot_3d_slicing(stencil, slice_axis=2, figure=None, data=None, **kwargs)

Visualizes a 3D, first-neighborhood stencil by plotting 3 slices along a given axis.

Parameters
• stencil – stencil as sequence of directions

• slice_axis – 0, 1, or 2 indicating the axis to slice through

• figure – optional matplotlib figure

• data – optional data to print as text besides the arrows

plot_3d(stencil, figure=None, axes=None, data=None, textsize='8')

Draws 3D stencil into a 3D coordinate system, parameters are similar to `visualize_stencil_2d()` If data is None, no labels are drawn. To draw the labels as in the 2D case, use `data=list(range(len(stencil)))`

plot_expression(expr, **kwargs)

Displays coefficients of a linear update expression of a single field as matplotlib arrow drawing.