EME
Every section function below accepts a ports argument, which names, windows, or displaces the ports on either end of the section, in place of its default left and right ports. Sections are otherwise connected in the order they are declared; use connect_ports to wire named ports explicitly instead, including into branching topologies. See Ports for the port model, the Port and Bounds classes, and make_angled_facet_port() for declaring an angled facet on a port.
- EME_settings
Declare global EME defaults that are inherited by sections created afterward. Each parameter left unspecified leaves the corresponding stored default unchanged. A section’s own
settingsargument at creation still overrides these globals. Sections created before this call are not affected.- Parameters:
apply_scattering (bool or list[float]) – whether interfacial scattering loss is automatically applied to the S-matrix, either for every wavelength (True), no wavelengths (False), or only the listed wavelengths, default: False
beta_interpolation (str) – either ‘uniform’ or ‘linear’ to specify how the propagation constant is interpolated between z-slices of a taper/gds section, default: ‘uniform’
junction_normalization (bool or str or dict) – controls how junction S-matrices are power-normalized; either a single bool/’gain’ value applied to both junction kinds, or a dict with ‘inter_section’ and ‘intra_section’ keys, each accepting True (full SVD unitarization), False (raw, unnormalized), or ‘gain’ (clip singular values at 1 while keeping the raw lossy mode-matching), default: ‘gain’ for inter-section junctions and True for intra-section junctions. It applies to junctions with a plane-wave side (
pwd_section) or an angled facet. A junction between two mode-solved cross-sections conserves power by construction and is not normalized.overlap_variation (float) – threshold of mode-list overlap between z-slices used by the automatic z-slicing bisection for taper/gds sections, default: 0.01
minimum_z_step (float) – [nm] the minimum allowed z-step for the automatic z-slicing bisection, default: 0.1
snap_window (float) – the fraction of a slice’s length around its midpoint within which the automatic z-slicing bisects at a cross-section already solved elsewhere (for the same settings, mesh and wavelength) instead of at the midpoint, which saves a mode solve wherever two tapers or GDS sections share widths. 0 always bisects at the midpoint, default: 0.25
initial_slices (str) – how a taper or GDS section is sliced before the automatic z-slicing bisection refines it, either ‘auto’ (boundaries placed where the cross-section changes, from its rasterized refractive index: none along a straight run, evenly along a linear taper, densely inside a short fast feature, and at every corner of a GDS outline) or ‘single’ (one slice, the behavior before EMode 1.0.6). Refinement still runs afterward and decides the final slicing, so the choice moves results only within its tolerance and changes how many rounds it takes. A
warm_startinEMEtakes its slices from the previous solve instead, default: ‘auto’simulation_name (str) – simulation name, default: ‘emode’
A section’s own
settingsdictionary accepts the keys above (exceptsimulation_name), and four more that tune the ‘auto’ initial slicing. They are rarely needed, andEME_settingsdoes not take them.schedule_samples: the number of positions along the section at which the refractive index is rasterized (no mode solve) to find where it changes, at least 2, default: 128schedule_change_per_slice: the relative change in the rasterized index that one initial slice spans, so a smaller value starts with more slices, default: 0.05schedule_max_slices: the largest number of initial slices, default: 64schedule_coarsen: how many times coarser than the profile’s mesh the index is rasterized, at least 1, default: 4
For example,
taper_section(..., settings={'schedule_change_per_slice': 0.02}). Initial slice boundaries closer together thanminimum_z_stepare merged.
- straight_section
Define a uniform-cross-section waveguide section for the EME solver. Sections are placed sequentially in the z-direction in the order they are declared (or updated, if
namealready exists).- Parameters:
name (str) – section name, default: an auto-generated number
profile (str) – name of the profile that defines the section’s cross-section
length (float) – [nm] the length of the section
offset (float or tuple[float, float]) – [nm] transverse displacement of this section relative to whatever its ports connect to; if only a single value is given it is assumed to be the x-offset, default: (0, 0). Legacy: this is the same displacement as
Port’s ownoffsetapplied to every port of the section at once, and setting both on one section raises an error. Prefer declaringoffseton the specific port that sits off-axis.ports (list[Port] or None) – replace the section’s default
[Port('left', None, 'left'), Port('right', None, 'right')]on a per-side basis, where a supplied port replaces every existing port on the same side, and multiple ports may share a side. SeePort, default: None (keep existing/default ports)nonlinear (SHGProcess or SFGProcess or DFGProcess or PulsedProcess or False or None) – declare a \(\chi^{(2)}\) process on this section (EMode3D only), one of
SHGProcess(pump_wavelength=...),SFGProcess(pump_wavelength_1=..., pump_wavelength_2=...)orDFGProcess(pump_wavelength=..., signal_wavelength=...)fromemodeconnection. You name the process’s input wavelength(s); the remaining one follows from energy conservation and is matched against the section’s own profile wavelengths. Quasi-phase matching is declared on the process withpoling_period[nm], plusduty_cycle(default: 0.5) andqpm_order(default: 1);inverted=Trueinstead flips the local \(\chi^{(2)}\) sign for this section alone, the building block for poling assembled by hand from alternating sections. The two routes agree. Omittingnonlinear(or passingNone) when updating an existing section leaves the declared process in place, passing a new one replaces it, andnonlinear=Falseremoves it, so the section propagates linearly again. A pump must also be declared, seeexcitationinsettings, and the power-dependent result is read back withget('response'). The process also carriesz_samples(default: 100), the number of points at which the forward amplitudes are recorded along each slice of this section once the driven solve converges. Those reach the caller asget('response').power_vs_z(wavelength), which returns the pump or signal power against position from a single solve rather than one solve per length. Set it to 0 to skip the sampling. A pulse’s nonlinearity is declared instead with aPulsedProcess, see pulsed nonlinear propagation. Default: Nonesettings (dict or None) – per-section overrides of the
EME_settings, merged onto the current global EME settings (or onto the section’s existing settings, when updating), e.g.settings={'overlap_variation': 0.005}, default: Nonesimulation_name (str) – simulation name, default: ‘emode’
- pwd_section
Define a free space section, in which the field is expanded in plane waves (a plane-wave decomposition, PWD) over a uniform material, rather than in the guided modes of a cross-section. This is intended for gaps, facets, and free space propagation between waveguide sections; the junctions between a free space section and its neighbors are computed analytically instead of from a mode solve.
The basis is the set of plane-wave harmonics of the section window, with transverse wavevectors
kx = 2*pi*m/window_widthandky = 2*pi*n/window_height, each harmonic carrying both a TE and a TM polarization. At least one ofmax_order,max_kt, ornum_modesis required to truncate the basis; when more than one is given, they are applied in the ordermax_order,max_kt,num_modes.- Parameters:
name (str) – section name, default: an auto-generated number
length (float) – [nm] the length of the section
material (str or ~MaterialProperties or ~MaterialSpec) – the material filling the section, either a material name (from the material database) or a ~MaterialProperties or ~MaterialSpec object; must be isotropic, default: “Vacuum”
profile (str) – name of the profile that supplies the default window and the wavelength(s) of the section, default: ‘_default’
window (tuple[float, float] or None) – [nm] the (width, height) of the plane-wave window, which overrides the window of
profile, default: None (use thewindow_widthandwindow_heightofprofile)offset (tuple[float, float]) – [nm] transverse displacement of the window’s origin, which is its horizontal center and bottom edge, default: (0, 0)
max_order (tuple[int, int] or None) – the largest harmonic order to keep in the x- and y-directions, so that
|m| <= max_order[0]and|n| <= max_order[1], default: Nonemax_kt (float) – [1/nm] the largest transverse wavevector magnitude to keep, default: None
num_modes (int) – the largest number of modes to keep, counting both polarizations of each harmonic, and applied after
max_orderandmax_kt; the basis always keeps a harmonic together with its opposite-direction pair, so the resulting count can land slightly below the requested value, default: Noneports (list[Port] or None) – replace the section’s default
[Port('left', None, 'left'), Port('right', None, 'right')]on a per-side basis, where a supplied port replaces every existing port on the same side, and multiple ports may share a side. SeePort, default: None (keep existing/default ports)settings (dict or None) – per-section overrides of the
EME_settings, default: Nonesimulation_name (str) – simulation name, default: ‘emode’
- taper_section
Define a section that linearly interpolates its cross-section between two profiles for the EME solver, automatically slicing the z-direction to track the mode evolution.
- Parameters:
name (str) – section name, default: an auto-generated number
profile (str) – name of the profile that defines the section beginning
profile_end (str) – name of the profile that defines the section ending
length (float) – [nm] the length of the section
ports (list[Port] or None) – replace the section’s default
[Port('left', None, 'left'), Port('right', None, 'right')]on a per-side basis, where a supplied port replaces every existing port on the same side, and multiple ports may share a side. SeePort, default: None (keep existing/default ports)nonlinear (SHGProcess or SFGProcess or DFGProcess or PulsedProcess or False or None) – declare a \(\chi^{(2)}\) process on this section (EMode3D only), one of
SHGProcess(pump_wavelength=...),SFGProcess(pump_wavelength_1=..., pump_wavelength_2=...)orDFGProcess(pump_wavelength=..., signal_wavelength=...)fromemodeconnection. You name the process’s input wavelength(s); the remaining one follows from energy conservation and is matched against the section’s own profile wavelengths. Quasi-phase matching is declared on the process withpoling_period[nm], plusduty_cycle(default: 0.5) andqpm_order(default: 1);inverted=Trueinstead flips the local \(\chi^{(2)}\) sign for this section alone, the building block for poling assembled by hand from alternating sections. The two routes agree. Omittingnonlinear(or passingNone) when updating an existing section leaves the declared process in place, passing a new one replaces it, andnonlinear=Falseremoves it, so the section propagates linearly again. A pump must also be declared, seeexcitationinsettings, and the power-dependent result is read back withget('response'). The process also carriesz_samples(default: 100), the number of points at which the forward amplitudes are recorded along each slice of this section once the driven solve converges. Those reach the caller asget('response').power_vs_z(wavelength), which returns the pump or signal power against position from a single solve rather than one solve per length. Set it to 0 to skip the sampling. A pulse’s nonlinearity is declared instead with aPulsedProcess, see pulsed nonlinear propagation. Default: Nonesettings (dict or None) – per-section overrides of the
EME_settings(notablyoverlap_variationandminimum_z_step, which control the automatic z-slicing), default: Nonesimulation_name (str) – simulation name, default: ‘emode’
- bend_section
Define a circular bend for the EME solver: the cross-section of
profileswept along an arc. The bend is placed in the layout like any other section, and sections declared after it continue from its end, turned bysweep_angle.An anisotropic crystal is fixed in the chip, so the guide sees it turn along the bend. When a material is anisotropic in the plane of the chip (x-cut lithium niobate, for example), the bend is sliced along its heading and refined like a taper, and every section placed after a turn sees the crystal turned with it. A bend of an isotropic material, or of a crystal whose optic axis is vertical (z-cut thin film), is a single slice and a single mode solve. A
copy_sectionreuses its source’s S-matrix, so it raises an error when its own placement would show the crystal differently, and asks for the copy to be declared as its own section.A bend has no mirror symmetry about x, so an x symmetry wall in the profile’s
boundary_condition(such as ‘0S’ or ‘SA’) is replaced by ‘0’ with a warning, and ‘TE’, ‘TM’, ‘TE-h’ and ‘TM-h’ keep only the vertical fold. Updating an existing bend changes only the arguments given.- Parameters:
name (str) – section name, default: an auto-generated number
profile (str) – name of the profile that defines the cross-section
radius (float) – [nm] the bend radius, measured to the origin of the profile’s x axis, must be positive, required for a new bend
sweep_angle (float) – [rad] the angle the bend turns through, positive toward +x and negative toward -x, not zero, required for a new bend
method (str) – how each slice is solved, either ‘cylindrical’ (the bend in cylindrical coordinates, as
bend_radiusinsettings) or ‘TO’ (transformation optics, seebend_methodinsettings), default: ‘cylindrical’ports (list[Port] or None) – replace the section’s default
[Port('left', None, 'left'), Port('right', None, 'right')]on a per-side basis, where a supplied port replaces every existing port on the same side, and multiple ports may share a side. SeePort, default: None (keep existing/default ports)settings (dict or None) – per-section overrides of the
EME_settings(notablyoverlap_variationandminimum_z_step, which control the automatic z-slicing), default: Nonesimulation_name (str) – simulation name, default: ‘emode’
- gds_section
Define a section whose cross-section varies along z according to a mask imported from a GDS file, for more complex geometries defined with third-party layout tools.
- Parameters:
name (str) – section name, default: an auto-generated number
profile (str) – name of the profile that defines the section’s cross-section outside of the GDS mask
gds_path (str) – path to the GDS file used to mask the section
layer_map (dict[str, int]) – mapping of profile shape names to GDS layer numbers, used to determine which shapes in
profileare masked by which GDS layerlength (float) – [nm] the length of the section, default: derived from the GDS bounding box
cell_index (int or str) – the cell index (or name) in the specified GDS file, default: 0
scale (float) – unit scale factor applied to the GDS coordinates (e.g. use 1000 if the GDS file is drawn in microns but the simulation is in nanometers), default: 1
port_poses (dict) – explicit port positions/orientations at the section boundaries, default: derived from the GDS bounding box (left port at w=0, right port at w=length)
heal (bool) – whether to heal small gaps/self-intersections in the imported GDS polygons before meshing, default: True
grow (float) – amount to grow imported GDS polygons by, to close small gaps, default: 1e-3
nonlinear (PulsedProcess or False or None) – declare a pulse’s nonlinearity on this section as a
PulsedProcess(see pulsed nonlinear propagation),Falseto remove one. The CW \(\chi^{(2)}\) processes are not available on a GDS section. Default: Noneports (list[Port] or None) – replace the section’s default
[Port('left', None, 'left'), Port('right', None, 'right')]on a per-side basis, where a supplied port replaces every existing port on the same side, and multiple ports may share a side. SeePort, default: None (keep existing/default ports)settings (dict or None) – per-section overrides of the
EME_settings, default: Nonesimulation_name (str) – simulation name, default: ‘emode’
Note
Once sections are declared, call plot() with plane='z-x' or plane='z-y' to preview a geometry-only ‘Outline’ of the section layout before running EME.
- copy_section
Place a second instance of an already-declared section in the chain, reusing its already-computed S-matrix instead of re-solving it.
- Parameters:
name (str) – section name, default: an auto-generated number
section_name (str) – name of the existing section to copy
mirror (bool) – whether to reverse the placement along the propagation direction (swapping the left/right ports), default: False
port_swap (dict) – explicit port-name mapping to use instead of the automatically computed left/right swap when
mirroris True, default: Noneports (list[Port] or None) – relabel/window this copy’s own left/right boundary, with the same semantics as any other section’s
ports, independent ofport_swapand of the source section’s own ports. SeePort, default: None (keep existing/default ports)settings (dict or None) – per-section overrides of the
EME_settings, default: Nonesimulation_name (str) – simulation name, default: ‘emode’
- connect_ports
Override the default left/right adjacency wiring between named ports declared with the
portsargument of any section function.Connecting two ports also pins their coordinate systems together: the two ports’ origins (the horizontal centre and bottom edge of each cross-section) are made to coincide, so the connection is what positions one section relative to the other. Use
Port’soffsetto displace a section off that shared origin, and itswindowto choose which part of a wider cross-section the port exposes. The first section you declare defines the global frame that plots are drawn in.- Parameters:
pairs (list[tuple[str, str]] or list[tuple[str, str, JunctionOverride]]) – a list of
('<section_name>.<port_name>', '<section_name>.<port_name>')pairs to connect, e.g.[('a.right', 'b.left'), ('c.right', 'd.left')]. A port can only have one connection, so declaring a new connection for a port that already had one supersedes it. Names are resolved against the actual declared sections/ports atEMEbuild time. An entry may carry an optional third element, aJunctionOverride, configuring the junction that connection forms, e.g.[('a.right', 'b.left', JunctionOverride(junction_normalization=False))].simulation_name (str) – simulation name, default: ‘emode’
- class JunctionOverride
Settings for a single junction, passed as the optional third element of a
connect_portsentry. Every parameter left unspecified inherits the value the junction’s sections resolved, so setting one does not disturb the others.These settings belong to the connection rather than to either port because each one describes the interface between the two sections – which algebra joins their mode sets, how the resulting scattering matrix is normalized – and not one side of it.
Only an explicitly connected junction can carry these. A junction formed by the default left/right adjacency has nowhere to declare them, so name that pair in
connect_portsto configure it, which supersedes the adjacency. The internal junctions of a taper or GDS section’s automatic z-slicing are controlled by that section’ssettingsinstead.- Parameters:
junction_normalization (bool or str or None) – how this junction’s scattering matrix is power-normalized – True (full SVD unitarization), False (raw, unnormalized), or ‘gain’ (clip singular values at 1 while keeping the raw lossy mode-matching), for a junction with a plane-wave side or an angled facet, default: None (inherit)
- EME
Calculate the complete scattering matrix of all defined sections using the eigenmode expansion method (EME). Before solving anything it checks the layout (see
check_layout) and raises an error when two sections overlap or a loop of connected sections misses closing (its two ports more thanminimum_z_stepapart, or more than 1e-6 rad from facing each other), and warns when a section’s outline crosses itself or a section is reached by no connection.- Parameters:
warm_start (bool) – whether to seed each taper/gds section’s automatic z-slice refinement from the previously solved chain (when available), instead of re-refining from scratch, default: False
simulation_name (str) – simulation name, default: ‘emode’
- check_layout
Check the layout of the declared sections without solving. Every section is placed where its connections put it and drawn top down from its shapes that do not span the window. Returns a
LayoutReportwithoverlaps(pairs of sections whose outlines overlap, as(section, section, area)with the area in nm2, where sections that only share a port edge do not overlap),self_intersecting(sections whose own outline crosses itself, such as a bend swept past a full turn),closures(for each connection that closes a loop, how far apart its two ports are in nm and how far from facing each other in radians), andunplaced(sections no connection reaches, which are placed after the section declared before them).max_closure()returns the largest closure distance and angle, or zeros without a loop.plot(view='layout')draws the same layout.LayoutReportis defined inemodeconnection.- Parameters:
simulation_name (str) – simulation name, default: ‘emode’
- chi2_spectrum
Conversion spectrum of a \(\chi^{(2)}\) section, solved sparsely in wavelength (EMode3D only). Returns the signal power out over the pump power in at every wavelength in
values.A nonlinear spectrum oscillates with the phase mismatch, so it cannot be interpolated – at any useful resolution it has to be evaluated point by point. What can be interpolated is what the coupled-mode equations consume: the coupling and the propagation constants, which vary smoothly with wavelength. So the modes are solved at a handful of wavelengths chosen by how fast the mode list is actually moving, and the response is then evaluated at every requested wavelength from interpolated coupling. Against a directly solved 13-point spectrum across a phase-matching peak, five solves reproduce every point to four decimals, sidelobes included.
Quasi-phase matching is included: the grating enters as a wavevector shift and a Fourier coefficient built from
poling_period,duty_cycleandqpm_order, none of which depend on wavelength, so a poled section keeps its exact grating while its phase mismatch moves with the interpolated propagation constants.Requires a chain with a declared \(\chi^{(2)}\) section (see
nonlinearonstraight_section/taper_section) and a declared pump (excitationinsettings).- Parameters:
values (list or array) – pump wavelengths [nm] to report at; the signal wavelength follows the declared process
section (str) – which nonlinear section to scan, default: the only one declared
tolerance (float) – the largest mode-list change tolerated between adjacent solves, default: 1e-3
minimum_step (float) – [nm] the smallest wavelength gap the sampler will bisect into, default: the output spacing, since resolving finer than you asked to see cannot change the reported curve
initial_points (int) – solves to place before any bisection, default: 5
power (float) – [W] pump power, default: the declared excitation’s
simulation_name (str) – simulation name, default: ‘emode’
Returns a dictionary with
values,conversion(signal out over pump in),solved_wavelengths(where the solver actually ran), andunconverged– the intervals, if any, the sampler could not resolve totolerancebefore reachingminimum_step.
- free_space_field
Declare, or update, a free-space field: a Gaussian beam launched into a port of the chain. This is an excitation, not a section. It does not appear in the scattering matrix or in the layout.
After
EME,plot(excitation=name)(or the plot window’s Mode menu,'<name> (free space)') renders the field the beam launches, projected onto the target port’s modes with the same pairing the junctions use. Re-declaring an existingnameupdates only the arguments you give.- Parameters:
name (str) – free-space field name, default: the next number
port (str) – the external port the beam enters, either a bare side
'left'(default) or'right', or a qualified'<section>.<port>'name. The beam travels inbound from that port.waist (float) – [nm] the 1/e field radius \(w\) in \(\exp(-r^2/w^2)\), required when declaring a new field
center (tuple[float, float]) – [nm] beam center
(x, y)in the port’s cross-section coordinates, default: (0, 0)tilt (tuple[float, float]) – [degrees]
(theta_x, theta_y), where a positivetheta_xsteers the beam toward +x. This is the angle inside the medium the beam travels through, default: (0, 0)component (str) – the one transverse E component the beam carries,
'Ex'(default) or'Ey'amplitude (float) – peak field value, default: 1
wavelength (float) – [nm], default: None (each port’s own wavelength)
simulation_name (str) – simulation name, default: ‘emode’
- free_space_field_diagnostics
How much of a declared free-space field’s power the target port’s modal basis actually captures, after
EMEhas solved the chain. The solver already warns when this falls below 90%. This returns it as a value a script can check or plot instead of parsing a log line.A low captured fraction means the port’s modes cannot represent the beam. Raise that section’s
num_modes, or widen its window, before trusting a coupling number computed from it.- Parameters:
name (str) – the free-space field to diagnose
wavelength (float) – [nm] which of a multi-wavelength chain’s ports to diagnose, default: None (the lowest wavelength present)
simulation_name (str) – simulation name, default: ‘emode’
Returns a
FreeSpaceProjectionwithcaptured_fraction, its complementdropped_fraction, the resolvedportandwavelength, and the launch basis’snum_modes.
- plot_S_matrix
Colormap plot of the transmission or reflection component of the EME scattering matrix.
- Parameters:
input (int or str) – input field (first number of the scattering matrix identifier), default: 0
output (int or str) – output field (second number of the scattering matrix identifier), default: 1
plot_function (str or None) – specify the function to apply to the plot data (‘abs^2’, ‘angle’, ‘real’, ‘imag’), default: ‘abs^2’
file_name (str) – if specified, forces the function to save a file with the given parameters and will not display the interactive plot, file is saved under a directory called EM_figures, default: None
file_type (str) – file type for saving a plot, ‘pdf’ or ‘png’, default: ‘’ (no extension is added to
file_nameunless a file type is given)simulation_name (str) – simulation name, default: ‘emode’
Monitors
A monitor is a plane inside the chain on which the solved field is sampled after EME. It is output only: it is not a port, does not enter the scattering matrix and does not change the solve, so monitors can be added, moved or removed without solving again. The plane runs across the full window in x and is tilted about x, so it can sample the light a grating coupler radiates upward. monitor_field returns the field on it, and monitor_coupling its coupling to a tilted Gaussian beam, such as the mode of a fiber above a grating. plot() draws each monitor’s plane on the ‘z-y’ panel, and sweep(result='monitor_coupling') sweeps the coupling (see sweep). The ‘EME: Grating Coupler’ example uses all three.
- monitor
Declare a monitor. Declaring the same name again replaces it.
- Parameters:
name (str) – the monitor’s name
w (float) – [nm] the position along the chain, from its left port, that the plane passes through
y (float) – [nm] the height that the plane passes through at
w. An untilted plane must lie inside the window, between 0 andwindow_heightangle (float) – [degrees] the tilt of the plane about x from horizontal, strictly between -90 and 90, where a positive angle tips the far end of the plane up, default: 0
length (float or None) – [nm] the extent along the plane, centered on (
w,y), default: None (as far as the chain and the window allow)resolution (float or None) – [nm] the sampling step along the plane, default: None (the window’s
x_resolution)simulation_name (str) – simulation name, default: ‘emode’
- monitor_field
The field on a monitor’s plane after
EME, for 1 W launched in one mode of one port.- Parameters:
name (str) – the monitor’s name
port (str) – the external port the chain is excited from, default: ‘left’
mode (int) – the launched mode, default: 0
wavelength (float or None) – [nm] which of a multi-wavelength chain’s wavelengths to use, the nearest one present, default: None (the chain’s first)
simulation_name (str) – simulation name, default: ‘emode’
Returns a
PlaneFieldwithfields, a dictionary of the six components (‘Ex’, ‘Ey’, ‘Ez’, ‘Hx’, ‘Hy’, ‘Hz’) on the plane, each a complex array of shape (len(x), len(s)), wherex[nm] runs across the plane ands[nm] along it, at chain positionswand heightsy[nm].Snis the time-averaged Poynting flux through the plane (positive along its upward normal),power_through_plane[W] its integral, andpower_inthe 1 W launched, sopower_through_planeis also the fraction of the launched power that crosses the plane.
- monitor_coupling
The coupling between a launched waveguide mode and a Gaussian beam through a monitor’s plane, after
EME. It is the fraction of the launched power crossing the plane times the normalized overlap of the field’spolarizationcomponent with the beam. By reciprocity the same number is the coupling from the beam into the launched mode, which is the figure a grating coupler is designed for. Only the overlap is computed, so trying other beams costs no solve.- Parameters:
name (str) – the monitor’s name
mode_field_diameter (float) – [nm] the beam’s mode field diameter, for example 10.4e3 for SMF-28 at 1550 nm
angle (float) – [degrees] the beam’s angle from the plane’s normal, positive toward +s (along the chain), default: 0
center (tuple[float, float] or None) – [nm] the beam’s center (x, s) on the plane, default: None (centered on the plane)
index (float or None) – the refractive index of the medium the beam travels in, default: None (the profile’s background material)
polarization (str) – the field component the beam couples to, ‘x’, ‘y’, or ‘s’ (along the plane), default: ‘x’
port (str) – the launching port, default: ‘left’
mode (int) – the launched mode, default: 0
wavelength (float or None) – [nm] which of a multi-wavelength chain’s wavelengths to use, default: None (the chain’s first)
simulation_name (str) – simulation name, default: ‘emode’
Returns a
BeamCouplingwithcoupling, its two factorspower_fractionandoverlap, and the beam it was computed for (mode_field_diameter,center,angle,index,polarization) atwavelength.
Pulsed nonlinear propagation
A femtosecond pulse is declared as the excitation, settings(excitation=PulsedSource(...)), and a section’s nonlinearity with nonlinear=PulsedProcess(...) on straight_section, taper_section or gds_section (EMode3D only). EME refines the chain at the pulse’s center wavelength, solves each distinct cross-section at dispersion_samples wavelengths across the pulse’s band, and propagates the pulse forward through every slice and junction with \(\chi^{(2)}\), Kerr (\(\chi^{(3)}\)), Raman and two-photon absorption. Reflections and power scattered into modes that are not tracked are discarded and reported, with a warning where that is not safe. The classes below are imported from emodeconnection.
The nonlinear coefficients come from the materials: \(\chi^{(2)}\) from the material’s \(d\) tensor, \(\chi^{(3)}\) from its nonlinear index \(n_2\) as \(\chi^{(3)} = \tfrac{4}{3}\varepsilon_0 c n^2 n_2\), the Raman response from the material that holds most of the Kerr overlap, and two-photon absorption from its coefficient \(\beta_\mathrm{TPA}\), active only for photon pairs above the material’s bandgap. In the material database, SiO2, SiN, LN and LN_MgO carry \(n_2\), SiO2 (Blow and Wood) and LN/LN_MgO (four A1(TO) lines, Bache and Schiek) a Raman response, and Si, AlGaAs, LN and LN_MgO a two-photon coefficient, each with its reference. A material of your own takes the same through MaterialProperties(n=..., n2=..., raman=(fraction, [(weight, position, half_width), ...]), tpa=..., bandgap=...), with \(n_2\) in m2/W, the Raman line positions and half widths in cm-1, \(\beta_\mathrm{TPA}\) in m/W and the bandgap in eV. PulsedProcess(chi3=True) raises an error naming a material that has no \(n_2\) (silicon, for one).
- class PulsedSource
A pulse launched into one port of the circuit, for
settings(excitation=...).- Parameters:
center_wavelength (float) – [nm] the carrier wavelength, inside
wavelength_rangeduration (float) – [fs] the intensity FWHM, required except for
shape='cw'energy (float) – [pJ] the pulse energy, give exactly one of
energyandpeak_powerpeak_power (float) – [W] the peak power
port (str) – the launch port, default: ‘left’
mode (int or dict) – the tracked mode that carries the pulse, or a dictionary
{mode: amplitude}of complex amplitudes that splits it between tracked modes (normalized, so only their ratios matter), default: 0shape (str) – ‘sech’, ‘gaussian’, or ‘cw’ (a continuous wave of
peak_poweratcenter_wavelength, with nodurationorenergy), default: ‘sech’chirp (float) – the chirp \(C\) of \(\exp(j C t^2 / 2 T_0^2)\), where a positive value raises the instantaneous frequency across the pulse, default: 0
repetition_rate (float) – [Hz] for average powers, default: None
wavelength_range (tuple[float, float]) – [nm] the span of the frequency grid, default: (450, 3500)
num_points (int) – frequency points, even and at least 16, which with
wavelength_rangeset the time window (the number of points over the frequency span, 28 ps at the defaults), default: 16384alias (int) – oversampling of the real-field products, 1, 2 or 3 (2 suffices for \(\chi^{(2)}\), 3 for \(\chi^{(3)}\)), default: 2
- class PulsedProcess
The nonlinear optics of one section for a pulsed simulation, for a section’s
nonlinear=.- Parameters:
chi2 (bool) – include \(\chi^{(2)}\), default: True
chi3 (bool) – include the Kerr effect, default: True
raman (bool) – include the delayed Raman part of the Kerr response, default: True
raman_mode (str) – ‘dominant’ (the response of the strongest field pattern, fast) or ‘full’, default: ‘dominant’
tpa (bool or None) – two-photon absorption on (True), off (False), or on wherever a material has a coefficient (None), default: None
modes (list[int] or None) – the tracked mode indices at the center wavelength, default: None (the source’s mode or modes)
poling (Poling or None) – the section’s domain pattern, default: None (unpoled)
dispersion_samples (int) – wavelengths at which each cross-section is solved, Chebyshev nodes over the source’s
wavelength_range, at least 4, default: 24pattern_threshold (float) – singular value, relative to the first, below which field patterns are dropped, in [0, 1), default: 1e-3
max_rank (int) – the largest number of field patterns, default: 12
- class Poling
The domain pattern of a poled section. Give exactly one of
period,z_knotswithperiods, anddomain_walls.- Parameters:
period (float) – [nm] a constant poling period
z_knots (list[float]) – [nm] positions along the section at which
periodsare given, interpolated between them (a chirp), at least 2periods (list[float]) – [nm] the local period at each knot
domain_walls (list[float]) – [nm] explicit domain wall positions along the section, strictly increasing
duty_cycle (float) – the fraction of each period in the first domain, default: 0.5
interpolation (str) – ‘linear’ or ‘spline’ between the knots, default: ‘linear’
inverted_first (bool) – start with an inverted domain, default: False
jitter_rms (float) – [nm] rms of a Gaussian random displacement of every wall, for fabrication tolerance studies, default: 0
seed (int) – the seed of the jitter, default: None
- class PulseResponse
Returned by
get('pulse_response')afterEMEorpulse_propagate.spectrumis (records, modes, points), the root-energy spectrum of every tracked mode in \(\sqrt{\mathrm{J/Hz}}\) onfrequency[Hz], withwavelength[nm] the same axis,z[nm] the record positions andenergy[pJ] per record and mode.junction_lossis, per junction, the fraction of the arriving energy that left the tracked modes there, andrank_per_sliceandsamples_per_slicereport the field patterns and mode solves of each slice.edge_energyis, per record, the fraction of the energy in the outer 5 % of the time window,domain_walls[nm] the positions along the chain of the domain walls the run used (jitter included), andstepsandrejected_stepscount the propagation steps.band_energy(wavelength_min, wavelength_max, z=None, mode=None)returns the energy [pJ] in a band at the record nearestz(default: the output), summed over the tracked modes unlessmodeis given.band_power(...)returns the average power [W] of a pulse train, withrepetition_ratetaken from the source unless given.psd(z, mode)returns the spectral density in dB relative to 1 pJ/nm,envelope(z, mode)the time [fs] and complex envelope [\(\sqrt{\mathrm{W}}\)], andenergy_outside_window()the largest fraction of the energy found in the outer 5 % of the time window. Above about 1e-3 the pulse is wrapping around the window, andnum_pointsshould grow.
- pulse_propagate
Propagate the pulse again through the chain the last
EMEprepared, without any mode solve (EMode3D only). Use it to try another poling, for example a chirp or fabrication jitter on the domain walls, at the cost of the propagation alone.- Parameters:
poling (Poling or dict or None) – a new domain pattern for every section with a
PulsedProcess(a singlePoling), or for the named sections (a dictionary of section name toPoling), default: None (keep the declared poling)records (int) – number of evenly spaced positions along the chain at which the spectrum is recorded, default: 100
local_error (float) – relative error allowed per propagation step, default: 1e-6
simulation_name (str) – simulation name, default: ‘emode’
The prepared chain lives for the session. After
open()of a saved file, runEMEagain first. The result is read back withget('pulse_response').