Skip to content

Commit 1327673

Browse files
committed
revert: Remove warnings on perturbed medium ranges
1 parent ffd90a4 commit 1327673

File tree

4 files changed

+48
-193
lines changed

4 files changed

+48
-193
lines changed

CHANGELOG.md

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

1212
### Changed
13+
- Removed validator that would warn if `PerturbationMedium` values could become numerically unstable, since an error will anyway be raised if this actually happens when the medium is converted using actual perturbation data.
1314

1415
### Fixed
1516

tests/test_components/test_perturbation_medium.py

Lines changed: 39 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,14 @@ def test_perturbation_medium(unstructured):
6161
perturbation_spec=td.IndexPerturbation(delta_n=pp_real, freq=td.C_0),
6262
)
6363

64-
with AssertLogLevel("WARNING"):
65-
pmed_direct = td.PerturbationMedium(permittivity=1.21, permittivity_perturbation=pp_real)
66-
with AssertLogLevel("WARNING"):
67-
pmed_perm = td.PerturbationMedium(
68-
permittivity=1.21, perturbation_spec=td.PermittivityPerturbation(delta_eps=pp_real)
69-
)
70-
with AssertLogLevel("WARNING"):
71-
pmed_index = td.PerturbationMedium(
72-
permittivity=1.21,
73-
perturbation_spec=td.IndexPerturbation(delta_n=pp_real, freq=td.C_0),
74-
)
64+
pmed_direct = td.PerturbationMedium(permittivity=1.21, permittivity_perturbation=pp_real)
65+
pmed_perm = td.PerturbationMedium(
66+
permittivity=1.21, perturbation_spec=td.PermittivityPerturbation(delta_eps=pp_real)
67+
)
68+
pmed_index = td.PerturbationMedium(
69+
permittivity=1.21,
70+
perturbation_spec=td.IndexPerturbation(delta_n=pp_real, freq=td.C_0),
71+
)
7572

7673
# test from_unperturbed function
7774
pmed_direct_from_med = td.PerturbationMedium.from_unperturbed(
@@ -120,18 +117,15 @@ def test_perturbation_medium(unstructured):
120117
subpixel=False,
121118
)
122119

123-
with AssertLogLevel("WARNING"):
124-
pmed_direct = td.PerturbationMedium(conductivity_perturbation=pp_real, subpixel=False)
125-
with AssertLogLevel("WARNING"):
126-
pmed_perm = td.PerturbationMedium(
127-
perturbation_spec=td.PermittivityPerturbation(delta_sigma=pp_real), subpixel=False
128-
)
129-
with AssertLogLevel("WARNING"):
130-
pmed_index = td.PerturbationMedium(
131-
permittivity=2,
132-
perturbation_spec=td.IndexPerturbation(delta_k=pp_real, freq=td.C_0),
133-
subpixel=False,
134-
)
120+
pmed_direct = td.PerturbationMedium(conductivity_perturbation=pp_real, subpixel=False)
121+
pmed_perm = td.PerturbationMedium(
122+
perturbation_spec=td.PermittivityPerturbation(delta_sigma=pp_real), subpixel=False
123+
)
124+
pmed_index = td.PerturbationMedium(
125+
permittivity=2,
126+
perturbation_spec=td.IndexPerturbation(delta_k=pp_real, freq=td.C_0),
127+
subpixel=False,
128+
)
135129

136130
for pmed in [pmed_direct, pmed_perm, pmed_index]:
137131
cmed = pmed.perturbed_copy(0.9 * temperature) # positive conductivity
@@ -182,33 +176,30 @@ def test_perturbation_medium(unstructured):
182176
allow_gain=True,
183177
)
184178

