Skip to content

Instantly share code, notes, and snippets.

@biergaizi
Created January 12, 2023 03:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save biergaizi/7f45c243f6e17b509bd1ea785a6af9e7 to your computer and use it in GitHub Desktop.
Save biergaizi/7f45c243f6e17b509bd1ea785a6af9e7 to your computer and use it in GitHub Desktop.
Running openEMS and pyEMS Simulations

The following insturctions have been tested on Fedora 36.

Install openEMS

  1. Clone the git repository

     cd ~/
     git clone --recurse-submodule https://github.com/thliebig/openEMS-Project.git
    
  2. Install Dependencies

     dnf install cmake boost-devel tinyxml-devel vtk-devel hdf5-devel CGAL-devel \
                 python3-Cython python3-h5py python3-matplotlib \
                 octave-devel \
                 paraview
    
  3. Build openEMS

     cd ~/openEMS-Project
     ./update_openEMS.sh ~/openEMS-bin --python
    
  4. Add ~/openEMS-bin/bin to Unix search path, e.g.

     export PATH=$(realpath ~/openEMS-bin/bin/):$PATH
    

    Make sure to add it in ~/.bashrc to make it permanent.

Install pyEMS

pyEMS is an unofficial framework for modeling and simulating circuit boards, it provides high-level objects like resistors, traces, vias, etc., so that everything doesn't have to be modeled from scratch, similar to a standard library.

Currently the project is in very-early stage development. It creates an openEMS model and calls openEMS for simulation. It's only the work of a single developer, unrelated to the openEMS project. But we install it since it has some interesting demos.

  1. Clone the git repository

     cd ~/
     git clone https://github.com/matthuszagh/pyems.git
    
  2. Install pyEMS

     cd pyems
     python3 setup.py install --user
    

Run openEMS Python demo

As a warm-up, run an official openEMS demo to ensure the installation is functional. There are many demos in the Git repository, this particular one is a simulation of a microstrip quarter-wave stub filter on a circuit board.

cd ~/openEMS-Project/openEMS/python/Tutorials
python3 MSL_NotchFilter.py

The simulation output looks like this:

Create FDTD operator (compressed SSE + multi-threading)
FDTD simulation size: 235x82x14 --> 269780 FDTD cells
FDTD timestep is: 1.73955e-13 s; Nyquist rate: 410 timesteps @7.01052e+09 Hz
Excitation signal length is: 4706 timesteps (8.1863e-10s)
Max. number of timesteps: 1000000000 ( --> 212495 * Excitation signal length)
Create FDTD engine (compressed SSE + multi-threading)
Running FDTD engine... this may take a while... grab a cup of coffee?!?
[@        4s] Timestep:         1326 || Speed:   88.8 MC/s (3.040e-03 s/TS) || Energy: ~7.06e-17 (- 0.00dB)
[@        8s] Timestep:         3162 || Speed:  122.4 MC/s (2.204e-03 s/TS) || Energy: ~1.24e-14 (- 0.00dB)
[@       12s] Timestep:         4998 || Speed:  122.4 MC/s (2.205e-03 s/TS) || Energy: ~9.41e-15 (- 1.19dB)
[@       16s] Timestep:         6834 || Speed:  121.3 MC/s (2.225e-03 s/TS) || Energy: ~1.76e-15 (- 8.47dB)
[@       20s] Timestep:         8670 || Speed:  122.5 MC/s (2.203e-03 s/TS) || Energy: ~7.45e-18 (-32.20dB)
[@       24s] Timestep:        10506 || Speed:  122.0 MC/s (2.211e-03 s/TS) || Energy: ~2.82e-20 (-56.42dB)
[@       28s] Timestep:        12342 || Speed:  122.1 MC/s (2.210e-03 s/TS) || Energy: ~1.46e-20 (-59.27dB)
[@       32s] Timestep:        14178 || Speed:  122.7 MC/s (2.199e-03 s/TS) || Energy: ~1.03e-20 (-60.78dB)
Time for 14178 iterations with 269780.00 cells : 32.41 sec
Speed: 118.02 MCells/s

