Skip to content

Phase-matching diagnostics (χ⁽³⁾)

FWM detuning, modulation-instability gain, dispersive-wave roots, readiness reports. Docstrings are the source of truth, rendered with mkdocstrings (numpydoc style).

photonics_helper.phase_matching

Phase-matching diagnostics for GNLSE simulations.

Provides cross-cutting analysis tools: - FWM delta-beta and efficiency - Modulation instability gain spectrum - Dispersive wave (Cherenkov) root finder - Simulation readiness assessment - Spectrum-to-PM validation

Where is phase matching? (χ³ vs χ² map) - This module: χ⁽³⁾ processes — FWM / modulation instability / dispersive-wave roots (all use beta_fn at a single ω). - photonics_helper.chi2: χ⁽²⁾ processes — SHG / SFG / DFG phase matching (delta_k_shg, Lambda_qpm) and the coupling constants. Compute the phase-mismatch objects with the module matching your process. Both modules accept any callable β(ω) — including a PropagationConstant directly since v0.1.1

Phase-matching predictions (MI gain, dispersive-wave roots, FWM detuning) assume the linear dispersion β(ω) and pump parameters supplied. They do not include self-steepening (shock term) corrections to the nonlinear polarization; for broadband supercontinuum, enable include_self_steepening on the GNLSE solver separately and treat PM overlays as linear guides only.

All internal math uses SI (rad/s, 1/m, W/m²). Public API functions accept SI inputs and convert at boundaries.

Public API

DispersionModel — protocol for β(ω) accessors DispersionAdaptor — wraps Dispersion → DispersionModel PropagationConstantAdaptor — wraps PropagationConstant → DispersionModel ZDependentDispersionAdaptor — wraps ZDependentDispersion → DispersionModel fwm_delta_beta_degenerate — Δβ for degenerate FWM fwm_delta_beta_general — Δβ for general 4-frequency FWM fwm_efficiency — conversion efficiency η(Δβ, L, α) fwm_idler_frequency — ωᵢ = 2ωₚ − ωₛ scan_fwm_detuning — scan Δβ and η over signal grid mi_gain_spectrum — classical MI gain g(Ω) mi_sideband_frequencies — MI sideband frequencies mi_gain_spectrum_extended — extended Lighthill criterion dispersive_wave_roots — full β(ω) DW root finder PhaseMatchResult — FWM scan result dataclass SimulationReadinessReport — readiness report dataclass assess_simulation_readiness — build readiness report compare_spectrum_to_phase_matching — post-flight validation plot_fwm_efficiency — FWM efficiency plot plot_mi_gain — MI gain plot plot_readiness_report — readiness panel plot_spectrum_with_pm_overlay — spectrum + PM vertical lines

DispersionModel

Bases: Protocol

Protocol for β(ω) accessors.

Any object providing beta(omega) -> NDArray[float] and beta1(omega) -> float satisfies this protocol.

beta

beta(omega: NDArray | float) -> NDArray | float

Return propagation constant β at angular frequency(ies).

Parameters:

Name Type Description Default
omega float or 1-D array — angular frequency in rad/s.
required

Returns:

Type Description
β in 1/m. Same shape as input.

beta1

beta1(omega: NDArray | float) -> NDArray | float

Return group delay per unit length dβ/dω at angular frequency(ies).

Parameters:

Name Type Description Default
omega float or 1-D array — angular frequency in rad/s.
required

Returns:

Type Description
β₁ in s/m. Same shape as input.

DispersionAdaptor

DispersionAdaptor(dispersion: Dispersion, omega0: float | None = None)

Build β(ω) from a Dispersion object via D(λ).

Uses the relation β₂(ω) = −D(λ)·λ²/(2πc) and numerical integration to reconstruct β(ω) from the dispersion table.

The adaptor is callable: adaptor(omega) returns β(ω).

omega0 instance-attribute

omega0 = omega0

beta

beta(omega: NDArray | float) -> NDArray | float

Return β(ω) via spline interpolation of pre-integrated values.

beta1

beta1(omega: NDArray | float) -> NDArray | float

