Skip to main content

photonhub

Python client for the PhotonHub FDTD solver. The pydantic models in photonhub.components are the single source of truth for the simulation JSON wire format; the published simulation schema is generated from them via python -m photonhub.schema emit.

Install

Python 3.11+:

python -m pip install photonhub

(From a monorepo checkout: python -m pip install -e ./photonhub.)

That installs the full scripting client: build simulations, estimate cost, run on the cloud GPU (ph.cloud.run_quoted(sim, max_usd=...) with your beta API key), and read results, with no compiler and no engine build. Local runs (ph.run_local) also need the phsolver engine binary, which pip does not ship: invited beta participants receive the standalone headless solver archive (install it with photonhub install-solver --archive <file> --sha256 <digest>, or point $PHOTONHUB_SOLVER at it or put it on PATH; the copy inside the desktop app is locked to that app and is not a standalone command), and developers with the monorepo build it with cmake -S engine -B build && cmake --build build.

Optional extras: photonhub[viz] (interactive/3D plots), [gds] (GDSII import/export), [hdf5] (HDF5 result export), [replicate], [notebook], and the service extras below.

import photonhub as ph

sim = ph.Simulation(
    size_um=(4.0, 4.0, 4.0),
    grid=ph.UniformMesh(dl_um=0.05),
    run=ph.RunSpec(run_time_s=8.0e-14),
    sources=[
        ph.PointDipole(
            center_um=(2.0, 2.0, 2.0),
            polarization="Ez",
            source_time=ph.GaussianPulse(freq0_hz=1.934e14, fwidth_hz=4.0e13),
        )
    ],
    monitors=[
        ph.TimeMonitor(name="probe", center_um=(3.0, 2.0, 2.0), fields=["Ez"]),
        ph.SnapshotMonitor(name="final", fields=["Ex", "Ey", "Ez"]),
    ],
)

data = ph.run_local(sim)        # finds phsolver, runs it, parses outputs
probe = data["probe"]           # xarray.DataArray, dims ('t', 'component')

Optional command-line services are kept out of the base SDK dependency set:

python -m pip install 'photonhub[mcp]'
photonhub-mcp                    # optionally pass a result directory to preload

python -m pip install 'photonhub[server]'
photonhub-serve-viz              # local result/preview HTTP service (loopback, unauthenticated:
                                 # single-user machines only; --enable-notebook opts into code cells)

The photonhub[app] extra includes both service dependency sets plus the desktop app's file-format integrations.

See your simulation before you run it

Every Simulation plots itself: geometry, sources, monitors, PML, and the permittivity the solver actually meshes, with matplotlib (built in; plotly for 3D). grid=True overlays the mesh cell edges so you can check resolution:

sim.plot(z=2.0)                   # scene cross-section through the source
sim.plot_index(z=2.0, grid=True)    # the permittivity the run sees + the mesh overlay
sim.plot_3d()                     # interactive 3D  (pip install photonhub[viz])

What you can do today

