_mesh#
Mesh management utilities for PSI staggered grid data.
MAS and POT3D solve their equations on staggered (Yee-type) spherical grids \((r, \theta, \varphi)\). Different physical quantities are located at different positions within each grid cell so that discrete differential operators (curl, divergence) are exactly satisfied at the discrete level. Each axis of a multi-dimensional output array is independently classified as either:
Main mesh — quantity sampled at the cell-center nodes.
Half mesh — quantity sampled at the face or edge midpoint, displaced by half a grid spacing along that axis.
Mesh codes#
A mesh code encodes the staggering of every axis in a single compact integer.
Each binary bit indicates, per axis, whether the data lives on the half mesh
(1) or the main mesh (0). With PSI’s Fortran column-major HDF convention
the most-significant bit maps to the last numpy axis (the radial \(r\)
direction), so a three-bit code reads \((r, \theta, \varphi)\) MSB → LSB:
Code |
\(r\) |
\(\theta\) |
\(\varphi\) |
Typical quantities |
|---|---|---|---|---|
|
half |
main |
main |
\(B_r\) (MAS) |
|
main |
half |
main |
\(B_\theta\) (MAS) |
|
main |
main |
half |
\(B_\varphi\) (MAS) |
|
main |
half |
half |
\(v_r\), \(J_r\) (MAS); \(B_r\) (POT3D) |
|
half |
main |
half |
\(v_\theta\), \(J_\theta\) (MAS); \(B_\theta\) (POT3D) |
|
half |
half |
main |
\(v_\varphi\), \(J_\varphi\) (MAS); \(B_\varphi\) (POT3D) |
|
half |
half |
half |
scalars: \(T\), \(\rho\), \(p\), … |
|
main |
main |
main |
all-main; result of remeshing every axis |
Accepted input forms for a mesh code are described by MeshCodeType
(integer, string shorthand 'main'/'half', or per-axis sequence).
The memory-order convention is described by ArrayOrdering.
Public API#
MeshEnum with two members —
MAINandHALF— representing the two mesh positions.MeshCodeTypeType alias for the three accepted forms of a mesh stagger specification.
ArrayOrderingType alias for the memory-order string (
'F'or'C') accepted byremesh_array().remesh_array()Shift an array from one mesh stagger to another by averaging adjacent elements along each axis that needs to move from half mesh to main mesh.
Examples#
Convert a radial magnetic-field array (half-mesh in \(r\), the last numpy axis) to the all-main mesh:
>>> import numpy as np
>>> from psi_io._mesh import remesh_array
>>> br = np.ones((128, 64, 57)) # shape (Nφ, Nθ, Nr); Nr is half-mesh size
>>> br_main = remesh_array(br, imesh=0b100, omesh='main')
>>> br_main.shape
(128, 64, 56)
Remesh a scalar quantity (all-half, 0b111) to all-main:
>>> rho = np.ones((128, 64, 57))
>>> remesh_array(rho, imesh=0b111, omesh='main').shape
(127, 63, 56)
Classes
|
Enum identifying the stagger position of one array axis. |
Functions
|
Shift an array from one mesh stagger to another. |
Attributes
Type alias for the memory-order convention accepted by |
|
Type alias for mesh stagger specifications accepted by |