Source code for jitxlib.physics
"""
Physics Utility Definitions and Functions
"""
import math
PERMITTIVITY_VAC = 8.85418782e-12 # (F / m), also (s^4 * A^2) / (kg * m^3)
"""Permittivity of Free Space (Vacuum)
see `https://en.wikipedia.org/wiki/Vacuum_permittivity`
"""
E0 = PERMITTIVITY_VAC
PERMEABILITY_VAC = math.pi * 4.0e-7 # H / m
"""Permeability of Free Space (Vacuum)
see `https://en.wikipedia.org/wiki/Vacuum_permeability`
"""
M0 = PERMEABILITY_VAC
[docs]
def wave_impedance(eps_r: float, mu_r: float):
"""Compute the Wave Impedance for a specific medium.
The wave impedance is the ratio of the electric field to the magnetic field.
Args:
eps_r: Relative Permittivity of the Medium. This value should be greater than or equal to 1.0
mu_r: Relative Magnetic Permeability of the Medium. This value should be greater than or equal to 1.0.
Returns:
The wave impedance in Ohms.
"""
assert eps_r >= 1.0
assert mu_r >= 1.0
return math.sqrt((M0 * mu_r) / (E0 * eps_r))
[docs]
def phase_velocity(eps_r: float, mu_r: float = 1.0):
"""Compute the Phase Velocity for a specific medium.
The phase velocity is the signal propagation velocity in a particular
medium. This function assumes that the medium of propagation is homogeneous.
For non-homogeneous medium, the user should compute the effective relative permittivity
and then pass it to this function.
When a field solver or the fab's impedance report gives an effective
relative permittivity (eps_eff) for the structure, pass that value. It
accounts for the real dielectric around the line (layers of different Dk
and thickness), the conductor thickness and, on microstrip, the line width
and any soldermask. Without one, these quasi-static closed forms give an
eps_eff to pass in. In each, ``er`` is the laminate's Dk at the signal
frequency.
* Stripline in one dielectric ``er``: the line carries a TEM mode in a
homogeneous medium, so ``eps_eff = er`` exactly, at any line width.
* Stripline whose strip lies on the boundary between two dielectrics ``er1``
and ``er2`` (a prepreg and a core), with equal dielectric height above and
below the strip: ``eps_eff = (er1 + er2) / 2``. By symmetry the field has
no component normal to the boundary, so this is exact for a strip of
negligible thickness. With unequal heights or a thick strip it is an
approximation, though eps_eff always lies between ``er1`` and ``er2``.
* Microstrip on a substrate ``er`` with air above: ``eps_eff = (er + 1) / 2``
is the quasi-static limit for a thin strip as w/h goes to 0, where the
strip sits on the boundary between two half-spaces, substrate and air,
and half its field lies in each. A wider strip puts more of its field in
the substrate, so eps_eff rises with width, and it approaches the limit
only slowly as the strip narrows. On ``er = 4.4`` (thin strip, no
soldermask), the Hammerstad and Jensen (1980) closed form shows this
limit overstating the velocity by about 4% even at w/h 0.1, 8% at w/h 1,
and 11% for a 50 ohm line (w/h near 1.9, eps_eff near 3.3; a
quasi-static finite-difference solve also gives about 3.3). Soldermask
over the line raises eps_eff further.
Args:
eps_r: Relative Permittivity of the Medium. This value should be greater than or equal to 1.0
mu_r: Relative Magnetic Permeability of the Medium. This value should be greater than or equal to 1.0.
The default value for this parameter is 1.0 - this is a typical default for non-magnetic materials.
Returns:
The signal propagation velocity in mm / s.
Examples:
>>> from jitxlib.physics import phase_velocity
>>> # Each result is a velocity in mm/s.
>>> # Stripline in one dielectric, er = 4.4: eps_eff = er.
>>> eps_eff = 4.4
>>> print(f"{phase_velocity(eps_eff):.4e}")
1.4292e+11
>>> # Stripline on the boundary of a prepreg (er = 3.9) and a core
>>> # (er = 4.3), with equal dielectric height above and below the strip.
>>> eps_eff = (3.9 + 4.3) / 2
>>> print(f"{phase_velocity(eps_eff):.4e}")
1.4806e+11
>>> # Microstrip on er = 4.4 with air above and no soldermask, narrow-strip
>>> # limit. A 50 ohm line has eps_eff near 3.3, so this velocity is about
>>> # 11% too high.
>>> eps_eff = (4.4 + 1) / 2
>>> print(f"{phase_velocity(eps_eff):.4e}")
1.8245e+11
"""
assert eps_r >= 1.0
assert mu_r >= 1.0
return 1000.0 / math.sqrt((M0 * mu_r) * (E0 * eps_r))
SPEED_OF_LIGHT_VAC = phase_velocity(1)
"""Speed of Light in Free Space (Vacuum) in mm / s"""
[docs]
def guide_wavelength(f: float, eps_r: float, mu_r: float = 1.0):
"""Compute the Guide Wavelength for a specific frequency in a medium.
The guide wavelength is the wavelength of a TEM wave in a specific medium.
Args:
f: Frequency in Hz
eps_r: Relative Permittivity of the Medium. This value should be greater than or equal to 1.0
mu_r: Relative Magnetic Permeability of the Medium. This value should be
greater than or equal to 1.0.
Returns:
Guide Wavelength at `f` in mm.
"""
assert f > 0, "frequency must be positive"
assert eps_r >= 1.0
assert mu_r >= 1.0
return phase_velocity(eps_r, mu_r) / f