Electromagnetic Simulation Laboratory

Name of the course Online Lecture Exercises Lab
Electromagnetic Simulation Lab

Self-paced programming laboratory for students with interest in electromagnetic simulation and a background in programming with C/C++ or CUDA. The course is a pure online laboratory without lectures. Presence is possible but not mandatory. Participants need some basic equipment to complete the course successfully, i.e. computer system with Ubuntu Linux and optionally if desired a graphics card that supports CUDA. The course material consists of a programming environment including a library with pre-compiled reference codes that allow students to verify their program results for correctness and run time. Students are provided with function prototypes to implement their program code.


Programming environment

Cuda-Version
2D/3D
CPU/GPU
scalar/vectorial
Version Archive
9.1
✓/✓
✓/✓
✓/✓
3.00 [.tgz]
CUDA 10.xx on Ubuntu 20.xx LTS has recently shown compile issues with options '-Ofast' and '-ffinite-math-only'. Please read the documentation below in case of problems.

The tar-archive in the table above provides a C/C++ programming environment for Ubuntu-Linux 16.04, 18.04 and 20.xx with CUDA version 9.x for nvcc and CUDA libraries to perform a self-paced programming laboratory. It allows students to implement 2D or 3D Fourier-based electromagnetic propagation methods for scalar or vector waves on a CPU or GPU. The environment compares the results against the results from reference codes and reports success if errors are below 0.1 per mil per spatial sample.

The tar-archive includes a pre-compiled library with reference codes for scalar and vector BPM and WPM on CPU and GPU. Student codes will be linked against this library and trainees run simulations from pre-defined adaptable configuration files to verify the results. The programming environment also reports on run-time and memory usage for CPU and GPU devices. Course participants can thereby implement the basic algorithms or improve code efficiency from advanced programming techniques, e.g. dynamic programming, multi-threading. Thereby, students select the appropriate algorithm, programming method and device as required for their level of expertise. This secures that participants work at the right level of complexity to master the course successfully.


How to install the environment?

Download and extract the tar achive.

$ tar xvfz UDPMLAB_Vx.xx.tgz

The host system needs support for fftw and gcc for CPU runs and nvcc for GPU runs. In case of GPU runs, the shared library libcufft7.5.so or libcufft9.1.so has to be available on the host system. LD_LIBRARY_PATH needs to be set properly to pick the libcufft shared library. libcufft is only needed if GPU runs shall be performed!


If libcufft is needed ...

$# this is just a comment
$ dpkg -i libcufft9.1_9.1.85-0ubuntu1_amd64.deb # install package
$ dpkg --contents libcufft9.1_9.1.85-0ubuntu1_amd64.deb # not needed but nice to know
$ dpkg -l # not needed but nice to know

If the cufft library is not available on your system and cannot be installed to the official system directory, get the library from the internet and extract it into a user subdirectory, e.g. the ./lib directory of the tar-archive. Then add the path to the environment variable LD_LIBRARY_PATH.

$# this is just a comment
$ dpkg -x libcufft9.1_9.1.85-0ubuntu1_amd64.deb ./lib # extract package to ./lib
$ export LD_LIBRARY_PATH =../lib:$LD_LIBRARY_PATH

Alternatively but maybe not the best choice due to side effects, redirect the installation to a local working directory.

$ dpkg -i --instdir=YOUR_DIR libcufft9.1_9.1.85-0ubuntu1_amd64.deb # install package to ./lib
$ find YOUR_DIR -name "*cufft*.so" -print # find LIBCUFFT_PATH to shared library
$ export LD_LIBRARY_PATH = LIBCUFFT_PATH:$LD_LIBRARY_PATH

The reference code in the package has been compiled with libcufft7.5 and libcufft9.1. If libcufft cannot be installed at all, user code will compile but errors will occur at runtime for GPU runs, i.e. option '-g'. CPU runs are not be affected. In this case, option '-g' cannot be applied.


If versions of nvcc and libcufft mismatch ...

