comnum.ManakovSsfm#

class comnum.ManakovSsfm(fiber, *, step_rule='fwm', fwm_phase=20.0, bandwidth_hz=None, max_nl_phase=0.02, steps_per_span=100, step_km=None, nonlinear_step='midpoint', max_iterations=10, tolerance=1e-05, amplification='edfa', raman=None, check_sampling=True)#

Dual-polarisation nonlinear propagation over the link: the Manakov equation solved by the symmetric split-step method (nonlinear_step="trapezoidal" is OptiCommPy’s manakovSSF).

Each step is a half linear step, the nonlinear phase (8/9) γ h P (P = |A_x|² + |A_y|² at the middle of the step; with nonlinear_step="trapezoidal", OptiCommPy’s (P(z) + P(z+h))/2, iterated until the relative change of the fields falls below tolerance) and a half linear step. The step is fixed (step_km) or adaptive (step_rule). An amplifier follows every span. Polarisation-mode dispersion is neglected (see ManakovPmd).

Parameters:
  • fiber (FiberParams) – the link.

  • step_rule (str) – "fwm", the rule of Musetti et al. (2018): the first step of a span bounds the four-wave-mixing phase across the signal bandwidth to fwm_phase, the next ones grow with the loss (about 0.01 dB of error on the SNR at 20 rad, whatever the power); "nonlinear_phase", OptiCommPy’s max_nl_phase per step; or "logarithmic", steps_per_span logarithmic steps (Bosco et al. 2000).

  • steps_per_span (int) – logarithmic steps per span, with step_rule="logarithmic".

  • fwm_phase (float) – the four-wave-mixing phase of the first step (rad).

  • bandwidth_hz (float, optional) – the signal bandwidth of the rule "fwm" (measured on the launched field if None).

  • max_nl_phase (float) – largest nonlinear phase rotation per step (rad), with step_rule="nonlinear_phase".

  • step_km (float, optional) – a fixed step (km) instead of the adaptive one.

  • nonlinear_step (str) – "midpoint", the power at the middle of a step (the scalar solver), or "trapezoidal", the mean of the power at its two ends, iterated (OptiCommPy): the trapezoidal mean smooths the cross-phase modulation of channels that walk off within a step.

  • max_iterations (int) – trapezoidal iterations per step at most.

  • tolerance (float) – convergence tolerance of the iterations.

  • amplification (str) – "edfa", "ideal" or "none".

  • raman (dict, optional) – Raman pumps and ISRS in every span (see raman_profile()).

  • check_sampling (bool) – refuse a field whose sampling rate is below 3/2 of its bandwidth or whose block is shorter than the walk-off of the link (the four-wave mixing would alias, Musetti et al. 2018, Appendix B).

Raises:

ValueError – for an invalid parameter or input (the message names it).

backpropagate(u, fs, *, steps_per_span=1, nonlinear_scale=1.0)#

Dual-polarisation digital back-propagation with steps_per_span symmetric steps per span (the Manakov equation with -α, -β₂, -γ, the amplifier gain removed before each span, the nonlinear phase of a step on its effective length).

Parameters:
  • u (array_like) – the received field, (2, n) (√W).

  • fs (float) – sampling rate (Hz).

  • steps_per_span (int) – steps per span.

  • nonlinear_scale (float) – ξ, multiplies the nonlinear phase (0: dispersion compensation only).

Returns:

the back-propagated field, (2, n) (complex128).

Return type:

numpy.ndarray

Raises:

ValueError – for an invalid parameter or input (the message names it).

propagate(u, fs, *, rng=None)#

Propagate the two polarisations.

Parameters:
  • u (array_like) – the field, (2, n): the two polarisations (√W).

  • fs (float) – sampling rate (Hz).

  • rng (Rng, optional) – the generator of the ASE (noiseless without one).

Returns:

the field at the end of the link, (2, n) (complex128); the number of steps is kept in last_steps.

Return type:

numpy.ndarray

Raises:

ValueError – for an invalid parameter or input (the message names it).

last_steps#

The number of steps of the last propagation (None before the first).

Type:

int | None