During a simulation, a pulse of electromagnetic energy is introduced in the simulation box. The energy in the system may go up and down for a while, but it should gradually decreases to zero, to -50 dB or lower. This marks the end of the simulation.

The average speed (in megacells per seconds) is what we want for benchmark.

After the simulation is finished, a Matplotlib window pops up to show its frequency characteristics, which can be ignored.

Run pyEMS demo

Then, we run a pyEMS demo. This particular demo is a microstrip directional coupler on a circuit board. This model is more complicated and takes several minutes to run, I think this model is particularly suitable for benchmarking.

cd ~/pyems/examples
python3 coupler.py

The Python script generates a huge number of warnings, such as...

RuntimeWarning: The iteration is not making good progress, as measured by the 
improvement from the last ten iterations.

This is harmless. It's just pyEMS's auto-mesher code.

A 3D CAD view would pop up, showing the 3D model of the circuit board. Just close the window. Then the script would ask

Continue simulation (y/n)?

Answer y. And the simulation runs...

 ---------------------------------------------------------------------- 
 | openEMS 64bit -- version v0.0.35-97-g0342eef
 | (C) 2010-2023 Thorsten Liebig <thorsten.liebig@gmx.de>  GPL license
 ---------------------------------------------------------------------- 
	Used external libraries:
		CSXCAD -- Version: v0.6.2-123-gc29742b
		hdf5   -- Version: 1.12.1
		          compiled against: HDF5 library version: 1.12.1
		tinyxml -- compiled against: 2.6.2
		fparser
		boost  -- compiled against: 1_76
		vtk -- Version: 9.1.0
		       compiled against: 9.1.0

Create FDTD operator (compressed SSE + multi-threading)
FDTD simulation size: 227x86x37 --> 722314 FDTD cells 
FDTD timestep is: 3.15554e-14 s; Nyquist rate: 880 timesteps @1.80059e+10 Hz
Excitation signal length is: 10088 timesteps (3.18331e-10s)
Max. number of timesteps: 1000000000 ( --> 99127.7 * Excitation signal length)
Create FDTD engine (compressed SSE + multi-threading)
Running FDTD engine... this may take a while... grab a cup of coffee?!?
[@        5s] Timestep:          440 || Speed:   54.0 MC/s (1.338e-02 s/TS) || Energy: ~2.78e-22 (- 0.00dB)
[...]
[@     6m43s] Timestep:        30800 || Speed:   56.2 MC/s (1.286e-02 s/TS) || Energy: ~2.51e-19 (-50.15dB)
Time for 30800 iterations with 722314.00 cells : 403.92 sec
Speed: 55.08 MCells/s

When the simulation is done, a Paraview window opens, allowing one to view the electromagnetic field from the simulation, this is not needed for benchmarking and can be closed.

Also, simulation result (the frequency response of the directional coupler, expressed in S-parameters) would appear on the console, which can be ignored.

freq        z0          s11         s21         s31         s41         
0.0000      19.3496     -30.4258    -0.1046     -67.4964    -69.2062    
0.0360      38.1013     -30.4258    -0.1047     -57.6830    -68.6046    

Headless

This pyems demo, by default, open CSX CAD and ask for conformation before the simulation and, and open Paraview to show the 3D view of the E&M field after the simulation. To make it headless-friendly, apply the following patch:

diff --git a/examples/coupler.py b/examples/coupler.py
index 5454205..b8a69c5 100755
--- a/examples/coupler.py
+++ b/examples/coupler.py
@@ -125,18 +125,4 @@ write_footprint(coupler, "coupler_20db", "coupler_20db.kicad_mod")
 if os.getenv("_PYEMS_PYTEST"):
     sys.exit(0)
 
-sim.run()
-sim.view_field()
-
-print_table(
-    data=[
-        sim.freq / 1e9,
-        np.abs(sim.ports[0].impedance()),
-        sim.s_param(1, 1),
-        sim.s_param(2, 1),
-        sim.s_param(3, 1),
-        sim.s_param(4, 1),
-    ],
-    col_names=["freq", "z0", "s11", "s21", "s31", "s41"],
-    prec=[4, 4, 4, 4, 4, 4],
-)
+sim.run(csx=False)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment