Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
343 changes: 343 additions & 0 deletions docs/api/microwave/impedance_calculator.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,343 @@
.. _impedance_calculator:

Impedance Calculator & Path Integrals
--------------------------------------

The impedance calculator and path integral classes provide tools for computing characteristic impedance, voltage, and current from electromagnetic field data. These tools can be applied to mode solver results, field monitor data, or any electromagnetic field distribution.

This section documents the **runtime execution** classes. For information on how to specify path integrals in :class:`.MicrowaveModeSpec`, see the :ref:`path_integrals` section.

Impedance Calculator
^^^^^^^^^^^^^^^^^^^^

.. autosummary::
:toctree: ../_autosummary/
:template: module.rst

tidy3d.ImpedanceCalculator

The :class:`~tidy3d.ImpedanceCalculator` computes characteristic impedance from electromagnetic field data using voltage and current path integrals. It supports three calculation methods depending on which integrals are provided:

* **V and I method**: :math:`Z_0 = V / I` (when both voltage and current integrals are provided)
* **P and V method**: :math:`Z_0 = V^2 / (2P)` (when only voltage integral is provided)
* **P and I method**: :math:`Z_0 = 2P / I^2` (when only current integral is provided)

where :math:`P` is the time-averaged power flux through the cross-section.

**Basic Usage**

.. code-block:: python

import tidy3d as td

# Define voltage integration path
voltage_integral = td.AxisAlignedVoltageIntegral(
center=(0, 0, 0),
size=(0, 0, 2), # Vertical line
sign="+",
extrapolate_to_endpoints=True,
snap_path_to_grid=True
)

# Define current integration contour
current_integral = td.AxisAlignedCurrentIntegral(
center=(0, 0, 0),
size=(4, 2, 0), # Rectangular loop
sign="+",
snap_contour_to_grid=True
)

# Create impedance calculator
Z_calculator = td.ImpedanceCalculator(
voltage_integral=voltage_integral,
current_integral=current_integral
)

# Compute impedance from mode data
mode_data = # ... obtain from ModeSimulation or ModeSolver
impedance = Z_calculator.compute_impedance(mode_data)

**Using with Mode Solver Data**

The impedance calculator is commonly used with mode solver results to determine the characteristic impedance of transmission line modes:

.. code-block:: python

# Run mode simulation
mode_sim = td.ModeSimulation(
size=(10, 10, 0),
grid_spec=td.GridSpec.auto(wavelength=0.3),
structures=[...],
monitors=[mode_monitor],
freqs=[1e9, 2e9, 3e9]
)

mode_data = td.web.run(mode_sim, task_name='mode_solver')

# Calculate impedance for each mode
for mode_index in range(num_modes):
mode_field = mode_data.sel(mode_index=mode_index)
Z0 = Z_calculator.compute_impedance(mode_field)
print(f"Mode {mode_index}: Z0 = {Z0} Ω")

**Obtaining Voltage and Current**

You can also retrieve the voltage and current values along with impedance:

.. code-block:: python

# Get impedance, voltage, and current
Z, V, I = Z_calculator.compute_impedance(
mode_data,
return_voltage_and_current=True
)

print(f"Impedance: {Z} Ω")
print(f"Voltage: {V} V")
print(f"Current: {I} A")

**Single Integral Calculation**

When only voltage or current integral is specified, the power flux is automatically used:

.. code-block:: python

# Calculator with only voltage integral
Z_calc_V = td.ImpedanceCalculator(
voltage_integral=voltage_integral,
current_integral=None
)

# Computes: Z = V^2 / (2*P)
Z_from_V = Z_calc_V.compute_impedance(mode_data)

# Calculator with only current integral
Z_calc_I = td.ImpedanceCalculator(
voltage_integral=None,
current_integral=current_integral
)

# Computes: Z = 2*P / I^2
Z_from_I = Z_calc_I.compute_impedance(mode_data)

