ETROYL Academy · Electromagnetic Modeling · Open-Source Tool

openEMS Parametric Design & Optimization Framework

An open-source Python framework for parametric electromagnetic design, full-wave simulation and global optimization built around openEMS.

ETROYL Academy Publication ID ETA-06-TL-000001 View Publication Registry
Built around openEMS

openEMS is an independent, free and open-source three-dimensional full-wave electromagnetic solver based on the FDTD method. This ETROYL resource does not replace or modify openEMS; it provides a structured Python workflow for parametric design, simulation and optimization around it.

Learn more from the official openEMS website and the official documentation.

Who is this for?

For engineers, researchers and students

This resource is intended for RF and microwave engineers, antenna and electromagnetic designers, radar and sensing engineers, academic researchers, engineering students, and developers interested in computational electromagnetics and automated design optimization.

01 · Foundations

Why parametric electromagnetic design?

Electromagnetic structures are often designed by changing dimensions, materials, feed locations or other physical parameters and repeatedly checking the resulting response. When this process is performed manually, each experiment can become a separate simulation setup, making comparisons harder to reproduce and optimization difficult to automate.

A parametric approach describes the structure through variables and relationships. The same simulation workflow can then generate many candidate geometries while changing only the parameters under investigation.

This framework applies that idea to full-wave 3D electromagnetic simulation. It combines YAML-based design definitions with Python, openEMS and CSXCAD, then adds objective functions, optimization engines and post-processing.

Category

Electromagnetic Modeling

Resource type

Open-Source Tool

Core technologies

Python · openEMS · CSXCAD · Optuna · SciPy

02 · Architecture

From design variables to electromagnetic results

The framework separates the main stages of a design study. A YAML file describes the design variables and geometry. Python resolves those parameters into an openEMS/CSXCAD model. The solver produces full-wave results, which are then converted into engineering quantities and objective values for optimization or analysis.

1. DefineVariables, materials, geometry, ports and simulation settings.
2. BuildResolve expressions and construct the 3D CSXCAD model.
3. SimulateRun the openEMS FDTD full-wave solver.
4. EvaluateCalculate S11, impedance, VSWR and radiation quantities.
5. OptimizeSearch the allowed parameter space using an objective function.
6. VerifyInspect the selected geometry and run a higher-accuracy simulation.

03 · Design Definition

Fixed geometry versus parametric geometry

The difference between a fixed design and an optimization-ready design is easiest to understand by looking at the complete YAML structure. In a fixed design, the geometry and port coordinates are explicit numbers. In a parametric design, the same physical description can be expressed through variables and mathematical relationships, allowing the framework to generate many candidate geometries automatically.

Fixed design

The repository's bowtie_4_points_fix.yaml is an example where the polygon coordinates, port coordinates and simulation settings are directly specified.

Geometry

primitives:
  - type: "polygon"
    material: "PEC_Patch"
    points:
      x: [0.001, 0.161, 0.161, 0.001]
      y: [0.0005, 0.083, -0.083, -0.0005]
    elevation: 0
    length: 0.0005
    norm_dir: "z"

  - type: "polygon"
    material: "PEC_Patch"
    points:
      x: [-0.001, -0.161, -0.161, -0.001]
      y: [0.0005, 0.083, -0.083, -0.0005]
    elevation: 0
    length: 0.0005
    norm_dir: "z"

Port

ports:
  - id: 1
    type: "lumped"
    resistance: 50.0
    direction: "x"
    excite: 1
    start: [-0.001, -0.0005, 0]
    stop:  [0.001, 0.0005, 0.0005]

Simulation

simulation:
  unit: 1.0
  fstart: 0.2
  fstop: 1.2
  n_pts: 1001

Variable design for optimization

The repository's dipole_variable.yaml expresses the geometry through variables. The optimizer can change selected variables while the geometry, port and simulation workflow remain structurally consistent.

Variables

variables:
  arm_length:
    type: "float"
    start: 0.15
    stop: 0.30
    step: 0.01
    default: 0.20

  root_width:
    type: "float"
    start: 0.004
    stop: 0.020
    step: 0.002
    default: 0.010

  tip_width:
    type: "float"
    start: 0.010
    stop: 0.40
    step: 0.005
    default: 0.30

  feed_gap:
    type: "float"
    start: 0.002
    stop: 0.002
    default: 0.002
    optimize: false

Geometry and port use expressions

points:
  x:
    - "feed_gap / 2.0"
    - "arm_length"
    - "arm_length"
    - "feed_gap / 2.0"
  y:
    - "root_width / 2.0"
    - "tip_width / 2.0"
    - "-tip_width / 2.0"
    - "-root_width / 2.0"

