Resonant dipoles at various heights

What is this? 🔗

This is a study of how the behavior of resonant half-wave dipoles changes when height is changed.

This is intended to be an interesting read by itself for people interested in antennas. This also serves as part of the showcase for my Python software antenna-simulation-driver, in the following sense:

Object of study 🔗

We study resonant half-wave dipoles at different heights from 2 m above ground to 100 m above ground. We do so by running many antenna simulations (via some NEC2 variant).

Each such dipole is resonant at 7100 kHz and consists of copper wire with a diameter of 1 mm.

Dipoles are studied over two grounds: Average ground with dielectric constant of 13 and conductivity of 0.005 S/m, and city ground with dielectric constant of 3 and conductivity 0.001 S/m.

As a first step, it was determined that the resonant half-wave length of a dipole built from such wire is 20.563 m in free space.

Dipole length 🔗

It is well-known that height (somewhat) de-tunes antennas. Before doing measurements for a resonant half-wave dipole at a certain height, we first determine the precise length required for half-wave resonance at that height.

Here is this relative length, in percent of the resonant length in free space, depending on height, for average ground and city ground:

Tow graphs. For numerical data, see below.

For accessibility and general karma, here is an excerpt of the same data as a textual table:

height/m length avg length city
2.0 99.20 99.14
3.0 99.21 99.35
4.0 99.10 99.39
5.0 98.91 99.37
6.0 98.78 99.35
7.0 98.73 99.36
8.0 98.75 99.41
9.0 98.86 99.49
10.0 99.03 99.60
12.5 99.64 99.95
15.0 100.26 100.26
20.0 100.69 100.36
25.0 99.96 99.87
30.0 99.52 99.73
35.0 99.93 100.04
40.0 100.36 100.21
45.0 100.12 100.02
50.0 99.74 99.83
55.0 99.86 99.96
60.0 100.19 100.14
65.0 100.16 100.06
70.0 99.86 99.89
75.0 99.84 99.93
80.0 100.10 100.08
85.0 100.16 100.08
90.0 99.94 99.94
95.0 99.85 99.92
100.0 100.04 100.04

Each of the following graphs in this blog post assumes that at each height, the half-wave dipole is used that is resonant at that height.

Sideline: computational effort 🔗

For people interested in a brief overview of the mechanics of these calculations:

Loss 🔗

Loss changes with height. We map combined wire and ground loss, again for both average and city ground, measured in dB.

Two graphs. For numerical data, see below.

For accessibility and general karma, here is an excerpt of the same data as a textual table:

height/m avg city
2.0 7.8 6.9
3.0 5.7 5.6
4.0 4.1 4.6
5.0 3.1 3.8
6.0 2.4 3.3
7.0 2.0 2.9
8.0 1.7 2.5
9.0 1.4 2.3
10.0 1.3 2.2
12.5 1.1 1.9
15.0 1.1 1.9
20.0 1.3 2.1
25.0 1.4 2.1
30.0 1.3 1.9
35.0 1.1 1.8
40.0 1.1 1.9
45.0 1.3 2.0
50.0 1.2 1.9
55.0 1.1 1.8
60.0 1.1 1.8
65.0 1.2 1.9
70.0 1.2 1.9
75.0 1.2 1.8
80.0 1.1 1.8
85.0 1.2 1.9
90.0 1.2 1.9
95.0 1.2 1.9
100.0 1.1 1.8

Dipole impedance 🔗

Dipole impedance also varies with height.

As we exclusively deal with resonant dipoles, all impedances are purely ohmic, in other words, there is no capacitive or inductive component, or, in still other words, the impedance has no imaginary part.

Two graphs. For numerical data, see below.

For accessibility and general karma, here is an excerpt of the same data as a textual table:

height/m Z/Ω avg Z/Ω city
2.0 57.5 80.9
3.0 54.0 73.9
4.0 53.4 71.6
5.0 56.2 71.4
6.0 60.7 72.6
7.0 66.1 74.6
8.0 71.7 76.9
9.0 77.1 79.2
10.0 81.8 81.1
12.5 89.4 83.5
15.0 89.3 81.9
20.0 74.0 72.3
25.0 64.3 68.6
30.0 72.9 75.1
35.0 81.4 78.7
40.0 76.9 74.8
45.0 69.3 71.1
50.0 71.6 73.5
55.0 78.0 76.9
60.0 77.4 75.6
65.0 71.8 72.5
70.0 71.4 73.0
75.0 76.1 75.8
80.0 77.3 75.8
85.0 73.3 73.4
90.0 71.6 73.0
95.0 74.9 75.1
100.0 77.0 75.8

Gain for a DX QSO 🔗

For DX QSOs, flat radiation is generally beneficial. Ground gain helps, too, which is very height-dependent.

We somewhat arbitrarily assume the ionosphere has an apparent height of 400 km, and we’ll reach that DX station if the first hop carries our signals back to ground 2000 km from home.

For this, our radio waves need to be emitted at an elevation of 17° above the horizon. So we ask our antenna simulation: What is the directional gain at that elevation, in dBi? We are interested in the “best” direction, perpendicular to the dipole wire. And we want to know directional gain depending on antenna height.

Here is the result:

Two graphs. For numerical data, see below.

For accessibility and general karma, here is an excerpt of the same data as a textual table:

Height/m dBi avg dBi city
2.0 -9.2 -7.1
3.0 -6.6 -5.4
4.0 -4.7 -4.1
5.0 -3.4 -3.0
6.0 -2.5 -2.2
7.0 -1.7 -1.4
8.0 -1.1 -0.7
9.0 -0.5 -0.1
10.0 0.0 0.4
12.5 1.4 1.7
15.0 2.7 3.0
20.0 5.4 5.2
25.0 7.2 6.4
30.0 7.3 6.6
35.0 7.1 6.6
40.0 7.2 6.6
45.0 7.0 6.1
50.0 5.8 4.8
55.0 3.7 2.8
60.0 1.0 0.1
65.0 -3.1 -4.1
70.0 -12.9 -9.7
75.0 -8.5 -5.7
80.0 -1.5 -0.8
85.0 2.4 2.4
90.0 4.8 4.5
95.0 6.0 5.6
100.0 6.8 6.4

NVIS gain 🔗

Not everybody is interested in far-away DX stations. For the opposite, “nearly vertical incident skywave” NVIS, we need radiation straight up.

Again, the gain in that direction depends on antenna height. Here is the data:

Two graphs. For numerical data, see below.

For accessibility and general karma, here is an excerpt of the same data as a textual table:

height/m dBi avg dBi city
2.0 -0.0 0.3
3.0 2.4 1.8
4.0 4.0 2.8
5.0 5.0 3.6
6.0 5.6 4.1
7.0 5.9 4.4
8.0 6.0 4.5
9.0 6.0 4.4
10.0 5.8 4.3
12.5 4.9 3.4
15.0 3.0 1.6
20.0 -6.5 -1.9
25.0 3.1 3.0
30.0 6.3 4.7
35.0 4.4 2.7
40.0 -3.8 -1.9
45.0 1.0 1.8
50.0 6.0 4.7
55.0 5.3 3.6
60.0 -1.0 -1.0
65.0 -1.7 0.5
70.0 5.5 4.4
75.0 5.9 4.2
80.0 1.3 0.2
85.0 -4.8 -0.8
90.0 4.6 3.9
95.0 6.2 4.5
100.0 3.0 1.4

Other sources 🔗

This ends the study of resonant half-wave dipoles of different heights.

It was done using my Python software antenna-simulation-driver, available via Pypi. That software does not have all “batteries included”, it needs nec2++ to be installed. See the software’s README for details.