Path Integral Execution Classes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. autosummary::
:toctree: ../_autosummary/
:template: module.rst

tidy3d.AxisAlignedVoltageIntegral
tidy3d.Custom2DVoltageIntegral
tidy3d.AxisAlignedCurrentIntegral
tidy3d.Custom2DCurrentIntegral
tidy3d.CompositeCurrentIntegral
tidy3d.AxisAlignedPathIntegral
tidy3d.Custom2DPathIntegral

These classes perform the actual runtime computation of path integrals on electromagnetic field data. They are created internally by :class:`~tidy3d.ImpedanceCalculator` and :class:`~tidy3d.MicrowaveModeSpec`, but can also be used directly for custom analysis.

**Note on Specification vs Execution Classes**

The path integral framework uses two parallel class hierarchies:

* **Specification classes** (``*Spec``): Define the configuration for path integrals, used in :class:`.MicrowaveModeSpec` and :class:`.CustomImpedanceSpec`. See :ref:`path_integrals`.
* **Execution classes** (``*Integral``): Perform the actual computation on field data, created from specifications or used directly.

**Direct Usage of Integral Classes**

While typically used through :class:`~tidy3d.ImpedanceCalculator`, you can also use the integral classes directly for custom analysis:

.. code-block:: python

# Create voltage integral directly
voltage_integral = td.AxisAlignedVoltageIntegral(
center=(0, 0, 0),
size=(0, 0, 2),
sign="+",
extrapolate_to_endpoints=True,
snap_path_to_grid=True
)

# Compute voltage from field data
voltage = voltage_integral.compute_voltage(field_data)

# Create current integral directly
current_integral = td.AxisAlignedCurrentIntegral(
center=(0, 0, 0),
size=(4, 2, 0),
sign="+",
snap_contour_to_grid=True
)

# Compute current from field data
current = current_integral.compute_current(field_data)

# Calculate impedance manually
impedance = voltage / current

**Composite Current Integrals**

For differential transmission lines or complex geometries with multiple current paths:

.. code-block:: python

# Define multiple current paths
path1 = td.AxisAlignedCurrentIntegral(
center=(-2, 0, 0),
size=(1, 1, 0),
sign="+"
)

path2 = td.AxisAlignedCurrentIntegral(
center=(2, 0, 0),
size=(1, 1, 0),
sign="+"
)

# Combine into composite integral
composite_integral = td.CompositeCurrentIntegral(
path_specs=(path1, path2),
sum_spec="sum" # or "split" for phase-separated contributions
)

# Compute total or split current
current = composite_integral.compute_current(field_data)

**Custom 2D Path Integrals**

For arbitrary integration paths:

.. code-block:: python

import numpy as np

# Define custom voltage path
vertices_V = np.array([[0, 0], [0.5, 0.5], [1, 1]])

custom_voltage_integral = td.Custom2DVoltageIntegral(
axis=2,
position=0.0,
vertices=vertices_V
)

voltage = custom_voltage_integral.compute_voltage(field_data)

# Define custom current contour (must be closed)
vertices_I = np.array([
[0, 0], [2, 0], [2, 1], [0, 1], [0, 0]
])

custom_current_integral = td.Custom2DCurrentIntegral(
axis=2,
position=0.0,
vertices=vertices_I
)

current = custom_current_integral.compute_current(field_data)

Field Data Compatibility
^^^^^^^^^^^^^^^^^^^^^^^^^

The impedance calculator and path integral classes work with various types of field data:

* :class:`~tidy3d.ModeSolverData`: Mode field profiles from 2D mode solver
* :class:`~tidy3d.FieldData`: Frequency-domain field data from monitors
* :class:`~tidy3d.FieldTimeData`: Time-domain field data from monitors
* :class:`~tidy3d.MicrowaveModeSolverData`: Microwave mode solver data (includes pre-computed integrals)

.. code-block:: python

