Ejemplo n.º 1
0
def ratrace(
        metal,
        substrate,
        z,  # [bottom of substrate, top of substrate, top of metal]
        port_length,
        ms_width,
        priority=9,
        lq=8.9 * mm,
        w=0.175 * mm,
        r1=0.7 * mm,
        r2=0.7 * mm,
        kicad=False,
        loopr=1.0 * mm):
    em = metal.em
    ms_width = ms_width
    endspace = 0.5 * mm

    feedx = -lq + -r2 + pi * r2 / 2.0
    arcx = feedx - lq + (r1 + r2) * pi / 2
    endspace = ms_width + port_length if kicad else endspace

    def addy_sym(y):
        em.mesh.AddLine('y', y)
        em.mesh.AddLine('y', -y)

    addy_sym(r1 - 0.5 * w)
    addy_sym(r1 + 0.5 * w)
    addy_sym(r1 + r2 - 0.5 * w)
    addy_sym(r1 + r2 + 0.5 * w)

    # substrate
    start = np.array([endspace, r1 + r2 + endspace, z[0]])
    stop = np.array([arcx - r1 - r2 - endspace, -1.0 * start[1], z[1]])
    substrate.AddBox(start, stop, 1)

    # outer loop
    c1 = arcx
    lo = cat((
        arc(-1.0 * r2, r1, r2 + 0.5 * w, 0 * pi, 0.5 * pi),
        arc(c1, 0, r1 + r2 + 0.5 * w, 0.5 * pi, 1.5 * pi),
        arc(-1.0 * r2, -r1, r2 + 0.5 * w, 1.5 * pi, 2 * pi),
    ))
    li = cat((
        arc(-1.0 * r2, r1, r2 - 0.5 * w, 0 * pi, 0.5 * pi),
        arc(c1, 0, r1 + r2 - 0.5 * w, 0.5 * pi, 1.5 * pi),
        arc(-1.0 * r2, -r1, r2 - 0.5 * w, 1.5 * pi, 2 * pi),
    ))
    l = cat((lo, li[::-1]))
    metal.AddPolygon(priority=priority,
                     points=l,
                     elevation=z[1:],
                     normal_direction='z',
                     pcb_layer='F.Cu',
                     pcb_width=0.001)

    # inner loop
    lo = arc(np.pi * r1 / 2.0 - lq, 0, r1 + 0.5 * w, 0.5 * pi, 1.5 * pi)
    li = arc(np.pi * r1 / 2.0 - lq, 0, r1 - 0.5 * w, 0.5 * pi, 1.5 * pi)
    lo = cat((lo, [[0.5 * w, -(r1 + 0.5 * w)], [0.5 * w, -(r1 - 0.5 * w)]]))
    li = cat(([[0.5 * w, r1 + 0.5 * w], [0.5 * w, r1 - 0.5 * w]], li))
    l = cat((lo, li[::-1]))
    metal.AddPolygon(priority=priority,
                     points=l,
                     elevation=z[1:],
                     normal_direction='z',
                     pcb_layer='F.Cu',
                     pcb_width=0.001)

    # delta port
    start = [feedx + 0.5 * ms_width, -1.0 * (r1 + r2) - endspace, z[1]]
    stop = [start[0] - ms_width, start[1] + port_length, z[2]]
    em.AddPort(start, stop, direction='y', z=50)

    # delta line
    start[1] = -1.0 * (r1 + r2)
    metal.AddBox(start, stop, priority, padname='1')

    # 0/180 ports
    start = [endspace, r1 - 0.5 * ms_width, z[1]]
    stop = [endspace - port_length, r1 + 0.5 * ms_width, z[2]]
    em.AddPort(start, stop, direction='x', z=50).duplicate().mirror('y')

    # 0/180 lines
    start[0] = 0
    metal.AddBox(start, stop, priority, padname='3')
    metal.AddBox(start, stop, priority, padname='4').mirror('y')

    # sum port
    portx1 = feedx - 0.5 * mm
    portx2 = portx1 - port_length
    start = [portx1, -0.5 * ms_width, z[1]]
    stop = [portx2, 0.5 * ms_width, z[2]]
    em.AddPort(start, stop, direction='x', z=50)

    # sum line
    start[0] = feedx
    stop[0] = portx1
    metal.AddBox(start, stop, priority, padname='2')

    # sum ground
    start[0] = portx2
    stop[0] = portx2 - 0.5 * mm
    start[2] = 0
    if not kicad:
        metal.AddBox(start, stop, priority)

    # ground loops
    if kicad:
        r = loopr
        y1 = r1 + r
        x = -lq + pi * r
        w = ms_width
        l = cat((
            arc(0, y1, r + 0.5 * w, -0.5 * pi, 0.5 * pi),
            [[x, y1 + r + 0.5 * w], [x, y1 + r - 0.5 * w]],
            arc(0, y1, r - 0.5 * w, 0.5 * pi, -0.5 * pi),
        ))
        metal.AddPolygon(priority=priority,
                         points=l,
                         elevation=z[1:],
                         normal_direction='z',
                         pcb_layer='F.Cu',
                         pcb_width=0.001).duplicate().mirror('y')
        openems.Via(metal,
                    priority=2,
                    x=x,
                    y=y1 + r,
                    z=[[0, z[2]], [z[1], z[2]]],
                    drillradius=0.1 * mm,
                    padradius=0.225 * mm,
                    padname='5').duplicate().mirror('y')
