cbeam.waveguide#

This page contains the documentation for the waveguide submodule, which functionally defines different kinds of waveguides, enables the creation of custom waveguides, and handles mesh generation for finite element analysis.

Waveguide class#

class cbeam.waveguide.Waveguide(prim3Dgroups)#

a Waveguide is a collection of prim3D objects (primitive 3D shapes like circular pipes and boxes), organized into layers as a nested list. the refractive index of earlier layers is overwritten by later layers.

__init__(prim3Dgroups)#

initialize a Waveguide object.

Parameters:

prim3Dgroups – a (potentially) nested list of prim3D objects. later top-level elements overwrite earlier ones, in terms of refractive index.

assign_IOR()#

build a dictionary which maps all material labels in the Waveguide mesh to the corresponding refractive index value

isolate(k)#

create a refractive index dictionary that sets all channels except one to the background index. ‘channels’ are assumed to be stored in the last list of self.prim3Dgroups. override this if your waveguide is different.

Parameters:

k – index of the channel to isolate

make_mesh(writeto=None)#

construct a finite element mesh for the waveguide at current z (default 0).

Parameters:

writeto (str or None) – filename for mesh (no extension). if None, no file is saved.

make_mesh_bndry_ref(writeto=None)#

construct a mesh with boundary refinement at material interfaces.

Parameters:

writeto (str or None) – filename for mesh (no extension). if None, no file is saved.

plot_boundaries()#

plot the boundaries of all prim3Dgroups. For unioned primitives, all boundaries of the original parts of the union are plotted in a lighter color.

plot_mesh(z=None, mesh=None, IOR_dict=None, alpha=0.1, ax=None, plot_points=True, verbose=True)#

plot a mesh and associated refractive index distribution

Parameters:
  • z – the z coordinate for the mesh we want to plot. if None, z=0.

  • mesh – the mesh to be plotted. if None, we auto-compute a mesh using default values

  • IOR_dict – dictionary that assigns each named region in the mesh to a refractive index value

  • alpha – transparency of mesh lines

  • ax – optionally, pass in a matplotlib axis for the plotter

  • plot_points – controls if the mesh nodes will be plotted

transform(x0, y0, z0, z)#

spatial transformation that should work with most meshes. kinda slow to compute currently, maybe could be sped up. general idea: for a point (x0,y0) find the two nearest primitives at z0. this point, plus the two closest points to to it, each constrained to lie on a primitive boundary, define a triangle. At z, the primitive boundaries move, and so two of the triangle vertices move. this transformation places the third point of the triangle, which is (x,y), to preserve triangle similarity.

Parameters:
  • x0 – (scalar or vector, if self.vectorized_transform) x coord. at z0

  • y0 – (scalar or vector, if self.vectorized_transform) y coord. at z0

  • z0 – reference z coord.

  • z – new z coord.

Returns:

a tuple containing:

  • x (scalar or vector): the transformed x coordinate at z.

  • y (scalar or vector): the transformed y coordinate at z.

Return type:

(tuple)

transform_mesh(mesh0, z0, z, mesh=None)#

use the transformation law to create a new, transformed mesh from the reference mesh.

Parameters:
  • mesh0 – the reference mesh (meshio object).

  • z0 – the z coordinate corresponding to mesh0 (typically 0).

  • z – the desired z coordinate of the transformed mesh.

  • mesh – a mesh object to store the new mesh. if None, a new mesh

  • generated. (object is)

transform_unvec(x0, y0, z0, z)#

unvectorized version of transform(); this was the original version and is still here just for reference.

update(z)#

update the mesh boundaries to the given z coordinate.

Parameters:

z (float) – desired z coordinate. note that all waveguides are updated to z=0 upon initialization.

linear = False#

whether the waveguide varies linearly with z a linear waveguide will still work fine with linear=false but calc will be more efficient if set to true.

Type:

bool

max_mesh_size = 100.0#

maximum allowed mesh size (~ triangle side length)

Type:

float

mesh_dist_power = 1.0#

mesh boundary refinement power scaling factor

Type:

float

mesh_dist_scale = 0.5#

mesh boundary refinement linear distance scaling factor

Type:

float

min_mesh_size = 0.01#

minimum allowed mesh size (~ triangle side length)

Type:

float

vectorized_transform = True#

whether or not the transform() function may take vector input. True for the default transform(). however, if you add/use Prim2Ds or Prim3Ds with unvectorized functions, you may need to set this False.

Type:

bool

z_ex = None#

length of the waveguide

Type:

float

z_invariant = False#

whether or not this waveguide changes shape w/ z

Type:

bool

classes that inherit from Waveguide#

class cbeam.waveguide.CircularStepIndexFiber(rcore, rclad, ncore, nclad, core_res=16, clad_res=32)#

generic class for a straight, circular step index fiber

__init__(rcore, rclad, ncore, nclad, core_res=16, clad_res=32)#

initialize a circular step index fiber waveguide

Parameters:
  • rcore – radius of core

  • rclad – radius of cladding

  • ncore – refractive index of the core

  • nclad – refractive index of the cladding

  • core_res – how many line segments to divide the core boundary into, default 16

  • clad_res – how many line segments to divide the cladding boundary into, default 32

