def calc( self, theta: np.array, phi: np.array, radius: float = 1, center: Coordinate3 = Coordinate3(0, 0, 0), verbose: int = 1, ): """ :param theta: Elevation (altitude) angle in degrees, which must be in the range [-90,90]. An angle of 0 degrees points along the positive z-axis. This parameter is an array where each value is an angle to test. :param phi: Azimuth angle in degrees, which must be in the range [0,360]. A value of 0 degrees points along the positive x-axis. A value between 0 and 90 degrees points between the positive x- and y-axes. This parameter is an array where each value is an angle to test. """ self._theta = theta self._phi = phi res = self._box.CalcNF2FF( sim_path=self.sim.sim_dir, freq=self.sim.reference_frequency, theta=theta, phi=phi, radius=radius, center=center.coordinate_list(), verbose=verbose, ) self._calc_gain(res) self._calc_enorm(res)
def construct_polygon( prop: CSProperties, points: List[Coordinate2], normal: Axis, elevation: float, priority: int, transform: CSTransform = None, ): """ """ poly_points = _poly_points(points) if transform is None: prim = _add_polygon( prop=prop, priority=priority, points=poly_points, norm_dir=normal.intval(), elevation=elevation, ) return prim fp_warning(construct_polygon) first_coord_center = np.average(poly_points[0]) second_coord_center = np.average(poly_points[1]) if normal.intval() == 0: center = Coordinate3( elevation, first_coord_center, second_coord_center ) elif normal.intval() == 1: center = Coordinate3( first_coord_center, elevation, second_coord_center ) else: center = Coordinate3( first_coord_center, second_coord_center, elevation ) centered_pts = [ np.subtract(pts, cent) for pts, cent in zip( poly_points, [first_coord_center, second_coord_center] ) ] prim = _add_polygon( prop=prop, priority=priority, points=centered_pts, norm_dir=normal.intval(), elevation=0, ) apply_transform(prim, transform) tr = CSTransform() tr.AddTransform("Translate", center.coordinate_list()) apply_transform(prim, tr) return prim
def test_corner(): box = Box3(Coordinate3(0, 0, 0), Coordinate3(1, 1, 1)) corners = box.corners() corners = [corner.coordinate_list() for corner in corners] assert corners == [ Coordinate3(0, 0, 0).coordinate_list(), Coordinate3(0, 1, 0).coordinate_list(), Coordinate3(1, 0, 0).coordinate_list(), Coordinate3(1, 1, 0).coordinate_list(), Coordinate3(0, 0, 1).coordinate_list(), Coordinate3(0, 1, 1).coordinate_list(), Coordinate3(1, 0, 1).coordinate_list(), Coordinate3(1, 1, 1).coordinate_list(), ]
def func(width: float): sim = Simulation(freq=freq, unit=unit, reference_frequency=ref_freq, sim_dir=None) pcb_prop = common_pcbs["oshpark4"] pcb = PCB( sim=sim, pcb_prop=pcb_prop, length=pcb_len, width=pcb_width, layers=range(3), omit_copper=[0], ) DifferentialMicrostrip( pcb=pcb, position=Coordinate2(0, 0), length=pcb_len, width=width, gap=trace_gap, propagation_axis=Axis("x"), port_number=1, excite=True, ref_impedance=50, ) Mesh( sim=sim, metal_res=1 / 80, nonmetal_res=1 / 10, min_lines=9, expand_bounds=((0, 0), (0, 0), (10, 40)), ) FieldDump( sim=sim, box=Box3( Coordinate3(-pcb_len / 2, -pcb_width / 2, 0), Coordinate3(pcb_len / 2, pcb_width / 2, 0), ), dump_type=DumpType.current_density_time, ) sim.run(csx=False) return np.abs(sim.ports[0].impedance(freq=ref_freq))
def test_corner(): box = Box3(Coordinate3(0, 0, 0), Coordinate3(1, 1, 1)) corners = box.corners() corners = np.array([corner.coordinate_list() for corner in corners]) assert np.array_equal( corners, np.array([ Coordinate3(0, 0, 0).coordinate_list(), Coordinate3(0, 1, 0).coordinate_list(), Coordinate3(1, 0, 0).coordinate_list(), Coordinate3(1, 1, 0).coordinate_list(), Coordinate3(0, 0, 1).coordinate_list(), Coordinate3(0, 1, 1).coordinate_list(), Coordinate3(1, 0, 1).coordinate_list(), Coordinate3(1, 1, 1).coordinate_list(), ]), )
def calc( self, theta: np.array, phi: np.array, radius: float = 1, center: Coordinate3 = Coordinate3(0, 0, 0), verbose: int = 1, ): """ """ self._theta = theta self._phi = phi res = self._box.CalcNF2FF( sim_path=self.sim.sim_dir, freq=self.sim.reference_frequency, theta=theta, phi=phi, radius=radius, center=center.coordinate_list(), verbose=verbose, ) self._calc_gain(res) self._calc_enorm(res)
def _poly_coords(poly: CSPrimPolygon) -> List[Coordinate3]: """ """ coords = poly.GetCoords() elev = poly.GetElevation() norm_dir = poly.GetNormDir() coord_list = [] for coord1, coord2 in zip(coords[0], coords[1]): if norm_dir == 0: coord_list.append(Coordinate3(elev, coord1, coord2)) elif norm_dir == 1: coord_list.append(Coordinate3(coord1, elev, coord2)) else: coord_list.append(Coordinate3(coord1, coord2, elev)) new_coords = [] for coord in coord_list: transform = poly.GetTransform() if transform is not None: coord = coord.transform(transform) coord = coord.round_prec(PREC) new_coords.append(coord) return _remove_prim_coord_dups(new_coords)
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, ) dump = FieldDump( sim=sim, box=Box3( Coordinate3(-pcb_len / 2, -pcb_width / 2, 0), Coordinate3(pcb_len / 2, pcb_width / 2, 0), ), ) mesh = 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)), ) if os.getenv("_PYEMS_PYTEST"): sys.exit(0)
lead = add_metal(csx=sim.csx, name="lead") construct_box( prop=lead, box=Box3( (pcb_len / 2 - sma_lead_len / 2, -sma_lead_width / 2, 0), (pcb_len / 2 + sma_rect_length, sma_lead_width / 2, sma_lead_height), ), priority=priorities["trace"], ) # coax port Coax( sim=sim, position=Coordinate3(pcb_len / 2 + sma_rect_length + coax_len / 2, 0, sma_lead_height / 2), length=coax_len, radius=coax_rad, core_radius=core_rad, shield_thickness=mil_to_mm(5), dielectric=coax_dielectric, propagation_axis=Axis("x", direction=-1), port_number=2, ref_impedance=50, ) mesh = Mesh( sim=sim, metal_res=1 / 120, nonmetal_res=1 / 10, min_lines=5,
unit = 1e-3 freq = np.linspace(5.3e9, 5.9e9, 501) sim = Simulation(freq=freq, unit=unit) metal = sim.csx.AddMetal("metal") stl = metal.AddPolyhedronReader(filename=os.path.abspath("horn-antenna.stl")) stl.ReadFile() wg = standard_waveguides["WR159"] wg.set_unit(unit) wg_len = 40 port = RectWaveguidePort( sim=sim, box=Box3( Coordinate3(-wg.a / 2, -wg.b / 2, -wg_len), Coordinate3(wg.a / 2, wg.b / 2, 0), ), propagation_axis=Axis("z"), excite=True, ) port.add_metal_shell(thickness=5) mesh = Mesh( sim=sim, metal_res=1 / 20, nonmetal_res=1 / 10, smooth=(1.5, 1.5, 1.5), min_lines=5, expand_bounds=((16, 16), (16, 16), (8, 24)), )
sim = Simulation( freq=freq, unit=unit, boundary_conditions=BoundaryConditions( (("PML_8", "PML_8"), ("PML_8", "PML_8"), ("PML_8", "PML_8")), ), ) dielectric = common_dielectrics["PTFE"] length = 50 coax_rad = mil_to_mm(190 / 2) # RG-141 core_rad = (coax_core_diameter( 2 * coax_rad, dielectric.epsr_at_freq(sim.center_frequency())) / 2) Coax( sim=sim, position=Coordinate3(0, 0, 0), length=length, radius=coax_rad, core_radius=core_rad, shield_thickness=mil_to_mm(5), dielectric=dielectric, propagation_axis=Axis("x"), port_number=1, excite=True, feed_shift=0.3, ref_impedance=50, ) mesh = Mesh( sim=sim, metal_res=1 / 40,
def sim_func(cutout_width: float): """ """ sim = Simulation(freq=freq, unit=unit, reference_frequency=ref_freq) core_rad = (coax_core_diameter( 2 * coax_rad, coax_dielectric.epsr_at_freq(sim.reference_frequency)) / 2) pcb_prop = common_pcbs["oshpark4"] 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=pcb_len, width=trace_width, propagation_axis=Axis("x"), trace_layer=0, gnd_layer=1, port_number=1, ref_impedance=50, excite=True, ) # Mueller BU-1420701851 edge mount SMA pad = sim.csx.AddConductingSheet( "pad", conductivity=pcb_prop.metal_conductivity(), thickness=pcb_prop.copper_thickness(0), ) pad.AddBox( priority=priorities["trace"], start=[pcb_len / 2 - sma_lead_len / 2, -sma_lead_width / 2, 0], stop=[pcb_len / 2, sma_lead_width / 2, 0], ) pad_cutout = sim.csx.AddMaterial( "gnd_cutout", epsilon=pcb_prop.substrate.epsr_at_freq(ref_freq), kappa=pcb_prop.substrate.kappa_at_freq(ref_freq), ) pad_cutout.AddBox( priority=priorities["keepout"], start=[ pcb_len / 2 - sma_lead_len / 2, -cutout_width / 2, pcb.copper_layer_elevation(1), ], stop=[pcb_len / 2, cutout_width / 2, pcb.copper_layer_elevation(1)], ) sma_box = sim.csx.AddMetal("sma_box") sma_box.AddBox( priority=priorities["ground"], start=[ pcb_len / 2, -sma_rect_width / 2, -sma_rect_height / 2 + sma_lead_height / 2, ], stop=[ pcb_len / 2 + sma_rect_length, sma_rect_width / 2, sma_rect_height / 2 + sma_lead_height / 2, ], ) sma_keepout = sim.csx.AddMaterial( "sma_keepout", epsilon=coax_dielectric.epsr_at_freq(ref_freq), kappa=coax_dielectric.kappa_at_freq(ref_freq), ) sma_keepout.AddCylinder( priority=priorities["keepout"], start=[pcb_len / 2, 0, sma_lead_height / 2], stop=[pcb_len / 2 + sma_rect_length, 0, sma_lead_height / 2], radius=coax_rad, ) for ypos in [ -sma_rect_width / 2, sma_rect_width / 2 - sma_gnd_prong_width, ]: # sma_box.AddBox( # priority=priorities["ground"], # start=[pcb_len / 2 - sma_gnd_prong_len, ypos, 0], # stop=[ # pcb_len / 2, # ypos + sma_gnd_prong_width, # sma_gnd_prong_height # ], # ) # sma_box.AddBox( # priority=priorities["ground"], # start=[ # pcb_len / 2 - sma_gnd_prong_len, # ypos, # pcb.copper_layer_elevation(1) # ], # stop=[ # pcb_len / 2, # ypos + sma_gnd_prong_width, # pcb.copper_layer_elevation(1) - sma_gnd_prong_height, # ], # ) sma_box.AddBox( priority=priorities["ground"], start=[ pcb_len / 2 - sma_gnd_prong_len, ypos, pcb.copper_layer_elevation(1) - sma_gnd_prong_height, ], stop=[ pcb_len / 2, ypos + sma_gnd_prong_width, sma_gnd_prong_height, ], ) lead = sim.csx.AddMetal("lead") lead.AddBox( priority=priorities["trace"], start=[pcb_len / 2 - sma_lead_len / 2, -sma_lead_width / 2, 0], stop=[ pcb_len / 2 + sma_rect_length, sma_lead_width / 2, sma_lead_height, ], ) # coax port Coax( sim=sim, position=Coordinate3( pcb_len / 2 + sma_rect_length + coax_len / 2, 0, sma_lead_height / 2, ), length=coax_len, radius=coax_rad, core_radius=core_rad, shield_thickness=mil_to_mm(5), dielectric=coax_dielectric, propagation_axis=Axis("x", direction=-1), port_number=2, ref_impedance=50, ) mesh = Mesh( sim=sim, metal_res=1 / 120, nonmetal_res=1 / 10, min_lines=5, expand_bounds=((0, 0), (0, 0), (10, 10)), ) box = mesh.sim_box(include_pml=False) sim.run(csx=False) s11 = sim.s_param(1, 1) s21 = sim.s_param(2, 1) print("cutout width: {}".format(cutout_width)) print_table( data=[sim.freq / 1e9, s11, s21], col_names=["freq", "s11", "s21"], prec=[4, 4, 4], ) return np.sum(s11)