Ejemplo n.º 2
0
def generate(
        em,  # openems instance
        metal_name='pec',  # metal instance, define with openems.Metal()
        z=[],  # z position vector, z[0] = substrate bottom, z[1] = substrate top, z[2] = foil top
        space=None,  # space between stub and coplanar ground
        width=0.25,  # width of stub
        length=5.0,  # length of stub
        priority=9,  # openems priority of all filter metal
        portlength=0.2 * mm,  # length of the openems port
        feedwidth=0.85 * mm,  # width of the trace leaving the filter and port
        feedgap=0.2 * mm,  # space from trace leaving the filter to via ring
        via_radius=0.15 * mm,  # radius of the via drills
        via_padradius=0.3 * mm,  # radius of the via pads
        mask_thickness=0,  # set to non-zero to enable solder mask over filter
        inner_metal=False,  # set to True to enable inner metal layers in via ring
        inner_metal_z=[[]]):
    ymin = -1.0 * (0.5 * feedwidth + feedgap + 2.0 * via_padradius)
    ymax = length + 2.0 * via_padradius
    xmax = 0.5 * width + space + 2.0 * via_padradius
    # stub line
    x1 = xmax - portlength
    x2 = 0.5 * width
    ppoints = np.array([[x1, -0.5 * feedwidth], [x1, 0.5 * feedwidth],
                        [x2, 0.5 * feedwidth], [x2, ymax], [-1.0 * x2, ymax],
                        [-1.0 * x2, 0.5 * feedwidth],
                        [-1.0 * x1, 0.5 * feedwidth],
                        [-1.0 * x1, -0.5 * feedwidth]])
    openems.Polygon(em,
                    name='stub',
                    material=metal_name,
                    priority=priority,
                    points=ppoints,
                    elevation=z[1:],
                    normal_direction='z',
                    pcb_layer='F.Cu',
                    pcb_width=0.001 * mm)
    # feed lines
    start = [x1, 0.5 * feedwidth, z[1]]
    stop = [x1 - feedwidth, -0.5 * feedwidth, z[2]]
    box2 = openems.Box(em,
                       'pe1',
                       metal_name,
                       priority,
                       start,
                       stop,
                       padname='1').duplicate('pe2').mirror('x')
    box2.padname = '2'
    # ports
    start = [x1, 0.5 * feedwidth, z[1]]
    stop = [x1 + portlength, -0.5 * feedwidth, z[2]]
    openems.Port(em, start, stop, direction='x', z=50).duplicate().mirror('x')
    # metal ring (sides)
    start = [xmax - 2.0 * via_padradius, 0.5 * feedwidth + feedgap, z[1]]
    stop = [xmax, ymax, z[2]]
    openems.Box(em, 'ring1', metal_name, priority, start, stop,
                padname='3').duplicate('ring2').mirror('x')
    # metal ring (bottom)
    start = [xmax, length, z[1]]
    stop = [-1.0 * xmax, ymax, z[2]]
    openems.Box(em, 'ring3', metal_name, priority, start, stop, padname='3')
    # metal ring (top)
    start = [xmax, -0.5 * feedwidth - feedgap, z[1]]
    stop = [-1.0 * xmax, ymin, z[2]]
    box = openems.Box(em,
                      'ring4',
                      metal_name,
                      priority,
                      start,
                      stop,
                      padname='3')
    # substrate
    start = np.array([-1.0 * xmax, ymin, z[0]])
    stop = np.array([xmax, ymax, z[1]])
    openems.Box(em, 'sub1', 'sub', 1, start, stop)
    # mask
    if mask_thickness > 0.0:
        start[2] = z[1]
        stop[2] = z[1] + mask_thickness
        openems.Box(em, 'mask', 'mask', 1, start, stop)
    # vias (along y)
    via_z = [[z[0], z[2]]]  #, [z[1], z[2]]]
    y_start = ymax - via_padradius
    y_stop = 0.5 * feedwidth + feedgap + via_padradius
    x = xmax - via_padradius
    n_via = 0
    n_vias = 1 + np.floor(np.abs(y_start - y_stop) / (2.0 * via_padradius))
    print "n vias Y = ", n_vias
    for y in np.linspace(y_start, y_stop, n_vias):
        v = openems.Via(em,
                        'via{}'.format(n_via),
                        'pec',
                        2,
                        x=x,
                        y=y,
                        z=via_z,
                        drillradius=via_radius,
                        padradius=via_padradius,
                        padname='3')
        v.duplicate('via{}'.format(n_via + 1)).mirror('x')
        n_via += 2
    # vias (along )x
    y = y_start
    x_start = x
    x_stop = -1.0 * x_start
    n_vias = 1 + np.floor(np.abs(x_start - x_stop) / (2.0 * via_padradius))
    print "n vias X = ", n_vias
    for x in np.linspace(x_start, x_stop, n_vias)[1:-1]:
        v = openems.Via(em,
                        'via{}'.format(n_via),
                        'pec',
                        2,
                        x=x,
                        y=y,
                        z=via_z,
                        drillradius=via_radius,
                        padradius=via_padradius,
                        padname='3')
        n_via += 1
    y = ymin + via_padradius
    for x in np.linspace(x_start, x_stop, n_vias):
        v = openems.Via(em,
                        'via{}'.format(n_via),
                        'pec',
                        2,
                        x=x,
                        y=y,
                        z=via_z,
                        drillradius=via_radius,
                        padradius=via_padradius,
                        padname='3')
        n_via += 1
