Skip to content

Commit 4caa880

Browse files
momchil-flextylerflex
authored andcommitted
Adding Sellmeier.from_dispersion()
1 parent 4bc41b6 commit 4caa880

File tree

4 files changed

+56
-3
lines changed

4 files changed

+56
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66
## [Unreleased]
77

88
### Added
9+
- ``Selmeier.from_dispersion()`` method to quickly make a single-pole fit for lossless weakly dispersive materials.
910
- Stable dispersive material fits via webservice.
1011
- Validates simulation based on discretized size.
1112

tests/test_components.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,25 @@ def test_medium_dispersion_create():
449449
struct = Structure(geometry=Box(size=(1, 1, 1)), medium=medium)
450450

451451

452+
def test_sellmeier_from_dispersion():
453+
n = 3.5
454+
wvl = 0.5
455+
freq = C_0 / wvl
456+
dn_dwvl = -0.1
457+
with pytest.raises(ValidationError) as e:
458+
# Check that postivie dispersion raises an error
459+
medium = Sellmeier.from_dispersion(n=n, freq=freq, dn_dwvl=-dn_dwvl)
460+
461+
# Check that medium properties are as epected
462+
medium = Sellmeier.from_dispersion(n=n, freq=freq, dn_dwvl=dn_dwvl)
463+
epses = [medium.eps_model(f) for f in [0.99 * freq, freq, 1.01 * freq]]
464+
ns = np.sqrt(epses)
465+
dn_df = (ns[2] - ns[0]) / 0.02 / freq
466+
467+
assert np.allclose(ns[1], n)
468+
assert np.allclose(-dn_df * C_0 / wvl ** 2, dn_dwvl)
469+
470+
452471
def eps_compare(medium: Medium, expected: Dict, tol: float = 1e-5):
453472

454473
for freq, val in expected.items():

tidy3d/components/medium.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from .validators import validate_name_str
1414

1515
from ..constants import C_0, pec_val, EPSILON_0, HERTZ, CONDUCTIVITY, PERMITTIVITY, RADPERSEC
16-
from ..log import log
16+
from ..log import log, ValidationError
1717

1818

1919
def ensure_freq_in_range(eps_model: Callable[[float], complex]) -> Callable[[float], complex]:
@@ -268,7 +268,7 @@ def from_nk(cls, n: float, k: float, freq: float):
268268
Real part of refractive index.
269269
k : float = 0
270270
Imaginary part of refrative index.
271-
frequency : float
271+
freq : float
272272
Frequency to evaluate permittivity at (Hz).
273273
274274
Returns
@@ -507,6 +507,39 @@ def pole_residue(self):
507507
name=self.name,
508508
)
509509

510+
@classmethod
511+
def from_dispersion(cls, n: float, freq: float, dn_dwvl: float = 0):
512+
"""Convert ``n`` and wavelength dispersion ``dn_dwvl`` values at frequency ``freq`` to
513+
a single-pole :class:`Sellmeier` medium.
514+
515+
Parameters
516+
----------
517+
n : float
518+
Real part of refractive index. Must be larger than or equal to one.
519+
dn_dwvl : float = 0
520+
Derivative of the refractive index with wavelength (1/um). Must be negative.
521+
frequency : float
522+
Frequency to evaluate permittivity at (Hz).
523+
524+
Returns
525+
-------
526+
:class:`Medium`
527+
medium containing the corresponding ``permittivity`` and ``conductivity``.
528+
"""
529+
530+
if dn_dwvl >= 0:
531+
raise ValidationError("Dispersion ``dn_dwvl`` must be smaller than zero.")
532+
if n < 1:
533+
raise ValidationError("Refractive index ``n`` cannot be smaller than one.")
534+
535+
wvl = C_0 / freq
536+
nsqm1 = n ** 2 - 1
537+
c_coeff = -(wvl ** 3) * n * dn_dwvl / (nsqm1 - wvl * n * dn_dwvl)
538+
b_coeff = (wvl ** 2 - c_coeff) / wvl ** 2 * nsqm1
539+
coeffs = [(b_coeff, c_coeff)]
540+
541+
return cls(coeffs=coeffs)
542+
510543

511544
class Lorentz(DispersiveMedium):
512545
"""A dispersive medium described by the Lorentz model.

tidy3d/log.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class Tidy3dKeyError(Tidy3dError):
4343

4444

4545
class ValidationError(Tidy3dError):
46-
"""eError when constructing Tidy3d components."""
46+
"""Error when constructing Tidy3d components."""
4747

4848

4949
class SetupError(Tidy3dError):

0 commit comments

Comments
 (0)