Return β₁(ω) = dβ/dω via spline interpolation of pre-integrated values.

PropagationConstantAdaptor

PropagationConstantAdaptor(pc: PropagationConstant)

Use stored β values with spline interpolation.

Wraps a PropagationConstant object directly — the β values are already absolute, so no integration is needed.

The adaptor is callable: adaptor(omega) returns β(ω).

beta

beta(omega: NDArray | float) -> NDArray | float

beta1

beta1(omega: NDArray | float) -> NDArray | float

ZDependentDispersionAdaptor

ZDependentDispersionAdaptor(zd_disp: ZDependentDispersion, z: float)

Return β(ω, z_fixed) via the existing interpolant.

Fixes z to a specific propagation position and provides a 1-D β(ω) interface.

The adaptor is callable: adaptor(omega) returns β(ω, z_fixed).

beta

beta(omega: NDArray | float) -> NDArray | float

beta1

beta1(omega: NDArray | float) -> NDArray | float

PhaseMatchResult dataclass

PhaseMatchResult(omega_signal: NDArray, delta_beta: NDArray, efficiency: NDArray, idler_omega: NDArray, pump_omega: float, length_m: float, alpha: float = 0.0)

Result from phase-matching scan.

Attributes:

Name Type Description
omega_signal 1-D array — signal angular frequencies (rad/s).
delta_beta 1-D array — Δβ values (1/m).
efficiency 1-D array — FWM conversion efficiency η (dimensionless, 0–1).
idler_omega 1-D array — idler angular frequencies (rad/s).
pump_omega float — pump angular frequency (rad/s).
length_m float — interaction length (m).
alpha float — loss coefficient (1/m).

omega_signal instance-attribute

omega_signal: NDArray

delta_beta instance-attribute

delta_beta: NDArray

efficiency instance-attribute

efficiency: NDArray

idler_omega instance-attribute

idler_omega: NDArray

pump_omega instance-attribute

pump_omega: float

length_m instance-attribute

length_m: float

alpha class-attribute instance-attribute

alpha: float = 0.0

DispersiveWaveResult dataclass

DispersiveWaveResult(wavelengths: WavelengthArray, soliton_omega: AngularFrequency, soliton_wavelength: Wavelength, q_sol: float = 0.0)

Result from dispersive wave root finding.

Attributes:

Name Type Description
wavelengths WavelengthArray — dispersive wave wavelengths.
soliton_omega AngularFrequency — soliton center angular frequency.
soliton_wavelength Wavelength — soliton wavelength.
q_sol float — soliton wavenumber correction (1/m).

wavelengths instance-attribute

wavelengths: WavelengthArray

soliton_omega instance-attribute

soliton_omega: AngularFrequency

soliton_wavelength instance-attribute

soliton_wavelength: Wavelength

q_sol class-attribute instance-attribute

q_sol: float = 0.0

SimulationReadinessReport dataclass

SimulationReadinessReport(dispersion_covers_grid: bool, grid_omega_min: AngularFrequency, grid_omega_max: AngularFrequency, dispersion_min_omega: AngularFrequency, dispersion_max_omega: AngularFrequency, soliton_order: float, dispersion_length: float, nonlinear_length: float, fission_length: float, recommended_num_steps: int, predicted_processes: list[str] = list(), warnings: list[str] = list(), recommendations: list[str] = list(), fwm_predictions: list[dict] = list(), mi_predictions: dict = dict(), dw_predictions: WavelengthArray = (lambda: WavelengthArray(np.array([]), 'nm'))())

Report on simulation readiness.

Attributes:

Name Type Description
dispersion_covers_grid bool — True if dispersion covers the pulse grid.
grid_omega_min AngularFrequency — minimum grid angular frequency.
grid_omega_max AngularFrequency — maximum grid angular frequency.
dispersion_min_omega AngularFrequency — minimum dispersion model frequency.
dispersion_max_omega AngularFrequency — maximum dispersion model frequency.
soliton_order float — estimated soliton order N.
dispersion_length float — L_D (m).
nonlinear_length float — L_NL (m).
fission_length float — L_fiss (m).
recommended_num_steps int — suggested step count.
predicted_processes list[str] — predicted nonlinear processes.
warnings list[str] — warnings about simulation setup.
recommendations list[str] — suggestions for improvement.
fwm_predictions list[dict] — predicted FWM idler wavelengths (contains Wavelength).
mi_predictions dict — predicted MI sideband info (contains WavelengthArray).
dw_predictions WavelengthArray — predicted DW wavelengths.