This text you just read is intended as a good, convenient entrance to get to know one of the things the antenna-simulation-driver software can do. If you want to know how it was done, you are invited to download, read, and maybe run the Jupyter notebook source that produced the graphs and numbers (recommended name resonant_dipoles.ipynb). The showcase page has instructions how to view and maybe run. It also has further examples of what else can be done with the software.

For a first glance into how this height parameter study was done, you can also try a pre-rendered version of the notebook. I find the formatting rather crappy, so I don’t fully recommend it.

Details, for the record 🔗

The study was organized as a Jupyter notebook, so besides Python 3.13, we used the “usual suspects” installed with pip:

numpy
notebook
pandas
matplotlib
scipy

In case you need to know (you probably don’t), the versions of those pieces of software and the dependencies pulled in by them were, in requirements.txt format:

antenna-simulation-driver==0.3.0
anyio==4.14.2
argon2-cffi==25.1.0
argon2-cffi-bindings==25.1.0
arrow==1.4.0
asttokens==3.0.2
async-lru==2.3.0
attrs==26.1.0
babel==2.18.0
beautifulsoup4==4.15.0
bleach==6.4.0
certifi==2026.7.22
cffi==2.1.1
charset-normalizer==3.5.1
comm==0.2.3
contourpy==1.3.3
cycler==0.12.1
debugpy==1.8.21
decorator==5.3.1
defusedxml==0.7.1
executing==2.2.1
fastjsonschema==2.22.2
fonttools==4.63.0
fqdn==1.5.1
h11==0.16.0
httpcore==1.0.9
httpx==0.28.1
idna==3.19
ipykernel==7.3.0
ipython==9.16.1
ipython-pygments-lexers==1.1.1
isoduration==20.11.0
jedi==0.20.0
jinja2==3.1.6
json5==0.15.0
jsonpointer==3.1.1
jsonschema==4.26.0
jsonschema-specifications==2025.9.1
jupyter-builder==1.2.2
jupyter-client==8.9.1
jupyter-core==5.9.1
jupyter-events==0.12.1
jupyter-lsp==2.3.1
jupyter-server==2.20.0
jupyter-server-terminals==0.5.4
jupyterlab==4.6.3
jupyterlab-pygments==0.3.0
jupyterlab-server==2.28.0
kiwisolver==1.5.0
lark==1.3.1
markupsafe==3.0.3
matplotlib==3.11.1
matplotlib-inline==0.2.2
mistune==3.3.4
nbclient==0.11.0
nbconvert==7.17.1
nbformat==5.11.1
nest-asyncio2==1.7.2
notebook==7.6.2
notebook-shim==0.2.4
numpy==2.5.2
packaging==26.3
pandas==3.0.5
pandocfilters==1.5.1
parso==0.8.7
pexpect==4.9.0
pillow==12.3.0
platformdirs==4.11.3
prometheus-client==0.26.0
prompt-toolkit==3.0.53
psutil==7.2.2
ptyprocess==0.7.0
pure-eval==0.2.3
pycparser==3.0
pygments==2.21.0
pyparsing==3.3.2
python-dateutil==2.9.0.post0
python-json-logger==4.2.0
pyyaml==6.0.3
pyzmq==27.1.0
referencing==0.37.0
requests==2.34.2
rfc3339-validator==0.1.4
rfc3986-validator==0.1.1
rfc3987-syntax==1.1.0
rpds-py==2026.6.3
scipy==1.18.0
send2trash==2.1.0
setuptools==82.0.1
six==1.17.0
soupsieve==2.9.2
stack-data==0.6.3
terminado==0.18.1
tinycss2==1.5.1
tornado==6.5.8
traitlets==5.16.1
typing-extensions==4.16.0
tzdata==2026.3
uri-template==1.3.0
urllib3==2.7.0
wcwidth==0.8.2
webcolors==25.10.0
webencodings==0.6.1
websocket-client==1.9.0

Discussion opportunity 🔗

If you want to comment or discuss this piece and have a Fediverse account, feel invited to answer my pertinent toot.