def gcpw(trace_width: float): """ """ sim = Simulation(freq=freq, unit=1e-3) pcb = PCB( sim=sim, pcb_prop=pcb_prop, length=pcb_len, width=pcb_width, layers=range(3), ) box = Box2( Coordinate2(-pcb_len / 2, -trace_width / 2), Coordinate2(pcb_len / 2, trace_width / 2), ) Microstrip( pcb=pcb, position=box.center(), length=box.length(), width=box.width(), propagation_axis=Axis("x"), trace_layer=0, gnd_layer=1, gnd_gap=(gap, gap), port_number=1, ref_impedance=50, excite=True, ) ViaWall( pcb=pcb, position=Coordinate2(0, trace_width / 2 + gap + via_gap), length=pcb_len, width=via_gap / 2, ) ViaWall( pcb=pcb, position=Coordinate2(0, -trace_width / 2 - gap - via_gap), length=pcb_len, width=via_gap / 2, ) Mesh( sim=sim, metal_res=1 / 120, nonmetal_res=1 / 40, smooth=(1.1, 1.5, 1.5), min_lines=25, expand_bounds=((0, 0), (24, 24), (24, 24)), ) sim.run(csx=False) return np.average(np.abs(np.abs(sim.ports[0].impedance()) - 50))
def gen_sim(width: float) -> Simulation: """ Create simulation objects to sweep over. :param width: Top layer trace width. This is the parameter we sweep over. """ sim = Simulation(freq=freq, unit=1e-3) pcb = PCB( sim=sim, pcb_prop=pcb_prop, length=pcb_len, width=pcb_width, layers=range(3), ) box = Box2( Coordinate2(-pcb_len / 2, -width / 2), Coordinate2(pcb_len / 2, width / 2), ) Microstrip( pcb=pcb, position=box.center(), length=box.length(), width=box.width(), propagation_axis=Axis("x"), trace_layer=0, gnd_layer=1, gnd_gap=(gap, gap), port_number=1, feed_shift=0.3, ref_impedance=50, excite=True, ) Mesh( sim=sim, metal_res=1 / 80, nonmetal_res=1 / 40, smooth=(1.2, 1.5, 1.5), min_lines=25, expand_bounds=((0, 0), (8, 8), (8, 20)), ) return sim_impedance(sim)
pcb_prop = common_pcbs["oshpark4"] pcb_len = 20 pcb_width = 5 trace_width = 0.34 gap = mil_to_mm(6) via_gap = 0.4 pcb = PCB( sim=sim, pcb_prop=pcb_prop, length=pcb_len, width=pcb_width, layers=range(3), ) box = Box2( Coordinate2(-pcb_len / 2, -trace_width / 2), Coordinate2(pcb_len / 2, trace_width / 2), ) Microstrip( pcb=pcb, position=box.center(), length=box.length(), width=box.width(), propagation_axis=Axis("x"), trace_layer=0, gnd_layer=1, gnd_gap=(gap, gap), port_number=1, ref_impedance=50, excite=True, )
def func(params: List[float]): """ """ cutout_width = params[0] sim = Simulation(freq=freq, unit=unit, sim_dir=None) pcb = PCB( sim=sim, pcb_prop=pcb_prop, length=pcb_len, width=pcb_width, layers=range(3), omit_copper=[0], ) box = Box2( Coordinate2(-pcb_len / 2, -trace_width / 2), Coordinate2(-(cap_dim.length / 2) - (pad_length / 2), trace_width / 2), ) Microstrip( pcb=pcb, position=box.center(), length=box.length(), width=box.width(), propagation_axis=Axis("x"), trace_layer=0, gnd_layer=1, port_number=1, excite=True, feed_shift=0.35, ref_impedance=z0_ref, ) SMDPassive( pcb=pcb, position=Coordinate2(0, 0), axis=Axis("x"), dimensions=cap_dim, pad_width=pad_width, pad_length=pad_length, c=10e-12, pcb_layer=0, gnd_cutout_width=cutout_width, gnd_cutout_length=1, ) box = Box2( Coordinate2(pcb_len / 2, trace_width / 2), Coordinate2((cap_dim.length / 2) + (pad_length / 2), -trace_width / 2), ) Microstrip( pcb=pcb, position=box.center(), length=box.length(), width=box.width(), propagation_axis=Axis("x", direction=-1), trace_layer=0, gnd_layer=1, port_number=2, excite=False, ref_impedance=z0_ref, ) Mesh( sim=sim, metal_res=1 / 120, nonmetal_res=1 / 40, smooth=(1.2, 1.2, 1.2), min_lines=5, expand_bounds=((0, 0), (0, 0), (10, 20)), ) sim.run(csx=False) print_table( data=[sim.freq / 1e9, sim.s_param(1, 1), sim.s_param(2, 1)], col_names=["freq", "s11", "s21"], prec=[4, 4, 4], ) return np.sum(sim.s_param(1, 1))
gcpw_width = 0.34 gcpw_gap = mil_to_mm(6) via_gap = 0.4 # drill_radius = gcpw_width / 2 - pcb_prop.via_plating_thickness(unit) drill_radius = 0.13 drill_diam = 2 * drill_radius annular_width = 0.145 antipad = gcpw_gap keepout_radius = drill_radius + annular_width + antipad via_sep = 0.76 via_fence_sep = via_sep * 2 sim = Simulation(freq=freq, unit=unit) pcb = PCB(sim=sim, pcb_prop=pcb_prop, length=pcb_len, width=pcb_width) box = Box2( Coordinate2(-pcb_len / 2, -gcpw_width / 2), Coordinate2(pcb_len / 4, gcpw_width / 2), ) Microstrip( pcb=pcb, position=box.center(), length=box.length(), width=box.width(), propagation_axis=Axis("x"), trace_layer=0, gnd_layer=1, gnd_gap=(gcpw_gap, gcpw_gap), via_gap=(via_gap, via_gap), via=None, port_number=1, feed_shift=0.2, excite=True,
drill_radius = 0.13 drill_diam = 2 * drill_radius annular_width = 0.145 antipad = mil_to_mm(6) keepout_radius = drill_radius + annular_width + antipad via_sep = 0.76 sim = Simulation(freq=freq, unit=unit) pcb = PCB( sim=sim, pcb_prop=pcb_prop, length=pcb_len, width=pcb_width, omit_copper=[0, 3], ) box = Box2((-pcb_len / 2, -microstrip_width / 2), (0, microstrip_width / 2)) Microstrip( pcb=pcb, position=box.center(), length=box.length(), width=box.width(), propagation_axis=Axis("x"), trace_layer=0, gnd_layer=1, port_number=1, feed_shift=0.3, excite=True, ref_impedance=z0_ref, ) Via(
freq = np.linspace(4e9, 8e9, 501) sim = Simulation(freq=freq, unit=1e-3) pcb_prop = common_pcbs["oshpark4"] pcb_len = 10 trace_width = 0.34 gap = mil_to_mm(6) via_gap = 0.4 pcb = PCB(sim=sim, pcb_prop=pcb_prop, length=pcb_len, width=pcb_len, layers=range(3)) box = Box2( Coordinate2(-pcb_len / 2, pcb_len / 4 - (trace_width / 2)), Coordinate2(pcb_len / 4, pcb_len / 4 + (trace_width / 2)), ) Microstrip( pcb=pcb, position=box.center(), length=box.max_corner.x - box.min_corner.x, width=trace_width, propagation_axis=Axis("x"), trace_layer=0, gnd_layer=1, gnd_gap=(gap, gap), port_number=1, feed_shift=0.4, excite=True, )
def sim_func(taper_angle: float): """ :param taper_angle: Linear taper angle in degrees. """ angle_rad = taper_angle * np.pi / 180 dy = np.abs(trace_width - microstrip_discontinuity_width) / 2 dx = dy / np.tan(angle_rad) taper_middle = microstrip_discontinuity_length / 2 + dx / 2 taper_end = microstrip_discontinuity_length / 2 + dx sim = Simulation(freq=freq, unit=unit, sim_dir=None) pcb = PCB( sim=sim, pcb_prop=pcb_prop, length=pcb_len, width=pcb_width, layers=range(3), omit_copper=[0], ) Microstrip( pcb=pcb, position=Coordinate2(0, 0), length=microstrip_discontinuity_length, width=microstrip_discontinuity_width, propagation_axis=Axis("x"), trace_layer=0, gnd_layer=1, ) Taper( pcb=pcb, position=Coordinate2(-taper_middle, 0), pcb_layer=0, width1=trace_width, width2=microstrip_discontinuity_width, length=dx, ) Taper( pcb=pcb, position=Coordinate2(taper_middle, 0), pcb_layer=0, width1=microstrip_discontinuity_width, width2=trace_width, length=dx, ) box = Box2( Coordinate2(-pcb_len / 2, -trace_width / 2), Coordinate2(-taper_end, trace_width / 2), ) Microstrip( pcb=pcb, position=box.center(), length=box.length(), width=trace_width, propagation_axis=Axis("x"), trace_layer=0, gnd_layer=1, port_number=1, excite=True, feed_shift=0.35, ref_impedance=50, ) box = Box2( Coordinate2(taper_end, -trace_width / 2), Coordinate2(pcb_len / 2, trace_width / 2), ) Microstrip( pcb=pcb, position=box.center(), length=box.length(), width=trace_width, propagation_axis=Axis("x", direction=-1), trace_layer=0, gnd_layer=1, port_number=2, ref_impedance=50, ) Mesh( sim=sim, metal_res=1 / 120, nonmetal_res=1 / 40, min_lines=5, expand_bounds=((0, 0), (0, 0), (10, 40)), ) # sim.run(csx=False) sim.run() return sim.s_param(1, 1)
taper_length = 0 # taper_length = 0.1501806 pcb = PCB( sim=sim, pcb_prop=pcb_prop, length=pcb_len, width=pcb_width, layers=range(3), omit_copper=[0], ) box = Box2( Coordinate2(-pcb_len / 2, -trace_width / 2), Coordinate2( -(cap_dim.length / 2) - (pad_length / 2) - taper_length, trace_width / 2, ), ) Microstrip( pcb=pcb, position=box.center(), length=box.length(), width=box.width(), propagation_axis=Axis("x"), trace_layer=0, gnd_layer=1, port_number=1, excite=True, feed_shift=0.35, ref_impedance=50,
pad_width=pad_width, pad_length=pad_length, c=10e-12, ) SMDPassive( pcb=pcb, position=Coordinate2(0, -trace_gap / 2 - trace_width / 2), axis=Axis("x"), dimensions=cap_dim, pad_width=pad_width, pad_length=pad_length, c=10e-12, ) box = Box2( Coordinate2(-pcb_len / 2, 0), Coordinate2(-cap_dim.length / 2 - pad_length / 2, 0), ) DifferentialMicrostrip( pcb=pcb, position=box.center(), length=box.length(), width=trace_width, gap=trace_gap, propagation_axis=Axis("x"), port_number=1, excite=True, ref_impedance=50, ) box = Box2( Coordinate2(cap_dim.length / 2 + pad_length / 2, 0), Coordinate2(pcb_len / 2, 0),
freq = np.linspace(4e9, 8e9, 501) sim = Simulation(freq=freq, unit=1e-3) pcb_prop = common_pcbs["oshpark4"] pcb_len = 10 trace_width = 0.38 gap = mil_to_mm(6) via_gap = 0.4 pcb = PCB(sim=sim, pcb_prop=pcb_prop, length=pcb_len, width=pcb_len, layers=range(3)) box = Box2( Coordinate2(-pcb_len / 2, pcb_len / 4 - (trace_width / 2)), Coordinate2(pcb_len / 4, pcb_len / 4 + (trace_width / 2)), ) miter = Miter( pcb=pcb, position=Coordinate2(pcb_len / 4, pcb_len / 4), pcb_layer=0, gnd_layer=1, trace_width=trace_width, gap=gap, ) print("miter: {:.4f}mm ({:.2f}%)".format( miter.miter, 100 * miter.miter / (trace_width * np.sqrt(2)))) Microstrip( pcb=pcb,
layers=range(3), omit_copper=[0], ) Microstrip( pcb=pcb, position=Coordinate2(0, 0), length=microstrip_discontinuity_length, width=microstrip_discontinuity_width, propagation_axis=Axis("x"), trace_layer=0, gnd_layer=1, ) box = Box2( Coordinate2(-pcb_len / 2, -trace_width / 2), Coordinate2(-microstrip_discontinuity_length / 2, trace_width / 2), ) Microstrip( pcb=pcb, position=box.center(), length=box.length(), width=trace_width, propagation_axis=Axis("x"), trace_layer=0, gnd_layer=1, port_number=1, excite=True, feed_shift=0.35, ref_impedance=50, )