Skip to content

Commit

Permalink
Merge pull request #953 from bhnzhang/fix_gc_ellipse_arb_neff
Browse files Browse the repository at this point in the history
Fix neff issue with component grating_coupler_elliptical_arbitrary
  • Loading branch information
joamatab committed Dec 2, 2022
2 parents 62a11e3 + 2df26cf commit 87b8fea
Showing 1 changed file with 49 additions and 28 deletions.
77 changes: 49 additions & 28 deletions gdsfactory/components/grating_coupler_elliptical_arbitrary.py
Expand Up @@ -23,7 +23,6 @@ def grating_coupler_elliptical_arbitrary(
taper_angle: float = 60.0,
wavelength: float = 1.554,
fiber_angle: float = 15.0,
neff: float = 2.638, # tooth effective index
nclad: float = 1.443,
layer_slab: LayerSpec = "SLAB150",
slab_xmin: float = -3.0,
Expand All @@ -47,7 +46,6 @@ def grating_coupler_elliptical_arbitrary(
taper_angle: grating flare angle.
wavelength: grating transmission central wavelength (um).
fiber_angle: fibre angle in degrees determines ellipticity.
neff: tooth effective index to compute ellipticity.
nclad: cladding effective index to compute ellipticity.
layer_slab: Optional slab.
slab_xmin: where 0 is at the start of the taper.
Expand Down Expand Up @@ -80,48 +78,46 @@ def grating_coupler_elliptical_arbitrary(
xs = gf.get_cross_section(cross_section, **kwargs)
wg_width = xs.width
layer = xs.layer

# Compute some ellipse parameters
sthc = np.sin(fiber_angle * DEG2RAD)
d = neff**2 - nclad**2 * sthc**2
a1 = wavelength * neff / d
b1 = wavelength / np.sqrt(d)
x1 = wavelength * nclad * sthc / d

a1 = round(a1, 3)
b1 = round(b1, 3)
x1 = round(x1, 3)
period = a1 + x1

# generate component
c = gf.Component()
c.info["polarization"] = polarization
c.info["wavelength"] = wavelength

gaps = gf.snap.snap_to_grid(np.array(gaps) + bias_gap)
widths = gf.snap.snap_to_grid(np.array(widths) - bias_gap)

xi = taper_length
for gap, width in zip(gaps, widths):
xi += gap + width / 2
p = xi / period
# get the physical parameters needed to compute ellipses
gaps = gf.snap.snap_to_grid(np.array(gaps) + bias_gap)
widths = gf.snap.snap_to_grid(np.array(widths) - bias_gap)
periods = [ g + w for g, w in zip(gaps,widths) ]
neffs = [ wavelength/p + nclad*sthc for p in periods ]
ds = [ neff**2 - nclad**2 * sthc**2 for neff in neffs ]
a1s = [ round(wavelength * neff / d, 3) for neff, d in zip(neffs,ds) ]
b1s = [ round(wavelength / np.sqrt(d), 3) for d in ds ]
x1s = [ round(wavelength * nclad * sthc / d, 3) for d in ds ]
xis = np.add( taper_length + np.cumsum(periods), -widths/2 ) # position of middle of each tooth
ps = np.divide( xis, periods )

# Make the grating teeth
# xi = taper_length # x intercept of current tooth
for a1, b1, x1, p, width in zip(a1s, b1s, x1s, ps, widths):
pts = grating_tooth_points(
p * a1, p * b1, p * x1, width, taper_angle, spiked=spiked
)
c.add_polygon(pts, layer)
xi += width / 2
# end grating teeth making for loop

# Make the taper
p = taper_length / period
a_taper = p * a1
b_taper = p * b1
x_taper = p * x1
p = taper_length / periods[0] # (gaps[0]+widths[0])
a_taper = p * a1s[0]
b_taper = p * b1s[0]
x_taper = p * x1s[0]

x_output = a_taper + x_taper - taper_length + widths[0] / 2
pts = grating_taper_points(
a_taper, b_taper, x_output, x_taper, taper_angle, wg_width=wg_width
)
c.add_polygon(pts, layer)
x = (taper_length + xi) / 2
x = (taper_length + xis[-1]) / 2
name = f"vertical_{polarization.lower()}"
c.add_port(
name=name,
Expand Down Expand Up @@ -167,6 +163,7 @@ def grating_coupler_elliptical_arbitrary(
c = xs.add_bbox(c)
if xs.add_pins:
c = xs.add_pins(c)

return c


Expand Down Expand Up @@ -225,7 +222,31 @@ def grating_coupler_elliptical_uniform(

if __name__ == "__main__":
# c = grating_coupler_elliptical_arbitrary()
c = grating_coupler_elliptical_uniform(n_periods=3, fill_factor=0.1)
# c = grating_coupler_elliptical_uniform(n_periods=3, fill_factor=0.1)
# c = grating_coupler_elliptical_arbitrary(fiber_angle=8, bias_gap=-0.05)
# c = gf.routing.add_fiber_array(grating_coupler=grating_coupler_elliptical_arbitrary)
c.show(show_ports=True)

# bz - testing gc with neff/period fix

# # testing default uniform designs
# c = grating_coupler_elliptical_arbitrary(layer_slab = None)
# c.write_gds(gdspath='gc_ellip_fix_unif.gds')
# # also make and draw the older version with incorrect neff
# c2 = grating_coupler_elliptical_arbitrary_old(layer_slab = None, neff = 2.0)
# c2.write_gds(gdspath='gc_ellip_old_unif.gds')

# # testing apodized design
# periods = np.linspace(0.650, 0.800, num=10)
# dcycles = np.linspace(0.9, 0.5, num=10)
# gaps = tuple( np.multiply( periods, 1-dcycles ) )
# widths = tuple( np.multiply( periods, dcycles ) )

# # print(widths)

# c = grating_coupler_elliptical_arbitrary(gaps = gaps, widths = widths, layer_slab = None)
# # c.show(show_ports=True)
# c.write_gds(gdspath='gc_ellip_fix_apod.gds')

# # also make and draw the older version
# c2 = grating_coupler_elliptical_arbitrary_old(gaps = gaps, widths = widths, layer_slab = None, neff = 2.0)
# c2.write_gds(gdspath='gc_ellip_old_apod.gds')

0 comments on commit 87b8fea

Please sign in to comment.