dispersion_covers_grid instance-attribute

dispersion_covers_grid: bool

grid_omega_min instance-attribute

grid_omega_min: AngularFrequency

grid_omega_max instance-attribute

grid_omega_max: AngularFrequency

dispersion_min_omega instance-attribute

dispersion_min_omega: AngularFrequency

dispersion_max_omega instance-attribute

dispersion_max_omega: AngularFrequency

soliton_order instance-attribute

soliton_order: float

dispersion_length instance-attribute

dispersion_length: float

nonlinear_length instance-attribute

nonlinear_length: float

fission_length instance-attribute

fission_length: float

recommended_num_steps instance-attribute

recommended_num_steps: int

predicted_processes class-attribute instance-attribute

predicted_processes: list[str] = field(default_factory=list)

warnings class-attribute instance-attribute

warnings: list[str] = field(default_factory=list)

recommendations class-attribute instance-attribute

recommendations: list[str] = field(default_factory=list)

fwm_predictions class-attribute instance-attribute

fwm_predictions: list[dict] = field(default_factory=list)

mi_predictions class-attribute instance-attribute

mi_predictions: dict = field(default_factory=dict)

dw_predictions class-attribute instance-attribute

dw_predictions: WavelengthArray = field(default_factory=lambda: WavelengthArray(np.array([]), 'nm'))

ValidationReport dataclass

ValidationReport(predictions: list[dict], peaks_found: list[dict], matches: list[dict], overall_pass: bool, tolerance: Wavelength)

Post-flight validation report.

Attributes:

Name Type Description
predictions list[dict] — list of PM predictions with Wavelength key.
peaks_found list[dict] — list of detected spectral peaks with Wavelength.
matches list[dict] — each has prediction, matched_peak, residual (Wavelength), pass.
overall_pass bool — True if all predictions have a matching peak.
tolerance Wavelength — wavelength tolerance used.

predictions instance-attribute

predictions: list[dict]

peaks_found instance-attribute

peaks_found: list[dict]

matches instance-attribute

matches: list[dict]

overall_pass instance-attribute

overall_pass: bool

tolerance instance-attribute

tolerance: Wavelength

fwm_delta_beta_degenerate

fwm_delta_beta_degenerate(beta_fn, omega_p: float, omega_s: float) -> float

Compute Δβ for degenerate FWM.

Δβ = 2β(ωₚ) − β(ωₛ) − β(ωᵢ) where ωᵢ = 2ωₚ − ωₛ

Parameters:

Name Type Description Default
beta_fn callable — β(ω) function (any DispersionModel or callable).
required
omega_p float — pump angular frequency (rad/s).
required
omega_s float — signal angular frequency (rad/s).
required

Returns:

Name Type Description
delta_beta float — phase mismatch (1/m).

fwm_delta_beta_general

fwm_delta_beta_general(beta_fn, omega_1: float, omega_2: float, omega_3: float, omega_4: float) -> float

Compute Δβ for general (non-degenerate) 4-wave mixing.

Δβ = β(ω₁) + β(ω₂) − β(ω₃) − β(ω₄)

Parameters:

Name Type Description Default
beta_fn callable — β(ω) function.
required
omega_1 float — pump/frequency-1 (rad/s).
required
omega_2 float — pump/frequency-1 (rad/s).
required
omega_3 float — signal/idler (rad/s).
required
omega_4 float — signal/idler (rad/s).
required

Returns:

Name Type Description
delta_beta float — phase mismatch (1/m).

fwm_efficiency

fwm_efficiency(delta_beta: float | NDArray, length_m: float, alpha: float = 0.0) -> float | NDArray

Compute FWM conversion efficiency η.

Lossless (α=0): η = sinc²(Δβ·L/2)