In some rare cases, versions of nvcc and lubcufft does not match and linker errors occur, e.g. undefined reference to `cudaSetupArgument'. In such cases, versions of nvcc and libcufft need to be aligned.

./bin$ nvcc --version # Cuda compilation tools, release 9.1, V9.1.85
./bin$ ldd ./pm # libcufft.so.9.1 => /usr/lib/x86_64-linux-gnu/libcufft.so.9.1

Versions can be changed by the following procedure ... NVIDIA_CUDA_Toolkit_9_1_Ubuntu_20_04.txt.


Files in the programming environment

The programming environment consists of the following files

./README.md
Quick introduction and FAQ
lib_UDPM_V0.01.a
Pre-compiled static library with reference code and support functions.
Makefile
Makefile to compile the student code against the reference code.
your_pm.hh, your_pm.cc
Function prototypes for student CPU codes. Function prototypes are pre-defined for 2D or 3D and scalar or vector waves and cannot be modified.
your_kernel.hh, your_kernel.cc
Function prototypes for student GPU codes. Function prototypes are pre-defined for 2D or 3D and scalar or vector waves and cannot be modified.
./bin/pm
Executable


What options are supported?

The programming environment supports the following options.

./bin$ ./pm --help

prints the manpage.

How to implement and execute own code?

Write your code into your_pm.cc for CPU code and your_kernel.cu for GPU code. Then remake the executable and run your code

./bin$ cd ..
./$ make
./$ cd bin
./bin$./pm -p -c -t -i wguide.txt


How to invoke the simulator?

To start a simulation, you need to specify a configuration file. Such files are provided with the tar-archive for simple system configurations like for example a waveguide, i.e. wguide.cfg.

./pm -p -i wguide.cfg

and supports the following options To start a simulation on your CPU and compare against the CPU reference code, invoke the simulator as follows

./pm -p -c -i wguide.cfg

For more examples click here.

How to configure a simulation?

Global parameters are set in the global section and some parameters are only applicable to the GUI-version of the tool. The relevant parameters for the batch-version are

[global]
nx = 48
ny = 48
nz = 96
x = 4000
y = 4000
z = 8000
method = vwpm
scale = nm
evanescent = 1
[/global]

Define one or more electric input field distributions by one wave section per distribution. Configuration files are parsed line-by-line. Please do not specify more than one parameter per line.

Gaussian beam Plane wave User-defined

[wave]
shape = gauss
sigmax = 1250
sigmay = 1250
x = 0
y = 0
z = 0
theta = 0
phi = 0
beta = 0
amp = 1
lambda = 850
[/wave]

[wave]
shape = plane
x = 0
y = 0
z = 0
theta = 0
phi = 0
beta = 0
amp = 1
lambda = 850
[/wave]

[wave]
shape = user

...


[/wave]

User-defined wave-sections and
layer-sections are under work
and will be available soon.
Layer properties are defined by their real and imaginary parts of the refractive index. Secure that the sum of lengths match the definition in the global section.

Homogeneous medium Lens Waveguide Taper 2D Grating

[layer]
type = homog
z = 1000
n = 1.0
k = 0
[/layer]

[layer]
type = lens
x = 0
y = 0
z = 2000
r = -1800
n = 1.6
k = 0
ne = 1.0
ke = 0
dx = 0
dy = 0
dz = 0
[/layer]

[layer]
type = waveguide
x = 0
y = 0
z = 3000
r = 500
n = 1.6
k = 0
ne = 1.0
ke = 0
dx = 0
dy = 0
dz = 0
[/layer]

[layer]
type = taper
x = 0
y = 0
z = 11000
rin = 1000
rout = 200
n = 1.6
k = 0
ne = 1.0
ke = 0.0
dx = 0
dy = 0
dz = 0
[/layer]

[layer]
type = grating
x = 0
y = 0
z = 2000
px = 10000
py = 10000
wx = 5000
wy = 5000
n = 1.6
k = 0.03
ne = 1.0
ke = 0
dx = 0
dy = 0
dz = 0
[/layer]

User-defined layer-sections are under work and will be available soon. Simple configuration files can be found here.

How to analyze the energy flux?

All options in a section [flux] are only supported by Version 3.00 or higher and only for the VWPM, i.e. if 'method' in section [global] is assigned 'vwpm'. Open a flux section in the configuration file with [flux], define the parameters for flux analysis and close the section with [/flux]. The following parameters are supported:

[flux]
do_evanescent_like_propagating=0
do_theta_90 = 1
do_tolerance = 0
do_trim = 0
do_verbose = 0
do_skip_evanescent_modes_from_manual_override = 0
do_eflux_from_h = 0
do_limit_nyquist = 1
do_limit_modes = 0
modes = 20
do_mode_map_report = 0
do_mode_map_summary = 1
do_filter_field = 0
do_filter_system = 1
do_flux_report = 1
do_divd = 0
do_divd_report = 0
do_divd_summary = 1
do_spectrum_report = 0
do_spectrum_summary = 1
[/flux]


do_evanescent_like_propagating
Treats evanescent like propagating modes when set to 1 and applies a model (Josefowski 2007) for evanescent modes when set to 0. This is experimental code to show that evanescent modes cannot be treated like propagating modes.
do_theta_90
Applies a threshold window between 89.9 and 90.1 degrees for the evanescent boundary to avoid numeric instabilities from floating point arithmetics.
do_tolerance
Applies a TOLERANCE of 1E-9 on the input of a propagation step (spectrum) and assigns zero on values smaller than TOLERANCE.
do_trim
Applies a tolerance of 1E-6 on the output of a propagation step and assigns zero on values smaller than TOLERANCE.
do_verbose
Returns information in case of NaN values or in the first case when the energy flux does not hold the conservation law.
do_skip_evanescent_modes_from_manual_override
Skip the processing of evanescent modes by manual override. Works only if do_evanescent_like_propagating is assigned zero.
do_eflux_from_h
Derives the energy flux from the electric and magnetic field if set 1 and only from the electric field if set 0.
do_limit_nyquist
Applies a spatial Anti-Aliasing filter.
do_limit_modes
Manually limits the number of modes. To be used with option 'modes'. 'modes' carries the number of modes to be computed. All discrete angles between (excluding) the -10th and +10th mode will be computed if the number of modes is assigned 20.
do_mode_map_report
Creates a full mode map to indicate propagting, evanescent and skipped mode due to various reasons. Read the description in the report.
do_mode_map_summary
Creates a brief summary of various types of modes and shows the mode structure for every layer under investigation. Read the description in the report.
do_filter_field
Applies a spatial filter on the computed electric field of each iteration. The option is to be used with the options 'filter_type' (0=linear, 2=Gaussian), 'filter_sigma' (floating point value to be used with Gaussian filters), 'filter_nx' (x-size in the filter matrix), 'filter_ny' (y-size of the filter matrix)
do_filter_system
Applies a spatial filter on the refractive index distribution of the system before the simulation is started. The result is stored in N_preRun.csv and N_postRun.csv. The option is to be used with the options 'filter_type' (0=linear, 2=Gaussian), 'filter_sigma' (floating point value to be used with Gaussian filters), 'filter_nx' (x-size in the filter matrix), 'filter_ny' (y-size of the filter matrix)
do_flux_report
Creates a standard flux report with the energy flux per layer and other information.
do_divd
Applies a modified spatial frequency vector derived from the first Maxwell equation to consider lateral field dependencies due to refractive index gradients. This is experimental code and therefore can be switched off by setting this option to '0'
do_divd_summary
Creates a brief summary with infformation on the divergence of the electric displacement field D. This option can be used independent from the option 'do_divd'.
do_divd_report
Creates a full (and large) report on the divergence of the electric displacement field D at every position on the grid. This makes the report very large.
do_spectrum_report
Creates a full report on the spectrum amplitude at every position on the grid. This makes the report very large.

What is the output?

The simulation returns the electric field distribution of vector or scalar fields as a comma-separated list, i.e. .csv-files.
../bin$ N.csv
Refractive index of the electric vector field per node for the configured cross-section (option -x) and layer (option -l).
../bin$ EX.csv
X-component of the electric vector field per node for the configured cross-section (option -x) and layer (option -l).
../bin$ EY.csv
Y-component of the electric vector field per node for the configured cross-section (option -x) and layer (option -l).
../bin$ EZ.csv
Z-component of the electric vector field per node for the configured cross-section (option -x) and layer (option -l).
../bin$ E.csv
Amplitude of the electric scalar field per node for the configured cross-section (option -x) and layer (option -l).
../bin$ F.csv
Energy flux per node for the configured cross-section (option -x) and layer (option -l).
../bin$ FZ.csv
Accumulated energy flux per layer Z.
The outputs can be easily imported into other tools for analysis and coloring. The output can be also imported to the GUI-version of the tool. The GUI-version supports lots of other useful features to setup complex systems and analyze the electromagnetic field distribution, the energy flux and irradiance and more.