# Output and diagnostics

`run_fdtd` returns the final simulation state. Detector results are held in the associated detector-state mapping and are keyed by the detector output names.

## Visual inspection

- `plot_setup` / `plot_setup_from_side`: object placement and simulation bounds.
- `plot_material` / `plot_material_from_side`: rasterized material slices.
- `plot_field_slice` / `plot_field_slice_component`: scalar or component field slices.

Always inspect the *rasterized* scene, not only the intended continuous geometry. At coarse resolution a narrow gap or polygon edge can disappear.

## Portable volume output

- `export_vti` writes uniform-image VTK data.
- `export_vtr` writes rectilinear-grid VTK data.
- `export_arrays_snapshot_to_vti` exports arrays from a state snapshot.
- `export_stl` writes compatible geometry surfaces.

VTK output can be opened in ParaView for volume slices, vector glyphs, and animation.

## Spectral data

Convert JAX arrays to NumPy only after the compiled/differentiated calculation:

```python
import numpy as np

spectrum = np.asarray(detector_state["flux"])
np.savez_compressed(
    "spectrum.npz",
    wavelength_m=wavelengths,
    transmission=spectrum,
)
```

Record units, propagation sign, phasor convention, source normalization, reference plane, grid spacing, runtime, and commit. A bare array is not a reproducible optical result.

## Useful scalar diagnostics

- finite-field and finite-gradient assertions;
- peak and residual energy;
- $R+T+A$ for layered media;
- closed-surface radiated power;
- incident calibration and passive output-power sum;
- best-so-far objective and gradient norm;
- error change under grid refinement.