class cbeam.waveguide.RectangularStepIndexFiber(xw, yw, xw_clad, yw_clad, ncore, nclad, core_mesh_size=None, clad_mesh_size=None)#

generic class for a straight, rectangular step index fiber

__init__(xw, yw, xw_clad, yw_clad, ncore, nclad, core_mesh_size=None, clad_mesh_size=None)#

intialize a waveguide with a rectangular core and cladding.

Parameters:
  • xw – width of the rectangular core

  • yw – height of the rectangular core

  • xw_clad – width of the cladding

  • yw_clad – height of the cladding

  • ncore – refractive index of the core

  • nclad – refractive index of the cladding

  • core_mesh_size – target mesh size inside the core; default is min(xw,yw)/10

  • clad_mesh_size – target mesh size in the cladding; default is min(xw_clad,yw_clad)/10

class cbeam.waveguide.Dicoupler(rcore1, rcore2, ncore1, ncore2, dmax, dmin, nclad, coupling_length, a, core_res, core_mesh_size, clad_mesh_size)#

generic class for 2x2 directional couplers made of pipes

__init__(rcore1, rcore2, ncore1, ncore2, dmax, dmin, nclad, coupling_length, a, core_res, core_mesh_size, clad_mesh_size)#

initialize a directional coupler waveguide.

Parameters:
  • rcore1 – the core radius of the left single mode channel

  • rcore2 – the core radius of the right single mode channel

  • ncore1 – the index of the left channel

  • ncore2 – the index of the right channel

  • dmax – the starting core separation

  • dmin – the minimum core separation

  • nclad – the cladding index

  • coupling_length – the approximate length in z over which the core separation is dmin

  • a – the approximate bend length

  • core_res – the # of segments used to resolve the core-cladding interface

  • core_mesh_size – the target mesh size inside cores

  • clad_mesh_size – the target mesh size inside the cladding

plot_paths()#

plot the single-mode channel paths

class cbeam.waveguide.Tricoupler(rcore, ncore, dmax, dmin, nclad, coupling_length, a, core_res, core_mesh_size, clad_mesh_size)#

generic class for symmetric equilateral tricouplers made of pipes

__init__(rcore, ncore, dmax, dmin, nclad, coupling_length, a, core_res, core_mesh_size, clad_mesh_size)#

initialize a tricoupler waveguide.

Parameters:
  • rcore – the core radius, shared for all single mode channels

  • ncore – the refractive index for all single mode channels

  • dmax – the diameter of the circle containing the center of each channel, at max separation

  • dmin – the diameter of the circle containing the center of each channel, at min separation

  • nclad – the cladding index

  • coupling_length – the approximate length in z over which the core separation is dmin

  • a – the approximate bend length

  • core_res – the # of segments used to resolve the core-cladding interface

  • core_mesh_size – the target mesh size inside cores

  • clad_mesh_size – the target mesh size inside the cladding

plot_paths()#

plot the single-mode channel paths

class cbeam.waveguide.PhotonicLantern(core_pos, rcores, rclad, rjack, ncores, nclad, njack, z_ex, taper_factor, core_res=30, clad_res=60, jack_res=30, core_mesh_size=None, clad_mesh_size=None)#

generic class for photonic lanterns

__init__(core_pos, rcores, rclad, rjack, ncores, nclad, njack, z_ex, taper_factor, core_res=30, clad_res=60, jack_res=30, core_mesh_size=None, clad_mesh_size=None)#

initialize a photonic lantern waveguide.

Parameters:
  • core_pos – an Nx2 array of (x,y) core positions at z=0

  • rcores – an array of core radii at z=0

  • rclad – the cladding radius at z=0

  • rjack – the jacket radius at z=0 (this sets the outer simulation boundary)

  • ncores – an array of refractive indices for the cores

  • nclad – the cladding refractive index

  • njack – the jacket refractive index

  • z_ex – the lantern length

  • taper_factor – the amount the lantern scales by, going from z=0 -> z=z_ex

  • core_res – number of line segments to resolve each core-cladding boundary with

  • clad_res – number of line segments to resolve the cladding-jacket boundary

  • jack_res – number of line segments to resolve the outer jacket boundary

  • core_mesh_size – target side length for triangles inside a core. defaults to the size set by core_res

  • clad_mesh_size – target side length for triangles inside the cladding. defaults to the size set by clad_res

class cbeam.waveguide.TestPhotonicLantern#

shorthand for doctesting

Prim3D class#

class cbeam.waveguide.Prim3D(prim2D: Prim2D, label: str)#

a Prim3D (3D primitive) is a function of z that returns a Prim2D. it can be used to represent tapering pipes, boxes, etc.

__init__(prim2D: Prim2D, label: str)#

initialize a Prim3D object. this default behavior is often overwritten by inheriting classes.

Parameters:
  • prim2D (Prim2D) – a prim2D object (e.g. Circle, Rectangle).

  • label (str) – a string label to attach to the 2D primitive.

make_points_at_z(z)#

