def generate(self): d1 = 0.5 * self.box_size d2 = d1 - self.port_length d3 = d2 - 0.2 * mm d4 = -0.5 * self.ms_width + self.miter # substrate start = np.array([0.5 * self.box_size, 0.5 * self.box_size, self.z[0]]) stop = np.array( [-0.5 * self.box_size, -0.5 * self.box_size, self.z[1]]) openems.Box(self.em, 'substrate', self.substrate_name, 1, start, stop) # port pads start = np.array([0.5 * self.ms_width, d2, self.z[1]]) stop = np.array([-0.5 * self.ms_width, d3, self.z[2]]) openems.Box(self.em, 'pad_1', self.metal_name, self.priority, start, stop, padname='1') start = np.array([d2, 0.5 * self.ms_width, self.z[1]]) stop = np.array([d3, -0.5 * self.ms_width, self.z[2]]) openems.Box(self.em, 'pad_2', self.metal_name, self.priority, start, stop, padname='2') # line openems.Polygon(self.em, name='miter_line', material=self.metal_name, priority=self.priority, points=np.array( [[-0.5 * self.ms_width, d2], [0.5 * self.ms_width, d2], [0.5 * self.ms_width, 0.5 * self.ms_width], [d2, 0.5 * self.ms_width], [d2, -0.5 * self.ms_width], [d4, -0.5 * self.ms_width], [-0.5 * self.ms_width, d4]]), elevation=self.z[1:], normal_direction='z', pcb_layer='F.Cu', pcb_width=0.001) # ports start = np.array([0.5 * self.ms_width, d1, self.z[1]]) stop = np.array([-0.5 * self.ms_width, d2, self.z[2]]) openems.Port(self.em, start, stop, direction='y', z=50) start = np.array([d1, 0.5 * self.ms_width, self.z[1]]) stop = np.array([d2, -0.5 * self.ms_width, self.z[2]]) openems.Port(self.em, start, stop, direction='x', z=50)
def smp_connector(em, x, y, z, zmax, coax_port_length=0.2e-3, pin_diameter=0.85e-3): copper_shield = openems.Metal(em, 'smp_shield') copper = openems.Metal(em, 'smp_pin') lcp = openems.Dielectric(em, 'lcp', eps_r=3.2) # shield outside = np.array([[-2.5, 1.0], [-2.5, 2.5], [2.5, 2.5], [2.5, -2.5], [-2.5, -2.5], [-2.5, -1.0]]) * 1e-3 angle = np.arcsin(1.0 / 2.25) inside = openems.arc(0, 0, 4.5e-3 / 2.0, -np.pi + angle, np.pi - angle) openems.Polygon(copper_shield, priority=9, pcb_layer=None, points=[x, y] + np.concatenate((inside, outside)), elevation=[z, z + 0.9e-3], normal_direction='z') outside = np.array([[0, 2.5], [2.5, 2.5], [2.5, -2.5], [0, -2.5]]) * 1e-3 inside = openems.arc(0, 0, 1.95e-3 / 2.0, -np.pi * 0.5, np.pi * 0.5) openems.Polygon(copper_shield, priority=9, pcb_layer=None, points=[x, y] + np.concatenate((inside, outside)), elevation=[z + 0.9e-3, zmax], normal_direction='z').duplicate().mirror('x') # pin start = np.array([x, y, zmax - coax_port_length]) stop = np.array([x, y, z + 0.9e-3]) copper.AddCylinder(start, stop, 0.5 * pin_diameter, priority=9) # smaller part of pin stop[2] = z copper.AddCylinder(start, stop, 0.5 * 0.8e-3, priority=9) # insulator start = np.array([x, y, z]) stop = np.array([x, y, z + 0.9e-3]) lcp.AddCylinder(start, stop, 4.5e-3 * 0.5, priority=1) if coax_port_length != 0: # port (coax) start = [ x + 0.5 * coax_port_length, y + 0.5 * coax_port_length, zmax - coax_port_length ] stop = [x - 0.5 * coax_port_length, y - 0.5 * coax_port_length, zmax] openems.Port(em, start, stop, direction='z', z=50) em.mesh.AddLine('z', start[2])
def generate(self): # substrate start = np.array( [0.5 * self.box_length, 0.5 * self.box_width, self.z[0]]) stop = np.array( [-0.5 * self.box_length, -0.5 * self.box_width, self.z[1]]) openems.Box(self.em, 'sub', self.substrate_name, 1, start, stop) # pads x0 = -0.5 * self.box_length x1 = x0 + self.port_length x2 = x1 + self.ms_width start = np.array([x1, 0.5 * self.ms_width, self.z[1]]) stop = np.array([x2, -0.5 * self.ms_width, self.z[2]]) l1 = openems.Box(self.em, 'line_p1', self.metal_name, self.priority, start, stop, padname='1') l2 = l1.duplicate("line_p2") l2.mirror('x') l2.padname = '2' x = x1 points = np.zeros((2 * len(self.section), 2)) i = 0 for s in self.section: points[i, 0] = x x += s[0] points[i + 1, 0] = x points[i, 1] = 0.5 * s[1] points[i + 1, 1] = 0.5 * s[1] i += 2 print points points = np.concatenate((points, points[::-1] * [1, -1.0])) print points openems.Polygon(self.em, name='f', material=self.metal_name, priority=self.priority, points=points, elevation=self.z[1:], normal_direction='z', pcb_layer='F.Cu', pcb_width=0.001 * mm) # main line ports start = [x0, -0.5 * self.ms_width, self.z[1]] stop = [x1, 0.5 * self.ms_width, self.z[2]] openems.Port(self.em, start, stop, direction='x', z=50).duplicate().mirror('x')
def ecbpf(em, rl, rw, space, feedwidth, portlength, z, ms50w = 0.5*mm): rl_max = np.max(rl) # finger 2 x = 0.5*rl_max y = 0.5*space[2] start = [x - rl[2], y, z[1]]; y += rw[2] stop = [x + rl[2], y, z[2]]; openems.Box(em, 'r2', 'pec', 9, start, stop).duplicate('r2m').mirror('xy') # finger 1 x += rl_max y += space[1] start = [x - rl[1], y, z[1]]; y += rw[1] stop = [x + rl[1], y, z[2]]; openems.Box(em, 'r1', 'pec', 9, start, stop).duplicate('r1m').mirror('xy') # finger 0 (half length coupling) x += rl_max y += space[0] start = [x - rl[0], y, z[1]]; stop = [x, y+rw[0], z[2]]; openems.Box(em, 'r0', 'pec', 9, start, stop).duplicate().mirror('xy') # ports ext start = [x, y, z[1]]; stop = [x + rw[0], y+rw[0], z[2]]; openems.Box(em, 'pext', 'pec', 9, start, stop).duplicate().mirror('xy') # ports ext x += rw[0] start = [x, y+rw[0], z[1]]; stop = [x + 0.5*mm, y+rw[0]-ms50w, z[2]]; openems.Box(em, 'pext2', 'pec', 9, start, stop).duplicate().mirror('xy') x += 0.5*mm # ports start = [x, y+rw[0], z[1]]; stop = [x+0.2*mm, y+rw[0]-ms50w, z[2]]; openems.Port(em, start, stop, direction='x', z=50).duplicate().mirror('xy') x += 0.2*mm y += 0.5*mm y += 0.25*mm # substrate start = [x, y, z[0]] stop = [-x, -y, z[1]] sub = openems.Box(em, None, 'sub', 1, start, stop);
# 0201 pads start = np.array([pad_x1, pad_y, substrate_top]) stop = np.array([pad_x2, -pad_y, foil_top]) copper.AddBox(start, stop, priority=9).duplicate().mirror('x') # 0201 body start = np.array([-body_x, -body_y, foil_top + body_z]) stop = np.array([ body_x, body_y, foil_top]) copper.AddBox(start, stop, padname = '1', priority=9) # ground plane cutout start = np.array([-cutout_x, -cutout_y, 0]) stop = np.array([ cutout_x, cutout_y, -foil_thickness]) air.AddBox(start, stop, priority=9) # port (ms) start = [-0.5*box_length, ms_width/2.0, substrate_top] stop = [-0.5*box_length + port_length, ms_width/-2.0, foil_top] openems.Port(em, start, stop, direction='x', z=50) # port (ms) start = [0.5*box_length, ms_width/2.0, substrate_top] stop = [0.5*box_length - port_length, ms_width/-2.0, foil_top] openems.Port(em, start, stop, direction='x', z=50) command = 'view solve' if len(sys.argv) > 2: command = sys.argv[2] em.run_openems(command)
def generate(self): x0 = self.endspace x1 = -1.0 * self.fork_length x2 = x1 - self.ms_width_70 x4 = x2 - self.endspace x3 = x4 + self.port_length y1 = self.resistor_gap y2 = y1 + self.ms_width_70 y4 = y2 + self.endspace y3 = y4 - self.port_length # substrate start = np.array([x0, y4, self.z[0]]) stop = np.array([x4, -1.0 * y4, self.z[1]]) openems.Box(self.em, 'wilkinson_sub', self.substrate_name, 1, start, stop) # common port line (pad 1) start = np.array([x1, 0.5 * self.ms_width, self.z[1]]) stop = np.array([x3, -0.5 * self.ms_width, self.z[2]]) openems.Box(self.em, 'line_common', self.metal_name, self.priority, start, stop, padname='1') # fork line openems.Polygon(self.em, name='forkline', material=self.metal_name, priority=self.priority, points=np.array([[0, y1], [0, y2], [x2 + self.miter, y2], [x2, y2 - self.miter], [x2, self.miter - y2], [x2 + self.miter, -1.0 * y2], [0, -1.0 * y2], [0, -1.0 * y1], [x1, -1.0 * y1], [x1, y1]]), elevation=self.z[1:], normal_direction='z', pcb_layer='F.Cu', pcb_width=0.001) # output lines start = np.array([-0.5 * self.ms_width, y1, self.z[1]]) stop = np.array([0.5 * self.ms_width, y3, self.z[2]]) lp2 = openems.Box(self.em, 'line_p2', self.metal_name, self.priority, start, stop, padname='2') lp3 = lp2.duplicate("line_p3") lp3.mirror('y') lp3.padname = '3' # main line port start = [x3, -0.5 * self.ms_width, self.z[1]] stop = [x4, 0.5 * self.ms_width, self.z[2]] openems.Port(self.em, start, stop, direction='x', z=50) # coupled line ports start = [-0.5 * self.ms_width, y3, self.z[1]] stop = [0.5 * self.ms_width, y4, self.z[2]] openems.Port(self.em, start, stop, direction='y', z=50).duplicate().mirror('y') # resistor self.em.add_resistor('r1', origin=np.array([0, 0, self.z[2]]), direction='y', value=100.0, invert=False, priority=9, dielectric_name='alumina', metal_name=self.metal_name, element_down=False)
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
def generate( em, substrate, z, # [bottom of substrate, top of substrate, top of metal] y1=5.5 * mm, y2=0.9 * mm, r=0.5 * mm, rv=[200, 200, 200, 200], w=[0.127 * mm, 0.152 * mm, 0.19 * mm, 0.23 * mm], port_length=0.2 * mm, ms_width=0.36 * mm, endspace=0.5 * mm, resistor_size='0402'): alumina = openems.Dielectric(em, 'alumina', eps_r=9.8) metal = openems.Metal(em, 'pec_wilkinson') n = len(rv) # substrate start = np.array([(n * 4 - 1) * r + endspace, y1 + r + endspace, z[0]]) stop = np.array([-1.0 * endspace, -1.0 * start[1], z[1]]) substrate.AddBox(start, stop, 1) # common port line (pad 1) start = np.array([-1.0 * endspace + port_length, 0.5 * ms_width, z[1]]) stop = np.array([0, -0.5 * ms_width, z[2]]) metal.AddBox(start, stop, priority=9, padname='1') lo = arc(r, -y1, r + 0.5 * w[0], pi, 2 * pi, 16) li = arc(r, -y1, r - 0.5 * w[0], pi, 2 * pi, 16) lo = cat((lo, arc(3 * r, -y2, r - 0.5 * w[0], pi, 0.55 * pi, 16))) li = cat((li, arc(3 * r, -y2, r + 0.5 * w[0], pi, 0.55 * pi, 16))) for i in range(n - 1): x = (4 * i + 3) * r w2 = w[1 + i] em.mesh.AddLine('x', x + r - 0.5 * w2) em.mesh.AddLine('x', x + r + 0.5 * w2) em.mesh.AddLine('x', x + 3 * r - 0.5 * w2) em.mesh.AddLine('x', x + 3 * r + 0.5 * w2) lo = cat((lo, arc(x, -y2, r - 0.5 * w2, 0.45 * pi, 0, 16))) li = cat((li, arc(x, -y2, r + 0.5 * w2, 0.45 * pi, 0, 16))) lo = cat((lo, arc(2 * r + x, -y1, r + 0.5 * w2, pi, 2 * pi, 16))) li = cat((li, arc(2 * r + x, -y1, r - 0.5 * w2, pi, 2 * pi, 16))) lo = cat((lo, arc(4 * r + x, -y2, r - 0.5 * w2, pi, 0.55 * pi, 16))) li = cat((li, arc(4 * r + x, -y2, r + 0.5 * w2, pi, 0.55 * pi, 16))) l = cat((lo, li[::-1])) l = cat((l[::-1] * [1, -1], l)) openems.Polygon(metal, priority=9, points=l, elevation=z[1:], normal_direction='z', pcb_layer='F.Cu', pcb_width=0.001) # x at 2 port side x0 = (n * 4 - 1) * r + endspace x1 = x0 - port_length # output lines for (ym, padname) in [(1, 2), (-1, 3)]: start = np.array([x1, ym * 0.2 * mm, z[1]]) stop = np.array([(n * 4 - 1) * r - 0.1 * mm, ym * (0.2 * mm + ms_width), z[2]]) lp2 = metal.AddBox(start, stop, priority=9, padname=padname) # main line port start = [-1.0 * endspace, -0.5 * ms_width, z[1]] stop = [-1.0 * endspace + port_length, 0.5 * ms_width, z[2]] openems.Port(em, start, stop, direction='x', z=50) # coupled line ports for ym in [-1, 1]: start = [x0 - port_length, ym * 0.2 * mm, z[1]] stop = [x0, ym * (0.2 * mm + ms_width), z[2]] openems.Port(em, start, stop, direction='x', z=50) for i in range(n): if not rv[i]: continue em.add_resistor('r{}'.format(i), origin=np.array([4 * r * i + 3 * r, 0, z[2]]), direction='y', value=rv[i], invert=False, priority=9, dielectric=alumina, metal=metal, element_down=False, size=resistor_size)
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)
def generate(self): # substrate start = np.array([0.5 * self.box_length, self.box_y[0], self.z[0]]) stop = np.array([-0.5 * self.box_length, self.box_y[1], self.z[1]]) openems.Box(self.em, 'coupler_sub', self.substrate_name, 1, start, stop) # through line ends (pads) x0 = -0.5 * self.box_length x1 = x0 + self.port_length start = np.array([x1, 0.5 * self.ms_width, self.z[1]]) stop = np.array( [x1 + self.pin_length, -0.5 * self.ms_width, self.z[2]]) l1 = openems.Box(self.em, 'line_p1', self.metal_name, self.priority, start, stop, padname='1') l2 = l1.duplicate("line_p2") l2.mirror('x') l2.padname = '2' xc1 = -0.5 * self.coupler_length - 0.5 * self.ms_width xc2 = xc1 + self.ms_width xm = xc1 + self.miter # through line middle diff = 0.5 * np.abs(self.ms_width - self.main_line_width) ppoints = np.array( [[x1, 0.5 * self.ms_width], [-1.0 * x1, 0.5 * self.ms_width], [-1.0 * x1, -0.5 * self.ms_width], [-1.0 * xm + diff, -0.5 * self.ms_width], [-1.0 * xm - diff, 0.5 * self.ms_width - self.main_line_width], [1.0 * xm + diff, 0.5 * self.ms_width - self.main_line_width], [xm - diff, -0.5 * self.ms_width], [x1, -0.5 * self.ms_width]]) openems.Polygon(self.em, name='throughline', material=self.metal_name, priority=self.priority, points=ppoints, elevation=self.z[1:], normal_direction='z', pcb_layer='F.Cu', pcb_width=0.001 * mm) # coupled line yc0 = 0.5 * self.ms_width + self.coupler_gap yc1 = yc0 + self.coupler_width yc4 = self.box_y[1] yc3 = yc4 - self.port_length yc2 = yc3 - self.pin_length # pads start = np.array([xc1, yc2, self.z[1]]) stop = np.array([xc2, yc3, self.z[2]]) l3 = openems.Box(self.em, 'line_p3', self.metal_name, self.priority, start, stop, padname='3') l4 = l3.duplicate("line_p4") l4.mirror('x') l4.padname = '4' if self.dual: l5 = l3.duplicate().mirror('y') l5.padname = '5' l6 = l4.duplicate().mirror('y') l6.padname = '6' p = openems.Polygon(self.em, name='coupledline', material=self.metal_name, priority=self.priority, points=np.array([[xc1 + self.miter, yc0], [xc1, yc0 + self.miter], [xc1, yc3], [xc2, yc3], [xc2, yc1], [-1.0 * xc2, yc1], [-1.0 * xc2, yc3], [-1.0 * xc1, yc3], [-1.0 * xc1, yc0 + self.miter], [-1.0 * xc1 - self.miter, yc0]]), elevation=self.z[1:], normal_direction='z', pcb_layer='F.Cu', pcb_width=0.001 * mm) if self.dual: p.duplicate().mirror('y') if not self.feed_coupled: # main line ports start = [x0, -0.5 * self.ms_width, self.z[1]] stop = [x1, 0.5 * self.ms_width, self.z[2]] openems.Port(self.em, start, stop, direction='x', z=50).duplicate().mirror('x') # coupled line ports start = [xc1, yc4, self.z[1]] stop = [xc2, yc3, self.z[2]] cp1 = openems.Port(self.em, start, stop, direction='y', z=50) cp2 = cp1.duplicate().mirror('x') if self.dual: cp1.duplicate().mirror('y') cp2.duplicate().mirror('y') if self.feed_coupled: # main line ports start = [x0, -0.5 * self.ms_width, self.z[1]] stop = [x1, 0.5 * self.ms_width, self.z[2]] openems.Port(self.em, start, stop, direction='x', z=50).duplicate().mirror('x') # ground via if self.cpw_gap != None: start = np.array([ -0.5 * self.box_length, -0.5 * self.ms_width - self.cpw_gap, self.z[0] ]) stop = np.array([0.5 * self.box_length, self.box_y[0], self.z[2]]) openems.Box(self.em, 'ground_lower_top', self.metal_name, self.priority, start, stop, padname=None) start = np.array([ -0.5 * self.box_length, 0.5 * self.ms_width + self.cpw_gap, self.z[0] ]) stop = np.array([xc1 - self.cpw_gap, self.box_y[1], self.z[2]]) openems.Box( self.em, 'ground_upper_left', self.metal_name, self.priority, start, stop, padname=None).duplicate('ground_upper_right').mirror('x')
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)
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')
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')
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)
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]] openems.Port(em, 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]] for m in ['', 'y']: openems.Port(em, start, stop, direction='x', z=50, mirror = m) # 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]] openems.Port(em, 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), )) for m in ['', 'y']: metal.AddPolygon( priority = priority, points = l, elevation = z[1:], normal_direction = 'z', pcb_layer = 'F.Cu', pcb_width = 0.001, mirror=m ) 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', mirror=m)
substrate_bottom = 0.0 substrate_top = substrate_bottom + substrate_thickness foil_top = substrate_top + foil_thickness from math import sqrt em.resolution = c/(em.fmax*sqrt(3.0))/100.0 # substrate start = np.array([0.5*box_length, 0.5*box_width, substrate_bottom]) stop = openems.mirror(start, 'xy') + np.array([0, 0, substrate_top+ms_air_above]) sub.AddBox(start, stop, 1); # line start = np.array([0.5*box_length-port_length, 0.5*ms_width, substrate_top]) stop = np.array([0, -0.5*ms_width, foil_top]) for m in [[1,1,1], [-1,1,1]]: pec.AddBox(start*m, stop*m, 2) # ports start = np.array([-0.5*box_length, ms_width/2.0, substrate_top]) stop = np.array([-0.5*box_length + port_length, ms_width/-2.0, foil_top]) for m in [[1,1,1], [-1,-1,1]]: openems.Port(em, start*m, stop*m, direction='x', z=50) em.write_kicad(em.name) command = 'view solve' if len(sys.argv) > 1: command = sys.argv[1] print(command) em.run_openems(command)