Files
mxpic_forge/mxpic/components/primitives/grating_couplers.py
T

193 lines
7.6 KiB
Python

import nazca as nd
import numpy as np
import math
import pandas as pd
from ...routing import Route
from ..geometry import _my_polygon,circle,Clothoid,hole
from ...basic import __cell_arg__
class GC_SiN_Si_Dual_Layer:
"""
GC SiN Si Dual Layer primitive component.
This component builds the GC SiN Si Dual Layer layout cell.
Parameters
----------
name : str, optional
Unique identifier for the device cell. Default is None.
w_teeth_SiN : list or float, optional
Width parameter in microns. Default is 0.5.
gap_teeth_SiN : list or float, optional
Spacing or gap parameter in microns. Default is 0.5.
w_teeth_Si : list or float, optional
Width parameter in microns. Default is 0.5.
gap_teeth_Si : list or float, optional
Spacing or gap parameter in microns. Default is 0.5.
ori_teeth_offset : float, optional
Value for the ori_teeth_offset parameter. Default is 5.0.
n_teeth_Si : float, optional
Value for the n_teeth_Si parameter. Default is 30.
n_teeth_SiN : float, optional
Value for the n_teeth_SiN parameter. Default is 30.
A_gc_taper : float, optional
Angle parameter in degrees. Default is 25.0.
R_teeth_ori_SiN : float, optional
Radius parameter in microns. Default is 40.0.
R_teeth_ori_Si : float, optional
Radius parameter in microns. Default is 40.0.
L_end_Si : float, optional
Length parameter in microns. Default is 0.2.
L_end_SiN : float, optional
Length parameter in microns. Default is 5.0.
w_port : float, optional
Width parameter in microns. Default is 0.9.
A_anti_rfl : float, optional
Angle parameter in degrees. Default is 4.0.
layer_SiN_slab : str, optional
Layer or cross-section name used by the device. Default is None.
layer_Si_slab : str, optional
Layer or cross-section name used by the device. Default is None.
layer_Si_teeth : str, optional
Layer or cross-section name used by the device. Default is None.
layer_SiN_teeth : str, optional
Layer or cross-section name used by the device. Default is None.
layer_SiN_etch : str, optional
Layer or cross-section name used by the device. Default is None.
layer_Si_etch : str, optional
Layer or cross-section name used by the device. Default is None.
layer_ox_open : str, optional
Layer or cross-section name used by the device. Default is None.
"""
def __init__(self,
name:str=None,
w_teeth_SiN:'list|float' = 0.5,
gap_teeth_SiN:'list|float' = 0.5,
w_teeth_Si:'list|float' = 0.5,
gap_teeth_Si:'list|float' = 0.5,
ori_teeth_offset:float = 5.0,
n_teeth_Si:float=30,
n_teeth_SiN:float=30,
A_gc_taper:float=25.0,
R_teeth_ori_SiN:float=40.0,
R_teeth_ori_Si:float=40.0,
L_end_Si:float=0.2,
L_end_SiN:float=5.0,
w_port : float = 0.9,
A_anti_rfl:float = 4.0,
layer_SiN_slab:str=None,
layer_Si_slab:str=None,
layer_Si_teeth:str=None,
layer_SiN_teeth:str=None,
layer_SiN_etch:str=None,
layer_Si_etch:str=None,
layer_ox_open:str=None,
):
self.name = name
self.w_teeth_SiN = w_teeth_SiN
self.gap_teeth_SiN = gap_teeth_SiN
self.w_teeth_Si = w_teeth_Si
self.gap_teeth_Si = gap_teeth_Si
self.ori_teeth_offset = ori_teeth_offset
self.n_teeth_SiN = n_teeth_SiN
self.n_teeth_Si = n_teeth_Si
self.A_gc_taper = A_gc_taper
self.w_port = w_port
self.L_end_Si = L_end_Si
self.L_end_SiN = L_end_SiN
self.A_anti_rfl = A_anti_rfl
self.R_teeth_ori_SiN = R_teeth_ori_SiN
self.R_teeth_ori_Si = R_teeth_ori_Si
self.layer_SiN_slab = layer_SiN_slab
self.layer_Si_slab = layer_Si_slab
self.layer_Si_teeth = layer_Si_teeth
self.layer_SiN_teeth = layer_SiN_teeth
self.layer_SiN_etch = layer_SiN_etch
self.layer_Si_etch = layer_Si_etch
self.layer_ox_open = layer_ox_open
self.cell = self.generate_gds()
def generate_gds(self):
""" creating instance cell or not """
if (self.name is None) : self.instantiate = False
else : self.instantiate = True
""" """
if (isinstance(self.w_teeth_SiN,list) or isinstance(self.w_teeth_SiN,np.ndarray)):
n_teeth_SiN = len(self.w_teeth_SiN)
elif (isinstance(self.w_teeth_SiN,float)):
n_teeth_SiN = self.n_teeth_SiN
w_teeth_SiN = [w_teeth_SiN]*n_teeth_SiN
""" """
if (isinstance(self.w_teeth_Si,list) or isinstance(self.w_teeth_Si,np.ndarray)):
n_teeth_Si = len(self.w_teeth_Si)
elif (isinstance(self.w_teeth_Si,float)):
n_teeth_Si = self.n_teeth_Si
w_teeth_Si = [w_teeth_Si]*n_teeth_Si
with nd.Cell(instantiate=self.instantiate, name=self.name) as C:
""" Creating SiN layer grating """
## whole area where the grating area covered
L_gc = self.R_teeth_ori_SiN + self.L_end_SiN + sum(self.w_teeth_SiN) + sum(self.gap_teeth_SiN)
w_box_gc = L_gc*np.sin(self.A_gc_taper/2*np.pi/180)*2
L_box_gc = L_gc*np.cos(self.A_gc_taper/2*np.pi/180)
x_slab = [0,L_box_gc,L_gc+w_box_gc*np.sin(self.A_anti_rfl*np.pi/180),L_gc,L_box_gc,0]
y_slab = [self.w_port/2,w_box_gc/2,w_box_gc/2,-w_box_gc/2,-w_box_gc/2,-self.w_port/2]
_my_polygon(layer_wg=self.layer_SiN_slab,vtx=np.c_[x_slab,y_slab]).put(0,0,0)
# circle(radius=self.R_teeth_ori_SiN/2,angle=self.A_gc_taper,layer=self.layer_SiN_slab,
# width=self.R_teeth_ori_SiN).cell.put(0,0,-self.A_gc_taper/2)
A_etch_ext = 4
## Placing teeth
r_in = self.R_teeth_ori_SiN
for idxT in range(0,n_teeth_SiN):
r_out = r_in + self.gap_teeth_SiN[idxT]
circle(radius=(r_out+r_in)/2,angle=self.A_gc_taper+A_etch_ext,layer=self.layer_SiN_etch,
width=self.gap_teeth_Si[idxT]).cell.put(0,0,-self.A_gc_taper/2-A_etch_ext/2)
r_in = r_out + self.w_teeth_SiN[idxT]
""" Creating Si layer grating """
w_Si_slab = sum(self.w_teeth_Si)+sum(self.gap_teeth_Si)
R_Si_slab = self.R_teeth_ori_Si+w_Si_slab/2
circle(radius=R_Si_slab,angle=self.A_gc_taper,layer=self.layer_Si_slab,
width=w_Si_slab).cell.put(0,0,-self.A_gc_taper/2)
## Placing teeth
r_in = self.R_teeth_ori_Si
for idxT in range(0,n_teeth_Si):
r_out = r_in + self.gap_teeth_Si[idxT]
if (self.layer_Si_etch is not None):
circle(radius=(r_out+r_in)/2,angle=self.A_gc_taper+A_etch_ext,layer=self.layer_Si_etch,
width=self.gap_teeth_Si[idxT]).cell.put(0,0,-self.A_gc_taper/2-A_etch_ext/2)
elif (self.layer_Si_teeth is not None):
circle(radius=r_out+(self.w_teeth_Si[idxT])/2,angle=self.A_gc_taper,layer=self.layer_Si_teeth,
width=self.w_teeth_Si[idxT]).cell.put(0,0,-self.A_gc_taper/2)
r_in = r_out + self.w_teeth_Si[idxT]
return C