Skip to content

Commit

Permalink
No commit message
Browse files Browse the repository at this point in the history
  • Loading branch information
paulxshen committed Dec 28, 2024
1 parent 14a2311 commit 8300caf
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 59 deletions.
119 changes: 67 additions & 52 deletions Luminescent_AI_docs.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"# FDTD Luminescent Simulation and Inverse Design\n",
"\n",
"**Undergoing maintenance. Check back in 2025 :D**\n",
"v0.2.12-beta\n",
"2024/12/06 \n",
"v0.3-beta\n",
"2024/12\n",
"Paul Shen <pxshen@alumni.stanford.edu>"
]
},
Expand Down Expand Up @@ -89,7 +89,18 @@
"source": [
"## Geometry layout\n",
"We layout using Python gdsfactory which is integrated with KLayout. Can also import .gds into gdsfactory . Internally, gdsfactory component and layer stack let generate a 3D mesh which is clipped vertically some depths above and below `core_layer`. By default,\n",
"we apply a SOI 220nm node (Si, SiO, SiN and Ge layers) implemented by [`gdsfactory.generic_tech`](https://gdsfactory.github.io/gdsfactory/notebooks/03_layer_stack.html#layerstack) layer stack. `luminescent.MATERIALS` maps the material tag of a layer in the layer stack to its property eg `MATERIALS[\"si\"][\"epsilon\"]`. Can create your own LAYER_STACK and MATERIALS for your process node."
"we apply a SOI 220nm node (Si, SiO, SiN and Ge layers) implemented by [`gdsfactory.generic_tech`](https://gdsfactory.github.io/gdsfactory/notebooks/03_layer_stack.html#layerstack) layer stack.\n"
]
},
{
"cell_type": "markdown",
"id": "66a94ddf",
"metadata": {},
"source": [
"## Materials\n",
"We use Tidy3D's open source `materials_library`. We map gdsfactory layerstack layers to Tidy3D materials via the layer's material property while taking into account common name variants (eg \"si\" or \"Si\" mapping to \"cSi\").\n",
"\n",
"Dispersive, anisotropic, and nonlinear materials are by default not simulated but can be implemented upon request."
]
},
{
Expand All @@ -116,7 +127,7 @@
"metadata": {},
"source": [
"## File workflow\n",
"Each simulation or design optimization run is saved to a folder named after `name` arg or (if unnamed) timestamp string. These run folders are inside working directory `wd=\"~/runs\"` which can be modified by passing to `write_sparams` or `gcell_problem`. Can access saved runs via `load_res()`, `load_res()`, `finetune()` which act on latest modified run folder inside `wd` if `name` not specified. "
"Each simulation or design optimization run is saved to a folder path. Can access saved runs via `load_res`, `finetune` "
]
},
{
Expand All @@ -143,7 +154,8 @@
"metadata": {},
"outputs": [],
"source": [
"!pip install -U luminescent"
"%%shell\n",
"pip install -U luminescent"
]
},
{
Expand Down Expand Up @@ -532,14 +544,15 @@
"metadata": {},
"outputs": [],
"source": [
"c = gf.components.straight(length=1.0,width=0.5,layer=core_layer)\n",
"wavelengths=1.55\n",
"nres=30\n",
"# c = gf.components.straight(length=1.0,width=0.5,layer=core_layer)\n",
"# wavelengths=1.55\n",
"# nres=30\n",
"\n",
"name=\"TE1\"\n",
"keys=[\"o2@1,o1@1\"]\n",
"lumi.make_pic_sim_prob(c,path, wavelengths=wavelengths, keys=keys,nres=nres, N=N, dtype=dtype, gpu=gpu)\n",
"lumi.load_res(path)"
"# path=\"TE1\"\n",
"# keys=[\"o2@1,o1@1\"]\n",
"# lumi.make_pic_sim_prob(path,c, wavelengths=wavelengths, keys=keys,nres=nres, N=N, dtype=dtype, gpu=gpu)\n",
"# lumi.solve(path)\n",
"# lumi.load_res(path)"
]
},
{
Expand All @@ -558,12 +571,13 @@
"metadata": {},
"outputs": [],
"source": [
"name=\"rib\"\n",
"keys=[\"2,1\"]\n",
"bbox_layer=[LAYER.WAFER,LAYER.SLAB90]\n",
"lumi.make_pic_sim_prob(c,path, wavelengths=wavelengths, keys=keys,nres=nres, N=N, dtype=dtype, gpu=gpu, \n",
" bbox_layer=bbox_layer)\n",
"sol = lumi.load_res(path)"
"# path=\"rib\"\n",
"# keys=[\"2,1\"]\n",
"# bbox_layer=[LAYER.WAFER,LAYER.SLAB90]\n",
"# lumi.make_pic_sim_prob(path,c, wavelengths=wavelengths, keys=keys,nres=nres, N=N, dtype=dtype, gpu=gpu, \n",
"# bbox_layer=bbox_layer)\n",
"# lumi.solve(path)\n",
"# sol = lumi.load_res(path)"
]
},
{
Expand All @@ -581,13 +595,14 @@
"metadata": {},
"outputs": [],
"source": [
"name=\"SiN\"\n",
"core_layer=LAYER.WGN\n",
"c = gf.components.straight(length=2.0, width=1.0, layer=core_layer)\n",
"# path=\"SiN\"\n",
"# core_layer=LAYER.WGN\n",
"# c = gf.components.straight(length=2.0, width=1.0, layer=core_layer)\n",
"\n",
"lumi.make_pic_sim_prob(c,path, wavelengths=wavelengths, keys=keys,nres=nres, N=N, dtype=dtype, gpu=gpu,\n",
" core_layer=core_layer)\n",
"sol = lumi.load_res(path)"
"# lumi.make_pic_sim_prob(path,c, wavelengths=wavelengths, keys=keys,nres=nres, N=N, dtype=dtype, gpu=gpu,\n",
"# core_layer=core_layer)\n",
"# lumi.solve(path)\n",
"# sol = lumi.load_res(path)"
]
},
{
Expand All @@ -598,7 +613,7 @@
"# Tutorials: PIC generative inverse design\n",
"We introduce GCells (generative cells), a natural evolution of PCells (parametric cells) in semiconductor design . Given a set of inverse design objectives, a GCell will generate optimal geometry using adjoint optimization while ensuring manufacturability by enforcing minimum feature lengths.\n",
"\n",
"In examples below, `gcells.mimo` (multi in multi out) is just a gdsfactory component with configurable waveguide ports, simple slab as pre-optimization geometry, and overlying rectangular design regions. Dimensions `l` along x and `w` along y. Ports are numbered incrementally: west (SW->NW) -> east (SE->NE) -> south (SW->SE) -> north (NW->NE). By default, they're spaced equally on a side. Example: `west=1, east=2` places port 1 on west, ports 2 & 3 on east. But can also individually specify their locations and widths. Example : `west=[1.0, 2.5], wwg_west=[0.5, 0.4]`.\n",
"In examples below, `mimo` (multi in multi out) is just a gdsfactory component with configurable waveguide ports, simple slab as pre-optimization geometry, and overlying rectangular design regions. Dimensions `l` along x and `w` along y. Ports are numbered incrementally: west (SW->NW) -> east (SE->NE) -> south (SW->SE) -> north (NW->NE). By default, they're spaced equally on a side. Example: `west=1, east=2` places port 1 on west, ports 2 & 3 on east. But can also individually specify their locations and widths. Example : `west=[1.0, 2.5], wwg_west=[0.5, 0.4]`.\n",
"\n",
"Optimization `targets` is a dictionary organized wrt target type & wavelength. Types include T-params (`tparams`, most common), phase difference (`phasediff`), S-params (`sparams`). Multiple types & wavelengths are possible & often necessary . Loss for each type is scaled automatically to vary from 0 to 1 usually . For example , `tparams` loss of 0.5 roughly means 50% of power going to wrong places.\n",
"\n",
Expand Down Expand Up @@ -635,16 +650,17 @@
"import luminescent as lumi\n",
"\n",
"path = \"mode_converter\" # can be any string\n",
"c = lumi.gcells.mimo(west=1, east=1, l=5.0, w=2.4,\n",
"c = lumi.mimo(west=1, east=1, l=5.0, w=2.4,\n",
" wwg=.5, taper=.05)\n",
"targets = {\"tparams\": {1.55: {\"o2@1,o1@0\": 1.0}}}\n",
"\n",
"prob = lumi.gcell_problem(\n",
" c, targets, path,\n",
"lumi.make_pic_inv_prob(\n",
" path,c, targets, \n",
" N=2, nres=15,\n",
" lvoid=0.15, lsolid=.15,\n",
" iters=100, stoploss=.05, )\n",
"lumi.solve(prob)"
"lumi.solve(path)\n",
"lumi.load_res(path)"
]
},
{
Expand All @@ -663,7 +679,7 @@
"outputs": [],
"source": [
"# import luminescent as lumi\n",
"# lumi.finetune(iters=40,name=\"mode_converter\")"
"# lumi.finetune(path,iters=40,path=\"mode_converter\")"
]
},
{
Expand Down Expand Up @@ -724,7 +740,7 @@
}
],
"source": [
"name=\"mode_converter\"\n",
"path=\"mode_converter\"\n",
"sol=lumi.load_res(path)"
]
},
Expand All @@ -742,7 +758,7 @@
"metadata": {},
"source": [
"### 1x2 splitter MMI\n",
"1.55um wavelength 1x2 splitter. We set symmetry about y so only need to specify T21=.5 as optimization target. Data saved to `name` folder inside working directory. We start iteratiions of adjoint optimization."
"1.55um wavelength 1x2 splitter. We set symmetry about y so only need to specify T21=.5 as optimization target. Data saved to `path` folder inside working directory. We start iteratiions of adjoint optimization."
]
},
{
Expand All @@ -756,17 +772,17 @@
"import luminescent as lumi\n",
"\n",
"path = \"splitter\"\n",
"c = lumi.gcells.mimo(west=1, east=2, l=4.0, w=2.0, wwg=.5, taper=.05, )\n",
"c = lumi.mimo(west=1, east=2, l=4.0, w=2.0, wwg=.5, taper=.05, )\n",
"targets = {\n",
" \"tparams\": {1.55: {\"2,1\": 0.5}},\n",
"}\n",
"\n",
"prob = lumi.gcell_problem(\n",
" c, targets, path,\n",
"lumi.make_pic_inv_prob(\n",
" path,c, targets, \n",
" N=2, nres=15, symmetries=[1],\n",
" lvoid=0.15, lsolid=.15,\n",
" iters=50, stoploss=.05, )\n",
"lumi.solve(prob, run=False)"
"lumi.solve(path)"
]
},
{
Expand Down Expand Up @@ -864,7 +880,7 @@
"outputs": [],
"source": [
"# finetune(iters=10,path)\n",
"sol = lumi.load_res(name)"
"# sol = lumi.load_res(path)"
]
},
{
Expand All @@ -886,18 +902,18 @@
"from pprint import pprint\n",
"import luminescent as lumi\n",
"\n",
"name=\"demux\"\n",
"c = lumi.gcells.mimo(west=1, east=2, l=4.0, w=4.0, wwg=.5)\n",
"path=\"demux\"\n",
"c = lumi.mimo(west=1, east=2, l=4.0, w=4.0, wwg=.5)\n",
"targets = {\"tparams\":{\n",
" 1.55: {\"2,1\": 1.0},\n",
" 1.20: {\"3,1\": 1.0},\n",
"}}\n",
"\n",
"prob = lumi.gcell_problem(\n",
" c, targets, path,\n",
"lumi.make_pic_inv_prob(\n",
" path,c, targets, \n",
" lvoid=0.15,lsolid=0.15, nres=15, \n",
" N=2, iters=50)\n",
"lumi.solve(prob)"
"lumi.solve(path)"
]
},
{
Expand All @@ -907,8 +923,8 @@
"metadata": {},
"outputs": [],
"source": [
"name=\"demux\"\n",
"sol = lumi.load_res(name)"
"path=\"demux\"\n",
"sol = lumi.load_res(path)"
]
},
{
Expand Down Expand Up @@ -936,15 +952,16 @@
"from pprint import pprint\n",
"import luminescent as lumi\n",
"\n",
"name=\"crossing\"\n",
"c = lumi.gcells.mimo(west=1, east=1, south=1, north=1, l=4.0, w=4.0, wwg=.5)\n",
"path=\"crossing\"\n",
"c = lumi.mimo(west=1, east=1, south=1, north=1, l=4.0, w=4.0, wwg=.5)\n",
"targets = {\"tparams\":{1.55: {\"2,1\": 1.0}}}\n",
"\n",
"prob = lumi.gcell_problem(\n",
" c, targets, path,\n",
"lumi.make_pic_inv_prob(\n",
" path,c, targets, \n",
" lvoid=0.15,lsolid=0.15, nres=15, symmetries=[0,1],\n",
" N=2, iters=40)\n",
"lumi.solve(prob)"
"lumi.solve(path)\n",
"sol = lumi.load_res(path)"
]
},
{
Expand All @@ -953,9 +970,7 @@
"id": "5a26e39b-9418-4c39-8133-b156583647f3",
"metadata": {},
"outputs": [],
"source": [
"sol = lumi.load_res(name)"
]
"source": []
},
{
"cell_type": "markdown",
Expand Down
4 changes: 2 additions & 2 deletions makedocs/src/luminescent.html
Original file line number Diff line number Diff line change
Expand Up @@ -7828,7 +7828,7 @@ <h2 id="Inverse-design-with-GCells">Inverse design with GCells<a class="anchor-l
<span class="p">}}</span>
<span class="n">c</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>