# Works with different data types
Z_from_mode = Z_calculator.compute_impedance(mode_solver_data)
Z_from_monitor = Z_calculator.compute_impedance(field_monitor_data)
Z_from_time = Z_calculator.compute_impedance(field_time_data)

Phase Convention
^^^^^^^^^^^^^^^^

.. note::

Tidy3D uses the physics phase convention :math:`e^{-i\omega t}`. Some RF simulation software and textbooks use the electrical engineering convention :math:`e^{i\omega t}`. This affects calculated S-parameters and impedance values.

To convert between conventions, use complex conjugation:

.. code-block:: python

import numpy as np

# Convert from physics to engineering convention
Z_engineering = np.conjugate(Z_physics)

# Convert from engineering to physics convention
Z_physics = np.conjugate(Z_engineering)

Practical Examples
^^^^^^^^^^^^^^^^^^

**Example 1: Microstrip Line**

.. code-block:: python

# Define microstrip geometry structures
substrate = td.Structure(...)
trace = td.Structure(...)
ground = td.Structure(...)

# Create voltage integral (substrate to trace)
V_int = td.AxisAlignedVoltageIntegral(
center=(0, 0, substrate_height/2),
size=(0, 0, substrate_height),
sign="+",
snap_path_to_grid=True
)

# Create current integral (loop around trace)
I_int = td.AxisAlignedCurrentIntegral(
center=(0, 0, substrate_height + trace_height/2),
size=(trace_width*3, trace_width*3, 0),
sign="+",
snap_contour_to_grid=True
)

# Calculate impedance
calc = td.ImpedanceCalculator(voltage_integral=V_int, current_integral=I_int)
Z0 = calc.compute_impedance(mode_data)

**Example 2: Differential Stripline**

.. code-block:: python

# Voltage between the two signal traces
V_int = td.AxisAlignedVoltageIntegral(
center=(0, 0, 0),
size=(trace_spacing, 0, 0), # Horizontal line between traces
sign="+",
snap_path_to_grid=True
)

# Current around one of the traces
I_int = td.AxisAlignedCurrentIntegral(
center=(-trace_spacing/2, 0, 0),
size=(trace_width*2, trace_width*2, 0),
sign="+",
snap_contour_to_grid=True
)

# Differential impedance
calc = td.ImpedanceCalculator(voltage_integral=V_int, current_integral=I_int)
Z_diff = calc.compute_impedance(mode_data)

.. seealso::

Related documentation:

+ :ref:`path_integrals`
+ :ref:`microwave_mode_solver`

Tutorials and examples:

+ `Computing the characteristic impedance of transmission lines <../../notebooks/CharacteristicImpedanceCalculator.html>`_
+ `Differential stripline benchmark <../../notebooks/DifferentialStripline.html>`_

~~~~
8 changes: 8 additions & 0 deletions docs/api/microwave/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ The following sections discuss:
* `Layer-based Grid Refinement`_: Automated grid refinement strategy for planar structures (e.g. printed circuit boards)
* `Lumped Port & Elements`_: Lumped excitations and circuit elements
* `Wave Port`_: Port excitation based on modal fields
* `Transmission Line Mode Analysis`_: Mode solving with automatic impedance calculation for transmission lines
* `Path Integral Specifications`_: Specifications for voltage, current, and impedance calculations
* `Impedance Calculator`_: Post-processing tool for impedance calculation from electromagnetic fields
* `Microwave Output Data`_: Data containers for microwave simulation results
* `Radiation & Scattering`_: Useful features for antenna and scattering problems

.. seealso::
Expand All @@ -40,4 +44,8 @@ The following sections discuss:
.. include:: /api/discretization/layer.rst
.. include:: /api/microwave/ports/lumped.rst
.. include:: /api/microwave/ports/wave.rst
.. include:: /api/microwave/mode_solver.rst
.. include:: /api/microwave/path_integrals.rst
.. include:: /api/microwave/impedance_calculator.rst
.. include:: /api/microwave/output_data.rst
.. include:: /api/microwave/radiation_scattering.rst
Loading