Skip to content
Merged
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
4 changes: 4 additions & 0 deletions docs/source/07_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ API
fdtdx.apply_params
fdtdx.ArrayContainer
fdtdx.autoinit
fdtdx.BaseModeOverlapDetector
fdtdx.BinaryMedianFilterModule
fdtdx.BlochBoundary
fdtdx.boundary_objects_from_config
Expand All @@ -30,6 +31,7 @@ API
fdtdx.compute_pole_coefficients_tensor
fdtdx.compute_poynting_flux
fdtdx.ConnectHolesAndStructures
fdtdx.CustomModeOverlapDetector
fdtdx.CustomTimeSignalProfile
fdtdx.Cylinder
fdtdx.Detector
Expand Down Expand Up @@ -60,6 +62,8 @@ API
fdtdx.frozen_field
fdtdx.frozen_private_field
fdtdx.full_backward
fdtdx.gaussian_mode_function
fdtdx.GaussianModeOverlapDetector
fdtdx.GaussianPlaneSource
fdtdx.GaussianPulseProfile
fdtdx.GaussianSmoothing2D
Expand Down
12 changes: 11 additions & 1 deletion src/fdtdx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,13 @@
FieldProjectionCartesianDetector,
FieldProjectionKSpaceDetector,
)
from fdtdx.objects.detectors.mode import ModeOverlapDetector
from fdtdx.objects.detectors.mode import (
BaseModeOverlapDetector,
CustomModeOverlapDetector,
GaussianModeOverlapDetector,
ModeOverlapDetector,
gaussian_mode_function,
)
from fdtdx.objects.detectors.phasor import PhasorDetector
from fdtdx.objects.detectors.poynting_flux import (
ClosedSurfacePhasorPoyntingFluxDetector,
Expand Down Expand Up @@ -163,6 +169,7 @@

__all__ = [
"ArrayContainer",
"BaseModeOverlapDetector",
"BinaryMedianFilterModule",
"BlochBoundary",
"BoundaryConfig",
Expand All @@ -173,6 +180,7 @@
"ClosestIndex",
"Color",
"ConnectHolesAndStructures",
"CustomModeOverlapDetector",
"CustomTimeSignalProfile",
"Cylinder",
"Detector",
Expand All @@ -193,6 +201,7 @@
"GDSLayerObject",
"GDSLayerSpec",
"GDSPortSpec",
"GaussianModeOverlapDetector",
"GaussianPlaneSource",
"GaussianPulseProfile",
"GaussianSmoothing2D",
Expand Down Expand Up @@ -281,6 +290,7 @@
"frozen_field",
"frozen_private_field",
"full_backward",
"gaussian_mode_function",
"gds_layer_stack",
"gds_layer_stack_from_component",
"import_from_json",
Expand Down
51 changes: 50 additions & 1 deletion src/fdtdx/core/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
import jax.numpy as jnp
import numpy as np

from fdtdx.core.axis import get_oriented_transverse_axes
from fdtdx.core.jax.pytrees import TreeClass, autoinit, frozen_field
from fdtdx.core.linalg import get_orthogonal_vector
from fdtdx.core.linalg import get_orthogonal_vector, get_wave_vector_raw, rotate_vector
from fdtdx.materials import Material


Expand Down Expand Up @@ -504,6 +505,54 @@ def normalize_polarization_for_source(
return e_pol, h_pol


def tilted_polarization_vectors(
direction: Literal["+", "-"],
propagation_axis: int,
*,
fixed_E_polarization_vector: tuple[float, float, float] | None = None,
fixed_H_polarization_vector: tuple[float, float, float] | None = None,
azimuth_radians: float | jax.Array = 0.0,
elevation_radians: float | jax.Array = 0.0,
dtype: jnp.dtype = jnp.float32,
) -> tuple[jax.Array, jax.Array, jax.Array]:
"""Resolve the E/H polarization unit vectors and wave vector of a plane wave.

Shared by the linearly-polarized plane sources and the analytic Gaussian
mode-overlap detector so both derive polarization and off-normal propagation
identically. The raw E/H polarization comes from
:func:`normalize_polarization_for_source`, the wave vector from
:func:`~fdtdx.core.linalg.get_wave_vector_raw`, and all three are rotated by the
azimuth/elevation angles (radians) about the ``(horizontal, vertical, propagation)``
axis triple via :func:`~fdtdx.core.linalg.rotate_vector` (a zero angle is the
identity, so normal incidence is unaffected).

Args:
direction: ``"+"`` (forward) or ``"-"`` (backward) along ``propagation_axis``.
propagation_axis: Physical propagation axis (0=x, 1=y, 2=z).
fixed_E_polarization_vector: Explicit E polarization 3-vector, or ``None``.
fixed_H_polarization_vector: Explicit H polarization 3-vector, or ``None``.
azimuth_radians: Tilt around the vertical axis, in radians.
elevation_radians: Tilt around the horizontal axis, in radians.
dtype: Float dtype used to build the vectors.

Returns:
``(e_pol, h_pol, wave_vector)`` unit vectors, each of shape ``(3,)``.
"""
e_pol, h_pol = normalize_polarization_for_source(
direction=direction,
propagation_axis=propagation_axis,
fixed_E_polarization_vector=fixed_E_polarization_vector,
fixed_H_polarization_vector=fixed_H_polarization_vector,
dtype=dtype,
)
wave_vector = get_wave_vector_raw(direction=direction, propagation_axis=propagation_axis, dtype=dtype)
axes_tpl = (*get_oriented_transverse_axes(propagation_axis), propagation_axis)
e_pol = rotate_vector(e_pol, azimuth_radians, elevation_radians, axes_tpl)
h_pol = rotate_vector(h_pol, azimuth_radians, elevation_radians, axes_tpl)
wave_vector = rotate_vector(wave_vector, azimuth_radians, elevation_radians, axes_tpl)
return e_pol, h_pol, wave_vector


@overload
def expand_to_3x3(arr: None) -> None: ...

Expand Down
Loading
Loading