tidy3d.plugins.autograd.invdes.initialize_params_from_simulation

tidy3d.plugins.autograd.invdes.initialize_params_from_simulation#

class initialize_params_from_simulation[source]#

Bases:

Initialize design parameters to match base simulation permittivity in a region.

Builds an objective that compares the base simulation’s permittivity against the permittivity generated by a user‑supplied parameterization and minimizes the relative L2 error using L‑BFGS‑B.

Notes

  • The simulation is not modified. If you need finer sampling inside the design region, add a MeshOverrideStructure to sim.grid_spec first.

  • The callable param_to_structure controls the parameterization and must return a Structure (typically with a CustomMedium). Its permittivity dataset (and coordinates) defines the grid used for comparison.

  • The base simulation permittivity is sampled once on an extended subgrid covering the design geometry and then interpolated onto the design region coordinates using coordinate-aware interpolation (no per-iteration interpolation).

  • Early stopping uses a single knob rel_improve_tol; optimization stops once the relative improvement over a small fixed window falls below this value.

  • If the design coordinates do not include the design geometry center, centered symmetric features can look half-cell shifted or kinked after initialization. This commonly happens with an even number of pixels across a centered design region.

  • Points outside the base‑epsilon coverage can be handled via outside_handling: 'extrapolate' (use nearest extrapolation, default in earlier versions), 'mask' (ignore outside points using a coverage mask; default), or 'nan' (non‑extended grid; treat outside as NaN and ignore in the loss).

Parameters:
  • sim (Simulation) – Base simulation without the design structure.

  • param_to_structure (Callable[
, Structure]) – Function mapping parameters to a Structure whose medium permittivity is used for comparison. Any extra keyword arguments passed to this initializer are forwarded to param_to_structure.

  • params0 (numpy.ndarray) – Initial parameter array (2D or 3D). Values may take any range, consistent with bounds and the expectations of param_to_structure.

  • maxiter (int = 100) – Maximum number of L‑BFGS‑B iterations.

  • freq (float, optional) – Frequency at which permittivity is evaluated. If None, uses infinite frequency.

  • outside_handling ({"extrapolate", "mask", "nan"} = "mask") –

    Strategy for points where design coordinates fall outside the sampled base epsilon: - “extrapolate”: include them using nearest extrapolation. - “mask”: include only points within the coverage bounds of sim.epsilon on the

    extended subgrid.

    • ”nan”: sample on a non‑extended subgrid and ignore points where interpolation returns NaN.

  • bounds (tuple[float | None, float | None] = (0.0, 1.0)) – Element‑wise parameter bounds, e.g. (0.0, 1.0) or (-1.0, 1.0). Use None to indicate an unbounded side.

  • rel_improve_tol (float = 1e-3) – Early‑stop tolerance on relative improvement over a small window.

  • verbose (bool = False) – If True, prints SciPy optimizer messages.

Returns:

Optimized parameters with the same shape as params0.

Return type:

numpy.ndarray

Examples

Initialize a small parameter array in a 2D simulation using a minimal, differentiable parameterization that maps parameters to a permittivity field.

>>> import autograd.numpy as np
>>> import tidy3d as td
>>> from tidy3d.plugins.autograd.invdes import initialize_params_from_simulation
>>> sim = td.Simulation(
...     size=(2.0, 2.0, 0.0),
...     grid_spec=td.GridSpec.uniform(dl=1.0),
...     boundary_spec=td.BoundarySpec.pml(x=True, y=True),
...     run_time=1e-12,
... )
>>> box = td.Box(center=(0, 0, 0), size=(1.0, 1.0, 1.0))
>>> params0 = np.zeros((3, 3))
>>> def param_to_structure(p):
...     # Map params -> density in [0, 1], then to eps in [1, 4].
...     density = 0.5 * (1 + np.tanh(p))
...     eps = 1.0 + 3.0 * density
...     eps3d = eps.reshape((*p.shape, 1))
...     return td.Structure.from_permittivity_array(geometry=box, eps_data=eps3d)
>>> params = initialize_params_from_simulation(
...     sim=sim,
...     param_to_structure=param_to_structure,
...     params0=params0,
...     maxiter=3,
... ) 
>>> params.shape 
(3, 3)