ports:
  - id: 1
    type: "lumped"
    resistance: 50.0
    direction: "x"
    excite: 1
    start:
      - "-feed_gap / 2.0"
      - "-root_width / 2.0"
      - 0
    stop:
      - "feed_gap / 2.0"
      - "root_width / 2.0"
      - 0.001

Simulation

simulation:
  unit: 1.0
  fstart: 0.3
  fstop: 1.0
  n_pts: 301
  end_criteria: 1e-2
  max_timesteps: 50000
  target_s11_db: -15.0
The key idea: the optimizer does not need a new electromagnetic model for every trial. It changes the selected variables, the framework resolves the geometry and port expressions, and openEMS evaluates the resulting candidate.

What can become variable?

Any design quantity exposed through the configuration can potentially become a design variable: dimensions, gaps, widths, positions and other geometry parameters. Variables can be bounded and quantized with a step size, while parameters such as a feed gap can remain fixed when they should not participate in the search.

04 · Simulation

Build and run the full-wave model

Once the parameters are resolved, the framework constructs the electromagnetic geometry and simulation setup. Materials, polygonal structures, boxes and lumped ports can be defined from the configuration. The mesh limits are derived from the simulation frequency range, and absorbing boundaries are applied around the computational domain.

A design can be inspected before running a full simulation. The repository provides a CAD-view workflow for checking the generated geometry and a dedicated simulation script for executing the FDTD solver.

Typical commands

python3 view_cad.py --config designs/dipole_variable.yaml

python3 simulate.py --config designs/dipole_variable.yaml

python3 postprocess.py --config designs/dipole_variable.yaml

05 · Objectives

Turn electromagnetic performance into an objective

Optimization requires a numerical measure of how good a candidate design is. The framework therefore keeps objective functions separate from geometry and solver code.

S11

Minimize reflection within a selected frequency band.

Worst-case S11

Penalize the poorest matching points relative to a target.

Bandwidth

Maximize the fraction of the band meeting an S11 threshold.

Impedance smoothness

Prefer designs with a flatter input-impedance magnitude.

Combined objective

Balance matching performance and impedance behavior with weighted terms.

Keeping objectives modular means that a design study can be changed from matching optimization to another engineering criterion without rebuilding the geometry or solver workflow.

06 · Optimization

Search the design space

The repository currently provides two optimization paths. Optuna's TPE sampler is suited to iterative exploration of parameter spaces, while SciPy SHGO performs a global search followed by Nelder-Mead local refinement. The SciPy path also quantizes candidate values to the configured parameter steps and caches repeated evaluations.

# Optuna TPE
python3 optimization.py     --config designs/dipole_variable.yaml     --n_trials 200

# SciPy SHGO + Nelder-Mead
python3 scipy_optimization.py     --config designs/dipole_variable.yaml     --max_evals 80

Each candidate is simulated and scored. Failed simulations receive a large penalty so that the optimizer moves away from invalid regions. After the search, the framework writes an optimized YAML configuration containing the selected parameter values.

07 · Verification & Analysis

Do not stop at the optimizer

Optimization is a search process, not a substitute for engineering verification. The selected design should be inspected and then simulated with higher-accuracy settings before its results are used for further engineering decisions.

The post-processing workflow extracts S11, input impedance and VSWR, and can calculate far-field patterns, directivity, realized gain and efficiency. The resulting plots provide a way to inspect the electromagnetic behavior rather than relying only on a single objective value.

Recommended learning sequence

  1. Inspect the default parametric geometry.
  2. Change one design variable and observe the generated geometry.
  3. Run a single simulation and inspect its electromagnetic response.
  4. Study the objective function and understand what it rewards.
  5. Run a small optimization experiment.
  6. Inspect the selected parameters and repeat the simulation at higher accuracy.
  7. Compare the optimized design against the original design.

09 · Questions & Feedback

Questions or feedback?

If you have a question, encounter an issue, or have a suggestion regarding the ETROYL framework, feel free to contact ETROYL. For questions about the openEMS solver itself, please use the official openEMS project resources.

Contact ETROYL →

10 · Source Code

Explore the engineering implementation

The ETROYL GitHub repository contains the complete implementation, example YAML designs, optimization engines, simulation workflow and post-processing scripts described on this page.

Use the Academy page to understand the engineering concepts and workflow; use the repository to inspect, run, modify and extend the implementation.

ETROYL/openEMS_Designs

Open-source Python framework for parametric electromagnetic design, simulation, post-processing and global optimization using openEMS.

View the complete source code on GitHub →