Source code for tidy3d.components.eme.sweep

"""Defines sweep settings for the EME simulation."""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Union

import pydantic.v1 as pd

from ..base import Tidy3dBaseModel
from ..types import ArrayFloat1D, ArrayInt1D, ArrayLike


class EMESweepSpec(Tidy3dBaseModel, ABC):
    """Abstract spec for sweep done during EME propagation step."""

    @property
    @abstractmethod
    def num_sweep(self) -> pd.PositiveInt:
        """Number of sweep indices."""


[docs] class EMELengthSweep(EMESweepSpec): """Spec for sweeping EME cell lengths.""" scale_factors: ArrayLike = pd.Field( ..., title="Length Scale Factor", description="Length scale factors to be used in the EME propagation step. " "The EME propagation step is repeated after scaling every cell length by this amount. " "The results are stored in 'sim_data.smatrix'. If a 2D array is provided, the " "first index is the sweep index and the second index is the cell index, " "allowing a nonuniform cell scaling along the propagation axis.", ) @property def num_sweep(self) -> pd.PositiveInt: """Number of sweep indices.""" return len(self.scale_factors)
[docs] class EMEModeSweep(EMESweepSpec): """Spec for sweeping number of modes in EME propagation step. Used for convergence testing.""" num_modes: ArrayInt1D = pd.Field( ..., title="Number of Modes", description="Max number of modes to use in the EME propagation step. " "The EME propagation step is repeated after dropping modes with mode_index " "exceeding this value. This can be used for convergence testing; reliable results " "should be independent of the number of modes used. This value cannot exceed " "the maximum number of modes in any EME cell in the simulation.", ) @property def num_sweep(self) -> pd.PositiveInt: """Number of sweep indices.""" return len(self.num_modes)
class EMEFreqSweep(EMESweepSpec): """Spec for sweeping frequency in EME propagation step. Unlike ``sim.freqs``, the frequency sweep is approximate, using a perturbative mode solver relative to the simulation EME modes. This can be a faster way to solve at a larger number of frequencies.""" freq_scale_factors: ArrayFloat1D = pd.Field( ..., title="Frequency Scale Factors", description="Scale factors " "applied to every frequency in 'EMESimulation.freqs'. After applying the scale factors, " "the new modes are computed approximately using the exact modes as a basis. " "If there are multiple 'EMESimulation.freqs', the exact modes are computed at each " "of those frequencies, and then the scale factors are applied to each independently.", ) @property def num_sweep(self) -> pd.PositiveInt: """Number of sweep indices.""" return len(self.freq_scale_factors) EMESweepSpecType = Union[EMELengthSweep, EMEModeSweep, EMEFreqSweep]