Published: Aug 1, 2025 by Liam Pattinson
Project info
ERMES is a Finite Element Method (FEM) solver for Maxwell’s equations with a wide range of applications. Developed originally at CIMNE (International Centre for Numerical Methods in Engineering), it has been successfully applied to problems in microwave engineering, bioelectromagnetics and electromagnetic compatibility. With the addition of electrostatic and cold plasma modules, it has found new applications in the design and analysis of tokamak fusion reactors, including the simulation of electric arcs and electromagnetic wave-plasma-wall interactions.
Working on ERMES was very different to most PlasmaFAIR projects. Rather than running as a command line application, ERMES is tightly coupled to GiD, a graphical program for geometrical modelling, pre-processing (setting source terms, solvers, meshing, etc), and post-processing (analysis and visualisation). The initial learning curve required to run the software was much greater than usual, and this coupling with an external piece of software placed significant restrictions on the sorts of packaging and testing solutions we could apply.
Being written in C++, the first step as always was to analyse the current build system and see if we could convert it to CMake. Starting from a Makefile that had been automatically generated from a CodeBlocks project file, it was fairly straightforward to write the CMake needed to compile the code. The difficulty came in two places:
- The project was split across multiple sub-projects in their own directories with numerous interdependencies, meaning it wasn’t possible to define a simple dependency graph.
- A mechanism had to be added to install the generated files into the correct locations relative to a user’s GiD installation. This took some trial and error to get right!
Tests were added using a combination of GoogleTest for unit testing and pytest for regression testing. With the CMake framework in place, it was easy to add a few example units tests to start the process, but regression testing was much more difficult due to the GiD integration and the nature of the problems that ERMES solves. Finding a minimum viable problem that could be solved quickly and accurately using finite element methods was challenging, and it was necessary to save a lot of opaque config files generated by GiD to the testing directory. In the end, a test based on microwave waveguides was created successfully, but another based on scattering from a spherical conductor had to be discarded due to the impracticality of solving the problem on an appropriate time scale.
There was already extensive documentation for ERMES in the form of a
LaTeX-based user guide, complete with many images demonstrating the graphical
user interface in GiD. I aimed to convert this to a set of HTML-based docs
using Sphinx, and thought using Pandoc would make the
.tex to .rst conversion simple – how wrong this was! While it was helpful
for a first pass, I found that every section heading, reference, figure, and
equation needed subtle tweaking before everything would work properly. Once
this was finished, it was relatively easy to add a framework for API docs using
Doxygen for in-source C++ documentation and Breathe to
bridge between Doxygen and Sphinx.
The final steps were to set up formatting and linting on the project using
clang-format and clang-tidy respectively. Both are highly
configurable, and with clang-format I aimed to find the settings that minimised
the changes over the whole project, achieving a consistent code style without
imposing any conventions that weren’t already broadly in use. Clang-tidy
revealed many linting errors, so here the aim was to start with a small set of
rules that would have the biggest impact – one of the most significant being
to ensure that library files were #include‘d in the right places rather than
relying on multi-file include chains.