185-
with AssertLogLevel("WARNING"):
186-
pmed_direct = td.PerturbationPoleResidue(
187-
eps_inf=0.2,
188-
poles=[(1j, 3), (2j, 4)],
189-
eps_inf_perturbation=pp_real,
190-
poles_perturbation=[(None, pp_real), (pp_complex, None)],
191-
subpixel=False,
192-
allow_gain=True,
193-
)
179+
pmed_direct = td.PerturbationPoleResidue(
180+
eps_inf=0.2,
181+
poles=[(1j, 3), (2j, 4)],
182+
eps_inf_perturbation=pp_real,
183+
poles_perturbation=[(None, pp_real), (pp_complex, None)],
184+
subpixel=False,
185+
allow_gain=True,
186+
)
194187

195-
with AssertLogLevel("WARNING"):
196-
pmed_perm = td.PerturbationPoleResidue(
197-
eps_inf=0.2,
198-
poles=[(1j, 3), (2j, 4)],
199-
perturbation_spec=td.PermittivityPerturbation(delta_eps=pp_real),
200-
subpixel=False,
201-
allow_gain=True,
202-
)
188+
pmed_perm = td.PerturbationPoleResidue(
189+
eps_inf=0.2,
190+
poles=[(1j, 3), (2j, 4)],
191+
perturbation_spec=td.PermittivityPerturbation(delta_eps=pp_real),
192+
subpixel=False,
193+
allow_gain=True,
194+
)
203195

204-
with AssertLogLevel("WARNING"):
205-
pmed_index = td.PerturbationPoleResidue(
206-
eps_inf=0.05,
207-
poles=[(0, 0.0001)],
208-
perturbation_spec=td.IndexPerturbation(delta_k=pp_real, freq=td.C_0),
209-
subpixel=False,
210-
allow_gain=True,
211-
)
196+
pmed_index = td.PerturbationPoleResidue(
197+
eps_inf=0.05,
198+
poles=[(0, 0.0001)],
199+
perturbation_spec=td.IndexPerturbation(delta_k=pp_real, freq=td.C_0),
200+
subpixel=False,
201+
allow_gain=True,
202+
)
212203

213204
# test from_unperturbed function
214205
pmed_direct_from_med = td.PerturbationPoleResidue.from_unperturbed(

tidy3d/components/medium.py

Lines changed: 1 addition & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
TensorReal,
9494
annotate_type,
9595
)
96-
from .validators import _warn_potential_error, validate_name_str, validate_parameter_perturbation
96+
from .validators import validate_name_str, validate_parameter_perturbation
9797
from .viz import VisualizationSpec, add_ax_if_none
9898

9999
# evaluate frequency as this number (Hz) if inf
@@ -6679,16 +6679,12 @@ class PerturbationMedium(Medium, AbstractPerturbationMedium):
66796679
_permittivity_perturbation_validator = validate_parameter_perturbation(
66806680
"permittivity_perturbation",
66816681
"permittivity",
6682-
allowed_real_range=[(1.0, None)],
6683-
allowed_imag_range=[None],
66846682
allowed_complex=False,
66856683
)
66866684

66876685
_conductivity_perturbation_validator = validate_parameter_perturbation(
66886686
"conductivity_perturbation",
66896687
"conductivity",
6690-
allowed_real_range=[(0.0, None)],
6691-
allowed_imag_range=[None],
66926688
allowed_complex=False,
66936689
)
66946690

@@ -6711,44 +6707,6 @@ def _check_overdefining(cls, values):
67116707

67126708
return values
67136709

