openEMS Changelog
Notable, user-visible changes in openEMS. The format follows
Keep a Changelog; versions follow
0.MINOR.PATCH.
The rendered version of this file, together with the CSXCAD changelog, is part of the openEMS documentation.
When you change something user-visible, add a bullet under Unreleased in the
same commit, creating that section if it is not there — it exists only while
there are unreleased changes. It becomes the next release entry.
Unreleased
The version scheme changed with this release: the previous release was v0.0.36,
this one is v0.37.0. The leading 0.0. was never going anywhere, so the minor
number moved up and patch releases now have somewhere to go.
Added
SAR calculation reworked, following IEEE/IEC 62704-1: averaging is done once for all frequencies instead of per frequency, and is multi-threaded, together giving a large speedup. The new
--autorangeoption restricts the calculation to the cells near the peak, a further speedup that does not guarantee finding the global peak. Available from Python (sar_calculation) and from Octave (CalcSAR.m, withautoRange,numThreadsandprogress), with a new SAR averaging tutorial.Waveguide mode excitation and probe from an HDF5 mode file, complementing the analytic mode functions.
WaveguidePort/RectWGPortaccept amode_fileargument, theAdd*WaveGuidePortmethods accept alocal_origin, andmatlab/h5writemode.m(with an Octave oct-file) writes the mode files. Requires the matching CSXCAD support.New Python port classes:
CircWGPort,CoaxialPort,StripLinePort,CPWPortandCurvePort, with matchingAdd*Portconvenience methods on theopenEMSclass following the existingAddLumpedPort/AddMSLPortpattern, plus acheck_mode_purity()utility. Ports also store their time base, which makes plotting easier.CreateNF2FFBox()(Python) acceptsdirectionsandmirror, which overrule the settings derived from the boundary conditions, e.g. to leave the face an antenna feed passes through out of the Huygens surface.DelayFidelity()(Python), the time delay from the source port to the antenna phase centre and the fidelity of the radiated pulse, for any polarisation via complex weights on E_theta and E_phi.Localized Mur and SA-Mur absorbers as stand-alone engine extensions, so an absorbing boundary can be placed inside the simulation domain rather than only at its edge.
Lumped RLC elements: series and parallel R/L/C, implemented with an auxiliary differential equation.
HDF5Dump(Python) for reading field dumps: a dump can be inspected before any field data is read,SetPlane/SetLine/SetRange/SetSamplingpush the selection down into HDF5 so only the requested part is read, andGetFieldAtFrequency()runs an on-the-fly DFT so time-domain and frequency-domain dumps are post-processed the same way.SetLibraryArguments(), which accepts almost every option of theopenEMSexecutable as a string. The Python binding uses it, so engine selection and the debugging options are now reachable from Python.Graceful abort on Ctrl-C. SIGINT is handled explicitly, so a run can be stopped and its data written out instead of being killed. This also restores Ctrl-C when openEMS runs as a Python module, where it previously did nothing.
FDTD setup and the CSX structure can be read from and written to XML.
The FDTD object can be reset from Python, and an excitation can be enabled and disabled.
Bundled head and body phantoms in
resources/phantoms/, reachable from every language interface, installed toshare/openEMS/and shipped inside the python wheel.openEMS_resource_path()(Octave) andopenEMS.utilities.get_resource_path()(Python) return the path of such a file, so a tutorial keeps working from wherever it was copied to. The MRI tutorials fall back to the phantoms when the IT’IS Virtual Family dataset is not installed.New tutorials and examples: Python
Horn_Antenna(coaxial pin feed with backshort),StripLine2MSL,Dipole_SAR,MRI_Loop_Coil, a rectangular resonant cavity example, and a SAR averaging tutorial. Ported from Octave:Parallel_Plate_Waveguide,Circ_Waveguide,Conical_Horn_Antenna,CylindricalWave_CCandRadarUWBTutorial.Python unit and integration tests, run in CI after each smoke test.
Optional oversampling for frequency-domain dumps and probes, to avoid the aliasing onto the upper band edge that sampling the DFT accumulation at exactly the Nyquist rate causes. A box opts in through CSXCAD’s new
OverSamplingproperty; the default is unchanged, so existing simulations and their performance are unaffected.--verbose/-vvnow reports the actual TD/FD sampling interval for each probe and dump box duringSetupProcessing.--exact-endcriteria, which evaluates the energy end-criteria every Nyquist period instead of every few seconds of wall-clock time. The run then stops at the same timestep regardless of machine speed and load, at the cost of performance — mainly useful for engine or code verification.
Changed
The MPI engine was removed. It had not compiled for years, as it used the C++ MPI bindings that MPI-3 dropped, it had no tests, and several extensions never supported it (#260). The multithreaded engine is unaffected.
WITH_MPI,--engine=MPI,openEMS_MPI.sh,RunOpenEMS_MPIandSetupMPIare gone. See Upgrade notes.nf2ff result format. The far field is written as one compound complex dataset per frequency,
/nf2ff/E_theta/FD/f{n}in (theta, phi) order — the format every other frequency-domain dump has used since HDF5 version 0.3 — instead of a splitf{n}_real/f{n}_imagpair in (phi, theta) order. Octave cannot read compound complex datasets, so the Octave/Matlab interface keeps the old layout, requested byCalcNF2FFthrough the newLegacyHDF5attribute of the nf2ff XML file. See Upgrade notes.Simulation directory cleanup no longer deletes the directory.
CleanupSimPath()(Octave/Matlab) andcleanup=Truein Python’sFDTD.Run()now remove only known openEMS output files. PointingSim_Pathat$HOME, or any other directory that matters, no longer destroys its contents. Generic*.h5files are only removed when they carry theopenEMS_HDF5_versionroot attribute, so user-supplied HDF5 files such as mode files survive.Command-line argument parsing was rewritten. Options are declared by the module that uses them rather than in
openems.cpp, which is what makesSetLibraryArguments()possible.The Gaussian excitation now ends at exactly zero, and the excitation types were renamed more descriptively.
Frequency-domain dump files get more readable names, and HDF5 dumps carry more metadata attributes.
boost/program_options.hppwas removed from the publicopenems.h.The
INVALIDlumped-element type was removed, following the same change in CSXCAD.Octave/Matlab docstrings were reformatted as Markdown so that the online function reference can be generated from them.
Python packaging modernised:
pyproject.toml, installable withpip, dynamic versioning viasetuptools_scm, and more robust detection of an installed CSXCAD.Internally, the multi-dimensional field arrays were replaced by a new
ArrayLib, and the engine, operator and their extensions converted to it.Default thread counts (multithreaded engine, nf2ff, SAR) now respect CPU affinity and cgroup CPU quotas (Linux only) instead of always using every CPU of the host, so a container or systemd unit with a CPU limit no longer oversubscribes it.
Fixed
DebyeMaterialdiverged oncesum(eps_delta)approachedepsilon, and did so silently – the NaN energy satisfied the end criteria, so the run reported a normal finish. Its branch carries no inductance, so integrating it like the Drude/Lorentz branch put the update’s root on -1. It now integrates the pole’s capacitor voltage, in its own extension pair;eps_deltais no longer limited, and a pole shorter than three timesteps is refused with a warning (#229).Python: a
ContinuousStructurehanded toSetCSX()is no longer destroyed twice.SetCSX()takes ownership, which the binding now states, andGetCSX()no longer leaks a fresh structure per call. Requires a CSXCAD providingCSObject. See Upgrade notes.Python:
GetCSX()returned an empty list after the structure had been read withReadFromXML(), and a wrapper could dangle afterReset().UPML: copy-paste errors in the update coefficients (#221).
Tutorial
CRLH_LeakyWaveAnt.m: the ground plane was added at the same priority as the substrate that spans z=0 as well, so it lost the tie and never made it into the operator.Modes higher than 0 in the parallel-plate direction were not excited correctly.
The mode-match probe coordinates now match the excitation coordinates.
nf2ff:
m_maxDirwas wrong for a radius other than 1.A steady-state engine extension could be freed twice on shutdown, and an operator extension that was never initialised could be freed invalidly. An extension that finds nothing to do — a conducting sheet without a primitive, for example — is now dropped instead of being kept and run empty.
Dmaxis a linear power quantity and was added to a dB value without conversion in the patch-antenna tutorials.Lumped RLC: the auxiliary-differential-equation update had several bugs, and
C = 0was not handled.Python:
Run()failed on a relativesim_path, and on one containing symlinks, with an assertion; both work now.Octave: an oct-file left over from an older Octave version is rebuilt instead of failing the run with “failed to load” or, on Windows, “the specified module could not be found” (#318).
Octave/Matlab: paths containing spaces are quoted for the binary and the log file, and HDF5 detection in
setup.mwas improved and is now tested in CI.Python:
SetCustomExciteencoding, and argument parsing with severalopenEMS()instances in one process.The excitation amplitude was ignored by
AddCoaxialPort('ExciteAmp') in Octave/Matlab and by the waveguide ports (excite) in Python: any non-zero value excited with amplitude 1.Python: a port with the number of an existing port now raises
ValueError. Both ports wrote their probes to the same files and corrupted them. Octave/Matlab already rejected this.Octave:
plotRefldied with “vertical dimensions mismatch” instead of drawing the Smith chart, because it added the trace after the legend and Octave’s legend autoupdate could not append it (#172).B-field dumps (
DumpType5/15) were not placed on the dual time/mesh like H-field dumps, despite reading the same dual-grid values: values were labelled half a cell and half a timestep off.Six of the nine steady-state detection probes sat on the first mesh line of their direction (usually a field-free boundary) instead of a quarter/three quarters across, due to an integer-division bug.
Build
C++11 is now required, and CMake 3.1 or newer.
VTK 9 and newer are supported without deprecated names.
Windows: builds via vcpkg manifest with MSVC and clang-cl under Visual Studio 2022; the
openEMSandnf2ffimport libraries are installed tolib/.Builds on ppc64le.
Two knobs for comparing the output of two builds bit by bit, both off the default path: debug builds compile with
-ffp-contract=offon GCC and Clang, and the newENABLE_FLUSH_TO_ZEROCMake option can be set toOFFto keep denormals in the engines.The
WITH_MPICMake option and the--with-MPIoption ofupdate_openEMS.shwere removed.CI covers Linux, macOS, FreeBSD and Windows, and compiles with warnings enabled.
Upgrade notes
Rebuild all components together. The CSXCAD
CSObjectchange alters the layout of every class deriving from it. The soname is unchanged and will not catch a partial rebuild. This release needs a CSXCAD that providesCSObject.A Python script that used a CSXCAD wrapper after its C++ object had been destroyed now stops with a
RuntimeErrorinstead of reading freed memory.Scripts that relied on
cleanupwiping the whole simulation directory now keep any file that is not recognised openEMS output. This is deliberate.The bundled phantoms moved from
matlab/Tutorials/phantoms/toresources/phantoms/, installed undershare/openEMS/.A tool that reads nf2ff result files directly has to handle the compound complex datasets described above;
nf2ff_results(Python) andReadNF2FF(Matlab) read both formats,ReadNF2FFunder Octave only the legacy one. Files written by the Octave/Matlab interface are unchanged.Octave/Matlab scripts calling
SetupMPIfail, as the function is gone; drop the call.RunOpenEMSwarns about aSettings.MPIfield and runs the multithreaded engine instead.
Older releases
Releases v0.0.32 (2013-11-27) through v0.0.36 (2023-10-22) were not recorded
here. See the commit history
or compare two tags, for example
v0.0.35...v0.0.36.
The entries below are the original NEWS file, kept verbatim.
v0.0.31
nf2ff: calculate circular polarization
improvements to calcPort
allow 1D and 2D lumped ports
improvements to SAR calculations
curve primitives and port fixes & improvements
FDTD operator now supports different material averaging methods
support for full multi-polar Lorentz/Drude/Debye dispersive material types
new ports for waveguides (rectangular and circular waveguides)
improved PEC debugging
improvements/simplifications in plotting far-fields (thanks to Stefan)
new tutorials and examples
many fixes and updates
v0.0.30
meshing improved with new detect edges and new smoothing capabilities
new calcPort function for simplified port analysis
cylindrical mesh improvement by considering 360° rotation symmetry
support for harminv on all platforms
update to auto-regressive model for voltage/current probes
new SAR calculation options, incl. 1g/10g averaging
support for a new primitive: polyhedron
CAD import: STL/PLY surface solids supported (matlab: ImportSTL / ImportPLY)
CAD export: STL/PLY export (using AppCSXCAD)
lot of minor fixes and updates
v0.0.29
Cylindrical sub-grids now fully support alpha-graded meshes
Property Electrode has been renamed to Excitation This doesn’t have any effect on the Matlab/Octave interface, but old *.xml files cannot be run with a current openEMS/CSXCAD version.
Overall memory usage reduced during pre-processing
New excitation: Total-field/scattered field (TFSF)
New tutorial on radar cross section on a metallic sphere using the TFSF excitation
official support for 64-bit windows version
check for engine extensions MPI compatibility
CSXCAD: support for new CSXGeomPlot export options (see help for more infos)