Skip to content

Commit

Permalink
Added Medium.eps_diagonal(); fixes #106
Browse files Browse the repository at this point in the history
  • Loading branch information
momchil-flex committed Dec 10, 2021
1 parent 90779cb commit 2d2d589
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 22 deletions.
15 changes: 14 additions & 1 deletion tests/test_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ def eps_compare(medium: Medium, expected: Dict, tol: float = 1e-5):


def test_epsilon_eval():
"""Compare epsilon evaluated from a dispersive model to expected."""
"""Compare epsilon evaluated from a dispersive various models to expected."""

# Dispersive silver model
poles_silver = [
Expand Down Expand Up @@ -310,6 +310,19 @@ def test_epsilon_eval():
}
eps_compare(material, expected)

# Anisotropic material
eps = (1.5, 2.0, 2.3)
sig = (0.01, 0.03, 0.015)
mediums = [Medium(permittivity=eps[i], conductivity=sig[i]) for i in range(3)]
material = AnisotropicMedium(xx=mediums[0], yy=mediums[1], zz=mediums[2])

eps_diag_2 = material.eps_diagonal(2e14)
eps_diag_5 = material.eps_diagonal(5e14)
assert np.all(np.array(eps_diag_2) == np.array([medium.eps_model(2e14) for medium in mediums]))

expected = {2e14: np.mean(eps_diag_2), 5e14: np.mean(eps_diag_5)}
eps_compare(material, expected)


""" modes """

Expand Down
81 changes: 60 additions & 21 deletions tidy3d/components/medium.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@
from ..log import log


def ensure_freq_in_range(eps_model: Callable[[float], complex]) -> Callable[[float], complex]:
"""Decorate ``eps_model`` to log warning if frequency supplied is out of bounds."""

def _eps_model(self, frequency: float) -> complex:
"""New eps_model function."""

# if frequency is none, don't check, return original function
if frequency is None or self.frequency_range is None:
return eps_model(self, frequency)

fmin, fmax = self.frequency_range
if np.any(frequency < fmin) or np.any(frequency > fmax):
log.warning(
"frequency passed to `Medium.eps_model()`"
f"is outside of `Medium.frequency_range` = {self.frequency_range}"
)
return eps_model(self, frequency)

return _eps_model


""" Medium Definitions """


Expand Down Expand Up @@ -51,6 +72,25 @@ def eps_model(self, frequency: float) -> complex:
Complex-valued relative permittivity evaluated at ``frequency``.
"""

@ensure_freq_in_range
def eps_diagonal(self, frequency: float) -> Tuple[complex, complex, complex]:
"""Main diagonal of the complex-valued permittivity tensor as a function of frequency.
Parameters
----------
frequency : float
Frequency to evaluate permittivity at (Hz).
Returns
-------
complex
The diagonal elements of the relative permittivity tensor evaluated at ``frequency``.
"""

# This only needs to be overwritten for anisotropic materials
eps = self.eps_model(frequency)
return (eps, eps, eps)

@add_ax_if_none
def plot(self, freqs: float, ax: Ax = None) -> Ax: # pylint: disable=invalid-name
"""Plot n, k of a :class:`Medium` as a function of frequency.
Expand Down Expand Up @@ -170,27 +210,6 @@ def eps_sigma_to_eps_complex(eps_real: float, sigma: float, freq: float) -> comp
return eps_real + 1j * sigma / omega / EPSILON_0


def ensure_freq_in_range(eps_model: Callable[[float], complex]) -> Callable[[float], complex]:
"""Decorate ``eps_model`` to log warning if frequency supplied is out of bounds."""

def _eps_model(self, frequency: float) -> complex:
"""New eps_model function."""

# if frequency is none, don't check, return original function
if frequency is None or self.frequency_range is None:
return eps_model(self, frequency)

fmin, fmax = self.frequency_range
if np.any(frequency < fmin) or np.any(frequency > fmax):
log.warning(
"frequency passed to `Medium.eps_model()`"
f"is outside of `Medium.frequency_range` = {self.frequency_range}"
)
return eps_model(self, frequency)

return _eps_model


""" Dispersionless Medium """

# PEC keyword
Expand Down Expand Up @@ -338,6 +357,26 @@ def eps_model(self, frequency: float) -> complex:
Tuple[complex, complex, complex]
Complex-valued relative permittivity for each component evaluated at ``frequency``.
"""
eps_xx = self.xx.eps_model(frequency)
eps_yy = self.yy.eps_model(frequency)
eps_zz = self.zz.eps_model(frequency)
return np.mean((eps_xx, eps_yy, eps_zz))

@ensure_freq_in_range
def eps_diagonal(self, frequency: float) -> Tuple[complex, complex, complex]:
"""Main diagonal of the complex-valued permittivity tensor as a function of frequency.
Parameters
----------
frequency : float
Frequency to evaluate permittivity at (Hz).
Returns
-------
complex
The diagonal elements of the relative permittivity tensor evaluated at ``frequency``.
"""

eps_xx = self.xx.eps_model(frequency)
eps_yy = self.yy.eps_model(frequency)
eps_zz = self.zz.eps_model(frequency)
Expand Down

0 comments on commit 2d2d589

Please sign in to comment.