Parametric curve

Parametric curve

How to create parametric curves between two points

Paramteric curve: pcurve_p2p()

Waveguides can be defined along a parametric curve where the position (x, y) of the spine of the curve is a function of parameter t: x(t), y(t).
The local width w(t) of the curve w is measured perpendicular to the spine, with the spine in the center.

The pcurve in Nazca is a specific implementation of a smooth curve of constant width. See the following example for the point to point (p2p) pcurve:

import nazca as nd
import nazca.demofab as demo

p1 = (0, 10, 145)
p2 = (300, 300, -85)
demo.shallow.pcurve_p2p(pin1=p1, pin2=p2).put()

nd.export_gds(filename='pcurve1.gds'))

Note that the pcurve smoothly changes the radius, however, this by itself is not a condition for adiabaticity. The layout designer has to make sure that the change is gentle enough for the waveguide under consideration.

The pcurve checks for a minimum radius, which is set in the xsection attribute ‘minimum_radius’. Nazca issues a warning if the radius drops under the minimum as demonstrated in the next example:

import nazca as nd
import nazca.demofab as demo

for i in range (5):
    s1 = demo.deep.strt(length=10).put(0, i*60)
    s2 = demo.deep.strt(length=10).put(200, i*100)
    demo.deep.pcurve_p2p(pin1=s1.pin['b0'], pin2=s2.pin['a0']).put()
    demo.shallow.pcurve_p2p(pin1=s2.pin['a0'], pin2=s1.pin['b0']).put()

nd.export_gds(filename='pcurve2.gds')

The above example prints “minimum radius” warnings. The minimum radius is a property of the xsection used. It can be changed as indicated in the following example. When running the example the warnings adapt to the new setting(s).

import nazca as nd
import nazca.demofab as demo

xs_shallow = nd.get_xsection('Shallow')
xs_shallow.minimum_radius = 50

for i in range (5):
    s1 = demo.deep.strt(length=10).put(0, i*60)
    s2 = demo.deep.strt(length=10).put(200, i*100)
    demo.deep.pcurve_p2p(pin1=s1.pin['b0'], pin2=s2.pin['a0']).put()
    demo.shallow.pcurve_p2p(pin1=s2.pin['a0'], pin2=s1.pin['b0']).put()

nd.export_gds(filename='pcurve2b.gds')

pcurve takes into account the curvature at the start and end of the curve via parameters radius1 and radius2. By default pcurve assumes no curvature, i.e. infinite radius (a straight guide), which is expressed in pcurve by radius = 0.

The next example shows how to connect pcurve with a continuous curvature to other guides.

import nazca as nd
import nazca.demofab as demo

s1 = demo.deep.strt(length=100).put(0)
s2 = demo.deep.strt(length=100).put(200, 200)
demo.deep.pcurve_p2p(pin1=s1.pin['a0'], pin2=s2.pin['a0']).put()

R1 = demo.shallow.radius
R2 = 100
b1 = demo.shallow.bend(angle=-45).put(0)
b2 = demo.shallow.bend(angle=45, radius=R2).put(200, 200)
demo.shallow.pcurve_p2p(pin1=b1.pin['a0'], pin2=b2.pin['a0'],
    radius1=R1, radius2=R2).put()

nd.export_gds(filename='pcurve3a.gds')

The straight-to-bend offset is automatically applied to the pcurve ends.

This is more explicitly visible in connections between the pcurve and waveguides of different curvature at the connections:

import nazca as nd
import nazca.demofab as demo

b1 = demo.shallow.strt(length=100).put(0, 0)
b2 = demo.shallow.bend(angle=45, radius=50).put(200, 300)
demo.shallow.pcurve_p2p(pin1=b1.pin['a0'], pin2=b2.pin['a0'],
    radius1=150, radius2=200).put()

nd.export_gds(filename='pcurve3b.gds')

It is possible to overrule the offset values by the offset1 and offset2 parameters for the start and end offset, respectively.

In order to use pcurves in your custom interconnects see the next example.
For completeness the example also includes the creation of a new xsection from scratch.

import nazca as nd
from nazca.interconnects import Interconnect

# create layers:
nd.add_layer(name='layerA', layer=(3000, 0), accuracy=0.001)
nd.add_layer(name='layerB', layer=(4000, 0), accuracy=0.010)

# create a xsection and set some of its properties:
def os(radius, width):
    if radius == 0:
        return 0
    return (100/radius)

XS = nd.add_xsection(name='newXS')
XS.minimum_radius = 50.0
XS.radius = 100.0
XS.width = 4.0
XS.os = os # straight-to-bend offset

# add layers to the xsection:
nd.add_layer2xsection(xsection='newXS', layer='layerA')
nd.add_layer2xsection(xsection='newXS', layer='layerB', growx=5.0)

# create an interconnect object. It will get its properties from 'newXS':
ic = Interconnect(radius=100, xs='newXS')

# create a pcurve with the interconnect:
b1 = ic.bend(angle=90).put(0)
ic.pcurve_p2p(pin1=b1.pin['b0'], pin2=(400, 300, -85)).put()

# create a pcurve with the interconnect, adapt the curvature:
b1 = ic.bend(angle=90).put(100, -50)
ic.pcurve_p2p(pin1=b1.pin['b0'], pin2=(500, 250, -85), radius1=XS.radius).put()

nd.export_gds(filename='pcurve4.gds')

Use demofab_klayout_colors.lyp when viewing the gds in KLayout.

Related Tutorials

Nazca LayoutNazca Foundry
16 November 2018

Add text to your layout

In this example we show how to add text to your layout.
Nazca LayoutNazca FoundryPhotonic BBs
19 January 2018

Create a building block using Polygons

In this example we show how to create a building block from Polygons.
Nazca LayoutNazca FoundryPhotonic BBs
19 January 2018

Create a photonic crystal using a GDS array

In this example we show how to create a photonic crystal using GDS array.