<jupyter_start><jupyter_text>Staggered grids[![Google Collab Book](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/tum-pbs/PhiFlow/blob/develop/docs/Staggered_Grids.ipynb)Staggered grids are a key component of the marker-and-cell (MAC) method \[Harlow and Welch 1965\].They sample the velocity components not at the cell centers but in staggered form at the corresponding face centers.Their main advantage is that the divergence of a cell can be computed exactly.ΦFlow only stores valid velocity values in memory.This may require non-uniform tensors for the values since the numbers of horizontal and vertical faces are generally not equal.Depending on the boundary conditions, the outer-most values may also be redundant and, thus, not stored.![image](./figures/Staggered.png)ΦFlow represents staggered grids as instances of [`StaggeredGrid`](phi/field/phi.field.StaggeredGrid).They have the same properties as `CenteredGrid` but the `values` field may reference a[non-uniform tensor](https://tum-pbs.github.io/PhiFlow/Math.htmlnon-uniform-tensors)to reflect the varying number of x, y and z sample points.<jupyter_code># !pip install --quiet phiflow
from phi.flow import *

grid = StaggeredGrid(0, extrapolation.BOUNDARY, x=10, y=10)
grid.values<jupyter_output><empty_output><jupyter_text>Here, each component of the values tensor has one more sample point in the direction it is facing.If the extrapolation was `extrapolation.ZERO`, it would be one less (see above image).  Creating Staggered GridsThe [`StaggeredGrid` constructor](phi/field/phi.field.StaggeredGrid) supports two modes:* **Direct construction** `StaggeredGrid(values: Tensor, extrapolation, bounds)`.  All required fields are passed as arguments and stored as-is.  The `values` tensor must have the correct shape considering the extrapolation.* **Construction by resampling** `StaggeredGrid(values: Any, extrapolation, bounds, resolution, **resolution)`.  When specifying the resolution as a `Shape` or via keyword arguments, non-Tensor values can be passed for `values`,  such as geometries, other fields, constants or functions (see the [documentation](phi/field/phi.field.StaggeredGrid)).Examples:<jupyter_code>domain = dict(x=10, y=10, bounds=Box(x=1, y=1), extrapolation=extrapolation.ZERO)

grid = StaggeredGrid((1, -1), **domain)  # from constant vector
grid = StaggeredGrid(Noise(), **domain)  # sample analytic field
grid = StaggeredGrid(grid, **domain)  # resample existing field
grid = StaggeredGrid(lambda x: math.exp(-x), **domain)  # function value(location)
grid = StaggeredGrid(Sphere([0, 0], radius=1), **domain)  # no anti-aliasing
grid = StaggeredGrid(SoftGeometryMask(Sphere([0, 0], radius=1)), **domain)  # with anti-aliasing<jupyter_output><empty_output><jupyter_text>Staggered grids can also be created from other fields using `field.at()` or `@` by passing an existing `StaggeredGrid`.Some field functions also return `StaggeredGrids`:* [`spatial_gradient()`](phi/field/phi.field.spatial_gradient) with `type=StaggeredGrid`* [`stagger()`](phi/field/phi.field.stagger)  Values TensorFor non-periodic staggered grids, the `values` tensor is [non-uniform](https://tum-pbs.github.io/PhiFlow/Math.htmlnon-uniform-tensors)to reflect the different number of sample points for each component.Functions to get a uniform tensor:* [`at_centers()`](phi/field/phi.field.StaggeredGrid.at_centers) interpolates the staggered values to the cell centers and returns a `CenteredGrid`* [`staggered_tensor()`](phi/field/phi.field.StaggeredGrid.staggered_tensor) pads the internal tensor to an invariant shape with n+1 entries along all dimensions.  SlicingLike tensors, grids can be sliced using the standard syntax.When selecting a vector component, such as `x` or `y`, the result is represented as a `CenteredGrid` with shifted locations.<jupyter_code>grid.vector['x']  # select component<jupyter_output><empty_output><jupyter_text>Grids do not support slicing along spatial dimensions because the result would be ambiguous with StaggeredGrids.Instead, slice the `values` directly.<jupyter_code>grid.values.x[3:4]  # spatial slice
grid.values.x[0]  # spatial slice<jupyter_output><empty_output><jupyter_text>Slicing along batch dimensions has no special effect, this just slices the `values`.<jupyter_code>grid.batch[0]  # batch slice<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10382513661202186, 'fraction_numerical': 0.006375227686703097, 'mean_word_length': 6.346153846153846, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '315504', 'license': 'MIT', 'n_tokens_mistral': 1326, 'n_tokens_neox': 1259, 'n_words': 429, 'path': 'docs/Staggered_Grids.ipynb', 'repo_name': 'eliasdjo/PhiFlow', 'size': '4392'}