OpenEMS Source Code Breakdown
1. Overview of OpenEMS
(1) Languages Composition
- C++: 56.5%, the core solver is based on C++
- EC-FDTD solver
- Field propagator
- MATLAB / Octave: 33.3%, this part serves as MATLAB / Octave interface bridging to the C++ core.
- These files end with a suffix .m.
- The MATLAB / Octave interface doesn’t directly call the C++ core. It will simply invoke openEMS.exe with a generated setup.xml.
- Python + Cython: 7.1% + 1.7%, this part serves as the Python interface.
- The Python interface communicate with the C++ core directly.
- This link process is completed by Cython. Cython will make use of .dll and/or .lib
- CMake + C + Other: 1.0% + 0.3% + 0.1%, this documents help to generate .lib, .dll and .exe.
(2) Code Structure
<0> Concepts
Engine & Operator: Most of the code files can be classified into either engines or operators. Operators yield coefficients \(vv, ii, vi, iv\) used to update fields at each time steps, while engines literally manipulate the data stored in RAM with these coefficients.
Extension: Boundary conditions, lumped components and excitations are implemented as extensions in OpenEMS, which are also separated into engines and operators.
<1> Main Structure
CMakeLists.txt /* cmake config */
extension /* a folder containing extension */
class operator*
class engine*
class engine_interface*
class openems_fdtd_mpi*
class excitation*
<2> Operator Class
operator.cpp
operator_sse.cpp
operator_sse_compressed.cpp
operator_mpi.cpp
operator_multithread.cpp
operator_cylinder.cpp
operator_cylindermultigrid.cpp
<3> Engine Class
engine.cpp
engine_sse.cpp
engine_sse_compressed.cpp
engine_mpi.cpp
engine_multithread.cpp
engine_cylinder.cpp
engine_cylindermultigrid.cpp
<4> Engine Interface Class
engine_interface_sse_fdtd.cpp
engine_interface_fdtd.cpp
engine_interface_cylindrical_fdtd.cpp
<5> OpenEMS FDTD MPI (Message Passing Interface)
openems_fdtd_mpi.cpp
<6> Excitation Class
excitation.cpp
.h file have a similar structure:
operator_sse_compressed.h
operator_sse.h
operator_multithread.h
operator_mpi.h
operator_cylindermultigrid.h
operator_cylinder.h
operator.h
openems_fdtd_mpi.h
excitation.h
engine_sse_compressed.h
engine_sse.h
engine_multithread.h
engine_mpi.h
engine_interface_sse_fdtd.h
engine_interface_fdtd.h
engine_interface_cylindrical_fdtd.h
engine_cylindermultigrid.h
engine_cylinder.h
engine.h
<7> Extension
i. Tools
CMakeLists.txt /* cmake config */
OptimizeCondSheetParameter.m /* Conducting Sheet Optimizer */
cond_sheet_parameter.h /* Definitions of conduction sheets, used by operator_ext_conductingsheet */
ii. Extension Loader
operator_extension.cpp, operator_extension.h
engine_extension.cpp, engine_extension.h
engine_extension_dispatcher.h
iii. Boundary Condition
operator_ext_upml.cpp, engine_ext_upml.cpp /* perfect matching layer */
operator_ext_tfsf.cpp, engine_ext_tfsf.cpp /* total field / scattered field boundary */
operator_ext_mur_abc.cpp, engine_ext_mur_abc.cpp /* Mur absorbing boundary */
operator_ext_absorbing_bc.cpp, engine_ext_absorbing_bc.cpp /* sheet-type absorbing boundary */
iv. Material Dispersion
operator_ext_lorentzmaterial.cpp, engine_ext_lorentzmaterial.cpp /* Lorentz model */
operator_ext_dispersive.cpp, engine_ext_dispersive.cpp /* dispersive material, more general */
operator_ext_conductingsheet.cpp /* conducting sheet, operate with cond_sheet_parameter.h*/
v. Lumped RLC
operator_ext_lumpedRLC.cpp, engine_ext_lumpedRLC.cpp
vi. Excitation
operator_ext_excitation.cpp, engine_ext_excitation.cpp
vii. Steady State
operator_ext_steadystate.cpp, engine_ext_steadystate.cpp
viii. Cylinder & Multigrid
operator_ext_cylinder.cpp, engine_ext_cylindermultigrid.cpp, engine_ext_cylinder.cpp
.h files have a similar structure:
operator_ext_upml.h
operator_ext_tfsf.h
operator_ext_steadystate.h
operator_ext_mur_abc.h
operator_ext_lumpedRLC.h
operator_ext_lorentzmaterial.h
operator_ext_excitation.h
operator_ext_dispersive.h
operator_ext_cylinder.h
operator_ext_conductingsheet.h
operator_ext_absorbing_bc.h
engine_ext_upml.h
engine_ext_tfsf.h
engine_ext_steadystate.h
engine_ext_mur_abc.h
engine_ext_lumpedRLC.h
engine_ext_lorentzmaterial.h
engine_ext_excitation.h
engine_ext_dispersive.h
engine_ext_cylindermultigrid.h
engine_ext_cylinder.h
engine_ext_absorbing_bc.h
(3) Cython Overview
Quick Start:
Step 1. Install Cython lib with pip or conda.
Step 2. New a file named either filename.pyx or filename.py, according to the chosen mode (Cython or Python)
Step 3. Code in Python and Cython decorator. The following is an example calculating Fibonacci
- Pure Python
# This is a pure python code calculating fibonacci
# Filename: fibonacci.py
def fibonacci(n: int) -> int:
if n<= 1:
return n
a, b = 0, 1
for _ in range(2, n + 1):
a, b = b, a + b
return b
if __name__ == "__main__":
print("Pure Python Fibonacci(10):", fibonacci(n=10))
- Cython (.pyx)
# This is a cython code calculating fibonacci
# Filename: fibonacci_cython.pyx
cimport cython
@cython.cdivision(True)
def fibonacci_cython(int n):
cdef int i
if n <= 1:
return n
a, b = 0, 1
for i in range(2, n + 1):
temp = a + b
a = b
b = temp
- Python + Cython decorator (.py)
# This is a python code with cython decorator calculating fibonacci
# Filename: fibonacci_pure.py
import cython
@cython.locals(n=cython.int)
def fibonacci(n: int) -> int:
if n<= 1:
return n
a, b = 0, 1
for _ in range(2, n + 1):
a, b = b, a + b
return b
if __name__ == "__main__":
print("Pure Python Fibonacci(10):", fibonacci(n=10))
- Setup File
# This file compiles cython code into a c-extension
# Filename: setup.py
from setuptools import setup, Extension
from Cython.Build import cythonize
extensions = [
Extension(
name="fibonacci_cython",
sources=["fibonacci_cython.pyx"],
extra_compile_args=["-03"], # Maximal optimization of the C compiler
extra_link_args=["-03"],
),
Extension(
name="fibonacci_pure",
sources=["fibonacci_pure.py"],
extra_compile_args=["-03"], # Maximal optimization of the C compiler
extra_link_args=["-03"],
),
]
setup(
name="Test"
ext_modules=cythonize(
module_list=extensions,
compiler_directives={
'language_level': 3,
'boundscheck': False,
'wraparound': False,
'cdivision': True,
},
),
zip_safe=False,
install_requires=['cython']
)
Step 4. Execute python3 setup.py build_ext --inplace in the command line, which will create .pyd files for Windows (.os files for Linux and MacOS).
(4) Concept of SPICE-FDTD Co-simulation
(5) Task Checklist
- Review basic concepts of FDTD.
- Find a way to embed time-varying / NL lumped components into Yee cell.
- Build operator_ext_NLlumpedRLC.cpp, engine_ext_NLlumpedRLC.cpp (as well as .h).
- SPICE solver for nonlinear simulation capability.
- CMake and generate .dll
- Case study & Convergence test.
- Generalize to distributed NL media.
2. FDTD Review
(I) Intro: Yee Cell & Time Stepping
The curl part of the Maxwell equations
With finite-difference approximation (leap-frog), we can get the update equations
(2) Boundary Conditions
(3) Lumped Elements
(4) Probe & Measurement
Near Field to Far Field (NF2FF)
3. Manual & Smoke Test
(1) CAD Design
OpenEMS is powered by continuous structure XML CAD (CSXCAD), which is a C++ library for describing geometrical objects and their physical or non-physical properties. It contains either physical or non-physical API, including Geometry, Materials, Mesh, Excitation, Probes and Data Export.