Ejemplo n.º 3
0
# port (ms)
start = [-0.5 * box_length, ms_width / 2.0, sub1t]
stop = [-0.5 * box_length + port_length, ms_width / -2.0, bt]
openems.Port(em, start, stop, direction='x', z=50)

# port (sl)
start = [0.5 * box_length, sl_width / 2.0, -sub2t]
stop = [0.5 * box_length - port_length, sl_width / -2.0, -sub2t - ifoil]
openems.Port(em, start, stop, direction='x', z=50)

openems.Via(copper,
            priority=9,
            x=0,
            y=0,
            z=[[bb, bt], [bt, bt - ofoil], [0, ifoil],
               [-sub2t, -sub2t - ifoil], [bb + ofoil, bb]],
            drillradius=0.5 * 0.25e-3,
            wall_thickness=25e-6,
            padradius=0.46e-3 * 0.5,
            padname='1')

for x in range(-3, 4):
    x *= 0.5 * mm
    for y in [-0.75 * mm, 0.75 * mm]:
        copper.AddCylinder([x, y, bb], [x, y, bt], 0.3 * mm * 0.5, priority=9)
        copper.AddCylinder([x, y, bt], [x, y, bt - ofoil],
                           0.46 * mm * 0.5,
                           priority=9)

command = 'view solve'
if len(sys.argv) > 1:
Ejemplo n.º 4
0
 def generate(self):
     ring_ix = 0.5 * (np.max(self.rl) + self.end_gap)
     ring_ox = ring_ix + 2.0 * self.via_padradius
     via_z = [[self.z[0], self.z[2]], [self.z[1], self.z[2]]]
     # fingers
     y = -0.5 * self.space[-1:][0]
     mirror = False
     mirrorstring = ['', 'x']
     for i in range(len(self.space))[::-1]:  # reverse order
         x1 = 0.5 * (ring_ox + ring_ix)
         x2 = ring_ix - self.rl[i]
         y += self.space[i]
         start = [x1, y, self.z[1]]
         y += self.rw[i]
         stop = [x2, y, self.z[2]]
         box = openems.Box(self.em,
                           None,
                           self.metal_name,
                           self.priority,
                           start,
                           stop,
                           padname='2')
         box.mirror(mirrorstring[mirror])
         mirror = not mirror
         box2 = box.duplicate()
         box2.mirror('xy')
         v = openems.Via(self.em,
                         None,
                         'pec',
                         2,
                         x=ring_ix + self.via_padradius,
                         y=y - 0.5 * self.rw[i],
                         z=via_z,
                         drillradius=self.via_radius,
                         padradius=self.via_padradius,
                         padname='2')
         v.mirror(mirrorstring[not mirror])
         v2 = v.duplicate()
         v2.mirror('xy')
     mirror = not mirror
     # ports
     y1 = y
     y -= 0.5 * self.rw[0]  # center of line
     y2 = y + 0.5 * self.feedwidth + self.ring_y_width  # y outside
     px = ring_ix - self.tapoffset
     py = y2 - self.portlength
     start = [px + 0.5 * self.feedwidth, y2, self.z[1]]
     stop = [px - 0.5 * self.feedwidth, py, self.z[2]]
     p = openems.Port(self.em, start, stop, direction='y', z=50)
     p.mirror(mirrorstring[mirror])
     p2 = p.duplicate().mirror('xy')
     # feed lines
     start = [px + 0.5 * self.feedwidth, py, self.z[1]]
     stop = [px - 0.5 * self.feedwidth, py - self.feedwidth, self.z[2]]
     box = openems.Box(self.em,
                       None,
                       self.metal_name,
                       self.priority,
                       start,
                       stop,
                       padname='1')
     box.mirror(mirrorstring[mirror])
     box2 = box.duplicate()
     box2.mirror('xy')
     box2.padname = '3'
     tie = openems.Polygon(self.em,
                           points=[[-px + 0.5 * self.feedwidth, py],
                                   [-px - 0.5 * self.feedwidth, py],
                                   [-px - 0.5 * self.feedwidth, y1],
                                   [-px + 0.5 * self.feedwidth, y1]],
                           elevation=[self.z[1], self.z[2]],
                           priority=9)
     tie2 = tie.duplicate().mirror('xy')
     # substrate
     start = np.array([ring_ox, y2, self.z[0]])
     stop = openems.mirror(start, 'xy')
     stop[2] = self.z[1]
     sub = openems.Box(self.em, None, 'sub', 1, start, stop)
     # mask
     if self.mask_thickness > 0.0:
         start = np.array([ring_ox, y2, self.z[1]])
         stop = openems.mirror(start, 'xy')
         stop[2] += self.mask_thickness
         openems.Box(self.em, None, 'mask', 1, start, stop)
Ejemplo n.º 5
0
 def generate(self):
     # fingers
     y = -0.5 * self.space[-1:][0]
     mirror = False
     mirrorstring = ['', 'x']
     for i in range(len(self.space))[::-1]:  # reverse order
         x1 = 0.5 * (self.ring_ox + self.ring_ix)
         x2 = self.ring_ix - self.rl[i]
         y += self.space[i]
         start = [x1, y, self.z[1]]
         y += self.rw[i]
         stop = [x2, y, self.z[2]]
         box = openems.Box(self.em,
                           None,
                           self.metal_name,
                           self.priority,
                           start,
                           stop,
                           padname='2')
         box.mirror(mirrorstring[mirror])
         mirror = not mirror
         box2 = box.duplicate()
         box2.mirror('xy')
         if i == 0:
             box.padname = '1'
             box2.padname = '3'
         box.offset(self.offset)
         box2.offset(self.offset)
     # feed lines
     mirror = not mirror
     y -= 0.5 * self.rw[0]  # center of line
     start = [self.ring_ix, y + 0.5 * self.feedwidth, self.z[1]]
     stop = [
         self.ring_ox - self.portlength, y - 0.5 * self.feedwidth, self.z[2]
     ]
     box = openems.Box(self.em,
                       None,
                       self.metal_name,
                       self.priority,
                       start,
                       stop,
                       padname='1')
     box.mirror(mirrorstring[mirror])
     box2 = box.duplicate()
     box2.mirror('xy')
     box2.padname = '3'
     box.offset(self.offset)
     box2.offset(self.offset)
     # ports
     start = [self.ring_ox, y + 0.5 * self.feedwidth, self.z[1]]
     stop = [
         self.ring_ox - self.portlength, y - 0.5 * self.feedwidth, self.z[2]
     ]
     p = openems.Port(self.em, start, stop, direction='x', z=50)
     p.mirror(mirrorstring[mirror])
     p2 = p.duplicate().mirror('xy')
     p.offset(self.offset)
     p2.offset(self.offset)
     # metal ring (sides)
     y1 = y + 0.5 * self.feedwidth + self.feedgap
     y2 = y1 + self.ring_y_width
     start = [self.ring_ox, y1, self.z[1]]
     stop = [-1.0 * self.ring_ox, y2, self.z[2]]
     box = openems.Box(self.em,
                       None,
                       self.metal_name,
                       self.priority,
                       start,
                       stop,
                       padname='2')
     box.mirror(mirrorstring[mirror])
     box2 = box.duplicate().mirror('xy')
     box.offset(self.offset)
     box2.offset(self.offset)
     # metal ring (sides)
     y3 = y - (0.5 * self.feedwidth + self.feedgap)
     start = [self.ring_ox, y3, self.z[1]]
     stop = [self.ring_ix, -1.0 * y2, self.z[2]]
     box = openems.Box(self.em,
                       None,
                       self.metal_name,
                       self.priority,
                       start,
                       stop,
                       padname='2')
     box.mirror(mirrorstring[mirror])
     box2 = box.duplicate().mirror('xy')
     box.offset(self.offset)
     box2.offset(self.offset)
     # metal - inner ends
     if self.inner_metal:
         for z in self.inner_metal_z:
             start = [self.ring_ox, y1, z[0]]
             stop = [-1.0 * self.ring_ox, y2, z[1]]
             box = openems.Box(self.em,
                               None,
                               self.metal_name,
                               self.priority,
                               start,
                               stop,
                               padname=None)
             box2 = box.duplicate().mirror('xy')
             box.offset(self.offset)
             box2.offset(self.offset)
             start = [self.ring_ox, y2, z[0]]
             stop = [self.ring_ix, -1.0 * y2, z[1]]
             box = openems.Box(self.em,
                               None,
                               self.metal_name,
                               self.priority,
                               start,
                               stop,
                               padname=None)
             box2 = box.duplicate().mirror('xy')
             box.offset(self.offset)
             box2.offset(self.offset)
     # substrate
     start = np.array([self.ring_ox, y2, self.z[0]])
     stop = openems.mirror(start, 'xy')
     stop[2] = self.z[1]
     sub = openems.Box(self.em, None, 'sub', 1, start, stop)
     sub.offset(self.offset)
     # mask
     if self.mask_thickness > 0.0:
         start = np.array([self.ring_ox, y2, self.z[1]])
         stop = openems.mirror(start, 'xy')
         stop[2] += self.mask_thickness
         openems.Box(self.em, None, 'mask', 1, start, stop)
     # vias (along y)
     via_z = [[self.z[0], self.z[2]]]  #, [self.z[1], self.z[2]]]
     y_start = y3 - self.via_padradius
     y_stop = -1.0 * y1 - self.via_padradius
     x = self.ring_ix + self.via_padradius
     if not self.via_radius:
         return
     n_via = 0
     n_vias = 1 + np.floor(
         np.abs(y_start - y_stop) / (2.0 * self.via_padradius))
     for y in np.linspace(y_start, y_stop, n_vias):
         v = openems.Via(self.em,
                         None,
                         'pec',
                         2,
                         x=x,
                         y=y,
                         z=via_z,
                         drillradius=self.via_radius,
                         padradius=self.via_padradius,
                         padname='2')
         v.mirror(mirrorstring[mirror])
         v2 = v.duplicate().mirror('xy')
         n_via += 2
         v.offset(self.offset)
         v2.offset(self.offset)
     # vias (along x)
     y = y_stop
     x_start = self.ring_ix + self.via_padradius
     x_stop = self.via_padradius - self.ring_ox
     n_vias = 1 + np.floor(
         np.abs(x_start - x_stop) / (2.0 * self.via_padradius))
     for x in np.linspace(x_start, x_stop, n_vias)[1:]:
         v = openems.Via(self.em,
                         None,
                         'pec',
                         2,
                         x=x,
                         y=y,
                         z=via_z,
                         drillradius=self.via_radius,
                         padradius=self.via_padradius,
                         padname='2')
         v.mirror(mirrorstring[mirror])
         v2 = v.duplicate().mirror('xy')
         n_via += 2
         v.offset(self.offset)
         v2.offset(self.offset)
