From 6989d67018f80aad5e1930c85966f9c790c0402b Mon Sep 17 00:00:00 2001 From: momchil Date: Wed, 24 Nov 2021 19:12:00 -0800 Subject: [PATCH 1/2] Adding 'diverged' to SimulationData and the hdf5 attributes --- tidy3d/components/__init__.py | 4 ++-- tidy3d/components/data.py | 17 ++++++++++++++++- tidy3d/log.py | 18 +++++++++--------- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/tidy3d/components/__init__.py b/tidy3d/components/__init__.py index 7849196032..fd90b966be 100644 --- a/tidy3d/components/__init__.py +++ b/tidy3d/components/__init__.py @@ -27,8 +27,8 @@ from .source import VolumeSource, PlaneWave, ModeSource, GaussianBeam # monitor -from .monitor import FieldMonitor, FieldTimeMonitor, FluxMonitor, FluxTimeMonitor -from .monitor import ModeMonitor +from .monitor import AbstractFieldMonitor, FreqMonitor, TimeMonitor, FieldMonitor, FieldTimeMonitor +from .monitor import AbstractFluxMonitor, FluxMonitor, FluxTimeMonitor, ModeMonitor # simulation from .simulation import Simulation diff --git a/tidy3d/components/data.py b/tidy3d/components/data.py index e789c805e9..8538daa4c4 100644 --- a/tidy3d/components/data.py +++ b/tidy3d/components/data.py @@ -3,6 +3,7 @@ from abc import ABC, abstractmethod from typing import Dict, List, Union +import logging import xarray as xr import numpy as np @@ -627,11 +628,14 @@ class SimulationData(Tidy3dBaseModel): Mapping of monitor name to :class:`Tidy3dData` intance. log_string : str = None A string containing the log information from the simulation run. + diverged : bool = False + A boolean flag denoting if the simulation run diverged. """ simulation: Simulation monitor_data: Dict[str, Tidy3dData] log_string: str = None + diverged: bool = False @property def log(self): @@ -825,12 +829,16 @@ def to_file(self, fname: str) -> None: with h5py.File(fname, "a") as f_handle: - # save json string as an attribute + # save json string as a dataset Tidy3dData.save_string(f_handle, "sim_json", self.simulation.json()) + # save log string as a dataset if self.log_string: Tidy3dData.save_string(f_handle, "log_string", self.log_string) + # save diverged flag as an attribute + f_handle.attrs["diverged"] = self.diverged + # make a group for monitor_data mon_data_grp = f_handle.create_group("monitor_data") for mon_name, mon_data in self.monitor_data.items(): @@ -864,6 +872,12 @@ def from_file(cls, fname: str): # get the log if exists log_string = Tidy3dData.load_string(f_handle, "log_string") + # set the diverged flag + # TODO: add link to documentation discussing divergence + diverged = f_handle.attrs["diverged"] + if diverged: + logging.warning("Simulation run has diverged!") + # loop through monitor dataset and create all MonitorData instances monitor_data_dict = {} for monitor_name, monitor_data in f_handle["monitor_data"].items(): @@ -877,6 +891,7 @@ def from_file(cls, fname: str): simulation=simulation, monitor_data=monitor_data_dict, log_string=log_string, + diverged=diverged, ) def __eq__(self, other): diff --git a/tidy3d/log.py b/tidy3d/log.py index c5f2646ad7..938c79afe2 100644 --- a/tidy3d/log.py +++ b/tidy3d/log.py @@ -25,7 +25,7 @@ """ Tidy3d custom exceptions """ -class Tidy3DError(Exception): +class Tidy3dError(Exception): """Any error in tidy3d""" def __init__(self, message: str = None): @@ -34,35 +34,35 @@ def __init__(self, message: str = None): super().__init__(self, message) -class ConfigError(Tidy3DError): +class ConfigError(Tidy3dError): """Error when configuring Tidy3d.""" -class Tidy3dKeyError(Tidy3DError): +class Tidy3dKeyError(Tidy3dError): """Could not find a key in a Tidy3d dictionary.""" -class ValidationError(Tidy3DError): +class ValidationError(Tidy3dError): """eError when constructing Tidy3d components.""" -class SetupError(Tidy3DError): +class SetupError(Tidy3dError): """Error regarding the setup of the components (outside of domains, etc).""" -class FileError(Tidy3DError): +class FileError(Tidy3dError): """Error reading or writing to file.""" -class WebError(Tidy3DError): +class WebError(Tidy3dError): """Error with the webAPI.""" -class AuthenticationError(Tidy3DError): +class AuthenticationError(Tidy3dError): """Error authenticating a user through webapi webAPI.""" -class DataError(Tidy3DError): +class DataError(Tidy3dError): """Error accessing data.""" From a2d0df16f64d3b89b9ffb1773a0ed34f9eb0a74f Mon Sep 17 00:00:00 2001 From: momchil Date: Mon, 29 Nov 2021 16:34:16 -0800 Subject: [PATCH 2/2] Adding type to PML and fix to dispersive conversion --- tests/test_components.py | 4 ++-- tidy3d/__init__.py | 4 ++-- tidy3d/components/__init__.py | 2 +- tidy3d/components/pml.py | 5 ++++- tidy3d/convert.py | 6 +++--- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/test_components.py b/tests/test_components.py index 66dc2703c0..60096dd10d 100644 --- a/tests/test_components.py +++ b/tests/test_components.py @@ -419,7 +419,7 @@ def test_VolumeSource_directional(): s = PlaneWave(size=(0, 1, 1), source_time=g, polarization="Ez", direction="+") # test we can make planewave - s = GaussianBeam(size=(0,1,1), source_time=g, polarization='Ez', direction='+') + s = GaussianBeam(size=(0, 1, 1), source_time=g, polarization="Ez", direction="+") # test that non-planar geometry crashes plane wave with pytest.raises(ValidationError) as e_info: @@ -429,7 +429,7 @@ def test_VolumeSource_directional(): with pytest.raises(ValidationError) as e_info: s = PlaneWave(size=(1, 1, 0), source_time=g, polarization="Ez", direction="+") with pytest.raises(ValidationError) as e_info: - s = GaussianBeam(size=(1,1,1), source_time=g, polarization='Ez', direction='+') + s = GaussianBeam(size=(1, 1, 1), source_time=g, polarization="Ez", direction="+") def test_VolumeSource_modal(): diff --git a/tidy3d/__init__.py b/tidy3d/__init__.py index 9c049c2bf4..24e0c7f958 100644 --- a/tidy3d/__init__.py +++ b/tidy3d/__init__.py @@ -1,7 +1,7 @@ """ Tidy3d package imports""" __version__ = "0.0.0" -from concurrent.futures import ProcessPoolExecutor +from concurrent.futures import ProcessPoolExecutor, process from rich import pretty, traceback @@ -63,4 +63,4 @@ # make all stdout and errors pretty pretty.install() -# traceback.install(suppress=[ProcessPoolExecutor]) +# traceback.install() diff --git a/tidy3d/components/__init__.py b/tidy3d/components/__init__.py index fd90b966be..f9a55006de 100644 --- a/tidy3d/components/__init__.py +++ b/tidy3d/components/__init__.py @@ -14,7 +14,7 @@ # medium from .medium import Medium, PoleResidue, Sellmeier, Debye, Drude, Lorentz, AnisotropicMedium, PEC -from .medium import AbstractMedium +from .medium import AbstractMedium, DispersiveMedium # structure from .structure import Structure diff --git a/tidy3d/components/pml.py b/tidy3d/components/pml.py index d8e579e468..cef9659fb0 100644 --- a/tidy3d/components/pml.py +++ b/tidy3d/components/pml.py @@ -151,6 +151,7 @@ class PML(AbsorberSpec): >>> pml = PML(num_layers=10) """ + type: Literal["PML"] = "PML" num_layers: pydantic.NonNegativeInt = 12 parameters: PMLParams = DefaultPMLParameters @@ -172,8 +173,9 @@ class StablePML(AbsorberSpec): >>> pml = StablePML(num_layers=40) """ + type: Literal["StablePML"] = "StablePML" num_layers: pydantic.NonNegativeInt = 40 - parameters: Literal[DefaultStablePMLParameters] = DefaultStablePMLParameters + parameters: PMLParams = DefaultStablePMLParameters class Absorber(AbsorberSpec): @@ -193,6 +195,7 @@ class Absorber(AbsorberSpec): >>> pml = Absorber(num_layers=40) """ + type: Literal["Absorber"] = "Absorber" num_layers: pydantic.NonNegativeInt = 40 parameters: AbsorberParams = DefaultAbsorberParameters diff --git a/tidy3d/convert.py b/tidy3d/convert.py index 571fddb2d6..ffbeaacc47 100644 --- a/tidy3d/convert.py +++ b/tidy3d/convert.py @@ -118,7 +118,7 @@ def old_json_structures(sim: Simulation) -> Tuple[List[Dict], List[Dict]]: elif isinstance(medium, DispersiveMedium): poles = [] for (a, c) in medium.pole_residue.poles: - poles.append([a[0], a[1], c[0], c[1]]) + poles.append([a.real, a.imag, c.real, c.imag]) med.update( { "type": "PoleResidue", @@ -295,8 +295,8 @@ def old_json_sources(sim: Simulation) -> List[Dict]: "waist_radius": float(source.waist_radius), "waist_distance": float(source.waist_distance), "pol_angle": float(source.pol_angle), - "amplitude": source.source_time.amplitude - } + "amplitude": source.source_time.amplitude, + } if src: src_list.append(src)