Skip to content

Commit

Permalink
merged develop into main for 1.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
tylerflex committed Feb 16, 2022
2 parents 3164e6c + 8634bf5 commit 257fbb1
Show file tree
Hide file tree
Showing 28 changed files with 4,136 additions and 435 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ tests/* linguist-vendored

*.ipynb linguist-detectable=false
*.ipynb linguist-generated=true

CHANGELOG.md merge=union
114 changes: 112 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added

### Changed

## [1.0.1] - 2021-2-16

### Added
- `Selmeier.from_dispersion()` method to quickly make a single-pole fit for lossless weakly dispersive materials.
- Stable dispersive material fits via webservice.
- Allow to load dispersive data directly by providing URL to txt or csv file
- Validates simulation based on discretized size.

### Changed
- Refined and updated documentation.
- `Polyslab.from_gds` returns a list of `PolySlab` objects imported from all polygons in given layer and dtype, can optionally specify single dtype.
- Warning about structure close to PML disabled if Absorber type.
- Source dft now ignores insignificant time amplitudes for speed.
- New color schemes for plots.

## [1.0.0] - 2021-1-31

### Added
- Stable dispersive material fits via webservice.

### Changed
- Refined and updated documentation.

## [0.2.0] - 2021-1-29

### Added
Expand Down Expand Up @@ -45,7 +63,99 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Web API implemented by converting simulations to old tidy3D

[Unreleased]: https://github.com/flexcompute/Tidy3D-client-revamp/compare/v0.2.0...develop
## Alpha Release Changes

### 22.1.1
- Solver speed improvement (gain depending on simulation + hardware details).
- Bringing the speed of the non-angled mode solver back to pre-21.4.2 levels.

### 21.4.4
- Improvements to subpixel averaging for dispersive materials.
- Enabled web login using environment variables ``TIDY3D_USER`` and ``TIDY3D_PASS``.

### 21.4.3
- Bugfix when running simulation with zero ``run_time``.
- More internal logging.
- Fixed unstable ``'Li1993_293K'`` variant of ``cSi`` in the material library.

### 21.4.2.2
- Bugfix when downloading data on Windows.
- Bugfix in material fitting tool when target tolerance is not reached.

### 21.4.2
- New Gaussian beam source and `example usage <examples/GratingCoupler.html>`__.
- Modal sources and monitors in bent and in angled waveguides with `tutorial <examples/Modes_bent_angled.html>`__.
- Nyquist-limit sampling in frequency-domain monitors (much faster without loss of accuracy).
- Support for Drude model of material dispersion.
- Small bugfixes to some of the other dispersion models.
- PEC boundaries applied by default at the truncation of any boundary with PML, avoiding potential
issues with using periodic boundaries under the PML instead.
- Source normalization no longer adding a spurious frequency-dependent phase to the fields.
- Fixed bug in unpacking monitor fields with symmetries and ``interpolate=False``.
- Lots of streamlining on the backend side.

### 21.4.1
- Fixed bug with zero-size monitor plotting.
- Fixed bug with empty simulation run introduced in 21.4.0.

### 21.4.0
- A few small fixes.


### 21.3.1.6
- Fixed nonlinear constraint in dispersive material fitting tool.
- Fixed potential issue when a monitor stores neither `'E'` nor `'H'`.
- Fixed some backwards compatibility issues introduced in 21.3.1.5.


### 21.3.1.5
- Frequency monitors can now optionally store the complex permittivity at the same locations where
the E-fields are recorded, at the monitor frequencies.
- Frequency monitors now also have an `'interpolate'` keyword, which defaults to `True` and
reproduces the behavior of previous versions. If set to `False`, however, the raw fields
evaluated at their corresponding Yee grid locations are returned, instead of the fields interpolated
to the Yee cell centers. This also affects the returned permittivity, if requested.
- Reorganized internal source time dependence handling, enabling more complicated functionality
in the future, like custom source time.
- Total field in the simulation now sampled at the time step of the peak of the source time dependence,
for better estimation of the shutoff factor.
- A number of bug fixes, especially in the new plotting introduced in 21.3.1.4.

### 21.3.1.4
- Reorganized plotting:
- Speeding up structure visualizations.
- Structures now shown based on primitive definitions rather than grid discretization. This
then shows the physical structures but not what the simulation "sees". Will add an option to
display the grid lines in next version.
- Bumped down matplotlib version requirement to 3.2 and python version requirement to 3.6.
- Improved handling of PEC interfaces.- Reorganized and extended internal logging.
- Added ``tidy3d.__version__``.
- A number of fixes to the example notebooks and the colab integration.

### 21.3.1.3
- Bumping back python version requirement from 3.8 to 3.7.

### 21.3.1.2
- Hotfix to an internal bug in some simulation runs.

### 21.3.1.1
- New dispersion fitting tool for material data and accompanying `tutorial <examples/Fitting.html>`__.
- (`beta`) Non-uniform Cartesian meshing now supported. The grid coordinates are provided
by hand to `Simulation`. Next step is implementing auto-meshing.
- `DispersionModel` objects can now be directly used as materials.
- Fixed bug to `Cylinder` subpixel averaging.
- Small bugs fixes/added checks for some edge cases.

### 21.3.1.0
- Rehash of symmetries and support for mode sources and monitors with symmetries.
- Anisotropic materials (diagonal epsilon tensor).
- Rehashed error handling to output more runtime errors to tidy3d.log.
- Job and Batch classes for better simulation handling (eventually to fully replace webapi functions).
- A large number of small improvements and bug fixes.

[Unreleased]: https://github.com/flexcompute/Tidy3D-client-revamp/compare/v1.0.1...develop
[1.0.1]: https://github.com/flexcompute/Tidy3D-client-revamp/compare/v1.0.0...v1.0.1
[1.0.0]: https://github.com/flexcompute/Tidy3D-client-revamp/compare/v0.2.0...v1.0.0
[0.2.0]: https://github.com/flexcompute/Tidy3D-client-revamp/compare/0.1.1...v0.2.0
[0.1.1]: https://github.com/flexcompute/Tidy3D-client-revamp/compare/0.1.0...0.1.1
[0.1.0]: https://github.com/flexcompute/Tidy3D-client-revamp/releases/tag/0.1.0
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ The easiest way to install this beta version of tidy3d is through [pip](https://
pip install tidy3d-beta
```

Note that whikle our old version is still currently pip installable as `tidy3d`, both versions are imoprted in python as `tidy3d`, eg. `import tidy3d as td`.
Note that while our old version is still currently pip installable as `tidy3d`, both versions are imoprted in python as `tidy3d`, eg. `import tidy3d as td`.

### (Alternativelty) installing from source

Expand Down
5 changes: 4 additions & 1 deletion lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import logging
from pylint.lint import Run

# wont pass until score (out of 10.0) is greater than this
DEFAULT_THRESHOLD = 10.0


def main():
logging.getLogger().setLevel(logging.INFO)
Expand All @@ -23,7 +26,7 @@ def main():
"-t",
"--threshold",
help="score threshold to fail pylint runner | " "Default: %(default)s | " "Type: %(type)s ",
default=9.0,
default=DEFAULT_THRESHOLD,
type=float,
)

Expand Down
37 changes: 30 additions & 7 deletions tests/_test_fit_web.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import numpy as np
import sys

sys.path.append("../tidy3d_client_revamp")
from tidy3d.plugins import StableDispersionFitter
from tidy3d.plugins import StableDispersionFitter, AdvancedFitterParam


def test_dispersion_load_list():
"""performs a fit on some random data"""
num_data = 10
n_data = np.random.random(num_data)
wvls = np.linspace(1, 2, num_data)
fitter = StableDispersionFitter(wvls, n_data)
fitter = StableDispersionFitter(wvl_um=wvls, n_data=n_data)

num_poles = 3
num_tries = 10
Expand All @@ -27,7 +25,7 @@ def test_dispersion_load_file():
fitter = StableDispersionFitter.from_file("tests/data/nk_data.csv", skiprows=1, delimiter=",")

num_poles = 3
num_tries = 30
num_tries = 10
tolerance_rms = 1e-3
best_medium, best_rms = fitter.fit(
num_tries=num_tries, num_poles=num_poles, tolerance_rms=tolerance_rms
Expand All @@ -36,5 +34,30 @@ def test_dispersion_load_file():
print(best_medium.eps_model(1e12))


if __name__ == "__main__":
test_dispersion_load_file()
def test_dispersion_load_url():

url_csv = "https://refractiveindex.info/data_csv.php?datafile=data/main/Ag/Johnson.yml"
fitter = StableDispersionFitter.from_url(url_csv)

num_poles = 2
num_tries = 10
tolerance_rms = 1e-3
best_medium, best_rms = fitter.fit(
num_tries=num_tries,
num_poles=num_poles,
tolerance_rms=tolerance_rms,
advanced_param=AdvancedFitterParam(constraint="hard", bound_eps_inf=10),
)
print(best_rms)
print(best_medium.eps_inf)

fitter.wvl_range = [1.0, 1.3]
print(len(fitter.freqs))
best_medium, best_rms = fitter.fit(
num_tries=num_tries,
num_poles=num_poles,
tolerance_rms=tolerance_rms,
advanced_param=AdvancedFitterParam(constraint="hard", bound_eps_inf=10),
)
print(best_rms)
print(best_medium.eps_inf)
4 changes: 2 additions & 2 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# required for development
black
black==22.1.0
pylint
tox
pytest
pytest
57 changes: 49 additions & 8 deletions tests/test_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,20 +173,37 @@ def _test_monitor_size():
s.validate_contents()


@pytest.mark.parametrize("fwidth,log_level", [(0.001, None), (3, 30)])
def test_sim_frequency_range(caplog, fwidth, log_level):
# small fwidth should be inside range, large one should throw warning
@pytest.mark.parametrize("freq, log_level", [(1.5, 30), (2.5, None), (3.5, 30)])
def test_monitor_medium_frequency_range(caplog, freq, log_level):
# monitor frequency above or below a given medium's range should throw a warning

size = (1, 1, 1)
medium = Medium(frequency_range=(2, 3))
box = Structure(geometry=Box(size=(0.1, 0.1, 0.1)), medium=medium)
mnt = FieldMonitor(size=(0, 0, 0), name="freq", freqs=[freq])
src = VolumeSource(
source_time=GaussianPulse(freq0=2.4, fwidth=fwidth),
source_time=GaussianPulse(freq0=2.5, fwidth=0.5),
size=(0, 0, 0),
polarization="Ex",
)
_ = Simulation(size=(1, 1, 1), grid_size=(0.1, 0.1, 0.1), structures=[box], sources=[src])
sim = Simulation(
size=(1, 1, 1), grid_size=(0.1, 0.1, 0.1), structures=[box], monitors=[mnt], sources=[src]
)
assert_log_level(caplog, log_level)


@pytest.mark.parametrize("fwidth, log_level", [(0.1, 30), (2, None)])
def test_monitor_simulation_frequency_range(caplog, fwidth, log_level):
# monitor frequency outside of the simulation's frequency range should throw a warning

size = (1, 1, 1)
src = VolumeSource(
source_time=GaussianPulse(freq0=2.0, fwidth=fwidth),
size=(0, 0, 0),
polarization="Ex",
)
mnt = FieldMonitor(size=(0, 0, 0), name="freq", freqs=[1.5])
sim = Simulation(size=(1, 1, 1), grid_size=(0.1, 0.1, 0.1), monitors=[mnt], sources=[src])
assert_log_level(caplog, log_level)


Expand Down Expand Up @@ -273,8 +290,13 @@ def test_sim_plane_wave_error():
def test_sim_structure_extent(caplog, box_size, log_level):
"""Make sure we warn if structure extends exactly to simulation edges."""

src = VolumeSource(
source_time=GaussianPulse(freq0=3e14, fwidth=1e13),
size=(0, 0, 0),
polarization="Ex",
)
box = Structure(geometry=Box(size=box_size), medium=Medium(permittivity=2))
sim = Simulation(size=(1, 1, 1), grid_size=(0.1, 0.1, 0.1), structures=[box])
sim = Simulation(size=(1, 1, 1), grid_size=(0.1, 0.1, 0.1), structures=[box], sources=[src])

assert_log_level(caplog, log_level)

Expand Down Expand Up @@ -449,6 +471,25 @@ def test_medium_dispersion_create():
struct = Structure(geometry=Box(size=(1, 1, 1)), medium=medium)


def test_sellmeier_from_dispersion():
n = 3.5
wvl = 0.5
freq = C_0 / wvl
dn_dwvl = -0.1
with pytest.raises(ValidationError) as e:
# Check that postivie dispersion raises an error
medium = Sellmeier.from_dispersion(n=n, freq=freq, dn_dwvl=-dn_dwvl)

# Check that medium properties are as epected
medium = Sellmeier.from_dispersion(n=n, freq=freq, dn_dwvl=dn_dwvl)
epses = [medium.eps_model(f) for f in [0.99 * freq, freq, 1.01 * freq]]
ns = np.sqrt(epses)
dn_df = (ns[2] - ns[0]) / 0.02 / freq

assert np.allclose(ns[1], n)
assert np.allclose(-dn_df * C_0 / wvl**2, dn_dwvl)


def eps_compare(medium: Medium, expected: Dict, tol: float = 1e-5):

for freq, val in expected.items():
Expand Down Expand Up @@ -479,15 +520,15 @@ def test_epsilon_eval():
eps_compare(material, expected)

# Constant and eps, zero sigma
material = Medium(permittivity=1.5 ** 2)
material = Medium(permittivity=1.5**2)
expected = {
2e14: 2.25,
5e14: 2.25,
}
eps_compare(material, expected)

# Constant eps and sigma
material = Medium(permittivity=1.5 ** 2, conductivity=0.1)
material = Medium(permittivity=1.5**2, conductivity=0.1)
expected = {
2e14: 2.25 + 8.987552009401353j,
5e14: 2.25 + 3.5950208037605416j,
Expand Down
23 changes: 19 additions & 4 deletions tests/test_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import tidy3d as td

from tidy3d.plugins import DispersionFitter
from tidy3d.plugins.dispersion.fit import _poles_to_coeffs, _coeffs_to_poles
from tidy3d.plugins.dispersion.fit import _pack_coeffs, _unpack_coeffs

from tidy3d.plugins import ModeSolver
from tidy3d.plugins import Near2Far
Expand Down Expand Up @@ -84,11 +82,14 @@ def test_dispersion():
num_data = 10
n_data = np.random.random(num_data)
wvls = np.linspace(1, 2, num_data)
fitter = DispersionFitter(wvls, n_data)
medium, rms = fitter.fit_single()
fitter = DispersionFitter(wvl_um=wvls, n_data=n_data)
medium, rms = fitter._fit_single()
medium, rms = fitter.fit(num_tries=2)
medium.to_file("tests/tmp/medium_fit.json")

k_data = np.random.random(num_data)
fitter = DispersionFitter(wvl_um=wvls, n_data=n_data, k_data=k_data)


def test_dispersion_load():
"""loads dispersion model from nk data file"""
Expand All @@ -101,3 +102,17 @@ def test_dispersion_plot():
fitter = DispersionFitter.from_file("tests/data/nk_data.csv", skiprows=1, delimiter=",")
medium, rms = fitter.fit(num_tries=20)
fitter.plot(medium)


def test_dispersion_set_wvg_range():
"""set wavelength range function"""
num_data = 50
n_data = np.random.random(num_data)
wvls = np.linspace(1, 2, num_data)
fitter = DispersionFitter(wvl_um=wvls, n_data=n_data)

wvl_min = np.random.random(1)[0] * 0.5 + 1
wvl_max = wvl_min + 0.5
fitter.wvl_range = [wvl_min, wvl_max]
assert len(fitter.freqs) < num_data
medium, rms = fitter.fit(num_tries=2)
Loading

0 comments on commit 257fbb1

Please sign in to comment.