Source code for geopulse.efield.planewave

"""Plane-wave geoelectric field: ``E(ω) = Z(ω) · B(ω) / μ₀``.

Delegates to :meth:`Impedance.apply` so the caller does not know or care
whether ``Z`` is scalar (1-D), tensor (2-D), or kernel (3-D). The IFFT back
to the time domain is the caller's responsibility.
"""

from __future__ import annotations

import numpy as np

from geopulse.earth.impedance import Impedance

__all__ = ["compute_efield_planewave"]


[docs] def compute_efield_planewave( freqs_Hz: np.ndarray, Bx_f: np.ndarray, By_f: np.ndarray, impedance: Impedance, ) -> tuple[np.ndarray, np.ndarray]: """Compute frequency-domain geoelectric field via the plane-wave relation. For a 1-D scalar impedance this reduces to:: E_x(ω) = Z(ω) / μ₀ · B_y(ω) E_y(ω) = -Z(ω) / μ₀ · B_x(ω) Parameters ---------- freqs_Hz : numpy.ndarray Frequency array in Hz. Shape ``(n_freqs,)``. Accepted for interface symmetry; the impedance already carries its own frequency grid. Bx_f, By_f : numpy.ndarray FFT of the horizontal B-field components in Tesla. Shape ``(n_freqs,)``. impedance : Impedance Any :class:`~geopulse.earth.impedance.Impedance` subclass; the type is not inspected here. Returns ------- Ex_f, Ey_f : numpy.ndarray FFT of the horizontal E-field components in V/m. Shape matches the impedance subclass semantics (``(n_freqs,)`` for scalar). Notes ----- Standard magnetotelluric plane-wave relation; see Boteler (2014). """ del freqs_Hz # unused — impedance already knows its own frequency grid return impedance.apply(Bx_f, By_f)