Standalone FEM STEP Model#

This tutorial tells you how to simulate a STEP CAD file with the FEM (GetDP) backend. You do not have to build a CSXCAD geometry first.

The FDTD backend has a related function. See Standalone FDTD STEP Model.

Note

This backend needs the getdp program on your PATH. See Installation.

Make a file with the name inset_fed_patch_step_fem.py.

Import the modules#

from pathlib import Path
import numpy as np
from simpleEMS import SimTools, simulate_step_FEM

simulate_step_FEM reads the STEP file and runs the FEM solver. SimTools shows and exports the results. All the simpleEMS workflows use SimTools.

Model structure#

A STEP file contains only named solids. It contains no material data and no port data. You must tell the function what each solid is.

Four arguments give the role of each solid:

  • dielectrics={name: (eps_r, tan_d)} — the dielectric solids, for example the substrate

  • pec=[name, ...] — the solids that are perfect conductors

  • lossy_conductor={name: sigma} — the conductors that have losses

  • ports={name: {"z0": ..., "direction": "x|y|z", "number": ...}} — the ports

The FEM backend also reads the name of each solid that these arguments do not name. A name that contains substrate becomes a dielectric. A name that contains ground or patch becomes a perfect conductor. A name that contains port becomes a port. The four arguments above always win.

The example uses a STEP file with five named solids:

Solid

Role from

Function

substrate

dielectrics

dielectric substrate

patch_inset

pec

radiant patch

feed

pec

inset feed line

ground

pec

ground plane

port_resist_1

ports

lumped port

Set the parameters#

STEP_FILE = Path(__file__).parent / "structure.step"

resonant_freq = 24.125e9  # Hz
span_freq = 2e9  # Hz
freqs = np.linspace(resonant_freq - span_freq, resonant_freq + span_freq, 501)

STEP_FILE gives the path to the CAD file. freqs gives the frequency points of the results.

Simulate the model#

sim_data = simulate_step_FEM(
    STEP_FILE,
    freqs,
    dielectrics={"substrate": (3.48, 0.0037)},  # (eps_r, tan_d)
    pec=["patch_inset", "feed", "ground"],
    ports={"port_resist_1": {"z0": 50.0, "direction": "z", "number": 1}},
    FEM_boundary="silver_muller",
    FEM_num_solve_points=12,
    charac_imp=50.0,
)

One call does all of these steps:

  1. It reads the named solids from the STEP file.

  2. It makes the mesh.

  3. It runs the GetDP solver at a small number of frequencies.

  4. It calculates the results at all the frequencies you asked for.

The FEM_* arguments control the solver and the mesh. They set the outer boundary, the symmetry plane, the element order, the air padding, the density of the mesh, and the number of frequencies to solve at. SimParams gives the same settings the same names.

The function returns the S-parameters, the impedance, the VSWR, and the port power in one SimData.

Show the results#

SimTools.plot_s_param(sim_data.freqs, sim_data.s11)
SimTools.plot_smith_chart(
    sim_data.freqs, sim_data.s11, charac_imp=sim_data.ref_impedance
)
SimTools.plot_vswr(sim_data.freqs, sim_data.vswr)
SimTools.plot_impedance(sim_data.freqs, sim_data.z11)

nf2ff = SimTools.create_nf2ff()
SimTools.plot_2d_directivity(nf2ff, resonant_freq)
SimTools.plot_2d_rad_pattern(nf2ff, resonant_freq)
nf2ff_3d = SimTools.compute_nf2ff_3d(nf2ff, resonant_freq)
SimTools.plot_3d_directivity(nf2ff_3d, resonant_freq)
SimTools.plot_3d_gain(nf2ff_3d, resonant_freq, sim_data.input_power)
SimTools.plot_3d_power(nf2ff_3d, resonant_freq)

SimTools.save_plots()
SimTools.show_plots()

These commands show the S11 curve, the Smith chart, the VSWR, and the input impedance.

To show a radiation pattern, first get the far-field object from SimTools.create_nf2ff(). Then give it to the radiation plots, for example plot_2d_directivity or plot_3d_gain.

Export the results#

SimTools.export_touchstone(freqs=sim_data.freqs, s11=sim_data.s11, charac_imp=50.0)

This command writes the S11 results to a Touchstone file. Other RF tools can read this file.

Complete script#

The complete script is below. It simulates an inset-fed patch antenna at 24.125 GHz directly from structure.step. Then it shows the S11 curve, the Smith chart, the VSWR, the input impedance, and the radiation patterns. At the end it writes a Touchstone file.

#!/usr/bin/env python3
"""Inset-fed patch antenna at 24.125 GHz, FEM simulation directly from a standalone STEP file."""

# IMPORTS
from pathlib import Path
import numpy as np
from simpleEMS import SimTools, simulate_step_FEM
# IMPORTS

# PARAMS
STEP_FILE = Path(__file__).parent / "structure.step"

resonant_freq = 24.125e9  # Hz
span_freq = 2e9  # Hz
freqs = np.linspace(resonant_freq - span_freq, resonant_freq + span_freq, 501)
# PARAMS

# SIMULATE
sim_data = simulate_step_FEM(
    STEP_FILE,
    freqs,
    dielectrics={"substrate": (3.48, 0.0037)},  # (eps_r, tan_d)
    pec=["patch_inset", "feed", "ground"],
    ports={"port_resist_1": {"z0": 50.0, "direction": "z", "number": 1}},
    FEM_boundary="silver_muller",
    FEM_num_solve_points=12,
    charac_imp=50.0,
)
# SIMULATE

# PPROCESS
SimTools.plot_s_param(sim_data.freqs, sim_data.s11)
SimTools.plot_smith_chart(
    sim_data.freqs, sim_data.s11, charac_imp=sim_data.ref_impedance
)
SimTools.plot_vswr(sim_data.freqs, sim_data.vswr)
SimTools.plot_impedance(sim_data.freqs, sim_data.z11)

nf2ff = SimTools.create_nf2ff()
SimTools.plot_2d_directivity(nf2ff, resonant_freq)
SimTools.plot_2d_rad_pattern(nf2ff, resonant_freq)
nf2ff_3d = SimTools.compute_nf2ff_3d(nf2ff, resonant_freq)
SimTools.plot_3d_directivity(nf2ff_3d, resonant_freq)
SimTools.plot_3d_gain(nf2ff_3d, resonant_freq, sim_data.input_power)
SimTools.plot_3d_power(nf2ff_3d, resonant_freq)

SimTools.save_plots()
SimTools.show_plots()
# PPROCESS

# EXPORT
SimTools.export_touchstone(freqs=sim_data.freqs, s11=sim_data.s11, charac_imp=50.0)
# EXPORT