Shipped surface as of schema v1.21.0-alpha.1 (a dispersive solver core cross-checked against analytic references: multi-pole Lorentz + Drude ADE with a fitted metals library (Au/Ag/Cu/Al) and PEC structures, with recorded CPU↔GPU equivalence (full inventory 475/475 on 2026-08-27, a dated pre-merge record) under the numerical contract's tolerances; plus full-vector mode injection, GDS import (ph.import_gds), adjoint gradients, and silicon photonic-circuit tools):

  • Ports and declarative setup: ph.Port names a plane, a guide and a mode. ph.Simulation(ports=..., source="in", wlens_um=..., domain=ph.Domain(...), mesh=ph.Mesh(...)) fits the box around your structures, builds the mesh, launches the driven port and records every port; data.transmission("out") and data.reflection() read them back as spectra. symmetry= reduces a symmetric device to the half the solver steps, and every view and readout shows the whole device.
  • Run a simulation: ph.run_local(sim) (subprocess + file protocol; device="cpu"|"gpu"|"gpu:N"), ph.submit(sim) and ph.Batch(...) for many sims in flight.
  • Know the cost first: sim.cost_estimate() (or ph.quote(sim)) returns a dollar estimate from an overridable planning rate per cell and time step before you press run; the default is an estimator input, not a production billing commitment.
  • Geometry: Box, Sphere, Cylinder (full, or an annular sector / ring via inner_radius_um + angle_start_rad / angle_stop_rad), and Polygon (an extruded polygon, e.g. a taper).
  • Sources: PointDipole, PlaneWave (normal-incidence TF/SF; oblique via Simulation.with_oblique_plane_wave + Bloch boundaries, schema 1.18), the closed TFSFBox scattering box (single-run cross-sections with PML on all sides), and the mode_launch waveguide-mode builder that declared ports use, all driven by a GaussianPulse or a steady-state CW carrier. The ModeSource wire type remains for legacy scalar and continuous-adjoint compatibility.
  • Monitors: TimeMonitor, SnapshotMonitor, ProfileMonitor, and PowerMonitor: fp64 DFT field and flux power. A DFT plane may carry the optional ModePort authoring recipe; the engine strictly validates and then ignores that metadata while recording the same raw fields, and result post-processing performs the requested modal projection. Workbench keeps one shared wavelength sweep across ports; port planes/windows stay outside PML/absorber cells; and preflight requires one downstream driven port linked to the first wire-order normalization source with no other active excitation, so an unevaluable S-column is rejected before the time-domain run.
  • Component library: ph.library.straight / bend / taper / crossing / coupler / ring: each returns a Component (structures + ports) in ~one line.
  • Material library: ph.materials: 20 literature materials (Si, SiO2, Si3N4, GaAs, InP, Ge, LiNbO3, sapphire, AlN, TiO2, MgF2, CaF2, PMMA, ...) with cited dispersion data and validity ranges. Si.medium(1.55) freezes the index at one wavelength; Si.medium(band_um=(1.5, 1.6)) least-squares fits the engine's single Lorentz pole over the band (Courant-safe pole placement; it warns when the fitted index is off by more than 1e-3). Bring measured ellipsometry data via materials.Material.from_nk_data(...).
  • Mode-resolved transmission by hand: the photonhub.analysis pipeline that declared ports build for you, solve_yee_mode → mode_launch → mode_monitor → transmission(out, in, data), returns {freq_hz: T}. Use solve_yee_mode_bank / solve_modes_by_freq for a broadband launch and readout; the legacy ModeSolver / mode_source path remains for scalar and adjoint compatibility. Full complex multiport S-matrices: analysis.smatrix (SPort + assemble_smatrix, one run per driven port, a multi-port S-parameter driver).
  • Meshing: UniformMesh, or GradedMesh + auto_mesh for a cells-per-λ graded mesh; MeshOverride (a per-structure mesh override) forces a target spacing inside a geometry regardless of material: sim.with_mesh_overrides(MeshOverride(geometry=Box(...), dl_um=(0.02,0.02,None))). Graded meshes run on CPU, single GPU, and multi-GPU with PML/absorber, dispersive media, DFT/flux monitors, and plane-wave/mode sources. They reject the full-tensor subpixel methods (tensor_full, contour_full).
  • Mode solving: the FDE plugins provide the lightweight semi-vectorial ModeSolver and the full-vector VectorModeSolver, including bent/leaky modes with complex n_eff and bend-loss readout.
  • Visualization: Simulation.plot / plot_index (draws Box / Sphere / Cylinder / Polygon; grid=True overlays the mesh) / plot_3d, RunResult.plot_field, and the module-level photonhub.viz.plot_mode (FDE mode heatmap) and photonhub.viz.plot_spectrum (T vs λ).
  • Export: HDF5 converter for the parsed results.
  • Correctness aids: pydantic models reject structural errors at construction, the capability manifest catches client/engine drift, and phsolver validate is authoritative for grid/device constraints. Subpixel smoothing supports Box / Sphere / Cylinder / Polygon; non-dispersive scenes default to contour smoothing, while dispersive scenes default off unless the user opts in.

Limits (today)

This is a dispersive solver core cross-checked against analytic references, plus silicon photonic-circuit tools:

  • Dispersion is multi-pole ADE: Lorentz + Drude poles per medium (metals/plasmonics; numerical definition in the numerics reference, §19; the single- and multi-pole/Drude scenes are in the recorded GPU equivalence inventory under §8 tolerances, dated 2026-08-27) on top of relative permittivity + Ohmic conductivity; a passivity-enforced pole fitter and anisotropic poles are still open. Explicit subpixel + Lorentz runs are supported and equivalence-tested, but the client keeps their construction default off and warns callers to use the stabilized PML profile.
  • S-matrix assembly (analysis.smatrix) costs one simulation per driven port; there is no single-run multiport solve.
  • Open issues and their workarounds are listed on the documentation site's known limitations page.

Net: shapes go in and mode-resolved transmission comes out: declare ports and read data.transmission("out"), or solve the eigenmode, inject it with mode_launch, ratio two mode_monitor planes, and plot T(λ); or assemble the full S-matrix with analysis.smatrix.

Learn more

The worked-example gallery of executed notebooks lives in the project source tree and is shown on the documentation site's examples page.

Metadata

Release files for photonhub 0.1.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for photonhub 0.1.4
File Size Uploaded Provenance Actions
photonhub-0.1.4.tar.gz 864.6 kB Without provenance Details for photonhub-0.1.4.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for photonhub 0.1.4
File Interpreter ABI Platform Actions
photonhub-0.1.4-py3-none-any.whl Python 3 none any Details for photonhub-0.1.4-py3-none-any.whl

Total release size: 1.8 MB

Release files / photonhub-0.1.4.tar.gz

Download URL photonhub-0.1.4.tar.gz
Size 864.6 kB
Tags Source
SHA-256 checksum
How to use checksums
29f2f4eb24fe724486c22fc2f4052c7023dc0bb479037a2faa630c7af16d63bf
BLAKE2b-256 checksum
How to use checksums
b15b86f9359b7f0d0a8e8c708038d89c10211ff076a6f6e6e117d01e78b4b7e8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.5

Release files / photonhub-0.1.4-py3-none-any.whl

Download URL photonhub-0.1.4-py3-none-any.whl
Size 933.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d8837c3b0726b43d614229e2eed37786406df2b46ceb9bcf86b03d4776c09cab
BLAKE2b-256 checksum
How to use checksums
839b606a03aa7d6c28b0335fa56201ac10910fb567b184354b8e68613d6fbabc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.5

Security for photonhub 0.1.4

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.4 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page