Package: pymininec
Author:Ralf Schlatterbeck <rsc@runtux.com>This is an attempt to rewrite the original MININEC3 basic sources in
Python. Standard use-case like computation of feed impedance and far
field are implemented and are quite well tested. There is only a command
line interface.An example of using the command-line interface uses the following
12-element Yagi/Uda antenna originally presented by Cebik[6]without
the resistive element loading and with slight corrections to the element
lengths to make the antenna symmetric (the errors in the display in
Cebik’s article may be due to a display issue of the program used that
displays negative numbers with less accuracy than positive numbers).
You can get further help by callingpymininecwith the--helpoption.  The command-line options for the 12-element antenna example
(also available in the filetest/12-el.pym) are:pymininec -f 148 \
-w 22,-.51943,0.00000,0,.51943,0.00000,0,.00238 \
-w 22,-.50165,0.22331,0,.50165,0.22331,0,.00238 \
-w 22,-.46991,0.34215,0,.46991,0.34215,0,.00238 \
-w 22,-.46136,0.64461,0,.46136,0.64461,0,.00238 \
-w 22,-.46224,1.03434,0,.46224,1.03434,0,.00238 \
-w 22,-.45989,1.55909,0,.45989,1.55909,0,.00238 \
-w 22,-.44704,2.19682,0,.44704,2.19682,0,.00238 \
-w 22,-.43561,2.94640,0,.43561,2.94640,0,.00238 \
-w 22,-.42672,3.72364,0,.42672,3.72364,0,.00238 \
-w 22,-.41783,4.53136,0,.41783,4.53136,0,.00238 \
-w 22,-.40894,5.33400,0,.40894,5.33400,0,.00238 \
-w 22,-.39624,6.0452,0,.39624,6.0452,0,.00238 \
--theta=0,5,37 --phi=0,5,73 \
--excitation-segment=33 > 12-el.poutUsers on Linux can run this using (I’m sure Windows users can come up
with a similar command-line on Windows):pymininec $(sed '/^#/d' test/12-el.pym) > 12-el.poutThis removes comments from the.pymfile and passes the result as
command-line parameters to pymininec.
The resulting output file contains currents, impedance at the feedpoint
and antenna far field in dBi as tables. The output tries to reproduce
the format of the original Basic implementation of Mininec.PlottingThe output tables produced bypymininecare not very useful to get an idea of the far field behaviour of
an antenna. The companion programplot-antennaused to be bundled
withpymininecbut was moved to its own project. You can currently
plot elevation and azimuth diagram of an antenna, a 3D-plot, the
geometry and VSWR. All either as a standalone program (using matplotlib)
or exported as HTML to the browser (using plotly).Ground (Media)The latest version implements the option parsing for the mininec ground
model for more than one medium. You also need to specify the--boundaryoption to set the type of boundary between media: The
defaultlinearboundary appends grounds in X-direction with the
distance in the 4th parameter of the--mediumoption. Thecircularboundary has concentric media with the radius of each
medium given in the 4th parameter of the--mediumoption. The third
parameter of the--mediumoption is the height. Note that you
typically wantnegativeheights for media further out, this allows
modelling of summits. Mininecallowsthe specification ofhighergrounds but the results will be questionable as no reflection at the
higher ground is modelled. The ground implementation was not yet tested
against the originally basic code (or any other modelling program
implementing the mininec engine).Test coverage: Making sure it is consistent with original MininecThere are several tests against theoriginal Basic source code, for
the test cases see the subdirectorytest. One of the test cases is
a simple 7MHz wire dipole with half the wavelength and 10 segments.
In one case the wire is 0.01m (1cm) thick, we use such a thick wire to
make the mininec code work harder because it cannot use the thin wire
assumptions. Another test is for the thin wire case. Also added are the
inverted-L and the T antenna from the original Mininec reports. All
these may also serve as examples.  Tests statement coverage is currently
at 100%.There is a line that is flagged as not covered by thepytestframework if the Python version is below 3.10. This is acontinuestatement incompute_impedance_matrixnear the end (as of this
writing line 1388). This is a bug in Python in versions below 3.10:
When setting a breakpoint in the python debugger on the continue
statement, the breakpoint is never reached although the continue
statement is correctly executed. A workaround would be to put a dummy
assignment before the continue statement and verify the test coverage
now reports the continue statement as covered.
I’vereported this as a bug in the pytest projectandas a bug in
python, the bugs are closed now because Python3.9 does no longer get
maintenance.For all the test examples it was carefully verified that the results are
close to the original results in Basic (seeRunning examples in Basicto see how you can run the original Basic code in the 21th century). The
differences are due to rounding errors in the single precision
implementation in Basic compared to a double precision implementation in
Python. I’m using numeric code fromnumpywhere possible to speed up
computation, e.g. solving the impedance matrix is done usingnumpy.linalg.solveinstead of a line-by-line translation from Basic.
You can verify the differences yourself. In thetestdirectory there
are input files with extension.miniwhich are intended (after
conversion to carriage-return convention) to be used as input to the
original Basic code. The output of the Basic code is in files with the
extension.boutwhile the output of the Python code is in files
with the extension.pout. The.poutfiles are compared in the
regression tests. The.pymfiles in thetestdirectory are the
command-line arguments to recreate the.poutfiles withmininec.py.In his thesis[5], Zeineddin investigates numerical instabilities when
comparing near and far field. He solves this by doing certain
computations for the near field in double precision arithmetics.
I’ve tried to replicate these experiments and the numerical
instabilities are reproduceable in the Basic version. In the Python
version the instabilities are not present (because everything is in
double precision). But the absolute field values computed in Python are
lower than the ones reported by Zeineddin (and the Basic codedoesreproduce Zeineddins values).It doesn’t look like there is a problem in the computations of the
currents in the Python code, the computed currents are lower than in
Basic which leads to lower field values. But the computed impedance
matrix when comparing both versions has very low error, see the testtest_matrix_fill_ohio_exampleintest/test_mininec.pyand the
routineplot_z_errorsto plot the errors (in percent) intest/ohio.py. Compared to the values computed by NEC[5], the Basic
code produces slightly higher values for near and far field while the
Python code produces slightly lower values than NEC. I’ve not tried to
simulate this myself in NEC yet.You can find the files intest/ohio*(the thesis was at Ohio University). This time there is a
python scriptohio.pyto compute the near and far field values
without recomputing the impedance matrix. This script can show the near
and far field values in a plot and the difference in a second plot.
There are two distances for which these are computed, so the code
produces four plots. There is a second script to plot the Basic near and
far field differencesplot_bas_ohio.py.The current Python code is still hard to understand – it’s the
result of a line-by-line translation from Basic, especially where I
didn’t (yet) understand the intention of the code. The same holds for
Variable names which might not (yet) reflect the intention of the code.
Ididmove things like computation of the angle of a complex number,
or the computation of the absolute value, or multiplication/division of
complex numbers to the corresponding complex arithmetic in python where
I detected the pattern.So thede-spaghettificationwas not successful in some parts of the
code yet :-) My notes from the reverse-engineering can be found in the
filebasic-notes.txtwhich has explanations of some of the variables
used in mininec and some sub routines with descriptions (mostly taken
fromREMstatements) of the Basic code.The code is also still quite slow: An example of a 12 element Yagi/Uda
antenna used in modeling examples by Cebik[6]takes about 50 seconds
on my PC (this has 264 segments, more than the original Mininec ever
supported) when I’m using 5 degree increments for theta and phi angles
and about 11 minutes (!) for 1 degree angles. The reason is that
everything currently is implemented (like in Basic) as nested loops.
This could (and should) be changed to use vector and matrix operations
innumpy. In the inner loop of the matrix fill operation there are
several integrals computed usinggaussian quadratureor a numeric
solution to anelliptic integral. These are now implemented using
methods (or at least constants in the case ofgaussian quadrature)
fromscipy.integrateandscipy.special.ellipk.Multiple Inverted-V ExampleAn oldweb-page from 1998 by Dr. Carol F. Milazzo, KP4MDhas examples
of antennas simulated with Mininec. The first of these examples is three
crossed inverted-V (one of which has loading inductors to boost the
effective length). The simulation results of pymininec are in the
ballpark of the Mininec-basedNEC4WINwhich was used by KP4MD. But it
looks likeNEC4WINmight use what it prints as “Diam.” as the radius
of the wire (see Fig. 1 in the website) as the radius (see Antenna Model
Files in the Appendix). At least if this format is inherited from NEC
the last column of the wire definition would hold the radius and this
interpretation of the format also is more consistent with the simulation
results of Pymininec. The following table shows the original data
compared to using half of the diameter in the original model in
Pymininec (“Pymininec r”) and the diameter as the radius (Pymininec 2r).
When using the (supposed) diameter for the radius, the output data
matches better to the website data.FrequencyOriginalPymininec rPymininec 2r7MHzGain Azimuth-2.42 dBi-2.52 dBi-2.49 dBiGain Elevation7.21 dBi7.21 dBi7.21 dBiImpedance38.74 +6.77j38.82 -3.66j39.28 +1.49j14MHzGain Azimuth4.33 dBi4.60 dBi4.37 dBiGain Elevation7.23 dBi7.73 dBi7.38 dBiImpedance46.16 -326j31.86 -307j43.00 -313jAll of KP4MD’s examples have been converted to Pymininec and are available asinve802B.pym,hloop40-14.pym,hloop40-7.pym,vloop20.pym, andlzh20.pymin thetestdirectory. Only theinve802B.pym(with the inverted-Vs) uses the diameter in the
original example as the radius in Pymininec, all others use half of the
value in the original example (which is supposed to be the diameter) as
the radius. But most examples match better to the values computed by
KP4MD when doubling the radius.Running the TestsYou can run the tests with:python3 -m pytest testIf coverage should be reported this becomes:python3 -m pytest --cov mininec testFor a more detailed coverage report use:python3 -m pytest --cov-report term-missing --cov mininec testThis will show a detailed report of the lines that are not covered by
tests.Notes on Elliptic Integral ParametersThe Mininec code uses the implementation of anelliptic integralwhen
computing the impedance matrix and in several other places. The integral
uses a set of E-vector coefficients that are cited differently in
different places. In the latest version of the open source Basic code
these parameters are in lines 1510–1512. They are also
reprinted in the publication[2]about that version of Mininec which
has a listing of the Basic source code (slightly different from the
version available online) where it is on p. C-31 in lines
1512–1514.1.38629436112.09666344259.03590092383.03742563713.01451196212.5.12498593397.06880248576.0332835346.00441787012In one of the first publications on Mininec[1]the authors give the
parameters on p. 13 as:1.38629436112.09666344259.03590092383.03742563713.01451196212.5.1249859397.06880248576.03328355346.00441787012This is consistent with the later Mininec paper[2]on version 3 of
the Mininec code on p. 9, but large portions of that paper are copy
& paste from the earlier paper.The first paper[1]has a listing of the Basic code of that version and
on p. 48 the parameters are given as:1.38629436.09666344.03590092.03742563713.01451196.5.12498594.06880249.0332836.0041787In each case the first line are theaparameters, the second line are
thebparameters. Theaparameters are consistent in all versions
but notice how in thebparameters (2nd line) the current Basic code
has one more3in the second column. The rounding of the earlier Basic
code suggests that the second3is a typo in the later Basic version.
Also notice that in the 4th column the later Basic code has a5less
than the version in the papers. The rounding in the earlier Basic code
also suggests that the later Basic code is in error.The errors in theelliptic integralparameters do not have much effect
on the computed values of the Mininec code. There are some minor
differences but these are below the differences between Basic and Python
implementation (single vs. double precision arithmetics). I had hoped
that this has something to do with the well known fact that Mininec
finds a resonance point of an antenna some percent too high which means
that usually in practice the computed wire lengths are a little too
long. This is apparently not the case. The resonance point is also wrong
for very thin wires below thesmall radius modification conditionwhich happens when the wire radius is below 1e-4 of the wavelength.
Even in that case –  where theelliptic integralis not used – the
resonance is slightly wrong.The reference for theelliptic integralparameters[3]cited in both
reports lists the following table on p. 591:1.38629436112.09666344259.03590092383.03742563713.01451196212.5.12498593597.06880248576.03328355346.00441787012Note that I could only locate the 1972 version of the Handbook, not the
1980 version cited by the reports. So there is a small chance that these
parameters were corrected in a later version. It turns out that the
reports are correct in the fourth column and the Basic program is wrong.
But the second column contains stillanotherversion, note that there
is a5in the 9th position after the comma, not a3like in the
Basic program and not a missing digit like in the Mininec reports[1][2].Since I could not be sure that there was a typo in the handbook[3], I
dug deeper: The handbook citesApproximations for Digital Computersby
Hastings (without giving a year)[4]. The version of that book I found
is from 1955 and lists the coefficients on p. 172:1.38629436112.09666344259.03590092383.03742563713.01451196212.5.12498593597.06880248576.03328355346.00441787012So apparently the handbook[3]is correct. And the Basic version andbothMininec reports have at least one typo.Since this paragraph was written the implementation of theelliptic
integralwas removed and replace with a call toscipy.special.ellipk.
The resulting differences in computed outputs were smaller than the
differences between the Basic (single precision) and the Python (double
precision) implementation.Running examples in BasicThe original Basic source code can still be run today, thanks to Rob
Hagemanspcbasicproject. It is written in Python and can be
installed with pip. It is also packaged in some Linux distributions,
e.g. inDebian.Since Mininec reads all inputs for an antenna simulation from the
command-line in Basic, I’m creating input files that contain
reproduceable command-line input for an antenna simulation. An example
of such a script is indipole-01.mini, the suffixminiindicating a Mininec file.Of course the input files only make sense if you actually run them with
the mininec basic code as this displays all the prompts.
Note that I had to change the dimensions of some arrays in the Basic
code to not run into an out-of-memory condition with the Basic
interpreter.You can runpcbasicwith the command-line option--input=to specify
an input file. Note that the input file has to be converted to carriage
return line endings (no newlines). I’ve described how I’m debugging the
Basic code using the Python debugger in acontribution to pcbasic,
this has been moved to thepcbasic wiki.In the filedebug-basic.txtyou can find my notes on how to debug
mininec using the python debugger. This is more or less a random
cut&paste buffer.Theoriginal basic source codecan be obtained from theunofficial
NEC archiveby PA3KJ or from aMininec github project, I’m using
the version from theunofficial NEC archiveand have not verified if
the two links I’ve given contain the same code.Release Notesv0.6.1: Fix entry point for scriptv0.6.0: Add pyproject.tomlAdd pyproject.tomlAdd LICENSE fileMinor fixesv0.5.0: Bug fixes and new load typesNew load types RLC load and Trap load: The first uses a series R-L-C
(with each being optional), the second serial R-L parallel to a C (for
a good emulation of traps in antennas)Bug-Fix in wire-end matching: If there are multiple wires connected
to a single point the previous implementation would not build the data
structures correctlyAdd more regression testsGet rid of unittest to avoid a mixture of the unittest and pytest
testing frameworksv0.4.0: Splitplot-antennainto own projectOwn projectplot-antennaFix parsing of several medium options, mention ground in documentationv0.3.0: Laplace loads correctly implementedUse scipy.special.ellipk for elliptic integralUse gaussian quadrature coefficients from scipy.integrateTest resonance (NEC vs. mininec)v0.2.0: Add short paragraph on new plotting programTest coverageExpression simplificationv0.1.0: Initial release[1](1,2,3)Alfredo J. Julian, James C. Logan, and John W. Rockway.
Mininec: A mini-numerical electromagnetics code. Technical Report
NOSC TD 516, Naval Ocean Systems Center (NOSC), San Diego,
California, September 1982. Available asADA121535from the Defense
Technical Information Center.[2](1,2,3)J. C. Logan and J. W. Rockway. The new MININEC (version 3): A
mini-numerical electromagnetic code. Technical Report NOSC TD 938,
Naval Ocean Systems Center (NOSC), San Diego, California, September
1986. Available asADA181682from the Defense Technical Information
Center. Note: The scan of that report isverybad. If you have
access to a better version, please make it available![3](1,2,3)Milton Abramowitz and Irene A. Stegun, editors. Handbook of
Mathematical Functions With Formulas, Graphs, and Mathematical
Tables.  Number 55 in Applied Mathematics Series.  National Bureau
of Standards, 1972.[4]Cecil Hastings, Jr. Approximations for Digital Computers.
Princeton University Press, 1955.[5](1,2)Rafik Paul Zeineddin. Numerical electromagnetics codes: Problems,
solutions and applications. Master’s thesis, Ohio University, March 1993.
Available from theOhioLINK Electronic Theses & Dissertations Center[6](1,2)L. B. Cebik. Radiation plots: Polar or rectangular; log or linear.
In Antenna Modeling Notes [7], chapter 48, pages 366–379. Available
in Cebik’sAntenna modelling notes episode 48[7]L. B. Cebik. Antenna Modeling Notes, volume 2. antenneX Online
Magazine, 2003. Available with antenna models from theCebik
collection.