solprop.translate.assembly#

Assembly: the physics objects of a run turned into a validated kernel problem.

assemble() is the translation layer’s entry point. It chooses the route – the mode-set route (with the coupled flows of solprop.translate.walls), the general modal route or a spatial geometry – builds its operator, transform and prefactor, compiles the responses, resolves the step limits the collars set, and returns the PropagationProblem with its run’s request, validated.

Module Attributes

MAX_GENERAL_FLOW_EXPONENT

Largest dz_max max|G| a general modal coupled flow is executed at.

Functions

assemble(grid, modes, responses, field0, *, ...)

Turn the physics objects of a run into a validated kernel problem.

solprop.translate.assembly.MAX_GENERAL_FLOW_EXPONENT: float = 1000.0#

Largest dz_max max|G| a general modal coupled flow is executed at.

Dimensionless. The backend takes the flow’s action by scaling and squaring a Schur factor, whose relative error grows with the exponent’s norm: at 1e3 the action is still good to about 1e-13 relative, which is the accuracy the diagonal route it replaces has. The exponent a split block produces is tiny – the departure of each channel from the reference is the block’s own splitting, 744 1/m on the TE01/TM01 pair, and dz_max is microns – so this limit exists to catch a block built from channels that were never a degenerate group, whose departures are the whole dispersion and which would silently lose digits.

solprop.translate.assembly.assemble(grid, modes, responses, field0, *, controller, save_planes, dz_max, dz_init, density=None, noise=None, frame=None, loss=LossPolicy(max_alpha=None), absorber=None, absorber_scheme='nonlinear', quadrature=None, components=None, tableau=Tableau(name='DOPRI5', nodes=array([0., 0.2, 0.3, 0.8, 0.88888889, 1., 1.]), matrix=array([[0., 0., 0., 0., 0., 0., 0.], [0.2, 0., 0., 0., 0., 0., 0.], [0.075, 0.225, 0., 0., 0., 0., 0.], [0.97777778, -3.73333333, 3.55555556, 0., 0., 0., 0.], [2.95259869, -11.59579332, 9.82289285, -0.29080933, 0., 0., 0.], [2.84627525, -10.75757576, 8.90642272, 0.27840909, -0.2735313, 0., 0.], [0.09114583, 0., 0.4492363, 0.65104167, -0.32237618, 0.13095238, 0.]]), solution_weights=array([0.09114583, 0., 0.4492363, 0.65104167, -0.32237618, 0.13095238, 0.]), error_weights=array([0.00123264, 0., -0.00425277, 0.03697917, -0.0508638, 0.04190476, -0.025]), order=5, embedded_order=4, first_same_as_last=True), integrator=None, schedule=None, dz_min=None, stretch=None, interval_cap=None, auto_init=False, interpolate_planes=False, step_planes=0, propagator_mode='auto', stats_spec=None, shock=True, prefactor_index=None, ionisation_field_range=None, spatial_grid=None, medium=None, margin=0.05, tol=1e-12, polarisation_taper=False, general=None, wall=None, taper_coupling=True, reuse=None, initial_z=0.0, evanescent_rate=None, spatial_absorber=None, adiabatic_accuracy=None)[source]#

Turn the physics objects of a run into a validated kernel problem.

This is the whole of the translation layer’s public entry point: it builds the cumulative linear operator, the masks, the modal transform and the compiled responses, derives the flags from what it built, and validates the result before returning it. Everything it does is expensive once and free thereafter (docs/dev/architecture.md section 7).

The run covers [initial_z, max(save_planes)]. Tables retain absolute positions from zero and cover a further margin beyond the last plane.

Parameters:
gridsolprop.grid.TimeGrid

The field or envelope grid.

modesMode or sequence of Mode

The mode, or the ordered set of a multimode problem. A set needs quadrature.

responsessequence

The declared nonlinear responses; see solprop.translate.responses.compile_responses(). A TDSE response owns the complete gas nonlinearity and refuses another Kerr or plasma term.

field0numpy.ndarray

Initial state, shape (n_modes, n_pol, n_omega) or already batched, complex, in the square root of watts and the internal FFT convention — a solprop.pulses.Pulse.build() result, or a stack of them.

controllersolprop.stepper.controller.PIController

Tolerances, norm and step-control parameters.

save_planesarray_like

Positions in z the driver will ask for, m, increasing and positive.

dz_maxfloat

Cap on the controller’s proposal, m.

dz_initfloat

First step, m.

densitysolprop.profiles.ZProfile or float or None, optional

