예제 #1
0
파일: nf2ff.py 프로젝트: matthuszagh/pyems
 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)
예제 #2
0
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
예제 #3
0
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(),
    ]
예제 #4
0
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))
예제 #5
0
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(),
        ]),
    )
예제 #6
0
 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)
예제 #7
0
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)
예제 #8
0
    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)
예제 #9
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,
예제 #10
0
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)),
)
예제 #11
0
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,
예제 #12
0
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)