Lossy (α>0): Full formula from plan §2.3: η = [α²/(α²+Δβ²)] · { 1 + [4 e^{-αL} sin²(Δβ·L/2)] / [(1−e^{-αL})² (α²+Δβ²)] }

Parameters:

Name Type Description Default
delta_beta float or array — phase mismatch Δβ (1/m).
required
length_m float — interaction length (m).
required
alpha float — loss coefficient (1/m). Default 0.
0.0

Returns:

Name Type Description
efficiency float or array — conversion efficiency (0–1 range).

fwm_idler_frequency

fwm_idler_frequency(omega_p: float, omega_s: float) -> float

Compute idler frequency for degenerate FWM.

ωᵢ = 2ωₚ − ωₛ

Parameters:

Name Type Description Default
omega_p float — pump angular frequency (rad/s).
required
omega_s float — signal angular frequency (rad/s).
required

Returns:

Name Type Description
omega_i float — idler angular frequency (rad/s).

scan_fwm_detuning

scan_fwm_detuning(beta_fn, omega_p: float, omega_signal_grid: NDArray, P_pump: float, gamma: float, alpha: float = 0.0, L: float | None = None) -> PhaseMatchResult

Scan FWM Δβ and efficiency over a grid of signal frequencies.

Parameters:

Name Type Description Default
beta_fn callable — β(ω) function.
required
omega_p float — pump angular frequency (rad/s).
required
omega_signal_grid 1-D array — signal angular frequencies to scan (rad/s).
required
P_pump float — pump power (W).
required
gamma float — nonlinear coefficient γ (1/(W·m)).
required
alpha float — loss coefficient (1/m). Default 0.
0.0
L float — interaction length (m). If None, uses 1/gamma as estimate.
None

Returns:

Name Type Description
result PhaseMatchResult

mi_gain_spectrum

mi_gain_spectrum(beta2: float, gamma: float, P: float, omega_m: NDArray | float | None = None) -> NDArray | float | dict

Compute classical MI gain g(Ω).

Exact linear-stability result for the NLSE i∂A/∂z = (β₂/2)∂²A/∂T² − γ|A|²A::

g(Ω) = |β₂ Ω| √(Ω_c² − Ω²)   for β₂ < 0 (anomalous), Ω < Ω_c
Ω_c² = 4γP/|β₂|               (cutoff)
Ω_peak² = 2γP/|β₂| = Ω_c²/2   (peak gain location)
g_max = 2γP                    (peak gain)

g(Ω) = 0 for β₂ > 0 (normal dispersion).

References
  • Agrawal, Nonlinear Fiber Optics, 5th ed., Eq. (5.1.9).
  • Hasegawa & Tappert, Appl. Phys. Lett. 23, 142 (1973).
  • Tai, Hasegawa & Tomita, Phys. Rev. Lett. 56, 135 (1986) (experimental observation of MI in optical fibers).

Parameters:

Name Type Description Default
beta2 float — group velocity dispersion β₂ (s²/m).
required
gamma float — nonlinear coefficient γ (1/(W·m)).
required
P float — CW pump power (W).
required
omega_m 1-D array — modulation frequencies Ω (rad/s). If None,
  returns peak gain and cutoff.
None

Returns:

Name Type Description
gain float or 1-D array — MI gain coefficient (1/m).

mi_sideband_frequencies

mi_sideband_frequencies(beta2: float, gamma: float, P: float) -> NDArray

Compute MI sideband frequencies.

Solves β₂Ω² + 4γP = 0 → Ω² = −4γP/β₂ (the exact MI cutoff for the NLSE i∂A/∂z = (β₂/2)∂²A/∂T² − γ|A|²A; Agrawal, Nonlinear Fiber Optics, §5.1).

Parameters:

Name Type Description Default
beta2 float — β₂ (s²/m).
required
gamma float — γ (1/(W·m)).
required
P float — pump power (W).
required

Returns:

Name Type Description
omega_sidebands 1-D array — [−Ω_sideband, +Ω_sideband] (rad/s).

mi_gain_spectrum_extended