Number density along z in m^-3. None takes the mode’s own density path when it declares one and 1.0 otherwise, which is the convention a medium with an absolute chi3 uses. Refused beside a mixture and beside a gas medium, which carry their own.

noisesolprop.noise.NoiseRealisation or None, optional

A shot-noise realisation to carry along the run.

framesolprop.linear.Frame or None, optional

The co-moving frame. None builds solprop.linear.Frame.comoving() for the grid, keeping beta_0 when a third-harmonic term is present on an envelope grid (solprop.translate.responses.declares_harmonic_carrier()). A frame given with subtract_beta0=True beside that term is refused.

losssolprop.linear.LossPolicy, optional

What to do with an attenuation too large to represent.

absorbersolprop.boundaries.Absorber or None, optional

The collar rates. Its spectral part is folded into the linear operator and its temporal part crosses the seam as a rate.

absorber_scheme{‘split_step’, ‘nonlinear’}, optional

Which application of the temporal absorber the backend will use.

quadraturesolprop.modes.quadrature.TransverseQuadrature or None, optional

The fixed transverse rule of a multimode problem. None builds the mode-averaged, single-node transform, which needs exactly one mode.

componentssequence of str or None, optional

The transverse Cartesian components the multimode transform resolves at each node, a non-empty subset of ("x", "y"). None takes the union of the mode set’s nonzero components at the entrance, from each mode’s principal_component(0.0): ("x",) for HE_1m modes at phi = 0, and both for a rotated or mixed set; pass ("x", "y") for a polarisation-resolved mode set (solprop.modes.collection.ModeCollection.with_polarisations()). Only meaningful with a quadrature, and refused without one. The product of its length and the state’s polarisation axis may not exceed two: the components are carried by the transform or by the state, never by both.

tableausolprop.stepper.tableau.Tableau, optional

The Runge-Kutta tableau. Default DOPRI5.

integratorsolprop.stepper.multistep.Multistep or LowStorageRungeKutta, optional

A low-call Adams method instead of the tableau (SEP 13), or the low-storage RK4 march, which replays schedule (SEP 24).

schedulesolprop.stepper.schedule.FixedSchedule or None, optional

A fixed schedule to replay. Its edges must contain every save plane and hard kink.

dz_minfloat or None, optional

Floor on the controller’s proposal, m. None uses solprop.stepper.controller.default_dz_min() of the run length.

stretchfloat or None, optional

Landing stretch factor. None uses DEFAULT_STRETCH.

interval_capbool or None, optional

Whether a step is capped at its operator-table interval’s width. None caps it only for a coupled flow or a reject-free controller (SEP 14 section 4.1).

auto_initbool, optional

Whether the start-up rule chooses the step after the first; dz_init is the first. Default False, the convenience interfaces’ choice when no dz_init is given. Off for a coupled flow or a reject-free controller.

interpolate_planesbool, optional

Whether save planes are observed inside accepted steps – through DOPRI5’s continuous extension or the Adams march’s polynomial – rather than landed on (SEP 14 phase 3). Refused beside a coupled flow, the per-step temporal collar and the modified noise model.

step_planesint, optional

Also save the end of every step_planes-th accepted step (SEP 14 phase 3); 0, the default, saves the requested planes only.

propagator_mode{‘auto’, ‘tabulate’, ‘recompute’}, optional

Whether the backend tabulates the stage propagators.

stats_specsolprop.stats.StatsSpec or None, optional

Which statistics the run collects, carried by the returned request. None collects none.

shockbool, optional

Keep the omega dependence of the prefactor’s numerator, which is the optical shock term. Default True.

prefactor_indexfloat or None, optional

Use this constant in the prefactor and power weight; None uses Re n_eff. The GNLSE passes 1.0, leaving its power normalisation and Phi unchanged.

ionisation_field_rangetuple of float or None, optional

Field amplitudes in V/m a plasma response’s rate table must cover.

spatial_gridRadialGrid, FreeGrid, PlanarGrid or None, optional

Radial or Cartesian geometry, or the hybrid planar grid (solprop.modes.slab.PlanarGrid); requires modes=None and a bulk medium. The initial columns then contain Hankel spectra in V m, raw Cartesian DFT spectra in V/m, or y-DFT spectra of slab amplitudes in sqrt(W/m) (the planar grid carries its own modes).

mediumsolprop.spatial.SpatialMedium or None, optional

Material and density path for spatial propagation. Its density is used for nonlinear responses; an explicit density is refused beside a gas or a mixture medium, and scales the responses of a glass or a constant index.

marginfloat, optional