Ejemplo n.º 6
0
    def generate(self):
        pec = openems.Metal(self.em, 'pec_filter')
        ring_ix = 0.5 * (np.max(self.rl) + self.end_gap)
        ring_ox = ring_ix + 2.0 * self.via_padradius
        via_z = [[self.z[0], self.z[1] + self.lidz], [self.z[1], self.z[2]]]
        # fingers
        y = -0.5 * self.space[-1:][0]
        mirror = False
        mirrorstring = ['', 'x']
        for i in range(len(self.space))[::-1]:  # reverse order
            x1 = 0.5 * (ring_ox + ring_ix)
            x2 = ring_ix - self.rl[i]
            y += self.space[i]
            start = [x1, y, self.z[1]]
            y += self.rw[i]
            stop = [x2, y, self.z[2]]
            box = openems.Box(pec,
                              9,
                              start,
                              stop,
                              padname='poly',
                              pcb_layer=self.pcb_layer)
            box.mirror(mirrorstring[mirror])
            mirror = not mirror
            box2 = box.duplicate()
            box2.mirror('xy')
            v = openems.Via(pec,
                            priority=2,
                            x=ring_ix + self.via_padradius,
                            y=y - 0.5 * self.rw[i],
                            z=via_z,
                            drillradius=self.via_radius,
                            padradius=self.via_padradius,
                            padname='2')
            if not mirror:
                v.mirror('x')
            v.duplicate().mirror('xy')
            if self.endmetal:
                v.duplicate().mirror('y')
                v.duplicate().mirror('x')

        mirror = not mirror
        # ports
        y1 = y
        y -= 0.5 * self.rw[0]  # center of line
        y2 = y + 0.5 * self.feedwidth + self.ring_y_width  # y outside
        px = ring_ix - self.tapoffset
        py = y2 - self.portlength
        start = [px + 0.5 * self.feedwidth, y2, self.z[1]]
        stop = [px - 0.5 * self.feedwidth, py, self.z[2]]
        p = openems.Port(self.em, start, stop, direction='y', z=50)
        p.mirror(mirrorstring[mirror])
        p2 = p.duplicate().mirror('xy')
        # feed lines
        start = [px + 0.5 * self.feedwidth, py, self.z[1]]
        stop = [px - 0.5 * self.feedwidth, y - 0.5 * self.rw[0], self.z[2]]
        box = openems.Box(pec,
                          9,
                          start,
                          stop,
                          padname='1',
                          pcb_layer=self.pcb_layer)
        box.mirror(mirrorstring[mirror])
        box2 = box.duplicate()
        box2.mirror('xy')
        box2.padname = '3'
        # substrate
        start = np.array([ring_ox, y2, self.z[0]])
        stop = openems.mirror(start, 'xy')
        stop[2] = self.z[1] + self.lidz
        sub = openems.Box(self.sub, 1, start, stop)
        # mask
        if self.mask_thickness > 0.0:
            start = np.array([ring_ox, y2, self.z[1]])
            stop = openems.mirror(start, 'xy')
            stop[2] += self.mask_thickness
            openems.Box(mask, 1, start, stop)
        # grounded end metal
        if self.endmetal:
            em1 = openems.Box(
                pec,
                9,
                start=[ring_ix, y2, self.z[1]],
                stop=[ring_ix + 2.0 * self.via_padradius, -y2, self.z[2]],
                padname='2',
                pcb_layer=self.pcb_layer)
            em1.duplicate().mirror('x')
