(WIP) doc-src: add preliminary openEMS documentation#417
Conversation
The following draft documentation adds a new section to the openEMS documentation website called "concepts". It explains several important concepts of CSXCAD, openEMS and FDTD. This represents a small part of my month-long work made in 2025 on documenting openEMS. Currently this documentation is still incomplete, some parts contain known mistakes. To my best knowledge, I am aware of two mistakes and several limitations: 1. "primitives.rst" contains many broken Python syntax in the example code. 2. "ports.rst" does not correctly explain the use of transmission line ports, the given information is only correct for lumped port. 3. Post-processing is unexplained. This part needs to be "ported" from my parallel-plate waveguide tutorial. 4. No tutorial is given, my parallel-plate waveguide tutorial needs some rework. I plan to fix (1) and (2) in the upcoming days, and get these documents merged. The rest can be added in the future. "Some documents" is always better than "no document". Although it's still a work in progress, I believe this documentation draft already contains information not documented anywhere about the openEMS project. In particular, "signals.rst" explains the usage of all excitation waveforms, and "dispersive.rst" explains the mathematical formulation of Debye, Drude, Lorentz models, including comparison to other textbook formulations. Both are original work. Comments (other than repeating the known problems) are welcomed since I may have still missed something. Signed-off-by: Yifeng Li <tomli@tomli.me>
f7a62c7 to
4776a4c
Compare
thliebig
left a comment
There was a problem hiding this comment.
Comments for the first few files. This is going to take a while...
|
|
||
| PML is a more effective absorber and is easy to use, but it has the | ||
| highest computational overhead (especially in openEMS, due to suboptimal | ||
| implementation). Avoid it if efficiency is critical (e.g. only use |
There was a problem hiding this comment.
well "optimal" is a matter of perspective. The goal for openEMS was to implement an FDTD algorithm that is easy to maintain and easy to extend with new experimental features. It was never designed to be as fast as possible as that almost by definition negates the first two goals.
But in any case, the PML is the relative "slowest" BC even in the most advanced implementations, thus this comment is not helpful in any case?
There was a problem hiding this comment.
well "optimal" is a matter of perspective.
Yes, it's a matter of perspective. But the old project wiki also agreed that the PML implementation in its current form is suboptimal, I only repeated the old statement in the new documentation. I thought you wrote that page?
This ABC is not optimally implemented regarding the simulation speed. Use the Mur-ABC for faster simulations.
There was a problem hiding this comment.
Not sure if I wrote that or not. But in any case, it is as sub-optimal as any other extension. Since it tries to make use of the main engine operator maybe even less than others.
In any case, it is not interesting for the reader of the docu? Because if you need to use the PML you simply need to 😏
|
|
||
| On the other hand, although openEMS is also available as a shared library, | ||
| but its C++ APIs are presently intended only for use by the Python binding, | ||
| not public use. Breaking changes may occur at any time. Invoke openEMS as |
There was a problem hiding this comment.
No actually the API is intended to be usable by other tools and I do intend to be very careful about breaking changes...
|
|
||
| * :func:`export_empire`: | ||
|
|
||
| * For comparing simulation results with proprietary, commercial |
There was a problem hiding this comment.
I completely forgot about this exporter, I think I have to check if it still works. and maybe implement a python version too 😏
| Python | ||
| """"""" | ||
|
|
||
| Unfortunately, none of the functions above have been implemented in Python. |
There was a problem hiding this comment.
STL is available, everything else should be put on the list of missing python features
thliebig
left a comment
There was a problem hiding this comment.
Still not done, but only three *.rst to do...
@biergaizi please not that some comments may be hidden under the "Load diff"
|
|
||
| Several kinds of dump boxes exist. | ||
|
|
||
| #. Time-domain dumps of electric field :math:`\mathbf{E}`, auxiliary magnetic |
There was a problem hiding this comment.
why "auxiliary" magnetic field? It is as primary as the electric field, after all that is what "EM" stands for 😏
There was a problem hiding this comment.
why "auxiliary" magnetic field? It is as primary as the electric field
It's "auxiliary" in the sense that it's not as "fundamental" as the B field. It would be pretty confusing if H and B are both called the "magnetic field", but "H" doesn't really have its own name in English at all. Griffiths for example recommends people to just call it the "H field" without a name. The only name ever used in the literature is "auxiliary magnetic field", which was what I used.
It's the old engineering vs. physics debate on whether H or B should be the "real" magnetic field, and physics textbooks (such as Griffiths's E&M and Max Born's Optics) generally say "B" is real while "H" is a calculation tool to analyze macroscopic materials. But, I guess for our purpose of FDTD and openEMS, calling "H" as the magnetic field has a point here because it's what actually stored in computer's memory.
I think I'll just change them to "magnetic field B" and "magnetic field H", using words and letters at the same time sidesteps the whole argument.
There was a problem hiding this comment.
Interesting point, I'm not sure if this "debate" actually exists in Germany.
For me the magnetic field is H, and the magnetic flux density is B.
I think this wording should be the clearest?
There was a problem hiding this comment.
Also compare the first and second paragraph in this section of the MEEP documentation:
Meep simulates Maxwell's equations, which describe the interactions of electric (E) and magnetic (H) fields
where D is the displacement field, ε is the dielectric constant, J is the current density (of electric charge), and JB is the magnetic-charge current density. Magnetic currents are a convenient computational fiction in some situations. B is the magnetic flux density (often called the magnetic field), μ is the magnetic permeability, and H is the magnetic field.
| #. Near-Field to Far-Field Transformation (NF2FF) for antenna analysis | ||
| (special setup required, via :meth:`openEMS.openEMS.CreateNF2FFBox` and a | ||
| separate post-processing tool). | ||
|
|
There was a problem hiding this comment.
- I think a reference to the different file types are missing? But at the same time the methods have an good documentation themself?
- Additionally for frequency dumps the recording frequencies must be specified.
- There could be made a point here that time-domain dumps are much more storage and file access effort and thus can not only produce very large files, but also slow down the simulation a lot. If you now the desired frequencies at the start, you should always use the FD dump instead (unless many frequencies are of interest)
| cells with different sizes around the edge, creating a non-uniform | ||
| rectilinear mesh with variable spacing. Around the metal edge, the metal |
There was a problem hiding this comment.
Thats not correct, the mesh can be uniform as long as the "edge cells" obay the 1/3-2/3 rule...
This just requires a very special cell width to make this happen...
There was a problem hiding this comment.
I meant to write
openEMS supports a rectilinear mesh with variable spacing, not use.
|
|
||
| 2. Only the electric field is known at an exact timestep, the magnetic field | ||
| is known with a half-timestep offset (``t + 0.5``). This error is always | ||
| neglected. |
There was a problem hiding this comment.
This error is always neglected.
Why is this an error? And it is never neglected. Wherever e.g. voltages and currents are analyzed the correct times are used, Otherwise phase errors would always be a major issue.
There was a problem hiding this comment.
Do you mean that if you create an E-field dump box and an H-field dump box, both E and H fields are also interpolated to the "correct" time?
There was a problem hiding this comment.
There is no correct time? Both fields are recorded with their respective time and always has to be taken care of properly. Putting E- and H-fields in a direct relationship in time-domain is difficult and should be avoided I guess.
There was a problem hiding this comment.
This is consistent with my own understanding, the field dump of E and H are off by a half-timestep, the openEMS engine does not auto-interpolate two H fields at H(t - 0.5), H(t + 0.5) to approximate H(t) - it's impossible even if someone wants to, because the engine only saves one copy of the field at the latest timestep, there's no double buffering.
This is why I said: "this error is always neglected", I meant it's neglected in openEMS engine's probes and field dumps.
I propose the following wording to clarify the issues.
Only the electric field is known at an exact timestep, the magnetic field is known with a half-timestep offset (
t + 0.5). When probing both voltages and currents, or dumping both electric and magnetic fields, users must explicitly take this simulation artifact into account. Since temporal interpolation is unsupported, analyzing both physical quantities at the same timestep is difficult, and best be avoided without a strong FDTD background.
There was a problem hiding this comment.
We could add that this only affects the fields in time-domain? None of this issue arise if you are looking (at the more common?) frequency domain.
| into the simulation, helping establish initial conditions for the system. | ||
| Simultaneously, a lumped resistor and a probe are also created at the | ||
| same location as the port, allowing it to provide a matched load for the | ||
| signal, or to measure the voltage or current at this region. |
There was a problem hiding this comment.
voltage and current. I think I know no port that only wants one of them
| These waveguides only have one conductor, unlike the usual two-conductor | ||
| transmission lines. An ordinary port can't excite them correctly, | ||
| as the waveguide is essentially a DC short circuit. Special waveguide | ||
| ports must be used to excite the unique TE-mode waves. These include |
There was a problem hiding this comment.
Although I'm not sure TM is really implemented at all?
There was a problem hiding this comment.
In the earliest draft I wrote "TE or TM", and I later deleted "TM" after I noticed that only the E-field excitation was implemented in AddWaveGuidePort.m.
CSX = AddExcitation( CSX, exc_name, 0, e_vec, varargin{:});
CSX = SetExcitationWeight(CSX, exc_name, E_WG_func );
CSX = AddBox( CSX, exc_name, prio, e_start, e_stop);
| :func:`CalcLorentzMaterial`, no workaround is available. These | ||
| Octave functions are helper functions that calculate the model's | ||
| output curves for the purpose of fitting parameters and preparing | ||
| a simulation. No C++ APIs exist because they're not actually used | ||
| in the simulation. |
There was a problem hiding this comment.
This should be really good test case for modern LLM's ? Feed them the Octave code and ask to transfer to python? I think this would be worth a shot?
There was a problem hiding this comment.
Yes, I believe this problem is easy for LLMs to solve, it's just a plain language translation and it's hard to get it wrong. Copyright issue is also non-existent, it's derived from our own code (and code itself is from physics formulas, not copyrightable anyway). Perhaps I will try translating a function myself, and later comparing it with different LLMs. the LLMs are possibly more readable than my code. LLMs memorized all Python idioms, helper functions and syntactic sugars. I wrote Python for 10 years but I can't memorize all.
However, using LLMs to generate code opens up the question of determining the project's LLM usage policy, which is tricky and controversial. For example, at the OCaml project, recently there was a prominent incident, a first-time contributor opened a Pull Request with 13k lines of LLM-generated code, delegating the review to the project maintainer. Although it was the most extreme incident, it was not the only one. So if we say "auto-generating contributions with LLMs will be accepted", there's a non-zero risk that you'll soon receive a flood of mixed-quality code to review...
For full disclosure, this documentation patch itself is also 10000 line-long, and I did use LLM in this tutorial, but only to flag writing problems, not for authoring it, I wrote everything on a Model M in a plain Vim window. Otherwise it won't take months - and none of my previous patches or forum posts were auto-generated (and I doubt LLMs can debug arcane build issues such as "Homebrew shipped a broken Python standard library on macOS", but perhaps I underestimate them).
There was a problem hiding this comment.
Well this is a valid point about the policy. I think my current personal policy is, if an LLM is used e.g. to translate some function, but the author of that code than does a good review and testing of that code and is open about the whole process in the PR, this should be okay?? But I guess we should have a look at what LLM usage policy we want to adopt at some point (soon)...
There was a problem hiding this comment.
but the author of that code than does a good review and testing of that code and is open about the whole process in the PR, this should be okay?
I think it's a reasonable policy.
|
Missing Python features are now documented in the Development section in Also, some documents can be difficult to check in the source form, you can use the preview provided by ReadTheDocs, such as the formula-heavy note on dispersive materials: https://openems--417.org.readthedocs.build/en/417/concepts/dispersive.html |
|
Update: Changed all silly mentions of "first-order model" in |
|
Update: Added 5 new sections on post-processing simulation S-parameter results:
Again, these sections are copied and pasted from my Parallel Plate Waveguide tutorial, some paragraphs need serious rewrites, otherwise it doesn't make sense due to lack of context. For example, currently the tutorial doesn't say anything about where the S-parameters come from. Still, early comments unrelated to these issues are appreciated. |
thliebig
left a comment
There was a problem hiding this comment.
Some comments on your comments
|
|
||
| PML is a more effective absorber and is easy to use, but it has the | ||
| highest computational overhead (especially in openEMS, due to suboptimal | ||
| implementation). Avoid it if efficiency is critical (e.g. only use |
There was a problem hiding this comment.
Not sure if I wrote that or not. But in any case, it is as sub-optimal as any other extension. Since it tries to make use of the main engine operator maybe even less than others.
In any case, it is not interesting for the reader of the docu? Because if you need to use the PML you simply need to 😏
|
|
||
| Several kinds of dump boxes exist. | ||
|
|
||
| #. Time-domain dumps of electric field :math:`\mathbf{E}`, auxiliary magnetic |
There was a problem hiding this comment.
Interesting point, I'm not sure if this "debate" actually exists in Germany.
For me the magnetic field is H, and the magnetic flux density is B.
I think this wording should be the clearest?
|
|
||
| 2. Only the electric field is known at an exact timestep, the magnetic field | ||
| is known with a half-timestep offset (``t + 0.5``). This error is always | ||
| neglected. |
There was a problem hiding this comment.
There is no correct time? Both fields are recorded with their respective time and always has to be taken care of properly. Putting E- and H-fields in a direct relationship in time-domain is difficult and should be avoided I guess.
| These waveguides only have one conductor, unlike the usual two-conductor | ||
| transmission lines. An ordinary port can't excite them correctly, | ||
| as the waveguide is essentially a DC short circuit. Special waveguide | ||
| ports must be used to excite the unique TE-mode waves. These include |
| :func:`CalcLorentzMaterial`, no workaround is available. These | ||
| Octave functions are helper functions that calculate the model's | ||
| output curves for the purpose of fitting parameters and preparing | ||
| a simulation. No C++ APIs exist because they're not actually used | ||
| in the simulation. |
There was a problem hiding this comment.
Well this is a valid point about the policy. I think my current personal policy is, if an LLM is used e.g. to translate some function, but the author of that code than does a good review and testing of that code and is open about the whole process in the PR, this should be okay?? But I guess we should have a look at what LLM usage policy we want to adopt at some point (soon)...
|
I don't know know how to create a link here, but the image for extruded polygons is wrong. This shows the image for rotated polygons. https://openems--417.org.readthedocs.build/en/417/concepts/primitives.html |
Signed-off-by: Yifeng Li <tomli@tomli.me>
|
@VolkerMuehlhaus Fixed. |
Signed-off-by: Yifeng Li <tomli@tomli.me>
6a6f728 to
69324fe
Compare
Signed-off-by: Yifeng Li <tomli@tomli.me>
WIP, do not merge, but comments welcomed
The following draft documentation adds a new section to the openEMS documentation website called "concepts". It explains several important concepts of CSXCAD, openEMS and FDTD. This represents a small part of my month-long work made in 2025 on documenting openEMS.
Currently this documentation is still incomplete, some parts contain known mistakes. To my best knowledge, I am aware of two mistakes and several limitations:
"primitives.rst" contains many broken Python syntax in the example code - All fixed!
"ports.rst" does not correctly explain the use of transmission line ports, the given information is only correct for lumped port.
Post-processing is unexplained. This part needs to be "ported" from my parallel-plate waveguide tutorial.
No tutorial is given, my parallel-plate waveguide tutorial needs some rework.
I plan to fix (1) and (2) in the upcoming days, and get these documents merged. The rest can be added in the future. "Some documents" is always better than "no document".
Although it's still a work in progress, I believe this documentation draft already contains information not documented anywhere about the openEMS project. In particular, "signals.rst" explains the usage of all excitation waveforms, and "dispersive.rst" explains the mathematical formulation of Debye, Drude, Lorentz models, including comparison to other textbook formulations. Both are original work.
Comments (other than repeating the known problems) are welcomed since I may have still missed something.