Arithmetic and NumPy Ufunc Support

Arithmetic and NumPy Ufunc Support#

SphericalMesh (and CartesianMesh) inherit a full arithmetic suite from _BaseFrameMesh. Standard Python operators (+, -, *, /, **, etc.) and NumPy ufuncs such as numpy.log10 and numpy.sqrt operate element-wise on the active scalar field and return a new mesh of the same type with the result as the active scalar. The coordinate arrays are never modified — only the data changes.

from __future__ import annotations

import numpy as np
from psi_data import fetch_mas_data

from pyvisual import Plot3d
from pyvisual.core.mesh3d import SphericalMesh

br_file = fetch_mas_data(domains="cor", variables="br").cor_br

Build a Mesh#

We initialize a SphericalMesh from the HDF file path, which triggers the file-path dispatch path (see Constructing a SphericalMesh for details on the three construction paths.

mesh = SphericalMesh(br_file)
mesh        # noqa: B018
SphericalMesh (0x31e2f1ba0)
  N Cells:      10672572
  N Points:     10826790
  X Bounds:     9.997e-01, 3.042e+01
  Y Bounds:     0.000e+00, 3.142e+00
  Z Bounds:     0.000e+00, 6.283e+00
  Dimensions:   255, 142, 299
  N Arrays:     2


Radial Flux Scaling#

Multiplying by \(r^2\) removes the geometric falloff and converts \(B_r\) to the signed radial flux \(B_r r^2\). The coordinate arrays are unchanged; only the active scalar is updated.

mesh_r2 = mesh * mesh.r[:, None, None] ** 2
print(f"Br     range: [{mesh.data.min():.4f}, {mesh.data.max():.4f}]")      # noqa: T201
print(f"Br r^2 range: [{mesh_r2.data.min():.4f}, {mesh_r2.data.max():.4f}]")        # noqa: T201

plotter = Plot3d()
plotter.show_axes()
plotter.add_mesh(mesh_r2, cmap="seismic", clim=(-1, 1), opacity=0.5, show_scalar_bar=False)
plotter.show()
p02 arithmetic
Br     range: [-38.1425, 33.6160]
Br r^2 range: [-38.1203, 33.5964]

NumPy Ufunc: np.log10#

The __array_ufunc__() hook lets any single-output NumPy ufunc act directly on the mesh. numpy.log10 applied to \(B_r r^2\) converts the field to a logarithmic scale.

To account for the sign of \(B_r r^2\), we take the absolute value before applying the logarithm using the python built-in abs() function, which also supports the mesh type.

mesh_log = np.log10(abs(mesh_r2))
print(f"log10(|Br r^2|) range: [{mesh_log.data.min():.3f}, {mesh_log.data.max():.3f}]")     # noqa: T201

plotter = Plot3d()
plotter.show_axes()
plotter.add_mesh(mesh_log, cmap="rainbow", clim=(-1, 1), opacity=0.5, show_scalar_bar=False)
plotter.show()
p02 arithmetic
log10(|Br r^2|) range: [-7.428, 1.581]

Total running time of the script: (0 minutes 4.421 seconds)

Gallery generated by Sphinx-Gallery