|
| 1 | +Simulation Tips for AI Agents |
| 2 | +============================= |
| 3 | + |
| 4 | +*Workflow patterns and runtime pitfalls for AI-assisted photonics simulation.* |
| 5 | + |
| 6 | +This page collects practical workflow guidance that spans multiple Tidy3D classes and doesn't belong in any single docstring. For API-level guidance (which source to use, how to set up materials, grid resolution), see the class docstrings — they contain selection guides and tips under **Practical Advice** headings. |
| 7 | + |
| 8 | +**Units**: length in micrometers, time in seconds, frequency in Hz. |
| 9 | + |
| 10 | +.. contents:: On this page |
| 11 | + :local: |
| 12 | + :depth: 2 |
| 13 | + |
| 14 | + |
| 15 | +Documentation Lookups with MCP |
| 16 | +------------------------------ |
| 17 | + |
| 18 | +The `FlexAgent MCP <flex_agent.html>`_ server is your primary source for API docs and examples. Always search it before writing simulation code. |
| 19 | + |
| 20 | +.. list-table:: |
| 21 | + :header-rows: 1 |
| 22 | + :widths: 40 60 |
| 23 | + |
| 24 | + * - Tool |
| 25 | + - Purpose |
| 26 | + * - ``search_flexcompute_docs`` |
| 27 | + - Search all Flexcompute docs and examples |
| 28 | + * - ``fetch_flexcompute_doc`` |
| 29 | + - Fetch a specific documentation page by URL |
| 30 | + |
| 31 | +**Search patterns:** |
| 32 | + |
| 33 | +- Device type: ``"ring resonator tidy3d"``, ``"grating coupler SOI"`` |
| 34 | +- API class: ``"ModeSource tidy3d"``, ``"FluxMonitor tidy3d"`` |
| 35 | +- Workflow: ``"parameter sweep batch tidy3d"``, ``"adjoint inverse design tidy3d"`` |
| 36 | + |
| 37 | +**Decompose the request before searching:** |
| 38 | + |
| 39 | +1. **Device** — what structure? Search ``"{device_type} tidy3d"`` |
| 40 | +2. **FOM** — what to measure? Search ``"{monitor_type} tidy3d"`` |
| 41 | +3. **Workflow** — single run, sweep, EME, or inverse design? |
| 42 | + |
| 43 | + |
| 44 | +Visualization-First Workflow |
| 45 | +---------------------------- |
| 46 | + |
| 47 | +Never run a simulation you haven't visually inspected. Generate plots liberally and inspect them — this is the cheapest way to catch errors. |
| 48 | + |
| 49 | +1. **Plot geometry** — ``sim.plot_eps(x=0)``, ``sim.plot_eps(y=0)``, ``sim.plot_eps(z=0)``. Check: waveguides extend through PML, sources in straight sections, monitors correctly placed, dimensions look right. |
| 50 | +2. **Fix and re-plot** — if anything looks wrong, fix it and plot again. Do not skip to running the simulation. |
| 51 | +3. **After running, inspect results** — are T values physical (at most 1.0)? Do field profiles look reasonable? Any shutoff warnings? Do sweep trends make sense? |
| 52 | +4. **Stop if wrong** — do not continue to optimization or parameter sweeps on top of a broken setup. |
| 53 | + |
| 54 | + |
| 55 | +Parameter Sweeps |
| 56 | +---------------- |
| 57 | + |
| 58 | +Use ``web.run_async()`` to run multiple simulations in parallel: |
| 59 | + |
| 60 | +.. code-block:: python |
| 61 | +
|
| 62 | + sims = {f"width_{w:.3f}": make_sim(w) for w in np.linspace(0.4, 0.6, 11)} |
| 63 | + batch_data = web.run_async(sims) |
| 64 | + for name, sim_data in batch_data.items(): |
| 65 | + T = sim_data["transmission"].flux.values |
| 66 | +
|
| 67 | +
|
| 68 | +S-Parameter Extraction |
| 69 | +---------------------- |
| 70 | + |
| 71 | +Use the ``ModalComponentModeler`` plugin for multi-port S-parameters: |
| 72 | + |
| 73 | +.. code-block:: python |
| 74 | +
|
| 75 | + from tidy3d.plugins.smatrix import ModalComponentModeler, Port |
| 76 | +
|
| 77 | + import tidy3d.web as web |
| 78 | +
|
| 79 | + ports = [ |
| 80 | + Port(center=(-5, 1, 0), size=(0, 2, 2), mode_spec=td.ModeSpec(), direction="+", name="in1"), |
| 81 | + Port(center=(5, 1, 0), size=(0, 2, 2), mode_spec=td.ModeSpec(), direction="-", name="out1"), |
| 82 | + ] |
| 83 | + modeler = ModalComponentModeler(simulation=sim, ports=ports, freqs=freqs) |
| 84 | + modeler_data = web.run(modeler) |
| 85 | + smatrix = modeler_data.smatrix() |
| 86 | + S21 = smatrix.loc[dict(port_in="in1", mode_index_in=0, port_out="out1", mode_index_out=0)] |
| 87 | +
|
| 88 | +
|
| 89 | +Resonator Q Factor |
| 90 | +------------------ |
| 91 | + |
| 92 | +Three methods: |
| 93 | + |
| 94 | +1. **Spectral fitting** — fit a Lorentzian to the transmission dip near resonance. |
| 95 | +2. **Time-domain decay** — place a ``FieldTimeMonitor`` at the cavity center, fit exponential decay to extract ``Q = omega * tau / 2``. |
| 96 | +3. **ResonanceFinder plugin** — ``from tidy3d.plugins.resonance import ResonanceFinder``. |
| 97 | + |
| 98 | + |
| 99 | +EME Simulations |
| 100 | +--------------- |
| 101 | + |
| 102 | +EME (Eigenmode Expansion) is efficient for devices with slowly varying cross-sections — tapers, transitions, periodic structures. |
| 103 | + |
| 104 | +.. code-block:: python |
| 105 | +
|
| 106 | + eme_sim = td.EMESimulation( |
| 107 | + size=(10, 4, 4), |
| 108 | + structures=[...], monitors=[...], |
| 109 | + grid_spec=td.GridSpec.auto(min_steps_per_wvl=20, wavelength=wavelength), |
| 110 | + axis=0, |
| 111 | + eme_grid_spec=td.EMEUniformGrid( |
| 112 | + num_cells=20, mode_spec=td.EMEModeSpec(num_modes=10) |
| 113 | + ), |
| 114 | + freqs=[freq0], |
| 115 | + ) |
| 116 | + eme_data = web.run(eme_sim, task_name="eme_taper") |
| 117 | +
|
| 118 | +EME can sweep device length without re-solving modes using ``sweep_spec=td.EMELengthSweep(scale_factors=np.linspace(0.5, 2.0, 20))``. |
| 119 | + |
| 120 | +.. list-table:: |
| 121 | + :header-rows: 1 |
| 122 | + :widths: 50 50 |
| 123 | + |
| 124 | + * - Use EME when... |
| 125 | + - Use FDTD when... |
| 126 | + * - Device is long (>20 wavelengths) |
| 127 | + - Complex 3D scattering |
| 128 | + * - Cross-section changes slowly |
| 129 | + - Broadband response needed |
| 130 | + * - Need length optimization |
| 131 | + - Time-domain effects matter |
| 132 | + |
| 133 | + |
| 134 | +Inverse Design |
| 135 | +-------------- |
| 136 | + |
| 137 | +Tidy3D uses **HIPS autograd**, not JAX. The old ``tidy3d.plugins.adjoint`` plugin has been removed. Regular ``td.Simulation`` and ``web.run()`` are differentiable — no special classes needed. |
| 138 | + |
| 139 | +.. code-block:: python |
| 140 | +
|
| 141 | + import autograd |
| 142 | + import autograd.numpy as anp |
| 143 | + # NOT: import jax |
| 144 | + # NOT: from tidy3d.plugins.adjoint import ... |
| 145 | +
|
| 146 | +For detailed patterns (filter and project, beta scheduling, learning rates, gradient sign conventions, traceable components, gotchas), see the autograd README in the Tidy3D source: ``tidy3d/plugins/autograd/README.md``. |
| 147 | + |
| 148 | + |
| 149 | +Pre-Flight Checklist |
| 150 | +-------------------- |
| 151 | + |
| 152 | +Run through before every simulation: |
| 153 | + |
| 154 | +1. Waveguides extend through PML — use ``td.inf`` |
| 155 | +2. Source/monitor in straight sections — not at bends or junctions |
| 156 | +3. Mode monitor sized 3-4x waveguide width |
| 157 | +4. Grid resolves features — at least 15-20 cells across smallest feature |
| 158 | +5. Transmission is physical — T at most 1.0 |
| 159 | +6. ``RunTimeSpec`` or sufficient ``run_time`` — no shutoff warnings |
| 160 | + |
| 161 | + |
| 162 | +Common Failure Modes |
| 163 | +-------------------- |
| 164 | + |
| 165 | +.. list-table:: |
| 166 | + :header-rows: 1 |
| 167 | + :widths: 20 35 45 |
| 168 | + |
| 169 | + * - Symptom |
| 170 | + - Likely Cause |
| 171 | + - Fix |
| 172 | + * - T = 0 |
| 173 | + - Source/monitor misaligned |
| 174 | + - Check geometry plot |
| 175 | + * - T > 1.0 |
| 176 | + - Monitor direction wrong |
| 177 | + - Check ``direction`` parameter |
| 178 | + * - NaN |
| 179 | + - Simulation diverged |
| 180 | + - Check PML, resolution, dispersive materials |
| 181 | + * - Shutoff warning |
| 182 | + - ``run_time`` too short |
| 183 | + - Use ``RunTimeSpec`` with higher ``quality_factor`` |
| 184 | + * - Wrong wavelength |
| 185 | + - ``n_eff`` guessed |
| 186 | + - Use ModeSolver to compute it |
| 187 | + * - Autograd TypeError |
| 188 | + - ``float()`` on traced param |
| 189 | + - Never cast traced params |
| 190 | + * - 0 gradient |
| 191 | + - Sim domain depends on params |
| 192 | + - Only geometry should be traced |
| 193 | + |
| 194 | + |
| 195 | +Coding Discipline |
| 196 | +----------------- |
| 197 | + |
| 198 | +- **Never suppress warnings** — every Tidy3D warning tells you something is wrong. Read it, fix the root cause. Do not use ``warnings.filterwarnings("ignore")``. |
| 199 | +- **Never use try/except to mask failures** — if ``web.run()`` fails, the error tells you what's wrong. Catching and ignoring it means proceeding with garbage. |
| 200 | +- **Never guess physical parameters** — always compute ``n_eff``, grating periods, etc. using ModeSolver or equivalent. This is the number one source of wrong results. |
| 201 | +- **Fix warnings, don't work around them** — search the MCP for the warning text, understand the cause, fix it, verify it's gone. |
0 commit comments