6714-
@pd.root_validator(skip_on_failure=True)
6715-
def _check_perturbation_spec_ranges(cls, values):
6716-
"""Check perturbation ranges if defined as ``perturbation_spec``."""
6717-
p_spec = values["perturbation_spec"]
6718-
if p_spec is None:
6719-
return values
6720-
6721-
perm = values["permittivity"]
6722-
cond = values["conductivity"]
6723-
6724-
if isinstance(p_spec, IndexPerturbation):
6725-
eps_complex = Medium._eps_model(
6726-
permittivity=perm, conductivity=cond, frequency=p_spec.freq
6727-
)
6728-
n, k = Medium.eps_complex_to_nk(eps_c=eps_complex)
6729-
delta_eps_range, delta_sigma_range = p_spec._delta_eps_delta_sigma_ranges(n, k)
6730-
elif isinstance(p_spec, PermittivityPerturbation):
6731-
delta_eps_range, delta_sigma_range = p_spec._delta_eps_delta_sigma_ranges()
6732-
else:
6733-
raise SetupError("Unknown type of 'perturbation_spec'.")
6734-
6735-
_warn_potential_error(
6736-
field_name="permittivity",
6737-
base_value=perm,
6738-
val_change_range=delta_eps_range,
6739-
allowed_real_range=(1.0, None),
6740-
allowed_imag_range=None,
6741-
)
6742-
6743-
_warn_potential_error(
6744-
field_name="conductivity",
6745-
base_value=cond,
6746-
val_change_range=delta_sigma_range,
6747-
allowed_real_range=(0.0, None),
6748-
allowed_imag_range=None,
6749-
)
6750-
return values
6751-
67526710
def perturbed_copy(
67536711
self,
67546712
temperature: CustomSpatialDataType = None,
@@ -6899,16 +6857,12 @@ class PerturbationPoleResidue(PoleResidue, AbstractPerturbationMedium):
68996857
_eps_inf_perturbation_validator = validate_parameter_perturbation(
69006858
"eps_inf_perturbation",
69016859
"eps_inf",
6902-
allowed_real_range=[(0.0, None)],
6903-
allowed_imag_range=[None],
69046860
allowed_complex=False,
69056861
)
69066862

69076863
_poles_perturbation_validator = validate_parameter_perturbation(
69086864
"poles_perturbation",
69096865
"poles",
6910-
allowed_real_range=[(None, 0.0), (None, None)],
6911-
allowed_imag_range=[None, None],
69126866
)
69136867

69146868
@pd.root_validator(pre=True)
@@ -6930,37 +6884,6 @@ def _check_overdefining(cls, values):
69306884

69316885
return values
69326886

6933-
@pd.root_validator(skip_on_failure=True)
6934-
def _check_perturbation_spec_ranges(cls, values):
6935-
"""Check perturbation ranges if defined as ``perturbation_spec``."""
6936-
p_spec = values["perturbation_spec"]
6937-
if p_spec is None:
6938-
return values
6939-
6940-
eps_inf = values["eps_inf"]
6941-
poles = values["poles"]
6942-
6943-
if isinstance(p_spec, IndexPerturbation):
6944-
eps_complex = PoleResidue._eps_model(
6945-
eps_inf=eps_inf, poles=poles, frequency=p_spec.freq
6946-
)
6947-
n, k = Medium.eps_complex_to_nk(eps_c=eps_complex)
6948-
delta_eps_range, _ = p_spec._delta_eps_delta_sigma_ranges(n, k)
6949-
elif isinstance(p_spec, PermittivityPerturbation):
6950-
delta_eps_range, _ = p_spec._delta_eps_delta_sigma_ranges()
6951-
else:
6952-
raise SetupError("Unknown type of 'perturbation_spec'.")
6953-
6954-
_warn_potential_error(
6955-
field_name="eps_inf",
6956-
base_value=eps_inf,
6957-
val_change_range=delta_eps_range,
6958-
allowed_real_range=(0.0, None),
6959-
allowed_imag_range=None,
6960-
)
6961-
6962-
return values
6963-
69646887
def perturbed_copy(
69656888
self,
69666889
temperature: CustomSpatialDataType = None,

tidy3d/components/validators.py

Lines changed: 7 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from __future__ import annotations
44

5-
from typing import Any, Optional
5+
from typing import Any
66

77
import numpy as np
88
import pydantic.v1 as pydantic
@@ -335,53 +335,16 @@ def _single_frequency_in_range(cls, val: FieldDataset, values: dict) -> FieldDat
335335
return _single_frequency_in_range
336336

337337

338-
def _warn_potential_error(
339-
field_name: str,
340-
base_value: float,
341-
val_change_range: tuple[float, float],
342-
allowed_real_range: tuple[float, float],
343-
allowed_imag_range: tuple[float, float],
344-
) -> None:
345-
"""Basic validation that perturbations do not drive a parameter out of physical bounds."""
346-
347-
min_val = val_change_range[0] + base_value
348-
max_val = val_change_range[1] + base_value
349-
350-
for part_range, part_func, part_name in zip(
351-
[allowed_real_range, allowed_imag_range], [np.real, np.imag], ["Re", "Im"]
352-
):
353-
if part_range is not None:
354-
min_allowed, max_allowed = part_range
355-
356-
if min_allowed is not None and part_func(min_val) < min_allowed:
357-
log.warning(
358-
f"'{part_name}({field_name})' could "
359-
f"become less than '{min_allowed}' for a perturbation "
360-
"medium.",
361-
custom_loc=[field_name],
362-
)
363-
364-
if max_allowed is not None and part_func(max_val) > max_allowed:
365-
log.warning(
366-
f"'{part_name}({field_name})' could "
367-
f"become greater than '{max_allowed}' for a perturbation "
368-
"medium.",
369-
custom_loc=[field_name],
370-
)
371-
372-
373338
def validate_parameter_perturbation(
374339
field_name: str,
375340
base_field_name: str,
376-
allowed_real_range: tuple[tuple[float, float], ...],
377-
allowed_imag_range: Optional[tuple[tuple[float, float], ...]] = None,
378341
allowed_complex: bool = True,
379342
):
380-
"""Assert perturbations do not drive a parameter out of physical bounds."""
343+
"""Assert perturbations have a valid shape and data type."""
381344

382345
@pydantic.validator(field_name, always=True, allow_reuse=True)
383-
def _warn_perturbed_val_range(cls, val, values):
384-
"""Assert perturbations do not drive a parameter out of physical bounds."""
346+
def _check_perturbed_val(cls, val, values):
347+
"""Assert perturbations have a valid shape and data type."""
385348

386349
if val is not None:
387350
# get base values
@@ -394,41 +357,18 @@ def _warn_perturbed_val_range(cls, val, values):
394357
f" with shape of base parameter '{base_field_name}' ({np.shape(base_values)})."
395358
)
396359

397-
for tuple_ind, (base_tuple, perturb_tuple) in enumerate(
398-
zip(np.atleast_1d(base_values), np.atleast_1d(val))
399-
):
400-
tuple_ind_str = "" if np.shape(base_values) == () else f"[{tuple_ind}]"
401-
for paramer_ind, (base_value, perturb, real_range, imag_range) in enumerate(
402-
zip(
403-
np.atleast_1d(base_tuple),
404-
np.atleast_1d(perturb_tuple),
405-
allowed_real_range,
406-
allowed_imag_range,
407-
)
408-
):
360+
for perturb_tuple in np.atleast_1d(val):
361+
for perturb in np.atleast_1d(perturb_tuple):
409362
if perturb is not None:
410363
# check real/complex type
411364
if perturb.is_complex and not allowed_complex:
412365
raise SetupError(
413366
f"Perturbation of '{base_field_name}' cannot be complex."
414367
)
415368

416-
ind_pointer = tuple_ind_str + (
417-
"" if np.shape(base_tuple) == () else f"[{paramer_ind}]"
418-
)
419-
420-
sub_field_name = base_field_name + ind_pointer
421-
422-
_warn_potential_error(
423-
field_name=sub_field_name,
424-
base_value=base_value,
425-
val_change_range=perturb.perturbation_range,
426-
allowed_real_range=real_range,
427-
allowed_imag_range=imag_range,
428-
)
429369
return val
430370

431-
return _warn_perturbed_val_range
371+
return _check_perturbed_val
432372

433373

434374
def _assert_min_freq(freqs, msg_start: str) -> None:

0 commit comments

Comments
 (0)