magnelio.ports#
Ports — declarative port classes, specs, conductors and reports.
PortWaveguide, PortAnalytical and PortLumped are declared
on the GeometryModel before meshing; the
PortSpec* family covers custom setups passed to an analysis via
ports=; refine_port_modes() converges a port’s mode parameters
on its own plane. The builders and runtime operators behind them are
internal.
- class magnelio.ports.BboxLateralConductor#
All four lateral bbox-wall nodes — the typical outer conductor.
For a port plane on (say) X_MIN, the lateral walls are the four bbox faces whose normal axis is tangential to the port plane (i.e.
Y_MIN,Y_MAX,Z_MIN,Z_MAX). All primal 2D nodes that sit on any of these walls are taken to belong to this conductor — i.e. all nodes withi_u ∈ {0, Nu_node−1}ori_v ∈ {0, Nv_node−1}.Useful for rectangular coax (the bbox itself acts as the outer conductor) and any other “outer = bbox boundary” topology.
- class magnelio.ports.Mode(name, mode_type, omega_c, epsilon_r, field_evaluator, z_line=None, discrete_e_u_profile=None, discrete_e_v_profile=None, discrete_h_u_profile=None, discrete_h_v_profile=None)#
A single waveguide eigenmode with closed-form frequency dependence.
A
Modecarries its transverse field information in one of two mutually exclusive forms:Analytical (Phase 1) —
field_evaluatoris set to a closure that samples the Poynting-normalised profile at any (u, v) point. All fourdiscrete_*_profilefields areNone. Used byCoaxAnalyticalModeSolverandRectWGAnalyticalModeSolver; resampled and B-orthonormalised onto the FIT grid bydiscretize_modes().Numerical (Phase 2) — all four
discrete_*_profilearrays are set to M_ε-orthonormal edge vectors built natively on the port-plane FIT grid;field_evaluatorisNone. Used byNumerical2DModeSolver;discretize_modes()passes these through unchanged (no resampling, no Gram-Schmidt).
The validity invariant is enforced at construction.
- Parameters:
name (str) – Human-readable mode identifier, e.g.
"TEM"or"TE10".mode_type (ModeType) – Mode classification. Drives the formulas for
z_waveandgamma.omega_c (float) – Cut-off angular frequency [rad/s]. Zero for TEM.
epsilon_r (float) – Relative permittivity of the (homogeneous) cross-section filling. Required by the wave-impedance and propagation- constant relations.
field_evaluator (FieldEvaluator or None) – Analytical-path closure that returns the Poynting-normalised transverse field profile at user-supplied (u, v) sample points.
Noneon the numerical path.z_line (float or None, default None) – Frequency-independent line impedance
Z₀ = 2P/I·I*for multi-conductor ports (TEM/QTEM).Nonefor hollow-pipe modes where no inner-conductor current is available.z_modal()returns this value when set; otherwise falls back toz_wave(omega).discrete_e_u_profile (np.ndarray or None, default None) – Numerical-path
E_uprofile, sampled at the port-plane u-edge midpoints. Shape(N_u,). M_ε-orthonormal by construction.discrete_e_v_profile (np.ndarray or None, default None) – Numerical-path
E_vprofile, shape(N_v,).discrete_h_u_profile (np.ndarray or None, default None) – Numerical-path
H_uprofile co-located with v-edges, shape(N_v,).discrete_h_v_profile (np.ndarray or None, default None) – Numerical-path
H_vprofile co-located with u-edges, shape(N_u,).
Notes
The Phase-1 architecture assumes a homogeneously filled cross- section (single
epsilon_r). Phase 2 (QTEM) will extend this to a frequency-dependent effective permittivity.- gamma(omega)#
Propagation constant
γ = α + jβat angular frequencyomega.Above cut-off, the mode is propagating and
γ = j β. Below cut-off it is evanescent andγ = α(real).- Parameters:
omega (float) – Angular frequency [rad/s].
- Return type:
complex
- z_modal(omega)#
Reference impedance for power-wave decomposition.
For multi-conductor modes (TEM/QTEM with
z_lineset), returns the line impedanceZ₀ = 2P/I·I*. For hollow-pipe modes, falls back toz_wave(omega).This is the impedance to use in
V_m^± = (V_m ± Z_modal · I_m) / 2for the modal-load absorption update.- Parameters:
omega (float) – Angular frequency [rad/s].
- Return type:
complex
- z_wave(omega)#
Modal wave impedance at angular frequency
omega.TEM:
Z = η₀ / √ε_r(frequency-independent).TE:
Z = j ω μ / γ(real positive above cut-off, reactive below).TM:
Z = γ / (j ω ε)(real positive above cut-off, reactive below).
- Parameters:
omega (float) – Angular frequency [rad/s]. Must be > 0.
- Return type:
complex
- class magnelio.ports.ModeReport(port_name, name, mode_type, f_cutoff, z_line, _discrete, _plane, _mirrors=(), _h_dual_lengths=(), epsilon_eff=None, termination=None, chain_spread=None)#
One solved port mode, inspectable without a TD run.
- Parameters:
port_name (str)
name (str)
mode_type (ModeType)
f_cutoff (float)
z_line (float | None)
_discrete (DiscreteMode)
_plane (PortPlane)
_mirrors (tuple)
_h_dual_lengths (tuple)
epsilon_eff (float | None)
termination (str | None)
chain_spread (float | None)
- port_name#
Label of the port the mode belongs to.
- Type:
str
- name#
Mode identifier from the 2D solver (e.g.
"TE10","TEM_lap00").- Type:
str
- f_cutoff#
Cut-off frequency [Hz];
0.0for TEM modes.- Type:
float
- z_line#
Frequency-independent line impedance
Z₀ = 2P/(I·I*)for multi-conductor (TEM/QTEM) modes;Nonefor hollow-pipe modes, whose reference impedance is the frequency-dependent wave impedance (usez_modal()).- Type:
float or None
- epsilon_eff#
Effective relative permittivity of a line mode — the
ε_effof a quasi-TEM mode (C'/C'_0, one value per mode of a coupled line: even and odd travel at different speeds), the fillingε_rof a homogeneous TEM mode;Nonefor hollow-pipe modes. The phase velocity isc / √ε_eff.- Type:
float or None
- termination#
How the channel closes the domain at the port plane.
'dtbc'is the exact discrete transparent boundary condition, reflection-free to roundoff;'mur'is the first-order absorber, a reflection floor of order −30 dB. A channel qualifies for the exact one when the feed cross-section is a uniform discrete chain;chain_spreadis that measurement.Nonewhere the port reports no per-channel termination (lumped ports carry no modes at all).- Type:
{‘dtbc’, ‘mur’} or None
- chain_spread#
Weighted RMS spread of the per-pair modal Courant number over the feed cross-section — 0 on a perfectly uniform chain, and the quantity
chain_floor_dbturns into a reflection. A value just above the acceptance threshold means a cross-section that was meant to be uniform and was not, and warns; a large one is an inhomogeneous line that never qualified for the scalar chain.Nonewhen the test does not apply: a mode with a closed-form field evaluator is ineligible by construction, and so is every channel of a port whose feed masses fail the slab consistency check upstream (both warn on their own).- Type:
float or None
- gamma(f)#
Propagation constant
γ = α + jβat frequencyf[Hz].- Parameters:
f (float)
- Return type:
complex
- plot(*, field='E', ax=None, density=20, normalize_arrows=True, threshold=0.0, flip=False, scale_mm=True, title=None, geometry=None)#
Quiver plot of the transverse mode profile on the port plane.
The discrete edge profiles (the B-orthonormal basis vectors the FIT operator actually injects and projects with) are averaged from their staggered edge positions onto the port-plane cell centres and rendered via
plot_field_vector().- Parameters:
field ({"E", "H"}, default "E") – Which transverse field profile to draw.
ax (matplotlib.axes.Axes, optional) – Target axes; a new figure is created when omitted.
density (int, default 20) – Number of arrows along the longer axis of the cross-section; the shorter one gets the count that keeps the spacing equal. The raster is deliberately independent of the computational grid, so a locally refined region does not show up as a cluster of arrows — but it also does not gain any. Raise this to read a feature that the default spacing steps over, such as the field in a thin gap.
normalize_arrows (bool, default True) – Unit-length arrows with magnitude encoded in colour (port-mode style).
threshold (float, default 0.0) – Suppress arrows below this fraction of the peak magnitude.
flip (bool, default False) – Swap the horizontal and vertical plot axes.
scale_mm (bool, default True) – Axis coordinates in mm instead of m.
title (str, optional) – Axes title; default names port, mode, and field.
geometry (GeometryModel, optional) – Geometry model for a cross-section overlay of the port plane (conductors filled, air regions as dashed outlines).
- Returns:
fig (matplotlib.figure.Figure)
ax (matplotlib.axes.Axes)
- Return type:
tuple[‘matplotlib.figure.Figure’, ‘matplotlib.axes.Axes’]
- z_modal(f)#
Power-wave reference impedance at frequency
f[Hz].- Parameters:
f (float)
- Return type:
complex
- z_wave(f)#
Modal wave impedance at frequency
f[Hz].- Parameters:
f (float)
- Return type:
complex
- property chain_floor_db: float | None#
Reflection the feed cross-section’s non-uniformity can cost [dB].
An upper bound, not an estimate. The exact termination is built for the weighted-mean chain, so a spread across the cross-section leaves a residual mismatch; measured through the production chain, the worst case rises linearly with the spread at about a seventh of it, and this bound takes the coefficient as one. A channel terminated by the exact boundary contributes at most this much reflection on top of whatever else limits it — compare it against the floor the port itself reaches.
Nonewhere no spread was measured (seechain_spread), andNoneon a channel the first-order absorber terminates: there the floor is set by the absorber, not by the cross-section, and the spread only explains why the exact boundary was withheld. Readchain_spreadin that case.
- class magnelio.ports.ModeType(value)#
Mode classification for homogeneously-filled waveguides.
- class magnelio.ports.PortAnalytical(name, plane, family='coax', inner_radius=None, outer_radius=None, width=None, height=None, epsilon_r=1.0, center=(0.0, 0.0, 0.0), n_modes=1)#
Declarative port with a closed-form analytical reference mode.
- Parameters:
name (str) – Unique port name.
plane (BoxFace or str) – Bbox face the port lives on.
family ({"coax", "rect_wg"}) – Which analytical family describes the cross-section.
inner_radius (float, optional) – Coax conductor radii [m] (required for
family="coax").outer_radius (float, optional) – Coax conductor radii [m] (required for
family="coax").width (float, optional) – Rectangular-waveguide cross-section [m] (required for
family="rect_wg");widthis the (usually broader) dimension along the lower-numbered global tangential axis.height (float, optional) – Rectangular-waveguide cross-section [m] (required for
family="rect_wg");widthis the (usually broader) dimension along the lower-numbered global tangential axis.epsilon_r (float, default 1.0) – Relative permittivity of the (homogeneous) filling.
center (tuple of float, default (0.0, 0.0, 0.0)) – Cross-section anchor as an
(x, y, z)world-coordinate point [m] — the coax axis, or the lower-left corner of the rectangle. The component along the face’s normal axis is fixed by plane already and is ignored (Noneis fine there).n_modes (int, default 1) – Number of modes.
- class magnelio.ports.PortDispersionReport(port_name, f_axis, z_line, epsilon_eff, gamma)#
Frequency dependence of a port’s modes on the grid.
Returned by
PortReport.dispersion(). Every array is indexed[mode, frequency]in the port’s mode order; a mode that does not propagate at a frequency (below its cut-on) is NaN there. The values are those of the true discrete modes of the feed cross-section — the modes the grid actually carries, solved per frequency — not the frequency-flat mode the port’s report lists.- port_name#
- Type:
str
- f_axis#
Frequencies [Hz].
- Type:
np.ndarray
- z_line#
Reference impedance [Ω] the mode carries at each frequency, full-model value on a port cut by a symmetry plane: the line impedance of a TEM or quasi-TEM mode, the modal impedance of a hollow-pipe mode in the port’s V/I convention.
- Type:
np.ndarray
- epsilon_eff#
Effective permittivity
(β c / ω)²with the grid’s own dispersion divided out — comparable with the closed-formε_eff(f)of the microstrip literature.- Type:
np.ndarray
- gamma#
Propagation constant
α + jβ[1/m], complex.- Type:
np.ndarray
- plot(ax=None, *, mode=None)#
Line impedance and effective permittivity against frequency.
- Parameters:
ax (matplotlib Axes, optional) – Axes for the impedance;
ε_effgoes on a twin axis.mode (int, optional) – One mode; default all.
- Returns:
The matplotlib figure and the impedance axes.
- Return type:
tuple
- summary()#
Multi-line summary at the first, middle and last frequency.
- Return type:
str
- class magnelio.ports.PortLumped(name, start=None, end=None, Z0=50.0, element=None, path=None, samples_per_cell=4)#
Declarative lumped port on an interior path.
The high-level spelling of the lumped Thévenin port: a path through the model and a reference impedance, optionally backed by an RLC companion element. Resolved into a
PortSpecLumpedby the analysis.- Parameters:
name (str) – Unique port name.
start (tuple of float, optional) –
Endpoints in metres — the two-point short form of path, and exclusive with it. Under a clipping symmetry declaration they stay in full-model coordinates: a port crossing an electric symmetry plane is clipped to the meshed half automatically.
The port’s polarity follows start → end; the recorded V and I change sign with it.
end (tuple of float, optional) –
Endpoints in metres — the two-point short form of path, and exclusive with it. Under a clipping symmetry declaration they stay in full-model coordinates: a port crossing an electric symmetry plane is clipped to the meshed half automatically.
The port’s polarity follows start → end; the recorded V and I change sign with it.
path (Curve or sequence of points, optional) – The port’s path: a
Curve, or a sequence of at least two(x, y, z)points [m] read as polyline vertices. Any direction is allowed — an oblique path is carried by a staircase of grid edges, which costs a little excess series inductance (see the lumped-elements guide). The path must not visit a grid edge twice: a two-terminal element is a series chain, so a self-crossing or doubled-back path is rejected.samples_per_cell (int, default 4) – Path samples per smallest cell while rasterising.
Z0 (float, default 50.0) – Power-wave reference impedance [Ω]; without element also the internal Thévenin impedance. Always the full-model value: under symmetry the solver internally halves or doubles it, and every reported quantity stays full-model.
element (SeriesRLC or ParallelRLC, optional) – Companion element replacing the pure resistor as the port’s internal impedance. Also declared with full-model values.
- class magnelio.ports.PortOperatorReport(z_line_num: 'Optional[float]' = None, z_line_ref: 'Optional[float]' = None, cutoff_num: 'Optional[float]' = None, cutoff_ref: 'Optional[float]' = None, symmetry_faces: 'tuple' = (), quasi_static: 'bool' = False)#
- Parameters:
z_line_num (float | None)
z_line_ref (float | None)
cutoff_num (float | None)
cutoff_ref (float | None)
symmetry_faces (tuple)
quasi_static (bool)
- property power_wave_full_scale: float#
Half-window → full-model scale for modal wave amplitudes.
The port modes are power-normalised on the half window, so a recorded amplitude of 1 √W accounts for the power crossing the meshed half only; the mirror half carries the same power again. Each cutting symmetry plane therefore scales the full-model wave amplitude by √2 (and the excitation by 1/√2 so that a declared injected power is a full-model watt).
- property z_line_full_scale: float#
Half-window → full-model scale for the line impedance.
Each cutting magnetic symmetry plane halves the window and its capacitance, so the two halves sit in parallel (
z_full = z_half / 2); an electric symmetry plane puts them in series (z_full = 2 · z_half).
- class magnelio.ports.PortRefinementReport(port_name, target, mode, levels, tol, converged, extrapolated=None, order=None, reports=())#
Convergence of one port’s mode parameter under port-plane refinement.
- Parameters:
port_name (str)
target (str)
mode (int)
levels (tuple[RefinementLevel, ...])
tol (float)
converged (bool)
extrapolated (float | None)
order (float | None)
reports (tuple)
- port_name#
- Type:
str
- target#
"z_line","epsilon_eff"or"f_cutoff"of modemode– the resolved quantity, also when"auto"was asked for.- Type:
str
- mode#
- Type:
int
- levels#
The ladder, level 0 first.
- Type:
tuple of RefinementLevel
- tol#
The relative change the ladder was asked to reach.
- Type:
float
- converged#
Whether the last change fell below
tolbefore the level cap.- Type:
bool
- extrapolated#
Richardson estimate from the last two levels (
Nonewith a single level).- Type:
float or None
- order#
Observed convergence order from the last three levels (
Nonewith fewer).- Type:
float or None
- reports#
The port report of every level, for the modes themselves.
- Type:
tuple of PortReport
- property value: float#
the extrapolated value, else the finest level’s.
- Type:
Best estimate
- class magnelio.ports.PortReport(name, modes, report=None, _dispersion_factory=None, _dispersion_cache=<factory>)#
Per-port mode-solution report (no TD run required).
- Parameters:
name (str)
modes (tuple[ModeReport, ...])
report (PortOperatorReport | None)
_dispersion_factory (object)
_dispersion_cache (dict)
- name#
Port label.
- Type:
str
- modes#
One entry per solved mode, in cut-off-ascending solver order (the same indexing as
excited=[(port, mode_idx)]). Empty for lumped ports.- Type:
tuple[ModeReport, …]
- report#
The two-path scalar summary attached by
build_modal_port(); exposesz_line_num/z_line_ref/cutoff_num/cutoff_ref. For lumped ports a synthetic report carryingz_line_num = Z0.- Type:
PortOperatorReport or None
- classmethod from_operator(op, mesh=None, *, dispersion_factory=None)#
Build a report from a built port operator.
Modal operators contribute one
ModeReportperdiscrete_modesentry; lumped operators (no mode solve) yield an empty mode tuple and a syntheticPortOperatorReportwithz_line_num = Z0.Passing the mesh lets the mode plots resolve the symmetry planes cutting the port window, so they show the full cross-section instead of the solved half; without it they show the solved window.
dispersion_factory— a callable returning the port’s dispersion record — enablesdispersion().- Return type:
- dispersion(f_axis)#
Impedance,
ε_effandγof the port’s modes per frequency.Solves the true discrete modes of the feed cross-section at every point of
f_axis— the modes the grid carries there, as opposed to the single frequency-flat mode the port operates with — and returns what each carries: its impedance, its effective permittivity and its propagation constant. On a quasi-TEM line these move with frequency (the impedance of the tutorial microstrip rises by 7 % over its band); on a homogeneous line they are flat, and the impedance is the exact discrete value the port’s power waves already use.The mode order is the port’s. A mode below its cut-on at a frequency is NaN there.
- Parameters:
f_axis (array_like) – Frequencies [Hz].
- Return type:
- Raises:
ValueError – On a lumped port, or when the feed behind the port plane is not a uniform chain (fewer than four equidistant cells, a taper or step too close to the port).
- summary()#
Multi-line human-readable summary (used by
str()).- Return type:
str
- class magnelio.ports.PortSpecCoax(name, plane, inner_radius, outer_radius, epsilon_r=1.0, center=(0.0, 0.0), n_modes=1)#
Coaxial-line modal port (TEM, Phase 1).
- Parameters:
name (str) – Port label, used by the recorder and S-parameter post-processing.
plane (BoxFace) – Bbox face on which the port lives.
inner_radius (float) – Inner and outer conductor radii [m].
outer_radius (float) – Inner and outer conductor radii [m].
epsilon_r (float, default 1.0) – Relative permittivity of the dielectric.
center (tuple[float, float], default (0.0, 0.0)) – Coax-axis location in the global tangential frame (lower-axis first). See module docstring for the convention.
n_modes (int, default 1) – Phase 1 supports only
n_modes = 1(TEM).
- class magnelio.ports.PortSpecLumped(name, start=None, end=None, Z0=50.0, element=None, path=None, samples_per_cell=4)#
Declarative description of a lumped discrete port / RLC element.
- Parameters:
name (str) – Unique port identifier (used as recorder channel key).
start (tuple[float, float, float], optional) – Endpoints in metres — the two-point short form of path. Exclusive with it; exactly one of the two forms is required. Under a clipping symmetry declaration they stay in full-model coordinates;
Z0/elementare full-model values throughout, and the builder derives the internally scaled half-model device.end (tuple[float, float, float], optional) – Endpoints in metres — the two-point short form of path. Exclusive with it; exactly one of the two forms is required. Under a clipping symmetry declaration they stay in full-model coordinates;
Z0/elementare full-model values throughout, and the builder derives the internally scaled half-model device.path (Curve or sequence of points, optional) – The port’s path through the model: a
Curveor a sequence of at least two(x, y, z)points [m] taken as polyline vertices. It may run in any direction; the rasterised staircase carries an oblique path. The chain must not visit an edge twice, so a self-crossing or doubled-back path is rejected — a two-terminal element is a series chain.samples_per_cell (int, default 4) – Path samples per smallest cell while rasterising. Higher values only refine which edges a strongly curved path picks up.
Z0 (float) – Power-wave reference impedance [Ω] (default 50 Ω). Without an
elementit is also the internal Thévenin impedance — the classic discrete port.element (SeriesRLC or ParallelRLC, optional) – Trapezoidal companion element replacing the pure resistor as the port’s internal impedance: an excited port becomes an RLC-backed source, an unexcited one a passive lumped RLC load.
None(default) meansSeriesRLC(R=Z0)— the behaviour-identical classic port. The element instance is deep-copied per run, so its transient state never leaks between excitations.
- class magnelio.ports.PortSpecMultiConductor(name, plane, conductors=None, epsilon_r=None, n_modes=1, window=None)#
Multi-conductor numerical port spec (Phase 2b/c factory cleanup).
Drives the TEM Laplace path (
solve_tem_laplace(), whenepsilon_ris set) or the QTEM dual-Laplace path (solve_qtem_laplace(), whenepsilon_risNone— the factory builds the vacuum reference mass viabuild_M_eps_vacuum()). Returns theK − 1line modes (Kconductor groups): the single conductor mode forK = 2, the modal basis of the line forK > 2— the capacitance-matrix eigenmodes (TEM) or the eigen-patterns ofC v = ε_eff C_0 v(QTEM), e.g. the even/odd pair of coupled lines, ordered by descending capacitance /ε_eff.Unified multi-mode port (WP-U2/WP-U6). On a homogeneous scalar filling (
epsilon_rset),n_modes > K − 1extends the port by the lowest TE/TM curl-curl modes of the same cross-section, merged by ascending cut-off (TEM channels first,f_c = 0) — the exact continuum decomposition TEM ⊕ TE ⊕ TM; the discrete family cross-orthogonality is at solver tolerance (WP-U1). On an inhomogeneous cross-section (epsilon_r=None, QTEM) no exact family split exists — the higher channels are the true hybrid eigenpairs of the ζ-pencil atf_calc: profiles exact atf_calc, dual-basis projections (the hybrids are not M_ε-orthogonal), termination per the standard defaults (certificates fail on inhomogeneous fillings → modal Mur-1st, loud notice;port_model="band"stays the reflection-critical opt-in for the tracked family). Mode labels stay family-explicit (TEM_lap00,TE_num00,QTEM_lap00,HYB_zp00, …).- Parameters:
name (str) – Port label.
plane (BoxFace) – Bbox face on which the port lives.
conductors (tuple[ConductorSpec, ...] or None, default None) –
[ground, signal_1, signal_2, ...]— at least 2 entries when given.conductors[0]is the gauge reference (φ = 0); each subsequent entry spawns one TEM/QTEM mode in input order. WhenNone, the conductor groups are auto-derived from the mesh PEC mask on the port plane viaextract_conductor_groups_from_mesh()— useful for OCC geometries (cylinders, arbitrary curved cross-sections) where the declarative ConductorSpec list is awkward.epsilon_r (float or None, default None) – Homogeneous-filling permittivity for the TEM path. If
None, the QTEM dispatch is selected: the factory constructs the vacuum-reference mass matrix (build_M_eps_vacuum()) so the dual-Laplace solver can extractε_eff = C' / C'_0.n_modes (int, default 1) – Number of returned modes. Up to
K − 1these are the TEM (or QTEM) line modes; beyond that the port is extended by TE/TM curl-curl modes (homogeneous filling) or ζ-pencil hybrid modes (inhomogeneous filling) — see the class docstring. The QTEM extension requires the requested modes to propagate atf_calcand raises with guidance otherwise.window (tuple of two corner points, optional) – Sub-rectangle of the face as two opposite corners in global tangential-axis ordering (
PortPlane.from_mesh()convention).None(default) covers the whole face. A PEC window boundary (via the legacy edge rule) joins the conductor-group graph as a boundary ring, so it can act as the ground conductor of an embedded port.
Notes
Conductor groups are auto-deduplicated in input order: nodes that belong to an earlier group are removed from later groups. This matches the “ground first wins” semantic — a node on the ground plane is at φ = 0 even if a signal conductor’s region spec nominally covers it.
- class magnelio.ports.PortSpecNumerical(name, plane, n_modes=1, epsilon_r=1.0, mode_type=None, window=None)#
Numerical-mode-solver port for hollow homogeneously-filled cross-sections.
Drives the numerical 2D curl-curl / node-Laplace eigenvalue solver (
Numerical2DModeSolver) for hollow waveguides whose cross-section has no analytical closed form (ridged, double-ridged, elliptical, circular with PEC bbox padding, …) or where a FIT-grid-native mode is preferred over an analytical projection.Scope: TE/TM modes on a hollow, homogeneously-filled cross-section. Multi-conductor TEM and inhomogeneous QTEM are served by
PortSpecMultiConductor.PEC walls are read from
mesh.pec_mask_edges— the canonical 3D-mesh source. Production setups define the wall geometry viaMesh.from_geometry()(OCC-meshed PEC body) orMesh.with_pec_boundaries()(BC-consolidated bbox faces); both populatemesh.pec_mask_edgesautomatically. For bareMesh.from_gridsetups without either, the factory falls back to the standard hollow-waveguide assumption (all four lateral bbox faces are PEC walls).- Parameters:
name (str) – Port label.
plane (BoxFace) – Bbox face on which the port lives.
n_modes (int, default 1) – Number of modes returned by the eigsh solver, ordered by ascending cut-off frequency.
epsilon_r (float, default 1.0) – Permittivity of the (homogeneous) cross-section filling. Used for the H-profile bake-in and the sigma heuristic.
mode_type (ModeType or None, default None) –
None(default) solves both TE and TM families and keeps then_modeslowest cut-offs, mixed types included — one operator injects/records/terminates every mode on the face (unified multi-mode port, WP-R3). PassModeType.TEorModeType.TMto restrict to one family.window (tuple of two corner points, optional) – Sub-rectangle of the face as two opposite corners in global tangential-axis ordering (
PortPlane.from_mesh()convention).None(default) covers the whole face. The window-boundary BCs follow the legacy edge rule: a port edge on a domain boundary inherits that wall’s BC, an interior edge inherits the port face’s BC (both read frommesh.pec_mask_edges).
- class magnelio.ports.PortSpecRectWG(name, plane, width_a, height_b, epsilon_r=1.0, center=(0.0, 0.0), n_modes=1)#
Rectangular-waveguide modal port (TE / TM, Phase 1).
- Parameters:
name (str) – Port label.
plane (BoxFace) – Bbox face on which the port lives.
width_a (float) – Cross-section dimension along the lower-numbered tangential global axis [m].
height_b (float) – Cross-section dimension along the higher-numbered tangential global axis [m].
epsilon_r (float, default 1.0) – Relative permittivity.
center (tuple[float, float], default (0.0, 0.0)) – Lower-left corner of the cross-section in the global tangential frame (lower-axis first).
n_modes (int, default 1) – Number of modes returned by the analytical solver, ordered by ascending cutoff frequency.
- class magnelio.ports.PortWaveguide(name, plane, corners=None, n_modes=1)#
Generic declarative waveguide port: “solve whatever is on this face”.
The mode-solver path (TEM / QTEM / TE-TM) is selected from the mesh cross-section at analysis-construction time — see the module docstring for the rules.
- Parameters:
name (str) – Unique port name.
plane (BoxFace or str) – Bbox face the port lives on (
"zmin",BoxFace.Z_MIN, …).corners (tuple of tuple, optional) –
Sub-rectangle of the face, given as two opposite corners
((x0, y0, z0), (x1, y1, z1))in world coordinates [m] — the same form asfrom_corners(). Corner order does not matter. The component along the face’s normal axis is fixed by plane already; write it asNone(or repeat the same value on both corners — differing values are rejected as a likely axis mix-up). An oversized rectangle is clipped to the domain and snapped to the nearest grid nodes, and a tangential component may beNoneto reach the domain boundary on that side. The window-boundary BCs follow the legacy edge rule: an edge on a domain boundary inherits that wall’s BC, an interior edge inherits the port face’s BC — so a port embedded in a PEC wall gets a PEC frame, which also counts as a conductor (ground) in the mode-path detection.None(default) covers the whole face.On an absorbing (CPML) face a port is the end of a conductor-enclosed guide reaching the wall — the neck of a horn, a coax entering the box: the window is required and must be enclosed by conductor on the port slab (align its corners with the guide’s inner walls), and the absorber is switched off in the columns behind it so the port’s own termination is what the guided wave meets. A whole-face port on an absorbing face, or a window whose ring lies in free space, is rejected.
n_modes (int, default 1) – Number of modes to solve on the port.
- class magnelio.ports.RefinementLevel(level, n_cells_port_plane, n_cells_3d, value, rel_change)#
One rung of the refinement ladder.
- Parameters:
level (int)
n_cells_port_plane (int)
n_cells_3d (int)
value (float)
rel_change (float)
- level#
0 is the user’s port-plane grid; level
kbisects itktimes along both tangential axes.- Type:
int
- n_cells_port_plane#
Cross-section cell count on the port plane.
- Type:
int
- n_cells_3d#
Cell count of the slab mesh.
- Type:
int
- value#
The target quantity at this level (full-model value).
- Type:
float
- rel_change#
|value − value_prev| / |value|;nanat level 0.- Type:
float
- class magnelio.ports.RegionConductor(axis_a_range, axis_b_range)#
Axis-aligned rectangular conductor region on the port plane.
The two ranges are given in the global axis ordering — the same convention as
PortSpecCoax.centerandPortSpecRectWG.width_a. Concretely:X-face port (u/v axes are y, z):
(y_range, z_range).Y-face port (u/v axes are x, z):
(x_range, z_range).Z-face port (u/v axes are x, y):
(x_range, y_range).
The factory swaps the pair internally on MAX faces so the user description does not depend on whether the port is MIN or MAX.
Primal 2D nodes whose physical (u, v) coordinate falls inside
[range_a_lo, range_a_hi] × [range_b_lo, range_b_hi](with a small tolerance relative to the port-plane extent) are taken to belong to this conductor.Typical uses: rectangular inner conductor of rect coax; the strip of a microstrip; a square bond pad.
- Parameters:
axis_a_range (tuple[float, float])
axis_b_range (tuple[float, float])
- class magnelio.ports.WallConductor(face)#
Single bbox-wall PEC conductor (e.g. microstrip ground plane).
facemust be a bbox face whose normal axis is tangential to the port plane (a “lateral” face from the port plane’s perspective). All primal 2D nodes lying on that wall are taken to belong to this conductor. Mirrors the validation in_build_lateral_pec_edge_mask().- Parameters:
face (BoxFace)
- magnelio.ports.refine_port_modes(model, control, mesh, port, *, levels=3, target='auto', mode=0, tol=0.001, slab_cells=6, verbose=None)#
Converge a port mode’s parameter by refining the port plane alone.
Builds a slab of the model behind the port face — the model’s shapes, materials and lateral closure, cut
slab_cellsof the user’s mesh in with the mesher’s own domain clip — and meshes it with the user’s mesh control at level 0 and every tangential cell split2^kways at levelk. Level 0 reproduces the port report ofmesh; the ladder converges the cross-section at4×the cells per level instead of the8×a 3D refinement costs, on a slab a few cells deep.- Parameters:
model (GeometryModel) – The model
meshwas generated from, ports declared.control (MeshControl) – The mesh control
meshwas generated with; every level keeps it and sets itssubdivideon the tangential axes.mesh (Mesh) – The user’s mesh (supplies the level-0 grid,
f_maxand the port declaration).port (str) – Name of a declared waveguide port.
levels (int, default 3) – Number of ladder rungs including level 0 (at most).
target ({"auto", "z_line", "epsilon_eff", "f_cutoff"}) – Quantity to converge.
"auto"(default) follows the mode family: the line impedance of a TEM or quasi-TEM mode, the cut-off frequency of a TE or TM mode, which has no line impedance. The report names the quantity it converged.mode (int, default 0) – Mode index on the port.
tol (float, default 1e-3) – Stop once the relative change between rungs falls below it.
slab_cells (int, default 6) – Depth of the slab in cells of the user’s mesh behind the port face (at least four: the port’s equidistant buffer).
verbose (bool, optional) – Report each level as it runs — the mesh build and port solve of the rung in progress, then its converged value.
None(the default) followsmagnelio.set_verbosity().
- Return type:
- Raises:
ValueError – If the port is not declared on the mesh, the model declares a symmetry plane on the port’s axis, or the target is not defined for the mode.