Fraction of the run length the tables extend beyond its end.

tolfloat, optional

Target bound on the uniform error of the tables. Raised automatically to the measured round-off floor of the operator (solprop.translate.linop).

polarisation_taperbool, optional

Whether the spectral collar tapers the nonlinear polarisation as well as absorbing the field through the operator. Default False: the taper sets a floor on a broad pulse of the size of its content in the collar.

generalsolprop.translate.general.GeneralModalRoute or None, optional

The seam leaves of a general modal guide. With it the three-component E/H route is assembled instead of the static transverse quadrature: modes are the guide’s channels in state order and supply the diagonal operator, the power weight is the constant one, the prefactor is the crop scale alone and the responses are the route’s own per-region record. A quadrature, components, spatial_grid, medium, density, prefactor_index, declared responses or shock=False is refused beside it by name, and the grid must be a field grid whose active band lies inside the guide’s support.

wallsolprop.modes.capillary.CoherentWall or None, optional

The declaration of a scalar coherent wall block on the capillary route or, with impedance="te_tm", of one azimuthal order, on a constant or a varying guide. With it Phi carries the mode-independent carrier alone and the modal part of the flow becomes linear.coupled_flow, which every backend executes. A general modal guide, a spatial geometry, a polarisation axis and a noise model are refused beside it by name.

taper_couplingbool, optional

Carry the taper coupling on a multimode capillary whose radius varies along z: the moving-basis connection between the HE_1m channels, in a frozen-residual linear.coupled_flow whose diagonal is each channel’s own propagation constant, lossless or not (solprop.modes.capillary.taper_coupling_block() says which sets). The default True; False keeps the adiabatic diagonal route, in which each channel propagates on its own. It has no effect on any other mode set or route, and False beside a wall is refused, because the wall always carries its connection.

reuseTranslationReuse or None, optional

Immutable data prequalified for the same grid, input, geometry and operator functions. New paths still undergo sampled-range checks. None builds fresh.

initial_zfloat, optional

Absolute launch position in m, non-negative and before the first save. field0 is a true-power spectrum at this position; the input boundary applies the corresponding modal power weight exactly once.

evanescent_ratefloat or None, optional

The spatial operator’s evanescent field attenuation cap in m^-1, positive and finite (SEP 22 section 4.4); None keeps solprop.spatial.EVANESCENT_RATE. Refused without a spatial grid.

spatial_absorbersolprop.spatial_absorber.SpatialAbsorber or None, optional

The transverse boundary (SEP 40): resolved against the grid, the medium and the noise-free field0 into the safety ramp, folded into the operator as SeparableOperator.kperp_rate, and a real-space collar on request, as the geometry’s absorber_rate; its design is the spatial route’s transverse (SpatialRoute). None, the default here, carries neither. Refused without a spatial grid.

adiabatic_accuracysolprop.adiabatic.AdiabaticAccuracy or None, optional

The budgets a radial medium varying along z must meet for its forward amplitude transport (SEP 34 section 4.5); None, the default, is AdiabaticAccuracy(). A path exceeding them is refused.

Returns:
Translation

The problem and the request of a fresh run of it, with the step limits the route resolved and clamped, validated together (validate_run()) and ready for a backend.

Raises:
TranslationError

If a response cannot be compiled, an argument is out of range, a frame that removes beta_0 is given beside a third-harmonic term on an envelope grid, or the assembled problem and its request fail validate_run().

Examples

>>> from solprop.grid import EnvelopeGrid
>>> from solprop.nonlinear.gnlse import problem_from
>>> from solprop.pulses import SechPulse
>>> from solprop.stepper import PIController
>>> from solprop.translate.assembly import assemble
>>> grid = EnvelopeGrid.from_limits(1.0, 835e-9, (500e-9, 2e-6), 4e-12)
>>> gnlse = problem_from([0.0, 0.0, -1.2e-26], omega_ref=grid.omega0, gamma=0.11,
...                      shock=False)
>>> start = SechPulse(wavelength=835e-9, width=1e-13, peak_power=1.0).build(grid)
>>> problem, request = assemble(
...     grid, gnlse.mode, [gnlse.kerr], start,
...     controller=PIController(rtol=1e-8, atol=1e-14), save_planes=[0.5, 1.0],
...     dz_max=0.1, dz_init=1e-3, shock=False, prefactor_index=1.0, density=1.0,
... )
>>> problem.flags.single_mode, problem.linear.n_intervals
(True, 1)
>>> request.observation.save_planes.tolist()
[0.5, 1.0]