make points of prim2D at given z coord. should be implemented by inheriting classes.

Parameters:

z (float) – the desired z coordinate

Returns:

an Nx2 array of points corresponding to the boundary at z.

Return type:

(array)

transform_point_inside(x0, y0, z0, z)#

for a point (x0,y0) inside the boundary at z0, compute a new point (x,y) at z, accounting for the z-variation of the Prim3D. should be implemented by inheriting classes, and should be vectorized if possible.

Parameters:
  • x0 (float or vector) – reference x coordinate(s) inside the boundary at z0

  • y0 (float or vector) – reference y coordinate(s) inside the boundary at z0

  • z0 (float) – reference z coordiante

  • z (float) – new z coordinate

Returns:

a tuple containing:
  • x1 (float or vector): the new x coordinate(s) at z

  • y1 (float or vector): the new y coordinate(s) at z

Return type:

(tuple)

update(z)#

update self.prim2D to the desired z coordinate.

preserve_shape = True#

whether or not the boundary may be deformed when advancing in z.

Type:

bool

classes that inherit from Prim3D#

class cbeam.waveguide.Pipe(n, label, res, rfunc, cfunc=(0, 0))#

a Pipe is a 3D primitive with circular cross section at all z.

__init__(n, label, res, rfunc, cfunc=(0, 0))#
Parameters:
  • n – the refractive index inside the pipe

  • label – a string name to attach to this pipe

  • res – the number of line segments used to resolve the circle

  • rfunc – function that returns a circular radius for a given z, or scalar for constant behavior

  • cfunc – a function that returns a center position (xc,yc) for a given z, or tuple for constant behavior

class cbeam.waveguide.BoxPipe(n, label, xwfunc, ywfunc, cfunc=(0, 0))#

an box whose width, height, and center can scale with z.

__init__(n, label, xwfunc, ywfunc, cfunc=(0, 0))#
Parameters:
  • n – refractive index

  • label – string identifier for this waveguide part

  • xwfunc – a function controlling the width of the box wrt z, or scalar for constant x width

  • ywfunc – a function controlling the height of the box wrt z, or scalar for constant y width

  • cfunc – a function controlling the center of the box, or a tuple for constant center location (x0,y0)

Prim2D class#

class cbeam.waveguide.Prim2D(n, points=[])#

a Prim2D (2D primitive) is an an array of N (x,y) points, shape (N,2), that denote a closed curve (so, a polygon). inside the closed curve, the primitive has refractive index n.

__init__(n, points=[])#
boundary_dist(x, y)#

this function computes the distance between the point (x,y) and the boundary of the primitive. negative distances -> inside the boundary, while positive -> outside. note that this doesn’t need to be exact, the “distance” just needs to be positive outside the boundary, negative inside the boundary, and go to 0 as you approach the boundary. it is better if it works on vectorized inputs for x,y.

Parameters:
  • x (float or vector) – x coordinate(s) of point(s) to measure distance w/ boundary.

  • y (float or vector) – y coordinate(s) of point(s) to measure distance w/ boundary.

Returns:

the distance(s) to the boundary from the point(s)

Return type:

(float or vector)

make_points()#

make an Nx2 array of points for marking the primitive boundary, according to some args.

nearest_boundary_point(x, y)#

this function computes the point on the boundary that is closest to a point (x,y). it is better if it works on vectorized inputs for x,y.

Parameters:
  • x (float or vector) – x coordinate(s) of point(s) to measure distance w/ boundary.

  • y (float or vector) – y coordinate(s) of point(s) to measure distance w/ boundary.

Returns:

a tuple containing:
  • (float or vector): the x coordinate(s) of the nearest boundary point

  • (float or vector): the y coordinate(s) of the nearest boundary point

Return type:

(tuple)

plot_mesh()#

a quick check to see what this object looks like. generates a mesh with default parameters.

update(points)#

update the primitive according to some args and return an Nx2 array of points. the default behavior is to manually pass in a points array. more specific primitives inheriting from Prim2D should implement their own update().

classes that inherit from Prim2D#

class cbeam.waveguide.Circle(n, points=[])#

a Circle primitive, defined by radius, center, and number of sides (so actually a regular polygon lol). initialize using only the desired refractive index n, then use make_points() to generate the point array.

make_points(radius, res, center=(0, 0))#

make an Nx2 array of points for marking the primitive boundary, according to some args.

class cbeam.waveguide.Rectangle(n, points=[])#

rectangle primitive, defined by corner points. initialize using only the desired refractive index n, then use make_points() to generate the point array.

make_points(xmin, xmax, ymin, ymax)#

make an Nx2 array of points for marking the primitive boundary, according to some args.

class cbeam.waveguide.Prim2DUnion(p1: Prim2D, p2: Prim2D)#
__init__(p1: Prim2D, p2: Prim2D)#

initialize a boolean union of two primitives, p1 and p2. not fully tested.

make_points(args1, args2)#

make points corresponding to the boundary of the primitive.

Parameters:
  • args1 (tuple) – the arguments of make_points for the first primitive

  • args2 (tuple) – the arguments of make_points for the second primitive