EM Fields’ ABC: Fundamentals of Electromagnetic Interactions#
In radio propagation and ray tracing, high-frequency electromagnetic fields interact with the physical environment through several distinct physical mechanisms:
Specular Reflection: Plane surfaces reflect rays according to Snell’s law, with reflection coefficients given by Fresnel formulas.
Edge Diffraction: Sharp edges scatter energy into geometric shadow zones governed by the Uniform Theory of Diffraction (UTD).
Transmission: Rays passing through finite-thickness dielectric slabs experience attenuation and phase delay.
Diffuse Scattering: Surface roughness scatters power into a broad angular lobe, following a scattering pattern (e.g., Lambertian, directive, or backscattering).
This tutorial demonstrates each interaction mathematically and visually using DiffeRT.
import differt.plotting as dplt
import jax.numpy as jnp
import matplotlib.pyplot as plt
from differt.em import (
BackscatteringPattern,
DirectivePattern,
InteractionType,
Material,
compute_received_fields,
compute_received_power,
materials,
)
from differt.geometry import Mesh, Scene, TracedPaths
dplt.set_backend("plotly")
Warp CUDA warning: Could not find or load the NVIDIA CUDA driver. GPU execution will not be available.
1. Specular Reflection: Two-Ray Ground Interference#
When both a direct Line-of-Sight (LoS) path and a ground-reflected path reach the receiver, their complex electric fields superimpose as
Because the propagation path lengths differ, the phase difference \(\Delta \phi = \frac{2\pi}{\lambda} \Delta d\) cycles periodically as the receiver moves, creating characteristic constructive and destructive interference fringes (two-ray multipath fading).
2. Edge Diffraction: The Shadow Region & UTD#
Classical geometrical optics predicts abrupt discontinuities at shadow boundaries:
Incident Shadow Boundary (ISB): where the direct LoS ray becomes occluded.
Reflection Shadow Boundary (RSB): where the specular reflected ray can no longer exist.
The Uniform Theory of Diffraction (UTD) introduces diffraction coefficients containing transition Fresnel integrals \(F(X)\) that compensate for these geometric shadow discontinuities, ensuring the total field remains continuous across shadow boundaries.
3. Transmission: Attenuation Through a Wall#
Transmission accounts for waves passing through finite-thickness dielectric obstacles.
A material requires an explicit thickness parameter \(d\).
The ray traverses the wall, attenuated by the slab transmission coefficient \(T(\theta)\).
4. Diffuse Scattering: Lambertian Rough Surfaces#
Real-world rough surfaces diffuse energy across a broad angular distribution.
Using a material’s scattering_coefficient \(S \in [0, 1]\), scattered fields follow
a Lambertian cosine pattern centered around the surface normal vector \(\hat{n}\).
5. Beyond Lambertian: Directive & Backscattering Patterns#
The Lambertian pattern above spreads diffusely-scattered power broadly around the surface normal \(\hat{n}\), independently of the incidence direction. Real rough surfaces, however, often scatter more power near the specular direction \(\hat{k}_{sp}\) (a directive lobe), or even back toward the transmitter (a retroreflective, or backscattering, lobe, as observed e.g. on foliage or building corners).
Material.scattering_pattern
accepts any
AbstractScatteringPattern
subclass, so swapping in
DirectivePattern or
BackscatteringPattern
(both following Degli-Esposti’s directive scattering model) is enough to
change a material’s scattering behavior, without touching the field
solver itself: this is exactly the point of the
AbstractScatteringPattern
abstraction. Implementing a new scattering physics only requires
subclassing it and providing a __call__ method.
directive_wall = Material(
name="itu_concrete",
properties=materials["itu_concrete"].properties,
scattering_coefficient=0.6,
scattering_pattern=DirectivePattern(alpha_r=6.0),
)
backscattering_wall = Material(
name="itu_concrete",
properties=materials["itu_concrete"].properties,
scattering_coefficient=0.6,
scattering_pattern=BackscatteringPattern(
alpha_r=6.0, alpha_i=6.0, lambda_=0.2
),
)
retroreflection_elevation = -specular_elevation # +45 deg, back toward the TX
plt.figure(figsize=(8, 4.5))
for label, material in (
("Lambertian", rough_wall),
(r"Directive ($\alpha_R = 6$)", directive_wall),
(
r"Backscattering ($\alpha_R = \alpha_I = 6$, $\Lambda = 0.2$)",
backscattering_wall,
),
):
power = compute_received_power(
compute_received_fields(
scat_paths,
wall_mesh,
freq_diff,
radio_materials={"itu_concrete": material},
)
)
plt.plot(elevation_deg, power, label=label)
plt.axvline(
specular_elevation,
color="gray",
linestyle="--",
label="Specular direction (-45°)",
)
plt.axvline(
retroreflection_elevation,
color="black",
linestyle=":",
label="Retroreflection direction (+45°)",
)
plt.xlabel("Receiver elevation from the surface normal (deg)")
plt.ylabel("Received power (dBW)")
plt.title(
"Directive and backscattering patterns concentrate power away from the normal"
)
plt.legend()
plt.grid(visible=True, alpha=0.3)
plt.show()
Summary & Custom Solvers#
DiffeRT provides a modular EM solver architecture:
High-level class
TracedFieldswraps field values, delays, operating frequencies, and validity masks.GeometricFieldSolverdispatches each path bounce to its corresponding interaction matrix (reflection_matrix,diffraction_matrix,scattering_matrix,transmission_matrix).New interaction types (such as
InteractionType.RIS) can be integrated by subclassingGeometricFieldSolverorAbstractFieldSolver.