Ejemplo n.º 7
0
def idbpf(
        em,  # openems instance
        sub,  # substrate, define with openems.Dielectric()
        z=[],  # z position, z[0] = sub bottom, z[1] = sub top, z[2] = foil top
        lidz=0,  # upper substrate thickness
        rl=[],  # length of resonator fingers
        rw=[],  # width of resonator fingers
        space=[],  # space between resonator fingers
        endmetal=True,  # add metal to filter ends
        portlength=0.2 * mm,  # length of the openems port
        feedwidth=0.85 * mm,  # width of the trace leaving the filter and port
        end_gap=0.3 * mm,  # space between the end of a resonator and ground
        via_radius=0.15 * mm,  # radius of the via drills
        via_padradius=0.3 * mm,  # radius of the via pads
        pcb_layer='F.Cu',  # Kicad layer
        mask=None,  # mask, define with openems.Dielectric()
        mask_thickness=0,  # set to non-zero to enable solder mask over filter
):
    edge_space = 0.5 * mm
    pec = openems.Metal(em, 'pec_filter')
    ring_ix = 0.5 * (np.max(rl) + end_gap)
    ring_ox = ring_ix + 2.0 * via_padradius
    via_z = [[z[0], z[1] + lidz], [z[1], z[2]]]
    # fingers
    y = -0.5 * space[-1:][0]
    mirror = False
    mirrorstring = ['', 'x']
    for i in range(len(space))[::-1]:  # reverse order
        x1 = 0.5 * (ring_ox + ring_ix)
        x2 = ring_ix - rl[i]
        y += space[i]
        start = [x1, y, z[1]]
        y += rw[i]
        stop = [x2, y, z[2]]
        box = openems.Box(pec,
                          9,
                          start,
                          stop,
                          padname='poly',
                          pcb_layer=pcb_layer)
        box.mirror(mirrorstring[mirror])
        mirror = not mirror
        box2 = box.duplicate()
        box2.mirror('xy')
        if i == 0:
            continue
        v = openems.Via(pec,
                        priority=2,
                        x=ring_ix + via_padradius,
                        y=y - 0.5 * rw[i],
                        z=via_z,
                        drillradius=via_radius,
                        padradius=via_padradius,
                        padname='2')
        if not mirror:
            v.mirror('x')
        v.duplicate().mirror('xy')
    mirror = not mirror
    # ports
    y1 = y + feedwidth - rw[0]  # outer edge of feed
    y2 = y - rw[0]  # inner edge
    px = ring_ox
    start = [px, y2, z[1]]
    stop = [px - portlength, y1, z[2]]
    p = openems.Port(em, start, stop, direction='x', z=50)
    p.mirror(mirrorstring[mirror])
    p2 = p.duplicate().mirror('xy')
    # feed lines
    start = [-ring_ix + rl[0], y1, z[1]]
    stop = [px - portlength, y2, z[2]]
    box = openems.Box(pec, 9, start, stop, padname='1', pcb_layer=pcb_layer)
    box.mirror(mirrorstring[mirror])
    box2 = box.duplicate()
    box2.mirror('xy')
    box2.padname = '3'
    # substrate
    start = np.array([ring_ox, y1 + edge_space, z[0]])
    stop = openems.mirror(start, 'xy')
    stop[2] = z[1] + lidz
    sub = openems.Box(sub, 1, start, stop)
    # mask
    if mask_thickness > 0.0:
        start = np.array([ring_ox, y2, z[1]])
        stop = openems.mirror(start, 'xy')
        stop[2] += mask_thickness
        openems.Box(mask, 1, start, stop)
    # grounded end metal
    if endmetal:
        em1 = openems.Box(
            pec,
            9,
            start=[ring_ix, -y2 + space[0], z[1]],
            stop=[ring_ix + 2.0 * via_padradius, y1 + edge_space, z[2]],
            padname='2',
            pcb_layer=pcb_layer)
        em1.duplicate().mirror('xy')
