From 58d0fd7b82f8377a05f26e4585273065f8ca3b69 Mon Sep 17 00:00:00 2001 From: Weiliang Jin Date: Wed, 7 Aug 2024 10:40:52 -0700 Subject: [PATCH] doc improvement --- CHANGELOG.md | 2 +- docs/api/mediums.rst | 10 +++++++ docs/api/subpixel_averaging.rst | 1 + tidy3d/components/medium.py | 48 +++++++++++++++++------------- tidy3d/components/subpixel_spec.py | 18 +++++------ 5 files changed, 49 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa1b84d94..90e42a14c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added plotting functionality to voltage and current path integrals in the `microwave` plugin. - Added convenience functions `from_terminal_positions` and `from_circular_path` to simplify setup of `VoltageIntegralAxisAligned` and `CustomCurrentIntegral2D`, respectively. - Added `axial_ratio` to `DirectivityData.axial_ratio` for the `DirectivityMonitor`, defined as the ratio of the major axis to the minor axis of the polarization ellipse. -- Added material type `LossyMetalMedium` that has high DC-conductivity. Its boundaries can be modeled by surface impedance boundary condition (SIBC). This is treated as a subpixel method, and can be switched by setting `SubpixelSpec(lossy_metal=method)` where `method` can be `Staircasing()`, `VolumetricAveraging()`, or `SurfaceImpedance()`. +- Added material type `LossyMetalMedium` that has high DC-conductivity. Its boundaries can be modeled by a surface impedance boundary condition (SIBC). This is treated as a subpixel method, which can be switched by setting `SubpixelSpec(lossy_metal=method)` where `method` can be `Staircasing()`, `VolumetricAveraging()`, or `SurfaceImpedance()`. ### Changed - Priority is given to `snapping_points` in `GridSpec` when close to structure boundaries, which reduces the chance of them being skipped. diff --git a/docs/api/mediums.rst b/docs/api/mediums.rst index 0238d354d..46db62eb7 100644 --- a/docs/api/mediums.rst +++ b/docs/api/mediums.rst @@ -14,6 +14,7 @@ Spatially uniform :template: module.rst tidy3d.Medium + tidy3d.LossyMetalMedium tidy3d.PECMedium tidy3d.FullyAnisotropicMedium @@ -25,6 +26,15 @@ Spatially varying tidy3d.CustomMedium +Fitting parameters +^^^^^^^^^^^^^^^^^^ + +.. autosummary:: + :toctree: _autosummary/ + :template: module.rst + + tidy3d.SkinDepthFitterParam + Dispersive Mediums ------------------ diff --git a/docs/api/subpixel_averaging.rst b/docs/api/subpixel_averaging.rst index 8bfbf9f96..fcca4f7d1 100644 --- a/docs/api/subpixel_averaging.rst +++ b/docs/api/subpixel_averaging.rst @@ -21,3 +21,4 @@ Types of Subpixel Averaging Methods tidy3d.HeuristicPECStaircasing tidy3d.PolarizedAveraging tidy3d.PECConformal + tidy3d.SurfaceImpedance diff --git a/tidy3d/components/medium.py b/tidy3d/components/medium.py index a73ce5c17..d9e1fc892 100644 --- a/tidy3d/components/medium.py +++ b/tidy3d/components/medium.py @@ -5983,42 +5983,50 @@ def perturbed_copy( class SkinDepthFitterParam(Tidy3dBaseModel): - """Advanced parameters for fitting complex-valued skin depth ``2j/k`` over its frequency - bandwidth, where k is the complex-valued wavenumber inside the lossy metal. Real part - of this quantity corresponds to physical skin depth. + """Advanced parameters for fitting complex-valued skin depth ``2j/k`` of a :class:`.LossyMetalMedium` + over its frequency bandwidth, where k is the complex-valued wavenumber inside the lossy metal. Real part + of this quantity corresponds to the physical skin depth. """ max_num_poles: pd.PositiveInt = pd.Field( LOSSY_METAL_DEFAULT_MAX_POLES, - title="Maximal number of poles", - description="Maximal number of poles in complex-conjugate poles residue model for " + title="Maximal Number Of Poles", + description="Maximal number of poles in complex-conjugate pole residue model for " "fitting complex-valued skin depth.", ) tolerance_rms: pd.NonNegativeFloat = pd.Field( LOSSY_METAL_DEFAULT_TOLERANCE_RMS, - title="Tolerance in fitting", + title="Tolerance In Fitting", description="Tolerance in fitting complex-valued skin depth.", ) frequency_sampling_points: pd.PositiveInt = pd.Field( LOSSY_METAL_DEFAULT_SAMPLING_FREQUENCY, - title="Number of sampling frequencies", + title="Number Of Sampling Frequencies", description="Number of sampling frequencies used in fitting.", ) log_sampling: bool = pd.Field( True, - title="Frequencies sampled in log scale", - description="Whether to sample frequencies logarithmically (True), " - "or linearly (False).", + title="Frequencies Sampling In Log Scale", + description="Whether to sample frequencies logarithmically (``True``), " + "or linearly (``False``).", ) class LossyMetalMedium(Medium): - """Material with high DC-conductivity that can be modeled with surface - impedance boundary condition (SIBC). The model is accurate when the skin depth - is much smaller than the structure feature size. + """Lossy metal modeled with a surface impedance boundary condition (SIBC). + + Notes + ----- + + SIBC is suitable when the skin depth is much smaller than the structure feature size. + + Example + ------- + >>> lossy_metal = LossyMetalMedium(conductivity=10, frequency_range=(9e9, 10e9)) + """ permittivity: Literal[1] = pd.Field( @@ -6034,9 +6042,9 @@ class LossyMetalMedium(Medium): fit_param: SkinDepthFitterParam = pd.Field( SkinDepthFitterParam(), - title="Complex-valued skin depth fitting parameters", + title="Complex-valued Skin Depth Fitting Parameters", description="Parameters for fitting complex-valued dispersive skin depth over " - "the frequency range by using pole-residue pair model.", + "the frequency range using pole-residue pair model.", ) @pd.validator("frequency_range") @@ -6051,7 +6059,7 @@ def _validate_frequency_range(cls, val): @cached_property def skin_depth_model(self) -> PoleResidue: - """Fit complex-valued skin depth using pole-residue pair model within ``frequency_range``.""" + """Fitted complex-valued skin depth using pole-residue pair model within ``frequency_range``.""" skin_depth = self.complex_skin_depth(self.sampling_frequencies) # let's use scaled `skin_depth` in fitting: minimal real part equals ``SCALED_REAL_PART`` @@ -6083,15 +6091,15 @@ def num_poles(self) -> int: """Number of poles in the fitted model.""" return len(self.skin_depth_model.poles) - def complex_skin_depth(self, frequencies): - """Compute complex-valued skin_depth.""" + def complex_skin_depth(self, frequencies: ArrayFloat1D): + """Complex-valued skin_depth defined as ``2j/k`` where ``k`` is the wavenumber inside the metal.""" # compute complex-valued skin depth n, k = self.nk_model(frequencies) wavenumber = 2 * np.pi * frequencies * (n + 1j * k) / C_0 return 2j / wavenumber @cached_property - def sampling_frequencies(self): + def sampling_frequencies(self) -> ArrayFloat1D: """Sampling frequencies used in fitting.""" if self.fit_param.frequency_sampling_points < 2: return np.array([np.mean(self.frequency_range)]) @@ -6113,7 +6121,7 @@ def plot( self, ax: Ax = None, ) -> Ax: - """Make plot of model vs data, at a set of wavelengths (if supplied). + """Make plot of complex-valued skin depth model vs fitted model, at sampling frequencies. Parameters ---------- ax : matplotlib.axes._subplots.Axes = None diff --git a/tidy3d/components/subpixel_spec.py b/tidy3d/components/subpixel_spec.py index 8c908343c..c971f91c3 100644 --- a/tidy3d/components/subpixel_spec.py +++ b/tidy3d/components/subpixel_spec.py @@ -61,7 +61,7 @@ class VolumetricAveraging(AbstractSubpixelAveragingMethod): staircase_normal_component: bool = pd.Field( True, - title="Staircasing for field components substantially normal to interface", + title="Staircasing For Field Components Substantially Normal To Interface", description="Volumetric averaging works accurately if the electric field component " "is substantially tangential to the interface. If ``True``, apply volumetric averaging only " "if the field component is largely tangential to the interface; if ``False``, apply volumetric " @@ -100,8 +100,8 @@ class PECConformal(AbstractSubpixelAveragingMethod): DEFAULT_COURANT_REDUCTION_PEC_CONFORMAL, title="Time Step Size Reduction Rate", description="Reduction factor between 0 and 1 such that the simulation's time step size " - "will be ``1 - timestep_reduction`` times its default value. " - "Accuracy can be improved with a smaller time step size, but simulation time increased as well.", + "is ``1 - timestep_reduction`` times its default value. " + "Accuracy can be improved with a smaller time step size, but the simulation time will be increased.", lt=1, ge=0, ) @@ -126,8 +126,8 @@ class SurfaceImpedance(PECConformal): DEFAULT_COURANT_REDUCTION_SIBC_CONFORMAL, title="Time Step Size Reduction Rate", description="Reduction factor between 0 and 1 such that the simulation's time step size " - "will be ``1 - timestep_reduction`` times its default value. " - "Accuracy can be improved with a smaller time step size, but simulation time increased as well.", + "is ``1 - timestep_reduction`` times its default value. " + "Accuracy can be improved with a smaller time step size, but the simulation time will be increased.", lt=1, ge=0, ) @@ -141,14 +141,14 @@ class SubpixelSpec(Tidy3dBaseModel): dielectric: DielectricSubpixelType = pd.Field( PolarizedAveraging(), - title="Subpixel averaging method on dielectric material interfaces", + title="Subpixel Averaging Method For Dielectric Interfaces", description="Subpixel averaging method applied to dielectric material interfaces.", discriminator=TYPE_TAG_STR, ) metal: MetalSubpixelType = pd.Field( Staircasing(), - title="Subpixel averaging method on metallic material interfaces", + title="Subpixel Averaging Method For Metallic Interfaces", description="Subpixel averaging method applied to metallic structure interfaces. " "A material is considered as metallic if its real part of relative permittivity " "is less than 1 at the central frequency.", @@ -157,14 +157,14 @@ class SubpixelSpec(Tidy3dBaseModel): pec: PECSubpixelType = pd.Field( PECConformal(), - title="Subpixel averaging method on PEC interfaces", + title="Subpixel Averaging Method For PEC Interfaces", description="Subpixel averaging method applied to PEC structure interfaces.", discriminator=TYPE_TAG_STR, ) lossy_metal: LossyMetalSubpixelType = pd.Field( SurfaceImpedance(), - title="Subpixel averaging method on lossy metal interfaces", + title="Subpixel Averaging Method for Lossy Metal Interfaces", description="Subpixel averaging method applied to ``td.LossyMetalMedium`` material interfaces.", discriminator=TYPE_TAG_STR, )