<span class="n">prob</span> <span class="o">=</span> <span class="n">lumi</span><span class="o">.</span><span class="n">gcell_problem</span><span class="p">(</span>
<span class="n">prob</span> <span class="o">=</span> <span class="n">lumi</span><span class="o">.</span><span class="n">make_pic_inv_prob</span><span class="p">(</span>
<span class="n">c</span><span class="p">,</span> <span class="n">tparam_targets</span><span class="o">=</span><span class="n">targets</span><span class="p">,</span>
<span class="n">lmin</span><span class="o">=</span><span class="mf">0.2</span><span class="p">,</span> <span class="n">dx</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span> <span class="n">iters</span><span class="o">=</span><span class="mi">40</span><span class="p">,</span> <span class="n">eta</span><span class="o">=</span><span class="mf">10.</span><span class="p">,</span> <span class="n">N</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">sol</span> <span class="o">=</span> <span class="n">lumi</span><span class="o">.</span><span class="n">solve</span><span class="p">(</span><span class="n">prob</span><span class="p">)</span>
Expand Down Expand Up @@ -7902,7 +7902,7 @@ <h2 id="Geometry-&amp;-materials">Geometry &amp; materials<a class="anchor-link"
<p>LAYER_STACK, LAYER, MATERIALS corresponding to a SOI node are provided in
<code>gdsfactory.generic_tech</code> similar to gdsfactory's. They can be customized and passed as
<code>layer_stack</code>, <code>MATERIALS</code> to
<code>make_pic_sim_prob, gcell_problem</code>
<code>make_pic_sim_prob, make_pic_inv_prob</code>
</p>
</div>
</div>
Expand Down
10 changes: 5 additions & 5 deletions scratch.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
"metadata": {},
"source": [
"## File workflow\n",
"Each simulation or design optimization run is saved to a folder named after `name` arg or (if unnamed) timestamp string. These run folders are inside working directory `wd=\"~/runs\"` which can be modified by passing to `make_pic_sim_prob` or `gcell_problem`. Can access saved runs via `load_res()`, `load_res()`, `finetune()` which act on latest modified run folder inside `wd` if `name` not specified. "
"Each simulation or design optimization run is saved to a folder named after `name` arg or (if unnamed) timestamp string. These run folders are inside working directory `wd=\"~/runs\"` which can be modified by passing to `make_pic_sim_prob` or `make_pic_inv_prob`. Can access saved runs via `load_res()`, `load_res()`, `finetune()` which act on latest modified run folder inside `wd` if `name` not specified. "
]
},
{
Expand Down Expand Up @@ -582,7 +582,7 @@
" wwg=.5, taper=.05)\n",
"targets = {\"tparams\": {1.55: {\"o2@1,o1@0\": 1.0}}}\n",
"\n",
"prob = lumi.gcell_problem(\n",
"prob = lumi.make_pic_inv_prob(\n",
" c, targets, path,\n",
" N=2, nres=15,\n",
" lvoid=0.15, lsolid=.15,\n",
Expand Down Expand Up @@ -704,7 +704,7 @@
" \"tparams\": {1.55: {\"2,1\": 0.5}},\n",
"}\n",
"\n",
"prob = lumi.gcell_problem(\n",
"prob = lumi.make_pic_inv_prob(\n",
" c, targets, path,\n",
" N=2, nres=15, symmetries=[1],\n",
" lvoid=0.15, lsolid=.15,\n",
Expand Down Expand Up @@ -836,7 +836,7 @@
" 1.20: {\"3,1\": 1.0},\n",
"}}\n",
"\n",
"prob = lumi.gcell_problem(\n",
"prob = lumi.make_pic_inv_prob(\n",
" c, targets, path,\n",
" lvoid=0.15,lsolid=0.15, nres=15, \n",
" N=2, iters=50)\n",
Expand Down Expand Up @@ -883,7 +883,7 @@
"c = lumi.gcells.mimo(west=1, east=1, south=1, north=1, l=4.0, w=4.0, wwg=.5)\n",
"targets = {\"tparams\":{1.55: {\"2,1\": 1.0}}}\n",
"\n",
"prob = lumi.gcell_problem(\n",
"prob = lumi.make_pic_inv_prob(\n",
" c, targets, path,\n",
" lvoid=0.15,lsolid=0.15, nres=15, symmetries=[0,1],\n",
" N=2, iters=40)\n",
Expand Down

0 comments on commit 8300caf

Please sign in to comment.