Ejemplo n.º 8
0
def idbpf(em, # openems instance
          sub, # substrate, define with openems.Dielectric()
          lidz = 0.0,
          z = [], # z position, z[0] = sub bottom, z[1] = sub top, z[2] = foil top
          space = [], # space between resonator fingers
          rl = [], # length of resonator fingers
          rw = [], # width of resonator fingers
          portlength = 0.2*mm, # length of the openems port
          feedwidth = 0.85*mm, # width of the trace leaving the filter and port
          tapoffset = 1.0*mm, # offset of tap from end of resonator
          end_gap = 0.3*mm, # space between the end of a resonator and ground
          via_radius = 0.15*mm, # radius of the via drills
          via_padradius = 0.3*mm, # radius of the via pads
          pcb_layer = 'F.Cu', # Kicad layer
          mask_thickness = 0, # set to non-zero to enable solder mask over filter
          mask = None, # mask, define with openems.Dielectric()
          endmetal = True, # add metal to filter ends
):
    pec = openems.Metal(em, 'pec_filter')
    ring_y_width = via_padradius * 2.0
    ring_ix = 0.5 * (np.max(rl) + end_gap)
    ring_ox = ring_ix + 2.0 * via_padradius
    via_z = [[z[0], z[1]+lidz], [z[1], z[2]]]
    # fingers
    y = -0.5*space[-1:][0]
    mirror = np.array([1,1,1])
    if len(space) % 2 == 0:
        mirror[0] *= -1
    for i in range(len(space))[::-1]: # reverse order
        x1 = 0.5 * (ring_ox + ring_ix)
        x2 = ring_ix - rl[i]
        y += space[i]
        start = [x1, y, z[1]];
        y += rw[i]
        stop  = [x2, y, z[2]];
        for m in [np.array([1,1,1]),np.array([-1,-1,1])]:
            m *= mirror
            openems.Box(pec, 9, start*m, stop*m, padname = 'poly', pcb_layer=pcb_layer)
            openems.Via(pec, priority=2,
                        x=m[0]*(ring_ix+via_padradius),
                        y=m[1]*(y-0.5*rw[i]),
                        z=via_z,
                        drillradius=via_radius,
                        padradius=via_padradius, padname='2')
        mirror[0] *= -1

        if endmetal:
            v.duplicate().mirror('y')
            v.duplicate().mirror('x')

    mirror *= [-1,1,1]
    # ports
    y1 = y
    y -= 0.5*rw[0] # center of line
    y2 = y + 0.5*feedwidth + ring_y_width # y outside
    px = ring_ix - tapoffset
    py = y2 - portlength
    for m in [-1,1]:
        start = [m*(px + 0.5*feedwidth), m*y2, z[1]]
        stop  = [m*(px - 0.5*feedwidth), m*py, z[2]]
        openems.Port(em, start, stop, direction='y', z=50)
        # feed lines
        start = [m*(px + 0.5*feedwidth), m*py, z[1]]
        stop  = [m*(px - 0.5*feedwidth), m*(y-0.5*rw[0]), z[2]]
        openems.Box(pec, 9, start, stop, padname = '1' if m==1 else '3',
                    pcb_layer=pcb_layer)
    # substrate
    start = np.array([ring_ox, y2, z[0]])
    stop  = openems.mirror(start, 'xy')
    stop[2] = z[1]+lidz
    sub = openems.Box(sub, 1, start, stop)
    # mask
    if mask_thickness > 0.0:
        start = np.array([ring_ox, y2, z[1]])
        stop  = openems.mirror(start, 'xy')
        stop[2] += mask_thickness
        openems.Box(mask, 1, start, stop)
    # grounded end metal
    if endmetal:
        for xm in [-1,1]:
            em1 = openems.Box(pec, 9, start = [xm*ring_ix, y2, z[1]],
                              stop = [xm*(ring_ix + 2.0*via_padradius), -y2, z[2]],
                              padname = '2', pcb_layer=pcb_layer)
