type hints and lint
This commit is contained in:
parent
eec3fc28a7
commit
c6c9159b13
30 changed files with 198 additions and 136 deletions
|
|
@ -683,7 +683,16 @@ def eigsolve(
|
|||
return numpy.abs(trace)
|
||||
|
||||
if False:
|
||||
def trace_deriv(theta, sgn: int = sgn, ZtAZ=ZtAZ, DtAD=DtAD, symZtD=symZtD, symZtAD=symZtAD, ZtZ=ZtZ, DtD=DtD): # noqa: ANN001
|
||||
def trace_deriv(
|
||||
theta: float,
|
||||
sgn: int = sgn,
|
||||
ZtAZ=ZtAZ, # noqa: ANN001
|
||||
DtAD=DtAD, # noqa: ANN001
|
||||
symZtD=symZtD, # noqa: ANN001
|
||||
symZtAD=symZtAD, # noqa: ANN001
|
||||
ZtZ=ZtZ, # noqa: ANN001
|
||||
DtD=DtD, # noqa: ANN001
|
||||
) -> float:
|
||||
Qi = Qi_func(theta)
|
||||
c2 = numpy.cos(2 * theta)
|
||||
s2 = numpy.sin(2 * theta)
|
||||
|
|
|
|||
|
|
@ -27,11 +27,13 @@ from scipy import sparse
|
|||
from ..fdmath import dx_lists2_t, vcfdfield2
|
||||
from .waveguide_2d import inner_product
|
||||
|
||||
type wavenumber_seq = Sequence[complex] | NDArray[numpy.complexfloating] | NDArray[numpy.floating]
|
||||
|
||||
|
||||
def _validate_port_modes(
|
||||
name: str,
|
||||
ehs: Sequence[Sequence[vcfdfield2]],
|
||||
wavenumbers: Sequence[complex],
|
||||
wavenumbers: wavenumber_seq,
|
||||
) -> tuple[tuple[int, ...], tuple[int, ...]]:
|
||||
if len(ehs) != len(wavenumbers):
|
||||
raise ValueError(f'{name} mode list and wavenumber list must have the same length')
|
||||
|
|
@ -61,9 +63,9 @@ def _validate_port_modes(
|
|||
|
||||
def get_tr(
|
||||
ehLs: Sequence[Sequence[vcfdfield2]],
|
||||
wavenumbers_L: Sequence[complex],
|
||||
wavenumbers_L: wavenumber_seq,
|
||||
ehRs: Sequence[Sequence[vcfdfield2]],
|
||||
wavenumbers_R: Sequence[complex],
|
||||
wavenumbers_R: wavenumber_seq,
|
||||
dxes: dx_lists2_t,
|
||||
) -> tuple[NDArray[numpy.complex128], NDArray[numpy.complex128]]:
|
||||
"""
|
||||
|
|
@ -118,9 +120,9 @@ def get_tr(
|
|||
|
||||
def get_abcd(
|
||||
ehLs: Sequence[Sequence[vcfdfield2]],
|
||||
wavenumbers_L: Sequence[complex],
|
||||
wavenumbers_L: wavenumber_seq,
|
||||
ehRs: Sequence[Sequence[vcfdfield2]],
|
||||
wavenumbers_R: Sequence[complex],
|
||||
wavenumbers_R: wavenumber_seq,
|
||||
**kwargs,
|
||||
) -> sparse.sparray:
|
||||
"""
|
||||
|
|
@ -151,9 +153,9 @@ def get_abcd(
|
|||
|
||||
def get_s(
|
||||
ehLs: Sequence[Sequence[vcfdfield2]],
|
||||
wavenumbers_L: Sequence[complex],
|
||||
wavenumbers_L: wavenumber_seq,
|
||||
ehRs: Sequence[Sequence[vcfdfield2]],
|
||||
wavenumbers_R: Sequence[complex],
|
||||
wavenumbers_R: wavenumber_seq,
|
||||
force_nogain: bool = False,
|
||||
force_reciprocal: bool = False,
|
||||
**kwargs,
|
||||
|
|
|
|||
|
|
@ -1,23 +1,24 @@
|
|||
"""
|
||||
Functions for performing near-to-farfield transformation (and the reverse).
|
||||
"""
|
||||
from typing import Any, cast, TYPE_CHECKING
|
||||
from typing import Any, cast
|
||||
from collections.abc import Sequence
|
||||
import numpy
|
||||
from numpy.fft import fft2, fftshift, fftfreq, ifft2, ifftshift
|
||||
from numpy import pi
|
||||
from numpy.typing import NDArray
|
||||
from numpy import complexfloating
|
||||
|
||||
from ..fdmath import cfdfield_t
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Sequence
|
||||
type farfield_slice = NDArray[complexfloating]
|
||||
type transverse_slice_pair = Sequence[farfield_slice]
|
||||
|
||||
|
||||
def near_to_farfield(
|
||||
E_near: cfdfield_t,
|
||||
H_near: cfdfield_t,
|
||||
E_near: transverse_slice_pair,
|
||||
H_near: transverse_slice_pair,
|
||||
dx: float,
|
||||
dy: float,
|
||||
padded_size: list[int] | int | None = None
|
||||
padded_size: Sequence[int] | int | None = None
|
||||
) -> dict[str, Any]:
|
||||
"""
|
||||
Compute the farfield, i.e. the distribution of the fields after propagation
|
||||
|
|
@ -58,7 +59,7 @@ def near_to_farfield(
|
|||
raise Exception('H_near must be a length-2 list of ndarrays')
|
||||
|
||||
s = E_near[0].shape
|
||||
if not all(s == f.shape for f in E_near + H_near):
|
||||
if not all(s == f.shape for f in [*E_near, *H_near]):
|
||||
raise Exception('All fields must be the same shape!')
|
||||
|
||||
if padded_size is None:
|
||||
|
|
@ -123,11 +124,11 @@ def near_to_farfield(
|
|||
|
||||
|
||||
def far_to_nearfield(
|
||||
E_far: cfdfield_t,
|
||||
H_far: cfdfield_t,
|
||||
E_far: transverse_slice_pair,
|
||||
H_far: transverse_slice_pair,
|
||||
dkx: float,
|
||||
dky: float,
|
||||
padded_size: list[int] | int | None = None
|
||||
padded_size: Sequence[int] | int | None = None
|
||||
) -> dict[str, Any]:
|
||||
"""
|
||||
Compute the farfield, i.e. the distribution of the fields after propagation
|
||||
|
|
@ -164,7 +165,7 @@ def far_to_nearfield(
|
|||
raise Exception('H_far must be a length-2 list of ndarrays')
|
||||
|
||||
s = E_far[0].shape
|
||||
if not all(s == f.shape for f in E_far + H_far):
|
||||
if not all(s == f.shape for f in [*E_far, *H_far]):
|
||||
raise Exception('All fields must be the same shape!')
|
||||
|
||||
if padded_size is None:
|
||||
|
|
|
|||
|
|
@ -423,10 +423,10 @@ def normalized_fields_h(
|
|||
def _normalized_fields(
|
||||
e: vcfdslice,
|
||||
h: vcfdslice,
|
||||
omega: complex,
|
||||
_omega: complex,
|
||||
dxes: dx_lists2_t,
|
||||
epsilon: vfdslice,
|
||||
mu: vfdslice | None = None,
|
||||
_mu: vfdslice | None = None,
|
||||
prop_phase: float = 0,
|
||||
) -> tuple[vcfdslice_t, vcfdslice_t]:
|
||||
r"""
|
||||
|
|
|
|||
|
|
@ -19,9 +19,8 @@ The intended workflow is:
|
|||
That same convention controls which side of the selected slice is used for the
|
||||
overlap window and how the expanded field is phased.
|
||||
"""
|
||||
from typing import Any, cast
|
||||
from typing import Any, TypedDict, cast
|
||||
import warnings
|
||||
from typing import Any
|
||||
from collections.abc import Sequence
|
||||
import numpy
|
||||
from numpy.typing import NDArray
|
||||
|
|
@ -31,6 +30,13 @@ from ..fdmath import vec, unvec, dx_lists_t, cfdfield_t, fdfield, cfdfield
|
|||
from . import operators, waveguide_2d
|
||||
|
||||
|
||||
class Waveguide3DMode(TypedDict):
|
||||
wavenumber: complex
|
||||
wavenumber_2d: complex
|
||||
H: NDArray[complexfloating]
|
||||
E: NDArray[complexfloating]
|
||||
|
||||
|
||||
def solve_mode(
|
||||
mode_number: int,
|
||||
omega: complex,
|
||||
|
|
@ -40,7 +46,7 @@ def solve_mode(
|
|||
slices: Sequence[slice],
|
||||
epsilon: fdfield,
|
||||
mu: fdfield | None = None,
|
||||
) -> dict[str, complex | NDArray[complexfloating]]:
|
||||
) -> Waveguide3DMode:
|
||||
r"""
|
||||
Given a 3D grid, selects a slice from the grid and attempts to
|
||||
solve for an eigenmode propagating through that slice.
|
||||
|
|
@ -121,7 +127,7 @@ def solve_mode(
|
|||
E[iii] = e[oo][:, :, None].transpose(reverse_order)
|
||||
H[iii] = h[oo][:, :, None].transpose(reverse_order)
|
||||
|
||||
results = {
|
||||
results: Waveguide3DMode = {
|
||||
'wavenumber': wavenumber,
|
||||
'wavenumber_2d': wavenumber_2d,
|
||||
'H': H,
|
||||
|
|
@ -184,13 +190,13 @@ def compute_source(
|
|||
|
||||
|
||||
def compute_overlap_e(
|
||||
E: cfdfield_t,
|
||||
E: cfdfield,
|
||||
wavenumber: complex,
|
||||
dxes: dx_lists_t,
|
||||
axis: int,
|
||||
polarity: int,
|
||||
slices: Sequence[slice],
|
||||
omega: float,
|
||||
_omega: float,
|
||||
) -> cfdfield_t:
|
||||
r"""
|
||||
Build an overlap field for projecting another 3D electric field onto a mode.
|
||||
|
|
@ -262,7 +268,7 @@ def compute_overlap_e(
|
|||
if clipped_start >= clipped_stop:
|
||||
raise ValueError('Requested overlap window lies outside the domain')
|
||||
if clipped_start != start or clipped_stop != stop:
|
||||
warnings.warn('Requested overlap window was clipped to fit within the domain', RuntimeWarning)
|
||||
warnings.warn('Requested overlap window was clipped to fit within the domain', RuntimeWarning, stacklevel=2)
|
||||
|
||||
slices2_l = list(slices)
|
||||
slices2_l[axis] = slice(clipped_start, clipped_stop)
|
||||
|
|
@ -275,7 +281,7 @@ def compute_overlap_e(
|
|||
norm = (Etgt.conj() * Etgt).sum()
|
||||
if norm == 0:
|
||||
raise ValueError('Requested overlap window contains no overlap field support')
|
||||
Etgt /= norm
|
||||
Etgt = Etgt / norm
|
||||
return cfdfield_t(Etgt)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ import numpy
|
|||
from numpy.typing import NDArray, ArrayLike
|
||||
from scipy import sparse
|
||||
|
||||
from ..fdmath import vec, unvec, dx_lists2_t, vcfdslice_t, vcfdfield2_t, vfdslice, vcfdslice, vcfdfield2
|
||||
from ..fdmath import vec, unvec, dx_lists2_t, vcfdslice_t, vfdslice, vcfdslice, vcfdfield2
|
||||
from ..fdmath.operators import deriv_forward, deriv_back
|
||||
from ..eigensolvers import signed_eigensolve, rayleigh_quotient_iteration
|
||||
from . import waveguide_2d
|
||||
|
|
@ -267,7 +267,7 @@ def solve_mode(
|
|||
mode_number: int,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
) -> tuple[vcfdslice, complex]:
|
||||
) -> tuple[vcfdfield2, complex]:
|
||||
"""
|
||||
Wrapper around `solve_modes()` that solves for a single mode.
|
||||
|
||||
|
|
@ -285,7 +285,7 @@ def solve_mode(
|
|||
|
||||
|
||||
def linear_wavenumbers(
|
||||
e_xys: list[vcfdfield2_t],
|
||||
e_xys: Sequence[vcfdfield2] | NDArray[numpy.complex128],
|
||||
angular_wavenumbers: ArrayLike,
|
||||
epsilon: vfdslice,
|
||||
dxes: dx_lists2_t,
|
||||
|
|
@ -537,11 +537,11 @@ def normalized_fields_e(
|
|||
def _normalized_fields(
|
||||
e: vcfdslice,
|
||||
h: vcfdslice,
|
||||
omega: complex,
|
||||
_omega: complex,
|
||||
dxes: dx_lists2_t,
|
||||
rmin: float, # Currently unused, but may want to use cylindrical poynting
|
||||
_rmin: float, # Currently unused, but may want to use cylindrical poynting
|
||||
epsilon: vfdslice,
|
||||
mu: vfdslice | None = None,
|
||||
_mu: vfdslice | None = None,
|
||||
prop_phase: float = 0,
|
||||
) -> tuple[vcfdslice_t, vcfdslice_t]:
|
||||
r"""
|
||||
|
|
|
|||
Loading…
Reference in a new issue