mi_gain_spectrum_extended(beta_fn=None, omega0: float | None = None, gamma: float | None = None, P: float | None = None, alpha: float = 0.0, L: float | None = None, omega_m: NDArray | None = None, betas: NDArray | None = None, beta_fn_convention: str = 'absolute') -> dict

Extended MI gain using full dispersion relation.

Computes the MI gain spectrum using the exact dispersion β(ω) instead of a Taylor expansion. Based on the linear stability analysis of the NLSE, the gain is

g(Ω) = √[−Δ(Ω)·(Δ(Ω) + 4γP)]  for −4γP < Δ(Ω) < 0
g(Ω) = 0  otherwise

where Δ(Ω) = β(ω₀+Ω) + β(ω₀−Ω) − 2β(ω₀) is the even dispersion mismatch (the β₁ term cancels). For a Taylor expansion β(ω) ≈ β₀ + β₁Ω + ½β₂Ω² this reduces exactly to the classical result g(Ω) = |β₂|Ω√(Ω_c² − Ω²) with Ω_c² = 4γP/|β₂|.

Numerics (ISSUES.md #2 — catastrophic cancellation): the mismatch is a small difference of large β values whenever the β argument carries the carrier offset. Evaluating a β(ω) callable at absolute frequencies ω₀ ≈ 1.2e15 rad/s limits Δ to the float64 ULP ≈ 0.25 rad/s, which swamps physical mismatches (0.01–0.4 rad/s for typical SMF). Two offset-aware contracts avoid forming Δ from large terms:

  1. betas=<β₂…βₖ s^k/m array> (recommended) — Δ is evaluated analytically as 2·Σ_${even k} βₖΩᵏ/k!, exact by construction.
  2. beta_fn_convention="detuning" — beta_fn(Ω) must return β(ω₀+Ω) − β(ω₀) as a function of the detuning Ω (rad/s); then Δ(Ω) = β~(Ω) + β~(−Ω) and the β₁ cancellation is built in.

The legacy beta_fn_convention="absolute" path (β_fn called at absolute ω) is deprecated and warns: at NIR carriers it is round-off-limited and should be re-derived as one of the two contract forms above.

References
  • Agrawal, Nonlinear Fiber Optics, 5th ed., §5.1 (linear stability analysis with higher-order dispersion).
  • Hasegawa & Tappert, Appl. Phys. Lett. 23, 142 (1973).

Parameters:

Name Type Description Default
beta_fn callable — Dispersion function. With ``"detuning"``,
  `beta_fn(Ω)` returns β(ω₀+Ω) − β(ω₀) from detuning Ω (rad/s);
  with the legacy ``"absolute"`` it is called at absolute angular
  frequency. Ignored when ``betas`` is given.
None
omega0 float — pump carrier frequency (rad/s). Used for grid
 auto-scaling and the deprecated absolute path.
None
gamma float — nonlinear coefficient (1/(W·m)).
None
P float — pump power (W).
None
alpha float — loss (1/m). Default 0 (not used in gain formula).
0.0
L float — length (m). If None, 1/γ (not used in gain formula).
None
omega_m 1-D array — modulation frequencies (rad/s). If None,
  auto-generates a grid based on classical estimate.
None
betas 1-D array — Taylor coefficients β₂…βₖ in s^k/m. When given, Δ is
computed analytically and `beta_fn` is ignored (recommended).
None
beta_fn_convention "absolute" (legacy, deprecated) or "detuning".
'absolute'

Returns:

Name Type Description
result dict with keys 'omega_m', 'gain', 'Omega_peak', 'Omega_cutoff'.

dispersive_wave_roots

dispersive_wave_roots(beta_fn, omega_sol: float | AngularFrequency, q_sol: float = 0.0, wl_range: tuple[Wavelength, Wavelength] | None = None, n_brackets: int = 50) -> DispersiveWaveResult

Find all dispersive wave (Cherenkov) frequencies.

Solves β(ω_DW) = β(ωₛ) + β₁(ωₛ)(ω_DW − ωₛ) + q_sol

Uses bracket search over wavelength range with scipy.optimize.root_scalar.

Parameters:

Name Type Description Default
beta_fn callable — β(ω) function (DispersionModel or similar).
required
omega_sol float or AngularFrequency — soliton center angular frequency.
required
q_sol float — soliton wavenumber correction (1/m). Default 0.
0.0
wl_range tuple[Wavelength, Wavelength] — (wl_min, wl_max) search range.
        Defaults to 300 nm – 2500 nm.
None
n_brackets int — number of bracket intervals to scan.
50

Returns:

Name Type Description
result DispersiveWaveResult with wavelengths as WavelengthArray

emit_readiness_warnings

emit_readiness_warnings(report: SimulationReadinessReport) -> None

Emit UserWarning for each readiness warning and recommendation.

assess_simulation_readiness

assess_simulation_readiness(pulse: Wave, fiber: FiberProfile, dispersion, betas: NDArray | None = None, length: Length | None = None) -> SimulationReadinessReport

Assess whether a proposed GNLSE simulation is adequately set up.

Checks dispersion coverage, estimates soliton parameters, and predicts which nonlinear processes should be relevant.

Parameters:

Name Type Description Default
pulse Wave — input pulse.
required
fiber FiberProfile — fiber parameters.
required
dispersion Dispersion or ZDependentDispersion or PropagationConstant — dispersion source.
required
betas NDArray — Taylor coefficients [β₂, β₃, ...] in ps^k/m. Optional.
None
length Length — propagation length. If None, uses fiber.length.
None

Returns:

Name Type Description
report SimulationReadinessReport

compare_spectrum_to_phase_matching

compare_spectrum_to_phase_matching(solver: GNLSESolver, report: SimulationReadinessReport, tolerance: Wavelength | float = 2.0, tolerance_frac: float = 0.01) -> ValidationReport

Compare simulated spectral peaks to PM predictions.

Uses adaptive tolerance: narrowband (±tolerance, default 2 nm) when pulse spectral FWHM ≤ 50 nm, or broadband (±tolerance_frac·λ, default 1%) when FWHM > 50 nm.

Parameters:

Name Type Description Default
solver GNLSESolver — solver with propagated results.
required
report SimulationReadinessReport — PM predictions from preflight.
required
tolerance Wavelength or float — narrowband wavelength tolerance.
    If float, interpreted as nm. Default 2.0 nm.
2.0
tolerance_frac float — broadband fractional tolerance. Default 0.01.
0.01

Returns:

Name Type Description
validation ValidationReport

plot_fwm_efficiency

plot_fwm_efficiency(fwm_result: PhaseMatchResult, ax=None) -> plt.Figure

Plot FWM Δβ and efficiency curves for degenerate FWM.

Parameters:

Name Type Description Default
fwm_result PhaseMatchResult — result from scan_fwm_detuning.
required
ax matplotlib Axes, optional.
None

Returns:

Name Type Description
fig matplotlib Figure

plot_mi_gain

plot_mi_gain(mi_result, ax=None) -> plt.Figure

Plot MI gain spectrum g(Ω) vs modulation frequency.

Parameters:

Name Type Description Default
mi_result PhaseMatchResult or dict — from mi_gain_spectrum or mi_gain_spectrum_extended.
required
ax matplotlib Axes, optional.
None

Returns:

Name Type Description
fig matplotlib Figure

plot_readiness_report

plot_readiness_report(report: SimulationReadinessReport, ax=None) -> plt.Figure

Plot readiness panel showing grid vs dispersion extent.

Parameters:

Name Type Description Default
report SimulationReadinessReport.
required
ax matplotlib Axes, optional.
None

Returns:

Name Type Description
fig matplotlib Figure

plot_spectrum_with_pm_overlay

plot_spectrum_with_pm_overlay(solver, report: SimulationReadinessReport, ax=None) -> plt.Figure

Plot final spectrum with vertical lines at PM-predicted frequencies.

Parameters:

Name Type Description Default
solver GNLSESolver — solver with propagated results.
required
report SimulationReadinessReport — PM predictions.
required
ax matplotlib Axes, optional.
None

Returns:

Name Type Description
fig matplotlib Figure