Ejemplo n.º 9
0
copper.AddBox(start, stop, priority=9)

# ms port
start = [-0.5*box_length, ms_width/2.0, sub1t]
stop  = [-0.5*box_length + port_length, ms_width/-2.0, bt]
openems.Port(em, start, stop, direction='x', z=50)

via_z = [[bt,bb],[bt, bt-ofoil], [0, ifoil], [-sub2t, -sub2t-ifoil], [bb+ofoil, bb]]

# ground vias
for n in range(-3,4):
    r = 1 * mm
    c = np.exp(1j*2*np.pi*n*22.0/180.0) * r
    openems.Via(copper, priority=9, x=np.real(c), y=np.imag(c), z=via_z,
                drillradius = 0.25*mm*0.5,
                wall_thickness = 25e-6,
                padradius = via_pad * 0.5,
                padname='2')

# signal via
openems.Via(copper, priority=9, x=0, y=0,
            z=[[bt,bb],[bt, bt-ofoil], [0, ifoil], [-sub2t, -sub2t-ifoil], [bb+ofoil, bb]],
            drillradius = 0.25*mm*0.5,
            wall_thickness = 25e-6,
            padradius = via_pad * 0.5,
            padname='1')

# coax shield
planar.add_center_hole(copper, [bb, zmin], r=1.5*mm/2.0, priority=1)

pin_diameter = 0.695*mm